summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsaurabhb172020-02-26 16:00:53 +0530
committerGitHub2020-02-26 16:00:53 +0530
commit886d9cb772e81d2e5262284bc3082664f084337f (patch)
tree6acee185a4dc19113fcbf0f9a3d6941085dedaf7
parent0db48f6533517ecebfd9f0693f89deca28408b76 (diff)
parentaa35045840b78d3f48212db45da59a2e5c69b223 (diff)
downloadKiCad-eSim-886d9cb772e81d2e5262284bc3082664f084337f.tar.gz
KiCad-eSim-886d9cb772e81d2e5262284bc3082664f084337f.tar.bz2
KiCad-eSim-886d9cb772e81d2e5262284bc3082664f084337f.zip
Merge pull request #1 from saurabhb17/develop
Added main functions
-rw-r--r--AUTHORS.txt75
-rw-r--r--CHANGELOG.txt204
-rw-r--r--CMakeLists.txt932
-rw-r--r--INSTALL.txt164
-rw-r--r--README.txt41
-rw-r--r--TODO.txt76
-rw-r--r--cvpcb/CMakeLists.txt190
-rw-r--r--cvpcb/Info.plist54
-rw-r--r--cvpcb/autosel.cpp304
-rw-r--r--cvpcb/autosel.h45
-rw-r--r--cvpcb/cfg.cpp92
-rw-r--r--cvpcb/class_DisplayFootprintsFrame.cpp569
-rw-r--r--cvpcb/class_DisplayFootprintsFrame.h138
-rw-r--r--cvpcb/class_components_listbox.cpp184
-rw-r--r--cvpcb/class_footprints_listbox.cpp291
-rw-r--r--cvpcb/class_library_listbox.cpp217
-rw-r--r--cvpcb/common_help_msg.h30
-rw-r--r--cvpcb/cvframe.cpp939
-rw-r--r--cvpcb/cvpcb.cpp198
-rw-r--r--cvpcb/cvpcb.h41
-rw-r--r--cvpcb/cvpcb.icnsbin0 -> 166061 bytes
-rw-r--r--cvpcb/cvpcb.rc2
-rw-r--r--cvpcb/cvpcb_doc.icnsbin0 -> 118770 bytes
-rw-r--r--cvpcb/cvpcb_id.h60
-rw-r--r--cvpcb/cvpcb_mainframe.h306
-rw-r--r--cvpcb/cvstruct.h240
-rw-r--r--cvpcb/dialogs/dialog_config_equfiles.cpp308
-rw-r--r--cvpcb/dialogs/dialog_config_equfiles.h71
-rw-r--r--cvpcb/dialogs/dialog_config_equfiles_base.cpp151
-rw-r--r--cvpcb/dialogs/dialog_config_equfiles_base.fbp1108
-rw-r--r--cvpcb/dialogs/dialog_config_equfiles_base.h82
-rw-r--r--cvpcb/dialogs/dialog_cvpcb_config_fbp.h100
-rw-r--r--cvpcb/dialogs/dialog_display_options.cpp136
-rw-r--r--cvpcb/dialogs/dialog_display_options.h61
-rw-r--r--cvpcb/dialogs/dialog_display_options_base.cpp93
-rw-r--r--cvpcb/dialogs/dialog_display_options_base.fbp861
-rw-r--r--cvpcb/dialogs/dialog_display_options_base.h68
-rw-r--r--cvpcb/dialogs/fp_conflict_assignment_selector.cpp190
-rw-r--r--cvpcb/dialogs/fp_conflict_assignment_selector.h79
-rw-r--r--cvpcb/dialogs/fp_conflict_assignment_selector_base.cpp58
-rw-r--r--cvpcb/dialogs/fp_conflict_assignment_selector_base.fbp313
-rw-r--r--cvpcb/dialogs/fp_conflict_assignment_selector_base.h59
-rw-r--r--cvpcb/listboxes.cpp122
-rw-r--r--cvpcb/menubar.cpp153
-rw-r--r--cvpcb/readwrite_dlgs.cpp402
-rw-r--r--cvpcb/tool_cvpcb.cpp115
-rw-r--r--eeschema/CMakeLists.txt383
-rw-r--r--eeschema/Info.plist35
-rw-r--r--eeschema/annotate.cpp200
-rw-r--r--eeschema/backanno.cpp264
-rw-r--r--eeschema/block.cpp538
-rw-r--r--eeschema/block_libedit.cpp355
-rw-r--r--eeschema/bus-wire-junction.cpp505
-rw-r--r--eeschema/busentry.cpp83
-rw-r--r--eeschema/class_drc_erc_item.cpp68
-rw-r--r--eeschema/class_libentry.cpp1898
-rw-r--r--eeschema/class_libentry.h773
-rw-r--r--eeschema/class_library.cpp1208
-rw-r--r--eeschema/class_library.h670
-rw-r--r--eeschema/class_netlist_object.cpp423
-rw-r--r--eeschema/class_netlist_object.h483
-rw-r--r--eeschema/class_sch_screen.h599
-rw-r--r--eeschema/cmp_library.keywords33
-rw-r--r--eeschema/cmp_library_lexer.cpp6
-rw-r--r--eeschema/component_references_lister.cpp788
-rw-r--r--eeschema/component_tree_search_container.cpp443
-rw-r--r--eeschema/component_tree_search_container.h145
-rw-r--r--eeschema/controle.cpp326
-rw-r--r--eeschema/cross-probing.cpp214
-rw-r--r--eeschema/dialog_erc_listbox.h120
-rw-r--r--eeschema/dialogs/dialog_annotate.cpp320
-rw-r--r--eeschema/dialogs/dialog_annotate_base.cpp245
-rw-r--r--eeschema/dialogs/dialog_annotate_base.fbp2636
-rw-r--r--eeschema/dialogs/dialog_annotate_base.h94
-rw-r--r--eeschema/dialogs/dialog_bom.cpp621
-rw-r--r--eeschema/dialogs/dialog_bom_base.cpp118
-rw-r--r--eeschema/dialogs/dialog_bom_base.fbp1445
-rw-r--r--eeschema/dialogs/dialog_bom_base.h98
-rw-r--r--eeschema/dialogs/dialog_bom_cfg.keywords4
-rw-r--r--eeschema/dialogs/dialog_bom_help.html282
-rw-r--r--eeschema/dialogs/dialog_choose_component.cpp409
-rw-r--r--eeschema/dialogs/dialog_choose_component.h92
-rw-r--r--eeschema/dialogs/dialog_choose_component_base.cpp93
-rw-r--r--eeschema/dialogs/dialog_choose_component_base.fbp594
-rw-r--r--eeschema/dialogs/dialog_choose_component_base.h69
-rw-r--r--eeschema/dialogs/dialog_color_config.cpp296
-rw-r--r--eeschema/dialogs/dialog_color_config.h58
-rw-r--r--eeschema/dialogs/dialog_color_config_base.cpp48
-rw-r--r--eeschema/dialogs/dialog_color_config_base.fbp217
-rw-r--r--eeschema/dialogs/dialog_color_config_base.h52
-rw-r--r--eeschema/dialogs/dialog_edit_component_in_lib.cpp579
-rw-r--r--eeschema/dialogs/dialog_edit_component_in_lib.h70
-rw-r--r--eeschema/dialogs/dialog_edit_component_in_lib_base.cpp294
-rw-r--r--eeschema/dialogs/dialog_edit_component_in_lib_base.fbp3354
-rw-r--r--eeschema/dialogs/dialog_edit_component_in_lib_base.h119
-rw-r--r--eeschema/dialogs/dialog_edit_component_in_schematic.cpp1107
-rw-r--r--eeschema/dialogs/dialog_edit_component_in_schematic_fbp.cpp324
-rw-r--r--eeschema/dialogs/dialog_edit_component_in_schematic_fbp.fbp3532
-rw-r--r--eeschema/dialogs/dialog_edit_component_in_schematic_fbp.h109
-rw-r--r--eeschema/dialogs/dialog_edit_label.cpp326
-rw-r--r--eeschema/dialogs/dialog_edit_label_base.cpp118
-rw-r--r--eeschema/dialogs/dialog_edit_label_base.fbp968
-rw-r--r--eeschema/dialogs/dialog_edit_label_base.h75
-rw-r--r--eeschema/dialogs/dialog_edit_libentry_fields_in_lib.cpp796
-rw-r--r--eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.cpp229
-rw-r--r--eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.fbp2326
-rw-r--r--eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.h92
-rw-r--r--eeschema/dialogs/dialog_edit_one_field.cpp278
-rw-r--r--eeschema/dialogs/dialog_edit_one_field.h159
-rw-r--r--eeschema/dialogs/dialog_eeschema_config.cpp490
-rw-r--r--eeschema/dialogs/dialog_eeschema_config_fbp.cpp175
-rw-r--r--eeschema/dialogs/dialog_eeschema_config_fbp.fbp1588
-rw-r--r--eeschema/dialogs/dialog_eeschema_config_fbp.h89
-rw-r--r--eeschema/dialogs/dialog_eeschema_options.cpp371
-rw-r--r--eeschema/dialogs/dialog_eeschema_options.h479
-rw-r--r--eeschema/dialogs/dialog_eeschema_options_base.cpp303
-rw-r--r--eeschema/dialogs/dialog_eeschema_options_base.fbp4612
-rw-r--r--eeschema/dialogs/dialog_eeschema_options_base.h145
-rw-r--r--eeschema/dialogs/dialog_erc.cpp579
-rw-r--r--eeschema/dialogs/dialog_erc.h92
-rw-r--r--eeschema/dialogs/dialog_erc_base.cpp152
-rw-r--r--eeschema/dialogs/dialog_erc_base.fbp1799
-rw-r--r--eeschema/dialogs/dialog_erc_base.h88
-rw-r--r--eeschema/dialogs/dialog_lib_edit_draw_item.cpp131
-rw-r--r--eeschema/dialogs/dialog_lib_edit_draw_item.fbp1205
-rw-r--r--eeschema/dialogs/dialog_lib_edit_draw_item.h67
-rw-r--r--eeschema/dialogs/dialog_lib_edit_draw_item_base.cpp140
-rw-r--r--eeschema/dialogs/dialog_lib_edit_draw_item_base.h67
-rw-r--r--eeschema/dialogs/dialog_lib_edit_pin.cpp193
-rw-r--r--eeschema/dialogs/dialog_lib_edit_pin.h146
-rw-r--r--eeschema/dialogs/dialog_lib_edit_pin_base.cpp224
-rw-r--r--eeschema/dialogs/dialog_lib_edit_pin_base.fbp2299
-rw-r--r--eeschema/dialogs/dialog_lib_edit_pin_base.h104
-rw-r--r--eeschema/dialogs/dialog_lib_edit_pin_table.cpp584
-rw-r--r--eeschema/dialogs/dialog_lib_edit_pin_table.h18
-rw-r--r--eeschema/dialogs/dialog_lib_edit_pin_table_base.cpp46
-rw-r--r--eeschema/dialogs/dialog_lib_edit_pin_table_base.fbp193
-rw-r--r--eeschema/dialogs/dialog_lib_edit_pin_table_base.h53
-rw-r--r--eeschema/dialogs/dialog_lib_edit_text.cpp222
-rw-r--r--eeschema/dialogs/dialog_lib_edit_text.h54
-rw-r--r--eeschema/dialogs/dialog_lib_edit_text_base.cpp150
-rw-r--r--eeschema/dialogs/dialog_lib_edit_text_base.fbp1427
-rw-r--r--eeschema/dialogs/dialog_lib_edit_text_base.h74
-rw-r--r--eeschema/dialogs/dialog_lib_new_component.cpp45
-rw-r--r--eeschema/dialogs/dialog_lib_new_component.fbp1597
-rw-r--r--eeschema/dialogs/dialog_lib_new_component.h97
-rw-r--r--eeschema/dialogs/dialog_lib_new_component_base.cpp146
-rw-r--r--eeschema/dialogs/dialog_lib_new_component_base.h67
-rw-r--r--eeschema/dialogs/dialog_libedit_options.cpp69
-rw-r--r--eeschema/dialogs/dialog_libedit_options.h93
-rw-r--r--eeschema/dialogs/dialog_libedit_options_base.cpp195
-rw-r--r--eeschema/dialogs/dialog_libedit_options_base.fbp2904
-rw-r--r--eeschema/dialogs/dialog_libedit_options_base.h85
-rw-r--r--eeschema/dialogs/dialog_netlist.cpp886
-rw-r--r--eeschema/dialogs/dialog_netlist_base.cpp151
-rw-r--r--eeschema/dialogs/dialog_netlist_base.fbp1624
-rw-r--r--eeschema/dialogs/dialog_netlist_base.h124
-rw-r--r--eeschema/dialogs/dialog_plot_schematic.cpp357
-rw-r--r--eeschema/dialogs/dialog_plot_schematic.h157
-rw-r--r--eeschema/dialogs/dialog_plot_schematic_base.cpp184
-rw-r--r--eeschema/dialogs/dialog_plot_schematic_base.fbp1852
-rw-r--r--eeschema/dialogs/dialog_plot_schematic_base.h91
-rw-r--r--eeschema/dialogs/dialog_print_using_printer.cpp487
-rw-r--r--eeschema/dialogs/dialog_print_using_printer_base.cpp80
-rw-r--r--eeschema/dialogs/dialog_print_using_printer_base.fbp732
-rw-r--r--eeschema/dialogs/dialog_print_using_printer_base.h61
-rw-r--r--eeschema/dialogs/dialog_rescue_each.cpp316
-rw-r--r--eeschema/dialogs/dialog_rescue_each_base.cpp127
-rw-r--r--eeschema/dialogs/dialog_rescue_each_base.fbp978
-rw-r--r--eeschema/dialogs/dialog_rescue_each_base.h70
-rw-r--r--eeschema/dialogs/dialog_sch_edit_sheet_pin.cpp60
-rw-r--r--eeschema/dialogs/dialog_sch_edit_sheet_pin.h59
-rw-r--r--eeschema/dialogs/dialog_sch_edit_sheet_pin_base.cpp102
-rw-r--r--eeschema/dialogs/dialog_sch_edit_sheet_pin_base.fbp1043
-rw-r--r--eeschema/dialogs/dialog_sch_edit_sheet_pin_base.h61
-rw-r--r--eeschema/dialogs/dialog_sch_sheet_props.cpp61
-rw-r--r--eeschema/dialogs/dialog_sch_sheet_props.fbp1503
-rw-r--r--eeschema/dialogs/dialog_sch_sheet_props.h80
-rw-r--r--eeschema/dialogs/dialog_sch_sheet_props_base.cpp131
-rw-r--r--eeschema/dialogs/dialog_sch_sheet_props_base.h65
-rw-r--r--eeschema/dialogs/dialog_schematic_find.cpp284
-rw-r--r--eeschema/dialogs/dialog_schematic_find.h201
-rw-r--r--eeschema/dialogs/dialog_schematic_find_base.cpp169
-rw-r--r--eeschema/dialogs/dialog_schematic_find_base.fbp1901
-rw-r--r--eeschema/dialogs/dialog_schematic_find_base.h81
-rw-r--r--eeschema/edit_bitmap.cpp199
-rw-r--r--eeschema/edit_component_in_schematic.cpp117
-rw-r--r--eeschema/edit_label.cpp320
-rw-r--r--eeschema/eeredraw.cpp86
-rw-r--r--eeschema/eeschema.cpp242
-rw-r--r--eeschema/eeschema.icnsbin0 -> 178654 bytes
-rw-r--r--eeschema/eeschema.rc3
-rw-r--r--eeschema/eeschema_config.cpp810
-rw-r--r--eeschema/eeschema_config.h13
-rw-r--r--eeschema/eeschema_doc.icnsbin0 -> 144703 bytes
-rw-r--r--eeschema/eeschema_id.h252
-rw-r--r--eeschema/erc.cpp617
-rw-r--r--eeschema/erc.h127
-rw-r--r--eeschema/events_called_functions_for_edit.cpp79
-rw-r--r--eeschema/files-io.cpp547
-rw-r--r--eeschema/find.cpp515
-rw-r--r--eeschema/general.h150
-rw-r--r--eeschema/getpart.cpp402
-rw-r--r--eeschema/help_common_strings.h90
-rw-r--r--eeschema/hierarch.cpp313
-rw-r--r--eeschema/hotkeys.cpp876
-rw-r--r--eeschema/hotkeys.h96
-rw-r--r--eeschema/invoke_sch_dialog.h97
-rw-r--r--eeschema/lib_arc.cpp825
-rw-r--r--eeschema/lib_arc.h161
-rw-r--r--eeschema/lib_bezier.cpp421
-rw-r--r--eeschema/lib_bezier.h119
-rw-r--r--eeschema/lib_circle.cpp356
-rw-r--r--eeschema/lib_circle.h121
-rw-r--r--eeschema/lib_collectors.cpp131
-rw-r--r--eeschema/lib_collectors.h135
-rw-r--r--eeschema/lib_draw_item.cpp160
-rw-r--r--eeschema/lib_draw_item.h448
-rw-r--r--eeschema/lib_export.cpp191
-rw-r--r--eeschema/lib_field.cpp771
-rw-r--r--eeschema/lib_field.h277
-rw-r--r--eeschema/lib_pin.cpp2314
-rw-r--r--eeschema/lib_pin.h561
-rw-r--r--eeschema/lib_polyline.cpp562
-rw-r--r--eeschema/lib_polyline.h133
-rw-r--r--eeschema/lib_rectangle.cpp434
-rw-r--r--eeschema/lib_rectangle.h126
-rw-r--r--eeschema/lib_text.cpp559
-rw-r--r--eeschema/lib_text.h152
-rw-r--r--eeschema/libarch.cpp119
-rw-r--r--eeschema/libedit.cpp742
-rw-r--r--eeschema/libedit_onleftclick.cpp213
-rw-r--r--eeschema/libedit_onrightclick.cpp348
-rw-r--r--eeschema/libedit_plot_component.cpp214
-rw-r--r--eeschema/libedit_undo_redo.cpp137
-rw-r--r--eeschema/libeditframe.cpp1375
-rw-r--r--eeschema/libeditframe.h678
-rw-r--r--eeschema/libfield.cpp161
-rw-r--r--eeschema/load_one_schematic_file.cpp413
-rw-r--r--eeschema/menubar.cpp521
-rw-r--r--eeschema/menubar_libedit.cpp297
-rw-r--r--eeschema/netform.cpp149
-rw-r--r--eeschema/netlist.cpp971
-rw-r--r--eeschema/netlist.h62
-rw-r--r--eeschema/netlist_exporters/netlist_exporter.cpp364
-rw-r--r--eeschema/netlist_exporters/netlist_exporter.h235
-rw-r--r--eeschema/netlist_exporters/netlist_exporter_cadstar.cpp204
-rw-r--r--eeschema/netlist_exporters/netlist_exporter_cadstar.h62
-rw-r--r--eeschema/netlist_exporters/netlist_exporter_generic.cpp580
-rw-r--r--eeschema/netlist_exporters/netlist_exporter_generic.h135
-rw-r--r--eeschema/netlist_exporters/netlist_exporter_kicad.cpp77
-rw-r--r--eeschema/netlist_exporters/netlist_exporter_kicad.h63
-rw-r--r--eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp145
-rw-r--r--eeschema/netlist_exporters/netlist_exporter_orcadpcb2.h46
-rw-r--r--eeschema/netlist_exporters/netlist_exporter_pspice.cpp358
-rw-r--r--eeschema/netlist_exporters/netlist_exporter_pspice.h50
-rw-r--r--eeschema/onleftclick.cpp407
-rw-r--r--eeschema/onrightclick.cpp927
-rw-r--r--eeschema/operations_on_items_lists.cpp264
-rw-r--r--eeschema/pinedit.cpp786
-rw-r--r--eeschema/plot_schematic_DXF.cpp166
-rw-r--r--eeschema/plot_schematic_HPGL.cpp260
-rw-r--r--eeschema/plot_schematic_PDF.cpp209
-rw-r--r--eeschema/plot_schematic_PS.cpp191
-rw-r--r--eeschema/plot_schematic_SVG.cpp205
-rw-r--r--eeschema/plugins/CMakeLists.txt30
-rw-r--r--eeschema/plugins/python_scripts/README-bom.txt38
-rw-r--r--eeschema/plugins/python_scripts/bom_csv_grouped_by_value.py167
-rw-r--r--eeschema/plugins/python_scripts/bom_csv_grouped_by_value_with_fp.py65
-rw-r--r--eeschema/plugins/python_scripts/bom_csv_sorted_by_ref.py62
-rw-r--r--eeschema/plugins/python_scripts/bom_html_grouped_by_value.py98
-rw-r--r--eeschema/plugins/python_scripts/bom_html_with_advanced_grouping.py132
-rw-r--r--eeschema/plugins/python_scripts/bom_sorted_by_ref.py61
-rw-r--r--eeschema/plugins/python_scripts/kicad_netlist_reader.py764
-rw-r--r--eeschema/plugins/python_scripts/round_robin.py28
-rw-r--r--eeschema/plugins/python_scripts/round_value_robin.py74
-rw-r--r--eeschema/plugins/xsl_scripts/bom2csv.xsl99
-rw-r--r--eeschema/plugins/xsl_scripts/bom2grouped_csv.xsl104
-rw-r--r--eeschema/plugins/xsl_scripts/bom_with_title_block_2_csv.xsl167
-rw-r--r--eeschema/plugins/xsl_scripts/netlist_form_OrcadPcb2.xsl210
-rw-r--r--eeschema/plugins/xsl_scripts/netlist_form_cadstar-RINF.xsl131
-rw-r--r--eeschema/plugins/xsl_scripts/netlist_form_cadstar.xsl123
-rw-r--r--eeschema/plugins/xsl_scripts/netlist_form_pads-pcb.xsl69
-rw-r--r--eeschema/project_rescue.cpp569
-rw-r--r--eeschema/project_rescue.h198
-rw-r--r--eeschema/protos.h58
-rw-r--r--eeschema/sch_base_frame.cpp203
-rw-r--r--eeschema/sch_base_frame.h213
-rw-r--r--eeschema/sch_bitmap.cpp309
-rw-r--r--eeschema/sch_bitmap.h149
-rw-r--r--eeschema/sch_bus_entry.cpp403
-rw-r--r--eeschema/sch_bus_entry.h185
-rw-r--r--eeschema/sch_collectors.cpp571
-rw-r--r--eeschema/sch_collectors.h408
-rw-r--r--eeschema/sch_component.cpp2048
-rw-r--r--eeschema/sch_component.h496
-rw-r--r--eeschema/sch_field.cpp589
-rw-r--r--eeschema/sch_field.h202
-rw-r--r--eeschema/sch_item_struct.cpp151
-rw-r--r--eeschema/sch_item_struct.h432
-rw-r--r--eeschema/sch_junction.cpp235
-rw-r--r--eeschema/sch_junction.h113
-rw-r--r--eeschema/sch_line.cpp611
-rw-r--r--eeschema/sch_line.h157
-rw-r--r--eeschema/sch_marker.cpp186
-rw-r--r--eeschema/sch_marker.h117
-rw-r--r--eeschema/sch_no_connect.cpp252
-rw-r--r--eeschema/sch_no_connect.h115
-rw-r--r--eeschema/sch_reference_list.h469
-rw-r--r--eeschema/sch_screen.cpp1563
-rw-r--r--eeschema/sch_sheet.cpp1236
-rw-r--r--eeschema/sch_sheet.h600
-rw-r--r--eeschema/sch_sheet_path.cpp924
-rw-r--r--eeschema/sch_sheet_path.h571
-rw-r--r--eeschema/sch_sheet_pin.cpp526
-rw-r--r--eeschema/sch_text.cpp1777
-rw-r--r--eeschema/sch_text.h366
-rw-r--r--eeschema/sch_validators.cpp141
-rw-r--r--eeschema/sch_validators.h72
-rw-r--r--eeschema/schedit.cpp1163
-rw-r--r--eeschema/schematic_undo_redo.cpp382
-rw-r--r--eeschema/schframe.cpp1320
-rw-r--r--eeschema/schframe.h1351
-rw-r--r--eeschema/selpart.cpp163
-rw-r--r--eeschema/sheet.cpp452
-rw-r--r--eeschema/sheetlab.cpp179
-rw-r--r--eeschema/symbdraw.cpp370
-rw-r--r--eeschema/symbedit.cpp269
-rw-r--r--eeschema/template_fieldnames.cpp211
-rw-r--r--eeschema/template_fieldnames.h190
-rw-r--r--eeschema/template_fieldnames.keywords5
-rw-r--r--eeschema/tool_lib.cpp243
-rw-r--r--eeschema/tool_sch.cpp325
-rw-r--r--eeschema/tool_viewlib.cpp279
-rw-r--r--eeschema/transform.cpp148
-rw-r--r--eeschema/transform.h106
-rw-r--r--eeschema/viewlib_frame.cpp595
-rw-r--r--eeschema/viewlib_frame.h188
-rw-r--r--eeschema/viewlibs.cpp310
-rw-r--r--gerbview/CMakeLists.txt190
-rw-r--r--gerbview/Info.plist55
-rw-r--r--gerbview/block.cpp221
-rw-r--r--gerbview/class_DCodeSelectionbox.cpp84
-rw-r--r--gerbview/class_DCodeSelectionbox.h58
-rw-r--r--gerbview/class_GERBER.cpp557
-rw-r--r--gerbview/class_GERBER.h378
-rw-r--r--gerbview/class_X2_gerber_attributes.cpp270
-rw-r--r--gerbview/class_X2_gerber_attributes.h178
-rw-r--r--gerbview/class_am_param.cpp251
-rw-r--r--gerbview/class_am_param.h268
-rw-r--r--gerbview/class_aperture_macro.cpp811
-rw-r--r--gerbview/class_aperture_macro.h262
-rw-r--r--gerbview/class_excellon.h308
-rw-r--r--gerbview/class_gbr_layer_box_selector.cpp81
-rw-r--r--gerbview/class_gbr_layer_box_selector.h59
-rw-r--r--gerbview/class_gbr_layout.cpp57
-rw-r--r--gerbview/class_gbr_layout.h148
-rw-r--r--gerbview/class_gbr_screen.cpp143
-rw-r--r--gerbview/class_gbr_screen.h69
-rw-r--r--gerbview/class_gerber_draw_item.cpp631
-rw-r--r--gerbview/class_gerber_draw_item.h309
-rw-r--r--gerbview/class_gerbview_layer_widget.cpp338
-rw-r--r--gerbview/class_gerbview_layer_widget.h134
-rw-r--r--gerbview/controle.cpp62
-rw-r--r--gerbview/dcode.cpp531
-rw-r--r--gerbview/dcode.h218
-rw-r--r--gerbview/dialogs/dialog_layers_select_to_pcb_base.cpp119
-rw-r--r--gerbview/dialogs/dialog_layers_select_to_pcb_base.fbp809
-rw-r--r--gerbview/dialogs/dialog_layers_select_to_pcb_base.h88
-rw-r--r--gerbview/dialogs/dialog_print_using_printer.cpp404
-rw-r--r--gerbview/dialogs/dialog_print_using_printer_base.cpp138
-rw-r--r--gerbview/dialogs/dialog_print_using_printer_base.fbp1167
-rw-r--r--gerbview/dialogs/dialog_print_using_printer_base.h78
-rw-r--r--gerbview/dialogs/dialog_select_one_pcb_layer.cpp277
-rw-r--r--gerbview/dialogs/dialog_show_page_borders.cpp84
-rw-r--r--gerbview/dialogs/dialog_show_page_borders.h47
-rw-r--r--gerbview/dialogs/dialog_show_page_borders_base.cpp64
-rw-r--r--gerbview/dialogs/dialog_show_page_borders_base.fbp316
-rw-r--r--gerbview/dialogs/dialog_show_page_borders_base.h55
-rw-r--r--gerbview/dialogs/gerbview_dialog_display_options_frame.cpp182
-rw-r--r--gerbview/dialogs/gerbview_dialog_display_options_frame_base.cpp141
-rw-r--r--gerbview/dialogs/gerbview_dialog_display_options_frame_base.fbp1334
-rw-r--r--gerbview/dialogs/gerbview_dialog_display_options_frame_base.h71
-rw-r--r--gerbview/draw_gerber_screen.cpp457
-rw-r--r--gerbview/events_called_functions.cpp390
-rw-r--r--gerbview/excellon_read_drill_file.cpp702
-rw-r--r--gerbview/export_to_pcbnew.cpp495
-rw-r--r--gerbview/files.cpp303
-rw-r--r--gerbview/gerber_test_files/aperture-circle-flash-with_hole.gbr27
-rw-r--r--gerbview/gerber_test_files/aperture-obround-flash-with_hole.gbr27
-rw-r--r--gerbview/gerber_test_files/aperture_macro-no_param-test.gbr82
-rw-r--r--gerbview/gerber_test_files/aperture_macro-with_param-test.gbr99
-rw-r--r--gerbview/gerber_test_files/apertures_rotated.gbr1109
-rw-r--r--gerbview/gerber_test_files/apertures_rotated_and_arcs_in_tracks.gbr1417
-rw-r--r--gerbview/gerber_test_files/octogonal.gbr27
-rw-r--r--gerbview/gerber_test_files/test-aperture-polygon-flash.gbr27
-rw-r--r--gerbview/gerber_test_files/test-aperture-rectangle-flash-with_hole.gbr27
-rw-r--r--gerbview/gerber_test_files/test-image-justify-with-offset.gbr19
-rw-r--r--gerbview/gerber_test_files/test-image-offset.gbr18
-rw-r--r--gerbview/gerber_test_files/test-image-polarity.gbr17
-rw-r--r--gerbview/gerber_test_files/test-image-rotation.gbr21
-rw-r--r--gerbview/gerber_test_files/test-layer-axis-select.gbr15
-rw-r--r--gerbview/gerber_test_files/test-layer-mixed_units_mode.gbr68
-rw-r--r--gerbview/gerber_test_files/test-layer-rotation.gbr23
-rw-r--r--gerbview/gerber_test_files/test-layer-scale-factor.gbr17
-rw-r--r--gerbview/gerber_test_files/test-layer-step-and_repeat-cross.gbr17
-rw-r--r--gerbview/gerber_test_files/test-layer-step-and_repeat-polygon.gbr18
-rw-r--r--gerbview/gerber_test_files/test-polygon_with_arc-fill.gbr18
-rw-r--r--gerbview/gerber_test_files/test2_line_with_rect_aperture.gbr67
-rw-r--r--gerbview/gerber_test_files/test_line_with_rect_aperture.gbr16
-rw-r--r--gerbview/gerber_test_files/test_polygons_with_arcs.gbr4163
-rw-r--r--gerbview/gerber_test_files/test_polygons_with_arcs_simple.gbr51
-rw-r--r--gerbview/gerbview.cpp152
-rw-r--r--gerbview/gerbview.h109
-rw-r--r--gerbview/gerbview.icnsbin0 -> 253784 bytes
-rw-r--r--gerbview/gerbview.rc3
-rw-r--r--gerbview/gerbview_config.cpp148
-rw-r--r--gerbview/gerbview_doc.icnsbin0 -> 153778 bytes
-rw-r--r--gerbview/gerbview_frame.cpp835
-rw-r--r--gerbview/gerbview_frame.h694
-rw-r--r--gerbview/gerbview_id.h81
-rw-r--r--gerbview/hotkeys.cpp216
-rw-r--r--gerbview/hotkeys.h51
-rw-r--r--gerbview/init_gbr_drawlayers.cpp98
-rw-r--r--gerbview/locate.cpp88
-rw-r--r--gerbview/menubar.cpp257
-rw-r--r--gerbview/onleftclick.cpp60
-rw-r--r--gerbview/onrightclick.cpp95
-rw-r--r--gerbview/options.cpp97
-rw-r--r--gerbview/pcbplot.cpp36
-rw-r--r--gerbview/pcbplot.h40
-rw-r--r--gerbview/printout_control.cpp269
-rw-r--r--gerbview/readgerb.cpp199
-rw-r--r--gerbview/rs274_read_XY_and_IJ_coordinates.cpp305
-rw-r--r--gerbview/rs274d.cpp771
-rw-r--r--gerbview/rs274x.cpp1064
-rw-r--r--gerbview/select_layers_to_pcb.cpp428
-rw-r--r--gerbview/select_layers_to_pcb.h72
-rw-r--r--gerbview/toolbars_gerber.cpp313
-rw-r--r--license_for_documentation.txt61
-rw-r--r--pcbnew/CMakeLists.txt746
-rw-r--r--pcbnew/Doxyfile_python2281
-rw-r--r--pcbnew/Doxyfile_xml315
-rw-r--r--pcbnew/Info.plist37
-rw-r--r--pcbnew/append_board_to_current.cpp221
-rw-r--r--pcbnew/attribut.cpp126
-rw-r--r--pcbnew/autorouter/auto_place_footprints.cpp1299
-rw-r--r--pcbnew/autorouter/autorout.cpp277
-rw-r--r--pcbnew/autorouter/autorout.h236
-rw-r--r--pcbnew/autorouter/cell.h116
-rw-r--r--pcbnew/autorouter/dist.cpp171
-rw-r--r--pcbnew/autorouter/graphpcb.cpp843
-rw-r--r--pcbnew/autorouter/move_and_route_event_functions.cpp200
-rw-r--r--pcbnew/autorouter/queue.cpp220
-rw-r--r--pcbnew/autorouter/rect_placement/RectanglePlacement.txt38
-rw-r--r--pcbnew/autorouter/rect_placement/rect_placement.cpp259
-rw-r--r--pcbnew/autorouter/rect_placement/rect_placement.h104
-rw-r--r--pcbnew/autorouter/routing_matrix.cpp550
-rw-r--r--pcbnew/autorouter/solve.cpp1348
-rw-r--r--pcbnew/autorouter/spread_footprints.cpp362
-rw-r--r--pcbnew/autorouter/work.cpp164
-rw-r--r--pcbnew/basepcbframe.cpp1020
-rw-r--r--pcbnew/block.cpp890
-rw-r--r--pcbnew/block_module_editor.cpp872
-rw-r--r--pcbnew/board_items_to_polygon_shape_transform.cpp1152
-rw-r--r--pcbnew/board_undo_redo.cpp713
-rw-r--r--pcbnew/build_BOM_from_board.cpp187
-rw-r--r--pcbnew/class_board.cpp2764
-rw-r--r--pcbnew/class_board.h1391
-rw-r--r--pcbnew/class_board_connected_item.cpp144
-rw-r--r--pcbnew/class_board_connected_item.h310
-rw-r--r--pcbnew/class_board_design_settings.cpp396
-rw-r--r--pcbnew/class_board_item.cpp245
-rw-r--r--pcbnew/class_dimension.cpp523
-rw-r--r--pcbnew/class_dimension.h240
-rw-r--r--pcbnew/class_drawsegment.cpp709
-rw-r--r--pcbnew/class_drawsegment.h256
-rw-r--r--pcbnew/class_drc_item.cpp137
-rw-r--r--pcbnew/class_edge_mod.cpp400
-rw-r--r--pcbnew/class_edge_mod.h145
-rw-r--r--pcbnew/class_footprint_wizard.cpp100
-rw-r--r--pcbnew/class_footprint_wizard.h190
-rw-r--r--pcbnew/class_marker_pcb.cpp144
-rw-r--r--pcbnew/class_marker_pcb.h140
-rw-r--r--pcbnew/class_mire.cpp211
-rw-r--r--pcbnew/class_mire.h112
-rw-r--r--pcbnew/class_module.cpp1307
-rw-r--r--pcbnew/class_module.h697
-rw-r--r--pcbnew/class_netclass.cpp266
-rw-r--r--pcbnew/class_netclass.h294
-rw-r--r--pcbnew/class_netinfo.h691
-rw-r--r--pcbnew/class_netinfo_item.cpp181
-rw-r--r--pcbnew/class_netinfolist.cpp300
-rw-r--r--pcbnew/class_pad.cpp994
-rw-r--r--pcbnew/class_pad.h597
-rw-r--r--pcbnew/class_pad_draw_functions.cpp762
-rw-r--r--pcbnew/class_pcb_layer_box_selector.cpp168
-rw-r--r--pcbnew/class_pcb_layer_box_selector.h105
-rw-r--r--pcbnew/class_pcb_layer_widget.cpp528
-rw-r--r--pcbnew/class_pcb_layer_widget.h158
-rw-r--r--pcbnew/class_pcb_text.cpp202
-rw-r--r--pcbnew/class_pcb_text.h148
-rw-r--r--pcbnew/class_text_mod.cpp550
-rw-r--r--pcbnew/class_text_mod.h196
-rw-r--r--pcbnew/class_track.cpp1655
-rw-r--r--pcbnew/class_track.h497
-rw-r--r--pcbnew/class_zone.cpp856
-rw-r--r--pcbnew/class_zone.h622
-rw-r--r--pcbnew/class_zone_settings.cpp135
-rw-r--r--pcbnew/class_zone_settings.h146
-rw-r--r--pcbnew/classpcb.cpp229
-rw-r--r--pcbnew/clean.cpp761
-rw-r--r--pcbnew/collectors.cpp501
-rw-r--r--pcbnew/collectors.h639
-rw-r--r--pcbnew/connect.cpp1003
-rw-r--r--pcbnew/connect.h263
-rw-r--r--pcbnew/controle.cpp355
-rw-r--r--pcbnew/cross-probing.cpp251
-rw-r--r--pcbnew/deltrack.cpp238
-rw-r--r--pcbnew/dialogs/dialog_SVG_print.cpp447
-rw-r--r--pcbnew/dialogs/dialog_SVG_print_base.cpp152
-rw-r--r--pcbnew/dialogs/dialog_SVG_print_base.fbp1337
-rw-r--r--pcbnew/dialogs/dialog_SVG_print_base.h78
-rw-r--r--pcbnew/dialogs/dialog_block_options_base.cpp106
-rw-r--r--pcbnew/dialogs/dialog_block_options_base.fbp1026
-rw-r--r--pcbnew/dialogs/dialog_block_options_base.h67
-rw-r--r--pcbnew/dialogs/dialog_cleaning_options.cpp48
-rw-r--r--pcbnew/dialogs/dialog_cleaning_options.h65
-rw-r--r--pcbnew/dialogs/dialog_cleaning_options_base.cpp69
-rw-r--r--pcbnew/dialogs/dialog_cleaning_options_base.fbp481
-rw-r--r--pcbnew/dialogs/dialog_cleaning_options_base.h59
-rw-r--r--pcbnew/dialogs/dialog_copper_zones.cpp718
-rw-r--r--pcbnew/dialogs/dialog_copper_zones_base.cpp273
-rw-r--r--pcbnew/dialogs/dialog_copper_zones_base.fbp3379
-rw-r--r--pcbnew/dialogs/dialog_copper_zones_base.h135
-rw-r--r--pcbnew/dialogs/dialog_create_array.cpp488
-rw-r--r--pcbnew/dialogs/dialog_create_array.h355
-rw-r--r--pcbnew/dialogs/dialog_create_array_base.cpp332
-rw-r--r--pcbnew/dialogs/dialog_create_array_base.fbp4716
-rw-r--r--pcbnew/dialogs/dialog_create_array_base.h118
-rw-r--r--pcbnew/dialogs/dialog_design_rules.cpp1082
-rw-r--r--pcbnew/dialogs/dialog_design_rules.h190
-rw-r--r--pcbnew/dialogs/dialog_design_rules_aux_helper_class.h78
-rw-r--r--pcbnew/dialogs/dialog_design_rules_base.cpp407
-rw-r--r--pcbnew/dialogs/dialog_design_rules_base.fbp3366
-rw-r--r--pcbnew/dialogs/dialog_design_rules_base.h117
-rw-r--r--pcbnew/dialogs/dialog_dimension_editor_base.cpp132
-rw-r--r--pcbnew/dialogs/dialog_dimension_editor_base.fbp1547
-rw-r--r--pcbnew/dialogs/dialog_dimension_editor_base.h75
-rw-r--r--pcbnew/dialogs/dialog_display_options.cpp186
-rw-r--r--pcbnew/dialogs/dialog_display_options.h43
-rw-r--r--pcbnew/dialogs/dialog_display_options_base.cpp143
-rw-r--r--pcbnew/dialogs/dialog_display_options_base.fbp1434
-rw-r--r--pcbnew/dialogs/dialog_display_options_base.h77
-rw-r--r--pcbnew/dialogs/dialog_drc.cpp647
-rw-r--r--pcbnew/dialogs/dialog_drc.h150
-rw-r--r--pcbnew/dialogs/dialog_drc_base.cpp256
-rw-r--r--pcbnew/dialogs/dialog_drc_base.fbp2480
-rw-r--r--pcbnew/dialogs/dialog_drc_base.h112
-rw-r--r--pcbnew/dialogs/dialog_drclistbox.h311
-rw-r--r--pcbnew/dialogs/dialog_edit_module_for_BoardEditor.cpp728
-rw-r--r--pcbnew/dialogs/dialog_edit_module_for_BoardEditor.h86
-rw-r--r--pcbnew/dialogs/dialog_edit_module_for_BoardEditor_base.cpp425
-rw-r--r--pcbnew/dialogs/dialog_edit_module_for_BoardEditor_base.fbp5383
-rw-r--r--pcbnew/dialogs/dialog_edit_module_for_BoardEditor_base.h145
-rw-r--r--pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp554
-rw-r--r--pcbnew/dialogs/dialog_edit_module_for_Modedit.h79
-rw-r--r--pcbnew/dialogs/dialog_edit_module_for_Modedit_base.cpp352
-rw-r--r--pcbnew/dialogs/dialog_edit_module_for_Modedit_base.fbp4416
-rw-r--r--pcbnew/dialogs/dialog_edit_module_for_Modedit_base.h127
-rw-r--r--pcbnew/dialogs/dialog_edit_module_text.cpp268
-rw-r--r--pcbnew/dialogs/dialog_edit_module_text.h53
-rw-r--r--pcbnew/dialogs/dialog_edit_module_text_base.cpp152
-rw-r--r--pcbnew/dialogs/dialog_edit_module_text_base.fbp1919
-rw-r--r--pcbnew/dialogs/dialog_edit_module_text_base.h77
-rw-r--r--pcbnew/dialogs/dialog_enum_pads.cpp46
-rw-r--r--pcbnew/dialogs/dialog_enum_pads.h49
-rw-r--r--pcbnew/dialogs/dialog_enum_pads_base.cpp71
-rw-r--r--pcbnew/dialogs/dialog_enum_pads_base.fbp662
-rw-r--r--pcbnew/dialogs/dialog_enum_pads_base.h58
-rw-r--r--pcbnew/dialogs/dialog_exchange_modules_base.cpp136
-rw-r--r--pcbnew/dialogs/dialog_exchange_modules_base.fbp1635
-rw-r--r--pcbnew/dialogs/dialog_exchange_modules_base.h76
-rw-r--r--pcbnew/dialogs/dialog_export_idf.cpp231
-rw-r--r--pcbnew/dialogs/dialog_export_idf_base.cpp134
-rw-r--r--pcbnew/dialogs/dialog_export_idf_base.fbp1223
-rw-r--r--pcbnew/dialogs/dialog_export_idf_base.h67
-rw-r--r--pcbnew/dialogs/dialog_export_vrml.cpp250
-rw-r--r--pcbnew/dialogs/dialog_export_vrml_base.cpp160
-rw-r--r--pcbnew/dialogs/dialog_export_vrml_base.fbp1677
-rw-r--r--pcbnew/dialogs/dialog_export_vrml_base.h81
-rw-r--r--pcbnew/dialogs/dialog_find.cpp196
-rw-r--r--pcbnew/dialogs/dialog_find.h57
-rw-r--r--pcbnew/dialogs/dialog_find_base.cpp73
-rw-r--r--pcbnew/dialogs/dialog_find_base.fbp645
-rw-r--r--pcbnew/dialogs/dialog_find_base.h59
-rw-r--r--pcbnew/dialogs/dialog_footprint_wizard_list.cpp110
-rw-r--r--pcbnew/dialogs/dialog_footprint_wizard_list.h47
-rw-r--r--pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp79
-rw-r--r--pcbnew/dialogs/dialog_footprint_wizard_list_base.fbp349
-rw-r--r--pcbnew/dialogs/dialog_footprint_wizard_list_base.h56
-rw-r--r--pcbnew/dialogs/dialog_fp_lib_table.cpp887
-rw-r--r--pcbnew/dialogs/dialog_fp_lib_table_base.cpp256
-rw-r--r--pcbnew/dialogs/dialog_fp_lib_table_base.fbp1763
-rw-r--r--pcbnew/dialogs/dialog_fp_lib_table_base.h86
-rw-r--r--pcbnew/dialogs/dialog_fp_plugin_options.cpp399
-rw-r--r--pcbnew/dialogs/dialog_fp_plugin_options_base.cpp158
-rw-r--r--pcbnew/dialogs/dialog_fp_plugin_options_base.fbp1027
-rw-r--r--pcbnew/dialogs/dialog_fp_plugin_options_base.h75
-rw-r--r--pcbnew/dialogs/dialog_freeroute_exchange.cpp208
-rw-r--r--pcbnew/dialogs/dialog_freeroute_exchange.h54
-rw-r--r--pcbnew/dialogs/dialog_freeroute_exchange_base.cpp101
-rw-r--r--pcbnew/dialogs/dialog_freeroute_exchange_base.fbp607
-rw-r--r--pcbnew/dialogs/dialog_freeroute_exchange_base.h63
-rw-r--r--pcbnew/dialogs/dialog_freeroute_exchange_help.html71
-rw-r--r--pcbnew/dialogs/dialog_gen_module_position_file_base.cpp121
-rw-r--r--pcbnew/dialogs/dialog_gen_module_position_file_base.fbp792
-rw-r--r--pcbnew/dialogs/dialog_gen_module_position_file_base.h67
-rw-r--r--pcbnew/dialogs/dialog_gendrill.cpp427
-rw-r--r--pcbnew/dialogs/dialog_gendrill.h113
-rw-r--r--pcbnew/dialogs/dialog_gendrill_base.cpp233
-rw-r--r--pcbnew/dialogs/dialog_gendrill_base.fbp2197
-rw-r--r--pcbnew/dialogs/dialog_gendrill_base.h85
-rw-r--r--pcbnew/dialogs/dialog_general_options.cpp152
-rw-r--r--pcbnew/dialogs/dialog_general_options.h53
-rw-r--r--pcbnew/dialogs/dialog_general_options_BoardEditor_base.cpp240
-rw-r--r--pcbnew/dialogs/dialog_general_options_BoardEditor_base.fbp2591
-rw-r--r--pcbnew/dialogs/dialog_general_options_BoardEditor_base.h103
-rw-r--r--pcbnew/dialogs/dialog_global_deletion.cpp275
-rw-r--r--pcbnew/dialogs/dialog_global_deletion.h55
-rw-r--r--pcbnew/dialogs/dialog_global_deletion_base.cpp145
-rw-r--r--pcbnew/dialogs/dialog_global_deletion_base.fbp1770
-rw-r--r--pcbnew/dialogs/dialog_global_deletion_base.h80
-rw-r--r--pcbnew/dialogs/dialog_global_edit_tracks_and_vias.cpp229
-rw-r--r--pcbnew/dialogs/dialog_global_edit_tracks_and_vias.h52
-rw-r--r--pcbnew/dialogs/dialog_global_edit_tracks_and_vias_base.cpp192
-rw-r--r--pcbnew/dialogs/dialog_global_edit_tracks_and_vias_base.fbp1399
-rw-r--r--pcbnew/dialogs/dialog_global_edit_tracks_and_vias_base.h74
-rw-r--r--pcbnew/dialogs/dialog_global_modules_fields_edition.cpp253
-rw-r--r--pcbnew/dialogs/dialog_global_modules_fields_edition_base.cpp141
-rw-r--r--pcbnew/dialogs/dialog_global_modules_fields_edition_base.fbp1494
-rw-r--r--pcbnew/dialogs/dialog_global_modules_fields_edition_base.h73
-rw-r--r--pcbnew/dialogs/dialog_global_pads_edition_base.cpp81
-rw-r--r--pcbnew/dialogs/dialog_global_pads_edition_base.fbp761
-rw-r--r--pcbnew/dialogs/dialog_global_pads_edition_base.h63
-rw-r--r--pcbnew/dialogs/dialog_graphic_item_properties.cpp339
-rw-r--r--pcbnew/dialogs/dialog_graphic_item_properties_base.cpp180
-rw-r--r--pcbnew/dialogs/dialog_graphic_item_properties_base.fbp2328
-rw-r--r--pcbnew/dialogs/dialog_graphic_item_properties_base.h84
-rw-r--r--pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp339
-rw-r--r--pcbnew/dialogs/dialog_graphic_items_options.cpp149
-rw-r--r--pcbnew/dialogs/dialog_graphic_items_options.h64
-rw-r--r--pcbnew/dialogs/dialog_graphic_items_options_base.cpp145
-rw-r--r--pcbnew/dialogs/dialog_graphic_items_options_base.fbp1931
-rw-r--r--pcbnew/dialogs/dialog_graphic_items_options_base.h77
-rw-r--r--pcbnew/dialogs/dialog_keepout_area_properties.cpp279
-rw-r--r--pcbnew/dialogs/dialog_keepout_area_properties_base.cpp102
-rw-r--r--pcbnew/dialogs/dialog_keepout_area_properties_base.fbp968
-rw-r--r--pcbnew/dialogs/dialog_keepout_area_properties_base.h75
-rw-r--r--pcbnew/dialogs/dialog_layer_selection_base.cpp224
-rw-r--r--pcbnew/dialogs/dialog_layer_selection_base.fbp1055
-rw-r--r--pcbnew/dialogs/dialog_layer_selection_base.h86
-rw-r--r--pcbnew/dialogs/dialog_layers_setup.cpp743
-rw-r--r--pcbnew/dialogs/dialog_layers_setup_base.cpp1633
-rw-r--r--pcbnew/dialogs/dialog_layers_setup_base.fbp18502
-rw-r--r--pcbnew/dialogs/dialog_layers_setup_base.h423
-rw-r--r--pcbnew/dialogs/dialog_mask_clearance.cpp118
-rw-r--r--pcbnew/dialogs/dialog_mask_clearance.h50
-rw-r--r--pcbnew/dialogs/dialog_mask_clearance_base.cpp130
-rw-r--r--pcbnew/dialogs/dialog_mask_clearance_base.fbp1670
-rw-r--r--pcbnew/dialogs/dialog_mask_clearance_base.h79
-rw-r--r--pcbnew/dialogs/dialog_modedit_options.cpp140
-rw-r--r--pcbnew/dialogs/dialog_modedit_options_base.cpp224
-rw-r--r--pcbnew/dialogs/dialog_modedit_options_base.fbp2998
-rw-r--r--pcbnew/dialogs/dialog_modedit_options_base.h91
-rw-r--r--pcbnew/dialogs/dialog_move_exact.cpp201
-rw-r--r--pcbnew/dialogs/dialog_move_exact.fbp1347
-rw-r--r--pcbnew/dialogs/dialog_move_exact.h99
-rw-r--r--pcbnew/dialogs/dialog_move_exact_base.cpp115
-rw-r--r--pcbnew/dialogs/dialog_move_exact_base.h74
-rw-r--r--pcbnew/dialogs/dialog_netlist.cpp487
-rw-r--r--pcbnew/dialogs/dialog_netlist.h97
-rw-r--r--pcbnew/dialogs/dialog_netlist_fbp.cpp200
-rw-r--r--pcbnew/dialogs/dialog_netlist_fbp.fbp1768
-rw-r--r--pcbnew/dialogs/dialog_netlist_fbp.h89
-rw-r--r--pcbnew/dialogs/dialog_non_copper_zones_properties.cpp268
-rw-r--r--pcbnew/dialogs/dialog_non_copper_zones_properties_base.cpp96
-rw-r--r--pcbnew/dialogs/dialog_non_copper_zones_properties_base.fbp795
-rw-r--r--pcbnew/dialogs/dialog_non_copper_zones_properties_base.h72
-rw-r--r--pcbnew/dialogs/dialog_orient_footprints.cpp162
-rw-r--r--pcbnew/dialogs/dialog_orient_footprints_base.cpp81
-rw-r--r--pcbnew/dialogs/dialog_orient_footprints_base.fbp741
-rw-r--r--pcbnew/dialogs/dialog_orient_footprints_base.h58
-rw-r--r--pcbnew/dialogs/dialog_pad_properties.cpp1247
-rw-r--r--pcbnew/dialogs/dialog_pad_properties_base.cpp640
-rw-r--r--pcbnew/dialogs/dialog_pad_properties_base.fbp8516
-rw-r--r--pcbnew/dialogs/dialog_pad_properties_base.h172
-rw-r--r--pcbnew/dialogs/dialog_pcb_text_properties.cpp309
-rw-r--r--pcbnew/dialogs/dialog_pcb_text_properties_base.cpp169
-rw-r--r--pcbnew/dialogs/dialog_pcb_text_properties_base.fbp2079
-rw-r--r--pcbnew/dialogs/dialog_pcb_text_properties_base.h81
-rw-r--r--pcbnew/dialogs/dialog_plot.cpp869
-rw-r--r--pcbnew/dialogs/dialog_plot.h81
-rw-r--r--pcbnew/dialogs/dialog_plot_base.cpp471
-rw-r--r--pcbnew/dialogs/dialog_plot_base.fbp4764
-rw-r--r--pcbnew/dialogs/dialog_plot_base.h146
-rw-r--r--pcbnew/dialogs/dialog_pns_diff_pair_dimensions.cpp83
-rw-r--r--pcbnew/dialogs/dialog_pns_diff_pair_dimensions.h52
-rw-r--r--pcbnew/dialogs/dialog_pns_diff_pair_dimensions_base.cpp103
-rw-r--r--pcbnew/dialogs/dialog_pns_diff_pair_dimensions_base.fbp1083
-rw-r--r--pcbnew/dialogs/dialog_pns_diff_pair_dimensions_base.h69
-rw-r--r--pcbnew/dialogs/dialog_pns_length_tuning_settings.cpp103
-rw-r--r--pcbnew/dialogs/dialog_pns_length_tuning_settings.h53
-rw-r--r--pcbnew/dialogs/dialog_pns_length_tuning_settings_base.cpp182
-rw-r--r--pcbnew/dialogs/dialog_pns_length_tuning_settings_base.fbp2269
-rw-r--r--pcbnew/dialogs/dialog_pns_length_tuning_settings_base.h84
-rw-r--r--pcbnew/dialogs/dialog_pns_settings.cpp75
-rw-r--r--pcbnew/dialogs/dialog_pns_settings.h43
-rw-r--r--pcbnew/dialogs/dialog_pns_settings_base.cpp161
-rw-r--r--pcbnew/dialogs/dialog_pns_settings_base.fbp1613
-rw-r--r--pcbnew/dialogs/dialog_pns_settings_base.h76
-rw-r--r--pcbnew/dialogs/dialog_print_for_modedit.cpp238
-rw-r--r--pcbnew/dialogs/dialog_print_for_modedit_base.cpp87
-rw-r--r--pcbnew/dialogs/dialog_print_for_modedit_base.fbp664
-rw-r--r--pcbnew/dialogs/dialog_print_for_modedit_base.h66
-rw-r--r--pcbnew/dialogs/dialog_print_using_printer.cpp518
-rw-r--r--pcbnew/dialogs/dialog_print_using_printer_base.cpp180
-rw-r--r--pcbnew/dialogs/dialog_print_using_printer_base.fbp1717
-rw-r--r--pcbnew/dialogs/dialog_print_using_printer_base.h86
-rw-r--r--pcbnew/dialogs/dialog_scripting.cpp52
-rw-r--r--pcbnew/dialogs/dialog_scripting.h39
-rw-r--r--pcbnew/dialogs/dialog_scripting_base.cpp43
-rw-r--r--pcbnew/dialogs/dialog_scripting_base.fbp278
-rw-r--r--pcbnew/dialogs/dialog_scripting_base.h49
-rw-r--r--pcbnew/dialogs/dialog_select_pretty_lib.cpp78
-rw-r--r--pcbnew/dialogs/dialog_select_pretty_lib.h58
-rw-r--r--pcbnew/dialogs/dialog_select_pretty_lib_base.cpp74
-rw-r--r--pcbnew/dialogs/dialog_select_pretty_lib_base.fbp645
-rw-r--r--pcbnew/dialogs/dialog_select_pretty_lib_base.h64
-rw-r--r--pcbnew/dialogs/dialog_set_grid.cpp307
-rw-r--r--pcbnew/dialogs/dialog_set_grid_base.cpp164
-rw-r--r--pcbnew/dialogs/dialog_set_grid_base.fbp1634
-rw-r--r--pcbnew/dialogs/dialog_set_grid_base.h76
-rw-r--r--pcbnew/dialogs/dialog_target_properties_base.cpp99
-rw-r--r--pcbnew/dialogs/dialog_target_properties_base.fbp930
-rw-r--r--pcbnew/dialogs/dialog_target_properties_base.h66
-rw-r--r--pcbnew/dialogs/dialog_track_via_properties.cpp364
-rw-r--r--pcbnew/dialogs/dialog_track_via_properties.h76
-rw-r--r--pcbnew/dialogs/dialog_track_via_properties_base.cpp231
-rw-r--r--pcbnew/dialogs/dialog_track_via_properties_base.fbp3112
-rw-r--r--pcbnew/dialogs/dialog_track_via_properties_base.h99
-rw-r--r--pcbnew/dialogs/dialog_track_via_size.cpp114
-rw-r--r--pcbnew/dialogs/dialog_track_via_size.h58
-rw-r--r--pcbnew/dialogs/dialog_track_via_size_base.cpp92
-rw-r--r--pcbnew/dialogs/dialog_track_via_size_base.fbp995
-rw-r--r--pcbnew/dialogs/dialog_track_via_size_base.h67
-rw-r--r--pcbnew/dialogs/wizard_3DShape_Libs_downloader.cpp543
-rw-r--r--pcbnew/dialogs/wizard_3DShape_Libs_downloader.h144
-rw-r--r--pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.cpp249
-rw-r--r--pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.fbp2149
-rw-r--r--pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.h88
-rw-r--r--pcbnew/dialogs/wizard_add_fplib.cpp863
-rw-r--r--pcbnew/dialogs/wizard_add_fplib.h279
-rw-r--r--pcbnew/dialogs/wizard_add_fplib_base.cpp247
-rw-r--r--pcbnew/dialogs/wizard_add_fplib_base.fbp2389
-rw-r--r--pcbnew/dialogs/wizard_add_fplib_base.h94
-rw-r--r--pcbnew/dimension.cpp466
-rw-r--r--pcbnew/drag.h205
-rw-r--r--pcbnew/dragsegm.cpp422
-rw-r--r--pcbnew/drc.cpp968
-rw-r--r--pcbnew/drc_clearance_test_functions.cpp1191
-rw-r--r--pcbnew/drc_marker_functions.cpp226
-rw-r--r--pcbnew/drc_stuff.h507
-rw-r--r--pcbnew/eagle_plugin.cpp2989
-rw-r--r--pcbnew/eagle_plugin.h231
-rw-r--r--pcbnew/edgemod.cpp436
-rw-r--r--pcbnew/edit.cpp1685
-rw-r--r--pcbnew/edit_pcb_text.cpp287
-rw-r--r--pcbnew/edit_track_width.cpp323
-rw-r--r--pcbnew/editedge.cpp367
-rw-r--r--pcbnew/editmod.cpp144
-rw-r--r--pcbnew/editrack-part2.cpp314
-rw-r--r--pcbnew/editrack.cpp1108
-rw-r--r--pcbnew/edtxtmod.cpp343
-rw-r--r--pcbnew/event_handlers_tracks_vias_sizes.cpp146
-rw-r--r--pcbnew/exporters/export_d356.cpp397
-rw-r--r--pcbnew/exporters/export_gencad.cpp1257
-rw-r--r--pcbnew/exporters/export_idf.cpp609
-rw-r--r--pcbnew/exporters/export_vrml.cpp1408
-rw-r--r--pcbnew/exporters/gen_drill_report_files.cpp455
-rw-r--r--pcbnew/exporters/gen_modules_placefile.cpp690
-rw-r--r--pcbnew/exporters/gendrill_Excellon_writer.cpp780
-rw-r--r--pcbnew/exporters/gendrill_Excellon_writer.h368
-rw-r--r--pcbnew/files.cpp869
-rw-r--r--pcbnew/footprint_wizard.cpp305
-rw-r--r--pcbnew/footprint_wizard_frame.cpp721
-rw-r--r--pcbnew/footprint_wizard_frame.h230
-rw-r--r--pcbnew/github/CMakeLists.txt50
-rw-r--r--pcbnew/github/avhttp-master.zipbin0 -> 173539 bytes
-rw-r--r--pcbnew/github/github_getliblist.cpp242
-rw-r--r--pcbnew/github/github_getliblist.h124
-rw-r--r--pcbnew/github/github_plugin.cpp599
-rw-r--r--pcbnew/github/github_plugin.h229
-rw-r--r--pcbnew/github/html_link_parser.cpp69
-rw-r--r--pcbnew/github/html_link_parser.h109
-rw-r--r--pcbnew/github/nginx.conf64
-rw-r--r--pcbnew/globaleditpad.cpp387
-rw-r--r--pcbnew/gpcb_plugin.cpp1127
-rw-r--r--pcbnew/gpcb_plugin.h102
-rw-r--r--pcbnew/help_common_strings.h26
-rw-r--r--pcbnew/highlight.cpp192
-rw-r--r--pcbnew/hotkeys.cpp476
-rw-r--r--pcbnew/hotkeys.h153
-rw-r--r--pcbnew/hotkeys_board_editor.cpp1205
-rw-r--r--pcbnew/hotkeys_module_editor.cpp416
-rw-r--r--pcbnew/import_dxf/dialog_dxf_import.cpp285
-rw-r--r--pcbnew/import_dxf/dialog_dxf_import.fbp1328
-rw-r--r--pcbnew/import_dxf/dialog_dxf_import.h64
-rw-r--r--pcbnew/import_dxf/dialog_dxf_import_base.cpp154
-rw-r--r--pcbnew/import_dxf/dialog_dxf_import_base.h77
-rw-r--r--pcbnew/import_dxf/dxf2brd_items.cpp824
-rw-r--r--pcbnew/import_dxf/dxf2brd_items.h192
-rw-r--r--pcbnew/import_dxf/examples/basic_ellipses.dxf2992
-rw-r--r--pcbnew/import_dxf/examples/test_outlines.dxf7264
-rw-r--r--pcbnew/initpcb.cpp128
-rw-r--r--pcbnew/invoke_pcb_dialog.h162
-rw-r--r--pcbnew/io_mgr.cpp272
-rw-r--r--pcbnew/io_mgr.h522
-rw-r--r--pcbnew/kicad_netlist_reader.cpp484
-rw-r--r--pcbnew/kicad_plugin.cpp2050
-rw-r--r--pcbnew/kicad_plugin.h226
-rw-r--r--pcbnew/layer_widget.cpp976
-rw-r--r--pcbnew/layer_widget.h434
-rw-r--r--pcbnew/legacy_netlist_reader.cpp264
-rw-r--r--pcbnew/legacy_plugin.cpp4793
-rw-r--r--pcbnew/legacy_plugin.h302
-rw-r--r--pcbnew/librairi.cpp850
-rw-r--r--pcbnew/loadcmp.cpp580
-rw-r--r--pcbnew/magnetic_tracks_functions.cpp306
-rw-r--r--pcbnew/menubar_modedit.cpp373
-rw-r--r--pcbnew/menubar_pcbframe.cpp682
-rw-r--r--pcbnew/minimun_spanning_tree.cpp145
-rw-r--r--pcbnew/minimun_spanning_tree.h101
-rw-r--r--pcbnew/modedit.cpp1005
-rw-r--r--pcbnew/modedit_onclick.cpp553
-rw-r--r--pcbnew/modedit_undo_redo.cpp174
-rw-r--r--pcbnew/modeditoptions.cpp151
-rw-r--r--pcbnew/module_editor_frame.h551
-rw-r--r--pcbnew/moduleframe.cpp954
-rw-r--r--pcbnew/modules.cpp512
-rw-r--r--pcbnew/modview_frame.cpp863
-rw-r--r--pcbnew/modview_frame.h187
-rw-r--r--pcbnew/move-drag_pads.cpp210
-rw-r--r--pcbnew/move_or_drag_track.cpp868
-rw-r--r--pcbnew/muonde.cpp1105
-rw-r--r--pcbnew/muwave_command.cpp126
-rw-r--r--pcbnew/netlist.cpp319
-rw-r--r--pcbnew/netlist_reader.cpp205
-rw-r--r--pcbnew/netlist_reader.h404
-rw-r--r--pcbnew/onleftclick.cpp602
-rw-r--r--pcbnew/onrightclick.cpp1095
-rw-r--r--pcbnew/pad_edition_functions.cpp276
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/CMakeLists.txt32
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/examples/files.txt7
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.cpp553
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.h104
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcad_plugin.cpp91
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcad_plugin.h60
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb.cpp937
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb.h92
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_arc.cpp193
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_arc.h61
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_callbacks.h64
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_component.cpp80
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_component.h87
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_copper_pour.cpp112
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_copper_pour.h54
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_cutout.cpp74
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_cutout.h53
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_keepout.cpp76
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_keepout.h52
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_line.cpp166
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_line.h62
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp640
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_module.h75
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_net.cpp104
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_net.h68
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp363
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_pad.h64
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_pad_shape.cpp142
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_pad_shape.h61
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_plane.cpp95
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_plane.h53
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp253
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_polygon.h75
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_text.cpp138
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_text.h59
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_via.cpp139
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_via.h54
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_via_shape.cpp88
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/pcb_via_shape.h52
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/s_expr_loader.cpp116
-rw-r--r--pcbnew/pcad2kicadpcb_plugin/s_expr_loader.h37
-rw-r--r--pcbnew/pcb_base_edit_frame.cpp95
-rw-r--r--pcbnew/pcb_base_edit_frame.h148
-rw-r--r--pcbnew/pcb_draw_panel_gal.cpp436
-rw-r--r--pcbnew/pcb_draw_panel_gal.h97
-rw-r--r--pcbnew/pcb_netlist.cpp249
-rw-r--r--pcbnew/pcb_netlist.h360
-rw-r--r--pcbnew/pcb_painter.cpp1026
-rw-r--r--pcbnew/pcb_painter.h219
-rw-r--r--pcbnew/pcb_parser.cpp3073
-rw-r--r--pcbnew/pcb_parser.h327
-rw-r--r--pcbnew/pcb_plot_params.cpp579
-rw-r--r--pcbnew/pcb_plot_params.h292
-rw-r--r--pcbnew/pcb_plot_params_parser.h73
-rw-r--r--pcbnew/pcbframe.cpp1087
-rw-r--r--pcbnew/pcbnew.cpp380
-rw-r--r--pcbnew/pcbnew.h114
-rw-r--r--pcbnew/pcbnew.icnsbin0 -> 182211 bytes
-rw-r--r--pcbnew/pcbnew.rc3
-rw-r--r--pcbnew/pcbnew_config.cpp553
-rw-r--r--pcbnew/pcbnew_config.h17
-rw-r--r--pcbnew/pcbnew_doc.icnsbin0 -> 138959 bytes
-rw-r--r--pcbnew/pcbnew_id.h399
-rw-r--r--pcbnew/pcbplot.cpp426
-rw-r--r--pcbnew/pcbplot.h281
-rw-r--r--pcbnew/plot_board_layers.cpp1040
-rw-r--r--pcbnew/plot_brditems_plotter.cpp688
-rw-r--r--pcbnew/plotcontroller.h129
-rw-r--r--pcbnew/plugin.cpp147
-rw-r--r--pcbnew/print_board_functions.cpp389
-rw-r--r--pcbnew/printout_controler.cpp353
-rw-r--r--pcbnew/printout_controler.h129
-rw-r--r--pcbnew/protos.h82
-rw-r--r--pcbnew/ratsnest.cpp929
-rw-r--r--pcbnew/ratsnest_data.cpp1271
-rw-r--r--pcbnew/ratsnest_data.h781
-rw-r--r--pcbnew/ratsnest_viewitem.cpp120
-rw-r--r--pcbnew/ratsnest_viewitem.h77
-rw-r--r--pcbnew/router/CMakeLists.txt47
-rw-r--r--pcbnew/router/direction.h357
-rw-r--r--pcbnew/router/length_tuner_tool.cpp311
-rw-r--r--pcbnew/router/length_tuner_tool.h54
-rw-r--r--pcbnew/router/pns_algo_base.cpp32
-rw-r--r--pcbnew/router/pns_algo_base.h62
-rw-r--r--pcbnew/router/pns_diff_pair.cpp870
-rw-r--r--pcbnew/router/pns_diff_pair.h495
-rw-r--r--pcbnew/router/pns_diff_pair_placer.cpp859
-rw-r--r--pcbnew/router/pns_diff_pair_placer.h299
-rw-r--r--pcbnew/router/pns_dp_meander_placer.cpp406
-rw-r--r--pcbnew/router/pns_dp_meander_placer.h146
-rw-r--r--pcbnew/router/pns_dragger.cpp336
-rw-r--r--pcbnew/router/pns_dragger.h126
-rw-r--r--pcbnew/router/pns_index.h315
-rw-r--r--pcbnew/router/pns_item.cpp87
-rw-r--r--pcbnew/router/pns_item.h350
-rw-r--r--pcbnew/router/pns_itemset.cpp138
-rw-r--r--pcbnew/router/pns_itemset.h227
-rw-r--r--pcbnew/router/pns_joint.h259
-rw-r--r--pcbnew/router/pns_layerset.h129
-rw-r--r--pcbnew/router/pns_line.cpp889
-rw-r--r--pcbnew/router/pns_line.h299
-rw-r--r--pcbnew/router/pns_line_placer.cpp1112
-rw-r--r--pcbnew/router/pns_line_placer.h397
-rw-r--r--pcbnew/router/pns_logger.cpp203
-rw-r--r--pcbnew/router/pns_logger.h59
-rw-r--r--pcbnew/router/pns_meander.cpp617
-rw-r--r--pcbnew/router/pns_meander.h514
-rw-r--r--pcbnew/router/pns_meander_placer.cpp268
-rw-r--r--pcbnew/router/pns_meander_placer.h118
-rw-r--r--pcbnew/router/pns_meander_placer_base.cpp187
-rw-r--r--pcbnew/router/pns_meander_placer_base.h165
-rw-r--r--pcbnew/router/pns_meander_skew_placer.cpp174
-rw-r--r--pcbnew/router/pns_meander_skew_placer.h65
-rw-r--r--pcbnew/router/pns_node.cpp1288
-rw-r--r--pcbnew/router/pns_node.h487
-rw-r--r--pcbnew/router/pns_optimizer.cpp1224
-rw-r--r--pcbnew/router/pns_optimizer.h181
-rw-r--r--pcbnew/router/pns_placement_algo.h185
-rw-r--r--pcbnew/router/pns_router.cpp1084
-rw-r--r--pcbnew/router/pns_router.h285
-rw-r--r--pcbnew/router/pns_routing_settings.cpp105
-rw-r--r--pcbnew/router/pns_routing_settings.h158
-rw-r--r--pcbnew/router/pns_segment.h130
-rw-r--r--pcbnew/router/pns_shove.cpp1375
-rw-r--r--pcbnew/router/pns_shove.h159
-rw-r--r--pcbnew/router/pns_sizes_settings.cpp167
-rw-r--r--pcbnew/router/pns_sizes_settings.h113
-rw-r--r--pcbnew/router/pns_solid.cpp77
-rw-r--r--pcbnew/router/pns_solid.h107
-rw-r--r--pcbnew/router/pns_tool_base.cpp308
-rw-r--r--pcbnew/router/pns_tool_base.h82
-rw-r--r--pcbnew/router/pns_topology.cpp433
-rw-r--r--pcbnew/router/pns_topology.h72
-rw-r--r--pcbnew/router/pns_tune_status_popup.cpp67
-rw-r--r--pcbnew/router/pns_tune_status_popup.h44
-rw-r--r--pcbnew/router/pns_utils.cpp244
-rw-r--r--pcbnew/router/pns_utils.h62
-rw-r--r--pcbnew/router/pns_via.cpp109
-rw-r--r--pcbnew/router/pns_via.h162
-rw-r--r--pcbnew/router/pns_walkaround.cpp273
-rw-r--r--pcbnew/router/pns_walkaround.h149
-rw-r--r--pcbnew/router/range.h93
-rw-r--r--pcbnew/router/ranged_num.h52
-rw-r--r--pcbnew/router/router_preview_item.cpp343
-rw-r--r--pcbnew/router/router_preview_item.h127
-rw-r--r--pcbnew/router/router_tool.cpp854
-rw-r--r--pcbnew/router/router_tool.h63
-rw-r--r--pcbnew/router/time_limit.cpp51
-rw-r--r--pcbnew/router/time_limit.h43
-rw-r--r--pcbnew/router/trace.h46
-rw-r--r--pcbnew/scripting/TODO.txt11
-rw-r--r--pcbnew/scripting/board.i117
-rw-r--r--pcbnew/scripting/board_item.i98
-rwxr-xr-xpcbnew/scripting/examples/createFPC40.py60
-rwxr-xr-xpcbnew/scripting/examples/createPcb.py48
-rw-r--r--pcbnew/scripting/examples/hidePcbValuesShowReferences.py14
-rwxr-xr-xpcbnew/scripting/examples/listPcb.py66
-rwxr-xr-xpcbnew/scripting/examples/listPcbLibrary.py12
-rw-r--r--pcbnew/scripting/module.i110
-rw-r--r--pcbnew/scripting/pcbnew.i169
-rw-r--r--pcbnew/scripting/pcbnew_footprint_wizards.cpp361
-rw-r--r--pcbnew/scripting/pcbnew_footprint_wizards.h71
-rw-r--r--pcbnew/scripting/pcbnew_scripting_helpers.cpp109
-rw-r--r--pcbnew/scripting/pcbnew_scripting_helpers.h47
-rw-r--r--pcbnew/scripting/plugins.i35
-rw-r--r--pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py156
-rw-r--r--pcbnew/scripting/plugins/FootprintWizardDrawingAids.py523
-rw-r--r--pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py330
-rw-r--r--pcbnew/scripting/plugins/PadArray.py275
-rw-r--r--pcbnew/scripting/plugins/__init__.py1
-rw-r--r--pcbnew/scripting/plugins/bga_wizard.py98
-rw-r--r--pcbnew/scripting/plugins/circular_pad_array_wizard.py83
-rw-r--r--pcbnew/scripting/plugins/qfp_wizard.py125
-rw-r--r--pcbnew/scripting/plugins/sdip_wizard.py237
-rw-r--r--pcbnew/scripting/plugins/touch_slider_wizard.py205
-rw-r--r--pcbnew/scripting/plugins/uss39_barcode.py149
-rw-r--r--pcbnew/scripting/plugins/zip_wizard.py201
-rw-r--r--pcbnew/scripting/python_console_frame.h105
-rw-r--r--pcbnew/scripting/tests/test1.py11
-rw-r--r--pcbnew/scripting/tests/test2.py8
-rw-r--r--pcbnew/scripting/units.i78
-rw-r--r--pcbnew/sel_layer.cpp429
-rw-r--r--pcbnew/specctra.cpp3793
-rw-r--r--pcbnew/specctra.h4004
-rw-r--r--pcbnew/specctra.keywords392
-rw-r--r--pcbnew/specctra_export.cpp2247
-rw-r--r--pcbnew/specctra_import.cpp564
-rw-r--r--pcbnew/specctra_test.cpp108
-rw-r--r--pcbnew/swap_layers.cpp430
-rw-r--r--pcbnew/target_edit.cpp288
-rw-r--r--pcbnew/tool_modedit.cpp279
-rw-r--r--pcbnew/tool_modview.cpp218
-rw-r--r--pcbnew/tool_onrightclick.cpp107
-rw-r--r--pcbnew/tool_pcb.cpp814
-rw-r--r--pcbnew/toolbars_update_user_interface.cpp241
-rw-r--r--pcbnew/tools/bright_box.cpp61
-rw-r--r--pcbnew/tools/bright_box.h79
-rw-r--r--pcbnew/tools/common_actions.cpp726
-rw-r--r--pcbnew/tools/common_actions.h337
-rw-r--r--pcbnew/tools/conditional_menu.cpp109
-rw-r--r--pcbnew/tools/conditional_menu.h221
-rw-r--r--pcbnew/tools/drawing_tool.cpp1541
-rw-r--r--pcbnew/tools/drawing_tool.h200
-rw-r--r--pcbnew/tools/edit_constraints.cpp191
-rw-r--r--pcbnew/tools/edit_constraints.h267
-rw-r--r--pcbnew/tools/edit_points.cpp227
-rw-r--r--pcbnew/tools/edit_points.h527
-rw-r--r--pcbnew/tools/edit_tool.cpp1099
-rw-r--r--pcbnew/tools/edit_tool.h238
-rw-r--r--pcbnew/tools/grid_helper.cpp393
-rw-r--r--pcbnew/tools/grid_helper.h108
-rw-r--r--pcbnew/tools/grid_menu.cpp68
-rw-r--r--pcbnew/tools/grid_menu.h44
-rw-r--r--pcbnew/tools/module_tools.cpp608
-rw-r--r--pcbnew/tools/module_tools.h117
-rw-r--r--pcbnew/tools/pcb_editor_control.cpp792
-rw-r--r--pcbnew/tools/pcb_editor_control.h116
-rw-r--r--pcbnew/tools/pcbnew_control.cpp1014
-rw-r--r--pcbnew/tools/pcbnew_control.h109
-rw-r--r--pcbnew/tools/picker_tool.cpp115
-rw-r--r--pcbnew/tools/picker_tool.h127
-rw-r--r--pcbnew/tools/placement_tool.cpp354
-rw-r--r--pcbnew/tools/placement_tool.h89
-rw-r--r--pcbnew/tools/point_editor.cpp890
-rw-r--r--pcbnew/tools/point_editor.h120
-rw-r--r--pcbnew/tools/selection_area.cpp63
-rw-r--r--pcbnew/tools/selection_area.h84
-rw-r--r--pcbnew/tools/selection_conditions.cpp256
-rw-r--r--pcbnew/tools/selection_conditions.h193
-rw-r--r--pcbnew/tools/selection_tool.cpp1459
-rw-r--r--pcbnew/tools/selection_tool.h361
-rw-r--r--pcbnew/tools/size_menu.cpp85
-rw-r--r--pcbnew/tools/size_menu.h55
-rw-r--r--pcbnew/tools/tools_common.cpp54
-rw-r--r--pcbnew/tools/zoom_menu.cpp71
-rw-r--r--pcbnew/tools/zoom_menu.h44
-rw-r--r--pcbnew/tr_modif.cpp324
-rw-r--r--pcbnew/tracepcb.cpp314
-rw-r--r--pcbnew/xchgmod.cpp561
-rw-r--r--pcbnew/zone_filling_algorithm.cpp249
-rw-r--r--pcbnew/zones.h102
-rw-r--r--pcbnew/zones_by_polygon.cpp968
-rw-r--r--pcbnew/zones_by_polygon_fill_functions.cpp188
-rw-r--r--pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp508
-rw-r--r--pcbnew/zones_convert_to_polygons_aux_functions.cpp251
-rw-r--r--pcbnew/zones_functions_for_undo_redo.cpp310
-rw-r--r--pcbnew/zones_functions_for_undo_redo.h72
-rw-r--r--pcbnew/zones_polygons_insulated_copper_islands.cpp102
-rw-r--r--pcbnew/zones_polygons_test_connections.cpp409
-rw-r--r--pcbnew/zones_test_and_combine_areas.cpp623
1112 files changed, 505343 insertions, 0 deletions
diff --git a/AUTHORS.txt b/AUTHORS.txt
new file mode 100644
index 0000000..f447c6d
--- /dev/null
+++ b/AUTHORS.txt
@@ -0,0 +1,75 @@
+* Copyright (C) 1992-2015 Jean-Pierre Charras
+* Copyright (C) 1992-2015 Kicad Developers Team
+* under GNU General Public License (see copyright.txt)
+
+== Main Authors
+Jean-Pierre Charras <jean-pierre.charras[at]gipsa-lab-dot-inpg-dot-fr>
+Dick Hollenbeck <dick[at]softplc-dot-com>
+Wayne Stambaugh <stambaughw[at]gmail-dot-com>
+
+
+== Contributors
+Hauptmech <hauptmech[at]gmail-dot-com>
+Jerry Jacobs <xor.gate.engineering[at]gmail-dot-com>
+Jonas Diemer <diemer[at]gmx-dot-de>
+Lorenzo <lomarcan[at]tin-dot-it>
+Marco Serantoni <marco.serantoni[at]gmail-dot-com> (OSX maintener)
+Rok Markovic <rok[at]kanardia.eu>
+Tim Hanson <sideskate[at]gmail-dot-com>
+Vesa Solonen <vesa.solonen[at]hut-dot-fi>
+Alexander Zakamaldin <zaka62[at]mail-dot-ru>
+Miguel Angel Ajo Pelayo <miguelangel[at]nbee-dot-es> (Python Scripting)
+Alexander Lunev <al.lunev[at]yahoo-dot-com> (Pcad to Kicad converter)
+Jacobo Aragunde Perez <jaragunde[at]igalia-dot-com> for Igalia and the CERN
+Brian Sidebotham <brian.sidebotham[at]gmail-dot-com>
+Maciej Sumiński <maciej.suminski[at]cern-dot-ch>
+Tomasz Wlostowski <tomasz.wlostowski[at]cern-dot-ch>
+Henner Zeller <h.zeller[at]acm-dot-org>
+Mark Roszko <mark.roszko[at]gmail-dot-com>
+Daniel Majewski <lordblick[at]gmail-dot-com>
+Konstantin Baranovskiy <baranovskiykonstantin[at]gmail-dot-com>
+Torsten Hüter <torstenhtr[at]gmx-dot-de>
+Nick Østergaard <oe.nick[at]gmail-dot-com>
+Andrew Zonenberg <azonenberg[at]drawersteak-dot-com>
+Cirilo Bernardo <cirilo_bernardo[at]yahoo-dot-com>
+Adam Wolf <adamwolf[at]feelslikeburning-dot-com>
+Bernhard Stegmaier <stegmaier[at]sw-systems-dot-de>
+Chris Pavlina <pavlina.chris[at]gmail-dot-com>
+Simon Richter <Simon.Richter[at]hogyros-dot-de>
+Mario Luzeiro <mrluzeiro[at]ua-dot-pt>
+Mateusz Skowroński <skowri[at]gmail-dot-com>
+See also CHANGELOG.txt for contributors.
+
+
+== Document Writers
+Jean-Pierre Charras <jean-pierre.charras[at]gipsa-lab.inpg-dot-fr>
+Igor Plyatov <plyatov[at]gmail-dot-com>
+Fabrizio Tappero <fabrizio-dot-tappero[at]gmail-dot-com>
+Marco Ciampa <ciampix[at]libero-dot-it>
+Wayne Stambaugh <stambaughw[at]gmail-dot-com
+
+
+== Translators
+Czech (CZ) Martin Kratoška <martin[at]ok1rr-dot-com>
+Dutch (NL) Jerry Jacobs <xor.gate.engineering[at]gmail-dot-com>
+Finnish (FI) Vesa Solonen <vesa.solonen[at]hut-dot-fi>
+French (FR) Jean-Pierre Charras <jean-pierre.charras[at]inpg-dot-fr>
+Polish (PL) Mateusz Skowro¿ski <skowri[at]gmail-dot-com>
+Polish (PL) Kerusey Karyu <keruseykaryu[at]o2.pl>
+Portuguese (PT) Renie Marquet <reniemarquet[at]uol-dot-com-dot-br>"
+Russian (RU) Igor Plyatov <plyatov[at]gmail-dot-com>
+Russian (RU) Andrey Fedorushkov <andrf[at]mail-dot-ru>
+Russian (RU) Eldar Khayrullin <eldar.khayrullin[at]mail-dot-ru>
+Spanish (ES) Pedro Martin del Valle <pkicad[at]yahoo-dot-es>
+Spanish (ES) Iñigo Zuluaga <inigo_zuluaga[at]yahoo-dot-es>
+German (DE) Rafael Sokolowski <Rafael.Sokolowski[at]web-dot-de
+Japanese (JA) Kenta Yonekura <yoneken[at]kicad-dot-jp>
+
+Remy Halvick, David Briscoe, Dominique Laigle, Paul Burke
+
+
+== Programm credits for icons and others
+Icons by Iñigo Zuluagaz <inigo_zuluaga[at]yahoo-dot-es>
+New Icons by Fabrizio Tappero <fabrizio-dot-tappero[at]gmail-dot-com>
+3D modules by Renie Marquet <reniemarquet[at]uol-dot-com-dot-br>
+3D modules by Christophe Boschat <nox454[at]hotmail-dot-fr>
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
new file mode 100644
index 0000000..2bce31b
--- /dev/null
+++ b/CHANGELOG.txt
@@ -0,0 +1,204 @@
+KiCad ChangeLog 2012
+====================
+
+Please add newer entries at the top, list the date and your name with
+email address.
+
+2012-Nov-19 UPDATE Dick Hollenbeck <dick@softplc.com>
+================================================================================
+Eliminate many assumptions in Pcbnew's library manager, pertaining to locality of libraries and
+their type, by using the more abstract PLUGIN::Footprint*() functions.
+
+This is an intermediate phase only, other changes will be necessary as library table support comes in.
+Encapsulate usage of library path searching, since that will go away as library table support comes in.
+Add FOOTPRINT_EDIT_FRAME::{get,set}LibPath() and FOOTPRINT_EDIT_FRAME::{get,set}LibNickName() functions
+to provide this encapsulation.
+
+2012-Nov-14 UPDATE Dick Hollenbeck <dick@softplc.com>
+================================================================================
+1) Switch to boost hashtable support from wx macros which did not handle std::string.
+ This required the additional compiler command line option "-std=c++0x".
+
+2) Switch to unique_ptr from auto_ptr which is C++ deprecated.
+
+3) Change to new English layer names per mailing list discussion, see class_board.cpp.
+
+4) When saving to *.kicad_pcb or *.kicad_mod, identify opportunities to use wildcard
+ layer sets, for pads so far.
+
+5) Switch to two std::string hashtables in pcb_parser.cpp, away from one wxString based one
+ for layer names and layer sets mapping. One hashtable holds the mask, the other the index.
+ Layer sets are only in the mask table.
+
+6) Move "LOCALE_IO toggle" into PCB_IO::Format() since it is a public API function and
+ caller should find it as convenient as possible to use. LOCALE_IO should handle
+ nesting OK in the case where public Format() is called from one of the Footprint*()
+ functions.
+
+7) Drop support for "export module to new library". Creating new libraries will have to
+ be handled in concert with library table entries, and we've talked recently about
+ creating a better footprint library manager, one that resides in a DLL/DSO. So
+ this kind of functionality needs to be handled in there in the near future.
+
+8) Change name of exported PCB_IO module/footprint to *.kicad_mod and not *.emp.
+
+
+
+2012-May-5 UPDATE Jerry Jacobs <jerry@xor-gate.org>
+================================================================================
+++ common
+ * Update about dialog to more native size so the notebook is not squeezed
+ * Increment copyright year to 2012
+ * Fix mousezoom jumping to center for Mac OS X and other platforms
+ * Remove lowercase application name because Mac OS X menubar was inconsitent
+
+2012-Mar-11 UPDATE Dick Hollenbeck <dick@softplc.com>
+================================================================================
+++pcbnew
+ * Add PCB_EDIT_FRAME::syncLayerVisibilities(), PCB_LAYER_MANAGER::SyncLayerVisibilities().
+ * Save all visibilities, layer and render, in BOARD and restore on load.
+
+
+2012-Feb-19 UPDATE Dick Hollenbeck <dick@softplc.com>
+================================================================================
+++pcbnew
+ * Remove virtual BOARD_ITEM::{Get,Set}Position() which in turn means all
+ derived classes' implementations of these functions become non virtual and
+ can be truly _inlined_ for speed! All GetPosition() in derived classes were also
+ changed to return const wxPoint&, that is, a reference rather than a
+ full copy of the position wxPoint. There was no need for polymorphism in
+ {Get,Set}Position() since we never call these functions via generic pointer.
+ * Remove BOARD::{Get,Set}Position() since they were only there to satisfy
+ the pure virtuals established in BOARD_ITEM, which are now gone.
+ * Added const wxPoint& CPolyLine::GetPos(), made CPolyLine::Get{X,Y}() inline.
+ * Derive CPolyPt from wxPoint so we can return "const wxPoint&" from
+ CPolyLine::GetPos().
+
+
+2012-Feb-19 UPDATE Dick Hollenbeck <dick@softplc.com>
+================================================================================
+++pcbnew
+ * remove global g_Pad_Master and put it into BOARD_DESIGN_SETTINGS
+ which is in turn already within BOARD.
+ * encapsulate class D_PAD with accessors, making data private.
+ * make D_PAD::GetBoundingRadius() do its longer calculation lazily, based on
+ m_boundingRadius == -1.
+
+
+2012-Feb-5 UPDATE Dick Hollenbeck <dick@softplc.com>
+================================================================================
+++pcbnew
+ * Changed classs ZONE_SETTING to class ZONE_SETTINGS, better English.
+ * Changed ZONE_SETTINGS::Import() to operator << ( ZONE_CONTAINER )
+ * move globals into BOARD:
+ bool g_Zone_45_Only, is now in BOARD::m_zoneSettings.m_Zone_45_Only
+ ZONE_SETTINGS g_Zone_Default_Setting is now in BOARD::m_zoneSettings
+ * Added BOARD::{Get,Set}ZoneSettings().
+ * Added PCB_BASE_FRAME::{Get,Set}ZoneSettings().
+ * Save/load BOARD::m_zoneSettings.m_Zone_45_Only to/from BOARD file.
+ * Removed PCB_EDIT_FRAME::InstallDialogNonCopperZonesEditor() in favor of
+ ::InvokeNonCopperZonesEditor() declared in zones.h
+ * Added ::InvokeCopperZonesEditor() declared in zones.h
+ * Removed dialog_copper_zones.h since DIALOG class is now declared in *.cpp.
+ * Renamed to enum ZONE_EDIT_T in zones.h
+ * SetVisibleAlls() is not called as it was in two previous cases for several
+ reasons. BOARD_DESIGN_SETTINGS constructor controls what is visible initially,
+ and in the near future so will the *.brd file. I believe the user should
+ have visibility setting rentention accross editing sessions of zones,
+ fields, etc.
+ * BOARD_DESIGN_SETTINGS constructor initializes hidden text as not visible.
+ * Added PCB_EDIT_FRAME::syncRenderStates() and PCB_LAYER_WIDGET::SyncRenderStates()
+ so the checkboxes can be set after loading a BOARD file containing previous
+ visibility settings.
+
+2012-Feb-2 UPDATE Dick Hollenbeck <dick@softplc.com>
+================================================================================
+++pcbnew
+ * move globals into BOARD
+ -wxSize g_ModuleTextSize; /* Default footprint texts size */
+ -int g_ModuleSegmentWidth;
+ -int g_ModuleTextWidth;
+ But now the module editor is left hanging. I'll have to figure out
+ a way to pass from board editor to module editor these values, still.
+
+
+2012-Feb-01, UPDATE Jean-Pierre Charras <jp.charras@wanadoo.fr>
+================================================================================
+Pcbnew:
+Cvpcb:
+ more about new netlist format:
+ Cvpcb can now read new netlist format.
+ There is a big change in Cvpcb: now Cvpcb just creates or updates a .cmp file
+ Before this change, Cvpcb recreated the netlist (adding footprint info)
+ and updated the .cmp file.
+ But there is no reason to modify the netlist, because Pcbnew uses always the .cmp file
+ (when exists) to know the footprint selection for components.
+ Currently the netlist is used only when the corresponding .cmp file is not fount
+ to select footprints.
+ So users should not notice this important change.
+
+2012-Jan-26, UPDATE Jean-Pierre Charras <jp.charras@wanadoo.fr>
+================================================================================
+Pcbnew:
+ First draft to use a new netlist format (using S expressions)
+ Eeschema can generate this netlist format.
+ Pcbnew can use (automatic identification) the current format or the new format.
+ Cvpcb does not use yet the new format.
+ To do:
+ New format in Cvpcb: how to use the .cmp file with the new netlist format
+
+
+2012-Jan-22 UPDATE Dick Hollenbeck <dick@softplc.com>
+================================================================================
+++all
+ * Switch to C++'s true and false and away from C" TRUE and FALSE.
+ * Enhance class PLUGIN's comments to improve their value as instructional.
+ * Switch #includes from "file.h" to <file.h>, and fiddle with search paths
+ by using include_directories(BEFORE ...)
+ * dialog_page_settings did not have symmetrical space on its right border.
+ And it now remembers it last position and size within a program session.
+ * base_screen.cpp is now compiled twice, once for {pcbnew,cvpcb} and once
+ for eeschema, in preparation for "compile time" support of internal units
+ rather than "runtime" support.
+
+
+2012-Jan-15 UPDATE Dick Hollenbeck <dick@softplc.com>
+================================================================================
+++all
+ Add "portrait" support to the page size settings for all standard paper
+ sizes. Tested with postscript output only. Required minor file format changes
+ to reflect the "portrait" setting. common/dialogs/dialog_page_settings.cpp
+ uses a checkbox but its name is "Landscape", which is inverted from portrait,
+ but since it is the more common choice, I used that rather than portrait.
+ The tooltip for that checkbox makes it clear. No portrait mode is supported
+ for "User" paper size.
+
+
+2012-Jan-9 UPDATE Dick Hollenbeck <dick@softplc.com>
+================================================================================
+++all
+ * Carve out TITLE_BLOCK from BASE_SCREEN
+ * Add include/hashtables.h and put class PROPERTIES in there.
+ Change PROPERTIES to use "const char*" as the key instead of wxString.
+++eeschema
+ * Add shim class SCH_BASE_FRAME which introduces the data model SCH_SCREEN
+ to the frame EESCHEMA frame class hierarchy and allows sharing of:
+ SCH_SCREEN* GetScreen() const; // overload EDA_DRAW_FRAME
+ void SetPageSettings( const PAGE_INFO& aPageSettings ); // overload EDA_DRAW_FRAME
+ const PAGE_INFO& GetPageSettings () const; // overload EDA_DRAW_FRAME
+ const wxSize GetPageSizeIU() const; // overload EDA_DRAW_FRAME
+ const wxPoint& GetOriginAxisPosition() const; // overload EDA_DRAW_FRAME
+ void SetOriginAxisPosition( const wxPoint& aPosition ); // overload EDA_DRAW_FRAME
+ const TITLE_BLOCK& GetTitleBlock() const; // overload EDA_DRAW_FRAME
+ void SetTitleBlock( const TITLE_BLOCK& aTitleBlock ); // overload EDA_DRAW_FRAME
+
+
+2012-Jan-5 UPDATE Dick Hollenbeck <dick@softplc.com>
+================================================================================
+++all
+ Ki_PageDescr was re-written as a proper C++ class and renamed to PAGE_INFO.
+ It describes paper. The m_Offset field was dropped since it was only used
+ in HPGL plotting within EESCHEMA. PAGE_INFO instance was moved out of
+ BASE_SCREEN (which is on its way out) into both SCH_SCREEN and BOARD.
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..09932cc
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,932 @@
+#
+# This program source code file is part of KICAD, a free EDA CAD application.
+#
+# Copyright (C) 2007-2016 Kicad Developers, see AUTHORS.txt for contributors.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, you may find one here:
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# or you may search the http://www.gnu.org website for the version 2 license,
+# or you may write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+
+# Default to CMAKE_BUILD_TYPE = Release unless overridden on command line
+# http://www.cmake.org/pipermail/cmake/2008-September/023808.html
+if( DEFINED CMAKE_BUILD_TYPE )
+ set( CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Set to either \"Release\" or \"Debug\"" )
+else()
+ set( CMAKE_BUILD_TYPE Release CACHE STRING "Set to either \"Release\" or \"Debug\"" )
+endif()
+
+project( kicad )
+
+cmake_minimum_required( VERSION 2.8.4 FATAL_ERROR )
+# because of http://public.kitware.com/Bug/view.php?id=10395
+
+# Path to local CMake modules.
+set( CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules )
+
+#
+# KiCad build options should be added below.
+#
+# If you add a new build option, please add it's state to the CopyVersionInfoToClipboard()
+# function in common/basicframe.cpp so that build option settings can be included in bug
+# reports.
+#
+
+# The desire is to migrate designs *away from* case independence, and to create designs which use
+# literally (case specific) interpreted component names. But for backwards compatibility,
+# you may turn OFF this option if you really must. (Remember that with KiCad using text
+# data files, typically you would be better off simply doctoring those files into
+# a case literal state with a text editor and move forward into the brave new
+# world of case specificity. Also, BOM generators may not work properly when you
+# have this option turned OFF, the xml export's referential integrity is broken
+# on library part name. Hence the default is ON now, as of 29-Jan-2014.
+option( KICAD_KEEPCASE
+ "Use case sensitive string matching for component names (default ON)."
+ ON
+ )
+
+option( USE_WX_GRAPHICS_CONTEXT
+ "Use wxGraphicsContext for rendering (default OFF). Warning, this is experimental" )
+
+option( USE_WX_OVERLAY
+ "Use wxOverlay: Always ON for MAC (default OFF). Warning, this is experimental" )
+
+option( KICAD_SCRIPTING
+ "Build the Python scripting support inside KiCad binaries (default OFF)."
+ )
+
+option( KICAD_SCRIPTING_MODULES
+ "Build KiCad Python modules that can be used from scripting languages (default OFF)."
+ )
+
+option( KICAD_SCRIPTING_WXPYTHON
+ "Build wxPython implementation for wx interface building in Python and py.shell (default OFF)."
+ )
+
+option( KICAD_BUILD_STATIC
+ "Build dependencies as static libraries. OSX only. (default OFF)."
+ )
+
+option( KICAD_BUILD_DYNAMIC
+ "Build dependencies as shared libraries. Required for wxPython support. OXS only. (default OFF)."
+ )
+
+option( USE_OSX_DEPS_BUILDER
+ "Build dependencies from source instead of dependencies installed on system. OSX only. (default OFF)."
+ )
+
+# WARNING: KiCad developers strongly advise you to build Boost with supplied patches,
+# as it is known to work with KiCad. Other versions may contain bugs that may result
+# in KiCad errors.
+option( KICAD_SKIP_BOOST
+ "Skip building downloaded Boost library components, use Boost from your system."
+ )
+mark_as_advanced( KICAD_SKIP_BOOST ) # Normal builders should build Boost.
+
+# when option KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES is enabled:
+# PYTHON_EXECUTABLE can be defined when invoking cmake
+# ( use -DPYTHON_EXECUTABLE=<python path>/python.exe or python2 )
+# when not defined by user, the default is python.exe under Windows and python2 for others
+# python binary file should be is exec path.
+
+option( BUILD_GITHUB_PLUGIN "Build the GITHUB_PLUGIN for pcbnew." ON )
+
+
+
+# All CMake downloads go here. Suggested is up in the source tree, not in the build dir where they
+# would have to be downloaded over and over again. The default is to choose a directory that is
+# hidden on linux (starts with a '.') because there is a way to exclude this directory when grepping
+# the source tree.
+set( DOWNLOAD_DIR ${PROJECT_SOURCE_DIR}/.downloads-by-cmake
+ CACHE PATH "Location of KiCad downloads, suggested is a dir common to all builds, i.e. global." )
+
+# Add option to add user directories for linker, if any
+LINK_DIRECTORIES( ${LINK_DIRECTORIES_PATH} )
+
+if( UNIX )
+ set( KICAD_USER_CONFIG_DIR $ENV{HOME} CACHE PATH "Location of user specific KiCad config files" )
+elseif( MINGW )
+ set( KICAD_USER_CONFIG_DIR $ENV{APPDATA} CACHE PATH "Location of user specific KiCad config files" )
+endif()
+mark_as_advanced( KICAD_USER_CONFIG_DIR )
+
+# Set default data file path to CMAKE_INSTALL_PREFIX if it wasn't specified during the
+# CMake configuration. The value of DEFAULT_INSTALL_PATH is expanded in config.h and
+# used in the source code to define the base path for kicad search paths and environment
+# variables.
+if( NOT DEFAULT_INSTALL_PATH )
+ set( DEFAULT_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}"
+ CACHE
+ PATH
+ "Location of KiCad data files." )
+endif()
+
+message( STATUS "Kicad install dir: <${DEFAULT_INSTALL_PATH}>" )
+
+# Generate build system specific header file.
+include( PerformFeatureChecks )
+perform_feature_checks()
+
+
+#================================================
+# Set flags for GCC, or treat llvm as GCC
+#================================================
+
+if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
+
+ execute_process( COMMAND ${CMAKE_C_COMPILER} -dumpversion
+ OUTPUT_VARIABLE GCC_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE )
+
+ if( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
+ set( TO_LINKER -XLinker )
+ else()
+ set( TO_LINKER -Wl )
+ endif()
+
+ # Establish -Wall early, so specialized relaxations of this may come
+ # subsequently on the command line, such as in pcbnew/github/CMakeLists.txt
+ set( CMAKE_C_FLAGS "-Wall ${CMAKE_C_FLAGS}" )
+ set( CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}" )
+
+ # The optimization level is -O1 instead of the usual -O2 level because
+ # boost::polygon has a function (inflate polygon) broken by the -O2 level
+ # with GCC 4.7.0 to 4.7.2 (works fine with with GCC 4.6 and 4.7.3).
+ # This lower optimization level does not have a significant change on the speed.
+ # See also:
+ # https://bugs.launchpad.net/kicad/+bug/1056926
+ # https://svn.boost.org/trac/boost/ticket/7983
+ if( GCC_VERSION VERSION_EQUAL 4.7.0 OR ( GCC_VERSION VERSION_GREATER 4.7.0 AND GCC_VERSION VERSION_LESS 4.7.3 ) )
+ set( CMAKE_C_FLAGS_RELEASE "-O1" )
+ set( CMAKE_CXX_FLAGS_RELEASE "-O1" )
+ else()
+ set( CMAKE_C_FLAGS_RELEASE "-O2" )
+ set( CMAKE_CXX_FLAGS_RELEASE "-O2" )
+ endif()
+
+ set( CMAKE_C_FLAGS_DEBUG "-g3 -ggdb3 -DDEBUG" )
+ set( CMAKE_CXX_FLAGS_DEBUG "-g3 -ggdb3 -DDEBUG -Wno-deprecated-declarations" )
+
+ set( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG" )
+ set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG" )
+
+ if( GXX_HAS_VISIBILITY_FLAG AND NOT APPLE )
+ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden" )
+ endif()
+
+ if( GXX_HAS_VISIBILITY_INLINES_FLAG AND NOT APPLE )
+ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden" )
+ endif()
+
+ find_package( OpenMP QUIET )
+
+ if( OPENMP_FOUND )
+ set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" )
+ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}" )
+ add_definitions( -DUSE_OPENMP )
+
+ # MinGW does not include the OpenMP link library and FindOpenMP.cmake does not
+ # set it either. Not sure this is the most elegant solution but it works.
+ if( MINGW )
+ set( OPENMP_LIBRARIES gomp )
+ endif()
+ endif()
+
+ if( MINGW )
+ set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" )
+
+ # _UNICODE definition seems needed under mingw/gcc 4.8
+ # (Kicad uses unicode, and on Windows, wxWidgets >= 2.9.4 is mandatory
+ # and uses unicode)
+ if( GCC_VERSION VERSION_EQUAL 4.8.0 OR GCC_VERSION VERSION_GREATER 4.8.0 )
+ add_definitions(-D_UNICODE)
+ endif()
+
+ # Since version 2.8.5, Cmake uses a response file (.rsp) to
+ # pass the list of include paths to gcc
+ # unfortunately, under mingw32+msys, at least with gcc 4.8 and previous,
+ # this file is not always expanded and in this case include paths defined in this file
+ # are not taken in account ( this is the case of wxWidgets includes )
+ # If it is the case, disable this response file for includes ( See Windows-GNU.cmake module )
+ if( false ) #set to true to disable the include response file
+ if( WIN32 AND MSYS AND NOT CMAKE_CROSSCOMPILING )
+ # fixme: it is needed only with MSYS+MINGW32? or always under MINGW
+ if( ${CMAKE_SIZEOF_VOID_P} MATCHES 4 )
+ set( CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 0 )
+ endif()
+ endif()
+ endif()
+
+ # for some reasons, cmake does do use always a response file to send the list of objects
+ # to the archiver, and because this list can be very long, and can create issue
+ # when it is used in a command line, force use of a response file to store it
+ SET( CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1 )
+
+ # The MinGW compiler can use the microsoft system snprintf as standard and it has a broken
+ # API with respect to the C99 standard, so make sure we force it to use its own compliant
+ # snprintf
+ add_definitions(-D__USE_MINGW_ANSI_STDIO=1)
+
+ else()
+ # We build DLL/DSOs from static libraries, so create position independent
+ # code for all cases, since we do not have DLL/DSO specific static
+ # libraries. Subdirectories via add_subdirectores() reference this
+ # variable, and it is either set or empty, empty for Windows.
+ set( PIC_FLAG -fPIC )
+
+ set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PIC_FLAG}" )
+ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PIC_FLAG}" )
+
+ if( NOT APPLE )
+ # Thou shalt not link vaporware and tell us it's a valid DSO (apple ld doesn't support it)
+ set( CMAKE_SHARED_LINKER_FLAGS "${TO_LINKER},--no-undefined" )
+ set( CMAKE_MODULE_LINKER_FLAGS "${TO_LINKER},--no-undefined" )
+
+ set( CMAKE_EXE_LINKER_FLAGS_RELEASE "-s" )
+
+ # Defeat ELF's ability to use the GOT to replace locally implemented functions
+ # with ones from another module.
+ # https://bugs.launchpad.net/kicad/+bug/1322354
+ set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${TO_LINKER},-Bsymbolic" )
+ set( CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${TO_LINKER},-Bsymbolic" )
+ endif()
+
+ endif()
+
+ # quiet GCC while in boost
+ if( GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8 )
+ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-local-typedefs" )
+ endif()
+ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-strict-aliasing" )
+
+ if( APPLE )
+
+ set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__ASSERTMACROS__" )
+ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__ASSERTMACROS__" )
+
+ # Allows .dylib relocation in the future - needed by fixbundle
+ set( CMAKE_LD_FLAGS "${CMAKE_LD_FLAGS} -headerpad_max_install_names")
+
+ if( NOT CMAKE_CXX_COMPILER )
+ EXEC_PROGRAM( wx-config ARGS --cc OUTPUT_VARIABLE CMAKE_C_COMPILER )
+ endif()
+
+ if( NOT CMAKE_CXX_COMPILER )
+ EXEC_PROGRAM( wx-config ARGS --cxx OUTPUT_VARIABLE CMAKE_CXX_COMPILER )
+ endif()
+
+ # There seems to be no consistent behavior when -mmacosx-min-version is
+ # not specified, so force user to set minimum OSX version to build for
+ if( NOT CMAKE_OSX_DEPLOYMENT_TARGET )
+ message( FATAL_ERROR "Please specify target OS X version using -DCMAKE_OSX_DEPLOYMENT_TARGET=10.x" )
+ endif()
+
+ endif()
+
+endif( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
+
+if( KICAD_KEEPCASE )
+ add_definitions( -DKICAD_KEEPCASE )
+endif()
+
+if( USE_WX_OVERLAY OR APPLE )
+ add_definitions( -DUSE_WX_OVERLAY )
+endif()
+
+if( KICAD_SCRIPTING )
+ add_definitions( -DKICAD_SCRIPTING )
+endif()
+
+if( KICAD_SCRIPTING_MODULES )
+ add_definitions( -DKICAD_SCRIPTING_MODULES )
+endif()
+
+if( KICAD_SCRIPTING_WXPYTHON )
+ add_definitions( -DKICAD_SCRIPTING_WXPYTHON )
+endif()
+
+if( USE_WX_GRAPHICS_CONTEXT OR APPLE )
+ add_definitions( -DUSE_WX_GRAPHICS_CONTEXT )
+endif()
+
+
+# By default images in menu items are enabled on all platforms except OSX.
+if( NOT APPLE )
+ set( USE_IMAGES_IN_MENUS ON CACHE BOOL "Enable images in menus" )
+else()
+ set( USE_IMAGES_IN_MENUS OFF CACHE BOOL "Enable images in menus" )
+endif()
+
+
+
+# KIFACE_SUFFIX is the file extension used for top level program modules which
+# implement the KIFACE interface. A valid suffix starts with a period '.'.
+
+if( false )
+ # This is the eventual situation near milestone C) of modular-kicad blueprint.
+ # Until then we use .kiface extension so we don't collide with python DSO.
+ set( KIFACE_SUFFIX ${CMAKE_SHARED_MODULE_SUFFIX} )
+else()
+ # Temporary situation until we can dovetail the python DSO into the kiface DSO.
+ set( KIFACE_SUFFIX ".kiface" )
+endif()
+
+# KIFACE_PREFIX is a basename prefix used for top level program modules which
+# implement the KIFACE.
+set( KIFACE_PREFIX "_" )
+#message( STATUS "KIFACE_SUFFIX:${KIFACE_SUFFIX} KIFACE_PREFIX:${KIFACE_PREFIX}" )
+
+
+#================================================
+# Locations for install targets.
+#================================================
+if( NOT APPLE )
+ # Everything without leading / is relative to CMAKE_INSTALL_PREFIX.
+ set( KICAD_BIN ${CMAKE_INSTALL_PREFIX}/bin
+ CACHE PATH "Location of KiCad binaries." )
+
+ if( WIN32 )
+ set( KICAD_PLUGINS ${KICAD_BIN}/scripting/plugins
+ CACHE PATH "Location of KiCad plugins." )
+ else()
+ set( KICAD_PLUGINS lib/kicad/plugins
+ CACHE PATH "Location of KiCad plugins." )
+ endif()
+
+ set( KICAD_DATA share/kicad
+ CACHE PATH "Location of KiCad data files." )
+ set( KICAD_DOCS share/doc/kicad
+ CACHE PATH "Location of KiCad documentation files." )
+ set( KICAD_DEMOS ${KICAD_DATA}/demos
+ CACHE PATH "Location of KiCad demo files." )
+ set( KICAD_TEMPLATE ${KICAD_DATA}/template
+ CACHE PATH "Location of KiCad template files." )
+else()
+ # everything without leading / is relative to CMAKE_INSTALL_PREFIX.
+ # CMAKE_INSTALL_PREFIX is root of .dmg image
+ set( KICAD_BIN ${CMAKE_INSTALL_PREFIX}
+ CACHE PATH "Location of KiCad binaries." FORCE )
+
+ # some paths to single app bundle
+ set( OSX_BUNDLE_MAIN "kicad.app" )
+ set( OSX_BUNDLE_BIN_DIR "Contents/MacOS" )
+ set( OSX_BUNDLE_LIB_DIR "Contents/Frameworks" )
+ set( OSX_BUNDLE_KIFACE_DIR "Contents/PlugIns" )
+ set( OSX_BUNDLE_SUP_DIR "Contents/SharedSupport" )
+ set( OSX_BUNDLE_APP_DIR "Contents/Applications" )
+ set( OSX_BUNDLE_BUILD_DIR "${CMAKE_BINARY_DIR}/kicad/${OSX_BUNDLE_MAIN}" )
+ set( OSX_BUNDLE_BUILD_BIN_DIR "${OSX_BUNDLE_BUILD_DIR}/${OSX_BUNDLE_BIN_DIR}" )
+ set( OSX_BUNDLE_BUILD_LIB_DIR "${OSX_BUNDLE_BUILD_DIR}/${OSX_BUNDLE_LIB_DIR}" )
+ set( OSX_BUNDLE_BUILD_KIFACE_DIR "${OSX_BUNDLE_BUILD_DIR}/${OSX_BUNDLE_KIFACE_DIR}" )
+ set( OSX_BUNDLE_INSTALL_DIR "${KICAD_BIN}/${OSX_BUNDLE_MAIN}" )
+ set( OSX_BUNDLE_INSTALL_BIN_DIR "${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_BIN_DIR}" )
+ set( OSX_BUNDLE_INSTALL_LIB_DIR "${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_LIB_DIR}" )
+ set( OSX_BUNDLE_INSTALL_KIFACE_DIR "${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_KIFACE_DIR}" )
+
+ # everything provided with the application bundle goes into
+ # kicad.app/Contents/SharedSupport => accessible via GetDataDir()
+ # everything else to the .dmg image
+ set( KICAD_DATA ${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_SUP_DIR}
+ CACHE PATH "Location of KiCad data files." FORCE )
+ set( KICAD_TEMPLATE ${KICAD_DATA}/template
+ CACHE PATH "Location of KiCad template files." FORCE )
+ set( KICAD_PLUGINS ${KICAD_DATA}/plugins
+ CACHE PATH "Location of KiCad plugins." FORCE )
+ set( KICAD_DOCS doc
+ CACHE PATH "Location of KiCad documentation files." FORCE )
+ set( KICAD_DEMOS demos
+ CACHE PATH "Location of KiCad demo files." FORCE )
+
+ # Override default paths for fixup_bundle
+ set( OSX_BUNDLE_OVERRIDE_PATHS "
+ function( gp_item_default_embedded_path_override item default_embedded_path_var )
+ # by default, embed things right next to the main bundle executable:
+ set( path \"@executable_path/../../Contents/MacOS\" )
+ set( overridden 0 )
+
+ # embed .dylibs right next to the main bundle executable:
+ if( item MATCHES \"\\\\.dylib$\" )
+ set( path \"@executable_path/../Frameworks\" )
+ set( overridden 1 )
+ endif()
+
+ set( \${default_embedded_path_var} \"\${path}\" PARENT_SCOPE )
+ endfunction(gp_item_default_embedded_path_override)
+ "
+ )
+endif()
+
+mark_as_advanced( KICAD_BIN
+ KICAD_PLUGINS
+ KICAD_DATA
+ KICAD_DOCS
+ KICAD_DEMOS
+ KICAD_TEMPLATE )
+
+include( Functions )
+
+include( ExternalProject )
+
+#================================================
+# Find libraries that are needed to build KiCad.
+#================================================
+include( CheckFindPackageResult )
+
+##########################
+# Find wxWidgets library #
+##########################
+# Here you can define what libraries of wxWidgets you need for your
+# application. You can figure out what libraries you need here;
+# http://www.wxwidgets.org/manuals/2.8/wx_librarieslist.html
+
+# Turn on wxWidgets compatibility mode for some classes
+add_definitions( -DWX_COMPATIBILITY )
+
+# See line 41 of CMakeModules/FindwxWidgets.cmake
+set( wxWidgets_CONFIG_OPTIONS ${wxWidgets_CONFIG_OPTIONS} --static=no )
+
+find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED )
+
+# Include wxWidgets macros.
+include( ${wxWidgets_USE_FILE} )
+
+#######################
+# Find OpenGL library #
+#######################
+find_package( OpenGL QUIET )
+check_find_package_result( OPENGL_FOUND "OpenGL" )
+
+# Dick 5-Feb-2014:
+# Marco: We cannot use both ExternalProject_Add() add and find_package()
+# in the same CMake tree and have them both reference the same package:
+# http://stackoverflow.com/questions/6351609/cmake-linking-to-library-downloaded-from-externalproject-add
+# https://www.mail-archive.com/cmake@cmake.org/msg47501.html
+
+# Handle target used to specify if a target needs wx-widgets or other libraries
+# Always defined, empty if no libraries are to be built
+add_custom_target( lib-dependencies )
+
+# Only download and build all dependencies from source on OSX if the user specifically requests
+# it. Otherwise, respect the developers wishes to use the dependencies already installed on
+# their system
+if( APPLE AND USE_OSX_DEPS_BUILDER )
+
+ # This should be built in all cases, if swig exec is not available
+ # will be impossible also enable SCRIPTING being for PCBNEW required immediately
+
+ include( download_pcre )
+ include( download_swig )
+
+
+ #set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so;.dylib;.dll")
+
+ if( KICAD_BUILD_STATIC AND KICAD_BUILD_DYNAMIC )
+ message(FATAL_ERROR "You can't build STATIC and DYNAMIC together")
+ endif()
+
+ if( KICAD_BUILD_STATIC )
+ message(STATUS "KICAD_BUILD_STATIC set")
+ if( KICAD_SCRIPTING OR KICAD_SCRIPTING_WXPYTHON OR KICAD_SCRIPTING_MODULES )
+ message(FATAL_ERROR "KICAD_SCRIPTING* is not supported with KICAD_BUILD_STATIC, please select KICAD_BUILD_DYNAMIC" )
+ endif()
+ endif()
+
+ if( KICAD_BUILD_DYNAMIC )
+ message(STATUS "KICAD_BUILD_DYNAMIC set")
+ endif()
+
+
+ if( KICAD_SCRIPTING OR KICAD_SCRIPTING_WXPYTHON OR KICAD_SCRIPTING_MODULES )
+
+ message(STATUS "Scripting ENABLED")
+ include( download_wxpython )
+
+ set( SWIG_EXECUTABLE ${SWIG_ROOT}/bin/swig )
+ set( SWIG_INCLUDE ${SWIG_ROOT}/include )
+ set( PYTHON_DEST ${LIBWXPYTHON_ROOT}/wxPython/lib/python2.6/site-packages )
+
+ if( NOT EXISTS ${SWIG_EXECUTABLE} )
+ set(KICAD_SCRIPTING CACHE OFF FORCE "Disabling KICAD_SCRIPTING")
+ message( STATUS "KICAD_SCRIPTING Enabled but SWIG not found, please disable and before reenabling execute: make swig")
+ message( FATAL_ERROR "Missing SWIG!")
+ endif()
+ message(STATUS "SWIG_EXECUTABLE: ${SWIG_EXECUTABLE}")
+
+ set( PYTHON_DEST ${LIBWXPYTHON_ROOT}/wxPython/lib/python2.6/site-packages )
+
+ add_dependencies( lib-dependencies libwxpython )
+ add_dependencies( lib-dependencies swig )
+ else()
+ include( download_wxwidgets )
+ add_dependencies( lib-dependencies libwx )
+ endif()
+
+ include( download_libpng )
+ include( download_pkgconfig )
+ set( PKG_CONFIG_EXECUTABLE "${PKGCONFIG_ROOT}/bin/pkg-config" )
+ include( download_glew )
+ set( GLEW_GLEW_LIBRARY "${GLEW_ROOT}/lib/libGLEW.a" )
+ set( GLEW_INCLUDE_DIR "${GLEW_ROOT}/include" )
+ include( download_pixman )
+ set( PIXMAN_LIBRARY "${PIXMAN_ROOT}/lib/libpixman-1.a" )
+ include( download_cairo )
+ set( CAIRO_INCLUDE_DIR "${CAIRO_ROOT}/include/cairo" )
+ set( CAIRO_LIBRARY "${CAIRO_ROOT}/lib/libcairo.a" )
+
+ add_dependencies( lib-dependencies boost )
+ add_dependencies( lib-dependencies cairo )
+ add_dependencies( lib-dependencies libpng )
+ add_dependencies( lib-dependencies pixman )
+ add_dependencies( lib-dependencies pkgconfig )
+
+ if( KICAD_BUILD_DYNAMIC AND APPLE )
+ add_custom_target( osx_fix_bundles ALL DEPENDS
+ eeschema gerbview kicad pcbnew bitmap2component pcb_calculator pl_editor)
+ add_custom_command(TARGET osx_fix_bundles
+ POST_BUILD COMMAND ${PROJECT_SOURCE_DIR}/scripts/osx_fixbundle.sh ${PROJECT_SOURCE_DIR}
+ COMMENT "Migrating dylibs to bundles")
+ endif()
+endif()
+
+#####################
+# Find GLEW library #
+#####################
+if( NOT GLEW_FOUND )
+ find_package( GLEW )
+ check_find_package_result( GLEW_FOUND "GLEW" )
+endif()
+
+# Find CURL library
+find_package( CURL REQUIRED )
+
+
+######################
+# Find Cairo library #
+######################
+if( NOT CAIRO_FOUND )
+ find_package( Cairo 1.8.1 QUIET )
+ check_find_package_result( CAIRO_FOUND "Cairo" )
+endif()
+
+# Download boost and possibly build parts of it
+#################################################
+if( KICAD_SKIP_BOOST )
+ find_package( Boost 1.54.0 REQUIRED COMPONENTS context date_time filesystem iostreams locale
+ program_options regex system thread )
+
+ if( NOT Boost_FOUND )
+ message( FATAL_ERROR "Boost 1.54+ libraries are required." )
+ endif()
+
+ # Keeps CMake from complaining about undefined boost dependencies even though Boost was
+ # found. Sigh!!!!!
+ add_custom_target( boost )
+
+ message( WARNING "
+WARNING: You decided to skip building boost library.
+KiCad developers strongly advise you to build the bundled boost library, as it is known to work with KiCad.
+Other versions may contain bugs that may result in KiCad errors." )
+else()
+ add_dependencies( lib-dependencies boost )
+ include( download_boost )
+endif()
+
+# Include MinGW resource compiler.
+include( MinGWResourceCompiler )
+
+# Find GDI+ on windows if wxGraphicsContext is available.
+if( MINGW AND USE_WX_GRAPHICS_CONTEXT )
+ find_package( GdiPlus )
+ check_find_package_result( GDI_PLUS_FOUND "GDI+" )
+endif()
+
+# Assist with header file searching optimization:
+# INC_BEFORE and INC_AFTER are two lists which go at the front and back of the
+# header file search lists, respectively.
+# INC_BEFORE is for use with "include_directories( BEFORE ...)", which _reverses_
+# the order during insertion. (So put first wanted last, which is
+# ${CMAKE_SOURCE_DIR/include.) Use '.' for current source dir since
+# we don't want expansion here and now, which would happen if using ${CMAKE_CURRENT_SOURCE_DIR}.
+# Instead we use '.' which is applicable to any source directory below here as a result of
+# this lack of expansion.
+set( INC_BEFORE
+ .
+ ${CMAKE_SOURCE_DIR}/include
+ )
+
+set( INC_AFTER
+ ${Boost_INCLUDE_DIR}
+ #include <config.h>
+ ${CMAKE_BINARY_DIR}
+ )
+
+
+# Find Python and other scripting resources
+if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
+ # force a python version < 3.0
+ set( PythonInterp_FIND_VERSION 2.6 )
+ set( PythonLibs_FIND_VERSION 2.6 )
+
+ find_package( PythonInterp )
+
+ check_find_package_result( PYTHONINTERP_FOUND "Python Interpreter" )
+
+ if( NOT PYTHON_VERSION_MAJOR EQUAL 2 )
+ message( FATAL_ERROR "Python 2.x is required." )
+ endif()
+
+ # Get the correct Python site package install path from the Python interpreter found by
+ # FindPythonInterp unless the user specifically defined a custom path.
+ if( NOT PYTHON_SITE_PACKAGE_PATH )
+ execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.sysconfig;print\"%s\"%distutils.sysconfig.get_python_lib(plat_specific=0, standard_lib=0, prefix='')"
+ OUTPUT_VARIABLE PYTHON_SITE_PACKAGE_PATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ if( NOT PYTHON_SITE_PACKAGE_PATH )
+ message( FATAL_ERROR "Error occurred while attempting to find the Python site library path." )
+ endif()
+ endif()
+
+ if( NOT APPLE )
+ set( PYTHON_DEST "${PYTHON_SITE_PACKAGE_PATH}"
+ CACHE PATH "Python module install path."
+ )
+ else()
+ # relative path for python in bundle
+ set( PYTHON_LIB_DIR "python/site-packages" )
+ # install into bundle Frameworks folder
+ set( PYTHON_DEST "${OSX_BUNDLE_BUILD_LIB_DIR}/${PYTHON_LIB_DIR}"
+ CACHE PATH "Python module install path."
+ )
+ endif()
+ mark_as_advanced( PYTHON_DEST )
+ message( STATUS "Python module install path: ${PYTHON_DEST}" )
+
+ find_package( PythonLibs 2.6 )
+
+ if( KICAD_SCRIPTING_WXPYTHON )
+ # Check to see if the correct version of wxPython is installed based on the version of
+ # wxWidgets found. At least the major an minor version should match.
+ set( _wxpy_version "${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}" )
+ set( _py_cmd "import wxversion;print wxversion.checkInstalled('${_wxpy_version}')" )
+
+ # Add user specified Python site package path.
+ if( PYTHON_SITE_PACKAGE_PATH )
+ set( _py_cmd
+ "import sys;sys.path.insert(0, \"${PYTHON_SITE_PACKAGE_PATH}\");${_py_cmd}" )
+ endif()
+
+ execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "${_py_cmd}"
+ RESULT_VARIABLE WXPYTHON_VERSION_RESULT
+ OUTPUT_VARIABLE WXPYTHON_VERSION_FOUND
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ # message( STATUS "WXPYTHON_VERSION_FOUND: ${WXPYTHON_VERSION_FOUND}" )
+ # message( STATUS "WXPYTHON_VERSION_RESULT: ${WXPYTHON_VERSION_RESULT}" )
+
+ # Check to see if any version of wxPython is installed on the system.
+ if( WXPYTHON_VERSION_RESULT GREATER 0 )
+ message( FATAL_ERROR "wxPython does not appear to be installed on the system." )
+ endif()
+
+ if( NOT WXPYTHON_VERSION_FOUND STREQUAL "True" )
+ message( FATAL_ERROR
+ "wxPython version ${_wxpy_version} does not appear to be installed on the system." )
+ endif()
+
+ set( WXPYTHON_VERSION ${_wxpy_version} CACHE STRING "wxPython version found." )
+ message( STATUS "wxPython version ${_wxpy_version} found." )
+ endif()
+
+ #message( STATUS "PYTHON_INCLUDE_DIRS:${PYTHON_INCLUDE_DIRS}" )
+
+ # Infrequently needed headers go at end of search paths, append to INC_AFTER which
+ # although is used for all components, should be a harmless hit for something like eeschema
+ # so long as unused search paths are at the end like this.
+ set( INC_AFTER ${INC_AFTER} ${PYTHON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/scripting )
+
+ #message( STATUS "/ INC_AFTER:${INC_AFTER}" )
+
+endif()
+
+if( EXISTS ${CMAKE_SOURCE_DIR}/include/config.h )
+ # This file may exist ( created by an alternate process to the svn test above),
+ # e.g. could be created by a checkout script that produces a source tar file.
+ # This directive means the about box will have the svn date & revision in it,
+ # but the hard coded release date ( program version) will be preserved.
+ add_definitions( -DHAVE_SVN_REVISION )
+endif()
+
+
+#================================================
+# Let CMake look in these directories for nested
+# 'CMakeLists.txt' files to process
+#================================================
+
+if( APPLE )
+ # Remove app bundles in ${KICAD_BIN} before installing anything new.
+ # Must be defined before all includes so that it is executed first.
+ install( CODE "
+ message( STATUS \"Removing existing application bundles...\" )
+ # Remove links to standalone apps
+ file( REMOVE ${KICAD_BIN}/bitmap2component.app )
+ file( REMOVE ${KICAD_BIN}/eeschema.app )
+ file( REMOVE ${KICAD_BIN}/gerbview.app )
+ file( REMOVE ${KICAD_BIN}/pcb_calculator.app )
+ file( REMOVE ${KICAD_BIN}/pcbnew.app )
+ file( REMOVE ${KICAD_BIN}/pl_editor.app )
+ # Remove main bundle
+ file( REMOVE_RECURSE ${KICAD_BIN}/${OSX_BUNDLE_MAIN} )
+ " COMPONENT Runtime
+ )
+endif()
+
+############################
+# Binaries ( CMake targets ) #
+############################
+
+add_subdirectory( bitmaps_png )
+add_subdirectory( common )
+add_subdirectory( 3d-viewer )
+add_subdirectory( cvpcb )
+add_subdirectory( eeschema )
+add_subdirectory( gerbview )
+add_subdirectory( lib_dxf )
+add_subdirectory( pcbnew )
+add_subdirectory( polygon )
+add_subdirectory( pagelayout_editor )
+add_subdirectory( potrace )
+add_subdirectory( bitmap2component )
+add_subdirectory( pcb_calculator )
+add_subdirectory( kicad ) # should follow pcbnew, eeschema
+add_subdirectory( tools )
+add_subdirectory( utils )
+add_subdirectory( qa )
+
+#add_subdirectory( new )
+
+
+# Make all libs and executables depend on ExternalProject_Add( boost ),
+# except perhaps bitmap lib. This allows a multi-threaded build to succeed.
+add_dependencies( pcbnew boost )
+add_dependencies( eeschema boost )
+add_dependencies( cvpcb_kiface boost )
+add_dependencies( gal boost )
+add_dependencies( common boost )
+add_dependencies( pcbcommon boost )
+add_dependencies( 3d-viewer boost )
+add_dependencies( pcad2kicadpcb boost )
+add_dependencies( polygon boost )
+add_dependencies( pl_editor boost )
+add_dependencies( pnsrouter boost )
+
+
+if( KICAD_BUILD_STATIC OR KICAD_BUILD_DYNAMIC )
+ add_dependencies( pcbnew lib-dependencies )
+ add_dependencies( eeschema lib-dependencies )
+ add_dependencies( cvpcb_kiface lib-dependencies )
+ add_dependencies( common lib-dependencies )
+ add_dependencies( gal lib-dependencies )
+ add_dependencies( pcbcommon lib-dependencies )
+ add_dependencies( 3d-viewer lib-dependencies )
+ add_dependencies( pcad2kicadpcb lib-dependencies )
+ add_dependencies( pl_editor lib-dependencies )
+ add_dependencies( pnsrouter lib-dependencies )
+endif()
+
+if( KICAD_BUILD_DYNAMIC )
+endif()
+
+#############
+# Resources #
+#############
+add_subdirectory( demos )
+add_subdirectory( template )
+
+#================================================
+# Doxygen Output
+#================================================
+find_package( Doxygen )
+if( DOXYGEN_FOUND )
+ add_custom_target( doxygen-docs
+ ${CMAKE_COMMAND} -E remove_directory Documentation/doxygen
+ COMMAND ${DOXYGEN_EXECUTABLE}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ DEPENDS Doxyfile
+ COMMENT "building doxygen docs into directory Documentation/doxygen/html"
+ )
+ add_custom_target( dev-docs
+ ${CMAKE_COMMAND} -E remove_directory Documentation/development/doxygen
+ COMMAND ${DOXYGEN_EXECUTABLE}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Documentation/development
+ DEPENDS Doxyfile
+ COMMENT "building developer's resource docs into directory Documentation/development/doxygen/html"
+ )
+else()
+ message( STATUS "WARNING: Doxygen not found - doxygen-docs (Source Docs) target not created" )
+endif()
+
+# Generate config.h.
+configure_file( ${PROJECT_SOURCE_DIR}/CMakeModules/config.h.cmake
+ ${CMAKE_BINARY_DIR}/config.h )
+
+#================================================
+# "make uninstall" rules
+#================================================
+configure_file(
+ "${CMAKE_MODULE_PATH}/cmake_uninstall.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+ IMMEDIATE @ONLY )
+
+add_custom_target( uninstall
+ "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" )
+
+
+#================================================
+# Installation
+#================================================
+
+install( FILES INSTALL.txt
+ DESTINATION ${KICAD_DOCS}
+ COMPONENT resources )
+
+###
+# Install scripts
+###
+if( UNIX )
+ install( DIRECTORY scripts
+ DESTINATION ${KICAD_DOCS}
+ COMPONENT resources
+ )
+endif()
+
+###
+# FreeDesktop .desktop and MIME resources
+###
+if( UNIX AND NOT APPLE )
+
+ # Set paths
+ set( UNIX_MIME_DIR resources/linux/mime )
+ set( UNIX_MIMELNK_FILES ${UNIX_MIME_DIR}/mimelnk )
+ set( UNIX_MIME_FILES ${UNIX_MIME_DIR}/mime )
+ set( UNIX_ICON_FILES ${UNIX_MIME_DIR}/icons )
+ set( UNIX_APPLICATIONS_FILES ${UNIX_MIME_DIR}/applications )
+
+ # Install Mimelnk directory
+ install( DIRECTORY ${UNIX_MIMELNK_FILES}
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/share
+ COMPONENT resources
+ )
+
+ # Install Mime directory
+ install( DIRECTORY ${UNIX_ICON_FILES}
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/share
+ COMPONENT resources
+ )
+
+ # Install Icons
+ install( DIRECTORY ${UNIX_MIME_FILES}
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/share
+ COMPONENT resources
+ )
+
+ # Install Applications directory (.desktop files)
+ install( DIRECTORY ${UNIX_APPLICATIONS_FILES}
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/share
+ COMPONENT resources
+ )
+endif()
+
+#include( CTest )
+
+
+if( UNIX AND NOT APPLE )
+
+ # Create a *.deb file:
+ set( CPACK_GENERATOR "DEB" )
+ set( CPACK_DEBIAN_PACKAGE_MAINTAINER "http://launchpad.net/kicad" )
+
+ set( CPACK_PACKAGE_VERSION_MAJOR 1 )
+ set( CPACK_PACKAGE_VERSION_MINOR 0 )
+ set( CPACK_PACKAGE_VERSION_PATCH 0 )
+ #set( CPACK_PACKAGE_CONTACT Firstname Lastname <email@company.com> )
+ set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "KiCad built by CMake build system." )
+
+ include( CPack )
+
+endif()
diff --git a/INSTALL.txt b/INSTALL.txt
new file mode 100644
index 0000000..208c508
--- /dev/null
+++ b/INSTALL.txt
@@ -0,0 +1,164 @@
+KiCad installation
+==================
+
+The parts of KiCad
+------------------
+KiCad consists of 3 packages:
+
+kicad - KiCad programs and core files.
+kicad-doc - Documentation and interactive help (optional package).
+kicad-library - KiCad schematic, pcb & 3D-model libraries (optional package).
+
+
+Installation from binary packages
+---------------------------------
+
+ KiCad binary packages exist for Linux and Windows (XP, 2000).
+
+ Data files (schematic, boards, libraries) are compatible with all platforms.
+
+*.zip - KiCad packages for Windows.
+*.tbz2 - KiCad for Linux.
+
+
+Installation from binary packages for Windows
+---------------------------------------------
+
+The KiCad binary archive can be installed anywhere on the system that as long as the user
+has write privileges.
+
+You can create a shortcut to '${prefix}\bin\kicad.exe' where ${prefix} is the install path.
+
+
+Installation from binary packages for Linux
+-------------------------------------------
+
+KiCad can be installed in '/usr' or '/usr/local'. You must have "root" access for installation.
+
+cd /
+tar -xjf kicad-{version}.tbz2
+tar -xjf kicad-doc-{version}.tbz2
+tar -xjf kicad-library-{version}.tbz2
+
+The main program is '/usr/bin/kicad'.
+
+
+Linux and Windows KiCad install tree
+-------------------------------------
+
+${prefix}/bin - Binaries (executable files).
+${prefix}/share/doc/kicad/ - Various documentation.
+${prefix}/share/doc/kicad/help - Interactive help.
+${prefix}/share/kicad/demos - Sample schematics and printed boards.
+${prefix}/share/kicad/internat - Dictionaries for interface localization.
+${prefix}/share/kicad/library - Interface localization files.
+${prefix}/share/kicad/modules - Module libraries for printed boards.
+${prefix}/share/kicad/modules/packages3d - 3D component models (.wrl and .wings format).
+
+KiCad searches for the libraries, templates, 3D models, etc. bin/../share.
+
+Warning:
+Do not change the KiCad tree, or the location of binary files. Otherwise
+KiCad may not be able to find some or all of its required files.
+
+
+Mac OS X KiCad tree
+-------------------
+
+System wide files
+
+/Library/Application Support/kicad/demos
+/Library/Application Support/kicad/internat
+/Library/Application Support/kicad/library
+/Library/Application Support/kicad/modules
+/Library/Application Support/kicad/modules/packages3d
+
+User files can be the same as the system wide files but only inside the users home directory.
+
+$HOME/Library/Application Support/kicad
+
+Warning:
+These paths are hardcoded into KiCad, if you put them somewhere else KiCad will not find
+them when a new project is created.
+
+Installation from source code
+-----------------------------
+
+Some dependencies must be satisfied for the correct installation of KiCad:
+
+wxWidgets >= 3.0.0 http://www.wxwidgets.org/
+
+CMake >= 2.8.4 http://www.cmake.org/
+
+Boost C++ Libraries:
+ files used by kicad are autmatically downloaded and patched if needed
+ from boost site ( http://www.boost.org/ )
+
+OpenGL
+ Linux: Mesa 3D Graphics Library http://www.mesa3d.org/
+ Windows: built-in
+
+Zlib Compression Library http://www.zlib.net/
+
+In source-tree-build are mostly unwanted, so make a subdir called "build" and
+change to it.
+
+Call cmake with the path to KiCad. E.g., when your build-folder is "build"
+within source-tree, type "cmake ../".
+
+Now your system get checked if it is able compiling KiCad and cmake generates
+the Makefiles.
+
+ After calling cmake just type "make" and build begins.
+
+ It is easy to build only a specific binary such as pcbnew alone:
+ make pcbnew
+
+ After "make" type "make install" and install begins.
+
+ You may install to a temporary-root with
+ make install DESTDIR=<temproot>
+
+ If you want to uninstall KiCad again type "make uninstall" from within the
+build directory.
+
+
+Important parameters to cmake
+-----------------------------
+
+See Documentation/compiling/build-config.txt for a list of all CMake options
+available when compiling KiCad.
+
+-DCMAKE_BUILD_TYPE=<buildtype>
+<buildtype> may current one of "Debug" and "Release".
+
+-DCMAKE_INSTALL_PREFIX=<prefix>
+Default to "/usr/local".
+
+-DwxWidgets_ROOT_DIR=<wxInstallDir>
+Required for Windows platform.
+
+-DwxWidgets_USE_DEBUG=ON
+Can be used only with -DCMAKE_BUILD_TYPE=Debug
+
+-DKICAD_KEEPCASE=ON
+Build the KiCad with no component name conversion to uppercase (if you want your
+ADuC.../Si.../bq... components named as just so).
+
+-DCMAKE_CXX_FLAGS=<some extra flags>
+Extra flags for the c++ compiler for your system required.
+
+-DCMAKE_VERBOSE_MAKEFILE=ON
+When more output is wanted use this cmake parameter or call "make VERBOSE=1".
+
+
+Extra CFLAGS and linker flags
+-----------------------------
+
+If you require extra flags for compiler and linker you may give them via
+environment variables
+ "CXXFLAGS" (c++ compiler)
+ "LDFLAGS" (for linker)
+ "CFLAGS" (for c-compiler, not needed in kdesvn build)
+
+eg., it may usefull on 64bit systems "-m64" to CXXFLAGS and LDFLAGS.
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..5a7fe27
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,41 @@
+KiCad README
+============
+For specific documentation like Compiling, GUI translation, Old changelogs see the
+Documentation subfolder.
+
+Files
+-----
+AUTHORS.txt - The authors, contributors, document writers and translators list
+CHANGELOG.txt - This years changelog (see for previous years Documentation/changelogs)
+CMakeList.txt - CMAKE build tool script
+COPYRIGHT.txt - A copy of the GNU General Public License Version 2
+CTestConfig.cmake - Support for CTest and CDash testing tools
+Doxyfile - Doxygen config file for Kicad
+INSTALL.txt - The release (binairy) installation instructions
+TODO.txt - Todo list
+uncrustify.cfg - Uncrustify config file for uncrustify sorces formatting tool
+
+Subdirectories
+--------------
+3d-viewer - Sourcecode of 3D viewer
+bitmaps - Menu and program icons
+bitmap2component - Sourcecode of a small application to create a footprint or a component from a B&W bitmap
+ this component or footprint has just graphic items that show the bitmap
+CMakeModules - Modules for the CMAKE build tool
+common - Sourcecode of the common library (common functions shared across whole suite)
+cvpcb - Sourcecode of CvPCB, tool to link components with footprints sourcecode
+demos - Some demo examples
+Documentation - Compiling documentation. Translating the GUI, old changelogs etcetera.
+eeschema - Sourcecode of the schematic editor
+gerbview - Sourcecode of the gerber viewer
+helpers - Helper tools and utilities for development
+include - Interfaces to the common library
+internat - Internationalisation files
+kicad - Sourcecode of the project manager
+packaging - Files for packaging on Windows and Mac OSX
+pcbnew - Sourcecode of the printed circuit board editor
+polygon - Sourcecode of the polygon library
+resources - Resources for installation, freedesktop mime-types for linux
+scripts - Helper scripts. For building, sourcecode packaging.
+template - Project template(s)
+
diff --git a/TODO.txt b/TODO.txt
new file mode 100644
index 0000000..0427a5f
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,76 @@
+KiCad TODO List
+===============
+
+WXMAC Platform
+--------------
+* Fix hotkey list to match CMD key
+* Fix AddHotkeyName to let wxWidgets handle Ctrl to CMD key
+* Fix toolbar button tooltips.
+
+Common
+------
+* Grep for @TODO or TODO for sourcecode tasks
+* Use Doxygen compatible comments on member functions (.h files)
+* Add tooltip text to all non-obvious controls in every dialog window.
+ Use wxFormBuilder.
+* Component and module search displays in which library the
+ module or component lives.
+* List auto up and down scrolling.
+* Push file open semantics down to one of the base frame classes ( likely candidate is
+ WinEDA_BasicFrame ) so that file open behavior is consistent across all applications.
+
+* Look over Brian's python BOM generation scripts, which are now in
+ scripts/python/ky and sort them out.
+ Code came from Brian in this posting's attachment, which is ky2.zip:
+ https://lists.launchpad.net/kicad-developers/msg06763.html
+ but is now in scripts/python/ky temporarily.
+
+
+
+Eeschema
+--------
+* Drag and drop between two Eeschema windows.
+
+Wayne:
+E3) Hook up perform last library search hot key to replace search libraries for
+ component support removed from find dialog.
+E4) Change add component dialog search text control to combobox and add component
+ search history save and restore capability. Also add session save and restore
+ to component history list control. Add advanced search capability similar to
+ new find dialog.
+E6) Start initial work for changing component library file format to use Dick's
+ dsnlexer. See note C2 above. Come up with a workable library file format to
+ handle the wishes of the library implementation group. Add initial clipboard
+ support to the library editor.
+
+
+
+PCBNew
+------
+
+*) Make the zone hit testing be done in screen coordinates, not internal units.
+ See the @todos in class_zone.cpp. A fixed distance in internal units becomes
+ a variable distance based on zoom factor, leading to inconsistent results at
+ various zoom factors. I believe that a fixed distance in pixels might make
+ for a friendlier UI.
+
+*) Add a hot key to toggle the 45 degree constraint on and off so that it can be
+ changed when drawing a trace.
+
+*) Paste (module ...) from clipboard into module editor.
+
+
+
+
+Dick's Final TODO List:
+======================
+*) Milestone B of Modular KiCad Blueprint:
+ * Put SEARCH_STACK::LastVisitedPath() out of its misery.
+ * Combine CVPCB into PCBNEW.
+
+*) Milestone C of Modular KiCad Blueprint
+ * SWIG class KIWAY, PROJECT, and KIWAY_MGR and fill out KIWAY_MGR as needed.
+ * Implement PROJECT::Substitute().
+ * Other stuff in blueprint milestone.
+
+*) Get licensing cleaned up.
diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt
new file mode 100644
index 0000000..bad525b
--- /dev/null
+++ b/cvpcb/CMakeLists.txt
@@ -0,0 +1,190 @@
+# the map generation creates on Windows/gcc a lot of useless warnings
+# so disable it on windows
+if( WIN32 AND NOT CMAKE_CROSSCOMPILING )
+ set( MAKE_LINK_MAPS false )
+else()
+ set( MAKE_LINK_MAPS true )
+endif()
+
+add_definitions( -DCVPCB )
+
+include_directories( BEFORE ${INC_BEFORE} )
+include_directories(
+ ./dialogs
+ ../3d-viewer
+ ../pcbnew
+ ../pcbnew/dialogs
+ ../polygon
+ ../common
+ ${INC_AFTER}
+ )
+
+
+set( CVPCB_DIALOGS
+ dialogs/fp_conflict_assignment_selector_base.cpp
+ dialogs/fp_conflict_assignment_selector.cpp
+ dialogs/dialog_display_options.cpp
+ dialogs/dialog_display_options_base.cpp
+ dialogs/dialog_config_equfiles_base.cpp
+ dialogs/dialog_config_equfiles.cpp
+ ../pcbnew/dialogs/dialog_fp_lib_table.cpp
+ ../pcbnew/dialogs/dialog_fp_lib_table_base.cpp
+ ../pcbnew/dialogs/dialog_fp_plugin_options.cpp
+ ../pcbnew/dialogs/dialog_fp_plugin_options_base.cpp
+ ../pcbnew/dialogs/wizard_add_fplib_base.cpp
+ ../pcbnew/dialogs/wizard_add_fplib.cpp
+ )
+
+set( CVPCB_SRCS
+ ../common/base_units.cpp
+ ../pcbnew/board_items_to_polygon_shape_transform.cpp
+ ../pcbnew/class_drc_item.cpp
+ autosel.cpp
+ cfg.cpp
+ class_components_listbox.cpp
+ class_DisplayFootprintsFrame.cpp
+ class_footprints_listbox.cpp
+ class_library_listbox.cpp
+ cvframe.cpp
+ listboxes.cpp
+ menubar.cpp
+ readwrite_dlgs.cpp
+ tool_cvpcb.cpp
+ )
+
+
+if( MINGW )
+ # CVPCB_RESOURCES variable is set by the macro.
+ mingw_resource_compiler( cvpcb )
+else()
+ set( CVPCB_RESOURCES cvpcb.rc )
+endif()
+
+
+if( false )
+ # setup bundle
+ set( CVPCB_RESOURCES cvpcb.icns cvpcb_doc.icns )
+ set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/cvpcb.icns" PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+ set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/cvpcb_doc.icns" PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+ set( MACOSX_BUNDLE_ICON_FILE cvpcb.icns )
+ set( MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-pcb.kicad )
+ set( MACOSX_BUNDLE_NAME cvpcb )
+endif()
+
+
+if( false ) # no CVPCB exe any more, only the *.kiface
+ add_executable( cvpcb WIN32 MACOSX_BUNDLE
+ ../common/single_top.cpp
+ ../common/pgm_base.cpp
+ ${CVPCB_RESOURCES}
+ )
+ set_source_files_properties( ../common/single_top.cpp PROPERTIES
+ COMPILE_DEFINITIONS "TOP_FRAME=FRAME_CVPCB;PGM_DATA_FILE_EXT=\"net\";BUILD_KIWAY_DLL"
+ )
+ target_link_libraries( cvpcb
+ #singletop # replaces common, giving us restrictive control and link warnings.
+ # There's way too much crap coming in from common yet.
+ common
+ bitmaps
+ ${wxWidgets_LIBRARIES}
+ )
+ if( MAKE_LINK_MAPS )
+ set_target_properties( cvpcb PROPERTIES
+ LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=cvpcb.map" )
+ endif()
+
+ if( APPLE )
+ set_target_properties( cvpcb PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
+ )
+
+ # put individual bundle outside of main bundle as a first step
+ # will be pulled into the main bundle when creating main bundle
+ install( TARGETS cvpcb
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+ install( CODE "
+ # override default embedded path settings
+ ${OSX_BUNDLE_OVERRIDE_PATHS}
+
+ # do all the work
+ include( BundleUtilities )
+ fixup_bundle( ${KICAD_BIN}/cvpcb.app/Contents/MacOS/cvpcb
+ \"\"
+ \"\"
+ )
+ " COMPONENT Runtime
+ )
+ else()
+ install( TARGETS cvpcb
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+ endif()
+
+endif() # no CVPCB exe
+
+
+# the main cvpcb program, in DSO form.
+add_library( cvpcb_kiface MODULE
+ cvpcb.cpp
+ ${CVPCB_SRCS}
+ ${CVPCB_DIALOGS}
+ )
+set_target_properties( cvpcb_kiface PROPERTIES
+ OUTPUT_NAME cvpcb
+ PREFIX ${KIFACE_PREFIX}
+ SUFFIX ${KIFACE_SUFFIX}
+ )
+target_link_libraries( cvpcb_kiface
+ 3d-viewer
+ pcbcommon
+ pcad2kicadpcb
+ common
+ bitmaps
+ polygon
+ gal
+ ${wxWidgets_LIBRARIES}
+ ${GDI_PLUS_LIBRARIES}
+ ${OPENMP_LIBRARIES} # used by 3d viewer
+ )
+
+if( BUILD_GITHUB_PLUGIN )
+ target_link_libraries( cvpcb_kiface github_plugin )
+endif()
+
+# Must follow github_plugin
+target_link_libraries( cvpcb_kiface ${Boost_LIBRARIES} )
+
+if( UNIX AND NOT APPLE )
+ # -lrt must follow Boost
+ target_link_libraries( cvpcb_kiface rt )
+endif()
+
+set_source_files_properties( cvpcb.cpp PROPERTIES
+ # The KIFACE is in cvpcb.cpp, export it:
+ COMPILE_DEFINITIONS "BUILD_KIWAY_DLL;COMPILING_DLL"
+ )
+
+if( MAKE_LINK_MAPS )
+ set_target_properties( cvpcb_kiface PROPERTIES
+ LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=_cvpcb.kiface.map" )
+endif()
+
+# these 2 binaries are a matched set, keep them together:
+if( APPLE )
+ # puts binaries into the *.app bundle while linking
+ set_target_properties( cvpcb_kiface PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_KIFACE_DIR}
+ )
+else()
+ install( TARGETS cvpcb_kiface
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+endif()
diff --git a/cvpcb/Info.plist b/cvpcb/Info.plist
new file mode 100644
index 0000000..4c6a7a3
--- /dev/null
+++ b/cvpcb/Info.plist
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeIconFile</key>
+ <string>cvpcb_doc.icns</string>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>net</string>
+ <string>cmp</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>cvpcb document</string>
+ <key>LSHandlerRank</key>
+ <string>Owner</string>
+ </dict>
+ </array>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>cvpcb</string>
+ <key>CFBundleGetInfoString</key>
+ <string></string>
+ <key>CFBundleIconFile</key>
+ <string>cvpcb.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.kicad-pcb.cvpcb</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleLongVersionString</key>
+ <string></string>
+ <key>CFBundleName</key>
+ <string>CvPCB</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string></string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string></string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+ <key>LSRequiresCarbon</key>
+ <true/>
+ <key>NSHumanReadableCopyright</key>
+ <string></string>
+ <key>NSHighResolutionCapable</key>
+ <string>True</string>
+</dict>
+</plist>
diff --git a/cvpcb/autosel.cpp b/cvpcb/autosel.cpp
new file mode 100644
index 0000000..e7731db
--- /dev/null
+++ b/cvpcb/autosel.cpp
@@ -0,0 +1,304 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file autosel.cpp
+ */
+
+// This file handle automatic selection of footprints, from .equ files which give
+// a footprint FPID associated to a component value.
+// These associations have this form:
+// 'FT232BL' 'QFP:LQFP-32_7x7mm_Pitch0.8mm'
+
+
+#include <fctsys.h>
+#include <common.h>
+#include <kiface_i.h>
+#include <project.h>
+#include <gestfich.h>
+#include <pgm_base.h>
+#include <kicad_string.h>
+#include <macros.h>
+
+#include <cvpcb.h>
+#include <cvpcb_mainframe.h>
+#include <cvstruct.h>
+#include <autosel.h>
+
+#define QUOTE '\''
+
+
+/*
+ * read the string between quotes and put it in aTarget
+ * put text in aTarget
+ * return a pointer to the last read char (the second quote if OK)
+ */
+wxString GetQuotedText( wxString& text )
+{
+ int i = text.Find( QUOTE );
+
+ if( wxNOT_FOUND == i )
+ return wxT( "" );
+
+ wxString shrt = text.Mid( i + 1 );
+ i = shrt.Find( QUOTE );
+
+ if( wxNOT_FOUND == i )
+ return wxT( "" );
+
+ text = shrt.Mid( i + 1 );
+ return shrt.Mid( 0, i );
+}
+
+
+// A sort compare function, used to sort a FOOTPRINT_EQUIVALENCE_LIST by cmp values
+// (m_ComponentValue member)
+bool sortListbyCmpValue( const FOOTPRINT_EQUIVALENCE& ref, const FOOTPRINT_EQUIVALENCE& test )
+{
+ return ref.m_ComponentValue.Cmp( test.m_ComponentValue ) >= 0;
+}
+
+
+// read the .equ files and populate the list of equivalents
+int CVPCB_MAINFRAME::buildEquivalenceList( FOOTPRINT_EQUIVALENCE_LIST& aList, wxString * aErrorMessages )
+{
+ char line[1024];
+ int error_count = 0;
+ FILE* file;
+ wxFileName fn;
+ wxString tmp, error_msg;
+
+ SEARCH_STACK& search = Kiface().KifaceSearch();
+
+ // Find equivalences in all available files, and populates the
+ // equiv_List with all equivalences found in .equ files
+ for( unsigned ii = 0; ii < m_EquFilesNames.GetCount(); ii++ )
+ {
+ fn = wxExpandEnvVars( m_EquFilesNames[ii] );
+
+ tmp = search.FindValidPath( fn.GetFullPath() );
+
+ if( !tmp )
+ {
+ error_count++;
+
+ if( aErrorMessages )
+ {
+ error_msg.Printf( _( "Equivalence file '%s' could not be found in the "
+ "default search paths." ),
+ GetChars( fn.GetFullName() ) );
+
+ if( ! aErrorMessages->IsEmpty() )
+ *aErrorMessages << wxT("\n\n");
+
+ *aErrorMessages += error_msg;
+ }
+
+ continue;
+ }
+
+ file = wxFopen( tmp, wxT( "rt" ) );
+
+ if( file == NULL )
+ {
+ error_count++;
+
+ if( aErrorMessages )
+ {
+ error_msg.Printf( _( "Error opening equivalence file '%s'." ), GetChars( tmp ) );
+
+ if( ! aErrorMessages->IsEmpty() )
+ *aErrorMessages << wxT("\n\n");
+
+ *aErrorMessages += error_msg;
+ }
+
+ continue;
+ }
+
+ while( GetLine( file, line, NULL, sizeof( line ) ) != NULL )
+ {
+ if( *line == 0 )
+ continue;
+
+ wxString wtext = FROM_UTF8( line );
+ wxString value = GetQuotedText( wtext );
+
+ if( value.IsEmpty() )
+ continue;
+
+ wxString footprint = GetQuotedText( wtext );
+
+ if( footprint.IsEmpty() )
+ continue;
+
+ value.Replace( wxT( " " ), wxT( "_" ) );
+
+ FOOTPRINT_EQUIVALENCE* equivItem = new FOOTPRINT_EQUIVALENCE();
+ equivItem->m_ComponentValue = value;
+ equivItem->m_FootprintFPID = footprint;
+ aList.push_back( equivItem );
+ }
+
+ fclose( file );
+ }
+
+ return error_count;
+}
+
+
+void CVPCB_MAINFRAME::AutomaticFootprintMatching( wxCommandEvent& event )
+{
+ FOOTPRINT_EQUIVALENCE_LIST equiv_List;
+ wxString msg, error_msg;
+
+ if( m_netlist.IsEmpty() )
+ return;
+
+ if( buildEquivalenceList( equiv_List, &error_msg ) )
+ wxMessageBox( error_msg, _( "Equivalence File Load Error" ), wxOK | wxICON_WARNING, this );
+
+ // Sort the association list by component value.
+ // When sorted, find duplicate definitions (i.e. 2 or more items
+ // having the same component value) is more easy.
+ std::sort( equiv_List.begin(), equiv_List.end(), sortListbyCmpValue );
+
+ // Display the number of footprint/component equivalences.
+ msg.Printf( _( "%lu footprint/cmp equivalences found." ), (unsigned long)equiv_List.size() );
+ SetStatusText( msg, 0 );
+
+ // Now, associate each free component with a footprint, when the association
+ // is found in list
+ m_skipComponentSelect = true;
+ error_msg.Empty();
+
+ for( unsigned kk = 0; kk < m_netlist.GetCount(); kk++ )
+ {
+ COMPONENT* component = m_netlist.GetComponent( kk );
+
+ bool found = false;
+
+ if( !component->GetFPID().empty() ) // the component has already a footprint
+ continue;
+
+ // Here a first attempt is made. We can have multiple equivItem of the same value.
+ // When happens, using the footprint filter of components can remove the ambiguity by
+ // filtering equivItem so one can use multiple equiv_List (for polar and
+ // non-polar caps for example)
+ wxString fpid_candidate;
+
+ for( unsigned idx = 0; idx < equiv_List.size(); idx++ )
+ {
+ FOOTPRINT_EQUIVALENCE& equivItem = equiv_List[idx];
+
+ if( equivItem.m_ComponentValue.CmpNoCase( component->GetValue() ) != 0 )
+ continue;
+
+ const FOOTPRINT_INFO *module = m_footprints.GetModuleInfo( equivItem.m_FootprintFPID );
+
+ bool equ_is_unique = true;
+ unsigned next = idx+1;
+ int previous = idx-1;
+
+ if( next < equiv_List.size() &&
+ equivItem.m_ComponentValue == equiv_List[next].m_ComponentValue )
+ equ_is_unique = false;
+
+ if( previous >= 0 &&
+ equivItem.m_ComponentValue == equiv_List[previous].m_ComponentValue )
+ equ_is_unique = false;
+
+ // If the equivalence is unique, no ambiguity: use the association
+ if( module && equ_is_unique )
+ {
+ SetNewPkg( equivItem.m_FootprintFPID, kk );
+ found = true;
+ break;
+ }
+
+ // Store the first candidate found in list, when equivalence is not unique
+ // We use it later.
+ if( module && fpid_candidate.IsEmpty() )
+ fpid_candidate = equivItem.m_FootprintFPID;
+
+ // The equivalence is not unique: use the footprint filter to try to remove
+ // ambiguity
+ // if the footprint filter does not remove ambiguity, we will use fpid_candidate
+ if( module )
+ {
+ size_t filtercount = component->GetFootprintFilters().GetCount();
+ found = ( 0 == filtercount ); // if no entries, do not filter
+
+ for( size_t jj = 0; jj < filtercount && !found; jj++ )
+ {
+ found = module->GetFootprintName().Matches( component->GetFootprintFilters()[jj] );
+ }
+ }
+ else
+ {
+ msg.Printf( _( "Component %s: footprint %s not found in any of the project "
+ "footprint libraries." ),
+ GetChars( component->GetReference() ),
+ GetChars( equivItem.m_FootprintFPID ) );
+
+ if( ! error_msg.IsEmpty() )
+ error_msg << wxT("\n\n");
+
+ error_msg += msg;
+ }
+
+ if( found )
+ {
+ SetNewPkg( equivItem.m_FootprintFPID, kk );
+ break;
+ }
+ }
+
+ if( found )
+ continue;
+ else if( !fpid_candidate.IsEmpty() )
+ {
+ SetNewPkg( fpid_candidate, kk );
+ continue;
+ }
+
+ // obviously the last chance: there's only one filter matching one footprint
+ if( 1 == component->GetFootprintFilters().GetCount() )
+ {
+ // we do not need to analyze wildcards: single footprint do not
+ // contain them and if there are wildcards it just will not match any
+ const FOOTPRINT_INFO* module = m_footprints.GetModuleInfo( component->GetFootprintFilters()[0] );
+
+ if( module )
+ {
+ SetNewPkg( component->GetFootprintFilters()[0], kk );
+ }
+ }
+ }
+
+ if( !error_msg.IsEmpty() )
+ wxMessageBox( error_msg, _( "CvPcb Warning" ), wxOK | wxICON_WARNING, this );
+
+ m_skipComponentSelect = false;
+ m_compListBox->Refresh();
+}
diff --git a/cvpcb/autosel.h b/cvpcb/autosel.h
new file mode 100644
index 0000000..30abce0
--- /dev/null
+++ b/cvpcb/autosel.h
@@ -0,0 +1,45 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef AUTOSEL_H
+#define AUTOSEL_H
+
+// A helper class to handle info read in .equ files, which gives a footprint FPID
+// corresponding to a component value.
+// Each line is something like:
+// 'FT232BL' 'QFP:LQFP-32_7x7mm_Pitch0.8mm'
+//
+
+
+class FOOTPRINT_EQUIVALENCE
+{
+public:
+ wxString m_ComponentValue; // The value of a component
+ wxString m_FootprintFPID; // the footprint FPID corresponding to this value
+
+ FOOTPRINT_EQUIVALENCE() {}
+};
+
+typedef boost::ptr_vector< FOOTPRINT_EQUIVALENCE > FOOTPRINT_EQUIVALENCE_LIST;
+
+#endif // ifndef AUTOSEL_H
diff --git a/cvpcb/cfg.cpp b/cvpcb/cfg.cpp
new file mode 100644
index 0000000..3cedd1e
--- /dev/null
+++ b/cvpcb/cfg.cpp
@@ -0,0 +1,92 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file cfg.cpp
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <fp_lib_table.h>
+#include <id.h>
+#include <common.h>
+#include <gestfich.h>
+#include <config_params.h>
+#include <wildcards_and_files_ext.h>
+#include <fp_lib_table.h>
+#include <confirm.h>
+
+#include <cvpcb.h>
+#include <cvpcb_mainframe.h>
+#include <class_DisplayFootprintsFrame.h>
+
+
+PARAM_CFG_ARRAY& CVPCB_MAINFRAME::GetProjectFileParameters()
+{
+ if( !m_projectFileParams.empty() )
+ return m_projectFileParams;
+
+ m_projectFileParams.push_back( new PARAM_CFG_BASE( GROUP_PCB_LIBS, PARAM_COMMAND_ERASE ) );
+
+ m_projectFileParams.push_back( new PARAM_CFG_LIBNAME_LIST(
+ wxT( "EquName" ), &m_EquFilesNames, GROUP_CVP_EQU ) );
+
+ m_projectFileParams.push_back( new PARAM_CFG_WXSTRING(
+ wxT( "NetIExt" ), &m_NetlistFileExtension ) );
+
+ return m_projectFileParams;
+}
+
+
+void CVPCB_MAINFRAME::LoadProjectFile()
+{
+ PROJECT& prj = Prj();
+
+ m_ModuleLibNames.Clear();
+ m_EquFilesNames.Clear();
+
+ prj.ConfigLoad( Kiface().KifaceSearch(), GROUP_CVP, GetProjectFileParameters() );
+
+ if( m_NetlistFileExtension.IsEmpty() )
+ m_NetlistFileExtension = wxT( "net" );
+}
+
+
+void CVPCB_MAINFRAME::SaveProjectFile( wxCommandEvent& aEvent )
+{
+ PROJECT& prj = Prj();
+ SetTitle( wxString::Format( _( "Project file: '%s'" ), GetChars( prj.GetProjectFullName() ) ) );
+ wxFileName fn = prj.GetProjectFullName();
+
+ if( !IsWritable( fn ) )
+ {
+ wxMessageBox( _( "Project file '%s' is not writable" ), fn.GetFullPath() );
+ return;
+ }
+
+ wxString pro_name = fn.GetFullPath();
+
+ prj.ConfigSave( Kiface().KifaceSearch(), GROUP_CVP, GetProjectFileParameters(), pro_name );
+}
+
diff --git a/cvpcb/class_DisplayFootprintsFrame.cpp b/cvpcb/class_DisplayFootprintsFrame.cpp
new file mode 100644
index 0000000..0b3a76a
--- /dev/null
+++ b/cvpcb/class_DisplayFootprintsFrame.cpp
@@ -0,0 +1,569 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2007-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_DisplayFootprintsFrame.cpp
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <class_draw_panel_gal.h>
+#include <confirm.h>
+#include <macros.h>
+#include <bitmaps.h>
+#include <msgpanel.h>
+#include <wildcards_and_files_ext.h>
+#include <fpid.h>
+#include <fp_lib_table.h>
+#include <pcbcommon.h>
+
+#include <io_mgr.h>
+#include <class_module.h>
+#include <class_board.h>
+
+#include <cvpcb_mainframe.h>
+#include <class_DisplayFootprintsFrame.h>
+#include <cvpcb_id.h>
+#include <cvstruct.h>
+
+#include <3d_viewer.h>
+
+
+BEGIN_EVENT_TABLE( DISPLAY_FOOTPRINTS_FRAME, PCB_BASE_FRAME )
+ EVT_CLOSE( DISPLAY_FOOTPRINTS_FRAME::OnCloseWindow )
+ EVT_SIZE( DISPLAY_FOOTPRINTS_FRAME::OnSize )
+ EVT_TOOL( ID_OPTIONS_SETUP, DISPLAY_FOOTPRINTS_FRAME::InstallOptionsDisplay )
+ EVT_TOOL( ID_CVPCB_SHOW3D_FRAME, DISPLAY_FOOTPRINTS_FRAME::Show3D_Frame )
+
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH,
+ DISPLAY_FOOTPRINTS_FRAME::OnSelectOptionToolbar)
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH,
+ DISPLAY_FOOTPRINTS_FRAME::OnSelectOptionToolbar)
+
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH,
+ DISPLAY_FOOTPRINTS_FRAME::OnUpdateTextDrawMode )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH,
+ DISPLAY_FOOTPRINTS_FRAME::OnUpdateLineDrawMode )
+END_EVENT_TABLE()
+
+
+DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( KIWAY* aKiway, CVPCB_MAINFRAME* aParent ) :
+ PCB_BASE_FRAME( aKiway, aParent, FRAME_CVPCB_DISPLAY, _( "Footprint Viewer" ),
+ wxDefaultPosition, wxDefaultSize,
+ KICAD_DEFAULT_DRAWFRAME_STYLE, FOOTPRINTVIEWER_FRAME_NAME )
+{
+ m_showAxis = true; // true to draw axis.
+
+ // Give an icon
+ wxIcon icon;
+
+ icon.CopyFromBitmap( KiBitmap( icon_cvpcb_xpm ) );
+ SetIcon( icon );
+
+ SetBoard( new BOARD() );
+ SetScreen( new PCB_SCREEN( GetPageSizeIU() ) );
+
+ LoadSettings( config() );
+
+ // Initialize grid id to a default value if not found in config or incorrect:
+ if( !( GetScreen()->GridExists( m_LastGridSizeId + ID_POPUP_GRID_LEVEL_1000 ) ) )
+ m_LastGridSizeId = ID_POPUP_GRID_LEVEL_500 - ID_POPUP_GRID_LEVEL_1000;
+
+ GetScreen()->SetGrid( m_LastGridSizeId + ID_POPUP_GRID_LEVEL_1000 );
+
+ // Initialize some display options
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+ displ_opts->m_DisplayPadIsol = false; // Pad clearance has no meaning here
+
+ // Track and via clearance has no meaning here.
+ displ_opts->m_ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE;
+
+ SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
+ ReCreateHToolbar();
+ ReCreateVToolbar();
+ ReCreateOptToolbar();
+
+ m_auimgr.SetManagedWindow( this );
+
+ EDA_PANEINFO horiz;
+ horiz.HorizontalToolbarPane();
+
+ EDA_PANEINFO vert;
+ vert.VerticalToolbarPane();
+
+ EDA_PANEINFO mesg;
+ mesg.MessageToolbarPane();
+
+ m_auimgr.AddPane( m_mainToolBar,
+ wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top(). Row( 0 ) );
+
+ if( m_drawToolBar ) // Currently, no vertical right toolbar.
+ m_auimgr.AddPane( m_drawToolBar,
+ wxAuiPaneInfo( vert ).Name( wxT( "m_drawToolBar" ) ).Right() );
+
+ m_auimgr.AddPane( m_canvas,
+ wxAuiPaneInfo().Name( wxT( "DisplayFrame" ) ).CentrePane() );
+
+ m_auimgr.AddPane( m_messagePanel,
+ wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );
+
+ m_auimgr.AddPane( m_optionsToolBar,
+ wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ).Left() );
+
+ m_auimgr.Update();
+
+ Show( true );
+}
+
+
+DISPLAY_FOOTPRINTS_FRAME::~DISPLAY_FOOTPRINTS_FRAME()
+{
+ delete GetScreen();
+ SetScreen( NULL ); // Be sure there is no double deletion
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::OnCloseWindow( wxCloseEvent& event )
+{
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->Close( true );
+
+ Destroy();
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::ReCreateVToolbar()
+{
+ // Currently, no vertical right toolbar.
+ // So do nothing
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::ReCreateOptToolbar()
+{
+ if( m_optionsToolBar )
+ return;
+
+ // Create options tool bar.
+ m_optionsToolBar = new wxAuiToolBar( this, ID_OPT_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GRID, wxEmptyString, KiBitmap( grid_xpm ),
+ _( "Hide grid" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_POLAR_COORD, wxEmptyString,
+ KiBitmap( polar_coord_xpm ),
+ _( "Display polar coordinates" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_INCH, wxEmptyString,
+ KiBitmap( unit_inch_xpm ),
+ _( "Units in inches" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_MM, wxEmptyString,
+ KiBitmap( unit_mm_xpm ),
+ _( "Units in millimeters" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_CURSOR, wxEmptyString,
+ KiBitmap( cursor_shape_xpm ),
+ _( "Change cursor shape" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_PADS_SKETCH, wxEmptyString,
+ KiBitmap( pad_sketch_xpm ),
+ _( "Show pads in outline mode" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH, wxEmptyString,
+ KiBitmap( text_sketch_xpm ),
+ _( "Show texts in line mode" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH, wxEmptyString,
+ KiBitmap( show_mod_edge_xpm ),
+ _( "Show outlines in line mode" ), wxITEM_CHECK );
+
+ m_optionsToolBar->Realize();
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::ReCreateHToolbar()
+{
+ if( m_mainToolBar != NULL )
+ return;
+
+ m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
+
+ m_mainToolBar->AddTool( ID_OPTIONS_SETUP, wxEmptyString, KiBitmap( display_options_xpm ),
+ _( "Display options" ) );
+
+ m_mainToolBar->AddSeparator();
+
+ m_mainToolBar->AddTool( ID_ZOOM_IN, wxEmptyString, KiBitmap( zoom_in_xpm ),
+ _( "Zoom in (F1)" ) );
+
+ m_mainToolBar->AddTool( ID_ZOOM_OUT, wxEmptyString, KiBitmap( zoom_out_xpm ),
+ _( "Zoom out (F2)" ) );
+
+ m_mainToolBar->AddTool( ID_ZOOM_REDRAW, wxEmptyString, KiBitmap( zoom_redraw_xpm ),
+ _( "Redraw view (F3)" ) );
+
+ m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ),
+ _( "Zoom auto (Home)" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_CVPCB_SHOW3D_FRAME, wxEmptyString, KiBitmap( three_d_xpm ),
+ _( "3D Display (Alt+3)" ) );
+
+ // after adding the buttons to the toolbar, must call Realize() to reflect
+ // the changes
+ m_mainToolBar->Realize();
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::OnUpdateTextDrawMode( wxUpdateUIEvent& aEvent )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ wxString msgTextsFill[2] = { _( "Show texts in filled mode" ),
+ _( "Show texts in sketch mode" ) };
+
+ unsigned i = displ_opts->m_DisplayModTextFill == SKETCH ? 0 : 1;
+
+ aEvent.Check( displ_opts->m_DisplayModTextFill == SKETCH );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH, msgTextsFill[i] );
+
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::OnUpdateLineDrawMode( wxUpdateUIEvent& aEvent )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ wxString msgEdgesFill[2] = { _( "Show outlines in filled mode" ),
+ _( "Show outlines in sketch mode" ) };
+
+ int i = displ_opts->m_DisplayModEdgeFill == SKETCH ? 0 : 1;
+
+ aEvent.Check( displ_opts->m_DisplayModEdgeFill == SKETCH );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH, msgEdgesFill[i] );
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
+{
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& MousePos )
+{
+}
+
+
+bool DISPLAY_FOOTPRINTS_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu )
+{
+ return true;
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ switch( id )
+ {
+ case ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH:
+ displ_opts->m_DisplayModTextFill = displ_opts->m_DisplayModTextFill == FILLED ? SKETCH : FILLED;
+ m_canvas->Refresh( );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH:
+ displ_opts->m_DisplayModEdgeFill = displ_opts->m_DisplayModEdgeFill == FILLED ? SKETCH : FILLED;
+ m_canvas->Refresh();
+ break;
+
+ default:
+ DisplayError( this,
+ wxT( "DISPLAY_FOOTPRINTS_FRAME::OnSelectOptionToolbar error" ) );
+ break;
+ }
+}
+
+
+bool DISPLAY_FOOTPRINTS_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
+{
+ bool eventHandled = true;
+
+ // Filter out the 'fake' mouse motion after a keyboard movement
+ if( !aHotKey && m_movingCursorWithKeyboard )
+ {
+ m_movingCursorWithKeyboard = false;
+ return false;
+ }
+
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+ cmd.SetEventObject( this );
+
+ wxPoint pos = aPosition;
+ wxPoint oldpos = GetCrossHairPosition();
+ GeneralControlKeyMovement( aHotKey, &pos, true );
+
+ switch( aHotKey )
+ {
+ case WXK_F1:
+ cmd.SetId( ID_POPUP_ZOOM_IN );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case WXK_F2:
+ cmd.SetId( ID_POPUP_ZOOM_OUT );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case WXK_F3:
+ cmd.SetId( ID_ZOOM_REDRAW );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case WXK_F4:
+ cmd.SetId( ID_POPUP_ZOOM_CENTER );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case WXK_HOME:
+ cmd.SetId( ID_ZOOM_PAGE );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case ' ':
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ break;
+
+ case GR_KB_ALT + '3':
+ cmd.SetId( ID_CVPCB_SHOW3D_FRAME );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ default:
+ eventHandled = false;
+ }
+
+ SetCrossHairPosition( pos );
+ RefreshCrossHair( oldpos, aPosition, aDC );
+
+ UpdateStatusBar(); /* Display new cursor coordinates */
+
+ return eventHandled;
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::Show3D_Frame( wxCommandEvent& event )
+{
+ if( m_Draw3DFrame )
+ {
+ // Raising the window does not show the window on Windows if iconized.
+ // This should work on any platform.
+ if( m_Draw3DFrame->IsIconized() )
+ m_Draw3DFrame->Iconize( false );
+
+ m_Draw3DFrame->Raise();
+
+ // Raising the window does not set the focus on Linux. This should work on any platform.
+ if( wxWindow::FindFocus() != m_Draw3DFrame )
+ m_Draw3DFrame->SetFocus();
+
+ return;
+ }
+
+ m_Draw3DFrame = new EDA_3D_FRAME( &Kiway(), this, _( "3D Viewer" ) );
+ m_Draw3DFrame->Raise(); // Needed with some Window Managers
+ m_Draw3DFrame->Show( true );
+}
+
+
+/**
+ * Virtual function needed by the PCB_SCREEN class derived from BASE_SCREEN
+ * this is a virtual pure function in BASE_SCREEN
+ * do nothing in Cvpcb
+ * could be removed later
+ */
+void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER&, int )
+{
+}
+
+
+bool DISPLAY_FOOTPRINTS_FRAME::IsGridVisible() const
+{
+ return m_drawGrid;
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::SetGridVisibility(bool aVisible)
+{
+ m_drawGrid = aVisible;
+}
+
+
+EDA_COLOR_T DISPLAY_FOOTPRINTS_FRAME::GetGridColor() const
+{
+ return DARKGRAY;
+}
+
+
+MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
+{
+ MODULE* footprint = NULL;
+
+ try
+ {
+ FPID fpid;
+
+ if( fpid.Parse( aFootprintName ) >= 0 )
+ {
+ DisplayInfoMessage( this, wxString::Format( wxT( "Footprint ID <%s> is not valid." ),
+ GetChars( aFootprintName ) ) );
+ return NULL;
+ }
+
+ std::string nickname = fpid.GetLibNickname();
+ std::string fpname = fpid.GetFootprintName();
+
+ wxLogDebug( wxT( "Load footprint <%s> from library <%s>." ),
+ fpname.c_str(), nickname.c_str() );
+
+ footprint = Prj().PcbFootprintLibs()->FootprintLoad(
+ FROM_UTF8( nickname.c_str() ), FROM_UTF8( fpname.c_str() ) );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( this, ioe.errorText );
+ return NULL;
+ }
+
+ if( footprint )
+ {
+ footprint->SetParent( (EDA_ITEM*) GetBoard() );
+ footprint->SetPosition( wxPoint( 0, 0 ) );
+ return footprint;
+ }
+
+ wxString msg = wxString::Format( _( "Footprint '%s' not found" ), aFootprintName.GetData() );
+ DisplayError( this, msg );
+ return NULL;
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::InitDisplay()
+{
+ wxString msg;
+
+ CVPCB_MAINFRAME* parentframe = (CVPCB_MAINFRAME *) GetParent();
+
+ wxString footprintName = parentframe->m_footprintListBox->GetSelectedFootprint();
+
+ if( !footprintName.IsEmpty() )
+ {
+ msg.Printf( _( "Footprint: %s" ), GetChars( footprintName ) );
+
+ SetTitle( msg );
+ const FOOTPRINT_INFO* module_info = parentframe->m_footprints.GetModuleInfo( footprintName );
+
+ const wxChar* libname;
+
+ if( module_info )
+ libname = GetChars( module_info->GetNickname() );
+ else
+ libname = GetChars( wxT( "???" ) );
+
+ msg.Printf( _( "Lib: %s" ), libname );
+
+ SetStatusText( msg, 0 );
+
+ if( GetBoard()->m_Modules.GetCount() )
+ {
+ // there is only one module in the list
+ GetBoard()->m_Modules.DeleteAll();
+ }
+
+ MODULE* module = Get_Module( footprintName );
+
+ if( module )
+ GetBoard()->m_Modules.PushBack( module );
+
+ Zoom_Automatique( false );
+ }
+ else // No footprint to display. Erase old footprint, if any
+ {
+ if( GetBoard()->m_Modules.GetCount() )
+ {
+ GetBoard()->m_Modules.DeleteAll();
+ Zoom_Automatique( false );
+ SetStatusText( wxEmptyString, 0 );
+ }
+ }
+
+ // Display new cursor coordinates and zoom value:
+ UpdateStatusBar();
+
+ GetCanvas()->Refresh();
+
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->NewDisplay();
+}
+
+
+void DISPLAY_FOOTPRINTS_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
+{
+ if( !GetBoard() )
+ return;
+
+ m_canvas->DrawBackGround( DC );
+ GetBoard()->Draw( m_canvas, DC, GR_COPY );
+
+ MODULE* Module = GetBoard()->m_Modules;
+
+ if ( Module )
+ {
+ MSG_PANEL_ITEMS items;
+ Module->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+ }
+
+ m_canvas->DrawCrossHair( DC );
+}
+
+
+/*
+ * Redraw the BOARD items but not cursors, axis or grid.
+ */
+void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ GR_DRAWMODE aDrawMode, const wxPoint& aOffset )
+{
+ if( m_Modules )
+ {
+ m_Modules->Draw( aPanel, aDC, GR_COPY );
+ }
+}
diff --git a/cvpcb/class_DisplayFootprintsFrame.h b/cvpcb/class_DisplayFootprintsFrame.h
new file mode 100644
index 0000000..6f4b0e9
--- /dev/null
+++ b/cvpcb/class_DisplayFootprintsFrame.h
@@ -0,0 +1,138 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2007-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_DisplayFootprintsFrame.h
+ */
+
+
+#include <wxBasePcbFrame.h>
+
+// The name (for wxWidgets) of the footprint viewer frame
+#define FOOTPRINTVIEWER_FRAME_NAME wxT( "FootprintViewerFrame" )
+
+class CVPCB_MAINFRAME;
+
+
+/**
+ * Class DISPLAY_FOOTPRINTS_FRAME
+ * is used to display footprints.
+ */
+class DISPLAY_FOOTPRINTS_FRAME : public PCB_BASE_FRAME
+{
+public:
+ DISPLAY_FOOTPRINTS_FRAME( KIWAY* aKiway, CVPCB_MAINFRAME* aParent );
+ ~DISPLAY_FOOTPRINTS_FRAME();
+
+ void OnCloseWindow( wxCloseEvent& Event );
+
+ /*
+ * Draws the current highlighted footprint.
+ */
+ void RedrawActiveWindow( wxDC* DC, bool EraseBg );
+
+ void ReCreateHToolbar();
+ void ReCreateVToolbar();
+ void ReCreateOptToolbar();
+ void RecreateMenuBar();
+
+ void OnSelectOptionToolbar( wxCommandEvent& event );
+
+ void OnUpdateTextDrawMode( wxUpdateUIEvent& aEvent );
+ void OnUpdateLineDrawMode( wxUpdateUIEvent& aEvent );
+
+ /**
+ * Function InitDisplay
+ * Refresh the full display for this frame:
+ * Set the title, the status line and redraw the canvas
+ * Must be called after the footprint to display is modifed
+ */
+ void InitDisplay();
+
+ /**
+ * Function IsGridVisible() , virtual
+ * @return true if the grid must be shown
+ */
+ virtual bool IsGridVisible() const;
+
+ /**
+ * Function SetGridVisibility() , virtual
+ * It may be overloaded by derived classes
+ * if you want to store/retrieve the grid visibility in configuration.
+ * @param aVisible = true if the grid must be shown
+ */
+ virtual void SetGridVisibility( bool aVisible );
+ /**
+ * Function GetGridColor() , virtual
+ * @return the color of the grid
+ */
+ virtual EDA_COLOR_T GetGridColor() const;
+
+ void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
+ void OnLeftDClick( wxDC* DC, const wxPoint& MousePos );
+ bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
+ bool GeneralControl( wxDC* DC, const wxPoint& aPosition, int aHotKey = 0 );
+ void InstallOptionsDisplay( wxCommandEvent& event );
+ MODULE* Get_Module( const wxString& CmpName );
+
+ ///> @copydoc EDA_DRAW_FRAME::GetHotKeyDescription()
+ EDA_HOTKEY* GetHotKeyDescription( int aCommand ) const { return NULL; }
+
+ void Process_Settings( wxCommandEvent& event );
+
+ /**
+ * Display 3D frame of current footprint selection.
+ */
+ void Show3D_Frame( wxCommandEvent& event );
+
+ /* SaveCopyInUndoList() virtual
+ * currently: do nothing in CvPcb.
+ * but but be defined because it is a pure virtual in PCB_BASE_FRAME
+ */
+ virtual void SaveCopyInUndoList( BOARD_ITEM* aItemToCopy,
+ UNDO_REDO_T aTypeCommand = UR_UNSPECIFIED,
+ const wxPoint& aTransformPoint = wxPoint( 0, 0 ) )
+ {
+ }
+
+
+ /**
+ * Function SaveCopyInUndoList (overloaded).
+ * Creates a new entry in undo list of commands.
+ * add a list of pickers to handle a list of items
+ * @param aItemsList = the list of items modified by the command to undo
+ * @param aTypeCommand = command type (see enum UNDO_REDO_T)
+ * @param aTransformPoint = the reference point of the transformation,
+ * for commands like move
+ */
+ virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
+ UNDO_REDO_T aTypeCommand,
+ const wxPoint& aTransformPoint = wxPoint( 0, 0 ) )
+ {
+ // currently: do nothing in CvPcb.
+ }
+
+
+ DECLARE_EVENT_TABLE()
+};
diff --git a/cvpcb/class_components_listbox.cpp b/cvpcb/class_components_listbox.cpp
new file mode 100644
index 0000000..c4188f3
--- /dev/null
+++ b/cvpcb/class_components_listbox.cpp
@@ -0,0 +1,184 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_components_listbox.cpp
+ */
+
+#include <fctsys.h>
+#include <wxstruct.h>
+
+#include <cvpcb.h>
+#include <cvpcb_mainframe.h>
+#include <cvstruct.h>
+#include <cvpcb_id.h>
+
+
+COMPONENTS_LISTBOX::COMPONENTS_LISTBOX( CVPCB_MAINFRAME* parent, wxWindowID id,
+ const wxPoint& loc, const wxSize& size ) :
+ ITEMS_LISTBOX_BASE( parent, id, loc, size, 0 )
+{
+}
+
+
+COMPONENTS_LISTBOX::~COMPONENTS_LISTBOX()
+{
+}
+
+
+BEGIN_EVENT_TABLE( COMPONENTS_LISTBOX, ITEMS_LISTBOX_BASE )
+ EVT_CHAR( COMPONENTS_LISTBOX::OnChar )
+ EVT_LIST_ITEM_SELECTED( ID_CVPCB_COMPONENT_LIST, COMPONENTS_LISTBOX::OnSelectComponent )
+END_EVENT_TABLE()
+
+
+void COMPONENTS_LISTBOX::Clear()
+{
+ m_ComponentList.Clear();
+ SetItemCount( 0 );
+}
+
+
+int COMPONENTS_LISTBOX::GetCount()
+{
+ return m_ComponentList.Count();
+}
+
+
+void COMPONENTS_LISTBOX::SetString( unsigned linecount, const wxString& text )
+{
+ if( linecount >= m_ComponentList.Count() )
+ linecount = m_ComponentList.Count() - 1;
+
+ if( m_ComponentList.Count() > 0 )
+ {
+ m_ComponentList[linecount] = text;
+ UpdateWidth( linecount );
+ }
+}
+
+
+void COMPONENTS_LISTBOX::AppendLine( const wxString& text )
+{
+ m_ComponentList.Add( text );
+ int lines = m_ComponentList.Count();
+ SetItemCount( lines );
+ UpdateWidth( lines - 1 );
+}
+
+
+wxString COMPONENTS_LISTBOX::OnGetItemText( long item, long column ) const
+{
+ return m_ComponentList.Item( item );
+}
+
+
+void COMPONENTS_LISTBOX::SetSelection( int index, bool State )
+{
+ if( index >= GetCount() )
+ index = GetCount() - 1;
+
+ if( (index >= 0) && (GetCount() > 0) )
+ {
+ Select( index, State );
+ EnsureVisible( index );
+
+#ifdef __WXMAC__
+ Update();
+#endif
+ }
+}
+
+
+void COMPONENTS_LISTBOX::OnChar( wxKeyEvent& event )
+{
+ int key = event.GetKeyCode();
+
+ switch( key )
+ {
+ case WXK_TAB:
+ case WXK_RIGHT:
+ case WXK_NUMPAD_RIGHT:
+ GetParent()->ChangeFocus( true );
+ return;
+
+ case WXK_LEFT:
+ case WXK_NUMPAD_LEFT:
+ GetParent()->ChangeFocus( false );
+ return;
+
+ case WXK_HOME:
+ case WXK_END:
+ case WXK_UP:
+ case WXK_DOWN:
+ case WXK_PAGEUP:
+ case WXK_PAGEDOWN:
+ event.Skip();
+ return;
+
+
+ default:
+ break;
+ }
+
+ // Search for an item name starting by the key code:
+ key = toupper( key );
+
+ for( unsigned ii = 0; ii < m_ComponentList.GetCount(); ii++ )
+ {
+ wxString text = m_ComponentList.Item( ii );
+
+ // Search for the start char of the footprint name. Skip the line number.
+ text.Trim( false ); // Remove leading spaces in line
+ unsigned jj = 0;
+
+ for( ; jj < text.Len(); jj++ )
+ { // skip line number
+ if( text[jj] == ' ' )
+ break;
+ }
+
+ for( ; jj < text.Len(); jj++ )
+ { // skip blanks
+ if( text[jj] != ' ' )
+ break;
+ }
+
+ int start_char = toupper( text[jj] );
+
+ if( key == start_char )
+ {
+ SetSelection( (int) ii, true ); // Ensure visible
+ break;
+ }
+ }
+
+ event.Skip();
+}
+
+
+void COMPONENTS_LISTBOX::OnSelectComponent( wxListEvent& event )
+{
+ SetFocus();
+ GetParent()->OnSelectComponent( event );
+}
diff --git a/cvpcb/class_footprints_listbox.cpp b/cvpcb/class_footprints_listbox.cpp
new file mode 100644
index 0000000..78ce524
--- /dev/null
+++ b/cvpcb/class_footprints_listbox.cpp
@@ -0,0 +1,291 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_footprints_listbox.cpp
+ * class to display the list of available footprints
+ */
+
+#include <fctsys.h>
+#include <wxstruct.h>
+#include <macros.h>
+#include <pgm_base.h>
+#include <wildcards_and_files_ext.h>
+
+#include <cvpcb.h>
+#include <cvpcb_mainframe.h>
+#include <cvstruct.h>
+#include <cvpcb_id.h>
+
+
+FOOTPRINTS_LISTBOX::FOOTPRINTS_LISTBOX( CVPCB_MAINFRAME* parent,
+ wxWindowID id, const wxPoint& loc,
+ const wxSize& size ) :
+ ITEMS_LISTBOX_BASE( parent, id, loc, size, wxLC_SINGLE_SEL )
+{
+}
+
+
+FOOTPRINTS_LISTBOX::~FOOTPRINTS_LISTBOX()
+{
+}
+
+
+int FOOTPRINTS_LISTBOX::GetCount()
+{
+ return m_footprintList.Count();
+}
+
+
+void FOOTPRINTS_LISTBOX::SetString( unsigned linecount, const wxString& text )
+{
+ unsigned count = m_footprintList.Count();
+ if( count > 0 )
+ {
+ if( linecount >= count )
+ linecount = count - 1;
+ m_footprintList[linecount] = text;
+ }
+ UpdateWidth( linecount );
+}
+
+
+wxString FOOTPRINTS_LISTBOX::GetSelectedFootprint()
+{
+ wxString footprintName;
+ int ii = GetFirstSelected();
+
+ if( ii >= 0 )
+ {
+ wxString msg = m_footprintList[ii];
+ msg.Trim( true );
+ msg.Trim( false );
+ footprintName = msg.AfterFirst( wxChar( ' ' ) );
+ }
+
+ return footprintName;
+}
+
+
+void FOOTPRINTS_LISTBOX::AppendLine( const wxString& text )
+{
+ m_footprintList.Add( text );
+ int lines = m_footprintList.Count();
+ SetItemCount( lines );
+ UpdateWidth( lines - 1 );
+}
+
+
+wxString FOOTPRINTS_LISTBOX::OnGetItemText( long item, long column ) const
+{
+ if( item < 0 || item >= (long)m_footprintList.GetCount() )
+ return wxEmptyString;
+
+ return m_footprintList.Item( item );
+}
+
+
+void FOOTPRINTS_LISTBOX::SetSelection( int index, bool State )
+{
+ if( index >= GetCount() )
+ index = GetCount() - 1;
+
+ if( (index >= 0) && (GetCount() > 0) )
+ {
+#ifndef __WXMAC__
+ Select( index, State );
+#endif
+
+ EnsureVisible( index );
+
+#ifdef __WXMAC__
+ Refresh();
+#endif
+ }
+}
+
+
+void FOOTPRINTS_LISTBOX::SetFootprints( FOOTPRINT_LIST& aList, const wxString& aLibName,
+ COMPONENT* aComponent, int aFilterType )
+{
+ wxArrayString newList;
+ wxString msg;
+ wxString oldSelection;
+
+ if( GetSelection() >= 0 && GetSelection() < (int)m_footprintList.GetCount() )
+ oldSelection = m_footprintList[ GetSelection() ];
+
+ for( unsigned ii = 0; ii < aList.GetCount(); ii++ )
+ {
+ if( aFilterType == UNFILTERED )
+ {
+ msg.Printf( wxT( "%3d %s:%s" ), int( newList.GetCount() + 1 ),
+ GetChars( aList.GetItem( ii ).GetNickname() ),
+ GetChars( aList.GetItem( ii ).GetFootprintName() ) );
+ newList.Add( msg );
+ continue;
+ }
+
+ if( (aFilterType & BY_LIBRARY) && !aLibName.IsEmpty()
+ && !aList.GetItem( ii ).InLibrary( aLibName ) )
+ continue;
+
+ if( (aFilterType & BY_COMPONENT) && aComponent
+ && !aComponent->MatchesFootprintFilters( aList.GetItem( ii ).GetFootprintName() ) )
+ continue;
+
+ if( (aFilterType & BY_PIN_COUNT) && aComponent
+ && aComponent->GetNetCount() != aList.GetItem( ii ).GetUniquePadCount() )
+ continue;
+
+ msg.Printf( wxT( "%3d %s:%s" ), int( newList.GetCount() + 1 ),
+ GetChars( aList.GetItem( ii ).GetNickname() ),
+ GetChars( aList.GetItem( ii ).GetFootprintName() ) );
+ newList.Add( msg );
+ }
+
+ if( newList == m_footprintList )
+ return;
+
+ m_footprintList = newList;
+
+ int selection = m_footprintList.Index( oldSelection );
+
+ if( selection == wxNOT_FOUND )
+ selection = 0;
+
+ DeleteAllItems();
+
+ if( m_footprintList.GetCount() )
+ {
+ SetItemCount( m_footprintList.GetCount() );
+ SetSelection( selection, true );
+ RefreshItems( 0L, m_footprintList.GetCount()-1 );
+ UpdateWidth();
+ }
+}
+
+
+BEGIN_EVENT_TABLE( FOOTPRINTS_LISTBOX, ITEMS_LISTBOX_BASE )
+ EVT_CHAR( FOOTPRINTS_LISTBOX::OnChar )
+ EVT_LIST_ITEM_SELECTED( ID_CVPCB_FOOTPRINT_LIST, FOOTPRINTS_LISTBOX::OnLeftClick )
+ EVT_LIST_ITEM_ACTIVATED( ID_CVPCB_FOOTPRINT_LIST, FOOTPRINTS_LISTBOX::OnLeftDClick )
+END_EVENT_TABLE()
+
+
+void FOOTPRINTS_LISTBOX::OnLeftClick( wxListEvent& event )
+{
+ if( m_footprintList.IsEmpty() )
+ return;
+
+ // On some plateforms (OSX) the focus is lost when the viewers (fp and 3D viewers)
+ // are opened and refreshed when a new footprint is selected.
+ // If the listbox has the focus before selecting a new footprint, it will be forced
+ // after selection.
+ bool hasFocus = HasFocus();
+
+ // If the footprint view window is displayed, update the footprint.
+ if( GetParent()->GetFpViewerFrame() )
+ GetParent()->CreateScreenCmp();
+
+ GetParent()->DisplayStatus();
+
+ if( hasFocus )
+ SetFocus();
+}
+
+
+void FOOTPRINTS_LISTBOX::OnLeftDClick( wxListEvent& event )
+{
+ wxString footprintName = GetSelectedFootprint();
+
+ GetParent()->SetNewPkg( footprintName );
+}
+
+
+void FOOTPRINTS_LISTBOX::OnChar( wxKeyEvent& event )
+{
+ int key = event.GetKeyCode();
+
+ switch( key )
+ {
+ case WXK_TAB:
+ case WXK_RIGHT:
+ case WXK_NUMPAD_RIGHT:
+ GetParent()->ChangeFocus( true );
+ return;
+
+ case WXK_LEFT:
+ case WXK_NUMPAD_LEFT:
+ GetParent()->ChangeFocus( false );
+ return;
+
+ case WXK_HOME:
+ case WXK_END:
+ case WXK_UP:
+ case WXK_DOWN:
+ case WXK_PAGEUP:
+ case WXK_PAGEDOWN:
+ event.Skip();
+ return;
+
+ default:
+ break;
+ }
+
+ // Search for an item name starting by the key code:
+ key = toupper( key );
+
+ for( unsigned ii = 0; ii < m_footprintList.GetCount(); ii++ )
+ {
+ wxString text = m_footprintList.Item( ii );
+
+ // Search for the start char of the footprint name. Skip the line number.
+ text.Trim( false ); // Remove leading spaces in line
+ unsigned jj = 0;
+
+ for( ; jj < text.Len(); jj++ )
+ {
+ // skip line number
+ if( text[jj] == ' ' )
+ break;
+ }
+
+ for( ; jj < text.Len(); jj++ )
+ { // skip blanks
+ if( text[jj] != ' ' )
+ break;
+ }
+
+ int start_char = toupper( text[jj] );
+
+ if( key == start_char )
+ {
+ SetSelection( ii, true ); // Ensure visible
+ break;
+ }
+ }
+
+ event.Skip();
+}
diff --git a/cvpcb/class_library_listbox.cpp b/cvpcb/class_library_listbox.cpp
new file mode 100644
index 0000000..53fe40d
--- /dev/null
+++ b/cvpcb/class_library_listbox.cpp
@@ -0,0 +1,217 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_library_listbox.cpp
+ * class to display used library and selecting it
+ */
+
+#include <fctsys.h>
+#include <wxstruct.h>
+#include <macros.h>
+
+#include <cvpcb.h>
+#include <cvpcb_mainframe.h>
+#include <cvstruct.h>
+#include <cvpcb_id.h>
+
+
+/***************************************/
+/* ListBox handling the library list */
+/***************************************/
+
+LIBRARY_LISTBOX::LIBRARY_LISTBOX( CVPCB_MAINFRAME* parent, wxWindowID id,
+ const wxPoint& loc, const wxSize& size ) :
+ ITEMS_LISTBOX_BASE( parent, id, loc, size, wxLC_SINGLE_SEL )
+{
+}
+
+
+LIBRARY_LISTBOX::~LIBRARY_LISTBOX()
+{
+}
+
+
+int LIBRARY_LISTBOX::GetCount()
+{
+ return m_libraryList.Count();
+}
+
+
+void LIBRARY_LISTBOX::SetString( unsigned linecount, const wxString& text )
+{
+ unsigned count = m_libraryList.Count();
+ if( count > 0 )
+ {
+ if( linecount >= count )
+ linecount = count - 1;
+ m_libraryList[linecount] = text;
+ UpdateWidth( linecount );
+ }
+}
+
+
+wxString LIBRARY_LISTBOX::GetSelectedLibrary()
+{
+ wxString libraryName;
+ int ii = GetFirstSelected();
+
+ if( ii >= 0 )
+ {
+ libraryName = m_libraryList[ii];
+ }
+
+ return libraryName;
+}
+
+
+void LIBRARY_LISTBOX::AppendLine( const wxString& text )
+{
+ m_libraryList.Add( text );
+ int lines = m_libraryList.Count();
+ SetItemCount( lines );
+ UpdateWidth( lines - 1 );
+}
+
+
+wxString LIBRARY_LISTBOX::OnGetItemText( long item, long column ) const
+{
+ return m_libraryList.Item( item );
+}
+
+
+void LIBRARY_LISTBOX::SetSelection( int index, bool State )
+{
+ if( index >= GetCount() )
+ index = GetCount() - 1;
+
+ if( (index >= 0) && (GetCount() > 0) )
+ {
+#ifndef __WXMAC__
+ Select( index, State );
+#endif
+ EnsureVisible( index );
+#ifdef __WXMAC__
+ Refresh();
+#endif
+ }
+}
+
+
+void LIBRARY_LISTBOX::SetLibraryList( const wxArrayString& aList )
+{
+ int oldSelection = GetSelection();
+
+ m_libraryList = aList;
+
+ SetItemCount( m_libraryList.GetCount() );
+
+ if( GetCount() == 0 || oldSelection < 0 || oldSelection >= GetCount() )
+ SetSelection( 0, true );
+
+ if( m_libraryList.Count() )
+ {
+ RefreshItems( 0L, m_libraryList.Count()-1 );
+ UpdateWidth();
+ }
+}
+
+
+BEGIN_EVENT_TABLE( LIBRARY_LISTBOX, ITEMS_LISTBOX_BASE )
+ EVT_CHAR( LIBRARY_LISTBOX::OnChar )
+ EVT_LIST_ITEM_SELECTED( ID_CVPCB_LIBRARY_LIST, LIBRARY_LISTBOX::OnSelectLibrary )
+END_EVENT_TABLE()
+
+
+void LIBRARY_LISTBOX::OnChar( wxKeyEvent& event )
+{
+ int key = event.GetKeyCode();
+
+ switch( key )
+ {
+ case WXK_TAB:
+ case WXK_RIGHT:
+ case WXK_NUMPAD_RIGHT:
+ GetParent()->ChangeFocus( true );
+ return;
+
+ case WXK_LEFT:
+ case WXK_NUMPAD_LEFT:
+ GetParent()->ChangeFocus( false );
+ return;
+
+ case WXK_HOME:
+ case WXK_END:
+ case WXK_UP:
+ case WXK_DOWN:
+ case WXK_PAGEUP:
+ case WXK_PAGEDOWN:
+ event.Skip();
+ return;
+
+ default:
+ break;
+ }
+
+ // Search for an item name starting by the key code:
+ key = toupper(key);
+
+ for( unsigned ii = 0; ii < m_libraryList.GetCount(); ii++ )
+ {
+ wxString text = m_libraryList.Item( ii );
+
+ // Search for the start char of the footprint name. Skip the line number.
+ text.Trim( false ); // Remove leading spaces in line
+ unsigned jj = 0;
+
+ for( ; jj < text.Len(); jj++ )
+ {
+ // skip line number
+ if( text[jj] == ' ' )
+ break;
+ }
+
+ for( ; jj < text.Len(); jj++ )
+ { // skip blanks
+ if( text[jj] != ' ' )
+ break;
+ }
+
+ int start_char = toupper( text[jj] );
+
+ if( key == start_char )
+ {
+ SetSelection( ii, true ); // Ensure visible
+ break;
+ }
+ }
+
+ event.Skip();
+}
+
+
+void LIBRARY_LISTBOX::OnSelectLibrary( wxListEvent& event )
+{
+ SetFocus();
+ GetParent()->OnSelectComponent( event );
+}
diff --git a/cvpcb/common_help_msg.h b/cvpcb/common_help_msg.h
new file mode 100644
index 0000000..f9e3bc0
--- /dev/null
+++ b/cvpcb/common_help_msg.h
@@ -0,0 +1,30 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014-2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef HELP_MESSAGE_FILE_H
+#define HELP_MESSAGE_FILE_H
+
+#define SAVE_HLP_MSG _( "Save footprint association in schematic component footprint fields" )
+
+#endif // HELP_MESSAGE_FILE_H
diff --git a/cvpcb/cvframe.cpp b/cvpcb/cvframe.cpp
new file mode 100644
index 0000000..d68f6b9
--- /dev/null
+++ b/cvpcb/cvframe.cpp
@@ -0,0 +1,939 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras
+ * Copyright (C) 2011-2016 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file cvframe.cpp
+ */
+
+#include <fctsys.h>
+#include <build_version.h>
+#include <kiway_express.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <macros.h>
+#include <confirm.h>
+#include <eda_doc.h>
+#include <eda_dde.h>
+#include <gestfich.h>
+#include <html_messagebox.h>
+#include <wildcards_and_files_ext.h>
+#include <fp_lib_table.h>
+#include <netlist_reader.h>
+
+#include <cvpcb_mainframe.h>
+#include <cvpcb.h>
+#include <cvstruct.h>
+#include <invoke_pcb_dialog.h>
+#include <class_DisplayFootprintsFrame.h>
+#include <cvpcb_id.h>
+
+
+#define FRAME_MIN_SIZE_X 450
+#define FRAME_MIN_SIZE_Y 300
+
+
+// option key to close CvPcb after saving files
+static const wxString KeepCvpcbOpenEntry( wxT( "KeepCvpcbOpen" ) );
+static const wxString FootprintDocFileEntry( wxT( "footprints_doc_file" ) );
+
+
+BEGIN_EVENT_TABLE( CVPCB_MAINFRAME, KIWAY_PLAYER )
+
+ // Menu events
+ EVT_MENU( wxID_SAVE, CVPCB_MAINFRAME::SaveQuitCvpcb )
+ EVT_MENU( wxID_EXIT, CVPCB_MAINFRAME::OnQuit )
+ EVT_MENU( wxID_HELP, CVPCB_MAINFRAME::GetKicadHelp )
+ EVT_MENU( wxID_ABOUT, CVPCB_MAINFRAME::GetKicadAbout )
+ EVT_MENU( ID_SAVE_PROJECT, CVPCB_MAINFRAME::SaveProjectFile )
+ EVT_MENU( ID_PREFERENCES_CONFIGURE_PATHS, CVPCB_MAINFRAME::OnConfigurePaths )
+ EVT_MENU( ID_CVPCB_CONFIG_KEEP_OPEN_ON_SAVE, CVPCB_MAINFRAME::OnKeepOpenOnSave )
+ EVT_MENU( ID_CVPCB_EQUFILES_LIST_EDIT, CVPCB_MAINFRAME::OnEditEquFilesList )
+
+ // Toolbar events
+ EVT_TOOL( ID_CVPCB_QUIT, CVPCB_MAINFRAME::OnQuit )
+
+ EVT_TOOL( ID_CVPCB_LIB_TABLE_EDIT, CVPCB_MAINFRAME::OnEditFootprintLibraryTable )
+ EVT_TOOL( ID_CVPCB_CREATE_SCREENCMP, CVPCB_MAINFRAME::DisplayModule )
+ EVT_TOOL( ID_CVPCB_GOTO_FIRSTNA, CVPCB_MAINFRAME::ToFirstNA )
+ EVT_TOOL( ID_CVPCB_GOTO_PREVIOUSNA, CVPCB_MAINFRAME::ToPreviousNA )
+ EVT_TOOL( ID_CVPCB_DEL_ASSOCIATIONS, CVPCB_MAINFRAME::DelAssociations )
+ EVT_TOOL( ID_CVPCB_AUTO_ASSOCIE, CVPCB_MAINFRAME::AutomaticFootprintMatching )
+ EVT_TOOL( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST,
+ CVPCB_MAINFRAME::OnSelectFilteringFootprint )
+ EVT_TOOL( ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST,
+ CVPCB_MAINFRAME::OnSelectFilteringFootprint )
+ EVT_TOOL( ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST,
+ CVPCB_MAINFRAME::OnSelectFilteringFootprint )
+
+ // Frame events
+ EVT_CLOSE( CVPCB_MAINFRAME::OnCloseWindow )
+ EVT_SIZE( CVPCB_MAINFRAME::OnSize )
+
+ EVT_UPDATE_UI( ID_CVPCB_CONFIG_KEEP_OPEN_ON_SAVE, CVPCB_MAINFRAME::OnUpdateKeepOpenOnSave )
+END_EVENT_TABLE()
+
+
+#define CVPCB_MAINFRAME_NAME wxT( "CvpcbFrame" )
+
+
+CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
+ KIWAY_PLAYER( aKiway, aParent, FRAME_CVPCB, wxT( "CvPCB" ), wxDefaultPosition,
+ wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, CVPCB_MAINFRAME_NAME )
+{
+ m_compListBox = NULL;
+ m_footprintListBox = NULL;
+ m_libListBox = NULL;
+ m_mainToolBar = NULL;
+ m_modified = false;
+ m_isEESchemaNetlist = false;
+ m_KeepCvpcbOpen = false;
+ m_undefinedComponentCnt = 0;
+ m_skipComponentSelect = false;
+ m_NetlistFileExtension = wxT( "net" );
+
+ /* Name of the document footprint list
+ * usually located in share/modules/footprints_doc
+ * this is of the responsibility to users to create this file
+ * if they want to have a list of footprints
+ */
+ m_DocModulesFileName = DEFAULT_FOOTPRINTS_LIST_FILENAME;
+
+ // Give an icon
+ wxIcon icon;
+ icon.CopyFromBitmap( KiBitmap( icon_cvpcb_xpm ) );
+ SetIcon( icon );
+
+ SetAutoLayout( true );
+
+ LoadSettings( config() );
+
+ if( m_FrameSize.x < FRAME_MIN_SIZE_X )
+ m_FrameSize.x = FRAME_MIN_SIZE_X;
+
+ if( m_FrameSize.y < FRAME_MIN_SIZE_Y )
+ m_FrameSize.y = FRAME_MIN_SIZE_Y;
+
+ // Set minimal frame width and height
+ SetSizeHints( FRAME_MIN_SIZE_X, FRAME_MIN_SIZE_Y, -1, -1, -1, -1 );
+
+ // Frame size and position
+ SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
+
+ // create the status bar
+ static const int dims[3] = { -1, -1, 250 };
+
+ CreateStatusBar( 3 );
+ SetStatusWidths( 3, dims );
+
+ ReCreateMenuBar();
+ ReCreateHToolbar();
+
+ // Create list of available modules and components of the schematic
+ BuildCmpListBox();
+ BuildFOOTPRINTS_LISTBOX();
+ BuildLIBRARY_LISTBOX();
+
+ m_auimgr.SetManagedWindow( this );
+
+ UpdateTitle();
+
+ EDA_PANEINFO horiz;
+ horiz.HorizontalToolbarPane();
+
+ EDA_PANEINFO info;
+ info.InfoToolbarPane();
+
+
+ if( m_mainToolBar )
+ m_auimgr.AddPane( m_mainToolBar,
+ wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top() );
+
+ if( m_compListBox )
+ m_auimgr.AddPane( m_compListBox,
+ wxAuiPaneInfo( horiz ).Name( wxT( "m_compListBox" ) ).CentrePane() );
+
+ if( m_libListBox)
+ m_auimgr.AddPane( m_libListBox,
+ wxAuiPaneInfo( info ).Name( wxT( "m_libListBox" ) ).
+ Left().BestSize( (int) ( m_FrameSize.x * 0.20 ), m_FrameSize.y ) );
+
+ if( m_footprintListBox )
+ m_auimgr.AddPane( m_footprintListBox,
+ wxAuiPaneInfo( info ).Name( wxT( "m_footprintListBox" ) ).
+ Right().BestSize( (int) ( m_FrameSize.x * 0.30 ), m_FrameSize.y ) );
+
+ m_auimgr.Update();
+}
+
+
+CVPCB_MAINFRAME::~CVPCB_MAINFRAME()
+{
+ m_auimgr.UnInit();
+}
+
+
+void CVPCB_MAINFRAME::LoadSettings( wxConfigBase* aCfg )
+{
+ EDA_BASE_FRAME::LoadSettings( aCfg );
+
+ aCfg->Read( KeepCvpcbOpenEntry, &m_KeepCvpcbOpen, true );
+ aCfg->Read( FootprintDocFileEntry, &m_DocModulesFileName,
+ DEFAULT_FOOTPRINTS_LIST_FILENAME );
+}
+
+
+void CVPCB_MAINFRAME::SaveSettings( wxConfigBase* aCfg )
+{
+ EDA_BASE_FRAME::SaveSettings( aCfg );
+
+ aCfg->Write( KeepCvpcbOpenEntry, m_KeepCvpcbOpen );
+ aCfg->Write( FootprintDocFileEntry, m_DocModulesFileName );
+
+ int state = 0;
+
+ if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST ) )
+ state |= FOOTPRINTS_LISTBOX::BY_COMPONENT;
+
+ if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST ) )
+ state |= FOOTPRINTS_LISTBOX::BY_PIN_COUNT;
+
+ if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST ) )
+ state |= FOOTPRINTS_LISTBOX::BY_LIBRARY;
+
+ aCfg->Write( wxT( FILTERFOOTPRINTKEY ), state );
+}
+
+
+void CVPCB_MAINFRAME::OnSize( wxSizeEvent& event )
+{
+ event.Skip();
+}
+
+
+void CVPCB_MAINFRAME::OnQuit( wxCommandEvent& event )
+{
+ Close( false );
+}
+
+
+void CVPCB_MAINFRAME::OnCloseWindow( wxCloseEvent& Event )
+{
+ if( m_modified )
+ {
+ wxString msg = _( "Component to Footprint links modified.\nSave before exit ?" );
+ int ii = DisplayExitDialog( this, msg );
+
+ switch( ii )
+ {
+ case wxID_CANCEL:
+ Event.Veto();
+ return;
+
+ case wxID_NO:
+ break;
+
+ case wxID_YES:
+ SaveEdits();
+ break;
+ }
+ }
+
+ // Close module display frame
+ if( GetFpViewerFrame() )
+ GetFpViewerFrame()->Close( true );
+
+ m_modified = false;
+
+ Destroy();
+ return;
+}
+
+
+void CVPCB_MAINFRAME::ChangeFocus( bool aMoveRight )
+{
+ wxWindow* hasFocus = wxWindow::FindFocus();
+
+ if( aMoveRight )
+ {
+ if( hasFocus == m_libListBox )
+ m_compListBox->SetFocus();
+ else if( hasFocus == m_compListBox )
+ m_footprintListBox->SetFocus();
+ else if( hasFocus == m_footprintListBox )
+ m_libListBox->SetFocus();
+ }
+ else
+ {
+ if( hasFocus == m_libListBox )
+ m_footprintListBox->SetFocus();
+ else if( hasFocus == m_compListBox )
+ m_libListBox->SetFocus();
+ else if( hasFocus == m_footprintListBox )
+ m_compListBox->SetFocus();
+ }
+}
+
+
+void CVPCB_MAINFRAME::ToFirstNA( wxCommandEvent& event )
+{
+ if( m_netlist.IsEmpty() )
+ return;
+
+ long first_selected = m_compListBox->GetFirstSelected();
+
+ if( first_selected < 0 )
+ first_selected = -1; // We will start to 0 for the first search , if no item selected
+
+ int candidate = -1;
+
+ for( unsigned jj = first_selected+1; jj < m_netlist.GetCount(); jj++ )
+ {
+ if( m_netlist.GetComponent( jj )->GetFPID().empty() )
+ {
+ candidate = jj;
+ break;
+ }
+ }
+
+ if( candidate >= 0 )
+ {
+ m_compListBox->DeselectAll();
+ m_compListBox->SetSelection( candidate );
+ SendMessageToEESCHEMA();
+ }
+}
+
+
+void CVPCB_MAINFRAME::ToPreviousNA( wxCommandEvent& event )
+{
+ if( m_netlist.IsEmpty() )
+ return;
+
+ int first_selected = m_compListBox->GetFirstSelected();
+
+ if( first_selected < 0 )
+ first_selected = m_compListBox->GetCount();
+
+ int candidate = -1;
+
+ for( int jj = first_selected-1; jj >= 0; jj-- )
+ {
+ if( m_netlist.GetComponent( jj )->GetFPID().empty() )
+ {
+ candidate = jj;
+ break;
+ }
+ }
+
+ if( candidate >= 0 )
+ {
+ m_compListBox->DeselectAll();
+ m_compListBox->SetSelection( candidate );
+ SendMessageToEESCHEMA();
+ }
+}
+
+
+void CVPCB_MAINFRAME::SaveQuitCvpcb( wxCommandEvent& aEvent )
+{
+ SaveEdits();
+
+ m_modified = false;
+
+ if( !m_KeepCvpcbOpen )
+ Close( true );
+}
+
+
+void CVPCB_MAINFRAME::DelAssociations( wxCommandEvent& event )
+{
+ if( IsOK( this, _( "Delete selections" ) ) )
+ {
+ m_skipComponentSelect = true;
+
+ // Remove all selections to avoid issues when setting the fpids
+ m_compListBox->DeselectAll();
+
+ for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
+ {
+ FPID fpid;
+
+ m_netlist.GetComponent( i )->SetFPID( fpid );
+ SetNewPkg( wxEmptyString );
+ }
+
+ // Remove all selections after setting the fpids
+ m_compListBox->DeselectAll();
+
+ m_skipComponentSelect = false;
+ m_compListBox->SetSelection( 0 );
+ m_undefinedComponentCnt = m_netlist.GetCount();
+ }
+
+ DisplayStatus();
+}
+
+
+/* Remove in favor of Kiway messaging method of sending netlist
+void CVPCB_MAINFRAME::LoadNetList( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ wxFileName newFileName;
+
+ if( id >= wxID_FILE1 && id <= wxID_FILE9 )
+ {
+ newFileName = GetFileFromHistory( id, _( "Netlist" ) );
+ }
+ else
+ {
+ wxFileDialog dlg( this, _( "Open Net List" ), wxGetCwd(),
+ wxEmptyString, NetlistFileWildcard,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ newFileName = dlg.GetPath();
+ }
+
+ if( newFileName == m_NetlistFileName )
+ return;
+
+ OpenProjectFiles( std::vector<wxString>( 1, newFileName.GetFullPath() ) );
+}
+*/
+
+
+bool CVPCB_MAINFRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
+{
+ return true;
+}
+
+
+void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent )
+{
+ bool tableChanged = false;
+ int r = InvokePcbLibTableEditor( this, &GFootprintTable, Prj().PcbFootprintLibs() );
+
+ if( r & 1 )
+ {
+ wxString fileName = FP_LIB_TABLE::GetGlobalTableFileName();
+
+ try
+ {
+ GFootprintTable.Save( fileName );
+ tableChanged = true;
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format(
+ _( "Error occurred saving the global footprint library table:\n'%s'\n%s" ),
+ GetChars( fileName ),
+ GetChars( ioe.errorText )
+ );
+ wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
+ }
+ }
+
+ if( r & 2 )
+ {
+ wxString fileName = Prj().FootprintLibTblName();
+
+ try
+ {
+ Prj().PcbFootprintLibs()->Save( fileName );
+ tableChanged = true;
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format(
+ _( "Error occurred saving the project footprint library table:\n'%s'\n%s" ),
+ GetChars( fileName ),
+ GetChars( ioe.errorText )
+ );
+ wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
+ }
+ }
+
+ if( tableChanged )
+ {
+ wxBusyCursor dummy;
+ BuildLIBRARY_LISTBOX();
+ m_footprints.ReadFootprintFiles( Prj().PcbFootprintLibs() );
+ }
+}
+
+
+void CVPCB_MAINFRAME::OnKeepOpenOnSave( wxCommandEvent& event )
+{
+ m_KeepCvpcbOpen = event.IsChecked();
+}
+
+
+void CVPCB_MAINFRAME::DisplayModule( wxCommandEvent& event )
+{
+ CreateScreenCmp();
+ GetFpViewerFrame()->RedrawScreen( wxPoint( 0, 0 ), false );
+}
+
+
+void CVPCB_MAINFRAME::OnSelectComponent( wxListEvent& event )
+{
+ if( m_skipComponentSelect )
+ return;
+
+ wxString libraryName;
+ COMPONENT* component = NULL;
+ int filter = FOOTPRINTS_LISTBOX::UNFILTERED;
+
+ if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST ) )
+ filter |= FOOTPRINTS_LISTBOX::BY_COMPONENT;
+
+ if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST ) )
+ filter |= FOOTPRINTS_LISTBOX::BY_PIN_COUNT;
+
+ if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST ) )
+ filter |= FOOTPRINTS_LISTBOX::BY_LIBRARY;
+
+ component = GetSelectedComponent();
+ libraryName = m_libListBox->GetSelectedLibrary();
+ m_footprintListBox->SetFootprints( m_footprints, libraryName, component, filter );
+
+ // Tell AuiMgr that objects are changed !
+ if( m_auimgr.GetManagedWindow() ) // Be sure Aui Manager is initialized
+ // (could be not the case when starting CvPcb
+ m_auimgr.Update();
+
+ if( component == NULL )
+ return;
+
+ // Preview of the already assigned footprint.
+ // Find the footprint that was already chosen for this component and select it,
+ // but only if the selection is made from the component list or the library list.
+ // If the selection is made from the footprint list, do not change the current
+ // selected footprint.
+ if( FindFocus() == m_compListBox || FindFocus() == m_libListBox )
+ {
+ wxString module = FROM_UTF8( component->GetFPID().Format().c_str() );
+
+ bool found = false;
+
+ for( int ii = 0; ii < m_footprintListBox->GetCount(); ii++ )
+ {
+ wxString footprintName;
+ wxString msg = m_footprintListBox->OnGetItemText( ii, 0 );
+ msg.Trim( true );
+ msg.Trim( false );
+ footprintName = msg.AfterFirst( wxChar( ' ' ) );
+
+ if( module.Cmp( footprintName ) == 0 )
+ {
+ m_footprintListBox->SetSelection( ii, true );
+ found = true;
+ break;
+ }
+ }
+
+ if( !found )
+ {
+ int ii = m_footprintListBox->GetSelection();
+
+ if ( ii >= 0 )
+ m_footprintListBox->SetSelection( ii, false );
+
+ if( GetFpViewerFrame() )
+ {
+ CreateScreenCmp();
+ }
+ }
+ }
+
+ SendMessageToEESCHEMA();
+ DisplayStatus();
+}
+
+
+void CVPCB_MAINFRAME::OnSelectFilteringFootprint( wxCommandEvent& event )
+{
+ wxListEvent l_event;
+
+ OnSelectComponent( l_event );
+}
+
+
+void CVPCB_MAINFRAME::OnUpdateKeepOpenOnSave( wxUpdateUIEvent& event )
+{
+ event.Check( m_KeepCvpcbOpen );
+}
+
+
+void CVPCB_MAINFRAME::DisplayStatus()
+{
+ wxString msg;
+ COMPONENT* component;
+
+ if( wxWindow::FindFocus() == m_compListBox || wxWindow::FindFocus() == m_libListBox )
+ {
+ msg.Printf( _( "Components: %d, unassigned: %d" ), (int) m_netlist.GetCount(),
+ m_undefinedComponentCnt );
+ SetStatusText( msg, 0 );
+
+ msg.Empty();
+
+ component = GetSelectedComponent();
+
+ if( component )
+ {
+ for( unsigned ii = 0; ii < component->GetFootprintFilters().GetCount(); ii++ )
+ {
+ if( msg.IsEmpty() )
+ msg += component->GetFootprintFilters()[ii];
+ else
+ msg += wxT( ", " ) + component->GetFootprintFilters()[ii];
+ }
+
+ msg = _( "Filter list: " ) + msg;
+ }
+
+ SetStatusText( msg, 1 );
+ }
+ else
+ {
+ wxString footprintName = m_footprintListBox->GetSelectedFootprint();
+
+ FOOTPRINT_INFO* module = m_footprints.GetModuleInfo( footprintName );
+
+ if( module ) // can be NULL if no netlist loaded
+ {
+ msg = _( "Description: " ) + module->GetDoc();
+ SetStatusText( msg, 0 );
+
+ msg = _( "Key words: " ) + module->GetKeywords();
+ SetStatusText( msg, 1 );
+ }
+ }
+
+ msg.Empty();
+ wxString filters;
+
+ if( m_footprintListBox )
+ {
+ if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST ) )
+ filters = _( "key words" );
+
+ if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST ) )
+ {
+ if( !filters.IsEmpty() )
+ filters += wxT( "+" );
+
+ filters += _( "pin count" );
+ }
+
+ if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST ) )
+ {
+ if( !filters.IsEmpty() )
+ filters += wxT( "+" );
+
+ filters += _( "library" );
+ }
+
+ if( filters.IsEmpty() )
+ msg = _( "No filtering" );
+ else
+ msg.Printf( _( "Filtered by %s" ), GetChars( filters ) );
+
+ msg << wxT( ": " ) << m_footprintListBox->GetCount();
+
+ SetStatusText( msg, 2 );
+ }
+}
+
+
+bool CVPCB_MAINFRAME::LoadFootprintFiles()
+{
+ FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();
+
+ // Check if there are footprint libraries in the footprint library table.
+ if( !fptbl || !fptbl->GetLogicalLibs().size() )
+ {
+ wxMessageBox( _( "No PCB footprint libraries are listed in the current footprint "
+ "library table." ), _( "Configuration Error" ), wxOK | wxICON_ERROR );
+ return false;
+ }
+
+ {
+ wxBusyCursor dummy; // Let the user know something is happening.
+
+ m_footprints.ReadFootprintFiles( fptbl );
+ }
+
+ if( m_footprints.GetErrorCount() )
+ {
+ m_footprints.DisplayErrors( this );
+ }
+
+ return true;
+}
+
+
+void CVPCB_MAINFRAME::UpdateTitle()
+{
+ wxString title = wxString::Format( wxT( "Cvpcb %s " ), GetChars( GetBuildVersion() ) );
+ PROJECT& prj = Prj();
+ wxFileName fn = prj.GetProjectFullName();
+
+ if( fn.IsOk() && !prj.GetProjectFullName().IsEmpty() && fn.FileExists() )
+ {
+ title += wxString::Format( _("Project: '%s'"),
+ GetChars( fn.GetFullPath() )
+ );
+
+ if( !fn.IsFileWritable() )
+ title += _( " [Read Only]" );
+ }
+ else
+ title += _( "[no project]" );
+
+ SetTitle( title );
+}
+
+
+void CVPCB_MAINFRAME::SendMessageToEESCHEMA()
+{
+ if( m_netlist.IsEmpty() )
+ return;
+
+ int selection = m_compListBox->GetSelection();
+
+ if ( selection < 0 )
+ selection = 0;
+
+ if( m_netlist.GetComponent( selection ) == NULL )
+ return;
+
+ COMPONENT* component = m_netlist.GetComponent( selection );
+
+ std::string packet = StrPrintf( "$PART: \"%s\"", TO_UTF8( component->GetReference() ) );
+
+ if( Kiface().IsSingle() )
+ SendCommand( MSG_TO_SCH, packet.c_str() );
+ else
+ Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, packet, this );
+}
+
+
+int CVPCB_MAINFRAME::ReadSchematicNetlist( const std::string& aNetlist )
+{
+ STRING_LINE_READER* strrdr = new STRING_LINE_READER( aNetlist, "Eeschema via Kiway" );
+ KICAD_NETLIST_READER netrdr( strrdr, &m_netlist );
+
+ m_netlist.Clear();
+
+ try
+ {
+ netrdr.LoadNetlist();
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() );
+ wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR );
+ return 1;
+ }
+
+ // We also remove footprint name if it is "$noname" because this is a dummy name,
+ // not the actual name of the footprint.
+ for( unsigned ii = 0; ii < m_netlist.GetCount(); ii++ )
+ {
+ if( m_netlist.GetComponent( ii )->GetFPID().GetFootprintName() == std::string( "$noname" ) )
+ m_netlist.GetComponent( ii )->SetFPID( FPID( wxEmptyString ) );
+ }
+
+ // Sort components by reference:
+ m_netlist.SortByReference();
+
+ return 0;
+}
+
+
+void CVPCB_MAINFRAME::CreateScreenCmp()
+{
+ DISPLAY_FOOTPRINTS_FRAME* fpframe = GetFpViewerFrame();
+
+ if( !fpframe )
+ {
+ fpframe = new DISPLAY_FOOTPRINTS_FRAME( &Kiway(), this );
+ fpframe->Show( true );
+ }
+ else
+ {
+ if( fpframe->IsIconized() )
+ fpframe->Iconize( false );
+
+ // The display footprint window might be buried under some other
+ // windows, so CreateScreenCmp() on an existing window would not
+ // show any difference, leaving the user confused.
+ // So we want to put it to front, second after our CVPCB_MAINFRAME.
+ // We do this by a little dance of bringing it to front then the main
+ // frame back.
+ fpframe->Raise(); // Make sure that is visible.
+ Raise(); // .. but still we want the focus.
+ }
+
+ fpframe->InitDisplay();
+}
+
+
+void CVPCB_MAINFRAME::BuildFOOTPRINTS_LISTBOX()
+{
+ wxFont guiFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
+
+ if( m_footprintListBox == NULL )
+ {
+ m_footprintListBox = new FOOTPRINTS_LISTBOX( this, ID_CVPCB_FOOTPRINT_LIST,
+ wxDefaultPosition, wxDefaultSize );
+ m_footprintListBox->SetFont( wxFont( guiFont.GetPointSize(),
+ wxFONTFAMILY_MODERN,
+ wxFONTSTYLE_NORMAL,
+ wxFONTWEIGHT_NORMAL ) );
+ }
+
+ m_footprintListBox->SetFootprints( m_footprints, wxEmptyString, NULL,
+ FOOTPRINTS_LISTBOX::UNFILTERED );
+ DisplayStatus();
+}
+
+
+void CVPCB_MAINFRAME::BuildCmpListBox()
+{
+ wxString msg;
+ COMPONENT* component;
+ wxFont guiFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
+
+ if( m_compListBox == NULL )
+ {
+ m_compListBox = new COMPONENTS_LISTBOX( this, ID_CVPCB_COMPONENT_LIST,
+ wxDefaultPosition, wxDefaultSize );
+ m_compListBox->SetFont( wxFont( guiFont.GetPointSize(),
+ wxFONTFAMILY_MODERN,
+ wxFONTSTYLE_NORMAL,
+ wxFONTWEIGHT_NORMAL ) );
+ }
+
+ m_compListBox->m_ComponentList.Clear();
+
+ for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
+ {
+ component = m_netlist.GetComponent( i );
+
+ msg.Printf( CMP_FORMAT, m_compListBox->GetCount() + 1,
+ GetChars( component->GetReference() ),
+ GetChars( component->GetValue() ),
+ GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
+ m_compListBox->m_ComponentList.Add( msg );
+ }
+
+ if( m_compListBox->m_ComponentList.Count() )
+ {
+ m_compListBox->SetItemCount( m_compListBox->m_ComponentList.Count() );
+ m_compListBox->SetSelection( 0, true );
+ m_compListBox->RefreshItems( 0L, m_compListBox->m_ComponentList.Count()-1 );
+ m_compListBox->UpdateWidth();
+ }
+}
+
+
+void CVPCB_MAINFRAME::BuildLIBRARY_LISTBOX()
+{
+ wxFont guiFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
+
+ if( m_libListBox == NULL )
+ {
+ m_libListBox = new LIBRARY_LISTBOX( this, ID_CVPCB_LIBRARY_LIST,
+ wxDefaultPosition, wxDefaultSize );
+ m_libListBox->SetFont( wxFont( guiFont.GetPointSize(),
+ wxFONTFAMILY_MODERN,
+ wxFONTSTYLE_NORMAL,
+ wxFONTWEIGHT_NORMAL ) );
+ }
+
+ FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
+
+ if( tbl )
+ {
+ wxArrayString libNames;
+
+ std::vector< wxString > libNickNames = tbl->GetLogicalLibs();
+
+ for( unsigned ii = 0; ii < libNickNames.size(); ii++ )
+ libNames.Add( libNickNames[ii] );
+
+ m_libListBox->SetLibraryList( libNames );
+ }
+}
+
+
+COMPONENT* CVPCB_MAINFRAME::GetSelectedComponent()
+{
+ int selection = m_compListBox->GetSelection();
+
+ if( selection >= 0 && selection < (int) m_netlist.GetCount() )
+ return m_netlist.GetComponent( selection );
+
+ return NULL;
+}
+
+
+DISPLAY_FOOTPRINTS_FRAME* CVPCB_MAINFRAME::GetFpViewerFrame()
+{
+ // returns the Footprint Viewer frame, if exists, or NULL
+ return (DISPLAY_FOOTPRINTS_FRAME*) wxWindow::FindWindowByName( FOOTPRINTVIEWER_FRAME_NAME );
+}
+
+
+void CVPCB_MAINFRAME::OnConfigurePaths( wxCommandEvent& aEvent )
+{
+ Pgm().ConfigurePaths( this );
+}
+
+
+void CVPCB_MAINFRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
+{
+ const std::string& payload = mail.GetPayload();
+
+ DBG(printf( "%s: %s\n", __func__, payload.c_str() );)
+
+ switch( mail.Command() )
+ {
+ case MAIL_EESCHEMA_NETLIST:
+ ReadNetListAndLinkFiles( payload );
+ /* @todo
+ Go into SCH_EDIT_FRAME::OnOpenCvpcb( wxCommandEvent& event ) and trim GNL_ALL down.
+ */
+ break;
+
+ default:
+ ; // ignore most
+ }
+}
diff --git a/cvpcb/cvpcb.cpp b/cvpcb/cvpcb.cpp
new file mode 100644
index 0000000..4680410
--- /dev/null
+++ b/cvpcb/cvpcb.cpp
@@ -0,0 +1,198 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jp..charras at wanadoo.fr
+ * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file cvpcb.cpp
+ */
+
+#include <fctsys.h>
+#include <macros.h>
+#include <fp_lib_table.h>
+#include <kiface_i.h>
+#include <pgm_base.h>
+#include <wxstruct.h>
+#include <confirm.h>
+#include <3d_viewer.h>
+#include <pcbcommon.h>
+
+#include <cvpcb.h>
+#include <zones.h>
+#include <cvpcb_mainframe.h>
+#include <colors_selection.h>
+#include <cvpcb_id.h>
+
+#include <build_version.h>
+
+#include <wx/snglinst.h>
+
+// Colors for layers and items
+COLORS_DESIGN_SETTINGS g_ColorsSettings;
+
+// Constant string definitions for CvPcb
+const wxString EquFileExtension( wxT( "equ" ) );
+
+// Wildcard for schematic retroannotation (import footprint names in schematic):
+const wxString EquFilesWildcard( _( "Component/footprint equ files (*.equ)|*.equ" ) );
+
+
+namespace CV {
+
+static struct IFACE : public KIFACE_I
+{
+ // Of course all are virtual overloads, implementations of the KIFACE.
+
+ IFACE( const char* aName, KIWAY::FACE_T aType ) :
+ KIFACE_I( aName, aType )
+ {}
+
+ bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits );
+
+ void OnKifaceEnd();
+
+ wxWindow* CreateWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 )
+ {
+ switch( aClassId )
+ {
+ case FRAME_CVPCB:
+ {
+ CVPCB_MAINFRAME* frame = new CVPCB_MAINFRAME( aKiway, aParent );
+ return frame;
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ return NULL;
+ }
+
+ /**
+ * Function IfaceOrAddress
+ * return a pointer to the requested object. The safest way to use this
+ * is to retrieve a pointer to a static instance of an interface, similar to
+ * how the KIFACE interface is exported. But if you know what you are doing
+ * use it to retrieve anything you want.
+ *
+ * @param aDataId identifies which object you want the address of.
+ *
+ * @return void* - and must be cast into the know type.
+ */
+ void* IfaceOrAddress( int aDataId )
+ {
+ return NULL;
+ }
+
+} kiface( "cvpcb", KIWAY::FACE_CVPCB );
+
+} // namespace
+
+using namespace CV;
+
+
+static PGM_BASE* process;
+
+
+KIFACE_I& Kiface() { return kiface; }
+
+
+// KIFACE_GETTER's actual spelling is a substitution macro found in kiway.h.
+// KIFACE_GETTER will not have name mangling due to declaration in kiway.h.
+MY_API( KIFACE* ) KIFACE_GETTER( int* aKIFACEversion, int aKIWAYversion, PGM_BASE* aProgram )
+{
+ process = (PGM_BASE*) aProgram;
+ return &kiface;
+}
+
+
+PGM_BASE& Pgm()
+{
+ wxASSERT( process ); // KIFACE_GETTER has already been called.
+ return *process;
+}
+
+
+//!!!!!!!!!!!!!!! This code is obsolete because of the merge into pcbnew, don't bother with it.
+
+FP_LIB_TABLE GFootprintTable;
+
+
+// A short lived implementation. cvpcb will get combine into pcbnew shortly, so
+// we skip setting KISYSMOD here for now. User should set the environment
+// variable.
+
+bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
+{
+ // This is process level, not project level, initialization of the DSO.
+
+ // Do nothing in here pertinent to a project!
+
+ start_common( aCtlBits );
+
+ /* Now that there are no *.mod files in the standard library, this function
+ has no utility. User should simply set the variable manually.
+ Looking for *.mod files which do not exist is fruitless.
+
+ // SetFootprintLibTablePath();
+ */
+
+ try
+ {
+ // The global table is not related to a specific project. All projects
+ // will use the same global table. So the KIFACE::OnKifaceStart() contract
+ // of avoiding anything project specific is not violated here.
+
+ if( !FP_LIB_TABLE::LoadGlobalTable( GFootprintTable ) )
+ {
+ DisplayInfoMessage( NULL, _(
+ "You have run CvPcb for the first time using the "
+ "new footprint library table method for finding "
+ "footprints. CvPcb has either copied the default "
+ "table or created an empty table in your home "
+ "folder. You must first configure the library "
+ "table to include all footprint libraries not "
+ "included with KiCad. See the \"Footprint Library "
+ "Table\" section of the CvPcb documentation for "
+ "more information." ) );
+ }
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _(
+ "An error occurred attempting to load the global footprint library "
+ "table:\n\n%s" ),
+ GetChars( ioe.errorText )
+ );
+ DisplayError( NULL, msg );
+ return false;
+ }
+
+ return true;
+}
+
+void IFACE::OnKifaceEnd()
+{
+ end_common();
+}
diff --git a/cvpcb/cvpcb.h b/cvpcb/cvpcb.h
new file mode 100644
index 0000000..eec99ea
--- /dev/null
+++ b/cvpcb/cvpcb.h
@@ -0,0 +1,41 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __CVPCB_H__
+#define __CVPCB_H__
+
+// config for footprints doc file access
+#define DEFAULT_FOOTPRINTS_LIST_FILENAME wxT( "footprints_doc/footprints.pdf" )
+
+// Define print format to display a schematic component line
+#define CMP_FORMAT wxT( "%3d %8s - %16s : %s" )
+
+#define FILTERFOOTPRINTKEY "FilterFootprint"
+
+
+extern const wxString EquFileExtension;
+extern const wxString EquFilesWildcard;
+
+
+#endif /* __CVPCB_H__ */
diff --git a/cvpcb/cvpcb.icns b/cvpcb/cvpcb.icns
new file mode 100644
index 0000000..343e75c
--- /dev/null
+++ b/cvpcb/cvpcb.icns
Binary files differ
diff --git a/cvpcb/cvpcb.rc b/cvpcb/cvpcb.rc
new file mode 100644
index 0000000..4c06802
--- /dev/null
+++ b/cvpcb/cvpcb.rc
@@ -0,0 +1,2 @@
+icon_cvpcb ICON "../bitmaps_png/icons/icon_cvpcb.ico"
+#include "wx/msw/wx.rc"
diff --git a/cvpcb/cvpcb_doc.icns b/cvpcb/cvpcb_doc.icns
new file mode 100644
index 0000000..ec0124d
--- /dev/null
+++ b/cvpcb/cvpcb_doc.icns
Binary files differ
diff --git a/cvpcb/cvpcb_id.h b/cvpcb/cvpcb_id.h
new file mode 100644
index 0000000..57a2fee
--- /dev/null
+++ b/cvpcb/cvpcb_id.h
@@ -0,0 +1,60 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file cvpcb_id.h
+ */
+/*
+ * Command IDs for CvPcb.
+ *
+ * Please add IDs that are unique to the component library viewer here and
+ * not in the global id.h file. This will prevent the entire project from
+ * being rebuilt when adding new commands to the component library viewer.
+ */
+
+// Generic IDs:
+#include <id.h>
+
+// specific IDs
+enum id_cvpcb_frm
+{
+ ID_CVPCB_QUIT = ID_END_LIST,
+ ID_CVPCB_SAVEQUITCVPCB,
+ ID_CVPCB_CREATE_SCREENCMP,
+ ID_CVPCB_GOTO_FIRSTNA,
+ ID_CVPCB_GOTO_PREVIOUSNA,
+ ID_CVPCB_DEL_ASSOCIATIONS,
+ ID_CVPCB_AUTO_ASSOCIE,
+ ID_CVPCB_COMPONENT_LIST,
+ ID_CVPCB_FOOTPRINT_LIST,
+ ID_CVPCB_SHOW3D_FRAME,
+ ID_CVPCB_FOOTPRINT_DISPLAY_FULL_LIST,
+ ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST,
+ ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST,
+ ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST,
+ ID_CVPCB_CONFIG_KEEP_OPEN_ON_SAVE,
+ ID_CVPCB_LIBRARY_LIST,
+ ID_CVPCB_EQUFILES_LIST_EDIT,
+ ID_CVPCB_LIB_TABLE_EDIT
+};
diff --git a/cvpcb/cvpcb_mainframe.h b/cvpcb/cvpcb_mainframe.h
new file mode 100644
index 0000000..f868b78
--- /dev/null
+++ b/cvpcb/cvpcb_mainframe.h
@@ -0,0 +1,306 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file cvpcb_mainframe.h
+ */
+
+#ifndef _CVPCB_MAINFRAME_H_
+#define _CVPCB_MAINFRAME_H_
+
+#include <wx/listctrl.h>
+#include <wx/filename.h>
+#include <pcb_netlist.h>
+#include <footprint_info.h>
+
+#include <wxBasePcbFrame.h>
+#include <config_params.h>
+#include <autosel.h>
+
+
+/* Forward declarations of all top-level window classes. */
+class wxAuiToolBar;
+class FOOTPRINTS_LISTBOX;
+class COMPONENTS_LISTBOX;
+class LIBRARY_LISTBOX;
+class DISPLAY_FOOTPRINTS_FRAME;
+class COMPONENT;
+class FP_LIB_TABLE;
+
+namespace CV { struct IFACE; }
+
+/**
+ * The CvPcb application main window.
+ */
+class CVPCB_MAINFRAME : public KIWAY_PLAYER
+{
+ friend struct CV::IFACE;
+
+ wxArrayString m_footprintListEntries;
+
+public:
+ bool m_KeepCvpcbOpen;
+ FOOTPRINTS_LISTBOX* m_footprintListBox;
+ LIBRARY_LISTBOX* m_libListBox;
+ COMPONENTS_LISTBOX* m_compListBox;
+ wxAuiToolBar* m_mainToolBar;
+ wxArrayString m_ModuleLibNames;
+ wxArrayString m_EquFilesNames;
+ wxString m_NetlistFileExtension;
+ wxString m_DocModulesFileName;
+ FOOTPRINT_LIST m_footprints;
+ NETLIST m_netlist;
+
+protected:
+ int m_undefinedComponentCnt;
+ bool m_modified;
+ bool m_isEESchemaNetlist;
+ bool m_skipComponentSelect; // true to skip OnSelectComponent event
+ // (in automatic selection/deletion of associations)
+ PARAM_CFG_ARRAY m_projectFileParams;
+
+ CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent );
+
+public:
+ ~CVPCB_MAINFRAME();
+
+ bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl=0 ); // overload KIWAY_PLAYER
+
+ void KiwayMailIn( KIWAY_EXPRESS& aEvent ); // override virtual from KIWAY_PLAYER
+
+ /**
+ * @return a pointer on the Footprint Viewer frame, if exists, or NULL
+ */
+ DISPLAY_FOOTPRINTS_FRAME* GetFpViewerFrame();
+
+ /**
+ * Function OnSelectComponent
+ * Called when clicking on a component in component list window
+ * * Updates the filtered footprint list, if the filtered list option is selected
+ * * Updates the current selected footprint in footprint list
+ * * Updates the footprint shown in footprint display window (if opened)
+ */
+ void OnSelectComponent( wxListEvent& event );
+
+ /**
+ * Function OnEditFootrprintLibraryTable
+ * displays the footprint library table editing dialog and updates the global and local
+ * footprint tables accordingly.
+ */
+ void OnEditFootrprintLibraryTable( wxCommandEvent& event );
+
+ void OnQuit( wxCommandEvent& event );
+ void OnCloseWindow( wxCloseEvent& Event );
+ void OnSize( wxSizeEvent& SizeEvent );
+ void ReCreateHToolbar();
+ virtual void ReCreateMenuBar();
+
+ void ChangeFocus( bool aMoveRight );
+
+ void ToFirstNA( wxCommandEvent& event );
+ void ToPreviousNA( wxCommandEvent& event );
+
+ /**
+ * Function DelAssociations
+ * removes all component footprint associations already made
+ */
+ void DelAssociations( wxCommandEvent& event );
+
+ void SaveProjectFile( wxCommandEvent& aEvent );
+ void SaveQuitCvpcb( wxCommandEvent& event );
+
+ /**
+ * Function LoadNetList
+ * reads a netlist selected by user when clicking on load netlist button or any entry
+ * in the file history menu.
+ */
+ void LoadNetList( wxCommandEvent& event );
+
+ /**
+ * Function OnEditLibraryTable
+ * envokes the footprint library table edit dialog.
+ */
+ void OnEditFootprintLibraryTable( wxCommandEvent& aEvent );
+
+ void OnConfigurePaths( wxCommandEvent& aEvent );
+
+ /**
+ * Function OnEditEquFilesList
+ * envokes the equ files list edit dialog.
+ */
+ void OnEditEquFilesList( wxCommandEvent& aEvent );
+
+ void OnKeepOpenOnSave( wxCommandEvent& event );
+ void DisplayModule( wxCommandEvent& event );
+
+ /**
+ * Called by the automatic association button
+ * Read *.equ files to try to find corresponding footprint
+ * for each component that is not already linked to a footprint ( a "free"
+ * component )
+ * format of a line:
+ * 'cmp_ref' 'footprint_name'
+ */
+ void AutomaticFootprintMatching( wxCommandEvent& event );
+
+ /**
+ * Function OnSelectFilteringFootprint
+ * is the command event handler for enabling and disabling footprint filtering.
+ */
+ void OnSelectFilteringFootprint( wxCommandEvent& event );
+
+ void OnUpdateKeepOpenOnSave( wxUpdateUIEvent& event );
+
+ /**
+ * Function SetNewPkg
+ * set the footprint name for all selected components in component list
+ * and selects the next component.
+ * @param aFootprintName = the new footprint name
+ */
+ void SetNewPkg( const wxString& aFootprintName );
+
+ /**
+ * Function SetNewPkg
+ * Set the footprint name for the component of position aIndex in the component list
+ *
+ * @param aFootprintName = the new footprint name
+ * @param aIndex = the index of the component to modify in the component list
+ */
+ void SetNewPkg( const wxString& aFootprintName, int aIndex );
+
+ void BuildCmpListBox();
+ void BuildFOOTPRINTS_LISTBOX();
+ void BuildLIBRARY_LISTBOX();
+
+ /**
+ * Create or Update the frame showing the current highlighted footprint
+ * and (if showed) the 3D display frame
+ */
+ void CreateScreenCmp();
+
+ /**
+ * Function SaveEdits
+ * saves the edits that the user has done by sending them back to eeschema
+ * via the kiway.
+ */
+ void SaveEdits();
+
+ /**
+ * Function ReadNetList
+ * reads the netlist (.net) file defined by #m_NetlistFileName.
+ * and the corresponding cmp to footprint (.cmp) link file
+ * @param aNetlist is the netlist from eeschema in kicad s-expr format.
+ */
+ bool ReadNetListAndLinkFiles( const std::string& aNetlist );
+
+ int ReadSchematicNetlist( const std::string& aNetlist );
+
+ /**
+ * Function LoadProjectFile
+ * reads the configuration parameter from the project (.pro) file \a aFileName
+ */
+ void LoadProjectFile();
+
+ void LoadSettings( wxConfigBase* aCfg ); // override virtual
+
+ void SaveSettings( wxConfigBase* aCfg ); // override virtual
+
+ /**
+ * Function DisplayStatus
+ * updates the information displayed on the status bar at bottom of the main frame.
+ *
+ * When the library or component list controls have the focus, the footprint assignment
+ * status of the components is displayed in the first status bar pane and the list of
+ * filters for the selected component is displayed in the second status bar pane. When
+ * the footprint list control has the focus, the description of the selected footprint is
+ * displayed in the first status bar pane and the key words for the selected footprint are
+ * displayed in the second status bar pane. The third status bar pane always displays the
+ * current footprint list filtering.
+ */
+ void DisplayStatus();
+
+ /**
+ * Function LoadFootprintFiles
+ * reads the list of footprint (*.mod files) and generate the list of footprints.
+ * for each module are stored
+ * the module name
+ * documentation string
+ * associated keywords
+ * m_ModuleLibNames is the list of library that must be read (loaded)
+ * fills m_footprints
+ * @return true if libraries are found, false otherwise.
+ */
+ bool LoadFootprintFiles();
+
+ /**
+ * Function GetProjectFileParameters
+ * return project file parameter list for CvPcb.
+ * <p>
+ * Populate the project file parameter array specific to CvPcb if it hasn't
+ * already been populated and return a reference to the array to the caller.
+ * Creating the parameter list at run time has the advantage of being able
+ * to define local variables. The old method of statically building the array
+ * at compile time requiring global variable definitions.
+ * </p>
+ *
+ * @return A reference to a PARAM_CFG_ARRAY contain the project settings for CvPcb.
+ */
+ PARAM_CFG_ARRAY& GetProjectFileParameters( void );
+
+ /**
+ * Function UpdateTitle
+ * sets the main window title bar text.
+ * <p>
+ * If file name defined by CVPCB_MAINFRAME::m_NetlistFileName is not set, the title is
+ * set to the application name appended with no file. Otherwise, the title is set to
+ * the full path and file name and read only is appended to the title if the user does
+ * not have write access to the file.
+ */
+ void UpdateTitle();
+
+ /**
+ * Function SendMessageToEESCHEMA
+ * Send a remote command to Eeschema via a socket,
+ * Commands are
+ * $PART: "reference" put cursor on component anchor
+ */
+ void SendMessageToEESCHEMA();
+
+ COMPONENT* GetSelectedComponent();
+
+private:
+
+ /**
+ * read the .equ files and populate the list of equvalents
+ * @param aList the list to populate
+ * @param aErrorMessages is a pointer to a wxString to store error messages
+ * (can be NULL)
+ * @return the error count ( 0 = no error)
+ */
+ int buildEquivalenceList( FOOTPRINT_EQUIVALENCE_LIST& aList, wxString * aErrorMessages = NULL );
+
+ DECLARE_EVENT_TABLE()
+};
+
+#endif //#ifndef _CVPCB_MAINFRAME_H_
diff --git a/cvpcb/cvstruct.h b/cvpcb/cvstruct.h
new file mode 100644
index 0000000..90eb4ef
--- /dev/null
+++ b/cvpcb/cvstruct.h
@@ -0,0 +1,240 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file cvstruct.h
+ */
+
+#ifndef CVSTRUCT_H
+#define CVSTRUCT_H
+
+#include <wx/listctrl.h>
+
+
+/* Forward declarations of all top-level window classes. */
+class CVPCB_MAINFRAME;
+class COMPONENT;
+class FOOTPRINT_LIST;
+
+#define LISTBOX_STYLE ( wxSUNKEN_BORDER | wxLC_NO_HEADER | wxLC_REPORT | wxLC_VIRTUAL | \
+ wxVSCROLL | wxHSCROLL )
+
+/*********************************************************************/
+/* ListBox (base class) to display lists of components or footprints */
+/*********************************************************************/
+class ITEMS_LISTBOX_BASE : public wxListView
+{
+public:
+ ITEMS_LISTBOX_BASE( CVPCB_MAINFRAME* aParent, wxWindowID aId,
+ const wxPoint& aLocation, const wxSize& aSize,
+ long aStyle = 0 );
+
+ ~ITEMS_LISTBOX_BASE();
+
+ /**
+ * @return the index of the selected item in lists allowing only one item selected
+ * and the index of the first selected item in lists allowing many selection
+ */
+ int GetSelection();
+
+ /**
+ * Removes all selection in lists which can have more than one item selected
+ */
+ void DeselectAll();
+
+ virtual CVPCB_MAINFRAME* GetParent() const;
+
+ /* Function UpdateWidth
+ *
+ * Update the width of the column based on its contents.
+ *
+ * @param aLine is the line to calculate the width from. If positive, the
+ * width will only be increased if needed. If negative, we start from
+ * scratch and all lines are considered, i.e., the column may be shrunk.
+ */
+ void UpdateWidth( int aLine = -1 );
+
+private:
+ void UpdateLineWidth( unsigned aLine );
+
+ int columnWidth;
+};
+
+
+/******************************************/
+/* ListBox showing the list of footprints */
+/******************************************/
+class FOOTPRINTS_LISTBOX : public ITEMS_LISTBOX_BASE
+{
+private:
+ wxArrayString m_footprintList;
+
+public:
+ enum FP_FILTER_T
+ {
+ UNFILTERED = 0,
+ BY_COMPONENT = 0x0001,
+ BY_PIN_COUNT = 0x0002,
+ BY_LIBRARY = 0x0004,
+ };
+
+ FOOTPRINTS_LISTBOX( CVPCB_MAINFRAME* parent, wxWindowID id,
+ const wxPoint& loc, const wxSize& size );
+ ~FOOTPRINTS_LISTBOX();
+
+ int GetCount();
+ void SetSelection( int index, bool State = true );
+ void SetString( unsigned linecount, const wxString& text );
+ void AppendLine( const wxString& text );
+
+ /**
+ * Function SetFootprints
+ * populates the wxListCtrl with the footprints from \a aList that meet the filter
+ * criteria defined by \a aFilterType.
+ *
+ * @param aList is a #FOOTPRINT_LIST item containing the footprints.
+ * @param aLibName is wxString containing the name of the selected library. Can be
+ * wxEmptyString.
+ * @param aComponent is the #COMPONENT used by the filtering criteria. Can be NULL.
+ * @param aFilterType defines the criteria to filter \a aList.
+ */
+ void SetFootprints( FOOTPRINT_LIST& aList, const wxString& aLibName,
+ COMPONENT* aComponent, int aFilterType );
+
+ wxString GetSelectedFootprint();
+
+ /**
+ * Function OnGetItemText
+ * this overloaded function MUST be provided for the wxLC_VIRTUAL mode
+ * because real data is not handled by ITEMS_LISTBOX_BASE
+ */
+ wxString OnGetItemText( long item, long column ) const;
+
+ // Events functions:
+ void OnLeftClick( wxListEvent& event );
+ void OnLeftDClick( wxListEvent& event );
+ void OnChar( wxKeyEvent& event );
+
+ DECLARE_EVENT_TABLE()
+};
+
+
+/******************************************/
+/* ListBox showing the list of library */
+/******************************************/
+class LIBRARY_LISTBOX : public ITEMS_LISTBOX_BASE
+{
+ wxArrayString m_libraryList;
+
+public:
+ LIBRARY_LISTBOX( CVPCB_MAINFRAME* parent, wxWindowID id,
+ const wxPoint& loc, const wxSize& size );
+ ~LIBRARY_LISTBOX();
+
+ int GetCount();
+ void SetSelection( int index, bool State = true );
+ void SetString( unsigned linecount, const wxString& text );
+ void AppendLine( const wxString& text );
+ void SetLibraryList( const wxArrayString& aList );
+
+ wxString GetSelectedLibrary();
+ wxString OnGetItemText( long item, long column ) const;
+
+ // Events functions:
+ void OnLeftClick( wxListEvent& event );
+
+ void OnSelectLibrary( wxListEvent& event );
+
+ /**
+ * Function OnChar
+ * called on a key pressed
+ * Call default handler for some special keys,
+ * and for "ascii" keys, select the first footprint
+ * that the name starts by the letter.
+ * This is the defaut behaviour of a listbox, but because we use
+ * virtual lists, the listbox does not know anything to what is displayed,
+ * we must handle this behaviour here.
+ * Furthermore the footprint name is not at the beginning of
+ * displayed lines (the first word is the line number)
+ */
+ void OnChar( wxKeyEvent& event );
+
+ DECLARE_EVENT_TABLE()
+};
+
+
+/****************************************************/
+/* ListBox showing the list of schematic components */
+/****************************************************/
+class COMPONENTS_LISTBOX : public ITEMS_LISTBOX_BASE
+{
+public:
+ wxArrayString m_ComponentList;
+
+public:
+
+ COMPONENTS_LISTBOX( CVPCB_MAINFRAME* parent, wxWindowID id,
+ const wxPoint& loc, const wxSize& size );
+
+ ~COMPONENTS_LISTBOX();
+
+ void Clear();
+ int GetCount();
+
+ /**
+ * Function OnGetItemText
+ * this overloaded function MUST be provided for the wxLC_VIRTUAL mode
+ * because real data is not handled by ITEMS_LISTBOX_BASE
+ */
+ wxString OnGetItemText( long item, long column ) const;
+
+ /*
+ * Enable or disable an item
+ */
+ void SetSelection( int index, bool State = true );
+ void SetString( unsigned linecount, const wxString& text );
+ void AppendLine( const wxString& text );
+
+ // Events functions:
+
+ /**
+ * Function OnChar
+ * called on a key pressed
+ * Call default handler for some special keys,
+ * and for "ascii" keys, select the first component
+ * that the name starts by the letter.
+ * This is the default behavior of a listbox, but because we use
+ * virtual lists, the listbox does not know anything to what is displayed,
+ * we must handle this behavior here.
+ * Furthermore the reference of components is not at the beginning of
+ * displayed lines (the first word is the line number)
+ */
+ void OnChar( wxKeyEvent& event );
+
+ void OnSelectComponent( wxListEvent& event );
+
+ DECLARE_EVENT_TABLE()
+};
+
+
+#endif //#ifndef CVSTRUCT_H
diff --git a/cvpcb/dialogs/dialog_config_equfiles.cpp b/cvpcb/dialogs/dialog_config_equfiles.cpp
new file mode 100644
index 0000000..3ae03fd
--- /dev/null
+++ b/cvpcb/dialogs/dialog_config_equfiles.cpp
@@ -0,0 +1,308 @@
+/**
+ * @file dialog_config_equfiles.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <common.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <id.h>
+#include <project.h> // For PROJECT_VAR_NAME definition
+#include <fp_lib_table.h> // For KISYSMOD definition
+
+#include <cvpcb.h>
+#include <cvpcb_mainframe.h>
+
+#include <dialog_config_equfiles.h>
+#include <wildcards_and_files_ext.h>
+
+
+DIALOG_CONFIG_EQUFILES::DIALOG_CONFIG_EQUFILES( CVPCB_MAINFRAME* aParent ) :
+ DIALOG_CONFIG_EQUFILES_BASE( aParent )
+{
+ m_Parent = aParent;
+ m_Config = Pgm().CommonSettings();
+
+ PROJECT& prj = Prj();
+ SetTitle( wxString::Format( _( "Project file: '%s'" ), GetChars( prj.GetProjectFullName() ) ) );
+
+ Init( );
+
+ GetSizer()->SetSizeHints( this );
+ Center();
+}
+
+void CVPCB_MAINFRAME::OnEditEquFilesList( wxCommandEvent& aEvent )
+{
+ DIALOG_CONFIG_EQUFILES dlg( this );
+
+ dlg.ShowModal();
+}
+
+
+void DIALOG_CONFIG_EQUFILES::Init()
+{
+ m_sdbSizerOK->SetDefault();
+ m_ListChanged = false;
+ m_ListEquiv->InsertItems( m_Parent->m_EquFilesNames, 0 );
+
+ if( getEnvVarCount() < 2 )
+ m_gridEnvVars->AppendRows(2 - getEnvVarCount() );
+
+ wxString evValue;
+ int row = 0;
+
+ m_gridEnvVars->SetCellValue( row++, 0, PROJECT_VAR_NAME );
+ m_gridEnvVars->SetCellValue( row, 0, FP_LIB_TABLE::GlobalPathEnvVariableName() );
+
+ for( row = 0; row < getEnvVarCount(); row++ )
+ {
+ if( wxGetEnv( m_gridEnvVars->GetCellValue( row, 0 ), &evValue ) )
+ m_gridEnvVars->SetCellValue( row, 1, evValue );
+ }
+
+ m_gridEnvVars->AutoSizeColumns();
+
+}
+
+void DIALOG_CONFIG_EQUFILES::OnEditEquFile( wxCommandEvent& event )
+{
+ wxString editorname = Pgm().GetEditorName();
+
+ if( editorname.IsEmpty() )
+ {
+ wxMessageBox( _( "No editor defined in Kicad. Please chose it" ) );
+ return;
+ }
+
+ wxArrayInt selections;
+ m_ListEquiv->GetSelections( selections );
+
+ wxString fullFileNames, tmp;
+
+ for( unsigned ii = 0; ii < selections.GetCount(); ii++ )
+ {
+ tmp = m_ListEquiv->GetString( selections[ii] );
+ fullFileNames << wxT( " \"" ) << wxExpandEnvVars( tmp ) << wxT( "\"" );
+ m_ListChanged = true;
+ }
+
+ ExecuteFile( this, editorname, fullFileNames );
+}
+
+
+void DIALOG_CONFIG_EQUFILES::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+void DIALOG_CONFIG_EQUFILES::OnOkClick( wxCommandEvent& event )
+{
+ // Save new equ file list if the files list was modified
+ if( m_ListChanged )
+ {
+ // Recreate equ list
+ m_Parent->m_EquFilesNames.Clear();
+
+ for( unsigned ii = 0; ii < m_ListEquiv->GetCount(); ii++ )
+ m_Parent->m_EquFilesNames.Add( m_ListEquiv->GetString( ii ) );
+
+ wxCommandEvent evt( ID_SAVE_PROJECT );
+ m_Parent->SaveProjectFile( evt );
+ }
+
+ EndModal( wxID_OK );
+}
+
+
+void DIALOG_CONFIG_EQUFILES::OnCloseWindow( wxCloseEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+/********************************************************************/
+void DIALOG_CONFIG_EQUFILES::OnButtonMoveUp( wxCommandEvent& event )
+/********************************************************************/
+{
+ wxArrayInt selections;
+
+ m_ListEquiv->GetSelections( selections );
+
+ if ( selections.GetCount() <= 0 ) // No selection.
+ return;
+
+ if( selections[0] == 0 ) // The first lib is selected. cannot move up it
+ return;
+
+ wxArrayString libnames = m_ListEquiv->GetStrings();
+
+ for( size_t ii = 0; ii < selections.GetCount(); ii++ )
+ {
+ int jj = selections[ii];
+ std::swap( libnames[jj], libnames[jj-1] );
+ }
+
+ m_ListEquiv->Set( libnames );
+
+ // Reselect previously selected names
+ for( size_t ii = 0; ii < selections.GetCount(); ii++ )
+ {
+ int jj = selections[ii];
+ m_ListEquiv->SetSelection( jj-1 );
+ }
+
+ m_ListChanged = true;
+}
+
+
+/*********************************************************************/
+void DIALOG_CONFIG_EQUFILES::OnButtonMoveDown( wxCommandEvent& event )
+/*********************************************************************/
+{
+ wxArrayInt selections;
+ m_ListEquiv->GetSelections( selections );
+
+ if ( selections.GetCount() <= 0 ) // No selection.
+ return;
+
+ // The last lib is selected. cannot move down it
+ if( selections.Last() == int( m_ListEquiv->GetCount()-1 ) )
+ return;
+
+ wxArrayString libnames = m_ListEquiv->GetStrings();
+
+ for( int ii = selections.GetCount()-1; ii >= 0; ii-- )
+ {
+ int jj = selections[ii];
+ std::swap( libnames[jj], libnames[jj+1]);
+ }
+
+ m_ListEquiv->Set( libnames );
+
+ // Reselect previously selected names
+ for( size_t ii = 0; ii < selections.GetCount(); ii++ )
+ {
+ int jj = selections[ii];
+ m_ListEquiv->SetSelection(jj+1);
+ }
+
+ m_ListChanged = true;
+}
+
+
+/* Remove a library to the library list.
+ * The real list (g_LibName_List) is not changed, so the change can be canceled
+ */
+void DIALOG_CONFIG_EQUFILES::OnRemoveFiles( wxCommandEvent& event )
+{
+ wxArrayInt selections;
+ m_ListEquiv->GetSelections( selections );
+
+ std::sort( selections.begin(), selections.end() );
+
+ for( int ii = selections.GetCount()-1; ii >= 0; ii-- )
+ {
+ m_ListEquiv->Delete(selections[ii] );
+ m_ListChanged = true;
+ }
+}
+
+
+/* Insert or add a library to the library list:
+ * The new library is put in list before (insert button) the selection,
+ * or added (add button) to end of list
+ */
+void DIALOG_CONFIG_EQUFILES::OnAddFiles( wxCommandEvent& event )
+{
+ wxString equFilename, wildcard;
+ wxFileName fn;
+
+ wildcard = EquFilesWildcard;
+ wxListBox* list = m_ListEquiv;
+
+ // Get a default path to open the file dialog:
+ wxString libpath;
+ wxArrayInt selectedRows = m_gridEnvVars->GetSelectedRows();
+
+ int row = selectedRows.GetCount() ? selectedRows[0] :
+ m_gridEnvVars->GetGridCursorRow();
+
+ libpath = m_gridEnvVars->GetCellValue( wxGridCellCoords( row, 1 ) );
+
+ wxFileDialog FilesDialog( this, _( "Equ files:" ), libpath,
+ wxEmptyString, wildcard,
+ wxFD_DEFAULT_STYLE | wxFD_MULTIPLE );
+
+ if( FilesDialog.ShowModal() != wxID_OK )
+ return;
+
+ wxArrayString Filenames;
+ FilesDialog.GetPaths( Filenames );
+
+ for( unsigned jj = 0; jj < Filenames.GetCount(); jj++ )
+ {
+ fn = Filenames[jj];
+ equFilename.Empty();
+
+ if( isPathRelativeAllowed() ) // try to use relative path
+ {
+ for( row = 0; row < getEnvVarCount(); row++ )
+ {
+ libpath = m_gridEnvVars->GetCellValue( wxGridCellCoords( row, 1 ) );
+
+ if( fn.MakeRelativeTo( libpath ) )
+ {
+ equFilename.Printf( wxT("${%s}%c%s"),
+ GetChars( m_gridEnvVars->GetCellValue( wxGridCellCoords( row, 0 ) ) ),
+ fn.GetPathSeparator(),
+ GetChars( fn.GetFullPath() ) );
+ break;
+ }
+ }
+ }
+
+ if( equFilename.IsEmpty() )
+ equFilename = Filenames[jj];
+
+ // Add or insert new library name, if not already in list
+ if( list->FindString( equFilename, fn.IsCaseSensitive() ) == wxNOT_FOUND )
+ {
+ m_ListChanged = true;
+ equFilename.Replace( wxT("\\"), wxT("/") ); // Use unix separators only.
+ list->Append( equFilename );
+ }
+ else
+ {
+ wxString msg;
+ msg.Printf( _( "File '%s' already exists in list" ), equFilename.GetData() );
+ DisplayError( this, msg );
+ }
+ }
+}
diff --git a/cvpcb/dialogs/dialog_config_equfiles.h b/cvpcb/dialogs/dialog_config_equfiles.h
new file mode 100644
index 0000000..aeb4868
--- /dev/null
+++ b/cvpcb/dialogs/dialog_config_equfiles.h
@@ -0,0 +1,71 @@
+/**
+ * @file dialog_config_equfiles.h
+ */
+
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2015 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 Kicad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _DIALOG_CONFIG_EQUFILES_H_
+#define _DIALOG_CONFIG_EQUFILES_H_
+
+#include <dialog_config_equfiles_base.h>
+
+class DIALOG_CONFIG_EQUFILES : public DIALOG_CONFIG_EQUFILES_BASE
+{
+private:
+ CVPCB_MAINFRAME* m_Parent;
+ wxConfigBase* m_Config;
+ wxString m_UserLibDirBufferImg;
+
+ bool m_ListChanged;
+
+private:
+ void Init();
+
+ // Virtual event handlers
+ void OnCloseWindow( wxCloseEvent& event );
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+ void OnAddFiles( wxCommandEvent& event );
+ void OnEditEquFile( wxCommandEvent& event );
+ void OnRemoveFiles( wxCommandEvent& event );
+ void OnButtonMoveUp( wxCommandEvent& event );
+ void OnButtonMoveDown( wxCommandEvent& event );
+
+ int getEnvVarCount() // Get the number of rows in env var table
+ {
+ return m_gridEnvVars->GetTable()->GetRowsCount();
+ }
+
+ bool isPathRelativeAllowed()
+ {
+ return m_rbPathOptionChoice->GetSelection() == 1;
+ }
+
+public:
+ DIALOG_CONFIG_EQUFILES( CVPCB_MAINFRAME* parent );
+ ~DIALOG_CONFIG_EQUFILES() {};
+};
+
+#endif // _DIALOG_CONFIG_EQUFILES_H_
diff --git a/cvpcb/dialogs/dialog_config_equfiles_base.cpp b/cvpcb/dialogs/dialog_config_equfiles_base.cpp
new file mode 100644
index 0000000..e4b8a8c
--- /dev/null
+++ b/cvpcb/dialogs/dialog_config_equfiles_base.cpp
@@ -0,0 +1,151 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_config_equfiles_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_CONFIG_EQUFILES_BASE::DIALOG_CONFIG_EQUFILES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbEquivChoiceSizer;
+ sbEquivChoiceSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Footprint/Component equ files (.equ files)") ), wxHORIZONTAL );
+
+ wxBoxSizer* bSizerFlist;
+ bSizerFlist = new wxBoxSizer( wxVERTICAL );
+
+ m_ListEquiv = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED|wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE );
+ m_ListEquiv->SetMinSize( wxSize( 350,-1 ) );
+
+ bSizerFlist->Add( m_ListEquiv, 1, wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ sbEquivChoiceSizer->Add( bSizerFlist, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerButtons;
+ bSizerButtons = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonAddEqu = new wxButton( this, ID_ADD_EQU, _("Add"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( m_buttonAddEqu, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonRemoveEqu = new wxButton( this, ID_REMOVE_EQU, _("Remove"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonRemoveEqu->SetToolTip( _("Unload the selected library") );
+
+ bSizerButtons->Add( m_buttonRemoveEqu, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonMoveUp = new wxButton( this, ID_EQU_UP, _("Move Up"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( m_buttonMoveUp, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonMoveDown = new wxButton( this, ID_EQU_DOWN, _("Move Down"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( m_buttonMoveDown, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonEdit = new wxButton( this, wxID_ANY, _("Edit Equ File"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( m_buttonEdit, 0, wxALL|wxEXPAND, 5 );
+
+
+ sbEquivChoiceSizer->Add( bSizerButtons, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bMainSizer->Add( sbEquivChoiceSizer, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerLower;
+ bSizerLower = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizerEnvVar;
+ bSizerEnvVar = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText2 = new wxStaticText( this, wxID_ANY, _("Available environment variables for relative paths:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText2->Wrap( -1 );
+ bSizerEnvVar->Add( m_staticText2, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_gridEnvVars = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_gridEnvVars->CreateGrid( 2, 2 );
+ m_gridEnvVars->EnableEditing( true );
+ m_gridEnvVars->EnableGridLines( true );
+ m_gridEnvVars->EnableDragGridSize( false );
+ m_gridEnvVars->SetMargins( 0, 0 );
+
+ // Columns
+ m_gridEnvVars->EnableDragColMove( false );
+ m_gridEnvVars->EnableDragColSize( true );
+ m_gridEnvVars->SetColLabelSize( 25 );
+ m_gridEnvVars->SetColLabelValue( 0, _("Name") );
+ m_gridEnvVars->SetColLabelValue( 1, _("Value") );
+ m_gridEnvVars->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_gridEnvVars->AutoSizeRows();
+ m_gridEnvVars->EnableDragRowSize( true );
+ m_gridEnvVars->SetRowLabelSize( 30 );
+ m_gridEnvVars->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_gridEnvVars->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ bSizerEnvVar->Add( m_gridEnvVars, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerLower->Add( bSizerEnvVar, 1, wxEXPAND, 5 );
+
+ wxString m_rbPathOptionChoiceChoices[] = { _("Absolute path"), _("Relative path") };
+ int m_rbPathOptionChoiceNChoices = sizeof( m_rbPathOptionChoiceChoices ) / sizeof( wxString );
+ m_rbPathOptionChoice = new wxRadioBox( this, wxID_ANY, _("Path option:"), wxDefaultPosition, wxDefaultSize, m_rbPathOptionChoiceNChoices, m_rbPathOptionChoiceChoices, 1, wxRA_SPECIFY_COLS );
+ m_rbPathOptionChoice->SetSelection( 1 );
+ bSizerLower->Add( m_rbPathOptionChoice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bMainSizer->Add( bSizerLower, 0, wxEXPAND, 5 );
+
+ m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline2, 0, wxEXPAND|wxALL, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bMainSizer->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnCloseWindow ) );
+ m_buttonAddEqu->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnAddFiles ), NULL, this );
+ m_buttonRemoveEqu->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnRemoveFiles ), NULL, this );
+ m_buttonMoveUp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnButtonMoveUp ), NULL, this );
+ m_buttonMoveDown->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnButtonMoveDown ), NULL, this );
+ m_buttonEdit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnEditEquFile ), NULL, this );
+ m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_CONFIG_EQUFILES_BASE::~DIALOG_CONFIG_EQUFILES_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnCloseWindow ) );
+ m_buttonAddEqu->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnAddFiles ), NULL, this );
+ m_buttonRemoveEqu->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnRemoveFiles ), NULL, this );
+ m_buttonMoveUp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnButtonMoveUp ), NULL, this );
+ m_buttonMoveDown->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnButtonMoveDown ), NULL, this );
+ m_buttonEdit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnEditEquFile ), NULL, this );
+ m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/cvpcb/dialogs/dialog_config_equfiles_base.fbp b/cvpcb/dialogs/dialog_config_equfiles_base.fbp
new file mode 100644
index 0000000..38e625e
--- /dev/null
+++ b/cvpcb/dialogs/dialog_config_equfiles_base.fbp
@@ -0,0 +1,1108 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_config_equfiles_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_cvpcb_config_equfile_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_CONFIG_EQUFILES_BASE</property>
+ <property name="pos"></property>
+ <property name="size">454,338</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseWindow</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprint/Component equ files (.equ files)</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbEquivChoiceSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerFlist</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxListBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,-1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">350,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_ListEquiv</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLB_EXTENDED|wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox"></event>
+ <event name="OnListBoxDClick"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerButtons</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADD_EQU</property>
+ <property name="label">Add</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonAddEqu</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnAddFiles</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_REMOVE_EQU</property>
+ <property name="label">Remove</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonRemoveEqu</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Unload the selected library</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnRemoveFiles</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_EQU_UP</property>
+ <property name="label">Move Up</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonMoveUp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonMoveUp</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_EQU_DOWN</property>
+ <property name="label">Move Down</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonMoveDown</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonMoveDown</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Edit Equ File</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonEdit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnEditEquFile</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerLower</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerEnvVar</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Available environment variables for relative paths:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">0</property>
+ <property name="autosize_rows">1</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg"></property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">25</property>
+ <property name="col_label_values">&quot;Name&quot; &quot;Value&quot;</property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">2</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">1</property>
+ <property name="editing">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_gridEnvVars</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">30</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">2</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick"></event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Absolute path&quot; &quot;Relative path&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Path option:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbPathOptionChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/cvpcb/dialogs/dialog_config_equfiles_base.h b/cvpcb/dialogs/dialog_config_equfiles_base.h
new file mode 100644
index 0000000..2220da5
--- /dev/null
+++ b/cvpcb/dialogs/dialog_config_equfiles_base.h
@@ -0,0 +1,82 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_CONFIG_EQUFILES_BASE_H__
+#define __DIALOG_CONFIG_EQUFILES_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/listbox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/statbox.h>
+#include <wx/stattext.h>
+#include <wx/grid.h>
+#include <wx/radiobox.h>
+#include <wx/statline.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_CONFIG_EQUFILES_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_CONFIG_EQUFILES_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ ID_ADD_EQU = 1000,
+ ID_REMOVE_EQU,
+ ID_EQU_UP,
+ ID_EQU_DOWN
+ };
+
+ wxListBox* m_ListEquiv;
+ wxButton* m_buttonAddEqu;
+ wxButton* m_buttonRemoveEqu;
+ wxButton* m_buttonMoveUp;
+ wxButton* m_buttonMoveDown;
+ wxButton* m_buttonEdit;
+ wxStaticText* m_staticText2;
+ wxGrid* m_gridEnvVars;
+ wxRadioBox* m_rbPathOptionChoice;
+ wxStaticLine* m_staticline2;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnAddFiles( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRemoveFiles( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonMoveUp( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonMoveDown( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnEditEquFile( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_CONFIG_EQUFILES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 454,338 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_CONFIG_EQUFILES_BASE();
+
+};
+
+#endif //__DIALOG_CONFIG_EQUFILES_BASE_H__
diff --git a/cvpcb/dialogs/dialog_cvpcb_config_fbp.h b/cvpcb/dialogs/dialog_cvpcb_config_fbp.h
new file mode 100644
index 0000000..7481dcd
--- /dev/null
+++ b/cvpcb/dialogs/dialog_cvpcb_config_fbp.h
@@ -0,0 +1,100 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Apr 10 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_CVPCB_CONFIG_FBP_H__
+#define __DIALOG_CVPCB_CONFIG_FBP_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/listbox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/textctrl.h>
+#include <wx/statline.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_CVPCB_CONFIG_FBP
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_CVPCB_CONFIG_FBP : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ ID_ADD_LIB = 1000,
+ ID_INSERT_LIB,
+ ID_REMOVE_LIB,
+ ID_LIB_UP,
+ ID_LIB_DOWN,
+ ID_ADD_EQU,
+ ID_INSERT_EQU,
+ ID_REMOVE_EQU,
+ ID_EQU_UP,
+ ID_EQU_DOWN,
+ ID_BROWSE_MOD_DOC,
+ ID_LIB_PATH_SEL,
+ ID_INSERT_PATH,
+ ID_REMOVE_PATH
+ };
+
+ wxListBox* m_ListLibr;
+ wxButton* m_buttonAddLib;
+ wxButton* m_buttonInsLib;
+ wxButton* m_buttonRemoveLib;
+ wxButton* m_buttonLibUp;
+ wxButton* m_buttonLibDown;
+ wxListBox* m_ListEquiv;
+ wxButton* m_buttonAddEqu;
+ wxButton* m_buttonInsEqu;
+ wxButton* m_buttonRemoveEqu;
+ wxButton* m_buttonEquUp;
+ wxButton* m_buttonEquDown;
+ wxTextCtrl* m_TextHelpModulesFileName;
+ wxButton* m_buttonModDoc;
+ wxListBox* m_listUserPaths;
+ wxButton* m_buttonAddPath;
+ wxButton* m_buttonInsPath;
+ wxButton* m_buttonRemovePath;
+ wxListBox* m_DefaultLibraryPathslistBox;
+ wxStaticLine* m_staticline2;
+ wxStdDialogButtonSizer* m_sdbSizer2;
+ wxButton* m_sdbSizer2OK;
+ wxButton* m_sdbSizer2Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnAddOrInsertLibClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRemoveLibClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonUpClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonDownClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnBrowseModDocFile( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnAddOrInsertPath( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRemoveUserPath( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_CVPCB_CONFIG_FBP( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 570,625 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_CVPCB_CONFIG_FBP();
+
+};
+
+#endif //__DIALOG_CVPCB_CONFIG_FBP_H__
diff --git a/cvpcb/dialogs/dialog_display_options.cpp b/cvpcb/dialogs/dialog_display_options.cpp
new file mode 100644
index 0000000..9911ebc
--- /dev/null
+++ b/cvpcb/dialogs/dialog_display_options.cpp
@@ -0,0 +1,136 @@
+/**
+ * @file cvpcb/dialogs/dialog_display_options.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+
+#include <wxstruct.h>
+#include <common.h>
+#include <cvpcb.h>
+#include <class_drawpanel.h>
+#include <cvstruct.h>
+#include <class_DisplayFootprintsFrame.h>
+
+#include <dialog_display_options.h>
+
+
+void DISPLAY_FOOTPRINTS_FRAME::InstallOptionsDisplay( wxCommandEvent& event )
+{
+ DIALOG_FOOTPRINTS_DISPLAY_OPTIONS* OptionWindow =
+ new DIALOG_FOOTPRINTS_DISPLAY_OPTIONS( this );
+
+ OptionWindow->ShowModal();
+ OptionWindow->Destroy();
+}
+
+
+DIALOG_FOOTPRINTS_DISPLAY_OPTIONS::DIALOG_FOOTPRINTS_DISPLAY_OPTIONS( PCB_BASE_FRAME* parent )
+ : DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE( parent )
+{
+ m_Parent = parent;
+
+ initDialog();
+ m_sdbSizer1OK->SetDefault();
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+DIALOG_FOOTPRINTS_DISPLAY_OPTIONS::~DIALOG_FOOTPRINTS_DISPLAY_OPTIONS( )
+{
+}
+
+
+/*!
+ * Control creation for DIALOG_FOOTPRINTS_DISPLAY_OPTIONS
+ */
+
+void DIALOG_FOOTPRINTS_DISPLAY_OPTIONS::initDialog()
+{
+ /* mandatory to use escape key as cancel under wxGTK. */
+ SetFocus();
+
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)m_Parent->GetDisplayOptions();
+
+ m_EdgesDisplayOption->SetValue( not displ_opts->m_DisplayModEdgeFill );
+ m_TextDisplayOption->SetValue( not displ_opts->m_DisplayModTextFill );
+ m_ShowPadSketch->SetValue( not displ_opts->m_DisplayPadFill );
+ m_ShowPadNum->SetValue( displ_opts->m_DisplayPadNum );
+ m_IsZoomNoCenter->SetValue( m_Parent->GetCanvas()->GetEnableZoomNoCenter() );
+ m_IsMiddleButtonPan->SetValue( m_Parent->GetCanvas()->GetEnableMiddleButtonPan() );
+ m_IsMiddleButtonPanLimited->SetValue( m_Parent->GetCanvas()->GetMiddleButtonPanLimited() );
+ m_IsMiddleButtonPanLimited->Enable( m_IsMiddleButtonPan->GetValue() );
+}
+
+
+
+/*!
+ * Update settings related to edges, text strings, and pads
+ */
+
+void DIALOG_FOOTPRINTS_DISPLAY_OPTIONS::UpdateObjectSettings( void )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)m_Parent->GetDisplayOptions();
+
+ displ_opts->m_DisplayModEdgeFill = not m_EdgesDisplayOption->GetValue();
+ displ_opts->m_DisplayModTextFill = not m_TextDisplayOption->GetValue();
+ displ_opts->m_DisplayPadNum = m_ShowPadNum->GetValue();
+ displ_opts->m_DisplayPadFill = not m_ShowPadSketch->GetValue();
+ m_Parent->GetCanvas()->SetEnableZoomNoCenter( m_IsZoomNoCenter->GetValue() );
+ m_Parent->GetCanvas()->SetEnableMiddleButtonPan( m_IsMiddleButtonPan->GetValue() );
+ m_Parent->GetCanvas()->SetMiddleButtonPanLimited( m_IsMiddleButtonPanLimited->GetValue() );
+ m_Parent->GetCanvas()->Refresh();
+}
+
+
+/*!
+ * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_OK
+ */
+
+void DIALOG_FOOTPRINTS_DISPLAY_OPTIONS::OnOkClick( wxCommandEvent& event )
+{
+ UpdateObjectSettings();
+ EndModal( 1 );
+}
+
+
+/*!
+ * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL
+ */
+
+void DIALOG_FOOTPRINTS_DISPLAY_OPTIONS::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( -1 );
+}
+
+
+/*!
+ * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_APPLY
+ */
+
+void DIALOG_FOOTPRINTS_DISPLAY_OPTIONS::OnApplyClick( wxCommandEvent& event )
+{
+ UpdateObjectSettings();
+}
diff --git a/cvpcb/dialogs/dialog_display_options.h b/cvpcb/dialogs/dialog_display_options.h
new file mode 100644
index 0000000..fada3f0
--- /dev/null
+++ b/cvpcb/dialogs/dialog_display_options.h
@@ -0,0 +1,61 @@
+/**
+ * @file cvpcb/dialogs/dialog_display_options.h
+ */
+
+#ifndef _DIALOG_DISPLAY_OPTIONS_H_
+#define _DIALOG_DISPLAY_OPTIONS_H_
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <dialog_display_options_base.h>
+
+/* Class DIALOG_FOOTPRINTS_DISPLAY_OPTIONS
+ * derived from DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE,
+ * created by wxformBuilder
+*/
+
+class DIALOG_FOOTPRINTS_DISPLAY_OPTIONS :
+ public DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE
+{
+private:
+PCB_BASE_FRAME * m_Parent;
+
+public:
+ DIALOG_FOOTPRINTS_DISPLAY_OPTIONS( PCB_BASE_FRAME* parent );
+ ~DIALOG_FOOTPRINTS_DISPLAY_OPTIONS();
+
+
+private:
+ void initDialog( );
+ void UpdateObjectSettings( void );
+ void OnApplyClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+ void OnOkClick( wxCommandEvent& event );
+ void OnMiddleBtnPanEnbl( wxCommandEvent& event )
+ {
+ m_IsMiddleButtonPanLimited->Enable( m_IsMiddleButtonPan->GetValue() );
+ }
+};
+
+#endif // _DIALOG_DISPLAY_OPTIONS_H_
diff --git a/cvpcb/dialogs/dialog_display_options_base.cpp b/cvpcb/dialogs/dialog_display_options_base.cpp
new file mode 100644
index 0000000..99be007
--- /dev/null
+++ b/cvpcb/dialogs/dialog_display_options_base.cpp
@@ -0,0 +1,93 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_display_options_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE::DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sbSizerDrawMode;
+ sbSizerDrawMode = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Draw options") ), wxVERTICAL );
+
+ m_EdgesDisplayOption = new wxCheckBox( this, wxID_ANY, _("Graphic items sketch mode"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerDrawMode->Add( m_EdgesDisplayOption, 0, wxALL, 5 );
+
+ m_TextDisplayOption = new wxCheckBox( this, wxID_ANY, _("Texts sketch mode"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerDrawMode->Add( m_TextDisplayOption, 0, wxALL, 5 );
+
+ m_ShowPadSketch = new wxCheckBox( this, ID_PADFILL_OPT, _("Pad sketch mode"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerDrawMode->Add( m_ShowPadSketch, 0, wxEXPAND|wxALL, 5 );
+
+ m_ShowPadNum = new wxCheckBox( this, wxID_ANY, _("Show pad &number"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerDrawMode->Add( m_ShowPadNum, 0, wxALL|wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( sbSizerDrawMode, 1, wxEXPAND|wxALL, 5 );
+
+ wxStaticBoxSizer* sbSizerViewOpt;
+ sbSizerViewOpt = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Pan and Zoom") ), wxVERTICAL );
+
+ m_IsZoomNoCenter = new wxCheckBox( this, wxID_ANY, _("Do not center and warp cursor on zoom"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_IsZoomNoCenter->SetToolTip( _("Keep the cursor at its current location when zooming") );
+
+ sbSizerViewOpt->Add( m_IsZoomNoCenter, 0, wxEXPAND|wxALL, 5 );
+
+ m_IsMiddleButtonPan = new wxCheckBox( this, wxID_ANY, _("Use middle mouse button to pan"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerViewOpt->Add( m_IsMiddleButtonPan, 0, wxEXPAND|wxALL, 5 );
+
+ m_IsMiddleButtonPanLimited = new wxCheckBox( this, wxID_ANY, _("Limit panning to scroll size"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerViewOpt->Add( m_IsMiddleButtonPanLimited, 0, wxALL|wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( sbSizerViewOpt, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bUpperSizer, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerMain->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Apply = new wxButton( this, wxID_APPLY );
+ m_sdbSizer1->AddButton( m_sdbSizer1Apply );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bSizerMain->Add( m_sdbSizer1, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ // Connect Events
+ m_IsMiddleButtonPan->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE::OnMiddleBtnPanEnbl ), NULL, this );
+ m_sdbSizer1Apply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE::OnApplyClick ), NULL, this );
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE::~DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE()
+{
+ // Disconnect Events
+ m_IsMiddleButtonPan->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE::OnMiddleBtnPanEnbl ), NULL, this );
+ m_sdbSizer1Apply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE::OnApplyClick ), NULL, this );
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/cvpcb/dialogs/dialog_display_options_base.fbp b/cvpcb/dialogs/dialog_display_options_base.fbp
new file mode 100644
index 0000000..1a7fb17
--- /dev/null
+++ b/cvpcb/dialogs/dialog_display_options_base.fbp
@@ -0,0 +1,861 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_display_options_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_display_options_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">425,206</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Display Options</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Draw options</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerDrawMode</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Graphic items sketch mode</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_EdgesDisplayOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Texts sketch mode</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextDisplayOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_PADFILL_OPT</property>
+ <property name="label">Pad sketch mode</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShowPadSketch</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show pad &amp;number</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShowPadNum</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pan and Zoom</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerViewOpt</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Do not center and warp cursor on zoom</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_IsZoomNoCenter</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Keep the cursor at its current location when zooming</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Use middle mouse button to pan</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_IsMiddleButtonPan</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnMiddleBtnPanEnbl</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Limit panning to scroll size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_IsMiddleButtonPanLimited</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">1</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick">OnApplyClick</event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/cvpcb/dialogs/dialog_display_options_base.h b/cvpcb/dialogs/dialog_display_options_base.h
new file mode 100644
index 0000000..febdd1f
--- /dev/null
+++ b/cvpcb/dialogs/dialog_display_options_base.h
@@ -0,0 +1,68 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_DISPLAY_OPTIONS_BASE_H__
+#define __DIALOG_DISPLAY_OPTIONS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/checkbox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_PADFILL_OPT 1000
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxCheckBox* m_EdgesDisplayOption;
+ wxCheckBox* m_TextDisplayOption;
+ wxCheckBox* m_ShowPadSketch;
+ wxCheckBox* m_ShowPadNum;
+ wxCheckBox* m_IsZoomNoCenter;
+ wxCheckBox* m_IsMiddleButtonPan;
+ wxCheckBox* m_IsMiddleButtonPanLimited;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Apply;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnMiddleBtnPanEnbl( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnApplyClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Display Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 425,206 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_FOOTPRINTS_DISPLAY_OPTIONS_BASE();
+
+};
+
+#endif //__DIALOG_DISPLAY_OPTIONS_BASE_H__
diff --git a/cvpcb/dialogs/fp_conflict_assignment_selector.cpp b/cvpcb/dialogs/fp_conflict_assignment_selector.cpp
new file mode 100644
index 0000000..35dcd8f
--- /dev/null
+++ b/cvpcb/dialogs/fp_conflict_assignment_selector.cpp
@@ -0,0 +1,190 @@
+/**
+ * @file fp_conflict_assignment_selector.cpp
+ */
+
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras <jp.charras at wanadoo.fr>
+ * Copyright (C) 1992-2014 Kicad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <common.h>
+
+#include <fp_conflict_assignment_selector.h>
+
+
+DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR::DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR( wxWindow* aParent )
+ : DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE( aParent )
+{
+ m_listFp->AppendColumn( _( "Ref" ) );
+ m_listFp->AppendColumn( _( "Schematic assignment" ) );
+ m_listFp->AppendColumn( wxT( "<=" ) );
+ m_listFp->AppendColumn( wxT( "=>" ) );
+ m_listFp->AppendColumn( _( "Cmp file assignment" ) );
+
+ m_lineCount = 0;
+}
+
+void DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR::Add( const wxString& aRef, const wxString& aFpSchName,
+ const wxString& aFpCmpName )
+{
+ long idx = m_listFp->InsertItem(m_lineCount, aRef );
+
+ m_listFp->SetItem(idx, COL_FPSCH, aFpSchName );
+ m_listFp->SetItem(idx, COL_SELSCH, wxT("") );
+ m_listFp->SetItem(idx, COL_SELCMP, wxT("X") );
+ m_listFp->SetItem(idx, COL_FPCMP, aFpCmpName );
+
+ m_lineCount ++;
+}
+
+int DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR::GetSelection( const wxString& aReference )
+{
+ // Find Reference
+ for( int ii = 0; ii < m_listFp->GetItemCount(); ii++ )
+ {
+ if( m_listFp->GetItemText( ii, COL_REF ) == aReference )
+ {
+ if( m_listFp->GetItemText( ii, COL_SELSCH ) != wxT("X") )
+ return 1;
+
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+void DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR::OnColumnClick( wxListEvent& event )
+{
+ // When clicking on the column title:
+ // when it is the COL_SELCMP column, set all item choices to cmp file assigment.
+ // when it is the COL_SELSCH column, set all item choices to schematic assigment.
+
+ wxListItem item = event.GetItem();
+
+ int column = event.GetColumn();
+ int colclr, colset;
+
+ switch( column )
+ {
+ case COL_SELSCH:
+ colclr = COL_SELCMP;
+ colset = COL_SELSCH;
+ break;
+
+ case COL_SELCMP:
+ colclr = COL_SELSCH;
+ colset = COL_SELCMP;
+ break;
+
+ default:
+ return;
+ }
+
+ for( int i = 0; i < m_listFp->GetItemCount(); i++ )
+ {
+ m_listFp->SetItem( i, colclr, wxT("") );
+ m_listFp->SetItem( i, colset, wxT("X") );
+ }
+}
+
+void DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR::OnItemClicked( wxMouseEvent& event )
+{
+ wxPoint pos = event.GetPosition();
+ int flgs = wxLIST_HITTEST_ONITEMLABEL;
+ long idx = m_listFp->HitTest( pos, flgs );
+
+ // Try to find the column clicked (must be COL_SELCMP or COL_SELSCH)
+ int colclr = -1, colset;
+ int minpx = m_listFp->GetColumnWidth( 0 ) + m_listFp->GetColumnWidth( 1 );
+ int maxpx = minpx + m_listFp->GetColumnWidth( 2 );
+
+ if( pos.x > minpx && pos.x < maxpx )
+ {
+ colclr = COL_SELCMP;
+ colset = COL_SELSCH;
+ }
+
+ else
+ {
+ minpx = maxpx;
+ int maxpx = minpx + m_listFp->GetColumnWidth( 3 );
+
+ if( pos.x > minpx && pos.x < maxpx )
+ {
+ colclr = COL_SELSCH;
+ colset = COL_SELCMP;
+ }
+ }
+
+ if( colclr < 0 )
+ return;
+
+ // Move selection to schematic or cmp file choice
+ // according to the column position (COL_SELCMP or COL_SELSCH)
+ m_listFp->SetItem( idx, colclr, wxT("") );
+ m_listFp->SetItem( idx, colset, wxT("X") );
+
+ event.Skip();
+}
+
+
+void DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR::OnSize( wxSizeEvent& aEvent )
+{
+ recalculateColumns();
+ aEvent.Skip();
+}
+
+
+void DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR::recalculateColumns()
+{
+ const int margin = 16;
+ int totalLength = 0;
+ int sel_length = GetTextSize( wxT("XX"), m_listFp ).x;
+ int maxRefLength = GetTextSize( wxT("XXX"), m_listFp ).x;
+
+ sel_length += margin;
+ m_listFp->SetColumnWidth( COL_SELSCH, sel_length );
+ m_listFp->SetColumnWidth( COL_SELCMP, sel_length );
+
+ // Find max character width of column Reference
+ for( int i = 0; i < m_listFp->GetItemCount(); i++ )
+ {
+ int length = GetTextSize( m_listFp->GetItemText( i, COL_REF ), m_listFp ).x;
+
+ if( length > maxRefLength )
+ maxRefLength = length;
+ }
+
+
+ // Use the lengths of column texts to create a scale of the max list width
+ // to set the column widths
+ maxRefLength += margin;
+ totalLength = maxRefLength + sel_length + sel_length;
+
+ int cwidth = (GetClientSize().x - totalLength) / 2;
+
+ m_listFp->SetColumnWidth( COL_REF, maxRefLength );
+ m_listFp->SetColumnWidth( COL_FPSCH, cwidth - 2 );
+ m_listFp->SetColumnWidth( COL_FPCMP, cwidth );
+}
+
diff --git a/cvpcb/dialogs/fp_conflict_assignment_selector.h b/cvpcb/dialogs/fp_conflict_assignment_selector.h
new file mode 100644
index 0000000..9beeb3f
--- /dev/null
+++ b/cvpcb/dialogs/fp_conflict_assignment_selector.h
@@ -0,0 +1,79 @@
+/**
+ * @file fp_conflict_assignment_selector.h
+ */
+
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras <jp.charras at wanadoo.fr>
+ * Copyright (C) 1992-2014 Kicad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fp_conflict_assignment_selector_base.h>
+
+
+class DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR : public DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE
+{
+ private:
+ enum COL_ID
+ {
+ COL_REF, COL_FPSCH, COL_SELSCH, COL_SELCMP, COL_FPCMP,
+ COL_COUNT
+ };
+
+ int m_lineCount;
+
+ public:
+
+ DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR( wxWindow* parent );
+
+ /**
+ * Add a line to the selection list.
+ * @param aRef = component reference text
+ * @param aFpSchName = fpid text from the netlist
+ * @param aFpCmpName = fpid text from the .cmp file
+ */
+ void Add( const wxString& aRef, const wxString& aFpSchName,
+ const wxString& aFpCmpName );
+
+ /**
+ * @return the selection option:
+ * 0 for fpid text from the netlist
+ * 1 for fpid text from the cmp file
+ * -1 on error
+ * @param aReference = the compoent schematic reference
+ */
+ int GetSelection( const wxString& aReference );
+
+ private:
+ void OnSize( wxSizeEvent& event );
+
+ // Virtual: called when clicking on the column title:
+ // when it is a column choice, set all item choices.
+ void OnColumnClick( wxListEvent& event );
+
+ void OnItemClicked( wxMouseEvent& event );
+
+ void OnCancelClick( wxCommandEvent& event ) { EndModal( wxID_CANCEL ); }
+ void OnOKClick( wxCommandEvent& event ) { EndModal( wxID_OK ); }
+
+ void recalculateColumns();
+
+};
diff --git a/cvpcb/dialogs/fp_conflict_assignment_selector_base.cpp b/cvpcb/dialogs/fp_conflict_assignment_selector_base.cpp
new file mode 100644
index 0000000..8f0d9f7
--- /dev/null
+++ b/cvpcb/dialogs/fp_conflict_assignment_selector_base.cpp
@@ -0,0 +1,58 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "fp_conflict_assignment_selector_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE::DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextInfo = new wxStaticText( this, wxID_ANY, wxT("Footprint assignments from schematic netlist and from .cmp file are conflicting\nPlease choose the assignment."), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
+ m_staticTextInfo->Wrap( -1 );
+ bSizerMain->Add( m_staticTextInfo, 0, wxALL|wxEXPAND, 5 );
+
+ m_listFp = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES );
+ bSizerMain->Add( m_listFp, 1, wxALL|wxEXPAND, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bSizerMain->Add( m_sdbSizer, 0, wxALIGN_RIGHT, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE::OnSize ) );
+ m_listFp->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE::OnItemClicked ), NULL, this );
+ m_listFp->Connect( wxEVT_COMMAND_LIST_COL_CLICK, wxListEventHandler( DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE::OnColumnClick ), NULL, this );
+ m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE::OnOKClick ), NULL, this );
+}
+
+DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE::~DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE::OnSize ) );
+ m_listFp->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE::OnItemClicked ), NULL, this );
+ m_listFp->Disconnect( wxEVT_COMMAND_LIST_COL_CLICK, wxListEventHandler( DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE::OnColumnClick ), NULL, this );
+ m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE::OnOKClick ), NULL, this );
+
+}
diff --git a/cvpcb/dialogs/fp_conflict_assignment_selector_base.fbp b/cvpcb/dialogs/fp_conflict_assignment_selector_base.fbp
new file mode 100644
index 0000000..fb57694
--- /dev/null
+++ b/cvpcb/dialogs/fp_conflict_assignment_selector_base.fbp
@@ -0,0 +1,313 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">fp_conflict_assignment_selector_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">0</property>
+ <property name="name">fp_conflict_assignment_selector</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE</property>
+ <property name="pos"></property>
+ <property name="size">478,294</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Footprint Assignment Conflicts</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize">OnSize</event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprint assignments from schematic netlist and from .cmp file are conflicting&#x0A;Please choose the assignment.</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextInfo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxALIGN_CENTRE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxListCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_listFp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown">OnItemClicked</event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBeginDrag"></event>
+ <event name="OnListBeginLabelEdit"></event>
+ <event name="OnListBeginRDrag"></event>
+ <event name="OnListCacheHint"></event>
+ <event name="OnListColBeginDrag"></event>
+ <event name="OnListColClick">OnColumnClick</event>
+ <event name="OnListColDragging"></event>
+ <event name="OnListColEndDrag"></event>
+ <event name="OnListColRightClick"></event>
+ <event name="OnListDeleteAllItems"></event>
+ <event name="OnListDeleteItem"></event>
+ <event name="OnListEndLabelEdit"></event>
+ <event name="OnListInsertItem"></event>
+ <event name="OnListItemActivated"></event>
+ <event name="OnListItemDeselected"></event>
+ <event name="OnListItemFocused"></event>
+ <event name="OnListItemMiddleClick"></event>
+ <event name="OnListItemRightClick"></event>
+ <event name="OnListItemSelected"></event>
+ <event name="OnListKeyDown"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/cvpcb/dialogs/fp_conflict_assignment_selector_base.h b/cvpcb/dialogs/fp_conflict_assignment_selector_base.h
new file mode 100644
index 0000000..b56df23
--- /dev/null
+++ b/cvpcb/dialogs/fp_conflict_assignment_selector_base.h
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE_H__
+#define __FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/listctrl.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticTextInfo;
+ wxListCtrl* m_listFp;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnSize( wxSizeEvent& event ) { event.Skip(); }
+ virtual void OnItemClicked( wxMouseEvent& event ) { event.Skip(); }
+ virtual void OnColumnClick( wxListEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Footprint Assignment Conflicts"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 478,294 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE();
+
+};
+
+#endif //__FP_CONFLICT_ASSIGNMENT_SELECTOR_BASE_H__
diff --git a/cvpcb/listboxes.cpp b/cvpcb/listboxes.cpp
new file mode 100644
index 0000000..e06c039
--- /dev/null
+++ b/cvpcb/listboxes.cpp
@@ -0,0 +1,122 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file listboxes.cpp
+ * @brief Implementation of class for displaying footprint list and component lists.
+ */
+
+#include <fctsys.h>
+#include <wxstruct.h>
+#include <macros.h>
+
+#include <cvpcb.h>
+#include <cvpcb_mainframe.h>
+#include <cvstruct.h>
+#include <cvpcb_id.h>
+
+
+/******************************************************************************
+* Basic class (from wxListView) to display component and footprint lists
+* Not directly used: the 2 list boxes actually used are derived from it
+******************************************************************************/
+
+ITEMS_LISTBOX_BASE::ITEMS_LISTBOX_BASE( CVPCB_MAINFRAME* aParent, wxWindowID aId,
+ const wxPoint& aLocation, const wxSize& aSize,
+ long aStyle) :
+ wxListView( aParent, aId, aLocation, aSize, LISTBOX_STYLE | aStyle ), columnWidth(0)
+{
+ InsertColumn( 0, wxEmptyString );
+}
+
+
+ITEMS_LISTBOX_BASE::~ITEMS_LISTBOX_BASE()
+{
+}
+
+
+void ITEMS_LISTBOX_BASE::UpdateWidth( int aLine )
+{
+ // Less than zero: recalculate width of all items.
+ if( aLine < 0 )
+ {
+ columnWidth = 0;
+ for( int ii = 0; ii < GetItemCount(); ii++ )
+ {
+ UpdateLineWidth( (unsigned)ii );
+ }
+ }
+
+ // Zero or above: update from a single line.
+ else
+ {
+ if( aLine < GetItemCount() )
+ UpdateLineWidth( (unsigned)aLine );
+ }
+}
+
+
+/*
+ * Calculate the width of the given line, and increase the column width
+ * if needed. This is effectively the wxListCtrl code for autosizing.
+ * NB. it relies on the caller checking the given line number is valid.
+ */
+void ITEMS_LISTBOX_BASE::UpdateLineWidth( unsigned aLine )
+{
+ wxClientDC dc( this );
+ wxCoord w;
+ int newWidth = 10; // Value of AUTOSIZE_COL_MARGIN from wxWidgets source.
+
+ dc.SetFont( GetFont() );
+ dc.GetTextExtent( GetItemText( aLine, 0 ) + " ", &w, NULL );
+ newWidth += w;
+
+ if( newWidth > columnWidth )
+ {
+ columnWidth = newWidth;
+ SetColumnWidth( 0, columnWidth );
+ }
+}
+
+
+/*
+ * Return an index for the selected item
+ */
+int ITEMS_LISTBOX_BASE::GetSelection()
+{
+ return GetFirstSelected();
+}
+
+/* Removes all selection in list
+*/
+void ITEMS_LISTBOX_BASE::DeselectAll()
+{
+ for( int i = 0; i < GetItemCount(); i++ )
+ Select( i, false );
+}
+
+
+CVPCB_MAINFRAME* ITEMS_LISTBOX_BASE::GetParent() const
+{
+ return (CVPCB_MAINFRAME*) wxListView::GetParent();
+}
diff --git a/cvpcb/menubar.cpp b/cvpcb/menubar.cpp
new file mode 100644
index 0000000..9be8744
--- /dev/null
+++ b/cvpcb/menubar.cpp
@@ -0,0 +1,153 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file cvpcb/menubar.cpp
+ * @brief (Re)Create the menubar for CvPcb
+ */
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <menus_helpers.h>
+
+#include <cvpcb.h>
+#include <cvpcb_mainframe.h>
+#include <cvpcb_id.h>
+
+#include <common_help_msg.h>
+
+
+/**
+ * @brief (Re)Create the menubar for the CvPcb mainframe
+ */
+void CVPCB_MAINFRAME::ReCreateMenuBar()
+{
+ // Create and try to get the current menubar
+ wxMenuItem* item;
+ wxMenuBar* menuBar = GetMenuBar();
+
+ if( ! menuBar ) // Delete all menus
+ menuBar = new wxMenuBar();
+
+ // Delete all existing menus so they can be rebuilt.
+ // This allows language changes of the menu text on the fly.
+ menuBar->Freeze();
+
+ while( menuBar->GetMenuCount() )
+ delete menuBar->Remove( 0 );
+
+ // Recreate all menus:
+
+ // Menu File:
+ wxMenu* filesMenu = new wxMenu;
+
+ // Save the footprints back into eeschema
+ AddMenuItem( filesMenu, wxID_SAVE,
+ _( "&Save Edits\tCtrl+S" ), SAVE_HLP_MSG, KiBitmap( save_xpm ) );
+
+ // Separator
+ filesMenu->AppendSeparator();
+
+ // Quit
+ AddMenuItem( filesMenu, wxID_EXIT,
+ _( "&Close" ), _( "Close CvPcb" ),
+ KiBitmap( exit_xpm ) );
+
+ // Menu Preferences:
+ wxMenu* preferencesMenu = new wxMenu;
+
+ AddMenuItem( preferencesMenu, ID_CVPCB_LIB_TABLE_EDIT,
+ _( "Footprint Li&braries" ), _( "Configure footprint libraries" ),
+ KiBitmap( library_table_xpm ) );
+
+ // Path configuration edit dialog.
+ AddMenuItem( preferencesMenu,
+ ID_PREFERENCES_CONFIGURE_PATHS,
+ _( "Configure Pa&ths" ),
+ _( "Edit path configuration environment variables" ),
+ KiBitmap( editor_xpm ) );
+
+ AddMenuItem( preferencesMenu, ID_CVPCB_EQUFILES_LIST_EDIT,
+ _( "Footprint &Association Files" ),
+ _( "Configure footprint association file (.equ) list."
+ "These files are used to automatically assign"
+ "the footprint name from the component value" ),
+ KiBitmap( library_table_xpm ) );
+
+ // Language submenu
+ Pgm().AddMenuLanguageList( preferencesMenu );
+
+ // Keep open on save
+ item = new wxMenuItem( preferencesMenu, ID_CVPCB_CONFIG_KEEP_OPEN_ON_SAVE,
+ _( "&Keep Open On Save" ),
+ _( "Prevent CvPcb from exiting after saving netlist file" ),
+ wxITEM_CHECK );
+ preferencesMenu->Append( item );
+ SETBITMAPS( window_close_xpm );
+
+ // Separator
+ preferencesMenu->AppendSeparator();
+ AddMenuItem( preferencesMenu, ID_SAVE_PROJECT,
+ _( "&Save Project File" ),
+ _( "Save changes to the project configuration file" ),
+ KiBitmap( save_setup_xpm ) );
+
+ // Menu Help:
+ wxMenu* helpMenu = new wxMenu;
+
+ // Version info
+ AddHelpVersionInfoMenuEntry( helpMenu );
+
+ // Manual Contents
+ AddMenuItem( helpMenu, wxID_HELP, _( "CvPcb &Manual" ),
+ _( "Open CvPcb Manual" ),
+ KiBitmap( online_help_xpm ) );
+
+ AddMenuItem( helpMenu,
+ wxID_INDEX,
+ _( "&Getting Started in KiCad" ),
+ _( "Open \"Getting Started in KiCad\" guide for beginners" ),
+ KiBitmap( help_xpm ) );
+
+ // About CvPcb
+ AddMenuItem( helpMenu, wxID_ABOUT,
+ _( "&About Kicad" ),
+ _( "About KiCad" ),
+ KiBitmap( info_xpm ) );
+
+ // Create the menubar and append all submenus
+ menuBar->Append( filesMenu, _( "&File" ) );
+ menuBar->Append( preferencesMenu, _( "&Preferences" ) );
+ menuBar->Append( helpMenu, _( "&Help" ) );
+
+ menuBar->Thaw();
+
+ // Associate the menu bar with the frame, if no previous menubar
+ if( GetMenuBar() == NULL )
+ SetMenuBar( menuBar );
+ else
+ menuBar->Refresh();
+}
diff --git a/cvpcb/readwrite_dlgs.cpp b/cvpcb/readwrite_dlgs.cpp
new file mode 100644
index 0000000..9e298e6
--- /dev/null
+++ b/cvpcb/readwrite_dlgs.cpp
@@ -0,0 +1,402 @@
+/**
+ * @file cvpcb/readwrite_dlgs.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <kiway.h>
+#include <common.h>
+#include <confirm.h>
+#include <build_version.h>
+#include <macros.h>
+#include <fpid.h>
+#include <fp_lib_table.h>
+#include <reporter.h>
+#include <html_messagebox.h>
+
+#include <cvpcb.h>
+#include <cvpcb_mainframe.h>
+#include <cvstruct.h>
+#include <wildcards_and_files_ext.h>
+#include <fp_conflict_assignment_selector.h>
+
+
+void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
+{
+ COMPONENT* component;
+ int componentIndex;
+
+ if( m_netlist.IsEmpty() )
+ return;
+
+ // If no component is selected, select the first one
+ if( m_compListBox->GetFirstSelected() < 0 )
+ {
+ componentIndex = 0;
+ m_compListBox->SetSelection( componentIndex, true );
+ }
+
+ // iterate over the selection
+ while( m_compListBox->GetFirstSelected() != -1 )
+ {
+ // Get the component for the current iteration
+ componentIndex = m_compListBox->GetFirstSelected();
+ component = m_netlist.GetComponent( componentIndex );
+
+ if( component == NULL )
+ return;
+
+ SetNewPkg( aFootprintName, componentIndex );
+
+ m_compListBox->SetSelection( componentIndex, false );
+ }
+
+ // Mark this "session" as modified
+ m_modified = true;
+
+ // select the next component, if there is one
+ if( componentIndex < (m_compListBox->GetCount() - 1) )
+ componentIndex++;
+
+ m_compListBox->SetSelection( componentIndex, true );
+
+ // update the statusbar
+ DisplayStatus();
+}
+
+
+void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName, int aIndex )
+{
+ COMPONENT* component;
+
+ if( m_netlist.IsEmpty() )
+ return;
+
+ component = m_netlist.GetComponent( aIndex );
+
+ if( component == NULL )
+ return;
+
+ // Check to see if the component has already a footprint set.
+ bool hasFootprint = !component->GetFPID().empty();
+
+ FPID fpid;
+
+ if( !aFootprintName.IsEmpty() )
+ {
+ wxCHECK_RET( fpid.Parse( aFootprintName ) < 0,
+ wxString::Format( wxT( "<%s> is not a valid FPID." ),
+ GetChars( aFootprintName ) ) );
+ }
+
+ component->SetFPID( fpid );
+
+ // create the new component description
+ wxString description = wxString::Format( CMP_FORMAT, aIndex + 1,
+ GetChars( component->GetReference() ),
+ GetChars( component->GetValue() ),
+ GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
+
+ // If the component hasn't had a footprint associated with it
+ // it now has, so we decrement the count of components without
+ // a footprint assigned.
+ if( !hasFootprint )
+ m_undefinedComponentCnt -= 1;
+
+ // Set the new description and deselect the processed component
+ m_compListBox->SetString( aIndex, description );
+
+ // Mark this "session" as modified
+ m_modified = true;
+
+ // update the statusbar
+ DisplayStatus();
+}
+
+
+/// Return true if the resultant FPID has a certain nickname. The guess
+/// is only made if this footprint resides in only one library.
+/// @return int - 0 on success, 1 on not found, 2 on ambiguous i.e. multiple matches
+static int guessNickname( FP_LIB_TABLE* aTbl, FPID* aFootprintId )
+{
+ if( aFootprintId->GetLibNickname().size() )
+ return 0;
+
+ wxString nick;
+ wxString fpname = aFootprintId->GetFootprintName();
+
+ std::vector<wxString> nicks = aTbl->GetLogicalLibs();
+
+ // Search each library going through libraries alphabetically.
+ for( unsigned libNdx = 0; libNdx<nicks.size(); ++libNdx )
+ {
+ wxArrayString fpnames = aTbl->FootprintEnumerate( nicks[libNdx] );
+
+ for( unsigned nameNdx = 0; nameNdx<fpnames.size(); ++nameNdx )
+ {
+ if( fpname == fpnames[nameNdx] )
+ {
+ if( !nick )
+ nick = nicks[libNdx];
+ else
+ return 2; // duplicate, the guess would not be certain
+ }
+ }
+ }
+
+ if( nick.size() )
+ {
+ aFootprintId->SetLibNickname( nick );
+ return 0;
+ }
+
+ return 1;
+}
+
+
+bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles( const std::string& aNetlist )
+{
+ wxString msg;
+ bool hasMissingNicks = false;
+
+ ReadSchematicNetlist( aNetlist );
+
+ if( m_compListBox == NULL )
+ return false;
+
+ LoadProjectFile();
+ LoadFootprintFiles();
+
+ BuildFOOTPRINTS_LISTBOX();
+ BuildLIBRARY_LISTBOX();
+
+ m_compListBox->Clear();
+ m_undefinedComponentCnt = 0;
+
+ if( m_netlist.AnyFootprintsLinked() )
+ {
+ for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
+ {
+ COMPONENT* component = m_netlist.GetComponent( i );
+
+ if( component->GetFPID().empty() )
+ continue;
+
+ if( component->GetFPID().IsLegacy() )
+ hasMissingNicks = true;
+ }
+ }
+
+ // Check if footprint links were generated before the footprint library table was implemented.
+ if( hasMissingNicks )
+ {
+ msg = _(
+ "Some of the assigned footprints are legacy entries (are missing lib nicknames). "
+ "Would you like CvPcb to attempt to convert them to the new required FPID format? "
+ "(If you answer no, then these assignments will be cleared out and you will "
+ "have to re-assign these footprints yourself.)"
+ );
+
+ if( IsOK( this, msg ) )
+ {
+ msg.Clear();
+
+ try
+ {
+ for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
+ {
+ COMPONENT* component = m_netlist.GetComponent( i );
+
+ if( component->GetFPID().IsLegacy() )
+ {
+ // get this first here, it's possibly obsoleted if we get it too soon.
+ FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
+
+ int guess = guessNickname( tbl, (FPID*) &component->GetFPID() );
+
+ switch( guess )
+ {
+ case 0:
+ DBG(printf("%s: guessed OK ref:%s fpid:%s\n", __func__,
+ TO_UTF8( component->GetReference() ), component->GetFPID().Format().c_str() );)
+ m_modified = true;
+ break;
+
+ case 1:
+ msg += wxString::Format( _(
+ "Component '%s' footprint '%s' was <b>not found</b> in any library.\n" ),
+ GetChars( component->GetReference() ),
+ GetChars( component->GetFPID().GetFootprintName() )
+ );
+ break;
+
+ case 2:
+ msg += wxString::Format( _(
+ "Component '%s' footprint '%s' was found in <b>multiple</b> libraries.\n" ),
+ GetChars( component->GetReference() ),
+ GetChars( component->GetFPID().GetFootprintName() )
+ );
+ break;
+ }
+ }
+ }
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = ioe.errorText;
+ msg += wxT( "\n\n" );
+ msg += _( "First check your footprint library table entries." );
+
+ wxMessageBox( msg, _( "Problematic Footprint Library Tables" ) );
+ return false;
+ }
+
+ if( msg.size() )
+ {
+ HTML_MESSAGE_BOX dlg( this, wxEmptyString );
+
+ dlg.MessageSet( _( "The following errors occurred attempting to convert the "
+ "footprint assignments:\n\n" ) );
+ dlg.ListSet( msg );
+ dlg.MessageSet( _( "\nYou will need to reassign them manually if you want them "
+ "to be updated correctly the next time you import the "
+ "netlist in Pcbnew." ) );
+
+#if 1
+ dlg.ShowModal();
+#else
+ dlg.Fit();
+ dlg.Show( true ); // modeless lets user watch while fixing the problems, but its not working.
+#endif
+ }
+ }
+ else
+ {
+ // Clear the legacy footprint assignments.
+ for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
+ {
+ COMPONENT* component = m_netlist.GetComponent( i );
+
+ if( component->GetFPID().IsLegacy() )
+ {
+ component->SetFPID( FPID() /* empty */ );
+ m_modified = true;
+ }
+ }
+ }
+ }
+
+
+ // Display a dialog to select footprint selection, if the netlist
+ // and the .cmp file give 2 different valid footprints
+ std::vector <int > m_indexes; // indexes of footprints in netlist
+
+ for( unsigned ii = 0; ii < m_netlist.GetCount(); ii++ )
+ {
+ COMPONENT* component = m_netlist.GetComponent( ii );
+
+ if( component->GetAltFPID().empty() )
+ continue;
+
+ if( component->GetFPID().IsLegacy() || component->GetAltFPID().IsLegacy())
+ continue;
+
+ m_indexes.push_back( ii );
+ }
+
+ // If a n assignment conflict is found,
+ // open a dialog to chose between schematic assignment
+ // and .cmp file assignment:
+ if( m_indexes.size() > 0 )
+ {
+ DIALOG_FP_CONFLICT_ASSIGNMENT_SELECTOR dlg( this );
+
+ for( unsigned ii = 0; ii < m_indexes.size(); ii++ )
+ {
+ COMPONENT* component = m_netlist.GetComponent( m_indexes[ii] );
+
+ wxString cmpfpid = component->GetFPID().Format();
+ wxString schfpid = component->GetAltFPID().Format();
+
+ dlg.Add( component->GetReference(), schfpid, cmpfpid );
+ }
+
+ if( dlg.ShowModal() == wxID_OK )
+ {
+
+ // Update the fp selection:
+ for( unsigned ii = 0; ii < m_indexes.size(); ii++ )
+ {
+ COMPONENT* component = m_netlist.GetComponent( m_indexes[ii] );
+
+ int choice = dlg.GetSelection( component->GetReference() );
+
+ if( choice == 0 ) // the schematic (alt fpid) is chosen:
+ component->SetFPID( component->GetAltFPID() );
+ }
+ }
+ }
+
+ // Populates the component list box:
+ for( unsigned i = 0; i < m_netlist.GetCount(); i++ )
+ {
+ COMPONENT* component = m_netlist.GetComponent( i );
+
+ msg.Printf( CMP_FORMAT, m_compListBox->GetCount() + 1,
+ GetChars( component->GetReference() ),
+ GetChars( component->GetValue() ),
+ GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
+
+ m_compListBox->AppendLine( msg );
+
+ if( component->GetFPID().empty() )
+ {
+ m_undefinedComponentCnt += 1;
+ continue;
+ }
+ }
+
+ if( !m_netlist.IsEmpty() )
+ m_compListBox->SetSelection( 0, true );
+
+ DisplayStatus();
+
+ UpdateTitle();
+ return true;
+}
+
+
+void CVPCB_MAINFRAME::SaveEdits()
+{
+ STRING_FORMATTER sf;
+
+ m_netlist.FormatBackAnnotation( &sf );
+
+ Kiway().ExpressMail( FRAME_SCH, MAIL_BACKANNOTATE_FOOTPRINTS, sf.GetString() );
+
+ SetStatusText( _("Edits sent to Eeschema") );
+}
diff --git a/cvpcb/tool_cvpcb.cpp b/cvpcb/tool_cvpcb.cpp
new file mode 100644
index 0000000..222059f
--- /dev/null
+++ b/cvpcb/tool_cvpcb.cpp
@@ -0,0 +1,115 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2011-2016 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2007-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file tool_cvpcb.cpp
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <common.h>
+
+#include <bitmaps.h>
+#include <cvpcb.h>
+#include <cvpcb_mainframe.h>
+#include <cvpcb_id.h>
+
+#include <common_help_msg.h>
+
+
+void CVPCB_MAINFRAME::ReCreateHToolbar()
+{
+ wxConfigBase* config = Kiface().KifaceSettings();
+
+ if( m_mainToolBar != NULL )
+ return;
+
+ m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
+
+ m_mainToolBar->AddTool( wxID_SAVE, wxEmptyString, KiBitmap( save_xpm ), SAVE_HLP_MSG );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_CVPCB_LIB_TABLE_EDIT, wxEmptyString,
+ KiBitmap( config_xpm ),
+ _( "Edit footprint library table" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_CVPCB_CREATE_SCREENCMP, wxEmptyString,
+ KiBitmap( show_footprint_xpm ),
+ _( "View selected footprint" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_CVPCB_GOTO_PREVIOUSNA, wxEmptyString,
+ KiBitmap( left_xpm ),
+ _( "Select previous unlinked component" ) );
+
+ m_mainToolBar->AddTool( ID_CVPCB_GOTO_FIRSTNA, wxEmptyString,
+ KiBitmap( right_xpm ),
+ _( "Select next unlinked component" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_CVPCB_AUTO_ASSOCIE, wxEmptyString,
+ KiBitmap( auto_associe_xpm ),
+ _( "Perform automatic footprint association" ) );
+
+ m_mainToolBar->AddTool( ID_CVPCB_DEL_ASSOCIATIONS, wxEmptyString,
+ KiBitmap( delete_association_xpm ),
+ _( "Delete all associations (links)" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST,
+ KiBitmap( module_filtered_list_xpm ),
+ wxNullBitmap,
+ true, NULL,
+ _( "Filter footprint list by keywords" ),
+ wxEmptyString );
+
+ m_mainToolBar->AddTool( ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST,
+ KiBitmap( module_pin_filtered_list_xpm ),
+ wxNullBitmap,
+ true, NULL,
+ _( "Filter footprint list by pin count" ),
+ wxEmptyString );
+
+ m_mainToolBar->AddTool( ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST,
+ KiBitmap( module_library_list_xpm ),
+ wxNullBitmap, true, NULL,
+ _( "Filter footprint list by library" ),
+ wxEmptyString );
+
+ if( config )
+ {
+ wxString key = wxT( FILTERFOOTPRINTKEY );
+ int opt = config->Read( key, (long) 1 );
+
+ m_mainToolBar->ToggleTool( ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST, opt & 4 );
+ m_mainToolBar->ToggleTool( ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST, opt & 2 );
+ m_mainToolBar->ToggleTool( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST, opt & 1 );
+ }
+
+ // after adding the buttons to the toolbar, must call Realize() to reflect the changes
+ m_mainToolBar->Realize();
+}
diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt
new file mode 100644
index 0000000..eb06147
--- /dev/null
+++ b/eeschema/CMakeLists.txt
@@ -0,0 +1,383 @@
+# the map generation creates on Windows/gcc a lot of useless warnings
+# so disable it on windows
+if( WIN32 AND NOT CMAKE_CROSSCOMPILING )
+ set( MAKE_LINK_MAPS false )
+else()
+ set( MAKE_LINK_MAPS true )
+endif()
+
+add_definitions( -DEESCHEMA )
+
+
+include_directories( BEFORE ${INC_BEFORE} )
+include_directories(
+ ./dialogs
+ ./netlist_exporters
+ ../common
+ ../common/dialogs
+ ${INC_AFTER}
+ )
+
+
+set( EESCHEMA_DLGS
+ dialogs/dialog_annotate.cpp
+ dialogs/dialog_annotate_base.cpp
+ dialogs/dialog_bom.cpp
+ dialogs/dialog_bom_base.cpp
+ dialogs/dialog_bom_cfg_keywords.cpp
+ dialogs/dialog_color_config.cpp
+ dialogs/dialog_color_config_base.cpp
+ dialogs/dialog_choose_component.cpp
+ dialogs/dialog_choose_component_base.cpp
+ dialogs/dialog_lib_edit_text.cpp
+ dialogs/dialog_lib_edit_text_base.cpp
+ dialogs/dialog_edit_component_in_lib.cpp
+ dialogs/dialog_edit_component_in_lib_base.cpp
+ dialogs/dialog_edit_component_in_schematic_fbp.cpp
+ dialogs/dialog_edit_component_in_schematic.cpp
+ dialogs/dialog_edit_label.cpp
+ dialogs/dialog_edit_label_base.cpp
+ dialogs/dialog_edit_libentry_fields_in_lib.cpp
+ dialogs/dialog_edit_libentry_fields_in_lib_base.cpp
+ dialogs/dialog_edit_one_field.cpp
+ dialogs/dialog_eeschema_config.cpp
+ dialogs/dialog_eeschema_config_fbp.cpp
+ dialogs/dialog_eeschema_options_base.cpp
+ dialogs/dialog_eeschema_options.cpp
+ dialogs/dialog_erc.cpp
+ dialogs/dialog_erc_base.cpp
+ dialogs/dialog_lib_edit_draw_item.cpp
+ dialogs/dialog_lib_edit_draw_item_base.cpp
+ dialogs/dialog_libedit_options_base.cpp
+ dialogs/dialog_libedit_options.cpp
+ dialogs/dialog_lib_edit_pin.cpp
+ dialogs/dialog_lib_edit_pin_base.cpp
+ dialogs/dialog_lib_edit_pin_table.cpp
+ dialogs/dialog_lib_edit_pin_table_base.cpp
+ dialogs/dialog_lib_new_component.cpp
+ dialogs/dialog_lib_new_component_base.cpp
+ dialogs/dialog_netlist.cpp
+ dialogs/dialog_netlist_base.cpp
+ dialogs/dialog_plot_schematic_base.cpp
+ dialogs/dialog_plot_schematic.cpp
+ dialogs/dialog_print_using_printer_base.cpp
+ dialogs/dialog_print_using_printer.cpp
+ dialogs/dialog_rescue_each.cpp
+ dialogs/dialog_rescue_each_base.cpp
+ dialogs/dialog_sch_edit_sheet_pin.cpp
+ dialogs/dialog_sch_edit_sheet_pin_base.cpp
+ dialogs/dialog_sch_sheet_props.cpp
+ dialogs/dialog_sch_sheet_props_base.cpp
+ dialogs/dialog_schematic_find.cpp
+ dialogs/dialog_schematic_find_base.cpp
+ )
+
+set( EESCHEMA_SRCS
+ annotate.cpp
+ backanno.cpp
+ block.cpp
+ block_libedit.cpp
+ busentry.cpp
+ bus-wire-junction.cpp
+ class_drc_erc_item.cpp
+ class_libentry.cpp
+ class_library.cpp
+ class_netlist_object.cpp
+ cmp_library_keywords.cpp
+ cmp_library_lexer.cpp
+ component_references_lister.cpp
+ controle.cpp
+ cross-probing.cpp
+ ${EESCHEMA_DLGS}
+ edit_component_in_schematic.cpp
+ edit_bitmap.cpp
+ edit_label.cpp
+ eeredraw.cpp
+ eeschema.cpp
+ eeschema_config.cpp
+ erc.cpp
+ events_called_functions_for_edit.cpp
+ files-io.cpp
+ find.cpp
+ getpart.cpp
+ component_tree_search_container.cpp
+ hierarch.cpp
+ hotkeys.cpp
+ libarch.cpp
+ libedit.cpp
+ libeditframe.cpp
+ libedit_onleftclick.cpp
+ libedit_onrightclick.cpp
+ libedit_plot_component.cpp
+ libedit_undo_redo.cpp
+ lib_arc.cpp
+ lib_bezier.cpp
+ lib_circle.cpp
+ lib_collectors.cpp
+ lib_draw_item.cpp
+ lib_export.cpp
+ lib_field.cpp
+ lib_pin.cpp
+ lib_polyline.cpp
+ lib_rectangle.cpp
+ lib_text.cpp
+ libfield.cpp
+ load_one_schematic_file.cpp
+ menubar.cpp
+ menubar_libedit.cpp
+ netform.cpp
+ netlist.cpp
+ onleftclick.cpp
+ onrightclick.cpp
+ operations_on_items_lists.cpp
+ pinedit.cpp
+ plot_schematic_DXF.cpp
+ plot_schematic_HPGL.cpp
+ plot_schematic_PS.cpp
+ plot_schematic_PDF.cpp
+ plot_schematic_SVG.cpp
+ project_rescue.cpp
+ sch_base_frame.cpp
+ sch_bitmap.cpp
+ sch_bus_entry.cpp
+ sch_collectors.cpp
+ sch_component.cpp
+ sch_field.cpp
+ sch_item_struct.cpp
+ sch_junction.cpp
+ sch_line.cpp
+ sch_marker.cpp
+ sch_no_connect.cpp
+ sch_screen.cpp
+ sch_sheet.cpp
+ sch_sheet_path.cpp
+ sch_sheet_pin.cpp
+ sch_text.cpp
+ sch_validators.cpp
+ schedit.cpp
+ schematic_undo_redo.cpp
+ schframe.cpp
+ selpart.cpp
+ sheet.cpp
+ sheetlab.cpp
+ symbdraw.cpp
+ symbedit.cpp
+ template_fieldnames_keywords.cpp
+ template_fieldnames.cpp
+ tool_lib.cpp
+ tool_sch.cpp
+ tool_viewlib.cpp
+ transform.cpp
+ viewlib_frame.cpp
+ viewlibs.cpp
+
+ netlist_exporters/netlist_exporter.cpp
+ netlist_exporters/netlist_exporter_cadstar.cpp
+ netlist_exporters/netlist_exporter_generic.cpp
+ netlist_exporters/netlist_exporter_kicad.cpp
+ netlist_exporters/netlist_exporter_orcadpcb2.cpp
+ netlist_exporters/netlist_exporter_pspice.cpp
+ )
+
+
+set( EESCHEMA_COMMON_SRCS
+ ../common/dialogs/dialog_page_settings.cpp
+ ../common/base_screen.cpp
+ ../common/eda_text.cpp
+ ../common/class_page_info.cpp
+ ../common/base_units.cpp
+ )
+
+
+if( MINGW )
+ # EESCHEMA_RESOURCES variable is set by the macro.
+ mingw_resource_compiler( eeschema )
+else()
+ set( EESCHEMA_RESOURCES eeschema.rc )
+endif()
+
+# Create a C++ compilable string initializer containing html text into a *.h file:
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h
+ COMMAND ${CMAKE_COMMAND}
+ -DinputFile=${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help.html
+ -DoutputFile=${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h
+ -P ${CMAKE_MODULE_PATH}/Html2C.cmake
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help.html
+ COMMENT "creating ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h
+ from ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help.html"
+ )
+
+set_source_files_properties( dialogs/dialog_bom.cpp
+ PROPERTIES
+ OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h
+ )
+
+if( APPLE )
+ # setup bundle
+ set( EESCHEMA_RESOURCES eeschema.icns eeschema_doc.icns )
+ set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/eeschema.icns" PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+ set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/eeschema_doc.icns" PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+ set( MACOSX_BUNDLE_ICON_FILE eeschema.icns )
+ set( MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-pcb.kicad )
+ set( MACOSX_BUNDLE_NAME eeschema )
+endif()
+
+
+add_executable( eeschema WIN32 MACOSX_BUNDLE
+ ../common/single_top.cpp
+ ../common/pgm_base.cpp
+ ${EESCHEMA_RESOURCES}
+ )
+set_source_files_properties( ../common/single_top.cpp PROPERTIES
+ COMPILE_DEFINITIONS "TOP_FRAME=FRAME_SCH;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL"
+ )
+target_link_libraries( eeschema
+ #singletop # replaces common, giving us restrictive control and link warnings.
+ # There's way too much crap coming in from common yet.
+ common
+ bitmaps
+ ${wxWidgets_LIBRARIES}
+ )
+
+# the DSO (KIFACE) housing the main eeschema code:
+add_library( eeschema_kiface MODULE
+ ${EESCHEMA_SRCS}
+ ${EESCHEMA_COMMON_SRCS}
+ )
+target_link_libraries( eeschema_kiface
+ common
+ bitmaps
+ polygon
+ gal
+ ${wxWidgets_LIBRARIES}
+ ${GDI_PLUS_LIBRARIES}
+ )
+set_target_properties( eeschema_kiface PROPERTIES
+ # Decorate OUTPUT_NAME with PREFIX and SUFFIX, creating something like
+ # _eeschema.so, _eeschema.dll, or _eeschema.kiface
+ OUTPUT_NAME eeschema
+ PREFIX ${KIFACE_PREFIX}
+ SUFFIX ${KIFACE_SUFFIX}
+ )
+
+# The KIFACE is in eeschema.cpp, export it:
+set_source_files_properties( eeschema.cpp PROPERTIES
+ COMPILE_DEFINITIONS "BUILD_KIWAY_DLL;COMPILING_DLL"
+ )
+
+# if building eeschema, then also build eeschema_kiface if out of date.
+add_dependencies( eeschema eeschema_kiface )
+
+if( MAKE_LINK_MAPS )
+ # generate link map with cross reference
+ set_target_properties( eeschema_kiface PROPERTIES
+ LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=${KIFACE_PREFIX}eeschema${KIFACE_SUFFIX}.map"
+ )
+ set_target_properties( eeschema PROPERTIES
+ LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=eeschema.map"
+ )
+endif()
+
+# these 2 binaries are a matched set, keep them together:
+if( APPLE )
+ set_target_properties( eeschema PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
+ )
+
+ # puts binaries into the *.app bundle while linking
+ set_target_properties( eeschema_kiface PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_KIFACE_DIR}
+ )
+ # put individual bundle outside of main bundle as a first step
+ # will be pulled into the main bundle when creating main bundle
+ install( TARGETS eeschema
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+ install( CODE "
+ # override default embedded path settings
+ ${OSX_BUNDLE_OVERRIDE_PATHS}
+
+ # do all the work
+ include( BundleUtilities )
+ fixup_bundle( ${KICAD_BIN}/eeschema.app/Contents/MacOS/eeschema
+ \"\"
+ \"\"
+ )
+ " COMPONENT Runtime
+ )
+else()
+ install( TARGETS eeschema
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+ install( TARGETS eeschema_kiface
+ # actual filename subject to change at milestone C)
+ # modular-kicad blueprint.
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+endif()
+
+# auto-generate cmp_library_lexer.h and cmp_library_keywords.cpp for the component
+# library format.
+make_lexer(
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library.keywords
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library_lexer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library_keywords.cpp
+ TLIB_T
+ )
+
+add_custom_target(
+ cmp_library_lexer_source_files ALL
+ DEPENDS
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library_lexer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library_keywords.cpp
+ )
+
+add_dependencies( eeschema_kiface cmp_library_lexer_source_files )
+
+make_lexer(
+ ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames.keywords
+ ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames_lexer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames_keywords.cpp
+ TFIELD_T
+
+ # Pass header file with dependency on *_lexer.h as extra_arg
+ template_fieldnames.h
+ )
+
+add_custom_target(
+ field_template_lexer_source_files ALL
+ DEPENDS
+ ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames_lexer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames_keywords.cpp
+ )
+
+add_dependencies( eeschema_kiface field_template_lexer_source_files )
+
+make_lexer(
+ ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg.keywords
+ ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_lexer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_keywords.cpp
+ T_BOMCFG_T
+
+ # Pass header file with dependency on *_lexer.h as extra_arg
+ dialogs/dialog_bom_cfg.h
+ )
+
+add_custom_target(
+ dialog_bom_cfg_lexer_source_files ALL
+ DEPENDS
+ ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_lexer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_keywords.cpp
+ )
+
+add_dependencies( eeschema_kiface dialog_bom_cfg_lexer_source_files )
+
+add_subdirectory( plugins )
diff --git a/eeschema/Info.plist b/eeschema/Info.plist
new file mode 100644
index 0000000..7d8663d
--- /dev/null
+++ b/eeschema/Info.plist
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeRole</key> <string>Editor</string>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>sch</string>
+ </array>
+ <key>CFBundleTypeIconFile</key> <string>eeschema_doc.icns</string>
+ <key>CFBundleTypeName</key> <string>eeschema document</string>
+ <key>LSHandlerRank</key> <string>Owner</string>
+ </dict>
+ </array>
+ <key>CFBundleDevelopmentRegion</key> <string>English</string>
+ <key>CFBundleExecutable</key> <string>eeschema</string>
+ <key>CFBundleGetInfoString</key> <string></string>
+ <key>CFBundleIconFile</key> <string>eeschema.icns</string>
+ <key>CFBundleIdentifier</key> <string>org.kicad-pcb.eeschema</string>
+ <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string>
+ <key>CFBundleLongVersionString</key> <string></string>
+ <key>CFBundleName</key> <string>EESchema</string>
+ <key>CFBundlePackageType</key> <string>APPL</string>
+ <key>CFBundleShortVersionString</key> <string></string>
+ <key>CFBundleSignature</key> <string>????</string>
+ <key>CFBundleVersion</key> <string></string>
+ <key>CSResourcesFileMapped</key> <true/>
+ <key>LSRequiresCarbon</key> <true/>
+ <key>NSHumanReadableCopyright</key> <string></string>
+ <key>NSHighResolutionCapable</key> <string>True</string>
+</dict>
+</plist>
diff --git a/eeschema/annotate.cpp b/eeschema/annotate.cpp
new file mode 100644
index 0000000..1b2a27d
--- /dev/null
+++ b/eeschema/annotate.cpp
@@ -0,0 +1,200 @@
+/**
+ * @file annotate.cpp
+ * @brief Component annotation.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <algorithm>
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <schframe.h>
+
+#include <sch_reference_list.h>
+#include <class_library.h>
+
+void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly )
+{
+ if( aCurrentSheetOnly )
+ {
+ SCH_SCREEN* screen = GetScreen();
+ wxCHECK_RET( screen != NULL, wxT( "Attempt to clear annotation of a NULL screen." ) );
+ screen->ClearAnnotation( m_CurrentSheet );
+ }
+ else
+ {
+ SCH_SCREENS ScreenList;
+ ScreenList.ClearAnnotation();
+ }
+
+ // Update the references for the sheet that is currently being displayed.
+ m_CurrentSheet->UpdateAllScreenReferences();
+ GetCanvas()->Refresh();
+ OnModify();
+}
+
+
+void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
+ ANNOTATE_ORDER_T aSortOption,
+ ANNOTATE_OPTION_T aAlgoOption,
+ bool aResetAnnotation,
+ bool aRepairTimestamps,
+ bool aLockUnits )
+{
+ SCH_REFERENCE_LIST references;
+
+ SCH_SCREENS screens;
+
+ // Build the sheet list.
+ SCH_SHEET_LIST sheets;
+
+ // Map of locked components
+ SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents;
+
+ // Test for and replace duplicate time stamps in components and sheets. Duplicate
+ // time stamps can happen with old schematics, schematic conversions, or manual
+ // editing of files.
+ if( aRepairTimestamps )
+ {
+ int count = screens.ReplaceDuplicateTimeStamps();
+
+ if( count )
+ {
+ wxString msg;
+ msg.Printf( _( "%d duplicate time stamps were found and replaced." ), count );
+ DisplayInfoMessage( NULL, msg, 2 );
+ }
+ }
+
+ // If units must be locked, collect all the sets that must be annotated together.
+ if( aLockUnits )
+ {
+ if( aAnnotateSchematic )
+ {
+ sheets.GetMultiUnitComponents( Prj().SchLibs(), lockedComponents );
+ }
+ else
+ {
+ m_CurrentSheet->GetMultiUnitComponents( Prj().SchLibs(), lockedComponents );
+ }
+ }
+
+ // If it is an annotation for all the components, reset previous annotation.
+ if( aResetAnnotation )
+ DeleteAnnotation( !aAnnotateSchematic );
+
+ // Set sheet number and number of sheets.
+ SetSheetNumberAndCount();
+
+ // Build component list
+ if( aAnnotateSchematic )
+ {
+ sheets.GetComponents( Prj().SchLibs(), references );
+ }
+ else
+ {
+ m_CurrentSheet->GetComponents( Prj().SchLibs(), references );
+ }
+
+ // Break full components reference in name (prefix) and number:
+ // example: IC1 become IC, and 1
+ references.SplitReferences();
+
+ switch( aSortOption )
+ {
+ default:
+ case SORT_BY_X_POSITION:
+ references.SortByXCoordinate();
+ break;
+
+ case SORT_BY_Y_POSITION:
+ references.SortByYCoordinate();
+ break;
+ }
+
+ bool useSheetNum = false;
+ int idStep = 100;
+
+ switch( aAlgoOption )
+ {
+ default:
+ case INCREMENTAL_BY_REF:
+ break;
+
+ case SHEET_NUMBER_X_100:
+ useSheetNum = true;
+ break;
+
+ case SHEET_NUMBER_X_1000:
+ useSheetNum = true;
+ idStep = 1000;
+ break;
+ }
+
+ // Recalculate and update reference numbers in schematic
+ references.Annotate( useSheetNum, idStep, lockedComponents );
+ references.UpdateAnnotation();
+
+ wxArrayString errors;
+
+ // Final control (just in case ... ).
+ if( CheckAnnotate( &errors, !aAnnotateSchematic ) )
+ {
+ wxString msg;
+
+ for( size_t i = 0; i < errors.GetCount(); i++ )
+ msg += errors[i];
+
+ // wxLogWarning is a cheap and dirty way to dump a potentially long list of
+ // strings to a dialog that can be saved to a file. This should be replaced
+ // by a more elegant solution.
+ wxLogWarning( msg );
+ }
+
+ OnModify();
+
+ // Update on screen references, that can be modified by previous calculations:
+ m_CurrentSheet->UpdateAllScreenReferences();
+ SetSheetNumberAndCount();
+
+ m_canvas->Refresh( true );
+}
+
+
+int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOnly )
+{
+ // build the screen list
+ SCH_SHEET_LIST SheetList;
+ SCH_REFERENCE_LIST ComponentsList;
+
+ // Build the list of components
+ if( !aOneSheetOnly )
+ SheetList.GetComponents( Prj().SchLibs(), ComponentsList );
+ else
+ m_CurrentSheet->GetComponents( Prj().SchLibs(), ComponentsList );
+
+ return ComponentsList.CheckAnnotation( aMessageList );
+}
diff --git a/eeschema/backanno.cpp b/eeschema/backanno.cpp
new file mode 100644
index 0000000..671f727
--- /dev/null
+++ b/eeschema/backanno.cpp
@@ -0,0 +1,264 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file backanno.cpp
+ * @brief Functions for backannotating footprint information.
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <kiface_i.h>
+#include <schframe.h>
+#include <build_version.h>
+#include <wildcards_and_files_ext.h>
+
+#include <general.h>
+#include <sch_sheet_path.h>
+#include <sch_component.h>
+#include <sch_reference_list.h>
+
+#include <dsnlexer.h>
+#include <ptree.h>
+#include <boost/property_tree/ptree.hpp>
+#include <wx/choicdlg.h>
+
+
+void SCH_EDIT_FRAME::backAnnotateFootprints( const std::string& aChangedSetOfReferences )
+ throw( IO_ERROR, boost::bad_pointer )
+{
+ // Build a flat list of components in schematic:
+ SCH_REFERENCE_LIST refs;
+ SCH_SHEET_LIST sheets;
+ bool isChanged = false;
+
+ sheets.GetComponents( Prj().SchLibs(), refs, false );
+
+ DSNLEXER lexer( aChangedSetOfReferences, FROM_UTF8( __func__ ) );
+ PTREE doc;
+
+ try
+ {
+ Scan( &doc, &lexer );
+
+#if defined(DEBUG) && 0
+ STRING_FORMATTER sf;
+ Format( &sf, 0, 0, doc );
+ printf( "%s: '%s'\n", __func__, sf.GetString().c_str() );
+#endif
+
+ CPTREE& back_anno = doc.get_child( "back_annotation" );
+ wxString footprint;
+
+ for( PTREE::const_iterator ref = back_anno.begin(); ref != back_anno.end(); ++ref )
+ {
+ wxASSERT( ref->first == "ref" );
+
+ wxString reference = (UTF8&) ref->second.front().first;
+
+ // Ensure the "fpid" node contains a footprint name,
+ // and get it if exists
+ if( ref->second.get_child( "fpid" ).size() )
+ {
+ wxString tmp = (UTF8&) ref->second.get_child( "fpid" ).front().first;
+ footprint = tmp;
+ }
+ else
+ footprint.Empty();
+
+ // DBG( printf( "%s: ref:%s fpid:%s\n", __func__, TO_UTF8( reference ), TO_UTF8( footprint ) ); )
+
+ // Search the component in the flat list
+ for( unsigned ii = 0; ii < refs.GetCount(); ++ii )
+ {
+ if( Cmp_KEEPCASE( reference, refs[ii].GetRef() ) == 0 )
+ {
+ // We have found a candidate.
+ // Note: it can be not unique (multiple parts per package)
+ // So we *do not* stop the search here
+ SCH_COMPONENT* component = refs[ii].GetComp();
+ SCH_FIELD* fpfield = component->GetField( FOOTPRINT );
+ const wxString& oldfp = fpfield->GetText();
+
+ if( !oldfp && fpfield->IsVisible() )
+ {
+ fpfield->SetVisible( false );
+ }
+
+ // DBG( printf("%s: ref:%s fpid:%s\n", __func__, TO_UTF8( refs[ii].GetRef() ), TO_UTF8( footprint ) );)
+ if( oldfp != footprint )
+ isChanged = true;
+
+ fpfield->SetText( footprint );
+ }
+ }
+ }
+ }
+ catch( const PTREE_ERROR& ex )
+ {
+ // remap the exception to something the caller is likely to understand.
+ THROW_IO_ERROR( ex.what() );
+ }
+
+ if( isChanged )
+ OnModify();
+}
+
+
+bool SCH_EDIT_FRAME::ProcessCmpToFootprintLinkFile( const wxString& aFullFilename,
+ bool aForceVisibilityState,
+ bool aVisibilityState )
+{
+ // Build a flat list of components in schematic:
+ SCH_REFERENCE_LIST referencesList;
+ SCH_SHEET_LIST sheetList;
+
+ sheetList.GetComponents( Prj().SchLibs(), referencesList, false );
+
+ FILE* cmpFile = wxFopen( aFullFilename, wxT( "rt" ) );
+
+ if( cmpFile == NULL )
+ return false;
+
+ // cmpFileReader dtor will close cmpFile
+ FILE_LINE_READER cmpFileReader( cmpFile, aFullFilename );
+
+ // Now, for each component found in file,
+ // replace footprint field value by the new value:
+ wxString reference;
+ wxString footprint;
+ wxString buffer;
+ wxString value;
+
+ while( cmpFileReader.ReadLine() )
+ {
+ buffer = FROM_UTF8( cmpFileReader.Line() );
+
+ if( !buffer.StartsWith( wxT( "BeginCmp" ) ) )
+ continue;
+
+ // Begin component description.
+ reference.Empty();
+ footprint.Empty();
+
+ while( cmpFileReader.ReadLine() )
+ {
+ buffer = FROM_UTF8( cmpFileReader.Line() );
+
+ if( buffer.StartsWith( wxT( "EndCmp" ) ) )
+ break;
+
+ // store string value, stored between '=' and ';' delimiters.
+ value = buffer.AfterFirst( '=' );
+ value = value.BeforeLast( ';' );
+ value.Trim(true);
+ value.Trim(false);
+
+ if( buffer.StartsWith( wxT( "Reference" ) ) )
+ {
+ reference = value;
+ }
+ else if( buffer.StartsWith( wxT( "IdModule" ) ) )
+ {
+ footprint = value;
+ }
+ }
+
+ // A block is read: initialize the footprint field of the corresponding component
+ // if the footprint name is not empty
+ if( reference.IsEmpty() )
+ continue;
+
+ // Search the component in the flat list
+ for( unsigned ii = 0; ii < referencesList.GetCount(); ii++ )
+ {
+ if( Cmp_KEEPCASE( reference, referencesList[ii].GetRef() ) == 0 )
+ {
+ // We have found a candidate.
+ // Note: it can be not unique (multiple units per part)
+ // So we *do not* stop the search here
+ SCH_COMPONENT* component = referencesList[ii].GetComp();
+ SCH_FIELD* fpfield = component->GetField( FOOTPRINT );
+
+ fpfield->SetText( footprint );
+
+ if( aForceVisibilityState )
+ {
+ component->GetField( FOOTPRINT )->SetVisible( aVisibilityState );
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+
+bool SCH_EDIT_FRAME::LoadCmpToFootprintLinkFile()
+{
+ wxString path = wxPathOnly( Prj().GetProjectFullName() );
+
+ wxFileDialog dlg( this, _( "Load Component Footprint Link File" ),
+ path, wxEmptyString,
+ ComponentFileExtensionWildcard,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return false;
+
+ wxString filename = dlg.GetPath();
+ wxString title = wxT( "Eeschema " ) + GetBuildVersion() + wxT( ' ' ) + filename;
+
+ SetTitle( title );
+
+ wxArrayString choices;
+ choices.Add( _( "Keep existing footprint field visibility" ) );
+ choices.Add( _( "Show all footprint fields" ) );
+ choices.Add( _( "Hide all footprint fields" ) );
+
+ wxSingleChoiceDialog choiceDlg( this, _( "Select the footprint field visibility setting." ),
+ _( "Change Visibility" ), choices );
+
+
+ if( choiceDlg.ShowModal() == wxID_CANCEL )
+ return false;
+
+ bool forceVisibility = (choiceDlg.GetSelection() != 0 );
+ bool visibilityState = (choiceDlg.GetSelection() == 1 );
+
+ if( !ProcessCmpToFootprintLinkFile( filename, forceVisibility, visibilityState ) )
+ {
+ wxString msg = wxString::Format( _( "Failed to open component-footprint link file '%s'" ),
+ filename.GetData() );
+
+ DisplayError( this, msg );
+ return false;
+ }
+
+ OnModify();
+ return true;
+}
diff --git a/eeschema/block.cpp b/eeschema/block.cpp
new file mode 100644
index 0000000..e4b38e9
--- /dev/null
+++ b/eeschema/block.cpp
@@ -0,0 +1,538 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2009-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/block.cpp
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <schframe.h>
+
+#include <general.h>
+#include <class_library.h>
+#include <lib_pin.h>
+#include <protos.h>
+#include <sch_bus_entry.h>
+#include <sch_marker.h>
+#include <sch_junction.h>
+#include <sch_line.h>
+#include <sch_no_connect.h>
+#include <sch_text.h>
+#include <sch_component.h>
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+
+// Imported functions:
+extern void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen );
+extern void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint aMoveVector );
+extern void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& Center );
+extern void MirrorX( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint );
+extern void MirrorY( PICKED_ITEMS_LIST& aItemsList, wxPoint& Center );
+extern void DuplicateItemsInList( SCH_SCREEN* screen,
+ PICKED_ITEMS_LIST& aItemsList,
+ const wxPoint aMoveVector );
+
+static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase );
+
+
+int SCH_EDIT_FRAME::BlockCommand( int key )
+{
+ int cmd = BLOCK_IDLE;
+
+ switch( key )
+ {
+ default:
+ cmd = key & 0xFF;
+ break;
+
+ case 0:
+ cmd = BLOCK_MOVE;
+ break;
+
+ case GR_KB_SHIFT:
+ cmd = BLOCK_COPY;
+ break;
+
+ case GR_KB_ALT:
+ cmd = BLOCK_ROTATE;
+ break;
+
+ case GR_KB_CTRL:
+ cmd = BLOCK_DRAG;
+ break;
+
+ case GR_KB_SHIFTCTRL:
+ cmd = BLOCK_DELETE;
+ break;
+
+ case MOUSE_MIDDLE:
+ cmd = BLOCK_ZOOM;
+ break;
+ }
+
+ return cmd;
+}
+
+
+void SCH_EDIT_FRAME::InitBlockPasteInfos()
+{
+ BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate;
+
+ block->GetItems().CopyList( m_blockItems.GetItems() );
+ m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
+}
+
+
+void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
+{
+ BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate;
+
+ if( !m_canvas->IsMouseCaptured() )
+ {
+ DisplayError( this, wxT( "HandleBlockPLace() : m_mouseCaptureCallback = NULL" ) );
+ }
+
+ if( block->GetCount() == 0 )
+ {
+ wxString msg;
+ msg.Printf( wxT( "HandleBlockPLace() error : no items to place (cmd %d, state %d)" ),
+ block->GetCommand(), block->GetState() );
+ DisplayError( this, msg );
+ }
+
+ block->SetState( STATE_BLOCK_STOP );
+
+ switch( block->GetCommand() )
+ {
+ case BLOCK_DRAG: // Drag from mouse
+ case BLOCK_DRAG_ITEM: // Drag from a component selection and drag command
+ case BLOCK_MOVE:
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ SaveCopyInUndoList( block->GetItems(), UR_MOVED, block->GetMoveVector() );
+ MoveItemsInList( block->GetItems(), block->GetMoveVector() );
+ block->ClearItemsList();
+ break;
+
+ case BLOCK_COPY: /* Copy */
+ case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ DuplicateItemsInList( GetScreen(), block->GetItems(), block->GetMoveVector() );
+
+ SaveCopyInUndoList( block->GetItems(),
+ ( block->GetCommand() == BLOCK_PRESELECT_MOVE ) ? UR_CHANGED : UR_NEW );
+
+ block->ClearItemsList();
+ break;
+
+ case BLOCK_PASTE:
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ PasteListOfItems( DC );
+ block->ClearItemsList();
+ break;
+
+ default: // others are handled by HandleBlockEnd()
+ break;
+ }
+
+ OnModify();
+
+ // clear dome flags and pointers
+ GetScreen()->ClearDrawingState();
+ GetScreen()->ClearBlockCommand();
+ GetScreen()->SetCurItem( NULL );
+ GetScreen()->TestDanglingEnds( m_canvas, DC );
+
+ if( block->GetCount() )
+ {
+ DisplayError( this, wxT( "HandleBlockPLace() error: some items left in buffer" ) );
+ block->ClearItemsList();
+ }
+
+ m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false );
+ m_canvas->Refresh();
+}
+
+
+bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
+{
+ bool nextcmd = false;
+ bool zoom_command = false;
+ BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate;
+
+ if( block->GetCount() )
+ {
+ BLOCK_STATE_T state = block->GetState();
+ BLOCK_COMMAND_T command = block->GetCommand();
+
+ m_canvas->CallEndMouseCapture( aDC );
+
+ block->SetState( state );
+ block->SetCommand( command );
+ m_canvas->SetMouseCapture( DrawAndSizingBlockOutlines, AbortBlockCurrentCommand );
+ SetCrossHairPosition( block->GetEnd() );
+
+ if( block->GetCommand() != BLOCK_ABORT )
+ m_canvas->MoveCursorToCrossHair();
+ }
+
+ if( m_canvas->IsMouseCaptured() )
+ {
+ switch( block->GetCommand() )
+ {
+ case BLOCK_IDLE:
+ DisplayError( this, wxT( "Error in HandleBlockPLace()" ) );
+ break;
+
+ case BLOCK_ROTATE:
+ GetScreen()->UpdatePickList();
+ DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false );
+
+ if( block->GetCount() )
+ {
+ // Compute the rotation center and put it on grid:
+ wxPoint rotationPoint = block->Centre();
+ rotationPoint = GetNearestGridPosition( rotationPoint );
+ SetCrossHairPosition( rotationPoint );
+ SaveCopyInUndoList( block->GetItems(), UR_ROTATED, rotationPoint );
+ RotateListOfItems( block->GetItems(), rotationPoint );
+ OnModify();
+ }
+
+ block->ClearItemsList();
+ GetScreen()->TestDanglingEnds( m_canvas, aDC );
+ m_canvas->Refresh();
+ break;
+
+ case BLOCK_DRAG:
+ case BLOCK_DRAG_ITEM: // Drag from a drag command
+ GetScreen()->BreakSegmentsOnJunctions();
+ // fall through
+
+ case BLOCK_MOVE:
+ case BLOCK_COPY:
+ if( block->GetCommand() == BLOCK_DRAG_ITEM &&
+ GetScreen()->GetCurItem() != NULL )
+ {
+ // This is a drag command, not a mouse block command
+ // Only this item is put in list
+ ITEM_PICKER picker;
+ picker.SetItem( GetScreen()->GetCurItem() );
+ block->PushItem( picker );
+ }
+ else
+ {
+ // Collect all items in the locate block
+ GetScreen()->UpdatePickList();
+ }
+ // fall through
+
+ case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/
+ if( block->GetCount() )
+ {
+ nextcmd = true;
+ GetScreen()->SelectBlockItems();
+ m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
+ m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
+ m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
+ block->SetState( STATE_BLOCK_MOVE );
+ }
+ else
+ {
+ m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
+ m_canvas->SetMouseCapture( NULL, NULL );
+ }
+ break;
+
+ case BLOCK_DELETE:
+ GetScreen()->UpdatePickList();
+ DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false );
+
+ if( block->GetCount() )
+ {
+ DeleteItemsInList( m_canvas, block->GetItems() );
+ OnModify();
+ }
+ block->ClearItemsList();
+ GetScreen()->TestDanglingEnds( m_canvas, aDC );
+ m_canvas->Refresh();
+ break;
+
+ case BLOCK_SAVE: // Save a copy of items in paste buffer
+ GetScreen()->UpdatePickList();
+ DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false );
+
+ if( block->GetCount() )
+ {
+ wxPoint move_vector = -GetScreen()->m_BlockLocate.GetLastCursorPosition();
+ copyBlockItems( block->GetItems() );
+ MoveItemsInList( m_blockItems.GetItems(), move_vector );
+ }
+
+ block->ClearItemsList();
+ break;
+
+ case BLOCK_PASTE:
+ block->SetState( STATE_BLOCK_MOVE );
+ break;
+
+ case BLOCK_ZOOM:
+ zoom_command = true;
+ break;
+
+ case BLOCK_MIRROR_X:
+ GetScreen()->UpdatePickList();
+ DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false );
+
+ if( block->GetCount() )
+ {
+ // Compute the mirror center and put it on grid.
+ wxPoint mirrorPoint = block->Centre();
+ mirrorPoint = GetNearestGridPosition( mirrorPoint );
+ SetCrossHairPosition( mirrorPoint );
+ SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_X, mirrorPoint );
+ MirrorX( block->GetItems(), mirrorPoint );
+ OnModify();
+ }
+
+ GetScreen()->TestDanglingEnds( m_canvas, aDC );
+ m_canvas->Refresh();
+ break;
+
+ case BLOCK_MIRROR_Y:
+ GetScreen()->UpdatePickList();
+ DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false );
+
+ if( block->GetCount() )
+ {
+ // Compute the mirror center and put it on grid.
+ wxPoint mirrorPoint = block->Centre();
+ mirrorPoint = GetNearestGridPosition( mirrorPoint );
+ SetCrossHairPosition( mirrorPoint );
+ SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_Y, mirrorPoint );
+ MirrorY( block->GetItems(), mirrorPoint );
+ OnModify();
+ }
+
+ GetScreen()->TestDanglingEnds( m_canvas, aDC );
+ m_canvas->Refresh();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( block->GetCommand() == BLOCK_ABORT )
+ {
+ GetScreen()->ClearDrawingState();
+ m_canvas->Refresh();
+ }
+
+ if( ! nextcmd )
+ {
+ block->SetState( STATE_NO_BLOCK );
+ block->SetCommand( BLOCK_IDLE );
+ GetScreen()->SetCurItem( NULL );
+ m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString,
+ false );
+ }
+
+ if( zoom_command )
+ Window_Zoom( GetScreen()->m_BlockLocate );
+
+ return nextcmd;
+}
+
+
+/* Traces the outline of the search block structures
+ * The entire block follows the cursor
+ */
+static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ BASE_SCREEN* screen = aPanel->GetScreen();
+ BLOCK_SELECTOR* block = &screen->m_BlockLocate;
+ SCH_ITEM* schitem;
+
+ /* Erase old block contents. */
+ if( aErase )
+ {
+ block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
+
+ for( unsigned ii = 0; ii < block->GetCount(); ii++ )
+ {
+ schitem = (SCH_ITEM*) block->GetItem( ii );
+
+ if( schitem->Type() == SCH_COMPONENT_T )
+ ((SCH_COMPONENT*)schitem)->Draw( aPanel, aDC, block->GetMoveVector(),
+ g_XorMode, g_GhostColor, false );
+ else
+ schitem->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, g_GhostColor );
+ }
+ }
+
+ /* Repaint new view. */
+ block->SetMoveVector( aPanel->GetParent()->GetCrossHairPosition() - block->GetLastCursorPosition() );
+ block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
+
+ for( unsigned ii = 0; ii < block->GetCount(); ii++ )
+ {
+ schitem = (SCH_ITEM*) block->GetItem( ii );
+
+ if( schitem->Type() == SCH_COMPONENT_T )
+ ((SCH_COMPONENT*)schitem)->Draw( aPanel, aDC, block->GetMoveVector(),
+ g_XorMode, g_GhostColor, false );
+ else
+ schitem->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, g_GhostColor );
+ }
+}
+
+
+void SCH_EDIT_FRAME::copyBlockItems( PICKED_ITEMS_LIST& aItemsList )
+{
+ m_blockItems.ClearListAndDeleteItems(); // delete previous saved list, if exists
+
+ for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
+ {
+ // Clear m_Flag member of selected items:
+ aItemsList.GetPickedItem( ii )->ClearFlags();
+
+ /* Make a copy of the original picked item. */
+ SCH_ITEM* copy = DuplicateStruct( (SCH_ITEM*) aItemsList.GetPickedItem( ii ) );
+ copy->SetParent( NULL );
+
+ // In list the wrapper is owner of the schematic item, we can use the UR_DELETED
+ // status for the picker because pickers with this status are owner of the picked item
+ // (or TODO ?: create a new status like UR_DUPLICATE)
+ ITEM_PICKER item( copy, UR_DELETED );
+
+ m_blockItems.PushItem( item );
+ }
+}
+
+
+void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC )
+{
+ unsigned i;
+ SCH_ITEM* item;
+ SCH_SHEET_LIST hierarchy; // This is the entire schematic hierarcy.
+
+ if( m_blockItems.GetCount() == 0 )
+ {
+ DisplayError( this, _( "No item to paste." ) );
+ return;
+ }
+
+ wxFileName destFn = m_CurrentSheet->Last()->GetFileName();
+
+ if( destFn.IsRelative() )
+ destFn.MakeAbsolute( Prj().GetProjectPath() );
+
+ // Make sure any sheets in the block to be pasted will not cause recursion in
+ // the destination sheet.
+ for( i = 0; i < m_blockItems.GetCount(); i++ )
+ {
+ item = (SCH_ITEM*) m_blockItems.GetItem( i );
+
+ if( item->Type() == SCH_SHEET_T )
+ {
+ SCH_SHEET* sheet = (SCH_SHEET*)item;
+ wxFileName srcFn = sheet->GetFileName();
+
+ if( srcFn.IsRelative() )
+ srcFn.MakeAbsolute( Prj().GetProjectPath() );
+
+ SCH_SHEET_LIST sheetHierarchy( sheet );
+
+ if( hierarchy.TestForRecursion( sheetHierarchy,
+ destFn.GetFullPath( wxPATH_UNIX ) ) )
+ {
+ wxString msg;
+
+ msg.Printf( _( "The sheet changes cannot be made because the destination "
+ "sheet already has the sheet <%s> or one of it's subsheets "
+ "as a parent somewhere in the schematic hierarchy." ),
+ GetChars( sheet->GetFileName() ) );
+ DisplayError( this, msg );
+ return;
+ }
+
+ // Duplicate sheet names and sheet time stamps are not valid. Use a time stamp
+ // based sheet name and update the time stamp for each sheet in the block.
+ unsigned long timeStamp = (unsigned long)GetNewTimeStamp();
+
+ sheet->SetName( wxString::Format( wxT( "sheet%8.8lX" ), timeStamp ) );
+ sheet->SetTimeStamp( (time_t)timeStamp );
+ }
+ }
+
+ PICKED_ITEMS_LIST picklist;
+
+ for( i = 0; i < m_blockItems.GetCount(); i++ )
+ {
+ item = DuplicateStruct( (SCH_ITEM*) m_blockItems.GetItem( i ) );
+
+ // Creates data, and push it as new data in undo item list buffer
+ ITEM_PICKER picker( item, UR_NEW );
+ picklist.PushItem( picker );
+
+ // Clear annotation and init new time stamp for the new components and sheets:
+ if( item->Type() == SCH_COMPONENT_T )
+ {
+ ( (SCH_COMPONENT*) item )->SetTimeStamp( GetNewTimeStamp() );
+ ( (SCH_COMPONENT*) item )->ClearAnnotation( NULL );
+ }
+ else if( item->Type() == SCH_SHEET_T )
+ {
+ ( (SCH_SHEET*) item )->SetTimeStamp( GetNewTimeStamp() );
+ }
+
+ SetSchItemParent( item, GetScreen() );
+ item->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+ GetScreen()->Append( item );
+ }
+
+ SaveCopyInUndoList( picklist, UR_NEW );
+
+ MoveItemsInList( picklist, GetScreen()->m_BlockLocate.GetMoveVector() );
+
+ // Clear flags for all items.
+ GetScreen()->ClearDrawingState();
+
+ OnModify();
+
+ return;
+}
diff --git a/eeschema/block_libedit.cpp b/eeschema/block_libedit.cpp
new file mode 100644
index 0000000..5dc235f
--- /dev/null
+++ b/eeschema/block_libedit.cpp
@@ -0,0 +1,355 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file block_libedit.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+
+#include <general.h>
+#include <class_library.h>
+#include <libeditframe.h>
+
+
+static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase );
+
+
+int LIB_EDIT_FRAME::BlockCommand( int key )
+{
+ int cmd = BLOCK_IDLE;
+
+ switch( key )
+ {
+ default:
+ cmd = key & 0xFF;
+ break;
+
+ case -1:
+ cmd = BLOCK_PRESELECT_MOVE;
+ break;
+
+ case 0:
+ cmd = BLOCK_MOVE;
+ break;
+
+ case GR_KB_SHIFT:
+ cmd = BLOCK_COPY;
+ break;
+
+ case GR_KB_ALT:
+ cmd = BLOCK_ROTATE;
+ break;
+
+ case GR_KB_SHIFTCTRL:
+ cmd = BLOCK_DELETE;
+ break;
+
+ case GR_KB_CTRL:
+ cmd = BLOCK_MIRROR_Y;
+ break;
+
+ case MOUSE_MIDDLE:
+ cmd = BLOCK_ZOOM;
+ break;
+ }
+
+ return cmd;
+}
+
+
+bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
+{
+ int ItemCount = 0;
+ bool nextCmd = false;
+ wxPoint pt;
+
+ if( GetScreen()->m_BlockLocate.GetCount() )
+ {
+ BLOCK_STATE_T state = GetScreen()->m_BlockLocate.GetState();
+ BLOCK_COMMAND_T command = GetScreen()->m_BlockLocate.GetCommand();
+ m_canvas->CallEndMouseCapture( DC );
+ GetScreen()->m_BlockLocate.SetState( state );
+ GetScreen()->m_BlockLocate.SetCommand( command );
+ m_canvas->SetMouseCapture( DrawAndSizingBlockOutlines, AbortBlockCurrentCommand );
+ SetCrossHairPosition( wxPoint( GetScreen()->m_BlockLocate.GetRight(),
+ GetScreen()->m_BlockLocate.GetBottom() ) );
+ m_canvas->MoveCursorToCrossHair();
+ }
+
+ switch( GetScreen()->m_BlockLocate.GetCommand() )
+ {
+ case BLOCK_IDLE:
+ DisplayError( this, wxT( "Error in HandleBlockPLace" ) );
+ break;
+
+ case BLOCK_DRAG: // Drag
+ case BLOCK_DRAG_ITEM:
+ case BLOCK_MOVE: // Move
+ case BLOCK_COPY: // Copy
+ if( GetCurPart() )
+ ItemCount = GetCurPart()->SelectItems( GetScreen()->m_BlockLocate,
+ m_unit, m_convert,
+ m_editPinsPerPartOrConvert );
+ if( ItemCount )
+ {
+ nextCmd = true;
+
+ if( m_canvas->IsMouseCaptured() )
+ {
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ }
+
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE );
+ m_canvas->Refresh( true );
+ }
+ break;
+
+ case BLOCK_PRESELECT_MOVE: // Move with preselection list
+ nextCmd = true;
+ m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE );
+ break;
+
+ case BLOCK_DELETE: // Delete
+ if( GetCurPart() )
+ ItemCount = GetCurPart()->SelectItems( GetScreen()->m_BlockLocate,
+ m_unit, m_convert,
+ m_editPinsPerPartOrConvert );
+ if( ItemCount )
+ SaveCopyInUndoList( GetCurPart() );
+
+ if( GetCurPart() )
+ {
+ GetCurPart()->DeleteSelectedItems();
+ OnModify();
+ }
+ break;
+
+ case BLOCK_SAVE: // Save
+ case BLOCK_PASTE:
+ case BLOCK_FLIP:
+ break;
+
+ case BLOCK_ROTATE:
+ case BLOCK_MIRROR_X:
+ case BLOCK_MIRROR_Y:
+ if( GetCurPart() )
+ ItemCount = GetCurPart()->SelectItems( GetScreen()->m_BlockLocate,
+ m_unit, m_convert,
+ m_editPinsPerPartOrConvert );
+ if( ItemCount )
+ SaveCopyInUndoList( GetCurPart() );
+
+ pt = GetScreen()->m_BlockLocate.Centre();
+ pt = GetNearestGridPosition( pt );
+ pt.y = -pt.y;
+
+ if( GetCurPart() )
+ {
+ OnModify();
+ int block_cmd = GetScreen()->m_BlockLocate.GetCommand();
+
+ if( block_cmd == BLOCK_MIRROR_Y)
+ GetCurPart()->MirrorSelectedItemsH( pt );
+ else if( block_cmd == BLOCK_MIRROR_X)
+ GetCurPart()->MirrorSelectedItemsV( pt );
+ else if( block_cmd == BLOCK_ROTATE )
+ GetCurPart()->RotateSelectedItems( pt );
+ }
+
+ break;
+
+ case BLOCK_ZOOM: // Window Zoom
+ Window_Zoom( GetScreen()->m_BlockLocate );
+ break;
+
+ case BLOCK_ABORT:
+ break;
+
+ case BLOCK_SELECT_ITEMS_ONLY:
+ break;
+
+ case BLOCK_COPY_AND_INCREMENT: // not used in Eeschema
+ case BLOCK_MOVE_EXACT: // not used in Eeschema
+ break;
+ }
+
+ if( !nextCmd )
+ {
+ if( GetScreen()->m_BlockLocate.GetCommand() != BLOCK_SELECT_ITEMS_ONLY && GetCurPart() )
+ GetCurPart()->ClearSelectedItems();
+
+ GetScreen()->m_BlockLocate.SetState( STATE_NO_BLOCK );
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_IDLE );
+ GetScreen()->SetCurItem( NULL );
+ m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString,
+ false );
+ m_canvas->Refresh( true );
+ }
+
+ return nextCmd;
+}
+
+
+void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
+{
+ wxPoint pt;
+
+ if( !m_canvas->IsMouseCaptured() )
+ {
+ DisplayError( this, wxT( "HandleBlockPLace : m_mouseCaptureCallback = NULL" ) );
+ }
+
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP );
+
+ switch( GetScreen()->m_BlockLocate.GetCommand() )
+ {
+ case BLOCK_IDLE:
+ break;
+
+ case BLOCK_DRAG: // Drag
+ case BLOCK_DRAG_ITEM:
+ case BLOCK_MOVE: // Move
+ case BLOCK_PRESELECT_MOVE: // Move with preselection list
+ GetScreen()->m_BlockLocate.ClearItemsList();
+
+ if( GetCurPart() )
+ SaveCopyInUndoList( GetCurPart() );
+
+ pt = GetScreen()->m_BlockLocate.GetMoveVector();
+ pt.y *= -1;
+
+ if( GetCurPart() )
+ GetCurPart()->MoveSelectedItems( pt );
+
+ m_canvas->Refresh( true );
+ break;
+
+ case BLOCK_COPY: // Copy
+ GetScreen()->m_BlockLocate.ClearItemsList();
+
+ if( GetCurPart() )
+ SaveCopyInUndoList( GetCurPart() );
+
+ pt = GetScreen()->m_BlockLocate.GetMoveVector();
+ pt.y = -pt.y;
+
+ if( GetCurPart() )
+ GetCurPart()->CopySelectedItems( pt );
+
+ break;
+
+ case BLOCK_PASTE: // Paste (recopy the last block saved)
+ GetScreen()->m_BlockLocate.ClearItemsList();
+ break;
+
+ case BLOCK_ROTATE: // Invert by popup menu, from block move
+ case BLOCK_MIRROR_X: // Invert by popup menu, from block move
+ case BLOCK_MIRROR_Y: // Invert by popup menu, from block move
+ if( GetCurPart() )
+ SaveCopyInUndoList( GetCurPart() );
+
+ pt = GetScreen()->m_BlockLocate.Centre();
+ pt = GetNearestGridPosition( pt );
+ pt.y = -pt.y;
+
+ if( GetCurPart() )
+ {
+ int block_cmd = GetScreen()->m_BlockLocate.GetCommand();
+
+ if( block_cmd == BLOCK_MIRROR_Y)
+ GetCurPart()->MirrorSelectedItemsH( pt );
+ else if( block_cmd == BLOCK_MIRROR_X)
+ GetCurPart()->MirrorSelectedItemsV( pt );
+ else if( block_cmd == BLOCK_ROTATE )
+ GetCurPart()->RotateSelectedItems( pt );
+ }
+
+ break;
+
+ case BLOCK_ZOOM: // Handled by HandleBlockEnd
+ case BLOCK_DELETE:
+ case BLOCK_SAVE:
+ case BLOCK_ABORT:
+ default:
+ break;
+ }
+
+ OnModify();
+
+ GetScreen()->m_BlockLocate.SetState( STATE_NO_BLOCK );
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_IDLE );
+ GetScreen()->SetCurItem( NULL );
+ m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false );
+ m_canvas->Refresh( true );
+}
+
+
+/*
+ * Traces the outline of the search block structures
+ * The entire block follows the cursor
+ */
+void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ BLOCK_SELECTOR* block;
+ BASE_SCREEN* screen = aPanel->GetScreen();
+ block = &screen->m_BlockLocate;
+
+ LIB_EDIT_FRAME* parent = (LIB_EDIT_FRAME*) aPanel->GetParent();
+ wxASSERT( parent != NULL );
+
+ LIB_PART* component = parent->GetCurPart();
+
+ if( component == NULL )
+ return;
+
+ int unit = parent->GetUnit();
+ int convert = parent->GetConvert();
+
+ if( aErase )
+ {
+ block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
+
+ component->Draw( aPanel, aDC, block->GetMoveVector(), unit, convert,
+ g_XorMode, UNSPECIFIED_COLOR, DefaultTransform, true, true, true );
+ }
+
+ // Repaint new view
+ block->SetMoveVector( parent->GetCrossHairPosition() - block->GetLastCursorPosition() );
+
+ GRSetDrawMode( aDC, g_XorMode );
+ block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
+
+ component->Draw( aPanel, aDC, block->GetMoveVector(), unit, convert,
+ g_XorMode, UNSPECIFIED_COLOR, DefaultTransform, true, true, true );
+}
diff --git a/eeschema/bus-wire-junction.cpp b/eeschema/bus-wire-junction.cpp
new file mode 100644
index 0000000..18e3bd1
--- /dev/null
+++ b/eeschema/bus-wire-junction.cpp
@@ -0,0 +1,505 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file bus-wire-junction.cpp
+ * @brief Code for editing buses, wires, and junctions.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <schframe.h>
+
+#include <lib_draw_item.h>
+#include <lib_pin.h>
+#include <general.h>
+#include <sch_bus_entry.h>
+#include <sch_junction.h>
+#include <sch_line.h>
+#include <sch_no_connect.h>
+#include <sch_text.h>
+#include <sch_component.h>
+#include <sch_sheet.h>
+
+
+static void AbortCreateNewLine( EDA_DRAW_PANEL* aPanel, wxDC* aDC );
+static void ComputeBreakPoint( SCH_LINE* segment, const wxPoint& new_pos );
+
+static DLIST< SCH_ITEM > s_wires; // when creating a new set of wires,
+ // stores here the new wires.
+
+
+/**
+ * In a contiguous list of wires, remove wires that backtrack over the previous
+ * wire. Example:
+ *
+ * Wire is added:
+ * ---------------------------------------->
+ *
+ * A second wire backtracks over it:
+ * -------------------<====================>
+ *
+ * RemoveBacktracks is called:
+ * ------------------->
+ */
+static void RemoveBacktracks( DLIST<SCH_ITEM>& aWires )
+{
+ SCH_LINE* last_line = NULL;
+
+ EDA_ITEM* first = aWires.GetFirst();
+ for( EDA_ITEM* p = first; p; )
+ {
+ SCH_LINE *line = dynamic_cast<SCH_LINE*>( p );
+ if( !line )
+ {
+ wxFAIL_MSG( "RemoveBacktracks() requires SCH_LINE items" );
+ break;
+ }
+ p = line->Next();
+
+ if( last_line )
+ {
+ wxASSERT_MSG( last_line->GetEndPoint() == line->GetStartPoint(),
+ "RemoveBacktracks() requires contiguous lines" );
+ if( IsPointOnSegment( last_line->GetStartPoint(), line->GetStartPoint(),
+ line->GetEndPoint() ) )
+ {
+ last_line->SetEndPoint( line->GetEndPoint() );
+ delete s_wires.Remove( line );
+ }
+ else
+ last_line = line;
+ }
+ else
+ last_line = line;
+ }
+}
+
+
+/**
+ * Mouse capture callback for drawing line segments.
+ */
+static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ SCH_LINE* segment;
+
+ if( s_wires.GetCount() == 0 )
+ return;
+
+ segment = (SCH_LINE*) s_wires.begin();
+ EDA_COLOR_T color = GetLayerColor( segment->GetLayer() );
+ ColorChangeHighlightFlag( &color, !(color & HIGHLIGHT_FLAG) );
+
+ if( aErase )
+ {
+ while( segment )
+ {
+ if( !segment->IsNull() ) // Redraw if segment length != 0
+ segment->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode, color );
+
+ segment = segment->Next();
+ }
+ }
+
+ SCH_EDIT_FRAME* frame = (SCH_EDIT_FRAME*) aPanel->GetParent();
+
+ wxPoint endpos = frame->GetCrossHairPosition();
+
+ if( frame->GetForceHVLines() ) /* Coerce the line to vertical or horizontal one: */
+ ComputeBreakPoint( (SCH_LINE*) s_wires.GetLast()->Back(), endpos );
+ else
+ ( (SCH_LINE*) s_wires.GetLast() )->SetEndPoint( endpos );
+
+ segment = (SCH_LINE*) s_wires.begin();
+
+ while( segment )
+ {
+ if( !segment->IsNull() ) // Redraw if segment length != 0
+ segment->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode, color );
+
+ segment = segment->Next();
+ }
+}
+
+
+void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type )
+{
+ SCH_LINE* segment;
+ SCH_LINE* nextSegment;
+ wxPoint cursorpos = GetCrossHairPosition();
+
+ // We should know if a segment is currently in progress
+ segment = (SCH_LINE*) GetScreen()->GetCurItem();
+ if( segment ) // a current item exists, but not necessary a currently edited item
+ {
+ if( !segment->GetFlags() || ( segment->Type() != SCH_LINE_T ) )
+ {
+ if( segment->GetFlags() )
+ {
+ wxLogDebug( wxT( "BeginSegment: item->GetFlags()== %X" ),
+ segment->GetFlags() );
+ }
+ // no wire, bus or graphic line in progress
+ segment = NULL;
+ }
+ }
+
+ if( !segment ) // first point : Create the first wire or bus segment
+ {
+ switch( type )
+ {
+ default:
+ segment = new SCH_LINE( cursorpos, LAYER_NOTES );
+ break;
+
+ case LAYER_WIRE:
+ segment = new SCH_LINE( cursorpos, LAYER_WIRE );
+
+ /* A junction will be created later, when we'll know the
+ * segment end position, and if the junction is really needed */
+ break;
+
+ case LAYER_BUS:
+ segment = new SCH_LINE( cursorpos, LAYER_BUS );
+ break;
+ }
+
+ segment->SetFlags( IS_NEW );
+ s_wires.PushBack( segment );
+ GetScreen()->SetCurItem( segment );
+
+ // We need 2 segments to go from a given start pin to an end point when the horizontal
+ // and vertical lines only switch is on.
+ if( GetForceHVLines() )
+ {
+ nextSegment = new SCH_LINE( *segment );
+ nextSegment->SetFlags( IS_NEW );
+ s_wires.PushBack( nextSegment );
+ GetScreen()->SetCurItem( nextSegment );
+ }
+
+ m_canvas->SetMouseCapture( DrawSegment, AbortCreateNewLine );
+ SetRepeatItem( NULL );
+ }
+ else // A segment is in progress: terminates the current segment and add a new segment.
+ {
+ SCH_LINE* prevSegment = segment->Back();
+
+ // Be aware prevSegment can be null when the horizontal and vertical lines only switch is off
+ // when we create the first segment.
+
+ if( !GetForceHVLines() )
+ {
+ // If only one segment is needed and it has a zero length, do not create a new one.
+ if( segment->IsNull() )
+ return;
+ }
+ else
+ {
+ wxCHECK_RET( prevSegment != NULL, wxT( "Failed to create second line segment." ) );
+
+ // If two segments are required and they both have zero length, do not
+ // create a new one.
+ if( prevSegment && prevSegment->IsNull() && segment->IsNull() )
+ return;
+ }
+
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ // Terminate the command if the end point is on a pin, junction, or another wire or bus.
+ if( GetScreen()->IsTerminalPoint( cursorpos, segment->GetLayer() ) )
+ {
+ EndSegment( DC );
+ return;
+ }
+
+ // Create a new segment, and chain it after the current new segment.
+ nextSegment = new SCH_LINE( *segment );
+ nextSegment->SetStartPoint( cursorpos );
+ s_wires.PushBack( nextSegment );
+
+ segment->SetEndPoint( cursorpos );
+ segment->ClearFlags( IS_NEW );
+ segment->SetFlags( SELECTED );
+ nextSegment->SetFlags( IS_NEW );
+ GetScreen()->SetCurItem( nextSegment );
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ }
+}
+
+
+void SCH_EDIT_FRAME::EndSegment( wxDC* DC )
+{
+ SCH_SCREEN* screen = GetScreen();
+ SCH_LINE* segment = (SCH_LINE*) screen->GetCurItem();
+
+ if( segment == NULL || segment->Type() != SCH_LINE_T || !segment->IsNew() )
+ return;
+
+ // Delete zero length segments and clear item flags.
+ SCH_ITEM* item = s_wires.begin();
+
+ while( item )
+ {
+ item->ClearFlags();
+
+ wxCHECK_RET( item->Type() == SCH_LINE_T, wxT( "Unexpected object type in wire list." ) );
+
+ segment = (SCH_LINE*) item;
+ item = item->Next();
+
+ if( segment->IsNull() )
+ delete s_wires.Remove( segment );
+ }
+
+ if( s_wires.GetCount() == 0 )
+ return;
+
+ // Get the last non-null wire (this is the last created segment).
+ SetRepeatItem( segment = (SCH_LINE*) s_wires.GetLast() );
+
+ screen->SetCurItem( NULL );
+ m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false );
+
+ // store the terminal point of this last segment: a junction could be needed
+ // (the last wire could be merged/deleted/modified, and lost)
+ wxPoint endpoint = segment->GetEndPoint();
+
+ // store the starting point of this first segment: a junction could be needed
+ SCH_LINE* firstsegment = (SCH_LINE*) s_wires.GetFirst();
+ wxPoint startPoint = firstsegment->GetStartPoint();
+
+ // Save the old wires for the undo command
+ DLIST< SCH_ITEM > oldWires; // stores here the old wires
+ GetScreen()->ExtractWires( oldWires, true ); // Save them in oldWires list
+ // Put the snap shot of the previous wire, buses, and junctions in the undo/redo list.
+ PICKED_ITEMS_LIST oldItems;
+ oldItems.m_Status = UR_WIRE_IMAGE;
+
+ while( oldWires.GetCount() != 0 )
+ {
+ ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE );
+ oldItems.PushItem( picker );
+ }
+
+ SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE );
+
+ // Remove segments backtracking over others
+ RemoveBacktracks( s_wires );
+
+ // Add the new wires
+ screen->Append( s_wires );
+
+ // Correct and remove segments that need to be merged.
+ screen->SchematicCleanUp( NULL, DC );
+
+ // A junction could be needed to connect the end point of the last created segment.
+ if( screen->IsJunctionNeeded( endpoint ) )
+ screen->Append( AddJunction( DC, endpoint ) );
+
+ // A junction could be needed to connect the start point of the set of new created wires
+ if( screen->IsJunctionNeeded( startPoint ) )
+ screen->Append( AddJunction( DC, startPoint ) );
+
+ m_canvas->Refresh();
+
+ OnModify();
+}
+
+
+/**
+ * Function ComputeBreakPoint
+ * computes the middle coordinate for 2 segments from the start point to \a aPosition
+ * with the segments kept in the horizontal or vertical axis only.
+ *
+ * @param aSegment A pointer to a #SCH_LINE object containing the first line break point
+ * to compute.
+ * @param aPosition A reference to a wxPoint object containing the coordinates of the
+ * position used to calculate the line break point.
+ */
+static void ComputeBreakPoint( SCH_LINE* aSegment, const wxPoint& aPosition )
+{
+ wxCHECK_RET( aSegment != NULL, wxT( "Cannot compute break point of NULL line segment." ) );
+
+ SCH_LINE* nextSegment = aSegment->Next();
+ wxPoint midPoint = aPosition;
+
+ wxCHECK_RET( nextSegment != NULL,
+ wxT( "Cannot compute break point of NULL second line segment." ) );
+
+#if 0
+ if( ABS( midPoint.x - aSegment->GetStartPoint().x ) <
+ ABS( midPoint.y - aSegment->GetStartPoint().y ) )
+ midPoint.x = aSegment->GetStartPoint().x;
+ else
+ midPoint.y = aSegment->GetStartPoint().y;
+#else
+ int iDx = aSegment->GetEndPoint().x - aSegment->GetStartPoint().x;
+ int iDy = aSegment->GetEndPoint().y - aSegment->GetStartPoint().y;
+
+ if( iDy != 0 ) // keep the first segment orientation (currently horizontal)
+ {
+ midPoint.x = aSegment->GetStartPoint().x;
+ }
+ else if( iDx != 0 ) // keep the first segment orientation (currently vertical)
+ {
+ midPoint.y = aSegment->GetStartPoint().y;
+ }
+ else
+ {
+ if( std::abs( midPoint.x - aSegment->GetStartPoint().x ) <
+ std::abs( midPoint.y - aSegment->GetStartPoint().y ) )
+ midPoint.x = aSegment->GetStartPoint().x;
+ else
+ midPoint.y = aSegment->GetStartPoint().y;
+ }
+#endif
+
+ aSegment->SetEndPoint( midPoint );
+ nextSegment->SetStartPoint( midPoint );
+ nextSegment->SetEndPoint( aPosition );
+}
+
+
+void SCH_EDIT_FRAME::DeleteCurrentSegment( wxDC* DC )
+{
+ SCH_SCREEN* screen = GetScreen();
+
+ SetRepeatItem( NULL );
+
+ if( ( screen->GetCurItem() == NULL ) || !screen->GetCurItem()->IsNew() )
+ return;
+
+ DrawSegment( m_canvas, DC, wxDefaultPosition, false );
+
+ screen->Remove( screen->GetCurItem() );
+ m_canvas->SetMouseCaptureCallback( NULL );
+ screen->SetCurItem( NULL );
+}
+
+
+SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( wxDC* aDC, const wxPoint& aPosition,
+ bool aPutInUndoList )
+{
+ SCH_JUNCTION* junction = new SCH_JUNCTION( aPosition );
+
+ SetRepeatItem( junction );
+
+ m_canvas->CrossHairOff( aDC ); // Erase schematic cursor
+ junction->Draw( m_canvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+ m_canvas->CrossHairOn( aDC ); // Display schematic cursor
+
+ if( aPutInUndoList )
+ {
+ GetScreen()->Append( junction );
+ SaveCopyInUndoList( junction, UR_NEW );
+ OnModify();
+ }
+
+ return junction;
+}
+
+
+SCH_NO_CONNECT* SCH_EDIT_FRAME::AddNoConnect( wxDC* aDC, const wxPoint& aPosition )
+{
+ SCH_NO_CONNECT* no_connect = new SCH_NO_CONNECT( aPosition );
+
+ SetRepeatItem( no_connect );
+ GetScreen()->Append( no_connect );
+ GetScreen()->SchematicCleanUp( m_canvas, aDC );
+ OnModify();
+ m_canvas->Refresh();
+ SaveCopyInUndoList( no_connect, UR_NEW );
+ return no_connect;
+}
+
+
+/* Abort function for wire, bus or line creation
+ */
+static void AbortCreateNewLine( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
+{
+ SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen();
+
+ if( screen->GetCurItem() )
+ {
+ s_wires.DeleteAll(); // Free the list, for a future usage
+ screen->SetCurItem( NULL );
+ aPanel->Refresh();
+ }
+ else
+ {
+ SCH_EDIT_FRAME* parent = ( SCH_EDIT_FRAME* ) aPanel->GetParent();
+ parent->SetRepeatItem( NULL );
+ }
+
+ // Clear flags used in edit functions.
+ screen->ClearDrawingState();
+}
+
+
+void SCH_EDIT_FRAME::RepeatDrawItem( wxDC* DC )
+{
+ SCH_ITEM* repeater = GetRepeatItem();
+
+ if( !repeater )
+ return;
+
+ //D( repeater>Show( 0, std::cout ); )
+
+ // clone the repeater, move it, insert into display list, then save a copy
+ // via SetRepeatItem();
+
+ SCH_ITEM* my_clone = (SCH_ITEM*) repeater->Clone();
+
+ // If cloning a component then put into 'move' mode.
+ if( my_clone->Type() == SCH_COMPONENT_T )
+ {
+ wxPoint pos = GetCrossHairPosition() -
+ ( (SCH_COMPONENT*) my_clone )->GetPosition();
+
+ my_clone->SetFlags( IS_NEW );
+ ( (SCH_COMPONENT*) my_clone )->SetTimeStamp( GetNewTimeStamp() );
+ my_clone->Move( pos );
+ my_clone->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode );
+ PrepareMoveItem( my_clone, DC );
+ }
+ else
+ {
+ my_clone->Move( GetRepeatStep() );
+
+ if( my_clone->CanIncrementLabel() )
+ ( (SCH_TEXT*) my_clone )->IncrementLabel( GetRepeatDeltaLabel() );
+
+ GetScreen()->Append( my_clone );
+ GetScreen()->TestDanglingEnds();
+ my_clone->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+ SaveCopyInUndoList( my_clone, UR_NEW );
+ my_clone->ClearFlags();
+ }
+
+ // clone my_clone, now that it has been moved, thus saving new position.
+ SetRepeatItem( my_clone );
+}
diff --git a/eeschema/busentry.cpp b/eeschema/busentry.cpp
new file mode 100644
index 0000000..06c3ba3
--- /dev/null
+++ b/eeschema/busentry.cpp
@@ -0,0 +1,83 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file busentry.cpp
+ * @brief Code to handle manipulation of bus entry objects.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <schframe.h>
+
+#include <sch_bus_entry.h>
+
+
+static int s_LastShape = '\\';
+
+
+SCH_BUS_BUS_ENTRY* SCH_EDIT_FRAME::CreateBusBusEntry()
+{
+ // Create and place a new bus entry at cursor position
+ SCH_BUS_BUS_ENTRY* busEntry = new SCH_BUS_BUS_ENTRY( GetCrossHairPosition(), s_LastShape );
+
+ busEntry->SetFlags( IS_NEW );
+ GetScreen()->SetCurItem( busEntry );
+ addCurrentItemToList();
+ return busEntry;
+}
+
+SCH_BUS_WIRE_ENTRY* SCH_EDIT_FRAME::CreateBusWireEntry()
+{
+ // Create and place a new bus entry at cursor position
+ SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( GetCrossHairPosition(), s_LastShape );
+
+ busEntry->SetFlags( IS_NEW );
+ GetScreen()->SetCurItem( busEntry );
+ addCurrentItemToList();
+ return busEntry;
+}
+
+/* set the shape of BusEntry (shape = / or \ )
+ */
+void SCH_EDIT_FRAME::SetBusEntryShape( wxDC* DC, SCH_BUS_ENTRY_BASE* BusEntry, char entry_shape )
+{
+ if( BusEntry == NULL )
+ return;
+
+ /* Put old item in undo list if it is not currently in edit */
+ if( BusEntry->GetFlags() == 0 )
+ SaveCopyInUndoList( BusEntry, UR_CHANGED );
+
+ s_LastShape = entry_shape == '/' ? '/' : '\\';
+
+ BusEntry->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode );
+ BusEntry->SetBusEntryShape( s_LastShape );
+ GetScreen()->TestDanglingEnds();
+ BusEntry->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode );
+
+ OnModify( );
+}
diff --git a/eeschema/class_drc_erc_item.cpp b/eeschema/class_drc_erc_item.cpp
new file mode 100644
index 0000000..9071dc8
--- /dev/null
+++ b/eeschema/class_drc_erc_item.cpp
@@ -0,0 +1,68 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/******************************************************************/
+/* class_drc_erc_item.cpp - DRC_ITEM class functions for eeschema */
+/******************************************************************/
+#include <fctsys.h>
+#include <common.h>
+
+#include <class_drc_item.h>
+#include <erc.h>
+#include <base_units.h>
+
+wxString DRC_ITEM::GetErrorText() const
+{
+ switch( m_ErrorCode )
+ {
+ case ERCE_UNSPECIFIED:
+ return wxString( _("ERC err unspecified") );
+ case ERCE_DUPLICATE_SHEET_NAME:
+ return wxString( _("Duplicate sheet names within a given sheet") );
+ case ERCE_PIN_NOT_CONNECTED:
+ return wxString( _("Pin not connected (and no connect symbol found on this pin)") );
+ case ERCE_PIN_NOT_DRIVEN:
+ return wxString( _("Pin connected to some others pins but no pin to drive it") );
+ case ERCE_PIN_TO_PIN_WARNING:
+ return wxString( _("Conflict problem between pins. Severity: warning") );
+ case ERCE_PIN_TO_PIN_ERROR:
+ return wxString( _("Conflict problem between pins. Severity: error") );
+ case ERCE_HIERACHICAL_LABEL:
+ return wxString( _("Mismatch between hierarchical labels and pins sheets"));
+ case ERCE_NOCONNECT_CONNECTED:
+ return wxString( _("A no connect symbol is connected to more than 1 pin"));
+ case ERCE_GLOBLABEL:
+ return wxString( _("Global label not connected to any other global label") );
+
+ default:
+ return wxString( wxT("Unkown.") );
+ }
+}
+
+wxString DRC_ITEM::ShowCoord( const wxPoint& aPos )
+{
+ wxString ret;
+ ret << aPos;
+ return ret;
+}
diff --git a/eeschema/class_libentry.cpp b/eeschema/class_libentry.cpp
new file mode 100644
index 0000000..cb99d68
--- /dev/null
+++ b/eeschema/class_libentry.cpp
@@ -0,0 +1,1898 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_libentry.cpp
+ */
+
+#include <fctsys.h>
+#include <macros.h>
+#include <kicad_string.h>
+#include <class_drawpanel.h>
+#include <plot_common.h>
+#include <gr_basic.h>
+#include <class_sch_screen.h>
+#include <richio.h>
+
+#include <general.h>
+#include <template_fieldnames.h>
+#include <transform.h>
+#include <class_library.h>
+#include <class_libentry.h>
+#include <lib_pin.h>
+#include <lib_arc.h>
+#include <lib_bezier.h>
+#include <lib_circle.h>
+#include <lib_polyline.h>
+#include <lib_rectangle.h>
+#include <lib_text.h>
+
+#include <boost/foreach.hpp>
+
+// the separator char between the subpart id and the reference
+// 0 (no separator) or '.' or some other character
+int LIB_PART::m_subpartIdSeparator = 0;
+
+// the ascii char value to calculate the subpart symbol id from the part number:
+// 'A' or '1' usually. (to print U1.A or U1.1)
+// if this a a digit, a number is used as id symbol
+int LIB_PART::m_subpartFirstId = 'A';
+
+
+const wxChar traceSchLibMem[] = wxT( "KISCHLIBMEM" ); // public
+
+
+LIB_ALIAS::LIB_ALIAS( const wxString& aName, LIB_PART* aRootPart ):
+ EDA_ITEM( LIB_ALIAS_T ),
+ shared( aRootPart )
+{
+ name = aName;
+}
+
+
+LIB_ALIAS::LIB_ALIAS( const LIB_ALIAS& aAlias, LIB_PART* aRootPart ) :
+ EDA_ITEM( aAlias ),
+ shared( aRootPart )
+{
+ name = aAlias.name;
+
+ description = aAlias.description;
+ keyWords = aAlias.keyWords;
+ docFileName = aAlias.docFileName;
+}
+
+
+LIB_ALIAS::~LIB_ALIAS()
+{
+ wxASSERT_MSG( shared, wxT( "~LIB_ALIAS() without a LIB_PART" ) );
+
+ wxLogTrace( traceSchLibMem,
+ wxT( "%s: destroying alias:'%s' of part:'%s'." ),
+ GetChars( wxString::FromAscii( __WXFUNCTION__ ) ), GetChars( name ),
+ GetChars( shared->GetName() ) );
+
+ if( shared )
+ shared->RemoveAlias( this );
+}
+
+
+const wxString LIB_ALIAS::GetLibraryName()
+{
+ wxASSERT_MSG( shared, wxT( "LIB_ALIAS without a LIB_PART" ) );
+
+ if( shared )
+ return shared->GetLibraryName();
+
+ return wxString( _( "none" ) );
+}
+
+
+bool LIB_ALIAS::IsRoot() const
+{
+ return Cmp_KEEPCASE( name, shared->GetName() ) == 0;
+}
+
+
+PART_LIB* LIB_ALIAS::GetLib()
+{
+ return shared->GetLib();
+}
+
+
+bool LIB_ALIAS::SaveDoc( OUTPUTFORMATTER& aFormatter )
+{
+ if( description.IsEmpty() && keyWords.IsEmpty() && docFileName.IsEmpty() )
+ return true;
+
+ try
+ {
+ aFormatter.Print( 0, "#\n$CMP %s\n", TO_UTF8( name ) );
+
+ if( !description.IsEmpty() )
+ aFormatter.Print( 0, "D %s\n", TO_UTF8( description ) );
+
+ if( !keyWords.IsEmpty() )
+ aFormatter.Print( 0, "K %s\n", TO_UTF8( keyWords ) );
+
+ if( !docFileName.IsEmpty() )
+ aFormatter.Print( 0, "F %s\n", TO_UTF8( docFileName ) );
+
+ aFormatter.Print( 0, "$ENDCMP\n" );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+bool LIB_ALIAS::operator==( const wxChar* aName ) const
+{
+ return Cmp_KEEPCASE( name, aName ) == 0;
+}
+
+
+bool operator<( const LIB_ALIAS& aItem1, const LIB_ALIAS& aItem2 )
+{
+ return Cmp_KEEPCASE( aItem1.GetName(), aItem2.GetName() ) < 0;
+}
+
+
+int LibraryEntryCompare( const LIB_ALIAS* aItem1, const LIB_ALIAS* aItem2 )
+{
+ return Cmp_KEEPCASE( aItem1->GetName(), aItem2->GetName() );
+}
+
+
+/// http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
+struct null_deleter
+{
+ void operator()(void const *) const
+ {
+ }
+};
+
+
+LIB_PART::LIB_PART( const wxString& aName, PART_LIB* aLibrary ) :
+ EDA_ITEM( LIB_PART_T ),
+ m_me( this, null_deleter() )
+{
+ m_name = aName;
+ m_library = aLibrary;
+ m_dateModified = 0;
+ m_unitCount = 1;
+ m_pinNameOffset = 40;
+ m_options = ENTRY_NORMAL;
+ m_unitsLocked = false;
+ m_showPinNumbers = true;
+ m_showPinNames = true;
+
+ // Create the default alias if the name parameter is not empty.
+ if( !aName.IsEmpty() )
+ m_aliases.push_back( new LIB_ALIAS( aName, this ) );
+
+ // Add the MANDATORY_FIELDS in RAM only. These are assumed to be present
+ // when the field editors are invoked.
+ LIB_FIELD* value = new LIB_FIELD( this, VALUE );
+ value->SetText( aName );
+ drawings.push_back( value );
+
+ drawings.push_back( new LIB_FIELD( this, REFERENCE ) );
+ drawings.push_back( new LIB_FIELD( this, FOOTPRINT ) );
+ drawings.push_back( new LIB_FIELD( this, DATASHEET ) );
+}
+
+
+LIB_PART::LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary ) :
+ EDA_ITEM( aPart ),
+ m_me( this, null_deleter() )
+{
+ LIB_ITEM* newItem;
+
+ m_library = aLibrary;
+ m_name = aPart.m_name;
+ m_FootprintList = aPart.m_FootprintList;
+ m_unitCount = aPart.m_unitCount;
+ m_unitsLocked = aPart.m_unitsLocked;
+ m_pinNameOffset = aPart.m_pinNameOffset;
+ m_showPinNumbers = aPart.m_showPinNumbers;
+ m_showPinNames = aPart.m_showPinNames;
+ m_dateModified = aPart.m_dateModified;
+ m_options = aPart.m_options;
+
+ BOOST_FOREACH( LIB_ITEM& oldItem, aPart.GetDrawItemList() )
+ {
+ if( oldItem.IsNew() )
+ continue;
+
+ newItem = (LIB_ITEM*) oldItem.Clone();
+ newItem->SetParent( this );
+ drawings.push_back( newItem );
+ }
+
+ for( size_t i = 0; i < aPart.m_aliases.size(); i++ )
+ {
+ LIB_ALIAS* alias = new LIB_ALIAS( *aPart.m_aliases[i], this );
+ m_aliases.push_back( alias );
+ }
+}
+
+
+LIB_PART::~LIB_PART()
+{
+ wxLogTrace( traceSchLibMem,
+ wxT( "%s: destroying part '%s' with alias list count of %llu." ),
+ GetChars( wxString::FromAscii( __WXFUNCTION__ ) ), GetChars( GetName() ),
+ (long long unsigned) m_aliases.size() );
+
+ // If the part is being deleted directly rather than through the library,
+ // delete all of the aliases.
+ while( m_aliases.size() )
+ {
+ LIB_ALIAS* alias = m_aliases.back();
+ m_aliases.pop_back();
+ delete alias;
+ }
+}
+
+
+const wxString LIB_PART::GetLibraryName()
+{
+ if( m_library )
+ return m_library->GetName();
+
+ return wxString( _( "none" ) );
+}
+
+
+wxString LIB_PART::SubReference( int aUnit, bool aAddSeparator )
+{
+ wxString subRef;
+
+ if( m_subpartIdSeparator != 0 && aAddSeparator )
+ subRef << wxChar( m_subpartIdSeparator );
+
+ if( m_subpartFirstId >= '0' && m_subpartFirstId <= '9' )
+ subRef << aUnit;
+ else
+ {
+ // use letters as notation. To allow more than 26 units, the sub ref
+ // use one letter if letter = A .. Z or a ... z, and 2 letters otherwise
+ // first letter is expected to be 'A' or 'a' (i.e. 26 letters are available)
+ int u;
+ aUnit -= 1; // Unit number starts to 1. now to 0.
+
+ while( aUnit >= 26 ) // more than one letter are needed
+ {
+ u = aUnit / 26;
+ subRef << wxChar( m_subpartFirstId + u -1 );
+ aUnit %= 26;
+ }
+
+ u = m_subpartFirstId + aUnit;
+ subRef << wxChar( u );
+ }
+
+ return subRef;
+}
+
+
+void LIB_PART::SetName( const wxString& aName )
+{
+ m_name = aName;
+ GetValueField().SetText( aName );
+ m_aliases[0]->SetName( aName );
+}
+
+
+void LIB_PART::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDc, const wxPoint& aOffset, int aMulti,
+ int aConvert, GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor,
+ const TRANSFORM& aTransform, bool aShowPinText, bool aDrawFields,
+ bool aOnlySelected, const std::vector<bool>* aPinsDangling )
+{
+ BASE_SCREEN* screen = aPanel ? aPanel->GetScreen() : NULL;
+
+ GRSetDrawMode( aDc, aDrawMode );
+
+ /* draw background for filled items using background option
+ * Solid lines will be drawn after the background
+ * Note also, background is not drawn when:
+ * printing in black and white
+ * If the color is not the default color (aColor != -1 )
+ */
+ if( ! (screen && screen->m_IsPrinting && GetGRForceBlackPenState())
+ && (aColor == UNSPECIFIED_COLOR) )
+ {
+ BOOST_FOREACH( LIB_ITEM& drawItem, drawings )
+ {
+ if( drawItem.m_Fill != FILLED_WITH_BG_BODYCOLOR )
+ continue;
+
+ if( aOnlySelected && !drawItem.IsSelected() )
+ continue;
+
+ // Do not draw an item while moving (the cursor handler does that)
+ if( drawItem.m_Flags & IS_MOVED )
+ continue;
+
+ // Do not draw items not attached to the current part
+ if( aMulti && drawItem.m_Unit && ( drawItem.m_Unit != aMulti ) )
+ continue;
+
+ if( aConvert && drawItem.m_Convert && ( drawItem.m_Convert != aConvert ) )
+ continue;
+
+ if( drawItem.Type() == LIB_FIELD_T )
+ continue;
+
+ if( drawItem.Type() == LIB_FIELD_T )
+ {
+ drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, (void*) NULL, aTransform );
+ }
+
+ // Now, draw only the background for items with
+ // m_Fill == FILLED_WITH_BG_BODYCOLOR:
+ drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, (void*) false, aTransform );
+ }
+ }
+
+ // Track the index into the dangling pins list
+ size_t pin_index = 0;
+
+ BOOST_FOREACH( LIB_ITEM& drawItem, drawings )
+ {
+ if( aOnlySelected && !drawItem.IsSelected() )
+ continue;
+
+ // Do not draw an item while moving (the cursor handler does that)
+ if( drawItem.m_Flags & IS_MOVED )
+ continue;
+
+ // Do not draw items not attached to the current part
+ if( aMulti && drawItem.m_Unit && ( drawItem.m_Unit != aMulti ) )
+ continue;
+
+ if( aConvert && drawItem.m_Convert && ( drawItem.m_Convert != aConvert ) )
+ continue;
+
+ if( !aDrawFields && drawItem.Type() == LIB_FIELD_T )
+ continue;
+
+ if( drawItem.Type() == LIB_PIN_T )
+ {
+ LIB_PIN& pin = dynamic_cast<LIB_PIN&>( drawItem );
+
+ uintptr_t flags = 0;
+ if( aShowPinText )
+ flags |= PIN_DRAW_TEXTS;
+
+ if( !aPinsDangling || (aPinsDangling->size() > pin_index && (*aPinsDangling)[pin_index] ) )
+ flags |= PIN_DRAW_DANGLING;
+
+ if( pin.IsPowerConnection() && IsPower() )
+ flags |= PIN_DANGLING_HIDDEN;
+
+ drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, (void*) flags, aTransform );
+
+ ++pin_index;
+ }
+ else if( drawItem.Type() == LIB_FIELD_T )
+ {
+ drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, (void*) NULL, aTransform );
+ }
+ else
+ {
+ bool forceNoFill = drawItem.m_Fill == FILLED_WITH_BG_BODYCOLOR;
+ drawItem.Draw( aPanel, aDc, aOffset, aColor, aDrawMode, (void*) forceNoFill,
+ aTransform );
+ }
+
+ }
+
+ // Enable this to draw the anchor of the component.
+#if 0
+ int len = aDc->DeviceToLogicalXRel( 3 );
+ EDA_RECT* const clipbox = aPanel ? aPanel->GetClipBox() : NULL;
+
+ GRLine( clipbox, aDc, aOffset.x, aOffset.y - len, aOffset.x,
+ aOffset.y + len, 0, aColor );
+ GRLine( clipbox, aDc, aOffset.x - len, aOffset.y, aOffset.x + len,
+ aOffset.y, 0, aColor );
+#endif
+
+ /* Enable this to draw the bounding box around the component to validate
+ * the bounding box calculations. */
+#if 0
+ EDA_RECT bBox = GetBoundingBox( aMulti, aConvert );
+ bBox.RevertYAxis();
+ bBox = aTransform.TransformCoordinate( bBox );
+ bBox.Move( aOffset );
+ GRRect( aPanel ? aPanel->GetClipBox() : NULL, aDc, bBox, 0, LIGHTMAGENTA );
+#endif
+}
+
+
+void LIB_PART::Plot( PLOTTER* aPlotter, int aUnit, int aConvert,
+ const wxPoint& aOffset, const TRANSFORM& aTransform )
+{
+ wxASSERT( aPlotter != NULL );
+
+ aPlotter->SetColor( GetLayerColor( LAYER_DEVICE ) );
+ bool fill = aPlotter->GetColorMode();
+
+ // draw background for filled items using background option
+ // Solid lines will be drawn after the background
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ // Lib Fields are not plotted here, because this plot function
+ // is used to plot schematic items, which have they own fields
+ if( item.Type() == LIB_FIELD_T )
+ continue;
+
+ if( aUnit && item.m_Unit && ( item.m_Unit != aUnit ) )
+ continue;
+
+ if( aConvert && item.m_Convert && ( item.m_Convert != aConvert ) )
+ continue;
+
+ if( item.m_Fill == FILLED_WITH_BG_BODYCOLOR )
+ item.Plot( aPlotter, aOffset, fill, aTransform );
+ }
+
+ // Not filled items and filled shapes are now plotted
+ // (plot only items which are not already plotted)
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ if( item.Type() == LIB_FIELD_T )
+ continue;
+
+ if( aUnit && item.m_Unit && ( item.m_Unit != aUnit ) )
+ continue;
+
+ if( aConvert && item.m_Convert && ( item.m_Convert != aConvert ) )
+ continue;
+
+ if( item.m_Fill != FILLED_WITH_BG_BODYCOLOR )
+ item.Plot( aPlotter, aOffset, fill, aTransform );
+ }
+}
+
+void LIB_PART::PlotLibFields( PLOTTER* aPlotter, int aUnit, int aConvert,
+ const wxPoint& aOffset, const TRANSFORM& aTransform )
+{
+ wxASSERT( aPlotter != NULL );
+
+ aPlotter->SetColor( GetLayerColor( LAYER_FIELDS ) );
+ bool fill = aPlotter->GetColorMode();
+
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ if( item.Type() != LIB_FIELD_T )
+ continue;
+
+ if( aUnit && item.m_Unit && ( item.m_Unit != aUnit ) )
+ continue;
+
+ if( aConvert && item.m_Convert && ( item.m_Convert != aConvert ) )
+ continue;
+
+ // The reference is a special case: we should change the basic text
+ // to add '?' and the part id
+ LIB_FIELD& field = (LIB_FIELD&) item;
+ wxString tmp = field.GetShownText();
+ if( field.GetId() == REFERENCE )
+ {
+ wxString text = field.GetFullText( aUnit );
+ field.SetText( text );
+ }
+ item.Plot( aPlotter, aOffset, fill, aTransform );
+ field.SetText( tmp );
+ }
+}
+
+
+void LIB_PART::RemoveDrawItem( LIB_ITEM* aItem, EDA_DRAW_PANEL* aPanel, wxDC* aDc )
+{
+ wxASSERT( aItem != NULL );
+
+ // none of the MANDATORY_FIELDS may be removed in RAM, but they may be
+ // omitted when saving to disk.
+ if( aItem->Type() == LIB_FIELD_T )
+ {
+ LIB_FIELD* field = (LIB_FIELD*) aItem;
+
+ if( field->GetId() < MANDATORY_FIELDS )
+ {
+ wxLogWarning( _(
+ "An attempt was made to remove the %s field from component %s in library %s." ),
+ GetChars( field->GetName() ), GetChars( GetName() ),
+ GetChars( GetLibraryName() ) );
+ return;
+ }
+ }
+
+ LIB_ITEMS::iterator i;
+
+ for( i = drawings.begin(); i < drawings.end(); i++ )
+ {
+ if( *i == aItem )
+ {
+ if( aDc != NULL )
+ aItem->Draw( aPanel, aDc, wxPoint( 0, 0 ), UNSPECIFIED_COLOR,
+ g_XorMode, NULL, DefaultTransform );
+
+ drawings.erase( i );
+ SetModified();
+ break;
+ }
+ }
+}
+
+
+void LIB_PART::AddDrawItem( LIB_ITEM* aItem )
+{
+ wxASSERT( aItem != NULL );
+
+ drawings.push_back( aItem );
+ drawings.sort();
+}
+
+
+LIB_ITEM* LIB_PART::GetNextDrawItem( LIB_ITEM* aItem, KICAD_T aType )
+{
+ /* Return the next draw object pointer.
+ * If item is NULL return the first item of type in the list.
+ */
+ if( drawings.empty() )
+ return NULL;
+
+ if( aItem == NULL && aType == TYPE_NOT_INIT ) // type is unspecified
+ return &drawings[0];
+
+ // Search for last item
+ size_t idx = 0;
+
+ if( aItem )
+ {
+ for( ; idx < drawings.size(); idx++ )
+ {
+ if( aItem == &drawings[idx] )
+ {
+ idx++; // Prepare the next item search
+ break;
+ }
+ }
+ }
+
+ // Search the next item
+ for( ; idx < drawings.size(); idx++ )
+ {
+ if( aType == TYPE_NOT_INIT || drawings[ idx ].Type() == aType )
+ return &drawings[ idx ];
+ }
+
+ return NULL;
+}
+
+
+void LIB_PART::GetPins( LIB_PINS& aList, int aUnit, int aConvert )
+{
+ /* Notes:
+ * when aUnit == 0: no unit filtering
+ * when aConvert == 0: no convert (shape selection) filtering
+ * when .m_Unit == 0, the body item is common to units
+ * when .m_Convert == 0, the body item is common to shapes
+ */
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ if( item.Type() != LIB_PIN_T ) // we search pins only
+ continue;
+
+ // Unit filtering:
+ if( aUnit && item.m_Unit && ( item.m_Unit != aUnit ) )
+ continue;
+
+ // Shape filtering:
+ if( aConvert && item.m_Convert && ( item.m_Convert != aConvert ) )
+ continue;
+
+ aList.push_back( (LIB_PIN*) &item );
+ }
+}
+
+
+LIB_PIN* LIB_PART::GetPin( const wxString& aNumber, int aUnit, int aConvert )
+{
+ wxString pNumber;
+ LIB_PINS pinList;
+
+ GetPins( pinList, aUnit, aConvert );
+
+ for( size_t i = 0; i < pinList.size(); i++ )
+ {
+ wxASSERT( pinList[i]->Type() == LIB_PIN_T );
+
+ pinList[i]->PinStringNum( pNumber );
+
+ if( aNumber == pNumber )
+ return pinList[i];
+ }
+
+ return NULL;
+}
+
+
+bool LIB_PART::PinsConflictWith( LIB_PART& aOtherPart, bool aTestNums, bool aTestNames,
+ bool aTestType, bool aTestOrientation, bool aTestLength )
+{
+ LIB_PINS thisPinList;
+ GetPins( thisPinList, /* aUnit */ 0, /* aConvert */ 0 );
+
+ BOOST_FOREACH( LIB_PIN* eachThisPin, thisPinList )
+ {
+ wxASSERT( eachThisPin );
+ LIB_PINS otherPinList;
+ aOtherPart.GetPins( otherPinList, /* aUnit */ 0, /* aConvert */ 0 );
+ bool foundMatch = false;
+
+ BOOST_FOREACH( LIB_PIN* eachOtherPin, otherPinList )
+ {
+ wxASSERT( eachOtherPin );
+ // Same position?
+ if( eachThisPin->GetPosition() != eachOtherPin->GetPosition() )
+ continue;
+
+ // Same number?
+ wxString eachThisPinNumber, eachOtherPinNumber;
+ eachThisPin->PinStringNum( eachThisPinNumber );
+ eachOtherPin->PinStringNum( eachOtherPinNumber );
+ if( aTestNums && ( eachThisPinNumber != eachOtherPinNumber ))
+ continue;
+
+ // Same name?
+ if( aTestNames && ( eachThisPin->GetName() != eachOtherPin->GetName() ))
+ continue;
+
+ // Same electrical type?
+ if( aTestType && ( eachThisPin->GetType() != eachOtherPin->GetType() ))
+ continue;
+
+ // Same orientation?
+ if( aTestOrientation && ( eachThisPin->GetOrientation() != eachOtherPin->GetOrientation() ))
+ continue;
+
+ // Same length?
+ if( aTestLength && ( eachThisPin->GetLength() != eachOtherPin->GetLength() ))
+ continue;
+
+ foundMatch = true;
+ }
+
+ if( !foundMatch )
+ {
+ // This means there was not an identical (according to the arguments)
+ // pin at the same position in the other component.
+ return true;
+ }
+ }
+
+ // The loop never gave up, so no conflicts were found.
+ return false;
+}
+
+
+bool LIB_PART::Save( OUTPUTFORMATTER& aFormatter )
+{
+ LIB_FIELD& value = GetValueField();
+
+ // First line: it s a comment (component name for readers)
+ aFormatter.Print( 0, "#\n# %s\n#\n", TO_UTF8( value.GetText() ) );
+
+ // Save data
+ aFormatter.Print( 0, "DEF" );
+
+#if 0 && defined(DEBUG)
+ if( value.GetText() == wxT( "R" ) )
+ {
+ int breakhere = 1;
+ (void) breakhere;
+ }
+#endif
+
+ if( value.IsVisible() )
+ {
+ aFormatter.Print( 0, " %s", TO_UTF8( value.GetText() ) );
+ }
+ else
+ {
+ aFormatter.Print( 0, " ~%s", TO_UTF8( value.GetText() ) );
+ }
+
+ LIB_FIELD& reference = GetReferenceField();
+
+ if( !reference.GetText().IsEmpty() )
+ {
+ aFormatter.Print( 0, " %s", TO_UTF8( reference.GetText() ) );
+ }
+ else
+ {
+ aFormatter.Print( 0, " ~" );
+ }
+
+ aFormatter.Print( 0, " %d %d %c %c %d %c %c\n",
+ 0, m_pinNameOffset,
+ m_showPinNumbers ? 'Y' : 'N',
+ m_showPinNames ? 'Y' : 'N',
+ m_unitCount, m_unitsLocked ? 'L' : 'F',
+ m_options == ENTRY_POWER ? 'P' : 'N' );
+
+ if( !SaveDateAndTime( aFormatter ) )
+ return false;
+
+ LIB_FIELDS fields;
+ GetFields( fields );
+
+ // Mandatory fields:
+ // may have their own save policy so there is a separate loop for them.
+ // Empty fields are saved, because the user may have set visibility,
+ // size and orientation
+ for( int i = 0; i < MANDATORY_FIELDS; ++i )
+ {
+ if( !fields[i].Save( aFormatter ) )
+ return false;
+ }
+
+ // User defined fields:
+ // may have their own save policy so there is a separate loop for them.
+
+ int fieldId = MANDATORY_FIELDS; // really wish this would go away.
+
+ for( unsigned i = MANDATORY_FIELDS; i < fields.size(); ++i )
+ {
+ // There is no need to save empty fields, i.e. no reason to preserve field
+ // names now that fields names come in dynamically through the template
+ // fieldnames.
+ if( !fields[i].GetText().IsEmpty() )
+ {
+ fields[i].SetId( fieldId++ );
+
+ if( !fields[i].Save( aFormatter ) )
+ return false;
+ }
+ }
+
+ // Save the alias list: a line starting by "ALIAS". The first alias is the root
+ // and has the same name as the component. In the old library file format this
+ // alias does not get added to the alias list.
+ if( m_aliases.size() > 1 )
+ {
+ aFormatter.Print( 0, "ALIAS" );
+
+ for( unsigned i = 1; i < m_aliases.size(); i++ )
+ {
+ aFormatter.Print( 0, " %s", TO_UTF8( m_aliases[i]->GetName() ) );
+ }
+
+ aFormatter.Print( 0, "\n" );
+ }
+
+ // Write the footprint filter list
+ if( m_FootprintList.GetCount() != 0 )
+ {
+ aFormatter.Print( 0, "$FPLIST\n" );
+
+ for( unsigned i = 0; i < m_FootprintList.GetCount(); i++ )
+ {
+ aFormatter.Print( 0, " %s\n", TO_UTF8( m_FootprintList[i] ) );
+ }
+
+ aFormatter.Print( 0, "$ENDFPLIST\n" );
+ }
+
+ // Save graphics items (including pins)
+ if( !drawings.empty() )
+ {
+ /* we sort the draw items, in order to have an edition more easy,
+ * when a file editing "by hand" is made */
+ drawings.sort();
+
+ aFormatter.Print( 0, "DRAW\n" );
+
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ if( item.Type() == LIB_FIELD_T )
+ continue;
+
+ if( !item.Save( aFormatter ) )
+ return false;
+ }
+
+ aFormatter.Print( 0, "ENDDRAW\n" );
+ }
+
+ aFormatter.Print( 0, "ENDDEF\n" );
+
+ return true;
+}
+
+
+bool LIB_PART::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
+{
+ int unused;
+ char* p;
+ char* componentName;
+ char* prefix = NULL;
+ char* line;
+
+ bool result;
+ wxString Msg;
+
+ line = aLineReader.Line();
+
+ p = strtok( line, " \t\r\n" );
+
+ if( strcmp( p, "DEF" ) != 0 )
+ {
+ aErrorMsg.Printf( wxT( "DEF command expected in line %d, aborted." ),
+ aLineReader.LineNumber() );
+ return false;
+ }
+
+ // Read DEF line:
+ char drawnum = 0;
+ char drawname = 0;
+
+ if( ( componentName = strtok( NULL, " \t\n" ) ) == NULL // Part name:
+ || ( prefix = strtok( NULL, " \t\n" ) ) == NULL // Prefix name:
+ || ( p = strtok( NULL, " \t\n" ) ) == NULL // NumOfPins:
+ || sscanf( p, "%d", &unused ) != 1
+ || ( p = strtok( NULL, " \t\n" ) ) == NULL // TextInside:
+ || sscanf( p, "%d", &m_pinNameOffset ) != 1
+ || ( p = strtok( NULL, " \t\n" ) ) == NULL // DrawNums:
+ || sscanf( p, "%c", &drawnum ) != 1
+ || ( p = strtok( NULL, " \t\n" ) ) == NULL // DrawNums:
+ || sscanf( p, "%c", &drawname ) != 1
+ || ( p = strtok( NULL, " \t\n" ) ) == NULL // m_unitCount:
+ || sscanf( p, "%d", &m_unitCount ) != 1 )
+ {
+ aErrorMsg.Printf( wxT( "Wrong DEF format in line %d, skipped." ),
+ aLineReader.LineNumber() );
+
+ while( (line = aLineReader.ReadLine()) != NULL )
+ {
+ p = strtok( line, " \t\n" );
+
+ if( p && stricmp( p, "ENDDEF" ) == 0 )
+ break;
+ }
+
+ return false;
+ }
+
+ // Ensure m_unitCount is >= 1 (could be read as 0 in old libraries)
+ if( m_unitCount < 1 )
+ m_unitCount = 1;
+
+ m_showPinNumbers = ( drawnum == 'N' ) ? false : true;
+ m_showPinNames = ( drawname == 'N' ) ? false : true;
+
+ // Copy part name and prefix.
+ LIB_FIELD& value = GetValueField();
+
+ if( componentName[0] != '~' )
+ {
+ m_name = FROM_UTF8( componentName );
+ value.SetText( m_name );
+ }
+ else
+ {
+ m_name = FROM_UTF8( &componentName[1] );
+ value.SetText( m_name );
+ value.SetVisible( false );
+ }
+
+ // Add the root alias to the alias list.
+ m_aliases.push_back( new LIB_ALIAS( m_name, this ) );
+
+ LIB_FIELD& reference = GetReferenceField();
+
+ if( strcmp( prefix, "~" ) == 0 )
+ {
+ reference.Empty();
+ reference.SetVisible( false );
+ }
+ else
+ {
+ reference.SetText( FROM_UTF8( prefix ) );
+ }
+
+ // Copy optional infos
+ if( ( p = strtok( NULL, " \t\n" ) ) != NULL && *p == 'L' )
+ m_unitsLocked = true;
+
+ if( ( p = strtok( NULL, " \t\n" ) ) != NULL && *p == 'P' )
+ m_options = ENTRY_POWER;
+
+ // Read next lines, until "ENDDEF" is found
+ while( ( line = aLineReader.ReadLine() ) != NULL )
+ {
+ p = strtok( line, " \t\r\n" );
+
+ // This is the error flag ( if an error occurs, result = false)
+ result = true;
+
+ if( *line == '#' ) // a comment
+ continue;
+
+ if( p == NULL ) // empty line
+ continue;
+
+ if( line[0] == 'T' && line[1] == 'i' )
+ result = LoadDateAndTime( aLineReader );
+ else if( *line == 'F' )
+ result = LoadField( aLineReader, Msg );
+ else if( strcmp( p, "ENDDEF" ) == 0 ) // End of component description
+ goto ok;
+ else if( strcmp( p, "DRAW" ) == 0 )
+ result = LoadDrawEntries( aLineReader, Msg );
+ else if( strncmp( p, "ALIAS", 5 ) == 0 )
+ {
+ p = strtok( NULL, "\r\n" );
+ result = LoadAliases( p, aErrorMsg );
+ }
+ else if( strncmp( p, "$FPLIST", 5 ) == 0 )
+ result = LoadFootprints( aLineReader, Msg );
+
+ // End line or block analysis: test for an error
+ if( !result )
+ {
+ if( Msg.IsEmpty() )
+ aErrorMsg.Printf( wxT( "error occurred at line %d " ), aLineReader.LineNumber() );
+ else
+ aErrorMsg.Printf( wxT( "error <%s> occurred at line %d " ),
+ GetChars( Msg ), aLineReader.LineNumber() );
+
+ return false;
+ }
+ }
+
+ return false;
+
+ok:
+ // If we are here, this part is O.k. - put it in:
+ drawings.sort();
+
+ return true;
+}
+
+
+bool LIB_PART::LoadDrawEntries( LINE_READER& aLineReader, wxString& aErrorMsg )
+{
+ char* line;
+ LIB_ITEM* newEntry = NULL;
+
+ while( true )
+ {
+ if( !( line = aLineReader.ReadLine() ) )
+ {
+ aErrorMsg = wxT( "file ended prematurely loading component draw element" );
+ return false;
+ }
+
+ if( strncmp( line, "ENDDRAW", 7 ) == 0 )
+ break;
+
+ newEntry = NULL;
+
+ switch( line[0] )
+ {
+ case 'A': // Arc
+ newEntry = ( LIB_ITEM* ) new LIB_ARC( this );
+ break;
+
+ case 'C': // Circle
+ newEntry = ( LIB_ITEM* ) new LIB_CIRCLE( this );
+ break;
+
+ case 'T': // Text
+ newEntry = ( LIB_ITEM* ) new LIB_TEXT( this );
+ break;
+
+ case 'S': // Square
+ newEntry = ( LIB_ITEM* ) new LIB_RECTANGLE( this );
+ break;
+
+ case 'X': // Pin Description
+ newEntry = ( LIB_ITEM* ) new LIB_PIN( this );
+ break;
+
+ case 'P': // Polyline
+ newEntry = ( LIB_ITEM* ) new LIB_POLYLINE( this );
+ break;
+
+ case 'B': // Bezier Curves
+ newEntry = ( LIB_ITEM* ) new LIB_BEZIER( this );
+ break;
+
+ case '#': // Comment
+ continue;
+
+ case '\n':
+ case '\r':
+ case 0: // empty line
+ continue;
+
+ default:
+ aErrorMsg.Printf( wxT( "undefined DRAW command %c" ), line[0] );
+ return false;
+ }
+
+ if( !newEntry->Load( aLineReader, aErrorMsg ) )
+ {
+ aErrorMsg.Printf( wxT( "error '%s' in DRAW command %c" ),
+ GetChars( aErrorMsg ), line[0] );
+ delete newEntry;
+
+ // Flush till end of draw section
+ do
+ {
+ if( !aLineReader.ReadLine() )
+ {
+ aErrorMsg = wxT( "file ended prematurely while attempting "
+ "to flush to end of drawing section." );
+ return false;
+ }
+ } while( strncmp( line, "ENDDRAW", 7 ) != 0 );
+
+ return false;
+ }
+ else
+ {
+ drawings.push_back( newEntry );
+ }
+ }
+
+ return true;
+}
+
+
+bool LIB_PART::LoadAliases( char* aLine, wxString& aErrorMsg )
+{
+ char* text = strtok( aLine, " \t\r\n" );
+
+ while( text )
+ {
+ m_aliases.push_back( new LIB_ALIAS( FROM_UTF8( text ), this ) );
+ text = strtok( NULL, " \t\r\n" );
+ }
+
+ return true;
+}
+
+
+bool LIB_PART::LoadField( LINE_READER& aLineReader, wxString& aErrorMsg )
+{
+ LIB_FIELD* field = new LIB_FIELD( this );
+
+ if( !field->Load( aLineReader, aErrorMsg ) )
+ {
+ delete field;
+ return false;
+ }
+
+ if( field->GetId() < MANDATORY_FIELDS )
+ {
+ LIB_FIELD* fixedField = GetField( field->GetId() );
+
+ // this will fire only if somebody broke a constructor or editor.
+ // MANDATORY_FIELDS are always present in ram resident components, no
+ // exceptions, and they always have their names set, even fixed fields.
+ wxASSERT( fixedField );
+
+ *fixedField = *field;
+
+ if( field->GetId() == VALUE )
+ m_name = field->GetText();
+
+ delete field;
+ }
+ else
+ {
+ drawings.push_back( field );
+ }
+
+ return true;
+}
+
+
+bool LIB_PART::LoadFootprints( LINE_READER& aLineReader, wxString& aErrorMsg )
+{
+ char* line;
+ char* p;
+
+ while( true )
+ {
+ if( !( line = aLineReader.ReadLine() ) )
+ {
+ aErrorMsg = wxT( "file ended prematurely while loading footprints" );
+ return false;
+ }
+
+ p = strtok( line, " \t\r\n" );
+
+ if( stricmp( p, "$ENDFPLIST" ) == 0 )
+ break;
+
+ m_FootprintList.Add( FROM_UTF8( p ) );
+ }
+
+ return true;
+}
+
+
+const EDA_RECT LIB_PART::GetBoundingBox( int aUnit, int aConvert ) const
+{
+ EDA_RECT bBox;
+ bool initialized = false;
+
+ for( unsigned ii = 0; ii < drawings.size(); ii++ )
+ {
+ const LIB_ITEM& item = drawings[ii];
+
+ if( ( item.m_Unit > 0 ) && ( ( m_unitCount > 1 ) && ( aUnit > 0 )
+ && ( aUnit != item.m_Unit ) ) )
+ continue;
+
+ if( item.m_Convert > 0 && ( ( aConvert > 0 ) && ( aConvert != item.m_Convert ) ) )
+ continue;
+
+ if ( ( item.Type() == LIB_FIELD_T ) && !( ( LIB_FIELD& ) item ).IsVisible() )
+ continue;
+
+ if( initialized )
+ bBox.Merge( item.GetBoundingBox() );
+ else
+ {
+ bBox = item.GetBoundingBox();
+ initialized = true;
+ }
+ }
+
+ return bBox;
+}
+
+
+const EDA_RECT LIB_PART::GetBodyBoundingBox( int aUnit, int aConvert ) const
+{
+ EDA_RECT bBox;
+ bool initialized = false;
+
+ for( unsigned ii = 0; ii < drawings.size(); ii++ )
+ {
+ const LIB_ITEM& item = drawings[ii];
+
+ if( ( item.m_Unit > 0 ) && ( ( m_unitCount > 1 ) && ( aUnit > 0 )
+ && ( aUnit != item.m_Unit ) ) )
+ continue;
+
+ if( item.m_Convert > 0 && ( ( aConvert > 0 ) && ( aConvert != item.m_Convert ) ) )
+ continue;
+
+ if ( item.Type() == LIB_FIELD_T )
+ continue;
+
+ if( initialized )
+ bBox.Merge( item.GetBoundingBox() );
+ else
+ {
+ bBox = item.GetBoundingBox();
+ initialized = true;
+ }
+ }
+
+ return bBox;
+}
+
+
+void LIB_PART::deleteAllFields()
+{
+ LIB_ITEMS::iterator it;
+
+ for( it = drawings.begin(); it!=drawings.end(); /* deleting */ )
+ {
+ if( it->Type() != LIB_FIELD_T )
+ {
+ ++it;
+ continue;
+ }
+
+ // 'it' is not advanced, but should point to next in list after erase()
+ it = drawings.erase( it );
+ }
+}
+
+
+void LIB_PART::SetFields( const std::vector <LIB_FIELD>& aFields )
+{
+ deleteAllFields();
+
+ for( unsigned i=0; i<aFields.size(); ++i )
+ {
+ // drawings is a ptr_vector, new and copy an object on the heap.
+ LIB_FIELD* field = new LIB_FIELD( aFields[i] );
+
+ field->SetParent( this );
+ drawings.push_back( field );
+ }
+
+ // Reorder drawings: transparent polygons first, pins and text last.
+ // so texts have priority on screen.
+ drawings.sort();
+}
+
+
+void LIB_PART::GetFields( LIB_FIELDS& aList )
+{
+ LIB_FIELD* field;
+
+ // The only caller of this function is the library field editor, so it
+ // establishes policy here.
+
+ // Grab the MANDATORY_FIELDS first, in expected order given by
+ // enum NumFieldType
+ for( int id=0; id<MANDATORY_FIELDS; ++id )
+ {
+ field = GetField( id );
+
+ // the MANDATORY_FIELDS are exactly that in RAM.
+ wxASSERT( field );
+
+ aList.push_back( *field );
+ }
+
+ // Now grab all the rest of fields.
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ if( item.Type() != LIB_FIELD_T )
+ continue;
+
+ field = ( LIB_FIELD* ) &item;
+
+ if( (unsigned) field->GetId() < MANDATORY_FIELDS )
+ continue; // was added above
+
+ aList.push_back( *field );
+ }
+}
+
+
+LIB_FIELD* LIB_PART::GetField( int aId )
+{
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ if( item.Type() != LIB_FIELD_T )
+ continue;
+
+ LIB_FIELD* field = ( LIB_FIELD* ) &item;
+
+ if( field->GetId() == aId )
+ return field;
+ }
+
+ return NULL;
+}
+
+
+LIB_FIELD* LIB_PART::FindField( const wxString& aFieldName )
+{
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ if( item.Type() != LIB_FIELD_T )
+ continue;
+
+ LIB_FIELD* field = ( LIB_FIELD* ) &item;
+
+ if( field->GetName() == aFieldName )
+ return field;
+ }
+
+ return NULL;
+}
+
+
+LIB_FIELD& LIB_PART::GetValueField()
+{
+ LIB_FIELD* field = GetField( VALUE );
+ wxASSERT( field != NULL );
+ return *field;
+}
+
+
+LIB_FIELD& LIB_PART::GetReferenceField()
+{
+ LIB_FIELD* field = GetField( REFERENCE );
+ wxASSERT( field != NULL );
+ return *field;
+}
+
+
+bool LIB_PART::SaveDateAndTime( OUTPUTFORMATTER& aFormatter )
+{
+ int year, mon, day, hour, min, sec;
+
+ if( m_dateModified == 0 )
+ return true;
+
+ sec = m_dateModified & 63;
+ min = ( m_dateModified >> 6 ) & 63;
+ hour = ( m_dateModified >> 12 ) & 31;
+ day = ( m_dateModified >> 17 ) & 31;
+ mon = ( m_dateModified >> 22 ) & 15;
+ year = ( m_dateModified >> 26 ) + 1990;
+
+ aFormatter.Print( 0, "Ti %d/%d/%d %d:%d:%d\n", year, mon, day, hour, min, sec );
+
+ return true;
+}
+
+
+bool LIB_PART::LoadDateAndTime( char* aLine )
+{
+ int year, mon, day, hour, min, sec;
+
+ year = mon = day = hour = min = sec = 0;
+ strtok( aLine, " \r\t\n" );
+ strtok( NULL, " \r\t\n" );
+
+ if( sscanf( aLine, "%d/%d/%d %d:%d:%d", &year, &mon, &day, &hour, &min, &sec ) != 6 )
+ return false;
+
+ m_dateModified = ( sec & 63 ) + ( ( min & 63 ) << 6 ) +
+ ( ( hour & 31 ) << 12 ) + ( ( day & 31 ) << 17 ) +
+ ( ( mon & 15 ) << 22 ) + ( ( year - 1990 ) << 26 );
+
+ return true;
+}
+
+
+void LIB_PART::SetOffset( const wxPoint& aOffset )
+{
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ item.SetOffset( aOffset );
+ }
+}
+
+
+void LIB_PART::RemoveDuplicateDrawItems()
+{
+ drawings.unique();
+}
+
+
+bool LIB_PART::HasConversion() const
+{
+ for( unsigned ii = 0; ii < drawings.size(); ii++ )
+ {
+ const LIB_ITEM& item = drawings[ii];
+ if( item.m_Convert > 1 )
+ return true;
+ }
+
+ return false;
+}
+
+
+void LIB_PART::ClearStatus()
+{
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ item.m_Flags = 0;
+ }
+}
+
+
+int LIB_PART::SelectItems( EDA_RECT& aRect, int aUnit, int aConvert, bool aEditPinByPin )
+{
+ int itemCount = 0;
+
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ item.ClearFlags( SELECTED );
+
+ if( ( item.m_Unit && item.m_Unit != aUnit )
+ || ( item.m_Convert && item.m_Convert != aConvert ) )
+ {
+ if( item.Type() != LIB_PIN_T )
+ continue;
+
+ // Specific rules for pins.
+ if( aEditPinByPin || m_unitsLocked
+ || ( item.m_Convert && item.m_Convert != aConvert ) )
+ continue;
+ }
+
+ if( item.Inside( aRect ) )
+ {
+ item.SetFlags( SELECTED );
+ itemCount++;
+ }
+ }
+
+ return itemCount;
+}
+
+
+void LIB_PART::MoveSelectedItems( const wxPoint& aOffset )
+{
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ if( !item.IsSelected() )
+ continue;
+
+ item.SetOffset( aOffset );
+ item.m_Flags = 0;
+ }
+
+ drawings.sort();
+}
+
+
+void LIB_PART::ClearSelectedItems()
+{
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ item.m_Flags = 0;
+ }
+}
+
+
+void LIB_PART::DeleteSelectedItems()
+{
+ LIB_ITEMS::iterator item = drawings.begin();
+
+ // We *do not* remove the 2 mandatory fields: reference and value
+ // so skip them (do not remove) if they are flagged selected.
+ // Skip also not visible items.
+ // But I think fields must not be deleted by a block delete command or other global command
+ // because they are not really graphic items
+ while( item != drawings.end() )
+ {
+ if( item->Type() == LIB_FIELD_T )
+ {
+#if 0 // Set to 1 to allows fields deletion on block delete or other global command
+ LIB_FIELD& field = ( LIB_FIELD& ) *item;
+
+ if( (field.GetId() == REFERENCE) || (field.m_FieldId == VALUE) ||
+ (field.m_Attributs & TEXT_NO_VISIBLE) )
+#endif
+ item->ClearFlags( SELECTED );
+ }
+
+ if( !item->IsSelected() )
+ item++;
+ else
+ item = drawings.erase( item );
+ }
+}
+
+
+void LIB_PART::CopySelectedItems( const wxPoint& aOffset )
+{
+ /* *do not* use iterators here, because new items
+ * are added to drawings that is a boost::ptr_vector.
+ * When push_back elements in buffer,
+ * a memory reallocation can happen and will break pointers
+ */
+ unsigned icnt = drawings.size();
+
+ for( unsigned ii = 0; ii < icnt; ii++ )
+ {
+ LIB_ITEM& item = drawings[ii];
+
+ // We *do not* copy fields because they are unique for the whole component
+ // so skip them (do not duplicate) if they are flagged selected.
+ if( item.Type() == LIB_FIELD_T )
+ item.ClearFlags( SELECTED );
+
+ if( !item.IsSelected() )
+ continue;
+
+ item.ClearFlags( SELECTED );
+ LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
+ newItem->SetFlags( SELECTED );
+ drawings.push_back( newItem );
+ }
+
+ MoveSelectedItems( aOffset );
+ drawings.sort();
+}
+
+
+
+void LIB_PART::MirrorSelectedItemsH( const wxPoint& aCenter )
+{
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ if( !item.IsSelected() )
+ continue;
+
+ item.MirrorHorizontal( aCenter );
+ item.m_Flags = 0;
+ }
+
+ drawings.sort();
+}
+
+void LIB_PART::MirrorSelectedItemsV( const wxPoint& aCenter )
+{
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ if( !item.IsSelected() )
+ continue;
+
+ item.MirrorVertical( aCenter );
+ item.m_Flags = 0;
+ }
+
+ drawings.sort();
+}
+
+void LIB_PART::RotateSelectedItems( const wxPoint& aCenter )
+{
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ if( !item.IsSelected() )
+ continue;
+
+ item.Rotate( aCenter );
+ item.m_Flags = 0;
+ }
+
+ drawings.sort();
+}
+
+
+
+LIB_ITEM* LIB_PART::LocateDrawItem( int aUnit, int aConvert,
+ KICAD_T aType, const wxPoint& aPoint )
+{
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ if( ( aUnit && item.m_Unit && ( aUnit != item.m_Unit) )
+ || ( aConvert && item.m_Convert && ( aConvert != item.m_Convert ) )
+ || ( ( item.Type() != aType ) && ( aType != TYPE_NOT_INIT ) ) )
+ continue;
+
+ if( item.HitTest( aPoint ) )
+ return &item;
+ }
+
+ return NULL;
+}
+
+
+LIB_ITEM* LIB_PART::LocateDrawItem( int aUnit, int aConvert, KICAD_T aType,
+ const wxPoint& aPoint, const TRANSFORM& aTransform )
+{
+ /* we use LocateDrawItem( int aUnit, int convert, KICAD_T type, const
+ * wxPoint& pt ) to search items.
+ * because this function uses DefaultTransform as orient/mirror matrix
+ * we temporary copy aTransform in DefaultTransform
+ */
+ LIB_ITEM* item;
+ TRANSFORM transform = DefaultTransform;
+ DefaultTransform = aTransform;
+
+ item = LocateDrawItem( aUnit, aConvert, aType, aPoint );
+
+ // Restore matrix
+ DefaultTransform = transform;
+
+ return item;
+}
+
+
+void LIB_PART::SetUnitCount( int aCount )
+{
+ if( m_unitCount == aCount )
+ return;
+
+ if( aCount < m_unitCount )
+ {
+ LIB_ITEMS::iterator i;
+ i = drawings.begin();
+
+ while( i != drawings.end() )
+ {
+ if( i->m_Unit > aCount )
+ i = drawings.erase( i );
+ else
+ i++;
+ }
+ }
+ else
+ {
+ int prevCount = m_unitCount;
+
+ // We cannot use an iterator here, because when adding items in vector
+ // the buffer can be reallocated, that change the previous value of
+ // .begin() and .end() iterators and invalidate others iterators
+ unsigned imax = drawings.size();
+
+ for( unsigned ii = 0; ii < imax; ii++ )
+ {
+ if( drawings[ii].m_Unit != 1 )
+ continue;
+
+ for( int j = prevCount + 1; j <= aCount; j++ )
+ {
+ LIB_ITEM* newItem = (LIB_ITEM*) drawings[ii].Clone();
+ newItem->m_Unit = j;
+ drawings.push_back( newItem );
+ }
+ }
+
+ drawings.sort();
+ }
+
+ m_unitCount = aCount;
+}
+
+
+void LIB_PART::SetConversion( bool aSetConvert )
+{
+ if( aSetConvert == HasConversion() )
+ return;
+
+ // Duplicate items to create the converted shape
+ if( aSetConvert )
+ {
+ std::vector< LIB_ITEM* > tmp; // Temporarily store the duplicated pins here.
+
+ BOOST_FOREACH( LIB_ITEM& item, drawings )
+ {
+ // Only pins are duplicated.
+ if( item.Type() != LIB_PIN_T )
+ continue;
+
+ if( item.m_Convert == 1 )
+ {
+ LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
+ newItem->m_Convert = 2;
+ tmp.push_back( newItem );
+ }
+ }
+
+ // Transfer the new pins to the LIB_PART.
+ for( unsigned i = 0; i < tmp.size(); i++ )
+ drawings.push_back( tmp[i] );
+ }
+ else
+ {
+ // Delete converted shape items because the converted shape does
+ // not exist
+ LIB_ITEMS::iterator i = drawings.begin();
+
+ while( i != drawings.end() )
+ {
+ if( i->m_Convert > 1 )
+ i = drawings.erase( i );
+ else
+ i++;
+ }
+ }
+}
+
+
+wxArrayString LIB_PART::GetAliasNames( bool aIncludeRoot ) const
+{
+ wxArrayString names;
+
+ LIB_ALIASES::const_iterator it;
+
+ for( it=m_aliases.begin(); it<m_aliases.end(); ++it )
+ {
+ if( !aIncludeRoot && (*it)->IsRoot() )
+ continue;
+
+ names.Add( (*it)->GetName() );
+ }
+
+ return names;
+}
+
+
+bool LIB_PART::HasAlias( const wxString& aName ) const
+{
+ wxCHECK2_MSG( !aName.IsEmpty(), return false,
+ wxT( "Cannot get alias with an empty name, bad programmer." ) );
+
+ for( size_t i = 0; i < m_aliases.size(); i++ )
+ {
+ if( Cmp_KEEPCASE( aName, m_aliases[i]->GetName() ) == 0 )
+ return true;
+ }
+
+ return false;
+}
+
+
+void LIB_PART::SetAliases( const wxArrayString& aAliasList )
+{
+ wxCHECK_RET( !m_library,
+ wxT( "Part aliases cannot be changed when they are owned by a library." ) );
+
+ if( aAliasList == GetAliasNames() )
+ return;
+
+ // Add names not existing in the current component alias list.
+ for( size_t i = 0; i < aAliasList.GetCount(); i++ )
+ {
+ if( HasAlias( aAliasList[ i ] ) )
+ continue;
+
+ m_aliases.push_back( new LIB_ALIAS( aAliasList[ i ], this ) );
+ }
+
+ // Remove names in the current component that are not in the new alias list.
+ LIB_ALIASES::iterator it = m_aliases.begin();
+
+ while( it != m_aliases.end() )
+ {
+ int index = aAliasList.Index( (*it)->GetName(), false );
+
+ if( index != wxNOT_FOUND || (*it)->IsRoot() )
+ ++it;
+ else
+ it = m_aliases.erase( it );
+ }
+}
+
+
+#if 0 // this version looked suspect to me, it did not rename a deleted root
+
+void LIB_PART::RemoveAlias( const wxString& aName )
+{
+ wxCHECK_RET( m_library == NULL,
+ wxT( "Part aliases cannot be changed when they are owned by a library." ) );
+ wxCHECK_RET( !aName.IsEmpty(), wxT( "Cannot get alias with an empty name." ) );
+
+ LIB_ALIASES::iterator it;
+
+ for( it = m_aliases.begin(); it < m_aliases.end(); it++ )
+ {
+ if( Cmp_KEEPCASE( aName, (*it)->GetName() ) == 0 )
+ {
+ m_aliases.erase( it );
+ break;
+ }
+ }
+}
+
+#else
+void LIB_PART::RemoveAlias( const wxString& aName )
+{
+ LIB_ALIAS* a = GetAlias( aName );
+
+ if( a )
+ RemoveAlias( a );
+}
+#endif
+
+
+LIB_ALIAS* LIB_PART::RemoveAlias( LIB_ALIAS* aAlias )
+{
+ wxCHECK_MSG( aAlias, NULL, wxT( "Cannot remove alias by NULL pointer." ) );
+
+ LIB_ALIAS* nextAlias = NULL;
+
+ LIB_ALIASES::iterator it = find( m_aliases.begin(), m_aliases.end(), aAlias );
+
+ if( it != m_aliases.end() )
+ {
+ bool rename = aAlias->IsRoot();
+
+ wxLogTrace( traceSchLibMem,
+ wxT( "%s: part:'%s', alias:'%s', alias count %llu, reference count %ld." ),
+ GetChars( wxString::FromAscii( __WXFUNCTION__ ) ),
+ GetChars( m_name ),
+ GetChars( aAlias->GetName() ),
+ (long long unsigned) m_aliases.size(),
+ m_me.use_count() );
+
+ it = m_aliases.erase( it );
+
+ if( !m_aliases.empty() )
+ {
+ if( it == m_aliases.end() )
+ it = m_aliases.begin();
+
+ nextAlias = *it;
+
+ if( rename )
+ SetName( nextAlias->GetName() );
+ }
+ }
+
+ return nextAlias;
+}
+
+
+void LIB_PART::RemoveAllAliases()
+{
+ // Remove all of the aliases except the root alias.
+ while( m_aliases.size() > 1 )
+ m_aliases.pop_back();
+}
+
+
+LIB_ALIAS* LIB_PART::GetAlias( const wxString& aName )
+{
+ wxCHECK2_MSG( !aName.IsEmpty(), return NULL,
+ wxT( "Cannot get alias with an empty name. Bad programmer!" ) );
+
+ for( size_t i = 0; i < m_aliases.size(); i++ )
+ {
+ if( Cmp_KEEPCASE( aName, m_aliases[i]->GetName() ) == 0 )
+ return m_aliases[i];
+ }
+
+ return NULL;
+}
+
+
+LIB_ALIAS* LIB_PART::GetAlias( size_t aIndex )
+{
+ wxCHECK2_MSG( aIndex < m_aliases.size(), return NULL,
+ wxT( "Illegal alias list index, bad programmer." ) );
+
+ return m_aliases[aIndex];
+}
+
+
+void LIB_PART::AddAlias( const wxString& aName )
+{
+ wxCHECK_RET( !HasAlias( aName ),
+ wxT( "Part <" ) + GetName() + wxT( "> already has an alias <" ) +
+ aName + wxT( ">. Bad programmer." ) );
+
+ m_aliases.push_back( new LIB_ALIAS( aName, this ) );
+}
+
+
+void LIB_PART::SetSubpartIdNotation( int aSep, int aFirstId )
+{
+ m_subpartFirstId = 'A';
+ m_subpartIdSeparator = 0;
+
+ if( aSep == '.' || aSep == '-' || aSep == '_' )
+ m_subpartIdSeparator = aSep;
+
+ if( aFirstId == '1' && aSep != 0 )
+ m_subpartFirstId = aFirstId;
+}
diff --git a/eeschema/class_libentry.h b/eeschema/class_libentry.h
new file mode 100644
index 0000000..b81859e
--- /dev/null
+++ b/eeschema/class_libentry.h
@@ -0,0 +1,773 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_libentry.h
+ */
+
+#ifndef CLASS_LIBENTRY_H
+#define CLASS_LIBENTRY_H
+
+#include <general.h>
+#include <lib_draw_item.h>
+#include <lib_field.h>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <vector>
+
+class LINE_READER;
+class OUTPUTFORMATTER;
+class PART_LIB;
+class LIB_ALIAS;
+class LIB_PART;
+class LIB_FIELD;
+
+
+/// Compiler controlled string compare function, either case independent or not:
+inline int Cmp_KEEPCASE( const wxString& aString1, const wxString& aString2 )
+{
+#ifdef KICAD_KEEPCASE
+ // case specificity, the normal behavior:
+ return aString1.Cmp( aString2 );
+#else
+ // case independence (only for guys who want that: not recommended)
+ return aString1.CmpNoCase( aString2 );
+#endif
+}
+
+
+typedef std::vector<LIB_ALIAS*> LIB_ALIASES;
+typedef boost::shared_ptr<LIB_PART> PART_SPTR; ///< shared pointer to LIB_PART
+typedef boost::weak_ptr<LIB_PART> PART_REF; ///< weak pointer to LIB_PART
+
+
+/* values for member .m_options */
+enum LIBRENTRYOPTIONS
+{
+ ENTRY_NORMAL, // Libentry is a standard part (real or alias)
+ ENTRY_POWER // Libentry is a power symbol
+};
+
+
+/// WXTRACE value to enable schematic library memory deletion debug output.
+extern const wxChar traceSchLibMem[];
+
+
+/**
+ * Part library alias object definition.
+ *
+ * Part aliases are not really parts. An alias uses the part definition
+ * (graphic, pins...) but has its own name, keywords and documentation. Therefore, when
+ * the part is modified, alias of this part are modified. This is a simple
+ * method to create parts that have the same physical layout with different names
+ * such as 74LS00, 74HC00 ... and many op amps.
+ */
+class LIB_ALIAS : public EDA_ITEM
+{
+ /**
+ * Actual LIB_PART referenced by [multiple] aliases.
+ *
+ * @note - Do not delete the shared part. The shared part is shared by
+ * all of the aliases associated with it. A shared LIB_PART will
+ * be deleted when all LIB_ALIASes pointing to it are deleted.
+ */
+ LIB_PART* shared;
+
+ friend class LIB_PART;
+
+protected:
+ wxString name;
+ wxString description; ///< documentation for info
+ wxString keyWords; ///< keyword list (used for search for parts by keyword)
+ wxString docFileName; ///< Associate doc file name
+
+public:
+ LIB_ALIAS( const wxString& aName, LIB_PART* aRootComponent );
+ LIB_ALIAS( const LIB_ALIAS& aAlias, LIB_PART* aRootComponent = NULL );
+
+ virtual ~LIB_ALIAS();
+
+ virtual wxString GetClass() const
+ {
+ return wxT( "LIB_ALIAS" );
+ }
+
+ /**
+ * Function GetPart
+ * gets the shared LIB_PART.
+ *
+ * @return LIB_PART* - the LIB_PART shared by
+ * this LIB_ALIAS with possibly other LIB_ALIASes.
+ */
+ LIB_PART* GetPart() const
+ {
+ return shared;
+ }
+
+ const wxString GetLibraryName();
+
+ bool IsRoot() const;
+
+ PART_LIB* GetLib();
+
+ const wxString& GetName() const { return name; }
+
+ void SetName( const wxString& aName ) { name = aName; }
+
+ void SetDescription( const wxString& aDescription )
+ {
+ description = aDescription;
+ }
+
+ wxString GetDescription() const { return description; }
+
+ void SetKeyWords( const wxString& aKeyWords )
+ {
+ keyWords = aKeyWords;
+ }
+
+ wxString GetKeyWords() const { return keyWords; }
+
+ void SetDocFileName( const wxString& aDocFileName )
+ {
+ docFileName = aDocFileName;
+ }
+
+ wxString GetDocFileName() const { return docFileName; }
+
+ /**
+ * Function SaveDocs
+ * write the entry document information to \a aFormatter in "*.dcm" format.
+ *
+ * @param aFormatter The #OUTPUTFORMATTER to write the alias documents to.
+ * @return True if success writing else false.
+ */
+ bool SaveDoc( OUTPUTFORMATTER& aFormatter );
+
+ /**
+ * KEEPCASE sensitive comparison of the part entry name.
+ */
+ bool operator==( const wxChar* aName ) const;
+ bool operator!=( const wxChar* aName ) const
+ {
+ return !( *this == aName );
+ }
+
+ bool operator==( const LIB_ALIAS* aAlias ) const { return this == aAlias; }
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+};
+
+extern bool operator<( const LIB_ALIAS& aItem1, const LIB_ALIAS& aItem2 );
+
+extern int LibraryEntryCompare( const LIB_ALIAS* aItem1, const LIB_ALIAS* aItem2 );
+
+
+/**
+ * Class LIB_PART
+ * defines a library part object.
+ *
+ * A library part object is typically saved and loaded in a part library file (.lib).
+ * Library parts are different from schematic components.
+ */
+class LIB_PART : public EDA_ITEM
+{
+ friend class PART_LIB;
+ friend class LIB_ALIAS;
+
+ PART_SPTR m_me; ///< http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
+ wxString m_name;
+ int m_pinNameOffset; ///< The offset in mils to draw the pin name. Set to 0
+ ///< to draw the pin name above the pin.
+ bool m_unitsLocked; ///< True if part has multiple units and changing
+ ///< one unit does not automatically change another unit.
+ bool m_showPinNames; ///< Determines if part pin names are visible.
+ bool m_showPinNumbers; ///< Determines if part pin numbers are visible.
+ long m_dateModified; ///< Date the part was last modified.
+ LIBRENTRYOPTIONS m_options; ///< Special part features such as POWER or NORMAL.)
+ int m_unitCount; ///< Number of units (parts) per package.
+ LIB_ITEMS drawings; ///< How to draw this part.
+ wxArrayString m_FootprintList; /**< List of suitable footprint names for the
+ part (wild card names accepted). */
+ LIB_ALIASES m_aliases; ///< List of alias object pointers associated with the
+ ///< part.
+ PART_LIB* m_library; ///< Library the part belongs to if any.
+
+ static int m_subpartIdSeparator; ///< the separator char between
+ ///< the subpart id and the reference
+ ///< like U1A ( m_subpartIdSeparator = 0 ) or U1.A or U1-A
+ static int m_subpartFirstId; ///< the ascii char value to calculate the subpart symbol id
+ ///< from the part number: only 'A', 'a' or '1' can be used,
+ ///< other values have no sense.
+private:
+ void deleteAllFields();
+
+ // LIB_PART() { } // not legal
+
+public:
+
+ LIB_PART( const wxString& aName, PART_LIB* aLibrary = NULL );
+ LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary = NULL );
+
+ virtual ~LIB_PART();
+
+ PART_SPTR SharedPtr()
+ {
+ // clone a shared pointer
+ return m_me;
+ }
+
+ virtual wxString GetClass() const
+ {
+ return wxT( "LIB_PART" );
+ }
+
+ virtual void SetName( const wxString& aName );
+
+ const wxString& GetName() { return m_name; }
+
+ const wxString GetLibraryName();
+
+ PART_LIB* GetLib() { return m_library; }
+
+ wxArrayString GetAliasNames( bool aIncludeRoot = true ) const;
+
+ size_t GetAliasCount() const { return m_aliases.size(); }
+
+ LIB_ALIAS* GetAlias( size_t aIndex );
+
+ LIB_ALIAS* GetAlias( const wxString& aName );
+
+ /**
+ * Function AddAlias
+ *
+ * Add an alias \a aName to the part.
+ *
+ * Duplicate alias names are not added to the alias list. Debug builds will raise an
+ * assertion. Release builds will fail silently.
+ *
+ * @param aName - Name of alias to add.
+ */
+ void AddAlias( const wxString& aName );
+
+ /**
+ * Test if alias \a aName is in part alias list.
+ *
+ * Alias name comparisons are case insensitive.
+ *
+ * @param aName - Name of alias.
+ * @return True if alias name in alias list.
+ */
+ bool HasAlias( const wxString& aName ) const;
+
+ void SetAliases( const wxArrayString& aAliasList );
+
+ void RemoveAlias( const wxString& aName );
+ LIB_ALIAS* RemoveAlias( LIB_ALIAS* aAlias );
+
+ void RemoveAllAliases();
+
+ wxArrayString& GetFootPrints() { return m_FootprintList; }
+
+ /**
+ * Function GetBoundingBox
+ * @return the part bounding box ( in user coordinates )
+ * @param aUnit = unit selection = 0, or 1..n
+ * @param aConvert = 0, 1 or 2
+ * If aUnit == 0, unit is not used
+ * if aConvert == 0 Convert is non used
+ * Invisible fields are not taken in account
+ **/
+ const EDA_RECT GetBoundingBox( int aUnit, int aConvert ) const;
+
+ /**
+ * Function GetBodyBoundingBox
+ * @return the part bounding box ( in user coordinates ) without fields
+ * @param aUnit = unit selection = 0, or 1..n
+ * @param aConvert = 0, 1 or 2
+ * If aUnit == 0, unit is not used
+ * if aConvert == 0 Convert is non used
+ * Fields are not taken in account
+ **/
+ const EDA_RECT GetBodyBoundingBox( int aUnit, int aConvert ) const;
+
+ /**
+ * Function SaveDateAndTime
+ * write the date and time of part to \a aFile in the format:
+ * "Ti yy/mm/jj hh:mm:ss"
+ *
+ * @param aFormatter A reference to an #OUTPUTFORMATTER object containing the
+ * output format to write to.
+ * @return True if the date and time were successfully written to \a aFormatter.
+ */
+ bool SaveDateAndTime( OUTPUTFORMATTER& aFormatter );
+
+ bool LoadDateAndTime( char* aLine );
+
+ /**
+ * Function Save
+ * writes the data structures out to \a aFormatter in the part library "*.lib"
+ * format.
+ *
+ * @param aFormatter A reference to an OUTPUTFORMATTER to write to.
+ * @return True if success writing else false.
+ */
+ bool Save( OUTPUTFORMATTER& aFormatter );
+
+ /**
+ * Load part definition from \a aReader.
+ *
+ * @param aReader A LINE_READER object to load file from.
+ * @param aErrorMsg - Description of error on load failure.
+ * @return True if the load was successful, false if there was an error.
+ */
+ bool Load( LINE_READER& aReader, wxString& aErrorMsg );
+ bool LoadField( LINE_READER& aReader, wxString& aErrorMsg );
+ bool LoadDrawEntries( LINE_READER& aReader, wxString& aErrorMsg );
+ bool LoadAliases( char* aLine, wxString& aErrorMsg );
+ bool LoadFootprints( LINE_READER& aReader, wxString& aErrorMsg );
+
+ bool IsPower() const { return m_options == ENTRY_POWER; }
+ bool IsNormal() const { return m_options == ENTRY_NORMAL; }
+
+ void SetPower() { m_options = ENTRY_POWER; }
+ void SetNormal() { m_options = ENTRY_NORMAL; }
+
+ void LockUnits( bool aLockUnits ) { m_unitsLocked = aLockUnits; }
+ bool UnitsLocked() const { return m_unitsLocked; }
+
+ /**
+ * Function SetFields
+ * overwrites all the existing in this part with fields supplied
+ * in \a aFieldsList. The only known caller of this function is the
+ * library part field editor, and it establishes needed behavior.
+ *
+` * @param aFieldsList is a set of fields to import, removing all previous fields.
+ */
+ void SetFields( const std::vector <LIB_FIELD>& aFieldsList );
+
+ /**
+ * Function GetFields
+ * returns a list of fields withing this part. The only known caller of
+ * this function is the library part field editor, and it establishes
+ * needed behavior.
+ *
+ * @param aList - List to add fields to
+ */
+ void GetFields( LIB_FIELDS& aList );
+
+ /**
+ * Function FindField
+ * finds a field within this part matching \a aFieldName and returns
+ * it or NULL if not found.
+ */
+ LIB_FIELD* FindField( const wxString& aFieldName );
+
+ /**
+ * Return pointer to the requested field.
+ *
+ * @param aId - Id of field to return.
+ * @return The field if found, otherwise NULL.
+ */
+ LIB_FIELD* GetField( int aId );
+
+ /** Return reference to the value field. */
+ LIB_FIELD& GetValueField();
+
+ /** Return reference to the reference designator field. */
+ LIB_FIELD& GetReferenceField();
+
+ /**
+ * Draw part.
+ *
+ * @param aPanel - Window to draw on. Can be NULL if not available.
+ * @param aDc - Device context to draw on.
+ * @param aOffset - Position of part.
+ * @param aMulti - unit if multiple units per part.
+ * @param aConvert - Component conversion (DeMorgan) if available.
+ * @param aDrawMode - Device context drawing mode, see wxDC.
+ * @param aColor - Color to draw part.
+ * @param aTransform - Coordinate adjustment settings.
+ * @param aShowPinText - Show pin text if true.
+ * @param aDrawFields - Draw field text if true otherwise just draw
+ * body items (useful to draw a body in schematic,
+ * because fields of schematic components replace
+ * the lib part fields).
+ * @param aOnlySelected - Draws only the body items that are selected.
+ * Used for block move redraws.
+ * @param aPinsDangling - if not NULL, this should be a pointer to
+ * vector<bool> exactly the same length as the number of pins,
+ * indicating whether each pin is dangling. If NULL, all pins
+ * will be drawn as if they were dangling.
+ */
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDc, const wxPoint& aOffset,
+ int aMulti, int aConvert, GR_DRAWMODE aDrawMode,
+ EDA_COLOR_T aColor = UNSPECIFIED_COLOR,
+ const TRANSFORM& aTransform = DefaultTransform,
+ bool aShowPinText = true, bool aDrawFields = true,
+ bool aOnlySelected = false,
+ const std::vector<bool>* aPinsDangling = NULL );
+
+ /**
+ * Plot lib part to plotter.
+ * Lib Fields not are plotted here, because this plot function
+ * is used to plot schematic items, which have they own fields
+ *
+ * @param aPlotter - Plotter object to plot to.
+ * @param aUnit - Component part to plot.
+ * @param aConvert - Component alternate body style to plot.
+ * @param aOffset - Distance to shift the plot coordinates.
+ * @param aTransform - Component plot transform matrix.
+ */
+ void Plot( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint& aOffset,
+ const TRANSFORM& aTransform );
+
+ /**
+ * Plot Lib Fields only of the part to plotter.
+ * is used to plot the full lib part, outside the schematic
+ *
+ * @param aPlotter - Plotter object to plot to.
+ * @param aUnit - Component part to plot.
+ * @param aConvert - Component alternate body style to plot.
+ * @param aOffset - Distance to shift the plot coordinates.
+ * @param aTransform - Component plot transform matrix.
+ */
+ void PlotLibFields( PLOTTER* aPlotter, int aUnit, int aConvert,
+ const wxPoint& aOffset, const TRANSFORM& aTransform );
+
+ /**
+ * Add a new draw \a aItem to the draw object list.
+ *
+ * @param aItem - New draw object to add to part.
+ */
+ void AddDrawItem( LIB_ITEM* aItem );
+
+ /**
+ * Remove draw \a aItem from list.
+ *
+ * @param aItem - Draw item to remove from list.
+ * @param aPanel - Panel to remove part from.
+ * @param aDc - Device context to remove part from.
+ */
+ void RemoveDrawItem( LIB_ITEM* aItem, EDA_DRAW_PANEL* aPanel = NULL, wxDC* aDc = NULL );
+
+ /**
+ * Return the next draw object pointer.
+ *
+ * @param aItem - Pointer to the current draw item. Setting item NULL
+ * with return the first item of type in the list.
+ * @param aType - type of searched item (filter).
+ * if TYPE_NOT_INIT search for all items types
+ * @return - The next drawing object in the list if found, otherwise NULL.
+ */
+ LIB_ITEM* GetNextDrawItem( LIB_ITEM* aItem = NULL, KICAD_T aType = TYPE_NOT_INIT );
+
+ /**
+ * Return the next pin object from the draw list.
+ *
+ * This is just a pin object specific version of GetNextDrawItem().
+ *
+ * @param aItem - Pointer to the previous pin item, or NULL to get the
+ * first pin in the draw object list.
+ * @return - The next pin object in the list if found, otherwise NULL.
+ */
+ LIB_PIN* GetNextPin( LIB_PIN* aItem = NULL )
+ {
+ return (LIB_PIN*) GetNextDrawItem( (LIB_ITEM*) aItem, LIB_PIN_T );
+ }
+
+
+ /**
+ * Return a list of pin object pointers from the draw item list.
+ *
+ * Note pin objects are owned by the draw list of the part.
+ * Deleting any of the objects will leave list in a unstable state
+ * and will likely segfault when the list is destroyed.
+ *
+ * @param aList - Pin list to place pin object pointers into.
+ * @param aUnit - Unit number of pin to add to list. Set to 0 to
+ * get pins from any part unit.
+ * @param aConvert - Convert number of pin to add to list. Set to 0 to
+ * get pins from any convert of part.
+ */
+ void GetPins( LIB_PINS& aList, int aUnit = 0, int aConvert = 0 );
+
+ /**
+ * Return pin object with the requested pin \a aNumber.
+ *
+ * @param aNumber - Number of the pin to find.
+ * @param aUnit - Unit of the part to find. Set to 0 if a specific
+ * unit number is not required.
+ * @param aConvert - Alternate body style filter (DeMorgan). Set to 0 if
+ * no alternate body style is required.
+ * @return The pin object if found. Otherwise NULL.
+ */
+ LIB_PIN* GetPin( const wxString& aNumber, int aUnit = 0, int aConvert = 0 );
+
+ /**
+ * Function PinsConflictWith
+ * returns true if this part's pins do not match another part's pins. This
+ * is used to detect whether the project cache is out of sync with the
+ * system libs.
+ *
+ * @param aOtherPart - The other library part to test
+ * @param aTestNums - Whether two pins at the same point must have the same number.
+ * @param aTestNames - Whether two pins at the same point must have the same name.
+ * @param aTestType - Whether two pins at the same point must have the same electrical type.
+ * @param aTestOrientation - Whether two pins at the same point must have the same orientation.
+ * @param aTestLength - Whether two pins at the same point must have the same length.
+ */
+ bool PinsConflictWith( LIB_PART& aOtherPart, bool aTestNums, bool aTestNames,
+ bool aTestType, bool aTestOrientation, bool aTestLength );
+
+ /**
+ * Move the part \a aOffset.
+ *
+ * @param aOffset - Offset displacement.
+ */
+ void SetOffset( const wxPoint& aOffset );
+
+ /**
+ * Remove duplicate draw items from list.
+ */
+ void RemoveDuplicateDrawItems();
+
+ /**
+ * Test if part has more than one body conversion type (DeMorgan).
+ *
+ * @return True if part has more than one conversion.
+ */
+ bool HasConversion() const;
+
+ /**
+ * Clears the status flag all draw objects in this part.
+ */
+ void ClearStatus();
+
+ /**
+ * Checks all draw objects of part to see if they are with block.
+ *
+ * Use this method to mark draw objects as selected during block
+ * functions.
+ *
+ * @param aRect - The bounding rectangle to test in draw items are inside.
+ * @param aUnit - The current unit number to test against.
+ * @param aConvert - Are the draw items being selected a conversion.
+ * @param aEditPinByPin - Used to ignore pin selections when in edit pin
+ * by pin mode is enabled.
+ * @return The number of draw objects found inside the block select
+ * rectangle.
+ */
+ int SelectItems( EDA_RECT& aRect, int aUnit, int aConvert, bool aEditPinByPin );
+
+ /**
+ * Clears all the draw items marked by a block select.
+ */
+ void ClearSelectedItems();
+
+ /**
+ * Deletes the select draw items marked by a block select.
+ *
+ * The name and reference field will not be deleted. They are the
+ * minimum drawing items required for any part. Their properties
+ * can be changed but the cannot be removed.
+ */
+ void DeleteSelectedItems();
+
+ /**
+ * Move the selected draw items marked by a block select.
+ */
+ void MoveSelectedItems( const wxPoint& aOffset );
+
+ /**
+ * Make a copy of the selected draw items marked by a block select.
+ *
+ * Fields are not copied. Only part body items are copied.
+ * Copying fields would result in duplicate fields which does not
+ * make sense in this context.
+ */
+ void CopySelectedItems( const wxPoint& aOffset );
+
+ /**
+ * Horizontally (X axis) mirror selected draw items about a point.
+ *
+ * @param aCenter - Center point to mirror around.
+ */
+ void MirrorSelectedItemsH( const wxPoint& aCenter );
+
+ /**
+ * Vertically (Y axis) mirror selected draw items about a point.
+ *
+ * @param aCenter - Center point to mirror around.
+ */
+ void MirrorSelectedItemsV( const wxPoint& aCenter );
+
+ /**
+ * Rotate CCW selected draw items about a point.
+ *
+ * @param aCenter - Center point to mirror around.
+ */
+ void RotateSelectedItems( const wxPoint& aCenter );
+
+ /**
+ * Locate a draw object.
+ *
+ * @param aUnit - Unit number of draw item.
+ * @param aConvert - Body style of draw item.
+ * @param aType - Draw object type, set to 0 to search for any type.
+ * @param aPoint - Coordinate for hit testing.
+ * @return The draw object if found. Otherwise NULL.
+ */
+ LIB_ITEM* LocateDrawItem( int aUnit, int aConvert, KICAD_T aType, const wxPoint& aPoint );
+
+ /**
+ * Locate a draw object (overlaid)
+ *
+ * @param aUnit - Unit number of draw item.
+ * @param aConvert - Body style of draw item.
+ * @param aType - Draw object type, set to 0 to search for any type.
+ * @param aPoint - Coordinate for hit testing.
+ * @param aTransform = the transform matrix
+ * @return The draw object if found. Otherwise NULL.
+ */
+ LIB_ITEM* LocateDrawItem( int aUnit, int aConvert, KICAD_T aType,
+ const wxPoint& aPoint, const TRANSFORM& aTransform );
+
+ /**
+ * Return a reference to the draw item list.
+ *
+ * @return LIB_ITEMS& - Reference to the draw item object list.
+ */
+ LIB_ITEMS& GetDrawItemList() { return drawings; }
+
+ /**
+ * Set the units per part count.
+ *
+ * If the count is greater than the current count, then the all of the
+ * current draw items are duplicated for each additional part. If the
+ * count is less than the current count, all draw objects for units
+ * greater that count are removed from the part.
+ *
+ * @param count - Number of units per package.
+ */
+ void SetUnitCount( int count );
+
+ int GetUnitCount() const { return m_unitCount; }
+
+ /**
+ * Function IsMulti
+ * @return true if the part has multiple units per part.
+ * When happens, the reference has a sub reference ti identify part
+ */
+ bool IsMulti() const { return m_unitCount > 1; }
+
+ /**
+ * Function SubReference
+ * @return the sub reference for part having multiple units per part.
+ * The sub reference identify the part (or unit)
+ * @param aUnit = the part identifier ( 1 to max count)
+ * @param aAddSeparator = true (default) to prpebd the sub ref
+ * by the separator symbol (if any)
+ * Note: this is a static function.
+ */
+ static wxString SubReference( int aUnit, bool aAddSeparator = true );
+
+ // Accessors to sub ref parameters
+ static int GetSubpartIdSeparator() { return m_subpartIdSeparator; }
+
+ /** return a reference to m_subpartIdSeparator,
+ * only for read/save setting functions
+ */
+ static int* SubpartIdSeparatorPtr() { return &m_subpartIdSeparator; }
+
+ static int GetSubpartFirstId() { return m_subpartFirstId; }
+
+ /** return a reference to m_subpartFirstId, only for read/save setting functions
+ */
+ static int* SubpartFirstIdPtr() { return &m_subpartFirstId; }
+
+ /** Set the separator char between the subpart id and the reference
+ * 0 (no separator) or '.' , '-' and '_'
+ * and the ascii char value to calculate the subpart symbol id from the part number:
+ * 'A' or '1' only are allowed. (to print U1.A or U1.1)
+ * if this is a digit, a number is used as id symbol
+ * Note also if the subpart symbol is a digit, the separator cannot be null.
+ * @param aSep = the separator symbol (0 (no separator) or '.' , '-' and '_')
+ * @param aFirstId = the Id of the first part ('A' or '1')
+ */
+ static void SetSubpartIdNotation( int aSep, int aFirstId );
+
+ /**
+ * Set or clear the alternate body style (DeMorgan) for the part.
+ *
+ * If the part already has an alternate body style set and a
+ * asConvert if false, all of the existing draw items for the alternate
+ * body style are remove. If the alternate body style is not set and
+ * asConvert is true, than the base draw items are duplicated and
+ * added to the part.
+ *
+ * @param aSetConvert - Set or clear the part alternate body style.
+ */
+ void SetConversion( bool aSetConvert );
+
+ /**
+ * Set the offset in mils of the pin name text from the pin symbol.
+ *
+ * Set the offset to 0 to draw the pin name above the pin symbol.
+ *
+ * @param aOffset - The offset in mils.
+ */
+ void SetPinNameOffset( int aOffset ) { m_pinNameOffset = aOffset; }
+
+ int GetPinNameOffset() { return m_pinNameOffset; }
+
+ /**
+ * Set or clear the pin name visibility flag.
+ *
+ * @param aShow - True to make the part pin names visible.
+ */
+ void SetShowPinNames( bool aShow ) { m_showPinNames = aShow; }
+
+ bool ShowPinNames() { return m_showPinNames; }
+
+ /**
+ * Set or clear the pin number visibility flag.
+ *
+ * @param aShow - True to make the part pin numbers visible.
+ */
+ void SetShowPinNumbers( bool aShow ) { m_showPinNumbers = aShow; }
+
+ bool ShowPinNumbers() { return m_showPinNumbers; }
+
+ bool operator==( const LIB_PART* aPart ) const { return this == aPart; }
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+};
+
+#endif // CLASS_LIBENTRY_H
diff --git a/eeschema/class_library.cpp b/eeschema/class_library.cpp
new file mode 100644
index 0000000..93a5331
--- /dev/null
+++ b/eeschema/class_library.cpp
@@ -0,0 +1,1208 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_library.cpp
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <eda_doc.h>
+#include <wxstruct.h>
+#include <richio.h>
+#include <config_params.h>
+#include <wildcards_and_files_ext.h>
+#include <project_rescue.h>
+
+#include <general.h>
+#include <class_library.h>
+
+#include <boost/foreach.hpp>
+
+#include <wx/tokenzr.h>
+#include <wx/regex.h>
+
+#define duplicate_name_msg \
+ _( "Library '%s' has duplicate entry name '%s'.\n" \
+ "This may cause some unexpected behavior when loading components into a schematic." )
+
+
+PART_LIB::PART_LIB( int aType, const wxString& aFileName ) :
+ // start @ != 0 so each additional library added
+ // is immediately detectable, zero would not be.
+ m_mod_hash( PART_LIBS::s_modify_generation )
+{
+ type = aType;
+ isModified = false;
+ timeStamp = 0;
+ isCache = false;
+ timeStamp = wxDateTime::Now();
+ versionMajor = 0; // Will be updated after reading the lib file
+ versionMinor = 0; // Will be updated after reading the lib file
+
+ fileName = aFileName;
+
+ if( !fileName.IsOk() )
+ fileName = wxT( "unnamed.lib" );
+}
+
+
+PART_LIB::~PART_LIB()
+{
+ // When the library is destroyed, all of the alias objects on the heap should be deleted.
+ for( LIB_ALIAS_MAP::iterator it = m_amap.begin(); it != m_amap.end(); ++it )
+ {
+ wxLogTrace( traceSchLibMem, wxT( "Removing alias %s from library %s." ),
+ GetChars( it->second->GetName() ), GetChars( GetLogicalName() ) );
+ LIB_PART* part = it->second->GetPart();
+ LIB_ALIAS* alias = it->second;
+ delete alias;
+
+ // When the last alias of a part is destroyed, the part is no longer required and it
+ // too is destroyed.
+ if( part && part->GetAliasCount() == 0 )
+ delete part;
+ }
+
+ m_amap.clear();
+}
+
+
+void PART_LIB::GetEntryNames( wxArrayString& aNames, bool aSort, bool aMakeUpperCase )
+{
+ for( LIB_ALIAS_MAP::iterator it = m_amap.begin(); it!=m_amap.end(); it++ )
+ {
+ if( aMakeUpperCase )
+ {
+ wxString tmp = (*it).first;
+ tmp.MakeUpper();
+ aNames.Add( tmp );
+ }
+ else
+ {
+ aNames.Add( (*it).first );
+ }
+ }
+
+ if( aSort )
+ aNames.Sort();
+}
+
+
+void PART_LIB::GetEntryTypePowerNames( wxArrayString& aNames, bool aSort, bool aMakeUpperCase )
+{
+ for( LIB_ALIAS_MAP::iterator it = m_amap.begin(); it!=m_amap.end(); it++ )
+ {
+ LIB_ALIAS* alias = it->second;
+ LIB_PART* root = alias->GetPart();
+
+ if( !root || !root->IsPower() )
+ continue;
+
+ if( aMakeUpperCase )
+ {
+ wxString tmp = (*it).first;
+ tmp.MakeUpper();
+ aNames.Add( tmp );
+ }
+ else
+ {
+ aNames.Add( (*it).first );
+ }
+ }
+
+ if( aSort )
+ aNames.Sort();
+}
+
+
+/**
+ * Function sortFunction
+ * simple function used as comparator to sort a std::vector<wxArrayString>&.
+ *
+ * @param aItem1 is the first comparison parameter.
+ * @param aItem2 is the second.
+ * @return bool - which item should be put first in the sorted list.
+ */
+bool sortFunction( wxArrayString aItem1, wxArrayString aItem2 )
+{
+ return( aItem1.Item( 0 ) < aItem2.Item( 0 ) );
+}
+
+
+void PART_LIB::SearchEntryNames( std::vector<wxArrayString>& aNames,
+ const wxString& aNameSearch,
+ const wxString& aKeySearch,
+ bool aSort )
+{
+ for( LIB_ALIAS_MAP::iterator it = m_amap.begin(); it != m_amap.end(); ++it )
+ {
+ if( !!aKeySearch && KeyWordOk( aKeySearch, it->second->GetKeyWords() ) )
+ {
+ wxArrayString item;
+
+ item.Add( it->first );
+ item.Add( GetLogicalName() );
+ aNames.push_back( item );
+ }
+
+ if( !aNameSearch.IsEmpty() &&
+ WildCompareString( aNameSearch, it->second->GetName(), false ) )
+ {
+ wxArrayString item;
+
+ item.Add( it->first );
+ item.Add( GetLogicalName() );
+ aNames.push_back( item );
+ }
+ }
+
+ if( aSort )
+ std::sort( aNames.begin(), aNames.end(), sortFunction );
+}
+
+
+void PART_LIB::SearchEntryNames( wxArrayString& aNames, const wxRegEx& aRe, bool aSort )
+{
+ if( !aRe.IsValid() )
+ return;
+
+ LIB_ALIAS_MAP::iterator it;
+
+ for( it = m_amap.begin(); it!=m_amap.end(); it++ )
+ {
+ if( aRe.Matches( it->second->GetKeyWords() ) )
+ aNames.Add( it->first );
+ }
+
+ if( aSort )
+ aNames.Sort();
+}
+
+
+bool PART_LIB::Conflicts( LIB_PART* aPart )
+{
+ wxCHECK_MSG( aPart != NULL, false,
+ wxT( "Cannot test NULL component for conflicts in library " ) + GetName() );
+
+ for( size_t i=0; i<aPart->m_aliases.size(); i++ )
+ {
+ LIB_ALIAS_MAP::iterator it = m_amap.find( aPart->m_aliases[i]->GetName() );
+
+ if( it != m_amap.end() )
+ return true;
+ }
+
+ return false;
+}
+
+
+LIB_ALIAS* PART_LIB::FindEntry( const wxString& aName )
+{
+ LIB_ALIAS_MAP::iterator it = m_amap.find( aName );
+
+ if( it != m_amap.end() )
+ return it->second;
+
+ return NULL;
+}
+
+
+LIB_ALIAS* PART_LIB::GetFirstEntry()
+{
+ if( m_amap.size() )
+ return m_amap.begin()->second;
+ else
+ return NULL;
+}
+
+
+LIB_PART* PART_LIB::FindPart( const wxString& aName )
+{
+#if 0 && defined(DEBUG)
+ if( !aName.Cmp( wxT( "TI_STELLARIS_BOOSTERPACK" ) ) )
+ {
+ int breakhere = 1;
+ (void) breakhere;
+ }
+#endif
+
+ if( LIB_ALIAS* alias = FindEntry( aName ) )
+ {
+ return alias->GetPart();
+ }
+
+ return NULL;
+}
+
+
+bool PART_LIB::HasPowerParts()
+{
+ // return true if at least one power part is found in lib
+ for( LIB_ALIAS_MAP::iterator it = m_amap.begin(); it!=m_amap.end(); it++ )
+ {
+ LIB_ALIAS* alias = it->second;
+ LIB_PART* root = alias->GetPart();
+
+ if( root && root->IsPower() )
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PART_LIB::AddAlias( LIB_ALIAS* aAlias )
+{
+ wxASSERT( aAlias );
+
+#if defined(DEBUG) && 0
+ if( !aAlias->GetName().Cmp( wxT( "TI_STELLARIS_BOOSTERPACK" ) ) )
+ {
+ int breakhere = 1;
+ (void) breakhere;
+ }
+#endif
+
+ LIB_ALIAS_MAP::iterator it = m_amap.find( aAlias->GetName() );
+
+ if( it != m_amap.end() )
+ {
+ wxString msg;
+
+ msg.Printf( _( "Cannot add duplicate alias '%s' to library '%s'." ),
+ GetChars( aAlias->GetName() ),
+ GetChars( fileName.GetName() ) );
+ return false;
+ }
+
+ wxString name = aAlias->GetName();
+
+ m_amap[ name ] = aAlias;
+ isModified = true;
+ ++m_mod_hash;
+
+ return true;
+}
+
+
+bool PART_LIB::AddPart( LIB_PART* aPart )
+{
+ // Conflict detection: See if already existing aliases exist,
+ // and if yes, ask user for continue or abort
+ // Special case: if the library is the library cache of the project,
+ // old aliases are always removed to avoid conflict,
+ // and user is not prompted )
+ if( Conflicts( aPart ) && !IsCache() )
+ {
+ wxFAIL_MSG( wxT( "Cannot add component <" ) + aPart->GetName() +
+ wxT( "> to library <" ) + GetName() + wxT( "> due to name conflict." ) );
+ return false;
+ }
+
+ // add a clone, not the caller's copy
+ LIB_PART* my_part = new LIB_PART( *aPart, this );
+
+ for( size_t i = 0; i < my_part->m_aliases.size(); i++ )
+ {
+ wxString aliasname = my_part->m_aliases[i]->GetName();
+
+ if( LIB_ALIAS* alias = FindAlias( aliasname ) )
+ RemoveEntry( alias );
+
+ m_amap[ aliasname ] = my_part->m_aliases[i];
+ }
+
+ isModified = true;
+ ++m_mod_hash;
+
+ return true;
+}
+
+
+LIB_ALIAS* PART_LIB::RemoveEntry( LIB_ALIAS* aEntry )
+{
+ wxCHECK_MSG( aEntry != NULL, NULL, wxT( "NULL pointer cannot be removed from library." ) );
+
+ LIB_ALIAS_MAP::iterator it = m_amap.find( aEntry->GetName() );
+
+ if( it == m_amap.end() )
+ return NULL;
+
+ // If the entry pointer doesn't match the name it is mapped to in the library, we
+ // have done something terribly wrong.
+ wxCHECK_MSG( *it->second == aEntry, NULL,
+ wxT( "Pointer mismatch while attempting to remove entry <" ) +
+ aEntry->GetName() + wxT( "> from library <" ) + GetName() + wxT( ">." ) );
+
+ LIB_ALIAS* alias = aEntry;
+ LIB_PART* part = alias->GetPart();
+
+ alias = part->RemoveAlias( alias );
+
+ if( !alias )
+ {
+ delete part;
+
+ if( m_amap.size() > 1 )
+ {
+ LIB_ALIAS_MAP::iterator next = it;
+ next++;
+
+ if( next == m_amap.end() )
+ next = m_amap.begin();
+
+ alias = next->second;
+ }
+ }
+
+ m_amap.erase( it );
+ isModified = true;
+ ++m_mod_hash;
+ return alias;
+}
+
+
+LIB_PART* PART_LIB::ReplacePart( LIB_PART* aOldPart, LIB_PART* aNewPart )
+{
+ wxASSERT( aOldPart != NULL );
+ wxASSERT( aNewPart != NULL );
+
+ /* Remove the old root component. The component will automatically be deleted
+ * when all it's aliases are deleted. Do not place any code that accesses
+ * aOldPart inside this loop that gets evaluated after the last alias is
+ * removed in RemoveEntry(). Failure to heed this warning will result in a
+ * segfault.
+ */
+ size_t i = aOldPart->m_aliases.size();
+
+ while( i > 0 )
+ {
+ i -= 1;
+ RemoveEntry( aOldPart->m_aliases[ i ] );
+ }
+
+ LIB_PART* my_part = new LIB_PART( *aNewPart, this );
+
+ // Add new aliases to library alias map.
+ for( i = 0; i < my_part->m_aliases.size(); i++ )
+ {
+ wxString aname = my_part->m_aliases[ i ]->GetName();
+ m_amap[ aname ] = my_part->m_aliases[ i ];
+ }
+
+ isModified = true;
+ ++m_mod_hash;
+ return my_part;
+}
+
+
+LIB_ALIAS* PART_LIB::GetNextEntry( const wxString& aName )
+{
+ if( m_amap.empty() )
+ return NULL;
+
+ LIB_ALIAS_MAP::iterator it = m_amap.find( aName );
+
+ it++;
+
+ if( it == m_amap.end() )
+ it = m_amap.begin();
+
+ return it->second;
+}
+
+
+LIB_ALIAS* PART_LIB::GetPreviousEntry( const wxString& aName )
+{
+ if( m_amap.empty() )
+ return NULL;
+
+ LIB_ALIAS_MAP::iterator it = m_amap.find( aName );
+
+ if( it == m_amap.begin() )
+ it = m_amap.end();
+
+ it--;
+
+ return it->second;
+}
+
+
+bool PART_LIB::Load( wxString& aErrorMsg )
+{
+ FILE* file;
+ char* line;
+ wxString msg;
+
+ if( fileName.GetFullPath().IsEmpty() )
+ {
+ aErrorMsg = _( "The component library file name is not set." );
+ return false;
+ }
+
+ file = wxFopen( fileName.GetFullPath(), wxT( "rt" ) );
+
+ if( file == NULL )
+ {
+ aErrorMsg = _( "The file could not be opened." );
+ return false;
+ }
+
+ FILE_LINE_READER reader( file, fileName.GetFullPath() );
+
+ if( !reader.ReadLine() )
+ {
+ aErrorMsg = _( "The file is empty!" );
+ return false;
+ }
+
+ // There is no header if this is a symbol library.
+ if( type == LIBRARY_TYPE_EESCHEMA )
+ {
+ line = reader.Line();
+
+ header = FROM_UTF8( line );
+
+ wxStringTokenizer tkn( header );
+
+ /*
+ * The file header (first line) in library versions 2.0 and lower
+ * apparently started with EESchema-LIB. Sometime after 2.0, it
+ * was changed to EESchema-LIBRARY. Therefore, the test for
+ * EESchema-LIB will work in both cases. Don't change this unless
+ * backwards compatibility is no longer required.
+ */
+ if( !tkn.HasMoreTokens()
+ || !tkn.GetNextToken().Upper().StartsWith(wxT( "EESCHEMA-LIB" ) ) )
+ {
+ aErrorMsg = _( "The file is NOT an Eeschema library!" );
+ return false;
+ }
+
+ if( !tkn.HasMoreTokens() )
+ {
+ aErrorMsg = _( "The file header is missing version and time stamp information." );
+ return false;
+ }
+
+ if( tkn.GetNextToken() != wxT( "Version" ) || !tkn.HasMoreTokens() )
+ {
+ aErrorMsg = wxT( "The file header version information is invalid." );
+ return false;
+ }
+
+ long major, minor;
+ wxStringTokenizer vers( tkn.GetNextToken(), wxT( "." ) );
+
+ if( !vers.HasMoreTokens() || !vers.GetNextToken().ToLong( &major )
+ || major < 1L || !vers.HasMoreTokens()
+ || !vers.GetNextToken().ToLong( & minor ) || minor < 0L
+ || minor > 99 )
+ {
+#if 0 // Note for developers:
+ // Not sure this warning is very useful: old designs *must* be always loadable
+ wxLogWarning( wxT(
+ "The component library '%s' header version "
+ "number is invalid.\n\nIn future versions of Eeschema this library may not "
+ "load correctly. To resolve this problem open the library in the library "
+ "editor and save it. If this library is the project cache library, save "
+ "the current schematic." ),
+ GetChars( GetName() ) );
+#endif
+ }
+ else
+ {
+ versionMajor = (int) major;
+ versionMinor = (int) minor;
+ }
+ }
+
+ while( reader.ReadLine() )
+ {
+ line = reader.Line();
+
+ if( type == LIBRARY_TYPE_EESCHEMA && strnicmp( line, "$HEADER", 7 ) == 0 )
+ {
+ if( !LoadHeader( reader ) )
+ {
+ aErrorMsg = _( "An error occurred attempting to read the header." );
+ return false;
+ }
+
+ continue;
+ }
+
+ if( strnicmp( line, "DEF", 3 ) == 0 )
+ {
+ // Read one DEF/ENDDEF part entry from library:
+ LIB_PART* part = new LIB_PART( wxEmptyString, this );
+
+ if( part->Load( reader, msg ) )
+ {
+ // Check for duplicate entry names and warn the user about
+ // the potential conflict.
+ if( FindEntry( part->GetName() ) != NULL )
+ {
+ wxString msg = duplicate_name_msg;
+
+ wxLogWarning( msg,
+ GetChars( fileName.GetName() ),
+ GetChars( part->GetName() ) );
+ }
+
+ LoadAliases( part );
+ }
+ else
+ {
+ wxLogWarning( _( "Library '%s' component load error %s." ),
+ GetChars( fileName.GetName() ),
+ GetChars( msg ) );
+ msg.Clear();
+ delete part;
+ }
+ }
+ }
+
+ ++m_mod_hash;
+
+ return true;
+}
+
+
+void PART_LIB::LoadAliases( LIB_PART* aPart )
+{
+ wxCHECK_RET( aPart, wxT( "Cannot load aliases of NULL part. Bad programmer!" ) );
+
+ for( size_t i = 0; i < aPart->m_aliases.size(); i++ )
+ {
+ if( FindEntry( aPart->m_aliases[i]->GetName() ) != NULL )
+ {
+ wxString msg = duplicate_name_msg;
+
+ wxLogError( msg,
+ GetChars( fileName.GetName() ),
+ GetChars( aPart->m_aliases[i]->GetName() ) );
+ }
+
+ wxString aname = aPart->m_aliases[i]->GetName();
+ m_amap[ aname ] = aPart->m_aliases[i];
+ }
+}
+
+
+bool PART_LIB::LoadHeader( LINE_READER& aLineReader )
+{
+ char* line, * text, * data;
+
+ while( aLineReader.ReadLine() )
+ {
+ line = (char*) aLineReader;
+
+ text = strtok( line, " \t\r\n" );
+ data = strtok( NULL, " \t\r\n" );
+
+ if( stricmp( text, "TimeStamp" ) == 0 )
+ timeStamp = atol( data );
+
+ if( stricmp( text, "$ENDHEADER" ) == 0 )
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PART_LIB::LoadDocs( wxString& aErrorMsg )
+{
+ int lineNumber = 0;
+ char line[8000], * name, * text;
+ LIB_ALIAS* entry;
+ FILE* file;
+ wxFileName fn = fileName;
+
+ fn.SetExt( DOC_EXT );
+
+ file = wxFopen( fn.GetFullPath(), wxT( "rt" ) );
+
+ if( file == NULL )
+ {
+ aErrorMsg.Printf( _( "Could not open component document library file '%s'." ),
+ GetChars( fn.GetFullPath() ) );
+ return false;
+ }
+
+ if( GetLine( file, line, &lineNumber, sizeof(line) ) == NULL )
+ {
+ aErrorMsg.Printf( _( "Part document library file '%s' is empty." ),
+ GetChars( fn.GetFullPath() ) );
+ fclose( file );
+ return false;
+ }
+
+ if( strnicmp( line, DOCFILE_IDENT, 10 ) != 0 )
+ {
+ aErrorMsg.Printf( _( "File '%s' is not a valid component library document file." ),
+ GetChars( fn.GetFullPath() ) );
+ fclose( file );
+ return false;
+ }
+
+ while( GetLine( file, line, &lineNumber, sizeof(line) ) )
+ {
+ if( strncmp( line, "$CMP", 4 ) != 0 )
+ {
+ aErrorMsg.Printf( wxT( "$CMP command expected in line %d, aborted." ), lineNumber );
+ fclose( file );
+ return false;
+ }
+
+ // Read one $CMP/$ENDCMP part entry from library:
+ name = strtok( line + 5, "\n\r" );
+
+ wxString cmpname = FROM_UTF8( name );
+
+ entry = FindEntry( cmpname );
+
+ while( GetLine( file, line, &lineNumber, sizeof(line) ) )
+ {
+ if( strncmp( line, "$ENDCMP", 7 ) == 0 )
+ break;
+
+ text = strtok( line + 2, "\n\r" );
+
+ if( entry )
+ {
+ switch( line[0] )
+ {
+ case 'D':
+ entry->SetDescription( FROM_UTF8( text ) );
+ break;
+
+ case 'K':
+ entry->SetKeyWords( FROM_UTF8( text ) );
+ break;
+
+ case 'F':
+ entry->SetDocFileName( FROM_UTF8( text ) );
+ break;
+ }
+ }
+ }
+ }
+
+ fclose( file );
+ return true;
+}
+
+
+bool PART_LIB::Save( OUTPUTFORMATTER& aFormatter )
+{
+ if( isModified )
+ {
+ timeStamp = GetNewTimeStamp();
+ isModified = false;
+ }
+
+ bool success = true;
+
+ try
+ {
+ SaveHeader( aFormatter );
+
+ for( LIB_ALIAS_MAP::iterator it=m_amap.begin(); it!=m_amap.end(); it++ )
+ {
+ if( !it->second->IsRoot() )
+ continue;
+
+ it->second->GetPart()->Save( aFormatter );
+ }
+
+ aFormatter.Print( 0, "#\n#End Library\n" );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+
+bool PART_LIB::SaveDocs( OUTPUTFORMATTER& aFormatter )
+{
+ bool success = true;
+
+ try
+ {
+ aFormatter.Print( 0, "%s\n", DOCFILE_IDENT );
+
+ for( LIB_ALIAS_MAP::iterator it=m_amap.begin(); it!=m_amap.end(); it++ )
+ {
+ if( !it->second->SaveDoc( aFormatter ) )
+ success = false;
+ }
+
+ aFormatter.Print( 0, "#\n#End Doc Library\n" );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+
+bool PART_LIB::SaveHeader( OUTPUTFORMATTER& aFormatter )
+{
+ aFormatter.Print( 0, "%s %d.%d\n", LIBFILE_IDENT,
+ LIB_VERSION_MAJOR, LIB_VERSION_MINOR );
+
+ aFormatter.Print( 0, "#encoding utf-8\n");
+
+#if 0
+ aFormatter.Print( 0, "$HEADER\n" );
+ aFormatter.Print( 0, "TimeStamp %8.8lX\n", m_TimeStamp );
+ aFormatter.Print( 0, "Parts %d\n", m_amap.size() );
+ aFormatter.Print( 0, "$ENDHEADER\n" ) != 1 );
+#endif
+
+ return true;
+}
+
+
+PART_LIB* PART_LIB::LoadLibrary( const wxString& aFileName ) throw( IO_ERROR, boost::bad_pointer )
+{
+ std::auto_ptr<PART_LIB> lib( new PART_LIB( LIBRARY_TYPE_EESCHEMA, aFileName ) );
+
+ wxBusyCursor ShowWait;
+
+ wxString errorMsg;
+
+ if( !lib->Load( errorMsg ) )
+ THROW_IO_ERROR( errorMsg );
+
+ if( USE_OLD_DOC_FILE_FORMAT( lib->versionMajor, lib->versionMinor ) )
+ {
+#if 1
+ // not fatal if error here.
+ lib->LoadDocs( errorMsg );
+#else
+ if( !lib->LoadDocs( errorMsg ) )
+ THROW_IO_ERROR( errorMsg );
+#endif
+ }
+
+ PART_LIB* ret = lib.release();
+
+ return ret;
+}
+
+
+PART_LIB* PART_LIBS::AddLibrary( const wxString& aFileName ) throw( IO_ERROR, boost::bad_pointer )
+{
+ PART_LIB* lib;
+
+#if 1
+ wxFileName fn = aFileName;
+ // Don't reload the library if it is already loaded.
+ lib = FindLibrary( fn.GetName() );
+ if( lib )
+ return lib;
+#endif
+
+ lib = PART_LIB::LoadLibrary( aFileName );
+
+ push_back( lib );
+
+ return lib;
+}
+
+
+PART_LIB* PART_LIBS::AddLibrary( const wxString& aFileName, PART_LIBS::iterator& aIterator )
+ throw( IO_ERROR, boost::bad_pointer )
+{
+#if 1
+ // Don't reload the library if it is already loaded.
+ wxFileName fn( aFileName );
+ PART_LIB* lib = FindLibrary( fn.GetName() );
+
+ if( lib )
+ return lib;
+#endif
+
+ lib = PART_LIB::LoadLibrary( aFileName );
+
+ if( aIterator >= begin() && aIterator < end() )
+ insert( aIterator, lib );
+ else
+ push_back( lib );
+
+ return lib;
+}
+
+
+void PART_LIBS::RemoveLibrary( const wxString& aName )
+{
+ if( aName.IsEmpty() )
+ return;
+
+ for( PART_LIBS::iterator it = begin(); it < end(); ++it )
+ {
+ if( it->GetName().CmpNoCase( aName ) == 0 )
+ {
+ erase( it );
+ return;
+ }
+ }
+}
+
+
+PART_LIB* PART_LIBS::FindLibrary( const wxString& aName )
+{
+ for( PART_LIBS::iterator it = begin(); it!=end(); ++it )
+ {
+ if( it->GetName() == aName )
+ return &*it;
+ }
+
+ return NULL;
+}
+
+
+wxArrayString PART_LIBS::GetLibraryNames( bool aSorted )
+{
+ wxArrayString cacheNames;
+ wxArrayString names;
+
+ BOOST_FOREACH( PART_LIB& lib, *this )
+ {
+ if( lib.IsCache() && aSorted )
+ cacheNames.Add( lib.GetName() );
+ else
+ names.Add( lib.GetName() );
+ }
+
+ // Even sorted, the cache library is always at the end of the list.
+ if( aSorted )
+ names.Sort();
+
+ for( unsigned int i = 0; i<cacheNames.Count(); i++ )
+ names.Add( cacheNames.Item( i ) );
+
+ return names;
+}
+
+
+LIB_PART* PART_LIBS::FindLibPart( const wxString& aPartName, const wxString& aLibraryName )
+{
+ LIB_PART* part = NULL;
+
+ BOOST_FOREACH( PART_LIB& lib, *this )
+ {
+ if( !aLibraryName.IsEmpty() && lib.GetName() != aLibraryName )
+ continue;
+
+ part = lib.FindPart( aPartName );
+
+ if( part )
+ break;
+ }
+
+ return part;
+}
+
+
+LIB_ALIAS* PART_LIBS::FindLibraryEntry( const wxString& aEntryName, const wxString& aLibraryName )
+{
+ LIB_ALIAS* entry = NULL;
+
+ BOOST_FOREACH( PART_LIB& lib, *this )
+ {
+ if( !!aLibraryName && lib.GetName() != aLibraryName )
+ continue;
+
+ entry = lib.FindEntry( aEntryName );
+
+ if( entry )
+ break;
+ }
+
+ return entry;
+}
+
+void PART_LIBS::FindLibraryEntries( const wxString& aEntryName, std::vector<LIB_ALIAS*>& aEntries )
+{
+ BOOST_FOREACH( PART_LIB& lib, *this )
+ {
+ LIB_ALIAS* entry = lib.FindEntry( aEntryName );
+
+ if( entry )
+ aEntries.push_back( entry );
+ }
+}
+
+/* searches all libraries in the list for an entry, using a case insensitive comparison.
+ * Used to find an entry, when the normal (case sensitive) search fails.
+ */
+void PART_LIBS::FindLibraryNearEntries( std::vector<LIB_ALIAS*>& aCandidates,
+ const wxString& aEntryName,
+ const wxString& aLibraryName )
+{
+ BOOST_FOREACH( PART_LIB& lib, *this )
+ {
+ if( !!aLibraryName && lib.GetName() != aLibraryName )
+ continue;
+
+ LIB_ALIAS* entry = lib.GetFirstEntry();
+
+ if( ! entry )
+ continue;
+
+ wxString first_entry_name = entry->GetName();
+ wxString entry_name = first_entry_name;
+
+ for( ;; )
+ {
+ if( entry_name.CmpNoCase( aEntryName ) == 0 )
+ aCandidates.push_back( entry );
+
+ entry = lib.GetNextEntry( entry_name );
+ entry_name = entry->GetName();
+
+ if( first_entry_name == entry_name )
+ break;
+ }
+ }
+}
+
+
+int PART_LIBS::s_modify_generation = 1; // starts at 1 and goes up
+
+
+int PART_LIBS::GetModifyHash()
+{
+ int hash = 0;
+
+ for( PART_LIBS::const_iterator it = begin(); it != end(); ++it )
+ {
+ hash += it->m_mod_hash;
+ }
+
+ return hash;
+}
+
+
+/*
+void PART_LIBS::RemoveCacheLibrary()
+{
+ for( PART_LIBS::iterator it = begin(); it < end(); ++it )
+ {
+ if( it->IsCache() )
+ erase( it-- );
+ }
+}
+*/
+
+
+void PART_LIBS::LibNamesAndPaths( PROJECT* aProject, bool doSave,
+ wxString* aPaths, wxArrayString* aNames )
+ throw( IO_ERROR, boost::bad_pointer )
+{
+ wxString pro = aProject->GetProjectFullName();
+
+ PARAM_CFG_ARRAY ca;
+
+ if( aPaths )
+ ca.push_back( new PARAM_CFG_FILENAME( wxT( "LibDir" ), aPaths ) );
+
+ if( aNames )
+ ca.push_back( new PARAM_CFG_LIBNAME_LIST( wxT( "LibName" ), aNames, GROUP_SCH_LIBS ) );
+
+ if( doSave )
+ {
+ aProject->ConfigSave( Kiface().KifaceSearch(), GROUP_SCH, ca );
+
+ /*
+ {
+ wxString msg = wxString::Format( _(
+ "Unable save project's '%s' file" ),
+ GetChars( pro )
+ );
+ THROW_IO_ERROR( msg );
+ }
+ */
+ }
+ else
+ {
+ if( !aProject->ConfigLoad( Kiface().KifaceSearch(), GROUP_SCH, ca ) )
+ {
+ wxString msg = wxString::Format( _(
+ "Unable to load project's '%s' file" ),
+ GetChars( pro )
+ );
+ THROW_IO_ERROR( msg );
+ }
+ }
+}
+
+
+const wxString PART_LIBS::CacheName( const wxString& aFullProjectFilename )
+{
+ /* until apr 2009 the project cache lib was named: <root_name>.cache.lib,
+ * and after: <root_name>-cache.lib. So if the <name>-cache.lib is not found,
+ * the old file will be renamed and returned.
+ */
+ wxFileName new_name = aFullProjectFilename;
+
+ new_name.SetName( new_name.GetName() + wxT( "-cache" ) );
+ new_name.SetExt( SchematicLibraryFileExtension );
+
+ if( new_name.FileExists() )
+ return new_name.GetFullPath();
+ else
+ {
+ wxFileName old_name = aFullProjectFilename;
+ old_name.SetExt( wxT( "cache.lib" ) );
+
+ if( old_name.FileExists() )
+ {
+ wxRenameFile( old_name.GetFullPath(), new_name.GetFullPath() );
+ return new_name.GetFullPath();
+ }
+ }
+ return wxEmptyString;
+}
+
+
+void PART_LIBS::LoadAllLibraries( PROJECT* aProject ) throw( IO_ERROR, boost::bad_pointer )
+{
+ wxFileName fn;
+ wxString filename;
+ wxString libs_not_found;
+ SEARCH_STACK* lib_search = aProject->SchSearchS();
+
+#if defined(DEBUG) && 1
+ lib_search->Show( __func__ );
+#endif
+
+ wxArrayString lib_names;
+
+ LibNamesAndPaths( aProject, false, NULL, &lib_names );
+
+ // If the list is empty, force loading the standard power symbol library.
+ if( !lib_names.GetCount() )
+ lib_names.Add( wxT( "power" ) );
+
+ wxASSERT( !size() ); // expect to load into "this" empty container.
+
+ for( unsigned i = 0; i < lib_names.GetCount(); ++i )
+ {
+ fn.Clear();
+ fn.SetName( lib_names[i] );
+ fn.SetExt( SchematicLibraryFileExtension );
+
+ // Skip if the file name is not valid..
+ if( !fn.IsOk() )
+ continue;
+
+ if( !fn.FileExists() )
+ {
+ filename = lib_search->FindValidPath( fn.GetFullPath() );
+
+ if( !filename )
+ {
+ libs_not_found += fn.GetName();
+ libs_not_found += wxT( '\n' );
+ continue;
+ }
+ }
+ else
+ {
+ filename = fn.GetFullPath();
+ }
+
+ try
+ {
+ AddLibrary( filename );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _(
+ "Part library '%s' failed to load. Error:\n"
+ "%s" ),
+ GetChars( filename ),
+ GetChars( ioe.errorText )
+ );
+
+ THROW_IO_ERROR( msg );
+ }
+ }
+
+ // add the special cache library.
+ wxString cache_name = CacheName( aProject->GetProjectFullName() );
+ PART_LIB* cache_lib;
+
+ if( !!cache_name )
+ {
+ try
+ {
+ cache_lib = AddLibrary( cache_name );
+ if( cache_lib )
+ cache_lib->SetCache();
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _(
+ "Part library '%s' failed to load.\nError: %s" ),
+ GetChars( cache_name ),
+ GetChars( ioe.errorText )
+ );
+
+ THROW_IO_ERROR( msg );
+ }
+ }
+
+ // Print the libraries not found
+ if( !!libs_not_found )
+ {
+ // Use a different exception type so catch()er can route to proper use
+ // of the HTML_MESSAGE_BOX.
+ THROW_PARSE_ERROR( wxEmptyString, UTF8( __func__ ),
+ UTF8( libs_not_found ), 0, 0 );
+ }
+
+#if defined(DEBUG) && 1
+ printf( "%s: lib_names:\n", __func__ );
+
+ for( PART_LIBS::const_iterator it = begin(); it < end(); ++it )
+ printf( " %s\n", TO_UTF8( it->GetName() ) );
+#endif
+}
diff --git a/eeschema/class_library.h b/eeschema/class_library.h
new file mode 100644
index 0000000..37bf0dd
--- /dev/null
+++ b/eeschema/class_library.h
@@ -0,0 +1,670 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_library.h
+ * @brief Definition for part library class.
+ */
+
+#ifndef CLASS_LIBRARY_H
+#define CLASS_LIBRARY_H
+
+#include <wx/filename.h>
+
+#include <class_libentry.h>
+
+#include <project.h>
+
+class LINE_READER;
+class OUTPUTFORMATTER;
+
+
+/*
+ * Part Library version and file header macros.
+ */
+#define LIB_VERSION_MAJOR 2
+#define LIB_VERSION_MINOR 3
+
+/* Must be the first line of part library (.lib) files. */
+#define LIBFILE_IDENT "EESchema-LIBRARY Version"
+
+#define LIB_VERSION( major, minor ) ( major * 100 + minor )
+
+#define IS_LIB_CURRENT_VERSION( major, minor ) \
+ ( \
+ LIB_VERSION( major1, minor1 ) == \
+ LIB_VERSION( LIB_VERSION_MAJOR, LIB_VERSION_MINOR) \
+ )
+
+/*
+ * Library versions 2.3 and lower use the old separate library (.lib) and
+ * document (.dcm) files. Part libraries after 2.3 merged the library
+ * and document files into a single library file. This macro checks if the
+ * library version supports the old format
+ */
+#define USE_OLD_DOC_FILE_FORMAT( major, minor ) \
+ ( LIB_VERSION( major, minor ) <= LIB_VERSION( 2, 3 ) )
+
+/* Must be the first line of part library document (.dcm) files. */
+#define DOCFILE_IDENT "EESchema-DOCLIB Version 2.0"
+
+#define DOC_EXT wxT( "dcm" )
+
+// Helper class to filter a list of libraries, and/or a list of PART_LIB
+// in dialogs
+class SCHLIB_FILTER
+{
+ wxArrayString m_allowedLibs; ///< a list of lib names to list some libraries
+ ///< if empty: no filter
+ bool m_filterPowerParts; ///< true to filter (show only) power parts
+ bool m_forceLoad; // When true, load a part lib from the lib
+ // which is given in m_allowedLibs[0]
+
+public:
+ SCHLIB_FILTER()
+ {
+ m_filterPowerParts = false;
+ m_forceLoad = false;
+ }
+
+ /**
+ * add a lib name to the allowed libraries
+ */
+ void AddLib( const wxString& aLibName )
+ {
+ m_allowedLibs.Add( aLibName );
+ m_forceLoad = false;
+ }
+
+
+ /**
+ * add a lib name to the allowed libraries
+ */
+ void LoadFrom( const wxString& aLibName )
+ {
+ m_allowedLibs.Clear();
+ m_allowedLibs.Add( aLibName );
+ m_forceLoad = true;
+ }
+
+ /**
+ * Clear the allowed libraries list (allows all libs)
+ */
+ void ClearLibList()
+ {
+ m_allowedLibs.Clear();
+ m_forceLoad = false;
+ }
+
+ /**
+ * set the filtering of power parts
+ */
+ void FilterPowerParts( bool aFilterEnable )
+ {
+ m_filterPowerParts = aFilterEnable;
+ }
+
+ // Accessors
+
+ /**
+ * Function GetFilterPowerParts
+ * @return true if the filtering of power parts is on
+ */
+ bool GetFilterPowerParts() const { return m_filterPowerParts; }
+
+
+ /**
+ * Function GetAllowedLibList
+ * @return am wxArrayString of the names of allowed libs
+ */
+ const wxArrayString& GetAllowedLibList() const { return m_allowedLibs; }
+
+ /**
+ * Function GetLibSource
+ * @return the name of the lib to use to load a part, or an a emty string
+ * Useful to load (in lib editor or lib viewer) a part from a given library
+ */
+ const wxString& GetLibSource() const
+ {
+ static wxString dummy;
+
+ if( m_forceLoad && m_allowedLibs.GetCount() > 0 )
+ return m_allowedLibs[0];
+ else
+ return dummy;
+ }
+};
+
+
+/* Helpers for creating a list of part libraries. */
+class PART_LIB;
+class wxRegEx;
+
+/**
+ * LIB_ALIAS map sorting.
+ */
+struct AliasMapSort
+{
+ bool operator() ( const wxString& aItem1, const wxString& aItem2 ) const
+ {
+ return Cmp_KEEPCASE( aItem1, aItem2 ) < 0;
+ }
+};
+
+/// Alias map used by part library object.
+
+typedef std::map< wxString, LIB_ALIAS*, AliasMapSort > LIB_ALIAS_MAP;
+typedef std::vector< LIB_ALIAS* > LIB_ALIASES;
+typedef boost::ptr_vector< PART_LIB > PART_LIBS_BASE;
+
+
+/**
+ * Class PART_LIBS
+ * is a collection of PART_LIBs. It extends from PROJECT::_ELEM so it can be
+ * hung in the PROJECT. It does not use any UI calls, but rather simply throws
+ * an IO_ERROR when there is a problem.
+ */
+class PART_LIBS : public PART_LIBS_BASE, public PROJECT::_ELEM
+{
+public:
+
+ static int s_modify_generation; ///< helper for GetModifyHash()
+
+ PART_LIBS()
+ {
+ ++s_modify_generation;
+ }
+
+ /// Return the modification hash for all libraries. The value returned
+ /// changes on every library modification.
+ int GetModifyHash();
+
+ /**
+ * Function AddLibrary
+ * allocates and adds a part library to the library list.
+ *
+ * @param aFileName - File name object of part library.
+ * @throw IO_ERROR if there's any problem loading.
+ */
+ PART_LIB* AddLibrary( const wxString& aFileName ) throw( IO_ERROR, boost::bad_pointer );
+
+ /**
+ * Function AddLibrary
+ * inserts a part library into the library list.
+ *
+ * @param aFileName - File name object of part library.
+ * @param aIterator - Iterator to insert library in front of.
+ * @return PART_LIB* - the new PART_LIB, which remains owned by this PART_LIBS container.
+ * @throw IO_ERROR if there's any problem loading.
+ */
+ PART_LIB* AddLibrary( const wxString& aFileName, PART_LIBS::iterator& aIterator )
+ throw( IO_ERROR, boost::bad_pointer );
+
+ /**
+ * Function RemoveLibrary
+ * removes a part library from the library list.
+ *
+ * @param aName - Name of part library to remove.
+ */
+ void RemoveLibrary( const wxString& aName );
+
+ void RemoveAllLibraries() { clear(); }
+
+ /**
+ * Function LoadAllLibraries
+ * loads all of the project's libraries into this container, which should
+ * be cleared before calling it.
+ */
+ void LoadAllLibraries( PROJECT* aProject ) throw( IO_ERROR, boost::bad_pointer );
+
+ /**
+ * Function LibNamesAndPaths
+ * either saves or loads the names of the currently configured part libraries
+ * (without paths).
+ */
+ static void LibNamesAndPaths( PROJECT* aProject, bool doSave,
+ wxString* aPaths, wxArrayString* aNames=NULL )
+ throw( IO_ERROR, boost::bad_pointer );
+
+ /**
+ * Function cacheName
+ * returns the name of the cache library after potentially fixing it from
+ * an older naming scheme. That is, the old file is renamed if needed.
+ * @param aFullProjectFilename - the *.pro filename with absolute path.
+ */
+ static const wxString CacheName( const wxString& aFullProjectFilename );
+
+ /**
+ * Function FindLibrary
+ * finds a part library by \a aName.
+ *
+ * @param aName - Library file name without path or extension to find.
+ * @return Part library if found, otherwise NULL.
+ */
+ PART_LIB* FindLibrary( const wxString& aName );
+
+ /**
+ * Function GetLibraryNames
+ * returns the list of part library file names without path and extension.
+ *
+ * @param aSorted - Sort the list of name if true. Otherwise use the
+ * library load order.
+ * @return The list of library names.
+ */
+ wxArrayString GetLibraryNames( bool aSorted = true );
+
+ /**
+ * Function FindLibPart
+ * searches all libraries in the list for a part.
+ *
+ * A part object will always be returned. If the entry found
+ * is an alias. The root part will be found and returned.
+ *
+ * @param aPartName - Name of part to search for.
+ * @param aLibraryName - Name of the library to search for part.
+ * @return LIB_PART* - The part object if found, otherwise NULL.
+ */
+ LIB_PART* FindLibPart( const wxString& aPartName, const wxString& aLibraryName = wxEmptyString );
+
+ /**
+ * Function FindLibraryEntry
+ * searches all libraries in the list for an entry.
+ *
+ * The object can be either a part or an alias.
+ *
+ * @param aEntryName - Name of entry to search for (case sensitive).
+ * @param aLibraryName - Name of the library to search.
+ * @return The entry object if found, otherwise NULL.
+ */
+ LIB_ALIAS* FindLibraryEntry( const wxString& aEntryName,
+ const wxString& aLibraryName = wxEmptyString );
+
+ /**
+ * Function FindLibraryEntries
+ * searches all libraries in the list for an entry, returns all matches.
+ *
+ * @param aEntryName - Name of entry to search for (case sensitive).
+ * @param aEntries - a std::vector to store entries
+ */
+ void FindLibraryEntries( const wxString& aEntryName, std::vector<LIB_ALIAS*>& aEntries );
+
+ /**
+ * Function FindLibraryNearEntries
+ * Searches all libraries in the list for an entry, using a case insensitive comparison.
+ * Helper function used in dialog to find all candidates.
+ * During a long time, eeschema was using a case insensitive search.
+ * Therefore, for old schematics (<= 2013), or libs, for some components,
+ * the chip name (name of alias in lib) can be broken.
+ * This function can be used to display a list of candidates, in component properties dialog.
+ *
+ * @param aEntryName - Name of entries to search for (case insensitive).
+ * @param aLibraryName - Name of the library to search.
+ * @param aCandidates - a std::vector to store candidates
+ */
+ void FindLibraryNearEntries( std::vector<LIB_ALIAS*>& aCandidates, const wxString& aEntryName,
+ const wxString& aLibraryName = wxEmptyString );
+
+ /**
+ * Function RemoveCacheLibrary
+ * removes all cache libraries from library list.
+ */
+ //void RemoveCacheLibrary();
+
+ int GetLibraryCount() { return size(); }
+
+};
+
+
+/**
+ * Class PART_LIB
+ * is used to load, save, search, and otherwise manipulate
+ * part library files.
+ */
+class PART_LIB
+{
+ int type; ///< Library type indicator.
+ wxFileName fileName; ///< Library file name.
+ wxDateTime timeStamp; ///< Library save time and date.
+ int versionMajor; ///< Library major version number.
+ int versionMinor; ///< Library minor version number.
+ bool isCache; /**< False for the "standard" libraries,
+ True for the library cache */
+ wxString header; ///< first line of loaded library.
+ bool isModified; ///< Library modification status.
+ LIB_ALIAS_MAP m_amap; ///< Map of alias objects associated with the library.
+ int m_mod_hash; ///< incremented each time library is changed.
+
+ friend class LIB_PART;
+ friend class PART_LIBS;
+
+public:
+ PART_LIB( int aType, const wxString& aFileName );
+ ~PART_LIB();
+
+ /**
+ * Function Save
+ * writes library to \a aFormatter.
+ *
+ * @param aFormatter An #OUTPUTFORMATTER object to write the library to.
+ * @return True if success writing to \a aFormatter.
+ */
+ bool Save( OUTPUTFORMATTER& aFormatter );
+
+ /**
+ * Function SaveDocs
+ * write the library document information to \a aFormatter.
+ *
+ * @param aFormatter An #OUTPUTFORMATTER object to write the library documentation to.
+ * @return True if success writing to \a aFormatter.
+ */
+ bool SaveDocs( OUTPUTFORMATTER& aFormatter );
+
+ /**
+ * Load library from file.
+ *
+ * @param aErrorMsg - Error message if load fails.
+ * @return True if load was successful otherwise false.
+ */
+ bool Load( wxString& aErrorMsg );
+
+ bool LoadDocs( wxString& aErrorMsg );
+
+private:
+ bool SaveHeader( OUTPUTFORMATTER& aFormatter );
+
+ bool LoadHeader( LINE_READER& aLineReader );
+ void LoadAliases( LIB_PART* aPart );
+
+public:
+ /**
+ * Get library entry status.
+ *
+ * @return True if there are no entries in the library.
+ */
+ bool IsEmpty() const
+ {
+ return m_amap.empty();
+ }
+
+ /**
+ * Function GetCount
+ * returns the number of entries in the library.
+ *
+ * @return The number of part and alias entries.
+ */
+ int GetCount() const
+ {
+ return m_amap.size();
+ }
+
+ bool IsModified() const
+ {
+ return isModified;
+ }
+
+ bool IsCache() const { return isCache; }
+
+ void SetCache( void ) { isCache = true; }
+
+ /**
+ * Function IsReadOnly
+ * @return true if current user does not have write access to the library file.
+ */
+ bool IsReadOnly() const { return !fileName.IsFileWritable(); }
+
+ /**
+ * Load a string array with the names of all the entries in this library.
+ *
+ * @param aNames - String array to place entry names into.
+ * @param aSort - Sort names if true.
+ * @param aMakeUpperCase - Force entry names to upper case.
+ */
+ void GetEntryNames( wxArrayString& aNames, bool aSort = true,
+ bool aMakeUpperCase = false );
+
+ /**
+ * Load a string array with the names of entries of type POWER in this library.
+ *
+ * @param aNames - String array to place entry names into.
+ * @param aSort - Sort names if true.
+ * @param aMakeUpperCase - Force entry names to upper case.
+ */
+ void GetEntryTypePowerNames( wxArrayString& aNames, bool aSort = true,
+ bool aMakeUpperCase = false );
+
+ /**
+ * Load string array with entry names matching name and/or key word.
+ *
+ * This currently mimics the old behavior of calling KeyWordOk() and
+ * WildCompareString(). The names array will be populated with the
+ * library entry names that meat the search criteria on exit.
+ *
+ * @param aNames - String array to place entry names into.
+ * @param aNameSearch - Name wild card search criteria.
+ * @param aKeySearch - Key word search criteria.
+ * @param aSort - Sort names if true.
+ */
+ void SearchEntryNames( std::vector<wxArrayString>& aNames,
+ const wxString& aNameSearch = wxEmptyString,
+ const wxString& aKeySearch = wxEmptyString,
+ bool aSort = true );
+
+ /**
+ * Find parts in library by key word regular expression search.
+ *
+ * @param aNames - String array to place found part names into.
+ * @param aRe - Regular expression used to search part key words.
+ * @param aSort - Sort part name list.
+ */
+ void SearchEntryNames( wxArrayString& aNames, const wxRegEx& aRe, bool aSort = true );
+
+ /**
+ * Checks \a aPart for name conflict in the library.
+ *
+ * @param aPart - The part to check.
+ * @return True if a conflict exists. Otherwise false.
+ */
+ bool Conflicts( LIB_PART* aPart );
+
+ /**
+ * Find entry by name.
+ *
+ * @param aName - Name of entry, case sensitive.
+ * @return Entry if found. NULL if not found.
+ */
+ LIB_ALIAS* FindEntry( const wxString& aName );
+
+ /**
+ * Find part by \a aName.
+ *
+ * This is a helper for FindEntry so casting a LIB_ALIAS pointer to
+ * a LIB_PART pointer is not required.
+ *
+ * @param aName - Name of part, case sensitive.
+ * @return LIB_PART* - part if found, else NULL.
+ */
+ LIB_PART* FindPart( const wxString& aName );
+
+ /**
+ * Find alias by \a nName.
+ *
+ * @param aName - Name of alias, case sensitive.
+ * @return Alias if found. NULL if not found.
+ */
+ LIB_ALIAS* FindAlias( const wxString& aName )
+ {
+ return (LIB_ALIAS*) FindEntry( aName );
+ }
+
+ /**
+ * Add a new \a aAlias entry to the library.
+ *
+ * First check if a part or alias with the same name already exists
+ * in the library and add alias if no conflict occurs. Once the alias
+ * is added to the library it is owned by the library. Deleting the
+ * alias pointer will render the library unstable. Use RemoveEntry to
+ * remove the alias from the library.
+ *
+ * @param aAlias - Alias to add to library.
+ * @return True if alias added to library. False if a conflict exists.
+ */
+ bool AddAlias( LIB_ALIAS* aAlias );
+
+ /**
+ * Add \a aPart entry to library.
+ * Note a part can have an alias list,
+ * so these alias will be added in library.
+ * Conflicts can happen if aliases are already existing.
+ * User is asked to choose what alias is removed (existing, or new)
+ *
+ * @param aPart - Part to add, caller retains ownership, a clone is added.
+ * @return bool - true iff successful.
+ */
+ bool AddPart( LIB_PART* aPart );
+
+ /**
+ * Safely remove \a aEntry from the library and return the next entry.
+ *
+ * The next entry returned depends on the entry being removed. If the entry being
+ * remove also removes the part, then the next entry from the list is returned.
+ * If the entry being used only removes an alias from a part, then the next alias
+ * of the part is returned.
+ *
+ * @param aEntry - Entry to remove from library.
+ * @return The next entry in the library or NULL if the library is empty.
+ */
+ LIB_ALIAS* RemoveEntry( LIB_ALIAS* aEntry );
+
+ /**
+ * Replace an existing part entry in the library.
+ * Note a part can have an alias list,
+ * so these alias will be added in library (and previously existing alias removed)
+ * @param aOldPart - The part to replace.
+ * @param aNewPart - The new part.
+ */
+ LIB_PART* ReplacePart( LIB_PART* aOldPart, LIB_PART* aNewPart );
+
+ /**
+ * Return the first entry in the library.
+ *
+ * @return The first entry or NULL if the library has no entries.
+ */
+ LIB_ALIAS* GetFirstEntry();
+
+ /**
+ * Find next library entry by \a aName.
+ *
+ * If the name of the entry is the last entry in the library, the first
+ * entry in the list is returned.
+ *
+ * @param aName - Name of current entry.
+ * @return Next entry if entry name is found. Otherwise NULL.
+ */
+ LIB_ALIAS* GetNextEntry( const wxString& aName );
+
+ /**
+ * Find previous library entry by \a aName.
+ *
+ * If the name of the entry is the first entry in the library, the last
+ * entry in the list is returned.
+ *
+ * @param aName - Name of current entry.
+ * @return Previous entry if entry name is found, otherwise NULL.
+ */
+ LIB_ALIAS* GetPreviousEntry( const wxString& aName );
+
+ /**
+ * Return the file name without path or extension.
+ *
+ * @return Name of library file.
+ */
+ const wxString GetName() const { return fileName.GetName(); }
+
+ /**
+ * Function GetFullFileName
+ * returns the full file library name with path and extension.
+ *
+ * @return wxString - Full library file name with path and extension.
+ */
+ wxString GetFullFileName() { return fileName.GetFullPath(); }
+
+ /**
+ * Function GetLogicalName
+ * returns the logical name of the library.
+ * @return wxString - The logical name of this library.
+ */
+ const wxString GetLogicalName()
+ {
+ /* for now is the filename without path or extension.
+
+ Technically the library should not know its logical name!
+ This will eventually come out of a pair of lookup tables using a
+ reverse lookup using the full name or library pointer as a key.
+ Search will be by project lookup table and then user lookup table if
+ not found.
+ */
+ return fileName.GetName();
+ }
+
+
+ /**
+ * Function SetFileName
+ * sets the part library file name.
+ *
+ * @param aFileName - New library file name.
+ */
+ void SetFileName( const wxString& aFileName )
+ {
+ if( aFileName != fileName.GetFullName() )
+ fileName = aFileName;
+ }
+
+ /**
+ * Function LoadLibrary
+ * allocates and loads a part library file.
+ *
+ * @param aFileName - File name of the part library to load.
+ * @return PART_LIB* - the allocated and loaded PART_LIB, which is owned by
+ * the caller.
+ * @throw IO_ERROR if there's any problem loading the library.
+ */
+ static PART_LIB* LoadLibrary( const wxString& aFileName ) throw( IO_ERROR, boost::bad_pointer );
+
+ /**
+ * Function HasPowerParts
+ * @return true if at least one power part is found in lib
+ * Useful to select or list only libs containing power parts
+ */
+ bool HasPowerParts();
+};
+
+
+/**
+ * Case insensitive library name comparison.
+ */
+bool operator==( const PART_LIB& aLibrary, const wxString& aName );
+bool operator!=( const PART_LIB& aLibrary, const wxString& aName );
+
+#endif // CLASS_LIBRARY_H
diff --git a/eeschema/class_netlist_object.cpp b/eeschema/class_netlist_object.cpp
new file mode 100644
index 0000000..760af59
--- /dev/null
+++ b/eeschema/class_netlist_object.cpp
@@ -0,0 +1,423 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_netlist_object.cpp
+ * @brief Class NETLIST_OBJECT to handle 1 item connected (in netlist and erc calculations)
+ */
+
+#include <fctsys.h>
+#include <macros.h>
+#include <schframe.h>
+
+#include <sch_component.h>
+#include <class_netlist_object.h>
+
+#include <wx/regex.h>
+
+
+/**
+ * The regular expression string for label bus notation. Valid bus labels are defined as
+ * one or more non-whitespace characters from the beginning of the string followed by the
+ * bus notation [nn...mm] with no characters after the closing bracket.
+ */
+static wxRegEx busLabelRe( wxT( "^([^[:space:]]+)(\\[[\\d]+\\.+[\\d]+\\])$" ), wxRE_ADVANCED );
+
+
+bool IsBusLabel( const wxString& aLabel )
+{
+ wxCHECK_MSG( busLabelRe.IsValid(), false,
+ wxT( "Invalid regular expression in IsBusLabel()." ) );
+
+ return busLabelRe.Matches( aLabel );
+}
+
+
+#if defined(DEBUG)
+
+#include <iostream>
+const char* ShowType( NETLIST_ITEM_T aType )
+{
+ const char* ret;
+
+ switch( aType )
+ {
+ case NET_SEGMENT:
+ ret = "segment"; break;
+
+ case NET_BUS:
+ ret = "bus"; break;
+
+ case NET_JUNCTION:
+ ret = "junction"; break;
+
+ case NET_LABEL:
+ ret = "label"; break;
+
+ case NET_HIERLABEL:
+ ret = "hierlabel"; break;
+
+ case NET_GLOBLABEL:
+ ret = "glabel"; break;
+
+ case NET_BUSLABELMEMBER:
+ ret = "buslblmember"; break;
+
+ case NET_HIERBUSLABELMEMBER:
+ ret = "hierbuslblmember"; break;
+
+ case NET_GLOBBUSLABELMEMBER:
+ ret = "gbuslblmember"; break;
+
+ case NET_SHEETBUSLABELMEMBER:
+ ret = "sbuslblmember"; break;
+
+ case NET_SHEETLABEL:
+ ret = "sheetlabel"; break;
+
+ case NET_PINLABEL:
+ ret = "pinlabel"; break;
+
+ case NET_PIN:
+ ret = "pin"; break;
+
+ case NET_NOCONNECT:
+ ret = "noconnect"; break;
+
+ default:
+ ret = "??"; break;
+ }
+
+ return ret;
+}
+
+
+void NETLIST_OBJECT::Show( std::ostream& out, int ndx ) const
+{
+ wxString path = m_SheetPath.PathHumanReadable();
+
+ out << "<netItem ndx=\"" << ndx << '"' <<
+ " type=\"" << ShowType( m_Type ) << '"' <<
+ " netCode=\"" << GetNet() << '"' <<
+ " sheet=\"" << TO_UTF8( path ) << '"' <<
+ ">\n";
+
+ out << " <start " << m_Start << "/> <end " << m_End << "/>\n";
+
+ if( !m_Label.IsEmpty() )
+ out << " <label>" << m_Label.mb_str() << "</label>\n";
+
+ out << " <sheetpath>" << m_SheetPath.PathHumanReadable().mb_str() << "</sheetpath>\n";
+
+ switch( m_Type )
+ {
+ case NET_PIN:
+ /* GetRef() needs to be const
+ out << " <refOfComp>" << GetComponentParent()->GetRef(&m_SheetPath).mb_str()
+ << "</refOfComp>\n";
+ */
+
+ if( m_Comp )
+ m_Comp->Show( 1, out );
+
+ break;
+
+ default:
+ // not all the m_Comp classes have working Show functions.
+ ;
+ }
+
+/* was segfault-ing
+ if( m_Comp )
+ m_Comp->Show( 1, out ); // labels may not have good Show() funcs?
+ else
+ out << " m_Comp==NULL\n";
+*/
+
+ out << "</netItem>\n";
+}
+
+#endif
+
+
+NETLIST_OBJECT::NETLIST_OBJECT()
+{
+ m_Type = NET_ITEM_UNSPECIFIED; /* Type of this item (see NETLIST_ITEM_T enum) */
+ m_Comp = NULL; /* Pointer on the library item that created this net object
+ * (the parent)*/
+ m_Link = NULL; /* For SCH_SHEET_PIN:
+ * Pointer to the hierarchy sheet that contains this
+ * SCH_SHEET_PIN For Pins: pointer to the component that
+ * contains this pin
+ */
+ m_Flag = 0; /* flag used in calculations */
+ m_ElectricalType = 0; /* Has meaning only for Pins and hierarchical pins: electrical
+ * type */
+ m_netCode = 0; /* net code for all items except BUS labels because a BUS
+ * label has as many net codes as bus members
+ */
+ m_BusNetCode = 0; /* Used for BUS connections */
+ m_Member = 0; /* for labels type NET_BUSLABELMEMBER ( bus member created
+ * from the BUS label ) member number
+ */
+ m_ConnectionType = UNCONNECTED;
+ m_PinNum = 0; /* pin number ( 1 long = 4 bytes -> 4 ascii codes) */
+ m_netNameCandidate = NULL; /* a pointer to a NETLIST_OBJECT type label connected to this
+ * object used to give a name to the net
+ */
+}
+
+
+// Copy constructor
+NETLIST_OBJECT::NETLIST_OBJECT( NETLIST_OBJECT& aSource )
+{
+ *this = aSource;
+}
+
+
+NETLIST_OBJECT::~NETLIST_OBJECT()
+{
+}
+
+
+// return true if the object is a label of any type
+bool NETLIST_OBJECT::IsLabelType() const
+{
+ return m_Type == NET_LABEL
+ || m_Type == NET_GLOBLABEL || m_Type == NET_HIERLABEL
+ || m_Type == NET_BUSLABELMEMBER || m_Type == NET_GLOBBUSLABELMEMBER
+ || m_Type == NET_HIERBUSLABELMEMBER
+ || m_Type == NET_PINLABEL;
+}
+
+bool NETLIST_OBJECT::IsLabelConnected( NETLIST_OBJECT* aNetItem )
+{
+ if( aNetItem == this ) // Don't compare the same net list object.
+ return false;
+
+ int at = m_Type;
+ int bt = aNetItem->m_Type;
+
+ if( ( at == NET_HIERLABEL || at == NET_HIERBUSLABELMEMBER )
+ && ( bt == NET_SHEETLABEL || bt == NET_SHEETBUSLABELMEMBER ) )
+ {
+ if( m_SheetPath == aNetItem->m_SheetPathInclude )
+ {
+ return true; //connected!
+ }
+ }
+ else if( ( at == NET_GLOBLABEL ) && ( bt == NET_GLOBLABEL ) )
+ {
+ if( m_Label == aNetItem->m_Label )
+ return true; //connected!
+ }
+
+ return false; //these two are unconnected
+}
+
+
+void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItems )
+{
+ wxCHECK_RET( IsBusLabel( m_Label ),
+ wxT( "<" ) + m_Label + wxT( "> is not a valid bus label." ) );
+
+ if( m_Type == NET_HIERLABEL )
+ m_Type = NET_HIERBUSLABELMEMBER;
+ else if( m_Type == NET_GLOBLABEL )
+ m_Type = NET_GLOBBUSLABELMEMBER;
+ else if( m_Type == NET_SHEETLABEL )
+ m_Type = NET_SHEETBUSLABELMEMBER;
+ else if( m_Type == NET_LABEL )
+ m_Type = NET_BUSLABELMEMBER;
+ else
+ wxCHECK_RET( false, wxT( "Net list object type is not valid." ) );
+
+ unsigned i;
+ wxString tmp, busName, busNumber;
+ long begin, end, member;
+
+ busName = busLabelRe.GetMatch( m_Label, 1 );
+ busNumber = busLabelRe.GetMatch( m_Label, 2 );
+
+ /* Search for '[' because a bus label is like "busname[nn..mm]" */
+ i = busNumber.Find( '[' );
+ i++;
+
+ while( i < busNumber.Len() && busNumber[i] != '.' )
+ {
+ tmp.Append( busNumber[i] );
+ i++;
+ }
+
+ tmp.ToLong( &begin );
+
+ while( i < busNumber.Len() && busNumber[i] == '.' )
+ i++;
+
+ tmp.Empty();
+
+ while( i < busNumber.Len() && busNumber[i] != ']' )
+ {
+ tmp.Append( busNumber[i] );
+ i++;
+ }
+
+ tmp.ToLong( &end );
+
+ if( begin < 0 )
+ begin = 0;
+
+ if( end < 0 )
+ end = 0;
+
+ if( begin > end )
+ std::swap( begin, end );
+
+ member = begin;
+ tmp = busName;
+ tmp << member;
+ m_Label = tmp;
+ m_Member = member;
+
+ for( member++; member <= end; member++ )
+ {
+ NETLIST_OBJECT* item = new NETLIST_OBJECT( *this );
+
+ // Conversion of bus label to the root name + the current member id.
+ tmp = busName;
+ tmp << member;
+ item->m_Label = tmp;
+ item->m_Member = member;
+
+ aNetListItems.push_back( item );
+ }
+}
+
+
+bool NETLIST_OBJECT::IsLabelGlobal() const
+{
+ // return true if the object is a global label
+ // * a actual global label
+ // * a pin label coming from a invisible power pin
+ return ( m_Type == NET_PINLABEL ) ||
+ ( m_Type == NET_GLOBLABEL ) ||
+ ( m_Type == NET_GLOBBUSLABELMEMBER );
+}
+
+
+bool NETLIST_OBJECT::IsLabelBusMemberType() const
+{
+ // return true if the object is a bus label member build from a
+ // schematic bus label (like label[xx..yy)
+ // They are labels with very specific properties, especially for connection
+ // between them: 2 bus label members can be connected only
+ // if they have the same member value.
+ return ( m_Type == NET_SHEETBUSLABELMEMBER ) ||
+ ( m_Type == NET_BUSLABELMEMBER ) ||
+ ( m_Type == NET_HIERBUSLABELMEMBER ) ||
+ ( m_Type == NET_GLOBBUSLABELMEMBER );
+}
+
+
+/*
+ * return the net name of the item
+ */
+wxString NETLIST_OBJECT::GetNetName() const
+{
+ if( m_netNameCandidate == NULL )
+ return wxEmptyString;
+
+ wxString netName;
+
+ if( m_netNameCandidate->m_Type == NET_PIN )
+ return GetShortNetName();
+
+ if( !m_netNameCandidate->IsLabelGlobal() )
+ {
+ // usual net name, prefix it by the sheet path
+ netName = m_netNameCandidate->m_SheetPath.PathHumanReadable();
+ }
+
+ netName += m_netNameCandidate->m_Label;
+
+ return netName;
+}
+
+/**
+ * return the short net name of the item i.e. the net name
+ * from the "best" label without any prefix.
+ * 2 different nets can have the same short name
+ */
+wxString NETLIST_OBJECT::GetShortNetName() const
+{
+ if( m_netNameCandidate == NULL )
+ return wxEmptyString;
+
+ wxString netName;
+
+ if( m_netNameCandidate->m_Type == NET_PIN )
+ {
+ SCH_COMPONENT* link = m_netNameCandidate->GetComponentParent();
+ if( link ) // Should be always true
+ {
+ netName = wxT("Net-(");
+ netName << link->GetRef( &m_netNameCandidate->m_SheetPath );
+ netName << wxT("-Pad")
+ << LIB_PIN::PinStringNum( m_netNameCandidate->m_PinNum )
+ << wxT(")");
+ }
+ }
+ else
+ netName = m_netNameCandidate->m_Label;
+
+ return netName;
+}
+
+/**
+ * Set m_netNameCandidate to a connected item which will
+ * be used to calcule the net name of the item
+ * Obviously the candidate can be only a label
+ * If there is no label on the net, a pad name will be
+ * used to build a net name (something like Cmp<REF>_Pad<PAD_NAME>
+ * @param aCandidate = the connected item candidate
+ */
+void NETLIST_OBJECT::SetNetNameCandidate( NETLIST_OBJECT* aCandidate )
+{
+ switch( aCandidate->m_Type )
+ {
+ case NET_HIERLABEL:
+ case NET_LABEL:
+ case NET_PINLABEL:
+ case NET_GLOBLABEL:
+ case NET_GLOBBUSLABELMEMBER:
+ case NET_SHEETBUSLABELMEMBER:
+ case NET_PIN:
+ m_netNameCandidate = aCandidate;
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/eeschema/class_netlist_object.h b/eeschema/class_netlist_object.h
new file mode 100644
index 0000000..3e726d4
--- /dev/null
+++ b/eeschema/class_netlist_object.h
@@ -0,0 +1,483 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_netlist_object.h
+ * @brief Definition of the NETLIST_OBJECT class.
+ */
+
+#ifndef _CLASS_NETLIST_OBJECT_H_
+#define _CLASS_NETLIST_OBJECT_H_
+
+
+#include <sch_sheet_path.h>
+#include <lib_pin.h> // LIB_PIN::PinStringNum( m_PinNum )
+#include <sch_item_struct.h>
+
+class NETLIST_OBJECT_LIST;
+class SCH_COMPONENT;
+
+
+/* Type of Net objects (wires, labels, pins...) */
+enum NETLIST_ITEM_T
+{
+ NET_ITEM_UNSPECIFIED, // only for not yet initialized instances
+ NET_SEGMENT, // connection by wire
+ NET_BUS, // connection by bus
+ NET_JUNCTION, // connection by junction: can connect to
+ // or more crossing wires
+ NET_LABEL, // this is a local label
+ NET_GLOBLABEL, // this is a global label that connect all
+ // others global label in whole hierarchy
+ NET_HIERLABEL, // element to indicate connection to a
+ // higher-level sheet
+ NET_SHEETLABEL, // element to indicate connection to a
+ // lower-level sheet.
+ NET_BUSLABELMEMBER, /* created when a bus label is found:
+ * the bus label (like DATA[0..7] is
+ * converted to n single labels like
+ * DATA0, DATA1 ...
+ * These objects are living only in the current
+ * NETLIST_OBJECT_LIST, not in shematic.
+ */
+ NET_GLOBBUSLABELMEMBER, // see NET_BUSLABELMEMBER, used when a
+ // global bus label is found
+ NET_HIERBUSLABELMEMBER, // see NET_BUSLABELMEMBER, used when a
+ // hierarchical bus label is found
+ NET_SHEETBUSLABELMEMBER, // see NET_BUSLABELMEMBER, used when a
+ // pin sheet label using bus notation
+ // is found
+ NET_PINLABEL, /* created when a pin is POWER (IN or
+ * OUT) with invisible attribute is found:
+ * these pins are equivalent to a global
+ * label and are automatically connected
+ */
+ NET_PIN, // this is an usual pin
+ NET_NOCONNECT // this is a no connect symbol
+};
+
+
+/* Values for .m_FlagOfConnection member */
+enum NET_CONNECTION_T
+{
+ UNCONNECTED = 0, /* Pin or Label not connected (error) */
+ NOCONNECT_SYMBOL_PRESENT, /* Pin not connected but have a NoConnect
+ * symbol on it (no error) */
+ PAD_CONNECT /* Normal connection (no error) */
+};
+
+
+class NETLIST_OBJECT
+{
+public:
+ NETLIST_ITEM_T m_Type; /* Type of item (see NETLIST_ITEM_T enum) */
+ EDA_ITEM* m_Comp; /* Pointer to the library item that
+ * created this net object (the parent)
+ */
+ SCH_ITEM* m_Link; /* For SCH_SHEET_PIN:
+ * Pointer to the hierarchy sheet that
+ * contains this SCH_SHEET_PIN
+ * For Pins: pointer to the schematic component
+ * that contains this pin
+ */
+ int m_Flag; /* flag used in calculations */
+ SCH_SHEET_PATH m_SheetPath; // the sheet path which contains this item
+ SCH_SHEET_PATH m_SheetPathInclude; // sheet path which contains the hierarchical label
+ int m_ElectricalType; /* Has meaning only for Pins and
+ * hierarchical pins: electrical type */
+ int m_BusNetCode; /* Used for BUS connections */
+ int m_Member; /* for labels type NET_BUSLABELMEMBER ( bus member
+ * created from the BUS label ) member number.
+ */
+ NET_CONNECTION_T m_ConnectionType; // Used to store the connection type
+ long m_PinNum; // pin number ( 1 long = 4 bytes -> 4 ascii codes)
+ wxString m_Label; // Label text (for labels) or Pin name (for pins)
+ wxPoint m_Start; // Position of object or for segments: starting point
+ wxPoint m_End; // For segments (wire and buses): ending point
+
+private:
+ int m_netCode; /* net code for all items except BUS
+ * labels because a BUS label has
+ * as many net codes as bus members
+ */
+ NETLIST_OBJECT* m_netNameCandidate; /* a pointer to a label connected to the net,
+ * that can be used to give a name to the net
+ * or a pin if there is no label in net
+ * When no label, the pin is used to build
+ * default net name.
+ */
+
+public:
+
+#if defined(DEBUG)
+ void Show( std::ostream& out, int ndx ) const; // override
+
+#endif
+
+ NETLIST_OBJECT();
+ NETLIST_OBJECT( NETLIST_OBJECT& aSource ); // Copy constructor
+
+ ~NETLIST_OBJECT();
+
+ // Accessors:
+ void SetNet( int aNetCode ) { m_netCode = aNetCode; }
+ int GetNet() const { return m_netCode; }
+
+ /**
+ * Set the item connection type:
+ * UNCONNECTED Pin or Label not connected (error)
+ * NOCONNECT_SYMBOL_PRESENT Pin not connected but have a NoConnect
+ * symbol on it (no error)
+ * PAD_CONNECT Normal connection (no error)
+ */
+ void SetConnectionType( NET_CONNECTION_T aFlg = UNCONNECTED )
+ {
+ m_ConnectionType = aFlg;
+ }
+
+ NET_CONNECTION_T GetConnectionType()
+ {
+ return m_ConnectionType;
+ }
+
+ /**
+ * Set m_netNameCandidate to a connected item which will
+ * be used to calcule the net name of the item
+ * Obviously the candidate can be only a label
+ * when there is no label on the net a pad which will
+ * used to build a net name (something like Cmp<REF>_Pad<PAD_NAME>
+ * @param aCandidate = the connected item candidate
+ */
+ void SetNetNameCandidate( NETLIST_OBJECT* aCandidate );
+
+ /**
+ * @return true if an item has already a net name candidate
+ * and false if not ( m_netNameCandidate == NULL )
+ */
+ bool HasNetNameCandidate() { return m_netNameCandidate != NULL; }
+
+ /**
+ * Function GetPinNum
+ * returns a pin number in wxString form. Pin numbers are not always
+ * numbers. \"A23\" would be a valid pin number.
+ */
+ wxString GetPinNumText()
+ {
+ // hide the ugliness in here, but do it inline.
+ return LIB_PIN::PinStringNum( m_PinNum );
+ }
+
+ /** For Pins (NET_PINS):
+ * @return the schematic component which contains this pin
+ * (Note: this is the schematic component, not the library component
+ * for others items: return NULL
+ */
+ SCH_COMPONENT* GetComponentParent() const
+ {
+ if( m_Link && m_Link->Type() == SCH_COMPONENT_T )
+ return (SCH_COMPONENT*) m_Link;
+
+ return NULL;
+ }
+
+ /**
+ * Function IsLabelConnected
+ * tests if the net list object is a hierarchical label or sheet label and is
+ * connected to an associated hierarchical label or sheet label of \a aNetItem.
+ *
+ * @param aNetItem A pointer to a NETLIST_OBJECT to test against.
+ * @return A bool value of true if there is a connection with \a aNetItem or false
+ * if no connection to \a aNetItem.
+ */
+ bool IsLabelConnected( NETLIST_OBJECT* aNetItem );
+
+ /**
+ * Function IsLabelGlobal
+ * @return true if the object is a global label
+ * (i.e. an real global label or a pin label coming
+ * from a power pin invisible
+ */
+ bool IsLabelGlobal() const;
+
+ /**
+ * Function IsLabelBusMemberType
+ * @return true if the object is a bus label member build from a
+ * schematic bus label (like label[xx..yy], xx and yy are the first and last
+ * bus member id)
+ * bus label members have specific properties:
+ * they do not live in schematic
+ * they have specific properties in connections:
+ * 2 bus label members can be connected connected only if they have the same member value.
+ */
+ bool IsLabelBusMemberType() const;
+
+ /**
+ * Function IsLabelType
+ * @return true if the object is a label of any type
+ */
+ bool IsLabelType() const;
+
+ /**
+ * Function GetNetName
+ * @return the full net name of the item, i.e. the net name
+ * from the "best" label, prefixed by the sheet path
+ */
+ wxString GetNetName() const;
+
+ /**
+ * Function GetShortNetName
+ * @return the short net name of the item i.e. the net name
+ * from the "best" label without any prefix.
+ * 2 different nets can have the same short name
+ */
+ wxString GetShortNetName() const;
+
+ /**
+ * Function ConvertBusToNetListItems
+ * breaks the text of a bus label type net list object into as many members as
+ * it contains and creates a #NETLIST_OBJECT for each label and adds it to \a
+ * aNetListItems.
+ *
+ * @param aNetListItems A reference to vector of #NETLIST_OBJECT pointers to add
+ * the bus label NETLIST_OBJECTs.
+ */
+ void ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItems );
+};
+
+
+/**
+ * Type NETLIST_OBJECTS
+ * is a container referring to (not owning) NETLIST_OBJECTs, which are connected items
+ * in a full schematic hierarchy. It is useful when referring to NETLIST_OBJECTs
+ * actually owned by some other container.
+ */
+typedef std::vector<NETLIST_OBJECT*> NETLIST_OBJECTS;
+
+
+/**
+ * Class NETLIST_OBJECT_LIST
+ * is a container holding and _owning_ NETLIST_OBJECTs, which are connected items
+ * in a full schematic hierarchy. It is helpful for netlist and ERC calculations.
+ */
+class NETLIST_OBJECT_LIST : public NETLIST_OBJECTS
+{
+ int m_lastNetCode; // Used in intermediate calculation: last net code created
+ int m_lastBusNetCode; // Used in intermediate calculation:
+ // last net code created for bus members
+
+public:
+ /**
+ * Constructor.
+ * NETLIST_OBJECT_LIST handle a list of connected items.
+ * the instance can be owner of items or not.
+ * If it is the owner, the items are freeed by the destructor
+ * @param aIsOwner true if the instance is the owner of item list
+ * (default = false)
+ */
+ NETLIST_OBJECT_LIST()
+ {
+ // Do not leave some members uninitialized:
+ m_lastNetCode = 0;
+ m_lastBusNetCode = 0;
+ }
+
+ ~NETLIST_OBJECT_LIST();
+
+ /**
+ * Function BuildNetListInfo
+ * the master function of tgis class.
+ * Build the list of connected objects (pins, labels ...) and
+ * all info to generate netlists or run ERC diags
+ * @param aSheets = the flattened sheet list
+ * @return true if OK, false is not item found
+ */
+ bool BuildNetListInfo( SCH_SHEET_LIST& aSheets );
+
+ /**
+ * Acces to an item in list
+ */
+ NETLIST_OBJECT* GetItem( unsigned aIdx ) const
+ {
+ return *( this->begin() + aIdx );
+ }
+
+ /**
+ * Acces to an item type
+ */
+ NETLIST_ITEM_T GetItemType( unsigned aIdx ) const
+ {
+ return GetItem( aIdx )->m_Type;
+ }
+
+ /**
+ * Acces to an item net code
+ */
+ int GetItemNet( unsigned aIdx ) const
+ {
+ return GetItem( aIdx )->GetNet();
+ }
+
+ NET_CONNECTION_T GetConnectionType( unsigned aIdx )
+ {
+ return GetItem( aIdx )->GetConnectionType();
+ }
+
+ /**
+ * Set the item connection type:
+ * UNCONNECTED Pin or Label not connected (error)
+ * NOCONNECT_SYMBOL_PRESENT Pin not connected but have a NoConnect
+ * symbol on it (no error)
+ * PAD_CONNECT Normal connection (no error)
+ */
+ void SetConnectionType( unsigned aIdx, NET_CONNECTION_T aFlg = UNCONNECTED )
+ {
+ GetItem( aIdx )->SetConnectionType( aFlg );
+ }
+
+ /** Delete all objects in list and clear list */
+ void Clear();
+
+ /**
+ * Reset the connection type of all items to UNCONNECTED type
+ */
+ void ResetConnectionsType()
+ {
+ for( unsigned ii = 0; ii < size(); ii++ )
+ GetItem( ii )->SetConnectionType( UNCONNECTED );
+ }
+
+ /*
+ * Sorts the list of connected items by net code
+ */
+ void SortListbyNetcode();
+
+ /*
+ * Sorts the list of connected items by sheet.
+ * This sorting is used when searching "physical" connection between items
+ * because obviously only items inside the same sheet can be connected
+ */
+ void SortListbySheet();
+
+
+ #if defined(DEBUG)
+ void DumpNetTable()
+ {
+ for( unsigned idx = 0; idx < size(); ++idx )
+ {
+ GetItem( idx )->Show( std::cout, idx );
+ }
+ }
+
+ #endif
+
+private:
+ /*
+ * Propagate aNewNetCode to items having an internal netcode aOldNetCode
+ * used to interconnect group of items already physically connected,
+ * when a new connection is found between aOldNetCode and aNewNetCode
+ */
+ void propageNetCode( int aOldNetCode, int aNewNetCode, bool aIsBus );
+
+ /*
+ * This function merges the net codes of groups of objects already connected
+ * to labels (wires, bus, pins ... ) when 2 labels are equivalents
+ * (i.e. group objects connected by labels)
+ */
+ void labelConnect( NETLIST_OBJECT* aLabelRef );
+
+ /* Comparison function to sort by increasing Netcode the list of connected items
+ */
+ static bool sortItemsbyNetcode( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 )
+ {
+ return Objet1->GetNet() < Objet2->GetNet();
+ }
+
+ /* Comparison routine to sort items by Sheet Number
+ */
+ static bool sortItemsBySheet( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 )
+ {
+ return Objet1->m_SheetPath.Cmp( Objet2->m_SheetPath ) < 0;
+ }
+
+ /**
+ * Propagate net codes from a parent sheet to an include sheet,
+ * from a pin sheet connection
+ */
+ void sheetLabelConnect( NETLIST_OBJECT* aSheetLabel );
+
+ void pointToPointConnect( NETLIST_OBJECT* aRef, bool aIsBus, int start );
+
+ /**
+ * Search connections between a junction and segments
+ * Propagate the junction net code to objects connected by this junction.
+ * The junction must have a valid net code
+ * The list of objects is expected sorted by sheets.
+ * Search is done from index aIdxStart to the last element of list
+ */
+ void segmentToPointConnect( NETLIST_OBJECT* aJonction, bool aIsBus, int aIdxStart );
+
+
+ /**
+ * Function connectBusLabels
+ * Propagate the net code (and create it, if not yet existing) between
+ * all bus label member objects connected by they name.
+ * Search is done in the entire list
+ */
+ void connectBusLabels();
+
+ /**
+ * Set the m_FlagOfConnection member of items in list
+ * depending on the connection type:
+ * UNCONNECTED, PAD_CONNECT or NOCONNECT_SYMBOL_PRESENT
+ * The list is expected sorted by order of net code,
+ * i.e. items having the same net code are grouped
+ */
+ void setUnconnectedFlag();
+
+ /**
+ * Function findBestNetNameForEachNet
+ * fill the .m_NetNameCandidate member of each item of aNetItemBuffer
+ * with a reference to the "best" NETLIST_OBJECT usable to give a name to the net
+ * If no suitable object found, .m_NetNameCandidate is filled with 0.
+ * The "best" NETLIST_OBJECT is a NETLIST_OBJECT that have the type label
+ * and by priority order:
+ * the label is global or local
+ * the label is in the first sheet in a hierarchy (the root sheet has the most priority)
+ * alphabetic order.
+ */
+ void findBestNetNameForEachNet();
+};
+
+
+/**
+ * Function IsBusLabel
+ * test if \a aLabel has a bus notation.
+ *
+ * @param aLabel A wxString object containing the label to test.
+ * @return true if text is a bus notation format otherwise false is returned.
+ */
+extern bool IsBusLabel( const wxString& aLabel );
+
+#endif // _CLASS_NETLIST_OBJECT_H_
diff --git a/eeschema/class_sch_screen.h b/eeschema/class_sch_screen.h
new file mode 100644
index 0000000..67c6451
--- /dev/null
+++ b/eeschema/class_sch_screen.h
@@ -0,0 +1,599 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_sch_screen.h
+ * @brief Definitions for the Eeschema program SCH_SCREEN class.
+ */
+
+#ifndef CLASS_SCREEN_H
+#define CLASS_SCREEN_H
+
+#include <macros.h>
+#include <dlist.h>
+#include <sch_item_struct.h>
+#include <class_base_screen.h>
+#include <class_title_block.h>
+#include <class_page_info.h>
+#include <kiway_player.h>
+#include <sch_marker.h>
+
+#include <../eeschema/general.h>
+
+
+class LIB_PIN;
+class SCH_COMPONENT;
+class SCH_SHEET_PATH;
+class SCH_SHEET_PIN;
+class SCH_LINE;
+class SCH_TEXT;
+class PLOTTER;
+
+
+enum SCH_LINE_TEST_T
+{
+ ENTIRE_LENGTH_T,
+ END_POINTS_ONLY_T,
+ EXCLUDE_END_POINTS_T
+};
+
+
+/// Max number of sheets in a hierarchy project
+#define NB_MAX_SHEET 500
+
+
+class SCH_SCREEN : public BASE_SCREEN, public KIWAY_HOLDER
+{
+private:
+
+ wxString m_fileName; ///< File used to load the screen.
+
+ int m_refCount; ///< Number of sheets referencing this screen.
+ ///< Delete when it goes to zero.
+
+ /// The size of the paper to print or plot on
+ PAGE_INFO m_paper; // keep with the MVC 'model' if this class gets split
+
+ TITLE_BLOCK m_titles;
+
+ /// Origin of the auxilliary axis, which is used in exports mostly, but not yet in EESCHEMA
+ wxPoint m_aux_origin;
+
+ DLIST< SCH_ITEM > m_drawList; ///< Object list for the screen.
+
+ int m_modification_sync; ///< inequality with PART_LIBS::GetModificationHash()
+ ///< will trigger ResolveAll().
+
+ /**
+ * Function addConnectedItemsToBlock
+ * add items connected at \a aPosition to the block pick list.
+ * <p>
+ * This method tests all connectible unselected items in the screen that are connected to
+ * \a aPosition and adds them to the block selection pick list. This is used when a block
+ * drag is being performed to ensure connections to items in the block are not lost.
+ *</p>
+ * @param aPosition = The connection point to test.
+ */
+ void addConnectedItemsToBlock( const wxPoint& aPosition );
+
+public:
+
+ /**
+ * Constructor
+ */
+ SCH_SCREEN( KIWAY* aKiway );
+
+ ~SCH_SCREEN();
+
+ virtual wxString GetClass() const
+ {
+ return wxT( "SCH_SCREEN" );
+ }
+
+ const PAGE_INFO& GetPageSettings() const { return m_paper; }
+ void SetPageSettings( const PAGE_INFO& aPageSettings ) { m_paper = aPageSettings; }
+
+ void SetFileName( const wxString& aFileName ) { m_fileName = aFileName; }
+
+ const wxString& GetFileName() const { return m_fileName; }
+
+ const wxPoint& GetAuxOrigin() const { return m_aux_origin; }
+ void SetAuxOrigin( const wxPoint& aPosition ) { m_aux_origin = aPosition; }
+
+ const TITLE_BLOCK& GetTitleBlock() const { return m_titles; }
+ //TITLE_BLOCK& GetTitleBlock() const { return (TITLE_BLOCK&) m_titles; }
+ void SetTitleBlock( const TITLE_BLOCK& aTitleBlock ) { m_titles = aTitleBlock; }
+
+ void DecRefCount();
+
+ void IncRefCount();
+
+ int GetRefCount() const { return m_refCount; }
+
+ /**
+ * Function GetDrawItems().
+ * @return - A pointer to the first item in the linked list of draw items.
+ */
+ SCH_ITEM* GetDrawItems() const { return m_drawList.begin(); }
+
+ void Append( SCH_ITEM* aItem )
+ {
+ m_drawList.Append( aItem );
+ --m_modification_sync;
+ }
+
+ /**
+ * Function Append
+ * adds \a aList of SCH_ITEM objects to the list for draw items for the sheet.
+ *
+ * @param aList A reference to a #DLIST containing the #SCH_ITEM to add to the sheet.
+ */
+ void Append( DLIST< SCH_ITEM >& aList )
+ {
+ m_drawList.Append( aList );
+ --m_modification_sync;
+ }
+
+ /**
+ * Function GetCurItem
+ * returns the currently selected SCH_ITEM, overriding BASE_SCREEN::GetCurItem().
+ * @return SCH_ITEM* - the one selected, or NULL.
+ */
+ SCH_ITEM* GetCurItem() const { return (SCH_ITEM*) BASE_SCREEN::GetCurItem(); }
+
+ /**
+ * Function SetCurItem
+ * sets the currently selected object, m_CurrentItem.
+ * @param aItem Any object derived from SCH_ITEM
+ */
+ void SetCurItem( SCH_ITEM* aItem ) { BASE_SCREEN::SetCurItem( (EDA_ITEM*) aItem ); }
+
+ /**
+ * Function Clear
+ * deletes all draw items and clears the project settings.
+ */
+ void Clear();
+
+ /**
+ * Free all the items from the schematic associated with the screen.
+ *
+ * This does not delete any sub hierarchies.
+ */
+ void FreeDrawList();
+
+ /**
+ * Function GetItem
+ * checks \a aPosition within a distance of \a aAccuracy for items of type \a aFilter.
+ * @param aPosition Position in drawing units.
+ * @param aAccuracy The maximum distance within \a Position to check for an item.
+ * @param aType The type of item to find or #NOT_USED to find any item type.
+ * @return The item found that meets the search criteria or NULL if none found.
+ */
+ SCH_ITEM* GetItem( const wxPoint& aPosition, int aAccuracy = 0,
+ KICAD_T aType = NOT_USED ) const;
+
+ void Place( SCH_EDIT_FRAME* frame, wxDC* DC ) { };
+
+ /**
+ * Function CheckComponentsToPartsLink
+ * initializes or reinitializes the weak reference
+ * to the LIB_PART for each SCH_COMPONENT found in m_drawList.
+ * It must be called from:
+ * - Draw function
+ * - when loading a schematic file
+ * - before creating a netlist (in case a library is modified)
+ */
+ void CheckComponentsToPartsLinks();
+
+ /**
+ * Function Draw
+ * draws all the items in the screen to \a aCanvas.
+ * note: this function is useful only for schematic.
+ * library editor and library viewer do not use a draw list, and therefore
+ * draws nothing
+ * @param aCanvas The canvas item to draw on.
+ * @param aDC The device context to draw on.
+ * @param aDrawMode The drawing mode.
+ * @param aColor The drawing color.
+ */
+ void Draw( EDA_DRAW_PANEL* aCanvas, wxDC* aDC, GR_DRAWMODE aDrawMode,
+ EDA_COLOR_T aColor = UNSPECIFIED_COLOR );
+
+ /**
+ * Function Plot
+ * plots all the schematic objects to \a aPlotter.
+ * note: this function is useful only for schematic.
+ * library editor and library viewer do not use a draw list, and therefore
+ * plots nothing
+ *
+ * @param aPlotter The plotter object to plot to.
+ */
+ void Plot( PLOTTER* aPlotter );
+
+ /**
+ * Function Remove
+ * removes \a aItem from the schematic associated with this screen.
+ *
+ * @note The removed item is not deleted. It is only unlinked from the item list.
+ * @param aItem Item to be removed from schematic.
+ */
+ void Remove( SCH_ITEM* aItem );
+
+ /**
+ * Function DeleteItem
+ * removes \a aItem from the linked list and deletes the object. If \a aItem is
+ * is a schematic sheet label, it is removed from the screen associated with the
+ * sheet that contains the label to be deleted.
+ * @param aItem The schematic object to be deleted from the screen.
+ */
+ void DeleteItem( SCH_ITEM* aItem );
+
+ bool CheckIfOnDrawList( SCH_ITEM* st );
+
+ /**
+ * Function SchematicCleanUp
+ * performs routine schematic cleaning including breaking wire and buses and
+ * deleting identical objects superimposed on top of each other.
+ *
+ * @param aCanvas The window to draw on.
+ * @param aDC The device context used for drawing to \a aCanvas.
+ * @return True if any schematic clean up was performed.
+ */
+ bool SchematicCleanUp( EDA_DRAW_PANEL* aCanvas = NULL, wxDC* aDC = NULL );
+
+ /**
+ * Function TestDanglingEnds
+ * tests all of the connectible objects in the schematic for unused connection points.
+ * @param aDC - The device context to draw the dangling status indicators.
+ * @param aCanvas - The window to draw on.
+ * @return True if any dangling ends were found.
+ */
+ bool TestDanglingEnds( EDA_DRAW_PANEL* aCanvas = NULL, wxDC* aDC = NULL );
+
+ /**
+ * Function ExtractWires
+ * extracts the old wires, junctions and buses. If \a aCreateCopy is true, replace
+ * extracted items with a copy of the original. Old items are to be put in undo list,
+ * and the new ones can be modified by clean up safely. If an abort draw segmat command
+ * is made, the old wires must be put back into #m_drawList, and the copies must be
+ * deleted. This is because previously stored undo commands can handle pointers on wires
+ * or buses, and we do not delete wires or buses, we must put them in undo list.
+ *
+ * Because cleanup deletes and/or modify bus and wires, it is easier is to put
+ * all the existing wires in undo list and use a new copy of wires for cleanup.
+ */
+ void ExtractWires( DLIST< SCH_ITEM >& aList, bool aCreateCopy );
+
+ /**
+ * Function ReplaceWires
+ * replaces all of the wires, buses, and junctions in the screen with \a aWireList.
+ *
+ * @param aWireList List of wires to replace the existing wires with.
+ */
+ void ReplaceWires( DLIST< SCH_ITEM >& aWireList );
+
+ /**
+ * Function MarkConnections
+ * add all wires and junctions connected to \a aSegment which are not connected any
+ * component pin to \a aItemList.
+ * @param aSegment The segment to test for connections.
+ */
+ void MarkConnections( SCH_LINE* aSegment );
+
+ /**
+ * Functions GetConnection
+ * adds all of the wires and junctions to \a aList that make up a connection to the
+ * object at \a aPosition.
+ * @param aPosition The position of the first connection object in drawing units.
+ * @param aList The pick list to add the connect item to.
+ * @param aFullConnection If true all the objects that make up this connection are
+ * add to \a aList. Otherwise, only the objects up to the first
+ * node are added.
+ * @return The number of items added to \a aList.
+ */
+ int GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aList, bool aFullConnection );
+
+ /**
+ * Function BreakSegment
+ * checks every wire and bus for a intersection at \a aPoint and break into two segments
+ * at \a aPoint if an intersection is found.
+ * @param aPoint Test this point for an intersection.
+ * @return True if any wires or buses were broken.
+ */
+ bool BreakSegment( const wxPoint& aPoint );
+
+ /**
+ * Function BreakSegmentsOnJunctions
+ * tests all junctions and bus entries in the schematic for intersections with wires and
+ * buses and breaks any intersections into multiple segments.
+ * @return True if any wires or buses were broken.
+ */
+ bool BreakSegmentsOnJunctions();
+
+ /* full undo redo management : */
+ // use BASE_SCREEN::PushCommandToUndoList( PICKED_ITEMS_LIST* aItem )
+ // use BASE_SCREEN::PushCommandToRedoList( PICKED_ITEMS_LIST* aItem )
+
+ /**
+ * Function ClearUndoORRedoList
+ * free the undo or redo list from List element
+ * Wrappers are deleted.
+ * data pointed by wrappers are deleted if not in use in schematic
+ * i.e. when they are copy of a schematic item or they are no more in use (DELETED)
+ * @param aList = the UNDO_REDO_CONTAINER to clear
+ * @param aItemCount = the count of items to remove. < 0 for all items
+ * items are removed from the beginning of the list.
+ * So this function can be called to remove old commands
+ */
+ virtual void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 );
+
+ /**
+ * Function Save
+ * writes the data structures for this object out to \a aFile in "*.sch" format.
+ *
+ * @param aFile The FILE to write to.
+ * @return bool - true if success writing else false.
+ */
+ bool Save( FILE* aFile ) const;
+
+ /**
+ * Clear the state flags of all the items in the screen.
+ */
+ void ClearDrawingState();
+
+ int CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) const;
+
+ /**
+ * Function IsJunctionNeeded
+ * tests if a junction is required for the items at \a aPosition on the screen.
+ * <p>
+ * A junction is required at \a aPosition if the following criteria are satisfied:
+ * <ul>
+ * <li>one wire midpoint, one or more wire endpoints and no junction.</li>
+ * <li>three or more wire endpoints and no junction.</li>
+ * <li>two wire midpoints and no junction</li>
+ * <li>one wire midpoint, a component pin, and no junction.</li>
+ * <li>three wire endpoints, a component pin, and no junction.</li>
+ * </ul>
+ * </p>
+ * @param aPosition The position to test.
+ * @return True if a junction is required at \a aPosition.
+ */
+ bool IsJunctionNeeded( const wxPoint& aPosition );
+
+ /**
+ * Function IsTerminalPoint
+ * tests if \a aPosition is a connection point on \a aLayer.
+ *
+ * @param aPosition Position to test.
+ * @param aLayer The layer type to test against. Valid layer types are #LAYER_NOTES,
+ * #LAYER_BUS, and #LAYER_WIRE.
+ * @return True if \a Position is a connection point on \a aLayer.
+ */
+ bool IsTerminalPoint( const wxPoint& aPosition, int aLayer );
+
+ /**
+ * Function GetPin
+ * test the screen for a component pin item at \a aPosition.
+ * @param aPosition Position to test.
+ * @param aComponent The component if a pin was found, otherwise NULL.
+ * @param aEndPointOnly Set to true to test if \a aPosition is the connection
+ * point of the pin.
+ * @return The pin item if found, otherwise NULL.
+ */
+ LIB_PIN* GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponent = NULL,
+ bool aEndPointOnly = false ) const;
+
+ /**
+ * Function GetSheet
+ * returns a sheet object pointer that is named \a aName.
+ *
+ * @note The screen hierarchy is not descened.
+ * @param aName is the case insensitive name of the sheet.
+ * @return A pointer to the SCH_SHEET object found or NULL.
+ */
+ SCH_SHEET* GetSheet( const wxString& aName );
+
+ /**
+ * Function GetSheetLabel
+ * test the screen if \a aPosition is a sheet label object.
+ * @param aPosition The position to test.
+ * @return The sheet label object if found otherwise NULL.
+ */
+ SCH_SHEET_PIN* GetSheetLabel( const wxPoint& aPosition );
+
+ /**
+ * Function ClearAnnotation
+ * clears the annotation for the components in \a aSheetPath on the screen.
+ * @param aSheetPath The sheet path of the component annotation to clear. If NULL then
+ * the entire hierarchy is cleared.
+ */
+ void ClearAnnotation( SCH_SHEET_PATH* aSheetPath );
+
+ /**
+ * Function GetHierarchicalItems
+ * adds all schematic sheet and component object in the screen to \a aItems.
+ * @param aItems Hierarchical item list to fill.
+ */
+ void GetHierarchicalItems( EDA_ITEMS& aItems );
+
+ /**
+ * Function GetNode
+ * returns all the items at \a aPosition that form a node.
+ *
+ * @param aPosition The wxPoint to test for node items.
+ * @param aList A #EDA_ITEMS container to place the items found.
+ * @return The number of node items found at \a aPosition.
+ */
+ int GetNode( const wxPoint& aPosition, EDA_ITEMS& aList );
+
+ /**
+ * Function GetWireOrBus
+ * returns a wire or bus item located at \a aPosition.
+ *
+ * @param aPosition The wxPoint to test for node items.
+ * @return The SCH_LINE* of the wire or bus item found at \a aPosition or NULL if item not
+ * found.
+ */
+ SCH_LINE* GetWireOrBus( const wxPoint& aPosition );
+
+ /**
+ * Function GetLine
+ * returns a line item located at \a aPosition.
+ *
+ * @param aPosition The wxPoint to test for a line item.
+ * @param aAccuracy Amount to inflate the item hit test bounding box.
+ * @param aLayer The layer the line is drawn upon.
+ * @param aSearchType Additional line test criteria.
+ * @return The SCH_LINE* of the wire item found at \a aPosition or NULL if item not
+ * found.
+ */
+ SCH_LINE* GetLine( const wxPoint& aPosition, int aAccuracy = 0, int aLayer = LAYER_NOTES,
+ SCH_LINE_TEST_T aSearchType = ENTIRE_LENGTH_T );
+
+ SCH_LINE* GetWire( const wxPoint& aPosition, int aAccuracy = 0,
+ SCH_LINE_TEST_T aSearchType = ENTIRE_LENGTH_T )
+ {
+ return GetLine( aPosition, aAccuracy, LAYER_WIRE, aSearchType );
+ }
+
+ SCH_LINE* GetBus( const wxPoint& aPosition, int aAccuracy = 0,
+ SCH_LINE_TEST_T aSearchType = ENTIRE_LENGTH_T )
+ {
+ return GetLine( aPosition, aAccuracy, LAYER_BUS, aSearchType );
+ }
+
+ /**
+ * Function GetLabel
+ * returns a label item located at \a aPosition.
+ *
+ * @param aPosition The wxPoint to test for label items.
+ * @param aAccuracy Amount to inflate the item hit test bounding box.
+ * @return The SCH_TEXT* of the label item found at \a aPosition or NULL if item not
+ * found.
+ */
+ SCH_TEXT* GetLabel( const wxPoint& aPosition, int aAccuracy = 0 );
+
+ /**
+ * Function SetFootprintField
+ * searches screen for a component with \a aReference and set the footprint field to
+ * \a aFootPrint if found.
+ *
+ * @param aSheetPath The sheet path used to look up the reference designator.
+ * @param aReference The reference designator of the component.
+ * @param aFootPrint The value to set the footprint field.
+ * @param aSetVisible The value to set the field visibility flag.
+ * @return True if \a aReference was found otherwise false.
+ */
+ bool SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxString& aReference,
+ const wxString& aFootPrint, bool aSetVisible );
+
+ /**
+ * Function SelectBlockItems
+ * creates a list of items found when a block command is initiated. The items selected
+ * depend on the block command. If the drag block command is issued, than any items
+ * connected to items in the block are also selected.
+ */
+ void SelectBlockItems();
+
+ /**
+ * Function UpdatePickList
+ * adds all the items in the screen within the block selection rectangle to the pick list.
+ * @return The number of items in the pick list.
+ */
+ int UpdatePickList();
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // overload
+#endif
+};
+
+
+/**
+ * Class SCH_SCREENS
+ * is a container class that holds multiple SCH_SCREENs in a hierarchy.
+ * Individual SCH_SCREENs are unique, and correspond to .sch files.
+ */
+class SCH_SCREENS
+{
+private:
+ std::vector< SCH_SCREEN* > m_screens;
+ unsigned int m_index;
+
+public:
+ SCH_SCREENS();
+ ~SCH_SCREENS();
+ int GetCount() const { return m_screens.size(); }
+ SCH_SCREEN* GetFirst();
+ SCH_SCREEN* GetNext();
+ SCH_SCREEN* GetScreen( unsigned int aIndex ) const;
+
+ /**
+ * Function ClearAnnotation
+ * clears the annotation for all components in the hierarchy.
+ */
+ void ClearAnnotation();
+
+ /**
+ * Function SchematicCleanUp
+ * merges and breaks wire segments in the entire schematic hierarchy.
+ */
+ void SchematicCleanUp();
+
+ /**
+ * Function ReplaceDuplicateTimeStamps
+ * test all sheet and component objects in the schematic for duplicate time stamps
+ * an replaces them as necessary. Time stamps must be unique in order for complex
+ * hierarchies know which components go to which sheets.
+ * @return The number of duplicate time stamps replaced.
+ */
+ int ReplaceDuplicateTimeStamps();
+
+ /**
+ * Function DeleteAllMarkers
+ * deletes all electronic rules check markers of \a aMarkerType from all the screens in
+ * the list.
+ * @param aMarkerType Type of markers to be deleted.
+ */
+ void DeleteAllMarkers( enum MARKER_BASE::TYPEMARKER aMarkerType );
+
+ /**
+ * Function GetMarkerCount
+ * returns the number of ERC markers of \a aMarkerType from all of the screens in the list.
+ *
+ * @param aMarkerType Indicates the type of marker to count. if MARKER_UNSPEC
+ * all markers are counted.
+ * @param aSeverity Indicates the error level of marker to count.
+ * useMARKER_SEVERITY_UNSPEC to count all markersof the specified type
+ * @return int count of the markers found.
+ */
+ int GetMarkerCount( enum MARKER_BASE::TYPEMARKER aMarkerType,
+ enum MARKER_BASE::MARKER_SEVERITY aSeverity );
+
+private:
+ void AddScreenToList( SCH_SCREEN* aScreen );
+ void BuildScreenList( EDA_ITEM* aItem );
+};
+
+#endif /* CLASS_SCREEN_H */
diff --git a/eeschema/cmp_library.keywords b/eeschema/cmp_library.keywords
new file mode 100644
index 0000000..6640005
--- /dev/null
+++ b/eeschema/cmp_library.keywords
@@ -0,0 +1,33 @@
+header
+version
+name
+author
+comment
+license
+url
+copyright
+symbol
+component
+field
+tags
+docs
+drawing
+arc
+start
+end
+rectangle
+position
+width
+height
+polyline
+circle
+center
+radius
+text
+orientation
+pin
+number
+length
+electical_type
+style
+fill_style
diff --git a/eeschema/cmp_library_lexer.cpp b/eeschema/cmp_library_lexer.cpp
new file mode 100644
index 0000000..750bbaf
--- /dev/null
+++ b/eeschema/cmp_library_lexer.cpp
@@ -0,0 +1,6 @@
+/*
+ * Do not delete this file. It will eventually become the new component
+ * library file DSN lexer which will replace the current library and library
+ * document file formats.
+ */
+#include <cmp_library_lexer.h>
diff --git a/eeschema/component_references_lister.cpp b/eeschema/component_references_lister.cpp
new file mode 100644
index 0000000..6796ef3
--- /dev/null
+++ b/eeschema/component_references_lister.cpp
@@ -0,0 +1,788 @@
+/**
+ * @file component_references_lister.cpp
+ * @brief Code for creating a flat list of components needed for annotation and BOM.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2011 jean-pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
+ * Copyright (C) 1992-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <wx/regex.h>
+#include <algorithm>
+#include <vector>
+
+#include <fctsys.h>
+#include <kicad_string.h>
+#include <schframe.h>
+#include <sch_reference_list.h>
+#include <sch_component.h>
+
+#include <boost/foreach.hpp>
+
+
+//#define USE_OLD_ALGO
+
+
+void SCH_REFERENCE_LIST::RemoveItem( unsigned int aIndex )
+{
+ if( aIndex < componentFlatList.size() )
+ componentFlatList.erase( componentFlatList.begin() + aIndex );
+}
+
+
+bool SCH_REFERENCE_LIST::sortByXPosition( const SCH_REFERENCE& item1,
+ const SCH_REFERENCE& item2 )
+{
+ int ii = item1.CompareRef( item2 );
+
+ if( ii == 0 )
+ ii = item1.m_SheetNum - item2.m_SheetNum;
+ if( ii == 0 )
+ ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
+ if( ii == 0 )
+ ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
+ if( ii == 0 )
+ ii = item1.m_TimeStamp - item2.m_TimeStamp;
+
+ return ii < 0;
+}
+
+bool SCH_REFERENCE_LIST::sortByYPosition( const SCH_REFERENCE& item1,
+ const SCH_REFERENCE& item2 )
+{
+ int ii = item1.CompareRef( item2 );
+
+ if( ii == 0 )
+ ii = item1.m_SheetNum - item2.m_SheetNum;
+ if( ii == 0 )
+ ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
+ if( ii == 0 )
+ ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
+ if( ii == 0 )
+ ii = item1.m_TimeStamp - item2.m_TimeStamp;
+
+ return ii < 0;
+}
+
+
+bool SCH_REFERENCE_LIST::sortByRefAndValue( const SCH_REFERENCE& item1,
+ const SCH_REFERENCE& item2 )
+{
+ int ii = item1.CompareRef( item2 );
+ if( ii == 0 )
+ ii = item1.CompareValue( item2 );
+ if( ii == 0 )
+ ii = item1.m_Unit - item2.m_Unit;
+ if( ii == 0 )
+ ii = item1.m_SheetNum - item2.m_SheetNum;
+ if( ii == 0 )
+ ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
+ if( ii == 0 )
+ ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
+ if( ii == 0 )
+ ii = item1.m_TimeStamp - item2.m_TimeStamp;
+
+ return ii < 0;
+}
+
+
+bool SCH_REFERENCE_LIST::sortByReferenceOnly( const SCH_REFERENCE& item1,
+ const SCH_REFERENCE& item2 )
+{
+ int ii;
+
+ ii = RefDesStringCompare( item1.GetRef(), item2.GetRef() );
+
+ if( ii == 0 )
+ {
+ ii = item1.m_RootCmp->GetField( VALUE )->GetText().CmpNoCase( item2.m_RootCmp->GetField( VALUE )->GetText() );
+ }
+
+ if( ii == 0 )
+ {
+ ii = item1.m_Unit - item2.m_Unit;
+ }
+
+ return ii < 0;
+}
+
+
+bool SCH_REFERENCE_LIST::sortByTimeStamp( const SCH_REFERENCE& item1,
+ const SCH_REFERENCE& item2 )
+{
+ int ii = item1.m_SheetPath.Cmp( item2.m_SheetPath );
+
+ if( ii == 0 )
+ ii = item1.m_TimeStamp - item2.m_TimeStamp;
+
+ return ii < 0;
+}
+
+int SCH_REFERENCE_LIST::FindUnit( size_t aIndex, int aUnit )
+{
+ int NumRef;
+
+ NumRef = componentFlatList[aIndex].m_NumRef;
+
+ for( size_t ii = 0; ii < componentFlatList.size(); ii++ )
+ {
+ if( ( aIndex == ii )
+ || ( componentFlatList[ii].m_IsNew )
+ || ( componentFlatList[ii].m_NumRef != NumRef )
+ || ( componentFlatList[aIndex].CompareRef( componentFlatList[ii] ) != 0 ) )
+ continue;
+
+ if( componentFlatList[ii].m_Unit == aUnit )
+ return (int) ii;
+ }
+
+ return -1;
+}
+
+
+void SCH_REFERENCE_LIST::RemoveSubComponentsFromList()
+{
+ SCH_COMPONENT* libItem;
+ wxString oldName;
+ wxString currName;
+
+ // The component list **MUST** be sorted by reference and by unit number
+ // in order to find all parts of a component
+ SortByReferenceOnly();
+
+ for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
+ {
+
+ libItem = componentFlatList[ii].m_RootCmp;
+ if( libItem == NULL )
+ continue;
+
+ currName = componentFlatList[ii].GetRef();
+
+ if( !oldName.IsEmpty() )
+ {
+ if( oldName == currName ) // currName is a subpart of oldName: remove it
+ {
+ componentFlatList.erase( componentFlatList.begin() + ii );
+ ii--;
+ }
+ }
+
+ oldName = currName;
+ }
+}
+
+
+void SCH_REFERENCE_LIST::ResetHiddenReferences()
+{
+ for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
+ {
+ if( componentFlatList[ii].GetRefStr()[0] == '#' )
+ {
+ componentFlatList[ii].m_IsNew = true;
+ componentFlatList[ii].m_NumRef = 0;
+ }
+ }
+}
+
+
+void SCH_REFERENCE_LIST::GetRefsInUse( int aIndex, std::vector< int >& aIdList, int aMinRefId )
+{
+ aIdList.clear();
+
+ for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
+ {
+ if( ( componentFlatList[aIndex].CompareRef( componentFlatList[ii] ) == 0 )
+ && ( componentFlatList[ii].m_NumRef >= aMinRefId ) )
+ aIdList.push_back( componentFlatList[ii].m_NumRef );
+ }
+
+ sort( aIdList.begin(), aIdList.end() );
+
+ // Ensure each reference number appears only once. If there are components with
+ // multiple parts per package the same number will be stored for each part.
+ std::vector< int >::iterator it = unique( aIdList.begin(), aIdList.end() );
+
+ // Using the C++ unique algorithm only moves the duplicate entries to the end of
+ // of the array. This removes the duplicate entries from the array.
+ aIdList.resize( it - aIdList.begin() );
+}
+
+
+int SCH_REFERENCE_LIST::GetLastReference( int aIndex, int aMinValue )
+{
+ int lastNumber = aMinValue;
+
+ for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
+ {
+ // search only for the current reference prefix:
+ if( componentFlatList[aIndex].CompareRef( componentFlatList[ii] ) != 0 )
+ continue;
+
+ // update max value for the current reference prefix
+ if( lastNumber < componentFlatList[ii].m_NumRef )
+ lastNumber = componentFlatList[ii].m_NumRef;
+ }
+
+ return lastNumber;
+}
+
+
+int SCH_REFERENCE_LIST::CreateFirstFreeRefId( std::vector<int>& aIdList, int aFirstValue )
+{
+ int expectedId = aFirstValue;
+
+ // We search for expected Id a value >= aFirstValue.
+ // Skip existing Id < aFirstValue
+ unsigned ii = 0;
+
+ for( ; ii < aIdList.size(); ii++ )
+ {
+ if( expectedId <= aIdList[ii] )
+ break;
+ }
+
+ // Ids are sorted by increasing value, from aFirstValue
+ // So we search from aFirstValue the first not used value, i.e. the first hole in list.
+ for( ; ii < aIdList.size(); ii++ )
+ {
+ if( expectedId != aIdList[ii] ) // This id is not yet used.
+ {
+ // Insert this free Id, in order to keep list sorted
+ aIdList.insert( aIdList.begin() + ii, expectedId );
+ return expectedId;
+ }
+
+ expectedId++;
+ }
+
+ // All existing Id are tested, and all values are found in use.
+ // So Create a new one.
+ aIdList.push_back( expectedId );
+ return expectedId;
+}
+
+
+void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId,
+ SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap )
+{
+ if ( componentFlatList.size() == 0 )
+ return;
+
+ int LastReferenceNumber = 0;
+ int NumberOfUnits, Unit;
+
+ // Components with an invisible reference (power...) always are re-annotated.
+ ResetHiddenReferences();
+
+ /* calculate index of the first component with the same reference prefix
+ * than the current component. All components having the same reference
+ * prefix will receive a reference number with consecutive values:
+ * IC .. will be set to IC4, IC4, IC5 ...
+ */
+ unsigned first = 0;
+
+ // calculate the last used number for this reference prefix:
+#ifdef USE_OLD_ALGO
+ int minRefId = 0;
+
+ // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
+ if( aUseSheetNum )
+ minRefId = componentFlatList[first].m_SheetNum * aSheetIntervalId;
+
+ LastReferenceNumber = GetLastReference( first, minRefId );
+#else
+ int minRefId = 1;
+
+ // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
+ if( aUseSheetNum )
+ minRefId = componentFlatList[first].m_SheetNum * aSheetIntervalId + 1;
+
+ // This is the list of all Id already in use for a given reference prefix.
+ // Will be refilled for each new reference prefix.
+ std::vector<int>idList;
+ GetRefsInUse( first, idList, minRefId );
+#endif
+ for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
+ {
+ if( componentFlatList[ii].m_Flag )
+ continue;
+
+ // Check whether this component is in aLockedUnitMap.
+ SCH_REFERENCE_LIST* lockedList = NULL;
+ BOOST_FOREACH( SCH_MULTI_UNIT_REFERENCE_MAP::value_type& pair, aLockedUnitMap )
+ {
+ unsigned n_refs = pair.second.GetCount();
+ for( unsigned thisRefI = 0; thisRefI < n_refs; ++thisRefI )
+ {
+ SCH_REFERENCE &thisRef = pair.second[thisRefI];
+
+ if( thisRef.IsSameInstance( componentFlatList[ii] ) )
+ {
+ lockedList = &pair.second;
+ break;
+ }
+ }
+ if( lockedList != NULL ) break;
+ }
+
+ if( ( componentFlatList[first].CompareRef( componentFlatList[ii] ) != 0 )
+ || ( aUseSheetNum && ( componentFlatList[first].m_SheetNum != componentFlatList[ii].m_SheetNum ) ) )
+ {
+ // New reference found: we need a new ref number for this reference
+ first = ii;
+#ifdef USE_OLD_ALGO
+ minRefId = 0;
+
+ // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
+ if( aUseSheetNum )
+ minRefId = componentFlatList[ii].m_SheetNum * aSheetIntervalId;
+
+ LastReferenceNumber = componentFlatList.GetLastReference( ii, minRefId );
+#else
+ minRefId = 1;
+
+ // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
+ if( aUseSheetNum )
+ minRefId = componentFlatList[ii].m_SheetNum * aSheetIntervalId + 1;
+
+ GetRefsInUse( first, idList, minRefId );
+#endif
+ }
+
+ // Annotation of one part per package components (trivial case).
+ if( componentFlatList[ii].GetLibComponent()->GetUnitCount() <= 1 )
+ {
+ if( componentFlatList[ii].m_IsNew )
+ {
+#ifdef USE_OLD_ALGO
+ LastReferenceNumber++;
+#else
+ LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
+#endif
+ componentFlatList[ii].m_NumRef = LastReferenceNumber;
+ }
+
+ componentFlatList[ii].m_Unit = 1;
+ componentFlatList[ii].m_Flag = 1;
+ componentFlatList[ii].m_IsNew = false;
+ continue;
+ }
+
+ // Annotation of multi-unit parts ( n units per part ) (complex case)
+ NumberOfUnits = componentFlatList[ii].GetLibComponent()->GetUnitCount();
+
+ if( componentFlatList[ii].m_IsNew )
+ {
+#ifdef USE_OLD_ALGO
+ LastReferenceNumber++;
+#else
+ LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
+#endif
+ componentFlatList[ii].m_NumRef = LastReferenceNumber;
+
+ if( !componentFlatList[ii].IsUnitsLocked() )
+ componentFlatList[ii].m_Unit = 1;
+
+ componentFlatList[ii].m_Flag = 1;
+ }
+
+ // If this component is in aLockedUnitMap, copy the annotation to all
+ // components that are not it
+ if( lockedList != NULL )
+ {
+ unsigned n_refs = lockedList->GetCount();
+ for( unsigned thisRefI = 0; thisRefI < n_refs; ++thisRefI )
+ {
+ SCH_REFERENCE &thisRef = (*lockedList)[thisRefI];
+ if( thisRef.IsSameInstance( componentFlatList[ii] ) )
+ {
+ // This is the component we're currently annotating. Hold the unit!
+ componentFlatList[ii].m_Unit = thisRef.m_Unit;
+ }
+
+ if( thisRef.CompareValue( componentFlatList[ii] ) != 0 ) continue;
+ if( thisRef.CompareLibName( componentFlatList[ii] ) != 0 ) continue;
+
+ // Find the matching component
+ for( unsigned jj = ii + 1; jj < componentFlatList.size(); jj++ )
+ {
+ if( ! thisRef.IsSameInstance( componentFlatList[jj] ) ) continue;
+ componentFlatList[jj].m_NumRef = componentFlatList[ii].m_NumRef;
+ componentFlatList[jj].m_Unit = thisRef.m_Unit;
+ componentFlatList[jj].m_IsNew = false;
+ componentFlatList[jj].m_Flag = 1;
+ break;
+ }
+ }
+ }
+
+ else
+ {
+ /* search for others units of this component.
+ * we search for others parts that have the same value and the same
+ * reference prefix (ref without ref number)
+ */
+ for( Unit = 1; Unit <= NumberOfUnits; Unit++ )
+ {
+ if( componentFlatList[ii].m_Unit == Unit )
+ continue;
+
+ int found = FindUnit( ii, Unit );
+
+ if( found >= 0 )
+ continue; // this unit exists for this reference (unit already annotated)
+
+ // Search a component to annotate ( same prefix, same value, not annotated)
+ for( unsigned jj = ii + 1; jj < componentFlatList.size(); jj++ )
+ {
+ if( componentFlatList[jj].m_Flag ) // already tested
+ continue;
+
+ if( componentFlatList[ii].CompareRef( componentFlatList[jj] ) != 0 )
+ continue;
+
+ if( componentFlatList[jj].CompareValue( componentFlatList[ii] ) != 0 )
+ continue;
+
+ if( componentFlatList[jj].CompareLibName( componentFlatList[ii] ) != 0 )
+ continue;
+
+ if( !componentFlatList[jj].m_IsNew )
+ continue;
+
+ // Component without reference number found, annotate it if possible
+ if( !componentFlatList[jj].IsUnitsLocked()
+ || ( componentFlatList[jj].m_Unit == Unit ) )
+ {
+ componentFlatList[jj].m_NumRef = componentFlatList[ii].m_NumRef;
+ componentFlatList[jj].m_Unit = Unit;
+ componentFlatList[jj].m_Flag = 1;
+ componentFlatList[jj].m_IsNew = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+int SCH_REFERENCE_LIST::CheckAnnotation( wxArrayString* aMessageList )
+{
+ int error = 0;
+ wxString tmp;
+ wxString msg;
+
+ SortByRefAndValue();
+
+ // Spiit reference designators into name (prefix) and number: IC1 becomes IC, and 1.
+ SplitReferences();
+
+ // count not yet annotated items or annotation error.
+ for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
+ {
+ msg.Empty();
+ tmp.Empty();
+
+ if( componentFlatList[ii].m_IsNew ) // Not yet annotated
+ {
+ if( componentFlatList[ii].m_NumRef >= 0 )
+ tmp << componentFlatList[ii].m_NumRef;
+ else
+ tmp = wxT( "?" );
+
+
+ if( ( componentFlatList[ii].m_Unit > 0 )
+ && ( componentFlatList[ii].m_Unit < 0x7FFFFFFF ) )
+ {
+ msg.Printf( _( "Item not annotated: %s%s (unit %d)\n" ),
+ GetChars( componentFlatList[ii].GetRef() ),
+ GetChars( tmp ),
+ componentFlatList[ii].m_Unit );
+ }
+ else
+ {
+ msg.Printf( _( "Item not annotated: %s%s\n" ),
+ GetChars( componentFlatList[ii].GetRef() ),
+ GetChars( tmp ) );
+ }
+
+ if( aMessageList )
+ aMessageList->Add( msg + wxT( "\n" ) );
+
+ error++;
+ break;
+ }
+
+ // Error if unit number selected does not exist ( greater than the number of
+ // parts in the component ). This can happen if a component has changed in a
+ // library after a previous annotation.
+ if( std::max( componentFlatList[ii].GetLibComponent()->GetUnitCount(), 1 )
+ < componentFlatList[ii].m_Unit )
+ {
+ if( componentFlatList[ii].m_NumRef >= 0 )
+ tmp << componentFlatList[ii].m_NumRef;
+ else
+ tmp = wxT( "?" );
+
+ msg.Printf( _( "Error item %s%s unit %d and no more than %d parts\n" ),
+ GetChars( componentFlatList[ii].GetRef() ),
+ GetChars( tmp ),
+ componentFlatList[ii].m_Unit,
+ componentFlatList[ii].GetLibComponent()->GetUnitCount() );
+
+ if( aMessageList )
+ aMessageList->Add( msg );
+
+ error++;
+ break;
+ }
+ }
+
+ if( error )
+ return error;
+
+ // count the duplicated elements (if all are annotated)
+ int imax = componentFlatList.size() - 1;
+
+ for( int ii = 0; (ii < imax) && (error < 4); ii++ )
+ {
+ msg.Empty();
+ tmp.Empty();
+
+ if( ( componentFlatList[ii].CompareRef( componentFlatList[ii + 1] ) != 0 )
+ || ( componentFlatList[ii].m_NumRef != componentFlatList[ii + 1].m_NumRef ) )
+ continue;
+
+ // Same reference found. If same unit, error!
+ if( componentFlatList[ii].m_Unit == componentFlatList[ii + 1].m_Unit )
+ {
+ if( componentFlatList[ii].m_NumRef >= 0 )
+ tmp << componentFlatList[ii].m_NumRef;
+ else
+ tmp = wxT( "?" );
+
+ if( ( componentFlatList[ii].m_Unit > 0 )
+ && ( componentFlatList[ii].m_Unit < 0x7FFFFFFF ) )
+ {
+ msg.Printf( _( "Multiple item %s%s (unit %d)\n" ),
+ GetChars( componentFlatList[ii].GetRef() ),
+ GetChars( tmp ),
+ componentFlatList[ii].m_Unit );
+ }
+ else
+ {
+ msg.Printf( _( "Multiple item %s%s\n" ),
+ GetChars( componentFlatList[ii].GetRef() ),
+ GetChars( tmp ) );
+ }
+
+ if( aMessageList )
+ aMessageList->Add( msg );
+
+ error++;
+ continue;
+ }
+
+ /* Test error if units are different but number of parts per package
+ * too high (ex U3 ( 1 part) and we find U3B this is an error) */
+ if( componentFlatList[ii].GetLibComponent()->GetUnitCount()
+ != componentFlatList[ii + 1].GetLibComponent()->GetUnitCount() )
+ {
+ if( componentFlatList[ii].m_NumRef >= 0 )
+ tmp << componentFlatList[ii].m_NumRef;
+ else
+ tmp = wxT( "?" );
+
+ if( ( componentFlatList[ii].m_Unit > 0 )
+ && ( componentFlatList[ii].m_Unit < 0x7FFFFFFF ) )
+ {
+ msg.Printf( _( "Multiple item %s%s (unit %d)\n" ),
+ GetChars( componentFlatList[ii].GetRef() ),
+ GetChars( tmp ),
+ componentFlatList[ii].m_Unit );
+ }
+ else
+ {
+ msg.Printf( _( "Multiple item %s%s\n" ),
+ GetChars( componentFlatList[ii].GetRef() ),
+ GetChars( tmp ) );
+ }
+
+ if( aMessageList )
+ aMessageList->Add( msg );
+
+ error++;
+ }
+
+ // Error if values are different between units, for the same reference
+ int next = ii + 1;
+
+ if( componentFlatList[ii].CompareValue( componentFlatList[next] ) != 0 )
+ {
+ msg.Printf( _( "Different values for %s%d%s (%s) and %s%d%s (%s)" ),
+ GetChars( componentFlatList[ii].GetRef() ),
+ componentFlatList[ii].m_NumRef,
+ GetChars( LIB_PART::SubReference(
+ componentFlatList[ii].m_Unit ) ),
+ GetChars( componentFlatList[ii].m_Value->GetText() ),
+ GetChars( componentFlatList[next].GetRef() ),
+ componentFlatList[next].m_NumRef,
+ GetChars( LIB_PART::SubReference(
+ componentFlatList[next].m_Unit ) ),
+ GetChars( componentFlatList[next].m_Value->GetText() ) );
+
+ if( aMessageList )
+ aMessageList->Add( msg + wxT( "\n" ));
+
+ error++;
+ }
+ }
+
+ // count the duplicated time stamps
+ SortByTimeStamp();
+
+ for( int ii = 0; ( ii < imax ) && ( error < 4 ); ii++ )
+ {
+ if( ( componentFlatList[ii].m_TimeStamp != componentFlatList[ii + 1].m_TimeStamp )
+ || ( componentFlatList[ii].GetSheetPath() != componentFlatList[ii + 1].GetSheetPath() ) )
+ continue;
+
+ // Same time stamp found.
+ wxString full_path;
+
+ full_path.Printf( wxT( "%s%8.8X" ),
+ GetChars( componentFlatList[ii].GetSheetPath().Path() ),
+ componentFlatList[ii].m_TimeStamp );
+
+ msg.Printf( _( "Duplicate time stamp (%s) for %s%d and %s%d" ),
+ GetChars( full_path ),
+ GetChars( componentFlatList[ii].GetRef() ), componentFlatList[ii].m_NumRef,
+ GetChars( componentFlatList[ii + 1].GetRef() ),
+ componentFlatList[ii + 1].m_NumRef );
+
+ if( aMessageList )
+ aMessageList->Add( msg + wxT( "\n" ));
+
+ error++;
+ }
+
+ return error;
+}
+
+
+SCH_REFERENCE::SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_PART* aLibComponent,
+ SCH_SHEET_PATH& aSheetPath )
+{
+ wxASSERT( aComponent != NULL && aLibComponent != NULL );
+
+ m_RootCmp = aComponent;
+ m_Entry = aLibComponent;
+ m_Unit = aComponent->GetUnitSelection( &aSheetPath );
+ m_SheetPath = aSheetPath;
+ m_IsNew = false;
+ m_Flag = 0;
+ m_TimeStamp = aComponent->GetTimeStamp();
+ m_CmpPos = aComponent->GetPosition();
+ m_SheetNum = 0;
+
+ if( aComponent->GetRef( &aSheetPath ).IsEmpty() )
+ aComponent->SetRef( &aSheetPath, wxT( "DefRef?" ) );
+
+ SetRef( aComponent->GetRef( &aSheetPath ) );
+
+ m_NumRef = -1;
+
+ if( aComponent->GetField( VALUE )->GetText().IsEmpty() )
+ aComponent->GetField( VALUE )->SetText( wxT( "~" ) );
+
+ m_Value = aComponent->GetField( VALUE );
+}
+
+
+void SCH_REFERENCE::Annotate()
+{
+ if( m_NumRef < 0 )
+ m_Ref += wxChar( '?' );
+ else
+ m_Ref = TO_UTF8( GetRef() << m_NumRef );
+
+ m_RootCmp->SetRef( &m_SheetPath, FROM_UTF8( m_Ref.c_str() ) );
+ m_RootCmp->SetUnit( m_Unit );
+ m_RootCmp->SetUnitSelection( &m_SheetPath, m_Unit );
+}
+
+
+void SCH_REFERENCE::Split()
+{
+ std::string refText = GetRefStr();
+
+ m_NumRef = -1;
+
+ int ll = refText.length() - 1;
+
+ if( refText[ll] == '?' )
+ {
+ m_IsNew = true;
+
+ if( !IsUnitsLocked() )
+ m_Unit = 0x7FFFFFFF;
+
+ refText.erase( ll ); // delete last char
+
+ SetRefStr( refText );
+ }
+ else if( isdigit( refText[ll] ) == 0 )
+ {
+ m_IsNew = true;
+
+ if( !IsUnitsLocked() )
+ m_Unit = 0x7FFFFFFF;
+ }
+ else
+ {
+ while( ll >= 0 )
+ {
+ if( (refText[ll] <= ' ' ) || isdigit( refText[ll] ) )
+ ll--;
+ else
+ {
+ if( isdigit( refText[ll + 1] ) )
+ {
+ // null terminated C string into cp
+ const char* cp = refText.c_str() + ll + 1;
+
+ m_NumRef = atoi( cp );
+ }
+
+ refText.erase( ll+1 ); // delete from ll+1 to end
+ break;
+ }
+ }
+
+ SetRefStr( refText );
+ }
+}
diff --git a/eeschema/component_tree_search_container.cpp b/eeschema/component_tree_search_container.cpp
new file mode 100644
index 0000000..c3061f9
--- /dev/null
+++ b/eeschema/component_tree_search_container.cpp
@@ -0,0 +1,443 @@
+/* -*- c++ -*-
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
+ * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include <component_tree_search_container.h>
+
+#include <algorithm>
+#include <boost/foreach.hpp>
+#include <set>
+
+#include <wx/string.h>
+#include <wx/tokenzr.h>
+#include <wx/treectrl.h>
+#include <wx/arrstr.h>
+
+#include <class_library.h>
+#include <macros.h>
+
+// Each node gets this lowest score initially, without any matches applied. Matches
+// will then increase this score depending on match quality.
+// This way, an empty search string will result in all components being displayed as they
+// have the minimum score. However, in that case, we avoid expanding all the nodes asd the
+// result is very unspecific.
+static const unsigned kLowestDefaultScore = 1;
+
+struct COMPONENT_TREE_SEARCH_CONTAINER::TREE_NODE
+{
+ // Levels of nodes.
+ enum NODE_TYPE {
+ TYPE_LIB,
+ TYPE_ALIAS,
+ TYPE_UNIT
+ };
+
+ TREE_NODE(NODE_TYPE aType, TREE_NODE* aParent, LIB_ALIAS* aAlias,
+ const wxString& aName, const wxString& aDisplayInfo,
+ const wxString& aSearchText )
+ : Type( aType ),
+ Parent( aParent ), Alias( aAlias ), Unit( 0 ),
+ DisplayName( aName ),
+ DisplayInfo( aDisplayInfo ),
+ MatchName( aName.Lower() ),
+ SearchText( aSearchText.Lower() ),
+ MatchScore( 0 ), PreviousScore( 0 )
+ {
+ }
+
+ const NODE_TYPE Type; ///< Type of node in the hierarchy.
+ TREE_NODE* const Parent; ///< NULL if library, pointer to parent when component/alias.
+ LIB_ALIAS* const Alias; ///< Component alias associated with this entry.
+ int Unit; ///< Part number; Assigned: >= 1; default = 0
+ const wxString DisplayName; ///< Exact name as displayed to the user.
+ const wxString DisplayInfo; ///< Additional info displayed in the tree (description..)
+
+ const wxString MatchName; ///< Preprocessed: lowercased display name.
+ const wxString SearchText; ///< Other text (keywords, description..) to search in.
+
+ unsigned MatchScore; ///< Result-Score after UpdateSearchTerm()
+ unsigned PreviousScore; ///< Optimization: used to see if we need any tree update.
+ wxTreeItemId TreeId; ///< Tree-ID if stored in the tree (if MatchScore > 0).
+};
+
+
+// Sort tree nodes by reverse match-score (bigger is first), then alphabetically.
+// Library (i.e. the ones that don't have a parent) are always sorted before any
+// leaf nodes. Component
+bool COMPONENT_TREE_SEARCH_CONTAINER::scoreComparator( const TREE_NODE* a1, const TREE_NODE* a2 )
+{
+ if( a1->Type != a2->Type )
+ return a1->Type < a2->Type;
+
+ if( a1->MatchScore != a2->MatchScore )
+ return a1->MatchScore > a2->MatchScore; // biggest first.
+
+ if( a1->Parent != a2->Parent )
+ return scoreComparator( a1->Parent, a2->Parent );
+
+ return a1->MatchName.Cmp( a2->MatchName ) < 0;
+}
+
+
+COMPONENT_TREE_SEARCH_CONTAINER::COMPONENT_TREE_SEARCH_CONTAINER( PART_LIBS* aLibs )
+ : m_tree( NULL ),
+ m_libraries_added( 0 ),
+ m_components_added( 0 ),
+ m_preselect_unit_number( -1 ),
+ m_libs( aLibs ),
+ m_filter( CMP_FILTER_NONE )
+{
+}
+
+
+COMPONENT_TREE_SEARCH_CONTAINER::~COMPONENT_TREE_SEARCH_CONTAINER()
+{
+ BOOST_FOREACH( TREE_NODE* node, m_nodes )
+ delete node;
+ m_nodes.clear();
+}
+
+
+void COMPONENT_TREE_SEARCH_CONTAINER::SetPreselectNode( const wxString& aComponentName,
+ int aUnit )
+{
+ m_preselect_node_name = aComponentName.Lower();
+ m_preselect_unit_number = aUnit;
+}
+
+
+void COMPONENT_TREE_SEARCH_CONTAINER::SetTree( wxTreeCtrl* aTree )
+{
+ m_tree = aTree;
+ UpdateSearchTerm( wxEmptyString );
+}
+
+
+void COMPONENT_TREE_SEARCH_CONTAINER::AddLibrary( PART_LIB& aLib )
+{
+ wxArrayString all_aliases;
+
+ if( m_filter == CMP_FILTER_POWER )
+ aLib.GetEntryTypePowerNames( all_aliases );
+ else
+ aLib.GetEntryNames( all_aliases );
+
+ AddAliasList( aLib.GetName(), all_aliases, &aLib );
+
+ ++m_libraries_added;
+}
+
+
+void COMPONENT_TREE_SEARCH_CONTAINER::AddAliasList( const wxString& aNodeName,
+ const wxArrayString& aAliasNameList,
+ PART_LIB* aOptionalLib )
+{
+ TREE_NODE* const lib_node = new TREE_NODE( TREE_NODE::TYPE_LIB, NULL, NULL,
+ aNodeName, wxEmptyString, wxEmptyString );
+ m_nodes.push_back( lib_node );
+
+ BOOST_FOREACH( const wxString& aName, aAliasNameList )
+ {
+ LIB_ALIAS* a;
+
+ if( aOptionalLib )
+ a = aOptionalLib->FindAlias( aName );
+ else
+ a = m_libs->FindLibraryEntry( aName, wxEmptyString );
+
+ if( a == NULL )
+ continue;
+
+ wxString search_text;
+ search_text = ( a->GetKeyWords().empty() ) ? wxT(" ") : a->GetKeyWords();
+ search_text += a->GetDescription();
+
+ wxString display_info;
+
+ if( !a->GetDescription().empty() )
+ {
+ // Preformatting. Unfortunately, the tree widget doesn't have columns
+ // and using tabs does not work very well or does not work at all
+ // (depending on OS versions). So indent with spaces in fixed-font width.
+
+ // The 98%-ile of length of strings found in the standard library is 15
+ // characters. Use this as a reasonable cut-off point for aligned indentation.
+ // For the few component names longer than that, the description is indented a
+ // bit more.
+ // The max found in the default lib would be 20 characters, but that creates too
+ // much visible whitespace for the less extreme component names.
+ const int COLUMN_DESCR_POS = 15;
+ const int indent_len = COLUMN_DESCR_POS - a->GetName().length();
+ display_info = wxString::Format( wxT( " %*s [ %s ]" ),
+ indent_len > 0 ? indent_len : 0, wxT( "" ),
+ GetChars( a->GetDescription() ) );
+ }
+
+ TREE_NODE* alias_node = new TREE_NODE( TREE_NODE::TYPE_ALIAS, lib_node,
+ a, a->GetName(), display_info, search_text );
+ m_nodes.push_back( alias_node );
+
+ if( a->GetPart()->IsMulti() ) // Add all units as sub-nodes.
+ {
+ for( int u = 1; u <= a->GetPart()->GetUnitCount(); ++u )
+ {
+ wxString unitName = _("Unit");
+ unitName += wxT( " " ) + LIB_PART::SubReference( u, false );
+ TREE_NODE* unit_node = new TREE_NODE( TREE_NODE::TYPE_UNIT,
+ alias_node, a,
+ unitName,
+ wxEmptyString, wxEmptyString );
+ unit_node->Unit = u;
+ m_nodes.push_back( unit_node );
+ }
+ }
+
+ ++m_components_added;
+ }
+}
+
+
+LIB_ALIAS* COMPONENT_TREE_SEARCH_CONTAINER::GetSelectedAlias( int* aUnit )
+{
+ if( m_tree == NULL )
+ return NULL;
+
+ const wxTreeItemId& select_id = m_tree->GetSelection();
+
+ BOOST_FOREACH( TREE_NODE* node, m_nodes )
+ {
+ if( node->MatchScore > 0 && node->TreeId == select_id ) {
+ if( aUnit && node->Unit > 0 )
+ *aUnit = node->Unit;
+ return node->Alias;
+ }
+ }
+ return NULL;
+}
+
+
+// Creates a score depending on the position of a string match. If the position
+// is 0 (= prefix match), this returns the maximum score. This degrades until
+// pos == max, which returns a score of 0;
+// Evertyhing else beyond that is just 0. Only values >= 0 allowed for position and max.
+//
+// @param aPosition is the position a string has been found in a substring.
+// @param aMaximum is the maximum score this function returns.
+// @return position dependent score.
+static int matchPosScore(int aPosition, int aMaximum)
+{
+ return ( aPosition < aMaximum ) ? aMaximum - aPosition : 0;
+}
+
+
+void COMPONENT_TREE_SEARCH_CONTAINER::UpdateSearchTerm( const wxString& aSearch )
+{
+ if( m_tree == NULL )
+ return;
+//#define SHOW_CALC_TIME // uncomment this to show calculation time
+
+#ifdef SHOW_CALC_TIME
+ unsigned starttime = GetRunningMicroSecs();
+#endif
+
+ // We score the list by going through it several time, essentially with a complexity
+ // of O(n). For the default library of 2000+ items, this typically takes less than 5ms
+ // on an i5. Good enough, no index needed.
+
+ // Initial AND condition: Leaf nodes are considered to match initially.
+ BOOST_FOREACH( TREE_NODE* node, m_nodes )
+ {
+ node->PreviousScore = node->MatchScore;
+ node->MatchScore = ( node->Type == TREE_NODE::TYPE_LIB ) ? 0 : kLowestDefaultScore;
+ }
+
+ // Create match scores for each node for all the terms, that come space-separated.
+ // Scoring adds up values for each term according to importance of the match. If a term does
+ // not match at all, the result is thrown out of the results (AND semantics).
+ // From high to low
+ // - Exact match for a ccmponent name gives the highest score, trumping all.
+ // - A positional score depending of where a term is found as substring; prefix-match: high.
+ // - substring-match in library name.
+ // - substring match in keywords and descriptions with positional score. Keywords come
+ // first so contribute more to the score.
+ //
+ // This is of course subject to tweaking.
+ wxStringTokenizer tokenizer( aSearch );
+
+ while ( tokenizer.HasMoreTokens() )
+ {
+ const wxString term = tokenizer.GetNextToken().Lower();
+
+ BOOST_FOREACH( TREE_NODE* node, m_nodes )
+ {
+ if( node->Type != TREE_NODE::TYPE_ALIAS )
+ continue; // Only aliases are actually scored here.
+
+ if( node->MatchScore == 0)
+ continue; // Leaf node without score are out of the game.
+
+ // Keywords and description we only count if the match string is at
+ // least two characters long. That avoids spurious, low quality
+ // matches. Most abbreviations are at three characters long.
+ int found_pos;
+
+ if( term == node->MatchName )
+ node->MatchScore += 1000; // exact match. High score :)
+ else if( (found_pos = node->MatchName.Find( term ) ) != wxNOT_FOUND )
+ {
+ // Substring match. The earlier in the string the better. score += 20..40
+ node->MatchScore += matchPosScore( found_pos, 20 ) + 20;
+ }
+ else if( node->Parent->MatchName.Find( term ) != wxNOT_FOUND )
+ node->MatchScore += 19; // parent name matches. score += 19
+ else if( ( found_pos = node->SearchText.Find( term ) ) != wxNOT_FOUND )
+ {
+ // If we have a very short search term (like one or two letters), we don't want
+ // to accumulate scores if they just happen to be in keywords or description as
+ // almost any one or two-letter combination shows up in there.
+ // For longer terms, we add scores 1..18 for positional match (higher in the
+ // front, where the keywords are). score += 0..18
+ node->MatchScore += ( ( term.length() >= 2 )
+ ? matchPosScore( found_pos, 17 ) + 1
+ : 0 );
+ }
+ else
+ node->MatchScore = 0; // No match. That's it for this item.
+ }
+ }
+
+ // Library nodes have the maximum score seen in any of their children.
+ // Alias nodes have the score of their parents.
+ unsigned highest_score_seen = 0;
+ bool any_change = false;
+
+ BOOST_FOREACH( TREE_NODE* node, m_nodes )
+ {
+ switch( node->Type )
+ {
+ case TREE_NODE::TYPE_ALIAS:
+ {
+ any_change |= (node->PreviousScore != node->MatchScore);
+ // Update library score.
+ node->Parent->MatchScore = std::max( node->Parent->MatchScore, node->MatchScore );
+ highest_score_seen = std::max( highest_score_seen, node->MatchScore );
+ }
+ break;
+
+ case TREE_NODE::TYPE_UNIT:
+ node->MatchScore = node->Parent->MatchScore;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // The tree update might be slow, so we want to bail out if there is no change.
+ if( !any_change )
+ return;
+
+ // Now: sort all items according to match score, libraries first.
+ std::sort( m_nodes.begin(), m_nodes.end(), scoreComparator );
+
+#ifdef SHOW_CALC_TIME
+ unsigned sorttime = GetRunningMicroSecs();
+#endif
+
+ // Fill the tree with all items that have a match. Re-arranging, adding and removing changed
+ // items is pretty complex, so we just re-build the whole tree.
+ m_tree->Freeze();
+ m_tree->DeleteAllItems();
+ const wxTreeItemId root_id = m_tree->AddRoot( wxEmptyString );
+ const TREE_NODE* first_match = NULL;
+ const TREE_NODE* preselected_node = NULL;
+
+ BOOST_FOREACH( TREE_NODE* node, m_nodes )
+ {
+ if( node->MatchScore == 0 )
+ continue;
+
+ // If we have nodes that go beyond the default score, suppress nodes that
+ // have the default score. That can happen if they have an honary += 0 score due to
+ // some one-letter match in the keyword or description. In this case, we prefer matches
+ // that just have higher scores. Improves relevancy and performance as the tree has to
+ // display less items.
+ if( highest_score_seen > kLowestDefaultScore && node->MatchScore == kLowestDefaultScore )
+ continue;
+
+ wxString node_text;
+#if 0
+ // Node text with scoring information for debugging
+ node_text.Printf( wxT("%s (s=%u)%s"), GetChars(node->DisplayName),
+ node->MatchScore, GetChars( node->DisplayInfo ));
+#else
+ node_text = node->DisplayName + node->DisplayInfo;
+#endif
+ node->TreeId = m_tree->AppendItem( node->Parent ? node->Parent->TreeId : root_id,
+ node_text );
+
+ // If we are a nicely scored alias, we want to have it visible. Also, if there
+ // is only a single library in this container, we want to have it unfolded
+ // (example: power library).
+ if( node->Type == TREE_NODE::TYPE_ALIAS
+ && ( node->MatchScore > kLowestDefaultScore || m_libraries_added == 1 ) )
+ {
+ m_tree->Expand( node->TreeId );
+
+ if( first_match == NULL )
+ first_match = node; // First, highest scoring: the "I am feeling lucky" element.
+ }
+
+ // The first node that matches our pre-select criteria is choosen. 'First node'
+ // means, it shows up in the history, as the history node is displayed very first
+ // (by virtue of alphabetical ordering)
+ if( preselected_node == NULL
+ && node->Type == TREE_NODE::TYPE_ALIAS
+ && node->MatchName == m_preselect_node_name )
+ preselected_node = node;
+
+ // Refinement in case we come accross a matching unit node.
+ if( preselected_node != NULL && preselected_node->Type == TREE_NODE::TYPE_ALIAS
+ && node->Parent == preselected_node
+ && m_preselect_unit_number >= 1 && node->Unit == m_preselect_unit_number )
+ preselected_node = node;
+ }
+
+ if( first_match ) // Highest score search match pre-selected.
+ {
+ m_tree->SelectItem( first_match->TreeId );
+ m_tree->EnsureVisible( first_match->TreeId );
+ }
+ else if( preselected_node ) // No search, so history item preselected.
+ {
+ m_tree->SelectItem( preselected_node->TreeId );
+ m_tree->EnsureVisible( preselected_node->TreeId );
+ }
+
+ m_tree->Thaw();
+
+#ifdef SHOW_CALC_TIME
+ unsigned endtime = GetRunningMicroSecs();
+ wxLogMessage( wxT("sort components %.1f ms, rebuild tree %.1f ms"),
+ double(sorttime-starttime)/1000.0, double(endtime-sorttime)/1000.0 );
+#endif
+}
diff --git a/eeschema/component_tree_search_container.h b/eeschema/component_tree_search_container.h
new file mode 100644
index 0000000..9d75f91
--- /dev/null
+++ b/eeschema/component_tree_search_container.h
@@ -0,0 +1,145 @@
+/* -*- c++ -*-
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
+ * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http: *www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http: *www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef COMPONENT_TREE_SEARCH_CONTAINER_H
+#define COMPONENT_TREE_SEARCH_CONTAINER_H
+
+#include <vector>
+#include <wx/string.h>
+
+class LIB_ALIAS;
+class PART_LIB;
+class PART_LIBS;
+class wxTreeCtrl;
+class wxArrayString;
+
+// class COMPONENT_TREE_SEARCH_CONTAINER
+// A container for components that allows to search them matching their name, keywords
+// and descriptions, updating a wxTreeCtrl with the results (toplevel nodes:
+// libraries, leafs: components), scored by relevance.
+//
+// The scored result list is adpated on each update on the search-term: this allows
+// to have a search-as-you-type experience.
+class COMPONENT_TREE_SEARCH_CONTAINER
+{
+public:
+ /** This enum allows a selective filtering of component to list
+ * currently: no filtering
+ * list power components only
+ */
+ enum CMP_FILTER_TYPE
+ {
+ CMP_FILTER_NONE, ///< no filtering
+ CMP_FILTER_POWER ///< list components flagged PWR
+ };
+
+public:
+ COMPONENT_TREE_SEARCH_CONTAINER( PART_LIBS* aLibs );
+ ~COMPONENT_TREE_SEARCH_CONTAINER();
+
+ void SetFilter( CMP_FILTER_TYPE aFilter )
+ {
+ m_filter = aFilter;
+ }
+
+ /** Function AddLibrary
+ * Add all the components and their aliases of this library to be searched.
+ * To be called in the setup phase to fill this container.
+ *
+ * @param aLib containting all the components to be added.
+ */
+ void AddLibrary( PART_LIB& aLib );
+
+ /** Function AddComponentList
+ * Add the given list of components, given by name, to be searched.
+ * To be called in the setup phase to fill this container.
+ *
+ * @param aNodeName The parent node name the components will show up as leaf.
+ * @param aAliasNameList List of alias names.
+ * @param aOptionalLib Library to look up the component names (if NULL: global lookup)
+ */
+ void AddAliasList( const wxString& aNodeName, const wxArrayString& aAliasNameList,
+ PART_LIB* aOptionalLib );
+
+ /** Function SetPreselectNode
+ * Set the component name to be selected in absence of any search-result.
+ *
+ * @param aComponentName the component name to be selected.
+ * @param aUnit the component unit to be selected (if > 0).
+ */
+ void SetPreselectNode( const wxString& aComponentName, int aUnit );
+
+ /** Function SetTree
+ * Set the tree to be manipulated.
+ * Each update of the search term will update the tree, with the most
+ * scoring component at the top and selected. If a preselect node is set, this
+ * is displayed. Does not take ownership of the tree.
+ *
+ * @param aTree that is to be modified on search updates.
+ */
+ void SetTree( wxTreeCtrl* aTree );
+
+ /** Function UpdateSearchTerm
+ * Update the search string provided by the user and narrow down the result list.
+ *
+ * This string is a space-separated list of terms, each of which
+ * is applied to the components list to narrow it down. Results are scored by
+ * relevancy (e.g. exact match scores higher than prefix-match which in turn scores
+ * higher than substring match). This updates the search and tree on each call.
+ *
+ * @param aSearch is the user-provided search string.
+ */
+ void UpdateSearchTerm( const wxString& aSearch );
+
+ /** Function GetSelectedAlias
+ *
+ * @param aUnit : if not NULL, the selected sub-unit is set here.
+ * @return the selected alias or NULL if there is none, or there is no tree.
+ */
+ LIB_ALIAS* GetSelectedAlias( int* aUnit );
+
+ /**
+ * Function GetComponentsCount
+ * @return the number of components loaded in the tree
+ */
+ int GetComponentsCount() { return m_components_added; }
+
+
+private:
+ struct TREE_NODE;
+ static bool scoreComparator( const TREE_NODE* a1, const TREE_NODE* a2 );
+
+ std::vector<TREE_NODE*> m_nodes;
+ wxTreeCtrl* m_tree;
+ int m_libraries_added;
+ int m_components_added;
+
+ wxString m_preselect_node_name;
+ int m_preselect_unit_number;
+
+ PART_LIBS* m_libs; // no ownership
+
+ enum CMP_FILTER_TYPE m_filter; // the current filter
+};
+
+#endif /* COMPONENT_TREE_SEARCH_CONTAINER_H */
diff --git a/eeschema/controle.cpp b/eeschema/controle.cpp
new file mode 100644
index 0000000..cfd7c6e
--- /dev/null
+++ b/eeschema/controle.cpp
@@ -0,0 +1,326 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * eeschema/controle.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <eda_dde.h>
+#include <schframe.h>
+#include <menus_helpers.h>
+#include <msgpanel.h>
+
+#include <eeschema_id.h>
+#include <general.h>
+#include <hotkeys.h>
+#include <libeditframe.h>
+#include <viewlib_frame.h>
+#include <lib_draw_item.h>
+#include <lib_pin.h>
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+#include <sch_marker.h>
+#include <sch_component.h>
+
+
+SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, const KICAD_T aFilterList[],
+ int aHotKeyCommandId )
+{
+ SCH_ITEM* item;
+ LIB_PIN* Pin = NULL;
+ SCH_COMPONENT* LibItem = NULL;
+ wxPoint gridPosition = GetNearestGridPosition( aPosition );
+
+ // Check the on grid position first. There is more likely to be multiple items on
+ // grid than off grid.
+ item = LocateItem( gridPosition, aFilterList, aHotKeyCommandId );
+
+ // If the user aborted the clarification context menu, don't show it again at the
+ // off grid position.
+ if( !item && m_canvas->GetAbortRequest() )
+ {
+ m_canvas->SetAbortRequest( false );
+ return NULL;
+ }
+
+ if( !item && (aPosition != gridPosition) )
+ item = LocateItem( aPosition, aFilterList, aHotKeyCommandId );
+
+ if( !item )
+ {
+ m_canvas->SetAbortRequest( false ); // Just in case the user aborted the context menu.
+ return NULL;
+ }
+
+ // Cross probing to Pcbnew if a pin or a component is found
+ switch( item->Type() )
+ {
+ case SCH_FIELD_T:
+ case LIB_FIELD_T:
+ LibItem = (SCH_COMPONENT*) item->GetParent();
+ SendMessageToPCBNEW( item, LibItem );
+ break;
+
+ case SCH_COMPONENT_T:
+ LibItem = (SCH_COMPONENT*) item;
+ SendMessageToPCBNEW( item, LibItem );
+ break;
+
+ case LIB_PIN_T:
+ Pin = (LIB_PIN*) item;
+ LibItem = (SCH_COMPONENT*) LocateItem( aPosition, SCH_COLLECTOR::ComponentsOnly );
+ break;
+
+ default:
+ ;
+ }
+
+ if( Pin )
+ {
+ // Force display pin information (the previous display could be a component info)
+ MSG_PANEL_ITEMS items;
+
+ Pin->GetMsgPanelInfo( items );
+
+ if( LibItem )
+ items.push_back( MSG_PANEL_ITEM( LibItem->GetRef( m_CurrentSheet ),
+ LibItem->GetField( VALUE )->GetShownText(), DARKCYAN ) );
+
+ SetMsgPanel( items );
+
+ // Cross probing:2 - pin found, and send a locate pin command to Pcbnew (highlight net)
+ SendMessageToPCBNEW( Pin, LibItem );
+ }
+
+ return item;
+}
+
+
+SCH_ITEM* SCH_EDIT_FRAME::LocateItem( const wxPoint& aPosition, const KICAD_T aFilterList[],
+ int aHotKeyCommandId )
+{
+ SCH_ITEM* item = NULL;
+
+ m_collectedItems.Collect( GetScreen()->GetDrawItems(), aFilterList, aPosition );
+
+ if( m_collectedItems.GetCount() == 0 )
+ {
+ ClearMsgPanel();
+ }
+ else if( m_collectedItems.GetCount() == 1 )
+ {
+ item = m_collectedItems[0];
+ }
+ else
+ {
+ // There are certain combinations of items that do not need clarification such as
+ // a corner were two lines meet or all the items form a junction.
+ if( aHotKeyCommandId )
+ {
+ switch( aHotKeyCommandId )
+ {
+ case HK_DRAG:
+ if( m_collectedItems.IsCorner() || m_collectedItems.IsNode( false )
+ || m_collectedItems.IsDraggableJunction() )
+ {
+ item = m_collectedItems[0];
+ }
+ default:
+ ;
+ }
+ }
+
+ if( item == NULL )
+ {
+ wxASSERT_MSG( m_collectedItems.GetCount() <= MAX_SELECT_ITEM_IDS,
+ wxT( "Select item clarification context menu size limit exceeded." ) );
+
+ wxMenu selectMenu;
+ wxMenuItem* title = new wxMenuItem( &selectMenu, wxID_NONE, _( "Clarify Selection" ) );
+
+ selectMenu.Append( title );
+ selectMenu.AppendSeparator();
+
+ for( int i = 0; i < m_collectedItems.GetCount() && i < MAX_SELECT_ITEM_IDS; i++ )
+ {
+ wxString text = m_collectedItems[i]->GetSelectMenuText();
+ BITMAP_DEF xpm = m_collectedItems[i]->GetMenuImage();
+ AddMenuItem( &selectMenu, ID_SELECT_ITEM_START + i, text, KiBitmap( xpm ) );
+ }
+
+ // Set to NULL in case user aborts the clarification context menu.
+ GetScreen()->SetCurItem( NULL );
+ m_canvas->SetAbortRequest( true ); // Changed to false if an item is selected
+ PopupMenu( &selectMenu );
+ m_canvas->MoveCursorToCrossHair();
+ item = GetScreen()->GetCurItem();
+ }
+ }
+
+ GetScreen()->SetCurItem( item );
+
+ if( item )
+ {
+ if( item->Type() == SCH_COMPONENT_T )
+ ( (SCH_COMPONENT*) item )->SetCurrentSheetPath( &GetCurrentSheet() );
+
+ MSG_PANEL_ITEMS items;
+ item->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+ }
+ else
+ {
+ ClearMsgPanel();
+ }
+
+ return item;
+}
+
+
+bool SCH_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
+{
+ bool eventHandled = true;
+
+ // Filter out the 'fake' mouse motion after a keyboard movement
+ if( !aHotKey && m_movingCursorWithKeyboard )
+ {
+ m_movingCursorWithKeyboard = false;
+ return false;
+ }
+
+ // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
+ // for next cursor position
+ // ( shift or ctrl key down are PAN command with mouse wheel)
+ bool snapToGrid = true;
+
+ if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
+ snapToGrid = false;
+
+ // Cursor is left off grid only if no block in progress
+ if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
+ snapToGrid = true;
+
+ wxPoint pos = aPosition;
+ wxPoint oldpos = GetCrossHairPosition();
+ GeneralControlKeyMovement( aHotKey, &pos, snapToGrid );
+
+ // Update cursor position.
+ SetCrossHairPosition( pos, snapToGrid );
+ RefreshCrossHair( oldpos, aPosition, aDC );
+
+ if( aHotKey )
+ {
+ SCH_SCREEN* screen = GetScreen();
+
+ if( screen->GetCurItem() && screen->GetCurItem()->GetFlags() )
+ eventHandled = OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() );
+ else
+ eventHandled = OnHotKey( aDC, aHotKey, aPosition, NULL );
+ }
+
+ UpdateStatusBar(); /* Display cursor coordinates info */
+
+ return eventHandled;
+}
+
+
+bool LIB_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
+{
+ bool eventHandled = true;
+
+ // Filter out the 'fake' mouse motion after a keyboard movement
+ if( !aHotKey && m_movingCursorWithKeyboard )
+ {
+ m_movingCursorWithKeyboard = false;
+ return false;
+ }
+
+ // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
+ // for next cursor position
+ // ( shift or ctrl key down are PAN command with mouse wheel)
+ bool snapToGrid = true;
+
+ if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
+ snapToGrid = false;
+
+ // Cursor is left off grid only if no block in progress
+ if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
+ snapToGrid = true;
+
+ wxPoint pos = aPosition;
+ wxPoint oldpos = GetCrossHairPosition();
+ GeneralControlKeyMovement( aHotKey, &pos, snapToGrid );
+
+ // Update the cursor position.
+ SetCrossHairPosition( pos, snapToGrid );
+ RefreshCrossHair( oldpos, aPosition, aDC );
+
+ if( aHotKey )
+ {
+ eventHandled = OnHotKey( aDC, aHotKey, aPosition, NULL );
+ }
+
+ UpdateStatusBar();
+
+ return eventHandled;
+}
+
+
+bool LIB_VIEW_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
+{
+ bool eventHandled = true;
+
+ // Filter out the 'fake' mouse motion after a keyboard movement
+ if( !aHotKey && m_movingCursorWithKeyboard )
+ {
+ m_movingCursorWithKeyboard = false;
+ return false;
+ }
+
+ wxPoint pos = aPosition;
+ wxPoint oldpos = GetCrossHairPosition();
+ GeneralControlKeyMovement( aHotKey, &pos, true );
+
+ // Update cursor position.
+ SetCrossHairPosition( pos, true );
+ RefreshCrossHair( oldpos, aPosition, aDC );
+
+ if( aHotKey )
+ {
+ SCH_SCREEN* screen = GetScreen();
+
+ if( screen->GetCurItem() && screen->GetCurItem()->GetFlags() )
+ eventHandled = OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() );
+ else
+ eventHandled = OnHotKey( aDC, aHotKey, aPosition, NULL );
+ }
+
+ UpdateStatusBar(); // Display cursor coordinates info.
+
+ return eventHandled;
+}
diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp
new file mode 100644
index 0000000..f9b67e7
--- /dev/null
+++ b/eeschema/cross-probing.cpp
@@ -0,0 +1,214 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/cross-probing.cpp
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <kiway_express.h>
+#include <macros.h>
+#include <eda_dde.h>
+#include <schframe.h>
+
+#include <general.h>
+#include <eeschema_id.h>
+#include <lib_draw_item.h>
+#include <lib_pin.h>
+#include <sch_component.h>
+
+
+/**
+ * Execute a remote command sent by Pcbnew via a socket connection.
+ * <p>
+ * When user selects a module or pin in Pcbnew, Eeschema shows that same
+ * component or pin and moves cursor on the item. The socket port used
+ * is #KICAD_SCH_PORT_SERVICE_NUMBER which defaults to 4243.
+ *
+ * Valid commands are:
+ * \li \c \$PART: \c "reference" Put cursor on component.
+ * \li \c \$PART: \c "reference" \c \$REF: \c "ref" Put cursor on component reference.
+ * \li \c \$PART: \c "reference" \c \$VAL: \c "value" Put cursor on component value.
+ * \li \c \$PART: \c "reference" \c \$PAD: \c "pin name" Put cursor on the component pin.
+ * <p>
+ * @param cmdline = received command from Pcbnew
+ */
+void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
+{
+ char line[1024];
+
+ strncpy( line, cmdline, sizeof(line) - 1 );
+ line[ sizeof(line) - 1 ] = '\0';
+
+ char* idcmd = strtok( line, " \n\r" );
+ char* text = strtok( NULL, "\"\n\r" );
+
+ if( (idcmd == NULL) || (text == NULL) )
+ return;
+
+ if( strcmp( idcmd, "$PART:" ) != 0 )
+ return;
+
+ wxString part_ref = FROM_UTF8( text );
+
+ /* look for a complement */
+ idcmd = strtok( NULL, " \n\r" );
+
+ if( idcmd == NULL ) // component only
+ {
+ FindComponentAndItem( part_ref, true, FIND_COMPONENT_ONLY, wxEmptyString, false );
+ return;
+ }
+
+ text = strtok( NULL, "\"\n\r" );
+
+ if( text == NULL )
+ return;
+
+ wxString msg = FROM_UTF8( text );
+
+ if( strcmp( idcmd, "$REF:" ) == 0 )
+ {
+ FindComponentAndItem( part_ref, true, FIND_REFERENCE, msg, false );
+ }
+ else if( strcmp( idcmd, "$VAL:" ) == 0 )
+ {
+ FindComponentAndItem( part_ref, true, FIND_VALUE, msg, false );
+ }
+ else if( strcmp( idcmd, "$PAD:" ) == 0 )
+ {
+ FindComponentAndItem( part_ref, true, FIND_PIN, msg, false );
+ }
+ else
+ {
+ FindComponentAndItem( part_ref, true, FIND_COMPONENT_ONLY, wxEmptyString, false );
+ }
+}
+
+
+std::string FormatProbeItem( EDA_ITEM* aComponent, SCH_COMPONENT* aPart )
+{
+ // Cross probing to Pcbnew if a pin or a component is found
+ switch( aComponent->Type() )
+ {
+ case SCH_FIELD_T:
+ case LIB_FIELD_T:
+ {
+ if( !aPart )
+ break;
+
+ return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
+ }
+ break;
+
+ case SCH_COMPONENT_T:
+ aPart = (SCH_COMPONENT*) aComponent;
+ return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
+
+ case LIB_PIN_T:
+ {
+ if( !aPart )
+ break;
+
+ LIB_PIN* pin = (LIB_PIN*) aComponent;
+
+ if( pin->GetNumber() )
+ {
+ wxString pinnum;
+
+ pin->PinStringNum( pinnum );
+
+ return StrPrintf( "$PIN: %s $PART: %s", TO_UTF8( pinnum ),
+ TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
+ }
+ else
+ {
+ return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return "";
+}
+
+
+void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* aComponent, SCH_COMPONENT* aPart )
+{
+#if 1
+ wxASSERT( aComponent ); // fix the caller
+
+#else // WTF?
+ if( !aComponent ) // caller remains eternally stupid.
+ return;
+#endif
+
+ std::string packet = FormatProbeItem( aComponent, aPart );
+
+ if( packet.size() )
+ {
+ if( Kiface().IsSingle() )
+ SendCommand( MSG_TO_PCB, packet.c_str() );
+ else
+ {
+ // Typically ExpressMail is going to be s-expression packets, but since
+ // we have existing interpreter of the cross probe packet on the other
+ // side in place, we use that here.
+ Kiway().ExpressMail( FRAME_PCB, MAIL_CROSS_PROBE, packet, this );
+ }
+ }
+}
+
+
+void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
+{
+ const std::string& payload = mail.GetPayload();
+
+ switch( mail.Command() )
+ {
+ case MAIL_CROSS_PROBE:
+ ExecuteRemoteCommand( payload.c_str() );
+ break;
+
+ case MAIL_BACKANNOTATE_FOOTPRINTS:
+ try
+ {
+ backAnnotateFootprints( payload );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DBG( printf( "%s: ioe:%s\n", __func__, TO_UTF8( ioe.errorText ) );)
+ }
+ break;
+
+ default:
+ ;
+ }
+}
diff --git a/eeschema/dialog_erc_listbox.h b/eeschema/dialog_erc_listbox.h
new file mode 100644
index 0000000..65bde96
--- /dev/null
+++ b/eeschema/dialog_erc_listbox.h
@@ -0,0 +1,120 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef DIALOG_ERC_LISTBOX_H
+#define DIALOG_ERC_LISTBOX_H
+
+#include <vector>
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <sch_marker.h>
+#include <wx/html/htmlwin.h>
+
+/**
+ * Class ERC_HTML_LISTFRAME
+ * is used to display a DRC_ITEM_LIST.
+ */
+class ERC_HTML_LISTFRAME : public wxHtmlWindow
+{
+private:
+ std::vector<SCH_MARKER*> m_MarkerListReferences; // The pointers to markers shown in list
+
+public:
+ ERC_HTML_LISTFRAME( wxWindow* parent, wxWindowID id = wxID_ANY,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = 0 ) :
+ wxHtmlWindow( parent, id, pos, size, style | wxHW_NO_SELECTION )
+ {
+ }
+
+ ~ERC_HTML_LISTFRAME()
+ {
+ }
+
+
+ /**
+ * Function AppendToList
+ * @param aItem The SCH_MARKER* to add to the current list which will be
+ * later displayed in the wxHtmlWindow
+ */
+ void AppendToList( SCH_MARKER* aMarker )
+ {
+ m_MarkerListReferences.push_back( aMarker );
+ }
+
+ /**
+ * Function DisplayList();
+ * Build the Html marker list and show it
+ */
+ void DisplayList()
+ {
+ wxString htmlpage;
+
+ // for each marker, build a link like:
+ // <A HREF="marker_index">text to click</A>
+ // The "text to click" is the error name (first line of the full error text).
+ wxString marker_text;
+
+ for( unsigned ii = 0; ii < m_MarkerListReferences.size(); ii++ )
+ {
+ marker_text.Printf( wxT( "<A HREF=\"%d\">" ), ii );
+ marker_text << m_MarkerListReferences[ii]->GetReporter().ShowHtml();
+ marker_text.Replace( wxT( "<ul>" ), wxT( "</A><ul>" ), false );
+ htmlpage += marker_text;
+ }
+
+ SetPage( htmlpage );
+ }
+
+ /**
+ * Function GetItem
+ * returns a requested DRC_ITEM* or NULL.
+ */
+ const SCH_MARKER* GetItem( unsigned aIndex )
+ {
+ if( m_MarkerListReferences.size() > aIndex )
+ {
+ return m_MarkerListReferences[ aIndex ];
+ }
+
+ return NULL;
+ }
+
+
+ /**
+ * Function ClearList
+ * deletes all items shown in the list.
+ * Does not erase markers in schematic
+ */
+ void ClearList()
+ {
+ m_MarkerListReferences.clear();
+ SetPage( wxEmptyString );
+ }
+};
+
+#endif
+
+// DIALOG_ERC_LISTBOX_H
diff --git a/eeschema/dialogs/dialog_annotate.cpp b/eeschema/dialogs/dialog_annotate.cpp
new file mode 100644
index 0000000..5c8b002
--- /dev/null
+++ b/eeschema/dialogs/dialog_annotate.cpp
@@ -0,0 +1,320 @@
+/**
+ * @file dialog_annotate.cpp
+ * @brief Annotation dialog functions.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 jean-pierre Charras <jean-pierre.charras@ujf-grenoble.fr>
+ * Copyright (C) 1992-2012 Kicad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <schframe.h>
+#include <class_drawpanel.h>
+
+#include <invoke_sch_dialog.h>
+#include <dialog_annotate_base.h>
+#include <kiface_i.h>
+
+#define KEY_ANNOTATE_SORT_OPTION wxT( "AnnotateSortOption" )
+#define KEY_ANNOTATE_ALGO_OPTION wxT( "AnnotateAlgoOption" )
+#define KEY_ANNOTATE_KEEP_OPEN_OPTION wxT( "AnnotateKeepOpenOption" )
+#define KEY_ANNOTATE_ASK_FOR_CONFIRMATION wxT( "AnnotateRequestConfirmation" )
+
+
+class wxConfigBase;
+
+namespace {
+
+/**
+ * Class DIALOG_ANNOTATE
+ */
+class DIALOG_ANNOTATE: public DIALOG_ANNOTATE_BASE
+{
+public:
+ DIALOG_ANNOTATE( SCH_EDIT_FRAME* parent, wxString message );
+
+
+private:
+ SCH_EDIT_FRAME* m_Parent;
+ wxConfigBase* m_Config;
+
+ /// Initialises member variables
+ void InitValues();
+ void OnCancelClick( wxCommandEvent& event );
+ void OnClearAnnotationCmpClick( wxCommandEvent& event );
+ void OnApplyClick( wxCommandEvent& event );
+
+ // User functions:
+ bool GetLevel();
+ bool GetResetItems();
+ bool GetLockUnits();
+
+ /**
+ * Function GetSortOrder
+ * @return 0 if annotation by X position,
+ * 1 if annotation by Y position,
+ * 2 if annotation by value
+ */
+ int GetSortOrder();
+
+ /**
+ * Function GetAnnotateAlgo
+ * @return 0 if annotation using first not used Id value
+ * 1 if annotation using first not used Id value inside sheet num * 100 to sheet num * 100 + 99
+ * 2 if annotation using first nhot used Id value inside sheet num * 1000 to sheet num * 1000 + 999
+ */
+ int GetAnnotateAlgo();
+
+ bool GetAnnotateKeepOpen()
+ {
+ return m_cbKeepDlgOpen->GetValue();
+ }
+
+ bool GetAnnotateAskForConfirmation()
+ {
+ return m_cbAskForConfirmation->GetValue();
+ }
+};
+
+} // anonymous namespace
+
+
+DIALOG_ANNOTATE::DIALOG_ANNOTATE( SCH_EDIT_FRAME* parent, wxString message )
+ : DIALOG_ANNOTATE_BASE( parent )
+{
+ m_Parent = parent;
+ m_userMessage->SetLabelText( message );
+ m_userMessage->Show( !message.empty() );
+
+ InitValues();
+ Layout();
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+
+void DIALOG_ANNOTATE::InitValues()
+{
+ m_Config = Kiface().KifaceSettings();
+
+ if( m_Config )
+ {
+ long option;
+
+ m_Config->Read( KEY_ANNOTATE_SORT_OPTION, &option, 0L );
+ switch( option )
+ {
+ default:
+ case 0:
+ m_rbSortBy_X_Position->SetValue( 1 );
+ break;
+
+ case 1:
+ m_rbSortBy_Y_Position->SetValue( 1 );
+ break;
+
+ case 2:
+ m_rbUseIncremental->SetValue( 1 );
+ break;
+ }
+
+ m_Config->Read( KEY_ANNOTATE_ALGO_OPTION, &option, 0L );
+ switch( option )
+ {
+ default:
+ case 0:
+ m_rbUseIncremental->SetValue( 1 );
+ break;
+
+ case 1:
+ m_rbUseSheetNum->SetValue( 1 );
+ break;
+
+ case 2:
+ m_rbStartSheetNumLarge->SetValue( 1 );
+ break;
+ }
+
+
+ m_Config->Read( KEY_ANNOTATE_KEEP_OPEN_OPTION, &option, 0L );
+ m_cbKeepDlgOpen->SetValue( option );
+
+
+ m_Config->Read( KEY_ANNOTATE_ASK_FOR_CONFIRMATION, &option, 1L );
+ m_cbAskForConfirmation->SetValue( option );
+ }
+
+ annotate_down_right_bitmap->SetBitmap( KiBitmap( annotate_down_right_xpm ) );
+ annotate_right_down_bitmap->SetBitmap( KiBitmap( annotate_right_down_xpm ) );
+
+ m_btnApply->SetDefault();
+}
+
+
+void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event )
+{
+ int response;
+ wxString message;
+
+ if( m_Config )
+ {
+ m_Config->Write( KEY_ANNOTATE_SORT_OPTION, GetSortOrder() );
+ m_Config->Write( KEY_ANNOTATE_ALGO_OPTION, GetAnnotateAlgo() );
+ m_Config->Write( KEY_ANNOTATE_KEEP_OPEN_OPTION, GetAnnotateKeepOpen() );
+ m_Config->Write( KEY_ANNOTATE_ASK_FOR_CONFIRMATION, GetAnnotateAskForConfirmation() );
+ }
+
+ // Display a message info if we always ask for confirmation
+ // or if a reset of the previous annotation is asked.
+ bool promptUser = GetAnnotateAskForConfirmation();
+
+ if( GetResetItems() )
+ {
+ if( GetLevel() )
+ message += _( "Clear and annotate all of the components on the entire schematic?" );
+ else
+ message += _( "Clear and annotate all of the components on the current sheet?" );
+ promptUser = true;
+ }
+ else
+ {
+ if( GetLevel() )
+ message += _( "Annotate only the unannotated components on the entire schematic?" );
+ else
+ message += _( "Annotate only the unannotated components on the current sheet?" );
+ }
+
+ message += _( "\n\nThis operation will change the current annotation and cannot be undone." );
+
+ if( promptUser )
+ {
+ // TODO(hzeller): ideally, this would be a wxMessageDialog that contains
+ // a checkbox asking the 'ask for confirmation' flag for better
+ // discoverability (and it should only show in the 'benign' case, so if
+ // !GetResetItems())
+ response = wxMessageBox( message, wxT( "" ), wxICON_EXCLAMATION | wxOK | wxCANCEL );
+
+ if( response == wxCANCEL )
+ return;
+ }
+
+ m_Parent->AnnotateComponents( GetLevel(), (ANNOTATE_ORDER_T) GetSortOrder(),
+ (ANNOTATE_OPTION_T) GetAnnotateAlgo(),
+ GetResetItems() , true, GetLockUnits() );
+ m_Parent->GetCanvas()->Refresh();
+
+ m_btnClear->Enable();
+
+ if( !GetAnnotateKeepOpen() )
+ {
+ if( IsModal() )
+ EndModal( wxID_OK );
+ else
+ {
+ SetReturnCode( wxID_OK );
+ this->Show( false );
+ }
+ }
+}
+
+
+void DIALOG_ANNOTATE::OnClearAnnotationCmpClick( wxCommandEvent& event )
+{
+ int response;
+ wxString message;
+
+ if( GetLevel() )
+ message = _( "Clear the existing annotation for the entire schematic?" );
+ else
+ message = _( "Clear the existing annotation for the current sheet?" );
+
+ message += _( "\n\nThis operation will clear the existing annotation and cannot be undone." );
+ response = wxMessageBox( message, wxT( "" ), wxICON_EXCLAMATION | wxOK | wxCANCEL );
+
+ if( response == wxCANCEL )
+ return;
+
+ m_Parent->DeleteAnnotation( GetLevel() ? false : true );
+ m_btnClear->Enable( false );
+}
+
+
+void DIALOG_ANNOTATE::OnCancelClick( wxCommandEvent& event )
+{
+ if( IsModal() )
+ EndModal( wxID_CANCEL );
+ else
+ {
+ SetReturnCode( wxID_CANCEL );
+ this->Show( false );
+ }
+}
+
+
+bool DIALOG_ANNOTATE::GetLevel()
+{
+ return m_rbEntireSchematic->GetValue();
+}
+
+
+bool DIALOG_ANNOTATE::GetResetItems()
+{
+ return m_rbResetAnnotation->GetValue() || m_rbResetButLock->GetValue();
+}
+
+bool DIALOG_ANNOTATE::GetLockUnits()
+{
+ return m_rbResetButLock->GetValue();
+}
+
+int DIALOG_ANNOTATE::GetSortOrder()
+{
+ if( m_rbSortBy_X_Position->GetValue() )
+ return 0;
+
+ if( m_rbSortBy_Y_Position->GetValue() )
+ return 1;
+
+ return 2;
+}
+
+
+int DIALOG_ANNOTATE::GetAnnotateAlgo()
+{
+ if( m_rbUseIncremental->GetValue() )
+ return 0;
+
+ if( m_rbUseSheetNum->GetValue() )
+ return 1;
+
+ return 2;
+}
+
+
+int InvokeDialogAnnotate( SCH_EDIT_FRAME* aCaller, wxString message )
+{
+ DIALOG_ANNOTATE dlg( aCaller, message );
+
+ return dlg.ShowModal();
+}
diff --git a/eeschema/dialogs/dialog_annotate_base.cpp b/eeschema/dialogs/dialog_annotate_base.cpp
new file mode 100644
index 0000000..2ae59aa
--- /dev/null
+++ b/eeschema/dialogs/dialog_annotate_base.cpp
@@ -0,0 +1,245 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_annotate_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_ANNOTATE_BASE::DIALOG_ANNOTATE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bmainSizer;
+ bmainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bupperSizer;
+ bupperSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_userMessage = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_userMessage->Wrap( 1 );
+ m_userMessage->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bupperSizer->Add( m_userMessage, 0, wxALL, 5 );
+
+ m_staticTextScope = new wxStaticText( this, wxID_ANY, _("Scope"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextScope->Wrap( -1 );
+ m_staticTextScope->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bupperSizer->Add( m_staticTextScope, 0, wxALL, 6 );
+
+ wxBoxSizer* bscopeOptSizer;
+ bscopeOptSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_rbEntireSchematic = new wxRadioButton( this, ID_ENTIRE_SCHEMATIC, _("Use the &entire schematic"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
+ bscopeOptSizer->Add( m_rbEntireSchematic, 0, wxALL, 3 );
+
+ m_rbCurrPage = new wxRadioButton( this, ID_CURRENT_PAGE, _("Use the current &page only"), wxDefaultPosition, wxDefaultSize, 0 );
+ bscopeOptSizer->Add( m_rbCurrPage, 0, wxALL, 3 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bscopeOptSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_rbKeepAnnotation = new wxRadioButton( this, ID_KEEP_ANNOTATION, _("&Keep existing annotation"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
+ bscopeOptSizer->Add( m_rbKeepAnnotation, 0, wxALL, 3 );
+
+ m_rbResetAnnotation = new wxRadioButton( this, ID_RESET_ANNOTATION, _("&Reset existing annotation"), wxDefaultPosition, wxDefaultSize, 0 );
+ bscopeOptSizer->Add( m_rbResetAnnotation, 0, wxALL, 3 );
+
+ m_rbResetButLock = new wxRadioButton( this, ID_RESET_BUT_LOCK, _("R&eset, but do not swap any annotated multi-unit parts"), wxDefaultPosition, wxDefaultSize, 0 );
+ bscopeOptSizer->Add( m_rbResetButLock, 0, wxALL, 3 );
+
+
+ bupperSizer->Add( bscopeOptSizer, 0, wxEXPAND|wxLEFT, 25 );
+
+ m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bupperSizer->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 );
+
+ m_staticTextOrder = new wxStaticText( this, wxID_ANY, _("Annotation Order"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextOrder->Wrap( -1 );
+ m_staticTextOrder->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bupperSizer->Add( m_staticTextOrder, 0, wxALL, 6 );
+
+ wxBoxSizer* b_orderOptSizer;
+ b_orderOptSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerXpos;
+ bSizerXpos = new wxBoxSizer( wxHORIZONTAL );
+
+ m_rbSortBy_X_Position = new wxRadioButton( this, ID_SORT_BY_X_POSITION, _("Sort components by &X position"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
+ bSizerXpos->Add( m_rbSortBy_X_Position, 0, wxALL, 3 );
+
+
+ bSizerXpos->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ annotate_down_right_bitmap = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerXpos->Add( annotate_down_right_bitmap, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 12 );
+
+
+ b_orderOptSizer->Add( bSizerXpos, 0, wxEXPAND|wxRIGHT, 5 );
+
+ wxBoxSizer* bSizerYpos;
+ bSizerYpos = new wxBoxSizer( wxHORIZONTAL );
+
+ m_rbSortBy_Y_Position = new wxRadioButton( this, ID_SORT_BY_Y_POSITION, _("Sort components by &Y position"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerYpos->Add( m_rbSortBy_Y_Position, 0, wxALL, 3 );
+
+
+ bSizerYpos->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ annotate_right_down_bitmap = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerYpos->Add( annotate_right_down_bitmap, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 12 );
+
+
+ b_orderOptSizer->Add( bSizerYpos, 0, wxEXPAND|wxRIGHT, 5 );
+
+
+ bupperSizer->Add( b_orderOptSizer, 0, wxEXPAND|wxLEFT, 25 );
+
+ m_staticline5 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bupperSizer->Add( m_staticline5, 0, wxEXPAND | wxALL, 5 );
+
+ wxBoxSizer* bSizerAnnotAlgo;
+ bSizerAnnotAlgo = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextAnnotateAlgo = new wxStaticText( this, wxID_ANY, _("Annotation Choice"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextAnnotateAlgo->Wrap( -1 );
+ m_staticTextAnnotateAlgo->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizerAnnotAlgo->Add( m_staticTextAnnotateAlgo, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizer1AlgoChoice;
+ bSizer1AlgoChoice = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerChoiceInc;
+ bSizerChoiceInc = new wxBoxSizer( wxHORIZONTAL );
+
+ m_rbUseIncremental = new wxRadioButton( this, ID_SORT_BY_X_POSITION, _("Use first free number in schematic"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
+ bSizerChoiceInc->Add( m_rbUseIncremental, 0, wxALL, 3 );
+
+
+ bSizerChoiceInc->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ bSizer1AlgoChoice->Add( bSizerChoiceInc, 0, wxEXPAND|wxRIGHT, 5 );
+
+ wxBoxSizer* bSizerChoiceIncBySheet;
+ bSizerChoiceIncBySheet = new wxBoxSizer( wxHORIZONTAL );
+
+ m_rbUseSheetNum = new wxRadioButton( this, wxID_ANY, _("Start to sheet number*100 and use first free number"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerChoiceIncBySheet->Add( m_rbUseSheetNum, 0, wxALL, 3 );
+
+
+ bSizerChoiceIncBySheet->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ bSizer1AlgoChoice->Add( bSizerChoiceIncBySheet, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerChoiceIncBySheetLarge;
+ bSizerChoiceIncBySheetLarge = new wxBoxSizer( wxHORIZONTAL );
+
+ m_rbStartSheetNumLarge = new wxRadioButton( this, wxID_ANY, _("Start to sheet number*1000 and use first free number"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerChoiceIncBySheetLarge->Add( m_rbStartSheetNumLarge, 0, wxALL, 3 );
+
+
+ bSizerChoiceIncBySheetLarge->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ bSizer1AlgoChoice->Add( bSizerChoiceIncBySheetLarge, 1, wxEXPAND, 5 );
+
+
+ bSizerAnnotAlgo->Add( bSizer1AlgoChoice, 1, wxEXPAND|wxLEFT, 25 );
+
+
+ bupperSizer->Add( bSizerAnnotAlgo, 0, wxEXPAND|wxRIGHT, 5 );
+
+ m_staticline4 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bupperSizer->Add( m_staticline4, 0, wxEXPAND | wxALL, 5 );
+
+ wxBoxSizer* bSizerDldOptions;
+ bSizerDldOptions = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextDlgOpts = new wxStaticText( this, wxID_ANY, _("Dialog"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextDlgOpts->Wrap( -1 );
+ m_staticTextDlgOpts->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizerDldOptions->Add( m_staticTextDlgOpts, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerDlgChoices;
+ bSizerDlgChoices = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerChoiceClose;
+ bSizerChoiceClose = new wxBoxSizer( wxHORIZONTAL );
+
+ m_cbKeepDlgOpen = new wxCheckBox( this, wxID_ANY, _("Keep this dialog open"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerChoiceClose->Add( m_cbKeepDlgOpen, 0, wxALL, 5 );
+
+
+ bSizerChoiceClose->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ bSizerDlgChoices->Add( bSizerChoiceClose, 0, wxEXPAND|wxRIGHT, 5 );
+
+ wxBoxSizer* bSizerChoiceSilentMode;
+ bSizerChoiceSilentMode = new wxBoxSizer( wxHORIZONTAL );
+
+ m_cbAskForConfirmation = new wxCheckBox( this, wxID_ANY, _("Always ask for confirmation"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_cbAskForConfirmation->SetValue(true);
+ bSizerChoiceSilentMode->Add( m_cbAskForConfirmation, 0, wxALL, 5 );
+
+
+ bSizerChoiceSilentMode->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ bSizerDlgChoices->Add( bSizerChoiceSilentMode, 1, wxEXPAND, 5 );
+
+
+ bSizerDldOptions->Add( bSizerDlgChoices, 1, wxEXPAND|wxLEFT, 25 );
+
+ m_staticline41 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerDldOptions->Add( m_staticline41, 0, wxEXPAND | wxALL, 5 );
+
+
+ bupperSizer->Add( bSizerDldOptions, 0, wxEXPAND|wxRIGHT, 5 );
+
+ wxBoxSizer* bButtonsSizer;
+ bButtonsSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ m_btnClose = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ bButtonsSizer->Add( m_btnClose, 0, wxALL|wxEXPAND, 5 );
+
+ m_btnClear = new wxButton( this, ID_CLEAR_ANNOTATION_CMP, _("Clear Annotation"), wxDefaultPosition, wxDefaultSize, 0 );
+ bButtonsSizer->Add( m_btnClear, 0, wxALL|wxEXPAND, 5 );
+
+ m_btnApply = new wxButton( this, wxID_APPLY, _("Annotate"), wxDefaultPosition, wxDefaultSize, 0 );
+ bButtonsSizer->Add( m_btnApply, 0, wxALL|wxEXPAND, 5 );
+
+
+ bupperSizer->Add( bButtonsSizer, 0, wxALIGN_CENTER_HORIZONTAL, 6 );
+
+
+ bmainSizer->Add( bupperSizer, 1, wxALL|wxEXPAND, 6 );
+
+
+ this->SetSizer( bmainSizer );
+ this->Layout();
+ bmainSizer->Fit( this );
+
+ // Connect Events
+ m_btnClose->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnCancelClick ), NULL, this );
+ m_btnClear->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnClearAnnotationCmpClick ), NULL, this );
+ m_btnApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnApplyClick ), NULL, this );
+}
+
+DIALOG_ANNOTATE_BASE::~DIALOG_ANNOTATE_BASE()
+{
+ // Disconnect Events
+ m_btnClose->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnCancelClick ), NULL, this );
+ m_btnClear->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnClearAnnotationCmpClick ), NULL, this );
+ m_btnApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ANNOTATE_BASE::OnApplyClick ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_annotate_base.fbp b/eeschema/dialogs/dialog_annotate_base.fbp
new file mode 100644
index 0000000..bc759c0
--- /dev/null
+++ b/eeschema/dialogs/dialog_annotate_base.fbp
@@ -0,0 +1,2636 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_annotate_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_annotate_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_ANNOTATE_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Annotate Schematic</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bupperSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_userMessage</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Scope</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextScope</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">25</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bscopeOptSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ENTIRE_SCHEMATIC</property>
+ <property name="label">Use the &amp;entire schematic</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbEntireSchematic</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRB_GROUP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CURRENT_PAGE</property>
+ <property name="label">Use the current &amp;page only</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbCurrPage</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_KEEP_ANNOTATION</property>
+ <property name="label">&amp;Keep existing annotation</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbKeepAnnotation</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRB_GROUP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_RESET_ANNOTATION</property>
+ <property name="label">&amp;Reset existing annotation</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbResetAnnotation</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_RESET_BUT_LOCK</property>
+ <property name="label">R&amp;eset, but do not swap any annotated multi-unit parts</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbResetButLock</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Annotation Order</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextOrder</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">25</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">b_orderOptSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerXpos</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SORT_BY_X_POSITION</property>
+ <property name="label">Sort components by &amp;X position</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbSortBy_X_Position</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRB_GROUP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">12</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBitmap" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmap">Load From Resource; </property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">annotate_down_right_bitmap</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerYpos</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SORT_BY_Y_POSITION</property>
+ <property name="label">Sort components by &amp;Y position</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbSortBy_Y_Position</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">12</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBitmap" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmap">Load From Resource; </property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">annotate_right_down_bitmap</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerAnnotAlgo</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Annotation Choice</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextAnnotateAlgo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">25</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer1AlgoChoice</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerChoiceInc</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SORT_BY_X_POSITION</property>
+ <property name="label">Use first free number in schematic</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbUseIncremental</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRB_GROUP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerChoiceIncBySheet</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Start to sheet number*100 and use first free number</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbUseSheetNum</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerChoiceIncBySheetLarge</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Start to sheet number*1000 and use first free number</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbStartSheetNumLarge</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerDldOptions</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Dialog</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextDlgOpts</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">25</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerDlgChoices</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerChoiceClose</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Keep this dialog open</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbKeepDlgOpen</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerChoiceSilentMode</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Always ask for confirmation</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbAskForConfirmation</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline41</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bButtonsSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_btnClose</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CLEAR_ANNOTATION_CMP</property>
+ <property name="label">Clear Annotation</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_btnClear</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnClearAnnotationCmpClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_APPLY</property>
+ <property name="label">Annotate</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_btnApply</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnApplyClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_annotate_base.h b/eeschema/dialogs/dialog_annotate_base.h
new file mode 100644
index 0000000..6ab1751
--- /dev/null
+++ b/eeschema/dialogs/dialog_annotate_base.h
@@ -0,0 +1,94 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 20 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_ANNOTATE_BASE_H__
+#define __DIALOG_ANNOTATE_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/radiobut.h>
+#include <wx/statline.h>
+#include <wx/sizer.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/statbmp.h>
+#include <wx/checkbox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_ENTIRE_SCHEMATIC 1000
+#define ID_CURRENT_PAGE 1001
+#define ID_KEEP_ANNOTATION 1002
+#define ID_RESET_ANNOTATION 1003
+#define ID_RESET_BUT_LOCK 1004
+#define ID_SORT_BY_X_POSITION 1005
+#define ID_SORT_BY_Y_POSITION 1006
+#define ID_CLEAR_ANNOTATION_CMP 1007
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_ANNOTATE_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_ANNOTATE_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_userMessage;
+ wxStaticText* m_staticTextScope;
+ wxRadioButton* m_rbEntireSchematic;
+ wxRadioButton* m_rbCurrPage;
+ wxStaticLine* m_staticline1;
+ wxRadioButton* m_rbKeepAnnotation;
+ wxRadioButton* m_rbResetAnnotation;
+ wxRadioButton* m_rbResetButLock;
+ wxStaticLine* m_staticline2;
+ wxStaticText* m_staticTextOrder;
+ wxRadioButton* m_rbSortBy_X_Position;
+ wxStaticBitmap* annotate_down_right_bitmap;
+ wxRadioButton* m_rbSortBy_Y_Position;
+ wxStaticBitmap* annotate_right_down_bitmap;
+ wxStaticLine* m_staticline5;
+ wxStaticText* m_staticTextAnnotateAlgo;
+ wxRadioButton* m_rbUseIncremental;
+ wxRadioButton* m_rbUseSheetNum;
+ wxRadioButton* m_rbStartSheetNumLarge;
+ wxStaticLine* m_staticline4;
+ wxStaticText* m_staticTextDlgOpts;
+ wxCheckBox* m_cbKeepDlgOpen;
+ wxCheckBox* m_cbAskForConfirmation;
+ wxStaticLine* m_staticline41;
+ wxButton* m_btnClose;
+ wxButton* m_btnClear;
+ wxButton* m_btnApply;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnClearAnnotationCmpClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnApplyClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_ANNOTATE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Annotate Schematic"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_ANNOTATE_BASE();
+
+};
+
+#endif //__DIALOG_ANNOTATE_BASE_H__
diff --git a/eeschema/dialogs/dialog_bom.cpp b/eeschema/dialogs/dialog_bom.cpp
new file mode 100644
index 0000000..23bc74d
--- /dev/null
+++ b/eeschema/dialogs/dialog_bom.cpp
@@ -0,0 +1,621 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras@wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/dialogs/dialog_bom.cpp
+ * @brief Dialog box for creating bom and other documents from generic netlist.
+ */
+
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <schframe.h>
+
+#include <netlist.h>
+#include <netlist_exporter_generic.h>
+#include <sch_sheet.h>
+#include <invoke_sch_dialog.h>
+#include <dialog_helpers.h>
+#include <dialog_bom_base.h>
+#include <html_messagebox.h>
+#include <reporter.h>
+
+#define BOM_PLUGINS_KEY wxT("bom_plugins")
+#define BOM_PLUGIN_SELECTED_KEY wxT("bom_plugin_selected")
+
+const char * s_bomHelpInfo =
+#include <dialog_bom_help_html.h>
+;
+
+#include <dialog_bom_cfg_lexer.h>
+
+using namespace T_BOMCFG_T;
+
+/**
+ * Class BOM_CFG_READER_PARSER
+ * holds data and functions pertinent to parsing a S-expression file
+ * for a WORKSHEET_LAYOUT.
+ */
+class BOM_CFG_READER_PARSER : public DIALOG_BOM_CFG_LEXER
+{
+ wxArrayString* m_pluginsList;
+
+public:
+ BOM_CFG_READER_PARSER( wxArrayString* aPlugins,
+ const char* aData, const wxString& aSource );
+ void Parse() throw( PARSE_ERROR, IO_ERROR );
+
+private:
+ void parsePlugin() throw( IO_ERROR, PARSE_ERROR );
+};
+
+// PCB_PLOT_PARAMS_PARSER
+
+BOM_CFG_READER_PARSER::BOM_CFG_READER_PARSER( wxArrayString* aPlugins,
+ const char* aLine,
+ const wxString& aSource ) :
+ DIALOG_BOM_CFG_LEXER( aLine, aSource )
+{
+ m_pluginsList = aPlugins;
+}
+
+
+void BOM_CFG_READER_PARSER::Parse() throw( PARSE_ERROR, IO_ERROR )
+{
+ T token;
+
+ while( ( token = NextTok() ) != T_RIGHT )
+ {
+ if( token == T_EOF)
+ break;
+
+ if( token == T_LEFT )
+ token = NextTok();
+
+ if( token == T_plugins )
+ continue;
+
+ switch( token )
+ {
+ case T_plugin: // Defines a new plugin
+ parsePlugin();
+ break;
+
+ default:
+// Unexpected( CurText() );
+ break;
+ }
+ }
+}
+
+void BOM_CFG_READER_PARSER::parsePlugin() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxString title, command;
+
+ NeedSYMBOLorNUMBER();
+ title = FromUTF8();
+
+ T token;
+ while( ( token = NextTok() ) != T_RIGHT )
+ {
+ if( token == T_EOF)
+ break;
+
+ switch( token )
+ {
+ case T_LEFT:
+ break;
+
+ case T_cmd:
+ NeedSYMBOLorNUMBER();
+ command = FromUTF8();
+ NeedRIGHT();
+ break;
+
+ case T_opts:
+ while( ( token = NextTok() ) != T_RIGHT && token != T_EOF );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ break;
+ }
+ }
+
+ if( ! title.IsEmpty() )
+ {
+ m_pluginsList->Add( title );
+ m_pluginsList->Add( command );
+ }
+}
+
+// The main dialog frame tu run scripts to build bom
+class DIALOG_BOM : public DIALOG_BOM_BASE
+{
+private:
+ SCH_EDIT_FRAME* m_parent;
+ // The list of scripts (or plugins):
+ // a script descr uses 2 lines:
+ // the first is the title
+ // the second is the command line
+ wxArrayString m_plugins;
+ wxConfigBase* m_config; // to store the "plugins"
+
+public:
+ // Constructor and destructor
+ DIALOG_BOM( SCH_EDIT_FRAME* parent );
+ ~DIALOG_BOM();
+
+private:
+ void OnPluginSelected( wxCommandEvent& event );
+ void OnRunPlugin( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+ void OnHelp( wxCommandEvent& event );
+ void OnAddPlugin( wxCommandEvent& event );
+ void OnRemovePlugin( wxCommandEvent& event );
+ void OnEditPlugin( wxCommandEvent& event );
+ void OnCommandLineEdited( wxCommandEvent& event );
+ void OnNameEdited( wxCommandEvent& event );
+
+ void pluginInit();
+ void installPluginsList();
+
+ /**
+ * @return the Plugin filename from a command line
+ * @param aCommand = the command line
+ */
+ wxString getPluginFileName( const wxString& aCommand );
+
+ /**
+ * display (when exists) the text found between the keyword "@package"
+ * (compatible with doxygen comments)
+ * and the end of comment block (""" in python", --> in xml)
+ */
+ void displayPluginInfo( FILE * aFile, const wxString& aFilename );
+
+ /**
+ * Browse plugin files, and set m_CommandStringCtrl field
+ * @return a command line ro run the plugin
+ */
+ wxString choosePlugin();
+};
+
+// Create and show DIALOG_BOM.
+int InvokeDialogCreateBOM( SCH_EDIT_FRAME* aCaller )
+{
+ DIALOG_BOM dlg( aCaller );
+ return dlg.ShowModal();
+}
+
+DIALOG_BOM::DIALOG_BOM( SCH_EDIT_FRAME* parent ) :
+ DIALOG_BOM_BASE( parent )
+{
+ m_parent = parent;
+ m_config = Kiface().KifaceSettings();
+ installPluginsList();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+DIALOG_BOM::~DIALOG_BOM()
+{
+ // Save the plugin descriptions in config.
+ // the config stores only one string.
+ // plugins are saved inside a S expr:
+ // ( plugins
+ // ( plugin "plugin name" (cmd "command line") )
+ // ....
+ // )
+
+ STRING_FORMATTER writer;
+ writer.Print( 0, "(plugins" );
+
+ for( unsigned ii = 0; ii < m_plugins.GetCount(); ii += 2 )
+ {
+ writer.Print( 1, "(plugin %s (cmd %s))",
+ writer.Quotew( m_plugins[ii] ).c_str(),
+ writer.Quotew( m_plugins[ii+1] ).c_str() );
+ }
+
+ writer.Print( 0, ")" );
+
+ wxString list( FROM_UTF8( writer.GetString().c_str() ) );
+
+ m_config->Write( BOM_PLUGINS_KEY, list );
+
+ wxString active_plugin_name = m_lbPlugins->GetStringSelection( );
+ m_config->Write( BOM_PLUGIN_SELECTED_KEY, active_plugin_name );
+
+}
+
+/* Read the initialized plugins in config and fill the list
+ * of names
+ */
+void DIALOG_BOM::installPluginsList()
+{
+ wxString list, active_plugin_name;
+ m_config->Read( BOM_PLUGINS_KEY, &list );
+ m_config->Read( BOM_PLUGIN_SELECTED_KEY, &active_plugin_name );
+
+ if( !list.IsEmpty() )
+ {
+ BOM_CFG_READER_PARSER cfg_parser( &m_plugins, TO_UTF8( list ),
+ wxT( "plugins" ) );
+ try
+ {
+ cfg_parser.Parse();
+ }
+ catch( const IO_ERROR& ioe )
+ {
+// wxLogMessage( ioe.errorText );
+ }
+ }
+
+ // Populate list box
+ for( unsigned ii = 0; ii < m_plugins.GetCount(); ii+=2 )
+ {
+ m_lbPlugins->Append( m_plugins[ii] );
+
+ if( active_plugin_name == m_plugins[ii] )
+ m_lbPlugins->SetSelection( ii/2 );
+ }
+
+ pluginInit();
+}
+
+void DIALOG_BOM::OnPluginSelected( wxCommandEvent& event )
+{
+ pluginInit();
+}
+
+#include <wx/ffile.h>
+void DIALOG_BOM::pluginInit()
+{
+ int ii = m_lbPlugins->GetSelection();
+
+ if( ii < 0 )
+ {
+ m_textCtrlName->SetValue( wxEmptyString );
+ m_textCtrlCommand->SetValue( wxEmptyString );
+ return;
+ }
+
+ m_textCtrlName->SetValue( m_plugins[2 * ii] );
+ m_textCtrlCommand->SetValue( m_plugins[(2 * ii)+1] );
+
+ wxString pluginName = getPluginFileName( m_textCtrlCommand->GetValue() );
+
+ if( pluginName.IsEmpty() )
+ return;
+
+ FILE* pluginFile = wxFopen( pluginName, "rt" );
+
+ if( pluginFile == NULL )
+ {
+ wxString msg;
+ msg.Printf( _( "Failed to open file '%s'" ), GetChars( pluginName ) );
+ DisplayError( this, msg );
+ return;
+ }
+
+ displayPluginInfo( pluginFile, pluginName );
+}
+
+
+void DIALOG_BOM::displayPluginInfo( FILE * aFile, const wxString& aFilename )
+{
+ m_Messages->Clear();
+
+ // display (when exists) the text found between the keyword "@package"
+ // (compatible with doxygen comments)
+ // and the end of comment block (""" in python", --> in xml)
+
+ wxString data;
+ wxFFile fdata( aFile ); // dtor will close the file
+
+ if( !fdata.ReadAll( &data ) )
+ return;
+
+ wxString header( wxT( "@package" ) );
+ wxString endsection( wxT( "-->" ) ); // For xml
+
+ wxFileName fn( aFilename );
+
+ if( fn.GetExt().IsSameAs( wxT("py"), false ) )
+ endsection = wxT( "\"\"\"" );
+ else if( !fn.GetExt().IsSameAs( wxT("xsl"), false ) )
+ // If this is not a python file, we know nothing about file
+ // and the info cannot be found
+ return;
+
+ // Extract substring between @package and """
+ int strstart = data.Find( header );
+
+ if( strstart == wxNOT_FOUND )
+ return;
+
+ strstart += header.Length();
+ int strend = data.find( endsection, strstart );
+
+ if( strend == wxNOT_FOUND)
+ return;
+
+ // Remove empty line if any
+ while( data[strstart] < ' ' )
+ strstart++;
+
+ m_Messages->SetValue( data.SubString( strstart, strend-1 ) );
+}
+
+/**
+ * Function RunPlugin
+ * run the plugin command line
+ */
+void DIALOG_BOM::OnRunPlugin( wxCommandEvent& event )
+{
+ wxFileName fn;
+
+ // Calculate the xml netlist filename
+ fn = g_RootSheet->GetScreen()->GetFileName();
+
+ fn.SetPath( wxPathOnly( Prj().GetProjectFullName() ) );
+
+ fn.ClearExt();
+ wxString fullfilename = fn.GetFullPath();
+ m_parent->ClearMsgPanel();
+
+ wxString reportmsg;
+ WX_STRING_REPORTER reporter( &reportmsg );
+ m_parent->SetNetListerCommand( m_textCtrlCommand->GetValue() );
+ m_parent->CreateNetlist( -1, fullfilename, 0, &reporter );
+
+ m_Messages->SetValue( reportmsg );
+}
+
+
+void DIALOG_BOM::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+/**
+ * Function OnRemovePlugin
+ * Remove a plugin from the list
+ */
+void DIALOG_BOM::OnRemovePlugin( wxCommandEvent& event )
+{
+ int ii = m_lbPlugins->GetSelection();
+
+ if( ii < 0 )
+ return;
+
+ m_lbPlugins->Delete( ii );
+
+ m_plugins.RemoveAt( 2*ii, 2 ); // Remove title and command line
+
+ // Select the next item, if exists
+ if( (int)m_lbPlugins->GetCount() >= ii )
+ ii = m_lbPlugins->GetCount() - 1;
+
+ if( ii >= 0 )
+ m_lbPlugins->SetSelection( ii );
+
+ pluginInit();
+}
+
+/**
+ * Function OnAddPlugin
+ * Add a new panel for a new netlist plugin
+ */
+void DIALOG_BOM::OnAddPlugin( wxCommandEvent& event )
+{
+ wxString cmdLine = choosePlugin();
+
+ if( cmdLine.IsEmpty() )
+ return;
+
+ // Creates a new plugin entry
+ wxFileName fn( getPluginFileName( cmdLine ) );
+
+ wxString defaultName = fn.GetName();
+ wxString name = wxGetTextFromUser( _("Plugin name in plugin list") ,
+ _("Plugin name"), defaultName );
+
+ if( name.IsEmpty() )
+ return;
+
+ // Verify if it does not exists
+ for( unsigned ii = 0; ii < m_plugins.GetCount(); ii += 2 )
+ {
+ if( name == m_plugins[ii] )
+ {
+ wxMessageBox( _("This name already exists. Abort") );
+ return;
+ }
+ }
+
+ // Eppend the new plugin
+ m_plugins.Add( name );
+ m_plugins.Add( wxEmptyString );
+ m_lbPlugins->SetSelection( m_lbPlugins->GetCount() - 1 );
+ m_lbPlugins->Append( name );
+ m_lbPlugins->SetSelection( m_lbPlugins->GetCount() - 1 );
+ m_textCtrlCommand->SetValue( cmdLine );
+
+ pluginInit();
+}
+
+/*
+ * Browse plugin files, and set m_CommandStringCtrl field
+ */
+wxString DIALOG_BOM::choosePlugin()
+{
+ wxString mask = wxT( "*" );
+#ifndef __WXMAC__
+ wxString path = Pgm().GetExecutablePath();
+#else
+ wxString path = GetOSXKicadDataDir() + wxT( "/plugins" );
+#endif
+
+ wxString fullFileName = EDA_FILE_SELECTOR( _( "Plugin files:" ),
+ path,
+ wxEmptyString,
+ wxEmptyString,
+ mask,
+ this,
+ wxFD_OPEN,
+ true );
+ if( fullFileName.IsEmpty() )
+ return wxEmptyString;
+
+ // Creates a default command line,
+ // suitable to run the external tool xslproc or python
+ // The default command line depending on plugin extension, currently
+ // "xsl" or "exe" or "py"
+ wxString cmdLine;
+ wxFileName fn( fullFileName );
+ wxString ext = fn.GetExt();
+
+ if( ext == wxT("xsl" ) )
+ cmdLine.Printf(wxT("xsltproc -o \"%%O\" \"%s\" \"%%I\""), GetChars( fullFileName ) );
+ else if( ext == wxT("exe" ) || ext.IsEmpty() )
+ cmdLine.Printf(wxT("\"%s\" < \"%%I\" > \"%%O\""), GetChars( fullFileName ) );
+ else if( ext == wxT("py" ) || ext.IsEmpty() )
+ cmdLine.Printf(wxT("python \"%s\" \"%%I\" \"%%O\""), GetChars( fullFileName ) );
+ else
+ cmdLine.Printf(wxT("\"%s\""), GetChars( fullFileName ) );
+
+ return cmdLine;
+}
+
+
+wxString DIALOG_BOM::getPluginFileName( const wxString& aCommand )
+{
+ wxString pluginName;
+
+ // Try to find the plugin name.
+ // This is possible if the name ends by .py or .xsl
+ int pos = -1;
+
+ if( (pos = aCommand.Find( wxT(".py") )) != wxNOT_FOUND )
+ pos += 2;
+ else if( (pos = aCommand.Find( wxT(".xsl") )) != wxNOT_FOUND )
+ pos += 3;
+
+ // the end of plugin name is at position pos.
+ if( pos > 0 )
+ {
+ // Be sure this is the end of the name: the next char is " or space
+ int eos = aCommand[pos+1];
+
+ if( eos == ' '|| eos == '\"' )
+ {
+ // search for the starting point of the name
+ int jj = pos-1;
+ while( jj >= 0 )
+ if( aCommand[jj] != eos )
+ jj--;
+ else
+ break;
+
+ // extract the name
+ if( jj >= 0 )
+ {
+ eos = aCommand[jj];
+
+ if( eos == ' '|| eos == '\"' ) // do not include delimiters
+ jj++;
+
+ pluginName = aCommand.SubString( jj, pos );
+ }
+ }
+ }
+
+ // Using a format like %P is possible in plugin name, so expand it
+ wxString prj_dir = Prj().GetProjectPath();
+
+ if( prj_dir.EndsWith( '/' ) || prj_dir.EndsWith( '\\' ) )
+ prj_dir.RemoveLast();
+
+ pluginName.Replace( wxT( "%P" ), prj_dir.GetData(), true );
+
+ return pluginName;
+}
+
+void DIALOG_BOM::OnEditPlugin( wxCommandEvent& event )
+{
+ wxString pluginName = getPluginFileName( m_textCtrlCommand->GetValue() );
+
+ if( pluginName.Length() <= 2 ) // if name != ""
+ {
+ wxMessageBox( _("Plugin file name not found. Cannot edit plugin file") );
+ return;
+ }
+
+ AddDelimiterString( pluginName );
+ wxString editorname = Pgm().GetEditorName();
+
+ if( !editorname.IsEmpty() )
+ ExecuteFile( this, editorname, pluginName );
+ else
+ wxMessageBox( _("No text editor selected in KiCad. Please choose it") );
+}
+
+void DIALOG_BOM::OnHelp( wxCommandEvent& event )
+{
+ HTML_MESSAGE_BOX help_Dlg( this, _("Bom Generation Help"),
+ wxDefaultPosition, wxSize( 750,550 ) );
+
+ wxString msg = FROM_UTF8(s_bomHelpInfo);
+ help_Dlg.m_htmlWindow->AppendToPage( msg );
+ help_Dlg.ShowModal();
+}
+
+void DIALOG_BOM::OnCommandLineEdited( wxCommandEvent& event )
+{
+ int ii = m_lbPlugins->GetSelection();
+
+ if( ii < 0 )
+ return;
+
+ m_plugins[(2 * ii)+1] = m_textCtrlCommand->GetValue();
+}
+
+void DIALOG_BOM::OnNameEdited( wxCommandEvent& event )
+{
+ int ii = m_lbPlugins->GetSelection();
+
+ if( ii < 0 )
+ return;
+
+ m_plugins[2 * ii] = m_textCtrlName->GetValue();
+ m_lbPlugins->SetString( ii, m_plugins[2 * ii] );
+}
diff --git a/eeschema/dialogs/dialog_bom_base.cpp b/eeschema/dialogs/dialog_bom_base.cpp
new file mode 100644
index 0000000..a32cc24
--- /dev/null
+++ b/eeschema/dialogs/dialog_bom_base.cpp
@@ -0,0 +1,118 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_bom_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+BEGIN_EVENT_TABLE( DIALOG_BOM_BASE, DIALOG_SHIM )
+ EVT_LISTBOX( wxID_ANY, DIALOG_BOM_BASE::_wxFB_OnPluginSelected )
+ EVT_TEXT( IN_NAMELINE, DIALOG_BOM_BASE::_wxFB_OnNameEdited )
+ EVT_BUTTON( ID_CREATE_BOM, DIALOG_BOM_BASE::_wxFB_OnRunPlugin )
+ EVT_BUTTON( wxID_CANCEL, DIALOG_BOM_BASE::_wxFB_OnCancelClick )
+ EVT_BUTTON( ID_HELP, DIALOG_BOM_BASE::_wxFB_OnHelp )
+ EVT_BUTTON( ID_ADD_PLUGIN, DIALOG_BOM_BASE::_wxFB_OnAddPlugin )
+ EVT_BUTTON( ID_REMOVEL_PLUGIN, DIALOG_BOM_BASE::_wxFB_OnRemovePlugin )
+ EVT_BUTTON( wxID_ANY, DIALOG_BOM_BASE::_wxFB_OnEditPlugin )
+ EVT_TEXT( ID_CMDLINE, DIALOG_BOM_BASE::_wxFB_OnCommandLineEdited )
+END_EVENT_TABLE()
+
+DIALOG_BOM_BASE::DIALOG_BOM_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bLeftSizer;
+ bLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextPluginTitle = new wxStaticText( this, wxID_ANY, _("Plugins"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextPluginTitle->Wrap( -1 );
+ bLeftSizer->Add( m_staticTextPluginTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_lbPlugins = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ bLeftSizer->Add( m_lbPlugins, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticTextName = new wxStaticText( this, wxID_ANY, _("Name:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextName->Wrap( -1 );
+ bLeftSizer->Add( m_staticTextName, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_textCtrlName = new wxTextCtrl( this, IN_NAMELINE, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textCtrlName->SetMaxLength( 0 );
+ bLeftSizer->Add( m_textCtrlName, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bUpperSizer->Add( bLeftSizer, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bRightSizer;
+ bRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonNetlist = new wxButton( this, ID_CREATE_BOM, _("Generate"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonNetlist->SetDefault();
+ bRightSizer->Add( m_buttonNetlist, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonCancel, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonHelp = new wxButton( this, ID_HELP, _("Help"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonHelp, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bRightSizer->Add( m_staticline2, 0, wxEXPAND|wxALL, 5 );
+
+ m_buttonAddPlugin = new wxButton( this, ID_ADD_PLUGIN, _("Add Plugin"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonAddPlugin, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonDelPlugin = new wxButton( this, ID_REMOVEL_PLUGIN, _("Remove Plugin"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonDelPlugin, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonEdit = new wxButton( this, wxID_ANY, _("Edit Plugin File"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonEdit, 0, wxALL|wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( bRightSizer, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bMainSizer->Add( bUpperSizer, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bbottomSizer;
+ bbottomSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextCmd = new wxStaticText( this, wxID_ANY, _("Command line:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextCmd->Wrap( -1 );
+ bbottomSizer->Add( m_staticTextCmd, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_textCtrlCommand = new wxTextCtrl( this, ID_CMDLINE, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textCtrlCommand->SetMaxLength( 0 );
+ m_textCtrlCommand->SetMinSize( wxSize( 380,-1 ) );
+
+ bbottomSizer->Add( m_textCtrlCommand, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bMainSizer->Add( bbottomSizer, 0, wxEXPAND, 5 );
+
+ m_staticTextInfo = new wxStaticText( this, wxID_ANY, _("Plugin Info:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextInfo->Wrap( -1 );
+ bMainSizer->Add( m_staticTextInfo, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_Messages = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY );
+ bMainSizer->Add( m_Messages, 1, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_BOM_BASE::~DIALOG_BOM_BASE()
+{
+}
diff --git a/eeschema/dialogs/dialog_bom_base.fbp b/eeschema/dialogs/dialog_bom_base.fbp
new file mode 100644
index 0000000..f00eec7
--- /dev/null
+++ b/eeschema/dialogs/dialog_bom_base.fbp
@@ -0,0 +1,1445 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">0</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">table</property>
+ <property name="file">dialog_bom_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_bom_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_BOM_BASE</property>
+ <property name="pos"></property>
+ <property name="size">409,393</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Bill of Material</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Plugins</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextPluginTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxListBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_lbPlugins</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox">OnPluginSelected</event>
+ <event name="OnListBoxDClick"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Name:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">IN_NAMELINE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnNameEdited</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CREATE_BOM</property>
+ <property name="label">Generate</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonNetlist</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnRunPlugin</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonCancel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_HELP</property>
+ <property name="label">Help</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonHelp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnHelp</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADD_PLUGIN</property>
+ <property name="label">Add Plugin</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonAddPlugin</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnAddPlugin</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_REMOVEL_PLUGIN</property>
+ <property name="label">Remove Plugin</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonDelPlugin</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnRemovePlugin</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Edit Plugin File</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonEdit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnEditPlugin</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bbottomSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Command line:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextCmd</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CMDLINE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">380,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlCommand</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnCommandLineEdited</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Plugin Info:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextInfo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Messages</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_MULTILINE|wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_bom_base.h b/eeschema/dialogs/dialog_bom_base.h
new file mode 100644
index 0000000..1357199
--- /dev/null
+++ b/eeschema/dialogs/dialog_bom_base.h
@@ -0,0 +1,98 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_BOM_BASE_H__
+#define __DIALOG_BOM_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/listbox.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/statline.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_BOM_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_BOM_BASE : public DIALOG_SHIM
+{
+ DECLARE_EVENT_TABLE()
+ private:
+
+ // Private event handlers
+ void _wxFB_OnPluginSelected( wxCommandEvent& event ){ OnPluginSelected( event ); }
+ void _wxFB_OnNameEdited( wxCommandEvent& event ){ OnNameEdited( event ); }
+ void _wxFB_OnRunPlugin( wxCommandEvent& event ){ OnRunPlugin( event ); }
+ void _wxFB_OnCancelClick( wxCommandEvent& event ){ OnCancelClick( event ); }
+ void _wxFB_OnHelp( wxCommandEvent& event ){ OnHelp( event ); }
+ void _wxFB_OnAddPlugin( wxCommandEvent& event ){ OnAddPlugin( event ); }
+ void _wxFB_OnRemovePlugin( wxCommandEvent& event ){ OnRemovePlugin( event ); }
+ void _wxFB_OnEditPlugin( wxCommandEvent& event ){ OnEditPlugin( event ); }
+ void _wxFB_OnCommandLineEdited( wxCommandEvent& event ){ OnCommandLineEdited( event ); }
+
+
+ protected:
+ enum
+ {
+ IN_NAMELINE = 1000,
+ ID_CREATE_BOM,
+ ID_HELP,
+ ID_ADD_PLUGIN,
+ ID_REMOVEL_PLUGIN,
+ ID_CMDLINE
+ };
+
+ wxStaticText* m_staticTextPluginTitle;
+ wxListBox* m_lbPlugins;
+ wxStaticText* m_staticTextName;
+ wxTextCtrl* m_textCtrlName;
+ wxButton* m_buttonNetlist;
+ wxButton* m_buttonCancel;
+ wxButton* m_buttonHelp;
+ wxStaticLine* m_staticline2;
+ wxButton* m_buttonAddPlugin;
+ wxButton* m_buttonDelPlugin;
+ wxButton* m_buttonEdit;
+ wxStaticText* m_staticTextCmd;
+ wxTextCtrl* m_textCtrlCommand;
+ wxStaticText* m_staticTextInfo;
+ wxTextCtrl* m_Messages;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnPluginSelected( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnNameEdited( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRunPlugin( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnHelp( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnAddPlugin( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRemovePlugin( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnEditPlugin( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCommandLineEdited( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_BOM_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Bill of Material"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 409,393 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_BOM_BASE();
+
+};
+
+#endif //__DIALOG_BOM_BASE_H__
diff --git a/eeschema/dialogs/dialog_bom_cfg.keywords b/eeschema/dialogs/dialog_bom_cfg.keywords
new file mode 100644
index 0000000..8790280
--- /dev/null
+++ b/eeschema/dialogs/dialog_bom_cfg.keywords
@@ -0,0 +1,4 @@
+plugins
+plugin
+cmd
+opts
diff --git a/eeschema/dialogs/dialog_bom_help.html b/eeschema/dialogs/dialog_bom_help.html
new file mode 100644
index 0000000..a254d88
--- /dev/null
+++ b/eeschema/dialogs/dialog_bom_help.html
@@ -0,0 +1,282 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=windows-1252"/>
+ <title>kicad help</title>
+ <meta name="generator" content="LibreOffice 4.3.5.2 (Windows)"/>
+ <meta name="created" content="00:00:00"/>
+ <meta name="changed" content="2015-05-27T11:29:49.733000000"/>
+ <meta name="created" content="00:00:00">
+ <meta name="changed" content="2015-05-27T10:36:10.287000000">
+ <meta name="created" content="00:00:00">
+ <meta name="changed" content="2015-05-27T09:45:48.809000000">
+ <meta name="created" content="00:00:00">
+ <meta name="changed" content="2015-05-27T09:29:26.026000000">
+ <meta name="created" content="00:00:00">
+ <meta name="changed" content="2014-12-03T20:04:24.723000000">
+ <meta name="created" content="00:00:00">
+ <meta name="changed" content="2014-12-03T20:04:06.003000000">
+ <meta name="created" content="00:00:00">
+ <meta name="changed" content="2014-12-03T19:59:24.882000000">
+ <style type="text/css">
+ @page { margin: 2cm }
+ p { margin-bottom: 0.21cm; color: #000000; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto }
+ p.western { font-family: "Arial", sans-serif; font-size: 10pt; so-language: en-US }
+ h1 { color: #000000 }
+ h1.western { font-family: "Times New Roman", serif }
+ h2 { color: #000000 }
+ h2.western { font-family: "Times New Roman", serif; font-size: 20pt }
+ h2.cjk { font-family: "SimSun"; font-size: 14pt }
+ h2.ctl { font-family: "Mangal"; font-size: 14pt }
+ h3 { background: transparent; color: #000000 }
+ h3.western { font-family: "Times New Roman", serif; font-size: 16pt; font-style: italic }
+ h3.cjk { font-family: "SimSun" }
+ h3.ctl { font-family: "Mangal" }
+ a:link { color: #004586; text-decoration: none }
+ a.western:link { font-family: "Liberation Sans", sans-serif; so-language: zxx; font-style: italic }
+ a.sdfootnotesym-western { font-family: "DejaVu Serif", serif }
+ </style>
+</head>
+<body lang="en-AU" text="#000000" link="#004586" dir="ltr">
+<h1 class="western"><a name="__RefHeading__2925_482973253"></a>1 -
+Full documentation:</h1>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><span style="font-weight: normal">The
+</span><i><b>Eeschema documentation</b></i> <span style="font-weight: normal">describes
+this </span><b>intermediate netlist and gives examples<br></b><span style="font-weight: normal">See
+also </span><i><b>https://answers.launchpad.net/kicad/+faq/2265</b></i></font></font></p>
+<h1 class="western"><i>2 - </i>The intermediate Netlist File</h1>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">BOM
+files (and netlist files) can be created from an Intermediate netlist
+file created by Eeschema.</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">This
+file uses XML syntax and is called the intermediate netlist. The
+intermediate netlist includes a large amount of data about your board
+and because of this, it can be used with post-processing to create a
+BOM or other reports.</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">Depending
+on the output (BOM or netlist), different subsets of the complete
+Intermediate Netlist file will be used in the post-processing.</font></font></p>
+<h1 class="western">3 - Conversion to a new format</h1>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">By
+applying a post-processing filter to the Intermediate netlist file
+you can generate foreign netlist files as well as BOM files. Because
+this conversion is a text to text transformation.</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">this
+post-processing filter can be written using <b>Python</b>, <b>XSLT</b>,
+or any other tool capable of taking XML as input.</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">XSLT
+itself is a XML language very suitable for XML transformations. There
+is a free program called </span></span></span><i><span style="font-weight: normal">xsltproc</span></i><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">that
+you can download and install. The</span></span></span><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">xsltproc
+program can be used to read the Intermediate XML netlist input file,
+apply</span></span></span><span style="font-variant: normal"> </span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">a
+style-sheet to transform the input, and save the results in an output
+file. Use of xsltproc requires a style-sheet file using XSLT
+conventions. The full conversion process is handled</span></span></span><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">by
+Eeschema, after it is configured once to run xsltproc in a specific
+way.</span></span></span></font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; font-variant: normal; font-style: normal; font-weight: normal; widows: 0; orphans: 0">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">A
+Python script is somewhat more easy to create.</font></font></p>
+<h1 class="western">4 - Initialization of the dialog window</h1>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">You
+should add a new pluging (a script) in plugin list by clicking on the
+Add Plugin button.</font></font></p>
+<h2 class="western">4.1 - Plugin Configuration Parameters</h2>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">The
+Eeschema plug-in configuration dialog requires the following
+information:</font></font></p>
+<ul>
+ <li/>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+ <font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">The
+ title: for instance, the name of the netlist format.</font></font></p>
+ <li/>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+ <font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">The
+ command line to launch the converter (usually a script).</font></font></p>
+</ul>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">Once
+you click on the generate button the following will happen:</font></font></p>
+<ol>
+ <li/>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+ <font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">Eeschema
+ creates an intermediate netlist file *.xml, for instance <i>test.xml.</i></font></font></p>
+ <li/>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+ <font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">Eeschema
+ runs the script from the command line to create the final output
+ file.</font></font></p>
+</ol>
+<h2 class="western">4.2 - Generate netlist files with the command
+line</h2>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">Assuming
+we are using the program <i>xsltproc.exe</i><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal">to
+apply the sheet style to the intermediate file, </span></span><i>xsltproc.exe</i><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal">is
+executed with the following command.</span></span></font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">xsltproc.exe
+-o &lt; output filename &gt; &lt; style-sheet filename &gt; &lt;
+input XML file to convert &gt;</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">On
+Windows the command line is the following.<br><i>f:/kicad/bin/xsltproc.exe
+-o &ldquo;%O&rdquo; f:/kicad/bin/plugins/myconverter.xsl &ldquo;%I&rdquo;</i></font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">On
+Linux the command becomes as following.<br><i>xsltproc -o &ldquo;%O&rdquo;
+/usr/local/kicad/bin/plugins/myconverter .xsl &ldquo;%I&rdquo;<br>w</i><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">here
+</span></span></span><span style="font-variant: normal"><i><span style="font-weight: normal">myconverter</span></i></span><i><span style="font-weight: normal">.xsl</span></i><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">is
+the style-sheet that you are applying.</span></span></span></font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">Do
+not forget the double quotes</span></span></span><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">around
+the file names, this allows them to have spaces after the
+substitution by Eeschema.</span></span></span></font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; font-variant: normal; font-style: normal; font-weight: normal; widows: 0; orphans: 0">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">If
+a Python script is used, the command line is something like
+(depending on the Python script):</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><i>python</i>
+<i>f:/kicad/bin/plugins/bom-in-python/myconverter.py</i>
+&ldquo;<i>%I&rdquo;&ldquo;%O&rdquo;<br>or<br>python</i>
+<i>/usr/local/kicad/bin/plugins/bom-in-python/myconverter .xsl &ldquo;%I&rdquo;
+&ldquo;%O&rdquo; </i></font></font>
+</p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">The
+command line format accepts parameters for filenames:</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">The
+supported formatting parameters are.</font></font></p>
+<ul>
+ <li/>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+ <font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><b>%B</b>
+ =&gt; base filename of selected output file, minus path and extension.</font></font></p>
+ <li/>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0">
+ <font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><b>%P</b>
+ =&gt; project directory, without name and without trailing '/'.</font></font></p>
+ <li/>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+ <font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><b>%I
+ </b>=&gt; complete filename and path of the temporary input file
+ (the intermediate net file).</font></font></p>
+ <li/>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+ <font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><b>%O</b>
+ =&gt; complete filename and path (but without extension) of the user
+ chosen output file.</font></font></p>
+</ul>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><b>%I</b>
+will be replaced by the actual intermediate file name<span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">(usually
+the full root sheet filename with extension &ldquo;.xml&rdquo;)</span></span></span><br><span style="font-variant: normal"><span style="font-style: normal"><b>%O</b></span></span><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">will
+be replaced by the actual output file name (the full root sheet
+filename minus extension).<br></span></span></span><span style="font-variant: normal"><span style="font-style: normal"><b>%B</b></span></span><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">will
+be replaced by the actual output short file name</span></span></span><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">(the
+short root sheet filename minus extension).<br></span></span></span><span style="font-variant: normal"><span style="font-style: normal"><b>%P</b></span></span><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">will
+be replaced by the actual current project path.</span></span></span></font></font></p>
+<h2 class="western">4.3 - Command line format:</h2>
+<h3 class="western">4.3.1 - Remark:</h3>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">Most
+of time, the created file must have an extension, depending on its
+type.<br>Therefore you have to add to the option <i><b>%O</b></i> the
+right file extension.</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">For
+instance:</font></font></p>
+<ul>
+ <li/>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0">
+ <font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><i><b>%O.csv</b></i>
+ to create a .csv file (comma separated value file).</font></font></p>
+ <li/>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0">
+ <font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><i><b>%O.html</b></i>
+ to create a .html file.</font></font></p>
+ <li/>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0">
+ <font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><i><b>%O.bom</b></i>
+ to create a .bom file.</font></font></p>
+</ul>
+<h3 class="western">4.3.2 Example for<i> </i><span style="font-variant: normal"><i>xsltproc:</i></span></h3>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><span style="font-variant: normal"><span style="font-style: normal">The
+command line format for xsltproc is the following:<br>&lt; path of
+</span></span>xsltproc &gt; <span style="font-variant: normal"><span style="font-style: normal">xsltproc
+&lt; </span></span>xsltproc parameters &gt;</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">On
+Windows:<br><i><b>f:/kicad/bin/xsltproc.exe -o &ldquo;%O.bom</b></i>&rdquo;
+<i><b>f:/kicad/bin/plugins/netlist_form_pads-pcb.xsl &ldquo;%I&rdquo;</b></i></font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">On
+Linux:<br><i><b>xsltproc -o &ldquo;%O.bom</b></i>&rdquo;
+<i><b>/usr/local/kicad/bin/plugins/netlist_form_pads-pcb.xsl &ldquo;%I&rdquo;</b></i></font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt"><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">The
+above examples assume</span></span></span><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">xsltproc
+is installed on your PC under Windows xsl</span></span></span><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">exe</span></span></span><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">files
+located in kicad/bin</span></span></span><span style="font-variant: normal"><i><b>plugins/</b></i></span><span style="font-variant: normal"><span style="font-style: normal"><span style="font-weight: normal">.</span></span></span></font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0">
+<br/>
+
+</p>
+<h3 class="western">4.3.3 <i>Example fo</i><span style="font-variant: normal"><i>r
+python scripts:</i></span></h3>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">The
+command line format for python is something like:<br><span style="font-variant: normal"><span style="font-style: normal">python</span></span><span style="font-variant: normal">
+</span><span style="font-variant: normal"><span style="font-style: normal">&lt;
+script file name </span></span>&gt; &lt; input filename &gt; &lt;
+output filename &gt;</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">On
+Windows:<br><i><b>python.exe f:/kicad/bin/plugins
+/bom-in-python/my_python_script.py</b></i> &ldquo;<i><b>%I&rdquo;
+&ldquo;%O.html</b></i>&rdquo;</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">On
+Linux:<br><i><b>python</b></i> <i><b>/usr/local/kicad/bin/plugins
+/bom-in-python/my_python_script.py</b></i> &ldquo;<i><b>%I&rdquo;
+&ldquo;%O.csv</b></i>&rdquo;</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<font face="Times New Roman, serif"><font size="3" style="font-size: 12pt">Assuming
+python is installed on your PC, and python scripts are located in
+<i><b>kicad/bin/plugins /bom-in-python/</b></i>.</font></font></p>
+<p lang="en-US" class="western" style="margin-bottom: 0cm; widows: 0; orphans: 0; page-break-before: auto; page-break-after: auto">
+<br/>
+
+</p>
+</body>
+</html>
diff --git a/eeschema/dialogs/dialog_choose_component.cpp b/eeschema/dialogs/dialog_choose_component.cpp
new file mode 100644
index 0000000..3183c1d
--- /dev/null
+++ b/eeschema/dialogs/dialog_choose_component.cpp
@@ -0,0 +1,409 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
+ * Copyright (C) 2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include <dialog_choose_component.h>
+
+#include <set>
+#include <wx/tokenzr.h>
+
+#include <class_library.h>
+#include <component_tree_search_container.h>
+#include <sch_base_frame.h>
+
+// Tree navigation helpers.
+static wxTreeItemId GetPrevItem( const wxTreeCtrl& tree, const wxTreeItemId& item );
+static wxTreeItemId GetNextItem( const wxTreeCtrl& tree, const wxTreeItemId& item );
+
+DIALOG_CHOOSE_COMPONENT::DIALOG_CHOOSE_COMPONENT( SCH_BASE_FRAME* aParent, const wxString& aTitle,
+ COMPONENT_TREE_SEARCH_CONTAINER* const aContainer,
+ int aDeMorganConvert )
+ : DIALOG_CHOOSE_COMPONENT_BASE( aParent, wxID_ANY, aTitle ), m_search_container( aContainer )
+{
+ m_parent = aParent;
+ m_deMorganConvert = aDeMorganConvert >= 0 ? aDeMorganConvert : 0;
+ m_external_browser_requested = false;
+ m_received_doubleclick_in_tree = false;
+ m_search_container->SetTree( m_libraryComponentTree );
+ m_searchBox->SetFocus();
+ m_componentDetails->SetEditable( false );
+ m_componentView->SetLayoutDirection( wxLayout_LeftToRight );
+
+ m_libraryComponentTree->ScrollTo( m_libraryComponentTree->GetFocusedItem() );
+
+ // The tree showing libs and component uses a fixed font,
+ // because we want controle the position of some info when drawing the
+ // tree. Using tabs does not work very well (does not work on Windows)
+ wxFont font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
+ m_libraryComponentTree->SetFont( wxFont( font.GetPointSize(),
+ wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL ) );
+
+ // We have to call SetSizeHints to fix the minimal size of the dialog
+ // and its widgets.
+ // this line also fixes an issue on Linux Ubuntu using Unity (dialog not shown).
+ GetSizer()->SetSizeHints( this );
+
+ Centre();
+}
+
+
+DIALOG_CHOOSE_COMPONENT::~DIALOG_CHOOSE_COMPONENT()
+{
+ m_search_container->SetTree( NULL );
+}
+
+
+LIB_ALIAS* DIALOG_CHOOSE_COMPONENT::GetSelectedAlias( int* aUnit ) const
+{
+ return m_search_container->GetSelectedAlias( aUnit );
+}
+
+
+void DIALOG_CHOOSE_COMPONENT::OnSearchBoxChange( wxCommandEvent& aEvent )
+{
+ m_search_container->UpdateSearchTerm( m_searchBox->GetLineText( 0 ) );
+ updateSelection();
+
+ // On Windows, but not on Linux, the focus is given to
+ // the m_libraryComponentTree, after modificatuons.
+ // We want the focus for m_searchBox.
+ //
+ // We cannot call SetFocus on Linux because it changes the current text selection
+ // and the text edit cursor position.
+#ifdef __WINDOWS__
+ m_searchBox->SetFocus();
+#endif
+}
+
+
+void DIALOG_CHOOSE_COMPONENT::OnSearchBoxEnter( wxCommandEvent& aEvent )
+{
+ EndModal( wxID_OK ); // We are done.
+}
+
+
+void DIALOG_CHOOSE_COMPONENT::selectIfValid( const wxTreeItemId& aTreeId )
+{
+ if( aTreeId.IsOk() && aTreeId != m_libraryComponentTree->GetRootItem() )
+ m_libraryComponentTree->SelectItem( aTreeId );
+}
+
+
+void DIALOG_CHOOSE_COMPONENT::OnInterceptSearchBoxKey( wxKeyEvent& aKeyStroke )
+{
+ // Cursor up/down and partiallyi cursor are use to do tree navigation operations.
+ // This is done by intercepting some navigational keystrokes that normally would go to
+ // the text search box (which has the focus by default). That way, we are mostly keyboard
+ // operable.
+ // (If the tree has the focus, it can handle that by itself).
+ const wxTreeItemId sel = m_libraryComponentTree->GetSelection();
+
+ switch( aKeyStroke.GetKeyCode() )
+ {
+ case WXK_UP:
+ selectIfValid( GetPrevItem( *m_libraryComponentTree, sel ) );
+ break;
+
+ case WXK_DOWN:
+ selectIfValid( GetNextItem( *m_libraryComponentTree, sel ) );
+ break;
+
+ // The following keys we can only hijack if they are not needed by the textbox itself.
+
+ case WXK_LEFT:
+ if( m_searchBox->GetInsertionPoint() == 0 )
+ m_libraryComponentTree->Collapse( sel );
+ else
+ aKeyStroke.Skip(); // Use for original purpose: move cursor.
+ break;
+
+ case WXK_RIGHT:
+ if( m_searchBox->GetInsertionPoint() >= (long) m_searchBox->GetLineText( 0 ).length() )
+ m_libraryComponentTree->Expand( sel );
+ else
+ aKeyStroke.Skip(); // Use for original purpose: move cursor.
+ break;
+
+ default:
+ aKeyStroke.Skip(); // Any other key: pass on to search box directly.
+ break;
+ }
+}
+
+
+void DIALOG_CHOOSE_COMPONENT::OnTreeSelect( wxTreeEvent& aEvent )
+{
+ updateSelection();
+}
+
+
+// Test strategy for OnDoubleClickTreeActivation()/OnTreeMouseUp() work around wxWidgets bug:
+// - search for an item.
+// - use the mouse to double-click on an item in the tree.
+// -> The dialog should close, and the component should _not_ be immediately placed
+void DIALOG_CHOOSE_COMPONENT::OnDoubleClickTreeActivation( wxTreeEvent& aEvent )
+{
+ if( !updateSelection() )
+ return;
+
+ // Ok, got selection. We don't just end the modal dialog here, but
+ // wait for the MouseUp event to occur. Otherwise something (broken?)
+ // happens: the dialog will close and will deliver the 'MouseUp' event
+ // to the eeschema canvas, that will immediately place the component.
+ m_received_doubleclick_in_tree = true;
+}
+
+
+void DIALOG_CHOOSE_COMPONENT::OnTreeMouseUp( wxMouseEvent& aMouseEvent )
+{
+ if( m_received_doubleclick_in_tree )
+ EndModal( wxID_OK ); // We are done (see OnDoubleClickTreeSelect)
+ else
+ aMouseEvent.Skip(); // Let upstream handle it.
+}
+
+// Test strategy to see if OnInterceptTreeEnter() works:
+// - search for an item.
+// - click into the tree once to set focus on tree; navigate. Press 'Enter'
+// -> The dialog should close and the component be available to place.
+void DIALOG_CHOOSE_COMPONENT::OnInterceptTreeEnter( wxKeyEvent& aEvent )
+{
+ // We have to do some special handling for double-click on a tree-item because
+ // of some superfluous event delivery bug in wxWidgets (see OnDoubleClickTreeActivation()).
+ // In tree-activation, we assume we got a double-click and need to take special precaution
+ // that the mouse-up event is not delivered to the window one level up by going through
+ // a state-sequence OnDoubleClickTreeActivation() -> OnTreeMouseUp().
+
+ // Pressing 'Enter' within a tree will also call OnDoubleClickTreeActivation(),
+ // but since this is not due to the double-click and we have no way of knowing that it is
+ // not, we need to intercept the 'Enter' key before that to know that it is time to exit.
+ if( aEvent.GetKeyCode() == WXK_RETURN )
+ EndModal( wxID_OK ); // Dialog is done.
+ else
+ aEvent.Skip(); // Let tree handle that key for navigation.
+}
+
+
+void DIALOG_CHOOSE_COMPONENT::OnStartComponentBrowser( wxMouseEvent& aEvent )
+{
+ m_external_browser_requested = true;
+ EndModal( wxID_OK ); // We are done.
+}
+
+
+bool DIALOG_CHOOSE_COMPONENT::updateSelection()
+{
+ int unit = 0;
+ LIB_ALIAS* selection = m_search_container->GetSelectedAlias( &unit );
+
+ m_componentView->Refresh();
+
+ m_componentDetails->Clear();
+
+ if( selection == NULL )
+ return false;
+
+ m_componentDetails->Freeze();
+ wxFont font_normal = m_componentDetails->GetFont();
+ wxFont font_bold = m_componentDetails->GetFont();
+ font_bold.SetWeight( wxFONTWEIGHT_BOLD );
+
+ wxTextAttr headline_attribute;
+ headline_attribute.SetFont( font_bold );
+ wxTextAttr text_attribute;
+ text_attribute.SetFont( font_normal );
+
+ const wxString name = selection->GetName();
+
+ if ( !name.empty() )
+ {
+ m_componentDetails->SetDefaultStyle( headline_attribute );
+ m_componentDetails->AppendText( name );
+ }
+
+ const wxString description = selection->GetDescription();
+
+ if( !description.empty() )
+ {
+ if ( !m_componentDetails->IsEmpty() )
+ m_componentDetails->AppendText( wxT( "\n\n" ) );
+
+ m_componentDetails->SetDefaultStyle( headline_attribute );
+ m_componentDetails->AppendText( _( "Description\n" ) );
+ m_componentDetails->SetDefaultStyle( text_attribute );
+ m_componentDetails->AppendText( description );
+ }
+
+ const wxString keywords = selection->GetKeyWords();
+
+ if( !keywords.empty() )
+ {
+ if ( !m_componentDetails->IsEmpty() )
+ m_componentDetails->AppendText( wxT( "\n\n" ) );
+
+ m_componentDetails->SetDefaultStyle( headline_attribute );
+ m_componentDetails->AppendText( _( "Keywords\n" ) );
+ m_componentDetails->SetDefaultStyle( text_attribute );
+ m_componentDetails->AppendText( keywords );
+ }
+
+ if ( !selection->IsRoot() )
+ {
+ LIB_PART* root_part = selection->GetPart();
+ const wxString root_component_name( root_part ? root_part->GetName() : _( "Unknown" ) );
+
+ if ( !m_componentDetails->IsEmpty() )
+ m_componentDetails->AppendText( wxT( "\n\n" ) );
+
+ m_componentDetails->SetDefaultStyle( headline_attribute );
+ m_componentDetails->AppendText( _( "Alias of " ) );
+ m_componentDetails->SetDefaultStyle( text_attribute );
+ m_componentDetails->AppendText( root_component_name );
+ }
+
+ m_componentDetails->SetInsertionPoint( 0 ); // scroll up.
+ m_componentDetails->Thaw();
+
+ return true;
+}
+
+
+void DIALOG_CHOOSE_COMPONENT::OnHandlePreviewRepaint( wxPaintEvent& aRepaintEvent )
+{
+ int unit = 0;
+ LIB_ALIAS* selection = m_search_container->GetSelectedAlias( &unit );
+ LIB_PART* part = selection ? selection->GetPart() : NULL;
+
+ // Don't draw anything (not even the background) if we don't have
+ // a part to show
+ if( !part )
+ return;
+
+ if( selection->IsRoot() )
+ {
+ // just show the part directly
+ renderPreview( part, unit );
+ }
+ else
+ {
+ // switch out the name temporarily for the alias name
+ wxString tmp( part->GetName() );
+ part->SetName( selection->GetName() );
+
+ renderPreview( part, unit );
+
+ part->SetName( tmp );
+ }
+}
+
+
+// Render the preview in our m_componentView. If this gets more complicated, we should
+// probably have a derived class from wxPanel; but this keeps things local.
+void DIALOG_CHOOSE_COMPONENT::renderPreview( LIB_PART* aComponent, int aUnit )
+{
+ wxPaintDC dc( m_componentView );
+
+ const wxSize dc_size = dc.GetSize();
+
+ // Avoid rendering when either dimension is zero
+ if( dc_size.x == 0 || dc_size.y == 0 )
+ return;
+
+ GRResetPenAndBrush( &dc );
+
+ EDA_COLOR_T bgcolor = m_parent->GetDrawBgColor();
+
+ dc.SetBackground( bgcolor == BLACK ? *wxBLACK_BRUSH : *wxWHITE_BRUSH );
+ dc.Clear();
+
+ if( aComponent == NULL )
+ return;
+
+ if( aUnit <= 0 )
+ aUnit = 1;
+
+ dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
+
+ // Find joint bounding box for everything we are about to draw.
+ EDA_RECT bBox = aComponent->GetBoundingBox( aUnit, m_deMorganConvert );
+ const double xscale = (double) dc_size.x / bBox.GetWidth();
+ const double yscale = (double) dc_size.y / bBox.GetHeight();
+ const double scale = std::min( xscale, yscale ) * 0.85;
+
+ dc.SetUserScale( scale, scale );
+
+ wxPoint offset = -bBox.Centre();
+
+
+ aComponent->Draw( NULL, &dc, offset, aUnit, m_deMorganConvert, GR_COPY,
+ UNSPECIFIED_COLOR, DefaultTransform, true, true, false );
+}
+
+
+static wxTreeItemId GetPrevItem( const wxTreeCtrl& tree, const wxTreeItemId& item )
+{
+ wxTreeItemId prevItem = tree.GetPrevSibling( item );
+
+ if( !prevItem.IsOk() )
+ {
+ prevItem = tree.GetItemParent( item );
+ }
+ else if( tree.IsExpanded( prevItem ) )
+ {
+ prevItem = tree.GetLastChild( prevItem );
+ }
+
+ return prevItem;
+}
+
+
+static wxTreeItemId GetNextItem( const wxTreeCtrl& tree, const wxTreeItemId& item )
+{
+ wxTreeItemId nextItem;
+
+ if( !item.IsOk() )
+ return nextItem; // item is not valid: return a not valid wxTreeItemId
+
+ if( tree.IsExpanded( item ) )
+ {
+ wxTreeItemIdValue dummy;
+ nextItem = tree.GetFirstChild( item, dummy );
+ }
+ else
+ {
+ wxTreeItemId root_cell= tree.GetRootItem();
+
+ // Walk up levels until we find one that has a next sibling.
+ for ( wxTreeItemId walk = item; walk.IsOk(); walk = tree.GetItemParent( walk ) )
+ {
+ if( walk == root_cell ) // the root cell (not displayed) is reached
+ break; // Exit (calling GetNextSibling( root_cell ) crashes.
+
+ nextItem = tree.GetNextSibling( walk );
+
+ if( nextItem.IsOk() )
+ break;
+ }
+ }
+
+ return nextItem;
+}
diff --git a/eeschema/dialogs/dialog_choose_component.h b/eeschema/dialogs/dialog_choose_component.h
new file mode 100644
index 0000000..8d8ac24
--- /dev/null
+++ b/eeschema/dialogs/dialog_choose_component.h
@@ -0,0 +1,92 @@
+/* -*- c++ -*-
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
+ * Copyright (C) 2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef DIALOG_CHOOSE_COMPONENT_H
+#define DIALOG_CHOOSE_COMPONENT_H
+
+#include <dialog_choose_component_base.h>
+
+class COMPONENT_TREE_SEARCH_CONTAINER;
+class LIB_ALIAS;
+class LIB_PART;
+class wxTreeItemId;
+class SCH_BASE_FRAME;
+
+class DIALOG_CHOOSE_COMPONENT : public DIALOG_CHOOSE_COMPONENT_BASE
+{
+ SCH_BASE_FRAME* m_parent;
+ COMPONENT_TREE_SEARCH_CONTAINER* const m_search_container;
+ int m_deMorganConvert;
+ bool m_external_browser_requested;
+ bool m_received_doubleclick_in_tree;
+
+public:
+ /**
+ * Create dialog to choose component.
+ *
+ * @param aParent a SCH_BASE_FRAME parent window.
+ * @param aTitle Dialog title.
+ * @param aSearchContainer The tree selection search container. Needs to be pre-populated
+ * This dialog does not take over ownership of this object.
+ * @param aDeMorganConvert preferred deMorgan conversion (TODO: should happen in dialog)
+ */
+ DIALOG_CHOOSE_COMPONENT( SCH_BASE_FRAME* aParent, const wxString& aTitle,
+ COMPONENT_TREE_SEARCH_CONTAINER* const aSearchContainer,
+ int aDeMorganConvert );
+ virtual ~DIALOG_CHOOSE_COMPONENT();
+
+ /** Function GetSelectedAlias
+ * To be called after this dialog returns from ShowModal().
+ *
+ * @param aUnit if not NULL, the selected unit is filled in here.
+ * @return the alias that has been selected, or NULL if there is none.
+ */
+ LIB_ALIAS* GetSelectedAlias( int* aUnit ) const;
+
+ /** Function IsExternalBrowserSelected
+ *
+ * @return true, iff the user pressed the thumbnail view of the component to
+ * launch the component browser.
+ */
+ bool IsExternalBrowserSelected() const { return m_external_browser_requested; }
+
+protected:
+ virtual void OnSearchBoxChange( wxCommandEvent& aEvent );
+ virtual void OnSearchBoxEnter( wxCommandEvent& aEvent );
+ virtual void OnInterceptSearchBoxKey( wxKeyEvent& aEvent );
+
+ virtual void OnTreeSelect( wxTreeEvent& aEvent );
+ virtual void OnDoubleClickTreeActivation( wxTreeEvent& aEvent );
+ virtual void OnInterceptTreeEnter( wxKeyEvent& aEvent );
+ virtual void OnTreeMouseUp( wxMouseEvent& aMouseEvent );
+
+ virtual void OnStartComponentBrowser( wxMouseEvent& aEvent );
+ virtual void OnHandlePreviewRepaint( wxPaintEvent& aRepaintEvent );
+
+private:
+ bool updateSelection();
+ void selectIfValid( const wxTreeItemId& aTreeId );
+ void renderPreview( LIB_PART* aComponent, int aUnit );
+};
+
+#endif /* DIALOG_CHOOSE_COMPONENT_H */
diff --git a/eeschema/dialogs/dialog_choose_component_base.cpp b/eeschema/dialogs/dialog_choose_component_base.cpp
new file mode 100644
index 0000000..3d6f7ad
--- /dev/null
+++ b/eeschema/dialogs/dialog_choose_component_base.cpp
@@ -0,0 +1,93 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_choose_component_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_CHOOSE_COMPONENT_BASE::DIALOG_CHOOSE_COMPONENT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSearchSizer;
+ bSearchSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ m_searchLabel = new wxStaticText( this, wxID_ANY, _("Filter:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_searchLabel->Wrap( -1 );
+ bSearchSizer->Add( m_searchLabel, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ m_searchBox = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
+ bSearchSizer->Add( m_searchBox, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bSizerMain->Add( bSearchSizer, 0, wxEXPAND, 5 );
+
+ m_libraryComponentTree = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE|wxTR_HIDE_ROOT );
+ m_libraryComponentTree->SetMinSize( wxSize( 400,200 ) );
+
+ bSizerMain->Add( m_libraryComponentTree, 1, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerView;
+ bSizerView = new wxBoxSizer( wxHORIZONTAL );
+
+ m_componentView = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER );
+ m_componentView->SetMinSize( wxSize( 200,200 ) );
+
+ bSizerView->Add( m_componentView, 4, wxEXPAND | wxALL, 5 );
+
+ m_componentDetails = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), wxTE_MULTILINE );
+ m_componentDetails->SetMinSize( wxSize( 200,200 ) );
+
+ bSizerView->Add( m_componentDetails, 3, wxALL|wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bSizerView, 1, wxEXPAND, 5 );
+
+ m_stdButtons = new wxStdDialogButtonSizer();
+ m_stdButtonsOK = new wxButton( this, wxID_OK );
+ m_stdButtons->AddButton( m_stdButtonsOK );
+ m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_stdButtons->AddButton( m_stdButtonsCancel );
+ m_stdButtons->Realize();
+
+ bSizerMain->Add( m_stdButtons, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_searchBox->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnInterceptSearchBoxKey ), NULL, this );
+ m_searchBox->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnSearchBoxChange ), NULL, this );
+ m_searchBox->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnSearchBoxEnter ), NULL, this );
+ m_libraryComponentTree->Connect( wxEVT_KEY_UP, wxKeyEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnInterceptTreeEnter ), NULL, this );
+ m_libraryComponentTree->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnTreeMouseUp ), NULL, this );
+ m_libraryComponentTree->Connect( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxTreeEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnDoubleClickTreeActivation ), NULL, this );
+ m_libraryComponentTree->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnTreeSelect ), NULL, this );
+ m_componentView->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnStartComponentBrowser ), NULL, this );
+ m_componentView->Connect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnHandlePreviewRepaint ), NULL, this );
+}
+
+DIALOG_CHOOSE_COMPONENT_BASE::~DIALOG_CHOOSE_COMPONENT_BASE()
+{
+ // Disconnect Events
+ m_searchBox->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnInterceptSearchBoxKey ), NULL, this );
+ m_searchBox->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnSearchBoxChange ), NULL, this );
+ m_searchBox->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnSearchBoxEnter ), NULL, this );
+ m_libraryComponentTree->Disconnect( wxEVT_KEY_UP, wxKeyEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnInterceptTreeEnter ), NULL, this );
+ m_libraryComponentTree->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnTreeMouseUp ), NULL, this );
+ m_libraryComponentTree->Disconnect( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxTreeEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnDoubleClickTreeActivation ), NULL, this );
+ m_libraryComponentTree->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnTreeSelect ), NULL, this );
+ m_componentView->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnStartComponentBrowser ), NULL, this );
+ m_componentView->Disconnect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_CHOOSE_COMPONENT_BASE::OnHandlePreviewRepaint ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_choose_component_base.fbp b/eeschema/dialogs/dialog_choose_component_base.fbp
new file mode 100644
index 0000000..5774001
--- /dev/null
+++ b/eeschema/dialogs/dialog_choose_component_base.fbp
@@ -0,0 +1,594 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_choose_component_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_choose_component_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_CHOOSE_COMPONENT_BASE</property>
+ <property name="pos"></property>
+ <property name="size">503,500</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSearchSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Filter:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_searchLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,-1</property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_searchBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_PROCESS_ENTER</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown">OnInterceptSearchBoxKey</event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnSearchBoxChange</event>
+ <event name="OnTextEnter">OnSearchBoxEnter</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTreeCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">400,200</property>
+ <property name="moveable">1</property>
+ <property name="name">m_libraryComponentTree</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTR_DEFAULT_STYLE|wxTR_HIDE_ROOT</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp">OnInterceptTreeEnter</event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp">OnTreeMouseUp</event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnTreeBeginDrag"></event>
+ <event name="OnTreeBeginLabelEdit"></event>
+ <event name="OnTreeBeginRDrag"></event>
+ <event name="OnTreeDeleteItem"></event>
+ <event name="OnTreeEndDrag"></event>
+ <event name="OnTreeEndLabelEdit"></event>
+ <event name="OnTreeGetInfo"></event>
+ <event name="OnTreeItemActivated">OnDoubleClickTreeActivation</event>
+ <event name="OnTreeItemCollapsed"></event>
+ <event name="OnTreeItemCollapsing"></event>
+ <event name="OnTreeItemExpanded"></event>
+ <event name="OnTreeItemExpanding"></event>
+ <event name="OnTreeItemGetTooltip"></event>
+ <event name="OnTreeItemMenu"></event>
+ <event name="OnTreeItemMiddleClick"></event>
+ <event name="OnTreeItemRightClick"></event>
+ <event name="OnTreeKeyDown"></event>
+ <event name="OnTreeSelChanged">OnTreeSelect</event>
+ <event name="OnTreeSelChanging"></event>
+ <event name="OnTreeSetInfo"></event>
+ <event name="OnTreeStateImageClick"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerView</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">4</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">200,200</property>
+ <property name="moveable">1</property>
+ <property name="name">m_componentView</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp">OnStartComponentBrowser</event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint">OnHandlePreviewRepaint</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">3</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">200,200</property>
+ <property name="moveable">1</property>
+ <property name="name">m_componentDetails</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxTE_MULTILINE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="0">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_stdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_choose_component_base.h b/eeschema/dialogs/dialog_choose_component_base.h
new file mode 100644
index 0000000..afcebe6
--- /dev/null
+++ b/eeschema/dialogs/dialog_choose_component_base.h
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_CHOOSE_COMPONENT_BASE_H__
+#define __DIALOG_CHOOSE_COMPONENT_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/treectrl.h>
+#include <wx/panel.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_CHOOSE_COMPONENT_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_CHOOSE_COMPONENT_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_searchLabel;
+ wxTextCtrl* m_searchBox;
+ wxTreeCtrl* m_libraryComponentTree;
+ wxPanel* m_componentView;
+ wxTextCtrl* m_componentDetails;
+ wxStdDialogButtonSizer* m_stdButtons;
+ wxButton* m_stdButtonsOK;
+ wxButton* m_stdButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnInterceptSearchBoxKey( wxKeyEvent& event ) { event.Skip(); }
+ virtual void OnSearchBoxChange( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnSearchBoxEnter( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnInterceptTreeEnter( wxKeyEvent& event ) { event.Skip(); }
+ virtual void OnTreeMouseUp( wxMouseEvent& event ) { event.Skip(); }
+ virtual void OnDoubleClickTreeActivation( wxTreeEvent& event ) { event.Skip(); }
+ virtual void OnTreeSelect( wxTreeEvent& event ) { event.Skip(); }
+ virtual void OnStartComponentBrowser( wxMouseEvent& event ) { event.Skip(); }
+ virtual void OnHandlePreviewRepaint( wxPaintEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_CHOOSE_COMPONENT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 503,500 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_CHOOSE_COMPONENT_BASE();
+
+};
+
+#endif //__DIALOG_CHOOSE_COMPONENT_BASE_H__
diff --git a/eeschema/dialogs/dialog_color_config.cpp b/eeschema/dialogs/dialog_color_config.cpp
new file mode 100644
index 0000000..c59b067
--- /dev/null
+++ b/eeschema/dialogs/dialog_color_config.cpp
@@ -0,0 +1,296 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Set up color Layers for Eeschema
+ */
+
+#include <fctsys.h>
+#include <draw_frame.h>
+#include <class_drawpanel.h>
+
+#include <general.h>
+
+#include <dialog_color_config.h>
+
+
+#define ID_COLOR_SETUP 1800
+
+// Specify the width and height of every (color-displaying / bitmap) button
+const int BUTT_SIZE_X = 16;
+const int BUTT_SIZE_Y = 16;
+
+
+/********************/
+/* Layer menu list. */
+/********************/
+
+struct COLORBUTTON
+{
+ wxString m_Name;
+ int m_Layer;
+};
+
+struct BUTTONINDEX
+{
+ wxString m_Name;
+ COLORBUTTON* m_Buttons;
+};
+
+static COLORBUTTON generalColorButtons[] = {
+ { _( "Wire" ), LAYER_WIRE },
+ { _( "Bus" ), LAYER_BUS },
+ { _( "Junction" ), LAYER_JUNCTION },
+ { _( "Label" ), LAYER_LOCLABEL },
+ { _( "Global label" ), LAYER_GLOBLABEL },
+ { _( "Net name" ), LAYER_NETNAM },
+ { _( "Notes" ), LAYER_NOTES },
+ { _( "No connect symbol" ), LAYER_NOCONNECT },
+ { wxT( "" ), -1 } // Sentinel marking end of list.
+};
+
+static COLORBUTTON componentColorButtons[] = {
+ { _( "Body" ), LAYER_DEVICE },
+ { _( "Body background" ), LAYER_DEVICE_BACKGROUND },
+ { _( "Pin" ), LAYER_PIN },
+ { _( "Pin number" ), LAYER_PINNUM },
+ { _( "Pin name" ), LAYER_PINNAM },
+ { _( "Reference" ), LAYER_REFERENCEPART },
+ { _( "Value" ), LAYER_VALUEPART },
+ { _( "Fields" ), LAYER_FIELDS },
+ { wxT( "" ), -1 } // Sentinel marking end of list.
+};
+
+static COLORBUTTON sheetColorButtons[] = {
+ { _( "Sheet" ), LAYER_SHEET },
+ { _( "Sheet file name" ), LAYER_SHEETFILENAME },
+ { _( "Sheet name" ), LAYER_SHEETNAME },
+ { _( "Sheet label" ), LAYER_SHEETLABEL },
+ { _( "Hierarchical label" ),LAYER_HIERLABEL },
+ { wxT( "" ), -1 } // Sentinel marking end of list.
+};
+
+static COLORBUTTON miscColorButtons[] = {
+ { _( "ERC warning" ), LAYER_ERC_WARN },
+ { _( "ERC error" ), LAYER_ERC_ERR },
+ { _( "Grid" ), LAYER_GRID },
+ { wxT( "" ), -1 } // Sentinel marking end of list.
+};
+
+
+static BUTTONINDEX buttonGroups[] = {
+ { _( "General" ), generalColorButtons },
+ { _( "Component" ), componentColorButtons },
+ { _( "Sheet" ), sheetColorButtons },
+ { _( "Miscellaneous" ), miscColorButtons },
+ { wxT( "" ), NULL }
+};
+
+
+static EDA_COLOR_T currentColors[ LAYERSCH_ID_COUNT ];
+
+
+DIALOG_COLOR_CONFIG::DIALOG_COLOR_CONFIG( EDA_DRAW_FRAME* aParent ) :
+ DIALOG_COLOR_CONFIG_BASE( aParent )
+{
+ m_parent = aParent;
+ CreateControls();
+
+ GetSizer()->SetSizeHints( this );
+}
+
+
+void DIALOG_COLOR_CONFIG::CreateControls()
+{
+ wxStaticText* label;
+ int buttonId = 1800;
+
+ BUTTONINDEX* groups = buttonGroups;
+ wxBoxSizer* columnBoxSizer = NULL;
+
+ while( groups->m_Buttons != NULL )
+ {
+ COLORBUTTON* buttons = groups->m_Buttons;
+
+ columnBoxSizer = new wxBoxSizer( wxVERTICAL );
+ m_mainBoxSizer->Add( columnBoxSizer, 1, wxALIGN_TOP | wxLEFT | wxTOP, 5 );
+ wxBoxSizer* rowBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+ columnBoxSizer->Add( rowBoxSizer, 0, wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
+
+ // Add a text string to identify the column of color select buttons.
+ label = new wxStaticText( this, wxID_ANY, groups->m_Name );
+
+ // Make the column label font bold.
+ wxFont font( label->GetFont() );
+ font.SetWeight( wxFONTWEIGHT_BOLD );
+ label->SetFont( font );
+
+ rowBoxSizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+
+ while( buttons->m_Layer >= 0 )
+ {
+ rowBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+ columnBoxSizer->Add( rowBoxSizer, 0, wxGROW | wxALL, 0 );
+
+ wxMemoryDC iconDC;
+ wxBitmap bitmap( BUTT_SIZE_X, BUTT_SIZE_Y );
+
+ iconDC.SelectObject( bitmap );
+
+ EDA_COLOR_T color = GetLayerColor( LAYERSCH_ID( buttons->m_Layer ) );
+ currentColors[ buttons->m_Layer ] = color;
+
+ iconDC.SetPen( *wxBLACK_PEN );
+
+ wxBrush brush;
+ ColorSetBrush( &brush, color );
+ brush.SetStyle( wxBRUSHSTYLE_SOLID );
+ iconDC.SetBrush( brush );
+ iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X, BUTT_SIZE_Y );
+
+ wxBitmapButton* bitmapButton = new wxBitmapButton(
+ this, buttonId, bitmap, wxDefaultPosition,
+ wxSize( BUTT_SIZE_X+8, BUTT_SIZE_Y+6 ) );
+ bitmapButton->SetClientData( (void*) buttons );
+
+ rowBoxSizer->Add( bitmapButton, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, 5 );
+
+ label = new wxStaticText( this, wxID_ANY, wxGetTranslation( buttons->m_Name ) );
+ rowBoxSizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, 5 );
+ buttonId += 1;
+ buttons++;
+ }
+
+ groups++;
+ }
+
+ Connect( 1800, buttonId - 1, wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler( DIALOG_COLOR_CONFIG::SetColor ) );
+
+ wxArrayString selBgColorStrings;
+ selBgColorStrings.Add( _( "White" ) );
+ selBgColorStrings.Add( _( "Black" ) );
+ m_SelBgColor = new wxRadioBox( this, wxID_ANY, _( "Background Color" ),
+ wxDefaultPosition, wxDefaultSize,
+ selBgColorStrings, 1, wxRA_SPECIFY_COLS );
+ m_SelBgColor->SetSelection( ( m_parent->GetDrawBgColor() == BLACK ) ? 1 : 0 );
+
+ if( columnBoxSizer )
+ {
+ // Add a spacer to improve appearance.
+ columnBoxSizer->AddSpacer( 5 );
+ columnBoxSizer->Add( m_SelBgColor, 1, wxGROW | wxRIGHT | wxTOP | wxBOTTOM, 5 );
+ }
+
+ currentColors[ LAYER_BACKGROUND ] = m_parent->GetDrawBgColor();
+
+ // Dialog now needs to be resized, but the associated command is found elsewhere.
+}
+
+
+void DIALOG_COLOR_CONFIG::SetColor( wxCommandEvent& event )
+{
+ wxBitmapButton* button = (wxBitmapButton*) event.GetEventObject();
+
+ wxCHECK_RET( button != NULL, wxT( "Color button event object is NULL." ) );
+
+ COLORBUTTON* colorButton = (COLORBUTTON*) button->GetClientData();
+
+ wxCHECK_RET( colorButton != NULL, wxT( "Client data not set for color button." ) );
+
+ EDA_COLOR_T color = DisplayColorFrame( this, colorButton->m_Layer );
+
+ if( color < 0 || currentColors[ colorButton->m_Layer ] == color )
+ return;
+
+ currentColors[ colorButton->m_Layer ] = color;
+
+ wxMemoryDC iconDC;
+
+ wxBitmap bitmap = button->GetBitmapLabel();
+ iconDC.SelectObject( bitmap );
+ iconDC.SetPen( *wxBLACK_PEN );
+
+ wxBrush brush;
+
+ ColorSetBrush( &brush, color);
+
+ brush.SetStyle( wxBRUSHSTYLE_SOLID );
+
+ iconDC.SetBrush( brush );
+ iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X, BUTT_SIZE_Y );
+ button->SetBitmapLabel( bitmap );
+ button->Refresh();
+
+ Refresh( false );
+}
+
+
+bool DIALOG_COLOR_CONFIG::TransferDataFromWindow()
+{
+ bool warning = false;
+
+ // Check for color conflicts with background color to give user a chance to bail
+ // out before making changes.
+
+ EDA_COLOR_T bgcolor = WHITE;
+
+ if( m_SelBgColor->GetSelection() > 0 )
+ bgcolor = BLACK;
+
+ for( LAYERSCH_ID clyr = LAYER_WIRE; clyr < LAYERSCH_ID_COUNT; ++clyr )
+ {
+ if( bgcolor == currentColors[ clyr ] && clyr != LAYER_BACKGROUND )
+ {
+ warning = true;
+ break;
+ }
+ }
+
+ // Prompt the user if an item has the same color as the background
+ // because this item cannot be seen:
+ if( warning )
+ {
+ if( wxMessageBox( _( "Some items have the same color as the background\n"
+ "and they will not be seen on the screen. Are you\n"
+ "sure you want to use these colors?" ),
+ _( "Warning" ),
+ wxYES_NO | wxICON_QUESTION, this ) == wxNO )
+ return false;
+ }
+
+ // Update color of background
+ m_parent->SetDrawBgColor( bgcolor );
+ currentColors[ LAYER_BACKGROUND ] = bgcolor;
+
+
+ for( LAYERSCH_ID clyr = LAYER_WIRE; clyr < LAYERSCH_ID_COUNT; ++clyr )
+ {
+ SetLayerColor( currentColors[ clyr ], clyr );
+ }
+
+ m_parent->SetGridColor( GetLayerColor( LAYER_GRID ) );
+ m_parent->GetCanvas()->Refresh();
+
+ return true;
+}
diff --git a/eeschema/dialogs/dialog_color_config.h b/eeschema/dialogs/dialog_color_config.h
new file mode 100644
index 0000000..0f07367
--- /dev/null
+++ b/eeschema/dialogs/dialog_color_config.h
@@ -0,0 +1,58 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 G. Harland
+ * Copyright (C) 1992-2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef DIALOG_COLOR_CONFIG_H_
+#define DIALOG_COLOR_CONFIG_H_
+
+#include <dialog_color_config_base.h>
+
+
+class wxBoxSizer;
+class wxStaticLine;
+class wxStdDialogButtonSizer;
+
+
+/***********************************************/
+/* Derived class for the frame color settings. */
+/***********************************************/
+
+class DIALOG_COLOR_CONFIG : public DIALOG_COLOR_CONFIG_BASE
+{
+private:
+ EDA_DRAW_FRAME* m_parent;
+ wxRadioBox* m_SelBgColor;
+
+ // Creates the controls and sizers
+ void CreateControls();
+
+ void SetColor( wxCommandEvent& aEvent );
+
+public:
+ // Constructors and destructor
+ DIALOG_COLOR_CONFIG( EDA_DRAW_FRAME* aParent );
+
+ bool TransferDataFromWindow();
+};
+
+#endif // DIALOG_COLOR_CONFIG_H_
diff --git a/eeschema/dialogs/dialog_color_config_base.cpp b/eeschema/dialogs/dialog_color_config_base.cpp
new file mode 100644
index 0000000..8991523
--- /dev/null
+++ b/eeschema/dialogs/dialog_color_config_base.cpp
@@ -0,0 +1,48 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_color_config_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_COLOR_CONFIG_BASE::DIALOG_COLOR_CONFIG_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bmainSizer;
+ bmainSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_mainBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+
+
+ bmainSizer->Add( m_mainBoxSizer, 1, wxEXPAND, 5 );
+
+ m_staticline = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bmainSizer->Add( m_staticline, 0, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerApply = new wxButton( this, wxID_APPLY );
+ m_sdbSizer->AddButton( m_sdbSizerApply );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bmainSizer->Add( m_sdbSizer, 0, wxALIGN_RIGHT|wxALL, 5 );
+
+
+ this->SetSizer( bmainSizer );
+ this->Layout();
+ bmainSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_COLOR_CONFIG_BASE::~DIALOG_COLOR_CONFIG_BASE()
+{
+}
diff --git a/eeschema/dialogs/dialog_color_config_base.fbp b/eeschema/dialogs/dialog_color_config_base.fbp
new file mode 100644
index 0000000..d739b57
--- /dev/null
+++ b/eeschema/dialogs/dialog_color_config_base.fbp
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_color_config_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_color_config_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_COLOR_CONFIG_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">EESchema Colors</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_mainBoxSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">protected</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">1</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_color_config_base.h b/eeschema/dialogs/dialog_color_config_base.h
new file mode 100644
index 0000000..83697b1
--- /dev/null
+++ b/eeschema/dialogs/dialog_color_config_base.h
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_COLOR_CONFIG_BASE_H__
+#define __DIALOG_COLOR_CONFIG_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/sizer.h>
+#include <wx/gdicmn.h>
+#include <wx/statline.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/string.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_COLOR_CONFIG_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_COLOR_CONFIG_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxBoxSizer* m_mainBoxSizer;
+ wxStaticLine* m_staticline;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerApply;
+ wxButton* m_sdbSizerCancel;
+
+ public:
+
+ DIALOG_COLOR_CONFIG_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("EESchema Colors"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_COLOR_CONFIG_BASE();
+
+};
+
+#endif //__DIALOG_COLOR_CONFIG_BASE_H__
diff --git a/eeschema/dialogs/dialog_edit_component_in_lib.cpp b/eeschema/dialogs/dialog_edit_component_in_lib.cpp
new file mode 100644
index 0000000..d7c58a2
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_component_in_lib.cpp
@@ -0,0 +1,579 @@
+/**
+ * @file dialog_edit_component_in_lib.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <kiway.h>
+#include <common.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <pgm_base.h>
+
+#include <general.h>
+#include <libeditframe.h>
+#include <class_library.h>
+#include <eeschema_id.h> // for ID_POPUP_SCH_SELECT_UNIT_CMP_MAX and ID_POPUP_SCH_SELECT_UNIT1
+
+#include <dialog_edit_component_in_lib.h>
+
+int DIALOG_EDIT_COMPONENT_IN_LIBRARY::m_lastOpenedPage = 0;
+
+DIALOG_EDIT_COMPONENT_IN_LIBRARY::DIALOG_EDIT_COMPONENT_IN_LIBRARY( LIB_EDIT_FRAME* aParent ):
+ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( aParent )
+{
+ m_Parent = aParent;
+ m_RecreateToolbar = false;
+
+ initDlg();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+DIALOG_EDIT_COMPONENT_IN_LIBRARY::~DIALOG_EDIT_COMPONENT_IN_LIBRARY()
+{
+ m_lastOpenedPage = m_NoteBook->GetSelection( );
+}
+
+/* Initialize state of check boxes and texts
+*/
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::initDlg()
+{
+ m_AliasLocation = -1;
+
+ LIB_PART* component = m_Parent->GetCurPart();
+
+ if( component == NULL )
+ {
+ SetTitle( _( "Library Component Properties" ) );
+ return;
+ }
+
+ wxString title;
+ bool isRoot = m_Parent->GetAliasName().CmpNoCase( component->GetName() ) == 0;
+
+ if( !isRoot )
+ {
+ title.Printf( _( "Properties for %s (alias of %s)" ),
+ GetChars( m_Parent->GetAliasName() ),
+ GetChars( component->GetName() ) );
+ }
+ else
+ title.Printf( _( "Properties for %s" ), GetChars( component->GetName() ) );
+
+ SetTitle( title );
+ InitPanelDoc();
+ InitBasicPanel();
+
+ if( isRoot && component->GetAliasCount() == 1 )
+ m_ButtonDeleteAllAlias->Enable( false );
+
+ /* Place list of alias names in listbox */
+ m_PartAliasListCtrl->Append( component->GetAliasNames( false ) );
+
+ if( component->GetAliasCount() <= 1 )
+ {
+ m_ButtonDeleteAllAlias->Enable( false );
+ m_ButtonDeleteOneAlias->Enable( false );
+ }
+
+ /* Read the Footprint Filter list */
+ m_FootprintFilterListBox->Append( component->GetFootPrints() );
+
+ if( component->GetFootPrints().GetCount() == 0 )
+ {
+ m_ButtonDeleteAllFootprintFilter->Enable( false );
+ m_ButtonDeleteOneFootprintFilter->Enable( false );
+ m_buttonEditOneFootprintFilter->Enable( false );
+ }
+
+ m_NoteBook->SetSelection( m_lastOpenedPage );
+
+ m_stdSizerButtonOK->SetDefault();
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::InitPanelDoc()
+{
+ LIB_ALIAS* alias;
+ LIB_PART* component = m_Parent->GetCurPart();
+
+ if( component == NULL )
+ return;
+
+ wxString aliasname = m_Parent->GetAliasName();
+
+ if( aliasname.IsEmpty() )
+ return;
+
+ alias = component->GetAlias( aliasname );
+
+ if( alias != NULL )
+ {
+ m_DocCtrl->SetValue( alias->GetDescription() );
+ m_KeywordsCtrl->SetValue( alias->GetKeyWords() );
+ m_DocfileCtrl->SetValue( alias->GetDocFileName() );
+ }
+}
+
+
+/*
+ * create the basic panel for component properties editing
+ */
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::InitBasicPanel()
+{
+ LIB_PART* component = m_Parent->GetCurPart();
+
+ if( m_Parent->GetShowDeMorgan() )
+ m_AsConvertButt->SetValue( true );
+
+ int maxUnits = ID_POPUP_SCH_SELECT_UNIT_CMP_MAX - ID_POPUP_SCH_SELECT_UNIT1;
+ m_SelNumberOfUnits->SetRange (1, maxUnits );
+
+ m_staticTextNbUnits->SetLabel( wxString::Format(
+ _( "Number of Units (max allowed %d)" ), maxUnits ) );
+
+
+ /* Default values for a new component. */
+ if( component == NULL )
+ {
+ m_ShowPinNumButt->SetValue( true );
+ m_ShowPinNameButt->SetValue( true );
+ m_PinsNameInsideButt->SetValue( true );
+ m_SelNumberOfUnits->SetValue( 1 );
+ m_SetSkew->SetValue( 40 );
+ m_OptionPower->SetValue( false );
+ m_OptionPartsLocked->SetValue( false );
+ return;
+ }
+
+ m_ShowPinNumButt->SetValue( component->ShowPinNumbers() );
+ m_ShowPinNameButt->SetValue( component->ShowPinNames() );
+ m_PinsNameInsideButt->SetValue( component->GetPinNameOffset() != 0 );
+ m_SelNumberOfUnits->SetValue( component->GetUnitCount() );
+ m_SetSkew->SetValue( component->GetPinNameOffset() );
+ m_OptionPower->SetValue( component->IsPower() );
+ m_OptionPartsLocked->SetValue( component->UnitsLocked() && component->GetUnitCount() > 1 );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnOkClick( wxCommandEvent& event )
+{
+ /* Update the doc, keyword and doc filename strings */
+ LIB_ALIAS* alias;
+ LIB_PART* component = m_Parent->GetCurPart();
+
+ if( component == NULL )
+ {
+ EndModal( wxID_CANCEL );
+ return;
+ }
+
+ m_Parent->SaveCopyInUndoList( component );
+
+ alias = component->GetAlias( m_Parent->GetAliasName() );
+
+ wxCHECK_RET( alias != NULL,
+ wxT( "Alias \"" ) + m_Parent->GetAliasName() + wxT( "\" of component \"" ) +
+ component->GetName() + wxT( "\" does not exist." ) );
+
+ alias->SetDescription( m_DocCtrl->GetValue() );
+ alias->SetKeyWords( m_KeywordsCtrl->GetValue() );
+ alias->SetDocFileName( m_DocfileCtrl->GetValue() );
+
+ component->SetAliases( m_PartAliasListCtrl->GetStrings() );
+
+ int unitCount = m_SelNumberOfUnits->GetValue();
+ ChangeNbUnitsPerPackage( unitCount );
+
+ if( m_AsConvertButt->GetValue() )
+ {
+ if( !m_Parent->GetShowDeMorgan() )
+ {
+ m_Parent->SetShowDeMorgan( true );
+ SetUnsetConvert();
+ }
+ }
+ else
+ {
+ if( m_Parent->GetShowDeMorgan() )
+ {
+ m_Parent->SetShowDeMorgan( false );
+ SetUnsetConvert();
+ }
+ }
+
+ component->SetShowPinNumbers( m_ShowPinNumButt->GetValue() );
+ component->SetShowPinNames( m_ShowPinNameButt->GetValue() );
+
+ if( m_PinsNameInsideButt->GetValue() == false )
+ component->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
+ else
+ {
+ component->SetPinNameOffset( m_SetSkew->GetValue() );
+ // Ensure component->m_TextInside != 0, because the meaning is "text outside".
+ if( component->GetPinNameOffset() == 0 )
+ component->SetPinNameOffset( 20 ); // give a reasonnable value
+ }
+
+ if( m_OptionPower->GetValue() == true )
+ component->SetPower();
+ else
+ component->SetNormal();
+
+ /* Set the option "Units locked".
+ * Obviously, cannot be true if there is only one part */
+ component->LockUnits( m_OptionPartsLocked->GetValue() );
+
+ if( component->GetUnitCount() <= 1 )
+ component->LockUnits( false );
+
+ /* Update the footprint filter list */
+ component->GetFootPrints().Clear();
+ component->GetFootPrints() = m_FootprintFilterListBox->GetStrings();
+
+ EndModal( wxID_OK );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::CopyDocFromRootToAlias( wxCommandEvent& event )
+{
+ if( m_Parent == NULL )
+ return;
+
+ LIB_ALIAS* parent_alias;
+ LIB_PART* component = m_Parent->GetCurPart();
+
+ if( component == NULL )
+ return;
+
+ // search for the main alias: this is the first alias in alias list
+ // something like the main component
+ parent_alias = component->GetAlias( 0 );
+
+ if( parent_alias == NULL ) // Should never occur (bug)
+ return;
+
+ m_DocCtrl->SetValue( parent_alias->GetDescription() );
+ m_DocfileCtrl->SetValue( parent_alias->GetDocFileName() );
+ m_KeywordsCtrl->SetValue( parent_alias->GetKeyWords() );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::DeleteAllAliasOfPart( wxCommandEvent& event )
+{
+ if( m_PartAliasListCtrl->FindString( m_Parent->GetAliasName() ) != wxNOT_FOUND )
+ {
+ wxString msg;
+ msg.Printf( _( "Alias <%s> cannot be removed while it is being edited!" ),
+ GetChars( m_Parent->GetAliasName() ) );
+ DisplayError( this, msg );
+ return;
+ }
+
+ if( IsOK( this, _( "Remove all aliases from list?" ) ) )
+ {
+ m_PartAliasListCtrl->Clear();
+ m_ButtonDeleteAllAlias->Enable( false );
+ m_ButtonDeleteOneAlias->Enable( false );
+ }
+}
+
+
+/* Add a new name to the alias list box
+ * New name cannot be the root name, and must not exists
+ */
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::AddAliasOfPart( wxCommandEvent& event )
+{
+ wxString aliasname;
+ LIB_PART* component = m_Parent->GetCurPart();
+ PART_LIB* library = m_Parent->GetCurLib();
+
+ if( component == NULL )
+ return;
+
+ wxTextEntryDialog dlg( this, _( "New alias:" ), _( "Component Alias" ), aliasname );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return; // cancelled by user
+
+ aliasname = dlg.GetValue( );
+
+ aliasname.Replace( wxT( " " ), wxT( "_" ) );
+ if( aliasname.IsEmpty() )
+ return;
+
+ if( m_PartAliasListCtrl->FindString( aliasname ) != wxNOT_FOUND )
+ {
+ wxString msg;
+ msg.Printf( _( "Alias or component name <%s> already in use." ),
+ GetChars( aliasname ) );
+ DisplayError( this, msg );
+ return;
+ }
+
+ if( library && library->FindEntry( aliasname ) != NULL )
+ {
+ wxString msg;
+ msg.Printf( _( "Alias or component name <%s> already exists in library <%s>." ),
+ GetChars( aliasname ),
+ GetChars( library->GetName() ) );
+ DisplayError( this, msg );
+ return;
+ }
+
+ m_PartAliasListCtrl->Append( aliasname );
+
+ if( m_Parent->GetAliasName().CmpNoCase( component->GetName() ) == 0 )
+ m_ButtonDeleteAllAlias->Enable( true );
+
+ m_ButtonDeleteOneAlias->Enable( true );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::DeleteAliasOfPart( wxCommandEvent& event )
+{
+ wxString aliasname = m_PartAliasListCtrl->GetStringSelection();
+
+ if( aliasname.IsEmpty() )
+ return;
+
+ if( aliasname.CmpNoCase( m_Parent->GetAliasName() ) == 0 )
+ {
+ wxString msg;
+ msg.Printf( _( "Alias <%s> cannot be removed while it is being edited!" ),
+ GetChars( aliasname ) );
+ DisplayError( this, msg );
+ return;
+ }
+
+ m_PartAliasListCtrl->Delete( m_PartAliasListCtrl->GetSelection() );
+ LIB_PART* component = m_Parent->GetCurPart();
+
+ if( component )
+ component->RemoveAlias( aliasname );
+
+ if( m_PartAliasListCtrl->IsEmpty() )
+ {
+ m_ButtonDeleteAllAlias->Enable( false );
+ m_ButtonDeleteOneAlias->Enable( false );
+ }
+}
+
+
+/*
+ * Change the number of parts per package.
+ */
+bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::ChangeNbUnitsPerPackage( int MaxUnit )
+{
+ LIB_PART* part = m_Parent->GetCurPart();
+
+ if( !part || part->GetUnitCount() == MaxUnit || MaxUnit < 1 )
+ return false;
+
+ if( MaxUnit < part->GetUnitCount()
+ && !IsOK( this, _( "Delete extra parts from component?" ) ) )
+ return false;
+
+ part->SetUnitCount( MaxUnit );
+ return true;
+}
+
+
+/*
+ * Set or clear the component alternate body style ( DeMorgan ).
+ */
+bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::SetUnsetConvert()
+{
+ LIB_PART* component = m_Parent->GetCurPart();
+
+ if( component == NULL || ( m_Parent->GetShowDeMorgan() == component->HasConversion() ) )
+ return false;
+
+ if( m_Parent->GetShowDeMorgan() )
+ {
+ if( !IsOK( this, _( "Add new pins for alternate body style ( DeMorgan ) to component?" ) ) )
+ return false;
+ }
+ else if( component->HasConversion() )
+ {
+ if( !IsOK( this, _( "Delete alternate body style (DeMorgan) draw items from component?" ) ) )
+ {
+ m_Parent->SetShowDeMorgan( true );
+ return false;
+ }
+ }
+
+ component->SetConversion( m_Parent->GetShowDeMorgan() );
+ m_Parent->OnModify();
+
+ return true;
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::BrowseAndSelectDocFile( wxCommandEvent& event )
+{
+ PROJECT& prj = Prj();
+ SEARCH_STACK* search = prj.SchSearchS();
+
+ wxString mask = wxT( "*" );
+ wxString docpath = prj.GetRString( PROJECT::DOC_PATH );
+
+ if( !docpath )
+ docpath = search->LastVisitedPath( wxT( "doc" ) );
+
+ wxString fullFileName = EDA_FILE_SELECTOR( _( "Doc Files" ),
+ docpath,
+ wxEmptyString,
+ wxEmptyString,
+ mask,
+ this,
+ wxFD_OPEN,
+ true );
+ if( fullFileName.IsEmpty() )
+ return;
+
+ /* If the path is already in the library search paths
+ * list, just add the library name to the list. Otherwise, add
+ * the library name with the full or relative path.
+ * the relative path, when possible is preferable,
+ * because it preserve use of default libraries paths, when the path is a sub path of
+ * these default paths
+ */
+ wxFileName fn = fullFileName;
+
+ prj.SetRString( PROJECT::DOC_PATH, fn.GetPath() );
+
+ wxString filename = search->FilenameWithRelativePathInSearchList(
+ fullFileName, wxPathOnly( Prj().GetProjectFullName() ) );
+
+ // Filenames are always stored in unix like mode, ie separator "\" is stored as "/"
+ // to ensure files are identical under unices and windows
+#ifdef __WINDOWS__
+ filename.Replace( wxT( "\\" ), wxT( "/" ) );
+#endif
+ m_DocfileCtrl->SetValue( filename );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::DeleteAllFootprintFilter( wxCommandEvent& event )
+{
+ if( IsOK( this, _( "OK to delete the footprint filter list ?" ) ) )
+ {
+ m_FootprintFilterListBox->Clear();
+ m_ButtonDeleteAllFootprintFilter->Enable( false );
+ m_ButtonDeleteOneFootprintFilter->Enable( false );
+ m_buttonEditOneFootprintFilter->Enable( false );
+ }
+}
+
+
+/* Add a new name to the footprint filter list box
+ * Obvioulsy, cannot be void
+ */
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::AddFootprintFilter( wxCommandEvent& event )
+{
+ wxString Line;
+ LIB_PART* component = m_Parent->GetCurPart();
+
+ if( component == NULL )
+ return;
+
+ wxTextEntryDialog dlg( this, _( "Add Footprint Filter" ), _( "Footprint Filter" ), Line );
+ if( dlg.ShowModal() != wxID_OK )
+ return; // cancelled by user
+
+ Line = dlg.GetValue();
+ Line.Replace( wxT( " " ), wxT( "_" ) );
+
+ if( Line.IsEmpty() )
+ return;
+
+ /* test for an existing name: */
+ int index = m_FootprintFilterListBox->FindString( Line );
+
+ if( index != wxNOT_FOUND )
+ {
+ wxString msg;
+
+ msg.Printf( _( "Foot print filter <%s> is already defined." ), GetChars( Line ) );
+ DisplayError( this, msg );
+ return;
+ }
+
+ m_FootprintFilterListBox->Append( Line );
+ m_ButtonDeleteAllFootprintFilter->Enable( true );
+ m_ButtonDeleteOneFootprintFilter->Enable( true );
+ m_buttonEditOneFootprintFilter->Enable( true );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::DeleteOneFootprintFilter( wxCommandEvent& event )
+{
+ LIB_PART* component = m_Parent->GetCurPart();
+ int ii = m_FootprintFilterListBox->GetSelection();
+
+ m_FootprintFilterListBox->Delete( ii );
+
+ if( !component || ( m_FootprintFilterListBox->GetCount() == 0 ) )
+ {
+ m_ButtonDeleteAllFootprintFilter->Enable( false );
+ m_ButtonDeleteOneFootprintFilter->Enable( false );
+ m_buttonEditOneFootprintFilter->Enable( false );
+ }
+}
+
+void DIALOG_EDIT_COMPONENT_IN_LIBRARY::EditOneFootprintFilter( wxCommandEvent& event )
+{
+ int idx = m_FootprintFilterListBox->GetSelection();
+
+ if( idx < 0 )
+ return;
+
+ wxString filter = m_FootprintFilterListBox->GetStringSelection();
+
+ wxTextEntryDialog dlg( this, wxEmptyString, _( "Edit footprint filter" ), filter );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return; // Aborted by user
+
+ filter = dlg.GetValue();
+
+ if( filter.IsEmpty() )
+ return; // do not accept blank filter.
+
+ m_FootprintFilterListBox->SetString( idx, filter );
+}
diff --git a/eeschema/dialogs/dialog_edit_component_in_lib.h b/eeschema/dialogs/dialog_edit_component_in_lib.h
new file mode 100644
index 0000000..829a8cc
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_component_in_lib.h
@@ -0,0 +1,70 @@
+/**
+ * @file dialog_edit_component_in_lib.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef _DIALOG_EDIT_COMPONENT_IN_LIB_H_
+#define _DIALOG_EDIT_COMPONENT_IN_LIB_H_
+
+#include <dialog_edit_component_in_lib_base.h>
+
+
+class DIALOG_EDIT_COMPONENT_IN_LIBRARY: public DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE
+{
+ static int m_lastOpenedPage; // To remember the last notebook selection
+
+public:
+ LIB_EDIT_FRAME* m_Parent;
+ bool m_RecreateToolbar;
+ int m_AliasLocation;
+
+public:
+ /// Constructors
+ DIALOG_EDIT_COMPONENT_IN_LIBRARY( LIB_EDIT_FRAME* parent);
+ ~DIALOG_EDIT_COMPONENT_IN_LIBRARY();
+
+private:
+ void initDlg();
+ void InitPanelDoc();
+ void InitBasicPanel();
+ void OnCancelClick( wxCommandEvent& event );
+ void OnOkClick(wxCommandEvent& event);
+ void DeleteAllAliasOfPart(wxCommandEvent& event);
+ void DeleteAliasOfPart(wxCommandEvent& event);
+ void AddAliasOfPart(wxCommandEvent& event);
+ bool ChangeNbUnitsPerPackage(int newUnit);
+ bool SetUnsetConvert();
+ void CopyDocFromRootToAlias(wxCommandEvent& event);
+ void BrowseAndSelectDocFile(wxCommandEvent& event);
+
+ void DeleteAllFootprintFilter(wxCommandEvent& event);
+ void DeleteOneFootprintFilter(wxCommandEvent& event);
+ void AddFootprintFilter(wxCommandEvent& event);
+ void EditOneFootprintFilter( wxCommandEvent& event );
+};
+
+#endif
+ // _DIALOG_EDIT_COMPONENT_IN_LIB_H_
diff --git a/eeschema/dialogs/dialog_edit_component_in_lib_base.cpp b/eeschema/dialogs/dialog_edit_component_in_lib_base.cpp
new file mode 100644
index 0000000..57f59d6
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_component_in_lib_base.cpp
@@ -0,0 +1,294 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_edit_component_in_lib_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_NoteBook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0|wxTAB_TRAVERSAL );
+ m_PanelBasic = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* bSizerBasicPanel;
+ bSizerBasicPanel = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* m_OptionsBoxSizer;
+ m_OptionsBoxSizer = new wxStaticBoxSizer( new wxStaticBox( m_PanelBasic, wxID_ANY, _("General") ), wxVERTICAL );
+
+ m_AsConvertButt = new wxCheckBox( m_PanelBasic, wxID_ANY, _("Has alternate symbol (DeMorgan)"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_AsConvertButt->SetToolTip( _("Check this option if the component has an alternate body style (De Morgan)") );
+
+ m_OptionsBoxSizer->Add( m_AsConvertButt, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_ShowPinNumButt = new wxCheckBox( m_PanelBasic, wxID_ANY, _("Show pin number"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ShowPinNumButt->SetValue(true);
+ m_ShowPinNumButt->SetToolTip( _("Show or hide pin numbers") );
+
+ m_OptionsBoxSizer->Add( m_ShowPinNumButt, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_ShowPinNameButt = new wxCheckBox( m_PanelBasic, wxID_ANY, _("Show pin name"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ShowPinNameButt->SetValue(true);
+ m_ShowPinNameButt->SetToolTip( _("Show or hide pin names") );
+
+ m_OptionsBoxSizer->Add( m_ShowPinNameButt, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PinsNameInsideButt = new wxCheckBox( m_PanelBasic, wxID_ANY, _("Place pin names inside"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PinsNameInsideButt->SetValue(true);
+ m_PinsNameInsideButt->SetToolTip( _("Check this option to have pin names inside the body and pin number outside.\nIf not checked pins names and pins numbers are outside.") );
+
+ m_OptionsBoxSizer->Add( m_PinsNameInsideButt, 0, wxALL, 5 );
+
+
+ bSizerBasicPanel->Add( m_OptionsBoxSizer, 0, 0, 5 );
+
+ m_staticline3 = new wxStaticLine( m_PanelBasic, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerBasicPanel->Add( m_staticline3, 0, wxEXPAND | wxALL, 5 );
+
+ wxBoxSizer* bSizerMidBasicPanel;
+ bSizerMidBasicPanel = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizernbunits;
+ bSizernbunits = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextNbUnits = new wxStaticText( m_PanelBasic, wxID_ANY, _("Number of Units"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextNbUnits->Wrap( -1 );
+ m_staticTextNbUnits->SetToolTip( _("Enter the number of units for a component that contains more than one unit") );
+
+ bSizernbunits->Add( m_staticTextNbUnits, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_SelNumberOfUnits = new wxSpinCtrl( m_PanelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 26, 1 );
+ bSizernbunits->Add( m_SelNumberOfUnits, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ bSizerMidBasicPanel->Add( bSizernbunits, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerOffset;
+ bSizerOffset = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextskew = new wxStaticText( m_PanelBasic, wxID_ANY, _("Pin Name Position Offset"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextskew->Wrap( -1 );
+ m_staticTextskew->SetToolTip( _("Margin (in 0.001 inches) between a pin name position and the component body.\nA value from 10 to 40 is usually good.") );
+
+ bSizerOffset->Add( m_staticTextskew, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_SetSkew = new wxSpinCtrl( m_PanelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 100, 0 );
+ bSizerOffset->Add( m_SetSkew, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerMidBasicPanel->Add( bSizerOffset, 1, wxEXPAND, 5 );
+
+
+ bSizerBasicPanel->Add( bSizerMidBasicPanel, 0, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( m_PanelBasic, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerBasicPanel->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_OptionPower = new wxCheckBox( m_PanelBasic, wxID_ANY, _("Define as power symbol"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptionPower->SetToolTip( _("Check this option when the component is a power symbol") );
+
+ bSizerBasicPanel->Add( m_OptionPower, 0, wxALL, 5 );
+
+ m_OptionPartsLocked = new wxCheckBox( m_PanelBasic, wxID_ANY, _("All units are not interchangeable"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptionPartsLocked->SetToolTip( _("Check this option when creating multiple unit components and all units are not interchangeable") );
+
+ bSizerBasicPanel->Add( m_OptionPartsLocked, 0, wxALL, 5 );
+
+
+ m_PanelBasic->SetSizer( bSizerBasicPanel );
+ m_PanelBasic->Layout();
+ bSizerBasicPanel->Fit( m_PanelBasic );
+ m_NoteBook->AddPage( m_PanelBasic, _("Options"), true );
+ m_PanelDoc = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* m_PanelDocBoxSizer;
+ m_PanelDocBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextDescription = new wxStaticText( m_PanelDoc, wxID_ANY, _("Description"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextDescription->Wrap( -1 );
+ m_staticTextDescription->SetToolTip( _("A short description that is displayed in Eeschema.\nCan be a very good help when selecting components in libraries components lists.") );
+
+ m_PanelDocBoxSizer->Add( m_staticTextDescription, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_DocCtrl = new wxTextCtrl( m_PanelDoc, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_DocCtrl->SetMaxLength( 0 );
+ m_PanelDocBoxSizer->Add( m_DocCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticTextKeywords = new wxStaticText( m_PanelDoc, wxID_ANY, _("Keywords"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextKeywords->Wrap( -1 );
+ m_staticTextKeywords->SetToolTip( _("Enter key words that can be used to select this component.\nKey words cannot have spaces and are separated by a space.") );
+
+ m_PanelDocBoxSizer->Add( m_staticTextKeywords, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_KeywordsCtrl = new wxTextCtrl( m_PanelDoc, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_KeywordsCtrl->SetMaxLength( 0 );
+ m_PanelDocBoxSizer->Add( m_KeywordsCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticTextDocFileName = new wxStaticText( m_PanelDoc, wxID_ANY, _("Documentation File Name"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextDocFileName->Wrap( -1 );
+ m_staticTextDocFileName->SetToolTip( _("Enter the documentation file (a .pdf document) associated to the component.") );
+
+ m_PanelDocBoxSizer->Add( m_staticTextDocFileName, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_DocfileCtrl = new wxTextCtrl( m_PanelDoc, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 400,-1 ), 0 );
+ m_DocfileCtrl->SetMaxLength( 0 );
+ m_PanelDocBoxSizer->Add( m_DocfileCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerPaneldocbutts;
+ bSizerPaneldocbutts = new wxBoxSizer( wxHORIZONTAL );
+
+ m_ButtonCopyDoc = new wxButton( m_PanelDoc, ID_COPY_DOC_TO_ALIAS, _("Copy Document from Parent"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerPaneldocbutts->Add( m_ButtonCopyDoc, 0, wxALL, 5 );
+
+ m_buttonBrowseDocFiles = new wxButton( m_PanelDoc, ID_BROWSE_DOC_FILES, _("Browse Files"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerPaneldocbutts->Add( m_buttonBrowseDocFiles, 0, wxALL, 5 );
+
+
+ m_PanelDocBoxSizer->Add( bSizerPaneldocbutts, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
+
+
+ m_PanelDoc->SetSizer( m_PanelDocBoxSizer );
+ m_PanelDoc->Layout();
+ m_PanelDocBoxSizer->Fit( m_PanelDoc );
+ m_NoteBook->AddPage( m_PanelDoc, _("Description"), false );
+ m_PanelAlias = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* bSizerMainPanelAlias;
+ bSizerMainPanelAlias = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bLeftBoxSizerPanelAlias;
+ bLeftBoxSizerPanelAlias = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextAlias = new wxStaticText( m_PanelAlias, wxID_ANY, _("Alias List"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextAlias->Wrap( -1 );
+ m_staticTextAlias->SetToolTip( _("An alias is a component that uses the body of its root component.\nIt has its own documentation and keywords.\nA fast way to extend a library with similar components") );
+
+ bLeftBoxSizerPanelAlias->Add( m_staticTextAlias, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PartAliasListCtrl = new wxListBox( m_PanelAlias, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ bLeftBoxSizerPanelAlias->Add( m_PartAliasListCtrl, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerMainPanelAlias->Add( bLeftBoxSizerPanelAlias, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bRightBoxSizerPanelAlias;
+ bRightBoxSizerPanelAlias = new wxBoxSizer( wxVERTICAL );
+
+ m_ButtonAddeAlias = new wxButton( m_PanelAlias, ID_ADD_ALIAS, _("Add"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightBoxSizerPanelAlias->Add( m_ButtonAddeAlias, 0, wxALL|wxEXPAND, 5 );
+
+ m_ButtonDeleteOneAlias = new wxButton( m_PanelAlias, ID_DELETE_ONE_ALIAS, _("Delete"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightBoxSizerPanelAlias->Add( m_ButtonDeleteOneAlias, 0, wxALL|wxEXPAND, 5 );
+
+ m_ButtonDeleteAllAlias = new wxButton( m_PanelAlias, ID_DELETE_ALL_ALIAS, _("Delete All"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightBoxSizerPanelAlias->Add( m_ButtonDeleteAllAlias, 0, wxALL, 5 );
+
+
+ bSizerMainPanelAlias->Add( bRightBoxSizerPanelAlias, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ m_PanelAlias->SetSizer( bSizerMainPanelAlias );
+ m_PanelAlias->Layout();
+ bSizerMainPanelAlias->Fit( m_PanelAlias );
+ m_NoteBook->AddPage( m_PanelAlias, _("Alias"), false );
+ m_PanelFootprintFilter = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* bPanelFpFilterBoxSizer;
+ bPanelFpFilterBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bFpFilterLeftBoxSizer;
+ bFpFilterLeftBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextFootprints = new wxStaticText( m_PanelFootprintFilter, wxID_ANY, _("Footprints"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextFootprints->Wrap( -1 );
+ m_staticTextFootprints->SetToolTip( _("A list of footprints names that can be used for this component.\nFootprints names can used jockers.\n(like sm* to allow all footprints names starting by sm).") );
+
+ bFpFilterLeftBoxSizer->Add( m_staticTextFootprints, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_FootprintFilterListBox = new wxListBox( m_PanelFootprintFilter, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ bFpFilterLeftBoxSizer->Add( m_FootprintFilterListBox, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bPanelFpFilterBoxSizer->Add( bFpFilterLeftBoxSizer, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bFpFilterRightBoxSizer;
+ bFpFilterRightBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonAddFpF = new wxButton( m_PanelFootprintFilter, ID_ADD_FOOTPRINT_FILTER, _("Add"), wxDefaultPosition, wxDefaultSize, 0 );
+ bFpFilterRightBoxSizer->Add( m_buttonAddFpF, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonEditOneFootprintFilter = new wxButton( m_PanelFootprintFilter, wxID_ANY, _("Edit"), wxDefaultPosition, wxDefaultSize, 0 );
+ bFpFilterRightBoxSizer->Add( m_buttonEditOneFootprintFilter, 0, wxALL|wxEXPAND, 5 );
+
+ m_ButtonDeleteOneFootprintFilter = new wxButton( m_PanelFootprintFilter, ID_DELETE_ONE_FOOTPRINT_FILTER, _("Delete"), wxDefaultPosition, wxDefaultSize, 0 );
+ bFpFilterRightBoxSizer->Add( m_ButtonDeleteOneFootprintFilter, 0, wxALL|wxEXPAND, 5 );
+
+ m_ButtonDeleteAllFootprintFilter = new wxButton( m_PanelFootprintFilter, ID_DELETE_ALL_FOOTPRINT_FILTER, _("Delete All"), wxDefaultPosition, wxDefaultSize, 0 );
+ bFpFilterRightBoxSizer->Add( m_ButtonDeleteAllFootprintFilter, 0, wxALL|wxEXPAND, 5 );
+
+
+ bPanelFpFilterBoxSizer->Add( bFpFilterRightBoxSizer, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ m_PanelFootprintFilter->SetSizer( bPanelFpFilterBoxSizer );
+ m_PanelFootprintFilter->Layout();
+ bPanelFpFilterBoxSizer->Fit( m_PanelFootprintFilter );
+ m_NoteBook->AddPage( m_PanelFootprintFilter, _("Footprint Filter"), false );
+
+ bUpperSizer->Add( m_NoteBook, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bUpperSizer, 1, wxEXPAND, 5 );
+
+ m_stdSizerButton = new wxStdDialogButtonSizer();
+ m_stdSizerButtonOK = new wxButton( this, wxID_OK );
+ m_stdSizerButton->AddButton( m_stdSizerButtonOK );
+ m_stdSizerButtonCancel = new wxButton( this, wxID_CANCEL );
+ m_stdSizerButton->AddButton( m_stdSizerButtonCancel );
+ m_stdSizerButton->Realize();
+
+ bMainSizer->Add( m_stdSizerButton, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ m_ButtonCopyDoc->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::CopyDocFromRootToAlias ), NULL, this );
+ m_buttonBrowseDocFiles->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::BrowseAndSelectDocFile ), NULL, this );
+ m_ButtonAddeAlias->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::AddAliasOfPart ), NULL, this );
+ m_ButtonDeleteOneAlias->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DeleteAliasOfPart ), NULL, this );
+ m_ButtonDeleteAllAlias->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DeleteAllAliasOfPart ), NULL, this );
+ m_buttonAddFpF->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::AddFootprintFilter ), NULL, this );
+ m_buttonEditOneFootprintFilter->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::EditOneFootprintFilter ), NULL, this );
+ m_ButtonDeleteOneFootprintFilter->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DeleteOneFootprintFilter ), NULL, this );
+ m_ButtonDeleteAllFootprintFilter->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DeleteAllFootprintFilter ), NULL, this );
+ m_stdSizerButtonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnCancelClick ), NULL, this );
+ m_stdSizerButtonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::~DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE()
+{
+ // Disconnect Events
+ m_ButtonCopyDoc->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::CopyDocFromRootToAlias ), NULL, this );
+ m_buttonBrowseDocFiles->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::BrowseAndSelectDocFile ), NULL, this );
+ m_ButtonAddeAlias->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::AddAliasOfPart ), NULL, this );
+ m_ButtonDeleteOneAlias->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DeleteAliasOfPart ), NULL, this );
+ m_ButtonDeleteAllAlias->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DeleteAllAliasOfPart ), NULL, this );
+ m_buttonAddFpF->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::AddFootprintFilter ), NULL, this );
+ m_buttonEditOneFootprintFilter->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::EditOneFootprintFilter ), NULL, this );
+ m_ButtonDeleteOneFootprintFilter->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DeleteOneFootprintFilter ), NULL, this );
+ m_ButtonDeleteAllFootprintFilter->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DeleteAllFootprintFilter ), NULL, this );
+ m_stdSizerButtonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnCancelClick ), NULL, this );
+ m_stdSizerButtonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_edit_component_in_lib_base.fbp b/eeschema/dialogs/dialog_edit_component_in_lib_base.fbp
new file mode 100644
index 0000000..9253971
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_component_in_lib_base.fbp
@@ -0,0 +1,3354 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_edit_component_in_lib_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_EDIT_COMPONENT_IN_LIBRARY_FBP</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">ID_LIBEDIT_NOTEBOOK</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Library Component Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxNotebook" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmapsize"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NoteBook</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnNotebookPageChanged"></event>
+ <event name="OnNotebookPageChanging"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Options</property>
+ <property name="select">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PanelBasic</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerBasicPanel</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">General</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_OptionsBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Has alternate symbol (DeMorgan)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AsConvertButt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Check this option if the component has an alternate body style (De Morgan)</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show pin number</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShowPinNumButt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Show or hide pin numbers</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show pin name</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShowPinNameButt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Show or hide pin names</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Place pin names inside</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PinsNameInsideButt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Check this option to have pin names inside the body and pin number outside.&#x0A;If not checked pins names and pins numbers are outside.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMidBasicPanel</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizernbunits</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Number of Units</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextNbUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enter the number of units for a component that contains more than one unit</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">1</property>
+ <property name="max">26</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SelNumberOfUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerOffset</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pin Name Position Offset</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextskew</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Margin (in 0.001 inches) between a pin name position and the component body.&#x0A;A value from 10 to 40 is usually good.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">0</property>
+ <property name="max">100</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SetSkew</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Define as power symbol</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptionPower</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Check this option when the component is a power symbol</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">All units are not interchangeable</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptionPartsLocked</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Check this option when creating multiple unit components and all units are not interchangeable</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Description</property>
+ <property name="select">0</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PanelDoc</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_PanelDocBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Description</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextDescription</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">A short description that is displayed in Eeschema.&#x0A;Can be a very good help when selecting components in libraries components lists.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DocCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Keywords</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextKeywords</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enter key words that can be used to select this component.&#x0A;Key words cannot have spaces and are separated by a space.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_KeywordsCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Documentation File Name</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextDocFileName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enter the documentation file (a .pdf document) associated to the component.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DocfileCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">400,-1</property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerPaneldocbutts</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_COPY_DOC_TO_ALIAS</property>
+ <property name="label">Copy Document from Parent</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ButtonCopyDoc</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">CopyDocFromRootToAlias</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_BROWSE_DOC_FILES</property>
+ <property name="label">Browse Files</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonBrowseDocFiles</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">BrowseAndSelectDocFile</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Alias</property>
+ <property name="select">0</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PanelAlias</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMainPanelAlias</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLeftBoxSizerPanelAlias</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Alias List</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextAlias</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">An alias is a component that uses the body of its root component.&#x0A;It has its own documentation and keywords.&#x0A;A fast way to extend a library with similar components</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxListBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PartAliasListCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox"></event>
+ <event name="OnListBoxDClick"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightBoxSizerPanelAlias</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADD_ALIAS</property>
+ <property name="label">Add</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ButtonAddeAlias</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">AddAliasOfPart</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_DELETE_ONE_ALIAS</property>
+ <property name="label">Delete</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ButtonDeleteOneAlias</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">DeleteAliasOfPart</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_DELETE_ALL_ALIAS</property>
+ <property name="label">Delete All</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ButtonDeleteAllAlias</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">DeleteAllAliasOfPart</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Footprint Filter</property>
+ <property name="select">0</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PanelFootprintFilter</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bPanelFpFilterBoxSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bFpFilterLeftBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprints</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextFootprints</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">A list of footprints names that can be used for this component.&#x0A;Footprints names can used jockers.&#x0A;(like sm* to allow all footprints names starting by sm).</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxListBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FootprintFilterListBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox"></event>
+ <event name="OnListBoxDClick"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bFpFilterRightBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADD_FOOTPRINT_FILTER</property>
+ <property name="label">Add</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonAddFpF</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">AddFootprintFilter</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Edit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonEditOneFootprintFilter</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">EditOneFootprintFilter</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_DELETE_ONE_FOOTPRINT_FILTER</property>
+ <property name="label">Delete</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ButtonDeleteOneFootprintFilter</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">DeleteOneFootprintFilter</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_DELETE_ALL_FOOTPRINT_FILTER</property>
+ <property name="label">Delete All</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ButtonDeleteAllFootprintFilter</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">DeleteAllFootprintFilter</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_stdSizerButton</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_edit_component_in_lib_base.h b/eeschema/dialogs/dialog_edit_component_in_lib_base.h
new file mode 100644
index 0000000..2dc78d7
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_component_in_lib_base.h
@@ -0,0 +1,119 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_EDIT_COMPONENT_IN_LIB_BASE_H__
+#define __DIALOG_EDIT_COMPONENT_IN_LIB_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/checkbox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/statline.h>
+#include <wx/stattext.h>
+#include <wx/spinctrl.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/listbox.h>
+#include <wx/notebook.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_LIBEDIT_NOTEBOOK 1000
+#define ID_COPY_DOC_TO_ALIAS 1001
+#define ID_BROWSE_DOC_FILES 1002
+#define ID_ADD_ALIAS 1003
+#define ID_DELETE_ONE_ALIAS 1004
+#define ID_DELETE_ALL_ALIAS 1005
+#define ID_ADD_FOOTPRINT_FILTER 1006
+#define ID_DELETE_ONE_FOOTPRINT_FILTER 1007
+#define ID_DELETE_ALL_FOOTPRINT_FILTER 1008
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxNotebook* m_NoteBook;
+ wxPanel* m_PanelBasic;
+ wxCheckBox* m_AsConvertButt;
+ wxCheckBox* m_ShowPinNumButt;
+ wxCheckBox* m_ShowPinNameButt;
+ wxCheckBox* m_PinsNameInsideButt;
+ wxStaticLine* m_staticline3;
+ wxStaticText* m_staticTextNbUnits;
+ wxSpinCtrl* m_SelNumberOfUnits;
+ wxStaticText* m_staticTextskew;
+ wxSpinCtrl* m_SetSkew;
+ wxStaticLine* m_staticline1;
+ wxCheckBox* m_OptionPower;
+ wxCheckBox* m_OptionPartsLocked;
+ wxPanel* m_PanelDoc;
+ wxStaticText* m_staticTextDescription;
+ wxTextCtrl* m_DocCtrl;
+ wxStaticText* m_staticTextKeywords;
+ wxTextCtrl* m_KeywordsCtrl;
+ wxStaticText* m_staticTextDocFileName;
+ wxTextCtrl* m_DocfileCtrl;
+ wxButton* m_ButtonCopyDoc;
+ wxButton* m_buttonBrowseDocFiles;
+ wxPanel* m_PanelAlias;
+ wxStaticText* m_staticTextAlias;
+ wxListBox* m_PartAliasListCtrl;
+ wxButton* m_ButtonAddeAlias;
+ wxButton* m_ButtonDeleteOneAlias;
+ wxButton* m_ButtonDeleteAllAlias;
+ wxPanel* m_PanelFootprintFilter;
+ wxStaticText* m_staticTextFootprints;
+ wxListBox* m_FootprintFilterListBox;
+ wxButton* m_buttonAddFpF;
+ wxButton* m_buttonEditOneFootprintFilter;
+ wxButton* m_ButtonDeleteOneFootprintFilter;
+ wxButton* m_ButtonDeleteAllFootprintFilter;
+ wxStdDialogButtonSizer* m_stdSizerButton;
+ wxButton* m_stdSizerButtonOK;
+ wxButton* m_stdSizerButtonCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void CopyDocFromRootToAlias( wxCommandEvent& event ) { event.Skip(); }
+ virtual void BrowseAndSelectDocFile( wxCommandEvent& event ) { event.Skip(); }
+ virtual void AddAliasOfPart( wxCommandEvent& event ) { event.Skip(); }
+ virtual void DeleteAliasOfPart( wxCommandEvent& event ) { event.Skip(); }
+ virtual void DeleteAllAliasOfPart( wxCommandEvent& event ) { event.Skip(); }
+ virtual void AddFootprintFilter( wxCommandEvent& event ) { event.Skip(); }
+ virtual void EditOneFootprintFilter( wxCommandEvent& event ) { event.Skip(); }
+ virtual void DeleteOneFootprintFilter( wxCommandEvent& event ) { event.Skip(); }
+ virtual void DeleteAllFootprintFilter( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wxWindow* parent, wxWindowID id = ID_LIBEDIT_NOTEBOOK, const wxString& title = _("Library Component Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE();
+
+};
+
+#endif //__DIALOG_EDIT_COMPONENT_IN_LIB_BASE_H__
diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp
new file mode 100644
index 0000000..105d6a5
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp
@@ -0,0 +1,1107 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_edit_component_in_schematic.cpp
+ */
+
+#include <wx/tooltip.h>
+#include <wx/hyperlink.h>
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiway.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <class_sch_screen.h>
+#include <schframe.h>
+#include <base_units.h>
+
+#include <general.h>
+#include <sch_base_frame.h>
+#include <class_library.h>
+#include <sch_component.h>
+#include <dialog_helpers.h>
+#include <sch_validators.h>
+
+#include <dialog_edit_component_in_schematic_fbp.h>
+
+
+/**
+ * class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC
+ * is hand coded and implements DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP which
+ * is maintained by wxFormBuilder. Do not auto-generate this class or file,
+ * it is hand coded.
+ */
+class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC : public DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP
+{
+public:
+ /** Constructor */
+ DIALOG_EDIT_COMPONENT_IN_SCHEMATIC( wxWindow* aParent );
+
+ /**
+ * Function InitBuffers
+ * sets up to edit the given component.
+ * @param aComponent The component to edit.
+ */
+ void InitBuffers( SCH_COMPONENT* aComponent );
+
+private:
+
+ friend class SCH_EDIT_FRAME;
+
+ SCH_EDIT_FRAME* m_parent;
+ SCH_COMPONENT* m_cmp;
+ LIB_PART* m_part;
+ bool m_skipCopyFromPanel;
+
+ static int s_SelectedRow;
+
+ /// a copy of the edited component's SCH_FIELDs
+ SCH_FIELDS m_FieldsBuf;
+
+ void setSelectedFieldNdx( int aFieldNdx );
+
+ int getSelectedFieldNdx();
+
+ /**
+ * Function copySelectedFieldToPanel
+ * sets the values displayed on the panel according to
+ * the currently selected field row
+ */
+ void copySelectedFieldToPanel();
+
+
+ /**
+ * Function copyPanelToSelectedField
+ * copies the values displayed on the panel fields to the currently
+ * selected field
+ * @return bool - true if all fields are OK, else false if the user has put
+ * bad data into a field, and this value can be used to deny a row change.
+ */
+ bool copyPanelToSelectedField();
+
+ void copyOptionsToPanel();
+
+ void copyPanelToOptions();
+
+ void setRowItem( int aFieldNdx, const wxString& aName, const wxString& aValue );
+
+ void setRowItem( int aFieldNdx, const SCH_FIELD& aField )
+ {
+ setRowItem( aFieldNdx, aField.GetName( false ), aField.GetText() );
+ }
+
+ // event handlers
+ void OnCloseDialog( wxCloseEvent& event );
+ void OnListItemDeselected( wxListEvent& event );
+ void OnListItemSelected( wxListEvent& event );
+ void OnCancelButtonClick( wxCommandEvent& event );
+ void OnOKButtonClick( wxCommandEvent& event );
+ void SetInitCmp( wxCommandEvent& event );
+ void addFieldButtonHandler( wxCommandEvent& event );
+ void deleteFieldButtonHandler( wxCommandEvent& event );
+ void moveUpButtonHandler( wxCommandEvent& event );
+ void showButtonHandler( wxCommandEvent& event );
+ void OnTestChipName( wxCommandEvent& event );
+ void OnSelectChipName( wxCommandEvent& event );
+ void OnInitDlg( wxInitDialogEvent& event )
+ {
+ TransferDataToWindow();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+ }
+
+ SCH_FIELD* findField( const wxString& aFieldName );
+
+ /**
+ * Function updateDisplay
+ * update the listbox showing fields, according to the fields texts
+ * must be called after a text change in fields, if this change is not an edition
+ */
+ void updateDisplay( )
+ {
+ for( unsigned ii = FIELD1; ii<m_FieldsBuf.size(); ii++ )
+ setRowItem( ii, m_FieldsBuf[ii] );
+ }
+};
+
+
+int DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::s_SelectedRow;
+
+
+void SCH_EDIT_FRAME::EditComponent( SCH_COMPONENT* aComponent )
+{
+ wxCHECK_RET( aComponent != NULL && aComponent->Type() == SCH_COMPONENT_T,
+ wxT( "Invalid component object pointer. Bad Programmer!" ) );
+
+ m_canvas->SetIgnoreMouseEvents( true );
+
+ DIALOG_EDIT_COMPONENT_IN_SCHEMATIC* dlg = new DIALOG_EDIT_COMPONENT_IN_SCHEMATIC( this );
+
+ dlg->InitBuffers( aComponent );
+
+ // make sure the chipnameTextCtrl is wide enough to hold any unusually long chip names:
+ EnsureTextCtrlWidth( dlg->chipnameTextCtrl );
+
+ // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
+ // frame. Therefore this dialog as a modal frame parent, MUST be run under
+ // quasimodal mode for the quasimodal frame support to work. So don't use
+ // the QUASIMODAL macros here.
+ int ret = dlg->ShowQuasiModal();
+
+ m_canvas->SetIgnoreMouseEvents( false );
+ m_canvas->MoveCursorToCrossHair();
+ dlg->Destroy();
+
+ if( ret == wxID_OK )
+ GetCanvas()->Refresh();
+}
+
+
+DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::DIALOG_EDIT_COMPONENT_IN_SCHEMATIC( wxWindow* aParent ) :
+ DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP( aParent )
+{
+ m_parent = (SCH_EDIT_FRAME*) aParent;
+
+ m_cmp = NULL;
+ m_part = NULL;
+ m_skipCopyFromPanel = false;
+
+ wxListItem columnLabel;
+
+ columnLabel.SetImage( -1 );
+
+ columnLabel.SetText( _( "Name" ) );
+ fieldListCtrl->InsertColumn( 0, columnLabel );
+
+ columnLabel.SetText( _( "Value" ) );
+ fieldListCtrl->InsertColumn( 1, columnLabel );
+
+ m_staticTextUnitSize->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_staticTextUnitPosX->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_staticTextUnitPosY->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+
+ wxToolTip::Enable( true );
+ stdDialogButtonSizerOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ Fit();
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnListItemDeselected( wxListEvent& event )
+{
+ if( !m_skipCopyFromPanel )
+ {
+ if( !copyPanelToSelectedField() )
+ event.Skip(); // do not go to the next row
+ }
+}
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnTestChipName( wxCommandEvent& event )
+{
+ wxString partname = chipnameTextCtrl->GetValue();
+ LIB_PART* entry = Prj().SchLibs()->FindLibPart( partname );
+
+ wxString msg;
+
+ if( entry )
+ {
+ msg.Printf( _( "Component '%s' found in library '%s'" ),
+ GetChars( partname ), GetChars( entry->GetLibraryName() ) );
+ wxMessageBox( msg );
+ return;
+ }
+
+ msg.Printf( _( "Component '%s' not found in any library" ), GetChars( partname ) );
+
+ // Try to find components which have a name "near" the current chip name,
+ // i.e. the same name when the comparison is case insensitive.
+ // Could be helpful for old designs when lower cases and upper case were
+ // equivalent.
+ std::vector<LIB_ALIAS*> candidates;
+ Prj().SchLibs()->FindLibraryNearEntries( candidates, partname );
+
+ if( candidates.size() == 0 )
+ {
+ wxMessageBox( msg );
+ return;
+ }
+
+ // Some candidates are found. Show them:
+ msg << wxT("\n") << _( "However, some candidates are found:" );
+
+ // add candidate names:
+ for( unsigned ii = 0; ii < candidates.size(); ii++ )
+ {
+ msg << wxT("\n") <<
+ wxString::Format( _( "'%s' found in library '%s'" ),
+ GetChars( candidates[ii]->GetName() ),
+ GetChars( candidates[ii]->GetLibraryName() ) );
+ }
+
+ wxMessageBox( msg );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnSelectChipName( wxCommandEvent& event )
+{
+ wxArrayString dummy;
+ int dummyunit = 1;
+ wxString chipname = m_parent->SelectComponentFromLibrary( NULL, dummy, dummyunit,
+ true, NULL, NULL );
+ if( chipname.IsEmpty() )
+ return;
+
+ chipnameTextCtrl->SetValue( chipname );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnListItemSelected( wxListEvent& event )
+{
+ DBG( printf( "OnListItemSelected()\n" ); )
+
+ // remember the selected row, statically
+ s_SelectedRow = event.GetIndex();
+
+ copySelectedFieldToPanel();
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnCloseDialog( wxCloseEvent& event )
+{
+ // On wxWidgets 2.8, and on Linux, calling EndQuasiModal here is mandatory
+ // Otherwise, the main event loop is never restored, and Eeschema does not
+ // respond to any event, because the DIALOG_SHIM destructor is never called.
+ // On wxWidgets 3.0, or on Windows, the DIALOG_SHIM destructor is called,
+ // and calls EndQuasiModal.
+ // therefore calling EndQuasiModal here is not always mandatory but it creates no issues
+ EndQuasiModal( wxID_CANCEL );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnCancelButtonClick( wxCommandEvent& event )
+{
+ EndQuasiModal( wxID_CANCEL );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copyPanelToOptions()
+{
+ wxString newname = chipnameTextCtrl->GetValue();
+
+ // Save current flags which could be modified by next change settings
+ STATUS_FLAGS flags = m_cmp->GetFlags();
+
+ newname.Replace( wxT( " " ), wxT( "_" ) );
+
+ if( newname.IsEmpty() )
+ {
+ DisplayError( NULL, _( "No Component Name!" ) );
+ }
+ else if( Cmp_KEEPCASE( newname, m_cmp->m_part_name ) )
+ {
+ PART_LIBS* libs = Prj().SchLibs();
+
+ if( libs->FindLibraryEntry( newname ) == NULL )
+ {
+ wxString msg = wxString::Format( _(
+ "Component '%s' not found!" ), GetChars( newname ) );
+ DisplayError( this, msg );
+ }
+ else // Change component from lib!
+ {
+ m_cmp->SetPartName( newname, libs );
+ }
+ }
+
+ // For components with multiple shapes (De Morgan representation) Set the selected shape:
+ if( convertCheckBox->IsEnabled() )
+ {
+ m_cmp->SetConvert( convertCheckBox->GetValue() ? 2 : 1 );
+ }
+
+ //Set the part selection in multiple part per package
+ if( m_cmp->GetUnit() )
+ {
+ int unit_selection = unitChoice->GetCurrentSelection() + 1;
+
+ m_cmp->SetUnitSelection( &m_parent->GetCurrentSheet(), unit_selection );
+ m_cmp->SetUnit( unit_selection );
+ }
+
+ switch( orientationRadioBox->GetSelection() )
+ {
+ case 0:
+ m_cmp->SetOrientation( CMP_ORIENT_0 );
+ break;
+
+ case 1:
+ m_cmp->SetOrientation( CMP_ORIENT_90 );
+ break;
+
+ case 2:
+ m_cmp->SetOrientation( CMP_ORIENT_180 );
+ break;
+
+ case 3:
+ m_cmp->SetOrientation( CMP_ORIENT_270 );
+ break;
+ }
+
+ int mirror = mirrorRadioBox->GetSelection();
+
+ switch( mirror )
+ {
+ case 0:
+ break;
+
+ case 1:
+ m_cmp->SetOrientation( CMP_MIRROR_X );
+ break;
+
+ case 2:
+ m_cmp->SetOrientation( CMP_MIRROR_Y );
+ break;
+ }
+
+ // Restore m_Flag modified by SetUnit() and other change settings
+ m_cmp->ClearFlags();
+ m_cmp->SetFlags( flags );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnOKButtonClick( wxCommandEvent& event )
+{
+ bool removeRemainingFields = false;
+
+ if( !copyPanelToSelectedField() )
+ return;
+
+ if( ! SCH_COMPONENT::IsReferenceStringValid( m_FieldsBuf[REFERENCE].GetText() ) )
+ {
+ DisplayError( NULL, _( "Illegal reference. A reference must start with a letter" ) );
+ return;
+ }
+
+ // save old cmp in undo list if not already in edit, or moving ...
+ // or the component to be edited is part of a block
+ if( m_cmp->m_Flags == 0
+ || m_parent->GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
+ m_parent->SaveCopyInUndoList( m_cmp, UR_CHANGED );
+
+ copyPanelToOptions();
+
+ // Delete any fields with no name before we copy all of m_FieldsBuf back into the component.
+ for( unsigned i = MANDATORY_FIELDS; i<m_FieldsBuf.size(); )
+ {
+ if( m_FieldsBuf[i].GetName( false ).IsEmpty() || m_FieldsBuf[i].GetText().IsEmpty() )
+ {
+ // If a field has no value and is not it the field template list, warn the user
+ // that it will be remove from the component. This gives the user a chance to
+ // correct the problem before removing the undefined fields. It should also
+ // resolve most of the bug reports and questions regarding missing fields.
+ if( !m_FieldsBuf[i].GetName( false ).IsEmpty() && m_FieldsBuf[i].GetText().IsEmpty()
+ && !m_parent->GetTemplates().HasFieldName( m_FieldsBuf[i].GetName( false ) )
+ && !removeRemainingFields )
+ {
+ wxString msg = wxString::Format(
+ _( "The field name <%s> does not have a value and is not defined in "
+ "the field template list. Empty field values are invalid an will "
+ "be removed from the component. Do you wish to remove this and "
+ "all remaining undefined fields?" ),
+ GetChars( m_FieldsBuf[i].GetName( false ) )
+ );
+
+ wxMessageDialog dlg( this, msg, _( "Remove Fields" ), wxYES_NO | wxNO_DEFAULT );
+
+ if( dlg.ShowModal() == wxID_NO )
+ return;
+
+ removeRemainingFields = true;
+ }
+
+ m_FieldsBuf.erase( m_FieldsBuf.begin() + i );
+ continue;
+ }
+
+ ++i;
+ }
+
+ // change all field positions from relative to absolute
+ for( unsigned i = 0; i<m_FieldsBuf.size(); ++i )
+ {
+ m_FieldsBuf[i].SetTextPosition( m_FieldsBuf[i].GetTextPosition() + m_cmp->m_Pos );
+ }
+
+ LIB_PART* entry = Prj().SchLibs()->FindLibPart( m_cmp->m_part_name );
+
+ if( entry && entry->IsPower() )
+ m_FieldsBuf[VALUE].SetText( m_cmp->m_part_name );
+
+ // copy all the fields back, and change the length of m_Fields.
+ m_cmp->SetFields( m_FieldsBuf );
+
+ // Reference has a specific initialization, depending on the current active sheet
+ // because for a given component, in a complex hierarchy, there are more than one
+ // reference.
+ m_cmp->SetRef( &m_parent->GetCurrentSheet(), m_FieldsBuf[REFERENCE].GetText() );
+
+ m_parent->OnModify();
+ m_parent->GetScreen()->TestDanglingEnds();
+
+ EndQuasiModal( wxID_OK );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::addFieldButtonHandler( wxCommandEvent& event )
+{
+ // in case m_FieldsBuf[REFERENCE].m_Orient has changed on screen only, grab
+ // screen contents.
+ if( !copyPanelToSelectedField() )
+ return;
+
+ unsigned fieldNdx = m_FieldsBuf.size();
+
+ SCH_FIELD blank( wxPoint(), fieldNdx, m_cmp );
+
+ blank.SetOrientation( m_FieldsBuf[REFERENCE].GetOrientation() );
+
+ m_FieldsBuf.push_back( blank );
+ m_FieldsBuf[fieldNdx].SetName( TEMPLATE_FIELDNAME::GetDefaultFieldName( fieldNdx ) );
+
+ m_skipCopyFromPanel = true;
+ setRowItem( fieldNdx, m_FieldsBuf[fieldNdx] );
+
+ setSelectedFieldNdx( fieldNdx );
+ m_skipCopyFromPanel = false;
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::deleteFieldButtonHandler( wxCommandEvent& event )
+{
+ unsigned fieldNdx = getSelectedFieldNdx();
+
+ if( fieldNdx >= m_FieldsBuf.size() ) // traps the -1 case too
+ return;
+
+ if( fieldNdx < MANDATORY_FIELDS )
+ {
+ wxBell();
+ return;
+ }
+
+ m_skipCopyFromPanel = true;
+ m_FieldsBuf.erase( m_FieldsBuf.begin() + fieldNdx );
+ fieldListCtrl->DeleteItem( fieldNdx );
+
+ if( fieldNdx >= m_FieldsBuf.size() )
+ --fieldNdx;
+
+ updateDisplay();
+
+ setSelectedFieldNdx( fieldNdx );
+ m_skipCopyFromPanel = false;
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::showButtonHandler( wxCommandEvent& event )
+{
+ unsigned fieldNdx = getSelectedFieldNdx();
+
+ if( fieldNdx == DATASHEET )
+ {
+ wxString datasheet_uri = fieldValueTextCtrl->GetValue();
+ ::wxLaunchDefaultBrowser( datasheet_uri );
+ }
+ else if( fieldNdx == FOOTPRINT )
+ {
+ // pick a footprint using the footprint picker.
+ wxString fpid;
+
+ KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true );
+
+ if( frame->ShowModal( &fpid, this ) )
+ {
+ // DBG( printf( "%s: %s\n", __func__, TO_UTF8( fpid ) ); )
+ fieldValueTextCtrl->SetValue( fpid );
+
+ setRowItem( fieldNdx, m_FieldsBuf[fieldNdx].GetName( false ), fpid );
+ }
+
+ frame->Destroy();
+ }
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::moveUpButtonHandler( wxCommandEvent& event )
+{
+ unsigned fieldNdx = getSelectedFieldNdx();
+
+ if( fieldNdx >= m_FieldsBuf.size() ) // traps the -1 case too
+ return;
+
+ if( fieldNdx <= MANDATORY_FIELDS )
+ {
+ wxBell();
+ return;
+ }
+
+ if( !copyPanelToSelectedField() )
+ return;
+
+ // swap the fieldNdx field with the one before it, in both the vector
+ // and in the fieldListCtrl
+ SCH_FIELD tmp = m_FieldsBuf[fieldNdx - 1];
+
+ DBG( printf( "tmp.m_Text=\"%s\" tmp.m_Name=\"%s\"\n",
+ TO_UTF8( tmp.GetText() ), TO_UTF8( tmp.GetName( false ) ) ); )
+
+ m_FieldsBuf[fieldNdx - 1] = m_FieldsBuf[fieldNdx];
+ setRowItem( fieldNdx - 1, m_FieldsBuf[fieldNdx] );
+
+ m_FieldsBuf[fieldNdx] = tmp;
+ setRowItem( fieldNdx, tmp );
+
+ updateDisplay();
+
+ m_skipCopyFromPanel = true;
+ setSelectedFieldNdx( fieldNdx - 1 );
+ m_skipCopyFromPanel = false;
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::setSelectedFieldNdx( int aFieldNdx )
+{
+ /* deselect old selection, but I think this is done by single selection
+ * flag within fieldListCtrl.
+ * fieldListCtrl->SetItemState( s_SelectedRow, 0,
+ * wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);
+ */
+
+ if( aFieldNdx >= (int) m_FieldsBuf.size() )
+ aFieldNdx = m_FieldsBuf.size() - 1;
+
+ if( aFieldNdx < 0 )
+ aFieldNdx = 0;
+
+ fieldListCtrl->SetItemState( aFieldNdx, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
+ fieldListCtrl->EnsureVisible( aFieldNdx );
+
+ s_SelectedRow = aFieldNdx;
+}
+
+
+int DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::getSelectedFieldNdx()
+{
+ return s_SelectedRow;
+}
+
+
+SCH_FIELD* DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::findField( const wxString& aFieldName )
+{
+ for( unsigned i=0; i<m_FieldsBuf.size(); ++i )
+ {
+ if( aFieldName == m_FieldsBuf[i].GetName( false ) )
+ return &m_FieldsBuf[i];
+ }
+
+ return NULL;
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::InitBuffers( SCH_COMPONENT* aComponent )
+{
+ m_cmp = aComponent;
+
+ /* We have 3 component related field lists to be aware of: 1) UI
+ presentation, 2) fields in component ram copy, and 3) fields recorded
+ with component on disk. m_FieldsBuf is the list of UI fields, and this
+ list is not the same as the list which is in the component, which is
+ also not the same as the list on disk. All 3 lists are potentially
+ different. In the UI we choose to preserve the order of the first
+ MANDATORY_FIELDS which are sometimes called fixed fields. Then we append
+ the template fieldnames in the exact same order as the template
+ fieldname editor shows them. Then we append any user defined fieldnames
+ which came from the component.
+ */
+
+ m_part = Prj().SchLibs()->FindLibPart( m_cmp->m_part_name );
+
+#if 0 && defined(DEBUG)
+ for( int i = 0; i<aComponent->GetFieldCount(); ++i )
+ {
+ printf( "Orig[%d] (x=%d, y=%d)\n", i, aComponent->m_Fields[i].GetTextPosition().x,
+ aComponent->m_Fields[i].GetTextPosition().y );
+ }
+
+#endif
+
+ // When this code was written, all field constructors ensure that the fixed fields
+ // are all present within a component. So we can knowingly copy them over
+ // in the normal order. Copy only the fixed fields at first.
+ // Please do not break the field constructors.
+
+ m_FieldsBuf.clear();
+
+ for( int i=0; i<MANDATORY_FIELDS; ++i )
+ {
+ m_FieldsBuf.push_back( aComponent->m_Fields[i] );
+
+ // make the editable field position relative to the component
+ m_FieldsBuf[i].SetTextPosition( m_FieldsBuf[i].GetTextPosition() - m_cmp->m_Pos );
+ }
+
+ // Add template fieldnames:
+ // Now copy in the template fields, in the order that they are present in the
+ // template field editor UI.
+ const TEMPLATE_FIELDNAMES& tfnames = m_parent->GetTemplateFieldNames();
+
+ for( TEMPLATE_FIELDNAMES::const_iterator it = tfnames.begin(); it!=tfnames.end(); ++it )
+ {
+ // add a new field unconditionally to the UI only
+ SCH_FIELD fld( wxPoint(0,0), -1 /* id is a relic */, m_cmp, it->m_Name );
+
+ // See if field by same name already exists in component.
+ SCH_FIELD* schField = aComponent->FindField( it->m_Name );
+
+ // If the field does not already exist in the component, then we
+ // use defaults from the template fieldname, otherwise the original
+ // values from the component will be set.
+ if( !schField )
+ {
+ if( !it->m_Visible )
+ fld.SetVisible( false );
+ else
+ fld.SetVisible( true );
+
+ fld.SetText( it->m_Value ); // empty? ok too.
+ }
+ else
+ {
+ fld = *schField;
+
+ // make the editable field position relative to the component
+ fld.SetTextPosition( fld.GetTextPosition() - m_cmp->m_Pos );
+ }
+
+ m_FieldsBuf.push_back( fld );
+ }
+
+ // Lastly, append any original fields from the component which were not added
+ // from the set of fixed fields nor from the set of template fields.
+ for( unsigned i=MANDATORY_FIELDS; i<aComponent->m_Fields.size(); ++i )
+ {
+ SCH_FIELD* cmp = &aComponent->m_Fields[i];
+ SCH_FIELD* buf = findField( cmp->GetName( false ) );
+
+ if( !buf )
+ {
+ int newNdx = m_FieldsBuf.size();
+ m_FieldsBuf.push_back( *cmp );
+
+ // make the editable field position relative to the component
+ m_FieldsBuf[newNdx].SetTextPosition( m_FieldsBuf[newNdx].GetTextPosition() -
+ m_cmp->m_Pos );
+ }
+ }
+
+
+#if 0 && defined(DEBUG)
+ for( unsigned i = 0; i<m_FieldsBuf.size(); ++i )
+ {
+ printf( "m_FieldsBuf[%d] (x=%-3d, y=%-3d) name:%s\n", i, m_FieldsBuf[i].m_Pos.x,
+ m_FieldsBuf[i].m_Pos.y, TO_UTF8(m_FieldsBuf[i].GetName( false ) ) );
+ }
+#endif
+
+ m_FieldsBuf[REFERENCE].SetText( m_cmp->GetRef( &m_parent->GetCurrentSheet() ) );
+
+ for( unsigned i = 0; i<m_FieldsBuf.size(); ++i )
+ {
+ setRowItem( i, m_FieldsBuf[i] );
+ }
+
+#if 0 && defined(DEBUG)
+ for( unsigned i = 0; i<m_FieldsBuf.size(); ++i )
+ {
+ printf( "after[%d] (x=%d, y=%d)\n", i, m_FieldsBuf[i].m_Pos.x,
+ m_FieldsBuf[i].m_Pos.y );
+ }
+
+#endif
+
+ copyOptionsToPanel();
+
+ // disable some options inside the edit dialog
+ // which can cause problems while dragging
+ if( m_cmp->IsDragging() )
+ {
+ orientationRadioBox->Disable();
+ mirrorRadioBox->Disable();
+ chipnameTextCtrl->Disable();
+ }
+
+ // put focus on the list ctrl
+ fieldListCtrl->SetFocus();
+
+ // resume editing at the last row edited, last time dialog was up.
+ setSelectedFieldNdx( s_SelectedRow );
+
+ copySelectedFieldToPanel();
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::setRowItem( int aFieldNdx, const wxString& aName, const wxString& aValue )
+{
+ wxASSERT( aFieldNdx >= 0 );
+
+ // insert blanks if aFieldNdx is referencing a "yet to be defined" row
+ while( aFieldNdx >= fieldListCtrl->GetItemCount() )
+ {
+ long ndx = fieldListCtrl->InsertItem( fieldListCtrl->GetItemCount(), wxEmptyString );
+
+ wxASSERT( ndx >= 0 );
+
+ fieldListCtrl->SetItem( ndx, 1, wxEmptyString );
+ }
+
+ fieldListCtrl->SetItem( aFieldNdx, 0, aName );
+ fieldListCtrl->SetItem( aFieldNdx, 1, aValue );
+
+ // recompute the column widths here, after setting texts
+ fieldListCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE );
+ fieldListCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE );
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copySelectedFieldToPanel()
+{
+ wxCHECK_RET( m_cmp != NULL, wxT( "Component pointer not initialized." ) );
+
+ unsigned fieldNdx = getSelectedFieldNdx();
+
+ if( fieldNdx >= m_FieldsBuf.size() ) // traps the -1 case too
+ return;
+
+ SCH_FIELD& field = m_FieldsBuf[fieldNdx];
+
+ showCheckBox->SetValue( field.IsVisible() );
+
+ rotateCheckBox->SetValue( field.GetOrientation() == TEXT_ORIENT_VERT );
+
+ int style = 0;
+
+ if( field.IsItalic() )
+ style = 1;
+
+ if( field.IsBold() )
+ style |= 2;
+
+ m_StyleRadioBox->SetSelection( style );
+
+ // Select the right text justification
+ if( field.GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT )
+ m_FieldHJustifyCtrl->SetSelection( 0 );
+ else if( field.GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT )
+ m_FieldHJustifyCtrl->SetSelection( 2 );
+ else
+ m_FieldHJustifyCtrl->SetSelection( 1 );
+
+ if( field.GetVertJustify() == GR_TEXT_VJUSTIFY_BOTTOM )
+ m_FieldVJustifyCtrl->SetSelection( 0 );
+ else if( field.GetVertJustify() == GR_TEXT_VJUSTIFY_TOP )
+ m_FieldVJustifyCtrl->SetSelection( 2 );
+ else
+ m_FieldVJustifyCtrl->SetSelection( 1 );
+
+
+ fieldNameTextCtrl->SetValue( field.GetName( false ) );
+
+ // the names of the fixed fields are not editable, others are.
+ fieldNameTextCtrl->Enable( fieldNdx >= MANDATORY_FIELDS );
+ fieldNameTextCtrl->SetEditable( fieldNdx >= MANDATORY_FIELDS );
+
+ // only user defined fields may be moved, and not the top most user defined
+ // field since it would be moving up into the fixed fields, > not >=
+ moveUpButton->Enable( fieldNdx > MANDATORY_FIELDS );
+
+ // may only delete user defined fields
+ deleteFieldButton->Enable( fieldNdx >= MANDATORY_FIELDS );
+
+ fieldValueTextCtrl->SetValidator( SCH_FIELD_VALIDATOR( false, field.GetId() ) );
+ fieldValueTextCtrl->SetValue( field.GetText() );
+
+ m_show_datasheet_button->Enable( fieldNdx == DATASHEET || fieldNdx == FOOTPRINT );
+
+ if( fieldNdx == DATASHEET )
+ m_show_datasheet_button->SetLabel( _( "Show in Browser" ) );
+ else if( fieldNdx == FOOTPRINT )
+ m_show_datasheet_button->SetLabel( _( "Assign Footprint" ) );
+ else
+ m_show_datasheet_button->SetLabel( wxEmptyString );
+
+ // For power symbols, the value is NOR editable, because value and pin
+ // name must be same and can be edited only in library editor
+ if( fieldNdx == VALUE && m_part && m_part->IsPower() )
+ fieldValueTextCtrl->Enable( false );
+ else
+ fieldValueTextCtrl->Enable( true );
+
+ textSizeTextCtrl->SetValue( EDA_GRAPHIC_TEXT_CTRL::FormatSize( g_UserUnit, field.GetSize().x ) );
+
+ wxPoint coord = field.GetTextPosition();
+ wxPoint zero = -m_cmp->m_Pos; // relative zero
+
+ // If the field value is empty and the position is at relative zero, we
+ // set the initial position as a small offset from the ref field, and
+ // orient it the same as the ref field. That is likely to put it at least
+ // close to the desired position.
+ if( coord == zero && field.GetText().IsEmpty() )
+ {
+ rotateCheckBox->SetValue( m_FieldsBuf[REFERENCE].GetOrientation() == TEXT_ORIENT_VERT );
+
+ coord.x = m_FieldsBuf[REFERENCE].GetTextPosition().x
+ + ( fieldNdx - MANDATORY_FIELDS + 1 ) * 100;
+
+ coord.y = m_FieldsBuf[REFERENCE].GetTextPosition().y
+ + ( fieldNdx - MANDATORY_FIELDS + 1 ) * 100;
+
+ // coord can compute negative if field is < MANDATORY_FIELDS, e.g. FOOTPRINT.
+ // That is ok, we basically don't want all the new empty fields on
+ // top of each other.
+ }
+
+ wxString coordText = StringFromValue( g_UserUnit, coord.x );
+ posXTextCtrl->SetValue( coordText );
+
+ coordText = StringFromValue( g_UserUnit, coord.y );
+ posYTextCtrl->SetValue( coordText );
+}
+
+
+bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copyPanelToSelectedField()
+{
+ unsigned fieldNdx = getSelectedFieldNdx();
+
+ if( fieldNdx >= m_FieldsBuf.size() ) // traps the -1 case too
+ return true;
+
+ // Check for illegal field text.
+ if( fieldValueTextCtrl->GetValidator()
+ && !fieldValueTextCtrl->GetValidator()->Validate( this ) )
+ return false;
+
+ SCH_FIELD& field = m_FieldsBuf[fieldNdx];
+
+ field.SetVisible( showCheckBox->GetValue() );
+
+ if( rotateCheckBox->GetValue() )
+ field.SetOrientation( TEXT_ORIENT_VERT );
+ else
+ field.SetOrientation( TEXT_ORIENT_HORIZ );
+
+ rotateCheckBox->SetValue( field.GetOrientation() == TEXT_ORIENT_VERT );
+
+ // Copy the text justification
+ static const EDA_TEXT_HJUSTIFY_T hjustify[] = {
+ GR_TEXT_HJUSTIFY_LEFT,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_HJUSTIFY_RIGHT
+ };
+
+ static const EDA_TEXT_VJUSTIFY_T vjustify[] = {
+ GR_TEXT_VJUSTIFY_BOTTOM,
+ GR_TEXT_VJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_TOP
+ };
+
+ field.SetHorizJustify( hjustify[m_FieldHJustifyCtrl->GetSelection()] );
+ field.SetVertJustify( vjustify[m_FieldVJustifyCtrl->GetSelection()] );
+
+ field.SetName( fieldNameTextCtrl->GetValue() );
+
+ /* Void fields texts for REFERENCE and VALUE (value is the name of the
+ * component in lib ! ) are not allowed
+ * change them only for a new non void value
+ * When void, usually netlists are broken
+ */
+ if( !fieldValueTextCtrl->GetValue().IsEmpty() || fieldNdx > VALUE )
+ field.SetText( fieldValueTextCtrl->GetValue() );
+
+ setRowItem( fieldNdx, field ); // update fieldListCtrl
+
+ int tmp = EDA_GRAPHIC_TEXT_CTRL::ParseSize( textSizeTextCtrl->GetValue(), g_UserUnit );
+ field.SetSize( wxSize( tmp, tmp ) );
+ int style = m_StyleRadioBox->GetSelection();
+
+ field.SetItalic( (style & 1 ) != 0 );
+ field.SetBold( (style & 2 ) != 0 );
+
+ wxPoint pos;
+ pos.x = ValueFromString( g_UserUnit, posXTextCtrl->GetValue() );
+ pos.y = ValueFromString( g_UserUnit, posYTextCtrl->GetValue() );
+ field.SetTextPosition( pos );
+
+ return true;
+}
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copyOptionsToPanel()
+{
+ // Remove non existing choices (choiceCount must be <= number for parts)
+ int unitcount = m_part ? m_part->GetUnitCount() : 1;
+
+ if( unitcount < 1 )
+ unitcount = 1;
+
+ unitChoice->Clear();
+
+ for( int ii = 1; ii <= unitcount; ii++ )
+ {
+ unitChoice->Append( LIB_PART::SubReference( ii, false ) );
+ }
+
+ // For components with multiple parts per package, set the unit selection
+ if( m_cmp->GetUnit() <= (int)unitChoice->GetCount() )
+ unitChoice->SetSelection( m_cmp->GetUnit() - 1 );
+
+ // Disable unit selection if only one unit exists:
+ if( m_cmp->GetUnitCount() <= 1 )
+ {
+ unitChoice->Enable( false );
+ unitsInterchageableLabel->Show( false );
+ unitsInterchageableText->Show( false );
+ }
+ else
+ {
+ // Show the "Units are not interchangeable" message option?
+ if( !m_part || !m_part->UnitsLocked() )
+ unitsInterchageableLabel->SetLabel( _( "Yes" ) );
+ else
+ unitsInterchageableLabel->SetLabel( _( "No" ) );
+ }
+
+ int orientation = m_cmp->GetOrientation() & ~( CMP_MIRROR_X | CMP_MIRROR_Y );
+
+ if( orientation == CMP_ORIENT_90 )
+ orientationRadioBox->SetSelection( 1 );
+ else if( orientation == CMP_ORIENT_180 )
+ orientationRadioBox->SetSelection( 2 );
+ else if( orientation == CMP_ORIENT_270 )
+ orientationRadioBox->SetSelection( 3 );
+ else
+ orientationRadioBox->SetSelection( 0 );
+
+ int mirror = m_cmp->GetOrientation() & ( CMP_MIRROR_X | CMP_MIRROR_Y );
+
+ if( mirror == CMP_MIRROR_X )
+ {
+ mirrorRadioBox->SetSelection( 1 );
+ DBG( printf( "mirror=X,1\n" ); )
+ }
+ else if( mirror == CMP_MIRROR_Y )
+ {
+ mirrorRadioBox->SetSelection( 2 );
+ DBG( printf( "mirror=Y,2\n" ); )
+ }
+ else
+ mirrorRadioBox->SetSelection( 0 );
+
+ // Activate/Desactivate the normal/convert option ? (activated only if
+ // the component has more than one shape)
+ if( m_cmp->GetConvert() > 1 )
+ convertCheckBox->SetValue( true );
+
+ if( m_part == NULL || !m_part->HasConversion() )
+ convertCheckBox->Enable( false );
+
+ // Set the component's library name.
+ chipnameTextCtrl->SetValue( m_cmp->m_part_name );
+
+ // Set the component's unique ID time stamp.
+ m_textCtrlTimeStamp->SetValue( wxString::Format( wxT( "%8.8lX" ),
+ (unsigned long) m_cmp->GetTimeStamp() ) );
+}
+
+
+#include <kicad_device_context.h>
+
+
+void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::SetInitCmp( wxCommandEvent& event )
+{
+ if( !m_cmp )
+ return;
+
+ if( LIB_PART* part = Prj().SchLibs()->FindLibPart( m_cmp->m_part_name ) )
+ {
+ // save old cmp in undo list if not already in edit, or moving ...
+ if( m_cmp->m_Flags == 0 )
+ m_parent->SaveCopyInUndoList( m_cmp, UR_CHANGED );
+
+ INSTALL_UNBUFFERED_DC( dc, m_parent->GetCanvas() );
+ m_cmp->Draw( m_parent->GetCanvas(), &dc, wxPoint( 0, 0 ), g_XorMode );
+
+ // Initialize fixed field values to default values found in library
+ // Note: the field texts are not modified because they are set in schematic,
+ // the text from libraries is most of time a dummy text
+ // Only VALUE, REFERENCE , FOOTPRINT and DATASHEET are re-initialized
+ LIB_FIELD& refField = part->GetReferenceField();
+
+ m_cmp->GetField( REFERENCE )->SetTextPosition( refField.GetTextPosition() + m_cmp->m_Pos );
+ m_cmp->GetField( REFERENCE )->ImportValues( refField );
+
+ LIB_FIELD& valField = part->GetValueField();
+
+ m_cmp->GetField( VALUE )->SetTextPosition( valField.GetTextPosition() + m_cmp->m_Pos );
+ m_cmp->GetField( VALUE )->ImportValues( valField );
+
+ LIB_FIELD* field = part->GetField(FOOTPRINT);
+
+ if( field && m_cmp->GetField( FOOTPRINT ) )
+ {
+ m_cmp->GetField( FOOTPRINT )->SetTextPosition( field->GetTextPosition() + m_cmp->m_Pos );
+ m_cmp->GetField( FOOTPRINT )->ImportValues( *field );
+ }
+
+ field = part->GetField(DATASHEET);
+
+ if( field && m_cmp->GetField( DATASHEET ) )
+ {
+ m_cmp->GetField( DATASHEET )->SetTextPosition( field->GetTextPosition() + m_cmp->m_Pos );
+ m_cmp->GetField( DATASHEET )->ImportValues( *field );
+ }
+
+ m_cmp->SetOrientation( CMP_NORMAL );
+
+ m_parent->OnModify();
+
+ m_cmp->Draw( m_parent->GetCanvas(), &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+
+ EndQuasiModal( wxID_OK );
+ }
+}
diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic_fbp.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic_fbp.cpp
new file mode 100644
index 0000000..6dddb57
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_component_in_schematic_fbp.cpp
@@ -0,0 +1,324 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 21 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_edit_component_in_schematic_fbp.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* mainSizer;
+ mainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* upperSizer;
+ upperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* optionsSizer;
+ optionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Component") ), wxVERTICAL );
+
+ m_staticTextUnit = new wxStaticText( optionsSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextUnit->Wrap( -1 );
+ optionsSizer->Add( m_staticTextUnit, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxArrayString unitChoiceChoices;
+ unitChoice = new wxChoice( optionsSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, unitChoiceChoices, 0 );
+ unitChoice->SetSelection( 0 );
+ optionsSizer->Add( unitChoice, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerUnitsInterchangeable;
+ bSizerUnitsInterchangeable = new wxBoxSizer( wxHORIZONTAL );
+
+ unitsInterchageableText = new wxStaticText( optionsSizer->GetStaticBox(), wxID_ANY, _("Units are interchangeable:"), wxDefaultPosition, wxDefaultSize, 0 );
+ unitsInterchageableText->Wrap( -1 );
+ bSizerUnitsInterchangeable->Add( unitsInterchageableText, 0, wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ unitsInterchageableLabel = new wxStaticText( optionsSizer->GetStaticBox(), wxID_ANY, _("Yes"), wxDefaultPosition, wxDefaultSize, 0 );
+ unitsInterchageableLabel->Wrap( -1 );
+ bSizerUnitsInterchangeable->Add( unitsInterchageableLabel, 0, wxALL, 5 );
+
+
+ optionsSizer->Add( bSizerUnitsInterchangeable, 0, wxEXPAND, 5 );
+
+ wxString orientationRadioBoxChoices[] = { _("0"), _("+90"), _("180"), _("-90") };
+ int orientationRadioBoxNChoices = sizeof( orientationRadioBoxChoices ) / sizeof( wxString );
+ orientationRadioBox = new wxRadioBox( optionsSizer->GetStaticBox(), wxID_ANY, _("Orientation (Degrees)"), wxDefaultPosition, wxDefaultSize, orientationRadioBoxNChoices, orientationRadioBoxChoices, 1, wxRA_SPECIFY_COLS );
+ orientationRadioBox->SetSelection( 0 );
+ orientationRadioBox->SetToolTip( _("Select if the component is to be rotated when drawn") );
+
+ optionsSizer->Add( orientationRadioBox, 0, wxEXPAND|wxALL, 5 );
+
+ wxString mirrorRadioBoxChoices[] = { _("Normal"), _("Mirror ---"), _("Mirror |") };
+ int mirrorRadioBoxNChoices = sizeof( mirrorRadioBoxChoices ) / sizeof( wxString );
+ mirrorRadioBox = new wxRadioBox( optionsSizer->GetStaticBox(), wxID_ANY, _("Mirror"), wxDefaultPosition, wxDefaultSize, mirrorRadioBoxNChoices, mirrorRadioBoxChoices, 1, wxRA_SPECIFY_COLS );
+ mirrorRadioBox->SetSelection( 0 );
+ mirrorRadioBox->SetToolTip( _("Pick the graphical transformation to be used when displaying the component, if any") );
+
+ optionsSizer->Add( mirrorRadioBox, 0, wxALL|wxEXPAND, 5 );
+
+ convertCheckBox = new wxCheckBox( optionsSizer->GetStaticBox(), wxID_ANY, _("Converted Shape"), wxDefaultPosition, wxDefaultSize, 0 );
+ convertCheckBox->SetToolTip( _("Use the alternate shape of this component.\nFor gates, this is the \"De Morgan\" conversion") );
+
+ optionsSizer->Add( convertCheckBox, 0, wxALL, 5 );
+
+ wxStaticBoxSizer* sbSizerChipName;
+ sbSizerChipName = new wxStaticBoxSizer( new wxStaticBox( optionsSizer->GetStaticBox(), wxID_ANY, _("Chip Name") ), wxVERTICAL );
+
+ chipnameTextCtrl = new wxTextCtrl( sbSizerChipName->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ chipnameTextCtrl->SetToolTip( _("The name of the symbol in the library from which this component came") );
+
+ sbSizerChipName->Add( chipnameTextCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+ wxBoxSizer* bSizerChpinameButt;
+ bSizerChpinameButt = new wxBoxSizer( wxHORIZONTAL );
+
+ m_buttonTestChipName = new wxButton( sbSizerChipName->GetStaticBox(), wxID_ANY, _("Test"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerChpinameButt->Add( m_buttonTestChipName, 0, wxTOP|wxBOTTOM|wxRIGHT, 5 );
+
+ m_buttonSelectChipName = new wxButton( sbSizerChipName->GetStaticBox(), wxID_ANY, _("Select"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerChpinameButt->Add( m_buttonSelectChipName, 0, wxTOP|wxBOTTOM, 5 );
+
+
+ sbSizerChipName->Add( bSizerChpinameButt, 1, wxEXPAND, 5 );
+
+
+ optionsSizer->Add( sbSizerChipName, 0, wxEXPAND|wxALL, 5 );
+
+ m_staticTextTimeStamp = new wxStaticText( optionsSizer->GetStaticBox(), wxID_ANY, _("Timestamp"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextTimeStamp->Wrap( -1 );
+ optionsSizer->Add( m_staticTextTimeStamp, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_textCtrlTimeStamp = new wxTextCtrl( optionsSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ m_textCtrlTimeStamp->SetToolTip( _("An unique ID (a time stamp) to identify the component.\nThis is an alternate identifier to the reference.") );
+
+ optionsSizer->Add( m_textCtrlTimeStamp, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( optionsSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ optionsSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ defaultsButton = new wxButton( optionsSizer->GetStaticBox(), wxID_ANY, _("Reset to Library Defaults"), wxDefaultPosition, wxDefaultSize, 0 );
+ defaultsButton->SetToolTip( _("Set position and style of fields and component orientation to default lib value.\nFields texts are not modified.") );
+
+ optionsSizer->Add( defaultsButton, 0, wxALL|wxEXPAND, 5 );
+
+
+ upperSizer->Add( optionsSizer, 0, wxEXPAND|wxALL, 5 );
+
+ wxStaticBoxSizer* fieldsSizer;
+ fieldsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Fields") ), wxHORIZONTAL );
+
+ wxStaticBoxSizer* gridStaticBoxSizer;
+ gridStaticBoxSizer = new wxStaticBoxSizer( new wxStaticBox( fieldsSizer->GetStaticBox(), wxID_ANY, wxEmptyString ), wxVERTICAL );
+
+ fieldListCtrl = new wxListCtrl( gridStaticBoxSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES );
+ fieldListCtrl->SetMinSize( wxSize( 220,-1 ) );
+
+ gridStaticBoxSizer->Add( fieldListCtrl, 1, wxALL|wxEXPAND, 8 );
+
+ addFieldButton = new wxButton( gridStaticBoxSizer->GetStaticBox(), wxID_ANY, _("Add Field"), wxDefaultPosition, wxDefaultSize, 0 );
+ addFieldButton->SetToolTip( _("Add a new custom field") );
+
+ gridStaticBoxSizer->Add( addFieldButton, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ deleteFieldButton = new wxButton( gridStaticBoxSizer->GetStaticBox(), wxID_ANY, _("Delete Field"), wxDefaultPosition, wxDefaultSize, 0 );
+ deleteFieldButton->SetToolTip( _("Delete one of the optional fields") );
+
+ gridStaticBoxSizer->Add( deleteFieldButton, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ moveUpButton = new wxButton( gridStaticBoxSizer->GetStaticBox(), wxID_ANY, _("Move Up"), wxDefaultPosition, wxDefaultSize, 0 );
+ moveUpButton->SetToolTip( _("Move the selected optional fields up one position") );
+
+ gridStaticBoxSizer->Add( moveUpButton, 0, wxALL|wxEXPAND, 5 );
+
+
+ fieldsSizer->Add( gridStaticBoxSizer, 3, wxEXPAND|wxRIGHT|wxLEFT, 8 );
+
+ wxBoxSizer* fieldEditBoxSizer;
+ fieldEditBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerJustification;
+ bSizerJustification = new wxBoxSizer( wxHORIZONTAL );
+
+ wxString m_FieldHJustifyCtrlChoices[] = { _("Left"), _("Center"), _("Right") };
+ int m_FieldHJustifyCtrlNChoices = sizeof( m_FieldHJustifyCtrlChoices ) / sizeof( wxString );
+ m_FieldHJustifyCtrl = new wxRadioBox( fieldsSizer->GetStaticBox(), wxID_ANY, _("Horiz. Justify"), wxDefaultPosition, wxDefaultSize, m_FieldHJustifyCtrlNChoices, m_FieldHJustifyCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_FieldHJustifyCtrl->SetSelection( 2 );
+ bSizerJustification->Add( m_FieldHJustifyCtrl, 1, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ wxString m_FieldVJustifyCtrlChoices[] = { _("Bottom"), _("Center"), _("Top") };
+ int m_FieldVJustifyCtrlNChoices = sizeof( m_FieldVJustifyCtrlChoices ) / sizeof( wxString );
+ m_FieldVJustifyCtrl = new wxRadioBox( fieldsSizer->GetStaticBox(), wxID_ANY, _("Vert. Justify"), wxDefaultPosition, wxDefaultSize, m_FieldVJustifyCtrlNChoices, m_FieldVJustifyCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_FieldVJustifyCtrl->SetSelection( 2 );
+ bSizerJustification->Add( m_FieldVJustifyCtrl, 1, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ fieldEditBoxSizer->Add( bSizerJustification, 1, wxEXPAND|wxBOTTOM, 5 );
+
+ wxBoxSizer* bSizerStyle;
+ bSizerStyle = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* visibilitySizer;
+ visibilitySizer = new wxStaticBoxSizer( new wxStaticBox( fieldsSizer->GetStaticBox(), wxID_ANY, _("Visibility") ), wxVERTICAL );
+
+ showCheckBox = new wxCheckBox( visibilitySizer->GetStaticBox(), wxID_ANY, _("Show"), wxDefaultPosition, wxDefaultSize, 0 );
+ showCheckBox->SetToolTip( _("Check if you want this field visible") );
+
+ visibilitySizer->Add( showCheckBox, 0, wxALL, 5 );
+
+ rotateCheckBox = new wxCheckBox( visibilitySizer->GetStaticBox(), wxID_ANY, _("Rotate"), wxDefaultPosition, wxDefaultSize, 0 );
+ rotateCheckBox->SetToolTip( _("Check if you want this field's text rotated 90 degrees") );
+
+ visibilitySizer->Add( rotateCheckBox, 0, wxALL, 5 );
+
+
+ bSizerStyle->Add( visibilitySizer, 1, wxEXPAND|wxALL, 5 );
+
+ wxString m_StyleRadioBoxChoices[] = { _("Normal"), _("Italic"), _("Bold"), _("Bold Italic") };
+ int m_StyleRadioBoxNChoices = sizeof( m_StyleRadioBoxChoices ) / sizeof( wxString );
+ m_StyleRadioBox = new wxRadioBox( fieldsSizer->GetStaticBox(), wxID_ANY, _("Style:"), wxDefaultPosition, wxDefaultSize, m_StyleRadioBoxNChoices, m_StyleRadioBoxChoices, 1, wxRA_SPECIFY_COLS );
+ m_StyleRadioBox->SetSelection( 3 );
+ m_StyleRadioBox->SetToolTip( _("The style of the currently selected field's text in the schematic") );
+
+ bSizerStyle->Add( m_StyleRadioBox, 1, wxEXPAND|wxALL, 5 );
+
+
+ fieldEditBoxSizer->Add( bSizerStyle, 1, wxEXPAND|wxBOTTOM, 5 );
+
+ wxBoxSizer* fieldNameBoxSizer;
+ fieldNameBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ fieldNameLabel = new wxStaticText( fieldsSizer->GetStaticBox(), wxID_ANY, _("Field Name"), wxDefaultPosition, wxDefaultSize, 0 );
+ fieldNameLabel->Wrap( -1 );
+ fieldNameBoxSizer->Add( fieldNameLabel, 0, wxTOP, 5 );
+
+ fieldNameTextCtrl = new wxTextCtrl( fieldsSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fieldNameTextCtrl->SetToolTip( _("The name of the currently selected field\nSome fixed fields names are not editable") );
+
+ fieldNameBoxSizer->Add( fieldNameTextCtrl, 0, wxBOTTOM|wxEXPAND, 5 );
+
+ fieldValueLabel = new wxStaticText( fieldsSizer->GetStaticBox(), wxID_ANY, _("Field Value"), wxDefaultPosition, wxDefaultSize, 0 );
+ fieldValueLabel->Wrap( -1 );
+ fieldNameBoxSizer->Add( fieldValueLabel, 0, wxALIGN_TOP|wxTOP, 5 );
+
+ fieldValueTextCtrl = new wxTextCtrl( fieldsSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fieldValueTextCtrl->SetToolTip( _("The name of the currently selected field\nSome fixed fields names are not editable") );
+
+ fieldNameBoxSizer->Add( fieldValueTextCtrl, 0, wxEXPAND|wxBOTTOM, 5 );
+
+ m_show_datasheet_button = new wxButton( fieldsSizer->GetStaticBox(), wxID_ANY, _("Show in Browser"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_show_datasheet_button->SetToolTip( _("If your datasheet is an http:// link or a complete file path, then it may show in your browser by pressing this button.") );
+
+ fieldNameBoxSizer->Add( m_show_datasheet_button, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+
+ fieldEditBoxSizer->Add( fieldNameBoxSizer, 0, wxBOTTOM|wxEXPAND, 5 );
+
+ wxFlexGridSizer* fgSizerPosSize;
+ fgSizerPosSize = new wxFlexGridSizer( 3, 3, 0, 0 );
+ fgSizerPosSize->AddGrowableCol( 1 );
+ fgSizerPosSize->SetFlexibleDirection( wxBOTH );
+ fgSizerPosSize->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ textSizeLabel = new wxStaticText( fieldsSizer->GetStaticBox(), wxID_ANY, _("Size"), wxDefaultPosition, wxDefaultSize, 0 );
+ textSizeLabel->Wrap( -1 );
+ fgSizerPosSize->Add( textSizeLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ textSizeTextCtrl = new wxTextCtrl( fieldsSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ textSizeTextCtrl->SetToolTip( _("The size of the currently selected field's text in the schematic") );
+
+ fgSizerPosSize->Add( textSizeTextCtrl, 0, wxEXPAND|wxBOTTOM, 5 );
+
+ m_staticTextUnitSize = new wxStaticText( fieldsSizer->GetStaticBox(), wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextUnitSize->Wrap( -1 );
+ fgSizerPosSize->Add( m_staticTextUnitSize, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ posXLabel = new wxStaticText( fieldsSizer->GetStaticBox(), wxID_ANY, _("PosX"), wxDefaultPosition, wxDefaultSize, 0 );
+ posXLabel->Wrap( -1 );
+ fgSizerPosSize->Add( posXLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ posXTextCtrl = new wxTextCtrl( fieldsSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ posXTextCtrl->SetToolTip( _("The X coordinate of the text relative to the component") );
+
+ fgSizerPosSize->Add( posXTextCtrl, 0, wxEXPAND|wxTOP, 5 );
+
+ m_staticTextUnitPosX = new wxStaticText( fieldsSizer->GetStaticBox(), wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextUnitPosX->Wrap( -1 );
+ fgSizerPosSize->Add( m_staticTextUnitPosX, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ posYLabel = new wxStaticText( fieldsSizer->GetStaticBox(), wxID_ANY, _("PosY"), wxDefaultPosition, wxDefaultSize, 0 );
+ posYLabel->Wrap( -1 );
+ fgSizerPosSize->Add( posYLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ posYTextCtrl = new wxTextCtrl( fieldsSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ posYTextCtrl->SetToolTip( _("The Y coordinate of the text relative to the component") );
+
+ fgSizerPosSize->Add( posYTextCtrl, 0, wxEXPAND, 5 );
+
+ m_staticTextUnitPosY = new wxStaticText( fieldsSizer->GetStaticBox(), wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextUnitPosY->Wrap( -1 );
+ fgSizerPosSize->Add( m_staticTextUnitPosY, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ fieldEditBoxSizer->Add( fgSizerPosSize, 1, wxEXPAND|wxTOP, 5 );
+
+
+ fieldsSizer->Add( fieldEditBoxSizer, 2, wxEXPAND, 5 );
+
+
+ upperSizer->Add( fieldsSizer, 1, wxALL|wxEXPAND, 5 );
+
+
+ mainSizer->Add( upperSizer, 1, wxEXPAND, 5 );
+
+ stdDialogButtonSizer = new wxStdDialogButtonSizer();
+ stdDialogButtonSizerOK = new wxButton( this, wxID_OK );
+ stdDialogButtonSizer->AddButton( stdDialogButtonSizerOK );
+ stdDialogButtonSizerCancel = new wxButton( this, wxID_CANCEL );
+ stdDialogButtonSizer->AddButton( stdDialogButtonSizerCancel );
+ stdDialogButtonSizer->Realize();
+
+ mainSizer->Add( stdDialogButtonSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( mainSizer );
+ this->Layout();
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnCloseDialog ) );
+ this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnInitDlg ) );
+ m_buttonTestChipName->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnTestChipName ), NULL, this );
+ m_buttonSelectChipName->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnSelectChipName ), NULL, this );
+ defaultsButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::SetInitCmp ), NULL, this );
+ fieldListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnListItemDeselected ), NULL, this );
+ fieldListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnListItemSelected ), NULL, this );
+ addFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::addFieldButtonHandler ), NULL, this );
+ deleteFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::deleteFieldButtonHandler ), NULL, this );
+ moveUpButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::moveUpButtonHandler ), NULL, this );
+ m_show_datasheet_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::showButtonHandler ), NULL, this );
+ stdDialogButtonSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnCancelButtonClick ), NULL, this );
+ stdDialogButtonSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnOKButtonClick ), NULL, this );
+}
+
+DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::~DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnCloseDialog ) );
+ this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnInitDlg ) );
+ m_buttonTestChipName->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnTestChipName ), NULL, this );
+ m_buttonSelectChipName->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnSelectChipName ), NULL, this );
+ defaultsButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::SetInitCmp ), NULL, this );
+ fieldListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnListItemDeselected ), NULL, this );
+ fieldListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnListItemSelected ), NULL, this );
+ addFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::addFieldButtonHandler ), NULL, this );
+ deleteFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::deleteFieldButtonHandler ), NULL, this );
+ moveUpButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::moveUpButtonHandler ), NULL, this );
+ m_show_datasheet_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::showButtonHandler ), NULL, this );
+ stdDialogButtonSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnCancelButtonClick ), NULL, this );
+ stdDialogButtonSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP::OnOKButtonClick ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic_fbp.fbp b/eeschema/dialogs/dialog_edit_component_in_schematic_fbp.fbp
new file mode 100644
index 0000000..d46b0b5
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_component_in_schematic_fbp.fbp
@@ -0,0 +1,3532 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration">; </property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">ANSI</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_edit_component_in_schematic_fbp</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_edit_component_in_schematic_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP</property>
+ <property name="pos"></property>
+ <property name="size">688,586</property>
+ <property name="style">wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Component Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseDialog</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog">OnInitDlg</event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">mainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">upperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Component</property>
+ <property name="minimum_size"></property>
+ <property name="name">optionsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">unitChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUnitsInterchangeable</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Units are interchangeable:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">unitsInterchageableText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Yes</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">unitsInterchageableLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;0&quot; &quot;+90&quot; &quot;180&quot; &quot;-90&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Orientation (Degrees)</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">orientationRadioBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Select if the component is to be rotated when drawn</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Normal&quot; &quot;Mirror ---&quot; &quot;Mirror |&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Mirror</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">mirrorRadioBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Pick the graphical transformation to be used when displaying the component, if any</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Converted Shape</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">convertCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Use the alternate shape of this component.&#x0A;For gates, this is the &quot;De Morgan&quot; conversion</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Chip Name</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerChipName</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">chipnameTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">The name of the symbol in the library from which this component came</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerChpinameButt</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Test</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonTestChipName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnTestChipName</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Select</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonSelectChipName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnSelectChipName</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Timestamp</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextTimeStamp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlTimeStamp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">An unique ID (a time stamp) to identify the component.&#x0A;This is an alternate identifier to the reference.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Reset to Library Defaults</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">defaultsButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Set position and style of fields and component orientation to default lib value.&#x0A;Fields texts are not modified.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">SetInitCmp</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Fields</property>
+ <property name="minimum_size"></property>
+ <property name="name">fieldsSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">8</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">3</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label"></property>
+ <property name="minimum_size"></property>
+ <property name="name">gridStaticBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">8</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxListCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">220,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">fieldListCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBeginDrag"></event>
+ <event name="OnListBeginLabelEdit"></event>
+ <event name="OnListBeginRDrag"></event>
+ <event name="OnListCacheHint"></event>
+ <event name="OnListColBeginDrag"></event>
+ <event name="OnListColClick"></event>
+ <event name="OnListColDragging"></event>
+ <event name="OnListColEndDrag"></event>
+ <event name="OnListColRightClick"></event>
+ <event name="OnListDeleteAllItems"></event>
+ <event name="OnListDeleteItem"></event>
+ <event name="OnListEndLabelEdit"></event>
+ <event name="OnListInsertItem"></event>
+ <event name="OnListItemActivated"></event>
+ <event name="OnListItemDeselected">OnListItemDeselected</event>
+ <event name="OnListItemFocused"></event>
+ <event name="OnListItemMiddleClick"></event>
+ <event name="OnListItemRightClick"></event>
+ <event name="OnListItemSelected">OnListItemSelected</event>
+ <event name="OnListKeyDown"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Add Field</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">addFieldButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Add a new custom field</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">addFieldButtonHandler</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Delete Field</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">deleteFieldButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Delete one of the optional fields</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">deleteFieldButtonHandler</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Move Up</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">moveUpButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Move the selected optional fields up one position</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">moveUpButtonHandler</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">2</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">fieldEditBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerJustification</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Left&quot; &quot;Center&quot; &quot;Right&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Horiz. Justify</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FieldHJustifyCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">2</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Bottom&quot; &quot;Center&quot; &quot;Top&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Vert. Justify</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FieldVJustifyCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">2</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerStyle</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Visibility</property>
+ <property name="minimum_size"></property>
+ <property name="name">visibilitySizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">showCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Check if you want this field visible</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Rotate</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">rotateCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Check if you want this field&apos;s text rotated 90 degrees</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Normal&quot; &quot;Italic&quot; &quot;Bold&quot; &quot;Bold Italic&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Style:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_StyleRadioBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">3</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">The style of the currently selected field&apos;s text in the schematic</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">fieldNameBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Field Name</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldNameLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldNameTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">The name of the currently selected field&#x0A;Some fixed fields names are not editable</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_TOP|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Field Value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldValueLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldValueTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">The name of the currently selected field&#x0A;Some fixed fields names are not editable</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show in Browser</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_show_datasheet_button</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If your datasheet is an http:// link or a complete file path, then it may show in your browser by pressing this button.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">showButtonHandler</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerPosSize</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">3</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">textSizeLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">textSizeTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">The size of the currently selected field&apos;s text in the schematic</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextUnitSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">PosX</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">posXLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">posXTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">The X coordinate of the text relative to the component</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextUnitPosX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">PosY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">posYLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">posYTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">The Y coordinate of the text relative to the component</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextUnitPosY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">stdDialogButtonSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelButtonClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKButtonClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic_fbp.h b/eeschema/dialogs/dialog_edit_component_in_schematic_fbp.h
new file mode 100644
index 0000000..4e50064
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_component_in_schematic_fbp.h
@@ -0,0 +1,109 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 21 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP_H__
+#define __DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/choice.h>
+#include <wx/sizer.h>
+#include <wx/radiobox.h>
+#include <wx/checkbox.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/statbox.h>
+#include <wx/statline.h>
+#include <wx/listctrl.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticTextUnit;
+ wxChoice* unitChoice;
+ wxStaticText* unitsInterchageableText;
+ wxStaticText* unitsInterchageableLabel;
+ wxRadioBox* orientationRadioBox;
+ wxRadioBox* mirrorRadioBox;
+ wxCheckBox* convertCheckBox;
+ wxTextCtrl* chipnameTextCtrl;
+ wxButton* m_buttonTestChipName;
+ wxButton* m_buttonSelectChipName;
+ wxStaticText* m_staticTextTimeStamp;
+ wxTextCtrl* m_textCtrlTimeStamp;
+ wxStaticLine* m_staticline1;
+ wxButton* defaultsButton;
+ wxListCtrl* fieldListCtrl;
+ wxButton* addFieldButton;
+ wxButton* deleteFieldButton;
+ wxButton* moveUpButton;
+ wxRadioBox* m_FieldHJustifyCtrl;
+ wxRadioBox* m_FieldVJustifyCtrl;
+ wxCheckBox* showCheckBox;
+ wxCheckBox* rotateCheckBox;
+ wxRadioBox* m_StyleRadioBox;
+ wxStaticText* fieldNameLabel;
+ wxTextCtrl* fieldNameTextCtrl;
+ wxStaticText* fieldValueLabel;
+ wxTextCtrl* fieldValueTextCtrl;
+ wxButton* m_show_datasheet_button;
+ wxStaticText* textSizeLabel;
+ wxTextCtrl* textSizeTextCtrl;
+ wxStaticText* m_staticTextUnitSize;
+ wxStaticText* posXLabel;
+ wxTextCtrl* posXTextCtrl;
+ wxStaticText* m_staticTextUnitPosX;
+ wxStaticText* posYLabel;
+ wxTextCtrl* posYTextCtrl;
+ wxStaticText* m_staticTextUnitPosY;
+ wxStdDialogButtonSizer* stdDialogButtonSizer;
+ wxButton* stdDialogButtonSizerOK;
+ wxButton* stdDialogButtonSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseDialog( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnInitDlg( wxInitDialogEvent& event ) { event.Skip(); }
+ virtual void OnTestChipName( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnSelectChipName( wxCommandEvent& event ) { event.Skip(); }
+ virtual void SetInitCmp( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnListItemDeselected( wxListEvent& event ) { event.Skip(); }
+ virtual void OnListItemSelected( wxListEvent& event ) { event.Skip(); }
+ virtual void addFieldButtonHandler( wxCommandEvent& event ) { event.Skip(); }
+ virtual void deleteFieldButtonHandler( wxCommandEvent& event ) { event.Skip(); }
+ virtual void moveUpButtonHandler( wxCommandEvent& event ) { event.Skip(); }
+ virtual void showButtonHandler( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Component Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 688,586 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU );
+ ~DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP();
+
+};
+
+#endif //__DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP_H__
diff --git a/eeschema/dialogs/dialog_edit_label.cpp b/eeschema/dialogs/dialog_edit_label.cpp
new file mode 100644
index 0000000..0f70dce
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_label.cpp
@@ -0,0 +1,326 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_text.h
+ * @brief Implementation of the label properties dialog.
+ */
+
+#include <fctsys.h>
+#include <wx/valgen.h>
+#include <schframe.h>
+#include <base_units.h>
+
+#include <class_drawpanel.h>
+#include <general.h>
+#include <drawtxt.h>
+#include <confirm.h>
+#include <sch_text.h>
+#include <typeinfo>
+
+#include <dialog_edit_label_base.h>
+
+class SCH_EDIT_FRAME;
+class SCH_TEXT;
+
+
+class DIALOG_LABEL_EDITOR : public DIALOG_LABEL_EDITOR_BASE
+{
+public:
+ DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* parent, SCH_TEXT* aTextItem );
+
+ void SetTitle( const wxString& aTitle ) // OVERRIDE wxTopLevelWindow::SetTitle
+ {
+ // This class is shared for numerous tasks: a couple of
+ // single line labels and multi-line text fields.
+ // Often the desired size of the multi-line text field editor
+ // is larger than is needed for the single line label.
+ // Therefore the session retained sizes of these dialogs needs
+ // to be class independent, make them title dependent.
+ switch( m_CurrentText->Type() )
+ {
+ case SCH_GLOBAL_LABEL_T:
+ case SCH_HIERARCHICAL_LABEL_T:
+ case SCH_LABEL_T:
+ // labels can share retained settings probably.
+ break;
+
+ default:
+ m_hash_key = TO_UTF8( aTitle );
+ m_hash_key += typeid(*this).name();
+ }
+
+ DIALOG_LABEL_EDITOR_BASE::SetTitle( aTitle );
+ }
+
+private:
+ void InitDialog( );
+ virtual void OnEnterKey( wxCommandEvent& aEvent );
+ virtual void OnOkClick( wxCommandEvent& aEvent );
+ virtual void OnCancelClick( wxCommandEvent& aEvent );
+ void TextPropertiesAccept( wxCommandEvent& aEvent );
+
+ SCH_EDIT_FRAME* m_Parent;
+ SCH_TEXT* m_CurrentText;
+ wxTextCtrl* m_textLabel;
+};
+
+
+
+/* Edit the properties of the text (Label, Global label, graphic text).. )
+ * pointed by "aTextStruct"
+ */
+void SCH_EDIT_FRAME::EditSchematicText( SCH_TEXT* aTextItem )
+{
+ if( aTextItem == NULL )
+ return;
+
+ DIALOG_LABEL_EDITOR dialog( this, aTextItem );
+
+ dialog.ShowModal();
+}
+
+
+DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTextItem ) :
+ DIALOG_LABEL_EDITOR_BASE( aParent )
+{
+ m_Parent = aParent;
+ m_CurrentText = aTextItem;
+ InitDialog();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void DIALOG_LABEL_EDITOR::InitDialog()
+{
+ wxString msg;
+ bool multiLine = false;
+
+ if( m_CurrentText->IsMultilineAllowed() )
+ {
+ m_textLabel = m_textLabelMultiLine;
+ m_textLabelSingleLine->Show( false );
+ multiLine = true;
+ }
+ else
+ {
+ m_textLabel = m_textLabelSingleLine;
+ m_textLabelMultiLine->Show( false );
+ wxTextValidator* validator = (wxTextValidator*) m_textLabel->GetValidator();
+ wxArrayString excludes;
+
+ // Add invalid label characters to this list.
+ excludes.Add( wxT( " " ) );
+ validator->SetExcludes( excludes );
+ }
+
+ m_textLabel->SetValue( m_CurrentText->GetText() );
+ m_textLabel->SetFocus();
+
+ switch( m_CurrentText->Type() )
+ {
+ case SCH_GLOBAL_LABEL_T:
+ SetTitle( _( "Global Label Properties" ) );
+ break;
+
+ case SCH_HIERARCHICAL_LABEL_T:
+ SetTitle( _( "Hierarchical Label Properties" ) );
+ break;
+
+ case SCH_LABEL_T:
+ SetTitle( _( "Label Properties" ) );
+ break;
+
+ case SCH_SHEET_PIN_T:
+ SetTitle( _( "Hierarchical Sheet Pin Properties." ) );
+ break;
+
+ default:
+ SetTitle( _( "Text Properties" ) );
+ break;
+ }
+
+ const int MINTEXTWIDTH = 40; // M's are big characters, a few establish a lot of width
+
+ int max_len = 0;
+
+ if ( !multiLine )
+ {
+ max_len = m_CurrentText->GetText().Length();
+ }
+ else
+ {
+ // calculate the length of the biggest line
+ // we cannot use the length of the entire text that has no meaning
+ int curr_len = MINTEXTWIDTH;
+ int imax = m_CurrentText->GetText().Length();
+
+ for( int count = 0; count < imax; count++ )
+ {
+ if( m_CurrentText->GetText()[count] == '\n' ||
+ m_CurrentText->GetText()[count] == '\r' ) // new line
+ {
+ curr_len = 0;
+ }
+ else
+ {
+ curr_len++;
+
+ if ( max_len < curr_len )
+ max_len = curr_len;
+ }
+ }
+ }
+
+ if( max_len < MINTEXTWIDTH )
+ max_len = MINTEXTWIDTH;
+
+ wxString textWidth;
+ textWidth.Append( 'M', MINTEXTWIDTH );
+ EnsureTextCtrlWidth( m_textLabel, &textWidth );
+
+ // Set validators
+ m_TextOrient->SetSelection( m_CurrentText->GetOrientation() );
+ m_TextShape->SetSelection( m_CurrentText->GetShape() );
+
+ int style = 0;
+
+ if( m_CurrentText->IsItalic() )
+ style = 1;
+
+ if( m_CurrentText->IsBold() )
+ style += 2;
+
+ m_TextStyle->SetSelection( style );
+
+ wxString units = ReturnUnitSymbol( g_UserUnit, wxT( "(%s)" ) );
+ msg.Printf( _( "H%s x W%s" ), GetChars( units ), GetChars( units ) );
+ m_staticSizeUnits->SetLabel( msg );
+
+ msg = StringFromValue( g_UserUnit, m_CurrentText->GetSize().x );
+ m_TextSize->SetValue( msg );
+
+ if( m_CurrentText->Type() != SCH_GLOBAL_LABEL_T
+ && m_CurrentText->Type() != SCH_HIERARCHICAL_LABEL_T )
+ {
+ m_TextShape->Show( false );
+ }
+
+ m_sdbSizer1OK->SetDefault();
+}
+
+
+/*!
+ * wxTE_PROCESS_ENTER event handler for m_textLabel
+ */
+
+void DIALOG_LABEL_EDITOR::OnEnterKey( wxCommandEvent& aEvent )
+{
+ TextPropertiesAccept( aEvent );
+}
+
+
+/*!
+ * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_OK
+ */
+
+void DIALOG_LABEL_EDITOR::OnOkClick( wxCommandEvent& aEvent )
+{
+ TextPropertiesAccept( aEvent );
+}
+
+
+/*!
+ * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL
+ */
+
+void DIALOG_LABEL_EDITOR::OnCancelClick( wxCommandEvent& aEvent )
+{
+ m_Parent->GetCanvas()->MoveCursorToCrossHair();
+ EndModal( wxID_CANCEL );
+}
+
+
+void DIALOG_LABEL_EDITOR::TextPropertiesAccept( wxCommandEvent& aEvent )
+{
+ wxString text;
+ int value;
+
+ /* save old text in undo list if not already in edit */
+ /* or the label to be edited is part of a block */
+ if( m_CurrentText->GetFlags() == 0 ||
+ m_Parent->GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
+ m_Parent->SaveCopyInUndoList( m_CurrentText, UR_CHANGED );
+
+ m_Parent->GetCanvas()->RefreshDrawingRect( m_CurrentText->GetBoundingBox() );
+
+ text = m_textLabel->GetValue();
+
+ if( !text.IsEmpty() )
+ m_CurrentText->SetText( text );
+ else if( !m_CurrentText->IsNew() )
+ {
+ DisplayError( this, _( "Empty Text!" ) );
+ return;
+ }
+
+ m_CurrentText->SetOrientation( m_TextOrient->GetSelection() );
+ text = m_TextSize->GetValue();
+ value = ValueFromString( g_UserUnit, text );
+ m_CurrentText->SetSize( wxSize( value, value ) );
+
+ if( m_TextShape )
+ /// @todo move cast to widget
+ m_CurrentText->SetShape( m_TextShape->GetSelection() );
+
+ int style = m_TextStyle->GetSelection();
+
+ m_CurrentText->SetItalic( ( style & 1 ) );
+
+ if( ( style & 2 ) )
+ {
+ m_CurrentText->SetBold( true );
+ m_CurrentText->SetThickness( GetPenSizeForBold( m_CurrentText->GetSize().x ) );
+ }
+ else
+ {
+ m_CurrentText->SetBold( false );
+ m_CurrentText->SetThickness( 0 );
+ }
+
+ m_Parent->OnModify();
+
+ // Make the text size the new default size ( if it is a new text ):
+ if( m_CurrentText->IsNew() )
+ SetDefaultTextSize( m_CurrentText->GetSize().x );
+
+ m_Parent->GetCanvas()->RefreshDrawingRect( m_CurrentText->GetBoundingBox() );
+ m_Parent->GetCanvas()->MoveCursorToCrossHair();
+ EndModal( wxID_OK );
+}
diff --git a/eeschema/dialogs/dialog_edit_label_base.cpp b/eeschema/dialogs/dialog_edit_label_base.cpp
new file mode 100644
index 0000000..f223491
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_label_base.cpp
@@ -0,0 +1,118 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Feb 26 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_edit_label_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_LABEL_EDITOR_BASE::DIALOG_LABEL_EDITOR_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_textControlSizer = new wxFlexGridSizer( 2, 2, 3, 3 );
+ m_textControlSizer->AddGrowableCol( 1 );
+ m_textControlSizer->AddGrowableRow( 0 );
+ m_textControlSizer->SetFlexibleDirection( wxBOTH );
+ m_textControlSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText1 = new wxStaticText( this, wxID_ANY, _("&Text:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ m_staticText1->SetToolTip( _("Enter the text to be used within the schematic") );
+
+ m_textControlSizer->Add( m_staticText1, 0, wxRIGHT, 3 );
+
+ wxBoxSizer* bSizeText;
+ bSizeText = new wxBoxSizer( wxVERTICAL );
+
+ m_textLabelSingleLine = new wxTextCtrl( this, wxID_VALUESINGLE, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
+ m_textLabelSingleLine->SetValidator( wxTextValidator( wxFILTER_EXCLUDE_CHAR_LIST, &m_labelText ) );
+
+ bSizeText->Add( m_textLabelSingleLine, 0, wxEXPAND|wxLEFT, 3 );
+
+ m_textLabelMultiLine = new wxTextCtrl( this, wxID_VALUEMULTI, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
+ m_textLabelMultiLine->SetMinSize( wxSize( -1,60 ) );
+
+ bSizeText->Add( m_textLabelMultiLine, 1, wxEXPAND|wxLEFT, 3 );
+
+
+ m_textControlSizer->Add( bSizeText, 1, wxEXPAND, 3 );
+
+ m_SizeTitle = new wxStaticText( this, wxID_ANY, _("&Size:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SizeTitle->Wrap( -1 );
+ m_textControlSizer->Add( m_SizeTitle, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 );
+
+ wxBoxSizer* bSizeCtrlSizer;
+ bSizeCtrlSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ m_TextSize = new wxTextCtrl( this, wxID_SIZE, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizeCtrlSizer->Add( m_TextSize, 0, wxEXPAND|wxLEFT|wxRIGHT, 3 );
+
+ m_staticSizeUnits = new wxStaticText( this, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticSizeUnits->Wrap( -1 );
+ bSizeCtrlSizer->Add( m_staticSizeUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 );
+
+
+ m_textControlSizer->Add( bSizeCtrlSizer, 1, wxEXPAND, 3 );
+
+
+ bMainSizer->Add( m_textControlSizer, 1, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 12 );
+
+ wxBoxSizer* m_OptionsSizer;
+ m_OptionsSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxString m_TextOrientChoices[] = { _("Right"), _("Up"), _("Left"), _("Down") };
+ int m_TextOrientNChoices = sizeof( m_TextOrientChoices ) / sizeof( wxString );
+ m_TextOrient = new wxRadioBox( this, wxID_ANY, _("O&rientation"), wxDefaultPosition, wxDefaultSize, m_TextOrientNChoices, m_TextOrientChoices, 1, wxRA_SPECIFY_COLS );
+ m_TextOrient->SetSelection( 0 );
+ m_OptionsSizer->Add( m_TextOrient, 1, wxRIGHT|wxTOP, 3 );
+
+ wxString m_TextStyleChoices[] = { _("Normal"), _("Italic"), _("Bold"), _("Bold Italic") };
+ int m_TextStyleNChoices = sizeof( m_TextStyleChoices ) / sizeof( wxString );
+ m_TextStyle = new wxRadioBox( this, wxID_ANY, _("St&yle"), wxDefaultPosition, wxDefaultSize, m_TextStyleNChoices, m_TextStyleChoices, 1, wxRA_SPECIFY_COLS );
+ m_TextStyle->SetSelection( 0 );
+ m_OptionsSizer->Add( m_TextStyle, 1, wxLEFT|wxRIGHT|wxTOP, 3 );
+
+ wxString m_TextShapeChoices[] = { _("Input"), _("Output"), _("Bidirectional"), _("Tri-State"), _("Passive") };
+ int m_TextShapeNChoices = sizeof( m_TextShapeChoices ) / sizeof( wxString );
+ m_TextShape = new wxRadioBox( this, wxID_ANY, _("S&hape"), wxDefaultPosition, wxDefaultSize, m_TextShapeNChoices, m_TextShapeChoices, 1, wxRA_SPECIFY_COLS );
+ m_TextShape->SetSelection( 0 );
+ m_OptionsSizer->Add( m_TextShape, 1, wxALL|wxLEFT|wxTOP, 3 );
+
+
+ bMainSizer->Add( m_OptionsSizer, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 12 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bMainSizer->Add( m_sdbSizer1, 0, wxALL|wxEXPAND, 12 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ m_textLabelSingleLine->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_LABEL_EDITOR_BASE::OnEnterKey ), NULL, this );
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LABEL_EDITOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LABEL_EDITOR_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_LABEL_EDITOR_BASE::~DIALOG_LABEL_EDITOR_BASE()
+{
+ // Disconnect Events
+ m_textLabelSingleLine->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_LABEL_EDITOR_BASE::OnEnterKey ), NULL, this );
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LABEL_EDITOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LABEL_EDITOR_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_edit_label_base.fbp b/eeschema/dialogs/dialog_edit_label_base.fbp
new file mode 100644
index 0000000..609c484
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_label_base.fbp
@@ -0,0 +1,968 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_edit_label_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_edit_label_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_LABEL_EDITOR_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Text Editor</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">12</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows">0</property>
+ <property name="hgap">3</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_textControlSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">protected</property>
+ <property name="rows">2</property>
+ <property name="vgap">3</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Text:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enter the text to be used within the schematic</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">bSizeText</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_VALUESINGLE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textLabelSingleLine</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_PROCESS_ENTER</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type">wxString</property>
+ <property name="validator_style">wxFILTER_EXCLUDE_CHAR_LIST</property>
+ <property name="validator_type">wxTextValidator</property>
+ <property name="validator_variable">m_labelText</property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnEnterKey</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_VALUEMULTI</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,60</property>
+ <property name="moveable">1</property>
+ <property name="name">m_textLabelMultiLine</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_MULTILINE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Size:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SizeTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizeCtrlSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_SIZE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">units</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticSizeUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">12</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_OptionsSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxRIGHT|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Right&quot; &quot;Up&quot; &quot;Left&quot; &quot;Down&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">O&amp;rientation</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextOrient</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Normal&quot; &quot;Italic&quot; &quot;Bold&quot; &quot;Bold Italic&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">St&amp;yle</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextStyle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxLEFT|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Input&quot; &quot;Output&quot; &quot;Bidirectional&quot; &quot;Tri-State&quot; &quot;Passive&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">S&amp;hape</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextShape</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">12</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_edit_label_base.h b/eeschema/dialogs/dialog_edit_label_base.h
new file mode 100644
index 0000000..2d22d1a
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_label_base.h
@@ -0,0 +1,75 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Feb 26 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_EDIT_LABEL_BASE_H__
+#define __DIALOG_EDIT_LABEL_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/valtext.h>
+#include <wx/sizer.h>
+#include <wx/radiobox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_LABEL_EDITOR_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_LABEL_EDITOR_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ wxID_VALUESINGLE = 1000,
+ wxID_VALUEMULTI,
+ wxID_SIZE
+ };
+
+ wxFlexGridSizer* m_textControlSizer;
+ wxStaticText* m_staticText1;
+ wxTextCtrl* m_textLabelSingleLine;
+ wxTextCtrl* m_textLabelMultiLine;
+ wxStaticText* m_SizeTitle;
+ wxTextCtrl* m_TextSize;
+ wxStaticText* m_staticSizeUnits;
+ wxRadioBox* m_TextOrient;
+ wxRadioBox* m_TextStyle;
+ wxRadioBox* m_TextShape;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnEnterKey( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+ wxString m_labelText;
+
+ DIALOG_LABEL_EDITOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Text Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_LABEL_EDITOR_BASE();
+
+};
+
+#endif //__DIALOG_EDIT_LABEL_BASE_H__
diff --git a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib.cpp b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib.cpp
new file mode 100644
index 0000000..ce10190
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib.cpp
@@ -0,0 +1,796 @@
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011-2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2007-2016 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <algorithm>
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiway.h>
+#include <confirm.h>
+#include <class_drawpanel.h>
+#include <schframe.h>
+#include <id.h>
+#include <base_units.h>
+
+#include <general.h>
+#include <libeditframe.h>
+#include <class_library.h>
+#include <sch_component.h>
+#include <sch_field.h>
+#include <template_fieldnames.h>
+#include <dialog_helpers.h>
+#include <sch_validators.h>
+
+#include <dialog_edit_libentry_fields_in_lib_base.h>
+
+// Local variables:
+static int s_SelectedRow;
+
+#define COLUMN_FIELD_NAME 0
+#define COLUMN_TEXT 1
+
+class DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB : public DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE
+{
+public:
+ DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB( LIB_EDIT_FRAME* aParent, LIB_PART* aLibEntry );
+ //~DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB() {}
+
+private:
+ // Events handlers:
+ void OnInitDialog( wxInitDialogEvent& event );
+ void OnCloseDialog( wxCloseEvent& event );
+
+ void OnListItemDeselected( wxListEvent& event );
+ void OnListItemSelected( wxListEvent& event );
+ void addFieldButtonHandler( wxCommandEvent& event );
+
+ /**
+ * Function deleteFieldButtonHandler
+ * deletes a field.
+ * MANDATORY_FIELDS cannot be deleted.
+ * If a field is empty, it is removed.
+ * if not empty, the text is removed.
+ */
+ void deleteFieldButtonHandler( wxCommandEvent& event );
+
+ void moveUpButtonHandler( wxCommandEvent& event );
+ void OnCancelButtonClick( wxCommandEvent& event );
+ void OnOKButtonClick( wxCommandEvent& event );
+ void showButtonHandler( wxCommandEvent& event );
+
+ // internal functions:
+ void setSelectedFieldNdx( int aFieldNdx );
+
+ int getSelectedFieldNdx();
+
+ /**
+ * Function initBuffers
+ * sets up to edit the given component.
+ */
+ void initBuffers();
+
+ /**
+ * Function findField
+ * searches m_FieldsBuf and returns a LIB_FIELD with \a aFieldName or NULL if
+ * not found.
+ */
+ LIB_FIELD* findField( const wxString& aFieldName );
+
+ /**
+ * Function copySelectedFieldToPanel
+ * sets the values displayed on the panel according to
+ * the currently selected field row
+ */
+ void copySelectedFieldToPanel();
+
+ /**
+ * Function copyPanelToSelectedField
+ * copies the values displayed on the panel fields to the currently selected field
+ * @return bool - true if all fields are OK, else false if the user has put
+ * bad data into a field, and this value can be used to deny a row change.
+ */
+ bool copyPanelToSelectedField();
+
+ void setRowItem( int aFieldNdx, const wxString& aName, const wxString& aValue );
+ void setRowItem( int aFieldNdx, const LIB_FIELD& aField )
+ {
+ setRowItem( aFieldNdx, aField.GetName(), aField.GetText() );
+ }
+
+ /**
+ * Function updateDisplay
+ * update the listbox showing fields, according to the fields texts
+ * must be called after a text change in fields, if this change is not an edition
+ */
+ void updateDisplay( )
+ {
+ for( unsigned ii = MANDATORY_FIELDS; ii<m_FieldsBuf.size(); ii++ )
+ setRowItem( ii, m_FieldsBuf[ii] );
+ }
+
+ LIB_EDIT_FRAME* m_parent;
+ LIB_PART* m_libEntry;
+ bool m_skipCopyFromPanel;
+
+ /// a copy of the edited component's LIB_FIELDs
+ std::vector <LIB_FIELD> m_FieldsBuf;
+};
+
+
+void LIB_EDIT_FRAME::InstallFieldsEditorDialog( wxCommandEvent& event )
+{
+ if( !GetCurPart() )
+ return;
+
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+
+ DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB dlg( this, GetCurPart() );
+
+ // This dialog itself subsequently can invoke a KIWAY_PLAYER as a quasimodal
+ // frame. Therefore this dialog as a modal frame parent, MUST be run under
+ // quasimodal mode for the quasimodal frame support to work. So don't use
+ // the QUASIMODAL macros here.
+ if( dlg.ShowQuasiModal() != wxID_OK )
+ return;
+
+ UpdateAliasSelectList();
+ UpdatePartSelectList();
+ DisplayLibInfos();
+ Refresh();
+}
+
+
+DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB(
+ LIB_EDIT_FRAME* aParent,
+ LIB_PART* aLibEntry ) :
+ DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE( aParent )
+{
+ m_parent = aParent;
+ m_libEntry = aLibEntry;
+ m_skipCopyFromPanel = false;
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::OnInitDialog( wxInitDialogEvent& event )
+{
+ m_skipCopyFromPanel = false;
+ wxListItem columnLabel;
+
+ columnLabel.SetImage( -1 );
+
+ columnLabel.SetText( _( "Name" ) );
+ fieldListCtrl->InsertColumn( COLUMN_FIELD_NAME, columnLabel );
+
+ columnLabel.SetText( _( "Value" ) );
+ fieldListCtrl->InsertColumn( COLUMN_TEXT, columnLabel );
+
+ m_staticTextUnitSize->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_staticTextUnitPosX->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_staticTextUnitPosY->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+
+ initBuffers();
+ copySelectedFieldToPanel();
+
+ stdDialogButtonSizerOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::OnListItemDeselected( wxListEvent& event )
+{
+ if( !m_skipCopyFromPanel )
+ {
+ if( !copyPanelToSelectedField() )
+ event.Skip(); // do not go to the next row
+ }
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::OnListItemSelected( wxListEvent& event )
+{
+ // remember the selected row, statically
+ s_SelectedRow = event.GetIndex();
+
+ copySelectedFieldToPanel();
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::OnCancelButtonClick( wxCommandEvent& event )
+{
+ EndQuasiModal( wxID_CANCEL );
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::OnCloseDialog( wxCloseEvent& event )
+{
+ // On wxWidgets 2.8, and on Linux, call EndQuasiModal here is mandatory
+ // Otherwise, the main event loop is never restored, and Eeschema does not
+ // respond to any event, because the DIALOG_SHIM destructor is never called.
+ // on wxWidgets 3.0, or on Windows, the DIALOG_SHIM destructor is called,
+ // and calls EndQuasiModal.
+ // Therefore calling EndQuasiModal here is not mandatory but it creates no issues.
+ EndQuasiModal( wxID_CANCEL );
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::OnOKButtonClick( wxCommandEvent& event )
+{
+ if( !copyPanelToSelectedField() )
+ return;
+
+ // test if reference prefix is acceptable
+ if( !SCH_COMPONENT::IsReferenceStringValid( m_FieldsBuf[REFERENCE].GetText() ) )
+ {
+ DisplayError( NULL, _( "Illegal reference. References must start with a letter." ) );
+ return;
+ }
+
+ /* Note: this code is now (2010-dec-04) not used, because the value field is no more editable
+ * because changing the value is equivalent to create a new component or alias.
+ * This is now handled in libedit main frame, and no more in this dialog
+ * but this code is not removed, just in case
+ */
+ /* If a new name entered in the VALUE field, that it not an existing alias name
+ * or root alias of the component */
+ wxString newvalue = m_FieldsBuf[VALUE].GetText();
+
+ if( m_libEntry->HasAlias( newvalue ) && !m_libEntry->GetAlias( newvalue )->IsRoot() )
+ {
+ wxString msg = wxString::Format(
+ _( "A new name is entered for this component\n"
+ "An alias %s already exists!\n"
+ "Cannot update this component" ),
+ GetChars( newvalue )
+ );
+ DisplayError( this, msg );
+ return;
+ }
+ /* End unused code */
+
+ // save old cmp in undo list
+ m_parent->SaveCopyInUndoList( m_libEntry );
+
+ // delete any fields with no name or no value before we copy all of m_FieldsBuf
+ // back into the component
+ for( unsigned i = MANDATORY_FIELDS; i < m_FieldsBuf.size(); )
+ {
+ if( m_FieldsBuf[i].GetName().IsEmpty() || m_FieldsBuf[i].GetText().IsEmpty() )
+ {
+ m_FieldsBuf.erase( m_FieldsBuf.begin() + i );
+ continue;
+ }
+
+ ++i;
+ }
+
+ // copy all the fields back, fully replacing any previous fields
+ m_libEntry->SetFields( m_FieldsBuf );
+
+ // We need to keep the name and the value the same at the moment!
+ SetName( m_libEntry->GetValueField().GetText() );
+
+ m_parent->OnModify();
+
+ EndQuasiModal( wxID_OK );
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::addFieldButtonHandler( wxCommandEvent& event )
+{
+ // in case m_FieldsBuf[REFERENCE].m_Orient has changed on screen only, grab
+ // screen contents.
+ if( !copyPanelToSelectedField() )
+ return;
+
+ unsigned fieldNdx = m_FieldsBuf.size();
+
+ LIB_FIELD blank( fieldNdx );
+
+ m_FieldsBuf.push_back( blank );
+ m_FieldsBuf[fieldNdx].SetName( TEMPLATE_FIELDNAME::GetDefaultFieldName( fieldNdx ) );
+
+ setRowItem( fieldNdx, m_FieldsBuf[fieldNdx] );
+
+ m_skipCopyFromPanel = true;
+ setSelectedFieldNdx( fieldNdx );
+ m_skipCopyFromPanel = false;
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::deleteFieldButtonHandler( wxCommandEvent& event )
+{
+ unsigned fieldNdx = getSelectedFieldNdx();
+
+ if( fieldNdx >= m_FieldsBuf.size() ) // traps the -1 case too
+ return;
+
+ if( fieldNdx < MANDATORY_FIELDS )
+ {
+ wxBell();
+ return;
+ }
+
+ m_skipCopyFromPanel = true;
+
+ if( m_FieldsBuf[fieldNdx].GetText().IsEmpty() )
+ {
+ m_FieldsBuf.erase( m_FieldsBuf.begin() + fieldNdx );
+ fieldListCtrl->DeleteItem( fieldNdx );
+
+ if( fieldNdx >= m_FieldsBuf.size() )
+ --fieldNdx;
+ }
+ else
+ {
+ m_FieldsBuf[fieldNdx].Empty();
+ copySelectedFieldToPanel();
+ }
+
+ updateDisplay( );
+
+ setRowItem( fieldNdx, m_FieldsBuf[fieldNdx] );
+ setSelectedFieldNdx( fieldNdx );
+ m_skipCopyFromPanel = false;
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB:: moveUpButtonHandler( wxCommandEvent& event )
+{
+ unsigned fieldNdx = getSelectedFieldNdx();
+
+ if( fieldNdx >= m_FieldsBuf.size() ) // traps the -1 case too
+ return;
+
+ // The first field which can be moved up is the second user field
+ // so any field which id <= MANDATORY_FIELDS cannot be moved up
+ if( fieldNdx <= MANDATORY_FIELDS )
+ return;
+
+ if( !copyPanelToSelectedField() )
+ return;
+
+ // swap the fieldNdx field with the one before it, in both the vector
+ // and in the fieldListCtrl
+ LIB_FIELD tmp = m_FieldsBuf[fieldNdx - 1];
+
+ m_FieldsBuf[fieldNdx - 1] = m_FieldsBuf[fieldNdx];
+ setRowItem( fieldNdx - 1, m_FieldsBuf[fieldNdx] );
+ m_FieldsBuf[fieldNdx - 1].SetId(fieldNdx - 1);
+
+ m_FieldsBuf[fieldNdx] = tmp;
+ setRowItem( fieldNdx, tmp );
+ m_FieldsBuf[fieldNdx].SetId(fieldNdx);
+
+ updateDisplay( );
+
+ m_skipCopyFromPanel = true;
+ setSelectedFieldNdx( fieldNdx - 1 );
+ m_skipCopyFromPanel = false;
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::showButtonHandler( wxCommandEvent& event )
+{
+ unsigned fieldNdx = getSelectedFieldNdx();
+
+ if( fieldNdx == DATASHEET )
+ {
+ wxString datasheet_uri = fieldValueTextCtrl->GetValue();
+ ::wxLaunchDefaultBrowser( datasheet_uri );
+ }
+ else if( fieldNdx == FOOTPRINT )
+ {
+ // pick a footprint using the footprint picker.
+ wxString fpid;
+
+ KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true );
+
+ if( frame->ShowModal( &fpid, this ) )
+ {
+ fieldValueTextCtrl->SetValue( fpid );
+ setRowItem( fieldNdx, m_FieldsBuf[fieldNdx].GetName( false ), fpid );
+ }
+
+ frame->Destroy();
+ }
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::setSelectedFieldNdx( int aFieldNdx )
+{
+ // deselect old selection, but I think this is done by single selection
+ // flag within fieldListCtrl
+ // fieldListCtrl->SetItemState( s_SelectedRow, 0, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);
+
+ if( aFieldNdx >= (int) m_FieldsBuf.size() )
+ aFieldNdx = m_FieldsBuf.size() - 1;
+
+ if( aFieldNdx < 0 )
+ aFieldNdx = 0;
+
+ fieldListCtrl->SetItemState( aFieldNdx, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
+ fieldListCtrl->EnsureVisible( aFieldNdx );
+
+ s_SelectedRow = aFieldNdx;
+}
+
+
+int DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::getSelectedFieldNdx()
+{
+ return s_SelectedRow;
+}
+
+
+/**
+ * Function findfield
+ * searches a LIB_FIELD_LIST for aFieldName.
+ */
+static LIB_FIELD* findfield( const LIB_FIELDS& aList, const wxString& aFieldName )
+{
+ const LIB_FIELD* field = NULL;
+
+ for( unsigned i=0; i<aList.size(); ++i )
+ {
+ if( aFieldName == aList[i].GetName() )
+ {
+ field = &aList[i]; // best to avoid casting here.
+ break;
+ }
+ }
+ return (LIB_FIELD*) field; // remove const-ness last
+}
+
+
+LIB_FIELD* DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::findField( const wxString& aFieldName )
+{
+ for( unsigned i=0; i<m_FieldsBuf.size(); ++i )
+ {
+ if( aFieldName == m_FieldsBuf[i].GetName() )
+ return &m_FieldsBuf[i];
+ }
+ return NULL;
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::initBuffers()
+{
+ LIB_FIELDS cmpFields;
+
+ m_libEntry->GetFields( cmpFields );
+
+ /* We have 3 component related field lists to be aware of: 1) UI
+ presentation (m_FieldsBuf), 2) fields in component ram copy, and 3)
+ fields recorded with component on disk. m_FieldsBuf is the list of UI
+ fields, and this list is not the same as the list which is in the
+ component, which is also not the same as the list on disk. All 3 lists
+ are potentially different. In the UI we choose to preserve the order of
+ the first MANDATORY_FIELDS which are sometimes called fixed fields. Then
+ we append the template fieldnames in the exact same order as the
+ template fieldname editor shows them. Then we append any user defined
+ fieldnames which came from the component, and user can modify it during
+ editing, but cannot delete or move a fixed field.
+ */
+
+ m_FieldsBuf.clear();
+
+ /* When this code was written, all field constructors ensured that the
+ MANDATORY_FIELDS are all present within a component (in ram only). So we can
+ knowingly copy them over in the normal order. Copy only the fixed fields
+ at first. Please do not break the field constructors.
+ */
+
+ // fixed fields:
+ for( int i=0; i<MANDATORY_FIELDS; ++i )
+ {
+ m_FieldsBuf.push_back( cmpFields[i] );
+ }
+
+ // Add template fieldnames:
+ // Now copy in the template fields, in the order that they are present in the
+ // template field editor UI.
+ SCH_EDIT_FRAME* editor = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, true );
+
+ const TEMPLATE_FIELDNAMES& tfnames = editor->GetTemplateFieldNames();
+
+ for( TEMPLATE_FIELDNAMES::const_iterator it = tfnames.begin(); it!=tfnames.end(); ++it )
+ {
+ // add a new field unconditionally to the UI only for this template fieldname
+
+ // field id must not be in range 0 - MANDATORY_FIELDS, set before saving to disk
+ LIB_FIELD fld( m_libEntry, -1 );
+
+ // See if field by same name already exists in component.
+ LIB_FIELD* libField = findfield( cmpFields, it->m_Name );
+
+ // If the field does not already exist in the component, then we
+ // use defaults from the template fieldname, otherwise the original
+ // values from the component will be set.
+ if( !libField )
+ {
+ fld.SetName( it->m_Name );
+ fld.SetText( it->m_Value ); // empty? ok too.
+
+ if( !it->m_Visible )
+ fld.SetVisible( false );
+ else
+ fld.SetVisible( true );
+ }
+ else
+ {
+ fld = *libField; // copy values from component, m_Name too
+ }
+
+ m_FieldsBuf.push_back( fld );
+ }
+
+ // Lastly, append any original fields from the component which were not added
+ // from the set of fixed fields nor from the set of template fields.
+ for( unsigned i=MANDATORY_FIELDS; i<cmpFields.size(); ++i )
+ {
+ LIB_FIELD* cmp = &cmpFields[i];
+ LIB_FIELD* buf = findField( cmp->GetName() );
+
+ if( !buf )
+ {
+ m_FieldsBuf.push_back( *cmp );
+ }
+ }
+
+ /* field names have become more important than field ids, so we cannot
+ mangle the names in the buffer, but can do so in the panel, see elsewhere.
+ m_FieldsBuf[VALUE].m_Name << wxT( "/" ) << _( "Chip Name" );
+ */
+
+ for( unsigned ii = 0; ii < m_FieldsBuf.size(); ++ii )
+ {
+ setRowItem( ii, m_FieldsBuf[ii] );
+ }
+
+ // put focus on the list ctrl
+ fieldListCtrl->SetFocus();
+
+ // resume editing at the last row edited, last time dialog was up.
+ if ( s_SelectedRow < (int) m_FieldsBuf.size() )
+ s_SelectedRow = 0;
+
+ setSelectedFieldNdx( s_SelectedRow );
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::setRowItem( int aFieldNdx, const wxString& aName, const wxString& aValue )
+{
+ wxASSERT( aFieldNdx >= 0 );
+
+ // insert blanks if aFieldNdx is referencing a "yet to be defined" row
+ while( aFieldNdx >= fieldListCtrl->GetItemCount() )
+ {
+ long ndx = fieldListCtrl->InsertItem( fieldListCtrl->GetItemCount(), wxEmptyString );
+
+ wxASSERT( ndx >= 0 );
+
+ fieldListCtrl->SetItem( ndx, COLUMN_TEXT, wxEmptyString );
+ }
+
+ fieldListCtrl->SetItem( aFieldNdx, COLUMN_FIELD_NAME, aName );
+ fieldListCtrl->SetItem( aFieldNdx, COLUMN_TEXT, aValue );
+
+ // recompute the column widths here, after setting texts
+ fieldListCtrl->SetColumnWidth( COLUMN_FIELD_NAME, wxLIST_AUTOSIZE );
+ fieldListCtrl->SetColumnWidth( COLUMN_TEXT, wxLIST_AUTOSIZE );
+}
+
+
+void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::copySelectedFieldToPanel()
+{
+ unsigned fieldNdx = getSelectedFieldNdx();
+
+ if( fieldNdx >= m_FieldsBuf.size() ) // traps the -1 case too
+ return;
+
+ LIB_FIELD& field = m_FieldsBuf[fieldNdx];
+
+ showCheckBox->SetValue( field.IsVisible() );
+
+ rotateCheckBox->SetValue( field.GetOrientation() == TEXT_ORIENT_VERT );
+
+ int style = 0;
+
+ if( field.IsItalic() )
+ style = 1;
+
+ if( field.IsBold() )
+ style |= 2;
+
+ m_StyleRadioBox->SetSelection( style );
+
+ // Select the right text justification
+ if( field.GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT )
+ m_FieldHJustifyCtrl->SetSelection(0);
+ else if( field.GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT )
+ m_FieldHJustifyCtrl->SetSelection(2);
+ else
+ m_FieldHJustifyCtrl->SetSelection(1);
+
+ if( field.GetVertJustify() == GR_TEXT_VJUSTIFY_BOTTOM )
+ m_FieldVJustifyCtrl->SetSelection(0);
+ else if( field.GetVertJustify() == GR_TEXT_VJUSTIFY_TOP )
+ m_FieldVJustifyCtrl->SetSelection(2);
+ else
+ m_FieldVJustifyCtrl->SetSelection(1);
+
+
+ // Field names have become more important than field ids, so we cannot
+ // mangle the names in the buffer but we can do so in the panel.
+ if( field.GetId() == VALUE )
+ {
+ // This field is the lib name and the default value when loading this component in
+ // schematic. The value is now not editable here (in this dialog) because changing
+ // it is equivalent to create a new component or alias. This is handles in libedir,
+ // not in this dialog.
+ fieldNameTextCtrl->SetValue( field.GetName() + wxT( " / " ) + _( "Chip Name" ) );
+ fieldValueTextCtrl->Enable( false );
+ }
+ else
+ {
+ fieldValueTextCtrl->Enable( true );
+ fieldNameTextCtrl->SetValue( field.GetName() );
+ }
+
+ // if fieldNdx == REFERENCE, VALUE, FOOTPRINT, or DATASHEET, then disable field name editing
+ fieldNameTextCtrl->Enable( fieldNdx >= MANDATORY_FIELDS );
+ fieldNameTextCtrl->SetEditable( fieldNdx >= MANDATORY_FIELDS );
+
+ // only user defined fields may be moved, and not the top most user defined
+ // field since it would be moving up into the fixed fields, > not >=
+ moveUpButton->Enable( fieldNdx > MANDATORY_FIELDS );
+
+ // if fieldNdx == REFERENCE, VALUE, then disable delete button
+ deleteFieldButton->Enable( fieldNdx >= MANDATORY_FIELDS );
+
+ fieldValueTextCtrl->SetValidator( SCH_FIELD_VALIDATOR( true, field.GetId() ) );
+ fieldValueTextCtrl->SetValue( field.GetText() );
+
+ textSizeTextCtrl->SetValue( EDA_GRAPHIC_TEXT_CTRL::FormatSize( g_UserUnit, field.GetSize().x ) );
+
+ m_show_datasheet_button->Enable( fieldNdx == DATASHEET || fieldNdx == FOOTPRINT );
+
+ if( fieldNdx == DATASHEET )
+ m_show_datasheet_button->SetLabel( _( "Show in Browser" ) );
+ else if( fieldNdx == FOOTPRINT )
+ m_show_datasheet_button->SetLabel( _( "Assign Footprint" ) );
+ else
+ m_show_datasheet_button->SetLabel( wxEmptyString );
+
+ wxPoint coord = field.GetTextPosition();
+ wxPoint zero;
+
+ // If the field value is empty and the position is at relative zero, we set the
+ // initial position as a small offset from the ref field, and orient
+ // it the same as the ref field. That is likely to put it at least
+ // close to the desired position.
+ if( coord == zero && field.GetText().IsEmpty() )
+ {
+ rotateCheckBox->SetValue( m_FieldsBuf[REFERENCE].GetOrientation() == TEXT_ORIENT_VERT );
+
+ coord.x = m_FieldsBuf[REFERENCE].GetTextPosition().x +
+ (fieldNdx - MANDATORY_FIELDS + 1) * 100;
+ coord.y = m_FieldsBuf[REFERENCE].GetTextPosition().y +
+ (fieldNdx - MANDATORY_FIELDS + 1) * 100;
+
+ // coord can compute negative if field is < MANDATORY_FIELDS, e.g. FOOTPRINT.
+ // That is ok, we basically don't want all the new empty fields on
+ // top of each other.
+ }
+
+ wxString coordText = StringFromValue( g_UserUnit, coord.x );
+ posXTextCtrl->SetValue( coordText );
+
+ // Note: the Y axis for components in lib is from bottom to top
+ // and the screen axis is top to bottom: we must change the y coord sign for editing
+ coord.y = -coord.y;
+ coordText = StringFromValue( g_UserUnit, coord.y );
+ posYTextCtrl->SetValue( coordText );
+}
+
+
+bool DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::copyPanelToSelectedField()
+{
+ unsigned fieldNdx = getSelectedFieldNdx();
+
+ if( fieldNdx >= m_FieldsBuf.size() ) // traps the -1 case too
+ return true;
+
+ // Check for illegal field text.
+ if( fieldValueTextCtrl->GetValidator()
+ && !fieldValueTextCtrl->GetValidator()->Validate( this ) )
+ return false;
+
+ LIB_FIELD& field = m_FieldsBuf[fieldNdx];
+
+ if( showCheckBox->GetValue() )
+ field.SetVisible( true );
+ else
+ field.SetVisible( false );
+
+ if( rotateCheckBox->GetValue() )
+ field.SetOrientation( TEXT_ORIENT_VERT );
+ else
+ field.SetOrientation( TEXT_ORIENT_HORIZ );
+
+ // Copy the text justification
+ static const EDA_TEXT_HJUSTIFY_T hjustify[3] = {
+ GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_HJUSTIFY_RIGHT
+ };
+
+ static const EDA_TEXT_VJUSTIFY_T vjustify[3] = {
+ GR_TEXT_VJUSTIFY_BOTTOM, GR_TEXT_VJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_TOP
+ };
+
+ field.SetHorizJustify( hjustify[m_FieldHJustifyCtrl->GetSelection()] );
+ field.SetVertJustify( vjustify[m_FieldVJustifyCtrl->GetSelection()] );
+
+ // Blank/empty field texts for REFERENCE and VALUE are not allowed.
+ // (Value is the name of the component in lib!)
+ // Change them only if user provided a non blank value
+ if( !fieldValueTextCtrl->GetValue().IsEmpty() || fieldNdx > VALUE )
+ field.SetText( fieldValueTextCtrl->GetValue() );
+
+ // FieldNameTextCtrl has a tricked value in it for VALUE index, do not copy it back.
+ // It has the "Chip Name" appended.
+ if( field.GetId() >= MANDATORY_FIELDS )
+ {
+ wxString name = fieldNameTextCtrl->GetValue();
+ field.SetName( name );
+ }
+
+ setRowItem( fieldNdx, field ); // update fieldListCtrl
+
+ int tmp = EDA_GRAPHIC_TEXT_CTRL::ParseSize( textSizeTextCtrl->GetValue(), g_UserUnit );
+
+ field.SetSize( wxSize( tmp, tmp ) );
+
+ int style = m_StyleRadioBox->GetSelection();
+
+ field.SetItalic( (style & 1 ) != 0 );
+ field.SetBold( (style & 2 ) != 0 );
+
+ wxPoint pos( ValueFromString( g_UserUnit, posXTextCtrl->GetValue() ),
+ ValueFromString( g_UserUnit, posYTextCtrl->GetValue() ) );
+
+ // Note: the Y axis for components in lib is from bottom to top
+ // and the screen axis is top to bottom: we must change the y coord sign for editing
+ pos.y = -pos.y;
+
+ field.SetTextPosition( pos );
+
+ return true;
+}
diff --git a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.cpp b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.cpp
new file mode 100644
index 0000000..8bdc8b5
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.cpp
@@ -0,0 +1,229 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_edit_libentry_fields_in_lib_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* mainSizer;
+ mainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerFieldsSetup;
+ bSizerFieldsSetup = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizerFiledsList;
+ bSizerFiledsList = new wxBoxSizer( wxVERTICAL );
+
+ fieldListCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES );
+ bSizerFiledsList->Add( fieldListCtrl, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 6 );
+
+ addFieldButton = new wxButton( this, wxID_ANY, _("Add Field"), wxDefaultPosition, wxDefaultSize, 0 );
+ addFieldButton->SetToolTip( _("Add a new custom field") );
+
+ bSizerFiledsList->Add( addFieldButton, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ deleteFieldButton = new wxButton( this, wxID_ANY, _("Delete Field"), wxDefaultPosition, wxDefaultSize, 0 );
+ deleteFieldButton->SetToolTip( _("Delete one of the optional fields") );
+
+ bSizerFiledsList->Add( deleteFieldButton, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ moveUpButton = new wxButton( this, wxID_ANY, _("Move Up"), wxDefaultPosition, wxDefaultSize, 0 );
+ moveUpButton->SetToolTip( _("Move the selected optional fields up one position") );
+
+ bSizerFiledsList->Add( moveUpButton, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizerFieldsSetup->Add( bSizerFiledsList, 3, wxEXPAND, 5 );
+
+ wxBoxSizer* fieldEditBoxSizer;
+ fieldEditBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerJustify;
+ bSizerJustify = new wxBoxSizer( wxHORIZONTAL );
+
+ wxString m_FieldHJustifyCtrlChoices[] = { _("Left"), _("Center"), _("Right") };
+ int m_FieldHJustifyCtrlNChoices = sizeof( m_FieldHJustifyCtrlChoices ) / sizeof( wxString );
+ m_FieldHJustifyCtrl = new wxRadioBox( this, wxID_ANY, _("Horiz. Justify"), wxDefaultPosition, wxDefaultSize, m_FieldHJustifyCtrlNChoices, m_FieldHJustifyCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_FieldHJustifyCtrl->SetSelection( 1 );
+ m_FieldHJustifyCtrl->SetToolTip( _("Select if the component is to be rotated when drawn") );
+
+ bSizerJustify->Add( m_FieldHJustifyCtrl, 1, wxEXPAND|wxALL, 5 );
+
+ wxString m_FieldVJustifyCtrlChoices[] = { _("Bottom"), _("Center"), _("Top") };
+ int m_FieldVJustifyCtrlNChoices = sizeof( m_FieldVJustifyCtrlChoices ) / sizeof( wxString );
+ m_FieldVJustifyCtrl = new wxRadioBox( this, wxID_ANY, _("Vert. Justify"), wxDefaultPosition, wxDefaultSize, m_FieldVJustifyCtrlNChoices, m_FieldVJustifyCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_FieldVJustifyCtrl->SetSelection( 0 );
+ m_FieldVJustifyCtrl->SetToolTip( _("Pick the graphical transformation to be used when displaying the component, if any") );
+
+ bSizerJustify->Add( m_FieldVJustifyCtrl, 1, wxEXPAND|wxALL, 5 );
+
+
+ fieldEditBoxSizer->Add( bSizerJustify, 1, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerAspect;
+ bSizerAspect = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* visibilitySizer;
+ visibilitySizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Visibility") ), wxVERTICAL );
+
+ showCheckBox = new wxCheckBox( this, wxID_ANY, _("Show"), wxDefaultPosition, wxDefaultSize, 0 );
+ showCheckBox->SetToolTip( _("Check if you want this field visible") );
+
+ visibilitySizer->Add( showCheckBox, 0, wxALL, 5 );
+
+ rotateCheckBox = new wxCheckBox( this, wxID_ANY, _("Rotate"), wxDefaultPosition, wxDefaultSize, 0 );
+ rotateCheckBox->SetToolTip( _("Check if you want this field's text rotated 90 degrees") );
+
+ visibilitySizer->Add( rotateCheckBox, 0, wxALL, 5 );
+
+
+ bSizerAspect->Add( visibilitySizer, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_StyleRadioBoxChoices[] = { _("Normal"), _("Italic"), _("Bold"), _("Bold Italic") };
+ int m_StyleRadioBoxNChoices = sizeof( m_StyleRadioBoxChoices ) / sizeof( wxString );
+ m_StyleRadioBox = new wxRadioBox( this, wxID_ANY, _("Style:"), wxDefaultPosition, wxDefaultSize, m_StyleRadioBoxNChoices, m_StyleRadioBoxChoices, 1, wxRA_SPECIFY_COLS );
+ m_StyleRadioBox->SetSelection( 0 );
+ bSizerAspect->Add( m_StyleRadioBox, 1, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ fieldEditBoxSizer->Add( bSizerAspect, 1, wxALL|wxEXPAND|wxTOP, 5 );
+
+ wxBoxSizer* fieldNameBoxSizer;
+ fieldNameBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ fieldNameLabel = new wxStaticText( this, wxID_ANY, _("Field Name"), wxDefaultPosition, wxDefaultSize, 0 );
+ fieldNameLabel->Wrap( -1 );
+ fieldNameBoxSizer->Add( fieldNameLabel, 0, 0, 5 );
+
+ fieldNameTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fieldNameTextCtrl->SetMaxLength( 0 );
+ fieldNameTextCtrl->SetToolTip( _("The text (or value) of the currently selected field") );
+
+ fieldNameBoxSizer->Add( fieldNameTextCtrl, 0, wxBOTTOM|wxEXPAND, 5 );
+
+ fieldValueLabel = new wxStaticText( this, wxID_ANY, _("Field Value"), wxDefaultPosition, wxDefaultSize, 0 );
+ fieldValueLabel->Wrap( -1 );
+ fieldNameBoxSizer->Add( fieldValueLabel, 0, wxTOP, 5 );
+
+ fieldValueTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fieldValueTextCtrl->SetMaxLength( 0 );
+ fieldValueTextCtrl->SetToolTip( _("The text (or value) of the currently selected field") );
+
+ fieldNameBoxSizer->Add( fieldValueTextCtrl, 0, wxBOTTOM|wxEXPAND, 5 );
+
+ m_show_datasheet_button = new wxButton( this, wxID_ANY, _("Show in Browser"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_show_datasheet_button->SetToolTip( _("If your datasheet is given as an http:// link, then pressing this button should bring it up in your webbrowser.") );
+
+ fieldNameBoxSizer->Add( m_show_datasheet_button, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 );
+
+
+ fieldEditBoxSizer->Add( fieldNameBoxSizer, 0, wxALL|wxEXPAND, 5 );
+
+ wxFlexGridSizer* fgSizerPosSize;
+ fgSizerPosSize = new wxFlexGridSizer( 3, 3, 5, 5 );
+ fgSizerPosSize->AddGrowableCol( 1 );
+ fgSizerPosSize->SetFlexibleDirection( wxBOTH );
+ fgSizerPosSize->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ textSizeLabel = new wxStaticText( this, wxID_ANY, _("Size"), wxDefaultPosition, wxDefaultSize, 0 );
+ textSizeLabel->Wrap( -1 );
+ fgSizerPosSize->Add( textSizeLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ textSizeTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ textSizeTextCtrl->SetMaxLength( 0 );
+ textSizeTextCtrl->SetToolTip( _("The vertical height of the currently selected field's text in the schematic") );
+
+ fgSizerPosSize->Add( textSizeTextCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+ m_staticTextUnitSize = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextUnitSize->Wrap( -1 );
+ fgSizerPosSize->Add( m_staticTextUnitSize, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ posXLabel = new wxStaticText( this, wxID_ANY, _("X Position"), wxDefaultPosition, wxDefaultSize, 0 );
+ posXLabel->Wrap( -1 );
+ fgSizerPosSize->Add( posXLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ posXTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ posXTextCtrl->SetMaxLength( 0 );
+ fgSizerPosSize->Add( posXTextCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+ m_staticTextUnitPosX = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextUnitPosX->Wrap( -1 );
+ fgSizerPosSize->Add( m_staticTextUnitPosX, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ posYLabel = new wxStaticText( this, wxID_ANY, _("Y Position"), wxDefaultPosition, wxDefaultSize, 0 );
+ posYLabel->Wrap( -1 );
+ fgSizerPosSize->Add( posYLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ posYTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ posYTextCtrl->SetMaxLength( 0 );
+ posYTextCtrl->SetToolTip( _("The Y coordinate of the text relative to the component") );
+
+ fgSizerPosSize->Add( posYTextCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+ m_staticTextUnitPosY = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextUnitPosY->Wrap( -1 );
+ fgSizerPosSize->Add( m_staticTextUnitPosY, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ fieldEditBoxSizer->Add( fgSizerPosSize, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizerFieldsSetup->Add( fieldEditBoxSizer, 2, wxEXPAND, 5 );
+
+
+ mainSizer->Add( bSizerFieldsSetup, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ mainSizer->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ stdDialogButtonSizer = new wxStdDialogButtonSizer();
+ stdDialogButtonSizerOK = new wxButton( this, wxID_OK );
+ stdDialogButtonSizer->AddButton( stdDialogButtonSizerOK );
+ stdDialogButtonSizerCancel = new wxButton( this, wxID_CANCEL );
+ stdDialogButtonSizer->AddButton( stdDialogButtonSizerCancel );
+ stdDialogButtonSizer->Realize();
+
+ mainSizer->Add( stdDialogButtonSizer, 0, wxALL|wxEXPAND, 6 );
+
+
+ this->SetSizer( mainSizer );
+ this->Layout();
+ mainSizer->Fit( this );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::OnCloseDialog ) );
+ this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::OnInitDialog ) );
+ fieldListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::OnListItemDeselected ), NULL, this );
+ fieldListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::OnListItemSelected ), NULL, this );
+ addFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::addFieldButtonHandler ), NULL, this );
+ deleteFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::deleteFieldButtonHandler ), NULL, this );
+ moveUpButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::moveUpButtonHandler ), NULL, this );
+ m_show_datasheet_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::showButtonHandler ), NULL, this );
+ stdDialogButtonSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::OnCancelButtonClick ), NULL, this );
+ stdDialogButtonSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::OnOKButtonClick ), NULL, this );
+}
+
+DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::~DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::OnCloseDialog ) );
+ this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::OnInitDialog ) );
+ fieldListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::OnListItemDeselected ), NULL, this );
+ fieldListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::OnListItemSelected ), NULL, this );
+ addFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::addFieldButtonHandler ), NULL, this );
+ deleteFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::deleteFieldButtonHandler ), NULL, this );
+ moveUpButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::moveUpButtonHandler ), NULL, this );
+ m_show_datasheet_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::showButtonHandler ), NULL, this );
+ stdDialogButtonSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::OnCancelButtonClick ), NULL, this );
+ stdDialogButtonSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE::OnOKButtonClick ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.fbp b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.fbp
new file mode 100644
index 0000000..42a647e
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.fbp
@@ -0,0 +1,2326 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration">; </property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">ANSI</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_edit_libentry_fields_in_lib_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DialogEditLibentryFields_in_lib_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Field Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseDialog</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog">OnInitDialog</event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">mainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerFieldsSetup</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">3</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerFiledsList</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxListCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">fieldListCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBeginDrag"></event>
+ <event name="OnListBeginLabelEdit"></event>
+ <event name="OnListBeginRDrag"></event>
+ <event name="OnListCacheHint"></event>
+ <event name="OnListColBeginDrag"></event>
+ <event name="OnListColClick"></event>
+ <event name="OnListColDragging"></event>
+ <event name="OnListColEndDrag"></event>
+ <event name="OnListColRightClick"></event>
+ <event name="OnListDeleteAllItems"></event>
+ <event name="OnListDeleteItem"></event>
+ <event name="OnListEndLabelEdit"></event>
+ <event name="OnListInsertItem"></event>
+ <event name="OnListItemActivated"></event>
+ <event name="OnListItemDeselected">OnListItemDeselected</event>
+ <event name="OnListItemFocused"></event>
+ <event name="OnListItemMiddleClick"></event>
+ <event name="OnListItemRightClick"></event>
+ <event name="OnListItemSelected">OnListItemSelected</event>
+ <event name="OnListKeyDown"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Add Field</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">addFieldButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Add a new custom field</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">addFieldButtonHandler</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Delete Field</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">deleteFieldButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Delete one of the optional fields</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">deleteFieldButtonHandler</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Move Up</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">moveUpButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Move the selected optional fields up one position</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">moveUpButtonHandler</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">2</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">fieldEditBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerJustify</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Left&quot; &quot;Center&quot; &quot;Right&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Horiz. Justify</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FieldHJustifyCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Select if the component is to be rotated when drawn</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Bottom&quot; &quot;Center&quot; &quot;Top&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Vert. Justify</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FieldVJustifyCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Pick the graphical transformation to be used when displaying the component, if any</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerAspect</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Visibility</property>
+ <property name="minimum_size"></property>
+ <property name="name">visibilitySizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">showCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Check if you want this field visible</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Rotate</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">rotateCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Check if you want this field&apos;s text rotated 90 degrees</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Normal&quot; &quot;Italic&quot; &quot;Bold&quot; &quot;Bold Italic&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Style:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_StyleRadioBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">fieldNameBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Field Name</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldNameLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldNameTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">The text (or value) of the currently selected field</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Field Value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldValueLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldValueTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">The text (or value) of the currently selected field</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show in Browser</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_show_datasheet_button</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If your datasheet is given as an http:// link, then pressing this button should bring it up in your webbrowser.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">showButtonHandler</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">5</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerPosSize</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">3</property>
+ <property name="vgap">5</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">textSizeLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">textSizeTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">The vertical height of the currently selected field&apos;s text in the schematic</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextUnitSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">X Position</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">posXLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">posXTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextUnitPosX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Y Position</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">posYLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">posYTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">The Y coordinate of the text relative to the component</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextUnitPosY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">stdDialogButtonSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelButtonClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKButtonClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.h b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.h
new file mode 100644
index 0000000..002e727
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib_base.h
@@ -0,0 +1,92 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE_H__
+#define __DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/listctrl.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/string.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/radiobox.h>
+#include <wx/checkbox.h>
+#include <wx/statbox.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/statline.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxListCtrl* fieldListCtrl;
+ wxButton* addFieldButton;
+ wxButton* deleteFieldButton;
+ wxButton* moveUpButton;
+ wxRadioBox* m_FieldHJustifyCtrl;
+ wxRadioBox* m_FieldVJustifyCtrl;
+ wxCheckBox* showCheckBox;
+ wxCheckBox* rotateCheckBox;
+ wxRadioBox* m_StyleRadioBox;
+ wxStaticText* fieldNameLabel;
+ wxTextCtrl* fieldNameTextCtrl;
+ wxStaticText* fieldValueLabel;
+ wxTextCtrl* fieldValueTextCtrl;
+ wxButton* m_show_datasheet_button;
+ wxStaticText* textSizeLabel;
+ wxTextCtrl* textSizeTextCtrl;
+ wxStaticText* m_staticTextUnitSize;
+ wxStaticText* posXLabel;
+ wxTextCtrl* posXTextCtrl;
+ wxStaticText* m_staticTextUnitPosX;
+ wxStaticText* posYLabel;
+ wxTextCtrl* posYTextCtrl;
+ wxStaticText* m_staticTextUnitPosY;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* stdDialogButtonSizer;
+ wxButton* stdDialogButtonSizerOK;
+ wxButton* stdDialogButtonSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseDialog( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
+ virtual void OnListItemDeselected( wxListEvent& event ) { event.Skip(); }
+ virtual void OnListItemSelected( wxListEvent& event ) { event.Skip(); }
+ virtual void addFieldButtonHandler( wxCommandEvent& event ) { event.Skip(); }
+ virtual void deleteFieldButtonHandler( wxCommandEvent& event ) { event.Skip(); }
+ virtual void moveUpButtonHandler( wxCommandEvent& event ) { event.Skip(); }
+ virtual void showButtonHandler( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Field Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU );
+ ~DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE();
+
+};
+
+#endif //__DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE_H__
diff --git a/eeschema/dialogs/dialog_edit_one_field.cpp b/eeschema/dialogs/dialog_edit_one_field.cpp
new file mode 100644
index 0000000..3ee5f1e
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_one_field.cpp
@@ -0,0 +1,278 @@
+/**
+ * @file dialog_edit_one_field.cpp
+ * @brief dialog to editing a field ( not a graphic text) in current component.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2016 Wayne Stambaugh, stambaughw@gmail.com
+ * Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <base_units.h>
+#include <kiway.h>
+#include <confirm.h>
+
+#include <general.h>
+#include <sch_base_frame.h>
+#include <sch_component.h>
+#include <class_libentry.h>
+#include <lib_field.h>
+#include <sch_component.h>
+#include <template_fieldnames.h>
+#include <class_library.h>
+#include <sch_validators.h>
+
+#include <dialog_edit_one_field.h>
+
+
+// These should probably moved into some other file as helpers.
+EDA_TEXT_HJUSTIFY_T IntToEdaTextHorizJustify( int aHorizJustify )
+{
+ wxASSERT( aHorizJustify >= GR_TEXT_HJUSTIFY_LEFT && aHorizJustify <= GR_TEXT_HJUSTIFY_RIGHT );
+
+ if( aHorizJustify > GR_TEXT_HJUSTIFY_RIGHT )
+ return GR_TEXT_HJUSTIFY_RIGHT;
+
+ if( aHorizJustify < GR_TEXT_HJUSTIFY_LEFT )
+ return GR_TEXT_HJUSTIFY_LEFT;
+
+ return (EDA_TEXT_HJUSTIFY_T) aHorizJustify;
+}
+
+
+EDA_TEXT_VJUSTIFY_T IntToEdaTextVertJustify( int aVertJustify )
+{
+ wxASSERT( aVertJustify >= GR_TEXT_VJUSTIFY_TOP && aVertJustify <= GR_TEXT_VJUSTIFY_BOTTOM );
+
+ if( aVertJustify > GR_TEXT_VJUSTIFY_BOTTOM )
+ return GR_TEXT_VJUSTIFY_BOTTOM;
+
+ if( aVertJustify < GR_TEXT_VJUSTIFY_TOP )
+ return GR_TEXT_VJUSTIFY_TOP;
+
+ return (EDA_TEXT_VJUSTIFY_T) aVertJustify;
+}
+
+
+DIALOG_EDIT_ONE_FIELD::DIALOG_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent, const wxString& aTitle,
+ const EDA_TEXT* aTextItem ) :
+ DIALOG_LIB_EDIT_TEXT_BASE( aParent )
+{
+ SetTitle( aTitle );
+
+ // The field ID and power status are Initialized in the derived object's ctor.
+ m_fieldId = VALUE;
+ m_isPower = false;
+
+ m_text = aTextItem->GetText();
+ m_style = aTextItem->IsItalic() ? 1 : 0;
+ m_style += aTextItem->IsBold() ? 2 : 0;
+ m_size = aTextItem->GetSize().x;
+ m_orientation = ( aTextItem->GetOrientation() == TEXT_ORIENT_VERT );
+ m_verticalJustification = aTextItem->GetVertJustify() + 1;
+ m_horizontalJustification = aTextItem->GetHorizJustify() + 1;
+ m_isVisible = aTextItem->IsVisible();
+}
+
+
+void DIALOG_EDIT_ONE_FIELD::init()
+{
+ wxString msg;
+
+ m_TextValue->SetFocus();
+ SCH_BASE_FRAME* parent = static_cast<SCH_BASE_FRAME*>( GetParent() );
+ m_TextValue->SetValidator( SCH_FIELD_VALIDATOR(
+ parent->IsType( FRAME_SCH_LIB_EDITOR ),
+ m_fieldId, &m_text ) );
+
+ // Disable options for graphic text editing which are not needed for fields.
+ m_CommonConvert->Show( false );
+ m_CommonUnit->Show( false );
+
+ // Show the footprint selection dialog if this is the footprint field.
+ if( m_fieldId == FOOTPRINT )
+ {
+ m_TextValueSelectButton->Show();
+ m_TextValueSelectButton->Enable();
+ }
+ else
+ {
+ m_TextValueSelectButton->Hide();
+ m_TextValueSelectButton->Disable();
+ }
+
+ msg = m_TextSizeText->GetLabel() + ReturnUnitSymbol();
+ m_TextSizeText->SetLabel( msg );
+
+
+ // Value fields of power components cannot be modified. This will grey out
+ // the text box and display an explanation.
+ if( m_fieldId == VALUE && m_isPower )
+ {
+ m_PowerComponentValues->Show( true );
+ m_TextValue->Enable( false );
+ }
+ else
+ {
+ m_PowerComponentValues->Show( false );
+ m_TextValue->Enable( true );
+ }
+
+ m_sdbSizerButtonsOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void DIALOG_EDIT_ONE_FIELD::OnTextValueSelectButtonClick( wxCommandEvent& aEvent )
+{
+ // pick a footprint using the footprint picker.
+ wxString fpid;
+
+ KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true );
+
+ if( frame->ShowModal( &fpid, this ) )
+ {
+ m_TextValue->SetValue( fpid );
+ }
+
+ frame->Destroy();
+}
+
+
+bool DIALOG_EDIT_ONE_FIELD::TransferDataToWindow()
+{
+ wxLogDebug( "In DIALOG_EDIT_ONE_FIELD::TransferDataToWindow()" );
+
+ m_TextValue->SetValue( m_text );
+ m_Orient->SetValue( m_orientation );
+ m_TextSize->SetValue( StringFromValue( g_UserUnit, m_size ) );
+ m_TextHJustificationOpt->SetSelection( m_horizontalJustification );
+ m_TextVJustificationOpt->SetSelection( m_verticalJustification );
+ m_Invisible->SetValue( !m_isVisible );
+ m_TextShapeOpt->SetSelection( m_style );
+
+ return true;
+}
+
+
+bool DIALOG_EDIT_ONE_FIELD::TransferDataFromWindow()
+{
+ wxLogDebug( "In DIALOG_EDIT_ONE_FIELD::TransferDataFromWindow()" );
+
+ m_text = m_TextValue->GetValue();
+
+ // There are lots of specific tests required to validate field text.
+ if( m_fieldId == REFERENCE )
+ {
+ // Test if the reference string is valid:
+ if( !SCH_COMPONENT::IsReferenceStringValid( m_text ) )
+ {
+ DisplayError( this, _( "Illegal reference field value!" ) );
+ return false;
+ }
+ }
+
+ m_orientation = m_Orient->GetValue();
+ m_size = ValueFromString( g_UserUnit, m_TextSize->GetValue() );
+ m_horizontalJustification = m_TextHJustificationOpt->GetSelection();
+ m_verticalJustification = m_TextVJustificationOpt->GetSelection();
+ m_isVisible = !m_Invisible->GetValue();
+ m_style = m_TextShapeOpt->GetSelection();
+
+ return true;
+}
+
+
+void DIALOG_EDIT_ONE_FIELD::updateText( EDA_TEXT* aText )
+{
+ aText->SetSize( wxSize( m_size, m_size ) );
+ aText->SetVisible( m_isVisible );
+ aText->SetOrientation( m_orientation ? TEXT_ORIENT_VERT : TEXT_ORIENT_HORIZ );
+ aText->SetItalic( (m_style & 1) != 0 );
+ aText->SetBold( (m_style & 2) != 0 );
+ aText->SetHorizJustify( IntToEdaTextHorizJustify( m_horizontalJustification - 1 ) );
+ aText->SetVertJustify( IntToEdaTextVertJustify( m_verticalJustification - 1 ) );
+}
+
+
+DIALOG_LIB_EDIT_ONE_FIELD::DIALOG_LIB_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent,
+ const wxString& aTitle,
+ const LIB_FIELD* aField ) :
+ DIALOG_EDIT_ONE_FIELD( aParent, aTitle, dynamic_cast< const EDA_TEXT* >( aField ) )
+{
+ m_fieldId = aField->GetId();
+
+ // When in the library editor, power components can be renamed.
+ m_isPower = false;
+ init();
+}
+
+
+DIALOG_SCH_EDIT_ONE_FIELD::DIALOG_SCH_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent,
+ const wxString& aTitle,
+ const SCH_FIELD* aField ) :
+ DIALOG_EDIT_ONE_FIELD( aParent, aTitle, dynamic_cast< const EDA_TEXT* >( aField ) )
+{
+ m_fieldId = aField->GetId();
+
+ const SCH_COMPONENT* component = (SCH_COMPONENT*) aField->GetParent();
+
+ wxASSERT_MSG( component != NULL && component->Type() == SCH_COMPONENT_T,
+ wxT( "Invalid schematic field parent item." ) );
+
+ const LIB_PART* part = GetParent()->Prj().SchLibs()->FindLibPart( component->GetPartName() );
+
+ wxASSERT_MSG( part, wxT( "Library part for component <" ) +
+ component->GetPartName() + wxT( "> could not be found." ) );
+
+ m_isPower = part->IsPower();
+
+ init();
+}
+
+
+void DIALOG_SCH_EDIT_ONE_FIELD::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH* aSheetPath )
+{
+ wxASSERT( aField != NULL || aField->Type() != SCH_FIELD_T );
+
+ if( aField->GetId() == REFERENCE )
+ {
+ wxASSERT( aSheetPath != NULL );
+
+ SCH_COMPONENT* component = dynamic_cast< SCH_COMPONENT* >( aField->GetParent() );
+
+ wxASSERT( component != NULL );
+
+ if( component != NULL )
+ component->SetRef( aSheetPath, m_text );
+ }
+
+ aField->SetText( m_text );
+ updateText( aField );
+}
diff --git a/eeschema/dialogs/dialog_edit_one_field.h b/eeschema/dialogs/dialog_edit_one_field.h
new file mode 100644
index 0000000..d12e47b
--- /dev/null
+++ b/eeschema/dialogs/dialog_edit_one_field.h
@@ -0,0 +1,159 @@
+
+#ifndef DIALOG_EDIT_ONE_FIELD_H_
+#define DIALOG_EDIT_ONE_FIELD_H_
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2016 Wayne Stambaugh, stambaughw@gmail.com
+ * Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <dialog_lib_edit_text_base.h>
+
+class SCH_BASE_FRAME;
+class LIB_FIELD;
+class SCH_FIELD;
+class EDA_TEXT;
+
+
+/**
+ * Class DIALOG_EDIT_ONE_FIELD
+ * is a base class to edit schematic and component library fields.
+ * <p>
+ * This class is setup in expectation of its children
+ * possibly using Kiway player so ShowQuasiModal is required when calling
+ * any subclasses.
+ *</p>
+ */
+class DIALOG_EDIT_ONE_FIELD : public DIALOG_LIB_EDIT_TEXT_BASE
+{
+public:
+ DIALOG_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent, const wxString& aTitle,
+ const EDA_TEXT* aTextItem );
+
+ ~DIALOG_EDIT_ONE_FIELD() {}
+
+ virtual bool TransferDataToWindow();
+
+ virtual bool TransferDataFromWindow();
+
+ SCH_BASE_FRAME* GetParent() { return dynamic_cast< SCH_BASE_FRAME* >( wxDialog::GetParent() ); }
+
+ const wxString& GetText() const { return m_text; }
+
+protected:
+
+ void init();
+
+ void updateText( EDA_TEXT* aText );
+
+ /**
+ * Function OnTextValueSelectButtonClick
+ * Handles the select button next to the text value field. The current assumption
+ * is that this event will only be enabled for footprint type fields. In the future
+ * this function may need to be moved to the subclasses to access m_field and check for
+ * the field type if more select actions are desired.
+ *
+ * @param aEvent is the the wX event thrown when the button is clicked, this isn't used
+ */
+ void OnTextValueSelectButtonClick( wxCommandEvent& aEvent );
+
+ /// @todo Update DIALOG_SHIM to handle this transparently so no matter what mode the
+ /// dialogs is shown, everything is handled without this ugliness.
+ void OnOkClick( wxCommandEvent& aEvent )
+ {
+ if( IsQuasiModal() )
+ EndQuasiModal( wxID_OK );
+ else
+ EndDialog( wxID_OK );
+ }
+
+ void OnCancelClick( wxCommandEvent& event )
+ {
+ if( IsQuasiModal() )
+ EndQuasiModal( wxID_CANCEL );
+ else
+ EndDialog( wxID_CANCEL );
+ }
+
+ void OnCloseDialog( wxCloseEvent& aEvent )
+ {
+ if( IsQuasiModal() )
+ EndQuasiModal( wxID_CANCEL );
+ else
+ EndDialog( wxID_CANCEL );
+ }
+
+ int m_fieldId;
+ bool m_isPower;
+ wxString m_text;
+ int m_style;
+ int m_size;
+ bool m_orientation;
+ int m_verticalJustification;
+ int m_horizontalJustification;
+ bool m_isVisible;
+};
+
+
+/**
+ * Class DIALOG_LIB_EDIT_ONE_FIELD
+ * is a the class to handle editing a single component field in the library editor.
+ * <p>
+ * @note Use ShowQuasiModal when calling this class!
+ * </p>
+ */
+class DIALOG_LIB_EDIT_ONE_FIELD : public DIALOG_EDIT_ONE_FIELD
+{
+public:
+ DIALOG_LIB_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent, const wxString& aTitle,
+ const LIB_FIELD* aField );
+
+ ~DIALOG_LIB_EDIT_ONE_FIELD() {}
+
+ void UpdateField( LIB_FIELD* aField )
+ {
+ aField->SetText( m_text );
+ updateText( aField );
+ }
+};
+
+
+/**
+ * Class DIALOG_SCH_EDIT_ONE_FIELD
+ * is a the class to handle editing a single component field in the schematic editor.
+ * <p>
+ * @note Use ShowQuasiModal when calling this class!
+ * </p>
+ */
+class DIALOG_SCH_EDIT_ONE_FIELD : public DIALOG_EDIT_ONE_FIELD
+{
+public:
+ DIALOG_SCH_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent, const wxString& aTitle,
+ const SCH_FIELD* aField );
+
+ ~DIALOG_SCH_EDIT_ONE_FIELD() {}
+
+ void UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH* aSheetPath );
+};
+
+#endif // DIALOG_EDIT_ONE_FIELD_H_
diff --git a/eeschema/dialogs/dialog_eeschema_config.cpp b/eeschema/dialogs/dialog_eeschema_config.cpp
new file mode 100644
index 0000000..07dab49
--- /dev/null
+++ b/eeschema/dialogs/dialog_eeschema_config.cpp
@@ -0,0 +1,490 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2006-2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_eeschema_config.cpp
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiway.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <schframe.h>
+#include <invoke_sch_dialog.h>
+#include <kiface_i.h>
+
+#include <general.h>
+#include <netlist.h>
+#include <libeditframe.h>
+#include <viewlib_frame.h>
+#include <wildcards_and_files_ext.h>
+#include <wx/tokenzr.h>
+#include <dialog_eeschema_config_fbp.h>
+#include <eeschema_config.h>
+
+
+class SCH_EDIT_FRAME;
+class EDA_DRAW_FRAME;
+
+
+class DIALOG_EESCHEMA_CONFIG : public DIALOG_EESCHEMA_CONFIG_FBP
+{
+public:
+ DIALOG_EESCHEMA_CONFIG( wxWindow* aParent,
+ wxString* aCallersProjectSpecificLibPaths, wxArrayString* aCallersLibNames );
+
+private:
+ wxConfigBase* m_config;
+ wxString* m_callers_project_specific_lib_paths;
+ wxArrayString* m_callers_lib_names;
+
+ bool m_lib_list_changed;
+ bool m_lib_path_changed;
+
+ //------ event handlers, overiding the fbp handlers --------------
+
+ void OnCloseWindow( wxCloseEvent& event );
+
+ /* Remove a library to the library list.
+ * The real list (m_Parent->m_ComponentLibFiles) is not changed, so the change can be canceled
+ */
+ void OnRemoveLibClick( wxCommandEvent& event );
+
+ /* Insert or add a library to the library list:
+ * The new library is put in list before (insert button) the selection,
+ * or added (add button) to end of list
+ * The real list (m_Parent->m_ComponentLibFiles) is not changed, so the change
+ * can be canceled
+ */
+ void OnAddOrInsertLibClick( wxCommandEvent& event );
+
+ void OnAddOrInsertPath( wxCommandEvent& event );
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+ void OnRemoveUserPath( wxCommandEvent& event );
+ void OnButtonUpClick( wxCommandEvent& event );
+ void OnButtonDownClick( wxCommandEvent& event );
+};
+
+
+DIALOG_EESCHEMA_CONFIG::DIALOG_EESCHEMA_CONFIG( wxWindow* aParent,
+ wxString* aCallersProjectSpecificLibPaths, wxArrayString* aCallersLibNames ) :
+ DIALOG_EESCHEMA_CONFIG_FBP( aParent ),
+ m_callers_project_specific_lib_paths( aCallersProjectSpecificLibPaths ),
+ m_callers_lib_names( aCallersLibNames ),
+ m_lib_list_changed( false ),
+ m_lib_path_changed( false )
+{
+ m_ListLibr->InsertItems( *aCallersLibNames, 0 );
+
+ // Load user libs paths:
+ wxArrayString paths;
+
+ SEARCH_STACK::Split( &paths, *aCallersProjectSpecificLibPaths );
+
+ for( unsigned i=0; i<paths.GetCount(); ++i )
+ {
+ wxString path = paths[i];
+
+ if( wxFileName::DirExists( Prj().AbsolutePath( path ) ) )
+ m_listUserPaths->Append( path );
+ }
+
+ // Display actual library paths which come in part from KIFACE::KifaceSearch()
+ // along with aCallersProjectSpecificLibPaths at the front.
+ SEARCH_STACK* libpaths = Prj().SchSearchS();
+
+ DBG( libpaths->Show( __func__ ); )
+
+ for( unsigned ii = 0; ii < libpaths->GetCount(); ii++ )
+ {
+ m_DefaultLibraryPathslistBox->Append( (*libpaths)[ii] );
+ }
+
+ // select the first path after the current project's path
+ if( libpaths->GetCount() > 1 )
+ m_DefaultLibraryPathslistBox->Select( 1 );
+
+ // Load setting for cache rescue
+ m_config = Kiface().KifaceSettings();
+ bool rescueNeverShow = false;
+ m_config->Read( RESCUE_NEVER_SHOW_KEY, &rescueNeverShow, false );
+ m_cbRescue->SetValue( !rescueNeverShow );
+
+ wxString msg = wxString::Format( _(
+ "Project '%s'" ),
+ GetChars( Prj().GetProjectFullName() )
+ );
+
+ SetTitle( msg );
+
+ if( GetSizer() )
+ GetSizer()->SetSizeHints( this );
+
+ m_sdbSizer1OK->SetDefault();
+}
+
+
+void DIALOG_EESCHEMA_CONFIG::OnButtonUpClick( wxCommandEvent& event )
+{
+ wxArrayInt selections;
+
+ m_ListLibr->GetSelections( selections );
+
+ if ( selections.GetCount() <= 0 ) // No selection.
+ return;
+
+ if( selections[0] == 0 ) // The first lib is selected. cannot move up it
+ return;
+
+ wxArrayString libnames = m_ListLibr->GetStrings();
+
+ for( size_t ii = 0; ii < selections.GetCount(); ii++ )
+ {
+ int jj = selections[ii];
+ std::swap( libnames[jj], libnames[jj-1]);
+ }
+
+ m_ListLibr->Set(libnames);
+
+ // Reselect previously selected names
+ for( size_t ii = 0; ii < selections.GetCount(); ii++ )
+ {
+ int jj = selections[ii];
+ m_ListLibr->SetSelection(jj-1);
+ }
+
+ m_lib_list_changed = true;
+}
+
+
+void DIALOG_EESCHEMA_CONFIG::OnButtonDownClick( wxCommandEvent& event )
+{
+ wxArrayInt selections;
+
+ m_ListLibr->GetSelections(selections);
+
+ if ( selections.GetCount() <= 0 ) // No selection.
+ return;
+
+ // The last lib is selected. cannot move down it
+ if( selections.Last() == (int)(m_ListLibr->GetCount()-1) )
+ return;
+
+ wxArrayString libnames = m_ListLibr->GetStrings();
+
+ for( int ii = selections.GetCount()-1; ii >= 0; ii-- )
+ {
+ int jj = selections[ii];
+ std::swap( libnames[jj], libnames[jj+1]);
+ }
+
+ m_ListLibr->Set( libnames );
+
+ // Reselect previously selected names
+ for( size_t ii = 0; ii < selections.GetCount(); ii++ )
+ {
+ int jj = selections[ii];
+ m_ListLibr->SetSelection(jj+1);
+ }
+
+ m_lib_list_changed = true;
+}
+
+
+void DIALOG_EESCHEMA_CONFIG::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+void DIALOG_EESCHEMA_CONFIG::OnOkClick( wxCommandEvent& event )
+{
+ // Give caller the changed paths
+ if( m_lib_path_changed )
+ {
+ wxString paths;
+
+ for( unsigned ii = 0; ii < m_listUserPaths->GetCount(); ii++ )
+ {
+ if( ii > 0 )
+ paths += wxT( ';' );
+
+ paths += m_listUserPaths->GetString( ii );
+ }
+
+ *m_callers_project_specific_lib_paths = paths;
+ }
+
+ // Update caller's lib_names if changed.
+ if( m_lib_list_changed )
+ {
+ wxArrayString list;
+
+ for( unsigned ii = 0; ii < m_ListLibr->GetCount(); ii ++ )
+ list.Add( m_ListLibr->GetString( ii ) );
+
+ // Recreate lib list
+ *m_callers_lib_names = list;
+ }
+
+ m_config->Write( RESCUE_NEVER_SHOW_KEY, ! m_cbRescue->GetValue() );
+
+ EndModal( wxID_OK );
+}
+
+
+void DIALOG_EESCHEMA_CONFIG::OnCloseWindow( wxCloseEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+void DIALOG_EESCHEMA_CONFIG::OnRemoveLibClick( wxCommandEvent& event )
+{
+ wxArrayInt selections;
+
+ m_ListLibr->GetSelections( selections );
+
+ for( int ii = selections.GetCount()-1; ii >= 0; ii-- )
+ {
+ m_ListLibr->Delete( selections[ii] );
+ m_lib_list_changed = true;
+ }
+
+ // Select next item after deleted in m_ListLibr
+ if( m_ListLibr->GetCount() > 0 && selections.GetCount() > 0 )
+ {
+ int pos = selections[selections.GetCount()-1];
+
+ if( pos == (int)m_ListLibr->GetCount() )
+ pos = m_ListLibr->GetCount() - 1;
+
+ m_ListLibr->SetSelection( pos );
+ }
+}
+
+
+void DIALOG_EESCHEMA_CONFIG::OnAddOrInsertLibClick( wxCommandEvent& event )
+{
+ int ii;
+ wxString libfilename;
+ wxArrayInt selections;
+
+ PROJECT& prj = Prj();
+
+ m_ListLibr->GetSelections( selections );
+
+ ii = selections.GetCount();
+
+ if( ii > 0 )
+ ii = selections[0];
+ else
+ ii = 0;
+
+ wxString selection = m_DefaultLibraryPathslistBox->GetStringSelection();
+ wxString libpath = Prj().AbsolutePath( selection );
+
+ if( !libpath )
+ {
+ libpath = prj.GetRString( PROJECT::SCH_LIB_PATH );
+ }
+
+ wxFileDialog filesDialog( this, _( "Library files:" ), libpath,
+ wxEmptyString, SchematicLibraryFileWildcard,
+ wxFD_DEFAULT_STYLE | wxFD_MULTIPLE );
+
+ if( filesDialog.ShowModal() != wxID_OK )
+ return;
+
+ wxArrayString filenames;
+
+ filesDialog.GetPaths( filenames );
+
+ wxFileName fn;
+
+ // Build libs paths, to find later a relative path:
+ wxArrayString paths;
+
+ for( unsigned ll=0; ll < m_DefaultLibraryPathslistBox->GetCount(); ++ll )
+ paths.Add( m_DefaultLibraryPathslistBox->GetString( ll ) );
+
+ for( unsigned ll=0; ll < m_listUserPaths->GetCount(); ++ll )
+ paths.Add( m_listUserPaths->GetString( ll ) );
+
+ for( unsigned jj = 0; jj < filenames.GetCount(); jj++ )
+ {
+ fn = filenames[jj];
+
+ if( jj == 0 )
+ prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
+
+ // Extension is not stored, so remove extension:
+ fn.SetExt( wxEmptyString );
+
+ // Try to use relative path:
+ for( unsigned ll = 0; ll < paths.GetCount(); ll++ )
+ {
+ wxFileName relfn = fn;
+ relfn.MakeRelativeTo( paths[ll] );
+
+ if( relfn.GetPath()[0] != '.' )
+ {
+ fn = relfn;
+ break;
+ }
+ }
+
+ libfilename = fn.GetFullPath();
+
+ // Add or insert new library name, if not already in list
+ if( m_ListLibr->FindString( libfilename, fn.IsCaseSensitive() ) == wxNOT_FOUND )
+ {
+ m_lib_list_changed = true;
+
+ if( event.GetId() == ID_ADD_LIB )
+ m_ListLibr->Append( libfilename );
+ else
+ m_ListLibr->Insert( libfilename, ii++ );
+ }
+ else
+ {
+ wxString msg = wxString::Format( _(
+ "'%s' : library already in use" ),
+ GetChars( libfilename )
+ );
+ DisplayError( this, msg );
+ }
+ }
+}
+
+
+void DIALOG_EESCHEMA_CONFIG::OnAddOrInsertPath( wxCommandEvent& event )
+{
+ PROJECT& prj = Prj();
+ wxString abs_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
+ wxString path;
+
+ bool select = EDA_PATH_SELECTOR( _( "Default Path for Libraries" ),
+ abs_path, wxDD_DEFAULT_STYLE,
+ this, wxDefaultPosition );
+
+ if( !select )
+ return;
+
+ if( !wxFileName::DirExists( abs_path ) ) // Should not occur
+ return;
+
+ // Add or insert path if not already in list
+ if( m_listUserPaths->FindString( abs_path ) == wxNOT_FOUND )
+ {
+ int ipos = m_listUserPaths->GetCount();
+
+ if( event.GetId() == wxID_INSERT_PATH )
+ {
+ if( ipos )
+ ipos--;
+
+ int jj = m_listUserPaths->GetSelection();
+
+ if( jj >= 0 )
+ ipos = jj;
+ }
+
+ // Ask the user if this is a relative path
+ int diag = wxMessageBox( _( "Use a relative path?" ), _( "Path type" ),
+ wxYES_NO | wxICON_QUESTION, this );
+
+ if( diag == wxYES )
+ {
+ // Make it relative
+ wxFileName fn = abs_path;
+ fn.MakeRelativeTo( wxPathOnly( Prj().GetProjectFullName() ) );
+ path = fn.GetPathWithSep() + fn.GetFullName();
+ }
+ else
+ path = abs_path;
+
+ m_listUserPaths->Insert( path, ipos );
+ m_lib_path_changed = true;
+
+ m_DefaultLibraryPathslistBox->InsertItems( 1, &path, ipos+1 );
+ }
+ else
+ {
+ DisplayError( this, _("Path already in use") );
+ }
+
+ prj.SetRString( PROJECT::SCH_LIB_PATH, abs_path );
+}
+
+
+static void remove_from_listbox( wxListBox* aListBox, const wxString& aText )
+{
+ wxArrayString a;
+
+ for( int i=0, cnt = aListBox->GetCount(); i<cnt; ++i )
+ {
+ wxString item = aListBox->GetString( i );
+
+ if( item != aText )
+ a.Add( item );
+ }
+
+ aListBox->Clear();
+
+ aListBox->InsertItems( a, 0 );
+}
+
+
+void DIALOG_EESCHEMA_CONFIG::OnRemoveUserPath( wxCommandEvent& event )
+{
+ int ii = m_listUserPaths->GetSelection();
+
+ if( ii < 0 )
+ ii = m_listUserPaths->GetCount()-1;
+
+ if( ii >= 0 )
+ {
+ wxString sel = m_listUserPaths->GetStringSelection();
+
+ remove_from_listbox( m_DefaultLibraryPathslistBox, sel );
+
+ m_listUserPaths->Delete( ii );
+ m_lib_path_changed = true;
+ }
+}
+
+
+bool InvokeEeschemaConfig( wxWindow* aParent,
+ wxString* aCallersProjectSpecificLibPaths, wxArrayString* aCallersLibNames )
+{
+ DIALOG_EESCHEMA_CONFIG dlg( aParent,
+ aCallersProjectSpecificLibPaths, aCallersLibNames );
+
+ int ret = dlg.ShowModal();
+
+ return wxID_OK == ret;
+}
diff --git a/eeschema/dialogs/dialog_eeschema_config_fbp.cpp b/eeschema/dialogs/dialog_eeschema_config_fbp.cpp
new file mode 100644
index 0000000..5ac72bc
--- /dev/null
+++ b/eeschema/dialogs/dialog_eeschema_config_fbp.cpp
@@ -0,0 +1,175 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_eeschema_config_fbp.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_EESCHEMA_CONFIG_FBP::DIALOG_EESCHEMA_CONFIG_FBP( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextLibsList = new wxStaticText( this, wxID_ANY, _("Component library files"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextLibsList->Wrap( -1 );
+ bSizerUpper->Add( m_staticTextLibsList, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerLibsChoice;
+ bSizerLibsChoice = new wxBoxSizer( wxHORIZONTAL );
+
+ m_ListLibr = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED|wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE );
+ m_ListLibr->SetToolTip( _("List of active library files.\nOnly library files in this list are loaded by Eeschema.\nThe order of this list is important:\nEeschema searchs for a given component using this list order priority.") );
+ m_ListLibr->SetMinSize( wxSize( 400,250 ) );
+
+ bSizerLibsChoice->Add( m_ListLibr, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bRightSizer;
+ bRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonAddLib = new wxButton( this, ID_ADD_LIB, _("Add"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonAddLib->SetToolTip( _("Add a new library after the selected library, and load it") );
+
+ bRightSizer->Add( m_buttonAddLib, 0, wxLEFT|wxRIGHT|wxTOP|wxEXPAND, 5 );
+
+ m_buttonIns = new wxButton( this, wxID_ANY, _("Insert"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonIns->SetToolTip( _("Add a new library before the selected library, and load it") );
+
+ bRightSizer->Add( m_buttonIns, 0, wxLEFT|wxRIGHT|wxTOP|wxEXPAND, 5 );
+
+ m_buttonRemoveLib = new wxButton( this, ID_REMOVE_LIB, _("Remove"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonRemoveLib->SetToolTip( _("Unload the selected library") );
+
+ bRightSizer->Add( m_buttonRemoveLib, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonUp = new wxButton( this, wxID_ANY, _("Up"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonUp, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_buttonDown = new wxButton( this, wxID_ANY, _("Down"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonDown, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ bSizerLibsChoice->Add( bRightSizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizerUpper->Add( bSizerLibsChoice, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bSizerUpper, 2, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerMiddle;
+ bSizerMiddle = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextPaths = new wxStaticText( this, wxID_ANY, _("User defined search path"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextPaths->Wrap( -1 );
+ bSizerMiddle->Add( m_staticTextPaths, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerPathsChoice;
+ bSizerPathsChoice = new wxBoxSizer( wxHORIZONTAL );
+
+ m_listUserPaths = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE );
+ m_listUserPaths->SetToolTip( _("Additional paths used in this project. The priority is higher than default KiCad paths.") );
+ m_listUserPaths->SetMinSize( wxSize( 400,90 ) );
+
+ bSizerPathsChoice->Add( m_listUserPaths, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bUserPathsButtonsSizer;
+ bUserPathsButtonsSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonAddPath = new wxButton( this, ID_LIB_PATH_SEL, _("Add"), wxDefaultPosition, wxDefaultSize, 0 );
+ bUserPathsButtonsSizer->Add( m_buttonAddPath, 0, wxLEFT|wxRIGHT|wxTOP|wxEXPAND, 5 );
+
+ m_buttonInsPath = new wxButton( this, wxID_INSERT_PATH, _("Insert"), wxDefaultPosition, wxDefaultSize, 0 );
+ bUserPathsButtonsSizer->Add( m_buttonInsPath, 0, wxLEFT|wxRIGHT|wxTOP|wxEXPAND, 5 );
+
+ m_buttonRemovePath = new wxButton( this, wxID_REMOVE_PATH, _("Remove"), wxDefaultPosition, wxDefaultSize, 0 );
+ bUserPathsButtonsSizer->Add( m_buttonRemovePath, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizerPathsChoice->Add( bUserPathsButtonsSizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizerMiddle->Add( bSizerPathsChoice, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bSizerMiddle, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerLower;
+ bSizerLower = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextPathlist = new wxStaticText( this, wxID_ANY, _("Current search path list"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextPathlist->Wrap( -1 );
+ bSizerLower->Add( m_staticTextPathlist, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_DefaultLibraryPathslistBox = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_NEEDED_SB );
+ m_DefaultLibraryPathslistBox->SetToolTip( _("System and user paths used to search and load library files and component doc files.\nSorted by decreasing priority order.") );
+
+ bSizerLower->Add( m_DefaultLibraryPathslistBox, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bMainSizer->Add( bSizerLower, 1, wxEXPAND, 5 );
+
+ m_cbRescue = new wxCheckBox( this, wxID_ANY, _("Check for cache/library conflicts when loading schematic"), wxDefaultPosition, wxDefaultSize, 0 );
+ bMainSizer->Add( m_cbRescue, 0, wxALL, 5 );
+
+ m_staticline3 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline3, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bMainSizer->Add( m_sdbSizer1, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnCloseWindow ) );
+ m_ListLibr->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnFilesListClick ), NULL, this );
+ m_ListLibr->Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnFilesListClick ), NULL, this );
+ m_buttonAddLib->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnAddOrInsertLibClick ), NULL, this );
+ m_buttonIns->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnAddOrInsertLibClick ), NULL, this );
+ m_buttonRemoveLib->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnRemoveLibClick ), NULL, this );
+ m_buttonUp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnButtonUpClick ), NULL, this );
+ m_buttonDown->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnButtonDownClick ), NULL, this );
+ m_buttonAddPath->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnAddOrInsertPath ), NULL, this );
+ m_buttonInsPath->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnAddOrInsertPath ), NULL, this );
+ m_buttonRemovePath->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnRemoveUserPath ), NULL, this );
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnOkClick ), NULL, this );
+}
+
+DIALOG_EESCHEMA_CONFIG_FBP::~DIALOG_EESCHEMA_CONFIG_FBP()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnCloseWindow ) );
+ m_ListLibr->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnFilesListClick ), NULL, this );
+ m_ListLibr->Disconnect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnFilesListClick ), NULL, this );
+ m_buttonAddLib->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnAddOrInsertLibClick ), NULL, this );
+ m_buttonIns->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnAddOrInsertLibClick ), NULL, this );
+ m_buttonRemoveLib->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnRemoveLibClick ), NULL, this );
+ m_buttonUp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnButtonUpClick ), NULL, this );
+ m_buttonDown->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnButtonDownClick ), NULL, this );
+ m_buttonAddPath->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnAddOrInsertPath ), NULL, this );
+ m_buttonInsPath->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnAddOrInsertPath ), NULL, this );
+ m_buttonRemovePath->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnRemoveUserPath ), NULL, this );
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EESCHEMA_CONFIG_FBP::OnOkClick ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_eeschema_config_fbp.fbp b/eeschema/dialogs/dialog_eeschema_config_fbp.fbp
new file mode 100644
index 0000000..72fcc43
--- /dev/null
+++ b/eeschema/dialogs/dialog_eeschema_config_fbp.fbp
@@ -0,0 +1,1588 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_eeschema_config_fbp</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_eeschema_config</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_EESCHEMA_CONFIG_FBP</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseWindow</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">2</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Component library files</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextLibsList</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerLibsChoice</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxListBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">400,250</property>
+ <property name="moveable">1</property>
+ <property name="name">m_ListLibr</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLB_EXTENDED|wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">List of active library files.&#x0A;Only library files in this list are loaded by Eeschema.&#x0A;The order of this list is important:&#x0A;Eeschema searchs for a given component using this list order priority.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox">OnFilesListClick</event>
+ <event name="OnListBoxDClick">OnFilesListClick</event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADD_LIB</property>
+ <property name="label">Add</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonAddLib</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Add a new library after the selected library, and load it</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnAddOrInsertLibClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Insert</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonIns</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Add a new library before the selected library, and load it</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnAddOrInsertLibClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_REMOVE_LIB</property>
+ <property name="label">Remove</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonRemoveLib</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Unload the selected library</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnRemoveLibClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Up</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonUp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonUpClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Down</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonDown</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonDownClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMiddle</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">User defined search path</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextPaths</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerPathsChoice</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxListBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">400,90</property>
+ <property name="moveable">1</property>
+ <property name="name">m_listUserPaths</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Additional paths used in this project. The priority is higher than default KiCad paths.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox"></event>
+ <event name="OnListBoxDClick"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUserPathsButtonsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_LIB_PATH_SEL</property>
+ <property name="label">Add</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonAddPath</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnAddOrInsertPath</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_INSERT_PATH</property>
+ <property name="label">Insert</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonInsPath</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnAddOrInsertPath</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_REMOVE_PATH</property>
+ <property name="label">Remove</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonRemovePath</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnRemoveUserPath</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerLower</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Current search path list</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextPathlist</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxListBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_DefaultLibraryPathslistBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLB_NEEDED_SB</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">System and user paths used to search and load library files and component doc files.&#x0A;Sorted by decreasing priority order.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox"></event>
+ <event name="OnListBoxDClick"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Check for cache/library conflicts when loading schematic</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbRescue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">public</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_eeschema_config_fbp.h b/eeschema/dialogs/dialog_eeschema_config_fbp.h
new file mode 100644
index 0000000..5af47cd
--- /dev/null
+++ b/eeschema/dialogs/dialog_eeschema_config_fbp.h
@@ -0,0 +1,89 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_EESCHEMA_CONFIG_FBP_H__
+#define __DIALOG_EESCHEMA_CONFIG_FBP_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/listbox.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/checkbox.h>
+#include <wx/statline.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_EESCHEMA_CONFIG_FBP
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_EESCHEMA_CONFIG_FBP : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ ID_ADD_LIB = 1000,
+ ID_REMOVE_LIB,
+ ID_LIB_PATH_SEL,
+ wxID_INSERT_PATH,
+ wxID_REMOVE_PATH
+ };
+
+ wxStaticText* m_staticTextLibsList;
+ wxListBox* m_ListLibr;
+ wxButton* m_buttonAddLib;
+ wxButton* m_buttonIns;
+ wxButton* m_buttonRemoveLib;
+ wxButton* m_buttonUp;
+ wxButton* m_buttonDown;
+ wxStaticText* m_staticTextPaths;
+ wxListBox* m_listUserPaths;
+ wxButton* m_buttonAddPath;
+ wxButton* m_buttonInsPath;
+ wxButton* m_buttonRemovePath;
+ wxStaticText* m_staticTextPathlist;
+ wxListBox* m_DefaultLibraryPathslistBox;
+ wxCheckBox* m_cbRescue;
+ wxStaticLine* m_staticline3;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnFilesListClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnAddOrInsertLibClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRemoveLibClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonUpClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonDownClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnAddOrInsertPath( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRemoveUserPath( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ DIALOG_EESCHEMA_CONFIG_FBP( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_EESCHEMA_CONFIG_FBP();
+
+};
+
+#endif //__DIALOG_EESCHEMA_CONFIG_FBP_H__
diff --git a/eeschema/dialogs/dialog_eeschema_options.cpp b/eeschema/dialogs/dialog_eeschema_options.cpp
new file mode 100644
index 0000000..70541b7
--- /dev/null
+++ b/eeschema/dialogs/dialog_eeschema_options.cpp
@@ -0,0 +1,371 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_eeschema_options.cpp
+ */
+
+#include <fctsys.h>
+#include <class_base_screen.h>
+
+#include <dialog_eeschema_options.h>
+
+#include "wx/settings.h"
+
+DIALOG_EESCHEMA_OPTIONS::DIALOG_EESCHEMA_OPTIONS( wxWindow* parent ) :
+ DIALOG_EESCHEMA_OPTIONS_BASE( parent )
+{
+ m_choiceUnits->SetFocus();
+ m_sdbSizerOK->SetDefault();
+
+ wxListItem col0;
+ col0.SetId( 0 );
+ col0.SetText( _( "Field Name" ) );
+
+ wxListItem col1;
+ col1.SetId( 1 );
+ col1.SetText( _( "Default Value" ) );
+
+ wxListItem col2;
+ col2.SetId( 2 );
+ col2.SetText( _( "Visible" ) );
+
+ templateFieldListCtrl->InsertColumn( 0, col0 );
+ templateFieldListCtrl->InsertColumn( 1, col1 );
+ templateFieldListCtrl->InsertColumn( 2, col2 );
+
+ templateFieldListCtrl->SetColumnWidth( 0, templateFieldListCtrl->GetSize().GetWidth() / 3.5 );
+ templateFieldListCtrl->SetColumnWidth( 1, templateFieldListCtrl->GetSize().GetWidth() / 3.5 );
+ templateFieldListCtrl->SetColumnWidth( 2, templateFieldListCtrl->GetSize().GetWidth() / 3.5 );
+
+ // Invalid field selected
+ selectedField = -1;
+
+ // Make sure we select the first tab of the options tab page
+ m_notebook->SetSelection( 0 );
+
+ // Connect the edit controls for the template field names to the kill focus event which
+ // doesn't propogate, hence the need to connect it here.
+
+ fieldNameTextCtrl->Connect( wxEVT_KILL_FOCUS,
+ wxFocusEventHandler( DIALOG_EESCHEMA_OPTIONS::OnEditControlKillFocus ), NULL, this );
+
+ fieldDefaultValueTextCtrl->Connect( wxEVT_KILL_FOCUS,
+ wxFocusEventHandler( DIALOG_EESCHEMA_OPTIONS::OnEditControlKillFocus ), NULL, this );
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::SetUnits( const wxArrayString& units, int select )
+{
+ wxASSERT( units.GetCount() > 0
+ && ( select >= 0 && (size_t) select < units.GetCount() ) );
+
+ m_choiceUnits->Append( units );
+ m_choiceUnits->SetSelection( select );
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::SetRefIdSeparator( wxChar aSep, wxChar aFirstId)
+{
+ // m_choiceSeparatorRefId displays one of
+ // "A" ".A" "-A" "_A" ".1" "-1" "_1" option
+
+ int sel = 0;
+ switch( aSep )
+ {
+ default:
+ case 0:
+ aFirstId = 'A'; // cannot use a number without separator
+ break;
+
+ case '.':
+ sel = 1;
+ break;
+
+ case '-':
+ sel = 2;
+ break;
+
+ case '_':
+ sel = 3;
+ break;
+ }
+
+ if( aFirstId == '1' )
+ sel = 4;
+
+ m_choiceSeparatorRefId->SetSelection( sel );
+}
+
+void DIALOG_EESCHEMA_OPTIONS::GetRefIdSeparator( int& aSep, int& aFirstId)
+{
+ // m_choiceSeparatorRefId displays one of
+ // "A" ".A" "-A" "_A" ".1" "-1" "_1" option
+
+ aFirstId = 'A';
+ switch( m_choiceSeparatorRefId->GetSelection() )
+ {
+ default:
+ case 0: aSep = 0; break;
+ case 1: aSep = '.'; break;
+ case 2: aSep = '-'; break;
+ case 3: aSep = '_'; break;
+ case 4: aFirstId = '1'; aSep = '.'; break;
+ case 5: aFirstId = '1'; aSep = '-'; break;
+ case 6: aFirstId = '1'; aSep = '_'; break;
+ }
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::SetGridSizes( const GRIDS& aGridSizes, int aGridId )
+{
+ wxASSERT( aGridSizes.size() > 0 );
+
+ int select = wxNOT_FOUND;
+
+ for( size_t i = 0; i < aGridSizes.size(); i++ )
+ {
+ wxString tmp;
+ tmp.Printf( wxT( "%0.1f" ), aGridSizes[i].m_Size.x );
+ m_choiceGridSize->Append( tmp );
+
+ if( aGridSizes[i].m_CmdId == aGridId )
+ select = (int) i;
+ }
+
+ m_choiceGridSize->SetSelection( select );
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::RefreshTemplateFieldView( void )
+{
+ // Loop through the template fieldnames and add them to the list control
+ // or just change texts if room exists
+ long itemindex = 0;
+ wxString tmp;
+
+ for( TEMPLATE_FIELDNAMES::iterator fld = templateFields.begin();
+ fld != templateFields.end(); ++fld, itemindex++ )
+ {
+ if( templateFieldListCtrl->GetItemCount() <= itemindex )
+ {
+ templateFieldListCtrl->InsertItem(
+ templateFieldListCtrl->GetItemCount(), fld->m_Name );
+ }
+
+ wxListItem litem;
+ litem.SetId( itemindex );
+ templateFieldListCtrl->GetItem( litem );
+
+ litem.SetColumn( 0 );
+ if( litem.GetText() != fld->m_Name )
+ templateFieldListCtrl->SetItem( itemindex, 0, fld->m_Name );
+
+ litem.SetColumn( 1 );
+ if( litem.GetText() != fld->m_Value )
+ templateFieldListCtrl->SetItem( itemindex, 1, fld->m_Value );
+
+ tmp = ( fld->m_Visible == true ) ? _( "Visible" ) : _( "Hidden" );
+
+ litem.SetColumn( 2 );
+ if( litem.GetText() != tmp )
+ templateFieldListCtrl->SetItem( itemindex, 2, tmp );
+ }
+
+ // Remove extra items:
+ while( templateFieldListCtrl->GetItemCount() > itemindex )
+ {
+ templateFieldListCtrl->DeleteItem( itemindex );
+ }
+
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::SelectTemplateField( int aItem )
+{
+ // Only select valid items!
+ if( ( aItem < 0 ) || ( aItem >= templateFieldListCtrl->GetItemCount() ) )
+ return;
+
+ // Make sure we select the new item in list control
+ if( templateFieldListCtrl->GetFirstSelected() != aItem )
+ templateFieldListCtrl->Select( aItem, true );
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::OnAddButtonClick( wxCommandEvent& event )
+{
+ // If there is currently a valid selection, copy the edit panel to the
+ // selected field so as not to lose the data
+ if( fieldSelectionValid( selectedField ) )
+ copyPanelToSelected();
+
+ // Add a new fieldname to the fieldname list
+ TEMPLATE_FIELDNAME newFieldname = TEMPLATE_FIELDNAME( "Fieldname" );
+ newFieldname.m_Value = wxT( "Value" );
+ newFieldname.m_Visible = false;
+ templateFields.push_back( newFieldname );
+
+ // Select the newly added field and then copy that data to the edit panel.
+ // Make sure any previously selected state is cleared and then select the
+ // new field
+ selectedField = templateFields.size() - 1;
+
+ // Update the display to reflect the new data
+ RefreshTemplateFieldView();
+ copySelectedToPanel();
+
+ // Make sure we select the new item
+ SelectTemplateField( selectedField );
+
+ event.Skip();
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::OnDeleteButtonClick( wxCommandEvent& event )
+{
+ // If there is currently a valid selection, delete the template field from
+ // the template field list
+ if( fieldSelectionValid( selectedField ) )
+ {
+ // Delete the fieldname from the fieldname list
+ templateFields.erase( templateFields.begin() + selectedField );
+
+ // If the selectedField is still not in the templateField range now,
+ // make sure we stay in range and when there are no fields present
+ // move to -1
+ if( selectedField >= int( templateFields.size() ) )
+ selectedField = templateFields.size() - 1;
+
+ // Update the display to reflect the new data
+ RefreshTemplateFieldView();
+
+ copySelectedToPanel();
+
+ // Make sure after the refresh that the selected item is correct
+ SelectTemplateField( selectedField );
+ }
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::copyPanelToSelected( void )
+{
+ if( !fieldSelectionValid( selectedField ) )
+ return;
+
+ // Update the template field from the edit panel
+ templateFields[selectedField].m_Name = fieldNameTextCtrl->GetValue();
+ templateFields[selectedField].m_Value = fieldDefaultValueTextCtrl->GetValue();
+ templateFields[selectedField].m_Visible = fieldVisibleCheckbox->GetValue();
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::OnEditControlKillFocus( wxFocusEvent& event )
+{
+ // Update the data + UI
+ copyPanelToSelected();
+ RefreshTemplateFieldView();
+ SelectTemplateField( selectedField );
+
+ event.Skip();
+}
+
+void DIALOG_EESCHEMA_OPTIONS::OnEnterKey( wxCommandEvent& event )
+{
+ // Process the event produced when the user presses enter key
+ // in template fieldname text control or template fieldvalue text control
+ // Validate the current name or value, and switch focus to the other param
+ // (value or name)
+ copyPanelToSelected();
+ RefreshTemplateFieldView();
+
+ if( fieldNameTextCtrl->HasFocus() )
+ fieldDefaultValueTextCtrl->SetFocus();
+ else
+ fieldNameTextCtrl->SetFocus();
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::OnVisibleFieldClick( wxCommandEvent& event )
+{
+ // Process the event produced when the user click on
+ // the check box which controls the field visibility
+ copyPanelToSelected();
+ RefreshTemplateFieldView();
+}
+
+void DIALOG_EESCHEMA_OPTIONS::copySelectedToPanel( void )
+{
+ if( !fieldSelectionValid( selectedField ) )
+ return;
+
+ // Update the panel data from the selected template field
+ fieldNameTextCtrl->SetValue( templateFields[selectedField].m_Name );
+ fieldDefaultValueTextCtrl->SetValue( templateFields[selectedField].m_Value );
+ fieldVisibleCheckbox->SetValue( templateFields[selectedField].m_Visible );
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::OnTemplateFieldSelected( wxListEvent& event )
+{
+ // Before getting the new field data, make sure we save the old!
+ copyPanelToSelected();
+
+ // Now update the selected field and copy the data from the field to the
+ // edit panel
+ selectedField = event.GetIndex();
+ copySelectedToPanel();
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::SetTemplateFields( const TEMPLATE_FIELDNAMES& aFields )
+{
+ // Set the template fields object
+ templateFields = aFields;
+
+ // select the last field ( will set selectedField to -1 if no field ):
+ selectedField = templateFields.size()-1;
+
+ // Build and refresh the view
+ RefreshTemplateFieldView();
+
+ if( selectedField >= 0 )
+ {
+ copySelectedToPanel();
+ SelectTemplateField( selectedField );
+ }
+
+}
+
+
+TEMPLATE_FIELDNAMES DIALOG_EESCHEMA_OPTIONS::GetTemplateFields( void )
+{
+ return templateFields;
+}
+
diff --git a/eeschema/dialogs/dialog_eeschema_options.h b/eeschema/dialogs/dialog_eeschema_options.h
new file mode 100644
index 0000000..12446b9
--- /dev/null
+++ b/eeschema/dialogs/dialog_eeschema_options.h
@@ -0,0 +1,479 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_eeschema_options.h
+ *
+ * Subclass of DIALOG_EESCHEMA_OPTIONS_BASE, which is generated by wxFormBuilder.
+ */
+
+#ifndef __dialog_eeschema_options__
+#define __dialog_eeschema_options__
+
+#include <dialog_eeschema_options_base.h>
+#include <template_fieldnames.h>
+
+class DIALOG_EESCHEMA_OPTIONS : public DIALOG_EESCHEMA_OPTIONS_BASE
+{
+protected:
+ /** @brief The template fieldnames for this dialog */
+ TEMPLATE_FIELDNAMES templateFields;
+
+ /** @brief The current row selected in the template fieldname wxListCtrl which is also in the
+ * edit panel
+ * selectedField = -1 when no valid item selected
+ */
+ int selectedField;
+
+ /** @brief return true if aFieldId is a valid field selection
+ */
+ bool fieldSelectionValid( int aFieldId )
+ {
+ return ( aFieldId >= 0 ) && ( aFieldId < int( templateFields.size() ) );
+ }
+
+ /**
+ * Function OnEnterKey (virtual)
+ * Process the wxWidgets @a event produced when the user presses enter key
+ * in template fieldname text control or template fieldvalue text control
+ */
+ void OnEnterKey( wxCommandEvent& event );
+
+ /**
+ * Function OnVisibleFieldClick (virtual)
+ * Process the wxWidgets @a event produced when the user click on
+ * the check box which controls the field visibility
+ */
+ void OnVisibleFieldClick( wxCommandEvent& event );
+
+ /**
+ * Function OnAddButtonClick
+ * Process the wxWidgets @a event produced when the user presses the Add buton for the
+ * template fieldnames control
+ *
+ * @param event The wxWidgets produced event information
+ *
+ * Adds a new template fieldname (with default values) to the template fieldnames data
+ */
+ void OnAddButtonClick( wxCommandEvent& event );
+
+ /**
+ * Function OnDeleteButtonClick
+ * Process the wxWidgets @a event produced when the user presses the Delete button for the
+ * template fieldnames control
+ *
+ * @param event The wxWidgets produced event information
+ *
+ * Deletes the selected template fieldname from the template fieldnames data
+ */
+ void OnDeleteButtonClick( wxCommandEvent& event );
+
+ /**
+ * Function OnEditControlKillFocus
+ * This Focus Event Handler should be connected to any controls in the template field edit box
+ * so that any loss of focus results in the data being saved to the currently selected template
+ * field
+ *
+ * @param event The wxWidgets produced event information
+ *
+ * Copies data from the edit box to the selected field template
+ */
+ void OnEditControlKillFocus( wxFocusEvent& event );
+
+ /**
+ * Function copyPanelToSelected
+ * Copies the data from the edit panel to the selected template fieldname
+ */
+ void copyPanelToSelected( void );
+
+ /**
+ * Function copySelectedToPanel
+ * Copies the data from the selected template fieldname and fills in the edit panel
+ */
+ void copySelectedToPanel( void );
+
+ /**
+ * Function OnTemplateFieldSelected
+ * Event handler for the wxListCtrl containing the template fieldnames
+ *
+ * @param event The event information provided by wxWidgets
+ *
+ * Processes data exchange between the edit panel and the selected template fieldname
+ */
+ void OnTemplateFieldSelected( wxListEvent& event );
+
+ /**
+ * Function RefreshTemplateFieldView
+ * Refresh the template fieldname wxListCtrl
+ *
+ * Deletes all data from the wxListCtrl and then re-polpulates the control with the data in
+ * the template fieldnames.
+ *
+ * Use any time the template field data has changed
+ */
+ void RefreshTemplateFieldView( void );
+
+ /**
+ * Function SelectTemplateField
+ * Selects @a aItem from the wxListCtrl populated with the template fieldnames
+ *
+ * @param aItem The item index of the row to be selected
+ *
+ * When RefreshTemplateFieldView() is used the selection is lost because all of the items are
+ * removed from the wxListCtrl and then the control is re-populated. This function can be used
+ * to re-select an item that was previously selected so that the selection is not lost.
+ *
+ * <b>NOTE:</b> This function first sets the ignoreSelection flag before making the selection.
+ * This means the class can select something in the wxListCtrl without causing further
+ * selection events.
+ */
+ void SelectTemplateField( int aItem );
+
+public:
+ /**
+ * Public constructor
+ *
+ * @param parent The dialog's parent
+ */
+ DIALOG_EESCHEMA_OPTIONS( wxWindow* parent );
+
+ /**
+ * Function GetUnitsSelection
+ * Returns the currently selected grid size in the dialog
+ */
+ int GetUnitsSelection( void ) { return m_choiceUnits->GetSelection(); }
+
+ /**
+ * Function SetUnits
+ * Set the unit options
+ *
+ * @param units The array of strings representing the unit options
+ * @param select The unit to select from the unit options
+ *
+ * Appends the @a units options to the list of unit options and selects the @a aSelect option
+ */
+ void SetUnits( const wxArrayString& units, int aSelect = 0 );
+
+ /**
+ * Function GetGridSelection
+ * Returns the curent grid size selected in the dialog
+ */
+ int GetGridSelection( void ) { return m_choiceGridSize->GetSelection(); }
+
+ /**
+ * Function SetGridSizes
+ * Sets the available grid size choices @a aGridSizes and selectd the current option @a aGridId
+ *
+ * @param aGridSizes The grid sizes that are able to be chosen from
+ * @param aGridId The grid size to select from the grid size options
+ */
+ void SetGridSizes( const GRIDS& aGridSizes, int aGridId );
+
+ /**
+ * Function GetBusWidth
+ * Get the current bus width setting from the dialog
+ */
+ int GetBusWidth( void ) { return m_spinBusWidth->GetValue(); }
+
+ /**
+ * Function SetBusWidth
+ * Sets the bus width setting in the dialog
+ *
+ * @param aWidth The bus width to set the dialog edit spinbox with
+ */
+ void SetBusWidth( int aWidth ) { m_spinBusWidth->SetValue( aWidth ); }
+
+ /**
+ * Function SetLineWidth
+ * Sets the current LineWidth value in the dialog
+ * @param aWidth The line width to set in the dialog
+ */
+ void SetLineWidth( int aWidth ) { m_spinLineWidth->SetValue( aWidth ); }
+
+ /**
+ * Function GetLineWidth
+ * Returns the current LineWidth value from the dialog
+ */
+ int GetLineWidth( void ) { return m_spinLineWidth->GetValue(); }
+
+ /**
+ * Function SetTextSize
+ * Sets the current default TextSize value in the dialog
+ * @param text_size The text size to set in the dialog
+ */
+ void SetTextSize( int text_size ) { m_spinTextSize->SetValue( text_size ); }
+
+ /**
+ * Function GetTextSize
+ * Returns the current default TextSize value from the dialog
+ */
+ int GetTextSize( void ) { return m_spinTextSize->GetValue(); }
+
+ /**
+ * Function SetRepeatHorizontal
+ * Sets the current RepeatHorizontal displacement value in the dialog
+ * @param displacement The displacement to set in the dialog
+ */
+ void SetRepeatHorizontal( int displacement )
+ {
+ m_spinRepeatHorizontal->SetValue( displacement );
+ }
+
+ /**
+ * Function GetRepeatHorizontal
+ * Returns the current RepeatHorizontal displacement value from the dialog
+ */
+ int GetRepeatHorizontal( void ) { return m_spinRepeatHorizontal->GetValue(); }
+
+ /**
+ * Function SetRepeatVertical
+ * Sets the current RepeatVertical displacement value in the dialog
+ * @param displacement The displacement to set in the dialog
+ */
+ void SetRepeatVertical( int displacement ) { m_spinRepeatVertical->SetValue( displacement ); }
+
+ /**
+ * Function GetRepeatVertical
+ * Returns the current RepeatVertical displacement value from the dialog
+ */
+ int GetRepeatVertical( void ) { return m_spinRepeatVertical->GetValue(); }
+
+ /**
+ * Function SetRepeatLabel
+ * Sets the current RepeatLabel increment value in the dialog
+ * @param increment The increment to set in the dialog
+ */
+ void SetRepeatLabel( int increment ) { m_spinRepeatLabel->SetValue( increment ); }
+
+ /**
+ * Function GetRepeatLabel
+ * Returns the current RepeatLabel increment value from the dialog
+ */
+ int GetRepeatLabel( void ) { return m_spinRepeatLabel->GetValue(); }
+
+ /**
+ * Function SetAutoSaveInterval
+ * Sets the current AutoSaveInterval value in the dialog
+ * @param aInterval The interval to set in the dialog
+ */
+ void SetAutoSaveInterval( int aInterval ) { m_spinAutoSaveInterval->SetValue( aInterval ); }
+
+ /**
+ * Function GetAutoSaveInterval
+ * Returns the current AutoSaveInterval value from the dialog
+ */
+ int GetAutoSaveInterval() const { return m_spinAutoSaveInterval->GetValue(); }
+
+ /**
+ * Function SetMaxUndoItems
+ * Sets the maximum number of undo items
+ * @param aItems the number to set
+ */
+ void SetMaxUndoItems( int aItems ) { m_spinMaxUndoItems->SetValue( aItems ); }
+
+ /**
+ * Function GetMaxUndoItems
+ * Return the current maximum number of undo items
+ */
+ int GetMaxUndoItems() const { return m_spinMaxUndoItems->GetValue(); }
+
+ /**
+ * Function SetRefIdSeparator
+ * Sets the current RefIdSeparator value in the dialog
+ * @param aSep The seperator to use between the reference and the part ID
+ * @param aFirstId The first part ID, currently either 'A' or '1'
+ */
+ void SetRefIdSeparator( wxChar aSep, wxChar aFirstId);
+
+ /**
+ * Function GetRefIdSeparator
+ * Returns the current RefIdSeparator value from the dialog
+ * @param aSep The OUTPUT seperator value
+ * @param aFirstId The OUTPUT reference first ID
+ */
+ void GetRefIdSeparator( int& aSep, int& aFirstId);
+
+ /**
+ * Function SetShowGrid
+ * Sets the current ShowGrid value in the dialog
+ * @param show The ShowGrid value to set in the dialog
+ */
+ void SetShowGrid( bool show ) { m_checkShowGrid->SetValue( show ); }
+
+ /**
+ * Function GetShowGrid
+ * Returns the current ShowGrid value from the dialog
+ */
+ bool GetShowGrid( void ) { return m_checkShowGrid->GetValue(); }
+
+ /**
+ * Function SetShowHiddenPins
+ * Sets the current ShowHiddenPins value in the dialog
+ * @param show The ShowHiddenPins value to set in the dialog
+ */
+ void SetShowHiddenPins( bool show ) { m_checkShowHiddenPins->SetValue( show ); }
+
+ /**
+ * Function GetShowHiddenPins
+ * Returns the current ShowHiddenPins value from the dialog
+ */
+ bool GetShowHiddenPins( void ) { return m_checkShowHiddenPins->GetValue(); }
+
+ /**
+ * Function SetEnableZoomNoCenter
+ * Sets the current ZoomNoCenter value in the dialog
+ * @param enable The ZoomNoCenter value to set in the dialog
+ */
+ void SetEnableZoomNoCenter( bool enable )
+ {
+ m_checkEnableZoomCenter->SetValue( !enable );
+ }
+
+ /**
+ * Function GetEnableZoomNoCenter
+ * Returns the current ZoomNoCenter value from the dialog
+ */
+ bool GetEnableZoomNoCenter( void )
+ {
+ return !m_checkEnableZoomCenter->GetValue();
+ }
+
+ /**
+ * Function SetEnableMiddleButtonPan
+ * Sets the current MiddleButtonPan value in the dialog
+ *
+ * @param enable The boolean value to set the MiddleButtonPan value in the dialog
+ */
+ void SetEnableMiddleButtonPan( bool enable )
+ {
+ m_checkEnableMiddleButtonPan->SetValue( enable );
+ m_checkMiddleButtonPanLimited->Enable( enable );
+ }
+
+ /**
+ * Function GetEnableMiddleButtonPan
+ * Returns the current MiddleButtonPan setting from the dialog
+ */
+ bool GetEnableMiddleButtonPan( void )
+ {
+ return m_checkEnableMiddleButtonPan->GetValue();
+ }
+
+ /**
+ * Function SetMiddleButtonPanLimited
+ * Sets the MiddleButtonPanLimited value in the dialog
+ *
+ * @param enable The boolean value to set the MiddleButtonPanLimted value in the dialog
+ */
+ void SetMiddleButtonPanLimited( bool enable )
+ {
+ m_checkMiddleButtonPanLimited->SetValue( enable );
+ }
+
+ /**
+ * Function GetMiddleButtonPanLimited
+ * Returns the MiddleButtonPanLimited setting from the dialog
+ */
+ bool GetMiddleButtonPanLimited( void )
+ {
+ return m_checkMiddleButtonPanLimited->GetValue();
+ }
+
+ /**
+ * Function SetEnableMousewheelPan
+ * Sets the MousewheelPan setting in the dialog
+ *
+ * @param enable The boolean value to set the AutoPan value in the dialog
+ */
+ void SetEnableMousewheelPan( bool enable ) { m_checkEnableMousewheelPan->SetValue( enable ); }
+
+ /**
+ * Function GetEnableMousewheelPan
+ * Return the MousewheelPan setting from the dialog
+ */
+ bool GetEnableMousewheelPan( void ) { return m_checkEnableMousewheelPan->GetValue(); }
+
+ /**
+ * Function SetEnableAutoPan
+ * Sets the AutoPan setting in the dialog
+ *
+ * @param enable The boolean value to set the AutoPan value in the dialog
+ */
+ void SetEnableAutoPan( bool enable ) { m_checkAutoPan->SetValue( enable ); }
+
+ /**
+ * Function GetEnableAutoPan
+ * Return the AutoPan setting from the dialog
+ */
+ bool GetEnableAutoPan( void ) { return m_checkAutoPan->GetValue(); }
+
+ /**
+ * Function SetEnableHVBusOrientation
+ * Set the HVBusOrientation setting in the dialog
+ *
+ * @param enable The boolean value to set the HVBusOrientation value in the dialog
+ */
+ void SetEnableHVBusOrientation( bool enable ) { m_checkHVOrientation->SetValue( enable ); }
+
+ /**
+ * Function GetEnableHVBusOrientation
+ * Get the HVBusOrientation setting from the dialog
+ */
+ bool GetEnableHVBusOrientation( void ) { return m_checkHVOrientation->GetValue(); }
+
+ /**
+ * Function
+ * Set the ShowPageLimits setting in the dialog
+ */
+ void SetShowPageLimits( bool show ) { m_checkPageLimits->SetValue( show ); }
+
+ /**
+ * Function
+ * Return the current ShowPageLimits setting from the dialog
+ */
+ bool GetShowPageLimits( void ) { return m_checkPageLimits->GetValue(); }
+
+ /**
+ * Function SetTemplateFields
+ * Set the template field data in the dialog
+ *
+ * @param aFields The template fieldnames that the dialog should start with before any editing
+ */
+ void SetTemplateFields( const TEMPLATE_FIELDNAMES& aFields );
+
+ /**
+ * Function GetTemplateFields
+ * Get the dialog's template field data
+ *
+ */
+ TEMPLATE_FIELDNAMES GetTemplateFields( void );
+
+private:
+ void OnMiddleBtnPanEnbl( wxCommandEvent& event )
+ {
+ m_checkMiddleButtonPanLimited->Enable( GetEnableMiddleButtonPan() );
+ }
+};
+
+#endif // __dialog_eeschema_options__
diff --git a/eeschema/dialogs/dialog_eeschema_options_base.cpp b/eeschema/dialogs/dialog_eeschema_options_base.cpp
new file mode 100644
index 0000000..ee48fbd
--- /dev/null
+++ b/eeschema/dialogs/dialog_eeschema_options_base.cpp
@@ -0,0 +1,303 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 21 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_eeschema_options_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+BEGIN_EVENT_TABLE( DIALOG_EESCHEMA_OPTIONS_BASE, DIALOG_SHIM )
+ EVT_SIZE( DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnSize )
+ EVT_CHOICE( wxID_ANY, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnChooseUnits )
+ EVT_CHECKBOX( xwID_ANY, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnMiddleBtnPanEnbl )
+ EVT_LIST_ITEM_DESELECTED( wxID_ANY, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnTemplateFieldDeselected )
+ EVT_LIST_ITEM_SELECTED( wxID_ANY, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnTemplateFieldSelected )
+ EVT_TEXT_ENTER( wxID_ANY, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnEnterKey )
+ EVT_TEXT_ENTER( wxID_ANY, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnEnterKey )
+ EVT_CHECKBOX( wxID_ANY, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnVisibleFieldClick )
+ EVT_BUTTON( wxID_ADD_FIELD, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnAddButtonClick )
+ EVT_BUTTON( wxID_DELETE_FIELD, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnDeleteButtonClick )
+END_EVENT_TABLE()
+
+DIALOG_EESCHEMA_OPTIONS_BASE::DIALOG_EESCHEMA_OPTIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* mainSizer;
+ mainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bOptionsSizer;
+ bOptionsSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_notebook->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
+
+ m_panel1 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* p1mainSizer;
+ p1mainSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizer3;
+ bSizer3 = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 0, 3, 0, 0 );
+ fgSizer1->AddGrowableCol( 0 );
+ fgSizer1->AddGrowableCol( 1 );
+ fgSizer1->AddGrowableCol( 2 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText2 = new wxStaticText( m_panel1, wxID_ANY, _("&Measurement units:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText2->Wrap( -1 );
+ fgSizer1->Add( m_staticText2, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ wxArrayString m_choiceUnitsChoices;
+ m_choiceUnits = new wxChoice( m_panel1, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceUnitsChoices, 0 );
+ m_choiceUnits->SetSelection( 0 );
+ fgSizer1->Add( m_choiceUnits, 0, wxALL|wxEXPAND, 3 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxEXPAND, 3 );
+
+ m_staticText3 = new wxStaticText( m_panel1, wxID_ANY, _("&Grid size:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ fgSizer1->Add( m_staticText3, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ wxArrayString m_choiceGridSizeChoices;
+ m_choiceGridSize = new wxChoice( m_panel1, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceGridSizeChoices, 0 );
+ m_choiceGridSize->SetSelection( 0 );
+ fgSizer1->Add( m_choiceGridSize, 0, wxEXPAND|wxALL, 3 );
+
+ m_staticGridUnits = new wxStaticText( m_panel1, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticGridUnits->Wrap( -1 );
+ fgSizer1->Add( m_staticGridUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_staticText51 = new wxStaticText( m_panel1, wxID_ANY, _("&Default bus thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText51->Wrap( -1 );
+ fgSizer1->Add( m_staticText51, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_spinBusWidth = new wxSpinCtrl( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, 1, 100, 1 );
+ fgSizer1->Add( m_spinBusWidth, 0, wxALL|wxEXPAND, 3 );
+
+ m_staticBusWidthUnits = new wxStaticText( m_panel1, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticBusWidthUnits->Wrap( -1 );
+ fgSizer1->Add( m_staticBusWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_staticText5 = new wxStaticText( m_panel1, wxID_ANY, _("D&efault line thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText5->Wrap( -1 );
+ fgSizer1->Add( m_staticText5, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_spinLineWidth = new wxSpinCtrl( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, 1, 100, 1 );
+ fgSizer1->Add( m_spinLineWidth, 0, wxALL|wxEXPAND, 3 );
+
+ m_staticLineWidthUnits = new wxStaticText( m_panel1, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticLineWidthUnits->Wrap( -1 );
+ fgSizer1->Add( m_staticLineWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_staticText7 = new wxStaticText( m_panel1, wxID_ANY, _("De&fault text size:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText7->Wrap( -1 );
+ fgSizer1->Add( m_staticText7, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_spinTextSize = new wxSpinCtrl( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, 0, 1000, 0 );
+ fgSizer1->Add( m_spinTextSize, 0, wxALL|wxEXPAND, 3 );
+
+ m_staticTextSizeUnits = new wxStaticText( m_panel1, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSizeUnits->Wrap( -1 );
+ fgSizer1->Add( m_staticTextSizeUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_staticText9 = new wxStaticText( m_panel1, wxID_ANY, _("&Horizontal pitch of repeated items:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText9->Wrap( -1 );
+ fgSizer1->Add( m_staticText9, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_spinRepeatHorizontal = new wxSpinCtrl( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, -5000, 5000, 0 );
+ fgSizer1->Add( m_spinRepeatHorizontal, 0, wxALL|wxEXPAND, 3 );
+
+ m_staticRepeatXUnits = new wxStaticText( m_panel1, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticRepeatXUnits->Wrap( -1 );
+ fgSizer1->Add( m_staticRepeatXUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_staticText12 = new wxStaticText( m_panel1, wxID_ANY, _("&Vertical pitch of repeated items:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText12->Wrap( -1 );
+ fgSizer1->Add( m_staticText12, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_spinRepeatVertical = new wxSpinCtrl( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, -5000, 5000, 100 );
+ fgSizer1->Add( m_spinRepeatVertical, 0, wxALL|wxEXPAND, 3 );
+
+ m_staticRepeatYUnits = new wxStaticText( m_panel1, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticRepeatYUnits->Wrap( -1 );
+ fgSizer1->Add( m_staticRepeatYUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_staticText16 = new wxStaticText( m_panel1, wxID_ANY, _("&Increment of repeated labels:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText16->Wrap( -1 );
+ fgSizer1->Add( m_staticText16, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_spinRepeatLabel = new wxSpinCtrl( m_panel1, wxID_ANY, wxT("1"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, -10, 10, 1 );
+ fgSizer1->Add( m_spinRepeatLabel, 0, wxALL|wxEXPAND, 3 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxEXPAND, 3 );
+
+ m_staticText221 = new wxStaticText( m_panel1, wxID_ANY, _("&Auto-save time interval"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText221->Wrap( -1 );
+ fgSizer1->Add( m_staticText221, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_spinAutoSaveInterval = new wxSpinCtrl( m_panel1, ID_M_SPINAUTOSAVEINTERVAL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 1000, 10 );
+ fgSizer1->Add( m_spinAutoSaveInterval, 0, wxALL|wxEXPAND, 3 );
+
+ m_staticText23 = new wxStaticText( m_panel1, wxID_ANY, _("minutes"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText23->Wrap( -1 );
+ fgSizer1->Add( m_staticText23, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_stMaxUndoItems = new wxStaticText( m_panel1, wxID_ANY, _("Ma&ximum undo items (0 = unlimited):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_stMaxUndoItems->Wrap( -1 );
+ fgSizer1->Add( m_stMaxUndoItems, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_spinMaxUndoItems = new wxSpinCtrl( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 65536, 0 );
+ fgSizer1->Add( m_spinMaxUndoItems, 0, wxALL|wxEXPAND, 3 );
+
+ m_stMaxUndoItemsUnit = new wxStaticText( m_panel1, wxID_ANY, _("actions"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_stMaxUndoItemsUnit->Wrap( -1 );
+ fgSizer1->Add( m_stMaxUndoItemsUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_staticText26 = new wxStaticText( m_panel1, wxID_ANY, _("&Part id notation:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText26->Wrap( -1 );
+ fgSizer1->Add( m_staticText26, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 3 );
+
+ wxString m_choiceSeparatorRefIdChoices[] = { _("A"), _(".A"), _("-A"), _("_A"), _(".1"), _("-1"), _("_1") };
+ int m_choiceSeparatorRefIdNChoices = sizeof( m_choiceSeparatorRefIdChoices ) / sizeof( wxString );
+ m_choiceSeparatorRefId = new wxChoice( m_panel1, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceSeparatorRefIdNChoices, m_choiceSeparatorRefIdChoices, 0 );
+ m_choiceSeparatorRefId->SetSelection( 0 );
+ fgSizer1->Add( m_choiceSeparatorRefId, 0, wxALL|wxEXPAND, 3 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ bSizer3->Add( fgSizer1, 0, wxEXPAND, 0 );
+
+ wxBoxSizer* bSizer2;
+ bSizer2 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticline1 = new wxStaticLine( m_panel1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizer2->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_checkShowGrid = new wxCheckBox( m_panel1, wxID_ANY, _("&Show grid"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer2->Add( m_checkShowGrid, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 3 );
+
+ m_checkShowHiddenPins = new wxCheckBox( m_panel1, wxID_ANY, _("Sho&w hidden pins"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer2->Add( m_checkShowHiddenPins, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 3 );
+
+ m_checkEnableZoomCenter = new wxCheckBox( m_panel1, wxID_ANY, _("Ce&nter and warp cursor on zoom"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkEnableZoomCenter->SetToolTip( _("Keep the cursor at its current location when zooming") );
+
+ bSizer2->Add( m_checkEnableZoomCenter, 0, wxTOP|wxRIGHT|wxLEFT, 3 );
+
+ m_checkEnableMiddleButtonPan = new wxCheckBox( m_panel1, xwID_ANY, _("&Use middle mouse button to pan"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkEnableMiddleButtonPan->SetToolTip( _("Use middle mouse button dragging to pan") );
+
+ bSizer2->Add( m_checkEnableMiddleButtonPan, 0, wxTOP|wxRIGHT|wxLEFT, 3 );
+
+ m_checkMiddleButtonPanLimited = new wxCheckBox( m_panel1, wxID_ANY, _("&Limit panning to scroll size"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkMiddleButtonPanLimited->SetToolTip( _("Middle mouse button panning limited by current scrollbar size") );
+
+ bSizer2->Add( m_checkMiddleButtonPanLimited, 0, wxTOP|wxRIGHT|wxLEFT, 3 );
+
+ m_checkEnableMousewheelPan = new wxCheckBox( m_panel1, xwID_ANY, _("Use touchpa&d to pan"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkEnableMousewheelPan->SetToolTip( _("Use touchpad to pan canvas") );
+
+ bSizer2->Add( m_checkEnableMousewheelPan, 0, wxLEFT|wxRIGHT|wxTOP, 3 );
+
+ m_checkAutoPan = new wxCheckBox( m_panel1, wxID_ANY, _("Pan while moving ob&ject"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer2->Add( m_checkAutoPan, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 3 );
+
+ m_checkHVOrientation = new wxCheckBox( m_panel1, wxID_ANY, _("&Restrict buses and wires to H and V orientation"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer2->Add( m_checkHVOrientation, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 3 );
+
+ m_checkPageLimits = new wxCheckBox( m_panel1, wxID_ANY, _("Show page limi&ts"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer2->Add( m_checkPageLimits, 0, wxALL|wxEXPAND, 3 );
+
+
+ bSizer3->Add( bSizer2, 0, wxEXPAND, 0 );
+
+
+ p1mainSizer->Add( bSizer3, 1, wxALL|wxEXPAND, 6 );
+
+
+ m_panel1->SetSizer( p1mainSizer );
+ m_panel1->Layout();
+ p1mainSizer->Fit( m_panel1 );
+ m_notebook->AddPage( m_panel1, _("General Options"), true );
+ m_panel2 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_panel2->SetToolTip( _("User defined field names for schematic components. ") );
+
+ wxBoxSizer* bSizer6;
+ bSizer6 = new wxBoxSizer( wxVERTICAL );
+
+ templateFieldListCtrl = new wxListView( m_panel2, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES );
+ templateFieldListCtrl->SetMinSize( wxSize( 500,-1 ) );
+
+ bSizer6->Add( templateFieldListCtrl, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 8 );
+
+ wxStaticBoxSizer* fieldSizer;
+ fieldSizer = new wxStaticBoxSizer( new wxStaticBox( m_panel2, wxID_ANY, _("Field Settings") ), wxVERTICAL );
+
+ fieldNameLabel = new wxStaticText( fieldSizer->GetStaticBox(), wxID_ANY, _("&Name"), wxDefaultPosition, wxDefaultSize, 0 );
+ fieldNameLabel->Wrap( -1 );
+ fieldSizer->Add( fieldNameLabel, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ fieldNameTextCtrl = new wxTextCtrl( fieldSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
+ fieldSizer->Add( fieldNameTextCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ fieldDefaultValueLabel = new wxStaticText( fieldSizer->GetStaticBox(), wxID_ANY, _("D&efault Value"), wxDefaultPosition, wxDefaultSize, 0 );
+ fieldDefaultValueLabel->Wrap( -1 );
+ fieldSizer->Add( fieldDefaultValueLabel, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ fieldDefaultValueTextCtrl = new wxTextCtrl( fieldSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
+ fieldSizer->Add( fieldDefaultValueTextCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ fieldVisibleCheckbox = new wxCheckBox( fieldSizer->GetStaticBox(), wxID_ANY, _("&Visible"), wxDefaultPosition, wxDefaultSize, 0 );
+ fieldSizer->Add( fieldVisibleCheckbox, 0, wxALL, 5 );
+
+
+ bSizer6->Add( fieldSizer, 0, wxEXPAND, 5 );
+
+ addFieldButton = new wxButton( m_panel2, wxID_ADD_FIELD, _("&Add"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer6->Add( addFieldButton, 0, wxALL|wxEXPAND, 5 );
+
+ deleteFieldButton = new wxButton( m_panel2, wxID_DELETE_FIELD, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer6->Add( deleteFieldButton, 0, wxALL|wxEXPAND, 5 );
+
+
+ m_panel2->SetSizer( bSizer6 );
+ m_panel2->Layout();
+ bSizer6->Fit( m_panel2 );
+ m_notebook->AddPage( m_panel2, _("Template Field Names"), false );
+
+ bOptionsSizer->Add( m_notebook, 1, wxALL|wxEXPAND, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bOptionsSizer->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 6 );
+
+
+ mainSizer->Add( bOptionsSizer, 1, wxEXPAND, 12 );
+
+
+ this->SetSizer( mainSizer );
+ this->Layout();
+ mainSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_EESCHEMA_OPTIONS_BASE::~DIALOG_EESCHEMA_OPTIONS_BASE()
+{
+}
diff --git a/eeschema/dialogs/dialog_eeschema_options_base.fbp b/eeschema/dialogs/dialog_eeschema_options_base.fbp
new file mode 100644
index 0000000..ed3cb31
--- /dev/null
+++ b/eeschema/dialogs/dialog_eeschema_options_base.fbp
@@ -0,0 +1,4612 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">table</property>
+ <property name="file">dialog_eeschema_options_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_eeschema_options</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_EESCHEMA_OPTIONS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Schematic Editor Options</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize">OnSize</event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">mainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">12</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bOptionsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxNotebook" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">wxSYS_COLOUR_BTNFACE</property>
+ <property name="bitmapsize"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_notebook</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnNotebookPageChanged"></event>
+ <event name="OnNotebookPageChanging"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">General Options</property>
+ <property name="select">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_panel1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">p1mainSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer3</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">0</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">0,1,2</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Measurement units:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">OnChooseUnits</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="0">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Grid size:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceGridSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticGridUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Default bus thickness:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText51</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">1</property>
+ <property name="max">100</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinBusWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS|wxSP_WRAP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticBusWidthUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">D&amp;efault line thickness:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">1</property>
+ <property name="max">100</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinLineWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS|wxSP_WRAP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticLineWidthUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">De&amp;fault text size:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText7</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">0</property>
+ <property name="max">1000</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinTextSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS|wxSP_WRAP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSizeUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Horizontal pitch of repeated items:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText9</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">0</property>
+ <property name="max">5000</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">-5000</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinRepeatHorizontal</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS|wxSP_WRAP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticRepeatXUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Vertical pitch of repeated items:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText12</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">100</property>
+ <property name="max">5000</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">-5000</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinRepeatVertical</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS|wxSP_WRAP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticRepeatYUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Fixed</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Increment of repeated labels:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText16</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">1</property>
+ <property name="max">10</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">-10</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinRepeatLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS|wxSP_WRAP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value">1</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="0">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Auto-save time interval</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText221</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_SPINAUTOSAVEINTERVAL</property>
+ <property name="initial">10</property>
+ <property name="max">1000</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinAutoSaveInterval</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">minutes</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText23</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Ma&amp;ximum undo items (0 = unlimited):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_stMaxUndoItems</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">0</property>
+ <property name="max">65536</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinMaxUndoItems</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">actions</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_stMaxUndoItemsUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Part id notation:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText26</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;A&quot; &quot;.A&quot; &quot;-A&quot; &quot;_A&quot; &quot;.1&quot; &quot;-1&quot; &quot;_1&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceSeparatorRefId</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="0">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">0</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer2</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Show grid</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkShowGrid</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Sho&amp;w hidden pins</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkShowHiddenPins</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Ce&amp;nter and warp cursor on zoom</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkEnableZoomCenter</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Keep the cursor at its current location when zooming</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">xwID_ANY</property>
+ <property name="label">&amp;Use middle mouse button to pan</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkEnableMiddleButtonPan</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Use middle mouse button dragging to pan</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnMiddleBtnPanEnbl</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Limit panning to scroll size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkMiddleButtonPanLimited</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Middle mouse button panning limited by current scrollbar size</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">xwID_ANY</property>
+ <property name="label">Use touchpa&amp;d to pan</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkEnableMousewheelPan</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Use touchpad to pan canvas</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pan while moving ob&amp;ject</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkAutoPan</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Restrict buses and wires to H and V orientation</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkHVOrientation</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show page limi&amp;ts</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkPageLimits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Template Field Names</property>
+ <property name="select">0</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_panel2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">User defined field names for schematic components. </property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer6</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">8</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxListCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">500,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">templateFieldListCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES</property>
+ <property name="subclass">wxListView; </property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBeginDrag"></event>
+ <event name="OnListBeginLabelEdit"></event>
+ <event name="OnListBeginRDrag"></event>
+ <event name="OnListCacheHint"></event>
+ <event name="OnListColBeginDrag"></event>
+ <event name="OnListColClick"></event>
+ <event name="OnListColDragging"></event>
+ <event name="OnListColEndDrag"></event>
+ <event name="OnListColRightClick"></event>
+ <event name="OnListDeleteAllItems"></event>
+ <event name="OnListDeleteItem"></event>
+ <event name="OnListEndLabelEdit"></event>
+ <event name="OnListInsertItem"></event>
+ <event name="OnListItemActivated"></event>
+ <event name="OnListItemDeselected">OnTemplateFieldDeselected</event>
+ <event name="OnListItemFocused"></event>
+ <event name="OnListItemMiddleClick"></event>
+ <event name="OnListItemRightClick"></event>
+ <event name="OnListItemSelected">OnTemplateFieldSelected</event>
+ <event name="OnListKeyDown"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Field Settings</property>
+ <property name="minimum_size"></property>
+ <property name="name">fieldSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Name</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldNameLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldNameTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_PROCESS_ENTER</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnEnterKey</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">D&amp;efault Value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldDefaultValueLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldDefaultValueTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_PROCESS_ENTER</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnEnterKey</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Visible</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">fieldVisibleCheckbox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnVisibleFieldClick</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ADD_FIELD</property>
+ <property name="label">&amp;Add</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">addFieldButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnAddButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_DELETE_FIELD</property>
+ <property name="label">&amp;Delete</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">deleteFieldButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnDeleteButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="0">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_eeschema_options_base.h b/eeschema/dialogs/dialog_eeschema_options_base.h
new file mode 100644
index 0000000..911a747
--- /dev/null
+++ b/eeschema/dialogs/dialog_eeschema_options_base.h
@@ -0,0 +1,145 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 21 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_EESCHEMA_OPTIONS_BASE_H__
+#define __DIALOG_EESCHEMA_OPTIONS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class wxListView;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/choice.h>
+#include <wx/spinctrl.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/checkbox.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/listctrl.h>
+#include <wx/textctrl.h>
+#include <wx/statbox.h>
+#include <wx/button.h>
+#include <wx/notebook.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_EESCHEMA_OPTIONS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_EESCHEMA_OPTIONS_BASE : public DIALOG_SHIM
+{
+ DECLARE_EVENT_TABLE()
+ private:
+
+ // Private event handlers
+ void _wxFB_OnSize( wxSizeEvent& event ){ OnSize( event ); }
+ void _wxFB_OnChooseUnits( wxCommandEvent& event ){ OnChooseUnits( event ); }
+ void _wxFB_OnMiddleBtnPanEnbl( wxCommandEvent& event ){ OnMiddleBtnPanEnbl( event ); }
+ void _wxFB_OnTemplateFieldDeselected( wxListEvent& event ){ OnTemplateFieldDeselected( event ); }
+ void _wxFB_OnTemplateFieldSelected( wxListEvent& event ){ OnTemplateFieldSelected( event ); }
+ void _wxFB_OnEnterKey( wxCommandEvent& event ){ OnEnterKey( event ); }
+ void _wxFB_OnVisibleFieldClick( wxCommandEvent& event ){ OnVisibleFieldClick( event ); }
+ void _wxFB_OnAddButtonClick( wxCommandEvent& event ){ OnAddButtonClick( event ); }
+ void _wxFB_OnDeleteButtonClick( wxCommandEvent& event ){ OnDeleteButtonClick( event ); }
+
+
+ protected:
+ enum
+ {
+ ID_M_SPINAUTOSAVEINTERVAL = 1000,
+ xwID_ANY,
+ wxID_ADD_FIELD,
+ wxID_DELETE_FIELD
+ };
+
+ wxNotebook* m_notebook;
+ wxPanel* m_panel1;
+ wxStaticText* m_staticText2;
+ wxChoice* m_choiceUnits;
+ wxStaticText* m_staticText3;
+ wxChoice* m_choiceGridSize;
+ wxStaticText* m_staticGridUnits;
+ wxStaticText* m_staticText51;
+ wxSpinCtrl* m_spinBusWidth;
+ wxStaticText* m_staticBusWidthUnits;
+ wxStaticText* m_staticText5;
+ wxSpinCtrl* m_spinLineWidth;
+ wxStaticText* m_staticLineWidthUnits;
+ wxStaticText* m_staticText7;
+ wxSpinCtrl* m_spinTextSize;
+ wxStaticText* m_staticTextSizeUnits;
+ wxStaticText* m_staticText9;
+ wxSpinCtrl* m_spinRepeatHorizontal;
+ wxStaticText* m_staticRepeatXUnits;
+ wxStaticText* m_staticText12;
+ wxSpinCtrl* m_spinRepeatVertical;
+ wxStaticText* m_staticRepeatYUnits;
+ wxStaticText* m_staticText16;
+ wxSpinCtrl* m_spinRepeatLabel;
+ wxStaticText* m_staticText221;
+ wxSpinCtrl* m_spinAutoSaveInterval;
+ wxStaticText* m_staticText23;
+ wxStaticText* m_stMaxUndoItems;
+ wxSpinCtrl* m_spinMaxUndoItems;
+ wxStaticText* m_stMaxUndoItemsUnit;
+ wxStaticText* m_staticText26;
+ wxChoice* m_choiceSeparatorRefId;
+ wxStaticLine* m_staticline1;
+ wxCheckBox* m_checkShowGrid;
+ wxCheckBox* m_checkShowHiddenPins;
+ wxCheckBox* m_checkEnableZoomCenter;
+ wxCheckBox* m_checkEnableMiddleButtonPan;
+ wxCheckBox* m_checkMiddleButtonPanLimited;
+ wxCheckBox* m_checkEnableMousewheelPan;
+ wxCheckBox* m_checkAutoPan;
+ wxCheckBox* m_checkHVOrientation;
+ wxCheckBox* m_checkPageLimits;
+ wxPanel* m_panel2;
+ wxListView* templateFieldListCtrl;
+ wxStaticText* fieldNameLabel;
+ wxTextCtrl* fieldNameTextCtrl;
+ wxStaticText* fieldDefaultValueLabel;
+ wxTextCtrl* fieldDefaultValueTextCtrl;
+ wxCheckBox* fieldVisibleCheckbox;
+ wxButton* addFieldButton;
+ wxButton* deleteFieldButton;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnSize( wxSizeEvent& event ) { event.Skip(); }
+ virtual void OnChooseUnits( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnMiddleBtnPanEnbl( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnTemplateFieldDeselected( wxListEvent& event ) { event.Skip(); }
+ virtual void OnTemplateFieldSelected( wxListEvent& event ) { event.Skip(); }
+ virtual void OnEnterKey( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnVisibleFieldClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnAddButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnDeleteButtonClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_EESCHEMA_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Schematic Editor Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_EESCHEMA_OPTIONS_BASE();
+
+};
+
+#endif //__DIALOG_EESCHEMA_OPTIONS_BASE_H__
diff --git a/eeschema/dialogs/dialog_erc.cpp b/eeschema/dialogs/dialog_erc.cpp
new file mode 100644
index 0000000..f1f28c0
--- /dev/null
+++ b/eeschema/dialogs/dialog_erc.cpp
@@ -0,0 +1,579 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_erc.cpp
+ * @brief Electrical Rules Check dialog implementation.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <pgm_base.h>
+#include <class_sch_screen.h>
+#include <schframe.h>
+#include <invoke_sch_dialog.h>
+#include <project.h>
+
+#include <netlist.h>
+#include <class_netlist_object.h>
+#include <sch_marker.h>
+#include <sch_sheet.h>
+#include <lib_pin.h>
+
+#include <dialog_erc.h>
+#include <erc.h>
+#include <id.h>
+
+
+bool DIALOG_ERC::m_writeErcFile = false;
+
+
+BEGIN_EVENT_TABLE( DIALOG_ERC, DIALOG_ERC_BASE )
+ EVT_COMMAND_RANGE( ID_MATRIX_0, ID_MATRIX_0 + ( PIN_NMAX * PIN_NMAX ) - 1,
+ wxEVT_COMMAND_BUTTON_CLICKED, DIALOG_ERC::ChangeErrorLevel )
+END_EVENT_TABLE()
+
+
+DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
+ DIALOG_ERC_BASE( parent, ID_DIALOG_ERC // parent looks for this ID explicitly
+ )
+{
+ m_parent = parent;
+ m_lastMarkerFound = NULL;
+ Init();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+DIALOG_ERC::~DIALOG_ERC()
+{
+}
+
+
+void DIALOG_ERC::Init()
+{
+ m_initialized = false;
+
+ for( int ii = 0; ii < PIN_NMAX; ii++ )
+ {
+ for( int jj = 0; jj < PIN_NMAX; jj++ )
+ m_buttonList[ii][jj] = NULL;
+ }
+
+ m_WriteResultOpt->SetValue( m_writeErcFile );
+
+ SCH_SCREENS screens;
+ updateMarkerCounts( &screens );
+
+ DisplayERC_MarkersList();
+
+ // Init Panel Matrix
+ ReBuildMatrixPanel();
+
+ // Set the run ERC button as the default button.
+ m_buttonERC->SetDefault();
+}
+
+
+void DIALOG_ERC::updateMarkerCounts( SCH_SCREENS *screens )
+{
+ int markers = screens->GetMarkerCount( MARKER_BASE::MARKER_ERC,
+ MARKER_BASE::MARKER_SEVERITY_UNSPEC );
+ int warnings = screens->GetMarkerCount( MARKER_BASE::MARKER_ERC,
+ MARKER_BASE::MARKER_SEVERITY_WARNING );
+ int errors = screens->GetMarkerCount( MARKER_BASE::MARKER_ERC,
+ MARKER_BASE::MARKER_SEVERITY_ERROR );
+
+ wxString num;
+ num.Printf( wxT( "%d" ), markers );
+ m_TotalErrCount->SetValue( num );
+
+ num.Printf( wxT( "%d" ), errors );
+ m_LastErrCount->SetValue( num );
+
+ num.Printf( wxT( "%d" ), warnings );
+ m_LastWarningCount->SetValue( num );
+}
+
+
+/* Delete the old ERC markers, over the whole hierarchy
+ */
+void DIALOG_ERC::OnEraseDrcMarkersClick( wxCommandEvent& event )
+{
+ SCH_SCREENS ScreenList;
+
+ ScreenList.DeleteAllMarkers( MARKER_BASE::MARKER_ERC );
+ updateMarkerCounts( &ScreenList );
+
+ m_MarkersList->ClearList();
+ m_parent->GetCanvas()->Refresh();
+}
+
+
+
+/* event handler for Close button
+*/
+void DIALOG_ERC::OnButtonCloseClick( wxCommandEvent& event )
+{
+ Close();
+}
+
+void DIALOG_ERC::OnCloseErcDialog( wxCloseEvent& event )
+{
+ Destroy();
+}
+
+
+void DIALOG_ERC::OnResetMatrixClick( wxCommandEvent& event )
+{
+ ResetDefaultERCDiag( event );
+}
+
+
+void DIALOG_ERC::OnErcCmpClick( wxCommandEvent& event )
+{
+ wxBusyCursor();
+ m_MarkersList->ClearList();
+
+ m_MessagesList->Clear();
+ wxSafeYield(); // m_MarkersList must be redraw
+ wxArrayString messageList;
+ TestErc( &messageList );
+
+ for( unsigned ii = 0; ii < messageList.GetCount(); ii++ )
+ m_MessagesList->AppendText( messageList[ii] );
+}
+
+
+void DIALOG_ERC::OnLeftClickMarkersList( wxHtmlLinkEvent& event )
+{
+ wxString link = event.GetLinkInfo().GetHref();
+
+ m_lastMarkerFound = NULL;
+
+ long index;
+
+ if( !link.ToLong( &index ) )
+ return;
+
+ const SCH_MARKER* marker = m_MarkersList->GetItem( index );
+
+ if( marker == NULL )
+ return;
+
+ // Search for the selected marker
+ SCH_SHEET_PATH* sheet;
+ SCH_SHEET_LIST SheetList;
+ bool notFound = true;
+
+ for( sheet = SheetList.GetFirst(); sheet; sheet = SheetList.GetNext() )
+ {
+ SCH_ITEM* item = (SCH_ITEM*) sheet->LastDrawList();
+
+ for( ; item; item = item->Next() )
+ {
+ if( item == marker )
+ {
+ notFound = false;
+ break;
+ }
+ }
+
+ if( notFound == false )
+ break;
+ }
+
+ if( notFound ) // Error
+ {
+ wxMessageBox( _( "Marker not found" ) );
+
+ // The marker was deleted, so rebuild marker list
+ DisplayERC_MarkersList();
+ return;
+ }
+
+ if( *sheet != m_parent->GetCurrentSheet() )
+ {
+ sheet->LastScreen()->SetZoom( m_parent->GetScreen()->GetZoom() );
+ m_parent->SetCurrentSheet( *sheet );
+ m_parent->GetCurrentSheet().UpdateAllScreenReferences();
+ }
+
+ m_lastMarkerFound = marker;
+ m_parent->SetCrossHairPosition( marker->m_Pos );
+ m_parent->RedrawScreen( marker->m_Pos, false);
+}
+
+
+void DIALOG_ERC::OnLeftDblClickMarkersList( wxMouseEvent& event )
+{
+ // Remember: OnLeftClickMarkersList was called just berfore
+ // and therefore m_lastMarkerFound was initialized.
+ // (NULL if not found)
+ if( m_lastMarkerFound )
+ {
+ m_parent->SetCrossHairPosition( m_lastMarkerFound->m_Pos );
+ m_parent->RedrawScreen( m_lastMarkerFound->m_Pos, true );
+ // prevent a mouse left button release event in
+ // coming from the ERC dialog double click
+ // ( the button is released after closing this dialog and will generate
+ // an unwanted event in parent frame)
+ m_parent->SkipNextLeftButtonReleaseEvent();
+ }
+
+ Close();
+}
+
+
+void DIALOG_ERC::ReBuildMatrixPanel()
+{
+ // Try to know the size of bitmap button used in drc matrix
+ wxBitmapButton * dummy = new wxBitmapButton( m_matrixPanel, wxID_ANY, KiBitmap( ercerr_xpm ) );
+ wxSize bitmap_size = dummy->GetSize();
+ delete dummy;
+
+ if( !DiagErcTableInit )
+ {
+ memcpy( DiagErc, DefaultDiagErc, sizeof(DefaultDiagErc) );
+ DiagErcTableInit = true;
+ }
+
+ wxPoint pos;
+ // Get the current text size:use a dummy text.
+ wxStaticText* text = new wxStaticText( m_matrixPanel, -1, wxT( "W" ), pos );
+ int text_height = text->GetRect().GetHeight();
+ bitmap_size.y = std::max( bitmap_size.y, text_height );
+ delete text;
+
+ // compute the Y pos interval:
+ pos.y = text_height;
+
+ if( m_initialized == false )
+ {
+ // Print row labels
+ for( int ii = 0; ii < PIN_NMAX; ii++ )
+ {
+ int y = pos.y + (ii * bitmap_size.y);
+ text = new wxStaticText( m_matrixPanel, -1, CommentERC_H[ii],
+ wxPoint( 5, y + ( bitmap_size.y / 2) - (text_height / 2) ) );
+
+ int x = text->GetRect().GetRight();
+ pos.x = std::max( pos.x, x );
+ }
+
+ pos.x += 5;
+ }
+ else
+ pos = m_buttonList[0][0]->GetPosition();
+
+ for( int ii = 0; ii < PIN_NMAX; ii++ )
+ {
+ int y = pos.y + (ii * bitmap_size.y);
+
+ for( int jj = 0; jj <= ii; jj++ )
+ {
+ // Add column labels (only once)
+ int diag = DiagErc[ii][jj];
+ int x = pos.x + (jj * bitmap_size.x);
+
+ if( (ii == jj) && !m_initialized )
+ {
+ wxPoint txtpos;
+ txtpos.x = x + (bitmap_size.x / 2);
+ txtpos.y = y - text_height;
+ text = new wxStaticText( m_matrixPanel, -1, CommentERC_V[ii], txtpos );
+ }
+
+ int event_id = ID_MATRIX_0 + ii + ( jj * PIN_NMAX );
+ BITMAP_DEF bitmap_butt = erc_green_xpm;
+
+ delete m_buttonList[ii][jj];
+ m_buttonList[ii][jj] = new wxBitmapButton( m_matrixPanel,
+ event_id,
+ KiBitmap( bitmap_butt ),
+ wxPoint( x, y ) );
+ setDRCMatrixButtonState( m_buttonList[ii][jj], diag );
+ }
+ }
+
+ m_initialized = true;
+}
+
+
+void DIALOG_ERC::setDRCMatrixButtonState( wxBitmapButton *aButton, int aState )
+{
+ BITMAP_DEF bitmap_butt = NULL;
+ wxString tooltip;
+
+ switch( aState )
+ {
+ case OK:
+ bitmap_butt = erc_green_xpm;
+ tooltip = _( "No error or warning" );
+ break;
+
+ case WAR:
+ bitmap_butt = ercwarn_xpm;
+ tooltip = _( "Generate warning" );
+ break;
+
+ case ERR:
+ bitmap_butt = ercerr_xpm;
+ tooltip = _( "Generate error" );
+ break;
+ }
+
+ if( bitmap_butt )
+ {
+ aButton->SetBitmap( KiBitmap( bitmap_butt ) );
+ aButton->SetToolTip( tooltip );
+ }
+}
+
+
+void DIALOG_ERC::DisplayERC_MarkersList()
+{
+ SCH_SHEET_LIST sheetList;
+ m_MarkersList->ClearList();
+
+ SCH_SHEET_PATH* sheet = sheetList.GetFirst();
+
+ for( ; sheet != NULL; sheet = sheetList.GetNext() )
+ {
+ SCH_ITEM* item = sheet->LastDrawList();
+
+ for( ; item != NULL; item = item->Next() )
+ {
+ if( item->Type() != SCH_MARKER_T )
+ continue;
+
+ SCH_MARKER* marker = (SCH_MARKER*) item;
+
+ if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
+ continue;
+
+ m_MarkersList->AppendToList( marker );
+ }
+ }
+
+ m_MarkersList->DisplayList();
+}
+
+
+void DIALOG_ERC::ResetDefaultERCDiag( wxCommandEvent& event )
+{
+ memcpy( DiagErc, DefaultDiagErc, sizeof( DiagErc ) );
+ ReBuildMatrixPanel();
+}
+
+
+void DIALOG_ERC::ChangeErrorLevel( wxCommandEvent& event )
+{
+ int id, level, ii, x, y;
+ wxPoint pos;
+
+ id = event.GetId();
+ ii = id - ID_MATRIX_0;
+ wxBitmapButton* butt = (wxBitmapButton*) event.GetEventObject();
+ pos = butt->GetPosition();
+
+ x = ii / PIN_NMAX; y = ii % PIN_NMAX;
+
+ level = DiagErc[y][x];
+
+ //change to the next error level
+ switch( level )
+ {
+ case OK:
+ level = WAR;
+ break;
+
+ case WAR:
+ level = ERR;
+ break;
+
+ case ERR:
+ level = OK;
+ break;
+ }
+
+ setDRCMatrixButtonState( butt, level);
+
+ DiagErc[y][x] = DiagErc[x][y] = level;
+}
+
+
+void DIALOG_ERC::TestErc( wxArrayString* aMessagesList )
+{
+ wxFileName fn;
+
+ if( !DiagErcTableInit )
+ {
+ memcpy( DiagErc, DefaultDiagErc, sizeof( DefaultDiagErc ) );
+ DiagErcTableInit = true;
+ }
+
+ m_writeErcFile = m_WriteResultOpt->GetValue();
+
+ // Build the whole sheet list in hierarchy (sheet, not screen)
+ SCH_SHEET_LIST sheets;
+ sheets.AnnotatePowerSymbols( Prj().SchLibs() );
+
+ if( m_parent->CheckAnnotate( aMessagesList, false ) )
+ {
+ if( aMessagesList )
+ {
+ wxString msg = _( "Annotation required!" );
+ msg += wxT( "\n" );
+ aMessagesList->Add( msg );
+ }
+
+ return;
+ }
+
+ SCH_SCREENS screens;
+
+ // Erase all previous DRC markers.
+ screens.DeleteAllMarkers( MARKER_BASE::MARKER_ERC );
+
+ for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() )
+ {
+ /* Ff wire list has changed, delete Undo Redo list to avoid pointers on deleted
+ * data problems.
+ */
+ if( screen->SchematicCleanUp( NULL ) )
+ screen->ClearUndoRedoList();
+ }
+
+ /* Test duplicate sheet names inside a given sheet, one cannot have sheets with
+ * duplicate names (file names can be duplicated).
+ */
+ TestDuplicateSheetNames( true );
+
+ std::auto_ptr<NETLIST_OBJECT_LIST> objectsConnectedList( m_parent->BuildNetListBase() );
+
+ // Reset the connection type indicator
+ objectsConnectedList->ResetConnectionsType();
+
+ unsigned lastNet;
+ unsigned nextNet = lastNet = 0;
+ int MinConn = NOC;
+
+ for( unsigned net = 0; net < objectsConnectedList->size(); net++ )
+ {
+ if( objectsConnectedList->GetItemNet( lastNet ) !=
+ objectsConnectedList->GetItemNet( net ) )
+ {
+ // New net found:
+ MinConn = NOC;
+ nextNet = net;
+ }
+
+ switch( objectsConnectedList->GetItemType( net ) )
+ {
+ // These items do not create erc problems
+ case NET_ITEM_UNSPECIFIED:
+ case NET_SEGMENT:
+ case NET_BUS:
+ case NET_JUNCTION:
+ case NET_LABEL:
+ case NET_BUSLABELMEMBER:
+ case NET_PINLABEL:
+ case NET_GLOBBUSLABELMEMBER:
+ break;
+
+ case NET_HIERLABEL:
+ case NET_HIERBUSLABELMEMBER:
+ case NET_SHEETLABEL:
+ case NET_SHEETBUSLABELMEMBER:
+ case NET_GLOBLABEL:
+
+ // ERC problems when pin sheets do not match hierarchical labels.
+ // Each pin sheet must match a hierarchical label
+ // Each hierarchical label must match a pin sheet
+ TestLabel( objectsConnectedList.get(), net, nextNet );
+ break;
+
+ case NET_NOCONNECT:
+
+ // ERC problems when a noconnect symbol is connected to more than one pin.
+ MinConn = NET_NC;
+
+ if( CountPinsInNet( objectsConnectedList.get(), nextNet ) > 1 )
+ Diagnose( objectsConnectedList->GetItem( net ), NULL, MinConn, UNC );
+
+ break;
+
+ case NET_PIN:
+
+ // Look for ERC problems between pins:
+ TestOthersItems( objectsConnectedList.get(), net, nextNet, &MinConn );
+ break;
+ }
+
+ lastNet = net;
+ }
+
+ // Displays global results:
+ updateMarkerCounts( &screens );
+
+ // Display diags:
+ DisplayERC_MarkersList();
+
+ // Display new markers:
+ m_parent->GetCanvas()->Refresh();
+
+ if( m_writeErcFile )
+ {
+ fn = g_RootSheet->GetScreen()->GetFileName();
+ fn.SetExt( wxT( "erc" ) );
+
+ wxFileDialog dlg( this, _( "ERC File" ), fn.GetPath(), fn.GetFullName(),
+ _( "Electronic rule check file (.erc)|*.erc" ),
+ wxFD_SAVE );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ if( WriteDiagnosticERC( dlg.GetPath() ) )
+ ExecuteFile( this, Pgm().GetEditorName(), QuoteFullPath( fn ) );
+ }
+}
+
+
+wxDialog* InvokeDialogERC( SCH_EDIT_FRAME* aCaller )
+{
+ // This is a modeless dialog, so new it rather than instantiating on stack.
+ DIALOG_ERC* dlg = new DIALOG_ERC( aCaller );
+
+ dlg->Show( true );
+
+ return dlg; // wxDialog is information hiding about DIALOG_ERC.
+}
diff --git a/eeschema/dialogs/dialog_erc.h b/eeschema/dialogs/dialog_erc.h
new file mode 100644
index 0000000..e086166
--- /dev/null
+++ b/eeschema/dialogs/dialog_erc.h
@@ -0,0 +1,92 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _DIALOG_ERC_H_
+#define _DIALOG_ERC_H_
+
+#include <wx/htmllbox.h>
+#include <vector>
+
+
+#include <dialog_erc_base.h>
+#include "dialog_erc_listbox.h"
+
+/* Variable locales */
+extern int DiagErc[PIN_NMAX][PIN_NMAX];
+extern bool DiagErcTableInit; // go to true after DiagErc init
+extern int DefaultDiagErc[PIN_NMAX][PIN_NMAX];
+
+/* Control identifiers */
+#define ID_MATRIX_0 1800
+
+/*!
+ * DIALOG_ERC class declaration
+ */
+
+class DIALOG_ERC : public DIALOG_ERC_BASE
+{
+ DECLARE_EVENT_TABLE()
+
+private:
+ SCH_EDIT_FRAME* m_parent;
+ wxBitmapButton* m_buttonList[PIN_NMAX][PIN_NMAX];
+ bool m_initialized;
+ const SCH_MARKER* m_lastMarkerFound;
+ static bool m_writeErcFile;
+
+public:
+ DIALOG_ERC( SCH_EDIT_FRAME* parent );
+ ~DIALOG_ERC();
+
+private:
+ void Init();
+
+ // from DIALOG_ERC_BASE:
+ void OnCloseErcDialog( wxCloseEvent& event );
+ void OnErcCmpClick( wxCommandEvent& event );
+ void OnEraseDrcMarkersClick( wxCommandEvent& event );
+ void OnButtonCloseClick( wxCommandEvent& event );
+ void OnResetMatrixClick( wxCommandEvent& event );
+
+ // Click on a marker info:
+ void OnLeftClickMarkersList( wxHtmlLinkEvent& event );
+
+ // Double click on a marker info:
+ void OnLeftDblClickMarkersList( wxMouseEvent& event );
+
+ void TestErc( wxArrayString* aMessagesList );
+ void DisplayERC_MarkersList();
+ void SelLocal( wxCommandEvent& event );
+ void SelNewCmp( wxCommandEvent& event );
+ void ResetDefaultERCDiag( wxCommandEvent& event );
+ void ChangeErrorLevel( wxCommandEvent& event );
+ void ReBuildMatrixPanel();
+ void setDRCMatrixButtonState( wxBitmapButton *aButton, int aState );
+ void updateMarkerCounts( SCH_SCREENS *screens );
+};
+
+
+#endif
+
+// _DIALOG_ERC_H_
diff --git a/eeschema/dialogs/dialog_erc_base.cpp b/eeschema/dialogs/dialog_erc_base.cpp
new file mode 100644
index 0000000..c1ef861
--- /dev/null
+++ b/eeschema/dialogs/dialog_erc_base.cpp
@@ -0,0 +1,152 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_erc_listbox.h"
+
+#include "dialog_erc_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_ERC_BASE::DIALOG_ERC_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizer1;
+ bSizer1 = new wxBoxSizer( wxVERTICAL );
+
+ m_NoteBook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PanelERC = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* bercSizer;
+ bercSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bupperSizer;
+ bupperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sdiagSizer;
+ sdiagSizer = new wxStaticBoxSizer( new wxStaticBox( m_PanelERC, wxID_ANY, _("ERC Report:") ), wxVERTICAL );
+
+ wxGridSizer* gSizeDiag;
+ gSizeDiag = new wxGridSizer( 3, 2, 0, 0 );
+
+ m_ErcTotalErrorsText = new wxStaticText( sdiagSizer->GetStaticBox(), wxID_ANY, _("Total:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ErcTotalErrorsText->Wrap( -1 );
+ gSizeDiag->Add( m_ErcTotalErrorsText, 1, wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_TotalErrCount = new wxTextCtrl( sdiagSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ gSizeDiag->Add( m_TotalErrCount, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_WarnErcErrorsText = new wxStaticText( sdiagSizer->GetStaticBox(), wxID_ANY, _("Warnings:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_WarnErcErrorsText->Wrap( -1 );
+ gSizeDiag->Add( m_WarnErcErrorsText, 1, wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_LastWarningCount = new wxTextCtrl( sdiagSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ gSizeDiag->Add( m_LastWarningCount, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_LastErrCountText = new wxStaticText( sdiagSizer->GetStaticBox(), wxID_ANY, _("Errors:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_LastErrCountText->Wrap( -1 );
+ gSizeDiag->Add( m_LastErrCountText, 1, wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_LastErrCount = new wxTextCtrl( sdiagSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ gSizeDiag->Add( m_LastErrCount, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ sdiagSizer->Add( gSizeDiag, 0, wxEXPAND, 5 );
+
+ m_WriteResultOpt = new wxCheckBox( sdiagSizer->GetStaticBox(), wxID_ANY, _("Create ERC file report"), wxDefaultPosition, wxDefaultSize, 0 );
+ sdiagSizer->Add( m_WriteResultOpt, 0, wxTOP|wxBOTTOM|wxRIGHT, 5 );
+
+
+ bupperSizer->Add( sdiagSizer, 0, wxEXPAND|wxTOP, 5 );
+
+ wxBoxSizer* bSizerMessages;
+ bSizerMessages = new wxBoxSizer( wxVERTICAL );
+
+ m_titleMessages = new wxStaticText( m_PanelERC, wxID_ANY, _("Messages:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_titleMessages->Wrap( -1 );
+ bSizerMessages->Add( m_titleMessages, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_MessagesList = new wxTextCtrl( m_PanelERC, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY );
+ bSizerMessages->Add( m_MessagesList, 1, wxEXPAND|wxLEFT, 5 );
+
+
+ bupperSizer->Add( bSizerMessages, 1, wxEXPAND, 5 );
+
+
+ bercSizer->Add( bupperSizer, 0, wxALL|wxEXPAND, 5 );
+
+ m_textMarkers = new wxStaticText( m_PanelERC, wxID_ANY, _("Error list:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_textMarkers->Wrap( -1 );
+ bercSizer->Add( m_textMarkers, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_MarkersList = new ERC_HTML_LISTFRAME( m_PanelERC, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO|wxSUNKEN_BORDER );
+ bercSizer->Add( m_MarkersList, 1, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bbuttonsSizer;
+ bbuttonsSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ m_buttondelmarkers = new wxButton( m_PanelERC, ID_ERASE_DRC_MARKERS, _("&Delete Markers"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttondelmarkers, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonERC = new wxButton( m_PanelERC, ID_ERC_CMP, _("&Run"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonERC->SetDefault();
+ bbuttonsSizer->Add( m_buttonERC, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonClose = new wxButton( m_PanelERC, wxID_CANCEL, _("&Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttonClose, 0, wxALL|wxEXPAND, 5 );
+
+
+ bercSizer->Add( bbuttonsSizer, 0, wxALIGN_RIGHT, 5 );
+
+
+ m_PanelERC->SetSizer( bercSizer );
+ m_PanelERC->Layout();
+ bercSizer->Fit( m_PanelERC );
+ m_NoteBook->AddPage( m_PanelERC, _("ERC"), true );
+ m_PanelERCOptions = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* m_panelMatrixSizer;
+ m_panelMatrixSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_ResetOptButton = new wxButton( m_PanelERCOptions, ID_RESET_MATRIX, _("Initialize to Default"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_panelMatrixSizer->Add( m_ResetOptButton, 0, wxALIGN_RIGHT|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_matrixPanel = new wxPanel( m_PanelERCOptions, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_panelMatrixSizer->Add( m_matrixPanel, 1, wxEXPAND | wxALL, 5 );
+
+
+ m_PanelERCOptions->SetSizer( m_panelMatrixSizer );
+ m_PanelERCOptions->Layout();
+ m_panelMatrixSizer->Fit( m_PanelERCOptions );
+ m_NoteBook->AddPage( m_PanelERCOptions, _("Options"), false );
+
+ bSizer1->Add( m_NoteBook, 1, wxEXPAND | wxALL, 5 );
+
+
+ this->SetSizer( bSizer1 );
+ this->Layout();
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_ERC_BASE::OnCloseErcDialog ) );
+ m_MarkersList->Connect( wxEVT_COMMAND_HTML_LINK_CLICKED, wxHtmlLinkEventHandler( DIALOG_ERC_BASE::OnLeftClickMarkersList ), NULL, this );
+ m_MarkersList->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_ERC_BASE::OnLeftDblClickMarkersList ), NULL, this );
+ m_buttondelmarkers->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ERC_BASE::OnEraseDrcMarkersClick ), NULL, this );
+ m_buttonERC->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ERC_BASE::OnErcCmpClick ), NULL, this );
+ m_buttonClose->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ERC_BASE::OnButtonCloseClick ), NULL, this );
+ m_ResetOptButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ERC_BASE::OnResetMatrixClick ), NULL, this );
+}
+
+DIALOG_ERC_BASE::~DIALOG_ERC_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_ERC_BASE::OnCloseErcDialog ) );
+ m_MarkersList->Disconnect( wxEVT_COMMAND_HTML_LINK_CLICKED, wxHtmlLinkEventHandler( DIALOG_ERC_BASE::OnLeftClickMarkersList ), NULL, this );
+ m_MarkersList->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_ERC_BASE::OnLeftDblClickMarkersList ), NULL, this );
+ m_buttondelmarkers->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ERC_BASE::OnEraseDrcMarkersClick ), NULL, this );
+ m_buttonERC->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ERC_BASE::OnErcCmpClick ), NULL, this );
+ m_buttonClose->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ERC_BASE::OnButtonCloseClick ), NULL, this );
+ m_ResetOptButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ERC_BASE::OnResetMatrixClick ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_erc_base.fbp b/eeschema/dialogs/dialog_erc_base.fbp
new file mode 100644
index 0000000..aa6589a
--- /dev/null
+++ b/eeschema/dialogs/dialog_erc_base.fbp
@@ -0,0 +1,1799 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_erc_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_ERC_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">0</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_ERC_BASE</property>
+ <property name="pos"></property>
+ <property name="size">519,457</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Electrical Rules Checker</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseErcDialog</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer1</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxNotebook" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmapsize"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NoteBook</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnNotebookPageChanged"></event>
+ <event name="OnNotebookPageChanging"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">ERC</property>
+ <property name="select">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PanelERC</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bercSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bupperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">ERC Report:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sdiagSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">gSizeDiag</property>
+ <property name="permission">none</property>
+ <property name="rows">3</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Total:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ErcTotalErrorsText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TotalErrCount</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Warnings:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_WarnErcErrorsText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LastWarningCount</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Errors:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LastErrCountText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LastErrCount</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Create ERC file report</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_WriteResultOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMessages</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Messages:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_titleMessages</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_MessagesList</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_MULTILINE|wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Error list:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textMarkers</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxHtmlWindow" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MarkersList</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxHW_SCROLLBAR_AUTO</property>
+ <property name="subclass">ERC_HTML_LISTFRAME; dialog_erc_listbox.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxSUNKEN_BORDER</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHtmlCellClicked"></event>
+ <event name="OnHtmlCellHover"></event>
+ <event name="OnHtmlLinkClicked">OnLeftClickMarkersList</event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick">OnLeftDblClickMarkersList</event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bbuttonsSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ERASE_DRC_MARKERS</property>
+ <property name="label">&amp;Delete Markers</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttondelmarkers</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnEraseDrcMarkersClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ERC_CMP</property>
+ <property name="label">&amp;Run</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonERC</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnErcCmpClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">&amp;Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonClose</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonCloseClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Options</property>
+ <property name="select">0</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PanelERCOptions</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_panelMatrixSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_RESET_MATRIX</property>
+ <property name="label">Initialize to Default</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ResetOptButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnResetMatrixClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_matrixPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_erc_base.h b/eeschema/dialogs/dialog_erc_base.h
new file mode 100644
index 0000000..007f946
--- /dev/null
+++ b/eeschema/dialogs/dialog_erc_base.h
@@ -0,0 +1,88 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_ERC_BASE_H__
+#define __DIALOG_ERC_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class ERC_HTML_LISTFRAME;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/checkbox.h>
+#include <wx/statbox.h>
+#include <wx/html/htmlwin.h>
+#include <wx/button.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/notebook.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_ERASE_DRC_MARKERS 1000
+#define ID_ERC_CMP 1001
+#define ID_RESET_MATRIX 1002
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_ERC_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_ERC_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxNotebook* m_NoteBook;
+ wxPanel* m_PanelERC;
+ wxStaticText* m_ErcTotalErrorsText;
+ wxTextCtrl* m_TotalErrCount;
+ wxStaticText* m_WarnErcErrorsText;
+ wxTextCtrl* m_LastWarningCount;
+ wxStaticText* m_LastErrCountText;
+ wxTextCtrl* m_LastErrCount;
+ wxCheckBox* m_WriteResultOpt;
+ wxStaticText* m_titleMessages;
+ wxTextCtrl* m_MessagesList;
+ wxStaticText* m_textMarkers;
+ ERC_HTML_LISTFRAME* m_MarkersList;
+ wxButton* m_buttondelmarkers;
+ wxButton* m_buttonERC;
+ wxButton* m_buttonClose;
+ wxPanel* m_PanelERCOptions;
+ wxButton* m_ResetOptButton;
+ wxPanel* m_matrixPanel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseErcDialog( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnLeftClickMarkersList( wxHtmlLinkEvent& event ) { event.Skip(); }
+ virtual void OnLeftDblClickMarkersList( wxMouseEvent& event ) { event.Skip(); }
+ virtual void OnEraseDrcMarkersClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnErcCmpClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonCloseClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnResetMatrixClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_ERC_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Electrical Rules Checker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 519,457 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_ERC_BASE();
+
+};
+
+#endif //__DIALOG_ERC_BASE_H__
diff --git a/eeschema/dialogs/dialog_lib_edit_draw_item.cpp b/eeschema/dialogs/dialog_lib_edit_draw_item.cpp
new file mode 100644
index 0000000..d0bf3ef
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_draw_item.cpp
@@ -0,0 +1,131 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2006-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_lib_edit_draw_item.cpp
+ */
+
+#include <dialog_lib_edit_draw_item.h>
+
+
+DIALOG_LIB_EDIT_DRAW_ITEM::DIALOG_LIB_EDIT_DRAW_ITEM( wxWindow* parent,
+ const wxString& itemName ) :
+ DIALOG_LIB_EDIT_DRAW_ITEM_BASE( parent )
+{
+ SetTitle( itemName + wxT( " " ) + GetTitle() );
+
+ // Required under wxGTK if we want to dismiss the dialog with the ESC key
+ SetFocus();
+ m_sdbSizer1OK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void DIALOG_LIB_EDIT_DRAW_ITEM::SetWidth( const wxString& width )
+{
+ m_textWidth->SetValue( width );
+}
+
+
+wxString DIALOG_LIB_EDIT_DRAW_ITEM::GetWidth( void )
+{
+ return m_textWidth->GetValue();
+}
+
+
+bool DIALOG_LIB_EDIT_DRAW_ITEM::GetApplyToAllConversions( void )
+{
+ return m_checkApplyToAllConversions->IsChecked();
+}
+
+
+void DIALOG_LIB_EDIT_DRAW_ITEM::SetApplyToAllConversions( bool applyToAll )
+{
+ m_checkApplyToAllConversions->SetValue( applyToAll );
+}
+
+
+void DIALOG_LIB_EDIT_DRAW_ITEM::EnableApplyToAllConversions( bool enable )
+{
+ m_checkApplyToAllConversions->Enable( enable );
+}
+
+
+bool DIALOG_LIB_EDIT_DRAW_ITEM::GetApplyToAllUnits( void )
+{
+ return m_checkApplyToAllUnits->IsChecked();
+}
+
+
+void DIALOG_LIB_EDIT_DRAW_ITEM::SetApplyToAllUnits( bool applyToAll )
+{
+ m_checkApplyToAllUnits->SetValue( applyToAll );
+}
+
+
+void DIALOG_LIB_EDIT_DRAW_ITEM::EnableApplyToAllUnits( bool enable )
+{
+ m_checkApplyToAllUnits->Enable( enable );
+}
+
+
+int DIALOG_LIB_EDIT_DRAW_ITEM::GetFillStyle( void )
+{
+ if( m_radioFillNone->GetValue() )
+ return 0;
+ if( m_radioFillForeground->GetValue() )
+ return 1;
+ if( m_radioFillBackground->GetValue() )
+ return 2;
+
+ return 0;
+}
+
+
+void DIALOG_LIB_EDIT_DRAW_ITEM::SetFillStyle( int fillStyle )
+{
+ if( fillStyle == 1 )
+ m_radioFillForeground->SetValue( true );
+ else if( fillStyle == 2 )
+ m_radioFillBackground->SetValue( true );
+ else
+ m_radioFillNone->SetValue( true );
+}
+
+
+void DIALOG_LIB_EDIT_DRAW_ITEM::EnableFillStyle( bool enable )
+{
+ m_radioFillNone->Enable( enable );
+ m_radioFillForeground->Enable( enable );
+ m_radioFillBackground->Enable( enable );
+}
+
+
+void DIALOG_LIB_EDIT_DRAW_ITEM::SetWidthUnits( const wxString& units )
+{
+ m_staticWidthUnits->SetLabel( units );
+}
diff --git a/eeschema/dialogs/dialog_lib_edit_draw_item.fbp b/eeschema/dialogs/dialog_lib_edit_draw_item.fbp
new file mode 100644
index 0000000..323b7d3
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_draw_item.fbp
@@ -0,0 +1,1205 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="11" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">table</property>
+ <property name="file">dialog_lib_edit_draw_item_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_lib_edit_draw_item</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_LIB_EDIT_DRAW_ITEM_BASE</property>
+ <property name="pos"></property>
+ <property name="size"></property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass"></property>
+ <property name="title">Drawing Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">mainSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">12</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">dlgBorderSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_LEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">General</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">0</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer3</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">12</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mm</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticWidthUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_STATICTEXTSHARING</property>
+ <property name="label">Sharing</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSharing</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">0</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer4</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">12</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Common to all &amp;units in component</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkApplyToAllUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer5</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">12</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Common to all body &amp;styles (DeMorgan)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkApplyToAllConversions</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">10</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_LEFT|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Fill Style</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">0</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer6</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">12</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">0</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer7</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Do &amp;not fill</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioFillNone</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRB_GROUP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">1</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Fill &amp;foreground</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioFillForeground</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Fill &amp;background</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioFillBackground</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">10</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">0</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_lib_edit_draw_item.h b/eeschema/dialogs/dialog_lib_edit_draw_item.h
new file mode 100644
index 0000000..3680a1f
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_draw_item.h
@@ -0,0 +1,67 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __dialog_lib_edit_draw_item__
+#define __dialog_lib_edit_draw_item__
+
+/**
+ * @file
+ * Subclass of DIALOG_LIB_EDIT_DRAW_ITEM_BASE, which is generated by
+ * wxFormBuilder.
+ */
+
+class LIB_DRAW_ITEM;
+
+
+#include <dialog_lib_edit_draw_item_base.h>
+
+
+/**
+ * Dialog to edit library component graphic items.
+ */
+class DIALOG_LIB_EDIT_DRAW_ITEM : public DIALOG_LIB_EDIT_DRAW_ITEM_BASE
+{
+public:
+ /** Constructor */
+ DIALOG_LIB_EDIT_DRAW_ITEM( wxWindow* parent, const wxString& itemName );
+
+ wxString GetWidth( void );
+ void SetWidth( const wxString& width );
+
+ bool GetApplyToAllConversions( void );
+ void SetApplyToAllConversions( bool applyToAll );
+ void EnableApplyToAllConversions( bool enable = true );
+
+ bool GetApplyToAllUnits( void );
+ void SetApplyToAllUnits( bool applyToAll );
+ void EnableApplyToAllUnits( bool enable = true );
+
+ int GetFillStyle( void );
+ void SetFillStyle( int fillStyle );
+ void EnableFillStyle( bool enable = true );
+
+ void SetWidthUnits( const wxString& units );
+};
+
+#endif // __dialog_lib_edit_draw_item__
diff --git a/eeschema/dialogs/dialog_lib_edit_draw_item_base.cpp b/eeschema/dialogs/dialog_lib_edit_draw_item_base.cpp
new file mode 100644
index 0000000..021d584
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_draw_item_base.cpp
@@ -0,0 +1,140 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 21 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_lib_edit_draw_item_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_LIB_EDIT_DRAW_ITEM_BASE::DIALOG_LIB_EDIT_DRAW_ITEM_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* mainSizer;
+ mainSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* dlgBorderSizer;
+ dlgBorderSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText1 = new wxStaticText( this, wxID_ANY, _("General"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ m_staticText1->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
+
+ dlgBorderSizer->Add( m_staticText1, 0, wxALIGN_LEFT, 3 );
+
+ wxBoxSizer* bSizer3;
+ bSizer3 = new wxBoxSizer( wxHORIZONTAL );
+
+
+ bSizer3->Add( 12, 0, 0, wxEXPAND, 3 );
+
+ m_staticWidth = new wxStaticText( this, wxID_ANY, _("&Width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticWidth->Wrap( -1 );
+ bSizer3->Add( m_staticWidth, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+
+ bSizer3->Add( 0, 0, 1, wxEXPAND, 3 );
+
+ m_textWidth = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer3->Add( m_textWidth, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_staticWidthUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticWidthUnits->Wrap( -1 );
+ bSizer3->Add( m_staticWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+
+ dlgBorderSizer->Add( bSizer3, 0, wxALL|wxEXPAND, 0 );
+
+ m_staticTextSharing = new wxStaticText( this, ID_M_STATICTEXTSHARING, _("Sharing"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSharing->Wrap( -1 );
+ m_staticTextSharing->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
+
+ dlgBorderSizer->Add( m_staticTextSharing, 0, wxTOP|wxBOTTOM, 5 );
+
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxHORIZONTAL );
+
+
+ bSizer4->Add( 12, 0, 0, wxEXPAND, 3 );
+
+ m_checkApplyToAllUnits = new wxCheckBox( this, wxID_ANY, _("Common to all &units in component"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer4->Add( m_checkApplyToAllUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+
+ dlgBorderSizer->Add( bSizer4, 0, wxALL|wxEXPAND, 0 );
+
+ wxBoxSizer* bSizer5;
+ bSizer5 = new wxBoxSizer( wxHORIZONTAL );
+
+
+ bSizer5->Add( 12, 0, 0, wxEXPAND, 3 );
+
+ m_checkApplyToAllConversions = new wxCheckBox( this, wxID_ANY, _("Common to all body &styles (DeMorgan)"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer5->Add( m_checkApplyToAllConversions, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+
+ dlgBorderSizer->Add( bSizer5, 0, wxEXPAND, 3 );
+
+
+ dlgBorderSizer->Add( 0, 0, 0, wxALL|wxEXPAND, 10 );
+
+ m_staticText4 = new wxStaticText( this, wxID_ANY, _("Fill Style"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText4->Wrap( -1 );
+ m_staticText4->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
+
+ dlgBorderSizer->Add( m_staticText4, 0, wxALIGN_LEFT|wxBOTTOM, 3 );
+
+ wxBoxSizer* bSizer6;
+ bSizer6 = new wxBoxSizer( wxHORIZONTAL );
+
+
+ bSizer6->Add( 12, 0, 0, wxEXPAND, 3 );
+
+ wxBoxSizer* bSizer7;
+ bSizer7 = new wxBoxSizer( wxVERTICAL );
+
+ m_radioFillNone = new wxRadioButton( this, wxID_ANY, _("Do &not fill"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
+ m_radioFillNone->SetValue( true );
+ bSizer7->Add( m_radioFillNone, 0, wxALL, 3 );
+
+ m_radioFillForeground = new wxRadioButton( this, wxID_ANY, _("Fill &foreground"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer7->Add( m_radioFillForeground, 0, wxALL, 3 );
+
+ m_radioFillBackground = new wxRadioButton( this, wxID_ANY, _("Fill &background"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer7->Add( m_radioFillBackground, 0, wxALL, 3 );
+
+
+ bSizer6->Add( bSizer7, 0, wxEXPAND, 0 );
+
+
+ dlgBorderSizer->Add( bSizer6, 1, wxALL|wxEXPAND, 0 );
+
+
+ dlgBorderSizer->Add( 0, 0, 0, wxALL|wxEXPAND, 10 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ dlgBorderSizer->Add( m_sdbSizer1, 0, wxALL|wxEXPAND, 0 );
+
+
+ mainSizer->Add( dlgBorderSizer, 1, wxALL|wxEXPAND, 12 );
+
+
+ this->SetSizer( mainSizer );
+ this->Layout();
+ mainSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_LIB_EDIT_DRAW_ITEM_BASE::~DIALOG_LIB_EDIT_DRAW_ITEM_BASE()
+{
+}
diff --git a/eeschema/dialogs/dialog_lib_edit_draw_item_base.h b/eeschema/dialogs/dialog_lib_edit_draw_item_base.h
new file mode 100644
index 0000000..553e7d9
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_draw_item_base.h
@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 21 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_LIB_EDIT_DRAW_ITEM_BASE_H__
+#define __DIALOG_LIB_EDIT_DRAW_ITEM_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/checkbox.h>
+#include <wx/radiobut.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_LIB_EDIT_DRAW_ITEM_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_LIB_EDIT_DRAW_ITEM_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ ID_M_STATICTEXTSHARING = 1000
+ };
+
+ wxStaticText* m_staticText1;
+ wxStaticText* m_staticWidth;
+ wxTextCtrl* m_textWidth;
+ wxStaticText* m_staticWidthUnits;
+ wxStaticText* m_staticTextSharing;
+ wxCheckBox* m_checkApplyToAllUnits;
+ wxCheckBox* m_checkApplyToAllConversions;
+ wxStaticText* m_staticText4;
+ wxRadioButton* m_radioFillNone;
+ wxRadioButton* m_radioFillForeground;
+ wxRadioButton* m_radioFillBackground;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ public:
+
+ DIALOG_LIB_EDIT_DRAW_ITEM_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Drawing Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_LIB_EDIT_DRAW_ITEM_BASE();
+
+};
+
+#endif //__DIALOG_LIB_EDIT_DRAW_ITEM_BASE_H__
diff --git a/eeschema/dialogs/dialog_lib_edit_pin.cpp b/eeschema/dialogs/dialog_lib_edit_pin.cpp
new file mode 100644
index 0000000..19ced99
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_pin.cpp
@@ -0,0 +1,193 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <macros.h>
+#include <gr_basic.h>
+#include <base_units.h>
+
+#include <libeditframe.h>
+#include <class_libentry.h>
+#include <lib_pin.h>
+
+#include <dialog_lib_edit_pin.h>
+
+DIALOG_LIB_EDIT_PIN::DIALOG_LIB_EDIT_PIN( EDA_DRAW_FRAME* parent, LIB_PIN* aPin ) :
+ DIALOG_LIB_EDIT_PIN_BASE( parent )
+{
+ // Creates a dummy pin to show on a panel, inside this dialog:
+ m_dummyPin = new LIB_PIN( *aPin );
+
+ // m_dummyPin changes do not propagate to other pins of the current lib component,
+ // so set parent to null and clear flags
+ m_dummyPin->SetParent( NULL );
+ m_dummyPin->ClearFlags();
+
+ m_panelShowPin->SetBackgroundColour( MakeColour( parent->GetDrawBgColor() ) );
+
+ // Set tab order
+ m_textPadName->MoveAfterInTabOrder(m_textPinName);
+ m_sdbSizerButtonsOK->SetDefault();
+
+ GetSizer()->SetSizeHints( this );
+
+ // On some windows manager (Unity, XFCE), this dialog is
+ // not always raised, depending on this dialog is run.
+ // Force it to be raised
+ Raise();
+}
+
+
+DIALOG_LIB_EDIT_PIN::~DIALOG_LIB_EDIT_PIN()
+{
+ delete m_dummyPin;
+}
+
+void DIALOG_LIB_EDIT_PIN::OnInitDialog( wxInitDialogEvent& event )
+{
+ m_textPinName->SetFocus();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+/*
+ * Draw (on m_panelShowPin) the pin currently edited
+ * accroding to current settings in dialog
+ */
+void DIALOG_LIB_EDIT_PIN::OnPaintShowPanel( wxPaintEvent& event )
+{
+ wxPaintDC dc( m_panelShowPin );
+ wxSize dc_size = dc.GetSize();
+ dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
+
+ // Give a parent to m_dummyPin only from draw purpose.
+ // In fact m_dummyPin should not have a parent, but draw functions need a parent
+ // to know some options, about pin texts
+ LIB_EDIT_FRAME* libframe = (LIB_EDIT_FRAME*) GetParent();
+ m_dummyPin->SetParent( libframe->GetCurPart() );
+
+ // Calculate a suitable scale to fit the available draw area
+ EDA_RECT bBox = m_dummyPin->GetBoundingBox();
+ double xscale = (double) dc_size.x / bBox.GetWidth();
+ double yscale = (double) dc_size.y / bBox.GetHeight();
+ double scale = std::min( xscale, yscale );
+
+ // Give a 10% margin
+ scale *= 0.9;
+ dc.SetUserScale( scale, scale );
+
+ wxPoint offset = -bBox.Centre();
+
+ GRResetPenAndBrush( &dc );
+ bool drawpinTexts = true; // this is a dummy param. We use its reference
+ // as non null value for m_dummyPin->Draw
+ m_dummyPin->Draw( NULL, &dc, offset, UNSPECIFIED_COLOR, GR_COPY,
+ &drawpinTexts, DefaultTransform );
+
+ m_dummyPin->SetParent(NULL);
+
+ event.Skip();
+}
+
+void DIALOG_LIB_EDIT_PIN::OnCloseDialog( wxCloseEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+void DIALOG_LIB_EDIT_PIN::OnCancelButtonClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+void DIALOG_LIB_EDIT_PIN::OnOKButtonClick( wxCommandEvent& event )
+{
+ EndModal( wxID_OK );
+}
+
+// Called when a pin properties changes
+void DIALOG_LIB_EDIT_PIN::OnPropertiesChange( wxCommandEvent& event )
+{
+ if( ! IsShown() ) // do nothing at init time
+ return;
+
+ int pinNameSize = ValueFromString( g_UserUnit, GetPinNameTextSize() );
+ int pinNumSize = ValueFromString( g_UserUnit, GetPadNameTextSize());
+ int pinOrient = LIB_PIN::GetOrientationCode( GetOrientation() );
+ int pinLength = ValueFromString( g_UserUnit, GetLength() );
+ int pinShape = LIB_PIN::GetStyleCode( GetStyle() );
+ int pinType = GetElectricalType();
+
+ m_dummyPin->SetName( GetPinName() );
+ m_dummyPin->SetNameTextSize( pinNameSize );
+ m_dummyPin->SetNumber( GetPadName() );
+ m_dummyPin->SetNumberTextSize( pinNumSize );
+ m_dummyPin->SetOrientation( pinOrient );
+ m_dummyPin->SetLength( pinLength );
+ m_dummyPin->SetShape( pinShape );
+ m_dummyPin->SetVisible( GetVisible() );
+ m_dummyPin->SetType( pinType );
+
+ m_panelShowPin->Refresh();
+}
+
+
+void DIALOG_LIB_EDIT_PIN::SetOrientationList( const wxArrayString& list,
+ const BITMAP_DEF* aBitmaps )
+{
+ for ( unsigned ii = 0; ii < list.GetCount(); ii++ )
+ {
+ if( aBitmaps == NULL )
+ m_choiceOrientation->Append( list[ii] );
+ else
+ m_choiceOrientation->Insert( list[ii], KiBitmap( aBitmaps[ii] ), ii );
+ }
+}
+
+
+void DIALOG_LIB_EDIT_PIN::SetElectricalTypeList( const wxArrayString& list,
+ const BITMAP_DEF* aBitmaps )
+{
+ for ( unsigned ii = 0; ii < list.GetCount(); ii++ )
+ {
+ if( aBitmaps == NULL )
+ m_choiceElectricalType->Append( list[ii] );
+ else
+ m_choiceElectricalType->Insert( list[ii], KiBitmap( aBitmaps[ii] ), ii );
+ }
+}
+
+
+void DIALOG_LIB_EDIT_PIN::SetStyleList( const wxArrayString& list, const BITMAP_DEF* aBitmaps )
+{
+ for ( unsigned ii = 0; ii < list.GetCount(); ii++ )
+ {
+ if( aBitmaps == NULL )
+ m_choiceStyle->Append( list[ii] );
+ else
+ m_choiceStyle->Insert( list[ii], KiBitmap( aBitmaps[ii] ), ii );
+ }
+}
diff --git a/eeschema/dialogs/dialog_lib_edit_pin.h b/eeschema/dialogs/dialog_lib_edit_pin.h
new file mode 100644
index 0000000..52227e2
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_pin.h
@@ -0,0 +1,146 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __dialog_lib_edit_pin__
+#define __dialog_lib_edit_pin__
+
+/**
+ * @file
+ * Subclass of DIALOG_LIB_EDIT_PIN_BASE, which is generated by wxFormBuilder.
+ */
+
+#include <wx/bmpcbox.h>
+
+#include <dialog_lib_edit_pin_base.h>
+
+/** Implementing DIALOG_LIB_EDIT_PIN_BASE */
+class DIALOG_LIB_EDIT_PIN : public DIALOG_LIB_EDIT_PIN_BASE
+{
+ LIB_PIN * m_dummyPin; // a working copy used to show changes
+
+public:
+ /** Constructor */
+ DIALOG_LIB_EDIT_PIN( EDA_DRAW_FRAME* parent, LIB_PIN* aPin );
+ ~DIALOG_LIB_EDIT_PIN();
+
+ void OnInitDialog( wxInitDialogEvent& event);
+
+ void OnCloseDialog( wxCloseEvent& event );
+ void OnCancelButtonClick( wxCommandEvent& event );
+ void OnOKButtonClick( wxCommandEvent& event );
+ void OnPaintShowPanel( wxPaintEvent& event );
+ void OnPropertiesChange( wxCommandEvent& event );
+
+ void SetOrientationList( const wxArrayString& list, const BITMAP_DEF* aBitmaps );
+ void SetOrientation( int orientation )
+ {
+ m_choiceOrientation->SetSelection( orientation );
+ }
+ int GetOrientation( void ) { return m_choiceOrientation->GetSelection(); }
+
+ void SetElectricalTypeList( const wxArrayString& list, const BITMAP_DEF* aBitmaps );
+ void SetElectricalType( int type )
+ {
+ m_choiceElectricalType->SetSelection( type );
+ }
+ int GetElectricalType( void )
+ {
+ return m_choiceElectricalType->GetSelection();
+ }
+
+ void SetStyleList( const wxArrayString& list, const BITMAP_DEF* aBitmaps );
+ void SetStyle( int style ) { m_choiceStyle->SetSelection( style ); }
+ int GetStyle( void ) { return m_choiceStyle->GetSelection(); }
+
+ void SetPinName( const wxString& name ) { m_textPinName->SetValue( name ); }
+ wxString GetPinName( void ) { return m_textPinName->GetValue(); }
+
+ void SetPinNameTextSize( const wxString& size )
+ {
+ m_textPinNameTextSize->SetValue( size );
+ }
+ wxString GetPinNameTextSize( void )
+ {
+ return m_textPinNameTextSize->GetValue();
+ }
+
+ void SetPinNameTextSizeUnits( const wxString& units )
+ {
+ m_staticNameTextSizeUnits->SetLabel( units );
+ }
+
+ void SetPadName( const wxString& number )
+ {
+ m_textPadName->SetValue( number );
+ }
+ wxString GetPadName( void ) { return m_textPadName->GetValue(); }
+
+ void SetPadNameTextSize( const wxString& size )
+ {
+ m_textPadNameTextSize->SetValue( size );
+ }
+ wxString GetPadNameTextSize( void )
+ {
+ return m_textPadNameTextSize->GetValue();
+ }
+
+ void SetPadNameTextSizeUnits( const wxString& units )
+ {
+ m_staticNumberTextSizeUnits->SetLabel( units );
+ }
+
+ void SetLength( const wxString& length )
+ {
+ m_textLength->SetValue( length );
+ }
+ wxString GetLength( void ) { return m_textLength->GetValue(); }
+
+ void SetLengthUnits( const wxString& units )
+ {
+ m_staticLengthUnits->SetLabel( units );
+ }
+
+ void SetAddToAllParts( bool apply )
+ {
+ m_checkApplyToAllParts->SetValue( apply );
+ }
+ bool GetAddToAllParts( void )
+ {
+ return m_checkApplyToAllParts->GetValue();
+ }
+
+ void SetAddToAllBodyStyles( bool apply )
+ {
+ m_checkApplyToAllConversions->SetValue( apply );
+ }
+ bool GetAddToAllBodyStyles( void )
+ {
+ return m_checkApplyToAllConversions->GetValue();
+ }
+
+ void SetVisible( bool visible ) { m_checkShow->SetValue( visible ); }
+ bool GetVisible( void ) { return m_checkShow->GetValue(); }
+};
+
+#endif // __dialog_lib_edit_pin__
diff --git a/eeschema/dialogs/dialog_lib_edit_pin_base.cpp b/eeschema/dialogs/dialog_lib_edit_pin_base.cpp
new file mode 100644
index 0000000..39aa7c5
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_pin_base.cpp
@@ -0,0 +1,224 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "wx/bmpcbox.h"
+
+#include "dialog_lib_edit_pin_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_LIB_EDIT_PIN_BASE::DIALOG_LIB_EDIT_PIN_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* mainSizer;
+ mainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bLeftSizer;
+ bLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizerPins;
+ fgSizerPins = new wxFlexGridSizer( 5, 2, 0, 0 );
+ fgSizerPins->AddGrowableCol( 1 );
+ fgSizerPins->SetFlexibleDirection( wxBOTH );
+ fgSizerPins->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
+
+ m_staticTextPinName = new wxStaticText( this, wxID_ANY, _("Pin &name:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextPinName->Wrap( -1 );
+ fgSizerPins->Add( m_staticTextPinName, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_textPinName = new wxTextCtrl( this, ID_M_TEXTPINNAME, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textPinName->SetMaxLength( 0 );
+ fgSizerPins->Add( m_textPinName, 0, wxEXPAND|wxTOP|wxBOTTOM, 3 );
+
+ m_staticTextPadName = new wxStaticText( this, ID_M_STATICTEXTPADNAME, _("Pin n&umber:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextPadName->Wrap( -1 );
+ m_staticTextPadName->SetToolTip( _("Pin number: 1 to 4 ASCII letters and/or digits") );
+
+ fgSizerPins->Add( m_staticTextPadName, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_textPadName = new wxTextCtrl( this, ID_M_TEXTPADNAME, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textPadName->SetMaxLength( 0 );
+ fgSizerPins->Add( m_textPadName, 0, wxEXPAND|wxTOP|wxBOTTOM, 3 );
+
+ m_staticTextOrient = new wxStaticText( this, wxID_ANY, _("&Orientation:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextOrient->Wrap( -1 );
+ fgSizerPins->Add( m_staticTextOrient, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_choiceOrientation = new wxBitmapComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
+ fgSizerPins->Add( m_choiceOrientation, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+ m_staticTextEType = new wxStaticText( this, wxID_ANY, _("&Electrical type:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextEType->Wrap( -1 );
+ m_staticTextEType->SetToolTip( _("Used by the ERC.") );
+
+ fgSizerPins->Add( m_staticTextEType, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_choiceElectricalType = new wxBitmapComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
+ fgSizerPins->Add( m_choiceElectricalType, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+ m_staticTextGstyle = new wxStaticText( this, wxID_ANY, _("Graphic &Style:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextGstyle->Wrap( -1 );
+ fgSizerPins->Add( m_staticTextGstyle, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_choiceStyle = new wxBitmapComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
+ fgSizerPins->Add( m_choiceStyle, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+
+ bLeftSizer->Add( fgSizerPins, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* boarderSizer;
+ boarderSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbSizerPinSharing;
+ sbSizerPinSharing = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Sharing") ), wxVERTICAL );
+
+ m_checkApplyToAllParts = new wxCheckBox( this, wxID_ANY, _("Common to all &units in component"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerPinSharing->Add( m_checkApplyToAllParts, 0, wxALL, 3 );
+
+ m_checkApplyToAllConversions = new wxCheckBox( this, wxID_ANY, _("Common to all body &styles (DeMorgan)"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerPinSharing->Add( m_checkApplyToAllConversions, 0, wxALL, 3 );
+
+
+ boarderSizer->Add( sbSizerPinSharing, 0, wxEXPAND|wxALL, 5 );
+
+ wxStaticBoxSizer* sbSizerSchematicProperties;
+ sbSizerSchematicProperties = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Schematic Properties") ), wxVERTICAL );
+
+ m_checkShow = new wxCheckBox( this, wxID_ANY, _("&Visible"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkShow->SetValue(true);
+ sbSizerSchematicProperties->Add( m_checkShow, 0, wxALL, 3 );
+
+
+ boarderSizer->Add( sbSizerSchematicProperties, 0, wxEXPAND|wxALL, 5 );
+
+
+ bLeftSizer->Add( boarderSizer, 0, wxEXPAND|wxTOP|wxBOTTOM, 12 );
+
+
+ bUpperSizer->Add( bLeftSizer, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bRightSizer;
+ bRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizerTextsSizes;
+ fgSizerTextsSizes = new wxFlexGridSizer( 3, 3, 0, 0 );
+ fgSizerTextsSizes->AddGrowableCol( 1 );
+ fgSizerTextsSizes->SetFlexibleDirection( wxBOTH );
+ fgSizerTextsSizes->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
+
+ m_staticTextNameSize = new wxStaticText( this, ID_M_STATICTEXTNAMESIZE, _("N&ame text size:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextNameSize->Wrap( -1 );
+ fgSizerTextsSizes->Add( m_staticTextNameSize, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_textPinNameTextSize = new wxTextCtrl( this, ID_M_TEXTPINNAMETEXTSIZE, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textPinNameTextSize->SetMaxLength( 0 );
+ fgSizerTextsSizes->Add( m_textPinNameTextSize, 1, wxEXPAND|wxTOP|wxBOTTOM, 3 );
+
+ m_staticNameTextSizeUnits = new wxStaticText( this, ID_M_STATICNAMETEXTSIZEUNITS, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticNameTextSizeUnits->Wrap( -1 );
+ fgSizerTextsSizes->Add( m_staticNameTextSizeUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_staticTextPadNameSize = new wxStaticText( this, ID_M_STATICTEXTPADNAMESIZE, _("Number te&xt size:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextPadNameSize->Wrap( -1 );
+ fgSizerTextsSizes->Add( m_staticTextPadNameSize, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_textPadNameTextSize = new wxTextCtrl( this, ID_M_TEXTPADNAMETEXTSIZE, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textPadNameTextSize->SetMaxLength( 0 );
+ fgSizerTextsSizes->Add( m_textPadNameTextSize, 0, wxTOP|wxBOTTOM|wxEXPAND, 3 );
+
+ m_staticNumberTextSizeUnits = new wxStaticText( this, ID_M_STATICNUMBERTEXTSIZEUNITS, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticNumberTextSizeUnits->Wrap( -1 );
+ fgSizerTextsSizes->Add( m_staticNumberTextSizeUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_staticTextPinLen = new wxStaticText( this, ID_M_STATICTEXTPINLEN, _("&Length:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextPinLen->Wrap( -1 );
+ fgSizerTextsSizes->Add( m_staticTextPinLen, 0, wxALL, 5 );
+
+ m_textLength = new wxTextCtrl( this, ID_M_TEXTLENGTH, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textLength->SetMaxLength( 0 );
+ fgSizerTextsSizes->Add( m_textLength, 0, wxTOP|wxBOTTOM|wxEXPAND, 5 );
+
+ m_staticLengthUnits = new wxStaticText( this, ID_M_STATICLENGTHUNITS, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticLengthUnits->Wrap( -1 );
+ fgSizerTextsSizes->Add( m_staticLengthUnits, 0, wxALL, 5 );
+
+
+ bRightSizer->Add( fgSizerTextsSizes, 0, wxALL|wxEXPAND, 5 );
+
+ m_panelShowPin = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
+ m_panelShowPin->SetMinSize( wxSize( 150,150 ) );
+
+ bRightSizer->Add( m_panelShowPin, 1, wxEXPAND | wxALL, 5 );
+
+
+ bUpperSizer->Add( bRightSizer, 1, wxEXPAND|wxRIGHT, 5 );
+
+
+ mainSizer->Add( bUpperSizer, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ mainSizer->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_sdbSizerButtons = new wxStdDialogButtonSizer();
+ m_sdbSizerButtonsOK = new wxButton( this, wxID_OK );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsOK );
+ m_sdbSizerButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsCancel );
+ m_sdbSizerButtons->Realize();
+
+ mainSizer->Add( m_sdbSizerButtons, 0, wxALL|wxALIGN_RIGHT, 5 );
+
+
+ this->SetSizer( mainSizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnCloseDialog ) );
+ this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnInitDialog ) );
+ m_textPinName->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_textPadName->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_choiceOrientation->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_choiceElectricalType->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_choiceStyle->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_checkApplyToAllParts->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_checkApplyToAllConversions->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_checkShow->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_textPinNameTextSize->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_textPadNameTextSize->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_textLength->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_panelShowPin->Connect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPaintShowPanel ), NULL, this );
+ m_sdbSizerButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnCancelButtonClick ), NULL, this );
+ m_sdbSizerButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnOKButtonClick ), NULL, this );
+}
+
+DIALOG_LIB_EDIT_PIN_BASE::~DIALOG_LIB_EDIT_PIN_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnCloseDialog ) );
+ this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnInitDialog ) );
+ m_textPinName->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_textPadName->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_choiceOrientation->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_choiceElectricalType->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_choiceStyle->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_checkApplyToAllParts->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_checkApplyToAllConversions->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_checkShow->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_textPinNameTextSize->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_textPadNameTextSize->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_textLength->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPropertiesChange ), NULL, this );
+ m_panelShowPin->Disconnect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnPaintShowPanel ), NULL, this );
+ m_sdbSizerButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnCancelButtonClick ), NULL, this );
+ m_sdbSizerButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_PIN_BASE::OnOKButtonClick ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_lib_edit_pin_base.fbp b/eeschema/dialogs/dialog_lib_edit_pin_base.fbp
new file mode 100644
index 0000000..a4523b0
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_pin_base.fbp
@@ -0,0 +1,2299 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_lib_edit_pin_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_lib_edit_pin</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_LIB_EDIT_PIN_BASE</property>
+ <property name="pos"></property>
+ <property name="size">515,370</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Pin Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseDialog</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog">OnInitDialog</event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">mainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerPins</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_ALL</property>
+ <property name="permission">none</property>
+ <property name="rows">5</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pin &amp;name:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextPinName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_TEXTPINNAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textPinName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnPropertiesChange</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_STATICTEXTPADNAME</property>
+ <property name="label">Pin n&amp;umber:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextPadName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Pin number: 1 to 4 ASCII letters and/or digits</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_TEXTPADNAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textPadName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnPropertiesChange</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Orientation:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextOrient</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceOrientation</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxCB_READONLY</property>
+ <property name="subclass">wxBitmapComboBox; wx/bmpcbox.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox">OnPropertiesChange</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Electrical type:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextEType</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Used by the ERC.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceElectricalType</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxCB_READONLY</property>
+ <property name="subclass">wxBitmapComboBox; wx/bmpcbox.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox">OnPropertiesChange</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Graphic &amp;Style:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextGstyle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceStyle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxCB_READONLY</property>
+ <property name="subclass">wxBitmapComboBox; wx/bmpcbox.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox">OnPropertiesChange</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">12</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">boarderSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Sharing</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerPinSharing</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Common to all &amp;units in component</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkApplyToAllParts</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnPropertiesChange</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Common to all body &amp;styles (DeMorgan)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkApplyToAllConversions</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnPropertiesChange</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Schematic Properties</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerSchematicProperties</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Visible</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkShow</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnPropertiesChange</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerTextsSizes</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_ALL</property>
+ <property name="permission">none</property>
+ <property name="rows">3</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_STATICTEXTNAMESIZE</property>
+ <property name="label">N&amp;ame text size:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextNameSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_TEXTPINNAMETEXTSIZE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textPinNameTextSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnPropertiesChange</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_STATICNAMETEXTSIZEUNITS</property>
+ <property name="label">units</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticNameTextSizeUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_STATICTEXTPADNAMESIZE</property>
+ <property name="label">Number te&amp;xt size:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextPadNameSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_TEXTPADNAMETEXTSIZE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textPadNameTextSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnPropertiesChange</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_STATICNUMBERTEXTSIZEUNITS</property>
+ <property name="label">units</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticNumberTextSizeUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_STATICTEXTPINLEN</property>
+ <property name="label">&amp;Length:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextPinLen</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_TEXTLENGTH</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textLength</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnPropertiesChange</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_STATICLENGTHUNITS</property>
+ <property name="label">units</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticLengthUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">150,150</property>
+ <property name="moveable">1</property>
+ <property name="name">m_panelShowPin</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER|wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint">OnPaintShowPanel</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizerButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelButtonClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKButtonClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_lib_edit_pin_base.h b/eeschema/dialogs/dialog_lib_edit_pin_base.h
new file mode 100644
index 0000000..548601f
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_pin_base.h
@@ -0,0 +1,104 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_LIB_EDIT_PIN_BASE_H__
+#define __DIALOG_LIB_EDIT_PIN_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class wxBitmapComboBox;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/combobox.h>
+#include <wx/sizer.h>
+#include <wx/checkbox.h>
+#include <wx/statbox.h>
+#include <wx/panel.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_LIB_EDIT_PIN_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_LIB_EDIT_PIN_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ ID_M_TEXTPINNAME = 1000,
+ ID_M_STATICTEXTPADNAME,
+ ID_M_TEXTPADNAME,
+ ID_M_STATICTEXTNAMESIZE,
+ ID_M_TEXTPINNAMETEXTSIZE,
+ ID_M_STATICNAMETEXTSIZEUNITS,
+ ID_M_STATICTEXTPADNAMESIZE,
+ ID_M_TEXTPADNAMETEXTSIZE,
+ ID_M_STATICNUMBERTEXTSIZEUNITS,
+ ID_M_STATICTEXTPINLEN,
+ ID_M_TEXTLENGTH,
+ ID_M_STATICLENGTHUNITS
+ };
+
+ wxStaticText* m_staticTextPinName;
+ wxTextCtrl* m_textPinName;
+ wxStaticText* m_staticTextPadName;
+ wxTextCtrl* m_textPadName;
+ wxStaticText* m_staticTextOrient;
+ wxBitmapComboBox* m_choiceOrientation;
+ wxStaticText* m_staticTextEType;
+ wxBitmapComboBox* m_choiceElectricalType;
+ wxStaticText* m_staticTextGstyle;
+ wxBitmapComboBox* m_choiceStyle;
+ wxCheckBox* m_checkApplyToAllParts;
+ wxCheckBox* m_checkApplyToAllConversions;
+ wxCheckBox* m_checkShow;
+ wxStaticText* m_staticTextNameSize;
+ wxTextCtrl* m_textPinNameTextSize;
+ wxStaticText* m_staticNameTextSizeUnits;
+ wxStaticText* m_staticTextPadNameSize;
+ wxTextCtrl* m_textPadNameTextSize;
+ wxStaticText* m_staticNumberTextSizeUnits;
+ wxStaticText* m_staticTextPinLen;
+ wxTextCtrl* m_textLength;
+ wxStaticText* m_staticLengthUnits;
+ wxPanel* m_panelShowPin;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizerButtons;
+ wxButton* m_sdbSizerButtonsOK;
+ wxButton* m_sdbSizerButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseDialog( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
+ virtual void OnPropertiesChange( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPaintShowPanel( wxPaintEvent& event ) { event.Skip(); }
+ virtual void OnCancelButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_LIB_EDIT_PIN_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Pin Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 515,370 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_LIB_EDIT_PIN_BASE();
+
+};
+
+#endif //__DIALOG_LIB_EDIT_PIN_BASE_H__
diff --git a/eeschema/dialogs/dialog_lib_edit_pin_table.cpp b/eeschema/dialogs/dialog_lib_edit_pin_table.cpp
new file mode 100644
index 0000000..dc39b53
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_pin_table.cpp
@@ -0,0 +1,584 @@
+#include "dialog_lib_edit_pin_table.h"
+
+#include "lib_pin.h"
+
+#include <boost/algorithm/string/join.hpp>
+#include <queue>
+
+/* Avoid wxWidgets bug #16906 -- http://trac.wxwidgets.org/ticket/16906
+ *
+ * If multiple elements live in the root of a wxDataViewCtrl, using
+ * ItemsAdded() can run into an assertion failure. To avoid this, we avoid
+ * notifying the widget of changes, but rather reinitialize it.
+ *
+ * When a fix for this exists in wxWidgets, this is the place to turn it
+ * off.
+ */
+#define REASSOCIATE_HACK
+
+class DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel :
+ public wxDataViewModel
+{
+public:
+ DataViewModel( LIB_PART& aPart );
+
+ // wxDataViewModel
+ virtual unsigned int GetColumnCount() const;
+ virtual wxString GetColumnType( unsigned int col ) const;
+ virtual void GetValue( wxVariant&, const wxDataViewItem&, unsigned int ) const;
+ virtual bool SetValue( const wxVariant&, const wxDataViewItem&, unsigned int );
+ virtual wxDataViewItem GetParent( const wxDataViewItem& ) const;
+ virtual bool IsContainer( const wxDataViewItem& ) const;
+ virtual bool HasContainerColumns( const wxDataViewItem& ) const;
+ virtual unsigned int GetChildren( const wxDataViewItem&, wxDataViewItemArray& ) const;
+
+ virtual int Compare( const wxDataViewItem& lhs,
+ const wxDataViewItem& rhs,
+ unsigned int col,
+ bool ascending ) const;
+
+ void SetGroupingColumn( int aCol );
+ void CalculateGrouping();
+ void Refresh();
+
+#ifdef REASSOCIATE_HACK
+ void SetWidget( wxDataViewCtrl* aWidget ) { m_Widget = aWidget; }
+#endif
+
+ enum
+ {
+ NONE = -1,
+ PIN_NUMBER = 0,
+ PIN_NAME = 1,
+ PIN_TYPE = 2,
+ PIN_POSITION = 3
+ };
+
+private:
+ LIB_PART& m_Part;
+ LIB_PINS m_Backing;
+ int m_GroupingColumn;
+ int m_UnitCount;
+
+ class Item;
+ class Group;
+ class Pin;
+
+ mutable std::list<Pin> m_Pins;
+ mutable std::map<wxString, Group> m_Groups;
+
+#ifdef REASSOCIATE_HACK
+ wxDataViewCtrl* m_Widget;
+#endif
+};
+
+class DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::Item
+{
+public:
+ virtual void GetValue( wxVariant& aValue, unsigned int aCol ) const = 0;
+ virtual wxDataViewItem GetParent() const = 0;
+ virtual bool IsContainer() const = 0;
+ virtual unsigned int GetChildren( wxDataViewItemArray& ) const = 0;
+};
+
+class DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::Group :
+ public Item
+{
+public:
+ Group( unsigned int aGroupingColumn ) : m_GroupingColumn( aGroupingColumn ) {}
+
+ virtual void GetValue( wxVariant& aValue, unsigned int aCol ) const;
+
+ virtual wxDataViewItem GetParent() const { return wxDataViewItem(); }
+ virtual bool IsContainer() const { return true; }
+ virtual unsigned int GetChildren( wxDataViewItemArray& aItems ) const
+ {
+ /// @todo C++11
+ for( std::list<Pin*>::const_iterator i = m_Members.begin(); i != m_Members.end(); ++i )
+ aItems.push_back( wxDataViewItem( *i ) );
+
+ return aItems.size();
+ }
+
+ unsigned int GetCount() const { return m_Members.size(); }
+ void Add( Pin* aPin );
+
+private:
+ std::list<Pin*> m_Members;
+ unsigned int m_GroupingColumn;
+};
+
+class DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::Pin :
+ public Item
+{
+public:
+ Pin( DataViewModel& aModel,
+ LIB_PIN* aBacking ) : m_Model( aModel ), m_Backing( aBacking ), m_Group( 0 ) {}
+
+ virtual void GetValue( wxVariant& aValue, unsigned int aCol ) const;
+
+ virtual wxDataViewItem GetParent() const { return wxDataViewItem( m_Group ); }
+ virtual bool IsContainer() const { return false; }
+ virtual unsigned int GetChildren( wxDataViewItemArray& ) const { return 0; }
+
+ void SetGroup( Group* aGroup ) { m_Group = aGroup; }
+
+private:
+ DataViewModel& m_Model;
+ LIB_PIN* m_Backing;
+ Group* m_Group;
+};
+
+DIALOG_LIB_EDIT_PIN_TABLE::DIALOG_LIB_EDIT_PIN_TABLE( wxWindow* parent,
+ LIB_PART& aPart ) :
+ DIALOG_LIB_EDIT_PIN_TABLE_BASE( parent ),
+ m_Model( new DataViewModel( aPart ) )
+{
+#ifdef REASSOCIATE_HACK
+ m_Model->SetWidget( m_Pins );
+#endif
+ m_Pins->AssociateModel( m_Model.get() );
+
+ /// @todo wxFormBuilder bug #61 -- move to base once supported
+ wxDataViewTextRenderer* rend0 = new wxDataViewTextRenderer( wxT( "string" ), wxDATAVIEW_CELL_INERT );
+ wxDataViewColumn* col0 = new wxDataViewColumn( _( "Number" ),
+ rend0,
+ DataViewModel::PIN_NUMBER,
+ 100,
+ wxAlignment( wxALIGN_LEFT | wxALIGN_TOP ),
+ wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE );
+ wxDataViewTextRenderer* rend1 = new wxDataViewTextRenderer( wxT( "string" ), wxDATAVIEW_CELL_INERT );
+ wxDataViewColumn* col1 = new wxDataViewColumn( _( "Name" ),
+ rend1,
+ DataViewModel::PIN_NAME,
+ 100,
+ wxAlignment( wxALIGN_LEFT | wxALIGN_TOP ),
+ wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE );
+ wxDataViewTextRenderer* rend2 = new wxDataViewTextRenderer( wxT( "string" ), wxDATAVIEW_CELL_INERT );
+ wxDataViewColumn* col2 = new wxDataViewColumn( _( "Type" ),
+ rend2,
+ DataViewModel::PIN_TYPE,
+ 100,
+ wxAlignment( wxALIGN_LEFT | wxALIGN_TOP ),
+ wxDATAVIEW_COL_RESIZABLE );
+ wxDataViewTextRenderer* rend3 = new wxDataViewTextRenderer( wxT( "string" ), wxDATAVIEW_CELL_INERT );
+ wxDataViewColumn* col3 = new wxDataViewColumn( _( "Position" ),
+ rend3,
+ DataViewModel::PIN_POSITION,
+ 100,
+ wxAlignment( wxALIGN_LEFT | wxALIGN_TOP ),
+ wxDATAVIEW_COL_RESIZABLE );
+ m_Pins->AppendColumn( col0 );
+ m_Pins->SetExpanderColumn( col0 );
+ m_Pins->AppendColumn( col1 );
+ m_Pins->AppendColumn( col2 );
+ m_Pins->AppendColumn( col3 );
+
+ GetSizer()->SetSizeHints(this);
+ Centre();
+}
+
+
+DIALOG_LIB_EDIT_PIN_TABLE::~DIALOG_LIB_EDIT_PIN_TABLE()
+{
+}
+
+
+void DIALOG_LIB_EDIT_PIN_TABLE::OnColumnHeaderRightClicked( wxDataViewEvent& event )
+{
+ m_Model->SetGroupingColumn( event.GetDataViewColumn()->GetModelColumn() );
+ event.Skip();
+}
+
+
+DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::DataViewModel( LIB_PART& aPart ) :
+ m_Part( aPart ),
+ m_GroupingColumn( 1 ),
+ m_UnitCount( m_Part.GetUnitCount() )
+{
+#ifdef REASSOCIATE_HACK
+ m_Widget = NULL;
+#endif
+ aPart.GetPins( m_Backing );
+ /// @todo C++11
+ for( LIB_PINS::const_iterator i = m_Backing.begin(); i != m_Backing.end(); ++i )
+ m_Pins.push_back( Pin( *this, *i ) );
+
+ CalculateGrouping();
+}
+
+
+unsigned int DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::GetColumnCount() const
+{
+ return 4;
+}
+
+
+wxString DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::GetColumnType( unsigned int aCol ) const
+{
+ return wxT( "string" );
+}
+
+
+void DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::GetValue( wxVariant& aVal,
+ const wxDataViewItem& aItem,
+ unsigned int aCol ) const
+{
+ assert( aItem.IsOk() );
+
+ reinterpret_cast<Item const*>( aItem.GetID() )->GetValue( aVal, aCol );
+}
+
+
+bool DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::SetValue( const wxVariant&,
+ const wxDataViewItem&,
+ unsigned int )
+{
+ return false;
+}
+
+
+wxDataViewItem DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::GetParent( const wxDataViewItem& aItem )
+const
+{
+ assert( aItem.IsOk() );
+
+ return reinterpret_cast<Item const*>( aItem.GetID() )->GetParent();
+}
+
+
+bool DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::IsContainer( const wxDataViewItem& aItem ) const
+{
+ if( aItem.IsOk() )
+ return reinterpret_cast<Item const*>( aItem.GetID() )->IsContainer();
+ else
+ return true;
+}
+
+
+bool DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::HasContainerColumns( const wxDataViewItem& ) const
+{
+ return true;
+}
+
+
+unsigned int DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::GetChildren( const wxDataViewItem& aItem,
+ wxDataViewItemArray& aItems ) const
+{
+ if( !aItem.IsOk() )
+ {
+ for( std::map<wxString, Group>::iterator i = m_Groups.begin(); i != m_Groups.end(); ++i )
+ if( i->second.GetCount() > 1 )
+ aItems.push_back( wxDataViewItem( &i->second ) );
+
+ for( std::list<Pin>::iterator i = m_Pins.begin(); i != m_Pins.end(); ++i )
+ if( !i->GetParent().IsOk() )
+ aItems.push_back( wxDataViewItem( &*i ) );
+
+ return aItems.size();
+ }
+ else
+ return reinterpret_cast<Item const*>( aItem.GetID() )->GetChildren( aItems );
+}
+
+
+namespace {
+wxString GetNextComponent( const wxString& str, wxString::size_type& cursor )
+{
+ if( str.size() <= cursor )
+ return wxEmptyString;
+
+ wxString::size_type begin = cursor;
+
+ wxUniChar c = str[cursor];
+
+ if( isdigit( c ) || c == '+' || c == '-' )
+ {
+ // number, possibly with sign
+ while( ++cursor < str.size() )
+ {
+ c = str[cursor];
+
+ if( isdigit( c ) || c == 'v' || c == 'V' )
+ continue;
+ else
+ break;
+ }
+ }
+ else
+ {
+ while( ++cursor < str.size() )
+ {
+ c = str[cursor];
+
+ if( isdigit( c ) )
+ break;
+ else
+ continue;
+ }
+ }
+
+ return str.substr( begin, cursor - begin );
+}
+
+
+int ComparePinNames( const wxString& lhs, const wxString& rhs )
+{
+ wxString::size_type cursor1 = 0;
+ wxString::size_type cursor2 = 0;
+
+ wxString comp1, comp2;
+
+ for( ; ; )
+ {
+ comp1 = GetNextComponent( lhs, cursor1 );
+ comp2 = GetNextComponent( rhs, cursor2 );
+
+ if( comp1.empty() && comp2.empty() )
+ return 0;
+
+ if( comp1.empty() )
+ return -1;
+
+ if( comp2.empty() )
+ return 1;
+
+ wxUniChar c1 = comp1[0];
+ wxUniChar c2 = comp2[0];
+
+ if( isdigit( c1 ) || c1 == '-' || c1 == '+' )
+ {
+ if( isdigit( c2 ) || c2 == '-' || c2 == '+' )
+ {
+ // numeric comparison
+ wxString::size_type v1 = comp1.find_first_of( "vV" );
+
+ if( v1 != wxString::npos )
+ comp1[v1] = '.';
+
+ wxString::size_type v2 = comp2.find_first_of( "vV" );
+
+ if( v2 != wxString::npos )
+ comp2[v2] = '.';
+
+ double val1, val2;
+
+ comp1.ToDouble( &val1 );
+ comp2.ToDouble( &val2 );
+
+ if( val1 < val2 )
+ return -1;
+
+ if( val1 > val2 )
+ return 1;
+ }
+ else
+ return -1;
+ }
+ else
+ {
+ if( isdigit( c2 ) || c2 == '-' || c2 == '+' )
+ return 1;
+
+ int res = comp1.Cmp( comp2 );
+
+ if( res != 0 )
+ return res;
+ }
+ }
+}
+
+
+class CompareLess
+{
+public:
+ bool operator()( const wxString& lhs, const wxString& rhs )
+ {
+ return ComparePinNames( lhs, rhs ) == -1;
+ }
+};
+}
+
+int DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::Compare( const wxDataViewItem& aItem1,
+ const wxDataViewItem& aItem2,
+ unsigned int aCol,
+ bool aAscending ) const
+{
+ wxVariant var1;
+
+ GetValue( var1, aItem1, aCol );
+ wxString str1 = var1.GetString();
+
+ wxVariant var2;
+ GetValue( var2, aItem2, aCol );
+ wxString str2 = var2.GetString();
+
+ int res = ComparePinNames( str1, str2 );
+
+ if( res == 0 )
+ res = ( aItem1.GetID() < aItem2.GetID() ) ? -1 : 1;
+
+ return res * ( aAscending ? 1 : -1 );
+}
+
+
+void DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::SetGroupingColumn( int aCol )
+{
+ if( m_GroupingColumn == aCol )
+ return;
+
+ m_GroupingColumn = aCol;
+
+ Cleared();
+ CalculateGrouping();
+ Refresh();
+}
+
+
+void DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::CalculateGrouping()
+{
+ m_Groups.clear();
+
+ if( m_GroupingColumn != -1 )
+ {
+ wxVariant value;
+
+ for( std::list<Pin>::iterator i = m_Pins.begin(); i != m_Pins.end(); ++i )
+ {
+ i->GetValue( value, m_GroupingColumn );
+ wxString str = value.GetString();
+ std::map<wxString, Group>::iterator j = m_Groups.find( str );
+
+ if( j == m_Groups.end() )
+ j = m_Groups.insert( std::make_pair( str, m_GroupingColumn ) ).first;
+
+ j->second.Add( &*i );
+ }
+ }
+ else
+ {
+ for( std::list<Pin>::iterator i = m_Pins.begin(); i != m_Pins.end(); ++i )
+ i->SetGroup( 0 );
+ }
+}
+
+
+void DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::Refresh()
+{
+#ifdef REASSOCIATE_HACK
+ m_Widget->AssociateModel( this );
+#else
+ std::queue<wxDataViewItem> todo;
+ todo.push( wxDataViewItem() );
+
+ while( !todo.empty() )
+ {
+ wxDataViewItem current = todo.front();
+ wxDataViewItemArray items;
+
+ GetChildren( current, items );
+ ItemsAdded( current, items );
+
+ for( wxDataViewItemArray::const_iterator i = items.begin(); i != items.end(); ++i )
+ {
+ if( IsContainer( *i ) )
+ todo.push( *i );
+ }
+
+ todo.pop();
+ }
+
+#endif
+}
+
+
+void DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::Group::GetValue( wxVariant& aValue,
+ unsigned int aCol ) const
+{
+ if( aCol == m_GroupingColumn )
+ {
+ // shortcut
+ m_Members.front()->GetValue( aValue, aCol );
+ }
+ else
+ {
+ std::set<wxString, CompareLess> values;
+
+ for( std::list<Pin*>::const_iterator i = m_Members.begin(); i != m_Members.end(); ++i )
+ {
+ wxVariant value;
+ (*i)->GetValue( value, aCol );
+ values.insert( value.GetString() );
+ }
+
+ aValue = boost::algorithm::join( values, "," );
+ }
+}
+
+
+void DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::Group::Add( Pin* aPin )
+{
+ switch( GetCount() )
+ {
+ case 0:
+ aPin->SetGroup( 0 );
+ break;
+
+ case 1:
+ m_Members.front()->SetGroup( this );
+ // fall through
+
+ default:
+ aPin->SetGroup( this );
+ }
+
+ m_Members.push_back( aPin );
+}
+
+
+void DIALOG_LIB_EDIT_PIN_TABLE::DataViewModel::Pin::GetValue( wxVariant& aValue,
+ unsigned int aCol ) const
+{
+ switch( aCol )
+ {
+ case PIN_NUMBER:
+ aValue = m_Backing->GetNumberString();
+ break;
+
+ case PIN_NAME:
+ {
+ if( m_Model.m_UnitCount > 1 )
+ {
+ wxString name;
+ int unit = m_Backing->GetPartNumber();
+
+ if( unit )
+ name << unit;
+ else
+ name << "com";
+
+ name << ':';
+ name << m_Backing->GetName();
+ aValue = name;
+ }
+ else
+ {
+ aValue = m_Backing->GetName();
+ }
+ }
+ break;
+
+ case PIN_TYPE:
+ aValue = m_Backing->GetElectricalTypeName();
+ break;
+
+ case PIN_POSITION:
+ {
+ wxPoint position = m_Backing->GetPosition();
+ wxString value;
+ value << "(" << position.x << "," << position.y << ")";
+ aValue = value;
+ }
+ break;
+ }
+}
diff --git a/eeschema/dialogs/dialog_lib_edit_pin_table.h b/eeschema/dialogs/dialog_lib_edit_pin_table.h
new file mode 100644
index 0000000..345a77c
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_pin_table.h
@@ -0,0 +1,18 @@
+#include "dialog_lib_edit_pin_table_base.h"
+
+#include "class_library.h"
+
+class DIALOG_LIB_EDIT_PIN_TABLE :
+ public DIALOG_LIB_EDIT_PIN_TABLE_BASE
+{
+public:
+ DIALOG_LIB_EDIT_PIN_TABLE( wxWindow* parent, LIB_PART& aPart );
+ ~DIALOG_LIB_EDIT_PIN_TABLE();
+
+ virtual void OnColumnHeaderRightClicked( wxDataViewEvent& aEvent );
+
+private:
+ class DataViewModel;
+
+ wxObjectDataPtr<DataViewModel> m_Model;
+};
diff --git a/eeschema/dialogs/dialog_lib_edit_pin_table_base.cpp b/eeschema/dialogs/dialog_lib_edit_pin_table_base.cpp
new file mode 100644
index 0000000..3e82df5
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_pin_table_base.cpp
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_lib_edit_pin_table_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_LIB_EDIT_PIN_TABLE_BASE::DIALOG_LIB_EDIT_PIN_TABLE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* top_sizer;
+ top_sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_Pins = new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxDV_HORIZ_RULES|wxDV_MULTIPLE|wxDV_ROW_LINES|wxDV_VERT_RULES );
+ m_Pins->SetMinSize( wxSize( 400,400 ) );
+
+ top_sizer->Add( m_Pins, 1, wxALL|wxEXPAND, 5 );
+
+ m_Buttons = new wxStdDialogButtonSizer();
+ m_ButtonsOK = new wxButton( this, wxID_OK );
+ m_Buttons->AddButton( m_ButtonsOK );
+ m_Buttons->Realize();
+
+ top_sizer->Add( m_Buttons, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( top_sizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxID_ANY, wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, wxDataViewEventHandler( DIALOG_LIB_EDIT_PIN_TABLE_BASE::OnColumnHeaderRightClicked ) );
+}
+
+DIALOG_LIB_EDIT_PIN_TABLE_BASE::~DIALOG_LIB_EDIT_PIN_TABLE_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxID_ANY, wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, wxDataViewEventHandler( DIALOG_LIB_EDIT_PIN_TABLE_BASE::OnColumnHeaderRightClicked ) );
+
+}
diff --git a/eeschema/dialogs/dialog_lib_edit_pin_table_base.fbp b/eeschema/dialogs/dialog_lib_edit_pin_table_base.fbp
new file mode 100644
index 0000000..b618c10
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_pin_table_base.fbp
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_lib_edit_pin_table_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_lib_edit_pin_table</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">decl_pure_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_LIB_EDIT_PIN_TABLE_BASE</property>
+ <property name="pos"></property>
+ <property name="size">431,304</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Pin Table</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">top_sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxDataViewCtrl" expanded="1">
+ <property name="bg"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">400,400</property>
+ <property name="name">m_Pins</property>
+ <property name="permission">protected</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDV_HORIZ_RULES|wxDV_MULTIPLE|wxDV_ROW_LINES|wxDV_VERT_RULES</property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnDataViewCtrlColumnHeaderClick"></event>
+ <event name="OnDataViewCtrlColumnHeaderRightClick">OnColumnHeaderRightClicked</event>
+ <event name="OnDataViewCtrlColumnReordered"></event>
+ <event name="OnDataViewCtrlColumnSorted"></event>
+ <event name="OnDataViewCtrlItemActivated"></event>
+ <event name="OnDataViewCtrlItemBeginDrag"></event>
+ <event name="OnDataViewCtrlItemCollapsed"></event>
+ <event name="OnDataViewCtrlItemCollapsing"></event>
+ <event name="OnDataViewCtrlItemContextMenu"></event>
+ <event name="OnDataViewCtrlItemDrop"></event>
+ <event name="OnDataViewCtrlItemDropPossible"></event>
+ <event name="OnDataViewCtrlItemEditingDone"></event>
+ <event name="OnDataViewCtrlItemEditingStarted"></event>
+ <event name="OnDataViewCtrlItemExpanded"></event>
+ <event name="OnDataViewCtrlItemExpanding"></event>
+ <event name="OnDataViewCtrlItemStartEditing"></event>
+ <event name="OnDataViewCtrlItemValueChanged"></event>
+ <event name="OnDataViewCtrlSelectionChanged"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">0</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_Buttons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_lib_edit_pin_table_base.h b/eeschema/dialogs/dialog_lib_edit_pin_table_base.h
new file mode 100644
index 0000000..5763e40
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_pin_table_base.h
@@ -0,0 +1,53 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_LIB_EDIT_PIN_TABLE_BASE_H__
+#define __DIALOG_LIB_EDIT_PIN_TABLE_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/dataview.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/string.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_LIB_EDIT_PIN_TABLE_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_LIB_EDIT_PIN_TABLE_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxDataViewCtrl* m_Pins;
+ wxStdDialogButtonSizer* m_Buttons;
+ wxButton* m_ButtonsOK;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnColumnHeaderRightClicked( wxDataViewEvent& event ) = 0;
+
+
+ public:
+
+ DIALOG_LIB_EDIT_PIN_TABLE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Pin Table"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 431,304 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_LIB_EDIT_PIN_TABLE_BASE();
+
+};
+
+#endif //__DIALOG_LIB_EDIT_PIN_TABLE_BASE_H__
diff --git a/eeschema/dialogs/dialog_lib_edit_text.cpp b/eeschema/dialogs/dialog_lib_edit_text.cpp
new file mode 100644
index 0000000..a1c7cee
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_text.cpp
@@ -0,0 +1,222 @@
+/**
+ * @file dialog_lib_edit_text.cpp
+ * @brief dialog to editing graphic texts (not fields) in body components.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2001 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <base_units.h>
+
+#include <general.h>
+#include <libeditframe.h>
+#include <class_libentry.h>
+#include <lib_text.h>
+
+#include <dialog_lib_edit_text.h>
+
+
+DIALOG_LIB_EDIT_TEXT::DIALOG_LIB_EDIT_TEXT( LIB_EDIT_FRAME* aParent, LIB_TEXT* aText ) :
+ DIALOG_LIB_EDIT_TEXT_BASE( aParent )
+{
+ m_parent = aParent;
+ m_graphicText = aText;
+ initDlg();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void DIALOG_LIB_EDIT_TEXT::initDlg( )
+{
+ wxString msg;
+
+ m_TextValue->SetFocus();
+
+ // Disable options for fieldedition, not existing in graphic text
+ m_Invisible->Show(false);
+
+ if ( m_graphicText )
+ {
+ msg = StringFromValue( g_UserUnit, m_graphicText->GetSize().x );
+ m_TextSize->SetValue( msg );
+ m_TextValue->SetValue( m_graphicText->GetText() );
+
+ if ( m_graphicText->GetUnit() == 0 )
+ m_CommonUnit->SetValue( true );
+ if ( m_graphicText->GetConvert() == 0 )
+ m_CommonConvert->SetValue( true );
+ if ( m_graphicText->GetOrientation() == TEXT_ORIENT_VERT )
+ m_Orient->SetValue( true );
+
+ int shape = 0;
+ if ( m_graphicText->IsItalic() )
+ shape = 1;
+ if ( m_graphicText->IsBold() )
+ shape |= 2;
+
+ m_TextShapeOpt->SetSelection( shape );
+
+ switch ( m_graphicText->GetHorizJustify() )
+ {
+ case GR_TEXT_HJUSTIFY_LEFT:
+ m_TextHJustificationOpt->SetSelection( 0 );
+ break;
+
+ case GR_TEXT_HJUSTIFY_CENTER:
+ m_TextHJustificationOpt->SetSelection( 1 );
+ break;
+
+ case GR_TEXT_HJUSTIFY_RIGHT:
+ m_TextHJustificationOpt->SetSelection( 2 );
+ break;
+
+ }
+
+ switch ( m_graphicText->GetVertJustify() )
+ {
+ case GR_TEXT_VJUSTIFY_BOTTOM:
+ m_TextVJustificationOpt->SetSelection( 0 );
+ break;
+
+ case GR_TEXT_VJUSTIFY_CENTER:
+ m_TextVJustificationOpt->SetSelection( 1 );
+ break;
+
+ case GR_TEXT_VJUSTIFY_TOP:
+ m_TextVJustificationOpt->SetSelection( 2 );
+ break;
+ }
+ }
+ else
+ {
+ msg = StringFromValue( g_UserUnit, m_parent->m_textSize );
+ m_TextSize->SetValue( msg );
+
+ if ( ! m_parent->m_drawSpecificUnit )
+ m_CommonUnit->SetValue( true );
+ if ( ! m_parent->m_drawSpecificConvert )
+ m_CommonConvert->SetValue( true );
+ if ( m_parent->m_textOrientation == TEXT_ORIENT_VERT )
+ m_Orient->SetValue( true );
+ }
+
+ msg = m_TextSizeText->GetLabel() + ReturnUnitSymbol();
+ m_TextSizeText->SetLabel( msg );
+
+ m_sdbSizerButtonsOK->SetDefault();
+
+ // Hide the select button as the child dialog classes use this
+ m_TextValueSelectButton->Hide();
+
+ // Hide the "Power component value text cannot be modified!" warning
+ m_PowerComponentValues->Show( false );
+ Fit();
+}
+
+
+void DIALOG_LIB_EDIT_TEXT::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal(wxID_CANCEL);
+}
+
+
+/* Updates the different parameters for the component being edited */
+void DIALOG_LIB_EDIT_TEXT::OnOkClick( wxCommandEvent& event )
+{
+ wxString Line;
+
+ Line = m_TextValue->GetValue();
+ m_parent->m_textOrientation = m_Orient->GetValue() ? TEXT_ORIENT_VERT : TEXT_ORIENT_HORIZ;
+ wxString msg = m_TextSize->GetValue();
+ m_parent->m_textSize = ValueFromString( g_UserUnit, msg );
+ m_parent->m_drawSpecificConvert = m_CommonConvert->GetValue() ? false : true;
+ m_parent->m_drawSpecificUnit = m_CommonUnit->GetValue() ? false : true;
+
+ if( m_graphicText )
+ {
+ if( ! Line.IsEmpty() )
+ m_graphicText->SetText( Line );
+ else
+ m_graphicText->SetText( wxT( "[null]" ) );
+
+ m_graphicText->SetSize( wxSize( m_parent->m_textSize, m_parent->m_textSize ) );
+ m_graphicText->SetOrientation( m_parent->m_textOrientation );
+
+ if( m_parent->m_drawSpecificUnit )
+ m_graphicText->SetUnit( m_parent->GetUnit() );
+ else
+ m_graphicText->SetUnit( 0 );
+
+ if( m_parent->m_drawSpecificConvert )
+ m_graphicText->SetConvert( m_parent->GetConvert() );
+ else
+ m_graphicText->SetConvert( 0 );
+
+ m_graphicText->SetItalic( ( m_TextShapeOpt->GetSelection() & 1 ) != 0 );
+ m_graphicText->SetBold( ( m_TextShapeOpt->GetSelection() & 2 ) != 0 );
+
+ switch( m_TextHJustificationOpt->GetSelection() )
+ {
+ case 0:
+ m_graphicText->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ break;
+
+ case 1:
+ m_graphicText->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
+ break;
+
+ case 2:
+ m_graphicText->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ break;
+ }
+
+ switch( m_TextVJustificationOpt->GetSelection() )
+ {
+ case 0:
+ m_graphicText->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+ break;
+
+ case 1:
+ m_graphicText->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
+ break;
+
+ case 2:
+ m_graphicText->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
+ break;
+ }
+ }
+
+ if( m_parent->GetDrawItem() )
+ m_parent->SetMsgPanel( m_parent->GetDrawItem() );
+
+ EndModal(wxID_OK);
+}
diff --git a/eeschema/dialogs/dialog_lib_edit_text.h b/eeschema/dialogs/dialog_lib_edit_text.h
new file mode 100644
index 0000000..24ad589
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_text.h
@@ -0,0 +1,54 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2001 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef _DIALOG_LIB_EDIT_TEXT_H_
+#define _DIALOG_LIB_EDIT_TEXT_H_
+
+
+#include <dialog_lib_edit_text_base.h>
+
+
+class LIB_EDIT_FRAME;
+class LIB_TEXT;
+
+
+class DIALOG_LIB_EDIT_TEXT : public DIALOG_LIB_EDIT_TEXT_BASE
+{
+private:
+ LIB_EDIT_FRAME* m_parent;
+ LIB_TEXT* m_graphicText;
+
+public:
+ DIALOG_LIB_EDIT_TEXT( LIB_EDIT_FRAME* aParent, LIB_TEXT* aText );
+ ~DIALOG_LIB_EDIT_TEXT() {};
+
+private:
+ void initDlg( );
+ void OnOkClick( wxCommandEvent& aEvent );
+ void OnCancelClick( wxCommandEvent& aEvent );
+};
+
+
+#endif // _DIALOG_LIB_EDIT_TEXT_H_
diff --git a/eeschema/dialogs/dialog_lib_edit_text_base.cpp b/eeschema/dialogs/dialog_lib_edit_text_base.cpp
new file mode 100644
index 0000000..5ba9cd5
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_text_base.cpp
@@ -0,0 +1,150 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_lib_edit_text_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_LIB_EDIT_TEXT_BASE::DIALOG_LIB_EDIT_TEXT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bPropertiesSizer;
+ bPropertiesSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperBoxSizer;
+ bUpperBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bTextValueBoxSizer;
+ bTextValueBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText1 = new wxStaticText( this, wxID_ANY, _("Text"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ bTextValueBoxSizer->Add( m_staticText1, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bTextValueOptsSizer;
+ bTextValueOptsSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ m_TextValue = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextValue->SetMaxLength( 0 );
+ m_TextValue->SetMinSize( wxSize( 200,-1 ) );
+
+ bTextValueOptsSizer->Add( m_TextValue, 1, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5 );
+
+ m_TextValueSelectButton = new wxButton( this, wxID_ANY, _("Select"), wxDefaultPosition, wxDefaultSize, 0 );
+ bTextValueOptsSizer->Add( m_TextValueSelectButton, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bTextValueBoxSizer->Add( bTextValueOptsSizer, 1, wxEXPAND, 5 );
+
+
+ bUpperBoxSizer->Add( bTextValueBoxSizer, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bTextSizeSizer;
+ bTextSizeSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_TextSizeText = new wxStaticText( this, wxID_ANY, _("Size"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextSizeText->Wrap( -1 );
+ bTextSizeSizer->Add( m_TextSizeText, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_TextSize = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextSize->SetMaxLength( 0 );
+ bTextSizeSizer->Add( m_TextSize, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+
+ bUpperBoxSizer->Add( bTextSizeSizer, 0, wxEXPAND, 5 );
+
+
+ bPropertiesSizer->Add( bUpperBoxSizer, 0, wxEXPAND, 5 );
+
+ m_PowerComponentValues = new wxStaticText( this, wxID_ANY, _("Power component value text cannot be modified!"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PowerComponentValues->Wrap( -1 );
+ m_PowerComponentValues->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bPropertiesSizer->Add( m_PowerComponentValues, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bBottomtBoxSizer;
+ bBottomtBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sOptionsSizer;
+ sOptionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options") ), wxVERTICAL );
+
+ m_Orient = new wxCheckBox( this, wxID_ANY, _("Vertical"), wxDefaultPosition, wxDefaultSize, 0 );
+ sOptionsSizer->Add( m_Orient, 0, wxALL, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ sOptionsSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_CommonUnit = new wxCheckBox( this, wxID_ANY, _("Common to all units"), wxDefaultPosition, wxDefaultSize, 0 );
+ sOptionsSizer->Add( m_CommonUnit, 0, wxALL, 5 );
+
+ m_CommonConvert = new wxCheckBox( this, wxID_ANY, _("Common to all body styles"), wxDefaultPosition, wxDefaultSize, 0 );
+ sOptionsSizer->Add( m_CommonConvert, 0, wxALL|wxEXPAND, 5 );
+
+ m_Invisible = new wxCheckBox( this, wxID_ANY, _("Invisible"), wxDefaultPosition, wxDefaultSize, 0 );
+ sOptionsSizer->Add( m_Invisible, 0, wxALL, 5 );
+
+
+ bBottomtBoxSizer->Add( sOptionsSizer, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_TextShapeOptChoices[] = { _("Normal"), _("Italic"), _("Bold"), _("Bold Italic") };
+ int m_TextShapeOptNChoices = sizeof( m_TextShapeOptChoices ) / sizeof( wxString );
+ m_TextShapeOpt = new wxRadioBox( this, wxID_ANY, _("Style"), wxDefaultPosition, wxDefaultSize, m_TextShapeOptNChoices, m_TextShapeOptChoices, 1, wxRA_SPECIFY_COLS );
+ m_TextShapeOpt->SetSelection( 0 );
+ bBottomtBoxSizer->Add( m_TextShapeOpt, 1, wxALL|wxEXPAND, 5 );
+
+ wxString m_TextHJustificationOptChoices[] = { _("Align left"), _("Align center"), _("Align right") };
+ int m_TextHJustificationOptNChoices = sizeof( m_TextHJustificationOptChoices ) / sizeof( wxString );
+ m_TextHJustificationOpt = new wxRadioBox( this, wxID_ANY, _("Horizontal Justify"), wxDefaultPosition, wxDefaultSize, m_TextHJustificationOptNChoices, m_TextHJustificationOptChoices, 1, wxRA_SPECIFY_COLS );
+ m_TextHJustificationOpt->SetSelection( 1 );
+ bBottomtBoxSizer->Add( m_TextHJustificationOpt, 1, wxALL|wxEXPAND, 5 );
+
+ wxString m_TextVJustificationOptChoices[] = { _("Align bottom"), _("Align center"), _("Align top") };
+ int m_TextVJustificationOptNChoices = sizeof( m_TextVJustificationOptChoices ) / sizeof( wxString );
+ m_TextVJustificationOpt = new wxRadioBox( this, wxID_ANY, _("Vertical Justify"), wxDefaultPosition, wxDefaultSize, m_TextVJustificationOptNChoices, m_TextVJustificationOptChoices, 1, wxRA_SPECIFY_COLS );
+ m_TextVJustificationOpt->SetSelection( 1 );
+ bBottomtBoxSizer->Add( m_TextVJustificationOpt, 1, wxALL|wxEXPAND, 5 );
+
+
+ bPropertiesSizer->Add( bBottomtBoxSizer, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bPropertiesSizer, 1, wxEXPAND, 6 );
+
+ m_sdbSizerButtons = new wxStdDialogButtonSizer();
+ m_sdbSizerButtonsOK = new wxButton( this, wxID_OK );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsOK );
+ m_sdbSizerButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsCancel );
+ m_sdbSizerButtons->Realize();
+
+ bMainSizer->Add( m_sdbSizerButtons, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnCloseDialog ) );
+ m_TextValueSelectButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnTextValueSelectButtonClick ), NULL, this );
+ m_sdbSizerButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_LIB_EDIT_TEXT_BASE::~DIALOG_LIB_EDIT_TEXT_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnCloseDialog ) );
+ m_TextValueSelectButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnTextValueSelectButtonClick ), NULL, this );
+ m_sdbSizerButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_lib_edit_text_base.fbp b/eeschema/dialogs/dialog_lib_edit_text_base.fbp
new file mode 100644
index 0000000..d48e9be
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_text_base.fbp
@@ -0,0 +1,1427 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_lib_edit_text_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_LIB_EDIT_TEXT_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_LIB_EDIT_TEXT_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Library Text Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseDialog</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bPropertiesSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperBoxSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bTextValueBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bTextValueOptsSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">200,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Select</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextValueSelectButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnTextValueSelectButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bTextSizeSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextSizeText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Power component value text cannot be modified!</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PowerComponentValues</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bBottomtBoxSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Options</property>
+ <property name="minimum_size"></property>
+ <property name="name">sOptionsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Vertical</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Orient</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Common to all units</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CommonUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Common to all body styles</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CommonConvert</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Invisible</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Invisible</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Normal&quot; &quot;Italic&quot; &quot;Bold&quot; &quot;Bold Italic&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Style</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextShapeOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Align left&quot; &quot;Align center&quot; &quot;Align right&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Horizontal Justify</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextHJustificationOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Align bottom&quot; &quot;Align center&quot; &quot;Align top&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Vertical Justify</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextVJustificationOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="0">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizerButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_lib_edit_text_base.h b/eeschema/dialogs/dialog_lib_edit_text_base.h
new file mode 100644
index 0000000..cb1964b
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_edit_text_base.h
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_LIB_EDIT_TEXT_BASE_H__
+#define __DIALOG_LIB_EDIT_TEXT_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/checkbox.h>
+#include <wx/statline.h>
+#include <wx/statbox.h>
+#include <wx/radiobox.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_LIB_EDIT_TEXT_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_LIB_EDIT_TEXT_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText1;
+ wxTextCtrl* m_TextValue;
+ wxButton* m_TextValueSelectButton;
+ wxStaticText* m_TextSizeText;
+ wxTextCtrl* m_TextSize;
+ wxStaticText* m_PowerComponentValues;
+ wxCheckBox* m_Orient;
+ wxStaticLine* m_staticline1;
+ wxCheckBox* m_CommonUnit;
+ wxCheckBox* m_CommonConvert;
+ wxCheckBox* m_Invisible;
+ wxRadioBox* m_TextShapeOpt;
+ wxRadioBox* m_TextHJustificationOpt;
+ wxRadioBox* m_TextVJustificationOpt;
+ wxStdDialogButtonSizer* m_sdbSizerButtons;
+ wxButton* m_sdbSizerButtonsOK;
+ wxButton* m_sdbSizerButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseDialog( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnTextValueSelectButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_LIB_EDIT_TEXT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Library Text Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_LIB_EDIT_TEXT_BASE();
+
+};
+
+#endif //__DIALOG_LIB_EDIT_TEXT_BASE_H__
diff --git a/eeschema/dialogs/dialog_lib_new_component.cpp b/eeschema/dialogs/dialog_lib_new_component.cpp
new file mode 100644
index 0000000..23ddad8
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_new_component.cpp
@@ -0,0 +1,45 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <dialog_lib_new_component.h>
+#include <sch_validators.h>
+#include <template_fieldnames.h>
+
+DIALOG_LIB_NEW_COMPONENT::DIALOG_LIB_NEW_COMPONENT( wxWindow* parent ) :
+ DIALOG_LIB_NEW_COMPONENT_BASE( parent )
+{
+ m_textName->SetValidator( SCH_FIELD_VALIDATOR( true, VALUE ) );
+ m_textReference->SetValidator( SCH_FIELD_VALIDATOR( true, REFERENCE ) );
+
+ // initial focus should be on first editable field.
+ m_textName->SetFocus();
+
+ // What happens when user presses "Enter"? OK button! OK?
+ m_sdbSizerOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
diff --git a/eeschema/dialogs/dialog_lib_new_component.fbp b/eeschema/dialogs/dialog_lib_new_component.fbp
new file mode 100644
index 0000000..01560a9
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_new_component.fbp
@@ -0,0 +1,1597 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">table</property>
+ <property name="file">dialog_lib_new_component_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_lib_new_component</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_LIB_NEW_COMPONENT_BASE</property>
+ <property name="pos"></property>
+ <property name="size"></property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Component Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer7</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer16</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">General Settings</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText8</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">20</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer31</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Component &amp;name:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the component name in library,&#x0A;and also the default component value when loaded in the schematic.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">100,-1</property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default reference designator:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText9</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textReference</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">U</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Number of units per package:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText10</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">0</property>
+ <property name="max">26</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinPartCount</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value">1</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">15</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer17</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Create component with alternate body style (DeMorgan)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkHasConversion</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Create component as power symbol</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkIsPowerSymbol</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Units are not interchangeable</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkLockItems</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer18</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">10</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">General Pin Settings</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText11</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">20</property>
+ <property name="flag">wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">55</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer4</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pin text position offset:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText12</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">40</property>
+ <property name="max">100</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinPinTextPosition</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value">40</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">15</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer19</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show pin number text</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkShowPinNumber</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show pin name text</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkShowPinName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pin name inside</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkShowPinNameInside</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">10</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_lib_new_component.h b/eeschema/dialogs/dialog_lib_new_component.h
new file mode 100644
index 0000000..b8b9619
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_new_component.h
@@ -0,0 +1,97 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009-2105 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __dialog_lib_new_component__
+#define __dialog_lib_new_component__
+
+/**
+ * @file
+ * Subclass of DIALOG_LIB_NEW_COMPONENT, which is generated by wxFormBuilder.
+ */
+
+#include <dialog_lib_new_component_base.h>
+
+/** Implementing DIALOG_LIB_NEW_COMPONENT */
+class DIALOG_LIB_NEW_COMPONENT : public DIALOG_LIB_NEW_COMPONENT_BASE
+{
+public:
+ /** Constructor */
+ DIALOG_LIB_NEW_COMPONENT( wxWindow* parent );
+
+ void SetName( const wxString& name ) { m_textName->SetValue( name ); }
+ wxString GetName( void ) const { return m_textName->GetValue(); }
+
+ void SetReference( const wxString& reference )
+ {
+ m_textReference->SetValue( reference );
+ }
+ wxString GetReference( void ) { return m_textReference->GetValue(); }
+
+ void SetPartCount( int count ) { m_spinPartCount->SetValue( count ); }
+ int GetUnitCount( void ) { return m_spinPartCount->GetValue(); }
+
+ void SetAlternateBodyStyle( bool enable )
+ {
+ m_checkHasConversion->SetValue( enable );
+ }
+ bool GetAlternateBodyStyle( void )
+ {
+ return m_checkHasConversion->GetValue();
+ }
+
+ void SetPowerSymbol( bool enable )
+ {
+ m_checkIsPowerSymbol->SetValue( enable );
+ }
+ bool GetPowerSymbol( void ) { return m_checkIsPowerSymbol->GetValue(); }
+
+ void SetLockItems( bool enable ) { m_checkLockItems->SetValue( enable ); }
+ bool GetLockItems( void ) { return m_checkLockItems->GetValue(); }
+
+ void SetPinTextPosition( int position )
+ {
+ m_spinPinTextPosition->SetValue( position );
+ }
+ int GetPinTextPosition( void ) { return m_spinPinTextPosition->GetValue(); }
+
+ void SetShowPinNumber( bool show )
+ {
+ m_checkShowPinNumber->SetValue( show );
+ }
+ bool GetShowPinNumber( void ) { return m_checkShowPinNumber->GetValue(); }
+
+ void SetShowPinName( bool show )
+ {
+ m_checkShowPinName->SetValue( show );
+ }
+ bool GetShowPinName( void ) { return m_checkShowPinName->GetValue(); }
+
+ void SetPinNameInside( bool show )
+ {
+ m_checkShowPinNameInside->SetValue( show );
+ }
+ bool GetPinNameInside( void ) { return m_checkShowPinNameInside->GetValue(); }
+};
+
+#endif // __dialog_lib_new_component__
diff --git a/eeschema/dialogs/dialog_lib_new_component_base.cpp b/eeschema/dialogs/dialog_lib_new_component_base.cpp
new file mode 100644
index 0000000..35910e8
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_new_component_base.cpp
@@ -0,0 +1,146 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_lib_new_component_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizer7;
+ bSizer7 = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizer16;
+ bSizer16 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText8 = new wxStaticText( this, wxID_ANY, _("General Settings"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText8->Wrap( -1 );
+ m_staticText8->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizer16->Add( m_staticText8, 0, wxALL, 5 );
+
+ wxFlexGridSizer* fgSizer31;
+ fgSizer31 = new wxFlexGridSizer( 0, 2, 0, 0 );
+ fgSizer31->AddGrowableCol( 1 );
+ fgSizer31->SetFlexibleDirection( wxBOTH );
+ fgSizer31->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText2 = new wxStaticText( this, wxID_ANY, _("Component &name:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText2->Wrap( -1 );
+ m_staticText2->SetToolTip( _("This is the component name in library,\nand also the default component value when loaded in the schematic.") );
+
+ fgSizer31->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_textName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 100,-1 ), 0 );
+ m_textName->SetMaxLength( 0 );
+ fgSizer31->Add( m_textName, 1, wxALL|wxEXPAND, 3 );
+
+ m_staticText9 = new wxStaticText( this, wxID_ANY, _("Default reference designator:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText9->Wrap( -1 );
+ fgSizer31->Add( m_staticText9, 0, wxALL, 5 );
+
+ m_textReference = new wxTextCtrl( this, wxID_ANY, _("U"), wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer31->Add( m_textReference, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticText10 = new wxStaticText( this, wxID_ANY, _("Number of units per package:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText10->Wrap( -1 );
+ fgSizer31->Add( m_staticText10, 0, wxALL, 5 );
+
+ m_spinPartCount = new wxSpinCtrl( this, wxID_ANY, wxT("1"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 26, 0 );
+ fgSizer31->Add( m_spinPartCount, 0, wxALL, 5 );
+
+
+ bSizer16->Add( fgSizer31, 1, wxEXPAND|wxLEFT|wxRIGHT, 20 );
+
+ wxBoxSizer* bSizer17;
+ bSizer17 = new wxBoxSizer( wxVERTICAL );
+
+ m_checkHasConversion = new wxCheckBox( this, wxID_ANY, _("Create component with alternate body style (DeMorgan)"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer17->Add( m_checkHasConversion, 0, wxALL, 5 );
+
+ m_checkIsPowerSymbol = new wxCheckBox( this, wxID_ANY, _("Create component as power symbol"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer17->Add( m_checkIsPowerSymbol, 0, wxALL, 5 );
+
+ m_checkLockItems = new wxCheckBox( this, wxID_ANY, _("Units are not interchangeable"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer17->Add( m_checkLockItems, 0, wxALL, 5 );
+
+
+ bSizer16->Add( bSizer17, 1, wxEXPAND|wxLEFT|wxRIGHT, 15 );
+
+
+ bSizer7->Add( bSizer16, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer18;
+ bSizer18 = new wxBoxSizer( wxVERTICAL );
+
+
+ bSizer18->Add( 0, 10, 0, wxEXPAND, 5 );
+
+ m_staticText11 = new wxStaticText( this, wxID_ANY, _("General Pin Settings"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText11->Wrap( -1 );
+ m_staticText11->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizer18->Add( m_staticText11, 0, wxALL, 5 );
+
+ wxFlexGridSizer* fgSizer4;
+ fgSizer4 = new wxFlexGridSizer( 0, 2, 0, 55 );
+ fgSizer4->SetFlexibleDirection( wxBOTH );
+ fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText12 = new wxStaticText( this, wxID_ANY, _("Pin text position offset:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText12->Wrap( -1 );
+ fgSizer4->Add( m_staticText12, 0, wxALL, 5 );
+
+ m_spinPinTextPosition = new wxSpinCtrl( this, wxID_ANY, wxT("40"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 100, 40 );
+ fgSizer4->Add( m_spinPinTextPosition, 0, wxALL, 5 );
+
+
+ bSizer18->Add( fgSizer4, 0, wxLEFT|wxRIGHT, 20 );
+
+ wxBoxSizer* bSizer19;
+ bSizer19 = new wxBoxSizer( wxVERTICAL );
+
+ m_checkShowPinNumber = new wxCheckBox( this, wxID_ANY, _("Show pin number text"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkShowPinNumber->SetValue(true);
+ bSizer19->Add( m_checkShowPinNumber, 0, wxALL, 5 );
+
+ m_checkShowPinName = new wxCheckBox( this, wxID_ANY, _("Show pin name text"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkShowPinName->SetValue(true);
+ bSizer19->Add( m_checkShowPinName, 0, wxALL, 5 );
+
+ m_checkShowPinNameInside = new wxCheckBox( this, wxID_ANY, _("Pin name inside"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkShowPinNameInside->SetValue(true);
+ bSizer19->Add( m_checkShowPinNameInside, 0, wxALL, 5 );
+
+
+ bSizer18->Add( bSizer19, 0, wxEXPAND|wxLEFT|wxRIGHT, 15 );
+
+
+ bSizer7->Add( bSizer18, 1, wxALL|wxEXPAND, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bSizer7->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 10 );
+
+
+ this->SetSizer( bSizer7 );
+ this->Layout();
+ bSizer7->Fit( this );
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_LIB_NEW_COMPONENT_BASE::~DIALOG_LIB_NEW_COMPONENT_BASE()
+{
+}
diff --git a/eeschema/dialogs/dialog_lib_new_component_base.h b/eeschema/dialogs/dialog_lib_new_component_base.h
new file mode 100644
index 0000000..e90c52c
--- /dev/null
+++ b/eeschema/dialogs/dialog_lib_new_component_base.h
@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_LIB_NEW_COMPONENT_BASE_H__
+#define __DIALOG_LIB_NEW_COMPONENT_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/spinctrl.h>
+#include <wx/sizer.h>
+#include <wx/checkbox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_LIB_NEW_COMPONENT_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_LIB_NEW_COMPONENT_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText8;
+ wxStaticText* m_staticText2;
+ wxTextCtrl* m_textName;
+ wxStaticText* m_staticText9;
+ wxTextCtrl* m_textReference;
+ wxStaticText* m_staticText10;
+ wxSpinCtrl* m_spinPartCount;
+ wxCheckBox* m_checkHasConversion;
+ wxCheckBox* m_checkIsPowerSymbol;
+ wxCheckBox* m_checkLockItems;
+ wxStaticText* m_staticText11;
+ wxStaticText* m_staticText12;
+ wxSpinCtrl* m_spinPinTextPosition;
+ wxCheckBox* m_checkShowPinNumber;
+ wxCheckBox* m_checkShowPinName;
+ wxCheckBox* m_checkShowPinNameInside;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ public:
+
+ DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Component Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_LIB_NEW_COMPONENT_BASE();
+
+};
+
+#endif //__DIALOG_LIB_NEW_COMPONENT_BASE_H__
diff --git a/eeschema/dialogs/dialog_libedit_options.cpp b/eeschema/dialogs/dialog_libedit_options.cpp
new file mode 100644
index 0000000..4506d77
--- /dev/null
+++ b/eeschema/dialogs/dialog_libedit_options.cpp
@@ -0,0 +1,69 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_libedit_options.cpp
+ */
+
+#include <fctsys.h>
+#include <class_base_screen.h>
+
+#include <dialog_libedit_options.h>
+#include <libeditframe.h>
+
+
+DIALOG_LIBEDIT_OPTIONS::DIALOG_LIBEDIT_OPTIONS( LIB_EDIT_FRAME* parent ) :
+ DIALOG_LIBEDIT_OPTIONS_BASE( parent )
+{
+ m_sdbSizerOK->SetDefault();
+
+ SetRepeatLabelInc( Parent()->GetRepeatDeltaLabel() );
+ SetItemRepeatStep( Parent()->GetRepeatStep() );
+ SetPinRepeatStep( Parent()->GetRepeatPinStep() );
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+void DIALOG_LIBEDIT_OPTIONS::SetGridSizes( const GRIDS& grid_sizes, int grid_id )
+{
+ wxASSERT( grid_sizes.size() > 0 );
+
+ int select = wxNOT_FOUND;
+
+ for( size_t i = 0; i < grid_sizes.size(); i++ )
+ {
+ wxString tmp;
+ tmp.Printf( wxT( "%0.1f" ), grid_sizes[i].m_Size.x );
+ m_choiceGridSize->Append( tmp );
+
+ if( grid_sizes[i].m_CmdId == grid_id )
+ select = (int) i;
+ }
+
+ m_choiceGridSize->SetSelection( select );
+}
diff --git a/eeschema/dialogs/dialog_libedit_options.h b/eeschema/dialogs/dialog_libedit_options.h
new file mode 100644
index 0000000..02ac67e
--- /dev/null
+++ b/eeschema/dialogs/dialog_libedit_options.h
@@ -0,0 +1,93 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_libedit_options.h
+ *
+ * Subclass of DIALOG_LIBEDIT_OPTIONS_BASE, which is generated by wxFormBuilder.
+ */
+
+#ifndef __DIALOG_LIBEDIT_OPTIONS__
+#define __DIALOG_LIBEDIT_OPTIONS__
+
+#include <dialog_libedit_options_base.h>
+
+class LIB_EDIT_FRAME;
+
+class DIALOG_LIBEDIT_OPTIONS : public DIALOG_LIBEDIT_OPTIONS_BASE
+{
+public:
+ DIALOG_LIBEDIT_OPTIONS( LIB_EDIT_FRAME* parent );
+
+ LIB_EDIT_FRAME* Parent() { return (LIB_EDIT_FRAME*) GetParent(); }
+
+ void SetGridSelection( int select ) { m_choiceGridSize->SetSelection( select ); }
+ int GetGridSelection( void ) { return m_choiceGridSize->GetSelection(); }
+ void SetGridSizes( const GRIDS& grid_sizes, int grid_id );
+
+ void SetShowGrid( bool show ) { m_checkShowGrid->SetValue( show ); }
+ bool GetShowGrid( void ) { return m_checkShowGrid->GetValue(); }
+
+ void SetLineWidth( int aWidth ) { m_spinLineWidth->SetValue( aWidth ); }
+ int GetLineWidth( void ) { return m_spinLineWidth->GetValue(); }
+
+ void SetPinLength( int aLength ) { m_spinPinLength->SetValue( aLength ); }
+ int GetPinLength( void ) { return m_spinPinLength->GetValue(); }
+
+ void SetPinNumSize( int text_size ) { m_spinPinNumSize->SetValue( text_size ); }
+ int GetPinNumSize( void ) { return m_spinPinNumSize->GetValue(); }
+
+ void SetPinNameSize( int text_size ) { m_spinPinNameSize->SetValue( text_size ); }
+ int GetPinNameSize( void ) { return m_spinPinNameSize->GetValue(); }
+
+ void SetPinRepeatStep( int aValue ) { m_choicePinDisplacement->SetSelection( aValue == 50 ? 1 : 0 ); }
+ int GetPinRepeatStep( void )
+ {
+ return m_choicePinDisplacement->GetSelection() == 1 ? 50 : 100;
+ }
+
+ void SetItemRepeatStep( wxPoint aValue )
+ {
+ m_spinRepeatHorizontal->SetValue( aValue.x );
+ m_spinRepeatVertical->SetValue( aValue.y );
+ }
+ wxPoint GetItemRepeatStep( void )
+ {
+ wxPoint step;
+ step.x = m_spinRepeatHorizontal->GetValue();
+ step.y = m_spinRepeatVertical->GetValue();
+ return step;
+ }
+
+ void SetRepeatLabelInc( int aValue ) { m_spinRepeatLabel->SetValue( aValue ); }
+ int GetRepeatLabelInc( void )
+ {
+ return m_spinRepeatLabel->GetValue();
+ }
+
+ void SetMaxUndoItems( int aItems ) { m_spinMaxUndoItems->SetValue( aItems ); }
+ int GetMaxUndoItems() const { return m_spinMaxUndoItems->GetValue(); }
+};
+
+#endif // __DIALOG_LIBEDIT_OPTIONS__
diff --git a/eeschema/dialogs/dialog_libedit_options_base.cpp b/eeschema/dialogs/dialog_libedit_options_base.cpp
new file mode 100644
index 0000000..2020571
--- /dev/null
+++ b/eeschema/dialogs/dialog_libedit_options_base.cpp
@@ -0,0 +1,195 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 13 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_libedit_options_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_LIBEDIT_OPTIONS_BASE::DIALOG_LIBEDIT_OPTIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* mainSizer;
+ mainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bOptionsSizer;
+ bOptionsSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* p1mainSizer;
+ p1mainSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizer3;
+ bSizer3 = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer;
+ fgSizer = new wxFlexGridSizer( 0, 3, 0, 0 );
+ fgSizer->AddGrowableCol( 0 );
+ fgSizer->AddGrowableCol( 1 );
+ fgSizer->AddGrowableCol( 2 );
+ fgSizer->SetFlexibleDirection( wxBOTH );
+ fgSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText3 = new wxStaticText( this, wxID_ANY, _("&Grid size:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ fgSizer->Add( m_staticText3, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ wxArrayString m_choiceGridSizeChoices;
+ m_choiceGridSize = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceGridSizeChoices, 0 );
+ m_choiceGridSize->SetSelection( 0 );
+ fgSizer->Add( m_choiceGridSize, 0, wxEXPAND|wxALL, 3 );
+
+ m_staticGridUnits = new wxStaticText( this, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticGridUnits->Wrap( -1 );
+ fgSizer->Add( m_staticGridUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_staticText5 = new wxStaticText( this, wxID_ANY, _("&Default line width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText5->Wrap( -1 );
+ fgSizer->Add( m_staticText5, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_spinLineWidth = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, 1, 100, 6 );
+ fgSizer->Add( m_spinLineWidth, 0, wxALL|wxEXPAND, 3 );
+
+ m_staticLineWidthUnits = new wxStaticText( this, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticLineWidthUnits->Wrap( -1 );
+ fgSizer->Add( m_staticLineWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_staticText52 = new wxStaticText( this, wxID_ANY, _("D&efault pin length:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText52->Wrap( -1 );
+ fgSizer->Add( m_staticText52, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 3 );
+
+ m_spinPinLength = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, 50, 1000, 200 );
+ fgSizer->Add( m_spinPinLength, 0, wxALL|wxEXPAND, 3 );
+
+ m_staticPinLengthUnits = new wxStaticText( this, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticPinLengthUnits->Wrap( -1 );
+ fgSizer->Add( m_staticPinLengthUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 3 );
+
+ m_staticText7 = new wxStaticText( this, wxID_ANY, _("De&fault pin number size:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText7->Wrap( -1 );
+ fgSizer->Add( m_staticText7, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_spinPinNumSize = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, 0, 1000, 0 );
+ fgSizer->Add( m_spinPinNumSize, 0, wxALL|wxEXPAND, 3 );
+
+ m_staticTextSizeUnits = new wxStaticText( this, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSizeUnits->Wrap( -1 );
+ fgSizer->Add( m_staticTextSizeUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_staticText9 = new wxStaticText( this, wxID_ANY, _("Def&ault pin name size:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText9->Wrap( -1 );
+ fgSizer->Add( m_staticText9, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_spinPinNameSize = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, -5000, 5000, 0 );
+ fgSizer->Add( m_spinPinNameSize, 0, wxALL|wxEXPAND, 3 );
+
+ m_staticRepeatXUnits = new wxStaticText( this, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticRepeatXUnits->Wrap( -1 );
+ fgSizer->Add( m_staticRepeatXUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 );
+
+ m_staticText11 = new wxStaticText( this, wxID_ANY, _("&Horizontal pitch of repeated items:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText11->Wrap( -1 );
+ fgSizer->Add( m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_spinRepeatHorizontal = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -1000, 1000, 0 );
+ fgSizer->Add( m_spinRepeatHorizontal, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticText12 = new wxStaticText( this, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText12->Wrap( -1 );
+ fgSizer->Add( m_staticText12, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_staticText13 = new wxStaticText( this, wxID_ANY, _("&Vertical pitch of repeated items:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText13->Wrap( -1 );
+ fgSizer->Add( m_staticText13, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_spinRepeatVertical = new wxSpinCtrl( this, wxID_ANY, wxT("100"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -1000, 1000, 0 );
+ fgSizer->Add( m_spinRepeatVertical, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticText14 = new wxStaticText( this, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText14->Wrap( -1 );
+ fgSizer->Add( m_staticText14, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_staticText15 = new wxStaticText( this, wxID_ANY, _("&Pitch of repeated pins:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText15->Wrap( -1 );
+ fgSizer->Add( m_staticText15, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxString m_choicePinDisplacementChoices[] = { _("100"), _("50") };
+ int m_choicePinDisplacementNChoices = sizeof( m_choicePinDisplacementChoices ) / sizeof( wxString );
+ m_choicePinDisplacement = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choicePinDisplacementNChoices, m_choicePinDisplacementChoices, 0 );
+ m_choicePinDisplacement->SetSelection( 0 );
+ fgSizer->Add( m_choicePinDisplacement, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticText16 = new wxStaticText( this, wxID_ANY, _("mils"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText16->Wrap( -1 );
+ fgSizer->Add( m_staticText16, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_staticText17 = new wxStaticText( this, wxID_ANY, _("&Increment of repeated labels:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText17->Wrap( -1 );
+ fgSizer->Add( m_staticText17, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_spinRepeatLabel = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -10, 10, 1 );
+ fgSizer->Add( m_spinRepeatLabel, 0, wxALL|wxEXPAND, 5 );
+
+
+ fgSizer->Add( 0, 0, 0, 0, 5 );
+
+ m_stMaxUndoItems = new wxStaticText( this, wxID_ANY, _("Ma&ximum undo items (0 = unlimited):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_stMaxUndoItems->Wrap( -1 );
+ fgSizer->Add( m_stMaxUndoItems, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_spinMaxUndoItems = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 65536, 0 );
+ fgSizer->Add( m_spinMaxUndoItems, 0, wxALL|wxEXPAND, 5 );
+
+ m_stMaxUndoItemsUnit = new wxStaticText( this, wxID_ANY, _("actions"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_stMaxUndoItemsUnit->Wrap( -1 );
+ fgSizer->Add( m_stMaxUndoItemsUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizer3->Add( fgSizer, 0, wxEXPAND, 0 );
+
+ wxBoxSizer* bSizer2;
+ bSizer2 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticline3 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizer2->Add( m_staticline3, 0, wxEXPAND | wxALL, 5 );
+
+ m_checkShowGrid = new wxCheckBox( this, wxID_ANY, _("&Show grid"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer2->Add( m_checkShowGrid, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 3 );
+
+
+ bSizer3->Add( bSizer2, 0, wxEXPAND, 0 );
+
+
+ p1mainSizer->Add( bSizer3, 1, wxALL|wxEXPAND, 6 );
+
+
+ bOptionsSizer->Add( p1mainSizer, 1, wxEXPAND, 5 );
+
+ m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bOptionsSizer->Add( m_staticline2, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bOptionsSizer->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 6 );
+
+
+ mainSizer->Add( bOptionsSizer, 1, wxEXPAND, 12 );
+
+
+ this->SetSizer( mainSizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_LIBEDIT_OPTIONS_BASE::~DIALOG_LIBEDIT_OPTIONS_BASE()
+{
+}
diff --git a/eeschema/dialogs/dialog_libedit_options_base.fbp b/eeschema/dialogs/dialog_libedit_options_base.fbp
new file mode 100644
index 0000000..3321b65
--- /dev/null
+++ b/eeschema/dialogs/dialog_libedit_options_base.fbp
@@ -0,0 +1,2904 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">table</property>
+ <property name="file">dialog_libedit_options_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_libedit_options</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_LIBEDIT_OPTIONS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">487,433</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Library Editor Options</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">mainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">12</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bOptionsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">p1mainSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer3</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">0</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">0,1,2</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Grid size:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceGridSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticGridUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Default line width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">6</property>
+ <property name="max">100</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinLineWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS|wxSP_WRAP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticLineWidthUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">D&amp;efault pin length:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText52</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">200</property>
+ <property name="max">1000</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">50</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinPinLength</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS|wxSP_WRAP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticPinLengthUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">De&amp;fault pin number size:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText7</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">0</property>
+ <property name="max">1000</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinPinNumSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS|wxSP_WRAP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSizeUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Def&amp;ault pin name size:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText9</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">0</property>
+ <property name="max">5000</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">-5000</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinPinNameSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS|wxSP_WRAP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticRepeatXUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Horizontal pitch of repeated items:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText11</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">0</property>
+ <property name="max">1000</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">-1000</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinRepeatHorizontal</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText12</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Vertical pitch of repeated items:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText13</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">0</property>
+ <property name="max">1000</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">-1000</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinRepeatVertical</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value">100</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText14</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Pitch of repeated pins:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText15</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;100&quot; &quot;50&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choicePinDisplacement</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mils</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText16</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Increment of repeated labels:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText17</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">1</property>
+ <property name="max">10</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">-10</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinRepeatLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Ma&amp;ximum undo items (0 = unlimited):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_stMaxUndoItems</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">0</property>
+ <property name="max">65536</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinMaxUndoItems</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">actions</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_stMaxUndoItemsUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">0</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer2</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Show grid</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkShowGrid</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="0">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_libedit_options_base.h b/eeschema/dialogs/dialog_libedit_options_base.h
new file mode 100644
index 0000000..9764e6f
--- /dev/null
+++ b/eeschema/dialogs/dialog_libedit_options_base.h
@@ -0,0 +1,85 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 13 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_LIBEDIT_OPTIONS_BASE_H__
+#define __DIALOG_LIBEDIT_OPTIONS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/choice.h>
+#include <wx/spinctrl.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/checkbox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_LIBEDIT_OPTIONS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_LIBEDIT_OPTIONS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText3;
+ wxChoice* m_choiceGridSize;
+ wxStaticText* m_staticGridUnits;
+ wxStaticText* m_staticText5;
+ wxSpinCtrl* m_spinLineWidth;
+ wxStaticText* m_staticLineWidthUnits;
+ wxStaticText* m_staticText52;
+ wxSpinCtrl* m_spinPinLength;
+ wxStaticText* m_staticPinLengthUnits;
+ wxStaticText* m_staticText7;
+ wxSpinCtrl* m_spinPinNumSize;
+ wxStaticText* m_staticTextSizeUnits;
+ wxStaticText* m_staticText9;
+ wxSpinCtrl* m_spinPinNameSize;
+ wxStaticText* m_staticRepeatXUnits;
+ wxStaticText* m_staticText11;
+ wxSpinCtrl* m_spinRepeatHorizontal;
+ wxStaticText* m_staticText12;
+ wxStaticText* m_staticText13;
+ wxSpinCtrl* m_spinRepeatVertical;
+ wxStaticText* m_staticText14;
+ wxStaticText* m_staticText15;
+ wxChoice* m_choicePinDisplacement;
+ wxStaticText* m_staticText16;
+ wxStaticText* m_staticText17;
+ wxSpinCtrl* m_spinRepeatLabel;
+ wxStaticText* m_stMaxUndoItems;
+ wxSpinCtrl* m_spinMaxUndoItems;
+ wxStaticText* m_stMaxUndoItemsUnit;
+ wxStaticLine* m_staticline3;
+ wxCheckBox* m_checkShowGrid;
+ wxStaticLine* m_staticline2;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ public:
+
+ DIALOG_LIBEDIT_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Library Editor Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 487,433 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_LIBEDIT_OPTIONS_BASE();
+
+};
+
+#endif //__DIALOG_LIBEDIT_OPTIONS_BASE_H__
diff --git a/eeschema/dialogs/dialog_netlist.cpp b/eeschema/dialogs/dialog_netlist.cpp
new file mode 100644
index 0000000..bd42d3d
--- /dev/null
+++ b/eeschema/dialogs/dialog_netlist.cpp
@@ -0,0 +1,886 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013-2015 Jean-Pierre Charras, jp.charras@wanadoo.fr
+ * Copyright (C) 2013-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/dialogs/dialog_netlist.cpp
+ * @brief Dialog box for creating netlists.
+ */
+
+/* Functions relative to the dialog creating the netlist for Pcbnew.
+ * The dialog is a notebook with 4 fixed netlist format:
+ * Pcbnew ORCADPCB2 CADSTAR and SPICE
+ * and up to CUSTOMPANEL_COUNTMAX (see netlist.h) user programmable format
+ * calling an external converter with convert an intermediate format to the
+ * user specific format.
+ * these external converters are referred there as plugins,
+ * but there are not really plugins, there are only external binaries
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <gestfich.h>
+#include <schframe.h>
+
+#include <general.h>
+#include <netlist.h>
+#include <sch_sheet.h>
+#include <dialog_helpers.h>
+#include <dialogs/dialog_netlist_base.h>
+#include <wildcards_and_files_ext.h>
+#include <wildcards_and_files_ext.h>
+#include <invoke_sch_dialog.h>
+
+#include <eeschema_id.h>
+
+
+
+#define CUSTOMPANEL_COUNTMAX 8 // Max number of netlist plugins
+
+
+/* panel (notebook page) identifiers */
+enum panel_netlist_index {
+ PANELPCBNEW = 0, /* Handle Netlist format Pcbnew */
+ PANELORCADPCB2, /* Handle Netlist format OracdPcb2 */
+ PANELCADSTAR, /* Handle Netlist format CadStar */
+ PANELSPICE, /* Handle Netlist format Pspice */
+ PANELCUSTOMBASE /* First auxiliary panel (custom netlists).
+ * others use PANELCUSTOMBASE+1, PANELCUSTOMBASE+2.. */
+};
+
+
+/* wxPanels for creating the NoteBook pages for each netlist format: */
+class NETLIST_PAGE_DIALOG : public wxPanel
+{
+public:
+ NETLIST_TYPE_ID m_IdNetType;
+ wxCheckBox* m_IsCurrentFormat;
+ wxCheckBox* m_AddSubPrefix;
+ wxCheckBox* m_SpiceUseNetcodeAsNetname;
+ wxTextCtrl* m_CommandStringCtrl;
+ wxTextCtrl* m_TitleStringCtrl;
+ wxButton* m_ButtonCancel;
+ wxBoxSizer* m_LeftBoxSizer;
+ wxBoxSizer* m_RightBoxSizer;
+ wxBoxSizer* m_RightOptionsBoxSizer;
+ wxBoxSizer* m_LowBoxSizer;
+
+private:
+ wxString m_pageNetFmtName;
+
+public:
+ /** Constructor to create a setup page for one netlist format.
+ * Used in Netlist format Dialog box creation
+ * @param parent = wxNotebook * parent
+ * @param title = title (name) of the notebook page
+ * @param id_NetType = netlist type id
+ */
+ NETLIST_PAGE_DIALOG( wxNotebook* parent, const wxString& title,
+ NETLIST_TYPE_ID id_NetType );
+ ~NETLIST_PAGE_DIALOG() { };
+
+ /**
+ * function GetPageNetFmtName
+ * @return the name of the netlist format for this page
+ * This is also the page label.
+ */
+ const wxString GetPageNetFmtName()
+ {
+ return m_pageNetFmtName;
+ }
+};
+
+
+/* Dialog frame for creating netlists */
+class NETLIST_DIALOG : public NETLIST_DIALOG_BASE
+{
+public:
+ SCH_EDIT_FRAME* m_Parent;
+ wxString m_NetFmtName;
+ NETLIST_PAGE_DIALOG* m_PanelNetType[4 + CUSTOMPANEL_COUNTMAX];
+
+private:
+ wxConfigBase* m_config;
+
+public:
+
+ // Constructor and destructor
+ NETLIST_DIALOG( SCH_EDIT_FRAME* parent );
+ ~NETLIST_DIALOG() { };
+
+private:
+ void InstallCustomPages();
+ NETLIST_PAGE_DIALOG* AddOneCustomPage( const wxString & aTitle,
+ const wxString & aCommandString,
+ NETLIST_TYPE_ID aNetTypeId );
+ void InstallPageSpice();
+ void GenNetlist( wxCommandEvent& event );
+ void RunSimulator( wxCommandEvent& event );
+ void NetlistUpdateOpt();
+ void OnCancelClick( wxCommandEvent& event );
+ void OnNetlistTypeSelection( wxNotebookEvent& event );
+ void SelectDefaultNetlistType( wxCommandEvent& event );
+
+ /**
+ * Function OnAddPlugin
+ * Add a new panel for a new netlist plugin
+ */
+ void OnAddPlugin( wxCommandEvent& event );
+
+ /**
+ * Function OnDelPlugin
+ * Remove a panel relative to a netlist plugin
+ */
+ void OnDelPlugin( wxCommandEvent& event );
+
+ /**
+ * Function WriteCurrentNetlistSetup
+ * Write the current netlist options setup in the configuration
+ */
+ void WriteCurrentNetlistSetup();
+
+ bool GetUseDefaultNetlistName()
+ {
+ return m_cbUseDefaultNetlistName->IsChecked();
+ }
+
+ /**
+ * Function UserNetlistTypeName
+ * to retrieve user netlist type names
+ * @param first_item = true: return first name of the list, false = return next
+ * @return a wxString : name of the type netlist or empty string
+ * this function must be called first with "first_item" = true
+ * and after with "first_item" = false to get all the other existing netlist names
+ */
+ const wxString UserNetlistTypeName( bool first_item );
+
+ /**
+ * Function FilenamePrms
+ * returns the filename extension and the wildcard string for this curr
+ * or a void name if there is no default name
+ * @param aNetTypeId = the netlist type ( NET_TYPE_PCBNEW ... )
+ * @param aExt = a reference to a wxString to return the default file ext.
+ * @param aWildCard = reference to a wxString to return the default wildcard.
+ * @return true for known netlist type, false for custom formats
+ */
+ bool FilenamePrms( NETLIST_TYPE_ID aNetTypeId,
+ wxString * aExt, wxString * aWildCard );
+
+ DECLARE_EVENT_TABLE()
+};
+
+
+class NETLIST_DIALOG_ADD_PLUGIN : public NETLIST_DIALOG_ADD_PLUGIN_BASE
+{
+private:
+ NETLIST_DIALOG* m_Parent;
+
+public:
+ NETLIST_DIALOG_ADD_PLUGIN( NETLIST_DIALOG* parent );
+ const wxString GetPluginTitle()
+ {
+ return m_textCtrlName->GetValue();
+ }
+ const wxString GetPluginTCommandLine()
+ {
+ return m_textCtrlCommand->GetValue();
+ }
+
+private:
+
+ /**
+ * Function OnOKClick
+ * Validate info relative to a new netlist plugin
+ */
+ void OnOKClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+
+ /*
+ * Browse plugin files, and set m_CommandStringCtrl field
+ */
+ void OnBrowsePlugins( wxCommandEvent& event );
+};
+
+
+/* Event id for notebook page buttons: */
+enum id_netlist {
+ ID_CREATE_NETLIST = ID_END_EESCHEMA_ID_LIST + 1,
+ ID_CURRENT_FORMAT_IS_DEFAULT,
+ ID_RUN_SIMULATOR,
+ ID_ADD_SUBCIRCUIT_PREFIX,
+ ID_USE_NETCODE_AS_NETNAME
+};
+
+
+// ID for configuration:
+#define CUSTOM_NETLIST_TITLE wxT( "CustomNetlistTitle" )
+#define CUSTOM_NETLIST_COMMAND wxT( "CustomNetlistCommand" )
+#define NETLIST_USE_DEFAULT_NETNAME wxT( "NetlistUseDefaultNetname" )
+#define NETLIST_PSPICE_USE_NETNAME wxT( "SpiceUseNetNames" )
+
+
+BEGIN_EVENT_TABLE( NETLIST_DIALOG, NETLIST_DIALOG_BASE )
+ EVT_BUTTON( ID_CREATE_NETLIST, NETLIST_DIALOG::GenNetlist )
+ EVT_CHECKBOX( ID_CURRENT_FORMAT_IS_DEFAULT,
+ NETLIST_DIALOG::SelectDefaultNetlistType )
+ EVT_BUTTON( ID_RUN_SIMULATOR, NETLIST_DIALOG::RunSimulator )
+END_EVENT_TABLE()
+
+
+
+NETLIST_PAGE_DIALOG::NETLIST_PAGE_DIALOG( wxNotebook* parent,
+ const wxString& title,
+ NETLIST_TYPE_ID id_NetType ) :
+ wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize,
+ wxTAB_TRAVERSAL | wxBORDER_SUNKEN )
+{
+ m_IdNetType = id_NetType;
+ m_pageNetFmtName = title;
+ m_CommandStringCtrl = NULL;
+ m_TitleStringCtrl = NULL;
+ m_IsCurrentFormat = NULL;
+ m_AddSubPrefix = NULL;
+ m_SpiceUseNetcodeAsNetname = NULL;
+ m_ButtonCancel = NULL;
+
+ wxString netfmtName = ((NETLIST_DIALOG*)parent->GetParent())->m_NetFmtName;
+
+ bool selected = m_pageNetFmtName == netfmtName;
+
+ // PCBNEW Format is a special type:
+ if( id_NetType == NET_TYPE_PCBNEW )
+ {
+ selected = true;
+ }
+
+
+ parent->AddPage( this, title, selected );
+
+ wxBoxSizer* MainBoxSizer = new wxBoxSizer( wxVERTICAL );
+ SetSizer( MainBoxSizer );
+ wxBoxSizer* UpperBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+ m_LowBoxSizer = new wxBoxSizer( wxVERTICAL );
+ MainBoxSizer->Add( UpperBoxSizer, 0, wxGROW | wxALL, 5 );
+ MainBoxSizer->Add( m_LowBoxSizer, 0, wxGROW | wxALL, 5 );
+
+ m_LeftBoxSizer = new wxBoxSizer( wxVERTICAL );
+ m_RightBoxSizer = new wxBoxSizer( wxVERTICAL );
+ m_RightOptionsBoxSizer = new wxBoxSizer( wxVERTICAL );
+ UpperBoxSizer->Add( m_LeftBoxSizer, 0, wxGROW | wxALL, 5 );
+ UpperBoxSizer->Add( m_RightBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+ UpperBoxSizer->Add( m_RightOptionsBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+
+ wxStaticText* text = new wxStaticText( this, -1, _( "Options:" ) );
+ m_LeftBoxSizer->Add( text, 0, wxGROW | wxALL, 5 );
+
+ m_IsCurrentFormat = new wxCheckBox( this, ID_CURRENT_FORMAT_IS_DEFAULT,
+ _( "Default format" ) );
+ m_LeftBoxSizer->Add( m_IsCurrentFormat, 0, wxGROW | wxALL, 5 );
+ m_IsCurrentFormat->SetValue( selected );
+}
+
+
+
+NETLIST_DIALOG::NETLIST_DIALOG( SCH_EDIT_FRAME* parent ) :
+ NETLIST_DIALOG_BASE( parent )
+{
+ m_Parent = parent;
+ m_config = Kiface().KifaceSettings();
+
+ long tmp;
+ m_config->Read( NETLIST_USE_DEFAULT_NETNAME, &tmp, 0l );
+ m_cbUseDefaultNetlistName->SetValue( tmp );
+ m_NetFmtName = m_Parent->GetNetListFormatName();
+
+ for( int ii = 0; ii < PANELCUSTOMBASE + CUSTOMPANEL_COUNTMAX; ii++ )
+ {
+ m_PanelNetType[ii] = NULL;
+ }
+
+ // Add notebook pages:
+
+ // Add Panel FORMAT PCBNEW
+ m_PanelNetType[PANELPCBNEW] =
+ new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "Pcbnew" ),
+ NET_TYPE_PCBNEW );
+
+ // Add Panel FORMAT ORCADPCB2
+ m_PanelNetType[PANELORCADPCB2] =
+ new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "OrcadPCB2" ),
+ NET_TYPE_ORCADPCB2 );
+
+ // Add Panel FORMAT CADSTAR
+ m_PanelNetType[PANELCADSTAR] =
+ new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "CadStar" ),
+ NET_TYPE_CADSTAR );
+
+ // Add Panel spice
+ InstallPageSpice();
+
+ // Add custom panels:
+ InstallCustomPages();
+
+ SetDefaultItem( m_buttonNetlist );
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+const wxString NETLIST_DIALOG::UserNetlistTypeName( bool first_item )
+{
+ static int index;
+ wxString name, msg;
+
+ if( first_item )
+ index = 0;
+ else
+ index++;
+
+ msg = CUSTOM_NETLIST_TITLE;
+ msg << index + 1;
+
+ name = m_config->Read( msg );
+
+ return name;
+}
+
+
+void NETLIST_DIALOG::InstallPageSpice()
+{
+ wxButton* Button;
+ NETLIST_PAGE_DIALOG* page;
+ wxString title = wxT( "Spice" );
+
+ page = m_PanelNetType[PANELSPICE] =
+ new NETLIST_PAGE_DIALOG( m_NoteBook, title, NET_TYPE_SPICE );
+
+ page->m_AddSubPrefix = new wxCheckBox( page, ID_ADD_SUBCIRCUIT_PREFIX,
+ _( "Prefix references 'U' and 'IC' with 'X'" ) );
+ page->m_AddSubPrefix->SetValue( m_Parent->GetSpiceAddReferencePrefix() );
+ page->m_LeftBoxSizer->Add( page->m_AddSubPrefix, 0, wxGROW | wxALL, 5 );
+
+ page->m_SpiceUseNetcodeAsNetname = new wxCheckBox( page, ID_USE_NETCODE_AS_NETNAME,
+ _( "Use net number as net name" ) );
+ page->m_SpiceUseNetcodeAsNetname->SetValue( m_Parent->GetSpiceUseNetcodeAsNetname() );
+ page->m_LeftBoxSizer->Add( page->m_SpiceUseNetcodeAsNetname, 0, wxGROW | wxALL, 5 );
+
+ page->m_LowBoxSizer->Add( new wxStaticText( page, -1, _( "Simulator command:" ) ), 0,
+ wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
+
+ page->m_CommandStringCtrl = new wxTextCtrl( page, -1, m_Parent->GetSimulatorCommand(),
+ wxDefaultPosition, wxDefaultSize );
+
+ page->m_CommandStringCtrl->SetInsertionPoint( 1 );
+ page->m_LowBoxSizer->Add( page->m_CommandStringCtrl,
+ 0,
+ wxGROW | wxLEFT | wxRIGHT | wxBOTTOM,
+ 5 );
+
+ // Add buttons
+ Button = new wxButton( page, ID_RUN_SIMULATOR, _( "&Run Simulator" ) );
+ page->m_RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
+}
+
+
+void NETLIST_DIALOG::InstallCustomPages()
+{
+ int ii;
+ wxString title, msg;
+ NETLIST_PAGE_DIALOG* currPage;
+
+ for( ii = 0; ii < CUSTOMPANEL_COUNTMAX; ii++ )
+ {
+ title = UserNetlistTypeName( ii == 0 ? true : false );
+
+ if( title.IsEmpty() )
+ break; // No more panel to install
+
+ // Install a plugin panel
+ msg = CUSTOM_NETLIST_COMMAND;
+ msg << ii + 1;
+ wxString command = m_config->Read( msg );
+
+ currPage = AddOneCustomPage( title, command,
+ (NETLIST_TYPE_ID)(NET_TYPE_CUSTOM1 + ii) );
+ m_PanelNetType[PANELCUSTOMBASE + ii] = currPage;
+ }
+}
+
+
+NETLIST_PAGE_DIALOG* NETLIST_DIALOG::AddOneCustomPage( const wxString & aTitle,
+ const wxString & aCommandString,
+ NETLIST_TYPE_ID aNetTypeId )
+{
+ NETLIST_PAGE_DIALOG* currPage;
+
+ currPage = new NETLIST_PAGE_DIALOG( m_NoteBook, aTitle, aNetTypeId );
+
+
+ currPage->m_LowBoxSizer->Add( new wxStaticText( currPage,
+ -1, _( "Netlist command:" ) ), 0,
+ wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
+
+ currPage->m_CommandStringCtrl = new wxTextCtrl( currPage, -1, aCommandString,
+ wxDefaultPosition, wxDefaultSize );
+
+ currPage->m_CommandStringCtrl->SetInsertionPoint( 1 );
+ currPage->m_LowBoxSizer->Add( currPage->m_CommandStringCtrl,
+ 0,
+ wxGROW | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM,
+ 5 );
+
+ currPage->m_LowBoxSizer->Add( new wxStaticText( currPage,
+ -1, _( "Title:" ) ), 0,
+ wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
+
+ currPage->m_TitleStringCtrl = new wxTextCtrl( currPage, -1, aTitle,
+ wxDefaultPosition, wxDefaultSize );
+
+ currPage->m_TitleStringCtrl->SetInsertionPoint( 1 );
+ currPage->m_LowBoxSizer->Add( currPage->m_TitleStringCtrl,
+ 0,
+ wxGROW | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM,
+ 5 );
+ return currPage;
+}
+
+
+void NETLIST_DIALOG::SelectDefaultNetlistType( wxCommandEvent& event )
+{
+ int ii;
+ NETLIST_PAGE_DIALOG* currPage;
+
+ for( ii = 0; ii < PANELCUSTOMBASE + CUSTOMPANEL_COUNTMAX; ii++ )
+ if( m_PanelNetType[ii] )
+ m_PanelNetType[ii]->m_IsCurrentFormat->SetValue( false );
+
+ currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
+
+ if( currPage == NULL )
+ return;
+
+ m_Parent->SetNetListFormatName( currPage->GetPageNetFmtName() );
+ currPage->m_IsCurrentFormat->SetValue( true );
+}
+
+
+void NETLIST_DIALOG::OnNetlistTypeSelection( wxNotebookEvent& event )
+{
+ NETLIST_PAGE_DIALOG* currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
+ if( currPage == NULL )
+ return;
+
+ m_buttonDelPlugin->Enable( currPage->m_IdNetType >= NET_TYPE_CUSTOM1 );
+ m_cbUseDefaultNetlistName->Enable( currPage->m_IdNetType < NET_TYPE_CUSTOM1 );
+
+ wxString fileExt;
+ if( FilenamePrms( currPage->m_IdNetType, &fileExt, NULL ) )
+ {
+ wxFileName fn = g_RootSheet->GetScreen()->GetFileName();
+ fn.SetExt( fileExt );
+ m_textCtrlDefaultFileName->SetValue( fn.GetFullName() );
+ }
+ else
+ m_textCtrlDefaultFileName->Clear();
+}
+
+
+void NETLIST_DIALOG::NetlistUpdateOpt()
+{
+ int ii;
+
+ m_Parent->SetSpiceAddReferencePrefix( m_PanelNetType[PANELSPICE]->m_AddSubPrefix->IsChecked() );
+ m_Parent->SetSpiceUseNetcodeAsNetname( m_PanelNetType[PANELSPICE]->m_SpiceUseNetcodeAsNetname->IsChecked() );
+ m_Parent->SetSimulatorCommand( m_PanelNetType[PANELSPICE]->m_CommandStringCtrl->GetValue() );
+ m_Parent->SetNetListFormatName( wxEmptyString );
+
+ for( ii = 0; ii < PANELCUSTOMBASE + CUSTOMPANEL_COUNTMAX; ii++ )
+ {
+ if( m_PanelNetType[ii] == NULL )
+ break;
+
+ if( m_PanelNetType[ii]->m_IsCurrentFormat->GetValue() == true )
+ m_Parent->SetNetListFormatName( m_PanelNetType[ii]->GetPageNetFmtName() );
+ }
+}
+
+
+void NETLIST_DIALOG::GenNetlist( wxCommandEvent& event )
+{
+ wxFileName fn;
+ wxString fileWildcard;
+ wxString fileExt;
+ wxString title = _( "Save Netlist File" );
+
+ NetlistUpdateOpt();
+
+ NETLIST_PAGE_DIALOG* currPage;
+ currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
+
+ unsigned netlist_opt = 0;
+
+ // Calculate the netlist filename
+ fn = g_RootSheet->GetScreen()->GetFileName();
+ FilenamePrms( currPage->m_IdNetType, &fileExt, &fileWildcard );
+
+ // Set some parameters
+ switch( currPage->m_IdNetType )
+ {
+ case NET_TYPE_SPICE:
+ // Set spice netlist options:
+ if( currPage->m_AddSubPrefix->GetValue() )
+ netlist_opt |= NET_USE_X_PREFIX;
+
+ if( currPage->m_SpiceUseNetcodeAsNetname->GetValue() )
+ netlist_opt |= NET_USE_NETCODES_AS_NETNAMES;
+ break;
+
+ case NET_TYPE_CADSTAR:
+ break;
+
+ case NET_TYPE_PCBNEW:
+ break;
+
+ case NET_TYPE_ORCADPCB2:
+ break;
+
+ default: // custom, NET_TYPE_CUSTOM1 and greater
+ title.Printf( _( "%s Export" ), currPage->m_TitleStringCtrl->GetValue().GetData() );
+ }
+
+ fn.SetExt( fileExt );
+
+ if( fn.GetPath().IsEmpty() )
+ fn.SetPath( wxPathOnly( Prj().GetProjectFullName() ) );
+
+ wxString fullpath = fn.GetFullPath();
+
+ if( !GetUseDefaultNetlistName() || currPage->m_IdNetType >= NET_TYPE_CUSTOM1 )
+ {
+ wxString fullname = fn.GetFullName();
+ wxString path = fn.GetPath();
+
+ // fullname does not and should not include the path, per wx docs.
+ wxFileDialog dlg( this, title, path, fullname, fileWildcard, wxFD_SAVE );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ fullpath = dlg.GetPath(); // directory + filename
+ }
+
+ m_Parent->ClearMsgPanel();
+
+ if( currPage->m_CommandStringCtrl )
+ m_Parent->SetNetListerCommand( currPage->m_CommandStringCtrl->GetValue() );
+ else
+ m_Parent->SetNetListerCommand( wxEmptyString );
+
+ m_Parent->CreateNetlist( currPage->m_IdNetType, fullpath, netlist_opt );
+
+ WriteCurrentNetlistSetup();
+
+ EndModal( wxID_OK );
+}
+
+
+bool NETLIST_DIALOG::FilenamePrms( NETLIST_TYPE_ID aNetTypeId,
+ wxString * aExt, wxString * aWildCard )
+{
+ wxString fileExt;
+ wxString fileWildcard;
+
+ bool ret = true;
+
+ switch( aNetTypeId )
+ {
+ case NET_TYPE_SPICE:
+ fileExt = wxT( "cir" );
+ fileWildcard = _( "SPICE netlist file (.cir)|*.cir" );
+ break;
+
+ case NET_TYPE_CADSTAR:
+ fileExt = wxT( "frp" );
+ fileWildcard = _( "CadStar netlist file (.frp)|*.frp" );
+ break;
+
+ case NET_TYPE_PCBNEW:
+ case NET_TYPE_ORCADPCB2:
+ fileExt = NetlistFileExtension;
+ fileWildcard = NetlistFileWildcard;
+ break;
+
+ default: // custom, NET_TYPE_CUSTOM1 and greater
+ fileWildcard = AllFilesWildcard;
+ ret = false;
+ }
+
+ if( aExt )
+ *aExt = fileExt;
+
+ if( aWildCard )
+ *aWildCard = fileWildcard;
+
+ return ret;
+}
+
+
+void NETLIST_DIALOG::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+void NETLIST_DIALOG::RunSimulator( wxCommandEvent& event )
+{
+ wxFileName fn;
+ wxString ExecFile, CommandLine;
+
+ NetlistUpdateOpt();
+
+ wxString tmp = m_PanelNetType[PANELSPICE]->m_CommandStringCtrl->GetValue();
+ tmp.Trim( false );
+ tmp.Trim( true );
+ m_Parent->SetSimulatorCommand( tmp );
+ ExecFile = tmp.BeforeFirst( ' ' );
+ CommandLine = tmp.AfterFirst( ' ' );
+
+ // Calculate the netlist filename
+ fn = g_RootSheet->GetScreen()->GetFileName();
+ fn.SetExt( wxT( "cir" ) );
+ CommandLine += wxT( " \"" ) + fn.GetFullPath() + wxT( "\"" );
+
+ NETLIST_PAGE_DIALOG* currPage;
+ currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
+
+ // Set spice netlist options:
+ unsigned netlist_opt = 0;
+
+ if( currPage->m_AddSubPrefix && currPage->m_AddSubPrefix->GetValue() )
+ netlist_opt |= NET_USE_X_PREFIX;
+
+ if( currPage->m_SpiceUseNetcodeAsNetname && currPage->m_SpiceUseNetcodeAsNetname->GetValue() )
+ netlist_opt |= NET_USE_NETCODES_AS_NETNAMES;
+
+ if( ! m_Parent->CreateNetlist( currPage->m_IdNetType, fn.GetFullPath(),
+ netlist_opt ) )
+ return;
+
+ ExecuteFile( this, ExecFile, CommandLine );
+}
+
+
+void NETLIST_DIALOG::WriteCurrentNetlistSetup()
+{
+ wxString msg, Command;
+
+ NetlistUpdateOpt();
+
+ m_config->Write( NETLIST_USE_DEFAULT_NETNAME, GetUseDefaultNetlistName() );
+
+ // Update existing custom pages
+ int jj = 0;
+ for( int ii = 0; ii < CUSTOMPANEL_COUNTMAX; ii++ )
+ {
+ NETLIST_PAGE_DIALOG* currPage = m_PanelNetType[ii + PANELCUSTOMBASE];
+
+ if( currPage == NULL )
+ break;
+
+ wxString title = currPage->m_TitleStringCtrl->GetValue();
+
+ if( title.IsEmpty() )
+ continue;
+
+ msg = CUSTOM_NETLIST_TITLE;
+ msg << jj + 1;
+ m_config->Write( msg, title );
+
+ Command = currPage->m_CommandStringCtrl->GetValue();
+ msg = CUSTOM_NETLIST_COMMAND;
+ msg << jj + 1;
+ m_config->Write( msg, Command );
+ jj++;
+ }
+
+ // Ensure all other pages are void
+ for(; jj < CUSTOMPANEL_COUNTMAX; jj++ )
+ {
+ msg = CUSTOM_NETLIST_TITLE;
+ msg << jj + 1;
+ m_config->Write( msg, wxEmptyString );
+
+ msg = CUSTOM_NETLIST_COMMAND;
+ msg << jj + 1;
+ m_config->Write( msg, wxEmptyString );
+ }
+}
+
+
+void NETLIST_DIALOG::OnDelPlugin( wxCommandEvent& event )
+{
+ NETLIST_PAGE_DIALOG* currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
+
+ currPage->m_CommandStringCtrl->SetValue( wxEmptyString );
+ currPage->m_TitleStringCtrl->SetValue( wxEmptyString );
+
+ if( currPage->m_IsCurrentFormat->IsChecked() )
+ {
+ currPage->m_IsCurrentFormat->SetValue( false );
+ m_PanelNetType[PANELPCBNEW]->m_IsCurrentFormat->SetValue( true );
+ }
+
+ WriteCurrentNetlistSetup();
+ EndModal( NET_PLUGIN_CHANGE );
+}
+
+
+void NETLIST_DIALOG::OnAddPlugin( wxCommandEvent& event )
+{
+ NETLIST_DIALOG_ADD_PLUGIN dlg( this );
+ if( dlg.ShowModal() != wxID_OK )
+ return;
+
+ // Creates a new custom plugin page
+ wxString title = dlg.GetPluginTitle();
+
+ // Verify it does not exists
+ int netTypeId = PANELCUSTOMBASE; // the first not used type id
+ NETLIST_PAGE_DIALOG* currPage;
+ for( int ii = 0; ii < CUSTOMPANEL_COUNTMAX; ii++ )
+ {
+ netTypeId = PANELCUSTOMBASE + ii;
+ currPage = m_PanelNetType[ii + PANELCUSTOMBASE];
+
+ if( currPage == NULL )
+ break;
+
+ if( currPage->GetPageNetFmtName() == title )
+ {
+ wxMessageBox( _("This plugin already exists. Abort") );
+ return;
+ }
+ }
+
+ wxString cmd = dlg.GetPluginTCommandLine();
+ currPage = AddOneCustomPage( title,cmd, (NETLIST_TYPE_ID)netTypeId );
+ m_PanelNetType[netTypeId] = currPage;
+ WriteCurrentNetlistSetup();
+
+ // Close and reopen dialog to rebuild the dialog after changes
+ EndModal( NET_PLUGIN_CHANGE );
+}
+
+
+NETLIST_DIALOG_ADD_PLUGIN::NETLIST_DIALOG_ADD_PLUGIN( NETLIST_DIALOG* parent ) :
+ NETLIST_DIALOG_ADD_PLUGIN_BASE( parent )
+{
+ m_Parent = parent;
+ GetSizer()->SetSizeHints( this );
+}
+
+
+void NETLIST_DIALOG_ADD_PLUGIN::OnOKClick( wxCommandEvent& event )
+{
+ if( m_textCtrlCommand->GetValue() == wxEmptyString )
+ {
+ wxMessageBox( _( "Error. You must provide a command String" ) );
+ return;
+ }
+
+ if( m_textCtrlName->GetValue() == wxEmptyString )
+ {
+ wxMessageBox( _( "Error. You must provide a Title" ) );
+ return;
+ }
+
+ EndModal( wxID_OK );
+}
+
+
+void NETLIST_DIALOG_ADD_PLUGIN::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+void NETLIST_DIALOG_ADD_PLUGIN::OnBrowsePlugins( wxCommandEvent& event )
+{
+ wxString FullFileName, Mask, Path;
+
+ Mask = wxT( "*" );
+#ifndef __WXMAC__
+ Path = Pgm().GetExecutablePath();
+#else
+ Path = GetOSXKicadDataDir() + wxT( "/plugins" );
+#endif
+ FullFileName = EDA_FILE_SELECTOR( _( "Plugin files:" ),
+ Path,
+ FullFileName,
+ wxEmptyString,
+ Mask,
+ this,
+ wxFD_OPEN,
+ true
+ );
+ if( FullFileName.IsEmpty() )
+ return;
+
+ // Creates a default command line, suitable for external tool xslproc or python
+ // try to build a default command line depending on plugin extension
+ // "xsl" or "exe" or "py"
+ wxString cmdLine;
+ wxFileName fn( FullFileName );
+ wxString ext = fn.GetExt();
+
+ if( ext == wxT("xsl" ) )
+ cmdLine.Printf(wxT("xsltproc -o \"%%O\" \"%s\" \"%%I\""), GetChars(FullFileName) );
+ else if( ext == wxT("exe" ) || ext.IsEmpty() )
+ cmdLine.Printf(wxT("\"%s\" > \"%%O\" < \"%%I\""), GetChars(FullFileName) );
+ else if( ext == wxT("py" ) || ext.IsEmpty() )
+ cmdLine.Printf(wxT("python \"%s\" \"%%I\" \"%%O\""), GetChars(FullFileName) );
+ else
+ cmdLine.Printf(wxT("\"%s\""), GetChars(FullFileName) );
+
+ m_textCtrlCommand->SetValue( cmdLine );
+
+ /* Get a title for this page */
+ wxString title = m_textCtrlName->GetValue();
+
+ if( title.IsEmpty() )
+ wxMessageBox( _( "Do not forget to choose a title for this netlist control page" ) );
+}
+
+
+int InvokeDialogNetList( SCH_EDIT_FRAME* aCaller )
+{
+ NETLIST_DIALOG dlg( aCaller );
+
+ return dlg.ShowModal();
+}
+
diff --git a/eeschema/dialogs/dialog_netlist_base.cpp b/eeschema/dialogs/dialog_netlist_base.cpp
new file mode 100644
index 0000000..39a8d0d
--- /dev/null
+++ b/eeschema/dialogs/dialog_netlist_base.cpp
@@ -0,0 +1,151 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_netlist_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+BEGIN_EVENT_TABLE( NETLIST_DIALOG_BASE, DIALOG_SHIM )
+ EVT_NOTEBOOK_PAGE_CHANGED( ID_CHANGE_NOTEBOOK_PAGE, NETLIST_DIALOG_BASE::_wxFB_OnNetlistTypeSelection )
+ EVT_BUTTON( ID_CREATE_NETLIST, NETLIST_DIALOG_BASE::_wxFB_GenNetlist )
+ EVT_BUTTON( wxID_CANCEL, NETLIST_DIALOG_BASE::_wxFB_OnCancelClick )
+ EVT_BUTTON( ID_ADD_PLUGIN, NETLIST_DIALOG_BASE::_wxFB_OnAddPlugin )
+ EVT_BUTTON( ID_DEL_PLUGIN, NETLIST_DIALOG_BASE::_wxFB_OnDelPlugin )
+END_EVENT_TABLE()
+
+NETLIST_DIALOG_BASE::NETLIST_DIALOG_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bRightSizer;
+ bRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_NoteBook = new wxNotebook( this, ID_CHANGE_NOTEBOOK_PAGE, wxDefaultPosition, wxDefaultSize, 0 );
+
+ bRightSizer->Add( m_NoteBook, 1, wxEXPAND | wxALL, 5 );
+
+
+ bUpperSizer->Add( bRightSizer, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bLeftSizer;
+ bLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+
+ bLeftSizer->Add( 0, 0, 0, wxTOP, 15 );
+
+ m_buttonNetlist = new wxButton( this, ID_CREATE_NETLIST, _("Generate"), wxDefaultPosition, wxDefaultSize, 0 );
+ bLeftSizer->Add( m_buttonNetlist, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
+ bLeftSizer->Add( m_buttonCancel, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonAddPlugin = new wxButton( this, ID_ADD_PLUGIN, _("Add Plugin"), wxDefaultPosition, wxDefaultSize, 0 );
+ bLeftSizer->Add( m_buttonAddPlugin, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonDelPlugin = new wxButton( this, ID_DEL_PLUGIN, _("Remove Plugin"), wxDefaultPosition, wxDefaultSize, 0 );
+ bLeftSizer->Add( m_buttonDelPlugin, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bLeftSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_cbUseDefaultNetlistName = new wxCheckBox( this, wxID_ANY, _("Use default netname"), wxDefaultPosition, wxDefaultSize, 0 );
+ bLeftSizer->Add( m_cbUseDefaultNetlistName, 0, wxALL, 5 );
+
+
+ bUpperSizer->Add( bLeftSizer, 0, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bUpperSizer, 1, wxEXPAND, 5 );
+
+ m_staticTextDefaultFN = new wxStaticText( this, wxID_ANY, _("Default Netlist Filename:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextDefaultFN->Wrap( -1 );
+ bMainSizer->Add( m_staticTextDefaultFN, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_textCtrlDefaultFileName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ m_textCtrlDefaultFileName->SetMaxLength( 0 );
+ bMainSizer->Add( m_textCtrlDefaultFileName, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+}
+
+NETLIST_DIALOG_BASE::~NETLIST_DIALOG_BASE()
+{
+}
+
+BEGIN_EVENT_TABLE( NETLIST_DIALOG_ADD_PLUGIN_BASE, DIALOG_SHIM )
+ EVT_BUTTON( wxID_OK, NETLIST_DIALOG_ADD_PLUGIN_BASE::_wxFB_OnOKClick )
+ EVT_BUTTON( wxID_CANCEL, NETLIST_DIALOG_ADD_PLUGIN_BASE::_wxFB_OnCancelClick )
+ EVT_BUTTON( wxID_BROWSE_PLUGINS, NETLIST_DIALOG_ADD_PLUGIN_BASE::_wxFB_OnBrowsePlugins )
+END_EVENT_TABLE()
+
+NETLIST_DIALOG_ADD_PLUGIN_BASE::NETLIST_DIALOG_ADD_PLUGIN_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizerLeft;
+ bSizerLeft = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextCmd = new wxStaticText( this, wxID_ANY, _("Netlist command:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextCmd->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextCmd, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_textCtrlCommand = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textCtrlCommand->SetMaxLength( 0 );
+ m_textCtrlCommand->SetMinSize( wxSize( 300,-1 ) );
+
+ bSizerLeft->Add( m_textCtrlCommand, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticTextName = new wxStaticText( this, wxID_ANY, _("Name:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextName->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextName, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_textCtrlName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textCtrlName->SetMaxLength( 0 );
+ bSizerLeft->Add( m_textCtrlName, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerMain->Add( bSizerLeft, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerRight;
+ bSizerRight = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonOK->SetDefault();
+ bSizerRight->Add( m_buttonOK, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerRight->Add( m_buttonCancel, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonPlugin = new wxButton( this, wxID_BROWSE_PLUGINS, _("Browse Plugins"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerRight->Add( m_buttonPlugin, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bSizerRight, 0, wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+}
+
+NETLIST_DIALOG_ADD_PLUGIN_BASE::~NETLIST_DIALOG_ADD_PLUGIN_BASE()
+{
+}
diff --git a/eeschema/dialogs/dialog_netlist_base.fbp b/eeschema/dialogs/dialog_netlist_base.fbp
new file mode 100644
index 0000000..c435a73
--- /dev/null
+++ b/eeschema/dialogs/dialog_netlist_base.fbp
@@ -0,0 +1,1624 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">0</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">table</property>
+ <property name="file">dialog_netlist_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_netlist_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">NETLIST_DIALOG_BASE</property>
+ <property name="pos"></property>
+ <property name="size">404,334</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Netlist</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxNotebook" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmapsize"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CHANGE_NOTEBOOK_PAGE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NoteBook</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnNotebookPageChanged">OnNetlistTypeSelection</event>
+ <event name="OnNotebookPageChanging"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">15</property>
+ <property name="flag">wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CREATE_NETLIST</property>
+ <property name="label">Generate</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonNetlist</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">GenNetlist</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Cancel</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonCancel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADD_PLUGIN</property>
+ <property name="label">Add Plugin</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonAddPlugin</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnAddPlugin</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_DEL_PLUGIN</property>
+ <property name="label">Remove Plugin</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonDelPlugin</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnDelPlugin</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Use default netname</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbUseDefaultNetlistName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default Netlist Filename:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextDefaultFN</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlDefaultFileName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">NETLIST_DIALOG_ADD_PLUGIN_BASE</property>
+ <property name="pos"></property>
+ <property name="size">312,144</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Plugins:</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerLeft</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Netlist command:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextCmd</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">300,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlCommand</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Name:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRight</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_OK</property>
+ <property name="label">OK</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonOK</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnOKClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Cancel</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonCancel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_BROWSE_PLUGINS</property>
+ <property name="label">Browse Plugins</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPlugin</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnBrowsePlugins</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_netlist_base.h b/eeschema/dialogs/dialog_netlist_base.h
new file mode 100644
index 0000000..6cfeda2
--- /dev/null
+++ b/eeschema/dialogs/dialog_netlist_base.h
@@ -0,0 +1,124 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_NETLIST_BASE_H__
+#define __DIALOG_NETLIST_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/gdicmn.h>
+#include <wx/notebook.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/string.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/statline.h>
+#include <wx/checkbox.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class NETLIST_DIALOG_BASE
+///////////////////////////////////////////////////////////////////////////////
+class NETLIST_DIALOG_BASE : public DIALOG_SHIM
+{
+ DECLARE_EVENT_TABLE()
+ private:
+
+ // Private event handlers
+ void _wxFB_OnNetlistTypeSelection( wxNotebookEvent& event ){ OnNetlistTypeSelection( event ); }
+ void _wxFB_GenNetlist( wxCommandEvent& event ){ GenNetlist( event ); }
+ void _wxFB_OnCancelClick( wxCommandEvent& event ){ OnCancelClick( event ); }
+ void _wxFB_OnAddPlugin( wxCommandEvent& event ){ OnAddPlugin( event ); }
+ void _wxFB_OnDelPlugin( wxCommandEvent& event ){ OnDelPlugin( event ); }
+
+
+ protected:
+ enum
+ {
+ ID_CHANGE_NOTEBOOK_PAGE = 1000,
+ ID_CREATE_NETLIST,
+ ID_ADD_PLUGIN,
+ ID_DEL_PLUGIN
+ };
+
+ wxNotebook* m_NoteBook;
+ wxButton* m_buttonNetlist;
+ wxButton* m_buttonCancel;
+ wxButton* m_buttonAddPlugin;
+ wxButton* m_buttonDelPlugin;
+ wxStaticLine* m_staticline1;
+ wxCheckBox* m_cbUseDefaultNetlistName;
+ wxStaticText* m_staticTextDefaultFN;
+ wxTextCtrl* m_textCtrlDefaultFileName;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnNetlistTypeSelection( wxNotebookEvent& event ) { event.Skip(); }
+ virtual void GenNetlist( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnAddPlugin( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnDelPlugin( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ NETLIST_DIALOG_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Netlist"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 404,334 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~NETLIST_DIALOG_BASE();
+
+};
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class NETLIST_DIALOG_ADD_PLUGIN_BASE
+///////////////////////////////////////////////////////////////////////////////
+class NETLIST_DIALOG_ADD_PLUGIN_BASE : public DIALOG_SHIM
+{
+ DECLARE_EVENT_TABLE()
+ private:
+
+ // Private event handlers
+ void _wxFB_OnOKClick( wxCommandEvent& event ){ OnOKClick( event ); }
+ void _wxFB_OnCancelClick( wxCommandEvent& event ){ OnCancelClick( event ); }
+ void _wxFB_OnBrowsePlugins( wxCommandEvent& event ){ OnBrowsePlugins( event ); }
+
+
+ protected:
+ enum
+ {
+ wxID_BROWSE_PLUGINS = 1000
+ };
+
+ wxStaticText* m_staticTextCmd;
+ wxTextCtrl* m_textCtrlCommand;
+ wxStaticText* m_staticTextName;
+ wxTextCtrl* m_textCtrlName;
+ wxButton* m_buttonOK;
+ wxButton* m_buttonCancel;
+ wxButton* m_buttonPlugin;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnBrowsePlugins( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ NETLIST_DIALOG_ADD_PLUGIN_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Plugins:"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 312,144 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~NETLIST_DIALOG_ADD_PLUGIN_BASE();
+
+};
+
+#endif //__DIALOG_NETLIST_BASE_H__
diff --git a/eeschema/dialogs/dialog_plot_schematic.cpp b/eeschema/dialogs/dialog_plot_schematic.cpp
new file mode 100644
index 0000000..2ddd5db
--- /dev/null
+++ b/eeschema/dialogs/dialog_plot_schematic.cpp
@@ -0,0 +1,357 @@
+/** @file dialog_plot_schematic.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2010 Lorenzo Marcantonio
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <worksheet.h>
+#include <plot_common.h>
+#include <class_sch_screen.h>
+#include <schframe.h>
+#include <base_units.h>
+#include <sch_sheet.h>
+#include <dialog_plot_schematic.h>
+#include <wx_html_report_panel.h>
+
+// Keys for configuration
+#define PLOT_FORMAT_KEY wxT( "PlotFormat" )
+#define PLOT_MODECOLOR_KEY wxT( "PlotModeColor" )
+#define PLOT_FRAME_REFERENCE_KEY wxT( "PlotFrameRef" )
+#define PLOT_HPGL_ORIGIN_KEY wxT( "PlotHPGLOrg" )
+#define PLOT_HPGL_PAPERSIZE_KEY wxT( "PlotHPGLPaperSize" )
+#define PLOT_HPGL_PEN_SIZE_KEY wxT( "PlotHPGLPenSize" )
+
+
+
+// static members (static to remember last state):
+int DIALOG_PLOT_SCHEMATIC::m_pageSizeSelect = PAGE_SIZE_AUTO;
+
+
+void SCH_EDIT_FRAME::PlotSchematic( wxCommandEvent& event )
+{
+ DIALOG_PLOT_SCHEMATIC dlg( this );
+
+ dlg.ShowModal();
+
+ // save project config if the prj config has changed:
+ if( dlg.PrjConfigChanged() )
+ SaveProjectSettings( true );
+}
+
+
+DIALOG_PLOT_SCHEMATIC::DIALOG_PLOT_SCHEMATIC( SCH_EDIT_FRAME* parent ) :
+ DIALOG_PLOT_SCHEMATIC_BASE( parent )
+{
+ m_parent = parent;
+ m_configChanged = false;
+ m_config = Kiface().KifaceSettings();
+
+ initDlg();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+
+// Initialize the dialog options:
+void DIALOG_PLOT_SCHEMATIC::initDlg()
+{
+ // Set paper size option
+ m_PaperSizeOption->SetSelection( m_pageSizeSelect );
+
+ // Set color or B&W plot option
+ bool tmp;
+ m_config->Read( PLOT_MODECOLOR_KEY, &tmp, true );
+ setModeColor( tmp );
+
+ // Set plot or not frame reference option
+ m_config->Read( PLOT_FRAME_REFERENCE_KEY, &tmp, true );
+ setPlotFrameRef( tmp );
+
+ // Set HPGL plot origin to center of paper of left bottom corner
+ m_config->Read( PLOT_HPGL_ORIGIN_KEY, &tmp, false );
+ SetPlotOriginCenter( tmp );
+
+ m_config->Read( PLOT_HPGL_PAPERSIZE_KEY, &m_HPGLPaperSizeSelect, 0 );
+ m_HPGLPaperSizeOption->SetSelection( m_HPGLPaperSizeSelect );
+
+ // HPGL Pen Size is stored in mm in config
+ m_config->Read( PLOT_HPGL_PEN_SIZE_KEY, &m_HPGLPenSize, 0.5 );
+ m_HPGLPenSize *= IU_PER_MM;
+
+ // Switch to the last save plot format
+ long plotfmt;
+ m_config->Read( PLOT_FORMAT_KEY, &plotfmt, 0 );
+
+ switch( plotfmt )
+ {
+ default:
+ case PLOT_FORMAT_POST:
+ m_plotFormatOpt->SetSelection( 0 );
+ break;
+
+ case PLOT_FORMAT_PDF:
+ m_plotFormatOpt->SetSelection( 1 );
+ break;
+
+ case PLOT_FORMAT_SVG:
+ m_plotFormatOpt->SetSelection( 2 );
+ break;
+
+ case PLOT_FORMAT_DXF:
+ m_plotFormatOpt->SetSelection( 3 );
+ break;
+
+ case PLOT_FORMAT_HPGL:
+ m_plotFormatOpt->SetSelection( 4 );
+ break;
+ }
+
+ // Set the default line width (pen width which should be used for
+ // items that do not have a pen size defined (like frame ref)
+ AddUnitSymbol( *m_defaultLineWidthTitle, g_UserUnit );
+ PutValueInLocalUnits( *m_DefaultLineSizeCtrl, GetDefaultLineThickness() );
+
+ // Initialize HPGL specific widgets
+ AddUnitSymbol( *m_penHPLGWidthTitle, g_UserUnit );
+ PutValueInLocalUnits( *m_penHPGLWidthCtrl, m_HPGLPenSize );
+ m_HPGLPaperSizeOption->SetSelection( m_HPGLPaperSizeSelect );
+
+ // Plot directory
+ wxString path = m_parent->GetPlotDirectoryName();
+#ifdef __WINDOWS__
+ path.Replace( '/', '\\' );
+#endif
+ m_outputDirectoryName->SetValue( path );
+
+ // Hide/show widgets that are not always displayed:
+ wxCommandEvent cmd_event;
+ OnPlotFormatSelection( cmd_event );
+}
+
+/*
+ * TODO: Copy of DIALOG_PLOT::OnOutputDirectoryBrowseClicked in dialog_plot.cpp, maybe merge to a common method.
+ */
+void DIALOG_PLOT_SCHEMATIC::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
+{
+ // Build the absolute path of current output plot directory
+ // to preselect it when opening the dialog.
+ wxFileName fn( m_outputDirectoryName->GetValue() );
+ wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() );
+
+ wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
+
+ if( dirDialog.ShowModal() == wxID_CANCEL )
+ {
+ return;
+ }
+
+ wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
+
+ fn = Prj().AbsolutePath( g_RootSheet->GetFileName() );
+ wxString defaultPath = fn.GetPathWithSep();
+ wxString msg;
+ msg.Printf( _( "Do you want to use a path relative to\n'%s'" ),
+ GetChars( defaultPath ) );
+
+ wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
+ wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
+
+ // relative directory selected
+ if( dialog.ShowModal() == wxID_YES )
+ {
+ if( !dirName.MakeRelativeTo( defaultPath ) )
+ wxMessageBox( _( "Cannot make path relative (target volume different from file volume)!" ),
+ _( "Plot Output Directory" ), wxOK | wxICON_ERROR );
+ }
+
+ m_outputDirectoryName->SetValue( dirName.GetFullPath() );
+}
+
+PlotFormat DIALOG_PLOT_SCHEMATIC::GetPlotFileFormat()
+{
+ switch( m_plotFormatOpt->GetSelection() )
+ {
+ default:
+ case 0: return PLOT_FORMAT_POST;
+ case 1: return PLOT_FORMAT_PDF;
+ case 2: return PLOT_FORMAT_SVG;
+ case 3: return PLOT_FORMAT_DXF;
+ case 4: return PLOT_FORMAT_HPGL;
+ }
+}
+
+
+void DIALOG_PLOT_SCHEMATIC::OnButtonCancelClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+void DIALOG_PLOT_SCHEMATIC::getPlotOptions()
+{
+ m_config->Write( PLOT_MODECOLOR_KEY, getModeColor() );
+ m_config->Write( PLOT_FRAME_REFERENCE_KEY, getPlotFrameRef() );
+ m_config->Write( PLOT_FORMAT_KEY, (long) GetPlotFileFormat() );
+ m_config->Write( PLOT_HPGL_ORIGIN_KEY, GetPlotOriginCenter() );
+ m_HPGLPaperSizeSelect = m_HPGLPaperSizeOption->GetSelection();
+ m_config->Write( PLOT_HPGL_PAPERSIZE_KEY, m_HPGLPaperSizeSelect );
+ // HPGL Pen Size is stored in mm in config
+ m_config->Write( PLOT_HPGL_PEN_SIZE_KEY, m_HPGLPenSize/IU_PER_MM );
+
+ m_pageSizeSelect = m_PaperSizeOption->GetSelection();
+ SetDefaultLineThickness( ValueFromTextCtrl( *m_DefaultLineSizeCtrl ) );
+
+ // Plot directory
+ wxString path = m_outputDirectoryName->GetValue();
+ path.Replace( '\\', '/' );
+
+ if( m_parent->GetPlotDirectoryName() != path )
+ m_configChanged = true;
+
+ m_parent->SetPlotDirectoryName( path );
+
+}
+
+
+void DIALOG_PLOT_SCHEMATIC::OnPlotFormatSelection( wxCommandEvent& event )
+{
+
+ switch( GetPlotFileFormat() )
+ {
+ default:
+ case PLOT_FORMAT_POST:
+ m_paperOptionsSizer->Hide( m_paperHPGLSizer );
+ m_paperOptionsSizer->Show( m_PaperSizeOption );
+ m_PaperSizeOption->Enable( true );
+ m_DefaultLineSizeCtrl->Enable( true );
+ break;
+
+ case PLOT_FORMAT_PDF:
+ m_paperOptionsSizer->Hide( m_paperHPGLSizer );
+ m_paperOptionsSizer->Show(m_PaperSizeOption);
+ m_PaperSizeOption->Enable( true );
+ m_DefaultLineSizeCtrl->Enable( true );
+ break;
+
+ case PLOT_FORMAT_SVG:
+ m_paperOptionsSizer->Hide( m_paperHPGLSizer );
+ m_paperOptionsSizer->Show(m_PaperSizeOption);
+ m_PaperSizeOption->Enable( false );
+ m_DefaultLineSizeCtrl->Enable( true );
+ break;
+
+ case PLOT_FORMAT_DXF:
+ m_paperOptionsSizer->Hide( m_paperHPGLSizer );
+ m_paperOptionsSizer->Show(m_PaperSizeOption);
+ m_PaperSizeOption->Enable( false );
+ m_DefaultLineSizeCtrl->Enable( false );
+ break;
+
+ case PLOT_FORMAT_HPGL:
+ m_paperOptionsSizer->Show( m_paperHPGLSizer );
+ m_paperOptionsSizer->Hide(m_PaperSizeOption);
+ m_DefaultLineSizeCtrl->Enable( false );
+ break;
+
+ }
+
+ GetSizer()->SetSizeHints( this );
+}
+
+
+void DIALOG_PLOT_SCHEMATIC::OnButtonPlotCurrentClick( wxCommandEvent& event )
+{
+ PlotSchematic( false );
+}
+
+
+void DIALOG_PLOT_SCHEMATIC::OnButtonPlotAllClick( wxCommandEvent& event )
+{
+ PlotSchematic( true );
+}
+
+
+void DIALOG_PLOT_SCHEMATIC::PlotSchematic( bool aPlotAll )
+{
+ getPlotOptions();
+
+ switch( GetPlotFileFormat() )
+ {
+ case PLOT_FORMAT_HPGL:
+ createHPGLFile( aPlotAll, getPlotFrameRef() );
+ break;
+
+ case PLOT_FORMAT_DXF:
+ CreateDXFFile( aPlotAll, getPlotFrameRef() );
+ break;
+
+ case PLOT_FORMAT_PDF:
+ createPDFFile( aPlotAll, getPlotFrameRef() );
+ break;
+
+ case PLOT_FORMAT_SVG:
+ createSVGFile( aPlotAll, getPlotFrameRef() );
+ break;
+
+ case PLOT_FORMAT_POST:
+ // Fall through. Default to Postscript.
+ default:
+ createPSFile( aPlotAll, getPlotFrameRef() );
+ break;
+
+ }
+}
+
+wxFileName DIALOG_PLOT_SCHEMATIC::createPlotFileName( wxTextCtrl* aOutputDirectoryName,
+ wxString& aPlotFileName,
+ wxString& aExtension,
+ REPORTER* aReporter )
+{
+ wxString outputDirName = aOutputDirectoryName->GetValue();
+ wxFileName outputDir = wxFileName::DirName( outputDirName );
+
+ wxString plotFileName = Prj().AbsolutePath( aPlotFileName + wxT(".") + aExtension);
+
+ if( !EnsureFileDirectoryExists( &outputDir, plotFileName, aReporter ) )
+ {
+ wxString msg;
+ msg.Printf( _( "Could not write plot files to folder '%s'." ),
+ GetChars( outputDir.GetPath() ) );
+ aReporter->Report( msg, REPORTER::RPT_ERROR );
+ }
+
+ wxFileName fn( plotFileName );
+ fn.SetPath( outputDir.GetFullPath() );
+ return fn;
+}
diff --git a/eeschema/dialogs/dialog_plot_schematic.h b/eeschema/dialogs/dialog_plot_schematic.h
new file mode 100644
index 0000000..69cf6c0
--- /dev/null
+++ b/eeschema/dialogs/dialog_plot_schematic.h
@@ -0,0 +1,157 @@
+/** @file dialog_plot_schematic.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2014 Jean-Pierre Charras <jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2010 Lorenzo Marcantonio
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <plot_common.h>
+#include <class_sch_screen.h>
+#include <schframe.h>
+#include <dialog_plot_schematic_base.h>
+#include <reporter.h>
+
+
+enum PageFormatReq {
+ PAGE_SIZE_AUTO,
+ PAGE_SIZE_A4,
+ PAGE_SIZE_A
+};
+
+
+class DIALOG_PLOT_SCHEMATIC : public DIALOG_PLOT_SCHEMATIC_BASE
+{
+private:
+ SCH_EDIT_FRAME* m_parent;
+ wxConfigBase* m_config;
+ bool m_configChanged; // true if a project config param has changed
+ static int m_pageSizeSelect; // Static to keep last option for some format:
+ // Static to keep last option:
+ // use default size or force A or A4 size
+ int m_HPGLPaperSizeSelect; // for HPGL format only: last selected paper size
+ double m_HPGLPenSize; // for HPGL format only: pen size
+
+public:
+ // / Constructors
+ DIALOG_PLOT_SCHEMATIC( SCH_EDIT_FRAME* parent );
+
+ bool PrjConfigChanged() { return m_configChanged; } // return true if the prj config was modified
+ // and therefore should be saved
+
+private:
+ void OnPlotFormatSelection( wxCommandEvent& event );
+ void OnButtonPlotCurrentClick( wxCommandEvent& event );
+ void OnButtonPlotAllClick( wxCommandEvent& event );
+ void OnButtonCancelClick( wxCommandEvent& event );
+
+ void initDlg();
+
+ // common
+ void getPlotOptions();
+
+ bool getModeColor()
+ { return m_ModeColorOption->GetSelection() == 0; }
+
+ void setModeColor( bool aColor )
+ { m_ModeColorOption->SetSelection( aColor ? 0 : 1 ); }
+
+ /**
+ * Set the m_outputDirectoryName variable to the selected directory from directory dialog.
+ */
+ void OnOutputDirectoryBrowseClicked( wxCommandEvent& event );
+
+ PlotFormat GetPlotFileFormat();
+
+ bool getPlotFrameRef() { return m_PlotFrameRefOpt->GetValue(); }
+ void setPlotFrameRef( bool aPlot) {m_PlotFrameRefOpt->SetValue( aPlot ); }
+
+ void PlotSchematic( bool aPlotAll );
+
+ // PDF
+ void createPDFFile( bool aPlotAll, bool aPlotFrameRef );
+ void plotOneSheetPDF( PLOTTER* aPlotter, SCH_SCREEN* aScreen, bool aPlotFrameRef);
+ void setupPlotPagePDF( PLOTTER* aPlotter, SCH_SCREEN* aScreen );
+
+ /**
+ * Everything done, close the plot and restore the environment
+ * @param aPlotter the plotter to close and destroy
+ * @param aOldsheetpath the stored old sheet path for the current sheet before the plot started
+ */
+ void restoreEnvironment( PDF_PLOTTER* aPlotter, SCH_SHEET_PATH& aOldsheetpath );
+
+ // DXF
+ void CreateDXFFile( bool aPlotAll, bool aPlotFrameRef );
+ bool PlotOneSheetDXF( const wxString& aFileName, SCH_SCREEN* aScreen,
+ wxPoint aPlot0ffset, double aScale, bool aPlotFrameRef );
+
+ // HPGL
+ bool GetPlotOriginCenter()
+ {
+ return m_plotOriginOpt->GetSelection() == 1;
+ }
+
+ void SetPlotOriginCenter( bool aCenter )
+ {
+ m_plotOriginOpt->SetSelection( aCenter ? 1 : 0 );
+ }
+
+ void createHPGLFile( bool aPlotAll, bool aPlotFrameRef );
+ void SetHPGLPenWidth();
+ bool Plot_1_Page_HPGL( const wxString& aFileName, SCH_SCREEN* aScreen,
+ const PAGE_INFO& aPageInfo,
+ wxPoint aPlot0ffset, double aScale, bool aPlotFrameRef );
+
+ // PS
+ void createPSFile( bool aPlotAll, bool aPlotFrameRef );
+ bool plotOneSheetPS( const wxString& aFileName, SCH_SCREEN* aScreen,
+ const PAGE_INFO& aPageInfo,
+ wxPoint aPlot0ffset, double aScale, bool aPlotFrameRef );
+
+ // SVG
+ void createSVGFile( bool aPlotAll, bool aPlotFrameRef );
+
+ /**
+ * Create a file name with an absolute path name
+ * @param aOutputDirectoryName the diretory name to plot,
+ * this can be a relative name of the current project diretory or an absolute directory name.
+ * @param aPlotFileName the name for the file to plot without a path
+ * @param aExtension the extension for the file to plot
+ * @param aReporter a point to a REPORTER object use to show messages (can be NULL)
+ * @return the created file name
+ * @throw IO_ERROR on file I/O errors
+ */
+ wxFileName createPlotFileName( wxTextCtrl* aOutputDirectoryName,
+ wxString& aPlotFileName,
+ wxString& aExtension, REPORTER* aReporter = NULL );
+
+public:
+ // This function is static because it is called by libedit
+ // outside a dialog. This is the reason we need aFrame as parameter
+ static bool plotOneSheetSVG( EDA_DRAW_FRAME* aFrame, const wxString& aFileName,
+ SCH_SCREEN* aScreen,
+ bool aPlotBlackAndWhite, bool aPlotFrameRef );
+};
diff --git a/eeschema/dialogs/dialog_plot_schematic_base.cpp b/eeschema/dialogs/dialog_plot_schematic_base.cpp
new file mode 100644
index 0000000..ca6467d
--- /dev/null
+++ b/eeschema/dialogs/dialog_plot_schematic_base.cpp
@@ -0,0 +1,184 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 6 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "wx_html_report_panel.h"
+
+#include "dialog_plot_schematic_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_PLOT_SCHEMATIC_BASE::DIALOG_PLOT_SCHEMATIC_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizer6;
+ bSizer6 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextOutputDirectory = new wxStaticText( this, wxID_ANY, _("Output directory:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextOutputDirectory->Wrap( -1 );
+ bSizer6->Add( m_staticTextOutputDirectory, 0, wxALL, 5 );
+
+ wxBoxSizer* bSizer5;
+ bSizer5 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_outputDirectoryName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_outputDirectoryName->SetMaxLength( 0 );
+ m_outputDirectoryName->SetToolTip( _("Target directory for plot files. Can be absolute or relative to the schematic main file location.") );
+
+ bSizer5->Add( m_outputDirectoryName, 1, wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_browseButton = new wxButton( this, wxID_ANY, _("Browse..."), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer5->Add( m_browseButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
+
+
+ bSizer6->Add( bSizer5, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bSizer6, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_optionsSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ m_paperOptionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Paper Options") ), wxVERTICAL );
+
+ wxString m_PaperSizeOptionChoices[] = { _("Schematic size"), _("Force size A4"), _("Force size A") };
+ int m_PaperSizeOptionNChoices = sizeof( m_PaperSizeOptionChoices ) / sizeof( wxString );
+ m_PaperSizeOption = new wxRadioBox( this, wxID_ANY, _("Page Size:"), wxDefaultPosition, wxDefaultSize, m_PaperSizeOptionNChoices, m_PaperSizeOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_PaperSizeOption->SetSelection( 1 );
+ m_paperOptionsSizer->Add( m_PaperSizeOption, 0, wxALL|wxEXPAND, 5 );
+
+ m_paperHPGLSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("HPGL Options") ), wxVERTICAL );
+
+ m_staticText4 = new wxStaticText( this, wxID_ANY, _("Page Size:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText4->Wrap( -1 );
+ m_paperHPGLSizer->Add( m_staticText4, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_HPGLPaperSizeOptionChoices[] = { _("Schematic size"), _("Page size A4"), _("Page size A3"), _("Page size A2"), _("Page size A1"), _("Page size A0"), _("Page size A"), _("Page size B"), _("Page size C"), _("Page size D"), _("Page size E") };
+ int m_HPGLPaperSizeOptionNChoices = sizeof( m_HPGLPaperSizeOptionChoices ) / sizeof( wxString );
+ m_HPGLPaperSizeOption = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_HPGLPaperSizeOptionNChoices, m_HPGLPaperSizeOptionChoices, 0 );
+ m_HPGLPaperSizeOption->SetSelection( 0 );
+ m_paperHPGLSizer->Add( m_HPGLPaperSizeOption, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ wxString m_plotOriginOptChoices[] = { _("Bottom left corner"), _("Center of the page") };
+ int m_plotOriginOptNChoices = sizeof( m_plotOriginOptChoices ) / sizeof( wxString );
+ m_plotOriginOpt = new wxRadioBox( this, wxID_ANY, _("Origin"), wxDefaultPosition, wxDefaultSize, m_plotOriginOptNChoices, m_plotOriginOptChoices, 1, wxRA_SPECIFY_COLS );
+ m_plotOriginOpt->SetSelection( 0 );
+ m_paperHPGLSizer->Add( m_plotOriginOpt, 0, wxALL, 5 );
+
+ m_penHPLGWidthTitle = new wxStaticText( this, wxID_ANY, _("Pen width"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_penHPLGWidthTitle->Wrap( -1 );
+ m_paperHPGLSizer->Add( m_penHPLGWidthTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_penHPGLWidthCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_penHPGLWidthCtrl->SetMaxLength( 0 );
+ m_paperHPGLSizer->Add( m_penHPGLWidthCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ m_paperOptionsSizer->Add( m_paperHPGLSizer, 1, wxEXPAND, 5 );
+
+
+ m_optionsSizer->Add( m_paperOptionsSizer, 0, wxEXPAND, 5 );
+
+ wxString m_plotFormatOptChoices[] = { _("Postscript"), _("PDF"), _("SVG"), _("DXF"), _("HPGL") };
+ int m_plotFormatOptNChoices = sizeof( m_plotFormatOptChoices ) / sizeof( wxString );
+ m_plotFormatOpt = new wxRadioBox( this, wxID_ANY, _("Format"), wxDefaultPosition, wxDefaultSize, m_plotFormatOptNChoices, m_plotFormatOptChoices, 1, wxRA_SPECIFY_COLS );
+ m_plotFormatOpt->SetSelection( 1 );
+ m_optionsSizer->Add( m_plotFormatOpt, 0, wxEXPAND|wxLEFT, 5 );
+
+ wxStaticBoxSizer* sbSizerPlotFormat;
+ sbSizerPlotFormat = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("General Options") ), wxVERTICAL );
+
+ m_defaultLineWidthTitle = new wxStaticText( this, wxID_ANY, _("Default line thickness"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_defaultLineWidthTitle->Wrap( -1 );
+ sbSizerPlotFormat->Add( m_defaultLineWidthTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_DefaultLineSizeCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_DefaultLineSizeCtrl->SetMaxLength( 0 );
+ m_DefaultLineSizeCtrl->SetToolTip( _("Selection of the default pen thickness used to draw items, when their thickness is set to 0.") );
+
+ sbSizerPlotFormat->Add( m_DefaultLineSizeCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ wxString m_ModeColorOptionChoices[] = { _("Color"), _("Black and white") };
+ int m_ModeColorOptionNChoices = sizeof( m_ModeColorOptionChoices ) / sizeof( wxString );
+ m_ModeColorOption = new wxRadioBox( this, wxID_ANY, _("Mode"), wxDefaultPosition, wxDefaultSize, m_ModeColorOptionNChoices, m_ModeColorOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_ModeColorOption->SetSelection( 1 );
+ m_ModeColorOption->SetToolTip( _("Choose if you want to draw the sheet like it appears on screen,\nor in black and white mode, better to print it when using black and white printers") );
+
+ sbSizerPlotFormat->Add( m_ModeColorOption, 0, wxALL|wxEXPAND, 5 );
+
+ m_PlotFrameRefOpt = new wxCheckBox( this, wxID_ANY, _("Plot border and title block"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PlotFrameRefOpt->SetValue(true);
+ m_PlotFrameRefOpt->SetToolTip( _("Print (or not) the Frame references.") );
+
+ sbSizerPlotFormat->Add( m_PlotFrameRefOpt, 0, wxALL, 5 );
+
+
+ m_optionsSizer->Add( sbSizerPlotFormat, 0, wxEXPAND|wxLEFT, 5 );
+
+ m_ButtonsSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonPlotCurrent = new wxButton( this, wxID_PRINT_CURRENT, _("Plot Current Page"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonPlotCurrent->SetDefault();
+ m_ButtonsSizer->Add( m_buttonPlotCurrent, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonPlotAll = new wxButton( this, wxID_PRINT_ALL, _("Plot All Pages"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonPlotAll->SetDefault();
+ m_ButtonsSizer->Add( m_buttonPlotAll, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonQuit = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ButtonsSizer->Add( m_buttonQuit, 0, wxALL|wxEXPAND, 5 );
+
+
+ m_optionsSizer->Add( m_ButtonsSizer, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bMainSizer->Add( m_optionsSizer, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText2 = new wxStaticText( this, wxID_ANY, _("Messages:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText2->Wrap( -1 );
+ bSizer4->Add( m_staticText2, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_MessagesBox = new WX_HTML_REPORT_PANEL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_MessagesBox->SetMinSize( wxSize( 300,150 ) );
+
+ bSizer4->Add( m_MessagesBox, 1, wxEXPAND | wxALL, 5 );
+
+
+ bMainSizer->Add( bSizer4, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnCloseWindow ) );
+ m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnOutputDirectoryBrowseClicked ), NULL, this );
+ m_HPGLPaperSizeOption->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnHPGLPageSelected ), NULL, this );
+ m_plotFormatOpt->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnPlotFormatSelection ), NULL, this );
+ m_buttonPlotCurrent->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnButtonPlotCurrentClick ), NULL, this );
+ m_buttonPlotAll->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnButtonPlotAllClick ), NULL, this );
+ m_buttonQuit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnButtonCancelClick ), NULL, this );
+}
+
+DIALOG_PLOT_SCHEMATIC_BASE::~DIALOG_PLOT_SCHEMATIC_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnCloseWindow ) );
+ m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnOutputDirectoryBrowseClicked ), NULL, this );
+ m_HPGLPaperSizeOption->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnHPGLPageSelected ), NULL, this );
+ m_plotFormatOpt->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnPlotFormatSelection ), NULL, this );
+ m_buttonPlotCurrent->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnButtonPlotCurrentClick ), NULL, this );
+ m_buttonPlotAll->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnButtonPlotAllClick ), NULL, this );
+ m_buttonQuit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnButtonCancelClick ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_plot_schematic_base.fbp b/eeschema/dialogs/dialog_plot_schematic_base.fbp
new file mode 100644
index 0000000..0018cb2
--- /dev/null
+++ b/eeschema/dialogs/dialog_plot_schematic_base.fbp
@@ -0,0 +1,1852 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_plot_schematic_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">Dialog_plot_schematic_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_PLOT_SCHEMATIC_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Plot Schematic</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseWindow</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer6</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Output directory:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextOutputDirectory</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer5</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_outputDirectoryName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Target directory for plot files. Can be absolute or relative to the schematic main file location.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Browse...</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_browseButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnOutputDirectoryBrowseClicked</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_optionsSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Paper Options</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_paperOptionsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Schematic size&quot; &quot;Force size A4&quot; &quot;Force size A&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Page Size:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PaperSizeOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">HPGL Options</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_paperHPGLSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Page Size:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Schematic size&quot; &quot;Page size A4&quot; &quot;Page size A3&quot; &quot;Page size A2&quot; &quot;Page size A1&quot; &quot;Page size A0&quot; &quot;Page size A&quot; &quot;Page size B&quot; &quot;Page size C&quot; &quot;Page size D&quot; &quot;Page size E&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_HPGLPaperSizeOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">OnHPGLPageSelected</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Bottom left corner&quot; &quot;Center of the page&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Origin</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotOriginOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pen width</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_penHPLGWidthTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_penHPGLWidthCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Postscript&quot; &quot;PDF&quot; &quot;SVG&quot; &quot;DXF&quot; &quot;HPGL&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Format</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotFormatOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox">OnPlotFormatSelection</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">General Options</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerPlotFormat</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default line thickness</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_defaultLineWidthTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DefaultLineSizeCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Selection of the default pen thickness used to draw items, when their thickness is set to 0.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Color&quot; &quot;Black and white&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Mode</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ModeColorOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Choose if you want to draw the sheet like it appears on screen,&#x0A;or in black and white mode, better to print it when using black and white printers</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Plot border and title block</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PlotFrameRefOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Print (or not) the Frame references.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_ButtonsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PRINT_CURRENT</property>
+ <property name="label">Plot Current Page</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPlotCurrent</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonPlotCurrentClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PRINT_ALL</property>
+ <property name="label">Plot All Pages</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPlotAll</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonPlotAllClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonQuit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer4</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Messages:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">300,150</property>
+ <property name="moveable">1</property>
+ <property name="name">m_MessagesBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass">WX_HTML_REPORT_PANEL; wx_html_report_panel.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_plot_schematic_base.h b/eeschema/dialogs/dialog_plot_schematic_base.h
new file mode 100644
index 0000000..b983cca
--- /dev/null
+++ b/eeschema/dialogs/dialog_plot_schematic_base.h
@@ -0,0 +1,91 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 6 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_PLOT_SCHEMATIC_BASE_H__
+#define __DIALOG_PLOT_SCHEMATIC_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class WX_HTML_REPORT_PANEL;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/radiobox.h>
+#include <wx/choice.h>
+#include <wx/statbox.h>
+#include <wx/checkbox.h>
+#include <wx/panel.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PLOT_SCHEMATIC_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PLOT_SCHEMATIC_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ wxID_PRINT_CURRENT = 1000,
+ wxID_PRINT_ALL
+ };
+
+ wxStaticText* m_staticTextOutputDirectory;
+ wxTextCtrl* m_outputDirectoryName;
+ wxButton* m_browseButton;
+ wxBoxSizer* m_optionsSizer;
+ wxStaticBoxSizer* m_paperOptionsSizer;
+ wxRadioBox* m_PaperSizeOption;
+ wxStaticBoxSizer* m_paperHPGLSizer;
+ wxStaticText* m_staticText4;
+ wxChoice* m_HPGLPaperSizeOption;
+ wxRadioBox* m_plotOriginOpt;
+ wxStaticText* m_penHPLGWidthTitle;
+ wxTextCtrl* m_penHPGLWidthCtrl;
+ wxRadioBox* m_plotFormatOpt;
+ wxStaticText* m_defaultLineWidthTitle;
+ wxTextCtrl* m_DefaultLineSizeCtrl;
+ wxRadioBox* m_ModeColorOption;
+ wxCheckBox* m_PlotFrameRefOpt;
+ wxBoxSizer* m_ButtonsSizer;
+ wxButton* m_buttonPlotCurrent;
+ wxButton* m_buttonPlotAll;
+ wxButton* m_buttonQuit;
+ wxStaticText* m_staticText2;
+ WX_HTML_REPORT_PANEL* m_MessagesBox;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnHPGLPageSelected( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPlotFormatSelection( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonPlotCurrentClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonPlotAllClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonCancelClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PLOT_SCHEMATIC_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Plot Schematic"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_PLOT_SCHEMATIC_BASE();
+
+};
+
+#endif //__DIALOG_PLOT_SCHEMATIC_BASE_H__
diff --git a/eeschema/dialogs/dialog_print_using_printer.cpp b/eeschema/dialogs/dialog_print_using_printer.cpp
new file mode 100644
index 0000000..09257bd
--- /dev/null
+++ b/eeschema/dialogs/dialog_print_using_printer.cpp
@@ -0,0 +1,487 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <class_sch_screen.h>
+#include <schframe.h>
+#include <base_units.h>
+
+#include <general.h>
+#include <eeschema_config.h>
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+
+#include <invoke_sch_dialog.h>
+#include <dialog_print_using_printer_base.h>
+
+
+
+/**
+ * Class DIALOG_PRINT_USING_PRINTER
+ * offers to print a schematic dialog.
+ *
+ * Derived from DIALOG_PRINT_USING_PRINTER_base created by wxFormBuilder
+ */
+class DIALOG_PRINT_USING_PRINTER : public DIALOG_PRINT_USING_PRINTER_BASE
+{
+public:
+ DIALOG_PRINT_USING_PRINTER( SCH_EDIT_FRAME* aParent );
+
+ SCH_EDIT_FRAME* GetParent() const
+ {
+ return ( SCH_EDIT_FRAME* ) wxWindow::GetParent();
+ }
+
+private:
+ void OnCloseWindow( wxCloseEvent& event );
+ void OnPageSetup( wxCommandEvent& event );
+ void OnPrintPreview( wxCommandEvent& event );
+ void OnPrintButtonClick( wxCommandEvent& event );
+ void OnButtonCancelClick( wxCommandEvent& event ) { Close(); }
+
+ void initDialog();
+ void GetPrintOptions();
+};
+
+
+
+/**
+ * Custom print out for printing schematics.
+ */
+class SCH_PRINTOUT : public wxPrintout
+{
+private:
+ SCH_EDIT_FRAME* m_parent;
+
+public:
+ SCH_PRINTOUT( SCH_EDIT_FRAME* aParent, const wxString& aTitle ) :
+ wxPrintout( aTitle )
+ {
+ wxASSERT( aParent != NULL );
+ m_parent = aParent;
+ }
+ bool OnPrintPage( int page );
+ bool HasPage( int page );
+ bool OnBeginDocument( int startPage, int endPage );
+ void GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo );
+ void DrawPage( SCH_SCREEN* aScreen );
+};
+
+/**
+ * Custom schematic print preview frame.
+ * This derived preview frame remembers its size and position during a session
+ */
+class SCH_PREVIEW_FRAME : public wxPreviewFrame
+{
+public:
+ SCH_PREVIEW_FRAME( wxPrintPreview* aPreview, wxWindow* aParent,
+ const wxString& aTitle, const wxPoint& aPos = wxDefaultPosition,
+ const wxSize& aSize = wxDefaultSize ) :
+ wxPreviewFrame( aPreview, aParent, aTitle, aPos, aSize )
+ {
+ }
+
+ bool Show( bool show ) // overload
+ {
+ bool ret;
+
+ // Show or hide the window. If hiding, save current position and size.
+ // If showing, use previous position and size.
+ if( show )
+ {
+ ret = wxPreviewFrame::Show( show );
+
+ if( s_size.x != 0 && s_size.y != 0 )
+ SetSize( s_pos.x, s_pos.y, s_size.x, s_size.y, 0 );
+ }
+ else
+ {
+ // Save the dialog's position & size before hiding
+ s_size = GetSize();
+ s_pos = GetPosition();
+
+ ret = wxPreviewFrame::Show( show );
+ }
+
+ return ret;
+ }
+
+private:
+ static wxPoint s_pos;
+ static wxSize s_size;
+};
+
+wxPoint SCH_PREVIEW_FRAME::s_pos;
+wxSize SCH_PREVIEW_FRAME::s_size;
+
+
+DIALOG_PRINT_USING_PRINTER::DIALOG_PRINT_USING_PRINTER( SCH_EDIT_FRAME* aParent ) :
+ DIALOG_PRINT_USING_PRINTER_BASE( aParent )
+{
+ wxASSERT( aParent != NULL );
+
+ m_checkReference->SetValue( aParent->GetPrintSheetReference() );
+ m_checkMonochrome->SetValue( aParent->GetPrintMonochrome() );
+ initDialog();
+
+#ifdef __WXMAC__
+ // Problems with modal on wx-2.9 - Anyway preview is standard for OSX
+ m_buttonPreview->Hide();
+#endif
+
+ GetSizer()->Fit( this );
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::initDialog()
+{
+ SCH_EDIT_FRAME* parent = GetParent();
+
+ // Initialize page specific print setup dialog settings.
+ const PAGE_INFO& pageInfo = parent->GetScreen()->GetPageSettings();
+ wxPageSetupDialogData& pageSetupDialogData = parent->GetPageSetupData();
+
+ pageSetupDialogData.SetPaperId( pageInfo.GetPaperId() );
+
+ if( pageInfo.IsCustom() )
+ {
+ if( pageInfo.IsPortrait() )
+ pageSetupDialogData.SetPaperSize( wxSize( Mils2mm( pageInfo.GetWidthMils() ),
+ Mils2mm( pageInfo.GetHeightMils() ) ) );
+ else
+ pageSetupDialogData.SetPaperSize( wxSize( Mils2mm( pageInfo.GetHeightMils() ),
+ Mils2mm( pageInfo.GetWidthMils() ) ) );
+ }
+
+ pageSetupDialogData.GetPrintData().SetOrientation( pageInfo.GetWxOrientation() );
+
+ if ( GetSizer() )
+ GetSizer()->SetSizeHints( this );
+
+ // Rely on the policy in class DIALOG_SHIM, which centers the dialog
+ // initially during a runtime session but gives user the ability to move it in
+ // that session.
+ // This dialog may get moved and resized in Show(), but in case this is
+ // the first time, center it for starters.
+ Center();
+
+ m_buttonPrint->SetDefault(); // on linux, this is inadequate to determine
+ // what ENTER does. Must also SetFocus().
+ m_buttonPrint->SetFocus();
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::GetPrintOptions()
+{
+ SCH_EDIT_FRAME* parent = GetParent();
+
+ parent->SetPrintMonochrome( m_checkMonochrome->IsChecked() );
+ parent->SetPrintSheetReference( m_checkReference->IsChecked() );
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::OnCloseWindow( wxCloseEvent& event )
+{
+ SCH_EDIT_FRAME* parent = GetParent();
+
+ if( !IsIconized() )
+ {
+ parent->SetPrintDialogPosition( GetPosition() );
+ parent->SetPrintDialogSize( GetSize() );
+ }
+
+ GetPrintOptions();
+
+ EndDialog( wxID_CANCEL );
+}
+
+
+/* Open a dialog box for printer setup (printer options, page size ...)
+ */
+void DIALOG_PRINT_USING_PRINTER::OnPageSetup( wxCommandEvent& event )
+{
+ SCH_EDIT_FRAME* parent = GetParent();
+
+ wxPageSetupDialog pageSetupDialog( this, &parent->GetPageSetupData() );
+
+ pageSetupDialog.ShowModal();
+
+ parent->GetPageSetupData() = pageSetupDialog.GetPageSetupDialogData();
+}
+
+
+/* Open and display a previewer frame for printing
+ */
+void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event )
+{
+ SCH_EDIT_FRAME* parent = GetParent();
+
+ GetPrintOptions();
+
+ // Pass two printout objects: for preview, and possible printing.
+ wxString title = _( "Preview" );
+ wxPrintPreview* preview = new wxPrintPreview( new SCH_PRINTOUT( parent, title ),
+ new SCH_PRINTOUT( parent, title ),
+ &parent->GetPageSetupData().GetPrintData() );
+
+ if( preview == NULL )
+ {
+ DisplayError( this, wxT( "Print preview error!" ) );
+ return;
+ }
+
+ preview->SetZoom( 100 );
+
+ SCH_PREVIEW_FRAME* frame = new SCH_PREVIEW_FRAME( preview, this, title );
+ frame->SetMinSize( wxSize( 550, 350 ) );
+
+ // on first invocation in this runtime session, set to 2/3 size of my parent,
+ // but will be changed in Show() if not first time as will position.
+ frame->SetSize( (parent->GetSize() * 2) / 3 );
+ frame->Center();
+
+ // On wxGTK, set the flag wxTOPLEVEL_EX_DIALOG is mandatory, if we want
+ // close the frame using the X box in caption, when the preview frame is run
+ // from a dialog
+ frame->SetExtraStyle( frame->GetExtraStyle() | wxTOPLEVEL_EX_DIALOG );
+
+ // We use here wxPreviewFrame_WindowModal option to make the wxPrintPreview frame
+ // modal for its caller only.
+ // An other reason is the fact when closing the frame without this option,
+ // all top level frames are reenabled.
+ // With this option, only the parent is reenabled.
+ // Reenabling all top level frames should be made by the parent dialog.
+ frame->InitializeWithModality( wxPreviewFrame_WindowModal );
+
+ frame->Raise(); // Needed on Ubuntu/Unity to display the frame
+ frame->Show( true );
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event )
+{
+ SCH_EDIT_FRAME* parent = GetParent();
+
+ GetPrintOptions();
+
+ wxPrintDialogData printDialogData( parent->GetPageSetupData().GetPrintData() );
+ printDialogData.SetMaxPage( g_RootSheet->CountSheets() );
+
+ if( g_RootSheet->CountSheets() > 1 )
+ printDialogData.EnablePageNumbers( true );
+
+ wxPrinter printer( &printDialogData );
+ SCH_PRINTOUT printout( parent, _( "Print Schematic" ) );
+
+ if( !printer.Print( this, &printout, true ) )
+ {
+ if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
+ wxMessageBox( _( "An error occurred attempting to print the schematic." ),
+ _( "Printing" ), wxOK );
+ }
+ else
+ {
+ parent->GetPageSetupData() = printer.GetPrintDialogData().GetPrintData();
+ }
+}
+
+
+bool SCH_PRINTOUT::OnPrintPage( int page )
+{
+ wxString msg;
+ msg.Printf( _( "Print page %d" ), page );
+ m_parent->ClearMsgPanel();
+ m_parent->AppendMsgPanel( msg, wxEmptyString, CYAN );
+
+ SCH_SCREEN* screen = m_parent->GetScreen();
+ SCH_SHEET_PATH oldsheetpath = m_parent->GetCurrentSheet();
+ SCH_SHEET_PATH list;
+ SCH_SHEET_LIST SheetList( NULL );
+ SCH_SHEET_PATH* sheetpath = SheetList.GetSheet( page - 1 );
+
+ if( list.BuildSheetPathInfoFromSheetPathValue( sheetpath->Path() ) )
+ {
+ m_parent->SetCurrentSheet( list );
+ m_parent->GetCurrentSheet().UpdateAllScreenReferences();
+ m_parent->SetSheetNumberAndCount();
+ screen = m_parent->GetCurrentSheet().LastScreen();
+ }
+ else
+ {
+ screen = NULL;
+ }
+
+ if( screen == NULL )
+ return false;
+
+ DrawPage( screen );
+ m_parent->SetCurrentSheet( oldsheetpath );
+ m_parent->GetCurrentSheet().UpdateAllScreenReferences();
+ m_parent->SetSheetNumberAndCount();
+
+ return true;
+}
+
+
+void SCH_PRINTOUT::GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo )
+{
+ *minPage = *selPageFrom = 1;
+ *maxPage = *selPageTo = g_RootSheet->CountSheets();
+}
+
+
+bool SCH_PRINTOUT::HasPage( int pageNum )
+{
+ int pageCount;
+
+ pageCount = g_RootSheet->CountSheets();
+ if( pageCount >= pageNum )
+ return true;
+
+ return false;
+}
+
+
+bool SCH_PRINTOUT::OnBeginDocument( int startPage, int endPage )
+{
+ if( !wxPrintout::OnBeginDocument( startPage, endPage ) )
+ return false;
+
+#ifdef __WXDEBUG__
+ wxLogDebug( wxT( "Printer name: " ) +
+ m_parent->GetPageSetupData().GetPrintData().GetPrinterName() );
+ wxLogDebug( wxT( "Paper ID: %d" ),
+ m_parent->GetPageSetupData().GetPrintData().GetPaperId() );
+ wxLogDebug( wxT( "Color: %d" ),
+ (int)m_parent->GetPageSetupData().GetPrintData().GetColour() );
+ wxLogDebug( wxT( "Monochrome: %d" ), m_parent->GetPrintMonochrome() );
+ wxLogDebug( wxT( "Orientation: %d:" ),
+ m_parent->GetPageSetupData().GetPrintData().GetOrientation() );
+ wxLogDebug( wxT( "Quality: %d"),
+ m_parent->GetPageSetupData().GetPrintData().GetQuality() );
+#endif
+
+ return true;
+}
+
+
+/*
+ * This is the real print function: print the active screen
+ */
+void SCH_PRINTOUT::DrawPage( SCH_SCREEN* aScreen )
+{
+ int oldZoom;
+ wxPoint tmp_startvisu;
+ wxSize pageSizeIU; // Page size in internal units
+ wxPoint old_org;
+ EDA_RECT oldClipBox;
+ wxRect fitRect;
+ wxDC* dc = GetDC();
+ EDA_DRAW_PANEL* panel = m_parent->GetCanvas();
+
+ wxBusyCursor dummy;
+
+ // Save current scale factor, offsets, and clip box.
+ tmp_startvisu = aScreen->m_StartVisu;
+ oldZoom = aScreen->GetZoom();
+ old_org = aScreen->m_DrawOrg;
+
+ oldClipBox = *panel->GetClipBox();
+
+ // Change clip box to print the whole page.
+ #define MAX_VALUE (INT_MAX/2) // MAX_VALUE is the max we can use in an integer
+ // and that allows calculations without overflow
+ panel->SetClipBox( EDA_RECT( wxPoint( 0, 0 ), wxSize( MAX_VALUE, MAX_VALUE ) ) );
+
+ // Change scale factor and offset to print the whole page.
+ bool printReference = m_parent->GetPrintSheetReference();
+
+ pageSizeIU = aScreen->GetPageSettings().GetSizeIU();
+ FitThisSizeToPaper( pageSizeIU );
+ fitRect = GetLogicalPaperRect();
+
+ wxLogDebug( wxT( "Fit rectangle: x = %d, y = %d, w = %d, h = %d" ),
+ fitRect.x, fitRect.y, fitRect.width, fitRect.height );
+
+ // When is the actual paper size does not match the schematic page
+ // size, the drawing is not perfectly centered on X or Y axis.
+ // Give a draw offset centers the schematic page on the paper draw area
+ // Because the sizes are fitted, only an Y or X offset is needed
+ // and both are 0 when sizes are identical.
+ // Y or Y offset is not null when the X/Y size ratio differs between
+ // the actual paper size and the schematic page
+ int xoffset = ( fitRect.width - pageSizeIU.x ) / 2;
+
+ // For an obscure reason, OffsetLogicalOrigin creates issues,
+ // under some circumstances, when yoffset is not always null
+ // and changes from a page to an other page
+ // This is only a workaround, not a fix
+ // see https://bugs.launchpad.net/kicad/+bug/1464773
+ // xoffset does not create issues.
+#if 0 // FIX ME
+ int yoffset = ( fitRect.height - pageSizeIU.y ) / 2;
+#else
+ // the Y centering will be not perfect, but this is less annoying
+ // than a blank page or a buggy centering
+ int yoffset = 0;
+#endif
+ OffsetLogicalOrigin( xoffset, yoffset );
+
+ GRResetPenAndBrush( dc );
+
+ if( m_parent->GetPrintMonochrome() )
+ GRForceBlackPen( true );
+
+ aScreen->m_IsPrinting = true;
+
+ EDA_COLOR_T bg_color = m_parent->GetDrawBgColor();
+
+ aScreen->Draw( panel, dc, (GR_DRAWMODE) 0 );
+
+ if( printReference )
+ m_parent->DrawWorkSheet( dc, aScreen, GetDefaultLineThickness(),
+ IU_PER_MILS, aScreen->GetFileName() );
+
+ m_parent->SetDrawBgColor( bg_color );
+ aScreen->m_IsPrinting = false;
+ panel->SetClipBox( oldClipBox );
+
+ GRForceBlackPen( false );
+
+ aScreen->m_StartVisu = tmp_startvisu;
+ aScreen->m_DrawOrg = old_org;
+ aScreen->SetZoom( oldZoom );
+}
+
+
+int InvokeDialogPrintUsingPrinter( SCH_EDIT_FRAME* aCaller )
+{
+ DIALOG_PRINT_USING_PRINTER dlg( aCaller );
+
+ return dlg.ShowModal();
+}
diff --git a/eeschema/dialogs/dialog_print_using_printer_base.cpp b/eeschema/dialogs/dialog_print_using_printer_base.cpp
new file mode 100644
index 0000000..6a163b1
--- /dev/null
+++ b/eeschema/dialogs/dialog_print_using_printer_base.cpp
@@ -0,0 +1,80 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_print_using_printer_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_PRINT_USING_PRINTER_BASE::DIALOG_PRINT_USING_PRINTER_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bleftSizer;
+ bleftSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText1 = new wxStaticText( this, wxID_ANY, _("Print options:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ m_staticText1->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bleftSizer->Add( m_staticText1, 0, wxTOP|wxRIGHT, 5 );
+
+ m_checkReference = new wxCheckBox( this, wxID_ANY, _("Print sheet &reference and title block"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkReference->SetValue(true);
+ m_checkReference->SetToolTip( _("Print (or not) the Frame references.") );
+
+ bleftSizer->Add( m_checkReference, 0, wxALL, 10 );
+
+ m_checkMonochrome = new wxCheckBox( this, wxID_ANY, _("Print in &black and white only"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkMonochrome->SetValue(true);
+ bleftSizer->Add( m_checkMonochrome, 0, wxBOTTOM|wxRIGHT|wxLEFT, 10 );
+
+
+ bMainSizer->Add( bleftSizer, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 12 );
+
+ wxBoxSizer* bbuttonsSizer;
+ bbuttonsSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonPageSetup = new wxButton( this, wxID_ANY, _("Page Setup"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttonPageSetup, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonPreview = new wxButton( this, wxID_ANY, _("Preview"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttonPreview, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonPrint = new wxButton( this, wxID_ANY, _("Print"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttonPrint, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonQuit = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttonQuit, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bbuttonsSizer, 0, wxALL, 12 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnCloseWindow ) );
+ m_buttonPageSetup->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPageSetup ), NULL, this );
+ m_buttonPreview->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPrintPreview ), NULL, this );
+ m_buttonPrint->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPrintButtonClick ), NULL, this );
+ m_buttonQuit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnButtonCancelClick ), NULL, this );
+}
+
+DIALOG_PRINT_USING_PRINTER_BASE::~DIALOG_PRINT_USING_PRINTER_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnCloseWindow ) );
+ m_buttonPageSetup->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPageSetup ), NULL, this );
+ m_buttonPreview->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPrintPreview ), NULL, this );
+ m_buttonPrint->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPrintButtonClick ), NULL, this );
+ m_buttonQuit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnButtonCancelClick ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_print_using_printer_base.fbp b/eeschema/dialogs/dialog_print_using_printer_base.fbp
new file mode 100644
index 0000000..cf785e1
--- /dev/null
+++ b/eeschema/dialogs/dialog_print_using_printer_base.fbp
@@ -0,0 +1,732 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_print_using_printer_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_print_schematic</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_PRINT_USING_PRINTER_BASE</property>
+ <property name="pos"></property>
+ <property name="size">388,185</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Print</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseWindow</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">12</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bleftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Print options:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">10</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Print sheet &amp;reference and title block</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkReference</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Print (or not) the Frame references.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">10</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Print in &amp;black and white only</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkMonochrome</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">12</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bbuttonsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Page Setup</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPageSetup</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnPageSetup</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Preview</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPreview</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnPrintPreview</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Print</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPrint</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnPrintButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonQuit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_print_using_printer_base.h b/eeschema/dialogs/dialog_print_using_printer_base.h
new file mode 100644
index 0000000..49994cf
--- /dev/null
+++ b/eeschema/dialogs/dialog_print_using_printer_base.h
@@ -0,0 +1,61 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_PRINT_USING_PRINTER_BASE_H__
+#define __DIALOG_PRINT_USING_PRINTER_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/checkbox.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PRINT_USING_PRINTER_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PRINT_USING_PRINTER_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText1;
+ wxCheckBox* m_checkReference;
+ wxCheckBox* m_checkMonochrome;
+ wxButton* m_buttonPageSetup;
+ wxButton* m_buttonPreview;
+ wxButton* m_buttonPrint;
+ wxButton* m_buttonQuit;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnPageSetup( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPrintPreview( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPrintButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonCancelClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PRINT_USING_PRINTER_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Print"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 388,185 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_PRINT_USING_PRINTER_BASE();
+
+};
+
+#endif //__DIALOG_PRINT_USING_PRINTER_BASE_H__
diff --git a/eeschema/dialogs/dialog_rescue_each.cpp b/eeschema/dialogs/dialog_rescue_each.cpp
new file mode 100644
index 0000000..73238e7
--- /dev/null
+++ b/eeschema/dialogs/dialog_rescue_each.cpp
@@ -0,0 +1,316 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Chris Pavlina <pavlina.chris@gmail.com>
+ * Copyright (C) 2015 Kicad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <schframe.h>
+#include <sch_component.h>
+#include <invoke_sch_dialog.h>
+#include <dialog_rescue_each_base.h>
+#include <kiface_i.h>
+#include <class_library.h>
+#include <class_libentry.h>
+#include <set>
+#include <vector>
+#include <boost/foreach.hpp>
+#include <project_rescue.h>
+#include <eeschema_config.h>
+
+class DIALOG_RESCUE_EACH: public DIALOG_RESCUE_EACH_BASE
+{
+public:
+ /**
+ * Constructor
+ * This dialog asks the user which rescuable, cached parts he wants to rescue.
+ * Any rejects will be pruned from aCandidates.
+ * @param aCaller - the SCH_EDIT_FRAME calling this
+ * @param aRescuer - the active RESCUER instance
+ * @param aAskShowAgain - if true, a "Never Show Again" button will be included
+ */
+ DIALOG_RESCUE_EACH( SCH_EDIT_FRAME* aParent, RESCUER& aRescuer, bool aAskShowAgain );
+
+ ~DIALOG_RESCUE_EACH();
+
+private:
+ SCH_EDIT_FRAME* m_Parent;
+ wxConfigBase* m_Config;
+ RESCUER* m_Rescuer;
+ bool m_AskShowAgain;
+
+ bool TransferDataToWindow();
+ bool TransferDataFromWindow();
+ void PopulateConflictList();
+ void PopulateInstanceList();
+ void OnConflictSelect( wxDataViewEvent& event );
+ void OnNeverShowClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+ void OnHandleCachePreviewRepaint( wxPaintEvent& aRepaintEvent );
+ void OnHandleLibraryPreviewRepaint( wxPaintEvent& aRepaintEvent );
+ void OnDialogResize( wxSizeEvent& aSizeEvent );
+ void renderPreview( LIB_PART* aComponent, int aUnit, wxPanel* panel );
+};
+
+
+DIALOG_RESCUE_EACH::DIALOG_RESCUE_EACH( SCH_EDIT_FRAME* aParent, RESCUER& aRescuer,
+ bool aAskShowAgain )
+ : DIALOG_RESCUE_EACH_BASE( aParent ),
+ m_Parent( aParent ),
+ m_Rescuer( &aRescuer ),
+ m_AskShowAgain( aAskShowAgain )
+{
+ m_Config = Kiface().KifaceSettings();
+ m_stdButtonsOK->SetDefault();
+
+ // Set the info message, customized to include the proper suffix.
+ wxString info_message =
+ _( "It looks like this project was made using older schematic component libraries.\n"
+ "Some parts may need to be relinked to a different symbol name, and some symbols\n"
+ "may need to be \"rescued\" (cloned and renamed) into a new library.\n"
+ "\n"
+ "The following changes are recommended to update the project." );
+ m_lblInfo->SetLabel( info_message );
+
+ m_componentViewOld->SetLayoutDirection( wxLayout_LeftToRight );
+ m_componentViewNew->SetLayoutDirection( wxLayout_LeftToRight );
+}
+
+
+DIALOG_RESCUE_EACH::~DIALOG_RESCUE_EACH()
+{
+}
+
+
+bool DIALOG_RESCUE_EACH::TransferDataToWindow()
+{
+ if( !wxDialog::TransferDataToWindow() )
+ return false;
+
+ m_ListOfConflicts->AppendToggleColumn( _( "Accept" ) );
+ m_ListOfConflicts->AppendTextColumn( _( "Symbol" ) );
+ m_ListOfConflicts->AppendTextColumn( _( "Action" ) );
+ m_ListOfInstances->AppendTextColumn( _( "Reference" ) );
+ m_ListOfInstances->AppendTextColumn( _( "Value" ) );
+ PopulateConflictList();
+ PopulateInstanceList();
+
+ if( !m_AskShowAgain )
+ m_btnNeverShowAgain->Hide();
+
+ GetSizer()->Layout();
+ GetSizer()->Fit( this );
+ GetSizer()->SetSizeHints( this );
+ Centre();
+
+ return true;
+}
+
+
+void DIALOG_RESCUE_EACH::PopulateConflictList()
+{
+ wxVector<wxVariant> data;
+ BOOST_FOREACH( RESCUE_CANDIDATE& each_candidate, m_Rescuer->m_all_candidates )
+ {
+ data.clear();
+ data.push_back( wxVariant( true ) );
+ data.push_back( each_candidate.GetRequestedName() );
+ data.push_back( each_candidate.GetActionDescription() );
+
+ m_ListOfConflicts->AppendItem( data );
+ }
+
+ if( !m_Rescuer->m_all_candidates.empty() )
+ {
+ // Select the first choice
+ m_ListOfConflicts->SelectRow( 0 );
+ }
+}
+
+
+void DIALOG_RESCUE_EACH::PopulateInstanceList()
+{
+ m_ListOfInstances->DeleteAllItems();
+
+ int row = m_ListOfConflicts->GetSelectedRow();
+
+ if( row == wxNOT_FOUND )
+ row = 0;
+
+ RESCUE_CANDIDATE& selected_part = m_Rescuer->m_all_candidates[row];
+
+ wxVector<wxVariant> data;
+ BOOST_FOREACH( SCH_COMPONENT* each_component, *m_Rescuer->GetComponents() )
+ {
+ if( each_component->GetPartName() != selected_part.GetRequestedName() )
+ continue;
+
+ SCH_FIELD* valueField = each_component->GetField( 1 );
+
+ data.clear();
+ data.push_back( each_component->GetRef( & m_Parent->GetCurrentSheet() ) );
+ data.push_back( valueField ? valueField->GetText() : wxT( "" ) );
+ m_ListOfInstances->AppendItem( data );
+
+ }
+}
+
+
+void DIALOG_RESCUE_EACH::OnHandleCachePreviewRepaint( wxPaintEvent& aRepaintEvent )
+{
+ int row = m_ListOfConflicts->GetSelectedRow();
+
+ if( row == wxNOT_FOUND )
+ row = 0;
+
+ RESCUE_CANDIDATE& selected_part = m_Rescuer->m_all_candidates[row];
+
+ if( selected_part.GetCacheCandidate() )
+ renderPreview( selected_part.GetCacheCandidate(), 0, m_componentViewOld );
+}
+
+
+void DIALOG_RESCUE_EACH::OnHandleLibraryPreviewRepaint( wxPaintEvent& aRepaintEvent )
+{
+ int row = m_ListOfConflicts->GetSelectedRow();
+
+ if( row == wxNOT_FOUND )
+ row = 0;
+
+ RESCUE_CANDIDATE& selected_part = m_Rescuer->m_all_candidates[row];
+
+ if( selected_part.GetLibCandidate() )
+ renderPreview( selected_part.GetLibCandidate(), 0, m_componentViewNew );
+}
+
+
+void DIALOG_RESCUE_EACH::OnDialogResize( wxSizeEvent& aSizeEvent )
+{
+ // Placeholer - I was previously doing some extra reflow here.
+ DIALOG_RESCUE_EACH_BASE::OnDialogResize( aSizeEvent );
+}
+
+
+// Render the preview in our m_componentView. If this gets more complicated, we should
+// probably have a derived class from wxPanel; but this keeps things local.
+// Call it only from a Paint Event, because we are using a wxPaintDC to draw the component
+void DIALOG_RESCUE_EACH::renderPreview( LIB_PART* aComponent, int aUnit, wxPanel* aPanel )
+{
+ wxPaintDC dc( aPanel );
+ EDA_COLOR_T bgcolor = m_Parent->GetDrawBgColor();
+
+ dc.SetBackground( bgcolor == BLACK ? *wxBLACK_BRUSH : *wxWHITE_BRUSH );
+ dc.Clear();
+
+ if( aComponent == NULL )
+ return;
+
+ if( aUnit <= 0 )
+ aUnit = 1;
+
+ const wxSize dc_size = dc.GetSize();
+ dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
+
+ // Find joint bounding box for everything we are about to draw.
+ EDA_RECT bBox = aComponent->GetBoundingBox( aUnit, /* deMorganConvert */ 1 );
+ const double xscale = (double) dc_size.x / bBox.GetWidth();
+ const double yscale = (double) dc_size.y / bBox.GetHeight();
+ const double scale = std::min( xscale, yscale ) * 0.85;
+
+ dc.SetUserScale( scale, scale );
+
+ wxPoint offset = - bBox.Centre();
+
+ // Avoid rendering when either dimension is zero
+ int width, height;
+
+ dc.GetSize( &width, &height );
+ if( !width || !height )
+ return;
+
+ aComponent->Draw( NULL, &dc, offset, aUnit, /* deMorganConvert */ 1, GR_COPY,
+ UNSPECIFIED_COLOR, DefaultTransform, true, true, false );
+}
+
+
+void DIALOG_RESCUE_EACH::OnConflictSelect( wxDataViewEvent& aEvent )
+{
+ // wxformbuilder connects this event to the _dialog_, not the data view.
+ // Make sure the correct item triggered it, otherwise we trigger recursively
+ // and get a stack overflow.
+ if( aEvent.GetEventObject() != m_ListOfConflicts )
+ return;
+
+ PopulateInstanceList();
+
+ m_componentViewOld->Refresh();
+ m_componentViewNew->Refresh();
+}
+
+
+bool DIALOG_RESCUE_EACH::TransferDataFromWindow()
+{
+ if( !wxDialog::TransferDataFromWindow() )
+ return false;
+
+ for( size_t index = 0; index < m_Rescuer->GetCandidateCount(); ++index )
+ {
+ wxVariant val;
+ m_ListOfConflicts->GetValue( val, index, 0 );
+ bool rescue_part = val.GetBool();
+
+ if( rescue_part )
+ m_Rescuer->m_chosen_candidates.push_back( &m_Rescuer->m_all_candidates[index] );
+ }
+ return true;
+}
+
+
+void DIALOG_RESCUE_EACH::OnNeverShowClick( wxCommandEvent& aEvent )
+{
+ wxMessageDialog dlg( m_Parent,
+ _( "Stop showing this tool?\n"
+ "No changes will be made.\n\n"
+ "This setting can be changed from the \"Component Libraries\" dialog,\n"
+ "and the tool can be activated manually from the \"Tools\" menu." ),
+ _( "Rescue Components" ), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
+ int resp = dlg.ShowModal ();
+
+ if( resp == wxID_YES )
+ {
+ m_Config->Write( RESCUE_NEVER_SHOW_KEY, true );
+ m_Rescuer->m_chosen_candidates.clear();
+ Close();
+ }
+}
+
+
+void DIALOG_RESCUE_EACH::OnCancelClick( wxCommandEvent& aEvent )
+{
+ m_Rescuer->m_chosen_candidates.clear();
+ DIALOG_RESCUE_EACH_BASE::OnCancelClick( aEvent );
+}
+
+
+int InvokeDialogRescueEach( SCH_EDIT_FRAME* aCaller, RESCUER& aRescuer, bool aAskShowAgain )
+{
+ DIALOG_RESCUE_EACH dlg( aCaller, aRescuer, aAskShowAgain );
+ return dlg.ShowModal();
+}
diff --git a/eeschema/dialogs/dialog_rescue_each_base.cpp b/eeschema/dialogs/dialog_rescue_each_base.cpp
new file mode 100644
index 0000000..99cdbcc
--- /dev/null
+++ b/eeschema/dialogs/dialog_rescue_each_base.cpp
@@ -0,0 +1,127 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 13 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_rescue_each_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_RESCUE_EACH_BASE::DIALOG_RESCUE_EACH_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( 450,100 ), wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ m_lblInfo = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_lblInfo->Wrap( 500 );
+ bSizerMain->Add( m_lblInfo, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticText5 = new wxStaticText( this, wxID_ANY, _("Symbols to update:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText5->Wrap( -1 );
+ m_staticText5->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizerMain->Add( m_staticText5, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_ListOfConflicts = new wxDataViewListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerMain->Add( m_ListOfConflicts, 2, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticText4 = new wxStaticText( this, wxID_ANY, _("Instances of this symbol:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText4->Wrap( -1 );
+ m_staticText4->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizerMain->Add( m_staticText4, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_ListOfInstances = new wxDataViewListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerMain->Add( m_ListOfInstances, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerView;
+ bSizerView = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizer6;
+ bSizer6 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText2 = new wxStaticText( this, wxID_ANY, _("Cached Part:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText2->Wrap( -1 );
+ m_staticText2->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizer6->Add( m_staticText2, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_componentViewOld = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER );
+ m_componentViewOld->SetMinSize( wxSize( 150,150 ) );
+
+ bSizer6->Add( m_componentViewOld, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerView->Add( bSizer6, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer7;
+ bSizer7 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText3 = new wxStaticText( this, wxID_ANY, _("Library Part:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ m_staticText3->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizer7->Add( m_staticText3, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_componentViewNew = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER );
+ m_componentViewNew->SetMinSize( wxSize( 150,150 ) );
+
+ bSizer7->Add( m_componentViewNew, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerView->Add( bSizer7, 1, wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bSizerView, 2, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer5;
+ bSizer5 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_btnNeverShowAgain = new wxButton( this, wxID_ANY, _("Never Show Again"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer5->Add( m_btnNeverShowAgain, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizer5->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_stdButtons = new wxStdDialogButtonSizer();
+ m_stdButtonsOK = new wxButton( this, wxID_OK );
+ m_stdButtons->AddButton( m_stdButtonsOK );
+ m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_stdButtons->AddButton( m_stdButtonsCancel );
+ m_stdButtons->Realize();
+
+ bSizer5->Add( m_stdButtons, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bSizer5, 0, wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_RESCUE_EACH_BASE::OnDialogResize ) );
+ this->Connect( wxID_ANY, wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_RESCUE_EACH_BASE::OnConflictSelect ) );
+ m_componentViewOld->Connect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_RESCUE_EACH_BASE::OnHandleCachePreviewRepaint ), NULL, this );
+ m_componentViewNew->Connect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_RESCUE_EACH_BASE::OnHandleLibraryPreviewRepaint ), NULL, this );
+ m_btnNeverShowAgain->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_RESCUE_EACH_BASE::OnNeverShowClick ), NULL, this );
+ m_stdButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_RESCUE_EACH_BASE::OnCancelClick ), NULL, this );
+}
+
+DIALOG_RESCUE_EACH_BASE::~DIALOG_RESCUE_EACH_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_RESCUE_EACH_BASE::OnDialogResize ) );
+ this->Disconnect( wxID_ANY, wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_RESCUE_EACH_BASE::OnConflictSelect ) );
+ m_componentViewOld->Disconnect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_RESCUE_EACH_BASE::OnHandleCachePreviewRepaint ), NULL, this );
+ m_componentViewNew->Disconnect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_RESCUE_EACH_BASE::OnHandleLibraryPreviewRepaint ), NULL, this );
+ m_btnNeverShowAgain->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_RESCUE_EACH_BASE::OnNeverShowClick ), NULL, this );
+ m_stdButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_RESCUE_EACH_BASE::OnCancelClick ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_rescue_each_base.fbp b/eeschema/dialogs/dialog_rescue_each_base.fbp
new file mode 100644
index 0000000..5199216
--- /dev/null
+++ b/eeschema/dialogs/dialog_rescue_each_base.fbp
@@ -0,0 +1,978 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_rescue_each_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_rescue_each_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">450,100</property>
+ <property name="name">DIALOG_RESCUE_EACH_BASE</property>
+ <property name="pos"></property>
+ <property name="size">529,593</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Project Rescue Helper</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize">OnDialogResize</event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_lblInfo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">500</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Symbols to update:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">2</property>
+ <object class="wxDataViewListCtrl" expanded="1">
+ <property name="bg"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">m_ListOfConflicts</property>
+ <property name="permission">protected</property>
+ <property name="pos"></property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnDataViewListCtrlColumnHeaderClick"></event>
+ <event name="OnDataViewListCtrlColumnHeaderRightClick"></event>
+ <event name="OnDataViewListCtrlColumnReordered"></event>
+ <event name="OnDataViewListCtrlColumnSorted"></event>
+ <event name="OnDataViewListCtrlItemActivated"></event>
+ <event name="OnDataViewListCtrlItemBeginDrag"></event>
+ <event name="OnDataViewListCtrlItemCollapsed"></event>
+ <event name="OnDataViewListCtrlItemCollapsing"></event>
+ <event name="OnDataViewListCtrlItemContextMenu"></event>
+ <event name="OnDataViewListCtrlItemDrop"></event>
+ <event name="OnDataViewListCtrlItemDropPossible"></event>
+ <event name="OnDataViewListCtrlItemEditingDone"></event>
+ <event name="OnDataViewListCtrlItemEditingStarted"></event>
+ <event name="OnDataViewListCtrlItemExpanded"></event>
+ <event name="OnDataViewListCtrlItemExpanding"></event>
+ <event name="OnDataViewListCtrlItemStartEditing"></event>
+ <event name="OnDataViewListCtrlItemValueChanged"></event>
+ <event name="OnDataViewListCtrlSelectionChanged">OnConflictSelect</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Instances of this symbol:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxDataViewListCtrl" expanded="1">
+ <property name="bg"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">m_ListOfInstances</property>
+ <property name="permission">protected</property>
+ <property name="pos"></property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnDataViewListCtrlColumnHeaderClick"></event>
+ <event name="OnDataViewListCtrlColumnHeaderRightClick"></event>
+ <event name="OnDataViewListCtrlColumnReordered"></event>
+ <event name="OnDataViewListCtrlColumnSorted"></event>
+ <event name="OnDataViewListCtrlItemActivated"></event>
+ <event name="OnDataViewListCtrlItemBeginDrag"></event>
+ <event name="OnDataViewListCtrlItemCollapsed"></event>
+ <event name="OnDataViewListCtrlItemCollapsing"></event>
+ <event name="OnDataViewListCtrlItemContextMenu"></event>
+ <event name="OnDataViewListCtrlItemDrop"></event>
+ <event name="OnDataViewListCtrlItemDropPossible"></event>
+ <event name="OnDataViewListCtrlItemEditingDone"></event>
+ <event name="OnDataViewListCtrlItemEditingStarted"></event>
+ <event name="OnDataViewListCtrlItemExpanded"></event>
+ <event name="OnDataViewListCtrlItemExpanding"></event>
+ <event name="OnDataViewListCtrlItemStartEditing"></event>
+ <event name="OnDataViewListCtrlItemValueChanged"></event>
+ <event name="OnDataViewListCtrlSelectionChanged"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">2</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerView</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer6</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Cached Part:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">150,150</property>
+ <property name="moveable">1</property>
+ <property name="name">m_componentViewOld</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint">OnHandleCachePreviewRepaint</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer7</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Library Part:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">150,150</property>
+ <property name="moveable">1</property>
+ <property name="name">m_componentViewNew</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint">OnHandleLibraryPreviewRepaint</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer5</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Never Show Again</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_btnNeverShowAgain</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnNeverShowClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="0">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_stdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_rescue_each_base.h b/eeschema/dialogs/dialog_rescue_each_base.h
new file mode 100644
index 0000000..40d1b11
--- /dev/null
+++ b/eeschema/dialogs/dialog_rescue_each_base.h
@@ -0,0 +1,70 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 13 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_RESCUE_EACH_BASE_H__
+#define __DIALOG_RESCUE_EACH_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/dataview.h>
+#include <wx/panel.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_RESCUE_EACH_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_RESCUE_EACH_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_lblInfo;
+ wxStaticText* m_staticText5;
+ wxDataViewListCtrl* m_ListOfConflicts;
+ wxStaticText* m_staticText4;
+ wxDataViewListCtrl* m_ListOfInstances;
+ wxStaticText* m_staticText2;
+ wxPanel* m_componentViewOld;
+ wxStaticText* m_staticText3;
+ wxPanel* m_componentViewNew;
+ wxButton* m_btnNeverShowAgain;
+ wxStdDialogButtonSizer* m_stdButtons;
+ wxButton* m_stdButtonsOK;
+ wxButton* m_stdButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnDialogResize( wxSizeEvent& event ) { event.Skip(); }
+ virtual void OnConflictSelect( wxDataViewEvent& event ) { event.Skip(); }
+ virtual void OnHandleCachePreviewRepaint( wxPaintEvent& event ) { event.Skip(); }
+ virtual void OnHandleLibraryPreviewRepaint( wxPaintEvent& event ) { event.Skip(); }
+ virtual void OnNeverShowClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_RESCUE_EACH_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Project Rescue Helper"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 529,593 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_RESCUE_EACH_BASE();
+
+};
+
+#endif //__DIALOG_RESCUE_EACH_BASE_H__
diff --git a/eeschema/dialogs/dialog_sch_edit_sheet_pin.cpp b/eeschema/dialogs/dialog_sch_edit_sheet_pin.cpp
new file mode 100644
index 0000000..9b44c99
--- /dev/null
+++ b/eeschema/dialogs/dialog_sch_edit_sheet_pin.cpp
@@ -0,0 +1,60 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <dialog_sch_edit_sheet_pin.h>
+
+
+static wxString sheetPinTypes[] =
+{
+ _( "Input" ),
+ _( "Output" ),
+ _( "Bidirectional" ),
+ _( "Tri-state" ),
+ _( "Passive" )
+};
+
+
+#define SHEET_PIN_TYPE_CNT ( sizeof( sheetPinTypes ) / sizeof( wxString ) )
+
+
+DIALOG_SCH_EDIT_SHEET_PIN::DIALOG_SCH_EDIT_SHEET_PIN( wxWindow* parent ) :
+ DIALOG_SCH_EDIT_SHEET_PIN_BASE( parent )
+{
+ for( size_t i = 0; i < SHEET_PIN_TYPE_CNT; i++ )
+ m_choiceConnectionType->Append( sheetPinTypes[ i ] );
+
+ m_choiceConnectionType->SetSelection( 0 );
+ m_textName->SetFocus();
+ m_sdbSizerOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+
+ // On some windows manager (Unity, XFCE), this dialog is
+ // not always raised, depending on this dialog is run.
+ // Force it to be raised
+ Raise();
+}
diff --git a/eeschema/dialogs/dialog_sch_edit_sheet_pin.h b/eeschema/dialogs/dialog_sch_edit_sheet_pin.h
new file mode 100644
index 0000000..fc35864
--- /dev/null
+++ b/eeschema/dialogs/dialog_sch_edit_sheet_pin.h
@@ -0,0 +1,59 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __dialog_sch_edit_sheet_pin__
+#define __dialog_sch_edit_sheet_pin__
+
+
+/**
+ * @file
+ * Subclass of DIALOG_SCH_EDIT_SHEET_PIN_BASE, which is generated by wxFormBuilder.
+ */
+
+
+#include <dialog_sch_edit_sheet_pin_base.h>
+
+
+class DIALOG_SCH_EDIT_SHEET_PIN : public DIALOG_SCH_EDIT_SHEET_PIN_BASE
+{
+public:
+ DIALOG_SCH_EDIT_SHEET_PIN( wxWindow* parent );
+
+ void SetLabelName( const wxString& aName ) { m_textName->SetValue( aName ); }
+ wxString GetLabelName() const { return m_textName->GetValue(); }
+
+ void SetTextHeight( const wxString& aHeight ) { m_textHeight->SetValue( aHeight ); }
+ wxString GetTextHeight() const { return m_textHeight->GetValue(); }
+
+ void SetTextWidth( const wxString& aWidth ) { m_textWidth->SetValue( aWidth ); }
+ wxString GetTextWidth() const { return m_textWidth->GetValue(); }
+
+ void SetConnectionType( int aType ) { m_choiceConnectionType->SetSelection( aType ); }
+ int GetConnectionType() const { return m_choiceConnectionType->GetCurrentSelection(); }
+
+ void SetTextHeightUnits( const wxString& aUnit ) { m_staticHeightUnits->SetLabel( aUnit ); }
+ void SetTextWidthUnits( const wxString& aUnit ) { m_staticWidthUnits->SetLabel( aUnit ); }
+};
+
+#endif // __dialog_sch_edit_sheet_pin__
diff --git a/eeschema/dialogs/dialog_sch_edit_sheet_pin_base.cpp b/eeschema/dialogs/dialog_sch_edit_sheet_pin_base.cpp
new file mode 100644
index 0000000..8fe85fd
--- /dev/null
+++ b/eeschema/dialogs/dialog_sch_edit_sheet_pin_base.cpp
@@ -0,0 +1,102 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_sch_edit_sheet_pin_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_SCH_EDIT_SHEET_PIN_BASE::DIALOG_SCH_EDIT_SHEET_PIN_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( 350,-1 ), wxDefaultSize );
+
+ wxBoxSizer* m_mainSizer;
+ m_mainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* m_nameSizer;
+ m_nameSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 4, 3, 0, 0 );
+ fgSizer1->AddGrowableCol( 1 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText1 = new wxStaticText( this, wxID_ANY, _("Name:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ fgSizer1->Add( m_staticText1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 6 );
+
+ m_textName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textName->SetMaxLength( 0 );
+ fgSizer1->Add( m_textName, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 6 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxEXPAND, 6 );
+
+ m_staticText2 = new wxStaticText( this, wxID_ANY, _("Text height:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText2->Wrap( -1 );
+ fgSizer1->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+ m_textHeight = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textHeight->SetMaxLength( 0 );
+ fgSizer1->Add( m_textHeight, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 6 );
+
+ m_staticHeightUnits = new wxStaticText( this, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticHeightUnits->Wrap( -1 );
+ fgSizer1->Add( m_staticHeightUnits, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+ m_staticText5 = new wxStaticText( this, wxID_ANY, _("Text width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText5->Wrap( -1 );
+ fgSizer1->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+ m_textWidth = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textWidth->SetMaxLength( 0 );
+ fgSizer1->Add( m_textWidth, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 6 );
+
+ m_staticWidthUnits = new wxStaticText( this, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticWidthUnits->Wrap( -1 );
+ fgSizer1->Add( m_staticWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+ m_staticText3 = new wxStaticText( this, wxID_ANY, _("Connection type:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ fgSizer1->Add( m_staticText3, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+ wxArrayString m_choiceConnectionTypeChoices;
+ m_choiceConnectionType = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceConnectionTypeChoices, 0 );
+ m_choiceConnectionType->SetSelection( 0 );
+ fgSizer1->Add( m_choiceConnectionType, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxEXPAND, 6 );
+
+
+ m_nameSizer->Add( fgSizer1, 1, wxEXPAND, 6 );
+
+
+ m_mainSizer->Add( m_nameSizer, 1, wxALL|wxEXPAND, 6 );
+
+
+ m_mainSizer->Add( 0, 0, 0, wxALL|wxEXPAND, 3 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ m_mainSizer->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 6 );
+
+
+ this->SetSizer( m_mainSizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_SCH_EDIT_SHEET_PIN_BASE::~DIALOG_SCH_EDIT_SHEET_PIN_BASE()
+{
+}
diff --git a/eeschema/dialogs/dialog_sch_edit_sheet_pin_base.fbp b/eeschema/dialogs/dialog_sch_edit_sheet_pin_base.fbp
new file mode 100644
index 0000000..f5c7863
--- /dev/null
+++ b/eeschema/dialogs/dialog_sch_edit_sheet_pin_base.fbp
@@ -0,0 +1,1043 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_sch_edit_sheet_pin_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_sch_edit_sheet_pin</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">350,-1</property>
+ <property name="name">DIALOG_SCH_EDIT_SHEET_PIN_BASE</property>
+ <property name="pos"></property>
+ <property name="size">350,189</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Sheet Pin Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_mainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_nameSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">4</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Name:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text height:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textHeight</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NUMERIC</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">units</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticHeightUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">units</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticWidthUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Connection type:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceConnectionType</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_sch_edit_sheet_pin_base.h b/eeschema/dialogs/dialog_sch_edit_sheet_pin_base.h
new file mode 100644
index 0000000..fb19f93
--- /dev/null
+++ b/eeschema/dialogs/dialog_sch_edit_sheet_pin_base.h
@@ -0,0 +1,61 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_SCH_EDIT_SHEET_PIN_BASE_H__
+#define __DIALOG_SCH_EDIT_SHEET_PIN_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/choice.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_SCH_EDIT_SHEET_PIN_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_SCH_EDIT_SHEET_PIN_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText1;
+ wxTextCtrl* m_textName;
+ wxStaticText* m_staticText2;
+ wxTextCtrl* m_textHeight;
+ wxStaticText* m_staticHeightUnits;
+ wxStaticText* m_staticText5;
+ wxTextCtrl* m_textWidth;
+ wxStaticText* m_staticWidthUnits;
+ wxStaticText* m_staticText3;
+ wxChoice* m_choiceConnectionType;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ public:
+
+ DIALOG_SCH_EDIT_SHEET_PIN_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Sheet Pin Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 350,189 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_SCH_EDIT_SHEET_PIN_BASE();
+
+};
+
+#endif //__DIALOG_SCH_EDIT_SHEET_PIN_BASE_H__
diff --git a/eeschema/dialogs/dialog_sch_sheet_props.cpp b/eeschema/dialogs/dialog_sch_sheet_props.cpp
new file mode 100644
index 0000000..795a56a
--- /dev/null
+++ b/eeschema/dialogs/dialog_sch_sheet_props.cpp
@@ -0,0 +1,61 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wx/string.h>
+#include <dialog_sch_sheet_props.h>
+#include <validators.h>
+
+
+DIALOG_SCH_SHEET_PROPS::DIALOG_SCH_SHEET_PROPS( wxWindow* parent ) :
+ DIALOG_SCH_SHEET_PROPS_BASE( parent )
+{
+ m_textFileName->SetValidator( FILE_NAME_WITH_PATH_CHAR_VALIDATOR() );
+ m_textFileName->SetFocus();
+ m_sdbSizer1OK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void DIALOG_SCH_SHEET_PROPS::SetFileName( const wxString& aFileName )
+{
+ // Filenames are stored using unix notation
+ wxString fname = aFileName;
+#ifdef __WINDOWS__
+ fname.Replace( wxT("/"), wxT("\\") );
+#endif
+ m_textFileName->SetValue( fname );
+}
+
+
+const wxString DIALOG_SCH_SHEET_PROPS::GetFileName()
+{
+ // Filenames are stored using unix notation
+ wxString fname = m_textFileName->GetValue();
+ fname.Replace( wxT("\\"), wxT("/") );
+ return fname;
+}
diff --git a/eeschema/dialogs/dialog_sch_sheet_props.fbp b/eeschema/dialogs/dialog_sch_sheet_props.fbp
new file mode 100644
index 0000000..93347cc
--- /dev/null
+++ b/eeschema/dialogs/dialog_sch_sheet_props.fbp
@@ -0,0 +1,1503 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">table</property>
+ <property name="file">dialog_sch_sheet_props_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_sch_sheet_props</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">500,150</property>
+ <property name="name">DIALOG_SCH_SHEET_PROPS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">519,187</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Schematic Sheet Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">mainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bupperSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">6</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;File name:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">5</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">200,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_textFileName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Si&amp;ze:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textFileNameSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">units</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticFileNameSizeUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Sheet name:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">5</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textSheetName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Size:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textSheetNameSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">units</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticSheetNameSizeUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unique timestamp:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextTimeStamp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlTimeStamp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_sch_sheet_props.h b/eeschema/dialogs/dialog_sch_sheet_props.h
new file mode 100644
index 0000000..e4aa3a6
--- /dev/null
+++ b/eeschema/dialogs/dialog_sch_sheet_props.h
@@ -0,0 +1,80 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __dialog_sch_sheet_props__
+#define __dialog_sch_sheet_props__
+
+/**
+ * @file
+ * Subclass of DIALOG_SCH_SHEET_PROPS_BASE, which is generated by wxFormBuilder.
+ */
+
+#include <dialog_sch_sheet_props_base.h>
+
+/** Implementing DIALOG_SCH_SHEET_PROPS_BASE */
+class DIALOG_SCH_SHEET_PROPS : public DIALOG_SCH_SHEET_PROPS_BASE
+{
+public:
+ /** Constructor */
+ DIALOG_SCH_SHEET_PROPS( wxWindow* parent );
+
+ void SetFileName( const wxString& aFileName );
+ const wxString GetFileName();
+
+ void SetSheetName( const wxString& aSheetName )
+ {
+ m_textSheetName->SetValue( aSheetName );
+ }
+ wxString GetSheetName() { return m_textSheetName->GetValue(); }
+
+ void SetFileNameTextSize( const wxString& aTextSize )
+ {
+ m_textFileNameSize->SetValue( aTextSize );
+ }
+ wxString GetFileNameTextSize() { return m_textFileNameSize->GetValue(); }
+
+ void SetSheetNameTextSize( const wxString& aTextSize )
+ {
+ m_textSheetNameSize->SetValue( aTextSize );
+ }
+ wxString GetSheetNameTextSize() { return m_textSheetNameSize->GetValue(); }
+
+ void SetFileNameTextSizeUnits(const wxString& aUnits)
+ {
+ m_staticFileNameSizeUnits->SetLabel( aUnits );
+ }
+
+ void SetSheetNameTextSizeUnits(const wxString& aUnits)
+ {
+ m_staticSheetNameSizeUnits->SetLabel( aUnits );
+ }
+
+ void SetSheetTimeStamp(const wxString& aTimeStamp)
+ {
+ m_textCtrlTimeStamp->SetValue( aTimeStamp );
+ }
+
+};
+
+#endif // __dialog_sch_sheet_props__
diff --git a/eeschema/dialogs/dialog_sch_sheet_props_base.cpp b/eeschema/dialogs/dialog_sch_sheet_props_base.cpp
new file mode 100644
index 0000000..f85225b
--- /dev/null
+++ b/eeschema/dialogs/dialog_sch_sheet_props_base.cpp
@@ -0,0 +1,131 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_sch_sheet_props_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_SCH_SHEET_PROPS_BASE::DIALOG_SCH_SHEET_PROPS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( 500,150 ), wxDefaultSize );
+
+ wxBoxSizer* mainSizer;
+ mainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bupperSizer;
+ bupperSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 0, 6, 0, 0 );
+ fgSizer1->AddGrowableCol( 1 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText1 = new wxStaticText( this, wxID_ANY, _("&File name:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ fgSizer1->Add( m_staticText1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_textFileName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textFileName->SetMaxLength( 0 );
+ m_textFileName->SetMinSize( wxSize( 200,-1 ) );
+
+ fgSizer1->Add( m_textFileName, 5, wxEXPAND|wxTOP|wxBOTTOM, 3 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxALIGN_CENTER_HORIZONTAL|wxALL, 3 );
+
+ m_staticText2 = new wxStaticText( this, wxID_ANY, _("Si&ze:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText2->Wrap( -1 );
+ fgSizer1->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_textFileNameSize = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textFileNameSize->SetMaxLength( 0 );
+ fgSizer1->Add( m_textFileNameSize, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 3 );
+
+ m_staticFileNameSizeUnits = new wxStaticText( this, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticFileNameSizeUnits->Wrap( -1 );
+ fgSizer1->Add( m_staticFileNameSizeUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_staticText4 = new wxStaticText( this, wxID_ANY, _("&Sheet name:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText4->Wrap( -1 );
+ fgSizer1->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_textSheetName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textSheetName->SetMaxLength( 0 );
+ fgSizer1->Add( m_textSheetName, 5, wxEXPAND|wxTOP|wxBOTTOM, 3 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_staticText5 = new wxStaticText( this, wxID_ANY, _("&Size:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText5->Wrap( -1 );
+ fgSizer1->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_textSheetNameSize = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textSheetNameSize->SetMaxLength( 0 );
+ fgSizer1->Add( m_textSheetNameSize, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 3 );
+
+ m_staticSheetNameSizeUnits = new wxStaticText( this, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticSheetNameSizeUnits->Wrap( -1 );
+ fgSizer1->Add( m_staticSheetNameSizeUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ fgSizer1->Add( m_staticline2, 0, wxEXPAND|wxALL, 5 );
+
+ m_staticline3 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ fgSizer1->Add( m_staticline3, 0, wxEXPAND | wxALL, 5 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_staticTextTimeStamp = new wxStaticText( this, wxID_ANY, _("Unique timestamp:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextTimeStamp->Wrap( -1 );
+ fgSizer1->Add( m_staticTextTimeStamp, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_textCtrlTimeStamp = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ fgSizer1->Add( m_textCtrlTimeStamp, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+
+ bupperSizer->Add( fgSizer1, 1, wxALL|wxEXPAND, 5 );
+
+
+ mainSizer->Add( bupperSizer, 0, wxEXPAND, 5 );
+
+
+ mainSizer->Add( 0, 0, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ mainSizer->Add( m_staticline1, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ mainSizer->Add( m_sdbSizer1, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( mainSizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_SCH_SHEET_PROPS_BASE::~DIALOG_SCH_SHEET_PROPS_BASE()
+{
+}
diff --git a/eeschema/dialogs/dialog_sch_sheet_props_base.h b/eeschema/dialogs/dialog_sch_sheet_props_base.h
new file mode 100644
index 0000000..46a438a
--- /dev/null
+++ b/eeschema/dialogs/dialog_sch_sheet_props_base.h
@@ -0,0 +1,65 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_SCH_SHEET_PROPS_BASE_H__
+#define __DIALOG_SCH_SHEET_PROPS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/statline.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_SCH_SHEET_PROPS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_SCH_SHEET_PROPS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText1;
+ wxTextCtrl* m_textFileName;
+ wxStaticText* m_staticText2;
+ wxTextCtrl* m_textFileNameSize;
+ wxStaticText* m_staticFileNameSizeUnits;
+ wxStaticText* m_staticText4;
+ wxTextCtrl* m_textSheetName;
+ wxStaticText* m_staticText5;
+ wxTextCtrl* m_textSheetNameSize;
+ wxStaticText* m_staticSheetNameSizeUnits;
+ wxStaticLine* m_staticline2;
+ wxStaticLine* m_staticline3;
+ wxStaticText* m_staticTextTimeStamp;
+ wxTextCtrl* m_textCtrlTimeStamp;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ public:
+
+ DIALOG_SCH_SHEET_PROPS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Schematic Sheet Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 519,187 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_SCH_SHEET_PROPS_BASE();
+
+};
+
+#endif //__DIALOG_SCH_SHEET_PROPS_BASE_H__
diff --git a/eeschema/dialogs/dialog_schematic_find.cpp b/eeschema/dialogs/dialog_schematic_find.cpp
new file mode 100644
index 0000000..52996a5
--- /dev/null
+++ b/eeschema/dialogs/dialog_schematic_find.cpp
@@ -0,0 +1,284 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2010-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_schematic_find.cpp
+ * @brief Schematic find and replace dialog implementation.
+ */
+
+#include <dialog_schematic_find.h>
+
+
+DEFINE_EVENT_TYPE( EVT_COMMAND_FIND_DRC_MARKER )
+DEFINE_EVENT_TYPE( EVT_COMMAND_FIND_COMPONENT_IN_LIB )
+
+
+DIALOG_SCH_FIND::DIALOG_SCH_FIND( wxWindow* aParent, wxFindReplaceData* aData,
+ const wxPoint& aPosition, const wxSize& aSize, int aStyle ) :
+ DIALOG_SCH_FIND_BASE( aParent, wxID_ANY, _( "Find" ), aPosition, aSize,
+ wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | aStyle )
+{
+ SetData( aData );
+
+ wxASSERT_MSG( m_findReplaceData, wxT( "can't create find dialog without data" ) );
+
+ if( aStyle & wxFR_REPLACEDIALOG )
+ {
+ SetTitle( _( "Find and Replace" ) );
+ m_buttonReplace->Show( true );
+ m_buttonReplaceAll->Show( true );
+ m_staticReplace->Show( true );
+ m_comboReplace->Show( true );
+ m_checkReplaceReferences->Show( true );
+ m_checkWildcardMatch->Show( false ); // Wildcard replace is not implemented.
+ }
+
+ int flags = m_findReplaceData->GetFlags();
+ m_radioForward->SetValue( flags & wxFR_DOWN );
+ m_radioBackward->SetValue( ( flags & wxFR_DOWN ) == 0 );
+ m_checkMatchCase->SetValue( flags & wxFR_MATCHCASE );
+ m_checkWholeWord->SetValue( flags & wxFR_WHOLEWORD );
+ m_checkNoWarpCursor->SetValue( flags & FR_NO_WARP_CURSOR );
+
+ /* Whole word and wild card searches are mutually exclusive. */
+ if( !( flags & wxFR_WHOLEWORD ) )
+ m_checkWildcardMatch->SetValue( flags & FR_MATCH_WILDCARD );
+
+ m_checkAllFields->SetValue( flags & FR_SEARCH_ALL_FIELDS );
+ m_checkReplaceReferences->SetValue( flags & FR_REPLACE_REFERENCES );
+ m_checkAllPins->SetValue( flags & FR_SEARCH_ALL_PINS );
+ m_checkWrap->SetValue( flags & FR_SEARCH_WRAP );
+ m_checkCurrentSheetOnly->SetValue( flags & FR_CURRENT_SHEET_ONLY );
+
+ m_buttonFind->SetDefault();
+ m_comboFind->SetFocus();
+ SetPosition( aPosition );
+
+ // Adjust the height of the dialog to prevent controls from being hidden when
+ // switching between the find and find/replace modes of the dialog. This ignores
+ // the users preferred height if any of the controls would be hidden.
+ GetSizer()->SetSizeHints( this );
+ wxSize size = aSize;
+
+ if( aSize != wxDefaultSize )
+ {
+ wxSize bestSize = GetBestSize();
+
+ if( size.GetHeight() != bestSize.GetHeight() )
+ size.SetHeight( bestSize.GetHeight() );
+ }
+
+ SetSize( size );
+
+ GetSizer()->Fit( this ); // Needed on Ubuntu/Unity to display the dialog
+}
+
+
+void DIALOG_SCH_FIND::OnClose( wxCloseEvent& aEvent )
+{
+ SendEvent( wxEVT_COMMAND_FIND_CLOSE );
+}
+
+
+void DIALOG_SCH_FIND::OnUpdateFindUI( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Enable( !m_comboFind->GetValue().empty() );
+}
+
+
+void DIALOG_SCH_FIND::OnUpdateReplaceUI( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Enable( HasFlag( wxFR_REPLACEDIALOG ) && !m_comboFind->GetValue().empty() &&
+ (m_findReplaceData->GetFlags() & FR_REPLACE_ITEM_FOUND) );
+}
+
+
+void DIALOG_SCH_FIND::OnUpdateWholeWordUI( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Enable( !m_checkWildcardMatch->GetValue() );
+}
+
+
+void DIALOG_SCH_FIND::OnUpdateWildcardUI( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Enable( !m_checkWholeWord->GetValue() );
+}
+
+
+void DIALOG_SCH_FIND::OnFind( wxCommandEvent& aEvent )
+{
+ int index = m_comboFind->FindString( m_comboFind->GetValue(), true );
+
+ if( index == wxNOT_FOUND )
+ {
+ m_comboFind->Insert( m_comboFind->GetValue(), 0 );
+ }
+ else if( index != 0 )
+ {
+ /* Move the search string to the top of the list if it isn't already there. */
+ wxString tmp = m_comboFind->GetValue();
+ m_comboFind->Delete( index );
+ m_comboFind->Insert( tmp, 0 );
+ m_comboFind->SetSelection( 0 );
+ }
+
+ SendEvent( wxEVT_COMMAND_FIND );
+}
+
+
+void DIALOG_SCH_FIND::OnReplace( wxCommandEvent& aEvent )
+{
+ int index = m_comboReplace->FindString( m_comboReplace->GetValue(), true );
+
+ if( index == wxNOT_FOUND )
+ {
+ m_comboReplace->Insert( m_comboReplace->GetValue(), 0 );
+ }
+ else if( index != 0 )
+ {
+ /* Move the search string to the top of the list if it isn't already there. */
+ wxString tmp = m_comboReplace->GetValue();
+ m_comboReplace->Delete( index );
+ m_comboReplace->Insert( tmp, 0 );
+ m_comboReplace->SetSelection( 0 );
+ }
+
+ if( aEvent.GetId() == wxID_REPLACE )
+ SendEvent( wxEVT_COMMAND_FIND_REPLACE );
+ else if( aEvent.GetId() == wxID_REPLACE_ALL )
+ SendEvent( wxEVT_COMMAND_FIND_REPLACE_ALL );
+}
+
+
+void DIALOG_SCH_FIND::OnCancel( wxCommandEvent& aEvent )
+{
+ SendEvent( wxEVT_COMMAND_FIND_CLOSE );
+ Show( false );
+}
+
+
+void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType )
+{
+ wxFindDialogEvent event( aEventType, GetId() );
+ event.SetEventObject( this );
+ event.SetFindString( m_comboFind->GetValue() );
+
+ int flags = 0;
+
+ if ( HasFlag( wxFR_REPLACEDIALOG ) )
+ {
+ event.SetReplaceString( m_comboReplace->GetValue() );
+ flags |= FR_SEARCH_REPLACE;
+ }
+
+ if( m_checkReplaceReferences->GetValue() )
+ flags |= FR_REPLACE_REFERENCES;
+
+ if( m_radioForward->GetValue() )
+ flags |= wxFR_DOWN;
+
+ if( m_checkMatchCase->GetValue() )
+ flags |= wxFR_MATCHCASE;
+
+ if( m_checkWholeWord->GetValue() )
+ flags |= wxFR_WHOLEWORD;
+
+ if( m_checkWildcardMatch->IsShown() && m_checkWildcardMatch->GetValue() )
+ flags |= FR_MATCH_WILDCARD;
+
+ if( m_checkAllFields->GetValue() )
+ flags |= FR_SEARCH_ALL_FIELDS;
+
+ if( m_checkAllPins->GetValue() )
+ flags |= FR_SEARCH_ALL_PINS;
+
+ if( m_checkWrap->GetValue() )
+ flags |= FR_SEARCH_WRAP;
+
+ if( m_checkCurrentSheetOnly->GetValue() )
+ flags |= FR_CURRENT_SHEET_ONLY;
+
+ if( m_checkNoWarpCursor->GetValue() )
+ flags |= FR_NO_WARP_CURSOR;
+
+ m_findReplaceData->SetFindString( event.GetFindString() );
+
+ if( HasFlag( wxFR_REPLACEDIALOG )
+ && ( event.GetEventType() == wxEVT_COMMAND_FIND_REPLACE
+ || event.GetEventType() == wxEVT_COMMAND_FIND_REPLACE_ALL ) )
+ {
+ m_findReplaceData->SetReplaceString( event.GetReplaceString() );
+ }
+
+ event.SetFlags( flags );
+
+ m_findReplaceData->SetFlags( event.GetFlags() );
+
+ // when we are no using the find/replace (just find)
+ // FR_REPLACE_REFERENCES flag bit is always set to 1 in event flags
+ // but not set in m_findReplaceData
+ if ( ! HasFlag( wxFR_REPLACEDIALOG ) )
+ {
+ flags |= FR_REPLACE_REFERENCES;
+ event.SetFlags( flags );
+ }
+
+ if( !GetEventHandler()->ProcessEvent( event ) )
+ {
+ GetParent()->GetEventHandler()->ProcessEvent( event );
+ }
+
+ if( event.GetFlags() != flags )
+ m_findReplaceData->SetFlags( event.GetFlags() );
+}
+
+
+wxArrayString DIALOG_SCH_FIND::GetFindEntries() const
+{
+ return m_comboFind->GetStrings();
+}
+
+
+void DIALOG_SCH_FIND::SetFindEntries( const wxArrayString& aEntries )
+{
+ m_comboFind->Append( aEntries );
+
+ if( m_comboFind->GetCount() )
+ {
+ m_comboFind->SetSelection( 0 );
+ m_comboFind->SelectAll();
+ }
+}
+
+
+void DIALOG_SCH_FIND::SetReplaceEntries( const wxArrayString& aEntries )
+{
+ m_comboReplace->Append( aEntries );
+
+ if( m_comboReplace->GetCount() )
+ {
+ m_comboReplace->SetSelection( 0 );
+ m_comboFind->SelectAll();
+ }
+}
diff --git a/eeschema/dialogs/dialog_schematic_find.h b/eeschema/dialogs/dialog_schematic_find.h
new file mode 100644
index 0000000..054cf01
--- /dev/null
+++ b/eeschema/dialogs/dialog_schematic_find.h
@@ -0,0 +1,201 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2010-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file
+ *
+ * Subclass of DIALOG_SCH_FIND_BASE, which is generated by wxFormBuilder.
+ *
+ * This dialog is used to define the search criteria used to search for items
+ * in the current schematic. What is searched depends on the schematic item
+ * type. Check the Matches() method for each item derived from SCH_ITEM() to
+ * find out how matching is performed against that item.
+ */
+
+#ifndef __dialog_schematic_find__
+#define __dialog_schematic_find__
+
+#include "dialog_schematic_find_base.h"
+
+#include <wx/fdrepdlg.h> // Use the wxFindReplaceDialog events, data, and enums.
+
+
+/**
+ * Define schematic specific find and replace dialog flags based on the enum entries
+ * in wxFindReplaceFlags. These flags are intended to be used as bit masks in the
+ * wxFindReplaceData::m_Flags member variable. The variable is defined as a wxUint32.
+ */
+enum SchematicFindReplaceFlags
+{
+ // The last wxFindReplaceFlag enum is wxFR_MATCHCASE = 0x4.
+
+ /// Search the current sheet only.
+ FR_CURRENT_SHEET_ONLY = wxFR_MATCHCASE << 1,
+
+ /// Search all fields in component, not just the value and reference fields.
+ FR_SEARCH_ALL_FIELDS = wxFR_MATCHCASE << 2,
+
+ /// Search texts (name and number (a 4 letters text) )in pins.
+ FR_SEARCH_ALL_PINS = wxFR_MATCHCASE << 3,
+
+ /// Perform search using simple wild card matching (* & ?).
+ FR_MATCH_WILDCARD = wxFR_MATCHCASE << 4,
+
+ /// Wrap around the beginning or end of search list.
+ FR_SEARCH_WRAP = wxFR_MATCHCASE << 5,
+
+ /// Don't warp cursor to found item until the dialog is closed.
+ FR_NO_WARP_CURSOR = wxFR_MATCHCASE << 6,
+
+ /// Perform a search for a item that has replaceable text.
+ FR_SEARCH_REPLACE = wxFR_MATCHCASE << 7,
+
+ /// Used by the search event handler to let the dialog know that a replaceable
+ /// item has been found.
+ FR_REPLACE_ITEM_FOUND = wxFR_MATCHCASE << 8,
+
+ /// Used by replace to ignore the component reference designator field.
+ FR_REPLACE_REFERENCES = wxFR_MATCHCASE << 9
+};
+
+
+/**
+ * Definition FR_MASK_NON_COMPARE_FLAGS
+ * is used to mask find/replace flag bits that do not effect the search results.
+ */
+#define FR_MASK_NON_COMPARE_FLAGS ~( wxFR_DOWN | FR_SEARCH_WRAP | FR_NO_WARP_CURSOR | \
+ FR_REPLACE_ITEM_FOUND )
+
+
+/**
+ * Class SCH_FIND_REPLACE_DATA
+ * adds missing useful comparison and assignment operators to the wxFindReplaceData object.
+ */
+class SCH_FIND_REPLACE_DATA : public wxFindReplaceData
+{
+public:
+
+ SCH_FIND_REPLACE_DATA& operator =( SCH_FIND_REPLACE_DATA& aFindReplaceData )
+ {
+ if( this == &aFindReplaceData )
+ return *this;
+
+ SetFlags( aFindReplaceData.GetFlags() );
+ SetFindString( aFindReplaceData.GetFindString() );
+ SetReplaceString( aFindReplaceData.GetReplaceString() );
+
+ return *this;
+ }
+
+ bool operator ==( SCH_FIND_REPLACE_DATA& aFindReplaceData )
+ {
+ return ( (GetFlags() == aFindReplaceData.GetFlags())
+ && (GetFindString() == aFindReplaceData.GetFindString())
+ && (GetReplaceString() == aFindReplaceData.GetReplaceString()) );
+ }
+
+ bool operator !=( SCH_FIND_REPLACE_DATA& aFindReplaceData )
+ {
+ return !( *this == aFindReplaceData );
+ }
+
+
+ /**
+ * Function ChangesCompare
+ * tests \a aFindReplaceData to see if it would result in a change in the search string
+ * comparison results.
+ *
+ * @param aFindReplaceData A reference to a #SCH_FIND_REPLACE_DATA object to compare
+ * against.
+ * @return True if \a aFindReplaceData would result in a search and/or replace change,
+ * otherwise false.
+ */
+ bool ChangesCompare( const SCH_FIND_REPLACE_DATA& aFindReplaceData )
+ {
+ return ( (GetFindString() != aFindReplaceData.GetFindString())
+ || (GetCompareFlags() != aFindReplaceData.GetCompareFlags()) );
+ }
+
+ bool IsReplacing() const { return (GetFlags() & FR_SEARCH_REPLACE) != 0; }
+ bool IsWrapping() const { return (GetFlags() & FR_SEARCH_WRAP) != 0; }
+
+private:
+ /**
+ * Function GetSearchFlags
+ * @return The flags that only effect the search result.
+ */
+ wxUint32 GetCompareFlags() const { return GetFlags() & FR_MASK_NON_COMPARE_FLAGS; }
+};
+
+
+/** Implementing DIALOG_SCH_FIND_BASE */
+class DIALOG_SCH_FIND : public DIALOG_SCH_FIND_BASE
+{
+protected:
+ // Handlers for DIALOG_SCH_FIND_BASE events.
+ void OnClose( wxCloseEvent& aEvent );
+ void OnUpdateFindUI( wxUpdateUIEvent& aEvent );
+ void OnUpdateReplaceUI( wxUpdateUIEvent& aEvent );
+ void OnUpdateWholeWordUI( wxUpdateUIEvent& aEvent );
+ void OnUpdateWildcardUI( wxUpdateUIEvent& aEvent );
+
+ void OnFind( wxCommandEvent& aEvent );
+ void OnReplace( wxCommandEvent& aEvent );
+ void OnCancel( wxCommandEvent& aEvent );
+
+ void SendEvent( const wxEventType& aEventType );
+
+ wxFindReplaceData *m_findReplaceData;
+
+ DECLARE_NO_COPY_CLASS( DIALOG_SCH_FIND )
+
+public:
+ DIALOG_SCH_FIND( wxWindow* aParent, wxFindReplaceData* aData,
+ const wxPoint& aPosition = wxDefaultPosition,
+ const wxSize& aSize = wxDefaultSize, int aStyle = 0 );
+
+ const wxFindReplaceData *GetData() const { return m_findReplaceData; }
+ void SetData(wxFindReplaceData *aData) { m_findReplaceData = aData; }
+
+ void SetFindEntries( const wxArrayString& aEntries );
+ wxArrayString GetFindEntries() const;
+
+ void SetReplaceEntries( const wxArrayString& aEntries );
+ wxArrayString GetReplaceEntries() const { return m_comboReplace->GetStrings(); }
+};
+
+
+BEGIN_DECLARE_EVENT_TYPES()
+ DECLARE_LOCAL_EVENT_TYPE( EVT_COMMAND_FIND_DRC_MARKER, wxID_ANY )
+ DECLARE_LOCAL_EVENT_TYPE( EVT_COMMAND_FIND_COMPONENT_IN_LIB, wxID_ANY )
+END_DECLARE_EVENT_TYPES()
+
+
+#define EVT_FIND_DRC_MARKER( id, fn ) \
+ wx__DECLARE_EVT1( EVT_COMMAND_FIND_DRC_MARKER, id, wxFindDialogEventHandler( fn ) )
+
+#define EVT_FIND_COMPONENT_IN_LIB( id, fn ) \
+ wx__DECLARE_EVT1( EVT_COMMAND_FIND_COMPONENT_IN_LIB, id, wxFindDialogEventHandler( fn ) )
+
+#endif // __dialog_schematic_find__
diff --git a/eeschema/dialogs/dialog_schematic_find_base.cpp b/eeschema/dialogs/dialog_schematic_find_base.cpp
new file mode 100644
index 0000000..59f78e2
--- /dev/null
+++ b/eeschema/dialogs/dialog_schematic_find_base.cpp
@@ -0,0 +1,169 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_schematic_find_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* mainSizer;
+ mainSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* leftSizer;
+ leftSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* leftGridSizer;
+ leftGridSizer = new wxFlexGridSizer( 3, 2, 3, 3 );
+ leftGridSizer->AddGrowableCol( 1 );
+ leftGridSizer->SetFlexibleDirection( wxBOTH );
+ leftGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText1 = new wxStaticText( this, wxID_ANY, _("&Search for:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ leftGridSizer->Add( m_staticText1, 0, wxEXPAND|wxLEFT|wxRIGHT, 6 );
+
+ m_comboFind = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN );
+ m_comboFind->SetToolTip( _("Text with optional wildcards") );
+ m_comboFind->SetMinSize( wxSize( 125,-1 ) );
+
+ leftGridSizer->Add( m_comboFind, 1, wxEXPAND|wxLEFT|wxRIGHT, 6 );
+
+ m_staticReplace = new wxStaticText( this, wxID_ANY, _("Replace &with:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticReplace->Wrap( -1 );
+ m_staticReplace->Hide();
+
+ leftGridSizer->Add( m_staticReplace, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_comboReplace = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ m_comboReplace->Hide();
+
+ leftGridSizer->Add( m_comboReplace, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticDirection = new wxStaticText( this, wxID_ANY, _("Direction:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticDirection->Wrap( -1 );
+ m_staticDirection->Hide();
+
+ leftGridSizer->Add( m_staticDirection, 0, 0, 5 );
+
+ wxBoxSizer* directionSizer;
+ directionSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_radioForward = new wxRadioButton( this, wxID_ANY, _("F&orward"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
+ m_radioForward->Hide();
+
+ directionSizer->Add( m_radioForward, 0, wxALL, 3 );
+
+ m_radioBackward = new wxRadioButton( this, wxID_ANY, _("&Backward"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_radioBackward->Hide();
+
+ directionSizer->Add( m_radioBackward, 0, wxALL, 3 );
+
+
+ leftGridSizer->Add( directionSizer, 1, wxEXPAND, 5 );
+
+
+ leftSizer->Add( leftGridSizer, 1, wxALL|wxEXPAND, 6 );
+
+ m_checkWholeWord = new wxCheckBox( this, wxID_ANY, _("Match whole wor&d"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkWholeWord->SetValue(true);
+ leftSizer->Add( m_checkWholeWord, 0, wxALL, 6 );
+
+ m_checkMatchCase = new wxCheckBox( this, wxID_ANY, _("&Match case"), wxDefaultPosition, wxDefaultSize, 0 );
+ leftSizer->Add( m_checkMatchCase, 0, wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+ m_checkWildcardMatch = new wxCheckBox( this, wxID_ANY, _("Search &using simple wildcard matching"), wxDefaultPosition, wxDefaultSize, 0 );
+ leftSizer->Add( m_checkWildcardMatch, 0, wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+ m_checkWrap = new wxCheckBox( this, wxID_ANY, _("Wrap around &end of search list"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkWrap->SetValue(true);
+ leftSizer->Add( m_checkWrap, 0, wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+ m_checkAllFields = new wxCheckBox( this, wxID_ANY, _("Search all com&ponent fields"), wxDefaultPosition, wxDefaultSize, 0 );
+ leftSizer->Add( m_checkAllFields, 0, wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+ m_checkAllPins = new wxCheckBox( this, wxID_ANY, _("Search all pin &names and numbers"), wxDefaultPosition, wxDefaultSize, 0 );
+ leftSizer->Add( m_checkAllPins, 0, wxBOTTOM|wxRIGHT|wxLEFT, 6 );
+
+ m_checkCurrentSheetOnly = new wxCheckBox( this, wxID_ANY, _("Search the current &sheet onl&y"), wxDefaultPosition, wxDefaultSize, 0 );
+ leftSizer->Add( m_checkCurrentSheetOnly, 0, wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+ m_checkReplaceReferences = new wxCheckBox( this, wxID_ANY, _("Replace componen&t reference designators"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkReplaceReferences->Hide();
+
+ leftSizer->Add( m_checkReplaceReferences, 0, wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+ m_checkNoWarpCursor = new wxCheckBox( this, wxID_ANY, _("D&o not warp cursor to found item"), wxDefaultPosition, wxDefaultSize, 0 );
+ leftSizer->Add( m_checkNoWarpCursor, 0, wxBOTTOM|wxLEFT|wxRIGHT, 6 );
+
+
+ mainSizer->Add( leftSizer, 1, wxALL|wxEXPAND, 6 );
+
+ wxBoxSizer* rightSizer;
+ rightSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonFind = new wxButton( this, wxID_FIND, _("&Find"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonFind->SetDefault();
+ rightSizer->Add( m_buttonFind, 0, wxALL|wxEXPAND, 6 );
+
+ m_buttonReplace = new wxButton( this, wxID_REPLACE, _("&Replace"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonReplace->Hide();
+
+ rightSizer->Add( m_buttonReplace, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 6 );
+
+ m_buttonReplaceAll = new wxButton( this, wxID_REPLACE_ALL, _("Replace &All"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonReplaceAll->Hide();
+
+ rightSizer->Add( m_buttonReplaceAll, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 6 );
+
+ m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ rightSizer->Add( m_buttonCancel, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 6 );
+
+
+ mainSizer->Add( rightSizer, 0, wxALL|wxEXPAND, 6 );
+
+
+ this->SetSizer( mainSizer );
+ this->Layout();
+ mainSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_SCH_FIND_BASE::OnClose ) );
+ m_comboFind->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateDrcUI ), NULL, this );
+ m_comboReplace->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateDrcUI ), NULL, this );
+ m_checkWholeWord->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateWholeWordUI ), NULL, this );
+ m_checkWildcardMatch->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateWildcardUI ), NULL, this );
+ m_buttonFind->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnFind ), NULL, this );
+ m_buttonFind->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateFindUI ), NULL, this );
+ m_buttonReplace->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnReplace ), NULL, this );
+ m_buttonReplace->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateReplaceUI ), NULL, this );
+ m_buttonReplaceAll->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnReplace ), NULL, this );
+ m_buttonReplaceAll->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateReplaceUI ), NULL, this );
+ m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnCancel ), NULL, this );
+}
+
+DIALOG_SCH_FIND_BASE::~DIALOG_SCH_FIND_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_SCH_FIND_BASE::OnClose ) );
+ m_comboFind->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateDrcUI ), NULL, this );
+ m_comboReplace->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateDrcUI ), NULL, this );
+ m_checkWholeWord->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateWholeWordUI ), NULL, this );
+ m_checkWildcardMatch->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateWildcardUI ), NULL, this );
+ m_buttonFind->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnFind ), NULL, this );
+ m_buttonFind->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateFindUI ), NULL, this );
+ m_buttonReplace->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnReplace ), NULL, this );
+ m_buttonReplace->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateReplaceUI ), NULL, this );
+ m_buttonReplaceAll->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnReplace ), NULL, this );
+ m_buttonReplaceAll->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateReplaceUI ), NULL, this );
+ m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnCancel ), NULL, this );
+
+}
diff --git a/eeschema/dialogs/dialog_schematic_find_base.fbp b/eeschema/dialogs/dialog_schematic_find_base.fbp
new file mode 100644
index 0000000..5a75974
--- /dev/null
+++ b/eeschema/dialogs/dialog_schematic_find_base.fbp
@@ -0,0 +1,1901 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_schematic_find_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_sch_find</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_SCH_FIND_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Find</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnClose</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">mainSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">leftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">3</property>
+ <property name="minimum_size"></property>
+ <property name="name">leftGridSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">3</property>
+ <property name="vgap">3</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Search for:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxComboBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">125,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_comboFind</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxCB_DROPDOWN</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Text with optional wildcards</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI">OnUpdateDrcUI</event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">1</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Replace &amp;with:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticReplace</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxComboBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">1</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_comboReplace</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI">OnUpdateDrcUI</event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">1</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Direction:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticDirection</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">directionSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">1</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">F&amp;orward</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioForward</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRB_GROUP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">1</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Backward</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioBackward</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Match whole wor&amp;d</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkWholeWord</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI">OnUpdateWholeWordUI</event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Match case</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkMatchCase</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Search &amp;using simple wildcard matching</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkWildcardMatch</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI">OnUpdateWildcardUI</event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Wrap around &amp;end of search list</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkWrap</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Search all com&amp;ponent fields</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkAllFields</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Search all pin &amp;names and numbers</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkAllPins</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Search the current &amp;sheet onl&amp;y</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkCurrentSheetOnly</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">1</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Replace componen&amp;t reference designators</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkReplaceReferences</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">D&amp;o not warp cursor to found item</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkNoWarpCursor</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">rightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_FIND</property>
+ <property name="label">&amp;Find</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonFind</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnFind</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI">OnUpdateFindUI</event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">1</property>
+ <property name="id">wxID_REPLACE</property>
+ <property name="label">&amp;Replace</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonReplace</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnReplace</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI">OnUpdateReplaceUI</event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">1</property>
+ <property name="id">wxID_REPLACE_ALL</property>
+ <property name="label">Replace &amp;All</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonReplaceAll</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnReplace</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI">OnUpdateReplaceUI</event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">6</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonCancel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnCancel</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/eeschema/dialogs/dialog_schematic_find_base.h b/eeschema/dialogs/dialog_schematic_find_base.h
new file mode 100644
index 0000000..9fe0de4
--- /dev/null
+++ b/eeschema/dialogs/dialog_schematic_find_base.h
@@ -0,0 +1,81 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_SCHEMATIC_FIND_BASE_H__
+#define __DIALOG_SCHEMATIC_FIND_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/combobox.h>
+#include <wx/radiobut.h>
+#include <wx/sizer.h>
+#include <wx/checkbox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_SCH_FIND_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_SCH_FIND_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText1;
+ wxComboBox* m_comboFind;
+ wxStaticText* m_staticReplace;
+ wxComboBox* m_comboReplace;
+ wxStaticText* m_staticDirection;
+ wxRadioButton* m_radioForward;
+ wxRadioButton* m_radioBackward;
+ wxCheckBox* m_checkWholeWord;
+ wxCheckBox* m_checkMatchCase;
+ wxCheckBox* m_checkWildcardMatch;
+ wxCheckBox* m_checkWrap;
+ wxCheckBox* m_checkAllFields;
+ wxCheckBox* m_checkAllPins;
+ wxCheckBox* m_checkCurrentSheetOnly;
+ wxCheckBox* m_checkReplaceReferences;
+ wxCheckBox* m_checkNoWarpCursor;
+ wxButton* m_buttonFind;
+ wxButton* m_buttonReplace;
+ wxButton* m_buttonReplaceAll;
+ wxButton* m_buttonCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnUpdateDrcUI( wxUpdateUIEvent& event ) { event.Skip(); }
+ virtual void OnUpdateWholeWordUI( wxUpdateUIEvent& event ) { event.Skip(); }
+ virtual void OnUpdateWildcardUI( wxUpdateUIEvent& event ) { event.Skip(); }
+ virtual void OnFind( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnUpdateFindUI( wxUpdateUIEvent& event ) { event.Skip(); }
+ virtual void OnReplace( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnUpdateReplaceUI( wxUpdateUIEvent& event ) { event.Skip(); }
+ virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Find"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_SCH_FIND_BASE();
+
+};
+
+#endif //__DIALOG_SCHEMATIC_FIND_BASE_H__
diff --git a/eeschema/edit_bitmap.cpp b/eeschema/edit_bitmap.cpp
new file mode 100644
index 0000000..2cdc892
--- /dev/null
+++ b/eeschema/edit_bitmap.cpp
@@ -0,0 +1,199 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 jean-pierre.charras
+ * Copyright (C) 2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file edit_bitmap.cpp
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+
+#include <schframe.h>
+#include <sch_bitmap.h>
+#include <dialog_image_editor.h>
+
+
+static void abortMoveBitmap( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
+{
+ SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen();
+ SCH_BITMAP* item = (SCH_BITMAP*) screen->GetCurItem();
+ SCH_EDIT_FRAME* parent = (SCH_EDIT_FRAME*) aPanel->GetParent();
+
+ parent->SetRepeatItem( NULL );
+
+ if( item == NULL ) /* no current item */
+ return;
+
+ if( item->IsNew() )
+ {
+ delete item;
+ item = NULL;
+ }
+ else // Move command on an existing text item, restore the data of the original.
+ {
+ item->ClearFlags();
+
+ SCH_BITMAP * olditem = (SCH_BITMAP*) parent->GetUndoItem();
+
+ wxCHECK_RET( olditem != NULL && item->Type() == olditem->Type() &&
+ item->Type() == SCH_BITMAP_T,
+ wxT( "Cannot restore undefined last text item." ) );
+
+ // Never delete existing item, because it can be referenced by an undo/redo command
+ // Just restore its data
+ item->SwapData( olditem );
+ parent->SetUndoItem( NULL );
+ }
+
+ screen->SetCurItem( item );
+ aPanel->Refresh();
+}
+
+static void moveBitmap( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, bool aErase )
+{
+ SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen();
+ SCH_BITMAP* image = (SCH_BITMAP*) screen->GetCurItem();
+
+ if( aErase )
+ {
+ // Erase the current bitmap at its current position.
+ // Note also items flagged IS_MOVING are not drawn,
+ // and if image is new, it is not yet il draw list
+ // so image is erased from screen
+ EDA_RECT dirty = image->GetBoundingBox();
+ dirty.Inflate( 4 ); // Give a margin
+ aPanel->SetMouseCapture( NULL, NULL ); // Avoid loop in redraw panel
+
+ STATUS_FLAGS flgs = image->GetFlags();
+ image->ClearFlags();
+ aPanel->RefreshDrawingRect( dirty );
+ image->SetFlags( flgs );
+ aPanel->SetMouseCapture( moveBitmap, abortMoveBitmap );
+ }
+
+ // Draw the bitmap at it's new position.
+ image->SetPosition( aPanel->GetParent()->GetCrossHairPosition() );
+ image->Draw( aPanel, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+}
+
+
+SCH_BITMAP* SCH_EDIT_FRAME::CreateNewImage( wxDC* aDC )
+{
+ wxFileDialog fileDlg( this, _( "Choose Image" ), wxEmptyString, wxEmptyString,
+ _( "Image Files " ) + wxImage::GetImageExtWildcard(),
+ wxFD_OPEN );
+ int diag = fileDlg.ShowModal();
+
+ if( diag != wxID_OK )
+ return NULL;
+
+ wxString fullFilename = fileDlg.GetPath();
+
+ if( !wxFileExists( fullFilename ) )
+ {
+ wxMessageBox( _( "Couldn't load image from <%s>" ), GetChars( fullFilename ) );
+ return NULL;
+ }
+
+ wxPoint pos = GetCrossHairPosition();
+
+ SCH_BITMAP* image = new SCH_BITMAP( pos );
+
+ if( !image->ReadImageFile( fullFilename ) )
+ {
+ wxMessageBox( _( "Couldn't load image from <%s>" ), GetChars( fullFilename ) );
+ delete image;
+ return NULL;
+ }
+
+
+ image->SetFlags( IS_NEW | IS_MOVED );
+ image->Draw( m_canvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+
+ m_canvas->SetMouseCapture( moveBitmap, abortMoveBitmap );
+ GetScreen()->SetCurItem( image );
+
+ OnModify();
+ return image;
+}
+
+void SCH_EDIT_FRAME::MoveImage( SCH_BITMAP* aImageItem, wxDC* aDC )
+{
+ aImageItem->SetFlags( IS_MOVED );
+
+ m_canvas->SetMouseCapture( moveBitmap, abortMoveBitmap );
+ GetScreen()->SetCurItem( aImageItem );
+ SetRepeatItem( NULL );
+
+ SetUndoItem( aImageItem );
+
+ m_canvas->CrossHairOff( aDC );
+ SetCrossHairPosition( aImageItem->GetPosition() );
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->CrossHairOn( aDC );
+
+ OnModify();
+}
+
+void SCH_EDIT_FRAME::RotateImage( SCH_BITMAP* aItem )
+{
+ if( aItem->GetFlags( ) == 0 )
+ SaveCopyInUndoList( aItem, UR_ROTATED, aItem->GetPosition() );
+
+ aItem->Rotate( aItem->GetPosition() );
+ OnModify();
+ m_canvas->Refresh();
+}
+
+void SCH_EDIT_FRAME::MirrorImage( SCH_BITMAP* aItem, bool Is_X_axis )
+{
+ if( aItem->GetFlags( ) == 0 )
+ SaveCopyInUndoList( aItem, UR_CHANGED );
+
+ if( Is_X_axis )
+ aItem->MirrorX( aItem->GetPosition().y );
+ else
+ aItem->MirrorY( aItem->GetPosition().x );
+
+ OnModify();
+ m_canvas->Refresh();
+}
+
+void SCH_EDIT_FRAME::EditImage( SCH_BITMAP* aItem )
+{
+ // TODO: change image scale or more
+ DIALOG_IMAGE_EDITOR dlg( this, aItem->m_Image );
+ if( dlg.ShowModal() != wxID_OK )
+ return;
+
+ // save old image in undo list if not already in edit
+ // or the image to be edited is part of a block
+ if( aItem->GetFlags() == 0 ||
+ GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
+ SaveCopyInUndoList( aItem, UR_CHANGED );
+
+ dlg.TransfertToImage(aItem->m_Image);
+ OnModify();
+ m_canvas->Refresh();
+}
diff --git a/eeschema/edit_component_in_schematic.cpp b/eeschema/edit_component_in_schematic.cpp
new file mode 100644
index 0000000..200bf27
--- /dev/null
+++ b/eeschema/edit_component_in_schematic.cpp
@@ -0,0 +1,117 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2016 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file edit_component_in_schematic.cpp
+ * @brief Schematic component editing code.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <schframe.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <class_library.h>
+#include <sch_component.h>
+
+#include <dialog_edit_one_field.h>
+
+
+void SCH_EDIT_FRAME::EditComponentFieldText( SCH_FIELD* aField )
+{
+ wxCHECK_RET( aField != NULL && aField->Type() == SCH_FIELD_T,
+ wxT( "Cannot edit invalid schematic field." ) );
+
+ SCH_COMPONENT* component = (SCH_COMPONENT*) aField->GetParent();
+
+ wxCHECK_RET( component != NULL && component->Type() == SCH_COMPONENT_T,
+ wxT( "Invalid schematic field parent item." ) );
+
+ LIB_PART* part = Prj().SchLibs()->FindLibPart( component->GetPartName() );
+
+ wxCHECK_RET( part, wxT( "Library part for component <" ) +
+ component->GetPartName() + wxT( "> could not be found." ) );
+
+ // Save old component in undo list if not already in edit, or moving.
+ if( aField->GetFlags() == 0 )
+ SaveCopyInUndoList( component, UR_CHANGED );
+
+ // Don't use GetText() here. If the field is the reference designator and it's parent
+ // component has multiple parts, we don't want the part suffix added to the field.
+ m_canvas->SetIgnoreMouseEvents( true );
+
+ wxString title;
+ title.Printf( _( "Edit %s Field" ), GetChars( aField->GetName() ) );
+
+ DIALOG_SCH_EDIT_ONE_FIELD dlg( this, title, aField );
+
+ // The dialog may invoke a kiway player for footprint fields
+ // so we must use a quasimodal
+ if( dlg.ShowQuasiModal() != wxID_OK )
+ {
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+ return;
+ }
+
+ dlg.UpdateField( aField, m_CurrentSheet );
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+ OnModify();
+
+ m_canvas->Refresh();
+
+ MSG_PANEL_ITEMS items;
+ component->SetCurrentSheetPath( &GetCurrentSheet() );
+ component->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+}
+
+
+void SCH_EDIT_FRAME::RotateField( SCH_FIELD* aField, wxDC* aDC )
+{
+ wxCHECK_RET( aField != NULL && aField->Type() == SCH_FIELD_T && !aField->GetText().IsEmpty(),
+ wxT( "Cannot rotate invalid schematic field." ) );
+
+ SCH_COMPONENT* component = (SCH_COMPONENT*) aField->GetParent();
+
+ // Save old component in undo list if not already in edit, or moving.
+ if( aField->GetFlags() == 0 )
+ SaveCopyInUndoList( component, UR_CHANGED );
+
+ aField->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode );
+
+ if( aField->GetOrientation() == TEXT_ORIENT_HORIZ )
+ aField->SetOrientation( TEXT_ORIENT_VERT );
+ else
+ aField->SetOrientation( TEXT_ORIENT_HORIZ );
+
+ aField->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode );
+
+ OnModify();
+}
diff --git a/eeschema/edit_label.cpp b/eeschema/edit_label.cpp
new file mode 100644
index 0000000..2be1d87
--- /dev/null
+++ b/eeschema/edit_label.cpp
@@ -0,0 +1,320 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file edit_label.cpp
+ * @brief Label, global label and text creation and editing.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <base_struct.h>
+#include <drawtxt.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <schframe.h>
+#include <kicad_device_context.h>
+
+#include <general.h>
+#include <sch_text.h>
+#include <eeschema_id.h>
+
+
+static int lastGlobalLabelShape = (int) NET_INPUT;
+static int lastTextOrientation = 0;
+static bool lastTextBold = false;
+static bool lastTextItalic = false;
+
+
+void SCH_EDIT_FRAME::ChangeTextOrient( SCH_TEXT* aTextItem, wxDC* aDC )
+{
+ wxCHECK_RET( (aTextItem != NULL) && aTextItem->CanIncrementLabel(),
+ wxT( "Invalid schematic text item." ) );
+
+ int orient = ( aTextItem->GetOrientation() + 1 ) & 3;
+
+ // Save current text orientation in undo list if is not already in edit.
+ if( aTextItem->GetFlags() == 0 )
+ SaveCopyInUndoList( aTextItem, UR_CHANGED );
+
+ m_canvas->CrossHairOff( aDC );
+ aTextItem->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode );
+ aTextItem->SetOrientation( orient );
+ OnModify();
+ aTextItem->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode );
+ m_canvas->CrossHairOn( aDC );
+}
+
+
+SCH_TEXT* SCH_EDIT_FRAME::CreateNewText( wxDC* aDC, int aType )
+{
+ SCH_TEXT* textItem = NULL;
+
+ SetRepeatItem( NULL );
+
+ switch( aType )
+ {
+ case LAYER_NOTES:
+ textItem = new SCH_TEXT( GetCrossHairPosition() );
+ break;
+
+ case LAYER_LOCLABEL:
+ textItem = new SCH_LABEL( GetCrossHairPosition() );
+ break;
+
+ case LAYER_HIERLABEL:
+ textItem = new SCH_HIERLABEL( GetCrossHairPosition() );
+ textItem->SetShape( lastGlobalLabelShape );
+ break;
+
+ case LAYER_GLOBLABEL:
+ textItem = new SCH_GLOBALLABEL( GetCrossHairPosition() );
+ textItem->SetShape( lastGlobalLabelShape );
+ break;
+
+ default:
+ DisplayError( this, wxT( "SCH_EDIT_FRAME::CreateNewText() Internal error" ) );
+ return NULL;
+ }
+
+ textItem->SetBold( lastTextBold );
+ textItem->SetItalic( lastTextItalic );
+ textItem->SetOrientation( lastTextOrientation );
+ textItem->SetSize( wxSize( GetDefaultTextSize(), GetDefaultTextSize() ) );
+ textItem->SetFlags( IS_NEW | IS_MOVED );
+
+ EditSchematicText( textItem );
+
+ if( textItem->GetText().IsEmpty() )
+ {
+ delete textItem;
+ return NULL;
+ }
+
+ lastTextBold = textItem->IsBold();
+ lastTextItalic = textItem->IsItalic();
+ lastTextOrientation = textItem->GetOrientation();
+
+ if( ( textItem->Type() == SCH_GLOBAL_LABEL_T ) ||
+ ( textItem->Type() == SCH_HIERARCHICAL_LABEL_T ) )
+ {
+ lastGlobalLabelShape = textItem->GetShape();
+ }
+
+ // Prepare display to move the new item
+ textItem->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode );
+ PrepareMoveItem( (SCH_ITEM*) textItem, aDC );
+
+ return textItem;
+}
+
+
+/*
+ * OnConvertTextType is a command event handler to change a text type to an other one.
+ * The new text, label, hierarchical label, or global label is created from the old text
+ * The old text is deleted.
+ * A tricky case is when the 'old" text is being edited (i.e. moving)
+ * because we must create a new text, and prepare the undo/redo command data for this
+ * change and the current move/edit command
+ */
+void SCH_EDIT_FRAME::OnConvertTextType( wxCommandEvent& aEvent )
+{
+ SCH_SCREEN* screen = GetScreen();
+ SCH_TEXT* text = (SCH_TEXT*) screen->GetCurItem();
+
+ wxCHECK_RET( (text != NULL) && text->CanIncrementLabel(),
+ wxT( "Cannot convert text type." ) );
+
+ KICAD_T type;
+
+ switch( aEvent.GetId() )
+ {
+ case ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_LABEL:
+ type = SCH_LABEL_T;
+ break;
+
+ case ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_GLABEL:
+ type = SCH_GLOBAL_LABEL_T;
+ break;
+
+ case ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_HLABEL:
+ type = SCH_HIERARCHICAL_LABEL_T;
+ break;
+
+ case ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT:
+ type = SCH_TEXT_T;
+ break;
+
+ default:
+ wxFAIL_MSG( wxString::Format( wxT( "Invalid text type command ID %d." ),
+ aEvent.GetId() ) );
+ return;
+ }
+
+ if( text->Type() == type )
+ return;
+
+ SCH_TEXT* newtext;
+ const wxPoint &position = text->GetPosition();
+ const wxString &txt = text->GetText();
+
+ switch( type )
+ {
+ case SCH_LABEL_T:
+ newtext = new SCH_LABEL( position, txt );
+ break;
+
+ case SCH_GLOBAL_LABEL_T:
+ newtext = new SCH_GLOBALLABEL( position, txt );
+ break;
+
+ case SCH_HIERARCHICAL_LABEL_T:
+ newtext = new SCH_HIERLABEL( position, txt );
+ break;
+
+ case SCH_TEXT_T:
+ newtext = new SCH_TEXT( position, txt );
+ break;
+
+ default:
+ newtext = NULL;
+ wxFAIL_MSG( wxString::Format( wxT( "Cannot convert text type to %d" ), type ) );
+ return;
+ }
+
+ /* Copy the old text item settings to the new one. Justifications are not copied because
+ * they are not used in labels. Justifications will be set to default value in the new
+ * text item type.
+ */
+ newtext->SetFlags( text->GetFlags() );
+ newtext->SetShape( text->GetShape() );
+ newtext->SetOrientation( text->GetOrientation() );
+ newtext->SetSize( text->GetSize() );
+ newtext->SetThickness( text->GetThickness() );
+ newtext->SetItalic( text->IsItalic() );
+ newtext->SetBold( text->IsBold() );
+
+ /* Save the new text in undo list if the old text was not itself a "new created text"
+ * In this case, the old text is already in undo list as a deleted item.
+ * Of course if the old text was a "new created text" the new text will be
+ * put in undo list later, at the end of the current command (if not aborted)
+ */
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+ m_canvas->CrossHairOff( &dc ); // Erase schematic cursor
+ text->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode );
+
+ // For an exiting item (i.e. already in list):
+ // replace the existing item by the new text in list
+ for( SCH_ITEM* item = screen->GetDrawItems(); item != NULL; item = item->Next() )
+ {
+ if( item == text )
+ {
+ screen->Remove( text );
+ screen->Append( newtext );
+ break;
+ }
+ }
+
+ SetRepeatItem( NULL );
+ OnModify();
+ newtext->Draw( m_canvas, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+ m_canvas->CrossHairOn( &dc ); // redraw schematic cursor
+
+ // if the old item is the current schematic item, replace it by the new text:
+ if( screen->GetCurItem() == text )
+ screen->SetCurItem( newtext );
+
+ if( text->IsNew() )
+ {
+ // if the previous text is new, no undo command to prepare here
+ // just delete this previous text.
+ delete text;
+ return;
+ }
+
+ // previous text is not new and we replace text by new text.
+ // So this is equivalent to delete text and add newtext
+ // If text if being currently edited (i.e. moved)
+ // we also save the initial copy of text, and prepare undo command for new text modifications.
+ // we must save it as modified text,if it is currently edited, then save as deleted text,
+ // and replace text with newtext
+ PICKED_ITEMS_LIST pickList;
+ ITEM_PICKER picker( text, UR_CHANGED );
+
+ if( text->GetFlags() )
+ {
+ // text is being edited, save initial text for undo command
+ picker.SetLink( GetUndoItem() );
+ pickList.PushItem( picker );
+
+ // the owner of undoItem is no more "this", it is now "picker":
+ SetUndoItem( NULL );
+
+ // save current newtext copy for undo/abort current command
+ SetUndoItem( newtext );
+ }
+
+ // Prepare undo command for delete old text
+ picker.SetStatus( UR_DELETED );
+ picker.SetLink( NULL );
+ pickList.PushItem( picker );
+
+ // Prepare undo command for new text
+ picker.SetStatus( UR_NEW );
+ picker.SetItem(newtext);
+ pickList.PushItem( picker );
+
+ SaveCopyInUndoList( pickList, UR_UNSPECIFIED );
+}
+
+
+/* Function to increment bus label members numbers,
+ * i.e. when a text is ending with a number, adds
+ * aIncrement to this number
+ */
+void IncrementLabelMember( wxString& name, int aIncrement )
+{
+ int ii, nn;
+ long number = 0;
+
+ ii = name.Len() - 1; nn = 0;
+
+ if( !isdigit( name.GetChar( ii ) ) )
+ return;
+
+ while( (ii >= 0) && isdigit( name.GetChar( ii ) ) )
+ {
+ ii--; nn++;
+ }
+
+ ii++; /* digits are starting at ii position */
+ wxString litt_number = name.Right( nn );
+
+ if( litt_number.ToLong( &number ) )
+ {
+ number += aIncrement;
+ name.Remove( ii ); name << number;
+ }
+}
diff --git a/eeschema/eeredraw.cpp b/eeschema/eeredraw.cpp
new file mode 100644
index 0000000..7f0899d
--- /dev/null
+++ b/eeschema/eeredraw.cpp
@@ -0,0 +1,86 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2006 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2009-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeredraw.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <schframe.h>
+#include <general.h>
+
+
+void DrawDanglingSymbol( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& pos, EDA_COLOR_T Color )
+{
+ BASE_SCREEN* screen = panel->GetScreen();
+
+ if( !screen->m_IsPrinting ) /* Draw but do not print the Dangling Symbol */
+ {
+ GRRect( panel->GetClipBox(), DC,
+ pos.x - DANGLING_SYMBOL_SIZE, pos.y - DANGLING_SYMBOL_SIZE,
+ pos.x + DANGLING_SYMBOL_SIZE, pos.y + DANGLING_SYMBOL_SIZE,
+ 0, Color );
+ }
+}
+
+
+/*
+ * Redraws only the active window which is assumed to be whole visible.
+ */
+void SCH_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
+{
+ if( GetScreen() == NULL )
+ return;
+
+ m_canvas->DrawBackGround( DC );
+
+ GetScreen()->Draw( m_canvas, DC, GR_DEFAULT_DRAWMODE );
+
+ DrawWorkSheet( DC, GetScreen(), GetDefaultLineThickness(), IU_PER_MILS,
+ GetScreen()->GetFileName() );
+
+#ifdef USE_WX_OVERLAY
+ if( IsShown() )
+ {
+ m_overlay.Reset();
+ wxDCOverlay overlaydc( m_overlay, (wxWindowDC*)DC );
+ overlaydc.Clear();
+ /* TODO: Investigate why toolbars are affected - to be searched in wxWidgets */
+ m_mainToolBar->Refresh();
+ m_drawToolBar->Refresh();
+ m_optionsToolBar->Refresh();
+ }
+#endif
+
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ m_canvas->DrawCrossHair( DC );
+
+ // Display the sheet filename, and the sheet path, for non root sheets
+ UpdateTitle();
+}
diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp
new file mode 100644
index 0000000..cfc062a
--- /dev/null
+++ b/eeschema/eeschema.cpp
@@ -0,0 +1,242 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema.cpp
+ * @brief the main file
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <class_drawpanel.h>
+#include <gestfich.h>
+#include <eda_dde.h>
+#include <schframe.h>
+#include <libeditframe.h>
+#include <viewlib_frame.h>
+#include <eda_text.h>
+
+#include <general.h>
+#include <class_libentry.h>
+#include <hotkeys.h>
+#include <dialogs/dialog_color_config.h>
+#include <transform.h>
+#include <wildcards_and_files_ext.h>
+
+#include <kiway.h>
+
+// The main sheet of the project
+SCH_SHEET* g_RootSheet = NULL;
+
+// a transform matrix, to display components in lib editor
+TRANSFORM DefaultTransform = TRANSFORM( 1, 0, 0, -1 );
+
+
+namespace SCH {
+
+static struct IFACE : public KIFACE_I
+{
+ // Of course all are virtual overloads, implementations of the KIFACE.
+
+ IFACE( const char* aName, KIWAY::FACE_T aType ) :
+ KIFACE_I( aName, aType )
+ {}
+
+ bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits );
+
+ void OnKifaceEnd();
+
+ wxWindow* CreateWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 )
+ {
+ switch( aClassId )
+ {
+ case FRAME_SCH:
+ {
+ SCH_EDIT_FRAME* frame = new SCH_EDIT_FRAME( aKiway, aParent );
+
+ if( Kiface().IsSingle() )
+ {
+ // only run this under single_top, not under a project manager.
+ CreateServer( frame, KICAD_SCH_PORT_SERVICE_NUMBER );
+ }
+ return frame;
+ }
+ break;
+
+ case FRAME_SCH_LIB_EDITOR:
+ {
+ LIB_EDIT_FRAME* frame = new LIB_EDIT_FRAME( aKiway, aParent );
+ return frame;
+ }
+ break;
+
+
+ case FRAME_SCH_VIEWER:
+ case FRAME_SCH_VIEWER_MODAL:
+ {
+ LIB_VIEW_FRAME* frame = new LIB_VIEW_FRAME( aKiway, aParent, FRAME_T( aClassId ) );
+ return frame;
+ }
+ break;
+
+ default:
+ return NULL;
+ }
+ }
+
+ /**
+ * Function IfaceOrAddress
+ * return a pointer to the requested object. The safest way to use this
+ * is to retrieve a pointer to a static instance of an interface, similar to
+ * how the KIFACE interface is exported. But if you know what you are doing
+ * use it to retrieve anything you want.
+ *
+ * @param aDataId identifies which object you want the address of.
+ *
+ * @return void* - and must be cast into the know type.
+ */
+ void* IfaceOrAddress( int aDataId )
+ {
+ return NULL;
+ }
+
+} kiface( "eeschema", KIWAY::FACE_SCH );
+
+} // namespace
+
+using namespace SCH;
+
+static PGM_BASE* process;
+
+
+KIFACE_I& Kiface() { return kiface; }
+
+
+// KIFACE_GETTER's actual spelling is a substitution macro found in kiway.h.
+// KIFACE_GETTER will not have name mangling due to declaration in kiway.h.
+MY_API( KIFACE* ) KIFACE_GETTER( int* aKIFACEversion, int aKiwayVersion, PGM_BASE* aProgram )
+{
+ process = aProgram;
+ return &kiface;
+}
+
+
+PGM_BASE& Pgm()
+{
+ wxASSERT( process ); // KIFACE_GETTER has already been called.
+ return *process;
+}
+
+
+static EDA_COLOR_T s_layerColor[LAYERSCH_ID_COUNT];
+
+EDA_COLOR_T GetLayerColor( LAYERSCH_ID aLayer )
+{
+ wxASSERT( unsigned( aLayer ) < DIM( s_layerColor ) );
+ return s_layerColor[aLayer];
+}
+
+void SetLayerColor( EDA_COLOR_T aColor, LAYERSCH_ID aLayer )
+{
+ wxASSERT( unsigned( aLayer ) < DIM( s_layerColor ) );
+ s_layerColor[aLayer] = aColor;
+}
+
+
+static PARAM_CFG_ARRAY& cfg_params()
+{
+ static PARAM_CFG_ARRAY ca;
+
+ if( !ca.size() )
+ {
+ // These are KIFACE specific, they need to be loaded once when the
+ // eeschema KIFACE comes in.
+
+#define CLR(x, y, z)\
+ ca.push_back( new PARAM_CFG_SETCOLOR( true, wxT( x ), &s_layerColor[y], z ) );
+
+ CLR( "ColorWireEx", LAYER_WIRE, GREEN )
+ CLR( "ColorBusEx", LAYER_BUS, BLUE )
+ CLR( "ColorConnEx", LAYER_JUNCTION, GREEN )
+ CLR( "ColorLLabelEx", LAYER_LOCLABEL, BLACK )
+ CLR( "ColorHLabelEx", LAYER_HIERLABEL, BROWN )
+ CLR( "ColorGLabelEx", LAYER_GLOBLABEL, RED )
+ CLR( "ColorPinNumEx", LAYER_PINNUM, RED )
+ CLR( "ColorPinNameEx", LAYER_PINNAM, CYAN )
+ CLR( "ColorFieldEx", LAYER_FIELDS, MAGENTA )
+ CLR( "ColorReferenceEx", LAYER_REFERENCEPART, CYAN )
+ CLR( "ColorValueEx", LAYER_VALUEPART, CYAN )
+ CLR( "ColorNoteEx", LAYER_NOTES, LIGHTBLUE )
+ CLR( "ColorBodyEx", LAYER_DEVICE, RED )
+ CLR( "ColorBodyBgEx", LAYER_DEVICE_BACKGROUND,LIGHTYELLOW )
+ CLR( "ColorNetNameEx", LAYER_NETNAM, DARKGRAY )
+ CLR( "ColorPinEx", LAYER_PIN, RED )
+ CLR( "ColorSheetEx", LAYER_SHEET, MAGENTA )
+ CLR( "ColorSheetFileNameEx", LAYER_SHEETFILENAME, BROWN )
+ CLR( "ColorSheetNameEx", LAYER_SHEETNAME, CYAN )
+ CLR( "ColorSheetLabelEx", LAYER_SHEETLABEL, BROWN )
+ CLR( "ColorNoConnectEx", LAYER_NOCONNECT, BLUE )
+ CLR( "ColorErcWEx", LAYER_ERC_WARN, GREEN )
+ CLR( "ColorErcEEx", LAYER_ERC_ERR, RED )
+ CLR( "ColorGridEx", LAYER_GRID, DARKGRAY )
+ CLR( "ColorBgCanvasEx", LAYER_BACKGROUND, WHITE )
+ }
+
+ return ca;
+}
+
+
+bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
+{
+ // This is process level, not project level, initialization of the DSO.
+
+ // Do nothing in here pertinent to a project!
+
+ start_common( aCtlBits );
+
+ // Give a default colour for all layers
+ // (actual color will be initialized by config)
+ for( LAYERSCH_ID ii = LAYER_FIRST; ii < LAYERSCH_ID_COUNT; ++ii )
+ SetLayerColor( DARKGRAY, ii );
+
+ SetLayerColor( WHITE, LAYER_BACKGROUND );
+
+ // Must be called before creating the main frame in order to
+ // display the real hotkeys in menus or tool tips
+ ReadHotkeyConfig( SCH_EDIT_FRAME_NAME, g_Eeschema_Hokeys_Descr );
+
+ wxConfigLoadSetups( KifaceSettings(), cfg_params() );
+
+ return true;
+}
+
+
+void IFACE::OnKifaceEnd()
+{
+ wxConfigSaveSetups( KifaceSettings(), cfg_params() );
+ end_common();
+}
+
diff --git a/eeschema/eeschema.icns b/eeschema/eeschema.icns
new file mode 100644
index 0000000..ca5e9d2
--- /dev/null
+++ b/eeschema/eeschema.icns
Binary files differ
diff --git a/eeschema/eeschema.rc b/eeschema/eeschema.rc
new file mode 100644
index 0000000..6c12ddd
--- /dev/null
+++ b/eeschema/eeschema.rc
@@ -0,0 +1,3 @@
+icon_eeschema ICON "../bitmaps_png/icons/icon_eeschema.ico"
+
+#include "wx/msw/wx.rc"
diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp
new file mode 100644
index 0000000..c2aeaeb
--- /dev/null
+++ b/eeschema/eeschema_config.cpp
@@ -0,0 +1,810 @@
+/**
+ * @file eeschema_config.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014-2016 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <schframe.h>
+#include <invoke_sch_dialog.h>
+#include <common.h>
+
+#include <eeschema_id.h>
+#include <general.h>
+#include <libeditframe.h>
+#include <eeschema_config.h>
+#include <hotkeys.h>
+#include <sch_sheet.h>
+#include <class_libentry.h>
+#include <worksheet_shape_builder.h>
+#include <class_library.h>
+
+#include <dialog_hotkeys_editor.h>
+
+#include <dialogs/dialog_color_config.h>
+#include <dialogs/dialog_eeschema_options.h>
+#include <dialogs/dialog_libedit_options.h>
+#include <dialogs/dialog_schematic_find.h>
+
+#include <wildcards_and_files_ext.h>
+
+#define FR_HISTORY_LIST_CNT 10 ///< Maximum number of find and replace strings.
+
+
+static int s_defaultBusThickness = DEFAULTBUSTHICKNESS;
+
+int GetDefaultBusThickness()
+{
+ return s_defaultBusThickness;
+}
+
+
+void SetDefaultBusThickness( int aThickness)
+{
+ if( aThickness >= 1 )
+ s_defaultBusThickness = aThickness;
+ else
+ s_defaultBusThickness = 1;
+}
+
+
+/// Default size for text (not only labels)
+static int s_defaultTextSize = DEFAULT_SIZE_TEXT;
+
+int GetDefaultTextSize()
+{
+ return s_defaultTextSize;
+}
+
+
+void SetDefaultTextSize( int aTextSize )
+{
+ s_defaultTextSize = aTextSize;
+}
+
+
+/*
+ * Default line (in Eeschema units) thickness used to draw/plot items having a
+ * default thickness line value (i.e. = 0 ).
+ */
+static int s_drawDefaultLineThickness = DEFAULTDRAWLINETHICKNESS;
+
+
+int GetDefaultLineThickness()
+{
+ return s_drawDefaultLineThickness;
+}
+
+
+void SetDefaultLineThickness( int aThickness )
+{
+ if( aThickness >=1 )
+ s_drawDefaultLineThickness = aThickness;
+ else
+ s_drawDefaultLineThickness = 1;
+}
+
+
+// Color to draw selected items
+EDA_COLOR_T GetItemSelectedColor()
+{
+ return BROWN;
+}
+
+
+// Color to draw items flagged invisible, in libedit (they are invisible
+// in Eeschema
+EDA_COLOR_T GetInvisibleItemColor()
+{
+ return DARKGRAY;
+}
+
+
+void LIB_EDIT_FRAME::InstallConfigFrame( wxCommandEvent& event )
+{
+ // Identical to SCH_EDIT_FRAME::InstallConfigFrame()
+
+ PROJECT* prj = &Prj();
+ wxArrayString lib_names;
+ wxString lib_paths;
+
+ try
+ {
+ PART_LIBS::LibNamesAndPaths( prj, false, &lib_paths, &lib_names );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DBG(printf( "%s: %s\n", __func__, TO_UTF8( ioe.errorText ) );)
+ return;
+ }
+
+ if( InvokeEeschemaConfig( this, &lib_paths, &lib_names ) )
+ {
+ // save the [changed] settings.
+ PART_LIBS::LibNamesAndPaths( prj, true, &lib_paths, &lib_names );
+
+ // Force a reload of the PART_LIBS
+ prj->SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL );
+ prj->SetElem( PROJECT::ELEM_SCH_SEARCH_STACK, NULL );
+ }
+}
+
+
+void LIB_EDIT_FRAME::OnColorConfig( wxCommandEvent& aEvent )
+{
+ DIALOG_COLOR_CONFIG dlg( this );
+
+ dlg.ShowModal();
+}
+
+
+void LIB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
+{
+ int id = event.GetId();
+
+ switch( id )
+ {
+ // Hotkey IDs
+ case ID_PREFERENCES_HOTKEY_SHOW_EDITOR:
+ InstallHotkeyFrame( this, g_Eeschema_Hokeys_Descr );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_EXPORT_CONFIG:
+ ExportHotkeyConfigToFile( g_Eeschema_Hokeys_Descr, wxT( "eeschema" ) );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_IMPORT_CONFIG:
+ ImportHotkeyConfigFromFile( g_Eeschema_Hokeys_Descr, wxT( "eeschema" ) );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST:
+ // Display current hotkey list for LibEdit.
+ DisplayHotkeyList( this, g_Libedit_Hokeys_Descr );
+ break;
+
+ default:
+ DisplayError( this, wxT( "LIB_EDIT_FRAME::Process_Config error" ) );
+ }
+}
+
+
+void SCH_EDIT_FRAME::OnColorConfig( wxCommandEvent& aEvent )
+{
+ DIALOG_COLOR_CONFIG dlg( this );
+
+ dlg.ShowModal();
+}
+
+
+void SCH_EDIT_FRAME::InstallConfigFrame( wxCommandEvent& event )
+{
+ // Identical to LIB_EDIT_FRAME::InstallConfigFrame()
+
+ PROJECT* prj = &Prj();
+ wxArrayString lib_names;
+ wxString lib_paths;
+
+ try
+ {
+ PART_LIBS::LibNamesAndPaths( prj, false, &lib_paths, &lib_names );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DBG(printf( "%s: %s\n", __func__, TO_UTF8( ioe.errorText ) );)
+ return;
+ }
+
+ if( InvokeEeschemaConfig( this, &lib_paths, &lib_names ) )
+ {
+ // save the [changed] settings.
+ PART_LIBS::LibNamesAndPaths( prj, true, &lib_paths, &lib_names );
+
+#if defined(DEBUG)
+ printf( "%s: lib_names:\n", __func__ );
+ for( unsigned i=0; i<lib_names.size(); ++i )
+ {
+ printf( " %s\n", TO_UTF8( lib_names[i] ) );
+ }
+
+ printf( "%s: lib_paths:'%s'\n", __func__, TO_UTF8( lib_paths ) );
+#endif
+
+ // Force a reload of the PART_LIBS
+ prj->SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL );
+ prj->SetElem( PROJECT::ELEM_SCH_SEARCH_STACK, NULL );
+ }
+}
+
+
+void SCH_EDIT_FRAME::Process_Config( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ wxFileName fn;
+
+ switch( id )
+ {
+ case ID_CONFIG_SAVE:
+ SaveProjectSettings( true );
+ break;
+
+ case ID_CONFIG_READ:
+ {
+ fn = g_RootSheet->GetScreen()->GetFileName();
+ fn.SetExt( ProjectFileExtension );
+
+ wxFileDialog dlg( this, _( "Read Project File" ), fn.GetPath(),
+ fn.GetFullName(), ProjectFileWildcard,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ break;
+
+ wxString chosen = dlg.GetPath();
+
+ if( chosen == Prj().GetProjectFullName() )
+ LoadProjectFile();
+ else
+ {
+ // Read library list and library path list
+ Prj().ConfigLoad( Kiface().KifaceSearch(), GROUP_SCH, GetProjectFileParametersList() );
+ // Read schematic editor setup
+ Prj().ConfigLoad( Kiface().KifaceSearch(), GROUP_SCH_EDITOR, GetProjectFileParametersList() );
+ }
+ }
+ break;
+
+ // Hotkey IDs
+ case ID_PREFERENCES_HOTKEY_EXPORT_CONFIG:
+ ExportHotkeyConfigToFile( g_Eeschema_Hokeys_Descr, wxT( "eeschema" ) );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_IMPORT_CONFIG:
+ ImportHotkeyConfigFromFile( g_Eeschema_Hokeys_Descr, wxT( "eeschema" ) );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_SHOW_EDITOR:
+ InstallHotkeyFrame( this, g_Eeschema_Hokeys_Descr );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST:
+ // Display current hotkey list for eeschema.
+ DisplayHotkeyList( this, g_Schematic_Hokeys_Descr );
+ break;
+
+ default:
+ DisplayError( this, wxT( "SCH_EDIT_FRAME::Process_Config error" ) );
+ }
+}
+
+
+void SCH_EDIT_FRAME::OnPreferencesOptions( wxCommandEvent& event )
+{
+ wxArrayString units;
+ GRIDS grid_list = GetScreen()->GetGrids();
+ bool saveProjectConfig = false;
+
+ DIALOG_EESCHEMA_OPTIONS dlg( this );
+
+ units.Add( GetUnitsLabel( INCHES ) );
+ units.Add( GetUnitsLabel( MILLIMETRES ) );
+
+ dlg.SetUnits( units, g_UserUnit );
+ dlg.SetGridSizes( grid_list, GetScreen()->GetGridCmdId() );
+ dlg.SetBusWidth( GetDefaultBusThickness() );
+ dlg.SetLineWidth( GetDefaultLineThickness() );
+ dlg.SetTextSize( GetDefaultTextSize() );
+ dlg.SetRepeatHorizontal( GetRepeatStep().x );
+ dlg.SetRepeatVertical( GetRepeatStep().y );
+ dlg.SetRepeatLabel( GetRepeatDeltaLabel() );
+ dlg.SetAutoSaveInterval( GetAutoSaveInterval() / 60 );
+ dlg.SetMaxUndoItems( GetScreen()->GetMaxUndoItems() );
+ dlg.SetRefIdSeparator( LIB_PART::GetSubpartIdSeparator(),
+ LIB_PART::GetSubpartFirstId() );
+
+ dlg.SetShowGrid( IsGridVisible() );
+ dlg.SetShowHiddenPins( m_showAllPins );
+ dlg.SetEnableMiddleButtonPan( m_canvas->GetEnableMiddleButtonPan() );
+ dlg.SetEnableMousewheelPan( m_canvas->GetEnableMousewheelPan() );
+ dlg.SetEnableZoomNoCenter( m_canvas->GetEnableZoomNoCenter() );
+ dlg.SetMiddleButtonPanLimited( m_canvas->GetMiddleButtonPanLimited() );
+ dlg.SetEnableAutoPan( m_canvas->GetEnableAutoPan() );
+ dlg.SetEnableHVBusOrientation( GetForceHVLines() );
+ dlg.SetShowPageLimits( m_showPageLimits );
+ dlg.Layout();
+ dlg.Fit();
+ dlg.SetMinSize( dlg.GetSize() );
+ dlg.SetTemplateFields( m_TemplateFieldNames.GetTemplateFieldNames() );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ g_UserUnit = (EDA_UNITS_T)dlg.GetUnitsSelection();
+
+ wxRealPoint gridsize = grid_list[ (size_t) dlg.GetGridSelection() ].m_Size;
+ m_LastGridSizeId = GetScreen()->SetGrid( gridsize );
+
+ int sep, firstId;
+ dlg.GetRefIdSeparator( sep, firstId);
+
+ if( sep != (int)LIB_PART::GetSubpartIdSeparator() ||
+ firstId != (int)LIB_PART::GetSubpartFirstId() )
+ {
+ LIB_PART::SetSubpartIdNotation( sep, firstId );
+ saveProjectConfig = true;
+ }
+
+ SetDefaultBusThickness( dlg.GetBusWidth() );
+ SetDefaultLineThickness( dlg.GetLineWidth() );
+
+ if( dlg.GetTextSize() != GetDefaultTextSize() )
+ {
+ SetDefaultTextSize( dlg.GetTextSize() );
+ saveProjectConfig = true;
+ }
+
+ wxPoint step;
+ step.x = dlg.GetRepeatHorizontal();
+ step.y = dlg.GetRepeatVertical();
+ SetRepeatStep( step );
+ SetRepeatDeltaLabel( dlg.GetRepeatLabel() );
+
+ SetAutoSaveInterval( dlg.GetAutoSaveInterval() * 60 );
+ GetScreen()->SetMaxUndoItems( dlg.GetMaxUndoItems() );
+ SetGridVisibility( dlg.GetShowGrid() );
+ m_showAllPins = dlg.GetShowHiddenPins();
+ m_canvas->SetEnableMiddleButtonPan( dlg.GetEnableMiddleButtonPan() );
+ m_canvas->SetEnableMousewheelPan( dlg.GetEnableMousewheelPan() );
+ m_canvas->SetEnableZoomNoCenter( dlg.GetEnableZoomNoCenter() );
+ m_canvas->SetMiddleButtonPanLimited( dlg.GetMiddleButtonPanLimited() );
+ m_canvas->SetEnableAutoPan( dlg.GetEnableAutoPan() );
+ SetForceHVLines( dlg.GetEnableHVBusOrientation() );
+ m_showPageLimits = dlg.GetShowPageLimits();
+
+ // Delete all template fieldnames and then restore them using the template field data from
+ // the options dialog
+ DeleteAllTemplateFieldNames();
+ TEMPLATE_FIELDNAMES newFieldNames = dlg.GetTemplateFields();
+
+ for( TEMPLATE_FIELDNAMES::iterator dlgfld = newFieldNames.begin();
+ dlgfld != newFieldNames.end(); ++dlgfld )
+ {
+ TEMPLATE_FIELDNAME fld = *dlgfld;
+ AddTemplateFieldName( fld );
+ }
+
+ SaveSettings( config() ); // save values shared by eeschema applications.
+
+ if( saveProjectConfig )
+ SaveProjectSettings( true );
+
+ m_canvas->Refresh( true );
+}
+
+
+PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetProjectFileParametersList()
+{
+ if( !m_projectFileParams.empty() )
+ return m_projectFileParams;
+
+ m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "PageLayoutDescrFile" ),
+ &BASE_SCREEN::m_PageLayoutDescrFileName ) );
+
+ m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "PlotDirectoryName" ),
+ &m_plotDirectoryName ) );
+
+ m_projectFileParams.push_back( new PARAM_CFG_INT( wxT( "SubpartIdSeparator" ),
+ LIB_PART::SubpartIdSeparatorPtr(),
+ 0, 0, 126 ) );
+ m_projectFileParams.push_back( new PARAM_CFG_INT( wxT( "SubpartFirstId" ),
+ LIB_PART::SubpartFirstIdPtr(),
+ 'A', '1', 'z' ) );
+
+ /* moved to library load/save specific code, in a specific section in .pro file
+ m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "LibDir" ),
+ &m_userLibraryPath ) );
+ m_projectFileParams.push_back( new PARAM_CFG_LIBNAME_LIST( wxT( "LibName" ),
+ &m_componentLibFiles,
+ GROUP_SCH_LIBS ) );
+ */
+
+ m_projectFileParams.push_back( new PARAM_CFG_WXSTRING( wxT( "NetFmtName" ),
+ &m_netListFormat) );
+ m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "SpiceForceRefPrefix" ),
+ &m_spiceNetlistAddReferencePrefix, false ) );
+ m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "SpiceUseNetNumbers" ),
+ &m_spiceNetlistUseNetcodeAsNetname, false ) );
+
+ m_projectFileParams.push_back( new PARAM_CFG_INT( wxT( "LabSize" ),
+ &s_defaultTextSize,
+ DEFAULT_SIZE_TEXT, 5,
+ 1000 ) );
+
+ return m_projectFileParams;
+}
+
+
+bool SCH_EDIT_FRAME::LoadProjectFile()
+{
+ // Read library list and library path list
+ bool isRead = Prj().ConfigLoad( Kiface().KifaceSearch(),
+ GROUP_SCH, GetProjectFileParametersList() );
+
+ // Read schematic editor setup
+ isRead = isRead && Prj().ConfigLoad( Kiface().KifaceSearch(),
+ GROUP_SCH_EDITOR, GetProjectFileParametersList() );
+
+ // Verify some values, because the config file can be edited by hand,
+ // and have bad values:
+ LIB_PART::SetSubpartIdNotation(
+ LIB_PART::GetSubpartIdSeparator(),
+ LIB_PART::GetSubpartFirstId() );
+
+ // Load the page layout decr file, from the filename stored in
+ // BASE_SCREEN::m_PageLayoutDescrFileName, read in config project file
+ // If empty, or not existing, the default descr is loaded
+ WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
+ wxString pg_fullfilename = WORKSHEET_LAYOUT::MakeFullFileName(
+ BASE_SCREEN::m_PageLayoutDescrFileName,
+ Prj().GetProjectPath() );
+
+ pglayout.SetPageLayout( pg_fullfilename );
+
+ return isRead;
+}
+
+
+void SCH_EDIT_FRAME::SaveProjectSettings( bool aAskForSave )
+{
+ PROJECT& prj = Prj();
+ wxFileName fn = g_RootSheet->GetScreen()->GetFileName(); //ConfigFileName
+
+ fn.SetExt( ProjectFileExtension );
+
+ if( !IsWritable( fn ) )
+ return;
+
+ if( aAskForSave )
+ {
+ wxFileDialog dlg( this, _( "Save Project File" ),
+ fn.GetPath(), fn.GetFullName(),
+ ProjectFileWildcard, wxFD_SAVE );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ fn = dlg.GetPath();
+ }
+
+ prj.ConfigSave( Kiface().KifaceSearch(), GROUP_SCH_EDITOR, GetProjectFileParametersList() );
+}
+
+
+static const wxChar DefaultBusWidthEntry[] = wxT( "DefaultBusWidth" );
+static const wxChar DefaultDrawLineWidthEntry[] = wxT( "DefaultDrawLineWidth" );
+static const wxChar ShowHiddenPinsEntry[] = wxT( "ShowHiddenPins" );
+static const wxChar HorzVertLinesOnlyEntry[] = wxT( "HorizVertLinesOnly" );
+static const wxChar PreviewFramePositionXEntry[] = wxT( "PreviewFramePositionX" );
+static const wxChar PreviewFramePositionYEntry[] = wxT( "PreviewFramePositionY" );
+static const wxChar PreviewFrameWidthEntry[] = wxT( "PreviewFrameWidth" );
+static const wxChar PreviewFrameHeightEntry[] = wxT( "PreviewFrameHeight" );
+static const wxChar PrintDialogPositionXEntry[] = wxT( "PrintDialogPositionX" );
+static const wxChar PrintDialogPositionYEntry[] = wxT( "PrintDialogPositionY" );
+static const wxChar PrintDialogWidthEntry[] = wxT( "PrintDialogWidth" );
+static const wxChar PrintDialogHeightEntry[] = wxT( "PrintDialogHeight" );
+static const wxChar FindDialogPositionXEntry[] = wxT( "FindDialogPositionX" );
+static const wxChar FindDialogPositionYEntry[] = wxT( "FindDialogPositionY" );
+static const wxChar FindDialogWidthEntry[] = wxT( "FindDialogWidth" );
+static const wxChar FindDialogHeightEntry[] = wxT( "FindDialogHeight" );
+static const wxChar FindReplaceFlagsEntry[] = wxT( "LastFindReplaceFlags" );
+static const wxChar FindStringEntry[] = wxT( "LastFindString" );
+static const wxChar ReplaceStringEntry[] = wxT( "LastReplaceString" );
+static const wxChar FindStringHistoryEntry[] = wxT( "FindStringHistoryList%d" );
+static const wxChar ReplaceStringHistoryEntry[] = wxT( "ReplaceStringHistoryList%d" );
+static const wxChar FieldNamesEntry[] = wxT( "FieldNames" );
+static const wxChar SimulatorCommandEntry[] = wxT( "SimCmdLine" );
+
+// Library editor wxConfig entry names.
+static const wxChar lastLibExportPathEntry[] = wxT( "LastLibraryExportPath" );
+static const wxChar lastLibImportPathEntry[] = wxT( "LastLibraryImportPath" );
+static const wxChar defaultPinNumSizeEntry[] = wxT( "LibeditPinNumSize" );
+static const wxChar defaultPinNameSizeEntry[] = wxT( "LibeditPinNameSize" );
+static const wxChar DefaultPinLengthEntry[] = wxT( "DefaultPinLength" );
+static const wxChar repeatLibLabelIncEntry[] = wxT( "LibeditRepeatLabelInc" );
+static const wxChar pinRepeatStepEntry[] = wxT( "LibeditPinRepeatStep" );
+static const wxChar repeatLibStepXEntry[] = wxT( "LibeditRepeatStepX" );
+static const wxChar repeatLibStepYEntry[] = wxT( "LibeditRepeatStepY" );
+
+
+PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetConfigurationSettings()
+{
+ if( !m_configSettings.empty() )
+ return m_configSettings;
+
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "ShowPageLimits" ),
+ &m_showPageLimits, true ) );
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "Units" ),
+ (int*)&g_UserUnit, MILLIMETRES ) );
+
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "PrintMonochrome" ),
+ &m_printMonochrome, true ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "PrintSheetReferenceAndTitleBlock" ),
+ &m_printSheetReference, true ) );
+
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "RepeatStepX" ),
+ &m_repeatStep.x,
+ DEFAULT_REPEAT_OFFSET_X,
+ -REPEAT_OFFSET_MAX,
+ REPEAT_OFFSET_MAX ) );
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "RepeatStepY" ),
+ &m_repeatStep.y,
+ DEFAULT_REPEAT_OFFSET_Y,
+ -REPEAT_OFFSET_MAX,
+ REPEAT_OFFSET_MAX ) );
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "RepeatLabelIncrement" ),
+ &m_repeatDeltaLabel,
+ DEFAULT_REPEAT_LABEL_INC, -10, +10 ) );
+ return m_configSettings;
+}
+
+
+void SCH_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::LoadSettings( aCfg );
+
+ long tmp;
+
+ wxConfigLoadSetups( aCfg, GetConfigurationSettings() );
+
+ SetGridColor( GetLayerColor( LAYER_GRID ) );
+ SetDrawBgColor( GetLayerColor( LAYER_BACKGROUND ) );
+
+ SetDefaultBusThickness( aCfg->Read( DefaultBusWidthEntry, DEFAULTBUSTHICKNESS ) );
+ SetDefaultLineThickness( aCfg->Read( DefaultDrawLineWidthEntry, DEFAULTDRAWLINETHICKNESS ) );
+ aCfg->Read( ShowHiddenPinsEntry, &m_showAllPins, false );
+ aCfg->Read( HorzVertLinesOnlyEntry, &m_forceHVLines, true );
+
+ // Load print preview window session settings.
+ aCfg->Read( PreviewFramePositionXEntry, &tmp, -1 );
+ m_previewPosition.x = (int) tmp;
+ aCfg->Read( PreviewFramePositionYEntry, &tmp, -1 );
+ m_previewPosition.y = (int) tmp;
+ aCfg->Read( PreviewFrameWidthEntry, &tmp, -1 );
+ m_previewSize.SetWidth( (int) tmp );
+ aCfg->Read( PreviewFrameHeightEntry, &tmp, -1 );
+ m_previewSize.SetHeight( (int) tmp );
+
+ // Load print dialog session settings.
+ aCfg->Read( PrintDialogPositionXEntry, &tmp, -1 );
+ m_printDialogPosition.x = (int) tmp;
+ aCfg->Read( PrintDialogPositionYEntry, &tmp, -1 );
+ m_printDialogPosition.y = (int) tmp;
+ aCfg->Read( PrintDialogWidthEntry, &tmp, -1 );
+ m_printDialogSize.SetWidth( (int) tmp );
+ aCfg->Read( PrintDialogHeightEntry, &tmp, -1 );
+ m_printDialogSize.SetHeight( (int) tmp );
+
+ // Load netlists options:
+ aCfg->Read( SimulatorCommandEntry, &m_simulatorCommand );
+
+ // Load find dialog session setting.
+ aCfg->Read( FindDialogPositionXEntry, &tmp, -1 );
+ m_findDialogPosition.x = (int) tmp;
+ aCfg->Read( FindDialogPositionYEntry, &tmp, -1 );
+ m_findDialogPosition.y = (int) tmp;
+ aCfg->Read( FindDialogWidthEntry, &tmp, -1 );
+ m_findDialogSize.SetWidth( (int) tmp );
+ aCfg->Read( FindDialogHeightEntry, &tmp, -1 );
+ m_findDialogSize.SetHeight( (int) tmp );
+
+ wxASSERT_MSG( m_findReplaceData,
+ wxT( "Find dialog data settings object not created. Bad programmer!" ) );
+
+ aCfg->Read( FindReplaceFlagsEntry, &tmp, (long) wxFR_DOWN );
+ m_findReplaceData->SetFlags( (wxUint32) tmp & ~FR_REPLACE_ITEM_FOUND );
+ m_findReplaceData->SetFindString( aCfg->Read( FindStringEntry, wxEmptyString ) );
+ m_findReplaceData->SetReplaceString( aCfg->Read( ReplaceStringEntry, wxEmptyString ) );
+
+ // Load the find and replace string history list.
+ for( int i = 0; i < FR_HISTORY_LIST_CNT; ++i )
+ {
+ wxString tmpHistory;
+ wxString entry;
+ entry.Printf( FindStringHistoryEntry, i );
+ tmpHistory = aCfg->Read( entry, wxEmptyString );
+
+ if( !tmpHistory.IsEmpty() )
+ m_findStringHistoryList.Add( tmpHistory );
+
+ entry.Printf( ReplaceStringHistoryEntry, i );
+ tmpHistory = aCfg->Read( entry, wxEmptyString );
+
+ if( !tmpHistory.IsEmpty() )
+ m_replaceStringHistoryList.Add( tmpHistory );
+ }
+
+ wxString templateFieldNames = aCfg->Read( FieldNamesEntry, wxEmptyString );
+
+ if( !templateFieldNames.IsEmpty() )
+ {
+ TEMPLATE_FIELDNAMES_LEXER lexer( TO_UTF8( templateFieldNames ) );
+
+ try
+ {
+ m_TemplateFieldNames.Parse( &lexer );
+ }
+ catch( const IO_ERROR& e )
+ {
+ // @todo show error msg
+ DBG( printf( "templatefieldnames parsing error: '%s'\n",
+ TO_UTF8( e.errorText ) ); )
+ }
+ }
+}
+
+
+void SCH_EDIT_FRAME::SaveSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::SaveSettings( aCfg );
+
+ wxConfigSaveSetups( aCfg, GetConfigurationSettings() );
+
+ aCfg->Write( DefaultBusWidthEntry, (long) GetDefaultBusThickness() );
+ aCfg->Write( DefaultDrawLineWidthEntry, (long) GetDefaultLineThickness() );
+ aCfg->Write( ShowHiddenPinsEntry, m_showAllPins );
+ aCfg->Write( HorzVertLinesOnlyEntry, GetForceHVLines() );
+
+ // Save print preview window session settings.
+ aCfg->Write( PreviewFramePositionXEntry, m_previewPosition.x );
+ aCfg->Write( PreviewFramePositionYEntry, m_previewPosition.y );
+ aCfg->Write( PreviewFrameWidthEntry, m_previewSize.GetWidth() );
+ aCfg->Write( PreviewFrameHeightEntry, m_previewSize.GetHeight() );
+
+ // Save print dialog session settings.
+ aCfg->Write( PrintDialogPositionXEntry, m_printDialogPosition.x );
+ aCfg->Write( PrintDialogPositionYEntry, m_printDialogPosition.y );
+ aCfg->Write( PrintDialogWidthEntry, m_printDialogSize.GetWidth() );
+ aCfg->Write( PrintDialogHeightEntry, m_printDialogSize.GetHeight() );
+
+ // Save netlists options:
+ aCfg->Write( SimulatorCommandEntry, m_simulatorCommand );
+
+ // Save find dialog session setting.
+ aCfg->Write( FindDialogPositionXEntry, m_findDialogPosition.x );
+ aCfg->Write( FindDialogPositionYEntry, m_findDialogPosition.y );
+ aCfg->Write( FindDialogWidthEntry, m_findDialogSize.GetWidth() );
+ aCfg->Write( FindDialogHeightEntry, m_findDialogSize.GetHeight() );
+ wxASSERT_MSG( m_findReplaceData,
+ wxT( "Find dialog data settings object not created. Bad programmer!" ) );
+ aCfg->Write( FindReplaceFlagsEntry,
+ (long) m_findReplaceData->GetFlags() & ~FR_REPLACE_ITEM_FOUND );
+ aCfg->Write( FindStringEntry, m_findReplaceData->GetFindString() );
+ aCfg->Write( ReplaceStringEntry, m_findReplaceData->GetReplaceString() );
+
+ // Save the find and replace string history list.
+ unsigned i;
+ wxString tmpHistory;
+ wxString entry; // invoke constructor outside of any loops
+
+ for( i = 0; i < m_findStringHistoryList.GetCount() && i < FR_HISTORY_LIST_CNT; i++ )
+ {
+ entry.Printf( FindStringHistoryEntry, i );
+ aCfg->Write( entry, m_findStringHistoryList[ i ] );
+ }
+
+ for( i = 0; i < m_replaceStringHistoryList.GetCount() && i < FR_HISTORY_LIST_CNT; i++ )
+ {
+ entry.Printf( ReplaceStringHistoryEntry, i );
+ aCfg->Write( entry, m_replaceStringHistoryList[ i ] );
+ }
+
+ // Save template fieldnames
+ STRING_FORMATTER sf;
+ m_TemplateFieldNames.Format( &sf, 0 );
+
+ wxString record = FROM_UTF8( sf.GetString().c_str() );
+ record.Replace( wxT("\n"), wxT(""), true ); // strip all newlines
+ record.Replace( wxT(" "), wxT(" "), true ); // double space to single
+
+ aCfg->Write( FieldNamesEntry, record );
+}
+
+
+void LIB_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::LoadSettings( aCfg );
+
+ SetGridColor( GetLayerColor( LAYER_GRID ) );
+ SetDrawBgColor( GetLayerColor( LAYER_BACKGROUND ) );
+
+ SetDefaultLineThickness( aCfg->Read( DefaultDrawLineWidthEntry, DEFAULTDRAWLINETHICKNESS ) );
+ SetDefaultPinLength( aCfg->Read( DefaultPinLengthEntry, DEFAULTPINLENGTH ) );
+ m_textPinNumDefaultSize = aCfg->Read( defaultPinNumSizeEntry, DEFAULTPINNUMSIZE );
+ m_textPinNameDefaultSize = aCfg->Read( defaultPinNameSizeEntry, DEFAULTPINNAMESIZE );
+ SetRepeatDeltaLabel( aCfg->Read( repeatLibLabelIncEntry, DEFAULT_REPEAT_LABEL_INC ) );
+ SetRepeatPinStep( aCfg->Read( pinRepeatStepEntry, DEFAULT_REPEAT_OFFSET_PIN ) );
+ wxPoint step;
+ step.x = aCfg->Read( repeatLibStepXEntry, (long)DEFAULT_REPEAT_OFFSET_X );
+ step.y = aCfg->Read( repeatLibStepYEntry, (long)DEFAULT_REPEAT_OFFSET_Y );
+ SetRepeatStep( step );
+}
+
+
+void LIB_EDIT_FRAME::SaveSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::SaveSettings( aCfg );
+
+ aCfg->Write( DefaultPinLengthEntry, (long) GetDefaultPinLength() );
+ aCfg->Write( defaultPinNumSizeEntry, (long) GetPinNumDefaultSize() );
+ aCfg->Write( defaultPinNameSizeEntry, (long) GetPinNameDefaultSize() );
+ aCfg->Write( repeatLibLabelIncEntry, (long) GetRepeatDeltaLabel() );
+ aCfg->Write( pinRepeatStepEntry, (long) GetRepeatPinStep() );
+ aCfg->Write( repeatLibStepXEntry, (long) GetRepeatStep().x );
+ aCfg->Write( repeatLibStepYEntry, (long) GetRepeatStep().y );
+}
+
+
+void LIB_EDIT_FRAME::OnPreferencesOptions( wxCommandEvent& event )
+{
+ wxArrayString units;
+ GRIDS grid_list = GetScreen()->GetGrids();
+
+ DIALOG_LIBEDIT_OPTIONS dlg( this );
+
+ dlg.SetGridSizes( grid_list, GetScreen()->GetGridCmdId() );
+ dlg.SetLineWidth( GetDefaultLineThickness() );
+ dlg.SetPinLength( GetDefaultPinLength() );
+ dlg.SetPinNumSize( m_textPinNumDefaultSize );
+ dlg.SetPinNameSize( m_textPinNameDefaultSize );
+ dlg.SetMaxUndoItems( GetScreen()->GetMaxUndoItems() );
+
+ dlg.SetShowGrid( IsGridVisible() );
+ dlg.Layout();
+ dlg.Fit();
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ wxRealPoint gridsize = grid_list[ (size_t) dlg.GetGridSelection() ].m_Size;
+ m_LastGridSizeId = GetScreen()->SetGrid( gridsize );
+
+ SetDefaultLineThickness( dlg.GetLineWidth() );
+ SetDefaultPinLength( dlg.GetPinLength() );
+ m_textPinNumDefaultSize = dlg.GetPinNumSize();
+ m_textPinNameDefaultSize = dlg.GetPinNameSize();
+ SetGridVisibility( dlg.GetShowGrid() );
+ SetRepeatPinStep( dlg.GetPinRepeatStep() );
+ SetRepeatStep( dlg.GetItemRepeatStep() );
+ SetRepeatDeltaLabel( dlg.GetRepeatLabelInc() );
+ GetScreen()->SetMaxUndoItems( dlg.GetMaxUndoItems() );
+
+ SaveSettings( config() ); // save values shared by eeschema applications.
+
+ m_canvas->Refresh( true );
+}
+
diff --git a/eeschema/eeschema_config.h b/eeschema/eeschema_config.h
new file mode 100644
index 0000000..e93160b
--- /dev/null
+++ b/eeschema/eeschema_config.h
@@ -0,0 +1,13 @@
+/**
+ * @file eeschema_config.h
+ */
+
+#ifndef EESCHEMA_CONFIG_H
+#define EESCHEMA_CONFIG_H
+
+#include <config_params.h>
+
+// a key to read write in user config the visibility of the rescue library dialog
+#define RESCUE_NEVER_SHOW_KEY wxT("RescueNeverShow")
+
+#endif // EESCHEMA_CONFIG_H
diff --git a/eeschema/eeschema_doc.icns b/eeschema/eeschema_doc.icns
new file mode 100644
index 0000000..7d2e0eb
--- /dev/null
+++ b/eeschema/eeschema_doc.icns
Binary files differ
diff --git a/eeschema/eeschema_id.h b/eeschema/eeschema_id.h
new file mode 100644
index 0000000..ca8eeeb
--- /dev/null
+++ b/eeschema/eeschema_id.h
@@ -0,0 +1,252 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2008 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema_id.h
+ */
+
+#ifndef __EESCHEMA_ID_H__
+#define __EESCHEMA_ID_H__
+
+
+#include <id.h>
+
+
+/**
+ * The maximum number of items in the clarify selection context menu. It is
+ * highly unlikely that there would ever be more than 10 items at the current
+ * cursor. Increase this number if that ever becomes a problem.
+ */
+#define MAX_SELECT_ITEM_IDS 10
+
+/**
+ * The maximum number of units per package.
+ * Increase this number if that ever becomes a problem, but remember
+ * the popup menu to select a given unit could be not easy to use.
+ */
+#define MAX_UNIT_COUNT_PER_PACKAGE 64
+
+
+/**
+ * Command IDs for the schematic editor.
+ *
+ * Please add IDs that are unique to the schematic editor (Eeschema) here and
+ * not in the global id.h file. This will prevent the entire project from
+ * being rebuilt when adding new command to Eeschema.
+ */
+
+enum id_eeschema_frm
+{
+ ID_UPDATE_ONE_SHEET = ID_END_LIST,
+ ID_SAVE_ONE_SHEET_UNDER_NEW_NAME,
+
+ /* Schematic editor main menubar IDs. */
+ ID_RESCUE_CACHED,
+
+ /* Schematic editor horizontal toolbar IDs */
+ ID_HIERARCHY,
+ ID_TO_LIBVIEW,
+ ID_GET_ANNOTATE,
+ ID_GET_ERC,
+ ID_BACKANNO_ITEMS,
+ ID_GEN_PLOT_SCHEMATIC,
+
+ /* Schematic editor veritcal toolbar IDs */
+ ID_SCHEMATIC_VERTICAL_TOOLBAR_START,
+ ID_HIERARCHY_PUSH_POP_BUTT,
+ ID_SCH_PLACE_COMPONENT,
+ ID_PLACE_POWER_BUTT,
+ ID_BUS_BUTT,
+ ID_WIRE_BUTT,
+ ID_BUSTOBUS_ENTRY_BUTT,
+ ID_WIRETOBUS_ENTRY_BUTT,
+ ID_LABEL_BUTT,
+ ID_GLABEL_BUTT,
+ ID_HIERLABEL_BUTT,
+ ID_IMPORT_HLABEL_BUTT,
+ ID_SHEET_PIN_BUTT,
+ ID_NOCONN_BUTT,
+ ID_JUNCTION_BUTT,
+ ID_SHEET_SYMBOL_BUTT,
+ ID_TEXT_COMMENT_BUTT,
+ ID_LINE_COMMENT_BUTT,
+ ID_ADD_IMAGE_BUTT,
+ ID_SCHEMATIC_DELETE_ITEM_BUTT,
+ ID_SCHEMATIC_VERTICAL_TOOLBAR_END,
+
+ // Toolbar options id:
+ ID_TB_OPTIONS_HIDDEN_PINS,
+ ID_TB_OPTIONS_BUS_WIRES_ORIENT,
+
+ /* Schematic editor context menu IDs. */
+ ID_POPUP_SCH_COPY_ITEM,
+
+ ID_POPUP_START_RANGE,
+ ID_POPUP_SCH_DELETE,
+ ID_POPUP_SCH_BREAK_WIRE,
+ ID_POPUP_SCH_BEGIN_WIRE,
+ ID_POPUP_SCH_BEGIN_BUS,
+ ID_POPUP_END_LINE,
+ ID_POPUP_SCH_DELETE_CONNECTION,
+ ID_POPUP_SCH_DELETE_NODE,
+ ID_POPUP_SCH_DELETE_CMP,
+ ID_POPUP_SCH_ENTRY_SELECT_SLASH,
+ ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH,
+
+ ID_POPUP_SCH_INIT_CMP,
+
+ ID_POPUP_SCH_SET_SHAPE_TEXT,
+ ID_POPUP_SCH_END_SHEET,
+ ID_POPUP_SCH_RESIZE_SHEET,
+ ID_POPUP_SCH_CLEANUP_SHEET,
+ ID_POPUP_IMPORT_HLABEL_TO_SHEETPIN,
+ ID_POPUP_SCH_GENERIC_ORIENT_CMP,
+ ID_POPUP_SCH_GENERIC_EDIT_CMP,
+ ID_POPUP_SCH_EDIT_CONVERT_CMP,
+ ID_POPUP_SCH_EDIT_FIELD,
+ ID_POPUP_SCH_DISPLAYDOC_CMP,
+ ID_POPUP_SCH_ENTER_SHEET,
+ ID_POPUP_SCH_LEAVE_SHEET,
+ ID_POPUP_SCH_ADD_JUNCTION,
+ ID_POPUP_SCH_ADD_LABEL,
+ ID_POPUP_SCH_ADD_GLABEL,
+ ID_POPUP_SCH_GETINFO_MARKER,
+ ID_POPUP_END_RANGE,
+
+ ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP,
+
+ // Unit select context menus command IDs.
+ ID_POPUP_SCH_SELECT_UNIT_CMP,
+ ID_POPUP_SCH_SELECT_UNIT1,
+ // ... leave room for MAX_UNIT_COUNT_PER_PACKAGE IDs ,
+ // to select one unit among MAX_UNIT_COUNT_PER_PACKAGE in popup menu
+ ID_POPUP_SCH_SELECT_UNIT_CMP_MAX = ID_POPUP_SCH_SELECT_UNIT1
+ + MAX_UNIT_COUNT_PER_PACKAGE,
+
+ // Change text type context menu command IDs.
+ ID_POPUP_SCH_CHANGE_TYPE_TEXT,
+ ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_LABEL,
+ ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_GLABEL,
+ ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_HLABEL,
+ ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT,
+
+ ID_SELECT_ITEM_START,
+ ID_SELECT_ITEM_END = ID_SELECT_ITEM_START + MAX_SELECT_ITEM_IDS,
+
+ // Change orientation command IDs.
+ ID_SCH_MIRROR_X,
+ ID_SCH_MIRROR_Y,
+ ID_SCH_ORIENT_NORMAL,
+
+ ID_SCH_ROTATE_CLOCKWISE,
+ ID_SCH_ROTATE_COUNTERCLOCKWISE,
+ ID_SCH_EDIT_ITEM,
+ ID_SCH_EDIT_COMPONENT_VALUE,
+ ID_SCH_EDIT_COMPONENT_REFERENCE,
+ ID_SCH_EDIT_COMPONENT_FOOTPRINT,
+ ID_SCH_MOVE_ITEM,
+ ID_SCH_DRAG_ITEM,
+
+ // Schematic editor commmands. These are command IDs that are generated by multiple
+ // events (menus, toolbar, context menu, etc.) that result in the same event handler.
+ ID_CANCEL_CURRENT_COMMAND,
+
+ /* Library editor main menubar IDs. */
+ ID_LIBEDIT_DIMENSIONS,
+
+ /* Library editor horizontal toolbar IDs. */
+ ID_LIBEDIT_SELECT_PART,
+ ID_LIBEDIT_SELECT_CURRENT_LIB,
+ ID_LIBEDIT_SAVE_CURRENT_LIB,
+ ID_LIBEDIT_SAVE_CURRENT_PART,
+ ID_LIBEDIT_NEW_PART,
+ ID_LIBEDIT_NEW_PART_FROM_EXISTING,
+ ID_LIBEDIT_GET_FRAME_EDIT_PART,
+ ID_LIBEDIT_GET_FRAME_EDIT_FIELDS,
+ ID_LIBEDIT_DELETE_PART,
+ ID_DE_MORGAN_NORMAL_BUTT,
+ ID_DE_MORGAN_CONVERT_BUTT,
+ ID_LIBEDIT_EDIT_PIN_BY_PIN,
+ ID_LIBEDIT_EDIT_PIN_BY_TABLE,
+ ID_LIBEDIT_VIEW_DOC,
+ ID_LIBEDIT_CHECK_PART,
+
+ ID_LIBEDIT_SELECT_PART_NUMBER,
+ ID_LIBEDIT_SELECT_ALIAS,
+
+ /* Library editor vertical toolbar IDs. */
+ ID_LIBEDIT_PIN_BUTT,
+ ID_LIBEDIT_BODY_LINE_BUTT,
+ ID_LIBEDIT_BODY_ARC_BUTT,
+ ID_LIBEDIT_BODY_CIRCLE_BUTT,
+ ID_LIBEDIT_BODY_RECT_BUTT,
+ ID_LIBEDIT_BODY_TEXT_BUTT,
+ ID_LIBEDIT_ANCHOR_ITEM_BUTT,
+ ID_LIBEDIT_IMPORT_BODY_BUTT,
+ ID_LIBEDIT_EXPORT_BODY_BUTT,
+ ID_LIBEDIT_DELETE_ITEM_BUTT,
+
+ ID_LIBEDIT_ROTATE_ITEM,
+
+ /* Library editor context menu IDs */
+ ID_LIBEDIT_EDIT_PIN,
+ ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_ITEM,
+ ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM,
+ ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM,
+ ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM,
+ ID_POPUP_LIBEDIT_BODY_EDIT_ITEM,
+ ID_POPUP_LIBEDIT_DELETE_ITEM,
+ ID_POPUP_LIBEDIT_MODIFY_ITEM,
+ ID_POPUP_LIBEDIT_END_CREATE_ITEM,
+ ID_POPUP_LIBEDIT_CANCEL_EDITING,
+ ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST,
+ ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM,
+ ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT,
+
+ /* Library editor menubar IDs */
+ ID_LIBEDIT_SAVE_CURRENT_LIB_AS,
+ ID_LIBEDIT_GEN_PNG_FILE,
+ ID_LIBEDIT_GEN_SVG_FILE,
+
+ /* Library viewer horizontal toolbar IDs */
+ ID_LIBVIEW_NEXT,
+ ID_LIBVIEW_PREVIOUS,
+ ID_LIBVIEW_SELECT_PART,
+ ID_LIBVIEW_SELECT_LIB,
+ ID_LIBVIEW_VIEWDOC,
+ ID_LIBVIEW_DE_MORGAN_NORMAL_BUTT,
+ ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT,
+ ID_LIBVIEW_SELECT_PART_NUMBER,
+ ID_LIBVIEW_LIB_LIST,
+ ID_LIBVIEW_CMP_LIST,
+ ID_LIBVIEW_LIBWINDOW,
+ ID_LIBVIEW_CMPWINDOW,
+ ID_LIBVIEW_CMP_EXPORT_TO_SCHEMATIC,
+ ID_SET_RELATIVE_OFFSET,
+
+ ID_END_EESCHEMA_ID_LIST
+};
+
+
+#endif /* __EESCHEMA_ID_H__ */
diff --git a/eeschema/erc.cpp b/eeschema/erc.cpp
new file mode 100644
index 0000000..099249c
--- /dev/null
+++ b/eeschema/erc.cpp
@@ -0,0 +1,617 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file erc.cpp
+ * @brief Electrical Rules Check implementation.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <kicad_string.h>
+#include <schframe.h>
+
+#include <netlist.h>
+#include <class_netlist_object.h>
+#include <lib_pin.h>
+#include <erc.h>
+#include <sch_marker.h>
+#include <sch_component.h>
+#include <sch_sheet.h>
+
+#include <wx/ffile.h>
+
+
+/* ERC tests :
+ * 1 - conflicts between connected pins ( example: 2 connected outputs )
+ * 2 - minimal connections requirements ( 1 input *must* be connected to an
+ * output, or a passive pin )
+ */
+
+
+/*
+ * Electrical type of pins:
+ * PIN_INPUT = usual pin input: must be connected
+ * PIN_OUTPUT = usual output
+ * PIN_BIDI = input or output (like port for a microprocessor)
+ * PIN_TRISTATE = tris state bus pin
+ * PIN_PASSIVE = pin for passive components: must be connected, and can be
+ * connected to any pin
+ * PIN_UNSPECIFIED = unknown electrical properties: creates always a warning
+ * when connected
+ * PIN_POWER_IN = power input (GND, VCC for ICs). Must be connected to a power
+ * output.
+ * PIN_POWER_OUT = output of a regulator: intended to be connected to power
+ * input pins
+ * PIN_OPENCOLLECTOR = pin type open collector
+ * PIN_OPENEMITTER = pin type open emitter
+ * PIN_NC = not connected (must be left open)
+ *
+ * Minimal requirements:
+ * All pins *must* be connected (except PIN_NC).
+ * When a pin is not connected in schematic, the user must place a "non
+ * connected" symbol to this pin.
+ * This ensures a forgotten connection will be detected.
+ */
+
+/* Messages for conflicts :
+ * PIN_INPUT, PIN_OUTPUT, PIN_BIDI, PIN_TRISTATE, PIN_PASSIVE,
+ * PIN_UNSPECIFIED, PIN_POWER_IN, PIN_POWER_OUT, PIN_OPENCOLLECTOR,
+ * PIN_OPENEMITTER, PIN_NC
+ * These messages are used to show the ERC matrix in ERC dialog
+ */
+
+// Messages for matrix rows:
+const wxString CommentERC_H[] =
+{
+ _( "Input Pin.........." ),
+ _( "Output Pin........." ),
+ _( "Bidirectional Pin.." ),
+ _( "Tri-State Pin......" ),
+ _( "Passive Pin........" ),
+ _( "Unspecified Pin...." ),
+ _( "Power Input Pin...." ),
+ _( "Power Output Pin..." ),
+ _( "Open Collector....." ),
+ _( "Open Emitter......." ),
+ _( "No Connection......" )
+};
+
+// Messages for matrix columns
+const wxString CommentERC_V[] =
+{
+ _( "Input Pin" ),
+ _( "Output Pin" ),
+ _( "Bidirectional Pin" ),
+ _( "Tri-State Pin" ),
+ _( "Passive Pin" ),
+ _( "Unspecified Pin" ),
+ _( "Power Input Pin" ),
+ _( "Power Output Pin" ),
+ _( "Open Collector" ),
+ _( "Open Emitter" ),
+ _( "No Connection" )
+};
+
+
+/* Look up table which gives the diag for a pair of connected pins
+ * Can be modified by ERC options.
+ * at start up: must be loaded by DefaultDiagErc
+ */
+int DiagErc[PIN_NMAX][PIN_NMAX];
+bool DiagErcTableInit; // go to true after DiagErc init
+
+/**
+ * Default Look up table which gives the ERC error level for a pair of connected pins
+ * Same as DiagErc, but cannot be modified.
+ * Used to init or reset DiagErc
+ * note also, to avoid inconsistancy:
+ * DefaultDiagErc[i][j] = DefaultDiagErc[j][i]
+ */
+int DefaultDiagErc[PIN_NMAX][PIN_NMAX] =
+{
+/* I, O, Bi, 3S, Pas, UnS, PwrI, PwrO, OC, OE, NC */
+/* I */ { OK, OK, OK, OK, OK, WAR, OK, OK, OK, OK, ERR },
+/* O */ { OK, ERR, OK, WAR, OK, WAR, OK, ERR, ERR, ERR, ERR },
+/* Bi*/ { OK, OK, OK, OK, OK, WAR, OK, WAR, OK, WAR, ERR },
+/* 3S*/ { OK, WAR, OK, OK, OK, WAR, WAR, ERR, WAR, WAR, ERR },
+/*Pas*/ { OK, OK, OK, OK, OK, WAR, OK, OK, OK, OK, ERR },
+/*UnS */ { WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, ERR },
+/*PwrI*/ { OK, OK, OK, WAR, OK, WAR, OK, OK, OK, OK, ERR },
+/*PwrO*/ { OK, ERR, WAR, ERR, OK, WAR, OK, ERR, ERR, ERR, ERR },
+/* OC */ { OK, ERR, OK, WAR, OK, WAR, OK, ERR, OK, OK, ERR },
+/* OE */ { OK, ERR, WAR, WAR, OK, WAR, OK, ERR, OK, OK, ERR },
+/* NC */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR }
+};
+
+
+/**
+ * Look up table which gives the minimal drive for a pair of connected pins on
+ * a net.
+ * <p>
+ * The initial state of a net is NOC (Net with No Connection). It can be updated to
+ * NPI (Pin Isolated), NET_NC (Net with a no connect symbol), NOD (Not Driven) or DRV
+ * (DRIven). It can be updated to NET_NC with no error only if there is only one pin
+ * in net. Nets are OK when their final state is NET_NC or DRV. Nets with the state
+ * NOD have no valid source signal.
+ */
+static int MinimalReq[PIN_NMAX][PIN_NMAX] =
+{
+/* In Out, Bi, 3S, Pas, UnS, PwrI,PwrO,OC, OE, NC */
+/* In*/ { NOD, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
+/*Out*/ { DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, NPI },
+/* Bi*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
+/* 3S*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
+/*Pas*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
+/*UnS*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
+/*PwrI*/ { NOD, DRV, NOD, NOD, NOD, NOD, NOD, DRV, NOD, NOD, NPI },
+/*PwrO*/ { DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, NPI },
+/* OC*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
+/* OE*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NPI },
+/* NC*/ { NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI, NPI }
+};
+
+
+int TestDuplicateSheetNames( bool aCreateMarker )
+{
+ SCH_SCREEN* screen;
+ SCH_ITEM* item;
+ SCH_ITEM* test_item;
+ int err_count = 0;
+ SCH_SCREENS screenList; // Created the list of screen
+
+ for( screen = screenList.GetFirst(); screen != NULL; screen = screenList.GetNext() )
+ {
+ for( item = screen->GetDrawItems(); item != NULL; item = item->Next() )
+ {
+ // search for a sheet;
+ if( item->Type() != SCH_SHEET_T )
+ continue;
+
+ for( test_item = item->Next(); test_item != NULL; test_item = test_item->Next() )
+ {
+ if( test_item->Type() != SCH_SHEET_T )
+ continue;
+
+ // We have found a second sheet: compare names
+ if( ( (SCH_SHEET*) item )->GetName().CmpNoCase(
+ ( ( SCH_SHEET* ) test_item )->GetName() ) == 0 )
+ {
+ if( aCreateMarker )
+ {
+ /* Create a new marker type ERC error*/
+ SCH_MARKER* marker = new SCH_MARKER();
+ marker->SetTimeStamp( GetNewTimeStamp() );
+ marker->SetData( ERCE_DUPLICATE_SHEET_NAME,
+ ( (SCH_SHEET*) test_item )->GetPosition(),
+ _( "Duplicate sheet name" ),
+ ( (SCH_SHEET*) test_item )->GetPosition() );
+ marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
+ marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR );
+ screen->Append( marker );
+ }
+
+ err_count++;
+ }
+ }
+ }
+ }
+
+ return err_count;
+}
+
+
+void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst,
+ int aMinConn, int aDiag )
+{
+ SCH_MARKER* marker = NULL;
+ SCH_SCREEN* screen;
+ int ii, jj;
+
+ if( aDiag == OK )
+ return;
+
+ /* Create new marker for ERC error. */
+ marker = new SCH_MARKER();
+ marker->SetTimeStamp( GetNewTimeStamp() );
+
+ marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
+ marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
+ screen = aNetItemRef->m_SheetPath.LastScreen();
+ screen->Append( marker );
+
+ wxString msg;
+
+ if( aMinConn < 0 )
+ {
+ if( (aNetItemRef->m_Type == NET_HIERLABEL)
+ || (aNetItemRef->m_Type == NET_HIERBUSLABELMEMBER) )
+ {
+ msg.Printf( _( "Hierarchical label %s is not connected to a sheet label." ),
+ GetChars( aNetItemRef->m_Label ) );
+ marker->SetData( ERCE_HIERACHICAL_LABEL,
+ aNetItemRef->m_Start,
+ msg,
+ aNetItemRef->m_Start );
+ }
+ else if( (aNetItemRef->m_Type == NET_GLOBLABEL) )
+ {
+ msg.Printf( _( "Global label %s is not connected to any other global label." ),
+ GetChars( aNetItemRef->m_Label ) );
+ marker->SetData( ERCE_GLOBLABEL,
+ aNetItemRef->m_Start,
+ msg,
+ aNetItemRef->m_Start );
+ }
+ else
+ {
+ msg.Printf( _( "Sheet label %s is not connected to a hierarchical label." ),
+ GetChars( aNetItemRef->m_Label ) );
+ marker->SetData( ERCE_HIERACHICAL_LABEL,
+ aNetItemRef->m_Start,
+ msg,
+ aNetItemRef->m_Start );
+ }
+
+ return;
+ }
+
+ ii = aNetItemRef->m_ElectricalType;
+
+ wxString string_pinnum, cmp_ref;
+ char ascii_buf[5];
+ ascii_buf[4] = 0;
+ memcpy( ascii_buf, &aNetItemRef->m_PinNum, 4 );
+ string_pinnum = FROM_UTF8( ascii_buf );
+ cmp_ref = wxT( "?" );
+
+ if( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link )
+ cmp_ref = aNetItemRef->GetComponentParent()->GetRef( &aNetItemRef->m_SheetPath );
+
+ if( aNetItemTst == NULL )
+ {
+ if( aMinConn == NOC ) /* Only 1 element in the net. */
+ {
+ msg.Printf( _( "Pin %s (%s) of component %s is unconnected." ),
+ GetChars( string_pinnum ),
+ GetChars( LIB_PIN::GetElectricalTypeName( ii ) ),
+ GetChars( cmp_ref ) );
+ marker->SetData( ERCE_PIN_NOT_CONNECTED,
+ aNetItemRef->m_Start,
+ msg,
+ aNetItemRef->m_Start );
+ return;
+ }
+
+ if( aMinConn == NOD ) /* Nothing driving the net. */
+ {
+ if( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link )
+ cmp_ref = aNetItemRef->GetComponentParent()->GetRef(
+ &aNetItemRef->m_SheetPath );
+
+ msg.Printf( _( "Pin %s (%s) of component %s is not driven (Net %d)." ),
+ GetChars( string_pinnum ),
+ GetChars( LIB_PIN::GetElectricalTypeName( ii ) ),
+ GetChars( cmp_ref ),
+ aNetItemRef->GetNet() );
+ marker->SetData( ERCE_PIN_NOT_DRIVEN,
+ aNetItemRef->m_Start,
+ msg,
+ aNetItemRef->m_Start );
+ return;
+ }
+
+ if( aDiag == UNC )
+ {
+ msg.Printf( _( "More than 1 pin connected to an UnConnect symbol." ) );
+ marker->SetData( ERCE_NOCONNECT_CONNECTED,
+ aNetItemRef->m_Start,
+ msg,
+ aNetItemRef->m_Start );
+ return;
+ }
+ }
+
+ if( aNetItemTst ) /* Error between 2 pins */
+ {
+ jj = aNetItemTst->m_ElectricalType;
+ int errortype = ERCE_PIN_TO_PIN_WARNING;
+
+ if( aDiag == ERR )
+ {
+ marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR );
+ errortype = ERCE_PIN_TO_PIN_ERROR;
+ }
+
+ wxString alt_string_pinnum, alt_cmp;
+ memcpy( ascii_buf, &aNetItemTst->m_PinNum, 4 );
+ alt_string_pinnum = FROM_UTF8( ascii_buf );
+ alt_cmp = wxT( "?" );
+
+ if( aNetItemTst->m_Type == NET_PIN && aNetItemTst->m_Link )
+ alt_cmp = aNetItemTst->GetComponentParent()->GetRef( &aNetItemTst->m_SheetPath );
+
+ msg.Printf( _( "Pin %s (%s) of component %s is connected to " ),
+ GetChars( string_pinnum ),
+ GetChars( LIB_PIN::GetElectricalTypeName( ii ) ),
+ GetChars( cmp_ref ) );
+ marker->SetData( errortype, aNetItemRef->m_Start, msg, aNetItemRef->m_Start );
+ msg.Printf( _( "pin %s (%s) of component %s (net %d)." ),
+ GetChars( alt_string_pinnum ),
+ GetChars( LIB_PIN::GetElectricalTypeName( jj ) ),
+ GetChars( alt_cmp ),
+ aNetItemRef->GetNet() );
+ marker->SetAuxiliaryData( msg, aNetItemTst->m_Start );
+ }
+}
+
+
+void TestOthersItems( NETLIST_OBJECT_LIST* aList,
+ unsigned aNetItemRef, unsigned aNetStart,
+ int* aMinConnexion )
+{
+ unsigned netItemTst = aNetStart;
+ int jj;
+ int erc = OK;
+
+ /* Analysis of the table of connections. */
+ int ref_elect_type = aList->GetItem( aNetItemRef )->m_ElectricalType;
+ int local_minconn = NOC;
+
+ if( ref_elect_type == PIN_NC )
+ local_minconn = NPI;
+
+ /* Test pins connected to NetItemRef */
+ for( ; ; netItemTst++ )
+ {
+ if( aNetItemRef == netItemTst )
+ continue;
+
+ // We examine only a given net. We stop the search if the net changes
+ if( ( netItemTst >= aList->size() ) // End of list
+ || ( aList->GetItemNet( aNetItemRef ) !=
+ aList->GetItemNet( netItemTst ) ) ) // End of net
+ {
+ /* End net code found: minimum connection test. */
+ if( ( *aMinConnexion < NET_NC ) && ( local_minconn < NET_NC ) )
+ {
+ /* Not connected or not driven pin. */
+ bool seterr = true;
+
+ if( local_minconn == NOC &&
+ aList->GetItemType( aNetItemRef ) == NET_PIN )
+ {
+ /* This pin is not connected: for multiple part per
+ * package, and duplicated pin,
+ * search for an other instance of this pin
+ * this will be flagged only if all instances of this pin
+ * are not connected
+ * TODO test also if instances connected are connected to
+ * the same net
+ */
+ for( unsigned duplicate = 0; duplicate < aList->size(); duplicate++ )
+ {
+ if( aList->GetItemType( duplicate ) != NET_PIN )
+ continue;
+
+ if( duplicate == aNetItemRef )
+ continue;
+
+ if( aList->GetItem( aNetItemRef )->m_PinNum !=
+ aList->GetItem( duplicate )->m_PinNum )
+ continue;
+
+ if( ( (SCH_COMPONENT*) aList->GetItem( aNetItemRef )->
+ m_Link )->GetRef( &aList->GetItem( aNetItemRef )-> m_SheetPath ) !=
+ ( (SCH_COMPONENT*) aList->GetItem( duplicate )->m_Link )
+ ->GetRef( &aList->GetItem( duplicate )->m_SheetPath ) )
+ continue;
+
+ // Same component and same pin. Do dot create error for this pin
+ // if the other pin is connected (i.e. if duplicate net has an other
+ // item)
+ if( (duplicate > 0)
+ && ( aList->GetItemNet( duplicate ) ==
+ aList->GetItemNet( duplicate - 1 ) ) )
+ seterr = false;
+
+ if( (duplicate < aList->size() - 1)
+ && ( aList->GetItemNet( duplicate ) ==
+ aList->GetItemNet( duplicate + 1 ) ) )
+ seterr = false;
+ }
+ }
+
+ if( seterr )
+ Diagnose( aList->GetItem( aNetItemRef ), NULL, local_minconn, WAR );
+
+ *aMinConnexion = DRV; // inhibiting other messages of this
+ // type for the net.
+ }
+ return;
+ }
+
+ switch( aList->GetItemType( netItemTst ) )
+ {
+ case NET_ITEM_UNSPECIFIED:
+ case NET_SEGMENT:
+ case NET_BUS:
+ case NET_JUNCTION:
+ case NET_LABEL:
+ case NET_HIERLABEL:
+ case NET_BUSLABELMEMBER:
+ case NET_HIERBUSLABELMEMBER:
+ case NET_SHEETBUSLABELMEMBER:
+ case NET_SHEETLABEL:
+ case NET_GLOBLABEL:
+ case NET_GLOBBUSLABELMEMBER:
+ case NET_PINLABEL:
+ break;
+
+ case NET_NOCONNECT:
+ local_minconn = std::max( NET_NC, local_minconn );
+ break;
+
+ case NET_PIN:
+ jj = aList->GetItem( netItemTst )->m_ElectricalType;
+ local_minconn = std::max( MinimalReq[ref_elect_type][jj], local_minconn );
+
+ if( netItemTst <= aNetItemRef )
+ break;
+
+ if( erc == OK )
+ {
+ erc = DiagErc[ref_elect_type][jj];
+
+ if( erc != OK )
+ {
+ if( aList->GetConnectionType( netItemTst ) == UNCONNECTED )
+ {
+ Diagnose( aList->GetItem( aNetItemRef ),
+ aList->GetItem( netItemTst ),
+ 0, erc );
+ aList->SetConnectionType( netItemTst, NOCONNECT_SYMBOL_PRESENT );
+ }
+ }
+ }
+
+ break;
+ }
+ }
+}
+
+
+int CountPinsInNet( NETLIST_OBJECT_LIST* aList, unsigned aNetStart )
+{
+ int count = 0;
+ int curr_net = aList->GetItemNet( aNetStart );
+
+ /* Test pins connected to NetItemRef */
+ for( unsigned item = aNetStart; item < aList->size(); item++ )
+ {
+ // We examine only a given net. We stop the search if the net changes
+ if( curr_net != aList->GetItemNet( item ) ) // End of net
+ break;
+
+ if( aList->GetItemType( item ) == NET_PIN )
+ count++;
+ }
+
+ return count;
+}
+
+bool WriteDiagnosticERC( const wxString& aFullFileName )
+{
+ wxString msg;
+
+ wxFFile file( aFullFileName, wxT( "wt" ) );
+
+ if( !file.IsOpened() )
+ return false;
+
+ msg = _( "ERC report" );
+ msg << wxT(" (") << DateAndTime() << wxT( ", " )
+ << _( "Encoding UTF8" ) << wxT( " )\n" );
+
+ int err_count = 0;
+ int warn_count = 0;
+ int total_count = 0;
+ SCH_SHEET_LIST sheetList;
+ SCH_SHEET_PATH* sheet;
+
+ for( sheet = sheetList.GetFirst(); sheet != NULL; sheet = sheetList.GetNext() )
+ {
+ msg << wxString::Format( _( "\n***** Sheet %s\n" ),
+ GetChars( sheet->PathHumanReadable() ) );
+
+ for( SCH_ITEM* item = sheet->LastDrawList(); item != NULL; item = item->Next() )
+ {
+ if( item->Type() != SCH_MARKER_T )
+ continue;
+
+ SCH_MARKER* marker = (SCH_MARKER*) item;
+
+ if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
+ continue;
+
+ total_count++;
+
+ if( marker->GetErrorLevel() == MARKER_BASE::MARKER_SEVERITY_ERROR )
+ err_count++;
+
+ if( marker->GetErrorLevel() == MARKER_BASE::MARKER_SEVERITY_WARNING )
+ warn_count++;
+
+ msg << marker->GetReporter().ShowReport();
+ }
+ }
+
+ msg << wxString::Format( _( "\n ** ERC messages: %d Errors %d Warnings %d\n" ),
+ total_count, err_count, warn_count );
+
+ // Currently: write report unsing UTF8 (as usual in Kicad).
+ // TODO: see if we can use the current encoding page (mainly for Windows users),
+ // Or other format (HTML?)
+ file.Write( msg );
+
+ // wxFFile dtor will close the file.
+
+ return true;
+}
+
+
+void TestLabel( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned aStartNet )
+{
+ unsigned netItemTst = aStartNet;
+ int erc = 1;
+
+ // Review the list of labels connected to NetItemRef:
+ for( ; ; netItemTst++ )
+ {
+ if( netItemTst == aNetItemRef )
+ continue;
+
+ /* Is always in the same net? */
+ if( ( netItemTst == aList->size() )
+ || ( aList->GetItemNet( aNetItemRef ) != aList->GetItemNet( netItemTst ) ) )
+ {
+ /* End Netcode found. */
+ if( erc )
+ {
+ /* Glabel or SheetLabel orphaned. */
+ Diagnose( aList->GetItem( aNetItemRef ), NULL, -1, WAR );
+ }
+
+ return;
+ }
+
+ if( aList->GetItem( aNetItemRef )->IsLabelConnected( aList->GetItem( netItemTst ) ) )
+ erc = 0;
+
+ //same thing, different order.
+ if( aList->GetItem( netItemTst )->IsLabelConnected( aList->GetItem( aNetItemRef ) ) )
+ erc = 0;
+ }
+}
diff --git a/eeschema/erc.h b/eeschema/erc.h
new file mode 100644
index 0000000..708fb6a
--- /dev/null
+++ b/eeschema/erc.h
@@ -0,0 +1,127 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2009-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file erc.h
+ */
+
+#ifndef _ERC_H
+#define _ERC_H
+
+
+class EDA_DRAW_PANEL;
+class NETLIST_OBJECT;
+class NETLIST_OBJECT_LIST;
+
+/* For ERC markers: error types (used in diags, and to set the color):
+*/
+enum errortype
+{
+ OK = 0,
+ WAR, // Error: severity = warning
+ ERR, // Error: severity = error
+ UNC // Error: unconnected pin
+};
+
+extern const wxString CommentERC_H[];
+extern const wxString CommentERC_V[];
+
+/// DRC error codes:
+#define ERCE_UNSPECIFIED 0
+#define ERCE_DUPLICATE_SHEET_NAME 1 // duplicate sheet names within a given sheet
+#define ERCE_PIN_NOT_CONNECTED 2 // pin not connected and not no connect symbol
+#define ERCE_PIN_NOT_DRIVEN 3 // pin connected to some others pins but no pin to drive it
+#define ERCE_PIN_TO_PIN_WARNING 4 // pin connected to an other pin: warning level
+#define ERCE_PIN_TO_PIN_ERROR 5 // pin connected to an other pin: error level
+#define ERCE_HIERACHICAL_LABEL 6 // mismatch between hierarchical labels and pins sheets
+#define ERCE_NOCONNECT_CONNECTED 7 // a no connect symbol is connected to more than 1 pin
+#define ERCE_GLOBLABEL 8 // global label not connected to any other global label
+
+/* Minimal connection table */
+#define NPI 4 // Net with Pin isolated, this pin has type Not Connected and must be left N.C.
+#define DRV 3 // Net driven by a signal (a pin output for instance)
+#define NET_NC 2 // Net "connected" to a "NoConnect symbol"
+#define NOD 1 // Net not driven ( Such as 2 or more connected inputs )
+#define NOC 0 // initial state of a net: no connection
+
+
+/**
+ * Function WriteDiagnosticERC
+ * save the ERC errors to \a aFullFileName.
+ *
+ * @param aFullFileName A wxString object containing the file name and path.
+ */
+extern bool WriteDiagnosticERC( const wxString& aFullFileName );
+
+/**
+ * Performs ERC testing and creates an ERC marker to show the ERC problem for aNetItemRef
+ * or between aNetItemRef and aNetItemTst.
+ * if MinConn < 0: this is an error on labels
+ */
+extern void Diagnose( NETLIST_OBJECT* NetItemRef, NETLIST_OBJECT* NetItemTst,
+ int MinConnexion, int Diag );
+
+/**
+ * Perform ERC testing for electrical conflicts between \a NetItemRef and other items
+ * (mainly pin) on the same net.
+ * @param aList = a reference to the list of connected objects
+ * @param aNetItemRef = index in list of the current object
+ * @param aNetStart = index in list of net objects of the first item
+ * @param aMinConnexion = a pointer to a variable to store the minimal connection
+ * found( NOD, DRV, NPI, NET_NC)
+ */
+extern void TestOthersItems( NETLIST_OBJECT_LIST* aList,
+ unsigned aNetItemRef, unsigned aNetStart,
+ int* aMinConnexion );
+
+/**
+ * Counts number of pins connected on the same net.
+ * Used to find all pins conected to a no connect symbol
+ * @return the pin count of the net starting at aNetStart
+ * @param aNetStart = index in list of net objects of the first item
+ * @param aList = a reference to the list of connected objects
+ */
+int CountPinsInNet( NETLIST_OBJECT_LIST* aList, unsigned aNetStart );
+
+
+/**
+ * Function TestLabel
+ * performs an ERC on a sheet labels to verify that it is connected to a corresponding
+ * sub sheet global label.
+ */
+extern void TestLabel( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned aStartNet );
+
+/**
+ * Function TestDuplicateSheetNames( )
+ * inside a given sheet, one cannot have sheets with duplicate names (file
+ * names can be duplicated).
+ * @return the error count
+ * @param aCreateMarker: true = create error markers in schematic,
+ * false = calculate error count only
+ */
+extern int TestDuplicateSheetNames( bool aCreateMarker );
+
+
+#endif // _ERC_H
diff --git a/eeschema/events_called_functions_for_edit.cpp b/eeschema/events_called_functions_for_edit.cpp
new file mode 100644
index 0000000..bc7c69a
--- /dev/null
+++ b/eeschema/events_called_functions_for_edit.cpp
@@ -0,0 +1,79 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * @file events_called_functions.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <general.h>
+#include <kicad_device_context.h>
+#include <schframe.h>
+#include <sch_component.h>
+#include <sch_text.h>
+
+
+void SCH_EDIT_FRAME::OnCopySchematicItemRequest( wxCommandEvent& event )
+{
+ SCH_ITEM * curr_item = GetScreen()->GetCurItem();
+
+ if( !curr_item || curr_item->GetFlags() )
+ return;
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ switch( curr_item->Type() )
+ {
+ case SCH_COMPONENT_T:
+ {
+ SCH_COMPONENT* newitem;
+ newitem = new SCH_COMPONENT( *( (SCH_COMPONENT*) curr_item ) );
+ newitem->SetTimeStamp( GetNewTimeStamp() );
+ newitem->ClearAnnotation( NULL );
+ newitem->SetFlags( IS_NEW );
+ // Draw the new part, MoveItem() expects it to be already on screen.
+ newitem->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode );
+ PrepareMoveItem( newitem, &dc );
+ }
+ break;
+
+ case SCH_TEXT_T:
+ case SCH_LABEL_T:
+ case SCH_GLOBAL_LABEL_T:
+ case SCH_HIERARCHICAL_LABEL_T:
+ {
+ SCH_TEXT* newitem = (SCH_TEXT*) curr_item->Clone();
+ newitem->SetFlags( IS_NEW );
+ // Draw the new item, MoveItem() expects it to be already on screen.
+ newitem->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode );
+ PrepareMoveItem( newitem, &dc );
+ }
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp
new file mode 100644
index 0000000..81b6d69
--- /dev/null
+++ b/eeschema/files-io.cpp
@@ -0,0 +1,547 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2013 CERN (www.cern.ch)
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/files-io.cpp
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <schframe.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+
+#include <eeschema_id.h>
+#include <class_library.h>
+#include <libeditframe.h>
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+#include <sch_component.h>
+#include <wildcards_and_files_ext.h>
+#include <project_rescue.h>
+#include <eeschema_config.h>
+
+
+bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName, bool aCreateBackupFile )
+{
+ wxString msg;
+ wxFileName schematicFileName;
+ bool success;
+
+ if( aScreen == NULL )
+ aScreen = GetScreen();
+
+ // If no name exists in the window yet - save as new.
+ if( aScreen->GetFileName().IsEmpty() )
+ aSaveUnderNewName = true;
+
+ // Construct the name of the file to be saved
+ schematicFileName = Prj().AbsolutePath( aScreen->GetFileName() );
+
+ if( aSaveUnderNewName )
+ {
+ wxFileDialog dlg( this, _( "Schematic Files" ),
+ wxPathOnly( Prj().GetProjectFullName() ),
+ schematicFileName.GetFullName(), SchematicFileWildcard,
+ wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return false;
+
+ schematicFileName = dlg.GetPath();
+
+ if( schematicFileName.GetExt() != SchematicFileExtension )
+ schematicFileName.SetExt( SchematicFileExtension );
+ }
+
+ if( !IsWritable( schematicFileName ) )
+ return false;
+
+ // Create backup if requested
+ if( aCreateBackupFile && schematicFileName.FileExists() )
+ {
+ wxFileName backupFileName = schematicFileName;
+
+ // Rename the old file to a '.bak' one:
+ backupFileName.SetExt( SchematicBackupFileExtension );
+
+ if( backupFileName.FileExists() )
+ wxRemoveFile( backupFileName.GetFullPath() );
+
+ if( !wxRenameFile( schematicFileName.GetFullPath(), backupFileName.GetFullPath() ) )
+ {
+ msg.Printf( _( "Could not save backup of file '%s'" ),
+ GetChars( schematicFileName.GetFullPath() ) );
+ DisplayError( this, msg );
+ }
+ }
+
+ // Save
+ wxLogTrace( traceAutoSave,
+ wxT( "Saving file <" ) + schematicFileName.GetFullPath() + wxT( ">" ) );
+
+ FILE* f = wxFopen( schematicFileName.GetFullPath(), wxT( "wt" ) );
+
+ if( !f )
+ {
+ msg.Printf( _( "Failed to create file '%s'" ),
+ GetChars( schematicFileName.GetFullPath() ) );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ success = aScreen->Save( f );
+
+ if( success )
+ {
+ // Delete auto save file.
+ wxFileName autoSaveFileName = schematicFileName;
+ autoSaveFileName.SetName( AUTOSAVE_PREFIX_FILENAME + schematicFileName.GetName() );
+
+ if( autoSaveFileName.FileExists() )
+ {
+ wxLogTrace( traceAutoSave,
+ wxT( "Removing auto save file <" ) + autoSaveFileName.GetFullPath() +
+ wxT( ">" ) );
+
+ wxRemoveFile( autoSaveFileName.GetFullPath() );
+ }
+
+ // Update the screen and frame info.
+ if( aSaveUnderNewName )
+ aScreen->SetFileName( schematicFileName.GetFullPath() );
+ aScreen->ClrSave();
+ aScreen->ClrModify();
+
+ msg.Printf( _( "File %s saved" ), GetChars( aScreen->GetFileName() ) );
+ SetStatusText( msg, 0 );
+ }
+ else
+ {
+ DisplayError( this, _( "File write operation failed." ) );
+ }
+
+ fclose( f );
+
+ return success;
+}
+
+
+void SCH_EDIT_FRAME::Save_File( wxCommandEvent& event )
+{
+ int id = event.GetId();
+
+ switch( id )
+ {
+ case ID_UPDATE_ONE_SHEET:
+ SaveEEFile( NULL );
+ break;
+
+ case ID_SAVE_ONE_SHEET_UNDER_NEW_NAME:
+ if( SaveEEFile( NULL, true ) )
+ {
+ CreateArchiveLibraryCacheFile( true );
+ }
+ break;
+ }
+
+ UpdateTitle();
+}
+
+
+bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
+{
+ // implement the pseudo code from KIWAY_PLAYER.h:
+
+ SCH_SCREENS screenList;
+
+ // This is for python:
+ if( aFileSet.size() != 1 )
+ {
+ UTF8 msg = StrPrintf( "Eeschema:%s() takes only a single filename", __func__ );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ wxString fullFileName( aFileSet[0] );
+
+ // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
+ wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(),
+ wxT( "bug in single_top.cpp or project manager." ) );
+
+ if( !LockFile( fullFileName ) )
+ {
+ wxString msg = wxString::Format( _(
+ "Schematic file '%s' is already open." ),
+ GetChars( fullFileName )
+ );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ // save any currently open and modified project files.
+ for( SCH_SCREEN* screen = screenList.GetFirst(); screen; screen = screenList.GetNext() )
+ {
+ if( screen->IsModify() )
+ {
+ int response = YesNoCancelDialog( this, _(
+ "The current schematic has been modified. Do you wish to save the changes?" ),
+ wxEmptyString,
+ _( "Save and Load" ),
+ _( "Load Without Saving" )
+ );
+
+ if( response == wxID_CANCEL )
+ {
+ return false;
+ }
+ else if( response == wxID_YES )
+ {
+ wxCommandEvent dummy;
+ OnSaveProject( dummy );
+ }
+ else
+ {
+ // response == wxID_NO, fall thru
+ }
+ break;
+ }
+ }
+
+ wxFileName pro = fullFileName;
+ pro.SetExt( ProjectFileExtension );
+
+ bool is_new = !wxFileName::IsFileReadable( fullFileName );
+
+ // If its a non-existent schematic and caller thinks it exists
+ if( is_new && !( aCtl & KICTL_CREATE ) )
+ {
+ // notify user that fullFileName does not exist, ask if user wants to create it.
+ wxString ask = wxString::Format( _(
+ "Schematic '%s' does not exist. Do you wish to create it?" ),
+ GetChars( fullFileName )
+ );
+ if( !IsOK( this, ask ) )
+ return false;
+ }
+
+ // unload current project file before loading new
+ {
+ delete g_RootSheet;
+ g_RootSheet = NULL;
+
+ CreateScreens();
+ }
+
+ GetScreen()->SetFileName( fullFileName );
+ g_RootSheet->SetFileName( fullFileName );
+
+ SetStatusText( wxEmptyString );
+ ClearMsgPanel();
+
+ wxString msg = wxString::Format( _(
+ "Ready\nProject dir: '%s'\n" ),
+ GetChars( wxPathOnly( Prj().GetProjectFullName() ) )
+ );
+ SetStatusText( msg );
+
+ // PROJECT::SetProjectFullName() is an impactful function. It should only be
+ // called under carefully considered circumstances.
+
+ // The calling code should know not to ask me here to change projects unless
+ // it knows what consequences that will have on other KIFACEs running and using
+ // this same PROJECT. It can be very harmful if that calling code is stupid.
+ Prj().SetProjectFullName( pro.GetFullPath() );
+
+ LoadProjectFile();
+
+ // load the libraries here, not in SCH_SCREEN::Draw() which is a context
+ // that will not tolerate DisplayError() dialog since we're already in an
+ // event handler in there.
+ // And when a schematic file is loaded, we need these libs to initialize
+ // some parameters (links to PART LIB, dangling ends ...)
+ Prj().SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL );
+ Prj().SchLibs();
+
+ if( is_new )
+ {
+ // mark new, unsaved file as modified.
+ GetScreen()->SetModify();
+ }
+ else
+ {
+ g_RootSheet->SetScreen( NULL );
+
+ DBG( printf( "%s: loading schematic %s\n", __func__, TO_UTF8( fullFileName ) );)
+
+ bool diag = g_RootSheet->Load( this );
+ (void) diag;
+
+ SetScreen( m_CurrentSheet->LastScreen() );
+
+ GetScreen()->ClrModify();
+
+ UpdateFileHistory( fullFileName );
+
+ // Check to see whether some old library parts need to be rescued
+ // Only do this if RescueNeverShow was not set.
+ wxConfigBase *config = Kiface().KifaceSettings();
+ bool rescueNeverShow = false;
+ config->Read( RESCUE_NEVER_SHOW_KEY, &rescueNeverShow, false );
+
+ if( !rescueNeverShow )
+ {
+ if( RescueProject( false ) )
+ {
+ GetScreen()->CheckComponentsToPartsLinks();
+ GetScreen()->TestDanglingEnds();
+ }
+ }
+ }
+
+ GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
+ Zoom_Automatique( false );
+ SetSheetNumberAndCount();
+
+ m_canvas->Refresh( true );
+
+ return true;
+}
+
+
+bool SCH_EDIT_FRAME::AppendOneEEProject()
+{
+ wxString fullFileName;
+
+ SCH_SCREEN* screen = GetScreen();
+
+ if( !screen )
+ {
+ wxLogError( wxT("Document not ready, cannot import") );
+ return false;
+ }
+
+ // open file chooser dialog
+ wxString path = wxPathOnly( Prj().GetProjectFullName() );
+
+ wxFileDialog dlg( this, _( "Import Schematic" ), path,
+ wxEmptyString, SchematicFileWildcard,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return false;
+
+ fullFileName = dlg.GetPath();
+
+ wxFileName fn = fullFileName;
+
+ if( fn.IsRelative() )
+ {
+ fn.MakeAbsolute();
+ fullFileName = fn.GetFullPath();
+ }
+
+ wxString cache_name = PART_LIBS::CacheName( fullFileName );
+ if( !!cache_name )
+ {
+ PART_LIBS* libs = Prj().SchLibs();
+
+ if( PART_LIB* lib = libs->AddLibrary( cache_name ) )
+ lib->SetCache();
+ }
+
+ wxLogDebug( wxT( "Importing schematic " ) + fullFileName );
+
+ // Keep trace of the last item in list.
+ // New items will be loaded after this one.
+ SCH_ITEM* bs = screen->GetDrawItems();
+
+ if( bs )
+ while( bs->Next() )
+ bs = bs->Next();
+
+ // load the project
+ bool success = LoadOneEEFile( screen, fullFileName, true );
+
+ if( success )
+ {
+ // the new loaded items need cleaning to avoid duplicate parameters
+ // which should be unique (ref and time stamp).
+ // Clear ref and set a new time stamp for new items
+ if( bs == NULL )
+ bs = screen->GetDrawItems();
+ else
+ bs = bs->Next();
+
+ while( bs )
+ {
+ SCH_ITEM* nextbs = bs->Next();
+
+ // To avoid issues with the current hieratchy,
+ // do not load included sheets files and give new filenames
+ // and new sheet names.
+ // There are many tricky cases (loops, creation of complex hierarchies
+ // with duplicate file names, duplicate sheet names...)
+ // So the included sheets names are renamed if existing,
+ // and filenames are just renamed to avoid loops and
+ // creation of complex hierarchies.
+ // If someone want to change it for a better append function, remember
+ // these cases need work to avoid issues.
+ if( bs->Type() == SCH_SHEET_T )
+ {
+ SCH_SHEET * sheet = (SCH_SHEET *) bs;
+ time_t newtimestamp = GetNewTimeStamp();
+ sheet->SetTimeStamp( newtimestamp );
+
+ // Check for existing subsheet name in the current sheet
+ wxString tmp = sheet->GetName();
+ sheet->SetName( wxEmptyString );
+ const SCH_SHEET* subsheet = GetScreen()->GetSheet( tmp );
+
+ if( subsheet )
+ sheet->SetName( wxString::Format( wxT( "Sheet%8.8lX" ), (long) newtimestamp ) );
+ else
+ sheet->SetName( tmp );
+
+ sheet->SetFileName( wxString::Format( wxT( "file%8.8lX.sch" ), (long) newtimestamp ) );
+ SCH_SCREEN* screen = new SCH_SCREEN( &Kiway() );
+ screen->SetMaxUndoItems( m_UndoRedoCountMax );
+ sheet->SetScreen( screen );
+ sheet->GetScreen()->SetFileName( sheet->GetFileName() );
+ }
+ // clear annotation and init new time stamp for the new components
+ else if( bs->Type() == SCH_COMPONENT_T )
+ {
+ ( (SCH_COMPONENT*) bs )->SetTimeStamp( GetNewTimeStamp() );
+ ( (SCH_COMPONENT*) bs )->ClearAnnotation( NULL );
+
+ // Clear flags, which are set by these previous modifications:
+ bs->ClearFlags();
+ }
+
+ bs = nextbs;
+ }
+ }
+
+ OnModify();
+
+ // redraw base screen (ROOT) if necessary
+ GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
+ Zoom_Automatique( false );
+ SetSheetNumberAndCount();
+ m_canvas->Refresh( true );
+ return success;
+}
+
+
+void SCH_EDIT_FRAME::OnAppendProject( wxCommandEvent& event )
+{
+ wxString msg = _( "This operation cannot be undone. "
+ "Besides, take into account that hierarchical sheets will not be appended.\n\n"
+ "Do you want to save the current document before proceeding?" );
+
+ if( IsOK( this, msg ) )
+ OnSaveProject( event );
+
+ AppendOneEEProject();
+}
+
+
+void SCH_EDIT_FRAME::OnSaveProject( wxCommandEvent& aEvent )
+{
+ SCH_SCREEN* screen;
+ SCH_SCREENS screenList;
+
+ // I want to see it in the debugger, show me the string! Can't do that with wxFileName.
+ wxString fileName = Prj().AbsolutePath( g_RootSheet->GetFileName() );
+
+ wxFileName fn = fileName;
+
+ if( !fn.IsDirWritable() )
+ {
+ wxString msg = wxString::Format( _(
+ "Directory '%s' is not writable" ),
+ GetChars( fn.GetPath() )
+ );
+
+ DisplayError( this, msg );
+ return;
+ }
+
+ for( screen = screenList.GetFirst(); screen; screen = screenList.GetNext() )
+ SaveEEFile( screen );
+
+ CreateArchiveLibraryCacheFile();
+
+ UpdateTitle();
+}
+
+
+bool SCH_EDIT_FRAME::doAutoSave()
+{
+ wxFileName tmpFileName = g_RootSheet->GetFileName();
+ wxFileName fn = tmpFileName;
+ wxFileName tmp;
+ SCH_SCREENS screens;
+
+ bool autoSaveOk = true;
+
+ tmp.AssignDir( fn.GetPath() );
+
+ if( !tmp.IsOk() )
+ return false;
+
+ if( !IsWritable( tmp ) )
+ return false;
+
+ for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
+ {
+ // Only create auto save files for the schematics that have been modified.
+ if( !screen->IsSave() )
+ continue;
+
+ tmpFileName = fn = screen->GetFileName();
+
+ // Auto save file name is the normal file name prefixed with AUTOSAVE_PREFIX_FILENAME.
+ fn.SetName( AUTOSAVE_PREFIX_FILENAME + fn.GetName() );
+
+ screen->SetFileName( fn.GetFullPath() );
+
+ if( SaveEEFile( screen, false, NO_BACKUP_FILE ) )
+ screen->SetModify();
+ else
+ autoSaveOk = false;
+
+ screen->SetFileName( tmpFileName.GetFullPath() );
+ }
+
+ if( autoSaveOk )
+ m_autoSaveState = false;
+
+ return autoSaveOk;
+}
diff --git a/eeschema/find.cpp b/eeschema/find.cpp
new file mode 100644
index 0000000..5109acd
--- /dev/null
+++ b/eeschema/find.cpp
@@ -0,0 +1,515 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/find.cpp
+ * @brief Functions for searching for a schematic item.
+ */
+
+/*
+ * Search a text (text, value, reference) within a component or
+ * search a component in libraries, a marker ...,
+ * in current sheet or whole the project
+ */
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <schframe.h>
+#include <base_units.h>
+
+#include <general.h>
+#include <class_library.h>
+#include <lib_pin.h>
+#include <sch_marker.h>
+#include <sch_component.h>
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+
+#include <kicad_device_context.h>
+
+#include <boost/foreach.hpp>
+
+#include <dialogs/dialog_schematic_find.h>
+
+
+void SCH_EDIT_FRAME::OnFindDrcMarker( wxFindDialogEvent& event )
+{
+ static SCH_MARKER* lastMarker = NULL;
+
+ wxString msg;
+ SCH_SHEET_LIST schematic;
+ SCH_SHEET_PATH* sheetFoundIn = NULL;
+ bool wrap = ( event.GetFlags() & FR_SEARCH_WRAP ) != 0;
+ bool warpCursor = ( ( event.GetId() == wxEVT_COMMAND_FIND_CLOSE ) ||
+ !( event.GetFlags() & FR_NO_WARP_CURSOR ) );
+
+ if( event.GetFlags() & FR_CURRENT_SHEET_ONLY )
+ {
+ sheetFoundIn = m_CurrentSheet;
+ lastMarker = (SCH_MARKER*) m_CurrentSheet->FindNextItem( SCH_MARKER_T, lastMarker, wrap );
+ }
+ else
+ {
+ lastMarker = (SCH_MARKER*) schematic.FindNextItem( SCH_MARKER_T, &sheetFoundIn,
+ lastMarker, wrap );
+ }
+
+ if( lastMarker != NULL )
+ {
+ if( *sheetFoundIn != *m_CurrentSheet )
+ {
+ sheetFoundIn->LastScreen()->SetZoom( GetScreen()->GetZoom() );
+ *m_CurrentSheet = *sheetFoundIn;
+ m_CurrentSheet->UpdateAllScreenReferences();
+ }
+
+ SetCrossHairPosition( lastMarker->GetPosition() );
+
+ RedrawScreen( lastMarker->GetPosition(), warpCursor );
+
+ wxString path = sheetFoundIn->Path();
+ wxString units = GetAbbreviatedUnitsLabel();
+ double x = To_User_Unit( g_UserUnit, (double) lastMarker->GetPosition().x );
+ double y = To_User_Unit( g_UserUnit, (double) lastMarker->GetPosition().y );
+ msg.Printf( _( "Design rule check marker found in sheet %s at %0.3f%s, %0.3f%s" ),
+ GetChars( path ), x, GetChars( units ), y, GetChars( units) );
+ SetStatusText( msg );
+ }
+ else
+ {
+ SetStatusText( _( "No more markers were found." ) );
+ }
+}
+
+
+SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference,
+ bool aSearchHierarchy,
+ SCH_SEARCH_T aSearchType,
+ const wxString& aSearchText,
+ bool aWarpMouse )
+{
+ SCH_SHEET_PATH* sheet;
+ SCH_SHEET_PATH* sheetWithComponentFound = NULL;
+ SCH_ITEM* item = NULL;
+ SCH_COMPONENT* Component = NULL;
+ wxPoint pos;
+ bool centerAndRedraw = false;
+ bool notFound = true;
+ LIB_PIN* pin;
+ SCH_SHEET_LIST sheetList;
+
+ sheet = sheetList.GetFirst();
+
+ if( !aSearchHierarchy )
+ sheet = m_CurrentSheet;
+
+ for( ; sheet != NULL; sheet = sheetList.GetNext() )
+ {
+ item = sheet->LastDrawList();
+
+ for( ; ( item != NULL ) && ( notFound == true ); item = item->Next() )
+ {
+ if( item->Type() != SCH_COMPONENT_T )
+ continue;
+
+ SCH_COMPONENT* pSch = (SCH_COMPONENT*) item;
+
+ if( aReference.CmpNoCase( pSch->GetRef( sheet ) ) == 0 )
+ {
+ Component = pSch;
+ sheetWithComponentFound = sheet;
+
+ switch( aSearchType )
+ {
+ default:
+ case FIND_COMPONENT_ONLY: // Find component only
+ notFound = false;
+ pos = pSch->GetPosition();
+ break;
+
+ case FIND_PIN: // find a pin
+ pos = pSch->GetPosition(); // temporary: will be changed if the pin is found.
+ pin = pSch->GetPin( aSearchText );
+
+ if( pin == NULL )
+ break;
+
+ notFound = false;
+ pos += pin->GetPosition();
+ break;
+
+ case FIND_REFERENCE: // find reference
+ notFound = false;
+ pos = pSch->GetField( REFERENCE )->GetPosition();
+ break;
+
+ case FIND_VALUE: // find value
+ pos = pSch->GetPosition();
+
+ if( aSearchText.CmpNoCase( pSch->GetField( VALUE )->GetShownText() ) != 0 )
+ break;
+
+ notFound = false;
+ pos = pSch->GetField( VALUE )->GetPosition();
+ break;
+ }
+ }
+ }
+
+ if( (aSearchHierarchy == false) || (notFound == false) )
+ break;
+ }
+
+ if( Component )
+ {
+ sheet = sheetWithComponentFound;
+
+ if( *sheet != *m_CurrentSheet )
+ {
+ sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
+ *m_CurrentSheet = *sheet;
+ m_CurrentSheet->UpdateAllScreenReferences();
+ centerAndRedraw = true;
+ }
+
+ wxPoint delta;
+ pos -= Component->GetPosition();
+ delta = Component->GetTransform().TransformCoordinate( pos );
+ pos = delta + Component->GetPosition();
+
+
+ /* There may be need to reframe the drawing */
+ if( ! m_canvas->IsPointOnDisplay( pos ) )
+ {
+ centerAndRedraw = true;
+ }
+
+ if( centerAndRedraw )
+ {
+ SetCrossHairPosition( pos );
+ RedrawScreen( pos, aWarpMouse );
+ }
+
+ else
+ {
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ m_canvas->CrossHairOff( &dc );
+
+ if( aWarpMouse )
+ m_canvas->MoveCursor( pos );
+
+ SetCrossHairPosition( pos );
+
+ m_canvas->CrossHairOn( &dc );
+ }
+ }
+
+
+ /* Print diag */
+ wxString msg_item;
+ wxString msg;
+
+ switch( aSearchType )
+ {
+ default:
+ case FIND_COMPONENT_ONLY: // Find component only
+ msg_item = _( "component" );
+ break;
+
+ case FIND_PIN: // find a pin
+ msg_item.Printf( _( "pin %s" ), GetChars( aSearchText ) );
+ break;
+
+ case FIND_REFERENCE: // find reference
+ msg_item.Printf( _( "reference %s" ), GetChars( aSearchText ) );
+ break;
+
+ case FIND_VALUE: // find value
+ msg_item.Printf( _( "value %s" ), GetChars( aSearchText ) );
+ break;
+
+ case FIND_FIELD: // find field. todo
+ msg_item.Printf( _( "field %s" ), GetChars( aSearchText ) );
+ break;
+ }
+
+ if( Component )
+ {
+ if( !notFound )
+ {
+ msg.Printf( _( "%s %s found" ),
+ GetChars( aReference ), GetChars( msg_item ) );
+ }
+ else
+ {
+ msg.Printf( _( "%s found but %s not found" ),
+ GetChars( aReference ), GetChars( msg_item ) );
+ }
+ }
+ else
+ {
+ msg.Printf( _( "Component %s not found" ),
+ GetChars( aReference ) );
+ }
+
+ SetStatusText( msg );
+
+ return item;
+}
+
+
+bool SCH_EDIT_FRAME::IsSearchCacheObsolete( const SCH_FIND_REPLACE_DATA& aSearchCriteria )
+{
+ PART_LIBS* libs = Prj().SchLibs();
+ int mod_hash = libs->GetModifyHash();
+
+ // the cache is obsolete whenever any library changes.
+ if( mod_hash != m_foundItems.GetLibHash() )
+ {
+ m_foundItems.SetForceSearch();
+ m_foundItems.SetLibHash( mod_hash );
+ return true;
+ }
+ else if( m_foundItems.IsSearchRequired( aSearchCriteria ) )
+ return true;
+ else
+ return false;
+}
+
+
+void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
+{
+ SCH_FIND_REPLACE_DATA searchCriteria;
+ SCH_FIND_COLLECTOR_DATA data;
+
+ searchCriteria.SetFlags( aEvent.GetFlags() );
+ searchCriteria.SetFindString( aEvent.GetFindString() );
+ searchCriteria.SetReplaceString( aEvent.GetReplaceString() );
+
+ if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE )
+ {
+ if( m_foundItems.GetCount() == 0 )
+ return;
+
+ // Refresh the search cache in case something has changed. This prevents any stale
+ // pointers from crashing Eeschema when the wxEVT_FIND_CLOSE event is handled.
+ if( IsSearchCacheObsolete( searchCriteria ) )
+ {
+ if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
+ {
+ m_foundItems.Collect( searchCriteria, m_CurrentSheet );
+ }
+ else
+ {
+ m_foundItems.Collect( searchCriteria );
+ }
+ }
+ }
+ else if( IsSearchCacheObsolete( searchCriteria ) )
+ {
+ if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
+ {
+ m_foundItems.Collect( searchCriteria, m_CurrentSheet );
+ }
+ else
+ {
+ m_foundItems.Collect( searchCriteria );
+ }
+ }
+ else
+ {
+ EDA_ITEM* currentItem = m_foundItems.GetItem( data );
+
+ if( currentItem != NULL )
+ currentItem->SetForceVisible( false );
+
+ m_foundItems.UpdateIndex();
+ }
+
+ updateFindReplaceView( aEvent );
+}
+
+
+void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent )
+{
+ static int nextFoundIndex = 0;
+ SCH_ITEM* item;
+ SCH_SHEET_PATH* sheet;
+ SCH_SHEET_LIST schematic;
+ SCH_FIND_COLLECTOR_DATA data;
+ SCH_FIND_REPLACE_DATA searchCriteria;
+
+ searchCriteria.SetFlags( aEvent.GetFlags() );
+ searchCriteria.SetFindString( aEvent.GetFindString() );
+ searchCriteria.SetReplaceString( aEvent.GetReplaceString() );
+ m_foundItems.SetReplaceString( aEvent.GetReplaceString() );
+
+ if( IsSearchCacheObsolete( searchCriteria ) )
+ {
+ if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
+ {
+ m_foundItems.Collect( searchCriteria, m_CurrentSheet );
+ }
+ else
+ {
+ m_foundItems.Collect( searchCriteria );
+ }
+
+ // Restore the next found index on cache refresh. Prevents single replace events
+ // from starting back at the beginning of the cache.
+ m_foundItems.SetFoundIndex( nextFoundIndex );
+ }
+
+ if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_REPLACE_ALL )
+ {
+ while( ( item = (SCH_ITEM*) m_foundItems.GetItem( data ) ) != NULL )
+ {
+ SCH_ITEM* undoItem = data.GetParent();
+
+ // Don't save child items in undo list.
+ if( undoItem == NULL )
+ undoItem = item;
+
+ SetUndoItem( undoItem );
+
+ sheet = schematic.GetSheetByPath( data.GetSheetPath() );
+
+ wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " ) + data.GetSheetPath() );
+
+ if( m_foundItems.ReplaceItem( sheet ) )
+ {
+ OnModify();
+ SaveUndoItemInUndoList( undoItem );
+ updateFindReplaceView( aEvent );
+ }
+
+ m_foundItems.IncrementIndex();
+
+ if( m_foundItems.PassedEnd() )
+ break;
+ }
+ }
+ else
+ {
+ item = (SCH_ITEM*) m_foundItems.GetItem( data );
+
+ wxCHECK_RET( item != NULL, wxT( "Invalid replace item in find collector list." ) );
+
+ SCH_ITEM* undoItem = data.GetParent();
+
+ if( undoItem == NULL )
+ undoItem = item;
+
+ SetUndoItem( undoItem );
+
+ sheet = schematic.GetSheetByPath( data.GetSheetPath() );
+
+ wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " ) + data.GetSheetPath() );
+
+ if( m_foundItems.ReplaceItem( sheet ) )
+ {
+ OnModify();
+ SaveUndoItemInUndoList( undoItem );
+ updateFindReplaceView( aEvent );
+ }
+
+ m_foundItems.IncrementIndex();
+ nextFoundIndex = m_foundItems.GetFoundIndex();
+ }
+
+ // End the replace if we are at the end if the list. This prevents an infinite loop if
+ // wrap search is selected and all of the items have been replaced with a value that
+ // still satisfies the search criteria.
+ if( m_foundItems.PassedEnd() )
+ aEvent.SetFlags( aEvent.GetFlags() & ~FR_REPLACE_ITEM_FOUND );
+}
+
+
+void SCH_EDIT_FRAME::updateFindReplaceView( wxFindDialogEvent& aEvent )
+{
+ wxString msg;
+ SCH_SHEET_LIST schematic;
+ SCH_FIND_COLLECTOR_DATA data;
+ SCH_FIND_REPLACE_DATA searchCriteria;
+ bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR );
+
+ searchCriteria.SetFlags( aEvent.GetFlags() );
+ searchCriteria.SetFindString( aEvent.GetFindString() );
+ searchCriteria.SetReplaceString( aEvent.GetReplaceString() );
+
+ if( m_foundItems.GetItem( data ) != NULL )
+ {
+ wxLogTrace( traceFindReplace, wxT( "Found " ) + m_foundItems.GetText() );
+
+ SCH_SHEET_PATH* sheet = schematic.GetSheetByPath( data.GetSheetPath() );
+
+ wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " ) +
+ data.GetSheetPath() );
+
+ SCH_ITEM* item = (SCH_ITEM*)m_foundItems.GetItem( data );
+
+ // Make the item temporarily visible just in case it's hide flag is set. This
+ // has no effect on objects that don't support hiding. If this is a close find
+ // dialog event, clear the temporary visibility flag.
+ if( item )
+ {
+ if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE )
+ item->SetForceVisible( false );
+ else if( item->Type() == SCH_FIELD_T && !( (SCH_FIELD*) item )->IsVisible() )
+ item->SetForceVisible( true );
+ }
+
+ if( sheet->PathHumanReadable() != m_CurrentSheet->PathHumanReadable() )
+ {
+ sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
+ *m_CurrentSheet = *sheet;
+ m_CurrentSheet->UpdateAllScreenReferences();
+ SetScreen( sheet->LastScreen() );
+ }
+
+ // careful here
+ SetCrossHairPosition( data.GetPosition() );
+
+ RedrawScreen( data.GetPosition(), warpCursor );
+
+ msg = m_foundItems.GetText();
+
+ if( aEvent.GetFlags() & FR_SEARCH_REPLACE )
+ aEvent.SetFlags( aEvent.GetFlags() | FR_REPLACE_ITEM_FOUND );
+ }
+ else
+ {
+ if( aEvent.GetFlags() & FR_SEARCH_REPLACE )
+ aEvent.SetFlags( aEvent.GetFlags() & ~FR_REPLACE_ITEM_FOUND );
+
+ msg.Printf( _( "No item found matching %s." ), GetChars( aEvent.GetFindString() ) );
+ }
+
+ SetStatusText( msg );
+}
diff --git a/eeschema/general.h b/eeschema/general.h
new file mode 100644
index 0000000..7f8b147
--- /dev/null
+++ b/eeschema/general.h
@@ -0,0 +1,150 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file general.h
+ */
+
+#ifndef _GENERAL_H_
+#define _GENERAL_H_
+
+#include <colors.h> // for EDA_COLOR_T
+
+class TRANSFORM;
+class SCH_SHEET;
+
+#define EESCHEMA_VERSION 2
+#define SCHEMATIC_HEAD_STRING "Schematic File Version"
+
+#define TXTMARGE 10 // Offset in mils for placement of labels and pin numbers
+#define DANGLING_SYMBOL_SIZE 12
+
+
+#define DEFAULT_REPEAT_OFFSET_X 0 ///< the default X value (overwritten by the eeschema config)
+#define DEFAULT_REPEAT_OFFSET_Y 100 ///< the default Y value (overwritten by the eeschema config)
+#define REPEAT_OFFSET_MAX 1000 ///< the max value of repeat offset value
+#define DEFAULT_REPEAT_LABEL_INC 1 ///< the default value (overwritten by the eeschema config)
+#define DEFAULT_REPEAT_OFFSET_PIN 100 ///< the default value (overwritten by the eeschema config)
+ ///< when repeating a pin
+
+///< The thickness to draw busses that do not have a specific width
+///< (can be changed in preference menu)
+#define DEFAULTBUSTHICKNESS 12
+
+///< The thickness to draw lines that thickness is set to 0 (default thickness)
+///< (can be changed in preference menu)
+#define DEFAULTDRAWLINETHICKNESS 6
+
+///< The default pin len value when creating pins(can be changed in preference menu)
+#define DEFAULTPINLENGTH 200
+
+///< The default pin len value when creating pins(can be changed in preference menu)
+#define DEFAULTPINNUMSIZE 50
+
+///< The default pin len value when creating pins(can be changed in preference menu)
+#define DEFAULTPINNAMESIZE 50
+
+#define GR_DEFAULT_DRAWMODE GR_COPY
+
+// this enum is for color management
+// Using here "LAYER" in name is due to historical reasons.
+// Eeschema does not actually use layers. It just uses "LAYER_XX" as identifier
+// mainly for item color
+typedef enum {
+ LAYER_FIRST,
+ LAYER_WIRE = LAYER_FIRST,
+ LAYER_BUS,
+ LAYER_JUNCTION,
+ LAYER_LOCLABEL,
+ LAYER_GLOBLABEL,
+ LAYER_HIERLABEL,
+ LAYER_PINNUM,
+ LAYER_PINNAM,
+ LAYER_REFERENCEPART,
+ LAYER_VALUEPART,
+ LAYER_FIELDS,
+ LAYER_DEVICE,
+ LAYER_NOTES,
+ LAYER_NETNAM,
+ LAYER_PIN,
+ LAYER_SHEET,
+ LAYER_SHEETNAME,
+ LAYER_SHEETFILENAME,
+ LAYER_SHEETLABEL,
+ LAYER_NOCONNECT,
+ LAYER_ERC_WARN,
+ LAYER_ERC_ERR,
+ LAYER_DEVICE_BACKGROUND,
+ LAYER_GRID,
+ LAYER_BACKGROUND,
+ LAYERSCH_ID_COUNT
+} LAYERSCH_ID;
+
+inline LAYERSCH_ID operator++( LAYERSCH_ID& a )
+{
+ a = LAYERSCH_ID( int( a ) + 1 );
+ return a;
+}
+
+
+/* Rotation, mirror of graphic items in components bodies are handled by a
+ * transform matrix. The default matrix is useful to draw lib entries with
+ * using this default matrix ( no rotation, no mirror but Y axis is bottom to top, and
+ * Y draw axis is to to bottom so we must have a default matrix that reverses
+ * the Y coordinate and keeps the X coordiate
+ */
+extern TRANSFORM DefaultTransform;
+
+/* First and main (root) screen */
+extern SCH_SHEET* g_RootSheet;
+
+/**
+ * Default line thickness used to draw/plot items having a
+ * default thickness line value (i.e. = 0 ).
+ */
+int GetDefaultLineThickness();
+void SetDefaultLineThickness( int aThickness );
+
+/**
+ * Default size for text in general
+ */
+int GetDefaultTextSize();
+void SetDefaultTextSize( int aSize );
+
+/**
+ * Default line thickness used to draw/plot busses.
+ */
+int GetDefaultBusThickness();
+void SetDefaultBusThickness( int aThickness );
+
+EDA_COLOR_T GetLayerColor( LAYERSCH_ID aLayer );
+void SetLayerColor( EDA_COLOR_T aColor, LAYERSCH_ID aLayer );
+
+// Color to draw selected items
+EDA_COLOR_T GetItemSelectedColor();
+
+// Color to draw items flagged invisible, in libedit (they are invisible in Eeschema
+EDA_COLOR_T GetInvisibleItemColor();
+
+#endif // _GENERAL_H_
diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp
new file mode 100644
index 0000000..8c8db7e
--- /dev/null
+++ b/eeschema/getpart.cpp
@@ -0,0 +1,402 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file getpart.cpp
+ * @brief functions to get and place library components.
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiway.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <schframe.h>
+#include <kicad_device_context.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <class_library.h>
+#include <sch_component.h>
+#include <libeditframe.h>
+#include <viewlib_frame.h>
+#include <eeschema_id.h>
+
+#include <dialog_choose_component.h>
+#include <component_tree_search_container.h>
+#include <dialog_get_component.h>
+
+#include <boost/foreach.hpp>
+
+
+wxString SCH_BASE_FRAME::SelectComponentFromLibBrowser( const SCHLIB_FILTER* aFilter,
+ LIB_ALIAS* aPreselectedAlias,
+ int* aUnit, int* aConvert )
+{
+ // Close any open non-modal Lib browser, and open a new one, in "modal" mode:
+ LIB_VIEW_FRAME* viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, false );
+
+ if( viewlibFrame )
+ viewlibFrame->Destroy();
+
+ viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER_MODAL, true );
+
+ if( aFilter )
+ viewlibFrame->SetFilter( aFilter );
+
+ if( aPreselectedAlias )
+ {
+ viewlibFrame->SetSelectedLibrary( aPreselectedAlias->GetLibraryName() );
+ viewlibFrame->SetSelectedComponent( aPreselectedAlias->GetName() );
+ }
+
+ if( aUnit && *aUnit > 0 )
+ viewlibFrame->SetUnit( *aUnit );
+
+ if( aConvert && *aConvert > 0 )
+ viewlibFrame->SetConvert( *aConvert );
+
+ viewlibFrame->Refresh();
+
+ wxString cmpname;
+
+ if( viewlibFrame->ShowModal( &cmpname, this ) )
+ {
+ if( aUnit )
+ *aUnit = viewlibFrame->GetUnit();
+
+ if( aConvert )
+ *aConvert = viewlibFrame->GetConvert();
+ }
+
+ viewlibFrame->Destroy();
+
+ return cmpname;
+}
+
+
+wxString SCH_BASE_FRAME::SelectComponentFromLibrary( const SCHLIB_FILTER* aFilter,
+ wxArrayString& aHistoryList,
+ int& aHistoryLastUnit,
+ bool aUseLibBrowser,
+ int* aUnit,
+ int* aConvert )
+{
+ wxString dialogTitle;
+ PART_LIBS* libs = Prj().SchLibs();
+
+ COMPONENT_TREE_SEARCH_CONTAINER search_container( libs ); // Container doing search-as-you-type
+ bool loaded = false;
+
+ if( aFilter )
+ {
+ const wxArrayString& liblist = aFilter->GetAllowedLibList();
+
+ for( unsigned ii = 0; ii < liblist.GetCount(); ii++ )
+ {
+ PART_LIB* currLibrary = libs->FindLibrary( liblist[ii] );
+
+ if( currLibrary )
+ {
+ loaded = true;
+ search_container.AddLibrary( *currLibrary );
+ }
+ }
+
+ if( aFilter->GetFilterPowerParts() )
+ search_container.SetFilter( COMPONENT_TREE_SEARCH_CONTAINER::CMP_FILTER_POWER );
+
+ }
+
+ if( !loaded )
+ {
+ BOOST_FOREACH( PART_LIB& lib, *libs )
+ {
+ search_container.AddLibrary( lib );
+ }
+ }
+
+
+ if( !aHistoryList.empty() )
+ {
+ // This is good for a transition for experienced users: giving them a History. Ideally,
+ // we actually make this part even faster to access with a popup on ALT-a or something.
+ // the history is under a node named "-- History --"
+ // However, because it is translatable, and we need to have a node name starting by "-- "
+ // because we (later) sort all node names alphabetically and this node should be the first,
+ // we build it with only with "History" string translatable
+ wxString nodename;
+ nodename << wxT("-- ") << _("History") << wxT(" --");
+ search_container.AddAliasList( nodename, aHistoryList, NULL );
+ search_container.SetPreselectNode( aHistoryList[0], aHistoryLastUnit );
+ }
+
+ const int deMorgan = aConvert ? *aConvert : 1;
+ dialogTitle.Printf( _( "Choose Component (%d items loaded)" ), search_container.GetComponentsCount() );
+ DIALOG_CHOOSE_COMPONENT dlg( this, dialogTitle, &search_container, deMorgan );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return wxEmptyString;
+
+ wxString cmpName;
+ LIB_ALIAS* const alias = dlg.GetSelectedAlias( aUnit );
+ if ( alias )
+ cmpName = alias->GetName();
+
+ if( dlg.IsExternalBrowserSelected() ) // User requested component browser.
+ cmpName = SelectComponentFromLibBrowser( aFilter, alias, aUnit, aConvert);
+
+ if( !cmpName.empty() )
+ {
+ AddHistoryComponentName( aHistoryList, cmpName );
+ if ( aUnit ) aHistoryLastUnit = *aUnit;
+ }
+
+ return cmpName;
+}
+
+
+SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( wxDC* aDC,
+ const SCHLIB_FILTER* aFilter,
+ wxArrayString& aHistoryList,
+ int& aHistoryLastUnit,
+ bool aUseLibBrowser )
+{
+ int unit = 1;
+ int convert = 1;
+ SetRepeatItem( NULL );
+ m_canvas->SetIgnoreMouseEvents( true );
+
+ wxString name = SelectComponentFromLibrary( aFilter, aHistoryList, aHistoryLastUnit,
+ aUseLibBrowser, &unit, &convert );
+
+ if( name.IsEmpty() )
+ {
+ m_canvas->SetIgnoreMouseEvents( false );
+ m_canvas->MoveCursorToCrossHair();
+ return NULL;
+ }
+
+ m_canvas->SetIgnoreMouseEvents( false );
+ m_canvas->MoveCursorToCrossHair();
+
+ wxString libsource; // the library name to use. If empty, load from any lib
+
+ if( aFilter )
+ libsource = aFilter->GetLibSource();
+
+ LIB_PART* part = Prj().SchLibs()->FindLibPart( name, libsource );
+
+ if( !part )
+ {
+ wxString msg = wxString::Format( _(
+ "Failed to find part '%s' in library" ),
+ GetChars( name )
+ );
+ wxMessageBox( msg );
+ return NULL;
+ }
+
+ SCH_COMPONENT* component = new SCH_COMPONENT( *part, m_CurrentSheet, unit, convert,
+ GetCrossHairPosition(), true );
+
+ // Set the m_ChipName value, from component name in lib, for aliases
+ // Note if part is found, and if name is an alias of a component,
+ // alias exists because its root component was found
+ component->SetPartName( name );
+
+ // Be sure the link to the corresponding LIB_PART is OK:
+ component->Resolve( Prj().SchLibs() );
+
+ // Set the component value that can differ from component name in lib, for aliases
+ component->GetField( VALUE )->SetText( name );
+
+ MSG_PANEL_ITEMS items;
+
+ component->SetCurrentSheetPath( &GetCurrentSheet() );
+ component->GetMsgPanelInfo( items );
+
+ SetMsgPanel( items );
+ component->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode );
+ component->SetFlags( IS_NEW );
+ PrepareMoveItem( (SCH_ITEM*) component, aDC );
+
+ return component;
+}
+
+
+void SCH_EDIT_FRAME::OrientComponent( COMPONENT_ORIENTATION_T aOrientation )
+{
+ SCH_SCREEN* screen = GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+
+ wxCHECK_RET( item != NULL && item->Type() == SCH_COMPONENT_T,
+ wxT( "Cannot change orientation of invalid schematic item." ) );
+
+ SCH_COMPONENT* component = (SCH_COMPONENT*) item;
+
+ m_canvas->MoveCursorToCrossHair();
+
+ if( component->GetFlags() == 0 )
+ {
+ SaveCopyInUndoList( item, UR_CHANGED );
+ GetScreen()->SetCurItem( NULL );
+ }
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ // Erase the previous component in it's current orientation.
+
+ m_canvas->CrossHairOff( &dc );
+
+ if( component->GetFlags() )
+ component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode );
+ else
+ {
+ component->SetFlags( IS_MOVED ); // do not redraw the component
+ m_canvas->RefreshDrawingRect( component->GetBoundingBox() );
+ component->ClearFlags( IS_MOVED );
+ }
+
+ component->SetOrientation( aOrientation );
+
+ /* Redraw the component in the new position. */
+ if( component->GetFlags() )
+ component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode );
+ else
+ component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+
+ m_canvas->CrossHairOn( &dc );
+ GetScreen()->TestDanglingEnds( m_canvas, &dc );
+ OnModify();
+}
+
+
+/*
+ * Handle select part in multi-unit part.
+ */
+void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent )
+{
+ SCH_SCREEN* screen = GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+
+ wxCHECK_RET( item != NULL && item->Type() == SCH_COMPONENT_T,
+ wxT( "Cannot select unit of invalid schematic item." ) );
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ m_canvas->MoveCursorToCrossHair();
+
+ SCH_COMPONENT* component = (SCH_COMPONENT*) item;
+
+ int unit = aEvent.GetId() + 1 - ID_POPUP_SCH_SELECT_UNIT1;
+
+ if( LIB_PART* part = Prj().SchLibs()->FindLibPart( component->GetPartName() ) )
+ {
+ int unitCount = part->GetUnitCount();
+
+ wxCHECK_RET( (unit >= 1) && (unit <= unitCount),
+ wxString::Format( wxT( "Cannot select unit %d from component " ), unit ) +
+ part->GetName() );
+
+ if( unitCount <= 1 || component->GetUnit() == unit )
+ return;
+
+ if( unit > unitCount )
+ unit = unitCount;
+
+ STATUS_FLAGS flags = component->GetFlags();
+
+ if( !flags ) // No command in progress: save in undo list
+ SaveCopyInUndoList( component, UR_CHANGED );
+
+ if( flags )
+ component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode, g_GhostColor );
+ else
+ component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode );
+
+ /* Update the unit number. */
+ component->SetUnitSelection( m_CurrentSheet, unit );
+ component->SetUnit( unit );
+ component->ClearFlags();
+ component->SetFlags( flags ); // Restore m_Flag modified by SetUnit()
+
+ /* Redraw the component in the new position. */
+ if( flags )
+ component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode, g_GhostColor );
+ else
+ component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+
+ screen->TestDanglingEnds( m_canvas, &dc );
+ OnModify();
+ }
+}
+
+
+void SCH_EDIT_FRAME::ConvertPart( SCH_COMPONENT* DrawComponent, wxDC* DC )
+{
+ if( !DrawComponent )
+ return;
+
+ if( LIB_PART* part = Prj().SchLibs()->FindLibPart( DrawComponent->GetPartName() ) )
+ {
+ if( !part->HasConversion() )
+ {
+ DisplayError( this, wxT( "No convert found" ) );
+ return;
+ }
+
+ STATUS_FLAGS flags = DrawComponent->GetFlags();
+
+ if( DrawComponent->GetFlags() )
+ DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode, g_GhostColor );
+ else
+ DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode );
+
+ DrawComponent->SetConvert( DrawComponent->GetConvert() + 1 );
+
+ // ensure m_Convert = 0, 1 or 2
+ // 0 and 1 = shape 1 = not converted
+ // 2 = shape 2 = first converted shape
+ // > 2 is not used but could be used for more shapes
+ // like multiple shapes for a programmable component
+ // When m_Convert = val max, return to the first shape
+ if( DrawComponent->GetConvert() > 2 )
+ DrawComponent->SetConvert( 1 );
+
+ DrawComponent->ClearFlags();
+ DrawComponent->SetFlags( flags ); // Restore m_Flag (modified by SetConvert())
+
+ /* Redraw the component in the new position. */
+ if( DrawComponent->IsMoving() )
+ DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode, g_GhostColor );
+ else
+ DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+
+ GetScreen()->TestDanglingEnds( m_canvas, DC );
+ OnModify();
+ }
+}
diff --git a/eeschema/help_common_strings.h b/eeschema/help_common_strings.h
new file mode 100644
index 0000000..f1f8515
--- /dev/null
+++ b/eeschema/help_common_strings.h
@@ -0,0 +1,90 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 CERN
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/help_common_strings.h
+ * strings common to toolbars and menubar
+ */
+
+/**
+ * These strings are used in menus and tools, that do the same command
+ * But they are internationalized, and therefore must be created
+ * at run time, on the fly.
+ * So they cannot be static.
+ *
+ * Therefore they are defined by \#define, used inside menu constructors
+ */
+
+// Common to schematic editor and component editor
+#define HELP_UNDO _( "Undo last command" )
+#define HELP_REDO _( "Redo last command" )
+
+#define HELP_ZOOM_IN _( "Zoom in" )
+#define HELP_ZOOM_OUT _( "Zoom out" )
+#define HELP_ZOOM_FIT _( "Fit schematic sheet on screen" )
+#define HELP_ZOOM_REDRAW _( "Redraw schematic view" )
+
+#define HELP_DELETE_ITEMS _( "Delete item" )
+
+// Schematic editor:
+#define HELP_FIND _( "Find components and text" )
+#define HELP_REPLACE _( "Find and replace text in schematic items" )
+#define HELP_PLACE_COMPONENTS _( "Place component" )
+#define HELP_PLACE_POWERPORT _( "Place power port" )
+#define HELP_PLACE_WIRE _( "Place wire" )
+#define HELP_PLACE_BUS _( "Place bus" )
+#define HELP_PLACE_WIRE2BUS_ENTRY _( "Place wire to bus entry" )
+#define HELP_PLACE_BUS2BUS_ENTRY _( "Place bus to bus entry" )
+#define HELP_PLACE_NC_FLAG _( "Place not-connected flag" )
+
+#define HELP_PLACE_NETLABEL _( "Place net name - local label" )
+#define HELP_PLACE_GLOBALLABEL \
+ _(\
+ "Place global label.\nWarning: inside global hierarchy , all global labels with same name are connected" )
+#define HELP_PLACE_HIER_LABEL \
+ _( "Place a hierarchical label. Label will be seen as a hierarchical pin in the sheet symbol" )
+
+#define HELP_PLACE_JUNCTION _( "Place junction" )
+#define HELP_PLACE_SHEET _( "Create hierarchical sheet" )
+#define HELP_IMPORT_SHEETPIN _( \
+ "Place hierarchical pin imported from the corresponding hierarchical label" )
+#define HELP_PLACE_SHEETPIN _( "Place hierarchical pin in sheet" )
+#define HELP_PLACE_GRAPHICLINES _( "Place graphic lines or polygons" )
+#define HELP_PLACE_GRAPHICTEXTS _( "Place text" )
+
+#define HELP_ANNOTATE _( "Annotate schematic components" )
+#define HELP_RUN_LIB_EDITOR _( "Library Editor - Create/edit components" )
+#define HELP_RUN_LIB_VIEWER _( "Library Browser - Browse components" )
+#define HELP_GENERATE_BOM _( "Generate bill of materials and/or cross references" )
+#define HELP_IMPORT_FOOTPRINTS \
+ _( "Back-import component footprint fields via CvPcb .cmp file" )
+
+// Component editor:
+#define HELP_ADD_PIN _( "Add pins to component" )
+#define HELP_ADD_BODYTEXT _( "Add text to component body" )
+#define HELP_ADD_BODYRECT _( "Add graphic rectangle to component body" )
+#define HELP_ADD_BODYCIRCLE _( "Add circles to component body" )
+#define HELP_ADD_BODYARC _( "Add arcs to component body" )
+#define HELP_ADD_BODYPOLYGON _( "Add lines and polygons to component body" )
+#define HELP_PLACE_GRAPHICIMAGES _("Add bitmap image")
diff --git a/eeschema/hierarch.cpp b/eeschema/hierarch.cpp
new file mode 100644
index 0000000..578274b
--- /dev/null
+++ b/eeschema/hierarch.cpp
@@ -0,0 +1,313 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file hierarch.cpp
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <id.h>
+#include <schframe.h>
+
+#include <general.h>
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+
+#include <wx/imaglist.h>
+#include <wx/treectrl.h>
+
+
+enum
+{
+ ID_TREECTRL_HIERARCHY = 1600
+};
+
+
+class HIERARCHY_NAVIG_DLG;
+
+/* This class derived from wxTreeItemData stores the SCH_SHEET_PATH of each
+ * sheet in hierarchy in each TreeItem, in its associated data buffer
+*/
+class TreeItemData : public wxTreeItemData
+{
+public:
+ SCH_SHEET_PATH m_SheetPath;
+
+ TreeItemData( SCH_SHEET_PATH& sheet ) : wxTreeItemData()
+ {
+ m_SheetPath = sheet;
+ }
+};
+
+/* Class to handle hierarchy tree. */
+class HIERARCHY_TREE : public wxTreeCtrl
+{
+private:
+ HIERARCHY_NAVIG_DLG* m_Parent;
+ wxImageList* imageList;
+
+public:
+ HIERARCHY_TREE()
+ {
+ m_Parent = NULL;
+ imageList = NULL;
+ }
+
+ HIERARCHY_TREE( HIERARCHY_NAVIG_DLG* parent );
+
+ DECLARE_DYNAMIC_CLASS( HIERARCHY_TREE )
+};
+
+IMPLEMENT_DYNAMIC_CLASS( HIERARCHY_TREE, wxTreeCtrl )
+
+
+HIERARCHY_TREE::HIERARCHY_TREE( HIERARCHY_NAVIG_DLG* parent ) :
+ wxTreeCtrl( (wxWindow*)parent, ID_TREECTRL_HIERARCHY, wxDefaultPosition, wxDefaultSize,
+ wxTR_HAS_BUTTONS, wxDefaultValidator, wxT( "HierachyTreeCtrl" ) )
+{
+ m_Parent = parent;
+
+ // Make an image list containing small icons
+ // All icons are expected having the same size.
+ wxBitmap tree_nosel_bm( KiBitmap( tree_nosel_xpm ) );
+ imageList = new wxImageList( tree_nosel_bm.GetWidth(),
+ tree_nosel_bm.GetHeight(), true, 2 );
+
+ imageList->Add( tree_nosel_bm );
+ imageList->Add( KiBitmap( tree_sel_xpm ) );
+
+ AssignImageList( imageList );
+}
+
+
+class HIERARCHY_NAVIG_DLG : public wxDialog
+{
+public:
+ SCH_EDIT_FRAME* m_Parent;
+ HIERARCHY_TREE* m_Tree;
+ int m_nbsheets;
+
+private:
+ wxSize m_TreeSize;
+ int maxposx;
+
+public:
+ HIERARCHY_NAVIG_DLG( SCH_EDIT_FRAME* aParent, const wxPoint& aPos );
+ void BuildSheetsTree( SCH_SHEET_PATH* list, wxTreeItemId* previousmenu );
+
+ ~HIERARCHY_NAVIG_DLG();
+
+ void OnSelect( wxTreeEvent& event );
+
+private:
+ void OnQuit( wxCommandEvent& event );
+
+ DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE( HIERARCHY_NAVIG_DLG, wxDialog )
+ EVT_TREE_ITEM_ACTIVATED( ID_TREECTRL_HIERARCHY, HIERARCHY_NAVIG_DLG::OnSelect )
+END_EVENT_TABLE()
+
+
+void SCH_EDIT_FRAME::InstallHierarchyFrame( wxPoint& pos )
+{
+ HIERARCHY_NAVIG_DLG* treeframe = new HIERARCHY_NAVIG_DLG( this, pos );
+
+ treeframe->ShowModal();
+ treeframe->Destroy();
+}
+
+
+HIERARCHY_NAVIG_DLG::HIERARCHY_NAVIG_DLG( SCH_EDIT_FRAME* aParent, const wxPoint& aPos ) :
+ wxDialog( aParent, wxID_ANY, _( "Navigator" ), aPos, wxSize( 110, 50 ),
+ wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )
+{
+ wxTreeItemId cellule;
+
+ m_Parent = aParent;
+ m_Tree = new HIERARCHY_TREE( this );
+
+ m_nbsheets = 1;
+
+ cellule = m_Tree->AddRoot( _( "Root" ), 0, 1 );
+ m_Tree->SetItemBold( cellule, true );
+
+ SCH_SHEET_PATH list;
+ list.Push( g_RootSheet );
+ m_Tree->SetItemData( cellule, new TreeItemData( list ) );
+
+ if( m_Parent->GetCurrentSheet().Last() == g_RootSheet )
+ m_Tree->SelectItem( cellule ); //root.
+
+ maxposx = 15;
+ BuildSheetsTree( &list, &cellule );
+
+ m_Tree->Expand( cellule );
+
+ wxRect itemrect;
+ m_Tree->GetBoundingRect( cellule, itemrect );
+
+ // Set dialog window size to be large enough
+ m_TreeSize.x = itemrect.GetWidth() + 20;
+ m_TreeSize.x = std::max( m_TreeSize.x, 250 );
+
+ // Readjust the size of the frame to an optimal value.
+ m_TreeSize.y = m_nbsheets * itemrect.GetHeight();
+ m_TreeSize.y += 10;
+
+ SetClientSize( m_TreeSize );
+}
+
+
+HIERARCHY_NAVIG_DLG::~HIERARCHY_NAVIG_DLG()
+{
+}
+
+
+void HIERARCHY_NAVIG_DLG::OnQuit( wxCommandEvent& event )
+{
+ // true is to force the frame to close
+ Close( true );
+}
+
+
+/* Routine to create the hierarchical tree of the schematic
+ * This routine is re-entrant!
+ */
+void HIERARCHY_NAVIG_DLG::BuildSheetsTree( SCH_SHEET_PATH* list, wxTreeItemId* previousmenu )
+
+{
+ wxTreeItemId menu;
+
+ if( m_nbsheets > NB_MAX_SHEET )
+ {
+ if( m_nbsheets == (NB_MAX_SHEET + 1) )
+ {
+ wxString msg;
+ msg << wxT( "BuildSheetsTree: Error: nbsheets > " ) << NB_MAX_SHEET;
+ DisplayError( this, msg );
+ m_nbsheets++;
+ }
+
+ return;
+ }
+
+ maxposx += m_Tree->GetIndent();
+ SCH_ITEM* schitem = list->LastDrawList();
+
+ while( schitem && m_nbsheets < NB_MAX_SHEET )
+ {
+ if( schitem->Type() == SCH_SHEET_T )
+ {
+ SCH_SHEET* sheet = (SCH_SHEET*) schitem;
+ m_nbsheets++;
+ menu = m_Tree->AppendItem( *previousmenu, sheet->GetName(), 0, 1 );
+ list->Push( sheet );
+ m_Tree->SetItemData( menu, new TreeItemData( *list ) );
+ int ll = m_Tree->GetItemText( menu ).Len();
+
+#ifdef __WINDOWS__
+ ll *= 9; // * char width
+#else
+ ll *= 12; // * char width
+#endif
+ ll += maxposx + 20;
+ m_TreeSize.x = std::max( m_TreeSize.x, ll );
+ m_TreeSize.y += 1;
+
+ if( *list == m_Parent->GetCurrentSheet() )
+ {
+ m_Tree->EnsureVisible( menu );
+ m_Tree->SelectItem( menu );
+ }
+
+ BuildSheetsTree( list, &menu );
+ m_Tree->Expand( menu );
+ list->Pop();
+ }
+
+ schitem = schitem->Next();
+ }
+
+ maxposx -= m_Tree->GetIndent();
+}
+
+
+/* Called on a double-click on a tree item:
+ * Open the selected sheet, and display the corresponding screen
+ */
+void HIERARCHY_NAVIG_DLG::OnSelect( wxTreeEvent& event )
+
+{
+ wxTreeItemId ItemSel = m_Tree->GetSelection();
+
+ m_Parent->SetCurrentSheet(( (TreeItemData*) m_Tree->GetItemData( ItemSel ) )->m_SheetPath );
+ m_Parent->DisplayCurrentSheet();
+ Close( true );
+}
+
+
+void SCH_EDIT_FRAME::DisplayCurrentSheet()
+{
+ SetRepeatItem( NULL );
+ ClearMsgPanel();
+
+ SCH_SCREEN* screen = m_CurrentSheet->LastScreen();
+
+ // Switch to current sheet,
+ // and update the grid size, because it can be modified in latest screen
+ SetScreen( screen );
+ GetScreen()->SetGrid( m_LastGridSizeId + ID_POPUP_GRID_LEVEL_1000 );
+
+ // update the References
+ m_CurrentSheet->UpdateAllScreenReferences();
+ SetSheetNumberAndCount();
+ m_canvas->SetCanStartBlock( -1 );
+
+ if( screen->m_FirstRedraw )
+ {
+ Zoom_Automatique( false );
+ screen->m_FirstRedraw = false;
+ SetCrossHairPosition( GetScrollCenterPosition() );
+ m_canvas->MoveCursorToCrossHair();
+ screen->SchematicCleanUp( GetCanvas(), NULL );
+ }
+ else
+ {
+ RedrawScreen( GetScrollCenterPosition(), true );
+ }
+
+ // Now refresh m_canvas. Should be not necessary, but because screen has changed
+ // the previous refresh has set all new draw parameters (scroll position ..)
+ // but most of time there were some inconsitencies about cursor parameters
+ // ( previous position of cursor ...) and artefacts can happen
+ // mainly when sheet size has changed
+ // This second refresh clears artefacts because at this point,
+ // all parameters are now updated
+ m_canvas->Refresh();
+}
diff --git a/eeschema/hotkeys.cpp b/eeschema/hotkeys.cpp
new file mode 100644
index 0000000..743371a
--- /dev/null
+++ b/eeschema/hotkeys.cpp
@@ -0,0 +1,876 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2017 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/hotkeys.cpp
+ */
+
+#include <fctsys.h>
+#include <eeschema_id.h>
+#include <hotkeys.h>
+#include <schframe.h>
+#include <class_drawpanel.h>
+
+#include <general.h>
+#include <libeditframe.h>
+#include <viewlib_frame.h>
+#include <class_libentry.h>
+#include <sch_junction.h>
+#include <sch_line.h>
+#include <sch_component.h>
+#include <sch_sheet.h>
+
+#include <dialogs/dialog_schematic_find.h>
+
+// Remark: the hotkey message info is used as keyword in hotkey config files and
+// as comments in help windows, therefore translated only when displayed
+// they are marked _HKI to be extracted by translation tools
+// See hotkeys_basic.h for more info
+
+
+/* How to add a new hotkey:
+ * add a new id in the enum hotkey_id_command like MY_NEW_ID_FUNCTION (see
+ * hotkeys.h).
+ * add a new EDA_HOTKEY entry like:
+ * static EDA_HOTKEY HkMyNewEntry(_HKI("Command Label"), MY_NEW_ID_FUNCTION,
+ * default key value);
+ * _HKI("Command Label") is the name used in hotkey list display, and the
+ * identifier in the hotkey list file
+ * MY_NEW_ID_FUNCTION is an equivalent id function used in the switch in
+ * OnHotKey() function.
+ * default key value is the default hotkey for this command. Can be overridden
+ * by the user hotkey list file
+ * add the HkMyNewEntry pointer in the schematic_Hotkey_List list or the
+ * libEdit_Hotkey_List list or common_Hotkey_List if the same command is
+ * added both in Eeschema and libedit)
+ * Add the new code in the switch in OnHotKey() function.
+ * when the variable itemInEdit is true, an item is currently edited.
+ * This can be useful if the new function cannot be executed while an item is
+ * currently being edited
+ * ( For example, one cannot start a new wire when a component is moving.)
+ *
+ * Note: If an hotkey is a special key be sure the corresponding wxWidget
+ * keycode (WXK_XXXX) is handled in the hotkey_name_descr
+ * s_Hotkey_Name_List list (see hotkeys_basic.cpp) and see this list
+ * for some ascii keys (space ...)
+ *
+ * Key modifier are: GR_KB_CTRL GR_KB_ALT
+ */
+
+
+// Common commands
+
+// Fit on Screen
+#if !defined( __WXMAC__ )
+static EDA_HOTKEY HkZoomAuto( _HKI( "Fit on Screen" ), HK_ZOOM_AUTO, WXK_HOME, ID_ZOOM_PAGE );
+#else
+static EDA_HOTKEY HkZoomAuto( _HKI( "Zoom Auto" ), HK_ZOOM_AUTO, GR_KB_CTRL + '0',
+ ID_ZOOM_PAGE );
+#endif
+
+static EDA_HOTKEY HkZoomCenter( _HKI( "Zoom Center" ), HK_ZOOM_CENTER, WXK_F4,
+ ID_POPUP_ZOOM_CENTER );
+
+// Refresh Screen
+#if !defined( __WXMAC__ )
+static EDA_HOTKEY HkZoomRedraw( _HKI( "Zoom Redraw" ), HK_ZOOM_REDRAW, WXK_F3, ID_ZOOM_REDRAW );
+#else
+static EDA_HOTKEY HkZoomRedraw( _HKI( "Zoom Redraw" ), HK_ZOOM_REDRAW, GR_KB_CTRL + 'R',
+ ID_ZOOM_REDRAW );
+#endif
+
+// Zoom In
+#if !defined( __WXMAC__ )
+static EDA_HOTKEY HkZoomIn( _HKI( "Zoom In" ), HK_ZOOM_IN, WXK_F1, ID_POPUP_ZOOM_IN );
+#else
+static EDA_HOTKEY HkZoomIn( _HKI( "Zoom In" ), HK_ZOOM_IN, GR_KB_CTRL + '+', ID_POPUP_ZOOM_IN );
+#endif
+
+// Zoom Out
+#if !defined( __WXMAC__ )
+static EDA_HOTKEY HkZoomOut( _HKI( "Zoom Out" ), HK_ZOOM_OUT, WXK_F2, ID_POPUP_ZOOM_OUT );
+#else
+static EDA_HOTKEY HkZoomOut( _HKI( "Zoom Out" ), HK_ZOOM_OUT, GR_KB_CTRL + '-', ID_POPUP_ZOOM_OUT );
+#endif
+
+static EDA_HOTKEY HkHelp( _HKI( "Help (this window)" ), HK_HELP, '?' );
+static EDA_HOTKEY HkResetLocalCoord( _HKI( "Reset Local Coordinates" ), HK_RESET_LOCAL_COORD, ' ' );
+static EDA_HOTKEY HkLeaveSheet( _HKI( "Leave Sheet" ), HK_LEAVE_SHEET, GR_KB_ALT + WXK_BACK,
+ ID_POPUP_SCH_LEAVE_SHEET );
+
+// Undo
+static EDA_HOTKEY HkUndo( _HKI( "Undo" ), HK_UNDO, GR_KB_CTRL + 'Z', (int) wxID_UNDO );
+
+// Redo
+#if !defined( __WXMAC__ )
+static EDA_HOTKEY HkRedo( _HKI( "Redo" ), HK_REDO, GR_KB_CTRL + 'Y', (int) wxID_REDO );
+#else
+static EDA_HOTKEY HkRedo( _HKI( "Redo" ), HK_REDO, GR_KB_SHIFT + GR_KB_CTRL + 'Z',
+ (int) wxID_REDO );
+#endif
+
+// mouse click command:
+static EDA_HOTKEY HkMouseLeftClick( _HKI( "Mouse Left Click" ), HK_LEFT_CLICK, WXK_RETURN, 0 );
+static EDA_HOTKEY HkMouseLeftDClick( _HKI( "Mouse Left Double Click" ), HK_LEFT_DCLICK, WXK_END, 0 );
+
+// Schematic editor
+static EDA_HOTKEY HkBeginWire( _HKI( "Begin Wire" ), HK_BEGIN_WIRE, 'W', ID_WIRE_BUTT );
+static EDA_HOTKEY HkBeginBus( _HKI( "Begin Bus" ), HK_BEGIN_BUS, 'B', ID_BUS_BUTT );
+static EDA_HOTKEY HkEndLineWireBus( _HKI( "End Line Wire Bus" ), HK_END_CURR_LINEWIREBUS, 'K',
+ ID_POPUP_END_LINE );
+
+static EDA_HOTKEY HkAddLabel( _HKI( "Add Label" ), HK_ADD_LABEL, 'L', ID_LABEL_BUTT );
+static EDA_HOTKEY HkAddHierarchicalLabel( _HKI( "Add Hierarchical Label" ), HK_ADD_HLABEL, 'H',
+ ID_HIERLABEL_BUTT );
+static EDA_HOTKEY HkAddGlobalLabel( _HKI( "Add Global Label" ), HK_ADD_GLABEL, GR_KB_CTRL + 'H',
+ ID_GLABEL_BUTT );
+static EDA_HOTKEY HkAddJunction( _HKI( "Add Junction" ), HK_ADD_JUNCTION, 'J', ID_JUNCTION_BUTT );
+static EDA_HOTKEY HkAddComponent( _HKI( "Add Component" ), HK_ADD_NEW_COMPONENT, 'A',
+ ID_SCH_PLACE_COMPONENT );
+static EDA_HOTKEY HkAddPower( _HKI( "Add Power" ), HK_ADD_NEW_POWER, 'P',
+ ID_PLACE_POWER_BUTT );
+static EDA_HOTKEY HkAddNoConn( _HKI( "Add No Connect Flag" ), HK_ADD_NOCONN_FLAG, 'Q',
+ ID_NOCONN_BUTT );
+static EDA_HOTKEY HkAddHierSheet( _HKI( "Add Sheet" ), HK_ADD_HIER_SHEET, 'S',
+ ID_SHEET_SYMBOL_BUTT );
+static EDA_HOTKEY HkAddBusEntry( _HKI( "Add Bus Entry" ), HK_ADD_BUS_ENTRY, '/',
+ ID_BUSTOBUS_ENTRY_BUTT );
+static EDA_HOTKEY HkAddWireEntry( _HKI( "Add Wire Entry" ), HK_ADD_WIRE_ENTRY, 'Z',
+ ID_WIRETOBUS_ENTRY_BUTT );
+static EDA_HOTKEY HkAddGraphicPolyLine( _HKI( "Add Graphic PolyLine" ), HK_ADD_GRAPHIC_POLYLINE,
+ 'I', ID_LINE_COMMENT_BUTT );
+static EDA_HOTKEY HkAddGraphicText( _HKI( "Add Graphic Text" ), HK_ADD_GRAPHIC_TEXT, 'T',
+ ID_TEXT_COMMENT_BUTT );
+static EDA_HOTKEY HkMirrorY( _HKI( "Mirror Y" ), HK_MIRROR_Y, 'Y',
+ ID_SCH_MIRROR_Y );
+static EDA_HOTKEY HkMirrorX( _HKI( "Mirror X" ), HK_MIRROR_X, 'X',
+ ID_SCH_MIRROR_X );
+static EDA_HOTKEY HkOrientNormalComponent( _HKI( "Orient Normal Component" ),
+ HK_ORIENT_NORMAL_COMPONENT, 'N', ID_SCH_ORIENT_NORMAL );
+static EDA_HOTKEY HkRotate( _HKI( "Rotate Item" ), HK_ROTATE, 'R', ID_SCH_ROTATE_CLOCKWISE );
+static EDA_HOTKEY HkEdit( _HKI( "Edit Item" ), HK_EDIT, 'E', ID_SCH_EDIT_ITEM );
+static EDA_HOTKEY HkEditComponentValue( _HKI( "Edit Component Value" ),
+ HK_EDIT_COMPONENT_VALUE, 'V',
+ ID_SCH_EDIT_COMPONENT_VALUE );
+static EDA_HOTKEY HkEditComponentReference( _HKI( "Edit Component Reference" ),
+ HK_EDIT_COMPONENT_REFERENCE, 'U',
+ ID_SCH_EDIT_COMPONENT_REFERENCE );
+static EDA_HOTKEY HkEditComponentFootprint( _HKI( "Edit Component Footprint" ),
+ HK_EDIT_COMPONENT_FOOTPRINT, 'F',
+ ID_SCH_EDIT_COMPONENT_FOOTPRINT );
+static EDA_HOTKEY HkEditComponentWithLibedit( _HKI( "Edit with Component Editor" ),
+ HK_EDIT_COMPONENT_WITH_LIBEDIT,
+ 'E' + GR_KB_CTRL,
+ ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP );
+static EDA_HOTKEY HkMove( _HKI( "Move Schematic Item" ),
+ HK_MOVE_COMPONENT_OR_ITEM, 'M',
+ ID_SCH_MOVE_ITEM );
+
+static EDA_HOTKEY HkCopyComponentOrText( _HKI( "Copy Component or Label" ),
+ HK_COPY_COMPONENT_OR_LABEL, 'C',
+ ID_POPUP_SCH_COPY_ITEM );
+
+static EDA_HOTKEY HkDrag( _HKI( "Drag Item" ), HK_DRAG, 'G', ID_SCH_DRAG_ITEM );
+static EDA_HOTKEY HkSaveBlock( _HKI( "Save Block" ), HK_SAVE_BLOCK, 'C' + GR_KB_CTRL, wxID_COPY );
+static EDA_HOTKEY HkMove2Drag( _HKI( "Move Block -> Drag Block" ),
+ HK_MOVEBLOCK_TO_DRAGBLOCK, '\t', ID_POPUP_DRAG_BLOCK );
+static EDA_HOTKEY HkInsert( _HKI( "Repeat Last Item" ), HK_REPEAT_LAST, WXK_INSERT );
+static EDA_HOTKEY HkDelete( _HKI( "Delete Item" ), HK_DELETE, WXK_DELETE );
+static EDA_HOTKEY HkDeleteNode( _HKI( "Delete Node" ), HK_DELETE_NODE, WXK_BACK,
+ ID_POPUP_SCH_DELETE_NODE );
+
+static EDA_HOTKEY HkFindItem( _HKI( "Find Item" ), HK_FIND_ITEM, 'F' + GR_KB_CTRL, ID_FIND_ITEMS );
+static EDA_HOTKEY HkFindNextItem( _HKI( "Find Next Item" ), HK_FIND_NEXT_ITEM, WXK_F5,
+ wxEVT_COMMAND_FIND );
+static EDA_HOTKEY HkFindReplace( _HKI( "Find and Replace" ), HK_FIND_REPLACE,
+ 'F' + GR_KB_CTRL + GR_KB_ALT, wxID_REPLACE );
+static EDA_HOTKEY HkFindNextDrcMarker( _HKI( "Find Next DRC Marker" ), HK_FIND_NEXT_DRC_MARKER,
+ WXK_F5 + GR_KB_SHIFT, EVT_COMMAND_FIND_DRC_MARKER );
+
+// Special keys for library editor:
+static EDA_HOTKEY HkCreatePin( _HKI( "Create Pin" ), HK_LIBEDIT_CREATE_PIN, 'P' );
+static EDA_HOTKEY HkInsertPin( _HKI( "Repeat Pin" ), HK_REPEAT_LAST, WXK_INSERT );
+static EDA_HOTKEY HkMoveLibItem( _HKI( "Move Library Item" ), HK_LIBEDIT_MOVE_GRAPHIC_ITEM, 'M' );
+
+// Load/save files
+static EDA_HOTKEY HkSaveLib( _HKI( "Save Library" ), HK_SAVE_LIB, 'S' + GR_KB_CTRL );
+static EDA_HOTKEY HkSaveSchematic( _HKI( "Save Schematic" ), HK_SAVE_SCH, 'S' + GR_KB_CTRL );
+static EDA_HOTKEY HkLoadSchematic( _HKI( "Load Schematic" ), HK_LOAD_SCH, 'L' + GR_KB_CTRL );
+
+// List of common hotkey descriptors
+static EDA_HOTKEY* common_Hotkey_List[] =
+{
+ &HkHelp,
+ &HkZoomIn,
+ &HkZoomOut,
+ &HkZoomRedraw,
+ &HkZoomCenter,
+ &HkZoomAuto,
+ &HkResetLocalCoord,
+ &HkEdit,
+ &HkDelete,
+ &HkRotate,
+ &HkDrag,
+ &HkUndo,
+ &HkRedo,
+ &HkMouseLeftClick,
+ &HkMouseLeftDClick,
+ NULL
+};
+
+// List of common hotkey descriptors, for the library vierwer
+static EDA_HOTKEY* common_basic_Hotkey_List[] =
+{
+ &HkHelp,
+ &HkZoomIn,
+ &HkZoomOut,
+ &HkZoomRedraw,
+ &HkZoomCenter,
+ &HkZoomAuto,
+ &HkResetLocalCoord,
+ &HkMouseLeftClick,
+ &HkMouseLeftDClick,
+ NULL
+};
+
+// List of hotkey descriptors for schematic
+static EDA_HOTKEY* schematic_Hotkey_List[] =
+{
+ &HkSaveSchematic,
+ &HkLoadSchematic,
+ &HkFindItem,
+ &HkFindNextItem,
+ &HkFindNextDrcMarker,
+ &HkFindReplace,
+ &HkInsert,
+ &HkMove2Drag,
+ &HkSaveBlock,
+ &HkMove,
+ &HkCopyComponentOrText,
+ &HkAddComponent,
+ &HkAddPower,
+ &HkMirrorX,
+ &HkMirrorY,
+ &HkOrientNormalComponent,
+ &HkEditComponentValue,
+ &HkEditComponentReference,
+ &HkEditComponentFootprint,
+ &HkEditComponentWithLibedit,
+ &HkBeginWire,
+ &HkBeginBus,
+ &HkEndLineWireBus,
+ &HkAddLabel,
+ &HkAddHierarchicalLabel,
+ &HkAddGlobalLabel,
+ &HkAddJunction,
+ &HkAddNoConn,
+ &HkAddHierSheet,
+ &HkAddWireEntry,
+ &HkAddBusEntry,
+ &HkAddGraphicPolyLine,
+ &HkAddGraphicText,
+ &HkLeaveSheet,
+ &HkDeleteNode,
+ NULL
+};
+
+// List of hotkey descriptors for library editor
+static EDA_HOTKEY* libEdit_Hotkey_List[] =
+{
+ &HkSaveLib,
+ &HkCreatePin,
+ &HkInsertPin,
+ &HkMoveLibItem,
+ NULL
+};
+
+// List of hotkey descriptors for library viewer (currently empty
+static EDA_HOTKEY* viewlib_Hotkey_List[] =
+{
+ NULL
+};
+
+// Keyword Identifiers (tags) in key code configuration file (section names)
+// (.m_SectionTag member of a EDA_HOTKEY_CONFIG)
+static wxString schematicSectionTag( wxT( "[eeschema]" ) );
+static wxString libEditSectionTag( wxT( "[libedit]" ) );
+
+// Titles for hotkey editor and hotkey display
+static wxString commonSectionTitle( _HKI( "Common" ) );
+static wxString schematicSectionTitle( _HKI( "Schematic Editor" ) );
+static wxString libEditSectionTitle( _HKI( "Library Editor" ) );
+
+// list of sections and corresponding hotkey list for Eeschema (used to create
+// an hotkey config file)
+struct EDA_HOTKEY_CONFIG g_Eeschema_Hokeys_Descr[] =
+{
+ { &g_CommonSectionTag, common_Hotkey_List, &commonSectionTitle },
+ { &schematicSectionTag, schematic_Hotkey_List, &schematicSectionTitle },
+ { &libEditSectionTag, libEdit_Hotkey_List, &libEditSectionTitle },
+ { NULL, NULL, NULL }
+};
+
+// list of sections and corresponding hotkey list for the schematic editor
+// (used to list current hotkeys)
+struct EDA_HOTKEY_CONFIG g_Schematic_Hokeys_Descr[] =
+{
+ { &g_CommonSectionTag, common_Hotkey_List, &commonSectionTitle },
+ { &schematicSectionTag, schematic_Hotkey_List, &schematicSectionTitle },
+ { NULL, NULL, NULL }
+};
+
+// list of sections and corresponding hotkey list for the component editor
+// (used to list current hotkeys)
+struct EDA_HOTKEY_CONFIG g_Libedit_Hokeys_Descr[] =
+{
+ { &g_CommonSectionTag, common_Hotkey_List, &commonSectionTitle },
+ { &libEditSectionTag, libEdit_Hotkey_List, &libEditSectionTitle },
+ { NULL, NULL, NULL }
+};
+
+// list of sections and corresponding hotkey list for the component browser
+// (used to list current hotkeys)
+struct EDA_HOTKEY_CONFIG g_Viewlib_Hokeys_Descr[] =
+{
+ { &g_CommonSectionTag, common_basic_Hotkey_List, &commonSectionTitle },
+ { NULL, NULL, NULL }
+};
+
+
+EDA_HOTKEY* SCH_EDIT_FRAME::GetHotKeyDescription( int aCommand ) const
+{
+ EDA_HOTKEY* HK_Descr = GetDescriptorFromCommand( aCommand, common_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ HK_Descr = GetDescriptorFromCommand( aCommand, schematic_Hotkey_List );
+
+ return HK_Descr;
+}
+
+
+/*
+ * Hot keys. Some commands are relative to the item under the mouse cursor
+ * Commands are case insensitive
+ */
+bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem )
+{
+ if( aHotKey == 0 )
+ return false;
+
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+
+ SCH_SCREEN* screen = GetScreen();
+
+ // itemInEdit == false means no item currently edited. We can ask for editing a new item
+ bool itemInEdit = screen->GetCurItem() && screen->GetCurItem()->GetFlags();
+
+ // blocInProgress == false means no block in progress.
+ // Because a drag command uses a drag block, false means also no drag in progress
+ // If false, we can ask for editing a new item
+ bool blocInProgress = screen->m_BlockLocate.GetState() != STATE_NO_BLOCK;
+
+ // notBusy == true means no item currently edited and no other command in progress
+ // We can change active tool and ask for editing a new item
+ bool notBusy = (!itemInEdit) && (!blocInProgress);
+
+ /* Convert lower to upper case (the usual toupper function has problem
+ * with non ascii codes like function keys */
+ if( (aHotKey >= 'a') && (aHotKey <= 'z') )
+ aHotKey += 'A' - 'a';
+
+ // Search command from key :
+ EDA_HOTKEY* hotKey = GetDescriptorFromHotkey( aHotKey, common_Hotkey_List );
+
+ if( hotKey == NULL )
+ hotKey = GetDescriptorFromHotkey( aHotKey, schematic_Hotkey_List );
+
+ if( hotKey == NULL )
+ return false;
+
+ switch( hotKey->m_Idcommand )
+ {
+ default:
+ case HK_NOT_FOUND:
+ return false;
+
+ case HK_HELP: // Display Current hotkey list
+ DisplayHotkeyList( this, g_Schematic_Hokeys_Descr );
+ break;
+
+ case HK_RESET_LOCAL_COORD: // Reset the relative coord
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ break;
+
+ case HK_LEFT_CLICK:
+ case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events
+ if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE )
+ {
+ GetCanvas()->SetAutoPanRequest( false );
+ HandleBlockPlace( aDC );
+ }
+ else if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK )
+ {
+ OnLeftClick( aDC, aPosition );
+
+ if( hotKey->m_Idcommand == HK_LEFT_DCLICK )
+ OnLeftDClick( aDC, aPosition );
+ }
+ break;
+
+ case HK_ZOOM_IN:
+ case HK_ZOOM_OUT:
+ case HK_ZOOM_REDRAW:
+ case HK_ZOOM_CENTER:
+ case HK_ZOOM_AUTO:
+// case HK_ZOOM_SELECTION:
+ case HK_MOVEBLOCK_TO_DRAGBLOCK: // Switch to drag mode, when block moving
+ case HK_SAVE_BLOCK: // Copy block to paste buffer.
+ cmd.SetId( hotKey->m_IdMenuEvent );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_DELETE:
+ if( notBusy )
+ DeleteItemAtCrossHair( aDC );
+ break;
+
+ case HK_REPEAT_LAST:
+ if( notBusy )
+ RepeatDrawItem( aDC );
+ break;
+
+ case HK_END_CURR_LINEWIREBUS:
+ // this key terminates a new line/bus/wire in progress
+ if( aItem && aItem->IsNew() &&
+ aItem->Type() == SCH_LINE_T )
+ {
+ cmd.SetId( hotKey->m_IdMenuEvent );
+ GetEventHandler()->ProcessEvent( cmd );
+ }
+ break;
+
+ case HK_UNDO: // Hot keys that map to command IDs that cannot be called
+ case HK_REDO: // while busy performing another command.
+ case HK_FIND_ITEM:
+ case HK_FIND_REPLACE:
+ case HK_DELETE_NODE:
+ case HK_LEAVE_SHEET:
+ if( notBusy )
+ {
+ cmd.SetId( hotKey->m_IdMenuEvent );
+ GetEventHandler()->ProcessEvent( cmd );
+ }
+ break;
+
+ case HK_FIND_NEXT_ITEM:
+ case HK_FIND_NEXT_DRC_MARKER:
+ if( notBusy )
+ {
+ wxFindDialogEvent event( hotKey->m_IdMenuEvent, GetId() );
+ event.SetEventObject( this );
+ event.SetFlags( m_findReplaceData->GetFlags() );
+ event.SetFindString( m_findReplaceData->GetFindString() );
+ GetEventHandler()->ProcessEvent( event );
+ }
+ break;
+
+ case HK_ADD_NEW_COMPONENT: // Add component
+ case HK_ADD_NEW_POWER: // Add power component
+ case HK_ADD_LABEL:
+ case HK_ADD_HLABEL:
+ case HK_ADD_GLABEL:
+ case HK_ADD_JUNCTION:
+ case HK_ADD_WIRE_ENTRY:
+ case HK_ADD_BUS_ENTRY:
+ case HK_ADD_HIER_SHEET:
+ case HK_ADD_GRAPHIC_TEXT:
+ case HK_ADD_GRAPHIC_POLYLINE:
+ case HK_ADD_NOCONN_FLAG: // Add a no connected flag
+ case HK_BEGIN_BUS:
+ case HK_BEGIN_WIRE:
+ if( notBusy )
+ {
+ EDA_HOTKEY_CLIENT_DATA data( aPosition );
+ cmd.SetInt( aHotKey );
+ cmd.SetClientObject( &data );
+ cmd.SetId( hotKey->m_IdMenuEvent );
+ GetEventHandler()->ProcessEvent( cmd );
+ }
+ else if( aItem && aItem->IsNew() )
+ {
+ // If the item is a bus or a wire, a begin command is not possible.
+ if( (GetToolId() == ID_BUS_BUTT) && (aItem->Type() == SCH_LINE_T) )
+ {
+ SCH_LINE* segment = (SCH_LINE*) aItem;
+
+ if( segment->GetLayer() != LAYER_BUS )
+ break;
+
+ // Bus in progress:
+ OnLeftClick( aDC, aPosition );
+ }
+ else if( (GetToolId() == ID_WIRE_BUTT ) && (aItem->Type() == SCH_LINE_T) )
+ {
+ SCH_LINE* segment = (SCH_LINE*) aItem;
+
+ if( segment->GetLayer() != LAYER_WIRE )
+ break;
+
+ // Wire in progress:
+ OnLeftClick( aDC, aPosition );
+ }
+ }
+ break;
+
+ case HK_COPY_COMPONENT_OR_LABEL: // Duplicate component or text/label
+ if( itemInEdit )
+ break;
+
+ if( aItem == NULL )
+ {
+ aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::MovableItems );
+
+ if( aItem == NULL )
+ break;
+ }
+
+ cmd.SetId( hotKey->m_IdMenuEvent );
+ wxPostEvent( this, cmd );
+ break;
+
+ case HK_DRAG: // Start drag
+ case HK_MOVE_COMPONENT_OR_ITEM: // Start move schematic item.
+ if( ! notBusy )
+ break;
+
+ // Fall through
+ case HK_EDIT:
+ // Edit schematic item. Do not allow sheet edition when mowing
+ // Because a sheet edition can be complex.
+ if( itemInEdit && screen->GetCurItem()->Type() == SCH_SHEET_T )
+ break;
+
+ // Fall through
+ case HK_EDIT_COMPONENT_VALUE: // Edit component value field.
+ case HK_EDIT_COMPONENT_REFERENCE: // Edit component value reference.
+ case HK_EDIT_COMPONENT_FOOTPRINT: // Edit component footprint field.
+ case HK_MIRROR_Y: // Mirror Y
+ case HK_MIRROR_X: // Mirror X
+ case HK_ORIENT_NORMAL_COMPONENT: // Orient 0, no mirror (Component)
+ case HK_ROTATE: // Rotate schematic item.
+ case HK_EDIT_COMPONENT_WITH_LIBEDIT: // Call Libedit and load the current component
+ {
+ // force a new item search on hot keys at current position,
+ // if there is no currently edited item,
+ // to avoid using a previously selected item
+ if( ! itemInEdit )
+ screen->SetCurItem( NULL );
+ EDA_HOTKEY_CLIENT_DATA data( aPosition );
+ cmd.SetInt( hotKey->m_Idcommand );
+ cmd.SetClientObject( &data );
+ cmd.SetId( hotKey->m_IdMenuEvent );
+ GetEventHandler()->ProcessEvent( cmd );
+ }
+ break;
+ }
+
+ // Hot key handled.
+ return true;
+}
+
+
+EDA_HOTKEY* LIB_EDIT_FRAME::GetHotKeyDescription( int aCommand ) const
+{
+ EDA_HOTKEY* HK_Descr = GetDescriptorFromCommand( aCommand, common_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ HK_Descr = GetDescriptorFromCommand( aCommand, libEdit_Hotkey_List );
+
+ return HK_Descr;
+}
+
+
+bool LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem )
+{
+ if( aHotKey == 0 )
+ return false;
+
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+
+ cmd.SetEventObject( this );
+
+ /* Convert lower to upper case (the usual toupper function has problem
+ * with non ascii codes like function keys */
+ if( (aHotKey >= 'a') && (aHotKey <= 'z') )
+ aHotKey += 'A' - 'a';
+
+ EDA_HOTKEY* hotKey = GetDescriptorFromHotkey( aHotKey, common_Hotkey_List );
+
+ if( hotKey == NULL )
+ hotKey = GetDescriptorFromHotkey( aHotKey, libEdit_Hotkey_List );
+
+ if( hotKey == NULL )
+ return false;
+
+ bool itemInEdit = m_drawItem && m_drawItem->InEditMode();
+
+ bool blocInProgress = GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK;
+
+ switch( hotKey->m_Idcommand )
+ {
+ default:
+ case HK_NOT_FOUND:
+ return false;
+
+ case HK_HELP: // Display Current hotkey list
+ DisplayHotkeyList( this, g_Libedit_Hokeys_Descr );
+ break;
+
+ case HK_RESET_LOCAL_COORD: // Reset the relative coord
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ break;
+
+ case HK_LEFT_CLICK:
+ OnLeftClick( aDC, aPosition );
+ break;
+
+ case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events
+ OnLeftClick( aDC, aPosition );
+ OnLeftDClick( aDC, aPosition );
+ break;
+
+ case HK_ZOOM_IN:
+ case HK_ZOOM_OUT:
+ case HK_ZOOM_REDRAW:
+ case HK_ZOOM_CENTER:
+ case HK_ZOOM_AUTO:
+ cmd.SetId( hotKey->m_IdMenuEvent );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_UNDO:
+ case HK_REDO:
+ if( !itemInEdit )
+ {
+ cmd.SetId( hotKey->m_IdMenuEvent );
+ GetEventHandler()->ProcessEvent( cmd );
+ }
+ break;
+
+ case HK_REPEAT_LAST:
+ if( ! itemInEdit )
+ {
+ if( m_lastDrawItem && !m_lastDrawItem->InEditMode() &&
+ ( m_lastDrawItem->Type() == LIB_PIN_T ) )
+ RepeatPinItem( aDC, (LIB_PIN*) m_lastDrawItem );
+ }
+ break;
+
+ case HK_EDIT:
+ if( !itemInEdit )
+ m_drawItem = LocateItemUsingCursor( aPosition );
+
+ if( m_drawItem )
+ {
+ switch( m_drawItem->Type() )
+ {
+ case LIB_PIN_T:
+ cmd.SetId( ID_LIBEDIT_EDIT_PIN );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case LIB_ARC_T:
+ case LIB_CIRCLE_T:
+ case LIB_RECTANGLE_T:
+ case LIB_POLYLINE_T:
+ case LIB_TEXT_T:
+ cmd.SetId( ID_POPUP_LIBEDIT_BODY_EDIT_ITEM );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case LIB_FIELD_T:
+ cmd.SetId( ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case HK_ROTATE:
+ if( blocInProgress )
+ {
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_ROTATE );
+ HandleBlockPlace( aDC );
+ }
+ else
+ {
+ if( !itemInEdit )
+ m_drawItem = LocateItemUsingCursor( aPosition );
+
+ if( m_drawItem )
+ {
+ cmd.SetId( ID_LIBEDIT_ROTATE_ITEM );
+ GetEventHandler()->ProcessEvent( cmd );
+ }
+ }
+ break;
+
+ case HK_LIBEDIT_CREATE_PIN:
+ if( ! itemInEdit )
+ {
+ SetToolID( ID_LIBEDIT_PIN_BUTT, wxCURSOR_PENCIL, _( "Add Pin" ) );
+ OnLeftClick( aDC, aPosition );
+ }
+ break;
+
+ case HK_DELETE:
+ if( !itemInEdit )
+ m_drawItem = LocateItemUsingCursor( aPosition );
+
+ if( m_drawItem && !m_drawItem->InEditMode() )
+ {
+ cmd.SetId( ID_POPUP_LIBEDIT_DELETE_ITEM );
+ Process_Special_Functions( cmd );
+ }
+ break;
+
+ case HK_LIBEDIT_MOVE_GRAPHIC_ITEM:
+ if( !itemInEdit )
+ {
+ m_drawItem = LocateItemUsingCursor( aPosition );
+
+ if( m_drawItem )
+ {
+ cmd.SetId( ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST );
+ Process_Special_Functions( cmd );
+ }
+ }
+ break;
+
+ case HK_DRAG:
+ if( !itemInEdit )
+ {
+ m_drawItem = LocateItemUsingCursor( aPosition );
+
+ if( m_drawItem && !m_drawItem->InEditMode() )
+ {
+ cmd.SetId( ID_POPUP_LIBEDIT_MODIFY_ITEM );
+ Process_Special_Functions( cmd );
+ }
+ }
+ break;
+ }
+
+ // Hot key handled.
+ return true;
+}
+
+
+EDA_HOTKEY* LIB_VIEW_FRAME::GetHotKeyDescription( int aCommand ) const
+{
+ EDA_HOTKEY* HK_Descr = GetDescriptorFromCommand( aCommand, common_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ HK_Descr = GetDescriptorFromCommand( aCommand, viewlib_Hotkey_List );
+
+ return HK_Descr;
+}
+
+
+bool LIB_VIEW_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem )
+{
+ if( aHotKey == 0 )
+ return false;
+
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+ cmd.SetEventObject( this );
+
+ /* Convert lower to upper case (the usual toupper function has problem with non ascii
+ * codes like function keys */
+ if( (aHotKey >= 'a') && (aHotKey <= 'z') )
+ aHotKey += 'A' - 'a';
+
+ EDA_HOTKEY* HK_Descr = GetDescriptorFromHotkey( aHotKey, common_basic_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ HK_Descr = GetDescriptorFromHotkey( aHotKey, viewlib_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ return false;
+
+ switch( HK_Descr->m_Idcommand )
+ {
+ default:
+ case HK_NOT_FOUND:
+ return false;
+
+ case HK_HELP: // Display Current hotkey list
+ DisplayHotkeyList( this, g_Viewlib_Hokeys_Descr );
+ break;
+
+ case HK_RESET_LOCAL_COORD: // set local (relative) coordinate origin
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ break;
+
+ case HK_LEFT_CLICK:
+ OnLeftClick( aDC, aPosition );
+ break;
+
+ case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events
+ OnLeftClick( aDC, aPosition );
+ OnLeftDClick( aDC, aPosition );
+ break;
+
+ case HK_ZOOM_IN:
+ cmd.SetId( ID_POPUP_ZOOM_IN );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_OUT:
+ cmd.SetId( ID_POPUP_ZOOM_OUT );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_REDRAW:
+ cmd.SetId( ID_ZOOM_REDRAW );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_CENTER:
+ cmd.SetId( ID_POPUP_ZOOM_CENTER );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_AUTO:
+ cmd.SetId( ID_ZOOM_PAGE );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+ }
+
+ return true;
+}
diff --git a/eeschema/hotkeys.h b/eeschema/hotkeys.h
new file mode 100644
index 0000000..afcebca
--- /dev/null
+++ b/eeschema/hotkeys.h
@@ -0,0 +1,96 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * eeschema/hotkeys.h
+ */
+#ifndef EESCHEMA_KOTKEYS_H_
+#define EESCHEMA_KOTKEYS_H_
+
+#include <hotkeys_basic.h>
+
+// List of hot keys id.
+// see also enum common_hotkey_id_commnand in hotkeys_basic.h
+// for shared hotkeys id
+enum hotkey_id_commnand {
+ HK_FIND_NEXT_ITEM = HK_COMMON_END,
+ HK_FIND_NEXT_DRC_MARKER,
+ HK_FIND_ITEM,
+ HK_FIND_REPLACE,
+ HK_DELETE,
+ HK_REPEAT_LAST,
+ HK_LIBEDIT_MOVE_GRAPHIC_ITEM,
+ HK_MOVEBLOCK_TO_DRAGBLOCK,
+ HK_SAVE_BLOCK,
+ HK_LIBEDIT_CREATE_PIN,
+ HK_DELETE_PIN,
+ HK_ROTATE,
+ HK_EDIT,
+ HK_EDIT_COMPONENT_VALUE,
+ HK_EDIT_COMPONENT_REFERENCE,
+ HK_EDIT_COMPONENT_FOOTPRINT,
+ HK_EDIT_COMPONENT_WITH_LIBEDIT,
+ HK_MIRROR_X,
+ HK_MIRROR_Y,
+ HK_ORIENT_NORMAL_COMPONENT,
+ HK_MOVE_COMPONENT_OR_ITEM,
+ HK_COPY_COMPONENT_OR_LABEL,
+ HK_DRAG,
+ HK_ADD_NEW_COMPONENT,
+ HK_ADD_NEW_POWER,
+ HK_BEGIN_WIRE,
+ HK_BEGIN_BUS,
+ HK_END_CURR_LINEWIREBUS,
+ HK_ADD_WIRE_ENTRY,
+ HK_ADD_BUS_ENTRY,
+ HK_ADD_LABEL,
+ HK_ADD_HLABEL,
+ HK_ADD_GLABEL,
+ HK_ADD_JUNCTION,
+ HK_ADD_HIER_SHEET,
+ HK_ADD_GRAPHIC_TEXT,
+ HK_ADD_GRAPHIC_POLYLINE,
+ HK_ADD_NOCONN_FLAG,
+ HK_SAVE_LIB,
+ HK_SAVE_SCH,
+ HK_LOAD_SCH,
+ HK_LEFT_CLICK,
+ HK_LEFT_DCLICK,
+ HK_LEAVE_SHEET,
+ HK_DELETE_NODE
+};
+
+// List of hotkey descriptors for Eeschema
+extern struct EDA_HOTKEY_CONFIG g_Eeschema_Hokeys_Descr[];
+
+// List of hotkey descriptors for the schematic editor only
+extern struct EDA_HOTKEY_CONFIG g_Schematic_Hokeys_Descr[];
+
+// List of hotkey descriptors for the lib editor only
+extern struct EDA_HOTKEY_CONFIG g_Libedit_Hokeys_Descr[];
+
+// List of hotkey descriptors for the lib browser only
+extern struct EDA_HOTKEY_CONFIG g_Viewlib_Hokeys_Descr[];
+
+#endif // EESCHEMA_KOTKEYS_H_
diff --git a/eeschema/invoke_sch_dialog.h b/eeschema/invoke_sch_dialog.h
new file mode 100644
index 0000000..fe36a41
--- /dev/null
+++ b/eeschema/invoke_sch_dialog.h
@@ -0,0 +1,97 @@
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+// This header is an insolation layer between top most frames and any number of
+// DIALOG classes which can be called from a frame window.
+// It is a place to put invocation functions for [modal] dialogs, with benefits:
+//
+// 1) The information about each dialog class is not exposed to the frame.
+// So therefore the DIALOG class can often be kept out of a header file entirely.
+//
+// 2) The information about the calling frame is not necessarily exposed to
+// to the called dialog class, at least not in here.
+
+// The actual InvokeDialog<class>() function is usually coded at the bottom of the
+// DIALOG_<class>.cpp file.
+
+
+#ifndef INVOKE_SCH_DIALOG_H_
+#define INVOKE_SCH_DIALOG_H_
+
+#include <set>
+#include <vector>
+
+class wxFrame;
+class wxDialog;
+class LIB_PART;
+class PART_LIBS;
+class SCH_COMPONENT;
+class RESCUER;
+
+// Often this is not used in the prototypes, since wxFrame is good enough and would
+// represent maximum information hiding.
+class SCH_EDIT_FRAME;
+
+/**
+ * Function InvokeDialogRescueEach
+ * This dialog asks the user which rescuable, cached parts he wants to rescue.
+ * Any rejects will be pruned from aCandidates.
+ * @param aCaller - the SCH_EDIT_FRAME calling this
+ * @param aRescuer - the active RESCUER instance
+ * @param aAskShowAgain - if true, a "Never Show Again" button will be included
+ */
+int InvokeDialogRescueEach( SCH_EDIT_FRAME* aCaller, RESCUER& aRescuer, bool aAskShowAgain );
+
+/// Create and show DIALOG_ANNOTATE and return whatever
+/// DIALOG_ANNOTATE::ShowModal() returns.
+int InvokeDialogAnnotate( SCH_EDIT_FRAME* aCaller, wxString message = "" );
+
+/// Create the modeless DIALOG_ERC and show it, return something to
+/// destroy or close it. The dialog will have ID_DIALOG_ERC from id.h
+wxDialog* InvokeDialogERC( SCH_EDIT_FRAME* aCaller );
+
+/// Create and show DIALOG_PRINT_USING_PRINTER and return whatever
+/// DIALOG_PRINT_USING_PRINTER::ShowModal() returns.
+int InvokeDialogPrintUsingPrinter( SCH_EDIT_FRAME* aCaller );
+
+/// Create and show DIALOG_BOM and return whatever
+/// DIALOG_BOM::ShowModal() returns.
+int InvokeDialogCreateBOM( SCH_EDIT_FRAME* aCaller );
+
+/**
+ * Function InvokeDialogNetList
+ * creates and shows NETLIST_DIALOG and returns whatever
+ * NETLIST_DIALOG::ShowModal() returns.
+ * @param int - NET_PLUGIN_CHANGE means user added or deleted a plugin,
+ * wxID_OK, or wxID_CANCEL.
+*/
+#define NET_PLUGIN_CHANGE 1
+int InvokeDialogNetList( SCH_EDIT_FRAME* aCaller );
+
+bool InvokeEeschemaConfig( wxWindow* aParent,
+ wxString* aCallersProjectSpecificLibPaths, wxArrayString* aCallersLibNames );
+
+
+#endif // INVOKE_SCH_DIALOG_H_
diff --git a/eeschema/lib_arc.cpp b/eeschema/lib_arc.cpp
new file mode 100644
index 0000000..68f52ef
--- /dev/null
+++ b/eeschema/lib_arc.cpp
@@ -0,0 +1,825 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_arc.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <plot_common.h>
+#include <trigo.h>
+#include <wxstruct.h>
+#include <richio.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <lib_arc.h>
+#include <transform.h>
+
+// Helper function
+static inline wxPoint twoPointVector( const wxPoint &startPoint, const wxPoint &endPoint )
+{
+ return endPoint - startPoint;
+}
+
+
+//! @brief Given three points A B C, compute the circumcenter of the resulting triangle
+//! reference: http://en.wikipedia.org/wiki/Circumscribed_circle
+//! Coordinates of circumcenter in Cartesian coordinates
+static wxPoint calcCenter( const wxPoint& A, const wxPoint& B, const wxPoint& C )
+{
+ double circumCenterX, circumCenterY;
+ double Ax = (double) A.x;
+ double Ay = (double) A.y;
+ double Bx = (double) B.x;
+ double By = (double) B.y;
+ double Cx = (double) C.x;
+ double Cy = (double) C.y;
+
+ wxPoint circumCenter;
+
+ double D = 2.0 * ( Ax * ( By - Cy ) + Bx * ( Cy - Ay ) + Cx * ( Ay - By ) );
+
+ // prevent division / 0
+ if( fabs( D ) < 1e-7 )
+ D = 1e-7;
+
+ circumCenterX = ( (Ay * Ay + Ax * Ax) * (By - Cy) +
+ (By * By + Bx * Bx) * (Cy - Ay) +
+ (Cy * Cy + Cx * Cx) * (Ay - By) ) / D;
+
+ circumCenterY = ( (Ay * Ay + Ax * Ax) * (Cx - Bx) +
+ (By * By + Bx * Bx) * (Ax - Cx) +
+ (Cy * Cy + Cx * Cx) * (Bx - Ax) ) / D;
+
+ circumCenter.x = (int) circumCenterX;
+ circumCenter.y = (int) circumCenterY;
+
+ return circumCenter;
+}
+
+
+LIB_ARC::LIB_ARC( LIB_PART* aParent ) : LIB_ITEM( LIB_ARC_T, aParent )
+{
+ m_Radius = 0;
+ m_t1 = 0;
+ m_t2 = 0;
+ m_Width = 0;
+ m_Fill = NO_FILL;
+ m_isFillable = true;
+ m_typeName = _( "Arc" );
+ m_editState = 0;
+ m_lastEditState = 0;
+ m_editCenterDistance = 0.0;
+ m_editSelectPoint = ARC_STATUS_START;
+ m_editDirection = 0;
+}
+
+
+bool LIB_ARC::Save( OUTPUTFORMATTER& aFormatter )
+{
+ int x1 = m_t1;
+
+ if( x1 > 1800 )
+ x1 -= 3600;
+
+ int x2 = m_t2;
+
+ if( x2 > 1800 )
+ x2 -= 3600;
+
+ aFormatter.Print( 0, "A %d %d %d %d %d %d %d %d %c %d %d %d %d\n",
+ m_Pos.x, m_Pos.y, m_Radius, x1, x2, m_Unit, m_Convert, m_Width,
+ fill_tab[m_Fill], m_ArcStart.x, m_ArcStart.y, m_ArcEnd.x,
+ m_ArcEnd.y );
+
+ return true;
+}
+
+
+bool LIB_ARC::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
+{
+ int startx, starty, endx, endy, cnt;
+ char tmp[256] = "";
+ char* line = (char*) aLineReader;
+
+ cnt = sscanf( line + 2, "%d %d %d %d %d %d %d %d %255s %d %d %d %d",
+ &m_Pos.x, &m_Pos.y, &m_Radius, &m_t1, &m_t2, &m_Unit,
+ &m_Convert, &m_Width, tmp, &startx, &starty, &endx, &endy );
+ if( cnt < 8 )
+ {
+ aErrorMsg.Printf( _( "Arc only had %d parameters of the required 8" ), cnt );
+ return false;
+ }
+
+ if( tmp[0] == 'F' )
+ m_Fill = FILLED_SHAPE;
+
+ if( tmp[0] == 'f' )
+ m_Fill = FILLED_WITH_BG_BODYCOLOR;
+
+ NORMALIZE_ANGLE_POS( m_t1 );
+ NORMALIZE_ANGLE_POS( m_t2 );
+
+ // Actual Coordinates of arc ends are read from file
+ if( cnt >= 13 )
+ {
+ m_ArcStart.x = startx;
+ m_ArcStart.y = starty;
+ m_ArcEnd.x = endx;
+ m_ArcEnd.y = endy;
+ }
+ else
+ {
+ // Actual Coordinates of arc ends are not read from file
+ // (old library), calculate them
+ m_ArcStart.x = m_Radius;
+ m_ArcStart.y = 0;
+ m_ArcEnd.x = m_Radius;
+ m_ArcEnd.y = 0;
+ RotatePoint( &m_ArcStart.x, &m_ArcStart.y, -m_t1 );
+ m_ArcStart.x += m_Pos.x;
+ m_ArcStart.y += m_Pos.y;
+ RotatePoint( &m_ArcEnd.x, &m_ArcEnd.y, -m_t2 );
+ m_ArcEnd.x += m_Pos.x;
+ m_ArcEnd.y += m_Pos.y;
+ }
+
+ return true;
+}
+
+
+bool LIB_ARC::HitTest( const wxPoint& aRefPoint ) const
+{
+ int mindist = GetPenSize() / 2;
+
+ // Have a minimal tolerance for hit test
+ if( mindist < MINIMUM_SELECTION_DISTANCE )
+ mindist = MINIMUM_SELECTION_DISTANCE;
+
+ return HitTest( aRefPoint, mindist, DefaultTransform );
+}
+
+
+bool LIB_ARC::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
+{
+
+ if( aThreshold < 0 )
+ aThreshold = GetPenSize() / 2;
+
+ // TODO: use aTransMat to calculates parameters
+ wxPoint relativePosition = aPosition;
+
+ relativePosition.y = -relativePosition.y; // reverse Y axis
+
+ int distance = KiROUND( GetLineLength( m_Pos, relativePosition ) );
+
+ if( abs( distance - m_Radius ) > aThreshold )
+ return false;
+
+ // We are on the circle, ensure we are only on the arc, i.e. between
+ // m_ArcStart and m_ArcEnd
+
+ wxPoint startEndVector = twoPointVector( m_ArcStart, m_ArcEnd);
+ wxPoint startRelativePositionVector = twoPointVector( m_ArcStart, relativePosition );
+
+ wxPoint centerStartVector = twoPointVector( m_Pos, m_ArcStart );
+ wxPoint centerEndVector = twoPointVector( m_Pos, m_ArcEnd );
+ wxPoint centerRelativePositionVector = twoPointVector( m_Pos, relativePosition );
+
+ // Compute the cross product to check if the point is in the sector
+ double crossProductStart = CrossProduct( centerStartVector, centerRelativePositionVector );
+ double crossProductEnd = CrossProduct( centerEndVector, centerRelativePositionVector );
+
+ // The cross products need to be exchanged, depending on which side the center point
+ // relative to the start point to end point vector lies
+ if( CrossProduct( startEndVector, startRelativePositionVector ) < 0 )
+ {
+ std::swap( crossProductStart, crossProductEnd );
+ }
+
+ // When the cross products have a different sign, the point lies in sector
+ // also check, if the reference is near start or end point
+ return HitTestPoints( m_ArcStart, relativePosition, MINIMUM_SELECTION_DISTANCE ) ||
+ HitTestPoints( m_ArcEnd, relativePosition, MINIMUM_SELECTION_DISTANCE ) ||
+ ( crossProductStart <= 0 && crossProductEnd >= 0 );
+}
+
+
+EDA_ITEM* LIB_ARC::Clone() const
+{
+ return new LIB_ARC( *this );
+}
+
+
+int LIB_ARC::compare( const LIB_ITEM& aOther ) const
+{
+ wxASSERT( aOther.Type() == LIB_ARC_T );
+
+ const LIB_ARC* tmp = ( LIB_ARC* ) &aOther;
+
+ if( m_Pos.x != tmp->m_Pos.x )
+ return m_Pos.x - tmp->m_Pos.x;
+
+ if( m_Pos.y != tmp->m_Pos.y )
+ return m_Pos.y - tmp->m_Pos.y;
+
+ if( m_t1 != tmp->m_t1 )
+ return m_t1 - tmp->m_t1;
+
+ if( m_t2 != tmp->m_t2 )
+ return m_t2 - tmp->m_t2;
+
+ return 0;
+}
+
+
+void LIB_ARC::SetOffset( const wxPoint& aOffset )
+{
+ m_Pos += aOffset;
+ m_ArcStart += aOffset;
+ m_ArcEnd += aOffset;
+}
+
+
+bool LIB_ARC::Inside( EDA_RECT& aRect ) const
+{
+ return aRect.Contains( m_ArcStart.x, -m_ArcStart.y )
+ || aRect.Contains( m_ArcEnd.x, -m_ArcEnd.y );
+}
+
+
+void LIB_ARC::Move( const wxPoint& aPosition )
+{
+ wxPoint offset = aPosition - m_Pos;
+ m_Pos = aPosition;
+ m_ArcStart += offset;
+ m_ArcEnd += offset;
+}
+
+
+void LIB_ARC::MirrorHorizontal( const wxPoint& aCenter )
+{
+ m_Pos.x -= aCenter.x;
+ m_Pos.x *= -1;
+ m_Pos.x += aCenter.x;
+ m_ArcStart.x -= aCenter.x;
+ m_ArcStart.x *= -1;
+ m_ArcStart.x += aCenter.x;
+ m_ArcEnd.x -= aCenter.x;
+ m_ArcEnd.x *= -1;
+ m_ArcEnd.x += aCenter.x;
+ std::swap( m_ArcStart, m_ArcEnd );
+ std::swap( m_t1, m_t2 );
+ m_t1 = 1800 - m_t1;
+ m_t2 = 1800 - m_t2;
+ if( m_t1 > 3600 || m_t2 > 3600 )
+ {
+ m_t1 -= 3600;
+ m_t2 -= 3600;
+ }
+ else if( m_t1 < -3600 || m_t2 < -3600 )
+ {
+ m_t1 += 3600;
+ m_t2 += 3600;
+ }
+}
+
+void LIB_ARC::MirrorVertical( const wxPoint& aCenter )
+{
+ m_Pos.y -= aCenter.y;
+ m_Pos.y *= -1;
+ m_Pos.y += aCenter.y;
+ m_ArcStart.y -= aCenter.y;
+ m_ArcStart.y *= -1;
+ m_ArcStart.y += aCenter.y;
+ m_ArcEnd.y -= aCenter.y;
+ m_ArcEnd.y *= -1;
+ m_ArcEnd.y += aCenter.y;
+ std::swap( m_ArcStart, m_ArcEnd );
+ std::swap( m_t1, m_t2 );
+ m_t1 = - m_t1;
+ m_t2 = - m_t2;
+ if( m_t1 > 3600 || m_t2 > 3600 )
+ {
+ m_t1 -= 3600;
+ m_t2 -= 3600;
+ }
+ else if( m_t1 < -3600 || m_t2 < -3600 )
+ {
+ m_t1 += 3600;
+ m_t2 += 3600;
+ }
+}
+
+void LIB_ARC::Rotate( const wxPoint& aCenter, bool aRotateCCW )
+{
+ int rot_angle = aRotateCCW ? -900 : 900;
+ RotatePoint( &m_Pos, aCenter, rot_angle );
+ RotatePoint( &m_ArcStart, aCenter, rot_angle );
+ RotatePoint( &m_ArcEnd, aCenter, rot_angle );
+ m_t1 -= rot_angle;
+ m_t2 -= rot_angle;
+ if( m_t1 > 3600 || m_t2 > 3600 )
+ {
+ m_t1 -= 3600;
+ m_t2 -= 3600;
+ }
+ else if( m_t1 < -3600 || m_t2 < -3600 )
+ {
+ m_t1 += 3600;
+ m_t2 += 3600;
+ }
+}
+
+
+
+void LIB_ARC::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform )
+{
+ wxASSERT( aPlotter != NULL );
+
+ int t1 = m_t1;
+ int t2 = m_t2;
+ wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
+
+ aTransform.MapAngles( &t1, &t2 );
+
+ if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
+ {
+ aPlotter->SetColor( GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
+ aPlotter->Arc( pos, -t2, -t1, m_Radius, FILLED_SHAPE, 0 );
+ }
+
+ bool already_filled = m_Fill == FILLED_WITH_BG_BODYCOLOR;
+ aPlotter->SetColor( GetLayerColor( LAYER_DEVICE ) );
+ aPlotter->Arc( pos, -t2, -t1, m_Radius, already_filled ? NO_FILL : m_Fill, GetPenSize() );
+}
+
+
+int LIB_ARC::GetPenSize() const
+{
+ return ( m_Width == 0 ) ? GetDefaultLineThickness() : m_Width;
+}
+
+
+void LIB_ARC::drawEditGraphics( EDA_RECT* aClipBox, wxDC* aDC, EDA_COLOR_T aColor )
+{
+ // The edit indicators only get drawn when a new arc is being drawn.
+ if( !IsNew() )
+ return;
+
+ // Use the last edit state so when the drawing switches from the end mode to the center
+ // point mode, the last line between the center points gets erased.
+ if( m_lastEditState == 1 )
+ {
+ GRLine( aClipBox, aDC, m_ArcStart.x, -m_ArcStart.y, m_ArcEnd.x, -m_ArcEnd.y, 0, aColor );
+ }
+ else
+ {
+ GRDashedLine( aClipBox, aDC, m_ArcStart.x, -m_ArcStart.y, m_Pos.x, -m_Pos.y, 0, aColor );
+ GRDashedLine( aClipBox, aDC, m_ArcEnd.x, -m_ArcEnd.y, m_Pos.x, -m_Pos.y, 0, aColor );
+ }
+}
+
+
+void LIB_ARC::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform )
+{
+ // Don't draw the arc until the end point is selected. Only the edit indicators
+ // get drawn at this time.
+ if( IsNew() && m_lastEditState == 1 )
+ return;
+
+ wxPoint pos1, pos2, posc;
+ EDA_COLOR_T color = GetLayerColor( LAYER_DEVICE );
+
+ if( aColor < 0 ) // Used normal color or selected color
+ {
+ if( IsSelected() )
+ color = GetItemSelectedColor();
+ }
+ else
+ {
+ color = aColor;
+ }
+
+ pos1 = aTransform.TransformCoordinate( m_ArcEnd ) + aOffset;
+ pos2 = aTransform.TransformCoordinate( m_ArcStart ) + aOffset;
+ posc = aTransform.TransformCoordinate( m_Pos ) + aOffset;
+ int pt1 = m_t1;
+ int pt2 = m_t2;
+ bool swap = aTransform.MapAngles( &pt1, &pt2 );
+
+ if( swap )
+ {
+ std::swap( pos1.x, pos2.x );
+ std::swap( pos1.y, pos2.y );
+ }
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ FILL_T fill = aData ? NO_FILL : m_Fill;
+
+ if( aColor >= 0 )
+ fill = NO_FILL;
+
+ EDA_RECT* const clipbox = aPanel? aPanel->GetClipBox() : NULL;
+
+ if( fill == FILLED_WITH_BG_BODYCOLOR )
+ {
+ GRFilledArc( clipbox, aDC, posc.x, posc.y, pt1, pt2,
+ m_Radius, GetPenSize( ),
+ (m_Flags & IS_MOVED) ? color : GetLayerColor( LAYER_DEVICE_BACKGROUND ),
+ GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
+ }
+ else if( fill == FILLED_SHAPE && !aData )
+ {
+ GRFilledArc( clipbox, aDC, posc.x, posc.y, pt1, pt2, m_Radius,
+ color, color );
+ }
+ else
+ {
+
+#ifdef DRAW_ARC_WITH_ANGLE
+
+ GRArc( clipbox, aDC, posc.x, posc.y, pt1, pt2, m_Radius,
+ GetPenSize(), color );
+#else
+
+ GRArc1( clipbox, aDC, pos1.x, pos1.y, pos2.x, pos2.y,
+ posc.x, posc.y, GetPenSize(), color );
+#endif
+ }
+
+ /* Set to one (1) to draw bounding box around arc to validate bounding box
+ * calculation. */
+#if 0
+ EDA_RECT bBox = GetBoundingBox();
+ bBox.RevertYAxis();
+ bBox = aTransform.TransformCoordinate( bBox );
+ bBox.Move( aOffset );
+ GRRect( clipbox, aDC, bBox, 0, LIGHTMAGENTA );
+#endif
+}
+
+
+const EDA_RECT LIB_ARC::GetBoundingBox() const
+{
+ int minX, minY, maxX, maxY, angleStart, angleEnd;
+ EDA_RECT rect;
+ wxPoint nullPoint, startPos, endPos, centerPos;
+ wxPoint normStart = m_ArcStart - m_Pos;
+ wxPoint normEnd = m_ArcEnd - m_Pos;
+
+ if( ( normStart == nullPoint ) || ( normEnd == nullPoint ) || ( m_Radius == 0 ) )
+ {
+ wxLogDebug( wxT("Invalid arc drawing definition, center(%d, %d) \
+start(%d, %d), end(%d, %d), radius %d" ),
+ m_Pos.x, m_Pos.y, m_ArcStart.x, m_ArcStart.y, m_ArcEnd.x,
+ m_ArcEnd.y, m_Radius );
+ return rect;
+ }
+
+ endPos = DefaultTransform.TransformCoordinate( m_ArcEnd );
+ startPos = DefaultTransform.TransformCoordinate( m_ArcStart );
+ centerPos = DefaultTransform.TransformCoordinate( m_Pos );
+ angleStart = m_t1;
+ angleEnd = m_t2;
+
+ if( DefaultTransform.MapAngles( &angleStart, &angleEnd ) )
+ {
+ std::swap( endPos.x, startPos.x );
+ std::swap( endPos.y, startPos.y );
+ }
+
+ /* Start with the start and end point of the arc. */
+ minX = std::min( startPos.x, endPos.x );
+ minY = std::min( startPos.y, endPos.y );
+ maxX = std::max( startPos.x, endPos.x );
+ maxY = std::max( startPos.y, endPos.y );
+
+ /* Zero degrees is a special case. */
+ if( angleStart == 0 )
+ maxX = centerPos.x + m_Radius;
+
+ /* Arc end angle wrapped passed 360. */
+ if( angleStart > angleEnd )
+ angleEnd += 3600;
+
+ if( angleStart <= 900 && angleEnd >= 900 ) /* 90 deg */
+ maxY = centerPos.y + m_Radius;
+
+ if( angleStart <= 1800 && angleEnd >= 1800 ) /* 180 deg */
+ minX = centerPos.x - m_Radius;
+
+ if( angleStart <= 2700 && angleEnd >= 2700 ) /* 270 deg */
+ minY = centerPos.y - m_Radius;
+
+ if( angleStart <= 3600 && angleEnd >= 3600 ) /* 0 deg */
+ maxX = centerPos.x + m_Radius;
+
+ rect.SetOrigin( minX, minY );
+ rect.SetEnd( maxX, maxY );
+ rect.Inflate( ( GetPenSize()+1 ) / 2 );
+
+ return rect;
+}
+
+
+void LIB_ARC::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString msg;
+ EDA_RECT bBox = GetBoundingBox();
+
+ LIB_ITEM::GetMsgPanelInfo( aList );
+
+ msg = StringFromValue( g_UserUnit, m_Width, true );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Line Width" ), msg, BLUE ) );
+
+ msg.Printf( wxT( "(%d, %d, %d, %d)" ), bBox.GetOrigin().x,
+ bBox.GetOrigin().y, bBox.GetEnd().x, bBox.GetEnd().y );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Bounding Box" ), msg, BROWN ) );
+}
+
+
+wxString LIB_ARC::GetSelectMenuText() const
+{
+ return wxString::Format( _( "Arc center (%s, %s), radius %s" ),
+ GetChars( CoordinateToString( m_Pos.x ) ),
+ GetChars( CoordinateToString( m_Pos.y ) ),
+ GetChars( CoordinateToString( m_Radius ) ) );
+}
+
+
+void LIB_ARC::BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aPosition )
+{
+ wxCHECK_RET( ( aEditMode & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
+ wxT( "Invalid edit mode for LIB_ARC object." ) );
+
+ if( aEditMode == IS_NEW )
+ {
+ m_ArcStart = m_ArcEnd = aPosition;
+ m_editState = m_lastEditState = 1;
+ }
+ else if( aEditMode == IS_MOVED )
+ {
+ m_initialPos = m_Pos;
+ m_initialCursorPos = aPosition;
+ SetEraseLastDrawItem();
+ }
+ else
+ {
+ // The arc center point has to be rotated with while adjusting the
+ // start or end point, determine the side of this point and the distance
+ // from the start / end point
+ wxPoint middlePoint = wxPoint( (m_ArcStart.x + m_ArcEnd.x) / 2,
+ (m_ArcStart.y + m_ArcEnd.y) / 2 );
+ wxPoint centerVector = m_Pos - middlePoint;
+ wxPoint startEndVector = twoPointVector( m_ArcStart, m_ArcEnd );
+ m_editCenterDistance = EuclideanNorm( centerVector );
+
+ // Determine on which side is the center point
+ m_editDirection = CrossProduct( startEndVector, centerVector ) ? 1 : -1;
+
+ // Drag either the start, end point or the outline
+ if( HitTestPoints( m_ArcStart, aPosition, MINIMUM_SELECTION_DISTANCE ) )
+ {
+ m_editSelectPoint = ARC_STATUS_START;
+ }
+ else if( HitTestPoints( m_ArcEnd, aPosition, MINIMUM_SELECTION_DISTANCE ) )
+ {
+ m_editSelectPoint = ARC_STATUS_END;
+ }
+ else
+ {
+ m_editSelectPoint = ARC_STATUS_OUTLINE;
+ }
+
+ m_editState = 0;
+ SetEraseLastDrawItem();
+ }
+
+ m_Flags = aEditMode;
+}
+
+
+bool LIB_ARC::ContinueEdit( const wxPoint aPosition )
+{
+ wxCHECK_MSG( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0, false,
+ wxT( "Bad call to ContinueEdit(). LIB_ARC is not being edited." ) );
+
+ if( m_Flags == IS_NEW )
+ {
+ if( m_editState == 1 ) // Second position yields the arc segment length.
+ {
+ m_ArcEnd = aPosition;
+ m_editState = 2;
+ SetEraseLastDrawItem( false );
+ return true; // Need third position to calculate center point.
+ }
+ }
+
+ return false;
+}
+
+
+void LIB_ARC::EndEdit( const wxPoint& aPosition, bool aAbort )
+{
+ wxCHECK_RET( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
+ wxT( "Bad call to EndEdit(). LIB_ARC is not being edited." ) );
+
+ SetEraseLastDrawItem( false );
+ m_lastEditState = 0;
+ m_editState = 0;
+ m_Flags = 0;
+}
+
+
+void LIB_ARC::calcEdit( const wxPoint& aPosition )
+{
+ if( m_Flags == IS_RESIZED )
+ {
+ wxPoint newCenterPoint, startPos, endPos;
+
+ // Choose the point of the arc to be adjusted
+ if( m_editSelectPoint == ARC_STATUS_START )
+ {
+ startPos = aPosition;
+ endPos = m_ArcEnd;
+ }
+ else if( m_editSelectPoint == ARC_STATUS_END )
+ {
+ endPos = aPosition;
+ startPos = m_ArcStart;
+ }
+ else
+ {
+ // Use the cursor for adjusting the arc curvature
+ startPos = m_ArcStart;
+ endPos = m_ArcEnd;
+
+ // If the distance is too small, use the old center point
+ // else the new center point is calculated over the three points start/end/cursor
+ if( DistanceLinePoint( startPos, endPos, aPosition ) > MINIMUM_SELECTION_DISTANCE )
+ {
+ newCenterPoint = calcCenter( startPos, aPosition, endPos );
+ }
+ else
+ {
+ newCenterPoint = m_Pos;
+ }
+
+ // Determine if the arc angle is larger than 180 degrees -> this happens if both
+ // points (cursor position, center point) lie on the same side of the vector
+ // start-end
+ double crossA = CrossProduct( twoPointVector( startPos, endPos ),
+ twoPointVector( endPos, aPosition ) );
+ double crossB = CrossProduct( twoPointVector( startPos, endPos ),
+ twoPointVector( endPos, newCenterPoint ) );
+
+ if( ( crossA < 0 && crossB < 0 ) || ( crossA >= 0 && crossB >= 0 ) )
+ newCenterPoint = m_Pos;
+ }
+
+ if( m_editSelectPoint == ARC_STATUS_START || m_editSelectPoint == ARC_STATUS_END )
+ {
+ // Compute the new center point when the start/end points are modified
+ wxPoint middlePoint = wxPoint( (startPos.x + endPos.x) / 2,
+ (startPos.y + endPos.y) / 2 );
+
+ wxPoint startEndVector = twoPointVector( startPos, endPos );
+ wxPoint perpendicularVector = wxPoint( -startEndVector.y, startEndVector.x );
+ double lengthPerpendicularVector = EuclideanNorm( perpendicularVector );
+
+ // prevent too large values, division / 0
+ if( lengthPerpendicularVector < 1e-1 )
+ lengthPerpendicularVector = 1e-1;
+
+ perpendicularVector.x = (int) ( (double) perpendicularVector.x *
+ m_editCenterDistance /
+ lengthPerpendicularVector ) * m_editDirection;
+ perpendicularVector.y = (int) ( (double) perpendicularVector.y *
+ m_editCenterDistance /
+ lengthPerpendicularVector ) * m_editDirection;
+
+ newCenterPoint = middlePoint + perpendicularVector;
+
+ m_ArcStart = startPos;
+ m_ArcEnd = endPos;
+ }
+
+ m_Pos = newCenterPoint;
+ calcRadiusAngles();
+ }
+ else if( m_Flags == IS_NEW )
+ {
+ if( m_editState == 1 )
+ {
+ m_ArcEnd = aPosition;
+ }
+
+ if( m_editState != m_lastEditState )
+ m_lastEditState = m_editState;
+
+ // Keep the arc center point up to date. Otherwise, there will be edit graphic
+ // artifacts left behind from the initial draw.
+ int dx, dy;
+ int cX, cY;
+ double angle;
+
+ cX = aPosition.x;
+ cY = aPosition.y;
+
+ dx = m_ArcEnd.x - m_ArcStart.x;
+ dy = m_ArcEnd.y - m_ArcStart.y;
+ cX -= m_ArcStart.x;
+ cY -= m_ArcStart.y;
+ angle = ArcTangente( dy, dx );
+ RotatePoint( &dx, &dy, angle ); /* The segment dx, dy is horizontal
+ * -> Length = dx, dy = 0 */
+ RotatePoint( &cX, &cY, angle );
+ cX = dx / 2; /* cX, cY is on the median segment 0.0 a dx, 0 */
+
+ RotatePoint( &cX, &cY, -angle );
+ cX += m_ArcStart.x;
+ cY += m_ArcStart.y;
+ m_Pos.x = cX;
+ m_Pos.y = cY;
+ calcRadiusAngles();
+
+ SetEraseLastDrawItem();
+ }
+ else if( m_Flags == IS_MOVED )
+ {
+ Move( m_initialPos + aPosition - m_initialCursorPos );
+ }
+}
+
+
+void LIB_ARC::calcRadiusAngles()
+{
+ wxPoint centerStartVector = twoPointVector( m_Pos, m_ArcStart );
+ wxPoint centerEndVector = twoPointVector( m_Pos, m_ArcEnd );
+
+ m_Radius = KiROUND( EuclideanNorm( centerStartVector ) );
+
+ // Angles in eeschema are still integers
+ m_t1 = KiROUND( ArcTangente( centerStartVector.y, centerStartVector.x ) );
+ m_t2 = KiROUND( ArcTangente( centerEndVector.y, centerEndVector.x ) );
+
+ NORMALIZE_ANGLE_POS( m_t1 );
+ NORMALIZE_ANGLE_POS( m_t2 ); // angles = 0 .. 3600
+
+ // Restrict angle to less than 180 to avoid PBS display mirror Trace because it is
+ // assumed that the arc is less than 180 deg to find orientation after rotate or mirror.
+ if( (m_t2 - m_t1) > 1800 )
+ m_t2 -= 3600;
+ else if( (m_t2 - m_t1) <= -1800 )
+ m_t2 += 3600;
+
+ while( (m_t2 - m_t1) >= 1800 )
+ {
+ m_t2--;
+ m_t1++;
+ }
+
+ while( (m_t1 - m_t2) >= 1800 )
+ {
+ m_t2++;
+ m_t1--;
+ }
+
+ NORMALIZE_ANGLE_POS( m_t1 );
+
+ if( !IsMoving() )
+ NORMALIZE_ANGLE_POS( m_t2 );
+}
diff --git a/eeschema/lib_arc.h b/eeschema/lib_arc.h
new file mode 100644
index 0000000..dcebbdf
--- /dev/null
+++ b/eeschema/lib_arc.h
@@ -0,0 +1,161 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_arc.h
+ */
+
+#ifndef _LIB_ARC_H_
+#define _LIB_ARC_H_
+
+#include <lib_draw_item.h>
+
+
+class TRANSFORM;
+
+
+class LIB_ARC : public LIB_ITEM
+{
+ enum SELECT_T // When creating an arc: status of arc
+ {
+ ARC_STATUS_START,
+ ARC_STATUS_END,
+ ARC_STATUS_OUTLINE,
+ };
+
+ int m_Radius;
+ int m_t1; // First radius angle of the arc in 0.1 degrees.
+ int m_t2; /* Second radius angle of the arc in 0.1 degrees. */
+ wxPoint m_ArcStart;
+ wxPoint m_ArcEnd; /* Arc end position. */
+ wxPoint m_Pos; /* Radius center point. */
+ int m_Width; /* Line width */
+ double m_editCenterDistance;
+ SELECT_T m_editSelectPoint;
+ int m_editState;
+ int m_editDirection;
+ int m_lastEditState;
+
+ /**
+ * Draws the arc.
+ */
+ void drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform );
+
+ /**
+ * Draw the graphics when the arc is being edited.
+ */
+ void drawEditGraphics( EDA_RECT* aClipBox, wxDC* aDC, EDA_COLOR_T aColor );
+
+ /**
+ * Calculates the center, radius, and angles at \a aPosition when the arc is being edited.
+ *
+ * Note: The center may not necessarily be on the grid.
+ *
+ * @param aPosition - The current mouse position in drawing coordinates.
+ */
+ void calcEdit( const wxPoint& aPosition );
+
+ /**
+ * Calculate the radius and angle of an arc using the start, end, and center points.
+ */
+ void calcRadiusAngles();
+
+public:
+ LIB_ARC( LIB_PART * aParent );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~LIB_ARC() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "LIB_ARC" );
+ }
+
+
+ bool Save( OUTPUTFORMATTER& aFormatter );
+
+ bool Load( LINE_READER& aLineReader, wxString& aErrorMsg );
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ bool HitTest( const wxPoint& aPosition, int aThreshold, const TRANSFORM& aTransform ) const;
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ int GetPenSize() const;
+
+ void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) );
+
+ bool ContinueEdit( const wxPoint aNextPoint );
+
+ void EndEdit( const wxPoint& aPosition, bool aAbort = false );
+
+ void SetOffset( const wxPoint& aOffset );
+
+ bool Inside( EDA_RECT& aRect ) const;
+
+ void Move( const wxPoint& aPosition );
+
+ wxPoint GetPosition() const { return m_Pos; }
+
+ void MirrorHorizontal( const wxPoint& aCenter );
+
+ void MirrorVertical( const wxPoint& aCenter );
+
+ void Rotate( const wxPoint& aCenter, bool aRotateCCW = true );
+
+ void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform );
+
+ int GetWidth() const { return m_Width; }
+
+ void SetWidth( int aWidth ) { m_Width = aWidth; }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_arc_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+private:
+
+ /**
+ * @copydoc LIB_ITEM::compare()
+ *
+ * The arc specific sort order is as follows:
+ * - Arc horizontal (X) position.
+ * - Arc vertical (Y) position.
+ * - Arc start angle.
+ * - Arc end angle.
+ */
+ int compare( const LIB_ITEM& aOther ) const;
+};
+
+
+#endif // _LIB_ARC_H_
diff --git a/eeschema/lib_bezier.cpp b/eeschema/lib_bezier.cpp
new file mode 100644
index 0000000..35c3187
--- /dev/null
+++ b/eeschema/lib_bezier.cpp
@@ -0,0 +1,421 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_bezier.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <plot_common.h>
+#include <trigo.h>
+#include <wxstruct.h>
+#include <bezier_curves.h>
+#include <richio.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <lib_bezier.h>
+#include <transform.h>
+
+
+LIB_BEZIER::LIB_BEZIER( LIB_PART* aParent ) :
+ LIB_ITEM( LIB_BEZIER_T, aParent )
+{
+ m_Fill = NO_FILL;
+ m_Width = 0;
+ m_isFillable = true;
+ m_typeName = _( "Bezier" );
+}
+
+
+bool LIB_BEZIER::Save( OUTPUTFORMATTER& aFormatter )
+{
+ int ccount = GetCornerCount();
+
+ aFormatter.Print( 0, "B %d %d %d %d", ccount, m_Unit, m_Convert, m_Width );
+
+ for( unsigned i = 0; i < GetCornerCount(); i++ )
+ {
+ aFormatter.Print( 0, " %d %d", m_BezierPoints[i].x, m_BezierPoints[i].y );
+ }
+
+ aFormatter.Print( 0, " %c\n", fill_tab[m_Fill] );
+
+ return true;
+}
+
+
+bool LIB_BEZIER::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
+{
+ char* p;
+ int i, ccount = 0;
+ wxPoint pt;
+ char* line = (char*) aLineReader;
+
+ i = sscanf( line + 2, "%d %d %d %d", &ccount, &m_Unit, &m_Convert, &m_Width );
+
+ if( i !=4 )
+ {
+ aErrorMsg.Printf( _( "Bezier only had %d parameters of the required 4" ), i );
+ return false;
+ }
+
+ if( ccount <= 0 )
+ {
+ aErrorMsg.Printf( _( "Bezier count parameter %d is invalid" ), ccount );
+ return false;
+ }
+
+ strtok( line + 2, " \t\n" ); // Skip field
+ strtok( NULL, " \t\n" ); // Skip field
+ strtok( NULL, " \t\n" ); // Skip field
+ strtok( NULL, " \t\n" );
+
+ for( i = 0; i < ccount; i++ )
+ {
+ p = strtok( NULL, " \t\n" );
+
+ if( sscanf( p, "%d", &pt.x ) != 1 )
+ {
+ aErrorMsg.Printf( _( "Bezier point %d X position not defined" ), i );
+ return false;
+ }
+
+ p = strtok( NULL, " \t\n" );
+
+ if( sscanf( p, "%d", &pt.y ) != 1 )
+ {
+ aErrorMsg.Printf( _( "Bezier point %d Y position not defined" ), i );
+ return false;
+ }
+
+ m_BezierPoints.push_back( pt );
+ }
+
+ m_Fill = NO_FILL;
+
+ if( ( p = strtok( NULL, " \t\n" ) ) != NULL )
+ {
+ if( p[0] == 'F' )
+ m_Fill = FILLED_SHAPE;
+
+ if( p[0] == 'f' )
+ m_Fill = FILLED_WITH_BG_BODYCOLOR;
+ }
+
+ return true;
+}
+
+
+EDA_ITEM* LIB_BEZIER::Clone() const
+{
+ return new LIB_BEZIER( *this );
+}
+
+
+int LIB_BEZIER::compare( const LIB_ITEM& aOther ) const
+{
+ wxASSERT( aOther.Type() == LIB_BEZIER_T );
+
+ const LIB_BEZIER* tmp = ( LIB_BEZIER* ) &aOther;
+
+ if( m_BezierPoints.size() != tmp->m_BezierPoints.size() )
+ return m_BezierPoints.size() - tmp->m_BezierPoints.size();
+
+ for( size_t i = 0; i < m_BezierPoints.size(); i++ )
+ {
+ if( m_BezierPoints[i].x != tmp->m_BezierPoints[i].x )
+ return m_BezierPoints[i].x - tmp->m_BezierPoints[i].x;
+
+ if( m_BezierPoints[i].y != tmp->m_BezierPoints[i].y )
+ return m_BezierPoints[i].y - tmp->m_BezierPoints[i].y;
+ }
+
+ return 0;
+}
+
+
+void LIB_BEZIER::SetOffset( const wxPoint& aOffset )
+{
+ size_t i;
+
+ for( i = 0; i < m_BezierPoints.size(); i++ )
+ m_BezierPoints[i] += aOffset;
+
+ for( i = 0; i < m_PolyPoints.size(); i++ )
+ m_PolyPoints[i] += aOffset;
+}
+
+
+bool LIB_BEZIER::Inside( EDA_RECT& aRect ) const
+{
+ for( size_t i = 0; i < m_PolyPoints.size(); i++ )
+ {
+ if( aRect.Contains( m_PolyPoints[i].x, -m_PolyPoints[i].y ) )
+ return true;
+ }
+
+ return false;
+}
+
+
+void LIB_BEZIER::Move( const wxPoint& aPosition )
+{
+ SetOffset( aPosition - m_PolyPoints[0] );
+}
+
+
+void LIB_BEZIER::MirrorHorizontal( const wxPoint& aCenter )
+{
+ size_t i, imax = m_PolyPoints.size();
+
+ for( i = 0; i < imax; i++ )
+ {
+ m_PolyPoints[i].x -= aCenter.x;
+ m_PolyPoints[i].x *= -1;
+ m_PolyPoints[i].x += aCenter.x;
+ }
+
+ imax = m_BezierPoints.size();
+
+ for( i = 0; i < imax; i++ )
+ {
+ m_BezierPoints[i].x -= aCenter.x;
+ m_BezierPoints[i].x *= -1;
+ m_BezierPoints[i].x += aCenter.x;
+ }
+}
+
+void LIB_BEZIER::MirrorVertical( const wxPoint& aCenter )
+{
+ size_t i, imax = m_PolyPoints.size();
+
+ for( i = 0; i < imax; i++ )
+ {
+ m_PolyPoints[i].y -= aCenter.y;
+ m_PolyPoints[i].y *= -1;
+ m_PolyPoints[i].y += aCenter.y;
+ }
+
+ imax = m_BezierPoints.size();
+
+ for( i = 0; i < imax; i++ )
+ {
+ m_BezierPoints[i].y -= aCenter.y;
+ m_BezierPoints[i].y *= -1;
+ m_BezierPoints[i].y += aCenter.y;
+ }
+}
+
+void LIB_BEZIER::Rotate( const wxPoint& aCenter, bool aRotateCCW )
+{
+ int rot_angle = aRotateCCW ? -900 : 900;
+
+ size_t i, imax = m_PolyPoints.size();
+
+ for( i = 0; i < imax; i++ )
+ {
+ RotatePoint( &m_PolyPoints[i], aCenter, rot_angle );
+ }
+
+ imax = m_BezierPoints.size();
+
+ for( i = 0; i < imax; i++ )
+ {
+ RotatePoint( &m_BezierPoints[i], aCenter, rot_angle );
+ }
+}
+
+
+void LIB_BEZIER::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform )
+{
+ wxASSERT( aPlotter != NULL );
+
+ static std::vector< wxPoint > cornerList;
+ cornerList.clear();
+
+ for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
+ {
+ wxPoint pos = m_PolyPoints[ii];
+ pos = aTransform.TransformCoordinate( pos ) + aOffset;
+ cornerList.push_back( pos );
+ }
+
+ if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
+ {
+ aPlotter->SetColor( GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
+ aPlotter->PlotPoly( cornerList, FILLED_WITH_BG_BODYCOLOR, 0 );
+ }
+
+ bool already_filled = m_Fill == FILLED_WITH_BG_BODYCOLOR;
+ aPlotter->SetColor( GetLayerColor( LAYER_DEVICE ) );
+ aPlotter->PlotPoly( cornerList, already_filled ? NO_FILL : m_Fill, GetPenSize() );
+}
+
+
+int LIB_BEZIER::GetPenSize() const
+{
+ return ( m_Width == 0 ) ? GetDefaultLineThickness() : m_Width;
+}
+
+
+void LIB_BEZIER::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform )
+{
+ std::vector<wxPoint> PolyPointsTraslated;
+
+ EDA_COLOR_T color = GetLayerColor( LAYER_DEVICE );
+
+ m_PolyPoints = Bezier2Poly( m_BezierPoints[0],
+ m_BezierPoints[1],
+ m_BezierPoints[2],
+ m_BezierPoints[3] );
+
+ PolyPointsTraslated.clear();
+
+ for( unsigned int i = 0; i < m_PolyPoints.size() ; i++ )
+ PolyPointsTraslated.push_back( aTransform.TransformCoordinate( m_PolyPoints[i] ) +
+ aOffset );
+
+ if( aColor < 0 ) // Used normal color or selected color
+ {
+ if( IsSelected() )
+ color = GetItemSelectedColor();
+ }
+ else
+ {
+ color = aColor;
+ }
+
+ FILL_T fill = aData ? NO_FILL : m_Fill;
+
+ if( aColor >= 0 )
+ fill = NO_FILL;
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ if( fill == FILLED_WITH_BG_BODYCOLOR )
+ GRPoly( aPanel->GetClipBox(), aDC, m_PolyPoints.size(),
+ &PolyPointsTraslated[0], 1, GetPenSize(),
+ (m_Flags & IS_MOVED) ? color : GetLayerColor( LAYER_DEVICE_BACKGROUND ),
+ GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
+ else if( fill == FILLED_SHAPE )
+ GRPoly( aPanel->GetClipBox(), aDC, m_PolyPoints.size(),
+ &PolyPointsTraslated[0], 1, GetPenSize(), color, color );
+ else
+ GRPoly( aPanel->GetClipBox(), aDC, m_PolyPoints.size(),
+ &PolyPointsTraslated[0], 0, GetPenSize(), color, color );
+
+ /* Set to one (1) to draw bounding box around bezier curve to validate
+ * bounding box calculation. */
+#if 0
+ EDA_RECT bBox = GetBoundingBox();
+ GRRect( aPanel->GetClipBox(), aDC, bBox.GetOrigin().x, bBox.GetOrigin().y,
+ bBox.GetEnd().x, bBox.GetEnd().y, 0, LIGHTMAGENTA );
+#endif
+}
+
+
+bool LIB_BEZIER::HitTest( const wxPoint& aRefPos ) const
+{
+ int mindist = GetPenSize() / 2;
+
+ // Have a minimal tolerance for hit test
+ if ( mindist < MINIMUM_SELECTION_DISTANCE )
+ mindist = MINIMUM_SELECTION_DISTANCE;
+
+ return HitTest( aRefPos, mindist, DefaultTransform );
+}
+
+
+bool LIB_BEZIER::HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const
+{
+ wxPoint start, end;
+
+ if( aThreshold < 0 )
+ aThreshold = GetPenSize() / 2;
+
+ for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
+ {
+ start = aTransform.TransformCoordinate( m_PolyPoints[ii - 1] );
+ end = aTransform.TransformCoordinate( m_PolyPoints[ii] );
+
+ if ( TestSegmentHit( aPosRef, start, end, aThreshold ) )
+ return true;
+ }
+
+ return false;
+}
+
+
+const EDA_RECT LIB_BEZIER::GetBoundingBox() const
+{
+ EDA_RECT rect;
+ int xmin, xmax, ymin, ymax;
+
+ if( !GetCornerCount() )
+ return rect;
+
+ xmin = xmax = m_PolyPoints[0].x;
+ ymin = ymax = m_PolyPoints[0].y;
+
+ for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
+ {
+ xmin = std::min( xmin, m_PolyPoints[ii].x );
+ xmax = std::max( xmax, m_PolyPoints[ii].x );
+ ymin = std::min( ymin, m_PolyPoints[ii].y );
+ ymax = std::max( ymax, m_PolyPoints[ii].y );
+ }
+
+ rect.SetOrigin( xmin, ymin );
+ rect.SetEnd( xmax, ymax );
+ rect.Inflate( ( GetPenSize()+1 ) / 2 );
+
+ rect.RevertYAxis();
+
+ return rect;
+}
+
+
+void LIB_BEZIER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString msg;
+ EDA_RECT bBox = GetBoundingBox();
+
+ LIB_ITEM::GetMsgPanelInfo( aList );
+
+ msg = StringFromValue( g_UserUnit, m_Width, true );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Line Width" ), msg, BLUE ) );
+
+ msg.Printf( wxT( "(%d, %d, %d, %d)" ), bBox.GetOrigin().x,
+ bBox.GetOrigin().y, bBox.GetEnd().x, bBox.GetEnd().y );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Bounding Box" ), msg, BROWN ) );
+}
diff --git a/eeschema/lib_bezier.h b/eeschema/lib_bezier.h
new file mode 100644
index 0000000..940b054
--- /dev/null
+++ b/eeschema/lib_bezier.h
@@ -0,0 +1,119 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_bezier.h
+ */
+
+#ifndef _LIB_BEZIER_H_
+#define _LIB_BEZIER_H_
+
+#include <lib_draw_item.h>
+
+
+/**
+ * Class LIB_BEZIER
+ * defines bezier curve graphic body item.
+ */
+class LIB_BEZIER : public LIB_ITEM
+{
+ int m_Width; // Line width
+ std::vector<wxPoint> m_BezierPoints; // list of parameter (3|4)
+ std::vector<wxPoint> m_PolyPoints; // list of points (>= 2)
+
+ void drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform );
+
+public:
+ LIB_BEZIER( LIB_PART * aParent );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~LIB_BEZIER() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "LIB_BEZIER" );
+ }
+
+
+ bool Save( OUTPUTFORMATTER& aFormatter );
+
+ bool Load( LINE_READER& aLineReader, wxString& aErrorMsg );
+
+ void AddPoint( const wxPoint& aPoint );
+
+ void SetOffset( const wxPoint& aOffset );
+
+ /**
+ * @return the number of corners
+ */
+ unsigned GetCornerCount() const { return m_PolyPoints.size(); }
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ bool HitTest( const wxPoint& aPosRef, int aThreshold, const TRANSFORM& aTransform ) const;
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ bool Inside( EDA_RECT& aRect ) const;
+
+ void Move( const wxPoint& aPosition );
+
+ wxPoint GetPosition() const { return m_PolyPoints[0]; }
+
+ void MirrorHorizontal( const wxPoint& aCenter );
+
+ void MirrorVertical( const wxPoint& aCenter );
+
+ void Rotate( const wxPoint& aCenter, bool aRotateCCW = true );
+
+ void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform );
+
+ int GetWidth() const { return m_Width; }
+
+ void SetWidth( int aWidth ) { m_Width = aWidth; }
+
+ int GetPenSize( ) const;
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ EDA_ITEM* Clone() const;
+
+private:
+
+ /**
+ * @copydoc LIB_ITEM::compare()
+ *
+ * The bezier curve specific sort order for each curve segment point is as follows:
+ * - Bezier horizontal (X) point position.
+ * - Bezier vertical (Y) point position.
+ */
+ int compare( const LIB_ITEM& aOther ) const;
+};
+
+
+#endif // _LIB_BEZIER_H_
diff --git a/eeschema/lib_circle.cpp b/eeschema/lib_circle.cpp
new file mode 100644
index 0000000..bcf6a40
--- /dev/null
+++ b/eeschema/lib_circle.cpp
@@ -0,0 +1,356 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_circle.cpp
+ * @brief LIB_CIRCLE class implementation.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <plot_common.h>
+#include <trigo.h>
+#include <wxstruct.h>
+#include <richio.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <lib_circle.h>
+#include <transform.h>
+
+
+LIB_CIRCLE::LIB_CIRCLE( LIB_PART* aParent ) :
+ LIB_ITEM( LIB_CIRCLE_T, aParent )
+{
+ m_Radius = 0;
+ m_Width = 0;
+ m_Fill = NO_FILL;
+ m_isFillable = true;
+ m_typeName = _( "Circle" );
+}
+
+
+bool LIB_CIRCLE::Save( OUTPUTFORMATTER& aFormatter )
+{
+ aFormatter.Print( 0, "C %d %d %d %d %d %d %c\n", m_Pos.x, m_Pos.y,
+ m_Radius, m_Unit, m_Convert, m_Width, fill_tab[m_Fill] );
+
+ return true;
+}
+
+
+bool LIB_CIRCLE::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
+{
+ char tmp[256];
+ char* line = (char*) aLineReader;
+
+ int cnt = sscanf( line + 2, "%d %d %d %d %d %d %255s", &m_Pos.x, &m_Pos.y,
+ &m_Radius, &m_Unit, &m_Convert, &m_Width, tmp );
+
+ if( cnt < 6 )
+ {
+ aErrorMsg.Printf( _( "Circle only had %d parameters of the required 6" ), cnt );
+ return false;
+ }
+
+ if( tmp[0] == 'F' )
+ m_Fill = FILLED_SHAPE;
+
+ if( tmp[0] == 'f' )
+ m_Fill = FILLED_WITH_BG_BODYCOLOR;
+
+ return true;
+}
+
+
+bool LIB_CIRCLE::HitTest( const wxPoint& aPosRef ) const
+{
+ int mindist = GetPenSize() / 2;
+
+ // Have a minimal tolerance for hit test
+ if( mindist < MINIMUM_SELECTION_DISTANCE )
+ mindist = MINIMUM_SELECTION_DISTANCE;
+
+ return HitTest( aPosRef, mindist, DefaultTransform );
+}
+
+
+bool LIB_CIRCLE::HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const
+{
+ if( aThreshold < 0 )
+ aThreshold = GetPenSize() / 2;
+
+ int dist = KiROUND( GetLineLength( aPosRef, aTransform.TransformCoordinate( m_Pos ) ) );
+
+ if( abs( dist - m_Radius ) <= aThreshold )
+ return true;
+ return false;
+}
+
+
+EDA_ITEM* LIB_CIRCLE::Clone() const
+{
+ return new LIB_CIRCLE( *this );
+}
+
+
+int LIB_CIRCLE::compare( const LIB_ITEM& aOther ) const
+{
+ wxASSERT( aOther.Type() == LIB_CIRCLE_T );
+
+ const LIB_CIRCLE* tmp = ( LIB_CIRCLE* ) &aOther;
+
+ if( m_Pos.x != tmp->m_Pos.x )
+ return m_Pos.x - tmp->m_Pos.x;
+
+ if( m_Pos.y != tmp->m_Pos.y )
+ return m_Pos.y - tmp->m_Pos.y;
+
+ if( m_Radius != tmp->m_Radius )
+ return m_Radius - tmp->m_Radius;
+
+ return 0;
+}
+
+
+void LIB_CIRCLE::SetOffset( const wxPoint& aOffset )
+{
+ m_Pos += aOffset;
+}
+
+
+bool LIB_CIRCLE::Inside( EDA_RECT& aRect ) const
+{
+ /*
+ * FIXME: This fails to take into account the radius around the center
+ * point.
+ */
+ return aRect.Contains( m_Pos.x, -m_Pos.y );
+}
+
+
+void LIB_CIRCLE::Move( const wxPoint& aPosition )
+{
+ m_Pos = aPosition;
+}
+
+
+void LIB_CIRCLE::MirrorHorizontal( const wxPoint& aCenter )
+{
+ m_Pos.x -= aCenter.x;
+ m_Pos.x *= -1;
+ m_Pos.x += aCenter.x;
+}
+
+
+void LIB_CIRCLE::MirrorVertical( const wxPoint& aCenter )
+{
+ m_Pos.y -= aCenter.y;
+ m_Pos.y *= -1;
+ m_Pos.y += aCenter.y;
+}
+
+
+void LIB_CIRCLE::Rotate( const wxPoint& aCenter, bool aRotateCCW )
+{
+ int rot_angle = aRotateCCW ? -900 : 900;
+
+ RotatePoint( &m_Pos, aCenter, rot_angle );
+}
+
+
+void LIB_CIRCLE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform )
+{
+ wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
+
+ if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
+ {
+ aPlotter->SetColor( GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
+ aPlotter->Circle( pos, m_Radius * 2, FILLED_SHAPE, 0 );
+ }
+
+ bool already_filled = m_Fill == FILLED_WITH_BG_BODYCOLOR;
+ aPlotter->SetColor( GetLayerColor( LAYER_DEVICE ) );
+ aPlotter->Circle( pos, m_Radius * 2, already_filled ? NO_FILL : m_Fill, GetPenSize() );
+}
+
+
+int LIB_CIRCLE::GetPenSize() const
+{
+ return ( m_Width == 0 ) ? GetDefaultLineThickness() : m_Width;
+}
+
+
+void LIB_CIRCLE::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform )
+{
+ wxPoint pos1;
+
+ EDA_COLOR_T color = GetLayerColor( LAYER_DEVICE );
+
+ if( aColor < 0 ) // Used normal color or selected color
+ {
+ if( IsSelected() )
+ color = GetItemSelectedColor();
+ }
+ else
+ {
+ color = aColor;
+ }
+
+ pos1 = aTransform.TransformCoordinate( m_Pos ) + aOffset;
+ GRSetDrawMode( aDC, aDrawMode );
+
+ FILL_T fill = aData ? NO_FILL : m_Fill;
+ if( aColor >= 0 )
+ fill = NO_FILL;
+
+ EDA_RECT* const clipbox = aPanel? aPanel->GetClipBox() : NULL;
+ if( fill == FILLED_WITH_BG_BODYCOLOR )
+ GRFilledCircle( clipbox, aDC, pos1.x, pos1.y, m_Radius, GetPenSize(),
+ (m_Flags & IS_MOVED) ? color : GetLayerColor( LAYER_DEVICE_BACKGROUND ),
+ GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
+ else if( fill == FILLED_SHAPE )
+ GRFilledCircle( clipbox, aDC, pos1.x, pos1.y, m_Radius, 0, color, color );
+ else
+ GRCircle( clipbox, aDC, pos1.x, pos1.y, m_Radius, GetPenSize(), color );
+
+ /* Set to one (1) to draw bounding box around circle to validate bounding
+ * box calculation. */
+#if 0
+ EDA_RECT bBox = GetBoundingBox();
+ bBox.RevertYAxis();
+ bBox = aTransform.TransformCoordinate( bBox );
+ bBox.Move( aOffset );
+ GRRect( clipbox, aDC, bBox, 0, LIGHTMAGENTA );
+#endif
+}
+
+
+const EDA_RECT LIB_CIRCLE::GetBoundingBox() const
+{
+ EDA_RECT rect;
+
+ rect.SetOrigin( m_Pos.x - m_Radius, m_Pos.y - m_Radius );
+ rect.SetEnd( m_Pos.x + m_Radius, m_Pos.y + m_Radius );
+ rect.Inflate( ( GetPenSize()+1 ) / 2 );
+
+ rect.RevertYAxis();
+
+ return rect;
+}
+
+
+void LIB_CIRCLE::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
+{
+ wxString msg;
+ EDA_RECT bBox = GetBoundingBox();
+
+ LIB_ITEM::GetMsgPanelInfo( aList );
+
+ msg = StringFromValue( g_UserUnit, m_Width, true );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Line Width" ), msg, BLUE ) );
+
+ msg = StringFromValue( g_UserUnit, m_Radius, true );
+ aList.push_back( MSG_PANEL_ITEM( _( "Radius" ), msg, RED ) );
+
+ msg.Printf( wxT( "(%d, %d, %d, %d)" ), bBox.GetOrigin().x,
+ bBox.GetOrigin().y, bBox.GetEnd().x, bBox.GetEnd().y );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Bounding Box" ), msg, BROWN ) );
+}
+
+
+wxString LIB_CIRCLE::GetSelectMenuText() const
+{
+ return wxString::Format( _( "Circle center (%s, %s), radius %s" ),
+ GetChars( CoordinateToString( m_Pos.x ) ),
+ GetChars( CoordinateToString( m_Pos.y ) ),
+ GetChars( CoordinateToString( m_Radius ) ) );
+}
+
+
+void LIB_CIRCLE::BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aPosition )
+{
+ wxCHECK_RET( ( aEditMode & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
+ wxT( "Invalid edit mode for LIB_CIRCLE object." ) );
+
+ if( aEditMode == IS_NEW )
+ {
+ m_Pos = m_initialPos = aPosition;
+ }
+ else if( aEditMode == IS_MOVED )
+ {
+ m_initialPos = m_Pos;
+ m_initialCursorPos = aPosition;
+ SetEraseLastDrawItem();
+ }
+ else if( aEditMode == IS_RESIZED )
+ {
+ SetEraseLastDrawItem();
+ }
+
+ m_Flags = aEditMode;
+}
+
+
+bool LIB_CIRCLE::ContinueEdit( const wxPoint aPosition )
+{
+ wxCHECK_MSG( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0, false,
+ wxT( "Bad call to ContinueEdit(). LIB_CIRCLE is not being edited." ) );
+
+ return false;
+}
+
+
+void LIB_CIRCLE::EndEdit( const wxPoint& aPosition, bool aAbort )
+{
+ wxCHECK_RET( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
+ wxT( "Bad call to EndEdit(). LIB_CIRCLE is not being edited." ) );
+
+ SetEraseLastDrawItem( false );
+ m_Flags = 0;
+}
+
+
+void LIB_CIRCLE::calcEdit( const wxPoint& aPosition )
+{
+ if( m_Flags == IS_NEW || m_Flags == IS_RESIZED )
+ {
+ if( m_Flags == IS_NEW )
+ SetEraseLastDrawItem();
+
+ m_Radius = KiROUND( GetLineLength( m_Pos, aPosition ) );
+ }
+ else
+ {
+ Move( m_initialPos + aPosition - m_initialCursorPos );
+ }
+}
diff --git a/eeschema/lib_circle.h b/eeschema/lib_circle.h
new file mode 100644
index 0000000..fe6ee3c
--- /dev/null
+++ b/eeschema/lib_circle.h
@@ -0,0 +1,121 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_circle.h
+ */
+
+#ifndef _LIB_CIRCLE_H_
+#define _LIB_CIRCLE_H_
+
+#include <lib_draw_item.h>
+
+
+class LIB_CIRCLE : public LIB_ITEM
+{
+ int m_Radius;
+ wxPoint m_Pos; // Position or centre (Arc and Circle) or start point (segments).
+ int m_Width; // Line width.
+
+ void drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform );
+
+ void calcEdit( const wxPoint& aPosition );
+
+public:
+ LIB_CIRCLE( LIB_PART * aParent );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~LIB_CIRCLE() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "LIB_CIRCLE" );
+ }
+
+
+ bool Save( OUTPUTFORMATTER& aFormatter );
+
+ bool Load( LINE_READER& aLineReader, wxString& aErrorMsg );
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ bool HitTest( const wxPoint& aPosRef, int aThreshold, const TRANSFORM& aTransform ) const;
+
+ int GetPenSize( ) const;
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) );
+
+ bool ContinueEdit( const wxPoint aNextPoint );
+
+ void EndEdit( const wxPoint& aPosition, bool aAbort = false );
+
+ void SetOffset( const wxPoint& aOffset );
+
+ bool Inside( EDA_RECT& aRect ) const;
+
+ void Move( const wxPoint& aPosition );
+
+ wxPoint GetPosition() const { return m_Pos; }
+
+ void MirrorHorizontal( const wxPoint& aCenter );
+
+ void MirrorVertical( const wxPoint& aCenter );
+
+ void Rotate( const wxPoint& aCenter, bool aRotateCCW = true );
+
+ void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform );
+
+ int GetWidth() const { return m_Width; }
+
+ void SetWidth( int aWidth ) { m_Width = aWidth; }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_circle_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+private:
+
+ /**
+ * @copydoc LIB_ITEM::compare()
+ *
+ * The circle specific sort order is as follows:
+ * - Circle horizontal (X) position.
+ * - Circle vertical (Y) position.
+ * - Circle radius.
+ */
+ int compare( const LIB_ITEM& aOther ) const;
+};
+
+
+#endif // _LIB_CIRCLE_H_
diff --git a/eeschema/lib_collectors.cpp b/eeschema/lib_collectors.cpp
new file mode 100644
index 0000000..157c7ab
--- /dev/null
+++ b/eeschema/lib_collectors.cpp
@@ -0,0 +1,131 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <macros.h>
+#include <general.h>
+#include <transform.h>
+#include <lib_collectors.h>
+
+
+const KICAD_T LIB_COLLECTOR::AllItems[] = {
+ LIB_ARC_T,
+ LIB_CIRCLE_T,
+ LIB_TEXT_T,
+ LIB_RECTANGLE_T,
+ LIB_POLYLINE_T,
+ LIB_BEZIER_T,
+ LIB_PIN_T,
+ LIB_FIELD_T,
+ EOT
+};
+
+
+const KICAD_T LIB_COLLECTOR::AllItemsButPins[] = {
+ LIB_ARC_T,
+ LIB_CIRCLE_T,
+ LIB_TEXT_T,
+ LIB_RECTANGLE_T,
+ LIB_POLYLINE_T,
+ LIB_BEZIER_T,
+ LIB_FIELD_T,
+ EOT
+};
+
+
+const KICAD_T LIB_COLLECTOR::EditableItems[] = {
+ LIB_ARC_T,
+ LIB_CIRCLE_T,
+ LIB_TEXT_T,
+ LIB_RECTANGLE_T,
+ LIB_POLYLINE_T,
+ LIB_BEZIER_T,
+ LIB_PIN_T,
+ LIB_FIELD_T,
+ EOT
+};
+
+
+const KICAD_T LIB_COLLECTOR::MovableItems[] = {
+ LIB_ARC_T,
+ LIB_CIRCLE_T,
+ LIB_TEXT_T,
+ LIB_RECTANGLE_T,
+ LIB_POLYLINE_T,
+ LIB_BEZIER_T,
+ LIB_PIN_T,
+ LIB_FIELD_T,
+ EOT
+};
+
+
+const KICAD_T LIB_COLLECTOR::RotatableItems[] = {
+ LIB_ARC_T,
+ LIB_CIRCLE_T,
+ LIB_TEXT_T,
+ LIB_RECTANGLE_T,
+ LIB_POLYLINE_T,
+ LIB_BEZIER_T,
+ LIB_PIN_T,
+ LIB_FIELD_T,
+ EOT
+};
+
+
+SEARCH_RESULT LIB_COLLECTOR::Inspect( EDA_ITEM* aItem, const void* aTestData )
+{
+ LIB_ITEM* item = (LIB_ITEM*) aItem;
+
+// wxLogDebug( wxT( "Inspecting item %s, unit %d, convert %d" ),
+// GetChars( item->GetSelectMenuText() ), item->GetUnit(), item->GetConvert() );
+
+ if( ( m_data.m_unit && item->GetUnit() && ( m_data.m_unit != item->GetUnit() ) )
+ || ( m_data.m_convert && item->GetConvert() && ( m_data.m_convert != item->GetConvert() ) )
+ || !item->HitTest( m_RefPos, -1, DefaultTransform ) )
+ return SEARCH_CONTINUE;
+
+ Append( aItem );
+
+ return SEARCH_CONTINUE;
+}
+
+
+void LIB_COLLECTOR::Collect( LIB_ITEMS& aItems, const KICAD_T aFilterList[],
+ const wxPoint& aPosition, int aUnit, int aConvert )
+{
+ Empty(); // empty the collection just in case
+
+ SetScanTypes( aFilterList );
+
+ // remember where the snapshot was taken from and pass refPos to the Inspect() function.
+ SetRefPos( aPosition );
+
+ m_data.m_unit = aUnit;
+ m_data.m_convert = aConvert;
+
+ for( size_t i = 0; i < aItems.size(); i++ )
+ {
+ if( SEARCH_QUIT == aItems[i].Visit( this, NULL, m_ScanTypes ) )
+ break;
+ }
+}
diff --git a/eeschema/lib_collectors.h b/eeschema/lib_collectors.h
new file mode 100644
index 0000000..e1b02a4
--- /dev/null
+++ b/eeschema/lib_collectors.h
@@ -0,0 +1,135 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _LIB_COLLECTORS_H_
+#define _LIB_COLLECTORS_H_
+
+
+#include <class_collector.h>
+#include <lib_draw_item.h>
+
+
+class LIB_COLLECTOR;
+
+
+class LIB_COLLECTOR_DATA
+{
+ int m_unit;
+ int m_convert;
+
+ friend class LIB_COLLECTOR;
+
+public:
+ LIB_COLLECTOR_DATA() :
+ m_unit( 0 ),
+ m_convert( 0 ) {}
+};
+
+
+/**
+ * Class LIB_COLLECTOR
+ */
+class LIB_COLLECTOR : public COLLECTOR
+{
+ LIB_COLLECTOR_DATA m_data;
+
+public:
+
+ /**
+ * A scan list for all schematic items.
+ */
+ static const KICAD_T AllItems[];
+
+ /**
+ * A scan list for all editable schematic items.
+ */
+ static const KICAD_T EditableItems[];
+
+ /**
+ * A scan list for all movable schematic items.
+ */
+ static const KICAD_T MovableItems[];
+
+ /**
+ * A scan list for all rotatable schematic items.
+ */
+ static const KICAD_T RotatableItems[];
+
+ /**
+ * A scan list for all schematic items except pins.
+ */
+ static const KICAD_T AllItemsButPins[];
+
+ /**
+ * Constructor LIB_COLLECTOR
+ */
+ LIB_COLLECTOR( const KICAD_T* aScanTypes = LIB_COLLECTOR::AllItems )
+ {
+ SetScanTypes( aScanTypes );
+ }
+
+ /**
+ * Operator []
+ * overloads COLLECTOR::operator[](int) to return a LIB_ITEM* instead of
+ * an EDA_ITEM* type.
+ * @param aIndex The index into the list.
+ * @return LIB_ITEM* at \a aIndex or NULL.
+ */
+ LIB_ITEM* operator[]( int aIndex ) const
+ {
+ if( (unsigned)aIndex < (unsigned)GetCount() )
+ return (LIB_ITEM*) m_List[ aIndex ];
+
+ return NULL;
+ }
+
+ /**
+ * Function Inspect
+ * is the examining function within the INSPECTOR which is passed to the
+ * Iterate function.
+ *
+ * @param aItem An EDA_ITEM to examine.
+ * @param aTestData is not used in this class.
+ * @return SEARCH_RESULT #SEARCH_QUIT if the iterator is to stop the scan,
+ * else #SEARCH_CONTINUE;
+ */
+ SEARCH_RESULT Inspect( EDA_ITEM* aItem, const void* aTestData = NULL );
+
+ /**
+ * Function Collect
+ * scans a SCH_ITEM using this class's Inspector method, which does the collection.
+ * @param aItem A SCH_ITEM to scan.
+ * @param aFilterList A list of #KICAD_T types with a terminating #EOT, that determines
+ * what is to be collected and the priority order of the resulting
+ * collection.
+ * @param aPosition A wxPoint to use in hit-testing.
+ * @param aUnit The unit of the items to collect or zero if all units.
+ * @param aConvert The convert of the items to collect or zero if all conversions.
+ */
+ void Collect( LIB_ITEMS& aItem, const KICAD_T aFilterList[], const wxPoint& aPosition,
+ int aUnit = 0, int aConvert = 0 );
+};
+
+
+#endif // _LIB_COLLECTORS_H_
diff --git a/eeschema/lib_draw_item.cpp b/eeschema/lib_draw_item.cpp
new file mode 100644
index 0000000..4c05347
--- /dev/null
+++ b/eeschema/lib_draw_item.cpp
@@ -0,0 +1,160 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jaen-pierre.charras at wanadoo.fr
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_draw_item.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <wxstruct.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <lib_draw_item.h>
+
+const int fill_tab[3] = { 'N', 'F', 'f' };
+
+//#define DRAW_ARC_WITH_ANGLE // Used to draw arcs
+
+
+LIB_ITEM::LIB_ITEM( KICAD_T aType,
+ LIB_PART* aComponent,
+ int aUnit,
+ int aConvert,
+ FILL_T aFillType ) :
+ EDA_ITEM( aType )
+{
+ m_Unit = aUnit;
+ m_Convert = aConvert;
+ m_Fill = aFillType;
+ m_Parent = (EDA_ITEM*) aComponent;
+ m_typeName = _( "Undefined" );
+ m_isFillable = false;
+ m_eraseLastDrawItem = false;
+}
+
+
+void LIB_ITEM::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
+{
+ wxString msg;
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Type" ), m_typeName, CYAN ) );
+
+ if( m_Unit == 0 )
+ msg = _( "All" );
+ else
+ msg.Printf( wxT( "%d" ), m_Unit );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Unit" ), msg, BROWN ) );
+
+ if( m_Convert == 0 )
+ msg = _( "All" );
+ else if( m_Convert == 1 )
+ msg = _( "no" );
+ else if( m_Convert == 2 )
+ msg = _( "yes" );
+ else
+ msg = wxT( "?" );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Convert" ), msg, BROWN ) );
+}
+
+
+bool LIB_ITEM::operator==( const LIB_ITEM& aOther ) const
+{
+ return ( ( Type() == aOther.Type() )
+ && ( m_Unit == aOther.m_Unit )
+ && ( m_Convert == aOther.m_Convert )
+ && compare( aOther ) == 0 );
+}
+
+
+bool LIB_ITEM::operator<( const LIB_ITEM& aOther ) const
+{
+ int result = m_Convert - aOther.m_Convert;
+
+ if( result != 0 )
+ return result < 0;
+
+ result = m_Unit - aOther.m_Unit;
+
+ if( result != 0 )
+ return result < 0;
+
+ result = Type() - aOther.Type();
+
+ if( result != 0 )
+ return result < 0;
+
+ return ( compare( aOther ) < 0 );
+}
+
+
+void LIB_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aOffset, EDA_COLOR_T aColor,
+ GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform )
+{
+ if( InEditMode() )
+ {
+ // Temporarily disable filling while the item is being edited.
+ FILL_T fillMode = m_Fill;
+ EDA_COLOR_T color = GetDefaultColor();
+
+ m_Fill = NO_FILL;
+
+#ifndef USE_WX_OVERLAY
+ // Erase the old items using the previous attributes.
+ if( m_eraseLastDrawItem )
+ {
+ GRSetDrawMode( aDC, g_XorMode );
+ drawEditGraphics( aPanel->GetClipBox(), aDC, color );
+ drawGraphic( aPanel, aDC, wxPoint( 0, 0 ), color, g_XorMode, aData,
+ aTransform );
+ }
+#endif
+ // Calculate the new attributes at the current cursor position.
+ calcEdit( aOffset );
+
+ // Draw the items using the new attributes.
+ drawEditGraphics( aPanel->GetClipBox(), aDC, color );
+ drawGraphic( aPanel, aDC, wxPoint( 0, 0 ), color, g_XorMode, aData,
+ aTransform );
+
+ m_Fill = fillMode;
+ }
+ else
+ {
+ drawGraphic( aPanel, aDC, aOffset, aColor, aDrawMode, aData, aTransform );
+ }
+}
+
+
+EDA_COLOR_T LIB_ITEM::GetDefaultColor()
+{
+ return GetLayerColor( LAYER_DEVICE );
+}
diff --git a/eeschema/lib_draw_item.h b/eeschema/lib_draw_item.h
new file mode 100644
index 0000000..47ca7a4
--- /dev/null
+++ b/eeschema/lib_draw_item.h
@@ -0,0 +1,448 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jaen-pierre.charras at wanadoo.fr
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_libentry.h
+ * @brief Class LIB_ITEM definition.
+ */
+
+#ifndef _LIB_ITEM_H_
+#define _LIB_ITEM_H_
+
+#include <base_struct.h>
+#include <transform.h>
+#include <gr_basic.h>
+
+#include <boost/ptr_container/ptr_vector.hpp>
+
+
+class LINE_READER;
+class OUTPUTFORMATTER;
+class LIB_PART;
+class PLOTTER;
+class LIB_ITEM;
+class LIB_PIN;
+class MSG_PANEL_ITEM;
+
+
+extern const int fill_tab[];
+
+
+#define MINIMUM_SELECTION_DISTANCE 2 // Minimum selection distance in internal units
+
+
+/**
+ * Helper for defining a list of library draw object pointers. The Boost
+ * pointer containers are responsible for deleting object pointers placed
+ * in them. If you access a object pointer from the list, do not delete
+ * it directly.
+ */
+typedef boost::ptr_vector< LIB_ITEM > LIB_ITEMS;
+
+/**
+ * Helper for defining a list of pin object pointers. The list does not
+ * use a Boost pointer class so the object pointers do not accidentally get
+ * deleted when the container is deleted.
+ */
+typedef std::vector< LIB_PIN* > LIB_PINS;
+
+
+/**
+ * Class LIB_ITEM
+ * is the base class for drawable items used by schematic library components.
+ */
+class LIB_ITEM : public EDA_ITEM
+{
+ /**
+ * Function drawGraphic
+ *
+ * draws the item on \a aPanel.
+ *
+ * @param aPanel A pointer to the panel to draw the object upon.
+ * @param aDC A pointer to the device context used to draw the object.
+ * @param aOffset A reference to a wxPoint object containing the offset where to draw
+ * from the object's current position.
+ * @param aColor An #EDA_COLOR_T to draw the object or -1 to draw the object in it's
+ * default color.
+ * @param aDrawMode The mode used to perform the draw (#GR_OR, #GR_COPY, etc.).
+ * @param aData A pointer to any object specific data required to perform the draw.
+ * @param aTransform A reference to a #TRANSFORM object containing drawing transform.
+ */
+ virtual void drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aOffset, EDA_COLOR_T aColor,
+ GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform ) = 0;
+
+ /**
+ * Draw any editing specific graphics when the item is being edited.
+ *
+ * @param aClipBox Clip box of the current device context.
+ * @param aDC The device context to draw on.
+ * @param aColor The index of the color to draw.
+ */
+ virtual void drawEditGraphics( EDA_RECT* aClipBox, wxDC* aDC, EDA_COLOR_T aColor ) {}
+
+ /**
+ * Calculates the attributes of an item at \a aPosition when it is being edited.
+ *
+ * This method gets called by the Draw() method when the item is being edited. This
+ * probably should be a pure virtual method but bezier curves are not yet editable in
+ * the component library editor. Therefore, the default method does nothing.
+ *
+ * @param aPosition The current mouse position in drawing coordinates.
+ */
+ virtual void calcEdit( const wxPoint& aPosition ) {}
+
+ bool m_eraseLastDrawItem; ///< Used when editing a new draw item to prevent drawing
+ ///< artifacts.
+
+ friend class LIB_PART;
+
+protected:
+ /**
+ * Unit identification for multiple parts per package. Set to 0 if the
+ * item is common to all units.
+ */
+ int m_Unit;
+
+ /**
+ * Shape identification for alternate body styles. Set 0 if the item
+ * is common to all body styles. This is commonly referred to as
+ * DeMorgan style and this is typically how it is used in KiCad.
+ */
+ int m_Convert;
+
+ /**
+ * The body fill type. This has meaning only for some items. For a list of
+ * fill types see #FILL_T.
+ */
+ FILL_T m_Fill;
+
+ wxString m_typeName; ///< Name of object displayed in the message panel.
+
+ wxPoint m_initialPos; ///< Temporary position when moving an existing item.
+ wxPoint m_initialCursorPos; ///< Initial cursor position at the beginning of a move.
+
+ /** Flag to indicate if draw item is fillable. Default is false. */
+ bool m_isFillable;
+
+public:
+
+ LIB_ITEM( KICAD_T aType,
+ LIB_PART* aComponent = NULL,
+ int aUnit = 0,
+ int aConvert = 0,
+ FILL_T aFillType = NO_FILL );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ virtual ~LIB_ITEM() { }
+
+ wxString GetTypeName() { return m_typeName; }
+
+ /**
+ * Begin an editing a component library draw item in \a aEditMode at \a aPosition.
+ *
+ * This is used to start an editing action such as resize or move a draw object.
+ * It typically would be called on a left click when a draw tool is selected in
+ * the component library editor and one of the graphics tools is selected. It
+ * allows the draw item to maintain it's own internal state while it is being
+ * edited. Call AbortEdit() to quit the editing mode.
+ *
+ * @param aEditMode The editing mode being performed. See base_struct.h for a list
+ * of mode flags.
+ * @param aPosition The position in drawing coordinates where the editing mode was
+ * started. This may or may not be required depending on the item
+ * being edited and the edit mode.
+ */
+ virtual void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aPosition = wxPoint( 0, 0 ) ) {}
+
+ /**
+ * Continue an edit in progress at \a aPosition.
+ *
+ * This is used to perform the next action while editing a draw item. This would be
+ * called for each additional left click when the mouse is captured while the item
+ * is being edited.
+ *
+ * @param aPosition The position of the mouse left click in drawing coordinates.
+ * @return True if additional mouse clicks are required to complete the edit in progress.
+ */
+ virtual bool ContinueEdit( const wxPoint aPosition ) { return false; }
+
+ /**
+ * End an object editing action.
+ *
+ * This is used to end or abort an edit action in progress initiated by BeginEdit().
+ *
+ * @param aPosition The position of the last edit event in drawing coordinates.
+ * @param aAbort Set to true to abort the current edit in progress.
+ */
+ virtual void EndEdit( const wxPoint& aPosition, bool aAbort = false ) { m_Flags = 0; }
+
+ /**
+ * Draw an item
+ *
+ * @param aPanel DrawPanel to use (can be null) mainly used for clipping purposes.
+ * @param aDC Device Context (can be null)
+ * @param aOffset Offset to draw
+ * @param aColor -1 to use the normal body item color, or use this color if >= 0
+ * @param aDrawMode GR_OR, GR_XOR, ...
+ * @param aData Value or pointer used to pass others parameters, depending on body items.
+ * Used for some items to force to force no fill mode ( has meaning only for
+ * items what can be filled ). used in printing or moving objects mode or to
+ * pass reference to the lib component for pins.
+ * @param aTransform Transform Matrix (rotation, mirror ..)
+ */
+ virtual void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint &aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform );
+
+ /**
+ * Function GetPenSize
+ *
+ * @return the size of the "pen" that be used to draw or plot this item
+ */
+ virtual int GetPenSize() const = 0;
+
+ /**
+ * Function Save
+ * writes draw item object to \a aFormatter in component library "*.lib" format.
+ *
+ * @param aFormatter A reference to an #OUTPUTFORMATTER object to write the
+ * component library item to.
+ * @return True if success writing else false.
+ */
+ virtual bool Save( OUTPUTFORMATTER& aFormatter ) = 0;
+
+ virtual bool Load( LINE_READER& aLine, wxString& aErrorMsg ) = 0;
+
+ LIB_PART* GetParent() const
+ {
+ return (LIB_PART *)m_Parent;
+ }
+
+ virtual bool HitTest( const wxPoint& aPosition ) const
+ {
+ return EDA_ITEM::HitTest( aPosition );
+ }
+
+ /**
+ * @param aPosition A wxPoint to test.
+ * @param aThreshold Maximum distance to this object (usually the half thickness of a line)
+ * if < 0, it will be automatically set to half pen size when locating
+ * lines or arcs and set to 0 for other items.
+ * @param aTransform The transform matrix.
+ * @return True if the point \a aPosition is near this object
+ */
+ virtual bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const = 0;
+
+ /**
+ * @return the boundary box for this, in library coordinates
+ */
+ virtual const EDA_RECT GetBoundingBox() const { return EDA_ITEM::GetBoundingBox(); }
+
+ /**
+ * Function GetMsgPanelInfo
+ * displays basic info (type, part and convert) about the current item
+ * in message panel.
+ * <p>
+ * This base function is used to display the information common to the
+ * all library items. Call the base class from the derived class or the
+ * common information will not be updated in the message panel.
+ * </p>
+ * @param aList is the list to populate.
+ */
+ virtual void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ /**
+ * Test LIB_ITEM objects for equivalence.
+ *
+ * @param aOther Object to test against.
+ * @return True if object is identical to this object.
+ */
+ bool operator==( const LIB_ITEM& aOther ) const;
+ bool operator==( const LIB_ITEM* aOther ) const
+ {
+ return *this == *aOther;
+ }
+
+ /**
+ * Test if another draw item is less than this draw object.
+ *
+ * @param aOther - Draw item to compare against.
+ * @return - True if object is less than this object.
+ */
+ bool operator<( const LIB_ITEM& aOther) const;
+
+ /**
+ * Function Offset
+ * sets the drawing object by \a aOffset from the current position.
+ *
+ * @param aOffset Coordinates to offset the item position.
+ */
+ virtual void SetOffset( const wxPoint& aOffset ) = 0;
+
+ /**
+ * Function Inside
+ * tests if any part of the draw object is inside rectangle bounds of \a aRect.
+ *
+ * @param aRect Rectangle to check against.
+ * @return True if object is inside rectangle.
+ */
+ virtual bool Inside( EDA_RECT& aRect ) const = 0;
+
+ /**
+ * Function Move
+ * moves a draw object to \a aPosition.
+ *
+ * @param aPosition Position to move draw item to.
+ */
+ virtual void Move( const wxPoint& aPosition ) = 0;
+
+ /**
+ * Function GetPosition
+ * returns the current draw object position.
+ *
+ * @return A wxPoint object containing the position of the object.
+ */
+ virtual wxPoint GetPosition() const = 0;
+
+ void SetPosition( const wxPoint& aPosition ) { Move( aPosition ); }
+
+ /**
+ * Function MirrorHorizontal
+ * mirrors the draw object along the horizontal (X) axis about \a aCenter point.
+ *
+ * @param aCenter Point to mirror around.
+ */
+ virtual void MirrorHorizontal( const wxPoint& aCenter ) = 0;
+
+ /**
+ * Function MirrorVertical
+ * mirrors the draw object along the MirrorVertical (Y) axis about \a aCenter point.
+ *
+ * @param aCenter Point to mirror around.
+ */
+ virtual void MirrorVertical( const wxPoint& aCenter ) = 0;
+
+ /**
+ * Function Rotate
+ * rotates the object about \a aCenter point.
+ *
+ * @param aCenter Point to rotate around.
+ * @param aRotateCCW True to rotate counter clockwise. False to rotate clockwise.
+ */
+ virtual void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) = 0;
+
+ /**
+ * Rotate the draw item.
+ */
+ virtual void Rotate() {}
+
+ /**
+ * Plot the draw item using the plot object.
+ *
+ * @param aPlotter The plot object to plot to.
+ * @param aOffset Plot offset position.
+ * @param aFill Flag to indicate whether or not the object is filled.
+ * @param aTransform The plot transform.
+ */
+ virtual void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform ) = 0;
+
+ /**
+ * Function GetWidth
+ * return the width of the draw item.
+ *
+ * @return Width of draw object.
+ */
+ virtual int GetWidth() const = 0;
+
+ /**
+ * Function SetWidth
+ * sets the width of the draw item to \a aWidth.
+ */
+ virtual void SetWidth( int aWidth ) = 0;
+
+ /**
+ * Check if draw object can be filled.
+ *
+ * The default setting is false. If the derived object support filling,
+ * set the m_isFillable member to true.
+ *
+ * @return True if draw object can be filled. Default is false.
+ */
+ bool IsFillable() const { return m_isFillable; }
+
+ /**
+ * Return the draw item editing mode status.
+ *
+ * @return True if the item is being edited.
+ */
+ bool InEditMode() const { return ( m_Flags & ( IS_NEW | IS_DRAGGED | IS_MOVED | IS_RESIZED ) ) != 0; }
+
+ void SetEraseLastDrawItem( bool aErase = true ) { m_eraseLastDrawItem = aErase; }
+
+ virtual EDA_COLOR_T GetDefaultColor();
+
+ void SetUnit( int aUnit ) { m_Unit = aUnit; }
+
+ int GetUnit() const { return m_Unit; }
+
+ void SetConvert( int aConvert ) { m_Convert = aConvert; }
+
+ int GetConvert() const { return m_Convert; }
+
+ void SetFillMode( FILL_T aFillMode ) { m_Fill = aFillMode; }
+
+ FILL_T GetFillMode() const { return m_Fill; }
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+
+private:
+
+ /**
+ * Function compare
+ * provides the draw object specific comparison called by the == and < operators.
+ *
+ * The base object sort order which always proceeds the derived object sort order
+ * is as follows:
+ * - Component alternate part (DeMorgan) number.
+ * - Component part number.
+ * - KICAD_T enum value.
+ * - Result of derived classes comparison.
+ *
+ * @param aOther A reference to the other #LIB_ITEM to compare the arc against.
+ * @return An integer value less than 0 if the object is less than \a aOther ojbect,
+ * zero if the object is equal to \a aOther object, or greater than 0 if the
+ * object is greater than \a aOther object.
+ */
+ virtual int compare( const LIB_ITEM& aOther ) const = 0;
+};
+
+
+#endif // _LIB_ITEM_H_
diff --git a/eeschema/lib_export.cpp b/eeschema/lib_export.cpp
new file mode 100644
index 0000000..ab74805
--- /dev/null
+++ b/eeschema/lib_export.cpp
@@ -0,0 +1,191 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2008-2016 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_export.cpp
+ * @brief Eeschema library maintenance routines to backup modified libraries and
+ * create, edit, and delete components.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+
+#include <general.h>
+#include <libeditframe.h>
+#include <class_library.h>
+#include <wildcards_and_files_ext.h>
+
+#include <wx/filename.h>
+
+
+extern int ExportPartId;
+
+
+void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event )
+{
+ m_lastDrawItem = NULL;
+
+ wxFileDialog dlg( this, _( "Import Component" ), m_mruPath,
+ wxEmptyString, SchematicLibraryFileWildcard,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ wxFileName fn = dlg.GetPath();
+
+ m_mruPath = fn.GetPath();
+
+ std::auto_ptr<PART_LIB> lib;
+
+ try
+ {
+ std::auto_ptr<PART_LIB> new_lib( PART_LIB::LoadLibrary( fn.GetFullPath() ) );
+ lib = new_lib;
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _(
+ "Unable to import library '%s'. Error:\n"
+ "%s" ),
+ GetChars( fn.GetFullPath() )
+ );
+
+ DisplayError( this, msg );
+ return;
+ }
+
+ LIB_ALIAS* entry = lib->GetFirstEntry();
+
+ if( !entry )
+ {
+ wxString msg = wxString::Format( _(
+ "Part library file '%s' is empty." ),
+ GetChars( fn.GetFullPath() )
+ );
+ DisplayError( this, msg );
+ return;
+ }
+
+ if( LoadOneLibraryPartAux( entry, lib.get() ) )
+ {
+ DisplayLibInfos();
+ GetScreen()->ClearUndoRedoList();
+ Zoom_Automatique( false );
+ }
+}
+
+
+void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event )
+{
+ wxString msg, title;
+ bool createLib = ( event.GetId() == ExportPartId ) ? false : true;
+
+ LIB_PART* part = GetCurPart();
+
+ if( !part )
+ {
+ DisplayError( this, _( "There is no component selected to save." ) );
+ return;
+ }
+
+ wxFileName fn = part->GetName().Lower();
+
+ fn.SetExt( SchematicLibraryFileExtension );
+
+ title = createLib ? _( "New Library" ) : _( "Export Component" );
+
+ wxFileDialog dlg( this, title, m_mruPath, fn.GetFullName(),
+ SchematicLibraryFileWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ fn = dlg.GetPath();
+
+ std::auto_ptr<PART_LIB> temp_lib( new PART_LIB( LIBRARY_TYPE_EESCHEMA, fn.GetFullPath() ) );
+
+ SaveOnePart( temp_lib.get() );
+
+ bool result = false;
+
+ try
+ {
+ FILE_OUTPUTFORMATTER formatter( fn.GetFullPath() );
+
+ result = temp_lib.get()->Save( formatter );
+ }
+ catch( ... /* IO_ERROR ioe */ )
+ {
+ fn.MakeAbsolute();
+ msg = wxT( "Failed to create component library file " ) + fn.GetFullPath();
+ DisplayError( this, msg );
+ return;
+ }
+
+ try
+ {
+ wxFileName docFileName = fn;
+
+ docFileName.SetExt( DOC_EXT );
+
+ FILE_OUTPUTFORMATTER formatter( docFileName.GetFullPath() );
+
+ result = temp_lib.get()->SaveDocs( formatter );
+ }
+ catch( ... /* IO_ERROR ioe */ )
+ {
+ fn.MakeAbsolute();
+ msg = wxT( "Failed to create component library document file " ) + fn.GetFullPath();
+ DisplayError( this, msg );
+ return;
+ }
+
+ if( result )
+ m_mruPath = fn.GetPath();
+
+ if( result )
+ {
+ if( createLib )
+ {
+ msg.Printf( _( "'%s' - OK" ), GetChars( fn.GetFullPath() ) );
+ DisplayInfoMessage( this, _(
+ "This library will not be available until it is loaded by Eeschema.\n\n"
+ "Modify the Eeschema library configuration if you want to include it"
+ " as part of this project." ) );
+ }
+ else
+ {
+ msg.Printf( _( "'%s' - Export OK" ), GetChars( fn.GetFullPath() ) );
+ }
+ }
+ else // Error
+ {
+ msg.Printf( _( "Error creating '%s'" ), GetChars( fn.GetFullName() ) );
+ }
+
+ SetStatusText( msg );
+}
diff --git a/eeschema/lib_field.cpp b/eeschema/lib_field.cpp
new file mode 100644
index 0000000..5b6b01e
--- /dev/null
+++ b/eeschema/lib_field.cpp
@@ -0,0 +1,771 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_field.cpp
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <base_struct.h>
+#include <drawtxt.h>
+#include <kicad_string.h>
+#include <class_drawpanel.h>
+#include <plot_common.h>
+#include <trigo.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <class_libentry.h>
+#include <transform.h>
+#include <lib_field.h>
+#include <template_fieldnames.h>
+
+
+LIB_FIELD::LIB_FIELD(LIB_PART * aParent, int idfield ) :
+ LIB_ITEM( LIB_FIELD_T, aParent )
+{
+ Init( idfield );
+}
+
+
+LIB_FIELD::LIB_FIELD( int idfield ) : LIB_ITEM( LIB_FIELD_T, NULL )
+{
+ Init( idfield );
+}
+
+
+LIB_FIELD::~LIB_FIELD()
+{
+}
+
+
+void LIB_FIELD::Init( int id )
+{
+ m_id = id;
+ m_Size.x = GetDefaultTextSize();
+ m_Size.y = GetDefaultTextSize();
+ m_typeName = _( "Field" );
+ m_Orient = TEXT_ORIENT_HORIZ;
+ m_rotate = false;
+ m_updateText = false;
+
+ // fields in RAM must always have names, because we are trying to get
+ // less dependent on field ids and more dependent on names.
+ // Plus assumptions are made in the field editors.
+ m_name = TEMPLATE_FIELDNAME::GetDefaultFieldName( id );
+
+ switch( id )
+ {
+ case DATASHEET:
+ case FOOTPRINT:
+ // by contrast, VALUE and REFERENCE are are always constructed as
+ // initially visible, and template fieldsnames' initial visibility
+ // is controlled by the template fieldname configuration record.
+ SetVisible( false );
+ break;
+ }
+}
+
+
+bool LIB_FIELD::Save( OUTPUTFORMATTER& aFormatter )
+{
+ int hjustify, vjustify;
+ wxString text = m_Text;
+
+ hjustify = 'C';
+
+ if( m_HJustify == GR_TEXT_HJUSTIFY_LEFT )
+ hjustify = 'L';
+ else if( m_HJustify == GR_TEXT_HJUSTIFY_RIGHT )
+ hjustify = 'R';
+
+ vjustify = 'C';
+
+ if( m_VJustify == GR_TEXT_VJUSTIFY_BOTTOM )
+ vjustify = 'B';
+ else if( m_VJustify == GR_TEXT_VJUSTIFY_TOP )
+ vjustify = 'T';
+
+ aFormatter.Print( 0, "F%d %s %d %d %d %c %c %c %c%c%c",
+ m_id,
+ EscapedUTF8( text ).c_str(), // wraps in quotes
+ m_Pos.x, m_Pos.y, m_Size.x,
+ m_Orient == 0 ? 'H' : 'V',
+ (m_Attributs & TEXT_NO_VISIBLE ) ? 'I' : 'V',
+ hjustify, vjustify,
+ m_Italic ? 'I' : 'N',
+ m_Bold ? 'B' : 'N' );
+
+ /* Save field name, if necessary
+ * Field name is saved only if it is not the default name.
+ * Just because default name depends on the language and can change from
+ * a country to an other
+ */
+ wxString defName = TEMPLATE_FIELDNAME::GetDefaultFieldName( m_id );
+
+ if( m_id >= FIELD1 && !m_name.IsEmpty() && m_name != defName )
+ aFormatter.Print( 0, " %s", EscapedUTF8( m_name ).c_str() );
+
+ aFormatter.Print( 0, "\n" );
+
+ return true;
+}
+
+
+bool LIB_FIELD::Load( LINE_READER& aLineReader, wxString& errorMsg )
+{
+ int cnt;
+ char textOrient;
+ char textVisible;
+ char textHJustify;
+ char textVJustify[256];
+
+ char* line = (char*) aLineReader;
+ char* limit = line + aLineReader.Length();
+
+ if( sscanf( line + 1, "%d", &m_id ) != 1 || m_id < 0 )
+ {
+ errorMsg = wxT( "invalid field header" );
+ return false;
+ }
+
+ // Caller did a strtok(), which inserts a nul, so next few bytes are ugly:
+ // digit(s), a nul, some whitespace, then a double quote.
+ while( line < limit && *line != '"' )
+ line++;
+
+ if( line == limit )
+ return false;
+
+ line += ReadDelimitedText( &m_Text, line );
+
+ // Doctor the *.lib file field which has a "~" in blank fields. New saves will
+ // not save like this, and eventually these two lines can be removed.
+ if( m_Text.size() == 1 && m_Text[0] == wxChar( '~' ) )
+ m_Text.clear();
+
+ memset( textVJustify, 0, sizeof( textVJustify ) );
+
+ cnt = sscanf( line, " %d %d %d %c %c %c %255s", &m_Pos.x, &m_Pos.y, &m_Size.y,
+ &textOrient, &textVisible, &textHJustify, textVJustify );
+
+ if( cnt < 5 )
+ {
+ errorMsg.Printf( wxT( "field %d does not have the correct number of parameters" ),
+ m_id );
+ return false;
+ }
+
+ m_Size.x = m_Size.y;
+
+ if( textOrient == 'H' )
+ m_Orient = TEXT_ORIENT_HORIZ;
+ else if( textOrient == 'V' )
+ m_Orient = TEXT_ORIENT_VERT;
+ else
+ {
+ errorMsg.Printf( wxT( "field %d text orientation parameter <%c> is not valid" ),
+ textOrient );
+ return false;
+ }
+
+ if( textVisible == 'V' )
+ m_Attributs &= ~TEXT_NO_VISIBLE;
+ else if ( textVisible == 'I' )
+ m_Attributs |= TEXT_NO_VISIBLE;
+ else
+ {
+ errorMsg.Printf( wxT( "field %d text visible parameter <%c> is not valid" ),
+ textVisible );
+ return false;
+ }
+
+ m_HJustify = GR_TEXT_HJUSTIFY_CENTER;
+ m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
+
+ if( cnt >= 6 )
+ {
+ if( textHJustify == 'C' )
+ m_HJustify = GR_TEXT_HJUSTIFY_CENTER;
+ else if( textHJustify == 'L' )
+ m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
+ else if( textHJustify == 'R' )
+ m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
+ else
+ {
+ errorMsg.Printf(
+ wxT( "field %d text horizontal justification parameter <%c> is not valid" ),
+ textHJustify );
+ return false;
+ }
+
+ if( textVJustify[0] == 'C' )
+ m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
+ else if( textVJustify[0] == 'B' )
+ m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
+ else if( textVJustify[0] == 'T' )
+ m_VJustify = GR_TEXT_VJUSTIFY_TOP;
+ else
+ {
+ errorMsg.Printf(
+ wxT( "field %d text vertical justification parameter <%c> is not valid" ),
+ textVJustify[0] );
+ return false;
+ }
+
+ if ( textVJustify[1] == 'I' ) // Italic
+ m_Italic = true;
+ if ( textVJustify[2] == 'B' ) // Bold
+ m_Bold = true;
+ }
+
+ // fields in RAM must always have names.
+ if( m_id < MANDATORY_FIELDS )
+ {
+ // Fields in RAM must always have names, because we are trying to get
+ // less dependent on field ids and more dependent on names.
+ // Plus assumptions are made in the field editors.
+ m_name = TEMPLATE_FIELDNAME::GetDefaultFieldName( m_id );
+ }
+ else
+ {
+ ReadDelimitedText( &m_name, line );
+ }
+
+ return true;
+}
+
+
+int LIB_FIELD::GetPenSize() const
+{
+ return ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness;
+}
+
+
+void LIB_FIELD::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform )
+{
+ wxPoint text_pos;
+ int color;
+ int linewidth = GetPenSize();
+
+ if( m_Bold )
+ linewidth = GetPenSizeForBold( m_Size.x );
+ else
+ linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
+
+ if( ( m_Attributs & TEXT_NO_VISIBLE ) && ( aColor < 0 ) )
+ {
+ color = GetInvisibleItemColor();
+ }
+ else if( IsSelected() && ( aColor < 0 ) )
+ {
+ color = GetItemSelectedColor();
+ }
+ else
+ {
+ color = aColor;
+ }
+
+ if( color < 0 )
+ color = GetDefaultColor();
+
+ text_pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
+
+ wxString text;
+
+ if( aData )
+ text = *(wxString*)aData;
+ else
+ text = m_Text;
+
+ GRSetDrawMode( aDC, aDrawMode );
+ EDA_RECT* clipbox = aPanel? aPanel->GetClipBox() : NULL;
+ DrawGraphicText( clipbox, aDC, text_pos, (EDA_COLOR_T) color, text, m_Orient, m_Size,
+ m_HJustify, m_VJustify, linewidth, m_Italic, m_Bold );
+
+ /* Set to one (1) to draw bounding box around field text to validate
+ * bounding box calculation. */
+#if 0
+ EDA_RECT bBox = GetBoundingBox();
+ bBox.RevertYAxis();
+ bBox = aTransform.TransformCoordinate( bBox );
+ bBox.Move( aOffset );
+ GRRect( clipbox, aDC, bBox, 0, LIGHTMAGENTA );
+#endif
+}
+
+
+bool LIB_FIELD::HitTest( const wxPoint& aPosition ) const
+{
+ // Because HitTest is mainly used to select the field
+ // return always false if this field is void
+ if( IsVoid() )
+ return false;
+
+ return HitTest( aPosition, 0, DefaultTransform );
+}
+
+
+bool LIB_FIELD::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
+{
+ if( aThreshold < 0 )
+ aThreshold = 0;
+
+ // Build a temporary copy of the text for hit testing
+ EDA_TEXT tmp_text( *this );
+
+ // Reference designator text has one or 2 additional character (displays
+ // U? or U?A)
+ if( m_id == REFERENCE )
+ {
+ wxString extended_text = tmp_text.GetText();
+ extended_text.Append('?');
+ const LIB_PART* parent = static_cast<const LIB_PART* >( m_Parent );
+
+ if ( parent && ( parent->GetUnitCount() > 1 ) )
+ extended_text.Append('A');
+ tmp_text.SetText( extended_text );
+ }
+
+ tmp_text.SetTextPosition( aTransform.TransformCoordinate( m_Pos ) );
+
+ /* The text orientation may need to be flipped if the
+ * transformation matrix causes xy axes to be flipped.
+ * this simple algo works only for schematic matrix (rot 90 or/and mirror)
+ */
+ int t1 = ( aTransform.x1 != 0 ) ^ ( m_Orient != 0 );
+ tmp_text.SetOrientation( t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT );
+
+ return tmp_text.TextHitTest( aPosition );
+}
+
+
+EDA_ITEM* LIB_FIELD::Clone() const
+{
+ LIB_FIELD* newfield = new LIB_FIELD( m_id );
+
+ Copy( newfield );
+
+ return (EDA_ITEM*) newfield;
+}
+
+
+void LIB_FIELD::Copy( LIB_FIELD* aTarget ) const
+{
+ aTarget->SetParent( m_Parent );
+ aTarget->m_Pos = m_Pos;
+ aTarget->m_Size = m_Size;
+ aTarget->m_Thickness = m_Thickness;
+ aTarget->m_Orient = m_Orient;
+ aTarget->m_Attributs = m_Attributs;
+ aTarget->m_Text = m_Text;
+ aTarget->m_name = m_name;
+ aTarget->m_HJustify = m_HJustify;
+ aTarget->m_VJustify = m_VJustify;
+ aTarget->m_Italic = m_Italic;
+ aTarget->m_Bold = m_Bold;
+}
+
+
+int LIB_FIELD::compare( const LIB_ITEM& other ) const
+{
+ wxASSERT( other.Type() == LIB_FIELD_T );
+
+ const LIB_FIELD* tmp = ( LIB_FIELD* ) &other;
+
+ if( m_id != tmp->m_id )
+ return m_id - tmp->m_id;
+
+ int result = m_Text.CmpNoCase( tmp->m_Text );
+
+ if( result != 0 )
+ return result;
+
+ if( m_Pos.x != tmp->m_Pos.x )
+ return m_Pos.x - tmp->m_Pos.x;
+
+ if( m_Pos.y != tmp->m_Pos.y )
+ return m_Pos.y - tmp->m_Pos.y;
+
+ if( m_Size.x != tmp->m_Size.x )
+ return m_Size.x - tmp->m_Size.x;
+
+ if( m_Size.y != tmp->m_Size.y )
+ return m_Size.y - tmp->m_Size.y;
+
+ return 0;
+}
+
+
+void LIB_FIELD::SetOffset( const wxPoint& aOffset )
+{
+ m_Pos += aOffset;
+}
+
+
+bool LIB_FIELD::Inside( EDA_RECT& rect ) const
+{
+ /*
+ * FIXME: This fails to take into account the size and/or orientation of
+ * the text.
+ */
+ return rect.Contains( m_Pos.x, -m_Pos.y );
+}
+
+
+void LIB_FIELD::Move( const wxPoint& newPosition )
+{
+ m_Pos = newPosition;
+}
+
+
+void LIB_FIELD::MirrorHorizontal( const wxPoint& center )
+{
+ m_Pos.x -= center.x;
+ m_Pos.x *= -1;
+ m_Pos.x += center.x;
+}
+
+void LIB_FIELD::MirrorVertical( const wxPoint& center )
+{
+ m_Pos.y -= center.y;
+ m_Pos.y *= -1;
+ m_Pos.y += center.y;
+}
+
+void LIB_FIELD::Rotate( const wxPoint& center, bool aRotateCCW )
+{
+ int rot_angle = aRotateCCW ? -900 : 900;
+ RotatePoint( &m_Pos, center, rot_angle );
+ m_Orient = m_Orient ? 0 : 900;
+}
+
+
+void LIB_FIELD::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform )
+{
+ if( IsVoid() )
+ return;
+
+ /* Calculate the text orientation, according to the component
+ * orientation/mirror */
+ int orient = m_Orient;
+
+ if( aTransform.y1 ) // Rotate component 90 deg.
+ {
+ if( orient == TEXT_ORIENT_HORIZ )
+ orient = TEXT_ORIENT_VERT;
+ else
+ orient = TEXT_ORIENT_HORIZ;
+ }
+
+ EDA_RECT BoundaryBox = GetBoundingBox();
+ BoundaryBox.RevertYAxis();
+
+ EDA_TEXT_HJUSTIFY_T hjustify = GR_TEXT_HJUSTIFY_CENTER;
+ EDA_TEXT_VJUSTIFY_T vjustify = GR_TEXT_VJUSTIFY_CENTER;
+ wxPoint textpos = aTransform.TransformCoordinate( BoundaryBox.Centre() )
+ + aOffset;
+
+ aPlotter->Text( textpos, GetDefaultColor(), GetShownText(), orient, m_Size,
+ hjustify, vjustify,
+ GetPenSize(), m_Italic, m_Bold );
+}
+
+
+wxString LIB_FIELD::GetFullText( int unit )
+{
+ if( m_id != REFERENCE )
+ return GetText();
+
+ wxString text = GetText();
+ text << wxT( "?" );
+
+ if( GetParent()->IsMulti() )
+ text << LIB_PART::SubReference( unit );
+
+ return text;
+}
+
+
+const EDA_RECT LIB_FIELD::GetBoundingBox() const
+{
+ /* Y coordinates for LIB_ITEMS are bottom to top, so we must invert the Y position when
+ * calling GetTextBox() that works using top to bottom Y axis orientation.
+ */
+ EDA_RECT rect = GetTextBox( -1, -1, true );
+ rect.RevertYAxis();
+
+ // We are using now a bottom to top Y axis.
+ wxPoint orig = rect.GetOrigin();
+ wxPoint end = rect.GetEnd();
+ RotatePoint( &orig, m_Pos, -m_Orient );
+ RotatePoint( &end, m_Pos, -m_Orient );
+ rect.SetOrigin( orig );
+ rect.SetEnd( end );
+
+ // We are using now a top to bottom Y axis:
+ rect.RevertYAxis();
+
+ return rect;
+}
+
+
+EDA_COLOR_T LIB_FIELD::GetDefaultColor()
+{
+ EDA_COLOR_T color;
+
+ switch( m_id )
+ {
+ case REFERENCE:
+ color = GetLayerColor( LAYER_REFERENCEPART );
+ break;
+
+ case VALUE:
+ color = GetLayerColor( LAYER_VALUEPART );
+ break;
+
+ default:
+ color = GetLayerColor( LAYER_FIELDS );
+ break;
+ }
+
+ return color;
+}
+
+
+void LIB_FIELD::Rotate()
+{
+ if( InEditMode() )
+ {
+ m_rotate = true;
+ }
+ else
+ {
+ m_Orient = ( m_Orient == TEXT_ORIENT_VERT ) ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT;
+ }
+}
+
+
+wxString LIB_FIELD::GetName( bool aTranslate ) const
+{
+ wxString name;
+
+ switch( m_id )
+ {
+ case REFERENCE:
+ if( aTranslate )
+ name = _( "Reference" );
+ else
+ name = wxT( "Reference" );
+ break;
+
+ case VALUE:
+ if( aTranslate )
+ name = _( "Value" );
+ else
+ name = wxT( "Value" );
+ break;
+
+ case FOOTPRINT:
+ if( aTranslate )
+ name = _( "Footprint" );
+ else
+ name = wxT( "Footprint" );
+ break;
+
+ case DATASHEET:
+ if( aTranslate )
+ name = _( "Datasheet" );
+ else
+ name = wxT( "Datasheet" );
+ break;
+
+ default:
+ if( m_name.IsEmpty() )
+ {
+ if( aTranslate )
+ name.Printf( _( "Field%d" ), m_id );
+ else
+ name.Printf( wxT( "Field%d" ), m_id );
+ }
+ else
+ name = m_name;
+ }
+
+ return name;
+}
+
+
+void LIB_FIELD::SetName( const wxString& aName )
+{
+ // Mandatory field names are fixed.
+
+ // So what? Why should the low level code be in charge of such a policy issue?
+ // Besides, m_id is a relic that is untrustworthy now.
+ if( m_id >=0 && m_id < MANDATORY_FIELDS )
+ {
+ DBG(printf( "trying to set a MANDATORY_FIELD's name\n" );)
+ return;
+ }
+
+ if( m_name != aName )
+ {
+ m_name = aName;
+ SetModified();
+ }
+}
+
+
+void LIB_FIELD::SetText( const wxString& aText )
+{
+ if( aText == GetText() )
+ return;
+
+ wxString oldName = m_Text;
+
+ if( m_id == VALUE && m_Parent != NULL )
+ {
+ LIB_PART* parent = GetParent();
+
+ // Set the parent component and root alias to the new name.
+ if( parent->GetName().CmpNoCase( aText ) != 0 )
+ parent->SetName( aText );
+ }
+
+ if( InEditMode() )
+ {
+ m_Text = oldName;
+ m_savedText = aText;
+ m_updateText = true;
+ }
+ else
+ {
+ m_Text = aText;
+ }
+}
+
+
+wxString LIB_FIELD::GetSelectMenuText() const
+{
+ return wxString::Format( _( "Field %s %s" ),
+ GetChars( GetName() ),
+ GetChars( ShortenedShownText() ) );
+}
+
+
+void LIB_FIELD::BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aPosition )
+{
+ wxCHECK_RET( ( aEditMode & ( IS_NEW | IS_MOVED ) ) != 0,
+ wxT( "Invalid edit mode for LIB_FIELD object." ) );
+
+ if( aEditMode == IS_MOVED )
+ {
+ m_initialPos = m_Pos;
+ m_initialCursorPos = aPosition;
+ SetEraseLastDrawItem();
+ }
+ else
+ {
+ m_Pos = aPosition;
+ }
+
+ m_Flags = aEditMode;
+}
+
+
+bool LIB_FIELD::ContinueEdit( const wxPoint aPosition )
+{
+ wxCHECK_MSG( ( m_Flags & ( IS_NEW | IS_MOVED ) ) != 0, false,
+ wxT( "Bad call to ContinueEdit(). Text is not being edited." ) );
+
+ return false;
+}
+
+
+void LIB_FIELD::EndEdit( const wxPoint& aPosition, bool aAbort )
+{
+ wxCHECK_RET( ( m_Flags & ( IS_NEW | IS_MOVED ) ) != 0,
+ wxT( "Bad call to EndEdit(). Text is not being edited." ) );
+
+ m_Flags = 0;
+ m_rotate = false;
+ m_updateText = false;
+ SetEraseLastDrawItem( false );
+}
+
+
+void LIB_FIELD::calcEdit( const wxPoint& aPosition )
+{
+ if( m_rotate )
+ {
+ m_Orient = ( m_Orient == TEXT_ORIENT_VERT ) ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT;
+ m_rotate = false;
+ }
+
+ if( m_updateText )
+ {
+ std::swap( m_Text, m_savedText );
+ m_updateText = false;
+ }
+
+ if( m_Flags == IS_NEW )
+ {
+ m_Pos = aPosition;
+ }
+ else if( m_Flags == IS_MOVED )
+ {
+ Move( m_initialPos + aPosition - m_initialCursorPos );
+ }
+}
+
+void LIB_FIELD::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
+{
+ wxString msg;
+
+ LIB_ITEM::GetMsgPanelInfo( aList );
+
+ // Display style:
+ msg = GetTextStyleName();
+ aList.push_back( MSG_PANEL_ITEM( _( "Style" ), msg, MAGENTA ) );
+
+ msg = StringFromValue( g_UserUnit, m_Size.x, true );
+ aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, BLUE ) );
+
+ msg = StringFromValue( g_UserUnit, m_Size.y, true );
+ aList.push_back( MSG_PANEL_ITEM( _( "Height" ), msg, BLUE ) );
+
+ // Display field name (ref, value ...)
+ msg = GetName();
+ aList.push_back( MSG_PANEL_ITEM( _( "Field" ), msg, BROWN ) );
+
+ // Display field text:
+ aList.push_back( MSG_PANEL_ITEM( _( "Value" ), GetShownText(), BROWN ) );
+}
diff --git a/eeschema/lib_field.h b/eeschema/lib_field.h
new file mode 100644
index 0000000..1f8f8e7
--- /dev/null
+++ b/eeschema/lib_field.h
@@ -0,0 +1,277 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_field.h
+ */
+
+#ifndef CLASS_LIBENTRY_FIELDS_H
+#define CLASS_LIBENTRY_FIELDS_H
+
+#include <eda_text.h>
+#include <lib_draw_item.h>
+
+
+/**
+ * Class LIB_FIELD
+ * is used in symbol libraries. At least MANDATORY_FIELDS are always present
+ * in a ram resident library symbol. All constructors must ensure this because
+ * the component property editor assumes it.
+ * <p>
+ * A field is a string linked to a component. Unlike purely graphical text, fields can
+ * be used in netlist generation and other tools (BOM).
+ *
+ * The first 4 fields have a special meaning:
+ *
+ * 0 = REFERENCE
+ * 1 = VALUE
+ * 2 = FOOTPRINT (default Footprint)
+ * 3 = DATASHEET (user doc link)
+ *
+ * others = free fields
+ * </p>
+ *
+ * @see enum NumFieldType
+ */
+class LIB_FIELD : public LIB_ITEM, public EDA_TEXT
+{
+ int m_id; ///< @see enum NumFieldType
+ wxString m_name; ///< Name (not the field text value itself, that is .m_Text)
+
+ wxString m_savedText; ///< Temporary storage for the string when edition.
+ bool m_rotate; ///< Flag to indicate a rotation occurred while editing.
+ bool m_updateText; ///< Flag to indicate text change occurred while editing.
+
+ /**
+ * Draw the field.
+ * <p>
+ * If \a aData not NULL, \a aData must point a wxString which is used instead of
+ * the m_Text
+ * </p>
+ */
+ void drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform );
+
+ /**
+ * Calculate the new circle at \a aPosition when editing.
+ *
+ * @param aPosition - The position to edit the circle in drawing coordinates.
+ */
+ void calcEdit( const wxPoint& aPosition );
+
+public:
+
+ LIB_FIELD( int idfield = 2 );
+
+ LIB_FIELD( LIB_PART * aParent, int idfield = 2 );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~LIB_FIELD();
+
+ wxString GetClass() const
+ {
+ return wxT( "LIB_FIELD" );
+ }
+
+ /**
+ * Object constructor initialization helper.
+ */
+ void Init( int idfield );
+
+ /**
+ * Returns the field name.
+ *
+ * The first four field IDs are reserved and therefore always return their respective
+ * names. The user definable fields will return FieldN where N is the ID of the field
+ * when the m_name member is empty.
+ *
+ * @param aTranslate True to return translated field name (default). False to return
+ * the english name (useful when the name is used as keyword in
+ * netlists ...)
+ * @return Name of the field.
+ */
+ wxString GetName( bool aTranslate = true ) const;
+
+ /**
+ * Function SetName
+ *
+ * Sets a user definable field name to \a aName.
+ *
+ * Reserved fields such as value and reference are not renamed. If the field name is
+ * changed, the field modified flag is set. If the field is the child of a component,
+ * the parent component's modified flag is also set.
+ *
+ * @param aName - User defined field name.
+ */
+ void SetName( const wxString& aName );
+
+ int GetId() const { return m_id; }
+
+ void SetId( int aId ) { m_id = aId; }
+
+ int GetPenSize( ) const;
+
+ bool Save( OUTPUTFORMATTER& aFormatter );
+
+ bool Load( LINE_READER& aLineReader, wxString& errorMsg );
+
+ /**
+ * Copy parameters of this field to another field. Pointers are not copied.
+ *
+ * @param aTarget Target field to copy values to.
+ */
+ void Copy( LIB_FIELD* aTarget ) const;
+
+ void SetFields( const std::vector <LIB_FIELD> aFields );
+
+ /**
+ * Function IsVoid
+ * @return true if the field value is void (no text in this field)
+ */
+ bool IsVoid() const
+ {
+ return m_Text.IsEmpty();
+ }
+
+ /**
+ * Function IsVisible
+ * @return true is this field is visible, false if flagged invisible
+ */
+ bool IsVisible()
+ {
+ return (m_Attributs & TEXT_NO_VISIBLE) == 0 ? true : false;
+ }
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const;
+
+ void operator=( const LIB_FIELD& field )
+ {
+ m_id = field.m_id;
+ m_Text = field.m_Text;
+ m_name = field.m_name;
+ m_Pos = field.m_Pos;
+ m_Size = field.m_Size;
+ m_Thickness = field.m_Thickness;
+ m_Orient = field.m_Orient;
+ m_Mirror = field.m_Mirror;
+ m_Attributs = field.m_Attributs;
+ m_Italic = field.m_Italic;
+ m_Bold = field.m_Bold;
+ m_HJustify = field.m_HJustify;
+ m_VJustify = field.m_VJustify;
+ m_Parent = field.m_Parent;
+ }
+
+ /**
+ * Return the text of a field.
+ *
+ * If the field is the reference field, the unit number is used to
+ * create a pseudo reference text. If the base reference field is U,
+ * the string U?A will be returned for unit = 1.
+ *
+ * @todo This should be handled by the field object.
+ *
+ * @param unit - The package unit number. Only effects reference field.
+ * @return Field text.
+ */
+ wxString GetFullText( int unit = 1 );
+
+ EDA_COLOR_T GetDefaultColor();
+
+ void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) );
+
+ bool ContinueEdit( const wxPoint aNextPoint );
+
+ void EndEdit( const wxPoint& aPosition, bool aAbort = false );
+
+ void Rotate();
+
+ /**
+ * Sets the field text to \a aText.
+ *
+ * This method does more than just set the set the field text. There are special
+ * cases when changing the text string alone is not enough. If the field is the
+ * value field, the parent component's name is changed as well. If the field is
+ * being moved, the name change must be delayed until the next redraw to prevent
+ * drawing artifacts.
+ *
+ * @param aText - New text value.
+ */
+ void SetText( const wxString& aText );
+
+ void SetOffset( const wxPoint& aOffset );
+
+ bool Inside( EDA_RECT& aRect ) const;
+
+ void Move( const wxPoint& aPosition );
+
+ wxPoint GetPosition() const { return m_Pos; }
+
+ void MirrorHorizontal( const wxPoint& aCenter );
+
+ void MirrorVertical( const wxPoint& aCenter );
+
+ void Rotate( const wxPoint& aCenter, bool aRotateCCW = true );
+
+ void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform );
+
+ int GetWidth() const { return m_Thickness; }
+
+ void SetWidth( int aWidth ) { m_Thickness = aWidth; }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return move_field_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+private:
+
+ /**
+ * @copydoc LIB_ITEM::compare()
+ *
+ * The field specific sort order is as follows:
+ *
+ * - Field ID, REFERENCE, VALUE, etc.
+ * - Field string, case insensitive compare.
+ * - Field horizontal (X) position.
+ * - Field vertical (Y) position.
+ * - Field width.
+ * - Field height.
+ */
+ int compare( const LIB_ITEM& aOther ) const;
+};
+
+typedef std::vector< LIB_FIELD > LIB_FIELDS;
+
+#endif // CLASS_LIBENTRY_FIELDS_H
diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp
new file mode 100644
index 0000000..e4b221f
--- /dev/null
+++ b/eeschema/lib_pin.cpp
@@ -0,0 +1,2314 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_pin.cpp
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <trigo.h>
+#include <class_drawpanel.h>
+#include <drawtxt.h>
+#include <plot_common.h>
+#include <schframe.h>
+#include <richio.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <libeditframe.h>
+#include <class_libentry.h>
+#include <lib_pin.h>
+#include <transform.h>
+#include <sch_component.h>
+
+
+static const int pin_orientation_codes[] =
+{
+ PIN_RIGHT,
+ PIN_LEFT,
+ PIN_UP,
+ PIN_DOWN
+};
+
+
+#define PIN_ORIENTATION_CNT DIM( pin_orientation_codes )
+
+// bitmaps to show pins orientations in dialog editor
+// must have same order than pin_orientation_names
+static const BITMAP_DEF iconsPinsOrientations[] =
+{
+ pinorient_right_xpm,
+ pinorient_left_xpm,
+ pinorient_up_xpm,
+ pinorient_down_xpm,
+};
+
+
+// bitmaps to show pins shapes in dialog editor
+// must have same order than pin_style_names
+static BITMAP_DEF iconsPinsShapes[] =
+{
+ pinshape_normal_xpm,
+ pinshape_invert_xpm,
+ pinshape_clock_normal_xpm,
+ pinshape_clock_invert_xpm,
+ pinshape_active_low_input_xpm,
+ pinshape_clock_active_low_xpm,
+ pinshape_active_low_output_xpm,
+ pinshape_clock_fall_xpm,
+ pinshape_nonlogic_xpm
+};
+
+
+
+static const int pin_style_codes[] =
+{
+ NONE,
+ INVERT,
+ CLOCK,
+ CLOCK | INVERT,
+ LOWLEVEL_IN,
+ LOWLEVEL_IN | CLOCK,
+ LOWLEVEL_OUT,
+ CLOCK_FALL,
+ NONLOGIC
+};
+
+#define PIN_STYLE_CNT DIM( pin_style_codes )
+
+// bitmaps to show pins electrical type in dialog editor
+// must have same order than enum ElectricPinType (see lib_pin.h)
+static const BITMAP_DEF iconsPinsElectricalType[] =
+{
+ pintype_input_xpm,
+ pintype_output_xpm,
+ pintype_bidi_xpm,
+ pintype_3states_xpm,
+ pintype_passive_xpm,
+ pintype_notspecif_xpm,
+ pintype_powerinput_xpm,
+ pintype_poweroutput_xpm,
+ pintype_opencoll_xpm,
+ pintype_openemit_xpm,
+ pintype_noconnect_xpm
+};
+
+#define PIN_ELECTRICAL_TYPE_CNT DIM( iconsPinsElectricalType )
+
+
+const wxString LIB_PIN::GetCanonicalElectricalTypeName( unsigned aType )
+{
+ // These strings are the canonical name of the electrictal type
+ // Not translated, no space in name, only ASCII chars.
+ // to use when the string name must be known and well defined
+ // must have same order than enum ElectricPinType (see lib_pin.h)
+ static const wxChar* msgPinElectricType[] =
+ {
+ wxT( "input" ),
+ wxT( "output" ),
+ wxT( "BiDi" ),
+ wxT( "3state" ),
+ wxT( "passive" ),
+ wxT( "unspc" ),
+ wxT( "power_in" ),
+ wxT( "power_out" ),
+ wxT( "openCol" ),
+ wxT( "openEm" ),
+ wxT( "NotConnected" ),
+ wxT( "???" )
+ };
+
+ if( aType > PIN_NMAX )
+ aType = PIN_NMAX;
+
+ return msgPinElectricType[ aType ];
+}
+
+
+// Helper functions to get the pin orientation name from pin_orientation_codes
+// Note: the strings are *not* static because they are translated and must be built
+// on the fly, to be properly translated
+
+static const wxString getPinOrientationName( unsigned aPinOrientationCode )
+{
+ /* Note: The following name lists are sentence capitalized per the GNOME UI
+ * standards for list controls. Please do not change the capitalization
+ * of these strings unless the GNOME UI standards are changed.
+ */
+ const wxString pin_orientation_names[] =
+ {
+ _( "Right" ),
+ _( "Left" ),
+ _( "Up" ),
+ _( "Down" ),
+ wxT( "???" )
+ };
+
+ if( aPinOrientationCode > PIN_ORIENTATION_CNT )
+ aPinOrientationCode = PIN_ORIENTATION_CNT;
+
+ return pin_orientation_names[ aPinOrientationCode ];
+}
+
+const wxString LIB_PIN::GetElectricalTypeName( unsigned aPinsElectricalType )
+{
+ const wxString pin_electrical_type_names[] =
+ { // Keep these translated strings not static
+ _( "Input" ),
+ _( "Output" ),
+ _( "Bidirectional" ),
+ _( "Tri-state" ),
+ _( "Passive" ),
+ _( "Unspecified" ),
+ _( "Power input" ),
+ _( "Power output" ),
+ _( "Open collector" ),
+ _( "Open emitter" ),
+ _( "Not connected" ),
+ wxT( "???" )
+ };
+
+ if( aPinsElectricalType > PIN_ELECTRICAL_TYPE_CNT )
+ aPinsElectricalType = PIN_ELECTRICAL_TYPE_CNT;
+
+ return pin_electrical_type_names[ aPinsElectricalType ];
+}
+
+static const wxString getPinStyleName( unsigned aPinsStyle )
+{
+ const wxString pin_style_names[] =
+ { // Keep these translated strings not static
+ _( "Line" ),
+ _( "Inverted" ),
+ _( "Clock" ),
+ _( "Inverted clock" ),
+ _( "Input low" ),
+ _( "Clock low" ),
+ _( "Output low" ),
+ _( "Falling edge clock" ),
+ _( "NonLogic" ),
+ wxT( "???" )
+ };
+
+ if( aPinsStyle > PIN_STYLE_CNT )
+ aPinsStyle = PIN_STYLE_CNT;
+
+ return pin_style_names[ aPinsStyle ];
+}
+
+
+/// Utility for getting the size of the 'internal' pin decorators (as a radius)
+// i.e. the clock symbols (falling clock is actually external but is of
+// the same kind)
+
+static int InternalPinDecoSize( const LIB_PIN &aPin )
+{
+ return aPin.GetNameTextSize() / 2;
+}
+
+/// Utility for getting the size of the 'external' pin decorators (as a radius)
+// i.e. the negation circle, the polarity 'slopes' and the nonlogic
+// marker
+static int ExternalPinDecoSize( const LIB_PIN &aPin )
+{
+ return aPin.GetNumberTextSize() / 2;
+}
+
+LIB_PIN::LIB_PIN( LIB_PART* aParent ) :
+ LIB_ITEM( LIB_PIN_T, aParent )
+{
+ m_length = LIB_EDIT_FRAME::GetDefaultPinLength();
+ m_orientation = PIN_RIGHT; // Pin orient: Up, Down, Left, Right
+ m_shape = NONE; // Pin shape, bitwise.
+ m_type = PIN_UNSPECIFIED; // electrical type of pin
+ m_attributes = 0; // bit 0 != 0: pin invisible
+ m_number = 0; // pin number (i.e. 4 ASCII chars)
+ m_numTextSize = LIB_EDIT_FRAME::GetPinNumDefaultSize();
+ m_nameTextSize = LIB_EDIT_FRAME::GetPinNameDefaultSize();
+ m_width = 0;
+ m_typeName = _( "Pin" );
+}
+
+
+void LIB_PIN::SetName( const wxString& aName )
+{
+ wxString tmp = ( aName.IsEmpty() ) ? wxT( "~" ) : aName;
+
+ tmp.Replace( wxT( " " ), wxT( "_" ) );
+
+ if( m_name != tmp )
+ {
+ m_name = tmp;
+ SetModified();
+ }
+
+ if( GetParent() == NULL )
+ return;
+
+ LIB_PINS pinList;
+ GetParent()->GetPins( pinList );
+
+ for( size_t i = 0; i < pinList.size(); i++ )
+ {
+ if( ( pinList[i]->m_Flags & IS_LINKED ) == 0 || pinList[i]->m_name == m_name )
+ continue;
+
+ pinList[i]->m_name = m_name;
+ SetModified();
+ }
+}
+
+
+void LIB_PIN::SetNameTextSize( int size )
+{
+ if( size != m_nameTextSize )
+ {
+ m_nameTextSize = size;
+ SetModified();
+ }
+
+ if( GetParent() == NULL )
+ return;
+
+ LIB_PINS pinList;
+ GetParent()->GetPins( pinList );
+
+ for( size_t i = 0; i < pinList.size(); i++ )
+ {
+ if( ( pinList[i]->m_Flags & IS_LINKED ) == 0 || pinList[i]->m_nameTextSize == size )
+ continue;
+
+ pinList[i]->m_nameTextSize = size;
+ SetModified();
+ }
+}
+
+
+void LIB_PIN::SetNumber( const wxString& number )
+{
+ wxString tmp = ( number.IsEmpty() ) ? wxT( "~" ) : number;
+
+ tmp.Replace( wxT( " " ), wxT( "_" ) );
+ long oldNumber = m_number;
+ SetPinNumFromString( tmp );
+
+ if( m_number != oldNumber )
+ SetFlags( IS_CHANGED );
+
+ /* Others pin numbers marked by EnableEditMode() are not modified
+ * because each pin has its own number
+ */
+}
+
+
+void LIB_PIN::SetNumberTextSize( int size )
+{
+ if( size != m_numTextSize )
+ {
+ m_numTextSize = size;
+ SetModified();
+ }
+
+ if( GetParent() == NULL )
+ return;
+
+ LIB_PINS pinList;
+ GetParent()->GetPins( pinList );
+
+ for( size_t i = 0; i < pinList.size(); i++ )
+ {
+ if( ( pinList[i]->m_Flags & IS_LINKED ) == 0 || pinList[i]->m_numTextSize == size )
+ continue;
+
+ pinList[i]->m_numTextSize = size;
+ SetModified();
+ }
+}
+
+
+void LIB_PIN::SetOrientation( int orientation )
+{
+ if( m_orientation != orientation )
+ {
+ m_orientation = orientation;
+ SetModified();
+ }
+
+ if( GetParent() == NULL )
+ return;
+
+ LIB_PINS pinList;
+ GetParent()->GetPins( pinList );
+
+ for( size_t i = 0; i < pinList.size(); i++ )
+ {
+ if( ( pinList[i]->m_Flags & IS_LINKED ) == 0 ||
+ pinList[i]->m_orientation == orientation )
+ continue;
+
+ pinList[i]->m_orientation = orientation;
+ SetModified();
+ }
+}
+
+
+void LIB_PIN::SetShape( int aShape )
+{
+ if( m_shape != aShape )
+ {
+ m_shape = aShape;
+ SetModified();
+ }
+
+ if( GetParent() == NULL )
+ return;
+
+ LIB_PINS pinList;
+ GetParent()->GetPins( pinList );
+
+ for( size_t i = 0; i < pinList.size(); i++ )
+ {
+ if( ( pinList[i]->m_Flags & IS_LINKED ) == 0
+ || pinList[i]->m_Convert != m_Convert
+ || pinList[i]->m_shape == aShape )
+ continue;
+
+ pinList[i]->m_shape = aShape;
+ SetModified();
+ }
+}
+
+
+void LIB_PIN::SetType( int aType )
+{
+ if( aType < 0 )
+ aType = 0;
+
+ if( aType >= (int)PIN_ELECTRICAL_TYPE_CNT )
+ aType = PIN_ELECTRICAL_TYPE_CNT - 1;
+
+ if( m_type != aType )
+ {
+ m_type = aType;
+ SetModified();
+ }
+
+ if( GetParent() == NULL )
+ return;
+
+ LIB_PINS pinList;
+ GetParent()->GetPins( pinList );
+
+ for( size_t i = 0; i < pinList.size(); i++ )
+ {
+ if( ( pinList[i]->m_Flags & IS_LINKED ) == 0 || pinList[i]->m_type == aType )
+ continue;
+
+ pinList[i]->m_type = aType;
+ SetModified();
+ }
+}
+
+
+void LIB_PIN::SetLength( int length )
+{
+ if( m_length != length )
+ {
+ m_length = length;
+ SetModified();
+ }
+
+ if( GetParent() == NULL )
+ return;
+
+ LIB_PINS pinList;
+ GetParent()->GetPins( pinList );
+
+ for( size_t i = 0; i < pinList.size(); i++ )
+ {
+ if( ( pinList[i]->m_Flags & IS_LINKED ) == 0
+ || pinList[i]->m_Convert != m_Convert
+ || pinList[i]->m_length == length )
+ continue;
+
+ pinList[i]->m_length = length;
+ SetModified();
+ }
+}
+
+
+void LIB_PIN::SetPartNumber( int part )
+{
+ if( m_Unit == part )
+ return;
+
+ m_Unit = part;
+ SetModified();
+
+ if( m_Unit == 0 )
+ {
+ LIB_PIN* pin;
+ LIB_PIN* tmp = GetParent()->GetNextPin();
+
+ while( tmp != NULL )
+ {
+ pin = tmp;
+ tmp = GetParent()->GetNextPin( pin );
+
+ if( pin->m_Flags == 0 || pin == this
+ || ( m_Convert && ( m_Convert != pin->m_Convert ) )
+ || ( m_position != pin->m_position )
+ || ( pin->m_orientation != m_orientation ) )
+ continue;
+
+ GetParent()->RemoveDrawItem( (LIB_ITEM*) pin );
+ }
+ }
+}
+
+
+void LIB_PIN::SetConversion( int style )
+{
+ if( m_Convert == style )
+ return;
+
+ m_Convert = style;
+ SetFlags( IS_CHANGED );
+
+ if( style == 0 )
+ {
+ LIB_PIN* pin;
+ LIB_PIN* tmp = GetParent()->GetNextPin();
+
+ while( tmp != NULL )
+ {
+ pin = tmp;
+ tmp = GetParent()->GetNextPin( pin );
+
+ if( ( pin->m_Flags & IS_LINKED ) == 0
+ || ( pin == this )
+ || ( m_Unit && ( m_Unit != pin->m_Unit ) )
+ || ( m_position != pin->m_position )
+ || ( pin->m_orientation != m_orientation ) )
+ continue;
+
+ GetParent()->RemoveDrawItem( (LIB_ITEM*) pin );
+ }
+ }
+}
+
+
+void LIB_PIN::SetVisible( bool visible )
+{
+ if( visible == IsVisible() )
+ return;
+
+ if( visible )
+ m_attributes &= ~PIN_INVISIBLE;
+ else
+ m_attributes |= PIN_INVISIBLE;
+
+ SetModified();
+
+ if( GetParent() == NULL )
+ return;
+
+ LIB_PINS pinList;
+ GetParent()->GetPins( pinList );
+
+ for( size_t i = 0; i < pinList.size(); i++ )
+ {
+ if( ( pinList[i]->m_Flags & IS_LINKED ) == 0 || pinList[i]->IsVisible() == visible )
+ continue;
+
+ if( visible )
+ pinList[i]->m_attributes &= ~PIN_INVISIBLE;
+ else
+ pinList[i]->m_attributes |= PIN_INVISIBLE;
+
+ SetModified();
+ }
+}
+
+
+void LIB_PIN::EnableEditMode( bool enable, bool editPinByPin )
+{
+ LIB_PINS pinList;
+
+ if( GetParent() == NULL )
+ return;
+
+ GetParent()->GetPins( pinList );
+
+ for( size_t i = 0; i < pinList.size(); i++ )
+ {
+ if( pinList[i] == this )
+ continue;
+
+ if( ( pinList[i]->m_position == m_position )
+ && ( pinList[i]->m_orientation == m_orientation )
+ && !IsNew()
+ && editPinByPin == false
+ && enable )
+ pinList[i]->SetFlags( IS_LINKED | IN_EDIT );
+ else
+ pinList[i]->ClearFlags( IS_LINKED | IN_EDIT );
+ }
+}
+
+
+bool LIB_PIN::HitTest( const wxPoint& aPosition ) const
+{
+ return HitTest( aPosition, 0, DefaultTransform );
+}
+
+
+bool LIB_PIN::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
+{
+ if( aThreshold < 0 )
+ aThreshold = 0;
+
+ TRANSFORM transform = DefaultTransform;
+ DefaultTransform = aTransform;
+
+ EDA_RECT rect = GetBoundingBox();
+ rect.Inflate( aThreshold );
+
+ //Restore matrix
+ DefaultTransform = transform;
+
+ return rect.Contains( aPosition );
+}
+
+
+bool LIB_PIN::Save( OUTPUTFORMATTER& aFormatter )
+{
+ wxString StringPinNum;
+ int Etype;
+
+ switch( m_type )
+ {
+ default:
+ case PIN_INPUT:
+ Etype = 'I';
+ break;
+
+ case PIN_OUTPUT:
+ Etype = 'O';
+ break;
+
+ case PIN_BIDI:
+ Etype = 'B';
+ break;
+
+ case PIN_TRISTATE:
+ Etype = 'T';
+ break;
+
+ case PIN_PASSIVE:
+ Etype = 'P';
+ break;
+
+ case PIN_UNSPECIFIED:
+ Etype = 'U';
+ break;
+
+ case PIN_POWER_IN:
+ Etype = 'W';
+ break;
+
+ case PIN_POWER_OUT:
+ Etype = 'w';
+ break;
+
+ case PIN_OPENCOLLECTOR:
+ Etype = 'C';
+ break;
+
+ case PIN_OPENEMITTER:
+ Etype = 'E';
+ break;
+
+ case PIN_NC:
+ Etype = 'N';
+ break;
+ }
+
+ PinStringNum( StringPinNum );
+
+ if( StringPinNum.IsEmpty() )
+ StringPinNum = wxT( "~" );
+
+ if( !m_name.IsEmpty() )
+ {
+ if( aFormatter.Print( 0, "X %s", TO_UTF8( m_name ) ) < 0 )
+ return false;
+ }
+ else
+ {
+ if( aFormatter.Print( 0, "X ~" ) < 0 )
+ return false;
+ }
+
+ if( aFormatter.Print( 0, " %s %d %d %d %c %d %d %d %d %c",
+ TO_UTF8( StringPinNum ), m_position.x, m_position.y,
+ (int) m_length, (int) m_orientation, m_numTextSize, m_nameTextSize,
+ m_Unit, m_Convert, Etype ) < 0 )
+ return false;
+
+ if( m_shape || !IsVisible() )
+ {
+ if( aFormatter.Print( 0, " " ) < 0 )
+ return false;
+ }
+
+ if( !IsVisible() && aFormatter.Print( 0, "N" ) < 0 )
+ return false;
+
+ if( m_shape & INVERT && aFormatter.Print( 0, "I" ) < 0 )
+ return false;
+
+ if( m_shape & CLOCK && aFormatter.Print( 0, "C" ) < 0 )
+ return false;
+
+ if( m_shape & LOWLEVEL_IN && aFormatter.Print( 0, "L" ) < 0 )
+ return false;
+
+ if( m_shape & LOWLEVEL_OUT && aFormatter.Print( 0, "V" ) < 0 )
+ return false;
+
+ if( m_shape & CLOCK_FALL && aFormatter.Print( 0, "F" ) < 0 )
+ return false;
+
+ if( m_shape & NONLOGIC && aFormatter.Print( 0, "X" ) < 0 )
+ return false;
+
+ if( aFormatter.Print( 0, "\n" ) < 0 )
+ return false;
+
+ ClearFlags( IS_CHANGED );
+
+ return true;
+}
+
+#include <wx/tokenzr.h>
+
+bool LIB_PIN::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
+{
+ char pinAttrs[64];
+ char pinOrient[64];
+ char pinType[64];
+
+ *pinAttrs = 0;
+
+ // We cannot use sscanf, at least on Windows, to parse the pin description.
+ // The reason is the pin name is free, and use UTF8 encoding.
+ // We encourtered issues (Windows specific) to read this name for some UTF8
+ // cyrillic codes
+ // So, read the pin name (and num) after conversion from UTF8, and read the others
+ // parameters (in ASCII) using sscanf
+
+ // the full line starts by "X ". The pin data starts at line + 2.
+ wxString utf8line = FROM_UTF8( aLineReader.Line() + 2 );
+ wxStringTokenizer tokenizer( utf8line, wxT(" \n\r" ) );
+ int prms_count = tokenizer.CountTokens();
+
+ if( prms_count < 11 )
+ {
+ aErrorMsg.Printf( wxT( "pin had %d parameters of the required 11 or 12" ), prms_count );
+ return false;
+ }
+
+ // Extract the pinName (UTF8 encoded)
+ m_name = tokenizer.GetNextToken();
+
+ wxString tmp;
+
+ // Extract the pinName (UTF8 encoded accepted, but should be only ASCII8.)
+ tmp = tokenizer.GetNextToken();
+ SetPinNumFromString( tmp );
+
+ // Read other parameters, in pure ASCII
+ char line[1024];
+ tmp = tokenizer.GetString();
+
+ unsigned len = tmp.Length();
+
+ if( len >= sizeof( line ) ) // Should not occur.
+ len = sizeof( line) - 1;
+
+ strncpy( line, TO_UTF8( tmp ), len );
+ line[len] = 0;
+
+ int cnt = sscanf( line, "%d %d %d %63s %d %d %d %d %63s %63s",
+ &m_position.x, &m_position.y, &m_length, pinOrient, &m_numTextSize,
+ &m_nameTextSize, &m_Unit, &m_Convert, pinType, pinAttrs );
+
+ if( cnt != (prms_count - 2) )
+ {
+ aErrorMsg.Printf( wxT( "pin parameters read issue" ) );
+ return false;
+ }
+
+ m_orientation = pinOrient[0] & 255;
+
+ switch( *pinType & 255 )
+ {
+ case 'I':
+ m_type = PIN_INPUT;
+ break;
+
+ case 'O':
+ m_type = PIN_OUTPUT;
+ break;
+
+ case 'B':
+ m_type = PIN_BIDI;
+ break;
+
+ case 'T':
+ m_type = PIN_TRISTATE;
+ break;
+
+ case 'P':
+ m_type = PIN_PASSIVE;
+ break;
+
+ case 'U':
+ m_type = PIN_UNSPECIFIED;
+ break;
+
+ case 'W':
+ m_type = PIN_POWER_IN;
+ break;
+
+ case 'w':
+ m_type = PIN_POWER_OUT;
+ break;
+
+ case 'C':
+ m_type = PIN_OPENCOLLECTOR;
+ break;
+
+ case 'E':
+ m_type = PIN_OPENEMITTER;
+ break;
+
+ case 'N':
+ m_type = PIN_NC;
+ break;
+
+ default:
+ aErrorMsg.Printf( wxT( "unknown pin type [%c]" ), *pinType & 255 );
+ return false;
+ }
+
+ if( prms_count >= 12 ) /* Special Symbol defined */
+ {
+ for( int j = strlen( pinAttrs ); j > 0; )
+ {
+ switch( pinAttrs[--j] )
+ {
+ case '~':
+ break;
+
+ case 'N':
+ m_attributes |= PIN_INVISIBLE;
+ break;
+
+ case 'I':
+ m_shape |= INVERT;
+ break;
+
+ case 'C':
+ m_shape |= CLOCK;
+ break;
+
+ case 'L':
+ m_shape |= LOWLEVEL_IN;
+ break;
+
+ case 'V':
+ m_shape |= LOWLEVEL_OUT;
+ break;
+
+ case 'F':
+ m_shape |= CLOCK_FALL;
+ break;
+
+ case 'X':
+ m_shape |= NONLOGIC;
+ break;
+
+ default:
+ aErrorMsg.Printf( wxT( "unknown pin attribute [%c]" ), pinAttrs[j] );
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+
+int LIB_PIN::GetPenSize() const
+{
+ return ( m_width == 0 ) ? GetDefaultLineThickness() : m_width;
+}
+
+
+void LIB_PIN::drawGraphic( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC,
+ const wxPoint& aOffset,
+ EDA_COLOR_T aColor,
+ GR_DRAWMODE aDrawMode,
+ void* aData,
+ const TRANSFORM& aTransform )
+{
+ // aData is used here as a bitfield of flags.
+ uintptr_t flags = (uintptr_t) aData;
+ bool drawPinText = flags & PIN_DRAW_TEXTS;
+ bool drawPinDangling = flags & PIN_DRAW_DANGLING;
+ bool drawDanglingHidden = flags & PIN_DANGLING_HIDDEN;
+
+ LIB_PART* Entry = GetParent();
+
+ /* Calculate pin orient taking in account the component orientation. */
+ int orient = PinDrawOrient( aTransform );
+
+ /* Calculate the pin position */
+ wxPoint pos1 = aTransform.TransformCoordinate( m_position ) + aOffset;
+
+ // Invisible pins are only drawn on request.
+ // They are drawn in GetInvisibleItemColor().
+ // in schematic, they are drawn only if m_showAllPins is true.
+ // In other windows, they are always drawn because we must see them.
+ if( ! IsVisible() )
+ {
+ EDA_DRAW_FRAME* frame = NULL;
+
+ if( aPanel && aPanel->GetParent() )
+ frame = (EDA_DRAW_FRAME*)aPanel->GetParent();
+
+ if( frame && frame->IsType( FRAME_SCH ) &&
+ ! ((SCH_EDIT_FRAME*)frame)->GetShowAllPins() )
+ {
+ if( drawPinDangling && drawDanglingHidden )
+ {
+ // Draw the target
+ DrawPinSymbol( aPanel, aDC, pos1, orient, aDrawMode, aColor, drawPinDangling,
+ /* aOnlyTarget */ true );
+ }
+ return;
+ }
+
+ aColor = GetInvisibleItemColor();
+ }
+
+ /* Drawing from the pin and the special symbol combination */
+ DrawPinSymbol( aPanel, aDC, pos1, orient, aDrawMode, aColor, drawPinDangling );
+
+ if( drawPinText )
+ {
+ DrawPinTexts( aPanel, aDC, pos1, orient, Entry->GetPinNameOffset(),
+ Entry->ShowPinNumbers(), Entry->ShowPinNames(),
+ aColor, aDrawMode );
+ }
+
+ /* Set to one (1) to draw bounding box around pin to validate bounding
+ * box calculation. */
+#if 0
+ EDA_RECT bBox = GetBoundingBox();
+ bBox.RevertYAxis();
+ bBox = aTransform.TransformCoordinate( bBox );
+ bBox.Move( aOffset );
+ GRRect( aPanel ? aPanel->GetClipBox() : NULL, aDC, bBox, 0, LIGHTMAGENTA );
+#endif
+}
+
+
+void LIB_PIN::DrawPinSymbol( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC,
+ const wxPoint& aPinPos,
+ int aOrient,
+ GR_DRAWMODE aDrawMode,
+ EDA_COLOR_T aColor,
+ bool aDrawDangling,
+ bool aOnlyTarget )
+{
+ int MapX1, MapY1, x1, y1;
+ int width = GetPenSize();
+ int posX = aPinPos.x, posY = aPinPos.y, len = m_length;
+ EDA_RECT* clipbox = aPanel ? aPanel->GetClipBox() : NULL;
+
+ EDA_COLOR_T color = GetLayerColor( LAYER_PIN );
+
+ if( aColor < 0 ) // Used normal color or selected color
+ {
+ if( IsSelected() )
+ color = GetItemSelectedColor();
+ }
+ else
+ color = aColor;
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ MapX1 = MapY1 = 0;
+ x1 = posX;
+ y1 = posY;
+
+ switch( aOrient )
+ {
+ case PIN_UP:
+ y1 = posY - len;
+ MapY1 = 1;
+ break;
+
+ case PIN_DOWN:
+ y1 = posY + len;
+ MapY1 = -1;
+ break;
+
+ case PIN_LEFT:
+ x1 = posX - len;
+ MapX1 = 1;
+ break;
+
+ case PIN_RIGHT:
+ x1 = posX + len;
+ MapX1 = -1;
+ break;
+ }
+
+ // Draw the pin end target (active end of the pin)
+ BASE_SCREEN* screen = aPanel ? aPanel->GetScreen() : NULL;
+ #define NCSYMB_PIN_DIM TARGET_PIN_RADIUS
+
+ // Draw but do not print the pin end target 1 pixel width
+ if( m_type != PIN_NC && ( screen == NULL || !screen->m_IsPrinting ) )
+ {
+ if( aDrawDangling )
+ GRCircle( clipbox, aDC, posX, posY, TARGET_PIN_RADIUS, 0, color );
+ }
+
+ if( aOnlyTarget )
+ return;
+
+
+ if( m_shape & INVERT )
+ {
+ const int radius = ExternalPinDecoSize( *this );
+ GRCircle( clipbox, aDC, MapX1 * radius + x1,
+ MapY1 * radius + y1,
+ radius, width, color );
+
+ GRMoveTo( MapX1 * radius * 2 + x1,
+ MapY1 * radius * 2 + y1 );
+ GRLineTo( clipbox, aDC, posX, posY, width, color );
+ }
+ else if( m_shape & CLOCK_FALL ) /* an alternative for Inverted Clock */
+ {
+ const int clock_size = InternalPinDecoSize( *this );
+ if( MapY1 == 0 ) /* MapX1 = +- 1 */
+ {
+ GRMoveTo( x1, y1 + clock_size );
+ GRLineTo( clipbox, aDC, x1 + MapX1 * clock_size * 2, y1,
+ width, color );
+ GRLineTo( clipbox, aDC, x1, y1 - clock_size, width, color );
+ }
+ else /* MapX1 = 0 */
+ {
+ GRMoveTo( x1 + clock_size, y1 );
+ GRLineTo( clipbox, aDC, x1, y1 + MapY1 * clock_size * 2,
+ width, color );
+ GRLineTo( clipbox, aDC, x1 - clock_size, y1,
+ width, color );
+ }
+ GRMoveTo( MapX1 * clock_size * 2 + x1, MapY1 * clock_size * 2 + y1 );
+ GRLineTo( clipbox, aDC, posX, posY, width, color );
+ }
+ else
+ {
+ GRMoveTo( x1, y1 );
+ GRLineTo( clipbox, aDC, posX, posY, width, color );
+ }
+
+ if( m_shape & CLOCK )
+ {
+ const int clock_size = InternalPinDecoSize( *this );
+ if( MapY1 == 0 ) /* MapX1 = +- 1 */
+ {
+ GRMoveTo( x1, y1 + clock_size );
+ GRLineTo( clipbox, aDC, x1 - MapX1 * clock_size * 2, y1,
+ width, color );
+ GRLineTo( clipbox, aDC, x1, y1 - clock_size,
+ width, color );
+ }
+ else /* MapX1 = 0 */
+ {
+ GRMoveTo( x1 + clock_size, y1 );
+ GRLineTo( clipbox, aDC, x1, y1 - MapY1 * clock_size * 2,
+ width, color );
+ GRLineTo( clipbox, aDC, x1 - clock_size, y1,
+ width, color );
+ }
+ }
+
+ if( m_shape & LOWLEVEL_IN ) /* IEEE symbol "Active Low Input" */
+ {
+ const int symbol_size = ExternalPinDecoSize( *this );
+ if( MapY1 == 0 ) /* MapX1 = +- 1 */
+ {
+ GRMoveTo( x1 + MapX1 * symbol_size * 2, y1 );
+ GRLineTo( clipbox, aDC,
+ x1 + MapX1 * symbol_size * 2, y1 - symbol_size * 2,
+ width, color );
+ GRLineTo( clipbox, aDC, x1, y1, width, color );
+ }
+ else /* MapX1 = 0 */
+ {
+ GRMoveTo( x1, y1 + MapY1 * symbol_size * 2 );
+ GRLineTo( clipbox, aDC, x1 - symbol_size * 2,
+ y1 + MapY1 * symbol_size * 2, width, color );
+ GRLineTo( clipbox, aDC, x1, y1, width, color );
+ }
+ }
+
+
+ if( m_shape & LOWLEVEL_OUT ) /* IEEE symbol "Active Low Output" */
+ {
+ const int symbol_size = ExternalPinDecoSize( *this );
+ if( MapY1 == 0 ) /* MapX1 = +- 1 */
+ {
+ GRMoveTo( x1, y1 - symbol_size * 2 );
+ GRLineTo( clipbox,
+ aDC,
+ x1 + MapX1 * symbol_size * 2,
+ y1,
+ width,
+ color );
+ }
+ else /* MapX1 = 0 */
+ {
+ GRMoveTo( x1 - symbol_size * 2, y1 );
+ GRLineTo( clipbox, aDC, x1, y1 + MapY1 * symbol_size * 2,
+ width, color );
+ }
+ }
+ else if( m_shape & NONLOGIC ) /* NonLogic pin symbol */
+ {
+ const int symbol_size = ExternalPinDecoSize( *this );
+ GRMoveTo( x1 - (MapX1 + MapY1) * symbol_size,
+ y1 - (MapY1 - MapX1) * symbol_size );
+ GRLineTo( clipbox, aDC,
+ x1 + (MapX1 + MapY1) * symbol_size,
+ y1 + (MapY1 - MapX1) * symbol_size,
+ width, color );
+ GRMoveTo( x1 - (MapX1 - MapY1) * symbol_size,
+ y1 - (MapY1 + MapX1) * symbol_size );
+ GRLineTo( clipbox, aDC,
+ x1 + (MapX1 - MapY1) * symbol_size,
+ y1 + (MapY1 + MapX1) * symbol_size,
+ width, color );
+ }
+
+ if( m_type == PIN_NC ) // Draw a N.C. symbol
+ {
+ GRLine( clipbox, aDC,
+ posX - NCSYMB_PIN_DIM, posY - NCSYMB_PIN_DIM,
+ posX + NCSYMB_PIN_DIM, posY + NCSYMB_PIN_DIM,
+ width, color );
+ GRLine( clipbox, aDC,
+ posX + NCSYMB_PIN_DIM, posY - NCSYMB_PIN_DIM,
+ posX - NCSYMB_PIN_DIM, posY + NCSYMB_PIN_DIM,
+ width, color );
+ }
+}
+
+
+void LIB_PIN::DrawPinTexts( EDA_DRAW_PANEL* panel,
+ wxDC* DC,
+ wxPoint& pin_pos,
+ int orient,
+ int TextInside,
+ bool DrawPinNum,
+ bool DrawPinName,
+ EDA_COLOR_T Color,
+ GR_DRAWMODE DrawMode )
+{
+ if( !DrawPinName && !DrawPinNum )
+ return;
+
+ int x, y;
+ wxString StringPinNum;
+
+ wxSize PinNameSize( m_nameTextSize, m_nameTextSize );
+ wxSize PinNumSize( m_numTextSize, m_numTextSize );
+
+ int nameLineWidth = GetPenSize();
+
+ nameLineWidth = Clamp_Text_PenSize( nameLineWidth, m_nameTextSize, false );
+ int numLineWidth = GetPenSize();
+ numLineWidth = Clamp_Text_PenSize( numLineWidth, m_numTextSize, false );
+
+ GRSetDrawMode( DC, DrawMode );
+ EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL;
+
+ /* Get the num and name colors */
+ if( (Color < 0) && IsSelected() )
+ Color = GetItemSelectedColor();
+
+ EDA_COLOR_T NameColor = Color == UNSPECIFIED_COLOR ?
+ GetLayerColor( LAYER_PINNAM ) : Color;
+ EDA_COLOR_T NumColor = Color == UNSPECIFIED_COLOR ?
+ GetLayerColor( LAYER_PINNUM ) : Color;
+
+ /* Create the pin num string */
+ PinStringNum( StringPinNum );
+
+ int x1 = pin_pos.x;
+ int y1 = pin_pos.y;
+
+ switch( orient )
+ {
+ case PIN_UP:
+ y1 -= m_length;
+ break;
+
+ case PIN_DOWN:
+ y1 += m_length;
+ break;
+
+ case PIN_LEFT:
+ x1 -= m_length;
+ break;
+
+ case PIN_RIGHT:
+ x1 += m_length;
+ break;
+ }
+
+ if( m_name.IsEmpty() )
+ DrawPinName = false;
+
+ if( TextInside ) // Draw the text inside, but the pin numbers outside.
+ {
+ if( (orient == PIN_LEFT) || (orient == PIN_RIGHT) )
+ {
+ // It is an horizontal line
+ if( DrawPinName )
+ {
+ if( orient == PIN_RIGHT )
+ {
+ x = x1 + TextInside;
+ DrawGraphicText( clipbox, DC, wxPoint( x, y1 ), NameColor,
+ m_name,
+ TEXT_ORIENT_HORIZ,
+ PinNameSize,
+ GR_TEXT_HJUSTIFY_LEFT,
+ GR_TEXT_VJUSTIFY_CENTER, nameLineWidth,
+ false, false );
+ }
+ else // Orient == PIN_LEFT
+ {
+ x = x1 - TextInside;
+ DrawGraphicText( clipbox, DC, wxPoint( x, y1 ), NameColor,
+ m_name,
+ TEXT_ORIENT_HORIZ,
+ PinNameSize,
+ GR_TEXT_HJUSTIFY_RIGHT,
+ GR_TEXT_VJUSTIFY_CENTER, nameLineWidth,
+ false, false );
+ }
+ }
+
+ if( DrawPinNum )
+ {
+ DrawGraphicText( clipbox, DC,
+ wxPoint( (x1 + pin_pos.x) / 2,
+ y1 - TXTMARGE ), NumColor,
+ StringPinNum,
+ TEXT_ORIENT_HORIZ, PinNumSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_BOTTOM, numLineWidth,
+ false, false );
+ }
+ }
+ else /* Its a vertical line. */
+ {
+ // Text is drawn from bottom to top (i.e. to negative value for Y axis)
+ if( orient == PIN_DOWN )
+ {
+ y = y1 + TextInside;
+
+ if( DrawPinName )
+ DrawGraphicText( clipbox, DC, wxPoint( x1, y ), NameColor,
+ m_name,
+ TEXT_ORIENT_VERT, PinNameSize,
+ GR_TEXT_HJUSTIFY_RIGHT,
+ GR_TEXT_VJUSTIFY_CENTER, nameLineWidth,
+ false, false );
+
+ if( DrawPinNum )
+ DrawGraphicText( clipbox, DC,
+ wxPoint( x1 - TXTMARGE,
+ (y1 + pin_pos.y) / 2 ), NumColor,
+ StringPinNum,
+ TEXT_ORIENT_VERT, PinNumSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_BOTTOM, numLineWidth,
+ false, false );
+ }
+ else /* PIN_UP */
+ {
+ y = y1 - TextInside;
+
+ if( DrawPinName )
+ DrawGraphicText( clipbox, DC, wxPoint( x1, y ), NameColor,
+ m_name,
+ TEXT_ORIENT_VERT, PinNameSize,
+ GR_TEXT_HJUSTIFY_LEFT,
+ GR_TEXT_VJUSTIFY_CENTER, nameLineWidth,
+ false, false );
+
+ if( DrawPinNum )
+ DrawGraphicText( clipbox, DC,
+ wxPoint( x1 - TXTMARGE,
+ (y1 + pin_pos.y) / 2 ), NumColor,
+ StringPinNum,
+ TEXT_ORIENT_VERT, PinNumSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_BOTTOM, numLineWidth,
+ false, false );
+ }
+ }
+ }
+ else /**** Draw num & text pin outside ****/
+ {
+ if( (orient == PIN_LEFT) || (orient == PIN_RIGHT) )
+ {
+ /* Its an horizontal line. */
+ if( DrawPinName )
+ {
+ x = (x1 + pin_pos.x) / 2;
+ DrawGraphicText( clipbox, DC, wxPoint( x, y1 - TXTMARGE ),
+ NameColor, m_name,
+ TEXT_ORIENT_HORIZ, PinNameSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_BOTTOM, nameLineWidth,
+ false, false );
+ }
+ if( DrawPinNum )
+ {
+ x = (x1 + pin_pos.x) / 2;
+ DrawGraphicText( clipbox, DC, wxPoint( x, y1 + TXTMARGE ),
+ NumColor, StringPinNum,
+ TEXT_ORIENT_HORIZ, PinNumSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_TOP, numLineWidth,
+ false, false );
+ }
+ }
+ else /* Its a vertical line. */
+ {
+ if( DrawPinName )
+ {
+ y = (y1 + pin_pos.y) / 2;
+ DrawGraphicText( clipbox, DC, wxPoint( x1 - TXTMARGE, y ),
+ NameColor, m_name,
+ TEXT_ORIENT_VERT, PinNameSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_BOTTOM, nameLineWidth,
+ false, false );
+ }
+
+ if( DrawPinNum )
+ {
+ DrawGraphicText( clipbox, DC,
+ wxPoint( x1 + TXTMARGE, (y1 + pin_pos.y) / 2 ),
+ NumColor, StringPinNum,
+ TEXT_ORIENT_VERT, PinNumSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_TOP, numLineWidth,
+ false, false );
+ }
+ }
+ }
+}
+
+
+void LIB_PIN::PlotSymbol( PLOTTER* aPlotter, const wxPoint& aPosition, int aOrientation )
+{
+ int MapX1, MapY1, x1, y1;
+ EDA_COLOR_T color = GetLayerColor( LAYER_PIN );
+
+ aPlotter->SetColor( color );
+ aPlotter->SetCurrentLineWidth( GetPenSize() );
+
+ MapX1 = MapY1 = 0;
+ x1 = aPosition.x; y1 = aPosition.y;
+
+ switch( aOrientation )
+ {
+ case PIN_UP:
+ y1 = aPosition.y - m_length;
+ MapY1 = 1;
+ break;
+
+ case PIN_DOWN:
+ y1 = aPosition.y + m_length;
+ MapY1 = -1;
+ break;
+
+ case PIN_LEFT:
+ x1 = aPosition.x - m_length;
+ MapX1 = 1;
+ break;
+
+ case PIN_RIGHT:
+ x1 = aPosition.x + m_length;
+ MapX1 = -1;
+ break;
+ }
+
+ if( m_shape & INVERT )
+ {
+ const int radius = ExternalPinDecoSize( *this );
+ aPlotter->Circle( wxPoint( MapX1 * radius + x1,
+ MapY1 * radius + y1 ),
+ radius * 2, // diameter
+ NO_FILL, // fill option
+ GetPenSize() ); // width
+
+ aPlotter->MoveTo( wxPoint( MapX1 * radius * 2 + x1,
+ MapY1 * radius * 2 + y1 ) );
+ aPlotter->FinishTo( aPosition );
+ }
+ else if( m_shape & CLOCK_FALL )
+ {
+ const int clock_size = InternalPinDecoSize( *this );
+ if( MapY1 == 0 ) /* MapX1 = +- 1 */
+ {
+ aPlotter->MoveTo( wxPoint( x1, y1 + clock_size ) );
+ aPlotter->LineTo( wxPoint( x1 + MapX1 * clock_size * 2, y1 ) );
+ aPlotter->FinishTo( wxPoint( x1, y1 - clock_size ) );
+ }
+ else /* MapX1 = 0 */
+ {
+ aPlotter->MoveTo( wxPoint( x1 + clock_size, y1 ) );
+ aPlotter->LineTo( wxPoint( x1, y1 + MapY1 * clock_size * 2 ) );
+ aPlotter->FinishTo( wxPoint( x1 - clock_size, y1 ) );
+ }
+
+ aPlotter->MoveTo( wxPoint( MapX1 * clock_size * 2 + x1,
+ MapY1 * clock_size * 2 + y1 ) );
+ aPlotter->FinishTo( aPosition );
+ }
+ else
+ {
+ aPlotter->MoveTo( wxPoint( x1, y1 ) );
+ aPlotter->FinishTo( aPosition );
+ }
+
+ if( m_shape & CLOCK )
+ {
+ const int clock_size = InternalPinDecoSize( *this );
+ if( MapY1 == 0 ) /* MapX1 = +- 1 */
+ {
+ aPlotter->MoveTo( wxPoint( x1, y1 + clock_size ) );
+ aPlotter->LineTo( wxPoint( x1 - MapX1 * clock_size * 2, y1 ) );
+ aPlotter->FinishTo( wxPoint( x1, y1 - clock_size ) );
+ }
+ else /* MapX1 = 0 */
+ {
+ aPlotter->MoveTo( wxPoint( x1 + clock_size, y1 ) );
+ aPlotter->LineTo( wxPoint( x1, y1 - MapY1 * clock_size * 2 ) );
+ aPlotter->FinishTo( wxPoint( x1 - clock_size, y1 ) );
+ }
+ }
+
+ if( m_shape & LOWLEVEL_IN ) /* IEEE symbol "Active Low Input" */
+ {
+ const int symbol_size = ExternalPinDecoSize( *this );
+
+ if( MapY1 == 0 ) /* MapX1 = +- 1 */
+ {
+ aPlotter->MoveTo( wxPoint( x1 + MapX1 * symbol_size * 2, y1 ) );
+ aPlotter->LineTo( wxPoint( x1 + MapX1 * symbol_size * 2,
+ y1 - symbol_size * 2 ) );
+ aPlotter->FinishTo( wxPoint( x1, y1 ) );
+ }
+ else /* MapX1 = 0 */
+ {
+ aPlotter->MoveTo( wxPoint( x1, y1 + MapY1 * symbol_size * 2 ) );
+ aPlotter->LineTo( wxPoint( x1 - symbol_size * 2,
+ y1 + MapY1 * symbol_size * 2 ) );
+ aPlotter->FinishTo( wxPoint( x1, y1 ) );
+ }
+ }
+
+
+ if( m_shape & LOWLEVEL_OUT ) /* IEEE symbol "Active Low Output" */
+ {
+ const int symbol_size = ExternalPinDecoSize( *this );
+
+ if( MapY1 == 0 ) /* MapX1 = +- 1 */
+ {
+ aPlotter->MoveTo( wxPoint( x1, y1 - symbol_size * 2 ) );
+ aPlotter->FinishTo( wxPoint( x1 + MapX1 * symbol_size * 2, y1 ) );
+ }
+ else /* MapX1 = 0 */
+ {
+ aPlotter->MoveTo( wxPoint( x1 - symbol_size * 2, y1 ) );
+ aPlotter->FinishTo( wxPoint( x1, y1 + MapY1 * symbol_size * 2 ) );
+ }
+ }
+ else if( m_shape & NONLOGIC ) /* NonLogic pin symbol */
+ {
+ const int symbol_size = ExternalPinDecoSize( *this );
+ aPlotter->MoveTo( wxPoint( x1 - (MapX1 + MapY1) * symbol_size,
+ y1 - (MapY1 - MapX1) * symbol_size ) );
+ aPlotter->FinishTo( wxPoint( x1 + (MapX1 + MapY1) * symbol_size,
+ y1 + (MapY1 - MapX1) * symbol_size ) );
+ aPlotter->MoveTo( wxPoint( x1 - (MapX1 - MapY1) * symbol_size,
+ y1 - (MapY1 + MapX1) * symbol_size ) );
+ aPlotter->FinishTo( wxPoint( x1 + (MapX1 - MapY1) * symbol_size,
+ y1 + (MapY1 + MapX1) * symbol_size ) );
+ }
+ if( m_type == PIN_NC ) // Draw a N.C. symbol
+ {
+ const int ex1 = aPosition.x;
+ const int ey1 = aPosition.y;
+ aPlotter->MoveTo( wxPoint( ex1 - NCSYMB_PIN_DIM, ey1 - NCSYMB_PIN_DIM ) );
+ aPlotter->FinishTo( wxPoint( ex1 + NCSYMB_PIN_DIM, ey1 + NCSYMB_PIN_DIM ) );
+ aPlotter->MoveTo( wxPoint( ex1 + NCSYMB_PIN_DIM, ey1 - NCSYMB_PIN_DIM ) );
+ aPlotter->FinishTo( wxPoint( ex1 - NCSYMB_PIN_DIM, ey1 + NCSYMB_PIN_DIM ) );
+ }
+}
+
+
+void LIB_PIN::PlotPinTexts( PLOTTER* plotter, wxPoint& pin_pos, int orient,
+ int TextInside, bool DrawPinNum,
+ bool DrawPinName, int aWidth )
+{
+ if( m_name.IsEmpty() || m_name == wxT( "~" ) )
+ DrawPinName = false;
+
+ /* Create the pin num string */
+ wxString StringPinNum;
+ PinStringNum( StringPinNum );
+
+ if( StringPinNum.IsEmpty() )
+ DrawPinNum = false;
+
+ if( !DrawPinNum && !DrawPinName )
+ return;
+
+ int x, y;
+ wxSize PinNameSize = wxSize( m_nameTextSize, m_nameTextSize );
+ wxSize PinNumSize = wxSize( m_numTextSize, m_numTextSize );
+
+ /* Get the num and name colors */
+ EDA_COLOR_T NameColor = GetLayerColor( LAYER_PINNAM );
+ EDA_COLOR_T NumColor = GetLayerColor( LAYER_PINNUM );
+
+ int x1 = pin_pos.x;
+ int y1 = pin_pos.y;
+
+ switch( orient )
+ {
+ case PIN_UP:
+ y1 -= m_length;
+ break;
+
+ case PIN_DOWN:
+ y1 += m_length;
+ break;
+
+ case PIN_LEFT:
+ x1 -= m_length;
+ break;
+
+ case PIN_RIGHT:
+ x1 += m_length;
+ break;
+ }
+
+ /* Draw the text inside, but the pin numbers outside. */
+ if( TextInside )
+ {
+ if( (orient == PIN_LEFT) || (orient == PIN_RIGHT) ) /* Its an horizontal line. */
+ {
+ if( DrawPinName )
+ {
+ if( orient == PIN_RIGHT )
+ {
+ x = x1 + TextInside;
+ plotter->Text( wxPoint( x, y1 ), NameColor,
+ m_name,
+ TEXT_ORIENT_HORIZ,
+ PinNameSize,
+ GR_TEXT_HJUSTIFY_LEFT,
+ GR_TEXT_VJUSTIFY_CENTER,
+ aWidth, false, false );
+ }
+ else // orient == PIN_LEFT
+ {
+ x = x1 - TextInside;
+
+ if( DrawPinName )
+ plotter->Text( wxPoint( x, y1 ),
+ NameColor, m_name, TEXT_ORIENT_HORIZ,
+ PinNameSize,
+ GR_TEXT_HJUSTIFY_RIGHT,
+ GR_TEXT_VJUSTIFY_CENTER,
+ aWidth, false, false );
+ }
+ }
+ if( DrawPinNum )
+ {
+ plotter->Text( wxPoint( (x1 + pin_pos.x) / 2, y1 - TXTMARGE ),
+ NumColor, StringPinNum,
+ TEXT_ORIENT_HORIZ, PinNumSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_BOTTOM,
+ aWidth, false, false );
+ }
+ }
+ else /* Its a vertical line. */
+ {
+ if( orient == PIN_DOWN )
+ {
+ y = y1 + TextInside;
+
+ if( DrawPinName )
+ plotter->Text( wxPoint( x1, y ), NameColor,
+ m_name,
+ TEXT_ORIENT_VERT, PinNameSize,
+ GR_TEXT_HJUSTIFY_RIGHT,
+ GR_TEXT_VJUSTIFY_CENTER,
+ aWidth, false, false );
+
+ if( DrawPinNum )
+ {
+ plotter->Text( wxPoint( x1 - TXTMARGE, (y1 + pin_pos.y) / 2 ),
+ NumColor, StringPinNum,
+ TEXT_ORIENT_VERT, PinNumSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_BOTTOM,
+ aWidth, false, false );
+ }
+ }
+ else /* PIN_UP */
+ {
+ y = y1 - TextInside;
+
+ if( DrawPinName )
+ plotter->Text( wxPoint( x1, y ), NameColor,
+ m_name,
+ TEXT_ORIENT_VERT, PinNameSize,
+ GR_TEXT_HJUSTIFY_LEFT,
+ GR_TEXT_VJUSTIFY_CENTER,
+ aWidth, false, false );
+
+ if( DrawPinNum )
+ {
+ plotter->Text( wxPoint( x1 - TXTMARGE, (y1 + pin_pos.y) / 2 ),
+ NumColor, StringPinNum,
+ TEXT_ORIENT_VERT, PinNumSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_BOTTOM,
+ aWidth, false, false );
+ }
+ }
+ }
+ }
+ else /* Draw num & text pin outside */
+ {
+ if( (orient == PIN_LEFT) || (orient == PIN_RIGHT) )
+ {
+ /* Its an horizontal line. */
+ if( DrawPinName )
+ {
+ x = (x1 + pin_pos.x) / 2;
+ plotter->Text( wxPoint( x, y1 - TXTMARGE ),
+ NameColor, m_name,
+ TEXT_ORIENT_HORIZ, PinNameSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_BOTTOM,
+ aWidth, false, false );
+ }
+
+ if( DrawPinNum )
+ {
+ x = ( x1 + pin_pos.x ) / 2;
+ plotter->Text( wxPoint( x, y1 + TXTMARGE ),
+ NumColor, StringPinNum,
+ TEXT_ORIENT_HORIZ, PinNumSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_TOP,
+ aWidth, false, false );
+ }
+ }
+ else /* Its a vertical line. */
+ {
+ if( DrawPinName )
+ {
+ y = ( y1 + pin_pos.y ) / 2;
+ plotter->Text( wxPoint( x1 - TXTMARGE, y ),
+ NameColor, m_name,
+ TEXT_ORIENT_VERT, PinNameSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_BOTTOM,
+ aWidth, false, false );
+ }
+
+ if( DrawPinNum )
+ {
+ plotter->Text( wxPoint( x1 + TXTMARGE, ( y1 + pin_pos.y ) / 2 ),
+ NumColor, StringPinNum,
+ TEXT_ORIENT_VERT, PinNumSize,
+ GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_TOP,
+ aWidth, false, false );
+ }
+ }
+ }
+}
+
+
+wxPoint LIB_PIN::PinEndPoint() const
+{
+ wxPoint pos = m_position;
+
+ switch( m_orientation )
+ {
+ case PIN_UP:
+ pos.y += m_length;
+ break;
+
+ case PIN_DOWN:
+ pos.y -= m_length;
+ break;
+
+ case PIN_LEFT:
+ pos.x -= m_length;
+ break;
+
+ case PIN_RIGHT:
+ pos.x += m_length;
+ break;
+ }
+
+ return pos;
+}
+
+
+int LIB_PIN::PinDrawOrient( const TRANSFORM& aTransform ) const
+{
+ int orient;
+ wxPoint end; // position of pin end starting at 0,0 according to its orientation, length = 1
+
+ switch( m_orientation )
+ {
+ case PIN_UP:
+ end.y = 1;
+ break;
+
+ case PIN_DOWN:
+ end.y = -1;
+ break;
+
+ case PIN_LEFT:
+ end.x = -1;
+ break;
+
+ case PIN_RIGHT:
+ end.x = 1;
+ break;
+ }
+
+ // = pos of end point, according to the component orientation
+ end = aTransform.TransformCoordinate( end );
+ orient = PIN_UP;
+
+ if( end.x == 0 )
+ {
+ if( end.y > 0 )
+ orient = PIN_DOWN;
+ }
+ else
+ {
+ orient = PIN_RIGHT;
+
+ if( end.x < 0 )
+ orient = PIN_LEFT;
+ }
+
+ return orient;
+}
+
+
+void LIB_PIN::PinStringNum( wxString& aStringBuffer ) const
+{
+ aStringBuffer = PinStringNum( m_number );
+}
+
+
+wxString LIB_PIN::PinStringNum( long aPinNum )
+{
+ char ascii_buf[5];
+
+ memcpy( ascii_buf, &aPinNum, 4 );
+ ascii_buf[4] = 0;
+
+ wxString buffer = FROM_UTF8( ascii_buf );
+
+ return buffer;
+}
+
+
+void LIB_PIN::SetPinNumFromString( wxString& buffer )
+{
+ char ascii_buf[4];
+ unsigned ii, len = buffer.Len();
+
+ ascii_buf[0] = ascii_buf[1] = ascii_buf[2] = ascii_buf[3] = 0;
+
+ if( len > 4 )
+ len = 4;
+
+ for( ii = 0; ii < len; ii++ )
+ {
+ ascii_buf[ii] = buffer.GetChar( ii );
+ ascii_buf[ii] &= 0xFF;
+ }
+
+ strncpy( (char*) &m_number, ascii_buf, 4 );
+}
+
+
+EDA_ITEM* LIB_PIN::Clone() const
+{
+ return new LIB_PIN( *this );
+}
+
+
+int LIB_PIN::compare( const LIB_ITEM& other ) const
+{
+ wxASSERT( other.Type() == LIB_PIN_T );
+
+ const LIB_PIN* tmp = (LIB_PIN*) &other;
+
+ if( m_number != tmp->m_number )
+ return m_number - tmp->m_number;
+
+ int result = m_name.CmpNoCase( tmp->m_name );
+
+ if( result != 0 )
+ return result;
+
+ if( m_position.x != tmp->m_position.x )
+ return m_position.x - tmp->m_position.x;
+
+ if( m_position.y != tmp->m_position.y )
+ return m_position.y - tmp->m_position.y;
+
+ return 0;
+}
+
+
+void LIB_PIN::SetOffset( const wxPoint& aOffset )
+{
+ m_position += aOffset;
+}
+
+
+bool LIB_PIN::Inside( EDA_RECT& rect ) const
+{
+ wxPoint end = PinEndPoint();
+
+ return rect.Contains( m_position.x, -m_position.y ) || rect.Contains( end.x, -end.y );
+}
+
+
+void LIB_PIN::Move( const wxPoint& newPosition )
+{
+ if( m_position != newPosition )
+ {
+ m_position = newPosition;
+ SetModified();
+ }
+}
+
+
+void LIB_PIN::MirrorHorizontal( const wxPoint& center )
+{
+ m_position.x -= center.x;
+ m_position.x *= -1;
+ m_position.x += center.x;
+
+ if( m_orientation == PIN_RIGHT )
+ m_orientation = PIN_LEFT;
+ else if( m_orientation == PIN_LEFT )
+ m_orientation = PIN_RIGHT;
+}
+
+void LIB_PIN::MirrorVertical( const wxPoint& center )
+{
+ m_position.y -= center.y;
+ m_position.y *= -1;
+ m_position.y += center.y;
+
+ if( m_orientation == PIN_UP )
+ m_orientation = PIN_DOWN;
+ else if( m_orientation == PIN_DOWN )
+ m_orientation = PIN_UP;
+}
+
+void LIB_PIN::Rotate( const wxPoint& center, bool aRotateCCW )
+{
+ int rot_angle = aRotateCCW ? -900 : 900;
+
+ RotatePoint( &m_position, center, rot_angle );
+
+ if( aRotateCCW )
+ {
+ switch( m_orientation )
+ {
+ case PIN_RIGHT:
+ m_orientation = PIN_UP;
+ break;
+
+ case PIN_UP:
+ m_orientation = PIN_LEFT;
+ break;
+ case PIN_LEFT:
+ m_orientation = PIN_DOWN;
+ break;
+
+ case PIN_DOWN:
+ m_orientation = PIN_RIGHT;
+ break;
+ }
+ }
+ else
+ {
+ switch( m_orientation )
+ {
+ case PIN_RIGHT:
+ m_orientation = PIN_DOWN;
+ break;
+
+ case PIN_UP:
+ m_orientation = PIN_RIGHT;
+ break;
+ case PIN_LEFT:
+ m_orientation = PIN_UP;
+ break;
+
+ case PIN_DOWN:
+ m_orientation = PIN_LEFT;
+ break;
+ }
+ }
+}
+
+
+void LIB_PIN::Plot( PLOTTER* plotter, const wxPoint& offset, bool fill,
+ const TRANSFORM& aTransform )
+{
+ if( ! IsVisible() )
+ return;
+
+ int orient = PinDrawOrient( aTransform );
+
+ wxPoint pos = aTransform.TransformCoordinate( m_position ) + offset;
+
+ PlotSymbol( plotter, pos, orient );
+ PlotPinTexts( plotter, pos, orient, GetParent()->GetPinNameOffset(),
+ GetParent()->ShowPinNumbers(), GetParent()->ShowPinNames(),
+ GetPenSize() );
+}
+
+
+void LIB_PIN::SetWidth( int aWidth )
+{
+ if( m_width != aWidth )
+ {
+ m_width = aWidth;
+ SetModified();
+ }
+}
+
+
+void LIB_PIN::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
+{
+ wxString text;
+
+ LIB_ITEM::GetMsgPanelInfo( aList );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Name" ), m_name, DARKCYAN ) );
+
+ if( m_number == 0 )
+ text = wxT( "?" );
+ else
+ PinStringNum( text );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Number" ), text, DARKCYAN ) );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Type" ),
+ LIB_PIN::GetElectricalTypeName( m_type ),
+ RED ) );
+
+ int styleCodeIndex = GetStyleCodeIndex( m_shape );
+
+ if( styleCodeIndex >= 0 )
+ text = getPinStyleName( styleCodeIndex );
+ else
+ text = wxT( "?" );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Style" ), text, BLUE ) );
+
+ if( IsVisible() )
+ text = _( "Yes" );
+ else
+ text = _( "No" );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Visible" ), text, DARKGREEN ) );
+
+ // Display pin length
+ text = StringFromValue( g_UserUnit, m_length, true );
+ aList.push_back( MSG_PANEL_ITEM( _( "Length" ), text, MAGENTA ) );
+
+ text = getPinOrientationName( (unsigned) GetOrientationCodeIndex( m_orientation ) );
+ aList.push_back( MSG_PANEL_ITEM( _( "Orientation" ), text, DARKMAGENTA ) );
+}
+
+
+const EDA_RECT LIB_PIN::GetBoundingBox() const
+{
+ LIB_PART* entry = (LIB_PART* ) m_Parent;
+ EDA_RECT bbox;
+ wxPoint begin;
+ wxPoint end;
+ int nameTextOffset = 0;
+ bool showName = !m_name.IsEmpty() && (m_name != wxT( "~" ));
+ bool showNum = m_number != 0;
+ int minsizeV = TARGET_PIN_RADIUS;
+
+
+ if( entry )
+ {
+ if( entry->ShowPinNames() )
+ nameTextOffset = entry->GetPinNameOffset();
+ else
+ showName = false;
+
+ showNum = entry->ShowPinNumbers();
+ }
+
+ // First, calculate boundary box corners position
+ int numberTextLength = showNum ? m_numTextSize * GetNumberString().Len() : 0;
+
+ // Actual text height is bigger than text size
+ int numberTextHeight = showNum ? KiROUND( m_numTextSize * 1.1 ) : 0;
+
+ if( m_shape & INVERT )
+ minsizeV = std::max( TARGET_PIN_RADIUS, ExternalPinDecoSize( *this ) );
+
+ // calculate top left corner position
+ // for the default pin orientation (PIN_RIGHT)
+ begin.y = std::max( minsizeV, numberTextHeight + TXTMARGE );
+ begin.x = std::min( -TARGET_PIN_RADIUS, m_length - (numberTextLength / 2) );
+
+ // calculate bottom right corner position and adjust top left corner position
+ int nameTextLength = 0;
+ int nameTextHeight = 0;
+
+ if( showName )
+ {
+ int length = m_name.Len();
+
+ // Don't count the line over text symbol.
+ if( m_name.Left( 1 ) == wxT( "~" ) )
+ length -= 1;
+
+ nameTextLength = ( m_nameTextSize * length ) + nameTextOffset;
+
+ // Actual text height are bigger than text size
+ nameTextHeight = KiROUND( m_nameTextSize * 1.1 ) + TXTMARGE;
+ }
+
+ if( nameTextOffset ) // for values > 0, pin name is inside the body
+ {
+ end.x = m_length + nameTextLength;
+ end.y = std::min( -minsizeV, -nameTextHeight / 2 );
+ }
+ else // if value == 0:
+ // pin name is outside the body, and above the pin line
+ // pin num is below the pin line
+ {
+ end.x = std::max(m_length, nameTextLength);
+ end.y = -begin.y;
+ begin.y = std::max( minsizeV, nameTextHeight );
+ }
+
+ // Now, calculate boundary box corners position for the actual pin orientation
+ int orient = PinDrawOrient( DefaultTransform );
+
+ /* Calculate the pin position */
+ switch( orient )
+ {
+ case PIN_UP:
+ // Pin is rotated and texts positions are mirrored
+ RotatePoint( &begin, wxPoint( 0, 0 ), -900 );
+ RotatePoint( &end, wxPoint( 0, 0 ), -900 );
+ break;
+
+ case PIN_DOWN:
+ RotatePoint( &begin, wxPoint( 0, 0 ), 900 );
+ RotatePoint( &end, wxPoint( 0, 0 ), 900 );
+ begin.x = -begin.x;
+ end.x = -end.x;
+ break;
+
+ case PIN_LEFT:
+ begin.x = -begin.x;
+ end.x = -end.x;
+ break;
+
+ case PIN_RIGHT:
+ break;
+ }
+
+ begin += m_position;
+ end += m_position;
+
+ bbox.SetOrigin( begin );
+ bbox.SetEnd( end );
+ bbox.Normalize();
+ bbox.Inflate( ( GetPenSize() / 2 ) + 1 );
+
+ // Draw Y axis is reversed in schematic:
+ bbox.RevertYAxis();
+
+ return bbox;
+}
+
+
+wxArrayString LIB_PIN::GetOrientationNames( void )
+{
+ wxArrayString tmp;
+
+ for( unsigned ii = 0; ii < PIN_ORIENTATION_CNT; ii++ )
+ tmp.Add( getPinOrientationName( ii ) );
+
+ return tmp;
+}
+
+
+int LIB_PIN::GetOrientationCode( int index )
+{
+ if( index >= 0 && index < (int) PIN_ORIENTATION_CNT )
+ return pin_orientation_codes[ index ];
+
+ return PIN_RIGHT;
+}
+
+
+int LIB_PIN::GetOrientationCodeIndex( int code )
+{
+ size_t i;
+
+ for( i = 0; i < PIN_ORIENTATION_CNT; i++ )
+ {
+ if( pin_orientation_codes[i] == code )
+ return (int) i;
+ }
+
+ return wxNOT_FOUND;
+}
+
+
+void LIB_PIN::Rotate()
+{
+ int orient = PIN_RIGHT;
+
+ switch( GetOrientation() )
+ {
+ case PIN_UP:
+ orient = PIN_LEFT;
+ break;
+
+ case PIN_DOWN:
+ orient = PIN_RIGHT;
+ break;
+
+ case PIN_LEFT:
+ orient = PIN_DOWN;
+ break;
+
+ case PIN_RIGHT:
+ orient = PIN_UP;
+ break;
+ }
+
+ // Set the new orientation
+ SetOrientation( orient );
+}
+
+
+wxArrayString LIB_PIN::GetStyleNames( void )
+{
+ wxArrayString tmp;
+
+ for( unsigned ii = 0; ii < PIN_STYLE_CNT; ii++ )
+ tmp.Add( getPinStyleName( ii ) );
+
+ return tmp;
+}
+
+
+int LIB_PIN::GetStyleCode( int index )
+{
+ if( index >= 0 && index < (int) PIN_STYLE_CNT )
+ return pin_style_codes[ index ];
+
+ return NONE;
+}
+
+
+int LIB_PIN::GetStyleCodeIndex( int code )
+{
+ size_t i;
+
+ for( i = 0; i < PIN_STYLE_CNT; i++ )
+ {
+ if( pin_style_codes[i] == code )
+ return (int) i;
+ }
+
+ return wxNOT_FOUND;
+}
+
+
+wxArrayString LIB_PIN::GetElectricalTypeNames( void )
+{
+ wxArrayString tmp;
+
+ for( unsigned ii = 0; ii < PIN_ELECTRICAL_TYPE_CNT; ii++ )
+ tmp.Add( LIB_PIN::GetElectricalTypeName( ii ) );
+
+ return tmp;
+}
+
+
+const BITMAP_DEF* LIB_PIN::GetElectricalTypeSymbols()
+{
+ return iconsPinsElectricalType;
+}
+
+
+const BITMAP_DEF* LIB_PIN::GetOrientationSymbols()
+{
+ return iconsPinsOrientations;
+}
+
+
+const BITMAP_DEF* LIB_PIN::GetStyleSymbols()
+{
+ return iconsPinsShapes;
+}
+
+
+BITMAP_DEF LIB_PIN::GetMenuImage() const
+{
+ return iconsPinsElectricalType[m_type];
+}
+
+
+wxString LIB_PIN::GetSelectMenuText() const
+{
+ wxString tmp;
+ wxString style;
+
+ int styleCode = GetStyleCodeIndex( m_shape );
+
+ if( styleCode >= 0 )
+ style = getPinStyleName( styleCode );
+ else
+ style = wxT( "?" );
+
+ tmp.Printf( _( "Pin %s, %s, %s" ),
+ GetChars( GetNumberString() ),
+ GetChars( GetElectricalTypeName() ),
+ GetChars( style )
+ );
+ return tmp;
+}
+
+
+bool LIB_PIN::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation )
+{
+ wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText() );
+
+ // Note: this will have to be modified if we add find and replace capability to the
+ // compoment library editor. Otherwise, you wont be able to replace pin text.
+ if( !( aSearchData.GetFlags() & FR_SEARCH_ALL_PINS )
+ || ( aSearchData.GetFlags() & FR_SEARCH_REPLACE ) )
+ return false;
+
+ wxLogTrace( traceFindItem, wxT( " child item " ) + GetSelectMenuText() );
+
+ if( EDA_ITEM::Matches( GetName(), aSearchData )
+ || EDA_ITEM::Matches( GetNumberString(), aSearchData ) )
+ {
+ if( aFindLocation )
+ *aFindLocation = GetBoundingBox().Centre();
+
+ return true;
+ }
+
+ return false;
+}
+
+
+#if defined(DEBUG)
+
+void LIB_PIN::Show( int nestLevel, std::ostream& os ) const
+{
+ NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
+ << " num=\"" << GetNumberString().mb_str()
+ << '"' << "/>\n";
+
+// NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
+}
+
+#endif
diff --git a/eeschema/lib_pin.h b/eeschema/lib_pin.h
new file mode 100644
index 0000000..6cf6801
--- /dev/null
+++ b/eeschema/lib_pin.h
@@ -0,0 +1,561 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jaen-pierre.charras at wanadoo.fr
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_libentry.h
+ * @brief Class LIB_PIN definition.
+ */
+#ifndef CLASS_PIN_H
+#define CLASS_PIN_H
+
+#include <lib_draw_item.h>
+
+
+#define TARGET_PIN_RADIUS 12 // Circle diameter drawn at the active end of pins
+
+/**
+ * The component library pin object electrical types used in ERC tests.
+ */
+enum ElectricPinType {
+ PIN_INPUT,
+ PIN_OUTPUT,
+ PIN_BIDI,
+ PIN_TRISTATE,
+ PIN_PASSIVE,
+ PIN_UNSPECIFIED,
+ PIN_POWER_IN,
+ PIN_POWER_OUT,
+ PIN_OPENCOLLECTOR,
+ PIN_OPENEMITTER,
+ PIN_NC, /* No connect */
+ PIN_NMAX /* End of List (no used as pin type) */
+};
+
+
+/* Pin visibility flag bit. */
+#define PIN_INVISIBLE 1 /* Set makes pin invisible */
+
+
+/**
+ * The component library pin object drawing shapes.
+ */
+enum DrawPinShape {
+ NONE = 0,
+ INVERT = 1,
+ CLOCK = 2,
+ LOWLEVEL_IN = 4,
+ LOWLEVEL_OUT = 8,
+ CLOCK_FALL = 0x10, /* this is common form for inverted clock in Eastern Block */
+ NONLOGIC = 0x20
+};
+
+
+/**
+ * The component library pin object orientations.
+ */
+enum DrawPinOrient {
+ PIN_RIGHT = 'R',
+ PIN_LEFT = 'L',
+ PIN_UP = 'U',
+ PIN_DOWN = 'D'
+};
+
+enum LibPinDrawFlags {
+ PIN_DRAW_TEXTS = 1,
+ PIN_DRAW_DANGLING = 2, // Draw this pin with a 'dangling' indicator
+ PIN_DANGLING_HIDDEN = 4, // Draw (only!) the dangling indicator if the pin is hidden
+};
+
+
+class LIB_PIN : public LIB_ITEM
+{
+ wxPoint m_position; ///< Position of the pin.
+ int m_length; ///< Length of the pin.
+ int m_orientation; ///< Pin orientation (Up, Down, Left, Right)
+ int m_shape; ///< Bitwise ORed of pin shapes (see enum DrawPinShape)
+ int m_width; ///< Line width of the pin.
+ int m_type; ///< Electrical type of the pin. See enum ElectricPinType.
+ int m_attributes; ///< Set bit 0 to indicate pin is invisible.
+ wxString m_name;
+ long m_number; ///< Pin number defined as 4 ASCII characters like "12", "anod",
+ ///< "G6", or "12". It is stored as "12\0\0" and does not
+ ///< depend on endian type.
+ int m_numTextSize;
+ int m_nameTextSize; ///< Pin num and Pin name sizes
+
+ /**
+ * Draw a pin, with or without the pin texts
+ *
+ * @param aPanel DrawPanel to use (can be null) mainly used for clipping purposes.
+ * @param aDC Device Context (can be null)
+ * @param aOffset Offset to draw
+ * @param aColor -1 to use the normal body item color, or use this color if >= 0
+ * @param aDrawMode GR_OR, GR_XOR, ...
+ * @param aData = used here as uintptr_t containing bitwise OR'd flags:
+ * PIN_DRAW_TEXTS, -- false to draw only pin shape, useful for fast mode
+ * PIN_DRAW_DANGLING, -- true to draw the pin with its target
+ * PIN_DANGLING_HIDDEN -- draw the target even if the pin is hidden
+ * @param aTransform Transform Matrix (rotation, mirror ..)
+ */
+ void drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform );
+
+public:
+ LIB_PIN( LIB_PART* aParent );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~LIB_PIN() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "LIB_PIN" );
+ }
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // virtual override
+#endif
+
+ bool Save( OUTPUTFORMATTER& aFormatter );
+
+ bool Load( LINE_READER& aLineReader, wxString& aErrorMsg );
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ bool HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const;
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ /**
+ * Function PinEndPoint
+ *
+ * @return The pin end position for a component in the normal orientation.
+ */
+ wxPoint PinEndPoint() const;
+
+ /**
+ * Function PinDrawOrient
+ * returns the pin real orientation (PIN_UP, PIN_DOWN, PIN_RIGHT, PIN_LEFT),
+ * according to its orientation and the matrix transform (rot, mirror) \a aTransform
+ *
+ * @param aTransform Transform matrix
+ */
+ int PinDrawOrient( const TRANSFORM& aTransform ) const;
+
+ /**
+ * Fill a string buffer with pin number.
+ *
+ * Pin numbers are coded as a long or 4 ASCII characters. Used to print
+ * or draw the pin number.
+ *
+ * @param aStringBuffer - the wxString to store the pin num as an unicode string
+ */
+ void PinStringNum( wxString& aStringBuffer ) const;
+
+ long GetNumber() const { return m_number; }
+
+ wxString GetNumberString() const { return PinStringNum( m_number ); }
+
+ /**
+ * Function PinStringNum (static function)
+ * Pin num is coded as a long or 4 ascii chars
+ * @param aPinNum = a long containing a pin num
+ * @return aStringBuffer = the wxString to store the pin num as an
+ * unicode string
+ */
+ static wxString PinStringNum( long aPinNum );
+
+ /**
+ * Function SetPinNumFromString
+ * fill the pin number buffer with \a aBuffer.
+ */
+ void SetPinNumFromString( wxString& aBuffer );
+
+ wxString GetName() const { return m_name; }
+
+ /**
+ * Set the pin name.
+ *
+ * This will also all of the pin names marked by EnableEditMode().
+ *
+ * @param aName New pin name.
+ */
+ void SetName( const wxString& aName );
+
+ /**
+ * Set the \a aSize of the pin name text.
+ *
+ * This will also update the text size of the name of the pins marked
+ * by EnableEditMode().
+ *
+ * @param aSize The text size of the pin name in schematic units ( mils ).
+ */
+ void SetNameTextSize( int aSize );
+
+ int GetNameTextSize() const { return m_nameTextSize; }
+
+ /**
+ * Set the pin number.
+ *
+ * Others pin numbers marked by EnableEditMode() are not modified
+ * because each pin has its own number
+ * @param aNumber New pin number.
+ */
+ void SetNumber( const wxString& aNumber );
+
+ /**
+ * Set the size of the pin number text.
+ *
+ * This will also update the text size of the number of the pins marked
+ * by EnableEditMode().
+ *
+ * @param aSize The text size of the pin number in schematic units ( mils ).
+ */
+ void SetNumberTextSize( int aSize );
+
+ int GetNumberTextSize() const { return m_numTextSize; }
+
+ int GetOrientation() const { return m_orientation; }
+
+ /**
+ * Set orientation on the pin.
+ *
+ * This will also update the orientation of the pins marked by EnableEditMode().
+ *
+ * @param aOrientation - The orientation of the pin.
+ */
+ void SetOrientation( int aOrientation );
+
+ void Rotate();
+
+ int GetShape() const { return m_shape; }
+
+ /**
+ * Set the shape of the pin to \a aShape.
+ *
+ * This will also update the draw style of the pins marked by EnableEditMode().
+ *
+ * @param aShape - The draw shape of the pin. See enum DrawPinShape.
+ */
+ void SetShape( int aShape );
+
+ /**
+ * Get the electrical type of the pin.
+ *
+ * @return The electrical type of the pin (see enun ElectricPinType for values).
+ */
+ int GetType() const { return m_type; }
+
+ /**
+ * return a string giving the electrical type of a pin.
+ * Can be used when a known, not translated name is needed (for instance in net lists)
+ * @param aType is the electrical type (see enum ElectricPinType )
+ * @return The electrical name for a pin type (see enun MsgPinElectricType for names).
+ */
+ static const wxString GetCanonicalElectricalTypeName( unsigned aType );
+
+ /**
+ * return a string giving the electrical type of the pin.
+ * Can be used when a known, not translated name is needed (for instance in net lists)
+ * @return The canonical electrical name of the pin.
+ */
+ wxString const GetCanonicalElectricalTypeName() const
+ {
+ return GetCanonicalElectricalTypeName( m_type );
+ }
+
+ /**
+ * return a translated string for messages giving the electrical type of a pin.
+ * @param aType is the electrical type (see enum ElectricPinType )
+ * @return The electrical name of the pin (see enun MsgPinElectricType for names).
+ */
+ static const wxString GetElectricalTypeName( unsigned aType );
+
+ /**
+ * return a translated string for messages giving the electrical type of the pin.
+ * @return The electrical name of the pin.
+ */
+ wxString const GetElectricalTypeName() const
+ {
+ return GetElectricalTypeName( m_type );
+ }
+
+ /**
+ * Set the electrical type of the pin.
+ *
+ * This will also update the electrical type of the pins marked by
+ * EnableEditMode().
+ *
+ * @param aType - The electrical type of the pin(see enun ElectricPinType for values).
+ */
+ void SetType( int aType );
+
+ /**
+ * Set the pin length.
+ *
+ * This will also update the length of the pins marked by EnableEditMode().
+ *
+ * @param aLength - The length of the pin in mils.
+ */
+ void SetLength( int aLength );
+
+ int GetLength() { return m_length; }
+
+ /**
+ * Set the pin part number.
+ *
+ * If the pin is changed from not common to common to all parts, any
+ * linked pins will be removed from the parent component.
+ *
+ * @param aPart - Number of the part the pin belongs to. Set to zero to
+ * make pin common to all parts in a multi-part component.
+ */
+ void SetPartNumber( int aPart );
+
+ /** Get the pin part number. */
+ int GetPartNumber() const { return m_Unit; }
+
+ /**
+ * Set the body style (conversion) of the pin.
+ *
+ * If the pin is changed from not common to common to all body styles, any
+ * linked pins will be removed from the parent component.
+ *
+ * @param aConversion - Body style of the pin. Set to zero to make pin
+ * common to all body styles.
+ */
+ void SetConversion( int aConversion );
+
+ /**
+ * Set or clear the visibility flag for the pin.
+ *
+ * This will also update the visibility of the pins marked by
+ * EnableEditMode().
+ *
+ * @param aVisible - True to make the pin visible or false to hide the pin.
+ */
+ void SetVisible( bool aVisible );
+
+ /**
+ * Enable or clear pin editing mode.
+ *
+ * The pin editing mode marks or unmarks all pins common to this
+ * pin object for further editing. If any of the pin modification
+ * methods are called after enabling the editing mode, all pins
+ * marked for editing will have the same attribute changed. The
+ * only case were this is not true making this pin common to all
+ * parts or body styles in the component. See SetCommonToAllParts()
+ * and SetCommonToAllBodyStyles() for more information.
+ *
+ * @param aEnable True marks all common pins for editing mode. False
+ * clears the editing mode.
+ * @param aEditPinByPin Enables the edit pin by pin mode.
+ */
+ void EnableEditMode( bool aEnable, bool aEditPinByPin = false );
+
+ /**
+ * Return the visibility status of the draw object.
+ *
+ * @return True if draw object is visible otherwise false.
+ */
+ bool IsVisible() const { return ( m_attributes & PIN_INVISIBLE ) == 0; }
+
+ /**
+ * Return whether this pin forms an implicit power connection: i.e., is hidden
+ * and of type POWER_IN.
+ */
+ bool IsPowerConnection() const { return !IsVisible() && GetType() == PIN_POWER_IN; }
+
+ int GetPenSize() const;
+
+ /**
+ * Function DrawPinSymbol
+ * Draw the pin symbol without text.
+ * If \a aColor != 0, draw with \a aColor, else with the normal pin color.
+ */
+ void DrawPinSymbol( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ int aOrientation, GR_DRAWMODE aDrawMode,
+ EDA_COLOR_T aColor = UNSPECIFIED_COLOR,
+ bool aDrawDangling = true,
+ bool aOnlyTarget = false );
+
+ /**
+ * Function DrawPinTexts
+ * puts the pin number and pin text info, given the pin line coordinates.
+ * The line must be vertical or horizontal.
+ * If DrawPinName == false the pin name is not printed.
+ * If DrawPinNum = false the pin number is not printed.
+ * If TextInside then the text is been put inside,otherwise all is drawn outside.
+ * Pin Name: substring between '~' is negated
+ * DrawMode = GR_OR, XOR ...
+ */
+ void DrawPinTexts( EDA_DRAW_PANEL* aPanel, wxDC* aDC, wxPoint& aPosition,
+ int aOrientation, int TextInside, bool DrawPinNum, bool DrawPinName,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode );
+
+ /**
+ * Function PlotPinTexts
+ * plots the pin number and pin text info, given the pin line coordinates.
+ * Same as DrawPinTexts((), but output is the plotter
+ * The line must be vertical or horizontal.
+ * If TextInside then the text is been put inside (moving from x1, y1 in
+ * the opposite direction to x2,y2), otherwise all is drawn outside.
+ */
+ void PlotPinTexts( PLOTTER *aPlotter,
+ wxPoint& aPosition,
+ int aOrientation,
+ int aTextInside,
+ bool aDrawPinNum,
+ bool aDrawPinName,
+ int aWidth );
+
+ void PlotSymbol( PLOTTER* aPlotter, const wxPoint& aPosition, int aOrientation );
+
+ /**
+ * Get a list of pin orientation names.
+ *
+ * @return List of valid pin orientation names.
+ */
+ static wxArrayString GetOrientationNames();
+
+ /**
+ * Get a list of pin orientation bitmaps for menus and dialogs.
+ *
+ * @return List of valid pin orientation bitmaps symbols in .xpm format
+ */
+ static const BITMAP_DEF* GetOrientationSymbols();
+
+ /**
+ * Get the orientation code by index used to set the pin orientation.
+ *
+ * @param aIndex - The index of the orientation code to look up.
+ * @return Orientation code if index is valid. Returns right
+ * orientation on index error.
+ */
+ static int GetOrientationCode( int aIndex );
+
+ /**
+ * Get the index of the orientation code.
+ *
+ * @param aCode - The orientation code to look up.
+ * @return The index of the orientation code if found. Otherwise,
+ * return wxNOT_FOUND.
+ */
+ static int GetOrientationCodeIndex( int aCode );
+
+ /**
+ * Get a list of pin draw style names.
+ *
+ * @return List of valid pin draw style names.
+ */
+ static wxArrayString GetStyleNames();
+
+ /**
+ * Get a list of pin styles bitmaps for menus and dialogs.
+ *
+ * @return List of valid pin electrical type bitmaps symbols in .xpm format.
+ */
+ static const BITMAP_DEF* GetStyleSymbols();
+
+ /**
+ * Get the pin draw style code by index used to set the pin draw style.
+ *
+ * @param aIndex - The index of the pin draw style code to look up.
+ * @return Pin draw style code if index is valid. Returns NONE
+ * style on index error.
+ */
+ static int GetStyleCode( int aIndex );
+
+ /**
+ * Get the index of the pin draw style code.
+ *
+ * @param aCode - The pin draw style code to look up.
+ * @return The index of the pin draw style code if found. Otherwise,
+ * return wxNOT_FOUND.
+ */
+ static int GetStyleCodeIndex( int aCode );
+
+ /**
+ * Get a list of pin electrical type names.
+ *
+ * @return List of valid pin electrical type names.
+ */
+ static wxArrayString GetElectricalTypeNames();
+
+ /**
+ * Get a list of pin electrical bitmaps for menus and dialogs.
+ *
+ * @return List of valid pin electrical type bitmaps symbols in .xpm format
+ */
+ static const BITMAP_DEF* GetElectricalTypeSymbols();
+
+ void SetOffset( const wxPoint& aOffset );
+
+ bool Inside( EDA_RECT& aRect ) const;
+
+ void Move( const wxPoint& aPosition );
+
+ wxPoint GetPosition() const { return m_position; }
+
+ void MirrorHorizontal( const wxPoint& aCenter );
+
+ void MirrorVertical( const wxPoint& aCenter );
+
+ void Rotate( const wxPoint& aCenter, bool aRotateCCW = true );
+
+ void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform );
+
+ int GetWidth() const { return m_width; }
+
+ void SetWidth( int aWidth );
+
+ BITMAP_DEF GetMenuImage() const;
+
+ wxString GetSelectMenuText() const;
+
+ EDA_ITEM* Clone() const;
+
+private:
+
+ /**
+ * @copydoc LIB_ITEM::compare()
+ *
+ * The pin specific sort order is as follows:
+ * - Pin number.
+ * - Pin name, case insensitive compare.
+ * - Pin horizontal (X) position.
+ * - Pin vertical (Y) position.
+ */
+ int compare( const LIB_ITEM& aOther ) const;
+};
+
+
+#endif // CLASS_PIN_H
diff --git a/eeschema/lib_polyline.cpp b/eeschema/lib_polyline.cpp
new file mode 100644
index 0000000..826adca
--- /dev/null
+++ b/eeschema/lib_polyline.cpp
@@ -0,0 +1,562 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_polyline.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <plot_common.h>
+#include <trigo.h>
+#include <wxstruct.h>
+#include <richio.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <lib_polyline.h>
+#include <transform.h>
+
+#include <boost/foreach.hpp>
+
+
+LIB_POLYLINE::LIB_POLYLINE( LIB_PART* aParent ) :
+ LIB_ITEM( LIB_POLYLINE_T, aParent )
+{
+ m_Fill = NO_FILL;
+ m_Width = 0;
+ m_isFillable = true;
+ m_typeName = _( "PolyLine" );
+ m_ModifyIndex = 0;
+}
+
+
+bool LIB_POLYLINE::Save( OUTPUTFORMATTER& aFormatter )
+{
+ int ccount = GetCornerCount();
+
+ aFormatter.Print( 0, "P %d %d %d %d", ccount, m_Unit, m_Convert, m_Width );
+
+ for( unsigned i = 0; i < GetCornerCount(); i++ )
+ {
+ aFormatter.Print( 0, " %d %d", m_PolyPoints[i].x, m_PolyPoints[i].y );
+ }
+
+ aFormatter.Print( 0, " %c\n", fill_tab[m_Fill] );
+
+ return true;
+}
+
+
+bool LIB_POLYLINE::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
+{
+ char* p;
+ int i, ccount = 0;
+ wxPoint pt;
+ char* line = (char*) aLineReader;
+
+ i = sscanf( line + 2, "%d %d %d %d", &ccount, &m_Unit, &m_Convert, &m_Width );
+
+ m_Fill = NO_FILL;
+
+ if( i < 4 )
+ {
+ aErrorMsg.Printf( _( "Polyline only had %d parameters of the required 4" ), i );
+ return false;
+ }
+
+ if( ccount <= 0 )
+ {
+ aErrorMsg.Printf( _( "Polyline count parameter %d is invalid" ), ccount );
+ return false;
+ }
+
+ strtok( line + 2, " \t\n" ); // Skip field
+ strtok( NULL, " \t\n" ); // Skip field
+ strtok( NULL, " \t\n" ); // Skip field
+ strtok( NULL, " \t\n" );
+
+ for( i = 0; i < ccount; i++ )
+ {
+ p = strtok( NULL, " \t\n" );
+
+ if( p == NULL || sscanf( p, "%d", &pt.x ) != 1 )
+ {
+ aErrorMsg.Printf( _( "Polyline point %d X position not defined" ), i );
+ return false;
+ }
+
+ p = strtok( NULL, " \t\n" );
+
+ if( p == NULL || sscanf( p, "%d", &pt.y ) != 1 )
+ {
+ aErrorMsg.Printf( _( "Polyline point %d Y position not defined" ), i );
+ return false;
+ }
+
+ AddPoint( pt );
+ }
+
+ if( ( p = strtok( NULL, " \t\n" ) ) != NULL )
+ {
+ if( p[0] == 'F' )
+ m_Fill = FILLED_SHAPE;
+
+ if( p[0] == 'f' )
+ m_Fill = FILLED_WITH_BG_BODYCOLOR;
+ }
+
+ return true;
+}
+
+
+EDA_ITEM* LIB_POLYLINE::Clone() const
+{
+ return new LIB_POLYLINE( *this );
+}
+
+
+int LIB_POLYLINE::compare( const LIB_ITEM& aOther ) const
+{
+ wxASSERT( aOther.Type() == LIB_POLYLINE_T );
+
+ const LIB_POLYLINE* tmp = (LIB_POLYLINE*) &aOther;
+
+ if( m_PolyPoints.size() != tmp->m_PolyPoints.size() )
+ return m_PolyPoints.size() - tmp->m_PolyPoints.size();
+
+ for( size_t i = 0; i < m_PolyPoints.size(); i++ )
+ {
+ if( m_PolyPoints[i].x != tmp->m_PolyPoints[i].x )
+ return m_PolyPoints[i].x - tmp->m_PolyPoints[i].x;
+
+ if( m_PolyPoints[i].y != tmp->m_PolyPoints[i].y )
+ return m_PolyPoints[i].y - tmp->m_PolyPoints[i].y;
+ }
+
+ return 0;
+}
+
+
+void LIB_POLYLINE::SetOffset( const wxPoint& aOffset )
+{
+ for( size_t i = 0; i < m_PolyPoints.size(); i++ )
+ m_PolyPoints[i] += aOffset;
+}
+
+
+bool LIB_POLYLINE::Inside( EDA_RECT& aRect ) const
+{
+ for( size_t i = 0; i < m_PolyPoints.size(); i++ )
+ {
+ if( aRect.Contains( m_PolyPoints[i].x, -m_PolyPoints[i].y ) )
+ return true;
+ }
+
+ return false;
+}
+
+
+void LIB_POLYLINE::Move( const wxPoint& aPosition )
+{
+ SetOffset( aPosition - m_PolyPoints[0] );
+}
+
+
+void LIB_POLYLINE::MirrorHorizontal( const wxPoint& aCenter )
+{
+ size_t i, imax = m_PolyPoints.size();
+
+ for( i = 0; i < imax; i++ )
+ {
+ m_PolyPoints[i].x -= aCenter.x;
+ m_PolyPoints[i].x *= -1;
+ m_PolyPoints[i].x += aCenter.x;
+ }
+}
+
+void LIB_POLYLINE::MirrorVertical( const wxPoint& aCenter )
+{
+ size_t i, imax = m_PolyPoints.size();
+
+ for( i = 0; i < imax; i++ )
+ {
+ m_PolyPoints[i].y -= aCenter.y;
+ m_PolyPoints[i].y *= -1;
+ m_PolyPoints[i].y += aCenter.y;
+ }
+}
+
+void LIB_POLYLINE::Rotate( const wxPoint& aCenter, bool aRotateCCW )
+{
+ int rot_angle = aRotateCCW ? -900 : 900;
+
+ size_t i, imax = m_PolyPoints.size();
+
+ for( i = 0; i < imax; i++ )
+ {
+ RotatePoint( &m_PolyPoints[i], aCenter, rot_angle );
+ }
+}
+
+
+void LIB_POLYLINE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform )
+{
+ wxASSERT( aPlotter != NULL );
+
+ static std::vector< wxPoint > cornerList;
+ cornerList.clear();
+
+ for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
+ {
+ wxPoint pos = m_PolyPoints[ii];
+ pos = aTransform.TransformCoordinate( pos ) + aOffset;
+ cornerList.push_back( pos );
+ }
+
+ if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
+ {
+ aPlotter->SetColor( GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
+ aPlotter->PlotPoly( cornerList, FILLED_WITH_BG_BODYCOLOR, 0 );
+ }
+
+ bool already_filled = m_Fill == FILLED_WITH_BG_BODYCOLOR;
+ aPlotter->SetColor( GetLayerColor( LAYER_DEVICE ) );
+ aPlotter->PlotPoly( cornerList, already_filled ? NO_FILL : m_Fill, GetPenSize() );
+}
+
+
+void LIB_POLYLINE::AddPoint( const wxPoint& point )
+{
+ m_PolyPoints.push_back( point );
+}
+
+
+int LIB_POLYLINE::GetPenSize() const
+{
+ return ( m_Width == 0 ) ? GetDefaultLineThickness() : m_Width;
+}
+
+
+void LIB_POLYLINE::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform )
+{
+ wxPoint pos1;
+ EDA_COLOR_T color = GetLayerColor( LAYER_DEVICE );
+ wxPoint* buffer = NULL;
+
+ if( aColor < 0 ) // Used normal color or selected color
+ {
+ if( IsSelected() )
+ color = GetItemSelectedColor();
+ }
+ else
+ {
+ color = aColor;
+ }
+
+ buffer = new wxPoint[ m_PolyPoints.size() ];
+
+ for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
+ {
+ buffer[ii] = aTransform.TransformCoordinate( m_PolyPoints[ii] ) + aOffset;
+ }
+
+ FILL_T fill = aData ? NO_FILL : m_Fill;
+
+ if( aColor >= 0 )
+ fill = NO_FILL;
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ EDA_RECT* const clipbox = aPanel? aPanel->GetClipBox() : NULL;
+ if( fill == FILLED_WITH_BG_BODYCOLOR )
+ GRPoly( clipbox, aDC, m_PolyPoints.size(), buffer, 1, GetPenSize(),
+ (m_Flags & IS_MOVED) ? color : GetLayerColor( LAYER_DEVICE_BACKGROUND ),
+ GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
+ else if( fill == FILLED_SHAPE )
+ GRPoly( clipbox, aDC, m_PolyPoints.size(), buffer, 1, GetPenSize(),
+ color, color );
+ else
+ GRPoly( clipbox, aDC, m_PolyPoints.size(), buffer, 0, GetPenSize(),
+ color, color );
+
+ delete[] buffer;
+
+ /* Set to one (1) to draw bounding box around polyline to validate
+ * bounding box calculation. */
+#if 0
+ EDA_RECT bBox = GetBoundingBox();
+ bBox.RevertYAxis();
+ bBox = aTransform.TransformCoordinate( bBox );
+ bBox.Move( aOffset );
+ GRRect( clipbox, aDC, bBox, 0, LIGHTMAGENTA );
+#endif
+}
+
+
+bool LIB_POLYLINE::HitTest( const wxPoint& aPosition ) const
+{
+ int mindist = GetPenSize() / 2;
+
+ // Have a minimal tolerance for hit test
+ if( mindist < MINIMUM_SELECTION_DISTANCE )
+ mindist = MINIMUM_SELECTION_DISTANCE;
+
+ return HitTest( aPosition, mindist, DefaultTransform );
+}
+
+
+bool LIB_POLYLINE::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
+{
+ wxPoint start, end;
+
+ if( aThreshold < 0 )
+ aThreshold = GetPenSize() / 2;
+
+ for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
+ {
+ start = aTransform.TransformCoordinate( m_PolyPoints[ii - 1] );
+ end = aTransform.TransformCoordinate( m_PolyPoints[ii] );
+
+ if( TestSegmentHit( aPosition, start, end, aThreshold ) )
+ return true;
+ }
+
+ return false;
+}
+
+
+const EDA_RECT LIB_POLYLINE::GetBoundingBox() const
+{
+ EDA_RECT rect;
+ int xmin, xmax, ymin, ymax;
+
+ xmin = xmax = m_PolyPoints[0].x;
+ ymin = ymax = m_PolyPoints[0].y;
+
+ for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
+ {
+ xmin = std::min( xmin, m_PolyPoints[ii].x );
+ xmax = std::max( xmax, m_PolyPoints[ii].x );
+ ymin = std::min( ymin, m_PolyPoints[ii].y );
+ ymax = std::max( ymax, m_PolyPoints[ii].y );
+ }
+
+ rect.SetOrigin( xmin, ymin );
+ rect.SetEnd( xmax, ymax );
+ rect.Inflate( ( GetPenSize()+1 ) / 2 );
+
+ rect.RevertYAxis();
+
+ return rect;
+}
+
+
+void LIB_POLYLINE::DeleteSegment( const wxPoint aPosition )
+{
+ // First segment is kept, only its end point is changed
+ while( GetCornerCount() > 2 )
+ {
+ m_PolyPoints.pop_back();
+
+ if( m_PolyPoints[ GetCornerCount() - 1 ] != aPosition )
+ {
+ m_PolyPoints[ GetCornerCount() - 1 ] = aPosition;
+ break;
+ }
+ }
+}
+
+
+void LIB_POLYLINE::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
+{
+ wxString msg;
+ EDA_RECT bBox = GetBoundingBox();
+
+ LIB_ITEM::GetMsgPanelInfo( aList );
+
+ msg = StringFromValue( g_UserUnit, m_Width, true );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Line Width" ), msg, BLUE ) );
+
+ msg.Printf( wxT( "(%d, %d, %d, %d)" ), bBox.GetOrigin().x,
+ bBox.GetOrigin().y, bBox.GetEnd().x, bBox.GetEnd().y );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Bounding Box" ), msg, BROWN ) );
+}
+
+
+wxString LIB_POLYLINE::GetSelectMenuText() const
+{
+ return wxString::Format( _( "Polyline at (%s, %s) with %d points" ),
+ GetChars( CoordinateToString( m_PolyPoints[0].x ) ),
+ GetChars( CoordinateToString( m_PolyPoints[0].y ) ),
+ int( m_PolyPoints.size() ) );
+}
+
+
+void LIB_POLYLINE::BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aPosition )
+{
+ wxCHECK_RET( ( aEditMode & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
+ wxT( "Invalid edit mode for LIB_POLYLINE object." ) );
+
+ if( aEditMode == IS_NEW )
+ {
+ m_PolyPoints.push_back( aPosition ); // Start point of first segment.
+ m_PolyPoints.push_back( aPosition ); // End point of first segment.
+ }
+ else if( aEditMode == IS_RESIZED )
+ {
+ // Drag one edge point of the polyline
+ // Find the nearest edge point to be dragged
+ wxPoint startPoint = m_PolyPoints[0];
+
+ // Begin with the first list point as nearest point
+ int index = 0;
+ m_ModifyIndex = 0;
+ m_initialPos = startPoint;
+
+ // First distance is the current minimum distance
+ int distanceMin = (aPosition - startPoint).x * (aPosition - startPoint).x
+ + (aPosition - startPoint).y * (aPosition - startPoint).y;
+
+ wxPoint prevPoint = startPoint;
+
+ // Find the right index of the point to be dragged
+ BOOST_FOREACH( wxPoint point, m_PolyPoints )
+ {
+ int distancePoint = (aPosition - point).x * (aPosition - point).x +
+ (aPosition - point).y * (aPosition - point).y;
+
+ if( distancePoint < distanceMin )
+ {
+ // Save point.
+ m_initialPos = point;
+ m_ModifyIndex = index;
+ distanceMin = distancePoint;
+ }
+
+ // check middle of an edge
+ wxPoint offset = ( aPosition + aPosition - point - prevPoint );
+ distancePoint = ( offset.x * offset.x + offset.y * offset.y ) / 4 + 1;
+
+ if( distancePoint < distanceMin )
+ {
+ // Save point.
+ m_initialPos = point;
+ m_ModifyIndex = -index; // negative indicates new vertex is to be inserted
+ distanceMin = distancePoint;
+ }
+
+ prevPoint = point;
+ index++;
+ }
+
+ SetEraseLastDrawItem();
+ }
+ else if( aEditMode == IS_MOVED )
+ {
+ m_initialCursorPos = aPosition;
+ m_initialPos = m_PolyPoints[0];
+ SetEraseLastDrawItem();
+ }
+
+ m_Flags = aEditMode;
+}
+
+
+bool LIB_POLYLINE::ContinueEdit( const wxPoint aPosition )
+{
+ wxCHECK_MSG( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0, false,
+ wxT( "Bad call to ContinueEdit(). LIB_POLYLINE is not being edited." ) );
+
+ if( m_Flags == IS_NEW )
+ {
+ // do not add zero length segments
+ if( m_PolyPoints[m_PolyPoints.size() - 2] != m_PolyPoints.back() )
+ m_PolyPoints.push_back( aPosition );
+
+ return true;
+ }
+
+ return false;
+}
+
+
+void LIB_POLYLINE::EndEdit( const wxPoint& aPosition, bool aAbort )
+{
+ wxCHECK_RET( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
+ wxT( "Bad call to EndEdit(). LIB_POLYLINE is not being edited." ) );
+
+ // do not include last point twice
+ if( m_Flags == IS_NEW && 2 < m_PolyPoints.size() )
+ {
+ if( m_PolyPoints[ m_PolyPoints.size() - 2 ] == m_PolyPoints.back() )
+ m_PolyPoints.pop_back();
+ }
+
+ if( (m_Flags == IS_RESIZED) && (m_PolyPoints.size() > 2) ) // do not delete last two points... keep it alive
+ {
+ if( ( m_ModifyIndex > 0 && m_PolyPoints[ m_ModifyIndex ] ==
+ m_PolyPoints[ m_ModifyIndex - 1 ] )
+ || ( m_ModifyIndex < (int) m_PolyPoints.size() - 1
+ && m_PolyPoints[ m_ModifyIndex ] == m_PolyPoints[ m_ModifyIndex + 1 ] ) )
+ {
+ m_PolyPoints.erase( m_PolyPoints.begin() + m_ModifyIndex ); // delete a point on this
+ }
+ }
+
+ m_Flags = 0;
+ SetEraseLastDrawItem( false );
+}
+
+
+void LIB_POLYLINE::calcEdit( const wxPoint& aPosition )
+{
+ if( m_Flags == IS_NEW )
+ {
+ m_PolyPoints[ GetCornerCount() - 1 ] = aPosition;
+ SetEraseLastDrawItem();
+ }
+ else if( m_Flags == IS_RESIZED )
+ {
+ if( m_ModifyIndex < 0 ) // negative indicates new vertex is to be inserted
+ {
+ m_ModifyIndex = -m_ModifyIndex;
+ m_PolyPoints.insert( m_PolyPoints.begin() + m_ModifyIndex, aPosition );
+ }
+
+ m_PolyPoints[ m_ModifyIndex ] = aPosition;
+ }
+ else if( m_Flags == IS_MOVED )
+ {
+ Move( m_initialPos + aPosition - m_initialCursorPos );
+ }
+}
diff --git a/eeschema/lib_polyline.h b/eeschema/lib_polyline.h
new file mode 100644
index 0000000..88e397f
--- /dev/null
+++ b/eeschema/lib_polyline.h
@@ -0,0 +1,133 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_polyline.h
+ */
+
+#ifndef _LIB_POLYLINE_H_
+#define _LIB_POLYLINE_H_
+
+#include <lib_draw_item.h>
+
+
+class LIB_POLYLINE : public LIB_ITEM
+{
+ int m_Width; // Line width
+ std::vector<wxPoint> m_PolyPoints; // list of points (>= 2)
+
+ int m_ModifyIndex; // Index of the polyline point to modify
+
+ void drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform );
+
+ void calcEdit( const wxPoint& aPosition );
+
+public:
+ LIB_POLYLINE( LIB_PART * aParent );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~LIB_POLYLINE() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "LIB_POLYLINE" );
+ }
+
+
+ bool Save( OUTPUTFORMATTER& aFormatter );
+
+ bool Load( LINE_READER& aLineReader, wxString& aErrorMsg );
+
+ void AddPoint( const wxPoint& aPoint );
+
+ /**
+ * Delete the segment at \a aPosition.
+ */
+ void DeleteSegment( const wxPoint aPosition );
+
+ /**
+ * @return the number of corners
+ */
+ unsigned GetCornerCount() const { return m_PolyPoints.size(); }
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const;
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ int GetPenSize( ) const;
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) );
+
+ bool ContinueEdit( const wxPoint aNextPoint );
+
+ void EndEdit( const wxPoint& aPosition, bool aAbort = false );
+
+ void SetOffset( const wxPoint& aOffset );
+
+ bool Inside( EDA_RECT& aRect ) const;
+
+ void Move( const wxPoint& aPosition );
+
+ wxPoint GetPosition() const { return m_PolyPoints[0]; }
+
+ void MirrorHorizontal( const wxPoint& aCenter );
+
+ void MirrorVertical( const wxPoint& aCenter );
+
+ void Rotate( const wxPoint& aCenter, bool aRotateCCW = true );
+
+ void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform );
+
+ int GetWidth() const { return m_Width; }
+
+ void SetWidth( int aWidth ) { m_Width = aWidth; }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_polygon_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+private:
+
+ /**
+ * @copydoc LIB_ITEM::compare()
+ *
+ * The sort order for specific to each polyline segment point is as follows:
+ * - Line segment point horizontal (X) position.
+ * - Line segment point vertical (Y) position.
+ */
+ int compare( const LIB_ITEM& aOther ) const;
+};
+
+
+#endif // _LIB_POLYLINE_H_
diff --git a/eeschema/lib_rectangle.cpp b/eeschema/lib_rectangle.cpp
new file mode 100644
index 0000000..74a1987
--- /dev/null
+++ b/eeschema/lib_rectangle.cpp
@@ -0,0 +1,434 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_rectangle.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <plot_common.h>
+#include <trigo.h>
+#include <wxstruct.h>
+#include <richio.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <lib_rectangle.h>
+#include <transform.h>
+
+
+LIB_RECTANGLE::LIB_RECTANGLE( LIB_PART* aParent ) :
+ LIB_ITEM( LIB_RECTANGLE_T, aParent )
+{
+ m_Width = 0;
+ m_Fill = NO_FILL;
+ m_isFillable = true;
+ m_typeName = _( "Rectangle" );
+ m_isHeightLocked = false;
+ m_isWidthLocked = false;
+ m_isStartPointSelected = false;
+}
+
+
+bool LIB_RECTANGLE::Save( OUTPUTFORMATTER& aFormatter )
+{
+ aFormatter.Print( 0, "S %d %d %d %d %d %d %d %c\n", m_Pos.x, m_Pos.y,
+ m_End.x, m_End.y, m_Unit, m_Convert, m_Width, fill_tab[m_Fill] );
+
+ return true;
+}
+
+
+bool LIB_RECTANGLE::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
+{
+ int cnt;
+ char tmp[256] = "";
+ char* line = (char*)aLineReader;
+
+ cnt = sscanf( line + 2, "%d %d %d %d %d %d %d %255s", &m_Pos.x, &m_Pos.y,
+ &m_End.x, &m_End.y, &m_Unit, &m_Convert, &m_Width, tmp );
+
+ if( cnt < 7 )
+ {
+ aErrorMsg.Printf( _( "Rectangle only had %d parameters of the required 7" ), cnt );
+ return false;
+ }
+
+ if( tmp[0] == 'F' )
+ m_Fill = FILLED_SHAPE;
+
+ if( tmp[0] == 'f' )
+ m_Fill = FILLED_WITH_BG_BODYCOLOR;
+
+ return true;
+}
+
+
+EDA_ITEM* LIB_RECTANGLE::Clone() const
+{
+ return new LIB_RECTANGLE( *this );
+}
+
+
+int LIB_RECTANGLE::compare( const LIB_ITEM& aOther ) const
+{
+ wxASSERT( aOther.Type() == LIB_RECTANGLE_T );
+
+ const LIB_RECTANGLE* tmp = ( LIB_RECTANGLE* ) &aOther;
+
+ if( m_Pos.x != tmp->m_Pos.x )
+ return m_Pos.x - tmp->m_Pos.x;
+
+ if( m_Pos.y != tmp->m_Pos.y )
+ return m_Pos.y - tmp->m_Pos.y;
+
+ if( m_End.x != tmp->m_End.x )
+ return m_End.x - tmp->m_End.x;
+
+ if( m_End.y != tmp->m_End.y )
+ return m_End.y - tmp->m_End.y;
+
+ return 0;
+}
+
+
+void LIB_RECTANGLE::SetOffset( const wxPoint& aOffset )
+{
+ m_Pos += aOffset;
+ m_End += aOffset;
+}
+
+
+bool LIB_RECTANGLE::Inside( EDA_RECT& aRect ) const
+{
+ return aRect.Contains( m_Pos.x, -m_Pos.y ) || aRect.Contains( m_End.x, -m_End.y );
+}
+
+
+void LIB_RECTANGLE::Move( const wxPoint& aPosition )
+{
+ wxPoint size = m_End - m_Pos;
+ m_Pos = aPosition;
+ m_End = aPosition + size;
+}
+
+
+void LIB_RECTANGLE::MirrorHorizontal( const wxPoint& aCenter )
+{
+ m_Pos.x -= aCenter.x;
+ m_Pos.x *= -1;
+ m_Pos.x += aCenter.x;
+ m_End.x -= aCenter.x;
+ m_End.x *= -1;
+ m_End.x += aCenter.x;
+}
+
+
+void LIB_RECTANGLE::MirrorVertical( const wxPoint& aCenter )
+{
+ m_Pos.y -= aCenter.y;
+ m_Pos.y *= -1;
+ m_Pos.y += aCenter.y;
+ m_End.y -= aCenter.y;
+ m_End.y *= -1;
+ m_End.y += aCenter.y;
+}
+
+
+void LIB_RECTANGLE::Rotate( const wxPoint& aCenter, bool aRotateCCW )
+{
+ int rot_angle = aRotateCCW ? -900 : 900;
+ RotatePoint( &m_Pos, aCenter, rot_angle );
+ RotatePoint( &m_End, aCenter, rot_angle );
+}
+
+
+void LIB_RECTANGLE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform )
+{
+ wxASSERT( aPlotter != NULL );
+
+ wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
+ wxPoint end = aTransform.TransformCoordinate( m_End ) + aOffset;
+
+ if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
+ {
+ aPlotter->SetColor( GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
+ aPlotter->Rect( pos, end, FILLED_WITH_BG_BODYCOLOR, 0 );
+ }
+
+ bool already_filled = m_Fill == FILLED_WITH_BG_BODYCOLOR;
+ aPlotter->SetColor( GetLayerColor( LAYER_DEVICE ) );
+ aPlotter->Rect( pos, end, already_filled ? NO_FILL : m_Fill, GetPenSize() );
+}
+
+
+int LIB_RECTANGLE::GetPenSize() const
+{
+ return ( m_Width == 0 ) ? GetDefaultLineThickness() : m_Width;
+}
+
+
+void LIB_RECTANGLE::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aOffset, EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode,
+ void* aData, const TRANSFORM& aTransform )
+{
+ wxPoint pos1, pos2;
+
+ EDA_COLOR_T color = GetLayerColor( LAYER_DEVICE );
+
+ if( aColor < 0 ) // Used normal color or selected color
+ {
+ if( IsSelected() )
+ color = GetItemSelectedColor();
+ }
+ else
+ {
+ color = aColor;
+ }
+
+ pos1 = aTransform.TransformCoordinate( m_Pos ) + aOffset;
+ pos2 = aTransform.TransformCoordinate( m_End ) + aOffset;
+
+ FILL_T fill = aData ? NO_FILL : m_Fill;
+
+ if( aColor >= 0 )
+ fill = NO_FILL;
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ EDA_RECT* const clipbox = aPanel? aPanel->GetClipBox() : NULL;
+ if( fill == FILLED_WITH_BG_BODYCOLOR && !aData )
+ GRFilledRect( clipbox, aDC, pos1.x, pos1.y, pos2.x, pos2.y, GetPenSize( ),
+ (m_Flags & IS_MOVED) ? color : GetLayerColor( LAYER_DEVICE_BACKGROUND ),
+ GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
+ else if( m_Fill == FILLED_SHAPE && !aData )
+ GRFilledRect( clipbox, aDC, pos1.x, pos1.y, pos2.x, pos2.y,
+ GetPenSize(), color, color );
+ else
+ GRRect( clipbox, aDC, pos1.x, pos1.y, pos2.x, pos2.y, GetPenSize(), color );
+
+ /* Set to one (1) to draw bounding box around rectangle to validate
+ * bounding box calculation. */
+#if 0
+ EDA_RECT bBox = GetBoundingBox();
+ bBox.RevertYAxis();
+ bBox = aTransform.TransformCoordinate( bBox );
+ bBox.Move( aOffset );
+ GRRect( clipbox, aDC, bBox, 0, LIGHTMAGENTA );
+#endif
+}
+
+
+void LIB_RECTANGLE::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
+{
+ wxString msg;
+
+ LIB_ITEM::GetMsgPanelInfo( aList );
+
+ msg = StringFromValue( g_UserUnit, m_Width, true );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Line Width" ), msg, BLUE ) );
+}
+
+
+const EDA_RECT LIB_RECTANGLE::GetBoundingBox() const
+{
+ EDA_RECT rect;
+
+ rect.SetOrigin( m_Pos );
+ rect.SetEnd( m_End );
+ rect.Inflate( ( GetPenSize()+1 ) / 2 );
+
+ rect.RevertYAxis();
+
+ return rect;
+}
+
+
+bool LIB_RECTANGLE::HitTest( const wxPoint& aPosition ) const
+{
+ int mindist = ( GetPenSize() / 2 ) + 1;
+
+ // Have a minimal tolerance for hit test
+ if( mindist < MINIMUM_SELECTION_DISTANCE )
+ mindist = MINIMUM_SELECTION_DISTANCE;
+
+ return HitTest( aPosition, mindist, DefaultTransform );
+}
+
+
+bool LIB_RECTANGLE::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
+{
+ if( aThreshold < 0 )
+ aThreshold = GetPenSize() / 2;
+
+ wxPoint actualStart = aTransform.TransformCoordinate( m_Pos );
+ wxPoint actualEnd = aTransform.TransformCoordinate( m_End );
+
+ // locate lower segment
+ wxPoint start, end;
+
+ start = actualStart;
+ end.x = actualEnd.x;
+ end.y = actualStart.y;
+
+ if( TestSegmentHit( aPosition, start, end, aThreshold ) )
+ return true;
+
+ // locate right segment
+ start.x = actualEnd.x;
+ end.y = actualEnd.y;
+
+ if( TestSegmentHit( aPosition, start, end, aThreshold ) )
+ return true;
+
+ // locate upper segment
+ start.y = actualEnd.y;
+ end.x = actualStart.x;
+
+ if( TestSegmentHit( aPosition, start, end, aThreshold ) )
+ return true;
+
+ // locate left segment
+ start = actualStart;
+ end.x = actualStart.x;
+ end.y = actualEnd.y;
+
+ if( TestSegmentHit( aPosition, start, end, aThreshold ) )
+ return true;
+
+ return false;
+}
+
+
+wxString LIB_RECTANGLE::GetSelectMenuText() const
+{
+ return wxString::Format( _( "Rectangle from (%s, %s) to (%s, %s)" ),
+ GetChars( CoordinateToString( m_Pos.x ) ),
+ GetChars( CoordinateToString( m_Pos.y ) ),
+ GetChars( CoordinateToString( m_End.x ) ),
+ GetChars( CoordinateToString( m_End.y ) ) );
+}
+
+
+void LIB_RECTANGLE::BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aPosition )
+{
+ wxCHECK_RET( ( aEditMode & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
+ wxT( "Invalid edit mode for LIB_RECTANGLE object." ) );
+
+ if( aEditMode == IS_NEW )
+ {
+ m_Pos = m_End = aPosition;
+ }
+ else if( aEditMode == IS_RESIZED )
+ {
+ m_isStartPointSelected = abs( m_Pos.x - aPosition.x ) < MINIMUM_SELECTION_DISTANCE
+ || abs( m_Pos.y - aPosition.y ) < MINIMUM_SELECTION_DISTANCE;
+
+ if( m_isStartPointSelected )
+ {
+ m_isWidthLocked = abs( m_Pos.x - aPosition.x ) >= MINIMUM_SELECTION_DISTANCE;
+ m_isHeightLocked = abs( m_Pos.y - aPosition.y ) >= MINIMUM_SELECTION_DISTANCE;
+ }
+ else
+ {
+ m_isWidthLocked = abs( m_End.x - aPosition.x ) >= MINIMUM_SELECTION_DISTANCE;
+ m_isHeightLocked = abs( m_End.y - aPosition.y ) >= MINIMUM_SELECTION_DISTANCE;
+ }
+
+ SetEraseLastDrawItem();
+ }
+ else if( aEditMode == IS_MOVED )
+ {
+ m_initialPos = m_Pos;
+ m_initialCursorPos = aPosition;
+ SetEraseLastDrawItem();
+ }
+
+ m_Flags = aEditMode;
+}
+
+
+bool LIB_RECTANGLE::ContinueEdit( const wxPoint aPosition )
+{
+ wxCHECK_MSG( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0, false,
+ wxT( "Bad call to ContinueEdit(). LIB_RECTANGLE is not being edited." ) );
+
+ return false;
+}
+
+
+void LIB_RECTANGLE::EndEdit( const wxPoint& aPosition, bool aAbort )
+{
+ wxCHECK_RET( ( m_Flags & ( IS_NEW | IS_MOVED | IS_RESIZED ) ) != 0,
+ wxT( "Bad call to EndEdit(). LIB_RECTANGLE is not being edited." ) );
+
+ m_Flags = 0;
+ m_isHeightLocked = false;
+ m_isWidthLocked = false;
+ SetEraseLastDrawItem( false );
+}
+
+
+void LIB_RECTANGLE::calcEdit( const wxPoint& aPosition )
+{
+ if( m_Flags == IS_NEW )
+ {
+ m_End = aPosition;
+ SetEraseLastDrawItem();
+ }
+ else if( m_Flags == IS_RESIZED )
+ {
+ if( m_isHeightLocked )
+ {
+ if( m_isStartPointSelected )
+ m_Pos.x = aPosition.x;
+ else
+ m_End.x = aPosition.x;
+ }
+ else if( m_isWidthLocked )
+ {
+ if( m_isStartPointSelected )
+ m_Pos.y = aPosition.y;
+ else
+ m_End.y = aPosition.y;
+ }
+ else
+ {
+ if( m_isStartPointSelected )
+ m_Pos = aPosition;
+ else
+ m_End = aPosition;
+ }
+ }
+ else if( m_Flags == IS_MOVED )
+ {
+ Move( m_initialPos + aPosition - m_initialCursorPos );
+ }
+}
diff --git a/eeschema/lib_rectangle.h b/eeschema/lib_rectangle.h
new file mode 100644
index 0000000..6df93c9
--- /dev/null
+++ b/eeschema/lib_rectangle.h
@@ -0,0 +1,126 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_rectangle.h
+ */
+
+#ifndef _LIB_RECTANGLE_H_
+#define _LIB_RECTANGLE_H_
+
+#include <lib_draw_item.h>
+
+
+class LIB_RECTANGLE : public LIB_ITEM
+{
+ wxPoint m_End; // Rectangle end point.
+ wxPoint m_Pos; // Rectangle start point.
+ int m_Width; // Line width
+ bool m_isWidthLocked; // Flag: Keep width locked
+ bool m_isHeightLocked; // Flag: Keep height locked
+ bool m_isStartPointSelected; // Flag: is the upper left edge selected?
+
+ void drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform );
+
+ void calcEdit( const wxPoint& aPosition );
+
+public:
+ LIB_RECTANGLE( LIB_PART * aParent );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~LIB_RECTANGLE() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "LIB_RECTANGLE" );
+ }
+
+ void SetEndPosition( const wxPoint& aPosition ) { m_End = aPosition; }
+
+ bool Save( OUTPUTFORMATTER& aFormatter );
+
+ bool Load( LINE_READER& aLineReader, wxString& aErrorMsg );
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ bool HitTest( const wxPoint &aPosRef, int aThreshold, const TRANSFORM& aTransform ) const;
+
+ int GetPenSize( ) const;
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) );
+
+ bool ContinueEdit( const wxPoint aNextPoint );
+
+ void EndEdit( const wxPoint& aPosition, bool aAbort = false );
+
+ void SetOffset( const wxPoint& aOffset );
+
+ bool Inside( EDA_RECT& aRect ) const;
+
+ void Move( const wxPoint& aPosition );
+
+ wxPoint GetPosition() const { return m_Pos; }
+
+ void MirrorHorizontal( const wxPoint& aCenter );
+
+ void MirrorVertical( const wxPoint& aCenter );
+
+ void Rotate( const wxPoint& aCenter, bool aRotateCCW = true );
+
+ void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform );
+
+ int GetWidth() const { return m_Width; }
+
+ void SetWidth( int aWidth ) { m_Width = aWidth; }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_rectangle_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+private:
+
+ /**
+ * @copydoc LIB_ITEM::compare()
+ *
+ * The rectangle specific sort order is as follows:
+ * - Rectangle horizontal (X) start position.
+ * - Rectangle vertical (Y) start position.
+ * - Rectangle horizontal (X) end position.
+ * - Rectangle vertical (Y) end position.
+ */
+ int compare( const LIB_ITEM& aOther ) const;
+};
+
+
+#endif // _LIB_RECTANGLE_H_
diff --git a/eeschema/lib_text.cpp b/eeschema/lib_text.cpp
new file mode 100644
index 0000000..be8ad78
--- /dev/null
+++ b/eeschema/lib_text.cpp
@@ -0,0 +1,559 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_text.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <plot_common.h>
+#include <drawtxt.h>
+#include <trigo.h>
+#include <wxstruct.h>
+#include <richio.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+#include <lib_draw_item.h>
+#include <general.h>
+#include <transform.h>
+#include <lib_text.h>
+
+
+LIB_TEXT::LIB_TEXT( LIB_PART * aParent ) :
+ LIB_ITEM( LIB_TEXT_T, aParent ),
+ EDA_TEXT()
+{
+ m_Size = wxSize( 50, 50 );
+ m_typeName = _( "Text" );
+ m_rotate = false;
+ m_updateText = false;
+}
+
+
+bool LIB_TEXT::Save( OUTPUTFORMATTER& aFormatter )
+{
+ wxString text = m_Text;
+
+ if( text.Contains( wxT( "~" ) ) || text.Contains( wxT( "\"" ) ) )
+ {
+ // convert double quote to similar-looking two apostrophes
+ text.Replace( wxT( "\"" ), wxT( "''" ) );
+ text = wxT( "\"" ) + text + wxT( "\"" );
+ }
+ else
+ {
+ // Spaces are not allowed in text because it is not double quoted:
+ // changed to '~'
+ text.Replace( wxT( " " ), wxT( "~" ) );
+ }
+
+ aFormatter.Print( 0, "T %g %d %d %d %d %d %d %s", GetOrientation(), m_Pos.x, m_Pos.y,
+ m_Size.x, m_Attributs, m_Unit, m_Convert, TO_UTF8( text ) );
+
+ aFormatter.Print( 0, " %s %d", m_Italic ? "Italic" : "Normal", ( m_Bold > 0 ) ? 1 : 0 );
+
+ char hjustify = 'C';
+
+ if( m_HJustify == GR_TEXT_HJUSTIFY_LEFT )
+ hjustify = 'L';
+ else if( m_HJustify == GR_TEXT_HJUSTIFY_RIGHT )
+ hjustify = 'R';
+
+ char vjustify = 'C';
+
+ if( m_VJustify == GR_TEXT_VJUSTIFY_BOTTOM )
+ vjustify = 'B';
+ else if( m_VJustify == GR_TEXT_VJUSTIFY_TOP )
+ vjustify = 'T';
+
+ aFormatter.Print( 0, " %c %c\n", hjustify, vjustify );
+
+ return true;
+}
+
+
+bool LIB_TEXT::Load( LINE_READER& aLineReader, wxString& errorMsg )
+{
+ int cnt, thickness = 0;
+ char hjustify = 'C', vjustify = 'C';
+ char buf[256];
+ char tmp[256];
+ char* line = (char*) aLineReader;
+ double angle;
+
+ buf[0] = 0;
+ tmp[0] = 0; // For italic option, Not in old versions
+
+ cnt = sscanf( line + 2, "%lf %d %d %d %d %d %d \"%[^\"]\" %255s %d %c %c",
+ &angle, &m_Pos.x, &m_Pos.y, &m_Size.x, &m_Attributs,
+ &m_Unit, &m_Convert, buf, tmp, &thickness, &hjustify,
+ &vjustify );
+
+ if( cnt >= 8 ) // if quoted loading failed, load as not quoted
+ {
+ m_Text = FROM_UTF8( buf );
+
+ // convert two apostrophes back to double quote
+ m_Text.Replace( wxT( "''" ), wxT( "\"" ) );
+ }
+ else
+ {
+ cnt = sscanf( line + 2, "%lf %d %d %d %d %d %d %255s %255s %d %c %c",
+ &angle, &m_Pos.x, &m_Pos.y, &m_Size.x, &m_Attributs,
+ &m_Unit, &m_Convert, buf, tmp, &thickness, &hjustify,
+ &vjustify );
+
+ if( cnt < 8 )
+ {
+ errorMsg.Printf( _( "Text only had %d parameters of the required 8" ), cnt );
+ return false;
+ }
+
+ /* Convert '~' to spaces (only if text is not quoted). */
+ m_Text = FROM_UTF8( buf );
+ m_Text.Replace( wxT( "~" ), wxT( " " ) );
+ }
+
+ SetOrientation( angle );
+
+ m_Size.y = m_Size.x;
+
+ if( strnicmp( tmp, "Italic", 6 ) == 0 )
+ m_Italic = true;
+
+ if( thickness > 0 )
+ {
+ m_Bold = true;
+ }
+
+ switch( hjustify )
+ {
+ case 'L':
+ m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
+ break;
+
+ case 'C':
+ m_HJustify = GR_TEXT_HJUSTIFY_CENTER;
+ break;
+
+ case 'R':
+ m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
+ break;
+ }
+
+ switch( vjustify )
+ {
+ case 'T':
+ m_VJustify = GR_TEXT_VJUSTIFY_TOP;
+ break;
+
+ case 'C':
+ m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
+ break;
+
+ case 'B':
+ m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
+ break;
+ }
+
+
+ return true;
+}
+
+
+bool LIB_TEXT::HitTest( const wxPoint& aPosition ) const
+{
+ return HitTest( aPosition, 0, DefaultTransform );
+}
+
+
+bool LIB_TEXT::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
+{
+ if( aThreshold < 0 )
+ aThreshold = 0;
+
+ EDA_TEXT tmp_text( *this );
+ tmp_text.SetTextPosition( aTransform.TransformCoordinate( m_Pos ) );
+
+ /* The text orientation may need to be flipped if the
+ * transformation matrix causes xy axes to be flipped.
+ * this simple algo works only for schematic matrix (rot 90 or/and mirror)
+ */
+ int t1 = ( aTransform.x1 != 0 ) ^ ( m_Orient != 0 );
+ tmp_text.SetOrientation( t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT );
+ return tmp_text.TextHitTest( aPosition );
+}
+
+
+EDA_ITEM* LIB_TEXT::Clone() const
+{
+ LIB_TEXT* newitem = new LIB_TEXT(NULL);
+
+ newitem->m_Pos = m_Pos;
+ newitem->m_Orient = m_Orient;
+ newitem->m_Size = m_Size;
+ newitem->m_Attributs = m_Attributs;
+ newitem->m_Unit = m_Unit;
+ newitem->m_Convert = m_Convert;
+ newitem->m_Flags = m_Flags;
+ newitem->m_Text = m_Text;
+ newitem->m_Thickness = m_Thickness;
+ newitem->m_Italic = m_Italic;
+ newitem->m_Bold = m_Bold;
+ newitem->m_HJustify = m_HJustify;
+ newitem->m_VJustify = m_VJustify;
+ return newitem;
+}
+
+
+int LIB_TEXT::compare( const LIB_ITEM& other ) const
+{
+ wxASSERT( other.Type() == LIB_TEXT_T );
+
+ const LIB_TEXT* tmp = ( LIB_TEXT* ) &other;
+
+ int result = m_Text.CmpNoCase( tmp->m_Text );
+
+ if( result != 0 )
+ return result;
+
+ if( m_Pos.x != tmp->m_Pos.x )
+ return m_Pos.x - tmp->m_Pos.x;
+
+ if( m_Pos.y != tmp->m_Pos.y )
+ return m_Pos.y - tmp->m_Pos.y;
+
+ if( m_Size.x != tmp->m_Size.x )
+ return m_Size.x - tmp->m_Size.x;
+
+ if( m_Size.y != tmp->m_Size.y )
+ return m_Size.y - tmp->m_Size.y;
+
+ return 0;
+}
+
+
+void LIB_TEXT::SetOffset( const wxPoint& aOffset )
+{
+ m_Pos += aOffset;
+}
+
+
+bool LIB_TEXT::Inside( EDA_RECT& rect ) const
+{
+ /*
+ * FIXME: This should calculate the text size and justification and
+ * use rectangle intersect.
+ */
+ return rect.Contains( m_Pos.x, -m_Pos.y );
+}
+
+
+void LIB_TEXT::Move( const wxPoint& newPosition )
+{
+ m_Pos = newPosition;
+}
+
+
+void LIB_TEXT::MirrorHorizontal( const wxPoint& center )
+{
+ m_Pos.x -= center.x;
+ m_Pos.x *= -1;
+ m_Pos.x += center.x;
+}
+
+void LIB_TEXT::MirrorVertical( const wxPoint& center )
+{
+ m_Pos.y -= center.y;
+ m_Pos.y *= -1;
+ m_Pos.y += center.y;
+}
+
+void LIB_TEXT::Rotate( const wxPoint& center, bool aRotateCCW )
+{
+ int rot_angle = aRotateCCW ? -900 : 900;
+
+ RotatePoint( &m_Pos, center, rot_angle );
+ m_Orient = m_Orient ? 0 : 900;
+}
+
+
+void LIB_TEXT::Plot( PLOTTER* plotter, const wxPoint& offset, bool fill,
+ const TRANSFORM& aTransform )
+{
+ wxASSERT( plotter != NULL );
+
+ EDA_RECT bBox = GetBoundingBox();
+ // convert coordinates from draw Y axis to libedit Y axis
+ bBox.RevertYAxis();
+ wxPoint txtpos = bBox.Centre();
+
+ /* The text orientation may need to be flipped if the
+ * transformation matrix causes xy axes to be flipped. */
+ int t1 = ( aTransform.x1 != 0 ) ^ ( m_Orient != 0 );
+ wxPoint pos = aTransform.TransformCoordinate( txtpos ) + offset;
+
+ // Get color
+ EDA_COLOR_T color;
+
+ if( plotter->GetColorMode() ) // Used normal color or selected color
+ color = IsSelected() ? GetItemSelectedColor() : GetDefaultColor();
+ else
+ color = BLACK;
+
+ plotter->Text( pos, color, GetShownText(),
+ t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT,
+ m_Size, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
+ GetPenSize(), m_Italic, m_Bold );
+}
+
+
+int LIB_TEXT::GetPenSize() const
+{
+ int pensize = m_Thickness;
+
+ if( pensize == 0 ) // Use default values for pen size
+ {
+ if( m_Bold )
+ pensize = GetPenSizeForBold( m_Size.x );
+ else
+ pensize = GetDefaultLineThickness();
+ }
+
+ // Clip pen size for small texts:
+ pensize = Clamp_Text_PenSize( pensize, m_Size, m_Bold );
+ return pensize;
+}
+
+
+void LIB_TEXT::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform )
+{
+ EDA_COLOR_T color = GetDefaultColor();
+
+ if( aColor < 0 ) // Used normal color or selected color
+ {
+ if( IsSelected() )
+ color = GetItemSelectedColor();
+ }
+ else
+ {
+ color = aColor;
+ }
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ /* Calculate the text orientation, according to the component
+ * orientation/mirror (needed when draw text in schematic)
+ */
+ int orient = m_Orient;
+
+ if( aTransform.y1 ) // Rotate component 90 degrees.
+ {
+ if( orient == TEXT_ORIENT_HORIZ )
+ orient = TEXT_ORIENT_VERT;
+ else
+ orient = TEXT_ORIENT_HORIZ;
+ }
+
+ /* Calculate the text justification, according to the component
+ * orientation/mirror this is a bit complicated due to cumulative
+ * calculations:
+ * - numerous cases (mirrored or not, rotation)
+ * - the DrawGraphicText function recalculate also H and H justifications
+ * according to the text orientation.
+ * - When a component is mirrored, the text is not mirrored and
+ * justifications are complicated to calculate
+ * so the more easily way is to use no justifications ( Centered text )
+ * and use GetBoundaryBox to know the text coordinate considered as centered
+ */
+ EDA_RECT bBox = GetBoundingBox();
+ // convert coordinates from draw Y axis to libedit Y axis:
+ bBox.RevertYAxis();
+ wxPoint txtpos = bBox.Centre();
+
+ // Calculate pos according to mirror/rotation.
+ txtpos = aTransform.TransformCoordinate( txtpos ) + aOffset;
+
+ EDA_RECT* clipbox = aPanel? aPanel->GetClipBox() : NULL;
+ DrawGraphicText( clipbox, aDC, txtpos, color, GetShownText(), orient, m_Size,
+ GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, GetPenSize(),
+ m_Italic, m_Bold );
+
+
+ /* Enable this to draw the bounding box around the text field to validate
+ * the bounding box calculations.
+ */
+#if 0
+ // bBox already uses libedit Y axis.
+ bBox = aTransform.TransformCoordinate( bBox );
+ bBox.Move( aOffset );
+ GRRect( clipbox, aDC, bBox, 0, LIGHTMAGENTA );
+#endif
+}
+
+
+void LIB_TEXT::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
+{
+ wxString msg;
+
+ LIB_ITEM::GetMsgPanelInfo( aList );
+
+ msg = StringFromValue( g_UserUnit, m_Thickness, true );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Line Width" ), msg, BLUE ) );
+}
+
+
+const EDA_RECT LIB_TEXT::GetBoundingBox() const
+{
+ /* Y coordinates for LIB_ITEMS are bottom to top, so we must invert the Y position when
+ * calling GetTextBox() that works using top to bottom Y axis orientation.
+ */
+ EDA_RECT rect = GetTextBox( -1, -1, true );
+ rect.RevertYAxis();
+
+ // We are using now a bottom to top Y axis.
+ wxPoint orig = rect.GetOrigin();
+ wxPoint end = rect.GetEnd();
+ RotatePoint( &orig, m_Pos, -m_Orient );
+ RotatePoint( &end, m_Pos, -m_Orient );
+
+ rect.SetOrigin( orig );
+ rect.SetEnd( end );
+
+ // We are using now a top to bottom Y axis:
+ rect.RevertYAxis();
+
+ return rect;
+}
+
+
+void LIB_TEXT::Rotate()
+{
+ if( InEditMode() )
+ {
+ m_rotate = true;
+ }
+ else
+ {
+ m_Orient = ( m_Orient == TEXT_ORIENT_VERT ) ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT;
+ }
+}
+
+
+void LIB_TEXT::SetText( const wxString& aText )
+{
+ if( aText == m_Text )
+ return;
+
+ if( InEditMode() )
+ {
+ m_savedText = aText;
+ m_updateText = true;
+ }
+ else
+ {
+ m_Text = aText;
+ }
+}
+
+
+wxString LIB_TEXT::GetSelectMenuText() const
+{
+ wxString msg;
+ msg.Printf( _( "Graphic Text %s" ), GetChars( ShortenedShownText() ) );
+ return msg;
+}
+
+
+void LIB_TEXT::BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aPosition )
+{
+ wxCHECK_RET( ( aEditMode & ( IS_NEW | IS_MOVED ) ) != 0,
+ wxT( "Invalid edit mode for LIB_TEXT object." ) );
+
+ if( aEditMode == IS_MOVED )
+ {
+ m_initialPos = m_Pos;
+ m_initialCursorPos = aPosition;
+ SetEraseLastDrawItem();
+ }
+ else
+ {
+ m_Pos = aPosition;
+ }
+
+ m_Flags = aEditMode;
+}
+
+
+bool LIB_TEXT::ContinueEdit( const wxPoint aPosition )
+{
+ wxCHECK_MSG( ( m_Flags & ( IS_NEW | IS_MOVED ) ) != 0, false,
+ wxT( "Bad call to ContinueEdit(). Text is not being edited." ) );
+
+ return false;
+}
+
+
+void LIB_TEXT::EndEdit( const wxPoint& aPosition, bool aAbort )
+{
+ wxCHECK_RET( ( m_Flags & ( IS_NEW | IS_MOVED ) ) != 0,
+ wxT( "Bad call to EndEdit(). Text is not being edited." ) );
+
+ m_Flags = 0;
+ m_rotate = false;
+ m_updateText = false;
+ SetEraseLastDrawItem( false );
+}
+
+
+void LIB_TEXT::calcEdit( const wxPoint& aPosition )
+{
+ if( m_rotate )
+ {
+ m_Orient = ( m_Orient == TEXT_ORIENT_VERT ) ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT;
+ m_rotate = false;
+ }
+
+ if( m_updateText )
+ {
+ std::swap( m_Text, m_savedText );
+ m_updateText = false;
+ }
+
+ if( m_Flags == IS_NEW )
+ {
+ SetEraseLastDrawItem();
+ m_Pos = aPosition;
+ }
+ else if( m_Flags == IS_MOVED )
+ {
+ Move( m_initialPos + aPosition - m_initialCursorPos );
+ }
+}
diff --git a/eeschema/lib_text.h b/eeschema/lib_text.h
new file mode 100644
index 0000000..518678b
--- /dev/null
+++ b/eeschema/lib_text.h
@@ -0,0 +1,152 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file lib_text.h
+ */
+
+#ifndef _LIB_TEXT_H_
+#define _LIB_TEXT_H_
+
+#include <eda_text.h>
+#include <lib_draw_item.h>
+
+
+/**
+ * Class LIB_TEXT
+ * defines a component library graphical text item.
+ * <p>
+ * This is only a graphical text item. Field text like the reference designator,
+ * component value, etc. are not LIB_TEXT items. See the #LIB_FIELD class for the
+ * field item definition.
+ * </p>
+ */
+class LIB_TEXT : public LIB_ITEM, public EDA_TEXT
+{
+ wxString m_savedText; ///< Temporary storage for the string when edition.
+ bool m_rotate; ///< Flag to indicate a rotation occurred while editing.
+ bool m_updateText; ///< Flag to indicate text change occurred while editing.
+
+ void drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
+ const TRANSFORM& aTransform );
+
+ void calcEdit( const wxPoint& aPosition );
+
+public:
+ LIB_TEXT( LIB_PART * aParent );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~LIB_TEXT() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "LIB_TEXT" );
+ }
+
+ /**
+ * Sets the text item string to \a aText.
+ *
+ * This method does more than just set the set the text string. There are special
+ * cases when changing the text string alone is not enough. If the text item is
+ * being moved, the name change must be delayed until the next redraw to prevent
+ * drawing artifacts.
+ *
+ * @param aText - New text value.
+ */
+ void SetText( const wxString& aText );
+
+ bool Save( OUTPUTFORMATTER& aFormatter );
+
+ bool Load( LINE_READER& aLineReader, wxString& aErrorMsg );
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ bool HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const;
+
+ bool HitTest( const EDA_RECT& aRect ) const
+ {
+ return TextHitTest( aRect );
+ }
+
+
+ int GetPenSize( ) const;
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ const EDA_RECT GetBoundingBox() const; // virtual
+
+ void Rotate();
+
+ void BeginEdit( STATUS_FLAGS aEditMode, const wxPoint aStartPoint = wxPoint( 0, 0 ) );
+
+ bool ContinueEdit( const wxPoint aNextPoint );
+
+ void EndEdit( const wxPoint& aPosition, bool aAbort = false );
+
+ void SetOffset( const wxPoint& aOffset );
+
+ bool Inside( EDA_RECT& aRect ) const;
+
+ void Move( const wxPoint& aPosition );
+
+ wxPoint GetPosition() const { return m_Pos; }
+
+ void MirrorHorizontal( const wxPoint& aCenter );
+
+ void MirrorVertical( const wxPoint& aCenter );
+
+ void Rotate( const wxPoint& aCenter, bool aRotateCCW = true );
+
+ void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
+ const TRANSFORM& aTransform );
+
+ int GetWidth() const { return m_Thickness; }
+
+ void SetWidth( int aWidth ) { m_Thickness = aWidth; }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_text_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+private:
+
+ /**
+ * @copydoc LIB_ITEM::compare()
+ *
+ * The text specific sort order is as follows:
+ * - Text string, case insensitive compare.
+ * - Text horizontal (X) position.
+ * - Text vertical (Y) position.
+ * - Text width.
+ * - Text height.
+ */
+ int compare( const LIB_ITEM& aOther ) const;
+};
+
+
+#endif // _LIB_TEXT_H_
diff --git a/eeschema/libarch.cpp b/eeschema/libarch.cpp
new file mode 100644
index 0000000..100b6aa
--- /dev/null
+++ b/eeschema/libarch.cpp
@@ -0,0 +1,119 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jp.charras ar wanadoo.fr
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file libarch.cpp
+ * @brief Module for generation of component archive files.
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <class_sch_screen.h>
+#include <wxstruct.h>
+#include <schframe.h>
+
+#include <class_library.h>
+#include <sch_component.h>
+#include <sch_sheet.h>
+#include <wildcards_and_files_ext.h>
+
+
+bool SCH_EDIT_FRAME::CreateArchiveLibraryCacheFile( bool aUseCurrentSheetFilename )
+{
+ wxFileName fn;
+
+ if( aUseCurrentSheetFilename )
+ fn = GetScreen()->GetFileName();
+ else
+ fn = g_RootSheet->GetScreen()->GetFileName();
+
+ fn.SetName( fn.GetName() + wxT( "-cache" ) );
+ fn.SetExt( SchematicLibraryFileExtension );
+
+ return CreateArchiveLibrary( fn.GetFullPath() );
+}
+
+
+bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName )
+{
+ SCH_SCREENS screens;
+ PART_LIBS* libs = Prj().SchLibs();
+
+ std::auto_ptr<PART_LIB> libCache( new PART_LIB( LIBRARY_TYPE_EESCHEMA, aFileName ) );
+
+ libCache->SetCache();
+
+ /* examine all screens (not sheets) used and build the list of components
+ * found in lib.
+ * Complex hierarchies are not a problem because we just want
+ * to know used components in libraries
+ */
+ for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
+ {
+ for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
+ {
+ if( item->Type() != SCH_COMPONENT_T )
+ continue;
+
+ SCH_COMPONENT* component = (SCH_COMPONENT*) item;
+
+ // If not already saved in the new cache, put it:
+ if( !libCache->FindEntry( component->GetPartName() ) )
+ {
+ if( LIB_PART* part = libs->FindLibPart( component->GetPartName() ) )
+ {
+ // AddPart() does first clone the part before adding.
+ libCache->AddPart( part );
+ }
+ }
+ }
+ }
+
+ try
+ {
+ FILE_OUTPUTFORMATTER formatter( aFileName );
+
+ if( !libCache->Save( formatter ) )
+ {
+ wxString msg = wxString::Format( _(
+ "An error occurred attempting to save component library '%s'." ),
+ GetChars( aFileName )
+ );
+ DisplayError( this, msg );
+ return false;
+ }
+ }
+ catch( ... /* IO_ERROR ioe */ )
+ {
+ wxString msg = wxString::Format( _(
+ "Failed to create component library file '%s'" ),
+ GetChars( aFileName )
+ );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ return true;
+}
diff --git a/eeschema/libedit.cpp b/eeschema/libedit.cpp
new file mode 100644
index 0000000..fe2f121
--- /dev/null
+++ b/eeschema/libedit.cpp
@@ -0,0 +1,742 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file libedit.cpp
+ * @brief Eeschema component library editor.
+ */
+
+#include <fctsys.h>
+#include <kiway.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <class_sch_screen.h>
+
+#include <eeschema_id.h>
+#include <general.h>
+#include <libeditframe.h>
+#include <class_library.h>
+#include <template_fieldnames.h>
+#include <wildcards_and_files_ext.h>
+
+#include <dialogs/dialog_lib_new_component.h>
+
+
+void LIB_EDIT_FRAME::DisplayLibInfos()
+{
+ wxString msg = _( "Part Library Editor: " );
+ PART_LIB* lib = GetCurLib();
+
+ if( lib )
+ {
+ msg += lib->GetFullFileName();
+
+ if( lib->IsReadOnly() )
+ msg += _( " [Read Only]" );
+ }
+ else
+ {
+ msg += _( "no library selected" );
+ }
+
+ SetTitle( msg );
+}
+
+
+void LIB_EDIT_FRAME::SelectActiveLibrary( PART_LIB* aLibrary )
+{
+ if( !aLibrary )
+ aLibrary = SelectLibraryFromList();
+
+ if( aLibrary )
+ {
+ SetCurLib( aLibrary );
+ }
+
+ DisplayLibInfos();
+}
+
+
+bool LIB_EDIT_FRAME::LoadComponentAndSelectLib( LIB_ALIAS* aLibEntry, PART_LIB* aLibrary )
+{
+ if( GetScreen()->IsModify()
+ && !IsOK( this, _( "The current component is not saved.\n\nDiscard current changes?" ) ) )
+ return false;
+
+ SelectActiveLibrary( aLibrary );
+ return LoadComponentFromCurrentLib( aLibEntry );
+}
+
+
+bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( LIB_ALIAS* aLibEntry )
+{
+ if( !LoadOneLibraryPartAux( aLibEntry, GetCurLib() ) )
+ return false;
+
+ m_editPinsPerPartOrConvert = GetCurPart()->UnitsLocked() ? true : false;
+
+ GetScreen()->ClearUndoRedoList();
+ Zoom_Automatique( false );
+ SetShowDeMorgan( GetCurPart()->HasConversion() );
+
+ return true;
+}
+
+
+void LIB_EDIT_FRAME::LoadOneLibraryPart( wxCommandEvent& event )
+{
+ wxString cmp_name;
+ LIB_ALIAS* libEntry = NULL;
+
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+
+ if( GetScreen()->IsModify()
+ && !IsOK( this, _( "The current component is not saved.\n\nDiscard current changes?" ) ) )
+ return;
+
+ PART_LIB* lib = GetCurLib();
+
+ // No current lib, ask user for the library to use.
+ if( !lib )
+ {
+ SelectActiveLibrary();
+ lib = GetCurLib();
+
+ if( !lib )
+ return;
+ }
+
+ wxArrayString dummyHistoryList;
+ int dummyLastUnit;
+ SCHLIB_FILTER filter;
+ filter.LoadFrom( lib->GetName() );
+ cmp_name = SelectComponentFromLibrary( &filter, dummyHistoryList, dummyLastUnit,
+ true, NULL, NULL );
+
+ if( cmp_name.IsEmpty() )
+ return;
+
+ GetScreen()->ClrModify();
+ m_lastDrawItem = m_drawItem = NULL;
+
+ // Delete previous library component, if any
+ SetCurPart( NULL );
+ m_aliasName.Empty();
+
+ // Load the new library component
+ libEntry = lib->FindEntry( cmp_name );
+ PART_LIB* searchLib = lib;
+
+ if( !libEntry )
+ {
+ // Not found in the active library: search inside the full list
+ // (can happen when using Viewlib to load a component)
+ libEntry = Prj().SchLibs()->FindLibraryEntry( cmp_name );
+
+ if( libEntry )
+ {
+ searchLib = libEntry->GetLib();
+
+ // The entry to load is not in the active lib
+ // Ask for a new active lib
+ wxString msg = _( "The selected component is not in the active library." );
+ msg += wxT("\n\n");
+ msg += _( "Do you want to change the active library?" );
+
+ if( IsOK( this, msg ) )
+ SelectActiveLibrary( searchLib );
+ }
+ }
+
+ if( !libEntry )
+ {
+ wxString msg = wxString::Format( _(
+ "Part name '%s' not found in library '%s'" ),
+ GetChars( cmp_name ),
+ GetChars( searchLib->GetName() )
+ );
+ DisplayError( this, msg );
+ return;
+ }
+
+ PART_LIB* old = SetCurLib( searchLib );
+
+ LoadComponentFromCurrentLib( libEntry );
+
+ SetCurLib( old );
+
+ DisplayLibInfos();
+}
+
+
+bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, PART_LIB* aLibrary )
+{
+ wxString msg, rootName;
+
+ if( !aEntry || !aLibrary )
+ return false;
+
+ if( aEntry->GetName().IsEmpty() )
+ {
+ wxLogWarning( wxT( "Entry in library <%s> has empty name field." ),
+ GetChars( aLibrary->GetName() ) );
+ return false;
+ }
+
+ wxString cmpName = m_aliasName = aEntry->GetName();
+
+ LIB_PART* lib_part = aEntry->GetPart();
+
+ wxASSERT( lib_part );
+
+ wxLogDebug( wxT( "\"<%s>\" is alias of \"<%s>\"" ),
+ GetChars( cmpName ),
+ GetChars( lib_part->GetName() ) );
+
+ LIB_PART* part = new LIB_PART( *lib_part ); // clone it and own it.
+ SetCurPart( part );
+ m_aliasName = aEntry->GetName();
+
+ m_unit = 1;
+ m_convert = 1;
+
+ m_showDeMorgan = false;
+
+ if( part->HasConversion() )
+ m_showDeMorgan = true;
+
+ GetScreen()->ClrModify();
+ DisplayLibInfos();
+ UpdateAliasSelectList();
+ UpdatePartSelectList();
+
+ // Display the document information based on the entry selected just in
+ // case the entry is an alias.
+ DisplayCmpDoc();
+
+ return true;
+}
+
+
+void LIB_EDIT_FRAME::RedrawComponent( wxDC* aDC, wxPoint aOffset )
+{
+ LIB_PART* part = GetCurPart();
+
+ if( part )
+ {
+ // display reference like in schematic (a reference U is shown U? or U?A)
+ // although it is stored without ? and part id.
+ // So temporary change the reference by a schematic like reference
+ LIB_FIELD* field = part->GetField( REFERENCE );
+ wxString fieldText = field->GetText();
+ wxString fieldfullText = field->GetFullText( m_unit );
+
+ field->EDA_TEXT::SetText( fieldfullText ); // change the field text string only
+ part->Draw( m_canvas, aDC, aOffset, m_unit, m_convert, GR_DEFAULT_DRAWMODE );
+ field->EDA_TEXT::SetText( fieldText ); // restore the field text string
+ }
+}
+
+void LIB_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
+{
+ if( GetScreen() == NULL )
+ return;
+
+ m_canvas->DrawBackGround( DC );
+
+ RedrawComponent( DC, wxPoint( 0, 0 ) );
+
+#ifdef USE_WX_OVERLAY
+ if( IsShown() )
+ {
+ m_overlay.Reset();
+ wxDCOverlay overlaydc( m_overlay, (wxWindowDC*)DC );
+ overlaydc.Clear();
+ }
+#endif
+
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ m_canvas->DrawCrossHair( DC );
+
+ DisplayLibInfos();
+ UpdateStatusBar();
+}
+
+
+void LIB_EDIT_FRAME::OnSaveActiveLibrary( wxCommandEvent& event )
+{
+ bool newFile = false;
+ if( event.GetId() == ID_LIBEDIT_SAVE_CURRENT_LIB_AS )
+ newFile = true;
+
+ this->SaveActiveLibrary( newFile );
+}
+
+
+bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
+{
+ wxFileName fn;
+ wxString msg;
+
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+
+ PART_LIB* lib = GetCurLib();
+
+ if( !lib )
+ {
+ DisplayError( this, _( "No library specified." ) );
+ return false;
+ }
+
+ if( GetScreen()->IsModify() )
+ {
+ if( IsOK( this, _( "Include last component changes?" ) ) )
+ SaveOnePart( lib, false );
+ }
+
+ if( newFile )
+ {
+ PROJECT& prj = Prj();
+ SEARCH_STACK* search = prj.SchSearchS();
+
+ // Get a new name for the library
+ wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
+
+ if( !default_path )
+ default_path = search->LastVisitedPath();
+
+ wxFileDialog dlg( this, _( "Part Library Name:" ), default_path,
+ wxEmptyString, SchematicLibraryFileWildcard,
+ wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return false;
+
+ fn = dlg.GetPath();
+
+ // The GTK file chooser doesn't return the file extension added to
+ // file name so add it here.
+ if( fn.GetExt().IsEmpty() )
+ fn.SetExt( SchematicLibraryFileExtension );
+
+ prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
+ }
+ else
+ {
+ fn = wxFileName( lib->GetFullFileName() );
+
+ msg.Printf( _( "Modify library file '%s' ?" ),
+ GetChars( fn.GetFullPath() ) );
+
+ if( !IsOK( this, msg ) )
+ return false;
+ }
+
+ // Verify the user has write privileges before attempting to
+ // save the library file.
+ if( !IsWritable( fn ) )
+ return false;
+
+ ClearMsgPanel();
+
+ wxFileName libFileName = fn;
+ wxFileName backupFileName = fn;
+
+ // Rename the old .lib file to .bak.
+ if( libFileName.FileExists() )
+ {
+ backupFileName.SetExt( wxT( "bak" ) );
+
+ if( backupFileName.FileExists() )
+ wxRemoveFile( backupFileName.GetFullPath() );
+
+ if( !wxRenameFile( libFileName.GetFullPath(), backupFileName.GetFullPath() ) )
+ {
+ libFileName.MakeAbsolute();
+ msg = wxT( "Failed to rename old component library file " ) +
+ backupFileName.GetFullPath();
+ DisplayError( this, msg );
+ }
+ }
+
+ try
+ {
+ FILE_OUTPUTFORMATTER libFormatter( libFileName.GetFullPath() );
+
+ if( !lib->Save( libFormatter ) )
+ {
+ msg.Printf( _( "Error occurred while saving library file '%s'" ),
+ GetChars( fn.GetFullPath() ) );
+ AppendMsgPanel( _( "*** ERROR: ***" ), msg, RED );
+ DisplayError( this, msg );
+ return false;
+ }
+ }
+ catch( ... /* IO_ERROR ioe */ )
+ {
+ libFileName.MakeAbsolute();
+ msg.Printf( _( "Failed to create component library file '%s'" ),
+ GetChars( libFileName.GetFullPath() ) );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ wxFileName docFileName = libFileName;
+
+ docFileName.SetExt( DOC_EXT );
+
+ // Rename .doc file to .bck.
+ if( docFileName.FileExists() )
+ {
+ backupFileName.SetExt( wxT( "bck" ) );
+
+ if( backupFileName.FileExists() )
+ wxRemoveFile( backupFileName.GetFullPath() );
+
+ if( !wxRenameFile( docFileName.GetFullPath(), backupFileName.GetFullPath() ) )
+ {
+ msg = wxT( "Failed to save old library document file " ) +
+ backupFileName.GetFullPath();
+ DisplayError( this, msg );
+ }
+ }
+
+ try
+ {
+ FILE_OUTPUTFORMATTER docFormatter( docFileName.GetFullPath() );
+
+ if( !lib->SaveDocs( docFormatter ) )
+ {
+ msg.Printf( _( "Error occurred while saving library documentation file <%s>" ),
+ GetChars( docFileName.GetFullPath() ) );
+ AppendMsgPanel( _( "*** ERROR: ***" ), msg, RED );
+ DisplayError( this, msg );
+ return false;
+ }
+ }
+ catch( ... /* IO_ERROR ioe */ )
+ {
+ docFileName.MakeAbsolute();
+ msg.Printf( _( "Failed to create component document library file <%s>" ),
+ GetChars( docFileName.GetFullPath() ) );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ msg.Printf( _( "Library file '%s' OK" ), GetChars( fn.GetFullName() ) );
+ fn.SetExt( DOC_EXT );
+ wxString msg1;
+ msg1.Printf( _( "Documentation file '%s' OK" ), GetChars( fn.GetFullPath() ) );
+ AppendMsgPanel( msg, msg1, BLUE );
+
+ return true;
+}
+
+
+void LIB_EDIT_FRAME::DisplayCmpDoc()
+{
+ LIB_ALIAS* alias;
+ PART_LIB* lib = GetCurLib();
+ LIB_PART* part = GetCurPart();
+
+ ClearMsgPanel();
+
+ if( !lib || !part )
+ return;
+
+ wxString msg = part->GetName();
+
+ AppendMsgPanel( _( "Name" ), msg, BLUE, 8 );
+
+ if( m_aliasName == part->GetName() )
+ msg = _( "None" );
+ else
+ msg = m_aliasName;
+
+ alias = part->GetAlias( m_aliasName );
+
+ wxCHECK_RET( alias != NULL, wxT( "Alias not found in component." ) );
+
+ AppendMsgPanel( _( "Alias" ), msg, RED, 8 );
+
+ static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
+ msg = UnitLetter[m_unit];
+
+ AppendMsgPanel( _( "Unit" ), msg, BROWN, 8 );
+
+ if( m_convert > 1 )
+ msg = _( "Convert" );
+ else
+ msg = _( "Normal" );
+
+ AppendMsgPanel( _( "Body" ), msg, GREEN, 8 );
+
+ if( part->IsPower() )
+ msg = _( "Power Symbol" );
+ else
+ msg = _( "Part" );
+
+ AppendMsgPanel( _( "Type" ), msg, MAGENTA, 8 );
+ AppendMsgPanel( _( "Description" ), alias->GetDescription(), CYAN, 8 );
+ AppendMsgPanel( _( "Key words" ), alias->GetKeyWords(), DARKDARKGRAY );
+ AppendMsgPanel( _( "Datasheet" ), alias->GetDocFileName(), DARKDARKGRAY );
+}
+
+
+void LIB_EDIT_FRAME::DeleteOnePart( wxCommandEvent& event )
+{
+ wxString cmp_name;
+ LIB_ALIAS* libEntry;
+ wxArrayString nameList;
+ wxString msg;
+
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+
+ m_lastDrawItem = NULL;
+ m_drawItem = NULL;
+
+ PART_LIB* lib = GetCurLib();
+
+ if( !lib )
+ {
+ SelectActiveLibrary();
+
+ lib = GetCurLib();
+ if( !lib )
+ {
+ DisplayError( this, _( "Please select a component library." ) );
+ return;
+ }
+ }
+
+ lib->GetEntryNames( nameList );
+
+ if( nameList.IsEmpty() )
+ {
+ msg.Printf( _( "Part library '%s' is empty." ), GetChars( lib->GetName() ) );
+ wxMessageBox( msg, _( "Delete Entry Error" ), wxID_OK | wxICON_EXCLAMATION, this );
+ return;
+ }
+
+ msg.Printf( _( "Select one of %d components to delete\nfrom library '%s'." ),
+ int( nameList.GetCount() ),
+ GetChars( lib->GetName() ) );
+
+ wxSingleChoiceDialog dlg( this, msg, _( "Delete Part" ), nameList );
+
+ if( dlg.ShowModal() == wxID_CANCEL || dlg.GetStringSelection().IsEmpty() )
+ return;
+
+ libEntry = lib->FindEntry( dlg.GetStringSelection() );
+
+ if( !libEntry )
+ {
+ msg.Printf( _( "Entry '%s' not found in library '%s'." ),
+ GetChars( dlg.GetStringSelection() ),
+ GetChars( lib->GetName() ) );
+ DisplayError( this, msg );
+ return;
+ }
+
+ msg.Printf( _( "Delete component '%s' from library '%s' ?" ),
+ GetChars( libEntry->GetName() ),
+ GetChars( lib->GetName() ) );
+
+ if( !IsOK( this, msg ) )
+ return;
+
+ LIB_PART* part = GetCurPart();
+
+ if( !part || !part->HasAlias( libEntry->GetName() ) )
+ {
+ lib->RemoveEntry( libEntry );
+ return;
+ }
+
+ // If deleting the current entry or removing one of the aliases for
+ // the current entry, sync the changes in the current entry as well.
+
+ if( GetScreen()->IsModify() && !IsOK( this, _(
+ "The component being deleted has been modified."
+ " All changes will be lost. Discard changes?" ) ) )
+ {
+ return;
+ }
+
+ LIB_ALIAS* nextEntry = lib->RemoveEntry( libEntry );
+
+ if( nextEntry != NULL )
+ {
+ if( LoadOneLibraryPartAux( nextEntry, lib ) )
+ Zoom_Automatique( false );
+ }
+ else
+ {
+ SetCurPart( NULL ); // delete CurPart
+ m_aliasName.Empty();
+ }
+
+ m_canvas->Refresh();
+}
+
+
+
+void LIB_EDIT_FRAME::CreateNewLibraryPart( wxCommandEvent& event )
+{
+ wxString name;
+
+ if( GetCurPart() && GetScreen()->IsModify() && !IsOK( this, _(
+ "All changes to the current component will be lost!\n\n"
+ "Clear the current component from the screen?" ) ) )
+ {
+ return;
+ }
+
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+
+ m_drawItem = NULL;
+
+ DIALOG_LIB_NEW_COMPONENT dlg( this );
+
+ dlg.SetMinSize( dlg.GetSize() );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ if( dlg.GetName().IsEmpty() )
+ {
+ wxMessageBox( _( "This new component has no name and cannot be created. Aborted" ) );
+ return;
+ }
+
+ name = dlg.GetName();
+ name.Replace( wxT( " " ), wxT( "_" ) );
+
+ PART_LIB* lib = GetCurLib();
+
+ // Test if there a component with this name already.
+ if( lib && lib->FindEntry( name ) )
+ {
+ wxString msg = wxString::Format( _(
+ "Part '%s' already exists in library '%s'" ),
+ GetChars( name ),
+ GetChars( lib->GetName() )
+ );
+ DisplayError( this, msg );
+ return;
+ }
+
+ LIB_PART* new_part = new LIB_PART( name );
+
+ SetCurPart( new_part );
+ m_aliasName = new_part->GetName();
+
+ new_part->GetReferenceField().SetText( dlg.GetReference() );
+ new_part->SetUnitCount( dlg.GetUnitCount() );
+
+ // Initialize new_part->m_TextInside member:
+ // if 0, pin text is outside the body (on the pin)
+ // if > 0, pin text is inside the body
+ new_part->SetConversion( dlg.GetAlternateBodyStyle() );
+ SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
+
+ if( dlg.GetPinNameInside() )
+ {
+ new_part->SetPinNameOffset( dlg.GetPinTextPosition() );
+
+ if( new_part->GetPinNameOffset() == 0 )
+ new_part->SetPinNameOffset( 1 );
+ }
+ else
+ {
+ new_part->SetPinNameOffset( 0 );
+ }
+
+ ( dlg.GetPowerSymbol() ) ? new_part->SetPower() : new_part->SetNormal();
+ new_part->SetShowPinNumbers( dlg.GetShowPinNumber() );
+ new_part->SetShowPinNames( dlg.GetShowPinName() );
+ new_part->LockUnits( dlg.GetLockItems() );
+
+ if( dlg.GetUnitCount() < 2 )
+ new_part->LockUnits( false );
+
+ m_unit = 1;
+ m_convert = 1;
+
+ DisplayLibInfos();
+ DisplayCmpDoc();
+ UpdateAliasSelectList();
+ UpdatePartSelectList();
+
+ m_editPinsPerPartOrConvert = new_part->UnitsLocked() ? true : false;
+ m_lastDrawItem = NULL;
+
+ GetScreen()->ClearUndoRedoList();
+ OnModify();
+
+ m_canvas->Refresh();
+ m_mainToolBar->Refresh();
+}
+
+
+bool LIB_EDIT_FRAME::SaveOnePart( PART_LIB* aLib, bool aPromptUser )
+{
+ wxString msg;
+ LIB_PART* part = GetCurPart();
+
+ GetScreen()->ClrModify();
+
+ LIB_PART* old_part = aLib->FindPart( part->GetName() );
+
+ if( old_part && aPromptUser )
+ {
+ msg.Printf( _( "Part '%s' already exists. Change it?" ),
+ GetChars( part->GetName() ) );
+
+ if( !IsOK( this, msg ) )
+ return false;
+ }
+
+ m_drawItem = m_lastDrawItem = NULL;
+
+ if( old_part )
+ aLib->ReplacePart( old_part, part );
+ else
+ aLib->AddPart( part );
+
+ msg.Printf( _( "Part '%s' saved in library '%s'" ),
+ GetChars( part->GetName() ),
+ GetChars( aLib->GetName() ) );
+
+ SetStatusText( msg );
+
+ return true;
+}
diff --git a/eeschema/libedit_onleftclick.cpp b/eeschema/libedit_onleftclick.cpp
new file mode 100644
index 0000000..5ee53d9
--- /dev/null
+++ b/eeschema/libedit_onleftclick.cpp
@@ -0,0 +1,213 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file libedit_onleftclick.cpp
+ * @brief Eeschema library editor event handler for a mouse left button single or double click.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <eeschema_id.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <libeditframe.h>
+#include <class_libentry.h>
+
+
+void LIB_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& aPosition )
+{
+ LIB_ITEM* item = m_drawItem;
+ bool item_in_edit = item && item->InEditMode();
+ bool no_item_edited = !item_in_edit;
+
+ LIB_PART* part = GetCurPart();
+
+ if( !part ) // No component loaded !
+ return;
+
+ if( ( GetToolId() == ID_NO_TOOL_SELECTED ) && no_item_edited )
+ {
+ item = LocateItemUsingCursor( aPosition );
+
+ if( item )
+ {
+ MSG_PANEL_ITEMS items;
+ item->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+ }
+ else
+ {
+ DisplayCmpDoc();
+
+ if( m_canvas->GetAbortRequest() )
+ m_canvas->SetAbortRequest( false );
+ }
+ }
+
+ switch( GetToolId() )
+ {
+ case ID_NO_TOOL_SELECTED:
+ // If an item is currently in edit, finish edit
+ if( item_in_edit )
+ {
+ switch( item->Type() )
+ {
+ case LIB_PIN_T:
+ PlacePin();
+ break;
+
+ default:
+ EndDrawGraphicItem( DC );
+ break;
+ }
+ }
+ break;
+
+ case ID_LIBEDIT_PIN_BUTT:
+ if( no_item_edited )
+ CreatePin( DC );
+ else
+ PlacePin();
+ break;
+
+ case ID_LIBEDIT_BODY_LINE_BUTT:
+ case ID_LIBEDIT_BODY_ARC_BUTT:
+ case ID_LIBEDIT_BODY_CIRCLE_BUTT:
+ case ID_LIBEDIT_BODY_RECT_BUTT:
+ case ID_LIBEDIT_BODY_TEXT_BUTT:
+ if( no_item_edited )
+ m_drawItem = CreateGraphicItem( part, DC );
+ else if( m_drawItem )
+ {
+ if( m_drawItem->IsNew() )
+ GraphicItemBeginDraw( DC );
+ else
+ EndDrawGraphicItem( DC );
+ }
+ break;
+
+ case ID_LIBEDIT_DELETE_ITEM_BUTT:
+ m_drawItem = LocateItemUsingCursor( aPosition );
+
+ if( m_drawItem )
+ deleteItem( DC );
+ else
+ DisplayCmpDoc();
+
+ break;
+
+ case ID_LIBEDIT_ANCHOR_ITEM_BUTT:
+ SaveCopyInUndoList( part );
+ PlaceAnchor();
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ break;
+
+ default:
+ wxFAIL_MSG( wxString::Format( wxT( "Unhandled command ID %d" ), GetToolId() ) );
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ break;
+ }
+}
+
+
+/*
+ * Called on a double click:
+ * If an editable item (field, pin, graphic):
+ * Call the suitable dialog editor.
+ */
+void LIB_EDIT_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& aPosition )
+{
+ LIB_PART* part = GetCurPart();
+
+ if( !part )
+ return;
+
+ if( !m_drawItem || !m_drawItem->InEditMode() )
+ { // We can locate an item
+ m_drawItem = LocateItemUsingCursor( aPosition );
+
+ if( m_drawItem == NULL )
+ {
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+
+ cmd.SetId( ID_LIBEDIT_GET_FRAME_EDIT_PART );
+ GetEventHandler()->ProcessEvent( cmd );
+ }
+ }
+
+ if( m_drawItem )
+ SetMsgPanel( m_drawItem );
+ else
+ return;
+
+ m_canvas->SetIgnoreMouseEvents( true );
+ bool not_edited = !m_drawItem->InEditMode();
+
+ switch( m_drawItem->Type() )
+ {
+ case LIB_PIN_T:
+ if( not_edited )
+ {
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+
+ cmd.SetId( ID_LIBEDIT_EDIT_PIN );
+ GetEventHandler()->ProcessEvent( cmd );
+ }
+ break;
+
+ case LIB_ARC_T:
+ case LIB_CIRCLE_T:
+ case LIB_RECTANGLE_T:
+ if( not_edited )
+ EditGraphicSymbol( DC, m_drawItem );
+ break;
+
+ case LIB_POLYLINE_T:
+ if( not_edited )
+ EditGraphicSymbol( DC, m_drawItem );
+ else if( m_drawItem->IsNew() )
+ EndDrawGraphicItem( DC );
+ break;
+
+ case LIB_TEXT_T:
+ if( not_edited )
+ EditSymbolText( DC, m_drawItem );
+ break;
+
+ case LIB_FIELD_T:
+ if( not_edited )
+ EditField( (LIB_FIELD*) m_drawItem );
+ break;
+
+ default:
+ wxFAIL_MSG( wxT( "Unhandled item <" ) + m_drawItem->GetClass() + wxT( ">" ) );
+ break;
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+}
diff --git a/eeschema/libedit_onrightclick.cpp b/eeschema/libedit_onrightclick.cpp
new file mode 100644
index 0000000..24067ed
--- /dev/null
+++ b/eeschema/libedit_onrightclick.cpp
@@ -0,0 +1,348 @@
+/**
+ * @file libedit_onrightclick.cpp
+ * @brief Library editor: create the pop menus when clicking on mouse right button
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <eeschema_id.h>
+#include <hotkeys.h>
+#include <class_drawpanel.h>
+#include <class_sch_screen.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <libeditframe.h>
+#include <class_libentry.h>
+#include <lib_pin.h>
+#include <lib_polyline.h>
+#include <menus_helpers.h>
+
+
+/* functions to add commands and submenus depending on the item */
+static void AddMenusForBlock( wxMenu* PopMenu, LIB_EDIT_FRAME* frame );
+static void AddMenusForPin( wxMenu* PopMenu, LIB_PIN* Pin, LIB_EDIT_FRAME* frame );
+
+
+bool LIB_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
+{
+ LIB_ITEM* item = GetDrawItem();
+ bool blockActive = GetScreen()->IsBlockActive();
+
+ if( blockActive )
+ {
+ AddMenusForBlock( PopMenu, this );
+ PopMenu->AppendSeparator();
+ return true;
+ }
+
+ LIB_PART* part = GetCurPart();
+
+ if( !part )
+ return true;
+
+ // If Command in progress, put menu "cancel"
+ if( item && item->InEditMode() )
+ {
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_CANCEL_EDITING, _( "Cancel" ),
+ KiBitmap( cancel_xpm ) );
+ PopMenu->AppendSeparator();
+ }
+ else
+ {
+ item = LocateItemUsingCursor( aPosition );
+
+ // If the clarify item selection context menu is aborted, don't show the context menu.
+ if( item == NULL && m_canvas->GetAbortRequest() )
+ {
+ m_canvas->SetAbortRequest( false );
+ return false;
+ }
+
+ if( GetToolId() != ID_NO_TOOL_SELECTED )
+ {
+ // If a tool is active, put menu "end tool"
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_CANCEL_EDITING, _( "End Tool" ),
+ KiBitmap( cursor_xpm ) );
+ PopMenu->AppendSeparator();
+ }
+ }
+
+ if( item )
+ {
+ MSG_PANEL_ITEMS items;
+ item->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+ }
+ else
+ {
+ return true;
+ }
+
+ m_drawItem = item;
+ bool not_edited = !item->InEditMode();
+ wxString msg;
+
+ switch( item->Type() )
+ {
+ case LIB_PIN_T:
+ AddMenusForPin( PopMenu, (LIB_PIN*) item, this );
+ break;
+
+ case LIB_ARC_T:
+ if( not_edited )
+ {
+ msg = AddHotkeyName( _( "Move Arc" ), g_Libedit_Hokeys_Descr,
+ HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg,
+ KiBitmap( move_arc_xpm ) );
+ msg = AddHotkeyName( _( "Drag Arc Size" ), g_Libedit_Hokeys_Descr, HK_DRAG );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM, msg, KiBitmap( move_arc_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Edit Arc Options" ), g_Libedit_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, msg, KiBitmap( options_arc_xpm ) );
+
+ if( not_edited )
+ {
+ msg = AddHotkeyName( _( "Delete Arc" ), g_Libedit_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, msg, KiBitmap( delete_arc_xpm ) );
+ }
+ break;
+
+ case LIB_CIRCLE_T:
+ if( not_edited )
+ {
+ msg = AddHotkeyName( _( "Move Circle" ), g_Libedit_Hokeys_Descr,
+ HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg,
+ KiBitmap( move_circle_xpm ) );
+ msg = AddHotkeyName( _( "Drag Circle Outline" ), g_Libedit_Hokeys_Descr, HK_DRAG );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM, msg,
+ KiBitmap( move_rectangle_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Edit Circle Options" ), g_Libedit_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, msg,
+ KiBitmap( options_circle_xpm ) );
+
+ if( not_edited )
+ {
+ msg = AddHotkeyName( _( "Delete Circle" ), g_Libedit_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, msg,
+ KiBitmap( delete_circle_xpm ) );
+ }
+ break;
+
+ case LIB_RECTANGLE_T:
+ if( not_edited )
+ {
+ msg = AddHotkeyName( _( "Move Rectangle" ), g_Libedit_Hokeys_Descr,
+ HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg,
+ KiBitmap( move_rectangle_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Edit Rectangle Options" ), g_Libedit_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, msg,
+ KiBitmap( options_rectangle_xpm ) );
+
+ if( not_edited )
+ {
+ msg = AddHotkeyName( _( "Drag Rectangle Edge" ), g_Libedit_Hokeys_Descr, HK_DRAG );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM, msg,
+ KiBitmap( move_rectangle_xpm ) );
+ msg = AddHotkeyName( _( "Delete Rectangle" ), g_Libedit_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, msg,
+ KiBitmap( delete_rectangle_xpm ) );
+ }
+
+ break;
+
+ case LIB_TEXT_T:
+ if( not_edited )
+ {
+ msg = AddHotkeyName( _( "Move Text" ), g_Libedit_Hokeys_Descr,
+ HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg,
+ KiBitmap( move_text_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Edit Text" ), g_Libedit_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
+
+ msg = AddHotkeyName( _( "Rotate Text" ), g_Libedit_Hokeys_Descr, HK_ROTATE );
+ AddMenuItem( PopMenu, ID_LIBEDIT_ROTATE_ITEM, msg, KiBitmap( edit_text_xpm ) );
+
+ if( not_edited )
+ {
+ msg = AddHotkeyName( _( "Delete Text" ), g_Libedit_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, msg, KiBitmap( delete_text_xpm ) );
+ }
+ break;
+
+ case LIB_POLYLINE_T:
+ if( not_edited )
+ {
+ msg = AddHotkeyName( _( "Move Line" ), g_Libedit_Hokeys_Descr,
+ HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg,
+ KiBitmap( move_line_xpm ) );
+ msg = AddHotkeyName( _( "Drag Edge Point" ), g_Libedit_Hokeys_Descr, HK_DRAG );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MODIFY_ITEM, msg, KiBitmap( move_line_xpm ) );
+ }
+
+ if( item->IsNew() )
+ {
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_END_CREATE_ITEM, _( "Line End" ),
+ KiBitmap( checked_ok_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Edit Line Options" ), g_Libedit_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_BODY_EDIT_ITEM, msg,
+ KiBitmap( options_segment_xpm ) );
+
+ if( not_edited )
+ {
+ msg = AddHotkeyName( _( "Delete Line " ), g_Libedit_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, msg,
+ KiBitmap( delete_segment_xpm ) );
+ }
+
+ if( item->IsNew() )
+ {
+ if( ( (LIB_POLYLINE*) item )->GetCornerCount() > 2 )
+ {
+ msg = AddHotkeyName( _( "Delete Segment" ), g_Libedit_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT,
+ msg, KiBitmap( delete_segment_xpm ) );
+ }
+ }
+
+ break;
+
+ case LIB_FIELD_T:
+ if( not_edited )
+ {
+ msg = AddHotkeyName( _( "Move Field" ), g_Libedit_Hokeys_Descr,
+ HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg,
+ KiBitmap( move_field_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Field Rotate" ), g_Libedit_Hokeys_Descr, HK_ROTATE );
+ AddMenuItem( PopMenu, ID_LIBEDIT_ROTATE_ITEM, msg, KiBitmap( rotate_field_xpm ) );
+ msg = AddHotkeyName( _( "Field Edit" ), g_Libedit_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
+ break;
+
+
+ default:
+ wxFAIL_MSG( wxString::Format( wxT( "Unknown library item type %d" ),
+ item->Type() ) );
+ m_drawItem = NULL;
+ break;
+ }
+
+ PopMenu->AppendSeparator();
+ return true;
+}
+
+// Add menu items for pin edition
+void AddMenusForPin( wxMenu* PopMenu, LIB_PIN* Pin, LIB_EDIT_FRAME* frame )
+{
+ bool selected = Pin->IsSelected();
+ bool not_in_move = !Pin->IsMoving();
+ wxString msg;
+
+ if( not_in_move )
+ {
+ msg = AddHotkeyName( _( "Move Pin " ), g_Libedit_Hokeys_Descr,
+ HK_LIBEDIT_MOVE_GRAPHIC_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST, msg, KiBitmap( move_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Edit Pin " ), g_Libedit_Hokeys_Descr, HK_EDIT);
+ AddMenuItem( PopMenu, ID_LIBEDIT_EDIT_PIN, msg, KiBitmap( edit_xpm ) );
+
+ msg = AddHotkeyName( _( "Rotate Pin " ), g_Libedit_Hokeys_Descr, HK_ROTATE );
+ AddMenuItem( PopMenu, ID_LIBEDIT_ROTATE_ITEM, msg, KiBitmap( rotate_pin_xpm ) );
+
+ if( not_in_move )
+ {
+ msg = AddHotkeyName( _( "Delete Pin " ), g_Libedit_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_DELETE_ITEM, msg, KiBitmap( delete_pin_xpm ) );
+ }
+
+ wxMenu* global_pin_change = new wxMenu;
+ AddMenuItem( PopMenu, global_pin_change,
+ ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_ITEM,
+ _( "Global" ), KiBitmap( pin_to_xpm ) );
+ AddMenuItem( global_pin_change,
+ ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM,
+ selected ? _( "Pin Size to selected pins" ) :
+ _( "Pin Size to Others" ), KiBitmap( pin_size_to_xpm ) );
+ AddMenuItem( global_pin_change,
+ ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM,
+ selected ? _( "Pin Name Size to selected pin" ) :
+ _( "Pin Name Size to Others" ), KiBitmap( pin_name_to_xpm ) );
+ AddMenuItem( global_pin_change,
+ ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM,
+ selected ? _( "Pin Num Size to selected pin" ) :
+ _( "Pin Num Size to Others" ), KiBitmap( pin_number_to_xpm ) );
+}
+
+
+/* Add menu commands for block */
+
+void AddMenusForBlock( wxMenu* PopMenu, LIB_EDIT_FRAME* frame )
+{
+ AddMenuItem( PopMenu, ID_POPUP_LIBEDIT_CANCEL_EDITING, _( "Cancel Block" ),
+ KiBitmap( cancel_xpm ) );
+
+ if( frame->GetScreen()->m_BlockLocate.GetCommand() == BLOCK_MOVE )
+ AddMenuItem( PopMenu, ID_POPUP_ZOOM_BLOCK,
+ _( "Zoom Block (drag middle mouse)" ),
+ KiBitmap( zoom_area_xpm ) );
+
+ PopMenu->AppendSeparator();
+
+ AddMenuItem( PopMenu, ID_POPUP_PLACE_BLOCK, _( "Place Block" ), KiBitmap( checked_ok_xpm ) );
+
+ if( frame->GetScreen()->m_BlockLocate.GetCommand() == BLOCK_MOVE )
+ {
+ AddMenuItem( PopMenu, ID_POPUP_SELECT_ITEMS_BLOCK, _( "Select Items" ),
+ KiBitmap( green_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_COPY_BLOCK, _( "Copy Block" ), KiBitmap( copyblock_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_MIRROR_Y_BLOCK, _( "Mirror Block ||" ),
+ KiBitmap( mirror_h_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_MIRROR_X_BLOCK, _( "Mirror Block --" ),
+ KiBitmap( mirror_v_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_ROTATE_BLOCK, _( "Rotate Block ccw" ),
+ KiBitmap( rotate_ccw_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_DELETE_BLOCK, _( "Delete Block" ), KiBitmap( delete_xpm ) );
+ }
+}
diff --git a/eeschema/libedit_plot_component.cpp b/eeschema/libedit_plot_component.cpp
new file mode 100644
index 0000000..ccdca67
--- /dev/null
+++ b/eeschema/libedit_plot_component.cpp
@@ -0,0 +1,214 @@
+/**
+ * @file libedit_plot_component.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+
+#include <gr_basic.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <eeschema_id.h>
+#include <class_sch_screen.h>
+
+#include <general.h>
+#include <libeditframe.h>
+#include <class_library.h>
+#include <dialogs/dialog_plot_schematic.h>
+
+#include <boost/foreach.hpp>
+
+
+void LIB_EDIT_FRAME::OnPlotCurrentComponent( wxCommandEvent& event )
+{
+ wxString fullFileName;
+ wxString file_ext;
+ wxString mask;
+
+ LIB_PART* part = GetCurPart();
+
+ if( !part )
+ {
+ wxMessageBox( _( "No component" ) );
+ return;
+ }
+
+ switch( event.GetId() )
+ {
+ case ID_LIBEDIT_GEN_PNG_FILE:
+ {
+ bool fmt_is_jpeg = false; // could be selectable later. so keep this option.
+
+ file_ext = fmt_is_jpeg ? wxT( "jpg" ) : wxT( "png" );
+ mask = wxT( "*." ) + file_ext;
+ wxFileName fn( part->GetName() );
+ fn.SetExt( file_ext );
+
+ wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
+
+ fullFileName = EDA_FILE_SELECTOR( _( "Filename:" ), pro_dir,
+ fn.GetFullName(), file_ext, mask, this,
+ wxFD_SAVE, true );
+
+ if( fullFileName.IsEmpty() )
+ return;
+
+ // calling wxYield is mandatory under Linux, after closing the file selector dialog
+ // to refresh the screen before creating the PNG or JPEG image from screen
+ wxYield();
+ CreatePNGorJPEGFile( fullFileName, fmt_is_jpeg );
+ }
+ break;
+
+ case ID_LIBEDIT_GEN_SVG_FILE:
+ {
+ file_ext = wxT( "svg" );
+ mask = wxT( "*." ) + file_ext;
+ wxFileName fn( part->GetName() );
+ fn.SetExt( file_ext );
+
+ wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
+
+ fullFileName = EDA_FILE_SELECTOR( _( "Filename:" ), pro_dir,
+ fn.GetFullName(), file_ext, mask, this,
+ wxFD_SAVE, true );
+
+ if( fullFileName.IsEmpty() )
+ return;
+
+ PAGE_INFO pageSave = GetScreen()->GetPageSettings();
+ PAGE_INFO pageTemp = pageSave;
+
+ wxSize componentSize = part->GetBoundingBox( m_unit, m_convert ).GetSize();
+
+ // Add a small margin to the plot bounding box
+ pageTemp.SetWidthMils( int( componentSize.x * 1.2 ) );
+ pageTemp.SetHeightMils( int( componentSize.y * 1.2 ) );
+
+ GetScreen()->SetPageSettings( pageTemp );
+ SVG_PlotComponent( fullFileName );
+ GetScreen()->SetPageSettings( pageSave );
+ }
+ break;
+ }
+}
+
+
+void LIB_EDIT_FRAME::CreatePNGorJPEGFile( const wxString& aFileName, bool aFmt_jpeg )
+{
+ wxSize image_size = m_canvas->GetClientSize();
+
+ wxClientDC dc( m_canvas );
+ wxBitmap bitmap( image_size.x, image_size.y );
+ wxMemoryDC memdc;
+
+ memdc.SelectObject( bitmap );
+ memdc.Blit( 0, 0, image_size.x, image_size.y, &dc, 0, 0 );
+ memdc.SelectObject( wxNullBitmap );
+
+ wxImage image = bitmap.ConvertToImage();
+
+ if( !image.SaveFile( aFileName, aFmt_jpeg ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG ) )
+ {
+ wxString msg;
+ msg.Printf( _( "Can't save file <%s>" ), GetChars( aFileName ) );
+ wxMessageBox( msg );
+ }
+
+ image.Destroy();
+}
+
+
+void LIB_EDIT_FRAME::SVG_PlotComponent( const wxString& aFullFileName )
+{
+ const bool plotBW = false;
+ const PAGE_INFO& pageInfo = GetScreen()->GetPageSettings();
+
+ SVG_PLOTTER* plotter = new SVG_PLOTTER();
+ plotter->SetPageSettings( pageInfo );
+ plotter->SetDefaultLineWidth( GetDefaultLineThickness() );
+ plotter->SetColorMode( plotBW );
+
+ wxPoint plot_offset;
+ const double scale = 1.0;
+ plotter->SetViewport( plot_offset, IU_PER_DECIMILS, scale, false );
+
+ // Init :
+ plotter->SetCreator( wxT( "Eeschema-SVG" ) );
+
+ if( ! plotter->OpenFile( aFullFileName ) )
+ {
+ delete plotter;
+ return;
+ }
+
+ LOCALE_IO toggle;
+
+ plotter->StartPlot();
+
+ LIB_PART* part = GetCurPart();
+
+ if( part )
+ {
+ TRANSFORM temp; // Uses default transform
+ wxPoint plotPos;
+
+ plotPos.x = pageInfo.GetWidthIU() /2;
+ plotPos.y = pageInfo.GetHeightIU()/2;
+
+ part->Plot( plotter, GetUnit(), GetConvert(), plotPos, temp );
+
+ // Plot lib fields, not plotted by m_component->Plot():
+ part->PlotLibFields( plotter, GetUnit(), GetConvert(), plotPos, temp );
+ }
+
+ plotter->EndPlot();
+ delete plotter;
+}
+
+void LIB_EDIT_FRAME::PrintPage( wxDC* aDC, LSET aPrintMask, bool aPrintMirrorMode, void* aData)
+{
+ LIB_PART* part = GetCurPart();
+
+ if( !part )
+ return;
+
+ wxSize pagesize = GetScreen()->GetPageSettings().GetSizeIU();
+
+ /* Plot item centered to the page
+ * In libedit, the component is centered at 0,0 coordinates.
+ * So we must plot it with an offset = pagesize/2.
+ */
+ wxPoint plot_offset;
+ plot_offset.x = pagesize.x/2;
+ plot_offset.y = pagesize.y/2;
+
+ part->Draw( m_canvas, aDC, plot_offset, m_unit, m_convert, GR_DEFAULT_DRAWMODE );
+}
+
+
diff --git a/eeschema/libedit_undo_redo.cpp b/eeschema/libedit_undo_redo.cpp
new file mode 100644
index 0000000..a293500
--- /dev/null
+++ b/eeschema/libedit_undo_redo.cpp
@@ -0,0 +1,137 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+
+//#include <general.h>
+//#include <protos.h>
+#include <libeditframe.h>
+#include <class_libentry.h>
+
+
+void LIB_EDIT_FRAME::SaveCopyInUndoList( EDA_ITEM* ItemToCopy )
+{
+ LIB_PART* CopyItem;
+ PICKED_ITEMS_LIST* lastcmd;
+
+ CopyItem = new LIB_PART( * (LIB_PART*) ItemToCopy );
+
+ // Clear current flags (which can be temporary set by a current edit command).
+ CopyItem->ClearStatus();
+
+ lastcmd = new PICKED_ITEMS_LIST();
+ ITEM_PICKER wrapper( CopyItem, UR_LIBEDIT );
+ lastcmd->PushItem(wrapper);
+ GetScreen()->PushCommandToUndoList( lastcmd );
+
+ // Clear redo list, because after new save there is no redo to do.
+ GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
+}
+
+
+void LIB_EDIT_FRAME::GetComponentFromRedoList( wxCommandEvent& event )
+{
+ if( GetScreen()->GetRedoCommandCount() <= 0 )
+ return;
+
+ PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
+
+ LIB_PART* part = GetCurPart();
+
+ ITEM_PICKER wrapper( part, UR_LIBEDIT );
+
+ lastcmd->PushItem( wrapper );
+ GetScreen()->PushCommandToUndoList( lastcmd );
+
+ lastcmd = GetScreen()->PopCommandFromRedoList();
+
+ wrapper = lastcmd->PopItem();
+
+ part = (LIB_PART*) wrapper.GetItem();
+
+ // Do not delete the previous part by calling SetCurPart( part )
+ // which calls delete <previous part>.
+ // <previous part> is now put in undo list and is owned by this list
+ // Just set the current part to the part which come from the redo list
+ m_my_part = part;
+
+ if( !part )
+ return;
+
+ if( !m_aliasName.IsEmpty() && !part->HasAlias( m_aliasName ) )
+ m_aliasName = part->GetName();
+
+ m_drawItem = NULL;
+ UpdateAliasSelectList();
+ UpdatePartSelectList();
+ SetShowDeMorgan( part->HasConversion() );
+ DisplayLibInfos();
+ DisplayCmpDoc();
+ OnModify();
+ m_canvas->Refresh();
+}
+
+
+void LIB_EDIT_FRAME::GetComponentFromUndoList( wxCommandEvent& event )
+{
+ if( GetScreen()->GetUndoCommandCount() <= 0 )
+ return;
+
+ PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
+
+ LIB_PART* part = GetCurPart();
+
+ ITEM_PICKER wrapper( part, UR_LIBEDIT );
+
+ lastcmd->PushItem( wrapper );
+ GetScreen()->PushCommandToRedoList( lastcmd );
+
+ lastcmd = GetScreen()->PopCommandFromUndoList();
+
+ wrapper = lastcmd->PopItem();
+
+ part = (LIB_PART* ) wrapper.GetItem();
+
+ // Do not delete the previous part by calling SetCurPart( part ),
+ // which calls delete <previous part>.
+ // <previous part> is now put in redo list and is owned by this list.
+ // Just set the current part to the part which come from the undo list
+ m_my_part = part;
+
+ if( !part )
+ return;
+
+ if( !m_aliasName.IsEmpty() && !part->HasAlias( m_aliasName ) )
+ m_aliasName = part->GetName();
+
+ m_drawItem = NULL;
+ UpdateAliasSelectList();
+ UpdatePartSelectList();
+ SetShowDeMorgan( part->HasConversion() );
+ DisplayLibInfos();
+ DisplayCmpDoc();
+ OnModify();
+ m_canvas->Refresh();
+}
diff --git a/eeschema/libeditframe.cpp b/eeschema/libeditframe.cpp
new file mode 100644
index 0000000..bd489a0
--- /dev/null
+++ b/eeschema/libeditframe.cpp
@@ -0,0 +1,1375 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file libeditframe.cpp
+ * @brief LIB_EDIT_FRAME class is the component library editor frame.
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <eda_doc.h>
+#include <gr_basic.h>
+#include <schframe.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <eeschema_id.h>
+#include <libeditframe.h>
+#include <class_library.h>
+#include <lib_polyline.h>
+#include <lib_pin.h>
+
+#include <kicad_device_context.h>
+#include <hotkeys.h>
+
+#include <dialogs/dialog_lib_edit_text.h>
+#include <dialogs/dialog_edit_component_in_lib.h>
+#include <dialogs/dialog_lib_edit_pin_table.h>
+
+#include <menus_helpers.h>
+
+#include <boost/foreach.hpp>
+
+
+/* This method guarantees unique IDs for the library this run of Eeschema
+ * which prevents ID conflicts and eliminates the need to recompile every
+ * source file in the project when adding IDs to include/id.h. */
+int ExportPartId = ::wxNewId();
+int ImportPartId = ::wxNewId();
+int CreateNewLibAndSavePartId = ::wxNewId();
+
+
+wxString LIB_EDIT_FRAME:: m_aliasName;
+int LIB_EDIT_FRAME:: m_unit = 1;
+int LIB_EDIT_FRAME:: m_convert = 1;
+LIB_ITEM* LIB_EDIT_FRAME::m_lastDrawItem = NULL;
+LIB_ITEM* LIB_EDIT_FRAME::m_drawItem = NULL;
+bool LIB_EDIT_FRAME:: m_showDeMorgan = false;
+wxSize LIB_EDIT_FRAME:: m_clientSize = wxSize( -1, -1 );
+int LIB_EDIT_FRAME:: m_textSize = -1;
+int LIB_EDIT_FRAME:: m_textOrientation = TEXT_ORIENT_HORIZ;
+int LIB_EDIT_FRAME:: m_drawLineWidth = 0;
+
+// these values are overridden when reading the config
+int LIB_EDIT_FRAME:: m_textPinNumDefaultSize = DEFAULTPINNUMSIZE;
+int LIB_EDIT_FRAME:: m_textPinNameDefaultSize = DEFAULTPINNAMESIZE;
+int LIB_EDIT_FRAME:: m_defaultPinLength = DEFAULTPINLENGTH;
+
+FILL_T LIB_EDIT_FRAME:: m_drawFillStyle = NO_FILL;
+
+
+BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
+ EVT_CLOSE( LIB_EDIT_FRAME::OnCloseWindow )
+ EVT_SIZE( LIB_EDIT_FRAME::OnSize )
+ EVT_ACTIVATE( LIB_EDIT_FRAME::OnActivate )
+
+ // Main horizontal toolbar.
+ EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_LIB, LIB_EDIT_FRAME::OnSaveActiveLibrary )
+ EVT_TOOL( ID_LIBEDIT_SELECT_CURRENT_LIB, LIB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_LIBEDIT_DELETE_PART, LIB_EDIT_FRAME::DeleteOnePart )
+ EVT_TOOL( ID_TO_LIBVIEW, LIB_EDIT_FRAME::OnOpenLibraryViewer )
+ EVT_TOOL( ID_LIBEDIT_NEW_PART, LIB_EDIT_FRAME::CreateNewLibraryPart )
+ EVT_TOOL( ID_LIBEDIT_NEW_PART_FROM_EXISTING, LIB_EDIT_FRAME::OnCreateNewPartFromExisting )
+
+ EVT_TOOL( ID_LIBEDIT_SELECT_PART, LIB_EDIT_FRAME::LoadOneLibraryPart )
+ EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_PART, LIB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( wxID_UNDO, LIB_EDIT_FRAME::GetComponentFromUndoList )
+ EVT_TOOL( wxID_REDO, LIB_EDIT_FRAME::GetComponentFromRedoList )
+ EVT_TOOL( ID_LIBEDIT_GET_FRAME_EDIT_PART, LIB_EDIT_FRAME::OnEditComponentProperties )
+ EVT_TOOL( ID_LIBEDIT_GET_FRAME_EDIT_FIELDS, LIB_EDIT_FRAME::InstallFieldsEditorDialog )
+ EVT_TOOL( ID_LIBEDIT_CHECK_PART, LIB_EDIT_FRAME::OnCheckComponent )
+ EVT_TOOL( ID_DE_MORGAN_NORMAL_BUTT, LIB_EDIT_FRAME::OnSelectBodyStyle )
+ EVT_TOOL( ID_DE_MORGAN_CONVERT_BUTT, LIB_EDIT_FRAME::OnSelectBodyStyle )
+ EVT_TOOL( ID_LIBEDIT_VIEW_DOC, LIB_EDIT_FRAME::OnViewEntryDoc )
+ EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_PIN, LIB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_TABLE, LIB_EDIT_FRAME::OnOpenPinTable )
+ EVT_TOOL( ExportPartId, LIB_EDIT_FRAME::OnExportPart )
+ EVT_TOOL( CreateNewLibAndSavePartId, LIB_EDIT_FRAME::OnExportPart )
+ EVT_TOOL( ImportPartId, LIB_EDIT_FRAME::OnImportPart )
+
+ EVT_COMBOBOX( ID_LIBEDIT_SELECT_PART_NUMBER, LIB_EDIT_FRAME::OnSelectPart )
+ EVT_COMBOBOX( ID_LIBEDIT_SELECT_ALIAS, LIB_EDIT_FRAME::OnSelectAlias )
+
+ // Right vertical toolbar.
+ EVT_TOOL( ID_NO_TOOL_SELECTED, LIB_EDIT_FRAME::OnSelectTool )
+ EVT_TOOL_RANGE( ID_LIBEDIT_PIN_BUTT, ID_LIBEDIT_DELETE_ITEM_BUTT,
+ LIB_EDIT_FRAME::OnSelectTool )
+
+ // menubar commands
+ EVT_MENU( wxID_EXIT, LIB_EDIT_FRAME::CloseWindow )
+ EVT_MENU( ID_LIBEDIT_SAVE_CURRENT_LIB_AS, LIB_EDIT_FRAME::OnSaveActiveLibrary )
+ EVT_MENU( ID_LIBEDIT_GEN_PNG_FILE, LIB_EDIT_FRAME::OnPlotCurrentComponent )
+ EVT_MENU( ID_LIBEDIT_GEN_SVG_FILE, LIB_EDIT_FRAME::OnPlotCurrentComponent )
+ EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_INDEX, EDA_DRAW_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::GetKicadAbout )
+
+ EVT_MENU( ID_COLORS_SETUP, LIB_EDIT_FRAME::OnColorConfig )
+ EVT_MENU( wxID_PREFERENCES, LIB_EDIT_FRAME::OnPreferencesOptions )
+ EVT_MENU( ID_CONFIG_REQ, LIB_EDIT_FRAME::InstallConfigFrame )
+ EVT_MENU( ID_COLORS_SETUP, LIB_EDIT_FRAME::Process_Config )
+
+ // Multiple item selection context menu commands.
+ EVT_MENU_RANGE( ID_SELECT_ITEM_START, ID_SELECT_ITEM_END, LIB_EDIT_FRAME::OnSelectItem )
+
+ EVT_MENU_RANGE( ID_PREFERENCES_HOTKEY_START, ID_PREFERENCES_HOTKEY_END,
+ LIB_EDIT_FRAME::Process_Config )
+
+ // Context menu events and commands.
+ EVT_MENU( ID_LIBEDIT_EDIT_PIN, LIB_EDIT_FRAME::OnEditPin )
+ EVT_MENU( ID_LIBEDIT_ROTATE_ITEM, LIB_EDIT_FRAME::OnRotateItem )
+
+ EVT_MENU_RANGE( ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_ITEM,
+ ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT,
+ LIB_EDIT_FRAME::Process_Special_Functions )
+
+ EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE,
+ LIB_EDIT_FRAME::Process_Special_Functions )
+
+ // Update user interface elements.
+ EVT_UPDATE_UI( ExportPartId, LIB_EDIT_FRAME::OnUpdateEditingPart )
+ EVT_UPDATE_UI( CreateNewLibAndSavePartId, LIB_EDIT_FRAME::OnUpdateEditingPart )
+ EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
+ EVT_UPDATE_UI( ID_LIBEDIT_GET_FRAME_EDIT_FIELDS, LIB_EDIT_FRAME::OnUpdateEditingPart )
+ EVT_UPDATE_UI( ID_LIBEDIT_CHECK_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
+ EVT_UPDATE_UI( ID_LIBEDIT_GET_FRAME_EDIT_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
+ EVT_UPDATE_UI( ID_LIBEDIT_NEW_PART_FROM_EXISTING, LIB_EDIT_FRAME::OnUpdateEditingPart )
+ EVT_UPDATE_UI( wxID_UNDO, LIB_EDIT_FRAME::OnUpdateUndo )
+ EVT_UPDATE_UI( wxID_REDO, LIB_EDIT_FRAME::OnUpdateRedo )
+ EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_LIB, LIB_EDIT_FRAME::OnUpdateSaveCurrentLib )
+ EVT_UPDATE_UI( ID_LIBEDIT_VIEW_DOC, LIB_EDIT_FRAME::OnUpdateViewDoc )
+ EVT_UPDATE_UI( ID_LIBEDIT_EDIT_PIN_BY_PIN, LIB_EDIT_FRAME::OnUpdatePinByPin )
+ EVT_UPDATE_UI( ID_LIBEDIT_EDIT_PIN_BY_TABLE, LIB_EDIT_FRAME::OnUpdatePinTable )
+ EVT_UPDATE_UI( ID_LIBEDIT_SELECT_PART_NUMBER, LIB_EDIT_FRAME::OnUpdatePartNumber )
+ EVT_UPDATE_UI( ID_LIBEDIT_SELECT_ALIAS, LIB_EDIT_FRAME::OnUpdateSelectAlias )
+ EVT_UPDATE_UI( ID_DE_MORGAN_NORMAL_BUTT, LIB_EDIT_FRAME::OnUpdateDeMorganNormal )
+ EVT_UPDATE_UI( ID_DE_MORGAN_CONVERT_BUTT, LIB_EDIT_FRAME::OnUpdateDeMorganConvert )
+ EVT_UPDATE_UI( ID_NO_TOOL_SELECTED, LIB_EDIT_FRAME::OnUpdateEditingPart )
+ EVT_UPDATE_UI_RANGE( ID_LIBEDIT_PIN_BUTT, ID_LIBEDIT_DELETE_ITEM_BUTT,
+ LIB_EDIT_FRAME::OnUpdateEditingPart )
+END_EVENT_TABLE()
+
+#define LIB_EDIT_FRAME_NAME wxT( "LibeditFrame" )
+
+LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
+ SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_LIB_EDITOR, _( "Library Editor" ),
+ wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, LIB_EDIT_FRAME_NAME )
+{
+ wxASSERT( aParent );
+
+ m_showAxis = true; // true to draw axis
+ SetShowDeMorgan( false );
+ m_drawSpecificConvert = true;
+ m_drawSpecificUnit = false;
+ m_hotkeysDescrList = g_Libedit_Hokeys_Descr;
+ m_editPinsPerPartOrConvert = false;
+ m_repeatPinStep = DEFAULT_REPEAT_OFFSET_PIN;
+
+ m_my_part = NULL;
+ m_tempCopyComponent = NULL;
+
+ // Delayed initialization
+ if( m_textSize == -1 )
+ m_textSize = GetDefaultTextSize();
+
+ // Initialize grid id to the default value 50 mils:
+ m_LastGridSizeId = ID_POPUP_GRID_LEVEL_50 - ID_POPUP_GRID_LEVEL_1000;
+
+ wxIcon icon;
+ icon.CopyFromBitmap( KiBitmap( libedit_icon_xpm ) );
+ SetIcon( icon );
+
+ LoadSettings( config() );
+
+ SetScreen( new SCH_SCREEN( aKiway ) );
+ GetScreen()->m_Center = true;
+ GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
+
+ SetCrossHairPosition( wxPoint( 0, 0 ) );
+
+ // Ensure m_LastGridSizeId is an offset inside the allowed schematic range
+ if( m_LastGridSizeId < ID_POPUP_GRID_LEVEL_50 - ID_POPUP_GRID_LEVEL_1000 )
+ m_LastGridSizeId = ID_POPUP_GRID_LEVEL_50 - ID_POPUP_GRID_LEVEL_1000;
+
+ if( m_LastGridSizeId > ID_POPUP_GRID_LEVEL_1 - ID_POPUP_GRID_LEVEL_1000 )
+ m_LastGridSizeId = ID_POPUP_GRID_LEVEL_1 - ID_POPUP_GRID_LEVEL_1000;
+
+ SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
+
+ GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
+
+ if( m_canvas )
+ m_canvas->SetEnableBlockCommands( true );
+
+ ReCreateMenuBar();
+ ReCreateHToolbar();
+ ReCreateVToolbar();
+
+ // Ensure the current alias name is valid if a part is loaded
+ // Sometimes it is not valid. This is the case
+ // when a part value (the part lib name), or the alias list was modified
+ // during a previous session and the modifications not saved in lib.
+ // Reopen libedit in a new session gives a non valid m_aliasName
+ // because the curr part is reloaded from the library (and this is the unmodified part)
+ // and the old alias name (from the previous edition) can be invalid
+ LIB_PART* part = GetCurPart();
+
+ if( part == NULL )
+ m_aliasName.Empty();
+ else if( m_aliasName != part->GetName() )
+ {
+ LIB_ALIAS* alias = part->GetAlias( m_aliasName );
+
+ if( !alias )
+ m_aliasName = part->GetName();
+ }
+
+
+ CreateOptionToolbar();
+ DisplayLibInfos();
+ DisplayCmpDoc();
+ UpdateAliasSelectList();
+ UpdatePartSelectList();
+
+ m_auimgr.SetManagedWindow( this );
+
+ EDA_PANEINFO horiz;
+ horiz.HorizontalToolbarPane();
+
+ EDA_PANEINFO vert;
+ vert.VerticalToolbarPane();
+
+ EDA_PANEINFO mesg;
+ mesg.MessageToolbarPane();
+
+ m_auimgr.AddPane( m_mainToolBar,
+ wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top().Row( 0 ) );
+
+ m_auimgr.AddPane( m_drawToolBar,
+ wxAuiPaneInfo( vert ).Name( wxT( "m_VToolBar" ) ).Right() );
+
+ m_auimgr.AddPane( m_optionsToolBar,
+ wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ).Left() );
+
+ m_auimgr.AddPane( m_canvas,
+ wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
+
+ m_auimgr.AddPane( m_messagePanel,
+ wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );
+
+ m_auimgr.Update();
+
+ Raise();
+ Show( true );
+
+ wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED, ID_ZOOM_PAGE );
+ wxPostEvent( this, evt );
+}
+
+
+LIB_EDIT_FRAME::~LIB_EDIT_FRAME()
+{
+ m_drawItem = m_lastDrawItem = NULL;
+
+ delete m_tempCopyComponent;
+ delete m_my_part;
+ m_my_part = NULL;
+ m_tempCopyComponent = NULL;
+}
+
+
+void LIB_EDIT_FRAME::SetDrawItem( LIB_ITEM* drawItem )
+{
+ m_drawItem = drawItem;
+}
+
+
+void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
+{
+ if( GetScreen()->IsModify() )
+ {
+ int ii = DisplayExitDialog( this, _( "Save the changes in the library before closing?" ) );
+
+ switch( ii )
+ {
+ case wxID_NO:
+ break;
+
+ case wxID_YES:
+ if ( this->SaveActiveLibrary( false ) )
+ break;
+
+ // fall through: cancel the close because of an error
+
+ case wxID_CANCEL:
+ Event.Veto();
+ return;
+ }
+ GetScreen()->ClrModify();
+ }
+
+ PART_LIBS* libs = Prj().SchLibs();
+
+ BOOST_FOREACH( const PART_LIB& lib, *libs )
+ {
+ if( lib.IsModified() )
+ {
+ wxString msg = wxString::Format( _(
+ "Library '%s' was modified!\nDiscard changes?" ),
+ GetChars( lib.GetName() )
+ );
+
+ if( !IsOK( this, msg ) )
+ {
+ Event.Veto();
+ return;
+ }
+ }
+ }
+
+ Destroy();
+}
+
+
+double LIB_EDIT_FRAME::BestZoom()
+{
+ /* Please, note: wxMSW before version 2.9 seems have
+ * problems with zoom values < 1 ( i.e. userscale > 1) and needs to be patched:
+ * edit file <wxWidgets>/src/msw/dc.cpp
+ * search for line static const int VIEWPORT_EXTENT = 1000;
+ * and replace by static const int VIEWPORT_EXTENT = 10000;
+ */
+ int dx, dy;
+
+ LIB_PART* part = GetCurPart();
+
+ if( part )
+ {
+ EDA_RECT boundingBox = part->GetBoundingBox( m_unit, m_convert );
+
+ dx = boundingBox.GetWidth();
+ dy = boundingBox.GetHeight();
+ SetScrollCenterPosition( wxPoint( 0, 0 ) );
+ }
+ else
+ {
+ const PAGE_INFO& pageInfo = GetScreen()->GetPageSettings();
+
+ dx = pageInfo.GetSizeIU().x;
+ dy = pageInfo.GetSizeIU().y;
+
+ SetScrollCenterPosition( wxPoint( 0, 0 ) );
+ }
+
+ wxSize size = m_canvas->GetClientSize();
+
+ // Reserve a 10% margin around component bounding box.
+ double margin_scale_factor = 0.8;
+ double zx =(double) dx / ( margin_scale_factor * (double)size.x );
+ double zy = (double) dy / ( margin_scale_factor * (double)size.y );
+
+ double bestzoom = std::max( zx, zy );
+
+ // keep it >= minimal existing zoom (can happen for very small components
+ // for instance when starting a new component
+ if( bestzoom < GetScreen()->m_ZoomList[0] )
+ bestzoom = GetScreen()->m_ZoomList[0];
+
+ return bestzoom;
+}
+
+
+void LIB_EDIT_FRAME::UpdateAliasSelectList()
+{
+ if( m_aliasSelectBox == NULL )
+ return;
+
+ m_aliasSelectBox->Clear();
+
+ LIB_PART* part = GetCurPart();
+
+ if( !part )
+ return;
+
+ m_aliasSelectBox->Append( part->GetAliasNames() );
+ m_aliasSelectBox->SetSelection( 0 );
+
+ int index = m_aliasSelectBox->FindString( m_aliasName );
+
+ if( index != wxNOT_FOUND )
+ m_aliasSelectBox->SetSelection( index );
+}
+
+
+void LIB_EDIT_FRAME::UpdatePartSelectList()
+{
+ if( m_partSelectBox == NULL )
+ return;
+
+ if( m_partSelectBox->GetCount() != 0 )
+ m_partSelectBox->Clear();
+
+ LIB_PART* part = GetCurPart();
+
+ if( !part || part->GetUnitCount() <= 1 )
+ {
+ m_unit = 1;
+ m_partSelectBox->Append( wxEmptyString );
+ }
+ else
+ {
+ for( int i = 0; i < part->GetUnitCount(); i++ )
+ {
+ wxString sub = LIB_PART::SubReference( i+1, false );
+ wxString unit = wxString::Format( _( "Unit %s" ), GetChars( sub ) );
+ m_partSelectBox->Append( unit );
+ }
+ }
+
+ // Ensure the current selected unit is compatible with
+ // the number of units of the current part:
+ if( part && part->GetUnitCount() < m_unit )
+ m_unit = 1;
+
+ m_partSelectBox->SetSelection( ( m_unit > 0 ) ? m_unit - 1 : 0 );
+}
+
+
+void LIB_EDIT_FRAME::OnUpdateEditingPart( wxUpdateUIEvent& aEvent )
+{
+ LIB_PART* part = GetCurPart();
+
+ aEvent.Enable( part != NULL );
+
+ if( part && aEvent.GetEventObject() == m_drawToolBar )
+ aEvent.Check( GetToolId() == aEvent.GetId() );
+}
+
+
+void LIB_EDIT_FRAME::OnUpdateNotEditingPart( wxUpdateUIEvent& event )
+{
+ event.Enable( !GetCurPart() );
+}
+
+
+void LIB_EDIT_FRAME::OnUpdateUndo( wxUpdateUIEvent& event )
+{
+ event.Enable( GetCurPart() && GetScreen() &&
+ GetScreen()->GetUndoCommandCount() != 0 && !IsEditingDrawItem() );
+}
+
+
+void LIB_EDIT_FRAME::OnUpdateRedo( wxUpdateUIEvent& event )
+{
+ event.Enable( GetCurPart() && GetScreen() &&
+ GetScreen()->GetRedoCommandCount() != 0 && !IsEditingDrawItem() );
+}
+
+
+void LIB_EDIT_FRAME::OnUpdateSaveCurrentLib( wxUpdateUIEvent& event )
+{
+ PART_LIB* lib = GetCurLib();
+
+ event.Enable( lib && !lib->IsReadOnly()
+ && ( lib->IsModified() || GetScreen()->IsModify() ) );
+}
+
+
+void LIB_EDIT_FRAME::OnUpdateViewDoc( wxUpdateUIEvent& event )
+{
+ bool enable = false;
+
+ PART_LIB* lib = GetCurLib();
+ LIB_PART* part = GetCurPart();
+
+ if( part && lib )
+ {
+ LIB_ALIAS* alias = part->GetAlias( m_aliasName );
+
+ wxCHECK_RET( alias != NULL, wxT( "Alias <" ) + m_aliasName + wxT( "> not found." ) );
+
+ enable = !alias->GetDocFileName().IsEmpty();
+ }
+
+ event.Enable( enable );
+}
+
+
+void LIB_EDIT_FRAME::OnUpdatePinByPin( wxUpdateUIEvent& event )
+{
+ LIB_PART* part = GetCurPart();
+
+ event.Enable( part && ( part->GetUnitCount() > 1 || m_showDeMorgan ) );
+
+ event.Check( m_editPinsPerPartOrConvert );
+}
+
+void LIB_EDIT_FRAME::OnUpdatePinTable( wxUpdateUIEvent& event )
+{
+ LIB_PART* part = GetCurPart();
+ event.Enable( part != NULL );
+}
+
+void LIB_EDIT_FRAME::OnUpdatePartNumber( wxUpdateUIEvent& event )
+{
+ if( m_partSelectBox == NULL )
+ return;
+
+ LIB_PART* part = GetCurPart();
+
+ // Using the typical event.Enable() call doesn't seem to work with wxGTK
+ // so use the pointer to alias combobox to directly enable or disable.
+ m_partSelectBox->Enable( part && part->GetUnitCount() > 1 );
+}
+
+
+void LIB_EDIT_FRAME::OnUpdateDeMorganNormal( wxUpdateUIEvent& event )
+{
+ if( m_mainToolBar == NULL )
+ return;
+
+ LIB_PART* part = GetCurPart();
+
+ event.Enable( GetShowDeMorgan() || ( part && part->HasConversion() ) );
+ event.Check( m_convert <= 1 );
+}
+
+
+void LIB_EDIT_FRAME::OnUpdateDeMorganConvert( wxUpdateUIEvent& event )
+{
+ if( m_mainToolBar == NULL )
+ return;
+
+ LIB_PART* part = GetCurPart();
+
+ event.Enable( GetShowDeMorgan() || ( part && part->HasConversion() ) );
+ event.Check( m_convert > 1 );
+}
+
+
+void LIB_EDIT_FRAME::OnUpdateSelectAlias( wxUpdateUIEvent& event )
+{
+ if( m_aliasSelectBox == NULL )
+ return;
+
+ LIB_PART* part = GetCurPart();
+
+ // Using the typical event.Enable() call doesn't seem to work with wxGTK
+ // so use the pointer to alias combobox to directly enable or disable.
+ m_aliasSelectBox->Enable( part && part->GetAliasCount() > 1 );
+}
+
+
+void LIB_EDIT_FRAME::OnSelectAlias( wxCommandEvent& event )
+{
+ if( m_aliasSelectBox == NULL
+ || ( m_aliasSelectBox->GetStringSelection().CmpNoCase( m_aliasName ) == 0) )
+ return;
+
+ m_lastDrawItem = NULL;
+ m_aliasName = m_aliasSelectBox->GetStringSelection();
+
+ DisplayCmpDoc();
+ m_canvas->Refresh();
+}
+
+
+void LIB_EDIT_FRAME::OnSelectPart( wxCommandEvent& event )
+{
+ int i = event.GetSelection();
+
+ if( ( i == wxNOT_FOUND ) || ( ( i + 1 ) == m_unit ) )
+ return;
+
+ m_lastDrawItem = NULL;
+ m_unit = i + 1;
+ m_canvas->Refresh();
+ DisplayCmpDoc();
+}
+
+
+void LIB_EDIT_FRAME::OnViewEntryDoc( wxCommandEvent& event )
+{
+ LIB_PART* part = GetCurPart();
+
+ if( !part )
+ return;
+
+ wxString fileName;
+ LIB_ALIAS* alias = part->GetAlias( m_aliasName );
+
+ wxCHECK_RET( alias != NULL, wxT( "Alias not found." ) );
+
+ fileName = alias->GetDocFileName();
+
+ if( !fileName.IsEmpty() )
+ {
+ SEARCH_STACK* lib_search = Prj().SchSearchS();
+
+ GetAssociatedDocument( this, fileName, lib_search );
+ }
+}
+
+
+void LIB_EDIT_FRAME::OnSelectBodyStyle( wxCommandEvent& event )
+{
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+
+ if( event.GetId() == ID_DE_MORGAN_NORMAL_BUTT )
+ m_convert = 1;
+ else
+ m_convert = 2;
+
+ m_lastDrawItem = NULL;
+ m_canvas->Refresh();
+}
+
+
+void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ wxPoint pos;
+
+ m_canvas->SetIgnoreMouseEvents( true );
+
+ wxGetMousePosition( &pos.x, &pos.y );
+ pos.y += 20;
+
+ switch( id ) // Stop placement commands before handling new command.
+ {
+ case ID_POPUP_LIBEDIT_END_CREATE_ITEM:
+ case ID_LIBEDIT_EDIT_PIN:
+ case ID_POPUP_LIBEDIT_BODY_EDIT_ITEM:
+ case ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM:
+ case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM:
+ case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM:
+ case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM:
+ case ID_POPUP_ZOOM_BLOCK:
+ case ID_POPUP_DELETE_BLOCK:
+ case ID_POPUP_COPY_BLOCK:
+ case ID_POPUP_SELECT_ITEMS_BLOCK:
+ case ID_POPUP_MIRROR_X_BLOCK:
+ case ID_POPUP_MIRROR_Y_BLOCK:
+ case ID_POPUP_ROTATE_BLOCK:
+ case ID_POPUP_PLACE_BLOCK:
+ case ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT:
+ break;
+
+ case ID_POPUP_LIBEDIT_CANCEL_EDITING:
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->EndMouseCapture();
+ else
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+ break;
+
+ case ID_POPUP_LIBEDIT_DELETE_ITEM:
+ m_canvas->EndMouseCapture();
+ break;
+
+ default:
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(),
+ wxEmptyString );
+ break;
+ }
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ switch( id )
+ {
+ case ID_POPUP_LIBEDIT_CANCEL_EDITING:
+ break;
+
+ case ID_LIBEDIT_SELECT_CURRENT_LIB:
+ SelectActiveLibrary();
+ break;
+
+ case ID_LIBEDIT_SAVE_CURRENT_PART:
+ {
+ LIB_PART* part = GetCurPart();
+
+ if( !part )
+ {
+ DisplayError( this, _( "No part to save." ) );
+ break;
+ }
+
+ PART_LIB* lib = GetCurLib();
+
+ if( !lib )
+ SelectActiveLibrary();
+
+ lib = GetCurLib();
+
+ if( !lib )
+ {
+ DisplayError( this, _( "No library specified." ) );
+ break;
+ }
+
+ SaveOnePart( lib );
+ }
+ break;
+
+ case ID_LIBEDIT_EDIT_PIN_BY_PIN:
+ m_editPinsPerPartOrConvert = m_mainToolBar->GetToolToggled( ID_LIBEDIT_EDIT_PIN_BY_PIN );
+ break;
+
+ case ID_POPUP_LIBEDIT_END_CREATE_ITEM:
+ m_canvas->MoveCursorToCrossHair();
+ if( m_drawItem )
+ {
+ EndDrawGraphicItem( &dc );
+ }
+ break;
+
+ case ID_POPUP_LIBEDIT_BODY_EDIT_ITEM:
+ if( m_drawItem )
+ {
+ m_canvas->CrossHairOff( &dc );
+
+ switch( m_drawItem->Type() )
+ {
+ case LIB_ARC_T:
+ case LIB_CIRCLE_T:
+ case LIB_RECTANGLE_T:
+ case LIB_POLYLINE_T:
+ EditGraphicSymbol( &dc, m_drawItem );
+ break;
+
+ case LIB_TEXT_T:
+ EditSymbolText( &dc, m_drawItem );
+ break;
+
+ default:
+ ;
+ }
+
+ m_canvas->CrossHairOn( &dc );
+ }
+ break;
+
+ case ID_POPUP_LIBEDIT_DELETE_CURRENT_POLY_SEGMENT:
+ {
+ // Delete the last created segment, while creating a polyline draw item
+ if( m_drawItem == NULL )
+ break;
+
+ m_canvas->MoveCursorToCrossHair();
+ STATUS_FLAGS oldFlags = m_drawItem->GetFlags();
+ m_drawItem->ClearFlags();
+ m_drawItem->Draw( m_canvas, &dc, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode, NULL,
+ DefaultTransform );
+ ( (LIB_POLYLINE*) m_drawItem )->DeleteSegment( GetCrossHairPosition( true ) );
+ m_drawItem->Draw( m_canvas, &dc, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode, NULL,
+ DefaultTransform );
+ m_drawItem->SetFlags( oldFlags );
+ m_lastDrawItem = NULL;
+ }
+ break;
+
+ case ID_POPUP_LIBEDIT_DELETE_ITEM:
+ if( m_drawItem )
+ deleteItem( &dc );
+
+ break;
+
+ case ID_POPUP_LIBEDIT_MOVE_ITEM_REQUEST:
+ if( m_drawItem == NULL )
+ break;
+
+ if( m_drawItem->Type() == LIB_PIN_T )
+ StartMovePin( &dc );
+ else
+ StartMoveDrawSymbol( &dc );
+ break;
+
+ case ID_POPUP_LIBEDIT_MODIFY_ITEM:
+
+ if( m_drawItem == NULL )
+ break;
+
+ m_canvas->MoveCursorToCrossHair();
+ if( m_drawItem->Type() == LIB_RECTANGLE_T
+ || m_drawItem->Type() == LIB_CIRCLE_T
+ || m_drawItem->Type() == LIB_POLYLINE_T
+ || m_drawItem->Type() == LIB_ARC_T
+ )
+ {
+ StartModifyDrawSymbol( &dc );
+ }
+
+ break;
+
+ case ID_POPUP_LIBEDIT_FIELD_EDIT_ITEM:
+ if( m_drawItem == NULL )
+ break;
+
+ m_canvas->CrossHairOff( &dc );
+
+ if( m_drawItem->Type() == LIB_FIELD_T )
+ {
+ EditField( (LIB_FIELD*) m_drawItem );
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->CrossHairOn( &dc );
+ break;
+
+ case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM:
+ case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM:
+ case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM:
+ {
+ if( !m_drawItem || m_drawItem->Type() != LIB_PIN_T )
+ break;
+
+ LIB_PART* part = GetCurPart();
+
+ SaveCopyInUndoList( part );
+
+ GlobalSetPins( (LIB_PIN*) m_drawItem, id );
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->Refresh();
+ }
+ break;
+
+ case ID_POPUP_ZOOM_BLOCK:
+ m_canvas->SetAutoPanRequest( false );
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_ZOOM );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_DELETE_BLOCK:
+ m_canvas->SetAutoPanRequest( false );
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_DELETE );
+ m_canvas->MoveCursorToCrossHair();
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_COPY_BLOCK:
+ m_canvas->SetAutoPanRequest( false );
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_COPY );
+ m_canvas->MoveCursorToCrossHair();
+ HandleBlockPlace( &dc );
+ break;
+
+ case ID_POPUP_SELECT_ITEMS_BLOCK:
+ m_canvas->SetAutoPanRequest( false );
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_SELECT_ITEMS_ONLY );
+ m_canvas->MoveCursorToCrossHair();
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_MIRROR_Y_BLOCK:
+ m_canvas->SetAutoPanRequest( false );
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_MIRROR_Y );
+ m_canvas->MoveCursorToCrossHair();
+ HandleBlockPlace( &dc );
+ break;
+
+ case ID_POPUP_MIRROR_X_BLOCK:
+ m_canvas->SetAutoPanRequest( false );
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_MIRROR_X );
+ m_canvas->MoveCursorToCrossHair();
+ HandleBlockPlace( &dc );
+ break;
+
+ case ID_POPUP_ROTATE_BLOCK:
+ m_canvas->SetAutoPanRequest( false );
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_ROTATE );
+ m_canvas->MoveCursorToCrossHair();
+ HandleBlockPlace( &dc );
+ break;
+
+ case ID_POPUP_PLACE_BLOCK:
+ m_canvas->SetAutoPanRequest( false );
+ m_canvas->MoveCursorToCrossHair();
+ HandleBlockPlace( &dc );
+ break;
+
+ default:
+ DisplayError( this, wxT( "LIB_EDIT_FRAME::Process_Special_Functions error" ) );
+ break;
+ }
+
+ m_canvas->SetIgnoreMouseEvents( false );
+
+ if( GetToolId() == ID_NO_TOOL_SELECTED )
+ m_lastDrawItem = NULL;
+}
+
+
+void LIB_EDIT_FRAME::OnActivate( wxActivateEvent& event )
+{
+ EDA_DRAW_FRAME::OnActivate( event );
+}
+
+
+PART_LIB* LIB_EDIT_FRAME::GetCurLib()
+{
+ wxString name = Prj().GetRString( PROJECT::SCH_LIBEDIT_CUR_LIB );
+
+ if( !!name )
+ {
+ PART_LIB* lib = Prj().SchLibs()->FindLibrary( name );
+
+ if( !lib )
+ Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, wxEmptyString );
+
+ return lib;
+ }
+
+ return NULL;
+}
+
+
+PART_LIB* LIB_EDIT_FRAME::SetCurLib( PART_LIB* aLib )
+{
+ PART_LIB* old = GetCurLib();
+
+ if( !aLib || !aLib->GetName() )
+ Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, wxEmptyString );
+ else
+ Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, aLib->GetName() );
+
+ return old;
+}
+
+
+LIB_PART* LIB_EDIT_FRAME::GetCurPart()
+{
+ if( !m_my_part )
+ {
+ wxString name = Prj().GetRString( PROJECT::SCH_LIBEDIT_CUR_PART );
+ LIB_PART* part;
+
+ if( !!name && ( part = Prj().SchLibs()->FindLibPart( name ) ) )
+ {
+ // clone it from the PART_LIB and own it.
+ m_my_part = new LIB_PART( *part );
+ }
+ else
+ Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_PART, wxEmptyString );
+ }
+
+ return m_my_part;
+}
+
+
+void LIB_EDIT_FRAME::SetCurPart( LIB_PART* aPart )
+{
+ delete m_my_part;
+ m_my_part = aPart; // take ownership here
+
+ // retain in case this wxFrame is re-opened later on the same PROJECT
+ Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_PART,
+ aPart ? aPart->GetName() : wxString() );
+}
+
+
+void LIB_EDIT_FRAME::TempCopyComponent()
+{
+ delete m_tempCopyComponent;
+
+ if( LIB_PART* part = GetCurPart() )
+ // clone it and own the clone.
+ m_tempCopyComponent = new LIB_PART( *part );
+ else
+ // clear it, there was no CurPart
+ m_tempCopyComponent = NULL;
+}
+
+
+void LIB_EDIT_FRAME::RestoreComponent()
+{
+ if( m_tempCopyComponent )
+ {
+ // transfer ownership to CurPart
+ SetCurPart( m_tempCopyComponent );
+ m_tempCopyComponent = NULL;
+ }
+}
+
+
+void LIB_EDIT_FRAME::ClearTempCopyComponent()
+{
+ delete m_tempCopyComponent;
+ m_tempCopyComponent = NULL;
+}
+
+
+void LIB_EDIT_FRAME::EditSymbolText( wxDC* DC, LIB_ITEM* DrawItem )
+{
+ if ( ( DrawItem == NULL ) || ( DrawItem->Type() != LIB_TEXT_T ) )
+ return;
+
+ // Deleting old text
+ if( DC && !DrawItem->InEditMode() )
+ DrawItem->Draw( m_canvas, DC, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode, NULL,
+ DefaultTransform );
+
+ DIALOG_LIB_EDIT_TEXT* frame = new DIALOG_LIB_EDIT_TEXT( this, (LIB_TEXT*) DrawItem );
+ frame->ShowModal();
+ frame->Destroy();
+ OnModify();
+
+ // Display new text
+ if( DC && !DrawItem->InEditMode() )
+ DrawItem->Draw( m_canvas, DC, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, GR_DEFAULT_DRAWMODE, NULL,
+ DefaultTransform );
+}
+
+
+void LIB_EDIT_FRAME::OnEditComponentProperties( wxCommandEvent& event )
+{
+ bool partLocked = GetCurPart()->UnitsLocked();
+
+ DIALOG_EDIT_COMPONENT_IN_LIBRARY dlg( this );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ if( partLocked != GetCurPart()->UnitsLocked() )
+ {
+ // m_editPinsPerPartOrConvert is set to the better value, if m_UnitSelectionLocked
+ // has changed
+ m_editPinsPerPartOrConvert = GetCurPart()->UnitsLocked() ? true : false;
+ }
+
+ UpdateAliasSelectList();
+ UpdatePartSelectList();
+ DisplayLibInfos();
+ DisplayCmpDoc();
+ OnModify();
+ m_canvas->Refresh();
+}
+
+
+void LIB_EDIT_FRAME::OnCreateNewPartFromExisting( wxCommandEvent& event )
+{
+ LIB_PART* part = GetCurPart();
+
+ wxCHECK_RET( part, wxT( "Cannot create new part from non-existent current part." ) );
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+ m_canvas->CrossHairOff( &dc );
+
+ EditField( &part->GetValueField() );
+
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->CrossHairOn( &dc );
+}
+
+
+void LIB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent )
+{
+ int id = aEvent.GetId();
+
+ if( GetToolId() == ID_NO_TOOL_SELECTED )
+ m_lastDrawItem = NULL;
+
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(),
+ wxEmptyString );
+
+ LIB_PART* part = GetCurPart();
+
+ switch( id )
+ {
+ case ID_NO_TOOL_SELECTED:
+ SetToolID( id, m_canvas->GetDefaultCursor(), wxEmptyString );
+ break;
+
+ case ID_LIBEDIT_PIN_BUTT:
+ if( part )
+ {
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add pin" ) );
+ }
+ else
+ {
+ SetToolID( id, wxCURSOR_ARROW, _( "Set pin options" ) );
+
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+
+ cmd.SetId( ID_LIBEDIT_EDIT_PIN );
+ GetEventHandler()->ProcessEvent( cmd );
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ }
+ break;
+
+ case ID_LIBEDIT_BODY_TEXT_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) );
+ break;
+
+ case ID_LIBEDIT_BODY_RECT_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add rectangle" ) );
+ break;
+
+ case ID_LIBEDIT_BODY_CIRCLE_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add circle" ) );
+ break;
+
+ case ID_LIBEDIT_BODY_ARC_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add arc" ) );
+ break;
+
+ case ID_LIBEDIT_BODY_LINE_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add line" ) );
+ break;
+
+ case ID_LIBEDIT_ANCHOR_ITEM_BUTT:
+ SetToolID( id, wxCURSOR_HAND, _( "Set anchor position" ) );
+ break;
+
+ case ID_LIBEDIT_IMPORT_BODY_BUTT:
+ SetToolID( id, m_canvas->GetDefaultCursor(), _( "Import" ) );
+ LoadOneSymbol();
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ break;
+
+ case ID_LIBEDIT_EXPORT_BODY_BUTT:
+ SetToolID( id, m_canvas->GetDefaultCursor(), _( "Export" ) );
+ SaveOneSymbol();
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ break;
+
+ case ID_LIBEDIT_DELETE_ITEM_BUTT:
+ if( !part )
+ {
+ wxBell();
+ break;
+ }
+
+ SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
+ break;
+
+ default:
+ break;
+ }
+
+ m_canvas->SetIgnoreMouseEvents( false );
+}
+
+
+void LIB_EDIT_FRAME::OnRotateItem( wxCommandEvent& aEvent )
+{
+ if( m_drawItem == NULL )
+ return;
+
+ if( !m_drawItem->InEditMode() )
+ {
+ LIB_PART* part = GetCurPart();
+
+ SaveCopyInUndoList( part );
+ m_drawItem->SetUnit( m_unit );
+ }
+
+ m_drawItem->Rotate();
+ OnModify();
+
+ if( !m_drawItem->InEditMode() )
+ m_drawItem->ClearFlags();
+
+ m_canvas->Refresh();
+
+ if( GetToolId() == ID_NO_TOOL_SELECTED )
+ m_lastDrawItem = NULL;
+}
+
+
+LIB_ITEM* LIB_EDIT_FRAME::LocateItemUsingCursor( const wxPoint& aPosition,
+ const KICAD_T aFilterList[] )
+{
+ LIB_PART* part = GetCurPart();
+
+ if( !part )
+ return NULL;
+
+ LIB_ITEM* item = locateItem( aPosition, aFilterList );
+
+ wxPoint pos = GetNearestGridPosition( aPosition );
+
+ if( item == NULL && aPosition != pos )
+ item = locateItem( pos, aFilterList );
+
+ return item;
+}
+
+
+LIB_ITEM* LIB_EDIT_FRAME::locateItem( const wxPoint& aPosition, const KICAD_T aFilterList[] )
+{
+ LIB_PART* part = GetCurPart();
+
+ if( !part )
+ return NULL;
+
+ LIB_ITEM* item = NULL;
+
+ m_collectedItems.Collect( part->GetDrawItemList(), aFilterList, aPosition,
+ m_unit, m_convert );
+
+ if( m_collectedItems.GetCount() == 0 )
+ {
+ ClearMsgPanel();
+ }
+ else if( m_collectedItems.GetCount() == 1 )
+ {
+ item = m_collectedItems[0];
+ }
+ else
+ {
+ if( item == NULL )
+ {
+ wxASSERT_MSG( m_collectedItems.GetCount() <= MAX_SELECT_ITEM_IDS,
+ wxT( "Select item clarification context menu size limit exceeded." ) );
+
+ wxMenu selectMenu;
+ wxMenuItem* title = new wxMenuItem( &selectMenu, wxID_NONE, _( "Clarify Selection" ) );
+
+ selectMenu.Append( title );
+ selectMenu.AppendSeparator();
+
+ for( int i = 0; i < m_collectedItems.GetCount() && i < MAX_SELECT_ITEM_IDS; i++ )
+ {
+ wxString text = m_collectedItems[i]->GetSelectMenuText();
+ BITMAP_DEF xpm = m_collectedItems[i]->GetMenuImage();
+
+ AddMenuItem( &selectMenu, ID_SELECT_ITEM_START + i, text, KiBitmap( xpm ) );
+ }
+
+ // Set to NULL in case user aborts the clarification context menu.
+ m_drawItem = NULL;
+ m_canvas->SetAbortRequest( true ); // Changed to false if an item is selected
+ PopupMenu( &selectMenu );
+ m_canvas->MoveCursorToCrossHair();
+ item = m_drawItem;
+ }
+ }
+
+ if( item )
+ {
+ MSG_PANEL_ITEMS items;
+ item->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+ }
+ else
+ {
+ ClearMsgPanel();
+ }
+
+ return item;
+}
+
+
+void LIB_EDIT_FRAME::deleteItem( wxDC* aDC )
+{
+ wxCHECK_RET( m_drawItem != NULL, wxT( "No drawing item selected to delete." ) );
+
+ m_canvas->CrossHairOff( aDC );
+
+ LIB_PART* part = GetCurPart();
+
+ SaveCopyInUndoList( part );
+
+ if( m_drawItem->Type() == LIB_PIN_T )
+ {
+ LIB_PIN* pin = (LIB_PIN*) m_drawItem;
+ wxPoint pos = pin->GetPosition();
+
+ part->RemoveDrawItem( (LIB_ITEM*) pin, m_canvas, aDC );
+
+ if( SynchronizePins() )
+ {
+ LIB_PIN* tmp = part->GetNextPin();
+
+ while( tmp != NULL )
+ {
+ pin = tmp;
+ tmp = part->GetNextPin( pin );
+
+ if( pin->GetPosition() != pos )
+ continue;
+
+ part->RemoveDrawItem( (LIB_ITEM*) pin );
+ }
+ }
+
+ m_canvas->Refresh();
+ }
+ else
+ {
+ if( m_canvas->IsMouseCaptured() )
+ {
+ m_canvas->CallEndMouseCapture( aDC );
+ }
+ else
+ {
+ part->RemoveDrawItem( m_drawItem, m_canvas, aDC );
+ m_canvas->Refresh();
+ }
+ }
+
+ m_drawItem = NULL;
+ m_lastDrawItem = NULL;
+ OnModify();
+ m_canvas->CrossHairOn( aDC );
+}
+
+
+void LIB_EDIT_FRAME::OnSelectItem( wxCommandEvent& aEvent )
+{
+ int id = aEvent.GetId();
+ int index = id - ID_SELECT_ITEM_START;
+
+ if( (id >= ID_SELECT_ITEM_START && id <= ID_SELECT_ITEM_END)
+ && (index >= 0 && index < m_collectedItems.GetCount()) )
+ {
+ LIB_ITEM* item = m_collectedItems[index];
+ m_canvas->SetAbortRequest( false );
+ m_drawItem = item;
+ }
+}
+
+void LIB_EDIT_FRAME::OnOpenPinTable( wxCommandEvent& aEvent )
+{
+ LIB_PART* part = GetCurPart();
+
+ DIALOG_LIB_EDIT_PIN_TABLE dlg( this, *part );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ return;
+}
+
+bool LIB_EDIT_FRAME::SynchronizePins()
+{
+ LIB_PART* part = GetCurPart();
+
+ return !m_editPinsPerPartOrConvert && ( part &&
+ ( part->HasConversion() || part->IsMulti() ) );
+}
diff --git a/eeschema/libeditframe.h b/eeschema/libeditframe.h
new file mode 100644
index 0000000..3964840
--- /dev/null
+++ b/eeschema/libeditframe.h
@@ -0,0 +1,678 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2014 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file libeditframe.h
+ * @brief Definition of class LIB_EDIT_FRAME
+ */
+
+#ifndef LIBEDITFRM_H_
+#define LIBEDITFRM_H_
+
+#include <sch_base_frame.h>
+#include <class_sch_screen.h>
+
+#include <lib_draw_item.h>
+#include <lib_collectors.h>
+
+
+class SCH_EDIT_FRAME;
+class PART_LIB;
+class LIB_PART;
+class LIB_ALIAS;
+class LIB_FIELD;
+class DIALOG_LIB_EDIT_TEXT;
+
+/**
+ * The component library editor main window.
+ */
+class LIB_EDIT_FRAME : public SCH_BASE_FRAME
+{
+ LIB_PART* m_my_part; ///< a part I own, it is not in any library, but a copy could be.
+ LIB_PART* m_tempCopyComponent; ///< temp copy of a part during edit, I own it here.
+ LIB_COLLECTOR m_collectedItems; ///< Used for hit testing.
+ wxComboBox* m_partSelectBox; ///< a Box to select a part to edit (if any)
+ wxComboBox* m_aliasSelectBox; ///< a box to select the alias to edit (if any)
+
+ /** Convert of the item currently being drawn. */
+ bool m_drawSpecificConvert;
+
+ /**
+ * Specify which component parts the current draw item applies to.
+ *
+ * If true, the item being drawn or edited applies only to the selected
+ * part. Otherwise it applies to all parts in the component.
+ */
+ bool m_drawSpecificUnit;
+
+ /**
+ * Set to true to not synchronize pins at the same position when editing
+ * components with multiple parts or multiple body styles. Setting this
+ * to false allows editing each pin per part or body style individually.
+ * This requires the user to open each part or body style to make changes
+ * to the pin at the same location.
+ */
+ bool m_editPinsPerPartOrConvert;
+
+ /** The current draw or edit graphic item fill style. */
+ static FILL_T m_drawFillStyle;
+
+ /** Default line width for drawing or editing graphic items. */
+ static int m_drawLineWidth;
+
+ static LIB_ITEM* m_lastDrawItem;
+ static LIB_ITEM* m_drawItem;
+ static wxString m_aliasName;
+
+ // The unit number to edit and show
+ static int m_unit;
+
+ // Show the normal shape ( m_convert <= 1 ) or the converted shape
+ // ( m_convert > 1 )
+ static int m_convert;
+
+ // true to force DeMorgan/normal tools selection enabled.
+ // They are enabled when the loaded component has
+ // Graphic items for converted shape
+ // But under some circumstances (New component created)
+ // these tools must left enabled
+ static bool m_showDeMorgan;
+
+ /// The current text size setting.
+ static int m_textSize;
+
+ /// Current text orientation setting.
+ static int m_textOrientation;
+
+ /// The default pin num text size setting.
+ static int m_textPinNumDefaultSize;
+
+ /// The default pin name text size setting.
+ static int m_textPinNameDefaultSize;
+
+ /// Default pin length
+ static int m_defaultPinLength;
+
+ /// Default repeat offset for pins in repeat place pin
+ int m_repeatPinStep;
+
+ static wxSize m_clientSize;
+
+ friend class DIALOG_LIB_EDIT_TEXT;
+
+ LIB_ITEM* locateItem( const wxPoint& aPosition, const KICAD_T aFilterList[] );
+
+public:
+
+ LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );
+
+ ~LIB_EDIT_FRAME();
+
+ /** The current library being edited, or NULL if none. */
+ PART_LIB* GetCurLib();
+
+ /** Sets the current library and return the old. */
+ PART_LIB* SetCurLib( PART_LIB* aLib );
+
+ /**
+ * Function GetCurPart
+ * returns the current part being edited, or NULL if none selected.
+ * This is a LIB_PART that I own, it is at best a copy of one in a library.
+ */
+ LIB_PART* GetCurPart();
+
+ /**
+ * Function SetCurPart
+ * takes ownership over aPart and notes that it is the one currently
+ * being edited.
+ */
+ void SetCurPart( LIB_PART* aPart );
+
+ /** @return the default pin num text size.
+ */
+ static int GetPinNumDefaultSize() { return m_textPinNumDefaultSize; }
+
+ /** @return The default pin name text size setting.
+ */
+ static int GetPinNameDefaultSize() { return m_textPinNameDefaultSize; }
+
+ /** @return The default pin len setting.
+ */
+ static int GetDefaultPinLength() { return m_defaultPinLength; }
+
+ /** Set the default pin len.
+ */
+ static void SetDefaultPinLength( int aLength ) { m_defaultPinLength = aLength; }
+
+ /**
+ * @return the increment value of the position of a pin
+ * for the pin repeat command
+ */
+ int GetRepeatPinStep() const { return m_repeatPinStep; }
+
+ /**
+ * Sets the repeat step value for pins repeat command
+ * @param aStep the increment value of the position of an item
+ * for the repeat command
+ */
+ void SetRepeatPinStep( int aStep) { m_repeatPinStep = aStep; }
+
+
+ void ReCreateMenuBar();
+
+ /**
+ * Function EnsureActiveLibExists
+ * must be called after the libraries are reloaded
+ * (for instance after loading a schematic project)
+ */
+ static void EnsureActiveLibExists();
+
+ void InstallConfigFrame( wxCommandEvent& event );
+ void OnColorConfig( wxCommandEvent& aEvent );
+ void OnPreferencesOptions( wxCommandEvent& event );
+ void Process_Config( wxCommandEvent& event );
+
+ /**
+ * Function SycnronizePins
+ * @return True if the edit pins per part or convert is false and the current
+ * component has multiple parts or body styles. Otherwise false is
+ * returned.
+ */
+ bool SynchronizePins();
+
+ /**
+ * Function OnPlotCurrentComponent
+ * plot the current component in SVG or PNG format.
+ */
+ void OnPlotCurrentComponent( wxCommandEvent& event );
+ void Process_Special_Functions( wxCommandEvent& event );
+ void OnSelectTool( wxCommandEvent& aEvent );
+
+ /**
+ * Routine to read one part.
+ * The format is that of libraries, but it loads only 1 component.
+ * Or 1 component if there are several.
+ * If the first component is an alias, it will load the corresponding root.
+ */
+ void OnImportPart( wxCommandEvent& event );
+
+ /**
+ * Function OnExportPart
+ * creates a new library and backup the current component in this library or export
+ * the component of the current library.
+ */
+ void OnExportPart( wxCommandEvent& event );
+ void OnSelectAlias( wxCommandEvent& event );
+ void OnSelectPart( wxCommandEvent& event );
+
+ /**
+ * Function DeleteOnePart
+ * is the command event handler to delete an entry from the current library.
+ *
+ * The deleted entry can be an alias or a component. If the entry is an alias,
+ * it is removed from the component and the list of alias is updated. If the
+ * entry is a component and the list of aliases is empty, the component and all
+ * it drawable items are deleted. Otherwise the first alias in the alias list
+ * becomes the new component name and the other aliases become dependent on
+ * renamed component.
+ *
+ * @note This only deletes the entry in memory. The file does not change.
+ */
+ void DeleteOnePart( wxCommandEvent& event );
+
+ /**
+ * Function CreateNewLibraryPart
+ * is the command event handler to create a new library component.
+ *
+ * If an old component is currently in edit, it is deleted.
+ */
+ void CreateNewLibraryPart( wxCommandEvent& event );
+
+ void OnCreateNewPartFromExisting( wxCommandEvent& event );
+ void OnEditComponentProperties( wxCommandEvent& event );
+ void InstallFieldsEditorDialog( wxCommandEvent& event );
+
+ /**
+ * Function LoadOneLibraryPart
+ * loads a library component from the currently selected library.
+ *
+ * If a library is already selected, the user is prompted for the component name
+ * to load. If there is no current selected library, the user is prompted to select
+ * a library name and then select component to load.
+ */
+ void LoadOneLibraryPart( wxCommandEvent& event );
+
+ void OnViewEntryDoc( wxCommandEvent& event );
+ void OnCheckComponent( wxCommandEvent& event );
+ void OnSelectBodyStyle( wxCommandEvent& event );
+ void OnEditPin( wxCommandEvent& event );
+ void OnSelectItem( wxCommandEvent& aEvent );
+
+ void OnOpenPinTable( wxCommandEvent& aEvent );
+
+ void OnUpdateSelectTool( wxUpdateUIEvent& aEvent );
+ void OnUpdateEditingPart( wxUpdateUIEvent& event );
+ void OnUpdateNotEditingPart( wxUpdateUIEvent& event );
+ void OnUpdateUndo( wxUpdateUIEvent& event );
+ void OnUpdateRedo( wxUpdateUIEvent& event );
+ void OnUpdateSaveCurrentLib( wxUpdateUIEvent& event );
+ void OnUpdateViewDoc( wxUpdateUIEvent& event );
+ void OnUpdatePinByPin( wxUpdateUIEvent& event );
+ void OnUpdatePinTable( wxUpdateUIEvent& event );
+ void OnUpdatePartNumber( wxUpdateUIEvent& event );
+ void OnUpdateDeMorganNormal( wxUpdateUIEvent& event );
+ void OnUpdateDeMorganConvert( wxUpdateUIEvent& event );
+ void OnUpdateSelectAlias( wxUpdateUIEvent& event );
+
+ void UpdateAliasSelectList();
+ void UpdatePartSelectList();
+
+ /**
+ * Function DisplayLibInfos
+ * updates the main window title bar with the current library name and read only status
+ * of the library.
+ */
+ void DisplayLibInfos();
+
+ /**
+ * Function RedrawComponent
+ * Redraw the current component loaded in library editor
+ * Display reference like in schematic (a reference U is shown U? or U?A)
+ * accordint to the current selected unit and De Morgan selection
+ * although it is stored without ? and part id.
+ * @param aDC = the current device context
+ * @param aOffset = a draw offset. usually 0,0 to draw on the screen, but
+ * can be set to page size / 2 to draw or print in SVG format.
+ */
+ void RedrawComponent( wxDC* aDC, wxPoint aOffset );
+
+ /**
+ * Function RedrawActiveWindow
+ * Redraw the current component loaded in library editor, an axes
+ * Display reference like in schematic (a reference U is shown U? or U?A)
+ * update status bar and info shown in the bottom of the window
+ */
+ void RedrawActiveWindow( wxDC* DC, bool EraseBg );
+
+ void OnCloseWindow( wxCloseEvent& Event );
+ void ReCreateHToolbar();
+ void ReCreateVToolbar();
+ void CreateOptionToolbar();
+ void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
+ bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
+ double BestZoom(); // Returns the best zoom
+ void OnLeftDClick( wxDC* DC, const wxPoint& MousePos );
+
+ ///> @copydoc EDA_DRAW_FRAME::GetHotKeyDescription()
+ EDA_HOTKEY* GetHotKeyDescription( int aCommand ) const;
+
+ bool OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem = NULL );
+
+ bool GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey = 0 );
+
+ void LoadSettings( wxConfigBase* aCfg );
+
+ void SaveSettings( wxConfigBase* aCfg );
+
+ /**
+ * Function CloseWindow
+ * triggers the wxCloseEvent, which is handled by the function given
+ * to EVT_CLOSE() macro:
+ * <p>
+ * EVT_CLOSE( LIB_EDIT_FRAME::OnCloseWindow )
+ */
+ void CloseWindow( wxCommandEvent& event )
+ {
+ // Generate a wxCloseEvent
+ Close( false );
+ }
+
+ /**
+ * Function OnModify
+ * Must be called after a schematic change
+ * in order to set the "modify" flag of the current screen
+ */
+ void OnModify()
+ {
+ GetScreen()->SetModify();
+ }
+
+ const wxString& GetAliasName() { return m_aliasName; }
+
+ int GetUnit() { return m_unit; }
+
+ void SetUnit( int unit )
+ {
+ wxASSERT( unit >= 1 );
+ m_unit = unit;
+ }
+
+ int GetConvert() { return m_convert; }
+
+ void SetConvert( int convert )
+ {
+ wxASSERT( convert >= 0 );
+ m_convert = convert;
+ }
+
+ LIB_ITEM* GetLastDrawItem() { return m_lastDrawItem; }
+
+ void SetLastDrawItem( LIB_ITEM* drawItem )
+ {
+ m_lastDrawItem = drawItem;
+ }
+
+ LIB_ITEM* GetDrawItem() { return m_drawItem; }
+
+ void SetDrawItem( LIB_ITEM* drawItem );
+
+ bool GetShowDeMorgan() { return m_showDeMorgan; }
+
+ void SetShowDeMorgan( bool show ) { m_showDeMorgan = show; }
+
+ FILL_T GetFillStyle() { return m_drawFillStyle; }
+
+ /**
+ * Function TempCopyComponent
+ * create a temporary copy of the current edited component
+ * Used to prepare an Undo ant/or abort command before editing the component
+ */
+ void TempCopyComponent();
+
+ /**
+ * Function RestoreComponent
+ * Restore the current edited component from its temporary copy.
+ * Used to abort a command
+ */
+ void RestoreComponent();
+
+ /**
+ * Function GetTempCopyComponent
+ * @return the temporary copy of the current component.
+ */
+ LIB_PART* GetTempCopyComponent() { return m_tempCopyComponent; }
+
+ /**
+ * Function ClearTempCopyComponent
+ * delete temporary copy of the current component and clear pointer
+ */
+ void ClearTempCopyComponent();
+
+ bool IsEditingDrawItem() { return m_drawItem && m_drawItem->InEditMode(); }
+
+private:
+
+ /**
+ * Function OnActivate
+ * is called when the frame is activated. Tests if the current library exists.
+ * The library list can be changed by the schematic editor after reloading a new schematic
+ * and the current library can point a non existent lib.
+ */
+ virtual void OnActivate( wxActivateEvent& event );
+
+ // General:
+
+ /**
+ * Function SaveOnePart
+ * saves the current LIB_PART into the provided PART_LIB.
+ *
+ * Any changes are updated in memory only and NOT to a file. The old component is
+ * deleted from the library and/or any aliases before the edited component is updated
+ * in the library.
+ * @param aLib - the part library where the part must be saved.
+ * @param aPromptUser true to ask for confirmation, when the part_lib is already existing
+ * in memory, false to save silently
+ * @return true if the part was saved, false if aborted by user
+ */
+ bool SaveOnePart( PART_LIB* aLib, bool aPromptUser = true );
+
+ /**
+ * Function SelectActiveLibrary
+ * sets the current active library to \a aLibrary.
+ *
+ * @param aLibrary A pointer to the PART_LIB object to select. If NULL, then display
+ * list of available libraries to select from.
+ */
+ void SelectActiveLibrary( PART_LIB* aLibrary = NULL );
+
+ /**
+ * Function OnSaveActiveLibrary
+ * it the command event handler to save the changes to the current library.
+ *
+ * A backup file of the current library is saved with the .bak extension before the
+ * changes made to the library are saved.
+ */
+ void OnSaveActiveLibrary( wxCommandEvent& event );
+
+ /**
+ * Function SaveActiveLibrary
+ * saves the changes to the current library.
+ *
+ * A backup file of the current library is saved with the .bak extension before the
+ * changes made to the library are saved.
+ * @param newFile Ask for a new file name to save the library.
+ * @return True if the library was successfully saved.
+ */
+ bool SaveActiveLibrary( bool newFile );
+
+ /**
+ * Function LoadComponentFromCurrentLib
+ * loads a component from the current active library.
+ * @param aLibEntry The component to load from \a aLibrary (can be an alias)
+ * @return true if \a aLibEntry loaded correctly.
+ */
+ bool LoadComponentFromCurrentLib( LIB_ALIAS* aLibEntry );
+
+ /**
+ * Function LoadOneLibraryPartAux
+ * loads a copy of \a aLibEntry from \a aLibrary into memory.
+ *
+ * @param aLibEntry A pointer to the LIB_ALIAS object to load.
+ * @param aLibrary A pointer to the PART_LIB object to load \a aLibEntry from.
+ * @return True if a copy of \a aLibEntry was successfully loaded from \a aLibrary.
+ */
+ bool LoadOneLibraryPartAux( LIB_ALIAS* aLibEntry, PART_LIB* aLibrary );
+
+ /**
+ * Function DisplayCmpDoc
+ * displays the documentation of the selected component.
+ */
+ void DisplayCmpDoc();
+
+ /**
+ * Function OnRotateItem
+ * rotates the current item.
+ */
+ void OnRotateItem( wxCommandEvent& aEvent );
+
+ /**
+ * Function deleteItem
+ * deletes the currently selected draw item.
+ * @param aDC The device context to draw upon when removing item.
+ */
+ void deleteItem( wxDC* aDC );
+
+ // General editing
+public:
+ /**
+ * Function SaveCopyInUndoList.
+ * Create a copy of the current component, and save it in the undo list.
+ * Because a component in library editor does not a lot of primitives,
+ * the full data is duplicated. It is not worth to try to optimize this save funtion
+ */
+ void SaveCopyInUndoList( EDA_ITEM* ItemToCopy );
+
+private:
+ void GetComponentFromUndoList( wxCommandEvent& event );
+ void GetComponentFromRedoList( wxCommandEvent& event );
+
+ // Editing pins
+ void CreatePin( wxDC* DC );
+ void StartMovePin( wxDC* DC );
+
+ /**
+ * Function CreateImagePins
+ * adds copies of \a aPin for \a aUnit in components with multiple parts and
+ * \a aConvert for components that have multiple body styles.
+ *
+ * @param aPin The pin to copy.
+ * @param aUnit The unit to add a copy of \a aPin to.
+ * @param aConvert The alternate body style to add a copy of \a aPin to.
+ * @param aDeMorgan Flag to indicate if \a aPin should be created for the
+ * alternate body style.
+ */
+ void CreateImagePins( LIB_PIN* aPin, int aUnit, int aConvert, bool aDeMorgan );
+
+ /**
+ * Function PlaceAnchor
+ * places an anchor reference coordinate for the current component.
+ * <p>
+ * All object coordinates are offset to the current cursor position.
+ * </p>
+ */
+ void PlaceAnchor();
+
+ // Editing graphic items
+ LIB_ITEM* CreateGraphicItem( LIB_PART* LibEntry, wxDC* DC );
+ void GraphicItemBeginDraw( wxDC* DC );
+ void StartMoveDrawSymbol( wxDC* DC );
+ void StartModifyDrawSymbol( wxDC* DC ); //<! Modify the item, adjust size etc.
+ void EndDrawGraphicItem( wxDC* DC );
+
+ /**
+ * Function LoadOneSymbol
+ * read a component symbol file (*.sym ) and add graphic items to the current component.
+ * <p>
+ * A symbol file *.sym has the same format as a library, and contains only
+ * one symbol.
+ * </p>
+ */
+ void LoadOneSymbol();
+
+ /**
+ * Function SaveOneSymbol
+ * saves the current component to a symbol file.
+ * <p>
+ * The symbol file format is similar to the standard component library file format, but
+ * there is only one symbol. Invisible pins are not saved.
+ */
+ void SaveOneSymbol();
+
+ void EditGraphicSymbol( wxDC* DC, LIB_ITEM* DrawItem );
+ void EditSymbolText( wxDC* DC, LIB_ITEM* DrawItem );
+ LIB_ITEM* LocateItemUsingCursor( const wxPoint& aPosition,
+ const KICAD_T aFilterList[] = LIB_COLLECTOR::AllItems );
+ void EditField( LIB_FIELD* Field );
+
+public:
+ /**
+ * Function LoadComponentAndSelectLib
+ * selects the current active library.
+ *
+ * @param aLibrary The PART_LIB to select
+ * @param aLibEntry The component to load from aLibrary (can be an alias).
+ * @return true if \a aLibEntry was loaded from \a aLibrary.
+ */
+ bool LoadComponentAndSelectLib( LIB_ALIAS* aLibEntry, PART_LIB* aLibrary );
+
+ /* Block commands: */
+
+ /**
+ * Function BlockCommand
+ * returns the block command (BLOCK_MOVE, BLOCK_COPY...) corresponding to
+ * the \a aKey (ALT, SHIFT ALT ..)
+ */
+ virtual int BlockCommand( int aKey );
+
+ /**
+ * Function HandleBlockPlace
+ * handles the block place command.
+ */
+ virtual void HandleBlockPlace( wxDC* DC );
+
+ /**
+ * Function HandleBlockEnd
+ * performs a block end command.
+ * @return If command finished (zoom, delete ...) false is returned otherwise true
+ * is returned indicating more processing is required.
+ */
+ virtual bool HandleBlockEnd( wxDC* DC );
+
+ /**
+ * Function PlacePin
+ * Place at cursor location the pin currently moved (i.e. pin pointed by m_drawItem)
+ * (and the linked pins, if any)
+ */
+ void PlacePin();
+
+ /**
+ * Function GlobalSetPins
+ * @param aMasterPin is the "template" pin
+ * @param aId is a param to select what should be mofified:
+ * - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM:
+ * Change pins text name size
+ * - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM:
+ * Change pins text num size
+ * - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM:
+ * Change pins length.
+ *
+ * If aMasterPin is selected ( .m_flag == IS_SELECTED ),
+ * only the other selected pins are modified
+ */
+ void GlobalSetPins( LIB_PIN* aMasterPin, int aId );
+
+ // Automatic placement of pins
+ void RepeatPinItem( wxDC* DC, LIB_PIN* Pin );
+
+ /**
+ * Function CreatePNGorJPEGFile
+ * creates an image (screenshot) of the current component in PNG or JPEG format.
+ * @param aFileName = the full filename
+ * @param aFmt_jpeg = true to use JPEG file format, false to use PNG file format
+ */
+ void CreatePNGorJPEGFile( const wxString& aFileName, bool aFmt_jpeg );
+
+ /**
+ * Virtual function PrintPage
+ * used to print a page
+ * @param aDC = wxDC given by the calling print function
+ * @param aPrintMask = not used here
+ * @param aPrintMirrorMode = not used here (Set when printing in mirror mode)
+ * @param aData = a pointer on an auxiliary data (not always used, NULL if not used)
+ */
+ virtual void PrintPage( wxDC* aDC, LSET aPrintMask,
+ bool aPrintMirrorMode, void* aData = NULL );
+
+ /**
+ * Function SVG_PlotComponent
+ * Creates the SVG print file for the current edited component.
+ * @param aFullFileName = the full filename
+ */
+ void SVG_PlotComponent( const wxString& aFullFileName );
+
+ DECLARE_EVENT_TABLE()
+};
+
+#endif // LIBEDITFRM_H_
diff --git a/eeschema/libfield.cpp b/eeschema/libfield.cpp
new file mode 100644
index 0000000..df3438c
--- /dev/null
+++ b/eeschema/libfield.cpp
@@ -0,0 +1,161 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2007-2016 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <class_sch_screen.h>
+
+#include <general.h>
+#include <sch_component.h>
+#include <libeditframe.h>
+#include <class_library.h>
+#include <template_fieldnames.h>
+#include <dialog_edit_one_field.h>
+
+
+void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField )
+{
+ wxString newFieldValue;
+ wxString title;
+ wxString caption;
+ wxString oldName;
+
+ if( aField == NULL )
+ return;
+
+ LIB_PART* parent = aField->GetParent();
+
+ wxASSERT( parent );
+
+ // Editing the component value field is equivalent to creating a new component based
+ // on the current component. Set the dialog message to inform the user.
+ if( aField->GetId() == VALUE )
+ {
+ caption = _( "Component Name" );
+ title = _( "Enter a name to create a new component based on this one." );
+ }
+ else
+ {
+ caption.Printf( _( "Edit Field %s" ), GetChars( aField->GetName() ) );
+ title.Printf( _( "Enter a new value for the %s field." ),
+ GetChars( aField->GetName().Lower() ) );
+ }
+
+ DIALOG_LIB_EDIT_ONE_FIELD dlg( this, caption, aField );
+
+ // The dialog may invoke a kiway player for footprint fields
+ // so we must use a quasimodal dialog.
+ if( dlg.ShowQuasiModal() != wxID_OK )
+ return;
+
+ newFieldValue = dlg.GetText();
+ wxString fieldText = aField->GetFullText( m_unit );
+
+ /* If the value field is changed, this is equivalent to creating a new component from
+ * the old one. Rename the component and remove any conflicting aliases to prevent name
+ * errors when updating the library.
+ */
+ if( aField->GetId() == VALUE && newFieldValue != aField->GetText() )
+ {
+ wxString msg;
+
+ PART_LIB* lib = GetCurLib();
+
+ // Test the current library for name conflicts.
+ if( lib && lib->FindEntry( newFieldValue ) )
+ {
+ msg.Printf( _(
+ "The name '%s' conflicts with an existing entry in the component library '%s'.\n\n"
+ "Do you wish to replace the current component in the library with this one?" ),
+ GetChars( newFieldValue ),
+ GetChars( lib->GetName() )
+ );
+
+ int rsp = wxMessageBox( msg, _( "Confirm" ),
+ wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT, this );
+
+ if( rsp == wxNO )
+ return;
+ }
+
+ // Test the current component for name conflicts.
+ if( parent->HasAlias( newFieldValue ) )
+ {
+ msg.Printf( _( "The current component already has an alias named '%s'.\n\n"
+ "Do you wish to remove this alias from the component?" ),
+ GetChars( newFieldValue ) );
+
+ int rsp = wxMessageBox( msg, _( "Confirm" ), wxYES_NO | wxICON_QUESTION, this );
+
+ if( rsp == wxNO )
+ return;
+
+ parent->RemoveAlias( newFieldValue );
+ }
+
+ parent->SetName( newFieldValue );
+
+ // Test the library for any conflicts with the any aliases in the current component.
+ if( parent->GetAliasCount() > 1 && lib && lib->Conflicts( parent ) )
+ {
+ msg.Printf( _(
+ "The new component contains alias names that conflict with entries in the "
+ "component library '%s'.\n\n"
+ "Do you wish to remove all of the conflicting aliases from this component?" ),
+ GetChars( lib->GetName() )
+ );
+
+ int rsp = wxMessageBox( msg, _( "Confirm" ), wxYES_NO | wxICON_QUESTION, this );
+
+ if( rsp == wxNO )
+ {
+ parent->SetName( fieldText );
+ return;
+ }
+
+ wxArrayString aliases = parent->GetAliasNames( false );
+
+ for( size_t i = 0; i < aliases.GetCount(); i++ )
+ {
+ if( lib->FindEntry( aliases[ i ] ) != NULL )
+ parent->RemoveAlias( aliases[ i ] );
+ }
+ }
+
+ if( !parent->HasAlias( m_aliasName ) )
+ m_aliasName = newFieldValue;
+ }
+
+ dlg.UpdateField( aField );
+
+ if( !aField->InEditMode() )
+ SaveCopyInUndoList( parent );
+
+ m_canvas->Refresh();
+
+ OnModify();
+ UpdateAliasSelectList();
+}
diff --git a/eeschema/load_one_schematic_file.cpp b/eeschema/load_one_schematic_file.cpp
new file mode 100644
index 0000000..5d4e345
--- /dev/null
+++ b/eeschema/load_one_schematic_file.cpp
@@ -0,0 +1,413 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 2008 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file load_one_schematic_file.cpp
+ * @brief Code to load and save Eeschema files.
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <schframe.h>
+#include <richio.h>
+#include <project.h>
+
+#include <general.h>
+#include <sch_bus_entry.h>
+#include <sch_marker.h>
+#include <sch_junction.h>
+#include <sch_line.h>
+#include <sch_no_connect.h>
+#include <sch_component.h>
+#include <sch_text.h>
+#include <sch_sheet.h>
+#include <sch_bitmap.h>
+#include <wildcards_and_files_ext.h>
+
+
+bool ReadSchemaDescr( LINE_READER* aLine, wxString& aMsgDiag, SCH_SCREEN* Window );
+
+
+bool SCH_EDIT_FRAME::LoadOneEEFile( SCH_SCREEN* aScreen, const wxString& aFullFileName, bool append )
+{
+ char name1[256];
+ bool itemLoaded = false;
+ SCH_ITEM* item;
+ wxString msgDiag; // Error and log messages
+ char* line;
+ wxFileName fn;
+
+ if( aScreen == NULL )
+ return false;
+
+ if( aFullFileName.IsEmpty() )
+ return false;
+
+ // Place the undo limit into the screen
+ aScreen->SetMaxUndoItems( m_UndoRedoCountMax );
+
+ // If path is relative, this expands it from the project directory.
+ wxString fname = Prj().AbsolutePath( aFullFileName );
+
+#ifdef __WINDOWS__
+ fname.Replace( wxT("/"), wxT("\\") );
+#else
+ fname.Replace( wxT("\\"), wxT("/") );
+#endif
+
+ fn = fname;
+ CheckForAutoSaveFile( fn, SchematicBackupFileExtension );
+
+ wxLogTrace( traceAutoSave, wxT( "Loading schematic file " ) + aFullFileName );
+
+ aScreen->SetCurItem( NULL );
+ if( !append )
+ aScreen->SetFileName( aFullFileName );
+
+ FILE* f = wxFopen( fname, wxT( "rt" ) );
+
+ if( !f )
+ {
+ msgDiag.Printf( _( "Failed to open '%s'" ), GetChars( aFullFileName ) );
+ DisplayError( this, msgDiag );
+ return false;
+ }
+
+ // reader now owns the open FILE.
+ FILE_LINE_READER reader( f, aFullFileName );
+
+ msgDiag.Printf( _( "Loading '%s'" ), GetChars( aScreen->GetFileName() ) );
+ PrintMsg( msgDiag );
+
+ if( !reader.ReadLine()
+ || strncmp( (char*)reader + 9, SCHEMATIC_HEAD_STRING,
+ sizeof( SCHEMATIC_HEAD_STRING ) - 1 ) != 0 )
+ {
+ msgDiag.Printf( _( "'%s' is NOT an Eeschema file!" ), GetChars( aFullFileName ) );
+ DisplayError( this, msgDiag );
+ return false;
+ }
+
+ line = reader.Line();
+
+ // get the file version here.
+ char *strversion = line + 9 + sizeof( SCHEMATIC_HEAD_STRING );
+
+ // Skip blanks
+ while( *strversion && *strversion < '0' )
+ strversion++;
+
+ int version = atoi( strversion );
+
+ if( version > EESCHEMA_VERSION )
+ {
+ msgDiag.Printf( _(
+ "'%s' was created by a more recent version of Eeschema and may not"
+ " load correctly. Please consider updating!" ),
+ GetChars( aFullFileName )
+ );
+ DisplayInfoMessage( this, msgDiag );
+ }
+
+#if 0
+ // Compile it if the new version is unreadable by previous Eeschema versions
+ else if( version < EESCHEMA_VERSION )
+ {
+ MsgDiag = aFullFileName + _( " was created by an older version of \
+Eeschema. It will be stored in the new file format when you save this file \
+again." );
+
+ DisplayInfoMessage( this, MsgDiag );
+ }
+#endif
+
+ // The next lines are the lib list section, and are mainly comments, like:
+ // LIBS:power
+ // the lib list is not used, but is in schematic file just in case.
+ // It is usually not empty, but we accept empty list.
+ // If empty, there is a legacy section, not used
+ // EELAYER i j
+ // and the last line is
+ // EELAYER END
+ // Skip all lines until the end of header "EELAYER END" is found
+ while( reader.ReadLine() )
+ {
+ line = reader.Line();
+
+ while( *line == ' ' )
+ line++;
+
+ if( strnicmp( line, "EELAYER END", 11 ) == 0 )
+ break; // end of not used header found
+ }
+
+ while( reader.ReadLine() )
+ {
+ itemLoaded = false;
+ line = reader.Line();
+
+ item = NULL;
+
+ char* sline = line;
+
+ while( (*sline != ' ' ) && *sline )
+ sline++;
+
+ switch( line[0] )
+ {
+ case '$': // identification block
+ if( line[1] == 'C' )
+ item = new SCH_COMPONENT();
+ else if( line[1] == 'S' )
+ item = new SCH_SHEET();
+ else if( line[1] == 'D' )
+ itemLoaded = ReadSchemaDescr( &reader, msgDiag, aScreen );
+ else if( line[1] == 'B' )
+ item = new SCH_BITMAP();
+ else if( line[1] == 'E' )
+ itemLoaded = true; // The EOF marker
+ break;
+
+ case 'L': // Its a library item.
+ item = new SCH_COMPONENT();
+ break;
+
+ case 'W': // Its a Segment (WIRE or BUS) item.
+ item = new SCH_LINE();
+ break;
+
+ case 'E': // Its a WIRE or BUS item.
+ /* The bus entry can be represented by two different
+ * classes, so we need a factory function */
+ itemLoaded = SCH_BUS_ENTRY_BASE::Load( reader, msgDiag, &item );
+ break;
+
+ case 'C': // It is a connection item.
+ item = new SCH_JUNCTION();
+ break;
+
+ case 'K': // It is a Marker item.
+ // Markers are no more read from file. they are only created on
+ // demand in schematic
+ itemLoaded = true; // Just skip descr and disable err message
+ break;
+
+ case 'N': // It is a NoConnect item.
+ item = new SCH_NO_CONNECT();
+ break;
+
+ case 'T': // It is a text item.
+ if( sscanf( sline, "%255s", name1 ) != 1 )
+ {
+ msgDiag.Printf( _( "Eeschema file text load error at line %d" ),
+ reader.LineNumber() );
+ itemLoaded = false;
+ }
+ else if( name1[0] == 'L' )
+ item = new SCH_LABEL();
+ else if( name1[0] == 'G' && version > 1 )
+ item = new SCH_GLOBALLABEL();
+ else if( (name1[0] == 'H') || (name1[0] == 'G' && version == 1) )
+ item = new SCH_HIERLABEL();
+ else
+ item = new SCH_TEXT();
+ break;
+
+ default:
+ itemLoaded = false;
+ msgDiag.Printf( _( "Eeschema file undefined object at line %d, aborted" ),
+ reader.LineNumber() );
+ msgDiag << wxT( "\n" ) << FROM_UTF8( line );
+ }
+
+ if( item )
+ {
+ // Load it if it wasn't by a factory
+ if( !itemLoaded )
+ itemLoaded = item->Load( reader, msgDiag );
+
+ if( !itemLoaded )
+ {
+ delete item;
+ }
+ else
+ {
+ aScreen->Append( item );
+ }
+ }
+
+ if( !itemLoaded )
+ {
+ msgDiag.Printf( _( "Eeschema file object not loaded at line %d, aborted" ),
+ reader.LineNumber() );
+ msgDiag << wxT( "\n" ) << FROM_UTF8( line );
+ DisplayError( this, msgDiag );
+ break;
+ }
+ }
+
+#if 0 && defined (DEBUG)
+ aScreen->Show( 0, std::cout );
+#endif
+
+ // Build links between each components and its part lib LIB_PART
+ aScreen->CheckComponentsToPartsLinks();
+
+ aScreen->TestDanglingEnds();
+
+ msgDiag.Printf( _( "Done Loading <%s>" ), GetChars( aScreen->GetFileName() ) );
+ PrintMsg( msgDiag );
+
+ return true; // Although it may be that file is only partially loaded.
+}
+
+
+/// Get the length of a string constant, at compile time
+#define SZ( x ) (sizeof(x)-1)
+
+static const char delims[] = " \t\r\n";
+
+/* Read the schematic header. */
+bool ReadSchemaDescr( LINE_READER* aLine, wxString& aMsgDiag, SCH_SCREEN* aScreen )
+{
+ char* line = aLine->Line();
+
+ char* pageType = strtok( line + SZ( "$Descr" ), delims );
+ char* width = strtok( NULL, delims );
+ char* height = strtok( NULL, delims );
+ char* orient = strtok( NULL, delims );
+
+ wxString pagename = FROM_UTF8( pageType );
+
+ PAGE_INFO pageInfo;
+ TITLE_BLOCK tb;
+
+ if( !pageInfo.SetType( pagename ) )
+ {
+ aMsgDiag.Printf( _( "Eeschema file dimension definition error line %d,"
+ "\nAbort reading file.\n" ),
+ aLine->LineNumber() );
+ aMsgDiag << FROM_UTF8( line );
+ }
+
+ if( pagename == PAGE_INFO::Custom )
+ {
+ if( width && height )
+ {
+ int w = atoi( width );
+ int h = atoi( height );
+
+ pageInfo.SetWidthMils( w );
+ pageInfo.SetHeightMils( h );
+ }
+ }
+
+ // non custom size, set portrait if its present
+ else if( orient && !strcmp( orient, "portrait" ) )
+ {
+ pageInfo.SetPortrait( true );
+ }
+
+ aScreen->SetPageSettings( pageInfo );
+
+ for(;;)
+ {
+ char buf[1024];
+
+ if( !aLine->ReadLine() )
+ return true;
+
+ line = aLine->Line();
+
+ if( strnicmp( line, "$End", 4 ) == 0 )
+ {
+ aScreen->SetTitleBlock( tb );
+ break;
+ }
+
+ if( strnicmp( line, "Sheet", 2 ) == 0 )
+ sscanf( line + 5, " %d %d",
+ &aScreen->m_ScreenNumber, &aScreen->m_NumberOfScreens );
+
+ if( strnicmp( line, "Title", 2 ) == 0 )
+ {
+ ReadDelimitedText( buf, line, 256 );
+ tb.SetTitle( FROM_UTF8( buf ) );
+ continue;
+ }
+
+ if( strnicmp( line, "Date", 2 ) == 0 )
+ {
+ ReadDelimitedText( buf, line, 256 );
+ tb.SetDate( FROM_UTF8( buf ) );
+ continue;
+ }
+
+ if( strnicmp( line, "Rev", 2 ) == 0 )
+ {
+ ReadDelimitedText( buf, line, 256 );
+ tb.SetRevision( FROM_UTF8( buf ) );
+ continue;
+ }
+
+ if( strnicmp( line, "Comp", 4 ) == 0 )
+ {
+ ReadDelimitedText( buf, line, 256 );
+ tb.SetCompany( FROM_UTF8( buf ) );
+ continue;
+ }
+
+ if( strnicmp( line, "Comment1", 8 ) == 0 )
+ {
+ ReadDelimitedText( buf, line, 256 );
+ tb.SetComment1( FROM_UTF8( buf ) );
+ continue;
+ }
+
+ if( strnicmp( line, "Comment2", 8 ) == 0 )
+ {
+ ReadDelimitedText( buf, line, 256 );
+ tb.SetComment2( FROM_UTF8( buf ) );
+ continue;
+ }
+
+ if( strnicmp( line, "Comment3", 8 ) == 0 )
+ {
+ ReadDelimitedText( buf, line, 256 );
+ tb.SetComment3( FROM_UTF8( buf ) );
+ continue;
+ }
+
+ if( strnicmp( line, "Comment4", 8 ) == 0 )
+ {
+ ReadDelimitedText( buf, line, 256 );
+ tb.SetComment4( FROM_UTF8( buf ) );
+ continue;
+ }
+ }
+
+ return true;
+}
diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp
new file mode 100644
index 0000000..0baaa1e
--- /dev/null
+++ b/eeschema/menubar.cpp
@@ -0,0 +1,521 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2009-2014 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/menubar.cpp
+ * @brief (Re)Create the main menubar for the schematic frame
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <pgm_base.h>
+#include <schframe.h>
+
+#include <general.h>
+#include <eeschema_id.h>
+#include <hotkeys.h>
+#include <menus_helpers.h>
+
+#include <help_common_strings.h>
+
+
+void SCH_EDIT_FRAME::ReCreateMenuBar()
+{
+ // Create and try to get the current menubar
+ wxString text;
+ wxMenuBar* menuBar = GetMenuBar();
+
+ if( !menuBar )
+ menuBar = new wxMenuBar();
+
+ // Delete all existing menus so they can be rebuilt.
+ // This allows language changes of the menu text on the fly.
+ menuBar->Freeze();
+
+ while( menuBar->GetMenuCount() )
+ delete menuBar->Remove( 0 );
+
+ // Recreate all menus:
+
+ // Menu File:
+ wxMenu* fileMenu = new wxMenu;
+
+ if( Kiface().IsSingle() ) // not when under a project mgr
+ {
+ AddMenuItem( fileMenu,
+ ID_NEW_PROJECT,
+ _( "&New Schematic Project" ),
+ _( "Clear current schematic hierarchy and start a new schematic root sheet" ),
+ KiBitmap( new_sch_xpm ) );
+
+ text = AddHotkeyName( _( "&Open Schematic Project" ), g_Schematic_Hokeys_Descr, HK_LOAD_SCH );
+ AddMenuItem( fileMenu,
+ ID_LOAD_PROJECT, text,
+ _( "Open an existing schematic hierarchy" ),
+ KiBitmap( open_document_xpm ) );
+ }
+
+ // @todo: static probably not OK in multiple open projects.
+ // Open Recent submenu
+ static wxMenu* openRecentMenu;
+
+ // Add this menu to list menu managed by m_fileHistory
+ // (the file history will be updated when adding/removing files in history
+ if( openRecentMenu )
+ Kiface().GetFileHistory().RemoveMenu( openRecentMenu );
+
+ openRecentMenu = new wxMenu();
+
+ Kiface().GetFileHistory().UseMenu( openRecentMenu );
+ Kiface().GetFileHistory().AddFilesToMenu( openRecentMenu );
+
+ if( Kiface().IsSingle() ) // not when under a project mgr
+ {
+ AddMenuItem( fileMenu, openRecentMenu,
+ wxID_ANY, _( "Open &Recent" ),
+ _( "Open a recent opened schematic project" ),
+ KiBitmap( open_project_xpm ) );
+ }
+
+ AddMenuItem( fileMenu,
+ ID_APPEND_PROJECT, _( "App&end Schematic Sheet" ),
+ _( "Append schematic sheet to current project" ),
+ KiBitmap( open_document_xpm ) );
+
+ fileMenu->AppendSeparator();
+
+ text = AddHotkeyName( _( "&Save Schematic Project" ),
+ g_Schematic_Hokeys_Descr, HK_SAVE_SCH );
+ AddMenuItem( fileMenu,
+ ID_SAVE_PROJECT, text,
+ _( "Save all sheets in schematic project" ),
+ KiBitmap( save_project_xpm ) );
+
+ AddMenuItem( fileMenu,
+ ID_UPDATE_ONE_SHEET,
+ _( "Save &Current Sheet Only" ),
+ _( "Save only current schematic sheet" ),
+ KiBitmap( save_xpm ) );
+
+ if( Kiface().IsSingle() ) // not when under a project mgr
+ {
+ AddMenuItem( fileMenu,
+ ID_SAVE_ONE_SHEET_UNDER_NEW_NAME,
+ _( "Save C&urrent Sheet As" ),
+ _( "Save current schematic sheet as..." ),
+ KiBitmap( save_as_xpm ) );
+ }
+
+ fileMenu->AppendSeparator();
+
+ AddMenuItem( fileMenu,
+ ID_SHEET_SET,
+ _( "Pa&ge Settings" ),
+ _( "Setting for sheet size and frame references" ),
+ KiBitmap( sheetset_xpm ) );
+
+ AddMenuItem( fileMenu,
+ wxID_PRINT,
+ _( "Pri&nt" ),
+ _( "Print schematic sheet" ),
+ KiBitmap( print_button_xpm ) );
+
+ // Plot submenu
+ wxMenu* choice_plot_fmt = new wxMenu;
+ AddMenuItem( choice_plot_fmt, ID_GEN_PLOT_SCHEMATIC,
+ _( "&Plot" ),
+ _( "Plot schematic sheet in PostScript, PDF, SVG, DXF or HPGL format" ),
+ KiBitmap( plot_xpm ) );
+
+ // Plot to Clipboard
+ AddMenuItem( choice_plot_fmt, ID_GEN_COPY_SHEET_TO_CLIPBOARD,
+ _( "Plot to C&lipboard" ),
+ _( "Export drawings to clipboard" ),
+ KiBitmap( copy_button_xpm ) );
+
+ // Plot
+ AddMenuItem( fileMenu, choice_plot_fmt,
+ ID_GEN_PLOT, _( "&Plot" ),
+ _( "Plot schematic sheet in HPGL, PostScript or SVG format" ),
+ KiBitmap( plot_xpm ) );
+
+ // Separator
+ fileMenu->AppendSeparator();
+
+ // Quit
+ AddMenuItem( fileMenu,
+ wxID_EXIT,
+ _( "&Close" ),
+ _( "Close Eeschema" ),
+ KiBitmap( exit_xpm ) );
+
+ // Menu Edit:
+ wxMenu* editMenu = new wxMenu;
+
+ // Undo
+ text = AddHotkeyName( _( "&Undo" ), g_Schematic_Hokeys_Descr, HK_UNDO );
+
+ AddMenuItem( editMenu, wxID_UNDO, text, HELP_UNDO, KiBitmap( undo_xpm ) );
+
+ // Redo
+ text = AddHotkeyName( _( "&Redo" ), g_Schematic_Hokeys_Descr, HK_REDO );
+
+ AddMenuItem( editMenu, wxID_REDO, text, HELP_REDO, KiBitmap( redo_xpm ) );
+
+ // Delete
+ editMenu->AppendSeparator();
+ AddMenuItem( editMenu, ID_SCHEMATIC_DELETE_ITEM_BUTT,
+ _( "&Delete" ), HELP_DELETE_ITEMS,
+ KiBitmap( delete_xpm ) );
+
+ // Find
+ editMenu->AppendSeparator();
+ text = AddHotkeyName( _( "&Find" ), g_Schematic_Hokeys_Descr, HK_FIND_ITEM );
+ AddMenuItem( editMenu, ID_FIND_ITEMS, text, HELP_FIND, KiBitmap( find_xpm ) );
+
+ // Find/Replace
+ text = AddHotkeyName( _( "Find and Re&place" ), g_Schematic_Hokeys_Descr,
+ HK_FIND_REPLACE );
+ AddMenuItem( editMenu, wxID_REPLACE, text, HELP_REPLACE,
+ KiBitmap( find_replace_xpm ) );
+
+ // Import footprint association from the CvPcb cmp file:
+ editMenu->AppendSeparator();
+ AddMenuItem( editMenu, ID_BACKANNO_ITEMS,
+ _( "Import Footprint Selection" ),
+ HELP_IMPORT_FOOTPRINTS,
+ KiBitmap( import_footprint_names_xpm ) );
+
+ // Menu View:
+ wxMenu* viewMenu = new wxMenu;
+
+ /**
+ * Important Note for ZOOM IN and ZOOM OUT commands from menubar:
+ * we cannot add hotkey shortcut here, because the hotkey HK_ZOOM_IN and HK_ZOOM_OUT
+ * events(default = WXK_F1 and WXK_F2) are *NOT* equivalent to this menu command:
+ * zoom in and out from hotkeys are equivalent to the pop up menu zoom
+ * From here, zooming is made around the screen center
+ * From hotkeys, zooming is made around the mouse cursor position
+ * (obviously not possible from the toolbar or menubar command)
+ *
+ * in others words HK_ZOOM_IN and HK_ZOOM_OUT *are NOT* accelerators
+ * for Zoom in and Zoom out sub menus
+ * SO WE ADD THE NAME OF THE CORRESPONDING HOTKEY AS A COMMENT, NOT AS A SHORTCUT
+ * using in AddHotkeyName call the option "false" (not a shortcut)
+ */
+
+ text = AddHotkeyName( _( "Zoom &In" ), g_Schematic_Hokeys_Descr,
+ HK_ZOOM_IN, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( viewMenu, ID_ZOOM_IN, text, HELP_ZOOM_IN, KiBitmap( zoom_in_xpm ) );
+
+ text = AddHotkeyName( _( "Zoom &Out" ), g_Schematic_Hokeys_Descr,
+ HK_ZOOM_OUT, IS_ACCELERATOR ); // add accelerator, not a shortcut
+ AddMenuItem( viewMenu, ID_ZOOM_OUT, text, HELP_ZOOM_OUT, KiBitmap( zoom_out_xpm ) );
+
+ text = AddHotkeyName( _( "&Fit on Screen" ), g_Schematic_Hokeys_Descr, HK_ZOOM_AUTO );
+
+ AddMenuItem( viewMenu, ID_ZOOM_PAGE, text, HELP_ZOOM_FIT, KiBitmap( zoom_fit_in_page_xpm ) );
+
+ text = AddHotkeyName( _( "&Redraw" ), g_Schematic_Hokeys_Descr, HK_ZOOM_REDRAW );
+
+ AddMenuItem( viewMenu, ID_ZOOM_REDRAW, text, HELP_ZOOM_REDRAW, KiBitmap( zoom_redraw_xpm ) );
+
+ viewMenu->AppendSeparator();
+
+ AddMenuItem( viewMenu,
+ ID_HIERARCHY,
+ _( "Show &Hierarchical Navigator" ),
+ _( "Navigate hierarchical sheets" ),
+ KiBitmap( hierarchy_nav_xpm ) );
+
+ text = AddHotkeyName( _( "&Leave Sheet" ), g_Schematic_Hokeys_Descr, HK_LEAVE_SHEET );
+
+ AddMenuItem( viewMenu,
+ ID_POPUP_SCH_LEAVE_SHEET,
+ text,
+ _( "Leave Sheet" ),
+ KiBitmap( leave_sheet_xpm ) );
+
+ // Menu place:
+ wxMenu* placeMenu = new wxMenu;
+
+ text = AddHotkeyName( _( "&Component" ), g_Schematic_Hokeys_Descr,
+ HK_ADD_NEW_COMPONENT, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_SCH_PLACE_COMPONENT, text,
+ HELP_PLACE_COMPONENTS,
+ KiBitmap( add_component_xpm ) );
+
+ text = AddHotkeyName( _( "&Power Port" ), g_Schematic_Hokeys_Descr,
+ HK_ADD_NEW_POWER, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_PLACE_POWER_BUTT, text,
+ HELP_PLACE_POWERPORT,
+ KiBitmap( add_power_xpm ) );
+
+ text = AddHotkeyName( _( "&Wire" ), g_Schematic_Hokeys_Descr,
+ HK_BEGIN_WIRE, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_WIRE_BUTT, text,
+ HELP_PLACE_WIRE,
+ KiBitmap( add_line_xpm ) );
+
+ text = AddHotkeyName( _( "&Bus" ), g_Schematic_Hokeys_Descr,
+ HK_BEGIN_BUS, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_BUS_BUTT, text,
+ HELP_PLACE_BUS,
+ KiBitmap( add_bus_xpm ) );
+
+ text = AddHotkeyName( _( "Wire to Bus &Entry" ), g_Schematic_Hokeys_Descr,
+ HK_ADD_WIRE_ENTRY, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_WIRETOBUS_ENTRY_BUTT, text,
+ HELP_PLACE_WIRE2BUS_ENTRY,
+ KiBitmap( add_line2bus_xpm ) );
+
+ text = AddHotkeyName( _( "Bus &to Bus Entry" ), g_Schematic_Hokeys_Descr,
+ HK_ADD_BUS_ENTRY, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_BUSTOBUS_ENTRY_BUTT, text,
+ HELP_PLACE_BUS2BUS_ENTRY,
+ KiBitmap( add_bus2bus_xpm ) );
+
+ text = AddHotkeyName( _( "&No Connect Flag" ), g_Schematic_Hokeys_Descr,
+ HK_ADD_NOCONN_FLAG, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_NOCONN_BUTT, text, HELP_PLACE_NC_FLAG, KiBitmap( noconn_xpm ) );
+
+ text = AddHotkeyName( _( "&Junction" ), g_Schematic_Hokeys_Descr,
+ HK_ADD_JUNCTION, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_JUNCTION_BUTT, text,
+ HELP_PLACE_JUNCTION,
+ KiBitmap( add_junction_xpm ) );
+
+ text = AddHotkeyName( _( "&Label" ), g_Schematic_Hokeys_Descr,
+ HK_ADD_LABEL, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_LABEL_BUTT, text,
+ HELP_PLACE_NETLABEL,
+ KiBitmap( add_line_label_xpm ) );
+
+ text = AddHotkeyName( _( "Gl&obal Label" ), g_Schematic_Hokeys_Descr,
+ HK_ADD_GLABEL, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_GLABEL_BUTT, text,
+ HELP_PLACE_GLOBALLABEL,
+ KiBitmap( add_glabel_xpm ) );
+
+ placeMenu->AppendSeparator();
+
+ text = AddHotkeyName( _( "&Hierarchical Label" ), g_Schematic_Hokeys_Descr,
+ HK_ADD_HLABEL, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_HIERLABEL_BUTT,
+ text, HELP_PLACE_HIER_LABEL,
+ KiBitmap( add_hierarchical_label_xpm ) );
+
+
+ text = AddHotkeyName( _( "Hierarchical &Sheet" ), g_Schematic_Hokeys_Descr,
+ HK_ADD_HIER_SHEET, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_SHEET_SYMBOL_BUTT, text,
+ HELP_PLACE_SHEET,
+ KiBitmap( add_hierarchical_subsheet_xpm ) );
+
+ AddMenuItem( placeMenu,
+ ID_IMPORT_HLABEL_BUTT,
+ _( "I&mport Hierarchical Label" ),
+ HELP_IMPORT_SHEETPIN,
+ KiBitmap( import_hierarchical_label_xpm ) );
+
+ AddMenuItem( placeMenu,
+ ID_SHEET_PIN_BUTT,
+ _( "Hierarchical Pi&n to Sheet" ),
+ HELP_PLACE_SHEETPIN,
+ KiBitmap( add_hierar_pin_xpm ) );
+
+ placeMenu->AppendSeparator();
+
+ text = AddHotkeyName( _( "Graphic Pol&yline" ), g_Schematic_Hokeys_Descr,
+ HK_ADD_GRAPHIC_POLYLINE, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_LINE_COMMENT_BUTT, text,
+ HELP_PLACE_GRAPHICLINES,
+ KiBitmap( add_dashed_line_xpm ) );
+
+ text = AddHotkeyName( _( "&Graphic Text" ), g_Schematic_Hokeys_Descr,
+ HK_ADD_GRAPHIC_TEXT, IS_ACCELERATOR ); // add an accelerator, not a shortcut
+ AddMenuItem( placeMenu, ID_TEXT_COMMENT_BUTT, text,
+ HELP_PLACE_GRAPHICTEXTS,
+ KiBitmap( add_text_xpm ) );
+
+ // Graphic image
+ AddMenuItem( placeMenu, ID_ADD_IMAGE_BUTT, _( "&Image" ),
+ HELP_PLACE_GRAPHICIMAGES,
+ KiBitmap( image_xpm ) );
+
+ // Menu Preferences:
+ wxMenu* preferencesMenu = new wxMenu;
+
+ // Library
+ AddMenuItem( preferencesMenu,
+ ID_CONFIG_REQ,
+ _( "Component &Libraries" ),
+ _( "Configure component libraries and paths" ),
+ KiBitmap( library_xpm ) );
+
+ // Colors
+ AddMenuItem( preferencesMenu,
+ ID_COLORS_SETUP,
+ _( "Set &Colors Scheme" ),
+ _( "Set color preferences" ),
+ KiBitmap( palette_xpm ) );
+
+ // Options (Preferences on WXMAC)
+
+#ifdef __WXMAC__
+ preferencesMenu->Append( wxID_PREFERENCES );
+#else
+ AddMenuItem( preferencesMenu,
+ wxID_PREFERENCES,
+ _( "Schematic Editor &Options" ),
+ _( "Set Eeschema preferences" ),
+ KiBitmap( preference_xpm ) );
+#endif // __WXMAC__
+
+
+ // Language submenu
+ Pgm().AddMenuLanguageList( preferencesMenu );
+
+ // Hotkey submenu
+ AddHotkeyConfigMenu( preferencesMenu );
+
+ // Separator
+ preferencesMenu->AppendSeparator();
+
+ AddMenuItem( preferencesMenu,
+ ID_CONFIG_SAVE,
+ _( "&Save Preferences" ),
+ _( "Save application preferences" ),
+ KiBitmap( save_setup_xpm ) );
+
+ AddMenuItem( preferencesMenu,
+ ID_CONFIG_READ,
+ _( "Load Prefe&rences" ),
+ _( "Load application preferences" ),
+ KiBitmap( read_setup_xpm ) );
+
+ // Menu Tools:
+ wxMenu* toolsMenu = new wxMenu;
+
+ AddMenuItem( toolsMenu,
+ ID_RUN_LIBRARY,
+ _( "Library &Editor" ), HELP_RUN_LIB_EDITOR,
+ KiBitmap( libedit_xpm ) );
+
+ AddMenuItem( toolsMenu,
+ ID_TO_LIBVIEW,
+ _( "Library &Browser" ), HELP_RUN_LIB_VIEWER,
+ KiBitmap( library_browse_xpm ) );
+
+ AddMenuItem( toolsMenu,
+ ID_RESCUE_CACHED,
+ _( "&Rescue Old Components" ),
+ _( "Find old components in the project and rename/rescue them" ),
+ KiBitmap( copycomponent_xpm ) );
+
+ toolsMenu->AppendSeparator();
+
+ AddMenuItem( toolsMenu,
+ ID_GET_ANNOTATE,
+ _( "&Annotate Schematic" ), HELP_ANNOTATE,
+ KiBitmap( annotate_xpm ) );
+
+ // ERC
+ AddMenuItem( toolsMenu,
+ ID_GET_ERC,
+ _( "Electrical Rules &Checker" ),
+ _( "Perform electrical rules check" ),
+ KiBitmap( erc_xpm ) );
+
+ AddMenuItem( toolsMenu,
+ ID_GET_NETLIST,
+ _( "Generate &Netlist File" ),
+ _( "Generate the component netlist file" ),
+ KiBitmap( netlist_xpm ) );
+
+ AddMenuItem( toolsMenu,
+ ID_GET_TOOLS,
+ _( "Generate Bill of &Materials" ),
+ HELP_GENERATE_BOM,
+ KiBitmap( bom_xpm ) );
+
+ toolsMenu->AppendSeparator();
+
+ // Run CvPcb
+ AddMenuItem( toolsMenu,
+ ID_RUN_CVPCB,
+ _( "A&ssign Component Footprint" ),
+ _( "Run CvPcb" ),
+ KiBitmap( cvpcb_xpm ) );
+
+ // Run Pcbnew
+ AddMenuItem( toolsMenu,
+ ID_RUN_PCB,
+ _( "&Layout Printed Circuit Board" ),
+ _( "Run Pcbnew" ),
+ KiBitmap( pcbnew_xpm ) );
+
+ // Help Menu:
+ wxMenu* helpMenu = new wxMenu;
+
+ // Version info
+ AddHelpVersionInfoMenuEntry( helpMenu );
+
+ AddMenuItem( helpMenu,
+ wxID_HELP,
+ _( "Eeschema &Manual" ),
+ _( "Open Eeschema Manual" ),
+ KiBitmap( online_help_xpm ) );
+
+ AddMenuItem( helpMenu,
+ wxID_INDEX,
+ _( "&Getting Started in KiCad" ),
+ _( "Open \"Getting Started in KiCad\" guide for beginners" ),
+ KiBitmap( help_xpm ) );
+
+ helpMenu->AppendSeparator();
+ AddMenuItem( helpMenu,
+ wxID_ABOUT,
+ _( "&About KiCad" ),
+ _( "About KiCad" ),
+ KiBitmap( info_xpm ) );
+
+ // Create the menubar and append all submenus
+ menuBar->Append( fileMenu, _( "&File" ) );
+ menuBar->Append( editMenu, _( "&Edit" ) );
+ menuBar->Append( viewMenu, _( "&View" ) );
+ menuBar->Append( placeMenu, _( "&Place" ) );
+ menuBar->Append( preferencesMenu, _( "P&references" ) );
+ menuBar->Append( toolsMenu, _( "&Tools" ) );
+ menuBar->Append( helpMenu, _( "&Help" ) );
+
+ menuBar->Thaw();
+
+ // Associate the menu bar with the frame, if no previous menubar
+ if( GetMenuBar() == NULL )
+ SetMenuBar( menuBar );
+ else
+ menuBar->Refresh();
+}
diff --git a/eeschema/menubar_libedit.cpp b/eeschema/menubar_libedit.cpp
new file mode 100644
index 0000000..f2c9599
--- /dev/null
+++ b/eeschema/menubar_libedit.cpp
@@ -0,0 +1,297 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2009-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/menubar_libedit.cpp
+ * @brief (Re)Create the main menubar for the component editor frame (LibEdit)
+ */
+#include <fctsys.h>
+#include <pgm_base.h>
+
+#include <general.h>
+#include <libeditframe.h>
+#include <eeschema_id.h>
+#include <hotkeys.h>
+
+#include <help_common_strings.h>
+#include <menus_helpers.h>
+
+/**
+ * @brief (Re)Create the menubar for the component editor frame
+ */
+void LIB_EDIT_FRAME::ReCreateMenuBar()
+{
+ // Create and try to get the current menubar
+ wxString text;
+ wxMenuBar* menuBar = GetMenuBar();
+
+ if( !menuBar )
+ menuBar = new wxMenuBar();
+
+ // Delete all existing menus so they can be rebuilt.
+ // This allows language changes of the menu text on the fly.
+ menuBar->Freeze();
+
+ while( menuBar->GetMenuCount() )
+ delete menuBar->Remove( 0 );
+
+ // Recreate all menus:
+
+ // Menu File:
+ wxMenu* fileMenu = new wxMenu;
+
+ // Select current library
+ AddMenuItem( fileMenu,
+ ID_LIBEDIT_SELECT_CURRENT_LIB,
+ _( "&Current Library" ),
+ _( "Select working library" ),
+ KiBitmap( library_xpm ) );
+ fileMenu->AppendSeparator();
+
+ // Save current library
+ AddMenuItem( fileMenu,
+ ID_LIBEDIT_SAVE_CURRENT_LIB,
+ _( "&Save Current Library\tCtrl+S" ),
+ _( "Save the current active library" ),
+ KiBitmap( save_xpm ) );
+
+ // Save current library as...
+ AddMenuItem( fileMenu,
+ ID_LIBEDIT_SAVE_CURRENT_LIB_AS,
+ _( "Save Current Library &As" ),
+ _( "Save current active library as..." ),
+ KiBitmap( save_as_xpm ) );
+
+ // Separator
+ fileMenu->AppendSeparator();
+
+ // Export as png file
+ AddMenuItem( fileMenu,
+ ID_LIBEDIT_GEN_PNG_FILE,
+ _( "Create &PNG File from Screen" ),
+ _( "Create a PNG file from the component displayed on screen" ),
+ KiBitmap( plot_xpm ) );
+
+ // Export as SVG file
+ AddMenuItem( fileMenu,
+ ID_LIBEDIT_GEN_SVG_FILE,
+ _( "Create S&VG File" ),
+ _( "Create a SVG file from the current loaded component" ),
+ KiBitmap( plot_svg_xpm ) );
+
+ // Separator
+ fileMenu->AppendSeparator();
+
+ // Quit
+ AddMenuItem( fileMenu,
+ wxID_EXIT,
+ _( "&Quit" ),
+ _( "Quit Library Editor" ),
+ KiBitmap( exit_xpm ) );
+
+ // Edit menu
+ wxMenu* editMenu = new wxMenu;
+
+ // Undo
+ text = AddHotkeyName( _( "&Undo" ), g_Libedit_Hokeys_Descr, HK_UNDO );
+
+ AddMenuItem( editMenu,
+ wxID_UNDO,
+ text,
+ _( "Undo last edit" ),
+ KiBitmap( undo_xpm ) );
+
+ // Redo
+ text = AddHotkeyName( _( "&Redo" ), g_Libedit_Hokeys_Descr, HK_REDO );
+ AddMenuItem( editMenu,
+ wxID_REDO,
+ text,
+ _( "Redo the last undo command" ),
+ KiBitmap( redo_xpm ) );
+
+ // Separator
+ editMenu->AppendSeparator();
+
+ // Delete
+ AddMenuItem( editMenu,
+ ID_LIBEDIT_DELETE_ITEM_BUTT,
+ _( "&Delete" ),
+ HELP_DELETE_ITEMS,
+ KiBitmap( delete_xpm ) );
+
+ // Menu View:
+ wxMenu* viewMenu = new wxMenu;
+
+ /**
+ * Important Note for ZOOM IN and ZOOM OUT commands from menubar:
+ * we cannot add hotkey info here, because the hotkey HK_ZOOM_IN and HK_ZOOM_OUT
+ * events(default = WXK_F1 and WXK_F2) are *NOT* equivalent to this menu command:
+ * zoom in and out from hotkeys are equivalent to the pop up menu zoom
+ * From here, zooming is made around the screen center
+ * From hotkeys, zooming is made around the mouse cursor position
+ * (obviously not possible from the toolbar or menubar command)
+ *
+ * in others words HK_ZOOM_IN and HK_ZOOM_OUT *are NOT* accelerators
+ * for Zoom in and Zoom out sub menus
+ */
+
+ // Zoom in
+ text = _( "Zoom &In" );
+ AddMenuItem( viewMenu, ID_ZOOM_IN, text, HELP_ZOOM_IN, KiBitmap( zoom_in_xpm ) );
+
+ // Zoom out
+ text = _( "Zoom &Out" );
+ AddMenuItem( viewMenu, ID_ZOOM_OUT, text, HELP_ZOOM_OUT, KiBitmap( zoom_out_xpm ) );
+
+ // Fit on screen
+ text = AddHotkeyName( _( "&Fit on Screen" ), g_Libedit_Hokeys_Descr, HK_ZOOM_AUTO );
+ AddMenuItem( viewMenu, ID_ZOOM_PAGE, text, HELP_ZOOM_FIT, KiBitmap( zoom_fit_in_page_xpm ) );
+
+ // Separator
+ viewMenu->AppendSeparator();
+
+ // Redraw
+ text = AddHotkeyName( _( "&Redraw" ), g_Libedit_Hokeys_Descr, HK_ZOOM_REDRAW );
+ AddMenuItem( viewMenu, ID_ZOOM_REDRAW, text, HELP_ZOOM_REDRAW, KiBitmap( zoom_redraw_xpm ) );
+
+ // Menu Place:
+ wxMenu* placeMenu = new wxMenu;
+
+ // Pin
+ AddMenuItem( placeMenu,
+ ID_LIBEDIT_PIN_BUTT,
+ _( "&Pin" ),
+ HELP_ADD_PIN,
+ KiBitmap( pin_xpm ) );
+
+ // Graphic text
+ AddMenuItem( placeMenu,
+ ID_LIBEDIT_BODY_TEXT_BUTT,
+ _( "Graphic &Text" ),
+ HELP_ADD_BODYTEXT,
+ KiBitmap( add_text_xpm ) );
+
+ // Graphic rectangle
+ AddMenuItem( placeMenu,
+ ID_LIBEDIT_BODY_RECT_BUTT,
+ _( "&Rectangle" ),
+ HELP_ADD_BODYRECT,
+ KiBitmap( add_rectangle_xpm ) );
+
+ // Graphic Circle
+ AddMenuItem( placeMenu,
+ ID_LIBEDIT_BODY_CIRCLE_BUTT,
+ _( "&Circle" ),
+ HELP_ADD_BODYCIRCLE,
+ KiBitmap( add_circle_xpm ) );
+
+ // Graphic Arc
+ AddMenuItem( placeMenu,
+ ID_LIBEDIT_BODY_ARC_BUTT,
+ _( "&Arc" ),
+ HELP_ADD_BODYARC,
+ KiBitmap( add_arc_xpm ) );
+
+ // Graphic Line or Polygon
+ AddMenuItem( placeMenu,
+ ID_LIBEDIT_BODY_LINE_BUTT,
+ _( "&Line or Polygon" ),
+ HELP_ADD_BODYPOLYGON,
+ KiBitmap( add_polygon_xpm ) );
+
+ // Menu Preferences:
+ wxMenu* preferencesMenu = new wxMenu;
+
+ // Library list
+ AddMenuItem( preferencesMenu,
+ ID_CONFIG_REQ,
+ _( "Component &Libraries" ),
+ _( "Configure component libraries and paths" ),
+ KiBitmap( library_xpm ) );
+
+ // Default values and options
+ AddMenuItem( preferencesMenu,
+ wxID_PREFERENCES,
+ _( "Component Editor &Options" ),
+ _( "Set Component Editor default values and options" ),
+ KiBitmap( preference_xpm ) );
+
+ // Colors
+ AddMenuItem( preferencesMenu,
+ ID_COLORS_SETUP,
+ _( "Set &Colors Scheme" ),
+ _( "Set color preferences" ),
+ KiBitmap( palette_xpm ) );
+
+ // Language submenu
+ Pgm().AddMenuLanguageList( preferencesMenu );
+
+ // Hotkey submenu
+ AddHotkeyConfigMenu( preferencesMenu );
+
+ // Menu Help:
+ wxMenu* helpMenu = new wxMenu;
+
+ // Version info
+ AddHelpVersionInfoMenuEntry( helpMenu );
+
+ // Contents
+ AddMenuItem( helpMenu,
+ wxID_HELP,
+ _( "Eeschema &Manual" ),
+ _( "Open the Eeschema Manual" ),
+ KiBitmap( online_help_xpm ) );
+
+ AddMenuItem( helpMenu,
+ wxID_INDEX,
+ _( "&Getting Started in KiCad" ),
+ _( "Open the \"Getting Started in KiCad\" guide for beginners" ),
+ KiBitmap( help_xpm ) );
+
+ // About Eeschema
+ helpMenu->AppendSeparator();
+
+ AddMenuItem( helpMenu,
+ wxID_ABOUT,
+ _( "&About KiCad" ),
+ _( "About KiCad" ),
+ KiBitmap( info_xpm ) );
+
+ // Create the menubar and append all submenus
+ menuBar->Append( fileMenu, _( "&File" ) );
+ menuBar->Append( editMenu, _( "&Edit" ) );
+ menuBar->Append( viewMenu, _( "&View" ) );
+ menuBar->Append( placeMenu, _( "&Place" ) );
+ menuBar->Append( preferencesMenu, _( "P&references" ) );
+ menuBar->Append( helpMenu, _( "&Help" ) );
+
+ menuBar->Thaw();
+
+ // Associate the menu bar with the frame, if no previous menubar
+ if( GetMenuBar() == NULL )
+ SetMenuBar( menuBar );
+ else
+ menuBar->Refresh();
+}
diff --git a/eeschema/netform.cpp b/eeschema/netform.cpp
new file mode 100644
index 0000000..4939476
--- /dev/null
+++ b/eeschema/netform.cpp
@@ -0,0 +1,149 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/netform.cpp
+ * @brief Net list generation code.
+ */
+
+#include <fctsys.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <pgm_base.h>
+#include <schframe.h>
+#include <reporter.h>
+
+#include <netlist.h>
+#include <netlist_exporter.h>
+#include <netlist_exporter_orcadpcb2.h>
+#include <netlist_exporter_cadstar.h>
+#include <netlist_exporter_pspice.h>
+#include <netlist_exporter_kicad.h>
+#include <netlist_exporter_generic.h>
+
+bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList,
+ int aFormat, const wxString& aFullFileName,
+ unsigned aNetlistOptions, REPORTER* aReporter )
+{
+ bool res = true;
+ bool executeCommandLine = false;
+
+ wxString fileName = aFullFileName;
+
+ NETLIST_EXPORTER *helper;
+
+ switch( aFormat )
+ {
+ case NET_TYPE_PCBNEW:
+ helper = new NETLIST_EXPORTER_KICAD( aConnectedItemsList, Prj().SchLibs() );
+ break;
+
+ case NET_TYPE_ORCADPCB2:
+ helper = new NETLIST_EXPORTER_ORCADPCB2( aConnectedItemsList, Prj().SchLibs() );
+ break;
+
+ case NET_TYPE_CADSTAR:
+ helper = new NETLIST_EXPORTER_CADSTAR( aConnectedItemsList, Prj().SchLibs() );
+ break;
+
+ case NET_TYPE_SPICE:
+ helper = new NETLIST_EXPORTER_PSPICE( aConnectedItemsList, Prj().SchLibs() );
+ break;
+
+ default:
+ {
+ wxFileName tmpFile = fileName;
+ tmpFile.SetExt( GENERIC_INTERMEDIATE_NETLIST_EXT );
+ fileName = tmpFile.GetFullPath();
+
+ helper = new NETLIST_EXPORTER_GENERIC( aConnectedItemsList, Prj().SchLibs() );
+ executeCommandLine = true;
+ }
+ break;
+ }
+
+ res = helper->WriteNetlist( fileName, aNetlistOptions );
+ delete helper;
+
+ // If user provided a plugin command line, execute it.
+ if( executeCommandLine && res && !m_netListerCommand.IsEmpty() )
+ {
+ wxString prj_dir = Prj().GetProjectPath();
+
+ // build full command line from user's format string, e.g.:
+ // "xsltproc -o %O /usr/local/lib/kicad/plugins/netlist_form_pads-pcb.xsl %I"
+ // becomes, after the user selects /tmp/s1.net as the output file from the file dialog:
+ // "xsltproc -o /tmp/s1.net /usr/local/lib/kicad/plugins/netlist_form_pads-pcb.xsl /tmp/s1.xml"
+ wxString commandLine = NETLIST_EXPORTER::MakeCommandLine( m_netListerCommand,
+ fileName, aFullFileName,
+ prj_dir.SubString( 0, prj_dir.Len() - 2 ) // strip trailing '/'
+ );
+
+ if( aReporter )
+ {
+ wxArrayString output, errors;
+ int diag = wxExecute( commandLine, output, errors, wxEXEC_SYNC );
+
+ wxString msg;
+
+ msg << _( "Run command:" ) << wxT( "\n" ) << commandLine << wxT( "\n\n" );
+
+ aReporter->Report( msg, REPORTER::RPT_ACTION );
+
+ if( diag != 0 )
+ aReporter->Report( wxString::Format(
+ _("Command error. Return code %d" ), diag ),
+ REPORTER::RPT_ERROR );
+ else
+ aReporter->Report( _( "Success" ), REPORTER::RPT_INFO );
+
+ *aReporter << wxT("\n");
+
+ if( output.GetCount() )
+ {
+ msg.Empty();
+ msg << wxT( "\n" ) << _( "Info messages:" ) << wxT( "\n" );
+ aReporter->Report( msg, REPORTER::RPT_INFO );
+
+ for( unsigned ii = 0; ii < output.GetCount(); ii++ )
+ aReporter->Report( output[ii] + wxT( "\n" ), REPORTER::RPT_INFO );
+ }
+
+ if( errors.GetCount() )
+ {
+ msg.Empty();
+ msg << wxT("\n") << _( "Error messages:" ) << wxT( "\n" );
+ aReporter->Report( msg, REPORTER::RPT_INFO );
+
+ for( unsigned ii = 0; ii < errors.GetCount(); ii++ )
+ aReporter->Report( errors[ii] + wxT( "\n" ), REPORTER::RPT_ERROR );
+ }
+ }
+ else
+ ProcessExecute( commandLine, wxEXEC_SYNC );
+ }
+
+ return res;
+}
diff --git a/eeschema/netlist.cpp b/eeschema/netlist.cpp
new file mode 100644
index 0000000..10a1ddd
--- /dev/null
+++ b/eeschema/netlist.cpp
@@ -0,0 +1,971 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/netlist.cpp
+ */
+
+#include <fctsys.h>
+#include <schframe.h>
+#include <confirm.h>
+#include <netlist_exporter_kicad.h>
+#include <kiway.h>
+
+#include <netlist.h>
+#include <class_netlist_object.h>
+#include <class_library.h>
+#include <lib_pin.h>
+#include <sch_junction.h>
+#include <sch_component.h>
+#include <sch_line.h>
+#include <sch_no_connect.h>
+#include <sch_text.h>
+#include <sch_sheet.h>
+#include <algorithm>
+#include <invoke_sch_dialog.h>
+#include <boost/foreach.hpp>
+
+#define IS_WIRE false
+#define IS_BUS true
+
+//Imported function:
+int TestDuplicateSheetNames( bool aCreateMarker );
+
+
+bool SCH_EDIT_FRAME::prepareForNetlist()
+{
+ SCH_SHEET_LIST sheets;
+
+ sheets.AnnotatePowerSymbols( Prj().SchLibs() );
+
+ // Performs some controls:
+ if( CheckAnnotate( NULL, 0 ) )
+ {
+ // Schematic must be annotated: call Annotate dialog and tell
+ // the user why that is.
+ InvokeDialogAnnotate( this, _( "Exporting the netlist requires a "
+ "completely\nannotated schematic." ) );
+
+ if( CheckAnnotate( NULL, 0 ) )
+ return false;
+ }
+
+ // Test duplicate sheet names:
+ if( TestDuplicateSheetNames( false ) > 0 )
+ {
+ if( !IsOK( NULL, _( "Error: duplicate sheet names. Continue?" ) ) )
+ return false;
+ }
+
+ // Cleanup the entire hierarchy
+ SCH_SCREENS screens;
+
+ screens.SchematicCleanUp();
+
+ return true;
+}
+
+
+void SCH_EDIT_FRAME::sendNetlist()
+{
+ NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase();
+
+ NETLIST_EXPORTER_KICAD exporter( net_atoms, Prj().SchLibs() );
+
+ STRING_FORMATTER formatter;
+
+ // @todo : trim GNL_ALL down to minimum for CVPCB
+ exporter.Format( &formatter, GNL_ALL );
+
+ Kiway().ExpressMail( FRAME_CVPCB,
+ MAIL_EESCHEMA_NETLIST,
+ formatter.GetString(), // an abbreviated "kicad" (s-expr) netlist
+ this
+ );
+}
+
+
+bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName,
+ unsigned aNetlistOptions, REPORTER* aReporter )
+{
+ if( !prepareForNetlist() )
+ return false;
+
+ std::auto_ptr<NETLIST_OBJECT_LIST> connectedItemsList( BuildNetListBase() );
+
+ bool success = WriteNetListFile( connectedItemsList.release(), aFormat,
+ aFullFileName, aNetlistOptions, aReporter );
+
+ return success;
+}
+
+
+//#define NETLIST_DEBUG
+
+NETLIST_OBJECT_LIST::~NETLIST_OBJECT_LIST()
+{
+ Clear();
+}
+
+
+void NETLIST_OBJECT_LIST::Clear()
+{
+ NETLIST_OBJECTS::iterator iter;
+
+ for( iter = begin(); iter != end(); iter++ )
+ {
+ NETLIST_OBJECT* item = *iter;
+ delete item;
+ }
+
+ clear();
+}
+
+
+void NETLIST_OBJECT_LIST::SortListbyNetcode()
+{
+ sort( this->begin(), this->end(), NETLIST_OBJECT_LIST::sortItemsbyNetcode );
+}
+
+
+void NETLIST_OBJECT_LIST::SortListbySheet()
+{
+ sort( this->begin(), this->end(), NETLIST_OBJECT_LIST::sortItemsBySheet );
+}
+
+
+NETLIST_OBJECT_LIST* SCH_EDIT_FRAME::BuildNetListBase()
+{
+ // I own this list until I return it to the new owner.
+ std::auto_ptr<NETLIST_OBJECT_LIST> ret( new NETLIST_OBJECT_LIST() );
+
+ // Creates the flattened sheet list:
+ SCH_SHEET_LIST aSheets;
+
+ // Build netlist info
+ bool success = ret->BuildNetListInfo( aSheets );
+
+ if( !success )
+ {
+ SetStatusText( _( "No Objects" ) );
+ return ret.release();
+ }
+
+ wxString msg = wxString::Format( _( "Net count = %d" ), int( ret->size() ) );
+
+ SetStatusText( msg );
+
+ return ret.release();
+}
+
+
+bool NETLIST_OBJECT_LIST::BuildNetListInfo( SCH_SHEET_LIST& aSheets )
+{
+ SCH_SHEET_PATH* sheet;
+
+ // Fill list with connected items from the flattened sheet list
+ for( sheet = aSheets.GetFirst(); sheet != NULL;
+ sheet = aSheets.GetNext() )
+ {
+ for( SCH_ITEM* item = sheet->LastScreen()->GetDrawItems(); item; item = item->Next() )
+ {
+ item->GetNetListItem( *this, sheet );
+ }
+ }
+
+ if( size() == 0 )
+ return false;
+
+ // Sort objects by Sheet
+ SortListbySheet();
+
+ sheet = &(GetItem( 0 )->m_SheetPath);
+ m_lastNetCode = m_lastBusNetCode = 1;
+
+ for( unsigned ii = 0, istart = 0; ii < size(); ii++ )
+ {
+ NETLIST_OBJECT* net_item = GetItem( ii );
+
+ if( net_item->m_SheetPath != *sheet ) // Sheet change
+ {
+ sheet = &(net_item->m_SheetPath);
+ istart = ii;
+ }
+
+ switch( net_item->m_Type )
+ {
+ case NET_ITEM_UNSPECIFIED:
+ wxMessageBox( wxT( "BuildNetListInfo() error" ) );
+ break;
+
+ case NET_PIN:
+ case NET_PINLABEL:
+ case NET_SHEETLABEL:
+ case NET_NOCONNECT:
+ if( net_item->GetNet() != 0 )
+ break;
+
+ case NET_SEGMENT:
+ // Test connections point to point type without bus.
+ if( net_item->GetNet() == 0 )
+ {
+ net_item->SetNet( m_lastNetCode );
+ m_lastNetCode++;
+ }
+
+ pointToPointConnect( net_item, IS_WIRE, istart );
+ break;
+
+ case NET_JUNCTION:
+ // Control of the junction outside BUS.
+ if( net_item->GetNet() == 0 )
+ {
+ net_item->SetNet( m_lastNetCode );
+ m_lastNetCode++;
+ }
+
+ segmentToPointConnect( net_item, IS_WIRE, istart );
+
+ // Control of the junction, on BUS.
+ if( net_item->m_BusNetCode == 0 )
+ {
+ net_item->m_BusNetCode = m_lastBusNetCode;
+ m_lastBusNetCode++;
+ }
+
+ segmentToPointConnect( net_item, IS_BUS, istart );
+ break;
+
+ case NET_LABEL:
+ case NET_HIERLABEL:
+ case NET_GLOBLABEL:
+ // Test connections type junction without bus.
+ if( net_item->GetNet() == 0 )
+ {
+ net_item->SetNet( m_lastNetCode );
+ m_lastNetCode++;
+ }
+
+ segmentToPointConnect( net_item, IS_WIRE, istart );
+ break;
+
+ case NET_SHEETBUSLABELMEMBER:
+ if( net_item->m_BusNetCode != 0 )
+ break;
+
+ case NET_BUS:
+ // Control type connections point to point mode bus
+ if( net_item->m_BusNetCode == 0 )
+ {
+ net_item->m_BusNetCode = m_lastBusNetCode;
+ m_lastBusNetCode++;
+ }
+
+ pointToPointConnect( net_item, IS_BUS, istart );
+ break;
+
+ case NET_BUSLABELMEMBER:
+ case NET_HIERBUSLABELMEMBER:
+ case NET_GLOBBUSLABELMEMBER:
+ // Control connections similar has on BUS
+ if( net_item->GetNet() == 0 )
+ {
+ net_item->m_BusNetCode = m_lastBusNetCode;
+ m_lastBusNetCode++;
+ }
+
+ segmentToPointConnect( net_item, IS_BUS, istart );
+ break;
+ }
+ }
+
+#if defined(NETLIST_DEBUG) && defined(DEBUG)
+ std::cout << "\n\nafter sheet local\n\n";
+ DumpNetTable();
+#endif
+
+ // Updating the Bus Labels Netcode connected by Bus
+ connectBusLabels();
+
+ // Group objects by label.
+ for( unsigned ii = 0; ii < size(); ii++ )
+ {
+ switch( GetItem( ii )->m_Type )
+ {
+ case NET_PIN:
+ case NET_SHEETLABEL:
+ case NET_SEGMENT:
+ case NET_JUNCTION:
+ case NET_BUS:
+ case NET_NOCONNECT:
+ break;
+
+ case NET_LABEL:
+ case NET_GLOBLABEL:
+ case NET_PINLABEL:
+ case NET_BUSLABELMEMBER:
+ case NET_GLOBBUSLABELMEMBER:
+ labelConnect( GetItem( ii ) );
+ break;
+
+ case NET_SHEETBUSLABELMEMBER:
+ case NET_HIERLABEL:
+ case NET_HIERBUSLABELMEMBER:
+ break;
+
+ case NET_ITEM_UNSPECIFIED:
+ break;
+ }
+ }
+
+#if defined(NETLIST_DEBUG) && defined(DEBUG)
+ std::cout << "\n\nafter sheet global\n\n";
+ DumpNetTable();
+#endif
+
+ // Connection between hierarchy sheets
+ for( unsigned ii = 0; ii < size(); ii++ )
+ {
+ if( GetItem( ii )->m_Type == NET_SHEETLABEL
+ || GetItem( ii )->m_Type == NET_SHEETBUSLABELMEMBER )
+ sheetLabelConnect( GetItem( ii ) );
+ }
+
+ // Sort objects by NetCode
+ SortListbyNetcode();
+
+#if defined(NETLIST_DEBUG) && defined(DEBUG)
+ std::cout << "\n\nafter qsort()\n";
+ DumpNetTable();
+#endif
+
+ // Compress numbers of Netcode having consecutive values.
+ int NetCode = 0;
+ m_lastNetCode = 0;
+
+ for( unsigned ii = 0; ii < size(); ii++ )
+ {
+ if( GetItem( ii )->GetNet() != m_lastNetCode )
+ {
+ NetCode++;
+ m_lastNetCode = GetItem( ii )->GetNet();
+ }
+
+ GetItem( ii )->SetNet( NetCode );
+ }
+
+ // Set the minimal connection info:
+ setUnconnectedFlag();
+
+ // find the best label object to give the best net name to each net
+ findBestNetNameForEachNet();
+
+ return true;
+}
+
+// Helper function to give a priority to sort labels:
+// NET_PINLABEL, NET_GLOBBUSLABELMEMBER and NET_GLOBLABEL are global labels
+// and the priority is high
+static int getPriority( const NETLIST_OBJECT* Objet )
+{
+ switch( Objet->m_Type )
+ {
+ case NET_PIN: return 1;
+ case NET_LABEL: return 2;
+ case NET_HIERLABEL: return 3;
+ case NET_PINLABEL: return 4;
+ case NET_GLOBBUSLABELMEMBER: return 5;
+ case NET_GLOBLABEL: return 6;
+ default: break;
+ }
+
+ return 0;
+}
+
+
+/* function evalLabelsPriority used by findBestNetNameForEachNet()
+ * evalLabelsPriority calculates the priority of alabel1 and aLabel2
+ * return true if alabel1 has a higher priority than aLabel2
+ */
+static bool evalLabelsPriority( const NETLIST_OBJECT* aLabel1,
+ const NETLIST_OBJECT* aLabel2 )
+{
+ // Global labels have the highest prioriy.
+ // For local labels: names are prefixed by their sheetpath
+ // use name defined in the more top level hierarchical sheet
+ // (i.e. shorter timestamp path because paths are /<timestamp1>/<timestamp2>/...
+ // and timestamp = 8 letters.
+ // Note: the final net name uses human sheetpath name, not timestamp sheetpath name
+ // They are equivalent, but not for human readers.
+ if( ! aLabel1->IsLabelGlobal() && ! aLabel2->IsLabelGlobal() )
+ {
+ if( aLabel1->m_SheetPath.Path().Length() != aLabel2->m_SheetPath.Path().Length() )
+ return aLabel1->m_SheetPath.Path().Length() < aLabel2->m_SheetPath.Path().Length();
+ }
+
+ int priority1 = getPriority( aLabel1 );
+ int priority2 = getPriority( aLabel2 );
+
+ if( priority1 != priority2 )
+ return priority1 > priority2;
+
+ // Objects have here the same priority, therefore they have the same type.
+ // for global labels, we select the best candidate by alphabetic order
+ // because they have no sheetpath as prefix name
+ // for other labels, we select them before by sheet deep order
+ // because the actual name is /sheetpath/label
+ // and for a given path length, by alphabetic order
+ if( aLabel1->IsLabelGlobal() )
+ return aLabel1->m_Label.Cmp( aLabel2->m_Label ) < 0;
+
+ // Sheet paths have here the same length: use alphabetic label name order
+ // For labels on sheets having an equivalent deep in hierarchy, use
+ // alphabetic label name order:
+ if( aLabel1->m_Label.Cmp( aLabel2->m_Label ) != 0 )
+ return aLabel1->m_Label.Cmp( aLabel2->m_Label ) < 0;
+
+ // For identical labels having the same priority: choose the
+ // alphabetic label full name order
+ return aLabel1->m_SheetPath.PathHumanReadable().Cmp(
+ aLabel2->m_SheetPath.PathHumanReadable() ) < 0;
+}
+
+
+void NETLIST_OBJECT_LIST::findBestNetNameForEachNet()
+{
+ // Important note: NET_SHEETLABEL items of sheet items should *NOT* be considered,
+ // because they live in a sheet but their names are actually used in the subsheet.
+ // Moreover, in the parent sheet, the name of NET_SHEETLABEL can be not unique,
+ // ( for instance when 2 different sheets share the same schematic in complex hierarchies
+ // and 2 identical NET_SHEETLABEL labels can be connected to 2 different nets
+
+ int netcode = 0; // current netcode for tested items
+ unsigned idxstart = 0; // index of the first item of this net
+ NETLIST_OBJECT* item;
+ NETLIST_OBJECT* candidate;
+
+ // Pass 1: find the best name for labelled nets:
+ candidate = NULL;
+ for( unsigned ii = 0; ii <= size(); ii++ )
+ {
+ if( ii == size() ) // last item already tested
+ item = NULL;
+ else
+ item = GetItem( ii );
+
+ if( !item || netcode != item->GetNet() ) // End of net found
+ {
+ if( candidate ) // One or more labels exists, find the best
+ {
+ for (unsigned jj = idxstart; jj < ii; jj++ )
+ GetItem( jj )->SetNetNameCandidate( candidate );
+ }
+
+ if( item == NULL ) // End of list
+ break;
+
+ // Prepare next net analysis:
+ netcode = item->GetNet();
+ candidate = NULL;
+ idxstart = ii;
+ }
+
+ switch( item->m_Type )
+ {
+ case NET_HIERLABEL:
+ case NET_LABEL:
+ case NET_PINLABEL:
+ case NET_GLOBLABEL:
+ case NET_GLOBBUSLABELMEMBER:
+ // A candidate is found: select the better between the previous
+ // and this one
+ if( candidate == NULL )
+ candidate = item;
+ else
+ {
+ if( evalLabelsPriority( item, candidate ) )
+ // item has a highter priority than candidate
+ // so update the best candidate
+ candidate = item;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Pass 2: find the best name for not labelled nets:
+ // The "default" net name is Net-<<Ref cmp>_Pad<num pad>>
+ // (see NETLIST_OBJECT::GetShortNetName())
+ // therefore the "best" is the short net name alphabetically classed first
+ // (to avoid net names changes when the net is not modified,
+ // even if components are moved or deleted and undelete or replaced, as long
+ // the reference is kept)
+
+ // Build a list of items with no net names
+ NETLIST_OBJECTS list; // no ownership of elements being pointed at
+
+ for( unsigned ii = 0; ii < size(); ii++ )
+ {
+ item = GetItem( ii );
+ if( !item->HasNetNameCandidate() )
+ list.push_back( item );
+ }
+
+ if( list.size() == 0 )
+ return;
+
+ idxstart = 0;
+ candidate = NULL;
+ netcode = list[0]->GetNet();
+
+ for( unsigned ii = 0; ii <= list.size(); ii++ )
+ {
+ if( ii < list.size() )
+ item = list[ii];
+ else
+ item = NULL;
+
+ if( !item || netcode != item->GetNet() ) // End of net found
+ {
+ if( candidate )
+ {
+ for (unsigned jj = idxstart; jj < ii; jj++ )
+ {
+ NETLIST_OBJECT* obj = list[jj];
+ obj->SetNetNameCandidate( candidate );
+ }
+ }
+
+ if( !item )
+ break;
+
+ netcode = item->GetNet();
+ candidate = NULL;
+ idxstart = ii;
+ }
+
+ // Examine all pins of the net to find the best candidate,
+ // i.e. the first net name candidate, by alphabetic order
+ // the net names are built by GetShortNetName
+ // (Net-<{reference}-Pad{pad number}> like Net-<U3-Pad5>
+ // Not named nets do not have usually a lot of members.
+ // Many have only 2 members(a pad and a non connection symbol)
+ if( item->m_Type == NET_PIN )
+ {
+ // A candidate is found, however components which are not in
+ // netlist are not candidate because some have their reference
+ // changed each time the netlist is built (power components)
+ // and anyway obviously they are not a good candidate
+ SCH_COMPONENT* link = item->GetComponentParent();
+ if( link && link->IsInNetlist() )
+ {
+ // select the better between the previous and this one
+ item->SetNetNameCandidate( item ); // Needed to calculate GetShortNetName
+
+ if( candidate == NULL )
+ candidate = item;
+ else
+ {
+ if( item->GetShortNetName().Cmp( candidate->GetShortNetName() ) < 0 )
+ candidate = item;
+ }
+ }
+ }
+ }
+}
+
+
+void NETLIST_OBJECT_LIST::sheetLabelConnect( NETLIST_OBJECT* SheetLabel )
+{
+ if( SheetLabel->GetNet() == 0 )
+ return;
+
+ for( unsigned ii = 0; ii < size(); ii++ )
+ {
+ NETLIST_OBJECT* ObjetNet = GetItem( ii );
+
+ if( ObjetNet->m_SheetPath != SheetLabel->m_SheetPathInclude )
+ continue; //use SheetInclude, not the sheet!!
+
+ if( (ObjetNet->m_Type != NET_HIERLABEL ) && (ObjetNet->m_Type != NET_HIERBUSLABELMEMBER ) )
+ continue;
+
+ if( ObjetNet->GetNet() == SheetLabel->GetNet() )
+ continue; //already connected.
+
+ if( ObjetNet->m_Label.CmpNoCase( SheetLabel->m_Label ) != 0 )
+ continue; //different names.
+
+ // Propagate Netcode having all the objects of the same Netcode.
+ if( ObjetNet->GetNet() )
+ propageNetCode( ObjetNet->GetNet(), SheetLabel->GetNet(), IS_WIRE );
+ else
+ ObjetNet->SetNet( SheetLabel->GetNet() );
+ }
+}
+
+
+void NETLIST_OBJECT_LIST::connectBusLabels()
+{
+ // Propagate the net code between all bus label member objects connected by they name.
+ // If the net code is not yet existing, a new one is created
+ // Search is done in the entire list
+ for( unsigned ii = 0; ii < size(); ii++ )
+ {
+ NETLIST_OBJECT* Label = GetItem( ii );
+
+ if( Label->IsLabelBusMemberType() )
+ {
+ if( Label->GetNet() == 0 )
+ {
+ // Not yet existiing net code: create a new one.
+ Label->SetNet( m_lastNetCode );
+ m_lastNetCode++;
+ }
+
+ for( unsigned jj = ii + 1; jj < size(); jj++ )
+ {
+ NETLIST_OBJECT* LabelInTst = GetItem( jj );
+
+ if( LabelInTst->IsLabelBusMemberType() )
+ {
+ if( LabelInTst->m_BusNetCode != Label->m_BusNetCode )
+ continue;
+
+ if( LabelInTst->m_Member != Label->m_Member )
+ continue;
+
+ if( LabelInTst->GetNet() == 0 )
+ // Append this object to the current net
+ LabelInTst->SetNet( Label->GetNet() );
+ else
+ // Merge the 2 net codes, they are connected.
+ propageNetCode( LabelInTst->GetNet(), Label->GetNet(), IS_WIRE );
+ }
+ }
+ }
+ }
+}
+
+
+void NETLIST_OBJECT_LIST::propageNetCode( int aOldNetCode, int aNewNetCode, bool aIsBus )
+{
+ if( aOldNetCode == aNewNetCode )
+ return;
+
+ if( aIsBus == false ) // Propagate NetCode
+ {
+ for( unsigned jj = 0; jj < size(); jj++ )
+ {
+ NETLIST_OBJECT* object = GetItem( jj );
+
+ if( object->GetNet() == aOldNetCode )
+ object->SetNet( aNewNetCode );
+ }
+ }
+ else // Propagate BusNetCode
+ {
+ for( unsigned jj = 0; jj < size(); jj++ )
+ {
+ NETLIST_OBJECT* object = GetItem( jj );
+
+ if( object->m_BusNetCode == aOldNetCode )
+ object->m_BusNetCode = aNewNetCode;
+ }
+ }
+}
+
+
+void NETLIST_OBJECT_LIST::pointToPointConnect( NETLIST_OBJECT* aRef, bool aIsBus,
+ int start )
+{
+ int netCode;
+
+ if( aIsBus == false ) // Objects other than BUS and BUSLABELS
+ {
+ netCode = aRef->GetNet();
+
+ for( unsigned i = start; i < size(); i++ )
+ {
+ NETLIST_OBJECT* item = GetItem( i );
+
+ if( item->m_SheetPath != aRef->m_SheetPath ) //used to be > (why?)
+ continue;
+
+ switch( item->m_Type )
+ {
+ case NET_SEGMENT:
+ case NET_PIN:
+ case NET_LABEL:
+ case NET_HIERLABEL:
+ case NET_GLOBLABEL:
+ case NET_SHEETLABEL:
+ case NET_PINLABEL:
+ case NET_JUNCTION:
+ case NET_NOCONNECT:
+ if( aRef->m_Start == item->m_Start
+ || aRef->m_Start == item->m_End
+ || aRef->m_End == item->m_Start
+ || aRef->m_End == item->m_End )
+ {
+ if( item->GetNet() == 0 )
+ item->SetNet( netCode );
+ else
+ propageNetCode( item->GetNet(), netCode, IS_WIRE );
+ }
+ break;
+
+ case NET_BUS:
+ case NET_BUSLABELMEMBER:
+ case NET_SHEETBUSLABELMEMBER:
+ case NET_HIERBUSLABELMEMBER:
+ case NET_GLOBBUSLABELMEMBER:
+ case NET_ITEM_UNSPECIFIED:
+ break;
+ }
+ }
+ }
+ else // Object type BUS, BUSLABELS, and junctions.
+ {
+ netCode = aRef->m_BusNetCode;
+
+ for( unsigned i = start; i < size(); i++ )
+ {
+ NETLIST_OBJECT* item = GetItem( i );
+
+ if( item->m_SheetPath != aRef->m_SheetPath )
+ continue;
+
+ switch( item->m_Type )
+ {
+ case NET_ITEM_UNSPECIFIED:
+ case NET_SEGMENT:
+ case NET_PIN:
+ case NET_LABEL:
+ case NET_HIERLABEL:
+ case NET_GLOBLABEL:
+ case NET_SHEETLABEL:
+ case NET_PINLABEL:
+ case NET_NOCONNECT:
+ break;
+
+ case NET_BUS:
+ case NET_BUSLABELMEMBER:
+ case NET_SHEETBUSLABELMEMBER:
+ case NET_HIERBUSLABELMEMBER:
+ case NET_GLOBBUSLABELMEMBER:
+ case NET_JUNCTION:
+ if( aRef->m_Start == item->m_Start
+ || aRef->m_Start == item->m_End
+ || aRef->m_End == item->m_Start
+ || aRef->m_End == item->m_End )
+ {
+ if( item->m_BusNetCode == 0 )
+ item->m_BusNetCode = netCode;
+ else
+ propageNetCode( item->m_BusNetCode, netCode, IS_BUS );
+ }
+ break;
+ }
+ }
+ }
+}
+
+
+void NETLIST_OBJECT_LIST::segmentToPointConnect( NETLIST_OBJECT* aJonction,
+ bool aIsBus, int aIdxStart )
+{
+ for( unsigned i = aIdxStart; i < size(); i++ )
+ {
+ NETLIST_OBJECT* segment = GetItem( i );
+
+ // if different sheets, obviously no physical connection between elements.
+ if( segment->m_SheetPath != aJonction->m_SheetPath )
+ continue;
+
+ if( aIsBus == IS_WIRE )
+ {
+ if( segment->m_Type != NET_SEGMENT )
+ continue;
+ }
+ else
+ {
+ if( segment->m_Type != NET_BUS )
+ continue;
+ }
+
+ if( IsPointOnSegment( segment->m_Start, segment->m_End, aJonction->m_Start ) )
+ {
+ // Propagation Netcode has all the objects of the same Netcode.
+ if( aIsBus == IS_WIRE )
+ {
+ if( segment->GetNet() )
+ propageNetCode( segment->GetNet(), aJonction->GetNet(), aIsBus );
+ else
+ segment->SetNet( aJonction->GetNet() );
+ }
+ else
+ {
+ if( segment->m_BusNetCode )
+ propageNetCode( segment->m_BusNetCode, aJonction->m_BusNetCode, aIsBus );
+ else
+ segment->m_BusNetCode = aJonction->m_BusNetCode;
+ }
+ }
+ }
+}
+
+
+void NETLIST_OBJECT_LIST::labelConnect( NETLIST_OBJECT* aLabelRef )
+{
+ if( aLabelRef->GetNet() == 0 )
+ return;
+
+ for( unsigned i = 0; i < size(); i++ )
+ {
+ NETLIST_OBJECT* item = GetItem( i );
+
+ if( item->GetNet() == aLabelRef->GetNet() )
+ continue;
+
+ if( item->m_SheetPath != aLabelRef->m_SheetPath )
+ {
+ if( item->m_Type != NET_PINLABEL && item->m_Type != NET_GLOBLABEL
+ && item->m_Type != NET_GLOBBUSLABELMEMBER )
+ continue;
+
+ if( (item->m_Type == NET_GLOBLABEL
+ || item->m_Type == NET_GLOBBUSLABELMEMBER)
+ && item->m_Type != aLabelRef->m_Type )
+ //global labels only connect other global labels.
+ continue;
+ }
+
+ // NET_HIERLABEL are used to connect sheets.
+ // NET_LABEL are local to a sheet
+ // NET_GLOBLABEL are global.
+ // NET_PINLABEL is a kind of global label (generated by a power pin invisible)
+ if( item->IsLabelType() )
+ {
+ if( item->m_Label.CmpNoCase( aLabelRef->m_Label ) != 0 )
+ continue;
+
+ if( item->GetNet() )
+ propageNetCode( item->GetNet(), aLabelRef->GetNet(), IS_WIRE );
+ else
+ item->SetNet( aLabelRef->GetNet() );
+ }
+ }
+}
+
+
+void NETLIST_OBJECT_LIST::setUnconnectedFlag()
+{
+ NETLIST_OBJECT* NetItemRef;
+ unsigned NetStart, NetEnd;
+ NET_CONNECTION_T StateFlag;
+
+ NetStart = NetEnd = 0;
+ StateFlag = UNCONNECTED;
+ for( unsigned ii = 0; ii < size(); ii++ )
+ {
+ NetItemRef = GetItem( ii );
+ if( NetItemRef->m_Type == NET_NOCONNECT && StateFlag != PAD_CONNECT )
+ StateFlag = NOCONNECT_SYMBOL_PRESENT;
+
+ // Analysis of current net.
+ unsigned idxtoTest = ii + 1;
+
+ if( ( idxtoTest >= size() )
+ || ( NetItemRef->GetNet() != GetItem( idxtoTest )->GetNet() ) )
+ {
+ // Net analysis to update m_ConnectionType
+ NetEnd = idxtoTest;
+
+ /* set m_ConnectionType member to StateFlag for all items of
+ * this net: */
+ for( unsigned kk = NetStart; kk < NetEnd; kk++ )
+ GetItem( kk )->m_ConnectionType = StateFlag;
+
+ if( idxtoTest >= size() )
+ return;
+
+ // Start Analysis next Net
+ StateFlag = UNCONNECTED;
+ NetStart = idxtoTest;
+ continue;
+ }
+
+ /* test the current item: if this is a pin and if the reference item
+ * is also a pin, then 2 pins are connected, so set StateFlag to
+ * PAD_CONNECT (can be already done) Of course, if the current
+ * item is a no connect symbol, set StateFlag to
+ * NOCONNECT_SYMBOL_PRESENT to inhibit error diags. However if
+ * StateFlag is already set to PAD_CONNECT this state is kept (the
+ * no connect symbol was surely an error and an ERC will report this)
+ */
+ for( ; ; idxtoTest++ )
+ {
+ if( ( idxtoTest >= size() )
+ || ( NetItemRef->GetNet() != GetItem( idxtoTest )->GetNet() ) )
+ break;
+
+ switch( GetItem( idxtoTest )->m_Type )
+ {
+ case NET_ITEM_UNSPECIFIED:
+ wxMessageBox( wxT( "BuildNetListBase() error" ) );
+ break;
+
+ case NET_SEGMENT:
+ case NET_LABEL:
+ case NET_HIERLABEL:
+ case NET_GLOBLABEL:
+ case NET_SHEETLABEL:
+ case NET_PINLABEL:
+ case NET_BUS:
+ case NET_BUSLABELMEMBER:
+ case NET_SHEETBUSLABELMEMBER:
+ case NET_HIERBUSLABELMEMBER:
+ case NET_GLOBBUSLABELMEMBER:
+ case NET_JUNCTION:
+ break;
+
+ case NET_PIN:
+ if( NetItemRef->m_Type == NET_PIN )
+ StateFlag = PAD_CONNECT;
+
+ break;
+
+ case NET_NOCONNECT:
+ if( StateFlag != PAD_CONNECT )
+ StateFlag = NOCONNECT_SYMBOL_PRESENT;
+
+ break;
+ }
+ }
+ }
+}
diff --git a/eeschema/netlist.h b/eeschema/netlist.h
new file mode 100644
index 0000000..2d20554
--- /dev/null
+++ b/eeschema/netlist.h
@@ -0,0 +1,62 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2011 jean-pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
+ * Copyright (C) 1992-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see changelog.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/**
+ * @file netlist.h
+ */
+
+#ifndef _NETLIST_H_
+#define _NETLIST_H_
+
+/// netlist types
+enum NETLIST_TYPE_ID {
+ NET_TYPE_UNINIT = 0,
+ NET_TYPE_PCBNEW,
+ NET_TYPE_ORCADPCB2,
+ NET_TYPE_CADSTAR,
+ NET_TYPE_SPICE,
+ NET_TYPE_CUSTOM1, /* NET_TYPE_CUSTOM1
+ * is the first id for user netlist format
+ * NET_TYPE_CUSTOM1+CUSTOMPANEL_COUNTMAX-1
+ * is the last id for user netlist format
+ */
+ //NET_TYPE_CUSTOM_MAX = NET_TYPE_CUSTOM1 + CUSTOMPANEL_COUNTMAX - 1
+};
+
+
+/// Options for Spice netlist generation (OR'ed bits
+enum netlistOptions {
+ NET_USE_X_PREFIX = 2, // for Spice netlist : change "U" and "IC" reference prefix to "X"
+ NET_USE_NETCODES_AS_NETNAMES = 4 // for Spice netlist : use netcode numbers as netnames
+};
+
+
+#define NETLIST_HEAD_STRING "EESchema Netlist Version 1.1"
+
+// Max pin number per component and footprint
+#define MAXPIN 5000
+
+#endif
diff --git a/eeschema/netlist_exporters/netlist_exporter.cpp b/eeschema/netlist_exporters/netlist_exporter.cpp
new file mode 100644
index 0000000..62e39cc
--- /dev/null
+++ b/eeschema/netlist_exporters/netlist_exporter.cpp
@@ -0,0 +1,364 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/**
+ * @file netlist_exporter.cpp
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <pgm_base.h>
+
+#include <sch_reference_list.h>
+#include <class_netlist_object.h>
+#include <class_library.h>
+#include <lib_pin.h>
+#include <sch_component.h>
+#include <sch_text.h>
+#include <sch_sheet.h>
+
+#include <netlist.h>
+#include <netlist_exporter.h>
+
+
+
+wxString NETLIST_EXPORTER::MakeCommandLine( const wxString& aFormatString,
+ const wxString& aTempfile, const wxString& aFinalFile, const wxString& aProjectPath )
+{
+ // Expand format symbols in the command line:
+ // %B => base filename of selected output file, minus path and extension.
+ // %P => project directory name, without trailing '/' or '\'.
+ // %I => full filename of the input file (the intermediate net file).
+ // %O => complete filename and path (but without extension) of the user chosen output file.
+
+ wxString ret = aFormatString;
+ wxFileName in = aTempfile;
+ wxFileName out = aFinalFile;
+
+ ret.Replace( wxT( "%P" ), aProjectPath.GetData(), true );
+ ret.Replace( wxT( "%B" ), out.GetName().GetData(), true );
+ ret.Replace( wxT( "%I" ), in.GetFullPath().GetData(), true );
+ ret.Replace( wxT( "%O" ), out.GetFullPath().GetData(), true );
+
+ // Use Unix like notation, which always works
+ ret.Replace( wxT( "\\" ), "/", true );
+
+ return ret;
+}
+
+
+void NETLIST_EXPORTER::sprintPinNetName( wxString& aResult,
+ const wxString& aNetNameFormat, NETLIST_OBJECT* aPin,
+ bool aUseNetcodeAsNetName )
+{
+ int netcode = aPin->GetNet();
+
+ // Not wxString::Clear(), which would free memory. We want the worst
+ // case wxString memory to grow to avoid reallocation from within the
+ // caller's loop.
+ aResult.Empty();
+
+ if( netcode != 0 && aPin->GetConnectionType() == PAD_CONNECT )
+ {
+ if( aUseNetcodeAsNetName )
+ {
+ aResult.Printf( wxT("%d"), netcode );
+ }
+ else
+ {
+ aResult = aPin->GetNetName();
+
+ if( aResult.IsEmpty() ) // No net name: give a name from net code
+ aResult.Printf( aNetNameFormat.GetData(), netcode );
+ }
+ }
+}
+
+
+SCH_COMPONENT* NETLIST_EXPORTER::findNextComponent( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath )
+{
+ wxString ref;
+
+ // continue searching from the middle of a linked list (the draw list)
+ for( ; aItem; aItem = aItem->Next() )
+ {
+ if( aItem->Type() != SCH_COMPONENT_T )
+ continue;
+
+ // found next component
+ SCH_COMPONENT* comp = (SCH_COMPONENT*) aItem;
+
+ // Power symbols and other components which have the reference starting
+ // with "#" are not included in netlist (pseudo or virtual components)
+ ref = comp->GetRef( aSheetPath );
+ if( ref[0] == wxChar( '#' ) )
+ continue;
+
+ // if( Component->m_FlagControlMulti == 1 )
+ // continue; /* yes */
+ // removed because with multiple instances of one schematic
+ // (several sheets pointing to 1 screen), this will be erroneously be
+ // toggled.
+
+ LIB_PART* part = m_libs->FindLibPart( comp->GetPartName() );
+ if( !part )
+ continue;
+
+ // If component is a "multi parts per package" type
+ if( part->GetUnitCount() > 1 )
+ {
+ // test if this reference has already been processed, and if so skip
+ if( m_ReferencesAlreadyFound.Lookup( ref ) )
+ continue;
+ }
+
+ // record the usage of this library component entry.
+ m_LibParts.insert( part ); // rejects non-unique pointers
+
+ return comp;
+ }
+
+ return NULL;
+}
+
+
+/// Comparison routine for sorting by pin numbers.
+static bool sortPinsByNum( NETLIST_OBJECT* aPin1, NETLIST_OBJECT* aPin2 )
+{
+ // return "lhs < rhs"
+ return RefDesStringCompare( aPin1->GetPinNumText(), aPin2->GetPinNumText() ) < 0;
+}
+
+
+SCH_COMPONENT* NETLIST_EXPORTER::findNextComponentAndCreatePinList( EDA_ITEM* aItem,
+ SCH_SHEET_PATH* aSheetPath )
+{
+ wxString ref;
+
+ m_SortedComponentPinList.clear();
+
+ // continue searching from the middle of a linked list (the draw list)
+ for( ; aItem; aItem = aItem->Next() )
+ {
+ if( aItem->Type() != SCH_COMPONENT_T )
+ continue;
+
+ // found next component
+ SCH_COMPONENT* comp = (SCH_COMPONENT*) aItem;
+
+ // Power symbols and other components which have the reference starting
+ // with "#" are not included in netlist (pseudo or virtual components)
+ ref = comp->GetRef( aSheetPath );
+
+ if( ref[0] == wxChar( '#' ) )
+ continue;
+
+ // if( Component->m_FlagControlMulti == 1 )
+ // continue; /* yes */
+ // removed because with multiple instances of one schematic
+ // (several sheets pointing to 1 screen), this will be erroneously be
+ // toggled.
+
+ LIB_PART* part = m_libs->FindLibPart( comp->GetPartName() );
+
+ if( !part )
+ continue;
+
+ // If component is a "multi parts per package" type
+ if( part->GetUnitCount() > 1 )
+ {
+ // test if this reference has already been processed, and if so skip
+ if( m_ReferencesAlreadyFound.Lookup( ref ) )
+ continue;
+
+ // Collect all pins for this reference designator by searching
+ // the entire design for other parts with the same reference designator.
+ // This is only done once, it would be too expensive otherwise.
+ findAllInstancesOfComponent( comp, part, aSheetPath );
+ }
+
+ else // entry->GetUnitCount() <= 1 means one part per package
+ {
+ LIB_PINS pins; // constructed once here
+
+ part->GetPins( pins, comp->GetUnitSelection( aSheetPath ), comp->GetConvert() );
+
+ for( size_t i = 0; i < pins.size(); i++ )
+ {
+ LIB_PIN* pin = pins[i];
+
+ wxASSERT( pin->Type() == LIB_PIN_T );
+
+ addPinToComponentPinList( comp, aSheetPath, pin );
+ }
+ }
+
+ // Sort pins in m_SortedComponentPinList by pin number
+ sort( m_SortedComponentPinList.begin(),
+ m_SortedComponentPinList.end(), sortPinsByNum );
+
+ // Remove duplicate Pins in m_SortedComponentPinList
+ eraseDuplicatePins( );
+
+ // record the usage of this library component entry.
+ m_LibParts.insert( part ); // rejects non-unique pointers
+
+ return comp;
+ }
+
+ return NULL;
+}
+
+bool NETLIST_EXPORTER::addPinToComponentPinList( SCH_COMPONENT* aComponent,
+ SCH_SHEET_PATH* aSheetPath, LIB_PIN* aPin )
+{
+ // Search the PIN description for Pin in g_NetObjectslist
+ for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
+ {
+ NETLIST_OBJECT* pin = m_masterList->GetItem( ii );
+
+ if( pin->m_Type != NET_PIN )
+ continue;
+
+ if( pin->m_Link != aComponent )
+ continue;
+
+ if( pin->m_PinNum != aPin->GetNumber() )
+ continue;
+
+ // most expensive test at the end.
+ if( pin->m_SheetPath != *aSheetPath )
+ continue;
+
+ m_SortedComponentPinList.push_back( pin );
+
+ if( m_SortedComponentPinList.size() >= MAXPIN )
+ {
+ // Log message for Internal error
+ DisplayError( NULL, wxT( "addPinToComponentPinList err: MAXPIN reached" ) );
+ }
+
+ return true; // we're done, we appended.
+ }
+
+ return false;
+}
+
+
+void NETLIST_EXPORTER::eraseDuplicatePins()
+{
+ for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
+ {
+ if( m_SortedComponentPinList[ii] == NULL ) /* already deleted */
+ continue;
+
+ /* Search for duplicated pins
+ * If found, remove duplicates. The priority is to keep connected pins
+ * and remove unconnected
+ * - So this allows (for instance when using multi op amps per package
+ * - to connect only one op amp to power
+ * Because the pin list is sorted by m_PinNum value, duplicated pins
+ * are necessary successive in list
+ */
+ int idxref = ii;
+ for( unsigned jj = ii + 1; jj < m_SortedComponentPinList.size(); jj++ )
+ {
+ if( m_SortedComponentPinList[jj] == NULL ) // Already removed
+ continue;
+
+ // if other pin num, stop search,
+ // because all pins having the same number are consecutive in list.
+ if( m_SortedComponentPinList[idxref]->m_PinNum != m_SortedComponentPinList[jj]->m_PinNum )
+ break;
+
+ if( m_SortedComponentPinList[idxref]->GetConnectionType() == PAD_CONNECT )
+ {
+ m_SortedComponentPinList[jj]->m_Flag = 1;
+ m_SortedComponentPinList[jj] = NULL;
+ }
+ else /* the reference pin is not connected: remove this pin if the
+ * other pin is connected */
+ {
+ if( m_SortedComponentPinList[jj]->GetConnectionType() == PAD_CONNECT )
+ {
+ m_SortedComponentPinList[idxref]->m_Flag = 1;
+ m_SortedComponentPinList[idxref] = NULL;
+ idxref = jj;
+ }
+ else // the 2 pins are not connected: remove the tested pin,
+ { // and continue ...
+ m_SortedComponentPinList[jj]->m_Flag = 1;
+ m_SortedComponentPinList[jj] = NULL;
+ }
+ }
+ }
+ }
+}
+
+
+void NETLIST_EXPORTER::findAllInstancesOfComponent( SCH_COMPONENT* aComponent,
+ LIB_PART* aEntry,
+ SCH_SHEET_PATH* aSheetPath )
+{
+ wxString ref = aComponent->GetRef( aSheetPath );
+ wxString ref2;
+
+ SCH_SHEET_LIST sheetList;
+
+ for( SCH_SHEET_PATH* sheet = sheetList.GetFirst(); sheet; sheet = sheetList.GetNext() )
+ {
+ for( EDA_ITEM* item = sheet->LastDrawList(); item; item = item->Next() )
+ {
+ if( item->Type() != SCH_COMPONENT_T )
+ continue;
+
+ SCH_COMPONENT* comp2 = (SCH_COMPONENT*) item;
+
+ ref2 = comp2->GetRef( sheet );
+ if( ref2.CmpNoCase( ref ) != 0 )
+ continue;
+
+ int unit2 = comp2->GetUnitSelection( sheet ); // slow
+
+ for( LIB_PIN* pin = aEntry->GetNextPin(); pin; pin = aEntry->GetNextPin( pin ) )
+ {
+ wxASSERT( pin->Type() == LIB_PIN_T );
+
+ if( pin->GetUnit() && pin->GetUnit() != unit2 )
+ continue;
+
+ if( pin->GetConvert() && pin->GetConvert() != comp2->GetConvert() )
+ continue;
+
+ // A suitable pin is found: add it to the current list
+ addPinToComponentPinList( comp2, sheet, pin );
+ }
+ }
+ }
+}
+
diff --git a/eeschema/netlist_exporters/netlist_exporter.h b/eeschema/netlist_exporters/netlist_exporter.h
new file mode 100644
index 0000000..dc3ebb0
--- /dev/null
+++ b/eeschema/netlist_exporters/netlist_exporter.h
@@ -0,0 +1,235 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef NETLIST_EXPORTER_H
+#define NETLIST_EXPORTER_H
+
+#include <kicad_string.h>
+
+#include <class_libentry.h>
+#include <class_netlist_object.h>
+#include <lib_pin.h>
+#include <sch_component.h>
+#include <sch_text.h>
+#include <sch_sheet.h>
+
+/**
+ * Class UNIQUE_STRINGS
+ * tracks unique wxStrings and is useful in telling if a string
+ * has been seen before.
+ */
+class UNIQUE_STRINGS
+{
+ std::set<wxString> m_set; ///< set of wxStrings already found
+
+ typedef std::set<wxString>::iterator us_iterator;
+
+public:
+ /**
+ * Function Clear
+ * erases the record.
+ */
+ void Clear() { m_set.clear(); }
+
+ /**
+ * Function Lookup
+ * returns true if \a aString already exists in the set, otherwise returns
+ * false and adds \a aString to the set for next time.
+ */
+ bool Lookup( const wxString& aString )
+ {
+ std::pair<us_iterator, bool> pair = m_set.insert( aString );
+
+ return !pair.second;
+ }
+};
+
+/**
+ * Struct LIB_PART_LESS_THAN
+ * is used by std:set<LIB_PART*> instantiation which uses LIB_PART name as its key.
+ */
+struct LIB_PART_LESS_THAN
+{
+ // a "less than" test on two LIB_PARTs (.m_name wxStrings)
+ bool operator()( LIB_PART* const& libpart1, LIB_PART* const& libpart2 ) const
+ {
+ // Use case specific GetName() wxString compare
+ return libpart1->GetName().Cmp( libpart2->GetName() ) < 0;
+ }
+};
+
+/**
+ * Class NETLIST_EXPORTER
+ * is a abstract class used for the netlist exporters that eeschema supports.
+ */
+class NETLIST_EXPORTER
+{
+protected:
+ NETLIST_OBJECT_LIST* m_masterList; /// yes ownership, connected items flat list
+
+ PART_LIBS* m_libs; /// no ownership
+
+ /// Used to temporary store and filter the list of pins of a schematic component
+ /// when generating schematic component data in netlist (comp section). No ownership
+ /// of members.
+ NETLIST_OBJECTS m_SortedComponentPinList;
+
+ /// Used for "multi parts per package" components,
+ /// avoids processing a lib component more than once.
+ UNIQUE_STRINGS m_ReferencesAlreadyFound;
+
+ /// unique library parts used. LIB_PART items are sorted by names
+ std::set<LIB_PART*, LIB_PART_LESS_THAN> m_LibParts;
+
+ // share a code generated std::set<void*> to reduce code volume
+ std::set<void*> m_Libraries; ///< unique libraries used
+
+ /**
+ * Function sprintPinNetName
+ * formats the net name for \a aPin using \a aNetNameFormat into \a aResult.
+ * <p>
+ * Net name is:
+ * <ul>
+ * <li> "?" if pin not connected
+ * <li> "netname" for global net (like gnd, vcc ..
+ * <li> "/path/netname" for the usual nets
+ * </ul>
+ * if aUseNetcodeAsNetName is true, the net name is just the net code (SPICE only)
+ */
+ static void sprintPinNetName( wxString& aResult, const wxString& aNetNameFormat,
+ NETLIST_OBJECT* aPin, bool aUseNetcodeAsNetName = false );
+
+ /**
+ * Function findNextComponentAndCreatePinList
+ * finds a component from the DrawList and builds
+ * its pin list in m_SortedComponentPinList. This list is sorted by pin num.
+ * the component is the next actual component after aItem
+ * (power symbols and virtual components that have their reference starting by '#'are skipped).
+ */
+ SCH_COMPONENT* findNextComponentAndCreatePinList( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath );
+
+ SCH_COMPONENT* findNextComponent( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath );
+
+
+ /**
+ * Function eraseDuplicatePins
+ * erase duplicate Pins from m_SortedComponentPinList (i.e. set pointer in this list to NULL).
+ * (This is a list of pins found in the whole schematic, for a single
+ * component.) These duplicate pins were put in list because some pins (powers... )
+ * are found more than one time when we have a multiple parts per package
+ * component. For instance, a 74ls00 has 4 parts, and therefore the VCC pin
+ * and GND pin appears 4 times in the list.
+ * Note: this list *MUST* be sorted by pin number (.m_PinNum member value)
+ * Also set the m_Flag member of "removed" NETLIST_OBJECT pin item to 1
+ */
+ void eraseDuplicatePins();
+
+ /**
+ * Function addPinToComponentPinList
+ * adds a new pin description to the pin list m_SortedComponentPinList.
+ * A pin description is a pointer to the corresponding structure
+ * created by BuildNetList() in the table g_NetObjectslist.
+ */
+ bool addPinToComponentPinList( SCH_COMPONENT* Component,
+ SCH_SHEET_PATH* sheet,
+ LIB_PIN* PinEntry );
+
+ /**
+ * Function findAllInstancesOfComponent
+ * is used for "multiple parts per package" components.
+ * <p>
+ * Search the entire design for all instances of \a aComponent based on
+ * matching reference designator, and for each part, add all its pins
+ * to the temporary sorted pin list.
+ */
+ void findAllInstancesOfComponent( SCH_COMPONENT* aComponent,
+ LIB_PART* aEntry,
+ SCH_SHEET_PATH* aSheetPath );
+
+public:
+
+ /**
+ * Constructor
+ * @param aMasterList we take ownership of this here.
+ */
+ NETLIST_EXPORTER( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs ) :
+ m_masterList( aMasterList ),
+ m_libs( aLibs )
+ {
+ }
+
+ virtual ~NETLIST_EXPORTER()
+ {
+ delete m_masterList; // I own the list itself in this instance.
+ }
+
+ /**
+ * Function WriteNetlist
+ * writes to specified output file
+ */
+ virtual bool WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
+ {
+ return false;
+ }
+
+ /**
+ * Function MakeCommandLine
+ * builds up a string that describes a command line for
+ * executing a child process. The input and output file names
+ * along with any options to the executable are all possibly
+ * in the returned string.
+ *
+ * @param aFormatString holds:
+ * <ul>
+ * <li>the name of the external program
+ * <li>any options needed by that program
+ * <li>formatting sequences, see below.
+ * </ul>
+ *
+ * @param aTempfile is the name of an input file to the
+ * external program.
+ * @param aFinalFile is the name of an output file that
+ * the user expects.
+ * @param aProjectDirectory is used for %P replacement, it should omit
+ * the trailing '/'.
+ *
+ * <p> Supported formatting sequences and their meaning:
+ * <ul>
+ * <li> %B => base filename of selected output file, minus
+ * path and extension.
+ * <li> %I => complete filename and path of the temporary
+ * input file.
+ * <li> %O => complete filename and path of the user chosen
+ * output file.
+ * <li> %P => project directory, without name and without trailing '/'
+ * </ul>
+ */
+ static wxString MakeCommandLine( const wxString& aFormatString,
+ const wxString& aTempfile, const wxString& aFinalFile,
+ const wxString& aProjectDirectory
+ );
+};
+
+#endif
diff --git a/eeschema/netlist_exporters/netlist_exporter_cadstar.cpp b/eeschema/netlist_exporters/netlist_exporter_cadstar.cpp
new file mode 100644
index 0000000..2b5b7fb
--- /dev/null
+++ b/eeschema/netlist_exporters/netlist_exporter_cadstar.cpp
@@ -0,0 +1,204 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <build_version.h>
+#include <confirm.h>
+
+#include <schframe.h>
+#include <sch_reference_list.h>
+#include <class_netlist_object.h>
+
+#include "netlist_exporter_cadstar.h"
+
+/* Generate CADSTAR net list. */
+static wxString StartLine( wxT( "." ) );
+
+bool NETLIST_EXPORTER_CADSTAR::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
+{
+ (void)aNetlistOptions; //unused
+ int ret = 0;
+ FILE* f = NULL;
+
+ if( ( f = wxFopen( aOutFileName, wxT( "wt" ) ) ) == NULL )
+ {
+ wxString msg;
+ msg.Printf( _( "Failed to create file '%s'" ),
+ GetChars( aOutFileName ) );
+ DisplayError( NULL, msg );
+ return false;
+ }
+
+ wxString StartCmpDesc = StartLine + wxT( "ADD_COM" );
+ wxString msg;
+ SCH_SHEET_PATH* sheet;
+ EDA_ITEM* DrawList;
+ SCH_COMPONENT* component;
+ wxString title = wxT( "Eeschema " ) + GetBuildVersion();
+
+ ret |= fprintf( f, "%sHEA\n", TO_UTF8( StartLine ) );
+ ret |= fprintf( f, "%sTIM %s\n", TO_UTF8( StartLine ), TO_UTF8( DateAndTime() ) );
+ ret |= fprintf( f, "%sAPP ", TO_UTF8( StartLine ) );
+ ret |= fprintf( f, "\"%s\"\n", TO_UTF8( title ) );
+ ret |= fprintf( f, "\n" );
+
+ // Prepare list of nets generation
+ for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
+ m_masterList->GetItem( ii )->m_Flag = 0;
+
+ // Create netlist module section
+ m_ReferencesAlreadyFound.Clear();
+
+ SCH_SHEET_LIST SheetList;
+
+ for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
+ {
+ for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() )
+ {
+ DrawList = component = findNextComponentAndCreatePinList( DrawList, sheet );
+
+ if( component == NULL )
+ break;
+
+ /*
+ doing nothing with footprint
+ if( !component->GetField( FOOTPRINT )->IsVoid() )
+ {
+ footprint = component->GetField( FOOTPRINT )->m_Text;
+ footprint.Replace( wxT( " " ), wxT( "_" ) );
+ }
+ else
+ footprint = wxT( "$noname" );
+ */
+
+ msg = component->GetRef( sheet );
+ ret |= fprintf( f, "%s ", TO_UTF8( StartCmpDesc ) );
+ ret |= fprintf( f, "%s", TO_UTF8( msg ) );
+
+ msg = component->GetField( VALUE )->GetText();
+ msg.Replace( wxT( " " ), wxT( "_" ) );
+ ret |= fprintf( f, " \"%s\"", TO_UTF8( msg ) );
+ ret |= fprintf( f, "\n" );
+ }
+ }
+
+ ret |= fprintf( f, "\n" );
+
+ m_SortedComponentPinList.clear();
+
+ if( ! writeListOfNets( f ) )
+ ret = -1; // set error
+
+ ret |= fprintf( f, "\n%sEND\n", TO_UTF8( StartLine ) );
+
+ fclose( f );
+
+ return ret >= 0;
+}
+
+
+bool NETLIST_EXPORTER_CADSTAR::writeListOfNets( FILE* f )
+{
+ int ret = 0;
+ wxString InitNetDesc = StartLine + wxT( "ADD_TER" );
+ wxString StartNetDesc = StartLine + wxT( "TER" );
+ wxString netcodeName, InitNetDescLine;
+ unsigned ii;
+ int print_ter = 0;
+ int NetCode, lastNetCode = -1;
+ SCH_COMPONENT* Cmp;
+ wxString netName;
+
+ for( ii = 0; ii < m_masterList->size(); ii++ )
+ {
+ NETLIST_OBJECT* nitem = m_masterList->GetItem( ii );
+
+ // Get the NetName of the current net :
+ if( ( NetCode = nitem->GetNet() ) != lastNetCode )
+ {
+ netName = nitem->GetNetName();
+ netcodeName = wxT( "\"" );
+
+ if( !netName.IsEmpty() )
+ netcodeName << netName;
+ else // this net has no name: create a default name $<net number>
+ netcodeName << wxT( "$" ) << NetCode;
+
+ netcodeName += wxT( "\"" );
+ lastNetCode = NetCode;
+ print_ter = 0;
+ }
+
+
+ if( nitem->m_Type != NET_PIN )
+ continue;
+
+ if( nitem->m_Flag != 0 )
+ continue;
+
+ Cmp = nitem->GetComponentParent();
+ wxString refstr = Cmp->GetRef( &nitem->m_SheetPath );
+ if( refstr[0] == '#' )
+ continue; // Power supply symbols.
+
+ switch( print_ter )
+ {
+ case 0:
+ {
+ char buf[5];
+ wxString str_pinnum;
+ strncpy( buf, (char*) &nitem->m_PinNum, 4 );
+ buf[4] = 0;
+ str_pinnum = FROM_UTF8( buf );
+ InitNetDescLine.Printf( wxT( "\n%s %s %.4s %s" ),
+ GetChars( InitNetDesc ),
+ GetChars( refstr ),
+ GetChars( str_pinnum ),
+ GetChars( netcodeName ) );
+ }
+ print_ter++;
+ break;
+
+ case 1:
+ ret |= fprintf( f, "%s\n", TO_UTF8( InitNetDescLine ) );
+ ret |= fprintf( f, "%s %s %.4s\n",
+ TO_UTF8( StartNetDesc ),
+ TO_UTF8( refstr ),
+ (char*) &nitem->m_PinNum );
+ print_ter++;
+ break;
+
+ default:
+ ret |= fprintf( f, " %s %.4s\n",
+ TO_UTF8( refstr ),
+ (char*) &nitem->m_PinNum );
+ break;
+ }
+
+ nitem->m_Flag = 1;
+ }
+
+ return ret >= 0;
+}
diff --git a/eeschema/netlist_exporters/netlist_exporter_cadstar.h b/eeschema/netlist_exporters/netlist_exporter_cadstar.h
new file mode 100644
index 0000000..909e1bd
--- /dev/null
+++ b/eeschema/netlist_exporters/netlist_exporter_cadstar.h
@@ -0,0 +1,62 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef NETLIST_EXPORTER_CADSTAR_H
+#define NETLIST_EXPORTER_CADSTAR_H
+
+#include "netlist_exporter.h"
+
+/**
+ * Class NETLIST_EXPORTER_CADSTAR
+ * generates a netlist compatible with CADSTAR
+ */
+class NETLIST_EXPORTER_CADSTAR : public NETLIST_EXPORTER
+{
+ /**
+ * Function writeListOfNetsCADSTAR
+ * writes a net list (ranked by Netcode), and pins connected to it.
+ * <p>
+ * Format:
+ * - ADD_TER RR2 6 \"$42\"
+ * - B U1 100
+ * - 6 CA
+ * </p>
+ */
+ bool writeListOfNets( FILE* f );
+
+public:
+ NETLIST_EXPORTER_CADSTAR( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs ) :
+ NETLIST_EXPORTER( aMasterList, aLibs )
+ {
+ }
+
+ /**
+ * Function WriteList
+ * writes to specified output file
+ */
+ bool WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions );
+};
+
+#endif
diff --git a/eeschema/netlist_exporters/netlist_exporter_generic.cpp b/eeschema/netlist_exporters/netlist_exporter_generic.cpp
new file mode 100644
index 0000000..921e0fc
--- /dev/null
+++ b/eeschema/netlist_exporters/netlist_exporter_generic.cpp
@@ -0,0 +1,580 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <build_version.h>
+#include <sch_base_frame.h>
+#include <class_library.h>
+
+#include <schframe.h>
+#include "netlist_exporter_generic.h"
+
+static bool sortPinsByNumber( LIB_PIN* aPin1, LIB_PIN* aPin2 );
+
+bool NETLIST_EXPORTER_GENERIC::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
+{
+ // Prepare list of nets generation
+ for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
+ m_masterList->GetItem( ii )->m_Flag = 0;
+
+ // output the XML format netlist.
+ wxXmlDocument xdoc;
+
+ xdoc.SetRoot( makeRoot( GNL_ALL ) );
+
+ return xdoc.Save( aOutFileName, 2 /* indent bug, today was ignored by wxXml lib */ );
+}
+
+
+XNODE* NETLIST_EXPORTER_GENERIC::makeRoot( int aCtl )
+{
+ XNODE* xroot = node( wxT( "export" ) );
+
+ xroot->AddAttribute( wxT( "version" ), wxT( "D" ) );
+
+ if( aCtl & GNL_HEADER )
+ // add the "design" header
+ xroot->AddChild( makeDesignHeader() );
+
+ if( aCtl & GNL_COMPONENTS )
+ xroot->AddChild( makeComponents() );
+
+ if( aCtl & GNL_PARTS )
+ xroot->AddChild( makeLibParts() );
+
+ if( aCtl & GNL_LIBRARIES )
+ // must follow makeGenericLibParts()
+ xroot->AddChild( makeLibraries() );
+
+ if( aCtl & GNL_NETS )
+ xroot->AddChild( makeListOfNets() );
+
+ return xroot;
+}
+
+
+XNODE* NETLIST_EXPORTER_GENERIC::makeComponents()
+{
+ XNODE* xcomps = node( wxT( "components" ) );
+
+ wxString timeStamp;
+
+ // some strings we need many times, but don't want to construct more
+ // than once for performance. These are used within loops so the
+ // enclosing wxString constructor would fire on each loop iteration if
+ // they were in a nested scope.
+
+ // these are actually constructor invocations, not assignments as it appears:
+ wxString sFields = wxT( "fields" );
+ wxString sField = wxT( "field" );
+ wxString sComponent = wxT( "comp" ); // use "part" ?
+ wxString sName = wxT( "name" );
+ wxString sRef = wxT( "ref" );
+ wxString sPins = wxT( "pins" );
+ wxString sPin = wxT( "pin" );
+ wxString sValue = wxT( "value" );
+ wxString sSheetPath = wxT( "sheetpath" );
+ wxString sFootprint = wxT( "footprint" );
+ wxString sDatasheet = wxT( "datasheet" );
+ wxString sTStamp = wxT( "tstamp" );
+ wxString sTStamps = wxT( "tstamps" );
+ wxString sTSFmt = wxT( "%8.8lX" ); // comp->m_TimeStamp
+ wxString sLibSource = wxT( "libsource" );
+ wxString sLibPart = wxT( "libpart" );
+ wxString sLib = wxT( "lib" );
+ wxString sPart = wxT( "part" );
+ wxString sNames = wxT( "names" );
+
+ m_ReferencesAlreadyFound.Clear();
+
+ SCH_SHEET_LIST sheetList;
+
+ // Output is xml, so there is no reason to remove spaces from the field values.
+ // And XML element names need not be translated to various languages.
+
+ for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path; path = sheetList.GetNext() )
+ {
+ for( EDA_ITEM* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() )
+ {
+ SCH_COMPONENT* comp = findNextComponentAndCreatePinList( schItem, path );
+ if( !comp )
+ break; // No component left
+
+ schItem = comp;
+
+ XNODE* xcomp; // current component being constructed
+
+ // Output the component's elements in order of expected access frequency.
+ // This may not always look best, but it will allow faster execution
+ // under XSL processing systems which do sequential searching within
+ // an element.
+
+ xcomps->AddChild( xcomp = node( sComponent ) );
+ xcomp->AddAttribute( sRef, comp->GetRef( path ) );
+
+ xcomp->AddChild( node( sValue, comp->GetField( VALUE )->GetText() ) );
+
+ if( !comp->GetField( FOOTPRINT )->IsVoid() )
+ xcomp->AddChild( node( sFootprint, comp->GetField( FOOTPRINT )->GetText() ) );
+
+ if( !comp->GetField( DATASHEET )->IsVoid() )
+ xcomp->AddChild( node( sDatasheet, comp->GetField( DATASHEET )->GetText() ) );
+
+ // Export all user defined fields within the component,
+ // which start at field index MANDATORY_FIELDS. Only output the <fields>
+ // container element if there are any <field>s.
+ if( comp->GetFieldCount() > MANDATORY_FIELDS )
+ {
+ XNODE* xfields;
+ xcomp->AddChild( xfields = node( sFields ) );
+
+ for( int fldNdx = MANDATORY_FIELDS; fldNdx < comp->GetFieldCount(); ++fldNdx )
+ {
+ SCH_FIELD* f = comp->GetField( fldNdx );
+
+ // only output a field if non empty and not just "~"
+ if( !f->IsVoid() )
+ {
+ XNODE* xfield;
+ xfields->AddChild( xfield = node( sField, f->GetText() ) );
+ xfield->AddAttribute( sName, f->GetName() );
+ }
+ }
+ }
+
+ XNODE* xlibsource;
+ xcomp->AddChild( xlibsource = node( sLibSource ) );
+
+ // "logical" library name, which is in anticipation of a better search
+ // algorithm for parts based on "logical_lib.part" and where logical_lib
+ // is merely the library name minus path and extension.
+ LIB_PART* part = m_libs->FindLibPart( comp->GetPartName() );
+ if( part )
+ xlibsource->AddAttribute( sLib, part->GetLib()->GetLogicalName() );
+
+ xlibsource->AddAttribute( sPart, comp->GetPartName() );
+
+ XNODE* xsheetpath;
+
+ xcomp->AddChild( xsheetpath = node( sSheetPath ) );
+ xsheetpath->AddAttribute( sNames, path->PathHumanReadable() );
+ xsheetpath->AddAttribute( sTStamps, path->Path() );
+
+ timeStamp.Printf( sTSFmt, (unsigned long)comp->GetTimeStamp() );
+ xcomp->AddChild( node( sTStamp, timeStamp ) );
+ }
+ }
+
+ return xcomps;
+}
+
+
+XNODE* NETLIST_EXPORTER_GENERIC::makeDesignHeader()
+{
+ SCH_SCREEN* screen;
+ XNODE* xdesign = node( wxT("design") );
+ XNODE* xtitleBlock;
+ XNODE* xsheet;
+ XNODE* xcomment;
+ wxString sheetTxt;
+ wxFileName sourceFileName;
+
+ // the root sheet is a special sheet, call it source
+ xdesign->AddChild( node( wxT( "source" ), g_RootSheet->GetScreen()->GetFileName() ) );
+
+ xdesign->AddChild( node( wxT( "date" ), DateAndTime() ) );
+
+ // which Eeschema tool
+ xdesign->AddChild( node( wxT( "tool" ), wxT( "Eeschema " ) + GetBuildVersion() ) );
+
+ /*
+ Export the sheets information
+ */
+ SCH_SHEET_LIST sheetList;
+
+ for( SCH_SHEET_PATH* sheet = sheetList.GetFirst(); sheet; sheet = sheetList.GetNext() )
+ {
+ screen = sheet->LastScreen();
+
+ xdesign->AddChild( xsheet = node( wxT( "sheet" ) ) );
+
+ // get the string representation of the sheet index number.
+ // Note that sheet->GetIndex() is zero index base and we need to increment the number by one to make
+ // human readable
+ sheetTxt.Printf( wxT( "%d" ), ( sheetList.GetIndex() + 1 ) );
+ xsheet->AddAttribute( wxT( "number" ), sheetTxt );
+ xsheet->AddAttribute( wxT( "name" ), sheet->PathHumanReadable() );
+ xsheet->AddAttribute( wxT( "tstamps" ), sheet->Path() );
+
+
+ TITLE_BLOCK tb = screen->GetTitleBlock();
+
+ xsheet->AddChild( xtitleBlock = node( wxT( "title_block" ) ) );
+
+ xtitleBlock->AddChild( node( wxT( "title" ), tb.GetTitle() ) );
+ xtitleBlock->AddChild( node( wxT( "company" ), tb.GetCompany() ) );
+ xtitleBlock->AddChild( node( wxT( "rev" ), tb.GetRevision() ) );
+ xtitleBlock->AddChild( node( wxT( "date" ), tb.GetDate() ) );
+
+ // We are going to remove the fileName directories.
+ sourceFileName = wxFileName( screen->GetFileName() );
+ xtitleBlock->AddChild( node( wxT( "source" ), sourceFileName.GetFullName() ) );
+
+ xtitleBlock->AddChild( xcomment = node( wxT( "comment" ) ) );
+ xcomment->AddAttribute( wxT("number"), wxT("1") );
+ xcomment->AddAttribute( wxT( "value" ), tb.GetComment1() );
+
+ xtitleBlock->AddChild( xcomment = node( wxT( "comment" ) ) );
+ xcomment->AddAttribute( wxT("number"), wxT("2") );
+ xcomment->AddAttribute( wxT( "value" ), tb.GetComment2() );
+
+ xtitleBlock->AddChild( xcomment = node( wxT( "comment" ) ) );
+ xcomment->AddAttribute( wxT("number"), wxT("3") );
+ xcomment->AddAttribute( wxT( "value" ), tb.GetComment3() );
+
+ xtitleBlock->AddChild( xcomment = node( wxT( "comment" ) ) );
+ xcomment->AddAttribute( wxT("number"), wxT("4") );
+ xcomment->AddAttribute( wxT( "value" ), tb.GetComment4() );
+ }
+
+ return xdesign;
+}
+
+
+XNODE* NETLIST_EXPORTER_GENERIC::makeLibraries()
+{
+ XNODE* xlibs = node( wxT( "libraries" ) ); // auto_ptr
+
+ for( std::set<void*>::iterator it = m_Libraries.begin(); it!=m_Libraries.end(); ++it )
+ {
+ PART_LIB* lib = (PART_LIB*) *it;
+ XNODE* xlibrary;
+
+ xlibs->AddChild( xlibrary = node( wxT( "library" ) ) );
+ xlibrary->AddAttribute( wxT( "logical" ), lib->GetLogicalName() );
+ xlibrary->AddChild( node( wxT( "uri" ), lib->GetFullFileName() ) );
+
+ // @todo: add more fun stuff here
+ }
+
+ return xlibs;
+}
+
+
+XNODE* NETLIST_EXPORTER_GENERIC::makeLibParts()
+{
+ XNODE* xlibparts = node( wxT( "libparts" ) ); // auto_ptr
+ wxString sLibpart = wxT( "libpart" );
+ wxString sLib = wxT( "lib" );
+ wxString sPart = wxT( "part" );
+ wxString sAliases = wxT( "aliases" );
+ wxString sAlias = wxT( "alias" );
+ wxString sPins = wxT( "pins" ); // key for library component pins list
+ wxString sPin = wxT( "pin" ); // key for one library component pin descr
+ wxString sPinNum = wxT( "num" ); // key for one library component pin num
+ wxString sPinName = wxT( "name" ); // key for one library component pin name
+ wxString sPinType = wxT( "type" ); // key for one library component pin electrical type
+ wxString sName = wxT( "name" );
+ wxString sField = wxT( "field" );
+ wxString sFields = wxT( "fields" );
+ wxString sDescr = wxT( "description" );
+ wxString sDocs = wxT( "docs" );
+ wxString sFprints = wxT( "footprints" );
+ wxString sFp = wxT( "fp" );
+
+ LIB_PINS pinList;
+ LIB_FIELDS fieldList;
+
+ m_Libraries.clear();
+
+ for( std::set<LIB_PART*>::iterator it = m_LibParts.begin(); it!=m_LibParts.end(); ++it )
+ {
+ LIB_PART* lcomp = *it;
+ PART_LIB* library = lcomp->GetLib();
+
+ m_Libraries.insert( library ); // inserts component's library if unique
+
+ XNODE* xlibpart;
+ xlibparts->AddChild( xlibpart = node( sLibpart ) );
+ xlibpart->AddAttribute( sLib, library->GetLogicalName() );
+ xlibpart->AddAttribute( sPart, lcomp->GetName() );
+
+ if( lcomp->GetAliasCount() )
+ {
+ wxArrayString aliases = lcomp->GetAliasNames( false );
+ if( aliases.GetCount() )
+ {
+ XNODE* xaliases = node( sAliases );
+ xlibpart->AddChild( xaliases );
+ for( unsigned i=0; i<aliases.GetCount(); ++i )
+ {
+ xaliases->AddChild( node( sAlias, aliases[i] ) );
+ }
+ }
+ }
+
+ //----- show the important properties -------------------------
+ if( !lcomp->GetAlias( 0 )->GetDescription().IsEmpty() )
+ xlibpart->AddChild( node( sDescr, lcomp->GetAlias( 0 )->GetDescription() ) );
+
+ if( !lcomp->GetAlias( 0 )->GetDocFileName().IsEmpty() )
+ xlibpart->AddChild( node( sDocs, lcomp->GetAlias( 0 )->GetDocFileName() ) );
+
+ // Write the footprint list
+ if( lcomp->GetFootPrints().GetCount() )
+ {
+ XNODE* xfootprints;
+ xlibpart->AddChild( xfootprints = node( sFprints ) );
+
+ for( unsigned i=0; i<lcomp->GetFootPrints().GetCount(); ++i )
+ {
+ xfootprints->AddChild( node( sFp, lcomp->GetFootPrints()[i] ) );
+ }
+ }
+
+ //----- show the fields here ----------------------------------
+ fieldList.clear();
+ lcomp->GetFields( fieldList );
+
+ XNODE* xfields;
+ xlibpart->AddChild( xfields = node( sFields ) );
+
+ for( unsigned i=0; i<fieldList.size(); ++i )
+ {
+ if( !fieldList[i].GetText().IsEmpty() )
+ {
+ XNODE* xfield;
+ xfields->AddChild( xfield = node( sField, fieldList[i].GetText() ) );
+ xfield->AddAttribute( sName, fieldList[i].GetName(false) );
+ }
+ }
+
+ //----- show the pins here ------------------------------------
+ pinList.clear();
+ lcomp->GetPins( pinList, 0, 0 );
+
+ /* we must erase redundant Pins references in pinList
+ * These redundant pins exist because some pins
+ * are found more than one time when a component has
+ * multiple parts per package or has 2 representations (DeMorgan conversion)
+ * For instance, a 74ls00 has DeMorgan conversion, with different pin shapes,
+ * and therefore each pin appears 2 times in the list.
+ * Common pins (VCC, GND) can also be found more than once.
+ */
+ sort( pinList.begin(), pinList.end(), sortPinsByNumber );
+ for( int ii = 0; ii < (int)pinList.size()-1; ii++ )
+ {
+ if( pinList[ii]->GetNumber() == pinList[ii+1]->GetNumber() )
+ { // 2 pins have the same number, remove the redundant pin at index i+1
+ pinList.erase(pinList.begin() + ii + 1);
+ ii--;
+ }
+ }
+
+ if( pinList.size() )
+ {
+ XNODE* pins;
+
+ xlibpart->AddChild( pins = node( sPins ) );
+ for( unsigned i=0; i<pinList.size(); ++i )
+ {
+ XNODE* pin;
+
+ pins->AddChild( pin = node( sPin ) );
+ pin->AddAttribute( sPinNum, pinList[i]->GetNumberString() );
+ pin->AddAttribute( sPinName, pinList[i]->GetName() );
+ pin->AddAttribute( sPinType, pinList[i]->GetCanonicalElectricalTypeName() );
+
+ // caution: construction work site here, drive slowly
+ }
+ }
+ }
+
+ return xlibparts;
+}
+
+
+XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets()
+{
+ XNODE* xnets = node( wxT( "nets" ) ); // auto_ptr if exceptions ever get used.
+ wxString netCodeTxt;
+ wxString netName;
+ wxString ref;
+
+ wxString sNet = wxT( "net" );
+ wxString sName = wxT( "name" );
+ wxString sCode = wxT( "code" );
+ wxString sRef = wxT( "ref" );
+ wxString sPin = wxT( "pin" );
+ wxString sNode = wxT( "node" );
+ wxString sFmtd = wxT( "%d" );
+
+ XNODE* xnet = 0;
+ int netCode;
+ int lastNetCode = -1;
+ int sameNetcodeCount = 0;
+
+
+ /* output:
+ <net code="123" name="/cfcard.sch/WAIT#">
+ <node ref="R23" pin="1"/>
+ <node ref="U18" pin="12"/>
+ </net>
+ */
+
+ m_LibParts.clear(); // must call this function before using m_LibParts.
+
+ for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
+ {
+ NETLIST_OBJECT* nitem = m_masterList->GetItem( ii );
+ SCH_COMPONENT* comp;
+
+ // New net found, write net id;
+ if( ( netCode = nitem->GetNet() ) != lastNetCode )
+ {
+ sameNetcodeCount = 0; // item count for this net
+ netName = nitem->GetNetName();
+ lastNetCode = netCode;
+ }
+
+ if( nitem->m_Type != NET_PIN )
+ continue;
+
+ if( nitem->m_Flag != 0 ) // Redundant pin, skip it
+ continue;
+
+ comp = nitem->GetComponentParent();
+
+ // Get the reference for the net name and the main parent component
+ ref = comp->GetRef( &nitem->m_SheetPath );
+ if( ref[0] == wxChar( '#' ) )
+ continue;
+
+ if( ++sameNetcodeCount == 1 )
+ {
+ xnets->AddChild( xnet = node( sNet ) );
+ netCodeTxt.Printf( sFmtd, netCode );
+ xnet->AddAttribute( sCode, netCodeTxt );
+ xnet->AddAttribute( sName, netName );
+ }
+
+ XNODE* xnode;
+ xnet->AddChild( xnode = node( sNode ) );
+ xnode->AddAttribute( sRef, ref );
+ xnode->AddAttribute( sPin, nitem->GetPinNumText() );
+ }
+
+ return xnets;
+}
+
+
+bool NETLIST_EXPORTER_GENERIC::writeListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
+{
+ int ret = 0;
+ int netCode;
+ int lastNetCode = -1;
+ int sameNetcodeCount = 0;
+ wxString netName;
+ wxString ref;
+ wxString netcodeName;
+ char firstItemInNet[256];
+
+ for( unsigned ii = 0; ii < aObjectsList.size(); ii++ )
+ {
+ SCH_COMPONENT* comp;
+ NETLIST_OBJECT* nitem = aObjectsList[ii];
+
+ // New net found, write net id;
+ if( ( netCode = nitem->GetNet() ) != lastNetCode )
+ {
+ sameNetcodeCount = 0; // Items count for this net
+ netName = nitem->GetNetName();
+
+ netcodeName.Printf( wxT( "Net %d " ), netCode );
+ netcodeName << wxT( "\"" ) << netName << wxT( "\"" );
+
+ // Add the netname without prefix, in cases we need only the
+ // "short" netname
+ netcodeName += wxT( " \"" ) + nitem->GetShortNetName() + wxT( "\"" );
+ lastNetCode = netCode;
+ }
+
+ if( nitem->m_Type != NET_PIN )
+ continue;
+
+ if( nitem->m_Flag != 0 ) // Redundant pin, skip it
+ continue;
+
+ comp = nitem->GetComponentParent();
+
+ // Get the reference for the net name and the main parent component
+ ref = comp->GetRef( &nitem->m_SheetPath );
+ if( ref[0] == wxChar( '#' ) )
+ continue; // Pseudo component (Like Power symbol)
+
+ // Print the pin list for this net, use special handling if
+ // 2 or more items are connected:
+
+ // if first item for this net found, defer printing this connection
+ // until a second item will is found
+ if( ++sameNetcodeCount == 1 )
+ {
+ snprintf( firstItemInNet, sizeof(firstItemInNet), " %s %.4s\n",
+ TO_UTF8( ref ),
+ (const char*) &aObjectsList[ii]->m_PinNum );
+ }
+
+ // Second item for this net found, print the Net name, and the
+ // first item
+ if( sameNetcodeCount == 2 )
+ {
+ ret |= fprintf( f, "%s\n", TO_UTF8( netcodeName ) );
+ ret |= fputs( firstItemInNet, f );
+ }
+
+ if( sameNetcodeCount >= 2 )
+ ret |= fprintf( f, " %s %.4s\n", TO_UTF8( ref ),
+ (const char*) &nitem->m_PinNum );
+ }
+
+ return ret >= 0;
+}
+
+
+XNODE* NETLIST_EXPORTER_GENERIC::node( const wxString& aName, const wxString& aTextualContent /* = wxEmptyString*/ )
+{
+ XNODE* n = new XNODE( wxXML_ELEMENT_NODE, aName );
+
+ if( aTextualContent.Len() > 0 ) // excludes wxEmptyString, the parameter's default value
+ n->AddChild( new XNODE( wxXML_TEXT_NODE, wxEmptyString, aTextualContent ) );
+
+ return n;
+}
+
+
+static bool sortPinsByNumber( LIB_PIN* aPin1, LIB_PIN* aPin2 )
+{
+ // return "lhs < rhs"
+ return RefDesStringCompare( aPin1->GetNumberString(), aPin2->GetNumberString() ) < 0;
+}
diff --git a/eeschema/netlist_exporters/netlist_exporter_generic.h b/eeschema/netlist_exporters/netlist_exporter_generic.h
new file mode 100644
index 0000000..89d57d5
--- /dev/null
+++ b/eeschema/netlist_exporters/netlist_exporter_generic.h
@@ -0,0 +1,135 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef NETLIST_EXPORT_GENERIC_H
+#define NETLIST_EXPORT_GENERIC_H
+
+#include <netlist_exporter.h>
+
+#include <xnode.h> // also nests: <wx/xml/xml.h>
+
+#define GENERIC_INTERMEDIATE_NETLIST_EXT wxT( "xml" )
+
+/**
+ * Enum GNL
+ * is a set of bit which control the totality of the tree built by makeRoot()
+ */
+enum GNL_T
+{
+ GNL_LIBRARIES = 1 << 0,
+ GNL_COMPONENTS = 1 << 1,
+ GNL_PARTS = 1 << 2,
+ GNL_HEADER = 1 << 3,
+ GNL_NETS = 1 << 4,
+};
+
+
+/**
+ * Class NETLIST_EXPORTER_GENERIC
+ * generates a generic XML based netlist file. This allows using XSLT or other methods to
+ * transform the XML to other netlist formats outside of the C++ codebase.
+ */
+class NETLIST_EXPORTER_GENERIC : public NETLIST_EXPORTER
+{
+public:
+ NETLIST_EXPORTER_GENERIC( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs ) :
+ NETLIST_EXPORTER( aMasterList, aLibs )
+ {
+ }
+
+ /**
+ * Function WriteNetlist
+ * writes to specified output file
+ */
+ bool WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions );
+
+#define GNL_ALL ( GNL_LIBRARIES | GNL_COMPONENTS | GNL_PARTS | GNL_HEADER | GNL_NETS )
+
+protected:
+ /**
+ * Function node
+ * is a convenience function that creates a new XNODE with an optional textual child.
+ * It also provides some insulation from a possible change in XML library.
+ *
+ * @param aName is the name to associate with a new node of type wxXML_ELEMENT_NODE.
+ * @param aTextualContent is optional, and if given is the text to include in a child
+ * of the returned node, and has type wxXML_TEXT_NODE.
+ */
+ XNODE* node( const wxString& aName, const wxString& aTextualContent = wxEmptyString );
+
+ /**
+ * Function writeGENERICListOfNets
+ * writes out nets (ranked by Netcode), and elements that are
+ * connected as part of that net.
+ */
+ bool writeListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList );
+
+ /**
+ * Function makeGenericRoot
+ * builds the entire document tree for the generic export. This is factored
+ * out here so we can write the tree in either S-expression file format
+ * or in XML if we put the tree built here into a wxXmlDocument.
+ * @param aCtl - a bitset or-ed together from GNL_ENUM values
+ * @return XNODE* - the root nodes
+ */
+ XNODE* makeRoot( int aCtl = GNL_ALL );
+
+ /**
+ * Function makeComponents
+ * @return XNODE* - returns a sub-tree holding all the schematic components.
+ */
+ XNODE* makeComponents();
+
+ /**
+ * Function makeDesignHeader
+ * fills out a project "design" header into an XML node.
+ * @return XNODE* - the design header
+ */
+ XNODE* makeDesignHeader();
+
+ /**
+ * Function makeLibParts
+ * fills out an XML node with the unique library parts and returns it.
+ * @return XNODE* - the library parts nodes
+ */
+ XNODE* makeLibParts();
+
+ /**
+ * Function makeListOfNets
+ * fills out an XML node with a list of nets and returns it.
+ * @return XNODE* - the list of nets nodes
+ */
+ XNODE* makeListOfNets();
+
+ /**
+ * Function makeLibraries
+ * fills out an XML node with a list of used libraries and returns it.
+ * Must have called makeGenericLibParts() before this function.
+ * @return XNODE* - the library nodes
+ */
+ XNODE* makeLibraries();
+};
+
+#endif
diff --git a/eeschema/netlist_exporters/netlist_exporter_kicad.cpp b/eeschema/netlist_exporters/netlist_exporter_kicad.cpp
new file mode 100644
index 0000000..e4b624c
--- /dev/null
+++ b/eeschema/netlist_exporters/netlist_exporter_kicad.cpp
@@ -0,0 +1,77 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <build_version.h>
+#include <confirm.h>
+
+#include <schframe.h>
+#include "netlist_exporter_kicad.h"
+
+bool NETLIST_EXPORTER_KICAD::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
+{
+#if 0
+ // Prepare list of nets generation
+ for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
+ m_masterList->GetItem( ii )->m_Flag = 0;
+
+ std::auto_ptr<XNODE> xroot( makeRoot() );
+
+ try
+ {
+ FILE_OUTPUTFORMATTER formatter( aOutFileName );
+
+ xroot->Format( &formatter, 0 );
+ }
+#else
+ try
+ {
+ FILE_OUTPUTFORMATTER formatter( aOutFileName );
+
+ Format( &formatter, GNL_ALL );
+ }
+#endif
+
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( NULL, ioe.errorText );
+ return false;
+ }
+
+ return true;
+}
+
+
+void NETLIST_EXPORTER_KICAD::Format( OUTPUTFORMATTER* aOut, int aCtl )
+{
+ // Prepare list of nets generation
+ for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
+ m_masterList->GetItem( ii )->m_Flag = 0;
+
+ std::auto_ptr<XNODE> xroot( makeRoot( aCtl ) );
+
+ xroot->Format( aOut, 0 );
+}
diff --git a/eeschema/netlist_exporters/netlist_exporter_kicad.h b/eeschema/netlist_exporters/netlist_exporter_kicad.h
new file mode 100644
index 0000000..433d12c
--- /dev/null
+++ b/eeschema/netlist_exporters/netlist_exporter_kicad.h
@@ -0,0 +1,63 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef NETLIST_EXPORTER_KICAD_H
+#define NETLIST_EXPORTER_KICAD_H
+
+#include <netlist_exporter_generic.h>
+
+class OUTPUTFORMATTER;
+
+/**
+ * Class NETLIST_EXPORTER_KICAD
+ * generates the kicad netlist format supported by pcbnew. It is basically
+ * the generic netlist format just formatted slightly different.
+ */
+class NETLIST_EXPORTER_KICAD : public NETLIST_EXPORTER_GENERIC
+{
+public:
+ NETLIST_EXPORTER_KICAD( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs ) :
+ NETLIST_EXPORTER_GENERIC( aMasterList, aLibs )
+ {
+ }
+
+ /**
+ * Function WriteNetlist
+ * writes to specified output file
+ */
+ bool WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions ); // OVERRIDE
+
+ /**
+ * Function Format
+ * outputs this s-expression netlist into @a aOutputFormatter.
+ * @param aOutputFormatter is the destination of the serialization to text.
+ * @param aCtl is bit set composed by OR-ing together enum GNL bits, it allows ouputting
+ * a subset of the full document model.
+ * @throw IO_ERROR if any problems.
+ */
+ void Format( OUTPUTFORMATTER* aOutputFormatter, int aCtl );
+};
+
+#endif
diff --git a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp
new file mode 100644
index 0000000..0aeaccc
--- /dev/null
+++ b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp
@@ -0,0 +1,145 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <build_version.h>
+#include <confirm.h>
+
+#include <schframe.h>
+#include <sch_reference_list.h>
+#include <class_library.h>
+#include <class_netlist_object.h>
+
+#include <netlist.h>
+#include "netlist_exporter_orcadpcb2.h"
+
+bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
+{
+ (void)aNetlistOptions; //unused
+ FILE* f = NULL;
+ wxString field;
+ wxString footprint;
+ int ret = 0; // zero now, OR in the sign bit on error
+ wxString netName;
+
+
+ if( ( f = wxFopen( aOutFileName, wxT( "wt" ) ) ) == NULL )
+ {
+ wxString msg;
+ msg.Printf( _( "Failed to create file '%s'" ),
+ GetChars( aOutFileName ) );
+ DisplayError( NULL, msg );
+ return false;
+ }
+
+ std::vector< SCH_REFERENCE > cmpList;
+
+ ret |= fprintf( f, "( { %s created %s }\n",
+ NETLIST_HEAD_STRING, TO_UTF8( DateAndTime() ) );
+
+ // Prepare list of nets generation
+ for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
+ m_masterList->GetItem( ii )->m_Flag = 0;
+
+ // Create netlist module section
+ m_ReferencesAlreadyFound.Clear();
+
+ SCH_SHEET_LIST sheetList;
+
+ for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path; path = sheetList.GetNext() )
+ {
+ for( EDA_ITEM* item = path->LastDrawList(); item; item = item->Next() )
+ {
+ SCH_COMPONENT* comp = findNextComponentAndCreatePinList( item, path );
+
+ if( !comp )
+ break;
+
+ item = comp;
+
+ // Get the Component FootprintFilter and put the component in
+ // cmpList if filter is present
+ LIB_PART* part = m_libs->FindLibPart( comp->GetPartName() );
+
+ if( part )
+ {
+ if( part->GetFootPrints().GetCount() != 0 ) // Put in list
+ {
+ cmpList.push_back( SCH_REFERENCE( comp, part, *path ) );
+ }
+ }
+
+ if( !comp->GetField( FOOTPRINT )->IsVoid() )
+ {
+ footprint = comp->GetField( FOOTPRINT )->GetText();
+ footprint.Replace( wxT( " " ), wxT( "_" ) );
+ }
+ else
+ footprint = wxT( "$noname" );
+
+ field = comp->GetRef( path );
+
+ ret |= fprintf( f, " ( %s %s",
+ TO_UTF8( comp->GetPath( path ) ),
+ TO_UTF8( footprint ) );
+
+ ret |= fprintf( f, " %s", TO_UTF8( field ) );
+
+ field = comp->GetField( VALUE )->GetText();
+ field.Replace( wxT( " " ), wxT( "_" ) );
+ ret |= fprintf( f, " %s", TO_UTF8( field ) );
+
+ ret |= fprintf( f, "\n" );
+
+ // Write pin list:
+ for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
+ {
+ NETLIST_OBJECT* pin = m_SortedComponentPinList[ii];
+
+ if( !pin )
+ continue;
+
+ sprintPinNetName( netName, wxT( "N-%.6d" ), pin );
+
+ if( netName.IsEmpty() )
+ netName = wxT( "?" );
+
+ netName.Replace( wxT( " " ), wxT( "_" ) );
+
+ ret |= fprintf( f, " ( %4.4s %s )\n", (char*) &pin->m_PinNum,
+ TO_UTF8( netName ) );
+ }
+
+ ret |= fprintf( f, " )\n" );
+ }
+ }
+
+ ret |= fprintf( f, ")\n*\n" );
+
+ fclose( f );
+
+ m_SortedComponentPinList.clear();
+ return ret >= 0;
+}
diff --git a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.h b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.h
new file mode 100644
index 0000000..06fcf10
--- /dev/null
+++ b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.h
@@ -0,0 +1,46 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef NETLIST_EXPORTER_ORCADPCB2_H
+#define NETLIST_EXPORTER_ORCADPCB2_H
+
+#include "netlist_exporter.h"
+
+/**
+ * Class NETLIST_EXPORTER_ORCADPCB2
+ * generates a netlist compatible with OrCAD
+ */
+class NETLIST_EXPORTER_ORCADPCB2 : public NETLIST_EXPORTER
+{
+public:
+ NETLIST_EXPORTER_ORCADPCB2( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs ) :
+ NETLIST_EXPORTER( aMasterList, aLibs )
+ {
+ }
+
+ bool WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions );
+};
+
+#endif
diff --git a/eeschema/netlist_exporters/netlist_exporter_pspice.cpp b/eeschema/netlist_exporters/netlist_exporter_pspice.cpp
new file mode 100644
index 0000000..7158bd4
--- /dev/null
+++ b/eeschema/netlist_exporters/netlist_exporter_pspice.cpp
@@ -0,0 +1,358 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <build_version.h>
+#include <confirm.h>
+
+#include <schframe.h>
+#include <netlist.h>
+#include <sch_reference_list.h>
+#include <class_netlist_object.h>
+#include <wx/tokenzr.h>
+#include "netlist_exporter_pspice.h"
+
+bool NETLIST_EXPORTER_PSPICE::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
+{
+ FILE* f = NULL;
+ bool aUsePrefix = aNetlistOptions & NET_USE_X_PREFIX;
+ bool aUseNetcodeAsNetName = aNetlistOptions & NET_USE_NETCODES_AS_NETNAMES;
+
+ int ret = 0;
+ int nbitems;
+ wxString text;
+ wxArrayString spiceCommandAtBeginFile;
+ wxArrayString spiceCommandAtEndFile;
+ wxString msg;
+ wxString netName;
+
+ #define BUFYPOS_LEN 4
+ wxChar bufnum[BUFYPOS_LEN + 1];
+ std::vector<int> pinSequence; // numeric indices into m_SortedComponentPinList
+ wxArrayString stdPinNameArray; // Array containing Standard Pin Names
+ wxString delimeters = wxT( "{:,; }" );
+ wxString disableStr = wxT( "N" );
+
+ if( ( f = wxFopen( aOutFileName, wxT( "wt" ) ) ) == NULL )
+ {
+ wxString msg;
+ msg.Printf( _( "Failed to create file '%s'" ),
+ GetChars( aOutFileName ) );
+ DisplayError( NULL, msg );
+ return false;
+ }
+
+ ret |= fprintf( f, "* %s\n\n", TO_UTF8( aOutFileName ) );
+ ret |= fprintf( f, "* %s (Spice format) creation date: %s\n\n",
+ NETLIST_HEAD_STRING, TO_UTF8( DateAndTime() ) );
+
+ // Prepare list of nets generation (not used here, but...
+ for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
+ m_masterList->GetItem( ii )->m_Flag = 0;
+
+ ret |= fprintf( f, "* To exclude a component from the Spice Netlist add [Spice_Netlist_Enabled] user FIELD set to: N\n" );
+ ret |= fprintf( f, "* To reorder the component spice node sequence add [Spice_Node_Sequence] user FIELD and define sequence: 2,1,0\n" );
+
+ // Create text list starting by [.-]pspice , or [.-]gnucap (simulator
+ // commands) and create text list starting by [+]pspice , or [+]gnucap
+ // (simulator commands)
+ bufnum[BUFYPOS_LEN] = 0;
+ SCH_SHEET_LIST sheetList;
+
+ for( SCH_SHEET_PATH* sheet = sheetList.GetFirst(); sheet; sheet = sheetList.GetNext() )
+ {
+ for( EDA_ITEM* item = sheet->LastDrawList(); item; item = item->Next() )
+ {
+ size_t l1, l2;
+ wxChar ident;
+
+ if( item->Type() != SCH_TEXT_T )
+ continue;
+
+ SCH_TEXT* drawText = (SCH_TEXT*) item;
+
+ text = drawText->GetText();
+
+ if( text.IsEmpty() )
+ continue;
+
+ ident = text.GetChar( 0 );
+
+ if( ident != '.' && ident != '-' && ident != '+' )
+ continue;
+
+ text.Remove( 0, 1 ); // Remove the first char.
+ text.Remove( 6 ); // text contains 6 char.
+ text.MakeLower();
+
+ if( text != wxT( "pspice" ) && text != wxT( "gnucap" ) )
+ continue;
+
+ text = drawText->GetText().Mid( 7 );
+ l1 = text.Length();
+ text.Trim( false );
+ l2 = text.Length();
+
+ if( l1 == l2 )
+ continue; // no whitespace after ident text
+
+ {
+ // Put the Y position as an ascii string, for sort by vertical
+ // position, using usual sort string by alphabetic value
+ int ypos = drawText->GetPosition().y;
+
+ for( int ii = 0; ii < BUFYPOS_LEN; ii++ )
+ {
+ bufnum[BUFYPOS_LEN - 1 - ii] = (ypos & 63) + ' ';
+ ypos >>= 6;
+ }
+
+ // First BUFYPOS_LEN char are the Y position.
+ msg.Printf( wxT( "%s %s" ), bufnum, text.GetData() );
+
+ if( ident == '+' )
+ spiceCommandAtEndFile.Add( msg );
+ else
+ spiceCommandAtBeginFile.Add( msg );
+ }
+ }
+ }
+
+ // Print texts starting by [.-]pspice , ou [.-]gnucap (of course, without
+ // the Y position string)
+ nbitems = spiceCommandAtBeginFile.GetCount();
+
+ if( nbitems )
+ {
+ spiceCommandAtBeginFile.Sort();
+
+ for( int ii = 0; ii < nbitems; ii++ )
+ {
+ spiceCommandAtBeginFile[ii].Remove( 0, BUFYPOS_LEN );
+ spiceCommandAtBeginFile[ii].Trim( true );
+ spiceCommandAtBeginFile[ii].Trim( false );
+ ret |= fprintf( f, "%s\n", TO_UTF8( spiceCommandAtBeginFile[ii] ) );
+ }
+ }
+ ret |= fprintf( f, "\n" );
+
+ // Create component list
+
+ m_ReferencesAlreadyFound.Clear();
+
+ for( SCH_SHEET_PATH* sheet = sheetList.GetFirst(); sheet; sheet = sheetList.GetNext() )
+ {
+ ret |= fprintf( f, "* Sheet Name: %s\n", TO_UTF8( sheet->PathHumanReadable() ) );
+
+ for( EDA_ITEM* item = sheet->LastDrawList(); item; item = item->Next() )
+ {
+ SCH_COMPONENT* comp = findNextComponentAndCreatePinList( item, sheet );
+
+ if( !comp )
+ break;
+
+ item = comp;
+
+ // Reset NodeSeqIndex Count:
+ pinSequence.clear();
+
+ // Check to see if component should be removed from Spice Netlist:
+ SCH_FIELD* netlistEnabledField = comp->FindField( wxT( "Spice_Netlist_Enabled" ) );
+
+ if( netlistEnabledField )
+ {
+ wxString netlistEnabled = netlistEnabledField->GetText();
+
+ if( netlistEnabled.CmpNoCase( disableStr ) == 0 )
+ continue;
+ }
+
+ // Check if Alternative Pin Sequence is Available:
+ SCH_FIELD* spiceSeqField = comp->FindField( wxT( "Spice_Node_Sequence" ) );
+
+ if( spiceSeqField )
+ {
+ // Get String containing the Sequence of Nodes:
+ wxString nodeSeqIndexLineStr = spiceSeqField->GetText();
+
+ // Verify Field Exists and is not empty:
+ if( !nodeSeqIndexLineStr.IsEmpty() )
+ {
+
+ // Create an Array of Standard Pin Names from part definition:
+ stdPinNameArray.Clear();
+
+ for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
+ {
+ NETLIST_OBJECT* pin = m_SortedComponentPinList[ii];
+
+ if( !pin )
+ continue;
+
+ stdPinNameArray.Add( pin->GetPinNumText() );
+ }
+
+ // Get Alt Pin Name Array From User:
+ wxStringTokenizer tkz( nodeSeqIndexLineStr, delimeters );
+
+ while( tkz.HasMoreTokens() )
+ {
+ wxString pinIndex = tkz.GetNextToken();
+ int seq;
+
+ // Find PinName In Standard List assign Standard List Index to Name:
+ seq = stdPinNameArray.Index(pinIndex);
+
+ if( seq != wxNOT_FOUND )
+ {
+ pinSequence.push_back( seq );
+ }
+ }
+
+ }
+ }
+
+ //Get Standard Reference Designator:
+ wxString RefName = comp->GetRef( sheet );
+
+ //Conditionally add Prefix only for devices that begin with U or IC:
+ if( aUsePrefix )
+ {
+ if( RefName.StartsWith( wxT( "U" ) ) || RefName.StartsWith( wxT( "IC" ) ) )
+ RefName = wxT( "X" ) + RefName;
+ }
+
+ ret |= fprintf( f, "%s ", TO_UTF8( RefName ) );
+
+ // Write pin list:
+ int activePinIndex = 0;
+
+ for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
+ {
+ // Case of Alt Sequence definition with Unused/Invalid Node index:
+ // Valid used Node Indexes are in the set
+ // {0,1,2,...m_SortedComponentPinList.size()-1}
+ if( pinSequence.size() )
+ {
+ // All Vector values must be less <= max package size
+ // And Total Vector size should be <= package size
+ if( ( (unsigned) pinSequence[ii] < m_SortedComponentPinList.size() )
+ && ( ii < pinSequence.size() ) )
+ {
+ // Case of Alt Pin Sequence in control good Index:
+ activePinIndex = pinSequence[ii];
+ }
+ else
+ {
+ // Case of Alt Pin Sequence in control Bad Index or not using all
+ // pins for simulation:
+ continue;
+ }
+ }
+ // Case of Standard Pin Sequence in control:
+ else
+ {
+ activePinIndex = ii;
+ }
+
+ NETLIST_OBJECT* pin = m_SortedComponentPinList[activePinIndex];
+
+ if( !pin )
+ continue;
+
+ sprintPinNetName( netName , wxT( "N-%.6d" ), pin, aUseNetcodeAsNetName );
+
+ //Replace parenthesis with underscore to prevent parse issues with Simulators:
+ netName.Replace( wxT( "(" ), wxT( "_" ) );
+ netName.Replace( wxT( ")" ), wxT( "_" ) );
+
+ if( netName.IsEmpty() )
+ netName = wxT( "?" );
+
+ ret |= fprintf( f, " %s", TO_UTF8( netName ) );
+ }
+
+ // Get Component Value Name:
+ wxString CompValue = comp->GetField( VALUE )->GetText();
+
+ // Check if Override Model Name is Provided:
+ SCH_FIELD* spiceModelField = comp->FindField( wxT( "spice_model" ) );
+
+ if( spiceModelField )
+ {
+ // Get Model Name String:
+ wxString ModelNameStr = spiceModelField->GetText();
+
+ // Verify Field Exists and is not empty:
+ if( !ModelNameStr.IsEmpty() )
+ CompValue = ModelNameStr;
+ }
+
+ // Print Component Value:
+ ret |= fprintf( f, " %s\t\t",TO_UTF8( CompValue ) );
+
+ // Show Seq Spec on same line as component using line-comment ";":
+ for( unsigned i = 0; i < pinSequence.size(); ++i )
+ {
+ if( i==0 )
+ ret |= fprintf( f, ";Node Sequence Spec.<" );
+
+ ret |= fprintf( f, "%s", TO_UTF8( stdPinNameArray.Item( pinSequence[i] ) ) );
+
+ if( i < pinSequence.size()-1 )
+ ret |= fprintf( f, "," );
+ else
+ ret |= fprintf( f, ">" );
+ }
+
+ // Next Netlist line record:
+ ret |= fprintf( f, "\n" );
+ }
+ }
+
+ m_SortedComponentPinList.clear();
+
+ // Print texts starting with [+]pspice or [+]gnucap
+ nbitems = spiceCommandAtEndFile.GetCount();
+
+ if( nbitems )
+ {
+ ret |= fprintf( f, "\n" );
+ spiceCommandAtEndFile.Sort();
+
+ for( int ii = 0; ii < nbitems; ii++ )
+ {
+ spiceCommandAtEndFile[ii].Remove( 0, +BUFYPOS_LEN );
+ spiceCommandAtEndFile[ii].Trim( true );
+ spiceCommandAtEndFile[ii].Trim( false );
+ ret |= fprintf( f, "%s\n", TO_UTF8( spiceCommandAtEndFile[ii] ) );
+ }
+ }
+
+ ret |= fprintf( f, "\n.end\n" );
+ fclose( f );
+
+ return ret >= 0;
+}
diff --git a/eeschema/netlist_exporters/netlist_exporter_pspice.h b/eeschema/netlist_exporters/netlist_exporter_pspice.h
new file mode 100644
index 0000000..c57938f
--- /dev/null
+++ b/eeschema/netlist_exporters/netlist_exporter_pspice.h
@@ -0,0 +1,50 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef NETLIST_EXPORTER_PSPICE_H
+#define NETLIST_EXPORTER_PSPICE_H
+
+#include "netlist_exporter.h"
+
+/**
+ * Class NETLIST_EXPORTER_PSPICE
+ * generates a PSPICE compatible netlist
+ */
+class NETLIST_EXPORTER_PSPICE : public NETLIST_EXPORTER
+{
+public:
+ NETLIST_EXPORTER_PSPICE( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs ) :
+ NETLIST_EXPORTER( aMasterList, aLibs )
+ {
+ }
+
+ /**
+ * Function WriteNetlist
+ * writes to specified output file
+ */
+ bool WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions );
+};
+
+#endif
diff --git a/eeschema/onleftclick.cpp b/eeschema/onleftclick.cpp
new file mode 100644
index 0000000..35ba87d
--- /dev/null
+++ b/eeschema/onleftclick.cpp
@@ -0,0 +1,407 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/onleftclick.cpp
+ */
+
+#include <fctsys.h>
+#include <eeschema_id.h>
+#include <class_drawpanel.h>
+#include <schframe.h>
+#include <menus_helpers.h>
+
+#include <sch_bus_entry.h>
+#include <sch_text.h>
+#include <sch_marker.h>
+#include <sch_junction.h>
+#include <sch_line.h>
+#include <sch_no_connect.h>
+#include <sch_component.h>
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+#include <sch_bitmap.h>
+#include <class_library.h> // fo class SCHLIB_FILTER to filter power parts
+
+
+// TODO(hzeller): These pairs of elmenets should be represented by an object, but don't want
+// to refactor too much right now to not get in the way with other code changes.
+static wxArrayString s_CmpNameList;
+static int s_CmpLastUnit;
+
+static wxArrayString s_PowerNameList;
+static int s_LastPowerUnit;
+
+
+void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
+{
+ SCH_ITEM* item = GetScreen()->GetCurItem();
+ wxPoint gridPosition = GetGridPosition( aPosition );
+
+ if( ( GetToolId() == ID_NO_TOOL_SELECTED ) || ( item && item->GetFlags() ) )
+ {
+ m_canvas->SetAutoPanRequest( false );
+ SetRepeatItem( NULL );
+
+ if( item && item->GetFlags() )
+ {
+ switch( item->Type() )
+ {
+ case SCH_LABEL_T:
+ case SCH_GLOBAL_LABEL_T:
+ case SCH_HIERARCHICAL_LABEL_T:
+ case SCH_TEXT_T:
+ case SCH_SHEET_PIN_T:
+ case SCH_SHEET_T:
+ case SCH_BUS_WIRE_ENTRY_T:
+ case SCH_BUS_BUS_ENTRY_T:
+ case SCH_JUNCTION_T:
+ case SCH_COMPONENT_T:
+ case SCH_FIELD_T:
+ case SCH_BITMAP_T:
+ case SCH_NO_CONNECT_T:
+ addCurrentItemToList();
+ return;
+
+ case SCH_LINE_T: // May already be drawing segment.
+ break;
+
+ default:
+ wxFAIL_MSG( wxT( "SCH_EDIT_FRAME::OnLeftClick error. Item type <" ) +
+ item->GetClass() + wxT( "> is already being edited." ) );
+ item->ClearFlags();
+ break;
+ }
+ }
+ else
+ {
+ item = LocateAndShowItem( aPosition );
+ }
+ }
+
+ switch( GetToolId() )
+ {
+ case ID_NO_TOOL_SELECTED:
+ break;
+
+ case ID_HIERARCHY_PUSH_POP_BUTT:
+ if( ( item && item->GetFlags() ) || ( g_RootSheet->CountSheets() == 0 ) )
+ break;
+
+ item = LocateAndShowItem( aPosition, SCH_COLLECTOR::SheetsOnly );
+
+ if( item ) // The user has clicked on a sheet: this is an enter sheet command
+ {
+ m_CurrentSheet->Push( (SCH_SHEET*) item );
+ DisplayCurrentSheet();
+ }
+ else if( m_CurrentSheet->Last() != g_RootSheet )
+ { // The user has clicked ouside a sheet:this is an leave sheet command
+ m_CurrentSheet->Pop();
+ DisplayCurrentSheet();
+ }
+ break;
+
+ case ID_NOCONN_BUTT:
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ {
+ if( GetScreen()->GetItem( gridPosition, 0, SCH_NO_CONNECT_T ) == NULL )
+ {
+ SCH_NO_CONNECT* no_connect = AddNoConnect( aDC, gridPosition );
+ SetRepeatItem( no_connect );
+ GetScreen()->SetCurItem( no_connect );
+ m_canvas->SetAutoPanRequest( true );
+ }
+ }
+ else
+ {
+ addCurrentItemToList();
+ }
+ break;
+
+ case ID_JUNCTION_BUTT:
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ {
+ if( GetScreen()->GetItem( gridPosition, 0, SCH_JUNCTION_T ) == NULL )
+ {
+ SCH_JUNCTION* junction = AddJunction( aDC, gridPosition, true );
+ SetRepeatItem( junction );
+ GetScreen()->SetCurItem( junction );
+ m_canvas->SetAutoPanRequest( true );
+ }
+ }
+ else
+ {
+ addCurrentItemToList();
+ }
+ break;
+
+ case ID_WIRETOBUS_ENTRY_BUTT:
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ {
+ CreateBusWireEntry();
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else
+ {
+ addCurrentItemToList();
+ }
+ break;
+
+ case ID_BUSTOBUS_ENTRY_BUTT:
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ {
+ CreateBusBusEntry();
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else
+ {
+ addCurrentItemToList();
+ }
+ break;
+
+ case ID_SCHEMATIC_DELETE_ITEM_BUTT:
+ DeleteItemAtCrossHair( aDC );
+ break;
+
+ case ID_WIRE_BUTT:
+ BeginSegment( aDC, LAYER_WIRE );
+ m_canvas->SetAutoPanRequest( true );
+ break;
+
+ case ID_BUS_BUTT:
+ BeginSegment( aDC, LAYER_BUS );
+ m_canvas->SetAutoPanRequest( true );
+ break;
+
+ case ID_LINE_COMMENT_BUTT:
+ BeginSegment( aDC, LAYER_NOTES );
+ m_canvas->SetAutoPanRequest( true );
+ break;
+
+ case ID_TEXT_COMMENT_BUTT:
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ {
+ GetScreen()->SetCurItem( CreateNewText( aDC, LAYER_NOTES ) );
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else
+ {
+ addCurrentItemToList();
+ }
+ break;
+
+ case ID_ADD_IMAGE_BUTT:
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ {
+ GetScreen()->SetCurItem( CreateNewImage( aDC ) );
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else
+ {
+ addCurrentItemToList();
+ }
+ break;
+
+ case ID_LABEL_BUTT:
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ {
+ GetScreen()->SetCurItem( CreateNewText( aDC, LAYER_LOCLABEL ) );
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else
+ {
+ addCurrentItemToList();
+ }
+ break;
+
+ case ID_GLABEL_BUTT:
+ case ID_HIERLABEL_BUTT:
+ if( (item == NULL) || (item->GetFlags() == 0) )
+ {
+ if( GetToolId() == ID_GLABEL_BUTT )
+ GetScreen()->SetCurItem( CreateNewText( aDC, LAYER_GLOBLABEL ) );
+
+ if( GetToolId() == ID_HIERLABEL_BUTT )
+ GetScreen()->SetCurItem( CreateNewText( aDC, LAYER_HIERLABEL ) );
+
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else
+ {
+ addCurrentItemToList();
+ }
+ break;
+
+ case ID_SHEET_SYMBOL_BUTT:
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ {
+ item = CreateSheet( aDC );
+
+ if( item != NULL )
+ {
+ GetScreen()->SetCurItem( item );
+ m_canvas->SetAutoPanRequest( true );
+ }
+ }
+ else
+ {
+ addCurrentItemToList();
+ }
+ break;
+
+ case ID_IMPORT_HLABEL_BUTT:
+ case ID_SHEET_PIN_BUTT:
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ item = LocateAndShowItem( aPosition, SCH_COLLECTOR::SheetsAndSheetLabels );
+
+ if( item == NULL )
+ break;
+
+ if( (item->Type() == SCH_SHEET_T) && (item->GetFlags() == 0) )
+ {
+ if( GetToolId() == ID_IMPORT_HLABEL_BUTT )
+ GetScreen()->SetCurItem( ImportSheetPin( (SCH_SHEET*) item, aDC ) );
+ else
+ GetScreen()->SetCurItem( CreateSheetPin( (SCH_SHEET*) item, aDC ) );
+ }
+ else if( (item->Type() == SCH_SHEET_PIN_T) && (item->GetFlags() != 0) )
+ {
+ addCurrentItemToList();
+ }
+ break;
+
+ case ID_SCH_PLACE_COMPONENT:
+ if( (item == NULL) || (item->GetFlags() == 0) )
+ {
+ GetScreen()->SetCurItem( Load_Component( aDC, NULL,
+ s_CmpNameList, s_CmpLastUnit, true ) );
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else
+ {
+ addCurrentItemToList();
+ }
+ break;
+
+ case ID_PLACE_POWER_BUTT:
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ {
+ SCHLIB_FILTER filter;
+ filter.FilterPowerParts( true );
+ GetScreen()->SetCurItem( Load_Component( aDC, &filter,
+ s_PowerNameList, s_LastPowerUnit, false ) );
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else
+ {
+ addCurrentItemToList();
+ }
+ break;
+
+ default:
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ wxFAIL_MSG( wxT( "SCH_EDIT_FRAME::OnLeftClick invalid tool ID <" ) +
+ wxString::Format( wxT( "%d> selected." ), GetToolId() ) );
+ }
+}
+
+
+/**
+ * Function OnLeftDClick
+ * called on a double click event from the drawpanel mouse handler
+ * if an editable item is found (text, component)
+ * Call the suitable dialog editor.
+ * Id a create command is in progress:
+ * validate and finish the command
+ */
+void SCH_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition )
+
+{
+ EDA_ITEM* item = GetScreen()->GetCurItem();
+
+ switch( GetToolId() )
+ {
+ case ID_NO_TOOL_SELECTED:
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ {
+ item = LocateAndShowItem( aPosition );
+ }
+
+ if( ( item == NULL ) || ( item->GetFlags() != 0 ) )
+ break;
+
+ switch( item->Type() )
+ {
+ case SCH_SHEET_T:
+ m_CurrentSheet->Push( (SCH_SHEET*) item );
+ DisplayCurrentSheet();
+ break;
+
+ case SCH_COMPONENT_T:
+ EditComponent( (SCH_COMPONENT*) item );
+ GetCanvas()->MoveCursorToCrossHair();
+
+ if( item->GetFlags() == 0 )
+ GetScreen()->SetCurItem( NULL );
+
+ GetCanvas()->Refresh();
+ break;
+
+ case SCH_TEXT_T:
+ case SCH_LABEL_T:
+ case SCH_GLOBAL_LABEL_T:
+ case SCH_HIERARCHICAL_LABEL_T:
+ EditSchematicText( (SCH_TEXT*) item );
+ break;
+
+ case SCH_BITMAP_T:
+ EditImage( (SCH_BITMAP*) item );
+ break;
+
+ case SCH_FIELD_T:
+ EditComponentFieldText( (SCH_FIELD*) item );
+ GetCanvas()->MoveCursorToCrossHair();
+ break;
+
+ case SCH_MARKER_T:
+ ( (SCH_MARKER*) item )->DisplayMarkerInfo( this );
+ break;
+
+ default:
+ break;
+ }
+
+ break;
+
+ case ID_BUS_BUTT:
+ case ID_WIRE_BUTT:
+ case ID_LINE_COMMENT_BUTT:
+ if( item && item->IsNew() )
+ EndSegment( aDC );
+
+ break;
+ }
+}
diff --git a/eeschema/onrightclick.cpp b/eeschema/onrightclick.cpp
new file mode 100644
index 0000000..442e241
--- /dev/null
+++ b/eeschema/onrightclick.cpp
@@ -0,0 +1,927 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2014 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file eeschema/onrightclick.cpp
+ */
+
+#include <fctsys.h>
+#include <eeschema_id.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <schframe.h>
+#include <menus_helpers.h>
+
+#include <general.h>
+#include <hotkeys.h>
+#include <class_library.h>
+#include <sch_bus_entry.h>
+#include <sch_marker.h>
+#include <sch_text.h>
+#include <sch_junction.h>
+#include <sch_component.h>
+#include <sch_line.h>
+#include <sch_no_connect.h>
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+#include <sch_bitmap.h>
+
+#include <iostream>
+
+static void AddMenusForBlock( wxMenu* PopMenu, SCH_EDIT_FRAME* frame );
+static void AddMenusForWire( wxMenu* PopMenu, SCH_LINE* Wire, SCH_EDIT_FRAME* frame );
+static void AddMenusForBus( wxMenu* PopMenu, SCH_LINE* Bus, SCH_EDIT_FRAME* frame );
+static void AddMenusForHierchicalSheet( wxMenu* PopMenu, SCH_SHEET* Sheet );
+static void AddMenusForSheetPin( wxMenu* PopMenu, SCH_SHEET_PIN* PinSheet );
+static void AddMenusForText( wxMenu* PopMenu, SCH_TEXT* Text );
+static void AddMenusForLabel( wxMenu* PopMenu, SCH_LABEL* Label );
+static void AddMenusForGLabel( wxMenu* PopMenu, SCH_GLOBALLABEL* GLabel );
+static void AddMenusForHLabel( wxMenu* PopMenu, SCH_HIERLABEL* GLabel );
+static void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* aLibs );
+static void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* aLibs );
+static void AddMenusForComponentField( wxMenu* PopMenu, SCH_FIELD* Field );
+static void AddMenusForMarkers( wxMenu* aPopMenu, SCH_MARKER* aMarker, SCH_EDIT_FRAME* aFrame );
+static void AddMenusForBitmap( wxMenu* aPopMenu, SCH_BITMAP * aBitmap );
+static void AddMenusForBusEntry( wxMenu* aPopMenu, SCH_BUS_ENTRY_BASE * aBusEntry );
+
+
+bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
+{
+ SCH_ITEM* item = GetScreen()->GetCurItem();
+ bool blockActive = GetScreen()->IsBlockActive();
+ wxString msg;
+
+ // Do not start a block command on context menu.
+ m_canvas->SetCanStartBlock( -1 );
+
+ if( blockActive )
+ {
+ AddMenusForBlock( PopMenu, this );
+ PopMenu->AppendSeparator();
+
+ // If we have a block containing only one main element
+ // we append its edition submenu
+ if( item != NULL )
+ {
+ switch( item->Type() )
+ {
+ case SCH_COMPONENT_T:
+ AddMenusForEditComponent( PopMenu, (SCH_COMPONENT *) item, Prj().SchLibs() );
+ PopMenu->AppendSeparator();
+ break;
+
+ case SCH_TEXT_T:
+ msg = AddHotkeyName( _( "Edit Text" ), g_Schematic_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
+ PopMenu->AppendSeparator();
+ break;
+
+ case SCH_LABEL_T:
+ msg = AddHotkeyName( _( "Edit Label" ), g_Schematic_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
+ PopMenu->AppendSeparator();
+ break;
+
+ case SCH_GLOBAL_LABEL_T:
+ msg = AddHotkeyName( _( "Edit Global Label" ), g_Schematic_Hokeys_Descr,
+ HK_EDIT );
+ AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
+ PopMenu->AppendSeparator();
+ break;
+
+ case SCH_HIERARCHICAL_LABEL_T:
+ msg = AddHotkeyName( _( "Edit Hierarchical Label" ), g_Schematic_Hokeys_Descr,
+ HK_EDIT );
+ AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
+ PopMenu->AppendSeparator();
+ break;
+
+ case SCH_BITMAP_T:
+ msg = AddHotkeyName( _( "Edit Image" ), g_Schematic_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( image_xpm ) );
+ PopMenu->AppendSeparator();
+ break;
+
+ default:
+ break;
+ }
+ }
+ return true;
+ }
+
+ // Try to locate items at cursor position.
+ if( (item == NULL) || (item->GetFlags() == 0) )
+ {
+ item = LocateAndShowItem( aPosition, SCH_COLLECTOR::AllItemsButPins );
+
+ // If the clarify item selection context menu is aborted, don't show the context menu.
+ if( item == NULL && m_canvas->GetAbortRequest() )
+ {
+ m_canvas->SetAbortRequest( false );
+ return false;
+ }
+ }
+
+ // If a command is in progress: add "cancel" and "end tool" menu
+ // If
+ if( GetToolId() != ID_NO_TOOL_SELECTED )
+ {
+ if( item && item->GetFlags() )
+ {
+ AddMenuItem( PopMenu, ID_CANCEL_CURRENT_COMMAND, _( "Cancel" ),
+ KiBitmap( cancel_xpm ) );
+ }
+ else
+ {
+ AddMenuItem( PopMenu, ID_CANCEL_CURRENT_COMMAND, _( "End Tool" ),
+ KiBitmap( cursor_xpm ) );
+ }
+
+ PopMenu->AppendSeparator();
+
+ switch( GetToolId() )
+ {
+ case ID_WIRE_BUTT:
+ AddMenusForWire( PopMenu, NULL, this );
+ if( item == NULL )
+ PopMenu->AppendSeparator();
+ break;
+
+ case ID_BUS_BUTT:
+ AddMenusForBus( PopMenu, NULL, this );
+ if( item == NULL )
+ PopMenu->AppendSeparator();
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ if( item && item->GetFlags() )
+ {
+ AddMenuItem( PopMenu, ID_CANCEL_CURRENT_COMMAND, _( "Cancel" ),
+ KiBitmap( cancel_xpm ) );
+ PopMenu->AppendSeparator();
+ }
+ }
+
+ if( item == NULL )
+ {
+ if( m_CurrentSheet->Last() != g_RootSheet )
+ {
+ msg = AddHotkeyName( _( "Leave Sheet" ), g_Schematic_Hokeys_Descr, HK_LEAVE_SHEET );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_LEAVE_SHEET, msg,
+ KiBitmap( leave_sheet_xpm ) );
+ PopMenu->AppendSeparator();
+ }
+ return true;
+ }
+
+ bool is_new = item->IsNew();
+
+ switch( item->Type() )
+ {
+ case SCH_NO_CONNECT_T:
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, _( "Delete No Connect" ),
+ KiBitmap( delete_xpm ) );
+ break;
+
+ case SCH_JUNCTION_T:
+ addJunctionMenuEntries( PopMenu, (SCH_JUNCTION*) item );
+ break;
+
+ case SCH_BUS_BUS_ENTRY_T:
+ case SCH_BUS_WIRE_ENTRY_T:
+ AddMenusForBusEntry( PopMenu, static_cast<SCH_BUS_ENTRY_BASE*>( item ) );
+ break;
+
+ case SCH_MARKER_T:
+ AddMenusForMarkers( PopMenu, (SCH_MARKER*) item, this );
+ break;
+
+ case SCH_TEXT_T:
+ AddMenusForText( PopMenu, (SCH_TEXT*) item );
+ break;
+
+ case SCH_LABEL_T:
+ AddMenusForLabel( PopMenu, (SCH_LABEL*) item );
+ break;
+
+ case SCH_GLOBAL_LABEL_T:
+ AddMenusForGLabel( PopMenu, (SCH_GLOBALLABEL*) item );
+ break;
+
+ case SCH_HIERARCHICAL_LABEL_T:
+ AddMenusForHLabel( PopMenu, (SCH_HIERLABEL*) item );
+ break;
+
+ case SCH_FIELD_T:
+ AddMenusForComponentField( PopMenu, (SCH_FIELD*) item );
+ break;
+
+ case SCH_COMPONENT_T:
+ AddMenusForComponent( PopMenu, (SCH_COMPONENT*) item, Prj().SchLibs() );
+ break;
+
+ case SCH_BITMAP_T:
+ AddMenusForBitmap( PopMenu, (SCH_BITMAP*) item );
+ break;
+
+ case SCH_LINE_T:
+ switch( item->GetLayer() )
+ {
+ case LAYER_WIRE:
+ AddMenusForWire( PopMenu, (SCH_LINE*) item, this );
+ break;
+
+ case LAYER_BUS:
+ AddMenusForBus( PopMenu, (SCH_LINE*) item, this );
+ break;
+
+ default:
+ if( is_new )
+ AddMenuItem( PopMenu, ID_POPUP_END_LINE, _( "End Drawing" ),
+ KiBitmap( checked_ok_xpm ) );
+
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, _( "Delete Drawing" ),
+ KiBitmap( delete_xpm ) );
+ break;
+ }
+ break;
+
+ case SCH_SHEET_T:
+ AddMenusForHierchicalSheet( PopMenu, (SCH_SHEET*) item );
+ break;
+
+ case SCH_SHEET_PIN_T:
+ AddMenusForSheetPin( PopMenu, (SCH_SHEET_PIN*) item );
+ break;
+
+ default:
+ wxFAIL_MSG( wxString::Format( wxT( "Cannot create context menu for unknown type %d" ),
+ item->Type() ) );
+ break;
+ }
+
+ PopMenu->AppendSeparator();
+ return true;
+}
+
+
+void AddMenusForComponentField( wxMenu* PopMenu, SCH_FIELD* Field )
+{
+ wxString msg, name;
+
+ if( !Field->GetFlags() )
+ {
+ switch( Field->GetId() )
+ {
+ case REFERENCE: name = _( "Move Reference" ); break;
+ case VALUE: name = _( "Move Value" ); break;
+ case FOOTPRINT: name = _( "Move Footprint Field" ); break;
+ default: name = _( "Move Field" ); break;
+ }
+
+ msg = AddHotkeyName( name, g_Schematic_Hokeys_Descr,
+ HK_MOVE_COMPONENT_OR_ITEM );
+ AddMenuItem( PopMenu, ID_SCH_MOVE_ITEM, msg, KiBitmap( move_text_xpm ) );
+ }
+
+ switch( Field->GetId() )
+ {
+ case REFERENCE: name = _( "Rotate Reference" ); break;
+ case VALUE: name = _( "Rotate Value" ); break;
+ case FOOTPRINT: name = _( "Rotate Footprint Field" ); break;
+ default: name = _( "Rotate Field" ); break;
+ }
+
+ msg = AddHotkeyName( name, g_Schematic_Hokeys_Descr, HK_ROTATE );
+ AddMenuItem( PopMenu, ID_SCH_ROTATE_CLOCKWISE, msg, KiBitmap( rotate_field_xpm ) );
+
+ // Ref, value and footprint have specific hotkeys. Show the specific hotkey:
+ hotkey_id_commnand id;
+ switch( Field->GetId() )
+ {
+ case REFERENCE:
+ id = HK_EDIT_COMPONENT_REFERENCE;
+ name = _( "Edit Reference" );
+ break;
+ case VALUE:
+ id = HK_EDIT_COMPONENT_VALUE;
+ name = _( "Edit Value" );
+ break;
+ case FOOTPRINT:
+ id = HK_EDIT_COMPONENT_FOOTPRINT;
+ name = _( "Edit Footprint Field" );
+ break;
+ default:
+ id = HK_EDIT;
+ name = _( "Edit Field" );
+ break;
+ }
+ msg = AddHotkeyName( name, g_Schematic_Hokeys_Descr, id );
+ AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
+}
+
+
+void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* aLibs )
+{
+ if( Component->Type() != SCH_COMPONENT_T )
+ {
+ wxASSERT( 0 );
+ return;
+ }
+
+ wxString msg;
+ LIB_ALIAS* libEntry = aLibs->FindLibraryEntry( Component->GetPartName() );
+
+ if( !Component->GetFlags() )
+ {
+ msg.Printf( _( "Move Component %s" ),
+ GetChars( Component->GetField( REFERENCE )->GetText() ) );
+ msg = AddHotkeyName( msg, g_Schematic_Hokeys_Descr, HK_MOVE_COMPONENT_OR_ITEM );
+ AddMenuItem( PopMenu, ID_SCH_MOVE_ITEM, msg, KiBitmap( move_xpm ) );
+ msg = AddHotkeyName( _( "Drag Component" ), g_Schematic_Hokeys_Descr, HK_DRAG );
+ AddMenuItem( PopMenu, ID_SCH_DRAG_ITEM, msg, KiBitmap( move_xpm ) );
+ }
+
+ wxMenu* orientmenu = new wxMenu;
+ msg = AddHotkeyName( _( "Rotate Clockwise" ), g_Schematic_Hokeys_Descr, HK_ROTATE );
+ AddMenuItem( orientmenu, ID_SCH_ROTATE_CLOCKWISE, msg, KiBitmap( rotate_cw_xpm ) );
+ AddMenuItem( orientmenu, ID_SCH_ROTATE_COUNTERCLOCKWISE, _( "Rotate Counterclockwise" ),
+ KiBitmap( rotate_ccw_xpm ) );
+ msg = AddHotkeyName( _( "Mirror --" ), g_Schematic_Hokeys_Descr, HK_MIRROR_X );
+ AddMenuItem( orientmenu, ID_SCH_MIRROR_X, msg, KiBitmap( mirror_v_xpm ) );
+ msg = AddHotkeyName( _( "Mirror ||" ), g_Schematic_Hokeys_Descr, HK_MIRROR_Y );
+ AddMenuItem( orientmenu, ID_SCH_MIRROR_Y, msg, KiBitmap( mirror_h_xpm ) );
+ msg = AddHotkeyName( _( "Normal" ), g_Schematic_Hokeys_Descr, HK_ORIENT_NORMAL_COMPONENT );
+ AddMenuItem( orientmenu, ID_SCH_ORIENT_NORMAL, msg, KiBitmap( normal_xpm ) );
+ AddMenuItem( PopMenu, orientmenu, ID_POPUP_SCH_GENERIC_ORIENT_CMP,
+ _( "Orient Component" ), KiBitmap( orient_xpm ) );
+
+ AddMenusForEditComponent( PopMenu, Component, aLibs );
+
+ if( !Component->GetFlags() )
+ {
+ msg = AddHotkeyName( _( "Copy Component" ), g_Schematic_Hokeys_Descr,
+ HK_COPY_COMPONENT_OR_LABEL );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_COPY_ITEM, msg, KiBitmap( copy_button_xpm ) );
+ msg = AddHotkeyName( _( "Delete Component" ), g_Schematic_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE_CMP, msg, KiBitmap( delete_xpm ) );
+ }
+
+ if( libEntry && !libEntry->GetDocFileName().IsEmpty() )
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DISPLAYDOC_CMP, _( "Doc" ), KiBitmap( datasheet_xpm ) );
+}
+
+
+void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* aLibs )
+{
+ if( Component->Type() != SCH_COMPONENT_T )
+ {
+ wxASSERT( 0 );
+ return;
+ }
+
+ wxString msg;
+ LIB_PART* part = NULL;
+ LIB_ALIAS* libEntry = aLibs->FindLibraryEntry( Component->GetPartName() );
+
+ if( libEntry )
+ part = libEntry->GetPart();
+
+ wxMenu* editmenu = new wxMenu;
+ msg = AddHotkeyName( _( "Edit" ), g_Schematic_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( editmenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_component_xpm ) );
+
+ if( part && part->IsNormal() )
+ {
+ msg = AddHotkeyName( _( "Value" ), g_Schematic_Hokeys_Descr,
+ HK_EDIT_COMPONENT_VALUE );
+ AddMenuItem( editmenu, ID_SCH_EDIT_COMPONENT_VALUE, msg,
+ KiBitmap( edit_comp_value_xpm ) );
+
+ msg = AddHotkeyName( _( "Reference" ), g_Schematic_Hokeys_Descr,
+ HK_EDIT_COMPONENT_REFERENCE );
+ AddMenuItem( editmenu, ID_SCH_EDIT_COMPONENT_REFERENCE, msg,
+ KiBitmap( edit_comp_ref_xpm ) );
+
+ msg = AddHotkeyName( _( "Footprint" ), g_Schematic_Hokeys_Descr,
+ HK_EDIT_COMPONENT_FOOTPRINT );
+ AddMenuItem( editmenu, ID_SCH_EDIT_COMPONENT_FOOTPRINT, msg,
+ KiBitmap( edit_comp_footprint_xpm ) );
+ }
+
+ if( part && part->HasConversion() )
+ AddMenuItem( editmenu, ID_POPUP_SCH_EDIT_CONVERT_CMP, _( "Convert" ),
+ KiBitmap( component_select_alternate_shape_xpm ) );
+
+ if( part && part->GetUnitCount() >= 2 )
+ {
+ wxMenu* sel_unit_menu = new wxMenu; int ii;
+
+ for( ii = 0; ii < part->GetUnitCount(); ii++ )
+ {
+ wxString num_unit;
+ int unit = Component->GetUnit();
+ num_unit.Printf( _( "Unit %s" ), GetChars( LIB_PART::SubReference( ii + 1, false ) ) );
+ wxMenuItem * item = sel_unit_menu->Append( ID_POPUP_SCH_SELECT_UNIT1 + ii,
+ num_unit, wxEmptyString,
+ wxITEM_CHECK );
+ if( unit == ii + 1 )
+ item->Check(true);
+
+ // The ID max for these submenus is ID_POPUP_SCH_SELECT_UNIT_CMP_MAX
+ // See eeschema_id to modify this value.
+ if( ii >= (ID_POPUP_SCH_SELECT_UNIT_CMP_MAX - ID_POPUP_SCH_SELECT_UNIT1) )
+ break; // We have used all IDs for these submenus
+ }
+
+ AddMenuItem( editmenu, sel_unit_menu, ID_POPUP_SCH_SELECT_UNIT_CMP,
+ _( "Unit" ), KiBitmap( component_select_unit_xpm ) );
+ }
+
+ if( !Component->GetFlags() )
+ {
+ msg = AddHotkeyName( _( "Edit with Library Editor" ), g_Schematic_Hokeys_Descr,
+ HK_EDIT_COMPONENT_WITH_LIBEDIT );
+ AddMenuItem( editmenu, ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP,
+ msg, KiBitmap( libedit_xpm ) );
+ }
+
+ AddMenuItem( PopMenu, editmenu, ID_SCH_EDIT_ITEM,
+ _( "Edit Component" ), KiBitmap( edit_component_xpm ) );
+}
+
+
+void AddMenusForGLabel( wxMenu* PopMenu, SCH_GLOBALLABEL* GLabel )
+{
+ wxMenu* menu_change_type = new wxMenu;
+ wxString msg;
+
+ if( !GLabel->GetFlags() )
+ {
+ msg = AddHotkeyName( _( "Move Global Label" ), g_Schematic_Hokeys_Descr,
+ HK_MOVE_COMPONENT_OR_ITEM );
+ AddMenuItem( PopMenu, ID_SCH_MOVE_ITEM, msg, KiBitmap( move_text_xpm ) );
+ msg = AddHotkeyName( _( "Drag Global Label" ), g_Schematic_Hokeys_Descr,
+ HK_DRAG );
+ AddMenuItem( PopMenu, ID_SCH_DRAG_ITEM, msg, KiBitmap( move_text_xpm ) );
+ msg = AddHotkeyName( _( "Copy Global Label" ), g_Schematic_Hokeys_Descr,
+ HK_COPY_COMPONENT_OR_LABEL );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_COPY_ITEM, msg, KiBitmap( copy_button_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Rotate Global Label" ), g_Schematic_Hokeys_Descr, HK_ROTATE );
+ AddMenuItem( PopMenu, ID_SCH_ROTATE_CLOCKWISE, msg, KiBitmap( rotate_glabel_xpm ) );
+ msg = AddHotkeyName( _( "Edit Global Label" ), g_Schematic_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
+ msg = AddHotkeyName( _( "Delete Global Label" ), g_Schematic_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, msg, KiBitmap( delete_text_xpm ) );
+
+ // add menu change type text (to label, glabel, text):
+ AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_HLABEL,
+ _( "Change to Hierarchical Label" ), KiBitmap( label2glabel_xpm ) );
+ AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_LABEL,
+ _( "Change to Label" ), KiBitmap( glabel2label_xpm ) );
+ AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT,
+ _( "Change to Text" ), KiBitmap( glabel2text_xpm ) );
+ AddMenuItem( PopMenu, menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT,
+ _( "Change Type" ), KiBitmap( gl_change_xpm ) );
+}
+
+
+void AddMenusForHLabel( wxMenu* PopMenu, SCH_HIERLABEL* HLabel )
+{
+ wxMenu* menu_change_type = new wxMenu;
+ wxString msg;
+
+ if( !HLabel->GetFlags() )
+ {
+ msg = AddHotkeyName( _( "Move Hierarchical Label" ), g_Schematic_Hokeys_Descr,
+ HK_MOVE_COMPONENT_OR_ITEM );
+ AddMenuItem( PopMenu, ID_SCH_MOVE_ITEM, msg, KiBitmap( move_text_xpm ) );
+ msg = AddHotkeyName( _( "Drag Hierarchical Label" ), g_Schematic_Hokeys_Descr, HK_DRAG );
+ AddMenuItem( PopMenu, ID_SCH_DRAG_ITEM, msg, KiBitmap( move_text_xpm ) );
+ msg = AddHotkeyName( _( "Copy Hierarchical Label" ), g_Schematic_Hokeys_Descr,
+ HK_COPY_COMPONENT_OR_LABEL );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_COPY_ITEM, msg, KiBitmap( copy_button_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Rotate Hierarchical Label" ), g_Schematic_Hokeys_Descr, HK_ROTATE );
+ AddMenuItem( PopMenu, ID_SCH_ROTATE_CLOCKWISE, msg, KiBitmap( rotate_glabel_xpm ) );
+ msg = AddHotkeyName( _( "Edit Hierarchical Label" ), g_Schematic_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
+ msg = AddHotkeyName( _( "Delete Hierarchical Label" ), g_Schematic_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, msg, KiBitmap( delete_text_xpm ) );
+
+ // add menu change type text (to label, glabel, text):
+ AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_LABEL,
+ _( "Change to Label" ), KiBitmap( glabel2label_xpm ) );
+ AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT,
+ _( "Change to Text" ), KiBitmap( glabel2text_xpm ) );
+ AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_GLABEL,
+ _( "Change to Global Label" ), KiBitmap( label2glabel_xpm ) );
+ AddMenuItem( PopMenu, menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT,
+ _( "Change Type" ), KiBitmap( gl_change_xpm ) );
+}
+
+
+void AddMenusForLabel( wxMenu* PopMenu, SCH_LABEL* Label )
+{
+ wxMenu* menu_change_type = new wxMenu;
+ wxString msg;
+
+ if( !Label->GetFlags() )
+ {
+ msg = AddHotkeyName( _( "Move Label" ), g_Schematic_Hokeys_Descr,
+ HK_MOVE_COMPONENT_OR_ITEM );
+ AddMenuItem( PopMenu, ID_SCH_MOVE_ITEM, msg, KiBitmap( move_text_xpm ) );
+ msg = AddHotkeyName( _( "Drag Label" ), g_Schematic_Hokeys_Descr, HK_DRAG );
+ AddMenuItem( PopMenu, ID_SCH_DRAG_ITEM, msg, KiBitmap( move_text_xpm ) );
+ msg = AddHotkeyName( _( "Copy Label" ), g_Schematic_Hokeys_Descr,
+ HK_COPY_COMPONENT_OR_LABEL );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_COPY_ITEM, msg, KiBitmap( copy_button_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Rotate Label" ), g_Schematic_Hokeys_Descr, HK_ROTATE );
+ AddMenuItem( PopMenu, ID_SCH_ROTATE_CLOCKWISE, msg, KiBitmap( rotate_ccw_xpm ) );
+ msg = AddHotkeyName( _( "Edit Label" ), g_Schematic_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
+ msg = AddHotkeyName( _( "Delete Label" ), g_Schematic_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, msg, KiBitmap( delete_text_xpm ) );
+
+ // add menu change type text (to label, glabel, text):
+ AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_HLABEL,
+ _( "Change to Hierarchical Label" ), KiBitmap( label2glabel_xpm ) );
+ AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT,
+ _( "Change to Text" ), KiBitmap( label2text_xpm ) );
+ AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_GLABEL,
+ _( "Change to Global Label" ), KiBitmap( label2glabel_xpm ) );
+ AddMenuItem( PopMenu, menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT,
+ _( "Change Type" ), KiBitmap( gl_change_xpm ) );
+}
+
+
+void AddMenusForText( wxMenu* PopMenu, SCH_TEXT* Text )
+{
+ wxString msg;
+ wxMenu* menu_change_type = new wxMenu;
+
+ if( !Text->GetFlags() )
+ {
+ msg = AddHotkeyName( _( "Move Text" ), g_Schematic_Hokeys_Descr,
+ HK_MOVE_COMPONENT_OR_ITEM );
+ AddMenuItem( PopMenu, ID_SCH_MOVE_ITEM, msg, KiBitmap( move_text_xpm ) );
+ msg = AddHotkeyName( _( "Copy Text" ), g_Schematic_Hokeys_Descr,
+ HK_COPY_COMPONENT_OR_LABEL );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_COPY_ITEM, msg, KiBitmap( copy_button_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Rotate Text" ), g_Schematic_Hokeys_Descr, HK_ROTATE );
+ AddMenuItem( PopMenu, ID_SCH_ROTATE_CLOCKWISE, msg, KiBitmap( rotate_ccw_xpm ) );
+ msg = AddHotkeyName( _( "Edit Text" ), g_Schematic_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) );
+ msg = AddHotkeyName( _( "Delete Text" ), g_Schematic_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, msg, KiBitmap( delete_text_xpm ) );
+
+ /* add menu change type text (to label, glabel, text),
+ * but only if this is a single line text
+ */
+ if( Text->GetText().Find( wxT( "\n" ) ) == wxNOT_FOUND )
+ {
+ AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_LABEL,
+ _( "Change to Label" ), KiBitmap( label2text_xpm ) );
+ AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_HLABEL,
+ _( "Change to Hierarchical Label" ), KiBitmap( label2glabel_xpm ) );
+ AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_GLABEL,
+ _( "Change to Global Label" ), KiBitmap( label2glabel_xpm ) );
+ AddMenuItem( PopMenu, menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT,
+ _( "Change Type" ), KiBitmap( gl_change_xpm ) );
+ }
+}
+
+
+void SCH_EDIT_FRAME::addJunctionMenuEntries( wxMenu* aMenu, SCH_JUNCTION* aJunction )
+{
+ wxString msg;
+ SCH_SCREEN* screen = GetScreen();
+
+ msg = AddHotkeyName( _( "Delete Junction" ), g_Schematic_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( aMenu, ID_POPUP_SCH_DELETE, msg, KiBitmap( delete_xpm ) );
+
+ if( !aJunction->IsNew() )
+ {
+ if( m_collectedItems.IsDraggableJunction() )
+ AddMenuItem( aMenu, ID_SCH_DRAG_ITEM, _( "Drag Junction" ), KiBitmap( move_xpm ) );
+
+ if( screen->GetWire( aJunction->GetPosition(), EXCLUDE_END_POINTS_T ) )
+ AddMenuItem( aMenu, ID_POPUP_SCH_BREAK_WIRE, _( "Break Wire" ),
+ KiBitmap( break_line_xpm ) );
+ }
+
+ if( screen->GetWireOrBus( aJunction->GetPosition() ) )
+ {
+ AddMenuItem( aMenu, ID_POPUP_SCH_DELETE_NODE, _( "Delete Node" ),
+ KiBitmap( delete_node_xpm ) );
+ AddMenuItem( aMenu, ID_POPUP_SCH_DELETE_CONNECTION, _( "Delete Connection" ),
+ KiBitmap( delete_connection_xpm ) );
+ }
+}
+
+
+void AddMenusForWire( wxMenu* PopMenu, SCH_LINE* Wire, SCH_EDIT_FRAME* frame )
+{
+ SCH_SCREEN* screen = frame->GetScreen();
+ wxPoint pos = frame->GetCrossHairPosition();
+ wxString msg;
+
+ if( Wire == NULL )
+ {
+ msg = AddHotkeyName( _( "Begin Wire" ), g_Schematic_Hokeys_Descr, HK_BEGIN_WIRE );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_BEGIN_WIRE, msg, KiBitmap( add_line_xpm ) );
+ return;
+ }
+
+ bool is_new = Wire->IsNew();
+ if( is_new )
+ {
+ msg = AddHotkeyName( _( "Wire End" ), g_Schematic_Hokeys_Descr, HK_END_CURR_LINEWIREBUS );
+ AddMenuItem( PopMenu, ID_POPUP_END_LINE, msg, KiBitmap( checked_ok_xpm ) );
+ return;
+ }
+
+ msg = AddHotkeyName( _( "Drag Wire" ), g_Schematic_Hokeys_Descr, HK_DRAG );
+ AddMenuItem( PopMenu, ID_SCH_DRAG_ITEM, msg, KiBitmap( move_track_xpm ) );
+ PopMenu->AppendSeparator();
+ msg = AddHotkeyName( _( "Delete Wire" ), g_Schematic_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, msg, KiBitmap( delete_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE_NODE, _( "Delete Node" ),
+ KiBitmap( delete_node_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE_CONNECTION, _( "Delete Connection" ),
+ KiBitmap( delete_connection_xpm ) );
+
+ SCH_LINE* line = screen->GetWireOrBus( frame->GetCrossHairPosition() );
+
+ if( line && !line->IsEndPoint( frame->GetCrossHairPosition() ) )
+ AddMenuItem( PopMenu, ID_POPUP_SCH_BREAK_WIRE, _( "Break Wire" ),
+ KiBitmap( break_line_xpm ) );
+
+ PopMenu->AppendSeparator();
+
+ msg = AddHotkeyName( _( "Add Junction" ), g_Schematic_Hokeys_Descr, HK_ADD_JUNCTION );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_ADD_JUNCTION, msg, KiBitmap( add_junction_xpm ) );
+ msg = AddHotkeyName( _( "Add Label" ), g_Schematic_Hokeys_Descr, HK_ADD_LABEL );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_ADD_LABEL, msg, KiBitmap( add_line_label_xpm ) );
+
+ // Add global label command only if the cursor is over one end of the wire.
+ if( Wire->IsEndPoint( pos ) )
+ AddMenuItem( PopMenu, ID_POPUP_SCH_ADD_GLABEL, _( "Add Global Label" ),
+ KiBitmap( add_glabel_xpm ) );
+}
+
+
+void AddMenusForBus( wxMenu* PopMenu, SCH_LINE* Bus, SCH_EDIT_FRAME* frame )
+{
+ wxPoint pos = frame->GetCrossHairPosition();
+ wxString msg;
+
+ if( Bus == NULL )
+ {
+ msg = AddHotkeyName( _( "Begin Bus" ), g_Schematic_Hokeys_Descr, HK_BEGIN_BUS );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_BEGIN_BUS, msg, KiBitmap( add_bus_xpm ) );
+ return;
+ }
+
+ bool is_new = Bus->IsNew();
+ if( is_new )
+ {
+ msg = AddHotkeyName( _( "Bus End" ), g_Schematic_Hokeys_Descr, HK_END_CURR_LINEWIREBUS );
+ AddMenuItem( PopMenu, ID_POPUP_END_LINE, msg, KiBitmap( checked_ok_xpm ) );
+ return;
+ }
+
+ msg = AddHotkeyName( _( "Delete Bus" ), g_Schematic_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, msg, KiBitmap( delete_bus_xpm ) );
+
+ AddMenuItem( PopMenu, ID_POPUP_SCH_BREAK_WIRE, _( "Break Bus" ), KiBitmap( break_bus_xpm ) );
+
+ PopMenu->AppendSeparator();
+ msg = AddHotkeyName( _( "Add Junction" ), g_Schematic_Hokeys_Descr, HK_ADD_JUNCTION );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_ADD_JUNCTION, msg, KiBitmap( add_junction_xpm ) );
+ msg = AddHotkeyName( _( "Add Label" ), g_Schematic_Hokeys_Descr, HK_ADD_LABEL );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_ADD_LABEL, msg, KiBitmap( add_line_label_xpm ) );
+
+ // Add global label command only if the cursor is over one end of the bus.
+ if( Bus->IsEndPoint( pos ) )
+ AddMenuItem( PopMenu, ID_POPUP_SCH_ADD_GLABEL, _( "Add Global Label" ),
+ KiBitmap( add_glabel_xpm ) );
+}
+
+
+void AddMenusForHierchicalSheet( wxMenu* PopMenu, SCH_SHEET* Sheet )
+{
+ wxString msg;
+
+ if( !Sheet->GetFlags() )
+ {
+ AddMenuItem( PopMenu, ID_POPUP_SCH_ENTER_SHEET, _( "Enter Sheet" ),
+ KiBitmap( enter_sheet_xpm ) );
+ PopMenu->AppendSeparator();
+ msg = AddHotkeyName( _( "Move Sheet" ), g_Schematic_Hokeys_Descr,
+ HK_MOVE_COMPONENT_OR_ITEM );
+ AddMenuItem( PopMenu, ID_SCH_MOVE_ITEM, msg, KiBitmap( move_sheet_xpm ) );
+
+ msg = AddHotkeyName( _( "Drag Sheet" ), g_Schematic_Hokeys_Descr, HK_DRAG );
+ AddMenuItem( PopMenu, ID_SCH_DRAG_ITEM, msg, KiBitmap( move_sheet_xpm ) );
+
+ wxMenu* orientmenu = new wxMenu;
+ msg = AddHotkeyName( _( "Rotate Sheet CW" ), g_Schematic_Hokeys_Descr, HK_ROTATE );
+ AddMenuItem( orientmenu, ID_SCH_ROTATE_CLOCKWISE, msg, KiBitmap( rotate_cw_xpm ) );
+
+ AddMenuItem( orientmenu, ID_SCH_ROTATE_COUNTERCLOCKWISE, _( "Rotate Sheet CCW" ),
+ KiBitmap( rotate_ccw_xpm ) );
+
+ msg = AddHotkeyName( _( "Mirror --" ), g_Schematic_Hokeys_Descr, HK_MIRROR_X );
+ AddMenuItem( orientmenu, ID_SCH_MIRROR_X, msg, KiBitmap( mirror_v_xpm ) );
+ msg = AddHotkeyName( _( "Mirror ||" ), g_Schematic_Hokeys_Descr, HK_MIRROR_Y );
+ AddMenuItem( orientmenu, ID_SCH_MIRROR_Y, msg, KiBitmap( mirror_h_xpm ) );
+
+ AddMenuItem( PopMenu, orientmenu, ID_POPUP_SCH_GENERIC_ORIENT_CMP,
+ _( "Orient Sheet" ), KiBitmap( orient_xpm ) );
+ }
+
+ if( Sheet->GetFlags() )
+ {
+ AddMenuItem( PopMenu, ID_POPUP_SCH_END_SHEET, _( "Place Sheet" ), KiBitmap( checked_ok_xpm ) );
+ }
+ else
+ {
+ msg = AddHotkeyName( _( "Edit Sheet" ), g_Schematic_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_sheet_xpm ) );
+
+ AddMenuItem( PopMenu, ID_POPUP_SCH_RESIZE_SHEET, _( "Resize Sheet" ),
+ KiBitmap( resize_sheet_xpm ) );
+ PopMenu->AppendSeparator();
+ AddMenuItem( PopMenu, ID_POPUP_IMPORT_HLABEL_TO_SHEETPIN, _( "Import Sheet Pins" ),
+ KiBitmap( import_hierarchical_label_xpm ) );
+
+ if( Sheet->HasUndefinedPins() ) // Sheet has pin labels, and can be cleaned
+ AddMenuItem( PopMenu, ID_POPUP_SCH_CLEANUP_SHEET, _( "Cleanup Sheet Pins" ),
+ KiBitmap( options_pinsheet_xpm ) );
+
+ PopMenu->AppendSeparator();
+ msg = AddHotkeyName( _( "Delete Sheet" ), g_Schematic_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, msg, KiBitmap( delete_sheet_xpm ) );
+ }
+}
+
+
+void AddMenusForSheetPin( wxMenu* PopMenu, SCH_SHEET_PIN* PinSheet )
+{
+ wxString msg;
+
+ if( !PinSheet->GetFlags() )
+ {
+ msg = AddHotkeyName( _( "Move Sheet Pin" ), g_Schematic_Hokeys_Descr,
+ HK_MOVE_COMPONENT_OR_ITEM );
+ AddMenuItem( PopMenu, ID_SCH_MOVE_ITEM, msg, KiBitmap( move_xpm ) );
+ }
+
+ AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, _( "Edit Sheet Pin" ), KiBitmap( edit_xpm ) );
+
+ if( !PinSheet->GetFlags() )
+ AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, _( "Delete Sheet Pin" ),
+ KiBitmap( delete_pinsheet_xpm ) );
+}
+
+
+void AddMenusForBlock( wxMenu* PopMenu, SCH_EDIT_FRAME* frame )
+{
+ wxString msg;
+
+ AddMenuItem( PopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel Block" ),
+ KiBitmap( cancel_xpm ) );
+
+ PopMenu->AppendSeparator();
+
+ if( frame->GetScreen()->m_BlockLocate.GetCommand() == BLOCK_MOVE )
+ AddMenuItem( PopMenu, ID_POPUP_ZOOM_BLOCK, _( "Window Zoom" ), KiBitmap( zoom_area_xpm ) );
+
+ AddMenuItem( PopMenu, ID_POPUP_PLACE_BLOCK, _( "Place Block" ), KiBitmap( checked_ok_xpm ) );
+
+ // After a block move (that is also a block selection) one can reselect
+ // a block function.
+ if( frame->GetScreen()->m_BlockLocate.GetCommand() == BLOCK_MOVE )
+ {
+ msg = AddHotkeyName( _( "Save Block" ), g_Schematic_Hokeys_Descr,
+ HK_SAVE_BLOCK );
+ AddMenuItem( PopMenu, wxID_COPY, msg, KiBitmap( copy_button_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_COPY_BLOCK, _( "Copy Block" ), KiBitmap( copyblock_xpm ) );
+ msg = AddHotkeyName( _( "Drag Block" ), g_Schematic_Hokeys_Descr,
+ HK_MOVEBLOCK_TO_DRAGBLOCK );
+ AddMenuItem( PopMenu, ID_POPUP_DRAG_BLOCK, msg, KiBitmap( move_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_DELETE_BLOCK, _( "Delete Block" ), KiBitmap( delete_xpm ) );
+ msg = AddHotkeyName( _( "Mirror Block ||" ), g_Schematic_Hokeys_Descr,
+ HK_MIRROR_Y );
+ AddMenuItem( PopMenu, ID_SCH_MIRROR_Y, msg, KiBitmap( mirror_h_xpm ) );
+ msg = AddHotkeyName( _( "Mirror Block --" ), g_Schematic_Hokeys_Descr,
+ HK_MIRROR_X );
+ AddMenuItem( PopMenu, ID_SCH_MIRROR_X, msg, KiBitmap( mirror_v_xpm ) );
+ msg = AddHotkeyName( _( "Rotate Block CCW" ), g_Schematic_Hokeys_Descr, HK_ROTATE );
+ AddMenuItem( PopMenu, ID_SCH_ROTATE_CLOCKWISE, msg, KiBitmap( rotate_ccw_xpm ) );
+
+#if 0
+ #ifdef __WINDOWS__
+ AddMenuItem( menu_other_block_commands, ID_GEN_COPY_BLOCK_TO_CLIPBOARD,
+ _( "Copy to Clipboard" ), KiBitmap( copy_button_xpm ) );
+ #endif
+#endif
+ }
+}
+
+
+void AddMenusForMarkers( wxMenu* aPopMenu, SCH_MARKER* aMarker, SCH_EDIT_FRAME* aFrame )
+{
+ AddMenuItem( aPopMenu, ID_POPUP_SCH_DELETE, _( "Delete Marker" ), KiBitmap( delete_xpm ) );
+ AddMenuItem( aPopMenu, ID_POPUP_SCH_GETINFO_MARKER, _( "Marker Error Info" ),
+ KiBitmap( info_xpm ) );
+}
+
+
+void AddMenusForBitmap( wxMenu* aPopMenu, SCH_BITMAP * aBitmap )
+{
+ wxString msg;
+
+ if( aBitmap->GetFlags() == 0 )
+ {
+ msg = AddHotkeyName( _( "Move Image" ), g_Schematic_Hokeys_Descr,
+ HK_MOVE_COMPONENT_OR_ITEM );
+ AddMenuItem( aPopMenu, ID_SCH_MOVE_ITEM, msg, KiBitmap( move_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Rotate Image" ), g_Schematic_Hokeys_Descr, HK_ROTATE );
+ AddMenuItem( aPopMenu, ID_SCH_ROTATE_CLOCKWISE, msg, KiBitmap( rotate_ccw_xpm ) );
+ msg = AddHotkeyName( _( "Mirror --" ), g_Schematic_Hokeys_Descr,
+ HK_MIRROR_X );
+ AddMenuItem( aPopMenu, ID_SCH_MIRROR_X, msg, KiBitmap( mirror_v_xpm ) );
+ msg = AddHotkeyName( _( "Mirror ||" ), g_Schematic_Hokeys_Descr,
+ HK_MIRROR_Y );
+ AddMenuItem( aPopMenu, ID_SCH_MIRROR_Y, msg, KiBitmap( mirror_h_xpm ) );
+ msg = AddHotkeyName( _( "Edit Image" ), g_Schematic_Hokeys_Descr, HK_EDIT );
+ AddMenuItem( aPopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( image_xpm ) );
+
+ if( aBitmap->GetFlags() == 0 )
+ {
+ aPopMenu->AppendSeparator();
+ msg = AddHotkeyName( _( "Delete Image" ), g_Schematic_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( aPopMenu, ID_POPUP_SCH_DELETE, msg, KiBitmap( delete_xpm ) );
+ }
+}
+
+
+void AddMenusForBusEntry( wxMenu* aPopMenu, SCH_BUS_ENTRY_BASE* aBusEntry )
+{
+ wxString msg;
+
+ if( !aBusEntry->GetFlags() )
+ {
+ msg = AddHotkeyName( _( "Move Bus Entry" ), g_Schematic_Hokeys_Descr,
+ HK_MOVE_COMPONENT_OR_ITEM );
+ AddMenuItem( aPopMenu, ID_SCH_MOVE_ITEM, msg, KiBitmap( move_xpm ) );
+ }
+
+ if( aBusEntry->GetBusEntryShape() == '\\' )
+ AddMenuItem( aPopMenu, ID_POPUP_SCH_ENTRY_SELECT_SLASH,
+ _( "Set Bus Entry Shape /" ), KiBitmap( change_entry_orient_xpm ) );
+ else
+ AddMenuItem( aPopMenu, ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH,
+ _( "Set Bus Entry Shape \\" ), KiBitmap( change_entry_orient_xpm ) );
+
+ msg = AddHotkeyName( _( "Delete Bus Entry" ), g_Schematic_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( aPopMenu, ID_POPUP_SCH_DELETE, msg, KiBitmap( delete_xpm ) );
+}
diff --git a/eeschema/operations_on_items_lists.cpp b/eeschema/operations_on_items_lists.cpp
new file mode 100644
index 0000000..89346b1
--- /dev/null
+++ b/eeschema/operations_on_items_lists.cpp
@@ -0,0 +1,264 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file operations_on_items_lists.cpp
+ * @brief Functions used in block commands, or undo/redo, to move, mirror, delete, copy ...
+ * lists of schematic items.
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <schframe.h>
+
+#include <general.h>
+#include <protos.h>
+#include <sch_bus_entry.h>
+#include <sch_marker.h>
+#include <sch_line.h>
+#include <sch_no_connect.h>
+#include <sch_sheet.h>
+#include <sch_component.h>
+#include <sch_junction.h>
+
+
+void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen )
+{
+ switch( Struct->Type() )
+ {
+ case SCH_JUNCTION_T:
+ case SCH_TEXT_T:
+ case SCH_LABEL_T:
+ case SCH_GLOBAL_LABEL_T:
+ case SCH_HIERARCHICAL_LABEL_T:
+ case SCH_COMPONENT_T:
+ case SCH_LINE_T:
+ case SCH_BUS_BUS_ENTRY_T:
+ case SCH_BUS_WIRE_ENTRY_T:
+ case SCH_SHEET_T:
+ case SCH_MARKER_T:
+ case SCH_NO_CONNECT_T:
+ Struct->SetParent( Screen );
+ break;
+
+ case SCH_SHEET_PIN_T:
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& rotationPoint )
+{
+ for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
+ {
+ SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
+ item->Rotate( rotationPoint ); // Place it in its new position.
+ item->ClearFlags();
+ }
+}
+
+
+void MirrorY( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint )
+{
+ for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
+ {
+ SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
+ item->MirrorY( aMirrorPoint.x ); // Place it in its new position.
+ item->ClearFlags();
+ }
+}
+
+
+void MirrorX( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint )
+{
+ for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
+ {
+ SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
+ item->MirrorX( aMirrorPoint.y ); // Place it in its new position.
+ item->ClearFlags();
+ }
+}
+
+
+/**
+ * Function MoveItemsInList
+ * Move a list of items to a given move vector
+ * @param aItemsList = list of picked items
+ * @param aMoveVector = the move vector value
+ */
+void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint aMoveVector )
+{
+ for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
+ {
+ SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
+ item->Move( aMoveVector );
+ }
+}
+
+
+/**
+ * Function DeleteItemsInList
+ * delete schematic items in aItemsList
+ * deleted items are put in undo list
+ */
+void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList )
+{
+ SCH_SCREEN* screen = (SCH_SCREEN*) panel->GetScreen();
+ SCH_EDIT_FRAME* frame = (SCH_EDIT_FRAME*) panel->GetParent();
+ PICKED_ITEMS_LIST itemsList;
+
+ for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
+ {
+ SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
+ ITEM_PICKER itemWrapper( item, UR_DELETED );
+
+ if( item->Type() == SCH_SHEET_PIN_T )
+ {
+ /* this item is depending on a sheet, and is not in global list */
+ wxMessageBox( wxT( "DeleteItemsInList() err: unexpected SCH_SHEET_PIN_T" ) );
+ }
+ else
+ {
+ screen->Remove( item );
+
+ /* Unlink the structure */
+ itemsList.PushItem( itemWrapper );
+ }
+ }
+
+ frame->SaveCopyInUndoList( itemsList, UR_DELETED );
+}
+
+
+void SCH_EDIT_FRAME::DeleteItem( SCH_ITEM* aItem )
+{
+ wxCHECK_RET( aItem != NULL, wxT( "Cannot delete invalid item." ) );
+
+ // Here, aItem is not null.
+
+ SCH_SCREEN* screen = GetScreen();
+
+ if( aItem->Type() == SCH_SHEET_PIN_T )
+ {
+ // This iten is attached to a node, and is not accessible by the global list directly.
+ SCH_SHEET* sheet = (SCH_SHEET*) aItem->GetParent();
+ wxCHECK_RET( (sheet != NULL) && (sheet->Type() == SCH_SHEET_T),
+ wxT( "Sheet label has invalid parent item." ) );
+ SaveCopyInUndoList( (SCH_ITEM*) sheet, UR_CHANGED );
+ sheet->RemovePin( (SCH_SHEET_PIN*) aItem );
+ m_canvas->RefreshDrawingRect( sheet->GetBoundingBox() );
+ }
+ else
+ {
+ screen->Remove( aItem );
+ SaveCopyInUndoList( aItem, UR_DELETED );
+ m_canvas->RefreshDrawingRect( aItem->GetBoundingBox() );
+ }
+}
+
+
+/* Routine to copy a new entity of an object for each object in list and
+ * reposition it.
+ * Return the new created object list in aItemsList
+ */
+void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
+ const wxPoint aMoveVector )
+{
+ SCH_ITEM* newitem;
+
+ if( aItemsList.GetCount() == 0 )
+ return;
+
+ for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
+ {
+ newitem = DuplicateStruct( (SCH_ITEM*) aItemsList.GetPickedItem( ii ) );
+ aItemsList.SetPickedItem( newitem, ii );
+ aItemsList.SetPickedItemStatus( UR_NEW, ii );
+ {
+ switch( newitem->Type() )
+ {
+ case SCH_JUNCTION_T:
+ case SCH_LINE_T:
+ case SCH_BUS_BUS_ENTRY_T:
+ case SCH_BUS_WIRE_ENTRY_T:
+ case SCH_TEXT_T:
+ case SCH_LABEL_T:
+ case SCH_GLOBAL_LABEL_T:
+ case SCH_HIERARCHICAL_LABEL_T:
+ case SCH_SHEET_PIN_T:
+ case SCH_MARKER_T:
+ case SCH_NO_CONNECT_T:
+ default:
+ break;
+
+ case SCH_SHEET_T:
+ {
+ SCH_SHEET* sheet = (SCH_SHEET*) newitem;
+ sheet->SetTimeStamp( GetNewTimeStamp() );
+ break;
+ }
+
+ case SCH_COMPONENT_T:
+ ( (SCH_COMPONENT*) newitem )->SetTimeStamp( GetNewTimeStamp() );
+ ( (SCH_COMPONENT*) newitem )->ClearAnnotation( NULL );
+ break;
+ }
+
+ SetSchItemParent( newitem, screen );
+ screen->Append( newitem );
+ }
+ }
+
+ MoveItemsInList( aItemsList, aMoveVector );
+}
+
+
+/**
+ * Function DuplicateStruct
+ * Routine to create a new copy of given struct.
+ * The new object is not put in draw list (not linked)
+ * @param aDrawStruct = the SCH_ITEM to duplicate
+ * @param aClone (default = false)
+ * if true duplicate also some parameters that must be unique
+ * (timestamp and sheet name)
+ * aClone must be false. use true only is undo/redo duplications
+ */
+SCH_ITEM* DuplicateStruct( SCH_ITEM* aDrawStruct, bool aClone )
+{
+ wxCHECK_MSG( aDrawStruct != NULL, NULL,
+ wxT( "Cannot duplicate NULL schematic item! Bad programmer." ) );
+
+ SCH_ITEM* NewDrawStruct = (SCH_ITEM*) aDrawStruct->Clone();
+
+ if( aClone )
+ NewDrawStruct->SetTimeStamp( aDrawStruct->GetTimeStamp() );
+
+ NewDrawStruct->SetImage( aDrawStruct );
+
+ return NewDrawStruct;
+}
diff --git a/eeschema/pinedit.cpp b/eeschema/pinedit.cpp
new file mode 100644
index 0000000..1b44172
--- /dev/null
+++ b/eeschema/pinedit.cpp
@@ -0,0 +1,786 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pinedit.cpp
+ * @brief Eeschema pin edit code.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <class_sch_screen.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+#include <libeditframe.h>
+#include <eeschema_id.h>
+#include <class_libentry.h>
+#include <lib_pin.h>
+#include <general.h>
+
+#include <../common/dialogs/dialog_display_info_HTML_base.h>
+#include <dialog_lib_edit_pin.h>
+
+
+extern void IncrementLabelMember( wxString& name, int aIncrement );
+
+
+static void AbortPinMove( EDA_DRAW_PANEL* Panel, wxDC* DC );
+static void DrawMovePin( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPositon, bool aErase );
+
+
+static wxPoint OldPos;
+static wxPoint PinPreviousPos;
+static int LastPinType = PIN_INPUT;
+static int LastPinOrient = PIN_RIGHT;
+static int LastPinShape = NONE;
+static bool LastPinCommonConvert = false;
+static bool LastPinCommonUnit = false;
+static bool LastPinVisible = true;
+
+// The -1 is a non-valid value to trigger delayed initialization
+static int LastPinLength = -1;
+static int LastPinNameSize = -1;
+static int LastPinNumSize = -1;
+
+static int GetLastPinLength()
+{
+ if( LastPinLength == -1 )
+ LastPinLength = LIB_EDIT_FRAME::GetDefaultPinLength();
+
+ return LastPinLength;
+}
+
+static int GetLastPinNameSize()
+{
+ if( LastPinNameSize == -1 )
+ LastPinNameSize = LIB_EDIT_FRAME::GetPinNameDefaultSize();
+
+ return LastPinNameSize;
+}
+
+static int GetLastPinNumSize()
+{
+ if( LastPinNumSize == -1 )
+ LastPinNumSize = LIB_EDIT_FRAME::GetPinNumDefaultSize();
+
+ return LastPinNumSize;
+}
+
+void LIB_EDIT_FRAME::OnEditPin( wxCommandEvent& event )
+{
+ if( m_drawItem == NULL || m_drawItem->Type() != LIB_PIN_T )
+ return;
+
+ STATUS_FLAGS item_flags = m_drawItem->GetFlags(); // save flags to restore them after editing
+ LIB_PIN* pin = (LIB_PIN*) m_drawItem;
+
+ DIALOG_LIB_EDIT_PIN dlg( this, pin );
+
+ wxString units = GetUnitsLabel( g_UserUnit );
+ dlg.SetOrientationList( LIB_PIN::GetOrientationNames(), LIB_PIN::GetOrientationSymbols() );
+ dlg.SetOrientation( LIB_PIN::GetOrientationCodeIndex( pin->GetOrientation() ) );
+ dlg.SetStyleList( LIB_PIN::GetStyleNames(), LIB_PIN::GetStyleSymbols() );
+ dlg.SetStyle( LIB_PIN::GetStyleCodeIndex( pin->GetShape() ) );
+ dlg.SetElectricalTypeList( LIB_PIN::GetElectricalTypeNames(),
+ LIB_PIN::GetElectricalTypeSymbols() );
+ dlg.SetElectricalType( pin->GetType() );
+ dlg.SetPinName( pin->GetName() );
+ dlg.SetPinNameTextSize( StringFromValue( g_UserUnit, pin->GetNameTextSize() ) );
+ dlg.SetPinNameTextSizeUnits( units );
+ dlg.SetPadName( pin->GetNumberString() );
+ dlg.SetPadNameTextSize( StringFromValue( g_UserUnit, pin->GetNumberTextSize() ) );
+
+ dlg.SetPadNameTextSizeUnits( units );
+ dlg.SetLength( StringFromValue( g_UserUnit, pin->GetLength() ) );
+ dlg.SetLengthUnits( units );
+ dlg.SetAddToAllParts( pin->GetUnit() == 0 );
+ dlg.SetAddToAllBodyStyles( pin->GetConvert() == 0 );
+ dlg.SetVisible( pin->IsVisible() );
+
+ /* This ugly hack fixes a bug in wxWidgets 2.8.7 and likely earlier
+ * versions for the flex grid sizer in wxGTK that prevents the last
+ * column from being sized correctly. It doesn't cause any problems
+ * on win32 so it doesn't need to wrapped in ugly #ifdef __WXGTK__
+ * #endif.
+ */
+ dlg.Layout();
+ dlg.Fit();
+ dlg.SetMinSize( dlg.GetSize() );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ {
+ if( pin->IsNew() )
+ {
+ pin->SetFlags( IS_CANCELLED );
+ m_canvas->EndMouseCapture();
+ }
+ return;
+ }
+
+ // Save the pin properties to use for the next new pin.
+ LastPinNameSize = ValueFromString( g_UserUnit, dlg.GetPinNameTextSize() );
+ LastPinNumSize = ValueFromString( g_UserUnit, dlg.GetPadNameTextSize() );
+ LastPinOrient = LIB_PIN::GetOrientationCode( dlg.GetOrientation() );
+ LastPinLength = ValueFromString( g_UserUnit, dlg.GetLength() );
+ LastPinShape = LIB_PIN::GetStyleCode( dlg.GetStyle() );
+ LastPinType = dlg.GetElectricalType();
+ LastPinCommonConvert = dlg.GetAddToAllBodyStyles();
+ LastPinCommonUnit = dlg.GetAddToAllParts();
+ LastPinVisible = dlg.GetVisible();
+
+ pin->EnableEditMode( true, m_editPinsPerPartOrConvert );
+ pin->SetName( dlg.GetPinName() );
+ pin->SetNameTextSize( GetLastPinNameSize() );
+ pin->SetNumber( dlg.GetPadName() );
+ pin->SetNumberTextSize( GetLastPinNumSize() );
+ pin->SetOrientation( LastPinOrient );
+ pin->SetLength( GetLastPinLength() );
+ pin->SetType( LastPinType );
+ pin->SetShape( LastPinShape );
+ pin->SetConversion( ( LastPinCommonConvert ) ? 0 : m_convert );
+ pin->SetPartNumber( ( LastPinCommonUnit ) ? 0 : m_unit );
+ pin->SetVisible( LastPinVisible );
+
+ if( pin->IsModified() || pin->IsNew() )
+ {
+ if( !pin->InEditMode() )
+ SaveCopyInUndoList( pin->GetParent() );
+
+ OnModify( );
+
+ MSG_PANEL_ITEMS items;
+ pin->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+ m_canvas->Refresh();
+ }
+
+ pin->EnableEditMode( false, m_editPinsPerPartOrConvert );
+
+ // Restore pin flags, that can be changed by the dialog editor
+ pin->ClearFlags();
+ pin->SetFlags( item_flags );
+}
+
+/**
+ * Clean up after aborting a move pin command.
+ */
+static void AbortPinMove( EDA_DRAW_PANEL* Panel, wxDC* DC )
+{
+ LIB_EDIT_FRAME* parent = (LIB_EDIT_FRAME*) Panel->GetParent();
+
+ if( parent == NULL )
+ return;
+
+ LIB_PIN* pin = (LIB_PIN*) parent->GetDrawItem();
+
+ if( pin == NULL || pin->Type() != LIB_PIN_T )
+ return;
+
+ pin->ClearFlags();
+
+ if( pin->IsNew() )
+ delete pin;
+ else
+ parent->RestoreComponent();
+
+ // clear edit flags
+ parent->SetDrawItem( NULL );
+ parent->SetLastDrawItem( NULL );
+ Panel->Refresh( true );
+}
+
+
+/**
+ * Managed cursor callback for placing component pins.
+ */
+void LIB_EDIT_FRAME::PlacePin()
+{
+ LIB_PIN* cur_pin = (LIB_PIN*) m_drawItem;
+ bool ask_for_pin = true;
+ wxPoint newpos;
+ bool status;
+
+ // Some tests
+ if( !cur_pin || cur_pin->Type() != LIB_PIN_T )
+ {
+ wxMessageBox( wxT( "LIB_EDIT_FRAME::PlacePin() error" ) );
+ return;
+ }
+
+ newpos = GetCrossHairPosition( true );
+
+ LIB_PART* part = GetCurPart();
+
+ // Test for an other pin in same new position:
+ for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
+ {
+ if( pin == cur_pin || newpos != pin->GetPosition() || pin->GetFlags() )
+ continue;
+
+ if( ask_for_pin && SynchronizePins() )
+ {
+ m_canvas->SetIgnoreMouseEvents( true );
+
+ status = IsOK( this, _( "This position is already occupied by another pin. Continue?" ) );
+
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+
+ if( !status )
+ return;
+ else
+ ask_for_pin = false;
+ }
+ }
+
+ // Create Undo from GetTempCopyComponent() if exists ( i.e. after a pin move)
+ // or from m_component (pin add ...)
+ if( GetTempCopyComponent() )
+ SaveCopyInUndoList( GetTempCopyComponent() );
+ else
+ SaveCopyInUndoList( part );
+
+ m_canvas->SetMouseCapture( NULL, NULL );
+ OnModify();
+ cur_pin->Move( newpos );
+
+ if( cur_pin->IsNew() )
+ {
+ LastPinOrient = cur_pin->GetOrientation();
+ LastPinType = cur_pin->GetType();
+ LastPinShape = cur_pin->GetShape();
+
+ if( SynchronizePins() )
+ CreateImagePins( cur_pin, m_unit, m_convert, m_showDeMorgan );
+
+ m_lastDrawItem = cur_pin;
+ part->AddDrawItem( m_drawItem );
+ }
+
+ // Put linked pins in new position, and clear flags
+ for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
+ {
+ if( pin->GetFlags() == 0 )
+ continue;
+
+ pin->Move( cur_pin->GetPosition() );
+ pin->ClearFlags();
+ }
+
+ m_drawItem = NULL;
+
+ m_canvas->Refresh();
+}
+
+
+/**
+ * Prepare the displacement of a pin
+ *
+ * Locate the pin pointed to by the cursor, and set the cursor management
+ * function move the pin.
+ */
+void LIB_EDIT_FRAME::StartMovePin( wxDC* DC )
+{
+ LIB_PIN* cur_pin = (LIB_PIN*) m_drawItem;
+ wxPoint startPos;
+
+ TempCopyComponent();
+
+ LIB_PART* part = GetCurPart();
+
+ // Mark pins for moving.
+ for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
+ {
+ pin->ClearFlags();
+
+ if( pin == cur_pin )
+ continue;
+
+ if( pin->GetPosition() == cur_pin->GetPosition() &&
+ pin->GetOrientation() == cur_pin->GetOrientation() && SynchronizePins() )
+ {
+ pin->SetFlags( IS_LINKED | IS_MOVED );
+ }
+ }
+
+ cur_pin->SetFlags( IS_LINKED | IS_MOVED );
+
+ PinPreviousPos = OldPos = cur_pin->GetPosition();
+ startPos.x = OldPos.x;
+ startPos.y = -OldPos.y;
+
+// m_canvas->CrossHairOff( DC );
+ SetCrossHairPosition( startPos );
+ m_canvas->MoveCursorToCrossHair();
+
+ MSG_PANEL_ITEMS items;
+
+ cur_pin->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+ m_canvas->SetMouseCapture( DrawMovePin, AbortPinMove );
+// m_canvas->CrossHairOn( DC );
+
+ // Refresh the screen to avoid color artifacts when drawing
+ // the pin in Edit mode and moving it from its start position
+ m_canvas->Refresh();
+}
+
+
+/* Move pin to the current mouse position. This function is called by the
+ * cursor management code. */
+static void DrawMovePin( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ LIB_EDIT_FRAME* parent = (LIB_EDIT_FRAME*) aPanel->GetParent();
+
+ if( parent == NULL )
+ return;
+
+ LIB_PIN* cur_pin = (LIB_PIN*) parent->GetDrawItem();
+
+ if( cur_pin == NULL || cur_pin->Type() != LIB_PIN_T )
+ return;
+
+ wxPoint pinpos = cur_pin->GetPosition();
+ bool showPinText = true;
+
+ // Erase pin in old position
+ if( aErase )
+ {
+ cur_pin->Move( PinPreviousPos );
+ cur_pin->Draw( aPanel, aDC, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode,
+ &showPinText, DefaultTransform );
+ }
+
+ // Redraw pin in new position
+ cur_pin->Move( aPanel->GetParent()->GetCrossHairPosition( true ) );
+ cur_pin->Draw( aPanel, aDC, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode,
+ &showPinText, DefaultTransform );
+
+ PinPreviousPos = cur_pin->GetPosition();
+
+ /* Keep the original position for existing pin (for Undo command)
+ * and the current position for a new pin */
+ if( !cur_pin->IsNew() )
+ cur_pin->Move( pinpos );
+}
+
+
+/*
+ * Create a new pin.
+ */
+void LIB_EDIT_FRAME::CreatePin( wxDC* DC )
+{
+ bool showPinText = true;
+
+ LIB_PART* part = GetCurPart();
+
+ if( !part )
+ return;
+
+ part->ClearStatus();
+
+ LIB_PIN* pin = new LIB_PIN( part );
+
+ m_drawItem = pin;
+
+ pin->SetFlags( IS_NEW );
+ pin->SetUnit( m_unit );
+ pin->SetConvert( m_convert );
+
+ // Flag pins to consider
+ if( SynchronizePins() )
+ pin->SetFlags( IS_LINKED );
+
+ pin->Move( GetCrossHairPosition( true ) );
+ pin->SetLength( GetLastPinLength() );
+ pin->SetOrientation( LastPinOrient );
+ pin->SetType( LastPinType );
+ pin->SetShape( LastPinShape );
+ pin->SetNameTextSize( GetLastPinNameSize() );
+ pin->SetNumberTextSize( GetLastPinNumSize() );
+ pin->SetConvert( LastPinCommonConvert ? 0 : m_convert );
+ pin->SetUnit( LastPinCommonUnit ? 0 : m_unit );
+ pin->SetVisible( LastPinVisible );
+ PinPreviousPos = pin->GetPosition();
+ m_canvas->SetIgnoreMouseEvents( true );
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+ cmd.SetId( ID_LIBEDIT_EDIT_PIN );
+ GetEventHandler()->ProcessEvent( cmd );
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+
+ if( pin->GetFlags() & IS_CANCELLED )
+ {
+ deleteItem( DC );
+ }
+ else
+ {
+ ClearTempCopyComponent();
+ m_canvas->SetMouseCapture( DrawMovePin, AbortPinMove );
+
+ if( DC )
+ pin->Draw( m_canvas, DC, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, GR_COPY, &showPinText,
+ DefaultTransform );
+
+ }
+}
+
+
+void LIB_EDIT_FRAME::CreateImagePins( LIB_PIN* aPin, int aUnit, int aConvert, bool aDeMorgan )
+{
+ int ii;
+ LIB_PIN* NewPin;
+
+ if( !SynchronizePins() )
+ return;
+
+ // Create "convert" pin at the current position.
+ if( aDeMorgan && ( aPin->GetConvert() != 0 ) )
+ {
+ NewPin = (LIB_PIN*) aPin->Clone();
+
+ if( aPin->GetConvert() > 1 )
+ NewPin->SetConvert( 1 );
+ else
+ NewPin->SetConvert( 2 );
+
+ aPin->GetParent()->AddDrawItem( NewPin );
+ }
+
+ for( ii = 1; ii <= aPin->GetParent()->GetUnitCount(); ii++ )
+ {
+ if( ii == aUnit || aPin->GetUnit() == 0 )
+ continue; // Pin common to all units.
+
+ NewPin = (LIB_PIN*) aPin->Clone();
+
+ // To avoid mistakes, gives this pin a new pin number because
+ // it does no have the save pin number as the master pin
+ // Because we do not know the actual number, give it '??'
+ wxString unknownNum( wxT( "??" ) );
+ NewPin->SetPinNumFromString( unknownNum );
+
+ if( aConvert != 0 )
+ NewPin->SetConvert( 1 );
+
+ NewPin->SetUnit( ii );
+ aPin->GetParent()->AddDrawItem( NewPin );
+
+ if( !( aDeMorgan && ( aPin->GetConvert() != 0 ) ) )
+ continue;
+
+ NewPin = (LIB_PIN*) aPin->Clone();
+ NewPin->SetConvert( 2 );
+ // Gives this pin a new pin number
+ // Because we do not know the actual number, give it '??'
+ NewPin->SetPinNumFromString( unknownNum );
+
+ if( aPin->GetUnit() != 0 )
+ NewPin->SetUnit( ii );
+
+ aPin->GetParent()->AddDrawItem( NewPin );
+ }
+}
+
+
+/* aMasterPin is the "template" pin
+ * aId is a param to select what should be mofified:
+ * - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM:
+ * Change pins text name size
+ * - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM:
+ * Change pins text num size
+ * - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM:
+ * Change pins length.
+ *
+ * If aMasterPin is selected ( .m_flag == IS_SELECTED ),
+ * only the other selected pins are modified
+ */
+void LIB_EDIT_FRAME::GlobalSetPins( LIB_PIN* aMasterPin, int aId )
+
+{
+ LIB_PART* part = GetCurPart();
+
+ if( !part || !aMasterPin )
+ return;
+
+ if( aMasterPin->Type() != LIB_PIN_T )
+ return;
+
+ OnModify( );
+
+ bool selected = aMasterPin->IsSelected();
+
+ for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
+ {
+ if( pin->GetConvert() && pin->GetConvert() != m_convert )
+ continue;
+
+ // Is it the "selected mode" ?
+ if( selected && !pin->IsSelected() )
+ continue;
+
+ switch( aId )
+ {
+ case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM:
+ pin->SetNumberTextSize( aMasterPin->GetNumberTextSize() );
+ break;
+
+ case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM:
+ pin->SetNameTextSize( aMasterPin->GetNameTextSize() );
+ break;
+
+ case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM:
+ pin->SetLength( aMasterPin->GetLength() );
+ break;
+ }
+
+ // Clear the flag IS_CHANGED, which was set by previous changes (if any)
+ // but not used here.
+ pin->ClearFlags( IS_CHANGED );
+ }
+}
+
+
+// Create a new pin based on the previous pin with an incremented pin number.
+void LIB_EDIT_FRAME::RepeatPinItem( wxDC* DC, LIB_PIN* SourcePin )
+{
+ wxString msg;
+
+ LIB_PART* part = GetCurPart();
+
+ if( !part || !SourcePin || SourcePin->Type() != LIB_PIN_T )
+ return;
+
+ LIB_PIN* pin = (LIB_PIN*) SourcePin->Clone();
+
+ pin->ClearFlags();
+ pin->SetFlags( IS_NEW );
+ wxPoint step;
+
+ switch( pin->GetOrientation() )
+ {
+ case PIN_UP:
+ step.x = GetRepeatPinStep();
+ break;
+
+ case PIN_DOWN:
+ step.x = GetRepeatPinStep();
+ break;
+
+ case PIN_LEFT:
+ step.y = - GetRepeatPinStep();
+ break;
+
+ case PIN_RIGHT:
+ step.y = - GetRepeatPinStep();
+ break;
+ }
+
+ pin->Move( pin->GetPosition() + step );
+ wxString nextName = pin->GetName();
+ IncrementLabelMember( nextName, GetRepeatDeltaLabel() );
+ pin->SetName( nextName );
+
+ pin->PinStringNum( msg );
+ IncrementLabelMember( msg, GetRepeatDeltaLabel() );
+ pin->SetPinNumFromString( msg );
+
+ m_drawItem = pin;
+
+ if( SynchronizePins() )
+ pin->SetFlags( IS_LINKED );
+
+ wxPoint savepos = GetCrossHairPosition();
+ m_canvas->CrossHairOff( DC );
+
+ SetCrossHairPosition( wxPoint( pin->GetPosition().x, -pin->GetPosition().y ) );
+
+ // Add this new pin in list, and creates pins for others parts if needed
+ m_drawItem = pin;
+ ClearTempCopyComponent();
+ PlacePin();
+ m_lastDrawItem = pin;
+
+ SetCrossHairPosition( savepos );
+ m_canvas->CrossHairOn( DC );
+
+ MSG_PANEL_ITEMS items;
+ pin->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+ OnModify( );
+}
+
+
+// helper function to sort pins by pin num
+bool sort_by_pin_number( const LIB_PIN* ref, const LIB_PIN* tst )
+{
+ int test = ref->GetNumber() - tst->GetNumber();
+
+ if( test == 0 )
+ {
+ test = ref->GetConvert() - tst->GetConvert();
+ }
+
+ if( test == 0 )
+ {
+ test = ref->GetUnit() - tst->GetUnit();
+ }
+
+ return test < 0;
+}
+
+
+void LIB_EDIT_FRAME::OnCheckComponent( wxCommandEvent& event )
+{
+ LIB_PART* part = GetCurPart();
+
+ if( !part )
+ return;
+
+ const int MIN_GRID_SIZE = 25;
+
+ LIB_PINS pinList;
+
+ part->GetPins( pinList );
+
+ if( pinList.size() == 0 )
+ {
+ DisplayInfoMessage( this, _( "No pins!" ) );
+ return;
+ }
+
+ // Sort pins by pin num, so 2 duplicate pins
+ // (pins with the same number) will be consecutive in list
+ sort( pinList.begin(), pinList.end(), sort_by_pin_number );
+
+ // Test for duplicates:
+ DIALOG_DISPLAY_HTML_TEXT_BASE error_display( this, wxID_ANY,
+ _( "Marker Information" ),
+ wxDefaultPosition,
+ wxSize( 750, 600 ) );
+
+ int dup_error = 0;
+
+ for( unsigned ii = 1; ii < pinList.size(); ii++ )
+ {
+ wxString stringPinNum, stringCurrPinNum;
+
+ LIB_PIN* curr_pin = pinList[ii];
+ LIB_PIN* pin = pinList[ii - 1];
+
+ if( pin->GetNumber() != curr_pin->GetNumber()
+ || pin->GetConvert() != curr_pin->GetConvert()
+ || pin->GetUnit() != curr_pin->GetUnit() )
+ continue;
+
+ dup_error++;
+ pin->PinStringNum( stringPinNum );
+
+ /* TODO I dare someone to find a way to make happy translators on
+ this thing! Lorenzo */
+ curr_pin->PinStringNum( stringCurrPinNum );
+
+ wxString msg = wxString::Format( _(
+ "<b>Duplicate pin %s</b> \"%s\" at location <b>(%.3f, %.3f)</b>"
+ " conflicts with pin %s \"%s\" at location <b>(%.3f, %.3f)</b>" ),
+ GetChars( stringCurrPinNum ),
+ GetChars( curr_pin->GetName() ),
+ curr_pin->GetPosition().x / 1000.0,
+ -curr_pin->GetPosition().y / 1000.0,
+ GetChars( stringPinNum ),
+ GetChars( pin->GetName() ),
+ pin->GetPosition().x / 1000.0,
+ -pin->GetPosition().y / 1000.0
+ );
+
+ if( part->GetUnitCount() > 1 )
+ {
+ msg += wxString::Format( _( " in part %c" ), 'A' + curr_pin->GetUnit() - 1 );
+ }
+
+ if( m_showDeMorgan )
+ {
+ if( curr_pin->GetConvert() )
+ msg += _( " of converted" );
+ else
+ msg += _( " of normal" );
+ }
+
+ msg += wxT( ".<br>" );
+
+ error_display.m_htmlWindow->AppendToPage( msg );
+ }
+
+ // Test for off grid pins:
+ int offgrid_error = 0;
+
+ for( unsigned ii = 0; ii < pinList.size(); ii++ )
+ {
+ LIB_PIN* pin = pinList[ii];
+
+ if( ( (pin->GetPosition().x % MIN_GRID_SIZE) == 0 ) &&
+ ( (pin->GetPosition().y % MIN_GRID_SIZE) == 0 ) )
+ continue;
+
+ // "pin" is off grid here.
+ offgrid_error++;
+ wxString stringPinNum;
+ pin->PinStringNum( stringPinNum );
+
+ wxString msg = wxString::Format( _(
+ "<b>Off grid pin %s</b> \"%s\" at location <b>(%.3f, %.3f)</b>" ),
+ GetChars( stringPinNum ),
+ GetChars( pin->GetName() ),
+ pin->GetPosition().x / 1000.0,
+ -pin->GetPosition().y / 1000.0
+ );
+
+ if( part->GetUnitCount() > 1 )
+ {
+ msg += wxString::Format( _( " in part %c" ), 'A' + pin->GetUnit() - 1 );
+ }
+
+ if( m_showDeMorgan )
+ {
+ if( pin->GetConvert() )
+ msg += _( " of converted" );
+ else
+ msg += _( " of normal" );
+ }
+
+ msg += wxT( ".<br>" );
+
+ error_display.m_htmlWindow->AppendToPage( msg );
+ }
+
+ if( !dup_error && !offgrid_error )
+ DisplayInfoMessage( this, _( "No off grid or duplicate pins were found." ) );
+ else
+ error_display.ShowModal();
+}
diff --git a/eeschema/plot_schematic_DXF.cpp b/eeschema/plot_schematic_DXF.cpp
new file mode 100644
index 0000000..a571c73
--- /dev/null
+++ b/eeschema/plot_schematic_DXF.cpp
@@ -0,0 +1,166 @@
+/** @file plot_schematic_DXF.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 Lorenzo Marcantonio
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <plot_common.h>
+#include <class_sch_screen.h>
+#include <schframe.h>
+#include <sch_sheet_path.h>
+#include <project.h>
+
+#include <dialog_plot_schematic.h>
+#include <wx_html_report_panel.h>
+
+
+void DIALOG_PLOT_SCHEMATIC::CreateDXFFile( bool aPlotAll, bool aPlotFrameRef )
+{
+ SCH_EDIT_FRAME* schframe = m_parent;
+ SCH_SCREEN* screen = schframe->GetScreen();
+ SCH_SHEET_PATH* sheetpath;
+ SCH_SHEET_PATH oldsheetpath = schframe->GetCurrentSheet();
+
+ /* When printing all pages, the printed page is not the current page.
+ * In complex hierarchies, we must setup references and others parameters
+ * in the printed SCH_SCREEN
+ * because in complex hierarchies a SCH_SCREEN (a schematic drawings)
+ * is shared between many sheets
+ */
+ SCH_SHEET_LIST SheetList( NULL );
+
+ sheetpath = SheetList.GetFirst();
+ SCH_SHEET_PATH list;
+ REPORTER& reporter = m_MessagesBox->Reporter();
+
+ while( true )
+ {
+ if( aPlotAll )
+ {
+ if( sheetpath == NULL )
+ break;
+
+ list.Clear();
+
+ if( list.BuildSheetPathInfoFromSheetPathValue( sheetpath->Path() ) )
+ {
+ schframe->SetCurrentSheet( list );
+ schframe->GetCurrentSheet().UpdateAllScreenReferences();
+ schframe->SetSheetNumberAndCount();
+ screen = schframe->GetCurrentSheet().LastScreen();
+ }
+ else // Should not happen
+ {
+ return;
+ }
+
+ sheetpath = SheetList.GetNext();
+ }
+
+ wxPoint plot_offset;
+ wxString msg;
+
+ try
+ {
+ wxString fname = schframe->GetUniqueFilenameForCurrentSheet();
+ wxString ext = DXF_PLOTTER::GetDefaultFileExtension();
+ wxFileName plotFileName = createPlotFileName( m_outputDirectoryName, fname,
+ ext, &reporter );
+
+ if( PlotOneSheetDXF( plotFileName.GetFullPath(), screen, plot_offset, 1.0, aPlotFrameRef ) )
+ {
+ msg.Printf( _( "Plot: '%s' OK.\n" ), GetChars( plotFileName.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ACTION );
+ }
+ else // Error
+ {
+ msg.Printf( _( "Unable to create file '%s'.\n" ), GetChars( plotFileName.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+ }
+ }
+ catch( IO_ERROR& e )
+ {
+ msg.Printf( wxT( "DXF Plotter exception: %s"), GetChars( e.errorText ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+ schframe->SetCurrentSheet( oldsheetpath );
+ schframe->GetCurrentSheet().UpdateAllScreenReferences();
+ schframe->SetSheetNumberAndCount();
+ return;
+ }
+ if( !aPlotAll )
+ {
+ break;
+ }
+ }
+
+ schframe->SetCurrentSheet( oldsheetpath );
+ schframe->GetCurrentSheet().UpdateAllScreenReferences();
+ schframe->SetSheetNumberAndCount();
+}
+
+
+bool DIALOG_PLOT_SCHEMATIC::PlotOneSheetDXF( const wxString& aFileName,
+ SCH_SCREEN* aScreen,
+ wxPoint aPlotOffset,
+ double aScale,
+ bool aPlotFrameRef )
+{
+ DXF_PLOTTER* plotter = new DXF_PLOTTER();
+
+ const PAGE_INFO& pageInfo = aScreen->GetPageSettings();
+ plotter->SetPageSettings( pageInfo );
+ plotter->SetColorMode( getModeColor() );
+ plotter->SetViewport( aPlotOffset, IU_PER_DECIMILS, aScale, false );
+
+ // Init :
+ plotter->SetCreator( wxT( "Eeschema-DXF" ) );
+
+ if( ! plotter->OpenFile( aFileName ) )
+ {
+ delete plotter;
+ return false;
+ }
+
+ LOCALE_IO toggle;
+
+ plotter->StartPlot();
+
+ if( aPlotFrameRef )
+ {
+ PlotWorkSheet( plotter, m_parent->GetTitleBlock(),
+ m_parent->GetPageSettings(),
+ aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens,
+ m_parent->GetScreenDesc(),
+ aScreen->GetFileName() );
+ }
+
+ aScreen->Plot( plotter );
+
+ // finish
+ plotter->EndPlot();
+ delete plotter;
+
+ return true;
+}
diff --git a/eeschema/plot_schematic_HPGL.cpp b/eeschema/plot_schematic_HPGL.cpp
new file mode 100644
index 0000000..9b64ab0
--- /dev/null
+++ b/eeschema/plot_schematic_HPGL.cpp
@@ -0,0 +1,260 @@
+/** @file plot_schematic_HPGL.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <plot_common.h>
+#include <class_sch_screen.h>
+#include <schframe.h>
+#include <base_units.h>
+#include <sch_sheet_path.h>
+#include <project.h>
+
+#include <dialog_plot_schematic.h>
+#include <wx_html_report_panel.h>
+
+enum HPGL_PAGEZ_T {
+ PAGE_DEFAULT = 0,
+ HPGL_PAGE_SIZE_A4,
+ HPGL_PAGE_SIZE_A3,
+ HPGL_PAGE_SIZE_A2,
+ HPGL_PAGE_SIZE_A1,
+ HPGL_PAGE_SIZE_A0,
+ HPGL_PAGE_SIZE_A,
+ HPGL_PAGE_SIZE_B,
+ HPGL_PAGE_SIZE_C,
+ HPGL_PAGE_SIZE_D,
+ HPGL_PAGE_SIZE_E,
+};
+
+
+static const wxChar* plot_sheet_list( int aSize )
+{
+ const wxChar* ret;
+
+ switch( aSize )
+ {
+ default:
+ case PAGE_DEFAULT:
+ ret = NULL; break;
+
+ case HPGL_PAGE_SIZE_A4:
+ ret = wxT( "A4" ); break;
+
+ case HPGL_PAGE_SIZE_A3:
+ ret = wxT( "A3" ); break;
+
+ case HPGL_PAGE_SIZE_A2:
+ ret = wxT( "A2" ); break;
+
+ case HPGL_PAGE_SIZE_A1:
+ ret = wxT( "A1" ); break;
+
+ case HPGL_PAGE_SIZE_A0:
+ ret = wxT( "A0" ); break;
+
+ case HPGL_PAGE_SIZE_A:
+ ret = wxT( "A" ); break;
+
+ case HPGL_PAGE_SIZE_B:
+ ret = wxT( "B" ); break;
+
+ case HPGL_PAGE_SIZE_C:
+ ret = wxT( "C" ); break;
+
+ case HPGL_PAGE_SIZE_D:
+ ret = wxT( "D" ); break;
+
+ case HPGL_PAGE_SIZE_E:
+ ret = wxT( "E" ); break;
+ }
+
+ return ret;
+};
+
+
+void DIALOG_PLOT_SCHEMATIC::SetHPGLPenWidth()
+{
+ m_HPGLPenSize = ValueFromTextCtrl( *m_penHPGLWidthCtrl );
+
+ if( m_HPGLPenSize > Millimeter2iu( 2 ) )
+ m_HPGLPenSize = Millimeter2iu( 2 );
+
+ if( m_HPGLPenSize < Millimeter2iu( 0.01 ) )
+ m_HPGLPenSize = Millimeter2iu( 0.01 );
+}
+
+
+void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef )
+{
+ SCH_SCREEN* screen = m_parent->GetScreen();
+ SCH_SHEET_PATH* sheetpath;
+ SCH_SHEET_PATH oldsheetpath = m_parent->GetCurrentSheet();
+
+ /* When printing all pages, the printed page is not the current page.
+ * In complex hierarchies, we must setup references and other parameters
+ * in the printed SCH_SCREEN
+ * because in complex hierarchies a SCH_SCREEN (a schematic drawings)
+ * is shared between many sheets
+ */
+ SCH_SHEET_LIST SheetList( NULL );
+
+ sheetpath = SheetList.GetFirst();
+ SCH_SHEET_PATH list;
+ REPORTER& reporter = m_MessagesBox->Reporter();
+
+ SetHPGLPenWidth();
+
+ while( true )
+ {
+ if( aPlotAll )
+ {
+ if( sheetpath == NULL )
+ break;
+
+ list.Clear();
+
+ if( list.BuildSheetPathInfoFromSheetPathValue( sheetpath->Path() ) )
+ {
+ m_parent->SetCurrentSheet( list );
+ m_parent->GetCurrentSheet().UpdateAllScreenReferences();
+ m_parent->SetSheetNumberAndCount();
+
+ screen = m_parent->GetCurrentSheet().LastScreen();
+
+ if( !screen ) // LastScreen() may return NULL
+ screen = m_parent->GetScreen();
+ }
+ else // Should not happen
+ return;
+
+ sheetpath = SheetList.GetNext();
+ }
+
+ const PAGE_INFO& curPage = screen->GetPageSettings();
+
+ PAGE_INFO plotPage = curPage;
+
+ // if plotting on a page size other than curPage
+ if( m_HPGLPaperSizeOption->GetSelection() != PAGE_DEFAULT )
+ plotPage.SetType( plot_sheet_list( m_HPGLPaperSizeOption->GetSelection() ) );
+
+ // Calculation of conversion scales.
+ double plot_scale = (double) plotPage.GetWidthMils() / curPage.GetWidthMils();
+
+ // Calculate offsets
+ wxPoint plotOffset;
+ wxString msg;
+
+ if( GetPlotOriginCenter() )
+ {
+ plotOffset.x = plotPage.GetWidthIU() / 2;
+ plotOffset.y = -plotPage.GetHeightIU() / 2;
+ }
+
+ try
+ {
+ wxString fname = m_parent->GetUniqueFilenameForCurrentSheet();
+ wxString ext = HPGL_PLOTTER::GetDefaultFileExtension();
+ wxFileName plotFileName = createPlotFileName( m_outputDirectoryName, fname,
+ ext, &reporter );
+
+ LOCALE_IO toggle;
+
+ if( Plot_1_Page_HPGL( plotFileName.GetFullPath(), screen, plotPage, plotOffset,
+ plot_scale, aPlotFrameRef ) )
+ {
+ msg.Printf( _( "Plot: '%s' OK.\n" ), GetChars( plotFileName.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ACTION );
+ }
+ else
+ {
+ msg.Printf( _( "Unable to create file '%s'.\n" ), GetChars( plotFileName.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+ }
+
+ if( !aPlotAll )
+ break;
+ }
+ catch( IO_ERROR& e )
+ {
+ msg.Printf( wxT( "HPGL Plotter exception: %s"), GetChars( e.errorText ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+ }
+
+ }
+
+ m_parent->SetCurrentSheet( oldsheetpath );
+ m_parent->GetCurrentSheet().UpdateAllScreenReferences();
+ m_parent->SetSheetNumberAndCount();
+}
+
+
+bool DIALOG_PLOT_SCHEMATIC::Plot_1_Page_HPGL( const wxString& aFileName,
+ SCH_SCREEN* aScreen,
+ const PAGE_INFO& aPageInfo,
+ wxPoint aPlot0ffset,
+ double aScale,
+ bool aPlotFrameRef )
+{
+ HPGL_PLOTTER* plotter = new HPGL_PLOTTER();
+
+ plotter->SetPageSettings( aPageInfo );
+ plotter->SetViewport( aPlot0ffset, IU_PER_DECIMILS, aScale, false );
+
+ // Init :
+ plotter->SetCreator( wxT( "Eeschema-HPGL" ) );
+
+ if( ! plotter->OpenFile( aFileName ) )
+ {
+ delete plotter;
+ return false;
+ }
+
+ LOCALE_IO toggle;
+
+ // Pen num and pen speed are not initialized here.
+ // Default HPGL driver values are used
+ plotter->SetPenDiameter( m_HPGLPenSize );
+ plotter->SetPenOverlap( m_HPGLPenSize / 4 );
+ plotter->StartPlot();
+
+ plotter->SetColor( BLACK );
+
+ if( getPlotFrameRef() )
+ PlotWorkSheet( plotter, m_parent->GetTitleBlock(),
+ m_parent->GetPageSettings(),
+ aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens,
+ m_parent->GetScreenDesc(),
+ aScreen->GetFileName() );
+
+ aScreen->Plot( plotter );
+
+ plotter->EndPlot();
+ delete plotter;
+
+ return true;
+}
diff --git a/eeschema/plot_schematic_PDF.cpp b/eeschema/plot_schematic_PDF.cpp
new file mode 100644
index 0000000..7fbdf11
--- /dev/null
+++ b/eeschema/plot_schematic_PDF.cpp
@@ -0,0 +1,209 @@
+/** @file plot_schematic_PDF.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <plot_common.h>
+#include <class_sch_screen.h>
+#include <schframe.h>
+#include <base_units.h>
+#include <sch_sheet_path.h>
+#include <project.h>
+
+#include <reporter.h>
+
+#include <dialog_plot_schematic.h>
+#include <wx_html_report_panel.h>
+
+void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef )
+{
+ SCH_SCREEN* screen = m_parent->GetScreen();
+ SCH_SHEET_PATH* sheetpath;
+ SCH_SHEET_PATH oldsheetpath = m_parent->GetCurrentSheet(); // sheetpath is saved here
+
+ /* When printing all pages, the printed page is not the current page. In
+ * complex hierarchies, we must update component references and others
+ * parameters in the given printed SCH_SCREEN, accordint to the sheet path
+ * because in complex hierarchies a SCH_SCREEN (a drawing ) is shared
+ * between many sheets and component references depend on the actual sheet
+ * path used
+ */
+ SCH_SHEET_LIST SheetList( NULL );
+
+ sheetpath = SheetList.GetFirst();
+
+ // Allocate the plotter and set the job level parameter
+ PDF_PLOTTER* plotter = new PDF_PLOTTER();
+ plotter->SetDefaultLineWidth( GetDefaultLineThickness() );
+ plotter->SetColorMode( getModeColor() );
+ plotter->SetCreator( wxT( "Eeschema-PDF" ) );
+
+ wxString msg;
+ wxFileName plotFileName;
+ REPORTER& reporter = m_MessagesBox->Reporter();
+ LOCALE_IO toggle; // Switch the locale to standard C
+
+ // First page handling is different
+ bool first_page = true;
+ do
+ {
+ // Step over the schematic hierarchy
+ if( aPlotAll )
+ {
+ SCH_SHEET_PATH list;
+
+ if( list.BuildSheetPathInfoFromSheetPathValue( sheetpath->Path() ) )
+ {
+ m_parent->SetCurrentSheet( list );
+ m_parent->GetCurrentSheet().UpdateAllScreenReferences();
+ m_parent->SetSheetNumberAndCount();
+ screen = m_parent->GetCurrentSheet().LastScreen();
+ }
+ else // Should not happen
+ wxASSERT( 0 );
+
+ sheetpath = SheetList.GetNext();
+ }
+
+ if( first_page )
+ {
+
+ try
+ {
+ wxString fname = m_parent->GetUniqueFilenameForCurrentSheet();
+ wxString ext = PDF_PLOTTER::GetDefaultFileExtension();
+ plotFileName = createPlotFileName( m_outputDirectoryName,
+ fname, ext, &reporter );
+
+ if( !plotter->OpenFile( plotFileName.GetFullPath() ) )
+ {
+ msg.Printf( _( "Unable to create file '%s'.\n" ), GetChars( plotFileName.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+ delete plotter;
+ return;
+ }
+
+ // Open the plotter and do the first page
+ setupPlotPagePDF( plotter, screen );
+ plotter->StartPlot();
+ first_page = false;
+
+ }
+ catch( const IO_ERROR& e )
+ {
+ // Cannot plot PDF file
+ msg.Printf( wxT( "PDF Plotter exception: %s" ), GetChars( e.errorText ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+
+ restoreEnvironment( plotter, oldsheetpath );
+ return;
+ }
+
+ }
+ else
+ {
+ /* For the following pages you need to close the (finished) page,
+ * reconfigure, and then start a new one */
+ plotter->ClosePage();
+ setupPlotPagePDF( plotter, screen );
+ plotter->StartPage();
+ }
+
+ plotOneSheetPDF( plotter, screen, aPlotFrameRef );
+ } while( aPlotAll && sheetpath );
+
+ // Everything done, close the plot and restore the environment
+ msg.Printf( _( "Plot: '%s' OK.\n" ), GetChars( plotFileName.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ACTION );
+
+
+ restoreEnvironment(plotter, oldsheetpath );
+
+}
+
+
+void DIALOG_PLOT_SCHEMATIC::restoreEnvironment( PDF_PLOTTER* aPlotter,
+ SCH_SHEET_PATH& aOldsheetpath )
+{
+ aPlotter->EndPlot();
+ delete aPlotter;
+
+ // Restore the previous sheet
+ m_parent->SetCurrentSheet( aOldsheetpath );
+ m_parent->GetCurrentSheet().UpdateAllScreenReferences();
+ m_parent->SetSheetNumberAndCount();
+}
+
+
+void DIALOG_PLOT_SCHEMATIC::plotOneSheetPDF( PLOTTER* aPlotter,
+ SCH_SCREEN* aScreen,
+ bool aPlotFrameRef )
+{
+ if( aPlotFrameRef )
+ {
+ aPlotter->SetColor( BLACK );
+ PlotWorkSheet( aPlotter, m_parent->GetTitleBlock(),
+ m_parent->GetPageSettings(),
+ aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens,
+ m_parent->GetScreenDesc(),
+ aScreen->GetFileName() );
+ }
+
+ aScreen->Plot( aPlotter );
+}
+
+
+void DIALOG_PLOT_SCHEMATIC::setupPlotPagePDF( PLOTTER * aPlotter, SCH_SCREEN* aScreen )
+{
+ PAGE_INFO plotPage; // page size selected to plot
+ // Considerations on page size and scaling requests
+ PAGE_INFO actualPage = aScreen->GetPageSettings(); // page size selected in schematic
+
+ switch( m_pageSizeSelect )
+ {
+ case PAGE_SIZE_A:
+ plotPage.SetType( wxT( "A" ) );
+ plotPage.SetPortrait( actualPage.IsPortrait() );
+ break;
+
+ case PAGE_SIZE_A4:
+ plotPage.SetType( wxT( "A4" ) );
+ plotPage.SetPortrait( actualPage.IsPortrait() );
+ break;
+
+ case PAGE_SIZE_AUTO:
+ default:
+ plotPage = actualPage;
+ break;
+ }
+
+ double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
+ double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
+ double scale = std::min( scalex, scaley );
+ aPlotter->SetPageSettings( plotPage );
+ aPlotter->SetViewport( wxPoint( 0, 0 ), IU_PER_DECIMILS, scale, false );
+}
+
diff --git a/eeschema/plot_schematic_PS.cpp b/eeschema/plot_schematic_PS.cpp
new file mode 100644
index 0000000..9e1c1b4
--- /dev/null
+++ b/eeschema/plot_schematic_PS.cpp
@@ -0,0 +1,191 @@
+/** @file plot_schematic_PS.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <plot_common.h>
+#include <class_sch_screen.h>
+#include <schframe.h>
+#include <base_units.h>
+#include <sch_sheet_path.h>
+#include <project.h>
+#include <reporter.h>
+
+#include <dialog_plot_schematic.h>
+#include <wx_html_report_panel.h>
+
+void DIALOG_PLOT_SCHEMATIC::createPSFile( bool aPlotAll, bool aPlotFrameRef )
+{
+ SCH_SCREEN* screen = m_parent->GetScreen();
+ SCH_SHEET_PATH* sheetpath;
+ SCH_SHEET_PATH oldsheetpath = m_parent->GetCurrentSheet(); // sheetpath is saved here
+ PAGE_INFO actualPage; // page size selected in schematic
+ PAGE_INFO plotPage; // page size selected to plot
+
+ /* When printing all pages, the printed page is not the current page.
+ * In complex hierarchies, we must update component references
+ * and others parameters in the given printed SCH_SCREEN, accordint to the sheet path
+ * because in complex hierarchies a SCH_SCREEN (a drawing )
+ * is shared between many sheets and component references depend on the actual sheet path used
+ */
+ SCH_SHEET_LIST SheetList( NULL );
+
+ sheetpath = SheetList.GetFirst();
+ SCH_SHEET_PATH list;
+
+ while( true )
+ {
+ if( aPlotAll )
+ {
+ if( sheetpath == NULL )
+ break;
+
+ list.Clear();
+
+ if( list.BuildSheetPathInfoFromSheetPathValue( sheetpath->Path() ) )
+ {
+ m_parent->SetCurrentSheet( list );
+ m_parent->GetCurrentSheet().UpdateAllScreenReferences();
+ m_parent->SetSheetNumberAndCount();
+ screen = m_parent->GetCurrentSheet().LastScreen();
+ }
+ else // Should not happen
+ return;
+
+ sheetpath = SheetList.GetNext();
+ }
+
+ actualPage = screen->GetPageSettings();
+
+ switch( m_pageSizeSelect )
+ {
+ case PAGE_SIZE_A:
+ plotPage.SetType( wxT( "A" ) );
+ plotPage.SetPortrait( actualPage.IsPortrait() );
+ break;
+
+ case PAGE_SIZE_A4:
+ plotPage.SetType( wxT( "A4" ) );
+ plotPage.SetPortrait( actualPage.IsPortrait() );
+ break;
+
+ case PAGE_SIZE_AUTO:
+ default:
+ plotPage = actualPage;
+ break;
+ }
+
+ double scalex = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
+ double scaley = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();
+
+ double scale = std::min( scalex, scaley );
+
+ wxPoint plot_offset;
+
+ wxString outputDirName = m_outputDirectoryName->GetValue();
+
+ wxString msg;
+ REPORTER& reporter = m_MessagesBox->Reporter();
+
+ try
+ {
+ wxString fname = m_parent->GetUniqueFilenameForCurrentSheet();
+ wxString ext = PS_PLOTTER::GetDefaultFileExtension();
+ wxFileName plotFileName = createPlotFileName( m_outputDirectoryName,
+ fname, ext, &reporter );
+
+ if( plotOneSheetPS( plotFileName.GetFullPath(), screen, plotPage, plot_offset,
+ scale, aPlotFrameRef ) )
+ {
+ msg.Printf( _( "Plot: '%s' OK.\n" ), GetChars( plotFileName.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ACTION );
+ }
+ else
+ {
+ // Error
+ msg.Printf( _( "Unable to create file '%s'.\n" ), GetChars( plotFileName.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+ }
+
+ }
+ catch( IO_ERROR& e )
+ {
+ msg.Printf( wxT( "PS Plotter exception: %s"), GetChars( e.errorText ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+ }
+
+ if( !aPlotAll )
+ break;
+ }
+
+ m_parent->SetCurrentSheet( oldsheetpath );
+ m_parent->GetCurrentSheet().UpdateAllScreenReferences();
+ m_parent->SetSheetNumberAndCount();
+}
+
+
+bool DIALOG_PLOT_SCHEMATIC::plotOneSheetPS( const wxString& aFileName,
+ SCH_SCREEN* aScreen,
+ const PAGE_INFO& aPageInfo,
+ wxPoint aPlot0ffset,
+ double aScale,
+ bool aPlotFrameRef )
+{
+ PS_PLOTTER* plotter = new PS_PLOTTER();
+ plotter->SetPageSettings( aPageInfo );
+ plotter->SetDefaultLineWidth( GetDefaultLineThickness() );
+ plotter->SetColorMode( getModeColor() );
+ plotter->SetViewport( aPlot0ffset, IU_PER_DECIMILS, aScale, false );
+
+ // Init :
+ plotter->SetCreator( wxT( "Eeschema-PS" ) );
+
+ if( ! plotter->OpenFile( aFileName ) )
+ {
+ delete plotter;
+ return false;
+ }
+
+ LOCALE_IO toggle; // Switch the locale to standard C
+
+ plotter->StartPlot();
+
+ if( aPlotFrameRef )
+ {
+ plotter->SetColor( BLACK );
+ PlotWorkSheet( plotter, m_parent->GetTitleBlock(),
+ m_parent->GetPageSettings(),
+ aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens,
+ m_parent->GetScreenDesc(),
+ aScreen->GetFileName() );
+ }
+
+ aScreen->Plot( plotter );
+
+ plotter->EndPlot();
+ delete plotter;
+
+ return true;
+}
diff --git a/eeschema/plot_schematic_SVG.cpp b/eeschema/plot_schematic_SVG.cpp
new file mode 100644
index 0000000..0cc81ed
--- /dev/null
+++ b/eeschema/plot_schematic_SVG.cpp
@@ -0,0 +1,205 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file plot_schematic_SVG.cpp
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <class_sch_screen.h>
+#include <schframe.h>
+#include <base_units.h>
+#include <libeditframe.h>
+#include <sch_sheet_path.h>
+#include <project.h>
+#include <reporter.h>
+
+#include <dialog_plot_schematic.h>
+#include <wx_html_report_panel.h>
+
+void DIALOG_PLOT_SCHEMATIC::createSVGFile( bool aPrintAll, bool aPrintFrameRef )
+{
+ wxString msg;
+ REPORTER& reporter = m_MessagesBox->Reporter();
+
+ if( aPrintAll )
+ {
+ SCH_SHEET_PATH* sheetpath;
+ SCH_SHEET_PATH oldsheetpath = m_parent->GetCurrentSheet();
+ SCH_SHEET_LIST SheetList( NULL );
+ sheetpath = SheetList.GetFirst();
+ SCH_SHEET_PATH list;
+
+ for( ; ; )
+ {
+ if( sheetpath == NULL )
+ {
+ break;
+ }
+
+ SCH_SCREEN* screen;
+ list.Clear();
+
+ if( list.BuildSheetPathInfoFromSheetPathValue( sheetpath->Path() ) )
+ {
+ m_parent->SetCurrentSheet( list );
+ m_parent->GetCurrentSheet().UpdateAllScreenReferences();
+ m_parent->SetSheetNumberAndCount();
+ screen = m_parent->GetCurrentSheet().LastScreen();
+ }
+ else // Should not happen
+ {
+ return;
+ }
+
+ sheetpath = SheetList.GetNext();
+
+ try
+ {
+ wxString fname = m_parent->GetUniqueFilenameForCurrentSheet();
+ wxString ext = SVG_PLOTTER::GetDefaultFileExtension();
+ wxFileName plotFileName = createPlotFileName( m_outputDirectoryName,
+ fname, ext, &reporter );
+
+ bool success = plotOneSheetSVG( m_parent, plotFileName.GetFullPath(), screen,
+ getModeColor() ? false : true,
+ aPrintFrameRef );
+
+ if( !success )
+ {
+ msg.Printf( _( "Cannot create file '%s'.\n" ),
+ GetChars( plotFileName.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+ }
+ else
+ {
+ msg.Printf( _( "Plot: '%s' OK.\n" ),
+ GetChars( plotFileName.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ACTION );
+ }
+ }
+ catch( const IO_ERROR& e )
+ {
+ // Cannot plot SVG file
+ msg.Printf( wxT( "SVG Plotter exception: %s" ), GetChars( e.errorText ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+
+ m_parent->SetCurrentSheet( oldsheetpath );
+ m_parent->GetCurrentSheet().UpdateAllScreenReferences();
+ m_parent->SetSheetNumberAndCount();
+ return;
+ }
+ }
+
+ m_parent->SetCurrentSheet( oldsheetpath );
+ m_parent->GetCurrentSheet().UpdateAllScreenReferences();
+ m_parent->SetSheetNumberAndCount();
+ }
+ else // Print current sheet
+ {
+ SCH_SCREEN* screen = (SCH_SCREEN*) m_parent->GetScreen();
+
+ try
+ {
+ wxString fname = screen->GetFileName();
+ wxString ext = SVG_PLOTTER::GetDefaultFileExtension();
+ wxFileName fn = createPlotFileName( m_outputDirectoryName, fname, ext );
+
+ bool success = plotOneSheetSVG( m_parent, fn.GetFullPath(), screen,
+ getModeColor() ? false : true,
+ aPrintFrameRef );
+ if( success )
+ {
+ msg.Printf( _( "Plot: '%s' OK.\n" ),
+ GetChars( fn.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ACTION );
+
+ }
+ else // Error
+ {
+ msg.Printf( _( "Unable to create file '%s'.\n" ),
+ GetChars( fn.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+ }
+ }
+ catch( const IO_ERROR& e )
+ {
+ // Cannot plot SVG file
+ msg.Printf( wxT( "SVG Plotter exception: %s."), GetChars( e.errorText ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+ return;
+ }
+ }
+}
+
+
+bool DIALOG_PLOT_SCHEMATIC::plotOneSheetSVG( EDA_DRAW_FRAME* aFrame,
+ const wxString& aFileName,
+ SCH_SCREEN* aScreen,
+ bool aPlotBlackAndWhite,
+ bool aPlotFrameRef )
+{
+ SVG_PLOTTER* plotter = new SVG_PLOTTER();
+
+ const PAGE_INFO& pageInfo = aScreen->GetPageSettings();
+ plotter->SetPageSettings( pageInfo );
+ plotter->SetDefaultLineWidth( GetDefaultLineThickness() );
+ plotter->SetColorMode( aPlotBlackAndWhite ? false : true );
+ wxPoint plot_offset;
+ double scale = 1.0;
+ plotter->SetViewport( plot_offset, IU_PER_DECIMILS, scale, false );
+
+ // Init :
+ plotter->SetCreator( wxT( "Eeschema-SVG" ) );
+
+ if( ! plotter->OpenFile( aFileName ) )
+ {
+ delete plotter;
+ return false;
+ }
+
+ LOCALE_IO toggle;
+
+ plotter->StartPlot();
+
+ if( aPlotFrameRef )
+ {
+ plotter->SetColor( BLACK );
+ PlotWorkSheet( plotter, aFrame->GetTitleBlock(),
+ aFrame->GetPageSettings(),
+ aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens,
+ aFrame->GetScreenDesc(),
+ aScreen->GetFileName() );
+ }
+
+ aScreen->Plot( plotter );
+
+ plotter->EndPlot();
+ delete plotter;
+
+ return true;
+}
diff --git a/eeschema/plugins/CMakeLists.txt b/eeschema/plugins/CMakeLists.txt
new file mode 100644
index 0000000..7ad2757
--- /dev/null
+++ b/eeschema/plugins/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Install the *.xsl file(s), user will need to install 'xsltproc' and setup
+# EESCHEMA's netlist plugins
+# See chapter 14 of eeschema.pdf
+
+
+set( XSL_SCRIPTS_LIST
+ xsl_scripts/bom_with_title_block_2_csv.xsl
+ xsl_scripts/bom2csv.xsl
+ xsl_scripts/bom2grouped_csv.xsl
+ xsl_scripts/netlist_form_cadstar-RINF.xsl
+ xsl_scripts/netlist_form_cadstar.xsl
+ xsl_scripts/netlist_form_OrcadPcb2.xsl
+ xsl_scripts/netlist_form_pads-pcb.xsl
+ )
+
+set( PYTHON_SCRIPTS_LIST
+ python_scripts/README-bom.txt
+ python_scripts/kicad_netlist_reader.py
+ python_scripts/bom_csv_grouped_by_value.py
+ python_scripts/bom_csv_grouped_by_value_with_fp.py
+ python_scripts/bom_csv_sorted_by_ref.py
+ python_scripts/bom_html_grouped_by_value.py
+ python_scripts/bom_html_with_advanced_grouping.py
+ python_scripts/bom_sorted_by_ref.py
+ )
+
+install( FILES ${XSL_SCRIPTS_LIST} ${PYTHON_SCRIPTS_LIST}
+ DESTINATION ${KICAD_PLUGINS}
+ COMPONENT binary
+ )
diff --git a/eeschema/plugins/python_scripts/README-bom.txt b/eeschema/plugins/python_scripts/README-bom.txt
new file mode 100644
index 0000000..7a53d7d
--- /dev/null
+++ b/eeschema/plugins/python_scripts/README-bom.txt
@@ -0,0 +1,38 @@
+bom_?.py are some python scripts which read a generic xml netlist from eeschema,
+and create a bom.
+
+All examples use kicad_netlist_reader.py, which is a python utility to read
+and parse this generic xml netlist and create the corresponding data
+used to build the bom.
+
+You can modify them to build the bom you want.
+
+to use them, you should install python, and run:
+python bom_example?.py <netlist name> <bom list netname>
+
+See Eeschema doc, chapter 14 for info about the generic xml netlist format,
+and how to run a script from Eeschema to create a customized netlist or BOM.
+
+If the python comment
+"""
+ @package
+ some comments
+"""
+is added to the begining of the python script, the comment will be displayed
+in Eescheam, in the BOM dialog
+
+For instance:
+"""
+ @package
+ Generate a HTML BOM list.
+ Components are sorted and grouped by value
+ Fields are (if exist)
+ Ref, Quantity, Value, Part, Datasheet, Description, Vendor
+"""
+
+displays:
+ Generate a HTML BOM list.
+ Components are sorted and grouped by value
+ Fields are (if exist)
+ Ref, Quantity, Value, Part, Datasheet, Description, Vendor
+in BOM dialog
diff --git a/eeschema/plugins/python_scripts/bom_csv_grouped_by_value.py b/eeschema/plugins/python_scripts/bom_csv_grouped_by_value.py
new file mode 100644
index 0000000..b582d61
--- /dev/null
+++ b/eeschema/plugins/python_scripts/bom_csv_grouped_by_value.py
@@ -0,0 +1,167 @@
+#
+# Example python script to generate a BOM from a KiCad generic netlist
+#
+# Example: Sorted and Grouped CSV BOM
+#
+"""
+ @package
+ Generate a csv BOM list.
+ Components are sorted by ref and grouped by value
+ Fields are (if exist)
+ Item, Qty, Reference(s), Value, LibPart, Footprint, Datasheet
+
+ Command line:
+ python "pathToFile/bom_csv_grouped_by_value.py" "%I" "%O.csv"
+"""
+
+from __future__ import print_function
+
+# Import the KiCad python helper module and the csv formatter
+import kicad_netlist_reader
+import csv
+import sys
+
+def myEqu(self, other):
+ """myEqu is a more advanced equivalence function for components which is
+ used by component grouping. Normal operation is to group components based
+ on their value and footprint.
+
+ In this example of a custom equivalency operator we compare the
+ value, the part name and the footprint.
+ """
+ result = True
+ if self.getValue() != other.getValue():
+ result = False
+ elif self.getPartName() != other.getPartName():
+ result = False
+ elif self.getFootprint() != other.getFootprint():
+ result = False
+
+ return result
+
+# Override the component equivalence operator - it is important to do this
+# before loading the netlist, otherwise all components will have the original
+# equivalency operator.
+kicad_netlist_reader.comp.__eq__ = myEqu
+
+if len(sys.argv) != 3:
+ print("Usage ", __file__, "<generic_netlist.xml> <output.csv>", file=sys.stderr)
+ sys.exit(1)
+
+
+# Generate an instance of a generic netlist, and load the netlist tree from
+# the command line option. If the file doesn't exist, execution will stop
+net = kicad_netlist_reader.netlist(sys.argv[1])
+
+# Open a file to write to, if the file cannot be opened output to stdout
+# instead
+try:
+ f = open(sys.argv[2], 'w')
+except IOError:
+ e = "Can't open output file for writing: " + sys.argv[2]
+ print( __file__, ":", e, sys.stderr )
+ f = sys.stdout
+
+# subset the components to those wanted in the BOM, controlled
+# by <configure> block in kicad_netlist_reader.py
+components = net.getInterestingComponents()
+
+compfields = net.gatherComponentFieldUnion(components)
+partfields = net.gatherLibPartFieldUnion()
+
+# remove Reference, Value, Datasheet, and Footprint, they will come from 'columns' below
+partfields -= set( ['Reference', 'Value', 'Datasheet', 'Footprint'] )
+
+columnset = compfields | partfields # union
+
+# prepend an initial 'hard coded' list and put the enchillada into list 'columns'
+columns = ['Item', 'Qty', 'Reference(s)', 'Value', 'LibPart', 'Footprint', 'Datasheet'] + sorted(list(columnset))
+
+# Create a new csv writer object to use as the output formatter
+out = csv.writer( f, lineterminator='\n', delimiter=',', quotechar='\"', quoting=csv.QUOTE_ALL )
+
+# override csv.writer's writerow() to support encoding conversion (initial encoding is utf8):
+def writerow( acsvwriter, columns ):
+ utf8row = []
+ for col in columns:
+ utf8row.append( str(col) ) # currently, no change
+ acsvwriter.writerow( utf8row )
+
+# Output a set of rows as a header providing general information
+writerow( out, ['Source:', net.getSource()] )
+writerow( out, ['Date:', net.getDate()] )
+writerow( out, ['Tool:', net.getTool()] )
+writerow( out, ['Generator:', sys.argv[0]] )
+writerow( out, ['Component Count:', len(components)] )
+writerow( out, [] )
+writerow( out, ['Individual Components:'] )
+writerow( out, [] ) # blank line
+writerow( out, columns )
+
+# Output all the interesting components individually first:
+row = []
+for c in components:
+ del row[:]
+ row.append('') # item is blank in individual table
+ row.append('') # Qty is always 1, why print it
+ row.append( c.getRef() ) # Reference
+ row.append( c.getValue() ) # Value
+ row.append( c.getLibName() + ":" + c.getPartName() ) # LibPart
+ #row.append( c.getDescription() )
+ row.append( c.getFootprint() )
+ row.append( c.getDatasheet() )
+
+ # from column 7 upwards, use the fieldnames to grab the data
+ for field in columns[7:]:
+ row.append( c.getField( field ) );
+
+ writerow( out, row )
+
+
+writerow( out, [] ) # blank line
+writerow( out, [] ) # blank line
+writerow( out, [] ) # blank line
+
+writerow( out, ['Collated Components:'] )
+writerow( out, [] ) # blank line
+writerow( out, columns ) # reuse same columns
+
+
+
+# Get all of the components in groups of matching parts + values
+# (see kicad_netlist_reader.py)
+grouped = net.groupComponents(components)
+
+
+# Output component information organized by group, aka as collated:
+item = 0
+for group in grouped:
+ del row[:]
+ refs = ""
+
+ # Add the reference of every component in the group and keep a reference
+ # to the component so that the other data can be filled in once per group
+ for component in group:
+ if len(refs) > 0:
+ refs += ", "
+ refs += component.getRef()
+ c = component
+
+ # Fill in the component groups common data
+ # columns = ['Item', 'Qty', 'Reference(s)', 'Value', 'LibPart', 'Footprint', 'Datasheet'] + sorted(list(columnset))
+ item += 1
+ row.append( item )
+ row.append( len(group) )
+ row.append( refs );
+ row.append( c.getValue() )
+ row.append( c.getLibName() + ":" + c.getPartName() )
+ row.append( net.getGroupFootprint(group) )
+ row.append( net.getGroupDatasheet(group) )
+
+ # from column 7 upwards, use the fieldnames to grab the data
+ for field in columns[7:]:
+ row.append( net.getGroupField(group, field) );
+
+ writerow( out, row )
+
+f.close()
diff --git a/eeschema/plugins/python_scripts/bom_csv_grouped_by_value_with_fp.py b/eeschema/plugins/python_scripts/bom_csv_grouped_by_value_with_fp.py
new file mode 100644
index 0000000..dd14af0
--- /dev/null
+++ b/eeschema/plugins/python_scripts/bom_csv_grouped_by_value_with_fp.py
@@ -0,0 +1,65 @@
+#
+# Example python script to generate a BOM from a KiCad generic netlist
+#
+# Example: Sorted and Grouped CSV BOM
+#
+
+"""
+ @package
+ Generate a Tab delimited list (csv file type).
+ Components are sorted by ref and grouped by value with same footprint
+ Fields are (if exist)
+ 'Ref', 'Qnty', 'Value', 'Cmp name', 'Footprint', 'Description', 'Vendor'
+
+ Command line:
+ python "pathToFile/bom_csv_grouped_by_value_with_fp.py" "%I" "%O.csv"
+"""
+
+# Import the KiCad python helper module and the csv formatter
+import kicad_netlist_reader
+import csv
+import sys
+
+# Generate an instance of a generic netlist, and load the netlist tree from
+# the command line option. If the file doesn't exist, execution will stop
+net = kicad_netlist_reader.netlist(sys.argv[1])
+
+# Open a file to write to, if the file cannot be opened output to stdout
+# instead
+try:
+ f = open(sys.argv[2], 'w')
+except IOError:
+ e = "Can't open output file for writing: " + sys.argv[2]
+ print(__file__, ":", e, sys.stderr)
+ f = sys.stdout
+
+# Create a new csv writer object to use as the output formatter
+out = csv.writer(f, lineterminator='\n', delimiter=',', quotechar='\"', quoting=csv.QUOTE_ALL)
+
+# Output a set of rows for a header providing general information
+out.writerow(['Source:', net.getSource()])
+out.writerow(['Date:', net.getDate()])
+out.writerow(['Tool:', net.getTool()])
+out.writerow( ['Generator:', sys.argv[0]] )
+out.writerow(['Component Count:', len(net.components)])
+out.writerow(['Ref', 'Qnty', 'Value', 'Cmp name', 'Footprint', 'Description', 'Vendor'])
+
+# Get all of the components in groups of matching parts + values
+# (see ky_generic_netlist_reader.py)
+grouped = net.groupComponents()
+
+# Output all of the component information
+for group in grouped:
+ refs = ""
+
+ # Add the reference of every component in the group and keep a reference
+ # to the component so that the other data can be filled in once per group
+ for component in group:
+ refs += component.getRef() + ", "
+ c = component
+
+ # Fill in the component groups common data
+ out.writerow([refs, len(group), c.getValue(), c.getPartName(), c.getFootprint(),
+ c.getDescription(), c.getField("Vendor")])
+
+
diff --git a/eeschema/plugins/python_scripts/bom_csv_sorted_by_ref.py b/eeschema/plugins/python_scripts/bom_csv_sorted_by_ref.py
new file mode 100644
index 0000000..e66cc13
--- /dev/null
+++ b/eeschema/plugins/python_scripts/bom_csv_sorted_by_ref.py
@@ -0,0 +1,62 @@
+#
+# Example python script to generate a BOM from a KiCad generic netlist
+#
+# Example: Ungrouped (One component per row) CSV output
+#
+
+"""
+ @package
+ Generate a csv list file.
+ Components are sorted by ref
+ One component per line
+ Fields are (if exist)
+ Ref, value, Part, footprint, Datasheet, Manufacturer, Vendor
+
+ Command line:
+ python "pathToFile/bom_csv_sorted_by_ref.py" "%I" "%O.csv"
+"""
+
+from __future__ import print_function
+
+# Import the KiCad python helper module
+import kicad_netlist_reader
+import csv
+import sys
+
+# Generate an instance of a generic netlist, and load the netlist tree from
+# the command line option. If the file doesn't exist, execution will stop
+net = kicad_netlist_reader.netlist(sys.argv[1])
+
+# Open a file to write to, if the file cannot be opened output to stdout
+# instead
+try:
+ f = open(sys.argv[2], 'w')
+except IOError:
+ e = "Can't open output file for writing: " + sys.argv[2]
+ print( __file__, ":", e, sys.stderr )
+ f = sys.stdout
+
+# Create a new csv writer object to use as the output formatter
+out = csv.writer(f, lineterminator='\n', delimiter=',', quotechar="\"", quoting=csv.QUOTE_ALL)
+
+# override csv.writer's writerow() to support utf8 encoding:
+def writerow( acsvwriter, columns ):
+ utf8row = []
+ for col in columns:
+ utf8row.append( str(col) )
+ acsvwriter.writerow( utf8row )
+
+components = net.getInterestingComponents()
+
+# Output a field delimited header line
+writerow( out, ['Source:', net.getSource()] )
+writerow( out, ['Date:', net.getDate()] )
+writerow( out, ['Tool:', net.getTool()] )
+writerow( out, ['Component Count:', len(components)] )
+writerow( out, ['Ref', 'Value', 'Footprint', 'Datasheet', 'Manufacturer', 'Vendor'] )
+
+# Output all of the component information (One component per row)
+for c in components:
+ writerow( out, [c.getRef(), c.getValue(), c.getFootprint(), c.getDatasheet(),
+ c.getField("Manufacturer"), c.getField("Vendor")])
+
diff --git a/eeschema/plugins/python_scripts/bom_html_grouped_by_value.py b/eeschema/plugins/python_scripts/bom_html_grouped_by_value.py
new file mode 100644
index 0000000..80def66
--- /dev/null
+++ b/eeschema/plugins/python_scripts/bom_html_grouped_by_value.py
@@ -0,0 +1,98 @@
+#
+# Example python script to generate a BOM from a KiCad generic netlist
+#
+# Example: Sorted and Grouped HTML BOM
+#
+"""
+ @package
+ Generate a HTML BOM list.
+ Components are sorted by ref and grouped by value
+ Fields are (if exist)
+ Ref, Quantity, Value, Part, Datasheet, Description, Vendor
+
+ Command line:
+ python "pathToFile/bom_html_grouped_by_value.py" "%I" "%O.html"
+"""
+
+from __future__ import print_function
+
+# Import the KiCad python helper module and the csv formatter
+import kicad_netlist_reader
+import sys
+
+# Start with a basic html template
+html = """
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ </head>
+ <body>
+ <h1><!--SOURCE--></h1>
+ <p><!--DATE--></p>
+ <p><!--TOOL--></p>
+ <p><!--COMPCOUNT--></p>
+ <table>
+ <!--TABLEROW-->
+ </table>
+ </body>
+</html>
+ """
+
+# Generate an instance of a generic netlist, and load the netlist tree from
+# the command line option. If the file doesn't exist, execution will stop
+net = kicad_netlist_reader.netlist(sys.argv[1])
+
+# Open a file to write to, if the file cannot be opened output to stdout
+# instead
+try:
+ f = open(sys.argv[2], 'w')
+except IOError:
+ e = "Can't open output file for writing: " + sys.argv[2]
+ print(__file__, ":", e, file=sys.stderr)
+ f = sys.stdout
+
+components = net.getInterestingComponents()
+
+# Output a set of rows for a header providing general information
+html = html.replace('<!--SOURCE-->', net.getSource())
+html = html.replace('<!--DATE-->', net.getDate())
+html = html.replace('<!--TOOL-->', net.getTool())
+html = html.replace('<!--COMPCOUNT-->', "<b>Component Count:</b>" + \
+ str(len(components)))
+
+row = "<tr><th style='width:640px'>Ref</th>"
+row += "<th>Qnty</th>"
+row += "<th>Value</th>" + "<th>Part</th>" + "<th>Datasheet</th>"
+row += "<th>Description</th>" + "<th>Vendor</th></tr>"
+
+html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
+
+# Get all of the components in groups of matching parts + values
+# (see kicad_netlist_reader.py)
+grouped = net.groupComponents(components)
+
+# Output all of the component information
+for group in grouped:
+ refs = ""
+
+ # Add the reference of every component in the group and keep a reference
+ # to the component so that the other data can be filled in once per group
+ for component in group:
+ if len(refs) > 0:
+ refs += ", "
+ refs += component.getRef()
+ c = component
+
+ row = "<tr><td>" + refs +"</td><td>" + str(len(group))
+ row += "</td><td>" + c.getValue()
+ row += "</td><td>" + c.getLibName() + ":" + c.getPartName()
+ row += "</td><td>" + c.getDatasheet()
+ row += "</td><td>" + c.getDescription()
+ row += "</td><td>" + c.getField("Vendor")+ "</td></tr>"
+
+ html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
+
+# Print the formatted html to the file
+print(html, file=f)
diff --git a/eeschema/plugins/python_scripts/bom_html_with_advanced_grouping.py b/eeschema/plugins/python_scripts/bom_html_with_advanced_grouping.py
new file mode 100644
index 0000000..a091351
--- /dev/null
+++ b/eeschema/plugins/python_scripts/bom_html_with_advanced_grouping.py
@@ -0,0 +1,132 @@
+#
+# Example python script to generate a BOM from a KiCad generic netlist
+#
+# Example: Sorted and Grouped HTML BOM with advanced grouping
+#
+
+"""
+ @package
+ Generate a HTML BOM list.
+ Components are sorted and grouped by value
+ Fields are (if exist)
+ Ref, Quantity, Value, Part, Footprint, Description, Vendor
+
+ Command line:
+ python "pathToFile/bom_with_advanced_grouping.py" "%I" "%O.html"
+"""
+
+
+from __future__ import print_function
+
+# Import the KiCad python helper module and the csv formatter
+import kicad_netlist_reader
+import sys
+
+# Start with a basic html template
+html = """
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>KiCad BOM Example 5</title>
+ </head>
+ <body>
+ <h1><!--SOURCE--></h1>
+ <p><!--DATE--></p>
+ <p><!--TOOL--></p>
+ <p><!--COMPCOUNT--></p>
+ <table>
+ <!--TABLEROW-->
+ </table>
+ </body>
+</html>
+ """
+
+def myEqu(self, other):
+ """myEqu is a more advanced equivalence function for components which is
+ used by component grouping. Normal operation is to group components based
+ on their Value and Footprint.
+
+ In this example of a more advanced equivalency operator we also compare the
+ custom fields Voltage, Tolerance and Manufacturer as well as the assigned
+ footprint. If these fields are not used in some parts they will simply be
+ ignored (they will match as both will be empty strings).
+
+ """
+ result = True
+ if self.getValue() != other.getValue():
+ result = False
+ elif self.getPartName() != other.getPartName():
+ result = False
+ elif self.getFootprint() != other.getFootprint():
+ result = False
+ elif self.getField("Tolerance") != other.getField("Tolerance"):
+ result = False
+ elif self.getField("Manufacturer") != other.getField("Manufacturer"):
+ result = False
+ elif self.getField("Voltage") != other.getField("Voltage"):
+ result = False
+
+ return result
+
+# Override the component equivalence operator - it is important to do this
+# before loading the netlist, otherwise all components will have the original
+# equivalency operator.
+kicad_netlist_reader.comp.__eq__ = myEqu
+
+# Generate an instance of a generic netlist, and load the netlist tree from
+# <file>.tmp. If the file doesn't exist, execution will stop
+net = kicad_netlist_reader.netlist(sys.argv[1])
+
+# Open a file to write too, if the file cannot be opened output to stdout
+# instead
+try:
+ f = open(sys.argv[2], 'w')
+except IOError:
+ e = "Can't open output file for writing: " + sys.argv[2]
+ print(__file__, ":", e, file=sys.stderr)
+ f = sys.stdout
+
+# Output a set of rows for a header providing general information
+html = html.replace('<!--SOURCE-->', net.getSource())
+html = html.replace('<!--DATE-->', net.getDate())
+html = html.replace('<!--TOOL-->', net.getTool())
+html = html.replace('<!--COMPCOUNT-->', "<b>Component Count:</b>" + \
+ str(len(net.components)))
+
+row = "<tr><th style='width:640px'>Ref</th>" + "<th>Qnty</th>"
+row += "<th>Value</th>" + "<th>Part</th>" + "<th>Footprint</th>"
+row += "<th>Description</th>" + "<th>Vendor</th></tr>"
+
+html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
+
+components = net.getInterestingComponents()
+
+# Get all of the components in groups of matching parts + values
+# (see kicad_netlist_reader.py)
+grouped = net.groupComponents(components)
+
+# Output all of the component information
+for group in grouped:
+ refs = ""
+
+ # Add the reference of every component in the group and keep a reference
+ # to the component so that the other data can be filled in once per group
+ for component in group:
+ if len(refs) > 0:
+ refs += ", "
+ refs += component.getRef()
+ c = component
+
+ row = "\n "
+ row += "<tr><td>" + refs +"</td><td>" + str(len(group))
+ row += "</td><td>" + c.getValue() + "</td><td>" + c.getLibName() + ":"
+ row += c.getPartName() + "</td><td>" + c.getFootprint() + "</td><td>"
+ row += c.getDescription() + "</td><td>" + c.getField("Vendor")
+ row += "</td></tr>"
+
+ html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
+
+# Print the formatted html to output file
+print(html, file=f)
diff --git a/eeschema/plugins/python_scripts/bom_sorted_by_ref.py b/eeschema/plugins/python_scripts/bom_sorted_by_ref.py
new file mode 100644
index 0000000..6dd28d5
--- /dev/null
+++ b/eeschema/plugins/python_scripts/bom_sorted_by_ref.py
@@ -0,0 +1,61 @@
+#
+# Example python script to generate a BOM from a KiCad generic netlist
+#
+"""
+ @package
+ Generate a BOM list file (a simple text).
+ Components are sorted by ref
+ One component per line
+ Fields are (if exist)
+ Ref, Quantity, value, Part, footprint, Description, Vendor
+ Fields are separated by tabs
+
+ Command line:
+ python "pathToFile/bom_sorted_by_ref.py" "%I" "%O.txt"
+"""
+
+from __future__ import print_function
+
+# Import the KiCad python helper module and the csv formatter
+import kicad_netlist_reader
+import csv
+import sys
+
+# Generate an instance of a generic netlist, and load the netlist tree from
+# the command line option. If the file doesn't exist, execution will stop
+net = kicad_netlist_reader.netlist(sys.argv[1])
+
+# Open a file to write to, if the file cannot be opened output to stdout
+# instead
+try:
+ f = open(sys.argv[2], 'w')
+except IOError:
+ e = "Can't open output file for writing: " + sys.argv[2]
+ print(__file__, ":", e, sys.stderr)
+ f = sys.stdout
+
+# Create a new csv writer object to use as the output formatter, although we
+# are created a tab delimited list instead!
+out = csv.writer(f, lineterminator='\n', delimiter='\t', quoting=csv.QUOTE_NONE)
+
+# override csv.writer's writerow() to support utf8 encoding:
+def writerow( acsvwriter, columns ):
+ utf8row = []
+ for col in columns:
+ txt=str(col);
+ utf8row.append( txt )
+ acsvwriter.writerow( utf8row )
+
+components = net.getInterestingComponents()
+
+# Output a field delimited header line
+writerow( out, ['Source:', net.getSource()] )
+writerow( out, ['Date:', net.getDate()] )
+writerow( out, ['Tool:', net.getTool()] )
+writerow( out, ['Component Count:', len(components)] )
+writerow( out, ['Ref', 'Value', 'Part', 'Footprint', 'Description', 'Vendor'] )
+
+# Output all of the component information
+for c in components:
+ writerow( out, [c.getRef(), c.getValue(), c.getLibName() + ":" + c.getPartName(),
+ c.getFootprint(), c.getDescription(), c.getField("Vendor")])
diff --git a/eeschema/plugins/python_scripts/kicad_netlist_reader.py b/eeschema/plugins/python_scripts/kicad_netlist_reader.py
new file mode 100644
index 0000000..407f572
--- /dev/null
+++ b/eeschema/plugins/python_scripts/kicad_netlist_reader.py
@@ -0,0 +1,764 @@
+#
+# KiCad python module for interpreting generic netlists which can be used
+# to generate Bills of materials, etc.
+#
+# Remember these files use UTF8 encoding
+#
+# No string formatting is used on purpose as the only string formatting that
+# is current compatible with python 2.4+ to 3.0+ is the '%' method, and that
+# is due to be deprecated in 3.0+ soon
+#
+
+"""
+ @package
+ Helper module for interpreting generic netlist and build custom
+ bom generators or netlists in foreign format
+"""
+
+
+from __future__ import print_function
+import sys
+import xml.sax as sax
+import re
+import pdb
+
+#-----<Configure>----------------------------------------------------------------
+
+# excluded_fields is a list of regular expressions. If any one matches a field
+# from either a component or a libpart, then that will not be included as a
+# column in the BOM. Otherwise all columns from all used libparts and components
+# will be unionized and will appear. Some fields are impossible to blacklist, such
+# as Ref, Value, Footprint, and Datasheet. Additionally Qty and Item are supplied
+# unconditionally as columns, and may not be removed.
+excluded_fields = [
+ #'Price@1000'
+ ]
+
+
+# You may exlude components from the BOM by either:
+#
+# 1) adding a custom field named "Installed" to your components and filling it
+# with a value of "NU" (Normally Uninstalled).
+# See netlist.getInterestingComponents(), or
+#
+# 2) blacklisting it in any of the three following lists:
+
+
+# regular expressions which match component 'Reference' fields of components that
+# are to be excluded from the BOM.
+excluded_references = [
+ 'TP[0-9]+' # all test points
+ ]
+
+
+# regular expressions which match component 'Value' fields of components that
+# are to be excluded from the BOM.
+excluded_values = [
+ 'MOUNTHOLE',
+ 'SCOPETEST',
+ 'MOUNT_HOLE',
+ 'SOLDER_BRIDGE.*'
+ ]
+
+
+# regular expressions which match component 'Footprint' fields of components that
+# are to be excluded from the BOM.
+excluded_footprints = [
+ #'MOUNTHOLE'
+ ]
+
+#-----</Configure>---------------------------------------------------------------
+
+
+class xmlElement():
+ """xml element which can represent all nodes of the netlist tree. It can be
+ used to easily generate various output formats by propogating format
+ requests to children recursively.
+ """
+ def __init__(self, name, parent=None):
+ self.name = name
+ self.attributes = {}
+ self.parent = parent
+ self.chars = ""
+ self.children = []
+
+ def __str__(self):
+ """String representation of this netlist element
+
+ """
+ return self.name + "[" + self.chars + "]" + " attr_count:" + str(len(self.attributes))
+
+ def formatXML(self, nestLevel=0, amChild=False):
+ """Return this element formatted as XML
+
+ Keywords:
+ nestLevel -- increases by one for each level of nesting.
+ amChild -- If set to True, the start of document is not returned.
+
+ """
+ s = ""
+
+ indent = ""
+ for i in range(nestLevel):
+ indent += " "
+
+ if not amChild:
+ s = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+
+ s += indent + "<" + self.name
+ for a in self.attributes:
+ s += " " + a + "=\"" + self.attributes[a] + "\""
+
+ if (len(self.chars) == 0) and (len(self.children) == 0):
+ s += "/>"
+ else:
+ s += ">" + self.chars
+
+ for c in self.children:
+ s += "\n"
+ s += c.formatXML(nestLevel+1, True)
+
+ if (len(self.children) > 0):
+ s += "\n" + indent
+
+ if (len(self.children) > 0) or (len(self.chars) > 0):
+ s += "</" + self.name + ">"
+
+ return s
+
+ def formatHTML(self, amChild=False):
+ """Return this element formatted as HTML
+
+ Keywords:
+ amChild -- If set to True, the start of document is not returned
+
+ """
+ s = ""
+
+ if not amChild:
+ s = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title></title>
+ </head>
+ <body>
+ <table>
+ """
+
+ s += "<tr><td><b>" + self.name + "</b><br>" + self.chars + "</td><td><ul>"
+ for a in self.attributes:
+ s += "<li>" + a + " = " + self.attributes[a] + "</li>"
+
+ s += "</ul></td></tr>\n"
+
+ for c in self.children:
+ s += c.formatHTML(True)
+
+ if not amChild:
+ s += """</table>
+ </body>
+ </html>"""
+
+ return s
+
+ def addAttribute(self, attr, value):
+ """Add an attribute to this element"""
+ if type(value) != str: value = value.encode('utf-8')
+ self.attributes[attr] = value
+
+ def setAttribute(self, attr, value):
+ """Set an attributes value - in fact does the same thing as add
+ attribute
+
+ """
+ self.attributes[attr] = value
+
+ def setChars(self, chars):
+ """Set the characters for this element"""
+ self.chars = chars
+
+ def addChars(self, chars):
+ """Add characters (textual value) to this element"""
+ self.chars += chars
+
+ def addChild(self, child):
+ """Add a child element to this element"""
+ self.children.append(child)
+ return self.children[len(self.children) - 1]
+
+ def getParent(self):
+ """Get the parent of this element (Could be None)"""
+ return self.parent
+
+ def getChild(self, name):
+ """Returns the first child element named 'name'
+
+ Keywords:
+ name -- The name of the child element to return"""
+ for child in self.children:
+ if child.name == name:
+ return child
+ return None
+
+ def getChildren(self, name=None):
+ if name:
+ # return _all_ children named "name"
+ ret = []
+ for child in self.children:
+ if child.name == name:
+ ret.append(child)
+ return ret
+ else:
+ return self.children
+
+ def get(self, elemName, attribute="", attrmatch=""):
+ """Return the text data for either an attribute or an xmlElement
+ """
+ if (self.name == elemName):
+ if attribute != "":
+ try:
+ if attrmatch != "":
+ if self.attributes[attribute] == attrmatch:
+ ret = self.chars
+ if type(ret) != str: ret = ret.encode('utf-8')
+ return ret
+ else:
+ ret = self.attributes[attribute]
+ if type(ret) != str: ret = ret.encode('utf-8')
+ return ret
+ except AttributeError:
+ ret = ""
+ if type(ret) != str: ret = ret.encode('utf-8')
+ return ret
+ else:
+ ret = self.chars
+ if type(ret) != str: ret = ret.encode('utf-8')
+ return ret
+
+ for child in self.children:
+ ret = child.get(elemName, attribute, attrmatch)
+ if ret != "":
+ if type(ret) != str: ret = ret.encode('utf-8')
+ return ret
+
+ ret = ""
+ if type(ret) != str: ret = ret.encode('utf-8')
+ return ret
+
+
+
+class libpart():
+ """Class for a library part, aka 'libpart' in the xml netlist file.
+ (Components in eeschema are instantiated from library parts.)
+ This part class is implemented by wrapping an xmlElement with accessors.
+ This xmlElement instance is held in field 'element'.
+ """
+ def __init__(self, xml_element):
+ #
+ self.element = xml_element
+
+ #def __str__(self):
+ # simply print the xmlElement associated with this part
+ #return str(self.element)
+
+ def getLibName(self):
+ return self.element.get("libpart", "lib")
+
+ def getPartName(self):
+ return self.element.get("libpart", "part")
+
+ def getDescription(self):
+ return self.element.get("description")
+
+ def getField(self, name):
+ return self.element.get("field", "name", name)
+
+ def getFieldNames(self):
+ """Return a list of field names in play for this libpart.
+ """
+ fieldNames = []
+ fields = self.element.getChild('fields')
+ if fields:
+ for f in fields.getChildren():
+ fieldNames.append( f.get('field','name') )
+ return fieldNames
+
+ def getDatasheet(self):
+ return self.getField("Datasheet")
+
+ def getFootprint(self):
+ return self.getField("Footprint")
+
+ def getAliases(self):
+ """Return a list of aliases or None"""
+ aliases = self.element.getChild("aliases")
+ if aliases:
+ ret = []
+ children = aliases.getChildren()
+ # grab the text out of each child:
+ for child in children:
+ ret.append( child.get("alias") )
+ return ret
+ return None
+
+
+class comp():
+ """Class for a component, aka 'comp' in the xml netlist file.
+ This component class is implemented by wrapping an xmlElement instance
+ with accessors. The xmlElement is held in field 'element'.
+ """
+
+ def __init__(self, xml_element):
+ self.element = xml_element
+ self.libpart = None
+
+ # Set to true when this component is included in a component group
+ self.grouped = False
+
+ def __eq__(self, other):
+ """ Equivalency operator, remember this can be easily overloaded
+ 2 components are equivalent ( i.e. can be grouped
+ if they have same value and same footprint
+
+ Override the component equivalence operator must be done before
+ loading the netlist, otherwise all components will have the original
+ equivalency operator.
+
+ You have to define a comparison module (for instance named myEqu)
+ and add the line;
+ kicad_netlist_reader.comp.__eq__ = myEqu
+ in your bom generator script before calling the netliste reader by something like:
+ net = kicad_netlist_reader.netlist(sys.argv[1])
+ """
+ result = False
+ if self.getValue() == other.getValue():
+ if self.getFootprint() == other.getFootprint():
+ result = True
+ return result
+
+ def setLibPart(self, part):
+ self.libpart = part
+
+ def getLibPart(self):
+ return self.libpart
+
+ def getPartName(self):
+ return self.element.get("libsource", "part")
+
+ def getLibName(self):
+ return self.element.get("libsource", "lib")
+
+ def setValue(self, value):
+ """Set the value of this component"""
+ v = self.element.getChild("value")
+ if v:
+ v.setChars(value)
+
+ def getValue(self):
+ return self.element.get("value")
+
+ def getField(self, name, libraryToo=True):
+ """Return the value of a field named name. The component is first
+ checked for the field, and then the components library part is checked
+ for the field. If the field doesn't exist in either, an empty string is
+ returned
+
+ Keywords:
+ name -- The name of the field to return the value for
+ libraryToo -- look in the libpart's fields for the same name if not found
+ in component itself
+ """
+
+ field = self.element.get("field", "name", name)
+ if field == "" and libraryToo:
+ field = self.libpart.getField(name)
+ return field
+
+ def getFieldNames(self):
+ """Return a list of field names in play for this component. Mandatory
+ fields are not included, and they are: Value, Footprint, Datasheet, Ref.
+ The netlist format only includes fields with non-empty values. So if a field
+ is empty, it will not be present in the returned list.
+ """
+ fieldNames = []
+ fields = self.element.getChild('fields')
+ if fields:
+ for f in fields.getChildren():
+ fieldNames.append( f.get('field','name') )
+ return fieldNames
+
+ def getRef(self):
+ return self.element.get("comp", "ref")
+
+ def getFootprint(self, libraryToo=True):
+ ret = self.element.get("footprint")
+ if ret =="" and libraryToo:
+ ret = self.libpart.getFootprint()
+ return ret
+
+ def getDatasheet(self, libraryToo=True):
+ ret = self.element.get("datasheet")
+ if ret == '' and libraryToo:
+ ret = self.libpart.getDatasheet()
+ return ret
+
+ def getTimestamp(self):
+ return self.element.get("tstamp")
+
+ def getDescription(self):
+ return self.libpart.getDescription()
+
+
+class netlist():
+ """ Kicad generic netlist class. Generally loaded from a kicad generic
+ netlist file. Includes several helper functions to ease BOM creating
+ scripts
+
+ """
+ def __init__(self, fname=""):
+ """Initialiser for the genericNetlist class
+
+ Keywords:
+ fname -- The name of the generic netlist file to open (Optional)
+
+ """
+ self.design = None
+ self.components = []
+ self.libparts = []
+ self.libraries = []
+ self.nets = []
+
+ # The entire tree is loaded into self.tree
+ self.tree = []
+
+ self._curr_element = None
+
+ # component blacklist regexs, made from exluded_* above.
+ self.excluded_references = []
+ self.excluded_values = []
+ self.excluded_footprints = []
+
+ if fname != "":
+ self.load(fname)
+
+ def addChars(self, content):
+ """Add characters to the current element"""
+ self._curr_element.addChars(content)
+
+ def addElement(self, name):
+ """Add a new kicad generic element to the list"""
+ if self._curr_element == None:
+ self.tree = xmlElement(name)
+ self._curr_element = self.tree
+ else:
+ self._curr_element = self._curr_element.addChild(
+ xmlElement(name, self._curr_element))
+
+ # If this element is a component, add it to the components list
+ if self._curr_element.name == "comp":
+ self.components.append(comp(self._curr_element))
+
+ # Assign the design element
+ if self._curr_element.name == "design":
+ self.design = self._curr_element
+
+ # If this element is a library part, add it to the parts list
+ if self._curr_element.name == "libpart":
+ self.libparts.append(libpart(self._curr_element))
+
+ # If this element is a net, add it to the nets list
+ if self._curr_element.name == "net":
+ self.nets.append(self._curr_element)
+
+ # If this element is a library, add it to the libraries list
+ if self._curr_element.name == "library":
+ self.libraries.append(self._curr_element)
+
+ return self._curr_element
+
+ def endDocument(self):
+ """Called when the netlist document has been fully parsed"""
+ # When the document is complete, the library parts must be linked to
+ # the components as they are seperate in the tree so as not to
+ # duplicate library part information for every component
+ for c in self.components:
+ for p in self.libparts:
+ if p.getLibName() == c.getLibName():
+ if p.getPartName() == c.getPartName():
+ c.setLibPart(p)
+ break
+ else:
+ aliases = p.getAliases()
+ if aliases and self.aliasMatch( c.getPartName(), aliases ):
+ c.setLibPart(p)
+ break;
+
+ if not c.getLibPart():
+ print( 'missing libpart for ref:', c.getRef(), c.getPartName(), c.getLibName() )
+
+
+ def aliasMatch(self, partName, aliasList):
+ for alias in aliasList:
+ if partName == alias:
+ return True
+ return False
+
+ def endElement(self):
+ """End the current element and switch to its parent"""
+ self._curr_element = self._curr_element.getParent()
+
+ def getDate(self):
+ """Return the date + time string generated by the tree creation tool"""
+ return self.design.get("date")
+
+ def getSource(self):
+ """Return the source string for the design"""
+ return self.design.get("source")
+
+ def getTool(self):
+ """Return the tool string which was used to create the netlist tree"""
+ return self.design.get("tool")
+
+ def gatherComponentFieldUnion(self, components=None):
+ """Gather the complete 'set' of unique component fields, fields found in any component.
+ """
+ if not components:
+ components=self.components
+
+ s = set()
+ for c in components:
+ s.update( c.getFieldNames() )
+
+ # omit anything matching any regex in excluded_fields
+ ret = set()
+ for field in s:
+ exclude = False
+ for rex in excluded_fields:
+ if re.match( rex, field ):
+ exclude = True
+ break
+ if not exclude:
+ ret.add(field)
+
+ return ret # this is a python 'set'
+
+ def gatherLibPartFieldUnion(self):
+ """Gather the complete 'set' of part fields, fields found in any part.
+ """
+ s = set()
+ for p in self.libparts:
+ s.update( p.getFieldNames() )
+
+ # omit anything matching any regex in excluded_fields
+ ret = set()
+ for field in s:
+ exclude = False
+ for rex in excluded_fields:
+ if re.match( rex, field ):
+ exclude = True
+ break
+ if not exclude:
+ ret.add(field)
+
+ return ret # this is a python 'set'
+
+ def getInterestingComponents(self):
+ """Return a subset of all components, those that should show up in the BOM.
+ Omit those that should not, by consulting the blacklists:
+ excluded_values, excluded_refs, and excluded_footprints, which hold one
+ or more regular expressions. If any of the the regular expressions match
+ the corresponding field's value in a component, then the component is exluded.
+ """
+
+ # pre-compile all the regex expressions:
+ del self.excluded_references[:]
+ del self.excluded_values[:]
+ del self.excluded_footprints[:]
+
+ for rex in excluded_references:
+ self.excluded_references.append( re.compile( rex ) )
+
+ for rex in excluded_values:
+ self.excluded_values.append( re.compile( rex ) )
+
+ for rex in excluded_footprints:
+ self.excluded_footprints.append( re.compile( rex ) )
+
+ # the subset of components to return, considered as "interesting".
+ ret = []
+
+ # run each component thru a series of tests, if it passes all, then add it
+ # to the interesting list 'ret'.
+ for c in self.components:
+ exclude = False
+ if not exclude:
+ for refs in self.excluded_references:
+ if refs.match(c.getRef()):
+ exclude = True
+ break;
+ if not exclude:
+ for vals in self.excluded_values:
+ if vals.match(c.getValue()):
+ exclude = True
+ break;
+ if not exclude:
+ for mods in self.excluded_footprints:
+ if mods.match(c.getFootprint()):
+ exclude = True
+ break;
+
+ if not exclude:
+ # This is a fairly personal way to flag DNS (Do Not Stuff). NU for
+ # me means Normally Uninstalled. You can 'or in' another expression here.
+ if c.getField( "Installed" ) == 'NU':
+ exclude = True
+
+ if not exclude:
+ ret.append(c)
+
+ # Sort first by ref as this makes for easier to read BOM's
+ def f(v):
+ return re.sub(r'([A-z]+)[0-9]+', r'\1', v) + '%08i' % int(re.sub(r'[A-z]+([0-9]+)', r'\1', v))
+ ret.sort(key=lambda g: f(g.getRef()))
+
+ return ret
+
+
+ def groupComponents(self, components = None):
+ """Return a list of component lists. Components are grouped together
+ when the value, library and part identifiers match.
+
+ Keywords:
+ components -- is a list of components, typically an interesting subset
+ of all components, or None. If None, then all components are looked at.
+ """
+ if not components:
+ components = self.components
+
+ groups = []
+
+ # Make sure to start off will all components ungrouped to begin with
+ for c in components:
+ c.grouped = False
+
+ # Group components based on the value, library and part identifiers
+ for c in components:
+ if c.grouped == False:
+ c.grouped = True
+ newgroup = []
+ newgroup.append(c)
+
+ # Check every other ungrouped component against this component
+ # and add to the group as necessary
+ for ci in components:
+ if ci.grouped == False and ci == c:
+ newgroup.append(ci)
+ ci.grouped = True
+
+ # Add the new component group to the groups list
+ groups.append(newgroup)
+
+ # Each group is a list of components, we need to sort each list first
+ # to get them in order as this makes for easier to read BOM's
+ def f(v):
+ return re.sub(r'([A-z]+)[0-9]+', r'\1', v) + '%08i' % int(re.sub(r'[A-z]+([0-9]+)', r'\1', v))
+ for g in groups:
+ g = sorted(g, key=lambda g: f(g.getRef()))
+
+ # Finally, sort the groups to order the references alphabetically
+ groups = sorted(groups, key=lambda group: f(group[0].getRef()))
+
+ return groups
+
+ def getGroupField(self, group, field):
+ """Return the whatever is known about the given field by consulting each
+ component in the group. If any of them know something about the property/field,
+ then return that first non-blank value.
+ """
+ for c in group:
+ ret = c.getField(field, False)
+ if ret != '':
+ return ret
+ return group[0].getLibPart().getField(field)
+
+ def getGroupFootprint(self, group):
+ """Return the whatever is known about the Footprint by consulting each
+ component in the group. If any of them know something about the Footprint,
+ then return that first non-blank value.
+ """
+ for c in group:
+ ret = c.getFootprint()
+ if ret != "":
+ return ret
+ return group[0].getLibPart().getFootprint()
+
+ def getGroupDatasheet(self, group):
+ """Return the whatever is known about the Datasheet by consulting each
+ component in the group. If any of them know something about the Datasheet,
+ then return that first non-blank value.
+ """
+ for c in group:
+ ret = c.getDatasheet()
+ if ret != "":
+ return ret
+
+ if len(group) > 0:
+ return group[0].getLibPart().getDatasheet()
+ else:
+ print("NULL!")
+ return ''
+
+ def formatXML(self):
+ """Return the whole netlist formatted in XML"""
+ return self.tree.formatXML()
+
+ def formatHTML(self):
+ """Return the whole netlist formatted in HTML"""
+ return self.tree.formatHTML()
+
+ def load(self, fname):
+ """Load a kicad generic netlist
+
+ Keywords:
+ fname -- The name of the generic netlist file to open
+
+ """
+ try:
+ self._reader = sax.make_parser()
+ self._reader.setContentHandler(_gNetReader(self))
+ self._reader.parse(fname)
+ except IOError as e:
+ print( __file__, ":", e, file=sys.stderr )
+ sys.exit(-1)
+
+
+
+class _gNetReader(sax.handler.ContentHandler):
+ """SAX kicad generic netlist content handler - passes most of the work back
+ to the 'netlist' class which builds a complete tree in RAM for the design
+
+ """
+ def __init__(self, aParent):
+ self.parent = aParent
+
+ def startElement(self, name, attrs):
+ """Start of a new XML element event"""
+ element = self.parent.addElement(name)
+
+ for name in attrs.getNames():
+ element.addAttribute(name, attrs.getValue(name))
+
+ def endElement(self, name):
+ self.parent.endElement()
+
+ def characters(self, content):
+ # Ignore erroneous white space - ignoreableWhitespace does not get rid
+ # of the need for this!
+ if not content.isspace():
+ self.parent.addChars(content)
+
+ def endDocument(self):
+ """End of the XML document event"""
+ self.parent.endDocument()
diff --git a/eeschema/plugins/python_scripts/round_robin.py b/eeschema/plugins/python_scripts/round_robin.py
new file mode 100644
index 0000000..0f15e6f
--- /dev/null
+++ b/eeschema/plugins/python_scripts/round_robin.py
@@ -0,0 +1,28 @@
+#
+# Example python script to generate an equivalent XML document from XML input
+#
+# Example: Round robin, XML to XML conversion
+#
+
+from __future__ import print_function
+
+# Import the KiCad python helper module and the csv formatter
+import kicad_netlist_reader
+import sys
+import pdb
+
+
+# Generate an instance of a generic netlist, and load the netlist tree from
+# the command line option. If the file doesn't exist, execution will stop
+net = kicad_netlist_reader.netlist(sys.argv[1])
+
+# Open a file to write to, if the file cannot be opened output to stdout
+# instead
+try:
+ f = open(sys.argv[2], 'w')
+except IOError:
+ e = "Can't open output file for writing: " + sys.argv[2]
+ print( __file__, ":", e, sys.stderr)
+ f = sys.stdout
+
+print(net.formatXML(), file=f)
diff --git a/eeschema/plugins/python_scripts/round_value_robin.py b/eeschema/plugins/python_scripts/round_value_robin.py
new file mode 100644
index 0000000..e1bf3ff
--- /dev/null
+++ b/eeschema/plugins/python_scripts/round_value_robin.py
@@ -0,0 +1,74 @@
+#
+# Example python script to generate an equivalent XML document from XML input
+#
+# Example: Round value robin, XML to XML conversion with partial value monging
+#
+
+from __future__ import print_function
+
+# Import the KiCad python helper module and the csv formatter
+import kicad_netlist_reader
+import sys
+
+def checkvalue(self):
+ """Check values, and replace with preferred/consistent values"""
+ ref = self.getRef()
+ r = ref.split("R")
+ c = ref.split("C")
+ v = self.getValue()
+
+ # Common to all values - convert decimation if necessary
+ dec = v.split(",")
+ if (len(dec) == 2):
+ newval = dec[0] + "." + dec[1]
+ self.setValue(newval)
+ v = self.getValue()
+
+ if len(r) == 2 and r[1].isdigit():
+ # This is a resistor - make values consistent
+ # If the value is a pure value, add R to the end of the value
+ if v.isdigit():
+ i = int(v)
+ if (i > 1000000):
+ i = i / 1000000
+ v = str(i) + "M"
+ if (i > 1000):
+ i = i / 1000
+ v = str(i) + "K"
+ else:
+ v = str(i) + "R"
+
+ self.setValue(v)
+ else:
+ # Get the multiplier character
+ multiplier = v[len(v) - 1]
+ v = v.strip(multiplier)
+ v = v.split(".")
+ if (len(v) == 2):
+ newval = v[0] + multiplier + v[1]
+ self.setValue(newval)
+ v = self.getValue()
+
+
+
+# Give components a new method for checking the values (this could easily be a
+# Company Part Number generator method instead)
+kicad_netlist_reader.comp.checkvalue = checkvalue
+
+# Generate an instance of a generic netlist, and load the netlist tree from
+# the command line option. If the file doesn't exist, execution will stop
+net = kicad_netlist_reader.netlist(sys.argv[1])
+
+# Open a file to write to, if the file cannot be opened output to stdout
+# instead
+try:
+ f = open(sys.argv[2], 'w')
+except IOError:
+ e = "Can't open output file for writing: " + sys.argv[2]
+ print(__file__, ":", e, file=sys.stderr)
+ f = sys.stdout
+
+for c in net.components:
+ c.checkvalue()
+
+print(net.formatXML(), file=f)
diff --git a/eeschema/plugins/xsl_scripts/bom2csv.xsl b/eeschema/plugins/xsl_scripts/bom2csv.xsl
new file mode 100644
index 0000000..67d588b
--- /dev/null
+++ b/eeschema/plugins/xsl_scripts/bom2csv.xsl
@@ -0,0 +1,99 @@
+<!--XSL style sheet to convert EESCHEMA XML Partlist Format to CSV BOM Format
+ Copyright (C) 2013, Stefan Helmert.
+ GPL v2.
+
+ Functionality:
+ Generation of csv table with table head of all existing field names
+ and correct assigned cell entries
+
+ How to use this is explained in eeschema.pdf chapter 14. You enter a command line into the
+ netlist exporter using a new (custom) tab in the netlist export dialog. The command is
+ similar to
+ on Windows:
+ xsltproc -o "%O.csv" "C:\Program Files (x86)\KiCad\bin\plugins\bom2csv.xsl" "%I"
+ on Linux:
+ xsltproc -o "%O.csv" /usr/local/lib/kicad/plugins/bom2csv.xsl "%I"
+
+ Instead of "%O.csv" you can alternatively use "%O" if you will supply your own file extension when
+ prompted in the UI. The double quotes are there to account for the possibility of space(s)
+ in the filename.
+-->
+
+<!--
+ @package
+ Generate a Tab delimited list (csv file type).
+ One component per line
+ Fields are
+ Ref,Value, Footprint, Datasheet, Field5, Field4, price
+
+ Command line
+ xsltproc -o "%O.csv" "pathToFile/bom2csv.xsl" "%I"
+-->
+
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY nl "&#xd;&#xa;"> <!--new line CR, LF, or LF, your choice -->
+]>
+
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="text"/>
+
+ <!-- for table head and empty table fields-->
+ <xsl:key name="headentr" match="field" use="@name"/>
+
+ <!-- main part -->
+ <xsl:template match="/export">
+ <xsl:text>Reference, Value, Footprint, Datasheet</xsl:text>
+
+ <!-- find all existing table head entries and list each one once -->
+ <xsl:for-each select="components/comp/fields/field[generate-id(.) = generate-id(key('headentr',@name)[1])]">
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="@name"/>
+ </xsl:for-each>
+ <xsl:text>&nl;</xsl:text>
+
+ <!-- all table entries -->
+ <xsl:apply-templates select="components/comp"/>
+ </xsl:template>
+
+ <!-- the table entries -->
+ <xsl:template match="components/comp">
+ <xsl:text>"</xsl:text>
+ <xsl:value-of select="@ref"/><xsl:text>","</xsl:text>
+ <xsl:value-of select="value"/><xsl:text>","</xsl:text>
+ <xsl:value-of select="footprint"/><xsl:text>","</xsl:text>
+ <xsl:value-of select="datasheet"/><xsl:text>"</xsl:text>
+ <xsl:apply-templates select="fields"/>
+ <xsl:text>&nl;</xsl:text>
+ </xsl:template>
+
+ <!-- table entries with dynamic table head -->
+ <xsl:template match="fields">
+
+ <!-- remember current fields section -->
+ <xsl:variable name="fieldvar" select="field"/>
+
+ <!-- for all existing head entries -->
+ <xsl:for-each select="/export/components/comp/fields/field[generate-id(.) = generate-id(key('headentr',@name)[1])]">
+ <xsl:variable name="allnames" select="@name"/>
+ <xsl:text>,"</xsl:text>
+
+ <!-- for all field entries in the remembered fields section -->
+ <xsl:for-each select="$fieldvar">
+
+ <!-- only if this field entry exists in this fields section -->
+ <xsl:if test="@name=$allnames">
+ <!-- content of the field -->
+ <xsl:value-of select="."/>
+ </xsl:if>
+ <!--
+ If it does not exist, use an empty cell in output for this row.
+ Every non-blank entry is assigned to its proper column.
+ -->
+ </xsl:for-each>
+
+ <xsl:text>"</xsl:text>
+ </xsl:for-each>
+ </xsl:template>
+
+ </xsl:stylesheet>
diff --git a/eeschema/plugins/xsl_scripts/bom2grouped_csv.xsl b/eeschema/plugins/xsl_scripts/bom2grouped_csv.xsl
new file mode 100644
index 0000000..e9b8446
--- /dev/null
+++ b/eeschema/plugins/xsl_scripts/bom2grouped_csv.xsl
@@ -0,0 +1,104 @@
+<!--XSL style sheet to convert EESCHEMA XML Partlist Format to grouped CSV BOM Format
+ Copyright (C) 2014, Wolf Walter.
+ Copyright (C) 2013, Stefan Helmert.
+ GPL v2.
+
+ Functionality:
+ Generation of Digi-Key ordering system compatible BOM
+
+ How to use this is explained in eeschema.pdf chapter 14. You enter a command line into the
+ netlist exporter using a new (custom) tab in the netlist export dialog.
+ The command line is
+ xsltproc -o "%O.csv" "FullPathToFile/bom2groupedCsv.xsl" "%I"
+-->
+<!--
+ @package
+ Functionality:
+ * Generate a comma separated value BOM list (csv file type).
+ * Components are sorted by ref and grouped by same value+footprint
+ One value per line
+ Fields are
+ Reference, Quantity, Value, Footprint, Datasheet
+
+ The command line is
+ xsltproc -o "%O.csv" "FullPathToFile/bom2groupedCsv.xsl" "%I"
+-->
+
+
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY nl "&#xd;&#xa;"> <!--new line CR, LF, or LF, your choice -->
+]>
+
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="text"/>
+
+ <!-- for Muenchian grouping of footprint and value combination -->
+ <xsl:key name="partTypeByValueAndFootprint" match="comp" use="concat(footprint, '-', value)" />
+
+ <!-- for table head and empty table fields-->
+ <xsl:key name="headentr" match="field" use="@name"/>
+
+ <!-- main part -->
+ <xsl:template match="/export">
+ <xsl:text>Reference, Quantity, Value, Footprint, Datasheet</xsl:text>
+
+ <!-- find all existing table head entries and list each one once -->
+ <xsl:for-each select="components/comp/fields/field[generate-id(.) = generate-id(key('headentr',@name)[1])]">
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="@name"/>
+ </xsl:for-each>
+
+ <!-- all table entries -->
+ <xsl:apply-templates select="components"/>
+ </xsl:template>
+
+ <xsl:template match="components">
+ <!-- for Muenchian grouping of footprint and value combination -->
+ <xsl:for-each select="comp[count(. | key('partTypeByValueAndFootprint', concat(footprint, '-', value))[1]) = 1]">
+ <xsl:sort select="@ref" />
+ <xsl:text>&nl;</xsl:text>
+ <!-- list of all references -->
+ <xsl:for-each select="key('partTypeByValueAndFootprint', concat(footprint, '-', value))">
+ <xsl:sort select="@ref" />
+ <xsl:value-of select="@ref"/><xsl:text> </xsl:text>
+ </xsl:for-each><xsl:text>,</xsl:text>
+ <!-- quantity of parts with same footprint and value -->
+ <xsl:value-of select="count(key('partTypeByValueAndFootprint', concat(footprint, '-', value)))"/><xsl:text>,</xsl:text>
+ <xsl:text>"</xsl:text>
+ <xsl:value-of select="value"/><xsl:text>","</xsl:text>
+ <xsl:value-of select="footprint"/><xsl:text>","</xsl:text>
+ <xsl:value-of select="datasheet"/><xsl:text>"</xsl:text>
+ <xsl:apply-templates select="fields"/>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- table entries with dynamic table head -->
+ <xsl:template match="fields">
+
+ <!-- remember current fields section -->
+ <xsl:variable name="fieldvar" select="field"/>
+
+ <!-- for all existing head entries -->
+ <xsl:for-each select="/export/components/comp/fields/field[generate-id(.) = generate-id(key('headentr',@name)[1])]">
+ <xsl:variable name="allnames" select="@name"/>
+ <xsl:text>,"</xsl:text>
+
+ <!-- for all field entries in the remembered fields section -->
+ <xsl:for-each select="$fieldvar">
+
+ <!-- only if this field entry exists in this fields section -->
+ <xsl:if test="@name=$allnames">
+ <!-- content of the field -->
+ <xsl:value-of select="."/>
+ <xsl:text>"</xsl:text>
+ </xsl:if>
+ <!--
+ If it does not exist, use an empty cell in output for this row.
+ Every non-blank entry is assigned to its proper column.
+ -->
+ </xsl:for-each>
+ </xsl:for-each>
+ </xsl:template>
+
+ </xsl:stylesheet> \ No newline at end of file
diff --git a/eeschema/plugins/xsl_scripts/bom_with_title_block_2_csv.xsl b/eeschema/plugins/xsl_scripts/bom_with_title_block_2_csv.xsl
new file mode 100644
index 0000000..feed1ce
--- /dev/null
+++ b/eeschema/plugins/xsl_scripts/bom_with_title_block_2_csv.xsl
@@ -0,0 +1,167 @@
+<!--
+ EESCHEMA BOM plugin. Creates BOM CSV files from the project net file.
+ Based on Stefan Helmert bom2csv.xsl
+
+ Note:
+ The project infomation (i.e title, company and revision) is taken from the root sheet.
+
+ Arthur:
+ Ronald Sousa HashDefineElectronics.com
+
+ Ouput Example:
+ Source,
+ Kicad Rev, working director and file source
+ Generated Date, date this file was generated
+
+ Title, the project's title
+ Company, the project's company
+ Rev, the project's revision
+ Date Source, project's issue date
+ Comment, This is comment 1
+ Comment, This is comment 2
+ Comment, This is comment 3
+ Comment, This is comment 4
+-->
+<!--
+ @package
+ Output format
+ Reference, Value, Fields[n], Library, Library Ref
+ U1, PIC32MX, Fields[n], KicadLib, PIC
+
+Command line:
+ xsltproc -o "%O.csv" "pathToFile/bom2csv.xsl" "%I"
+-->
+
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY nl "&#xd;&#xa;"> <!--new line CR, LF, or LF, your choice -->
+]>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output method="text"/>
+
+ <!-- for table head and empty table fields-->
+ <xsl:key name="headentr" match="field" use="@name"/>
+
+ <!-- main part -->
+ <xsl:template match="/export">
+ <xsl:text>Source,</xsl:text><xsl:value-of select="design/source"/><xsl:text>&nl;</xsl:text>
+ <xsl:text>Kicad Rev,</xsl:text><xsl:value-of select="design/tool"/><xsl:text>&nl;</xsl:text>
+ <xsl:text>Generated Date,</xsl:text><xsl:value-of select="design/date"/><xsl:text>&nl;</xsl:text>
+
+ <xsl:text>&nl;</xsl:text>
+
+ <!-- Ouput Root sheet project information -->
+ <xsl:apply-templates select="/export/design/sheet[1]"/>
+
+ <xsl:text>&nl;</xsl:text>
+
+ <!-- Output table header -->
+ <xsl:text>Reference,Value,</xsl:text>
+ <xsl:for-each select="components/comp/fields/field[generate-id(.) = generate-id(key('headentr',@name)[1])]">
+ <xsl:value-of select="@name"/>
+ <xsl:text>,</xsl:text>
+ </xsl:for-each>
+ <xsl:text>Library,Library Ref</xsl:text>
+ <xsl:text>&nl;</xsl:text>
+
+ <!-- all table entries -->
+ <xsl:apply-templates select="components/comp"/>
+ </xsl:template>
+
+ <!-- generate the Root sheet project information -->
+ <xsl:template match="/export/design/sheet[1]">
+
+ <xsl:choose>
+ <xsl:when test="title_block/title !=''">
+ <xsl:text>Title,</xsl:text><xsl:value-of select="title_block/title"/><xsl:text>&nl;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>Title,Not Set</xsl:text><xsl:text>&nl;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+
+
+ <xsl:choose>
+ <xsl:when test="title_block/company !=''">
+ <xsl:text>Company,</xsl:text><xsl:value-of select="title_block/company"/><xsl:text>&nl;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>Company,Not Set</xsl:text><xsl:text>&nl;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="title_block/rev !=''">
+ <xsl:text>Revision,</xsl:text><xsl:value-of select="title_block/rev"/><xsl:text>&nl;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>Revision,Not Set</xsl:text><xsl:text>&nl;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="title_block/date !=''">
+ <xsl:text>Date Issue,</xsl:text><xsl:value-of select="title_block/date"/><xsl:text>&nl;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>Date Issue,Not Set</xsl:text><xsl:text>&nl;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:apply-templates select="title_block/comment"/>
+
+ </xsl:template>
+
+ <xsl:template match="title_block/comment">
+ <xsl:choose>
+ <xsl:when test="@value !=''">
+ <xsl:text>Comment,</xsl:text><xsl:value-of select="@value"/><xsl:text>&nl;</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:template>
+
+
+
+ <!-- the table entries -->
+ <xsl:template match="components/comp">
+ <xsl:value-of select="@ref"/><xsl:text>,</xsl:text>
+ <xsl:value-of select="value"/><xsl:text>,</xsl:text>
+ <xsl:apply-templates select="fields"/>
+ <xsl:apply-templates select="libsource"/>
+ <xsl:text>&nl;</xsl:text>
+ </xsl:template>
+
+ <!-- the library selection -->
+ <xsl:template match="libsource">
+ <xsl:value-of select="@lib"/><xsl:text>,</xsl:text>
+ <xsl:value-of select="@part"/>
+ </xsl:template>
+
+ <!-- table entries with dynamic table head -->
+ <xsl:template match="fields">
+
+ <!-- remember current fields section -->
+ <xsl:variable name="fieldvar" select="field"/>
+
+ <!-- for all existing head entries -->
+ <xsl:for-each select="/export/components/comp/fields/field[generate-id(.) = generate-id(key('headentr',@name)[1])]">
+ <xsl:variable name="allnames" select="@name"/>
+
+ <!-- for all field entries in the remembered fields section -->
+ <xsl:for-each select="$fieldvar">
+
+ <!-- only if this field entry exists in this fields section -->
+ <xsl:if test="@name=$allnames">
+ <!-- content of the field -->
+ <xsl:value-of select="."/>
+ </xsl:if>
+ <!--
+ If it does not exist, use an empty cell in output for this row.
+ Every non-blank entry is assigned to its proper column.
+ -->
+ </xsl:for-each>
+ <xsl:text>,</xsl:text>
+ </xsl:for-each>
+ </xsl:template>
+
+ </xsl:stylesheet>
diff --git a/eeschema/plugins/xsl_scripts/netlist_form_OrcadPcb2.xsl b/eeschema/plugins/xsl_scripts/netlist_form_OrcadPcb2.xsl
new file mode 100644
index 0000000..3017711
--- /dev/null
+++ b/eeschema/plugins/xsl_scripts/netlist_form_OrcadPcb2.xsl
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--XSL style sheet to EESCHEMA Generic Netlist Format to CADSTAR netlist format
+ Copyright (C) 2010, SoftPLC Corporation.
+ GPL v2.
+
+ How to use:
+ see eeschema.pdf, chapter 14
+-->
+
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY nl "&#xd;&#xa;"> <!--new line CR, LF -->
+]>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
+
+<!--
+ Netlist header
+ Creates the entire netlist
+ (can be seen as equivalent to main function in C
+-->
+<xsl:template match="/export">
+ <xsl:text>( { EESchema Netlist Version 1.1 </xsl:text>
+ <!-- Generate line .TIM <time> -->
+ <xsl:apply-templates select="design/date"/>
+ <!-- Generate line eeschema version ... -->
+ <xsl:apply-templates select="design/tool"/>
+ <xsl:text>}&nl;</xsl:text>
+
+ <!-- Generate the list of components -->
+ <xsl:apply-templates select="components/comp"/> <!-- Generate list of components -->
+
+ <!-- end of file -->
+ <xsl:text>)&nl;*&nl;</xsl:text>
+</xsl:template>
+
+<!--
+ Generate id in header like "eeschema (2010-08-17 BZR 2450)-unstable"
+-->
+<xsl:template match="tool">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<!--
+ Generate date in header like "20/08/2010 10:45:33"
+-->
+<xsl:template match="date">
+ <xsl:apply-templates/>
+ <xsl:text>&nl;</xsl:text>
+</xsl:template>
+
+<!--
+ This template read each component
+ (path = /export/components/comp)
+ creates lines:
+ ( 3EBF7DBD $noname U1 74LS125
+ ... pin list ...
+ )
+ and calls "create_pin_list" template to build the pin list
+-->
+<xsl:template match="comp">
+ <xsl:text> ( </xsl:text>
+ <xsl:choose>
+ <xsl:when test = "tstamp != '' ">
+ <xsl:apply-templates select="tstamp"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>00000000</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text> </xsl:text>
+ <xsl:choose>
+ <xsl:when test = "footprint != '' ">
+ <xsl:apply-templates select="footprint"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>$noname</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@ref"/>
+ <xsl:text> </xsl:text>
+ <xsl:choose>
+ <xsl:when test = "value != '' ">
+ <xsl:apply-templates select="value"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>"~"</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>&nl;</xsl:text>
+ <xsl:call-template name="Search_pin_list" >
+ <xsl:with-param name="cmplib_id" select="libsource/@part"/>
+ <xsl:with-param name="cmp_ref" select="@ref"/>
+ </xsl:call-template>
+ <xsl:text> )&nl;</xsl:text>
+</xsl:template>
+
+<!--
+ This template search for a given lib component description in list
+ lib component descriptions are in /export/libparts,
+ and each description start at ./libpart
+ We search here for the list of pins of the given component
+ This template has 2 parameters:
+ "cmplib_id" (reference in libparts)
+ "cmp_ref" (schematic reference of the given component)
+-->
+<xsl:template name="Search_pin_list" >
+ <xsl:param name="cmplib_id" select="0" />
+ <xsl:param name="cmp_ref" select="0" />
+ <xsl:for-each select="/export/libparts/libpart">
+ <xsl:if test = "@part = $cmplib_id ">
+ <xsl:apply-templates name="build_pin_list" select="pins/pin">
+ <xsl:with-param name="cmp_ref" select="$cmp_ref"/>
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+
+<!--
+ This template writes the pin list of a component
+ from the pin list of the library description
+ The pin list from library description is something like
+ <pins>
+ <pin num="1" type="passive"/>
+ <pin num="2" type="passive"/>
+ </pins>
+ Output pin list is ( <pin num> <net name> )
+ something like
+ ( 1 VCC )
+ ( 2 GND )
+-->
+<xsl:template name="build_pin_list" match="pin">
+ <xsl:param name="cmp_ref" select="0" />
+
+ <!-- write pin numner and separator -->
+ <xsl:text> ( </xsl:text>
+ <xsl:value-of select="@num"/>
+ <xsl:text> </xsl:text>
+
+ <!-- search net name in nets section and write it: -->
+ <xsl:variable name="pinNum" select="@num" />
+ <xsl:for-each select="/export/nets/net">
+ <!-- net name is output only if there is more than one pin in net
+ else use "?" as net name, so count items in this net
+ -->
+ <xsl:variable name="pinCnt" select="count(node)" />
+ <xsl:apply-templates name="Search_pin_netname" select="node">
+ <xsl:with-param name="cmp_ref" select="$cmp_ref"/>
+ <xsl:with-param name="pin_cnt_in_net" select="$pinCnt"/>
+ <xsl:with-param name="pin_num"> <xsl:value-of select="$pinNum"/>
+ </xsl:with-param>
+ </xsl:apply-templates>
+ </xsl:for-each>
+
+ <!-- close line -->
+ <xsl:text> )&nl;</xsl:text>
+</xsl:template>
+
+<!--
+ This template writes the pin netname of a given pin of a given component
+ from the nets list
+ The nets list description is something like
+ <nets>
+ <net code="1" name="GND">
+ <node ref="J1" pin="20"/>
+ <node ref="C2" pin="2"/>
+ </net>
+ <net code="2" name="">
+ <node ref="U2" pin="11"/>
+ </net>
+ </nets>
+ This template has 2 parameters:
+ "cmp_ref" (schematic reference of the given component)
+ "pin_num" (pin number)
+-->
+
+<xsl:template name="Search_pin_netname" match="node">
+ <xsl:param name="cmp_ref" select="0" />
+ <xsl:param name="pin_num" select="0" />
+ <xsl:param name="pin_cnt_in_net" select="0" />
+
+ <xsl:if test = "@ref = $cmp_ref ">
+ <xsl:if test = "@pin = $pin_num">
+ <!-- net name is output only if there is more than one pin in net
+ else use "?" as net name
+ -->
+ <xsl:if test = "$pin_cnt_in_net>1">
+ <xsl:choose>
+ <!-- if a net has a name, use it,
+ else build a name from its net code
+ -->
+ <xsl:when test = "../@name != '' ">
+ <xsl:value-of select="../@name"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>$N-0</xsl:text><xsl:value-of select="../@code"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ <xsl:if test = "$pin_cnt_in_net &lt;2">
+ <xsl:text>?</xsl:text>
+ </xsl:if>
+ </xsl:if>
+ </xsl:if>
+
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/eeschema/plugins/xsl_scripts/netlist_form_cadstar-RINF.xsl b/eeschema/plugins/xsl_scripts/netlist_form_cadstar-RINF.xsl
new file mode 100644
index 0000000..7df4b76
--- /dev/null
+++ b/eeschema/plugins/xsl_scripts/netlist_form_cadstar-RINF.xsl
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--XSL style sheet to EESCHEMA Generic Netlist Format to CADSTAR netlist format
+ Copyright (C) 2010, SoftPLC Corporation.
+ GPL v2.
+
+ How to use:
+ see eeschema.pdf, chapter 14
+-->
+
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY nl "&#xd;&#xa;"> <!--new line CR, LF -->
+]>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
+
+<!-- Netlist header -->
+<xsl:template match="/export">
+ <xsl:text>.HEA&nl;</xsl:text>
+ <xsl:apply-templates select="design/date"/> <!-- Generate line .TIM <time> -->
+ <xsl:apply-templates select="design/tool"/> <!-- Generate line .APP <eeschema version> -->
+ <xsl:text>&nl;</xsl:text>
+ <xsl:apply-templates select="components/comp"/> <!-- Generate list of components -->
+ <xsl:text>&nl;&nl;</xsl:text>
+ <xsl:apply-templates select="nets/net"/> <!-- Generate list of nets and connections -->
+ <xsl:text>&nl;.END&nl;</xsl:text>
+</xsl:template>
+
+ <!-- Generate line .APP "eeschema (2010-08-17 BZR 2450)-unstable" -->
+<xsl:template match="tool">
+ <xsl:text>.APP "</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>"&nl;</xsl:text>
+</xsl:template>
+
+ <!-- Generate line .TIM 20/08/2010 10:45:33 -->
+<xsl:template match="date">
+ <xsl:text>.TIM </xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&nl;</xsl:text>
+</xsl:template>
+
+<!-- for each component -->
+<!-- create lines like
+ .ADD_COM U3 74LS541 (when no footprint name specified)
+ .ADD_COM JP1 CONN_8X2 pin_array_8x2 pin_array_8x2 (with a specified footprint name)
+-->
+<xsl:template match="comp">
+ <xsl:text>.ADD_COM </xsl:text>
+ <xsl:value-of select="@ref"/>
+ <xsl:text> </xsl:text>
+ <xsl:choose>
+ <xsl:when test = "value != '' ">
+ <xsl:apply-templates select="value"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>?</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test = "footprint != '' ">
+ <xsl:text> </xsl:text>
+ <xsl:apply-templates select="footprint"/>
+ </xsl:when>
+ <xsl:otherwise>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>&nl;</xsl:text>
+</xsl:template>
+
+<!-- for each net -->
+<!-- create lines like
+.ADD_TER U3.9 /PC-RST
+.TER U3.8
+ BUS1.2
+.ADD_TER BUS1.14 /PC-IOR
+.TER U3.7
+-->
+<xsl:template match="net">
+ <!-- nets are output only if there is more than one pin in net -->
+ <xsl:if test="count(node)>1">
+ <xsl:variable name="netname">
+ <xsl:text> </xsl:text>
+ <xsl:choose>
+ <xsl:when test = "@name != '' ">
+ <xsl:value-of select="@name"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>N-</xsl:text>
+ <xsl:value-of select="@code"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>&nl;</xsl:text>
+ </xsl:variable>
+ <xsl:apply-templates select="node" mode="first"/>
+ <xsl:value-of select="$netname"/>
+ <xsl:apply-templates select="node" mode="others"/>
+ </xsl:if>
+</xsl:template>
+
+<!-- for each node -->
+<xsl:template match="node" mode="first">
+ <xsl:if test="position()=1">
+ <xsl:text>.ADD_TER </xsl:text>
+ <xsl:value-of select="@ref"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="@pin"/>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="node" mode="others">
+ <xsl:choose>
+ <xsl:when test='position()=1'>
+ </xsl:when>
+ <xsl:when test='position()=2'>
+ <xsl:text>.TER </xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> </xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="position()>1">
+ <xsl:value-of select="@ref"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="@pin"/>
+ <xsl:text>&nl;</xsl:text>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/eeschema/plugins/xsl_scripts/netlist_form_cadstar.xsl b/eeschema/plugins/xsl_scripts/netlist_form_cadstar.xsl
new file mode 100644
index 0000000..0c72f53
--- /dev/null
+++ b/eeschema/plugins/xsl_scripts/netlist_form_cadstar.xsl
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--XSL style sheet to EESCHEMA Generic Netlist Format to CADSTAR netlist format
+ Copyright (C) 2010, SoftPLC Corporation.
+ GPL v2.
+
+ How to use:
+ see eeschema.pdf, chapter 14
+-->
+
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY nl "&#xd;&#xa;"> <!--new line CR, LF -->
+]>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
+
+<!-- Netlist header -->
+<xsl:template match="/export">
+ <xsl:text>.HEA&nl;</xsl:text>
+ <xsl:apply-templates select="design/date"/> <!-- Generate line .TIM <time> -->
+ <xsl:apply-templates select="design/tool"/> <!-- Generate line .APP <eeschema version> -->
+ <xsl:text>&nl;</xsl:text>
+ <xsl:apply-templates select="components/comp"/> <!-- Generate list of components -->
+ <xsl:text>&nl;&nl;</xsl:text>
+ <xsl:apply-templates select="nets/net"/> <!-- Generate list of nets and connections -->
+ <xsl:text>&nl;.END&nl;</xsl:text>
+</xsl:template>
+
+ <!-- Generate line .APP "eeschema (2010-08-17 BZR 2450)-unstable" -->
+<xsl:template match="tool">
+ <xsl:text>.APP "</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>"&nl;</xsl:text>
+</xsl:template>
+
+ <!-- Generate line .TIM 20/08/2010 10:45:33 -->
+<xsl:template match="date">
+ <xsl:text>.TIM </xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&nl;</xsl:text>
+</xsl:template>
+
+<!-- for each component -->
+<!-- create lines like
+ .ADD_COM U3 "74LS541" (when no footprint name specified)
+ .ADD_COM JP1 "CONN_8X2" "pin_array_8x2" "pin_array_8x2" (with a specified footprint name)
+-->
+<xsl:template match="comp">
+ <xsl:text>.ADD_COM </xsl:text>
+ <xsl:value-of select="@ref"/>
+ <xsl:text> </xsl:text>
+ <xsl:choose>
+ <xsl:when test = "value != '' ">
+ <xsl:text>"</xsl:text> <xsl:apply-templates select="value"/> <xsl:text>"</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>""</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>&nl;</xsl:text>
+</xsl:template>
+
+<!-- for each net -->
+<!-- create lines like
+.ADD_TER U3.9 "/PC-RST"
+.TER U3.8
+ BUS1.2
+.ADD_TER BUS1.14 "/PC-IOR"
+.TER U3.7
+-->
+<xsl:template match="net">
+ <!-- nets are output only if there is more than one pin in net -->
+ <xsl:if test="count(node)>1">
+ <xsl:variable name="netname">
+ <xsl:text>"</xsl:text>
+ <xsl:choose>
+ <xsl:when test = "@name != '' ">
+ <xsl:value-of select="@name"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>N-</xsl:text>
+ <xsl:value-of select="@code"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>"&nl;</xsl:text>
+ </xsl:variable>
+ <xsl:apply-templates select="node" mode="first"/>
+ <xsl:value-of select="$netname"/>
+ <xsl:apply-templates select="node" mode="others"/>
+ </xsl:if>
+</xsl:template>
+
+<!-- for each node -->
+<xsl:template match="node" mode="first">
+ <xsl:if test="position()=1">
+ <xsl:text>.ADD_TER </xsl:text>
+ <xsl:value-of select="@ref"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="@pin"/>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="node" mode="others">
+ <xsl:choose>
+ <xsl:when test='position()=1'>
+ </xsl:when>
+ <xsl:when test='position()=2'>
+ <xsl:text>.TER </xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> </xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="position()>1">
+ <xsl:value-of select="@ref"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="@pin"/>
+ <xsl:text>&nl;</xsl:text>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/eeschema/plugins/xsl_scripts/netlist_form_pads-pcb.xsl b/eeschema/plugins/xsl_scripts/netlist_form_pads-pcb.xsl
new file mode 100644
index 0000000..355072c
--- /dev/null
+++ b/eeschema/plugins/xsl_scripts/netlist_form_pads-pcb.xsl
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--XSL style sheet to EESCHEMA Generic Netlist Format to PADS netlist format
+ Copyright (C) 2010, SoftPLC Corporation.
+ GPL v2.
+
+ How to use:
+ see eeschema.pdf, chapter 14
+-->
+
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY nl "&#xd;&#xa;"> <!--new line CR, LF -->
+]>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
+
+<xsl:template match="/export">
+ <xsl:text>*PADS-PCB*&nl;*PART*&nl;</xsl:text>
+ <xsl:apply-templates select="components/comp"/>
+ <xsl:text>&nl;*NET*&nl;</xsl:text>
+ <xsl:apply-templates select="nets/net"/>
+ <xsl:text>*END*&nl;</xsl:text>
+</xsl:template>
+
+<!-- for each component -->
+<xsl:template match="comp">
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@ref"/>
+ <xsl:text> </xsl:text>
+ <xsl:choose>
+ <xsl:when test = "footprint != '' ">
+ <xsl:apply-templates select="footprint"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>unknown</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>&nl;</xsl:text>
+</xsl:template>
+
+<!-- for each net -->
+<xsl:template match="net">
+ <!-- nets are output only if there is more than one pin in net -->
+ <xsl:if test="count(node)>1">
+ <xsl:text>*SIGNAL* </xsl:text>
+ <xsl:choose>
+ <xsl:when test = "@name != '' ">
+ <xsl:value-of select="@name"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>N-</xsl:text>
+ <xsl:value-of select="@code"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>&nl;</xsl:text>
+ <xsl:apply-templates select="node"/>
+ </xsl:if>
+</xsl:template>
+
+<!-- for each node -->
+<xsl:template match="node">
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@ref"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="@pin"/>
+ <xsl:text>&nl;</xsl:text>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/eeschema/project_rescue.cpp b/eeschema/project_rescue.cpp
new file mode 100644
index 0000000..098d3a3
--- /dev/null
+++ b/eeschema/project_rescue.cpp
@@ -0,0 +1,569 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Chris Pavlina <pavlina.chris@gmail.com>
+ * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <class_drawpanel.h>
+#include <class_library.h>
+#include <confirm.h>
+#include <invoke_sch_dialog.h>
+#include <kicad_device_context.h>
+#include <project_rescue.h>
+#include <sch_component.h>
+#include <sch_sheet.h>
+#include <schframe.h>
+#include <wildcards_and_files_ext.h>
+
+#include <cctype>
+#include <boost/foreach.hpp>
+#include <map>
+
+
+typedef std::pair<SCH_COMPONENT*, wxString> COMPONENT_NAME_PAIR;
+
+
+/**
+ * Function save_library
+ * writes the library out to disk. Returns true on success.
+ *
+ * @param aFileName - Filename to receive the library
+ * @param aLibrary - Library to write
+ * @param aEditFrame - the calling SCH_EDIT_FRAME
+ */
+static bool save_library( const wxString& aFileName, PART_LIB* aLibrary, SCH_EDIT_FRAME* aEditFrame )
+{
+ try
+ {
+ FILE_OUTPUTFORMATTER formatter( aFileName );
+
+ if( !aLibrary->Save( formatter ) )
+ {
+ wxString msg = wxString::Format( _(
+ "An error occurred attempting to save component library '%s'." ),
+ GetChars( aFileName )
+ );
+ DisplayError( aEditFrame, msg );
+ return false;
+ }
+ }
+ catch( ... /* IO_ERROR ioe */ )
+ {
+ wxString msg = wxString::Format( _(
+ "Failed to create component library file '%s'" ),
+ GetChars( aFileName )
+ );
+ DisplayError( aEditFrame, msg );
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * Function insert_library
+ * inserts a library into the project and refreshes libraries.
+ *
+ * @param aProject - project that will be modified
+ * @param aLibrary - PART_LIB to add
+ * @param aIndex - index in the list at which the library is to be inserted
+ *
+ * @return true on success, false on failure
+ */
+static bool insert_library( PROJECT *aProject, PART_LIB *aLibrary, size_t aIndex ) throw( boost::bad_pointer )
+{
+ wxArrayString libNames;
+ wxString libPaths;
+
+ wxString libName = aLibrary->GetName();
+ PART_LIBS *libs = dynamic_cast<PART_LIBS*>( aProject->GetElem( PROJECT::ELEM_SCH_PART_LIBS ) );
+ if( !libs )
+ {
+ libs = new PART_LIBS();
+ aProject->SetElem( PROJECT::ELEM_SCH_PART_LIBS, libs );
+ }
+
+ try
+ {
+ PART_LIBS::LibNamesAndPaths( aProject, false, &libPaths, &libNames );
+
+ // Make sure the library is not already in the list
+ while( libNames.Index( libName ) != wxNOT_FOUND )
+ libNames.Remove( libName );
+
+ // Add the library to the list and save
+ libNames.Insert( libName, aIndex );
+ PART_LIBS::LibNamesAndPaths( aProject, true, &libPaths, &libNames );
+ }
+ catch( const IO_ERROR& e )
+ {
+ // Could not get or save the current libraries.
+ return false;
+ }
+
+ // Save the old libraries in case there is a problem after clear(). We'll
+ // put them back in.
+ boost::ptr_vector<PART_LIB> libsSave;
+ libsSave.transfer( libsSave.end(), libs->begin(), libs->end(), *libs );
+
+ aProject->SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL );
+
+ libs = new PART_LIBS();
+ try
+ {
+ libs->LoadAllLibraries( aProject );
+ }
+ catch( const PARSE_ERROR& e )
+ {
+ // Some libraries were not found. There's no point in showing the error,
+ // because it was already shown. Just don't do anything.
+ }
+ catch( const IO_ERROR& e )
+ {
+ // Restore the old list
+ libs->clear();
+ libs->transfer( libs->end(), libsSave.begin(), libsSave.end(), libsSave );
+ return false;
+ }
+ aProject->SetElem( PROJECT::ELEM_SCH_PART_LIBS, libs );
+
+ return true;
+}
+
+
+/**
+ * Function get_components
+ * Fills a vector with all of the project's components, to ease iterating over them.
+ *
+ * @param aComponents - a vector that will take the components
+ */
+static void get_components( std::vector<SCH_COMPONENT*>& aComponents )
+{
+ SCH_SCREENS screens;
+ for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
+ {
+ for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
+ {
+ if( item->Type() != SCH_COMPONENT_T ) continue;
+ SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( item );
+ aComponents.push_back( component );
+ }
+ }
+}
+
+
+/**
+ * Function find_component
+ * Search the libraries for the first component with a given name.
+ *
+ * @param aName - name to search for
+ * @param aLibs - the loaded PART_LIBS
+ * @param aCached - whether we are looking for the cached part
+ */
+static LIB_PART* find_component( wxString aName, PART_LIBS* aLibs, bool aCached )
+{
+ LIB_PART *part = NULL;
+
+ BOOST_FOREACH( PART_LIB& each_lib, *aLibs )
+ {
+ if( aCached && !each_lib.IsCache() )
+ continue;
+
+ if( !aCached && each_lib.IsCache() )
+ continue;
+
+ part = each_lib.FindPart( aName );
+ if( part )
+ break;
+ }
+
+ return part;
+}
+
+
+void RESCUER::RemoveDuplicates()
+{
+ std::vector<wxString> names_seen;
+
+ for( boost::ptr_vector<RESCUE_CANDIDATE>::iterator it = m_all_candidates.begin();
+ it != m_all_candidates.end(); )
+ {
+ bool seen_already = false;
+ BOOST_FOREACH( wxString& name_seen, names_seen )
+ {
+ if( name_seen == it->GetRequestedName() )
+ {
+ seen_already = true;
+ break;
+ }
+ }
+
+ if( seen_already )
+ {
+ it = m_all_candidates.erase( it );
+ }
+ else
+ {
+ names_seen.push_back( it->GetRequestedName() );
+ ++it;
+ }
+ }
+}
+
+
+class RESCUE_CASE_CANDIDATE: public RESCUE_CANDIDATE
+{
+ wxString m_requested_name;
+ wxString m_new_name;
+ LIB_PART* m_lib_candidate;
+
+public:
+ /**
+ * Function FindRescues
+ * Grab all possible RESCUE_CASE_CANDIDATES into a vector.
+ * @param aRescuer - the working RESCUER instance.
+ * @param aCandidates - the vector the will hold the candidates.
+ */
+ static void FindRescues( RESCUER& aRescuer, boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates )
+ {
+ typedef std::map<wxString, RESCUE_CASE_CANDIDATE> candidate_map_t;
+ candidate_map_t candidate_map;
+
+ BOOST_FOREACH( SCH_COMPONENT* each_component, *( aRescuer.GetComponents() ) )
+ {
+ wxString part_name( each_component->GetPartName() );
+
+ LIB_ALIAS* case_sensitive_match = aRescuer.GetLibs()->FindLibraryEntry( part_name );
+ std::vector<LIB_ALIAS*> case_insensitive_matches;
+ aRescuer.GetLibs()->FindLibraryNearEntries( case_insensitive_matches, part_name );
+
+ if( case_sensitive_match || !( case_insensitive_matches.size() ) )
+ continue;
+
+ RESCUE_CASE_CANDIDATE candidate(
+ part_name, case_insensitive_matches[0]->GetName(),
+ case_insensitive_matches[0]->GetPart() );
+ candidate_map[part_name] = candidate;
+ }
+
+ // Now, dump the map into aCandidates
+ BOOST_FOREACH( const candidate_map_t::value_type& each_pair, candidate_map )
+ {
+ aCandidates.push_back( new RESCUE_CASE_CANDIDATE( each_pair.second ) );
+ }
+ }
+
+ /**
+ * Constructor RESCUE_CANDIDATE
+ * @param aRequestedName - the name the schematic asks for
+ * @param aNewName - the name we want to change it to
+ * @param aLibCandidate - the part that will give us
+ */
+ RESCUE_CASE_CANDIDATE( const wxString& aRequestedName, const wxString& aNewName,
+ LIB_PART* aLibCandidate )
+ : m_requested_name( aRequestedName ),
+ m_new_name( aNewName ),
+ m_lib_candidate( aLibCandidate ) { }
+
+ RESCUE_CASE_CANDIDATE() { m_lib_candidate = NULL; }
+
+ virtual wxString GetRequestedName() const { return m_requested_name; }
+ virtual wxString GetNewName() const { return m_new_name; }
+ virtual LIB_PART* GetLibCandidate() const { return m_lib_candidate; }
+ virtual wxString GetActionDescription() const
+ {
+ wxString action;
+ action.Printf( _( "Rename to %s" ), m_new_name );
+ return action;
+ }
+
+ virtual bool PerformAction( RESCUER* aRescuer )
+ {
+ BOOST_FOREACH( SCH_COMPONENT* each_component, *aRescuer->GetComponents() )
+ {
+ if( each_component->GetPartName() != m_requested_name ) continue;
+ each_component->SetPartName( m_new_name );
+ each_component->ClearFlags();
+ aRescuer->LogRescue( each_component, m_requested_name, m_new_name );
+ }
+ return true;
+ }
+};
+
+
+class RESCUE_CACHE_CANDIDATE: public RESCUE_CANDIDATE
+{
+ wxString m_requested_name;
+ wxString m_new_name;
+ LIB_PART* m_cache_candidate;
+ LIB_PART* m_lib_candidate;
+
+ static std::auto_ptr<PART_LIB> m_rescue_lib;
+ static wxFileName m_library_fn;
+
+public:
+ /**
+ * Function FindRescues
+ * Grab all possible RESCUE_CACHE_CANDIDATEs into a vector.
+ * @param aRescuer - the working RESCUER instance.
+ * @param aCandidates - the vector the will hold the candidates.
+ */
+ static void FindRescues( RESCUER& aRescuer, boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates )
+ {
+ typedef std::map<wxString, RESCUE_CACHE_CANDIDATE> candidate_map_t;
+ candidate_map_t candidate_map;
+
+ wxString part_name_suffix = aRescuer.GetPartNameSuffix();
+
+ BOOST_FOREACH( SCH_COMPONENT* each_component, *( aRescuer.GetComponents() ) )
+ {
+ wxString part_name( each_component->GetPartName() );
+
+ LIB_PART* cache_match = find_component( part_name, aRescuer.GetLibs(), /* aCached */ true );
+ LIB_PART* lib_match = aRescuer.GetLibs()->FindLibPart( part_name );
+
+ // Test whether there is a conflict
+ if( !cache_match || !lib_match )
+ continue;
+ if( !cache_match->PinsConflictWith( *lib_match, /* aTestNums */ true,
+ /* aTestNames */ true, /* aTestType */ true, /* aTestOrientation */ true,
+ /* aTestLength */ false ))
+ continue;
+
+ RESCUE_CACHE_CANDIDATE candidate(
+ part_name, part_name + part_name_suffix,
+ cache_match, lib_match );
+ candidate_map[part_name] = candidate;
+ }
+
+ // Now, dump the map into aCandidates
+ BOOST_FOREACH( const candidate_map_t::value_type& each_pair, candidate_map )
+ {
+ aCandidates.push_back( new RESCUE_CACHE_CANDIDATE( each_pair.second ) );
+ }
+ }
+
+ /**
+ * Constructor RESCUE_CACHE_CANDIDATE
+ * @param aRequestedName - the name the schematic asks for
+ * @param aNewName - the name we want to change it to
+ * @param aCacheCandidate - the part from the cache
+ * @param aLibCandidate - the part that would be loaded from the library
+ */
+ RESCUE_CACHE_CANDIDATE( const wxString& aRequestedName, const wxString& aNewName,
+ LIB_PART* aCacheCandidate, LIB_PART* aLibCandidate )
+ : m_requested_name( aRequestedName ),
+ m_new_name( aNewName ),
+ m_cache_candidate( aCacheCandidate ),
+ m_lib_candidate( aLibCandidate ) { }
+
+ RESCUE_CACHE_CANDIDATE()
+ : m_cache_candidate( NULL ), m_lib_candidate( NULL ) {}
+
+ virtual wxString GetRequestedName() const { return m_requested_name; }
+ virtual wxString GetNewName() const { return m_new_name; }
+ virtual LIB_PART* GetCacheCandidate() const { return m_cache_candidate; }
+ virtual LIB_PART* GetLibCandidate() const { return m_lib_candidate; }
+ virtual wxString GetActionDescription() const
+ {
+ wxString action;
+ action.Printf( _( "Rescue %s as %s" ), m_requested_name, m_new_name );
+ return action;
+ }
+
+ /**
+ * Function OpenRescueLibrary
+ * Creates the new rescue library. Must be called before calling any PerformAction()s.
+ */
+ static void OpenRescueLibrary()
+ {
+ wxFileName fn( g_RootSheet->GetScreen()->GetFileName() );
+ fn.SetName( fn.GetName() + wxT( "-rescue" ) );
+ fn.SetExt( SchematicLibraryFileExtension );
+ m_library_fn.SetPath( fn.GetPath() );
+ m_library_fn.SetName( fn.GetName() );
+ m_library_fn.SetExt( wxT( "lib" ) );
+
+ std::auto_ptr<PART_LIB> rescue_lib( new PART_LIB( LIBRARY_TYPE_EESCHEMA,
+ fn.GetFullPath() ) );
+
+ m_rescue_lib = rescue_lib;
+ }
+
+ virtual bool PerformAction( RESCUER* aRescuer )
+ {
+ LIB_PART new_part( *m_cache_candidate, m_rescue_lib.get() );
+ new_part.SetName( m_new_name );
+ new_part.RemoveAllAliases();
+ RESCUE_CACHE_CANDIDATE::m_rescue_lib.get()->AddPart( &new_part );
+
+ BOOST_FOREACH( SCH_COMPONENT* each_component, *aRescuer->GetComponents() )
+ {
+ if( each_component->GetPartName() != m_requested_name ) continue;
+ each_component->SetPartName( m_new_name );
+ each_component->ClearFlags();
+ aRescuer->LogRescue( each_component, m_requested_name, m_new_name );
+ }
+ return true;
+ }
+
+ /**
+ * Function WriteRescueLibrary
+ * Writes out the rescue library. Called after successful PerformAction()s. If this fails,
+ * undo the actions.
+ * @return True on success.
+ */
+ static bool WriteRescueLibrary( SCH_EDIT_FRAME *aEditFrame, PROJECT* aProject )
+ {
+
+ if( !save_library( m_library_fn.GetFullPath(), m_rescue_lib.get(), aEditFrame ) )
+ return false;
+ return insert_library( aProject, m_rescue_lib.get(), 0 );
+ }
+};
+
+std::auto_ptr<PART_LIB> RESCUE_CACHE_CANDIDATE::m_rescue_lib;
+wxFileName RESCUE_CACHE_CANDIDATE::m_library_fn;
+
+RESCUER::RESCUER( SCH_EDIT_FRAME& aEditFrame, PROJECT& aProject )
+{
+ get_components( m_components );
+ m_prj = &aProject;
+ m_libs = m_prj->SchLibs();
+ m_edit_frame = &aEditFrame;
+}
+
+
+void RESCUER::FindCandidates()
+{
+ RESCUE_CASE_CANDIDATE::FindRescues( *this, m_all_candidates );
+ RESCUE_CACHE_CANDIDATE::FindRescues( *this, m_all_candidates );
+}
+
+
+void RESCUER::InvokeDialog( bool aAskShowAgain )
+{
+ InvokeDialogRescueEach( m_edit_frame, *this, aAskShowAgain );
+}
+
+
+void RESCUER::LogRescue( SCH_COMPONENT *aComponent, const wxString &aOldName,
+ const wxString &aNewName )
+{
+ RESCUE_LOG logitem;
+ logitem.component = aComponent;
+ logitem.old_name = aOldName;
+ logitem.new_name = aNewName;
+ m_rescue_log.push_back( logitem );
+}
+
+
+bool RESCUER::DoRescues()
+{
+ BOOST_FOREACH( RESCUE_CANDIDATE* each_candidate, m_chosen_candidates )
+ {
+ if( ! each_candidate->PerformAction( this ) )
+ return false;
+ }
+ return true;
+}
+
+
+void RESCUER::UndoRescues()
+{
+ BOOST_FOREACH( RESCUE_LOG& each_logitem, m_rescue_log )
+ {
+ each_logitem.component->SetPartName( each_logitem.old_name );
+ each_logitem.component->ClearFlags();
+ }
+}
+
+
+wxString RESCUER::GetPartNameSuffix()
+{
+ wxString suffix = wxT( "-RESCUE-" );
+ wxString pname = GetPrj()->GetProjectName();
+ for( size_t i = 0; i < pname.Len(); ++i )
+ {
+ if( isspace( pname[i].GetValue() ) )
+ suffix.Append( '_' );
+ else
+ suffix.Append( pname[i] );
+ }
+
+ return suffix;
+}
+
+
+bool SCH_EDIT_FRAME::RescueProject( bool aRunningOnDemand )
+{
+ RESCUER rescuer( *this, Prj() );
+
+ rescuer.FindCandidates();
+
+ if( ! rescuer.GetCandidateCount() )
+ {
+ if( aRunningOnDemand )
+ {
+ wxMessageDialog dlg( this, _( "This project has nothing to rescue." ) );
+ dlg.ShowModal();
+ }
+ return true;
+ }
+
+ rescuer.RemoveDuplicates();
+
+ rescuer.InvokeDialog( !aRunningOnDemand );
+
+ // If no components were rescued, let the user know what's going on. He might
+ // have clicked cancel by mistake, and should have some indication of that.
+ if( !rescuer.GetChosenCandidateCount() )
+ {
+ wxMessageDialog dlg( this, _( "No symbols were rescued." ) );
+ dlg.ShowModal();
+
+ // Set the modified flag even on Cancel. Many users seem to instinctively want to Save at
+ // this point, due to the reloading of the symbols, so we'll make the save button active.
+ OnModify();
+ return true;
+ }
+
+ RESCUE_CACHE_CANDIDATE::OpenRescueLibrary();
+
+ if( !rescuer.DoRescues() )
+ {
+ rescuer.UndoRescues();
+ return false;
+ }
+
+ RESCUE_CACHE_CANDIDATE::WriteRescueLibrary( this, &Prj() );
+
+ Prj().SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL );
+
+ // Clean up wire ends
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+ GetScreen()->SchematicCleanUp( NULL, &dc );
+ m_canvas->Refresh( true );
+ OnModify();
+
+ return true;
+}
diff --git a/eeschema/project_rescue.h b/eeschema/project_rescue.h
new file mode 100644
index 0000000..4ba538f
--- /dev/null
+++ b/eeschema/project_rescue.h
@@ -0,0 +1,198 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Chris Pavlina <pavlina.chris@gmail.com>
+ * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _LIB_CACHE_RESCUE_H_
+#define _LIB_CACHE_RESCUE_H_
+
+/* This code handles the case where an old schematic was made before
+ * various changes were made, either to KiCad or to the libraries, and
+ * the project needs to be recovered. The function of note is a member
+ * of SCH_EDIT_FRAME, defined thus:
+ *
+ * bool SCH_EDIT_FRAME::RescueProject( bool aSilentIfNone );
+ *
+ * When this is called, a list of problematic components is compiled. If
+ * this list is empty, then the function displays a notification and returns
+ * (if aSilentIfNone is true, the notification is silenced).
+ */
+
+#include <schframe.h>
+
+#include <vector>
+#include <wx/string.h>
+#include <boost/ptr_container/ptr_vector.hpp>
+
+class LIB_PART;
+class SCH_COMPONENT;
+class RESCUER;
+
+enum RESCUE_TYPE
+{
+ RESCUE_CONFLICT,
+ RESCUE_CASE,
+};
+
+class RESCUE_CANDIDATE
+{
+public:
+ virtual ~RESCUE_CANDIDATE() {}
+
+ /**
+ * Function GetRequestedName
+ * Get the name that was originally requested in the schematic
+ */
+ virtual wxString GetRequestedName() const = 0;
+
+ /**
+ * Function GetNewName
+ * Get the name we're proposing changing it to
+ */
+ virtual wxString GetNewName() const = 0;
+
+ /**
+ * Function GetCacheCandidate
+ * Get the part that can be loaded from the project cache, if possible, or
+ * else NULL.
+ */
+ virtual LIB_PART* GetCacheCandidate() const { return NULL; }
+
+ /**
+ * Function GetLibCandidate
+ * Get the part the would be loaded from the libraries, if possible, or else
+ * NULL.
+ */
+ virtual LIB_PART* GetLibCandidate() const { return NULL; }
+
+ /**
+ * Function GetActionDescription
+ * Get a description of the action proposed, for displaying in the UI.
+ */
+ virtual wxString GetActionDescription() const = 0;
+
+ /**
+ * Function PerformAction
+ * Perform the actual rescue action. If successful, this must log the rescue using
+ * RESCUER::LogRescue to allow it to be reversed.
+ * @return True on success.
+ */
+ virtual bool PerformAction( RESCUER* aRescuer ) = 0;
+};
+
+class RESCUE_LOG
+{
+public:
+ SCH_COMPONENT* component;
+ wxString old_name;
+ wxString new_name;
+};
+
+class RESCUER
+{
+ friend class DIALOG_RESCUE_EACH;
+
+ std::vector<SCH_COMPONENT*> m_components;
+ PART_LIBS* m_libs;
+ PROJECT* m_prj;
+ SCH_EDIT_FRAME* m_edit_frame;
+
+ boost::ptr_vector<RESCUE_CANDIDATE> m_all_candidates;
+ std::vector<RESCUE_CANDIDATE*> m_chosen_candidates;
+
+ std::vector<RESCUE_LOG> m_rescue_log;
+
+public:
+ RESCUER( SCH_EDIT_FRAME& aEditFrame, PROJECT& aProject );
+
+ /**
+ * Function FindCandidates
+ * Populate the RESCUER with all possible candidates.
+ */
+ void FindCandidates();
+
+ /**
+ * Function RemoveDuplicates
+ * Filter out duplicately named rescue candidates.
+ */
+ void RemoveDuplicates();
+
+ /**
+ * Function GetCandidateCount
+ */
+ size_t GetCandidateCount() { return m_all_candidates.size(); }
+
+ /**
+ * Function GetChosenCandidateCount
+ */
+ size_t GetChosenCandidateCount() { return m_chosen_candidates.size(); }
+
+ /**
+ * Function GetComponents
+ */
+ std::vector<SCH_COMPONENT*>* GetComponents() { return &m_components; }
+
+ /**
+ * Function GetLibs
+ */
+ PART_LIBS* GetLibs() { return m_libs; }
+
+ /**
+ * Function GetPrj
+ */
+ PROJECT* GetPrj() { return m_prj; }
+
+ /**
+ * Function GetPartNameSuffix
+ * Return the suffix to add to rescued parts.
+ */
+ wxString GetPartNameSuffix();
+
+ /**
+ * Function InvokeDialog
+ * Display a dialog to allow the user to select rescues.
+ * @param aAskShowAgain - whether the "Never Show Again" button should be visible
+ */
+ void InvokeDialog( bool aAskShowAgain );
+
+ /**
+ * Function LogRescue
+ * Used by individual RESCUE_CANDIDATEs to log a rescue for undoing.
+ */
+ void LogRescue( SCH_COMPONENT *aComponent, const wxString& aOldName,
+ const wxString& aNewName );
+
+ /**
+ * Function DoRescues
+ * Perform all chosen rescue actions, logging them to be undone if necessary.
+ * @return True on success
+ */
+ bool DoRescues();
+
+ /**
+ * Function UndoRescues
+ * Reverse the effects of all rescues on the project.
+ */
+ void UndoRescues();
+};
+
+#endif // _LIB_CACHE_RESCUE_H_
diff --git a/eeschema/protos.h b/eeschema/protos.h
new file mode 100644
index 0000000..ae3cf1d
--- /dev/null
+++ b/eeschema/protos.h
@@ -0,0 +1,58 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef __PROTOS_H__
+#define __PROTOS_H__
+
+#include <colors.h>
+
+class EDA_DRAW_PANEL;
+class PICKED_ITEMS_LIST;
+class SCH_ITEM;
+
+
+// operations_on_item_lists.cpp
+void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList );
+
+/**
+ * Function DuplicateStruct
+ * creates a new copy of given struct.
+ * @param aDrawStruct = the SCH_ITEM to duplicate
+ * @param aClone (defualt = true)
+ * if true duplicate also some parameters that must be unique
+ * (timestamp and sheet name)
+ * aClone must be false. use true only is undo/redo duplications
+ */
+SCH_ITEM* DuplicateStruct( SCH_ITEM* DrawStruct, bool aClone = false );
+
+
+/****************/
+/* EEREDRAW.CPP */
+/****************/
+void DrawDanglingSymbol( EDA_DRAW_PANEL* panel, wxDC* DC,
+ const wxPoint& pos, EDA_COLOR_T Color );
+
+
+#endif /* __PROTOS_H__ */
diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp
new file mode 100644
index 0000000..52898e8
--- /dev/null
+++ b/eeschema/sch_base_frame.cpp
@@ -0,0 +1,203 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <sch_base_frame.h>
+#include <viewlib_frame.h>
+#include <libeditframe.h>
+#include <base_units.h>
+#include <kiway.h>
+#include <class_drawpanel.h>
+
+// Sttaic members:
+
+
+SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent,
+ FRAME_T aWindowType, const wxString& aTitle,
+ const wxPoint& aPosition, const wxSize& aSize, long aStyle,
+ const wxString& aFrameName ) :
+ EDA_DRAW_FRAME( aKiway, aParent, aWindowType, aTitle, aPosition,
+ aSize, aStyle, aFrameName )
+{
+ m_zoomLevelCoeff = 11.0; // Adjusted to roughly displays zoom level = 1
+ // when the screen shows a 1:1 image
+ // obviously depends on the monitor,
+ // but this is an acceptable value
+ m_repeatStep = wxPoint( DEFAULT_REPEAT_OFFSET_X, DEFAULT_REPEAT_OFFSET_Y );
+ m_repeatDeltaLabel = DEFAULT_REPEAT_LABEL_INC;
+}
+
+
+void SCH_BASE_FRAME::OnOpenLibraryViewer( wxCommandEvent& event )
+{
+ LIB_VIEW_FRAME* viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, true );
+
+ viewlibFrame->PushPreferences( m_canvas );
+
+ // On Windows, Raise() does not bring the window on screen, when iconized
+ if( viewlibFrame->IsIconized() )
+ viewlibFrame->Iconize( false );
+
+ viewlibFrame->Show( true );
+ viewlibFrame->Raise();
+}
+
+// Virtual from EDA_DRAW_FRAME
+EDA_COLOR_T SCH_BASE_FRAME::GetDrawBgColor() const
+{
+ return GetLayerColor( LAYER_BACKGROUND );
+}
+
+void SCH_BASE_FRAME::SetDrawBgColor( EDA_COLOR_T aColor)
+{
+ m_drawBgColor= aColor;
+ SetLayerColor( aColor, LAYER_BACKGROUND );
+}
+
+
+SCH_SCREEN* SCH_BASE_FRAME::GetScreen() const
+{
+ return (SCH_SCREEN*) EDA_DRAW_FRAME::GetScreen();
+}
+
+const wxString SCH_BASE_FRAME::GetZoomLevelIndicator() const
+{
+ return EDA_DRAW_FRAME::GetZoomLevelIndicator();
+}
+
+void SCH_BASE_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
+{
+ GetScreen()->SetPageSettings( aPageSettings );
+}
+
+
+const PAGE_INFO& SCH_BASE_FRAME::GetPageSettings () const
+{
+ return GetScreen()->GetPageSettings();
+}
+
+
+const wxSize SCH_BASE_FRAME::GetPageSizeIU() const
+{
+ // GetSizeIU is compile time dependent:
+ return GetScreen()->GetPageSettings().GetSizeIU();
+}
+
+
+const wxPoint& SCH_BASE_FRAME::GetAuxOrigin() const
+{
+ wxASSERT( GetScreen() );
+ return GetScreen()->GetAuxOrigin();
+}
+
+
+void SCH_BASE_FRAME::SetAuxOrigin( const wxPoint& aPosition )
+{
+ wxASSERT( GetScreen() );
+ GetScreen()->SetAuxOrigin( aPosition );
+}
+
+
+const TITLE_BLOCK& SCH_BASE_FRAME::GetTitleBlock() const
+{
+ wxASSERT( GetScreen() );
+ return GetScreen()->GetTitleBlock();
+}
+
+
+void SCH_BASE_FRAME::SetTitleBlock( const TITLE_BLOCK& aTitleBlock )
+{
+ wxASSERT( GetScreen() );
+ GetScreen()->SetTitleBlock( aTitleBlock );
+}
+
+
+void SCH_BASE_FRAME::UpdateStatusBar()
+{
+ wxString line;
+ int dx, dy;
+ BASE_SCREEN* screen = GetScreen();
+
+ if( !screen )
+ return;
+
+ EDA_DRAW_FRAME::UpdateStatusBar();
+
+ // Display absolute coordinates:
+ double dXpos = To_User_Unit( g_UserUnit, GetCrossHairPosition().x );
+ double dYpos = To_User_Unit( g_UserUnit, GetCrossHairPosition().y );
+
+ if ( g_UserUnit == MILLIMETRES )
+ {
+ dXpos = RoundTo0( dXpos, 100.0 );
+ dYpos = RoundTo0( dYpos, 100.0 );
+ }
+
+ wxString absformatter;
+ wxString locformatter;
+
+ switch( g_UserUnit )
+ {
+ case INCHES:
+ absformatter = wxT( "X %.3f Y %.3f" );
+ locformatter = wxT( "dx %.3f dy %.3f dist %.3f" );
+ break;
+
+ case MILLIMETRES:
+ absformatter = wxT( "X %.2f Y %.2f" );
+ locformatter = wxT( "dx %.2f dy %.2f dist %.2f" );
+ break;
+
+ case UNSCALED_UNITS:
+ absformatter = wxT( "X %f Y %f" );
+ locformatter = wxT( "dx %f dy %f dist %f" );
+ break;
+
+ case DEGREES:
+ wxASSERT( false );
+ break;
+ }
+
+ line.Printf( absformatter, dXpos, dYpos );
+ SetStatusText( line, 2 );
+
+ // Display relative coordinates:
+ dx = GetCrossHairPosition().x - screen->m_O_Curseur.x;
+ dy = GetCrossHairPosition().y - screen->m_O_Curseur.y;
+
+ dXpos = To_User_Unit( g_UserUnit, dx );
+ dYpos = To_User_Unit( g_UserUnit, dy );
+
+ if( g_UserUnit == MILLIMETRES )
+ {
+ dXpos = RoundTo0( dXpos, 100.0 );
+ dYpos = RoundTo0( dYpos, 100.0 );
+ }
+
+ // We already decided the formatter above
+ line.Printf( locformatter, dXpos, dYpos, hypot( dXpos, dYpos ) );
+ SetStatusText( line, 3 );
+
+ // refresh units display
+ DisplayUnitsMsg();
+}
diff --git a/eeschema/sch_base_frame.h b/eeschema/sch_base_frame.h
new file mode 100644
index 0000000..c99e1a6
--- /dev/null
+++ b/eeschema/sch_base_frame.h
@@ -0,0 +1,213 @@
+#ifndef SCH_BASE_FRAME_H_
+#define SCH_BASE_FRAME_H_
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <draw_frame.h>
+#include <class_sch_screen.h>
+
+class PAGE_INFO;
+class TITLE_BLOCK;
+class LIB_VIEW_FRAME;
+class LIB_EDIT_FRAME;
+class LIB_ALIAS;
+class PART_LIB;
+class SCHLIB_FILTER;
+
+/**
+ * Class SCH_BASE_FRAME
+ * is a shim class between EDA_DRAW_FRAME and several derived classes:
+ * LIB_EDIT_FRAME, LIB_VIEW_FRAME, and SCH_EDIT_FRAME, and it brings in a
+ * common way of handling the provided virtual functions for the derived classes.
+ * <p>
+ * The motivation here is to switch onto GetScreen() for the underlying data model.
+ *
+ * @author Dick Hollenbeck
+ */
+class SCH_BASE_FRAME : public EDA_DRAW_FRAME
+{
+protected:
+ wxPoint m_repeatStep; ///< the increment value of the position of an item
+ ///< when it is repeated
+ int m_repeatDeltaLabel; ///< the increment value of labels like bus members
+ ///< when they are repeated
+
+
+public:
+ SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent,
+ FRAME_T aWindowType,
+ const wxString& aTitle,
+ const wxPoint& aPosition, const wxSize& aSize,
+ long aStyle, const wxString & aFrameName );
+
+ SCH_SCREEN* GetScreen() const; // overload EDA_DRAW_FRAME
+
+ /**
+ * @return the increment value of the position of an item
+ * for the repeat command
+ */
+ const wxPoint GetRepeatStep() const { return m_repeatStep; }
+
+ /**
+ * Sets the repeat step value for repeat command
+ * @param aStep the increment value of the position of an item
+ * for the repeat command
+ */
+ void SetRepeatStep( const wxPoint& aStep) { m_repeatStep = aStep; }
+
+ /**
+ * @return the increment value of labels like bus members
+ * for the repeat command
+ */
+ int GetRepeatDeltaLabel() const { return m_repeatDeltaLabel; }
+
+ /**
+ * Sets the repeat delta label value for repeat command
+ * @param aDelta the increment value of labels like bus members
+ * for the repeat command
+ */
+ void SetRepeatDeltaLabel( int aDelta ) { m_repeatDeltaLabel = aDelta; }
+
+
+ /**
+ * Function GetZoomLevelIndicator
+ * returns a human readable value which can be displayed as zoom
+ * level indicator in dialogs.
+ * Virtual from the base class
+ */
+ const wxString GetZoomLevelIndicator() const;
+
+ void SetPageSettings( const PAGE_INFO& aPageSettings ); // overload EDA_DRAW_FRAME
+ const PAGE_INFO& GetPageSettings () const; // overload EDA_DRAW_FRAME
+ const wxSize GetPageSizeIU() const; // overload EDA_DRAW_FRAME
+
+ const wxPoint& GetAuxOrigin() const; // overload EDA_DRAW_FRAME
+ void SetAuxOrigin( const wxPoint& aPosition ); // overload EDA_DRAW_FRAME
+
+ const wxPoint& GetGridOrigin() const // overload EDA_DRAW_FRAME
+ {
+ static wxPoint zero;
+ return zero;
+ }
+ void SetGridOrigin( const wxPoint& aPoint ) {} // overload EDA_DRAW_FRAME
+
+ // Virtual from EDA_DRAW_FRAME
+ // the background color of the draw canvas:
+ EDA_COLOR_T GetDrawBgColor() const;
+ void SetDrawBgColor( EDA_COLOR_T aColor);
+
+ const TITLE_BLOCK& GetTitleBlock() const; // overload EDA_DRAW_FRAME
+ void SetTitleBlock( const TITLE_BLOCK& aTitleBlock ); // overload EDA_DRAW_FRAME
+
+ void UpdateStatusBar(); // overload EDA_DRAW_FRAME
+
+ /**
+ * Function SelectComponentFromLib
+ * Calls the library viewer to select component to import into schematic.
+ * if the library viewer is currently running, it is closed and reopened
+ * in modal mode.
+ * @param aFilter is a SCHLIB_FILTER filter to pass the allowed library names
+ * and/or the library name to load the component from and/or some other filter
+ * if NULL, no filtering.
+ * @param aHistoryList list of previously loaded components
+ * @param aHistoryLastUnit remembering last unit in last component.
+ * @param aUseLibBrowser bool to call the library viewer to select the component
+ * @param aUnit a pointer to int to return the selected unit (if any)
+ * @param aConvert a pointer to int to return the selected De Morgan shape (if any)
+ *
+ * @return the component name
+ */
+ wxString SelectComponentFromLibrary( const SCHLIB_FILTER* aFilter,
+ wxArrayString& aHistoryList,
+ int& aHistoryLastUnit,
+ bool aUseLibBrowser,
+ int* aUnit,
+ int* aConvert );
+
+protected:
+
+ /**
+ * Function SelectComponentFromLibBrowser
+ * Calls the library viewer to select component to import into schematic.
+ * if the library viewer is currently running, it is closed and reopened
+ * in modal mode.
+ * @param aFilter is a filter to pass the allowed library names
+ * and/or some other filter
+ * @param aPreselectedAlias Preselected component alias. NULL if none.
+ * @param aUnit Pointer to Unit-number. Input is the pre-selected unit, output
+ * is the finally selected unit by the user. Can be NULL.
+ * @param aConvert Pointer to deMorgan conversion. Input is what is pre-selected,
+ * output is the finally selected deMorgan type by the user.
+ * @return the component name
+ */
+ wxString SelectComponentFromLibBrowser( const SCHLIB_FILTER* aFilter,
+ LIB_ALIAS* aPreselectedAlias,
+ int* aUnit, int* aConvert );
+
+ /**
+ * Function OnOpenLibraryViewer
+ * Open the library viewer only to browse library contents.
+ * If the viewed is already opened from this, raise the viewer
+ * If the viewed is already opened from an other window, close it and reopen
+ */
+ void OnOpenLibraryViewer( wxCommandEvent& event );
+
+ /**
+ * Function DisplayComponentsNamesInLib
+ * Select a component from the list of components in a library
+ *
+ * @param aLibrary = a reference to the library to explore
+ * If NULL the user will be prompted tp chose a library
+ * @param aBuffer = a wxString to put the selected component name
+ *
+ * @return true if a component is selected
+ * false on cancel
+ */
+ bool DisplayListComponentsInLib( PART_LIB* aLibrary, wxString& aBuffer,
+ wxString& aPreviousChoice );
+
+ /**
+ * Function SelectLibraryFromList
+ * displays a list of current loaded libraries, and allows the user to select
+ * a library
+ * This list is sorted, with the library cache always at end of the list
+ * @return a reference to the selected library, or NULL
+ */
+ PART_LIB* SelectLibraryFromList();
+
+ /**
+ * Function SelectPartNameToLoad
+ * Select a part name from the list of components (parts) found in a library.
+ *
+ * @param aLibrary = a reference to the library to explore
+ * If NULL the user will be prompted tp chose a library
+ * @param aBufName = a wxString to put the selected component name
+ *
+ * @return true if a component is selected
+ * false on cancel
+ */
+ bool SelectPartNameToLoad( PART_LIB* aLibrary, wxString& aBufName );
+};
+
+#endif // SCH_BASE_FRAME_H_
diff --git a/eeschema/sch_bitmap.cpp b/eeschema/sch_bitmap.cpp
new file mode 100644
index 0000000..ce10c61
--- /dev/null
+++ b/eeschema/sch_bitmap.cpp
@@ -0,0 +1,309 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011 jean-pierre.charras
+ * Copyright (C) 2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_bitmap.cpp
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <trigo.h>
+#include <macros.h>
+#include <sch_bitmap.h>
+
+#include <wx/mstream.h>
+
+
+/*
+ * class SCH_BITMAP
+ * This class handle a bitmap image that can be inserted in a schematic.
+ */
+
+SCH_BITMAP::SCH_BITMAP( const wxPoint& pos ) :
+ SCH_ITEM( NULL, SCH_BITMAP_T )
+{
+ m_Pos = pos;
+ m_Layer = LAYER_NOTES; // used only to draw/plot a rectangle,
+ // when a bitmap cannot be drawn or plotted
+ m_Image = new BITMAP_BASE();
+}
+
+
+SCH_BITMAP::SCH_BITMAP( const SCH_BITMAP& aSchBitmap ) :
+ SCH_ITEM( aSchBitmap )
+{
+ m_Pos = aSchBitmap.m_Pos;
+ m_Layer = aSchBitmap.m_Layer;
+ m_Image = new BITMAP_BASE( *aSchBitmap.m_Image );
+}
+
+
+SCH_ITEM& SCH_BITMAP::operator=( const SCH_ITEM& aItem )
+{
+ wxCHECK_MSG( Type() == aItem.Type(), *this,
+ wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
+ GetClass() );
+
+ if( &aItem != this )
+ {
+ SCH_ITEM::operator=( aItem );
+
+ SCH_BITMAP* bitmap = (SCH_BITMAP*) &aItem;
+
+ delete m_Image;
+ m_Image = new BITMAP_BASE( *bitmap->m_Image );
+ m_Pos = bitmap->m_Pos;
+ }
+
+ return *this;
+}
+
+
+bool SCH_BITMAP::ReadImageFile( const wxString& aFullFilename )
+{
+ return m_Image->ReadImageFile( aFullFilename );
+}
+
+
+bool SCH_BITMAP::Save( FILE* aFile ) const
+{
+ if( fprintf( aFile, "$Bitmap\n" ) == EOF )
+ return false;
+
+ if( fprintf( aFile, "Pos %-4d %-4d\n", m_Pos.x, m_Pos.y ) == EOF )
+ return false;
+
+ if( fprintf( aFile, "Scale %f\n", m_Image->m_Scale ) == EOF )
+ return false;
+
+ if( fprintf( aFile, "Data\n" ) == EOF )
+ return false;
+
+ if( !m_Image->SaveData( aFile ) )
+ return false;
+
+ if( fprintf( aFile, "\nEndData\n" ) == EOF )
+ return false;
+
+
+ if( fprintf( aFile, "$EndBitmap\n" ) == EOF )
+ return false;
+
+ return true;
+}
+
+
+EDA_ITEM* SCH_BITMAP::Clone() const
+{
+ return new SCH_BITMAP( *this );
+}
+
+
+void SCH_BITMAP::SwapData( SCH_ITEM* aItem )
+{
+ wxCHECK_RET( aItem->Type() == SCH_BITMAP_T,
+ wxString::Format( wxT( "SCH_BITMAP object cannot swap data with %s object." ),
+ GetChars( aItem->GetClass() ) ) );
+
+ SCH_BITMAP* item = (SCH_BITMAP*) aItem;
+ std::swap( m_Pos, item->m_Pos );
+ std::swap( m_Image, item->m_Image );
+}
+
+
+bool SCH_BITMAP::Load( LINE_READER& aLine, wxString& aErrorMsg )
+{
+ char* line = aLine.Line();
+
+ if( strnicmp( line, "$Bitmap", 7 ) != 0 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file bitmap image load error at line %d, aborted" ),
+ aLine.LineNumber() );
+ aErrorMsg << wxT( "\n" ) << FROM_UTF8( (char*) aLine );
+ return false;
+ }
+
+ for( ; ; )
+ {
+ if( !aLine.ReadLine() )
+ return false;
+
+ line = aLine.Line();
+
+ if( strnicmp( line, "Pos", 3 ) == 0 )
+ {
+ sscanf( line + 3, "%d %d", &m_Pos.x, &m_Pos.y );
+ continue;
+ }
+
+ if( strnicmp( line, "Scale", 5 ) == 0 )
+ {
+ sscanf( line + 5, "%lf", &m_Image->m_Scale );
+ continue;
+ }
+
+ if( strnicmp( line, "Data", 4 ) == 0 )
+ {
+ m_Image->LoadData( aLine, aErrorMsg );
+ }
+
+ if( strnicmp( line, "$EndBitmap", 4 ) == 0 )
+ break;
+ }
+
+ return true;
+}
+
+
+const EDA_RECT SCH_BITMAP::GetBoundingBox() const
+{
+ EDA_RECT rect = m_Image->GetBoundingBox();
+
+ rect.Move( m_Pos );
+
+ return rect;
+}
+
+
+void SCH_BITMAP::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor )
+{
+ wxPoint pos = m_Pos + aOffset;
+
+ if( aColor < 0 ) // Use normal drawing function
+ {
+ // https://bugs.launchpad.net/kicad/+bug/1529163
+ // "Moving images in eeschema on OS X uses
+ // wrong position and shows image flipped"
+ //
+ // Original fix was to only GRSetDrawMode if aColor >= 0, but this made
+ // moving SCH_BITMAP work poorly on other platforms.
+#ifndef __WXMAC__
+ GRSetDrawMode( aDC, aDrawMode );
+#endif
+
+ m_Image->DrawBitmap( aPanel, aDC, pos );
+ }
+ else // draws bounding box only (used to move items)
+ {
+ GRSetDrawMode( aDC, aDrawMode );
+ // To draw the rect, pos is the upper left corner position
+ wxSize size = m_Image->GetSize();
+ pos.x -= size.x / 2;
+ pos.y -= size.y / 2;
+ GRRect( aPanel->GetClipBox(), aDC, pos.x, pos.y,
+ pos.x + size.x, pos.y + size.y, 0, aColor );
+ }
+}
+
+
+/* Function GetSize
+ * returns the actual size (in user units, not in pixels) of the image
+ */
+wxSize SCH_BITMAP::GetSize() const
+{
+ return m_Image->GetSize();
+}
+
+
+/*
+ * Mirror image relative to a horizontal X axis )
+ */
+void SCH_BITMAP::MirrorX( int aXaxis_position )
+{
+ MIRROR( m_Pos.y, aXaxis_position );
+ m_Image->Mirror( true );
+}
+
+
+/*
+ * Mirror image relative to a vertical Y axis
+ */
+void SCH_BITMAP::MirrorY( int aYaxis_position )
+{
+ MIRROR( m_Pos.x, aYaxis_position );
+ m_Image->Mirror( false );
+}
+
+
+void SCH_BITMAP::Rotate( wxPoint aPosition )
+{
+ RotatePoint( &m_Pos, aPosition, 900 );
+ m_Image->Rotate( false );
+}
+
+
+bool SCH_BITMAP::IsSelectStateChanged( const wxRect& aRect )
+{
+ bool previousState = IsSelected();
+
+ if( aRect.Contains( m_Pos ) )
+ SetFlags( SELECTED );
+ else
+ ClearFlags( SELECTED );
+
+ return previousState != IsSelected();
+}
+
+
+#if defined(DEBUG)
+void SCH_BITMAP::Show( int nestLevel, std::ostream& os ) const
+{
+ // XML output:
+ wxString s = GetClass();
+
+ NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_Pos << "/>\n";
+}
+
+
+#endif
+
+
+bool SCH_BITMAP::HitTest( const wxPoint& aPosition, int aAccuracy ) const
+{
+ EDA_RECT rect = GetBoundingBox();
+
+ rect.Inflate( aAccuracy );
+
+ return rect.Contains( aPosition );
+}
+
+
+bool SCH_BITMAP::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ EDA_RECT rect = aRect;
+
+ rect.Inflate( aAccuracy );
+
+ if( aContained )
+ return rect.Contains( GetBoundingBox() );
+
+ return rect.Intersects( GetBoundingBox() );
+}
+
+
+void SCH_BITMAP::Plot( PLOTTER* aPlotter )
+{
+ m_Image->PlotImage( aPlotter, m_Pos, GetLayerColor( GetLayer() ), GetPenSize() );
+}
diff --git a/eeschema/sch_bitmap.h b/eeschema/sch_bitmap.h
new file mode 100644
index 0000000..27e96e0
--- /dev/null
+++ b/eeschema/sch_bitmap.h
@@ -0,0 +1,149 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011 jean-pierre.charras
+ * Copyright (C) 2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_bitmap.h
+ *
+ */
+
+#ifndef _SCH_BITMAP_H_
+#define _SCH_BITMAP_H_
+
+
+#include <sch_item_struct.h>
+#include <class_bitmap_base.h>
+
+
+class SCH_BITMAP : public SCH_ITEM
+{
+ wxPoint m_Pos; // XY coordinates of center of the bitmap
+
+public:
+ BITMAP_BASE* m_Image; // the BITMAP_BASE item
+
+
+public:
+ SCH_BITMAP( const wxPoint& pos = wxPoint( 0, 0 ) );
+
+ SCH_BITMAP( const SCH_BITMAP& aSchBitmap );
+
+ ~SCH_BITMAP()
+ {
+ delete m_Image;
+ }
+
+ SCH_ITEM& operator=( const SCH_ITEM& aItem );
+
+ /*
+ * Accessors:
+ */
+ double GetPixelScaleFactor() { return m_Image->GetPixelScaleFactor(); }
+ void SetPixelScaleFactor( double aSF ) { m_Image->SetPixelScaleFactor( aSF ); }
+
+ /**
+ * Function GetScalingFactor
+ * @return the scaling factor from pixel size to actual draw size
+ * this scaling factor depend on m_pixelScaleFactor and m_Scale
+ * m_pixelScaleFactor gives the scaling factor between a pixel size and
+ * the internal schematic units
+ * m_Scale is an user dependant value, and gives the "zoom" value
+ * m_Scale = 1.0 = original size of bitmap.
+ * m_Scale < 1.0 = the bitmap is drawn smaller than its original size.
+ * m_Scale > 1.0 = the bitmap is drawn bigger than its original size.
+ */
+ double GetScalingFactor() const
+ {
+ return m_Image->GetScalingFactor();
+ }
+
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_BITMAP" );
+ }
+
+
+ /**
+ * Function GetSize
+ * @returns the actual size (in user units, not in pixels) of the image
+ */
+ wxSize GetSize() const;
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ void SwapData( SCH_ITEM* aItem );
+
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR );
+
+ /**
+ * Function ReadImageFile
+ * Reads and stores an image file. Init the bitmap used to draw this item
+ * format.
+ * @param aFullFilename The full filename of the image file to read.
+ * @return bool - true if success reading else false.
+ */
+ bool ReadImageFile( const wxString& aFullFilename );
+
+ bool Save( FILE* aFile ) const;
+
+ bool Load( LINE_READER& aLine, wxString& aErrorMsg );
+
+ void Move( const wxPoint& aMoveVector )
+ {
+ m_Pos += aMoveVector;
+ }
+
+
+ void MirrorY( int aYaxis_position );
+
+ void MirrorX( int aXaxis_position );
+
+ void Rotate( wxPoint aPosition );
+
+ bool IsSelectStateChanged( const wxRect& aRect );
+
+ wxString GetSelectMenuText() const { return wxString( _( "Image" ) ); }
+
+ BITMAP_DEF GetMenuImage() const { return image_xpm; }
+
+ wxPoint GetPosition() const { return m_Pos; }
+
+ void SetPosition( const wxPoint& aPosition ) { m_Pos = aPosition; }
+
+ bool HitTest( const wxPoint& aPosition, int aAccuracy ) const;
+
+ bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const;
+
+ void Plot( PLOTTER* aPlotter );
+
+ EDA_ITEM* Clone() const;
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // override
+#endif
+};
+
+
+#endif // _SCH_BITMAP_H_
diff --git a/eeschema/sch_bus_entry.cpp b/eeschema/sch_bus_entry.cpp
new file mode 100644
index 0000000..9ac8806
--- /dev/null
+++ b/eeschema/sch_bus_entry.cpp
@@ -0,0 +1,403 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_bus_entry.cpp
+ *
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <trigo.h>
+#include <common.h>
+#include <richio.h>
+#include <plot_common.h>
+#include <boost/foreach.hpp>
+
+#include <eeschema_config.h>
+#include <general.h>
+#include <sch_bus_entry.h>
+
+
+SCH_BUS_ENTRY_BASE::SCH_BUS_ENTRY_BASE( KICAD_T aType, const wxPoint& pos, char shape ) :
+ SCH_ITEM( NULL, aType )
+{
+ m_pos = pos;
+ m_size.x = 100;
+ m_size.y = 100;
+
+ if( shape == '/' )
+ m_size.y = -100;
+
+ m_isDanglingStart = m_isDanglingEnd = true;
+}
+
+SCH_BUS_WIRE_ENTRY::SCH_BUS_WIRE_ENTRY( const wxPoint& pos, char shape ) :
+ SCH_BUS_ENTRY_BASE( SCH_BUS_WIRE_ENTRY_T, pos, shape )
+{
+ m_Layer = LAYER_WIRE;
+}
+
+SCH_BUS_BUS_ENTRY::SCH_BUS_BUS_ENTRY( const wxPoint& pos, char shape ) :
+ SCH_BUS_ENTRY_BASE( SCH_BUS_BUS_ENTRY_T, pos, shape )
+{
+ m_Layer = LAYER_BUS;
+}
+
+EDA_ITEM* SCH_BUS_WIRE_ENTRY::Clone() const
+{
+ return new SCH_BUS_WIRE_ENTRY( *this );
+}
+
+EDA_ITEM* SCH_BUS_BUS_ENTRY::Clone() const
+{
+ return new SCH_BUS_BUS_ENTRY( *this );
+}
+
+
+wxPoint SCH_BUS_ENTRY_BASE::m_End() const
+{
+ return wxPoint( m_pos.x + m_size.x, m_pos.y + m_size.y );
+}
+
+
+void SCH_BUS_ENTRY_BASE::SwapData( SCH_ITEM* aItem )
+{
+ SCH_BUS_ENTRY_BASE* item = dynamic_cast<SCH_BUS_ENTRY_BASE*>( aItem );
+ wxCHECK_RET( item, wxT( "Cannot swap bus entry data with invalid item." ) );
+
+ std::swap( m_pos, item->m_pos );
+ std::swap( m_size, item->m_size );
+}
+
+
+bool SCH_BUS_WIRE_ENTRY::Save( FILE* aFile ) const
+{
+ if( fprintf( aFile, "Entry Wire Line\n\t%-4d %-4d %-4d %-4d\n",
+ m_pos.x, m_pos.y, m_End().x, m_End().y ) == EOF )
+ return false;
+ return true;
+}
+
+
+bool SCH_BUS_BUS_ENTRY::Save( FILE* aFile ) const
+{
+ if( fprintf( aFile, "Entry Bus Bus\n\t%-4d %-4d %-4d %-4d\n",
+ m_pos.x, m_pos.y, m_End().x, m_End().y ) == EOF )
+ return false;
+ return true;
+}
+
+
+bool SCH_BUS_ENTRY_BASE::Load( LINE_READER& aLine, wxString& aErrorMsg,
+ SCH_ITEM **out )
+{
+ char Name1[256];
+ char Name2[256];
+ char* line = (char*) aLine;
+ *out = NULL;
+
+ while( (*line != ' ' ) && *line )
+ line++;
+
+ if( sscanf( line, "%255s %255s", Name1, Name2 ) != 2 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file bus entry load error at line %d" ),
+ aLine.LineNumber() );
+ aErrorMsg << wxT( "\n" ) << FROM_UTF8( (char*) aLine );
+ return false;
+ }
+
+ SCH_BUS_ENTRY_BASE *this_new;
+ if( Name1[0] == 'B' )
+ this_new = new SCH_BUS_BUS_ENTRY;
+ else
+ this_new = new SCH_BUS_WIRE_ENTRY;
+ *out = this_new;
+
+ if( !aLine.ReadLine() || sscanf( (char*) aLine, "%d %d %d %d ",
+ &this_new->m_pos.x, &this_new->m_pos.y,
+ &this_new->m_size.x, &this_new->m_size.y ) != 4 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file bus entry load error at line %d" ),
+ aLine.LineNumber() );
+ aErrorMsg << wxT( "\n" ) << FROM_UTF8( (char*) aLine );
+ return false;
+ }
+
+ this_new->m_size.x -= this_new->m_pos.x;
+ this_new->m_size.y -= this_new->m_pos.y;
+
+ return true;
+}
+
+
+const EDA_RECT SCH_BUS_ENTRY_BASE::GetBoundingBox() const
+{
+ EDA_RECT box;
+
+ box.SetOrigin( m_pos );
+ box.SetEnd( m_End() );
+
+ box.Normalize();
+ box.Inflate( GetPenSize() / 2 );
+
+ return box;
+}
+
+
+int SCH_BUS_WIRE_ENTRY::GetPenSize() const
+{
+ return GetDefaultLineThickness();
+}
+
+
+int SCH_BUS_BUS_ENTRY::GetPenSize() const
+{
+ return GetDefaultBusThickness();
+}
+
+
+void SCH_BUS_ENTRY_BASE::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor )
+{
+ EDA_COLOR_T color;
+ EDA_RECT* clipbox = aPanel->GetClipBox();
+
+ if( aColor >= 0 )
+ color = aColor;
+ else
+ color = GetLayerColor( m_Layer );
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ GRLine( clipbox, aDC, m_pos.x + aOffset.x, m_pos.y + aOffset.y,
+ m_End().x + aOffset.x, m_End().y + aOffset.y, GetPenSize(), color );
+
+
+ // Draw pin targets if part is being dragged
+ bool dragging = aPanel->GetScreen()->GetCurItem() == this && aPanel->IsMouseCaptured();
+
+ if( m_isDanglingStart || dragging )
+ {
+ GRCircle( clipbox, aDC, m_pos.x + aOffset.x, m_pos.y + aOffset.y,
+ TARGET_BUSENTRY_RADIUS, 0, color );
+ }
+
+ if( m_isDanglingEnd || dragging )
+ {
+ GRCircle( clipbox, aDC, m_End().x + aOffset.x, m_End().y + aOffset.y,
+ TARGET_BUSENTRY_RADIUS, 0, color );
+ }
+}
+
+
+void SCH_BUS_ENTRY_BASE::MirrorX( int aXaxis_position )
+{
+ MIRROR( m_pos.y, aXaxis_position );
+ m_size.y = -m_size.y;
+}
+
+
+void SCH_BUS_ENTRY_BASE::MirrorY( int aYaxis_position )
+{
+ MIRROR( m_pos.x, aYaxis_position );
+ m_size.x = -m_size.x;
+}
+
+
+void SCH_BUS_ENTRY_BASE::Rotate( wxPoint aPosition )
+{
+ RotatePoint( &m_pos, aPosition, 900 );
+ RotatePoint( &m_size.x, &m_size.y, 900 );
+}
+
+
+void SCH_BUS_ENTRY_BASE::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
+{
+ DANGLING_END_ITEM item( ENTRY_END, this, m_pos );
+ aItemList.push_back( item );
+
+ DANGLING_END_ITEM item1( ENTRY_END, this, m_End() );
+ aItemList.push_back( item1 );
+}
+
+
+bool SCH_BUS_ENTRY_BASE::IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList )
+{
+ bool previousStateStart = m_isDanglingStart;
+ bool previousStateEnd = m_isDanglingEnd;
+
+ m_isDanglingStart = m_isDanglingEnd = true;
+
+ // Wires and buses are stored in the list as a pair, start and end. This
+ // variable holds the start position from one iteration so it can be used
+ // when the end position is found.
+ wxPoint seg_start;
+
+ // Special case: if both items are wires, show as dangling. This is because
+ // a bus entry between two wires will look like a connection, but does NOT
+ // actually represent one. We need to clarify this for the user.
+ bool start_is_wire = false;
+ bool end_is_wire = false;
+
+ BOOST_FOREACH( DANGLING_END_ITEM& each_item, aItemList )
+ {
+ if( each_item.GetItem() == this )
+ continue;
+
+ switch( each_item.GetType() )
+ {
+ case WIRE_START_END:
+ case BUS_START_END:
+ seg_start = each_item.GetPosition();
+ break;
+
+ case WIRE_END_END:
+ if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) )
+ start_is_wire = true;
+ if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) )
+ end_is_wire = true;
+ // Fall through
+
+ case BUS_END_END:
+ if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_pos ) )
+ m_isDanglingStart = false;
+ if( IsPointOnSegment( seg_start, each_item.GetPosition(), m_End() ) )
+ m_isDanglingEnd = false;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // See above: show as dangling if joining two wires
+ if( start_is_wire && end_is_wire )
+ m_isDanglingStart = m_isDanglingEnd = true;
+
+ return (previousStateStart != m_isDanglingStart) || (previousStateEnd != m_isDanglingEnd);
+}
+
+
+bool SCH_BUS_ENTRY_BASE::IsDangling() const
+{
+ return m_isDanglingStart || m_isDanglingEnd;
+}
+
+
+bool SCH_BUS_ENTRY_BASE::IsSelectStateChanged( const wxRect& aRect )
+{
+ bool previousState = IsSelected();
+
+ // If either end of the bus entry is inside the selection rectangle, the entire
+ // bus entry is selected. Bus entries have a fixed length and angle.
+ if( aRect.Contains( m_pos ) || aRect.Contains( m_End() ) )
+ SetFlags( SELECTED );
+ else
+ ClearFlags( SELECTED );
+
+ return previousState != IsSelected();
+}
+
+
+void SCH_BUS_ENTRY_BASE::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
+{
+ aPoints.push_back( m_pos );
+ aPoints.push_back( m_End() );
+}
+
+
+wxString SCH_BUS_WIRE_ENTRY::GetSelectMenuText() const
+{
+ return wxString( _( "Bus to Wire Entry" ) );
+}
+
+
+wxString SCH_BUS_BUS_ENTRY::GetSelectMenuText() const
+{
+ return wxString( _( "Bus to Bus Entry" ) );
+}
+
+
+bool SCH_BUS_ENTRY_BASE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
+{
+ return TestSegmentHit( aPosition, m_pos, m_End(), aAccuracy );
+}
+
+
+bool SCH_BUS_ENTRY_BASE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ EDA_RECT rect = aRect;
+
+ rect.Inflate( aAccuracy );
+
+ if( aContained )
+ return rect.Contains( GetBoundingBox() );
+
+ return rect.Intersects( GetBoundingBox() );
+}
+
+
+void SCH_BUS_ENTRY_BASE::Plot( PLOTTER* aPlotter )
+{
+ aPlotter->SetCurrentLineWidth( GetPenSize() );
+ aPlotter->SetColor( GetLayerColor( GetLayer() ) );
+ aPlotter->MoveTo( m_pos );
+ aPlotter->FinishTo( m_End() );
+}
+
+/* SetBusEntryShape:
+ * Set the shape of the bus entry.
+ * aShape = ascii code '/' or '\'
+ */
+void SCH_BUS_ENTRY_BASE::SetBusEntryShape( char aShape )
+{
+ switch( aShape )
+ {
+ case '\\':
+ if( m_size.y < 0 )
+ m_size.y = -m_size.y;
+ break;
+
+ case '/':
+ if( m_size.y > 0 )
+ m_size.y = -m_size.y;
+ break;
+ }
+}
+
+
+/* GetBusEntryShape:
+ * return the shape of the bus entry, as an ascii code '/' or '\'
+ */
+char SCH_BUS_ENTRY_BASE::GetBusEntryShape() const
+{
+ if( GetSize().y < 0 )
+ return '/';
+ else
+ return '\\';
+}
+
diff --git a/eeschema/sch_bus_entry.h b/eeschema/sch_bus_entry.h
new file mode 100644
index 0000000..5de14e6
--- /dev/null
+++ b/eeschema/sch_bus_entry.h
@@ -0,0 +1,185 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_bus_entry.h
+ *
+ */
+
+#ifndef _SCH_BUS_ENTRY_H_
+#define _SCH_BUS_ENTRY_H_
+
+#include <sch_item_struct.h>
+
+#define TARGET_BUSENTRY_RADIUS 12 // Circle diameter drawn at the ends
+
+
+/**
+ * Class SCH_BUS_ENTRY_BASE
+ *
+ * Base class for a bus or wire entry.
+ */
+class SCH_BUS_ENTRY_BASE : public SCH_ITEM
+{
+protected:
+ wxPoint m_pos;
+ wxSize m_size;
+ bool m_isDanglingStart, m_isDanglingEnd;
+
+public:
+ SCH_BUS_ENTRY_BASE( KICAD_T aType, const wxPoint& pos = wxPoint( 0, 0 ), char shape = '\\' );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~SCH_BUS_ENTRY_BASE() { }
+
+ /**
+ * Virtual function IsMovableFromAnchorPoint
+ * Return true for items which are moved with the anchor point at mouse cursor
+ * and false for items moved with no reference to anchor
+ * @return false for a bus entry
+ */
+ bool IsMovableFromAnchorPoint() { return false; }
+
+ wxPoint m_End() const;
+
+ /**
+ * function GetBusEntryShape
+ * @return the shape of the bus entry, as an ascii code '/' or '\'
+ */
+ char GetBusEntryShape() const;
+
+ /**
+ * function SetBusEntryShape
+ * @param aShape = the shape of the bus entry, as an ascii code '/' or '\'
+ */
+ void SetBusEntryShape( char aShape );
+
+ wxSize GetSize() const { return m_size; }
+
+ void SetSize( const wxSize& aSize ) { m_size = aSize; }
+
+ void SwapData( SCH_ITEM* aItem );
+
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR );
+
+ static bool Load( LINE_READER& aLine, wxString& aErrorMsg, SCH_ITEM **out );
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ void Move( const wxPoint& aMoveVector )
+ {
+ m_pos += aMoveVector;
+ }
+
+
+ void MirrorY( int aYaxis_position );
+
+ void MirrorX( int aXaxis_position );
+
+ void Rotate( wxPoint aPosition );
+
+ void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList );
+
+ bool IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList );
+
+ bool IsDangling() const;
+
+ bool IsSelectStateChanged( const wxRect& aRect );
+
+ bool IsConnectable() const { return true; }
+
+ void GetConnectionPoints( std::vector< wxPoint >& aPoints ) const;
+
+ BITMAP_DEF GetMenuImage() const { return add_entry_xpm; }
+
+ wxPoint GetPosition() const { return m_pos; }
+
+ void SetPosition( const wxPoint& aPosition ) { m_pos = aPosition; }
+
+ bool HitTest( const wxPoint& aPosition, int aAccuracy ) const;
+
+ bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const;
+
+ void Plot( PLOTTER* aPlotter );
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+};
+
+/**
+ * Class SCH_BUS_WIRE_ENTRY
+ *
+ * Class for a wire to bus entry.
+ */
+class SCH_BUS_WIRE_ENTRY : public SCH_BUS_ENTRY_BASE
+{
+public:
+ SCH_BUS_WIRE_ENTRY( const wxPoint& pos = wxPoint( 0, 0 ), char shape = '\\' );
+
+ ~SCH_BUS_WIRE_ENTRY() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_BUS_WIRE_ENTRY" );
+ }
+
+ bool Save( FILE* aFile ) const;
+
+ int GetPenSize() const;
+
+ wxString GetSelectMenuText() const;
+
+ EDA_ITEM* Clone() const;
+};
+
+/**
+ * Class SCH_BUS_WIRE_ENTRY
+ *
+ * Class for a bus to bus entry.
+ */
+class SCH_BUS_BUS_ENTRY : public SCH_BUS_ENTRY_BASE
+{
+public:
+ SCH_BUS_BUS_ENTRY( const wxPoint& pos = wxPoint( 0, 0 ), char shape = '\\' );
+
+ ~SCH_BUS_BUS_ENTRY() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_BUS_BUS_ENTRY" );
+ }
+
+ bool Save( FILE* aFile ) const;
+
+ int GetPenSize() const;
+
+ wxString GetSelectMenuText() const;
+
+ EDA_ITEM* Clone() const;
+};
+
+#endif // _SCH_BUS_ENTRY_H_
diff --git a/eeschema/sch_collectors.cpp b/eeschema/sch_collectors.cpp
new file mode 100644
index 0000000..04e6b10
--- /dev/null
+++ b/eeschema/sch_collectors.cpp
@@ -0,0 +1,571 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_collectors.cpp
+ */
+
+#include <macros.h>
+
+#include <sch_sheet_path.h>
+#include <transform.h>
+#include <sch_collectors.h>
+#include <sch_component.h>
+#include <sch_line.h>
+#include <sch_bus_entry.h>
+
+
+const KICAD_T SCH_COLLECTOR::AllItems[] = {
+ SCH_MARKER_T,
+ SCH_JUNCTION_T,
+ SCH_NO_CONNECT_T,
+ SCH_BUS_BUS_ENTRY_T,
+ SCH_BUS_WIRE_ENTRY_T,
+ SCH_LINE_T,
+ SCH_BITMAP_T,
+ SCH_TEXT_T,
+ SCH_LABEL_T,
+ SCH_GLOBAL_LABEL_T,
+ SCH_HIERARCHICAL_LABEL_T,
+ SCH_FIELD_T,
+ SCH_COMPONENT_T,
+ LIB_PIN_T,
+ SCH_SHEET_PIN_T,
+ SCH_SHEET_T,
+ EOT
+};
+
+
+const KICAD_T SCH_COLLECTOR::AllItemsButPins[] = {
+ SCH_MARKER_T,
+ SCH_JUNCTION_T,
+ SCH_NO_CONNECT_T,
+ SCH_BUS_BUS_ENTRY_T,
+ SCH_BUS_WIRE_ENTRY_T,
+ SCH_LINE_T,
+ SCH_BITMAP_T,
+ SCH_TEXT_T,
+ SCH_LABEL_T,
+ SCH_GLOBAL_LABEL_T,
+ SCH_HIERARCHICAL_LABEL_T,
+ SCH_FIELD_T,
+ SCH_COMPONENT_T,
+ SCH_SHEET_PIN_T,
+ SCH_SHEET_T,
+ EOT
+};
+
+
+const KICAD_T SCH_COLLECTOR::EditableItems[] = {
+ SCH_TEXT_T,
+ SCH_LABEL_T,
+ SCH_GLOBAL_LABEL_T,
+ SCH_HIERARCHICAL_LABEL_T,
+ SCH_FIELD_T,
+ SCH_COMPONENT_T,
+ SCH_SHEET_PIN_T,
+ SCH_SHEET_T,
+ SCH_BITMAP_T,
+ EOT
+};
+
+const KICAD_T SCH_COLLECTOR::CmpFieldValueOnly[] = {
+ SCH_FIELD_LOCATE_VALUE_T,
+ EOT
+};
+
+const KICAD_T SCH_COLLECTOR::CmpFieldReferenceOnly[] = {
+ SCH_FIELD_LOCATE_REFERENCE_T,
+ EOT
+};
+
+const KICAD_T SCH_COLLECTOR::CmpFieldFootprintOnly[] = {
+ SCH_FIELD_LOCATE_FOOTPRINT_T,
+ EOT
+};
+
+
+const KICAD_T SCH_COLLECTOR::MovableItems[] = {
+ SCH_MARKER_T,
+ SCH_JUNCTION_T,
+ SCH_NO_CONNECT_T,
+ SCH_BUS_BUS_ENTRY_T,
+ SCH_BUS_WIRE_ENTRY_T,
+// SCH_LINE_T,
+ SCH_BITMAP_T,
+ SCH_TEXT_T,
+ SCH_LABEL_T,
+ SCH_GLOBAL_LABEL_T,
+ SCH_HIERARCHICAL_LABEL_T,
+ SCH_FIELD_T,
+ SCH_COMPONENT_T,
+ SCH_SHEET_PIN_T,
+ SCH_SHEET_T,
+ EOT
+};
+
+
+const KICAD_T SCH_COLLECTOR::DraggableItems[] = {
+ SCH_JUNCTION_T,
+ SCH_BUS_BUS_ENTRY_T,
+ SCH_BUS_WIRE_ENTRY_T,
+ SCH_LINE_T,
+ SCH_LABEL_T,
+ SCH_GLOBAL_LABEL_T,
+ SCH_HIERARCHICAL_LABEL_T,
+ SCH_COMPONENT_T,
+ SCH_SHEET_T,
+ EOT
+};
+
+
+const KICAD_T SCH_COLLECTOR::RotatableItems[] = {
+ SCH_TEXT_T,
+ SCH_LABEL_T,
+ SCH_GLOBAL_LABEL_T,
+ SCH_HIERARCHICAL_LABEL_T,
+ SCH_FIELD_T,
+ SCH_COMPONENT_T,
+ SCH_SHEET_T,
+ SCH_BITMAP_T,
+ EOT
+};
+
+
+const KICAD_T SCH_COLLECTOR::ParentItems[] = {
+ SCH_MARKER_T,
+ SCH_JUNCTION_T,
+ SCH_NO_CONNECT_T,
+ SCH_BUS_BUS_ENTRY_T,
+ SCH_BUS_WIRE_ENTRY_T,
+ SCH_LINE_T,
+ SCH_TEXT_T,
+ SCH_LABEL_T,
+ SCH_GLOBAL_LABEL_T,
+ SCH_HIERARCHICAL_LABEL_T,
+ SCH_COMPONENT_T,
+ SCH_SHEET_PIN_T,
+ SCH_SHEET_T,
+ SCH_BITMAP_T,
+ EOT
+};
+
+
+const KICAD_T SCH_COLLECTOR::ComponentsOnly[] = {
+ SCH_COMPONENT_T,
+ EOT
+};
+
+
+const KICAD_T SCH_COLLECTOR::SheetsOnly[] = {
+ SCH_SHEET_T,
+ EOT
+};
+
+
+const KICAD_T SCH_COLLECTOR::SheetsAndSheetLabels[] = {
+ SCH_SHEET_PIN_T,
+ SCH_SHEET_T,
+ EOT
+};
+
+
+const KICAD_T SCH_COLLECTOR::OrientableItems[] = {
+ SCH_COMPONENT_T,
+ SCH_BITMAP_T,
+ SCH_SHEET_T,
+ EOT
+};
+
+
+SEARCH_RESULT SCH_COLLECTOR::Inspect( EDA_ITEM* aItem, const void* aTestData )
+{
+ if( aItem->Type() != LIB_PIN_T && !aItem->HitTest( m_RefPos ) )
+ return SEARCH_CONTINUE;
+
+ // Pins have special hit testing requirements that are relative to their parent
+ // SCH_COMPONENT item.
+ if( aItem->Type() == LIB_PIN_T )
+ {
+ wxCHECK_MSG( aTestData && ( (EDA_ITEM*) aTestData )->Type() == SCH_COMPONENT_T,
+ SEARCH_CONTINUE, wxT( "Cannot inspect invalid data. Bad programmer!" ) );
+
+ // Pin hit testing is relative to the components position and orientation in the
+ // schematic. The hit test position must be converted to library coordinates.
+ SCH_COMPONENT* component = (SCH_COMPONENT*) aTestData;
+ TRANSFORM transform = component->GetTransform().InverseTransform();
+ wxPoint position = transform.TransformCoordinate( m_RefPos - component->GetPosition() );
+
+ position.y *= -1; // Y axis polarity in schematic is inverted from library.
+
+ if( !aItem->HitTest( position ) )
+ return SEARCH_CONTINUE;
+ }
+
+ Append( aItem );
+
+ return SEARCH_CONTINUE;
+}
+
+
+void SCH_COLLECTOR::Collect( SCH_ITEM* aItem, const KICAD_T aFilterList[],
+ const wxPoint& aPosition )
+{
+ Empty(); // empty the collection just in case
+
+ SetScanTypes( aFilterList );
+
+ // remember where the snapshot was taken from and pass refPos to the Inspect() function.
+ SetRefPos( aPosition );
+
+ EDA_ITEM::IterateForward( aItem, this, NULL, m_ScanTypes );
+}
+
+
+bool SCH_COLLECTOR::IsCorner() const
+{
+ if( GetCount() != 2 )
+ return false;
+
+ bool is_busentry0 = (dynamic_cast<SCH_BUS_ENTRY_BASE*>( m_List[0] ) != NULL);
+ bool is_busentry1 = (dynamic_cast<SCH_BUS_ENTRY_BASE*>( m_List[1] ) != NULL);
+
+ if( (m_List[0]->Type() == SCH_LINE_T) && (m_List[1]->Type() == SCH_LINE_T) )
+ return true;
+
+ if( (m_List[0]->Type() == SCH_LINE_T) && is_busentry1 )
+ return true;
+
+ if( is_busentry0 && (m_List[1]->Type() == SCH_LINE_T) )
+ return true;
+
+ return false;
+}
+
+
+bool SCH_COLLECTOR::IsNode( bool aIncludePins ) const
+{
+ for( size_t i = 0; i < m_List.size(); i++ )
+ {
+ SCH_ITEM* item = (SCH_ITEM*) m_List[ i ];
+ KICAD_T type = item->Type();
+
+ if( type == SCH_JUNCTION_T )
+ continue;
+
+ if( type == SCH_LINE_T )
+ {
+ if( item->GetLayer() != LAYER_WIRE )
+ return false;
+
+ continue;
+ }
+
+ if( type == LIB_PIN_T )
+ {
+ if( !aIncludePins )
+ return false;
+
+ continue;
+ }
+
+ // Any other item types indicate that this collection is not a node.
+ return false;
+ }
+
+ return true;
+}
+
+
+bool SCH_COLLECTOR::IsDraggableJunction() const
+{
+ int wireEndCount = 0;
+ int wireMidPoint = 0;
+ int junctionCount = 0;
+
+ for( size_t i = 0; i < m_List.size(); i++ )
+ {
+ SCH_ITEM* item = (SCH_ITEM*) m_List[ i ];
+ KICAD_T type = item->Type();
+
+ if( type == SCH_JUNCTION_T )
+ {
+ junctionCount++;
+ continue;
+ }
+
+ if( type == SCH_LINE_T )
+ {
+ if( item->GetLayer() != LAYER_WIRE )
+ return false;
+
+ SCH_LINE* line = (SCH_LINE*) item;
+
+ if( line->IsEndPoint( m_RefPos ) )
+ wireEndCount++;
+ else
+ wireMidPoint++;
+
+ continue;
+ }
+
+ // Any other item types indicate that this collection is not a draggable junction.
+ return false;
+ }
+
+ return (wireEndCount >= 3) || ((wireEndCount >= 1) && (wireMidPoint == 1))
+ || ((wireMidPoint >= 2) && (junctionCount == 1));
+}
+
+
+bool SCH_FIND_COLLECTOR::PassedEnd() const
+{
+ bool retv = false;
+
+ wxUint32 flags = m_findReplaceData.GetFlags();
+
+ if( GetCount() == 0 )
+ return true;
+
+ if( !(flags & FR_SEARCH_WRAP) || (flags & FR_SEARCH_REPLACE) )
+ {
+ if( flags & wxFR_DOWN )
+ {
+ if( m_foundIndex >= GetCount() )
+ retv = true;
+ }
+ else
+ {
+ if( m_foundIndex < 0 )
+ retv = true;
+ }
+ }
+
+ return retv;
+}
+
+
+#if defined(DEBUG)
+
+void SCH_FIND_COLLECTOR::dump()
+{
+ int tmp = m_foundIndex;
+
+ wxLogTrace( traceFindReplace, wxT( "%d items found to replace %s with %s." ),
+ GetCount(), GetChars( m_findReplaceData.GetFindString() ),
+ GetChars( m_findReplaceData.GetReplaceString() ) );
+
+ for( m_foundIndex = 0; m_foundIndex < GetCount(); m_foundIndex++ )
+ wxLogTrace( traceFindReplace, wxT( " " ) + GetText() );
+
+ m_foundIndex = tmp;
+}
+
+#endif
+
+
+void SCH_FIND_COLLECTOR::UpdateIndex()
+{
+ wxUint32 flags = m_findReplaceData.GetFlags();
+
+ if( flags & wxFR_DOWN )
+ {
+ if( m_foundIndex < GetCount() )
+ m_foundIndex += 1;
+ if( (m_foundIndex >= GetCount()) && (flags & FR_SEARCH_WRAP) )
+ m_foundIndex = 0;
+ }
+ else
+ {
+ if( m_foundIndex >= 0 )
+ m_foundIndex -= 1;
+ if( (m_foundIndex < 0) && (flags & FR_SEARCH_WRAP) )
+ m_foundIndex = GetCount() - 1;
+ }
+}
+
+
+SCH_FIND_COLLECTOR_DATA SCH_FIND_COLLECTOR::GetFindData( int aIndex )
+{
+ wxCHECK_MSG( (unsigned) aIndex < m_data.size(), SCH_FIND_COLLECTOR_DATA(),
+ wxT( "Attempt to get find data outside of list boundary." ) );
+
+ return m_data[ aIndex ];
+}
+
+
+wxString SCH_FIND_COLLECTOR::GetText()
+{
+ wxCHECK_MSG( (GetCount() != 0) && IsValidIndex( m_foundIndex ), wxEmptyString,
+ wxT( "Cannot get found item at invalid index." ) );
+
+ SCH_FIND_COLLECTOR_DATA data = m_data[ m_foundIndex ];
+ EDA_ITEM* foundItem = m_List[ m_foundIndex ];
+
+ wxCHECK_MSG( foundItem != NULL, wxEmptyString, wxT( "Invalid found item pointer." ) );
+
+ wxString msg;
+
+ if( data.GetParent() )
+ {
+ msg.Printf( _( "Child item %s of parent item %s found in sheet %s" ),
+ GetChars( foundItem->GetSelectMenuText() ),
+ GetChars( data.GetParent()->GetSelectMenuText() ),
+ GetChars( data.GetSheetPath() ) );
+ }
+ else
+ {
+ msg.Printf( _( "Item %s found in sheet %s" ),
+ GetChars( foundItem->GetSelectMenuText() ),
+ GetChars( data.GetSheetPath() ) );
+ }
+
+ return msg;
+}
+
+
+EDA_ITEM* SCH_FIND_COLLECTOR::GetItem( SCH_FIND_COLLECTOR_DATA& aData )
+{
+ if( PassedEnd() )
+ return NULL;
+
+ aData = m_data[ m_foundIndex ];
+ return m_List[ m_foundIndex ];
+}
+
+
+bool SCH_FIND_COLLECTOR::ReplaceItem( SCH_SHEET_PATH* aSheetPath )
+{
+ if( PassedEnd() )
+ return false;
+
+ wxCHECK_MSG( IsValidIndex( m_foundIndex ), false,
+ wxT( "Invalid replace list index in SCH_FIND_COLLECTOR." ) );
+
+ EDA_ITEM* item = m_List[ m_foundIndex ];
+
+ bool replaced = item->Replace( m_findReplaceData, aSheetPath );
+
+ if( replaced )
+ SetForceSearch();
+
+ return replaced;
+}
+
+
+SEARCH_RESULT SCH_FIND_COLLECTOR::Inspect( EDA_ITEM* aItem, const void* aTestData )
+{
+ wxPoint position;
+
+ if( aItem->Matches( m_findReplaceData, m_sheetPath, &position ) )
+ {
+ if( aItem->Type() == LIB_PIN_T )
+ {
+ wxCHECK_MSG( aTestData && ( (EDA_ITEM*) aTestData )->Type() == SCH_COMPONENT_T,
+ SEARCH_CONTINUE, wxT( "Cannot inspect invalid data. Bad programmer!" ) );
+
+ // Pin positions are relative to their parent component's position and
+ // orientation in the schematic. The pin's position must be converted
+ // schematic coordinates.
+ SCH_COMPONENT* component = (SCH_COMPONENT*) aTestData;
+ TRANSFORM transform = component->GetTransform();
+ position.y = -position.y;
+ position = transform.TransformCoordinate( position ) + component->GetPosition();
+ }
+
+ Append( aItem );
+ m_data.push_back( SCH_FIND_COLLECTOR_DATA( position, m_sheetPath->PathHumanReadable(),
+ (SCH_ITEM*) aTestData ) );
+ }
+
+ return SEARCH_CONTINUE;
+}
+
+
+void SCH_FIND_COLLECTOR::SetReplaceString( const wxString &aReplaceString )
+{
+ m_findReplaceData.SetReplaceString( aReplaceString );
+}
+
+
+void SCH_FIND_COLLECTOR::Collect( SCH_FIND_REPLACE_DATA& aFindReplaceData,
+ SCH_SHEET_PATH* aSheetPath )
+{
+ if( !IsSearchRequired( aFindReplaceData ) && !m_List.empty() && !m_forceSearch )
+ return;
+
+ m_findReplaceData = aFindReplaceData;
+ Empty(); // empty the collection just in case
+ m_data.clear();
+ m_foundIndex = 0;
+ SetForceSearch( false );
+
+ if( aSheetPath )
+ {
+ m_sheetPath = aSheetPath;
+ EDA_ITEM::IterateForward( aSheetPath->LastDrawList(), this, NULL, m_ScanTypes );
+ }
+ else
+ {
+ SCH_SHEET_LIST schematic;
+ m_sheetPath = schematic.GetFirst();
+
+ while( m_sheetPath != NULL )
+ {
+ EDA_ITEM::IterateForward( m_sheetPath->LastDrawList(), this, NULL, m_ScanTypes );
+ m_sheetPath = schematic.GetNext();
+ }
+ }
+
+#if defined(DEBUG)
+ dump();
+#endif
+
+ if( m_List.size() != m_data.size() )
+ {
+ wxFAIL_MSG( wxT( "List size mismatch." ) );
+ m_List.clear();
+ m_data.clear();
+ }
+}
+
+
+SEARCH_RESULT SCH_TYPE_COLLECTOR::Inspect( EDA_ITEM* aItem, const void* aTestData )
+{
+ // The Vist() function only visits the testItem if its type was in the
+ // the scanList, so therefore we can collect anything given to us here.
+ Append( aItem );
+
+ return SEARCH_CONTINUE;
+}
+
+
+void SCH_TYPE_COLLECTOR::Collect( SCH_ITEM* aItem, const KICAD_T aFilterList[] )
+{
+ Empty(); // empty the collection
+
+ SetScanTypes( aFilterList );
+
+ EDA_ITEM::IterateForward( aItem, this, NULL, m_ScanTypes );
+}
diff --git a/eeschema/sch_collectors.h b/eeschema/sch_collectors.h
new file mode 100644
index 0000000..81f19a5
--- /dev/null
+++ b/eeschema/sch_collectors.h
@@ -0,0 +1,408 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2011-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_collectors.h
+ */
+
+#ifndef _SCH_COLLECTORS_H_
+#define _SCH_COLLECTORS_H_
+
+
+#include <class_collector.h>
+#include <sch_item_struct.h>
+#include <dialogs/dialog_schematic_find.h>
+
+
+/**
+ * Class SCH_COLLECTOR
+ */
+class SCH_COLLECTOR : public COLLECTOR
+{
+public:
+
+ /**
+ * A scan list for all schematic items.
+ */
+ static const KICAD_T AllItems[];
+
+ /**
+ * A scan list for all editable schematic items.
+ */
+ static const KICAD_T EditableItems[];
+
+ /**
+ * A scan list for a specific editable field: Value.
+ */
+ static const KICAD_T CmpFieldValueOnly[];
+
+ /**
+ * A scan list for a specific editable field: Reference.
+ */
+ static const KICAD_T CmpFieldReferenceOnly[];
+
+ /**
+ * A scan list for a specific editable field: Footprint.
+ */
+ static const KICAD_T CmpFieldFootprintOnly[];
+
+ /**
+ * A scan list for all movable schematic items.
+ */
+ static const KICAD_T MovableItems[];
+
+ /**
+ * A scan list for all draggable schematic items.
+ */
+ static const KICAD_T DraggableItems[];
+
+ /**
+ * A scan list for all rotatable schematic items.
+ */
+ static const KICAD_T RotatableItems[];
+
+ /**
+ * A scan list for only parent schematic items.
+ */
+ static const KICAD_T ParentItems[];
+
+ /**
+ * A scan list for all schematic items except pins.
+ */
+ static const KICAD_T AllItemsButPins[];
+
+ /**
+ * A scan list for schematic component items only.
+ */
+ static const KICAD_T ComponentsOnly[];
+
+ /**
+ * A scan list for schematic sheet items only.
+ */
+ static const KICAD_T SheetsOnly[];
+
+ /**
+ * A scan list for schematic sheet and sheet label items.
+ */
+ static const KICAD_T SheetsAndSheetLabels[];
+
+ /**
+ * A scan list for schematic items that can be mirrored.
+ */
+ static const KICAD_T OrientableItems[];
+
+ /**
+ * Constructor SCH_COLLECTOR
+ */
+ SCH_COLLECTOR( const KICAD_T* aScanTypes = SCH_COLLECTOR::AllItems )
+ {
+ SetScanTypes( aScanTypes );
+ }
+
+ /**
+ * Operator []
+ * overloads COLLECTOR::operator[](int) to return a SCH_ITEM* instead of
+ * an EDA_ITEM* type.
+ * @param aIndex The index into the list.
+ * @return SCH_ITEM* at \a aIndex or NULL.
+ */
+ SCH_ITEM* operator[]( int aIndex ) const
+ {
+ if( (unsigned)aIndex < (unsigned)GetCount() )
+ return (SCH_ITEM*) m_List[ aIndex ];
+
+ return NULL;
+ }
+
+ SEARCH_RESULT Inspect( EDA_ITEM* aItem, const void* aTestData = NULL );
+
+ /**
+ * Function Collect
+ * scans a SCH_ITEM using this class's Inspector method, which does the collection.
+ * @param aItem A SCH_ITEM to scan.
+ * @param aFilterList A list of #KICAD_T types with a terminating #EOT, that determines
+ * what is to be collected and the priority order of the resulting
+ * collection.
+ * @param aPosition A wxPoint to use in hit-testing.
+ */
+ void Collect( SCH_ITEM* aItem, const KICAD_T aFilterList[], const wxPoint& aPosition );
+
+ /**
+ * Function IsCorner
+ * tests if the collected items forms as corner of two line segments.
+ * @return True if the collected items form a corner of two line segments.
+ */
+ bool IsCorner() const;
+
+ /**
+ * Function IsNode
+ * tests if the collected items form a node.
+ *
+ * @param aIncludePins Indicate if component pin items should be included in the test.
+ * @return True if the collected items form a node.
+ */
+ bool IsNode( bool aIncludePins = true ) const;
+
+ /**
+ * Function IsDraggableJunction
+ * tests to see if the collected items form a draggable junction.
+ * <p>
+ * Daggable junctions are defined as:
+ * <ul>
+ * <li> The intersection of three or more wire end points. </li>
+ * <li> The intersection of one or more wire end point and one wire mid point. </li>
+ * <li> The crossing of two or more wire mid points and a junction. </li>
+ * </ul>
+ * </p>
+ * @return True if the collection is a draggable junction.
+ */
+ bool IsDraggableJunction() const;
+};
+
+
+/**
+ * Class SCH_FIND_COLLECTOR_DATA
+ * is used as a data container for the associated item found by the #SCH_FIND_COLLECTOR
+ * object.
+ */
+class SCH_FIND_COLLECTOR_DATA
+{
+ /// The position in drawing units of the found item.
+ wxPoint m_position;
+
+ /// The human readable sheet path @see SCH_SHEET_PATH::PathHumanReadable() of the found item.
+ wxString m_sheetPath;
+
+ /// The parent object if the item found is a child object.
+ SCH_ITEM* m_parent;
+
+public:
+ SCH_FIND_COLLECTOR_DATA( const wxPoint& aPosition = wxDefaultPosition,
+ const wxString& aSheetPath = wxEmptyString,
+ SCH_ITEM* aParent = NULL )
+ : m_position( aPosition )
+ , m_sheetPath( aSheetPath )
+ , m_parent( aParent )
+ { }
+
+ wxPoint GetPosition() const { return m_position; }
+
+ wxString GetSheetPath() const { return m_sheetPath; }
+
+ SCH_ITEM* GetParent() const { return m_parent; }
+};
+
+
+/**
+ * Class SCH_FIND_COLLECTOR
+ * is used to iterate over all of the items in a schematic or sheet and collect all
+ * the items that match the given search criteria.
+ */
+class SCH_FIND_COLLECTOR : public COLLECTOR
+{
+ /// Data associated with each found item.
+ std::vector< SCH_FIND_COLLECTOR_DATA > m_data;
+
+ /// The criteria used to test for matching items.
+ SCH_FIND_REPLACE_DATA m_findReplaceData;
+
+ /// The path of the sheet currently being iterated over.
+ SCH_SHEET_PATH* m_sheetPath;
+
+ /// The current found item list index.
+ int m_foundIndex;
+
+ /// A flag to indicate that the schemtic has been modified and a new search must be
+ /// performed even if the search criteria hasn't changed.
+ bool m_forceSearch;
+
+ /// last known library change hash, used to detect library changes which
+ /// should trigger cache obsolescence.
+ int m_lib_hash;
+
+ /**
+ * Function dump
+ * is a helper to dump the items in the find list for debugging purposes.
+ */
+#if defined(DEBUG)
+ void dump();
+#endif
+
+public:
+
+ /**
+ * Constructor SCH_FIND_COLLECTOR
+ */
+ SCH_FIND_COLLECTOR( const KICAD_T* aScanTypes = SCH_COLLECTOR::AllItems )
+ {
+ SetScanTypes( aScanTypes );
+ m_foundIndex = 0;
+ SetForceSearch( false );
+ m_sheetPath = NULL;
+ m_lib_hash = 0;
+ }
+
+ void Empty()
+ {
+ m_foundIndex = 0;
+ COLLECTOR::Empty();
+ m_data.clear();
+ }
+
+ void SetForceSearch( bool doSearch = true ) { m_forceSearch = doSearch; }
+
+ int GetLibHash() const { return m_lib_hash; }
+ void SetLibHash( int aHash ) { m_lib_hash = aHash; }
+
+ int GetFoundIndex() const { return m_foundIndex; }
+ void SetFoundIndex( int aIndex )
+ {
+ m_foundIndex = ( (unsigned) aIndex < m_data.size() ) ? aIndex : 0;
+ }
+
+ /**
+ * Function PassedEnd
+ * tests if #m_foundIndex is beyond the end of the list give the current
+ * find/replace criterial in #m_findReplaceData.
+ *
+ * @return True if #m_foundIndex has crossed the end of the found item list.
+ */
+ bool PassedEnd() const;
+
+ /**
+ * Function UpdateIndex
+ * updates the list index according to the current find and replace criteria.
+ */
+ void UpdateIndex();
+
+ /**
+ * Function GetFindData
+ * returns the data associated with the item found at \a aIndex.
+ *
+ * @param aIndex The list index of the data to return.
+ * @return The associated found item data at \a aIndex if \a aIndex is within the
+ * list limits. Otherwise an empty data item will be returned.
+ */
+ SCH_FIND_COLLECTOR_DATA GetFindData( int aIndex );
+
+ /**
+ * Function IsSearchRequired
+ * checks the current collector state against \a aFindReplaceData to see if a new search
+ * needs to be performed to update the collector.
+ *
+ * @param aFindReplaceData A #SCH_FIND_REPLACE_DATA object containing the search criteria
+ * to test for changes against the current search criteria.
+ * @return True if \a aFindReplaceData would require a new search to be performaed or
+ * the force search flag is true. Otherwise, false is returned.
+ */
+ bool IsSearchRequired( const SCH_FIND_REPLACE_DATA& aFindReplaceData )
+ {
+ return m_findReplaceData.ChangesCompare( aFindReplaceData ) || m_forceSearch ||
+ (m_findReplaceData.IsWrapping() != aFindReplaceData.IsWrapping());
+ }
+
+ /**
+ * Function GetText()
+ * @return A wxString object containing the description of the item found at the
+ * current index or a wxEmptyString if the list is empty or the index is
+ * invalid.
+ */
+ wxString GetText();
+
+ /**
+ * Function GetItem
+ * returns the item and associated data of the current index.
+ *
+ * @param aFindData A reference to a #SCH_FIND_COLLECTOR_DATA object to place the
+ * associated data for the current item into if the current item
+ * index is valid.
+ * @return A pointer to the current #EDA_ITEM in the list if the list index is valid
+ * Otherwise NULL is returned and the \a aFindData object is not updated.
+ */
+ EDA_ITEM* GetItem( SCH_FIND_COLLECTOR_DATA& aFindData );
+
+ /**
+ * Function ReplaceItem
+ * performs a string replace of the item at the current index.
+ *
+ * @return True if the text replace occurred otherwise false.
+ */
+ bool ReplaceItem( SCH_SHEET_PATH* aSheetPath = NULL );
+
+ SEARCH_RESULT Inspect( EDA_ITEM* aItem, const void* aTestData = NULL );
+
+ /**
+ * Update the replace string without changing anything else.
+ */
+ void SetReplaceString( const wxString &aReplaceString );
+
+ /**
+ * Function Collect
+ * scans \a aSheetPath using this class's Inspector method for items matching
+ * \a aFindReplaceData.
+ *
+ * @param aFindReplaceData A #SCH_FIND_REPLACE_DATA object containing the search criteria.
+ * @param aSheetPath A pointer to a #SCH_SHEET_PATH object to test for matches. A NULL
+ * value searches the entire schematic hierarchy.
+ */
+ void Collect( SCH_FIND_REPLACE_DATA& aFindReplaceData, SCH_SHEET_PATH* aSheetPath = NULL );
+
+ void IncrementIndex() { m_foundIndex += 1; }
+};
+
+
+/**
+ * Class TYPE_COLLECTOR
+ * merely gathers up all SCH_ITEMs of a given set of KICAD_T type(s). It does
+ * no hit-testing.
+ *
+ * @see class COLLECTOR
+ */
+class SCH_TYPE_COLLECTOR : public SCH_COLLECTOR
+{
+public:
+ /**
+ * Function Inspect
+ * is the examining function within the INSPECTOR which is passed to the
+ * Iterate function.
+ *
+ * @param testItem An EDA_ITEM to examine.
+ * @param testData is not used in this class.
+ * @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
+ * else SCAN_CONTINUE;
+ */
+ SEARCH_RESULT Inspect( EDA_ITEM* testItem, const void* testData );
+
+ /**
+ * Function Collect
+ * scans a BOARD_ITEM using this class's Inspector method, which does
+ * the collection.
+ * @param aBoard The BOARD_ITEM to scan.
+ * @param aScanList The KICAD_Ts to gather up.
+ */
+ void Collect( SCH_ITEM* aBoard, const KICAD_T aScanList[] );
+};
+
+
+#endif // _SCH_COLLECTORS_H_
diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp
new file mode 100644
index 0000000..82694d8
--- /dev/null
+++ b/eeschema/sch_component.cpp
@@ -0,0 +1,2048 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_component.cpp
+ * @brief Implementation of the class SCH_COMPONENT.
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <gr_basic.h>
+#include <kicad_string.h>
+#include <richio.h>
+#include <schframe.h>
+#include <plot_common.h>
+#include <msgpanel.h>
+#include <boost/foreach.hpp>
+
+#include <general.h>
+#include <class_library.h>
+#include <lib_rectangle.h>
+#include <lib_pin.h>
+#include <lib_text.h>
+#include <sch_component.h>
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+//#include <sch_collectors.h>
+#include <class_netlist_object.h>
+#include <lib_draw_item.h>
+
+#include <dialogs/dialog_schematic_find.h>
+
+#include <wx/tokenzr.h>
+#include <iostream>
+
+#define NULL_STRING "_NONAME_"
+
+/**
+ * Function toUTFTildaText
+ * convert a wxString to UTF8 and replace any control characters with a ~,
+ * where a control character is one of the first ASCII values up to ' ' 32d.
+ */
+static std::string toUTFTildaText( const wxString& txt )
+{
+ std::string ret = TO_UTF8( txt );
+
+ for( std::string::iterator it = ret.begin(); it!=ret.end(); ++it )
+ {
+ if( (unsigned char) *it <= ' ' )
+ *it = '~';
+ }
+ return ret;
+}
+
+
+/**
+ * Used when a LIB_PART is not found in library
+ * to draw a dummy shape
+ * This component is a 400 mils square with the text ??
+ * DEF DUMMY U 0 40 Y Y 1 0 N
+ * F0 "U" 0 -350 60 H V
+ * F1 "DUMMY" 0 350 60 H V
+ * DRAW
+ * T 0 0 0 150 0 0 0 ??
+ * S -200 200 200 -200 0 1 0
+ * ENDDRAW
+ * ENDDEF
+ */
+static LIB_PART* dummy()
+{
+ static LIB_PART* part;
+
+ if( !part )
+ {
+ part = new LIB_PART( wxEmptyString );
+
+ LIB_RECTANGLE* square = new LIB_RECTANGLE( part );
+
+ square->Move( wxPoint( -200, 200 ) );
+ square->SetEndPosition( wxPoint( 200, -200 ) );
+
+ LIB_TEXT* text = new LIB_TEXT( part );
+
+ text->SetSize( wxSize( 150, 150 ) );
+ text->SetText( wxString( wxT( "??" ) ) );
+
+ part->AddDrawItem( square );
+ part->AddDrawItem( text );
+ }
+
+ return part;
+}
+
+
+SCH_COMPONENT::SCH_COMPONENT( const wxPoint& aPos, SCH_ITEM* aParent ) :
+ SCH_ITEM( aParent, SCH_COMPONENT_T )
+{
+ Init( aPos );
+ m_currentSheetPath = NULL;
+}
+
+
+SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, SCH_SHEET_PATH* sheet, int unit,
+ int convert, const wxPoint& pos, bool setNewItemFlag ) :
+ SCH_ITEM( NULL, SCH_COMPONENT_T )
+{
+ Init( pos );
+
+ m_unit = unit;
+ m_convert = convert;
+ m_part_name = aPart.GetName();
+ m_part = aPart.SharedPtr();
+ m_currentSheetPath = NULL;
+
+ SetTimeStamp( GetNewTimeStamp() );
+
+ if( setNewItemFlag )
+ m_Flags = IS_NEW | IS_MOVED;
+
+ // Import user defined fields from the library component:
+ LIB_FIELDS libFields;
+
+ aPart.GetFields( libFields );
+
+ for( LIB_FIELDS::iterator it = libFields.begin(); it!=libFields.end(); ++it )
+ {
+ // Can no longer insert an empty name, since names are now keys. The
+ // field index is not used beyond the first MANDATORY_FIELDS
+ if( it->GetName().IsEmpty() )
+ continue;
+
+ // See if field already exists (mandatory fields always exist).
+ // for mandatory fields, the name and field id are fixed, so we use the
+ // known and fixed id to get them (more reliable than names, which can be translated)
+ // for other fields (custom fields), locate the field by same name
+ // (field id has no known meaning for custom fields)
+ int idx = it->GetId();
+ SCH_FIELD* schField;
+
+ if( idx < MANDATORY_FIELDS )
+ schField = GetField( idx );
+ else
+ schField = FindField( it->GetName() );
+
+ if( !schField )
+ {
+ SCH_FIELD fld( wxPoint( 0, 0 ), GetFieldCount(), this, it->GetName() );
+ schField = AddField( fld );
+ }
+
+ schField->SetTextPosition( m_Pos + it->GetTextPosition() );
+ schField->ImportValues( *it );
+ schField->SetText( it->GetText() );
+ }
+
+ wxString msg = aPart.GetReferenceField().GetText();
+
+ if( msg.IsEmpty() )
+ msg = wxT( "U" );
+
+ m_prefix = msg;
+
+ // update the reference -- just the prefix for now.
+ msg += wxT( "?" );
+ SetRef( sheet, msg );
+
+ // Use the schematic component name instead of the library value field
+ // name.
+ GetField( VALUE )->SetText( GetPartName() );
+}
+
+
+SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) :
+ SCH_ITEM( aComponent )
+{
+ m_currentSheetPath = NULL;
+ m_Parent = aComponent.m_Parent;
+ m_Pos = aComponent.m_Pos;
+ m_unit = aComponent.m_unit;
+ m_convert = aComponent.m_convert;
+ m_part_name = aComponent.m_part_name;
+ m_part = aComponent.m_part;
+
+ SetTimeStamp( aComponent.m_TimeStamp );
+
+ m_transform = aComponent.m_transform;
+ m_prefix = aComponent.m_prefix;
+ m_PathsAndReferences = aComponent.m_PathsAndReferences;
+ m_Fields = aComponent.m_Fields;
+
+ // Re-parent the fields, which before this had aComponent as parent
+ for( int i = 0; i<GetFieldCount(); ++i )
+ {
+ GetField( i )->SetParent( this );
+ }
+
+ m_isDangling = aComponent.m_isDangling;
+}
+
+
+void SCH_COMPONENT::Init( const wxPoint& pos )
+{
+ m_Pos = pos;
+ m_unit = 0; // In multi unit chip - which unit to draw.
+ m_convert = 0; // De Morgan Handling
+
+ // The rotation/mirror transformation matrix. pos normal
+ m_transform = TRANSFORM();
+
+ // construct only the mandatory fields, which are the first 4 only.
+ for( int i = 0; i < MANDATORY_FIELDS; ++i )
+ {
+ SCH_FIELD field( pos, i, this, TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) );
+
+ if( i == REFERENCE )
+ field.SetLayer( LAYER_REFERENCEPART );
+ else if( i == VALUE )
+ field.SetLayer( LAYER_VALUEPART );
+
+ // else keep LAYER_FIELDS from SCH_FIELD constructor
+
+ // SCH_FIELD's implicitly created copy constructor is called in here
+ AddField( field );
+ }
+
+ m_prefix = wxString( wxT( "U" ) );
+}
+
+
+EDA_ITEM* SCH_COMPONENT::Clone() const
+{
+ return new SCH_COMPONENT( *this );
+}
+
+
+void SCH_COMPONENT::SetPartName( const wxString& aName, PART_LIBS* aLibs )
+{
+ if( m_part_name != aName )
+ {
+ m_part_name = aName;
+ SetModified();
+
+ if( aLibs )
+ Resolve( aLibs );
+ else
+ m_part.reset();
+ }
+}
+
+
+bool SCH_COMPONENT::Resolve( PART_LIBS* aLibs )
+{
+ // I've never been happy that the actual individual PART_LIB is left up to
+ // flimsy search path ordering. None-the-less find a part based on that design:
+ if( LIB_PART* part = aLibs->FindLibPart( m_part_name ) )
+ {
+ m_part = part->SharedPtr();
+ return true;
+ }
+
+ return false;
+}
+
+
+void SCH_COMPONENT::ResolveAll(
+ const SCH_COLLECTOR& aComponents, PART_LIBS* aLibs )
+{
+ for( int i = 0; i < aComponents.GetCount(); ++i )
+ {
+ SCH_COMPONENT* cmp = dynamic_cast<SCH_COMPONENT*>( aComponents[i] );
+ wxASSERT( cmp );
+
+ if( cmp ) // cmp == NULL should not occur.
+ cmp->Resolve( aLibs );
+ }
+}
+
+
+void SCH_COMPONENT::SetUnit( int aUnit )
+{
+ if( m_unit != aUnit )
+ {
+ m_unit = aUnit;
+ SetModified();
+ }
+}
+
+void SCH_COMPONENT::UpdateUnit( int aUnit )
+{
+ m_unit = aUnit;
+}
+
+
+void SCH_COMPONENT::SetConvert( int aConvert )
+{
+ if( m_convert != aConvert )
+ {
+ m_convert = aConvert;
+ SetModified();
+ }
+}
+
+
+void SCH_COMPONENT::SetTransform( const TRANSFORM& aTransform )
+{
+ if( m_transform != aTransform )
+ {
+ m_transform = aTransform;
+ SetModified();
+ }
+}
+
+
+int SCH_COMPONENT::GetUnitCount() const
+{
+ if( PART_SPTR part = m_part.lock() )
+ {
+ return part->GetUnitCount();
+ }
+
+ return 0;
+}
+
+
+void SCH_COMPONENT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor,
+ bool aDrawPinText )
+{
+ if( PART_SPTR part = m_part.lock() )
+ {
+ // Draw pin targets if part is being dragged
+ bool dragging = aPanel->GetScreen()->GetCurItem() == this && aPanel->IsMouseCaptured();
+
+ part->Draw( aPanel, aDC, m_Pos + aOffset, m_unit, m_convert, aDrawMode, aColor,
+ m_transform, aDrawPinText, false, false, dragging ? NULL : &m_isDangling );
+ }
+ else // Use dummy() part if the actual cannot be found.
+ {
+ dummy()->Draw( aPanel, aDC, m_Pos + aOffset, 0, 0, aDrawMode, aColor,
+ m_transform, aDrawPinText, false );
+ }
+
+ SCH_FIELD* field = GetField( REFERENCE );
+
+ if( field->IsVisible() && !field->IsMoving() )
+ {
+ field->Draw( aPanel, aDC, aOffset, aDrawMode );
+ }
+
+ for( int ii = VALUE; ii < GetFieldCount(); ii++ )
+ {
+ field = GetField( ii );
+
+ if( field->IsMoving() )
+ continue;
+
+ field->Draw( aPanel, aDC, aOffset, aDrawMode );
+ }
+
+#if 0
+ // Only for testing purposes, draw the component bounding box
+ {
+ EDA_RECT boundingBox = GetBoundingBox();
+ GRRect( aPanel->GetClipBox(), aDC, boundingBox, 0, BROWN );
+#if 1
+ if( GetField( REFERENCE )->IsVisible() )
+ {
+ boundingBox = GetField( REFERENCE )->GetBoundingBox();
+ GRRect( aPanel->GetClipBox(), aDC, boundingBox, 0, BROWN );
+ }
+
+ if( GetField( VALUE )->IsVisible() )
+ {
+ boundingBox = GetField( VALUE )->GetBoundingBox();
+ GRRect( aPanel->GetClipBox(), aDC, boundingBox, 0, BROWN );
+ }
+#endif
+ }
+#endif
+}
+
+
+void SCH_COMPONENT::AddHierarchicalReference( const wxString& aPath,
+ const wxString& aRef,
+ int aMulti )
+{
+ wxString h_path, h_ref;
+ wxStringTokenizer tokenizer;
+ wxString separators( wxT( " " ) );
+
+ // Search for an existing path and remove it if found (should not occur)
+ for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
+ {
+ tokenizer.SetString( m_PathsAndReferences[ii], separators );
+ h_path = tokenizer.GetNextToken();
+
+ if( h_path.Cmp( aPath ) == 0 )
+ {
+ m_PathsAndReferences.RemoveAt( ii );
+ ii--;
+ }
+ }
+
+ h_ref = aPath + wxT( " " ) + aRef;
+ h_ref << wxT( " " ) << aMulti;
+ m_PathsAndReferences.Add( h_ref );
+}
+
+
+wxString SCH_COMPONENT::GetPath( const SCH_SHEET_PATH* sheet ) const
+{
+ wxCHECK_MSG( sheet != NULL, wxEmptyString,
+ wxT( "Cannot get component path with invalid sheet object." ) );
+
+ wxString str;
+
+ str.Printf( wxT( "%8.8lX" ), (long unsigned) m_TimeStamp );
+ return sheet->Path() + str;
+}
+
+
+const wxString SCH_COMPONENT::GetRef( const SCH_SHEET_PATH* sheet )
+{
+ wxString path = GetPath( sheet );
+ wxString h_path, h_ref;
+ wxStringTokenizer tokenizer;
+ wxString separators( wxT( " " ) );
+
+ for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
+ {
+ tokenizer.SetString( m_PathsAndReferences[ii], separators );
+ h_path = tokenizer.GetNextToken();
+
+ if( h_path.Cmp( path ) == 0 )
+ {
+ h_ref = tokenizer.GetNextToken();
+
+ /* printf( "GetRef hpath: %s\n",
+ * TO_UTF8( m_PathsAndReferences[ii] ) ); */
+ return h_ref;
+ }
+ }
+
+ // if it was not found in m_Paths array, then see if it is in
+ // m_Field[REFERENCE] -- if so, use this as a default for this path.
+ // this will happen if we load a version 1 schematic file.
+ // it will also mean that multiple instances of the same sheet by default
+ // all have the same component references, but perhaps this is best.
+ if( !GetField( REFERENCE )->GetText().IsEmpty() )
+ {
+ SetRef( sheet, GetField( REFERENCE )->GetText() );
+ return GetField( REFERENCE )->GetText();
+ }
+
+ return m_prefix;
+}
+
+
+/* Function IsReferenceStringValid (static function)
+ * Tests for an acceptable reference string
+ * An acceptable reference string must support unannotation
+ * i.e starts by letter
+ * returns true if OK
+ */
+bool SCH_COMPONENT::IsReferenceStringValid( const wxString& aReferenceString )
+{
+ wxString text = aReferenceString;
+ bool ok = true;
+
+ // Try to unannotate this reference
+ while( !text.IsEmpty() && ( text.Last() == '?' || isdigit( text.Last() ) ) )
+ text.RemoveLast();
+
+ if( text.IsEmpty() )
+ ok = false;
+
+ // Add here other constraints
+ // Currently:no other constraint
+
+ return ok;
+}
+
+
+void SCH_COMPONENT::SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref )
+{
+ wxString path = GetPath( sheet );
+
+ bool notInArray = true;
+
+ wxString h_path, h_ref;
+ wxStringTokenizer tokenizer;
+ wxString separators( wxT( " " ) );
+
+ // check to see if it is already there before inserting it
+ for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
+ {
+ tokenizer.SetString( m_PathsAndReferences[ii], separators );
+ h_path = tokenizer.GetNextToken();
+
+ if( h_path.Cmp( path ) == 0 )
+ {
+ // just update the reference text, not the timestamp.
+ h_ref = h_path + wxT( " " ) + ref;
+ h_ref += wxT( " " );
+ tokenizer.GetNextToken(); // Skip old reference
+ h_ref += tokenizer.GetNextToken(); // Add part selection
+ // Ann the part selection
+ m_PathsAndReferences[ii] = h_ref;
+ notInArray = false;
+ }
+ }
+
+ if( notInArray )
+ AddHierarchicalReference( path, ref, m_unit );
+
+ SCH_FIELD* rf = GetField( REFERENCE );
+
+ if( rf->GetText().IsEmpty()
+ || ( abs( rf->GetTextPosition().x - m_Pos.x ) +
+ abs( rf->GetTextPosition().y - m_Pos.y ) > 10000 ) )
+ {
+ // move it to a reasonable position
+ rf->SetTextPosition( m_Pos + wxPoint( 50, 50 ) );
+ }
+
+ rf->SetText( ref ); // for drawing.
+
+ // Reinit the m_prefix member if needed
+ wxString prefix = ref;
+
+ if( IsReferenceStringValid( prefix ) )
+ {
+ while( prefix.Last() == '?' || isdigit( prefix.Last() ) )
+ prefix.RemoveLast();
+ }
+ else
+ {
+ prefix = wxT( "U" ); // Set to default ref prefix
+ }
+
+ if( m_prefix != prefix )
+ m_prefix = prefix;
+}
+
+
+void SCH_COMPONENT::SetTimeStamp( time_t aNewTimeStamp )
+{
+ wxString string_timestamp, string_oldtimestamp;
+
+ string_timestamp.Printf( wxT( "%08lX" ), (long unsigned) aNewTimeStamp );
+ string_oldtimestamp.Printf( wxT( "%08lX" ), (long unsigned) m_TimeStamp );
+ EDA_ITEM::SetTimeStamp( aNewTimeStamp );
+
+ for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
+ {
+ m_PathsAndReferences[ii].Replace( string_oldtimestamp.GetData(),
+ string_timestamp.GetData() );
+ }
+}
+
+
+int SCH_COMPONENT::GetUnitSelection( SCH_SHEET_PATH* aSheet )
+{
+ wxString path = GetPath( aSheet );
+ wxString h_path, h_multi;
+ wxStringTokenizer tokenizer;
+ wxString separators( wxT( " " ) );
+
+ for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
+ {
+ tokenizer.SetString( m_PathsAndReferences[ii], separators );
+ h_path = tokenizer.GetNextToken();
+
+ if( h_path.Cmp( path ) == 0 )
+ {
+ tokenizer.GetNextToken(); // Skip reference
+ h_multi = tokenizer.GetNextToken();
+ long imulti = 1;
+ h_multi.ToLong( &imulti );
+ return imulti;
+ }
+ }
+
+ // if it was not found in m_Paths array, then use m_unit.
+ // this will happen if we load a version 1 schematic file.
+ return m_unit;
+}
+
+
+void SCH_COMPONENT::SetUnitSelection( SCH_SHEET_PATH* aSheet, int aUnitSelection )
+{
+ wxString path = GetPath( aSheet );
+
+ bool notInArray = true;
+
+ wxString h_path, h_ref;
+ wxStringTokenizer tokenizer;
+ wxString separators( wxT( " " ) );
+
+ //check to see if it is already there before inserting it
+ for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
+ {
+ tokenizer.SetString( m_PathsAndReferences[ii], separators );
+ h_path = tokenizer.GetNextToken();
+
+ if( h_path.Cmp( path ) == 0 )
+ {
+ //just update the unit selection.
+ h_ref = h_path + wxT( " " );
+ h_ref += tokenizer.GetNextToken(); // Add reference
+ h_ref += wxT( " " );
+ h_ref << aUnitSelection; // Add part selection
+
+ // Ann the part selection
+ m_PathsAndReferences[ii] = h_ref;
+ notInArray = false;
+ }
+ }
+
+ if( notInArray )
+ AddHierarchicalReference( path, m_prefix, aUnitSelection );
+}
+
+
+SCH_FIELD* SCH_COMPONENT::GetField( int aFieldNdx ) const
+{
+ const SCH_FIELD* field;
+
+ if( (unsigned) aFieldNdx < m_Fields.size() )
+ field = &m_Fields[aFieldNdx];
+ else
+ field = NULL;
+
+ wxASSERT( field );
+
+ // use cast to remove const-ness
+ return (SCH_FIELD*) field;
+}
+
+
+SCH_FIELD* SCH_COMPONENT::AddField( const SCH_FIELD& aField )
+{
+ int newNdx = m_Fields.size();
+
+ m_Fields.push_back( aField );
+ return &m_Fields[newNdx];
+}
+
+
+SCH_FIELD* SCH_COMPONENT::FindField( const wxString& aFieldName )
+{
+ for( unsigned i = 0; i<m_Fields.size(); ++i )
+ {
+ if( aFieldName == m_Fields[i].GetName( false ) )
+ return &m_Fields[i];
+ }
+
+ return NULL;
+}
+
+
+LIB_PIN* SCH_COMPONENT::GetPin( const wxString& number )
+{
+ if( PART_SPTR part = m_part.lock() )
+ {
+ return part->GetPin( number, m_unit, m_convert );
+ }
+ return NULL;
+}
+
+
+void SCH_COMPONENT::SwapData( SCH_ITEM* aItem )
+{
+ wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_COMPONENT_T),
+ wxT( "Cannot swap data with invalid component." ) );
+
+ SCH_COMPONENT* component = (SCH_COMPONENT*) aItem;
+
+ std::swap( m_part_name, component->m_part_name );
+ std::swap( m_part, component->m_part );
+ std::swap( m_Pos, component->m_Pos );
+ std::swap( m_unit, component->m_unit );
+ std::swap( m_convert, component->m_convert );
+
+ TRANSFORM tmp = m_transform;
+
+ m_transform = component->m_transform;
+ component->m_transform = tmp;
+
+ m_Fields.swap( component->m_Fields ); // std::vector's swap()
+
+ // Reparent items after copying data
+ // (after swap(), m_Parent member does not point to the right parent):
+ for( int ii = 0; ii < component->GetFieldCount(); ++ii )
+ {
+ component->GetField( ii )->SetParent( component );
+ }
+
+ for( int ii = 0; ii < GetFieldCount(); ++ii )
+ {
+ GetField( ii )->SetParent( this );
+ }
+
+ std::swap( m_PathsAndReferences, component->m_PathsAndReferences );
+}
+
+
+void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
+{
+ bool keepMulti = false;
+ wxArrayString reference_fields;
+
+ static const wxChar separators[] = wxT( " " );
+
+ PART_SPTR part = m_part.lock();
+
+ if( part && part->UnitsLocked() )
+ keepMulti = true;
+
+ // Build a reference with no annotation,
+ // i.e. a reference ended by only one '?'
+ wxString defRef = m_prefix;
+
+ if( IsReferenceStringValid( defRef ) )
+ {
+ while( defRef.Last() == '?' )
+ defRef.RemoveLast();
+ }
+ else
+ { // This is a malformed reference: reinit this reference
+ m_prefix = defRef = wxT("U"); // Set to default ref prefix
+ }
+
+ defRef.Append( wxT( "?" ) );
+
+ wxString multi = wxT( "1" );
+
+ // For components with units locked,
+ // we cannot remove all annotations: part selection must be kept
+ // For all components: if aSheetPath is not NULL,
+ // remove annotation only for the given path
+ if( keepMulti || aSheetPath )
+ {
+ wxString NewHref;
+ wxString path;
+
+ if( aSheetPath )
+ path = GetPath( aSheetPath );
+
+ for( unsigned int ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
+ {
+ // Break hierarchical reference in path, ref and multi selection:
+ reference_fields = wxStringTokenize( m_PathsAndReferences[ii], separators );
+
+ if( aSheetPath == NULL || reference_fields[0].Cmp( path ) == 0 )
+ {
+ if( keepMulti ) // Get and keep part selection
+ multi = reference_fields[2];
+
+ NewHref = reference_fields[0];
+ NewHref << wxT( " " ) << defRef << wxT( " " ) << multi;
+ m_PathsAndReferences[ii] = NewHref;
+ }
+ }
+ }
+ else
+ {
+ // Clear reference strings, but does not free memory because a new annotation
+ // will reuse it
+ m_PathsAndReferences.Empty();
+ m_unit = 1;
+ }
+
+ // These 2 changes do not work in complex hierarchy.
+ // When a clear annotation is made, the calling function must call a
+ // UpdateAllScreenReferences for the active sheet.
+ // But this call cannot made here.
+ m_Fields[REFERENCE].SetText( defRef ); //for drawing.
+
+ SetModified();
+}
+
+
+void SCH_COMPONENT::SetOrientation( int aOrientation )
+{
+ TRANSFORM temp = TRANSFORM();
+ bool transform = false;
+
+ switch( aOrientation )
+ {
+ case CMP_ORIENT_0:
+ case CMP_NORMAL: // default transform matrix
+ m_transform.x1 = 1;
+ m_transform.y2 = -1;
+ m_transform.x2 = m_transform.y1 = 0;
+ break;
+
+ case CMP_ROTATE_COUNTERCLOCKWISE: // Rotate + (incremental rotation)
+ temp.x1 = temp.y2 = 0;
+ temp.y1 = 1;
+ temp.x2 = -1;
+ transform = true;
+ break;
+
+ case CMP_ROTATE_CLOCKWISE: // Rotate - (incremental rotation)
+ temp.x1 = temp.y2 = 0;
+ temp.y1 = -1;
+ temp.x2 = 1;
+ transform = true;
+ break;
+
+ case CMP_MIRROR_Y: // Mirror Y (incremental rotation)
+ temp.x1 = -1;
+ temp.y2 = 1;
+ temp.y1 = temp.x2 = 0;
+ transform = true;
+ break;
+
+ case CMP_MIRROR_X: // Mirror X (incremental rotation)
+ temp.x1 = 1;
+ temp.y2 = -1;
+ temp.y1 = temp.x2 = 0;
+ transform = true;
+ break;
+
+ case CMP_ORIENT_90:
+ SetOrientation( CMP_ORIENT_0 );
+ SetOrientation( CMP_ROTATE_COUNTERCLOCKWISE );
+ break;
+
+ case CMP_ORIENT_180:
+ SetOrientation( CMP_ORIENT_0 );
+ SetOrientation( CMP_ROTATE_COUNTERCLOCKWISE );
+ SetOrientation( CMP_ROTATE_COUNTERCLOCKWISE );
+ break;
+
+ case CMP_ORIENT_270:
+ SetOrientation( CMP_ORIENT_0 );
+ SetOrientation( CMP_ROTATE_CLOCKWISE );
+ break;
+
+ case ( CMP_ORIENT_0 + CMP_MIRROR_X ):
+ SetOrientation( CMP_ORIENT_0 );
+ SetOrientation( CMP_MIRROR_X );
+ break;
+
+ case ( CMP_ORIENT_0 + CMP_MIRROR_Y ):
+ SetOrientation( CMP_ORIENT_0 );
+ SetOrientation( CMP_MIRROR_Y );
+ break;
+
+ case ( CMP_ORIENT_90 + CMP_MIRROR_X ):
+ SetOrientation( CMP_ORIENT_90 );
+ SetOrientation( CMP_MIRROR_X );
+ break;
+
+ case ( CMP_ORIENT_90 + CMP_MIRROR_Y ):
+ SetOrientation( CMP_ORIENT_90 );
+ SetOrientation( CMP_MIRROR_Y );
+ break;
+
+ case ( CMP_ORIENT_180 + CMP_MIRROR_X ):
+ SetOrientation( CMP_ORIENT_180 );
+ SetOrientation( CMP_MIRROR_X );
+ break;
+
+ case ( CMP_ORIENT_180 + CMP_MIRROR_Y ):
+ SetOrientation( CMP_ORIENT_180 );
+ SetOrientation( CMP_MIRROR_Y );
+ break;
+
+ case ( CMP_ORIENT_270 + CMP_MIRROR_X ):
+ SetOrientation( CMP_ORIENT_270 );
+ SetOrientation( CMP_MIRROR_X );
+ break;
+
+ case ( CMP_ORIENT_270 + CMP_MIRROR_Y ):
+ SetOrientation( CMP_ORIENT_270 );
+ SetOrientation( CMP_MIRROR_Y );
+ break;
+
+ default:
+ transform = false;
+ wxMessageBox( wxT( "SetRotateMiroir() error: ill value" ) );
+ break;
+ }
+
+ if( transform )
+ {
+ /* The new matrix transform is the old matrix transform modified by the
+ * requested transformation, which is the temp transform (rot,
+ * mirror ..) in order to have (in term of matrix transform):
+ * transform coord = new_m_transform * coord
+ * where transform coord is the coord modified by new_m_transform from
+ * the initial value coord.
+ * new_m_transform is computed (from old_m_transform and temp) to
+ * have:
+ * transform coord = old_m_transform * temp
+ */
+ TRANSFORM newTransform;
+
+ newTransform.x1 = m_transform.x1 * temp.x1 + m_transform.x2 * temp.y1;
+ newTransform.y1 = m_transform.y1 * temp.x1 + m_transform.y2 * temp.y1;
+ newTransform.x2 = m_transform.x1 * temp.x2 + m_transform.x2 * temp.y2;
+ newTransform.y2 = m_transform.y1 * temp.x2 + m_transform.y2 * temp.y2;
+ m_transform = newTransform;
+ }
+}
+
+
+int SCH_COMPONENT::GetOrientation()
+{
+ int type_rotate = CMP_ORIENT_0;
+ TRANSFORM transform;
+ int ii;
+
+ #define ROTATE_VALUES_COUNT 12
+
+ // list of all possibilities, but only the first 8 are actually used
+ int rotate_value[ROTATE_VALUES_COUNT] =
+ {
+ CMP_ORIENT_0, CMP_ORIENT_90, CMP_ORIENT_180,
+ CMP_ORIENT_270,
+ CMP_MIRROR_X + CMP_ORIENT_0, CMP_MIRROR_X + CMP_ORIENT_90,
+ CMP_MIRROR_X + CMP_ORIENT_180, CMP_MIRROR_X + CMP_ORIENT_270,
+ CMP_MIRROR_Y + CMP_ORIENT_0, CMP_MIRROR_Y + CMP_ORIENT_90,
+ CMP_MIRROR_Y + CMP_ORIENT_180, CMP_MIRROR_Y + CMP_ORIENT_270
+ };
+
+ // Try to find the current transform option:
+ transform = m_transform;
+
+ for( ii = 0; ii < ROTATE_VALUES_COUNT; ii++ )
+ {
+ type_rotate = rotate_value[ii];
+ SetOrientation( type_rotate );
+
+ if( transform == m_transform )
+ return type_rotate;
+ }
+
+ // Error: orientation not found in list (should not happen)
+ wxMessageBox( wxT( "Component orientation matrix internal error" ) );
+ m_transform = transform;
+
+ return CMP_NORMAL;
+}
+
+
+wxPoint SCH_COMPONENT::GetScreenCoord( const wxPoint& aPoint )
+{
+ return m_transform.TransformCoordinate( aPoint );
+}
+
+
+#if defined(DEBUG)
+
+void SCH_COMPONENT::Show( int nestLevel, std::ostream& os ) const
+{
+ // for now, make it look like XML:
+ NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
+ << " ref=\"" << TO_UTF8( GetField( 0 )->GetName() )
+ << '"' << " chipName=\""
+ << TO_UTF8( GetPartName() ) << '"' << m_Pos
+ << " layer=\"" << m_Layer
+ << '"' << ">\n";
+
+ // skip the reference, it's been output already.
+ for( int i = 1; i < GetFieldCount(); ++i )
+ {
+ wxString value = GetField( i )->GetText();
+
+ if( !value.IsEmpty() )
+ {
+ NestedSpace( nestLevel + 1, os ) << "<field" << " name=\""
+ << TO_UTF8( GetField( i )->GetName() )
+ << '"' << " value=\""
+ << TO_UTF8( value ) << "\"/>\n";
+ }
+ }
+
+ NestedSpace( nestLevel, os ) << "</" << TO_UTF8( GetClass().Lower() ) << ">\n";
+}
+
+#endif
+
+
+bool SCH_COMPONENT::Save( FILE* f ) const
+{
+ std::string name1;
+ std::string name2;
+ wxArrayString reference_fields;
+
+ static wxString delimiters( wxT( " " ) );
+
+ // this is redundant with the AR entries below, but it makes the
+ // files backwards-compatible.
+ if( m_PathsAndReferences.GetCount() > 0 )
+ {
+ reference_fields = wxStringTokenize( m_PathsAndReferences[0], delimiters );
+
+ name1 = toUTFTildaText( reference_fields[1] );
+ }
+ else
+ {
+ if( GetField( REFERENCE )->GetText().IsEmpty() )
+ name1 = toUTFTildaText( m_prefix );
+ else
+ name1 = toUTFTildaText( GetField( REFERENCE )->GetText() );
+ }
+
+ wxString part_name = GetPartName();
+
+ if( part_name.size() )
+ {
+ name2 = toUTFTildaText( part_name );
+ }
+ else
+ {
+ name2 = NULL_STRING;
+ }
+
+ if( fprintf( f, "$Comp\n" ) == EOF )
+ return false;
+
+ if( fprintf( f, "L %s %s\n", name2.c_str(), name1.c_str() ) == EOF )
+ return false;
+
+ // Generate unit number, convert and time stamp
+ if( fprintf( f, "U %d %d %8.8lX\n", m_unit, m_convert, m_TimeStamp ) == EOF )
+ return false;
+
+ // Save the position
+ if( fprintf( f, "P %d %d\n", m_Pos.x, m_Pos.y ) == EOF )
+ return false;
+
+ /* If this is a complex hierarchy; save hierarchical references.
+ * but for simple hierarchies it is not necessary.
+ * the reference inf is already saved
+ * this is useful for old Eeschema version compatibility
+ */
+ if( m_PathsAndReferences.GetCount() > 1 )
+ {
+ for( unsigned int ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
+ {
+ /*format:
+ * AR Path="/140/2" Ref="C99" Part="1"
+ * where 140 is the uid of the containing sheet
+ * and 2 is the timestamp of this component.
+ * (timestamps are actually 8 hex chars)
+ * Ref is the conventional component reference for this 'path'
+ * Part is the conventional component part selection for this 'path'
+ */
+ reference_fields = wxStringTokenize( m_PathsAndReferences[ii], delimiters );
+
+ if( fprintf( f, "AR Path=\"%s\" Ref=\"%s\" Part=\"%s\" \n",
+ TO_UTF8( reference_fields[0] ),
+ TO_UTF8( reference_fields[1] ),
+ TO_UTF8( reference_fields[2] ) ) == EOF )
+ return false;
+ }
+ }
+
+ // update the ugly field index, which I would like to see go away someday soon.
+ for( unsigned i = 0; i<m_Fields.size(); ++i )
+ {
+ SCH_FIELD* fld = GetField( i );
+ fld->SetId( i ); // we don't need field Ids, please be gone.
+ }
+
+ // Fixed fields:
+ // Save mandatory fields even if they are blank,
+ // because the visibility, size and orientation are set from libary editor.
+ for( unsigned i = 0; i<MANDATORY_FIELDS; ++i )
+ {
+ SCH_FIELD* fld = GetField( i );
+ if( !fld->Save( f ) )
+ return false;
+ }
+
+ // User defined fields:
+ // The *policy* about which user defined fields are part of a symbol is now
+ // only in the dialog editors. No policy should be enforced here, simply
+ // save all the user defined fields, they are present because a dialog editor
+ // thought they should be. If you disagree, go fix the dialog editors.
+ for( unsigned i = MANDATORY_FIELDS; i<m_Fields.size(); ++i )
+ {
+ SCH_FIELD* fld = GetField( i );
+
+ if( !fld->Save( f ) )
+ return false;
+ }
+
+ // Unit number, position, box ( old standard )
+ if( fprintf( f, "\t%-4d %-4d %-4d\n", m_unit, m_Pos.x, m_Pos.y ) == EOF )
+ return false;
+
+ if( fprintf( f, "\t%-4d %-4d %-4d %-4d\n",
+ m_transform.x1, m_transform.y1, m_transform.x2, m_transform.y2 ) == EOF )
+ return false;
+
+ if( fprintf( f, "$EndComp\n" ) == EOF )
+ return false;
+
+ return true;
+}
+
+
+bool SCH_COMPONENT::Load( LINE_READER& aLine, wxString& aErrorMsg )
+{
+ // Remark: avoid using sscanf to read texts entered by user
+ // which are UTF8 encoded, because sscanf does not work well on Windows
+ // with some UTF8 values.
+ int ii;
+ char name1[256],
+ char1[256], char2[256], char3[256];
+ int newfmt = 0;
+ char* ptcar;
+ wxString fieldName;
+ char* line = aLine.Line();
+
+ m_convert = 1;
+
+ if( line[0] == '$' )
+ {
+ newfmt = 1;
+
+ if( !(line = aLine.ReadLine()) )
+ return true;
+ }
+
+ // Parse the first line of description:
+ // like "L partname ref" (for instance "L 74LS00 U4"
+ // They are UTF8 texts, so do not use sscanf
+
+ line += 1;
+
+ if( *line == ' ' )
+ line++;
+
+ // line points the first parameter
+ wxString buffer( FROM_UTF8( line ) );
+ wxStringTokenizer tokenizer( buffer, wxT( " \r\n" ) );
+
+ if( tokenizer.CountTokens() < 2 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema component description error at line %d, aborted" ),
+ aLine.LineNumber() );
+ aErrorMsg << wxT( "\n" ) << FROM_UTF8( line );
+ return false;
+ }
+
+ wxString partname = tokenizer.NextToken();
+ partname.Replace( wxT("~"), wxT(" ") ); // all spaces were replaced by ~ in files.
+
+ if( partname != NULL_STRING )
+ {
+ SetPartName( partname );
+
+ if( !newfmt )
+ GetField( VALUE )->SetText( partname );
+ }
+ else
+ {
+ m_part_name.Empty();
+ GetField( VALUE )->Empty();
+ GetField( VALUE )->SetOrientation( TEXT_ORIENT_HORIZ );
+ GetField( VALUE )->SetVisible( false );
+ }
+
+ wxString reference = tokenizer.NextToken();
+ reference.Replace( wxT("~"), wxT(" ") ); // all spaces were replaced by ~ in files.
+ reference.Trim( true );
+ reference.Trim( false );
+
+ if( reference != NULL_STRING )
+ {
+ wxString prefix = reference;
+ // Build reference prefix from the actual reference by removing trailing digits
+ // (Perhaps outdated code, only for very old schematic files)
+ while( prefix.Length() )
+ {
+ if( ( prefix.Last() < '0' || prefix.Last() > '9') && prefix.Last() != '?' )
+ break;
+
+ prefix.RemoveLast();
+ }
+
+ // Avoid a prefix containing trailing/leading spaces
+ prefix.Trim( true );
+ prefix.Trim( false );
+
+ if( prefix.IsEmpty() )
+ m_prefix = wxT( "U" );
+ else
+ m_prefix = prefix;
+
+ if( !newfmt )
+ GetField( REFERENCE )->SetText( reference );
+ }
+ else
+ {
+ GetField( REFERENCE )->SetVisible( false );
+ }
+
+ /* Parse component description
+ * These lines begin with:
+ * "P" = Position
+ * U = Num Unit and Conversion
+ * "Fn" = Fields (0 .. n = = number of field)
+ * "Ar" = Alternate reference in the case of multiple sheets referring to
+ * one schematic file.
+ */
+ for( ; ; )
+ {
+ if( !(line = aLine.ReadLine()) )
+ return false;
+
+ if( line[0] == 'U' )
+ {
+ sscanf( line + 1, "%d %d %lX", &m_unit, &m_convert, &m_TimeStamp );
+ }
+ else if( line[0] == 'P' )
+ {
+ sscanf( line + 1, "%d %d", &m_Pos.x, &m_Pos.y );
+
+ // Set fields position to a default position (that is the
+ // component position. For existing fields, the real position
+ // will be set later
+ for( int i = 0; i<GetFieldCount(); i++ )
+ {
+ if( GetField( i )->GetText().IsEmpty() )
+ GetField( i )->SetTextPosition( m_Pos );
+ }
+ }
+ else if( line[0] == 'A' && line[1] == 'R' )
+ {
+ /* format:
+ * AR Path="/9086AF6E/67452AA0" Ref="C99" Part="1"
+ * where 9086AF6E is the unique timestamp of the containing sheet
+ * and 67452AA0 is the timestamp of this component.
+ * C99 is the reference given this path.
+ */
+ int ii;
+ ptcar = line + 2;
+
+ //copy the path.
+ ii = ReadDelimitedText( name1, ptcar, 255 );
+ ptcar += ii + 1;
+ wxString path = FROM_UTF8( name1 );
+
+ // copy the reference
+ ii = ReadDelimitedText( name1, ptcar, 255 );
+ ptcar += ii + 1;
+ wxString ref = FROM_UTF8( name1 );
+
+ // copy the multi, if exists
+ ii = ReadDelimitedText( name1, ptcar, 255 );
+
+ if( name1[0] == 0 ) // Nothing read, put a default value
+ sprintf( name1, "%d", m_unit );
+
+ int multi = atoi( name1 );
+
+ if( multi < 0 || multi > 26 )
+ multi = 1;
+
+ AddHierarchicalReference( path, ref, multi );
+ GetField( REFERENCE )->SetText( ref );
+ }
+ else if( line[0] == 'F' )
+ {
+ int fieldNdx;
+
+ wxString fieldText;
+ EDA_TEXT_HJUSTIFY_T hjustify = GR_TEXT_HJUSTIFY_CENTER;
+ EDA_TEXT_VJUSTIFY_T vjustify = GR_TEXT_VJUSTIFY_CENTER;
+
+ ptcar = (char*) aLine;
+
+ while( *ptcar && (*ptcar != '"') )
+ ptcar++;
+
+ if( *ptcar != '"' )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file library field F at line %d, aborted" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ ptcar += ReadDelimitedText( &fieldText, ptcar );
+
+ if( *ptcar == 0 )
+ {
+ aErrorMsg.Printf( wxT( "Component field F at line %d, aborted" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ fieldNdx = atoi( line + 2 );
+
+ ReadDelimitedText( &fieldName, ptcar );
+
+ if( fieldName.IsEmpty() )
+ fieldName = TEMPLATE_FIELDNAME::GetDefaultFieldName( fieldNdx );
+
+ if( fieldNdx >= GetFieldCount() )
+ {
+ // The first MANDATOR_FIELDS _must_ be constructed within
+ // the SCH_COMPONENT constructor. This assert is simply here
+ // to guard against a change in that constructor.
+ wxASSERT( GetFieldCount() >= MANDATORY_FIELDS );
+
+ // Ignore the _supplied_ fieldNdx. It is not important anymore
+ // if within the user defined fields region (i.e. >= MANDATORY_FIELDS).
+ // We freely renumber the index to fit the next available field slot.
+
+ fieldNdx = GetFieldCount(); // new has this index after insertion
+
+ SCH_FIELD field( wxPoint( 0, 0 ),
+ -1, // field id is not relavant for user defined fields
+ this, fieldName );
+
+ AddField( field );
+ }
+ else
+ {
+ GetField( fieldNdx )->SetName( fieldName );
+ }
+
+ GetField( fieldNdx )->SetText( fieldText );
+ memset( char3, 0, sizeof(char3) );
+ int x, y, w, attr;
+
+ if( ( ii = sscanf( ptcar, "%255s %d %d %d %X %255s %255s", char1, &x, &y, &w, &attr,
+ char2, char3 ) ) < 4 )
+ {
+ aErrorMsg.Printf( wxT( "Component Field error line %d, aborted" ),
+ aLine.LineNumber() );
+ continue;
+ }
+
+ GetField( fieldNdx )->SetTextPosition( wxPoint( x, y ) );
+ GetField( fieldNdx )->SetAttributes( attr );
+
+ if( (w == 0 ) || (ii == 4) )
+ w = GetDefaultTextSize();
+
+ GetField( fieldNdx )->SetSize( wxSize( w, w ) );
+ GetField( fieldNdx )->SetOrientation( TEXT_ORIENT_HORIZ );
+
+ if( char1[0] == 'V' )
+ GetField( fieldNdx )->SetOrientation( TEXT_ORIENT_VERT );
+
+ if( ii >= 7 )
+ {
+ if( *char2 == 'L' )
+ hjustify = GR_TEXT_HJUSTIFY_LEFT;
+ else if( *char2 == 'R' )
+ hjustify = GR_TEXT_HJUSTIFY_RIGHT;
+
+ if( char3[0] == 'B' )
+ vjustify = GR_TEXT_VJUSTIFY_BOTTOM;
+ else if( char3[0] == 'T' )
+ vjustify = GR_TEXT_VJUSTIFY_TOP;
+
+ GetField( fieldNdx )->SetItalic( char3[1] == 'I' );
+ GetField( fieldNdx )->SetBold( char3[2] == 'B' );
+ GetField( fieldNdx )->SetHorizJustify( hjustify );
+ GetField( fieldNdx )->SetVertJustify( vjustify );
+ }
+
+ if( fieldNdx == REFERENCE )
+ if( GetField( fieldNdx )->GetText()[0] == '#' )
+ GetField( fieldNdx )->SetVisible( false );
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if( sscanf( line, "%d %d %d", &m_unit, &m_Pos.x, &m_Pos.y ) != 3 )
+ {
+ aErrorMsg.Printf( wxT( "Component unit & pos error at line %d, aborted" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ if( !(line = aLine.ReadLine()) ||
+ sscanf( line, "%d %d %d %d",
+ &m_transform.x1,
+ &m_transform.y1,
+ &m_transform.x2,
+ &m_transform.y2 ) != 4 )
+ {
+ aErrorMsg.Printf( wxT( "Component orient error at line %d, aborted" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ if( newfmt )
+ {
+ if( !(line = aLine.ReadLine()) )
+ return false;
+
+ if( strnicmp( "$End", line, 4 ) != 0 )
+ {
+ aErrorMsg.Printf( wxT( "Component End expected at line %d, aborted" ),
+ aLine.LineNumber() );
+ return false;
+ }
+ }
+
+ // ensure flags (mainly used in edit) are cleared.
+ // some changes have set the modified flag
+ m_Flags = 0;
+
+ return true;
+}
+
+
+EDA_RECT SCH_COMPONENT::GetBodyBoundingBox() const
+{
+ EDA_RECT bBox;
+
+ if( PART_SPTR part = m_part.lock() )
+ {
+ bBox = part->GetBodyBoundingBox( m_unit, m_convert );
+ }
+ else
+ {
+ bBox = dummy()->GetBodyBoundingBox( m_unit, m_convert );
+ }
+
+ int x0 = bBox.GetX();
+ int xm = bBox.GetRight();
+
+ // We must reverse Y values, because matrix orientation
+ // suppose Y axis normal for the library items coordinates,
+ // m_transform reverse Y values, but bBox is already reversed!
+ int y0 = -bBox.GetY();
+ int ym = -bBox.GetBottom();
+
+ // Compute the real Boundary box (rotated, mirrored ...)
+ int x1 = m_transform.x1 * x0 + m_transform.y1 * y0;
+ int y1 = m_transform.x2 * x0 + m_transform.y2 * y0;
+ int x2 = m_transform.x1 * xm + m_transform.y1 * ym;
+ int y2 = m_transform.x2 * xm + m_transform.y2 * ym;
+
+ // H and W must be > 0:
+ if( x2 < x1 )
+ std::swap( x2, x1 );
+
+ if( y2 < y1 )
+ std::swap( y2, y1 );
+
+ bBox.SetX( x1 );
+ bBox.SetY( y1 );
+ bBox.SetWidth( x2 - x1 );
+ bBox.SetHeight( y2 - y1 );
+
+ bBox.Offset( m_Pos );
+ return bBox;
+}
+
+
+const EDA_RECT SCH_COMPONENT::GetBoundingBox() const
+{
+ EDA_RECT bbox = GetBodyBoundingBox();
+
+ for( size_t i = 0; i < m_Fields.size(); i++ )
+ {
+ bbox.Merge( m_Fields[i].GetBoundingBox() );
+ }
+
+ return bbox;
+}
+
+
+void SCH_COMPONENT::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
+{
+ // part and alias can differ if alias is not the root
+ if( PART_SPTR part = m_part.lock() )
+ {
+ LIB_ALIAS* alias = part->GetAlias( GetPartName() );
+
+ if( !alias )
+ return;
+
+ if( m_currentSheetPath )
+ aList.push_back( MSG_PANEL_ITEM( _( "Reference" ),
+ GetRef( m_currentSheetPath ),
+ DARKCYAN ) );
+
+ wxString msg = part->IsPower() ? _( "Power symbol" ) : _( "Value" );
+
+ aList.push_back( MSG_PANEL_ITEM( msg, GetField( VALUE )->GetShownText(), DARKCYAN ) );
+
+ // Display component reference in library and library
+ aList.push_back( MSG_PANEL_ITEM( _( "Component" ), GetPartName(), BROWN ) );
+
+ if( alias->GetName() != part->GetName() )
+ aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), part->GetName(), BROWN ) );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Library" ), alias->GetLibraryName(), BROWN ) );
+
+ // Display the current associated footprint, if exists.
+ if( !GetField( FOOTPRINT )->IsVoid() )
+ msg = GetField( FOOTPRINT )->GetShownText();
+ else
+ msg = _( "<Unknown>" );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), msg, DARKRED ) );
+
+ // Display description of the component, and keywords found in lib
+ aList.push_back( MSG_PANEL_ITEM( _( "Description" ), alias->GetDescription(), DARKCYAN ) );
+ aList.push_back( MSG_PANEL_ITEM( _( "Key Words" ), alias->GetKeyWords(), DARKCYAN ) );
+ }
+}
+
+
+void SCH_COMPONENT::MirrorY( int aYaxis_position )
+{
+ int dx = m_Pos.x;
+
+ SetOrientation( CMP_MIRROR_Y );
+ MIRROR( m_Pos.x, aYaxis_position );
+ dx -= m_Pos.x; // dx,0 is the move vector for this transform
+
+ for( int ii = 0; ii < GetFieldCount(); ii++ )
+ {
+ // Move the fields to the new position because the component itself has moved.
+ wxPoint pos = GetField( ii )->GetTextPosition();
+ pos.x -= dx;
+ GetField( ii )->SetTextPosition( pos );
+ }
+}
+
+
+void SCH_COMPONENT::MirrorX( int aXaxis_position )
+{
+ int dy = m_Pos.y;
+
+ SetOrientation( CMP_MIRROR_X );
+ MIRROR( m_Pos.y, aXaxis_position );
+ dy -= m_Pos.y; // dy,0 is the move vector for this transform
+
+ for( int ii = 0; ii < GetFieldCount(); ii++ )
+ {
+ // Move the fields to the new position because the component itself has moved.
+ wxPoint pos = GetField( ii )->GetTextPosition();
+ pos.y -= dy;
+ GetField( ii )->SetTextPosition( pos );
+ }
+}
+
+
+void SCH_COMPONENT::Rotate( wxPoint aPosition )
+{
+ wxPoint prev = m_Pos;
+
+ RotatePoint( &m_Pos, aPosition, 900 );
+
+ SetOrientation( CMP_ROTATE_COUNTERCLOCKWISE );
+
+ for( int ii = 0; ii < GetFieldCount(); ii++ )
+ {
+ // Move the fields to the new position because the component itself has moved.
+ wxPoint pos = GetField( ii )->GetTextPosition();
+ pos.x -= prev.x - m_Pos.x;
+ pos.y -= prev.y - m_Pos.y;
+ GetField( ii )->SetTextPosition( pos );
+ }
+}
+
+
+bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData,
+ wxPoint* aFindLocation )
+{
+ wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText() );
+
+ // Components are searchable via the child field and pin item text.
+ return false;
+}
+
+
+void SCH_COMPONENT::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
+{
+ if( PART_SPTR part = m_part.lock() )
+ {
+ for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
+ {
+ wxASSERT( pin->Type() == LIB_PIN_T );
+
+ if( pin->GetUnit() && m_unit && ( m_unit != pin->GetUnit() ) )
+ continue;
+
+ if( pin->GetConvert() && m_convert && ( m_convert != pin->GetConvert() ) )
+ continue;
+
+ DANGLING_END_ITEM item( PIN_END, pin, GetPinPhysicalPosition( pin ) );
+ aItemList.push_back( item );
+ }
+ }
+}
+
+
+bool SCH_COMPONENT::IsPinDanglingStateChanged( std::vector<DANGLING_END_ITEM> &aItemList,
+ LIB_PINS& aLibPins, unsigned aPin )
+{
+ bool previousState;
+
+ if( aPin < m_isDangling.size() )
+ {
+ previousState = m_isDangling[aPin];
+ m_isDangling[aPin] = true;
+ }
+ else
+ {
+ previousState = true;
+ m_isDangling.push_back( true );
+ }
+
+ wxPoint pin_position = GetPinPhysicalPosition( aLibPins[aPin] );
+
+ BOOST_FOREACH( DANGLING_END_ITEM& each_item, aItemList )
+ {
+ // Some people like to stack pins on top of each other in a symbol to indicate
+ // internal connection. While technically connected, it is not particularly useful
+ // to display them that way, so skip any pins that are in the same symbol as this
+ // one.
+ //
+ // Do not make this exception for hidden pins, because those actually make internal
+ // connections to a power net.
+ const LIB_PIN* item_pin = dynamic_cast<const LIB_PIN*>( each_item.GetItem() );
+
+ if( item_pin
+ && ( !item_pin->IsPowerConnection() || !IsInNetlist() )
+ && std::find( aLibPins.begin(), aLibPins.end(), item_pin) != aLibPins.end() )
+ continue;
+
+ switch( each_item.GetType() )
+ {
+ case PIN_END:
+ case LABEL_END:
+ case SHEET_LABEL_END:
+ case WIRE_START_END:
+ case WIRE_END_END:
+ case NO_CONNECT_END:
+ case JUNCTION_END:
+ if( pin_position == each_item.GetPosition() )
+ m_isDangling[aPin] = false;
+ break;
+ default:
+ break;
+ }
+ if( !m_isDangling[aPin] )
+ break;
+ }
+
+ return previousState != m_isDangling[aPin];
+}
+
+
+bool SCH_COMPONENT::IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList )
+{
+ bool changed = false;
+ LIB_PINS libPins;
+ if( PART_SPTR part = m_part.lock() )
+ part->GetPins( libPins, m_unit, m_convert );
+ for( size_t i = 0; i < libPins.size(); ++i )
+ {
+ if( IsPinDanglingStateChanged( aItemList, libPins, i ) )
+ changed = true;
+ }
+ return changed;
+}
+
+
+bool SCH_COMPONENT::IsDangling() const
+{
+ BOOST_FOREACH( bool each, m_isDangling )
+ {
+ if( each )
+ return true;
+ }
+ return false;
+}
+
+
+wxPoint SCH_COMPONENT::GetPinPhysicalPosition( LIB_PIN* Pin )
+{
+ wxCHECK_MSG( Pin != NULL && Pin->Type() == LIB_PIN_T, wxPoint( 0, 0 ),
+ wxT( "Cannot get physical position of pin." ) );
+
+ return m_transform.TransformCoordinate( Pin->GetPosition() ) + m_Pos;
+}
+
+
+bool SCH_COMPONENT::IsSelectStateChanged( const wxRect& aRect )
+{
+ bool previousState = IsSelected();
+
+ EDA_RECT boundingBox = GetBoundingBox();
+
+ if( aRect.Intersects( boundingBox ) )
+ SetFlags( SELECTED );
+ else
+ ClearFlags( SELECTED );
+
+ return previousState != IsSelected();
+}
+
+
+void SCH_COMPONENT::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
+{
+ if( PART_SPTR part = m_part.lock() )
+ {
+ for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
+ {
+ wxCHECK_RET( pin->Type() == LIB_PIN_T,
+ wxT( "GetNextPin() did not return a pin object. Bad programmer!" ) );
+
+ // Skip items not used for this part.
+ if( m_unit && pin->GetUnit() && ( pin->GetUnit() != m_unit ) )
+ continue;
+
+ if( m_convert && pin->GetConvert() && ( pin->GetConvert() != m_convert ) )
+ continue;
+
+ // Calculate the pin position relative to the component position and orientation.
+ aPoints.push_back( m_transform.TransformCoordinate( pin->GetPosition() ) + m_Pos );
+ }
+ }
+ else
+ {
+ wxCHECK_RET( 0,
+ wxT( "Cannot add connection points to list. Cannot find component <" ) +
+ GetPartName() + wxT( "> in any of the loaded libraries." ) );
+ }
+}
+
+
+LIB_ITEM* SCH_COMPONENT::GetDrawItem( const wxPoint& aPosition, KICAD_T aType )
+{
+ if( PART_SPTR part = m_part.lock() )
+ {
+ // Calculate the position relative to the component.
+ wxPoint libPosition = aPosition - m_Pos;
+
+ return part->LocateDrawItem( m_unit, m_convert, aType, libPosition, m_transform );
+ }
+
+ return NULL;
+}
+
+
+wxString SCH_COMPONENT::GetSelectMenuText() const
+{
+ wxString tmp;
+ tmp.Printf( _( "Component %s, %s" ),
+ GetChars( GetPartName() ),
+ GetChars( GetField( REFERENCE )->GetShownText() ) );
+ return tmp;
+}
+
+
+SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR* aInspector, const void* aTestData,
+ const KICAD_T aFilterTypes[] )
+{
+ KICAD_T stype;
+
+ for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
+ {
+ // If caller wants to inspect component type or and component children types.
+ if( stype == Type() )
+ {
+ if( SEARCH_QUIT == aInspector->Inspect( this, aTestData ) )
+ return SEARCH_QUIT;
+ }
+
+ switch( stype )
+ {
+ case SCH_FIELD_T:
+ // Test the bounding boxes of fields if they are visible and not empty.
+ for( int ii = 0; ii < GetFieldCount(); ii++ )
+ {
+ if( SEARCH_QUIT == aInspector->Inspect( GetField( ii ), (void*) this ) )
+ return SEARCH_QUIT;
+ }
+ break;
+
+ case SCH_FIELD_LOCATE_REFERENCE_T:
+ if( SEARCH_QUIT == aInspector->Inspect( GetField( REFERENCE ), (void*) this ) )
+ return SEARCH_QUIT;
+ break;
+
+ case SCH_FIELD_LOCATE_VALUE_T:
+ if( SEARCH_QUIT == aInspector->Inspect( GetField( VALUE ), (void*) this ) )
+ return SEARCH_QUIT;
+ break;
+
+ case SCH_FIELD_LOCATE_FOOTPRINT_T:
+ if( SEARCH_QUIT == aInspector->Inspect( GetField( FOOTPRINT ), (void*) this ) )
+ return SEARCH_QUIT;
+ break;
+
+
+ case LIB_PIN_T:
+ if( PART_SPTR part = m_part.lock() )
+ {
+ LIB_PINS pins;
+
+ part->GetPins( pins, m_unit, m_convert );
+
+ for( size_t i = 0; i < pins.size(); i++ )
+ {
+ if( SEARCH_QUIT == aInspector->Inspect( pins[ i ], (void*) this ) )
+ return SEARCH_QUIT;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return SEARCH_CONTINUE;
+}
+
+
+void SCH_COMPONENT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
+ SCH_SHEET_PATH* aSheetPath )
+{
+ if( PART_SPTR part = m_part.lock() )
+ {
+ for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
+ {
+ wxASSERT( pin->Type() == LIB_PIN_T );
+
+ if( pin->GetUnit() && ( pin->GetUnit() != GetUnitSelection( aSheetPath ) ) )
+ continue;
+
+ if( pin->GetConvert() && ( pin->GetConvert() != GetConvert() ) )
+ continue;
+
+ wxPoint pos = GetTransform().TransformCoordinate( pin->GetPosition() ) + m_Pos;
+
+ NETLIST_OBJECT* item = new NETLIST_OBJECT();
+ item->m_SheetPathInclude = *aSheetPath;
+ item->m_Comp = (SCH_ITEM*) pin;
+ item->m_SheetPath = *aSheetPath;
+ item->m_Type = NET_PIN;
+ item->m_Link = (SCH_ITEM*) this;
+ item->m_ElectricalType = pin->GetType();
+ item->m_PinNum = pin->GetNumber();
+ item->m_Label = pin->GetName();
+ item->m_Start = item->m_End = pos;
+
+ aNetListItems.push_back( item );
+
+ if( pin->IsPowerConnection() )
+ {
+ // There is an associated PIN_LABEL.
+ item = new NETLIST_OBJECT();
+ item->m_SheetPathInclude = *aSheetPath;
+ item->m_Comp = NULL;
+ item->m_SheetPath = *aSheetPath;
+ item->m_Type = NET_PINLABEL;
+ item->m_Label = pin->GetName();
+ item->m_Start = pos;
+ item->m_End = item->m_Start;
+
+ aNetListItems.push_back( item );
+ }
+ }
+ }
+}
+
+
+bool SCH_COMPONENT::operator <( const SCH_ITEM& aItem ) const
+{
+ if( Type() != aItem.Type() )
+ return Type() < aItem.Type();
+
+ SCH_COMPONENT* component = (SCH_COMPONENT*) &aItem;
+
+ EDA_RECT rect = GetBodyBoundingBox();
+
+ if( rect.GetArea() != component->GetBodyBoundingBox().GetArea() )
+ return rect.GetArea() < component->GetBodyBoundingBox().GetArea();
+
+ if( m_Pos.x != component->m_Pos.x )
+ return m_Pos.x < component->m_Pos.x;
+
+ if( m_Pos.y != component->m_Pos.y )
+ return m_Pos.y < component->m_Pos.y;
+
+ return false;
+}
+
+
+bool SCH_COMPONENT::operator==( const SCH_COMPONENT& aComponent ) const
+{
+ if( GetFieldCount() != aComponent.GetFieldCount() )
+ return false;
+
+ for( int i = VALUE; i < GetFieldCount(); i++ )
+ {
+ if( GetField( i )->GetText().Cmp( aComponent.GetField( i )->GetText() ) != 0 )
+ return false;
+ }
+
+ return true;
+}
+
+
+bool SCH_COMPONENT::operator!=( const SCH_COMPONENT& aComponent ) const
+{
+ return !( *this == aComponent );
+}
+
+
+SCH_ITEM& SCH_COMPONENT::operator=( const SCH_ITEM& aItem )
+{
+ wxCHECK_MSG( Type() == aItem.Type(), *this,
+ wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
+ GetClass() );
+
+ if( &aItem != this )
+ {
+ SCH_ITEM::operator=( aItem );
+
+ SCH_COMPONENT* c = (SCH_COMPONENT*) &aItem;
+
+ m_part_name = c->m_part_name;
+ m_part = c->m_part;
+ m_Pos = c->m_Pos;
+ m_unit = c->m_unit;
+ m_convert = c->m_convert;
+ m_transform = c->m_transform;
+
+ m_PathsAndReferences = c->m_PathsAndReferences;
+
+ m_Fields = c->m_Fields; // std::vector's assignment operator.
+
+ // Reparent fields after assignment to new component.
+ for( int ii = 0; ii < GetFieldCount(); ++ii )
+ {
+ GetField( ii )->SetParent( this );
+ }
+ }
+
+ return *this;
+}
+
+
+bool SCH_COMPONENT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
+{
+ EDA_RECT bBox = GetBodyBoundingBox();
+ bBox.Inflate( aAccuracy );
+
+ if( bBox.Contains( aPosition ) )
+ return true;
+
+ return false;
+}
+
+
+bool SCH_COMPONENT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ if( m_Flags & STRUCT_DELETED || m_Flags & SKIP_STRUCT )
+ return false;
+
+ EDA_RECT rect = aRect;
+
+ rect.Inflate( aAccuracy );
+
+ if( aContained )
+ return rect.Contains( GetBodyBoundingBox() );
+
+ return rect.Intersects( GetBodyBoundingBox() );
+}
+
+
+bool SCH_COMPONENT::doIsConnected( const wxPoint& aPosition ) const
+{
+ std::vector< wxPoint > pts;
+
+ GetConnectionPoints( pts );
+
+ for( size_t i = 0; i < pts.size(); i++ )
+ {
+ if( pts[i] == aPosition )
+ return true;
+ }
+
+ return false;
+}
+
+
+bool SCH_COMPONENT::IsInNetlist() const
+{
+ SCH_FIELD* rf = GetField( REFERENCE );
+ return ! rf->GetText().StartsWith( wxT( "#" ) );
+}
+
+
+void SCH_COMPONENT::Plot( PLOTTER* aPlotter )
+{
+ TRANSFORM temp;
+
+ if( PART_SPTR part = m_part.lock() )
+ {
+ temp = GetTransform();
+
+ part->Plot( aPlotter, GetUnit(), GetConvert(), m_Pos, temp );
+
+ for( size_t i = 0; i < m_Fields.size(); i++ )
+ {
+ m_Fields[i].Plot( aPlotter );
+ }
+ }
+}
diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h
new file mode 100644
index 0000000..8984fc4
--- /dev/null
+++ b/eeschema/sch_component.h
@@ -0,0 +1,496 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_component.h
+ * @brief Definition the SCH_COMPONENT class for Eeschema.
+ */
+
+#ifndef COMPONENT_CLASS_H
+#define COMPONENT_CLASS_H
+
+
+#include <sch_field.h>
+#include <transform.h>
+#include <general.h>
+#include <boost/weak_ptr.hpp>
+#include <vector>
+#include <lib_draw_item.h>
+
+class SCH_SHEET_PATH;
+class LIB_ITEM;
+class LIB_PIN;
+class LIB_PART;
+class NETLIST_OBJECT_LIST;
+class LIB_PART;
+class PART_LIBS;
+class SCH_COLLECTOR;
+
+
+/// A container for several SCH_FIELD items
+typedef std::vector<SCH_FIELD> SCH_FIELDS;
+
+typedef boost::weak_ptr<LIB_PART> PART_REF;
+
+
+/**
+ * Class SCH_COMPONENT
+ * describes a real schematic component
+ */
+class SCH_COMPONENT : public SCH_ITEM
+{
+ friend class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC;
+
+ wxPoint m_Pos;
+ wxString m_part_name; ///< Name to look for in the library, i.e. "74LS00".
+
+ int m_unit; ///< The unit for multiple part per package components.
+ int m_convert; ///< The alternate body style for components that have more than
+ ///< one body style defined. Primarily used for components that
+ ///< have a De Morgan conversion.
+ wxString m_prefix; ///< C, R, U, Q etc - the first character which typically indicates
+ ///< what the component is. Determined, upon placement, from the
+ ///< library component. Created upon file load, by the first
+ ///< non-digits in the reference fields.
+ TRANSFORM m_transform; ///< The rotation/mirror transformation matrix.
+ SCH_FIELDS m_Fields; ///< Variable length list of fields.
+
+ PART_REF m_part; ///< points into the PROJECT's libraries to the LIB_PART for this component
+
+ std::vector<bool> m_isDangling; ///< One isDangling per pin
+
+ /**
+ * A temporary sheet path is required to generate the correct reference designator string
+ * in complex heirarchies. Hopefully this is only a temporary hack to decouple schematic
+ * objects from the drawing window until a better design for handling complex heirarchies
+ * can be implemented.
+ */
+ const SCH_SHEET_PATH* m_currentSheetPath;
+
+ /**
+ * Defines the hierarchical path and reference of the component. This allows support
+ * for hierarchical sheets that reference the same schematic. The format for the path
+ * is /&ltsheet time stamp&gt/&ltsheet time stamp&gt/.../&lscomponent time stamp&gt.
+ * A single / denotes the root sheet.
+ */
+ wxArrayString m_PathsAndReferences;
+
+ void Init( const wxPoint& pos = wxPoint( 0, 0 ) );
+
+ EDA_RECT GetBodyBoundingBox() const;
+
+public:
+ SCH_COMPONENT( const wxPoint& pos = wxPoint( 0, 0 ), SCH_ITEM* aParent = NULL );
+
+ /**
+ * Create schematic component from library component object.
+ *
+ * @param aPart - library part to create schematic component from.
+ * @param aSheet - Schematic sheet the component is place into.
+ * @param unit - Part for components that have multiple parts per
+ * package.
+ * @param convert - Use the alternate body style for the schematic
+ * component.
+ * @param pos - Position to place new component.
+ * @param setNewItemFlag - Set the component IS_NEW and IS_MOVED flags.
+ */
+ SCH_COMPONENT( LIB_PART& aPart, SCH_SHEET_PATH* aSheet,
+ int unit = 0, int convert = 0,
+ const wxPoint& pos = wxPoint( 0, 0 ),
+ bool setNewItemFlag = false );
+
+ /**
+ * Copy Constructor
+ * clones \a aComponent into a new object. All fields are copied as is except
+ * for the linked list management pointers which are set to NULL, and the
+ * SCH_FIELD's m_Parent pointers which are set to the new parent,
+ * i.e. this new object.
+ */
+ SCH_COMPONENT( const SCH_COMPONENT& aComponent );
+
+ ~SCH_COMPONENT() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_COMPONENT" );
+ }
+
+ /**
+ * Virtual function IsMovableFromAnchorPoint
+ * Return true for items which are moved with the anchor point at mouse cursor
+ * and false for items moved with no reference to anchor
+ * Usually return true for small items (labels, junctions) and false for
+ * items which can be large (hierarchical sheets, compoments)
+ * @return false for a componant
+ */
+ bool IsMovableFromAnchorPoint() { return false; }
+
+ void SetPartName( const wxString& aName, PART_LIBS* aLibs=NULL );
+ const wxString& GetPartName() const { return m_part_name; }
+
+ /**
+ * Function Resolve
+ * [re-]assigns the current LIB_PART from aLibs which this component
+ * is based on.
+ * @param aLibs is the current set of LIB_PARTs to choose from.
+ */
+ bool Resolve( PART_LIBS* aLibs );
+
+ static void ResolveAll( const SCH_COLLECTOR& aComponents, PART_LIBS* aLibs );
+
+ int GetUnit() const { return m_unit; }
+
+ /**
+ * change the unit id to aUnit
+ * has maening only for multiple parts per package
+ * Also set the modified flag bit
+ * @param aUnit = the new unit Id
+ */
+ void SetUnit( int aUnit );
+
+ /**
+ * change the unit id to aUnit
+ * has maening only for multiple parts per package
+ * Do not change the modified flag bit, and should be used when
+ * change is not due to an edition command
+ * @param aUnit = the new unit Id
+ */
+ void UpdateUnit( int aUnit );
+
+ int GetConvert() const { return m_convert; }
+
+ void SetConvert( int aConvert );
+
+ wxString GetPrefix() const { return m_prefix; }
+
+ TRANSFORM& GetTransform() const { return const_cast< TRANSFORM& >( m_transform ); }
+
+ void SetTransform( const TRANSFORM& aTransform );
+
+ /**
+ * Function GetUnitCount
+ * returns the number of parts per package of the component.
+ *
+ * @return The number of parts per package or zero if the library entry cannot be found.
+ */
+ int GetUnitCount() const;
+
+ bool Save( FILE* aFile ) const;
+
+ bool Load( LINE_READER& aLine, wxString& aErrorMsg );
+
+ /**
+ * Function SetOrientation
+ * computes the new transform matrix based on \a aOrientation for the component which is
+ * applied to the current transform.
+ * @param aOrientation The orientation to apply to the transform.
+ */
+ void SetOrientation( int aOrientation );
+
+ /**
+ * Function GetOrientation
+ * Used to display component orientation (in dialog editor or info)
+ * @return the orientation and mirror
+ * Note: Because there are different ways to have a given orientation/mirror,
+ * the orientation/mirror is not necessary what the used does
+ * (example : a mirrorX then a mirrorY give no mirror but rotate the
+ * component).
+ * So this function find a rotation and a mirror value
+ * ( CMP_MIRROR_X because this is the first mirror option tested)
+ * but can differs from the orientation made by an user
+ * ( a CMP_MIRROR_Y is find as a CMP_MIRROR_X + orientation 180, because
+ * they are equivalent)
+ */
+ int GetOrientation();
+
+ /**
+ * Function GetScreenCoord
+ * Returns the coordinated point relative to the orientation of the component of \a aPoint.
+ * The coordinates are always relative to the anchor position of the component.
+ * @param aPoint The coordinates to transform.
+ * @return The transformed point.
+ */
+ wxPoint GetScreenCoord( const wxPoint& aPoint );
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ /**
+ * Function ClearAnnotation
+ * clears exiting component annotation ( i.i IC23 changed to IC? and part reset to 1)
+ * @param aSheetPath: SCH_SHEET_PATH value: if NULL remove all annotations,
+ * else remove annotation relative to this sheetpath
+ */
+ void ClearAnnotation( SCH_SHEET_PATH* aSheetPath );
+
+ /**
+ * Function SetTimeStamp
+ * changes the time stamp to \a aNewTimeStamp updates the reference path.
+ * @see m_PathsAndReferences
+ * @param aNewTimeStamp = new time stamp
+ */
+ void SetTimeStamp( time_t aNewTimeStamp );
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ //-----<Fields>-----------------------------------------------------------
+
+ /**
+ * Function GetField
+ * returns a field.
+ * @param aFieldNdx An index into the array of fields, not a field id.
+ * @return SCH_FIELD* - the field value or NULL if does not exist
+ */
+ SCH_FIELD* GetField( int aFieldNdx ) const;
+
+ /**
+ * Function AddField
+ * adds a field to the component. The field is copied as it is put into
+ * the component.
+ * @param aField A const reference to the SCH_FIELD to add.
+ * @return SCH_FIELD* - the newly inserted field.
+ */
+ SCH_FIELD* AddField( const SCH_FIELD& aField );
+
+ /**
+ * Function FindField
+ * searches for SCH_FIELD with \a aFieldName and returns it if found, else NULL.
+ */
+ SCH_FIELD* FindField( const wxString& aFieldName );
+
+ void SetFields( const SCH_FIELDS& aFields )
+ {
+ m_Fields = aFields; // vector copying, length is changed possibly
+ }
+
+ //-----</Fields>----------------------------------------------------------
+
+ /**
+ * Function GetFieldCount
+ * returns the number of fields in this component.
+ */
+ int GetFieldCount() const { return (int) m_Fields.size(); }
+
+ /**
+ * Function GetPin
+ * finds a component pin by number.
+ *
+ * @param number - The number of the pin to find.
+ * @return Pin object if found, otherwise NULL.
+ */
+ LIB_PIN* GetPin( const wxString& number );
+
+ /**
+ * Virtual function, from the base class SCH_ITEM::Draw
+ */
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR )
+ {
+ Draw( aPanel, aDC, aOffset, aDrawMode, aColor, true );
+ }
+
+ /**
+ * Function Draw, specific to components.
+ * Draw a component, with or without pin texts.
+ * @param aPanel DrawPanel to use (can be null) mainly used for clipping purposes.
+ * @param aDC Device Context (can be null)
+ * @param aOffset drawing Offset (usually wxPoint(0,0),
+ * but can be different when moving an object)
+ * @param aDrawMode GR_OR, GR_XOR, ...
+ * @param aColor UNSPECIFIED_COLOR to use the normal body item color, or use this color if >= 0
+ * @param aDrawPinText = true to draw pin texts, false to draw only the pin shape
+ * usually false to draw a component when moving it, and true otherwise.
+ */
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor,
+ bool aDrawPinText );
+
+ void SwapData( SCH_ITEM* aItem );
+
+ // returns a unique ID, in the form of a path.
+ wxString GetPath( const SCH_SHEET_PATH* sheet ) const;
+
+ /**
+ * Function IsReferenceStringValid (static)
+ * Tests for an acceptable reference string
+ * An acceptable reference string must support unannotation
+ * i.e starts by letter
+ * @param aReferenceString = the reference string to validate
+ * @return true if OK
+ */
+ static bool IsReferenceStringValid( const wxString& aReferenceString );
+
+ void SetCurrentSheetPath( const SCH_SHEET_PATH* aSheetPath )
+ {
+ m_currentSheetPath = aSheetPath;
+ }
+
+ /**
+ * Function GetRef
+ * returns the reference, for the given sheet path.
+ */
+ const wxString GetRef( const SCH_SHEET_PATH* sheet );
+
+ /**
+ * Set the reference, for the given sheet path.
+ */
+ void SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref );
+
+ /**
+ * Function AddHierarchicalReference
+ * adds a full hierarchical reference (path + local reference)
+ * @param aPath Hierarchical path (/&ltsheet timestamp&gt/&ltcomponent
+ * timestamp&gt like /05678E50/A23EF560)
+ * @param aRef :local reference like C45, R56
+ * @param aMulti Part selection, used in multi part per package (0 or 1 for non multi)
+ */
+ void AddHierarchicalReference( const wxString& aPath,
+ const wxString& aRef,
+ int aMulti );
+
+ // returns the unit selection, for the given sheet path.
+ int GetUnitSelection( SCH_SHEET_PATH* aSheet );
+
+ // Set the unit selection, for the given sheet path.
+ void SetUnitSelection( SCH_SHEET_PATH* aSheet, int aUnitSelection );
+
+ // Geometric transforms (used in block operations):
+
+ void Move( const wxPoint& aMoveVector )
+ {
+ if( aMoveVector == wxPoint( 0, 0 ) )
+ return;
+
+ m_Pos += aMoveVector;
+
+ for( int ii = 0; ii < GetFieldCount(); ii++ )
+ GetField( ii )->Move( aMoveVector );
+
+ SetModified();
+ }
+
+ void MirrorY( int aYaxis_position );
+
+ void MirrorX( int aXaxis_position );
+
+ void Rotate( wxPoint aPosition );
+
+ bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
+
+ void GetEndPoints( std::vector<DANGLING_END_ITEM>& aItemList );
+
+ /**
+ * Test if the component's dangling state has changed for one given pin index. As
+ * a side effect, actually update the dangling status for that pin.
+ *
+ * @param aItemList - list of all DANGLING_END_ITEMs to be tested
+ * @param aLibPins - list of all the LIB_PIN items in this component's symbol
+ * @param aPin - index into aLibPins that identifies the pin to test
+ * @return true if the pin's state has changed.
+ */
+ bool IsPinDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList,
+ LIB_PINS& aLibPins, unsigned aPin );
+
+ /**
+ * Test if the component's dangling state has changed for all pins. As a side
+ * effect, actually update the dangling status for all pins (does not short-circuit).
+ *
+ * @param aItemList - list of all DANGLING_END_ITEMs to be tested
+ * @return true if any pin's state has changed.
+ */
+ bool IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList );
+
+ /**
+ * Return whether any pin has dangling status. Does NOT update the internal status,
+ * only checks the existing status.
+ */
+ bool IsDangling() const;
+
+ wxPoint GetPinPhysicalPosition( LIB_PIN* Pin );
+
+ bool IsSelectStateChanged( const wxRect& aRect );
+
+ bool IsConnectable() const { return true; }
+
+ /**
+ * @return true if the component is in netlist
+ * which means this is not a power component, or something
+ * like a component reference starting by #
+ */
+ bool IsInNetlist() const;
+
+ void GetConnectionPoints( std::vector<wxPoint>& aPoints ) const;
+
+ SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
+ const KICAD_T scanTypes[] );
+
+ /**
+ * Function GetDrawItem().
+ * Return the component library item at \a aPosition that is part of this component.
+ *
+ * @param aPosition - Schematic position of the component library object.
+ * @param aType - Type of component library object to find or any if set to TYPE_NOT_INIT.
+ * @return A pointer to the component library object if found, otherwise NULL.
+ */
+ LIB_ITEM* GetDrawItem( const wxPoint& aPosition, KICAD_T aType = TYPE_NOT_INIT );
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_component_xpm; }
+
+ void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
+ SCH_SHEET_PATH* aSheetPath );
+
+ bool operator <( const SCH_ITEM& aItem ) const;
+
+ bool operator==( const SCH_COMPONENT& aComponent) const;
+ bool operator!=( const SCH_COMPONENT& aComponent) const;
+
+ SCH_ITEM& operator=( const SCH_ITEM& aItem );
+
+ bool IsReplaceable() const { return true; }
+
+ wxPoint GetPosition() const { return m_Pos; }
+
+ void SetPosition( const wxPoint& aPosition ) { Move( aPosition - m_Pos ); }
+
+ bool HitTest( const wxPoint& aPosition, int aAccuracy ) const;
+
+ bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const;
+
+ void Plot( PLOTTER* aPlotter );
+
+ EDA_ITEM* Clone() const;
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // override
+#endif
+
+private:
+ bool doIsConnected( const wxPoint& aPosition ) const;
+};
+
+
+#endif /* COMPONENT_CLASS_H */
diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp
new file mode 100644
index 0000000..46b8834
--- /dev/null
+++ b/eeschema/sch_field.cpp
@@ -0,0 +1,589 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_field.cpp
+ * @brief Implementation of the SCH_FIELD class.
+ */
+
+/* Fields are texts attached to a component, having a special meaning
+ * Fields 0 and 1 are very important: reference and value
+ * Field 2 is used as default footprint name.
+ * Field 3 is reserved (not currently used
+ * Fields 4 and more are user fields.
+ * They can be renamed and can appear in reports
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <base_struct.h>
+#include <gr_basic.h>
+#include <drawtxt.h>
+#include <macros.h>
+#include <schframe.h>
+#include <plot_common.h>
+
+#include <general.h>
+#include <class_library.h>
+#include <sch_component.h>
+#include <sch_field.h>
+#include <kicad_string.h>
+
+
+SCH_FIELD::SCH_FIELD( const wxPoint& aPos, int aFieldId, SCH_COMPONENT* aParent, wxString aName ) :
+ SCH_ITEM( aParent, SCH_FIELD_T ),
+ EDA_TEXT()
+{
+ m_Pos = aPos;
+ m_id = aFieldId;
+ m_Attributs = TEXT_NO_VISIBLE;
+ m_name = aName;
+
+ SetLayer( LAYER_FIELDS );
+}
+
+
+SCH_FIELD::~SCH_FIELD()
+{
+}
+
+
+EDA_ITEM* SCH_FIELD::Clone() const
+{
+ return new SCH_FIELD( *this );
+}
+
+
+const wxString SCH_FIELD::GetFullyQualifiedText() const
+{
+ wxString text = m_Text;
+
+ /* For more than one part per package, we must add the part selection
+ * A, B, ... or 1, 2, .. to the reference. */
+ if( m_id == REFERENCE )
+ {
+ SCH_COMPONENT* component = (SCH_COMPONENT*) m_Parent;
+
+ wxCHECK_MSG( component != NULL, text,
+ wxT( "No component associated with field" ) + text );
+
+ if( component->GetUnitCount() > 1 )
+ text << LIB_PART::SubReference( component->GetUnit() );
+ }
+
+ return text;
+}
+
+
+int SCH_FIELD::GetPenSize() const
+{
+ int pensize = m_Thickness;
+
+ if( pensize == 0 ) // Use default values for pen size
+ {
+ if( m_Bold )
+ pensize = GetPenSizeForBold( m_Size.x );
+ else
+ pensize = GetDefaultLineThickness();
+ }
+
+ // Clip pen size for small texts:
+ pensize = Clamp_Text_PenSize( pensize, m_Size, m_Bold );
+ return pensize;
+}
+
+
+void SCH_FIELD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor )
+{
+ int orient;
+ EDA_COLOR_T color;
+ wxPoint textpos;
+ SCH_COMPONENT* parentComponent = (SCH_COMPONENT*) m_Parent;
+ int LineWidth = m_Thickness;
+
+ if( LineWidth == 0 ) // Use default values for pen size
+ {
+ if( m_Bold )
+ LineWidth = GetPenSizeForBold( m_Size.x );
+ else
+ LineWidth = GetDefaultLineThickness();
+ }
+
+ // Clip pen size for small texts:
+ LineWidth = Clamp_Text_PenSize( LineWidth, m_Size, m_Bold );
+
+ if( ((m_Attributs & TEXT_NO_VISIBLE) && !m_forceVisible) || IsVoid() )
+ return;
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ // Calculate the text orientation according to the component orientation.
+ orient = m_Orient;
+
+ if( parentComponent->GetTransform().y1 ) // Rotate component 90 degrees.
+ {
+ if( orient == TEXT_ORIENT_HORIZ )
+ orient = TEXT_ORIENT_VERT;
+ else
+ orient = TEXT_ORIENT_HORIZ;
+ }
+
+ /* Calculate the text justification, according to the component
+ * orientation/mirror this is a bit complicated due to cumulative
+ * calculations:
+ * - numerous cases (mirrored or not, rotation)
+ * - the DrawGraphicText function recalculate also H and H justifications
+ * according to the text orientation.
+ * - When a component is mirrored, the text is not mirrored and
+ * justifications are complicated to calculate
+ * so the more easily way is to use no justifications ( Centered text )
+ * and use GetBoundaryBox to know the text coordinate considered as centered
+ */
+ EDA_RECT boundaryBox = GetBoundingBox();
+ textpos = boundaryBox.Centre() + aOffset;
+
+ if( m_forceVisible )
+ {
+ color = DARKGRAY;
+ }
+ else
+ {
+ if( m_id == REFERENCE )
+ color = GetLayerColor( LAYER_REFERENCEPART );
+ else if( m_id == VALUE )
+ color = GetLayerColor( LAYER_VALUEPART );
+ else
+ color = GetLayerColor( LAYER_FIELDS );
+ }
+
+ EDA_RECT* clipbox = aPanel ? aPanel->GetClipBox() : NULL;
+ DrawGraphicText( clipbox, aDC, textpos, color, GetFullyQualifiedText(), orient, m_Size,
+ GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
+ LineWidth, m_Italic, m_Bold );
+
+ // While moving: don't loose visual contact to which component this label belongs.
+ if ( IsWireImage() )
+ {
+ const wxPoint origin = parentComponent->GetPosition();
+ textpos = m_Pos - origin;
+ textpos = parentComponent->GetScreenCoord( textpos );
+ textpos += parentComponent->GetPosition();
+ GRLine( clipbox, aDC, origin, textpos, 2, DARKGRAY );
+ }
+
+ /* Enable this to draw the bounding box around the text field to validate
+ * the bounding box calculations.
+ */
+#if 0
+
+ // Draw boundary box:
+ GRRect( aPanel->GetClipBox(), aDC, boundaryBox, 0, BROWN );
+
+ // Draw the text anchor point
+
+ /* Calculate the text position, according to the component
+ * orientation/mirror */
+ textpos = m_Pos - parentComponent->GetPosition();
+ textpos = parentComponent->GetScreenCoord( textpos );
+ textpos += parentComponent->GetPosition();
+ const int len = 10;
+ GRLine( clipbox, aDC,
+ textpos.x - len, textpos.y, textpos.x + len, textpos.y, 0, BLUE );
+ GRLine( clipbox, aDC,
+ textpos.x, textpos.y - len, textpos.x, textpos.y + len, 0, BLUE );
+#endif
+}
+
+
+void SCH_FIELD::ImportValues( const LIB_FIELD& aSource )
+{
+ m_Orient = aSource.GetOrientation();
+ m_Size = aSource.GetSize();
+ m_HJustify = aSource.GetHorizJustify();
+ m_VJustify = aSource.GetVertJustify();
+ m_Italic = aSource.IsItalic();
+ m_Bold = aSource.IsBold();
+ m_Thickness = aSource.GetThickness();
+ m_Attributs = aSource.GetAttributes();
+ m_Mirror = aSource.IsMirrored();
+}
+
+
+void SCH_FIELD::SwapData( SCH_ITEM* aItem )
+{
+ wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_FIELD_T),
+ wxT( "Cannot swap field data with invalid item." ) );
+
+ SCH_FIELD* item = (SCH_FIELD*) aItem;
+
+ std::swap( m_Text, item->m_Text );
+ std::swap( m_Layer, item->m_Layer );
+ std::swap( m_Pos, item->m_Pos );
+ std::swap( m_Size, item->m_Size );
+ std::swap( m_Thickness, item->m_Thickness );
+ std::swap( m_Orient, item->m_Orient );
+ std::swap( m_Mirror, item->m_Mirror );
+ std::swap( m_Attributs, item->m_Attributs );
+ std::swap( m_Italic, item->m_Italic );
+ std::swap( m_Bold, item->m_Bold );
+ std::swap( m_HJustify, item->m_HJustify );
+ std::swap( m_VJustify, item->m_VJustify );
+}
+
+
+const EDA_RECT SCH_FIELD::GetBoundingBox() const
+{
+ SCH_COMPONENT* parentComponent = (SCH_COMPONENT*) m_Parent;
+ int linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness;
+
+ // We must pass the effective text thickness to GetTextBox
+ // when calculating the bounding box
+ linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
+
+ // Calculate the text bounding box:
+ EDA_RECT rect;
+
+ if( m_id == REFERENCE ) // multi units have one letter or more added to reference
+ {
+ SCH_FIELD text( *this ); // Make a local copy to change text
+ // because GetBoundingBox() is const
+ text.SetText( GetFullyQualifiedText() );
+ rect = text.GetTextBox( -1, linewidth );
+ }
+ else
+ rect = GetTextBox( -1, linewidth );
+
+ // Calculate the bounding box position relative to the component:
+ wxPoint origin = parentComponent->GetPosition();
+ wxPoint pos = m_Pos - origin;
+ wxPoint begin = rect.GetOrigin() - origin;
+ wxPoint end = rect.GetEnd() - origin;
+ RotatePoint( &begin, pos, m_Orient );
+ RotatePoint( &end, pos, m_Orient );
+
+ // Due to the Y axis direction, we must mirror the bounding box,
+ // relative to the text position:
+ MIRROR( begin.y, pos.y );
+ MIRROR( end.y, pos.y );
+
+ // Now, apply the component transform (mirror/rot)
+ begin = parentComponent->GetTransform().TransformCoordinate( begin );
+ end = parentComponent->GetTransform().TransformCoordinate( end );
+ rect.SetOrigin( begin);
+ rect.SetEnd( end);
+ rect.Move( origin );
+ rect.Normalize();
+ return rect;
+}
+
+
+bool SCH_FIELD::Save( FILE* aFile ) const
+{
+ char hjustify = 'C';
+
+ if( m_HJustify == GR_TEXT_HJUSTIFY_LEFT )
+ hjustify = 'L';
+ else if( m_HJustify == GR_TEXT_HJUSTIFY_RIGHT )
+ hjustify = 'R';
+
+ char vjustify = 'C';
+
+ if( m_VJustify == GR_TEXT_VJUSTIFY_BOTTOM )
+ vjustify = 'B';
+ else if( m_VJustify == GR_TEXT_VJUSTIFY_TOP )
+ vjustify = 'T';
+
+ if( fprintf( aFile, "F %d %s %c %-3d %-3d %-3d %4.4X %c %c%c%c",
+ m_id,
+ EscapedUTF8( m_Text ).c_str(), // wraps in quotes too
+ m_Orient == TEXT_ORIENT_HORIZ ? 'H' : 'V',
+ m_Pos.x, m_Pos.y,
+ m_Size.x,
+ m_Attributs,
+ hjustify, vjustify,
+ m_Italic ? 'I' : 'N',
+ m_Bold ? 'B' : 'N' ) == EOF )
+ {
+ return false;
+ }
+
+ // Save field name, if the name is user definable
+ if( m_id >= FIELD1 )
+ {
+ if( fprintf( aFile, " %s", EscapedUTF8( m_name ).c_str() ) == EOF )
+ {
+ return false;
+ }
+ }
+
+ if( fprintf( aFile, "\n" ) == EOF )
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+void SCH_FIELD::Place( SCH_EDIT_FRAME* frame, wxDC* DC )
+{
+ frame->GetCanvas()->SetMouseCapture( NULL, NULL );
+
+ SCH_COMPONENT* component = (SCH_COMPONENT*) GetParent();
+
+ // save old cmp in undo list
+ frame->SaveUndoItemInUndoList( component );
+
+ Draw( frame->GetCanvas(), DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+ ClearFlags();
+ frame->GetScreen()->SetCurItem( NULL );
+ frame->OnModify();
+}
+
+
+bool SCH_FIELD::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation )
+{
+ bool match;
+ wxString text = GetFullyQualifiedText();
+
+ // User defined fields have an ID of -1.
+ if( ((m_id > VALUE || m_id < REFERENCE) && !(aSearchData.GetFlags() & FR_SEARCH_ALL_FIELDS))
+ || ((m_id == REFERENCE) && !(aSearchData.GetFlags() & FR_REPLACE_REFERENCES)) )
+ return false;
+
+ wxLogTrace( traceFindItem, wxT( " child item " ) + GetSelectMenuText() );
+
+ // Take sheet path into account which effects the reference field and the unit for
+ // components with multiple parts.
+ if( m_id == REFERENCE && aAuxData != NULL )
+ {
+ SCH_COMPONENT* component = (SCH_COMPONENT*) m_Parent;
+
+ wxCHECK_MSG( component != NULL, false,
+ wxT( "No component associated with field" ) + text );
+
+ text = component->GetRef( (SCH_SHEET_PATH*) aAuxData );
+
+ if( component->GetUnitCount() > 1 )
+ text << LIB_PART::SubReference( component->GetUnit() );
+ }
+
+ match = SCH_ITEM::Matches( text, aSearchData );
+
+ if( match )
+ {
+ if( aFindLocation )
+ *aFindLocation = GetBoundingBox().Centre();
+
+ return true;
+ }
+
+ return false;
+}
+
+
+bool SCH_FIELD::Replace( wxFindReplaceData& aSearchData, void* aAuxData )
+{
+ bool isReplaced;
+ wxString text = GetFullyQualifiedText();
+
+ if( m_id == REFERENCE )
+ {
+ wxCHECK_MSG( aAuxData != NULL, false,
+ wxT( "Cannot replace reference designator without valid sheet path." ) );
+
+ wxCHECK_MSG( aSearchData.GetFlags() & FR_REPLACE_REFERENCES, false,
+ wxT( "Invalid replace component reference field call." ) ) ;
+
+ SCH_COMPONENT* component = (SCH_COMPONENT*) m_Parent;
+
+ wxCHECK_MSG( component != NULL, false,
+ wxT( "No component associated with field" ) + text );
+
+ text = component->GetRef( (SCH_SHEET_PATH*) aAuxData );
+
+ // if( component->GetUnitCount() > 1 )
+ // text << LIB_PART::SubReference( component->GetUnit() );
+
+ isReplaced = EDA_ITEM::Replace( aSearchData, text );
+
+ if( isReplaced )
+ component->SetRef( (SCH_SHEET_PATH*) aAuxData, text );
+ }
+ else
+ {
+ isReplaced = EDA_ITEM::Replace( aSearchData, m_Text );
+ }
+
+ return isReplaced;
+}
+
+
+void SCH_FIELD::Rotate( wxPoint aPosition )
+{
+ RotatePoint( &m_Pos, aPosition, 900 );
+}
+
+
+wxString SCH_FIELD::GetSelectMenuText() const
+{
+ wxString tmp;
+ tmp.Printf( _( "Field %s" ), GetChars( GetName() ) );
+
+ return tmp;
+}
+
+
+wxString SCH_FIELD::GetName( bool aUseDefaultName ) const
+{
+ if( !m_name.IsEmpty() )
+ return m_name;
+ else if( aUseDefaultName )
+ return TEMPLATE_FIELDNAME::GetDefaultFieldName( m_id );
+
+ return wxEmptyString;
+}
+
+
+BITMAP_DEF SCH_FIELD::GetMenuImage() const
+{
+ if( m_id == REFERENCE )
+ return edit_comp_ref_xpm;
+
+ if( m_id == VALUE )
+ return edit_comp_value_xpm;
+
+ if( m_id == FOOTPRINT )
+ return edit_comp_footprint_xpm;
+
+ return edit_text_xpm;
+}
+
+
+bool SCH_FIELD::HitTest( const wxPoint& aPosition, int aAccuracy ) const
+{
+ // Do not hit test hidden or empty fields.
+ if( !IsVisible() || IsVoid() )
+ return false;
+
+ EDA_RECT rect = GetBoundingBox();
+
+ rect.Inflate( aAccuracy );
+
+ return rect.Contains( aPosition );
+}
+
+
+bool SCH_FIELD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ // Do not hit test hidden fields.
+ if( !IsVisible() || IsVoid() )
+ return false;
+
+ EDA_RECT rect = aRect;
+
+ rect.Inflate( aAccuracy );
+
+ if( aContained )
+ return rect.Contains( GetBoundingBox() );
+
+ return rect.Intersects( GetBoundingBox() );
+}
+
+
+void SCH_FIELD::Plot( PLOTTER* aPlotter )
+{
+ SCH_COMPONENT* parent = ( SCH_COMPONENT* ) GetParent();
+
+ wxCHECK_RET( parent != NULL && parent->Type() == SCH_COMPONENT_T,
+ wxT( "Cannot plot field with invalid parent." ) );
+
+ EDA_COLOR_T color = GetLayerColor( GetLayer() );
+
+ if( m_Attributs & TEXT_NO_VISIBLE )
+ return;
+
+ if( IsVoid() )
+ return;
+
+ /* Calculate the text orientation, according to the component
+ * orientation/mirror */
+ int orient = m_Orient;
+
+ if( parent->GetTransform().y1 ) // Rotate component 90 deg.
+ {
+ if( orient == TEXT_ORIENT_HORIZ )
+ orient = TEXT_ORIENT_VERT;
+ else
+ orient = TEXT_ORIENT_HORIZ;
+ }
+
+ /* Calculate the text justification, according to the component
+ * orientation/mirror
+ * this is a bit complicated due to cumulative calculations:
+ * - numerous cases (mirrored or not, rotation)
+ * - the DrawGraphicText function recalculate also H and H justifications
+ * according to the text orientation.
+ * - When a component is mirrored, the text is not mirrored and
+ * justifications are complicated to calculate
+ * so the more easily way is to use no justifications ( Centered text )
+ * and use GetBoundaryBox to know the text coordinate considered as centered
+ */
+ EDA_RECT BoundaryBox = GetBoundingBox();
+ EDA_TEXT_HJUSTIFY_T hjustify = GR_TEXT_HJUSTIFY_CENTER;
+ EDA_TEXT_VJUSTIFY_T vjustify = GR_TEXT_VJUSTIFY_CENTER;
+ wxPoint textpos = BoundaryBox.Centre();
+
+ int thickness = GetPenSize();
+
+ aPlotter->Text( textpos, color, GetFullyQualifiedText(), orient, m_Size, hjustify, vjustify,
+ thickness, m_Italic, m_Bold );
+}
+
+
+void SCH_FIELD::SetPosition( const wxPoint& aPosition )
+{
+ SCH_COMPONENT* component = (SCH_COMPONENT*) GetParent();
+
+ wxPoint pos = ( (SCH_COMPONENT*) GetParent() )->GetPosition();
+
+ // Actual positions are calculated by the rotation/mirror transform of the
+ // parent component of the field. The inverse transfrom is used to calculate
+ // the position relative to the parent component.
+ wxPoint pt = aPosition - pos;
+
+ m_Pos = pos + component->GetTransform().InverseTransform().TransformCoordinate( pt );
+}
+
+
+wxPoint SCH_FIELD::GetPosition() const
+{
+
+ SCH_COMPONENT* component = (SCH_COMPONENT*) GetParent();
+
+ wxPoint pos = m_Pos - component->GetPosition();
+
+ return component->GetTransform().TransformCoordinate( pos ) + component->GetPosition();
+}
diff --git a/eeschema/sch_field.h b/eeschema/sch_field.h
new file mode 100644
index 0000000..8b458bc
--- /dev/null
+++ b/eeschema/sch_field.h
@@ -0,0 +1,202 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_field.h
+ * @brief Definition of the SCH_FIELD class for Eeschema.
+ */
+
+#ifndef CLASS_SCH_FIELD_H
+#define CLASS_SCH_FIELD_H
+
+
+#include <eda_text.h>
+#include <sch_item_struct.h>
+#include <general.h>
+
+
+class SCH_EDIT_FRAME;
+class SCH_COMPONENT;
+class LIB_FIELD;
+
+
+/**
+ * Class SCH_FIELD
+ * instances are attached to a component and provide a place for the component's value,
+ * reference designator, footprint, and user definable name-value pairs of arbitrary purpose.
+ *
+ * <ul> <li>Field 0 is reserved for the component reference.</li>
+ * <li>Field 1 is reserved for the component value.</li>
+ * <li>Field 2 is reserved for the component footprint.</li>
+ * <li>Field 3 is reserved for the component data sheet file.</li>
+ * <li>Field 4 and higher are user defineable.</li></ul>
+ */
+
+class SCH_FIELD : public SCH_ITEM, public EDA_TEXT
+{
+ int m_id; ///< Field index, @see enum NumFieldType
+
+ wxString m_name;
+
+public:
+ SCH_FIELD( const wxPoint& aPos, int aFieldId, SCH_COMPONENT* aParent,
+ wxString aName = wxEmptyString );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~SCH_FIELD();
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_FIELD" );
+ }
+
+ /**
+ * Function GetName
+ * returns the field name.
+ *
+ * @param aUseDefaultName When true return the default field name if the field name is
+ * empty. Otherwise the default field name is returned.
+ * @return A wxString object containing the name of the field.
+ */
+ wxString GetName( bool aUseDefaultName = true ) const;
+
+ void SetName( const wxString& aName ) { m_name = aName; }
+
+ int GetId() const { return m_id; }
+
+ void SetId( int aId ) { m_id = aId; }
+
+ /**
+ * Function GetFullyQualifiedText
+ * returns the fully qualified field text by allowing for the part suffix to be added
+ * to the reference designator field if the component has multiple parts. For all other
+ * fields this is the equivalent of EDA_TEXT::GetText().
+ *
+ * @return a const wxString object containing the field's string.
+ */
+ const wxString GetFullyQualifiedText() const;
+
+ void Place( SCH_EDIT_FRAME* frame, wxDC* DC );
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ /**
+ * Function IsVoid
+ * returns true if the field is either empty or holds "~".
+ */
+ bool IsVoid() const
+ {
+ size_t len = m_Text.Len();
+
+ return len == 0 || ( len == 1 && m_Text[0] == wxChar( '~' ) );
+ }
+
+ void SwapData( SCH_ITEM* aItem );
+
+ /**
+ * Function ImportValues
+ * copy parameters from a source.
+ * Pointers and specific values (position) are not copied
+ * @param aSource = the LIB_FIELD to read
+ */
+ void ImportValues( const LIB_FIELD& aSource );
+
+ int GetPenSize() const;
+
+ /**
+ * Function IsVisible
+ * @return true is this field is visible, false if flagged invisible
+ */
+ bool IsVisible() const
+ {
+ return (m_Attributs & TEXT_NO_VISIBLE) == 0 ? true : false;
+ }
+
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR );
+
+ bool Save( FILE* aFile ) const;
+
+ // Geometric transforms (used in block operations):
+
+ void Move( const wxPoint& aMoveVector )
+ {
+ m_Pos += aMoveVector;
+ }
+
+
+ void Rotate( wxPoint aPosition );
+
+ /**
+ * @copydoc SCH_ITEM::MirrorX()
+ *
+ * This overload does nothing. Fields are never mirrored alone. They are moved
+ * when the parent component is mirrored. This function is only needed by the
+ * pure function of the master class.
+ */
+ void MirrorX( int aXaxis_position )
+ {
+ }
+
+ /**
+ * @copydoc SCH_ITEM::MirrorY()
+ *
+ * This overload does nothing. Fields are never mirrored alone. They are moved
+ * when the parent component is mirrored. This function is only needed by the
+ * pure function of the master class.
+ */
+ void MirrorY( int aYaxis_position )
+ {
+ }
+
+ bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
+
+ bool Replace( wxFindReplaceData& aSearchData, void* aAuxData = NULL );
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const;
+
+ bool IsReplaceable() const { return true; }
+
+ wxPoint GetPosition() const;
+
+ void SetPosition( const wxPoint& aPosition );
+
+ bool HitTest( const wxPoint& aPosition, int aAccuracy ) const;
+
+ bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const;
+
+ void Plot( PLOTTER* aPlotter );
+
+ EDA_ITEM* Clone() const;
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+};
+
+
+#endif /* CLASS_SCH_FIELD_H */
diff --git a/eeschema/sch_item_struct.cpp b/eeschema/sch_item_struct.cpp
new file mode 100644
index 0000000..047d5c8
--- /dev/null
+++ b/eeschema/sch_item_struct.cpp
@@ -0,0 +1,151 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2006 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_item_struct.cpp
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <gr_basic.h>
+#include <base_struct.h>
+#include <sch_item_struct.h>
+#include <class_sch_screen.h>
+#include <class_drawpanel.h>
+#include <schframe.h>
+
+#include <general.h>
+
+
+const wxString traceFindItem( wxT( "KicadFindItem" ) );
+
+
+bool sort_schematic_items( const SCH_ITEM* aItem1, const SCH_ITEM* aItem2 )
+{
+ return *aItem1 < *aItem2;
+}
+
+
+/* Constructor and destructor for SCH_ITEM */
+/* They are not inline because this creates problems with gcc at linking time
+ * in debug mode
+ */
+
+SCH_ITEM::SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType ) :
+ EDA_ITEM( aParent, aType )
+{
+ m_Layer = LAYER_WIRE; // It's only a default, in fact
+}
+
+
+SCH_ITEM::SCH_ITEM( const SCH_ITEM& aItem ) :
+ EDA_ITEM( aItem )
+{
+ m_Layer = aItem.m_Layer;
+}
+
+
+SCH_ITEM::~SCH_ITEM()
+{
+ // Do not let the connections container go out of scope with any objects or they
+ // will be deleted by the container will cause the Eeschema to crash. These objects
+ // are owned by the sheet object container.
+ if( !m_connections.empty() )
+ m_connections.clear();
+}
+
+
+bool SCH_ITEM::IsConnected( const wxPoint& aPosition ) const
+{
+ if( m_Flags & STRUCT_DELETED || m_Flags & SKIP_STRUCT )
+ return false;
+
+ return doIsConnected( aPosition );
+}
+
+
+void SCH_ITEM::SwapData( SCH_ITEM* aItem )
+{
+ wxFAIL_MSG( wxT( "SwapData() method not implemented for class " ) + GetClass() );
+}
+
+
+bool SCH_ITEM::operator < ( const SCH_ITEM& aItem ) const
+{
+ wxCHECK_MSG( false, this->Type() < aItem.Type(),
+ wxT( "Less than operator not defined for " ) + GetClass() );
+}
+
+
+void SCH_ITEM::Plot( PLOTTER* aPlotter )
+{
+ wxFAIL_MSG( wxT( "Plot() method not implemented for class " ) + GetClass() );
+}
+
+
+std::string SCH_ITEM::FormatInternalUnits( int aValue )
+{
+ char buf[50];
+ double engUnits = aValue;
+ int len;
+
+ if( engUnits != 0.0 && fabs( engUnits ) <= 0.0001 )
+ {
+ len = snprintf( buf, sizeof(buf), "%.10f", engUnits );
+
+ while( --len > 0 && buf[len] == '0' )
+ buf[len] = '\0';
+
+ ++len;
+ }
+ else
+ {
+ len = snprintf( buf, sizeof(buf), "%.10g", engUnits );
+ }
+
+ return std::string( buf, len );
+}
+
+
+std::string SCH_ITEM::FormatAngle( double aAngle )
+{
+ char temp[50];
+ int len;
+
+ len = snprintf( temp, sizeof(temp), "%.10g", aAngle / 10.0 );
+
+ return std::string( temp, len );
+}
+
+
+std::string SCH_ITEM::FormatInternalUnits( const wxPoint& aPoint )
+{
+ return FormatInternalUnits( aPoint.x ) + " " + FormatInternalUnits( aPoint.y );
+}
+
+
+std::string SCH_ITEM::FormatInternalUnits( const wxSize& aSize )
+{
+ return FormatInternalUnits( aSize.GetWidth() ) + " " + FormatInternalUnits( aSize.GetHeight() );
+}
diff --git a/eeschema/sch_item_struct.h b/eeschema/sch_item_struct.h
new file mode 100644
index 0000000..c53f40a
--- /dev/null
+++ b/eeschema/sch_item_struct.h
@@ -0,0 +1,432 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_item_struct.h
+ * @brief Base schematic object class definition.
+ */
+
+#ifndef SCH_ITEM_STRUCT_H
+#define SCH_ITEM_STRUCT_H
+
+#include <vector>
+#include <class_base_screen.h>
+#include <general.h>
+
+#include <boost/ptr_container/ptr_vector.hpp>
+
+class SCH_ITEM;
+class SCH_SHEET_PATH;
+class LINE_READER;
+class SCH_EDIT_FRAME;
+class wxFindReplaceData;
+class PLOTTER;
+class NETLIST_OBJECT;
+class NETLIST_OBJECT_LIST;
+
+
+typedef boost::ptr_vector< SCH_ITEM > SCH_ITEMS;
+typedef SCH_ITEMS::iterator SCH_ITEMS_ITR;
+typedef std::vector< SCH_ITEMS_ITR > SCH_ITEMS_ITRS;
+
+
+#define FMT_IU SCH_ITEM::FormatInternalUnits
+#define FMT_ANGLE SCH_ITEM::FormatAngle
+
+
+/// Flag to enable find item tracing using the WXTRACE environment variable. This
+/// flag generates a lot of debug output.
+extern const wxString traceFindItem;
+
+
+enum DANGLING_END_T {
+ UNKNOWN = 0,
+ WIRE_START_END,
+ WIRE_END_END,
+ BUS_START_END,
+ BUS_END_END,
+ JUNCTION_END,
+ PIN_END,
+ LABEL_END,
+ ENTRY_END,
+ SHEET_LABEL_END,
+ NO_CONNECT_END,
+};
+
+
+/**
+ * Class DANGLING_END_ITEM
+ * is a helper class used to store the state of schematic items that can be connected to
+ * other schematic items.
+ */
+class DANGLING_END_ITEM
+{
+private:
+ /// A pointer to the connectable object.
+ const EDA_ITEM* m_item;
+
+ /// The position of the connection point.
+ wxPoint m_pos;
+
+ /// The type of connection of #m_item.
+ DANGLING_END_T m_type;
+
+public:
+ DANGLING_END_ITEM( DANGLING_END_T aType, const EDA_ITEM* aItem, const wxPoint& aPosition )
+ {
+ m_item = aItem;
+ m_type = aType;
+ m_pos = aPosition;
+ }
+
+ wxPoint GetPosition() const { return m_pos; }
+ const EDA_ITEM* GetItem() const { return m_item; }
+ DANGLING_END_T GetType() const { return m_type; }
+};
+
+
+/**
+ * Class SCH_ITEM
+ * is a base class for any item which can be embedded within the SCHEMATIC
+ * container class, and therefore instances of derived classes should only be
+ * found in EESCHEMA or other programs that use class SCHEMATIC and its contents.
+ * The corresponding class in Pcbnew is BOARD_ITEM.
+ */
+class SCH_ITEM : public EDA_ITEM
+{
+protected:
+ LAYERSCH_ID m_Layer;
+ EDA_ITEMS m_connections; ///< List of items connected to this item.
+ wxPoint m_storedPos; ///< a temporary variable used in some move commands
+ ///> to store a initial pos (of the item or mouse cursor)
+
+public:
+ SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType );
+
+ SCH_ITEM( const SCH_ITEM& aItem );
+
+ ~SCH_ITEM();
+
+ virtual wxString GetClass() const
+ {
+ return wxT( "SCH_ITEM" );
+ }
+
+ /**
+ * Function SwapData
+ * swap the internal data structures \a aItem with the schematic item.
+ * Obviously, aItem must have the same type than me
+ * @param aItem The item to swap the data structures with.
+ */
+ virtual void SwapData( SCH_ITEM* aItem );
+
+ SCH_ITEM* Next() const { return static_cast<SCH_ITEM*>( Pnext ); }
+ SCH_ITEM* Back() const { return static_cast<SCH_ITEM*>( Pback ); }
+
+ /**
+ * Virtual function IsMovableFromAnchorPoint
+ * @return true for items which are moved with the anchor point at mouse cursor
+ * and false for items moved with no reference to anchor
+ * Usually return true for small items (labels, junctions) and false for
+ * items which can be large (hierarchical sheets, compoments)
+ */
+ virtual bool IsMovableFromAnchorPoint() { return true; }
+
+ wxPoint& GetStoredPos() { return m_storedPos; }
+ void SetStoredPos( wxPoint aPos ) { m_storedPos = aPos; }
+
+
+ /**
+ * Function GetLayer
+ * returns the layer this item is on.
+ */
+ LAYERSCH_ID GetLayer() const { return m_Layer; }
+
+ /**
+ * Function SetLayer
+ * sets the layer this item is on.
+ * @param aLayer The layer number.
+ */
+ void SetLayer( LAYERSCH_ID aLayer ) { m_Layer = aLayer; }
+
+ /**
+ * Function GetPenSize virtual pure
+ * @return the size of the "pen" that be used to draw or plot this item
+ */
+ virtual int GetPenSize() const { return 0; }
+
+ /**
+ * Function Draw
+ * Draw a schematic item. Each schematic item should have its own method
+ * @param aPanel DrawPanel to use (can be null) mainly used for clipping purposes.
+ * @param aDC Device Context (can be null)
+ * @param aOffset drawing Offset (usually wxPoint(0,0),
+ * but can be different when moving an object)
+ * @param aDrawMode GR_OR, GR_XOR, ...
+ * @param aColor UNSPECIFIED_COLOR to use the normal body item color,
+ * or force this color if it is a valid color
+ */
+ virtual void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR ) = 0;
+
+ /**
+ * Function Move
+ * moves the item by \a aMoveVector to a new position.
+ * @param aMoveVector = the displacement vector
+ */
+ virtual void Move( const wxPoint& aMoveVector ) = 0;
+
+ /**
+ * Function MirrorY
+ * mirrors item relative to the Y axis about \a aYaxis_position.
+ * @param aYaxis_position The Y axis position to mirror around.
+ */
+ virtual void MirrorY( int aYaxis_position ) = 0;
+
+ /**
+ * Function MirrorX
+ * mirrors item relative to the X axis about \a aXaxis_position.
+ * @param aXaxis_position The X axis position to mirror around.
+ */
+ virtual void MirrorX( int aXaxis_position ) = 0;
+
+ /**
+ * Function Rotate
+ * rotates the item around \a aPosition 90 degrees in the clockwise direction.
+ * @param aPosition A reference to a wxPoint object containing the coordinates to
+ * rotate around.
+ */
+ virtual void Rotate( wxPoint aPosition ) = 0;
+
+ /**
+ * Function Save
+ * writes the data structures for this object out to a FILE in "*.sch" format.
+ * @param aFile The FILE to write to.
+ * @return bool - true if success writing else false.
+ */
+ virtual bool Save( FILE* aFile ) const = 0;
+
+ /**
+ * Function Load
+ * reads a schematic item from \a aLine in a .sch file.
+ *
+ * @param aLine - Essentially this is file to read the object from.
+ * @param aErrorMsg - Description of the error if an error occurs while loading the object.
+ * @return True if the object loaded successfully.
+ */
+ virtual bool Load( LINE_READER& aLine, wxString& aErrorMsg ) { return false; }
+
+ /**
+ * Function GetEndPoints
+ * adds the schematic item end points to \a aItemList if the item has end points.
+ *
+ * The default version doesn't do anything since many of the schematic object cannot
+ * be tested for dangling ends. If you add a new schematic item that can have a
+ * dangling end ( no connect ), override this method to provide the correct end
+ * points.
+ *
+ * @param aItemList - List of DANGLING_END_ITEMS to add to.
+ */
+ virtual void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList ) {}
+
+ /**
+ * Function IsDanglingStateChanged
+ * tests the schematic item to \a aItemList to check if it's dangling state has changed.
+ *
+ * Note that the return value only true when the state of the test has changed. Use
+ * the IsDangling() method to get the current dangling state of the item. Some of
+ * the schematic objects cannot be tested for a dangling state, the default method
+ * always returns false. Only override the method if the item can be tested for a
+ * dangling state.
+ *
+ * @param aItemList - List of items to test item against.
+ * @return True if the dangling state has changed from it's current setting.
+ */
+ virtual bool IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList ) { return false; }
+
+ virtual bool IsDangling() const { return false; }
+
+ /**
+ * Function IsSelectStateChanged
+ * checks if the selection state of an item inside \a aRect has changed.
+ *
+ * This is used by the block selection code to verify if an item is selected or not.
+ * True is be return anytime the select state changes. If you need to know the
+ * the current selection state, use the IsSelected() method.
+ *
+ * @param aRect - Rectangle to test against.
+ */
+ virtual bool IsSelectStateChanged( const wxRect& aRect ) { return false; }
+
+ /**
+ * Function IsConnectable
+ * returns true if the schematic item can connect to another schematic item.
+ */
+ virtual bool IsConnectable() const { return false; }
+
+ /**
+ * Function GetConnectionPoints
+ * add all the connection points for this item to \a aPoints.
+ *
+ * Not all schematic items have connection points so the default method does nothing.
+ *
+ * @param aPoints List of connection points to add to.
+ */
+ virtual void GetConnectionPoints( std::vector< wxPoint >& aPoints ) const { }
+
+ /**
+ * Function ClearConnections
+ * clears all of the connection items from the list.
+ *
+ * The vector release method is used to prevent the item pointers from being deleted.
+ * Do not use the vector erase method on the connection list.
+ */
+ void ClearConnections() { m_connections.clear(); }
+
+ /**
+ * Function IsConnected
+ * tests the item to see if it is connected to \a aPoint.
+ *
+ * @param aPoint A reference to a wxPoint object containing the coordinates to test.
+ * @return True if connection to \a aPoint exists.
+ */
+ bool IsConnected( const wxPoint& aPoint ) const;
+
+ /** @copydoc EDA_ITEM::HitTest(const wxPoint&) */
+ virtual bool HitTest( const wxPoint& aPosition ) const
+ {
+ return HitTest( aPosition, 0 );
+ }
+
+ /**
+ * Function HitTest
+ * tests if \a aPosition is contained within or on the bounding box of an item.
+ *
+ * @param aPosition A reference to a wxPoint object containing the coordinates to test.
+ * @param aAccuracy Increase the item bounding box by this amount.
+ * @return True if \a aPosition is within the item bounding box.
+ */
+ virtual bool HitTest( const wxPoint& aPosition, int aAccuracy ) const { return false; }
+
+ /**
+ * Function HitTest
+ * tests if \a aRect intersects or is contained within the bounding box of an item.
+ *
+ * @param aRect A reference to a EDA_RECT object containing the rectangle to test.
+ * @param aContained Set to true to test for containment instead of an intersection.
+ * @param aAccuracy Increase \a aRect by this amount.
+ * @return True if \a aRect contains or intersects the item bounding box.
+ */
+ virtual bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const
+ {
+ return false;
+ }
+
+ virtual bool CanIncrementLabel() const { return false; }
+
+ /**
+ * Function Plot
+ * plots the schematic item to \a aPlotter.
+ *
+ * @param aPlotter A pointer to a #PLOTTER object.
+ */
+ virtual void Plot( PLOTTER* aPlotter );
+
+ /**
+ * Function GetNetListItem
+ * creates a new #NETLIST_OBJECT for the schematic object and adds it to
+ * \a aNetListItems.
+ * <p>
+ * Not all schematic objects have net list items associated with them. This
+ * method only needs to be overridden for those schematic objects that have
+ * net list objects associated with them.
+ * </p>
+ */
+ virtual void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
+ SCH_SHEET_PATH* aSheetPath ) { }
+
+ /**
+ * Function GetPosition
+ * @return A wxPoint object containing the schematic item position.
+ */
+ virtual wxPoint GetPosition() const = 0;
+
+ /**
+ * Function SetPosition
+ * set the schematic item position to \a aPosition.
+ *
+ * @param aPosition A reference to a wxPoint object containing the new position.
+ */
+ virtual void SetPosition( const wxPoint& aPosition ) = 0;
+
+ virtual bool operator <( const SCH_ITEM& aItem ) const;
+
+ /**
+ * Function FormatInternalUnits
+ * converts \a aValue from schematic internal units to a string appropriate for writing
+ * to file.
+ *
+ * @param aValue A coordinate value to convert.
+ * @return A std::string object containing the converted value.
+ */
+ static std::string FormatInternalUnits( int aValue );
+
+ /**
+ * Function FormatAngle
+ * converts \a aAngle from board units to a string appropriate for writing to file.
+ *
+ * @note Internal angles for board items can be either degrees or tenths of degree
+ * on how KiCad is built.
+ * @param aAngle A angle value to convert.
+ * @return A std::string object containing the converted angle.
+ */
+ static std::string FormatAngle( double aAngle );
+
+ static std::string FormatInternalUnits( const wxPoint& aPoint );
+
+ static std::string FormatInternalUnits( const wxSize& aSize );
+
+private:
+ /**
+ * Function doIsConnected
+ * provides the object specific test to see if it is connected to \a aPosition.
+ *
+ * @note Override this function if the derived object can be connect to another
+ * object such as a wire, bus, or junction. Do not override this function
+ * for objects that cannot have connections. The default will always return
+ * false. This functions is call through the public function IsConnected()
+ * which performs tests common to all schematic items before calling the
+ * item specific connection testing.
+ *
+ * @param aPosition A reference to a wxPoint object containing the test position.
+ * @return True if connection to \a aPosition exists.
+ */
+ virtual bool doIsConnected( const wxPoint& aPosition ) const { return false; }
+};
+
+
+extern bool sort_schematic_items( const SCH_ITEM* aItem1, const SCH_ITEM* aItem2 );
+
+
+#endif /* SCH_ITEM_STRUCT_H */
diff --git a/eeschema/sch_junction.cpp b/eeschema/sch_junction.cpp
new file mode 100644
index 0000000..9c08b63
--- /dev/null
+++ b/eeschema/sch_junction.cpp
@@ -0,0 +1,235 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_junction.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <trigo.h>
+#include <common.h>
+#include <richio.h>
+#include <plot_common.h>
+
+#include <sch_junction.h>
+#include <class_netlist_object.h>
+
+
+int SCH_JUNCTION::m_symbolSize = 40; // Default diameter of the junction symbol
+
+SCH_JUNCTION::SCH_JUNCTION( const wxPoint& pos ) :
+ SCH_ITEM( NULL, SCH_JUNCTION_T )
+{
+ m_pos = pos;
+ m_Layer = LAYER_JUNCTION;
+}
+
+
+bool SCH_JUNCTION::Save( FILE* aFile ) const
+{
+ bool success = true;
+
+ if( fprintf( aFile, "Connection ~ %-4d %-4d\n", m_pos.x, m_pos.y ) == EOF )
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+
+EDA_ITEM* SCH_JUNCTION::Clone() const
+{
+ return new SCH_JUNCTION( *this );
+}
+
+
+void SCH_JUNCTION::SwapData( SCH_ITEM* aItem )
+{
+ wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_JUNCTION_T),
+ wxT( "Cannot swap junction data with invalid item." ) );
+
+ SCH_JUNCTION* item = (SCH_JUNCTION*) aItem;
+ std::swap( m_pos, item->m_pos );
+}
+
+
+bool SCH_JUNCTION::Load( LINE_READER& aLine, wxString& aErrorMsg )
+{
+ char name[256];
+ char* line = (char*) aLine;
+
+ while( (*line != ' ' ) && *line )
+ line++;
+
+ if( sscanf( line, "%255s %d %d", name, &m_pos.x, &m_pos.y ) != 3 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file connection load error at line %d, aborted" ),
+ aLine.LineNumber() );
+ aErrorMsg << wxT( "\n" ) << FROM_UTF8( (char*) aLine );
+ return false;
+ }
+
+ return true;
+}
+
+
+const EDA_RECT SCH_JUNCTION::GetBoundingBox() const
+{
+ EDA_RECT rect;
+
+ rect.SetOrigin( m_pos );
+ rect.Inflate( ( GetPenSize() + GetSymbolSize() ) / 2 );
+
+ return rect;
+}
+
+
+void SCH_JUNCTION::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor )
+{
+ EDA_COLOR_T color;
+
+ if( aColor >= 0 )
+ color = aColor;
+ else
+ color = GetLayerColor( m_Layer );
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ GRFilledCircle( aPanel->GetClipBox(), aDC, m_pos.x + aOffset.x, m_pos.y + aOffset.y,
+ ( GetSymbolSize() / 2 ), 0, color, color );
+}
+
+
+void SCH_JUNCTION::MirrorX( int aXaxis_position )
+{
+ MIRROR( m_pos.y, aXaxis_position );
+}
+
+
+void SCH_JUNCTION::MirrorY( int aYaxis_position )
+{
+ MIRROR( m_pos.x, aYaxis_position );
+}
+
+
+void SCH_JUNCTION::Rotate( wxPoint aPosition )
+{
+ RotatePoint( &m_pos, aPosition, 900 );
+}
+
+
+void SCH_JUNCTION::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
+{
+ DANGLING_END_ITEM item( JUNCTION_END, this, m_pos );
+ aItemList.push_back( item );
+}
+
+
+bool SCH_JUNCTION::IsSelectStateChanged( const wxRect& aRect )
+{
+ bool previousState = IsSelected();
+
+ if( aRect.Contains( m_pos ) )
+ SetFlags( SELECTED );
+ else
+ ClearFlags( SELECTED );
+
+ return previousState != IsSelected();
+}
+
+
+void SCH_JUNCTION::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
+{
+ aPoints.push_back( m_pos );
+}
+
+
+void SCH_JUNCTION::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
+ SCH_SHEET_PATH* aSheetPath )
+{
+ NETLIST_OBJECT* item = new NETLIST_OBJECT();
+
+ item->m_SheetPath = *aSheetPath;
+ item->m_SheetPathInclude = *aSheetPath;
+ item->m_Comp = (SCH_ITEM*) this;
+ item->m_Type = NET_JUNCTION;
+ item->m_Start = item->m_End = m_pos;
+
+ aNetListItems.push_back( item );
+}
+
+
+#if defined(DEBUG)
+void SCH_JUNCTION::Show( int nestLevel, std::ostream& os ) const
+{
+ // XML output:
+ wxString s = GetClass();
+
+ NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_pos << "/>\n";
+}
+#endif
+
+
+bool SCH_JUNCTION::HitTest( const wxPoint& aPosition, int aAccuracy ) const
+{
+ EDA_RECT rect = GetBoundingBox();
+
+ rect.Inflate( aAccuracy );
+
+ return rect.Contains( aPosition );
+}
+
+
+bool SCH_JUNCTION::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ if( m_Flags & STRUCT_DELETED || m_Flags & SKIP_STRUCT )
+ return false;
+
+ EDA_RECT rect = aRect;
+
+ rect.Inflate( aAccuracy );
+
+ if( aContained )
+ return rect.Contains( GetBoundingBox() );
+
+ return rect.Intersects( GetBoundingBox() );
+}
+
+
+bool SCH_JUNCTION::doIsConnected( const wxPoint& aPosition ) const
+{
+ return m_pos == aPosition;
+}
+
+
+void SCH_JUNCTION::Plot( PLOTTER* aPlotter )
+{
+ aPlotter->SetColor( GetLayerColor( GetLayer() ) );
+ aPlotter->Circle( m_pos, GetSymbolSize(), FILLED_SHAPE );
+}
diff --git a/eeschema/sch_junction.h b/eeschema/sch_junction.h
new file mode 100644
index 0000000..0e93d84
--- /dev/null
+++ b/eeschema/sch_junction.h
@@ -0,0 +1,113 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_junction.h
+ */
+
+#ifndef _SCH_JUNCTION_H_
+#define _SCH_JUNCTION_H_
+
+
+#include <sch_item_struct.h>
+class NETLIST_OBJECT_LIST;
+
+class SCH_JUNCTION : public SCH_ITEM
+{
+ wxPoint m_pos; // Position of the junction.
+ static int m_symbolSize; // diameter of the junction graphic symbol
+
+public:
+ SCH_JUNCTION( const wxPoint& pos = wxPoint( 0, 0 ) );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~SCH_JUNCTION() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_JUNCTION" );
+ }
+
+ static int GetSymbolSize() { return m_symbolSize; }
+ static void SetSymbolSize( int aSize ) { m_symbolSize = aSize; }
+
+ void SwapData( SCH_ITEM* aItem );
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR );
+
+ bool Save( FILE* aFile ) const;
+
+ bool Load( LINE_READER& aLine, wxString& aErrorMsg );
+
+ void Move( const wxPoint& aMoveVector )
+ {
+ m_pos += aMoveVector;
+ }
+
+ void MirrorY( int aYaxis_position );
+
+ void MirrorX( int aXaxis_position );
+
+ void Rotate( wxPoint aPosition );
+
+ void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList );
+
+ bool IsSelectStateChanged( const wxRect& aRect );
+
+ bool IsConnectable() const { return true; }
+
+ void GetConnectionPoints( std::vector< wxPoint >& aPoints ) const;
+
+ wxString GetSelectMenuText() const { return wxString( _( "Junction" ) ); }
+
+ BITMAP_DEF GetMenuImage() const { return add_junction_xpm; }
+
+ void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, SCH_SHEET_PATH* aSheetPath );
+
+ wxPoint GetPosition() const { return m_pos; }
+
+ void SetPosition( const wxPoint& aPosition ) { m_pos = aPosition; }
+
+ bool HitTest( const wxPoint& aPosition, int aAccuracy ) const;
+
+ bool HitTest( const EDA_RECT& aRect, bool aContained = false,
+ int aAccuracy = 0 ) const;
+ void Plot( PLOTTER* aPlotter );
+
+ EDA_ITEM* Clone() const;
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // override
+#endif
+
+private:
+ bool doIsConnected( const wxPoint& aPosition ) const;
+};
+
+
+#endif // _SCH_JUNCTION_H_
diff --git a/eeschema/sch_line.cpp b/eeschema/sch_line.cpp
new file mode 100644
index 0000000..72efb5c
--- /dev/null
+++ b/eeschema/sch_line.cpp
@@ -0,0 +1,611 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_line.cpp
+ * @brief Class SCH_LINE implementation
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <plot_common.h>
+#include <base_units.h>
+#include <eeschema_config.h>
+#include <general.h>
+#include <protos.h>
+#include <sch_line.h>
+#include <class_netlist_object.h>
+
+#include <boost/foreach.hpp>
+
+
+SCH_LINE::SCH_LINE( const wxPoint& pos, int layer ) :
+ SCH_ITEM( NULL, SCH_LINE_T )
+{
+ m_start = pos;
+ m_end = pos;
+ m_startIsDangling = m_endIsDangling = false;
+
+ switch( layer )
+ {
+ default:
+ m_Layer = LAYER_NOTES;
+ break;
+
+ case LAYER_WIRE:
+ m_Layer = LAYER_WIRE;
+ break;
+
+ case LAYER_BUS:
+ m_Layer = LAYER_BUS;
+ break;
+ }
+}
+
+
+SCH_LINE::SCH_LINE( const SCH_LINE& aLine ) :
+ SCH_ITEM( aLine )
+{
+ m_start = aLine.m_start;
+ m_end = aLine.m_end;
+ m_startIsDangling = m_endIsDangling = false;
+}
+
+
+EDA_ITEM* SCH_LINE::Clone() const
+{
+ return new SCH_LINE( *this );
+}
+
+
+void SCH_LINE::Move( const wxPoint& aOffset )
+{
+ if( (m_Flags & STARTPOINT) == 0 && aOffset != wxPoint( 0, 0 ) )
+ {
+ m_start += aOffset;
+ SetModified();
+ }
+
+ if( (m_Flags & ENDPOINT) == 0 && aOffset != wxPoint( 0, 0 ) )
+ {
+ m_end += aOffset;
+ SetModified();
+ }
+}
+
+
+#if defined(DEBUG)
+
+void SCH_LINE::Show( int nestLevel, std::ostream& os ) const
+{
+ NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
+ << " layer=\"" << m_Layer << '"'
+ << " startIsDangling=\"" << m_startIsDangling
+ << '"' << " endIsDangling=\""
+ << m_endIsDangling << '"' << ">"
+ << " <start" << m_start << "/>"
+ << " <end" << m_end << "/>" << "</"
+ << GetClass().Lower().mb_str() << ">\n";
+}
+
+#endif
+
+
+const EDA_RECT SCH_LINE::GetBoundingBox() const
+{
+ int width = 25;
+
+ int xmin = std::min( m_start.x, m_end.x ) - width;
+ int ymin = std::min( m_start.y, m_end.y ) - width;
+
+ int xmax = std::max( m_start.x, m_end.x ) + width;
+ int ymax = std::max( m_start.y, m_end.y ) + width;
+
+ // return a rectangle which is [pos,dim) in nature. therefore the +1
+ EDA_RECT ret( wxPoint( xmin, ymin ), wxSize( xmax - xmin + 1, ymax - ymin + 1 ) );
+
+ return ret;
+}
+
+
+double SCH_LINE::GetLength() const
+{
+ return GetLineLength( m_start, m_end );
+}
+
+
+bool SCH_LINE::Save( FILE* aFile ) const
+{
+ bool success = true;
+
+ const char* layer = "Notes";
+ const char* width = "Line";
+
+ if( GetLayer() == LAYER_WIRE )
+ layer = "Wire";
+
+ if( GetLayer() == LAYER_BUS )
+ layer = "Bus";
+
+ if( fprintf( aFile, "Wire %s %s\n", layer, width ) == EOF )
+ {
+ success = false;
+ }
+
+ if( fprintf( aFile, "\t%-4d %-4d %-4d %-4d\n", m_start.x, m_start.y,
+ m_end.x, m_end.y ) == EOF )
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+
+bool SCH_LINE::Load( LINE_READER& aLine, wxString& aErrorMsg )
+{
+ char Name1[256];
+ char Name2[256];
+ char* line = (char*) aLine;
+
+ while( (*line != ' ' ) && *line )
+ line++;
+
+ if( sscanf( line, "%255s %255s", Name1, Name2 ) != 2 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file segment error at line %d, aborted" ),
+ aLine.LineNumber() );
+ aErrorMsg << wxT( "\n" ) << FROM_UTF8( (char*) aLine );
+ return false;
+ }
+
+ m_Layer = LAYER_NOTES;
+
+ if( Name1[0] == 'W' )
+ m_Layer = LAYER_WIRE;
+
+ if( Name1[0] == 'B' )
+ m_Layer = LAYER_BUS;
+
+ if( !aLine.ReadLine() || sscanf( (char*) aLine, "%d %d %d %d ",
+ &m_start.x, &m_start.y, &m_end.x, &m_end.y ) != 4 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file Segment struct error at line %d, aborted" ),
+ aLine.LineNumber() );
+ aErrorMsg << wxT( "\n" ) << FROM_UTF8( (char*) aLine );
+ return false;
+ }
+
+ return true;
+}
+
+
+int SCH_LINE::GetPenSize() const
+{
+
+ if( m_Layer == LAYER_BUS )
+ return GetDefaultBusThickness();
+
+ return GetDefaultLineThickness();
+}
+
+
+void SCH_LINE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
+ GR_DRAWMODE DrawMode, EDA_COLOR_T Color )
+{
+ EDA_COLOR_T color;
+ int width = GetPenSize();
+
+ if( Color >= 0 )
+ color = Color;
+ else
+ color = GetLayerColor( m_Layer );
+
+ GRSetDrawMode( DC, DrawMode );
+
+ wxPoint start = m_start;
+ wxPoint end = m_end;
+
+ if( ( m_Flags & STARTPOINT ) == 0 )
+ start += offset;
+
+ if( ( m_Flags & ENDPOINT ) == 0 )
+ end += offset;
+
+ if( m_Layer == LAYER_NOTES )
+ GRDashedLine( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y, width, color );
+ else
+ GRLine( panel->GetClipBox(), DC, start, end, width, color );
+
+ if( m_startIsDangling )
+ DrawDanglingSymbol( panel, DC, start, color );
+
+ if( m_endIsDangling )
+ DrawDanglingSymbol( panel, DC, end, color );
+}
+
+
+void SCH_LINE::MirrorX( int aXaxis_position )
+{
+ MIRROR( m_start.y, aXaxis_position );
+ MIRROR( m_end.y, aXaxis_position );
+}
+
+
+void SCH_LINE::MirrorY( int aYaxis_position )
+{
+ MIRROR( m_start.x, aYaxis_position );
+ MIRROR( m_end.x, aYaxis_position );
+}
+
+
+void SCH_LINE::Rotate( wxPoint aPosition )
+{
+ RotatePoint( &m_start, aPosition, 900 );
+ RotatePoint( &m_end, aPosition, 900 );
+}
+
+
+/*
+ * helper sort function, used by MergeOverlap
+ * sorts ref and test by x values, or (for same x values) by y values
+ */
+bool sort_by_ends_position(const wxPoint * ref, const wxPoint * tst )
+{
+ if( ref->x == tst->x )
+ return ref->y < tst->y;
+ return ref->x < tst->x;
+}
+
+/*
+ * MergeOverlap try to merge 2 lines that are colinear.
+ * this function expects these 2 lines have at least a common end
+ */
+bool SCH_LINE::MergeOverlap( SCH_LINE* aLine )
+{
+ wxCHECK_MSG( aLine != NULL && aLine->Type() == SCH_LINE_T, false,
+ wxT( "Cannot test line segment for overlap." ) );
+
+ if( this == aLine || GetLayer() != aLine->GetLayer() )
+ return false;
+
+ // Search for a common end:
+ if( m_start == aLine->m_start )
+ {
+ if( m_end == aLine->m_end ) // Trivial case
+ return true;
+ }
+ else if( m_start == aLine->m_end )
+ {
+ if( m_end == aLine->m_start ) // Trivial case
+ return true;
+ }
+ else if( m_end == aLine->m_end )
+ {
+ std::swap( aLine->m_start, aLine->m_end );
+ }
+ else if( m_end != aLine->m_start )
+ {
+ // No common end point, segments cannot be merged.
+ return false;
+ }
+
+ bool colinear = false;
+
+ /* Test alignment: */
+ if( m_start.y == m_end.y ) // Horizontal segment
+ {
+ if( aLine->m_start.y == aLine->m_end.y )
+ {
+ colinear = true;
+ }
+ }
+ else if( m_start.x == m_end.x ) // Vertical segment
+ {
+ if( aLine->m_start.x == aLine->m_end.x )
+ {
+ colinear = true;
+ }
+ }
+ else
+ {
+ if( atan2( (double) ( m_start.x - m_end.x ), (double) ( m_start.y - m_end.y ) )
+ == atan2( (double) ( aLine->m_start.x - aLine->m_end.x ),
+ (double) ( aLine->m_start.y - aLine->m_end.y ) ) )
+ {
+ colinear = true;
+ }
+ }
+
+ // Make a segment which merge the 2 segments
+ // we must find the extremums
+ // i.e. the more to the left and to the right points, or
+ // for horizontal segments the uppermost and the lowest point
+ if( colinear )
+ {
+ static std::vector <wxPoint*> candidates;
+ candidates.clear();
+ candidates.push_back( &m_start );
+ candidates.push_back( &m_end );
+ candidates.push_back( &aLine->m_start );
+ candidates.push_back( &aLine->m_end );
+ sort( candidates.begin(), candidates.end(), sort_by_ends_position );
+ wxPoint tmp = *candidates[3];
+ m_start = *candidates[0];
+ m_end = tmp;
+ return true;
+ }
+ return false;
+}
+
+
+void SCH_LINE::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
+{
+ if( GetLayer() == LAYER_NOTES )
+ return;
+
+ if( ( GetLayer() == LAYER_BUS ) || ( GetLayer() == LAYER_WIRE ) )
+ {
+ DANGLING_END_ITEM item( (GetLayer() == LAYER_BUS) ? BUS_START_END : WIRE_START_END, this,
+ m_start );
+ aItemList.push_back( item );
+
+ DANGLING_END_ITEM item1( (GetLayer() == LAYER_BUS) ? BUS_END_END : WIRE_END_END, this,
+ m_end );
+ aItemList.push_back( item1 );
+ }
+}
+
+
+bool SCH_LINE::IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList )
+{
+ bool previousStartState = m_startIsDangling;
+ bool previousEndState = m_endIsDangling;
+
+ m_startIsDangling = m_endIsDangling = true;
+
+ if( GetLayer() == LAYER_WIRE )
+ {
+ BOOST_FOREACH( DANGLING_END_ITEM item, aItemList )
+ {
+ if( item.GetItem() == this )
+ continue;
+
+ if( item.GetType() == NO_CONNECT_END )
+ continue;
+
+ if( m_start == item.GetPosition() )
+ m_startIsDangling = false;
+
+ if( m_end == item.GetPosition() )
+ m_endIsDangling = false;
+
+ if( (m_startIsDangling == false) && (m_endIsDangling == false) )
+ break;
+ }
+ }
+ else if( GetLayer() == LAYER_BUS || GetLayer() == LAYER_NOTES )
+ {
+ // Lines on the notes layer and the bus layer cannot be tested for dangling ends.
+ previousStartState = previousEndState = m_startIsDangling = m_endIsDangling = false;
+ }
+
+ return ( previousStartState != m_startIsDangling ) || ( previousEndState != m_endIsDangling );
+}
+
+
+bool SCH_LINE::IsSelectStateChanged( const wxRect& aRect )
+{
+ bool previousState = IsSelected();
+
+ if( aRect.Contains( m_start ) && aRect.Contains( m_end ) )
+ {
+ SetFlags( SELECTED );
+ ClearFlags( STARTPOINT | ENDPOINT );
+ }
+ else if( aRect.Contains( m_start ) )
+ {
+ ClearFlags( STARTPOINT );
+ SetFlags( SELECTED | ENDPOINT );
+ }
+ else if( aRect.Contains( m_end ) )
+ {
+ ClearFlags( ENDPOINT );
+ SetFlags( SELECTED | STARTPOINT );
+ }
+ else
+ {
+ ClearFlags( SELECTED | STARTPOINT | ENDPOINT );
+ }
+
+ return previousState != IsSelected();
+}
+
+
+bool SCH_LINE::IsConnectable() const
+{
+ if( m_Layer == LAYER_WIRE || m_Layer == LAYER_BUS )
+ return true;
+
+ return false;
+}
+
+
+void SCH_LINE::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
+{
+ aPoints.push_back( m_start );
+ aPoints.push_back( m_end );
+}
+
+
+wxString SCH_LINE::GetSelectMenuText() const
+{
+ wxString menuText, txtfmt, orient;
+
+ if( m_start.x == m_end.x )
+ orient = _("Vert.");
+ else if( m_start.y == m_end.y )
+ orient = _("Horiz.");
+
+ switch( m_Layer )
+ {
+ case LAYER_NOTES:
+ txtfmt = _( "%s Graphic Line from (%s,%s) to (%s,%s) " );
+ break;
+
+ case LAYER_WIRE:
+ txtfmt = _( "%s Wire from (%s,%s) to (%s,%s)" );
+ break;
+
+ case LAYER_BUS:
+ txtfmt = _( "%s Bus from (%s,%s) to (%s,%s)" );
+ break;
+
+ default:
+ txtfmt += _( "%s Line on Unknown Layer from (%s,%s) to (%s,%s)" );
+ }
+
+ menuText.Printf( txtfmt, GetChars( orient ),
+ GetChars( CoordinateToString( m_start.x ) ),
+ GetChars( CoordinateToString( m_start.y ) ),
+ GetChars( CoordinateToString( m_end.x ) ),
+ GetChars( CoordinateToString( m_end.y ) ) );
+
+ return menuText;
+}
+
+
+BITMAP_DEF SCH_LINE::GetMenuImage() const
+{
+ if( m_Layer == LAYER_NOTES )
+ return add_dashed_line_xpm;
+ else if( m_Layer == LAYER_WIRE )
+ return add_line_xpm;
+
+ return add_bus_xpm;
+}
+
+
+void SCH_LINE::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
+ SCH_SHEET_PATH* aSheetPath )
+{
+ // Net list item not required for graphic lines.
+ if( (GetLayer() != LAYER_BUS) && (GetLayer() != LAYER_WIRE) )
+ return;
+
+ NETLIST_OBJECT* item = new NETLIST_OBJECT();
+ item->m_SheetPath = *aSheetPath;
+ item->m_SheetPathInclude = *aSheetPath;
+ item->m_Comp = (SCH_ITEM*) this;
+ item->m_Start = m_start;
+ item->m_End = m_end;
+
+ if( GetLayer() == LAYER_BUS )
+ {
+ item->m_Type = NET_BUS;
+ }
+ else /* WIRE */
+ {
+ item->m_Type = NET_SEGMENT;
+ }
+
+ aNetListItems.push_back( item );
+}
+
+
+bool SCH_LINE::operator <( const SCH_ITEM& aItem ) const
+{
+ if( Type() != aItem.Type() )
+ return Type() < aItem.Type();
+
+ SCH_LINE* line = (SCH_LINE*) &aItem;
+
+ if( GetLength() != line->GetLength() )
+ return GetLength() < line->GetLength();
+
+ if( m_start.x != line->m_start.x )
+ return m_start.x < line->m_start.x;
+
+ if( m_start.y != line->m_start.y )
+ return m_start.y < line->m_start.y;
+
+ return false;
+}
+
+
+bool SCH_LINE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
+{
+ return TestSegmentHit( aPosition, m_start, m_end, aAccuracy );
+}
+
+
+bool SCH_LINE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ if( m_Flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
+ return false;
+
+ EDA_RECT rect = aRect;
+
+ if ( aAccuracy )
+ rect.Inflate( aAccuracy );
+
+ if( aContained )
+ return rect.Contains( m_start ) && rect.Contains( m_end );
+
+ return rect.Intersects( m_start, m_end );
+}
+
+
+bool SCH_LINE::doIsConnected( const wxPoint& aPosition ) const
+{
+ if( m_Layer != LAYER_WIRE && m_Layer != LAYER_BUS )
+ return false;
+
+ return IsEndPoint( aPosition );
+}
+
+
+void SCH_LINE::Plot( PLOTTER* aPlotter )
+{
+ aPlotter->SetColor( GetLayerColor( GetLayer() ) );
+ aPlotter->SetCurrentLineWidth( GetPenSize() );
+
+ if( m_Layer == LAYER_NOTES )
+ aPlotter->SetDash( true );
+
+ aPlotter->MoveTo( m_start );
+ aPlotter->FinishTo( m_end );
+
+ if( m_Layer == LAYER_NOTES )
+ aPlotter->SetDash( false );
+}
+
+
+void SCH_LINE::SetPosition( const wxPoint& aPosition )
+{
+ m_end = m_end - ( m_start - aPosition );
+ m_start = aPosition;
+}
diff --git a/eeschema/sch_line.h b/eeschema/sch_line.h
new file mode 100644
index 0000000..87a3972
--- /dev/null
+++ b/eeschema/sch_line.h
@@ -0,0 +1,157 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_line.h
+ */
+
+#ifndef _SCH_LINE_H_
+#define _SCH_LINE_H_
+
+
+#include <sch_item_struct.h>
+
+class NETLIST_OBJECT_LIST;
+
+/**
+ * Class SCH_LINE
+ * is a segment description base class to describe items which have 2 end
+ * points (track, wire, draw line ...)
+ */
+class SCH_LINE : public SCH_ITEM
+{
+ bool m_startIsDangling; ///< True if start point is not connected.
+ bool m_endIsDangling; ///< True if end point is not connected.
+ wxPoint m_start; ///< Line start point
+ wxPoint m_end; ///< Line end point
+
+public:
+ SCH_LINE( const wxPoint& pos = wxPoint( 0, 0 ), int layer = LAYER_NOTES );
+
+ SCH_LINE( const SCH_LINE& aLine );
+
+ ~SCH_LINE() { }
+
+ SCH_LINE* Next() const { return (SCH_LINE*) Pnext; }
+ SCH_LINE* Back() const { return (SCH_LINE*) Pback; }
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_LINE" );
+ }
+
+ bool IsEndPoint( const wxPoint& aPoint ) const
+ {
+ return aPoint == m_start || aPoint == m_end;
+ }
+
+ bool IsNull() const { return m_start == m_end; }
+
+ wxPoint GetStartPoint() const { return m_start; }
+
+ void SetStartPoint( const wxPoint& aPosition ) { m_start = aPosition; }
+
+ wxPoint GetEndPoint() const { return m_end; }
+
+ void SetEndPoint( const wxPoint& aPosition ) { m_end = aPosition; }
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ /**
+ * Function GetLength
+ * @return The length of the line segment.
+ */
+ double GetLength() const;
+
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR );
+
+ bool Save( FILE* aFile ) const;
+
+ bool Load( LINE_READER& aLine, wxString& aErrorMsg );
+
+ int GetPenSize() const;
+
+ void Move( const wxPoint& aMoveVector );
+
+ void MirrorX( int aXaxis_position );
+
+ void MirrorY( int aYaxis_position );
+
+ void Rotate( wxPoint aPosition );
+
+ /**
+ * Check line against \a aLine to see if it overlaps and merge if it does.
+ *
+ * This method will change the line to be equivalent of the line and \a aLine if the
+ * two lines overlap. This method is used to merge multiple line segments into a single
+ * line.
+ *
+ * @param aLine - Line to compare.
+ * @return True if lines overlap and the line was merged with \a aLine.
+ */
+ bool MergeOverlap( SCH_LINE* aLine );
+
+ void GetEndPoints( std::vector<DANGLING_END_ITEM>& aItemList );
+
+ bool IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList );
+
+ bool IsDangling() const { return m_startIsDangling || m_endIsDangling; }
+
+ bool IsSelectStateChanged( const wxRect& aRect );
+
+ bool IsConnectable() const;
+
+ void GetConnectionPoints(std::vector< wxPoint >& aPoints ) const;
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const;
+
+ void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, SCH_SHEET_PATH* aSheetPath );
+
+ bool operator <( const SCH_ITEM& aItem ) const;
+
+ wxPoint GetPosition() const { return m_start; }
+
+ void SetPosition( const wxPoint& aPosition );
+
+ bool HitTest( const wxPoint& aPosition, int aAccuracy ) const;
+
+ bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const;
+
+ void Plot( PLOTTER* aPlotter );
+
+ EDA_ITEM* Clone() const;
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // override
+#endif
+
+private:
+ bool doIsConnected( const wxPoint& aPosition ) const;
+};
+
+
+#endif // _SCH_LINE_H_
diff --git a/eeschema/sch_marker.cpp b/eeschema/sch_marker.cpp
new file mode 100644
index 0000000..334d277
--- /dev/null
+++ b/eeschema/sch_marker.cpp
@@ -0,0 +1,186 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_marker.cpp
+ * @brief Class SCH_MARKER implementation
+ */
+
+#include <fctsys.h>
+#include <wxstruct.h>
+#include <class_drawpanel.h>
+#include <trigo.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <sch_marker.h>
+#include <erc.h>
+
+
+/********************/
+/* class SCH_MARKER */
+/********************/
+
+SCH_MARKER::SCH_MARKER() : SCH_ITEM( NULL, SCH_MARKER_T ), MARKER_BASE()
+{
+}
+
+
+SCH_MARKER::SCH_MARKER( const wxPoint& pos, const wxString& text ) :
+ SCH_ITEM( NULL, SCH_MARKER_T ),
+ MARKER_BASE( 0, pos, text, pos )
+{
+}
+
+
+EDA_ITEM* SCH_MARKER::Clone() const
+{
+ return new SCH_MARKER( *this );
+}
+
+
+#if defined(DEBUG)
+
+void SCH_MARKER::Show( int nestLevel, std::ostream& os ) const
+{
+ // for now, make it look like XML:
+ NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
+ << GetPos() << "/>\n";
+}
+
+#endif
+
+/**
+ * Function Save (do nothing : markers are no more saved in files )
+ * writes the data structures for this object out to a FILE in "*.brd" format.
+ * @param aFile The FILE to write to.
+ * @return bool - true if success writing else false.
+ */
+bool SCH_MARKER::Save( FILE* aFile ) const
+{
+ return true;
+}
+
+
+void SCH_MARKER::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aOffset, GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor )
+{
+ EDA_COLOR_T color = m_Color;
+ EDA_COLOR_T tmp = color;
+
+ if( GetMarkerType() == MARKER_BASE::MARKER_ERC )
+ {
+ color = ( GetErrorLevel() == MARKER_BASE::MARKER_SEVERITY_ERROR ) ?
+ GetLayerColor( LAYER_ERC_ERR ) : GetLayerColor( LAYER_ERC_WARN );
+ }
+
+ if( aColor < 0 )
+ m_Color = color;
+ else
+ m_Color = aColor;
+
+ DrawMarker( aPanel, aDC, aDrawMode, aOffset );
+ m_Color = tmp;
+}
+
+
+bool SCH_MARKER::Matches( wxFindReplaceData& aSearchData, void* aAuxData,
+ wxPoint * aFindLocation )
+{
+ if( SCH_ITEM::Matches( m_drc.GetErrorText(), aSearchData ) ||
+ SCH_ITEM::Matches( m_drc.GetMainText(), aSearchData ) ||
+ SCH_ITEM::Matches( m_drc.GetAuxiliaryText(), aSearchData ) )
+ {
+ if( aFindLocation )
+ *aFindLocation = m_Pos;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+/**
+ * Function GetBoundingBox
+ * returns the orthogonal, bounding box of this object for display purposes.
+ * This box should be an enclosing perimeter for visible components of this
+ * object, and the units should be in the pcb or schematic coordinate system.
+ * It is OK to overestimate the size by a few counts.
+ */
+const EDA_RECT SCH_MARKER::GetBoundingBox() const
+{
+ return GetBoundingBoxMarker();
+}
+
+
+void SCH_MARKER::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
+{
+ wxString msg;
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Electronics Rule Check Error" ),
+ GetReporter().GetErrorText(), DARKRED ) );
+}
+
+
+void SCH_MARKER::Rotate( wxPoint aPosition )
+{
+ RotatePoint( &m_Pos, aPosition, 900 );
+}
+
+
+void SCH_MARKER::MirrorX( int aXaxis_position )
+{
+ m_Pos.y -= aXaxis_position;
+ m_Pos.y = -m_Pos.y;
+ m_Pos.y += aXaxis_position;
+}
+
+
+void SCH_MARKER::MirrorY( int aYaxis_position )
+{
+ m_Pos.x -= aYaxis_position;
+ m_Pos.x = -m_Pos.x;
+ m_Pos.x += aYaxis_position;
+}
+
+
+bool SCH_MARKER::IsSelectStateChanged( const wxRect& aRect )
+{
+ bool previousState = IsSelected();
+
+ if( aRect.Contains( m_Pos ) )
+ SetFlags( SELECTED );
+ else
+ ClearFlags( SELECTED );
+
+ return previousState != IsSelected();
+}
+
+
+bool SCH_MARKER::HitTest( const wxPoint& aPosition, int aAccuracy ) const
+{
+ return HitTestMarker( aPosition );
+}
+
diff --git a/eeschema/sch_marker.h b/eeschema/sch_marker.h
new file mode 100644
index 0000000..0c534d9
--- /dev/null
+++ b/eeschema/sch_marker.h
@@ -0,0 +1,117 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * @file sch_marker.h
+ * @brief SCH_MARKER class definition.
+ */
+
+#ifndef TYPE_SCH_MARKER_H_
+#define TYPE_SCH_MARKER_H_
+
+#include <sch_item_struct.h>
+#include <class_marker_base.h>
+
+
+/* Names for corresponding types of markers: */
+extern const wxChar* NameMarqueurType[];
+
+
+class SCH_MARKER : public SCH_ITEM, public MARKER_BASE
+{
+public:
+ SCH_MARKER();
+
+ SCH_MARKER( const wxPoint& aPos, const wxString& aText );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_MARKER" );
+ }
+
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDraw_mode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR );
+
+ void Plot( PLOTTER* aPlotter )
+ {
+ // SCH_MARKERs should not be plotted. However, SCH_ITEM will fail an
+ // assertion if we do not confirm this by locally implementing a no-op
+ // Plot().
+ (void) aPlotter;
+ }
+
+ bool Save( FILE* aFile ) const;
+
+ EDA_RECT const GetBoundingBox() const; // Virtual
+
+ // Geometric transforms (used in block operations):
+
+ void Move( const wxPoint& aMoveVector )
+ {
+ m_Pos += aMoveVector;
+ }
+
+
+ void MirrorY( int aYaxis_position );
+
+ void MirrorX( int aXaxis_position );
+
+ void Rotate( wxPoint aPosition );
+
+ /**
+ * Function Matches, virtual from the base class EDA_ITEM
+ * Compare DRC marker main and auxiliary text against search string.
+ *
+ * @param aSearchData - Criteria to search against.
+ * @param aAuxData A pointer to optional data required for the search or NULL
+ * if not used.
+ * @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL.
+ * @return True if the DRC main or auxiliary text matches the search criteria.
+ */
+ bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ bool IsSelectStateChanged( const wxRect& aRect );
+
+ wxString GetSelectMenuText() const { return wxString( _( "ERC Marker" ) ); }
+
+ BITMAP_DEF GetMenuImage() const { return erc_xpm; }
+
+ wxPoint GetPosition() const { return m_Pos; }
+
+ void SetPosition( const wxPoint& aPosition ) { m_Pos = aPosition; }
+
+ bool HitTest( const wxPoint& aPosition, int aAccuracy ) const;
+
+ EDA_ITEM* Clone() const;
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // override
+#endif
+};
+
+#endif // TYPE_SCH_MARKER_H_
diff --git a/eeschema/sch_no_connect.cpp b/eeschema/sch_no_connect.cpp
new file mode 100644
index 0000000..dd1e978
--- /dev/null
+++ b/eeschema/sch_no_connect.cpp
@@ -0,0 +1,252 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_no_connect.cpp
+ * @brief Class SCH_NO_CONNECT implementation.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <common.h>
+#include <plot_common.h>
+
+#include <general.h>
+#include <sch_no_connect.h>
+#include <class_netlist_object.h>
+
+
+SCH_NO_CONNECT::SCH_NO_CONNECT( const wxPoint& pos ) :
+ SCH_ITEM( NULL, SCH_NO_CONNECT_T )
+{
+#define DRAWNOCONNECT_SIZE 48 /* No symbol connection range. */
+ m_pos = pos;
+ m_size.x = m_size.y = DRAWNOCONNECT_SIZE;
+#undef DRAWNOCONNECT_SIZE
+
+ SetLayer( LAYER_NOCONNECT );
+}
+
+
+EDA_ITEM* SCH_NO_CONNECT::Clone() const
+{
+ return new SCH_NO_CONNECT( *this );
+}
+
+
+void SCH_NO_CONNECT::SwapData( SCH_ITEM* aItem )
+{
+ wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_NO_CONNECT_T),
+ wxT( "Cannot swap no connect data with invalid item." ) );
+
+ SCH_NO_CONNECT* item = (SCH_NO_CONNECT*)aItem;
+ std::swap( m_pos, item->m_pos );
+ std::swap( m_size, item->m_size );
+}
+
+
+const EDA_RECT SCH_NO_CONNECT::GetBoundingBox() const
+{
+ int delta = ( GetPenSize() + m_size.x ) / 2;
+ EDA_RECT box;
+
+ box.SetOrigin( m_pos );
+ box.Inflate( delta );
+
+ return box;
+}
+
+
+bool SCH_NO_CONNECT::Save( FILE* aFile ) const
+{
+ bool success = true;
+
+ if( fprintf( aFile, "NoConn ~ %-4d %-4d\n", m_pos.x, m_pos.y ) == EOF )
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+
+bool SCH_NO_CONNECT::Load( LINE_READER& aLine, wxString& aErrorMsg )
+{
+ char name[256];
+ char* line = (char*) aLine;
+
+ while( (*line != ' ' ) && *line )
+ line++;
+
+ if( sscanf( line, "%255s %d %d", name, &m_pos.x, &m_pos.y ) != 3 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file No Connect load error at line %d" ),
+ aLine.LineNumber() );
+ aErrorMsg << wxT( "\n" ) << FROM_UTF8( ((char*)aLine) );
+ return false;
+ }
+
+ return true;
+}
+
+
+void SCH_NO_CONNECT::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList )
+{
+ DANGLING_END_ITEM item( NO_CONNECT_END, this, m_pos );
+ aItemList.push_back( item );
+}
+
+
+int SCH_NO_CONNECT::GetPenSize() const
+{
+ return GetDefaultLineThickness();
+}
+
+
+void SCH_NO_CONNECT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor )
+{
+ int pX, pY;
+ int delta = m_size.x / 2;
+ int width = GetDefaultLineThickness();
+
+ pX = m_pos.x + aOffset.x;
+ pY = m_pos.y + aOffset.y;
+
+ EDA_COLOR_T color;
+ if( aColor >= 0 )
+ color = aColor;
+ else
+ color = GetLayerColor( LAYER_NOCONNECT );
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ GRLine( aPanel->GetClipBox(), aDC, pX - delta, pY - delta, pX + delta, pY + delta,
+ width, color );
+ GRLine( aPanel->GetClipBox(), aDC, pX + delta, pY - delta, pX - delta, pY + delta,
+ width, color );
+}
+
+
+void SCH_NO_CONNECT::MirrorX( int aXaxis_position )
+{
+ MIRROR( m_pos.y, aXaxis_position );
+}
+
+
+void SCH_NO_CONNECT::MirrorY( int aYaxis_position )
+{
+ MIRROR( m_pos.x, aYaxis_position );
+}
+
+
+void SCH_NO_CONNECT::Rotate( wxPoint aPosition )
+{
+ RotatePoint( &m_pos, aPosition, 900 );
+}
+
+
+bool SCH_NO_CONNECT::IsSelectStateChanged( const wxRect& aRect )
+{
+ bool previousState = IsSelected();
+
+ if( aRect.Contains( m_pos ) )
+ SetFlags( SELECTED );
+ else
+ ClearFlags( SELECTED );
+
+ return previousState != IsSelected();
+}
+
+
+void SCH_NO_CONNECT::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
+{
+ aPoints.push_back( m_pos );
+}
+
+
+void SCH_NO_CONNECT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
+ SCH_SHEET_PATH* aSheetPath )
+{
+ NETLIST_OBJECT* item = new NETLIST_OBJECT();
+
+ item->m_SheetPath = *aSheetPath;
+ item->m_SheetPathInclude = *aSheetPath;
+ item->m_Comp = this;
+ item->m_Type = NET_NOCONNECT;
+ item->m_Start = item->m_End = m_pos;
+
+ aNetListItems.push_back( item );
+}
+
+
+bool SCH_NO_CONNECT::doIsConnected( const wxPoint& aPosition ) const
+{
+ return m_pos == aPosition;
+}
+
+bool SCH_NO_CONNECT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
+{
+ int delta = ( ( m_size.x + GetDefaultLineThickness() ) / 2 ) + aAccuracy;
+
+ wxPoint dist = aPosition - m_pos;
+
+ if( ( std::abs( dist.x ) <= delta ) && ( std::abs( dist.y ) <= delta ) )
+ return true;
+
+ return false;
+}
+
+
+bool SCH_NO_CONNECT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ EDA_RECT rect = aRect;
+
+ rect.Inflate( aAccuracy );
+
+ if( aContained )
+ return rect.Contains( GetBoundingBox() );
+
+ return rect.Intersects( GetBoundingBox() );
+}
+
+
+void SCH_NO_CONNECT::Plot( PLOTTER* aPlotter )
+{
+ int delta = m_size.x / 2;
+ int pX, pY;
+
+ pX = m_pos.x;
+ pY = m_pos.y;
+
+ aPlotter->SetCurrentLineWidth( GetPenSize() );
+ aPlotter->SetColor( GetLayerColor( GetLayer() ) );
+ aPlotter->MoveTo( wxPoint( pX - delta, pY - delta ) );
+ aPlotter->FinishTo( wxPoint( pX + delta, pY + delta ) );
+ aPlotter->MoveTo( wxPoint( pX + delta, pY - delta ) );
+ aPlotter->FinishTo( wxPoint( pX - delta, pY + delta ) );
+}
+
diff --git a/eeschema/sch_no_connect.h b/eeschema/sch_no_connect.h
new file mode 100644
index 0000000..f566304
--- /dev/null
+++ b/eeschema/sch_no_connect.h
@@ -0,0 +1,115 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_no_connect.h
+ */
+
+#ifndef _SCH_NO_CONNECT_H_
+#define _SCH_NO_CONNECT_H_
+
+
+#include <sch_item_struct.h>
+
+class NETLIST_OBJECT_LIST;
+
+class SCH_NO_CONNECT : public SCH_ITEM
+{
+ wxPoint m_pos; ///< Position of the no connect object.
+ wxSize m_size; ///< Size of the no connect object.
+
+public:
+ SCH_NO_CONNECT( const wxPoint& pos = wxPoint( 0, 0 ) );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~SCH_NO_CONNECT() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_NO_CONNECT" );
+ }
+
+ int GetPenSize() const;
+
+ void SwapData( SCH_ITEM* aItem );
+
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR );
+
+ bool Save( FILE* aFile ) const;
+
+ bool Load( LINE_READER& aLine, wxString& aErrorMsg );
+
+ void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList );
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ // Geometric transforms (used in block operations):
+
+ void Move( const wxPoint& aMoveVector )
+ {
+ m_pos += aMoveVector;
+ }
+
+ void MirrorY( int aYaxis_position );
+
+ void MirrorX( int aXaxis_position );
+
+ void Rotate( wxPoint aPosition );
+
+ bool IsSelectStateChanged( const wxRect& aRect );
+
+ bool IsConnectable() const { return true; }
+
+ void GetConnectionPoints( std::vector< wxPoint >& aPoints ) const;
+
+ wxString GetSelectMenuText() const { return wxString( _( "No Connect" ) ); }
+
+ BITMAP_DEF GetMenuImage() const { return noconn_xpm; }
+
+ void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, SCH_SHEET_PATH* aSheetPath );
+
+ wxPoint GetPosition() const { return m_pos; }
+
+ void SetPosition( const wxPoint& aPosition ) { m_pos = aPosition; }
+
+ bool HitTest( const wxPoint& aPosition, int aAccuracy ) const;
+
+ bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const;
+
+ void Plot( PLOTTER* aPlotter );
+
+ EDA_ITEM* Clone() const;
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+
+private:
+ bool doIsConnected( const wxPoint& aPosition ) const;
+};
+
+
+#endif // _SCH_NO_CONNECT_H_
diff --git a/eeschema/sch_reference_list.h b/eeschema/sch_reference_list.h
new file mode 100644
index 0000000..d5048cb
--- /dev/null
+++ b/eeschema/sch_reference_list.h
@@ -0,0 +1,469 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2011 jean-pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
+ * Copyright (C) 1992-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see authors.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/**
+ * @file eeschema/sch_reference_list.h
+ */
+
+#ifndef _SCH_REFERENCE_LIST_H_
+#define _SCH_REFERENCE_LIST_H_
+
+
+#include <macros.h>
+
+#include <class_libentry.h>
+#include <sch_sheet_path.h>
+#include <sch_component.h>
+#include <sch_text.h>
+
+#include <map>
+
+class SCH_REFERENCE;
+class SCH_REFERENCE_LIST;
+
+/**
+ * Class SCH_REFERENCE
+ * is used as a helper to define a component's reference designator in a schematic. This
+ * helper is required in a complex hierarchy because a component can be used more than
+ * once and its reference depends on the sheet path. This class is used to flatten the
+ * schematic hierarchy for annotation, net list generation, and bill of material
+ * generation.
+ */
+class SCH_REFERENCE
+{
+ /// Component reference prefix, without number (for IC1, this is IC) )
+ UTF8 m_Ref; // it's private, use the accessors please
+ SCH_COMPONENT* m_RootCmp; ///< The component associated the reference object.
+ LIB_PART* m_Entry; ///< The source component from a library.
+ wxPoint m_CmpPos; ///< The physical position of the component in schematic
+ ///< used to annotate by X or Y position
+ int m_Unit; ///< The unit number for components with multiple parts
+ ///< per package.
+ SCH_SHEET_PATH m_SheetPath; ///< The sheet path for this reference.
+ bool m_IsNew; ///< True if not yet annotated.
+ int m_SheetNum; ///< The sheet number for the reference.
+ time_t m_TimeStamp; ///< The time stamp for the reference.
+ EDA_TEXT* m_Value; ///< The component value of the refernce. It is the
+ ///< same for all instances.
+ int m_NumRef; ///< The numeric part of the reference designator.
+ int m_Flag;
+
+ friend class SCH_REFERENCE_LIST;
+
+
+public:
+
+ SCH_REFERENCE() :
+ m_SheetPath()
+ {
+ m_RootCmp = NULL;
+ m_Entry = NULL;
+ m_Unit = 0;
+ m_TimeStamp = 0;
+ m_IsNew = false;
+ m_Value = NULL;
+ m_NumRef = 0;
+ m_Flag = 0;
+ m_SheetNum = 0;
+ }
+
+ SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_PART* aLibComponent,
+ SCH_SHEET_PATH& aSheetPath );
+
+ SCH_COMPONENT* GetComp() const { return m_RootCmp; }
+
+ LIB_PART* GetLibComponent() const { return m_Entry; }
+
+ SCH_SHEET_PATH GetSheetPath() const { return m_SheetPath; }
+
+ int GetUnit() const { return m_Unit; }
+
+ void SetSheetNumber( int aSheetNumber ) { m_SheetNum = aSheetNumber; }
+
+ /**
+ * Function Annotate
+ * updates the annotation of the component according the the current object state.
+ */
+ void Annotate();
+
+ /**
+ * Function Split
+ * attempts to split the reference designator into a name (U) and number (1). If the
+ * last character is '?' or not a digit, the reference is tagged as not annotated.
+ * For components with multiple parts per package that are not already annotated, set
+ * m_Unit to a max value (0x7FFFFFFF).
+ */
+ void Split();
+
+ /* Some accessors which hide the strategy of how the reference is stored,
+ thereby making it easy to change that strategy.
+ */
+
+ void SetRef( const wxString& aReference )
+ {
+ m_Ref = aReference;
+ }
+
+ wxString GetRef() const
+ {
+ return m_Ref;
+ }
+ void SetRefStr( const std::string& aReference )
+ {
+ m_Ref = aReference;
+ }
+ const char* GetRefStr() const
+ {
+ return m_Ref.c_str();
+ }
+
+ int CompareValue( const SCH_REFERENCE& item ) const
+ {
+ return Cmp_KEEPCASE( m_Value->GetText(), item.m_Value->GetText() );
+ }
+
+ int CompareRef( const SCH_REFERENCE& item ) const
+ {
+ return m_Ref.compare( item.m_Ref );
+ }
+
+ int CompareLibName( const SCH_REFERENCE& item ) const
+ {
+ return Cmp_KEEPCASE( m_RootCmp->GetPartName(), item.m_RootCmp->GetPartName() );
+ }
+
+ /**
+ * Function IsSameInstance
+ * returns whether this reference refers to the same component instance
+ * (component and sheet) as another.
+ */
+ bool IsSameInstance( const SCH_REFERENCE& other ) const
+ {
+ return GetComp() == other.GetComp() && GetSheetPath().Path() == other.GetSheetPath().Path();
+ }
+
+ bool IsUnitsLocked()
+ {
+ return m_Entry->UnitsLocked();
+ }
+};
+
+
+/**
+ * Class SCH_REFERENCE_LIST
+ * is used to create a flattened list of components because in a complex hierarchy, a component
+ * can be used more than once and its reference designator is dependent on the sheet path for
+ * the same component. This flattened list is used for netlist generation, BOM generation,
+ * and schematic annotation.
+ */
+class SCH_REFERENCE_LIST
+{
+private:
+ std::vector <SCH_REFERENCE> componentFlatList;
+
+public:
+ /** Constructor
+ */
+ SCH_REFERENCE_LIST()
+ {
+ }
+
+ SCH_REFERENCE& operator[]( int aIndex )
+ {
+ return componentFlatList[ aIndex ];
+ }
+
+ /**
+ * Function GetCount
+ * @return the number of items in the list
+ */
+ unsigned GetCount()
+ {
+ return componentFlatList.size();
+ }
+
+ /**
+ * Function GetItem
+ * @return the aIdx item
+ */
+ SCH_REFERENCE& GetItem( int aIdx )
+ {
+ return componentFlatList[aIdx];
+ }
+
+ /**
+ * Function AddItem
+ * adds a SCH_REFERENCE object to the list of references.
+ * @param aItem - a SCH_REFERENCE item to add
+ */
+ void AddItem( SCH_REFERENCE& aItem )
+ {
+ componentFlatList.push_back( aItem );
+ }
+
+ /**
+ * Function RemoveItem
+ * removes an item from the list of references.
+ *
+ * @param aIndex is the index of the item to be removed.
+ */
+ void RemoveItem( unsigned int aIndex );
+
+ /**
+ * Function RemoveSubComponentsFromList
+ * Remove sub components from the list, when multiples parts per package are
+ * found in this list.
+ * Useful to create BOM, when a component must appear only once
+ */
+ void RemoveSubComponentsFromList();
+
+ /* Sort functions:
+ * Sort functions are used to sort components for annotation or BOM generation.
+ * Because sorting depend on we want to do, there are many sort functions.
+ * Note:
+ * When creating BOM, components are fully annotated.
+ * references are something like U3, U5 or R4, R8
+ * When annotating, some or all components are not annotated,
+ * i.e. ref is only U or R, with no number.
+ */
+
+ /**
+ * Function SplitReferences
+ * attempts to split all reference designators into a name (U) and number (1). If the
+ * last character is '?' or not a digit, the reference is tagged as not annotated.
+ * For components with multiple parts per package that are not already annotated, set
+ * m_Unit to a max value (0x7FFFFFFF).
+ * @see SCH_REFERENCE::Split()
+ */
+ void SplitReferences()
+ {
+ for( unsigned ii = 0; ii < GetCount(); ii++ )
+ componentFlatList[ii].Split();
+ }
+
+ /**
+ * function UpdateAnnotation
+ * Updates the reference components for the schematic project (or the current sheet)
+ * Note: this function does not calculate the reference numbers stored in m_NumRef
+ * So, it must be called after calculation of new reference numbers
+ * @see SCH_REFERENCE::Annotate()
+ */
+ void UpdateAnnotation()
+ {
+ /* update the reference numbers */
+ for( unsigned ii = 0; ii < GetCount(); ii++ )
+ {
+ componentFlatList[ii].Annotate();
+ }
+ }
+
+ /**
+ * Function Annotate
+ * set the reference designators in the list that have not been annotated.
+ * @param aUseSheetNum Set to true to start annotation for each sheet at the sheet number
+ * times \a aSheetIntervalId. Otherwise annotate incrementally.
+ * @param aSheetIntervalId The per sheet reference designator multiplier.
+ * @param aLockedUnitMap A SCH_MULTI_UNIT_REFERENCE_MAP of reference designator wxStrings
+ * to SCH_REFERENCE_LISTs. May be an empty map. If not empty, any multi-unit parts
+ * found in this map will be annotated as a group rather than individually.
+ * <p>
+ * If a the sheet number is 2 and \a aSheetIntervalId is 100, then the first reference
+ * designator would be 201 and the last reference designator would be 299 when no overlap
+ * occurs with sheet number 3. If there are 150 items in sheet number 2, then items are
+ * referenced U201 to U351, and items in sheet 3 start from U352
+ * </p>
+ */
+ void Annotate( bool aUseSheetNum, int aSheetIntervalId, SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap );
+
+ /**
+ * Function CheckAnnotation
+ * check for annotations errors.
+ * <p>
+ * The following annotation error conditions are tested:
+ * <ul>
+ * <li>Components not annotated.</li>
+ * <li>Components having the same reference designator (duplicates).</li>
+ * <li>Components with multiple parts per package having different reference designators.</li>
+ * <li>Components with multiple parts per package with invalid part count.</li>
+ * </ul>
+ * </p>
+ * @param aMessageList A wxArrayString to store error messages.
+ * @return The number of errors found.
+ */
+ int CheckAnnotation( wxArrayString* aMessageList );
+
+ /**
+ * Function sortByXCoordinate
+ * sorts the list of references by X position.
+ * <p>
+ * Components are sorted as follows:
+ * <ul>
+ * <li>Numeric value of reference designator.</li>
+ * <li>Sheet number.</li>
+ * <li>X coordinate position.</li>
+ * <li>Y coordinate position.</li>
+ * <li>Time stamp.</li>
+ * </ul>
+ * </p>
+ */
+ void SortByXCoordinate()
+ {
+ sort( componentFlatList.begin(), componentFlatList.end(), sortByXPosition );
+ }
+
+ /**
+ * Function sortByYCoordinate
+ * sorts the list of references by Y position.
+ * <p>
+ * Components are sorted as follows:
+ * <ul>
+ * <li>Numeric value of reference designator.</li>
+ * <li>Sheet number.</li>
+ * <li>Y coordinate position.</li>
+ * <li>X coordinate position.</li>
+ * <li>Time stamp.</li>
+ * </ul>
+ * </p>
+ */
+ void SortByYCoordinate()
+ {
+ sort( componentFlatList.begin(), componentFlatList.end(), sortByYPosition );
+ }
+
+ /**
+ * Function SortComponentsByTimeStamp
+ * sort the flat list by Time Stamp.
+ * Useful to detect duplicate Time Stamps
+ */
+ void SortByTimeStamp()
+ {
+ sort( componentFlatList.begin(), componentFlatList.end(), sortByTimeStamp );
+ }
+
+ /**
+ * Function SortByRefAndValue
+ * sorts the list of references by value.
+ * <p>
+ * Components are sorted in the following order:
+ * <ul>
+ * <li>Numeric value of reference designator.</li>
+ * <li>Value of component.</li>
+ * <li>Unit number when component has multiple parts.</li>
+ * <li>Sheet number.</li>
+ * <li>X coordinate position.</li>
+ * <li>Y coordinate position.</li>
+ * </ul>
+ * </p>
+ */
+ void SortByRefAndValue()
+ {
+ sort( componentFlatList.begin(), componentFlatList.end(), sortByRefAndValue );
+ }
+
+ /**
+ * Function SortByReferenceOnly
+ * sorts the list of references by reference.
+ * <p>
+ * Components are sorted in the following order:
+ * <ul>
+ * <li>Numeric value of reference designator.</li>
+ * <li>Unit number when component has multiple parts.</li>
+ * </ul>
+ * </p>
+ */
+ void SortByReferenceOnly()
+ {
+ sort( componentFlatList.begin(), componentFlatList.end(), sortByReferenceOnly );
+ }
+
+ /**
+ * Function GetUnit
+ * searches the sorted list of components for a another component with the same
+ * reference and a given part unit. Use this method to manage components with
+ * multiple parts per package.
+ * @param aIndex = index in aComponentsList for of given SCH_REFERENCE item to test.
+ * @param aUnit = the given unit number to search
+ * @return index in aComponentsList if found or -1 if not found
+ */
+ int FindUnit( size_t aIndex, int aUnit );
+
+ /**
+ * Function ResetHiddenReferences
+ * clears the annotation for all references that have an invisible reference designator.
+ * Invisible reference designators always have # as the first letter.
+ */
+ void ResetHiddenReferences();
+
+ /**
+ * Function GetRefsInUse
+ * adds all the reference designator numbers greater than \a aMinRefId to \a aIdList
+ * skipping the reference at \a aIndex.
+ * @param aIndex = the current component index to use for reference prefix filtering.
+ * @param aIdList = the buffer to fill
+ * @param aMinRefId = the min id value to store. all values < aMinRefId are ignored
+ */
+ void GetRefsInUse( int aIndex, std::vector< int >& aIdList, int aMinRefId );
+
+ /**
+ * Function GetLastReference
+ * returns the last used (greatest) reference number in the reference list
+ * for the prefix reference given by \a aIndex. The component list must be
+ * sorted.
+ *
+ * @param aIndex The index of the reference item used for the search pattern.
+ * @param aMinValue The minimum value for the current search.
+ */
+ int GetLastReference( int aIndex, int aMinValue );
+
+private:
+ /* sort functions used to sort componentFlatList
+ */
+
+ static bool sortByRefAndValue( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
+
+ static bool sortByXPosition( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
+
+ static bool sortByYPosition( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
+
+ static bool sortByTimeStamp( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
+
+ static bool sortByReferenceOnly( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
+
+ /**
+ * Function CreateFirstFreeRefId
+ * searches for the first free reference number in \a aListId of reference numbers in use.
+ * This function just searches for a hole in a list of incremented numbers, this list must
+ * be sorted by increasing values and each value can be stored only once. The new value
+ * is added to the list.
+ * @see BuildRefIdInUseList to prepare this list
+ * @param aIdList The buffer that contains the reference numbers in use.
+ * @param aFirstValue The first expected free value
+ * @return The first free (not yet used) value.
+ */
+ int CreateFirstFreeRefId( std::vector<int>& aIdList, int aFirstValue );
+};
+
+#endif // _SCH_REFERENCE_LIST_H_
diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp
new file mode 100644
index 0000000..c2f8201
--- /dev/null
+++ b/eeschema/sch_screen.cpp
@@ -0,0 +1,1563 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_screen.cpp
+ * @brief Implementation of SCH_SCREEN and SCH_SCREENS classes.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <common.h>
+#include <kicad_string.h>
+#include <eeschema_id.h>
+#include <pgm_base.h>
+#include <kiway.h>
+#include <class_drawpanel.h>
+#include <sch_item_struct.h>
+#include <schframe.h>
+#include <plot_common.h>
+
+#include <netlist.h>
+#include <class_netlist_object.h>
+#include <class_library.h>
+#include <sch_junction.h>
+#include <sch_bus_entry.h>
+#include <sch_line.h>
+#include <sch_marker.h>
+#include <sch_no_connect.h>
+#include <sch_sheet.h>
+#include <sch_component.h>
+#include <sch_text.h>
+#include <lib_pin.h>
+
+#include <boost/foreach.hpp>
+
+#define EESCHEMA_FILE_STAMP "EESchema"
+
+/* Default zoom values. Limited to these values to keep a decent size
+ * to menus
+ */
+static double SchematicZoomList[] =
+{
+ 0.5, 0.7, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 8.0, 11.0,
+ 13.0, 16.0, 20.0, 26.0, 32.0, 48.0, 64.0, 80.0, 128.0
+};
+
+#define MM_TO_SCH_UNITS 1000.0 / 25.4 //schematic internal unites are mils
+
+
+/* Default grid sizes for the schematic editor.
+ * Do NOT add others values (mainly grid values in mm), because they
+ * can break the schematic: Because wires and pins are considered as
+ * connected when the are to the same coordinate we cannot mix
+ * coordinates in mils (internal units) and mm (that cannot exactly
+ * converted in mils in many cases). In fact schematic must only use
+ * 50 and 25 mils to place labels, wires and components others values
+ * are useful only for graphic items (mainly in library editor) so use
+ * integer values in mils only. The 100 mil grid is added to help
+ * conform to the KiCad Library Convention. Which states: "Using a
+ * 100mil grid, pin ends and origin must lie on grid nodes IEC-60617"
+*/
+static GRID_TYPE SchematicGridList[] = {
+ { ID_POPUP_GRID_LEVEL_100, wxRealPoint( 100, 100 ) },
+ { ID_POPUP_GRID_LEVEL_50, wxRealPoint( 50, 50 ) },
+ { ID_POPUP_GRID_LEVEL_25, wxRealPoint( 25, 25 ) },
+ { ID_POPUP_GRID_LEVEL_10, wxRealPoint( 10, 10 ) },
+ { ID_POPUP_GRID_LEVEL_5, wxRealPoint( 5, 5 ) },
+ { ID_POPUP_GRID_LEVEL_2, wxRealPoint( 2, 2 ) },
+ { ID_POPUP_GRID_LEVEL_1, wxRealPoint( 1, 1 ) },
+};
+
+
+SCH_SCREEN::SCH_SCREEN( KIWAY* aKiway ) :
+ BASE_SCREEN( SCH_SCREEN_T ),
+ KIWAY_HOLDER( aKiway ),
+ m_paper( wxT( "A4" ) )
+{
+ m_modification_sync = 0;
+
+ SetZoom( 32 );
+
+ for( unsigned i = 0; i < DIM( SchematicZoomList ); i++ )
+ m_ZoomList.push_back( SchematicZoomList[i] );
+
+ for( unsigned i = 0; i < DIM( SchematicGridList ); i++ )
+ AddGrid( SchematicGridList[i] );
+
+ SetGrid( wxRealPoint( 50, 50 ) ); // Default grid size.
+ m_refCount = 0;
+
+ // Suitable for schematic only. For libedit and viewlib, must be set to true
+ m_Center = false;
+
+ InitDataPoints( m_paper.GetSizeIU() );
+}
+
+
+SCH_SCREEN::~SCH_SCREEN()
+{
+ ClearUndoRedoList();
+ FreeDrawList();
+}
+
+
+void SCH_SCREEN::IncRefCount()
+{
+ m_refCount++;
+}
+
+
+void SCH_SCREEN::DecRefCount()
+{
+ wxCHECK_RET( m_refCount != 0,
+ wxT( "Screen reference count already zero. Bad programmer!" ) );
+ m_refCount--;
+}
+
+
+void SCH_SCREEN::Clear()
+{
+ FreeDrawList();
+
+ // Clear the project settings
+ m_ScreenNumber = m_NumberOfScreens = 1;
+
+ m_titles.Clear();
+}
+
+
+void SCH_SCREEN::FreeDrawList()
+{
+ m_drawList.DeleteAll();
+}
+
+
+void SCH_SCREEN::Remove( SCH_ITEM* aItem )
+{
+ m_drawList.Remove( aItem );
+}
+
+
+void SCH_SCREEN::DeleteItem( SCH_ITEM* aItem )
+{
+ wxCHECK_RET( aItem, wxT( "Cannot delete invalid item from screen." ) );
+
+ SetModify();
+
+ if( aItem->Type() == SCH_SHEET_PIN_T )
+ {
+ // This structure is attached to a sheet, get the parent sheet object.
+ SCH_SHEET_PIN* sheetPin = (SCH_SHEET_PIN*) aItem;
+ SCH_SHEET* sheet = sheetPin->GetParent();
+ wxCHECK_RET( sheet,
+ wxT( "Sheet label parent not properly set, bad programmer!" ) );
+ sheet->RemovePin( sheetPin );
+ return;
+ }
+ else
+ {
+ delete m_drawList.Remove( aItem );
+ }
+}
+
+
+bool SCH_SCREEN::CheckIfOnDrawList( SCH_ITEM* aItem )
+{
+ SCH_ITEM* itemList = m_drawList.begin();
+
+ while( itemList )
+ {
+ if( itemList == aItem )
+ return true;
+
+ itemList = itemList->Next();
+ }
+
+ return false;
+}
+
+
+SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T aType ) const
+{
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->HitTest( aPosition, aAccuracy ) && (aType == NOT_USED) )
+ return item;
+
+ if( (aType == SCH_FIELD_T) && (item->Type() == SCH_COMPONENT_T) )
+ {
+ SCH_COMPONENT* component = (SCH_COMPONENT*) item;
+
+ for( int i = REFERENCE; i < component->GetFieldCount(); i++ )
+ {
+ SCH_FIELD* field = component->GetField( i );
+
+ if( field->HitTest( aPosition, aAccuracy ) )
+ return (SCH_ITEM*) field;
+ }
+ }
+ else if( (aType == SCH_SHEET_PIN_T) && (item->Type() == SCH_SHEET_T) )
+ {
+ SCH_SHEET* sheet = (SCH_SHEET*)item;
+
+ SCH_SHEET_PIN* label = sheet->GetPin( aPosition );
+
+ if( label )
+ return (SCH_ITEM*) label;
+ }
+ else if( (item->Type() == aType) && item->HitTest( aPosition, aAccuracy ) )
+ {
+ return item;
+ }
+ }
+
+ return NULL;
+}
+
+
+void SCH_SCREEN::ExtractWires( DLIST< SCH_ITEM >& aList, bool aCreateCopy )
+{
+ SCH_ITEM* item;
+ SCH_ITEM* next_item;
+
+ for( item = m_drawList.begin(); item; item = next_item )
+ {
+ next_item = item->Next();
+
+ switch( item->Type() )
+ {
+ case SCH_JUNCTION_T:
+ case SCH_LINE_T:
+ m_drawList.Remove( item );
+ aList.Append( item );
+
+ if( aCreateCopy )
+ m_drawList.Insert( (SCH_ITEM*) item->Clone(), next_item );
+
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+void SCH_SCREEN::ReplaceWires( DLIST< SCH_ITEM >& aWireList )
+{
+ SCH_ITEM* item;
+ SCH_ITEM* next_item;
+
+ for( item = m_drawList.begin(); item; item = next_item )
+ {
+ next_item = item->Next();
+
+ switch( item->Type() )
+ {
+ case SCH_JUNCTION_T:
+ case SCH_LINE_T:
+ Remove( item );
+ delete item;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ m_drawList.Append( aWireList );
+}
+
+
+void SCH_SCREEN::MarkConnections( SCH_LINE* aSegment )
+{
+ wxCHECK_RET( (aSegment) && (aSegment->Type() == SCH_LINE_T),
+ wxT( "Invalid object pointer." ) );
+
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->GetFlags() & CANDIDATE )
+ continue;
+
+ if( item->Type() == SCH_JUNCTION_T )
+ {
+ SCH_JUNCTION* junction = (SCH_JUNCTION*) item;
+
+ if( aSegment->IsEndPoint( junction->GetPosition() ) )
+ item->SetFlags( CANDIDATE );
+
+ continue;
+ }
+
+ if( item->Type() != SCH_LINE_T )
+ continue;
+
+ SCH_LINE* segment = (SCH_LINE*) item;
+
+ if( aSegment->IsEndPoint( segment->GetStartPoint() )
+ && !GetPin( segment->GetStartPoint(), NULL, true ) )
+ {
+ item->SetFlags( CANDIDATE );
+ MarkConnections( segment );
+ }
+
+ if( aSegment->IsEndPoint( segment->GetEndPoint() )
+ && !GetPin( segment->GetEndPoint(), NULL, true ) )
+ {
+ item->SetFlags( CANDIDATE );
+ MarkConnections( segment );
+ }
+ }
+}
+
+
+bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition )
+{
+ if( GetItem( aPosition, 0, SCH_JUNCTION_T ) )
+ return false;
+
+ if( GetWire( aPosition, 0, EXCLUDE_END_POINTS_T ) )
+ {
+ if( GetWire( aPosition, 0, END_POINTS_ONLY_T ) )
+ return true;
+
+ if( GetPin( aPosition, NULL, true ) )
+ return true;
+ }
+
+ return false;
+}
+
+
+bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
+{
+ wxCHECK_MSG( aLayer == LAYER_NOTES || aLayer == LAYER_BUS || aLayer == LAYER_WIRE, false,
+ wxT( "Invalid layer type passed to SCH_SCREEN::IsTerminalPoint()." ) );
+
+ SCH_SHEET_PIN* label;
+ SCH_TEXT* text;
+
+ switch( aLayer )
+ {
+ case LAYER_BUS:
+
+ if( GetBus( aPosition ) )
+ return true;
+
+ label = GetSheetLabel( aPosition );
+
+ if( label && IsBusLabel( label->GetText() ) && label->IsConnected( aPosition ) )
+ return true;
+
+ text = GetLabel( aPosition );
+
+ if( text && IsBusLabel( text->GetText() ) && text->IsConnected( aPosition )
+ && (text->Type() != SCH_LABEL_T) )
+ return true;
+
+ break;
+
+ case LAYER_NOTES:
+
+ if( GetLine( aPosition ) )
+ return true;
+
+ break;
+
+ case LAYER_WIRE:
+ if( GetItem( aPosition, std::max( GetDefaultLineThickness(), 3 ), SCH_BUS_WIRE_ENTRY_T) )
+ return true;
+
+ if( GetItem( aPosition, std::max( GetDefaultLineThickness(), 3 ), SCH_BUS_BUS_ENTRY_T) )
+ return true;
+
+ if( GetItem( aPosition, std::max( GetDefaultLineThickness(), 3 ), SCH_JUNCTION_T ) )
+ return true;
+
+ if( GetPin( aPosition, NULL, true ) )
+ return true;
+
+ if( GetWire( aPosition ) )
+ return true;
+
+ text = GetLabel( aPosition );
+
+ if( text && text->IsConnected( aPosition ) && !IsBusLabel( text->GetText() ) )
+ return true;
+
+ label = GetSheetLabel( aPosition );
+
+ if( label && label->IsConnected( aPosition ) && !IsBusLabel( label->GetText() ) )
+ return true;
+
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+
+bool SCH_SCREEN::SchematicCleanUp( EDA_DRAW_PANEL* aCanvas, wxDC* aDC )
+{
+ SCH_ITEM* item, * testItem;
+ bool modified = false;
+
+ item = m_drawList.begin();
+
+ for( ; item; item = item->Next() )
+ {
+ if( ( item->Type() != SCH_LINE_T ) && ( item->Type() != SCH_JUNCTION_T ) )
+ continue;
+
+ testItem = item->Next();
+
+ while( testItem )
+ {
+ if( ( item->Type() == SCH_LINE_T ) && ( testItem->Type() == SCH_LINE_T ) )
+ {
+ SCH_LINE* line = (SCH_LINE*) item;
+
+ if( line->MergeOverlap( (SCH_LINE*) testItem ) )
+ {
+ // Keep the current flags, because the deleted segment can be flagged.
+ item->SetFlags( testItem->GetFlags() );
+ DeleteItem( testItem );
+ testItem = m_drawList.begin();
+ modified = true;
+ }
+ else
+ {
+ testItem = testItem->Next();
+ }
+ }
+ else if ( ( ( item->Type() == SCH_JUNCTION_T ) && ( testItem->Type() == SCH_JUNCTION_T ) ) && ( testItem != item ) )
+ {
+ if ( testItem->HitTest( item->GetPosition() ) )
+ {
+ // Keep the current flags, because the deleted segment can be flagged.
+ item->SetFlags( testItem->GetFlags() );
+ DeleteItem( testItem );
+ testItem = m_drawList.begin();
+ modified = true;
+ }
+ else
+ {
+ testItem = testItem->Next();
+ }
+ }
+ else
+ {
+ testItem = testItem->Next();
+ }
+ }
+ }
+
+ TestDanglingEnds( aCanvas, aDC );
+
+ if( aCanvas && modified )
+ aCanvas->Refresh();
+
+ return modified;
+}
+
+
+bool SCH_SCREEN::Save( FILE* aFile ) const
+{
+ // Creates header
+ if( fprintf( aFile, "%s %s %d\n", EESCHEMA_FILE_STAMP,
+ SCHEMATIC_HEAD_STRING, EESCHEMA_VERSION ) < 0 )
+ return false;
+
+ BOOST_FOREACH( const PART_LIB& lib, *Prj().SchLibs() )
+ {
+ if( fprintf( aFile, "LIBS:%s\n", TO_UTF8( lib.GetName() ) ) < 0 )
+ return false;
+ }
+
+ // This section is not used, but written for file compatibility
+ if( fprintf( aFile, "EELAYER %d %d\n", LAYERSCH_ID_COUNT, 0 ) < 0
+ || fprintf( aFile, "EELAYER END\n" ) < 0 )
+ return false;
+
+ /* Write page info, ScreenNumber and NumberOfScreen; not very meaningful for
+ * SheetNumber and Sheet Count in a complex hierarchy, but useful in
+ * simple hierarchy and flat hierarchy. Used also to search the root
+ * sheet ( ScreenNumber = 1 ) within the files
+ */
+ const TITLE_BLOCK& tb = GetTitleBlock();
+
+ if( fprintf( aFile, "$Descr %s %d %d%s\n", TO_UTF8( m_paper.GetType() ),
+ m_paper.GetWidthMils(),
+ m_paper.GetHeightMils(),
+ !m_paper.IsCustom() && m_paper.IsPortrait() ?
+ " portrait" : ""
+ ) < 0
+ || fprintf( aFile, "encoding utf-8\n") < 0
+ || fprintf( aFile, "Sheet %d %d\n", m_ScreenNumber, m_NumberOfScreens ) < 0
+ || fprintf( aFile, "Title %s\n", EscapedUTF8( tb.GetTitle() ).c_str() ) < 0
+ || fprintf( aFile, "Date %s\n", EscapedUTF8( tb.GetDate() ).c_str() ) < 0
+ || fprintf( aFile, "Rev %s\n", EscapedUTF8( tb.GetRevision() ).c_str() ) < 0
+ || fprintf( aFile, "Comp %s\n", EscapedUTF8( tb.GetCompany() ).c_str() ) < 0
+ || fprintf( aFile, "Comment1 %s\n", EscapedUTF8( tb.GetComment1() ).c_str() ) < 0
+ || fprintf( aFile, "Comment2 %s\n", EscapedUTF8( tb.GetComment2() ).c_str() ) < 0
+ || fprintf( aFile, "Comment3 %s\n", EscapedUTF8( tb.GetComment3() ).c_str() ) < 0
+ || fprintf( aFile, "Comment4 %s\n", EscapedUTF8( tb.GetComment4() ).c_str() ) < 0
+ || fprintf( aFile, "$EndDescr\n" ) < 0 )
+ return false;
+
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( !item->Save( aFile ) )
+ return false;
+ }
+
+ if( fprintf( aFile, "$EndSCHEMATC\n" ) < 0 )
+ return false;
+
+ return true;
+}
+
+
+void SCH_SCREEN::CheckComponentsToPartsLinks()
+{
+ // Initialize or reinitialize the pointer to the LIB_PART for each component
+ // found in m_drawList, but only if needed (change in lib or schematic)
+ // therefore the calculation time is usually very low.
+
+ if( m_drawList.GetCount() )
+ {
+ PART_LIBS* libs = Prj().SchLibs();
+ int mod_hash = libs->GetModifyHash();
+
+ // Must we resolve?
+ if( m_modification_sync != mod_hash )
+ {
+ SCH_TYPE_COLLECTOR c;
+
+ c.Collect( GetDrawItems(), SCH_COLLECTOR::ComponentsOnly );
+
+ SCH_COMPONENT::ResolveAll( c, libs );
+
+ m_modification_sync = mod_hash; // note the last mod_hash
+
+ // guard against unneeded runs through this code path by printing trace
+ DBG(printf("%s: resync-ing %s\n", __func__, TO_UTF8( GetFileName() ) );)
+ }
+ }
+}
+
+
+void SCH_SCREEN::Draw( EDA_DRAW_PANEL* aCanvas, wxDC* aDC, GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor )
+{
+ /* note: SCH_SCREEN::Draw is useful only for schematic.
+ * library editor and library viewer do not use m_drawList, and therefore
+ * their SCH_SCREEN::Draw() draws nothing
+ */
+
+ CheckComponentsToPartsLinks();
+
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->IsMoving() || item->IsResized() )
+ continue;
+
+ // uncomment line below when there is a virtual
+ // EDA_ITEM::GetBoundingBox()
+ // if( panel->GetClipBox().Intersects( Structs->GetBoundingBox()
+ // ) )
+ item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), aDrawMode, aColor );
+ }
+}
+
+
+/* note: SCH_SCREEN::Plot is useful only for schematic.
+ * library editor and library viewer do not use a draw list, and therefore
+ * SCH_SCREEN::Plot plots nothing
+ */
+void SCH_SCREEN::Plot( PLOTTER* aPlotter )
+{
+ CheckComponentsToPartsLinks();
+
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ aPlotter->SetCurrentLineWidth( item->GetPenSize() );
+ item->Plot( aPlotter );
+ }
+}
+
+
+void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount )
+{
+ if( aItemCount == 0 )
+ return;
+
+ unsigned icnt = aList.m_CommandsList.size();
+
+ if( aItemCount > 0 )
+ icnt = aItemCount;
+
+ for( unsigned ii = 0; ii < icnt; ii++ )
+ {
+ if( aList.m_CommandsList.size() == 0 )
+ break;
+
+ PICKED_ITEMS_LIST* curr_cmd = aList.m_CommandsList[0];
+ aList.m_CommandsList.erase( aList.m_CommandsList.begin() );
+
+ curr_cmd->ClearListAndDeleteItems();
+ delete curr_cmd; // Delete command
+ }
+}
+
+
+void SCH_SCREEN::ClearDrawingState()
+{
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ item->ClearFlags();
+}
+
+
+LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponent,
+ bool aEndPointOnly ) const
+{
+ SCH_ITEM* item;
+ SCH_COMPONENT* component = NULL;
+ LIB_PIN* pin = NULL;
+
+ for( item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->Type() != SCH_COMPONENT_T )
+ continue;
+
+ component = (SCH_COMPONENT*) item;
+
+ if( aEndPointOnly )
+ {
+ pin = NULL;
+
+ LIB_PART* part = Prj().SchLibs()->FindLibPart( component->GetPartName() );
+
+ if( !part )
+ continue;
+
+ for( pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
+ {
+ // Skip items not used for this part.
+ if( component->GetUnit() && pin->GetUnit() &&
+ ( pin->GetUnit() != component->GetUnit() ) )
+ continue;
+
+ if( component->GetConvert() && pin->GetConvert() &&
+ ( pin->GetConvert() != component->GetConvert() ) )
+ continue;
+
+ if(component->GetPinPhysicalPosition( pin ) == aPosition )
+ break;
+ }
+ if( pin )
+ break;
+ }
+ else
+ {
+ pin = (LIB_PIN*) component->GetDrawItem( aPosition, LIB_PIN_T );
+
+ if( pin )
+ break;
+ }
+ }
+
+ if( pin && aComponent )
+ *aComponent = component;
+
+ return pin;
+}
+
+
+SCH_SHEET* SCH_SCREEN::GetSheet( const wxString& aName )
+{
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->Type() != SCH_SHEET_T )
+ continue;
+
+ SCH_SHEET* sheet = (SCH_SHEET*) item;
+
+ if( aName.CmpNoCase( sheet->GetName() ) == 0 )
+ return sheet;
+ }
+
+ return NULL;
+}
+
+
+SCH_SHEET_PIN* SCH_SCREEN::GetSheetLabel( const wxPoint& aPosition )
+{
+ SCH_SHEET_PIN* sheetPin = NULL;
+
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->Type() != SCH_SHEET_T )
+ continue;
+
+ SCH_SHEET* sheet = (SCH_SHEET*) item;
+ sheetPin = sheet->GetPin( aPosition );
+
+ if( sheetPin )
+ break;
+ }
+
+ return sheetPin;
+}
+
+
+int SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) const
+{
+ SCH_ITEM* item;
+ int count = 0;
+
+ for( item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->Type() == SCH_JUNCTION_T && !aTestJunctions )
+ continue;
+
+ if( item->IsConnected( aPos ) )
+ count++;
+ }
+
+ return count;
+}
+
+
+void SCH_SCREEN::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
+{
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->Type() == SCH_COMPONENT_T )
+ {
+ SCH_COMPONENT* component = (SCH_COMPONENT*) item;
+
+ component->ClearAnnotation( aSheetPath );
+
+ // Clear the modified component flag set by component->ClearAnnotation
+ // because we do not use it here and we should not leave this flag set,
+ // when an edition is finished:
+ component->ClearFlags();
+ }
+ }
+}
+
+
+void SCH_SCREEN::GetHierarchicalItems( EDA_ITEMS& aItems )
+{
+ SCH_ITEM* item = m_drawList.begin();
+
+ while( item )
+ {
+ if( ( item->Type() == SCH_SHEET_T ) || ( item->Type() == SCH_COMPONENT_T ) )
+ aItems.push_back( item );
+
+ item = item->Next();
+ }
+}
+
+
+void SCH_SCREEN::SelectBlockItems()
+{
+ PICKED_ITEMS_LIST* pickedlist = &m_BlockLocate.GetItems();
+
+ if( pickedlist->GetCount() == 0 )
+ return;
+
+ ClearDrawingState();
+
+ for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ )
+ {
+ SCH_ITEM* item = (SCH_ITEM*) pickedlist->GetPickedItem( ii );
+ item->SetFlags( SELECTED );
+ }
+
+ if( !m_BlockLocate.IsDragging() )
+ return;
+
+ // Select all the items in the screen connected to the items in the block.
+ // be sure end lines that are on the block limits are seen inside this block
+ m_BlockLocate.Inflate( 1 );
+ unsigned last_select_id = pickedlist->GetCount();
+
+ for( unsigned ii = 0; ii < last_select_id; ii++ )
+ {
+ SCH_ITEM* item = (SCH_ITEM*)pickedlist->GetPickedItem( ii );
+ item->SetFlags( IS_DRAGGED );
+
+ if( item->Type() == SCH_LINE_T )
+ {
+ item->IsSelectStateChanged( m_BlockLocate );
+
+ if( !item->IsSelected() )
+ { // This is a special case:
+ // this selected wire has no ends in block.
+ // But it was selected (because it intersects the selecting area),
+ // so we must keep it selected and select items connected to it
+ // Note: an other option could be: remove it from drag list
+ item->SetFlags( SELECTED | SKIP_STRUCT );
+ std::vector< wxPoint > connections;
+ item->GetConnectionPoints( connections );
+
+ for( size_t i = 0; i < connections.size(); i++ )
+ addConnectedItemsToBlock( connections[i] );
+ }
+
+ pickedlist->SetPickerFlags( item->GetFlags(), ii );
+ }
+ else if( item->IsConnectable() )
+ {
+ std::vector< wxPoint > connections;
+
+ item->GetConnectionPoints( connections );
+
+ for( size_t jj = 0; jj < connections.size(); jj++ )
+ addConnectedItemsToBlock( connections[jj] );
+ }
+ }
+
+ m_BlockLocate.Inflate( -1 );
+}
+
+
+void SCH_SCREEN::addConnectedItemsToBlock( const wxPoint& position )
+{
+ SCH_ITEM* item;
+ ITEM_PICKER picker;
+ bool addinlist = true;
+
+ for( item = m_drawList.begin(); item; item = item->Next() )
+ {
+ picker.SetItem( item );
+
+ if( !item->IsConnectable() || !item->IsConnected( position )
+ || (item->GetFlags() & SKIP_STRUCT) )
+ continue;
+
+ if( item->IsSelected() && item->Type() != SCH_LINE_T )
+ continue;
+
+ // A line having 2 ends, it can be tested twice: one time per end
+ if( item->Type() == SCH_LINE_T )
+ {
+ if( ! item->IsSelected() ) // First time this line is tested
+ item->SetFlags( SELECTED | STARTPOINT | ENDPOINT );
+ else // second time (or more) this line is tested
+ addinlist = false;
+
+ SCH_LINE* line = (SCH_LINE*) item;
+
+ if( line->GetStartPoint() == position )
+ item->ClearFlags( STARTPOINT );
+ else if( line->GetEndPoint() == position )
+ item->ClearFlags( ENDPOINT );
+ }
+ else
+ item->SetFlags( SELECTED );
+
+ if( addinlist )
+ {
+ picker.SetFlags( item->GetFlags() );
+ m_BlockLocate.GetItems().PushItem( picker );
+ }
+ }
+}
+
+
+int SCH_SCREEN::UpdatePickList()
+{
+ ITEM_PICKER picker;
+ EDA_RECT area;
+ unsigned count;
+
+ area.SetOrigin( m_BlockLocate.GetOrigin() );
+ area.SetSize( m_BlockLocate.GetSize() );
+ area.Normalize();
+
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ // An item is picked if its bounding box intersects the reference area.
+ if( item->HitTest( area ) )
+ {
+ picker.SetItem( item );
+ m_BlockLocate.PushItem( picker );
+ }
+ }
+
+ // if the block is composed of one item,
+ // select it as the current item
+ count = m_BlockLocate.GetCount();
+ if( count == 1 )
+ {
+ SetCurItem( (SCH_ITEM*) m_BlockLocate.GetItem( 0 ) );
+ }
+ else
+ {
+ SetCurItem( NULL );
+ }
+
+ return count;
+}
+
+
+bool SCH_SCREEN::TestDanglingEnds( EDA_DRAW_PANEL* aCanvas, wxDC* aDC )
+{
+ SCH_ITEM* item;
+ std::vector< DANGLING_END_ITEM > endPoints;
+ bool hasDanglingEnds = false;
+
+ for( item = m_drawList.begin(); item; item = item->Next() )
+ item->GetEndPoints( endPoints );
+
+ for( item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->IsDanglingStateChanged( endPoints ) && ( aCanvas ) && ( aDC ) )
+ {
+ item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), g_XorMode );
+ item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+ }
+
+ if( item->IsDangling() )
+ hasDanglingEnds = true;
+ }
+
+ return hasDanglingEnds;
+}
+
+
+bool SCH_SCREEN::BreakSegment( const wxPoint& aPoint )
+{
+ SCH_LINE* segment;
+ SCH_LINE* newSegment;
+ bool brokenSegments = false;
+
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( (item->Type() != SCH_LINE_T) || (item->GetLayer() == LAYER_NOTES) )
+ continue;
+
+ segment = (SCH_LINE*) item;
+
+ if( !segment->HitTest( aPoint, 0 ) || segment->IsEndPoint( aPoint ) )
+ continue;
+
+ // Break the segment at aPoint and create a new segment.
+ newSegment = new SCH_LINE( *segment );
+ newSegment->SetStartPoint( aPoint );
+ segment->SetEndPoint( aPoint );
+ m_drawList.Insert( newSegment, segment->Next() );
+ item = newSegment;
+ brokenSegments = true;
+ }
+
+ return brokenSegments;
+}
+
+
+bool SCH_SCREEN::BreakSegmentsOnJunctions()
+{
+ bool brokenSegments = false;
+
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->Type() == SCH_JUNCTION_T )
+ {
+ SCH_JUNCTION* junction = ( SCH_JUNCTION* ) item;
+
+ if( BreakSegment( junction->GetPosition() ) )
+ brokenSegments = true;
+ }
+ else
+ {
+ SCH_BUS_ENTRY_BASE* busEntry = dynamic_cast<SCH_BUS_ENTRY_BASE*>( item );
+ if( busEntry )
+ {
+ if( BreakSegment( busEntry->GetPosition() )
+ || BreakSegment( busEntry->m_End() ) )
+ brokenSegments = true;
+ }
+ }
+ }
+
+ return brokenSegments;
+}
+
+
+int SCH_SCREEN::GetNode( const wxPoint& aPosition, EDA_ITEMS& aList )
+{
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->Type() == SCH_LINE_T && item->HitTest( aPosition )
+ && (item->GetLayer() == LAYER_BUS || item->GetLayer() == LAYER_WIRE) )
+ {
+ aList.push_back( item );
+ }
+ else if( item->Type() == SCH_JUNCTION_T && item->HitTest( aPosition ) )
+ {
+ aList.push_back( item );
+ }
+ }
+
+ return (int) aList.size();
+}
+
+
+SCH_LINE* SCH_SCREEN::GetWireOrBus( const wxPoint& aPosition )
+{
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( (item->Type() == SCH_LINE_T) && item->HitTest( aPosition )
+ && (item->GetLayer() == LAYER_BUS || item->GetLayer() == LAYER_WIRE) )
+ {
+ return (SCH_LINE*) item;
+ }
+ }
+
+ return NULL;
+}
+
+
+SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer,
+ SCH_LINE_TEST_T aSearchType )
+{
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->Type() != SCH_LINE_T )
+ continue;
+
+ if( item->GetLayer() != aLayer )
+ continue;
+
+ if( !item->HitTest( aPosition, aAccuracy ) )
+ continue;
+
+ switch( aSearchType )
+ {
+ case ENTIRE_LENGTH_T:
+ return (SCH_LINE*) item;
+
+ case EXCLUDE_END_POINTS_T:
+ if( !( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
+ return (SCH_LINE*) item;
+ break;
+
+ case END_POINTS_ONLY_T:
+ if( ( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
+ return (SCH_LINE*) item;
+ }
+ }
+
+ return NULL;
+}
+
+
+SCH_TEXT* SCH_SCREEN::GetLabel( const wxPoint& aPosition, int aAccuracy )
+{
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case SCH_LABEL_T:
+ case SCH_GLOBAL_LABEL_T:
+ case SCH_HIERARCHICAL_LABEL_T:
+ if( item->HitTest( aPosition, aAccuracy ) )
+ return (SCH_TEXT*) item;
+
+ default:
+ ;
+ }
+ }
+
+ return NULL;
+}
+
+
+bool SCH_SCREEN::SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxString& aReference,
+ const wxString& aFootPrint, bool aSetVisible )
+{
+ SCH_COMPONENT* component;
+ bool found = false;
+
+ for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->Type() != SCH_COMPONENT_T )
+ continue;
+
+ component = (SCH_COMPONENT*) item;
+
+ if( aReference.CmpNoCase( component->GetRef( aSheetPath ) ) == 0 )
+ {
+ // Found: Init Footprint Field
+
+ /* Give a reasonable value to the field position and
+ * orientation, if the text is empty at position 0, because
+ * it is probably not yet initialized
+ */
+ SCH_FIELD * fpfield = component->GetField( FOOTPRINT );
+ if( fpfield->GetText().IsEmpty()
+ && ( fpfield->GetTextPosition() == component->GetPosition() ) )
+ {
+ fpfield->SetOrientation( component->GetField( VALUE )->GetOrientation() );
+ fpfield->SetTextPosition( component->GetField( VALUE )->GetTextPosition() );
+ fpfield->SetSize( component->GetField( VALUE )->GetSize() );
+
+ if( fpfield->GetOrientation() == 0 )
+ fpfield->Offset( wxPoint( 0, 100 ) );
+ else
+ fpfield->Offset( wxPoint( 100, 0 ) );
+ }
+
+ fpfield->SetText( aFootPrint );
+ fpfield->SetVisible( aSetVisible );
+
+ found = true;
+ }
+ }
+
+ return found;
+}
+
+
+int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aList,
+ bool aFullConnection )
+{
+ SCH_ITEM* item;
+ EDA_ITEM* tmp;
+ EDA_ITEMS list;
+
+ // Clear flags member for all items.
+ ClearDrawingState();
+ BreakSegmentsOnJunctions();
+
+ if( GetNode( aPosition, list ) == 0 )
+ return 0;
+
+ for( size_t i = 0; i < list.size(); i++ )
+ {
+ item = (SCH_ITEM*) list[ i ];
+ item->SetFlags( SELECTEDNODE | STRUCT_DELETED );
+
+ /* Put this structure in the picked list: */
+ ITEM_PICKER picker( item, UR_DELETED );
+ aList.PushItem( picker );
+ }
+
+ // Mark all wires, junctions, .. connected to the item(s) found.
+ if( aFullConnection )
+ {
+ SCH_LINE* segment;
+
+ for( item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( !(item->GetFlags() & SELECTEDNODE) )
+ continue;
+
+ if( item->Type() != SCH_LINE_T )
+ continue;
+
+ MarkConnections( (SCH_LINE*) item );
+ }
+
+ // Search all attached wires (i.e wire with one new dangling end )
+ for( item = m_drawList.begin(); item; item = item->Next() )
+ {
+ bool noconnect = false;
+
+ if( item->GetFlags() & STRUCT_DELETED )
+ continue; // Already seen
+
+ if( !(item->GetFlags() & CANDIDATE) )
+ continue; // not a candidate
+
+ if( item->Type() != SCH_LINE_T )
+ continue;
+
+ item->SetFlags( SKIP_STRUCT );
+
+ segment = (SCH_LINE*) item;
+
+ /* If the wire start point is connected to a wire that was already found
+ * and now is not connected, add the wire to the list. */
+ for( tmp = m_drawList.begin(); tmp; tmp = tmp->Next() )
+ {
+ // Ensure tmp is a previously deleted segment:
+ if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 )
+ continue;
+
+ if( tmp->Type() != SCH_LINE_T )
+ continue;
+
+ SCH_LINE* testSegment = (SCH_LINE*) tmp;
+
+ // Test for segment connected to the previously deleted segment:
+ if( testSegment->IsEndPoint( segment->GetStartPoint() ) )
+ break;
+ }
+
+ // when tmp != NULL, segment is a new candidate:
+ // put it in deleted list if
+ // the start point is not connected to an other item (like pin)
+ if( tmp && !CountConnectedItems( segment->GetStartPoint(), true ) )
+ noconnect = true;
+
+ /* If the wire end point is connected to a wire that has already been found
+ * and now is not connected, add the wire to the list. */
+ for( tmp = m_drawList.begin(); tmp; tmp = tmp->Next() )
+ {
+ // Ensure tmp is a previously deleted segment:
+ if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 )
+ continue;
+
+ if( tmp->Type() != SCH_LINE_T )
+ continue;
+
+ SCH_LINE* testSegment = (SCH_LINE*) tmp;
+
+ // Test for segment connected to the previously deleted segment:
+ if( testSegment->IsEndPoint( segment->GetEndPoint() ) )
+ break;
+ }
+
+ // when tmp != NULL, segment is a new candidate:
+ // put it in deleted list if
+ // the end point is not connected to an other item (like pin)
+ if( tmp && !CountConnectedItems( segment->GetEndPoint(), true ) )
+ noconnect = true;
+
+ item->ClearFlags( SKIP_STRUCT );
+
+ if( noconnect )
+ {
+ item->SetFlags( STRUCT_DELETED );
+
+ ITEM_PICKER picker( item, UR_DELETED );
+ aList.PushItem( picker );
+
+ item = m_drawList.begin();
+ }
+ }
+
+ // Get redundant junctions (junctions which connect < 3 end wires
+ // and no pin)
+ for( item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->GetFlags() & STRUCT_DELETED )
+ continue;
+
+ if( !(item->GetFlags() & CANDIDATE) )
+ continue;
+
+ if( item->Type() != SCH_JUNCTION_T )
+ continue;
+
+ SCH_JUNCTION* junction = (SCH_JUNCTION*) item;
+
+ if( CountConnectedItems( junction->GetPosition(), false ) <= 2 )
+ {
+ item->SetFlags( STRUCT_DELETED );
+
+ ITEM_PICKER picker( item, UR_DELETED );
+ aList.PushItem( picker );
+ }
+ }
+
+ for( item = m_drawList.begin(); item; item = item->Next() )
+ {
+ if( item->GetFlags() & STRUCT_DELETED )
+ continue;
+
+ if( item->Type() != SCH_LABEL_T )
+ continue;
+
+ tmp = GetWireOrBus( ( (SCH_TEXT*) item )->GetPosition() );
+
+ if( tmp && tmp->GetFlags() & STRUCT_DELETED )
+ {
+ item->SetFlags( STRUCT_DELETED );
+
+ ITEM_PICKER picker( item, UR_DELETED );
+ aList.PushItem( picker );
+ }
+ }
+ }
+
+ ClearDrawingState();
+
+ return aList.GetCount();
+}
+
+
+/******************************************************************/
+/* Class SCH_SCREENS to handle the list of screens in a hierarchy */
+/******************************************************************/
+
+/**
+ * Function SortByTimeStamp
+ * sorts a list of schematic items by time stamp and type.
+ */
+static bool SortByTimeStamp( const EDA_ITEM* item1, const EDA_ITEM* item2 )
+{
+ int ii = item1->GetTimeStamp() - item2->GetTimeStamp();
+
+ /* If the time stamps are the same, compare type in order to have component objects
+ * before sheet object. This is done because changing the sheet time stamp
+ * before the component time stamp could cause the current annotation to be lost.
+ */
+ if( ( ii == 0 && ( item1->Type() != item2->Type() ) ) && ( item1->Type() == SCH_SHEET_T ) )
+ ii = -1;
+
+ return ii < 0;
+}
+
+
+SCH_SCREENS::SCH_SCREENS()
+{
+ m_index = 0;
+ BuildScreenList( g_RootSheet );
+}
+
+
+SCH_SCREENS::~SCH_SCREENS()
+{
+}
+
+
+SCH_SCREEN* SCH_SCREENS::GetFirst()
+{
+ m_index = 0;
+
+ if( m_screens.size() > 0 )
+ return m_screens[0];
+
+ return NULL;
+}
+
+
+SCH_SCREEN* SCH_SCREENS::GetNext()
+{
+ if( m_index < m_screens.size() )
+ m_index++;
+
+ return GetScreen( m_index );
+}
+
+
+SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const
+{
+ if( aIndex < m_screens.size() )
+ return m_screens[ aIndex ];
+
+ return NULL;
+}
+
+
+void SCH_SCREENS::AddScreenToList( SCH_SCREEN* aScreen )
+{
+ if( aScreen == NULL )
+ return;
+
+ for( unsigned int i = 0; i < m_screens.size(); i++ )
+ {
+ if( m_screens[i] == aScreen )
+ return;
+ }
+
+ m_screens.push_back( aScreen );
+}
+
+
+void SCH_SCREENS::BuildScreenList( EDA_ITEM* aItem )
+{
+ if( aItem && aItem->Type() == SCH_SHEET_T )
+ {
+ SCH_SHEET* ds = (SCH_SHEET*) aItem;
+ aItem = ds->GetScreen();
+ }
+
+ if( aItem && aItem->Type() == SCH_SCREEN_T )
+ {
+ SCH_SCREEN* screen = (SCH_SCREEN*) aItem;
+
+ // Ensure each component has its pointer to its part lib LIB_PART
+ // up to date (the cost is low if this is the case)
+ // We do this update here, because most of time this function is called
+ // to create a netlist, or an ERC, which need this update
+ screen->CheckComponentsToPartsLinks();
+
+ AddScreenToList( screen );
+ EDA_ITEM* strct = screen->GetDrawItems();
+
+ while( strct )
+ {
+ if( strct->Type() == SCH_SHEET_T )
+ {
+ BuildScreenList( strct );
+ }
+
+ strct = strct->Next();
+ }
+ }
+}
+
+
+void SCH_SCREENS::ClearAnnotation()
+{
+ for( size_t i = 0; i < m_screens.size(); i++ )
+ m_screens[i]->ClearAnnotation( NULL );
+}
+
+
+void SCH_SCREENS::SchematicCleanUp()
+{
+ for( size_t i = 0; i < m_screens.size(); i++ )
+ {
+ // if wire list has changed, delete the undo/redo list to avoid
+ // pointer problems with deleted data.
+ if( m_screens[i]->SchematicCleanUp() )
+ m_screens[i]->ClearUndoRedoList();
+ }
+}
+
+
+int SCH_SCREENS::ReplaceDuplicateTimeStamps()
+{
+ EDA_ITEMS items;
+ SCH_ITEM* item;
+
+ for( size_t i = 0; i < m_screens.size(); i++ )
+ m_screens[i]->GetHierarchicalItems( items );
+
+ if( items.size() < 2 )
+ return 0;
+
+ sort( items.begin(), items.end(), SortByTimeStamp );
+
+ int count = 0;
+
+ for( size_t ii = 0; ii < items.size() - 1; ii++ )
+ {
+ item = (SCH_ITEM*)items[ii];
+
+ SCH_ITEM* nextItem = (SCH_ITEM*)items[ii + 1];
+
+ if( item->GetTimeStamp() == nextItem->GetTimeStamp() )
+ {
+ count++;
+
+ // for a component, update its Time stamp and its paths
+ // (m_PathsAndReferences field)
+ if( item->Type() == SCH_COMPONENT_T )
+ ( (SCH_COMPONENT*) item )->SetTimeStamp( GetNewTimeStamp() );
+
+ // for a sheet, update only its time stamp (annotation of its
+ // components will be lost)
+ // @todo: see how to change sheet paths for its cmp list (can
+ // be possible in most cases)
+ else
+ item->SetTimeStamp( GetNewTimeStamp() );
+ }
+ }
+
+ return count;
+}
+
+
+void SCH_SCREENS::DeleteAllMarkers( enum MARKER_BASE::TYPEMARKER aMarkerType )
+{
+ SCH_ITEM* item;
+ SCH_ITEM* nextItem;
+ SCH_MARKER* marker;
+ SCH_SCREEN* screen;
+
+ for( screen = GetFirst(); screen; screen = GetNext() )
+ {
+ for( item = screen->GetDrawItems(); item; item = nextItem )
+ {
+ nextItem = item->Next();
+
+ if( item->Type() != SCH_MARKER_T )
+ continue;
+
+ marker = (SCH_MARKER*) item;
+
+ if( marker->GetMarkerType() != aMarkerType )
+ continue;
+
+ screen->DeleteItem( marker );
+ }
+ }
+}
+
+
+int SCH_SCREENS::GetMarkerCount( enum MARKER_BASE::TYPEMARKER aMarkerType,
+ enum MARKER_BASE::MARKER_SEVERITY aSeverity )
+{
+ int count = 0;
+
+ for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
+ {
+ for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
+ {
+ if( item->Type() != SCH_MARKER_T )
+ continue;
+
+ SCH_MARKER* marker = (SCH_MARKER*) item;
+
+ if( ( aMarkerType != MARKER_BASE::MARKER_UNSPEC ) &&
+ ( marker->GetMarkerType() != aMarkerType ) )
+ continue;
+
+ if( aSeverity == MARKER_BASE::MARKER_SEVERITY_UNSPEC ||
+ aSeverity == marker->GetErrorLevel() )
+ count++;
+ }
+ }
+
+ return count;
+}
+
+#if defined(DEBUG)
+void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
+{
+ // for now, make it look like XML, expand on this later.
+ NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
+
+ for( EDA_ITEM* item = m_drawList.begin(); item; item = item->Next() )
+ {
+ item->Show( nestLevel+1, os );
+ }
+
+ NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
+}
+#endif
diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp
new file mode 100644
index 0000000..0a03994
--- /dev/null
+++ b/eeschema/sch_sheet.cpp
@@ -0,0 +1,1236 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2011 Kicad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_sheet.cpp
+ * @brief Implementation of SCH_SHEET class.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <drawtxt.h>
+#include <trigo.h>
+#include <richio.h>
+#include <schframe.h>
+#include <plot_common.h>
+#include <kicad_string.h>
+#include <msgpanel.h>
+
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+#include <sch_component.h>
+#include <class_netlist_object.h>
+
+
+SCH_SHEET::SCH_SHEET( const wxPoint& pos ) :
+ SCH_ITEM( NULL, SCH_SHEET_T )
+{
+ m_Layer = LAYER_SHEET;
+ m_pos = pos;
+ m_size = wxSize( MIN_SHEET_WIDTH, MIN_SHEET_HEIGHT );
+ SetTimeStamp( GetNewTimeStamp() );
+ m_sheetNameSize = GetDefaultTextSize();
+ m_fileNameSize = GetDefaultTextSize();
+ m_screen = NULL;
+ m_name.Printf( wxT( "Sheet%8.8lX" ), (long) m_TimeStamp );
+ m_fileName.Printf( wxT( "file%8.8lX.sch" ), (long) m_TimeStamp );
+}
+
+
+SCH_SHEET::SCH_SHEET( const SCH_SHEET& aSheet ) :
+ SCH_ITEM( aSheet )
+{
+ m_pos = aSheet.m_pos;
+ m_size = aSheet.m_size;
+ m_Layer = aSheet.m_Layer;
+ SetTimeStamp( aSheet.m_TimeStamp );
+ m_sheetNameSize = aSheet.m_sheetNameSize;
+ m_fileNameSize = aSheet.m_fileNameSize;
+ m_screen = aSheet.m_screen;
+ m_name = aSheet.m_name;
+ m_fileName = aSheet.m_fileName;
+ m_pins = aSheet.m_pins;
+
+ for( size_t i = 0; i < m_pins.size(); i++ )
+ m_pins[i].SetParent( this );
+
+ if( m_screen )
+ m_screen->IncRefCount();
+}
+
+
+SCH_SHEET::~SCH_SHEET()
+{
+// wxLogDebug( wxT( "Destroying sheet " ) + m_name );
+
+ // also, look at the associated sheet & its reference count
+ // perhaps it should be deleted also.
+ if( m_screen )
+ {
+ m_screen->DecRefCount();
+
+ if( m_screen->GetRefCount() == 0 )
+ delete m_screen;
+ }
+}
+
+
+EDA_ITEM* SCH_SHEET::Clone() const
+{
+ return new SCH_SHEET( *this );
+}
+
+
+void SCH_SHEET::SetScreen( SCH_SCREEN* aScreen )
+{
+ if( aScreen == m_screen )
+ return;
+
+ if( m_screen != NULL )
+ {
+ m_screen->DecRefCount();
+
+ if( m_screen->GetRefCount() == 0 )
+ {
+ delete m_screen;
+ m_screen = NULL;
+ }
+ }
+
+ m_screen = aScreen;
+
+ if( m_screen )
+ m_screen->IncRefCount();
+}
+
+
+int SCH_SHEET::GetScreenCount() const
+{
+ if( m_screen == NULL )
+ return 0;
+
+ return m_screen->GetRefCount();
+}
+
+
+bool SCH_SHEET::Save( FILE* aFile ) const
+{
+ if( fprintf( aFile, "$Sheet\n" ) == EOF
+ || fprintf( aFile, "S %-4d %-4d %-4d %-4d\n",
+ m_pos.x, m_pos.y, m_size.x, m_size.y ) == EOF )
+ return false;
+
+ //save the unique timestamp, like other schematic parts.
+ if( fprintf( aFile, "U %8.8lX\n", m_TimeStamp ) == EOF )
+ return false;
+
+ /* Save schematic sheetname and filename. */
+ if( !m_name.IsEmpty() )
+ {
+ if( fprintf( aFile, "F0 %s %d\n", EscapedUTF8( m_name ).c_str(),
+ m_sheetNameSize ) == EOF )
+ return false;
+ }
+
+ if( !m_fileName.IsEmpty() )
+ {
+ if( fprintf( aFile, "F1 %s %d\n", EscapedUTF8( m_fileName ).c_str(),
+ m_fileNameSize ) == EOF )
+ return false;
+ }
+
+ /* Save the list of labels in the sheet. */
+
+ BOOST_FOREACH( const SCH_SHEET_PIN& label, m_pins )
+ {
+ if( !label.Save( aFile ) )
+ return false;
+ }
+
+ if( fprintf( aFile, "$EndSheet\n" ) == EOF )
+ return false;
+
+ return true;
+}
+
+
+bool SCH_SHEET::Load( LINE_READER& aLine, wxString& aErrorMsg )
+{
+ int fieldNdx, size;
+ SCH_SHEET_PIN* sheetPin;
+ char* ptcar;
+
+ SetTimeStamp( GetNewTimeStamp() );
+
+ // sheets are added to the GetDrawItems() like other schematic components.
+ // however, in order to preserve the hierarchy (through m_Parent pointers),
+ // a duplicate of the sheet is added to m_SubSheet array.
+ // must be a duplicate, references just work for a two-layer structure.
+ // this is accomplished through the Sync() function.
+
+ if( ((char*)aLine)[0] == '$' ) // line should be "$Sheet"
+ {
+ if( !aLine.ReadLine() )
+ {
+ aErrorMsg.Printf( wxT( "Read File Error" ) );
+ return false;
+ }
+ }
+
+ /* Next line: must be "S xx yy nn mm" with xx, yy = sheet position
+ * ( upper left corner ) et nn,mm = sheet size */
+ if( ( sscanf( &((char*)aLine)[1], "%d %d %d %d",
+ &m_pos.x, &m_pos.y, &m_size.x, &m_size.y ) != 4 )
+ || ( ((char*)aLine)[0] != 'S' ) )
+ {
+ aErrorMsg.Printf( wxT( " ** Eeschema file sheet struct error at line %d, aborted\n" ),
+ aLine.LineNumber() );
+
+ aErrorMsg << FROM_UTF8( ((char*)aLine) );
+ return false;
+ }
+
+ /* Read fields */
+ for( ; ; ) /* Analysis of lines "Fn" text. */
+ {
+ if( !aLine.ReadLine() )
+ return false;
+
+ if( ((char*)aLine)[0] == 'U' )
+ {
+ sscanf( ((char*)aLine) + 1, "%lX", &m_TimeStamp );
+ if( m_TimeStamp == 0 ) // zero is not unique!
+ SetTimeStamp( GetNewTimeStamp() );
+ continue;
+ }
+
+ if( ((char*)aLine)[0] != 'F' )
+ break;
+
+ sscanf( ((char*)aLine) + 1, "%d", &fieldNdx );
+
+ /* Read the field:
+ * If fieldNdx> = 2: Fn "text" t s posx posy
+ * If F0 "text" for SheetName
+ * F1 and "text" for filename
+ */
+ ptcar = ((char*)aLine);
+
+ while( *ptcar && ( *ptcar != '"' ) )
+ ptcar++;
+
+ if( *ptcar != '"' )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file sheet label F%d at line %d, aborted\n" ),
+ fieldNdx, aLine.LineNumber() );
+ aErrorMsg << FROM_UTF8( (char*) aLine );
+ return false;
+ }
+
+ wxString sheetName;
+ ptcar += ReadDelimitedText( &sheetName, ptcar );
+
+ if( *ptcar == 0 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file sheet field F at line %d, aborted\n" ),
+ aLine.LineNumber() );
+ aErrorMsg << FROM_UTF8( (char*) aLine );
+ return false;
+ }
+
+ if( ( fieldNdx == 0 ) || ( fieldNdx == 1 ) )
+ {
+ if( sscanf( ptcar, "%d", &size ) != 1 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file sheet Label error line %d, aborted\n" ),
+ aLine.LineNumber() );
+
+ aErrorMsg << FROM_UTF8( (char*) aLine );
+ }
+
+ if( size == 0 )
+ size = GetDefaultTextSize();
+
+ if( fieldNdx == 0 )
+ {
+ m_name = sheetName;
+ m_sheetNameSize = size;
+ }
+ else
+ {
+ SetFileName( sheetName );
+ m_fileNameSize = size;
+ }
+ }
+
+ if( fieldNdx > 1 )
+ {
+ sheetPin = new SCH_SHEET_PIN( this );
+
+ if( !sheetPin->Load( aLine, aErrorMsg ) )
+ {
+ delete sheetPin;
+ sheetPin = NULL;
+ return false;
+ }
+
+ AddPin( sheetPin );
+ }
+ }
+
+ if( strnicmp( "$End", ((char*)aLine), 4 ) != 0 )
+ {
+ aErrorMsg.Printf( wxT( "**Eeschema file end_sheet struct error at line %d, aborted\n" ),
+ aLine.LineNumber() );
+ aErrorMsg << FROM_UTF8( ((char*)aLine) );
+ return false;
+ }
+
+ return true;
+}
+
+
+void SCH_SHEET::SwapData( SCH_ITEM* aItem )
+{
+ wxCHECK_RET( aItem->Type() == SCH_SHEET_T,
+ wxString::Format( wxT( "SCH_SHEET object cannot swap data with %s object." ),
+ GetChars( aItem->GetClass() ) ) );
+
+ SCH_SHEET* sheet = ( SCH_SHEET* ) aItem;
+
+ std::swap( m_pos, sheet->m_pos );
+ std::swap( m_size, sheet->m_size );
+ std::swap( m_name, sheet->m_name );
+ std::swap( m_sheetNameSize, sheet->m_sheetNameSize );
+ std::swap( m_fileNameSize, sheet->m_fileNameSize );
+ m_pins.swap( sheet->m_pins );
+
+ // Ensure sheet labels have their .m_Parent member pointing really on their
+ // parent, after swapping.
+ BOOST_FOREACH( SCH_SHEET_PIN& sheetPin, m_pins )
+ {
+ sheetPin.SetParent( this );
+ }
+
+ BOOST_FOREACH( SCH_SHEET_PIN& sheetPin, sheet->m_pins )
+ {
+ sheetPin.SetParent( sheet );
+ }
+}
+
+
+void SCH_SHEET::AddPin( SCH_SHEET_PIN* aSheetPin )
+{
+ wxASSERT( aSheetPin != NULL );
+ wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
+
+ m_pins.push_back( aSheetPin );
+ renumberPins();
+}
+
+
+void SCH_SHEET::RemovePin( SCH_SHEET_PIN* aSheetPin )
+{
+ wxASSERT( aSheetPin != NULL );
+ wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
+
+ SCH_SHEET_PINS::iterator i;
+
+ for( i = m_pins.begin(); i < m_pins.end(); ++i )
+ {
+ if( *i == aSheetPin )
+ {
+ m_pins.erase( i );
+ renumberPins();
+ return;
+ }
+ }
+
+ wxLogDebug( wxT( "Fix me: attempt to remove label %s which is not in sheet %s." ),
+ GetChars( aSheetPin->GetShownText() ), GetChars( m_name ) );
+}
+
+
+bool SCH_SHEET::HasPin( const wxString& aName )
+{
+ BOOST_FOREACH( SCH_SHEET_PIN pin, m_pins )
+ {
+ if( pin.GetText().CmpNoCase( aName ) == 0 )
+ return true;
+ }
+
+ return false;
+}
+
+
+bool SCH_SHEET::IsVerticalOrientation() const
+{
+ BOOST_FOREACH( SCH_SHEET_PIN pin, m_pins )
+ {
+ if( pin.GetEdge() > 1 )
+ return true;
+ }
+ return false;
+}
+
+
+bool SCH_SHEET::HasUndefinedPins()
+{
+ BOOST_FOREACH( SCH_SHEET_PIN pin, m_pins )
+ {
+ /* Search the schematic for a hierarchical label corresponding to this sheet label. */
+ EDA_ITEM* DrawStruct = m_screen->GetDrawItems();
+ const SCH_HIERLABEL* HLabel = NULL;
+
+ for( ; DrawStruct != NULL; DrawStruct = DrawStruct->Next() )
+ {
+ if( DrawStruct->Type() != SCH_HIERARCHICAL_LABEL_T )
+ continue;
+
+ HLabel = static_cast<SCH_HIERLABEL*>( DrawStruct );
+
+ if( pin.GetText().CmpNoCase( HLabel->GetText() ) == 0 )
+ break; // Found!
+
+ HLabel = NULL;
+ }
+
+ if( HLabel == NULL ) // Corresponding hierarchical label not found.
+ return true;
+ }
+
+ return false;
+}
+
+
+int SCH_SHEET::GetMinWidth() const
+{
+ int width = MIN_SHEET_WIDTH;
+
+ for( size_t i = 0; i < m_pins.size(); i++ )
+ {
+ int edge = m_pins[i].GetEdge();
+
+ // Make sure pin is on right or left side of sheet.
+ if( edge >= 2 )
+ continue;
+
+ EDA_RECT rect = m_pins[i].GetBoundingBox();
+
+ if( width < rect.GetWidth() )
+ width = rect.GetWidth();
+
+ for( size_t j = 0; j < m_pins.size(); j++ )
+ {
+ if( (i == j) || (m_pins[i].GetPosition().y != m_pins[j].GetPosition().y) )
+ continue;
+
+ if( width < rect.GetWidth() + m_pins[j].GetBoundingBox().GetWidth() )
+ {
+ width = rect.GetWidth() + m_pins[j].GetBoundingBox().GetWidth();
+ break;
+ }
+ }
+ }
+
+ return width;
+}
+
+
+int SCH_SHEET::GetMinHeight() const
+{
+ int height = MIN_SHEET_HEIGHT;
+
+ for( size_t i = 0; i < m_pins.size(); i++ )
+ {
+ int pinY = m_pins[i].GetPosition().y - m_pos.y;
+
+ if( pinY > height )
+ height = pinY;
+ }
+
+ return height;
+}
+
+
+/**
+ * Delete sheet labels which do not have corresponding hierarchical label.
+ */
+void SCH_SHEET::CleanupSheet()
+{
+ SCH_SHEET_PINS::iterator i = m_pins.begin();
+
+ while( i != m_pins.end() )
+ {
+ /* Search the schematic for a hierarchical label corresponding to this sheet label. */
+ EDA_ITEM* DrawStruct = m_screen->GetDrawItems();
+ const SCH_HIERLABEL* HLabel = NULL;
+
+ for( ; DrawStruct != NULL; DrawStruct = DrawStruct->Next() )
+ {
+ if( DrawStruct->Type() != SCH_HIERARCHICAL_LABEL_T )
+ continue;
+
+ HLabel = static_cast<SCH_HIERLABEL*>( DrawStruct );
+
+ if( i->GetText().CmpNoCase( HLabel->GetText() ) == 0 )
+ break; // Found!
+
+ HLabel = NULL;
+ }
+
+ if( HLabel == NULL ) // Hlabel not found: delete sheet label.
+ m_pins.erase( i );
+ else
+ ++i;
+ }
+}
+
+
+SCH_SHEET_PIN* SCH_SHEET::GetPin( const wxPoint& aPosition )
+{
+ BOOST_FOREACH( SCH_SHEET_PIN& pin, m_pins )
+ {
+ if( pin.HitTest( aPosition, 0 ) )
+ return &pin;
+ }
+
+ return NULL;
+}
+
+
+int SCH_SHEET::GetPenSize() const
+{
+ return GetDefaultLineThickness();
+}
+
+
+wxPoint SCH_SHEET::GetSheetNamePosition()
+{
+ wxPoint pos = m_pos;
+
+ if( IsVerticalOrientation() )
+ {
+ pos.x -= 8;
+ pos.y += m_size.y;
+ }
+ else
+ {
+ pos.y -= 8;
+ }
+
+ return pos;
+}
+
+
+wxPoint SCH_SHEET::GetFileNamePosition()
+{
+ wxPoint pos = m_pos;
+ int margin = GetPenSize() + 4;
+
+ if( IsVerticalOrientation() )
+ {
+ pos.x += m_size.x + margin;
+ pos.y += m_size.y;
+ }
+ else
+ {
+ pos.y += m_size.y + margin;
+ }
+
+ return pos;
+}
+
+
+void SCH_SHEET::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aOffset, GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor )
+{
+ EDA_COLOR_T txtcolor;
+ wxString Text;
+ EDA_COLOR_T color;
+ int name_orientation;
+ wxPoint pos_sheetname,pos_filename;
+ wxPoint pos = m_pos + aOffset;
+ int lineWidth = GetPenSize();
+ EDA_RECT* clipbox = aPanel? aPanel->GetClipBox() : NULL;
+
+ if( aColor >= 0 )
+ color = aColor;
+ else
+ color = GetLayerColor( m_Layer );
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ GRRect( clipbox, aDC, pos.x, pos.y,
+ pos.x + m_size.x, pos.y + m_size.y, lineWidth, color );
+
+ pos_sheetname = GetSheetNamePosition() + aOffset;
+ pos_filename = GetFileNamePosition() + aOffset;
+
+ if( IsVerticalOrientation() )
+ name_orientation = TEXT_ORIENT_VERT;
+ else
+ name_orientation = TEXT_ORIENT_HORIZ;
+
+ /* Draw text : SheetName */
+ if( aColor > 0 )
+ txtcolor = aColor;
+ else
+ txtcolor = GetLayerColor( LAYER_SHEETNAME );
+
+ Text = wxT( "Sheet: " ) + m_name;
+ DrawGraphicText( clipbox, aDC, pos_sheetname,
+ txtcolor, Text, name_orientation,
+ wxSize( m_sheetNameSize, m_sheetNameSize ),
+ GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_BOTTOM, lineWidth,
+ false, false );
+
+ /* Draw text : FileName */
+ if( aColor >= 0 )
+ txtcolor = aColor;
+ else
+ txtcolor = GetLayerColor( LAYER_SHEETFILENAME );
+
+ Text = wxT( "File: " ) + m_fileName;
+ DrawGraphicText( clipbox, aDC, pos_filename,
+ txtcolor, Text, name_orientation,
+ wxSize( m_fileNameSize, m_fileNameSize ),
+ GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP, lineWidth,
+ false, false );
+
+
+ /* Draw text : SheetLabel */
+ BOOST_FOREACH( SCH_SHEET_PIN& sheetPin, m_pins )
+ {
+ if( !sheetPin.IsMoving() )
+ sheetPin.Draw( aPanel, aDC, aOffset, aDrawMode, aColor );
+ }
+}
+
+
+const EDA_RECT SCH_SHEET::GetBoundingBox() const
+{
+ wxPoint end;
+ EDA_RECT box( m_pos, m_size );
+ int lineWidth = GetPenSize();
+
+ // Determine length of texts
+ wxString text = wxT( "Sheet: " ) + m_name;
+ int textlen = GraphicTextWidth( text, m_sheetNameSize, false, lineWidth );
+ text = wxT( "File: " ) + m_fileName;
+ int textlen2 = GraphicTextWidth( text, m_fileNameSize, false, lineWidth );
+
+ // Calculate bounding box X size:
+ textlen = std::max( textlen, textlen2 );
+ end.x = std::max( m_size.x, textlen );
+
+ // Calculate bounding box pos:
+ end.y = m_size.y;
+ end += m_pos;
+
+ // Move upper and lower limits to include texts:
+ box.SetY( box.GetY() - ( KiROUND( m_sheetNameSize * 1.3 ) + 8 ) );
+ end.y += KiROUND( m_fileNameSize * 1.3 ) + 8;
+
+ box.SetEnd( end );
+ box.Inflate( lineWidth / 2 );
+
+ return box;
+}
+
+
+int SCH_SHEET::ComponentCount()
+{
+ int n = 0;
+
+ if( m_screen )
+ {
+ EDA_ITEM* bs;
+
+ for( bs = m_screen->GetDrawItems(); bs != NULL; bs = bs->Next() )
+ {
+ if( bs->Type() == SCH_COMPONENT_T )
+ {
+ SCH_COMPONENT* Cmp = (SCH_COMPONENT*) bs;
+
+ if( Cmp->GetField( VALUE )->GetText().GetChar( 0 ) != '#' )
+ n++;
+ }
+
+ if( bs->Type() == SCH_SHEET_T )
+ {
+ SCH_SHEET* sheet = (SCH_SHEET*) bs;
+ n += sheet->ComponentCount();
+ }
+ }
+ }
+
+ return n;
+}
+
+
+bool SCH_SHEET::SearchHierarchy( const wxString& aFilename, SCH_SCREEN** aScreen )
+{
+ if( m_screen )
+ {
+ EDA_ITEM* item = m_screen->GetDrawItems();
+
+ while( item )
+ {
+ if( item->Type() == SCH_SHEET_T )
+ {
+ SCH_SHEET* sheet = (SCH_SHEET*) item;
+
+ if( sheet->m_screen
+ && sheet->m_screen->GetFileName().CmpNoCase( aFilename ) == 0 )
+ {
+ *aScreen = sheet->m_screen;
+ return true;
+ }
+
+ if( sheet->SearchHierarchy( aFilename, aScreen ) )
+ return true;
+ }
+
+ item = item->Next();
+ }
+ }
+
+ return false;
+}
+
+
+bool SCH_SHEET::LocatePathOfScreen( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aList )
+{
+ if( m_screen )
+ {
+ aList->Push( this );
+
+ if( m_screen == aScreen )
+ return true;
+
+ EDA_ITEM* strct = m_screen->GetDrawItems();
+
+ while( strct )
+ {
+ if( strct->Type() == SCH_SHEET_T )
+ {
+ SCH_SHEET* ss = (SCH_SHEET*) strct;
+
+ if( ss->LocatePathOfScreen( aScreen, aList ) )
+ return true;
+ }
+
+ strct = strct->Next();
+ }
+
+ aList->Pop();
+ }
+ return false;
+}
+
+
+bool SCH_SHEET::Load( SCH_EDIT_FRAME* aFrame )
+{
+ bool success = true;
+
+ SCH_SCREEN* screen = NULL;
+ if( !m_screen )
+ {
+ g_RootSheet->SearchHierarchy( m_fileName, &screen );
+
+ if( screen )
+ {
+ SetScreen( screen );
+
+ //do not need to load the sub-sheets - this has already been done.
+ }
+ else
+ {
+ SetScreen( new SCH_SCREEN( &aFrame->Kiway() ) );
+
+ success = aFrame->LoadOneEEFile( m_screen, m_fileName );
+
+ if( success )
+ {
+ EDA_ITEM* bs = m_screen->GetDrawItems();
+
+ while( bs )
+ {
+ if( bs->Type() == SCH_SHEET_T )
+ {
+ SCH_SHEET* sheetstruct = (SCH_SHEET*) bs;
+
+ if( !sheetstruct->Load( aFrame ) )
+ success = false;
+ }
+
+ bs = bs->Next();
+ }
+ }
+ }
+ }
+
+ return success;
+}
+
+
+int SCH_SHEET::CountSheets()
+{
+ int count = 1; //1 = this!!
+
+ if( m_screen )
+ {
+ EDA_ITEM* strct = m_screen->GetDrawItems();
+
+ for( ; strct; strct = strct->Next() )
+ {
+ if( strct->Type() == SCH_SHEET_T )
+ {
+ SCH_SHEET* subsheet = (SCH_SHEET*) strct;
+ count += subsheet->CountSheets();
+ }
+ }
+ }
+ return count;
+}
+
+
+wxString SCH_SHEET::GetFileName( void ) const
+{
+ return m_fileName;
+}
+
+
+void SCH_SHEET::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
+{
+ aList.push_back( MSG_PANEL_ITEM( _( "Sheet Name" ), m_name, CYAN ) );
+ aList.push_back( MSG_PANEL_ITEM( _( "File Name" ), m_fileName, BROWN ) );
+
+#if 0 // Set to 1 to display the sheet time stamp (mainly for test)
+ wxString msg;
+ msg.Printf( wxT( "%.8X" ), m_TimeStamp );
+ aList.push_back( MSG_PANEL_ITEM( _( "Time Stamp" ), msg, BLUE ) );
+#endif
+}
+
+
+void SCH_SHEET::Rotate(wxPoint aPosition)
+{
+ RotatePoint( &m_pos, aPosition, 900 );
+ RotatePoint( &m_size.x, &m_size.y, 900 );
+
+ if( m_size.x < 0 )
+ {
+ m_pos.x += m_size.x;
+ m_size.x = -m_size.x;
+ }
+
+ if( m_size.y < 0 )
+ {
+ m_pos.y += m_size.y;
+ m_size.y = -m_size.y;
+ }
+
+ BOOST_FOREACH( SCH_SHEET_PIN& sheetPin, m_pins )
+ {
+ sheetPin.Rotate( aPosition );
+ }
+}
+
+
+void SCH_SHEET::MirrorX( int aXaxis_position )
+{
+ MIRROR( m_pos.y, aXaxis_position );
+ m_pos.y -= m_size.y;
+
+ BOOST_FOREACH( SCH_SHEET_PIN& sheetPin, m_pins )
+ {
+ sheetPin.MirrorX( aXaxis_position );
+ }
+}
+
+
+void SCH_SHEET::MirrorY( int aYaxis_position )
+{
+ MIRROR( m_pos.x, aYaxis_position );
+ m_pos.x -= m_size.x;
+
+ BOOST_FOREACH( SCH_SHEET_PIN& label, m_pins )
+ {
+ label.MirrorY( aYaxis_position );
+ }
+}
+
+void SCH_SHEET::SetPosition( const wxPoint& aPosition )
+{
+ // Remember the sheet and all pin sheet positions must be
+ // modified. So use Move function to do that.
+ Move( aPosition - m_pos );
+}
+
+
+
+void SCH_SHEET::Resize( const wxSize& aSize )
+{
+ if( aSize == m_size )
+ return;
+
+ m_size = aSize;
+
+ /* Move the sheet labels according to the new sheet size. */
+ BOOST_FOREACH( SCH_SHEET_PIN& label, m_pins )
+ {
+ label.ConstrainOnEdge( label.GetPosition() );
+ }
+}
+
+
+bool SCH_SHEET::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation )
+{
+ wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText() );
+
+ // Ignore the sheet file name if searching to replace.
+ if( !(aSearchData.GetFlags() & FR_SEARCH_REPLACE)
+ && SCH_ITEM::Matches( m_fileName, aSearchData ) )
+ {
+ if( aFindLocation )
+ *aFindLocation = GetFileNamePosition();
+
+ return true;
+ }
+
+ if( SCH_ITEM::Matches( m_name, aSearchData ) )
+ {
+ if( aFindLocation )
+ *aFindLocation = GetSheetNamePosition();
+
+ return true;
+ }
+
+ return false;
+}
+
+
+bool SCH_SHEET::Replace( wxFindReplaceData& aSearchData, void* aAuxData )
+{
+ return EDA_ITEM::Replace( aSearchData, m_name );
+}
+
+
+void SCH_SHEET::renumberPins()
+{
+ int id = 2;
+
+ BOOST_FOREACH( SCH_SHEET_PIN& pin, m_pins )
+ {
+ pin.SetNumber( id );
+ id++;
+ }
+}
+
+
+void SCH_SHEET::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
+{
+ for( unsigned ii = 0; ii < GetPins().size(); ii++ )
+ {
+ SCH_SHEET_PIN &pinsheet = GetPins()[ii];
+
+ wxCHECK2_MSG( pinsheet.Type() == SCH_SHEET_PIN_T, continue,
+ wxT( "Invalid item in schematic sheet pin list. Bad programmer!" ) );
+
+ pinsheet.GetEndPoints( aItemList );
+ }
+}
+
+
+bool SCH_SHEET::IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList )
+{
+ bool currentState = IsDangling();
+
+ BOOST_FOREACH( SCH_SHEET_PIN& pinsheet, GetPins() )
+ {
+ pinsheet.IsDanglingStateChanged( aItemList );
+ }
+
+ return currentState != IsDangling();
+}
+
+
+bool SCH_SHEET::IsDangling() const
+{
+ // If any hierarchical label in the sheet is dangling, then the sheet is dangling.
+ for( size_t i = 0; i < GetPins().size(); i++ )
+ {
+ if( GetPins()[i].IsDangling() )
+ return true;
+ }
+
+ return false;
+}
+
+
+bool SCH_SHEET::IsSelectStateChanged( const wxRect& aRect )
+{
+ bool previousState = IsSelected();
+
+ EDA_RECT boundingBox = GetBoundingBox();
+
+ if( aRect.Intersects( boundingBox ) )
+ SetFlags( SELECTED );
+ else
+ ClearFlags( SELECTED );
+
+ return previousState != IsSelected();
+}
+
+
+void SCH_SHEET::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
+{
+ for( size_t i = 0; i < GetPins().size(); i++ )
+ aPoints.push_back( GetPins()[i].GetPosition() );
+}
+
+
+SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR* aInspector, const void* aTestData,
+ const KICAD_T aFilterTypes[] )
+{
+ KICAD_T stype;
+
+ for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
+ {
+ // If caller wants to inspect my type
+ if( stype == Type() )
+ {
+ if( SEARCH_QUIT == aInspector->Inspect( this, NULL ) )
+ return SEARCH_QUIT;
+ }
+ else if( stype == SCH_SHEET_PIN_T )
+ {
+ // Test the sheet labels.
+ for( size_t i = 0; i < m_pins.size(); i++ )
+ {
+ if( SEARCH_QUIT == aInspector->Inspect( &m_pins[ i ], (void*) this ) )
+ return SEARCH_QUIT;
+ }
+ }
+ }
+
+ return SEARCH_CONTINUE;
+}
+
+
+wxString SCH_SHEET::GetSelectMenuText() const
+{
+ wxString tmp;
+ tmp.Printf( _( "Hierarchical Sheet %s" ), GetChars( m_name ) );
+ return tmp;
+}
+
+
+bool SCH_SHEET::HitTest( const wxPoint& aPosition, int aAccuracy ) const
+{
+ EDA_RECT rect = GetBoundingBox();
+
+ rect.Inflate( aAccuracy );
+
+ return rect.Contains( aPosition );
+}
+
+
+bool SCH_SHEET::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ EDA_RECT rect = aRect;
+
+ rect.Inflate( aAccuracy );
+
+ if( aContained )
+ return rect.Contains( GetBoundingBox() );
+
+ return rect.Intersects( GetBoundingBox() );
+}
+
+
+wxPoint SCH_SHEET::GetResizePosition() const
+{
+ return wxPoint( m_pos.x + m_size.GetWidth(), m_pos.y + m_size.GetHeight() );
+}
+
+
+void SCH_SHEET::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
+ SCH_SHEET_PATH* aSheetPath )
+{
+ SCH_SHEET_PATH sheetPath = *aSheetPath;
+ sheetPath.Push( this );
+
+ for( size_t i = 0; i < m_pins.size(); i++ )
+ {
+ NETLIST_OBJECT* item = new NETLIST_OBJECT();
+ item->m_SheetPathInclude = sheetPath;
+ item->m_SheetPath = *aSheetPath;
+ item->m_Comp = &m_pins[i];
+ item->m_Link = this;
+ item->m_Type = NET_SHEETLABEL;
+ item->m_ElectricalType = m_pins[i].GetShape();
+ item->m_Label = m_pins[i].GetText();
+ item->m_Start = item->m_End = m_pins[i].GetPosition();
+ aNetListItems.push_back( item );
+
+ if( IsBusLabel( m_pins[i].GetText() ) )
+ item->ConvertBusToNetListItems( aNetListItems );
+ }
+}
+
+
+void SCH_SHEET::Plot( PLOTTER* aPlotter )
+{
+ EDA_COLOR_T txtcolor = UNSPECIFIED_COLOR;
+ wxSize size;
+ wxString Text;
+ int name_orientation;
+ wxPoint pos_sheetname, pos_filename;
+ wxPoint pos;
+
+ aPlotter->SetColor( GetLayerColor( GetLayer() ) );
+
+ int thickness = GetPenSize();
+ aPlotter->SetCurrentLineWidth( thickness );
+
+ aPlotter->MoveTo( m_pos );
+ pos = m_pos;
+ pos.x += m_size.x;
+
+ aPlotter->LineTo( pos );
+ pos.y += m_size.y;
+
+ aPlotter->LineTo( pos );
+ pos = m_pos;
+ pos.y += m_size.y;
+
+ aPlotter->LineTo( pos );
+ aPlotter->FinishTo( m_pos );
+
+ if( IsVerticalOrientation() )
+ {
+ pos_sheetname = wxPoint( m_pos.x - 8, m_pos.y + m_size.y );
+ pos_filename = wxPoint( m_pos.x + m_size.x + 4, m_pos.y + m_size.y );
+ name_orientation = TEXT_ORIENT_VERT;
+ }
+ else
+ {
+ pos_sheetname = wxPoint( m_pos.x, m_pos.y - 4 );
+ pos_filename = wxPoint( m_pos.x, m_pos.y + m_size.y + 4 );
+ name_orientation = TEXT_ORIENT_HORIZ;
+ }
+
+ /* Draw texts: SheetName */
+ Text = m_name;
+ size = wxSize( m_sheetNameSize, m_sheetNameSize );
+
+ //pos = m_pos; pos.y -= 4;
+ thickness = GetDefaultLineThickness();
+ thickness = Clamp_Text_PenSize( thickness, size, false );
+
+ aPlotter->SetColor( GetLayerColor( LAYER_SHEETNAME ) );
+
+ bool italic = false;
+ aPlotter->Text( pos_sheetname, txtcolor, Text, name_orientation, size,
+ GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_BOTTOM,
+ thickness, italic, false );
+
+ /*Draw texts : FileName */
+ Text = GetFileName();
+ size = wxSize( m_fileNameSize, m_fileNameSize );
+ thickness = GetDefaultLineThickness();
+ thickness = Clamp_Text_PenSize( thickness, size, false );
+
+ aPlotter->SetColor( GetLayerColor( LAYER_SHEETFILENAME ) );
+
+ aPlotter->Text( pos_filename, txtcolor, Text, name_orientation, size,
+ GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP,
+ thickness, italic, false );
+
+ aPlotter->SetColor( GetLayerColor( GetLayer() ) );
+
+ /* Draw texts : SheetLabel */
+ for( size_t i = 0; i < m_pins.size(); i++ )
+ {
+ m_pins[i].Plot( aPlotter );
+ }
+}
+
+
+SCH_ITEM& SCH_SHEET::operator=( const SCH_ITEM& aItem )
+{
+ wxLogDebug( wxT( "Sheet assignment operator." ) );
+
+ wxCHECK_MSG( Type() == aItem.Type(), *this,
+ wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
+ GetClass() );
+
+ if( &aItem != this )
+ {
+ SCH_ITEM::operator=( aItem );
+
+ SCH_SHEET* sheet = (SCH_SHEET*) &aItem;
+
+ m_pos = sheet->m_pos;
+ m_size = sheet->m_size;
+ m_name = sheet->m_name;
+ m_sheetNameSize = sheet->m_sheetNameSize;
+ m_fileNameSize = sheet->m_fileNameSize;
+ m_pins = sheet->m_pins;
+
+ // Ensure sheet labels have their #m_Parent member pointing really on their
+ // parent, after assigning.
+ BOOST_FOREACH( SCH_SHEET_PIN& sheetPin, m_pins )
+ {
+ sheetPin.SetParent( this );
+ }
+ }
+
+ return *this;
+}
+
+
+#if defined(DEBUG)
+
+void SCH_SHEET::Show( int nestLevel, std::ostream& os ) const
+{
+ // XML output:
+ wxString s = GetClass();
+
+ NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << ">" << " sheet_name=\""
+ << TO_UTF8( m_name ) << '"' << ">\n";
+
+ // show all the pins, and check the linked list integrity
+ BOOST_FOREACH( const SCH_SHEET_PIN& label, m_pins )
+ {
+ label.Show( nestLevel + 1, os );
+ }
+
+ NestedSpace( nestLevel, os ) << "</" << s.Lower().mb_str() << ">\n" << std::flush;
+}
+
+#endif
diff --git a/eeschema/sch_sheet.h b/eeschema/sch_sheet.h
new file mode 100644
index 0000000..3304a0d
--- /dev/null
+++ b/eeschema/sch_sheet.h
@@ -0,0 +1,600 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_sheet.h
+ * @brief Definition of the SCH_SHEET class for Eeschema.
+ */
+
+#ifndef SCH_SHEEET_H
+#define SCH_SHEEET_H
+
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/foreach.hpp>
+#include <sch_text.h>
+
+
+class LINE_READER;
+class SCH_SCREEN;
+class SCH_SHEET;
+class SCH_SHEET_PIN;
+class SCH_SHEET_PATH;
+class DANGLING_END_ITEM;
+class SCH_EDIT_FRAME;
+class NETLIST_OBJECT_LIST;
+
+
+#define MIN_SHEET_WIDTH 500
+#define MIN_SHEET_HEIGHT 150
+
+
+/**
+ * Class SCH_SHEET_PIN
+ * defines a sheet pin (label) used in sheets to create hierarchical schematics.
+ *
+ * A SCH_SHEET_PIN is used to create a hierarchical sheet in the same way a
+ * pin is used in a component. It connects the objects in the sheet object
+ * to the objects in the schematic page to the objects in the page that is
+ * represented by the sheet. In a sheet object, a SCH_SHEET_PIN must be
+ * connected to a wire, bus, or label. In the schematic page represented by
+ * the sheet, it corresponds to a hierarchical label.
+ */
+class SCH_SHEET_PIN : public SCH_HIERLABEL
+{
+private:
+ int m_number; ///< Label number use for saving sheet label to file.
+ ///< Sheet label numbering begins at 2.
+ ///< 0 is reserved for the sheet name.
+ ///< 1 is reserve for the sheet file name.
+
+ /**
+ * Defines the edge of the sheet that the sheet pin is positioned
+ * SHEET_LEFT_SIDE = 0: pin on left side
+ * SHEET_RIGHT_SIDE = 1: pin on right side
+ * SHEET_TOP_SIDE = 2: pin on top side
+ * SHEET_BOTTOM_SIDE =3: pin on bottom side
+ *
+ * For compatibility reasons, this does not follow same values as text orientation.
+ */
+ enum SHEET_SIDE
+ {
+ SHEET_LEFT_SIDE = 0,
+ SHEET_RIGHT_SIDE,
+ SHEET_TOP_SIDE,
+ SHEET_BOTTOM_SIDE,
+ SHEET_UNDEFINED_SIDE
+ };
+ SHEET_SIDE m_edge;
+
+public:
+ SCH_SHEET_PIN( SCH_SHEET* parent,
+ const wxPoint& pos = wxPoint( 0, 0 ),
+ const wxString& text = wxEmptyString );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~SCH_SHEET_PIN() { }
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_SHEET_PIN" );
+ }
+
+ bool operator ==( const SCH_SHEET_PIN* aPin ) const;
+
+ /**
+ * Virtual function IsMovableFromAnchorPoint
+ * Return true for items which are moved with the anchor point at mouse cursor
+ * and false for items moved with no reference to anchor (usually large items)
+ * @return true for a hierarchical sheet pin
+ */
+ bool IsMovableFromAnchorPoint() { return true; }
+
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR );
+
+ /**
+ * Function CreateGraphicShape (virtual)
+ * Calculates the graphic shape (a polygon) associated to the text
+ * @param aPoints = a buffer to fill with polygon corners coordinates
+ * @param aPos = Position of the shape
+ */
+ void CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& aPos );
+
+ void SwapData( SCH_ITEM* aItem );
+
+ int GetPenSize() const;
+
+ /**
+ * Get the sheet label number.
+ *
+ * @return Number of the sheet label.
+ */
+ int GetNumber() const { return m_number; }
+
+ /**
+ * Set the sheet label number.
+ *
+ * @param aNumber - New sheet number label.
+ */
+ void SetNumber( int aNumber );
+
+ void SetEdge( SHEET_SIDE aEdge );
+
+ SHEET_SIDE GetEdge() const;
+
+ /**
+ * Function ConstrainOnEdge
+ * is used to adjust label position to edge based on proximity to vertical / horizontal edge
+ * of the parent sheet.
+ */
+ void ConstrainOnEdge( wxPoint Pos );
+
+ /**
+ * Get the parent sheet object of this sheet pin.
+ *
+ * @return The sheet that is the parent of this sheet pin or NULL if it does
+ * not have a parent.
+ */
+ SCH_SHEET* GetParent() const { return (SCH_SHEET*) m_Parent; }
+
+ bool Save( FILE* aFile ) const;
+
+ bool Load( LINE_READER& aLine, wxString& aErrorMsg );
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // override
+#endif
+
+ // Geometric transforms (used in block operations):
+
+ void Move( const wxPoint& aMoveVector )
+ {
+ m_Pos += aMoveVector;
+ }
+
+ void MirrorY( int aYaxis_position );
+
+ void Rotate( wxPoint aPosition );
+
+ void MirrorX( int aXaxis_position );
+
+ bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
+
+ bool Replace( wxFindReplaceData& aSearchData, void* aAuxData = NULL )
+ {
+ return EDA_ITEM::Replace( aSearchData, m_Text );
+ }
+
+ bool IsReplaceable() const { return true; }
+
+ void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList );
+
+ bool IsConnectable() const { return true; }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_hierar_pin_xpm; }
+
+ void SetPosition( const wxPoint& aPosition ) { ConstrainOnEdge( aPosition ); }
+
+ bool HitTest( const wxPoint& aPosition, int aAccuracy ) const;
+
+ EDA_ITEM* Clone() const;
+};
+
+
+typedef boost::ptr_vector<SCH_SHEET_PIN> SCH_SHEET_PINS;
+
+
+/**
+ * Class SCH_SHEET
+ * is the sheet symbol placed in a schematic, and is the entry point for a sub schematic.
+ */
+class SCH_SHEET : public SCH_ITEM
+{
+ friend class SCH_SHEET_PIN;
+
+ /// Screen that contains the physical data for the sheet. In complex hierarchies
+ /// multiple sheets can share a common screen.
+ SCH_SCREEN* m_screen;
+
+ /// The list of sheet connection points.
+ SCH_SHEET_PINS m_pins;
+
+ /// The file name is also in the #SCH_SCREEN object associated with the sheet. It is
+ /// also needed here for loading after reading the sheet description from file.
+ wxString m_fileName;
+
+ /// This is equivalent to the reference designator for components and is stored in F0
+ /// sheet pin in the schematic file.
+ wxString m_name;
+
+ /// The height of the text used to draw the sheet name.
+ int m_sheetNameSize;
+
+ /// The height of the text used to draw the file name.
+ int m_fileNameSize;
+
+ /// The position of the sheet.
+ wxPoint m_pos;
+
+ /// The size of the sheet.
+ wxSize m_size;
+
+public:
+ SCH_SHEET( const wxPoint& pos = wxPoint( 0, 0 ) );
+
+ /**
+ * Copy Constructor
+ * clones \a aSheet into a new object. All sheet pins are copied as is except and
+ * the SCH_SHEET_PIN's #m_Parent pointers are set to the new copied parent object.
+ */
+ SCH_SHEET( const SCH_SHEET& aSheet );
+
+ ~SCH_SHEET();
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_SHEET" );
+ }
+
+ /**
+ * Virtual function IsMovableFromAnchorPoint
+ * Return true for items which are moved with the anchor point at mouse cursor
+ * and false for items moved with no reference to anchor
+ * Usually return true for small items (labels, junctions) and false for
+ * items which can be large (hierarchical sheets, compoments)
+ * @return false for a hierarchical sheet
+ */
+ bool IsMovableFromAnchorPoint() { return false; }
+
+ wxString GetName() const { return m_name; }
+
+ void SetName( const wxString& aName ) { m_name = aName; }
+
+ int GetSheetNameSize() const { return m_sheetNameSize; }
+
+ void SetSheetNameSize( int aSize ) { m_sheetNameSize = aSize; }
+
+ int GetFileNameSize() const { return m_fileNameSize; }
+
+ void SetFileNameSize( int aSize ) { m_fileNameSize = aSize; }
+
+ SCH_SCREEN* GetScreen() { return m_screen; }
+
+ wxSize GetSize() { return m_size; }
+
+ void SetSize( const wxSize& aSize ) { m_size = aSize; }
+
+ /**
+ * Function SetScreen
+ * sets the screen associated with this sheet to \a aScreen.
+ * <p>
+ * The screen reference counting is performed by SetScreen. If \a aScreen is not
+ * the same as the current screen, the current screen reference count is decremented
+ * and \a aScreen becomes the screen for the sheet. If the current screen reference
+ * count reaches zero, the current screen is deleted. NULL is a valid value for
+ * \a aScreen.
+ * </p>
+ * @param aScreen The new screen to associate with the sheet.
+ */
+ void SetScreen( SCH_SCREEN* aScreen );
+
+ /**
+ * Function GetScreenCount
+ * returns the number of times the associated screen for the sheet is being used. If
+ * no screen is associated with the sheet, then zero is returned.
+ */
+ int GetScreenCount() const;
+
+ bool Save( FILE* aFile ) const;
+
+ bool Load( LINE_READER& aLine, wxString& aErrorMsg );
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ /* there is no member for orientation in sch_sheet, to preserve file
+ * format, we detect orientation based on pin edges
+ */
+ bool IsVerticalOrientation() const;
+
+ /**
+ * Add aSheetPin to the sheet.
+ *
+ * Note: Once a sheet pin is added to the sheet, it is owned by the sheet.
+ * Do not delete the sheet pin object or you will likely get a segfault
+ * when the sheet is destroyed.
+ *
+ * @param aSheetPin The sheet pin item to add to the sheet.
+ */
+ void AddPin( SCH_SHEET_PIN* aSheetPin );
+
+ SCH_SHEET_PINS& GetPins() { return m_pins; }
+
+ SCH_SHEET_PINS& GetPins() const
+ {
+ return const_cast< SCH_SHEET_PINS& >( m_pins );
+ }
+
+ /**
+ * Remove \a aSheetPin from the sheet.
+ *
+ * @param aSheetPin The sheet pin item to remove from the sheet.
+ */
+ void RemovePin( SCH_SHEET_PIN* aSheetPin );
+
+ /**
+ * Delete sheet label which do not have a corresponding hierarchical label.
+ *
+ * Note: Make sure you save a copy of the sheet in the undo list before calling
+ * CleanupSheet() otherwise any unreferenced sheet labels will be lost.
+ */
+ void CleanupSheet();
+
+ /**
+ * Return the sheet pin item found at \a aPosition in the sheet.
+ *
+ * @param aPosition The position to check for a sheet pin.
+ *
+ * @return The sheet pin found at \a aPosition or NULL if no sheet pin is found.
+ */
+ SCH_SHEET_PIN* GetPin( const wxPoint& aPosition );
+
+ /**
+ * Checks if the sheet already has a sheet pin named \a aName.
+ *
+ * @param aName Name of the sheet pin to search for.
+ *
+ * @return True if sheet pin with \a aName is found, otherwise false.
+ */
+ bool HasPin( const wxString& aName );
+
+ bool HasPins() { return !m_pins.empty(); }
+
+ /**
+ * Check all sheet labels against schematic for undefined hierarchical labels.
+ *
+ * @return True if there are any undefined labels.
+ */
+ bool HasUndefinedPins();
+
+ /**
+ * Function GetMinWidth
+ * returns the minimum width of the sheet based on the widths of the sheet pin text.
+ *
+ * <p>
+ * The minimum sheet width is determined by the width of the bounding box of each
+ * hierarchical sheet pin. If two pins are horizontally adjacent ( same Y position )
+ * to each other, the sum of the bounding box widths is used. If at some point in
+ * the future sheet objects can be rotated or pins can be placed in the vertical
+ * orientation, this function will need to be changed.
+ * </p>
+ *
+ * @return The minimum width the sheet can be resized.
+ */
+ int GetMinWidth() const;
+
+ /**
+ * Function GetMinHeight
+ * returns the minimum height that the sheet can be resized based on the sheet pin
+ * positions.
+ *
+ * <p>
+ * The minimum width of a sheet is determined by the Y axis location of the bottom
+ * most sheet pin. If at some point in the future sheet objects can be rotated or
+ * pins can be placed in the vertical orientation, this function will need to be
+ * changed.
+ * </p>
+ *
+ * @return The minimum height the sheet can be resized.
+ */
+ int GetMinHeight() const;
+
+ int GetPenSize() const;
+
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
+ GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor = UNSPECIFIED_COLOR );
+
+ EDA_RECT const GetBoundingBox() const;
+
+ /**
+ * Function GetResizePos
+ * returns the position of the lower right corner of the sheet in drawing units.
+ *
+ * @return A wxPoint containing lower right corner of the sheet in drawing units.
+ */
+ wxPoint GetResizePosition() const;
+
+ void SwapData( SCH_ITEM* aItem );
+
+ /**
+ * Function ComponentCount
+ * count our own components, without the power components.
+ * @return the component count.
+ */
+ int ComponentCount();
+
+ /**
+ * Function Load.
+ * for the sheet: load the file m_fileName
+ * if a screen already exists, the file is already read.
+ * m_screen point on the screen, and its m_RefCount is
+ * incremented
+ * else creates a new associated screen and load the data file.
+ * @param aFrame = a SCH_EDIT_FRAME pointer to the maim schematic frame
+ * @return true if OK
+ */
+ bool Load( SCH_EDIT_FRAME* aFrame );
+
+ /**
+ * Function SearchHierarchy
+ * search the existing hierarchy for an instance of screen "FileName".
+ * @param aFilename = the filename to find
+ * @param aScreen = a location to return a pointer to the screen (if found)
+ * @return bool if found, and a pointer to the screen
+ */
+ bool SearchHierarchy( const wxString& aFilename, SCH_SCREEN** aScreen );
+
+ /**
+ * Function LocatePathOfScreen
+ * search the existing hierarchy for an instance of screen "FileName".
+ * don't bother looking at the root sheet - it must be unique,
+ * no other references to its m_screen otherwise there would be
+ * loops in the hierarchy.
+ *
+ * @param aScreen = the SCH_SCREEN* screen that we search for
+ * @param aList = the SCH_SHEET_PATH* that must be used
+ * @return true if found
+ */
+ bool LocatePathOfScreen( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aList );
+
+ /**
+ * Function CountSheets
+ * calculates the number of sheets found in "this"
+ * this number includes the full subsheets count
+ * @return the full count of sheets+subsheets contained by "this"
+ */
+ int CountSheets();
+
+ /**
+ * Function GetFileName
+ * return the filename corresponding to this sheet
+ * @return a wxString containing the filename
+ */
+ wxString GetFileName( void ) const;
+
+ // Set a new filename without changing anything else
+ void SetFileName( const wxString& aFilename )
+ {
+ m_fileName = aFilename;
+ // Filenames are stored using unix notation
+ m_fileName.Replace( wxT("\\"), wxT("/") );
+ }
+
+ bool ChangeFileName( SCH_EDIT_FRAME* aFrame, const wxString& aFileName );
+
+ //void RemoveSheet(SCH_SHEET* sheet);
+ //to remove a sheet, just delete it
+ //-- the destructor should take care of everything else.
+
+ // Geometric transforms (used in block operations):
+
+ void Move( const wxPoint& aMoveVector )
+ {
+ m_pos += aMoveVector;
+
+ BOOST_FOREACH( SCH_SHEET_PIN& pin, m_pins )
+ {
+ pin.Move( aMoveVector );
+ }
+ }
+
+ void MirrorY( int aYaxis_position );
+
+ void MirrorX( int aXaxis_position );
+
+ void Rotate( wxPoint aPosition );
+
+ bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
+
+ bool Replace( wxFindReplaceData& aSearchData, void* aAuxData = NULL );
+
+ bool IsReplaceable() const { return true; }
+
+ /**
+ * Resize this sheet to aSize and adjust all of the labels accordingly.
+ *
+ * @param aSize - The new size for this sheet.
+ */
+ void Resize( const wxSize& aSize );
+
+ /**
+ * Function GetSheetNamePosition
+ * @return the position of the anchor of sheet name text
+ */
+ wxPoint GetSheetNamePosition();
+
+ /**
+ * Function GetFileNamePosition
+ * @return the position of the anchor of filename text
+ */
+ wxPoint GetFileNamePosition();
+
+ void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList );
+
+ bool IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList );
+
+ bool IsDangling() const;
+
+ bool IsSelectStateChanged( const wxRect& aRect );
+
+ bool IsConnectable() const { return true; }
+
+ void GetConnectionPoints( std::vector< wxPoint >& aPoints ) const;
+
+ SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
+ const KICAD_T scanTypes[] );
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_hierarchical_subsheet_xpm; }
+
+ void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
+ SCH_SHEET_PATH* aSheetPath );
+
+ SCH_ITEM& operator=( const SCH_ITEM& aSheet );
+
+ wxPoint GetPosition() const { return m_pos; }
+
+ void SetPosition( const wxPoint& aPosition );
+
+ bool HitTest( const wxPoint& aPosition, int aAccuracy ) const;
+
+ bool HitTest( const EDA_RECT& aRect, bool aContained = false, int aAccuracy = 0 ) const;
+
+ void Plot( PLOTTER* aPlotter );
+
+ EDA_ITEM* Clone() const;
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // override
+#endif
+
+protected:
+
+ /**
+ * Renumber the sheet pins in the sheet.
+ *
+ * This method is used internally by SCH_SHEET to update the pin numbering
+ * when the pin list changes. Make sure you call this method any time a
+ * sheet pin is added or removed.
+ */
+ void renumberPins();
+};
+
+
+typedef std::vector< SCH_SHEET* > SCH_SHEETS;
+
+#endif /* SCH_SHEEET_H */
diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp
new file mode 100644
index 0000000..790a22c
--- /dev/null
+++ b/eeschema/sch_sheet_path.cpp
@@ -0,0 +1,924 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_sheet_path.cpp
+ * @brief SCH_SHEET_PATH class implementation.
+ */
+
+#include <fctsys.h>
+
+#include <general.h>
+#include <dlist.h>
+#include <class_sch_screen.h>
+#include <sch_item_struct.h>
+
+#include <sch_reference_list.h>
+#include <class_library.h>
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+#include <sch_component.h>
+#include <template_fieldnames.h>
+
+#include <dialogs/dialog_schematic_find.h>
+
+#include <boost/foreach.hpp>
+#include <wx/filename.h>
+
+
+SCH_SHEET_PATH::SCH_SHEET_PATH()
+{
+ for( int i = 0; i<DSLSZ; i++ )
+ m_sheets[i] = NULL;
+
+ m_numSheets = 0;
+}
+
+
+bool SCH_SHEET_PATH::BuildSheetPathInfoFromSheetPathValue( const wxString& aPath, bool aFound )
+{
+ if( aFound )
+ return true;
+
+ if( GetCount() == 0 )
+ Push( g_RootSheet );
+
+ if( aPath == Path() )
+ return true;
+
+ SCH_ITEM* schitem = LastDrawList();
+
+ while( schitem && GetCount() < NB_MAX_SHEET )
+ {
+ if( schitem->Type() == SCH_SHEET_T )
+ {
+ SCH_SHEET* sheet = (SCH_SHEET*) schitem;
+ Push( sheet );
+
+ if( aPath == Path() )
+ return true;
+
+ if( BuildSheetPathInfoFromSheetPathValue( aPath ) )
+ return true;
+
+ Pop();
+ }
+
+ schitem = schitem->Next();
+ }
+
+ return false;
+}
+
+
+int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const
+{
+ if( m_numSheets > aSheetPathToTest.m_numSheets )
+ return 1;
+
+ if( m_numSheets < aSheetPathToTest.m_numSheets )
+ return -1;
+
+ //otherwise, same number of sheets.
+ for( unsigned i = 0; i<m_numSheets; i++ )
+ {
+ if( m_sheets[i]->GetTimeStamp() > aSheetPathToTest.m_sheets[i]->GetTimeStamp() )
+ return 1;
+
+ if( m_sheets[i]->GetTimeStamp() < aSheetPathToTest.m_sheets[i]->GetTimeStamp() )
+ return -1;
+ }
+
+ return 0;
+}
+
+
+SCH_SHEET* SCH_SHEET_PATH::Last() const
+{
+ if( m_numSheets )
+ return m_sheets[m_numSheets - 1];
+
+ return NULL;
+}
+
+
+SCH_SCREEN* SCH_SHEET_PATH::LastScreen() const
+{
+ SCH_SHEET* lastSheet = Last();
+
+ if( lastSheet )
+ return lastSheet->GetScreen();
+
+ return NULL;
+}
+
+
+SCH_ITEM* SCH_SHEET_PATH::LastDrawList() const
+{
+ SCH_SHEET* lastSheet = Last();
+
+ if( lastSheet && lastSheet->GetScreen() )
+ return lastSheet->GetScreen()->GetDrawItems();
+
+ return NULL;
+}
+
+
+SCH_ITEM* SCH_SHEET_PATH::FirstDrawList() const
+{
+ SCH_ITEM* item = NULL;
+
+ if( m_numSheets && m_sheets[0]->GetScreen() )
+ item = m_sheets[0]->GetScreen()->GetDrawItems();
+
+ /* @fixme - These lists really should be one of the boost pointer containers. This
+ * is a brain dead hack to allow reverse iteration of EDA_ITEM linked
+ * list.
+ */
+ SCH_ITEM* lastItem = NULL;
+
+ while( item )
+ {
+ lastItem = item;
+ item = item->Next();
+ }
+
+ return lastItem;
+}
+
+
+void SCH_SHEET_PATH::Push( SCH_SHEET* aSheet )
+{
+ wxCHECK_RET( m_numSheets < DSLSZ,
+ wxString::Format( _( "Schematic sheets can only be nested %d levels deep." ),
+ DSLSZ ) );
+
+ m_sheets[ m_numSheets ] = aSheet;
+ m_numSheets++;
+}
+
+
+SCH_SHEET* SCH_SHEET_PATH::Pop()
+{
+ if( m_numSheets > 0 )
+ {
+ m_numSheets--;
+ return m_sheets[m_numSheets];
+ }
+
+ return NULL;
+}
+
+
+wxString SCH_SHEET_PATH::Path() const
+{
+ wxString s, t;
+
+ s = wxT( "/" ); // This is the root path
+
+ // start at 1 to avoid the root sheet,
+ // which does not need to be added to the path
+ // it's timestamp changes anyway.
+ for( unsigned i = 1; i < m_numSheets; i++ )
+ {
+ t.Printf( _( "%8.8lX/" ), (long unsigned) m_sheets[i]->GetTimeStamp() );
+ s = s + t;
+ }
+
+ return s;
+}
+
+
+wxString SCH_SHEET_PATH::PathHumanReadable() const
+{
+ wxString s;
+
+ s = wxT( "/" );
+
+ // start at 1 to avoid the root sheet, as above.
+ for( unsigned i = 1; i< m_numSheets; i++ )
+ {
+ s = s + m_sheets[i]->GetName() + wxT( "/" );
+ }
+
+ return s;
+}
+
+
+void SCH_SHEET_PATH::UpdateAllScreenReferences()
+{
+ EDA_ITEM* t = LastDrawList();
+
+ while( t )
+ {
+ if( t->Type() == SCH_COMPONENT_T )
+ {
+ SCH_COMPONENT* component = (SCH_COMPONENT*) t;
+ component->GetField( REFERENCE )->SetText( component->GetRef( this ) );
+ component->UpdateUnit( component->GetUnitSelection( this ) );
+ }
+
+ t = t->Next();
+ }
+}
+
+
+void SCH_SHEET_PATH::AnnotatePowerSymbols( PART_LIBS* aLibs, int* aReference )
+{
+ int ref = 1;
+
+ if( aReference )
+ ref = *aReference;
+
+ for( EDA_ITEM* item = LastDrawList(); item; item = item->Next() )
+ {
+ if( item->Type() != SCH_COMPONENT_T )
+ continue;
+
+ SCH_COMPONENT* component = (SCH_COMPONENT*) item;
+ LIB_PART* part = aLibs->FindLibPart( component->GetPartName() );
+
+ if( !part || !part->IsPower() )
+ continue;
+
+ wxString refstr = component->GetPrefix();
+
+ //str will be "C?" or so after the ClearAnnotation call.
+ while( refstr.Last() == '?' )
+ refstr.RemoveLast();
+
+ if( !refstr.StartsWith( wxT( "#" ) ) )
+ refstr = wxT( "#" ) + refstr;
+
+ refstr << wxT( "0" ) << ref;
+ component->SetRef( this, refstr );
+ ref++;
+ }
+
+ if( aReference )
+ *aReference = ref;
+}
+
+
+void SCH_SHEET_PATH::GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols )
+{
+ // Search to sheet path number:
+ int sheetnumber = 1; // 1 = root
+
+ SCH_SHEET_LIST sheetList;
+
+ for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path; path = sheetList.GetNext(), sheetnumber++ )
+ {
+ if( Cmp( *path ) == 0 )
+ break;
+ }
+
+ for( SCH_ITEM* item = LastDrawList(); item; item = item->Next() )
+ {
+ if( item->Type() == SCH_COMPONENT_T )
+ {
+ SCH_COMPONENT* component = (SCH_COMPONENT*) item;
+
+ // Skip pseudo components, which have a reference starting with #. This mainly
+ // affects power symbols.
+ if( !aIncludePowerSymbols && component->GetRef( this )[0] == wxT( '#' ) )
+ continue;
+
+ LIB_PART* part = aLibs->FindLibPart( component->GetPartName() );
+ if( part )
+ {
+ SCH_REFERENCE reference = SCH_REFERENCE( component, part, *this );
+ reference.SetSheetNumber( sheetnumber );
+ aReferences.AddItem( reference );
+ }
+ }
+ }
+}
+
+void SCH_SHEET_PATH::GetMultiUnitComponents( PART_LIBS* aLibs, SCH_MULTI_UNIT_REFERENCE_MAP &aRefList,
+ bool aIncludePowerSymbols )
+{
+ // Find sheet path number
+ int sheetnumber = 1; // 1 = root
+
+ SCH_SHEET_LIST sheetList;
+
+ for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path; path = sheetList.GetNext(), sheetnumber++ )
+ {
+ if( Cmp( *path ) == 0 )
+ break;
+ }
+
+ for( SCH_ITEM* item = LastDrawList(); item; item = item->Next() )
+ {
+ if( item->Type() != SCH_COMPONENT_T ) continue;
+ SCH_COMPONENT* component = (SCH_COMPONENT*) item;
+
+ // Skip pseudo components, which have a reference starting with #. This mainly
+ // affects power symbols.
+ if( !aIncludePowerSymbols && component->GetRef( this )[0] == wxT( '#' ) )
+ continue;
+
+ LIB_PART* part = aLibs->FindLibPart( component->GetPartName() );
+ if( part && part->GetUnitCount() > 1 )
+ {
+ SCH_REFERENCE reference = SCH_REFERENCE( component, part, *this );
+ reference.SetSheetNumber( sheetnumber );
+ wxString reference_str = reference.GetRef();
+
+ // Never lock unassigned references
+ if( reference_str[reference_str.Len() - 1] == '?' ) continue;
+
+ aRefList[reference_str].AddItem( reference );
+ }
+ }
+}
+
+
+SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) const
+{
+ bool hasWrapped = false;
+ bool firstItemFound = false;
+ SCH_ITEM* drawItem = LastDrawList();
+
+ while( drawItem )
+ {
+ if( drawItem->Type() == aType )
+ {
+ if( !aLastItem || firstItemFound )
+ {
+ return drawItem;
+ }
+ else if( !firstItemFound && drawItem == aLastItem )
+ {
+ firstItemFound = true;
+ }
+ }
+
+ drawItem = drawItem->Next();
+
+ if( !drawItem && aLastItem && aWrap && !hasWrapped )
+ {
+ hasWrapped = true;
+ drawItem = LastDrawList();
+ }
+ }
+
+ return NULL;
+}
+
+
+SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) const
+{
+ bool hasWrapped = false;
+ bool firstItemFound = false;
+ SCH_ITEM* drawItem = FirstDrawList();
+
+ while( drawItem )
+ {
+ if( drawItem->Type() == aType )
+ {
+ if( aLastItem == NULL || firstItemFound )
+ {
+ return drawItem;
+ }
+ else if( !firstItemFound && drawItem == aLastItem )
+ {
+ firstItemFound = true;
+ }
+ }
+
+ drawItem = drawItem->Back();
+
+ if( drawItem == NULL && aLastItem && aWrap && !hasWrapped )
+ {
+ hasWrapped = true;
+ drawItem = FirstDrawList();
+ }
+ }
+
+ return NULL;
+}
+
+
+bool SCH_SHEET_PATH::SetComponentFootprint( const wxString& aReference, const wxString& aFootPrint,
+ bool aSetVisible )
+{
+ SCH_SCREEN* screen = LastScreen();
+
+ if( screen == NULL )
+ return false;
+
+ return screen->SetComponentFootprint( this, aReference, aFootPrint, aSetVisible );
+}
+
+
+SCH_SHEET_PATH& SCH_SHEET_PATH::operator=( const SCH_SHEET_PATH& d1 )
+{
+ if( this == &d1 ) // Self assignment is bad!
+ return *this;
+
+ m_numSheets = d1.m_numSheets;
+
+ unsigned i;
+
+ for( i = 0; i < m_numSheets; i++ )
+ m_sheets[i] = d1.m_sheets[i];
+
+ for( ; i < DSLSZ; i++ )
+ m_sheets[i] = 0;
+
+ return *this;
+}
+
+
+bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 ) const
+{
+ if( m_numSheets != d1.m_numSheets )
+ return false;
+
+ for( unsigned i = 0; i < m_numSheets; i++ )
+ {
+ if( m_sheets[i] != d1.m_sheets[i] )
+ return false;
+ }
+
+ return true;
+}
+
+
+bool SCH_SHEET_PATH::TestForRecursion( const wxString& aSrcFileName,
+ const wxString& aDestFileName ) const
+{
+ wxFileName rootFn = g_RootSheet->GetFileName();
+ wxFileName srcFn = aSrcFileName;
+ wxFileName destFn = aDestFileName;
+
+ if( srcFn.IsRelative() )
+ srcFn.MakeAbsolute( rootFn.GetPath() );
+
+ if( destFn.IsRelative() )
+ destFn.MakeAbsolute( rootFn.GetPath() );
+
+
+ // The source and destination sheet file names cannot be the same.
+ if( srcFn == destFn )
+ return true;
+
+ /// @todo Store sheet file names with full path, either relative to project path
+ /// or absolute path. The current design always assumes subsheet files are
+ /// located in the project folder which may or may not be desirable.
+ unsigned i = 0;
+
+ while( i < m_numSheets )
+ {
+ wxFileName cmpFn = m_sheets[i]->GetFileName();
+
+ if( cmpFn.IsRelative() )
+ cmpFn.MakeAbsolute( rootFn.GetPath() );
+
+ // Test if the file name of the destination sheet is in anywhere in this sheet path.
+ if( cmpFn == destFn )
+ break;
+
+ i++;
+ }
+
+ // The destination sheet file name was not found in the sheet path or the destination
+ // sheet file name is the root sheet so no recursion is possible.
+ if( i >= m_numSheets || i == 0 )
+ return false;
+
+ // Walk back up to the root sheet to see if the source file name is already a parent in
+ // the sheet path. If so, recursion will occur.
+ do
+ {
+ i -= 1;
+
+ wxFileName cmpFn = m_sheets[i]->GetFileName();
+
+ if( cmpFn.IsRelative() )
+ cmpFn.MakeAbsolute( rootFn.GetPath() );
+
+ if( cmpFn == srcFn )
+ return true;
+
+ } while( i != 0 );
+
+ // The source sheet file name is not a parent of the destination sheet file name.
+ return false;
+}
+
+
+int SCH_SHEET_PATH::FindSheet( const wxString& aFileName ) const
+{
+ for( unsigned i = 0; i < m_numSheets; i++ )
+ {
+ if( m_sheets[i]->GetFileName().CmpNoCase( aFileName ) == 0 )
+ return (int)i;
+ }
+
+ return SHEET_NOT_FOUND;
+}
+
+
+SCH_SHEET* SCH_SHEET_PATH::FindSheetByName( const wxString& aSheetName )
+{
+ for( unsigned i = 0; i < m_numSheets; i++ )
+ {
+ if( m_sheets[i]->GetName().CmpNoCase( aSheetName ) == 0 )
+ return m_sheets[i];
+ }
+
+ return NULL;
+}
+
+
+/********************************************************************/
+/* Class SCH_SHEET_LIST to handle the list of Sheets in a hierarchy */
+/********************************************************************/
+SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet )
+{
+ m_index = 0;
+ m_count = 0;
+ m_list = NULL;
+ m_isRootSheet = false;
+
+ if( aSheet == NULL )
+ aSheet = g_RootSheet;
+
+ BuildSheetList( aSheet );
+}
+
+
+SCH_SHEET_PATH* SCH_SHEET_LIST::GetFirst()
+{
+ m_index = 0;
+
+ if( GetCount() > 0 )
+ return &( m_list[0] );
+
+ return NULL;
+}
+
+
+SCH_SHEET_PATH* SCH_SHEET_LIST::GetNext()
+{
+ if( m_index < GetCount() )
+ m_index++;
+
+ return GetSheet( m_index );
+}
+
+
+SCH_SHEET_PATH* SCH_SHEET_LIST::GetLast()
+{
+ if( GetCount() == 0 )
+ return NULL;
+
+ m_index = GetCount() - 1;
+
+ return GetSheet( m_index );
+}
+
+
+SCH_SHEET_PATH* SCH_SHEET_LIST::GetPrevious()
+{
+ if( m_index == 0 )
+ return NULL;
+
+ m_index -= 1;
+
+ return GetSheet( m_index );
+}
+
+
+SCH_SHEET_PATH* SCH_SHEET_LIST::GetSheet( int aIndex ) const
+{
+ if( aIndex < GetCount() )
+ return &( m_list[aIndex] );
+
+ return NULL;
+}
+
+
+SCH_SHEET_PATH* SCH_SHEET_LIST::GetSheetByPath( const wxString aPath, bool aHumanReadable )
+{
+ SCH_SHEET_PATH* sheet = GetFirst();
+ wxString sheetPath;
+
+ while( sheet )
+ {
+ sheetPath = ( aHumanReadable ) ? sheet->PathHumanReadable() : sheet->Path();
+
+ if( sheetPath == aPath )
+ return sheet;
+
+ sheet = GetNext();
+ }
+
+ return NULL;
+}
+
+
+void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet )
+{
+ wxCHECK_RET( aSheet != NULL, wxT( "Cannot build sheet list from undefined sheet." ) );
+
+ if( aSheet == g_RootSheet )
+ m_isRootSheet = true;
+
+ if( m_list == NULL )
+ {
+ int count = aSheet->CountSheets();
+
+ m_count = count;
+ m_index = 0;
+ m_list = new SCH_SHEET_PATH[ count ];
+ m_currList.Clear();
+ }
+
+ m_currList.Push( aSheet );
+ m_list[m_index] = m_currList;
+ m_index++;
+
+ if( aSheet->GetScreen() )
+ {
+ EDA_ITEM* strct = m_currList.LastDrawList();
+
+ while( strct )
+ {
+ if( strct->Type() == SCH_SHEET_T )
+ {
+ SCH_SHEET* sheet = (SCH_SHEET*) strct;
+ BuildSheetList( sheet );
+ }
+
+ strct = strct->Next();
+ }
+ }
+
+ m_currList.Pop();
+}
+
+
+bool SCH_SHEET_LIST::IsModified()
+{
+ for( SCH_SHEET_PATH* sheet = GetFirst(); sheet; sheet = GetNext() )
+ {
+ if( sheet->LastScreen() && sheet->LastScreen()->IsModify() )
+ return true;
+ }
+
+ return false;
+}
+
+
+bool SCH_SHEET_LIST::IsAutoSaveRequired()
+{
+ for( SCH_SHEET_PATH* sheet = GetFirst(); sheet; sheet = GetNext() )
+ {
+ if( sheet->LastScreen() && sheet->LastScreen()->IsSave() )
+ return true;
+ }
+
+ return false;
+}
+
+
+void SCH_SHEET_LIST::ClearModifyStatus()
+{
+ for( SCH_SHEET_PATH* sheet = GetFirst(); sheet; sheet = GetNext() )
+ {
+ if( sheet->LastScreen() )
+ sheet->LastScreen()->ClrModify();
+ }
+}
+
+
+void SCH_SHEET_LIST::AnnotatePowerSymbols( PART_LIBS* aLibs )
+{
+ int ref = 1;
+
+ for( SCH_SHEET_PATH* path = GetFirst(); path; path = GetNext() )
+ path->AnnotatePowerSymbols( aLibs, &ref );
+}
+
+
+void SCH_SHEET_LIST::GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences,
+ bool aIncludePowerSymbols )
+{
+ for( SCH_SHEET_PATH* path = GetFirst(); path; path = GetNext() )
+ path->GetComponents( aLibs, aReferences, aIncludePowerSymbols );
+}
+
+void SCH_SHEET_LIST::GetMultiUnitComponents( PART_LIBS* aLibs,
+ SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols )
+{
+ for( SCH_SHEET_PATH* path = GetFirst(); path; path = GetNext() )
+ {
+ SCH_MULTI_UNIT_REFERENCE_MAP tempMap;
+ path->GetMultiUnitComponents( aLibs, tempMap );
+ BOOST_FOREACH( SCH_MULTI_UNIT_REFERENCE_MAP::value_type& pair, tempMap )
+ {
+ // Merge this list into the main one
+ unsigned n_refs = pair.second.GetCount();
+ for( unsigned thisRef = 0; thisRef < n_refs; ++thisRef )
+ {
+ aRefList[pair.first].AddItem( pair.second[thisRef] );
+ }
+ }
+ }
+}
+
+
+SCH_ITEM* SCH_SHEET_LIST::FindNextItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFoundIn,
+ SCH_ITEM* aLastItem, bool aWrap )
+{
+ bool hasWrapped = false;
+ bool firstItemFound = false;
+
+ SCH_ITEM* drawItem = NULL;
+ SCH_SHEET_PATH* sheet = GetFirst();
+
+ while( sheet )
+ {
+ drawItem = sheet->LastDrawList();
+
+ while( drawItem )
+ {
+ if( drawItem->Type() == aType )
+ {
+ if( aLastItem == NULL || firstItemFound )
+ {
+ if( aSheetFoundIn )
+ *aSheetFoundIn = sheet;
+
+ return drawItem;
+ }
+ else if( !firstItemFound && drawItem == aLastItem )
+ {
+ firstItemFound = true;
+ }
+ }
+
+ drawItem = drawItem->Next();
+ }
+
+ sheet = GetNext();
+
+ if( sheet == NULL && aLastItem && aWrap && !hasWrapped )
+ {
+ hasWrapped = true;
+ sheet = GetFirst();
+ }
+ }
+
+ return NULL;
+}
+
+
+SCH_ITEM* SCH_SHEET_LIST::FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFoundIn,
+ SCH_ITEM* aLastItem, bool aWrap )
+{
+ bool hasWrapped = false;
+ bool firstItemFound = false;
+ SCH_ITEM* drawItem = NULL;
+ SCH_SHEET_PATH* sheet = GetLast();
+
+ while( sheet )
+ {
+ drawItem = sheet->FirstDrawList();
+
+ while( drawItem )
+ {
+ if( drawItem->Type() == aType )
+ {
+ if( aLastItem == NULL || firstItemFound )
+ {
+ if( aSheetFoundIn )
+ *aSheetFoundIn = sheet;
+
+ return drawItem;
+ }
+ else if( !firstItemFound && drawItem == aLastItem )
+ {
+ firstItemFound = true;
+ }
+ }
+
+ drawItem = drawItem->Back();
+ }
+
+ sheet = GetPrevious();
+
+ if( sheet == NULL && aLastItem && aWrap && !hasWrapped )
+ {
+ hasWrapped = true;
+ sheet = GetLast();
+ }
+ }
+
+ return NULL;
+}
+
+
+bool SCH_SHEET_LIST::SetComponentFootprint( const wxString& aReference,
+ const wxString& aFootPrint, bool aSetVisible )
+{
+ bool found = false;
+
+ for( SCH_SHEET_PATH* path = GetFirst(); path; path = GetNext() )
+ found = path->SetComponentFootprint( aReference, aFootPrint, aSetVisible );
+
+ return found;
+}
+
+
+bool SCH_SHEET_LIST::IsComplexHierarchy() const
+{
+ wxString fileName;
+
+ for( int i = 0; i < m_count; i++ )
+ {
+ fileName = m_list[i].Last()->GetFileName();
+
+ for( int j = 0; j < m_count; j++ )
+ {
+ if( i == j )
+ continue;
+
+ if( fileName == m_list[j].Last()->GetFileName() )
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+bool SCH_SHEET_LIST::TestForRecursion( const SCH_SHEET_LIST& aSrcSheetHierarchy,
+ const wxString& aDestFileName ) const
+{
+ wxFileName rootFn = g_RootSheet->GetFileName();
+ wxFileName destFn = aDestFileName;
+
+ if( destFn.IsRelative() )
+ destFn.MakeAbsolute( rootFn.GetPath() );
+
+ // Test each SCH_SHEET_PATH in this SCH_SHEET_LIST for potential recursion.
+ for( int i = 0; i < m_count; i++ )
+ {
+ // Test each SCH_SHEET_PATH in the source sheet.
+ for( int j = 0; j < aSrcSheetHierarchy.GetCount(); j++ )
+ {
+ SCH_SHEET_PATH* sheetPath = aSrcSheetHierarchy.GetSheet( j );
+
+ for( unsigned k = 0; k < sheetPath->GetCount(); k++ )
+ {
+ if( m_list[i].TestForRecursion( sheetPath->GetSheet( k )->GetFileName(),
+ aDestFileName ) )
+ return true;
+ }
+ }
+ }
+
+ // The source sheet file can safely be added to the destination sheet file.
+ return false;
+}
+
+
+SCH_SHEET* SCH_SHEET_LIST::FindSheetByName( const wxString& aSheetName )
+{
+ for( int i = 0; i < m_count; i++ )
+ {
+ SCH_SHEET* sheet = m_list[i].FindSheetByName( aSheetName );
+
+ if( sheet )
+ return sheet;
+ }
+
+ return NULL;
+}
diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h
new file mode 100644
index 0000000..939d899
--- /dev/null
+++ b/eeschema/sch_sheet_path.h
@@ -0,0 +1,571 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_sheet_path.h
+ * @brief Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
+ */
+
+#ifndef CLASS_DRAWSHEET_PATH_H
+#define CLASS_DRAWSHEET_PATH_H
+
+#include <base_struct.h>
+
+
+/** Info about complex hierarchies handling:
+ * A hierarchical schematic uses sheets (hierarchical sheets) included in a
+ * given sheet. Each sheet corresponds to a schematic drawing handled by a
+ * SCH_SCREEN structure. A SCH_SCREEN structure contains drawings, and have
+ * a filename to write it's data. Also a SCH_SCREEN display a sheet number
+ * and the name of the sheet.
+ *
+ * In simple (and flat) hierarchies a sheet is linked to a SCH_SCREEN,
+ * and a SCH_SCREEN is used by only one hierarchical sheet.
+ *
+ * In complex hierarchies the same SCH_SCREEN (and its data) is shared between
+ * more than one sheet. Therefore subsheets (like subsheets in a SCH_SCREEN
+ * shared by many sheets) can be also shared. So the same SCH_SCREEN must
+ * handle different components references and parts selection depending on
+ * which sheet is currently selected, and how a given subsheet is selected.
+ * 2 sheets share the same SCH_SCREEN (the same drawings) if they have the
+ * same filename.
+ *
+ * In KiCad each component and sheet receives (when created) an unique
+ * identification called Time Stamp. So each sheet has 2 ids: its time stamp
+ * (that cannot change) and its name ( that can be edited and therefore is
+ * not reliable for strong identification). KiCad uses Time Stamp ( a unique
+ * 32 bit id), to identify sheets in hierarchies.
+ * A given sheet in a hierarchy is fully labeled by its path (or sheet path)
+ * that is the list of time stamp found to access it through the hierarchy
+ * the root sheet is /. All other sheets have a path like /1234ABCD or
+ * /4567FEDC/AA2233DD/. This path can be displayed as human readable sheet
+ * name like: / or /sheet1/include_sheet/ or /sheet2/include_sheet/
+ *
+ * So to know for a given SCH_SCREEN (a given schematic drawings) we must:
+ * 1) Handle all references possibilities.
+ * 2) When acceded by a given selected sheet, display (update) the
+ * corresponding references and sheet path
+ *
+ * The class SCH_SHEET_PATH handles paths used to access a sheet. The class
+ * SCH_SHEET_LIST allows to handle the full (or partial) list of sheets and
+ * their paths in a complex hierarchy. The class EDA_ScreenList allow to
+ * handle the list of SCH_SCREEN. It is useful to clear or save data,
+ * but is not suitable to handle the full complex hierarchy possibilities
+ * (usable in flat and simple hierarchies).
+ */
+
+
+class wxFindReplaceData;
+class SCH_SCREEN;
+class SCH_MARKER;
+class SCH_SHEET;
+class SCH_ITEM;
+class SCH_REFERENCE_LIST;
+class PART_LIBS;
+
+#define SHEET_NOT_FOUND -1
+
+
+/**
+ * Type SCH_MULTI_UNIT_REFERENCE_MAP
+ * is used to create a map of reference designators for multi-unit parts.
+ */
+typedef std::map<wxString, SCH_REFERENCE_LIST> SCH_MULTI_UNIT_REFERENCE_MAP;
+
+/**
+ * Class SCH_SHEET_PATH
+ * handles access to a sheet by way of a path.
+ * <p>
+ * The member m_sheets stores the list of sheets from the first (usually
+ * g_RootSheet) to a given sheet in last position.
+ * The _last_ sheet is usually the sheet we want to select or reach (which is
+ * what the function Last() returns).
+ * Others sheets constitute the "path" from the first to the last sheet.
+ * </p>
+ */
+class SCH_SHEET_PATH
+{
+#define DSLSZ 32 // Max number of levels for a sheet path
+
+ SCH_SHEET* m_sheets[ DSLSZ ];
+ unsigned m_numSheets;
+
+public:
+ SCH_SHEET_PATH();
+
+ void Clear()
+ {
+ m_numSheets = 0;
+ }
+
+ unsigned GetCount()
+ {
+ return m_numSheets;
+ }
+
+ SCH_SHEET* GetSheet( unsigned index )
+ {
+ if( index < m_numSheets )
+ return m_sheets[index];
+
+ return NULL;
+ }
+
+ /**
+ * Function Cmp
+ * Compare if this is the same sheet path as aSheetPathToTest
+ * @param aSheetPathToTest = sheet path to compare
+ * @return 1 if this sheet path has more sheets than aSheetPathToTest,
+ * -1 if this sheet path has fewer sheets than aSheetPathToTest,
+ * or 0 if same
+ */
+ int Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const;
+
+ /**
+ * Function Last
+ * returns a pointer to the last sheet of the list
+ * One can see the others sheet as the "path" to reach this last sheet
+ */
+ SCH_SHEET* Last() const;
+
+ /**
+ * Function LastScreen
+ * @return the SCH_SCREEN relative to the last sheet in list
+ */
+ SCH_SCREEN* LastScreen() const;
+
+ /**
+ * Function LastDrawList
+ * @return a pointer to the first schematic item handled by the
+ * SCH_SCREEN relative to the last sheet in list
+ */
+ SCH_ITEM* LastDrawList() const;
+
+ /**
+ * Get the last schematic item relative to the first sheet in the list.
+ *
+ * @return Last schematic item relative to the first sheet in the list if list
+ * is not empty. Otherwise NULL.
+ */
+ SCH_ITEM* FirstDrawList() const;
+
+ /**
+ * Function Push
+ * store (push) aSheet in list
+ * @param aSheet = pointer to the SCH_SHEET to store in list
+ * Push is used when entered a sheet to select or analyze it
+ * This is like cd &ltdirectory&gt in directories navigation
+ */
+ void Push( SCH_SHEET* aSheet );
+
+ /**
+ * Function Pop
+ * retrieves (pop) the last entered sheet and remove it from list
+ * @return a SCH_SHEET* pointer to the removed sheet in list
+ * Pop is used when leaving a sheet after a selection or analyze
+ * This is like cd .. in directories navigation
+ */
+ SCH_SHEET* Pop();
+
+ /**
+ * Function Path
+ * the path uses the time stamps which do not changes even when editing
+ * sheet parameters
+ * a path is something like / (root) or /34005677 or /34005677/00AE4523
+ */
+ wxString Path() const;
+
+ /**
+ * Function PathHumanReadable
+ * returns the sheet path in a human readable form, i.e. as a path made
+ * from sheet names. The the "normal" path instead uses the time
+ * stamps in the path. (Time stamps do not change even when editing
+ * sheet parameters).
+ */
+ wxString PathHumanReadable() const;
+
+ /**
+ * Function BuildSheetPathInfoFromSheetPathValue
+ * Fill this with data to access to the hierarchical sheet known by its path \a aPath
+ * @param aPath = path of the sheet to reach (in non human readable format)
+ * @param aFound - Please document me.
+ * @return true if success else false
+ */
+ bool BuildSheetPathInfoFromSheetPathValue( const wxString& aPath, bool aFound = false );
+
+ /**
+ * Function UpdateAllScreenReferences
+ * updates the reference and the m_Multi parameter (part selection) for all
+ * components on a screen depending on the actual sheet path.
+ * Mandatory in complex hierarchies because sheets use the same screen
+ * (basic schematic)
+ * but with different references and part selections according to the
+ * displayed sheet
+ */
+ void UpdateAllScreenReferences();
+
+ /**
+ * Function AnnotatePowerSymbols
+ * annotates the power symbols only starting at \a aReference in the sheet path.
+ * @param aLibs the library list to use
+ * @param aReference A pointer to the number for the reference designator of the
+ * first power symbol to be annotated. If the pointer is NULL
+ * the annotation starts at 1. The number is incremented for
+ * each power symbol annotated.
+ */
+ void AnnotatePowerSymbols( PART_LIBS* aLibs, int* aReference );
+
+ /**
+ * Function GetComponents
+ * adds a SCH_REFERENCE() object to \a aReferences for each component in the sheet.
+ * @param aLibs the library list to use
+ * @param aReferences List of references to populate.
+ * @param aIncludePowerSymbols : false to only get normal components.
+ */
+ void GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences,
+ bool aIncludePowerSymbols = true );
+
+ /**
+ * Function GetMultiUnitComponents
+ * adds a SCH_REFERENCE_LIST object to \a aRefList for each same-reference set of
+ * multi-unit parts in the sheet. The map key for each element will be the
+ * reference designator.
+ * @param aLibs the library list to use
+ * @param aRefList Map of reference designators to reference lists
+ * @param aIncludePowerSymbols : false to only get normal components.
+ */
+ void GetMultiUnitComponents( PART_LIBS* aLibs, SCH_MULTI_UNIT_REFERENCE_MAP &aRefList,
+ bool aIncludePowerSymbols = true );
+
+ /**
+ * Function SetFootprintField
+ * searches last sheet in the path for a component with \a aReference and set the footprint
+ * field to \a aFootPrint if found.
+ *
+ * @param aReference The reference designator of the component.
+ * @param aFootPrint The value to set the footprint field.
+ * @param aSetVisible The value to set the field visibility flag.
+ * @return True if \a aReference was found otherwise false.
+ */
+ bool SetComponentFootprint( const wxString& aReference, const wxString& aFootPrint,
+ bool aSetVisible );
+
+ /**
+ * Find the next schematic item in this sheet object.
+ *
+ * @param aType - The type of schematic item object to search for.
+ * @param aLastItem - Start search from aLastItem. If no aLastItem, search from
+ * the beginning of the list.
+ * @param aWrap - Wrap around the end of the list to find the next item if aLastItem
+ * is defined.
+ * @return - The next schematic item if found. Otherwise, NULL is returned.
+ */
+ SCH_ITEM* FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ) const;
+
+ /**
+ * Find the previous schematic item in this sheet path object.
+ *
+ * @param aType - The type of schematic item object to search for.
+ * @param aLastItem - Start search from aLastItem. If no aLastItem, search from
+ * the end of the list.
+ * @param aWrap - Wrap around the beginning of the list to find the next item if aLastItem
+ * is defined.
+ * @return - The previous schematic item if found. Otherwise, NULL is returned.
+ */
+ SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ) const;
+
+ /**
+ * Function TestForRecursion
+ *
+ * test the SCH_SHEET_PATH file names to check adding the sheet stored in the file
+ * \a aSrcFileName to the sheet stored in file \a aDestFileName will cause a sheet
+ * path recursion.
+ *
+ * @param aSrcFileName is the source file name of the sheet add to \a aDestFileName.
+ * @param aDestFileName is the file name of the destination sheet for \a aSrcFileName.
+ * @return true if \a aFileName will cause recursion in the sheet path. Otherwise false.
+ */
+ bool TestForRecursion( const wxString& aSrcFileName, const wxString& aDestFileName ) const;
+
+ int FindSheet( const wxString& aFileName ) const;
+
+ /**
+ * Function FindSheetByName
+ *
+ * searches the #SCH_SHEET_PATH for a sheet named \a aSheetName.
+ *
+ * @param aSheetName is the name of the sheet to find.
+ * @return a pointer to the sheet named \a aSheetName if found or NULL if not found.
+ */
+ SCH_SHEET* FindSheetByName( const wxString& aSheetName );
+
+ SCH_SHEET_PATH& operator=( const SCH_SHEET_PATH& d1 );
+
+ bool operator==( const SCH_SHEET_PATH& d1 ) const;
+
+ bool operator!=( const SCH_SHEET_PATH& d1 ) const { return !( *this == d1 ) ; }
+};
+
+
+/**
+ * Class SCH_SHEET_LIST
+ * handles the list of Sheets in a hierarchy.
+ * Sheets are not unique, there can be many sheets with the same
+ * filename and the same SCH_SCREEN reference.
+ * The schematic (SCH_SCREEN) is shared between these sheets,
+ * and component references are specific to a sheet path.
+ * When a sheet is entered, component references and sheet number are updated.
+ */
+class SCH_SHEET_LIST
+{
+private:
+ SCH_SHEET_PATH* m_list;
+ int m_count; /* Number of sheets included in hierarchy,
+ * starting at the given sheet in constructor .
+ * the given sheet is counted
+ */
+ int m_index; /* internal variable to handle GetNext(): cleared by
+ * GetFirst() and incremented by GetNext() after
+ * returning the next item in m_list. Also used for
+ * internal calculations in BuildSheetList()
+ */
+ bool m_isRootSheet;
+ SCH_SHEET_PATH m_currList;
+
+public:
+
+ /**
+ * Constructor
+ * builds the list of sheets from aSheet.
+ * If aSheet == NULL (default) build the whole list of sheets in hierarchy.
+ * So usually call it with no parameter.
+ */
+ SCH_SHEET_LIST( SCH_SHEET* aSheet = NULL );
+
+ ~SCH_SHEET_LIST()
+ {
+ if( m_list )
+ delete[] m_list;
+
+ m_list = NULL;
+ }
+
+ /**
+ * Function GetCount
+ * @return the number of sheets in list:
+ * usually the number of sheets found in the whole hierarchy
+ */
+ int GetCount() const { return m_count; }
+
+ /**
+ * Function GetIndex
+ * @return the last selected screen index.
+ */
+ int GetIndex() const { return m_index; }
+
+ /**
+ * Function GetFirst
+ * @return the first item (sheet) in m_list and prepare calls to GetNext()
+ */
+ SCH_SHEET_PATH* GetFirst();
+
+ /**
+ * Function GetNext
+ * @return the next item (sheet) in m_list or NULL if no more item in
+ * sheet list
+ */
+ SCH_SHEET_PATH* GetNext();
+
+ /**
+ * Function GetLast
+ * returns the last sheet in the sheet list.
+ *
+ * @return Last sheet in the list or NULL if sheet list is empty.
+ */
+ SCH_SHEET_PATH* GetLast();
+
+ /**
+ * Function GetPrevious
+ * returns the previous sheet in the sheet list.
+ *
+ * @return The previous sheet in the sheet list or NULL if already at the
+ * beginning of the list.
+ */
+ SCH_SHEET_PATH* GetPrevious();
+
+ /**
+ * Function GetSheet
+ *
+ * @param aIndex A index in sheet list to get the sheet.
+ * @return the sheet at \a aIndex position in m_list or NULL if \a aIndex is
+ * outside the bounds of the index list.
+ */
+ SCH_SHEET_PATH* GetSheet( int aIndex ) const;
+
+ /**
+ * Function GetSheetByPath
+ * returns a sheet matching the path name in \a aPath.
+ *
+ * @param aPath A wxString object containing path of the sheet to get.
+ * @param aHumanReadable True uses the human readable path for comparison.
+ * False uses the timestamp generated path.
+ * @return The sheet that matches \a aPath or NULL if no sheet matching
+ * \a aPath is found.
+ */
+ SCH_SHEET_PATH* GetSheetByPath( const wxString aPath, bool aHumanReadable = true );
+
+ /**
+ * Function IsModified
+ * checks the entire hierarchy for any modifications.
+ * @returns True if the hierarchy is modified otherwise false.
+ */
+ bool IsModified();
+
+ /**
+ * Function IsAutoSaveRequired
+ * checks the entire hierarchy for any modifications that require auto save.
+ * @return True if the hierarchy is modified otherwise false.
+ */
+ bool IsAutoSaveRequired();
+
+ void ClearModifyStatus();
+
+ /**
+ * Function AnnotatePowerSymbols
+ * clear and annotates the entire hierarchy of the sheet path list.
+ * @param aLib the library list to use
+ */
+ void AnnotatePowerSymbols( PART_LIBS* aLib );
+
+ /**
+ * Function GetComponents
+ * adds a SCH_REFERENCE() object to \a aReferences for each component in the list
+ * of sheets.
+ * @param aLibs the library list to use
+ * @param aReferences List of references to populate.
+ * @param aIncludePowerSymbols Set to false to only get normal components.
+ */
+ void GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true );
+
+ /**
+ * Function GetMultiUnitComponents
+ * adds a SCH_REFERENCE_LIST object to \a aRefList for each same-reference set of
+ * multi-unit parts in the list of sheets. The map key for each element will be the
+ * reference designator.
+ * @param aLibs the library list to use
+ * @param aRefList Map of reference designators to reference lists
+ * @param aIncludePowerSymbols Set to false to only get normal components.
+ */
+ void GetMultiUnitComponents( PART_LIBS* aLibs, SCH_MULTI_UNIT_REFERENCE_MAP &aRefList,
+ bool aIncludePowerSymbols = true );
+
+ /**
+ * Function FindNextItem
+ * searches the entire schematic for the next schematic object.
+ *
+ * @param aType - The type of schematic item to find.
+ * @param aSheetFound - The sheet the item was found in. NULL if the next item
+ * is not found.
+ * @param aLastItem - Find next item after aLastItem if not NULL.
+ * @param aWrap - Wrap past around the end of the list of sheets.
+ * @return If found, Returns the next schematic item. Otherwise, returns NULL.
+ */
+ SCH_ITEM* FindNextItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFound = NULL,
+ SCH_ITEM* aLastItem = NULL, bool aWrap = true );
+
+ /**
+ * Function FindPreviousItem
+ * searches the entire schematic for the previous schematic item.
+ *
+ * @param aType - The type of schematic item to find.
+ * @param aSheetFound - The sheet the item was found in. NULL if the previous item
+ * is not found.
+ * @param aLastItem - Find the previous item before aLastItem if not NULL.
+ * @param aWrap - Wrap past around the beginning of the list of sheets.
+ * @return If found, the previous schematic item. Otherwise, NULL.
+ */
+ SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFound = NULL,
+ SCH_ITEM* aLastItem = NULL, bool aWrap = true );
+
+ /**
+ * Function SetFootprintField
+ * searches all the sheets for a component with \a aReference and set the footprint
+ * field to \a aFootPrint if found.
+ *
+ * @param aReference The reference designator of the component.
+ * @param aFootPrint The value to set the footprint field.
+ * @param aSetVisible The value to set the field visibility flag.
+ * @return True if \a aReference was found otherwise false.
+ */
+ bool SetComponentFootprint( const wxString& aReference, const wxString& aFootPrint,
+ bool aSetVisible );
+
+ /**
+ * Function IsComplexHierarchy
+ * searches all of the sheets for duplicate files names which indicates a complex
+ * hierarchy.
+ *
+ * @return true if the #SCH_SHEET_LIST is a complex hierarchy.
+ */
+ bool IsComplexHierarchy() const;
+
+ /**
+ * Function TestForRecursion
+ *
+ * test every SCH_SHEET_PATH in the SCH_SHEET_LIST to verify if adding the sheets stored
+ * in \a aSrcSheetHierarchy to the sheet stored in \a aDestFileName will cause recursion.
+ *
+ * @param aSrcSheetHierarchy is the SCH_SHEET_LIST of the source sheet add to \a aDestFileName.
+ * @param aDestFileName is the file name of the destination sheet for \a aSrcFileName.
+ * @return true if \a aFileName will cause recursion in the sheet path. Otherwise false.
+ */
+ bool TestForRecursion( const SCH_SHEET_LIST& aSrcSheetHierarchy,
+ const wxString& aDestFileName ) const;
+
+ /**
+ * Function FindSheetByName
+ *
+ * searches the entire #SCH_SHEET_LIST for a sheet named \a aSheetName.
+ *
+ * @param aSheetName is the name of the sheet to find.
+ * @return a pointer to the sheet named \a aSheetName if found or NULL if not found.
+ */
+ SCH_SHEET* FindSheetByName( const wxString& aSheetName );
+
+private:
+
+ /**
+ * Function BuildSheetList
+ * builds the list of sheets and their sheet path from \a aSheet.
+ * If \a aSheet is the root sheet, the full sheet path and sheet list are built.
+ *
+ * @param aSheet is the starting sheet from which the list is built, or NULL
+ * indicating that g_RootSheet should be used.
+ * @throw std::bad_alloc if the memory for the sheet path list could not be allocated.
+ */
+ void BuildSheetList( SCH_SHEET* aSheet );
+};
+
+#endif // CLASS_DRAWSHEET_PATH_H
diff --git a/eeschema/sch_sheet_pin.cpp b/eeschema/sch_sheet_pin.cpp
new file mode 100644
index 0000000..b4c7697
--- /dev/null
+++ b/eeschema/sch_sheet_pin.cpp
@@ -0,0 +1,526 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2006 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_sheet_pin.cpp
+ * @brief Implementation of the SCH_SHEET_PIN class.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <drawtxt.h>
+#include <plot_common.h>
+#include <trigo.h>
+#include <richio.h>
+#include <schframe.h>
+
+#include <general.h>
+#include <sch_sheet.h>
+#include <kicad_string.h>
+
+
+SCH_SHEET_PIN::SCH_SHEET_PIN( SCH_SHEET* parent, const wxPoint& pos, const wxString& text ) :
+ SCH_HIERLABEL( pos, text, SCH_SHEET_PIN_T )
+{
+ SetParent( parent );
+ wxASSERT( parent );
+ m_Layer = LAYER_SHEETLABEL;
+ m_Pos = pos;
+
+ if( parent->IsVerticalOrientation() )
+ SetEdge( SHEET_TOP_SIDE );
+ else
+ SetEdge( SHEET_LEFT_SIDE );
+
+ m_shape = NET_INPUT;
+ m_isDangling = true;
+ m_number = 2;
+}
+
+
+EDA_ITEM* SCH_SHEET_PIN::Clone() const
+{
+ return new SCH_SHEET_PIN( *this );
+}
+
+
+void SCH_SHEET_PIN::Draw( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC,
+ const wxPoint& aOffset,
+ GR_DRAWMODE aDraw_mode,
+ EDA_COLOR_T aColor )
+{
+ // The icon selection is handle by the virtual method CreateGraphicShape
+ // called by ::Draw
+ SCH_HIERLABEL::Draw( aPanel, aDC, aOffset, aDraw_mode, aColor );
+}
+
+
+void SCH_SHEET_PIN::SwapData( SCH_ITEM* aItem )
+{
+ wxCHECK_RET( aItem->Type() == SCH_SHEET_PIN_T,
+ wxString::Format( wxT( "SCH_SHEET_PIN object cannot swap data with %s object." ),
+ GetChars( aItem->GetClass() ) ) );
+
+ SCH_SHEET_PIN* pin = ( SCH_SHEET_PIN* ) aItem;
+ SCH_TEXT::SwapData( (SCH_TEXT*) pin );
+ int tmp = pin->GetNumber();
+ pin->SetNumber( GetNumber() );
+ SetNumber( tmp );
+ SHEET_SIDE stmp = pin->GetEdge();
+ pin->SetEdge( GetEdge() );
+ SetEdge( stmp );
+}
+
+
+bool SCH_SHEET_PIN::operator==( const SCH_SHEET_PIN* aPin ) const
+{
+ return aPin == this;
+}
+
+
+int SCH_SHEET_PIN::GetPenSize() const
+{
+ return GetDefaultLineThickness();
+}
+
+
+void SCH_SHEET_PIN::SetNumber( int aNumber )
+{
+ wxASSERT( aNumber >= 2 );
+
+ m_number = aNumber;
+}
+
+
+void SCH_SHEET_PIN::SetEdge( SCH_SHEET_PIN::SHEET_SIDE aEdge )
+{
+ SCH_SHEET* Sheet = GetParent();
+
+ // use SHEET_UNDEFINED_SIDE to adjust text orientation without changing edge
+
+ switch( aEdge )
+ {
+ case SHEET_LEFT_SIDE:
+ m_edge = aEdge;
+ m_Pos.x = Sheet->m_pos.x;
+ SetOrientation( 2 ); /* Orientation horiz inverse */
+ break;
+
+ case SHEET_RIGHT_SIDE:
+ m_edge = aEdge;
+ m_Pos.x = Sheet->m_pos.x + Sheet->m_size.x;
+ SetOrientation( 0 ); /* Orientation horiz normal */
+ break;
+
+ case SHEET_TOP_SIDE:
+ m_edge = aEdge;
+ m_Pos.y = Sheet->m_pos.y;
+ SetOrientation( 3 ); /* Orientation vert BOTTOM */
+ break;
+
+ case SHEET_BOTTOM_SIDE:
+ m_edge = aEdge;
+ m_Pos.y = Sheet->m_pos.y + Sheet->m_size.y;
+ SetOrientation( 1 ); /* Orientation vert UP */
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+enum SCH_SHEET_PIN::SHEET_SIDE SCH_SHEET_PIN::GetEdge() const
+{
+ return m_edge;
+}
+
+
+void SCH_SHEET_PIN::ConstrainOnEdge( wxPoint Pos )
+{
+ SCH_SHEET* sheet = GetParent();
+
+ if( sheet == NULL )
+ return;
+
+ wxPoint center = sheet->m_pos + ( sheet->m_size / 2 );
+
+ if( m_edge == SHEET_LEFT_SIDE || m_edge == SHEET_RIGHT_SIDE )
+ {
+ if( Pos.x > center.x )
+ {
+ SetEdge( SHEET_RIGHT_SIDE );
+ }
+ else
+ {
+ SetEdge( SHEET_LEFT_SIDE );
+ }
+
+ m_Pos.y = Pos.y;
+
+ if( m_Pos.y < sheet->m_pos.y )
+ m_Pos.y = sheet->m_pos.y;
+
+ if( m_Pos.y > (sheet->m_pos.y + sheet->m_size.y) )
+ m_Pos.y = sheet->m_pos.y + sheet->m_size.y;
+ }
+ else /* vertical sheetpin*/
+ {
+ if( Pos.y > center.y )
+ {
+ SetEdge( SHEET_BOTTOM_SIDE ); //bottom
+ }
+ else
+ {
+ SetEdge( SHEET_TOP_SIDE ); //top
+ }
+
+ m_Pos.x = Pos.x;
+
+ if( m_Pos.x < sheet->m_pos.x )
+ m_Pos.x = sheet->m_pos.x;
+
+ if( m_Pos.x > (sheet->m_pos.x + sheet->m_size.x) )
+ m_Pos.x = sheet->m_pos.x + sheet->m_size.x;
+ }
+}
+
+
+bool SCH_SHEET_PIN::Save( FILE* aFile ) const
+{
+ int type = 'U', side = 'L';
+
+ if( m_Text.IsEmpty() )
+ return true;
+
+ switch( m_edge )
+ {
+ default:
+ case SHEET_LEFT_SIDE: //pin on left side
+ side = 'L';
+ break;
+
+ case SHEET_RIGHT_SIDE: //pin on right side
+ side = 'R';
+ break;
+
+ case SHEET_TOP_SIDE: //pin on top side
+ side = 'T';
+ break;
+
+ case SHEET_BOTTOM_SIDE: //pin on bottom side
+ side = 'B';
+ break;
+ }
+
+ switch( m_shape )
+ {
+ case NET_INPUT:
+ type = 'I'; break;
+
+ case NET_OUTPUT:
+ type = 'O'; break;
+
+ case NET_BIDI:
+ type = 'B'; break;
+
+ case NET_TRISTATE:
+ type = 'T'; break;
+
+ case NET_UNSPECIFIED:
+ type = 'U'; break;
+ }
+
+ if( fprintf( aFile, "F%d %s %c %c %-3d %-3d %-3d\n", m_number,
+ EscapedUTF8( m_Text ).c_str(), // supplies wrapping quotes
+ type, side, m_Pos.x, m_Pos.y,
+ m_Size.x ) == EOF )
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+bool SCH_SHEET_PIN::Load( LINE_READER& aLine, wxString& aErrorMsg )
+{
+ int size;
+ char number[256];
+ char name[256];
+ char connectType[256];
+ char sheetSide[256];
+ char* line = aLine.Line();
+ char* cp;
+
+ static const char delims[] = " \t";
+
+ // Read coordinates.
+ // D( printf( "line: \"%s\"\n", line );)
+
+ cp = strtok( line, delims );
+
+ strncpy( number, cp, sizeof(number) );
+ number[sizeof(number)-1] = 0;
+
+ cp += strlen( number ) + 1;
+
+ cp += ReadDelimitedText( name, cp, sizeof(name) );
+
+ cp = strtok( cp, delims );
+ strncpy( connectType, cp, sizeof(connectType) );
+ connectType[sizeof(connectType)-1] = 0;
+
+ cp = strtok( NULL, delims );
+ strncpy( sheetSide, cp, sizeof(sheetSide) );
+ sheetSide[sizeof(sheetSide)-1] = 0;
+
+ cp += strlen( sheetSide ) + 1;
+
+ int r = sscanf( cp, "%d %d %d", &m_Pos.x, &m_Pos.y, &size );
+ if( r != 3 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file sheet hierarchical label error at line %d.\n" ),
+ aLine.LineNumber() );
+
+ aErrorMsg << FROM_UTF8( line );
+ return false;
+ }
+
+ m_Text = FROM_UTF8( name );
+
+ if( size == 0 )
+ size = GetDefaultTextSize();
+
+ m_Size.x = m_Size.y = size;
+
+ switch( connectType[0] )
+ {
+ case 'I':
+ m_shape = NET_INPUT;
+ break;
+
+ case 'O':
+ m_shape = NET_OUTPUT;
+ break;
+
+ case 'B':
+ m_shape = NET_BIDI;
+ break;
+
+ case 'T':
+ m_shape = NET_TRISTATE;
+ break;
+
+ case 'U':
+ m_shape = NET_UNSPECIFIED;
+ break;
+ }
+
+ switch( sheetSide[0] )
+ {
+ case 'R' : /* pin on right side */
+ SetEdge( SHEET_RIGHT_SIDE );
+ break;
+
+ case 'T' : /* pin on top side */
+ SetEdge( SHEET_TOP_SIDE );
+ break;
+
+ case 'B' : /* pin on bottom side */
+ SetEdge( SHEET_BOTTOM_SIDE );
+ break;
+
+ case 'L' : /* pin on left side */
+ default :
+ SetEdge( SHEET_LEFT_SIDE );
+ break;
+ }
+
+ return true;
+}
+
+
+bool SCH_SHEET_PIN::Matches( wxFindReplaceData& aSearchData,
+ void* aAuxData, wxPoint* aFindLocation )
+{
+ wxCHECK_MSG( GetParent() != NULL, false,
+ wxT( "Sheet pin " ) + m_Text + wxT( " does not have a parent sheet!" ) );
+
+ wxLogTrace( traceFindItem, wxT( " child item " ) + GetSelectMenuText() );
+
+ if( SCH_ITEM::Matches( m_Text, aSearchData ) )
+ {
+ if( aFindLocation )
+ *aFindLocation = GetBoundingBox().Centre();
+
+ return true;
+ }
+
+ return false;
+}
+
+
+void SCH_SHEET_PIN::MirrorX( int aXaxis_position )
+{
+ int p = m_Pos.y - aXaxis_position;
+
+ m_Pos.y = aXaxis_position - p;
+
+ switch( m_edge )
+ {
+ case SHEET_TOP_SIDE:
+ SetEdge( SHEET_BOTTOM_SIDE );
+ break;
+
+ case SHEET_BOTTOM_SIDE:
+ SetEdge( SHEET_TOP_SIDE );
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void SCH_SHEET_PIN::MirrorY( int aYaxis_position )
+{
+ int p = m_Pos.x - aYaxis_position;
+
+ m_Pos.x = aYaxis_position - p;
+
+ switch( m_edge )
+ {
+ case SHEET_LEFT_SIDE:
+ SetEdge( SHEET_RIGHT_SIDE );
+ break;
+
+ case SHEET_RIGHT_SIDE:
+ SetEdge( SHEET_LEFT_SIDE );
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void SCH_SHEET_PIN::Rotate( wxPoint aPosition )
+{
+ RotatePoint( &m_Pos, aPosition, 900 );
+
+ switch( m_edge )
+ {
+ case SHEET_LEFT_SIDE: //pin on left side
+ SetEdge( SHEET_BOTTOM_SIDE );
+ break;
+
+ case SHEET_RIGHT_SIDE: //pin on right side
+ SetEdge( SHEET_TOP_SIDE );
+ break;
+
+ case SHEET_TOP_SIDE: //pin on top side
+ SetEdge( SHEET_LEFT_SIDE );
+ break;
+
+ case SHEET_BOTTOM_SIDE: //pin on bottom side
+ SetEdge( SHEET_RIGHT_SIDE );
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void SCH_SHEET_PIN::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& aPos )
+{
+ /* This is the same icon shapes as SCH_HIERLABEL
+ * but the graphic icon is slightly different in 2 cases:
+ * for INPUT type the icon is the OUTPUT shape of SCH_HIERLABEL
+ * for OUTPUT type the icon is the INPUT shape of SCH_HIERLABEL
+ */
+ int tmp = m_shape;
+
+ switch( m_shape )
+ {
+ case NET_INPUT:
+ m_shape = NET_OUTPUT;
+ break;
+
+ case NET_OUTPUT:
+ m_shape = NET_INPUT;
+ break;
+
+ default:
+ break;
+ }
+
+ SCH_HIERLABEL::CreateGraphicShape( aPoints, aPos );
+ m_shape = tmp;
+}
+
+
+void SCH_SHEET_PIN::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
+{
+ DANGLING_END_ITEM item( SHEET_LABEL_END, this, m_Pos );
+ aItemList.push_back( item );
+}
+
+
+wxString SCH_SHEET_PIN::GetSelectMenuText() const
+{
+ wxString tmp;
+ tmp.Printf( _( "Hierarchical Sheet Pin %s" ), GetChars( ShortenedShownText() ) );
+ return tmp;
+}
+
+
+bool SCH_SHEET_PIN::HitTest( const wxPoint& aPoint, int aAccuracy ) const
+{
+ EDA_RECT rect = GetBoundingBox();
+
+ rect.Inflate( aAccuracy );
+
+ return rect.Contains( aPoint );
+}
+
+
+#if defined(DEBUG)
+
+void SCH_SHEET_PIN::Show( int nestLevel, std::ostream& os ) const
+{
+ // XML output:
+ wxString s = GetClass();
+
+ NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << ">"
+ << " pin_name=\"" << TO_UTF8( m_Text )
+ << '"' << "/>\n" << std::flush;
+
+// NestedSpace( nestLevel, os ) << "</" << s.Lower().mb_str() << ">\n";
+}
+
+#endif
diff --git a/eeschema/sch_text.cpp b/eeschema/sch_text.cpp
new file mode 100644
index 0000000..c84852c
--- /dev/null
+++ b/eeschema/sch_text.cpp
@@ -0,0 +1,1777 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_text.cpp
+ * @brief Code for handling schematic sheet labels.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <trigo.h>
+#include <eeschema_id.h>
+#include <class_drawpanel.h>
+#include <drawtxt.h>
+#include <schframe.h>
+#include <plot_common.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <protos.h>
+#include <sch_text.h>
+#include <class_netlist_object.h>
+
+
+extern void IncrementLabelMember( wxString& name, int aIncrement );
+
+
+/* Names of sheet label types. */
+const char* SheetLabelType[] =
+{
+ "Input",
+ "Output",
+ "BiDi",
+ "3State",
+ "UnSpc",
+ "???"
+};
+
+/* Coding polygons for global symbol graphic shapes.
+ * the first parml is the number of corners
+ * others are the corners coordinates in reduced units
+ * the real coordinate is the reduced coordinate * text half size
+ */
+static int TemplateIN_HN[] = { 6, 0, 0, -1, -1, -2, -1, -2, 1, -1, 1, 0, 0 };
+static int TemplateIN_HI[] = { 6, 0, 0, 1, 1, 2, 1, 2, -1, 1, -1, 0, 0 };
+static int TemplateIN_UP[] = { 6, 0, 0, 1, -1, 1, -2, -1, -2, -1, -1, 0, 0 };
+static int TemplateIN_BOTTOM[] = { 6, 0, 0, 1, 1, 1, 2, -1, 2, -1, 1, 0, 0 };
+
+static int TemplateOUT_HN[] = { 6, -2, 0, -1, 1, 0, 1, 0, -1, -1, -1, -2, 0 };
+static int TemplateOUT_HI[] = { 6, 2, 0, 1, -1, 0, -1, 0, 1, 1, 1, 2, 0 };
+static int TemplateOUT_UP[] = { 6, 0, -2, 1, -1, 1, 0, -1, 0, -1, -1, 0, -2 };
+static int TemplateOUT_BOTTOM[] = { 6, 0, 2, 1, 1, 1, 0, -1, 0, -1, 1, 0, 2 };
+
+static int TemplateUNSPC_HN[] = { 5, 0, -1, -2, -1, -2, 1, 0, 1, 0, -1 };
+static int TemplateUNSPC_HI[] = { 5, 0, -1, 2, -1, 2, 1, 0, 1, 0, -1 };
+static int TemplateUNSPC_UP[] = { 5, 1, 0, 1, -2, -1, -2, -1, 0, 1, 0 };
+static int TemplateUNSPC_BOTTOM[] = { 5, 1, 0, 1, 2, -1, 2, -1, 0, 1, 0 };
+
+static int TemplateBIDI_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
+static int TemplateBIDI_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
+static int TemplateBIDI_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
+static int TemplateBIDI_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
+
+static int Template3STATE_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
+static int Template3STATE_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
+static int Template3STATE_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
+static int Template3STATE_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
+
+static int* TemplateShape[5][4] =
+{
+ { TemplateIN_HN, TemplateIN_UP, TemplateIN_HI, TemplateIN_BOTTOM },
+ { TemplateOUT_HN, TemplateOUT_UP, TemplateOUT_HI, TemplateOUT_BOTTOM },
+ { TemplateBIDI_HN, TemplateBIDI_UP, TemplateBIDI_HI, TemplateBIDI_BOTTOM },
+ { Template3STATE_HN, Template3STATE_UP, Template3STATE_HI, Template3STATE_BOTTOM },
+ { TemplateUNSPC_HN, TemplateUNSPC_UP, TemplateUNSPC_HI, TemplateUNSPC_BOTTOM }
+};
+
+
+SCH_TEXT::SCH_TEXT( const wxPoint& pos, const wxString& text, KICAD_T aType ) :
+ SCH_ITEM( NULL, aType ),
+ EDA_TEXT( text )
+{
+ m_Layer = LAYER_NOTES;
+ m_Pos = pos;
+ m_shape = 0;
+ m_isDangling = false;
+ m_MultilineAllowed = true;
+ m_schematicOrientation = 0;
+}
+
+
+SCH_TEXT::SCH_TEXT( const SCH_TEXT& aText ) :
+ SCH_ITEM( aText ),
+ EDA_TEXT( aText )
+{
+ m_Pos = aText.m_Pos;
+ m_shape = aText.m_shape;
+ m_MultilineAllowed = aText.m_MultilineAllowed;
+ m_schematicOrientation = aText.m_schematicOrientation;
+ m_isDangling = false;
+}
+
+
+EDA_ITEM* SCH_TEXT::Clone() const
+{
+ return new SCH_TEXT( *this );
+}
+
+
+void SCH_TEXT::IncrementLabel( int aIncrement )
+{
+ IncrementLabelMember( m_Text, aIncrement );
+}
+
+
+wxPoint SCH_TEXT::GetSchematicTextOffset() const
+{
+ wxPoint text_offset;
+
+ // add a small offset (TXTMARGE) to x ( or y) position to allow a text to
+ // be on a wire or a line and be readable
+ switch( m_schematicOrientation )
+ {
+ default:
+ case 0: /* Horiz Normal Orientation (left justified) */
+ text_offset.y = -TXTMARGE;
+ break;
+
+ case 1: /* Vert Orientation UP */
+ text_offset.x = -TXTMARGE;
+ break;
+
+ case 2: /* Horiz Orientation - Right justified */
+ text_offset.y = -TXTMARGE;
+ break;
+
+ case 3: /* Vert Orientation BOTTOM */
+ text_offset.x = -TXTMARGE;
+ break;
+ }
+
+ return text_offset;
+}
+
+
+bool SCH_TEXT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint * aFindLocation )
+{
+ wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText() );
+
+ if( SCH_ITEM::Matches( m_Text, aSearchData ) )
+ {
+ EDA_RECT BoundaryBox = GetBoundingBox();
+
+ if( aFindLocation )
+ *aFindLocation = BoundaryBox.Centre();
+
+ return true;
+ }
+
+ return false;
+}
+
+
+void SCH_TEXT::MirrorY( int aYaxis_position )
+{
+ // Text is NOT really mirrored; it is moved to a suitable horizontal position
+ switch( GetOrientation() )
+ {
+ case 0: // horizontal text
+ SetOrientation( 2 );
+ break;
+
+ case 2: // invert horizontal text
+ SetOrientation( 0 );
+ break;
+
+ case 1: // Vert Orientation UP
+ case 3: // Vert Orientation BOTTOM
+ default:
+ break;
+ }
+
+ MIRROR( m_Pos.x, aYaxis_position );
+}
+
+
+void SCH_TEXT::MirrorX( int aXaxis_position )
+{
+ // Text is NOT really mirrored; it is moved to a suitable vertical position
+ switch( GetOrientation() )
+ {
+ case 1: // Vert Orientation UP
+ SetOrientation( 3 );
+ break;
+
+ case 3: // Vert Orientation BOTTOM
+ SetOrientation( 1 );
+ break;
+
+ case 0: // horizontal text
+ case 2: // invert horizontal text
+ default:
+ break;
+ }
+
+ MIRROR( m_Pos.y, aXaxis_position );
+}
+
+
+void SCH_TEXT::Rotate( wxPoint aPosition )
+{
+ int dy;
+
+ RotatePoint( &m_Pos, aPosition, 900 );
+ SetOrientation( (GetOrientation() + 1) % 4 );
+
+ switch( GetOrientation() )
+ {
+ case 0: // horizontal text
+ dy = m_Size.y;
+ break;
+
+ case 1: // Vert Orientation UP
+ dy = 0;
+ break;
+
+ case 2: // invert horizontal text
+ dy = m_Size.y;
+ break;
+
+ case 3: // Vert Orientation BOTTOM
+ dy = 0;
+ break;
+
+ default:
+ dy = 0;
+ break;
+ }
+
+ m_Pos.y += dy;
+}
+
+
+void SCH_TEXT::SetOrientation( int aOrientation )
+{
+ m_schematicOrientation = aOrientation;
+
+ switch( m_schematicOrientation )
+ {
+ default:
+ case 0: /* Horiz Normal Orientation (left justified) */
+ m_Orient = TEXT_ORIENT_HORIZ;
+ m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
+ m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
+ break;
+
+ case 1: /* Vert Orientation UP */
+ m_Orient = TEXT_ORIENT_VERT;
+ m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
+ m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
+ break;
+
+ case 2: /* Horiz Orientation - Right justified */
+ m_Orient = TEXT_ORIENT_HORIZ;
+ m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
+ m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
+ break;
+
+ case 3: /* Vert Orientation BOTTOM */
+ m_Orient = TEXT_ORIENT_VERT;
+ m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
+ m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
+ break;
+ }
+}
+
+
+void SCH_TEXT::SwapData( SCH_ITEM* aItem )
+{
+ SCH_TEXT* item = (SCH_TEXT*) aItem;
+
+ std::swap( m_Text, item->m_Text );
+ std::swap( m_Pos, item->m_Pos );
+ std::swap( m_Size, item->m_Size );
+ std::swap( m_Thickness, item->m_Thickness );
+ std::swap( m_shape, item->m_shape );
+ std::swap( m_Orient, item->m_Orient );
+
+ std::swap( m_Layer, item->m_Layer );
+ std::swap( m_HJustify, item->m_HJustify );
+ std::swap( m_VJustify, item->m_VJustify );
+ std::swap( m_isDangling, item->m_isDangling );
+ std::swap( m_schematicOrientation, item->m_schematicOrientation );
+}
+
+
+int SCH_TEXT::GetPenSize() const
+{
+ int pensize = m_Thickness;
+
+ if( pensize == 0 ) // Use default values for pen size
+ {
+ if( m_Bold )
+ pensize = GetPenSizeForBold( m_Size.x );
+ else
+ pensize = GetDefaultLineThickness();
+ }
+
+ // Clip pen size for small texts:
+ pensize = Clamp_Text_PenSize( pensize, m_Size, m_Bold );
+ return pensize;
+}
+
+
+void SCH_TEXT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& aOffset,
+ GR_DRAWMODE DrawMode, EDA_COLOR_T Color )
+{
+ EDA_COLOR_T color;
+ int linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness;
+ EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL;
+
+ linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
+
+ if( Color >= 0 )
+ color = Color;
+ else
+ color = GetLayerColor( m_Layer );
+
+ GRSetDrawMode( DC, DrawMode );
+
+ wxPoint text_offset = aOffset + GetSchematicTextOffset();
+ std::swap( linewidth, m_Thickness ); // Set the minimum width
+ EDA_TEXT::Draw( clipbox, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR );
+ std::swap( linewidth, m_Thickness ); // set initial value
+
+ if( m_isDangling && panel)
+ DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color );
+
+ // Enable these line to draw the bounding box (debug tests purposes only)
+#if 0
+ {
+ EDA_RECT BoundaryBox = GetBoundingBox();
+ GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
+ }
+#endif
+}
+
+
+bool SCH_TEXT::Save( FILE* aFile ) const
+{
+ bool success = true;
+ const char* shape = "~";
+
+ if( m_Italic )
+ shape = "Italic";
+
+ // For compatibility reason, the text must be saved in only one text line
+ // so we replace all E.O.L. by \\n
+ wxString text = m_Text;
+
+ text.Replace( wxT("\n"), wxT( "\\n" ) );
+
+ // Here we should have no CR or LF character in line
+ // This is not always the case if a multiline text was copied (using a copy/paste function)
+ // from a text that uses E.O.L characters that differs from the current EOL format
+ // This is mainly the case under Linux using LF symbol when copying a text from
+ // Windows (using CRLF symbol)
+ // So we must just remove the extra CR left (or LF left under MacOSX)
+ for( unsigned ii = 0; ii < text.Len(); )
+ {
+ if( text[ii] == 0x0A || text[ii] == 0x0D )
+ text.erase( ii, 1 );
+ else
+ ii++;
+ }
+
+
+ if( fprintf( aFile, "Text Notes %-4d %-4d %-4d %-4d %s %d\n%s\n",
+ m_Pos.x, m_Pos.y, m_schematicOrientation, m_Size.x,
+ shape, m_Thickness, TO_UTF8( text ) ) == EOF )
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+
+bool SCH_TEXT::Load( LINE_READER& aLine, wxString& aErrorMsg )
+{
+ char Name1[256];
+ char Name2[256];
+ char Name3[256];
+ int thickness = 0, size = 0, orient = 0;
+
+ Name1[0] = 0; Name2[0] = 0; Name3[0] = 0;
+
+ char* sline = (char*) aLine;
+
+ while( ( *sline != ' ' ) && *sline )
+ sline++;
+
+ // sline points the start of parameters
+ int ii = sscanf( sline, "%255s %d %d %d %d %255s %255s %d", Name1, &m_Pos.x, &m_Pos.y,
+ &orient, &size, Name2, Name3, &thickness );
+
+ if( ii < 4 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file text load error at line %d" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ if( !aLine.ReadLine() )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file text load error at line %d" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ if( size == 0 )
+ size = GetDefaultTextSize();
+
+ char* text = strtok( (char*) aLine, "\n\r" );
+
+ if( text == NULL )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file text load error at line %d" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ wxString val = FROM_UTF8( text );
+
+ for( ; ; )
+ {
+ int i = val.find( wxT( "\\n" ) );
+
+ if( i == wxNOT_FOUND )
+ break;
+
+ val.erase( i, 2 );
+ val.insert( i, wxT( "\n" ) );
+ }
+
+ m_Text = val;
+ m_Size.x = m_Size.y = size;
+ SetOrientation( orient );
+
+ if( isdigit( Name3[0] ) )
+ {
+ thickness = atol( Name3 );
+ m_Bold = ( thickness != 0 );
+ m_Thickness = m_Bold ? GetPenSizeForBold( size ) : 0;
+ }
+
+ if( strnicmp( Name2, "Italic", 6 ) == 0 )
+ m_Italic = 1;
+
+ return true;
+}
+
+
+void SCH_TEXT::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
+{
+ // Normal text labels cannot be tested for dangling ends.
+ if( Type() == SCH_TEXT_T )
+ return;
+
+ DANGLING_END_ITEM item( LABEL_END, this, m_Pos );
+ aItemList.push_back( item );
+}
+
+
+bool SCH_TEXT::IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList )
+{
+ // Normal text labels cannot be tested for dangling ends.
+ if( Type() == SCH_TEXT_T )
+ return false;
+
+ bool previousState = m_isDangling;
+ m_isDangling = true;
+
+ for( unsigned ii = 0; ii < aItemList.size(); ii++ )
+ {
+ DANGLING_END_ITEM& item = aItemList[ii];
+
+ if( item.GetItem() == this )
+ continue;
+
+ switch( item.GetType() )
+ {
+ case PIN_END:
+ case LABEL_END:
+ case SHEET_LABEL_END:
+ if( m_Pos == item.GetPosition() )
+ m_isDangling = false;
+
+ break;
+
+ case WIRE_START_END:
+ case BUS_START_END:
+ {
+ // These schematic items have created 2 DANGLING_END_ITEM one per end. But being
+ // a paranoid programmer, I'll check just in case.
+ ii++;
+
+ wxCHECK_MSG( ii < aItemList.size(), previousState != m_isDangling,
+ wxT( "Dangling end type list overflow. Bad programmer!" ) );
+
+ DANGLING_END_ITEM & nextItem = aItemList[ii];
+ m_isDangling = !IsPointOnSegment( item.GetPosition(), nextItem.GetPosition(), m_Pos );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if( !m_isDangling )
+ break;
+ }
+
+ return previousState != m_isDangling;
+}
+
+
+bool SCH_TEXT::IsSelectStateChanged( const wxRect& aRect )
+{
+ bool previousState = IsSelected();
+
+ if( aRect.Contains( m_Pos ) )
+ SetFlags( SELECTED );
+ else
+ ClearFlags( SELECTED );
+
+ return previousState != IsSelected();
+}
+
+
+void SCH_TEXT::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
+{
+ // Normal text labels do not have connection points. All others do.
+ if( Type() == SCH_TEXT_T )
+ return;
+
+ aPoints.push_back( m_Pos );
+}
+
+
+const EDA_RECT SCH_TEXT::GetBoundingBox() const
+{
+ // We must pass the effective text thickness to GetTextBox
+ // when calculating the bounding box
+ int linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness;
+
+ linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
+
+ EDA_RECT rect = GetTextBox( -1, linewidth );
+
+ if( m_Orient ) // Rotate rect
+ {
+ wxPoint pos = rect.GetOrigin();
+ wxPoint end = rect.GetEnd();
+ RotatePoint( &pos, m_Pos, m_Orient );
+ RotatePoint( &end, m_Pos, m_Orient );
+ rect.SetOrigin( pos );
+ rect.SetEnd( end );
+ }
+
+ rect.Normalize();
+ return rect;
+}
+
+
+wxString SCH_TEXT::GetSelectMenuText() const
+{
+ wxString msg;
+ msg.Printf( _( "Graphic Text %s" ), GetChars( ShortenedShownText() ) );
+ return msg;
+}
+
+
+void SCH_TEXT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
+ SCH_SHEET_PATH* aSheetPath )
+{
+ if( GetLayer() == LAYER_NOTES || GetLayer() == LAYER_SHEETLABEL )
+ return;
+
+ NETLIST_OBJECT* item = new NETLIST_OBJECT();
+ item->m_SheetPath = *aSheetPath;
+ item->m_SheetPathInclude = *aSheetPath;
+ item->m_Comp = (SCH_ITEM*) this;
+ item->m_Type = NET_LABEL;
+
+ if( GetLayer() == LAYER_GLOBLABEL )
+ item->m_Type = NET_GLOBLABEL;
+ else if( GetLayer() == LAYER_HIERLABEL )
+ item->m_Type = NET_HIERLABEL;
+
+ item->m_Label = m_Text;
+ item->m_Start = item->m_End = m_Pos;
+
+ aNetListItems.push_back( item );
+
+ /* If a bus connects to label */
+ if( IsBusLabel( m_Text ) )
+ item->ConvertBusToNetListItems( aNetListItems );
+}
+
+
+bool SCH_TEXT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
+{
+ EDA_RECT bBox = GetBoundingBox();
+ bBox.Inflate( aAccuracy );
+ return bBox.Contains( aPosition );
+}
+
+
+bool SCH_TEXT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ EDA_RECT bBox = GetBoundingBox();
+ bBox.Inflate( aAccuracy );
+
+ if( aContained )
+ return aRect.Contains( bBox );
+
+ return aRect.Intersects( bBox );
+}
+
+
+void SCH_TEXT::Plot( PLOTTER* aPlotter )
+{
+ static std::vector <wxPoint> Poly;
+
+ EDA_COLOR_T color = GetLayerColor( GetLayer() );
+ wxPoint textpos = m_Pos + GetSchematicTextOffset();
+ int thickness = GetPenSize();
+
+ aPlotter->SetCurrentLineWidth( thickness );
+
+ if( m_MultilineAllowed )
+ {
+ std::vector<wxPoint> positions;
+ wxArrayString strings_list;
+ wxStringSplit( GetShownText(), strings_list, '\n' );
+ positions.reserve( strings_list.Count() );
+
+ GetPositionsOfLinesOfMultilineText(positions, strings_list.Count() );
+
+ for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
+ {
+ wxString& txt = strings_list.Item( ii );
+ aPlotter->Text( positions[ii], color, txt, m_Orient, m_Size, m_HJustify,
+ m_VJustify, thickness, m_Italic, m_Bold );
+ }
+ }
+ else
+ {
+ aPlotter->Text( textpos, color, GetShownText(), m_Orient, m_Size, m_HJustify,
+ m_VJustify, thickness, m_Italic, m_Bold );
+ }
+
+ /* Draw graphic symbol for global or hierarchical labels */
+ CreateGraphicShape( Poly, m_Pos );
+
+ aPlotter->SetCurrentLineWidth( GetPenSize() );
+
+ if( Poly.size() )
+ aPlotter->PlotPoly( Poly, NO_FILL );
+}
+
+
+/*
+ * Display the type, shape, size and some other props to the Message panel
+ */
+void SCH_TEXT::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
+{
+ wxString msg;
+
+ switch( Type() )
+ {
+ case SCH_TEXT_T:
+ msg = _( "Graphic Text" );
+ break;
+
+ case SCH_LABEL_T:
+ msg = _( "Label" );
+ break;
+
+ case SCH_GLOBAL_LABEL_T:
+ msg = _( "Global Label" );
+ break;
+
+ case SCH_HIERARCHICAL_LABEL_T:
+ msg = _( "Hierarchical Label" );
+ break;
+
+ case SCH_SHEET_PIN_T:
+ msg = _( "Hierarchical Sheet Pin" );
+ break;
+
+ default:
+ return;
+ }
+
+ aList.push_back( MSG_PANEL_ITEM( msg, GetShownText(), DARKCYAN ) );
+
+ switch( GetOrientation() )
+ {
+ case 0: // horizontal text
+ msg = _( "Horizontal" );
+ break;
+
+ case 1: // Vert Orientation UP
+ msg = _( "Vertical up" );
+ break;
+
+ case 2: // invert horizontal text
+ msg = _( "Horizontal invert" );
+ break;
+
+ case 3: // Vert Orientation Down
+ msg = _( "Vertical down" );
+ break;
+
+ default:
+ msg = wxT( "???" );
+ break;
+ }
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Orientation" ), msg, BROWN ) );
+
+ wxString textStyle[] = { _( "Normal" ), _( "Italic" ), _( "Bold" ), _( "Bold Italic" ) };
+ int style = 0;
+
+ if( m_Italic )
+ style = 1;
+
+ if( m_Bold )
+ style += 2;
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Style" ), textStyle[style], BROWN ) );
+
+
+ // Display electricat type if it is relevant
+ if( (Type() == SCH_GLOBAL_LABEL_T) ||
+ (Type() == SCH_HIERARCHICAL_LABEL_T ) ||
+ (Type() == SCH_SHEET_PIN_T ) )
+ {
+ switch( GetShape() )
+ {
+ case NET_INPUT: msg = _( "Input" ); break;
+ case NET_OUTPUT: msg = _( "Output" ); break;
+ case NET_BIDI: msg = _( "Bidirectional" ); break;
+ case NET_TRISTATE: msg = _( "Tri-State" ); break;
+ case NET_UNSPECIFIED: msg = _( "Passive" ); break;
+ default: msg = wxT( "???" ); break;
+ }
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, BLUE ) );
+ }
+
+ // Display text size (X or Y value, with are the same value in Eeschema)
+ msg = StringFromValue( g_UserUnit, m_Size.x, true );
+ aList.push_back( MSG_PANEL_ITEM( _( "Size" ), msg, RED ) );
+}
+
+#if defined(DEBUG)
+
+void SCH_TEXT::Show( int nestLevel, std::ostream& os ) const
+{
+ // XML output:
+ wxString s = GetClass();
+
+ NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str()
+ << " layer=\"" << m_Layer << '"'
+ << " shape=\"" << m_shape << '"'
+ << " dangling=\"" << m_isDangling << '"'
+ << '>'
+ << TO_UTF8( m_Text )
+ << "</" << s.Lower().mb_str() << ">\n";
+}
+
+#endif
+
+
+SCH_LABEL::SCH_LABEL( const wxPoint& pos, const wxString& text ) :
+ SCH_TEXT( pos, text, SCH_LABEL_T )
+{
+ m_Layer = LAYER_LOCLABEL;
+ m_shape = NET_INPUT;
+ m_isDangling = true;
+ m_MultilineAllowed = false;
+}
+
+
+EDA_ITEM* SCH_LABEL::Clone() const
+{
+ return new SCH_LABEL( *this );
+}
+
+
+wxPoint SCH_LABEL::GetSchematicTextOffset() const
+{
+ return SCH_TEXT::GetSchematicTextOffset();
+}
+
+
+void SCH_LABEL::SetOrientation( int aOrientation )
+{
+ SCH_TEXT::SetOrientation( aOrientation );
+}
+
+
+void SCH_LABEL::MirrorX( int aXaxis_position )
+{
+ // Text is NOT really mirrored; it is moved to a suitable position
+ switch( GetOrientation() )
+ {
+ case 1: // Vert Orientation UP
+ SetOrientation( 3 );
+ break;
+
+ case 3: // Vert Orientation BOTTOM
+ SetOrientation( 1 );
+ break;
+
+ case 0: // horizontal text
+ case 2: // invert horizontal text
+ default:
+ break;
+ }
+
+ MIRROR( m_Pos.y, aXaxis_position );
+}
+
+
+void SCH_LABEL::Rotate( wxPoint aPosition )
+{
+ RotatePoint( &m_Pos, aPosition, 900 );
+ SetOrientation( (GetOrientation() + 1) % 4 );
+}
+
+
+bool SCH_LABEL::Save( FILE* aFile ) const
+{
+ bool success = true;
+ const char* shape = "~";
+
+ if( m_Italic )
+ shape = "Italic";
+
+ if( fprintf( aFile, "Text Label %-4d %-4d %-4d %-4d %s %d\n%s\n",
+ m_Pos.x, m_Pos.y, m_schematicOrientation, m_Size.x, shape,
+ m_Thickness, TO_UTF8( m_Text ) ) == EOF )
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+
+bool SCH_LABEL::Load( LINE_READER& aLine, wxString& aErrorMsg )
+{
+ char Name1[256];
+ char Name2[256];
+ char Name3[256];
+ int thickness = 0, size = 0, orient = 0;
+
+ Name1[0] = 0; Name2[0] = 0; Name3[0] = 0;
+
+ char* sline = (char*) aLine;
+
+ while( ( *sline != ' ' ) && *sline )
+ sline++;
+
+ // sline points the start of parameters
+ int ii = sscanf( sline, "%255s %d %d %d %d %255s %255s %d", Name1, &m_Pos.x, &m_Pos.y,
+ &orient, &size, Name2, Name3, &thickness );
+
+ if( ii < 4 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file label load error at line %d" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ if( !aLine.ReadLine() )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file label load error atline %d" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ if( size == 0 )
+ size = GetDefaultTextSize();
+
+ char* text = strtok( (char*) aLine, "\n\r" );
+
+ if( text == NULL )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file label load error at line %d" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ m_Text = FROM_UTF8( text );
+ m_Size.x = m_Size.y = size;
+ SetOrientation( orient );
+
+ if( isdigit( Name3[0] ) )
+ {
+ thickness = atol( Name3 );
+ m_Bold = ( thickness != 0 );
+ m_Thickness = m_Bold ? GetPenSizeForBold( size ) : 0;
+ }
+
+ if( stricmp( Name2, "Italic" ) == 0 )
+ m_Italic = 1;
+
+ return true;
+}
+
+
+void SCH_LABEL::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
+ GR_DRAWMODE DrawMode, EDA_COLOR_T Color )
+{
+ SCH_TEXT::Draw( panel, DC, offset, DrawMode, Color );
+}
+
+
+const EDA_RECT SCH_LABEL::GetBoundingBox() const
+{
+ int x, y, dx, dy, length, height;
+
+ x = m_Pos.x;
+ y = m_Pos.y;
+ int width = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
+ length = LenSize( GetShownText() );
+ height = m_Size.y + width;
+ dx = dy = 0;
+
+ switch( m_schematicOrientation )
+ {
+ case 0: /* Horiz Normal Orientation (left justified) */
+ dx = 2 * DANGLING_SYMBOL_SIZE + length;
+ dy = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
+ x -= DANGLING_SYMBOL_SIZE;
+ y += DANGLING_SYMBOL_SIZE;
+ break;
+
+ case 1: /* Vert Orientation UP */
+ dx = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
+ dy = -2 * DANGLING_SYMBOL_SIZE - length;
+ x += DANGLING_SYMBOL_SIZE;
+ y += DANGLING_SYMBOL_SIZE;
+ break;
+
+ case 2: /* Horiz Orientation - Right justified */
+ dx = -2 * DANGLING_SYMBOL_SIZE - length;
+ dy = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
+ x += DANGLING_SYMBOL_SIZE;
+ y += DANGLING_SYMBOL_SIZE;
+ break;
+
+ case 3: /* Vert Orientation BOTTOM */
+ dx = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
+ dy = 2 * DANGLING_SYMBOL_SIZE + length;
+ x += DANGLING_SYMBOL_SIZE;
+ y -= DANGLING_SYMBOL_SIZE;
+ break;
+ }
+
+ EDA_RECT box( wxPoint( x, y ), wxSize( dx, dy ) );
+ box.Normalize();
+ return box;
+}
+
+
+wxString SCH_LABEL::GetSelectMenuText() const
+{
+ wxString msg;
+ msg.Printf( _( "Label %s" ), GetChars( ShortenedShownText() ) );
+ return msg;
+}
+
+
+
+SCH_GLOBALLABEL::SCH_GLOBALLABEL( const wxPoint& pos, const wxString& text ) :
+ SCH_TEXT( pos, text, SCH_GLOBAL_LABEL_T )
+{
+ m_Layer = LAYER_GLOBLABEL;
+ m_shape = NET_BIDI;
+ m_isDangling = true;
+ m_MultilineAllowed = false;
+}
+
+
+EDA_ITEM* SCH_GLOBALLABEL::Clone() const
+{
+ return new SCH_GLOBALLABEL( *this );
+}
+
+
+bool SCH_GLOBALLABEL::Save( FILE* aFile ) const
+{
+ bool success = true;
+ const char* shape = "~";
+
+ if( m_Italic )
+ shape = "Italic";
+
+ if( fprintf( aFile, "Text GLabel %-4d %-4d %-4d %-4d %s %s %d\n%s\n",
+ m_Pos.x, m_Pos.y, m_schematicOrientation, m_Size.x,
+ SheetLabelType[m_shape], shape, m_Thickness, TO_UTF8( m_Text ) ) == EOF )
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+
+bool SCH_GLOBALLABEL::Load( LINE_READER& aLine, wxString& aErrorMsg )
+{
+ char Name1[256];
+ char Name2[256];
+ char Name3[256];
+ int thickness = 0, size = 0, orient = 0;
+
+ Name1[0] = 0; Name2[0] = 0; Name3[0] = 0;
+
+ char* sline = (char*) aLine;
+
+ while( (*sline != ' ' ) && *sline )
+ sline++;
+
+ // sline points the start of parameters
+ int ii = sscanf( sline, "%255s %d %d %d %d %255s %255s %d", Name1, &m_Pos.x, &m_Pos.y,
+ &orient, &size, Name2, Name3, &thickness );
+
+ if( ii < 4 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file global label load error at line %d" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ if( !aLine.ReadLine() )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file global label load error at line %d" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ if( size == 0 )
+ size = GetDefaultTextSize();
+
+ char* text = strtok( (char*) aLine, "\n\r" );
+
+ if( text == NULL )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file global label load error at line %d" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ m_Text = FROM_UTF8( text );
+ m_Size.x = m_Size.y = size;
+ SetOrientation( orient );
+ m_shape = NET_INPUT;
+ m_Bold = ( thickness != 0 );
+ m_Thickness = m_Bold ? GetPenSizeForBold( size ) : 0;
+
+ if( stricmp( Name2, SheetLabelType[NET_OUTPUT] ) == 0 )
+ m_shape = NET_OUTPUT;
+
+ if( stricmp( Name2, SheetLabelType[NET_BIDI] ) == 0 )
+ m_shape = NET_BIDI;
+
+ if( stricmp( Name2, SheetLabelType[NET_TRISTATE] ) == 0 )
+ m_shape = NET_TRISTATE;
+
+ if( stricmp( Name2, SheetLabelType[NET_UNSPECIFIED] ) == 0 )
+ m_shape = NET_UNSPECIFIED;
+
+ if( stricmp( Name3, "Italic" ) == 0 )
+ m_Italic = 1;
+
+ return true;
+}
+
+
+void SCH_GLOBALLABEL::MirrorY( int aYaxis_position )
+{
+ /* The global label is NOT really mirrored.
+ * for an horizontal label, the schematic orientation is changed.
+ * for a vertical label, the schematic orientation is not changed.
+ * and the label is moved to a suitable position
+ */
+ switch( GetOrientation() )
+ {
+ case 0: /* horizontal text */
+ SetOrientation( 2 );
+ break;
+
+ case 2: /* invert horizontal text*/
+ SetOrientation( 0 );
+ break;
+ }
+
+ MIRROR( m_Pos.x, aYaxis_position );
+}
+
+
+void SCH_GLOBALLABEL::MirrorX( int aXaxis_position )
+{
+ switch( GetOrientation() )
+ {
+ case 1: /* vertical text */
+ SetOrientation( 3 );
+ break;
+
+ case 3: /* invert vertical text*/
+ SetOrientation( 1 );
+ break;
+ }
+
+ MIRROR( m_Pos.y, aXaxis_position );
+}
+
+
+void SCH_GLOBALLABEL::Rotate( wxPoint aPosition )
+{
+ RotatePoint( &m_Pos, aPosition, 900 );
+ SetOrientation( (GetOrientation() + 3) % 4 );
+}
+
+
+wxPoint SCH_GLOBALLABEL::GetSchematicTextOffset() const
+{
+ wxPoint text_offset;
+ int width = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
+
+ width = Clamp_Text_PenSize( width, m_Size, m_Bold );
+ int HalfSize = m_Size.x / 2;
+ int offset = width;
+
+ switch( m_shape )
+ {
+ case NET_INPUT:
+ case NET_BIDI:
+ case NET_TRISTATE:
+ offset += HalfSize;
+ break;
+
+ case NET_OUTPUT:
+ case NET_UNSPECIFIED:
+ offset += TXTMARGE;
+ break;
+
+ default:
+ break;
+ }
+
+ switch( m_schematicOrientation )
+ {
+ case 0: /* Orientation horiz normal */
+ text_offset.x -= offset;
+ break;
+
+ case 1: /* Orientation vert UP */
+ text_offset.y -= offset;
+ break;
+
+ case 2: /* Orientation horiz inverse */
+ text_offset.x += offset;
+ break;
+
+ case 3: /* Orientation vert BOTTOM */
+ text_offset.y += offset;
+ break;
+ }
+
+ return text_offset;
+}
+
+
+void SCH_GLOBALLABEL::SetOrientation( int aOrientation )
+{
+ m_schematicOrientation = aOrientation;
+
+ switch( m_schematicOrientation )
+ {
+ default:
+ case 0: /* Horiz Normal Orientation */
+ m_Orient = TEXT_ORIENT_HORIZ;
+ m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
+ m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
+ break;
+
+ case 1: /* Vert Orientation UP */
+ m_Orient = TEXT_ORIENT_VERT;
+ m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
+ m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
+ break;
+
+ case 2: /* Horiz Orientation */
+ m_Orient = TEXT_ORIENT_HORIZ;
+ m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
+ m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
+ break;
+
+ case 3: /* Vert Orientation BOTTOM */
+ m_Orient = TEXT_ORIENT_VERT;
+ m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
+ m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
+ break;
+ }
+}
+
+
+void SCH_GLOBALLABEL::Draw( EDA_DRAW_PANEL* panel,
+ wxDC* DC,
+ const wxPoint& aOffset,
+ GR_DRAWMODE DrawMode,
+ EDA_COLOR_T Color )
+{
+ static std::vector <wxPoint> Poly;
+ EDA_COLOR_T color;
+ wxPoint text_offset = aOffset + GetSchematicTextOffset();
+
+ if( Color >= 0 )
+ color = Color;
+ else
+ color = GetLayerColor( m_Layer );
+
+ GRSetDrawMode( DC, DrawMode );
+
+ int linewidth = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
+ linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
+ std::swap( linewidth, m_Thickness ); // Set the minimum width
+ EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL;
+ EDA_TEXT::Draw( clipbox, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR );
+ std::swap( linewidth, m_Thickness ); // set initial value
+
+ CreateGraphicShape( Poly, m_Pos + aOffset );
+ GRPoly( clipbox, DC, Poly.size(), &Poly[0], 0, linewidth, color, color );
+
+ if( m_isDangling && panel )
+ DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color );
+
+ // Enable these line to draw the bounding box (debug tests purposes only)
+#if 0
+ {
+ EDA_RECT BoundaryBox = GetBoundingBox();
+ GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
+ }
+#endif
+}
+
+
+void SCH_GLOBALLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& Pos )
+{
+ int HalfSize = m_Size.y / 2;
+ int linewidth = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
+
+ linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
+
+ aPoints.clear();
+
+ int symb_len = LenSize( GetShownText() ) + ( TXTMARGE * 2 );
+
+ // Create outline shape : 6 points
+ int x = symb_len + linewidth + 3;
+
+ // Use negation bar Y position to calculate full vertical size
+ #define Y_CORRECTION 1.3
+ // Note: this factor is due to the fact the negation bar Y position
+ // does not give exactly the full Y size of text
+ // and is experimentally set to this value
+ int y = KiROUND( OverbarPositionY( HalfSize ) * Y_CORRECTION );
+ // add room for line thickness and space between top of text and graphic shape
+ y += linewidth;
+
+ // Starting point(anchor)
+ aPoints.push_back( wxPoint( 0, 0 ) );
+ aPoints.push_back( wxPoint( 0, -y ) ); // Up
+ aPoints.push_back( wxPoint( -x, -y ) ); // left
+ aPoints.push_back( wxPoint( -x, 0 ) ); // Up left
+ aPoints.push_back( wxPoint( -x, y ) ); // left down
+ aPoints.push_back( wxPoint( 0, y ) ); // down
+
+ int x_offset = 0;
+
+ switch( m_shape )
+ {
+ case NET_INPUT:
+ x_offset = -HalfSize;
+ aPoints[0].x += HalfSize;
+ break;
+
+ case NET_OUTPUT:
+ aPoints[3].x -= HalfSize;
+ break;
+
+ case NET_BIDI:
+ case NET_TRISTATE:
+ x_offset = -HalfSize;
+ aPoints[0].x += HalfSize;
+ aPoints[3].x -= HalfSize;
+ break;
+
+ case NET_UNSPECIFIED:
+ default:
+ break;
+ }
+
+ int angle = 0;
+
+ switch( m_schematicOrientation )
+ {
+ case 0: /* Orientation horiz normal */
+ break;
+
+ case 1: /* Orientation vert UP */
+ angle = -900;
+ break;
+
+ case 2: /* Orientation horiz inverse */
+ angle = 1800;
+ break;
+
+ case 3: /* Orientation vert BOTTOM */
+ angle = 900;
+ break;
+ }
+
+ // Rotate outlines and move corners in real position
+ for( unsigned ii = 0; ii < aPoints.size(); ii++ )
+ {
+ aPoints[ii].x += x_offset;
+
+ if( angle )
+ RotatePoint( &aPoints[ii], angle );
+
+ aPoints[ii] += Pos;
+ }
+
+ aPoints.push_back( aPoints[0] ); // closing
+}
+
+
+const EDA_RECT SCH_GLOBALLABEL::GetBoundingBox() const
+{
+ int x, y, dx, dy, length, height;
+
+ x = m_Pos.x;
+ y = m_Pos.y;
+ dx = dy = 0;
+
+ int width = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
+ height = ( (m_Size.y * 15) / 10 ) + width + 2 * TXTMARGE;
+
+ // text X size add height for triangular shapes(bidirectional)
+ length = LenSize( GetShownText() ) + height + DANGLING_SYMBOL_SIZE;
+
+ switch( m_schematicOrientation ) // respect orientation
+ {
+ case 0: /* Horiz Normal Orientation (left justified) */
+ dx = -length;
+ dy = height;
+ x += DANGLING_SYMBOL_SIZE;
+ y -= height / 2;
+ break;
+
+ case 1: /* Vert Orientation UP */
+ dx = height;
+ dy = -length;
+ x -= height / 2;
+ y += DANGLING_SYMBOL_SIZE;
+ break;
+
+ case 2: /* Horiz Orientation - Right justified */
+ dx = length;
+ dy = height;
+ x -= DANGLING_SYMBOL_SIZE;
+ y -= height / 2;
+ break;
+
+ case 3: /* Vert Orientation BOTTOM */
+ dx = height;
+ dy = length;
+ x -= height / 2;
+ y -= DANGLING_SYMBOL_SIZE;
+ break;
+ }
+
+ EDA_RECT box( wxPoint( x, y ), wxSize( dx, dy ) );
+ box.Normalize();
+ return box;
+}
+
+
+wxString SCH_GLOBALLABEL::GetSelectMenuText() const
+{
+ wxString msg;
+ msg.Printf( _( "Global Label %s" ), GetChars( ShortenedShownText() ) );
+ return msg;
+}
+
+
+
+SCH_HIERLABEL::SCH_HIERLABEL( const wxPoint& pos, const wxString& text, KICAD_T aType ) :
+ SCH_TEXT( pos, text, aType )
+{
+ m_Layer = LAYER_HIERLABEL;
+ m_shape = NET_INPUT;
+ m_isDangling = true;
+ m_MultilineAllowed = false;
+}
+
+
+EDA_ITEM* SCH_HIERLABEL::Clone() const
+{
+ return new SCH_HIERLABEL( *this );
+}
+
+
+bool SCH_HIERLABEL::Save( FILE* aFile ) const
+{
+ bool success = true;
+ const char* shape = "~";
+
+ if( m_Italic )
+ shape = "Italic";
+
+ if( fprintf( aFile, "Text HLabel %-4d %-4d %-4d %-4d %s %s %d\n%s\n",
+ m_Pos.x, m_Pos.y, m_schematicOrientation, m_Size.x,
+ SheetLabelType[m_shape], shape, m_Thickness, TO_UTF8( m_Text ) ) == EOF )
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+
+bool SCH_HIERLABEL::Load( LINE_READER& aLine, wxString& aErrorMsg )
+{
+ char Name1[256];
+ char Name2[256];
+ char Name3[256];
+ int thickness = 0, size = 0, orient = 0;
+
+ Name1[0] = 0; Name2[0] = 0; Name3[0] = 0;
+
+ char* sline = (char*) aLine;
+
+ while( (*sline != ' ' ) && *sline )
+ sline++;
+
+ // sline points the start of parameters
+ int ii = sscanf( sline, "%255s %d %d %d %d %255s %255s %d", Name1, &m_Pos.x, &m_Pos.y,
+ &orient, &size, Name2, Name3, &thickness );
+
+ if( ii < 4 )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file hierarchical label load error at line %d" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ if( !aLine.ReadLine() )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file hierarchical label load error at line %d" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ if( size == 0 )
+ size = GetDefaultTextSize();
+
+ char* text = strtok( (char*) aLine, "\n\r" );
+
+ if( text == NULL )
+ {
+ aErrorMsg.Printf( wxT( "Eeschema file hierarchical label load error at line %d" ),
+ aLine.LineNumber() );
+ return false;
+ }
+
+ m_Text = FROM_UTF8( text );
+ m_Size.x = m_Size.y = size;
+ SetOrientation( orient );
+ m_shape = NET_INPUT;
+ m_Bold = ( thickness != 0 );
+ m_Thickness = m_Bold ? GetPenSizeForBold( size ) : 0;
+
+ if( stricmp( Name2, SheetLabelType[NET_OUTPUT] ) == 0 )
+ m_shape = NET_OUTPUT;
+
+ if( stricmp( Name2, SheetLabelType[NET_BIDI] ) == 0 )
+ m_shape = NET_BIDI;
+
+ if( stricmp( Name2, SheetLabelType[NET_TRISTATE] ) == 0 )
+ m_shape = NET_TRISTATE;
+
+ if( stricmp( Name2, SheetLabelType[NET_UNSPECIFIED] ) == 0 )
+ m_shape = NET_UNSPECIFIED;
+
+ if( stricmp( Name3, "Italic" ) == 0 )
+ m_Italic = 1;
+
+ return true;
+}
+
+
+void SCH_HIERLABEL::SetOrientation( int aOrientation )
+{
+ m_schematicOrientation = aOrientation;
+
+ switch( m_schematicOrientation )
+ {
+ default:
+ case 0: /* Horiz Normal Orientation */
+ m_Orient = TEXT_ORIENT_HORIZ;
+ m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
+ m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
+ break;
+
+ case 1: /* Vert Orientation UP */
+ m_Orient = TEXT_ORIENT_VERT;
+ m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
+ m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
+ break;
+
+ case 2: /* Horiz Orientation */
+ m_Orient = TEXT_ORIENT_HORIZ;
+ m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
+ m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
+ break;
+
+ case 3: /* Vert Orientation BOTTOM */
+ m_Orient = TEXT_ORIENT_VERT;
+ m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
+ m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
+ break;
+ }
+}
+
+
+void SCH_HIERLABEL::Draw( EDA_DRAW_PANEL* panel,
+ wxDC* DC,
+ const wxPoint& offset,
+ GR_DRAWMODE DrawMode,
+ EDA_COLOR_T Color )
+{
+ static std::vector <wxPoint> Poly;
+ EDA_COLOR_T color;
+ int linewidth = m_Thickness == 0 ?
+ GetDefaultLineThickness() : m_Thickness;
+ EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL;
+
+ linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
+
+ if( Color >= 0 )
+ color = Color;
+ else
+ color = GetLayerColor( m_Layer );
+
+ GRSetDrawMode( DC, DrawMode );
+
+ std::swap( linewidth, m_Thickness ); // Set the minimum width
+ wxPoint text_offset = offset + GetSchematicTextOffset();
+ EDA_TEXT::Draw( clipbox, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR );
+ std::swap( linewidth, m_Thickness ); // set initial value
+
+ CreateGraphicShape( Poly, m_Pos + offset );
+ GRPoly( clipbox, DC, Poly.size(), &Poly[0], 0, linewidth, color, color );
+
+ if( m_isDangling && panel )
+ DrawDanglingSymbol( panel, DC, m_Pos + offset, color );
+
+ // Enable these line to draw the bounding box (debug tests purposes only)
+#if 0
+ {
+ EDA_RECT BoundaryBox = GetBoundingBox();
+ GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
+ }
+#endif
+}
+
+
+void SCH_HIERLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& Pos )
+{
+ int* Template = TemplateShape[m_shape][m_schematicOrientation];
+ int HalfSize = m_Size.x / 2;
+
+ int imax = *Template; Template++;
+
+ aPoints.clear();
+
+ for( int ii = 0; ii < imax; ii++ )
+ {
+ wxPoint corner;
+ corner.x = ( HalfSize * (*Template) ) + Pos.x;
+ Template++;
+
+ corner.y = ( HalfSize * (*Template) ) + Pos.y;
+ Template++;
+
+ aPoints.push_back( corner );
+ }
+}
+
+
+const EDA_RECT SCH_HIERLABEL::GetBoundingBox() const
+{
+ int x, y, dx, dy, length, height;
+
+ x = m_Pos.x;
+ y = m_Pos.y;
+ dx = dy = 0;
+
+ int width = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
+ height = m_Size.y + width + 2 * TXTMARGE;
+ length = LenSize( GetShownText() )
+ + height // add height for triangular shapes
+ + 2 * DANGLING_SYMBOL_SIZE;
+
+ switch( m_schematicOrientation ) // respect orientation
+ {
+ case 0: /* Horiz Normal Orientation (left justified) */
+ dx = -length;
+ dy = height;
+ x += DANGLING_SYMBOL_SIZE;
+ y -= height / 2;
+ break;
+
+ case 1: /* Vert Orientation UP */
+ dx = height;
+ dy = -length;
+ x -= height / 2;
+ y += DANGLING_SYMBOL_SIZE;
+ break;
+
+ case 2: /* Horiz Orientation - Right justified */
+ dx = length;
+ dy = height;
+ x -= DANGLING_SYMBOL_SIZE;
+ y -= height / 2;
+ break;
+
+ case 3: /* Vert Orientation BOTTOM */
+ dx = height;
+ dy = length;
+ x -= height / 2;
+ y -= DANGLING_SYMBOL_SIZE;
+ break;
+ }
+
+ EDA_RECT box( wxPoint( x, y ), wxSize( dx, dy ) );
+ box.Normalize();
+ return box;
+}
+
+
+wxPoint SCH_HIERLABEL::GetSchematicTextOffset() const
+{
+ wxPoint text_offset;
+
+ int width = std::max( m_Thickness, GetDefaultLineThickness() );
+
+ int ii = m_Size.x + TXTMARGE + width;
+
+ switch( m_schematicOrientation )
+ {
+ case 0: /* Orientation horiz normale */
+ text_offset.x = -ii;
+ break;
+
+ case 1: /* Orientation vert UP */
+ text_offset.y = -ii;
+ break;
+
+ case 2: /* Orientation horiz inverse */
+ text_offset.x = ii;
+ break;
+
+ case 3: /* Orientation vert BOTTOM */
+ text_offset.y = ii;
+ break;
+ }
+
+ return text_offset;
+}
+
+
+void SCH_HIERLABEL::MirrorY( int aYaxis_position )
+{
+ /* The hierarchical label is NOT really mirrored for an horizontal label, the schematic
+ * orientation is changed. For a vertical label, the schematic orientation is not changed
+ * and the label is moved to a suitable position.
+ */
+
+ switch( GetOrientation() )
+ {
+ case 0: /* horizontal text */
+ SetOrientation( 2 );
+ break;
+
+ case 2: /* invert horizontal text*/
+ SetOrientation( 0 );
+ break;
+ }
+
+ MIRROR( m_Pos.x, aYaxis_position );
+}
+
+
+void SCH_HIERLABEL::MirrorX( int aXaxis_position )
+{
+ switch( GetOrientation() )
+ {
+ case 1: /* vertical text */
+ SetOrientation( 3 );
+ break;
+
+ case 3: /* invert vertical text*/
+ SetOrientation( 1 );
+ break;
+ }
+
+ MIRROR( m_Pos.y, aXaxis_position );
+}
+
+
+void SCH_HIERLABEL::Rotate( wxPoint aPosition )
+{
+ RotatePoint( &m_Pos, aPosition, 900 );
+ SetOrientation( (GetOrientation() + 3) % 4 );
+}
+
+
+wxString SCH_HIERLABEL::GetSelectMenuText() const
+{
+ wxString msg;
+ msg.Printf( _( "Hierarchical Label %s" ), GetChars( ShortenedShownText() ) );
+ return msg;
+}
diff --git a/eeschema/sch_text.h b/eeschema/sch_text.h
new file mode 100644
index 0000000..a570bfc
--- /dev/null
+++ b/eeschema/sch_text.h
@@ -0,0 +1,366 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_text.h
+ * @brief Definitions of the SCH_TEXT class and derivatives for Eeschema.
+ */
+
+#ifndef CLASS_TEXT_LABEL_H
+#define CLASS_TEXT_LABEL_H
+
+
+#include <macros.h>
+#include <eda_text.h>
+#include <sch_item_struct.h>
+
+
+class LINE_READER;
+class NETLIST_OBJECT_LIST;
+
+
+/* Type of SCH_HIERLABEL and SCH_GLOBALLABEL
+ * mainly used to handle the graphic associated shape
+ */
+typedef enum {
+ NET_INPUT,
+ NET_OUTPUT,
+ NET_BIDI,
+ NET_TRISTATE,
+ NET_UNSPECIFIED,
+ NET_TMAX /* Last value */
+} TypeSheetLabel;
+
+
+extern const char* SheetLabelType[]; /* names of types of labels */
+
+class SCH_TEXT : public SCH_ITEM, public EDA_TEXT
+{
+protected:
+ int m_shape;
+
+ /// True if not connected to another object if the object derive from SCH_TEXT
+ /// supports connections.
+ bool m_isDangling;
+
+ /**
+ * The orientation of text and any associated drawing elements of derived objects.
+ * 0 is the horizontal and left justified.
+ * 1 is vertical and top justified.
+ * 2 is horizontal and right justified. It is the equivalent of the mirrored 0 orentation.
+ * 3 is veritcal and bottom justifiend. It is the equivalent of the mirrored 1 orentation.
+ * This is a duplicattion of m_Orient, m_HJustified, and m_VJustified in #EDA_TEXT but is
+ * easier to handle that 3 parameters when editing and reading and saving files.
+ */
+ int m_schematicOrientation;
+
+public:
+ SCH_TEXT( const wxPoint& pos = wxPoint( 0, 0 ),
+ const wxString& text = wxEmptyString,
+ KICAD_T aType = SCH_TEXT_T );
+
+ /**
+ * Copy Constructor
+ * clones \a aText into a new object. All members are copied as is except
+ * for the #m_isDangling member which is set to false. This prevents newly
+ * copied objects derived from #SCH_TEXT from having their connection state
+ * improperly set.
+ */
+ SCH_TEXT( const SCH_TEXT& aText );
+
+ ~SCH_TEXT() { }
+
+ virtual wxString GetClass() const
+ {
+ return wxT( "SCH_TEXT" );
+ }
+
+ /**
+ * Function IncrementLabel
+ * increments the label text, if it ends with a number.
+ * @param aIncrement = the increment value to add to the number
+ * ending the text
+ */
+ void IncrementLabel( int aIncrement );
+
+ /**
+ * Function SetOrientation
+ * Set m_schematicOrientation, and initialize
+ * m_orient,m_HJustified and m_VJustified, according to the value of
+ * m_schematicOrientation (for a text )
+ * must be called after changing m_schematicOrientation
+ * @param aSchematicOrientation =
+ * 0 = normal (horizontal, left justified).
+ * 1 = up (vertical)
+ * 2 = (horizontal, right justified). This can be seen as the mirrored position of 0
+ * 3 = bottom . This can be seen as the mirrored position of up
+ */
+ virtual void SetOrientation( int aSchematicOrientation );
+
+ int GetOrientation() { return m_schematicOrientation; }
+
+ int GetShape() const { return m_shape; }
+
+ void SetShape( int aShape ) { m_shape = aShape; }
+
+ /**
+ * Function GetSchematicTextOffset (virtual)
+ * @return the offset between the SCH_TEXT position and the text itself position
+ *
+ * This offset depends on the orientation, the type of text, and the area required to
+ * draw the associated graphic symbol or to put the text above a wire.
+ */
+ virtual wxPoint GetSchematicTextOffset() const;
+
+ virtual void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
+ GR_DRAWMODE draw_mode, EDA_COLOR_T Color = UNSPECIFIED_COLOR );
+
+ /**
+ * Function CreateGraphicShape
+ * Calculates the graphic shape (a polygon) associated to the text
+ * @param aPoints A buffer to fill with polygon corners coordinates
+ * @param Pos Position of the shape, for texts and labels: do nothing
+ * Mainly for derived classes (SCH_SHEET_PIN and Hierarchical labels)
+ */
+ virtual void CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& Pos )
+ {
+ aPoints.clear();
+ }
+
+ virtual void SwapData( SCH_ITEM* aItem );
+
+ virtual const EDA_RECT GetBoundingBox() const;
+
+ virtual bool Save( FILE* aFile ) const;
+
+ virtual bool Load( LINE_READER& aLine, wxString& aErrorMsg );
+
+ virtual int GetPenSize() const;
+
+ // Geometric transforms (used in block operations):
+
+ virtual void Move( const wxPoint& aMoveVector )
+ {
+ m_Pos += aMoveVector;
+ }
+
+ virtual void MirrorY( int aYaxis_position );
+
+ virtual void MirrorX( int aXaxis_position );
+
+ virtual void Rotate( wxPoint aPosition );
+
+ virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
+
+ virtual bool Replace( wxFindReplaceData& aSearchData, void* aAuxData = NULL )
+ {
+ return EDA_ITEM::Replace( aSearchData, m_Text );
+ }
+
+ virtual bool IsReplaceable() const { return true; }
+
+ virtual void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList );
+
+ virtual bool IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList );
+
+ virtual bool IsDangling() const { return m_isDangling; }
+
+ virtual bool IsSelectStateChanged( const wxRect& aRect );
+
+ virtual void GetConnectionPoints( std::vector< wxPoint >& aPoints ) const;
+
+ virtual bool CanIncrementLabel() const { return true; }
+
+ virtual wxString GetSelectMenuText() const;
+
+ virtual BITMAP_DEF GetMenuImage() const { return add_text_xpm; }
+
+ virtual void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
+ SCH_SHEET_PATH* aSheetPath );
+
+ virtual wxPoint GetPosition() const { return m_Pos; }
+
+ virtual void SetPosition( const wxPoint& aPosition ) { m_Pos = aPosition; }
+
+ virtual bool HitTest( const wxPoint& aPosition, int aAccuracy ) const;
+
+ virtual bool HitTest( const EDA_RECT& aRect, bool aContained = false,
+ int aAccuracy = 0 ) const;
+
+ virtual void Plot( PLOTTER* aPlotter );
+
+ virtual EDA_ITEM* Clone() const;
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // override
+#endif
+};
+
+
+class SCH_LABEL : public SCH_TEXT
+{
+public:
+ SCH_LABEL( const wxPoint& pos = wxPoint( 0, 0 ), const wxString& text = wxEmptyString );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~SCH_LABEL() { }
+
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
+ GR_DRAWMODE draw_mode, EDA_COLOR_T Color = UNSPECIFIED_COLOR );
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_LABEL" );
+ }
+
+ void SetOrientation( int aSchematicOrientation );
+
+ wxPoint GetSchematicTextOffset() const;
+
+ void MirrorX( int aXaxis_position );
+
+ void Rotate( wxPoint aPosition );
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ bool Save( FILE* aFile ) const;
+
+ bool Load( LINE_READER& aLine, wxString& aErrorMsg );
+
+ bool IsConnectable() const { return true; }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_line_label_xpm; }
+
+ bool IsReplaceable() const { return true; }
+
+ EDA_ITEM* Clone() const;
+
+private:
+ bool doIsConnected( const wxPoint& aPosition ) const { return m_Pos == aPosition; }
+};
+
+
+class SCH_GLOBALLABEL : public SCH_TEXT
+{
+public:
+ SCH_GLOBALLABEL( const wxPoint& pos = wxPoint( 0, 0 ), const wxString& text = wxEmptyString );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~SCH_GLOBALLABEL() { }
+
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
+ GR_DRAWMODE draw_mode, EDA_COLOR_T Color = UNSPECIFIED_COLOR );
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_GLOBALLABEL" );
+ }
+
+ void SetOrientation( int aSchematicOrientation );
+
+ wxPoint GetSchematicTextOffset() const;
+
+ bool Save( FILE* aFile ) const;
+
+ bool Load( LINE_READER& aLine, wxString& aErrorMsg );
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ void CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& aPos );
+
+ void MirrorY( int aYaxis_position );
+
+ void MirrorX( int aXaxis_position );
+
+ void Rotate( wxPoint aPosition );
+
+ bool IsConnectable() const { return true; }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_glabel_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+private:
+ bool doIsConnected( const wxPoint& aPosition ) const { return m_Pos == aPosition; }
+};
+
+
+class SCH_HIERLABEL : public SCH_TEXT
+{
+public:
+ SCH_HIERLABEL( const wxPoint& pos = wxPoint( 0, 0 ),
+ const wxString& text = wxEmptyString,
+ KICAD_T aType = SCH_HIERARCHICAL_LABEL_T );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~SCH_HIERLABEL() { }
+
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
+ GR_DRAWMODE draw_mode, EDA_COLOR_T Color = UNSPECIFIED_COLOR );
+
+ wxString GetClass() const
+ {
+ return wxT( "SCH_HIERLABEL" );
+ }
+
+ void SetOrientation( int aSchematicOrientation );
+
+ wxPoint GetSchematicTextOffset() const;
+
+ void CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& Pos );
+
+ bool Save( FILE* aFile ) const;
+
+ bool Load( LINE_READER& aLine, wxString& aErrorMsg );
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ void MirrorY( int aYaxis_position );
+
+ void MirrorX( int aXaxis_position );
+
+ void Rotate( wxPoint aPosition );
+
+ bool IsConnectable() const { return true; }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_hierarchical_label_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+private:
+ bool doIsConnected( const wxPoint& aPosition ) const { return m_Pos == aPosition; }
+};
+
+#endif /* CLASS_TEXT_LABEL_H */
diff --git a/eeschema/sch_validators.cpp b/eeschema/sch_validators.cpp
new file mode 100644
index 0000000..b506f27
--- /dev/null
+++ b/eeschema/sch_validators.cpp
@@ -0,0 +1,141 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2016 Wayne Stambaugh, stambaughw@gmail.com
+ * Copyright (C) 2016-2017 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_validators.cpp
+ * @brief Implementation of control validators for schematic dialogs.
+ */
+
+#include <sch_validators.h>
+#include <template_fieldnames.h>
+
+SCH_FIELD_VALIDATOR::SCH_FIELD_VALIDATOR( bool aIsCmplibEditor,
+ int aFieldId, wxString* aValue ) :
+ wxTextValidator( wxFILTER_EXCLUDE_CHAR_LIST, aValue )
+{
+ m_fieldId = aFieldId;
+ m_isLibEditor = aIsCmplibEditor;
+
+ // Fields cannot contain carriage returns, line feeds, or tabs.
+ wxString excludes( "\r\n\t" );
+
+ // The reference field cannot contain spaces.
+ if( aFieldId == REFERENCE )
+ excludes += " ";
+ else if( aFieldId == VALUE && m_isLibEditor )
+ excludes += " ";
+
+ long style = GetStyle();
+
+ // The reference and value fields cannot be empty.
+ if( aFieldId == REFERENCE || aFieldId == VALUE )
+ style |= wxFILTER_EMPTY;
+
+ SetStyle( style );
+ SetCharExcludes( excludes );
+}
+
+
+SCH_FIELD_VALIDATOR::SCH_FIELD_VALIDATOR( const SCH_FIELD_VALIDATOR& aValidator ) :
+ wxTextValidator( aValidator )
+{
+ m_fieldId = aValidator.m_fieldId;
+ m_isLibEditor = aValidator.m_isLibEditor;
+}
+
+
+bool SCH_FIELD_VALIDATOR::Validate( wxWindow *aParent )
+{
+ // If window is disabled, simply return
+ if( !m_validatorWindow->IsEnabled() )
+ return true;
+
+ wxTextEntry * const text = GetTextEntry();
+
+ if( !text )
+ return false;
+
+ wxString val( text->GetValue() );
+ wxString tmp = val.Clone(); // For trailing and leading white space tests.
+ wxString fieldName;
+
+ switch( m_fieldId )
+ {
+ case REFERENCE: fieldName = _( "reference designator" ); break;
+ case VALUE: fieldName = _( "value" ); break;
+ case FOOTPRINT: fieldName = _( "footprint" ); break;
+ case DATASHEET: fieldName = _( "data sheet" ); break;
+ default: fieldName = _( "user defined" ); break;
+ };
+
+ wxString errorMsg;
+
+ // We can only do some kinds of validation once the input is complete, so
+ // check for them here:
+ if( HasFlag( wxFILTER_EMPTY ) && val.empty() )
+ errorMsg.Printf( _( "The %s field cannot be empty." ), fieldName );
+ else if( HasFlag( wxFILTER_EXCLUDE_CHAR_LIST ) && ContainsExcludedCharacters( val ) )
+ {
+ wxArrayString whiteSpace;
+ bool spaceIllegal = ( m_fieldId == REFERENCE ) ||
+ ( m_fieldId == VALUE && m_isLibEditor );
+
+ if( val.Find( '\r' ) != wxNOT_FOUND )
+ whiteSpace.Add( _( "carriage return" ) );
+ if( val.Find( '\n' ) != wxNOT_FOUND )
+ whiteSpace.Add( _( "line feed" ) );
+ if( val.Find( '\t' ) != wxNOT_FOUND )
+ whiteSpace.Add( _( "tab" ) );
+ if( spaceIllegal && (val.Find( ' ' ) != wxNOT_FOUND) )
+ whiteSpace.Add( _( "space" ) );
+
+ wxString badChars;
+
+ if( whiteSpace.size() == 1 )
+ badChars = whiteSpace[0];
+ else if( whiteSpace.size() == 2 )
+ badChars.Printf( _( "%s or %s" ), whiteSpace[0], whiteSpace[1] );
+ else if( whiteSpace.size() == 3 )
+ badChars.Printf( _( "%s, %s, or %s" ), whiteSpace[0], whiteSpace[1], whiteSpace[2] );
+ else if( whiteSpace.size() == 4 )
+ badChars.Printf( _( "%s, %s, %s, or %s" ),
+ whiteSpace[0], whiteSpace[1], whiteSpace[2], whiteSpace[3] );
+ else
+ wxCHECK_MSG( false, true, wxT( "Invalid illegal character in field validator." ) );
+
+ errorMsg.Printf( _( "The %s field cannot contain %s characters." ), fieldName, badChars );
+ }
+
+ if ( !errorMsg.empty() )
+ {
+ m_validatorWindow->SetFocus();
+
+ wxMessageBox( errorMsg, _( "Field Validation Error" ),
+ wxOK | wxICON_EXCLAMATION, aParent );
+
+ return false;
+ }
+
+ return true;
+}
diff --git a/eeschema/sch_validators.h b/eeschema/sch_validators.h
new file mode 100644
index 0000000..6c34060
--- /dev/null
+++ b/eeschema/sch_validators.h
@@ -0,0 +1,72 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2016 Wayne Stambaugh, stambaughw@gmail.com
+ * Copyright (C) 2016 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sch_validators.h
+ * @brief Defintions of control validators for schematic dialogs.
+ */
+
+#ifndef _SCH_VALIDATORS_H_
+#define _SCH_VALIDATORS_H_
+
+
+#include <wx/valtext.h>
+
+/**
+ * class SCH_FILED_VALIDATOR
+ *
+ * is the text control validator used for validating the text allowed in library and
+ * schematic component fields.
+ * Note
+ * Reference field does not accept spaces
+ * Value field does not accept spaces in Component Library Editor, because in .lib component
+ * libraries, the value field is the component name in lib, and spaces are not allowed
+ * in component names in lib
+ */
+class SCH_FIELD_VALIDATOR : public wxTextValidator
+{
+ int m_fieldId;
+ bool m_isLibEditor;
+
+public:
+ SCH_FIELD_VALIDATOR( bool aIsCmplibEditor, int aFieldId, wxString* aValue = NULL );
+
+ SCH_FIELD_VALIDATOR( const SCH_FIELD_VALIDATOR& aValidator );
+
+ virtual wxObject* Clone() const { return new SCH_FIELD_VALIDATOR( *this ); }
+
+ /**
+ * Function Validate
+ *
+ * overrides the default Validate() function provided by wxTextValidate to provide
+ * better error messages.
+ *
+ * @param aParent - a pointer to the parent window of the error message dialog.
+ * @return true if the text in the control is valid otherwise false.
+ */
+ virtual bool Validate( wxWindow *aParent );
+};
+
+
+#endif // _SCH_VALIDATORS_H_
diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp
new file mode 100644
index 0000000..927e44c
--- /dev/null
+++ b/eeschema/schedit.cpp
@@ -0,0 +1,1163 @@
+ /*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file schedit.cpp
+ */
+
+#include <fctsys.h>
+#include <kiway.h>
+#include <gr_basic.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <eda_doc.h>
+#include <schframe.h>
+#include <kicad_device_context.h>
+#include <hotkeys_basic.h>
+
+#include <general.h>
+#include <eeschema_id.h>
+#include <protos.h>
+#include <class_library.h>
+#include <sch_bus_entry.h>
+#include <sch_marker.h>
+#include <sch_component.h>
+#include <sch_junction.h>
+#include <sch_line.h>
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+
+
+void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ wxPoint pos;
+ SCH_SCREEN* screen = GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+
+ pos = wxGetMousePosition();
+
+ pos.y += 20;
+
+ // If needed, stop the current command and deselect current tool
+ switch( id )
+ {
+ case wxID_CUT:
+ case wxID_COPY:
+ case ID_POPUP_CANCEL_CURRENT_COMMAND:
+ case ID_POPUP_SCH_ENTRY_SELECT_SLASH:
+ case ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH:
+ case ID_POPUP_SCH_BEGIN_WIRE:
+ case ID_POPUP_SCH_BEGIN_BUS:
+ case ID_POPUP_END_LINE:
+ case ID_POPUP_SCH_SET_SHAPE_TEXT:
+ case ID_POPUP_SCH_CLEANUP_SHEET:
+ case ID_POPUP_SCH_END_SHEET:
+ case ID_POPUP_SCH_RESIZE_SHEET:
+ case ID_POPUP_IMPORT_HLABEL_TO_SHEETPIN:
+ case ID_POPUP_SCH_INIT_CMP:
+ case ID_POPUP_SCH_DISPLAYDOC_CMP:
+ case ID_POPUP_SCH_EDIT_CONVERT_CMP:
+ case ID_POPUP_DELETE_BLOCK:
+ case ID_POPUP_PLACE_BLOCK:
+ case ID_POPUP_ZOOM_BLOCK:
+ case ID_POPUP_DRAG_BLOCK:
+ case ID_POPUP_COPY_BLOCK:
+ case ID_POPUP_SCH_DELETE_NODE:
+ case ID_POPUP_SCH_DELETE_CONNECTION:
+ case ID_POPUP_SCH_ENTER_SHEET:
+ case ID_POPUP_SCH_LEAVE_SHEET:
+ case ID_POPUP_SCH_ADD_JUNCTION:
+ case ID_POPUP_SCH_ADD_LABEL:
+ case ID_POPUP_SCH_GETINFO_MARKER:
+
+ /* At this point: Do nothing. these commands do not need to stop the
+ * current command (mainly a block command) or reset the current state
+ * They will be executed later, in next switch structure.
+ */
+ break;
+
+ case ID_POPUP_SCH_DELETE_CMP:
+ case ID_POPUP_SCH_DELETE:
+
+ // Stop the current command (if any) but keep the current tool
+ m_canvas->EndMouseCapture();
+ break;
+
+ default:
+
+ // Stop the current command and deselect the current tool
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+ break;
+ }
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+ item = screen->GetCurItem(); // Can be modified by previous calls.
+
+ switch( id )
+ {
+ case ID_HIERARCHY:
+ InstallHierarchyFrame( pos );
+ SetRepeatItem( NULL );
+ break;
+
+ case wxID_CUT:
+ if( screen->m_BlockLocate.GetCommand() != BLOCK_MOVE )
+ break;
+
+ screen->m_BlockLocate.SetCommand( BLOCK_DELETE );
+ screen->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ SetRepeatItem( NULL );
+ SetSheetNumberAndCount();
+ break;
+
+ case wxID_PASTE:
+ HandleBlockBegin( &dc, BLOCK_PASTE, GetCrossHairPosition() );
+ break;
+
+ case ID_POPUP_SCH_ENTRY_SELECT_SLASH:
+ m_canvas->MoveCursorToCrossHair();
+ SetBusEntryShape( &dc, dynamic_cast<SCH_BUS_ENTRY_BASE*>( item ), '/' );
+ break;
+
+ case ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH:
+ m_canvas->MoveCursorToCrossHair();
+ SetBusEntryShape( &dc, dynamic_cast<SCH_BUS_ENTRY_BASE*>( item ), '\\' );
+ break;
+
+ case ID_POPUP_CANCEL_CURRENT_COMMAND:
+ if( m_canvas->IsMouseCaptured() )
+ {
+ m_canvas->EndMouseCapture();
+ SetToolID( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString );
+ }
+ else
+ {
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ }
+
+ break;
+
+ case ID_POPUP_END_LINE:
+ m_canvas->MoveCursorToCrossHair();
+ EndSegment( &dc );
+ break;
+
+ case ID_POPUP_SCH_BEGIN_WIRE:
+ m_canvas->MoveCursorToCrossHair();
+ OnLeftClick( &dc, GetCrossHairPosition() );
+ break;
+
+ case ID_POPUP_SCH_BEGIN_BUS:
+ m_canvas->MoveCursorToCrossHair();
+ OnLeftClick( &dc, GetCrossHairPosition() );
+ break;
+
+ case ID_POPUP_SCH_SET_SHAPE_TEXT:
+ // Not used
+ break;
+
+ case ID_POPUP_SCH_DELETE_NODE:
+ case ID_POPUP_SCH_DELETE_CONNECTION:
+ m_canvas->MoveCursorToCrossHair();
+ DeleteConnection( id == ID_POPUP_SCH_DELETE_CONNECTION );
+ screen->SetCurItem( NULL );
+ SetRepeatItem( NULL );
+ screen->TestDanglingEnds( m_canvas, &dc );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_SCH_BREAK_WIRE:
+ {
+ DLIST< SCH_ITEM > oldWires;
+
+ oldWires.SetOwnership( false ); // Prevent DLIST for deleting items in destructor.
+ m_canvas->MoveCursorToCrossHair();
+ screen->ExtractWires( oldWires, true );
+ screen->BreakSegment( GetCrossHairPosition() );
+
+ if( oldWires.GetCount() != 0 )
+ {
+ PICKED_ITEMS_LIST oldItems;
+
+ oldItems.m_Status = UR_WIRE_IMAGE;
+
+ while( oldWires.GetCount() != 0 )
+ {
+ ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE );
+ oldItems.PushItem( picker );
+ }
+
+ SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE );
+ }
+
+ screen->TestDanglingEnds( m_canvas, &dc );
+ }
+ break;
+
+ case ID_POPUP_SCH_DELETE_CMP:
+ case ID_POPUP_SCH_DELETE:
+ if( item == NULL )
+ break;
+
+ DeleteItem( item );
+ screen->SetCurItem( NULL );
+ SetRepeatItem( NULL );
+ screen->TestDanglingEnds( m_canvas, &dc );
+ SetSheetNumberAndCount();
+ OnModify();
+ break;
+
+ case ID_POPUP_SCH_END_SHEET:
+ m_canvas->MoveCursorToCrossHair();
+ addCurrentItemToList();
+ break;
+
+ case ID_POPUP_SCH_RESIZE_SHEET:
+ ReSizeSheet( (SCH_SHEET*) item, &dc );
+ screen->TestDanglingEnds( m_canvas, &dc );
+ break;
+
+ case ID_POPUP_IMPORT_HLABEL_TO_SHEETPIN:
+ if( item != NULL && item->Type() == SCH_SHEET_T )
+ screen->SetCurItem( ImportSheetPin( (SCH_SHEET*) item, &dc ) );
+ break;
+
+ case ID_POPUP_SCH_CLEANUP_SHEET:
+ if( item != NULL && item->Type() == SCH_SHEET_T )
+ {
+ SCH_SHEET* sheet = (SCH_SHEET*) item;
+
+ if( !sheet->HasUndefinedPins() )
+ {
+ DisplayInfoMessage( this,
+ _( "There are no undefined labels in this sheet to clean up." ) );
+ return;
+ }
+
+ if( !IsOK( this, _( "Do you wish to cleanup this sheet?" ) ) )
+ return;
+
+ /* Save sheet in undo list before cleaning up unreferenced hierarchical labels. */
+ SaveCopyInUndoList( sheet, UR_CHANGED );
+ sheet->CleanupSheet();
+ OnModify();
+ m_canvas->RefreshDrawingRect( sheet->GetBoundingBox() );
+ }
+ break;
+
+ case ID_POPUP_SCH_INIT_CMP:
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_SCH_EDIT_CONVERT_CMP:
+
+ // Ensure the struct is a component (could be a struct of a component, like Field, text..)
+ if( item && item->Type() == SCH_COMPONENT_T )
+ {
+ m_canvas->MoveCursorToCrossHair();
+ ConvertPart( (SCH_COMPONENT*) item, &dc );
+ }
+
+ break;
+
+ case ID_POPUP_SCH_DISPLAYDOC_CMP:
+
+ // Ensure the struct is a component (could be a piece of a component, like Field, text..)
+ if( item && item->Type() == SCH_COMPONENT_T )
+ {
+ if( PART_LIBS* libs = Prj().SchLibs() )
+ {
+ LIB_ALIAS* entry = libs->FindLibraryEntry( ( (SCH_COMPONENT*) item )->GetPartName() );
+
+ if( entry && !!entry->GetDocFileName() )
+ {
+ SEARCH_STACK* lib_search = Prj().SchSearchS();
+
+ GetAssociatedDocument( this, entry->GetDocFileName(), lib_search );
+ }
+ }
+ }
+ break;
+
+ case ID_POPUP_SCH_ENTER_SHEET:
+
+ if( item && (item->Type() == SCH_SHEET_T) )
+ {
+ m_CurrentSheet->Push( (SCH_SHEET*) item );
+ DisplayCurrentSheet();
+ }
+
+ break;
+
+ case ID_POPUP_SCH_LEAVE_SHEET:
+ if( m_CurrentSheet->Last() != g_RootSheet )
+ {
+ m_CurrentSheet->Pop();
+ DisplayCurrentSheet();
+ }
+
+ break;
+
+ case wxID_COPY: // really this is a Save block for paste
+ screen->m_BlockLocate.SetCommand( BLOCK_SAVE );
+ screen->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_PLACE_BLOCK:
+ m_canvas->SetAutoPanRequest( false );
+ m_canvas->MoveCursorToCrossHair();
+ HandleBlockPlace( &dc );
+ break;
+
+ case ID_POPUP_ZOOM_BLOCK:
+ screen->m_BlockLocate.SetCommand( BLOCK_ZOOM );
+ screen->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_DELETE_BLOCK:
+ if( screen->m_BlockLocate.GetCommand() != BLOCK_MOVE )
+ break;
+
+ m_canvas->MoveCursorToCrossHair();
+ screen->m_BlockLocate.SetCommand( BLOCK_DELETE );
+ screen->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ SetSheetNumberAndCount();
+ break;
+
+ case ID_POPUP_COPY_BLOCK:
+ if( screen->m_BlockLocate.GetCommand() != BLOCK_MOVE )
+ break;
+
+ m_canvas->MoveCursorToCrossHair();
+ screen->m_BlockLocate.SetCommand( BLOCK_COPY );
+ screen->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_DRAG_BLOCK:
+ if( screen->m_BlockLocate.GetCommand() != BLOCK_MOVE )
+ break;
+
+ m_canvas->MoveCursorToCrossHair();
+ screen->m_BlockLocate.SetCommand( BLOCK_DRAG );
+ screen->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_SCH_ADD_JUNCTION:
+ m_canvas->MoveCursorToCrossHair();
+ screen->SetCurItem( AddJunction( &dc, GetCrossHairPosition(), true ) );
+ screen->TestDanglingEnds( m_canvas, &dc );
+ screen->SetCurItem( NULL );
+ break;
+
+ case ID_POPUP_SCH_ADD_LABEL:
+ case ID_POPUP_SCH_ADD_GLABEL:
+ screen->SetCurItem( CreateNewText( &dc, id == ID_POPUP_SCH_ADD_LABEL ?
+ LAYER_LOCLABEL : LAYER_GLOBLABEL ) );
+ item = screen->GetCurItem();
+
+ if( item )
+ addCurrentItemToList();
+
+ break;
+
+ case ID_POPUP_SCH_GETINFO_MARKER:
+ if( item && item->Type() == SCH_MARKER_T )
+ ( (SCH_MARKER*) item )->DisplayMarkerInfo( this );
+
+ break;
+
+ default: // Log error:
+ wxFAIL_MSG( wxString::Format( wxT( "Cannot process command event ID %d" ),
+ event.GetId() ) );
+ break;
+ }
+
+ // End switch ( id ) (Command execution)
+
+ if( GetToolId() == ID_NO_TOOL_SELECTED )
+ SetRepeatItem( NULL );
+}
+
+
+void SCH_EDIT_FRAME::OnMoveItem( wxCommandEvent& aEvent )
+{
+ SCH_SCREEN* screen = GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+
+ if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK )
+ {
+ // trying to move an item when there is a block at the same time is not acceptable
+ return;
+ }
+
+ if( item == NULL )
+ {
+ // If we didn't get here by a hot key, then something has gone wrong.
+ if( aEvent.GetInt() == 0 )
+ return;
+
+ EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();
+
+ wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
+
+ item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::MovableItems,
+ aEvent.GetInt() );
+
+ // Exit if no item found at the current location or the item is already being edited.
+ if( (item == NULL) || (item->GetFlags() != 0) )
+ return;
+ }
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ switch( item->Type() )
+ {
+ case SCH_LINE_T:
+ break;
+
+ case SCH_JUNCTION_T:
+ case SCH_NO_CONNECT_T:
+ case SCH_BUS_BUS_ENTRY_T:
+ case SCH_BUS_WIRE_ENTRY_T:
+ case SCH_LABEL_T:
+ case SCH_GLOBAL_LABEL_T:
+ case SCH_HIERARCHICAL_LABEL_T:
+ case SCH_TEXT_T:
+ case SCH_COMPONENT_T:
+ case SCH_SHEET_PIN_T:
+ case SCH_FIELD_T:
+ case SCH_SHEET_T:
+ PrepareMoveItem( item, &dc );
+ break;
+
+ case SCH_BITMAP_T:
+ // move an image is a special case:
+ // we cannot undraw/redraw a bitmap just using our xor mode
+ // the MoveImage function handle this undraw/redraw difficulty
+ // By redrawing the full bounding box
+ MoveImage( (SCH_BITMAP*) item, &dc );
+ break;
+
+ case SCH_MARKER_T:
+ // Moving a marker has no sense
+ break;
+
+ default:
+ // Unknown items cannot be moved
+ wxFAIL_MSG( wxString::Format(
+ wxT( "Cannot move item type %d" ), item->Type() ) );
+ break;
+ }
+
+ if( GetToolId() == ID_NO_TOOL_SELECTED )
+ SetRepeatItem( NULL );
+}
+
+
+void SCH_EDIT_FRAME::OnCancelCurrentCommand( wxCommandEvent& aEvent )
+{
+ SCH_SCREEN* screen = GetScreen();
+
+ if( screen->IsBlockActive() )
+ {
+ m_canvas->SetCursor( (wxStockCursor) m_canvas->GetDefaultCursor() );
+ screen->ClearBlockCommand();
+
+ // Stop the current command (if any) but keep the current tool
+ m_canvas->EndMouseCapture();
+ }
+ else
+ {
+ if( m_canvas->IsMouseCaptured() ) // Stop the current command but keep the current tool
+ m_canvas->EndMouseCapture();
+ else // Deselect current tool
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+ }
+}
+
+
+void SCH_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent )
+{
+ int id = aEvent.GetId();
+
+ // Stop the current command and deselect the current tool.
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+
+ switch( id )
+ {
+ case ID_NO_TOOL_SELECTED:
+ SetToolID( id, m_canvas->GetDefaultCursor(), _( "No tool selected" ) );
+ break;
+
+ case ID_HIERARCHY_PUSH_POP_BUTT:
+ SetToolID( id, wxCURSOR_HAND, _( "Descend or ascend hierarchy" ) );
+ break;
+
+ case ID_NOCONN_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add no connect" ) );
+ break;
+
+ case ID_WIRE_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add wire" ) );
+ break;
+
+ case ID_BUS_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add bus" ) );
+ break;
+
+ case ID_LINE_COMMENT_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add lines" ) );
+ break;
+
+ case ID_JUNCTION_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add junction" ) );
+ break;
+
+ case ID_LABEL_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add label" ) );
+ break;
+
+ case ID_GLABEL_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add global label" ) );
+ break;
+
+ case ID_HIERLABEL_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add hierarchical label" ) );
+ break;
+
+ case ID_TEXT_COMMENT_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) );
+ break;
+
+ case ID_ADD_IMAGE_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add image" ) );
+ break;
+
+ case ID_WIRETOBUS_ENTRY_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add wire to bus entry" ) );
+ break;
+
+ case ID_BUSTOBUS_ENTRY_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add bus to bus entry" ) );
+ break;
+
+ case ID_SHEET_SYMBOL_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add sheet" ) );
+ break;
+
+ case ID_SHEET_PIN_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add sheet pins" ) );
+ break;
+
+ case ID_IMPORT_HLABEL_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Import sheet pins" ) );
+ break;
+
+ case ID_SCH_PLACE_COMPONENT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add component" ) );
+ break;
+
+ case ID_PLACE_POWER_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add power" ) );
+ break;
+
+ case ID_SCHEMATIC_DELETE_ITEM_BUTT:
+ SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
+ break;
+
+ default:
+ SetRepeatItem( NULL );
+ }
+
+ // Simulate left click event if we got here from a hot key.
+ if( aEvent.GetClientObject() != NULL )
+ {
+ EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();
+
+ wxPoint pos = data->GetPosition();
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+ OnLeftClick( &dc, pos );
+ }
+}
+
+
+void SCH_EDIT_FRAME::OnUpdateSelectTool( wxUpdateUIEvent& aEvent )
+{
+ if( aEvent.GetEventObject() == m_drawToolBar )
+ aEvent.Check( GetToolId() == aEvent.GetId() );
+}
+
+
+void SCH_EDIT_FRAME::DeleteConnection( bool aFullConnection )
+{
+ PICKED_ITEMS_LIST pickList;
+ SCH_SCREEN* screen = GetScreen();
+ wxPoint pos = GetCrossHairPosition();
+
+ if( screen->GetConnection( pos, pickList, aFullConnection ) != 0 )
+ {
+ DeleteItemsInList( m_canvas, pickList );
+ OnModify();
+ }
+}
+
+
+bool SCH_EDIT_FRAME::DeleteItemAtCrossHair( wxDC* DC )
+{
+ SCH_ITEM* item;
+ SCH_SCREEN* screen = GetScreen();
+
+ item = LocateItem( GetCrossHairPosition(), SCH_COLLECTOR::ParentItems );
+
+ if( item )
+ {
+ bool itemHasConnections = item->IsConnectable();
+
+ screen->SetCurItem( NULL );
+ SetRepeatItem( NULL );
+ DeleteItem( item );
+
+ if( itemHasConnections )
+ screen->TestDanglingEnds( m_canvas, DC );
+
+ OnModify();
+ return true;
+ }
+
+ return false;
+}
+
+// This function is a callback function, called by the mouse cursor movin event
+// when an item is currently moved
+static void moveItemWithMouseCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase )
+{
+ SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+
+ wxCHECK_RET( (item != NULL), wxT( "Cannot move invalid schematic item." ) );
+
+ SCH_COMPONENT* cmp = NULL;
+
+ if( item->Type() == SCH_COMPONENT_T )
+ cmp = static_cast< SCH_COMPONENT* >( item );
+
+#ifndef USE_WX_OVERLAY
+ // Erase the current item at its current position.
+ if( aErase )
+ {
+ if( cmp ) // Use fast mode (do not draw pin texts)
+ cmp->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode, UNSPECIFIED_COLOR, false );
+ else
+ item->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
+ }
+#endif
+
+ wxPoint cpos = aPanel->GetParent()->GetCrossHairPosition();
+ cpos -= item->GetStoredPos();
+
+ item->SetPosition( cpos );
+
+ // Draw the item item at it's new position.
+ item->SetWireImage(); // While moving, the item may choose to render differently
+
+ if( cmp ) // Use fast mode (do not draw pin texts)
+ cmp->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode, UNSPECIFIED_COLOR, false );
+ else
+ item->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
+}
+
+
+static void abortMoveItem( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
+{
+ SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+ SCH_EDIT_FRAME* parent = (SCH_EDIT_FRAME*) aPanel->GetParent();
+
+ parent->SetRepeatItem( NULL );
+ screen->SetCurItem( NULL );
+
+ if( item == NULL ) /* no current item */
+ return;
+
+ if( item->IsNew() )
+ {
+ delete item;
+ item = NULL;
+ }
+ else
+ {
+ SCH_ITEM* oldItem = parent->GetUndoItem();
+
+ SCH_ITEM* currentItem;
+
+ // Items that are children of other objects are undone by swapping the contents
+ // of the parent items.
+ if( (item->Type() == SCH_SHEET_PIN_T) || (item->Type() == SCH_FIELD_T) )
+ {
+ currentItem = (SCH_ITEM*) item->GetParent();
+ }
+ else
+ {
+ currentItem = item;
+ }
+
+ wxCHECK_RET( oldItem != NULL && currentItem->Type() == oldItem->Type(),
+ wxT( "Cannot restore undefined or bad last schematic item." ) );
+
+ // Never delete existing item, because it can be referenced by an undo/redo command
+ // Just restore its data
+ currentItem->SwapData( oldItem );
+
+ // Erase the wire representation before the 'normal' view is drawn.
+ if ( item->IsWireImage() )
+ item->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
+
+ item->ClearFlags();
+ }
+
+ aPanel->Refresh();
+}
+
+
+void SCH_EDIT_FRAME::PrepareMoveItem( SCH_ITEM* aItem, wxDC* aDC )
+{
+ wxCHECK_RET( aItem != NULL, wxT( "Cannot move invalid schematic item" ) );
+
+ SetRepeatItem( NULL );
+
+ if( !aItem->IsNew() )
+ {
+ if( (aItem->Type() == SCH_SHEET_PIN_T) || (aItem->Type() == SCH_FIELD_T) )
+ SetUndoItem( (SCH_ITEM*) aItem->GetParent() );
+ else
+ SetUndoItem( aItem );
+ }
+
+ aItem->SetFlags( IS_MOVED );
+
+ // For some items, moving the cursor to anchor is not good
+ // (for instance large hierarchical sheets od componants can have
+ // the anchor position outside the canvas)
+ // these items return IsMovableFromAnchorPoint() == false
+ // For these items, do not wrap the cursor
+ if( aItem->IsMovableFromAnchorPoint() )
+ {
+ SetCrossHairPosition( aItem->GetPosition() );
+ m_canvas->MoveCursorToCrossHair();
+ aItem->SetStoredPos( wxPoint( 0,0 ) );
+ }
+ else
+ aItem->SetStoredPos( GetCrossHairPosition() - aItem->GetPosition() );
+
+ OnModify();
+
+ GetScreen()->SetCurItem( aItem );
+ m_canvas->SetMouseCapture( moveItemWithMouseCursor, abortMoveItem );
+
+ m_canvas->Refresh();
+}
+
+
+void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
+{
+ SCH_SCREEN* screen = GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ // Allows block rotate operation on hot key.
+ if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK )
+ {
+ screen->m_BlockLocate.SetCommand( BLOCK_ROTATE );
+ HandleBlockEnd( &dc );
+ return;
+ }
+
+ if( item == NULL )
+ {
+ // If we didn't get here by a hot key, then something has gone wrong.
+ if( aEvent.GetInt() == 0 )
+ return;
+
+ EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();
+
+ wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
+
+ item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::RotatableItems,
+ aEvent.GetInt() );
+
+ // Exit if no item found at the current location or the item is already being edited.
+ if( (item == NULL) || (item->GetFlags() != 0) )
+ return;
+ }
+
+ switch( item->Type() )
+ {
+ case SCH_COMPONENT_T:
+ if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE )
+ OrientComponent( CMP_ROTATE_CLOCKWISE );
+ else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE )
+ OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE );
+ else
+ wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) );
+
+ break;
+
+ case SCH_TEXT_T:
+ case SCH_LABEL_T:
+ case SCH_GLOBAL_LABEL_T:
+ case SCH_HIERARCHICAL_LABEL_T:
+ m_canvas->MoveCursorToCrossHair();
+ ChangeTextOrient( (SCH_TEXT*) item, &dc );
+ break;
+
+ case SCH_FIELD_T:
+ m_canvas->MoveCursorToCrossHair();
+ RotateField( (SCH_FIELD*) item, &dc );
+ break;
+
+ case SCH_BITMAP_T:
+ RotateImage( (SCH_BITMAP*) item );
+ break;
+
+ case SCH_SHEET_T:
+ if( !item->IsNew() ) // rotate a sheet during its creation has no sense
+ {
+ bool retCCW = ( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE );
+ RotateHierarchicalSheet( static_cast<SCH_SHEET*>( item ), retCCW );
+ }
+
+ break;
+
+ case SCH_JUNCTION_T:
+ case SCH_NO_CONNECT_T:
+ // these items are not rotated, because rotation does not change them.
+ break;
+
+ default:
+ // Other items (wires...) cannot be rotated, at least during creation
+ if( item->IsNew() )
+ break;
+
+ wxFAIL_MSG( wxString::Format( wxT( "Cannot rotate schematic item type %s." ),
+ GetChars( item->GetClass() ) ) );
+ }
+
+ if( item->GetFlags() == 0 )
+ screen->SetCurItem( NULL );
+}
+
+
+void SCH_EDIT_FRAME::OnEditItem( wxCommandEvent& aEvent )
+{
+ SCH_SCREEN* screen = GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+
+ if( item == NULL )
+ {
+ // If we didn't get here by a hot key, then something has gone wrong.
+ if( aEvent.GetInt() == 0 )
+ return;
+
+ EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();
+
+ wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
+
+ // Set the locat filter, according to the edit command
+ const KICAD_T* filterList = SCH_COLLECTOR::EditableItems;
+ const KICAD_T* filterListAux = NULL;
+
+ switch( aEvent.GetId() )
+ {
+ case ID_SCH_EDIT_COMPONENT_REFERENCE:
+ filterList = SCH_COLLECTOR::CmpFieldReferenceOnly;
+ filterListAux = SCH_COLLECTOR::ComponentsOnly;
+ break;
+
+ case ID_SCH_EDIT_COMPONENT_VALUE:
+ filterList = SCH_COLLECTOR::CmpFieldValueOnly;
+ filterListAux = SCH_COLLECTOR::ComponentsOnly;
+ break;
+
+ case ID_SCH_EDIT_COMPONENT_FOOTPRINT:
+ filterList = SCH_COLLECTOR::CmpFieldFootprintOnly;
+ filterListAux = SCH_COLLECTOR::ComponentsOnly;
+ break;
+
+ default:
+ break;
+ }
+
+ item = LocateAndShowItem( data->GetPosition(), filterList, aEvent.GetInt() );
+
+ // If no item found, and if an auxiliary filter exists, try to use it
+ if( !item && filterListAux )
+ item = LocateAndShowItem( data->GetPosition(), filterListAux, aEvent.GetInt() );
+
+ // Exit if no item found at the current location or the item is already being edited.
+ if( (item == NULL) || (item->GetFlags() != 0) )
+ return;
+ }
+
+ switch( item->Type() )
+ {
+ case SCH_COMPONENT_T:
+ {
+ switch( aEvent.GetId() )
+ {
+ case ID_SCH_EDIT_COMPONENT_REFERENCE:
+ EditComponentFieldText( ( (SCH_COMPONENT*) item )->GetField( REFERENCE ) );
+ break;
+
+ case ID_SCH_EDIT_COMPONENT_VALUE:
+ EditComponentFieldText( ( (SCH_COMPONENT*) item )->GetField( VALUE ) );
+ break;
+
+ case ID_SCH_EDIT_COMPONENT_FOOTPRINT:
+ EditComponentFieldText( ( (SCH_COMPONENT*) item )->GetField( FOOTPRINT ) );
+ break;
+
+ case ID_SCH_EDIT_ITEM:
+ EditComponent( (SCH_COMPONENT*) item );
+ break;
+
+ default:
+ wxFAIL_MSG( wxString::Format( wxT( "Invalid schematic component edit command ID %d" ),
+ aEvent.GetId() ) );
+ }
+
+ break;
+ }
+
+ case SCH_SHEET_T:
+ if( EditSheet( (SCH_SHEET*) item, m_CurrentSheet ) )
+ m_canvas->Refresh();
+ break;
+
+ case SCH_SHEET_PIN_T:
+ EditSheetPin( (SCH_SHEET_PIN*) item, true );
+ break;
+
+ case SCH_TEXT_T:
+ case SCH_LABEL_T:
+ case SCH_GLOBAL_LABEL_T:
+ case SCH_HIERARCHICAL_LABEL_T:
+ EditSchematicText( (SCH_TEXT*) item );
+ break;
+
+ case SCH_FIELD_T:
+ EditComponentFieldText( (SCH_FIELD*) item );
+ break;
+
+ case SCH_BITMAP_T:
+ EditImage( (SCH_BITMAP*) item );
+ break;
+
+ case SCH_LINE_T: // These items have no param to edit
+ case SCH_MARKER_T:
+ case SCH_JUNCTION_T:
+ case SCH_NO_CONNECT_T:
+ break;
+
+ default: // Unexpected item
+ wxFAIL_MSG( wxString::Format( wxT( "Cannot edit schematic item type %s." ),
+ GetChars( item->GetClass() ) ) );
+ }
+
+ if( item->GetFlags() == 0 )
+ screen->SetCurItem( NULL );
+}
+
+
+void SCH_EDIT_FRAME::OnDragItem( wxCommandEvent& aEvent )
+{
+ SCH_SCREEN* screen = GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+
+ // The easiest way to handle a menu or a hot key drag command
+ // is to simulate a block drag command
+ //
+ // When a drag item is requested, some items use a BLOCK_DRAG_ITEM drag type
+ // an some items use a BLOCK_DRAG drag type (mainly a junction)
+ // a BLOCK_DRAG collects all items in a block (here a 2x2 rect centered on the cursor)
+ // and BLOCK_DRAG_ITEM drag only the selected item
+ BLOCK_COMMAND_T dragType = BLOCK_DRAG_ITEM;
+
+ if( item == NULL )
+ {
+ // If we didn't get here by a hot key, then something has gone wrong.
+ if( aEvent.GetInt() == 0 )
+ return;
+
+ EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();
+
+ wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
+
+ item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::DraggableItems,
+ aEvent.GetInt() );
+
+ // Exit if no item found at the current location or the item is already being edited.
+ if( (item == NULL) || (item->GetFlags() != 0) )
+ return;
+
+ // When a junction or a node is found, a BLOCK_DRAG is better
+ if( m_collectedItems.IsCorner() || m_collectedItems.IsNode( false )
+ || m_collectedItems.IsDraggableJunction() )
+ dragType = BLOCK_DRAG;
+ }
+
+ switch( item->Type() )
+ {
+ case SCH_BUS_BUS_ENTRY_T:
+ case SCH_BUS_WIRE_ENTRY_T:
+ case SCH_LINE_T:
+ case SCH_JUNCTION_T:
+ case SCH_COMPONENT_T:
+ case SCH_LABEL_T:
+ case SCH_GLOBAL_LABEL_T:
+ case SCH_HIERARCHICAL_LABEL_T:
+ case SCH_SHEET_T:
+ m_canvas->MoveCursorToCrossHair();
+
+ if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK )
+ {
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ if( !HandleBlockBegin( &dc, dragType, GetCrossHairPosition() ) )
+ break;
+
+ // Give a non null size to the search block:
+ screen->m_BlockLocate.Inflate( 1 );
+ HandleBlockEnd( &dc );
+ }
+
+ break;
+
+ default:
+ wxFAIL_MSG( wxString::Format( wxT( "Cannot drag schematic item type %s." ),
+ GetChars( item->GetClass() ) ) );
+ }
+}
+
+
+void SCH_EDIT_FRAME::OnOrient( wxCommandEvent& aEvent )
+{
+ SCH_SCREEN* screen = GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ // Allows block rotate operation on hot key.
+ if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK )
+ {
+ if( aEvent.GetId() == ID_SCH_MIRROR_X )
+ {
+ m_canvas->MoveCursorToCrossHair();
+ screen->m_BlockLocate.SetMessageBlock( this );
+ screen->m_BlockLocate.SetCommand( BLOCK_MIRROR_X );
+ HandleBlockEnd( &dc );
+ }
+ else if( aEvent.GetId() == ID_SCH_MIRROR_Y )
+ {
+ m_canvas->MoveCursorToCrossHair();
+ screen->m_BlockLocate.SetMessageBlock( this );
+ screen->m_BlockLocate.SetCommand( BLOCK_MIRROR_Y );
+ HandleBlockEnd( &dc );
+ }
+ else
+ {
+ wxFAIL_MSG( wxT( "Unknown block oriention command ID." ) );
+ }
+
+ return;
+ }
+
+ if( item == NULL )
+ {
+ // If we didn't get here by a hot key, then something has gone wrong.
+ if( aEvent.GetInt() == 0 )
+ return;
+
+ EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();
+
+ wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
+
+ item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::OrientableItems,
+ aEvent.GetInt() );
+
+ // Exit if no item found at the current location or the item is already being edited.
+ if( (item == NULL) || (item->GetFlags() != 0) )
+ return;
+ }
+
+
+ switch( item->Type() )
+ {
+ case SCH_COMPONENT_T:
+ if( aEvent.GetId() == ID_SCH_MIRROR_X )
+ OrientComponent( CMP_MIRROR_X );
+ else if( aEvent.GetId() == ID_SCH_MIRROR_Y )
+ OrientComponent( CMP_MIRROR_Y );
+ else if( aEvent.GetId() == ID_SCH_ORIENT_NORMAL )
+ OrientComponent( CMP_NORMAL );
+ else
+ wxFAIL_MSG( wxT( "Invalid orient schematic component command ID." ) );
+
+ break;
+
+ case SCH_BITMAP_T:
+ if( aEvent.GetId() == ID_SCH_MIRROR_X )
+ MirrorImage( (SCH_BITMAP*) item, true );
+ else if( aEvent.GetId() == ID_SCH_MIRROR_Y )
+ MirrorImage( (SCH_BITMAP*) item, false );
+
+ break;
+
+ case SCH_SHEET_T:
+ if( aEvent.GetId() == ID_SCH_MIRROR_X )
+ MirrorSheet( (SCH_SHEET*) item, true );
+ else if( aEvent.GetId() == ID_SCH_MIRROR_Y )
+ MirrorSheet( (SCH_SHEET*) item, false );
+
+ break;
+
+ default:
+ // This object cannot be oriented.
+ ;
+ }
+
+ if( item->GetFlags() == 0 )
+ screen->SetCurItem( NULL );
+}
diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp
new file mode 100644
index 0000000..7c539d0
--- /dev/null
+++ b/eeschema/schematic_undo_redo.cpp
@@ -0,0 +1,382 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file schematic_undo_redo.cpp
+ * @brief Eeschema undo and redo functions for schematic editor.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <schframe.h>
+
+#include <general.h>
+#include <protos.h>
+#include <sch_bus_entry.h>
+#include <sch_marker.h>
+#include <sch_junction.h>
+#include <sch_line.h>
+#include <sch_no_connect.h>
+#include <sch_component.h>
+#include <sch_sheet.h>
+#include <sch_bitmap.h>
+
+
+/* Functions to undo and redo edit commands.
+ * commands to undo are stored in CurrentScreen->m_UndoList
+ * commands to redo are stored in CurrentScreen->m_RedoList
+ *
+ * m_UndoList and m_RedoList handle a std::vector of PICKED_ITEMS_LIST
+ * Each PICKED_ITEMS_LIST handle a std::vector of pickers (class ITEM_PICKER),
+ * that store the list of schematic items that are concerned by the command to
+ * undo or redo and is created for each command to undo (handle also a command
+ * to redo). each picker has a pointer pointing to an item to undo or redo (in
+ * fact: deleted, added or modified), and has a pointer to a copy of this item,
+ * when this item has been modified (the old values of parameters are
+ * therefore saved)
+ *
+ * there are 3 cases:
+ * - delete item(s) command
+ * - change item(s) command
+ * - add item(s) command
+ * and 2 cases for block:
+ * - move list of items
+ * - mirror (Y) list of items
+ *
+ * Undo command
+ * - delete item(s) command:
+ * => deleted items are moved in undo list
+ *
+ * - change item(s) command
+ * => A copy of item(s) is made (a DrawPickedStruct list of wrappers)
+ * the .m_Link member of each wrapper points the modified item.
+ * the .m_Item member of each wrapper points the old copy of this item.
+ *
+ * - add item(s) command
+ * =>A list of item(s) is made. The .m_Item member of each wrapper points
+ * the new item.
+ *
+ * Redo command
+ * - delete item(s) old command:
+ * => deleted items are moved in GetDrawItems() list, and in
+ *
+ * - change item(s) command
+ * => the copy of item(s) is moved in Undo list
+ *
+ * - add item(s) command
+ * => The list of item(s) is used to create a deleted list in undo
+ * list(same as a delete command)
+ *
+ * Some block operations that change items can be undone without memorized
+ * items, just the coordinates of the transform: move list of items (undo/
+ * redo is made by moving with the opposite move vector) mirror (Y) and flip
+ * list of items (undo/redo is made by mirror or flip items) so they are
+ * handled specifically.
+ *
+ * A problem is the hierarchical sheet handling.
+ * the data associated (sub-hierarchy, undo/redo list) is deleted only
+ * when the sheet is really deleted (i.e. when deleted from undo or redo list)
+ * This is handled by its destructor.
+ */
+
+
+/* Used if undo / redo command:
+ * swap data between Item and its copy, pointed by its .m_Image member
+ * swapped data is data modified by edition, so not all values are swapped
+ */
+
+void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem,
+ UNDO_REDO_T aCommandType,
+ const wxPoint& aTransformPoint )
+{
+ /* Does not save a null item or a UR_WIRE_IMAGE command type. UR_WIRE_IMAGE commands
+ * are handled by the overloaded version of SaveCopyInUndoList that takes a reference
+ * to a PICKED_ITEMS_LIST.
+ */
+ if( aItem == NULL || aCommandType == UR_WIRE_IMAGE )
+ return;
+
+ PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
+ commandToUndo->m_TransformPoint = aTransformPoint;
+
+ ITEM_PICKER itemWrapper( aItem, aCommandType );
+ itemWrapper.SetFlags( aItem->GetFlags() );
+
+ switch( aCommandType )
+ {
+ case UR_CHANGED: /* Create a copy of item */
+ itemWrapper.SetLink( DuplicateStruct( aItem, true ) );
+ commandToUndo->PushItem( itemWrapper );
+ break;
+
+ case UR_NEW:
+ case UR_DELETED:
+ case UR_ROTATED:
+ case UR_MOVED:
+ commandToUndo->PushItem( itemWrapper );
+ break;
+
+ default:
+ wxFAIL_MSG( wxString::Format( wxT( "SaveCopyInUndoList() error (unknown code %X)" ),
+ aCommandType ) );
+ break;
+ }
+
+ if( commandToUndo->GetCount() )
+ {
+ /* Save the copy in undo list */
+ GetScreen()->PushCommandToUndoList( commandToUndo );
+
+ /* Clear redo list, because after new save there is no redo to do */
+ GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
+ }
+ else
+ {
+ delete commandToUndo;
+ }
+}
+
+
+void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
+ UNDO_REDO_T aTypeCommand,
+ const wxPoint& aTransformPoint )
+{
+ PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
+
+ commandToUndo->m_TransformPoint = aTransformPoint;
+ commandToUndo->m_Status = aTypeCommand;
+
+ // Copy picker list:
+ commandToUndo->CopyList( aItemsList );
+
+ // Verify list, and creates data if needed
+ for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ )
+ {
+ SCH_ITEM* item = (SCH_ITEM*) commandToUndo->GetPickedItem( ii );
+ wxASSERT( item );
+
+ UNDO_REDO_T command = commandToUndo->GetPickedItemStatus( ii );
+
+ if( command == UR_UNSPECIFIED )
+ {
+ command = aTypeCommand;
+ commandToUndo->SetPickedItemStatus( command, ii );
+ }
+
+ switch( command )
+ {
+ case UR_CHANGED: /* Create a copy of item */
+
+ /* If needed, create a copy of item, and put in undo list
+ * in the picker, as link
+ * If this link is not null, the copy is already done
+ */
+ if( commandToUndo->GetPickedItemLink( ii ) == NULL )
+ commandToUndo->SetPickedItemLink( DuplicateStruct( item, true ), ii );
+
+ wxASSERT( commandToUndo->GetPickedItemLink( ii ) );
+ break;
+
+ case UR_MOVED:
+ case UR_MIRRORED_Y:
+ case UR_MIRRORED_X:
+ case UR_ROTATED:
+ case UR_NEW:
+ case UR_DELETED:
+ case UR_EXCHANGE_T:
+ case UR_WIRE_IMAGE:
+ break;
+
+ default:
+ wxFAIL_MSG( wxString::Format( wxT( "Unknown undo/redo command %d" ), command ) );
+ break;
+ }
+ }
+
+ if( commandToUndo->GetCount() || aTypeCommand == UR_WIRE_IMAGE )
+ {
+ /* Save the copy in undo list */
+ GetScreen()->PushCommandToUndoList( commandToUndo );
+
+ /* Clear redo list, because after new save there is no redo to do */
+ GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
+ }
+ else // Should not occur
+ {
+ delete commandToUndo;
+ }
+}
+
+
+void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRedoCommand )
+{
+ SCH_ITEM* item;
+ SCH_ITEM* alt_item;
+
+ // Exchange the current wires, buses, and junctions with the copy save by the last edit.
+ if( aList->m_Status == UR_WIRE_IMAGE )
+ {
+ DLIST< SCH_ITEM > oldWires;
+
+ // Prevent items from being deleted when the DLIST goes out of scope.
+ oldWires.SetOwnership( false );
+
+ // Remove all of the wires, buses, and junctions from the current screen.
+ GetScreen()->ExtractWires( oldWires, false );
+
+ // Copy the saved wires, buses, and junctions to the current screen.
+ for( unsigned int i = 0; i < aList->GetCount(); i++ )
+ GetScreen()->Append( (SCH_ITEM*) aList->GetPickedItem( i ) );
+
+ aList->ClearItemsList();
+
+ // Copy the previous wires, buses, and junctions to the picked item list for the
+ // redo operation.
+ while( oldWires.GetCount() != 0 )
+ {
+ ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE );
+ aList->PushItem( picker );
+ }
+
+ return;
+ }
+
+ // Undo in the reverse order of list creation: (this can allow stacked changes like the
+ // same item can be changes and deleted in the same complex command.
+ for( int ii = aList->GetCount() - 1; ii >= 0; ii-- )
+ {
+ item = (SCH_ITEM*) aList->GetPickedItem( ii );
+ wxASSERT( item );
+
+ item->ClearFlags();
+
+ SCH_ITEM* image = (SCH_ITEM*) aList->GetPickedItemLink( ii );
+
+ switch( aList->GetPickedItemStatus( ii ) )
+ {
+ case UR_CHANGED: /* Exchange old and new data for each item */
+ item->SwapData( image );
+ break;
+
+ case UR_NEW: /* new items are deleted */
+ aList->SetPickedItemStatus( UR_DELETED, ii );
+ GetScreen()->Remove( item );
+ break;
+
+ case UR_DELETED: /* deleted items are put in the draw item list, as new items */
+ aList->SetPickedItemStatus( UR_NEW, ii );
+ GetScreen()->Append( item );
+ break;
+
+ case UR_MOVED:
+ item->ClearFlags();
+ item->SetFlags( aList->GetPickerFlags( ii ) );
+ item->Move( aRedoCommand ? aList->m_TransformPoint : -aList->m_TransformPoint );
+ item->ClearFlags();
+ break;
+
+ case UR_MIRRORED_Y:
+ item->MirrorY( aList->m_TransformPoint.x );
+ break;
+
+ case UR_MIRRORED_X:
+ item->MirrorX( aList->m_TransformPoint.y );
+ break;
+
+ case UR_ROTATED:
+ // To undo a rotate 90 deg transform we must rotate 270 deg to undo
+ // and 90 deg to redo:
+ item->Rotate( aList->m_TransformPoint );
+
+ if( aRedoCommand )
+ break; // A only one rotate transform is OK
+
+ // Make 3 rotate 90 deg transforms is this is actually an undo command
+ item->Rotate( aList->m_TransformPoint );
+ item->Rotate( aList->m_TransformPoint );
+ break;
+
+ case UR_EXCHANGE_T:
+ alt_item = (SCH_ITEM*) aList->GetPickedItemLink( ii );
+ alt_item->SetNext( NULL );
+ alt_item->SetBack( NULL );
+ GetScreen()->Remove( item );
+ GetScreen()->Append( alt_item );
+ aList->SetPickedItem( alt_item, ii );
+ aList->SetPickedItemLink( item, ii );
+ break;
+
+ default:
+ wxFAIL_MSG( wxString::Format( wxT( "Unknown undo/redo command %d" ),
+ aList->GetPickedItemStatus( ii ) ) );
+ break;
+ }
+ }
+}
+
+
+void SCH_EDIT_FRAME::GetSchematicFromUndoList( wxCommandEvent& event )
+{
+ if( GetScreen()->GetUndoCommandCount() <= 0 )
+ return;
+
+ /* Get the old list */
+ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
+
+ /* Undo the command */
+ PutDataInPreviousState( List, false );
+
+ /* Put the old list in RedoList */
+ List->ReversePickersListOrder();
+ GetScreen()->PushCommandToRedoList( List );
+
+ OnModify();
+ SetSheetNumberAndCount();
+
+ GetScreen()->TestDanglingEnds();
+ m_canvas->Refresh();
+}
+
+
+void SCH_EDIT_FRAME::GetSchematicFromRedoList( wxCommandEvent& event )
+{
+ if( GetScreen()->GetRedoCommandCount() == 0 )
+ return;
+
+ /* Get the old list */
+ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();
+
+ /* Redo the command: */
+ PutDataInPreviousState( List, true );
+
+ /* Put the old list in UndoList */
+ List->ReversePickersListOrder();
+ GetScreen()->PushCommandToUndoList( List );
+
+ OnModify();
+ SetSheetNumberAndCount();
+
+ GetScreen()->TestDanglingEnds();
+ m_canvas->Refresh();
+}
diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp
new file mode 100644
index 0000000..2568576
--- /dev/null
+++ b/eeschema/schframe.cpp
@@ -0,0 +1,1320 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file schframe.cpp
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <pgm_base.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <gestfich.h>
+#include <confirm.h>
+#include <base_units.h>
+#include <msgpanel.h>
+#include <html_messagebox.h>
+
+#include <general.h>
+#include <eeschema_id.h>
+#include <netlist.h>
+#include <lib_pin.h>
+#include <class_library.h>
+#include <schframe.h>
+#include <sch_component.h>
+
+#include <dialog_helpers.h>
+#include <libeditframe.h>
+#include <viewlib_frame.h>
+#include <hotkeys.h>
+#include <eeschema_config.h>
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+
+#include <invoke_sch_dialog.h>
+#include <dialogs/dialog_schematic_find.h>
+
+#include <wx/display.h>
+#include <build_version.h>
+#include <wildcards_and_files_ext.h>
+
+
+// non-member so it can be moved easily, and kept REALLY private.
+// Do NOT Clear() in here.
+static void add_search_paths( SEARCH_STACK* aDst, const SEARCH_STACK& aSrc, int aIndex )
+{
+ for( unsigned i=0; i<aSrc.GetCount(); ++i )
+ aDst->AddPaths( aSrc[i], aIndex );
+}
+
+
+// non-member so it can be moved easily, and kept REALLY private.
+// Do NOT Clear() in here.
+static void add_search_paths( SEARCH_STACK* aDst, wxConfigBase* aCfg, int aIndex )
+{
+ for( int i=1; true; ++i )
+ {
+ wxString key = wxString::Format( wxT( "LibraryPath%d" ), i );
+ wxString upath = aCfg->Read( key, wxEmptyString );
+
+ if( !upath )
+ break;
+
+ aDst->AddPaths( upath, aIndex );
+ }
+}
+
+//-----<SCH "data on demand" functions>-------------------------------------------
+
+SEARCH_STACK* PROJECT::SchSearchS()
+{
+ SEARCH_STACK* ss = (SEARCH_STACK*) GetElem( PROJECT::ELEM_SCH_SEARCH_STACK );
+
+ wxASSERT( !ss || dynamic_cast<SEARCH_STACK*>( GetElem( PROJECT::ELEM_SCH_SEARCH_STACK ) ) );
+
+ if( !ss )
+ {
+ ss = new SEARCH_STACK();
+
+ // Make PROJECT the new SEARCH_STACK owner.
+ SetElem( PROJECT::ELEM_SCH_SEARCH_STACK, ss );
+
+ // to the empty SEARCH_STACK for SchSearchS(), add project dir as first
+ ss->AddPaths( m_project_name.GetPath() );
+
+ // next add the paths found in *.pro, variable "LibDir"
+ wxString libDir;
+
+ try
+ {
+ PART_LIBS::LibNamesAndPaths( this, false, &libDir );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DBG(printf( "%s: %s\n", __func__, TO_UTF8( ioe.errorText ) );)
+ }
+
+ if( !!libDir )
+ {
+ wxArrayString paths;
+
+ SEARCH_STACK::Split( &paths, libDir );
+
+ for( unsigned i =0; i<paths.GetCount(); ++i )
+ {
+ wxString path = AbsolutePath( paths[i] );
+
+ ss->AddPaths( path ); // at the end
+ }
+ }
+
+ // append all paths from aSList
+ add_search_paths( ss, Kiface().KifaceSearch(), -1 );
+
+ // addLibrarySearchPaths( SEARCH_STACK* aSP, wxConfigBase* aCfg )
+ // This is undocumented, but somebody wanted to store !schematic!
+ // library search paths in the .kicad_common file?
+ add_search_paths( ss, Pgm().CommonSettings(), -1 );
+ }
+
+ return ss;
+}
+
+
+PART_LIBS* PROJECT::SchLibs()
+{
+ PART_LIBS* libs = (PART_LIBS*) GetElem( PROJECT::ELEM_SCH_PART_LIBS );
+
+ wxASSERT( !libs || dynamic_cast<PART_LIBS*>( libs ) );
+
+ if( !libs )
+ {
+ libs = new PART_LIBS();
+
+ // Make PROJECT the new PART_LIBS owner.
+ SetElem( PROJECT::ELEM_SCH_PART_LIBS, libs );
+
+ try
+ {
+ libs->LoadAllLibraries( this );
+ }
+ catch( const PARSE_ERROR& pe )
+ {
+ wxString lib_list = UTF8( pe.inputLine );
+ wxWindow* parent = 0; // Pgm().App().GetTopWindow();
+
+ // parent of this dialog cannot be NULL since that breaks the Kiway() chain.
+ HTML_MESSAGE_BOX dlg( parent, _( "Not Found" ) );
+
+ dlg.MessageSet( _( "The following libraries were not found:" ) );
+
+ dlg.ListSet( lib_list );
+
+ dlg.Layout();
+
+ dlg.ShowModal();
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( NULL, ioe.errorText );
+ }
+ }
+
+ return libs;
+}
+
+/*
+NETLIST_OBJECT_LIST* PROJECT::Netlist()
+{
+ NETLIST_OBJECT_LIST* netlist = (NETLIST_OBJECT_LIST*) GetElem( PROJECT::ELEM_SCH_NETLIST );
+
+ wxASSERT( !libs || dynamic_cast<NETLIST_OBJECT_LIST*>( netlist ) );
+
+ if( !netlist )
+ {
+ netlist = new NETLIST_OBJECT_LIST();
+
+ // Make PROJECT the new NETLIST_OBJECT_LIST owner.
+ SetElem( PROJECT::ELEM_SCH_NETLIST, netlist );
+ }
+}
+*/
+
+//-----</SCH "data on demand" functions>------------------------------------------
+
+
+BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
+ EVT_SOCKET( ID_EDA_SOCKET_EVENT_SERV, EDA_DRAW_FRAME::OnSockRequestServer )
+ EVT_SOCKET( ID_EDA_SOCKET_EVENT, EDA_DRAW_FRAME::OnSockRequest )
+
+ EVT_CLOSE( SCH_EDIT_FRAME::OnCloseWindow )
+ EVT_SIZE( SCH_EDIT_FRAME::OnSize )
+
+ EVT_MENU( ID_NEW_PROJECT, SCH_EDIT_FRAME::OnNewProject )
+ EVT_MENU( ID_LOAD_PROJECT, SCH_EDIT_FRAME::OnLoadProject )
+
+ EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, SCH_EDIT_FRAME::OnLoadFile )
+
+ EVT_MENU( ID_APPEND_PROJECT, SCH_EDIT_FRAME::OnAppendProject )
+
+ EVT_TOOL( ID_NEW_PROJECT, SCH_EDIT_FRAME::OnNewProject )
+ EVT_TOOL( ID_LOAD_PROJECT, SCH_EDIT_FRAME::OnLoadProject )
+
+ EVT_MENU( ID_SAVE_PROJECT, SCH_EDIT_FRAME::OnSaveProject )
+ EVT_MENU( ID_UPDATE_ONE_SHEET, SCH_EDIT_FRAME::Save_File )
+ EVT_MENU( ID_SAVE_ONE_SHEET_UNDER_NEW_NAME, SCH_EDIT_FRAME::Save_File )
+ EVT_MENU( ID_GEN_PLOT_SCHEMATIC, SCH_EDIT_FRAME::PlotSchematic )
+ EVT_MENU( ID_GEN_COPY_SHEET_TO_CLIPBOARD, EDA_DRAW_FRAME::CopyToClipboard )
+ EVT_MENU( wxID_EXIT, SCH_EDIT_FRAME::OnExit )
+
+ EVT_MENU( ID_POPUP_SCH_COPY_ITEM, SCH_EDIT_FRAME::OnCopySchematicItemRequest )
+
+ EVT_MENU( ID_CONFIG_REQ, SCH_EDIT_FRAME::InstallConfigFrame )
+ EVT_MENU( ID_CONFIG_SAVE, SCH_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_CONFIG_READ, SCH_EDIT_FRAME::Process_Config )
+ EVT_MENU_RANGE( ID_PREFERENCES_HOTKEY_START, ID_PREFERENCES_HOTKEY_END,
+ SCH_EDIT_FRAME::Process_Config )
+
+ EVT_MENU( ID_COLORS_SETUP, SCH_EDIT_FRAME::OnColorConfig )
+ EVT_TOOL( wxID_PREFERENCES, SCH_EDIT_FRAME::OnPreferencesOptions )
+
+ EVT_TOOL( ID_RUN_LIBRARY, SCH_EDIT_FRAME::OnOpenLibraryEditor )
+ EVT_TOOL( ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP, SCH_EDIT_FRAME::OnOpenLibraryEditor )
+ EVT_TOOL( ID_TO_LIBVIEW, SCH_EDIT_FRAME::OnOpenLibraryViewer )
+ EVT_TOOL( ID_RESCUE_CACHED, SCH_EDIT_FRAME::OnRescueProject )
+
+ EVT_TOOL( ID_RUN_PCB, SCH_EDIT_FRAME::OnOpenPcbnew )
+ EVT_TOOL( ID_RUN_PCB_MODULE_EDITOR, SCH_EDIT_FRAME::OnOpenPcbModuleEditor )
+
+ EVT_TOOL( ID_RUN_CVPCB, SCH_EDIT_FRAME::OnOpenCvpcb )
+
+ EVT_TOOL( ID_SHEET_SET, EDA_DRAW_FRAME::Process_PageSettings )
+ EVT_TOOL( ID_HIERARCHY, SCH_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( wxID_CUT, SCH_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( wxID_COPY, SCH_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( wxID_PASTE, SCH_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( wxID_UNDO, SCH_EDIT_FRAME::GetSchematicFromUndoList )
+ EVT_TOOL( wxID_REDO, SCH_EDIT_FRAME::GetSchematicFromRedoList )
+ EVT_TOOL( ID_GET_ANNOTATE, SCH_EDIT_FRAME::OnAnnotate )
+ EVT_TOOL( wxID_PRINT, SCH_EDIT_FRAME::OnPrint )
+ EVT_TOOL( ID_GET_ERC, SCH_EDIT_FRAME::OnErc )
+ EVT_TOOL( ID_GET_NETLIST, SCH_EDIT_FRAME::OnCreateNetlist )
+ EVT_TOOL( ID_GET_TOOLS, SCH_EDIT_FRAME::OnCreateBillOfMaterials )
+ EVT_TOOL( ID_FIND_ITEMS, SCH_EDIT_FRAME::OnFindItems )
+ EVT_TOOL( wxID_REPLACE, SCH_EDIT_FRAME::OnFindItems )
+ EVT_TOOL( ID_BACKANNO_ITEMS, SCH_EDIT_FRAME::OnLoadCmpToFootprintLinkFile )
+ EVT_TOOL( ID_SCH_MOVE_ITEM, SCH_EDIT_FRAME::OnMoveItem )
+ EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_INDEX, EDA_DRAW_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::GetKicadAbout )
+
+ // Tools and buttons for vertical toolbar.
+ EVT_TOOL( ID_NO_TOOL_SELECTED, SCH_EDIT_FRAME::OnSelectTool )
+ EVT_TOOL_RANGE( ID_SCHEMATIC_VERTICAL_TOOLBAR_START, ID_SCHEMATIC_VERTICAL_TOOLBAR_END,
+ SCH_EDIT_FRAME::OnSelectTool )
+
+ EVT_MENU( ID_CANCEL_CURRENT_COMMAND, SCH_EDIT_FRAME::OnCancelCurrentCommand )
+ EVT_MENU( ID_SCH_DRAG_ITEM, SCH_EDIT_FRAME::OnDragItem )
+ EVT_MENU_RANGE( ID_SCH_ROTATE_CLOCKWISE, ID_SCH_ROTATE_COUNTERCLOCKWISE,
+ SCH_EDIT_FRAME::OnRotate )
+ EVT_MENU_RANGE( ID_SCH_EDIT_ITEM, ID_SCH_EDIT_COMPONENT_FOOTPRINT,
+ SCH_EDIT_FRAME::OnEditItem )
+ EVT_MENU_RANGE( ID_SCH_MIRROR_X, ID_SCH_ORIENT_NORMAL, SCH_EDIT_FRAME::OnOrient )
+ EVT_MENU_RANGE( ID_POPUP_START_RANGE, ID_POPUP_END_RANGE,
+ SCH_EDIT_FRAME::Process_Special_Functions )
+
+ // Tools and buttons options toolbar
+ EVT_TOOL( ID_TB_OPTIONS_HIDDEN_PINS, SCH_EDIT_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_BUS_WIRES_ORIENT, SCH_EDIT_FRAME::OnSelectOptionToolbar )
+
+ EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE,
+ SCH_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU_RANGE( ID_POPUP_SCH_SELECT_UNIT1, ID_POPUP_SCH_SELECT_UNIT_CMP_MAX,
+ SCH_EDIT_FRAME::OnSelectUnit )
+ EVT_MENU_RANGE( ID_POPUP_SCH_CHANGE_TYPE_TEXT, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT,
+ SCH_EDIT_FRAME::OnConvertTextType )
+
+ // Multple item selection context menu commands.
+ EVT_MENU_RANGE( ID_SELECT_ITEM_START, ID_SELECT_ITEM_END, SCH_EDIT_FRAME::OnSelectItem )
+
+ /* Handle user interface update events. */
+ EVT_UPDATE_UI( wxID_CUT, SCH_EDIT_FRAME::OnUpdateBlockSelected )
+ EVT_UPDATE_UI( wxID_COPY, SCH_EDIT_FRAME::OnUpdateBlockSelected )
+ EVT_UPDATE_UI( wxID_PASTE, SCH_EDIT_FRAME::OnUpdatePaste )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_HIDDEN_PINS, SCH_EDIT_FRAME::OnUpdateHiddenPins )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_BUS_WIRES_ORIENT, SCH_EDIT_FRAME::OnUpdateBusOrientation )
+ EVT_UPDATE_UI( ID_NO_TOOL_SELECTED, SCH_EDIT_FRAME::OnUpdateSelectTool )
+ EVT_UPDATE_UI_RANGE( ID_SCHEMATIC_VERTICAL_TOOLBAR_START, ID_SCHEMATIC_VERTICAL_TOOLBAR_END,
+ SCH_EDIT_FRAME::OnUpdateSelectTool )
+ EVT_UPDATE_UI( ID_SAVE_PROJECT, SCH_EDIT_FRAME::OnUpdateSave )
+ EVT_UPDATE_UI( ID_UPDATE_ONE_SHEET, SCH_EDIT_FRAME::OnUpdateSaveSheet )
+ EVT_UPDATE_UI( ID_POPUP_SCH_LEAVE_SHEET, SCH_EDIT_FRAME::OnUpdateHierarchySheet )
+
+ /* Search dialog events. */
+ EVT_FIND_CLOSE( wxID_ANY, SCH_EDIT_FRAME::OnFindDialogClose )
+ EVT_FIND_DRC_MARKER( wxID_ANY, SCH_EDIT_FRAME::OnFindDrcMarker )
+ EVT_FIND( wxID_ANY, SCH_EDIT_FRAME::OnFindSchematicItem )
+ EVT_FIND_REPLACE( wxID_ANY, SCH_EDIT_FRAME::OnFindReplace )
+ EVT_FIND_REPLACE_ALL( wxID_ANY, SCH_EDIT_FRAME::OnFindReplace )
+
+END_EVENT_TABLE()
+
+
+SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ):
+ SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH, wxT( "Eeschema" ),
+ wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, SCH_EDIT_FRAME_NAME ),
+ m_item_to_repeat( 0 )
+{
+ m_showAxis = false; // true to show axis
+ m_showBorderAndTitleBlock = true; // true to show sheet references
+ m_CurrentSheet = new SCH_SHEET_PATH;
+ m_DefaultSchematicFileName = NAMELESS_PROJECT;
+ m_DefaultSchematicFileName += wxT( ".sch" );
+ m_showAllPins = false;
+ m_previewPosition = wxDefaultPosition;
+ m_previewSize = wxDefaultSize;
+ m_printMonochrome = true;
+ m_printSheetReference = true;
+ SetShowPageLimits( true );
+ m_hotkeysDescrList = g_Schematic_Hokeys_Descr;
+ m_dlgFindReplace = NULL;
+ m_findReplaceData = new wxFindReplaceData( wxFR_DOWN );
+ m_undoItem = NULL;
+ m_hasAutoSave = true;
+
+ SetForceHVLines( true );
+ SetSpiceAddReferencePrefix( false );
+ SetSpiceUseNetcodeAsNetname( false );
+
+ // Give an icon
+ wxIcon icon;
+ icon.CopyFromBitmap( KiBitmap( icon_eeschema_xpm ) );
+ SetIcon( icon );
+
+ // Initialize grid id to the default value (50 mils):
+ const int default_grid = ID_POPUP_GRID_LEVEL_50 - ID_POPUP_GRID_LEVEL_1000;
+ m_LastGridSizeId = default_grid;
+
+ LoadSettings( config() );
+
+ CreateScreens();
+
+ // Ensure m_LastGridSizeId is an offset inside the allowed schematic grid range
+ if( !GetScreen()->GridExists( m_LastGridSizeId + ID_POPUP_GRID_LEVEL_1000 ) )
+ m_LastGridSizeId = default_grid;
+
+ SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
+
+ if( m_canvas )
+ m_canvas->SetEnableBlockCommands( true );
+
+ ReCreateMenuBar();
+ ReCreateHToolbar();
+ ReCreateVToolbar();
+ ReCreateOptToolbar();
+
+ // Initialize common print setup dialog settings.
+ m_pageSetupData.GetPrintData().SetPrintMode( wxPRINT_MODE_PRINTER );
+ m_pageSetupData.GetPrintData().SetQuality( wxPRINT_QUALITY_MEDIUM );
+ m_pageSetupData.GetPrintData().SetBin( wxPRINTBIN_AUTO );
+ m_pageSetupData.GetPrintData().SetNoCopies( 1 );
+
+ m_auimgr.SetManagedWindow( this );
+
+ EDA_PANEINFO horiz;
+ horiz.HorizontalToolbarPane();
+
+ EDA_PANEINFO vert;
+ vert.VerticalToolbarPane();
+
+ EDA_PANEINFO mesg;
+ mesg.MessageToolbarPane();
+
+ if( m_mainToolBar )
+ m_auimgr.AddPane( m_mainToolBar,
+ wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top().Row( 0 ) );
+
+ if( m_drawToolBar )
+ m_auimgr.AddPane( m_drawToolBar, wxAuiPaneInfo( vert ).Name( wxT( "m_drawToolBar" ) ).Right() );
+
+ if( m_optionsToolBar )
+ m_auimgr.AddPane( m_optionsToolBar,
+ wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ).Left() );
+
+ if( m_canvas )
+ m_auimgr.AddPane( m_canvas, wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
+
+ if( m_messagePanel )
+ m_auimgr.AddPane( m_messagePanel, wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().
+ Layer(10) );
+
+ m_auimgr.Update();
+
+ // Now Drawpanel is sized, we can use BestZoom to show the component (if any)
+ GetScreen()->SetZoom( BestZoom() );
+
+ Zoom_Automatique( false );
+}
+
+
+SCH_EDIT_FRAME::~SCH_EDIT_FRAME()
+{
+ delete m_item_to_repeat; // we own the cloned object, see this->SetRepeatItem()
+
+ SetScreen( NULL );
+
+ delete m_CurrentSheet; // a SCH_SHEET_PATH, on the heap.
+ delete m_undoItem;
+ delete g_RootSheet;
+ delete m_findReplaceData;
+
+ m_CurrentSheet = NULL;
+ m_undoItem = NULL;
+ g_RootSheet = NULL;
+ m_findReplaceData = NULL;
+}
+
+
+void SCH_EDIT_FRAME::SetRepeatItem( SCH_ITEM* aItem )
+{
+ // we cannot store a pointer to an item in the display list here since
+ // that item may be deleted, such as part of a line concatonation or other.
+ // So simply always keep a copy of the object which is to be repeated.
+
+ SCH_ITEM* old = m_item_to_repeat;
+ SCH_ITEM* cur = aItem;
+
+ if( cur != old )
+ {
+ if( cur )
+ {
+ aItem = (SCH_ITEM*) cur->Clone();
+
+ // Clone() preserves the flags, we want 'em cleared.
+ aItem->ClearFlags();
+ }
+
+ m_item_to_repeat = aItem;
+
+ delete old;
+ }
+}
+
+
+void SCH_EDIT_FRAME::SetSheetNumberAndCount()
+{
+ SCH_SCREEN* screen;
+ SCH_SCREENS s_list;
+
+ /* Set the sheet count, and the sheet number (1 for root sheet)
+ */
+ int sheet_count = g_RootSheet->CountSheets();
+ int SheetNumber = 1;
+ wxString current_sheetpath = m_CurrentSheet->Path();
+ SCH_SHEET_LIST sheetList;
+
+ // Examine all sheets path to find the current sheets path,
+ // and count them from root to the current sheet path:
+ SCH_SHEET_PATH* sheet;
+
+ for( sheet = sheetList.GetFirst(); sheet != NULL; sheet = sheetList.GetNext() )
+ {
+ wxString sheetpath = sheet->Path();
+
+ if( sheetpath == current_sheetpath ) // Current sheet path found
+ break;
+
+ SheetNumber++; /* Not found, increment sheet
+ * number before this current
+ * path */
+ }
+
+ for( screen = s_list.GetFirst(); screen != NULL; screen = s_list.GetNext() )
+ {
+ screen->m_NumberOfScreens = sheet_count;
+ }
+
+ GetScreen()->m_ScreenNumber = SheetNumber;
+}
+
+
+SCH_SCREEN* SCH_EDIT_FRAME::GetScreen() const
+{
+ return m_CurrentSheet->LastScreen();
+}
+
+
+wxString SCH_EDIT_FRAME::GetScreenDesc() const
+{
+ wxString s = m_CurrentSheet->PathHumanReadable();
+
+ return s;
+}
+
+
+void SCH_EDIT_FRAME::CreateScreens()
+{
+ if( g_RootSheet == NULL )
+ {
+ g_RootSheet = new SCH_SHEET();
+ }
+
+ if( g_RootSheet->GetScreen() == NULL )
+ {
+ SCH_SCREEN* screen = new SCH_SCREEN( &Kiway() );
+ screen->SetMaxUndoItems( m_UndoRedoCountMax );
+ g_RootSheet->SetScreen( screen );
+ SetScreen( g_RootSheet->GetScreen() );
+ }
+
+ g_RootSheet->GetScreen()->SetFileName( m_DefaultSchematicFileName );
+
+ m_CurrentSheet->Clear();
+ m_CurrentSheet->Push( g_RootSheet );
+
+ if( GetScreen() == NULL )
+ {
+ SCH_SCREEN* screen = new SCH_SCREEN( &Kiway() );
+ screen->SetMaxUndoItems( m_UndoRedoCountMax );
+ SetScreen( screen );
+ }
+
+ GetScreen()->SetZoom( 32.0 );
+}
+
+
+SCH_SHEET_PATH& SCH_EDIT_FRAME::GetCurrentSheet()
+{
+ wxASSERT_MSG( m_CurrentSheet != NULL, wxT( "SCH_EDIT_FRAME m_CurrentSheet member is NULL." ) );
+
+ return *m_CurrentSheet;
+}
+
+
+void SCH_EDIT_FRAME::SetCurrentSheet( const SCH_SHEET_PATH& aSheet )
+{
+ *m_CurrentSheet = aSheet;
+}
+
+
+void SCH_EDIT_FRAME::SetUndoItem( const SCH_ITEM* aItem )
+{
+ // if aItem != NULL, delete a previous m_undoItem, if exists
+ // if aItme = NULL, just clear m_undoItem,
+ // because when calling SetUndoItem( NULL ), we only clear m_undoItem,
+ // because the owner of m_undoItem is no more me.
+ if( aItem && m_undoItem )
+ {
+ delete m_undoItem;
+ }
+
+ m_undoItem = NULL;
+
+ if( aItem )
+ m_undoItem = (SCH_ITEM*) aItem->Clone();
+
+}
+
+
+void SCH_EDIT_FRAME::SaveUndoItemInUndoList( SCH_ITEM* aItem )
+{
+ wxCHECK_RET( aItem != NULL,
+ wxT( "Cannot swap undo item structures. Bad programmer!." ) );
+ wxCHECK_RET( m_undoItem != NULL,
+ wxT( "Cannot swap undo item structures. Bad programmer!." ) );
+ wxCHECK_RET( aItem->Type() == m_undoItem->Type(),
+ wxT( "Cannot swap undo item structures. Bad programmer!." ) );
+
+ aItem->SwapData( m_undoItem );
+ SaveCopyInUndoList( aItem, UR_CHANGED );
+ aItem->SwapData( m_undoItem );
+}
+
+
+void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
+{
+ if( Kiface().IsSingle() )
+ {
+ LIB_EDIT_FRAME* libeditFrame = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, false );
+ if( libeditFrame && !libeditFrame->Close() ) // Can close component editor?
+ return;
+
+ LIB_VIEW_FRAME* viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, false );
+ if( viewlibFrame && !viewlibFrame->Close() ) // Can close component viewer?
+ return;
+
+ viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER_MODAL, false );
+ if( viewlibFrame && !viewlibFrame->Close() ) // Can close modal component viewer?
+ return;
+ }
+
+ SCH_SHEET_LIST sheetList;
+
+ if( sheetList.IsModified() )
+ {
+ wxString fileName = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() );
+ wxString msg = wxString::Format( _(
+ "Save the changes in\n'%s'\nbefore closing?"),
+ GetChars( fileName )
+ );
+
+ int ii = DisplayExitDialog( this, msg );
+
+ switch( ii )
+ {
+ case wxID_CANCEL:
+ aEvent.Veto();
+ return;
+
+ case wxID_NO:
+ break;
+
+ case wxID_YES:
+ wxCommandEvent tmp( ID_SAVE_PROJECT );
+ OnSaveProject( tmp );
+ break;
+ }
+ }
+
+ // Close the find dialog and preserve it's setting if it is displayed.
+ if( m_dlgFindReplace )
+ {
+ m_findDialogPosition = m_dlgFindReplace->GetPosition();
+ m_findDialogSize = m_dlgFindReplace->GetSize();
+ m_findStringHistoryList = m_dlgFindReplace->GetFindEntries();
+ m_replaceStringHistoryList = m_dlgFindReplace->GetReplaceEntries();
+ m_dlgFindReplace->Destroy();
+ m_dlgFindReplace = NULL;
+ }
+
+ SCH_SCREENS screens;
+ wxFileName fn;
+
+ for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() )
+ {
+ fn = Prj().AbsolutePath( screen->GetFileName() );
+
+ // Auto save file name is the normal file name prepended with AUTOSAVE_PREFIX_FILENAME.
+ fn.SetName( AUTOSAVE_PREFIX_FILENAME + fn.GetName() );
+
+ if( fn.FileExists() && fn.IsFileWritable() )
+ wxRemoveFile( fn.GetFullPath() );
+ }
+
+ sheetList.ClearModifyStatus();
+
+ wxString fileName = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() );
+
+ if( !g_RootSheet->GetScreen()->GetFileName().IsEmpty() &&
+ g_RootSheet->GetScreen()->GetDrawItems() != NULL )
+ {
+ UpdateFileHistory( fileName );
+ }
+
+ g_RootSheet->GetScreen()->Clear();
+
+ // all sub sheets are deleted, only the main sheet is usable
+ m_CurrentSheet->Clear();
+
+ Destroy();
+}
+
+
+double SCH_EDIT_FRAME::BestZoom()
+{
+ int dx, dy;
+ wxSize size;
+
+ dx = GetScreen()->GetPageSettings().GetWidthIU();
+ dy = GetScreen()->GetPageSettings().GetHeightIU();
+
+ size = m_canvas->GetClientSize();
+
+ // Reserve no margin because best zoom shows the full page
+ // and margins are already included in function that draws the sheet refernces
+ double margin_scale_factor = 1.0;
+ double zx =(double) dx / ( margin_scale_factor * (double)size.x );
+ double zy = (double) dy / ( margin_scale_factor * (double)size.y );
+
+ double bestzoom = std::max( zx, zy );
+
+ SetScrollCenterPosition( wxPoint( dx / 2, dy / 2 ) );
+
+ return bestzoom;
+}
+
+
+wxString SCH_EDIT_FRAME::GetUniqueFilenameForCurrentSheet()
+{
+ wxFileName fn = GetScreen()->GetFileName();
+
+ // Name is <root sheet filename>-<sheet path> and has no extension.
+ // However if filename is too long name is <sheet filename>-<sheet number>
+
+ #define FN_LEN_MAX 80 // A reasonable value for the short filename len
+
+ wxString filename = fn.GetName();
+ wxString sheetFullName = m_CurrentSheet->PathHumanReadable();
+
+ // Remove the last '/' of the path human readable
+ // (and for the root sheet, make sheetFullName empty):
+ sheetFullName.RemoveLast();
+
+ sheetFullName.Trim( true );
+ sheetFullName.Trim( false );
+
+ // Convert path human readable separator to '-'
+ sheetFullName.Replace( wxT( "/" ), wxT( "-" ) );
+
+ if( ( filename.Len() + sheetFullName.Len() ) < FN_LEN_MAX )
+ filename += sheetFullName;
+ else
+ filename << wxT( "-" ) << GetScreen()->m_ScreenNumber;
+
+ return filename;
+}
+
+
+void SCH_EDIT_FRAME::OnModify()
+{
+ GetScreen()->SetModify();
+ GetScreen()->SetSave();
+
+ m_foundItems.SetForceSearch();
+}
+
+
+void SCH_EDIT_FRAME::OnUpdateBlockSelected( wxUpdateUIEvent& event )
+{
+ bool enable = ( GetScreen() && GetScreen()->m_BlockLocate.GetCommand() == BLOCK_MOVE );
+
+ event.Enable( enable );
+}
+
+
+void SCH_EDIT_FRAME::OnUpdatePaste( wxUpdateUIEvent& event )
+{
+ event.Enable( m_blockItems.GetCount() > 0 );
+}
+
+
+void SCH_EDIT_FRAME::OnUpdateBusOrientation( wxUpdateUIEvent& aEvent )
+{
+ wxString tool_tip = GetForceHVLines() ?
+ _( "Draw wires and buses in any direction" ) :
+ _( "Draw horizontal and vertical wires and buses only" );
+
+ aEvent.Check( GetForceHVLines() );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_BUS_WIRES_ORIENT, tool_tip );
+}
+
+
+void SCH_EDIT_FRAME::OnUpdateHiddenPins( wxUpdateUIEvent& aEvent )
+{
+ wxString tool_tip = m_showAllPins ? _( "Do not show hidden pins" ) :
+ _( "Show hidden pins" );
+
+ aEvent.Check( m_showAllPins );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_HIDDEN_PINS, tool_tip );
+}
+
+
+void SCH_EDIT_FRAME::OnUpdateSave( wxUpdateUIEvent& aEvent )
+{
+ SCH_SHEET_LIST sheetList;
+
+ aEvent.Enable( sheetList.IsModified() );
+}
+
+
+void SCH_EDIT_FRAME::OnUpdateSaveSheet( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Enable( GetScreen()->IsModify() );
+
+}
+
+
+void SCH_EDIT_FRAME::OnUpdateHierarchySheet( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Enable( m_CurrentSheet->Last() != g_RootSheet );
+}
+
+
+void SCH_EDIT_FRAME::OnAnnotate( wxCommandEvent& event )
+{
+ InvokeDialogAnnotate( this );
+}
+
+
+void SCH_EDIT_FRAME::OnErc( wxCommandEvent& event )
+{
+ // See if it's already open...
+ wxWindow* erc = FindWindowById( ID_DIALOG_ERC, this );
+
+ if( erc )
+ // Bring it to the top if already open. Dual monitor users need this.
+ erc->Raise();
+ else
+ InvokeDialogERC( this );
+}
+
+
+void SCH_EDIT_FRAME::OnCreateNetlist( wxCommandEvent& event )
+{
+ int result;
+
+ do
+ {
+ result = InvokeDialogNetList( this );
+
+ // If a plugin is removed or added, rebuild and reopen the new dialog
+
+ } while( result == NET_PLUGIN_CHANGE );
+}
+
+
+void SCH_EDIT_FRAME::OnCreateBillOfMaterials( wxCommandEvent& )
+{
+ InvokeDialogCreateBOM( this );
+}
+
+
+void SCH_EDIT_FRAME::OnFindItems( wxCommandEvent& aEvent )
+{
+ wxCHECK_RET( m_findReplaceData != NULL,
+ wxT( "Forgot to create find/replace data. Bad Programmer!" ) );
+
+ if( m_dlgFindReplace )
+ {
+ delete m_dlgFindReplace;
+ m_dlgFindReplace = NULL;
+ }
+
+ // Verify the find dialog is not drawn off the visible display area in case the
+ // display configuration has changed since the last time the dialog position was
+ // saved.
+ wxRect displayRect = wxDisplay().GetGeometry();
+ wxRect dialogRect = wxRect( m_findDialogPosition, m_findDialogSize );
+
+ wxPoint position = m_findDialogPosition;
+
+ if( !displayRect.Contains( dialogRect ) )
+ {
+ position = wxDefaultPosition;
+ }
+
+ int style = 0;
+
+ if( aEvent.GetId() == wxID_REPLACE )
+ style = wxFR_REPLACEDIALOG;
+
+ m_dlgFindReplace = new DIALOG_SCH_FIND( this, m_findReplaceData, position, m_findDialogSize,
+ style );
+
+ m_dlgFindReplace->SetFindEntries( m_findStringHistoryList );
+ m_dlgFindReplace->SetReplaceEntries( m_replaceStringHistoryList );
+ m_dlgFindReplace->Show( true );
+}
+
+
+void SCH_EDIT_FRAME::OnFindDialogClose( wxFindDialogEvent& event )
+{
+ // If the user dismissed the dialog with the mouse, this will send the cursor back
+ // to the last item found.
+ OnFindSchematicItem( event );
+
+ if( m_dlgFindReplace )
+ {
+ m_findDialogPosition = m_dlgFindReplace->GetPosition();
+ m_findDialogSize = m_dlgFindReplace->GetSize();
+ m_findStringHistoryList = m_dlgFindReplace->GetFindEntries();
+ m_replaceStringHistoryList = m_dlgFindReplace->GetReplaceEntries();
+ m_dlgFindReplace->Destroy();
+ m_dlgFindReplace = NULL;
+ }
+}
+
+
+void SCH_EDIT_FRAME::OnLoadFile( wxCommandEvent& event )
+{
+ wxString fn = GetFileFromHistory( event.GetId(), _( "Schematic" ) );
+
+ if( fn.size() )
+ OpenProjectFiles( std::vector<wxString>( 1, fn ) );
+}
+
+
+void SCH_EDIT_FRAME::OnLoadCmpToFootprintLinkFile( wxCommandEvent& event )
+{
+ LoadCmpToFootprintLinkFile();
+ m_canvas->Refresh();
+}
+
+
+void SCH_EDIT_FRAME::OnNewProject( wxCommandEvent& event )
+{
+// wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
+ wxString pro_dir = m_mruPath;
+
+ wxFileDialog dlg( this, _( "New Schematic" ), pro_dir,
+ wxEmptyString, SchematicFileWildcard,
+ wxFD_SAVE );
+
+ if( dlg.ShowModal() != wxID_CANCEL )
+ {
+ // Enforce the extension, wxFileDialog is inept.
+ wxFileName create_me = dlg.GetPath();
+ create_me.SetExt( SchematicFileExtension );
+
+ if( create_me.FileExists() )
+ {
+ wxString msg = wxString::Format( _(
+ "Schematic file '%s' already exists, use Open instead" ),
+ GetChars( create_me.GetFullName() )
+ );
+ DisplayError( this, msg );
+ return ;
+ }
+
+ // OpenProjectFiles() requires absolute
+ wxASSERT_MSG( create_me.IsAbsolute(), wxT( "wxFileDialog returned non-absolute" ) );
+
+ OpenProjectFiles( std::vector<wxString>( 1, create_me.GetFullPath() ), KICTL_CREATE );
+ m_mruPath = create_me.GetPath();
+ }
+}
+
+
+void SCH_EDIT_FRAME::OnLoadProject( wxCommandEvent& event )
+{
+// wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
+ wxString pro_dir = m_mruPath;
+
+ wxFileDialog dlg( this, _( "Open Schematic" ), pro_dir,
+ wxEmptyString, SchematicFileWildcard,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST );
+
+ if( dlg.ShowModal() != wxID_CANCEL )
+ {
+ OpenProjectFiles( std::vector<wxString>( 1, dlg.GetPath() ) );
+ m_mruPath = Prj().GetProjectPath();
+ }
+}
+
+
+void SCH_EDIT_FRAME::OnOpenPcbnew( wxCommandEvent& event )
+{
+ wxFileName kicad_board = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() );
+
+ if( kicad_board.IsOk() )
+ {
+ kicad_board.SetExt( PcbFileExtension );
+ wxFileName legacy_board( kicad_board );
+ legacy_board.SetExt( LegacyPcbFileExtension );
+ wxFileName& boardfn = ( !legacy_board.FileExists() || kicad_board.FileExists() ) ?
+ kicad_board : legacy_board;
+
+ if( Kiface().IsSingle() )
+ {
+ wxString filename = QuoteFullPath( boardfn );
+ ExecuteFile( this, PCBNEW_EXE, filename );
+ }
+ else
+ {
+ KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB, true );
+
+ // a pcb frame can be already existing, but not yet used.
+ // this is the case when running the footprint editor, or the footprint viewer first
+ // if the frame is not visible, the board is not yet loaded
+ if( !frame->IsVisible() )
+ {
+ frame->OpenProjectFiles( std::vector<wxString>( 1, boardfn.GetFullPath() ) );
+ frame->Show( true );
+ }
+
+ // On Windows, Raise() does not bring the window on screen, when iconized
+ if( frame->IsIconized() )
+ frame->Iconize( false );
+
+ frame->Raise();
+ }
+ }
+ else
+ {
+ ExecuteFile( this, PCBNEW_EXE );
+ }
+}
+
+
+void SCH_EDIT_FRAME::OnOpenPcbModuleEditor( wxCommandEvent& event )
+{
+ wxFileName fn = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() );
+
+ if( fn.IsOk() )
+ {
+ KIWAY_PLAYER* fp_editor = Kiway().Player( FRAME_PCB_MODULE_EDITOR );
+
+ // On Windows, Raise() does not bring the window on screen, when iconized
+ if( fp_editor->IsIconized() )
+ fp_editor->Iconize( false );
+
+ fp_editor->Show( true );
+ fp_editor->Raise();
+ }
+}
+
+
+void SCH_EDIT_FRAME::OnOpenCvpcb( wxCommandEvent& event )
+{
+ wxFileName fn = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() );
+
+ fn.SetExt( NetlistFileExtension );
+
+ if( prepareForNetlist() )
+ {
+ KIWAY_PLAYER* player = Kiway().Player( FRAME_CVPCB, false ); // test open already.
+
+ if( !player )
+ {
+ player = Kiway().Player( FRAME_CVPCB, true );
+ player->Show( true );
+ // player->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
+ }
+
+ sendNetlist();
+
+ player->Raise();
+ }
+}
+
+
+void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event )
+{
+ SCH_COMPONENT* component = NULL;
+
+ if( event.GetId() == ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP )
+ {
+ // We want to edit a component with Libedit.
+ // we are here by a hot key, or by a popup menu
+ SCH_ITEM* item = GetScreen()->GetCurItem();
+
+ if( !item )
+ {
+ // If we didn't get here by a hot key, then something has gone wrong.
+ if( event.GetInt() == 0 )
+ return;
+
+ EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) event.GetClientObject();
+
+ wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
+
+ // Set the locat filter, according to the edit command
+ const KICAD_T* filterList = SCH_COLLECTOR::ComponentsOnly;
+ item = LocateAndShowItem( data->GetPosition(), filterList, event.GetInt() );
+
+ // Exit if no item found at the current location or the item is already being edited.
+ if( (item == NULL) || (item->GetFlags() != 0) )
+ return;
+ }
+
+
+ if( !item || (item->GetFlags() != 0) || ( item->Type() != SCH_COMPONENT_T ) )
+ {
+ wxMessageBox( _( "Error: not a component or no component" ) );
+ return;
+ }
+
+ component = (SCH_COMPONENT*) item;
+ }
+
+ LIB_EDIT_FRAME* libeditFrame = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, false );
+
+ if( !libeditFrame )
+ {
+ libeditFrame = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, true );
+ libeditFrame->Show( true );
+ }
+
+ libeditFrame->PushPreferences( m_canvas );
+
+ // On Windows, Raise() does not bring the window on screen, when iconized
+ if( libeditFrame->IsIconized() )
+ libeditFrame->Iconize( false );
+
+ libeditFrame->Raise();
+
+ if( component )
+ {
+ if( PART_LIBS* libs = Prj().SchLibs() )
+ {
+ LIB_ALIAS* entry = libs->FindLibraryEntry( component->GetPartName() );
+
+ if( !entry ) // Should not occur
+ return;
+
+ PART_LIB* library = entry->GetLib();
+
+ libeditFrame->LoadComponentAndSelectLib( entry, library );
+ }
+ }
+}
+
+
+void SCH_EDIT_FRAME::OnRescueProject( wxCommandEvent& event )
+{
+ RescueProject( true );
+}
+
+
+void SCH_EDIT_FRAME::OnExit( wxCommandEvent& event )
+{
+ Close( false );
+}
+
+
+void SCH_EDIT_FRAME::OnPrint( wxCommandEvent& event )
+{
+ InvokeDialogPrintUsingPrinter( this );
+
+ wxFileName fn = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() );
+
+ if( fn.GetName() != NAMELESS_PROJECT )
+ {
+ // was: wxGetApp().WriteProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParametersList() );
+ Prj().ConfigSave( Kiface().KifaceSearch(), GROUP_SCH_EDITOR,
+ GetProjectFileParametersList() );
+ }
+}
+
+
+void SCH_EDIT_FRAME::PrintPage( wxDC* aDC, LSET aPrintMask, bool aPrintMirrorMode,
+ void* aData )
+{
+ wxString fileName = Prj().AbsolutePath( GetScreen()->GetFileName() );
+
+ GetScreen()->Draw( m_canvas, aDC, GR_DEFAULT_DRAWMODE );
+ DrawWorkSheet( aDC, GetScreen(), GetDefaultLineThickness(), IU_PER_MILS, fileName );
+}
+
+
+void SCH_EDIT_FRAME::OnSelectItem( wxCommandEvent& aEvent )
+{
+ int id = aEvent.GetId();
+ int index = id - ID_SELECT_ITEM_START;
+
+ if( (id >= ID_SELECT_ITEM_START && id <= ID_SELECT_ITEM_END)
+ && (index >= 0 && index < m_collectedItems.GetCount()) )
+ {
+ SCH_ITEM* item = m_collectedItems[index];
+ m_canvas->SetAbortRequest( false );
+ GetScreen()->SetCurItem( item );
+ }
+}
+
+
+bool SCH_EDIT_FRAME::isAutoSaveRequired() const
+{
+ // In case this event happens before g_RootSheet is initialized which does happen
+ // on mingw64 builds.
+
+ if( g_RootSheet != NULL )
+ {
+ SCH_SHEET_LIST sheetList;
+
+ return sheetList.IsAutoSaveRequired();
+ }
+
+ return false;
+}
+
+
+void SCH_EDIT_FRAME::addCurrentItemToList( bool aRedraw )
+{
+ SCH_SCREEN* screen = GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+
+ wxCHECK_RET( item != NULL, wxT( "Cannot add current item to list." ) );
+
+ m_canvas->SetAutoPanRequest( false );
+
+ SCH_ITEM* undoItem = item;
+
+ if( item->Type() == SCH_SHEET_PIN_T )
+ {
+ SCH_SHEET* sheet = (SCH_SHEET*) item->GetParent();
+
+ wxCHECK_RET( (sheet != NULL) && (sheet->Type() == SCH_SHEET_T),
+ wxT( "Cannot place sheet pin in invalid schematic sheet object." ) );
+
+ undoItem = sheet;
+ }
+
+ else if( item->Type() == SCH_FIELD_T )
+ {
+ SCH_COMPONENT* cmp = (SCH_COMPONENT*) item->GetParent();
+
+ wxCHECK_RET( (cmp != NULL) && (cmp->Type() == SCH_COMPONENT_T),
+ wxT( "Cannot place field in invalid schematic component object." ) );
+
+ undoItem = cmp;
+ }
+
+ if( item->IsNew() )
+ {
+ if( item->Type() == SCH_SHEET_T )
+ {
+ // Fix the size and position of the new sheet using the last values set by
+ // the m_mouseCaptureCallback function.
+ m_canvas->SetMouseCapture( NULL, NULL );
+
+ if( !EditSheet( (SCH_SHEET*)item, m_CurrentSheet ) )
+ {
+ screen->SetCurItem( NULL );
+ delete item;
+
+ if( aRedraw )
+ GetCanvas()->Refresh();
+
+ return;
+ }
+
+ SetSheetNumberAndCount();
+ }
+
+ if( undoItem == item )
+ {
+ if( !screen->CheckIfOnDrawList( item ) ) // don't want a loop!
+ screen->Append( item );
+
+ SetRepeatItem( item );
+
+ SaveCopyInUndoList( undoItem, UR_NEW );
+ }
+ else
+ {
+ // Here, item is not a basic schematic item, but an item inside
+ // a parent basic schematic item,
+ // currently: sheet pin or component field.
+ // currently, only a sheet pin can be found as new item,
+ // because new component fields have a specific handling, and do not appears here
+ SaveCopyInUndoList( undoItem, UR_CHANGED );
+
+ if( item->Type() == SCH_SHEET_PIN_T )
+ ( (SCH_SHEET*)undoItem )->AddPin( (SCH_SHEET_PIN*) item );
+ else
+ wxLogMessage( wxT( "addCurrentItemToList: expected type = SCH_SHEET_PIN_T, actual type = %d" ),
+ item->Type() );
+ }
+ }
+ else
+ {
+ SaveUndoItemInUndoList( undoItem );
+ }
+
+ item->ClearFlags();
+ screen->SetModify();
+ screen->SetCurItem( NULL );
+ m_canvas->SetMouseCapture( NULL, NULL );
+ m_canvas->EndMouseCapture();
+
+ if( item->IsConnectable() )
+ screen->TestDanglingEnds();
+
+ if( aRedraw )
+ GetCanvas()->Refresh();
+}
+
+
+void SCH_EDIT_FRAME::UpdateTitle()
+{
+ wxString title;
+
+ if( GetScreen()->GetFileName() == m_DefaultSchematicFileName )
+ {
+ title.Printf( wxT( "Eeschema %s [%s]" ), GetChars( GetBuildVersion() ),
+ GetChars( GetScreen()->GetFileName() ) );
+ }
+ else
+ {
+ wxString fileName = Prj().AbsolutePath( GetScreen()->GetFileName() );
+ wxFileName fn = fileName;
+
+ title.Printf( wxT( "[ %s %s] (%s)" ),
+ GetChars( fn.GetName() ),
+ GetChars( m_CurrentSheet->PathHumanReadable() ),
+ GetChars( fn.GetPath() ) );
+
+ if( fn.FileExists() )
+ {
+ if( !fn.IsFileWritable() )
+ title += _( " [Read Only]" );
+ }
+ else
+ title += _( " [no file]" );
+ }
+
+ SetTitle( title );
+}
+
diff --git a/eeschema/schframe.h b/eeschema/schframe.h
new file mode 100644
index 0000000..0db8ea8
--- /dev/null
+++ b/eeschema/schframe.h
@@ -0,0 +1,1351 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras wanadoo.fr
+ * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file wxEeschemaStruct.h
+ */
+
+#ifndef WX_EESCHEMA_STRUCT_H
+#define WX_EESCHEMA_STRUCT_H
+
+#include <sch_base_frame.h>
+#include <config_params.h>
+#include <class_undoredo_container.h>
+#include <template_fieldnames.h>
+#include <block_commande.h>
+#include <class_sch_screen.h>
+#include <sch_collectors.h>
+
+
+class LIB_EDIT_FRAME;
+class LIB_VIEW_FRAME;
+class DRAWSEGMENT;
+class SCH_ITEM;
+class SCH_NO_CONNECT;
+class EDA_ITEM;
+class SCH_BUS_ENTRY_BASE;
+class SCH_BUS_WIRE_ENTRY;
+class SCH_BUS_BUS_ENTRY;
+class SCH_GLOBALLABEL;
+class SCH_TEXT;
+class SCH_BITMAP;
+class SCH_SHEET;
+class SCH_SHEET_PATH;
+class SCH_SHEET_PIN;
+class SCH_COMPONENT;
+class SCH_FIELD;
+class LIB_PIN;
+class SCH_JUNCTION;
+class DIALOG_SCH_FIND;
+class wxFindDialogEvent;
+class wxFindReplaceData;
+class SCHLIB_FILTER;
+
+
+/// enum used in RotationMiroir()
+enum COMPONENT_ORIENTATION_T {
+ CMP_NORMAL, // Normal orientation, no rotation or mirror
+ CMP_ROTATE_CLOCKWISE, // Rotate -90
+ CMP_ROTATE_COUNTERCLOCKWISE, // Rotate +90
+ CMP_ORIENT_0, // No rotation and no mirror id CMP_NORMAL
+ CMP_ORIENT_90, // Rotate 90, no mirror
+ CMP_ORIENT_180, // Rotate 180, no mirror
+ CMP_ORIENT_270, // Rotate -90, no mirror
+ CMP_MIRROR_X = 0x100, // Mirror around X axis
+ CMP_MIRROR_Y = 0x200 // Mirror around Y axis
+};
+
+
+/** Schematic annotation order options. */
+enum ANNOTATE_ORDER_T {
+ SORT_BY_X_POSITION, ///< Annotate by X position from left to right.
+ SORT_BY_Y_POSITION, ///< Annotate by Y position from top to bottom.
+ UNSORTED, ///< Annotate by position of component in the schematic sheet
+ ///< object list.
+};
+
+
+/** Schematic annotation type options. */
+enum ANNOTATE_OPTION_T {
+ INCREMENTAL_BY_REF, ///< Annotate incrementally using the first free reference number.
+ SHEET_NUMBER_X_100, ///< Annotate using the first free reference number starting at
+ ///< the sheet number * 100.
+ SHEET_NUMBER_X_1000, ///< Annotate using the first free reference number starting at
+ ///< the sheet number * 1000.
+};
+
+
+/// Schematic search type used by the socket link with Pcbnew
+enum SCH_SEARCH_T {
+ FIND_COMPONENT_ONLY, ///< Find a component in the schematic.
+ FIND_PIN, ///< Find a component pin in the schematic.
+ FIND_REFERENCE, ///< Find an item by it's reference designator.
+ FIND_VALUE, ///< Find an item by it's value field.
+ FIND_FIELD ///< Find a component field.
+};
+
+
+#define SCH_EDIT_FRAME_NAME wxT( "SchematicFrame" )
+
+/**
+ * Schematic editor (Eeschema) main window.
+ */
+class SCH_EDIT_FRAME : public SCH_BASE_FRAME
+{
+private:
+ SCH_SHEET_PATH* m_CurrentSheet; ///< which sheet we are presently working on.
+ wxString m_DefaultSchematicFileName;
+
+ PARAM_CFG_ARRAY m_projectFileParams;
+ PARAM_CFG_ARRAY m_configSettings;
+ wxPageSetupDialogData m_pageSetupData;
+ wxFindReplaceData* m_findReplaceData;
+ wxPoint m_previewPosition;
+ wxSize m_previewSize;
+ wxPoint m_printDialogPosition;
+ wxSize m_printDialogSize;
+ bool m_printMonochrome; ///< Print monochrome instead of grey scale.
+ bool m_printSheetReference;
+ DIALOG_SCH_FIND* m_dlgFindReplace;
+ wxPoint m_findDialogPosition;
+ wxSize m_findDialogSize;
+ wxArrayString m_findStringHistoryList;
+ wxArrayString m_replaceStringHistoryList;
+ BLOCK_SELECTOR m_blockItems; ///< List of selected items.
+ SCH_ITEM* m_item_to_repeat; ///< Last item to insert by the repeat command.
+ int m_repeatLabelDelta; ///< Repeat label number increment step.
+ SCH_COLLECTOR m_collectedItems; ///< List of collected items.
+ SCH_FIND_COLLECTOR m_foundItems; ///< List of find/replace items.
+ SCH_ITEM* m_undoItem; ///< Copy of the current item being edited.
+ wxString m_simulatorCommand; ///< Command line used to call the circuit
+ ///< simulator (gnucap, spice, ...)
+ wxString m_netListerCommand; ///< Command line to call a custom net list
+ ///< generator.
+
+ bool m_forceHVLines; ///< force H or V directions for wires, bus, line
+
+ /// An index to the last find item in the found items list #m_foundItems.
+ int m_foundItemIndex;
+
+ /// Flag to indicate show hidden pins.
+ bool m_showAllPins;
+
+ /// The name of the destination directory to use when generating plot files.
+ wxString m_plotDirectoryName;
+
+ /// The name of the format to use when generating a net list.
+ wxString m_netListFormat;
+
+ /// Add X prefix to component references when generating spice net lists.
+ bool m_spiceNetlistAddReferencePrefix;
+
+ /// Use netcodes (net number) as net names when generating spice net lists.
+ bool m_spiceNetlistUseNetcodeAsNetname;
+
+ /* these are PROJECT specific, not schematic editor specific
+ wxString m_userLibraryPath;
+ wxArrayString m_componentLibFiles;
+ */
+
+ static int m_lastSheetPinType; ///< Last sheet pin type.
+ static wxSize m_lastSheetPinTextSize; ///< Last sheet pin text size.
+ static wxPoint m_lastSheetPinPosition; ///< Last sheet pin position.
+
+protected:
+ TEMPLATES m_TemplateFieldNames;
+
+ /**
+ * Initializing accessor for the pin text size
+ */
+ const wxSize &GetLastSheetPinTextSize();
+
+ /**
+ * Function doAutoSave
+ * saves the schematic files that have been modified and not yet saved.
+ *
+ * @return true if the auto save was successful otherwise false.
+ */
+ virtual bool doAutoSave();
+
+ /**
+ * Function autoSaveRequired
+ * returns true if the schematic has been modified.
+ */
+ virtual bool isAutoSaveRequired() const;
+
+ /**
+ * Function addCurrentItemToList
+ * adds the item currently being edited to the schematic and adds the changes to
+ * the undo/redo container.
+ *
+ * @param aRedraw = true (default) to redrw -the screen after adding the item.
+ */
+ void addCurrentItemToList( bool aRedraw = true );
+
+ void updateFindReplaceView( wxFindDialogEvent& aEvent );
+
+ void backAnnotateFootprints( const std::string& aChangedSetOfReferences )
+ throw( IO_ERROR, boost::bad_pointer );
+
+ /**
+ * Function prepareForNetlist
+ * verifies that annotation is complete so that a proper netlist is even
+ * possible. If not, asks the user if annotation should be done.
+ * @return bool - true if annotation is complete, else false.
+ */
+ bool prepareForNetlist();
+
+ /**
+ * Function sendNetlist
+ * sends the kicad netlist over to CVPCB.
+ */
+ void sendNetlist();
+
+public:
+ SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );
+ ~SCH_EDIT_FRAME();
+
+ SCH_SCREEN* GetScreen() const; // overload SCH_BASE_FRAME
+
+ void OnCloseWindow( wxCloseEvent& Event );
+
+ bool GetForceHVLines() const { return m_forceHVLines; }
+ void SetForceHVLines( bool aForceHVdirection ) { m_forceHVLines = aForceHVdirection; }
+
+ bool GetShowAllPins() const { return m_showAllPins; }
+
+ void SetShowAllPins( bool aEnable ) { m_showAllPins = aEnable; }
+
+ const wxString GetNetListFormatName() const { return m_netListFormat; }
+
+ void SetNetListFormatName( const wxString& aFormat ) { m_netListFormat = aFormat; }
+
+ bool GetSpiceAddReferencePrefix() const { return m_spiceNetlistAddReferencePrefix; }
+
+ void SetSpiceAddReferencePrefix( bool aEnable ) { m_spiceNetlistAddReferencePrefix = aEnable; }
+
+ bool GetSpiceUseNetcodeAsNetname() const { return m_spiceNetlistUseNetcodeAsNetname; }
+
+ void SetSpiceUseNetcodeAsNetname( bool aEnable ) { m_spiceNetlistUseNetcodeAsNetname = aEnable; }
+
+ /* These are PROJECT specific, not schematic editor specific
+ wxString GetUserLibraryPath() const { return m_userLibraryPath; }
+ void SetUserLibraryPath( const wxString& aPath ) { m_userLibraryPath = aPath; }
+ const wxArrayString& GetComponentLibraries() const { return m_componentLibFiles; }
+ void SetComponentLibraries( const wxArrayString& aList ) { m_componentLibFiles = aList; }
+ */
+
+ /// accessor to the destination directory to use when generating plot files.
+ const wxString& GetPlotDirectoryName() const { return m_plotDirectoryName; }
+ void SetPlotDirectoryName( const wxString& aDirName ) { m_plotDirectoryName = aDirName; }
+
+ void Process_Special_Functions( wxCommandEvent& event );
+ void OnColorConfig( wxCommandEvent& aEvent );
+ void Process_Config( wxCommandEvent& event );
+ void OnSelectTool( wxCommandEvent& aEvent );
+
+ bool GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey = 0 );
+
+ /**
+ * Function GetProjectFileParametersList
+ * returns the project file parameter list for Eeschema.
+ *
+ *<p>
+ * Populate the project file parameter array specific to Eeschema if it hasn't
+ * already been populated and return a reference to the array to the caller.
+ * </p>
+ */
+ PARAM_CFG_ARRAY& GetProjectFileParametersList();
+
+ /**
+ * Function SaveProjectSettings
+ * saves changes to the project settings to the project (.pro) file.
+ * @param aAskForSave = true to open a dialog before saving the settings
+ */
+ void SaveProjectSettings( bool aAskForSave );
+
+ /**
+ * Function LoadProjectFile
+ * loads the KiCad project file (*.pro) settings specific to Eeschema.
+ *
+ * @return True if the project file was loaded correctly.
+ */
+ bool LoadProjectFile();
+
+ /**
+ * Function GetDefaultFieldName
+ * returns a default symbol field name for field \a aFieldNdx for all components.
+ * These field names are not modifiable, but template field names are.
+ * @param aFieldNdx The field number index
+ */
+ static wxString GetDefaultFieldName( int aFieldNdx );
+
+ /**
+ * Function AddTemplateFieldName
+ * inserts or appends a wanted symbol field name into the field names
+ * template. Should be used for any symbol property editor. If the name
+ * already exists, it overwrites the same name.
+ *
+ * @param aFieldName is a full description of the wanted field, and it must not match
+ * any of the default field names.
+ * @return int - the index within the config container at which aFieldName was
+ * added, or -1 if the name is illegal because it matches a default field name.
+ */
+ int AddTemplateFieldName( const TEMPLATE_FIELDNAME& aFieldName )
+ {
+ return m_TemplateFieldNames.AddTemplateFieldName( aFieldName );
+ }
+
+
+ /**
+ * Function GetTemplateFieldName
+ * returns a template field names list for read only access.
+ */
+ const TEMPLATE_FIELDNAMES& GetTemplateFieldNames()
+ {
+ return m_TemplateFieldNames.GetTemplateFieldNames();
+ }
+
+
+ /**
+ * Function GetTemplates
+ * returns the field names template for read only access.
+ */
+ const TEMPLATES& GetTemplates()
+ {
+ return m_TemplateFieldNames;
+ }
+
+ /**
+ * Function DeleteAllTemplateFieldNames
+ * removes all template field names.
+ */
+ void DeleteAllTemplateFieldNames()
+ {
+ m_TemplateFieldNames.DeleteAllTemplateFieldNames();
+ }
+
+ /**
+ * Function GetConfigurationSettings
+ * returns the Eeschema applications settings.
+ * <p>
+ * This replaces the old statically define list that had the project file settings and
+ * the application settings mixed together. This was confusing and caused some settings
+ * to get saved and loaded incorrectly. Currently, only the settings that are needed at
+ * start up by the main window are defined here. There are other locally used settings
+ * scattered throughout the Eeschema source code. If you need to define a configuration
+ * setting that need to be loaded at run time, this is the place to define it.
+ * </p>
+ */
+ PARAM_CFG_ARRAY& GetConfigurationSettings();
+
+ void LoadSettings( wxConfigBase* aCfg );
+ void SaveSettings( wxConfigBase* aCfg );
+
+ void RedrawActiveWindow( wxDC* DC, bool EraseBg );
+
+ void CreateScreens();
+ void ReCreateHToolbar();
+ void ReCreateVToolbar();
+ void ReCreateOptToolbar();
+ void ReCreateMenuBar();
+
+ ///> @copydoc EDA_DRAW_FRAME::GetHotKeyDescription()
+ EDA_HOTKEY* GetHotKeyDescription( int aCommand ) const;
+
+ bool OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem = NULL );
+
+ /**
+ * Function OnModify
+ * Must be called after a schematic change
+ * in order to set the "modify" flag of the current screen
+ * and update the date in frame reference
+ */
+ void OnModify();
+
+ virtual wxString GetScreenDesc() const;
+
+ void InstallConfigFrame( wxCommandEvent& event );
+
+ /**
+ * Execute a remote command send by Pcbnew via a socket,
+ * port KICAD_SCH_PORT_SERVICE_NUMBER (currently 4243)
+ * this is a virtual function called by EDA_DRAW_FRAME::OnSockRequest().
+ * @param cmdline = received command from socket
+ */
+ virtual void ExecuteRemoteCommand( const char* cmdline );
+
+ void KiwayMailIn( KIWAY_EXPRESS& aEvent ); // override virtual from KIWAY_PLAYER
+
+ void OnLeftClick( wxDC* aDC, const wxPoint& aPosition );
+ void OnLeftDClick( wxDC* aDC, const wxPoint& aPosition );
+ bool OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu );
+ void OnSelectOptionToolbar( wxCommandEvent& event );
+ double BestZoom();
+
+ /**
+ * Function LocateAndShowItem
+ * checks the schematic at \a aPosition in logical (drawing) units for a item
+ * matching the types in \a aFilterList.
+ * <p>
+ * The search is first performed at the nearest grid position to \a aPosition. If no
+ * item if found on grid, then \a aPosition is tested for any items. If the item found
+ * can be cross probed, a message is send to Pcbnew and the selected item is highlighted
+ * in PCB editor.
+ * </p>
+ * @param aPosition The wxPoint on the schematic to search.
+ * @param aFilterList A list of #KICAD_T types to to filter.
+ * @param aHotKeyCommandId A hot key command ID for performing additional tests when
+ * multiple items are found at \a aPosition.
+ * @return A SCH_ITEM pointer of the item found or NULL if no item found
+ */
+ SCH_ITEM* LocateAndShowItem( const wxPoint& aPosition,
+ const KICAD_T aFilterList[] = SCH_COLLECTOR::AllItems,
+ int aHotKeyCommandId = 0 );
+
+ /**
+ * Function LocateItem
+ * checks for items at \a aPosition matching the types in \a aFilterList.
+ * <p>
+ * If multiple items are located at \a aPosition, a context menu is displayed to clarify
+ * which item the user intended to select. If the user aborts the context menu, NULL is
+ * returned and the abort request flag will be set to true. Make sure to clear this flag
+ * before attempting to display any other context menus.
+ * </p>
+ *
+ * @param aPosition The wxPoint location where to search.
+ * @param aFilterList A list of #KICAD_T types to to filter.
+ * @param aHotKeyCommandId A hot key command ID for performing additional tests when
+ * multiple items are found at \a aPosition.
+ * @return The SCH_ITEM pointer of the item found or NULL if no item found.
+ */
+ SCH_ITEM* LocateItem( const wxPoint& aPosition,
+ const KICAD_T aFilterList[] = SCH_COLLECTOR::AllItems,
+ int aHotKeyCommandId = 0 );
+
+ /**
+ * Function DeleteItemAtCrossHair
+ * delete the item found under the cross hair. If multiple items are found at the
+ * cross hair position, a context menu is displayed to clarify which item to delete.
+ * See LocateItem() for more information on locating multiple items.
+ *
+ * @param aDC The device context to update if and item is deleted.
+ * @return True if an item was deleted.
+ */
+ bool DeleteItemAtCrossHair( wxDC* aDC );
+
+ /**
+ * Function FindComponentAndItem
+ * finds a component in the schematic and an item in this component.
+ * @param aReference The component reference designator to find.
+ * @param aSearchHierarchy If false, search the current sheet only. Otherwise,
+ * the entire hierarchy
+ * @param aSearchType A #SCH_SEARCH_T value used to determine what to search for.
+ * @param aSearchText The text to search for, either in value, reference or elsewhere.
+ * @param aWarpMouse If true, then move the mouse cursor to the item.
+ */
+ SCH_ITEM* FindComponentAndItem( const wxString& aReference,
+ bool aSearchHierarchy,
+ SCH_SEARCH_T aSearchType,
+ const wxString& aSearchText,
+ bool aWarpMouse );
+
+ /**
+ * Function SendMessageToPcbnew
+ * send a remote to Pcbnew via a socket connection.
+ * @param objectToSync Item to be located on board (footprint, pad or text)
+ * @param LibItem Component in library if objectToSync is a sub item of a component
+ * <p>
+ * Commands are
+ * $PART: reference put cursor on footprint anchor
+ * $PIN: number $PART: reference put cursor on the footprint pad
+ * </p>
+ */
+ void SendMessageToPCBNEW( EDA_ITEM* objectToSync, SCH_COMPONENT* LibItem );
+
+ /**
+ * BuildNetListBase
+ * netlist generation:
+ * Creates a flat list which stores all connected objects, and mainly
+ * pins and labels.
+ * @return NETLIST_OBJECT_LIST* - caller owns the object.
+ */
+ NETLIST_OBJECT_LIST* BuildNetListBase();
+
+ /**
+ * Function CreateNetlist
+ * <ul>
+ * <li> test for some issues (missing or duplicate references and sheet names)
+ * <li> build netlist info
+ * <li> create the netlist file (different formats)
+ * </ul>
+ * @param aFormat = netlist format (NET_TYPE_PCBNEW ...)
+ * @param aFullFileName = full netlist file name
+ * @param aNetlistOptions = netlist options using OR'ed bits.
+ * <p>
+ * For SPICE netlist only:
+ * if NET_USE_NETNAMES is set, use net names from labels in schematic
+ * else use net numbers (net codes)
+ * if NET_USE_X_PREFIX is set : change "U" and "IC" refernce prefix to "X"
+ * </p>
+ * @param aReporter = a REPORTER to report error messages,
+ * mainly if a command line must be run (can be NULL
+ * @return true if success.
+ */
+ bool CreateNetlist( int aFormat,
+ const wxString& aFullFileName,
+ unsigned aNetlistOptions,
+ REPORTER* aReporter = NULL );
+
+ /**
+ * Function WriteNetListFile
+ * Create the netlist file. Netlist info must be existing
+ * (BuildNetListBase() creates this info)
+ * @param aConnectedItemsList = the initialized list of connected items, take ownership.
+ * @param aFormat = netlist format (NET_TYPE_PCBNEW ...)
+ * @param aFullFileName = full netlist file name
+ * @param aNetlistOptions = netlist options using OR'ed bits.
+ * <p>
+ * For SPICE netlist only:
+ * if NET_USE_NETNAMES is set, use net names from labels in schematic
+ * else use net numbers (net codes)
+ * if NET_USE_X_PREFIX is set : change "U" and "IC" refernce prefix to "X"
+ * </p>
+ * @param aReporter = a REPORTER to report error messages,
+ * mainly if a command line must be run (can be NULL
+ * @return true if success.
+ */
+ bool WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList,
+ int aFormat,
+ const wxString& aFullFileName,
+ unsigned aNetlistOptions,
+ REPORTER* aReporter = NULL );
+
+ /**
+ * Function DeleteAnnotation
+ * clears the current component annotation.
+ * @param aCurrentSheetOnly Clear only the annotation for the current sheet if true.
+ * Otherwise clear the entire schematic annotation.
+ */
+ void DeleteAnnotation( bool aCurrentSheetOnly );
+
+ /**
+ * Function AnnotateComponents
+ *
+ * annotates the components in the schematic that are not currently annotated.
+ *
+ * @param aAnnotateSchematic Annotate the entire schematic if true. Otherwise annotate
+ * the current sheet only.
+ * @param aSortOption Define the annotation order. See #ANNOTATE_ORDER_T.
+ * @param aAlgoOption Define the annotation style. See #ANNOTATE_OPTION_T.
+ * @param aResetAnnotation Clear any previous annotation if true. Otherwise, keep the
+ * existing component annotation.
+ * @param aRepairTimestamps Test for and repair any duplicate time stamps if true.
+ * Otherwise, keep the existing time stamps. This option
+ * could change previous annotation because time stamps are
+ * used to handle annotation in complex hierarchies.
+ * @param aLockUnits When both aLockUnits and aResetAnnotation are true, all unit
+ * associations should be kept when reannotating. That is, if
+ * two components were R8A and R8B, they may become R3A and R3B,
+ * but not R3A and R3C or R3C and R4D.
+ * When aResetAnnotation is true but aLockUnits is false, the
+ * usual behavior of annotating each part individually is
+ * performed.
+ * When aResetAnnotation is false, this option has no effect.
+ *
+ * When the sheet number is used in annotation, each sheet annotation starts from sheet
+ * number * 100. In other words the first sheet uses 100 to 199, the second sheet uses
+ * 200 to 299, and so on.
+ */
+ void AnnotateComponents( bool aAnnotateSchematic, ANNOTATE_ORDER_T aSortOption,
+ ANNOTATE_OPTION_T aAlgoOption, bool aResetAnnotation,
+ bool aRepairTimestamps, bool aLockUnits );
+
+ /**
+ * Function CheckAnnotate
+ * checks for annotation errors.
+ *
+ * <p>
+ * The following list of items are checked:
+ * <ul>
+ * <li> Components that are not annotated.
+ * <li> Duplicate component references.
+ * <li> Multiple part per package components where the part\n
+ * number is greater number of parts in the package.
+ * <li> Multiple part per package components where the reference\n
+ * designator is different between parts.
+ * </ul>
+ * </p>
+ *
+ * @return Number of annotation errors found.
+ * @param aMessageList A wxArrayString to store error messages.
+ * @param aOneSheetOnly Check the current sheet only if true. Otherwise check
+ * the entire schematic.
+ */
+ int CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOnly );
+
+ // Functions used for hierarchy handling
+ SCH_SHEET_PATH& GetCurrentSheet();
+
+ void SetCurrentSheet( const SCH_SHEET_PATH& aSheet );
+
+ /**
+ * Function DisplayCurrentSheet
+ * draws the current sheet on the display.
+ */
+ void DisplayCurrentSheet();
+
+ /**
+ * Function GetUniqueFilenameForCurrentSheet
+ * @return a filename that can be used in plot and print functions
+ * for the current screen and sheet path.
+ * This filename is unique and must be used instead of the screen filename
+ * (or screen filename) when one must creates file for each sheet in the
+ * hierarchy. because in complex hierarchies a sheet and a SCH_SCREEN is
+ * used more than once
+ * Name is &ltroot sheet filename&gt-&ltsheet path&gt and has no extension.
+ * However if filename is too long name is &ltsheet filename&gt-&ltsheet number&gt
+ */
+ wxString GetUniqueFilenameForCurrentSheet();
+
+ /**
+ * Function SetSheetNumberAndCount
+ * Set the m_ScreenNumber and m_NumberOfScreens members for screens
+ * must be called after a delete or add sheet command, and when entering
+ * a sheet
+ */
+ void SetSheetNumberAndCount();
+
+ /**
+ * Show the print dialog
+ */
+ void OnPrint( wxCommandEvent& event );
+
+ wxPageSetupDialogData& GetPageSetupData() { return m_pageSetupData; }
+
+ void SetPreviewPosition( const wxPoint& aPoint ) { m_previewPosition = aPoint; }
+ void SetPreviewSize( const wxSize& aSize ) { m_previewSize = aSize; }
+ const wxPoint& GetPreviewPosition() { return m_previewPosition; }
+ const wxSize& GetPreviewSize() { return m_previewSize; }
+
+ void SetPrintDialogPosition( const wxPoint& aPoint )
+ {
+ m_printDialogPosition = aPoint;
+ }
+
+
+ void SetPrintDialogSize( const wxSize& aSize ) { m_printDialogSize = aSize; }
+ const wxPoint& GetPrintDialogPosition() { return m_printDialogPosition; }
+ const wxSize& GetPrintDialogSize() { return m_printDialogSize; }
+
+ bool GetPrintMonochrome() { return m_printMonochrome; }
+ void SetPrintMonochrome( bool aMonochrome ) { m_printMonochrome = aMonochrome; }
+ bool GetPrintSheetReference() { return m_printSheetReference; }
+ void SetPrintSheetReference( bool aShow ) { m_printSheetReference = aShow; }
+
+ // Plot functions:
+// void ToPostProcess( wxCommandEvent& event );
+ void PlotSchematic( wxCommandEvent& event );
+
+ // read and save files
+ void Save_File( wxCommandEvent& event );
+
+ /**
+ * Function OnSaveProject
+ * is the command event handler to save the entire project and create a component library
+ * archive.
+ *
+ * The component library archive name is &ltroot_name&gt-cache.lib
+ */
+ void OnSaveProject( wxCommandEvent& aEvent );
+
+ bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl = 0 ); // virtual from KIWAY_PLAYER
+
+ /**
+ * Function AppendOneEEProject
+ * read an entire project and loads it into the schematic editor *without*
+ * replacing the existing contents.
+ * @return True if the project was imported properly.
+ */
+ bool AppendOneEEProject();
+
+ /**
+ * Function LoadOneEEFile
+ * loads the schematic (.sch) file \a aFullFileName into \a aScreen.
+ *
+ * @param aScreen Pointer to the associated SCH_SCREEN object in which to load
+ * \a aFullFileName.
+ * @param aFullFileName A reference to a wxString object containing the absolute path
+ * and file name to load.
+ * @param append True if loaded file is being appended to the currently open file instead
+ * of replacing it.
+ * @return True if \a aFullFileName has been loaded (at least partially.)
+ */
+ bool LoadOneEEFile( SCH_SCREEN* aScreen, const wxString& aFullFileName, bool append = false );
+
+ /**
+ * Function ReadCmpToFootprintLinkFile
+ * Loads a .cmp file from CvPcb and update the footprin field
+ * of components
+ * Prepares parameters and calls ProcessCmpToFootprintLinkFile
+ * to actually read the file and update Fp fields
+ */
+ bool LoadCmpToFootprintLinkFile();
+
+ /**
+ * Function ProcessStuffFile
+ * gets footprint info from each line in the Stuff File by Ref Desg
+ *
+ * Read a Cmp To Footprint Link file created by CvPcb (the .cmp file).
+ * That file has lines like:
+ * BeginCmp
+ * TimeStamp = /32307DE2/AA450F67;
+ * Reference = C1;
+ * ValeurCmp = 47uF;
+ * IdModule = CP6;
+ * EndCmp
+ *
+ * @param aFullFilename = the full filename to read
+ * @param aForceVisibilityState = Set to true to change the footprint field visibility
+ * state to \a aVisibilityState. False retains the
+ * current footprint field visibility state.
+ * @param aVisibilityState True to show the footprint field or false to hide the footprint
+ * field if \a aForceVisibilityState is true.
+ * @return bool = true if success.
+ */
+ bool ProcessCmpToFootprintLinkFile( const wxString& aFullFilename,
+ bool aForceVisibilityState,
+ bool aVisibilityState );
+
+ /**
+ * Function SaveEEFile
+ * saves \a aScreen to a schematic file.
+ *
+ * @param aScreen A pointer to the SCH_SCREEN object to save. A NULL pointer saves
+ * the current screen.
+ * @param aSaveUnderNewName Controls how the file is to be saved;: using previous name
+ * or under a new name .
+ * @param aCreateBackupFile Creates a back of the file associated with \a aScreen
+ * if true.
+ * Helper definitions #CREATE_BACKUP_FILE and
+ * #NO_BACKUP_FILE are defined for improved code readability.
+ * @return True if the file has been saved.
+ */
+ bool SaveEEFile( SCH_SCREEN* aScreen,
+ bool aSaveUnderNewName = false,
+ bool aCreateBackupFile = CREATE_BACKUP_FILE );
+
+ // General search:
+
+ bool IsSearchCacheObsolete( const SCH_FIND_REPLACE_DATA& aSearchCriteria );
+
+
+private:
+
+ /**
+ * Function OnMoveItem
+ * handles the #ID_SCH_MOVE_ITEM event used to move schematic itams.
+ */
+ void OnMoveItem( wxCommandEvent& aEvent );
+
+ /**
+ * Function OnRotate
+ * handles the #ID_SCH_ROTATE_CLOCKWISE and #ID_SCH_ROTATE_COUNTERCLOCKWISE events
+ * used to rotate schematic itams and blocks.
+ */
+ void OnRotate( wxCommandEvent& aEvent );
+
+ /**
+ * Function OnEditItem
+ * handles the #ID_SCH_EDIT_ITEM event used to edit schematic itams.
+ */
+ void OnEditItem( wxCommandEvent& aEvent );
+
+ /**
+ * Function OnDragItem
+ * handles the #ID_SCH_DRAG_ITEM event used to drag schematic itams.
+ */
+ void OnDragItem( wxCommandEvent& aEvent );
+
+ /**
+ * Function OnOrient
+ * handles the #ID_SCH_MIRROR_X, #ID_SCH_MIRROR_Y, and #ID_SCH_ORIENT_NORMAL events
+ * used to orient schematic itams and blocks.
+ */
+ void OnOrient( wxCommandEvent& aEvent );
+
+ void OnExit( wxCommandEvent& event );
+ void OnAnnotate( wxCommandEvent& event );
+ void OnErc( wxCommandEvent& event );
+ void OnCreateNetlist( wxCommandEvent& event );
+ void OnCreateBillOfMaterials( wxCommandEvent& event );
+ void OnFindItems( wxCommandEvent& event );
+ void OnFindDialogClose( wxFindDialogEvent& event );
+ void OnFindDrcMarker( wxFindDialogEvent& event );
+ void OnFindCompnentInLib( wxFindDialogEvent& event );
+
+ /**
+ * Function OnFindSchematicItem
+ * finds an item in the schematic matching the search criteria in \a aEvent.
+ *
+ * @param aEvent - Find dialog event containing the find parameters.
+ */
+ void OnFindSchematicItem( wxFindDialogEvent& aEvent );
+
+ /**
+ * Function OnReplace
+ * performs a search and replace of text in an item in the schematic matching the
+ * search and replace criteria in \a aEvent.
+ *
+ * @param aEvent - Find dialog event containing the search and replace parameters.
+ */
+ void OnFindReplace( wxFindDialogEvent& aEvent );
+
+ void OnLoadFile( wxCommandEvent& event );
+ void OnLoadCmpToFootprintLinkFile( wxCommandEvent& event );
+ void OnNewProject( wxCommandEvent& event );
+ void OnLoadProject( wxCommandEvent& event );
+ void OnAppendProject( wxCommandEvent& event );
+ void OnOpenPcbnew( wxCommandEvent& event );
+ void OnOpenPcbModuleEditor( wxCommandEvent& event );
+ void OnOpenCvpcb( wxCommandEvent& event );
+ void OnOpenLibraryEditor( wxCommandEvent& event );
+ void OnRescueProject( wxCommandEvent& event );
+ void OnPreferencesOptions( wxCommandEvent& event );
+ void OnCancelCurrentCommand( wxCommandEvent& aEvent );
+
+ void OnSelectItem( wxCommandEvent& aEvent );
+
+ /**
+ * Function OnCopySchematicItemRequest
+ * is the command event handler for duplicating the item at the current location.
+ */
+ void OnCopySchematicItemRequest( wxCommandEvent& event );
+
+ /* User interface update event handlers. */
+ void OnUpdateBlockSelected( wxUpdateUIEvent& event );
+ void OnUpdatePaste( wxUpdateUIEvent& event );
+ void OnUpdateHiddenPins( wxUpdateUIEvent& event );
+ void OnUpdateBusOrientation( wxUpdateUIEvent& event );
+ void OnUpdateSelectTool( wxUpdateUIEvent& aEvent );
+ void OnUpdateSave( wxUpdateUIEvent& aEvent );
+ void OnUpdateSaveSheet( wxUpdateUIEvent& aEvent );
+ void OnUpdateHierarchySheet( wxUpdateUIEvent& aEvent );
+
+ /**
+ * Function UpdateTitle
+ * sets the main window title bar text.
+ * <p>
+ * If file name defined by SCH_SCREEN::m_FileName is not set, the title is set to the
+ * application name appended with no file.
+ * Otherwise, the title is set to the hierarchical sheet path and the full file name,
+ * and read only is appended to the title if the user does not have write
+ * access to the file.
+ * </p>
+ */
+ void UpdateTitle();
+
+ // Bus Entry
+ SCH_BUS_WIRE_ENTRY* CreateBusWireEntry();
+ SCH_BUS_BUS_ENTRY* CreateBusBusEntry();
+ void SetBusEntryShape( wxDC* DC, SCH_BUS_ENTRY_BASE* BusEntry, char entry_shape );
+
+ /**
+ * Function AddNoConnect
+ * add a no connect item to the current schematic sheet at \a aPosition.
+ * @param aDC The device context to draw the no connect to.
+ * @param aPosition The position in logical (drawing) units to add the no connect.
+ * @return The no connect item added.
+ */
+ SCH_NO_CONNECT* AddNoConnect( wxDC* aDC, const wxPoint& aPosition );
+
+ /**
+ * Function AddJunction
+ * adds a new junction at \a aPosition.
+ */
+ SCH_JUNCTION* AddJunction( wxDC* aDC, const wxPoint& aPosition, bool aPutInUndoList = false );
+
+ /**
+ * Function PrepareMoveItem
+ * start moving \a aItem using the mouse.
+ *
+ * @param aItem A pointer to an SCH_ITEM to move.
+ * @param aDC The device context to draw \a aItem.
+ */
+ void PrepareMoveItem( SCH_ITEM* aItem, wxDC* aDC );
+
+ // Text, label, glabel
+ SCH_TEXT* CreateNewText( wxDC* aDC, int aType );
+ void EditSchematicText( SCH_TEXT* TextStruct );
+ void ChangeTextOrient( SCH_TEXT* aTextItem, wxDC* aDC );
+
+ /**
+ * Function OnCovertTextType
+ * is a command event handler to change a text type to an other one. The new text,
+ * label, hierarchical label, or global label is created from the old text and the
+ * old text is deleted.
+ */
+ void OnConvertTextType( wxCommandEvent& aEvent );
+
+ /**
+ * Function BeginSegment
+ * creates a new segment ( WIRE, BUS ) or terminates the current segment in progress.
+ *
+ * If the end of the current segment is on an other segment, place a junction if needed
+ * and terminates the command. If the end of the current segment is on a pin, terminate
+ * the command. In all other cases starts a new segment.
+ */
+ void BeginSegment( wxDC* DC, int type );
+
+ /**
+ * Function EndSegment
+ * called to terminate a bus, wire, or line creation
+ */
+ void EndSegment( wxDC* DC );
+
+ /**
+ * Function DeleteCurrentSegment
+ * erases the last segment at the current mouse position.
+ */
+ void DeleteCurrentSegment( wxDC* DC );
+ void DeleteConnection( bool DeleteFullConnection );
+
+ // graphic lines
+ void Edge( DRAWSEGMENT* Segment, wxDC* DC );
+ void SetNewWidth( DRAWSEGMENT* DrawSegm, wxDC* DC );
+ void Layer( DRAWSEGMENT* Segment, wxDC* DC );
+ DRAWSEGMENT* Begin_Edge( DRAWSEGMENT* Segment, wxDC* DC );
+
+ // Images:
+ SCH_BITMAP* CreateNewImage( wxDC* aDC );
+ void MoveImage( SCH_BITMAP* aItem, wxDC* aDC );
+ void RotateImage( SCH_BITMAP* aItem );
+ /**
+ * Function MirrorImage
+ * Mirror a bitmap
+ * @param aItem = the SCH_BITMAP item to mirror
+ * @param Is_X_axis = true to mirror relative to Horizontal axis
+ * false to mirror relative to vertical axis
+ */
+ void MirrorImage( SCH_BITMAP* aItem, bool Is_X_axis );
+ void EditImage( SCH_BITMAP* aItem );
+
+ // Hierarchical Sheet & PinSheet
+ void InstallHierarchyFrame( wxPoint& pos );
+ SCH_SHEET* CreateSheet( wxDC* DC );
+ void ReSizeSheet( SCH_SHEET* Sheet, wxDC* DC );
+
+ /**
+ * Rotate a sheet on itself. Sheets do not have a anchor point.
+ * Because rotating it from its origin or its end is not friendly,
+ * Rotation is made around its centre
+ * @param aSheet the hierarchical sheet to rotate
+ * @param aRotCCW = true to rotate CCW, false to rotate CW
+ */
+ void RotateHierarchicalSheet( SCH_SHEET* aSheet, bool aRotCCW );
+
+ /**
+ * Function MirrorSheet
+ * Mirror a hierarchical sheet
+ * Mirroring is made around its centre
+ * @param aSheet = the SCH_SHEET to mirror
+ * @param aFromXaxis = true to mirror relative to Horizontal axis
+ * false to mirror relative to vertical axis
+ */
+ void MirrorSheet( SCH_SHEET* aSheet, bool aFromXaxis );
+
+ /// Loads the cache library associated to the aFileName
+ bool LoadCacheLibrary( const wxString& aFileName );
+
+public:
+ /**
+ * Function EditSheet
+ * is used to edit an existing sheet or add a new sheet to the schematic.
+ * <p>
+ * When \a aSheet is a new sheet:
+ * <ul>
+ * <li>and the file name already exists in the schematic hierarchy, the screen associated
+ * with the sheet found in the hierarchy is associated with \a aSheet.</li>
+ * <li>and the file name already exists on the system, then \a aSheet is loaded with the
+ * existing file.</li>
+ * <li>and the file name does not exist in the schematic hierarchy or on the file system,
+ * then a new screen is created and associated with \a aSheet.</li>
+ * </ul> </p> <p>
+ * When \a aSheet is an existing sheet:
+ * <ul>
+ * <li>and the file name already exists in the schematic hierarchy, the current associated
+ * screen is replace by the one found in the hierarchy.</li>
+ * <li>and the file name already exists on the system, the current associated screen file
+ * name is changed and the file is loaded.</li>
+ * <li>and the file name does not exist in the schematic hierarchy or on the file system,
+ * the current associated screen file name is changed and saved to disk.</li>
+ * </ul> </p>
+ *
+ * Note: the screen is not refresh. The caller is responsible to do that
+ */
+ bool EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy );
+
+ wxPoint GetLastSheetPinPosition() const { return m_lastSheetPinPosition; }
+
+private:
+ /**
+ * Function CreateSheetPin
+ * creates a new SCH_SHEET_PIN object and add it to \a aSheet at the current cursor position.
+ * @param aSheet The sheet to add the new sheet pin to.
+ * @param aDC The device context to draw on.
+ * @return The new sheet pin object created or NULL if the task was aborted by the user.
+ */
+ SCH_SHEET_PIN* CreateSheetPin( SCH_SHEET* aSheet, wxDC* aDC );
+
+ /**
+ * Function EditSheetPin
+ * displays the dialog for editing the parameters of \a aSheetPin.
+ * @param aSheetPin The sheet pin item to edit.
+ * @param aRedraw = true to refresh the screen
+ * @return The user response from the edit dialog.
+ */
+ int EditSheetPin( SCH_SHEET_PIN* aSheetPin, bool aRedraw );
+
+ /**
+ * Function ImportSheetPin
+ * automatically creates a sheet pin from the hierarchical labels in the schematic
+ * referenced by \a aSheet.
+ * @param aSheet The sheet to import the new sheet pin to.
+ * @param aDC The device context to draw on.
+ * @return The new sheet pin object importd or NULL if the task was aborted by the user.
+ */
+ SCH_SHEET_PIN* ImportSheetPin( SCH_SHEET* aSheet, wxDC* aDC );
+
+public:
+ /**
+ * Function DeleteItem
+ * removes \a aItem from the current screen and saves it in the undo list.
+ * @param aItem The item to remove from the current screen.
+ */
+ void DeleteItem( SCH_ITEM* aItem );
+
+ int GetLabelIncrement() const { return m_repeatLabelDelta; }
+
+private:
+
+ /**
+ * Function Load_Component
+ * loads from a library and places a component.
+ * if libname != "", search in lib "libname"
+ * else search in all loaded libs
+ *
+ * @param aDC is the device context to draw upon.
+ * @param aFilters is a filter to pass the allowed lib names list, or library name
+ * to load the component from and/or some other filters
+ * if NULL, no filtering.
+ * @param aHistoryList list remembering recently used component names.
+ * @param aHistoryLastUnit remembering last unit in last component.
+ * @param aUseLibBrowser is the flag to determine if the library browser should be launched.
+ * @return a pointer the SCH_COMPONENT object selected or NULL if no component was selected.
+ * (TODO(hzeller): This really should be a class doing history, but didn't
+ * want to change too much while other refactoring is going on)
+ */
+ SCH_COMPONENT* Load_Component( wxDC* aDC,
+ const SCHLIB_FILTER* aFilter,
+ wxArrayString& aHistoryList,
+ int& aHistoryLastUnit,
+ bool aUseLibBrowser );
+
+ /**
+ * Function EditComponent
+ * displays the edit component dialog to edit the parameters of \a aComponent.
+ *
+ * @param aComponent is a pointer to the SCH_COMPONENT object to be edited.
+ */
+ void EditComponent( SCH_COMPONENT* aComponent );
+
+public:
+
+ /**
+ * Function OrientComponent
+ * rotates and mirrors a component.
+ */
+ void OrientComponent( COMPONENT_ORIENTATION_T aOrientation = CMP_NORMAL );
+
+private:
+ void OnSelectUnit( wxCommandEvent& aEvent );
+ void ConvertPart( SCH_COMPONENT* DrawComponent, wxDC* DC );
+ void SetInitCmp( SCH_COMPONENT* DrawComponent, wxDC* DC );
+
+ /**
+ * Function EditComponentFieldText
+ * displays the edit field dialog to edit the parameters of \a aField.
+ *
+ * @param aField is a pointer to the SCH_FIELD object to be edited.
+ */
+ void EditComponentFieldText( SCH_FIELD* aField );
+
+ void RotateField( SCH_FIELD* aField, wxDC* aDC );
+
+ /**
+ * Function PastListOfItems
+ * pastes a list of items from the block stack.
+ */
+ void PasteListOfItems( wxDC* DC );
+
+ /* Undo - redo */
+public:
+
+ /**
+ * Function SaveCopyInUndoList.
+ * Create a copy of the current schematic item, and put it in the undo list.
+ *
+ * flag_type_command =
+ * UR_CHANGED
+ * UR_NEW
+ * UR_DELETED
+ * UR_WIRE_IMAGE
+ * UR_MOVED
+ *
+ * If it is a delete command, items are put on list with the .Flags member
+ * set to UR_DELETED. When it will be really deleted, the GetDrawItems() and the
+ * sub-hierarchy will be deleted. If it is only a copy, the GetDrawItems() and the
+ * sub-hierarchy must NOT be deleted.
+ *
+ * @note
+ * Edit wires and buses is a bit complex.
+ * because when a new wire is added, a lot of modifications in wire list is made
+ * (wire concatenation): modified items, deleted items and new items
+ * so flag_type_command is UR_WIRE_IMAGE: the struct ItemToCopy is a list of
+ * wires saved in Undo List (for Undo or Redo commands, saved wires will be
+ * exchanged with current wire list
+ * @param aItemToCopy = the schematic item modified by the command to undo
+ * @param aTypeCommand = command type (see enum UNDO_REDO_T)
+ * @param aTransformPoint = the reference point of the transformation,
+ * for commands like move
+ */
+ void SaveCopyInUndoList( SCH_ITEM* aItemToCopy,
+ UNDO_REDO_T aTypeCommand,
+ const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
+
+ /**
+ * Function SaveCopyInUndoList (overloaded).
+ * Creates a new entry in undo list of commands.
+ * add a list of pickers to handle a list of items
+ * @param aItemsList = the list of items modified by the command to undo
+ * @param aTypeCommand = command type (see enum UNDO_REDO_T)
+ * @param aTransformPoint = the reference point of the transformation,
+ * for commands like move
+ */
+ void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
+ UNDO_REDO_T aTypeCommand,
+ const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
+
+private:
+
+ /**
+ * Function PutDataInPreviousState
+ * is used in undo or redo command to put data pointed by List in the previous state, i.e.
+ * the state stored in \a aList
+ * @param aList a PICKED_ITEMS_LIST pointer to the list of items to undo/redo
+ * @param aRedoCommand a bool: true for redo, false for undo
+ */
+ void PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRedoCommand );
+
+ /**
+ * Function GetSchematicFromRedoList
+ * Redo the last edition:
+ * - Save the current schematic in Undo list
+ * - Get an old version of the schematic from Redo list
+ * @return none
+ */
+ void GetSchematicFromRedoList( wxCommandEvent& event );
+
+ /**
+ * Function GetSchematicFromUndoList
+ * performs an undo the last edition:
+ * - Save the current schematic in Redo list
+ * - Get an old version of the schematic from Undo list
+ */
+ void GetSchematicFromUndoList( wxCommandEvent& event );
+
+ /**
+ * Function copyBlockItems
+ * copies the list of block item.
+ * @sa m_blockItems
+ * @param aItemsList List to copy the block select items into.
+ */
+ void copyBlockItems( PICKED_ITEMS_LIST& aItemsList );
+
+ /**
+ * Function addJunctionMenuEntries
+ * adds the context menu items to \a aMenu for \a aJunction.
+ * @param aMenu The menu to add the items to.
+ * @param aJunction The SCH_JUNCTION object selected.
+ */
+ void addJunctionMenuEntries( wxMenu* aMenu, SCH_JUNCTION* aJunction );
+
+public:
+ void Key( wxDC* DC, int hotkey, EDA_ITEM* DrawStruct );
+
+ /**
+ * Function InitBlockPasteInfos
+ * initializes the parameters used by the block paste command.
+ */
+ void InitBlockPasteInfos();
+
+ /**
+ * Function BlockCommand
+ * Returns the block command internat code (BLOCK_MOVE, BLOCK_COPY...)
+ * corresponding to the keys pressed (ALT, SHIFT, SHIFT ALT ..) when
+ * block command is started by dragging the mouse.
+ * @param aKey = the key modifiers (Alt, Shift ...)
+ * @return the block command id (BLOCK_MOVE, BLOCK_COPY...)
+ */
+ virtual int BlockCommand( int aKey );
+
+ /**
+ * Function HandleBlockPlace
+ * Called after HandleBlockEnd, when a block command needs to be
+ * executed after the block is moved to its new place
+ * (bloc move, drag, copy .. )
+ * Parameters must be initialized in GetScreen()->m_BlockLocate
+ */
+ virtual void HandleBlockPlace( wxDC* DC );
+
+ /**
+ * Function HandleBlockEnd
+ * Handle the "end" of a block command,
+ * i.e. is called at the end of the definition of the area of a block.
+ * depending on the current block command, this command is executed
+ * or parameters are initialized to prepare a call to HandleBlockPlace
+ * in GetScreen()->m_BlockLocate
+ *
+ * @param aDC is a device context to draw on.
+ * @return false if no item selected, or command finished,
+ * true if some items found and HandleBlockPlace must be called later
+ */
+ virtual bool HandleBlockEnd( wxDC* aDC );
+
+ /**
+ * Function RepeatDrawItem
+ * repeats the last item placement if the last item was a bus, bus entry,
+ * label, or component.
+ *
+ * Labels that end with a number will be incremented.
+ */
+ void RepeatDrawItem( wxDC* DC );
+
+ /**
+ * Function SetRepeatItem
+ * clones aItem and owns that clone in this container.
+ */
+ void SetRepeatItem( SCH_ITEM* aItem );
+
+ /**
+ * Function GetRepeatItem
+ * returns the item which is to be repeated with the insert key. Such object
+ * is owned by this container, and must be cloned.
+ */
+ SCH_ITEM* GetRepeatItem() const { return m_item_to_repeat; }
+
+ /**
+ * Function SetUndoItem
+ * clones \a aItem which can be used to restore the state of the item being edited
+ * when the user cancels the editing in progress.
+ *
+ * @param aItem The item to make a clone of for undoing the last change. Set to
+ * NULL to free the current undo item.
+ */
+ void SetUndoItem( const SCH_ITEM* aItem );
+
+ SCH_ITEM* GetUndoItem() const { return m_undoItem; }
+
+ /**
+ * Function SaveUndoItemInUndoList
+ * swaps the cloned item in member variable m_undoItem with \a aItem and saves it to
+ * the undo list then swap the data back. This swaps the internal structure of the
+ * item with the cloned item. It does not swap the actual item pointers themselves.
+ *
+ * @param aItem The item to swap with the current undo item.
+ */
+ void SaveUndoItemInUndoList( SCH_ITEM* aItem );
+
+ /**
+ * Function CreateArchiveLibraryCacheFile
+ * creates a library file with the name of the root document plus the '-cache' suffix,
+ * That file will contain all components used in the current schematic.
+ *
+ * @param aUseCurrentSheetFilename = false to use the root shhet filename
+ * (default) or true to use the currently opened sheet.
+ * @return true if the file was written successfully.
+ */
+ bool CreateArchiveLibraryCacheFile( bool aUseCurrentSheetFilename = false );
+
+ /**
+ * Function CreateArchiveLibrary
+ * creates a library \a aFileName that contains all components used in the current schematic.
+ *
+ * @param aFileName The full path and file name of the archive library.
+ * @return True if \a aFileName was written successfully.
+ */
+ bool CreateArchiveLibrary( const wxString& aFileName );
+
+ /**
+ * Function RescueProject
+ * performs rescue operations to recover old projects from before certain
+ * changes were made.
+ *
+ * - Exports cached symbols that conflict with new symbols to a separate
+ * library
+ * - Renames symbols named before libraries were case sensitive
+ *
+ * @param aRunningOnDemand - indicates whether the tool has been called up by the user
+ * (as opposed to being run automatically). If true, an information dialog is
+ * displayed if there are no components to rescue. If false, the tool is silent
+ * if there are no components to rescue, and a "Never Show Again" button is
+ * displayed.
+ */
+ bool RescueProject( bool aRunningOnDemand );
+
+ /**
+ * Function PrintPage
+ * plots or prints the current sheet to the clipboard.
+ * @param aDC = wxDC given by the calling print function
+ * @param aPrintMask = not used here
+ * @param aPrintMirrorMode = not used here (Set when printing in mirror mode)
+ * @param aData = a pointer on an auxiliary data (not always used, NULL if not used)
+ */
+ virtual void PrintPage( wxDC* aDC, LSET aPrintMask,
+ bool aPrintMirrorMode, void* aData = NULL );
+
+ void SetSimulatorCommand( const wxString& aCommand ) { m_simulatorCommand = aCommand; }
+
+ wxString GetSimulatorCommand() const { return m_simulatorCommand; }
+
+ void SetNetListerCommand( const wxString& aCommand ) { m_netListerCommand = aCommand; }
+
+ wxString GetNetListerCommand() const { return m_netListerCommand; }
+
+ DECLARE_EVENT_TABLE()
+};
+
+
+#endif // WX_EESCHEMA_STRUCT_H
diff --git a/eeschema/selpart.cpp b/eeschema/selpart.cpp
new file mode 100644
index 0000000..b0b3629
--- /dev/null
+++ b/eeschema/selpart.cpp
@@ -0,0 +1,163 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file selpart.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <confirm.h>
+#include <pgm_base.h>
+#include <sch_base_frame.h>
+
+#include <general.h>
+#include <class_library.h>
+#include <dialog_helpers.h>
+
+// Used in DisplayListComponentsInLib: this is a callback function for EDA_LIST_DIALOG
+// to display keywords and description of a component
+static void DisplayCmpDocAndKeywords( wxString& aName, void* aData )
+{
+ PART_LIBS* libs = (PART_LIBS*) aData;
+
+ wxASSERT( libs );
+
+ LIB_ALIAS* part = libs->FindLibraryEntry( aName );
+
+ if( !part )
+ return;
+
+ aName = wxT( "Description: " ) + part->GetDescription();
+ aName += wxT( "\nKey Words: " ) + part->GetKeyWords();
+}
+
+
+PART_LIB* SCH_BASE_FRAME::SelectLibraryFromList()
+{
+ PROJECT& prj = Prj();
+
+ if( PART_LIBS* libs = prj.SchLibs() )
+ {
+ if( !libs->GetLibraryCount() )
+ {
+ DisplayError( this, _( "No component libraries are loaded." ) );
+ return NULL;
+ }
+
+ wxArrayString headers;
+
+ headers.Add( wxT( "Library" ) );
+
+ wxArrayString libNamesList = libs->GetLibraryNames();
+
+ std::vector<wxArrayString> itemsToDisplay;
+
+ // Conversion from wxArrayString to vector of ArrayString
+ for( unsigned i = 0; i < libNamesList.GetCount(); i++ )
+ {
+ wxArrayString item;
+
+ item.Add( libNamesList[i] );
+
+ itemsToDisplay.push_back( item );
+ }
+
+ wxString old_lib_name = prj.GetRString( PROJECT::SCH_LIB_SELECT );
+
+ EDA_LIST_DIALOG dlg( this, _( "Select Library" ), headers, itemsToDisplay, old_lib_name );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return NULL;
+
+ wxString libname = dlg.GetTextSelection();
+
+ if( !libname )
+ return NULL;
+
+ PART_LIB* lib = libs->FindLibrary( libname );
+
+ if( lib )
+ prj.SetRString( PROJECT::SCH_LIB_SELECT, libname );
+
+ return lib;
+ }
+
+ return NULL;
+}
+
+
+
+bool SCH_BASE_FRAME::DisplayListComponentsInLib( PART_LIB* aLibrary,
+ wxString& aBuffer, wxString& aPreviousChoice )
+{
+ wxArrayString nameList;
+
+ if( aLibrary == NULL )
+ aLibrary = SelectLibraryFromList();
+
+ if( aLibrary == NULL )
+ return false;
+
+ aLibrary->GetEntryNames( nameList );
+
+ wxArrayString headers;
+ headers.Add( wxT("Component") );
+ headers.Add( wxT("Library") );
+ std::vector<wxArrayString> itemsToDisplay;
+
+ // Conversion from wxArrayString to vector of ArrayString
+ for( unsigned i = 0; i < nameList.GetCount(); i++ )
+ {
+ wxArrayString item;
+ item.Add( nameList[i] );
+ item.Add( aLibrary->GetLogicalName() );
+ itemsToDisplay.push_back( item );
+ }
+
+ EDA_LIST_DIALOG dlg( this, _( "Select Component" ), headers, itemsToDisplay,
+ aPreviousChoice, DisplayCmpDocAndKeywords, Prj().SchLibs() );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return false;
+
+ aBuffer = dlg.GetTextSelection();
+
+ return true;
+}
+
+
+bool SCH_BASE_FRAME::SelectPartNameToLoad( PART_LIB* aLibrary, wxString& aBufName )
+{
+ int ii;
+ static wxString previousCmpName;
+
+ ii = DisplayListComponentsInLib( aLibrary, aBufName, previousCmpName );
+
+ if( ii <= 0 || aBufName.IsEmpty() )
+ return false;
+
+ previousCmpName = aBufName;
+ return true;
+}
diff --git a/eeschema/sheet.cpp b/eeschema/sheet.cpp
new file mode 100644
index 0000000..95005c6
--- /dev/null
+++ b/eeschema/sheet.cpp
@@ -0,0 +1,452 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sheet.cpp
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <schframe.h>
+#include <base_units.h>
+#include <kiface_i.h>
+
+#include <sch_sheet.h>
+#include <sch_sheet_path.h>
+
+#include <dialogs/dialog_sch_sheet_props.h>
+#include <wildcards_and_files_ext.h>
+#include <project.h>
+
+
+bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy )
+{
+ if( aSheet == NULL || aHierarchy == NULL )
+ return false;
+
+ SCH_SHEET_LIST hierarchy; // This is the schematic sheet hierarchy.
+
+ // Get the new texts
+ DIALOG_SCH_SHEET_PROPS dlg( this );
+
+ wxString units = GetUnitsLabel( g_UserUnit );
+ dlg.SetFileName( aSheet->GetFileName() );
+ dlg.SetFileNameTextSize( StringFromValue( g_UserUnit, aSheet->GetFileNameSize() ) );
+ dlg.SetFileNameTextSizeUnits( units );
+ dlg.SetSheetName( aSheet->GetName() );
+ dlg.SetSheetNameTextSize( StringFromValue( g_UserUnit, aSheet->GetSheetNameSize() ) );
+ dlg.SetSheetNameTextSizeUnits( units );
+ dlg.SetSheetTimeStamp( wxString::Format( wxT("%8.8lX"),
+ (unsigned long) aSheet->GetTimeStamp() ) );
+
+ /* This ugly hack fixes a bug in wxWidgets 2.8.7 and likely earlier
+ * versions for the flex grid sizer in wxGTK that prevents the last
+ * column from being sized correctly. It doesn't cause any problems
+ * on win32 so it doesn't need to wrapped in ugly #ifdef __WXGTK__
+ * #endif.
+ * Still presen in wxWidgets 3.0.2
+ */
+ dlg.Layout();
+ dlg.Fit();
+ dlg.SetMinSize( dlg.GetSize() );
+ dlg.GetSizer()->Fit( &dlg );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return false;
+
+ wxFileName fileName = dlg.GetFileName();
+ fileName.SetExt( SchematicFileExtension );
+
+ if( !fileName.IsOk() )
+ {
+ DisplayError( this, _( "File name is not valid!" ) );
+ return false;
+ }
+
+ // Duplicate sheet names are not valid.
+ const SCH_SHEET* sheet = hierarchy.FindSheetByName( dlg.GetSheetName() );
+
+ if( sheet && (sheet != aSheet) )
+ {
+ DisplayError( this, wxString::Format( _( "A sheet named \"%s\" already exists." ),
+ GetChars( dlg.GetSheetName() ) ) );
+ return false;
+ }
+
+ wxString msg;
+ bool loadFromFile = false;
+ SCH_SCREEN* useScreen = NULL;
+
+ wxString newFilename = fileName.GetFullPath();
+
+ // Search for a schematic file having the same filename
+ // already in use in the hierarchy or on disk, in order to reuse it.
+ if( !g_RootSheet->SearchHierarchy( newFilename, &useScreen ) )
+ {
+ // if user entered a relative path, allow that to stay, but do the
+ // file existence test with an absolute (full) path. This transformation
+ // is local to this scope, but is the same one used at load time later.
+ wxString absolute = Prj().AbsolutePath( newFilename );
+
+ loadFromFile = wxFileExists( absolute );
+ }
+
+ // Inside Eeschema, filenames are stored using unix notation
+ newFilename.Replace( wxT( "\\" ), wxT( "/" ) );
+
+ if( aSheet->GetScreen() == NULL ) // New sheet.
+ {
+ if( useScreen || loadFromFile ) // Load from existing file.
+ {
+ if( useScreen != NULL )
+ {
+ msg.Printf( _( "A file named '%s' already exists in the current schematic "
+ "hierarchy." ), GetChars( newFilename ) );
+ }
+ else
+ {
+ msg.Printf( _( "A file named '%s' already exists." ), GetChars( newFilename ) );
+ }
+
+ msg += _( "\n\nDo you want to create a sheet with the contents of this file?" );
+
+ if( !IsOK( this, msg ) )
+ {
+ return false;
+ }
+ }
+ else // New file.
+ {
+ aSheet->SetScreen( new SCH_SCREEN( &Kiway() ) );
+ aSheet->GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
+ aSheet->GetScreen()->SetFileName( newFilename );
+ }
+ }
+ else // Existing sheet.
+ {
+ bool isUndoable = true;
+ bool renameFile = false;
+
+ // We are always using here a case insensitive comparison
+ // to avoid issues under Windows, although under Unix
+ // filenames are case sensitive.
+ // But many users create schematic under both Unix and Windows
+ if( newFilename.CmpNoCase( aSheet->GetFileName() ) != 0 )
+ {
+ // Sheet file name changes cannot be undone.
+ isUndoable = false;
+ msg = _( "Changing the sheet file name cannot be undone. " );
+
+ if( useScreen || loadFromFile ) // Load from existing file.
+ {
+ wxString tmp;
+
+ if( useScreen != NULL )
+ {
+ tmp.Printf( _( "A file named <%s> already exists in the current schematic "
+ "hierarchy." ), GetChars( newFilename ) );
+ }
+ else
+ {
+ tmp.Printf( _( "A file named <%s> already exists." ),
+ GetChars( newFilename ) );
+ }
+
+ msg += tmp;
+ msg += _( "\n\nDo you want to replace the sheet with the contents of this file?" );
+
+ if( !IsOK( this, msg ) )
+ return false;
+
+ if( loadFromFile )
+ aSheet->SetScreen( NULL );
+ }
+ else // Save to new file name.
+ {
+ if( aSheet->GetScreenCount() > 1 )
+ {
+ msg += _( "This sheet uses shared data in a complex hierarchy.\n\n" );
+ msg += _( "Do you wish to convert it to a simple hierarchical sheet?" );
+
+ if( !IsOK( NULL, msg ) )
+ return false;
+ }
+
+ renameFile = true;
+ }
+ }
+
+ m_canvas->SetIgnoreMouseEvents( true );
+
+ if( isUndoable )
+ SaveCopyInUndoList( aSheet, UR_CHANGED );
+
+ if( renameFile )
+ {
+ aSheet->GetScreen()->SetFileName( newFilename );
+ SaveEEFile( aSheet->GetScreen() );
+
+ // If the the associated screen is shared by more than one sheet, remove the
+ // screen and reload the file to a new screen. Failure to do this will trash
+ // the screen reference counting in complex hierarchies.
+ if( aSheet->GetScreenCount() > 1 )
+ {
+ aSheet->SetScreen( NULL );
+ loadFromFile = true;
+ }
+ }
+ }
+
+ aSheet->SetFileName( newFilename );
+
+ if( useScreen )
+ aSheet->SetScreen( useScreen );
+ else if( loadFromFile )
+ aSheet->Load( this );
+
+ aSheet->SetFileNameSize( ValueFromString( g_UserUnit, dlg.GetFileNameTextSize() ) );
+ aSheet->SetName( dlg.GetSheetName() );
+ aSheet->SetSheetNameSize( ValueFromString( g_UserUnit, dlg.GetSheetNameTextSize() ) );
+
+ if( aSheet->GetName().IsEmpty() )
+ aSheet->SetName( wxString::Format( wxT( "Sheet%8.8lX" ),
+ (long unsigned) aSheet->GetTimeStamp() ) );
+
+ // Make sure the sheet changes do not cause any recursion.
+ SCH_SHEET_LIST sheetHierarchy( aSheet );
+
+ // Make sure files have fully qualified path and file name.
+ wxFileName destFn = aHierarchy->Last()->GetFileName();
+
+ if( destFn.IsRelative() )
+ destFn.MakeAbsolute( Prj().GetProjectPath() );
+
+ if( hierarchy.TestForRecursion( sheetHierarchy, destFn.GetFullPath( wxPATH_UNIX ) ) )
+ {
+ msg.Printf( _( "The sheet changes cannot be made because the destination sheet already "
+ "has the sheet <%s> or one of it's subsheets as a parent somewhere in "
+ "the schematic hierarchy." ),
+ GetChars( newFilename ) );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+ OnModify();
+
+ return true;
+}
+
+
+/* Move selected sheet with the cursor.
+ * Callback function used by m_mouseCaptureCallback.
+ * Note also now this function is aclled only when resizing the sheet
+ * But the (very small code) relative to sheet move is still present here
+ */
+static void resizeSheetWithMouseCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ BASE_SCREEN* screen = aPanel->GetScreen();
+ SCH_SHEET* sheet = (SCH_SHEET*) screen->GetCurItem();
+
+ if( aErase )
+ sheet->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
+
+ wxPoint pos = sheet->GetPosition();
+
+ int width = aPanel->GetParent()->GetCrossHairPosition().x - sheet->GetPosition().x;
+ int height = aPanel->GetParent()->GetCrossHairPosition().y - sheet->GetPosition().y;
+
+ // If the sheet doesn't have any pins, clamp the minimum size to the default values.
+ width = ( width < MIN_SHEET_WIDTH ) ? MIN_SHEET_WIDTH : width;
+ height = ( height < MIN_SHEET_HEIGHT ) ? MIN_SHEET_HEIGHT : height;
+
+ if( sheet->HasPins() )
+ {
+ int gridSizeX = KiROUND( screen->GetGridSize().x );
+ int gridSizeY = KiROUND( screen->GetGridSize().y );
+
+ // If the sheet has pins, use the pin positions to clamp the minimum height.
+ height = ( height < sheet->GetMinHeight() + gridSizeY ) ?
+ sheet->GetMinHeight() + gridSizeY : height;
+ width = ( width < sheet->GetMinWidth() + gridSizeX ) ?
+ sheet->GetMinWidth() + gridSizeX : width;
+ }
+
+ wxPoint grid = aPanel->GetParent()->GetNearestGridPosition(
+ wxPoint( pos.x + width, pos.y + height ) );
+ sheet->Resize( wxSize( grid.x - pos.x, grid.y - pos.y ) );
+
+ sheet->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
+}
+
+
+// Complete sheet move.
+static void ExitSheet( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
+{
+ SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+
+ SCH_EDIT_FRAME* parent = (SCH_EDIT_FRAME*) aPanel->GetParent();
+
+ if( (item == NULL) || (item->Type() != SCH_SHEET_T) || (parent == NULL) )
+ return;
+
+ parent->SetRepeatItem( NULL );
+
+ item->Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
+
+ if( item->IsNew() )
+ {
+ delete item;
+ }
+ else if( item->IsMoving() || item->IsResized() )
+ {
+ screen->Remove( item );
+ delete item;
+
+ item = parent->GetUndoItem();
+
+ wxCHECK_RET( item != NULL, wxT( "Cannot restore undefined last sheet item." ) );
+
+ screen->Append( item );
+ // the owner of item is no more parent, this is the draw list of screen:
+ parent->SetUndoItem( NULL );
+
+ item->Draw( aPanel, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+ item->ClearFlags();
+ }
+ else
+ {
+ item->ClearFlags();
+ }
+
+ screen->SetCurItem( NULL );
+}
+
+
+// Create hierarchy sheet.
+SCH_SHEET* SCH_EDIT_FRAME::CreateSheet( wxDC* aDC )
+{
+ SetRepeatItem( NULL );
+
+ SCH_SHEET* sheet = new SCH_SHEET( GetCrossHairPosition() );
+
+ sheet->SetFlags( IS_NEW | IS_RESIZED );
+ sheet->SetTimeStamp( GetNewTimeStamp() );
+ sheet->SetParent( GetScreen() );
+ sheet->SetScreen( NULL );
+
+ // need to check if this is being added to the GetDrawItems().
+ // also need to update the hierarchy, if we are adding
+ // a sheet to a screen that already has multiple instances (!)
+ GetScreen()->SetCurItem( sheet );
+ m_canvas->SetMouseCapture( resizeSheetWithMouseCursor, ExitSheet );
+ m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
+ m_canvas->CrossHairOff( aDC );
+
+ SetCrossHairPosition( sheet->GetResizePosition() );
+
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->CrossHairOn( aDC );
+
+ return sheet;
+}
+
+
+void SCH_EDIT_FRAME::ReSizeSheet( SCH_SHEET* aSheet, wxDC* aDC )
+{
+ if( aSheet == NULL || aSheet->IsNew() )
+ return;
+
+ wxCHECK_RET( aSheet->Type() == SCH_SHEET_T,
+ wxString::Format( wxT( "Cannot perform sheet resize on %s object." ),
+ GetChars( aSheet->GetClass() ) ) );
+
+ m_canvas->CrossHairOff( aDC );
+ SetCrossHairPosition( aSheet->GetResizePosition() );
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->CrossHairOn( aDC );
+
+ SetUndoItem( aSheet );
+ aSheet->SetFlags( IS_RESIZED );
+
+ m_canvas->SetMouseCapture( resizeSheetWithMouseCursor, ExitSheet );
+ m_canvas->CallMouseCapture( aDC, wxDefaultPosition, true );
+
+ if( aSheet->IsNew() ) // not already in edit, save a copy for undo/redo
+ SetUndoItem( aSheet );
+}
+
+
+void SCH_EDIT_FRAME::RotateHierarchicalSheet( SCH_SHEET* aSheet, bool aRotCCW )
+{
+ if( aSheet == NULL )
+ return;
+
+ // Save old sheet in undo list if not already in edit, or moving.
+ if( aSheet->GetFlags() == 0 )
+ SaveCopyInUndoList( aSheet, UR_CHANGED );
+
+ // Rotate the sheet on itself. Sheets do not have a anchor point.
+ // Rotation is made around it center
+ wxPoint rotPoint = aSheet->GetBoundingBox().Centre();
+
+ // rotate CCW, or CW. to rotate CW, rotate 3 times
+ aSheet->Rotate( rotPoint );
+
+ if( !aRotCCW )
+ {
+ aSheet->Rotate( rotPoint );
+ aSheet->Rotate( rotPoint );
+ }
+
+ GetCanvas()->Refresh();
+ OnModify();
+}
+
+
+void SCH_EDIT_FRAME::MirrorSheet( SCH_SHEET* aSheet, bool aFromXaxis )
+{
+ if( aSheet == NULL )
+ return;
+
+ // Save old sheet in undo list if not already in edit, or moving.
+ if( aSheet->GetFlags() == 0 )
+ SaveCopyInUndoList( aSheet, UR_CHANGED );
+
+ // Mirror the sheet on itself. Sheets do not have a anchor point.
+ // Mirroring is made around it center
+ wxPoint mirrorPoint = aSheet->GetBoundingBox().Centre();
+
+ if( aFromXaxis ) // mirror relative to Horizontal axis
+ aSheet->MirrorX( mirrorPoint.y );
+ else // Mirror relative to vertical axis
+ aSheet->MirrorY( mirrorPoint.x );
+
+ GetCanvas()->Refresh();
+ OnModify();
+}
diff --git a/eeschema/sheetlab.cpp b/eeschema/sheetlab.cpp
new file mode 100644
index 0000000..aeca483
--- /dev/null
+++ b/eeschema/sheetlab.cpp
@@ -0,0 +1,179 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file sheetlab.cpp
+ * @brief Create and edit the SCH_SHEET_PIN items.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <schframe.h>
+#include <base_units.h>
+
+#include <general.h>
+#include <sch_sheet.h>
+#include <dialog_helpers.h>
+
+#include <dialogs/dialog_sch_edit_sheet_pin.h>
+
+
+int SCH_EDIT_FRAME::m_lastSheetPinType = NET_INPUT;
+wxSize SCH_EDIT_FRAME::m_lastSheetPinTextSize( -1, -1 );
+wxPoint SCH_EDIT_FRAME::m_lastSheetPinPosition;
+
+const wxSize &SCH_EDIT_FRAME::GetLastSheetPinTextSize()
+{
+ // Delayed initialization (need the preferences to be loaded)
+ if( m_lastSheetPinTextSize.x == -1 )
+ {
+ m_lastSheetPinTextSize.x = GetDefaultTextSize();
+ m_lastSheetPinTextSize.y = GetDefaultTextSize();
+ }
+ return m_lastSheetPinTextSize;
+}
+
+int SCH_EDIT_FRAME::EditSheetPin( SCH_SHEET_PIN* aSheetPin, bool aRedraw )
+{
+ if( aSheetPin == NULL )
+ return wxID_CANCEL;
+
+ DIALOG_SCH_EDIT_SHEET_PIN dlg( this );
+
+ dlg.SetLabelName( aSheetPin->GetText() );
+ dlg.SetTextHeight( StringFromValue( g_UserUnit, aSheetPin->GetSize().y ) );
+ dlg.SetTextHeightUnits( GetUnitsLabel( g_UserUnit ) );
+ dlg.SetTextWidth( StringFromValue( g_UserUnit, aSheetPin->GetSize().x ) );
+ dlg.SetTextWidthUnits( GetUnitsLabel( g_UserUnit ) );
+ dlg.SetConnectionType( aSheetPin->GetShape() );
+
+ /* This ugly hack fixes a bug in wxWidgets 2.8.7 and likely earlier versions for
+ * the flex grid sizer in wxGTK that prevents the last column from being sized
+ * correctly. It doesn't cause any problems on win32 so it doesn't need to wrapped
+ * in ugly #ifdef __WXGTK__ #endif.
+ */
+ dlg.Layout();
+ dlg.Fit();
+ dlg.SetMinSize( dlg.GetSize() );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return wxID_CANCEL;
+
+ if( !aSheetPin->IsNew() )
+ {
+ SaveCopyInUndoList( (SCH_ITEM*) aSheetPin->GetParent(), UR_CHANGED );
+ GetScreen()->SetCurItem( NULL );
+ }
+
+ aSheetPin->SetText( dlg.GetLabelName() );
+ aSheetPin->SetSize( wxSize( ValueFromString( g_UserUnit, dlg.GetTextWidth() ),
+ ValueFromString( g_UserUnit, dlg.GetTextHeight() ) ) );
+ aSheetPin->SetShape( dlg.GetConnectionType() );
+
+ OnModify();
+
+ if( aRedraw )
+ m_canvas->Refresh();
+
+ return wxID_OK;
+}
+
+
+SCH_SHEET_PIN* SCH_EDIT_FRAME::CreateSheetPin( SCH_SHEET* aSheet, wxDC* aDC )
+{
+ wxString line;
+ SCH_SHEET_PIN* sheetPin;
+
+ sheetPin = new SCH_SHEET_PIN( aSheet, wxPoint( 0, 0 ), line );
+ sheetPin->SetFlags( IS_NEW );
+ sheetPin->SetSize( GetLastSheetPinTextSize() );
+ sheetPin->SetShape( m_lastSheetPinType );
+
+ int response = EditSheetPin( sheetPin, false );
+
+ if( sheetPin->GetText().IsEmpty() || (response == wxID_CANCEL) )
+ {
+ delete sheetPin;
+ return NULL;
+ }
+
+ m_lastSheetPinType = sheetPin->GetShape();
+ m_lastSheetPinTextSize = sheetPin->GetSize();
+
+ sheetPin->SetPosition( GetCrossHairPosition() );
+ sheetPin->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode );
+ PrepareMoveItem( (SCH_ITEM*) sheetPin, aDC );
+
+ OnModify();
+ return sheetPin;
+}
+
+
+SCH_SHEET_PIN* SCH_EDIT_FRAME::ImportSheetPin( SCH_SHEET* aSheet, wxDC* aDC )
+{
+ EDA_ITEM* item;
+ SCH_SHEET_PIN* sheetPin;
+ SCH_HIERLABEL* label = NULL;
+
+ if( !aSheet->GetScreen() )
+ return NULL;
+
+ item = aSheet->GetScreen()->GetDrawItems();
+
+ for( ; item != NULL; item = item->Next() )
+ {
+ if( item->Type() != SCH_HIERARCHICAL_LABEL_T )
+ continue;
+
+ label = (SCH_HIERLABEL*) item;
+
+ /* A global label has been found: check if there a corresponding sheet label. */
+ if( !aSheet->HasPin( label->GetText() ) )
+ break;
+
+ label = NULL;
+ }
+
+ if( label == NULL )
+ {
+ DisplayInfoMessage( this, _( "No new hierarchical labels found." ) );
+ return NULL;
+ }
+
+ sheetPin = new SCH_SHEET_PIN( aSheet, wxPoint( 0, 0 ), label->GetText() );
+ sheetPin->SetFlags( IS_NEW );
+ sheetPin->SetSize( GetLastSheetPinTextSize() );
+ m_lastSheetPinType = label->GetShape();
+ sheetPin->SetShape( label->GetShape() );
+ sheetPin->SetPosition( GetCrossHairPosition() );
+
+ sheetPin->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode );
+ PrepareMoveItem( (SCH_ITEM*) sheetPin, aDC );
+
+ return sheetPin;
+}
diff --git a/eeschema/symbdraw.cpp b/eeschema/symbdraw.cpp
new file mode 100644
index 0000000..10b81b8
--- /dev/null
+++ b/eeschema/symbdraw.cpp
@@ -0,0 +1,370 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2006 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2009-2017 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file symbdraw.cpp
+ * @brief Create, move .. graphic shapes used to build and draw a component (lines, arcs ..)
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <class_sch_screen.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+#include <eeschema_id.h>
+#include <general.h>
+#include <libeditframe.h>
+#include <class_libentry.h>
+#include <lib_arc.h>
+#include <lib_circle.h>
+#include <lib_polyline.h>
+#include <lib_rectangle.h>
+#include <lib_text.h>
+
+#include <dialogs/dialog_lib_edit_draw_item.h>
+
+
+static void SymbolDisplayDraw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase );
+static void RedrawWhileMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase );
+
+
+void LIB_EDIT_FRAME::EditGraphicSymbol( wxDC* DC, LIB_ITEM* DrawItem )
+{
+ if( DrawItem == NULL )
+ return;
+
+ LIB_PART* component = DrawItem->GetParent();
+
+ DIALOG_LIB_EDIT_DRAW_ITEM dialog( this, DrawItem->GetTypeName() );
+
+ dialog.SetWidthUnits( ReturnUnitSymbol( g_UserUnit ) );
+
+ wxString val = StringFromValue( g_UserUnit, DrawItem->GetWidth() );
+ dialog.SetWidth( val );
+ dialog.SetApplyToAllUnits( DrawItem->GetUnit() == 0 );
+ dialog.EnableApplyToAllUnits( component && component->GetUnitCount() > 1 );
+ dialog.SetApplyToAllConversions( DrawItem->GetConvert() == 0 );
+ dialog.EnableApplyToAllConversions( component && component->HasConversion() );
+ dialog.SetFillStyle( DrawItem->GetFillMode() );
+ dialog.EnableFillStyle( DrawItem->IsFillable() );
+
+ if( dialog.ShowModal() == wxID_CANCEL )
+ return;
+
+ // Init default values (used to create a new draw item)
+ val = dialog.GetWidth();
+ m_drawLineWidth = ValueFromString( g_UserUnit, val );
+ m_drawSpecificConvert = !dialog.GetApplyToAllConversions();
+ m_drawSpecificUnit = !dialog.GetApplyToAllUnits();
+
+#if 0
+ /* TODO: see if m_drawFillStyle must retain the last fill option or not.
+ * if the last is Filled, having next new graphic items created
+ * with filled body is often bad.
+ * currently m_drawFillStyle is left with the default value (not filled)
+ */
+ if( DrawItem->IsFillable() )
+ m_drawFillStyle = (FILL_T) dialog.GetFillStyle();
+#endif
+
+ // Save copy for undo if not in edit (edit command already handle the save copy)
+ if( !DrawItem->InEditMode() )
+ SaveCopyInUndoList( DrawItem->GetParent() );
+
+ if( m_drawSpecificUnit )
+ DrawItem->SetUnit( GetUnit() );
+ else
+ DrawItem->SetUnit( 0 );
+
+ if( m_drawSpecificConvert )
+ DrawItem->SetConvert( GetConvert() );
+ else
+ DrawItem->SetConvert( 0 );
+
+ if( DrawItem->IsFillable() )
+ DrawItem->SetFillMode( (FILL_T) dialog.GetFillStyle() );
+
+ DrawItem->SetWidth( m_drawLineWidth );
+
+ if( component )
+ component->GetDrawItemList().sort();
+
+ OnModify( );
+
+ MSG_PANEL_ITEMS items;
+ DrawItem->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+ m_canvas->Refresh();
+}
+
+
+static void AbortSymbolTraceOn( EDA_DRAW_PANEL* Panel, wxDC* DC )
+{
+ LIB_EDIT_FRAME* parent = (LIB_EDIT_FRAME*) Panel->GetParent();
+ LIB_ITEM* item = parent->GetDrawItem();
+
+ if( item == NULL )
+ return;
+
+ bool newItem = item->IsNew();
+ item->EndEdit( parent->GetCrossHairPosition( true ), true );
+
+ if( newItem )
+ {
+ delete item;
+ }
+ else
+ parent->RestoreComponent();
+
+ parent->SetDrawItem( NULL );
+ Panel->Refresh();
+}
+
+
+LIB_ITEM* LIB_EDIT_FRAME::CreateGraphicItem( LIB_PART* LibEntry, wxDC* DC )
+{
+ m_canvas->SetMouseCapture( SymbolDisplayDraw, AbortSymbolTraceOn );
+ wxPoint drawPos = GetCrossHairPosition( true );
+
+ // no temp copy -> the current version of component will be used for Undo
+ // This is normal when adding new items to the current component
+ ClearTempCopyComponent();
+
+ switch( GetToolId() )
+ {
+ case ID_LIBEDIT_BODY_ARC_BUTT:
+ m_drawItem = new LIB_ARC( LibEntry );
+ break;
+
+ case ID_LIBEDIT_BODY_CIRCLE_BUTT:
+ m_drawItem = new LIB_CIRCLE( LibEntry );
+ break;
+
+ case ID_LIBEDIT_BODY_RECT_BUTT:
+ m_drawItem = new LIB_RECTANGLE( LibEntry );
+ break;
+
+ case ID_LIBEDIT_BODY_LINE_BUTT:
+ m_drawItem = new LIB_POLYLINE( LibEntry );
+ break;
+
+ case ID_LIBEDIT_BODY_TEXT_BUTT:
+ {
+ LIB_TEXT* Text = new LIB_TEXT( LibEntry );
+ Text->SetSize( wxSize( m_textSize, m_textSize ) );
+ Text->SetOrientation( m_textOrientation );
+
+ // Enter the graphic text info
+ m_canvas->SetIgnoreMouseEvents( true );
+ EditSymbolText( NULL, Text );
+ m_canvas->SetIgnoreMouseEvents( false );
+ m_canvas->MoveCursorToCrossHair();
+
+ if( Text->GetText().IsEmpty() )
+ {
+ delete Text;
+ m_drawItem = NULL;
+ }
+ else
+ {
+ m_drawItem = Text;
+ }
+ }
+ break;
+
+ default:
+ DisplayError( this, wxT( "LIB_EDIT_FRAME::CreateGraphicItem() error" ) );
+ return NULL;
+ }
+
+ if( m_drawItem )
+ {
+ m_drawItem->BeginEdit( IS_NEW, drawPos );
+
+ // Don't set line parameters for text objects.
+ if( m_drawItem->Type() != LIB_TEXT_T )
+ {
+ m_drawItem->SetWidth( m_drawLineWidth );
+ m_drawItem->SetFillMode( m_drawFillStyle );
+ }
+
+ if( m_drawSpecificUnit )
+ m_drawItem->SetUnit( m_unit );
+
+ if( m_drawSpecificConvert )
+ m_drawItem->SetConvert( m_convert );
+
+ // Draw initial symbol:
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ }
+ else
+ {
+ m_canvas->EndMouseCapture();
+ return NULL;
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+
+ return m_drawItem;
+}
+
+
+void LIB_EDIT_FRAME::GraphicItemBeginDraw( wxDC* DC )
+{
+ if( m_drawItem == NULL )
+ return;
+
+ wxPoint pos = GetCrossHairPosition( true );
+
+ if( m_drawItem->ContinueEdit( pos ) )
+ {
+ m_drawItem->Draw( m_canvas, DC, pos, UNSPECIFIED_COLOR, g_XorMode, NULL, DefaultTransform );
+ return;
+ }
+
+ EndDrawGraphicItem( DC );
+}
+
+
+/*
+ * Redraw the graphic shape while moving
+ */
+static void RedrawWhileMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ LIB_ITEM* item;
+
+ item = ( (LIB_EDIT_FRAME*) aPanel->GetParent() )->GetDrawItem();
+
+ if( item == NULL )
+ return;
+
+ item->SetEraseLastDrawItem( aErase );
+
+ // if item is the reference field, we must add the current unit id
+ if( item->Type() == LIB_FIELD_T )
+ {
+ int unit = ((LIB_EDIT_FRAME*)aPanel->GetParent())->GetUnit();
+ wxString text = ((LIB_FIELD*)item)->GetFullText( unit );
+
+ item->Draw( aPanel, aDC, aPanel->GetParent()->GetCrossHairPosition( true ),
+ UNSPECIFIED_COLOR, g_XorMode, &text,
+ DefaultTransform );
+ }
+ else
+ item->Draw( aPanel, aDC, aPanel->GetParent()->GetCrossHairPosition( true ),
+ UNSPECIFIED_COLOR, g_XorMode, NULL,
+ DefaultTransform );
+}
+
+
+void LIB_EDIT_FRAME::StartMoveDrawSymbol( wxDC* DC )
+{
+ if( m_drawItem == NULL )
+ return;
+
+ SetCursor( wxCURSOR_HAND );
+
+ TempCopyComponent();
+
+ // For fields only, move the anchor point of the field
+ // to the cursor position to allow user to see the text justification
+ if( m_drawItem->Type() == LIB_FIELD_T )
+ m_drawItem->BeginEdit( IS_MOVED, m_drawItem->GetPosition() );
+ else
+ m_drawItem->BeginEdit( IS_MOVED, GetCrossHairPosition( true ) );
+
+ m_canvas->SetMouseCapture( RedrawWhileMovingCursor, AbortSymbolTraceOn );
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, true );
+}
+
+
+void LIB_EDIT_FRAME::StartModifyDrawSymbol( wxDC* DC )
+{
+ if( m_drawItem == NULL )
+ return;
+
+ TempCopyComponent();
+ m_drawItem->BeginEdit( IS_RESIZED, GetCrossHairPosition( true ) );
+ m_canvas->SetMouseCapture( SymbolDisplayDraw, AbortSymbolTraceOn );
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, true );
+}
+
+
+//! @brief Manage mouse events when creating new graphic object or modifying an graphic object.
+static void SymbolDisplayDraw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ LIB_ITEM* item = ( (LIB_EDIT_FRAME*) aPanel->GetParent() )->GetDrawItem();
+
+ if( item == NULL )
+ return;
+
+ item->SetEraseLastDrawItem( aErase );
+ item->Draw( aPanel, aDC, aPanel->GetParent()->GetCrossHairPosition( true ), UNSPECIFIED_COLOR,
+ g_XorMode, NULL, DefaultTransform );
+}
+
+
+void LIB_EDIT_FRAME::EndDrawGraphicItem( wxDC* DC )
+{
+ if( LIB_PART* part = GetCurPart() )
+ {
+ if( !m_drawItem )
+ return;
+
+ if( GetToolId() != ID_NO_TOOL_SELECTED )
+ SetCursor( wxCURSOR_PENCIL );
+ else
+ SetCursor( (wxStockCursor) m_canvas->GetDefaultCursor() );
+
+ if( GetTempCopyComponent() ) // used when editing an existing item
+ SaveCopyInUndoList( GetTempCopyComponent() );
+ else
+ {
+ // When creating a new item, there is still no change for the
+ // current component. So save it.
+ SaveCopyInUndoList( part );
+ }
+
+ if( m_drawItem->IsNew() )
+ part->AddDrawItem( m_drawItem );
+
+ m_drawItem->EndEdit( GetCrossHairPosition( true ) );
+
+ m_drawItem = NULL;
+
+ OnModify();
+
+ m_canvas->SetMouseCapture( NULL, NULL );
+ m_canvas->Refresh();
+ }
+}
diff --git a/eeschema/symbedit.cpp b/eeschema/symbedit.cpp
new file mode 100644
index 0000000..10536b3
--- /dev/null
+++ b/eeschema/symbedit.cpp
@@ -0,0 +1,269 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file symbedit.cpp
+ * @brief Functions to load from and save to file component libraries and symbols.
+ */
+
+#include <fctsys.h>
+#include <kiway.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <class_sch_screen.h>
+
+#include <general.h>
+#include <libeditframe.h>
+#include <class_library.h>
+#include <wildcards_and_files_ext.h>
+
+#include <boost/foreach.hpp>
+
+
+void LIB_EDIT_FRAME::LoadOneSymbol()
+{
+ LIB_PART* part = GetCurPart();
+
+ // Exit if no library entry is selected or a command is in progress.
+ if( !part || ( m_drawItem && m_drawItem->GetFlags() ) )
+ return;
+
+ PROJECT& prj = Prj();
+ SEARCH_STACK* search = prj.SchSearchS();
+
+ m_canvas->SetIgnoreMouseEvents( true );
+
+ wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
+ if( !default_path )
+ default_path = search->LastVisitedPath();
+
+ wxFileDialog dlg( this, _( "Import Symbol Drawings" ), default_path,
+ wxEmptyString, SchematicSymbolFileWildcard,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ SetCrossHairPosition( wxPoint( 0, 0 ) );
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+
+ wxString filename = dlg.GetPath();
+
+ prj.SetRString( PROJECT::SCH_LIB_PATH, filename );
+
+ std::auto_ptr<PART_LIB> lib( new PART_LIB( LIBRARY_TYPE_SYMBOL, filename ) );
+
+ wxString err;
+
+ if( !lib->Load( err ) )
+ {
+ wxString msg = wxString::Format( _(
+ "Error '%s' occurred loading part file '%s'." ),
+ GetChars( err ),
+ GetChars( filename )
+ );
+ DisplayError( this, msg );
+ return;
+ }
+
+ if( lib->IsEmpty() )
+ {
+ wxString msg = wxString::Format( _(
+ "No parts found in part file '%s'." ),
+ GetChars( filename )
+ );
+ DisplayError( this, msg );
+ return;
+ }
+
+ if( lib->GetCount() > 1 )
+ {
+ wxString msg = wxString::Format( _(
+ "More than one part in part file '%s'." ),
+ GetChars( filename )
+ );
+ wxMessageBox( msg, _( "Warning" ), wxOK | wxICON_EXCLAMATION, this );
+ }
+
+ LIB_PART* first = lib->GetFirstEntry()->GetPart();
+ LIB_ITEMS& drawList = first->GetDrawItemList();
+
+ BOOST_FOREACH( LIB_ITEM& item, drawList )
+ {
+ if( item.Type() == LIB_FIELD_T )
+ continue;
+
+ if( item.GetUnit() )
+ item.SetUnit( m_unit );
+
+ if( item.GetConvert() )
+ item.SetConvert( m_convert );
+
+ item.SetFlags( IS_NEW | SELECTED );
+
+ LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
+
+ newItem->SetParent( part );
+ part->AddDrawItem( newItem );
+ }
+
+ part->RemoveDuplicateDrawItems();
+ part->ClearSelectedItems();
+
+ OnModify();
+ m_canvas->Refresh();
+}
+
+
+void LIB_EDIT_FRAME::SaveOneSymbol()
+{
+ wxString msg;
+ PROJECT& prj = Prj();
+ SEARCH_STACK* search = prj.SchSearchS();
+ LIB_PART* part = GetCurPart();
+
+ if( !part || part->GetDrawItemList().empty() )
+ return;
+
+ wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
+ if( !default_path )
+ default_path = search->LastVisitedPath();
+
+ wxFileDialog dlg( this, _( "Export Symbol Drawings" ), default_path,
+ part->GetName(), SchematicSymbolFileWildcard,
+ wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ wxFileName fn = dlg.GetPath();
+
+ /* The GTK file chooser doesn't return the file extension added to
+ * file name so add it here. */
+ if( fn.GetExt().IsEmpty() )
+ fn.SetExt( SchematicSymbolFileExtension );
+
+ prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
+
+ msg.Printf( _( "Saving symbol in '%s'" ), GetChars( fn.GetPath() ) );
+ SetStatusText( msg );
+
+ wxString line;
+
+ // File header
+ line << wxT( LIBFILE_IDENT ) << wxT( " " ) << LIB_VERSION_MAJOR
+ << wxT( "." ) << LIB_VERSION_MINOR << wxT( " SYMBOL " )
+ << wxT( "Date: " ) << DateAndTime() << wxT( "\n" );
+
+ // Component name comment and definition.
+ line << wxT( "# SYMBOL " ) << part->GetName() << wxT( "\n#\nDEF " )
+ << part->GetName() << wxT( " " );
+
+ if( !part->GetReferenceField().GetText().IsEmpty() )
+ line << part->GetReferenceField().GetText() << wxT( " " );
+ else
+ line << wxT( "~ " );
+
+ line << 0 << wxT( " " ) << part->GetPinNameOffset() << wxT( " " );
+
+ if( part->ShowPinNumbers() )
+ line << wxT( "Y " );
+ else
+ line << wxT( "N " );
+
+ if( part->ShowPinNames() )
+ line << wxT( "Y " );
+ else
+ line << wxT( "N " );
+
+ line << wxT( "1 0 N\n" );
+
+ try
+ {
+ FILE_OUTPUTFORMATTER formatter( fn.GetFullPath() );
+
+ try
+ {
+ formatter.Print( 0, "%s", TO_UTF8( line ) );
+ part->GetReferenceField().Save( formatter );
+ part->GetValueField().Save( formatter );
+ formatter.Print( 0, "DRAW\n" );
+
+ LIB_ITEMS& drawList = part->GetDrawItemList();
+
+ BOOST_FOREACH( LIB_ITEM& item, drawList )
+ {
+ if( item.Type() == LIB_FIELD_T )
+ continue;
+
+ // Don't save unused parts or alternate body styles.
+ if( m_unit && item.GetUnit() && ( item.GetUnit() != m_unit ) )
+ continue;
+
+ if( m_convert && item.GetConvert() && ( item.GetConvert() != m_convert ) )
+ continue;
+
+ item.Save( formatter );
+ }
+
+ formatter.Print( 0, "ENDDRAW\n" );
+ formatter.Print( 0, "ENDDEF\n" );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ msg.Printf( _( "An error occurred attempting to save symbol file '%s'" ),
+ GetChars( fn.GetFullPath() ) );
+ DisplayError( this, msg );
+ }
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( this, ioe.errorText );
+ return;
+ }
+}
+
+
+void LIB_EDIT_FRAME::PlaceAnchor()
+{
+ if( LIB_PART* part = GetCurPart() )
+ {
+ const wxPoint& cross_hair = GetCrossHairPosition();
+
+ wxPoint offset( -cross_hair.x, cross_hair.y );
+
+ OnModify( );
+
+ part->SetOffset( offset );
+
+ // Redraw the symbol
+ RedrawScreen( wxPoint( 0 , 0 ), true );
+ m_canvas->Refresh();
+ }
+}
diff --git a/eeschema/template_fieldnames.cpp b/eeschema/template_fieldnames.cpp
new file mode 100644
index 0000000..28be5dd
--- /dev/null
+++ b/eeschema/template_fieldnames.cpp
@@ -0,0 +1,211 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <template_fieldnames.h>
+#include <dsnlexer.h>
+#include <fctsys.h>
+#include <macros.h>
+
+using namespace TFIELD_T;
+
+const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx )
+{
+ // Fixed values for the first few default fields used by EESCHEMA
+ // (mandatory fields)
+ switch( aFieldNdx )
+ {
+ case REFERENCE:
+ return _( "Reference" ); // The component reference, R1, C1, etc.
+
+ case VALUE:
+ return _( "Value" ); // The component value + name
+
+ case FOOTPRINT:
+ return _( "Footprint" ); // The footprint for use with Pcbnew
+
+ case DATASHEET:
+ return _( "Datasheet" ); // Link to a datasheet for component
+
+ default:
+ break;
+ }
+
+ // Other fields are use fields, give a default name:
+ wxString fieldName = _( "Field" );
+ fieldName << aFieldNdx;
+ return fieldName;
+}
+
+void TEMPLATE_FIELDNAME::Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR )
+{
+ out->Print( nestLevel, "(field (name %s)", out->Quotew( m_Name ).c_str() );
+
+ if( !m_Value.IsEmpty() )
+ out->Print( 0, "(value %s)", out->Quotew( m_Value ).c_str() );
+
+ if( m_Visible )
+ out->Print( 0, " visible" );
+
+ out->Print( 0, ")\n" );
+}
+
+
+void TEMPLATE_FIELDNAME::Parse( TEMPLATE_FIELDNAMES_LEXER* in ) throw( IO_ERROR )
+{
+ T tok;
+
+ in->NeedLEFT(); // begin (name ...)
+
+ if( (tok = in->NextTok()) != T_name )
+ in->Expecting( T_name );
+
+ in->NeedSYMBOLorNUMBER();
+
+ m_Name = FROM_UTF8( in->CurText() );
+
+ in->NeedRIGHT(); // end (name ...)
+
+ while( (tok = in->NextTok() ) != T_RIGHT && tok != T_EOF )
+ {
+ // "visible" has no '(' prefix, "value" does, so T_LEFT is optional.
+ if( tok == T_LEFT )
+ tok = in->NextTok();
+
+ switch( tok )
+ {
+ case T_value:
+ in->NeedSYMBOLorNUMBER();
+ m_Value = FROM_UTF8( in->CurText() );
+ in->NeedRIGHT();
+ break;
+
+ case T_visible:
+ m_Visible = true;
+ break;
+
+ default:
+ in->Expecting( "value|visible" );
+ break;
+ }
+ }
+}
+
+
+void TEMPLATES::Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR )
+{
+ // We'll keep this general, and include the \n, even though the only known
+ // use at this time will not want the newlines or the indentation.
+ out->Print( nestLevel, "(templatefields" );
+
+ for( unsigned i=0; i<m_Fields.size(); ++i )
+ m_Fields[i].Format( out, nestLevel+1 );
+
+ out->Print( 0, ")\n" );
+}
+
+
+void TEMPLATES::Parse( TEMPLATE_FIELDNAMES_LEXER* in ) throw( IO_ERROR )
+{
+ T tok;
+
+ while( ( tok = in->NextTok() ) != T_RIGHT && tok != T_EOF )
+ {
+ if( tok == T_LEFT )
+ tok = in->NextTok();
+
+ switch( tok )
+ {
+ case T_templatefields: // a token indicating class TEMPLATES.
+
+ // Be flexible regarding the starting point of the TEMPLATE_FIELDNAMES_LEXER
+ // stream. Caller may not have read the first two tokens out of the
+ // stream: T_LEFT and T_templatefields, so ignore them if seen here.
+ break;
+
+ case T_field:
+ {
+ // instantiate on stack, so if exception is thrown,
+ // destructor runs
+ TEMPLATE_FIELDNAME field;
+
+ field.Parse( in );
+
+ // add the field
+ AddTemplateFieldName( field );
+ }
+ break;
+
+ default:
+ in->Unexpected( in->CurText() );
+ break;
+ }
+ }
+}
+
+
+int TEMPLATES::AddTemplateFieldName( const TEMPLATE_FIELDNAME& aFieldName )
+{
+ // Ensure that the template fieldname does not match a fixed fieldname.
+ for( int i=0; i<MANDATORY_FIELDS; ++i )
+ {
+ if( TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) == aFieldName.m_Name )
+ {
+ return -1;
+ }
+ }
+
+ // ensure uniqueness, overwrite any template fieldname by the same name.
+ for( unsigned i=0; i<m_Fields.size(); ++i )
+ {
+ if( m_Fields[i].m_Name == aFieldName.m_Name )
+ {
+ // DBG( printf( "inserting template fieldname:'%s' at %d\n",
+ // TO_UTF8( aFieldName.m_Name ), i ); )
+
+ m_Fields[i] = aFieldName;
+ return i; // return the container index
+ }
+ }
+
+ // DBG(printf("appending template fieldname:'%s'\n", aFieldName.m_Name.utf8_str() );)
+
+ // the name is legal and not previously added to the config container, append
+ // it and return its index within the container.
+ m_Fields.push_back( aFieldName );
+
+ return m_Fields.size() - 1; // return the index of insertion.
+}
+
+
+bool TEMPLATES::HasFieldName( const wxString& aName ) const
+{
+ for( size_t i=0; i<m_Fields.size(); ++i )
+ {
+ if( m_Fields[i].m_Name == aName )
+ return true;
+ }
+
+ return false;
+}
+
diff --git a/eeschema/template_fieldnames.h b/eeschema/template_fieldnames.h
new file mode 100644
index 0000000..130ab14
--- /dev/null
+++ b/eeschema/template_fieldnames.h
@@ -0,0 +1,190 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef _TEMPLATE_FIELDNAME_H_
+#define _TEMPLATE_FIELDNAME_H_
+
+#include <richio.h>
+#include <wxstruct.h>
+#include <macros.h>
+#include <template_fieldnames_lexer.h>
+
+class TEMPLATE_FIELDNAMES_LEXER;
+
+
+/**
+ * Enum NumFieldType
+ * is the set of all field indices assuming an array like sequence that a
+ * SCH_COMPONENT or LIB_PART can hold.
+ * The first fields are called fixed fields and the quantity of them is
+ * given by MANDATORY_FIELDS. After that come an unlimited number of
+ * user defined fields, only some of which have indices defined here.
+ */
+enum NumFieldType {
+ REFERENCE = 0, ///< Field Reference of part, i.e. "IC21"
+ VALUE, ///< Field Value of part, i.e. "3.3K"
+ FOOTPRINT, ///< Field Name Module PCB, i.e. "16DIP300"
+ DATASHEET, ///< name of datasheet
+
+ /// The first 4 are mandatory, and must be instantiated in SCH_COMPONENT
+ /// and LIB_PART constructors
+ MANDATORY_FIELDS,
+
+ FIELD1 = MANDATORY_FIELDS,
+ FIELD2,
+ FIELD3,
+ FIELD4,
+ FIELD5,
+ FIELD6,
+ FIELD7,
+ FIELD8
+};
+
+
+/**
+ * Struct TEMPLATE_FIELDNAME
+ * holds a name of a component's field, field value, and default visibility.
+ * Template fieldnames are wanted fieldnames for use in the symbol/component
+ * property editors.
+ */
+struct TEMPLATE_FIELDNAME
+{
+ wxString m_Name; ///< The field name
+ wxString m_Value; ///< The default value or empty
+ bool m_Visible; ///< If first appearance of the field's editor has as visible.
+
+ TEMPLATE_FIELDNAME() :
+ m_Visible( false )
+ {
+ }
+
+ TEMPLATE_FIELDNAME( const wxString& aName ) :
+ m_Name( aName ),
+ m_Visible( false )
+ {
+ }
+
+ TEMPLATE_FIELDNAME( const TEMPLATE_FIELDNAME& ref )
+ {
+ m_Name = ref.m_Name;
+ m_Value = ref.m_Value;
+ m_Visible = ref.m_Visible;
+ }
+
+ /**
+ * Function Format
+ * serializes this object out as text into the given OUTPUTFORMATTER.
+ */
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR );
+
+ /**
+ * Function Parse
+ * fills this object from information in the input stream \a aSpec, which
+ * is a TEMPLATE_FIELDNAMES_LEXER. The entire textual element spec is <br>
+ * (field (name _yourfieldname_)(value _yourvalue_) visible)) <br>
+ * The presence of value is optional, the presence of visible is optional.
+ * When this function is called, the input token stream given by \a aSpec
+ * is assumed to be positioned at the '^' in the following example, i.e. just after the
+ * identifying keyword and before the content specifying stuff.<br>
+ * (field ^ (....) )
+ *
+ * @param aSpec is the input token stream of keywords and symbols.
+ */
+ void Parse( TEMPLATE_FIELDNAMES_LEXER* aSpec ) throw( IO_ERROR );
+
+ /**
+ * Function GetDefaultFieldName
+ * returns a default symbol field name for field \a aFieldNdx for all components.
+ * These fieldnames are not modifiable, but template fieldnames are.
+ * @param aFieldNdx The field number index, > 0
+ */
+ static const wxString GetDefaultFieldName( int aFieldNdx );
+};
+
+typedef std::vector< TEMPLATE_FIELDNAME > TEMPLATE_FIELDNAMES;
+
+
+class TEMPLATES
+{
+private:
+ TEMPLATE_FIELDNAMES m_Fields;
+
+public:
+
+ /**
+ * Function Format
+ * serializes this object out as text into the given OUTPUTFORMATTER.
+ */
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR );
+
+ /**
+ * Function Parse
+ * fills this object from information in the input stream handled by TEMPLATE_FIELDNAMES_LEXER
+ */
+ void Parse( TEMPLATE_FIELDNAMES_LEXER* in ) throw( IO_ERROR );
+
+
+ /**
+ * Function AddTemplateFieldName
+ * inserts or appends a wanted symbol field name into the fieldnames
+ * template. Should be used for any symbol property editor. If the name
+ * already exists, it overwrites the same name.
+ *
+ * @param aFieldName is a full description of the wanted field, and it must not match
+ * any of the default fieldnames.
+ * @return int - the index within the config container at which aFieldName was
+ * added, or -1 if the name is illegal because it matches a default fieldname.
+ */
+ int AddTemplateFieldName( const TEMPLATE_FIELDNAME& aFieldName );
+
+ /**
+ * Function DeleteAllTemplateFieldNames
+ * deletes the entire contents.
+ */
+ void DeleteAllTemplateFieldNames()
+ {
+ m_Fields.clear();
+ }
+
+ /**
+ * Function GetTemplateFieldName
+ * returns a template fieldnames list for read only access.
+ */
+ const TEMPLATE_FIELDNAMES& GetTemplateFieldNames()
+ {
+ return m_Fields;
+ }
+
+ /**
+ * Function HasFieldName
+ * checks for \a aName in the the template field name list.
+ *
+ * @param aName A wxString object containing the field name to search for.
+ * @return True if \a aName is found in the list.
+ */
+ bool HasFieldName( const wxString& aName ) const;
+};
+
+#endif // _TEMPLATE_FIELDNAME_H_
diff --git a/eeschema/template_fieldnames.keywords b/eeschema/template_fieldnames.keywords
new file mode 100644
index 0000000..acd4468
--- /dev/null
+++ b/eeschema/template_fieldnames.keywords
@@ -0,0 +1,5 @@
+field
+name
+templatefields
+value
+visible
diff --git a/eeschema/tool_lib.cpp b/eeschema/tool_lib.cpp
new file mode 100644
index 0000000..729b768
--- /dev/null
+++ b/eeschema/tool_lib.cpp
@@ -0,0 +1,243 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file tool_lib.cpp
+ */
+
+#include <fctsys.h>
+#include <hotkeys.h>
+#include <eeschema_id.h>
+
+#include <general.h>
+#include <libeditframe.h>
+#include <dialog_helpers.h>
+
+#include <help_common_strings.h>
+
+#ifdef __UNIX__
+#define LISTBOX_WIDTH 140
+#else
+#define LISTBOX_WIDTH 120
+#endif
+
+
+extern int ExportPartId;
+extern int ImportPartId;
+extern int CreateNewLibAndSavePartId;
+
+
+void LIB_EDIT_FRAME::ReCreateVToolbar()
+{
+ if( m_drawToolBar != NULL )
+ return;
+
+ m_drawToolBar = new wxAuiToolBar( this, ID_V_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
+
+ // Set up toolbar
+ m_drawToolBar->AddTool( ID_NO_TOOL_SELECTED, wxEmptyString, KiBitmap( cursor_xpm ),
+ _( "Deselect current tool" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_LIBEDIT_PIN_BUTT, wxEmptyString, KiBitmap( pin_xpm ),
+ HELP_ADD_PIN, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_LIBEDIT_BODY_TEXT_BUTT, wxEmptyString, KiBitmap( add_text_xpm ),
+ HELP_ADD_BODYTEXT, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_LIBEDIT_BODY_RECT_BUTT, wxEmptyString, KiBitmap( add_rectangle_xpm ),
+ HELP_ADD_BODYRECT, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_LIBEDIT_BODY_CIRCLE_BUTT, wxEmptyString, KiBitmap( add_circle_xpm ),
+ HELP_ADD_BODYCIRCLE, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_LIBEDIT_BODY_ARC_BUTT, wxEmptyString, KiBitmap( add_arc_xpm ),
+ HELP_ADD_BODYARC, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_LIBEDIT_BODY_LINE_BUTT, wxEmptyString, KiBitmap( add_polygon_xpm ),
+ HELP_ADD_BODYPOLYGON, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_LIBEDIT_ANCHOR_ITEM_BUTT, wxEmptyString, KiBitmap( anchor_xpm ),
+ _( "Move part anchor" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_LIBEDIT_IMPORT_BODY_BUTT, wxEmptyString, KiBitmap( import_xpm ),
+ _( "Import existing drawings" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_LIBEDIT_EXPORT_BODY_BUTT, wxEmptyString, KiBitmap( export_xpm ),
+ _( "Export current drawing" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_LIBEDIT_DELETE_ITEM_BUTT, wxEmptyString, KiBitmap( delete_xpm ),
+ HELP_DELETE_ITEMS, wxITEM_CHECK );
+
+ m_drawToolBar->Realize();
+}
+
+
+void LIB_EDIT_FRAME::ReCreateHToolbar()
+{
+ wxString msg;
+
+ // Create the toolbar if not exists
+ if( m_mainToolBar != NULL )
+ return;
+
+ m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
+
+ // Set up toolbar
+ m_mainToolBar->AddTool( ID_LIBEDIT_SAVE_CURRENT_LIB, wxEmptyString,
+ KiBitmap( save_library_xpm ),
+ _( "Save current library to disk" ) );
+
+ m_mainToolBar->AddTool( ID_LIBEDIT_SELECT_CURRENT_LIB, wxEmptyString, KiBitmap( library_xpm ),
+ _( "Select working library" ) );
+
+ m_mainToolBar->AddTool( ID_LIBEDIT_DELETE_PART, wxEmptyString, KiBitmap( delete_xpm ),
+ _( "Delete component in current library" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_TO_LIBVIEW, wxEmptyString, KiBitmap( library_browse_xpm ),
+ HELP_RUN_LIB_VIEWER );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_LIBEDIT_NEW_PART, wxEmptyString, KiBitmap( new_component_xpm ),
+ _( "Create a new component" ) );
+
+ m_mainToolBar->AddTool( ID_LIBEDIT_SELECT_PART, wxEmptyString,
+ KiBitmap( import_cmp_from_lib_xpm ),
+ _( "Load component to edit from the current library" ) );
+
+ m_mainToolBar->AddTool( ID_LIBEDIT_NEW_PART_FROM_EXISTING, wxEmptyString,
+ KiBitmap( copycomponent_xpm ),
+ _( "Create a new component from the current one" ) );
+
+ m_mainToolBar->AddTool( ID_LIBEDIT_SAVE_CURRENT_PART, wxEmptyString,
+ KiBitmap( save_part_in_mem_xpm ),
+ _( "Update current component in current library" ) );
+
+ m_mainToolBar->AddTool( ImportPartId, wxEmptyString, KiBitmap( import_xpm ),
+ _( "Import component" ) );
+
+ m_mainToolBar->AddTool( ExportPartId, wxEmptyString, KiBitmap( export_xpm ),
+ _( "Export component" ) );
+
+ m_mainToolBar->AddTool( CreateNewLibAndSavePartId, wxEmptyString, KiBitmap( new_library_xpm ),
+ _( "Save current component to new library" ) );
+
+ m_mainToolBar->AddSeparator();
+ msg = AddHotkeyName( _( "Undo last command" ), g_Libedit_Hokeys_Descr, HK_UNDO, IS_COMMENT );
+ m_mainToolBar->AddTool( wxID_UNDO, wxEmptyString, KiBitmap( undo_xpm ), msg );
+ msg = AddHotkeyName( _( "Redo the last command" ), g_Libedit_Hokeys_Descr, HK_REDO,
+ IS_COMMENT );
+ m_mainToolBar->AddTool( wxID_REDO, wxEmptyString, KiBitmap( redo_xpm ), msg );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_LIBEDIT_GET_FRAME_EDIT_PART, wxEmptyString,
+ KiBitmap( part_properties_xpm ), _( "Edit component properties" ) );
+
+ m_mainToolBar->AddTool( ID_LIBEDIT_GET_FRAME_EDIT_FIELDS, wxEmptyString,
+ KiBitmap( add_text_xpm ),
+ _( "Add and remove fields and edit field properties" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_LIBEDIT_CHECK_PART, wxEmptyString, KiBitmap( erc_xpm ),
+ _( "Test for duplicate and off grid pins" ) );
+
+ m_mainToolBar->AddSeparator();
+ msg = AddHotkeyName( HELP_ZOOM_IN, g_Libedit_Hokeys_Descr, HK_ZOOM_IN, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_IN, wxEmptyString, KiBitmap( zoom_in_xpm ), msg );
+
+ msg = AddHotkeyName( HELP_ZOOM_OUT, g_Libedit_Hokeys_Descr, HK_ZOOM_OUT, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_OUT, wxEmptyString, KiBitmap( zoom_out_xpm ), msg );
+
+ msg = AddHotkeyName( HELP_ZOOM_REDRAW, g_Libedit_Hokeys_Descr, HK_ZOOM_REDRAW, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_REDRAW, wxEmptyString, KiBitmap( zoom_redraw_xpm ), msg );
+
+ msg = AddHotkeyName( HELP_ZOOM_FIT, g_Libedit_Hokeys_Descr, HK_ZOOM_AUTO, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ), msg );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_DE_MORGAN_NORMAL_BUTT, wxEmptyString, KiBitmap( morgan1_xpm ),
+ _( "Show as \"De Morgan\" normal part" ), wxITEM_CHECK );
+ m_mainToolBar->AddTool( ID_DE_MORGAN_CONVERT_BUTT, wxEmptyString, KiBitmap( morgan2_xpm ),
+ _( "Show as \"De Morgan\" convert part" ), wxITEM_CHECK );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_LIBEDIT_VIEW_DOC, wxEmptyString, KiBitmap( datasheet_xpm ),
+ _( "Show the associated datasheet or document" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_partSelectBox = new wxComboBox( m_mainToolBar,
+ ID_LIBEDIT_SELECT_PART_NUMBER,
+ wxEmptyString,
+ wxDefaultPosition,
+ wxSize( LISTBOX_WIDTH, -1 ),
+ 0, NULL, wxCB_READONLY );
+ m_mainToolBar->AddControl( m_partSelectBox );
+
+ m_aliasSelectBox = new wxComboBox( m_mainToolBar,
+ ID_LIBEDIT_SELECT_ALIAS,
+ wxEmptyString,
+ wxDefaultPosition,
+ wxSize( LISTBOX_WIDTH, -1 ),
+ 0, NULL, wxCB_READONLY );
+ m_mainToolBar->AddControl( m_aliasSelectBox );
+
+ m_mainToolBar->AddSeparator();
+ msg = _( "Edit pins per part or body style (Use carefully!)" );
+ m_mainToolBar->AddTool( ID_LIBEDIT_EDIT_PIN_BY_PIN, wxEmptyString, KiBitmap( pin2pin_xpm ),
+ msg, wxITEM_CHECK );
+ m_mainToolBar->AddTool( ID_LIBEDIT_EDIT_PIN_BY_TABLE, wxEmptyString, KiBitmap( pin_table_xpm ),
+ _( "Show pin table" ) );
+
+ // after adding the buttons to the toolbar, must call Realize() to reflect the changes
+ m_mainToolBar->Realize();
+}
+
+
+void LIB_EDIT_FRAME::CreateOptionToolbar()
+{
+ if( m_optionsToolBar )
+ return;
+
+ m_optionsToolBar = new wxAuiToolBar( this, ID_OPT_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GRID, wxEmptyString, KiBitmap( grid_xpm ),
+ _( "Turn grid off" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_INCH, wxEmptyString,
+ KiBitmap( unit_inch_xpm ), _( "Units in inches" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_MM, wxEmptyString,
+ KiBitmap( unit_mm_xpm ),
+ _( "Units in millimeters" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_CURSOR, wxEmptyString,
+ KiBitmap( cursor_shape_xpm ),
+ _( "Change cursor shape" ), wxITEM_CHECK );
+
+ m_optionsToolBar->Realize();
+}
diff --git a/eeschema/tool_sch.cpp b/eeschema/tool_sch.cpp
new file mode 100644
index 0000000..314313c
--- /dev/null
+++ b/eeschema/tool_sch.cpp
@@ -0,0 +1,325 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file tool_sch.cpp
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <schframe.h>
+#include <kiface_i.h>
+
+#include <general.h>
+#include <hotkeys.h>
+#include <eeschema_id.h>
+
+#include <help_common_strings.h>
+
+
+/* Create the main Horizontal Toolbar for the schematic editor
+ */
+void SCH_EDIT_FRAME::ReCreateHToolbar()
+{
+ if( m_mainToolBar != NULL )
+ return;
+
+ wxString msg;
+ m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
+
+ // Set up toolbar
+ if( Kiface().IsSingle() ) // not when under a project mgr
+ {
+ // These 2 menus have meaning only outside a project, i.e. not under a project manager:
+ m_mainToolBar->AddTool( ID_NEW_PROJECT, wxEmptyString, KiBitmap( new_sch_xpm ),
+ _( "New schematic project" ) );
+
+ m_mainToolBar->AddTool( ID_LOAD_PROJECT, wxEmptyString, KiBitmap( open_document_xpm ),
+ _( "Open schematic project" ) );
+ }
+
+ m_mainToolBar->AddTool( ID_SAVE_PROJECT, wxEmptyString, KiBitmap( save_project_xpm ),
+ _( "Save schematic project" ) );
+
+ m_mainToolBar->AddSeparator();
+
+ m_mainToolBar->AddTool( ID_SHEET_SET, wxEmptyString, KiBitmap( sheetset_xpm ),
+ _( "Page settings" ) );
+
+ m_mainToolBar->AddSeparator();
+
+ m_mainToolBar->AddTool( wxID_PRINT, wxEmptyString, KiBitmap( print_button_xpm ),
+ _( "Print schematic" ) );
+
+ m_mainToolBar->AddTool( ID_GEN_PLOT_SCHEMATIC, wxEmptyString, KiBitmap( plot_xpm ),
+ _( "Plot schematic" ) );
+
+ m_mainToolBar->AddSeparator();
+
+ m_mainToolBar->AddTool( wxID_CUT, wxEmptyString, KiBitmap( cut_button_xpm ),
+ _( "Cut selected item" ) );
+
+ m_mainToolBar->AddTool( wxID_COPY, wxEmptyString, KiBitmap( copy_button_xpm ),
+ _( "Copy selected item" ) );
+
+ m_mainToolBar->AddTool( wxID_PASTE, wxEmptyString, KiBitmap( paste_xpm ),
+ _( "Paste" ) );
+
+
+ m_mainToolBar->AddSeparator();
+
+ msg = AddHotkeyName( HELP_UNDO, g_Schematic_Hokeys_Descr, HK_UNDO, IS_COMMENT );
+ m_mainToolBar->AddTool( wxID_UNDO, wxEmptyString, KiBitmap( undo_xpm ), msg );
+
+ msg = AddHotkeyName( HELP_REDO, g_Schematic_Hokeys_Descr, HK_REDO, IS_COMMENT );
+ m_mainToolBar->AddTool( wxID_REDO, wxEmptyString, KiBitmap( redo_xpm ), msg );
+
+
+ m_mainToolBar->AddSeparator();
+
+ msg = AddHotkeyName( HELP_FIND, g_Schematic_Hokeys_Descr, HK_FIND_ITEM, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_FIND_ITEMS, wxEmptyString, KiBitmap( find_xpm ), msg );
+
+ m_mainToolBar->AddTool( wxID_REPLACE, wxEmptyString, KiBitmap( find_replace_xpm ),
+ wxNullBitmap, wxITEM_NORMAL, _( "Find and replace text" ),
+ HELP_REPLACE, NULL );
+
+
+ m_mainToolBar->AddSeparator();
+
+ msg = AddHotkeyName( HELP_ZOOM_IN, g_Schematic_Hokeys_Descr, HK_ZOOM_IN, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_IN, wxEmptyString, KiBitmap( zoom_in_xpm ), msg );
+
+ msg = AddHotkeyName( HELP_ZOOM_OUT, g_Schematic_Hokeys_Descr, HK_ZOOM_OUT, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_OUT, wxEmptyString, KiBitmap( zoom_out_xpm ), msg );
+
+ msg = AddHotkeyName( HELP_ZOOM_REDRAW, g_Schematic_Hokeys_Descr, HK_ZOOM_REDRAW, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_REDRAW, wxEmptyString, KiBitmap( zoom_redraw_xpm ), msg );
+
+ msg = AddHotkeyName( HELP_ZOOM_FIT, g_Schematic_Hokeys_Descr, HK_ZOOM_AUTO, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ), msg );
+
+
+ m_mainToolBar->AddSeparator();
+
+ m_mainToolBar->AddTool( ID_HIERARCHY, wxEmptyString, KiBitmap( hierarchy_nav_xpm ),
+ _( "Navigate schematic hierarchy" ) );
+
+
+ m_mainToolBar->AddTool( ID_POPUP_SCH_LEAVE_SHEET, wxEmptyString, KiBitmap( leave_sheet_xpm ),
+ _( "Leave sheet" ) );
+
+ m_mainToolBar->AddSeparator();
+
+ m_mainToolBar->AddTool( ID_RUN_LIBRARY, wxEmptyString, KiBitmap( libedit_xpm ),
+ HELP_RUN_LIB_EDITOR );
+
+ m_mainToolBar->AddTool( ID_TO_LIBVIEW, wxEmptyString, KiBitmap( library_browse_xpm ),
+ HELP_RUN_LIB_VIEWER );
+
+ // modedit is with libedit in a "library section" because the user must have footprints before
+ // they can be assigned.
+ m_mainToolBar->AddTool( ID_RUN_PCB_MODULE_EDITOR, wxEmptyString, KiBitmap( module_editor_xpm ),
+ _( "Footprint Editor" ) );
+
+ m_mainToolBar->AddSeparator();
+
+ m_mainToolBar->AddTool( ID_GET_ANNOTATE, wxEmptyString, KiBitmap( annotate_xpm ),
+ HELP_ANNOTATE );
+
+ m_mainToolBar->AddTool( ID_GET_ERC, wxEmptyString, KiBitmap( erc_xpm ),
+ _( "Perform electrical rules check" ) );
+
+ m_mainToolBar->AddTool( ID_RUN_CVPCB, wxEmptyString, KiBitmap( cvpcb_xpm ),
+ _( "Run CvPcb to associate components and footprints" ) );
+
+ m_mainToolBar->AddTool( ID_GET_NETLIST, wxEmptyString, KiBitmap( netlist_xpm ),
+ _( "Generate netlist" ) );
+
+ m_mainToolBar->AddTool( ID_GET_TOOLS, wxEmptyString, KiBitmap( bom_xpm ),
+ HELP_GENERATE_BOM );
+
+
+ m_mainToolBar->AddSeparator();
+
+ m_mainToolBar->AddTool( ID_RUN_PCB, wxEmptyString, KiBitmap( pcbnew_xpm ),
+ _( "Run Pcbnew to layout printed circuit board" ) );
+
+ m_mainToolBar->AddTool( ID_BACKANNO_ITEMS, wxEmptyString,
+ KiBitmap( import_footprint_names_xpm ),
+ HELP_IMPORT_FOOTPRINTS );
+
+ // after adding the tools to the toolbar, must call Realize() to reflect the changes
+ m_mainToolBar->Realize();
+}
+
+
+/* Create Vertical Right Toolbar
+ */
+void SCH_EDIT_FRAME::ReCreateVToolbar()
+{
+ if( m_drawToolBar )
+ return;
+
+ m_drawToolBar = new wxAuiToolBar( this, ID_V_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
+
+ // Set up toolbar
+ m_drawToolBar->AddTool( ID_NO_TOOL_SELECTED, wxEmptyString, KiBitmap( cursor_xpm ),
+ wxEmptyString, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_HIERARCHY_PUSH_POP_BUTT, wxEmptyString,
+ KiBitmap( hierarchy_cursor_xpm ),
+ _( "Ascend/descend hierarchy" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_SCH_PLACE_COMPONENT, wxEmptyString, KiBitmap( add_component_xpm ),
+ HELP_PLACE_COMPONENTS, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_PLACE_POWER_BUTT, wxEmptyString, KiBitmap( add_power_xpm ),
+ HELP_PLACE_POWERPORT, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_WIRE_BUTT, wxEmptyString, KiBitmap( add_line_xpm ),
+ HELP_PLACE_WIRE, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_BUS_BUTT, wxEmptyString, KiBitmap( add_bus_xpm ),
+ HELP_PLACE_BUS, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_WIRETOBUS_ENTRY_BUTT, wxEmptyString, KiBitmap( add_line2bus_xpm ),
+ HELP_PLACE_WIRE2BUS_ENTRY, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_BUSTOBUS_ENTRY_BUTT, wxEmptyString, KiBitmap( add_bus2bus_xpm ),
+ HELP_PLACE_BUS2BUS_ENTRY, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_NOCONN_BUTT, wxEmptyString, KiBitmap( noconn_xpm ),
+ HELP_PLACE_NC_FLAG, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_JUNCTION_BUTT, wxEmptyString, KiBitmap( add_junction_xpm ),
+ HELP_PLACE_JUNCTION, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_LABEL_BUTT, wxEmptyString, KiBitmap( add_line_label_xpm ),
+ HELP_PLACE_NETLABEL, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_GLABEL_BUTT, wxEmptyString, KiBitmap( add_glabel_xpm ),
+ HELP_PLACE_GLOBALLABEL, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_HIERLABEL_BUTT, wxEmptyString,
+ KiBitmap( add_hierarchical_label_xpm ),
+ HELP_PLACE_HIER_LABEL, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_SHEET_SYMBOL_BUTT, wxEmptyString,
+ KiBitmap( add_hierarchical_subsheet_xpm ),
+ HELP_PLACE_SHEET, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_IMPORT_HLABEL_BUTT, wxEmptyString,
+ KiBitmap( import_hierarchical_label_xpm ),
+ HELP_IMPORT_SHEETPIN, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_SHEET_PIN_BUTT, wxEmptyString,
+ KiBitmap( add_hierar_pin_xpm ),
+ HELP_PLACE_SHEETPIN, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_LINE_COMMENT_BUTT, wxEmptyString,
+ KiBitmap( add_dashed_line_xpm ),
+ HELP_PLACE_GRAPHICLINES, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_TEXT_COMMENT_BUTT, wxEmptyString, KiBitmap( add_text_xpm ),
+ HELP_PLACE_GRAPHICTEXTS, wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_ADD_IMAGE_BUTT, wxEmptyString, KiBitmap( image_xpm ),
+ _("Add bitmap image"), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_SCHEMATIC_DELETE_ITEM_BUTT, wxEmptyString,
+ KiBitmap( delete_xpm ),
+ HELP_DELETE_ITEMS, wxITEM_CHECK );
+
+ m_drawToolBar->Realize();
+}
+
+
+/* Create Vertical Left Toolbar (Option Toolbar)
+ */
+void SCH_EDIT_FRAME::ReCreateOptToolbar()
+{
+ if( m_optionsToolBar )
+ return;
+
+ m_optionsToolBar = new wxAuiToolBar( this, ID_OPT_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GRID, wxEmptyString,
+ KiBitmap( grid_xpm ),
+ _( "Turn grid off" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_INCH, wxEmptyString,
+ KiBitmap( unit_inch_xpm ),
+ _( "Set unit to inch" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_MM, wxEmptyString,
+ KiBitmap( unit_mm_xpm ),
+ _( "Set unit to mm" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_CURSOR, wxEmptyString,
+ KiBitmap( cursor_shape_xpm ),
+ _( "Change cursor shape" ), wxITEM_CHECK );
+
+ //m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_HIDDEN_PINS, wxEmptyString,
+ KiBitmap( hidden_pin_xpm ),
+ _( "Show hidden pins" ), wxITEM_CHECK );
+
+ //m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_BUS_WIRES_ORIENT, wxEmptyString,
+ KiBitmap( lines90_xpm ),
+ _( "HV orientation for wires and bus" ),
+ wxITEM_CHECK );
+
+ m_optionsToolBar->Realize();
+}
+
+
+void SCH_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
+{
+ if( m_canvas == NULL )
+ return;
+
+ int id = event.GetId();
+
+ switch( id )
+ {
+ case ID_TB_OPTIONS_HIDDEN_PINS:
+ m_showAllPins = m_optionsToolBar->GetToolToggled( id );
+ m_canvas->Refresh();
+ break;
+
+ case ID_TB_OPTIONS_BUS_WIRES_ORIENT:
+ SetForceHVLines( m_optionsToolBar->GetToolToggled( id ) );
+ break;
+
+ default:
+ wxFAIL_MSG( wxT( "Unexpected select option tool bar ID." ) );
+ break;
+ }
+}
diff --git a/eeschema/tool_viewlib.cpp b/eeschema/tool_viewlib.cpp
new file mode 100644
index 0000000..79a50bd
--- /dev/null
+++ b/eeschema/tool_viewlib.cpp
@@ -0,0 +1,279 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file tool_viewlib.cpp
+ * @brief Build the toolbars for the library browser.
+ */
+
+#include <fctsys.h>
+#include <macros.h>
+#include <eeschema_id.h>
+
+#include <general.h>
+#include <hotkeys.h>
+#include <class_library.h>
+#include <viewlib_frame.h>
+#include <dialog_helpers.h>
+#include <menus_helpers.h>
+#include <help_common_strings.h>
+
+
+void LIB_VIEW_FRAME::ReCreateHToolbar()
+{
+ wxString msg;
+ LIB_ALIAS* entry = NULL;
+ bool asdeMorgan = false;
+ LIB_PART* part = NULL;
+
+ if( m_mainToolBar == NULL )
+ {
+ m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
+
+ // Set up toolbar
+ m_mainToolBar->AddTool( ID_LIBVIEW_SELECT_LIB, wxEmptyString,
+ KiBitmap( library_xpm ),
+ _( "Select library to browse" ) );
+
+ m_mainToolBar->AddTool( ID_LIBVIEW_SELECT_PART, wxEmptyString,
+ KiBitmap( add_component_xpm ),
+ _( "Select component to browse" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_LIBVIEW_PREVIOUS, wxEmptyString,
+ KiBitmap( lib_previous_xpm ),
+ _( "Display previous component" ) );
+
+ m_mainToolBar->AddTool( ID_LIBVIEW_NEXT, wxEmptyString,
+ KiBitmap( lib_next_xpm ),
+ _( "Display next component" ) );
+
+ m_mainToolBar->AddSeparator();
+ msg = AddHotkeyName( _( "Zoom in" ), g_Viewlib_Hokeys_Descr,
+ HK_ZOOM_IN, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_IN, wxEmptyString,
+ KiBitmap( zoom_in_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Zoom out" ), g_Viewlib_Hokeys_Descr,
+ HK_ZOOM_OUT, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_OUT, wxEmptyString,
+ KiBitmap( zoom_out_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Redraw view" ), g_Viewlib_Hokeys_Descr,
+ HK_ZOOM_REDRAW, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_REDRAW, wxEmptyString,
+ KiBitmap( zoom_redraw_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Zoom auto" ), g_Viewlib_Hokeys_Descr,
+ HK_ZOOM_AUTO, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString,
+ KiBitmap( zoom_fit_in_page_xpm ), msg );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_LIBVIEW_DE_MORGAN_NORMAL_BUTT, wxEmptyString,
+ KiBitmap( morgan1_xpm ),
+ _( "Show as \"De Morgan\" normal part" ),
+ wxITEM_CHECK );
+
+ m_mainToolBar->AddTool( ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT, wxEmptyString,
+ KiBitmap( morgan2_xpm ),
+ _( "Show as \"De Morgan\" convert part" ),
+ wxITEM_CHECK );
+
+ m_mainToolBar->AddSeparator();
+
+ m_selpartBox = new wxComboBox( m_mainToolBar, ID_LIBVIEW_SELECT_PART_NUMBER,
+ wxEmptyString, wxDefaultPosition,
+ wxSize( 150, -1 ), 0, NULL, wxCB_READONLY );
+ m_mainToolBar->AddControl( m_selpartBox );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_LIBVIEW_VIEWDOC, wxEmptyString,
+ KiBitmap( datasheet_xpm ),
+ _( "View component documents" ) );
+ m_mainToolBar->EnableTool( ID_LIBVIEW_VIEWDOC, false );
+
+ if( IsModal() )
+ {
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_LIBVIEW_CMP_EXPORT_TO_SCHEMATIC,
+ wxEmptyString, KiBitmap( export_xpm ),
+ _( "Insert component in schematic" ) );
+ }
+
+ // after adding the buttons to the toolbar, must call Realize() to
+ // reflect the changes
+ m_mainToolBar->Realize();
+ }
+
+ if( m_libraryName.size() && m_entryName.size() )
+ {
+ if( PART_LIB* lib = Prj().SchLibs()->FindLibrary( m_libraryName ) )
+ {
+ part = lib->FindPart( m_entryName );
+
+ if( part && part->HasConversion() )
+ asdeMorgan = true;
+
+ entry = lib->FindEntry( m_entryName );
+ }
+ }
+
+ // Must be AFTER Realize():
+ m_mainToolBar->EnableTool( ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT, asdeMorgan );
+ m_mainToolBar->EnableTool( ID_LIBVIEW_DE_MORGAN_NORMAL_BUTT, asdeMorgan );
+
+ if( asdeMorgan )
+ {
+ bool normal = m_convert <= 1;
+ m_mainToolBar->ToggleTool( ID_LIBVIEW_DE_MORGAN_NORMAL_BUTT,normal );
+ m_mainToolBar->ToggleTool( ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT, !normal );
+ }
+ else
+ {
+ m_mainToolBar->ToggleTool( ID_LIBVIEW_DE_MORGAN_NORMAL_BUTT, true );
+ m_mainToolBar->ToggleTool( ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT, false );
+ }
+
+ int parts_count = 1;
+
+ if( part )
+ parts_count = std::max( part->GetUnitCount(), 1 );
+
+ m_selpartBox->Clear();
+
+ for( int ii = 0; ii < parts_count; ii++ )
+ {
+ wxString msg = wxString::Format( _( "Unit %c" ), 'A' + ii );
+ m_selpartBox->Append( msg );
+ }
+
+ m_selpartBox->SetSelection( m_unit > 0 ? m_unit - 1 : 0 );
+ m_selpartBox->Enable( parts_count > 1 );
+
+ m_mainToolBar->EnableTool( ID_LIBVIEW_VIEWDOC, entry && !!entry->GetDocFileName() );
+
+ m_mainToolBar->Refresh();
+}
+
+
+void LIB_VIEW_FRAME::ReCreateVToolbar()
+{
+}
+
+
+// Virtual function
+void LIB_VIEW_FRAME::ReCreateMenuBar( void )
+{
+ // Create and try to get the current menubar
+ wxMenuBar* menuBar = GetMenuBar();
+
+ if( !menuBar )
+ menuBar = new wxMenuBar();
+
+ // Delete all existing menus so they can be rebuilt.
+ // This allows language changes of the menu text on the fly.
+ menuBar->Freeze();
+
+ while( menuBar->GetMenuCount() )
+ delete menuBar->Remove( 0 );
+
+ // Recreate all menus:
+ wxString text;
+
+ // Menu File:
+ wxMenu* fileMenu = new wxMenu;
+
+ // Active library selection
+ AddMenuItem( fileMenu, ID_LIBVIEW_SELECT_LIB, _("Set Current Library"),
+ _( "Select library to be displayed" ),
+ KiBitmap( open_library_xpm ) );
+ fileMenu->AppendSeparator();
+
+ // Close viewer
+ AddMenuItem( fileMenu, wxID_EXIT,
+ _( "Cl&ose" ),
+ _( "Close schematic component viewer" ),
+ KiBitmap( exit_xpm ) );
+
+ // View menu
+ wxMenu* viewMenu = new wxMenu;
+
+ text = AddHotkeyName( _( "Zoom &In" ), g_Viewlib_Hokeys_Descr,
+ HK_ZOOM_IN, IS_ACCELERATOR );
+ AddMenuItem( viewMenu, ID_ZOOM_IN, text, HELP_ZOOM_IN, KiBitmap( zoom_in_xpm ) );
+
+ text = AddHotkeyName( _( "Zoom &Out" ), g_Viewlib_Hokeys_Descr,
+ HK_ZOOM_OUT, IS_ACCELERATOR );
+ AddMenuItem( viewMenu, ID_ZOOM_OUT, text, HELP_ZOOM_OUT, KiBitmap( zoom_out_xpm ) );
+
+ text = AddHotkeyName( _( "&Fit on Screen" ), g_Viewlib_Hokeys_Descr,
+ HK_ZOOM_AUTO );
+ AddMenuItem( viewMenu, ID_ZOOM_PAGE, text, HELP_ZOOM_FIT,
+ KiBitmap( zoom_fit_in_page_xpm ) );
+
+ text = AddHotkeyName( _( "&Redraw" ), g_Viewlib_Hokeys_Descr, HK_ZOOM_REDRAW );
+ AddMenuItem( viewMenu, ID_ZOOM_REDRAW, text,
+ HELP_ZOOM_REDRAW, KiBitmap( zoom_redraw_xpm ) );
+
+ // Menu Help:
+ wxMenu* helpMenu = new wxMenu;
+
+ // Version info
+ AddHelpVersionInfoMenuEntry( helpMenu );
+
+ // Contents
+ AddMenuItem( helpMenu, wxID_HELP,
+ _( "Eeschema &Manual" ),
+ _( "Open Eeschema manual" ),
+ KiBitmap( online_help_xpm ) );
+
+ AddMenuItem( helpMenu, wxID_INDEX,
+ _( "&Getting Started in KiCad" ),
+ _( "Open the \"Getting Started in KiCad\" guide for beginners" ),
+ KiBitmap( help_xpm ) );
+
+ // About Pcbnew
+ helpMenu->AppendSeparator();
+ AddMenuItem( helpMenu, wxID_ABOUT,
+ _( "&About Eeschema" ),
+ _( "About Eeschema schematic designer" ),
+ KiBitmap( info_xpm ) );
+
+ // Append menus to the menubar
+ menuBar->Append( fileMenu, _( "&File" ) );
+
+ menuBar->Append( viewMenu, _( "&View" ) );
+ menuBar->Append( helpMenu, _( "&Help" ) );
+
+ menuBar->Thaw();
+
+ // Associate the menu bar with the frame, if no previous menubar
+ if( GetMenuBar() == NULL )
+ SetMenuBar( menuBar );
+ else
+ menuBar->Refresh();
+}
diff --git a/eeschema/transform.cpp b/eeschema/transform.cpp
new file mode 100644
index 0000000..53aac2d
--- /dev/null
+++ b/eeschema/transform.cpp
@@ -0,0 +1,148 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <macros.h>
+#include <trigo.h>
+#include <transform.h>
+#include <common.h>
+#include <class_eda_rect.h>
+
+
+TRANSFORM& TRANSFORM::operator=( const TRANSFORM& aTransform )
+{
+ if( this == &aTransform ) // Check for self assingnemt;
+ return *this;
+
+ x1 = aTransform.x1;
+ y1 = aTransform.y1;
+ x2 = aTransform.x2;
+ y2 = aTransform.y2;
+ return *this;
+}
+
+
+bool TRANSFORM::operator==( const TRANSFORM& aTransform ) const
+{
+ return ( x1 == aTransform.x1 &&
+ y1 == aTransform.y1 &&
+ x2 == aTransform.x2 &&
+ y2 == aTransform.y2 );
+}
+
+
+wxPoint TRANSFORM::TransformCoordinate( const wxPoint& aPoint ) const
+{
+ return wxPoint( ( x1 * aPoint.x ) + ( y1 * aPoint.y ),
+ ( x2 * aPoint.x ) + ( y2 * aPoint.y ) );
+}
+
+EDA_RECT TRANSFORM::TransformCoordinate( const EDA_RECT& aRect ) const
+{
+ EDA_RECT rect;
+ rect.SetOrigin( TransformCoordinate( aRect.GetOrigin() ) );
+ rect.SetEnd( TransformCoordinate( aRect.GetEnd() ) );
+ return rect;
+}
+
+/*
+* Calculate the Inverse mirror/rotation transform.
+*/
+TRANSFORM TRANSFORM::InverseTransform( ) const
+{
+ int invx1;
+ int invx2;
+ int invy1;
+ int invy2;
+
+ /* Calculates the inverse matrix coeffs:
+ * for a matrix m{x1, x2, y1, y2}
+ * the inverse matrix is 1/(x1*y2 -x2*y1) m{y2,-x2,-y1,x1)
+ */
+ int det = x1*y2 -x2*y1; // Is never null, because the inverse matrix exists
+ invx1 = y2/det;
+ invx2 = -x2/det;
+ invy1 = -y1/det;
+ invy2 = x1/det;
+
+ TRANSFORM invtransform( invx1, invy1, invx2, invy2 );
+ return invtransform;
+}
+
+
+bool TRANSFORM::MapAngles( int* aAngle1, int* aAngle2 ) const
+{
+ wxCHECK_MSG( aAngle1 != NULL && aAngle2 != NULL, false,
+ wxT( "Cannot map NULL point angles." ) );
+
+ int Angle, Delta;
+ double x, y, t;
+ bool swap = false;
+
+ Delta = *aAngle2 - *aAngle1;
+ if( Delta >= 1800 )
+ {
+ *aAngle1 -= 1;
+ *aAngle2 += 1;
+ }
+
+ x = cos( DECIDEG2RAD( *aAngle1 ) );
+ y = sin( DECIDEG2RAD( *aAngle1 ) );
+ t = x * x1 + y * y1;
+ y = x * x2 + y * y2;
+ x = t;
+ *aAngle1 = KiROUND( RAD2DECIDEG( atan2( y, x ) ) );
+
+ x = cos( DECIDEG2RAD( *aAngle2 ) );
+ y = sin( DECIDEG2RAD( *aAngle2 ) );
+ t = x * x1 + y * y1;
+ y = x * x2 + y * y2;
+ x = t;
+ *aAngle2 = KiROUND( RAD2DECIDEG( atan2( y, x ) ) );
+
+ NORMALIZE_ANGLE_POS( *aAngle1 );
+ NORMALIZE_ANGLE_POS( *aAngle2 );
+ if( *aAngle2 < *aAngle1 )
+ *aAngle2 += 3600;
+
+ if( *aAngle2 - *aAngle1 > 1800 ) // Need to swap the two angles
+ {
+ Angle = (*aAngle1);
+ *aAngle1 = (*aAngle2);
+ *aAngle2 = Angle;
+
+ NORMALIZE_ANGLE_POS( *aAngle1 );
+ NORMALIZE_ANGLE_POS( *aAngle2 );
+ if( *aAngle2 < *aAngle1 )
+ *aAngle2 += 3600;
+ swap = true;
+ }
+
+ if( Delta >= 1800 )
+ {
+ *aAngle1 += 1;
+ *aAngle2 -= 1;
+ }
+
+ return swap;
+}
diff --git a/eeschema/transform.h b/eeschema/transform.h
new file mode 100644
index 0000000..7d220e0
--- /dev/null
+++ b/eeschema/transform.h
@@ -0,0 +1,106 @@
+/**
+ * @file transform.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2010 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef _TRANSFORM_H_
+#define _TRANSFORM_H_
+
+#include <wx/gdicmn.h>
+
+class EDA_RECT;
+
+/**
+ * Class for tranforming drawing coordinates for a wxDC device context.
+ *
+ * This probably should be a base class with all pure methods and a derived class
+ * named WXDC_TRANFORM be created. Then in the future if some new device context
+ * is used, a new transform could be derived from the base class and all the drawable
+ * objects would have to do is provide overloaded draw methods to use the new transorm.
+ */
+class TRANSFORM
+{
+public:
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+
+ /**
+ * The default construct creates a tranform that draws object is the normal orientation.
+ */
+ TRANSFORM() : x1( 1 ), y1( 0 ), x2( 0 ), y2( -1 ) {}
+
+ TRANSFORM( int x1, int y1, int x2, int y2 ) : x1( x1 ), y1( y1 ), x2( x2 ), y2( y2 ) {}
+
+ TRANSFORM& operator=( const TRANSFORM& aTransform );
+
+ bool operator==( const TRANSFORM& aTransform ) const;
+
+ bool operator!=( const TRANSFORM& aTransform ) const { return !( *this == aTransform ); }
+
+ /**
+ * Calculate a new coordinate according to the mirror/rotation transform.
+ * Useful to calculate actual coordinates of a point
+ * from coordinates relative to a component
+ * which are given for a non rotated, non mirrored item
+ * @param aPoint = The position to transform
+ * @return The transformed coordinate.
+ */
+ wxPoint TransformCoordinate( const wxPoint& aPoint ) const;
+
+ /**
+ * Calculate a new rect according to the mirror/rotation transform.
+ * Useful to calculate actual coordinates of a point
+ * from coordinates relative to a component
+ * which are given for a non rotated, non mirrored item
+ * @param aRect = The rectangle to transform
+ * @return The transformed rectangle.
+ */
+ EDA_RECT TransformCoordinate( const EDA_RECT& aRect ) const;
+
+ /**
+ * Calculate the Inverse mirror/rotation transform.
+ * Useful to calculate coordinates relative to a component
+ * which must be for a non rotated, non mirrored item
+ * from the actual coordinate.
+ * @return The inverse transform.
+ */
+ TRANSFORM InverseTransform( ) const;
+
+ /**
+ * Calculate new angles according to the transform.
+ *
+ * @param aAngle1 = The first angle to transform
+ * @param aAngle2 = The second angle to transform
+ * @return True if the angles were swapped during the transform.
+ */
+ bool MapAngles( int* aAngle1, int* aAngle2 ) const;
+};
+
+
+#endif // _TRANSFORM_H_
diff --git a/eeschema/viewlib_frame.cpp b/eeschema/viewlib_frame.cpp
new file mode 100644
index 0000000..ddcefa9
--- /dev/null
+++ b/eeschema/viewlib_frame.cpp
@@ -0,0 +1,595 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file viewlib_frame.cpp
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <pgm_base.h>
+#include <eeschema_id.h>
+#include <class_drawpanel.h>
+#include <schframe.h>
+#include <msgpanel.h>
+
+#include <general.h>
+#include <viewlib_frame.h>
+#include <class_library.h>
+#include <hotkeys.h>
+#include <dialog_helpers.h>
+
+
+// Save previous component library viewer state.
+wxString LIB_VIEW_FRAME::m_libraryName;
+wxString LIB_VIEW_FRAME::m_entryName;
+
+int LIB_VIEW_FRAME::m_unit = 1;
+int LIB_VIEW_FRAME::m_convert = 1;
+
+
+BEGIN_EVENT_TABLE( LIB_VIEW_FRAME, EDA_DRAW_FRAME )
+ // Window events
+ EVT_CLOSE( LIB_VIEW_FRAME::OnCloseWindow )
+ EVT_SIZE( LIB_VIEW_FRAME::OnSize )
+ EVT_ACTIVATE( LIB_VIEW_FRAME::OnActivate )
+
+ // Toolbar events
+ EVT_TOOL_RANGE( ID_LIBVIEW_NEXT, ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT,
+ LIB_VIEW_FRAME::Process_Special_Functions )
+
+ EVT_TOOL( ID_LIBVIEW_CMP_EXPORT_TO_SCHEMATIC, LIB_VIEW_FRAME::ExportToSchematicLibraryPart )
+ EVT_COMBOBOX( ID_LIBVIEW_SELECT_PART_NUMBER, LIB_VIEW_FRAME::Process_Special_Functions )
+
+ // listbox events
+ EVT_LISTBOX( ID_LIBVIEW_LIB_LIST, LIB_VIEW_FRAME::ClickOnLibList )
+ EVT_LISTBOX( ID_LIBVIEW_CMP_LIST, LIB_VIEW_FRAME::ClickOnCmpList )
+ EVT_LISTBOX_DCLICK( ID_LIBVIEW_CMP_LIST, LIB_VIEW_FRAME::DClickOnCmpList )
+
+ // Menu (and/or hotkey) events
+ EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_EXIT, LIB_VIEW_FRAME::CloseLibraryViewer )
+ EVT_MENU( ID_SET_RELATIVE_OFFSET, LIB_VIEW_FRAME::OnSetRelativeOffset )
+
+END_EVENT_TABLE()
+
+
+/* Note:
+ * LIB_VIEW_FRAME can be build in "modal mode", or as a usual frame.
+ * In modal mode:
+ * a tool to export the selected symbol is shown in the toolbar
+ * the style is wxSTAY_ON_TOP on Windows and wxFRAME_FLOAT_ON_PARENT on unix
+ * reason:
+ * the parent is usually the kicad window manager (not easy to change)
+ * On windows, when the frame with stype wxFRAME_FLOAT_ON_PARENT is displayed
+ * its parent frame is brought to the foreground, on the top of the calling frame.
+ * and stays displayed when closing the LIB_VIEW_FRAME frame.
+ * this issue does not happen on unix.
+ *
+ * So we use wxSTAY_ON_TOP on Windows, and wxFRAME_FLOAT_ON_PARENT on unix
+ * to simulate a dialog called by ShowModal.
+ */
+
+#define LIB_VIEW_FRAME_NAME wxT( "ViewlibFrame" )
+
+LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
+ PART_LIB* aLibrary ) :
+ SCH_BASE_FRAME( aKiway, aParent, aFrameType, _( "Library Browser" ),
+ wxDefaultPosition, wxDefaultSize,
+ aFrameType==FRAME_SCH_VIEWER_MODAL ?
+#ifdef __WINDOWS__
+ KICAD_DEFAULT_DRAWFRAME_STYLE | wxSTAY_ON_TOP :
+#else
+ KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT :
+#endif
+ KICAD_DEFAULT_DRAWFRAME_STYLE,
+ LIB_VIEW_FRAME_NAME )
+{
+ wxASSERT( aFrameType == FRAME_SCH_VIEWER || aFrameType == FRAME_SCH_VIEWER_MODAL );
+
+ if( aFrameType == FRAME_SCH_VIEWER_MODAL )
+ SetModal( true );
+
+ m_configFrameName = LIB_VIEW_FRAME_NAME;
+
+ // Give an icon
+ wxIcon icon;
+ icon.CopyFromBitmap( KiBitmap( library_browse_xpm ) );
+ SetIcon( icon );
+
+ m_hotkeysDescrList = g_Viewlib_Hokeys_Descr;
+ m_cmpList = NULL;
+ m_libList = NULL;
+ m_listPowerCmpOnly = false;
+
+ SetScreen( new SCH_SCREEN( aKiway ) );
+ GetScreen()->m_Center = true; // Axis origin centered on screen.
+ LoadSettings( config() );
+
+ SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
+
+ // Initialize grid id to the default value (50 mils):
+ m_LastGridSizeId = ID_POPUP_GRID_LEVEL_50 - ID_POPUP_GRID_LEVEL_1000;
+ GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
+
+ // Menu bar is not mandatory: uncomment/comment the next line
+ // to add/remove the menubar
+ ReCreateMenuBar();
+ ReCreateHToolbar();
+ ReCreateVToolbar();
+
+ if( !aLibrary )
+ {
+ // Creates the libraries window display
+ m_libList = new wxListBox( this, ID_LIBVIEW_LIB_LIST,
+ wxPoint( 0, 0 ), wxSize(m_libListWidth, -1),
+ 0, NULL, wxLB_HSCROLL );
+ }
+ else
+ {
+ m_libraryName = aLibrary->GetName();
+ m_entryName.Clear();
+ m_unit = 1;
+ m_convert = 1;
+ m_libListWidth = 0;
+ }
+
+ // Creates the component window display
+ m_cmpList = new wxListBox( this, ID_LIBVIEW_CMP_LIST,
+ wxPoint( 0, 0 ), wxSize(m_cmpListWidth, -1),
+ 0, NULL, wxLB_HSCROLL );
+
+ if( m_libList )
+ ReCreateListLib();
+
+ DisplayLibInfos();
+
+ m_auimgr.SetManagedWindow( this );
+
+ EDA_PANEINFO horiz;
+ horiz.HorizontalToolbarPane();
+
+ EDA_PANEINFO vert;
+ vert.VerticalToolbarPane();
+
+ EDA_PANEINFO info;
+ info.InfoToolbarPane();
+
+ EDA_PANEINFO mesg;
+ mesg.MessageToolbarPane();
+
+
+ // Manage main toolbal
+ m_auimgr.AddPane( m_mainToolBar,
+ wxAuiPaneInfo( horiz ).Name( wxT ("m_mainToolBar" ) ).Top().Row( 0 ) );
+
+ // Manage the left window (list of libraries)
+ if( m_libList )
+ m_auimgr.AddPane( m_libList, wxAuiPaneInfo( info ).Name( wxT( "m_libList" ) ).
+ Left().Row( 0 ) );
+
+ // Manage the list of components)
+ m_auimgr.AddPane( m_cmpList,
+ wxAuiPaneInfo( info ).Name( wxT( "m_cmpList" ) ).
+ Left().Row( 1 ) );
+
+ // Manage the draw panel
+ m_auimgr.AddPane( m_canvas,
+ wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
+
+ // Manage the message panel
+ m_auimgr.AddPane( m_messagePanel,
+ wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );
+
+ /* Now the minimum windows are fixed, set library list
+ * and component list of the previous values from last viewlib use
+ */
+ if( m_libList )
+ {
+ m_auimgr.GetPane( m_libList ).MinSize( wxSize( 80, -1) );
+ m_auimgr.GetPane( m_libList ).BestSize( wxSize(m_libListWidth, -1) );
+ }
+
+ m_auimgr.GetPane( m_cmpList ).MinSize( wxSize( 80, -1) );
+ m_auimgr.GetPane( m_cmpList ).BestSize(wxSize(m_cmpListWidth, -1) );
+
+ m_auimgr.Update();
+
+ // Now Drawpanel is sized, we can use BestZoom to show the component (if any)
+#ifdef USE_WX_GRAPHICS_CONTEXT
+ GetScreen()->SetZoom( BestZoom() );
+#else
+ Zoom_Automatique( false );
+#endif
+
+ if( !IsModal() ) // For modal mode, calling ShowModal() will show this frame
+ {
+ Raise();
+ Show( true );
+ }
+}
+
+
+LIB_VIEW_FRAME::~LIB_VIEW_FRAME()
+{
+}
+
+
+void LIB_VIEW_FRAME::OnCloseWindow( wxCloseEvent& Event )
+{
+ if( !IsModal() )
+ {
+ Destroy();
+ }
+ else if( !IsDismissed() )
+ {
+ // only dismiss modal frame if not already dismissed.
+ DismissModal( false );
+
+ // Modal frame will be destroyed by the calling function.
+ }
+}
+
+
+void LIB_VIEW_FRAME::OnSize( wxSizeEvent& SizeEv )
+{
+ if( m_auimgr.GetManagedWindow() )
+ m_auimgr.Update();
+
+ SizeEv.Skip();
+}
+
+
+void LIB_VIEW_FRAME::OnSetRelativeOffset( wxCommandEvent& event )
+{
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ UpdateStatusBar();
+}
+
+
+double LIB_VIEW_FRAME::BestZoom()
+{
+ /* Please, note: wxMSW before version 2.9 seems have
+ * problems with zoom values < 1 ( i.e. userscale > 1) and needs to be patched:
+ * edit file <wxWidgets>/src/msw/dc.cpp
+ * search for line static const int VIEWPORT_EXTENT = 1000;
+ * and replace by static const int VIEWPORT_EXTENT = 10000;
+ */
+
+ LIB_PART* part = NULL;
+ double bestzoom = 16.0; // default value for bestzoom
+ PART_LIB* lib = Prj().SchLibs()->FindLibrary( m_libraryName );
+
+ if( lib )
+ part = lib->FindPart( m_entryName );
+
+ if( !part )
+ {
+ SetScrollCenterPosition( wxPoint( 0, 0 ) );
+ return bestzoom;
+ }
+
+ wxSize size = m_canvas->GetClientSize();
+
+ EDA_RECT boundingBox = part->GetBoundingBox( m_unit, m_convert );
+
+ // Reserve a 10% margin around component bounding box.
+ double margin_scale_factor = 0.8;
+ double zx =(double) boundingBox.GetWidth() /
+ ( margin_scale_factor * (double)size.x );
+ double zy = (double) boundingBox.GetHeight() /
+ ( margin_scale_factor * (double)size.y);
+
+ // Calculates the best zoom
+ bestzoom = std::max( zx, zy );
+
+ // keep it >= minimal existing zoom (can happen for very small components
+ // like small power symbols
+ if( bestzoom < GetScreen()->m_ZoomList[0] )
+ bestzoom = GetScreen()->m_ZoomList[0];
+
+ SetScrollCenterPosition( boundingBox.Centre() );
+
+ return bestzoom;
+}
+
+
+void LIB_VIEW_FRAME::ReCreateListLib()
+{
+ if( !m_libList )
+ return;
+
+ m_libList->Clear();
+
+ wxArrayString libs = Prj().SchLibs()->GetLibraryNames();
+
+ // Remove not allowed libs from main list, if the allowed lib list is not empty
+ if( m_allowedLibs.GetCount() )
+ {
+ for( unsigned ii = 0; ii < libs.GetCount(); )
+ {
+ if( m_allowedLibs.Index( libs[ii] ) == wxNOT_FOUND )
+ libs.RemoveAt( ii );
+ else
+ ii++;
+ }
+ }
+
+ // Remove libs which have no power components, if this filter is activated
+ if( m_listPowerCmpOnly )
+ {
+ for( unsigned ii = 0; ii < libs.GetCount(); )
+ {
+ PART_LIB* lib = Prj().SchLibs()->FindLibrary( libs[ii] );
+
+ if( lib && !lib->HasPowerParts() )
+ libs.RemoveAt( ii );
+ else
+ ii++;
+ }
+ }
+
+ m_libList->Append( libs );
+
+ // Search for a previous selection:
+ int index = m_libList->FindString( m_libraryName );
+
+ if( index != wxNOT_FOUND )
+ {
+ m_libList->SetSelection( index, true );
+ }
+ else
+ {
+ // If not found, clear current library selection because it can be
+ // deleted after a config change.
+ m_libraryName = wxEmptyString;
+ m_entryName = wxEmptyString;
+ m_unit = 1;
+ m_convert = 1;
+ }
+
+ ReCreateListCmp();
+ ReCreateHToolbar();
+ DisplayLibInfos();
+ m_canvas->Refresh();
+}
+
+
+void LIB_VIEW_FRAME::ReCreateListCmp()
+{
+ if( m_cmpList == NULL )
+ return;
+
+ m_cmpList->Clear();
+
+ PART_LIB* lib = Prj().SchLibs()->FindLibrary( m_libraryName );
+
+ if( !lib )
+ {
+ m_libraryName = wxEmptyString;
+ m_entryName = wxEmptyString;
+ m_convert = 1;
+ m_unit = 1;
+ return;
+ }
+
+ wxArrayString nameList;
+
+ if( m_listPowerCmpOnly )
+ lib->GetEntryTypePowerNames( nameList );
+ else
+ lib->GetEntryNames( nameList );
+
+ m_cmpList->Append( nameList );
+
+ int index = m_cmpList->FindString( m_entryName );
+
+ if( index == wxNOT_FOUND )
+ {
+ m_entryName = wxEmptyString;
+ m_convert = 1;
+ m_unit = 1;
+ }
+ else
+ {
+ m_cmpList->SetSelection( index, true );
+ }
+}
+
+
+void LIB_VIEW_FRAME::ClickOnLibList( wxCommandEvent& event )
+{
+ int ii = m_libList->GetSelection();
+
+ if( ii < 0 )
+ return;
+
+ SetSelectedLibrary( m_libList->GetString( ii ) );
+}
+
+
+void LIB_VIEW_FRAME::SetSelectedLibrary( const wxString& aLibraryName )
+{
+ if( m_libraryName == aLibraryName )
+ return;
+
+ m_libraryName = aLibraryName;
+ ReCreateListCmp();
+ m_canvas->Refresh();
+ DisplayLibInfos();
+ ReCreateHToolbar();
+
+ // Ensure the corresponding line in m_libList is selected
+ // (which is not necessary the case if SetSelectedLibrary is called
+ // by an other caller than ClickOnLibList.
+ m_libList->SetStringSelection( m_libraryName, true );
+}
+
+
+void LIB_VIEW_FRAME::ClickOnCmpList( wxCommandEvent& event )
+{
+ int ii = m_cmpList->GetSelection();
+
+ if( ii < 0 )
+ return;
+
+ SetSelectedComponent( m_cmpList->GetString( ii ) );
+}
+
+
+void LIB_VIEW_FRAME::SetSelectedComponent( const wxString& aComponentName )
+{
+ if( m_entryName.CmpNoCase( aComponentName ) != 0 )
+ {
+ m_entryName = aComponentName;
+
+ // Ensure the corresponding line in m_cmpList is selected
+ // (which is not necessarily the case if SetSelectedComponent is called
+ // by another caller than ClickOnCmpList.
+ m_cmpList->SetStringSelection( aComponentName, true );
+ DisplayLibInfos();
+ m_unit = 1;
+ m_convert = 1;
+ Zoom_Automatique( false );
+ ReCreateHToolbar();
+ m_canvas->Refresh();
+ }
+}
+
+
+void LIB_VIEW_FRAME::DClickOnCmpList( wxCommandEvent& event )
+{
+ if( IsModal() )
+ {
+ ExportToSchematicLibraryPart( event );
+
+ // The schematic editor might not be the parent of the library viewer.
+ // It could be a python window.
+ SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
+
+ if( schframe )
+ {
+ // Prevent the double click from being as a single click in the parent
+ // window which would cause the part to be parked rather than staying
+ // in drag mode.
+ schframe->SkipNextLeftButtonReleaseEvent();
+ }
+ }
+}
+
+
+void LIB_VIEW_FRAME::ExportToSchematicLibraryPart( wxCommandEvent& event )
+{
+ int ii = m_cmpList->GetSelection();
+
+ if( ii >= 0 )
+ {
+ wxString part_name = m_cmpList->GetString( ii );
+
+ // a selection was made, pass true
+ DismissModal( true, part_name );
+ }
+ else
+ {
+ // no selection was made, pass false
+ DismissModal( false );
+ }
+
+ Close( true );
+}
+
+
+#define LIBLIST_WIDTH_KEY wxT( "ViewLiblistWidth" )
+#define CMPLIST_WIDTH_KEY wxT( "ViewCmplistWidth" )
+
+// Currently, the library viewer has no dialog to change the background color
+// of the draw canvas. Therefore the background color is here just
+// in case of this option is added to some library viewer config dialog
+#define LIBVIEW_BGCOLOR wxT( "LibviewBgColor" )
+
+
+void LIB_VIEW_FRAME::LoadSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::LoadSettings( aCfg );
+
+ SetGridColor( GetLayerColor( LAYER_GRID ) );
+ SetDrawBgColor( GetLayerColor( LAYER_BACKGROUND ) );
+
+ aCfg->Read( LIBLIST_WIDTH_KEY, &m_libListWidth, 150 );
+ aCfg->Read( CMPLIST_WIDTH_KEY, &m_cmpListWidth, 150 );
+
+ // Set parameters to a reasonable value.
+ if( m_libListWidth > m_FrameSize.x/2 )
+ m_libListWidth = m_FrameSize.x/2;
+
+ if( m_cmpListWidth > m_FrameSize.x/2 )
+ m_cmpListWidth = m_FrameSize.x/2;
+}
+
+
+void LIB_VIEW_FRAME::SaveSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::SaveSettings( aCfg );
+
+ if( m_libListWidth && m_libList )
+ {
+ m_libListWidth = m_libList->GetSize().x;
+ aCfg->Write( LIBLIST_WIDTH_KEY, m_libListWidth );
+ }
+
+ m_cmpListWidth = m_cmpList->GetSize().x;
+ aCfg->Write( CMPLIST_WIDTH_KEY, m_cmpListWidth );
+}
+
+
+void LIB_VIEW_FRAME::OnActivate( wxActivateEvent& event )
+{
+ EDA_DRAW_FRAME::OnActivate( event );
+
+ if( m_libList )
+ ReCreateListLib();
+
+ DisplayLibInfos();
+}
+
+
+void LIB_VIEW_FRAME::CloseLibraryViewer( wxCommandEvent& event )
+{
+ Close();
+}
+
+void LIB_VIEW_FRAME::SetFilter( const SCHLIB_FILTER* aFilter )
+{
+ m_listPowerCmpOnly = false;
+ m_allowedLibs.Clear();
+
+ if( aFilter )
+ {
+ m_allowedLibs = aFilter->GetAllowedLibList();
+ m_listPowerCmpOnly = aFilter->GetFilterPowerParts();
+ }
+
+ ReCreateListLib();
+}
diff --git a/eeschema/viewlib_frame.h b/eeschema/viewlib_frame.h
new file mode 100644
index 0000000..ab7ecb2
--- /dev/null
+++ b/eeschema/viewlib_frame.h
@@ -0,0 +1,188 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2014 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file viewlib_frame.h
+ */
+
+#ifndef LIBVIEWFRM_H_
+#define LIBVIEWFRM_H_
+
+
+#include <wx/gdicmn.h>
+
+#include <sch_base_frame.h>
+#include <class_sch_screen.h>
+
+class wxListBox;
+class PART_LIB;
+class SCHLIB_FILTER;
+
+
+/**
+ * Component library viewer main window.
+ */
+class LIB_VIEW_FRAME : public SCH_BASE_FRAME
+{
+public:
+
+ /**
+ * Constructor
+ * @param aKiway
+ * @param aParent = the parent frame
+ * @param aFrameType must be given either FRAME_SCH_LIB_VIEWER or
+ * FRAME_SCH_LIB_VIEWER_MODAL
+ * @param aLibrary = the library to open when starting (default = NULL)
+ */
+ LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent,
+ FRAME_T aFrameType, PART_LIB* aLibrary = NULL );
+
+ ~LIB_VIEW_FRAME();
+
+ void OnSize( wxSizeEvent& event );
+
+ /**
+ * Function ReCreateListLib
+ *
+ * Creates or recreates the list of current loaded libraries.
+ * This list is sorted, with the library cache always at end of the list
+ */
+ void ReCreateListLib();
+
+ void ReCreateListCmp();
+ void Process_Special_Functions( wxCommandEvent& event );
+ void DisplayLibInfos();
+ void RedrawActiveWindow( wxDC* DC, bool EraseBg );
+ void OnCloseWindow( wxCloseEvent& Event );
+ void CloseLibraryViewer( wxCommandEvent& event );
+ void ReCreateHToolbar();
+ void ReCreateVToolbar();
+ void ReCreateMenuBar();
+
+ void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
+ double BestZoom();
+ void ClickOnLibList( wxCommandEvent& event );
+ void ClickOnCmpList( wxCommandEvent& event );
+ void OnSetRelativeOffset( wxCommandEvent& event );
+
+ bool GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey = 0 );
+
+ ///> @copydoc EDA_DRAW_FRAME::GetHotKeyDescription()
+ EDA_HOTKEY* GetHotKeyDescription( int aCommand ) const;
+
+ /**
+ * Function OnHotKey
+ * handle hot key events.
+ * <p?
+ * Some commands are relative to the item under the mouse cursor. Commands are
+ * case insensitive
+ * </p>
+ */
+ bool OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem = NULL );
+
+ void LoadSettings( wxConfigBase* aCfg );
+ void SaveSettings( wxConfigBase* aCfg );
+
+ /**
+ * set a filter to display only libraries and/or components
+ * which match the filter
+ *
+ * @param aFilter is a filter to pass the allowed library name list
+ * and/or some other filter
+ * see SCH_BASE_FRAME::SelectComponentFromLibrary() for details.
+ * if aFilter == NULL, remove all filtering
+ */
+ void SetFilter( const SCHLIB_FILTER* aFilter );
+
+ /**
+ * Set the selected library in the library window.
+ *
+ * @param aLibName name of the library to be selected.
+ */
+ void SetSelectedLibrary( const wxString& aLibName );
+
+ /**
+ * Set the selected component.
+ *
+ * @param aComponentName : the name of the component to be selected.
+ */
+ void SetSelectedComponent( const wxString& aComponentName );
+
+ // Accessors:
+ void SetUnit( int aUnit ) { m_unit = aUnit; }
+ int GetUnit( void ) { return m_unit; }
+
+ void SetConvert( int aConvert ) { m_convert = aConvert; }
+ int GetConvert( void ) { return m_convert; }
+
+private:
+ /**
+ * Function OnActivate
+ * is called when the frame frame is activate to reload the libraries and component lists
+ * that can be changed by the schematic editor or the library editor.
+ */
+ virtual void OnActivate( wxActivateEvent& event );
+
+ void SelectCurrentLibrary();
+ void SelectAndViewLibraryPart( int option );
+
+ /**
+ * Function ExportToSchematicLibraryPart
+ * exports the current component to schematic and close the library browser.
+ */
+ void ExportToSchematicLibraryPart( wxCommandEvent& event );
+ void ViewOneLibraryContent( PART_LIB* Lib, int Flag );
+ bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
+ void DClickOnCmpList( wxCommandEvent& event );
+
+// Private members:
+ wxComboBox* m_selpartBox;
+
+ // List of libraries (for selection )
+ wxListBox* m_libList; // The list of libs
+ int m_libListWidth; // Last width of the window
+
+ // List of components in the selected library
+ wxListBox* m_cmpList; // The list of components
+ int m_cmpListWidth; // Last width of the window
+
+ // Filters to build list of libs/list of parts
+ bool m_listPowerCmpOnly;
+ wxArrayString m_allowedLibs;
+
+ // TODO(hzeller): looks like these members were chosen to be static to survive different
+ // instances of this browser and communicate it to the next instance. This looks like an
+ // ugly hack, and should be solved differently.
+ static wxString m_libraryName;
+
+ static wxString m_entryName;
+
+ static int m_unit;
+ static int m_convert;
+
+ DECLARE_EVENT_TABLE()
+};
+
+#endif // LIBVIEWFRM_H_
diff --git a/eeschema/viewlibs.cpp b/eeschema/viewlibs.cpp
new file mode 100644
index 0000000..c71ea9d
--- /dev/null
+++ b/eeschema/viewlibs.cpp
@@ -0,0 +1,310 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file viewlibs.cpp
+ */
+
+#include <fctsys.h>
+#include <kiway.h>
+#include <gr_basic.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <eda_doc.h>
+#include <class_sch_screen.h>
+
+#include <general.h>
+#include <viewlib_frame.h>
+#include <eeschema_id.h>
+#include <class_library.h>
+#include <dialog_helpers.h>
+
+
+#define NEXT_PART 1
+#define NEW_PART 0
+#define PREVIOUS_PART -1
+
+
+void LIB_VIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
+{
+ wxString msg;
+ LIB_ALIAS* entry;
+ int ii, id = event.GetId();
+
+ switch( id )
+ {
+ case ID_LIBVIEW_SELECT_LIB:
+ SelectCurrentLibrary();
+ break;
+
+ case ID_LIBVIEW_SELECT_PART:
+ SelectAndViewLibraryPart( NEW_PART );
+ break;
+
+ case ID_LIBVIEW_NEXT:
+ SelectAndViewLibraryPart( NEXT_PART );
+ break;
+
+ case ID_LIBVIEW_PREVIOUS:
+ SelectAndViewLibraryPart( PREVIOUS_PART );
+ break;
+
+ case ID_LIBVIEW_VIEWDOC:
+ entry = Prj().SchLibs()->FindLibraryEntry( m_entryName, m_libraryName );
+
+ if( entry && !entry->GetDocFileName().IsEmpty() )
+ {
+ SEARCH_STACK* lib_search = Prj().SchSearchS();
+
+ GetAssociatedDocument( this, entry->GetDocFileName(), lib_search );
+ }
+ break;
+
+ case ID_LIBVIEW_DE_MORGAN_NORMAL_BUTT:
+ m_mainToolBar->ToggleTool( ID_LIBVIEW_DE_MORGAN_NORMAL_BUTT, true );
+ m_mainToolBar->ToggleTool( ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT, false );
+ m_convert = 1;
+ m_canvas->Refresh();
+ break;
+
+ case ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT:
+ m_mainToolBar->ToggleTool( ID_LIBVIEW_DE_MORGAN_NORMAL_BUTT, false );
+ m_mainToolBar->ToggleTool( ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT, true );
+ m_convert = 2;
+ m_canvas->Refresh();
+ break;
+
+ case ID_LIBVIEW_SELECT_PART_NUMBER:
+ ii = m_selpartBox->GetCurrentSelection();
+ if( ii < 0 )
+ return;
+ m_unit = ii + 1;
+ m_canvas->Refresh();
+ break;
+
+ default:
+ msg << wxT( "LIB_VIEW_FRAME::Process_Special_Functions error: id = " ) << id;
+ DisplayError( this, msg );
+ break;
+ }
+}
+
+
+void LIB_VIEW_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
+{
+}
+
+
+bool LIB_VIEW_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu )
+{
+ return true;
+}
+
+
+void LIB_VIEW_FRAME::DisplayLibInfos()
+{
+ PART_LIBS* libs = Prj().SchLibs();
+
+ if( libs )
+ {
+ PART_LIB* lib = libs->FindLibrary( m_libraryName );
+
+ wxString msg = _( "Library Browser" );
+
+ msg += wxT( " [" );
+
+ if( lib )
+ msg += lib->GetFullFileName();
+ else
+ msg += _( "no library selected" );
+
+ msg += wxT( "]" );
+
+ SetTitle( msg );
+ }
+}
+
+
+void LIB_VIEW_FRAME::SelectCurrentLibrary()
+{
+ PART_LIB* Lib;
+
+ Lib = SelectLibraryFromList();
+
+ if( Lib )
+ {
+ m_entryName.Empty();
+ m_libraryName = Lib->GetName();
+ DisplayLibInfos();
+
+ if( m_libList )
+ {
+ ReCreateListCmp();
+ m_canvas->Refresh();
+ DisplayLibInfos();
+ ReCreateHToolbar();
+ int id = m_libList->FindString( m_libraryName.GetData() );
+
+ if( id >= 0 )
+ m_libList->SetSelection( id );
+ }
+ }
+}
+
+
+void LIB_VIEW_FRAME::SelectAndViewLibraryPart( int option )
+{
+ if( m_libraryName.IsEmpty() )
+ SelectCurrentLibrary();
+
+ if( m_libraryName.IsEmpty() )
+ return;
+
+ if( PART_LIBS* libs = Prj().SchLibs() )
+ {
+ if( PART_LIB* lib = libs->FindLibrary( m_libraryName ) )
+ {
+ if( m_entryName.IsEmpty() || option == NEW_PART )
+ {
+ ViewOneLibraryContent( lib, NEW_PART );
+ return;
+ }
+
+ if( lib->FindEntry( m_entryName ) )
+ {
+ if( option == NEXT_PART )
+ ViewOneLibraryContent( lib, NEXT_PART );
+
+ if( option == PREVIOUS_PART )
+ ViewOneLibraryContent( lib, PREVIOUS_PART );
+ }
+ }
+ }
+}
+
+
+void LIB_VIEW_FRAME::ViewOneLibraryContent( PART_LIB* Lib, int Flag )
+{
+ int NumOfParts = 0;
+
+ if( Lib )
+ NumOfParts = Lib->GetCount();
+
+ if( NumOfParts == 0 )
+ {
+ DisplayError( this, wxT( "No library or library is empty!" ) );
+ return;
+ }
+
+ LIB_ALIAS* entry;
+ wxString CmpName;
+
+ if( Flag == NEW_PART )
+ DisplayListComponentsInLib( Lib, CmpName, m_entryName );
+
+ if( Flag == NEXT_PART )
+ {
+ entry = Lib->GetNextEntry( m_entryName );
+
+ if( entry )
+ CmpName = entry->GetName();
+ }
+
+ if( Flag == PREVIOUS_PART )
+ {
+ entry = Lib->GetPreviousEntry( m_entryName );
+
+ if( entry )
+ CmpName = entry->GetName();
+ }
+
+ m_unit = 1;
+ m_convert = 1;
+
+ entry = Lib->FindEntry( CmpName );
+ m_entryName = CmpName;
+ DisplayLibInfos();
+ Zoom_Automatique( false );
+ m_canvas->Refresh( );
+
+ if( m_cmpList )
+ {
+ int id = m_cmpList->FindString( m_entryName.GetData() );
+ if( id >= 0 )
+ m_cmpList->SetSelection( id );
+ }
+
+ ReCreateHToolbar();
+}
+
+
+void LIB_VIEW_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
+{
+ LIB_ALIAS* entry = Prj().SchLibs()->FindLibraryEntry( m_entryName, m_libraryName );
+
+ if( !entry )
+ return;
+
+ LIB_PART* part = entry->GetPart();
+
+ if( !part )
+ return;
+
+ wxString msg;
+ wxString tmp;
+
+ m_canvas->DrawBackGround( DC );
+
+ if( !entry->IsRoot() )
+ {
+ // Temporarily change the name field text to reflect the alias name.
+ msg = entry->GetName();
+ tmp = part->GetName();
+
+ part->SetName( msg );
+
+ if( m_unit < 1 )
+ m_unit = 1;
+
+ if( m_convert < 1 )
+ m_convert = 1;
+ }
+ else
+ msg = _( "None" );
+
+ part->Draw( m_canvas, DC, wxPoint( 0, 0 ), m_unit, m_convert, GR_DEFAULT_DRAWMODE );
+
+ // Redraw the cursor
+ m_canvas->DrawCrossHair( DC );
+
+ if( !tmp.IsEmpty() )
+ part->SetName( tmp );
+
+ ClearMsgPanel();
+ AppendMsgPanel( _( "Part" ), part->GetName(), BLUE, 6 );
+ AppendMsgPanel( _( "Alias" ), msg, RED, 6 );
+ AppendMsgPanel( _( "Description" ), entry->GetDescription(), CYAN, 6 );
+ AppendMsgPanel( _( "Key words" ), entry->GetKeyWords(), DARKDARKGRAY );
+}
diff --git a/gerbview/CMakeLists.txt b/gerbview/CMakeLists.txt
new file mode 100644
index 0000000..1404964
--- /dev/null
+++ b/gerbview/CMakeLists.txt
@@ -0,0 +1,190 @@
+# the map generation creates on Windows/gcc a lot of useless warnings
+# so disable it on windows
+if( WIN32 AND NOT CMAKE_CROSSCOMPILING )
+ set( MAKE_LINK_MAPS false )
+else()
+ set( MAKE_LINK_MAPS true )
+endif()
+
+add_definitions(-DGERBVIEW)
+
+include_directories( BEFORE ${INC_BEFORE} )
+include_directories(
+ ../pcbnew
+ dialogs
+ ../3d-viewer
+ ../polygon
+ ${INC_AFTER}
+ )
+
+
+set( DIALOGS_SRCS
+ dialogs/gerbview_dialog_display_options_frame_base.cpp
+ dialogs/gerbview_dialog_display_options_frame.cpp
+ dialogs/dialog_layers_select_to_pcb_base.cpp
+ dialogs/dialog_print_using_printer.cpp
+ dialogs/dialog_print_using_printer_base.cpp
+ dialogs/dialog_select_one_pcb_layer.cpp
+ dialogs/dialog_show_page_borders.cpp
+ dialogs/dialog_show_page_borders_base.cpp
+ )
+
+set( GERBVIEW_SRCS
+ block.cpp
+ class_am_param.cpp
+ class_aperture_macro.cpp
+ class_DCodeSelectionbox.cpp
+ class_gbr_screen.cpp
+ class_gbr_layout.cpp
+ class_GERBER.cpp
+ class_gerber_draw_item.cpp
+ class_gerbview_layer_widget.cpp
+ class_gbr_layer_box_selector.cpp
+ class_X2_gerber_attributes.cpp
+ controle.cpp
+ dcode.cpp
+ draw_gerber_screen.cpp
+ events_called_functions.cpp
+ excellon_read_drill_file.cpp
+ export_to_pcbnew.cpp
+ files.cpp
+ gerbview_config.cpp
+ gerbview_frame.cpp
+ hotkeys.cpp
+ init_gbr_drawlayers.cpp
+ locate.cpp
+ menubar.cpp
+ onleftclick.cpp
+ onrightclick.cpp
+ pcbplot.cpp
+ printout_control.cpp
+ readgerb.cpp
+ rs274_read_XY_and_IJ_coordinates.cpp
+ rs274d.cpp
+ rs274x.cpp
+ select_layers_to_pcb.cpp
+ toolbars_gerber.cpp
+ )
+
+set( GERBVIEW_EXTRA_SRCS
+ ../common/base_screen.cpp
+ ../common/base_units.cpp
+ ../common/eda_text.cpp
+ ../common/class_layer_box_selector.cpp
+ ../common/class_page_info.cpp
+ ../pcbnew/layer_widget.cpp
+)
+
+if( MINGW )
+ # GERBVIEW_RESOURCES variable is set by the macro.
+ mingw_resource_compiler( gerbview )
+else()
+ set( GERBVIEW_RESOURCES gerbview.rc )
+endif()
+
+if( APPLE )
+ # setup bundle
+ set( GERBVIEW_RESOURCES gerbview.icns gerbview_doc.icns )
+ set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/gerbview.icns" PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+ set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/gerbview_doc.icns" PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+ set( MACOSX_BUNDLE_ICON_FILE gerbview.icns )
+ set( MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-pcb.kicad )
+ set( MACOSX_BUNDLE_NAME gerbview )
+endif()
+
+add_executable( gerbview WIN32 MACOSX_BUNDLE
+ ../common/single_top.cpp
+ ../common/pgm_base.cpp
+ ${GERBVIEW_RESOURCES}
+ )
+set_source_files_properties( ../common/single_top.cpp PROPERTIES
+ COMPILE_DEFINITIONS "TOP_FRAME=FRAME_GERBER;BUILD_KIWAY_DLL"
+ )
+target_link_libraries( gerbview
+ #singletop # replaces common, giving us restrictive control and link warnings.
+ # There's way too much crap coming in from common yet.
+ common
+ bitmaps
+ ${wxWidgets_LIBRARIES}
+ )
+
+if( MAKE_LINK_MAPS )
+ set_target_properties( gerbview PROPERTIES
+ LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=gerbview.map" )
+endif()
+
+# the main gerbview program, in DSO form.
+add_library( gerbview_kiface MODULE
+ gerbview.cpp
+ ${GERBVIEW_SRCS}
+ ${DIALOGS_SRCS}
+ ${GERBVIEW_EXTRA_SRCS}
+ )
+set_target_properties( gerbview_kiface PROPERTIES
+ OUTPUT_NAME gerbview
+ PREFIX ${KIFACE_PREFIX}
+ SUFFIX ${KIFACE_SUFFIX}
+ )
+target_link_libraries( gerbview_kiface
+ common
+ polygon
+ bitmaps
+ gal
+ ${wxWidgets_LIBRARIES}
+ ${GDI_PLUS_LIBRARIES}
+ )
+set_source_files_properties( gerbview.cpp PROPERTIES
+ # The KIFACE is in gerbview.cpp, export it:
+ COMPILE_DEFINITIONS "BUILD_KIWAY_DLL;COMPILING_DLL"
+ )
+
+if( MAKE_LINK_MAPS )
+ set_target_properties( gerbview_kiface PROPERTIES
+ LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=_gerbview.kiface.map" )
+endif()
+
+# if building gerbview, then also build gerbview_kiface if out of date.
+add_dependencies( gerbview gerbview_kiface )
+
+# these 2 binaries are a matched set, keep them together
+if( APPLE )
+ set_target_properties( gerbview PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
+ )
+
+ # puts binaries into the *.app bundle while linking
+ set_target_properties( gerbview_kiface PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_KIFACE_DIR}
+ )
+ # put individual bundle outside of main bundle as a first step
+ # will be pulled into the main bundle when creating main bundle
+ install( TARGETS gerbview
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+ install( CODE "
+ # override default embedded path settings
+ ${OSX_BUNDLE_OVERRIDE_PATHS}
+
+ # do all the work
+ include( BundleUtilities )
+ fixup_bundle( ${KICAD_BIN}/gerbview.app/Contents/MacOS/gerbview
+ \"\"
+ \"\"
+ )
+ " COMPONENT Runtime
+ )
+else()
+ install( TARGETS gerbview
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+ install( TARGETS gerbview_kiface
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+endif()
diff --git a/gerbview/Info.plist b/gerbview/Info.plist
new file mode 100644
index 0000000..f3dbf5c
--- /dev/null
+++ b/gerbview/Info.plist
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>pen</string>
+ <string>gba</string>
+ <string>gbr</string>
+ <string>gbx</string>
+ <string>gbo</string>
+ <string>gbl</string>
+ <string>gtl</string>
+ <string>gto</string>
+ <string>gta</string>
+ <string>gbp</string>
+ <string>gbp</string>
+ <string>gbs</string>
+ <string>gts</string>
+ <string>gtp</string>
+ <string>gbx</string>
+ <string>lgr</string>
+ <string>ger</string>
+ <string>pho</string>
+ <string>drl</string>
+ </array>
+
+ <key>CFBundleTypeIconFile</key> <string>gerbview_doc.icns</string>
+ <key>CFBundleTypeName</key> <string>gerbview document</string>
+ <key>LSHandlerRank</key> <string>Default</string>
+ <key>CFBundleTypeRole</key> <string>Viewer</string>
+ </dict>
+ </array>
+
+ <key>CFBundleDevelopmentRegion</key> <string>English</string>
+ <key>CFBundleExecutable</key> <string>gerbview</string>
+ <key>CFBundleGetInfoString</key> <string></string>
+ <key>CFBundleIconFile</key> <string>gerbview.icns</string>
+ <key>CFBundleIdentifier</key> <string>org.kicad-pcb.gerbview</string>
+ <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string>
+ <key>CFBundleLongVersionString</key> <string></string>
+ <key>CFBundleName</key> <string>GerbView</string>
+ <key>CFBundlePackageType</key> <string>APPL</string>
+ <key>CFBundleShortVersionString</key> <string></string>
+ <key>CFBundleSignature</key> <string>????</string>
+ <key>CFBundleVersion</key> <string></string>
+ <key>CSResourcesFileMapped</key> <true/>
+ <key>LSRequiresCarbon</key> <true/>
+ <key>NSHumanReadableCopyright</key> <string></string>
+ <key>NSHighResolutionCapable</key> <string>True</string>
+</dict>
+</plist>
diff --git a/gerbview/block.cpp b/gerbview/block.cpp
new file mode 100644
index 0000000..1218322
--- /dev/null
+++ b/gerbview/block.cpp
@@ -0,0 +1,221 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 <Jean-Pierre Charras>
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file gerbview/block.cpp
+ * @brief Block operations: displacement.
+ */
+
+
+#include <fctsys.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <gr_basic.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <class_gerber_draw_item.h>
+
+#include <wx/debug.h>
+
+#define BLOCK_COLOR BROWN
+
+
+static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool erase );
+
+
+int GERBVIEW_FRAME::BlockCommand( int key )
+{
+ int cmd = 0;
+
+ switch( key )
+ {
+ default:
+ cmd = key & 0x255;
+ break;
+
+ case 0:
+ cmd = BLOCK_MOVE;
+ break;
+
+ case GR_KB_SHIFT:
+ case GR_KB_CTRL:
+ case GR_KB_SHIFTCTRL:
+ case GR_KB_ALT:
+ break;
+
+ case MOUSE_MIDDLE:
+ cmd = BLOCK_ZOOM;
+ break;
+ }
+
+ return cmd;
+}
+
+
+void GERBVIEW_FRAME::HandleBlockPlace( wxDC* DC )
+{
+ wxASSERT( m_canvas->IsMouseCaptured() );
+
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP );
+
+ switch( GetScreen()->m_BlockLocate.GetCommand() )
+ {
+ case BLOCK_MOVE: /* Move */
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ Block_Move( DC );
+ GetScreen()->m_BlockLocate.ClearItemsList();
+ break;
+
+ default:
+ wxFAIL_MSG( wxT("HandleBlockPlace: Unexpected block command") );
+ break;
+ }
+
+ m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false );
+ GetScreen()->SetModify();
+ GetScreen()->ClearBlockCommand();
+
+ wxASSERT( GetScreen()->m_BlockLocate.GetCount() == 0 );
+
+ DisplayToolMsg( wxEmptyString );
+}
+
+
+bool GERBVIEW_FRAME::HandleBlockEnd( wxDC* DC )
+{
+ bool nextcmd = false;
+ bool zoom_command = false;
+
+ if( m_canvas->IsMouseCaptured() )
+
+ switch( GetScreen()->m_BlockLocate.GetCommand() )
+ {
+ case BLOCK_MOVE: /* Move */
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE );
+ nextcmd = true;
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ break;
+
+ case BLOCK_ZOOM: /* Window Zoom */
+ zoom_command = true;
+ break;
+
+ default:
+ wxFAIL_MSG( wxT("HandleBlockEnd: Unexpected block command") );
+ break;
+ }
+
+ if( ! nextcmd )
+ {
+ GetScreen()->ClearBlockCommand();
+ m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString,
+ false );
+ }
+
+ if( zoom_command )
+ Window_Zoom( GetScreen()->m_BlockLocate );
+
+ return nextcmd ;
+}
+
+
+/* Traces the outline of the block structures of a repositioning move
+ */
+static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPositon,
+ bool aErase )
+{
+ BASE_SCREEN* screen = aPanel->GetScreen();
+
+ EDA_COLOR_T Color = YELLOW;
+
+ if( aErase )
+ {
+ screen->m_BlockLocate.Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode, Color );
+
+ if( screen->m_BlockLocate.GetMoveVector().x|| screen->m_BlockLocate.GetMoveVector().y )
+ {
+ screen->m_BlockLocate.Draw( aPanel,
+ aDC,
+ screen->m_BlockLocate.GetMoveVector(),
+ g_XorMode,
+ Color );
+ }
+ }
+
+ if( screen->m_BlockLocate.GetState() != STATE_BLOCK_STOP )
+ {
+ const wxPoint& cross_hair = aPanel->GetParent()->GetCrossHairPosition();
+
+ screen->m_BlockLocate.SetMoveVector(
+ wxPoint( cross_hair.x - screen->m_BlockLocate.GetRight(),
+ cross_hair.y - screen->m_BlockLocate.GetBottom() ) );
+ }
+
+ screen->m_BlockLocate.Draw( aPanel, aDC, wxPoint( 0, 0 ), g_XorMode, Color );
+
+ if( screen->m_BlockLocate.GetMoveVector().x || screen->m_BlockLocate.GetMoveVector().y )
+ {
+ screen->m_BlockLocate.Draw( aPanel,
+ aDC,
+ screen->m_BlockLocate.GetMoveVector(),
+ g_XorMode,
+ Color );
+ }
+}
+
+
+void GERBVIEW_FRAME::Block_Move( wxDC* DC )
+{
+ wxPoint delta;
+ wxPoint oldpos;
+
+ oldpos = GetCrossHairPosition();
+ m_canvas->SetMouseCaptureCallback( NULL );
+
+ SetCrossHairPosition( oldpos );
+ m_canvas->MoveCursorToCrossHair();
+ GetScreen()->SetModify();
+ GetScreen()->m_BlockLocate.Normalize();
+
+ /* Calculate displacement vectors. */
+ delta = GetScreen()->m_BlockLocate.GetMoveVector();
+
+ /* Move items in block */
+ for( GERBER_DRAW_ITEM* item = GetItemsList(); item; item = item->Next() )
+ {
+ GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
+
+ if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) )
+ gerb_item->MoveAB( delta );
+ }
+
+ m_canvas->Refresh( true );
+}
diff --git a/gerbview/class_DCodeSelectionbox.cpp b/gerbview/class_DCodeSelectionbox.cpp
new file mode 100644
index 0000000..2d13596
--- /dev/null
+++ b/gerbview/class_DCodeSelectionbox.cpp
@@ -0,0 +1,84 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <wxstruct.h>
+#include <class_drawpanel.h>
+#include <gerbview.h>
+#include <dcode.h>
+
+#include <class_DCodeSelectionbox.h>
+
+/*******************************************/
+/* Helper class for displaying DCodes list */
+/*******************************************/
+
+DCODE_SELECTION_BOX::DCODE_SELECTION_BOX( wxAuiToolBar* aParent, wxWindowID aId,
+ const wxPoint& aLocation, const wxSize& aSize,
+ const wxArrayString& aChoices ) :
+ wxComboBox( aParent, aId, wxEmptyString, aLocation, aSize, 0, NULL, wxCB_READONLY )
+{
+ m_dcodeList = &aChoices;
+ // Append aChoices here is by far faster than use aChoices inside
+ // the wxComboBox constructor
+ Append(aChoices);
+}
+
+
+DCODE_SELECTION_BOX::~DCODE_SELECTION_BOX()
+{
+}
+
+
+int DCODE_SELECTION_BOX::GetSelectedDCodeId()
+{
+ int ii = GetSelection();
+
+ if( ii > 0 )
+ {
+ wxString msg = (*m_dcodeList)[ii].AfterFirst( wxChar( ' ' ) );
+ long id;
+ msg.ToLong(&id);
+ return id;
+ }
+
+ return -1;
+}
+
+
+/* SetDCodeSelection
+ * aDCodeId = the DCode Id to select or -1 to select "no dcode"
+ */
+void DCODE_SELECTION_BOX::SetDCodeSelection( int aDCodeId )
+{
+ if( aDCodeId > LAST_DCODE )
+ aDCodeId = LAST_DCODE;
+
+ int index = 0;
+ if( aDCodeId >= FIRST_DCODE )
+ index = aDCodeId - FIRST_DCODE + 1;
+
+ SetSelection(index);
+}
diff --git a/gerbview/class_DCodeSelectionbox.h b/gerbview/class_DCodeSelectionbox.h
new file mode 100644
index 0000000..d65578b
--- /dev/null
+++ b/gerbview/class_DCodeSelectionbox.h
@@ -0,0 +1,58 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+// file class_DCodeSelectionbox.h
+
+#ifndef CLASS_DCODESELECTIONBOX_H
+#define CLASS_DCODESELECTIONBOX_H
+
+/* helper class to display a DCode list and select a DCode id.
+ */
+
+// Define event type for DCODE_SELECTION_BOX
+#define EVT_SELECT_DCODE EVT_COMBOBOX
+
+class DCODE_SELECTION_BOX : public wxComboBox
+{
+private:
+ const wxArrayString* m_dcodeList;
+
+public: DCODE_SELECTION_BOX( wxAuiToolBar* aParent, wxWindowID aId,
+ const wxPoint& aLocation, const wxSize& aSize,
+ const wxArrayString& aChoices);
+ ~DCODE_SELECTION_BOX();
+
+ /**
+ * Function GetSelectedDCodeId
+ * @return the current selected DCode Id or -1 if no dcode
+ */
+ int GetSelectedDCodeId();
+ /**
+ * Function SetDCodeSelection
+ * @param aDCodeId = the DCode Id to select or -1 to select "no dcode"
+ */
+ void SetDCodeSelection( int aDCodeId );
+};
+
+#endif //CLASS_DCODESELECTIONBOX_H
diff --git a/gerbview/class_GERBER.cpp b/gerbview/class_GERBER.cpp
new file mode 100644
index 0000000..59d7615
--- /dev/null
+++ b/gerbview/class_GERBER.cpp
@@ -0,0 +1,557 @@
+/**
+ * @file class_GERBER.cpp
+ * a GERBER class handle for a given layer info about used D_CODES and how the layer is drawn
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <macros.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <class_GERBER.h>
+#include <class_X2_gerber_attributes.h>
+
+#include <algorithm>
+
+
+/**
+ * Function scaletoIU
+ * converts a distance given in floating point to our internal units
+ */
+extern int scaletoIU( double aCoord, bool isMetric ); // defined it rs274d_read_XY_and_IJ_coordiantes.cpp
+
+/* Format Gerber: NOTES:
+ * Tools and D_CODES
+ * tool number (identification of shapes)
+ * 1 to 999
+ *
+ * D_CODES:
+ * D01 ... D9 = action codes:
+ * D01 = activating light (lower pen) when di placement
+ * D02 = light extinction (lift pen) when di placement
+ * D03 Flash
+ * D09 = VAPE Flash
+ * D10 ... = Indentification Tool (Opening)
+ *
+ * For tools:
+ * DCode min = D10
+ * DCode max = 999
+ */
+
+
+GERBER_LAYER::GERBER_LAYER()
+{
+ ResetDefaultValues();
+}
+
+
+GERBER_LAYER::~GERBER_LAYER()
+{
+}
+
+
+void GERBER_LAYER::ResetDefaultValues()
+{
+ m_LayerName = wxT( "no name" ); // Layer name from the LN command
+ m_LayerNegative = false; // true = Negative Layer
+ m_StepForRepeat.x = m_StepForRepeat.y = 0; // X and Y offsets for Step and Repeat command
+ m_XRepeatCount = 1; // The repeat count on X axis
+ m_YRepeatCount = 1; // The repeat count on Y axis
+ m_StepForRepeatMetric = false; // false = Inches, true = metric
+}
+
+
+GERBER_IMAGE::GERBER_IMAGE( GERBVIEW_FRAME* aParent, int aLayer )
+{
+ m_Parent = aParent;
+ m_GraphicLayer = aLayer; // Graphic layer Number
+
+ m_Selected_Tool = FIRST_DCODE;
+ m_FileFunction = NULL; // file function parameters
+
+ ResetDefaultValues();
+
+ for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
+ m_Aperture_List[ii] = 0;
+}
+
+
+GERBER_IMAGE::~GERBER_IMAGE()
+{
+ for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
+ {
+ delete m_Aperture_List[ii];
+ }
+
+ delete m_FileFunction;
+}
+
+/*
+ * Function GetItemsList
+ * returns the first GERBER_DRAW_ITEM * item of the items list
+ */
+GERBER_DRAW_ITEM * GERBER_IMAGE::GetItemsList()
+{
+ return m_Parent->GetItemsList();
+}
+
+D_CODE* GERBER_IMAGE::GetDCODE( int aDCODE, bool create )
+{
+ unsigned ndx = aDCODE - FIRST_DCODE;
+
+ if( ndx < (unsigned) DIM( m_Aperture_List ) )
+ {
+ // lazily create the D_CODE if it does not exist.
+ if( create )
+ {
+ if( m_Aperture_List[ndx] == NULL )
+ m_Aperture_List[ndx] = new D_CODE( ndx + FIRST_DCODE );
+ }
+
+ return m_Aperture_List[ndx];
+ }
+ return NULL;
+}
+
+
+APERTURE_MACRO* GERBER_IMAGE::FindApertureMacro( const APERTURE_MACRO& aLookup )
+{
+ APERTURE_MACRO_SET::iterator iter = m_aperture_macros.find( aLookup );
+
+ if( iter != m_aperture_macros.end() )
+ {
+ APERTURE_MACRO* pam = (APERTURE_MACRO*) &(*iter);
+ return pam;
+ }
+
+ return NULL; // not found
+}
+
+
+void GERBER_IMAGE::ResetDefaultValues()
+{
+ m_InUse = false;
+ m_GBRLayerParams.ResetDefaultValues();
+ m_FileName.Empty();
+ m_ImageName = wxT( "no name" ); // Image name from the IN command
+ m_ImageNegative = false; // true = Negative image
+ m_IsX2_file = false; // true only if a %TF, %TA or %TD command
+ delete m_FileFunction; // file function parameters
+ m_FileFunction = NULL;
+ m_MD5_value.Empty(); // MD5 value found in a %TF.MD5 command
+ m_PartString.Empty(); // string found in a %TF.Part command
+ m_hasNegativeItems = -1; // set to uninitialized
+ m_ImageJustifyOffset = wxPoint(0,0); // Image justify Offset
+ m_ImageJustifyXCenter = false; // Image Justify Center on X axis (default = false)
+ m_ImageJustifyYCenter = false; // Image Justify Center on Y axis (default = false)
+ m_GerbMetric = false; // false = Inches (default), true = metric
+ m_Relative = false; // false = absolute Coord,
+ // true = relative Coord
+ m_NoTrailingZeros = false; // true: trailing zeros deleted
+ m_DecimalFormat = false; // true: use floating point notations for coordinates
+ m_ImageOffset.x = m_ImageOffset.y = 0; // Coord Offset, from IO command
+ m_ImageRotation = 0; // Allowed 0, 90, 180, 270 (in degree)
+ m_LocalRotation = 0.0; // Layer totation from RO command (in 0.1 degree)
+ m_Offset.x = 0;
+ m_Offset.y = 0; // Coord Offset, from OF command
+ m_Scale.x = m_Scale.y = 1.0; // scale (A and B) this layer
+ m_MirrorA = false; // true: miror / axe A (default = X)
+ m_MirrorB = false; // true: miror / axe B (default = Y)
+ m_SwapAxis = false; // false if A = X, B = Y; true if A =Y, B = Y
+ m_Has_DCode = false; // true = DCodes in file
+ // false = no DCode->
+ // search for separate DCode file
+ m_FmtScale.x = m_FmtScale.y = 4; // Initialize default format to 3.4 => 4
+ m_FmtLen.x = m_FmtLen.y = 3 + 4; // Initialize default format len = 3+4
+
+ m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // Linear, 90 arc, Circ.
+ m_360Arc_enbl = false; // 360 deg circular
+ // interpolation disable
+ m_Current_Tool = 0; // Current Dcode selected
+ m_CommandState = 0; // State of the current command
+ m_CurrentPos.x = m_CurrentPos.y = 0; // current specified coord
+ m_PreviousPos.x = m_PreviousPos.y = 0; // last specified coord
+ m_IJPos.x = m_IJPos.y = 0; // current centre coord for
+ // plot arcs & circles
+ m_Current_File = NULL; // Gerber file to read
+ m_FilesPtr = 0;
+ m_PolygonFillMode = false;
+ m_PolygonFillModeState = 0;
+ m_Selected_Tool = FIRST_DCODE;
+ m_Last_Pen_Command = 0;
+ m_Exposure = false;
+
+ for( unsigned ii = 0; ii < DIM( m_FilesList ); ii++ )
+ m_FilesList[ii] = NULL;
+}
+
+/* Function HasNegativeItems
+ * return true if at least one item must be drawn in background color
+ * used to optimize screen refresh
+ */
+bool GERBER_IMAGE::HasNegativeItems()
+{
+ if( m_hasNegativeItems < 0 ) // negative items are not yet searched: find them if any
+ {
+ if( m_ImageNegative ) // A negative layer is expected having always negative objects.
+ m_hasNegativeItems = 1;
+ else
+ {
+ m_hasNegativeItems = 0;
+ for( GERBER_DRAW_ITEM* item = GetItemsList(); item; item = item->Next() )
+ {
+ if( item->GetLayer() != m_GraphicLayer )
+ continue;
+ if( item->HasNegativeItems() )
+ {
+ m_hasNegativeItems = 1;
+ break;
+ }
+ }
+ }
+ }
+ return m_hasNegativeItems == 1;
+}
+
+int GERBER_IMAGE::UsedDcodeNumber()
+{
+ int count = 0;
+
+ for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
+ {
+ if( m_Aperture_List[ii] )
+ if( m_Aperture_List[ii]->m_InUse || m_Aperture_List[ii]->m_Defined )
+ ++count;
+ }
+
+ return count;
+}
+
+
+void GERBER_IMAGE::InitToolTable()
+{
+ for( int count = 0; count < TOOLS_MAX_COUNT; count++ )
+ {
+ if( m_Aperture_List[count] == NULL )
+ continue;
+
+ m_Aperture_List[count]->m_Num_Dcode = count + FIRST_DCODE;
+ m_Aperture_List[count]->Clear_D_CODE_Data();
+ }
+
+ m_aperture_macros.clear();
+}
+
+
+/**
+ * Function ReportMessage
+ * Add a message (a string) in message list
+ * for instance when reading a Gerber file
+ * @param aMessage = the straing to add in list
+ */
+void GERBER_IMAGE::ReportMessage( const wxString aMessage )
+{
+ m_Parent->ReportMessage( aMessage );
+}
+
+
+/**
+ * Function ClearMessageList
+ * Clear the message list
+ * Call it before reading a Gerber file
+ */
+void GERBER_IMAGE::ClearMessageList()
+{
+ m_Parent->ClearMessageList();
+}
+
+
+/**
+ * Function StepAndRepeatItem
+ * Gerber format has a command Step an Repeat
+ * This function must be called when reading a gerber file and
+ * after creating a new gerber item that must be repeated
+ * (i.e when m_XRepeatCount or m_YRepeatCount are > 1)
+ * @param aItem = the item to repeat
+ */
+void GERBER_IMAGE::StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem )
+{
+ if( GetLayerParams().m_XRepeatCount < 2 &&
+ GetLayerParams().m_YRepeatCount < 2 )
+ return; // Nothing to repeat
+ // Duplicate item:
+ wxString msg;
+ for( int ii = 0; ii < GetLayerParams().m_XRepeatCount; ii++ )
+ {
+ for( int jj = 0; jj < GetLayerParams().m_YRepeatCount; jj++ )
+ {
+ // the first gerber item already exists (this is the template)
+ // create duplicate only if ii or jj > 0
+ if( jj == 0 && ii == 0 )
+ continue;
+ GERBER_DRAW_ITEM* dupItem = new GERBER_DRAW_ITEM( aItem );
+ wxPoint move_vector;
+ move_vector.x = scaletoIU( ii * GetLayerParams().m_StepForRepeat.x,
+ GetLayerParams().m_StepForRepeatMetric );
+ move_vector.y = scaletoIU( jj * GetLayerParams().m_StepForRepeat.y,
+ GetLayerParams().m_StepForRepeatMetric );
+ dupItem->MoveXY( move_vector );
+ m_Parent->GetGerberLayout()->m_Drawings.Append( dupItem );
+ }
+ }
+}
+
+
+/**
+ * Function DisplayImageInfo
+ * has knowledge about the frame and how and where to put status information
+ * about this object into the frame's message panel.
+ * Display info about Image Parameters.
+ * These parameters are valid for the entire file, and must set only once
+ * (If more than once, only the last value is used)
+ */
+void GERBER_IMAGE::DisplayImageInfo( void )
+{
+ wxString msg;
+
+ m_Parent->ClearMsgPanel();
+
+ // Display Image name (Image specific)
+ m_Parent->AppendMsgPanel( _( "Image name" ), m_ImageName, CYAN );
+
+ // Display graphic layer number used to draw this Image
+ // (not a Gerber parameter but is also image specific)
+ msg.Printf( wxT( "%d" ), m_GraphicLayer + 1 );
+ m_Parent->AppendMsgPanel( _( "Graphic layer" ), msg, BROWN );
+
+ // Display Image rotation (Image specific)
+ msg.Printf( wxT( "%d" ), m_ImageRotation );
+ m_Parent->AppendMsgPanel( _( "Img Rot." ), msg, CYAN );
+
+ // Display Image polarity (Image specific)
+ msg = m_ImageNegative ? _("Negative") : _("Normal");
+ m_Parent->AppendMsgPanel( _( "Polarity" ), msg, BROWN );
+
+ // Display Image justification and offset for justification (Image specific)
+ msg = m_ImageJustifyXCenter ? _("Center") : _("Normal");
+ m_Parent->AppendMsgPanel( _( "X Justify" ), msg, DARKRED );
+
+ msg = m_ImageJustifyYCenter ? _("Center") : _("Normal");
+ m_Parent->AppendMsgPanel( _( "Y Justify" ), msg, DARKRED );
+
+ if( g_UserUnit == INCHES )
+ msg.Printf( wxT( "X=%f Y=%f" ), (double) m_ImageJustifyOffset.x/10000,
+ (double) m_ImageJustifyOffset.y/10000 );
+ else
+ msg.Printf( wxT( "X=%f Y=%f" ), (double) m_ImageJustifyOffset.x*2.54/1000,
+ (double) m_ImageJustifyOffset.y*2.54/1000 );
+ m_Parent->AppendMsgPanel( _( "Image Justify Offset" ), msg, DARKRED );
+}
+
+// GERBER_IMAGE_LIST is a helper class to handle a list of GERBER_IMAGE files
+GERBER_IMAGE_LIST::GERBER_IMAGE_LIST()
+{
+ m_GERBER_List.reserve( GERBER_DRAWLAYERS_COUNT );
+
+ for( unsigned layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
+ m_GERBER_List.push_back( NULL );
+}
+
+GERBER_IMAGE_LIST::~GERBER_IMAGE_LIST()
+{
+ ClearList();
+
+ for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
+ {
+ delete m_GERBER_List[layer];
+ m_GERBER_List[layer] = NULL;
+ }
+}
+
+GERBER_IMAGE* GERBER_IMAGE_LIST::GetGbrImage( int aIdx )
+{
+ if( (unsigned)aIdx < m_GERBER_List.size() )
+ return m_GERBER_List[aIdx];
+
+ return NULL;
+}
+
+/**
+ * creates a new, empty GERBER_IMAGE* at index aIdx
+ * or at the first free location if aIdx < 0
+ * @param aIdx = the location to use ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
+ * @return true if the index used, or -1 if no room to add image
+ */
+int GERBER_IMAGE_LIST::AddGbrImage( GERBER_IMAGE* aGbrImage, int aIdx )
+{
+ int idx = aIdx;
+
+ if( idx < 0 )
+ {
+ for( idx = 0; idx < (int)m_GERBER_List.size(); idx++ )
+ {
+ if( !IsUsed( idx ) )
+ break;
+ }
+ }
+
+ if( idx >= (int)m_GERBER_List.size() )
+ return -1; // No room
+
+ m_GERBER_List[idx] = aGbrImage;
+
+ return idx;
+}
+
+
+// remove all loaded data in list, but do not delete empty images
+// (can be reused)
+void GERBER_IMAGE_LIST::ClearList()
+{
+ for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
+ ClearImage( layer );
+}
+
+// remove the loaded data of image aIdx, but do not delete it
+void GERBER_IMAGE_LIST::ClearImage( int aIdx )
+{
+ if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() && m_GERBER_List[aIdx] )
+ {
+ m_GERBER_List[aIdx]->InitToolTable();
+ m_GERBER_List[aIdx]->ResetDefaultValues();
+ m_GERBER_List[aIdx]->m_InUse = false;
+ }
+}
+
+// Build a name for image aIdx which can be used in layers manager
+const wxString GERBER_IMAGE_LIST::GetDisplayName( int aIdx )
+{
+ wxString name;
+
+ GERBER_IMAGE* gerber = NULL;
+
+ if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() )
+ gerber = m_GERBER_List[aIdx];
+
+ if( gerber && IsUsed(aIdx ) )
+ {
+ if( gerber->m_FileFunction )
+ {
+ if( gerber->m_FileFunction->IsCopper() )
+ {
+ name.Printf( _( "Layer %d (%s, %s, %s)" ), aIdx + 1,
+ GetChars( gerber->m_FileFunction->GetFileType() ),
+ GetChars( gerber->m_FileFunction->GetBrdLayerId() ),
+ GetChars( gerber->m_FileFunction->GetBrdLayerSide() ) );
+ }
+ else
+ {
+ name.Printf( _( "Layer %d (%s, %s)" ), aIdx + 1,
+ GetChars( gerber->m_FileFunction->GetFileType() ),
+ GetChars( gerber->m_FileFunction->GetBrdLayerId() ) );
+ }
+ }
+ else
+ name.Printf( _( "Layer %d *" ), aIdx + 1 );
+ }
+ else
+ name.Printf( _( "Layer %d" ), aIdx + 1 );
+
+ return name;
+}
+
+// return true if image is used (loaded and not cleared)
+bool GERBER_IMAGE_LIST::IsUsed( int aIdx )
+{
+ if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() )
+ return m_GERBER_List[aIdx] != NULL && m_GERBER_List[aIdx]->m_InUse;
+
+ return false;
+}
+
+// Helper function, for std::sort.
+// Sort loaded images by Z order priority, if they have the X2 FileFormat info
+// returns true if the first argument (ref) is ordered before the second (test).
+static bool sortZorder( const GERBER_IMAGE* const& ref, const GERBER_IMAGE* const& test )
+{
+ if( !ref && !test )
+ return false; // do not change order: no criteria to sort items
+
+ if( !ref || !ref->m_InUse )
+ return false; // Not used: ref ordered after
+
+ if( !test || !test->m_InUse )
+ return true; // Not used: ref ordered before
+
+ if( !ref->m_FileFunction && !test->m_FileFunction )
+ return false; // do not change order: no criteria to sort items
+
+ if( !ref->m_FileFunction )
+ return false;
+
+ if( !test->m_FileFunction )
+ return true;
+
+ if( ref->m_FileFunction->GetZOrder() != test->m_FileFunction->GetZOrder() )
+ return ref->m_FileFunction->GetZOrder() > test->m_FileFunction->GetZOrder();
+
+ return ref->m_FileFunction->GetZSubOrder() > test->m_FileFunction->GetZSubOrder();
+}
+
+void GERBER_IMAGE_LIST::SortImagesByZOrder( GERBER_DRAW_ITEM* aDrawList )
+{
+ std::sort( m_GERBER_List.begin(), m_GERBER_List.end(), sortZorder );
+
+ // The image order has changed.
+ // Graphic layer numbering must be updated to match the widgets layer order
+
+ // Store the old/new graphic layer info:
+ std::map <int, int> tab_lyr;
+
+ for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
+ {
+ if( m_GERBER_List[layer] )
+ {
+ tab_lyr[m_GERBER_List[layer]->m_GraphicLayer] = layer;
+ m_GERBER_List[layer]->m_GraphicLayer = layer ;
+ }
+ }
+
+ // update the graphic layer in items to draw
+ for( GERBER_DRAW_ITEM* item = aDrawList; item; item = item->Next() )
+ {
+ int layer = item->GetLayer();
+ item->SetLayer( tab_lyr[layer] );
+ }
+}
+
+
+// The global image list:
+GERBER_IMAGE_LIST g_GERBER_List;
diff --git a/gerbview/class_GERBER.h b/gerbview/class_GERBER.h
new file mode 100644
index 0000000..1f72c1c
--- /dev/null
+++ b/gerbview/class_GERBER.h
@@ -0,0 +1,378 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2013 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _CLASS_GERBER_H_
+#define _CLASS_GERBER_H_
+
+#include <vector>
+#include <set>
+
+#include <dcode.h>
+#include <class_gerber_draw_item.h>
+#include <class_aperture_macro.h>
+
+// An useful macro used when reading gerber files;
+#define IsNumber( x ) ( ( ( (x) >= '0' ) && ( (x) <='9' ) ) \
+ || ( (x) == '-' ) || ( (x) == '+' ) || ( (x) == '.' ) )
+
+class GERBVIEW_FRAME;
+class D_CODE;
+
+/* gerber files have different parameters to define units and how items must be plotted.
+ * some are for the entire file, and other can change along a file.
+ * In Gerber world:
+ * an image is the entire gerber file and its "global" parameters
+ * a layer (that is very different from a board layer) is just a sub set of a file that
+ * have specific parameters
+ * if a Image parameter is set more than once, only the last value is used
+ * Some parameters can change along a file and are not layer specific: they are stored
+ * in GERBER_ITEM items, when instancied.
+ *
+ * In GerbView, to handle these parameters, there are 2 classes:
+ * GERBER_IMAGE : the main class containing most of parameters and data to plot a graphic layer
+ * Some of them can change along the file
+ * There is one GERBER_IMAGE per file and one graphic layer per file or GERBER_IMAGE
+ * GerbView does not read and merge 2 gerber file in one graphic layer:
+ * I believe this is not possible due to the constraints in Image parameters.
+ * GERBER_LAYER : containing the subset of parameters that is layer speficic
+ * A GERBER_IMAGE must include one GERBER_LAYER to define all parameters to plot a file.
+ * But a GERBER_IMAGE can use more than one GERBER_LAYER.
+ */
+
+class GERBER_IMAGE;
+class X2_ATTRIBUTE_FILEFUNCTION;
+
+class GERBER_LAYER
+{
+ friend class GERBER_IMAGE;
+public:
+
+ // These parameters are layer specfic:
+ wxString m_LayerName; // Layer name, from LN <name>* command
+ bool m_LayerNegative; // true = Negative Layer: command LP
+ wxRealPoint m_StepForRepeat; // X and Y offsets for Step and Repeat command
+ int m_XRepeatCount; // The repeat count on X axis
+ int m_YRepeatCount; // The repeat count on Y axis
+ bool m_StepForRepeatMetric; // false = Inches, true = metric
+ // needed here because repeated
+ // gerber items can have coordinates
+ // in different units than step parameters
+ // and the actual coordinates calculation must handle this
+
+public:
+ GERBER_LAYER();
+ ~GERBER_LAYER();
+private:
+ void ResetDefaultValues();
+};
+
+/**
+ * Class GERBER_IMAGE
+ * holds the Image data and parameters for one gerber file
+ * and layer parameters (TODO: move them in GERBER_LAYER class
+ */
+class GERBER_IMAGE
+{
+ GERBVIEW_FRAME* m_Parent; // the parent GERBVIEW_FRAME (used to display messages...)
+ D_CODE* m_Aperture_List[TOOLS_MAX_COUNT]; ///< Dcode (Aperture) List for this layer (max 999)
+ bool m_Exposure; ///< whether an aperture macro tool is flashed on or off
+
+ GERBER_LAYER m_GBRLayerParams; // hold params for the current gerber layer
+
+public:
+ bool m_InUse; // true if this image is currently in use
+ // (a file is loaded in it)
+ wxString m_FileName; // Full File Name for this layer
+ wxString m_ImageName; // Image name, from IN <name>* command
+ bool m_IsX2_file; // true if a X2 gerber attribute was found in file
+ X2_ATTRIBUTE_FILEFUNCTION* m_FileFunction; // file function parameters, found in a %TF command
+ // or a G04
+ wxString m_MD5_value; // MD5 value found in a %TF.MD5 command
+ wxString m_PartString; // string found in a %TF.Part command
+ int m_GraphicLayer; // Graphic layer Number
+ bool m_ImageNegative; // true = Negative image
+ bool m_ImageJustifyXCenter; // Image Justify Center on X axis (default = false)
+ bool m_ImageJustifyYCenter; // Image Justify Center on Y axis (default = false)
+ wxPoint m_ImageJustifyOffset; // Image Justify Offset on XY axis (default = 0,0)
+ bool m_GerbMetric; // false = Inches, true = metric
+ bool m_Relative; // false = absolute Coord, true = relative Coord
+ bool m_NoTrailingZeros; // true: remove tailing zeros.
+ bool m_DecimalFormat; // true: use floating point notations for coordinates
+ // If true, overrides m_NoTrailingZeros parameter.
+ wxPoint m_ImageOffset; // Coord Offset, from IO command
+ wxSize m_FmtScale; // Fmt 2.3: m_FmtScale = 3, fmt 3.4: m_FmtScale = 4
+ wxSize m_FmtLen; // Nb chars per coord. ex fmt 2.3, m_FmtLen = 5
+ int m_ImageRotation; // Image rotation (0, 90, 180, 270 only) in degrees
+ double m_LocalRotation; // Local rotation, in degrees, added to m_ImageRotation
+ // Note this value is stored in 0.1 degrees
+ wxPoint m_Offset; // Coord Offset, from OF command
+ wxRealPoint m_Scale; // scale (X and Y) of layer.
+ bool m_SwapAxis; // false (default) if A = X and B = Y
+ // true if A = Y, B = X
+ bool m_MirrorA; // true: miror / axe A (X)
+ bool m_MirrorB; // true: miror / axe B (Y)
+ int m_Iterpolation; // Linear, 90 arc, Circ.
+ int m_Current_Tool; // Current Tool (Dcode) number selected
+ int m_Last_Pen_Command; // Current or last pen state (0..9, set by Dn option with n <10
+ int m_CommandState; // state of gerber analysis command.
+ wxPoint m_CurrentPos; // current specified coord for plot
+ wxPoint m_PreviousPos; // old current specified coord for plot
+ wxPoint m_IJPos; // IJ coord (for arcs & circles )
+
+ FILE* m_Current_File; // Current file to read
+ #define INCLUDE_FILES_CNT_MAX 10
+ FILE* m_FilesList[INCLUDE_FILES_CNT_MAX + 2]; // Included files list
+ int m_FilesPtr; // Stack pointer for files list
+
+ int m_Selected_Tool; // For hightlight: current selected Dcode
+ bool m_Has_DCode; // true = DCodes in file
+ // (false = no DCode -> separate DCode file
+ bool m_360Arc_enbl; // Enbl 360 deg circular interpolation
+ bool m_PolygonFillMode; // Enable polygon mode (read coord as a polygon descr)
+ int m_PolygonFillModeState; // In polygon mode: 0 = first segm, 1 = next segm
+
+ APERTURE_MACRO_SET m_aperture_macros; ///< a collection of APERTURE_MACROS, sorted by name
+
+private:
+ int m_hasNegativeItems; // true if the image is negative or has some negative items
+ // Used to optimize drawing, because when there are no
+ // negative items screen refresh does not need
+ // to build an intermediate bitmap specfic to this image
+ // -1 = negative items are
+ // 0 = no negative items found
+ // 1 = have negative items found
+
+public:
+ GERBER_IMAGE( GERBVIEW_FRAME* aParent, int layer );
+ virtual ~GERBER_IMAGE();
+ void Clear_GERBER_IMAGE();
+ int UsedDcodeNumber();
+ virtual void ResetDefaultValues();
+
+ /**
+ * Function GetParent
+ * @return the GERBVIEW_FRAME parent of this GERBER_IMAGE
+ */
+ GERBVIEW_FRAME* GetParent() const
+ {
+ return m_Parent;
+ }
+
+ /**
+ * Function GetItemsList
+ * @return the first GERBER_DRAW_ITEM * item of the items list
+ */
+ GERBER_DRAW_ITEM * GetItemsList();
+
+ /**
+ * Function GetLayerParams
+ * @return the current layers params
+ */
+ GERBER_LAYER& GetLayerParams()
+ {
+ return m_GBRLayerParams;
+ }
+
+ /**
+ * Function HasNegativeItems
+ * @return true if at least one item must be drawn in background color
+ * used to optimize screen refresh (when no items are in background color
+ * refresh can be faster)
+ */
+ bool HasNegativeItems();
+
+ /**
+ * Function ReportMessage
+ * Add a message (a string) in message list
+ * for instance when reading a Gerber file
+ * @param aMessage = the straing to add in list
+ */
+ void ReportMessage( const wxString aMessage );
+
+ /**
+ * Function ClearMessageList
+ * Clear the message list
+ * Call it before reading a Gerber file
+ */
+ void ClearMessageList();
+
+ /**
+ * Function InitToolTable
+ */
+ void InitToolTable();
+
+ /**
+ * Function ReadXYCoord
+ * Returns the current coordinate type pointed to by XnnYnn Text (XnnnnYmmmm)
+ */
+ wxPoint ReadXYCoord( char*& Text );
+
+ /**
+ * Function ReadIJCoord
+ * Returns the current coordinate type pointed to by InnJnn Text (InnnnJmmmm)
+ * These coordinates are relative, so if coordinate is absent, it's value
+ * defaults to 0
+ */
+ wxPoint ReadIJCoord( char*& Text );
+
+ // functions to read G commands or D commands:
+ int GCodeNumber( char*& Text );
+ int DCodeNumber( char*& Text );
+
+ // functions to execute G commands or D commands:
+ bool Execute_G_Command( char*& text, int G_command );
+ bool Execute_DCODE_Command( char*& text, int D_command );
+
+ /**
+ * Function ReadRS274XCommand
+ * reads a single RS274X command terminated with a %
+ */
+ bool ReadRS274XCommand( char aBuff[GERBER_BUFZ], char* & text );
+
+ /**
+ * Function ExecuteRS274XCommand
+ * executes 1 command
+ */
+ bool ExecuteRS274XCommand( int command, char aBuff[GERBER_BUFZ],
+ char* & text );
+
+
+ /**
+ * Function ReadApertureMacro
+ * reads in an aperture macro and saves it in m_aperture_macros.
+ * @param aBuff a character buffer at least GERBER_BUFZ long that can be
+ * used to read successive lines from the gerber file.
+ * @param text A reference to a character pointer which gives the initial
+ * text to read from.
+ * @param gerber_file Which file to read from for continuation.
+ * @return bool - true if a macro was read in successfully, else false.
+ */
+ bool ReadApertureMacro( char aBuff[GERBER_BUFZ], char* & text,
+ FILE * gerber_file );
+
+
+ /**
+ * Function GetDCODE
+ * returns a pointer to the D_CODE within this GERBER for the given
+ * \a aDCODE.
+ * @param aDCODE The numeric value of the D_CODE to look up.
+ * @param createIfNoExist If true, then create the D_CODE if it does not
+ * exist.
+ * @return D_CODE* - the one implied by the given \a aDCODE, or NULL
+ * if the requested \a aDCODE is out of range.
+ */
+ D_CODE* GetDCODE( int aDCODE, bool createIfNoExist = true );
+
+ /**
+ * Function FindApertureMacro
+ * looks up a previously read in aperture macro.
+ * @param aLookup A dummy APERTURE_MACRO with [only] the name field set.
+ * @return APERTURE_MACRO* - the one with a matching name, or NULL if
+ * not found.
+ */
+ APERTURE_MACRO* FindApertureMacro( const APERTURE_MACRO& aLookup );
+
+ /**
+ * Function StepAndRepeatItem
+ * Gerber format has a command Step an Repeat
+ * This function must be called when reading a gerber file and
+ * after creating a new gerber item that must be repeated
+ * (i.e when m_XRepeatCount or m_YRepeatCount are > 1)
+ * @param aItem = the item to repeat
+ */
+ void StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem );
+
+ /**
+ * Function DisplayImageInfo
+ * has knowledge about the frame and how and where to put status information
+ * about this object into the frame's message panel.
+ * Display info about Image Parameters.
+ */
+ void DisplayImageInfo( void );
+};
+
+/**
+ * @brief GERBER_IMAGE_LIST is a helper class to handle a list of GERBER_IMAGE files
+ * which are loaded and can be displayed
+ * there are 32 images max which can be loaded
+ */
+class GERBER_IMAGE_LIST
+{
+ // the list of loaded images (1 image = 1 gerber file)
+ std::vector<GERBER_IMAGE*> m_GERBER_List;
+
+public:
+ GERBER_IMAGE_LIST();
+ ~GERBER_IMAGE_LIST();
+
+ //Accessor
+ GERBER_IMAGE* GetGbrImage( int aIdx );
+
+ /**
+ * Add a GERBER_IMAGE* at index aIdx
+ * or at the first free location if aIdx < 0
+ * @param aGbrImage = the image to add
+ * @param aIdx = the location to use ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
+ * @return true if the index used, or -1 if no room to add image
+ */
+ int AddGbrImage( GERBER_IMAGE* aGbrImage, int aIdx );
+
+
+ /**
+ * remove all loaded data in list
+ */
+ void ClearList();
+
+ /**
+ * remove the loaded data of image aIdx
+ * @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
+ */
+ void ClearImage( int aIdx );
+
+ /**
+ * @return a name for image aIdx which can be used in layers manager
+ * and layer selector
+ * is is "Layer n" (n = aIdx+1), followed by file attribute info (if X2 format)
+ * @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
+ */
+ const wxString GetDisplayName( int aIdx );
+
+ /**
+ * @return true if image is used (loaded and with items)
+ * @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
+ */
+ bool IsUsed( int aIdx );
+
+ /**
+ * Sort loaded images by Z order priority, if they have the X2 FileFormat info
+ * @param aDrawList: the draw list associated to the gerber images
+ * (SortImagesByZOrder updates the graphic layer of these items)
+ */
+ void SortImagesByZOrder( GERBER_DRAW_ITEM* aDrawList );
+};
+
+
+extern GERBER_IMAGE_LIST g_GERBER_List;
+
+#endif // ifndef _CLASS_GERBER_H_
diff --git a/gerbview/class_X2_gerber_attributes.cpp b/gerbview/class_X2_gerber_attributes.cpp
new file mode 100644
index 0000000..52d59b1
--- /dev/null
+++ b/gerbview/class_X2_gerber_attributes.cpp
@@ -0,0 +1,270 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_X2_gerber_attributes.cpp
+ */
+
+/*
+ * Manage the gerber extensions (attributes) in the new X2 version
+ * only few extensions are handled
+ * See http://www.ucamco.com/files/downloads/file/81/the_gerber_file_format_specification.pdf
+ *
+ * gerber attributes in the new X2 version look like:
+ * %TF.FileFunction,Copper,L1,Top*%
+ *
+ * Currently:
+ * .FileFunction .FileFunction Identifies the file’s function in the PCB.
+ * Other Standard Attributes, not yet used in Gerbview:
+ * .Part Identifies the part the file represents, e.g. a single PCB
+ * .MD5 Sets the MD5 file signature or checksum.
+ */
+
+#include <wx/log.h>
+#include <class_X2_gerber_attributes.h>
+
+/*
+ * class X2_ATTRIBUTE
+ * The attribute value consists of a number of substrings separated by a “,”
+*/
+
+X2_ATTRIBUTE::X2_ATTRIBUTE()
+{
+}
+
+X2_ATTRIBUTE::~X2_ATTRIBUTE()
+{
+}
+
+/* return the attribute name (for instance .FileFunction)
+ * which is given by TF command.
+ */
+const wxString& X2_ATTRIBUTE::GetAttribute()
+{
+ return m_Prms.Item( 0 );
+}
+
+/* return a parameter
+ * aIdx = the index of the parameter
+ * aIdx = 0 is the parameter read after the TF function
+ * (the same as GetAttribute())
+ */
+const wxString& X2_ATTRIBUTE::GetPrm( int aIdx)
+{
+ static const wxString dummy;
+
+ if( GetPrmCount() < aIdx && aIdx >= 0 )
+ return m_Prms.Item( aIdx );
+
+ return dummy;
+}
+
+// Debug function: pring using wxLogMessage le list of parameters
+void X2_ATTRIBUTE::DbgListPrms()
+{
+ wxLogMessage( wxT("prms count %d"), GetPrmCount() );
+
+ for( int ii = 0; ii < GetPrmCount(); ii++ )
+ wxLogMessage( m_Prms.Item( ii ) );
+}
+
+/*
+ * parse a TF command and fill m_Prms by the parameters found.
+ * aFile = a FILE* ptr to the current Gerber file.
+ * buff = the buffer containing current Gerber data (GERBER_BUFZ size)
+ * text = a pointer to the first char to read in Gerber data
+ */
+bool X2_ATTRIBUTE::ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, char* &aText )
+{
+ bool ok = true;
+ wxString data;
+
+ for( ; ; )
+ {
+ while( *aText )
+ {
+ switch( *aText )
+ {
+ case '%': // end of command
+ return ok; // success completion
+
+ case ' ':
+ case '\r':
+ case '\n':
+ aText++;
+ break;
+
+ case '*': // End of block
+ m_Prms.Add( data );
+ data.Empty();
+ aText++;
+ break;
+
+ case ',': // End of parameter
+ aText++;
+ m_Prms.Add( data );
+ data.Empty();
+ break;
+
+ default:
+ data.Append( *aText );
+ aText++;
+ break;
+ }
+ }
+
+ // end of current line, read another one.
+ if( aBuffer )
+ {
+ if( fgets( aBuffer, aBuffSize, aFile ) == NULL )
+ {
+ // end of file
+ ok = false;
+ break;
+ }
+
+ aText = aBuffer;
+ }
+ else
+ return ok;
+ }
+
+ return ok;
+}
+
+/*
+ * class X2_ATTRIBUTE_FILEFUNCTION ( from %TF.FileFunction in Gerber file)
+ * Example file function:
+ * %TF.FileFunction,Copper,L1,Top*%
+ * - Type. Such as copper, solder mask etc.
+ * - Position. Specifies where the file appears in the PCB layer structure.
+ * Corresponding position substring:
+ * Copper layer: L1, L2, L3...to indicate the layer position followed by Top, Inr or
+ * Bot. L1 is always the top copper layer. E.g. L2,Inr.
+ * Extra layer, e.g. solder mask: Top or Bot – defines the attachment of the layer.
+ * Drill/rout layer: E.g. 1,4 – where 1 is the start and 4 is the end copper layer. The
+ * pair 1,4 defines the span of the drill/rout file
+ * Optional index. This can be used in instances where for example there are two solder
+ * masks on the same side. The index counts from the PCB surface outwards.
+ */
+X2_ATTRIBUTE_FILEFUNCTION::X2_ATTRIBUTE_FILEFUNCTION( X2_ATTRIBUTE& aAttributeBase )
+ : X2_ATTRIBUTE()
+{
+ m_Prms = aAttributeBase.GetPrms();
+ m_z_order = 0;
+
+ //ensure at least 5 parameters
+ while( GetPrmCount() < 5 )
+ m_Prms.Add( wxEmptyString );
+
+ set_Z_Order();
+}
+
+const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetFileType()
+{
+ // the type of layer (Copper , Soldermask ... )
+ return m_Prms.Item( 1 );
+}
+
+const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetBrdLayerId()
+{
+ // the brd layer identifier: Ln (for Copper type) or Top, Bot
+ return m_Prms.Item( 2 );
+}
+
+const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetBrdLayerSide()
+{
+ if( IsCopper() )
+ // the brd layer identifier: Top, Bot, Inr
+ return m_Prms.Item( 3 );
+ else
+ // the brd layer identifier: Top, Bot ( same as GetBrdLayerId() )
+ return m_Prms.Item( 2 );
+}
+
+const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetLabel()
+{
+ if( IsCopper() )
+ return m_Prms.Item( 4 );
+ else
+ return m_Prms.Item( 3 );
+}
+
+
+bool X2_ATTRIBUTE_FILEFUNCTION::IsCopper()
+{
+ // the filefunction label, if any
+ return GetFileType().IsSameAs( wxT( "Copper" ), false );
+}
+
+// Initialize the z order priority of the current file, from its attributes
+// this priority is the order of layers from top to bottom to draw/display gerber images
+// Stack up is( from external copper layer to external)
+// copper, then solder paste, then solder mask, then silk screen.
+// and global stackup is Front (top) layers then internal copper layers then Back (bottom) layers
+void X2_ATTRIBUTE_FILEFUNCTION::set_Z_Order()
+{
+ m_z_order = -100; // low level
+ m_z_sub_order = 0;
+
+ if( IsCopper() )
+ {
+ // Copper layer: the priority is the layer Id
+ m_z_order = 0;
+ wxString num = GetBrdLayerId().Mid( 1 );
+ long lnum;
+ if( num.ToLong( &lnum ) )
+ m_z_sub_order = -lnum;
+ }
+
+ if( GetFileType().IsSameAs( wxT( "Paste" ), false ) )
+ {
+ // solder paste layer: the priority is top then bottom
+ m_z_order = 1; // for top
+
+ if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) )
+ m_z_order = -m_z_order;
+ }
+
+ if( GetFileType().IsSameAs( wxT( "Soldermask" ), false ) )
+ {
+ // solder mask layer: the priority is top then bottom
+ m_z_order = 2; // for top
+
+ if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) )
+ m_z_order = -m_z_order;
+ }
+
+ if( GetFileType().IsSameAs( wxT( "Legend" ), false ) )
+ {
+ // Silk screen layer: the priority is top then bottom
+ m_z_order = 3; // for top
+
+ if( GetFileType().IsSameAs( wxT( "Legend" ), false ) )
+
+ if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) )
+ m_z_order = -m_z_order;
+ }
+}
+
diff --git a/gerbview/class_X2_gerber_attributes.h b/gerbview/class_X2_gerber_attributes.h
new file mode 100644
index 0000000..cdd68b5
--- /dev/null
+++ b/gerbview/class_X2_gerber_attributes.h
@@ -0,0 +1,178 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_X2_gerber_attributes.h
+ */
+
+#ifndef _CLASS_X2_GERBER_ATTRIBUTE_H_
+#define _CLASS_X2_GERBER_ATTRIBUTE_H_
+
+/*
+ * Manage the gerber extensions (attributes) in the new X2 version
+ * only few extensions are handled
+ * See http://www.ucamco.com/files/downloads/file/81/the_gerber_file_format_specification.pdf
+ *
+ * gerber attributes in the new X2 version look like:
+ * %TF.FileFunction,Copper,L1,Top*%
+ *
+ * Currently:
+ * .FileFunction .FileFunction Identifies the file’s function in the PCB.
+ * Other Standard Attributes, not yet used in Gerbview:
+ * .Part Identifies the part the file represents, e.g. a single PCB
+ * .MD5 Sets the MD5 file signature or checksum.
+ */
+
+#include <wx/arrstr.h>
+
+/**
+ * class X2_ATTRIBUTE
+ * The attribute value consists of a number of substrings separated by a “,”
+*/
+
+class X2_ATTRIBUTE
+{
+protected:
+ wxArrayString m_Prms; ///< the list of parameters (after TF) in gbr file
+ ///< the first one is the attribute name,
+ ///< if starting by '.'
+
+public:
+ X2_ATTRIBUTE();
+ ~X2_ATTRIBUTE();
+
+ /**
+ * @return the parameters list read in TF command.
+ */
+ wxArrayString& GetPrms() { return m_Prms; }
+
+ /**
+ * @return a parameter read in TF command.
+ * @param aIdx = the index of the parameter
+ * aIdx = 0 is the parameter read after the TF function
+ * (the same as GetAttribute())
+ */
+ const wxString& GetPrm( int aIdx );
+
+ /**
+ * @return the attribute name (for instance .FileFunction)
+ * which is given by TF command (i.e. the first parameter read).
+ */
+ const wxString& GetAttribute();
+
+ /**
+ * @return the number of parameters read in TF command.
+ */
+ int GetPrmCount() { return int( m_Prms.GetCount() ); }
+
+ /**
+ * parse a TF command terminated with a % and fill m_Prms
+ * by the parameters found.
+ * @param aFile = a FILE* ptr to the current Gerber file.
+ * @param aBuffer = the buffer containing current Gerber data (can be null)
+ * @param aBuffSize = the size of the buffer
+ * @param aText = a pointer to the first char to read from Gerber data stored in aBuffer
+ * After parsing, text points the last char of the command line ('%') (X2 mode)
+ * or the end of line if the line does not contain '%' or aBuffer == NULL (X1 mode)
+ * @return true if no error.
+ */
+ bool ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, char* &aText );
+
+ /**
+ * Debug function: pring using wxLogMessage le list of parameters
+ */
+ void DbgListPrms();
+
+ /**
+ * return true if the attribute is .FileFunction
+ */
+ bool IsFileFunction()
+ {
+ return GetAttribute().IsSameAs( wxT(".FileFunction"), false );
+ }
+
+ /**
+ * return true if the attribute is .MD5
+ */
+ bool IsFileMD5()
+ {
+ return GetAttribute().IsSameAs( wxT(".MD5"), false );
+ }
+
+ /**
+ * return true if the attribute is .Part
+ */
+ bool IsFilePart()
+ {
+ return GetAttribute().IsSameAs( wxT(".Part"), false );
+ }
+};
+
+/**
+ * class X2_ATTRIBUTE_FILEFUNCTION ( from %TF.FileFunction in Gerber file)
+ * Example file function:
+ * %TF.FileFunction,Copper,L1,Top*%
+ * - Type. Such as copper, solder mask etc.
+ * - Position. Specifies where the file appears in the PCB layer structure.
+ * Corresponding position substring:
+ * Copper layer: L1, L2, L3...to indicate the layer position followed by Top, Inr or
+ * Bot. L1 is always the top copper layer. E.g. L2,Inr.
+ * Extra layer, e.g. solder mask: Top or Bot – defines the attachment of the layer.
+ * Drill/rout layer: E.g. 1,4 – where 1 is the start and 4 is the end copper layer. The
+ * pair 1,4 defines the span of the drill/rout file
+ * Optional index. This can be used in instances where for example there are two solder
+ * masks on the same side. The index counts from the PCB surface outwards.
+ */
+
+class X2_ATTRIBUTE_FILEFUNCTION : public X2_ATTRIBUTE
+{
+ int m_z_order; // the z order of the layer for a board
+ int m_z_sub_order; // the z sub_order of the copper layer for a board
+
+public:
+ X2_ATTRIBUTE_FILEFUNCTION( X2_ATTRIBUTE& aAttributeBase );
+
+ bool IsCopper(); ///< return true if the filefunction type is "Copper"
+
+ const wxString& GetFileType(); ///< the type of layer (Copper, Soldermask ... )
+ const wxString& GetBrdLayerId(); ///< the brd layer identifier: Ln, only for Copper type
+ ///< or Top, Bot for other types
+ const wxString& GetBrdLayerSide(); ///< the brd layer Pos: Top, Bot, Inr
+ ///< same as GetBrdLayerId() for non copper type
+ const wxString& GetLabel(); ///< the filefunction label, if any
+
+ int GetZOrder() { return m_z_order; } ///< the Order of the board layer,
+ ///< from front (Top) side to back (Bot) side
+ int GetZSubOrder() { return m_z_sub_order; } ///< the Order of the bdr copper layer,
+ ///< from front (Top) side to back (Bot) side
+
+private:
+
+ /**
+ * Initialize the z order priority of the current file, from its attributes
+ */
+ void set_Z_Order();
+};
+
+#endif // _CLASS_X2_GERBER_ATTRIBUTE_H_
diff --git a/gerbview/class_am_param.cpp b/gerbview/class_am_param.cpp
new file mode 100644
index 0000000..63306a4
--- /dev/null
+++ b/gerbview/class_am_param.cpp
@@ -0,0 +1,251 @@
+/**
+ * @file class_am_param.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <class_am_param.h>
+#include <class_aperture_macro.h>
+
+extern int ReadInt( char*& text, bool aSkipSeparator = true );
+extern double ReadDouble( char*& text, bool aSkipSeparator = true );
+
+/* Class AM_PARAM
+ * holds a parameter value for an "aperture macro" as defined within
+ * standard RS274X. The parameter can be a constant, i.e. "immediate" parameter,
+ * or depend on some defered values, defined in a D_CODE, by the ADD command.
+ * Note the actual value could need an evaluation from an arithmetical expression
+ * items in the expression are stored in .
+ * A simple definition is just a value stored in one item in m_paramStack
+ */
+AM_PARAM::AM_PARAM( )
+{
+ m_index = -1;
+}
+
+/**
+ * Function IsImmediate
+ * tests if this AM_PARAM holds an immediate parameter or has parameter
+ * held by an owning D_CODE.
+ */
+bool AM_PARAM::IsImmediate() const
+{
+ bool isimmediate = true;
+ for( unsigned ii = 0; ii < m_paramStack.size(); ii++ )
+ {
+ if( m_paramStack[ii].IsDefered() )
+ { // a defered value is found in operand list,
+ // so the parameter is not immediate
+ isimmediate = false;
+ break;
+ }
+ }
+ return isimmediate;
+}
+
+double AM_PARAM::GetValue( const D_CODE* aDcode ) const
+{
+ double paramvalue = 0.0;
+ double curr_value = 0.0;
+ parm_item_type state = POPVALUE;
+
+ for( unsigned ii = 0; ii < m_paramStack.size(); ii++ )
+ {
+ AM_PARAM_ITEM item = m_paramStack[ii];
+ switch( item.GetType() )
+ {
+ case ADD:
+ case SUB:
+ case MUL:
+ case DIV: // just an operator for next parameter value: store it
+ state = item.GetType();
+ break;
+
+ case PUSHPARM:
+ // get the parameter from the aDcode
+ if( aDcode ) // should be always true here
+ {
+ if( item.GetIndex() <= aDcode->GetParamCount() )
+ curr_value = aDcode->GetParam( item.GetIndex() );
+ else // Get parameter from local param definition
+ {
+ const APERTURE_MACRO * am_parent = aDcode->GetMacro();
+ curr_value = am_parent->GetLocalParam( aDcode, item.GetIndex() );
+ }
+ }
+ else
+ {
+ wxLogDebug( wxT( "AM_PARAM::GetValue(): NULL param aDcode\n" ) );
+ }
+ // Fall through
+ case PUSHVALUE: // a value is on the stack:
+ if( item.GetType() == PUSHVALUE )
+ curr_value = item.GetValue();
+ switch( state )
+ {
+ case POPVALUE:
+ paramvalue = curr_value;
+ break;
+
+ case ADD:
+ paramvalue += curr_value;
+ break;
+
+ case SUB:
+ paramvalue -= curr_value;
+ break;
+
+ case MUL:
+ paramvalue *= curr_value;
+ break;
+
+ case DIV:
+ paramvalue /= curr_value;
+ break;
+
+ default:
+ wxLogDebug( wxT( "AM_PARAM::GetValue() : unexpected operator\n" ) );
+ break;
+ }
+ break;
+
+ default:
+ wxLogDebug( wxT( "AM_PARAM::GetValue(): unexpected type\n" ) );
+ break;
+ }
+ }
+ return paramvalue;
+}
+
+/**
+ * add an operator/operand to the current stack
+ * aType = NOP, PUSHVALUE, PUSHPARM, ADD, SUB, MUL, DIV, EQUATE
+ * aValue required only for PUSHVALUE (double) or PUSHPARM (int) aType.
+ */
+void AM_PARAM::PushOperator( parm_item_type aType, double aValue )
+{
+ AM_PARAM_ITEM item( aType, aValue);
+ m_paramStack.push_back( item );
+}
+
+void AM_PARAM::PushOperator( parm_item_type aType, int aValue )
+{
+ AM_PARAM_ITEM item( aType, aValue);
+ m_paramStack.push_back( item );
+}
+
+/**
+ * Function ReadParam
+ * Read one aperture macro parameter
+ * a parameter can be:
+ * a number
+ * a reference to an aperture definition parameter value: $1 ot $3 ...
+ * a parameter definition can be complex and have operators between numbers and/or other parameter
+ * like $1+3 or $2x2..
+ * Note minus sign is not always an operator. It can be the sign of a value.
+ * Parameters are separated by a comma ( of finish by *)
+ * @param aText = pointer to the parameter to read. Will be modified to point to the next field
+ * @return true if a param is read, or false
+ */
+bool AM_PARAM::ReadParam( char*& aText )
+{
+ bool found = false;
+ int ivalue;
+ double dvalue;
+ bool end = false;
+
+ while( !end )
+ {
+ switch( *aText )
+ {
+ case ',':
+ aText++;
+ // fall through
+ case 0: // EOL
+ case '*': // Terminator in a gerber command
+ end = true;
+ break;
+
+ case ' ':
+ aText++;
+ break;
+
+ case '$':
+ // defered value defined later, in ADD command which define defered parameters
+ ++aText;
+ ivalue = ReadInt( aText, false );
+ if( m_index < 1 )
+ SetIndex( ivalue );
+ PushOperator( PUSHPARM, ivalue );
+ found = true;
+ break;
+
+ case '/':
+ PushOperator( DIV );
+ aText++;
+ break;
+
+ case 'x':
+ case 'X':
+ PushOperator( MUL );
+ aText++;
+ break;
+
+ case '-':
+ case '+':
+ // Test if this is an operator between 2 params, or the sign of a value
+ if( m_paramStack.size() > 0 && !m_paramStack.back().IsOperator() )
+ { // Seems an operator
+ PushOperator( *aText == '+' ? ADD : SUB );
+ aText++;
+ }
+ else
+ { // seems the sign of a value
+ dvalue = ReadDouble( aText, false );
+ PushOperator( PUSHVALUE, dvalue );
+ found = true;
+ }
+ break;
+
+ case '=': // A local definition found like $4=$3/2
+ // At this point, one defered parameter is expected to be read.
+ // this parameter value (the index) is stored in m_index.
+ // The list of items is cleared
+ aText++;
+ m_paramStack.clear();
+ found = false;
+ break;
+
+ default:
+ dvalue = ReadDouble( aText, false );
+ PushOperator( PUSHVALUE, dvalue );
+ found = true;
+ break;
+ }
+ }
+
+ return found;
+}
diff --git a/gerbview/class_am_param.h b/gerbview/class_am_param.h
new file mode 100644
index 0000000..c60e311
--- /dev/null
+++ b/gerbview/class_am_param.h
@@ -0,0 +1,268 @@
+/**
+ * @file class_am_param.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _AM_PARAM_H_
+#define _AM_PARAM_H_
+
+/*
+ * An aperture macro defines a complex shape and is a list of aperture primitives.
+ * Each aperture primitive defines a simple shape (circle, rect, regular polygon...)
+ * Inside a given aperture primitive, a fixed list of parameters defines info
+ * about the shape: size, thickness, number of vertex ...
+ *
+ * Each parameter can be an immediate value or a defered value.
+ * When value is defered, it is defined when the aperture macro is instancied by
+ * an ADD macro command
+ *
+ * Actual values of a parameter can also be the result of an arithmetic operation.
+ *
+ * Here is some examples:
+ * An immediate value:
+ * 3.5
+ * A deferend value:
+ * $2 means: replace me by the second value given in the ADD command
+ * Actual value as arithmetic calculation:
+ * $2/2+1
+ *
+ * Note also a defered parameter can be defined in aperture macro,
+ * but outside aperture primitives. Example
+ * %AMRECTHERM*
+ * $4=$3/2* parameter $4 is half value of parameter $3
+ * 21,1,$1-$3,$2-$3,0-$1/2-$4,0-$2/2-$4,0*
+ * For the aperture primitive, parameters $1 to $3 will be defined in ADD command,
+ * and $4 is defined inside the macro
+ *
+ * Some examples of aperture macro definition
+ * A simple definition, no parameters:
+ * %AMMOIRE10*
+ * 6,0,0,0.350000,0.005,0.050,3,0.005,0.400000,0.0*%
+ * Example of instanciation:
+ * %ADD19THERM19*%
+ *
+ * A simple definition, one parameter:
+ * %AMCIRCLE*
+ * 1,1,$1,0,0*
+ * Example of instanciation:
+ * %ADD11CIRCLE,.5*%
+ *
+ * A definition, with parameters and arithmetic operations:
+ * %AMVECTOR*
+ * 2,1,$1,0,0,$2+1,$3,-135*%
+ * Example of instanciation:
+ * %ADD12VECTOR,0.05X0X0*%
+ *
+ * A more complicated aperture macro definition, with parameters and arihmetic operations:
+ * %AMRNDREC*
+ * 0 this is a comment*
+ * 21,1,$1+$1,$2+$2-$3-$3,0,0,0*
+ * 21,1,$1+$1-$3-$3,$2+$2,0,0,0*
+ * 1,1,$3+$3,$1-$3,$2-$3*
+ * 1,1,$3+$3,$3-$1,$2-$3*
+ * 1,1,$3+$3,$1-$3,$3-$2*
+ * 1,1,$3+$3,$3-$1,$3-$2*%
+ * Example of instanciation:
+ *
+ * A more complicated sample of aperture macro definition:
+ * G04 Rectangular Thermal Macro, params: W/2, H/2, T/2 *
+ * %AMRECTHERM*
+ * $4=$3/2*
+ * 21,1,$1-$3,$2-$3,0-$1/2-$4,0-$2/2-$4,0*
+ * 21,1,$1-$3,$2-$3,0-$1/2-$4,$2/2+$4,0*
+ * 21,1,$1-$3,$2-$3,$1/2+$4,0-$2/2-$4,0*
+ * 21,1,$1-$3,$2-$3,$1/2+$4,$2/2+$4,0*%
+ * Example of instanciation:
+ * %ADD28RECTHERM,0.035591X0.041496X0.005000*%
+ */
+
+#include <vector>
+
+#include <dcode.h>
+/*
+Values of a parameter can be the result of an arithmetic operation,
+between immediate values and defered value.
+From an idea found in Gerbv, here is the way to evaluate a parameter.
+a AM_PARAM_ITEM holds info about operands and operators in a parameter definition
+( a AM_PARAM ) like $2+$2-$3-$3/2
+
+There is no precedence defined in gerber RS274X, so actual value is calculated step to step.
+Parameter definition is described by a very primitive assembler.
+This "program "should describe how to calculate the parameter.
+The assembler consist of 8 instruction intended for a stackbased machine.
+The instructions are:
+NOP, PUSHVALUE, PUSHPARM, ADD, SUB, MUL, DIV, EQUATE
+
+The instructions
+----------------
+NOP : The no operation. This is the default instruction and are
+ added as a security measure.
+PUSHVALUE : Pushes an arithmetical value on the stack. This machine only works with floats
+ on the stack.
+PUSHPARM: Pushes a defered parameter onto the stack. Gerber aperture macros accepts
+ parameters to be set when later declared, so the same macro can
+ be used at several instances. Which parameter to be set is an integer
+ and starts with 1. definition is like $1 or $3
+ADD : The mathematical operation +. Takes the two uppermost values on the
+ the stack, adds them and pushes the result back onto the stack.
+SUB : Same as ADD, but with -.
+MUL : Same as ADD, but with *.
+DIV : Same as ADD, but with /.
+POPVALUE : used when evaluate the expression: store current calculated value
+*/
+
+enum parm_item_type
+{
+ NOP, PUSHVALUE, PUSHPARM, ADD, SUB, MUL, DIV, POPVALUE
+};
+
+/**
+ * Class AM_PARAM
+ * holds an operand for an AM_PARAM as defined within
+ * standard RS274X. The \a value field can be a constant, i.e. "immediate"
+ * parameter or it may not be used if this param is going to defer to the
+ * referencing aperture macro. In that case, the \a index field is an index
+ * into the aperture macro's parameters.
+ */
+class AM_PARAM_ITEM
+{
+private:
+ parm_item_type m_type; // the type of item
+ double m_dvalue; // the value, for PUSHVALUE type item
+ int m_ivalue; // the integer value, for PUSHPARM type item
+
+public:
+ AM_PARAM_ITEM( parm_item_type aType, double aValue )
+ {
+ m_type = aType;
+ m_dvalue = aValue;
+ m_ivalue = 0;
+ }
+ AM_PARAM_ITEM( parm_item_type aType, int aValue )
+ {
+ m_type = aType;
+ m_dvalue = 0.0;
+ m_ivalue = aValue;
+ }
+
+ void SetValue( double aValue )
+ {
+ m_dvalue = aValue;
+ }
+ double GetValue( ) const
+ {
+ return m_dvalue;
+ }
+ parm_item_type GetType() const
+ {
+ return m_type;
+ }
+ unsigned GetIndex() const
+ {
+ return (unsigned) m_ivalue;
+ }
+ bool IsOperator() const
+ {
+ return m_type == ADD || m_type == SUB || m_type == MUL || m_type == DIV;
+ }
+ bool IsOperand() const
+ {
+ return m_type == PUSHVALUE || m_type == PUSHPARM;
+ }
+ bool IsDefered() const
+ {
+ return m_type == PUSHPARM;
+ }
+};
+
+/**
+ * Class AM_PARAM
+ * holds a parameter value for an "aperture macro" as defined within
+ * standard RS274X. The parameter can be a constant, i.e. "immediate" parameter,
+ * or depend on some defered values, defined in a D_CODE, by the ADD command.
+ * Note the actual value could need an evaluation from an arithmetical expression
+ * items in the expression are stored in .
+ * A simple definition is just a value stored in one item in m_paramStack
+ */
+class AM_PARAM
+{
+private:
+ int m_index; // has meaning to define parameter local to an aperture macro
+ std::vector<AM_PARAM_ITEM> m_paramStack; // list of operands/operators to evalutate the actual value
+ // if a par def is $3/2, there are 3 items in stack:
+ // 3 (type PUSHPARM) , / (type DIV), 2 (type PUSHVALUE)
+
+public:
+ AM_PARAM();
+
+ /**
+ * function PushOperator
+ * add an operator/operand to the current stack
+ * @param aType = the type of item (NOP, PUSHVALUE, PUSHPARM, ADD, SUB, MUL, DIV, EQUATE)
+ * @param aValue = the item value, double for PUSHVALUE or int for PUSHPARM type.
+ */
+ void PushOperator( parm_item_type aType, double aValue );
+ void PushOperator( parm_item_type aType, int aValue = 0);
+
+ double GetValue( const D_CODE* aDcode ) const;
+
+ /**
+ * Function IsImmediate
+ * tests if this AM_PARAM holds an immediate parameter or is a pointer
+ * into a parameter held by an owning D_CODE.
+ * @return true if the value is immediate, i.e. no defered value in operands used in its definition
+ */
+ bool IsImmediate() const;
+
+ unsigned GetIndex() const
+ {
+ return (unsigned) m_index;
+ }
+
+ void SetIndex( int aIndex )
+ {
+ m_index = aIndex;
+ }
+
+ /**
+ * Function ReadParam
+ * Read one aperture macro parameter
+ * a parameter can be:
+ * a number
+ * a reference to an aperture definition parameter value: $1 ot $3 ...
+ * a parameter definition can be complex and have operators between numbers and/or other parameter
+ * like $1+3 or $2x2..
+ * Parameters are separated by a comma ( of finish by *)
+ * @param aText = pointer to the parameter to read. Will be modified to point to the next field
+ * @return true if a param is read, or false
+ */
+ bool ReadParam( char*& aText );
+};
+
+typedef std::vector<AM_PARAM> AM_PARAMS;
+
+#endif // _AM_PARAM_H_
diff --git a/gerbview/class_aperture_macro.cpp b/gerbview/class_aperture_macro.cpp
new file mode 100644
index 0000000..0c48a5b
--- /dev/null
+++ b/gerbview/class_aperture_macro.cpp
@@ -0,0 +1,811 @@
+/**
+ * @file class_aperture_macro.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <macros.h>
+#include <trigo.h>
+#include <gr_basic.h>
+
+#include <gerbview.h>
+#include <class_GERBER.h>
+
+
+
+/**
+ * Function scaletoIU
+ * converts a distance given in floating point to our internal units
+ */
+extern int scaletoIU( double aCoord, bool isMetric ); // defined it rs274d_read_XY_and_IJ_coordiantes.cpp
+
+/**
+ * Function mapPt
+ * translates a point from the aperture macro coordinate system to our
+ * deci-mils coordinate system.
+ * @return wxPoint - The GerbView coordinate system vector.
+ */
+static wxPoint mapPt( double x, double y, bool isMetric )
+{
+ wxPoint ret( scaletoIU( x, isMetric ), scaletoIU( y, isMetric ) );
+
+ return ret;
+}
+
+/**
+ * Function mapExposure
+ * translates the first parameter from an aperture macro into a current
+ * exposure setting.
+ * @param aParent = a GERBER_DRAW_ITEM that handle:
+ * ** m_Exposure A dynamic setting which can change throughout the
+ * reading of the gerber file, and it indicates whether the current tool
+ * is lit or not.
+ * ** m_ImageNegative A dynamic setting which can change throughout the reading
+ * of the gerber file, and it indicates whether the current D codes are to
+ * be interpreted as erasures or not.
+ * @return true to draw with current color, false to draw with alt color (erase)
+ */
+bool AM_PRIMITIVE::mapExposure( GERBER_DRAW_ITEM* aParent )
+{
+ bool exposure;
+ switch( primitive_id )
+ {
+ case AMP_CIRCLE:
+ case AMP_LINE2:
+ case AMP_LINE20:
+ case AMP_LINE_CENTER:
+ case AMP_LINE_LOWER_LEFT:
+ case AMP_OUTLINE:
+ case AMP_THERMAL:
+ case AMP_POLYGON:
+ // All have an exposure parameter and can return true or false
+ switch( GetExposure(aParent) )
+ {
+ case 0: // exposure always OFF
+ exposure = false;
+ break;
+
+ default:
+ case 1: // exposure always OON
+ exposure = true;
+ break;
+
+ case 2: // reverse exposure
+ exposure = !aParent->GetLayerPolarity();
+ }
+ break;
+
+ case AMP_MOIRE:
+ case AMP_EOF:
+ case AMP_UNKNOWN:
+ default:
+ return true; // All have no exposure parameter and must return true (no change for exposure)
+ break;
+ }
+
+ return exposure ^ aParent->m_imageParams->m_ImageNegative;
+}
+
+
+/**
+ * Function GetExposure
+ * returns the first parameter in integer form. Some but not all primitives
+ * use the first parameter as an exposure control.
+ */
+int AM_PRIMITIVE::GetExposure(GERBER_DRAW_ITEM* aParent) const
+{
+ // No D_CODE* for GetValue()
+ wxASSERT( params.size() && params[0].IsImmediate() );
+ return (int) params[0].GetValue( aParent->GetDcodeDescr() );
+}
+
+/**
+ * Function DrawBasicShape
+ * Draw the primitive shape for flashed items.
+ */
+void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
+ EDA_RECT* aClipBox,
+ wxDC* aDC,
+ EDA_COLOR_T aColor, EDA_COLOR_T aAltColor,
+ wxPoint aShapePos,
+ bool aFilledShape )
+{
+ static std::vector<wxPoint> polybuffer; // create a static buffer to avoid a lot of memory reallocation
+ polybuffer.clear();
+
+ wxPoint curPos = aShapePos;
+ D_CODE* tool = aParent->GetDcodeDescr();
+ double rotation;
+ if( mapExposure( aParent ) == false )
+ {
+ std::swap( aColor, aAltColor );
+ }
+
+ switch( primitive_id )
+ {
+ case AMP_CIRCLE: // Circle, given diameter and position
+ {
+ /* Generated by an aperture macro declaration like:
+ * "1,1,0.3,0.5, 1.0*"
+ * type (1), exposure, diameter, pos.x, pos.y
+ * type is not stored in parameters list, so the first parameter is exposure
+ */
+ curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), m_GerbMetric );
+ curPos = aParent->GetABPosition( curPos );
+ int radius = scaletoIU( params[1].GetValue( tool ), m_GerbMetric ) / 2;
+ if( !aFilledShape )
+ GRCircle( aClipBox, aDC, curPos, radius, 0, aColor );
+ else
+ GRFilledCircle( aClipBox, aDC, curPos, radius, aColor );
+ }
+ break;
+
+ case AMP_LINE2:
+ case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
+ {
+ /* Generated by an aperture macro declaration like:
+ * "2,1,0.3,0,0, 0.5, 1.0,-135*"
+ * type (2), exposure, width, start.x, start.y, end.x, end.y, rotation
+ * type is not stored in parameters list, so the first parameter is exposure
+ */
+ ConvertShapeToPolygon( aParent, polybuffer );
+
+ // shape rotation:
+ rotation = params[6].GetValue( tool ) * 10.0;
+ if( rotation != 0)
+ {
+ for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+ RotatePoint( &polybuffer[ii], -rotation );
+ }
+
+ // Move to current position:
+ for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+ {
+ polybuffer[ii] += curPos;
+ polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
+ }
+
+ GRClosedPoly( aClipBox, aDC,
+ polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
+ }
+ break;
+
+ case AMP_LINE_CENTER:
+ {
+ /* Generated by an aperture macro declaration like:
+ * "21,1,0.3,0.03,0,0,-135*"
+ * type (21), exposure, ,width, height, center pos.x, center pos.y, rotation
+ * type is not stored in parameters list, so the first parameter is exposure
+ */
+ ConvertShapeToPolygon( aParent, polybuffer );
+
+ // shape rotation:
+ rotation = params[5].GetValue( tool ) * 10.0;
+ if( rotation != 0 )
+ {
+ for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+ RotatePoint( &polybuffer[ii], -rotation );
+ }
+
+ // Move to current position:
+ for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+ {
+ polybuffer[ii] += curPos;
+ polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
+ }
+
+ GRClosedPoly( aClipBox, aDC,
+ polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
+ }
+ break;
+
+ case AMP_LINE_LOWER_LEFT:
+ {
+ /* Generated by an aperture macro declaration like:
+ * "22,1,0.3,0.03,0,0,-135*"
+ * type (22), exposure, ,width, height, corner pos.x, corner pos.y, rotation
+ * type is not stored in parameters list, so the first parameter is exposure
+ */
+ ConvertShapeToPolygon( aParent, polybuffer );
+
+ // shape rotation:
+ rotation = params[5].GetValue( tool ) * 10.0;
+ if( rotation != 0)
+ {
+ for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+ RotatePoint( &polybuffer[ii], -rotation );
+ }
+
+ // Move to current position:
+ for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+ {
+ polybuffer[ii] += curPos;
+ polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
+ }
+
+ GRClosedPoly( aClipBox, aDC,
+ polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
+ }
+ break;
+
+ case AMP_THERMAL:
+ {
+ /* Generated by an aperture macro declaration like:
+ * "7, 0,0,1.0,0.3,0.01,-13*"
+ * type (7), center.x , center.y, outside diam, inside diam, crosshair thickness, rotation
+ * type is not stored in parameters list, so the first parameter is center.x
+ */
+ curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ), m_GerbMetric );
+ ConvertShapeToPolygon( aParent, polybuffer );
+
+ // shape rotation:
+ rotation = params[5].GetValue( tool ) * 10.0;
+
+ // Because a thermal shape has 4 identical sub-shapes, only one is created in polybuffer.
+ // We must draw 4 sub-shapes rotated by 90 deg
+ std::vector<wxPoint> subshape_poly;
+ for( int ii = 0; ii < 4; ii++ )
+ {
+ subshape_poly = polybuffer;
+ double sub_rotation = rotation + 900 * ii;
+ for( unsigned jj = 0; jj < subshape_poly.size(); jj++ )
+ RotatePoint( &subshape_poly[jj], -sub_rotation );
+
+ // Move to current position:
+ for( unsigned jj = 0; jj < subshape_poly.size(); jj++ )
+ {
+ subshape_poly[jj] += curPos;
+ subshape_poly[jj] = aParent->GetABPosition( subshape_poly[jj] );
+ }
+
+ GRClosedPoly( aClipBox, aDC,
+ subshape_poly.size(), &subshape_poly[0], true, aAltColor,
+ aAltColor );
+ }
+ }
+ break;
+
+ case AMP_MOIRE: // A cross hair with n concentric circles
+ {
+ curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ),
+ m_GerbMetric );
+
+ /* Generated by an aperture macro declaration like:
+ * "6,0,0,0.125,.01,0.01,3,0.003,0.150,0"
+ * type(6), pos.x, pos.y, diam, penwidth, gap, circlecount, crosshair thickness, crosshaire len, rotation
+ * type is not stored in parameters list, so the first parameter is pos.x
+ */
+ int outerDiam = scaletoIU( params[2].GetValue( tool ), m_GerbMetric );
+ int penThickness = scaletoIU( params[3].GetValue( tool ), m_GerbMetric );
+ int gap = scaletoIU( params[4].GetValue( tool ), m_GerbMetric );
+ int numCircles = KiROUND( params[5].GetValue( tool ) );
+
+ // Draw circles:
+ wxPoint center = aParent->GetABPosition( curPos );
+ // adjust outerDiam by this on each nested circle
+ int diamAdjust = (gap + penThickness); //*2; //Should we use * 2 ?
+ for( int i = 0; i < numCircles; ++i, outerDiam -= diamAdjust )
+ {
+ if( outerDiam <= 0 )
+ break;
+ if( !aFilledShape )
+ {
+ // draw the border of the pen's path using two circles, each as narrow as possible
+ GRCircle( aClipBox, aDC, center, outerDiam / 2, 0, aColor );
+ GRCircle( aClipBox, aDC, center, outerDiam / 2 - penThickness, 0, aColor );
+ }
+ else // Filled mode
+ {
+ GRCircle( aClipBox, aDC, center,
+ (outerDiam - penThickness) / 2, penThickness, aColor );
+ }
+ }
+
+ // Draw the cross:
+ ConvertShapeToPolygon( aParent, polybuffer );
+
+ rotation = params[8].GetValue( tool ) * 10.0;
+ for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+ {
+ // shape rotation:
+ RotatePoint( &polybuffer[ii], -rotation );
+ // Move to current position:
+ polybuffer[ii] += curPos;
+ polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
+ }
+
+ GRClosedPoly( aClipBox, aDC,
+ polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
+ }
+ break;
+
+ case AMP_OUTLINE:
+ {
+ /* Generated by an aperture macro declaration like:
+ * "4,1,3,0.0,0.0,0.0,0.5,0.5,0.5,0.5,0.0,-25"
+ * type(4), exposure, corners count, corner1.x, corner.1y, ..., rotation
+ * type is not stored in parameters list, so the first parameter is exposure
+ */
+ int numPoints = (int) params[1].GetValue( tool );
+ rotation = params[numPoints * 2 + 4].GetValue( tool ) * 10.0;
+ wxPoint pos;
+ // Read points. numPoints does not include the starting point, so add 1.
+ for( int i = 0; i<numPoints + 1; ++i )
+ {
+ int jj = i * 2 + 2;
+ pos.x = scaletoIU( params[jj].GetValue( tool ), m_GerbMetric );
+ pos.y = scaletoIU( params[jj + 1].GetValue( tool ), m_GerbMetric );
+ polybuffer.push_back(pos);
+ }
+ // rotate polygon and move it to the actual position
+ // shape rotation:
+ for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+ {
+ RotatePoint( &polybuffer[ii], -rotation );
+ }
+
+ // Move to current position:
+ for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+ {
+ polybuffer[ii] += curPos;
+ polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
+ }
+
+ GRClosedPoly( aClipBox, aDC,
+ polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
+ }
+ break;
+
+ case AMP_POLYGON: // Is a regular polygon
+ /* Generated by an aperture macro declaration like:
+ * "5,1,0.6,0,0,0.5,25"
+ * type(5), exposure, vertices count, pox.x, pos.y, diameter, rotation
+ * type is not stored in parameters list, so the first parameter is exposure
+ */
+ curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), m_GerbMetric );
+ // Creates the shape:
+ ConvertShapeToPolygon( aParent, polybuffer );
+
+ // rotate polygon and move it to the actual position
+ rotation = params[5].GetValue( tool ) * 10.0;
+ for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
+ {
+ RotatePoint( &polybuffer[ii], -rotation );
+ polybuffer[ii] += curPos;
+ polybuffer[ii] = aParent->GetABPosition( polybuffer[ii] );
+ }
+ GRClosedPoly( aClipBox, aDC,
+ polybuffer.size(), &polybuffer[0], aFilledShape, aColor, aColor );
+ break;
+
+ case AMP_EOF:
+ // not yet supported, waiting for you.
+ break;
+
+ case AMP_UNKNOWN:
+ default:
+ DBG( printf( "AM_PRIMITIVE::DrawBasicShape() err: unknown prim id %d\n",primitive_id) );
+ break;
+ }
+}
+
+
+/**
+ * Function ConvertShapeToPolygon (virtual)
+ * convert a shape to an equivalent polygon.
+ * Arcs and circles are approximated by segments
+ * Useful when a shape is not a graphic primitive (shape with hole,
+ * rotated shape ... ) and cannot be easily drawn.
+ * note for some schapes conbining circles and solid lines (rectangles), only rectangles are converted
+ * because circles are very easy to draw (no rotation problem) so convert them in polygons,
+ * and draw them as polygons is not a good idea.
+ */
+void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,
+ std::vector<wxPoint>& aBuffer )
+{
+ D_CODE* tool = aParent->GetDcodeDescr();
+
+ switch( primitive_id )
+ {
+ case AMP_CIRCLE: // Circle, currently convertion not needed
+ break;
+
+ case AMP_LINE2:
+ case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
+ {
+ int width = scaletoIU( params[1].GetValue( tool ), m_GerbMetric );
+ wxPoint start = mapPt( params[2].GetValue( tool ),
+ params[3].GetValue( tool ), m_GerbMetric );
+ wxPoint end = mapPt( params[4].GetValue( tool ),
+ params[5].GetValue( tool ), m_GerbMetric );
+ wxPoint delta = end - start;
+ int len = KiROUND( EuclideanNorm( delta ) );
+
+ // To build the polygon, we must create a horizonta polygon starting to "start"
+ // and rotate it to have it end point to "end"
+ wxPoint currpt;
+ currpt.y += width / 2; // Upper left
+ aBuffer.push_back( currpt );
+ currpt.x = len; // Upper right
+ aBuffer.push_back( currpt );
+ currpt.y -= width; // lower right
+ aBuffer.push_back( currpt );
+ currpt.x = 0; // Upper left
+ aBuffer.push_back( currpt );
+
+ // Rotate rectangle and move it to the actual start point
+ double angle = ArcTangente( delta.y, delta.x );
+
+ for( unsigned ii = 0; ii < 4; ii++ )
+ {
+ RotatePoint( &aBuffer[ii], -angle );
+ aBuffer[ii] += start;
+ }
+ }
+ break;
+
+ case AMP_LINE_CENTER:
+ {
+ wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
+ wxPoint pos = mapPt( params[3].GetValue( tool ), params[4].GetValue( tool ), m_GerbMetric );
+
+ // Build poly:
+ pos.x -= size.x / 2;
+ pos.y -= size.y / 2; // Lower left
+ aBuffer.push_back( pos );
+ pos.y += size.y; // Upper left
+ aBuffer.push_back( pos );
+ pos.x += size.x; // Upper right
+ aBuffer.push_back( pos );
+ pos.y -= size.y; // lower right
+ aBuffer.push_back( pos );
+ }
+ break;
+
+ case AMP_LINE_LOWER_LEFT:
+ {
+ wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
+ wxPoint lowerLeft = mapPt( params[3].GetValue( tool ), params[4].GetValue(
+ tool ), m_GerbMetric );
+
+ // Build poly:
+ aBuffer.push_back( lowerLeft );
+ lowerLeft.y += size.y; // Upper left
+ aBuffer.push_back( lowerLeft );
+ lowerLeft.x += size.x; // Upper right
+ aBuffer.push_back( lowerLeft );
+ lowerLeft.y -= size.y; // lower right
+ aBuffer.push_back( lowerLeft );
+ }
+ break;
+
+ case AMP_THERMAL:
+ {
+ // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
+ // rotated by 90, 180 and 270 deg.
+ // params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
+ int outerRadius = scaletoIU( params[2].GetValue( tool ), m_GerbMetric ) / 2;
+ int innerRadius = scaletoIU( params[3].GetValue( tool ), m_GerbMetric ) / 2;
+ int halfthickness = scaletoIU( params[4].GetValue( tool ), m_GerbMetric ) / 2;
+ double angle_start = RAD2DECIDEG( asin( (double) halfthickness / innerRadius ) );
+
+ // Draw shape in the first cadrant (X and Y > 0)
+ wxPoint pos, startpos;
+
+ // Inner arc
+ startpos.x = innerRadius;
+ double angle_end = 900 - angle_start;
+ for( double angle = angle_start; angle < angle_end; angle += 100 )
+ {
+ pos = startpos;
+ RotatePoint( &pos, angle );
+ aBuffer.push_back( pos );
+ }
+
+ // Last point
+ pos = startpos;
+ RotatePoint( &pos, angle_end );
+ aBuffer.push_back( pos );
+
+ // outer arc
+ startpos.x = outerRadius;
+ startpos.y = 0;
+ angle_start = RAD2DECIDEG( asin( (double) halfthickness / outerRadius ) );
+ angle_end = 900 - angle_start;
+
+ // First point, near Y axis, outer arc
+ for( double angle = angle_end; angle > angle_start; angle -= 100 )
+ {
+ pos = startpos;
+ RotatePoint( &pos, angle );
+ aBuffer.push_back( pos );
+ }
+
+ // last point
+ pos = startpos;
+ RotatePoint( &pos, angle_start );
+ aBuffer.push_back( pos );
+
+ aBuffer.push_back( aBuffer[0] ); // Close poly
+ }
+ break;
+
+ case AMP_MOIRE: // A cross hair with n concentric circles. Only the cros is build as polygon
+ // because circles can be drawn easily
+ {
+ int crossHairThickness = scaletoIU( params[6].GetValue( tool ), m_GerbMetric );
+ int crossHairLength = scaletoIU( params[7].GetValue( tool ), m_GerbMetric );
+
+ // Create cross. First create 1/4 of the shape.
+ // Others point are the same, totated by 90, 180 and 270 deg
+ wxPoint pos( crossHairThickness / 2, crossHairLength / 2 );
+ aBuffer.push_back( pos );
+ pos.y = crossHairThickness / 2;
+ aBuffer.push_back( pos );
+ pos.x = -crossHairLength / 2;
+ aBuffer.push_back( pos );
+ pos.y = -crossHairThickness / 2;
+ aBuffer.push_back( pos );
+
+ // Copy the 4 shape, rotated by 90, 180 and 270 deg
+ for( int jj = 1; jj <= 3; jj ++ )
+ {
+ for( int ii = 0; ii < 4; ii++ )
+ {
+ pos = aBuffer[ii];
+ RotatePoint( &pos, jj*900 );
+ aBuffer.push_back( pos );
+ }
+ }
+ }
+ break;
+
+ case AMP_OUTLINE:
+ // already is a polygon. Do nothing
+ break;
+
+ case AMP_POLYGON: // Creates a regular polygon
+ {
+ int vertexcount = KiROUND( params[1].GetValue( tool ) );
+ int radius = scaletoIU( params[4].GetValue( tool ), m_GerbMetric ) / 2;
+ // rs274x said: vertex count = 3 ... 10, and the first corner is on the X axis
+ if( vertexcount < 3 )
+ vertexcount = 3;
+ if( vertexcount > 10 )
+ vertexcount = 10;
+ for( int ii = 0; ii <= vertexcount; ii++ )
+ {
+ wxPoint pos( radius, 0);
+ RotatePoint( &pos, ii * 3600 / vertexcount );
+ aBuffer.push_back( pos );
+ }
+ }
+ break;
+
+ case AMP_COMMENT:
+ case AMP_UNKNOWN:
+ case AMP_EOF:
+ break;
+ }
+}
+
+/** GetShapeDim
+ * Calculate a value that can be used to evaluate the size of text
+ * when displaying the D-Code of an item
+ * due to the complexity of the shape of some primitives
+ * one cannot calculate the "size" of a shape (only abounding box)
+ * but here, the "dimension" of the shape is the diameter of the primitive
+ * or for lines the width of the line
+ * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
+ * @return a dimension, or -1 if no dim to calculate
+ */
+int AM_PRIMITIVE::GetShapeDim( GERBER_DRAW_ITEM* aParent )
+{
+ int dim = -1;
+ D_CODE* tool = aParent->GetDcodeDescr();
+
+ switch( primitive_id )
+ {
+ case AMP_CIRCLE:
+ // params = exposure, diameter, pos.x, pos.y
+ dim = scaletoIU( params[1].GetValue( tool ), m_GerbMetric ); // Diameter
+ break;
+
+ case AMP_LINE2:
+ case AMP_LINE20: // Line with rectangle ends. (Width, start and end pos + rotation)
+ dim = scaletoIU( params[1].GetValue( tool ), m_GerbMetric ); // linne width
+ break;
+
+ case AMP_LINE_CENTER:
+ {
+ wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
+ dim = std::min(size.x, size.y);
+ }
+ break;
+
+ case AMP_LINE_LOWER_LEFT:
+ {
+ wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
+ dim = std::min(size.x, size.y);
+ }
+ break;
+
+ case AMP_THERMAL:
+ {
+ // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
+ // rotated by 90, 180 and 270 deg.
+ // params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
+ dim = scaletoIU( params[2].GetValue( tool ), m_GerbMetric ) / 2; // Outer diam
+ }
+ break;
+
+ case AMP_MOIRE: // A cross hair with n concentric circles.
+ dim = scaletoIU( params[7].GetValue( tool ), m_GerbMetric ); // = cross hair len
+ break;
+
+ case AMP_OUTLINE: // a free polygon :
+ // dim = min side of the bounding box (this is a poor criteria, but what is a good criteria b?)
+ {
+ // exposure, corners count, corner1.x, corner.1y, ..., rotation
+ int numPoints = (int) params[1].GetValue( tool );
+ // Read points. numPoints does not include the starting point, so add 1.
+ // and calculate the bounding box;
+ wxSize pos_min, pos_max, pos;
+ for( int i = 0; i<numPoints + 1; ++i )
+ {
+ int jj = i * 2 + 2;
+ pos.x = scaletoIU( params[jj].GetValue( tool ), m_GerbMetric );
+ pos.y = scaletoIU( params[jj + 1].GetValue( tool ), m_GerbMetric );
+ if( i == 0 )
+ pos_min = pos_max = pos;
+ else
+ {
+ // upper right corner:
+ if( pos_min.x > pos.x )
+ pos_min.x = pos.x;
+ if( pos_min.y > pos.y )
+ pos_min.y = pos.y;
+ // lower left corner:
+ if( pos_max.x < pos.x )
+ pos_max.x = pos.x;
+ if( pos_max.y < pos.y )
+ pos_max.y = pos.y;
+ }
+ }
+ // calculate dim
+ wxSize size;
+ size.x = pos_max.x - pos_min.x;
+ size.y = pos_max.y - pos_min.y;
+ dim = std::min( size.x, size.y );
+ }
+ break;
+
+ case AMP_POLYGON: // Regular polygon
+ dim = scaletoIU( params[4].GetValue( tool ), m_GerbMetric ) / 2; // Radius
+ break;
+
+ case AMP_COMMENT:
+ case AMP_UNKNOWN:
+ case AMP_EOF:
+ break;
+ }
+ return dim;
+}
+
+
+/**
+ * Function DrawApertureMacroShape
+ * Draw the primitive shape for flashed items.
+ * When an item is flashed, this is the shape of the item
+ */
+void APERTURE_MACRO::DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent,
+ EDA_RECT* aClipBox, wxDC* aDC,
+ EDA_COLOR_T aColor, EDA_COLOR_T aAltColor,
+ wxPoint aShapePos, bool aFilledShape )
+{
+ for( AM_PRIMITIVES::iterator prim_macro = primitives.begin();
+ prim_macro != primitives.end(); ++prim_macro )
+ {
+ prim_macro->DrawBasicShape( aParent, aClipBox, aDC,
+ aColor, aAltColor,
+ aShapePos,
+ aFilledShape );
+ }
+}
+
+/* Function HasNegativeItems
+ * return true if this macro has at least one aperture primitives
+ * that must be drawn in background color
+ * used to optimize screen refresh
+ */
+bool APERTURE_MACRO::HasNegativeItems( GERBER_DRAW_ITEM* aParent )
+{
+ for( AM_PRIMITIVES::iterator prim_macro = primitives.begin();
+ prim_macro != primitives.end(); ++prim_macro )
+ {
+ if( prim_macro->mapExposure( aParent ) == false ) // = is negative
+ return true;
+ }
+
+ return false;
+}
+
+
+/** GetShapeDim
+ * Calculate a value that can be used to evaluate the size of text
+ * when displaying the D-Code of an item
+ * due to the complexity of a shape using many primitives
+ * one cannot calculate the "size" of a shape (only abounding box)
+ * but most of aperture macro are using one or few primitives
+ * and the "dimension" of the shape is the diameter of the primitive
+ * (or the max diameter of primitives)
+ * @return a dimension, or -1 if no dim to calculate
+ */
+int APERTURE_MACRO::GetShapeDim( GERBER_DRAW_ITEM* aParent )
+{
+ int dim = -1;
+ for( AM_PRIMITIVES::iterator prim_macro = primitives.begin();
+ prim_macro != primitives.end(); ++prim_macro )
+ {
+ int pdim = prim_macro->GetShapeDim( aParent );
+ if( dim < pdim )
+ dim = pdim;
+ }
+
+ return dim;
+}
+
+
+/**
+ * function GetLocalParam
+ * Usually, parameters are defined inside the aperture primitive
+ * using immediate mode or defered mode.
+ * in defered mode the value is defined in a DCODE that want to use the aperture macro.
+ * But some parameters are defined outside the aperture primitive
+ * and are local to the aperture macro
+ * @return the value of a defered parameter defined inside the aperture macro
+ * @param aParamId = the param id (defined by $3 or $5 ..) to evaluate
+ */
+double APERTURE_MACRO::GetLocalParam( const D_CODE* aDcode, unsigned aParamId ) const
+{
+ // find parameter descr.
+ const AM_PARAM * param = NULL;
+ for( unsigned ii = 0; ii < m_localparamStack.size(); ii ++ )
+ {
+ if( m_localparamStack[ii].GetIndex() == aParamId )
+ {
+ param = &m_localparamStack[ii];
+ break;
+ }
+ }
+ if ( param == NULL ) // not found
+ return 0.0;
+ // Evaluate parameter
+ double value = param->GetValue( aDcode );
+ return value;
+}
diff --git a/gerbview/class_aperture_macro.h b/gerbview/class_aperture_macro.h
new file mode 100644
index 0000000..959a254
--- /dev/null
+++ b/gerbview/class_aperture_macro.h
@@ -0,0 +1,262 @@
+/**
+ * @file class_aperture_macro.h
+ */
+
+#ifndef _APERTURE_MACRO_H_
+#define _APERTURE_MACRO_H_
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <vector>
+#include <set>
+
+#include <base_struct.h>
+#include <class_am_param.h>
+
+/*
+ * An aperture macro defines a complex shape and is a list of aperture primitives.
+ * Each aperture primitive defines a simple shape (circle, rect, regular polygon...)
+ * Inside a given aperture primitive, a fixed list of parameters defines info
+ * about the shape: size, thickness, number of vertex ...
+ *
+ * Each parameter can be an immediate value or a defered value.
+ * When value is defered, it is defined when the aperture macro is instancied by
+ * an ADD macro command
+ * Note also a defered parameter can be defined in aperture macro,
+ * but outside aperture primitives. Example
+ * %AMRECTHERM*
+ * $4=$3/2* parameter $4 is half value of parameter $3
+ * 21,1,$1-$3,$2-$3,0-$1/2-$4,0-$2/2-$4,0*
+ * For the aperture primitive, parameters $1 to $3 will be defined in ADD command,
+ * and $4 is defined inside the macro
+ */
+
+/**
+ * Enum AM_PRIMITIVE_ID
+ * is the set of all "aperture macro primitives" (primitive numbers). See
+ * Table 3 in http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
+ * aperture macro primitives are basic shapes which can be combined to create a complex shape
+ * This complex shape is flashed.
+ */
+enum AM_PRIMITIVE_ID {
+ AMP_UNKNOWN = -1, // A value for uninitialized AM_PRIMITIVE.
+ AMP_COMMENT = 0, // A primitive description is not really a primitive, this is a comment
+ AMP_CIRCLE = 1, // Circle. (diameter and position)
+ AMP_LINE2 = 2, // Line with rectangle ends. (Width, start and end pos + rotation)
+ AMP_LINE20 = 20, // Same as AMP_LINE2
+ AMP_LINE_CENTER = 21, // Rectangle. (height, width and center pos + rotation)
+ AMP_LINE_LOWER_LEFT = 22, // Rectangle. (height, width and left bottom corner pos + rotation)
+ AMP_EOF = 3, // End Of File marquer: not really a shape
+ AMP_OUTLINE = 4, // Free polyline (n corners + rotation)
+ AMP_POLYGON = 5, // Closed regular polygon(diameter, number of vertices (3 to 10), rotation)
+ AMP_MOIRE = 6, // A cross hair with n concentric circles + rotation
+ AMP_THERMAL = 7 // Thermal shape (pos, outer and inner diameter, cross hair thickness + rotation)
+};
+
+
+/**
+ * Struct AM_PRIMITIVE
+ * holds an aperture macro primitive as given in Table 3 of
+ * http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
+ */
+class AM_PRIMITIVE
+{
+public:
+ AM_PRIMITIVE_ID primitive_id; ///< The primitive type
+ AM_PARAMS params; ///< A sequence of parameters used by
+ // the primitive
+ bool m_GerbMetric; // units for this primitive:
+ // false = Inches, true = metric
+public: AM_PRIMITIVE( bool aGerbMetric, AM_PRIMITIVE_ID aId = AMP_UNKNOWN )
+ {
+ primitive_id = aId;
+ m_GerbMetric = aGerbMetric;
+ }
+
+
+ ~AM_PRIMITIVE() {}
+
+ /**
+ * Function GetExposure
+ * returns the first parameter in integer form. Some but not all primitives
+ * use the first parameter as an exposure control.
+ */
+ int GetExposure( GERBER_DRAW_ITEM* aParent ) const;
+
+ /**
+ * Function mapExposure
+ * translates the first parameter from an aperture macro into a current
+ * exposure setting.
+ * @param aParent = a GERBER_DRAW_ITEM that handle:
+ * ** m_Exposure A dynamic setting which can change throughout the
+ * reading of the gerber file, and it indicates whether the current tool
+ * is lit or not.
+ * ** m_ImageNegative A dynamic setting which can change throughout the reading
+ * of the gerber file, and it indicates whether the current D codes are to
+ * be interpreted as erasures or not.
+ * @return true to draw with current color, false to draw with alt color (erase)
+ */
+ bool mapExposure( GERBER_DRAW_ITEM* aParent );
+
+ /* Draw functions: */
+
+ /**
+ * Function DrawBasicShape
+ * Draw the primitive shape for flashed items.
+ * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
+ * @param aClipBox = DC clip box (NULL is no clip)
+ * @param aDC = device context
+ * @param aColor = the normal color to use
+ * @param aAltColor = the color used to draw with "reverse" exposure mode (used in aperture macros only)
+ * @param aShapePos = the actual shape position
+ * @param aFilledShape = true to draw in filled mode, false to draw in skecth mode
+ */
+ void DrawBasicShape( GERBER_DRAW_ITEM* aParent, EDA_RECT* aClipBox, wxDC* aDC,
+ EDA_COLOR_T aColor, EDA_COLOR_T aAltColor, wxPoint aShapePos, bool aFilledShape );
+
+ /** GetShapeDim
+ * Calculate a value that can be used to evaluate the size of text
+ * when displaying the D-Code of an item
+ * due to the complexity of the shape of some primitives
+ * one cannot calculate the "size" of a shape (only a bounding box)
+ * but here, the "dimension" of the shape is the diameter of the primitive
+ * or for lines the width of the line
+ * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
+ * @return a dimension, or -1 if no dim to calculate
+ */
+ int GetShapeDim( GERBER_DRAW_ITEM* aParent );
+
+private:
+
+ /**
+ * Function ConvertShapeToPolygon
+ * convert a shape to an equivalent polygon.
+ * Arcs and circles are approximated by segments
+ * Useful when a shape is not a graphic primitive (shape with hole,
+ * rotated shape ... ) and cannot be easily drawn.
+ */
+ void ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector<wxPoint>& aBuffer );
+};
+
+
+typedef std::vector<AM_PRIMITIVE> AM_PRIMITIVES;
+
+/**
+ * Struct APERTURE_MACRO
+ * helps support the "aperture macro" defined within standard RS274X.
+ */
+struct APERTURE_MACRO
+{
+ wxString name; ///< The name of the aperture macro
+ AM_PRIMITIVES primitives; ///< A sequence of AM_PRIMITIVEs
+
+ /* A defered parameter can be defined in aperture macro,
+ * but outside aperture primitives. Example
+ * %AMRECTHERM*
+ * $4=$3/2* parameter $4 is half value of parameter $3
+ * m_localparamStack handle a list of local defered parameters
+ */
+ AM_PARAMS m_localparamStack;
+
+ /**
+ * function GetLocalParam
+ * Usually, parameters are defined inside the aperture primitive
+ * using immediate mode or defered mode.
+ * in defered mode the value is defined in a DCODE that want to use the aperture macro.
+ * But some parameters are defined outside the aperture primitive
+ * and are local to the aperture macro
+ * @return the value of a defered parameter defined inside the aperture macro
+ * @param aDcode = the D_CODE that uses this apertur macro and define defered parameters
+ * @param aParamId = the param id (defined by $3 or $5 ..) to evaluate
+ */
+ double GetLocalParam( const D_CODE* aDcode, unsigned aParamId ) const;
+
+ /**
+ * Function DrawApertureMacroShape
+ * Draw the primitive shape for flashed items.
+ * When an item is flashed, this is the shape of the item
+ * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
+ * @param aClipBox = DC clip box (NULL is no clip)
+ * @param aDC = device context
+ * @param aColor = the normal color to use
+ * @param aAltColor = the color used to draw with "reverse" exposure mode (used in aperture macros only)
+ * @param aShapePos = the actual shape position
+ * @param aFilledShape = true to draw in filled mode, false to draw in skecth mode
+ */
+ void DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent, EDA_RECT* aClipBox, wxDC* aDC,
+ EDA_COLOR_T aColor, EDA_COLOR_T aAltColor, wxPoint aShapePos, bool aFilledShape );
+
+ /**
+ * Function GetShapeDim
+ * Calculate a value that can be used to evaluate the size of text
+ * when displaying the D-Code of an item
+ * due to the complexity of a shape using many primitives
+ * one cannot calculate the "size" of a shape (only abounding box)
+ * but most of aperture macro are using one or few primitives
+ * and the "dimension" of the shape is the diameter of the primitive
+ * (or the max diameter of primitives)
+ * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
+ * @return a dimension, or -1 if no dim to calculate
+ */
+ int GetShapeDim( GERBER_DRAW_ITEM* aParent );
+
+ /**
+ * Function HasNegativeItems
+ * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
+ * @return true if this macro has at least one shape (using aperture primitives)
+ * must be drawn in background color
+ * used to optimize screen refresh (when no items are in background color
+ * refresh can be faster)
+ */
+ bool HasNegativeItems( GERBER_DRAW_ITEM* aParent );
+};
+
+
+/**
+ * Struct APERTURE_MACRO_less_than
+ * is used by std:set<APERTURE_MACRO> instantiation which uses
+ * APERTURE_MACRO.name as its key.
+ */
+struct APERTURE_MACRO_less_than
+{
+ // a "less than" test on two APERTURE_MACROs (.name wxStrings)
+ bool operator()( const APERTURE_MACRO& am1, const APERTURE_MACRO& am2 ) const
+ {
+ return am1.name.Cmp( am2.name ) < 0; // case specific wxString compare
+ }
+};
+
+
+/**
+ * Type APERTURE_MACRO_SET
+ * is a sorted collection of APERTURE_MACROS whose key is the name field in
+ * the APERTURE_MACRO.
+ */
+typedef std::set<APERTURE_MACRO, APERTURE_MACRO_less_than> APERTURE_MACRO_SET;
+typedef std::pair<APERTURE_MACRO_SET::iterator, bool> APERTURE_MACRO_SET_PAIR;
+
+
+#endif // ifndef _APERTURE_MACRO_H_
diff --git a/gerbview/class_excellon.h b/gerbview/class_excellon.h
new file mode 100644
index 0000000..d115d7b
--- /dev/null
+++ b/gerbview/class_excellon.h
@@ -0,0 +1,308 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef CLASS_EXCELLON_H
+#define CLASS_EXCELLON_H
+
+
+enum drill_M_code_t {
+ DRILL_M_UNKNOWN,
+ DRILL_M_END,
+ DRILL_M_ENDREWIND,
+ DRILL_M_MESSAGE,
+ DRILL_M_LONGMESSAGE,
+ DRILL_M_HEADER,
+ DRILL_M_ENDHEADER,
+ DRILL_M_BEGINPATTERN,
+ DRILL_M_ENDPATTERN,
+ DRILL_M_CANNEDTEXT,
+ DRILL_M_TIPCHECK,
+ DRILL_M_METRIC,
+ DRILL_M_IMPERIAL,
+ DRILL_METRICHEADER,
+ DRILL_IMPERIALHEADER,
+ DRILL_DETECT_BROKEN,
+ DRILL_INCREMENTALHEADER,
+ DRILL_REWIND_STOP,
+ DRILL_TOOL_CHANGE_STOP,
+ DRILL_AUTOMATIC_SPEED,
+ DRILL_AXIS_VERSION,
+ DRILL_RESET_CMD,
+ DRILL_AUTOMATIC_TOOL_CHANGE,
+ DRILL_FMT,
+ DRILL_SKIP,
+ DRILL_TOOL_INFORMATION
+};
+
+
+enum drill_G_code_t {
+ DRILL_G_UNKNOWN,
+ DRILL_G_ABSOLUTE,
+ DRILL_G_INCREMENTAL,
+ DRILL_G_ZEROSET,
+ DRILL_G_ROUT,
+ DRILL_G_DRILL,
+ DRILL_G_SLOT,
+ DRILL_G_ZERO_SET,
+ DRILL_G_LINEARMOVE,
+ DRILL_G_CWMOVE,
+ DRILL_G_CCWMOVE
+};
+
+// Helper struct to analyse Excellon commands
+struct EXCELLON_CMD
+{
+ std::string m_Name; // key string
+ int m_Code; // internal code, used as id in functions
+ int m_asParams; // 0 = no param, -1 = skip params, 1 = read params
+};
+
+
+/* EXCELLON_IMAGE handle a drill image
+ * It is derived from GERBER_IMAGE because there is a lot of likeness
+ * between EXCELLON files and GERBER files
+ * DCode aperture are also similat to T Codes.
+ * So we can reuse GERBER_IMAGE to handle EXCELLON_IMAGE with very few new functions
+ */
+
+class EXCELLON_IMAGE : public GERBER_IMAGE
+{
+private:
+ enum excellon_state {
+ READ_HEADER_STATE, // When we are in this state, we are reading header
+ READ_PROGRAM_STATE // When we are in this state, we are reading drill data
+ };
+ excellon_state m_State; // state of excellon file analysis
+ bool m_SlotOn; // true during an oval driil definition
+
+public: EXCELLON_IMAGE( GERBVIEW_FRAME* aParent, int layer ) :
+ GERBER_IMAGE( aParent, layer )
+ {
+ m_State = READ_HEADER_STATE;
+ m_SlotOn = false;
+ }
+
+
+ ~EXCELLON_IMAGE() {};
+
+ virtual void ResetDefaultValues()
+ {
+ GERBER_IMAGE::ResetDefaultValues();
+ SelectUnits( false );
+ }
+
+
+ bool Read_EXCELLON_File( FILE* aFile, const wxString& aFullFileName );
+
+private:
+ bool Execute_HEADER_Command( char*& text );
+ bool Select_Tool( char*& text );
+ bool Execute_EXCELLON_G_Command( char*& text );
+ bool Execute_Drill_Command( char*& text );
+
+ int TCodeNumber( char*& Text )
+ {
+ return DCodeNumber( Text );
+ }
+
+
+ void SelectUnits( bool aMetric );
+};
+
+
+/*
+ * EXCELLON commands are given here.
+ * Pcbnew uses only few excellon commands
+ */
+
+/*
+ * see http://www.excellon.com/manuals/program.htm
+ */
+
+/* coordintes units:
+ * Coordinates are measured either in inch or metric (millimeters).
+ * Inch coordinates are in six digits (00.0000) with increments as small as 0.0001 (1/10,000).
+ * Metric coordinates can be measured in microns (thousandths of a millimeter)
+ * in one of the following three ways:
+ * Five digit 10 micron resolution (000.00)
+ * Six digit 10 micron resolution (0000.00)
+ * Six digit micron resolution (000.000)
+ *
+ * Leading and trailing zeros:
+ * Excellon (CNC-7) uses inches in six digits and metric in five or six digits.
+ * The zeros to the left of the coordinate are called leading zeros (LZ).
+ * The zeros to right of the coordinate are called trailing zeros (TZ).
+ * The CNC-7 uses leading zeros unless you specify otherwise through a part program.
+ * You can do so with the INCH/METRIC command.
+ * With leading zeros, the leading zeros must always be included.
+ * Trailing zeros are unneeded and may be left off.
+ * For trailing zeros, the reverse of the above is true.
+ */
+
+/*
+ * EXCELLON Commands Used in a Header
+ * The following table provides you with a list of commands which
+ * are the most used in a part program header.
+ * COMMAND DESCRIPTION
+ * AFS Automatic Feeds and Speeds
+ * ATC Automatic Tool Change
+ * BLKD Delete all Blocks starting with a slash (/)
+ * CCW Clockwise or Counter-clockwise Routing
+ * CP Cutter Compensation
+ * DETECT Broken Tool Detection
+ * DN Down Limit Set
+ * DTMDIST Maximum Rout Distance Before Toolchange
+ * EXDA Extended Drill Area
+ * FMAT Format 1 or 2
+ * FSB Turns the Feed/Speed Buttons off
+ * HPCK Home Pulse Check
+ * ICI Incremental Input of Part Program Coordinates
+ * INCH Measure Everything in Inches
+ * METRIC Measure Everything in Metric
+ * M48 Beginning of Part Program Header
+ * M95 End of Header
+ * NCSL NC Slope Enable/Disable
+ * OM48 Override Part Program Header
+ * OSTOP Optional Stop Switch
+ * OTCLMP Override Table Clamp
+ * PCKPARAM Set up pecking tool,depth,infeed and retract parameters
+ * PF Floating Pressure Foot Switch
+ * PPR Programmable Plunge Rate Enable
+ * PVS Pre-vacuum Shut-off Switch
+ * R,C Reset Clocks
+ * R,CP Reset Program Clocks
+ * R,CR Reset Run Clocks
+ * R,D Reset All Cutter Distances
+ * R,H Reset All Hit Counters
+ * R,T Reset Tool Data
+ * SBK Single Block Mode Switch
+ * SG Spindle Group Mode
+ * SIXM Input From External Source
+ * T Tool Information
+ * TCST Tool Change Stop
+ * UP Upper Limit Set
+ * VER Selection of X and Y Axis Version
+ * Z Zero Set
+ * ZA Auxiliary Zero
+ * ZC Zero Correction
+ * ZS Zero Preset
+ * Z+# or Z-# Set Depth Offset
+ * % Rewind Stop
+ * #/#/# Link Tool for Automatic Tool Change
+ * / Clear Tool Linking
+ */
+
+/*
+ * Beyond The Header: The Part Program Body
+ * COMMAND DESCRIPTION
+ * A# Arc Radius
+ * B# Retract Rate
+ * C# Tool Diameter
+ * F# Table Feed Rate;Z Axis Infeed Rate
+ * G00X#Y# Route Mode
+ * G01 Linear (Straight Line) Mode
+ * G02 Circular CW Mode
+ * G03 Circular CCW Mode
+ * G04 X# Variable Dwell
+ * G05 Drill Mode
+ * G07 Override current tool feed or speed
+ * G32X#Y#A# Routed Circle Canned Cycle
+ * CW G33X#Y#A# Routed Circle Canned Cycle
+ * CCW G34,#(,#) Select Vision Tool
+ * G35(X#Y#) Single Point Vision Offset (Relative to Work Zero)
+ * G36(X#Y#) Multipoint Vision Translation (Relative to Work Zero)
+ * G37 Cancel Vision Translation or Offset (From G35 or G36)
+ * G38(X#Y#) Vision Corrected Single Hole Drilling (Relative to Work Zero)
+ * G39(X#Y#) Vision System Autocalibration
+ * G40 Cutter Compensation Off
+ * G41 Cutter Compensation Left
+ * G42 Cutter Compensation Right
+ * G45(X#Y#) Single Point Vision Offset (Relative to G35 or G36)
+ * G46(X#Y#) Multipoint Vision Translation (Relative to G35 or G36)
+ * G47 Cancel Vision Translation or Offset (From G45 or G46)
+ * G48(X#Y#) Vision Corrected Single Hole Drilling (Relative to G35 or G36)
+ * G82(G81) Dual In Line Package
+ * G83 Eight Pin L Pack
+ * G84 Circle
+ * G85 Slot
+ * G87 Routed Step Slot Canned Cycle
+ * G90 Absolute Mode
+ * G91 Incremental Input Mode
+ * G93X#Y# Zero Set
+ * H# Maximum hit count
+ * I#J# Arc Center Offset
+ * M00(X#Y#) End of Program - No Rewind
+ * M01 End of Pattern
+ * M02X#Y# Repeat Pattern Offset
+ * M06(X#Y#) Optional Stop
+ * M08 End of Step and Repeat
+ * M09(X#Y#) Stop for Inspection
+ * M14 Z Axis Route Position With Depth Controlled Contouring
+ * M15 Z Axis Route Position
+ * M16 Retract With Clamping
+ * M17 Retract Without Clamping
+ * M18 Command tool tip check
+ * M25 Beginning of Pattern
+ * M30(X#Y#) End of Program Rewind
+ * M45,long message\ Long Operator message on multiple\ part program lines
+ * M47,text Operator Message
+ * M50,# Vision Step and Repeat Pattern Start
+ * M51,# Vision Step and Repeat Rewind
+ * M52(#) Vision Step and Repeat Offset Counter Control
+ * M02XYM70 Swap Axes
+ * M60 Reference Scaling enable
+ * M61 Reference Scaling disable
+ * M62 Turn on peck drilling
+ * M63 Turn off peck drilling
+ * M71 Metric Measuring Mode
+ * M72 Inch Measuring Mode
+ * M02XYM80 Mirror Image X Axis
+ * M02XYM90 Mirror Image Y Axis
+ * M97,text Canned Text
+ * M98,text Canned Text
+ * M99,subprogram User Defined Stored Pattern
+ * P#X#(Y#) Repeat Stored Pattern
+ * R#M02X#Y# Repeat Pattern (S&R)
+ * R#(X#Y#) Repeat Hole
+ * S# Spindle RPM
+ * T# Tool Selection; Cutter Index
+ * Z+# or Z-# Depth Offset
+ * % Beginning of Pattern (see M25 command)
+ * / Block Delete
+ */
+
+/*
+ * Example of a Header
+ * COMMAND PURPOSE
+ * M48 The beginning of a header
+ * INCH,LZ Use the inch measuring system with leading zeros
+ * VER,1 Use Version 1 X and Y axis layout
+ * FMAT,2 Use Format 2 commands
+ * 1/2/3 Link tools 1, 2, and 3
+ * T1C.04F200S65 Set Tool 1 for 0.040" with infeed rate of 200 inch/min Speed of 65,000 RPM
+ * DETECT,ON Detect broken tools
+ * M95 End of the header
+ */
+
+#endif // CLASS_EXCELLON_H
diff --git a/gerbview/class_gbr_layer_box_selector.cpp b/gerbview/class_gbr_layer_box_selector.cpp
new file mode 100644
index 0000000..f148306
--- /dev/null
+++ b/gerbview/class_gbr_layer_box_selector.cpp
@@ -0,0 +1,81 @@
+/**
+ * @file class_gbr_layer_box_selector.cpp
+ * @brief a derived class of LAYER_BOX_SELECTOR to handle the layer box selector
+ * in GerbView
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 Jean-Pierre Charras <jean-pierre.charras@ujf-grenoble.fr>
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <common.h>
+#include <colors_selection.h>
+#include <layers_id_colors_and_visibility.h>
+#include <gerbview_frame.h>
+#include <class_GERBER.h>
+#include <class_X2_gerber_attributes.h>
+
+#include <class_gbr_layer_box_selector.h>
+
+void GBR_LAYER_BOX_SELECTOR::Resync()
+{
+ Freeze();
+ Clear();
+
+ for( int layerid = 0; layerid < GERBER_DRAWLAYERS_COUNT; ++layerid )
+ {
+ wxBitmap layerbmp( 14, 14 );
+ wxString layername;
+
+ if( !IsLayerEnabled( layerid ) )
+ continue;
+
+ // Prepare Bitmap
+ SetBitmapLayer( layerbmp, layerid );
+
+ layername = GetLayerName( layerid );
+
+ Append( layername, layerbmp, (void*)(intptr_t) layerid );
+ }
+
+ Thaw();
+}
+
+
+// Returns a color index from the layer id
+EDA_COLOR_T GBR_LAYER_BOX_SELECTOR::GetLayerColor( int aLayer ) const
+{
+ GERBVIEW_FRAME* frame = (GERBVIEW_FRAME*) GetParent()->GetParent();
+
+ return frame->GetLayerColor( aLayer );
+}
+
+
+// Returns the name of the layer id
+wxString GBR_LAYER_BOX_SELECTOR::GetLayerName( int aLayer ) const
+{
+ wxString name = g_GERBER_List.GetDisplayName( aLayer );
+
+ return name;
+}
diff --git a/gerbview/class_gbr_layer_box_selector.h b/gerbview/class_gbr_layer_box_selector.h
new file mode 100644
index 0000000..6128bce
--- /dev/null
+++ b/gerbview/class_gbr_layer_box_selector.h
@@ -0,0 +1,59 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef CLASS_GBR_LAYER_BOX_SELECTOR_H
+#define CLASS_GBR_LAYER_BOX_SELECTOR_H 1
+
+#include <class_layer_box_selector.h>
+
+
+// class to display a layer list in GerbView.
+class GBR_LAYER_BOX_SELECTOR : public LAYER_BOX_SELECTOR
+{
+public:
+ GBR_LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id,
+ const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+ int n = 0, const wxString choices[] = NULL ) :
+ LAYER_BOX_SELECTOR( parent, id, pos, size, n, choices )
+ {
+ m_layerhotkeys = false;
+ }
+
+ // Reload the Layers names and bitmaps
+ // Virtual function
+ void Resync();
+
+ // Returns a color index from the layer id
+ // Virtual function
+ EDA_COLOR_T GetLayerColor( int aLayer ) const;
+
+ // Returns true if the layer id is enabled (i.e. is it should be displayed)
+ // Virtual function
+ bool IsLayerEnabled( int aLayer ) const { return true; };
+
+ // Returns the name of the layer id
+ wxString GetLayerName( int aLayer ) const;
+};
+
+#endif //CLASS_GBR_LAYER_BOX_SELECTOR_H
diff --git a/gerbview/class_gbr_layout.cpp b/gerbview/class_gbr_layout.cpp
new file mode 100644
index 0000000..427cab1
--- /dev/null
+++ b/gerbview/class_gbr_layout.cpp
@@ -0,0 +1,57 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_gbr_layout.cpp
+ * @brief GBR_LAYOUT class functions.
+ */
+
+#include <limits.h>
+#include <algorithm>
+
+#include <fctsys.h>
+#include <common.h>
+#include <class_gbr_layout.h>
+
+GBR_LAYOUT::GBR_LAYOUT()
+{
+ m_printLayersMask.set();
+}
+
+
+GBR_LAYOUT::~GBR_LAYOUT()
+{
+}
+
+
+EDA_RECT GBR_LAYOUT::ComputeBoundingBox()
+{
+ EDA_RECT bbox;
+
+ for( GERBER_DRAW_ITEM* gerb_item = m_Drawings; gerb_item; gerb_item = gerb_item->Next() )
+ bbox.Merge( gerb_item->GetBoundingBox() );
+
+ SetBoundingBox( bbox );
+ return bbox;
+}
diff --git a/gerbview/class_gbr_layout.h b/gerbview/class_gbr_layout.h
new file mode 100644
index 0000000..e5610ec
--- /dev/null
+++ b/gerbview/class_gbr_layout.h
@@ -0,0 +1,148 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_gbr_layout.h
+ * @brief Class CLASS_GBR_LAYOUT to handle info to draw/print loaded Gerber images
+ * and page frame reference
+ */
+
+#ifndef CLASS_GBR_LAYOUT_H
+#define CLASS_GBR_LAYOUT_H
+
+
+#include <dlist.h>
+
+#include <class_colors_design_settings.h>
+#include <common.h> // PAGE_INFO
+#include <gerbview.h> // GERBER_DRAWLAYERS_COUNT
+#include <class_title_block.h>
+#include <class_gerber_draw_item.h>
+
+#include <gr_basic.h>
+
+/**
+ * Class GBR_LAYOUT
+ * holds list of GERBER_DRAW_ITEM currently loaded.
+ */
+class GBR_LAYOUT
+{
+private:
+ EDA_RECT m_BoundingBox;
+ TITLE_BLOCK m_titles;
+ wxPoint m_originAxisPosition;
+ std::bitset <GERBER_DRAWLAYERS_COUNT> m_printLayersMask; // When printing: the list of layers to print
+public:
+
+ DLIST<GERBER_DRAW_ITEM> m_Drawings; // linked list of Gerber Items to draw
+
+ GBR_LAYOUT();
+ ~GBR_LAYOUT();
+
+ const wxPoint& GetAuxOrigin() const
+ {
+ return m_originAxisPosition;
+ }
+
+ void SetAuxOrigin( const wxPoint& aPosition )
+ {
+ m_originAxisPosition = aPosition;
+ }
+
+ TITLE_BLOCK& GetTitleBlock()
+ {
+ return m_titles;
+ }
+
+ void SetTitleBlock( const TITLE_BLOCK& aTitleBlock )
+ {
+ m_titles = aTitleBlock;
+ }
+
+ /**
+ * Function ComputeBoundingBox
+ * calculates the bounding box containing all Gerber items.
+ * @return EDA_RECT - the full item list bounding box
+ */
+ EDA_RECT ComputeBoundingBox();
+
+ /**
+ * Function GetBoundingBox
+ * may be called soon after ComputeBoundingBox() to return the same EDA_RECT,
+ * as long as the CLASS_GBR_LAYOUT has not changed.
+ */
+ EDA_RECT GetBoundingBox() const { return m_BoundingBox; } // override
+
+ void SetBoundingBox( const EDA_RECT& aBox ) { m_BoundingBox = aBox; }
+
+ /**
+ * Function Draw.
+ * Redraw the CLASS_GBR_LAYOUT items but not cursors, axis or grid.
+ * @param aPanel = the panel relative to the board
+ * @param aDC = the current device context
+ * @param aDrawMode = GR_COPY, GR_OR ... (not always used)
+ * @param aOffset = an draw offset value
+ * @param aPrintBlackAndWhite = true to force black and white insdeat of color
+ * useful only to print/plot gebview layers
+ */
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ GR_DRAWMODE aDrawMode, const wxPoint& aOffset,
+ bool aPrintBlackAndWhite = false );
+ /**
+ * Function SetPrintableLayers
+ * changes the list of printable layers
+ * @param aLayerMask = The new bit-mask of printable layers
+ */
+ void SetPrintableLayers( const std::bitset <GERBER_DRAWLAYERS_COUNT>& aLayerMask )
+ {
+ m_printLayersMask = aLayerMask;
+ }
+
+ /**
+ * Function GetPrintableLayers
+ * @return the bit-mask of printable layers
+ */
+ std::bitset <GERBER_DRAWLAYERS_COUNT> GetPrintableLayers()
+ {
+ return m_printLayersMask;
+ }
+
+ /**
+ * Function IsLayerPrintable
+ * tests whether a given layer is visible
+ * @param aLayer = The layer to be tested
+ * @return bool - true if the layer is visible.
+ */
+ bool IsLayerPrintable( int aLayer ) const
+ {
+ return m_printLayersMask[ aLayer ];
+ }
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // overload
+
+#endif
+};
+
+#endif // #ifndef CLASS_GBR_LAYOUT_H
diff --git a/gerbview/class_gbr_screen.cpp b/gerbview/class_gbr_screen.cpp
new file mode 100644
index 0000000..2cd2e7f
--- /dev/null
+++ b/gerbview/class_gbr_screen.cpp
@@ -0,0 +1,143 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_gbr_screen.cpp
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <macros.h>
+#include <class_gbr_screen.h>
+#include <base_units.h>
+#include <gerbview_id.h>
+
+#define DMIL_GRID( x ) wxRealPoint( x * IU_PER_DECIMILS,\
+ x * IU_PER_DECIMILS )
+#define MM_GRID( x ) wxRealPoint( x * IU_PER_MM,\
+ x * IU_PER_MM )
+
+
+/**
+ Default GerbView zoom values.
+ Roughly a 1.5 progression.
+*/
+static const double gbrZoomList[] =
+{
+ ZOOM_FACTOR( 0.5 ),
+ ZOOM_FACTOR( 0.75 ),
+ ZOOM_FACTOR( 1.0 ),
+ ZOOM_FACTOR( 1.5 ),
+ ZOOM_FACTOR( 2.0 ),
+ ZOOM_FACTOR( 3.0 ),
+ ZOOM_FACTOR( 4.5 ),
+ ZOOM_FACTOR( 7.0 ),
+ ZOOM_FACTOR( 10.0 ),
+ ZOOM_FACTOR( 15.0 ),
+ ZOOM_FACTOR( 22.0 ),
+ ZOOM_FACTOR( 35.0 ),
+ ZOOM_FACTOR( 50.0 ),
+ ZOOM_FACTOR( 80.0 ),
+ ZOOM_FACTOR( 110.0 ),
+ ZOOM_FACTOR( 150.0 ),
+ ZOOM_FACTOR( 200.0 ),
+ ZOOM_FACTOR( 350.0 ),
+ ZOOM_FACTOR( 500.0 ),
+ ZOOM_FACTOR( 1000.0 ),
+ ZOOM_FACTOR( 2000.0 )
+};
+
+
+// Default grid sizes for PCB editor screens.
+static GRID_TYPE gbrGridList[] =
+{
+ // predefined grid list in 0.0001 inches
+ { ID_POPUP_GRID_LEVEL_1000, DMIL_GRID( 1000 ) },
+ { ID_POPUP_GRID_LEVEL_500, DMIL_GRID( 500 ) },
+ { ID_POPUP_GRID_LEVEL_250, DMIL_GRID( 250 ) },
+ { ID_POPUP_GRID_LEVEL_200, DMIL_GRID( 200 ) },
+ { ID_POPUP_GRID_LEVEL_100, DMIL_GRID( 100 ) },
+ { ID_POPUP_GRID_LEVEL_50, DMIL_GRID( 50 ) },
+ { ID_POPUP_GRID_LEVEL_25, DMIL_GRID( 25 ) },
+ { ID_POPUP_GRID_LEVEL_20, DMIL_GRID( 20 ) },
+ { ID_POPUP_GRID_LEVEL_10, DMIL_GRID( 10 ) },
+ { ID_POPUP_GRID_LEVEL_5, DMIL_GRID( 5 ) },
+ { ID_POPUP_GRID_LEVEL_2, DMIL_GRID( 2 ) },
+ { ID_POPUP_GRID_LEVEL_1, DMIL_GRID( 1 ) },
+
+ // predefined grid list in mm
+ { ID_POPUP_GRID_LEVEL_5MM, MM_GRID( 5.0 ) },
+ { ID_POPUP_GRID_LEVEL_2_5MM, MM_GRID( 2.5 ) },
+ { ID_POPUP_GRID_LEVEL_1MM, MM_GRID( 1.0 ) },
+ { ID_POPUP_GRID_LEVEL_0_5MM, MM_GRID( 0.5 ) },
+ { ID_POPUP_GRID_LEVEL_0_25MM, MM_GRID( 0.25 ) },
+ { ID_POPUP_GRID_LEVEL_0_2MM, MM_GRID( 0.2 ) },
+ { ID_POPUP_GRID_LEVEL_0_1MM, MM_GRID( 0.1 ) },
+ { ID_POPUP_GRID_LEVEL_0_0_5MM, MM_GRID( 0.05 ) },
+ { ID_POPUP_GRID_LEVEL_0_0_25MM, MM_GRID( 0.025 ) },
+ { ID_POPUP_GRID_LEVEL_0_0_1MM, MM_GRID( 0.01 ) }
+};
+
+
+GBR_SCREEN::GBR_SCREEN( const wxSize& aPageSizeIU ) :
+ BASE_SCREEN( SCREEN_T )
+{
+ for( unsigned i = 0; i < DIM( gbrZoomList ); ++i )
+ m_ZoomList.push_back( gbrZoomList[i] );
+
+ for( unsigned i = 0; i < DIM( gbrGridList ); ++i )
+ AddGrid( gbrGridList[i] );
+
+ // Set the working grid size to a reasonable value (in 1/10000 inch)
+ SetGrid( DMIL_GRID( 500 ) );
+
+ m_Active_Layer = B_Cu; // default active layer = bottom layer
+
+ SetZoom( ZOOM_FACTOR( 350 ) ); // a default value for zoom
+
+ InitDataPoints( aPageSizeIU );
+}
+
+
+GBR_SCREEN::~GBR_SCREEN()
+{
+ ClearUndoRedoList();
+}
+
+
+// virtual function
+int GBR_SCREEN::MilsToIuScalar()
+{
+ return (int)IU_PER_MILS;
+}
+
+
+/* Virtual function needed by classes derived from BASE_SCREEN
+ * this is a virtual pure function in BASE_SCREEN
+ * do nothing in GerbView
+ * could be removed later
+ */
+void GBR_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER&, int )
+{
+}
diff --git a/gerbview/class_gbr_screen.h b/gerbview/class_gbr_screen.h
new file mode 100644
index 0000000..19b5f90
--- /dev/null
+++ b/gerbview/class_gbr_screen.h
@@ -0,0 +1,69 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_gbr_screen.h
+ */
+
+#ifndef CLASS_GBR_SCREEN_H_
+#define CLASS_GBR_SCREEN_H_
+
+
+#include <base_units.h>
+#include <class_base_screen.h>
+#include <layers_id_colors_and_visibility.h>
+
+#define ZOOM_FACTOR( x ) ( x * IU_PER_DECIMILS )
+
+
+/* Handle info to display a board */
+class GBR_SCREEN : public BASE_SCREEN
+{
+public:
+ LAYER_NUM m_Active_Layer;
+ /**
+ * Constructor
+ * @param aPageSizeIU is the size of the initial paper page in internal units.
+ */
+ GBR_SCREEN( const wxSize& aPageSizeIU );
+
+ ~GBR_SCREEN();
+
+ GBR_SCREEN* Next() const { return static_cast<GBR_SCREEN*>( Pnext ); }
+
+// void SetNextZoom();
+// void SetPreviousZoom();
+// void SetLastZoom();
+
+ virtual int MilsToIuScalar();
+
+ /**
+ * Function ClearUndoORRedoList
+ * virtual pure in BASE_SCREEN, so it must be defined here
+ */
+ void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 );
+};
+
+
+#endif // CLASS_GBR_SCREEN_H_
diff --git a/gerbview/class_gerber_draw_item.cpp b/gerbview/class_gerber_draw_item.cpp
new file mode 100644
index 0000000..b915395
--- /dev/null
+++ b/gerbview/class_gerber_draw_item.cpp
@@ -0,0 +1,631 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 <Jean-Pierre Charras>
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_gerber_draw_item.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <common.h>
+#include <trigo.h>
+#include <class_drawpanel.h>
+#include <macros.h>
+#include <msgpanel.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <class_gerber_draw_item.h>
+#include <class_GERBER.h>
+
+
+GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( GBR_LAYOUT* aParent, GERBER_IMAGE* aGerberparams ) :
+ EDA_ITEM( (EDA_ITEM*)aParent, TYPE_GERBER_DRAW_ITEM )
+{
+ m_imageParams = aGerberparams;
+ m_Layer = 0;
+ m_Shape = GBR_SEGMENT;
+ m_Flashed = false;
+ m_DCode = 0;
+ m_UnitsMetric = false;
+ m_LayerNegative = false;
+ m_swapAxis = false;
+ m_mirrorA = false;
+ m_mirrorB = false;
+ m_drawScale.x = m_drawScale.y = 1.0;
+ m_lyrRotation = 0;
+ if( m_imageParams )
+ SetLayerParameters();
+}
+
+
+// Copy constructor
+GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ) :
+ EDA_ITEM( aSource )
+{
+ m_imageParams = aSource.m_imageParams;
+ m_Shape = aSource.m_Shape;
+
+ m_Flags = aSource.m_Flags;
+ SetTimeStamp( aSource.m_TimeStamp );
+
+ SetStatus( aSource.GetStatus() );
+ m_Start = aSource.m_Start;
+ m_End = aSource.m_End;
+ m_Size = aSource.m_Size;
+ m_Layer = aSource.m_Layer;
+ m_Shape = aSource.m_Shape;
+ m_Flashed = aSource.m_Flashed;
+ m_DCode = aSource.m_DCode;
+ m_PolyCorners = aSource.m_PolyCorners;
+ m_UnitsMetric = aSource.m_UnitsMetric;
+ m_LayerNegative = aSource.m_LayerNegative;
+ m_swapAxis = aSource.m_swapAxis;
+ m_mirrorA = aSource.m_mirrorA;
+ m_mirrorB = aSource.m_mirrorB;
+ m_layerOffset = aSource.m_layerOffset;
+ m_drawScale = aSource.m_drawScale;
+ m_lyrRotation = aSource.m_lyrRotation;
+}
+
+
+GERBER_DRAW_ITEM::~GERBER_DRAW_ITEM()
+{
+}
+
+
+GERBER_DRAW_ITEM* GERBER_DRAW_ITEM::Copy() const
+{
+ return new GERBER_DRAW_ITEM( *this );
+}
+
+
+wxPoint GERBER_DRAW_ITEM::GetABPosition( const wxPoint& aXYPosition ) const
+{
+ /* Note: RS274Xrevd_e is obscure about the order of transforms:
+ * For instance: Rotation must be made after or before mirroring ?
+ * Note: if something is changed here, GetYXPosition must reflect changes
+ */
+ wxPoint abPos = aXYPosition + m_imageParams->m_ImageJustifyOffset;
+
+ if( m_swapAxis )
+ std::swap( abPos.x, abPos.y );
+
+ abPos += m_layerOffset + m_imageParams->m_ImageOffset;
+ abPos.x = KiROUND( abPos.x * m_drawScale.x );
+ abPos.y = KiROUND( abPos.y * m_drawScale.y );
+ double rotation = m_lyrRotation * 10 + m_imageParams->m_ImageRotation * 10;
+
+ if( rotation )
+ RotatePoint( &abPos, -rotation );
+
+ // Negate A axis if mirrored
+ if( m_mirrorA )
+ abPos.x = -abPos.x;
+
+ // abPos.y must be negated when no mirror, because draw axis is top to bottom
+ if( !m_mirrorB )
+ abPos.y = -abPos.y;
+ return abPos;
+}
+
+
+wxPoint GERBER_DRAW_ITEM::GetXYPosition( const wxPoint& aABPosition ) const
+{
+ // do the inverse transform made by GetABPosition
+ wxPoint xyPos = aABPosition;
+
+ if( m_mirrorA )
+ xyPos.x = -xyPos.x;
+
+ if( !m_mirrorB )
+ xyPos.y = -xyPos.y;
+
+ double rotation = m_lyrRotation * 10 + m_imageParams->m_ImageRotation * 10;
+
+ if( rotation )
+ RotatePoint( &xyPos, rotation );
+
+ xyPos.x = KiROUND( xyPos.x / m_drawScale.x );
+ xyPos.y = KiROUND( xyPos.y / m_drawScale.y );
+ xyPos -= m_layerOffset + m_imageParams->m_ImageOffset;
+
+ if( m_swapAxis )
+ std::swap( xyPos.x, xyPos.y );
+
+ return xyPos - m_imageParams->m_ImageJustifyOffset;
+}
+
+
+void GERBER_DRAW_ITEM::SetLayerParameters()
+{
+ m_UnitsMetric = m_imageParams->m_GerbMetric;
+ m_swapAxis = m_imageParams->m_SwapAxis; // false if A = X, B = Y;
+
+ // true if A =Y, B = Y
+ m_mirrorA = m_imageParams->m_MirrorA; // true: mirror / axe A
+ m_mirrorB = m_imageParams->m_MirrorB; // true: mirror / axe B
+ m_drawScale = m_imageParams->m_Scale; // A and B scaling factor
+ m_layerOffset = m_imageParams->m_Offset; // Offset from OF command
+
+ // Rotation from RO command:
+ m_lyrRotation = m_imageParams->m_LocalRotation;
+ m_LayerNegative = m_imageParams->GetLayerParams().m_LayerNegative;
+}
+
+
+wxString GERBER_DRAW_ITEM::ShowGBRShape()
+{
+ switch( m_Shape )
+ {
+ case GBR_SEGMENT:
+ return _( "Line" );
+
+ case GBR_ARC:
+ return _( "Arc" );
+
+ case GBR_CIRCLE:
+ return _( "Circle" );
+
+ case GBR_SPOT_OVAL:
+ return wxT( "spot_oval" );
+
+ case GBR_SPOT_CIRCLE:
+ return wxT( "spot_circle" );
+
+ case GBR_SPOT_RECT:
+ return wxT( "spot_rect" );
+
+ case GBR_SPOT_POLY:
+ return wxT( "spot_poly" );
+
+ case GBR_POLYGON:
+ return wxT( "polygon" );
+
+ case GBR_SPOT_MACRO:
+ {
+ wxString name = wxT( "apt_macro" );
+ D_CODE* dcode = GetDcodeDescr();
+
+ if( dcode && dcode->GetMacro() )
+ name << wxT(" ") << dcode->GetMacro()->name;
+
+ return name;
+ }
+
+ default:
+ return wxT( "??" );
+ }
+}
+
+
+D_CODE* GERBER_DRAW_ITEM::GetDcodeDescr()
+{
+ if( (m_DCode < FIRST_DCODE) || (m_DCode > LAST_DCODE) )
+ return NULL;
+
+ GERBER_IMAGE* gerber = g_GERBER_List.GetGbrImage( m_Layer );
+
+ if( gerber == NULL )
+ return NULL;
+
+ D_CODE* d_code = gerber->GetDCODE( m_DCode, false );
+
+ return d_code;
+}
+
+
+const EDA_RECT GERBER_DRAW_ITEM::GetBoundingBox() const
+{
+ // return a rectangle which is (pos,dim) in nature. therefore the +1
+ EDA_RECT bbox( m_Start, wxSize( 1, 1 ) );
+
+ bbox.Inflate( m_Size.x / 2, m_Size.y / 2 );
+
+ bbox.SetOrigin( GetABPosition( bbox.GetOrigin() ) );
+ bbox.SetEnd( GetABPosition( bbox.GetEnd() ) );
+ return bbox;
+}
+
+
+void GERBER_DRAW_ITEM::MoveAB( const wxPoint& aMoveVector )
+{
+ wxPoint xymove = GetXYPosition( aMoveVector );
+
+ m_Start += xymove;
+ m_End += xymove;
+ m_ArcCentre += xymove;
+
+ for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ )
+ m_PolyCorners[ii] += xymove;
+}
+
+
+void GERBER_DRAW_ITEM::MoveXY( const wxPoint& aMoveVector )
+{
+ m_Start += aMoveVector;
+ m_End += aMoveVector;
+ m_ArcCentre += aMoveVector;
+
+ for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ )
+ m_PolyCorners[ii] += aMoveVector;
+}
+
+
+bool GERBER_DRAW_ITEM::Save( FILE* aFile ) const
+{
+ return true;
+}
+
+bool GERBER_DRAW_ITEM::HasNegativeItems()
+{
+ bool isClear = m_LayerNegative ^ m_imageParams->m_ImageNegative;
+
+ // if isClear is true, this item has negative shape
+ // but if isClear is true, and if this item use an aperture macro definition,
+ // we must see if this aperture macro uses a negative shape.
+ if( isClear )
+ return true;
+
+ // see for a macro def
+ D_CODE* dcodeDescr = GetDcodeDescr();
+
+ if( dcodeDescr == NULL )
+ return false;
+
+ if( m_Shape == GBR_SPOT_MACRO )
+ {
+ APERTURE_MACRO* macro = dcodeDescr->GetMacro();
+
+ if( macro ) // macro == NULL should not occurs
+ return macro->HasNegativeItems( this );
+ }
+
+ return false;
+}
+
+
+void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
+ const wxPoint& aOffset )
+{
+ // used when a D_CODE is not found. default D_CODE to draw a flashed item
+ static D_CODE dummyD_CODE( 0 );
+ EDA_COLOR_T color, alt_color;
+ bool isFilled;
+ int radius;
+ int halfPenWidth;
+ static bool show_err;
+ D_CODE* d_codeDescr = GetDcodeDescr();
+ GERBVIEW_FRAME* gerbFrame = (GERBVIEW_FRAME*) aPanel->GetParent();
+
+ if( d_codeDescr == NULL )
+ d_codeDescr = &dummyD_CODE;
+
+ if( gerbFrame->IsLayerVisible( GetLayer() ) == false )
+ return;
+
+ color = gerbFrame->GetLayerColor( GetLayer() );
+
+ if( aDrawMode & GR_HIGHLIGHT )
+ ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) );
+
+ ColorApplyHighlightFlag( &color );
+
+ alt_color = gerbFrame->GetNegativeItemsColor();
+
+ /* isDark is true if flash is positive and should use a drawing
+ * color other than the background color, else use the background color
+ * when drawing so that an erasure happens.
+ */
+ bool isDark = !(m_LayerNegative ^ m_imageParams->m_ImageNegative);
+
+ if( !isDark )
+ {
+ // draw in background color ("negative" color)
+ std::swap( color, alt_color );
+ }
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ isFilled = gerbFrame->DisplayLinesSolidMode();
+
+ switch( m_Shape )
+ {
+ case GBR_POLYGON:
+ isFilled = gerbFrame->DisplayPolygonsSolidMode();
+
+ if( !isDark )
+ isFilled = true;
+
+ DrawGbrPoly( aPanel->GetClipBox(), aDC, color, aOffset, isFilled );
+ break;
+
+ case GBR_CIRCLE:
+ radius = KiROUND( GetLineLength( m_Start, m_End ) );
+
+ halfPenWidth = m_Size.x >> 1;
+
+ if( !isFilled )
+ {
+ // draw the border of the pen's path using two circles, each as narrow as possible
+ GRCircle( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
+ radius - halfPenWidth, 0, color );
+ GRCircle( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
+ radius + halfPenWidth, 0, color );
+ }
+ else // Filled mode
+ {
+ GRCircle( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
+ radius, m_Size.x, color );
+ }
+ break;
+
+ case GBR_ARC:
+ // Currently, arcs plotted with a rectangular aperture are not supported.
+ // a round pen only is expected.
+
+#if 0 // for arc debug only
+ GRLine( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
+ GetABPosition( m_ArcCentre ), 0, color );
+ GRLine( aPanel->GetClipBox(), aDC, GetABPosition( m_End ),
+ GetABPosition( m_ArcCentre ), 0, color );
+#endif
+
+ if( !isFilled )
+ {
+ GRArc1( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
+ GetABPosition( m_End ), GetABPosition( m_ArcCentre ),
+ 0, color );
+ }
+ else
+ {
+ GRArc1( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
+ GetABPosition( m_End ), GetABPosition( m_ArcCentre ),
+ m_Size.x, color );
+ }
+
+ break;
+
+ case GBR_SPOT_CIRCLE:
+ case GBR_SPOT_RECT:
+ case GBR_SPOT_OVAL:
+ case GBR_SPOT_POLY:
+ case GBR_SPOT_MACRO:
+ isFilled = gerbFrame->DisplayFlashedItemsSolidMode();
+ d_codeDescr->DrawFlashedShape( this, aPanel->GetClipBox(), aDC, color, alt_color,
+ m_Start, isFilled );
+ break;
+
+ case GBR_SEGMENT:
+ /* Plot a line from m_Start to m_End.
+ * Usually, a round pen is used, but some gerber files use a rectangular pen
+ * In fact, any aperture can be used to plot a line.
+ * currently: only a square pen is handled (I believe using a polygon gives a strange plot).
+ */
+ if( d_codeDescr->m_Shape == APT_RECT )
+ {
+ if( m_PolyCorners.size() == 0 )
+ ConvertSegmentToPolygon( );
+
+ DrawGbrPoly( aPanel->GetClipBox(), aDC, color, aOffset, isFilled );
+ }
+ else
+ {
+ if( !isFilled )
+ {
+ GRCSegm( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
+ GetABPosition( m_End ), m_Size.x, color );
+ }
+ else
+ {
+ GRFilledSegment( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
+ GetABPosition( m_End ), m_Size.x, color );
+ }
+ }
+
+ break;
+
+ default:
+ if( !show_err )
+ {
+ wxMessageBox( wxT( "Trace_Segment() type error" ) );
+ show_err = true;
+ }
+
+ break;
+ }
+}
+
+
+void GERBER_DRAW_ITEM::ConvertSegmentToPolygon( )
+{
+ m_PolyCorners.clear();
+ m_PolyCorners.reserve(6);
+
+ wxPoint start = m_Start;
+ wxPoint end = m_End;
+
+ // make calculations more easy if ensure start.x < end.x
+ // (only 2 quadrants to consider)
+ if( start.x > end.x )
+ std::swap( start, end );
+
+ // calculate values relative to start point:
+ wxPoint delta = end - start;
+
+ // calculate corners for the first quadrant only (delta.x and delta.y > 0 )
+ // currently, delta.x already is > 0.
+ // make delta.y > 0
+ bool change = delta.y < 0;
+
+ if( change )
+ delta.y = -delta.y;
+
+ // Now create the full polygon.
+ // Due to previous changes, the shape is always something like
+ // 3 4
+ // 2 5
+ // 1 6
+ wxPoint corner;
+ corner.x -= m_Size.x/2;
+ corner.y -= m_Size.y/2;
+ m_PolyCorners.push_back( corner ); // Lower left corner, start point (1)
+ corner.y += m_Size.y;
+ m_PolyCorners.push_back( corner ); // upper left corner, start point (2)
+
+ if( delta.x || delta.y)
+ {
+ corner += delta;
+ m_PolyCorners.push_back( corner ); // upper left corner, end point (3)
+ }
+
+ corner.x += m_Size.x;
+ m_PolyCorners.push_back( corner ); // upper right corner, end point (4)
+ corner.y -= m_Size.y;
+ m_PolyCorners.push_back( corner ); // lower right corner, end point (5)
+
+ if( delta.x || delta.y )
+ {
+ corner -= delta;
+ m_PolyCorners.push_back( corner ); // lower left corner, start point (6)
+ }
+
+ // Create final polygon:
+ for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ )
+ {
+ if( change )
+ m_PolyCorners[ii].y = -m_PolyCorners[ii].y;
+
+ m_PolyCorners[ii] += start;
+ }
+}
+
+
+void GERBER_DRAW_ITEM::DrawGbrPoly( EDA_RECT* aClipBox,
+ wxDC* aDC,
+ EDA_COLOR_T aColor,
+ const wxPoint& aOffset,
+ bool aFilledShape )
+{
+ std::vector<wxPoint> points;
+
+ points = m_PolyCorners;
+ for( unsigned ii = 0; ii < points.size(); ii++ )
+ {
+ points[ii] += aOffset;
+ points[ii] = GetABPosition( points[ii] );
+ }
+
+ GRClosedPoly( aClipBox, aDC, points.size(), &points[0], aFilledShape, aColor, aColor );
+}
+
+
+void GERBER_DRAW_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString msg;
+
+ msg = ShowGBRShape();
+ aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) );
+
+ // Display D_Code value:
+ msg.Printf( wxT( "%d" ), m_DCode );
+ aList.push_back( MSG_PANEL_ITEM( _( "D Code" ), msg, RED ) );
+
+ // Display graphic layer number
+ msg.Printf( wxT( "%d" ), GetLayer() + 1 );
+ aList.push_back( MSG_PANEL_ITEM( _( "Graphic Layer" ), msg, BROWN ) );
+
+ // Display item rotation
+ // The full rotation is Image rotation + m_lyrRotation
+ // but m_lyrRotation is specific to this object
+ // so we display only this parameter
+ msg.Printf( wxT( "%f" ), m_lyrRotation );
+ aList.push_back( MSG_PANEL_ITEM( _( "Rotation" ), msg, BLUE ) );
+
+ // Display item polarity (item specific)
+ msg = m_LayerNegative ? _("Clear") : _("Dark");
+ aList.push_back( MSG_PANEL_ITEM( _( "Polarity" ), msg, BLUE ) );
+
+ // Display mirroring (item specific)
+ msg.Printf( wxT( "A:%s B:%s" ),
+ m_mirrorA ? _("Yes") : _("No"),
+ m_mirrorB ? _("Yes") : _("No"));
+ aList.push_back( MSG_PANEL_ITEM( _( "Mirror" ), msg, DARKRED ) );
+
+ // Display AB axis swap (item specific)
+ msg = m_swapAxis ? wxT( "A=Y B=X" ) : wxT( "A=X B=Y" );
+ aList.push_back( MSG_PANEL_ITEM( _( "AB axis" ), msg, DARKRED ) );
+}
+
+
+bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) const
+{
+ // calculate aRefPos in XY gerber axis:
+ wxPoint ref_pos = GetXYPosition( aRefPos );
+
+ // TODO: a better analyze of the shape (perhaps create a D_CODE::HitTest for flashed items)
+ int radius = std::min( m_Size.x, m_Size.y ) >> 1;
+
+ if( m_Flashed )
+ return HitTestPoints( m_Start, ref_pos, radius );
+ else
+ return TestSegmentHit( ref_pos, m_Start, m_End, radius );
+}
+
+
+bool GERBER_DRAW_ITEM::HitTest( const EDA_RECT& aRefArea ) const
+{
+ wxPoint pos = GetABPosition( m_Start );
+
+ if( aRefArea.Contains( pos ) )
+ return true;
+
+ pos = GetABPosition( m_End );
+
+ if( aRefArea.Contains( pos ) )
+ return true;
+
+ return false;
+}
+
+
+#if defined(DEBUG)
+
+void GERBER_DRAW_ITEM::Show( int nestLevel, std::ostream& os ) const
+{
+ NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() <<
+
+ " shape=\"" << m_Shape << '"' <<
+ " addr=\"" << std::hex << this << std::dec << '"' <<
+ " layer=\"" << m_Layer << '"' <<
+ " size=\"" << m_Size << '"' <<
+ " flags=\"" << m_Flags << '"' <<
+ " status=\"" << GetStatus() << '"' <<
+ "<start" << m_Start << "/>" <<
+ "<end" << m_End << "/>";
+
+ os << "</" << GetClass().Lower().mb_str() << ">\n";
+}
+
+#endif
diff --git a/gerbview/class_gerber_draw_item.h b/gerbview/class_gerber_draw_item.h
new file mode 100644
index 0000000..49e3340
--- /dev/null
+++ b/gerbview/class_gerber_draw_item.h
@@ -0,0 +1,309 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 <Jean-Pierre Charras>
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_gerber_draw_item.h
+ */
+
+#ifndef CLASS_GERBER_DRAW_ITEM_H
+#define CLASS_GERBER_DRAW_ITEM_H
+
+#include <base_struct.h>
+#include <dlist.h>
+#include <layers_id_colors_and_visibility.h>
+#include <gr_basic.h>
+
+class GERBER_IMAGE;
+class GBR_LAYOUT;
+class D_CODE;
+class MSG_PANEL_ITEM;
+
+
+/* Shapes id for basic shapes ( .m_Shape member ) */
+enum Gbr_Basic_Shapes {
+ GBR_SEGMENT = 0, // usual segment : line with rounded ends
+ GBR_ARC, // Arcs (with rounded ends)
+ GBR_CIRCLE, // ring
+ GBR_POLYGON, // polygonal shape
+ GBR_SPOT_CIRCLE, // flashed shape: round shape (can have hole)
+ GBR_SPOT_RECT, // flashed shape: rectangular shape can have hole)
+ GBR_SPOT_OVAL, // flashed shape: oval shape
+ GBR_SPOT_POLY, // flashed shape: regular polygon, 3 to 12 edges
+ GBR_SPOT_MACRO, // complex shape described by a macro
+ GBR_LAST // last value for this list
+};
+
+/***/
+
+class GERBER_DRAW_ITEM : public EDA_ITEM
+{
+ // make SetNext() and SetBack() private so that they may not be called from anywhere.
+ // list management is done on GERBER_DRAW_ITEMs using DLIST<GERBER_DRAW_ITEM> only.
+private:
+ void SetNext( EDA_ITEM* aNext ) { Pnext = aNext; }
+ void SetBack( EDA_ITEM* aBack ) { Pback = aBack; }
+
+
+public:
+ bool m_UnitsMetric; /* store here the gerber units (inch/mm). Used
+ * only to calculate aperture macros shapes sizes */
+ int m_Shape; // Shape and type of this gerber item
+ wxPoint m_Start; // Line or arc start point or position of the shape
+ // for flashed items
+ wxPoint m_End; // Line or arc end point
+ wxPoint m_ArcCentre; // for arcs only: Centre of arc
+ std::vector <wxPoint> m_PolyCorners; // list of corners for polygons (G36 to G37 coordinates)
+ // or for complex shapes which are converted to polygon
+ wxSize m_Size; // Flashed shapes: size of the shape
+ // Lines : m_Size.x = m_Size.y = line width
+ bool m_Flashed; // True for flashed items
+ int m_DCode; // DCode used to draw this item.
+ // 0 for items that do not use DCodes (polygons)
+ // or when unknown and normal values are 10 to 999
+ // values 0 to 9 can be used for special purposes
+ GERBER_IMAGE* m_imageParams; /* main GERBER info for this item
+ * Note: some params stored in this class are common
+ * to the whole gerber file (i.e) the whole graphic
+ * layer and some can change when reaging the file,
+ * so they are stored inside this item there is no
+ * redundancy for these parameters
+ */
+private:
+ int m_Layer;
+
+ // These values are used to draw this item, according to gerber layers parameters
+ // Because they can change inside a gerber image, they are stored here
+ // for each item
+ bool m_LayerNegative; // true = item in negative Layer
+ bool m_swapAxis; // false if A = X, B = Y; true if A =Y, B = Y
+ bool m_mirrorA; // true: mirror / axe A
+ bool m_mirrorB; // true: mirror / axe B
+ wxRealPoint m_drawScale; // A and B scaling factor
+ wxPoint m_layerOffset; // Offset for A and B axis, from OF parameter
+ double m_lyrRotation; // Fine rotation, from OR parameter, in degrees
+
+public:
+ GERBER_DRAW_ITEM( GBR_LAYOUT* aParent, GERBER_IMAGE* aGerberparams );
+ GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource );
+ ~GERBER_DRAW_ITEM();
+
+ /**
+ * Function Copy
+ * will copy this object
+ * the corresponding type.
+ * @return - GERBER_DRAW_ITEM*
+ */
+ GERBER_DRAW_ITEM* Copy() const;
+
+ GERBER_DRAW_ITEM* Next() const { return static_cast<GERBER_DRAW_ITEM*>( Pnext ); }
+ GERBER_DRAW_ITEM* Back() const { return static_cast<GERBER_DRAW_ITEM*>( Pback ); }
+
+ /**
+ * Function GetLayer
+ * returns the layer this item is on.
+ */
+ int GetLayer() const { return m_Layer; }
+
+ /**
+ * Function SetLayer
+ * sets the layer this item is on.
+ * @param aLayer The layer number.
+ * is virtual because some items (in fact: class DIMENSION)
+ * have a slightly different initialization
+ */
+ void SetLayer( int aLayer ) { m_Layer = aLayer; }
+
+ bool GetLayerPolarity()
+ {
+ return m_LayerNegative;
+ }
+
+ /**
+ * Function HasNegativeItems
+ * @return true if this item or at least one shape (when using aperture macros
+ * must be drawn in background color
+ * used to optimize screen refresh (when no items are in background color
+ * refresh can be faster)
+ */
+ bool HasNegativeItems();
+
+ /**
+ * Function SetLayerParameters
+ * Initialize parameters from Image and Layer parameters
+ * found in the gerber file:
+ * m_UnitsMetric,
+ * m_MirrorA, m_MirrorB,
+ * m_DrawScale, m_DrawOffset
+ */
+ void SetLayerParameters();
+
+ void SetLayerPolarity( bool aNegative)
+ {
+ m_LayerNegative = aNegative;
+ }
+
+ /**
+ * Function MoveAB
+ * move this object.
+ * @param aMoveVector - the move vector for this object.
+ */
+ void MoveAB( const wxPoint& aMoveVector );
+
+ /**
+ * Function MoveXY
+ * move this object.
+ * @param aMoveVector - the move vector for this object, in XY gerber axis.
+ */
+ void MoveXY( const wxPoint& aMoveVector );
+
+ /**
+ * Function GetPosition
+ * returns the position of this object.
+ * @return const wxPoint& - The position of this object.
+ * This function exists mainly to satisfy the virtual GetPosition() in parent class
+ */
+ const wxPoint& GetPosition() const { return m_Start; }
+ void SetPosition( const wxPoint& aPos ) { m_Start = aPos; }
+
+ /**
+ * Function GetABPosition
+ * returns the image position of aPosition for this object.
+ * Image position is the value of aPosition, modified by image parameters:
+ * offsets, axis selection, scale, rotation
+ * @param aXYPosition = position in X,Y gerber axis
+ * @return const wxPoint - The given position in plotter A,B axis.
+ */
+ wxPoint GetABPosition( const wxPoint& aXYPosition ) const;
+
+ /**
+ * Function GetXYPosition
+ * returns the image position of aPosition for this object.
+ * Image position is the value of aPosition, modified by image parameters:
+ * offsets, axis selection, scale, rotation
+ * @param aABPosition = position in A,B plotter axis
+ * @return const wxPoint - The given position in X,Y axis.
+ */
+ wxPoint GetXYPosition( const wxPoint& aABPosition ) const;
+
+ /**
+ * Function GetDcodeDescr
+ * returns the GetDcodeDescr of this object, or NULL.
+ * @return D_CODE* - a pointer to the DCode description (for flashed items).
+ */
+ D_CODE* GetDcodeDescr();
+
+ const EDA_RECT GetBoundingBox() const; // Virtual
+
+ /* Display on screen: */
+ void Draw( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC,
+ GR_DRAWMODE aDrawMode,
+ const wxPoint&aOffset );
+
+ /**
+ * Function ConvertSegmentToPolygon
+ * convert a line to an equivalent polygon.
+ * Useful when a line is plotted using a rectangular pen.
+ * In this case, the usual segment plot function cannot be used
+ */
+ void ConvertSegmentToPolygon();
+
+ /**
+ * Function DrawGbrPoly
+ * a helper function used to draw the polygon stored in m_PolyCorners
+ */
+ void DrawGbrPoly( EDA_RECT* aClipBox,
+ wxDC* aDC, EDA_COLOR_T aColor,
+ const wxPoint& aOffset, bool aFilledShape );
+
+ /* divers */
+ int Shape() const { return m_Shape; }
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ wxString ShowGBRShape();
+
+ /**
+ * Function HitTest
+ * tests if the given wxPoint is within the bounds of this object.
+ * @param aRefPos a wxPoint to test
+ * @return bool - true if a hit, else false
+ */
+ bool HitTest( const wxPoint& aRefPos ) const;
+
+ /**
+ * Function HitTest (overloaded)
+ * tests if the given wxRect intersect this object.
+ * For now, an ending point must be inside this rect.
+ * @param aRefArea a wxPoint to test
+ * @return bool - true if a hit, else false
+ */
+ bool HitTest( const EDA_RECT& aRefArea ) const;
+
+ /**
+ * Function GetClass
+ * returns the class name.
+ * @return wxString
+ */
+ wxString GetClass() const
+ {
+ return wxT( "GERBER_DRAW_ITEM" );
+ }
+
+ /**
+ * Function Save.
+ * currently: no nothing, but must be defined to meet requirements
+ * of the basic class
+ */
+ bool Save( FILE* aFile ) const;
+
+ /**
+ * Function UnLink
+ * detaches this object from its owner.
+ */
+ void UnLink()
+ {
+ DLIST<GERBER_DRAW_ITEM>* list = (DLIST<GERBER_DRAW_ITEM>*) GetList();
+ wxASSERT( list );
+
+ if( list )
+ list->Remove( this );
+ }
+
+ /**
+ * Function DeleteStructure
+ * deletes this object after UnLink()ing it from its owner.
+ */
+ void DeleteStructure()
+ {
+ UnLink();
+ delete this;
+ }
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // override
+#endif
+
+};
+
+#endif /* CLASS_GERBER_DRAW_ITEM_H */
diff --git a/gerbview/class_gerbview_layer_widget.cpp b/gerbview/class_gerbview_layer_widget.cpp
new file mode 100644
index 0000000..f2108ac
--- /dev/null
+++ b/gerbview/class_gerbview_layer_widget.cpp
@@ -0,0 +1,338 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2010 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/**
+ * @file class_gerbview_layer_widget.cpp
+ * @brief GerbView layers manager.
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <pcbstruct.h>
+#include <macros.h>
+#include <class_gbr_layer_box_selector.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <class_GERBER.h>
+#include <layer_widget.h>
+#include <class_gerbview_layer_widget.h>
+#include <class_X2_gerber_attributes.h>
+
+
+/*
+ * Class GERBER_LAYER_WIDGET
+ * is here to implement the abtract functions of LAYER_WIDGET so they
+ * may be tied into the GERBVIEW_FRAME's data and so we can add a popup
+ * menu which is specific to Pcbnew's needs.
+ */
+
+
+GERBER_LAYER_WIDGET::GERBER_LAYER_WIDGET( GERBVIEW_FRAME* aParent, wxWindow* aFocusOwner,
+ int aPointSize ) :
+ LAYER_WIDGET( aParent, aFocusOwner, aPointSize ),
+ myframe( aParent )
+{
+ m_alwaysShowActiveLayer = false;
+
+ ReFillRender();
+
+ // Update default tabs labels for GerbView
+ SetLayersManagerTabsText( );
+
+ //-----<Popup menu>-------------------------------------------------
+ // handle the popup menu over the layer window.
+ m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN,
+ wxMouseEventHandler( GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this );
+
+ // since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
+ // and not m_LayerScrolledWindow->Connect()
+ Connect( ID_LAYER_MANAGER_START, ID_LAYER_MANAGER_END,
+ wxEVT_COMMAND_MENU_SELECTED,
+ wxCommandEventHandler( GERBER_LAYER_WIDGET::onPopupSelection ), NULL, this );
+
+ // install the right click handler into each control at end of ReFill()
+ // using installRightLayerClickHandler
+}
+
+/**
+ * Function SetLayersManagerTabsText
+ * Update the layer manager tabs labels
+ * Useful when changing Language or to set labels to a non default value
+ */
+void GERBER_LAYER_WIDGET::SetLayersManagerTabsText( )
+{
+ m_notebook->SetPageText(0, _("Layer") );
+ m_notebook->SetPageText(1, _("Render") );
+}
+
+/**
+ * Function ReFillRender
+ * Rebuild Render for instance after the config is read
+ */
+void GERBER_LAYER_WIDGET::ReFillRender()
+{
+ ClearRenderRows();
+
+ // Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
+ // is changed before appending to the LAYER_WIDGET. This is an automatic variable
+ // not a static variable, change the color & state after copying from code to renderRows
+ // on the stack.
+ LAYER_WIDGET::ROW renderRows[3] = {
+
+#define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
+
+ // text id color tooltip checked
+ RR( _( "Grid" ), GERBER_GRID_VISIBLE, WHITE, _( "Show the (x,y) grid dots" ) ),
+ RR( _( "DCodes" ), DCODES_VISIBLE, WHITE, _( "Show DCodes identification" ) ),
+ RR( _( "Neg. Obj." ), NEGATIVE_OBJECTS_VISIBLE, DARKGRAY,
+ _( "Show negative objects in this color" ) ),
+ };
+
+ for( unsigned row=0; row<DIM(renderRows); ++row )
+ {
+ if( renderRows[row].color != -1 ) // does this row show a color?
+ {
+ renderRows[row].color = myframe->GetVisibleElementColor(
+ (GERBER_VISIBLE_ID)renderRows[row].id );
+ }
+ renderRows[row].state = myframe->IsElementVisible(
+ (GERBER_VISIBLE_ID)renderRows[row].id );
+ }
+
+ AppendRenderRows( renderRows, DIM(renderRows) );
+}
+
+void GERBER_LAYER_WIDGET::installRightLayerClickHandler()
+{
+ int rowCount = GetLayerRowCount();
+
+ for( int row=0; row<rowCount; ++row )
+ {
+ for( int col=0; col<LYR_COLUMN_COUNT; ++col )
+ {
+ wxWindow* w = getLayerComp( row, col );
+
+ w->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler(
+ GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this );
+ }
+ }
+}
+
+
+void GERBER_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event )
+{
+ wxMenu menu;
+
+ // Remember: menu text is capitalized (see our rules_for_capitalization_in_Kicad_UI.txt)
+ menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_LAYERS,
+ _("Show All Layers") ) );
+
+ menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_LAYERS_BUT_ACTIVE,
+ _( "Hide All Layers But Active" ) ) );
+
+ menu.Append( new wxMenuItem( &menu, ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE,
+ _( "Always Hide All Layers But Active" ) ) );
+
+ menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_LAYERS,
+ _( "Hide All Layers" ) ) );
+
+ menu.AppendSeparator();
+ menu.Append( new wxMenuItem( &menu, ID_SORT_GBR_LAYERS,
+ _( "Sort Layers if X2 Mode" ) ) );
+ PopupMenu( &menu );
+
+ passOnFocus();
+}
+
+void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
+{
+ int rowCount;
+ int menuId = event.GetId();
+ bool visible = (menuId == ID_SHOW_ALL_LAYERS) ? true : false;
+ long visibleLayers = 0;
+ bool force_active_layer_visible;
+
+ m_alwaysShowActiveLayer = ( menuId == ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE );
+ force_active_layer_visible = ( menuId == ID_SHOW_NO_LAYERS_BUT_ACTIVE ||
+ menuId == ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE );
+
+ switch( menuId )
+ {
+ case ID_SHOW_ALL_LAYERS:
+ case ID_SHOW_NO_LAYERS:
+ case ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE:
+ case ID_SHOW_NO_LAYERS_BUT_ACTIVE:
+ rowCount = GetLayerRowCount();
+ for( int row=0; row < rowCount; ++row )
+ {
+ wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
+ int layer = getDecodedId( cb->GetId() );
+ bool loc_visible = visible;
+
+ if( force_active_layer_visible && (layer == myframe->getActiveLayer() ) )
+ loc_visible = true;
+
+ cb->SetValue( loc_visible );
+
+ if( loc_visible )
+ visibleLayers |= 1 << row;
+ else
+ visibleLayers &= ~( 1 << row );
+ }
+
+ myframe->SetVisibleLayers( visibleLayers );
+ myframe->GetCanvas()->Refresh();
+ break;
+
+ case ID_SORT_GBR_LAYERS:
+ g_GERBER_List.SortImagesByZOrder( myframe->GetItemsList() );
+ myframe->ReFillLayerWidget();
+ myframe->syncLayerBox();
+ myframe->GetCanvas()->Refresh();
+ break;
+ }
+}
+
+bool GERBER_LAYER_WIDGET::OnLayerSelected()
+{
+ if( !m_alwaysShowActiveLayer )
+ return false;
+
+ // postprocess after active layer selection
+ // ensure active layer visible
+ wxCommandEvent event;
+ event.SetId( ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE );
+ onPopupSelection( event );
+ return true;
+}
+
+
+void GERBER_LAYER_WIDGET::ReFill()
+{
+ Freeze();
+
+ ClearLayerRows();
+
+ for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
+ {
+ wxString msg = g_GERBER_List.GetDisplayName( layer );
+
+ AppendLayerRow( LAYER_WIDGET::ROW( msg, layer,
+ myframe->GetLayerColor( layer ), wxEmptyString, true ) );
+ }
+
+ Thaw();
+
+ installRightLayerClickHandler();
+}
+
+//-----<LAYER_WIDGET callbacks>-------------------------------------------
+
+void GERBER_LAYER_WIDGET::OnLayerColorChange( int aLayer, EDA_COLOR_T aColor )
+{
+ myframe->SetLayerColor( aLayer, aColor );
+ myframe->m_SelLayerBox->ResyncBitmapOnly();
+ myframe->GetCanvas()->Refresh();
+}
+
+bool GERBER_LAYER_WIDGET::OnLayerSelect( int aLayer )
+{
+ // the layer change from the GERBER_LAYER_WIDGET can be denied by returning
+ // false from this function.
+ int layer = myframe->getActiveLayer( );
+ myframe->setActiveLayer( aLayer, false );
+ myframe->syncLayerBox();
+
+ if( layer != myframe->getActiveLayer( ) )
+ {
+ if( ! OnLayerSelected() )
+ myframe->GetCanvas()->Refresh();
+ }
+
+ return true;
+}
+
+void GERBER_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal )
+{
+ long visibleLayers = myframe->GetVisibleLayers();
+
+ if( isVisible )
+ visibleLayers |= 1 << aLayer;
+ else
+ visibleLayers &= ~( 1 << aLayer );
+
+ myframe->SetVisibleLayers( visibleLayers );
+
+ if( isFinal )
+ myframe->GetCanvas()->Refresh();
+}
+
+void GERBER_LAYER_WIDGET::OnRenderColorChange( int aId, EDA_COLOR_T aColor )
+{
+ myframe->SetVisibleElementColor( (GERBER_VISIBLE_ID)aId, aColor );
+ myframe->GetCanvas()->Refresh();
+}
+
+void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
+{
+ myframe->SetElementVisibility( (GERBER_VISIBLE_ID)aId, isEnabled );
+ myframe->GetCanvas()->Refresh();
+}
+
+//-----</LAYER_WIDGET callbacks>------------------------------------------
+
+/*
+ * Virtual Function useAlternateBitmap
+ * return true if bitmaps shown in Render layer list
+ * must be alternate bitmaps, or false to use "normal" bitmaps
+ */
+bool GERBER_LAYER_WIDGET::useAlternateBitmap(int aRow)
+{
+ return g_GERBER_List.IsUsed( aRow );
+}
+
+/*
+ * Update the layer manager icons (layers only)
+ * Useful when loading a file or clearing a layer because they change
+ */
+void GERBER_LAYER_WIDGET::UpdateLayerIcons()
+{
+ int row_count = GetLayerRowCount();
+ for( int row = 0; row < row_count ; row++ )
+ {
+ wxStaticBitmap* bm = (wxStaticBitmap*) getLayerComp( row, COLUMN_ICON_ACTIVE );
+ if( bm == NULL)
+ continue;
+
+ if( row == m_CurrentRow )
+ bm->SetBitmap( useAlternateBitmap(row) ? *m_RightArrowAlternateBitmap :
+ *m_RightArrowBitmap );
+ else
+ bm->SetBitmap( useAlternateBitmap(row) ? *m_BlankAlternateBitmap : *m_BlankBitmap );
+ }
+}
diff --git a/gerbview/class_gerbview_layer_widget.h b/gerbview/class_gerbview_layer_widget.h
new file mode 100644
index 0000000..d7dfc78
--- /dev/null
+++ b/gerbview/class_gerbview_layer_widget.h
@@ -0,0 +1,134 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/************************************************************/
+/* class_gerber_layer_widget.h : header for the layers manager */
+/************************************************************/
+
+#ifndef _CLASS_GERBER_LAYER_WIDGET_H_
+#define _CLASS_GERBER_LAYER_WIDGET_H_
+
+#include <layer_widget.h>
+
+// popup menu ids. in layer manager
+enum LAYER_MANAGER
+{
+ ID_LAYER_MANAGER_START = wxID_HIGHEST+1,
+ ID_SHOW_ALL_LAYERS = ID_LAYER_MANAGER_START,
+ ID_SHOW_NO_LAYERS,
+ ID_SHOW_NO_LAYERS_BUT_ACTIVE,
+ ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE,
+ ID_SORT_GBR_LAYERS,
+ ID_LAYER_MANAGER_END = ID_SORT_GBR_LAYERS,
+};
+
+/**
+ * Class GERBER_LAYER_WIDGET
+ * is here to implement the abtract functions of LAYER_WIDGET so they
+ * may be tied into the GERBVIEW_FRAME's data and so we can add a popup
+ * menu which is specific to Pcbnew's needs.
+ */
+class GERBER_LAYER_WIDGET : public LAYER_WIDGET
+{
+ GERBVIEW_FRAME* myframe;
+ bool m_alwaysShowActiveLayer; // If true: Only shows the current active layer
+ // even if it is changed
+
+
+ /**
+ * Function OnRightDownLayers
+ * puts up a popup menu for the layer panel.
+ */
+ void onRightDownLayers( wxMouseEvent& event );
+
+ void onPopupSelection( wxCommandEvent& event );
+
+ /// this is for the popup menu, the right click handler has to be installed
+ /// on every child control within the layer panel.
+ void installRightLayerClickHandler();
+
+ /**
+ * Virtual Function useAlternateBitmap
+ * @return true if bitmaps shown in Render layer list
+ * are alternate bitmaps, or false if they are "normal" bitmaps
+ */
+ virtual bool useAlternateBitmap(int aRow);
+
+public:
+
+ /**
+ * Constructor
+ * @param aParent : the parent frame
+ * @param aFocusOwner : the window that has the keyboard focus.
+ * @param aPointSize is the font point size to use within the widget. This
+ * effectively sets the overal size of the widget via the row height and bitmap
+ * button sizes.
+ */
+ GERBER_LAYER_WIDGET( GERBVIEW_FRAME* aParent, wxWindow* aFocusOwner, int aPointSize = 10 );
+
+ void ReFill();
+
+ /**
+ * Function ReFillRender
+ * Rebuild Render for instance after the config is read
+ */
+ void ReFillRender();
+
+ //-----<implement LAYER_WIDGET abstract callback functions>-----------
+ void OnLayerColorChange( int aLayer, EDA_COLOR_T aColor );
+ bool OnLayerSelect( int aLayer );
+ void OnLayerVisible( int aLayer, bool isVisible, bool isFinal );
+ void OnRenderColorChange( int aId, EDA_COLOR_T aColor );
+ void OnRenderEnable( int aId, bool isEnabled );
+ /**
+ * Function SetLayersManagerTabsText
+ * Update the layer manager tabs labels
+ * Useful when changing Language or to set labels to a non default value
+ */
+ void SetLayersManagerTabsText( );
+ //-----</implement LAYER_WIDGET abstract callback functions>----------
+
+ /**
+ * Function OnLayerSelected
+ * ensure the active layer is visible, and other layers not visible
+ * when m_alwaysShowActiveLayer is true
+ * Otherwise do nothing.
+ * @return true m_alwaysShowActiveLayer is true and the canvas is refreshed,
+ * and false if do nothing
+ */
+ bool OnLayerSelected(); // postprocess after an active layer selection
+ // ensure active layer visible if
+ // m_alwaysShowActiveCopperLayer is true;
+
+ /**
+ * Function UpdateLayerIcons
+ * Update the layer manager icons (layers only)
+ * Useful when loading a file or clearing a layer because they change
+ */
+ void UpdateLayerIcons();
+};
+
+#endif // _CLASS_GERBER_LAYER_WIDGET_H_
diff --git a/gerbview/controle.cpp b/gerbview/controle.cpp
new file mode 100644
index 0000000..ace281c
--- /dev/null
+++ b/gerbview/controle.cpp
@@ -0,0 +1,62 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 <Jean-Pierre Charras>
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file gerbview/controle.cpp
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <gerbview.h>
+#include <gerbview_frame.h>
+
+
+bool GERBVIEW_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
+{
+ bool eventHandled = true;
+
+ // Filter out the 'fake' mouse motion after a keyboard movement
+ if( !aHotKey && m_movingCursorWithKeyboard )
+ {
+ m_movingCursorWithKeyboard = false;
+ return false;
+ }
+
+ wxPoint pos = aPosition;
+ wxPoint oldpos = GetCrossHairPosition();
+ GeneralControlKeyMovement( aHotKey, &pos, true );
+
+ SetCrossHairPosition( pos );
+ RefreshCrossHair( oldpos, aPosition, aDC );
+
+ if( aHotKey )
+ {
+ eventHandled = OnHotKey( aDC, aHotKey, aPosition );
+ }
+
+ UpdateStatusBar();
+
+ return eventHandled;
+}
diff --git a/gerbview/dcode.cpp b/gerbview/dcode.cpp
new file mode 100644
index 0000000..8063b81
--- /dev/null
+++ b/gerbview/dcode.cpp
@@ -0,0 +1,531 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dcode.cpp
+ * @brief D_CODE class implementation
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <macros.h>
+#include <trigo.h>
+#include <gr_basic.h>
+#include <base_units.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <class_gerber_draw_item.h>
+#include <class_GERBER.h>
+
+#define DEFAULT_SIZE 100
+
+/* Format Gerber: NOTES:
+ * Tools and D_CODES
+ * tool number (identification of shapes)
+ * 1 to 999
+ *
+ * D_CODES:
+ * D01 ... D9 = command codes:
+ * D01 = activating light (pen down) while moving
+ * D02 = light extinction (pen up) while moving
+ * D03 = Flash
+ * D04 to D09 = non used
+ * D10 ... D999 = Identification Tool (Shape id)
+ *
+ * For tools defining a shape):
+ * DCode min = D10
+ * DCode max = 999
+ */
+
+
+/***************/
+/* Class DCODE */
+/***************/
+
+
+D_CODE::D_CODE( int num_dcode )
+{
+ m_Num_Dcode = num_dcode;
+ Clear_D_CODE_Data();
+}
+
+
+D_CODE::~D_CODE()
+{
+}
+
+
+void D_CODE::Clear_D_CODE_Data()
+{
+ m_Size.x = DEFAULT_SIZE;
+ m_Size.y = DEFAULT_SIZE;
+ m_Shape = APT_CIRCLE;
+ m_Drill.x = m_Drill.y = 0;
+ m_DrillShape = APT_DEF_NO_HOLE;
+ m_InUse = false;
+ m_Defined = false;
+ m_Macro = NULL;
+ m_Rotation = 0.0;
+ m_EdgesCount = 0;
+ m_PolyCorners.clear();
+}
+
+
+const wxChar* D_CODE::ShowApertureType( APERTURE_T aType )
+{
+ const wxChar* ret;
+
+ switch( aType )
+ {
+ case APT_CIRCLE:
+ ret = wxT( "Round" ); break;
+
+ case APT_RECT:
+ ret = wxT( "Rect" ); break;
+
+ case APT_OVAL:
+ ret = wxT( "Oval" ); break;
+
+ case APT_POLYGON:
+ ret = wxT( "Poly" ); break;
+
+ case APT_MACRO:
+ ret = wxT( "Macro" ); break;
+
+ default:
+ ret = wxT( "???" ); break;
+ }
+
+ return ret;
+}
+
+int D_CODE::GetShapeDim( GERBER_DRAW_ITEM* aParent )
+{
+ int dim = -1;
+ switch( m_Shape )
+ {
+ case APT_CIRCLE:
+ dim = m_Size.x;
+ break;
+
+ case APT_RECT:
+ case APT_OVAL:
+ dim = std::min( m_Size.x, m_Size.y );
+ break;
+
+ case APT_POLYGON:
+ dim = std::min( m_Size.x, m_Size.y );
+ break;
+
+ case APT_MACRO:
+ if( m_Macro )
+ dim = m_Macro->GetShapeDim( aParent );
+ break;
+
+ default:
+ break;
+ }
+
+ return dim;
+}
+
+
+void GERBVIEW_FRAME::CopyDCodesSizeToItems()
+{
+ static D_CODE dummy( 999 ); //Used if D_CODE not found in list
+
+ GERBER_DRAW_ITEM* gerb_item = GetItemsList();
+ for( ; gerb_item; gerb_item = gerb_item->Next() )
+ {
+ D_CODE* dcode = gerb_item->GetDcodeDescr();
+ wxASSERT( dcode );
+ if( dcode == NULL )
+ dcode = &dummy;
+
+ dcode->m_InUse = true;
+
+ gerb_item->m_Size = dcode->m_Size;
+
+ if( // Line Item
+ (gerb_item->m_Shape == GBR_SEGMENT ) /* rectilinear segment */
+ || (gerb_item->m_Shape == GBR_ARC ) /* segment arc (rounded tips) */
+ || (gerb_item->m_Shape == GBR_CIRCLE ) /* segment in a circle (ring) */
+ )
+ {
+ }
+ else // Spots ( Flashed Items )
+ {
+ switch( dcode->m_Shape )
+ {
+ case APT_CIRCLE: /* spot round */
+ gerb_item->m_Shape = GBR_SPOT_CIRCLE;
+ break;
+
+ case APT_OVAL: /* spot oval*/
+ gerb_item->m_Shape = GBR_SPOT_OVAL;
+ break;
+
+ case APT_RECT: /* spot rect*/
+ gerb_item->m_Shape = GBR_SPOT_RECT;
+ break;
+
+ case APT_POLYGON:
+ gerb_item->m_Shape = GBR_SPOT_POLY;
+ break;
+
+ case APT_MACRO: /* spot defined by a macro */
+ gerb_item->m_Shape = GBR_SPOT_MACRO;
+ break;
+
+ default:
+ wxMessageBox( wxT( "GERBVIEW_FRAME::CopyDCodesSizeToItems() error" ) );
+ break;
+ }
+ }
+ }
+}
+
+
+void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
+ EDA_RECT* aClipBox, wxDC* aDC, EDA_COLOR_T aColor,
+ EDA_COLOR_T aAltColor,
+ wxPoint aShapePos, bool aFilledShape )
+{
+ int radius;
+
+ switch( m_Shape )
+ {
+ case APT_MACRO:
+ GetMacro()->DrawApertureMacroShape( aParent, aClipBox, aDC, aColor, aAltColor,
+ aShapePos, aFilledShape);
+ break;
+
+ case APT_CIRCLE:
+ radius = m_Size.x >> 1;
+ if( !aFilledShape )
+ GRCircle( aClipBox, aDC, aParent->GetABPosition(aShapePos), radius, 0, aColor );
+ else
+ if( m_DrillShape == APT_DEF_NO_HOLE )
+ {
+ GRFilledCircle( aClipBox, aDC, aParent->GetABPosition(aShapePos),
+ radius, aColor );
+ }
+ else if( APT_DEF_ROUND_HOLE == 1 ) // round hole in shape
+ {
+ int width = (m_Size.x - m_Drill.x ) / 2;
+ GRCircle( aClipBox, aDC, aParent->GetABPosition(aShapePos),
+ radius - (width / 2), width, aColor );
+ }
+ else // rectangular hole
+ {
+ if( m_PolyCorners.size() == 0 )
+ ConvertShapeToPolygon();
+
+ DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
+ }
+ break;
+
+ case APT_RECT:
+ {
+ wxPoint start;
+ start.x = aShapePos.x - m_Size.x / 2;
+ start.y = aShapePos.y - m_Size.y / 2;
+ wxPoint end = start + m_Size;
+ start = aParent->GetABPosition( start );
+ end = aParent->GetABPosition( end );
+
+ if( !aFilledShape )
+ {
+ GRRect( aClipBox, aDC, start.x, start.y, end.x, end.y, 0, aColor );
+ }
+ else if( m_DrillShape == APT_DEF_NO_HOLE )
+ {
+ GRFilledRect( aClipBox, aDC, start.x, start.y, end.x, end.y, 0, aColor, aColor );
+ }
+ else
+ {
+ if( m_PolyCorners.size() == 0 )
+ ConvertShapeToPolygon();
+
+ DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
+ }
+ }
+ break;
+
+ case APT_OVAL:
+ {
+ wxPoint start = aShapePos;
+ wxPoint end = aShapePos;
+
+ if( m_Size.x > m_Size.y ) // horizontal oval
+ {
+ int delta = (m_Size.x - m_Size.y) / 2;
+ start.x -= delta;
+ end.x += delta;
+ radius = m_Size.y;
+ }
+ else // horizontal oval
+ {
+ int delta = (m_Size.y - m_Size.x) / 2;
+ start.y -= delta;
+ end.y += delta;
+ radius = m_Size.x;
+ }
+
+ start = aParent->GetABPosition( start );
+ end = aParent->GetABPosition( end );
+
+ if( !aFilledShape )
+ {
+ GRCSegm( aClipBox, aDC, start.x, start.y, end.x, end.y, radius, aColor );
+ }
+ else if( m_DrillShape == APT_DEF_NO_HOLE )
+ {
+ GRFillCSegm( aClipBox, aDC, start.x, start.y, end.x, end.y, radius, aColor );
+ }
+ else
+ {
+ if( m_PolyCorners.size() == 0 )
+ ConvertShapeToPolygon();
+
+ DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
+ }
+ }
+ break;
+
+ case APT_POLYGON:
+ if( m_PolyCorners.size() == 0 )
+ ConvertShapeToPolygon();
+
+ DrawFlashedPolygon( aParent, aClipBox, aDC, aColor, aFilledShape, aShapePos );
+ break;
+ }
+}
+
+
+void D_CODE::DrawFlashedPolygon( GERBER_DRAW_ITEM* aParent,
+ EDA_RECT* aClipBox, wxDC* aDC,
+ EDA_COLOR_T aColor, bool aFilled,
+ const wxPoint& aPosition )
+{
+ if( m_PolyCorners.size() == 0 )
+ return;
+
+ std::vector<wxPoint> points;
+ points = m_PolyCorners;
+
+ for( unsigned ii = 0; ii < points.size(); ii++ )
+ {
+ points[ii] += aPosition;
+ points[ii] = aParent->GetABPosition( points[ii] );
+ }
+
+ GRClosedPoly( aClipBox, aDC, points.size(), &points[0], aFilled, aColor, aColor );
+}
+
+
+#define SEGS_CNT 32 // number of segments to approximate a circle
+
+
+// A helper function for D_CODE::ConvertShapeToPolygon(). Add a hole to a polygon
+static void addHoleToPolygon( std::vector<wxPoint>& aBuffer,
+ APERTURE_DEF_HOLETYPE aHoleShape,
+ wxSize aSize,
+ wxPoint aAnchorPos );
+
+
+void D_CODE::ConvertShapeToPolygon()
+{
+ wxPoint initialpos;
+ wxPoint currpos;
+
+ m_PolyCorners.clear();
+
+ switch( m_Shape )
+ {
+ case APT_CIRCLE: // creates only a circle with rectangular hole
+ currpos.x = m_Size.x >> 1;
+ initialpos = currpos;
+
+ for( unsigned ii = 0; ii <= SEGS_CNT; ii++ )
+ {
+ currpos = initialpos;
+ RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT );
+ m_PolyCorners.push_back( currpos );
+ }
+
+ addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
+ break;
+
+ case APT_RECT:
+ currpos.x = m_Size.x / 2;
+ currpos.y = m_Size.y / 2;
+ initialpos = currpos;
+ m_PolyCorners.push_back( currpos );
+ currpos.x -= m_Size.x;
+ m_PolyCorners.push_back( currpos );
+ currpos.y -= m_Size.y;
+ m_PolyCorners.push_back( currpos );
+ currpos.x += m_Size.x;
+ m_PolyCorners.push_back( currpos );
+ currpos.y += m_Size.y;
+ m_PolyCorners.push_back( currpos ); // close polygon
+
+ addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
+ break;
+
+ case APT_OVAL:
+ {
+ int delta, radius;
+
+ // we create an horizontal oval shape. then rotate if needed
+ if( m_Size.x > m_Size.y ) // horizontal oval
+ {
+ delta = (m_Size.x - m_Size.y) / 2;
+ radius = m_Size.y / 2;
+ }
+ else // vertical oval
+ {
+ delta = (m_Size.y - m_Size.x) / 2;
+ radius = m_Size.x / 2;
+ }
+
+ currpos.y = radius;
+ initialpos = currpos;
+ m_PolyCorners.push_back( currpos );
+
+ // build the right arc of the shape
+ unsigned ii = 0;
+
+ for( ; ii <= SEGS_CNT / 2; ii++ )
+ {
+ currpos = initialpos;
+ RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT );
+ currpos.x += delta;
+ m_PolyCorners.push_back( currpos );
+ }
+
+ // build the left arc of the shape
+ for( ii = SEGS_CNT / 2; ii <= SEGS_CNT; ii++ )
+ {
+ currpos = initialpos;
+ RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT );
+ currpos.x -= delta;
+ m_PolyCorners.push_back( currpos );
+ }
+
+ m_PolyCorners.push_back( initialpos ); // close outline
+
+ if( m_Size.y > m_Size.x ) // vertical oval, rotate polygon.
+ {
+ for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ )
+ RotatePoint( &m_PolyCorners[jj], 900 );
+ }
+
+ addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
+ }
+ break;
+
+ case APT_POLYGON:
+ currpos.x = m_Size.x >> 1; // first point is on X axis
+ initialpos = currpos;
+
+ // rs274x said: m_EdgesCount = 3 ... 12
+ if( m_EdgesCount < 3 )
+ m_EdgesCount = 3;
+
+ if( m_EdgesCount > 12 )
+ m_EdgesCount = 12;
+
+ for( int ii = 0; ii <= m_EdgesCount; ii++ )
+ {
+ currpos = initialpos;
+ RotatePoint( &currpos, ii * 3600.0 / m_EdgesCount );
+ m_PolyCorners.push_back( currpos );
+ }
+
+ addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
+
+ if( m_Rotation ) // vertical oval, rotate polygon.
+ {
+ int angle = KiROUND( m_Rotation * 10 );
+
+ for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ )
+ {
+ RotatePoint( &m_PolyCorners[jj], -angle );
+ }
+ }
+
+ break;
+
+ case APT_MACRO:
+
+ // TODO
+ break;
+ }
+}
+
+
+// The helper function for D_CODE::ConvertShapeToPolygon().
+// Add a hole to a polygon
+static void addHoleToPolygon( std::vector<wxPoint>& aBuffer,
+ APERTURE_DEF_HOLETYPE aHoleShape,
+ wxSize aSize,
+ wxPoint aAnchorPos )
+{
+ wxPoint currpos;
+
+ if( aHoleShape == APT_DEF_ROUND_HOLE ) // build a round hole
+ {
+ for( int ii = 0; ii <= SEGS_CNT; ii++ )
+ {
+ currpos.x = 0;
+ currpos.y = aSize.x / 2; // aSize.x / 2 is the radius of the hole
+ RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT );
+ aBuffer.push_back( currpos );
+ }
+
+ aBuffer.push_back( aAnchorPos ); // link to outline
+ }
+
+ if( aHoleShape == APT_DEF_RECT_HOLE ) // Create rectangular hole
+ {
+ currpos.x = aSize.x / 2;
+ currpos.y = aSize.y / 2;
+ aBuffer.push_back( currpos ); // link to hole and begin hole
+ currpos.x -= aSize.x;
+ aBuffer.push_back( currpos );
+ currpos.y -= aSize.y;
+ aBuffer.push_back( currpos );
+ currpos.x += aSize.x;
+ aBuffer.push_back( currpos );
+ currpos.y += aSize.y;
+ aBuffer.push_back( currpos ); // close hole
+ aBuffer.push_back( aAnchorPos ); // link to outline
+ }
+}
diff --git a/gerbview/dcode.h b/gerbview/dcode.h
new file mode 100644
index 0000000..ebc36c1
--- /dev/null
+++ b/gerbview/dcode.h
@@ -0,0 +1,218 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dcode.h
+ */
+
+#ifndef _DCODE_H_
+#define _DCODE_H_
+
+#include <vector>
+
+#include <base_struct.h>
+
+
+class GERBER_DRAW_ITEM;
+
+
+/**
+ * Enum APERTURE_T
+ * is the set of all gerber aperture types allowed, according to page 16 of
+ * http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
+ */
+enum APERTURE_T {
+ APT_CIRCLE = 'C', // Flashed shape: Circle with or without hole
+ APT_RECT = 'R', // Flashed shape: Rectangle with or without hole
+ APT_OVAL = '0', // Flashed shape: Oval with or without hole
+ APT_POLYGON = 'P', // Flashed shape: Regular polygon (3 to 12 edges)
+ // with or without hole. Can be rotated
+ APT_MACRO = 'M' // Complex shape given by a macro definition (see AM_PRIMITIVE_ID)
+};
+
+// In aperture definition, round, oval and rectangular flashed shapes
+// can have a hole (round or rectangular)
+// this option is stored in .m_DrillShape D_CODE member
+enum APERTURE_DEF_HOLETYPE {
+ APT_DEF_NO_HOLE = 0,
+ APT_DEF_ROUND_HOLE,
+ APT_DEF_RECT_HOLE
+};
+
+/* define min and max values for D Codes values.
+ * note: values >= 0 and > FIRST_DCODE can be used for special purposes
+ */
+#define FIRST_DCODE 10
+#define LAST_DCODE 999
+#define TOOLS_MAX_COUNT (LAST_DCODE + 1)
+
+struct APERTURE_MACRO;
+
+
+/**
+ * Class D_CODE
+ * holds a gerber DCODE definition.
+ */
+class D_CODE
+{
+private:
+ APERTURE_MACRO* m_Macro; ///< no ownership, points to
+ // GERBER.m_aperture_macros element
+ /**
+ * parameters used only when this D_CODE holds a reference to an aperture
+ * macro, and these parameters would customize the macro.
+ */
+ std::vector<double> m_am_params;
+
+ std::vector <wxPoint> m_PolyCorners; /* Polygon used to draw APT_POLYGON shape and some other
+ * complex shapes which are converted to polygon
+ * (shapes with hole )
+ */
+
+public:
+ wxSize m_Size; /* Horizontal and vertical dimensions. */
+ APERTURE_T m_Shape; /* shape ( Line, rectangle, circle , oval .. ) */
+ int m_Num_Dcode; /* D code ( >= 10 ) */
+ wxSize m_Drill; /* dimension of the hole (if any) */
+ APERTURE_DEF_HOLETYPE m_DrillShape; /* shape of the hole (0 = no hole, round = 1, rect = 2) */
+ double m_Rotation; /* shape rotation in degrees */
+ int m_EdgesCount; /* in aperture definition Polygon only: number of edges for the polygon */
+ bool m_InUse; /* false if not used */
+ bool m_Defined; /* false if not defined */
+ wxString m_SpecialDescr;
+
+public:
+ D_CODE( int num_dcode );
+ ~D_CODE();
+ void Clear_D_CODE_Data();
+
+ /**
+ * AppendParam()
+ * Add a parameter to the D_CODE parameter list.
+ * used to customize the corresponding aperture macro
+ */
+ void AppendParam( double aValue )
+ {
+ m_am_params.push_back( aValue );
+ }
+
+ /**
+ * GetParamCount()
+ * Returns the number of parameters stored in parameter list.
+ */
+ unsigned GetParamCount() const
+ {
+ return m_am_params.size();
+ }
+
+ /**
+ * GetParam()
+ * Returns a parameter stored in parameter list.
+ * @param aIdx = index of parameter
+ */
+ double GetParam( unsigned aIdx ) const
+ {
+ wxASSERT( aIdx <= m_am_params.size() );
+ if( aIdx <= m_am_params.size() )
+ return m_am_params[aIdx - 1];
+ else
+ return 0;
+ }
+
+
+ void SetMacro( APERTURE_MACRO* aMacro )
+ {
+ m_Macro = aMacro;
+ }
+
+
+ APERTURE_MACRO* GetMacro() const { return m_Macro; }
+
+ /**
+ * Function ShowApertureType
+ * returns a character string telling what type of aperture type \a aType is.
+ * @param aType The aperture type to show.
+ */
+ static const wxChar* ShowApertureType( APERTURE_T aType );
+
+ /**
+ * Function DrawFlashedShape
+ * Draw the dcode shape for flashed items.
+ * When an item is flashed, the DCode shape is the shape of the item
+ * @param aParent = the GERBER_DRAW_ITEM being drawn
+ * @param aClipBox = DC clip box (NULL is no clip)
+ * @param aDC = device context
+ * @param aColor = the normal color to use
+ * @param aAltColor = the color used to draw with "reverse" exposure mode (used in
+ * aperture macros only)
+ * @param aShapePos = the actual shape position
+ * @param aFilledShape = true to draw in filled mode, false to draw in sketch mode
+ */
+ void DrawFlashedShape( GERBER_DRAW_ITEM* aParent, EDA_RECT* aClipBox,
+ wxDC* aDC, EDA_COLOR_T aColor, EDA_COLOR_T aAltColor,
+ wxPoint aShapePos, bool aFilledShape );
+
+ /**
+ * Function DrawFlashedPolygon
+ * a helper function used to draw the polygon stored ion m_PolyCorners
+ * Draw some Apertures shapes when they are defined as filled polygons.
+ * APT_POLYGON is always a polygon, but some complex shapes are also converted to
+ * polygons (shapes with holes, some rotated shapes)
+ * @param aParent = the GERBER_DRAW_ITEM being drawn
+ * @param aClipBox = DC clip box (NULL is no clip)
+ * @param aDC = device context
+ * @param aColor = the normal color to use
+ * @param aFilled = true to draw in filled mode, false to draw in sketch mode
+ * @param aPosition = the actual shape position
+ */
+ void DrawFlashedPolygon( GERBER_DRAW_ITEM* aParent,
+ EDA_RECT* aClipBox, wxDC* aDC, EDA_COLOR_T aColor,
+ bool aFilled, const wxPoint& aPosition );
+
+ /**
+ * Function ConvertShapeToPolygon
+ * convert a shape to an equivalent polygon.
+ * Arcs and circles are approximated by segments
+ * Useful when a shape is not a graphic primitive (shape with hole,
+ * rotated shape ... ) and cannot be easily drawn.
+ */
+ void ConvertShapeToPolygon();
+
+ /**
+ * Function GetShapeDim
+ * calculates a value that can be used to evaluate the size of text
+ * when displaying the D-Code of an item
+ * due to the complexity of some shapes,
+ * one cannot calculate the "size" of a shape (only a bounding box)
+ * but here, the "dimension" of the shape is the diameter of the primitive
+ * or for lines the width of the line if the shape is a line
+ * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
+ * @return a dimension, or -1 if no dim to calculate
+ */
+ int GetShapeDim( GERBER_DRAW_ITEM* aParent );
+};
+
+
+#endif // ifndef _DCODE_H_
diff --git a/gerbview/dialogs/dialog_layers_select_to_pcb_base.cpp b/gerbview/dialogs/dialog_layers_select_to_pcb_base.cpp
new file mode 100644
index 0000000..068d992
--- /dev/null
+++ b/gerbview/dialogs/dialog_layers_select_to_pcb_base.cpp
@@ -0,0 +1,119 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Apr 10 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_layers_select_to_pcb_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+BEGIN_EVENT_TABLE( LAYERS_MAP_DIALOG_BASE, DIALOG_SHIM )
+ EVT_COMBOBOX( ID_M_COMBOCOPPERLAYERSCOUNT, LAYERS_MAP_DIALOG_BASE::_wxFB_OnBrdLayersCountSelection )
+ EVT_BUTTON( ID_STORE_CHOICE, LAYERS_MAP_DIALOG_BASE::_wxFB_OnStoreSetup )
+ EVT_BUTTON( ID_GET_PREVIOUS_CHOICE, LAYERS_MAP_DIALOG_BASE::_wxFB_OnGetSetup )
+ EVT_BUTTON( ID_RESET_CHOICE, LAYERS_MAP_DIALOG_BASE::_wxFB_OnResetClick )
+ EVT_BUTTON( wxID_CANCEL, LAYERS_MAP_DIALOG_BASE::_wxFB_OnCancelClick )
+ EVT_BUTTON( wxID_OK, LAYERS_MAP_DIALOG_BASE::_wxFB_OnOkClick )
+END_EVENT_TABLE()
+
+LAYERS_MAP_DIALOG_BASE::LAYERS_MAP_DIALOG_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* sbUpperSizer;
+ sbUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ sbSizerLayersTable = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Layers selection:") ), wxHORIZONTAL );
+
+ m_flexLeftColumnBoxSizer = new wxFlexGridSizer( 16, 4, 0, 0 );
+ m_flexLeftColumnBoxSizer->AddGrowableCol( 0 );
+ m_flexLeftColumnBoxSizer->AddGrowableCol( 1 );
+ m_flexLeftColumnBoxSizer->AddGrowableCol( 2 );
+ m_flexLeftColumnBoxSizer->AddGrowableCol( 3 );
+ m_flexLeftColumnBoxSizer->SetFlexibleDirection( wxBOTH );
+ m_flexLeftColumnBoxSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+
+ sbSizerLayersTable->Add( m_flexLeftColumnBoxSizer, 1, wxEXPAND, 5 );
+
+ m_staticlineSep = new wxStaticLine( this, ID_M_STATICLINESEP, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
+ sbSizerLayersTable->Add( m_staticlineSep, 0, wxEXPAND | wxALL, 5 );
+
+
+ sbUpperSizer->Add( sbSizerLayersTable, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bRightSizer;
+ bRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerLyrCnt;
+ bSizerLyrCnt = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextCopperlayerCount = new wxStaticText( this, ID_M_STATICTEXTCOPPERLAYERCOUNT, _("Copper layers count:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextCopperlayerCount->Wrap( -1 );
+ bSizerLyrCnt->Add( m_staticTextCopperlayerCount, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_comboCopperLayersCount = new wxComboBox( this, ID_M_COMBOCOPPERLAYERSCOUNT, _("2 Layers"), wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ m_comboCopperLayersCount->Append( _("2 Layers") );
+ m_comboCopperLayersCount->Append( _("4 Layers") );
+ m_comboCopperLayersCount->Append( _("6 Layers") );
+ m_comboCopperLayersCount->Append( _("8 Layers") );
+ m_comboCopperLayersCount->Append( _("10 Layers") );
+ m_comboCopperLayersCount->Append( _("12 Layers") );
+ m_comboCopperLayersCount->Append( _("14 Layers") );
+ m_comboCopperLayersCount->Append( _("16 Layers") );
+ bSizerLyrCnt->Add( m_comboCopperLayersCount, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bRightSizer->Add( bSizerLyrCnt, 0, wxEXPAND, 5 );
+
+
+ bRightSizer->Add( 5, 15, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerButtons;
+ bSizerButtons = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonStore = new wxButton( this, ID_STORE_CHOICE, _("Store Choice"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( m_buttonStore, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonRetrieve = new wxButton( this, ID_GET_PREVIOUS_CHOICE, _("Get Stored Choice"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( m_buttonRetrieve, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonReset = new wxButton( this, ID_RESET_CHOICE, _("Reset"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( m_buttonReset, 0, wxALL|wxEXPAND, 5 );
+
+
+ bRightSizer->Add( bSizerButtons, 0, wxEXPAND, 5 );
+
+
+ sbUpperSizer->Add( bRightSizer, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bSizerMain->Add( sbUpperSizer, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerMain->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_sdbSizerButtons = new wxStdDialogButtonSizer();
+ m_sdbSizerButtonsOK = new wxButton( this, wxID_OK );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsOK );
+ m_sdbSizerButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsCancel );
+ m_sdbSizerButtons->Realize();
+
+ bSizerMain->Add( m_sdbSizerButtons, 0, wxALIGN_RIGHT|wxALL, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+}
+
+LAYERS_MAP_DIALOG_BASE::~LAYERS_MAP_DIALOG_BASE()
+{
+}
diff --git a/gerbview/dialogs/dialog_layers_select_to_pcb_base.fbp b/gerbview/dialogs/dialog_layers_select_to_pcb_base.fbp
new file mode 100644
index 0000000..2969fb1
--- /dev/null
+++ b/gerbview/dialogs/dialog_layers_select_to_pcb_base.fbp
@@ -0,0 +1,809 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="11" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">table</property>
+ <property name="file">dialog_layers_select_to_pcb_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_layers_select_to_pcb_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">ID_LAYERS_MAP_DIALOG_BASE</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">LAYERS_MAP_DIALOG_BASE</property>
+ <property name="pos"></property>
+ <property name="size">400,286</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Layer selection:</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">sbUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layers selection:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerLayersTable</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">4</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">0,1,2,3</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_flexLeftColumnBoxSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">protected</property>
+ <property name="rows">16</property>
+ <property name="vgap">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_STATICLINESEP</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticlineSep</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_VERTICAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerLyrCnt</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_STATICTEXTCOPPERLAYERCOUNT</property>
+ <property name="label">Copper layers count:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextCopperlayerCount</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;2 Layers&quot; &quot;4 Layers&quot; &quot;6 Layers&quot; &quot;8 Layers&quot; &quot;10 Layers&quot; &quot;12 Layers&quot; &quot;14 Layers&quot; &quot;16 Layers&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_COMBOCOPPERLAYERSCOUNT</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_comboCopperLayersCount</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">2 Layers</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox">OnBrdLayersCountSelection</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">15</property>
+ <property name="permission">protected</property>
+ <property name="width">5</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerButtons</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_STORE_CHOICE</property>
+ <property name="label">Store Choice</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonStore</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnStoreSetup</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_GET_PREVIOUS_CHOICE</property>
+ <property name="label">Get Stored Choice</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonRetrieve</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnGetSetup</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_RESET_CHOICE</property>
+ <property name="label">Reset</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonReset</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnResetClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizerButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/gerbview/dialogs/dialog_layers_select_to_pcb_base.h b/gerbview/dialogs/dialog_layers_select_to_pcb_base.h
new file mode 100644
index 0000000..c5cfba6
--- /dev/null
+++ b/gerbview/dialogs/dialog_layers_select_to_pcb_base.h
@@ -0,0 +1,88 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Apr 10 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_LAYERS_SELECT_TO_PCB_BASE_H__
+#define __DIALOG_LAYERS_SELECT_TO_PCB_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+#include "dialog_shim.h"
+#include <wx/sizer.h>
+#include <wx/gdicmn.h>
+#include <wx/statline.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/string.h>
+#include <wx/statbox.h>
+#include <wx/stattext.h>
+#include <wx/combobox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class LAYERS_MAP_DIALOG_BASE
+///////////////////////////////////////////////////////////////////////////////
+class LAYERS_MAP_DIALOG_BASE : public DIALOG_SHIM
+{
+ DECLARE_EVENT_TABLE()
+ private:
+
+ // Private event handlers
+ void _wxFB_OnBrdLayersCountSelection( wxCommandEvent& event ){ OnBrdLayersCountSelection( event ); }
+ void _wxFB_OnStoreSetup( wxCommandEvent& event ){ OnStoreSetup( event ); }
+ void _wxFB_OnGetSetup( wxCommandEvent& event ){ OnGetSetup( event ); }
+ void _wxFB_OnResetClick( wxCommandEvent& event ){ OnResetClick( event ); }
+ void _wxFB_OnCancelClick( wxCommandEvent& event ){ OnCancelClick( event ); }
+ void _wxFB_OnOkClick( wxCommandEvent& event ){ OnOkClick( event ); }
+
+
+ protected:
+ enum
+ {
+ ID_LAYERS_MAP_DIALOG_BASE = 1000,
+ ID_M_STATICLINESEP,
+ ID_M_STATICTEXTCOPPERLAYERCOUNT,
+ ID_M_COMBOCOPPERLAYERSCOUNT,
+ ID_STORE_CHOICE,
+ ID_GET_PREVIOUS_CHOICE,
+ ID_RESET_CHOICE
+ };
+
+ wxStaticBoxSizer* sbSizerLayersTable;
+ wxFlexGridSizer* m_flexLeftColumnBoxSizer;
+ wxStaticLine* m_staticlineSep;
+ wxStaticText* m_staticTextCopperlayerCount;
+ wxComboBox* m_comboCopperLayersCount;
+ wxButton* m_buttonStore;
+ wxButton* m_buttonRetrieve;
+ wxButton* m_buttonReset;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizerButtons;
+ wxButton* m_sdbSizerButtonsOK;
+ wxButton* m_sdbSizerButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnBrdLayersCountSelection( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnStoreSetup( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnGetSetup( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnResetClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ LAYERS_MAP_DIALOG_BASE( wxWindow* parent, wxWindowID id = ID_LAYERS_MAP_DIALOG_BASE, const wxString& title = _("Layer selection:"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 400,286 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~LAYERS_MAP_DIALOG_BASE();
+
+};
+
+#endif //__DIALOG_LAYERS_SELECT_TO_PCB_BASE_H__
diff --git a/gerbview/dialogs/dialog_print_using_printer.cpp b/gerbview/dialogs/dialog_print_using_printer.cpp
new file mode 100644
index 0000000..9141f3f
--- /dev/null
+++ b/gerbview/dialogs/dialog_print_using_printer.cpp
@@ -0,0 +1,404 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+// Set this to 1 if you want to test PostScript printing under MSW.
+#define wxTEST_POSTSCRIPT_IN_MSW 1
+
+#include <fctsys.h>
+
+#include <kiface_i.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+
+#include <dialog_print_using_printer_base.h>
+#include <printout_controler.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <class_GERBER.h>
+#include <pcbplot.h>
+
+static double s_ScaleList[] =
+{ 0, 0.5, 0.7, 0.999, 1.0, 1.4, 2.0, 3.0, 4.0 };
+
+// Define min et max reasonnable values for print scale
+#define MIN_SCALE 0.01
+#define MAX_SCALE 100.0
+
+// static print data and page setup data, to remember settings during the session
+static wxPrintData* s_printData;
+static wxPageSetupDialogData* s_pageSetupData = (wxPageSetupDialogData*) NULL;
+
+// Variables locales
+static PRINT_PARAMETERS s_Parameters;
+
+
+/* Dialog to print schematic. Class derived from DIALOG_PRINT_USING_PRINTER_BASE
+ * created by wxFormBuilder
+ */
+class DIALOG_PRINT_USING_PRINTER : public DIALOG_PRINT_USING_PRINTER_BASE
+{
+private:
+ GERBVIEW_FRAME* m_Parent;
+ wxConfigBase* m_Config;
+ wxCheckBox* m_BoxSelectLayer[32];
+
+public:
+ DIALOG_PRINT_USING_PRINTER( GERBVIEW_FRAME* parent );
+ ~DIALOG_PRINT_USING_PRINTER() {};
+
+private:
+ void OnCloseWindow( wxCloseEvent& event );
+ void OnInitDialog( wxInitDialogEvent& event );
+ void OnPageSetup( wxCommandEvent& event );
+ void OnPrintPreview( wxCommandEvent& event );
+ void OnPrintButtonClick( wxCommandEvent& event );
+ void OnScaleSelectionClick( wxCommandEvent& event );
+
+ void OnButtonCancelClick( wxCommandEvent& event ) { Close(); }
+ void SetPrintParameters();
+ void InitValues();
+
+public:
+ bool IsMirrored() { return m_Print_Mirror->IsChecked(); }
+ bool PrintUsingSinglePage() { return true; }
+ int SetLayerSetFromListSelection();
+ // Prepare print parameters. return true if OK,
+ // false if there is an issue (mainly no printable layers)
+ bool PreparePrintPrms();
+};
+
+
+/*******************************************************/
+void GERBVIEW_FRAME::ToPrinter( wxCommandEvent& event )
+/*******************************************************/
+
+/* Virtual function:
+ * Display the print dialog
+ */
+{
+ if( s_printData == NULL ) // First print
+ s_printData = new wxPrintData();
+
+ if( !s_printData->Ok() )
+ {
+ DisplayError( this, _( "Error Init Printer info" ) );
+ return;
+ }
+
+ s_printData->SetQuality( wxPRINT_QUALITY_HIGH );
+ s_printData->SetOrientation( GetPageSettings().IsPortrait() ?
+ wxPORTRAIT : wxLANDSCAPE );
+
+ DIALOG_PRINT_USING_PRINTER* frame = new DIALOG_PRINT_USING_PRINTER( this );
+
+ frame->ShowModal();
+ frame->Destroy();
+}
+
+
+/*************************************************************************************/
+DIALOG_PRINT_USING_PRINTER::DIALOG_PRINT_USING_PRINTER( GERBVIEW_FRAME* parent ) :
+ DIALOG_PRINT_USING_PRINTER_BASE( parent )
+/*************************************************************************************/
+{
+ m_Parent = parent;
+ m_Config = Kiface().KifaceSettings();
+
+ InitValues( );
+ GetSizer()->SetSizeHints( this );
+
+#ifdef __WXMAC__
+ /* Problems with modal on wx-2.9 - Anyway preview is standard for OSX */
+ m_buttonPreview->Hide();
+#endif
+
+ GetSizer()->Fit( this );
+}
+
+
+/************************************************************************/
+void DIALOG_PRINT_USING_PRINTER::InitValues( )
+/************************************************************************/
+{
+ SetFocus();
+ wxString msg;
+
+ if( s_pageSetupData == NULL )
+ {
+ s_pageSetupData = new wxPageSetupDialogData;
+ // Set initial page margins.
+ // Margins are already set in Gerbview, so we can use 0
+ s_pageSetupData->SetMarginTopLeft( wxPoint( 0, 0 ) );
+ s_pageSetupData->SetMarginBottomRight( wxPoint( 0, 0 ) );
+ }
+
+ s_Parameters.m_PageSetupData = s_pageSetupData;
+
+ // Create layer list
+ for( int ii = 0; ii < GERBER_DRAWLAYERS_COUNT; ++ii )
+ {
+ msg = _( "Layer" );
+ msg << wxT( " " ) << ii + 1;
+
+ wxStaticBoxSizer* boxSizer = ( ii < 16 ) ? m_leftLayersBoxSizer
+ : m_rightLayersBoxSizer;
+
+ m_BoxSelectLayer[ii] = new wxCheckBox( boxSizer->GetStaticBox(),
+ wxID_ANY, msg );
+ boxSizer->Add( m_BoxSelectLayer[ii], wxGROW | wxLEFT | wxRIGHT | wxTOP );
+
+ if( g_GERBER_List.GetGbrImage( ii ) == NULL )
+ // Nothing loaded on this draw layer
+ m_BoxSelectLayer[ii]->Enable( false );
+ }
+
+ // Read the scale adjust option
+ int scale_idx = 4; // default selected scale = ScaleList[4] = 1.000
+
+ if( m_Config )
+ {
+ m_Config->Read( OPTKEY_PRINT_X_FINESCALE_ADJ, &s_Parameters.m_XScaleAdjust );
+ m_Config->Read( OPTKEY_PRINT_Y_FINESCALE_ADJ, &s_Parameters.m_YScaleAdjust );
+ m_Config->Read( OPTKEY_PRINT_SCALE, &scale_idx );
+ m_Config->Read( OPTKEY_PRINT_PAGE_FRAME, &s_Parameters.m_Print_Sheet_Ref, 1 );
+ m_Config->Read( OPTKEY_PRINT_MONOCHROME_MODE, &s_Parameters.m_Print_Black_and_White, 1 );
+
+ // Test for a reasonnable scale value. Set to 1 if problem
+ if( s_Parameters.m_XScaleAdjust < MIN_SCALE ||
+ s_Parameters.m_YScaleAdjust < MIN_SCALE ||
+ s_Parameters.m_XScaleAdjust > MAX_SCALE ||
+ s_Parameters.m_YScaleAdjust > MAX_SCALE )
+ s_Parameters.m_XScaleAdjust = s_Parameters.m_YScaleAdjust = 1.0;
+
+ for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
+ {
+ wxString layerKey;
+ bool option;
+
+ layerKey.Printf( OPTKEY_LAYERBASE, layer );
+ m_Config->Read( layerKey, &option, false );
+ m_BoxSelectLayer[layer]->SetValue( option );
+ }
+ }
+
+ m_ScaleOption->SetSelection( scale_idx );
+ scale_idx = m_ScaleOption->GetSelection();
+ s_Parameters.m_PrintScale = s_ScaleList[scale_idx];
+ m_Print_Mirror->SetValue( s_Parameters.m_PrintMirror );
+
+
+ if( s_Parameters.m_Print_Black_and_White )
+ m_ModeColorOption->SetSelection( 1 );
+ else
+ m_ModeColorOption->SetSelection( 0 );
+
+ s_Parameters.m_PenDefaultSize = 0;
+
+ // Create scale adjust option
+ msg.Printf( wxT( "%f" ), s_Parameters.m_XScaleAdjust );
+ m_FineAdjustXscaleOpt->SetValue( msg );
+ msg.Printf( wxT( "%f" ), s_Parameters.m_YScaleAdjust );
+ m_FineAdjustYscaleOpt->SetValue( msg );
+
+ bool enable = (s_Parameters.m_PrintScale == 1.0);
+
+ m_FineAdjustXscaleOpt->Enable(enable);
+ m_FineAdjustYscaleOpt->Enable(enable);
+}
+
+
+int DIALOG_PRINT_USING_PRINTER::SetLayerSetFromListSelection()
+{
+ int page_count = 0;
+ std::bitset <GERBER_DRAWLAYERS_COUNT> layerMask;
+ for( int ii = 0; ii < GERBER_DRAWLAYERS_COUNT; ++ii )
+ {
+ if( m_BoxSelectLayer[ii]->IsChecked() && m_BoxSelectLayer[ii]->IsEnabled() )
+ {
+ page_count++;
+ layerMask[ii] = true;
+ }
+ else
+ layerMask[ii] = false;
+ }
+
+ m_Parent->GetGerberLayout()->SetPrintableLayers( layerMask );
+ s_Parameters.m_PageCount = page_count;
+
+ return page_count;
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::OnCloseWindow( wxCloseEvent& event )
+{
+ SetPrintParameters();
+
+ if( m_Config )
+ {
+ m_Config->Write( OPTKEY_PRINT_X_FINESCALE_ADJ, s_Parameters.m_XScaleAdjust );
+ m_Config->Write( OPTKEY_PRINT_Y_FINESCALE_ADJ, s_Parameters.m_YScaleAdjust );
+ m_Config->Write( OPTKEY_PRINT_SCALE, m_ScaleOption->GetSelection() );
+ m_Config->Write( OPTKEY_PRINT_PAGE_FRAME, s_Parameters.m_Print_Sheet_Ref);
+ m_Config->Write( OPTKEY_PRINT_MONOCHROME_MODE, s_Parameters.m_Print_Black_and_White);
+ wxString layerKey;
+ for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
+ {
+ layerKey.Printf( OPTKEY_LAYERBASE, layer );
+ m_Config->Write( layerKey, m_BoxSelectLayer[layer]->IsChecked() );
+ }
+ }
+
+ EndModal( 0 );
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::SetPrintParameters()
+{
+ s_Parameters.m_PrintMirror = m_Print_Mirror->GetValue();
+ s_Parameters.m_Print_Black_and_White =
+ m_ModeColorOption->GetSelection() != 0;
+
+ // Due to negative objects in gerber objects, always use one page per image,
+ // because these objects create artefact when they are printed on an existing image.
+ s_Parameters.m_OptionPrintPage = false;
+
+ SetLayerSetFromListSelection();
+
+ int idx = m_ScaleOption->GetSelection();
+ s_Parameters.m_PrintScale = s_ScaleList[idx];
+
+ if( m_FineAdjustXscaleOpt )
+ {
+ if( s_Parameters.m_XScaleAdjust > MAX_SCALE ||
+ s_Parameters.m_YScaleAdjust > MAX_SCALE )
+ DisplayInfoMessage( NULL, _( "Warning: Scale option set to a very large value" ) );
+ m_FineAdjustXscaleOpt->GetValue().ToDouble( &s_Parameters.m_XScaleAdjust );
+ }
+ if( m_FineAdjustYscaleOpt )
+ {
+ // Test for a reasonnable scale value
+ if( s_Parameters.m_XScaleAdjust < MIN_SCALE ||
+ s_Parameters.m_YScaleAdjust < MIN_SCALE )
+ DisplayInfoMessage( NULL, _( "Warning: Scale option set to a very small value" ) );
+ m_FineAdjustYscaleOpt->GetValue().ToDouble( &s_Parameters.m_YScaleAdjust );
+ }
+}
+
+void DIALOG_PRINT_USING_PRINTER::OnScaleSelectionClick( wxCommandEvent& event )
+{
+ double scale = s_ScaleList[m_ScaleOption->GetSelection()];
+ bool enable = (scale == 1.0);
+ if( m_FineAdjustXscaleOpt )
+ m_FineAdjustXscaleOpt->Enable(enable);
+ if( m_FineAdjustYscaleOpt )
+ m_FineAdjustYscaleOpt->Enable(enable);
+}
+
+// Open a dialog box for printer setup (printer options, page size ...)
+void DIALOG_PRINT_USING_PRINTER::OnPageSetup( wxCommandEvent& event )
+{
+ *s_pageSetupData = *s_printData;
+
+ wxPageSetupDialog pageSetupDialog(this, s_pageSetupData);
+ pageSetupDialog.ShowModal();
+
+ (*s_printData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
+ (*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
+}
+
+bool DIALOG_PRINT_USING_PRINTER::PreparePrintPrms()
+{
+ SetPrintParameters();
+
+ // If no layer selected, we have no plot. prompt user if it happens
+ // because he could think there is a bug in Pcbnew:
+ if( m_Parent->GetGerberLayout()->GetPrintableLayers().none() )
+ {
+ DisplayError( this, _( "No layer selected" ) );
+ return false;
+ }
+
+ return true;
+}
+
+// Open and display a previewer frame for printing
+void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event )
+{
+ if( !PreparePrintPrms() )
+ return;
+
+ // Pass two printout objects: for preview, and possible printing.
+ wxString title = _( "Print Preview" );
+ wxPrintPreview* preview =
+ new wxPrintPreview( new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_Parent, title ),
+ new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_Parent, title ),
+ s_printData );
+
+ if( preview == NULL )
+ {
+ DisplayError( this, wxT( "OnPrintPreview() problem" ) );
+ return;
+ }
+
+
+ // Uses the parent position and size.
+ // @todo uses last position and size ans store them when exit in m_Config
+ wxPoint WPos = m_Parent->GetPosition();
+ wxSize WSize = m_Parent->GetSize();
+
+ wxPreviewFrame* frame = new wxPreviewFrame( preview, this, title, WPos, WSize );
+ frame->SetMinSize( wxSize( 550, 350 ) );
+
+ frame->Initialize();
+
+ frame->Raise(); // Needed on Ubuntu/Unity to display the frame
+ frame->Show( true );
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event )
+{
+ if( !PreparePrintPrms() )
+ return;
+
+ wxPrintDialogData printDialogData( *s_printData );
+
+ wxPrinter printer( &printDialogData );
+ wxString title = _( "Print" );
+ BOARD_PRINTOUT_CONTROLLER printout( s_Parameters, m_Parent, title );
+
+ if( !printer.Print( this, &printout, true ) )
+ {
+ if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
+ DisplayError( this, _( "There was a problem printing" ) );
+ return;
+ }
+ else
+ {
+ *s_printData = printer.GetPrintDialogData().GetPrintData();
+ }
+}
+
diff --git a/gerbview/dialogs/dialog_print_using_printer_base.cpp b/gerbview/dialogs/dialog_print_using_printer_base.cpp
new file mode 100644
index 0000000..1202588
--- /dev/null
+++ b/gerbview/dialogs/dialog_print_using_printer_base.cpp
@@ -0,0 +1,138 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_print_using_printer_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_PRINT_USING_PRINTER_BASE::DIALOG_PRINT_USING_PRINTER_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sbLayersSizer;
+ sbLayersSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Layers:") ), wxVERTICAL );
+
+ wxBoxSizer* bleftSizer;
+ bleftSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ m_leftLayersBoxSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Layers:") ), wxVERTICAL );
+
+
+ bleftSizer->Add( m_leftLayersBoxSizer, 1, wxALL, 5 );
+
+ m_rightLayersBoxSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Layers:") ), wxVERTICAL );
+
+
+ bleftSizer->Add( m_rightLayersBoxSizer, 1, wxALL, 5 );
+
+
+ sbLayersSizer->Add( bleftSizer, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( sbLayersSizer, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bmiddleLeftSizer;
+ bmiddleLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_ScaleOptionChoices[] = { _("fit in page"), _("Scale 0.5"), _("Scale 0.7"), _("Approx. Scale 1"), _("Accurate Scale 1"), _("Scale 1.4"), _("Scale 2"), _("Scale 3"), _("Scale 4") };
+ int m_ScaleOptionNChoices = sizeof( m_ScaleOptionChoices ) / sizeof( wxString );
+ m_ScaleOption = new wxRadioBox( this, wxID_ANY, _("Approx. Scale:"), wxDefaultPosition, wxDefaultSize, m_ScaleOptionNChoices, m_ScaleOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_ScaleOption->SetSelection( 3 );
+ bmiddleLeftSizer->Add( m_ScaleOption, 0, wxALL, 5 );
+
+ m_FineAdjustXscaleTitle = new wxStaticText( this, wxID_ANY, _("X Scale Adjust"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_FineAdjustXscaleTitle->Wrap( -1 );
+ bmiddleLeftSizer->Add( m_FineAdjustXscaleTitle, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_FineAdjustXscaleOpt = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_FineAdjustXscaleOpt->SetMaxLength( 0 );
+ m_FineAdjustXscaleOpt->SetToolTip( _("Set X scale adjust for exact scale plotting") );
+
+ bmiddleLeftSizer->Add( m_FineAdjustXscaleOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_FineAdjustYscaleTitle = new wxStaticText( this, wxID_ANY, _("Y Scale Adjust"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_FineAdjustYscaleTitle->Wrap( -1 );
+ bmiddleLeftSizer->Add( m_FineAdjustYscaleTitle, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_FineAdjustYscaleOpt = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_FineAdjustYscaleOpt->SetMaxLength( 0 );
+ m_FineAdjustYscaleOpt->SetToolTip( _("Set Y scale adjust for exact scale plotting") );
+
+ bmiddleLeftSizer->Add( m_FineAdjustYscaleOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bmiddleLeftSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bmiddleRightSizer;
+ bmiddleRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbOptionsSizer;
+ sbOptionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options:") ), wxVERTICAL );
+
+ m_Print_Mirror = new wxCheckBox( this, wxID_ANY, _("Mirror"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbOptionsSizer->Add( m_Print_Mirror, 0, wxALL, 5 );
+
+
+ bmiddleRightSizer->Add( sbOptionsSizer, 0, wxEXPAND|wxALL, 5 );
+
+ wxString m_ModeColorOptionChoices[] = { _("Color"), _("Black and white") };
+ int m_ModeColorOptionNChoices = sizeof( m_ModeColorOptionChoices ) / sizeof( wxString );
+ m_ModeColorOption = new wxRadioBox( this, wxID_PRINT_MODE, _("Print Mode"), wxDefaultPosition, wxDefaultSize, m_ModeColorOptionNChoices, m_ModeColorOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_ModeColorOption->SetSelection( 0 );
+ m_ModeColorOption->SetToolTip( _("Choose if you want to print sheets in color, or force the black and white mode.") );
+
+ bmiddleRightSizer->Add( m_ModeColorOption, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bmiddleRightSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* b_buttonsSizer;
+ b_buttonsSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonOption = new wxButton( this, wxID_PRINT_OPTIONS, _("Page Options"), wxDefaultPosition, wxDefaultSize, 0 );
+ b_buttonsSizer->Add( m_buttonOption, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonPreview = new wxButton( this, wxID_PREVIEW, _("Preview"), wxDefaultPosition, wxDefaultSize, 0 );
+ b_buttonsSizer->Add( m_buttonPreview, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonPrint = new wxButton( this, wxID_PRINT_ALL, _("Print"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonPrint->SetDefault();
+ b_buttonsSizer->Add( m_buttonPrint, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonQuit = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ b_buttonsSizer->Add( m_buttonQuit, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( b_buttonsSizer, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnCloseWindow ) );
+ m_ScaleOption->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnScaleSelectionClick ), NULL, this );
+ m_buttonOption->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPageSetup ), NULL, this );
+ m_buttonPreview->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPrintPreview ), NULL, this );
+ m_buttonPrint->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPrintButtonClick ), NULL, this );
+ m_buttonQuit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnButtonCancelClick ), NULL, this );
+}
+
+DIALOG_PRINT_USING_PRINTER_BASE::~DIALOG_PRINT_USING_PRINTER_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnCloseWindow ) );
+ m_ScaleOption->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnScaleSelectionClick ), NULL, this );
+ m_buttonOption->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPageSetup ), NULL, this );
+ m_buttonPreview->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPrintPreview ), NULL, this );
+ m_buttonPrint->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPrintButtonClick ), NULL, this );
+ m_buttonQuit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnButtonCancelClick ), NULL, this );
+
+}
diff --git a/gerbview/dialogs/dialog_print_using_printer_base.fbp b/gerbview/dialogs/dialog_print_using_printer_base.fbp
new file mode 100644
index 0000000..184cdb8
--- /dev/null
+++ b/gerbview/dialogs/dialog_print_using_printer_base.fbp
@@ -0,0 +1,1167 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_print_using_printer_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DialogPrint_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_PRINT_USING_PRINTER_BASE</property>
+ <property name="pos"></property>
+ <property name="size">551,314</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Print</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseWindow</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layers:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbLayersSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bleftSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layers:</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_leftLayersBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layers:</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_rightLayersBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmiddleLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;fit in page&quot; &quot;Scale 0.5&quot; &quot;Scale 0.7&quot; &quot;Approx. Scale 1&quot; &quot;Accurate Scale 1&quot; &quot;Scale 1.4&quot; &quot;Scale 2&quot; &quot;Scale 3&quot; &quot;Scale 4&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Approx. Scale:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ScaleOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">3</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox">OnScaleSelectionClick</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">X Scale Adjust</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FineAdjustXscaleTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FineAdjustXscaleOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Set X scale adjust for exact scale plotting</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Y Scale Adjust</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FineAdjustYscaleTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FineAdjustYscaleOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Set Y scale adjust for exact scale plotting</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmiddleRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Options:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbOptionsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Mirror</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Print_Mirror</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Color&quot; &quot;Black and white&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PRINT_MODE</property>
+ <property name="label">Print Mode</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ModeColorOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Choose if you want to print sheets in color, or force the black and white mode.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">b_buttonsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PRINT_OPTIONS</property>
+ <property name="label">Page Options</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnPageSetup</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PREVIEW</property>
+ <property name="label">Preview</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPreview</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnPrintPreview</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PRINT_ALL</property>
+ <property name="label">Print</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPrint</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnPrintButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonQuit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/gerbview/dialogs/dialog_print_using_printer_base.h b/gerbview/dialogs/dialog_print_using_printer_base.h
new file mode 100644
index 0000000..f99650c
--- /dev/null
+++ b/gerbview/dialogs/dialog_print_using_printer_base.h
@@ -0,0 +1,78 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_PRINT_USING_PRINTER_BASE_H__
+#define __DIALOG_PRINT_USING_PRINTER_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/gdicmn.h>
+#include <wx/radiobox.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/checkbox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PRINT_USING_PRINTER_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PRINT_USING_PRINTER_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ wxID_PRINT_MODE = 1000,
+ wxID_PRINT_OPTIONS,
+ wxID_PRINT_ALL
+ };
+
+ wxStaticBoxSizer* m_leftLayersBoxSizer;
+ wxStaticBoxSizer* m_rightLayersBoxSizer;
+ wxRadioBox* m_ScaleOption;
+ wxStaticText* m_FineAdjustXscaleTitle;
+ wxTextCtrl* m_FineAdjustXscaleOpt;
+ wxStaticText* m_FineAdjustYscaleTitle;
+ wxTextCtrl* m_FineAdjustYscaleOpt;
+ wxCheckBox* m_Print_Mirror;
+ wxRadioBox* m_ModeColorOption;
+ wxButton* m_buttonOption;
+ wxButton* m_buttonPreview;
+ wxButton* m_buttonPrint;
+ wxButton* m_buttonQuit;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnScaleSelectionClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPageSetup( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPrintPreview( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPrintButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonCancelClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PRINT_USING_PRINTER_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Print"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 551,314 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_PRINT_USING_PRINTER_BASE();
+
+};
+
+#endif //__DIALOG_PRINT_USING_PRINTER_BASE_H__
diff --git a/gerbview/dialogs/dialog_select_one_pcb_layer.cpp b/gerbview/dialogs/dialog_select_one_pcb_layer.cpp
new file mode 100644
index 0000000..1a847ce
--- /dev/null
+++ b/gerbview/dialogs/dialog_select_one_pcb_layer.cpp
@@ -0,0 +1,277 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_select_one_pcb_layer.cpp
+ * @brief Set up a dialog to choose a PCB Layer.
+ */
+
+#include <fctsys.h>
+#include <gerbview_frame.h>
+#include <select_layers_to_pcb.h>
+
+#define NB_PCB_LAYERS LAYER_ID_COUNT
+#define FIRST_COPPER_LAYER 0
+#define LAST_COPPER_LAYER 31
+
+// Exported function
+const wxString GetPCBDefaultLayerName( int aLayerId );
+
+
+enum layer_sel_id {
+ ID_LAYER_SELECT_TOP = 1800,
+ ID_LAYER_SELECT_BOTTOM,
+ ID_LAYER_SELECT
+};
+
+
+class SELECT_LAYER_DIALOG : public wxDialog
+{
+private:
+ wxRadioBox* m_layerList;
+ std::vector <int> m_layerId;
+
+public:
+ // Constructor and destructor
+ SELECT_LAYER_DIALOG( GERBVIEW_FRAME* parent, int aDefaultLayer,
+ int aCopperLayerCount, bool aShowDeselectOption );
+ ~SELECT_LAYER_DIALOG() { };
+
+private:
+ void OnLayerSelected( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+
+ DECLARE_EVENT_TABLE()
+};
+
+
+BEGIN_EVENT_TABLE( SELECT_LAYER_DIALOG, wxDialog )
+ EVT_BUTTON( wxID_OK, SELECT_LAYER_DIALOG::OnLayerSelected )
+ EVT_BUTTON( wxID_CANCEL, SELECT_LAYER_DIALOG::OnCancelClick )
+ EVT_RADIOBOX( ID_LAYER_SELECT, SELECT_LAYER_DIALOG::OnLayerSelected )
+END_EVENT_TABLE()
+
+
+/** Install the dialog box for layer selection
+ * @param aDefaultLayer = Preselection (GERBER_DRAWLAYERS_COUNT for "(Deselect)" layer)
+ * @param aCopperLayerCount = number of copper layers
+ * @param aShowDeselectOption = display a "(Deselect)" radiobutton (when set to true)
+ * @return new layer value (GERBER_DRAWLAYERS_COUNT when "(Deselect)" radiobutton selected),
+ * or -1 if canceled
+ *
+ * Providing the option to also display a "(Deselect)" radiobutton makes the
+ * GerbView's "Export to Pcbnew" command) more "user friendly",
+ * by permitting any layer to be "deselected" immediately after its
+ * corresponding radiobutton has been clicked on. (It would otherwise be
+ * necessary to first cancel the "Select Layer:" dialog box (invoked after a
+ * different radiobutton is clicked on) prior to then clicking on the "Deselect"
+ * button provided within the "Layer selection:" dialog box).
+ */
+int GERBVIEW_FRAME::SelectPCBLayer( int aDefaultLayer, int aCopperLayerCount,
+ bool aShowDeselectOption )
+{
+ SELECT_LAYER_DIALOG* frame = new SELECT_LAYER_DIALOG( this, aDefaultLayer,
+ aCopperLayerCount,
+ aShowDeselectOption );
+
+ int layer = frame->ShowModal();
+ frame->Destroy();
+ return layer;
+}
+
+
+/*
+ * The "OK" and "Cancel" buttons are positioned (in a horizontal line)
+ * beneath the "Layer" radiobox, unless that contains only one column of
+ * radiobuttons, in which case they are positioned (in a vertical line)
+ * to the right of that radiobox.
+ */
+SELECT_LAYER_DIALOG::SELECT_LAYER_DIALOG( GERBVIEW_FRAME* parent,
+ int aDefaultLayer, int aCopperLayerCount,
+ bool aShowDeselectOption ) :
+ wxDialog( parent, -1, _( "Select Layer:" ), wxPoint( -1, -1 ),
+ wxSize( 470, 250 ),
+ wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )
+{
+ wxButton* button;
+ int ii;
+ wxArrayString layerList;
+ int layerSelect = -1;
+
+ // Build the layer list; first build copper layers list
+ int layerCount = 0;
+
+ for( ii = FIRST_COPPER_LAYER; ii <= LAST_COPPER_LAYER; ++ii )
+ {
+ if( ii == FIRST_COPPER_LAYER || ii == LAST_COPPER_LAYER || ii < aCopperLayerCount-1 )
+ {
+ layerList.Add( GetPCBDefaultLayerName( ii ) );
+
+ if( ii == aDefaultLayer )
+ layerSelect = layerCount;
+
+ m_layerId.push_back( ii );
+ layerCount++;
+ }
+ }
+
+ // Build the layer list; build non copper layers list
+ for( ; ii < NB_PCB_LAYERS; ++ii )
+ {
+ layerList.Add( GetPCBDefaultLayerName( ii ) );
+
+ if( ii == aDefaultLayer )
+ layerSelect = layerCount;
+
+ m_layerId.push_back( ii );
+ layerCount++;
+ }
+
+ // When appropriate, also provide a "(Deselect)" radiobutton
+ if( aShowDeselectOption )
+ {
+ layerList.Add( _( "Do not export" ) );
+
+ if( UNSELECTED_LAYER == aDefaultLayer )
+ layerSelect = layerCount;
+
+ m_layerId.push_back( UNSELECTED_LAYER );
+ layerCount++;
+ }
+
+ m_layerList = new wxRadioBox( this, ID_LAYER_SELECT, _( "Layer" ),
+ wxPoint( -1, -1 ), wxSize( -1, -1 ),
+ layerList,
+ (layerCount < 8) ? layerCount : 8,
+ wxRA_SPECIFY_ROWS );
+
+ if( layerSelect >= 0 )
+ m_layerList->SetSelection( layerSelect );
+
+ wxBoxSizer* FrameBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+ SetSizer( FrameBoxSizer );
+ FrameBoxSizer->Add( m_layerList, 0, wxALIGN_TOP | wxALL, 5 );
+ wxBoxSizer* ButtonBoxSizer = new wxBoxSizer( wxVERTICAL );
+ FrameBoxSizer->Add( ButtonBoxSizer, 0, wxALIGN_BOTTOM | wxALL, 0 );
+
+ button = new wxButton( this, wxID_OK, _( "OK" ) );
+ button->SetDefault();
+ ButtonBoxSizer->Add( button, 0, wxGROW | wxALL, 5 );
+
+ button = new wxButton( this, wxID_CANCEL, _( "Cancel" ) );
+ ButtonBoxSizer->Add( button, 0, wxGROW | wxALL, 5 );
+
+ GetSizer()->SetSizeHints( this );
+
+ Center();
+}
+
+
+void SELECT_LAYER_DIALOG::OnLayerSelected( wxCommandEvent& event )
+{
+ int ii = m_layerId[m_layerList->GetSelection()];
+
+ EndModal( ii );
+}
+
+
+void SELECT_LAYER_DIALOG::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( -1 );
+}
+
+// This function is a duplicate of
+// const wxChar* LSET::Name( LAYER_ID aLayerId )
+// However it avoids a dependency to Pcbnew code.
+const wxString GetPCBDefaultLayerName( int aLayerId )
+{
+ const wxChar* txt;
+
+ // using a switch to explicitly show the mapping more clearly
+ switch( aLayerId )
+ {
+ case F_Cu: txt = wxT( "F.Cu" ); break;
+ case In1_Cu: txt = wxT( "In1.Cu" ); break;
+ case In2_Cu: txt = wxT( "In2.Cu" ); break;
+ case In3_Cu: txt = wxT( "In3.Cu" ); break;
+ case In4_Cu: txt = wxT( "In4.Cu" ); break;
+ case In5_Cu: txt = wxT( "In5.Cu" ); break;
+ case In6_Cu: txt = wxT( "In6.Cu" ); break;
+ case In7_Cu: txt = wxT( "In7.Cu" ); break;
+ case In8_Cu: txt = wxT( "In8.Cu" ); break;
+ case In9_Cu: txt = wxT( "In9.Cu" ); break;
+ case In10_Cu: txt = wxT( "In10.Cu" ); break;
+ case In11_Cu: txt = wxT( "In11.Cu" ); break;
+ case In12_Cu: txt = wxT( "In12.Cu" ); break;
+ case In13_Cu: txt = wxT( "In13.Cu" ); break;
+ case In14_Cu: txt = wxT( "In14.Cu" ); break;
+ case In15_Cu: txt = wxT( "In15.Cu" ); break;
+ case In16_Cu: txt = wxT( "In16.Cu" ); break;
+ case In17_Cu: txt = wxT( "In17.Cu" ); break;
+ case In18_Cu: txt = wxT( "In18.Cu" ); break;
+ case In19_Cu: txt = wxT( "In19.Cu" ); break;
+ case In20_Cu: txt = wxT( "In20.Cu" ); break;
+ case In21_Cu: txt = wxT( "In21.Cu" ); break;
+ case In22_Cu: txt = wxT( "In22.Cu" ); break;
+ case In23_Cu: txt = wxT( "In23.Cu" ); break;
+ case In24_Cu: txt = wxT( "In24.Cu" ); break;
+ case In25_Cu: txt = wxT( "In25.Cu" ); break;
+ case In26_Cu: txt = wxT( "In26.Cu" ); break;
+ case In27_Cu: txt = wxT( "In27.Cu" ); break;
+ case In28_Cu: txt = wxT( "In28.Cu" ); break;
+ case In29_Cu: txt = wxT( "In29.Cu" ); break;
+ case In30_Cu: txt = wxT( "In30.Cu" ); break;
+ case B_Cu: txt = wxT( "B.Cu" ); break;
+
+ // Technicals
+ case B_Adhes: txt = wxT( "B.Adhes" ); break;
+ case F_Adhes: txt = wxT( "F.Adhes" ); break;
+ case B_Paste: txt = wxT( "B.Paste" ); break;
+ case F_Paste: txt = wxT( "F.Paste" ); break;
+ case B_SilkS: txt = wxT( "B.SilkS" ); break;
+ case F_SilkS: txt = wxT( "F.SilkS" ); break;
+ case B_Mask: txt = wxT( "B.Mask" ); break;
+ case F_Mask: txt = wxT( "F.Mask" ); break;
+
+ // Users
+ case Dwgs_User: txt = wxT( "Dwgs.User" ); break;
+ case Cmts_User: txt = wxT( "Cmts.User" ); break;
+ case Eco1_User: txt = wxT( "Eco1.User" ); break;
+ case Eco2_User: txt = wxT( "Eco2.User" ); break;
+ case Edge_Cuts: txt = wxT( "Edge.Cuts" ); break;
+ case Margin: txt = wxT( "Margin" ); break;
+
+ // Footprint
+ case F_CrtYd: txt = wxT( "F.CrtYd" ); break;
+ case B_CrtYd: txt = wxT( "B.CrtYd" ); break;
+ case F_Fab: txt = wxT( "F.Fab" ); break;
+ case B_Fab: txt = wxT( "B.Fab" ); break;
+
+ default:
+ wxASSERT_MSG( 0, wxT( "aLayerId out of range" ) );
+ txt = wxT( "BAD INDEX!" ); break;
+ }
+
+ return wxString( txt );
+}
diff --git a/gerbview/dialogs/dialog_show_page_borders.cpp b/gerbview/dialogs/dialog_show_page_borders.cpp
new file mode 100644
index 0000000..7c2dcfd
--- /dev/null
+++ b/gerbview/dialogs/dialog_show_page_borders.cpp
@@ -0,0 +1,84 @@
+/**
+ * @file dialog_show_page_borders.cpp
+ * Dialog to show/hide frame reference and select paper size for printing
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011 jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <macros.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <dialog_show_page_borders.h>
+
+
+DIALOG_PAGE_SHOW_PAGE_BORDERS::DIALOG_PAGE_SHOW_PAGE_BORDERS( GERBVIEW_FRAME *parent) :
+ DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE( parent, wxID_ANY )
+{
+ m_Parent = parent;
+ SetFocus();
+
+ m_ShowPageLimits->SetSelection(0);
+
+ if( m_Parent->GetShowBorderAndTitleBlock() )
+ {
+ wxString curPaperType = m_Parent->GetPageSettings().GetType();
+
+ for( unsigned i = 1; i<DIM( g_GerberPageSizeList ); ++i )
+ {
+ if( curPaperType == g_GerberPageSizeList[i] )
+ {
+ m_ShowPageLimits->SetSelection( i );
+ break;
+ }
+ }
+ }
+
+ GetSizer()->Fit( this );
+ GetSizer()->SetSizeHints( this );
+ Center();
+ m_sdbSizer1OK->SetDefault();
+}
+
+
+void DIALOG_PAGE_SHOW_PAGE_BORDERS::OnCancelButtonClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+void DIALOG_PAGE_SHOW_PAGE_BORDERS::OnOKBUttonClick( wxCommandEvent& event )
+{
+ int idx = m_ShowPageLimits->GetSelection();
+
+ m_Parent->SetShowBorderAndTitleBlock( idx > 0 ? true : false );
+
+ m_Parent->SetPageSettings( PAGE_INFO( g_GerberPageSizeList[idx] ) );
+
+ EndModal( wxID_OK );
+}
+
diff --git a/gerbview/dialogs/dialog_show_page_borders.h b/gerbview/dialogs/dialog_show_page_borders.h
new file mode 100644
index 0000000..1c86686
--- /dev/null
+++ b/gerbview/dialogs/dialog_show_page_borders.h
@@ -0,0 +1,47 @@
+/**
+ * @file dialog_show_page_borders.h
+ * Dialog to show/hide frame reference and select paper size for printing
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011 jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <dialog_show_page_borders_base.h>
+
+
+class DIALOG_PAGE_SHOW_PAGE_BORDERS : public DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE
+{
+private:
+ GERBVIEW_FRAME* m_Parent;
+
+public:
+
+ DIALOG_PAGE_SHOW_PAGE_BORDERS( GERBVIEW_FRAME* parent );
+ ~DIALOG_PAGE_SHOW_PAGE_BORDERS() {};
+
+private:
+ void OnOKBUttonClick( wxCommandEvent& event );
+ void OnCancelButtonClick( wxCommandEvent& event );
+};
+
diff --git a/gerbview/dialogs/dialog_show_page_borders_base.cpp b/gerbview/dialogs/dialog_show_page_borders_base.cpp
new file mode 100644
index 0000000..9e19938
--- /dev/null
+++ b/gerbview/dialogs/dialog_show_page_borders_base.cpp
@@ -0,0 +1,64 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Apr 10 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_show_page_borders_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE::DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bDialogSizer;
+ bDialogSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bRightSizer;
+ bRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_ShowPageLimitsChoices[] = { _("Full size. Do not show page limits"), _("Full size"), _("Size A4"), _("Size A3"), _("Size A2"), _("Size A"), _("Size B"), _("Size C") };
+ int m_ShowPageLimitsNChoices = sizeof( m_ShowPageLimitsChoices ) / sizeof( wxString );
+ m_ShowPageLimits = new wxRadioBox( this, wxID_ANY, _("Show Page Limits:"), wxDefaultPosition, wxDefaultSize, m_ShowPageLimitsNChoices, m_ShowPageLimitsChoices, 1, wxRA_SPECIFY_COLS );
+ m_ShowPageLimits->SetSelection( 0 );
+ bRightSizer->Add( m_ShowPageLimits, 0, wxALL|wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( bRightSizer, 1, wxEXPAND, 5 );
+
+
+ bDialogSizer->Add( bUpperSizer, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bDialogSizer->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bDialogSizer->Add( m_sdbSizer1, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( bDialogSizer );
+ this->Layout();
+
+ // Connect Events
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE::OnCancelButtonClick ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE::OnOKBUttonClick ), NULL, this );
+}
+
+DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE::~DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE()
+{
+ // Disconnect Events
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE::OnCancelButtonClick ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE::OnOKBUttonClick ), NULL, this );
+
+}
diff --git a/gerbview/dialogs/dialog_show_page_borders_base.fbp b/gerbview/dialogs/dialog_show_page_borders_base.fbp
new file mode 100644
index 0000000..3872fe6
--- /dev/null
+++ b/gerbview/dialogs/dialog_show_page_borders_base.fbp
@@ -0,0 +1,316 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="11" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_show_page_borders_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_show_page_borders_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">263,254</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Page Borders</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bDialogSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Full size. Do not show page limits&quot; &quot;Full size&quot; &quot;Size A4&quot; &quot;Size A3&quot; &quot;Size A2&quot; &quot;Size A&quot; &quot;Size B&quot; &quot;Size C&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show Page Limits:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShowPageLimits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelButtonClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKBUttonClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/gerbview/dialogs/dialog_show_page_borders_base.h b/gerbview/dialogs/dialog_show_page_borders_base.h
new file mode 100644
index 0000000..4203815
--- /dev/null
+++ b/gerbview/dialogs/dialog_show_page_borders_base.h
@@ -0,0 +1,55 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Apr 10 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_SHOW_PAGE_BORDERS_BASE_H__
+#define __DIALOG_SHOW_PAGE_BORDERS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/radiobox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxRadioBox* m_ShowPageLimits;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCancelButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOKBUttonClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Page Borders"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 263,254 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_PAGE_SHOW_PAGE_BORDERS_BASE();
+
+};
+
+#endif //__DIALOG_SHOW_PAGE_BORDERS_BASE_H__
diff --git a/gerbview/dialogs/gerbview_dialog_display_options_frame.cpp b/gerbview/dialogs/gerbview_dialog_display_options_frame.cpp
new file mode 100644
index 0000000..d64bac5
--- /dev/null
+++ b/gerbview/dialogs/gerbview_dialog_display_options_frame.cpp
@@ -0,0 +1,182 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2016 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file gerbview_dialog_display_options_frame.cpp
+ * Set some display options for GerbView
+ */
+
+
+#include <fctsys.h>
+#include <common.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+
+#include <pcbplot.h>
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <gerbview_dialog_display_options_frame_base.h>
+
+
+/*******************************************/
+/* Dialog frame to select display options */
+/*******************************************/
+class DIALOG_DISPLAY_OPTIONS : public DIALOG_DISPLAY_OPTIONS_BASE
+{
+private:
+ GERBVIEW_FRAME* m_Parent;
+
+public:
+
+ DIALOG_DISPLAY_OPTIONS( GERBVIEW_FRAME* parent );
+ ~DIALOG_DISPLAY_OPTIONS() {};
+
+private:
+ void OnOKBUttonClick( wxCommandEvent& event );
+ void OnCancelButtonClick( wxCommandEvent& event );
+ void initOptDialog( );
+ void OnMiddleBtnPanEnbl( wxCommandEvent& event )
+ {
+ m_OptMiddleButtonPanLimited->Enable( m_OptMiddleButtonPan->GetValue() );
+ }
+};
+
+
+void GERBVIEW_FRAME::InstallGerberOptionsDialog( wxCommandEvent& event )
+{
+ DIALOG_DISPLAY_OPTIONS dlg( this );
+ int opt = dlg.ShowModal();
+
+ if( opt > 0 )
+ m_canvas->Refresh();
+}
+
+
+DIALOG_DISPLAY_OPTIONS::DIALOG_DISPLAY_OPTIONS( GERBVIEW_FRAME *parent) :
+ DIALOG_DISPLAY_OPTIONS_BASE( parent, wxID_ANY )
+{
+ m_Parent = parent;
+ SetFocus();
+ initOptDialog( );
+
+ GetSizer()->Fit( this );
+ GetSizer()->SetSizeHints( this );
+ Center();
+ m_sdbSizer1OK->SetDefault();
+}
+
+
+void DIALOG_DISPLAY_OPTIONS::OnCancelButtonClick( wxCommandEvent& event )
+{
+ EndModal( 0 );
+}
+
+
+void DIALOG_DISPLAY_OPTIONS::initOptDialog( )
+{
+ m_PolarDisplay->SetSelection( m_Parent->m_DisplayOptions.m_DisplayPolarCood ? 1 : 0 );
+ m_BoxUnits->SetSelection( g_UserUnit ? 1 : 0 );
+ m_CursorShape->SetSelection( m_Parent->GetCursorShape() ? 1 : 0 );
+
+ // Show Option Draw Lines. We use DisplayPcbTrackFill as Lines draw option
+ m_OptDisplayLines->SetSelection( m_Parent->m_DisplayOptions.m_DisplayLinesFill ? 1 : 0 );
+ m_OptDisplayFlashedItems->SetSelection( m_Parent->m_DisplayOptions.m_DisplayFlashedItemsFill ? 1 : 0);
+
+ // Show Option Draw polygons
+ m_OptDisplayPolygons->SetSelection( m_Parent->m_DisplayOptions.m_DisplayPolygonsFill ? 1 : 0 );
+
+ m_ShowPageLimits->SetSelection(0);
+
+ if( m_Parent->GetShowBorderAndTitleBlock() )
+ {
+ wxString curPaperType = m_Parent->GetPageSettings().GetType();
+
+ for( unsigned i = 1; i < DIM( g_GerberPageSizeList ); ++i )
+ {
+ if( g_GerberPageSizeList[i] == curPaperType )
+ {
+ m_ShowPageLimits->SetSelection( i );
+ break;
+ }
+ }
+ }
+
+ m_OptDisplayDCodes->SetValue( m_Parent->IsElementVisible( DCODES_VISIBLE ) );
+
+
+ m_OptZoomNoCenter->SetValue( m_Parent->GetCanvas()->GetEnableZoomNoCenter() );
+ m_OptMousewheelPan->SetValue( m_Parent->GetCanvas()->GetEnableMousewheelPan() );
+ m_OptMiddleButtonPan->SetValue( m_Parent->GetCanvas()->GetEnableMiddleButtonPan() );
+ m_OptMiddleButtonPanLimited->SetValue( m_Parent->GetCanvas()->GetMiddleButtonPanLimited() );
+ m_OptMiddleButtonPanLimited->Enable( m_OptMiddleButtonPan->GetValue() );
+}
+
+
+void DIALOG_DISPLAY_OPTIONS::OnOKBUttonClick( wxCommandEvent& event )
+{
+ m_Parent->m_DisplayOptions.m_DisplayPolarCood =
+ (m_PolarDisplay->GetSelection() == 0) ? false : true;
+ g_UserUnit = (m_BoxUnits->GetSelection() == 0) ? INCHES : MILLIMETRES;
+ m_Parent->SetCursorShape( m_CursorShape->GetSelection() );
+
+ if( m_OptDisplayLines->GetSelection() == 1 )
+ m_Parent->m_DisplayOptions.m_DisplayLinesFill = true;
+ else
+ m_Parent->m_DisplayOptions.m_DisplayLinesFill = false;
+
+ if( m_OptDisplayFlashedItems->GetSelection() == 1 )
+ {
+ m_Parent->m_DisplayOptions.m_DisplayFlashedItemsFill = true;
+ }
+ else
+ {
+ m_Parent->m_DisplayOptions.m_DisplayFlashedItemsFill = false;
+ }
+
+
+ if( m_OptDisplayPolygons->GetSelection() == 0 )
+ m_Parent->m_DisplayOptions.m_DisplayPolygonsFill = false;
+ else
+ m_Parent->m_DisplayOptions.m_DisplayPolygonsFill = true;
+
+ m_Parent->SetElementVisibility( DCODES_VISIBLE, m_OptDisplayDCodes->GetValue() );
+
+ int idx = m_ShowPageLimits->GetSelection();
+
+ m_Parent->SetShowBorderAndTitleBlock( idx > 0 ? true : false );
+
+ PAGE_INFO pageInfo( g_GerberPageSizeList[idx] );
+
+ m_Parent->SetPageSettings( pageInfo );
+
+ m_Parent->GetCanvas()->SetEnableZoomNoCenter( m_OptZoomNoCenter->GetValue() );
+ m_Parent->GetCanvas()->SetEnableMousewheelPan( m_OptMousewheelPan->GetValue() );
+ m_Parent->GetCanvas()->SetEnableMiddleButtonPan( m_OptMiddleButtonPan->GetValue() );
+ m_Parent->GetCanvas()->SetMiddleButtonPanLimited( m_OptMiddleButtonPanLimited->GetValue() );
+
+ m_Parent->GetCanvas()->Refresh();
+
+ EndModal( 1 );
+}
+
diff --git a/gerbview/dialogs/gerbview_dialog_display_options_frame_base.cpp b/gerbview/dialogs/gerbview_dialog_display_options_frame_base.cpp
new file mode 100644
index 0000000..c6bdd8f
--- /dev/null
+++ b/gerbview/dialogs/gerbview_dialog_display_options_frame_base.cpp
@@ -0,0 +1,141 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "gerbview_dialog_display_options_frame_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_DISPLAY_OPTIONS_BASE::DIALOG_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bDialogSizer;
+ bDialogSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bLeftSizer;
+ bLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_PolarDisplayChoices[] = { _("Cartesian coordinates"), _("Polar coordinates") };
+ int m_PolarDisplayNChoices = sizeof( m_PolarDisplayChoices ) / sizeof( wxString );
+ m_PolarDisplay = new wxRadioBox( this, wxID_ANY, _("Coordinates"), wxDefaultPosition, wxDefaultSize, m_PolarDisplayNChoices, m_PolarDisplayChoices, 1, wxRA_SPECIFY_COLS );
+ m_PolarDisplay->SetSelection( 0 );
+ bLeftSizer->Add( m_PolarDisplay, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_BoxUnitsChoices[] = { _("Inches"), _("Millimeters") };
+ int m_BoxUnitsNChoices = sizeof( m_BoxUnitsChoices ) / sizeof( wxString );
+ m_BoxUnits = new wxRadioBox( this, wxID_ANY, _("Units"), wxDefaultPosition, wxDefaultSize, m_BoxUnitsNChoices, m_BoxUnitsChoices, 1, wxRA_SPECIFY_COLS );
+ m_BoxUnits->SetSelection( 0 );
+ bLeftSizer->Add( m_BoxUnits, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_CursorShapeChoices[] = { _("Small cross"), _("Full screen cursor") };
+ int m_CursorShapeNChoices = sizeof( m_CursorShapeChoices ) / sizeof( wxString );
+ m_CursorShape = new wxRadioBox( this, wxID_ANY, _("Cursor"), wxDefaultPosition, wxDefaultSize, m_CursorShapeNChoices, m_CursorShapeChoices, 1, wxRA_SPECIFY_COLS );
+ m_CursorShape->SetSelection( 1 );
+ bLeftSizer->Add( m_CursorShape, 0, wxALL|wxEXPAND, 5 );
+
+ m_OptDisplayDCodes = new wxCheckBox( this, wxID_ANY, _("Show D codes"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptDisplayDCodes->SetValue(true);
+ bLeftSizer->Add( m_OptDisplayDCodes, 0, wxALL, 5 );
+
+
+ bUpperSizer->Add( bLeftSizer, 1, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bMiddleSizer;
+ bMiddleSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_OptDisplayLinesChoices[] = { _("Sketch"), _("Filled") };
+ int m_OptDisplayLinesNChoices = sizeof( m_OptDisplayLinesChoices ) / sizeof( wxString );
+ m_OptDisplayLines = new wxRadioBox( this, wxID_ANY, _("Lines"), wxDefaultPosition, wxDefaultSize, m_OptDisplayLinesNChoices, m_OptDisplayLinesChoices, 1, wxRA_SPECIFY_COLS );
+ m_OptDisplayLines->SetSelection( 1 );
+ bMiddleSizer->Add( m_OptDisplayLines, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_OptDisplayFlashedItemsChoices[] = { _("Sketch"), _("Filled") };
+ int m_OptDisplayFlashedItemsNChoices = sizeof( m_OptDisplayFlashedItemsChoices ) / sizeof( wxString );
+ m_OptDisplayFlashedItems = new wxRadioBox( this, wxID_ANY, _("Pads"), wxDefaultPosition, wxDefaultSize, m_OptDisplayFlashedItemsNChoices, m_OptDisplayFlashedItemsChoices, 1, wxRA_SPECIFY_COLS );
+ m_OptDisplayFlashedItems->SetSelection( 1 );
+ bMiddleSizer->Add( m_OptDisplayFlashedItems, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_OptDisplayPolygonsChoices[] = { _("Sketch"), _("Filled") };
+ int m_OptDisplayPolygonsNChoices = sizeof( m_OptDisplayPolygonsChoices ) / sizeof( wxString );
+ m_OptDisplayPolygons = new wxRadioBox( this, wxID_ANY, _("Polygons"), wxDefaultPosition, wxDefaultSize, m_OptDisplayPolygonsNChoices, m_OptDisplayPolygonsChoices, 1, wxRA_SPECIFY_COLS );
+ m_OptDisplayPolygons->SetSelection( 1 );
+ bMiddleSizer->Add( m_OptDisplayPolygons, 0, wxALL|wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( bMiddleSizer, 1, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bRightSizer;
+ bRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_ShowPageLimitsChoices[] = { _("Full size without limits"), _("Full size"), _("Size A4"), _("Size A3"), _("Size A2"), _("Size A"), _("Size B"), _("Size C") };
+ int m_ShowPageLimitsNChoices = sizeof( m_ShowPageLimitsChoices ) / sizeof( wxString );
+ m_ShowPageLimits = new wxRadioBox( this, wxID_ANY, _("Page"), wxDefaultPosition, wxDefaultSize, m_ShowPageLimitsNChoices, m_ShowPageLimitsChoices, 1, wxRA_SPECIFY_COLS );
+ m_ShowPageLimits->SetSelection( 0 );
+ bRightSizer->Add( m_ShowPageLimits, 0, wxALL|wxEXPAND, 5 );
+
+ wxStaticBoxSizer* bLeftBottomSizer;
+ bLeftBottomSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Pan and Zoom") ), wxVERTICAL );
+
+ m_OptZoomNoCenter = new wxCheckBox( bLeftBottomSizer->GetStaticBox(), wxID_ANY, _("Do not center and warp cursor on zoom"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptZoomNoCenter->SetToolTip( _("Keep the cursor at its current location when zooming") );
+
+ bLeftBottomSizer->Add( m_OptZoomNoCenter, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_OptMiddleButtonPan = new wxCheckBox( bLeftBottomSizer->GetStaticBox(), wxID_ANY, _("Use middle mouse button to pan"), wxDefaultPosition, wxDefaultSize, 0 );
+ bLeftBottomSizer->Add( m_OptMiddleButtonPan, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_OptMiddleButtonPanLimited = new wxCheckBox( bLeftBottomSizer->GetStaticBox(), wxID_ANY, _("Limit panning to scroll size"), wxDefaultPosition, wxDefaultSize, 0 );
+ bLeftBottomSizer->Add( m_OptMiddleButtonPanLimited, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_OptMousewheelPan = new wxCheckBox( bLeftBottomSizer->GetStaticBox(), wxID_ANY, _("Use touchpad to pan"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptMousewheelPan->SetToolTip( _("Use touchpad to pan canvas") );
+
+ bLeftBottomSizer->Add( m_OptMousewheelPan, 0, wxALL, 5 );
+
+
+ bRightSizer->Add( bLeftBottomSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ bUpperSizer->Add( bRightSizer, 2, wxALL|wxEXPAND, 5 );
+
+
+ bDialogSizer->Add( bUpperSizer, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bDialogSizer->Add( m_staticline1, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bDialogSizer->Add( m_sdbSizer1, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( bDialogSizer );
+ this->Layout();
+ bDialogSizer->Fit( this );
+
+ // Connect Events
+ m_OptMiddleButtonPan->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DISPLAY_OPTIONS_BASE::OnMiddleBtnPanEnbl ), NULL, this );
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DISPLAY_OPTIONS_BASE::OnCancelButtonClick ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DISPLAY_OPTIONS_BASE::OnOKBUttonClick ), NULL, this );
+}
+
+DIALOG_DISPLAY_OPTIONS_BASE::~DIALOG_DISPLAY_OPTIONS_BASE()
+{
+ // Disconnect Events
+ m_OptMiddleButtonPan->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DISPLAY_OPTIONS_BASE::OnMiddleBtnPanEnbl ), NULL, this );
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DISPLAY_OPTIONS_BASE::OnCancelButtonClick ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DISPLAY_OPTIONS_BASE::OnOKBUttonClick ), NULL, this );
+
+}
diff --git a/gerbview/dialogs/gerbview_dialog_display_options_frame_base.fbp b/gerbview/dialogs/gerbview_dialog_display_options_frame_base.fbp
new file mode 100644
index 0000000..4c57b25
--- /dev/null
+++ b/gerbview/dialogs/gerbview_dialog_display_options_frame_base.fbp
@@ -0,0 +1,1334 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">gerbview_dialog_display_options_frame_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">gerbview_dialog_display_options_frame_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_DISPLAY_OPTIONS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Gerbview Options</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bDialogSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Cartesian coordinates&quot; &quot;Polar coordinates&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Coordinates</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PolarDisplay</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Inches&quot; &quot;Millimeters&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Units</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_BoxUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Small cross&quot; &quot;Full screen cursor&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Cursor</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CursorShape</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show D codes</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayDCodes</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMiddleSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Sketch&quot; &quot;Filled&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Lines</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayLines</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Sketch&quot; &quot;Filled&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pads</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayFlashedItems</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Sketch&quot; &quot;Filled&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Polygons</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayPolygons</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">2</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Full size without limits&quot; &quot;Full size&quot; &quot;Size A4&quot; &quot;Size A3&quot; &quot;Size A2&quot; &quot;Size A&quot; &quot;Size B&quot; &quot;Size C&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Page</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShowPageLimits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pan and Zoom</property>
+ <property name="minimum_size"></property>
+ <property name="name">bLeftBottomSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Do not center and warp cursor on zoom</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptZoomNoCenter</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Keep the cursor at its current location when zooming</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Use middle mouse button to pan</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptMiddleButtonPan</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnMiddleBtnPanEnbl</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Limit panning to scroll size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptMiddleButtonPanLimited</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Use touchpad to pan</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptMousewheelPan</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Use touchpad to pan canvas</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelButtonClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKBUttonClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/gerbview/dialogs/gerbview_dialog_display_options_frame_base.h b/gerbview/dialogs/gerbview_dialog_display_options_frame_base.h
new file mode 100644
index 0000000..d49eea1
--- /dev/null
+++ b/gerbview/dialogs/gerbview_dialog_display_options_frame_base.h
@@ -0,0 +1,71 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __GERBVIEW_DIALOG_DISPLAY_OPTIONS_FRAME_BASE_H__
+#define __GERBVIEW_DIALOG_DISPLAY_OPTIONS_FRAME_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/radiobox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/checkbox.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_DISPLAY_OPTIONS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_DISPLAY_OPTIONS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxRadioBox* m_PolarDisplay;
+ wxRadioBox* m_BoxUnits;
+ wxRadioBox* m_CursorShape;
+ wxCheckBox* m_OptDisplayDCodes;
+ wxRadioBox* m_OptDisplayLines;
+ wxRadioBox* m_OptDisplayFlashedItems;
+ wxRadioBox* m_OptDisplayPolygons;
+ wxRadioBox* m_ShowPageLimits;
+ wxCheckBox* m_OptZoomNoCenter;
+ wxCheckBox* m_OptMiddleButtonPan;
+ wxCheckBox* m_OptMiddleButtonPanLimited;
+ wxCheckBox* m_OptMousewheelPan;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnMiddleBtnPanEnbl( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOKBUttonClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Gerbview Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_DISPLAY_OPTIONS_BASE();
+
+};
+
+#endif //__GERBVIEW_DIALOG_DISPLAY_OPTIONS_FRAME_BASE_H__
diff --git a/gerbview/draw_gerber_screen.cpp b/gerbview/draw_gerber_screen.cpp
new file mode 100644
index 0000000..2ae6f4a
--- /dev/null
+++ b/gerbview/draw_gerber_screen.cpp
@@ -0,0 +1,457 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jpierre.charras at wanadoo
+ * Copyright (C) 2013-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file draw_gerber_screen.cpp
+ */
+
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <drawtxt.h>
+#include <base_units.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <colors_selection.h>
+#include <class_gerber_draw_item.h>
+#include <class_GERBER.h>
+#include <printout_controler.h>
+
+
+void GERBVIEW_FRAME::PrintPage( wxDC* aDC, LSET aPrintMasklayer,
+ bool aPrintMirrorMode, void* aData )
+{
+ wxCHECK_RET( aData != NULL, wxT( "aData cannot be NULL." ) );
+
+ // Save current draw options, because print mode has specific options:
+ GBR_DISPLAY_OPTIONS imgDisplayOptions = m_DisplayOptions;
+ std::bitset <GERBER_DRAWLAYERS_COUNT> printLayersMask = GetGerberLayout()->GetPrintableLayers();
+
+ // Set draw options for printing:
+ m_DisplayOptions.m_DisplayFlashedItemsFill = true;
+ m_DisplayOptions.m_DisplayLinesFill = true;
+ m_DisplayOptions.m_DisplayPolygonsFill = true;
+ m_DisplayOptions.m_DisplayDCodes = false;
+ m_DisplayOptions.m_IsPrinting = true;
+
+ PRINT_PARAMETERS* printParameters = (PRINT_PARAMETERS*) aData;
+
+ // Find the layer to be printed
+ int page = printParameters->m_Flags; // contains the page number (not necessarily layer number)
+ int layer = 0;
+
+ // Find the layer number for the printed page (search through the mask and count bits)
+ while( page > 0 )
+ {
+ if( printLayersMask[layer++] )
+ --page;
+ }
+ --layer;
+
+ std::bitset <GERBER_DRAWLAYERS_COUNT> printCurrLayerMask;
+ printCurrLayerMask.reset();
+ printCurrLayerMask.set( layer );
+ GetGerberLayout()->SetPrintableLayers( printCurrLayerMask );
+ m_canvas->SetPrintMirrored( aPrintMirrorMode );
+ bool printBlackAndWhite = printParameters->m_Print_Black_and_White;
+
+ GetGerberLayout()->Draw( m_canvas, aDC, (GR_DRAWMODE) 0,
+ wxPoint( 0, 0 ), printBlackAndWhite );
+
+ m_canvas->SetPrintMirrored( false );
+
+ // Restore draw options:
+ GetGerberLayout()->SetPrintableLayers( printLayersMask );
+ m_DisplayOptions = imgDisplayOptions;
+}
+
+
+void GERBVIEW_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
+{
+ GBR_SCREEN* screen = (GBR_SCREEN*) GetScreen();
+
+ if( !GetGerberLayout() )
+ return;
+
+ wxBusyCursor dummy;
+
+ GR_DRAWMODE drawMode = UNSPECIFIED_DRAWMODE;
+
+ switch( GetDisplayMode() )
+ {
+ default:
+ case 0:
+ break;
+
+ case 1:
+ drawMode = GR_COPY;
+ break;
+
+ case 2:
+ drawMode = GR_OR;
+ break;
+ }
+
+ // Draw according to the current setting. This needs to be GR_COPY or GR_OR.
+ GetGerberLayout()->Draw( m_canvas, DC, drawMode, wxPoint( 0, 0 ) );
+
+ // Draw the "background" now, i.e. grid and axis after gerber layers
+ // because most of time the actual background is erased by successive drawings of each gerber
+ // layer mainly in COPY mode
+ m_canvas->DrawBackGround( DC );
+
+ if( IsElementVisible( DCODES_VISIBLE ) )
+ DrawItemsDCodeID( DC, GR_COPY );
+
+ DrawWorkSheet( DC, screen, 0, IU_PER_MILS, wxEmptyString );
+
+#ifdef USE_WX_OVERLAY
+ if( IsShown() )
+ {
+ m_overlay.Reset();
+ wxDCOverlay overlaydc( m_overlay, (wxWindowDC*)DC );
+ overlaydc.Clear();
+ }
+#endif
+
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ m_canvas->DrawCrossHair( DC );
+
+ // Display the filename and the layer name (found in the gerber files, if any)
+ // relative to the active layer
+ UpdateTitleAndInfo();
+}
+
+
+/*
+ * Redraw All GerbView layers, using a buffered mode or not
+ */
+void GBR_LAYOUT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
+ const wxPoint& aOffset, bool aPrintBlackAndWhite )
+{
+ GERBVIEW_FRAME* gerbFrame = (GERBVIEW_FRAME*) aPanel->GetParent();
+
+ // Because Images can be negative (i.e with background filled in color) items are drawn
+ // graphic layer per graphic layer, after the background is filled
+ // to a temporary bitmap
+ // at least when aDrawMode = GR_COPY or aDrawMode = GR_OR
+ // If aDrawMode = UNSPECIFIED_DRAWMODE, items are drawn to the main screen, and therefore
+ // artifacts can happen with negative items or negative images
+
+ wxColour bgColor = MakeColour( gerbFrame->GetDrawBgColor() );
+ wxBrush bgBrush( bgColor, wxBRUSHSTYLE_SOLID );
+
+ int bitmapWidth, bitmapHeight;
+ wxDC* plotDC = aDC;
+
+ aPanel->GetClientSize( &bitmapWidth, &bitmapHeight );
+
+ wxBitmap* layerBitmap = NULL;
+ wxBitmap* screenBitmap = NULL;
+ wxMemoryDC layerDC; // used sequentially for each gerber layer
+ wxMemoryDC screenDC;
+
+ // When each image must be drawn using GR_OR (transparency mode)
+ // or GR_COPY (stacked mode) we must use a temporary bitmap
+ // to draw gerber images.
+ // this is due to negative objects (drawn using background color) that create artifacts
+ // on other images when drawn on screen
+ bool useBufferBitmap = false;
+
+#ifndef __WXMAC__
+ // Can't work with MAC
+ // Don't try this with retina display
+ if( (aDrawMode == GR_COPY) || ( aDrawMode == GR_OR ) )
+ useBufferBitmap = true;
+#endif
+
+ // these parameters are saved here, because they are modified
+ // and restored later
+ EDA_RECT drawBox = *aPanel->GetClipBox();
+ double scale;
+ aDC->GetUserScale(&scale, &scale);
+ wxPoint dev_org = aDC->GetDeviceOrigin();
+ wxPoint logical_org = aDC->GetLogicalOrigin( );
+
+
+ if( useBufferBitmap )
+ {
+ layerBitmap = new wxBitmap( bitmapWidth, bitmapHeight );
+ screenBitmap = new wxBitmap( bitmapWidth, bitmapHeight );
+ layerDC.SelectObject( *layerBitmap );
+ aPanel->DoPrepareDC( layerDC );
+ aPanel->SetClipBox( drawBox );
+ layerDC.SetBackground( bgBrush );
+ layerDC.SetBackgroundMode( wxSOLID );
+ layerDC.Clear();
+
+ screenDC.SelectObject( *screenBitmap );
+ screenDC.SetBackground( bgBrush );
+ screenDC.SetBackgroundMode( wxSOLID );
+ screenDC.Clear();
+
+ plotDC = &layerDC;
+ }
+
+ bool doBlit = false; // this flag requests an image transfer to actual screen when true.
+
+ bool end = false;
+
+ // Draw layers from bottom to top, and active layer last
+ // in non transparent modes, the last layer drawn mask mask previously drawn layer
+ for( int layer = GERBER_DRAWLAYERS_COUNT-1; !end; --layer )
+ {
+ int active_layer = gerbFrame->getActiveLayer();
+
+ if( layer == active_layer ) // active layer will be drawn after other layers
+ continue;
+
+ if( layer < 0 ) // last loop: draw active layer
+ {
+ end = true;
+ layer = active_layer;
+ }
+
+ if( !gerbFrame->IsLayerVisible( layer ) )
+ continue;
+
+ GERBER_IMAGE* gerber = g_GERBER_List.GetGbrImage( layer );
+
+ if( gerber == NULL ) // Graphic layer not yet used
+ continue;
+
+ EDA_COLOR_T color = gerbFrame->GetLayerColor( layer );
+
+ // Force black and white draw mode on request:
+ if( aPrintBlackAndWhite )
+ gerbFrame->SetLayerColor( layer, gerbFrame->GetDrawBgColor() == BLACK ? WHITE : BLACK );
+
+ if( useBufferBitmap )
+ {
+ // Draw each layer into a bitmap first. Negative Gerber
+ // layers are drawn in background color.
+ if( gerber->HasNegativeItems() && doBlit )
+ {
+ // Set Device origin, logical origin and scale to default values
+ // This is needed by Blit function when using a mask.
+ // Beside, for Blit call, both layerDC and screenDc must have the same settings
+ layerDC.SetDeviceOrigin(0,0);
+ layerDC.SetLogicalOrigin( 0, 0 );
+ layerDC.SetUserScale( 1, 1 );
+
+ if( aDrawMode == GR_COPY )
+ {
+ // Use the layer bitmap itself as a mask when blitting. The bitmap
+ // cannot be referenced by a device context when setting the mask.
+ layerDC.SelectObject( wxNullBitmap );
+ layerBitmap->SetMask( new wxMask( *layerBitmap, bgColor ) );
+ layerDC.SelectObject( *layerBitmap );
+ screenDC.Blit( 0, 0, bitmapWidth, bitmapHeight, &layerDC, 0, 0, wxCOPY, true );
+ }
+ else if( aDrawMode == GR_OR )
+ {
+ // On Linux with a large screen, this version is much faster and without
+ // flicker, but gives a Pcbnew look where layer colors blend together.
+ // Plus it works only because the background color is black. But it may
+ // be more usable for some. The difference is due in part because of
+ // the cpu cycles needed to create the monochromatic bitmap above, and
+ // the extra time needed to do bit indexing into the monochromatic bitmap
+ // on the blit above.
+ screenDC.Blit( 0, 0, bitmapWidth, bitmapHeight, &layerDC, 0, 0, wxOR );
+ }
+ // Restore actual values and clear bitmap for next drawing
+ layerDC.SetDeviceOrigin( dev_org.x, dev_org.y );
+ layerDC.SetLogicalOrigin( logical_org.x, logical_org.y );
+ layerDC.SetUserScale( scale, scale );
+ layerDC.SetBackground( bgBrush );
+ layerDC.SetBackgroundMode( wxSOLID );
+ layerDC.Clear();
+
+ doBlit = false;
+ }
+
+ }
+
+ if( gerber->m_ImageNegative )
+ {
+ // Draw background negative (i.e. in graphic layer color) for negative images.
+ EDA_COLOR_T color = gerbFrame->GetLayerColor( layer );
+
+ GRSetDrawMode( &layerDC, GR_COPY );
+ GRFilledRect( &drawBox, plotDC, drawBox.GetX(), drawBox.GetY(),
+ drawBox.GetRight(), drawBox.GetBottom(),
+ 0, color, color );
+
+ GRSetDrawMode( plotDC, GR_COPY );
+ doBlit = true;
+ }
+
+ int dcode_highlight = 0;
+
+ if( layer == gerbFrame->getActiveLayer() )
+ dcode_highlight = gerber->m_Selected_Tool;
+
+ GR_DRAWMODE layerdrawMode = GR_COPY;
+
+ if( aDrawMode == GR_OR && !gerber->HasNegativeItems() )
+ layerdrawMode = GR_OR;
+
+ // Now we can draw the current layer to the bitmap buffer
+ // When needed, the previous bitmap is already copied to the screen buffer.
+ for( GERBER_DRAW_ITEM* item = gerbFrame->GetItemsList(); item; item = item->Next() )
+ {
+ if( item->GetLayer() != layer )
+ continue;
+
+ GR_DRAWMODE drawMode = layerdrawMode;
+
+ if( dcode_highlight && dcode_highlight == item->m_DCode )
+ DrawModeAddHighlight( &drawMode);
+
+ item->Draw( aPanel, plotDC, drawMode, wxPoint(0,0) );
+ doBlit = true;
+ }
+
+ if( aPrintBlackAndWhite )
+ gerbFrame->SetLayerColor( layer, color );
+ }
+
+ if( doBlit && useBufferBitmap ) // Blit is used only if aDrawMode >= 0
+ {
+ // For this Blit call, layerDC and screenDC must have the same settings
+ // So we set device origin, logical origin and scale to default values
+ // in layerDC
+ layerDC.SetDeviceOrigin(0,0);
+ layerDC.SetLogicalOrigin( 0, 0 );
+ layerDC.SetUserScale( 1, 1 );
+
+ // this is the last transfer to screenDC. If there are no negative items, this is
+ // the only one
+ if( aDrawMode == GR_COPY )
+ {
+ layerDC.SelectObject( wxNullBitmap );
+ layerBitmap->SetMask( new wxMask( *layerBitmap, bgColor ) );
+ layerDC.SelectObject( *layerBitmap );
+ screenDC.Blit( 0, 0, bitmapWidth, bitmapHeight, &layerDC, 0, 0, wxCOPY, true );
+
+ }
+ else if( aDrawMode == GR_OR )
+ {
+ screenDC.Blit( 0, 0, bitmapWidth, bitmapHeight, &layerDC, 0, 0, wxOR );
+ }
+ }
+
+ if( useBufferBitmap )
+ {
+ // For this Blit call, aDC and screenDC must have the same settings
+ // So we set device origin, logical origin and scale to default values
+ // in aDC
+ aDC->SetDeviceOrigin( 0, 0);
+ aDC->SetLogicalOrigin( 0, 0 );
+ aDC->SetUserScale( 1, 1 );
+
+ aDC->Blit( 0, 0, bitmapWidth, bitmapHeight, &screenDC, 0, 0, wxCOPY );
+
+ // Restore aDC values
+ aDC->SetDeviceOrigin(dev_org.x, dev_org.y);
+ aDC->SetLogicalOrigin( logical_org.x, logical_org.y );
+ aDC->SetUserScale( scale, scale );
+
+ layerDC.SelectObject( wxNullBitmap );
+ screenDC.SelectObject( wxNullBitmap );
+ delete layerBitmap;
+ delete screenBitmap;
+ }
+}
+
+
+void GERBVIEW_FRAME::DrawItemsDCodeID( wxDC* aDC, GR_DRAWMODE aDrawMode )
+{
+ wxPoint pos;
+ int width;
+ double orient;
+ wxString Line;
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ for( GERBER_DRAW_ITEM* item = GetItemsList(); item != NULL; item = item->Next() )
+ {
+ if( IsLayerVisible( item->GetLayer() ) == false )
+ continue;
+
+ if( item->m_DCode <= 0 )
+ continue;
+
+ if( item->m_Flashed || item->m_Shape == GBR_ARC )
+ {
+ pos = item->m_Start;
+ }
+ else
+ {
+ pos.x = (item->m_Start.x + item->m_End.x) / 2;
+ pos.y = (item->m_Start.y + item->m_End.y) / 2;
+ }
+
+ pos = item->GetABPosition( pos );
+
+ Line.Printf( wxT( "D%d" ), item->m_DCode );
+
+ if( item->GetDcodeDescr() )
+ width = item->GetDcodeDescr()->GetShapeDim( item );
+ else
+ width = std::min( item->m_Size.x, item->m_Size.y );
+
+ orient = TEXT_ORIENT_HORIZ;
+
+ if( item->m_Flashed )
+ {
+ // A reasonable size for text is width/3 because most of time this text has 3 chars.
+ width /= 3;
+ }
+ else // this item is a line
+ {
+ wxPoint delta = item->m_Start - item->m_End;
+
+ if( abs( delta.x ) < abs( delta.y ) )
+ orient = TEXT_ORIENT_VERT;
+
+ // A reasonable size for text is width/2 because text needs margin below and above it.
+ // a margin = width/4 seems good
+ width /= 2;
+ }
+
+ int color = GetVisibleElementColor( DCODES_VISIBLE );
+
+ DrawGraphicText( m_canvas->GetClipBox(), aDC, pos, (EDA_COLOR_T) color, Line,
+ orient, wxSize( width, width ),
+ GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
+ 0, false, false );
+ }
+}
diff --git a/gerbview/events_called_functions.cpp b/gerbview/events_called_functions.cpp
new file mode 100644
index 0000000..c5a5566
--- /dev/null
+++ b/gerbview/events_called_functions.cpp
@@ -0,0 +1,390 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file events_called_functions.cpp
+ * @brief GerbView command event functions.
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <common.h>
+#include <gestfich.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <kicad_device_context.h>
+#include <gerbview_id.h>
+#include <class_GERBER.h>
+#include <dialog_helpers.h>
+#include <class_DCodeSelectionbox.h>
+#include <class_gerbview_layer_widget.h>
+#include <dialog_show_page_borders.h>
+
+
+// Event table:
+
+BEGIN_EVENT_TABLE( GERBVIEW_FRAME, EDA_DRAW_FRAME )
+ EVT_CLOSE( GERBVIEW_FRAME::OnCloseWindow )
+ EVT_SIZE( GERBVIEW_FRAME::OnSize )
+
+ EVT_TOOL( wxID_FILE, GERBVIEW_FRAME::Files_io )
+ EVT_TOOL( ID_GERBVIEW_ERASE_ALL, GERBVIEW_FRAME::Files_io )
+ EVT_TOOL( ID_GERBVIEW_LOAD_DRILL_FILE, GERBVIEW_FRAME::Files_io )
+ EVT_TOOL( ID_NEW_BOARD, GERBVIEW_FRAME::Files_io )
+ EVT_TOOL( ID_GERBVIEW_SET_PAGE_BORDER, GERBVIEW_FRAME::Process_Special_Functions )
+
+ // Menu Files:
+ EVT_MENU( wxID_FILE, GERBVIEW_FRAME::Files_io )
+ EVT_MENU( ID_NEW_BOARD, GERBVIEW_FRAME::Files_io )
+ EVT_MENU( ID_GEN_PLOT, GERBVIEW_FRAME::ToPlotter )
+ EVT_MENU( ID_GERBVIEW_EXPORT_TO_PCBNEW, GERBVIEW_FRAME::ExportDataInPcbnewFormat )
+
+ EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, GERBVIEW_FRAME::OnGbrFileHistory )
+ EVT_MENU_RANGE( ID_GERBVIEW_DRILL_FILE1, ID_GERBVIEW_DRILL_FILE9,
+ GERBVIEW_FRAME::OnDrlFileHistory )
+
+ EVT_MENU( wxID_EXIT, GERBVIEW_FRAME::OnQuit )
+
+ // menu Preferences
+ EVT_MENU_RANGE( ID_PREFERENCES_HOTKEY_START, ID_PREFERENCES_HOTKEY_END,
+ GERBVIEW_FRAME::Process_Config )
+
+ EVT_MENU( ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
+ GERBVIEW_FRAME::OnSelectOptionToolbar )
+ EVT_MENU( wxID_PREFERENCES, GERBVIEW_FRAME::InstallGerberOptionsDialog )
+
+ // menu Postprocess
+ EVT_MENU( ID_GERBVIEW_SHOW_LIST_DCODES, GERBVIEW_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_GERBVIEW_SHOW_SOURCE, GERBVIEW_FRAME::OnShowGerberSourceFile )
+ EVT_MENU( ID_MENU_GERBVIEW_SELECT_PREFERED_EDITOR,
+ EDA_BASE_FRAME::OnSelectPreferredEditor )
+
+ // menu Miscellaneous
+ EVT_MENU( ID_GERBVIEW_GLOBAL_DELETE, GERBVIEW_FRAME::Process_Special_Functions )
+
+ // Menu Help
+ EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_INDEX, EDA_DRAW_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_ABOUT, EDA_DRAW_FRAME::GetKicadAbout )
+
+ EVT_TOOL( wxID_UNDO, GERBVIEW_FRAME::Process_Special_Functions )
+ EVT_TOOL( wxID_PRINT, GERBVIEW_FRAME::ToPrinter )
+ EVT_COMBOBOX( ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER,
+ GERBVIEW_FRAME::OnSelectActiveLayer )
+
+ EVT_SELECT_DCODE( ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE, GERBVIEW_FRAME::OnSelectActiveDCode )
+
+ // Vertical toolbar:
+ EVT_TOOL( ID_NO_TOOL_SELECTED, GERBVIEW_FRAME::Process_Special_Functions )
+
+ EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE,
+ GERBVIEW_FRAME::Process_Special_Functions )
+
+ // Option toolbar
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_POLAR_COORD, GERBVIEW_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH, GERBVIEW_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH, GERBVIEW_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_LINES_SKETCH, GERBVIEW_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR,
+ GERBVIEW_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_DCODES, GERBVIEW_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_NEGATIVE_ITEMS, GERBVIEW_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL_RANGE( ID_TB_OPTIONS_SHOW_GBR_MODE_0, ID_TB_OPTIONS_SHOW_GBR_MODE_2,
+ GERBVIEW_FRAME::OnSelectDisplayMode )
+
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_POLAR_COORD, GERBVIEW_FRAME::OnUpdateCoordType )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH,
+ GERBVIEW_FRAME::OnUpdateFlashedItemsDrawMode )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_LINES_SKETCH, GERBVIEW_FRAME::OnUpdateLinesDrawMode )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH, GERBVIEW_FRAME::OnUpdatePolygonsDrawMode )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_DCODES, GERBVIEW_FRAME::OnUpdateShowDCodes )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_NEGATIVE_ITEMS, GERBVIEW_FRAME::OnUpdateShowNegativeItems )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR,
+ GERBVIEW_FRAME::OnUpdateShowLayerManager )
+
+ EVT_UPDATE_UI( ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE, GERBVIEW_FRAME::OnUpdateSelectDCode )
+ EVT_UPDATE_UI( ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER,
+ GERBVIEW_FRAME::OnUpdateLayerSelectBox )
+ EVT_UPDATE_UI_RANGE( ID_TB_OPTIONS_SHOW_GBR_MODE_0, ID_TB_OPTIONS_SHOW_GBR_MODE_2,
+ GERBVIEW_FRAME::OnUpdateDrawMode )
+
+END_EVENT_TABLE()
+
+
+/* Handles the selection of tools, menu, and popup menu commands.
+ */
+void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
+{
+ int id = event.GetId();
+
+ switch( id )
+ {
+ case ID_POPUP_PLACE_BLOCK:
+ case ID_POPUP_ZOOM_BLOCK:
+ break;
+
+ case ID_POPUP_CANCEL_CURRENT_COMMAND:
+ m_canvas->EndMouseCapture();
+
+ if( GetScreen()->m_BlockLocate.GetCommand() != BLOCK_IDLE )
+ {
+ /* Should not be executed, except bug */
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_IDLE );
+ GetScreen()->m_BlockLocate.SetState( STATE_NO_BLOCK );
+ GetScreen()->m_BlockLocate.ClearItemsList();
+ }
+
+ if( GetToolId() == ID_NO_TOOL_SELECTED )
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ else
+ m_canvas->SetCursor( (wxStockCursor) m_canvas->GetCurrentCursor() );
+ break;
+
+ default:
+ m_canvas->EndMouseCapture();
+ break;
+ }
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ switch( id )
+ {
+ case ID_GERBVIEW_SET_PAGE_BORDER:
+ {
+ DIALOG_PAGE_SHOW_PAGE_BORDERS dlg( this );
+
+ if( dlg.ShowModal() == wxID_OK )
+ m_canvas->Refresh();
+ }
+ break;
+
+ case ID_GERBVIEW_GLOBAL_DELETE:
+ Erase_Current_DrawLayer( true );
+ ClearMsgPanel();
+ break;
+
+ case ID_NO_TOOL_SELECTED:
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ break;
+
+ case ID_POPUP_CLOSE_CURRENT_TOOL:
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ break;
+
+ case ID_POPUP_CANCEL_CURRENT_COMMAND:
+ break;
+
+ case ID_GERBVIEW_SHOW_LIST_DCODES:
+ Liste_D_Codes();
+ break;
+
+ case ID_POPUP_PLACE_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE );
+ m_canvas->SetAutoPanRequest( false );
+ HandleBlockPlace( &dc );
+ break;
+
+ case ID_POPUP_ZOOM_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_ZOOM );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ default:
+ wxFAIL_MSG( wxT( "GERBVIEW_FRAME::Process_Special_Functions error" ) );
+ break;
+ }
+}
+
+
+void GERBVIEW_FRAME::OnSelectActiveDCode( wxCommandEvent& event )
+{
+ GERBER_IMAGE* gerber_image = g_GERBER_List.GetGbrImage( getActiveLayer() );
+
+ if( gerber_image )
+ {
+ int tool = m_DCodeSelector->GetSelectedDCodeId();
+
+ if( tool != gerber_image->m_Selected_Tool )
+ {
+ gerber_image->m_Selected_Tool = tool;
+ m_canvas->Refresh();
+ }
+ }
+}
+
+
+void GERBVIEW_FRAME::OnSelectActiveLayer( wxCommandEvent& event )
+{
+ int layer = getActiveLayer();
+
+ setActiveLayer( event.GetSelection() );
+
+ if( layer != getActiveLayer() )
+ {
+ if( m_LayersManager->OnLayerSelected() )
+ m_canvas->Refresh();
+ }
+}
+
+
+void GERBVIEW_FRAME::OnShowGerberSourceFile( wxCommandEvent& event )
+{
+ int layer = getActiveLayer();
+ GERBER_IMAGE* gerber_layer = g_GERBER_List.GetGbrImage( layer );
+
+ if( gerber_layer )
+ {
+ wxString editorname = Pgm().GetEditorName();
+ if( !editorname.IsEmpty() )
+ {
+ wxFileName fn( gerber_layer->m_FileName );
+ ExecuteFile( this, editorname, QuoteFullPath( fn ) );
+ }
+ else
+ wxMessageBox( _( "No editor defined. Please select one" ) );
+ }
+
+ else
+ {
+ wxString msg;
+ msg.Printf( _( "No file loaded on the active layer %d" ), layer + 1 );
+ wxMessageBox( msg );
+ }
+}
+
+
+void GERBVIEW_FRAME::OnSelectDisplayMode( wxCommandEvent& event )
+{
+ int oldMode = GetDisplayMode();
+
+ switch( event.GetId() )
+ {
+ case ID_TB_OPTIONS_SHOW_GBR_MODE_0:
+ SetDisplayMode( 0 );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_GBR_MODE_1:
+ SetDisplayMode( 1 );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_GBR_MODE_2:
+ SetDisplayMode( 2 );
+ break;
+ }
+
+ if( GetDisplayMode() != oldMode )
+ m_canvas->Refresh();
+}
+
+
+void GERBVIEW_FRAME::OnQuit( wxCommandEvent& event )
+{
+ Close( true );
+}
+
+
+void GERBVIEW_FRAME::ShowChangedLanguage()
+{
+ // call my base class
+ EDA_DRAW_FRAME::ShowChangedLanguage();
+
+ m_LayersManager->SetLayersManagerTabsText();
+
+ wxAuiPaneInfo& pane_info = m_auimgr.GetPane( m_LayersManager );
+ pane_info.Caption( _( "Visibles" ) );
+ m_auimgr.Update();
+
+ ReFillLayerWidget();
+}
+
+
+void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ bool state;
+
+ switch( id )
+ {
+ case ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG:
+ state = ! m_show_layer_manager_tools;
+ id = ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR;
+ break;
+
+ default:
+ state = m_optionsToolBar->GetToolToggled( id );
+ break;
+ }
+
+ switch( id )
+ {
+ case ID_TB_OPTIONS_SHOW_POLAR_COORD:
+ m_DisplayOptions.m_DisplayPolarCood = state;
+ break;
+
+ case ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH:
+ m_DisplayOptions.m_DisplayFlashedItemsFill = not state;
+ m_canvas->Refresh( true );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_LINES_SKETCH:
+ m_DisplayOptions.m_DisplayLinesFill = not state;
+ m_canvas->Refresh( true );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH:
+ m_DisplayOptions.m_DisplayPolygonsFill = not state;
+ m_canvas->Refresh( true );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_DCODES:
+ SetElementVisibility( DCODES_VISIBLE, state );
+ m_canvas->Refresh( true );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_NEGATIVE_ITEMS:
+ SetElementVisibility( NEGATIVE_OBJECTS_VISIBLE, state );
+ m_canvas->Refresh( true );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR:
+
+ // show/hide auxiliary Vertical layers and visibility manager toolbar
+ m_show_layer_manager_tools = state;
+ m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( m_show_layer_manager_tools );
+ m_auimgr.Update();
+ GetMenuBar()->SetLabel( ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
+ m_show_layer_manager_tools ?
+ _("Hide &Layers Manager" ) : _("Show &Layers Manager" ));
+ break;
+
+ default:
+ wxMessageBox( wxT( "GERBVIEW_FRAME::OnSelectOptionToolbar error" ) );
+ break;
+ }
+}
+
diff --git a/gerbview/excellon_read_drill_file.cpp b/gerbview/excellon_read_drill_file.cpp
new file mode 100644
index 0000000..54283ab
--- /dev/null
+++ b/gerbview/excellon_read_drill_file.cpp
@@ -0,0 +1,702 @@
+/**
+ * @file excellon_read_drill_file.cpp
+ * Functions to read drill files (EXCELLON format) created by Pcbnew
+ * These files use only a subset of EXCELLON commands.
+ */
+
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2014 Jean-Pierre Charras <jp.charras at wanadoo.fr>
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Here is a sample of drill files created by Pcbnew, in decimal format:
+ * (Note: coordinates formats are same as Gerber, and T commands are near Gerber D commands).
+ * M48
+ * ;DRILL file {PCBnew (2011-03-14 BZR 2894)-testing} date 15/03/2011 14:23:22
+ * ;FORMAT={-:-/ absolute / inch / decimal}
+ * FMAT,2
+ * INCH,TZ
+ * T1C0.02
+ * T2C0.032
+ * %
+ * G90
+ * G05
+ * M72
+ * T1
+ * X1.580Y-1.360
+ * X1.580Y-4.860
+ * X8.680Y-1.360
+ * X8.680Y-4.860
+ * T2
+ * X2.930Y-3.560
+ * X5.280Y-2.535
+ * X5.405Y-2.610
+ * X5.620Y-2.900
+ * T0
+ * M30
+ */
+ /*
+ * Note there are some variant of tool definition:
+ * T1F00S00C0.2 or T1C0.02F00S00 ... Feed Rate and Spindle Speed of Tool 1
+ * Feed Rate and Spindle Speed are just skipped because they are not used in a viewer
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <confirm.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <trigo.h>
+#include <macros.h>
+#include <base_units.h>
+#include <class_gerber_draw_item.h>
+#include <class_GERBER.h>
+#include <class_excellon.h>
+#include <kicad_string.h>
+#include <class_X2_gerber_attributes.h>
+
+#include <cmath>
+
+#include <html_messagebox.h>
+
+// Default format for dimensions
+// number of digits in mantissa:
+static int fmtMantissaMM = 3;
+static int fmtMantissaInch = 4;
+// number of digits, integer part:
+static int fmtIntegerMM = 3;
+static int fmtIntegerInch = 2;
+
+extern int ReadInt( char*& text, bool aSkipSeparator = true );
+extern double ReadDouble( char*& text, bool aSkipSeparator = true );
+extern void fillFlashedGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
+ APERTURE_T aAperture,
+ int Dcode_index,
+ int aLayer,
+ const wxPoint& aPos,
+ wxSize aSize,
+ bool aLayerNegative );
+void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
+ int Dcode_index,
+ int aLayer,
+ const wxPoint& aStart,
+ const wxPoint& aEnd,
+ wxSize aPenSize,
+ bool aLayerNegative );
+
+// Getber X2 files have a file attribute which specify the type of image
+// (copper, solder paste ... and sides tpo, bottom or inner copper layers)
+// Excellon drill files do not have attributes, so, just to identify the image
+// In gerbview, we add this attribute, like a Gerber drill file
+static const char file_attribute[] = ".FileFunction,Other,Drill*";
+
+static EXCELLON_CMD excellonHeaderCmdList[] =
+{
+ { "M0", DRILL_M_END, -1 }, // End of Program - No Rewind
+ { "M00", DRILL_M_END, -1 }, // End of Program - No Rewind
+ { "M30", DRILL_M_ENDREWIND, -1 }, // End of Program Rewind
+ { "M47", DRILL_M_MESSAGE, -1 }, // Operator Message
+ { "M45", DRILL_M_LONGMESSAGE, -1 }, // Long Operator message (use more than one line)
+ { "M48", DRILL_M_HEADER, 0 }, // beginning of a header
+ { "M95", DRILL_M_ENDHEADER, 0 }, // End of the header
+ { "METRIC", DRILL_METRICHEADER, 1 },
+ { "INCH", DRILL_IMPERIALHEADER, 1 },
+ { "M71", DRILL_M_METRIC, 1 },
+ { "M72", DRILL_M_IMPERIAL, 1 },
+ { "M25", DRILL_M_BEGINPATTERN, 0 }, // Beginning of Pattern
+ { "M01", DRILL_M_ENDPATTERN, 0 }, // End of Pattern
+ { "M97", DRILL_M_CANNEDTEXT, -1 },
+ { "M98", DRILL_M_CANNEDTEXT, -1 },
+ { "DETECT", DRILL_DETECT_BROKEN, -1 },
+ { "ICI", DRILL_INCREMENTALHEADER, 1 },
+ { "FMAT", DRILL_FMT, 1 }, // Use Format command
+ { "ATC", DRILL_AUTOMATIC_TOOL_CHANGE, 0 },
+ { "TCST", DRILL_TOOL_CHANGE_STOP, 0 }, // Tool Change Stop
+ { "AFS", DRILL_AUTOMATIC_SPEED }, // Automatic Feeds and Speeds
+ { "VER", DRILL_AXIS_VERSION, 1 }, // Selection of X and Y Axis Version
+ { "R", DRILL_RESET_CMD, -1 }, // Reset commands
+ { "%", DRILL_REWIND_STOP, -1 }, // Rewind stop. End of the header
+ { "/", DRILL_SKIP, -1 }, // Clear Tool Linking. End of the header
+ // Keep this item after all commands starting by 'T':
+ { "T", DRILL_TOOL_INFORMATION, 0 }, // Tool Information
+ { "", DRILL_M_UNKNOWN, 0 } // last item in list
+};
+
+static EXCELLON_CMD excellon_G_CmdList[] =
+{
+ { "G90", DRILL_G_ABSOLUTE, 0 }, // Absolute Mode
+ { "G91", DRILL_G_INCREMENTAL, 0 }, // Incremental Input Mode
+ { "G90", DRILL_G_ZEROSET, 0 }, // Absolute Mode
+ { "G00", DRILL_G_ROUT, 1 }, // Route Mode
+ { "G05", DRILL_G_DRILL, 0 }, // Drill Mode
+ { "G85", DRILL_G_SLOT, 0 }, // Drill Mode slot (oval holes)
+ { "G01", DRILL_G_LINEARMOVE, 0 }, // Linear (Straight Line) Mode
+ { "G02", DRILL_G_CWMOVE, 0 }, // Circular CW Mode
+ { "G03", DRILL_G_CCWMOVE, 0 }, // Circular CCW Mode
+ { "G93", DRILL_G_ZERO_SET, 1 }, // Zero Set (XnnYmm and coordintes origin)
+ { "", DRILL_G_UNKNOWN, 0 }, // last item in list
+};
+
+
+/*
+ * Read a EXCELLON file.
+ * Gerber classes are used because there is likeness between Gerber files
+ * and Excellon files
+ * DCode can easily store T code (tool size) as round (or oval) shape
+ * Drill commands are similar to flashed gerber items
+ * Routing commands are similar to Gerber polygons
+ * coordinates have the same format as Gerber, can be given in:
+ * decimal format (i.i. floating notation format)
+ * integer 2.4 format in imperial units,
+ * integer 3.2 or 3.3 format (metric units).
+ */
+bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName )
+{
+ wxString msg;
+ int layerId = getActiveLayer(); // current layer used in GerbView
+ EXCELLON_IMAGE* drill_Layer = (EXCELLON_IMAGE*) g_GERBER_List.GetGbrImage( layerId );
+
+ if( drill_Layer == NULL )
+ {
+ drill_Layer = new EXCELLON_IMAGE( this, layerId );
+ layerId = g_GERBER_List.AddGbrImage( drill_Layer, layerId );
+ }
+
+ if( layerId < 0 )
+ {
+ DisplayError( this, _( "No room to load file" ) );
+ return false;
+ }
+
+ ClearMessageList();
+
+ /* Read the gerber file */
+ FILE * file = wxFopen( aFullFileName, wxT( "rt" ) );
+ if( file == NULL )
+ {
+ msg.Printf( _( "File %s not found" ), GetChars( aFullFileName ) );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ wxString path = wxPathOnly( aFullFileName );
+
+ if( path != wxEmptyString )
+ wxSetWorkingDirectory( path );
+
+ bool success = drill_Layer->Read_EXCELLON_File( file, aFullFileName );
+
+ // Display errors list
+ if( m_Messages.size() > 0 )
+ {
+ HTML_MESSAGE_BOX dlg( this, _( "Files not found" ) );
+ dlg.ListSet( m_Messages );
+ dlg.ShowModal();
+ }
+ return success;
+}
+
+bool EXCELLON_IMAGE::Read_EXCELLON_File( FILE * aFile,
+ const wxString & aFullFileName )
+{
+ /* Set the gerber scale: */
+ ResetDefaultValues();
+
+ m_FileName = aFullFileName;
+ m_Current_File = aFile;
+
+ LOCALE_IO toggleIo;
+
+ // FILE_LINE_READER will close the file.
+ if( m_Current_File == NULL )
+ {
+ wxMessageBox( wxT("NULL!"), m_FileName );
+ return false;
+ }
+
+ FILE_LINE_READER excellonReader( m_Current_File, m_FileName );
+ while( true )
+ {
+ if( excellonReader.ReadLine() == 0 )
+ break;
+
+ char* line = excellonReader.Line();
+ char* text = StrPurge( line );
+
+ if( *text == ';' ) // comment: skip line
+ continue;
+
+ if( m_State == EXCELLON_IMAGE::READ_HEADER_STATE )
+ {
+ Execute_HEADER_Command( text );
+ }
+ else
+ {
+ switch( *text )
+ {
+ case 'M':
+ Execute_HEADER_Command( text );
+ break;
+
+ case 'G': /* Line type Gxx : command */
+ Execute_EXCELLON_G_Command( text );
+ break;
+
+ case 'X':
+ case 'Y': // command like X12550Y19250
+ Execute_Drill_Command(text);
+ break;
+
+ case 'I':
+ case 'J': /* Auxiliary Move command */
+ m_IJPos = ReadIJCoord( text );
+ if( *text == '*' ) // command like X35142Y15945J504
+ {
+ Execute_Drill_Command( text);
+ }
+ break;
+
+ case 'T': // Tool command
+ Select_Tool( text );
+ break;
+
+ case '%':
+ break;
+
+ default:
+ {
+ wxString msg;
+ msg.Printf( wxT( "Unexpected symbol &lt;%c&gt;" ), *text );
+ if( GetParent() )
+ GetParent()->ReportMessage( msg );
+ }
+ break;
+ } // End switch
+ }
+ }
+
+ // Add our file attribute, to identify the drill file
+ X2_ATTRIBUTE dummy;
+ char* text = (char*)file_attribute;
+ dummy.ParseAttribCmd( m_Current_File, NULL, 0, text );
+ delete m_FileFunction;
+ m_FileFunction = new X2_ATTRIBUTE_FILEFUNCTION( dummy );
+
+ m_InUse = true;
+
+ return true;
+}
+
+
+bool EXCELLON_IMAGE::Execute_HEADER_Command( char*& text )
+{
+ EXCELLON_CMD* cmd = NULL;
+ int iprm;
+ double dprm;
+ D_CODE* dcode;
+ wxString msg;
+
+ // Search command in list
+ EXCELLON_CMD* candidate;
+
+ for( unsigned ii = 0; ; ii++ )
+ {
+ candidate = &excellonHeaderCmdList[ii];
+ int len = candidate->m_Name.size();
+ if( len == 0 ) // End of list reached
+ break;
+ if( candidate->m_Name.compare( 0, len, text, len ) == 0 ) // found.
+ {
+ cmd = candidate;
+ text += len;
+ break;
+ }
+ }
+
+ if( !cmd )
+ {
+ msg.Printf( wxT( "Unknown Excellon command &lt;%s&gt;" ), text );
+ ReportMessage( msg );
+ while( *text )
+ text++;
+
+ return false;
+ }
+
+ // Execute command
+ // some do nothing
+ switch( cmd->m_Code )
+ {
+ case DRILL_SKIP:
+ case DRILL_M_UNKNOWN:
+ break;
+
+ case DRILL_M_END:
+ break;
+
+ case DRILL_M_ENDREWIND:
+ break;
+
+ case DRILL_M_MESSAGE:
+ break;
+
+ case DRILL_M_LONGMESSAGE:
+ break;
+
+ case DRILL_M_HEADER:
+ m_State = READ_HEADER_STATE;
+ break;
+
+ case DRILL_M_ENDHEADER:
+ m_State = READ_PROGRAM_STATE;
+ break;
+
+ case DRILL_REWIND_STOP: // End of header. No action in a viewer
+ m_State = READ_PROGRAM_STATE;
+ break;
+
+ case DRILL_M_METRIC:
+ SelectUnits( true );
+ break;
+
+ case DRILL_METRICHEADER: // command like METRIC,TZ or METRIC,LZ
+ SelectUnits( true );
+ if( *text != ',' )
+ {
+ ReportMessage( _( "METRIC command has no parameter" ) );
+ break;
+ }
+ text++; // skip separator
+ if( *text == 'T' )
+ m_NoTrailingZeros = false;
+ else
+ m_NoTrailingZeros = true;
+ break;
+
+ case DRILL_M_IMPERIAL:
+ SelectUnits( false );
+ break;
+
+ case DRILL_IMPERIALHEADER: // command like INCH,TZ or INCH,LZ
+ SelectUnits( false );
+ if( *text != ',' )
+ {
+ ReportMessage( _( "INCH command has no parameter" ) );
+ break;
+ }
+ text++; // skip separator
+ if( *text == 'T' )
+ m_NoTrailingZeros = false;
+ else
+ m_NoTrailingZeros = true;
+ break;
+
+ case DRILL_M_BEGINPATTERN:
+ break;
+
+ case DRILL_M_ENDPATTERN:
+ break;
+
+ case DRILL_M_CANNEDTEXT:
+ break;
+
+ case DRILL_M_TIPCHECK:
+ break;
+
+ case DRILL_DETECT_BROKEN:
+ break;
+
+ case DRILL_INCREMENTALHEADER:
+ if( *text != ',' )
+ {
+ ReportMessage( _( "ICI command has no parameter" ) );
+ break;
+ }
+ text++; // skip separator
+ // Parameter should be ON or OFF
+ if( strnicmp( text, "OFF", 3 ) == 0 )
+ m_Relative = false;
+ else if( strnicmp( text, "ON", 2 ) == 0 )
+ m_Relative = true;
+ else
+ ReportMessage( _( "ICI command has incorrect parameter" ) );
+ break;
+
+ case DRILL_TOOL_CHANGE_STOP:
+ break;
+
+ case DRILL_AUTOMATIC_SPEED:
+ break;
+
+ case DRILL_AXIS_VERSION:
+ break;
+
+ case DRILL_RESET_CMD:
+ break;
+
+ case DRILL_AUTOMATIC_TOOL_CHANGE:
+ break;
+
+ case DRILL_FMT:
+ break;
+
+ case DRILL_TOOL_INFORMATION:
+
+ // Read a tool definition like T1C0.02:
+ // or T1F00S00C0.02 or T1C0.02F00S00
+ // Read tool number:
+ iprm = ReadInt( text, false );
+
+ // Skip Feed rate and Spindle speed, if any here
+ while( *text && ( *text == 'F' || *text == 'S' ) )
+ {
+ text++;
+ ReadInt( text, false );
+ }
+
+ // Read tool shape
+ if( *text != 'C' )
+ ReportMessage( wxString:: Format(
+ _( "Tool definition <%c> not supported" ), *text ) );
+ if( *text )
+ text++;
+
+ //read tool diameter:
+ dprm = ReadDouble( text, false );
+ m_Has_DCode = true;
+
+ // Initialize Dcode to handle this Tool
+ dcode = GetDCODE( iprm + FIRST_DCODE ); // Remember: dcodes are >= FIRST_DCODE
+ if( dcode == NULL )
+ break;
+ // conv_scale = scaling factor from inch to Internal Unit
+ double conv_scale = IU_PER_MILS * 1000;
+ if( m_GerbMetric )
+ conv_scale /= 25.4;
+
+ dcode->m_Size.x = dcode->m_Size.y = KiROUND( dprm * conv_scale );
+ dcode->m_Shape = APT_CIRCLE;
+ break;
+ }
+
+ while( *text )
+ text++;
+
+ return true;
+}
+
+
+bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text )
+{
+ D_CODE* tool;
+ GERBER_DRAW_ITEM * gbritem;
+ while( true )
+ {
+ switch( *text )
+ {
+ case 'X':
+ ReadXYCoord( text );
+ break;
+ case 'Y':
+ ReadXYCoord( text );
+ break;
+ case 'G': // G85 is found here for oval holes
+ m_PreviousPos = m_CurrentPos;
+ Execute_EXCELLON_G_Command( text );
+ break;
+ case 0: // E.O.L: execute command
+ tool = GetDCODE( m_Current_Tool, false );
+ if( !tool )
+ {
+ wxString msg;
+ msg.Printf( _( "Tool <%d> not defined" ), m_Current_Tool );
+ ReportMessage( msg );
+ return false;
+ }
+ gbritem = new GERBER_DRAW_ITEM( GetParent()->GetGerberLayout(), this );
+ GetParent()->GetGerberLayout()->m_Drawings.Append( gbritem );
+ if( m_SlotOn ) // Oblong hole
+ {
+ fillLineGBRITEM( gbritem,
+ tool->m_Num_Dcode, GetParent()->getActiveLayer(),
+ m_PreviousPos, m_CurrentPos,
+ tool->m_Size, false );
+ // the hole is made: reset the slot on command (G85)
+ // (it is needed for each oblong hole)
+ m_SlotOn = false;
+ }
+ else
+ {
+ fillFlashedGBRITEM( gbritem, tool->m_Shape,
+ tool->m_Num_Dcode, GetParent()->getActiveLayer(),
+ m_CurrentPos,
+ tool->m_Size, false );
+ }
+ StepAndRepeatItem( *gbritem );
+ m_PreviousPos = m_CurrentPos;
+ return true;
+ break;
+
+ default:
+ text++;
+ break;
+ }
+ }
+
+ return true;
+}
+
+
+bool EXCELLON_IMAGE::Select_Tool( char*& text )
+{
+ int tool_id = TCodeNumber( text );
+
+ if( tool_id >= 0 )
+ {
+ tool_id += FIRST_DCODE; // Remember: dcodes are >= FIRST_DCODE
+ if( tool_id > (TOOLS_MAX_COUNT - 1) )
+ tool_id = TOOLS_MAX_COUNT - 1;
+ m_Current_Tool = tool_id;
+ D_CODE* pt_Dcode = GetDCODE( tool_id , false );
+ if( pt_Dcode )
+ pt_Dcode->m_InUse = true;
+ }
+ while( *text )
+ text++;
+
+ return tool_id >= 0;
+}
+
+
+bool EXCELLON_IMAGE::Execute_EXCELLON_G_Command( char*& text )
+{
+ EXCELLON_CMD* cmd = NULL;
+ bool success = false;
+ int id = DRILL_G_UNKNOWN;
+
+ // Search command in list
+ EXCELLON_CMD* candidate;
+ char * gcmd = text; // gcmd points the G command, for error messages.
+
+ for( unsigned ii = 0; ; ii++ )
+ {
+ candidate = &excellon_G_CmdList[ii];
+ int len = candidate->m_Name.size();
+ if( len == 0 ) // End of list reached
+ break;
+ if( candidate->m_Name.compare( 0, len, text, len ) == 0 ) // found.
+ {
+ cmd = candidate;
+ text += len;
+ success = true;
+ id = cmd->m_Code;
+ break;
+ }
+ }
+
+ switch( id )
+ {
+ case DRILL_G_ZERO_SET:
+ ReadXYCoord( text );
+ m_Offset = m_CurrentPos;
+ break;
+
+ case DRILL_G_ROUT:
+ m_SlotOn = false;
+ m_PolygonFillMode = true;
+ break;
+
+ case DRILL_G_DRILL:
+ m_SlotOn = false;
+ m_PolygonFillMode = false;
+ break;
+
+ case DRILL_G_SLOT:
+ m_SlotOn = true;
+ break;
+
+ case DRILL_G_LINEARMOVE:
+ m_Iterpolation = GERB_INTERPOL_LINEAR_1X;
+ break;
+
+ case DRILL_G_CWMOVE:
+ m_Iterpolation = GERB_INTERPOL_ARC_NEG;
+ break;
+
+ case DRILL_G_CCWMOVE:
+ m_Iterpolation = GERB_INTERPOL_ARC_POS;
+ break;
+
+ case DRILL_G_ABSOLUTE:
+ m_Relative = false; // false = absolute coord
+ break;
+
+ case DRILL_G_INCREMENTAL:
+ m_Relative = true; // true = relative coord
+ break;
+
+ case DRILL_G_UNKNOWN:
+ default:
+ {
+ wxString msg;
+ msg.Printf( _( "Unknown Excellon G Code: &lt;%s&gt;" ), GetChars(FROM_UTF8(gcmd)) );
+ ReportMessage( msg );
+ while( *text )
+ text++;
+ return false;
+ }
+ }
+ return success;
+}
+
+void EXCELLON_IMAGE::SelectUnits( bool aMetric )
+{
+ /* Coordinates are measured either in inch or metric (millimeters).
+ * Inch coordinates are in six digits (00.0000) with increments
+ * as small as 0.0001 (1/10,000).
+ * Metric coordinates can be measured in microns (thousandths of a millimeter)
+ * in one of the following three ways:
+ * Five digit 10 micron resolution (000.00)
+ * Six digit 10 micron resolution (0000.00)
+ * Six digit micron resolution (000.000)
+ */
+ /* Inches: Default fmt = 2.4 for X and Y axis: 6 digits with 0.0001 resolution
+ * metric: Default fmt = 3.3 for X and Y axis: 6 digits, 1 micron resolution
+ */
+ if( aMetric )
+ {
+ m_GerbMetric = true;
+ // number of digits in mantissa
+ m_FmtScale.x = m_FmtScale.y = fmtMantissaMM;
+ // number of digits (mantissa+interger)
+ m_FmtLen.x = m_FmtLen.y = fmtIntegerMM+fmtMantissaMM;
+ }
+ else
+ {
+ m_GerbMetric = false;
+ m_FmtScale.x = m_FmtScale.y = fmtMantissaInch;
+ m_FmtLen.x = m_FmtLen.y = fmtIntegerInch+fmtMantissaInch;
+ }
+}
diff --git a/gerbview/export_to_pcbnew.cpp b/gerbview/export_to_pcbnew.cpp
new file mode 100644
index 0000000..1b4de9f
--- /dev/null
+++ b/gerbview/export_to_pcbnew.cpp
@@ -0,0 +1,495 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file export_to_pcbnew.cpp
+ * @brief Export the layers to Pcbnew.
+ */
+
+#include <vector>
+
+#include <fctsys.h>
+#include <common.h>
+#include <confirm.h>
+#include <macros.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <trigo.h>
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <class_gerber_draw_item.h>
+#include <class_GERBER.h>
+#include <select_layers_to_pcb.h>
+#include <build_version.h>
+#include <wildcards_and_files_ext.h>
+
+
+// Imported function
+extern const wxString GetPCBDefaultLayerName( LAYER_NUM aLayerNumber );
+
+#define TO_PCB_UNIT( x ) ( x / IU_PER_MM)
+
+#define TRACK_TYPE 0
+
+/* A helper class to export a Gerber set of files to Pcbnew
+ */
+class GBR_TO_PCB_EXPORTER
+{
+private:
+ GERBVIEW_FRAME* m_gerbview_frame; // the main gerber frame
+ wxString m_pcb_file_name; // BOARD file to write to
+ FILE* m_fp; // the board file
+ int m_pcbCopperLayersCount;
+ std::vector<wxPoint> m_vias_coordinates; // list of already generated vias,
+ // used to export only once a via
+ // having a given coordinate
+public:
+ GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME* aFrame, const wxString& aFileName );
+ ~GBR_TO_PCB_EXPORTER();
+
+ /**
+ * Function ExportPcb
+ * saves a board from a set of Gerber images.
+ */
+ bool ExportPcb( LAYER_NUM* aLayerLookUpTable, int aCopperLayers );
+
+private:
+ /**
+ * Function export_non_copper_item
+ * write a non copper line or arc to the board file.
+ * @param aGbrItem = the Gerber item (line, arc) to export
+ * @param aLayer = the technical layer to use
+ */
+ void export_non_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer );
+
+ /**
+ * Function export_copper_item
+ * write a track or via) to the board file.
+ * @param aGbrItem = the Gerber item (line, arc, flashed) to export
+ * @param aLayer = the copper layer to use
+ */
+ void export_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer );
+
+ /**
+ * Function export_flashed_copper_item
+ * write a via to the board file (always uses a via through).
+ * @param aGbrItem = the flashed Gerber item to export
+ */
+ void export_flashed_copper_item( GERBER_DRAW_ITEM* aGbrItem );
+
+ /**
+ * Function export_segline_copper_item
+ * write a track (not via) to the board file.
+ * @param aGbrItem = the Gerber item (line only) to export
+ * @param aLayer = the copper layer to use
+ */
+ void export_segline_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer );
+
+ /**
+ * Function export_segarc_copper_item
+ * write a set of tracks (arcs are approximated by track segments)
+ * to the board file.
+ * @param aGbrItem = the Gerber item (arc only) to export
+ * @param aLayer = the copper layer to use
+ */
+ void export_segarc_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer );
+
+ /**
+ * function writePcbLineItem
+ * basic write function to write a DRAWSEGMENT item or a TRACK item
+ * to the board file, from a non flashed item
+ */
+ void writePcbLineItem( bool aIsArc, wxPoint& aStart, wxPoint& aEnd,
+ int aWidth, LAYER_NUM aLayer, double aAngle = 0 );
+
+ /**
+ * function writeCopperLineItem
+ * basic write function to write a a TRACK item
+ * to the board file, from a non flashed item
+ */
+ void writeCopperLineItem( wxPoint& aStart, wxPoint& aEnd,
+ int aWidth, LAYER_NUM aLayer );
+
+ /**
+ * function writePcbHeader
+ * Write a very basic header to the board file
+ */
+ void writePcbHeader( LAYER_NUM* aLayerLookUpTable );
+};
+
+
+GBR_TO_PCB_EXPORTER::GBR_TO_PCB_EXPORTER( GERBVIEW_FRAME* aFrame, const wxString& aFileName )
+{
+ m_gerbview_frame = aFrame;
+ m_pcb_file_name = aFileName;
+ m_fp = NULL;
+ m_pcbCopperLayersCount = 2;
+}
+
+
+GBR_TO_PCB_EXPORTER::~GBR_TO_PCB_EXPORTER()
+{
+}
+
+
+/* Export data in Pcbnew format
+ * remember Pcbnew uses a Y reversed axis, so we must negate all Y coordinates
+ */
+void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event )
+{
+ int layercount = 0;
+
+ // Count the Gerber layers which are actually currently used
+ for( LAYER_NUM ii = 0; ii < GERBER_DRAWLAYERS_COUNT; ++ii )
+ {
+ if( g_GERBER_List.GetGbrImage( ii ) )
+ layercount++;
+ }
+
+ if( layercount == 0 )
+ {
+ DisplayInfoMessage( this,
+ _( "None of the Gerber layers contain any data" ) );
+ return;
+ }
+
+ wxString fileName;
+ wxString path = m_mruPath;
+
+ wxFileDialog filedlg( this, _( "Board file name:" ),
+ path, fileName, PcbFileWildcard,
+ wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( filedlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ fileName = filedlg.GetPath();
+
+ /* Install a dialog frame to choose the mapping
+ * between gerber layers and Pcbnew layers
+ */
+ LAYERS_MAP_DIALOG* layerdlg = new LAYERS_MAP_DIALOG( this );
+ int ok = layerdlg->ShowModal();
+ layerdlg->Destroy();
+
+ if( ok != wxID_OK )
+ return;
+
+ m_mruPath = wxFileName( fileName ).GetPath();
+
+ GBR_TO_PCB_EXPORTER gbr_exporter( this, fileName );
+
+ gbr_exporter.ExportPcb( layerdlg->GetLayersLookUpTable(), layerdlg->GetCopperLayersCount() );
+}
+
+
+bool GBR_TO_PCB_EXPORTER::ExportPcb( LAYER_NUM* aLayerLookUpTable, int aCopperLayers )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ m_fp = wxFopen( m_pcb_file_name, wxT( "wt" ) );
+
+ if( m_fp == NULL )
+ {
+ wxString msg;
+ msg.Printf( _( "Cannot create file '%s'" ), GetChars( m_pcb_file_name ) );
+ DisplayError( m_gerbview_frame, msg );
+ return false;
+ }
+
+ m_pcbCopperLayersCount = aCopperLayers;
+
+ writePcbHeader( aLayerLookUpTable );
+
+ // create an image of gerber data
+ // First: non copper layers:
+ GERBER_DRAW_ITEM* gerb_item = m_gerbview_frame->GetItemsList();
+ int pcbCopperLayerMax = 31;
+
+ for( ; gerb_item; gerb_item = gerb_item->Next() )
+ {
+ int layer = gerb_item->GetLayer();
+ LAYER_NUM pcb_layer_number = aLayerLookUpTable[layer];
+
+ if( !IsPcbLayer( pcb_layer_number ) )
+ continue;
+
+ if( pcb_layer_number > pcbCopperLayerMax )
+ export_non_copper_item( gerb_item, pcb_layer_number );
+ }
+
+ // Copper layers
+ gerb_item = m_gerbview_frame->GetItemsList();
+
+ for( ; gerb_item; gerb_item = gerb_item->Next() )
+ {
+ int layer = gerb_item->GetLayer();
+ LAYER_NUM pcb_layer_number = aLayerLookUpTable[layer];
+
+ if( pcb_layer_number < 0 || pcb_layer_number > pcbCopperLayerMax )
+ continue;
+
+ else
+ export_copper_item( gerb_item, pcb_layer_number );
+ }
+
+ fprintf( m_fp, ")\n" );
+
+ fclose( m_fp );
+ m_fp = NULL;
+ return true;
+}
+
+
+void GBR_TO_PCB_EXPORTER::export_non_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
+{
+ bool isArc = false;
+
+ double angle = 0;
+ wxPoint seg_start = aGbrItem->m_Start;
+ wxPoint seg_end = aGbrItem->m_End;
+
+ if( aGbrItem->m_Shape == GBR_ARC )
+ {
+ double a = atan2( (double) ( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y),
+ (double) ( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
+ double b = atan2( (double) ( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
+ (double) ( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
+
+ isArc = true;
+ angle = RAD2DEG(b - a);
+ seg_start = aGbrItem->m_ArcCentre;
+
+ // Ensure arc orientation is CCW
+ if( angle < 0 )
+ angle += 360.0;
+ }
+
+ // Reverse Y axis:
+ seg_start.y = -seg_start.y;
+ seg_end.y = -seg_end.y;
+ writePcbLineItem( isArc, seg_start, seg_end, aGbrItem->m_Size.x, aLayer, angle );
+}
+
+
+void GBR_TO_PCB_EXPORTER::export_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
+{
+ switch( aGbrItem->m_Shape )
+ {
+ case GBR_SPOT_CIRCLE:
+ case GBR_SPOT_RECT:
+ case GBR_SPOT_OVAL:
+ // replace spots with vias when possible
+ export_flashed_copper_item( aGbrItem );
+ break;
+
+ case GBR_ARC:
+ export_segarc_copper_item( aGbrItem, aLayer );
+ break;
+
+ default:
+ export_segline_copper_item( aGbrItem, aLayer );
+ break;
+ }
+}
+
+
+void GBR_TO_PCB_EXPORTER::export_segline_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
+{
+ wxPoint seg_start, seg_end;
+
+ seg_start = aGbrItem->m_Start;
+ seg_end = aGbrItem->m_End;
+
+ // Reverse Y axis:
+ seg_start.y = -seg_start.y;
+ seg_end.y = -seg_end.y;
+
+ writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
+}
+
+
+void GBR_TO_PCB_EXPORTER::writeCopperLineItem( wxPoint& aStart, wxPoint& aEnd,
+ int aWidth, LAYER_NUM aLayer )
+{
+ fprintf( m_fp, "(segment (start %s %s) (end %s %s) (width %s) (layer %s) (net 0))\n",
+ Double2Str( TO_PCB_UNIT(aStart.x) ).c_str(),
+ Double2Str( TO_PCB_UNIT(aStart.y) ).c_str(),
+ Double2Str( TO_PCB_UNIT(aEnd.x) ).c_str(),
+ Double2Str( TO_PCB_UNIT(aEnd.y) ).c_str(),
+ Double2Str( TO_PCB_UNIT( aWidth ) ).c_str(),
+ TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
+}
+
+
+void GBR_TO_PCB_EXPORTER::export_segarc_copper_item( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
+{
+ double a = atan2( (double) ( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y ),
+ (double) ( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
+ double b = atan2( (double) ( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
+ (double) ( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
+
+ wxPoint start = aGbrItem->m_Start;
+ wxPoint end = aGbrItem->m_End;
+
+ /* Because Pcbnew does not know arcs in tracks,
+ * approximate arc by segments (SEG_COUNT__CIRCLE segment per 360 deg)
+ * The arc is drawn anticlockwise from the start point to the end point.
+ */
+ #define SEG_COUNT_CIRCLE 16
+ #define DELTA_ANGLE 2 * M_PI / SEG_COUNT_CIRCLE
+
+ // calculate the number of segments from a to b.
+ // we want CNT_PER_360 segments fo a circle
+ if( a > b )
+ b += 2 * M_PI;
+
+ wxPoint curr_start = start;
+ wxPoint seg_start, seg_end;
+
+ int ii = 1;
+
+ for( double rot = a; rot < (b - DELTA_ANGLE); rot += DELTA_ANGLE, ii++ )
+ {
+ seg_start = curr_start;
+ wxPoint curr_end = start;
+ RotatePoint( &curr_end, aGbrItem->m_ArcCentre,
+ -RAD2DECIDEG( DELTA_ANGLE * ii ) );
+ seg_end = curr_end;
+ // Reverse Y axis:
+ seg_start.y = -seg_start.y;
+ seg_end.y = -seg_end.y;
+ writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
+ curr_start = curr_end;
+ }
+
+ if( end != curr_start )
+ {
+ seg_start = curr_start;
+ seg_end = end;
+ // Reverse Y axis:
+ seg_start.y = -seg_start.y;
+ seg_end.y = -seg_end.y;
+ writeCopperLineItem( seg_start, seg_end, aGbrItem->m_Size.x, aLayer );
+ }
+}
+
+
+/*
+ * creates a via from a flashed gerber item.
+ * Flashed items are usually pads or vias, so we try to export all of them
+ * using vias
+ */
+void GBR_TO_PCB_EXPORTER::export_flashed_copper_item( GERBER_DRAW_ITEM* aGbrItem )
+{
+ // First, explore already created vias, before creating a new via
+ for( unsigned ii = 0; ii < m_vias_coordinates.size(); ii++ )
+ {
+ if( m_vias_coordinates[ii] == aGbrItem->m_Start ) // Already created
+ return;
+ }
+
+ m_vias_coordinates.push_back( aGbrItem->m_Start );
+
+ wxPoint via_pos = aGbrItem->m_Start;
+ int width = (aGbrItem->m_Size.x + aGbrItem->m_Size.y) / 2;
+ // Reverse Y axis:
+ via_pos.y = -via_pos.y;
+
+ // Layers are Front to Back
+ fprintf( m_fp, " (via (at %s %s) (size %s)",
+ Double2Str( TO_PCB_UNIT(via_pos.x) ).c_str(),
+ Double2Str( TO_PCB_UNIT(via_pos.y) ).c_str(),
+ Double2Str( TO_PCB_UNIT( width ) ).c_str() );
+
+ fprintf( m_fp, " (layers %s %s))\n",
+ TO_UTF8( GetPCBDefaultLayerName( F_Cu ) ),
+ TO_UTF8( GetPCBDefaultLayerName( B_Cu ) ) );
+}
+
+void GBR_TO_PCB_EXPORTER::writePcbHeader( LAYER_NUM* aLayerLookUpTable )
+{
+ fprintf( m_fp, "(kicad_pcb (version 4) (host Gerbview \"%s\")\n\n",
+ TO_UTF8( GetBuildVersion() ) );
+
+ // Write layers section
+ fprintf( m_fp, " (layers \n" );
+
+ for( int ii = 0; ii < m_pcbCopperLayersCount; ii++ )
+ {
+ int id = ii;
+
+ if( ii == m_pcbCopperLayersCount-1)
+ id = B_Cu;
+
+ fprintf( m_fp, " (%d %s signal)\n", id, TO_UTF8( GetPCBDefaultLayerName( id ) ) );
+ }
+
+ for( int ii = B_Adhes; ii < LAYER_ID_COUNT; ii++ )
+ {
+ fprintf( m_fp, " (%d %s user)\n", ii, TO_UTF8( GetPCBDefaultLayerName( ii ) ) );
+ }
+
+ fprintf( m_fp, " )\n\n" );
+}
+
+
+void GBR_TO_PCB_EXPORTER::writePcbLineItem( bool aIsArc, wxPoint& aStart, wxPoint& aEnd,
+ int aWidth, LAYER_NUM aLayer, double aAngle )
+{
+ if( aIsArc && ( aAngle == 360.0 || aAngle == 0 ) )
+ {
+ fprintf( m_fp, "(gr_circle (center %s %s) (end %s %s)(layer %s) (width %s))\n",
+ Double2Str( TO_PCB_UNIT(aStart.x) ).c_str(),
+ Double2Str( TO_PCB_UNIT(aStart.y) ).c_str(),
+ Double2Str( TO_PCB_UNIT(aEnd.x) ).c_str(),
+ Double2Str( TO_PCB_UNIT(aEnd.y) ).c_str(),
+ TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
+ Double2Str( TO_PCB_UNIT( aWidth ) ).c_str()
+ );
+ }
+ else if( aIsArc )
+ {
+ fprintf( m_fp, "(gr_arc (start %s %s) (end %s %s) (angle %s)(layer %s) (width %s))\n",
+ Double2Str( TO_PCB_UNIT(aStart.x) ).c_str(),
+ Double2Str( TO_PCB_UNIT(aStart.y) ).c_str(),
+ Double2Str( TO_PCB_UNIT(aEnd.x) ).c_str(),
+ Double2Str( TO_PCB_UNIT(aEnd.y) ).c_str(),
+ Double2Str( aAngle ).c_str(),
+ TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
+ Double2Str( TO_PCB_UNIT( aWidth ) ).c_str()
+ );
+ }
+ else
+ {
+ fprintf( m_fp, "(gr_line (start %s %s) (end %s %s)(layer %s) (width %s))\n",
+ Double2Str( TO_PCB_UNIT(aStart.x) ).c_str(),
+ Double2Str( TO_PCB_UNIT(aStart.y) ).c_str(),
+ Double2Str( TO_PCB_UNIT(aEnd.x) ).c_str(),
+ Double2Str( TO_PCB_UNIT(aEnd.y) ).c_str(),
+ TO_UTF8( GetPCBDefaultLayerName( aLayer ) ),
+ Double2Str( TO_PCB_UNIT( aWidth ) ).c_str()
+ );
+ }
+}
diff --git a/gerbview/files.cpp b/gerbview/files.cpp
new file mode 100644
index 0000000..2bf2ef1
--- /dev/null
+++ b/gerbview/files.cpp
@@ -0,0 +1,303 @@
+/**
+ * @file gerbview/files.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <gestfich.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <gerbview_id.h>
+#include <class_gerbview_layer_widget.h>
+#include <wildcards_and_files_ext.h>
+
+
+void GERBVIEW_FRAME::OnGbrFileHistory( wxCommandEvent& event )
+{
+ wxString fn;
+
+ fn = GetFileFromHistory( event.GetId(), _( "Gerber files" ) );
+
+ if( !fn.IsEmpty() )
+ {
+ Erase_Current_DrawLayer( false );
+ LoadGerberFiles( fn );
+ }
+}
+
+
+void GERBVIEW_FRAME::OnDrlFileHistory( wxCommandEvent& event )
+{
+ wxString fn;
+
+ fn = GetFileFromHistory( event.GetId(), _( "Drill files" ), &m_drillFileHistory );
+
+ if( !fn.IsEmpty() )
+ {
+ Erase_Current_DrawLayer( false );
+ LoadExcellonFiles( fn );
+ }
+}
+
+
+/* File commands. */
+void GERBVIEW_FRAME::Files_io( wxCommandEvent& event )
+{
+ int id = event.GetId();
+
+ switch( id )
+ {
+ case wxID_FILE:
+ Erase_Current_DrawLayer( false );
+ LoadGerberFiles( wxEmptyString );
+ break;
+
+ case ID_GERBVIEW_ERASE_ALL:
+ Clear_DrawLayers( false );
+ Zoom_Automatique( false );
+ m_canvas->Refresh();
+ ClearMsgPanel();
+ ReFillLayerWidget();
+ break;
+
+ case ID_GERBVIEW_LOAD_DRILL_FILE:
+ LoadExcellonFiles( wxEmptyString );
+ m_canvas->Refresh();
+ break;
+
+ default:
+ wxFAIL_MSG( wxT( "File_io: unexpected command id" ) );
+ break;
+ }
+}
+
+
+bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
+{
+ wxString filetypes;
+ wxArrayString filenamesList;
+ wxFileName filename = aFullFileName;
+ wxString currentPath;
+
+ if( !filename.IsOk() )
+ {
+ /* Standard gerber filetypes
+ * (See http://en.wikipedia.org/wiki/Gerber_File)
+ * the .gbr (.pho in legacy files) extension is the default used in Pcbnew
+ * However there are a lot of other extensions used for gerber files
+ * Because the first letter is usually g, we accept g* as extension
+ * (Mainly internal copper layers do not have specific extension,
+ * and filenames are like *.g1, *.g2 *.gb1 ...).
+ * Now (2014) Ucamco (the company which manager the Gerber format) encourage
+ * use of .gbr only and the Gerber X2 file format.
+ */
+ filetypes = _( "Gerber files (.g* .lgr .pho)" );
+ filetypes << wxT("|");
+ filetypes += wxT("*.g*;*.G*;*.pho;*.PHO" );
+ filetypes << wxT("|");
+
+ /* Special gerber filetypes */
+ filetypes += _( "Top layer (*.GTL)|*.GTL;*.gtl|" );
+ filetypes += _( "Bottom layer (*.GBL)|*.GBL;*.gbl|" );
+ filetypes += _( "Bottom solder resist (*.GBS)|*.GBS;*.gbs|" );
+ filetypes += _( "Top solder resist (*.GTS)|*.GTS;*.gts|" );
+ filetypes += _( "Bottom overlay (*.GBO)|*.GBO;*.gbo|" );
+ filetypes += _( "Top overlay (*.GTO)|*.GTO;*.gto|" );
+ filetypes += _( "Bottom paste (*.GBP)|*.GBP;*.gbp|" );
+ filetypes += _( "Top paste (*.GTP)|*.GTP;*.gtp|" );
+ filetypes += _( "Keep-out layer (*.GKO)|*.GKO;*.gko|" );
+ filetypes += _( "Mechanical layers (*.GMx)|*.GM1;*.gm1;*.GM2;*.gm2;*.GM3;*.gm3|" );
+ filetypes += _( "Top Pad Master (*.GPT)|*.GPT;*.gpt|" );
+ filetypes += _( "Bottom Pad Master (*.GPB)|*.GPB;*.gpb|" );
+
+ /* All filetypes */
+ filetypes += AllFilesWildcard;
+
+ /* Use the current working directory if the file name path does not exist. */
+ if( filename.DirExists() )
+ currentPath = filename.GetPath();
+ else
+ currentPath = m_mruPath;
+
+ wxFileDialog dlg( this,
+ _( "Open Gerber File" ),
+ currentPath,
+ filename.GetFullName(),
+ filetypes,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return false;
+
+ dlg.GetPaths( filenamesList );
+
+ // @todo Take a closer look at the CWD switching here. The current working directory
+ // gets changed by wxFileDialog because the wxFD_CHANGE_DIR flag is set. Is this the
+ // appropriate behavior? The current working directory is not returned to the previous
+ // value so this may be an issue elsewhere.
+ currentPath = wxGetCwd();
+ m_mruPath = currentPath;
+ }
+ else
+ {
+ wxFileName filename = aFullFileName;
+ filenamesList.Add( aFullFileName );
+ currentPath = filename.GetPath();
+ m_mruPath = currentPath;
+ }
+
+ // Read gerber files: each file is loaded on a new GerbView layer
+ int layer = getActiveLayer();
+
+ for( unsigned ii = 0; ii < filenamesList.GetCount(); ii++ )
+ {
+ wxFileName filename = filenamesList[ii];
+
+ if( !filename.IsAbsolute() )
+ filename.SetPath( currentPath );
+
+ m_lastFileName = filename.GetFullPath();
+
+ setActiveLayer( layer, false );
+
+ if( Read_GERBER_File( filename.GetFullPath(), filename.GetFullPath() ) )
+ {
+ UpdateFileHistory( m_lastFileName );
+
+ layer = getNextAvailableLayer( layer );
+
+ if( layer == NO_AVAILABLE_LAYERS )
+ {
+ wxString msg = wxT( "No more empty available layers.\n"
+ "The remaining gerber files will not be loaded." );
+ wxMessageBox( msg );
+ break;
+ }
+
+ setActiveLayer( layer, false );
+ }
+ }
+
+ Zoom_Automatique( false );
+
+ // Synchronize layers tools with actual active layer:
+ ReFillLayerWidget();
+ setActiveLayer( getActiveLayer() );
+ m_LayersManager->UpdateLayerIcons();
+ syncLayerBox();
+ return true;
+}
+
+
+bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName )
+{
+ wxString filetypes;
+ wxArrayString filenamesList;
+ wxFileName filename = aFullFileName;
+ wxString currentPath;
+
+ if( !filename.IsOk() )
+ {
+ filetypes = wxGetTranslation( DrillFileWildcard );
+ filetypes << wxT("|");
+ /* All filetypes */
+ filetypes += wxGetTranslation( AllFilesWildcard );
+
+ /* Use the current working directory if the file name path does not exist. */
+ if( filename.DirExists() )
+ currentPath = filename.GetPath();
+ else
+ currentPath = m_mruPath;
+
+ wxFileDialog dlg( this,
+ _( "Open Drill File" ),
+ currentPath,
+ filename.GetFullName(),
+ filetypes,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_CHANGE_DIR );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return false;
+
+ dlg.GetPaths( filenamesList );
+ currentPath = wxGetCwd();
+ m_mruPath = currentPath;
+ }
+ else
+ {
+ wxFileName filename = aFullFileName;
+ filenamesList.Add( aFullFileName );
+ currentPath = filename.GetPath();
+ m_mruPath = currentPath;
+ }
+
+ // Read gerber files: each file is loaded on a new GerbView layer
+ int layer = getActiveLayer();
+
+ for( unsigned ii = 0; ii < filenamesList.GetCount(); ii++ )
+ {
+ wxFileName filename = filenamesList[ii];
+
+ if( !filename.IsAbsolute() )
+ filename.SetPath( currentPath );
+
+ m_lastFileName = filename.GetFullPath();
+
+ setActiveLayer( layer, false );
+
+ if( Read_EXCELLON_File( filename.GetFullPath() ) )
+ {
+ // Update the list of recent drill files.
+ UpdateFileHistory( filename.GetFullPath(), &m_drillFileHistory );
+
+ layer = getNextAvailableLayer( layer );
+
+ if( layer == NO_AVAILABLE_LAYERS )
+ {
+ wxString msg = wxT( "No more empty available layers.\n"
+ "The remaining gerber files will not be loaded." );
+ wxMessageBox( msg );
+ break;
+ }
+
+ setActiveLayer( layer, false );
+ }
+ }
+
+ Zoom_Automatique( false );
+
+ // Synchronize layers tools with actual active layer:
+ ReFillLayerWidget();
+ setActiveLayer( getActiveLayer() );
+ m_LayersManager->UpdateLayerIcons();
+ syncLayerBox();
+
+ return true;
+}
diff --git a/gerbview/gerber_test_files/aperture-circle-flash-with_hole.gbr b/gerbview/gerber_test_files/aperture-circle-flash-with_hole.gbr
new file mode 100644
index 0000000..8ae16ce
--- /dev/null
+++ b/gerbview/gerber_test_files/aperture-circle-flash-with_hole.gbr
@@ -0,0 +1,27 @@
+G04 Test flashing of circular apertures*
+G04 Four groups of circular apertures are arranged in a square*
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%ADD10C,0.050*%
+%ADD11C,0.050X0.025*%
+%ADD12C,0.050X0.025X0.030*%
+
+G04 No hole, centered at 0,0 *
+G54D10*
+X0Y0D03*
+
+G04 Round hole, centered at 0.1,0 *
+G54D11*
+X00100Y0D03*
+
+G04 Square hole, centered at 0,0.1 *
+G54D12*
+X0Y00100D03*
+
+G04 Two, with round holes, slightly overlapping, centered at 0.1,0.1 *
+G54D11*
+X100Y90D03*
+X00100Y00110D03*
+
+M02*
diff --git a/gerbview/gerber_test_files/aperture-obround-flash-with_hole.gbr b/gerbview/gerber_test_files/aperture-obround-flash-with_hole.gbr
new file mode 100644
index 0000000..b09bf43
--- /dev/null
+++ b/gerbview/gerber_test_files/aperture-obround-flash-with_hole.gbr
@@ -0,0 +1,27 @@
+G04 Test flashing of obround apertures*
+G04 Four groups of obround apertures are arranged in a square*
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%ADD10O,0.050X0.080*%
+%ADD11O,0.080X0.050X0.025*%
+%ADD12O,0.050X0.025X0.025X0.0150*%
+
+G04 No hole, centered at 0,0 *
+G54D10*
+X0Y0D03*
+
+G04 Round hole, centered at 0.1,0 *
+G54D11*
+X00100Y0D03*
+
+G04 Square hole, centered at 0,0.1 *
+G54D12*
+X0Y00100D03*
+
+G04 Two, with round holes, slightly overlapping, centered at 0.1,0.1 *
+G54D11*
+X00100Y00090D03*
+X00100Y00110D03*
+
+M02*
diff --git a/gerbview/gerber_test_files/aperture_macro-no_param-test.gbr b/gerbview/gerber_test_files/aperture_macro-no_param-test.gbr
new file mode 100644
index 0000000..f586dbe
--- /dev/null
+++ b/gerbview/gerber_test_files/aperture_macro-no_param-test.gbr
@@ -0,0 +1,82 @@
+G04 Verification of all aperture macros *
+G04 Handcoded by Stefan Petersen *
+%MOIN*%
+%FSLAX23Y23*%
+%OFA0.0000B0.0000*%
+G90*
+%AMCIRCLE*
+1,1,0.5,0,0*
+%
+%AMVECTOR*
+2,1,0.3,0,0,1,1,-15*
+%
+%AMLINE*
+21,1,0.3,0.05,0,0,-135*
+%
+%AMLINE2*
+22,1,0.8,0.5,0,0,-45*
+%
+%AMOUTLINE*
+4,1,3,0.0,0.0,0.0,0.5,0.5,0.5,0.5,0.0,-25*
+%
+%AMPOLYGON*
+5,1,5,0,0,0.5,25*
+%
+%AMMOIRE*
+6,0,0,1.0,0.1,0.4,2,0.01,1,20*
+%
+%AMTHERMAL*
+7,0,0,1.0,0.3,0.04,-13*
+%
+%ADD10C,0.0650*%
+%ADD11CIRCLE*%
+%ADD12VECTOR*%
+%ADD13LINE*%
+%ADD14LINE2*%
+%ADD15OUTLINE*%
+%ADD16POLYGON*%
+%ADD18MOIRE*%
+%ADD19THERMAL*%
+G04 Outline*
+X0Y0D02*
+G54D10*
+X0Y0D01*
+X10000D01*
+Y10000D01*
+X0D01*
+Y0D01*
+G04 Dots *
+X2000Y5000D03*
+X3000D03*
+X4000D03*
+X5000D03*
+X6000D03*
+X7000D03*
+X8000D03*
+X9000D03*
+Y6200X9000D03*
+G04 Draw circle*
+G54D11*
+X2000Y5000D03*
+G04 Draw line vector *
+G54D12*
+X3000D03*
+G04 Draw line center *
+G54D13*
+X4000D03*
+G04 Draw line lower left *
+G54D14*
+X5000D03*
+G04 Draw outline *
+G54D15*
+X6000D03*
+G04 Draw polygon 1 *
+G54D16*
+X7000D03*
+G04 Draw Moire *
+G54D18*
+X9000D03*
+G04 Draw Thermal *
+G54D19*
+Y6200X9000D03*
+M02*
diff --git a/gerbview/gerber_test_files/aperture_macro-with_param-test.gbr b/gerbview/gerber_test_files/aperture_macro-with_param-test.gbr
new file mode 100644
index 0000000..774d97a
--- /dev/null
+++ b/gerbview/gerber_test_files/aperture_macro-with_param-test.gbr
@@ -0,0 +1,99 @@
+G04 Verification of all aperture macros *
+G04 Handcoded by Stefan Petersen *
+%MOIN*%
+%FSLAX23Y23*%
+%OFA0.0000B0.0000*%
+G90*
+%AMCIRCLE*
+1,1,$1,0,0*
+%
+%AMVECTOR*
+2,1,$1,0,0,$2,$3,-135*
+%
+%AMVECTOR1*
+2,1,0.3,0,0,1,1,-15*
+%
+%AMLINE1*
+21,1,$1,$2,0,0,-135*
+%
+%AMLINE*
+21,1,0.3,0.03,0,0,-135*
+%
+%AMLINE2*
+22,1,$1,$2,0,0,-45*
+%
+%AMLINELOWLEFT*
+22,1,0.2,1.5,0,0,-15*
+%
+%AMOUTLINE*
+4,1,3,0.0,0.0,0.0,0.5,0.5,0.5,0.5,0.0,-25*
+%
+%AMPOLYGON*
+5,1,$1,0,0,0.5,$2*
+%
+%AMMOIRE*
+6,0,0,1.0,0.1,0.4,2,0.01,1,20*
+%
+%AMTHERMAL*
+7,0,0,1.0,0.3,0.01,-13*
+%
+%ADD10C,0.0650*%
+%ADD11CIRCLE,.5*%
+%ADD12VECTOR,0.05X1X0*%
+%ADD13LINE1,0.3X0.05*%
+%ADD14LINE2,0.8X0.5*%
+%ADD15OUTLINE*%
+%ADD16POLYGON,3X-10*%
+%ADD17POLYGON,6X10*%
+%ADD18MOIRE*%
+%ADD19THERMAL*%
+%ADD20LINELOWLEFT*%
+G04 Outline*
+X0Y0D02*
+G54D10*
+X0Y0D01*
+X10000D01*
+Y10000D01*
+X0D01*
+Y0D01*
+G04 Dots *
+X2000Y5000D03*
+X3000D03*
+X4000D03*
+X5000D03*
+X6000D03*
+X7000D03*
+X8000D03*
+X9000D03*
+Y6200X9000D03*
+G04 Draw circle*
+G54D11*
+X2000Y5000D03*
+G04 Draw line vector *
+G54D12*
+X3000D03*
+G04 Draw line center *
+G54D13*
+X4000D03*
+G04 Draw line lower left *
+G54D14*
+X5000D03*
+G04 Draw outline *
+G54D15*
+X6000D03*
+G04 Draw polygon 1 *
+G54D16*
+X7000D03*
+G04 Draw polygon 1 *
+G54D17*
+X8000D03*
+G04 Draw Moire *
+G54D18*
+X9000D03*
+G04 Draw vector at 0,0*
+G54D20*
+X00000Y00000D03*
+G04 Draw Thermal *
+G54D19*
+Y6200X9000D03*
+M02*
diff --git a/gerbview/gerber_test_files/apertures_rotated.gbr b/gerbview/gerber_test_files/apertures_rotated.gbr
new file mode 100644
index 0000000..3f1e727
--- /dev/null
+++ b/gerbview/gerber_test_files/apertures_rotated.gbr
@@ -0,0 +1,1109 @@
+%ICAS*%
+%FSLAX44Y44*%
+%OFA0B0*%
+%SFA1B1*%
+%MOMM*%
+%AMFRECTNOHOLE10*
+21,1,1.5748,2.2860,0.0000,0.0000,0*
+%
+%AMFRECTNOHOLE11*
+21,1,0.5080,1.1430,0.0000,0.0000,180*
+%
+%AMFRECTNOHOLE12*
+21,1,1.5240,2.0320,0.0000,0.0000,180*
+%
+%AMFRECTNOHOLE13*
+21,1,1.5240,2.0320,0.0000,0.0000,270*
+%
+%AMFRECTNOHOLE14*
+21,1,1.5240,2.0320,0.0000,0.0000,90*
+%
+%AMFRECTNOHOLE15*
+21,1,0.8890,1.3970,0.0000,0.0000,270*
+%
+%ADD10FRECTNOHOLE10*%
+%ADD11FRECTNOHOLE11*%
+%ADD12FRECTNOHOLE12*%
+%ADD13FRECTNOHOLE13*%
+%ADD14FRECTNOHOLE14*%
+%ADD15FRECTNOHOLE15*%
+%ADD17C,0.3048X0.0000X0.0000*%
+%ADD19C,1.6764X0.0000X0.0000*%
+%ADD22C,2.2860X0.0000X0.0000*%
+%LNBottom*%
+G54D10*
+X2279650Y-1339850D3*
+X1809750Y-1339850D3*
+G54D11*
+X2355850Y-1435100D3*
+X2343150Y-1371600D3*
+X2355850Y-1371600D3*
+X2368550Y-1371600D3*
+X2381250Y-1371600D3*
+X2393950Y-1371600D3*
+X2406650Y-1371600D3*
+X2419350Y-1371600D3*
+X2432050Y-1371600D3*
+X2432050Y-1435100D3*
+X2419350Y-1435100D3*
+X2406650Y-1435100D3*
+X2393950Y-1435100D3*
+X2381250Y-1435100D3*
+X2368550Y-1435100D3*
+X2343150Y-1435100D3*
+X1885950Y-1435100D3*
+X1873250Y-1371600D3*
+X1885950Y-1371600D3*
+X1898650Y-1371600D3*
+X1911350Y-1371600D3*
+X1924050Y-1371600D3*
+X1936750Y-1371600D3*
+X1949450Y-1371600D3*
+X1962150Y-1371600D3*
+X1962150Y-1435100D3*
+X1949450Y-1435100D3*
+X1936750Y-1435100D3*
+X1924050Y-1435100D3*
+X1911350Y-1435100D3*
+X1898650Y-1435100D3*
+X1873250Y-1435100D3*
+G54D12*
+X2024380Y-1430020D3*
+X1991360Y-1430020D3*
+G54D13*
+X2272030Y-1418590D3*
+X2272030Y-1451610D3*
+G54D14*
+X2101850Y-1369060D3*
+X2101850Y-1336040D3*
+X2228850Y-1369060D3*
+X2228850Y-1336040D3*
+X2190750Y-1369060D3*
+X2190750Y-1336040D3*
+X2152650Y-1369060D3*
+X2152650Y-1336040D3*
+G54D15*
+X1986280Y-1386205D3*
+X1986280Y-1405255D3*
+X2321560Y-1384935D3*
+X2321560Y-1403985D3*
+X2059940Y-1339215D3*
+X2059940Y-1358265D3*
+G54D17*
+X1873250Y-1439291D2*
+X1873250Y-1435100D1*
+X1873250Y-1441867D2*
+X1873250Y-1439291D1*
+X1874738Y-1443355D2*
+X1873250Y-1441867D1*
+X1881450Y-1445546D2*
+X1874738Y-1443355D1*
+X1883990Y-1445546D2*
+X1881450Y-1445546D1*
+X1887910Y-1445546D2*
+X1883990Y-1445546D1*
+X1890068Y-1444625D2*
+X1887910Y-1445546D1*
+X1892300Y-1442393D2*
+X1890068Y-1444625D1*
+X1892300Y-1427807D2*
+X1892300Y-1442393D1*
+X1894532Y-1425575D2*
+X1892300Y-1427807D1*
+X1896690Y-1424654D2*
+X1894532Y-1425575D1*
+X1900610Y-1424654D2*
+X1896690Y-1424654D1*
+X1902768Y-1425575D2*
+X1900610Y-1424654D1*
+X1905000Y-1427807D2*
+X1902768Y-1425575D1*
+X1905000Y-1442393D2*
+X1905000Y-1427807D1*
+X1907232Y-1444625D2*
+X1905000Y-1442393D1*
+X1909390Y-1445546D2*
+X1907232Y-1444625D1*
+X1922090Y-1445546D2*
+X1909390Y-1445546D1*
+X1926010Y-1445546D2*
+X1922090Y-1445546D1*
+X1928168Y-1444625D2*
+X1926010Y-1445546D1*
+X1930400Y-1442393D2*
+X1928168Y-1444625D1*
+X1930400Y-1427807D2*
+X1930400Y-1442393D1*
+X1932632Y-1425575D2*
+X1930400Y-1427807D1*
+X1937330Y-1424654D2*
+X1932632Y-1425575D1*
+X1941250Y-1424654D2*
+X1937330Y-1424654D1*
+X1948180Y-1424686D2*
+X1941250Y-1424654D1*
+X1949450Y-1430909D2*
+X1949450Y-1435100D1*
+X1949450Y-1428333D2*
+X1949450Y-1430909D1*
+X1948180Y-1424686D2*
+X1949450Y-1428333D1*
+X2419350Y-1430909D2*
+X2419350Y-1435100D1*
+X2419350Y-1428333D2*
+X2419350Y-1430909D1*
+X2417862Y-1426845D2*
+X2419350Y-1428333D1*
+X2411150Y-1424654D2*
+X2417862Y-1426845D1*
+X2408610Y-1424654D2*
+X2411150Y-1424654D1*
+X2404690Y-1424654D2*
+X2408610Y-1424654D1*
+X2402532Y-1425575D2*
+X2404690Y-1424654D1*
+X2400300Y-1427807D2*
+X2402532Y-1425575D1*
+X2400300Y-1447822D2*
+X2400300Y-1427807D1*
+X2398931Y-1451126D2*
+X2400300Y-1447822D1*
+X2389021Y-1461036D2*
+X2398931Y-1451126D1*
+X2385717Y-1462405D2*
+X2389021Y-1461036D1*
+X2378280Y-1463326D2*
+X2385717Y-1462405D1*
+X2363900Y-1463326D2*
+X2378280Y-1463326D1*
+X2358820Y-1463326D2*
+X2363900Y-1463326D1*
+X2355177Y-1461817D2*
+X2358820Y-1463326D1*
+X2345008Y-1451648D2*
+X2355177Y-1461817D1*
+X2343499Y-1448005D2*
+X2345008Y-1451648D1*
+X2343150Y-1445023D2*
+X2343499Y-1448005D1*
+X2343150Y-1439291D2*
+X2343150Y-1445023D1*
+X2343150Y-1435100D2*
+X2343150Y-1439291D1*
+X2223421Y-1342136D2*
+X2228850Y-1336040D1*
+X2223421Y-1345620D2*
+X2223421Y-1342136D1*
+X2223262Y-1348486D2*
+X2223421Y-1345620D1*
+X2110486Y-1338929D2*
+X2101850Y-1336040D1*
+X2113970Y-1338929D2*
+X2110486Y-1338929D1*
+X2140530Y-1348391D2*
+X2113970Y-1338929D1*
+X2175252Y-1356856D2*
+X2140530Y-1348391D1*
+X2195572Y-1356856D2*
+X2175252Y-1356856D1*
+X2206248Y-1356856D2*
+X2195572Y-1356856D1*
+X2206467Y-1356765D2*
+X2206248Y-1356856D1*
+X2223262Y-1348486D2*
+X2206467Y-1356765D1*
+X2093214Y-1338929D2*
+X2101850Y-1336040D1*
+X2089730Y-1338929D2*
+X2093214Y-1338929D1*
+X2072640Y-1343914D2*
+X2089730Y-1338929D1*
+X2057686Y-1361186D2*
+X2059940Y-1358265D1*
+X2057686Y-1364670D2*
+X2057686Y-1361186D1*
+X2054915Y-1367441D2*
+X2057686Y-1364670D1*
+X1999062Y-1404116D2*
+X2054915Y-1367441D1*
+X1998687Y-1404271D2*
+X1999062Y-1404116D1*
+X1995106Y-1405255D2*
+X1998687Y-1404271D1*
+X1991741Y-1405255D2*
+X1995106Y-1405255D1*
+X1986280Y-1405255D2*
+X1991741Y-1405255D1*
+X2062194Y-1355344D2*
+X2059940Y-1358265D1*
+X2062194Y-1351860D2*
+X2062194Y-1355344D1*
+X2064965Y-1349089D2*
+X2062194Y-1351860D1*
+X2068885Y-1348391D2*
+X2064965Y-1349089D1*
+X2071656Y-1345620D2*
+X2068885Y-1348391D1*
+X2072640Y-1343914D2*
+X2071656Y-1345620D1*
+X2065401Y-1339215D2*
+X2059940Y-1339215D1*
+X2068766Y-1339215D2*
+X2065401Y-1339215D1*
+X2071370Y-1341819D2*
+X2068766Y-1339215D1*
+X2072640Y-1343914D2*
+X2071370Y-1341819D1*
+X2316099Y-1403985D2*
+X2321560Y-1403985D1*
+X2308957Y-1403985D2*
+X2316099Y-1403985D1*
+X2308220Y-1403680D2*
+X2308957Y-1403985D1*
+X2303742Y-1401492D2*
+X2308220Y-1403680D1*
+X2240970Y-1356709D2*
+X2303742Y-1401492D1*
+X2223262Y-1348486D2*
+X2240970Y-1356709D1*
+X2323814Y-1406906D2*
+X2321560Y-1403985D1*
+X2323814Y-1410390D2*
+X2323814Y-1406906D1*
+X2335879Y-1431345D2*
+X2323814Y-1410390D1*
+X2338650Y-1434116D2*
+X2335879Y-1431345D1*
+X2340610Y-1434116D2*
+X2338650Y-1434116D1*
+X2342134Y-1434116D2*
+X2340610Y-1434116D1*
+X2343150Y-1435100D2*
+X2342134Y-1434116D1*
+X1980819Y-1405255D2*
+X1986280Y-1405255D1*
+X1977454Y-1405255D2*
+X1980819Y-1405255D1*
+X1948180Y-1424686D2*
+X1977454Y-1405255D1*
+X2030476Y-1426210D2*
+X2024380Y-1430020D1*
+X2057095Y-1426210D2*
+X2030476Y-1426210D1*
+X2057095Y-1422400D2*
+X2057095Y-1426210D1*
+X2158079Y-1375156D2*
+X2152650Y-1369060D1*
+X2158079Y-1378640D2*
+X2158079Y-1375156D1*
+X2162099Y-1416050D2*
+X2158079Y-1378640D1*
+X2162099Y-1422400D2*
+X2162099Y-1416050D1*
+X2232101Y-1375156D2*
+X2228850Y-1369060D1*
+X2232101Y-1416050D2*
+X2232101Y-1375156D1*
+X2232101Y-1422400D2*
+X2232101Y-1416050D1*
+X2161286Y-1338929D2*
+X2152650Y-1336040D1*
+X2164770Y-1338929D2*
+X2161286Y-1338929D1*
+X2178691Y-1348244D2*
+X2164770Y-1338929D1*
+X2199011Y-1348244D2*
+X2178691Y-1348244D1*
+X2202809Y-1348244D2*
+X2199011Y-1348244D1*
+X2205494Y-1345559D2*
+X2202809Y-1348244D1*
+X2213959Y-1326460D2*
+X2205494Y-1345559D1*
+X2216730Y-1323689D2*
+X2213959Y-1326460D1*
+X2220650Y-1323689D2*
+X2216730Y-1323689D1*
+X2240970Y-1323689D2*
+X2220650Y-1323689D1*
+X2243741Y-1326460D2*
+X2240970Y-1323689D1*
+X2267045Y-1353240D2*
+X2243741Y-1326460D1*
+X2302606Y-1389893D2*
+X2267045Y-1353240D1*
+X2309617Y-1396904D2*
+X2302606Y-1389893D1*
+X2329637Y-1396904D2*
+X2309617Y-1396904D1*
+X2331181Y-1398448D2*
+X2329637Y-1396904D1*
+X2349500Y-1427807D2*
+X2331181Y-1398448D1*
+X2349500Y-1442393D2*
+X2349500Y-1427807D1*
+X2352544Y-1446612D2*
+X2349500Y-1442393D1*
+X2360213Y-1454281D2*
+X2352544Y-1446612D1*
+X2360588Y-1454436D2*
+X2360213Y-1454281D1*
+X2373288Y-1454436D2*
+X2360588Y-1454436D1*
+X2384132Y-1454436D2*
+X2373288Y-1454436D1*
+X2384507Y-1454281D2*
+X2384132Y-1454436D1*
+X2392176Y-1446612D2*
+X2384507Y-1454281D1*
+X2392331Y-1446237D2*
+X2392176Y-1446612D1*
+X2393950Y-1441867D2*
+X2392331Y-1446237D1*
+X2393950Y-1439291D2*
+X2393950Y-1441867D1*
+X2393950Y-1435100D2*
+X2393950Y-1439291D1*
+X2144014Y-1333151D2*
+X2152650Y-1336040D1*
+X2140530Y-1333151D2*
+X2144014Y-1333151D1*
+X2113970Y-1323689D2*
+X2140530Y-1333151D1*
+X2093650Y-1323689D2*
+X2113970Y-1323689D1*
+X2089730Y-1323689D2*
+X2093650Y-1323689D1*
+X2050995Y-1330039D2*
+X2089730Y-1323689D1*
+X2048224Y-1332810D2*
+X2050995Y-1330039D1*
+X1997996Y-1392610D2*
+X2048224Y-1332810D1*
+X1995225Y-1395381D2*
+X1997996Y-1392610D1*
+X1973873Y-1396079D2*
+X1995225Y-1395381D1*
+X1973498Y-1396234D2*
+X1973873Y-1396079D1*
+X1931474Y-1416700D2*
+X1973498Y-1396234D1*
+X1924050Y-1424146D2*
+X1931474Y-1416700D1*
+X1924050Y-1429385D2*
+X1924050Y-1424146D1*
+X1924050Y-1430909D2*
+X1924050Y-1429385D1*
+X1924050Y-1435100D2*
+X1924050Y-1430909D1*
+X2432050Y-1439291D2*
+X2432050Y-1435100D1*
+X2432050Y-1441867D2*
+X2432050Y-1439291D1*
+X2419949Y-1456684D2*
+X2432050Y-1441867D1*
+X2407279Y-1469354D2*
+X2419949Y-1456684D1*
+X2399792Y-1476714D2*
+X2407279Y-1469354D1*
+X2399384Y-1476986D2*
+X2399792Y-1476714D1*
+X2389669Y-1481010D2*
+X2399384Y-1476986D1*
+X2389187Y-1481106D2*
+X2389669Y-1481010D1*
+X2368233Y-1481106D2*
+X2389187Y-1481106D1*
+X2355533Y-1481106D2*
+X2368233Y-1481106D1*
+X1908468Y-1454436D2*
+X2355533Y-1481106D1*
+X1908093Y-1454281D2*
+X1908468Y-1454436D1*
+X1904602Y-1450975D2*
+X1908093Y-1454281D1*
+X1898650Y-1445023D2*
+X1904602Y-1450975D1*
+X1898650Y-1440815D2*
+X1898650Y-1445023D1*
+X1898650Y-1439291D2*
+X1898650Y-1440815D1*
+X1898650Y-1435100D2*
+X1898650Y-1439291D1*
+X2432050Y-1342898D2*
+X2432050Y-1339850D1*
+X2416093Y-1352419D2*
+X2432050Y-1342898D1*
+X2408424Y-1360088D2*
+X2416093Y-1352419D1*
+X2408269Y-1360463D2*
+X2408424Y-1360088D1*
+X2406650Y-1364833D2*
+X2408269Y-1360463D1*
+X2406650Y-1367409D2*
+X2406650Y-1364833D1*
+X2406650Y-1371600D2*
+X2406650Y-1367409D1*
+X2381250Y-1342898D2*
+X2381250Y-1339850D1*
+X2381250Y-1367409D2*
+X2381250Y-1342898D1*
+X2381250Y-1371600D2*
+X2381250Y-1367409D1*
+X2330450Y-1342898D2*
+X2330450Y-1339850D1*
+X2354362Y-1363345D2*
+X2330450Y-1342898D1*
+X2355850Y-1364833D2*
+X2354362Y-1363345D1*
+X2355850Y-1365885D2*
+X2355850Y-1364833D1*
+X2355850Y-1367409D2*
+X2355850Y-1365885D1*
+X2355850Y-1371600D2*
+X2355850Y-1367409D1*
+X2282793Y-1349756D2*
+X2279650Y-1339850D1*
+X2282793Y-1353240D2*
+X2282793Y-1349756D1*
+X2311940Y-1390471D2*
+X2282793Y-1353240D1*
+X2313484Y-1392015D2*
+X2311940Y-1390471D1*
+X2333503Y-1392015D2*
+X2313484Y-1392015D1*
+X2340515Y-1399027D2*
+X2333503Y-1392015D1*
+X2355850Y-1424146D2*
+X2340515Y-1399027D1*
+X2355850Y-1429385D2*
+X2355850Y-1424146D1*
+X2355850Y-1430909D2*
+X2355850Y-1429385D1*
+X2355850Y-1435100D2*
+X2355850Y-1430909D1*
+X2457450Y-1260602D2*
+X2457450Y-1263650D1*
+X2419782Y-1181100D2*
+X2457450Y-1260602D1*
+X2419782Y-1174750D2*
+X2419782Y-1181100D1*
+X2406650Y-1260602D2*
+X2406650Y-1263650D1*
+X2349779Y-1181100D2*
+X2406650Y-1260602D1*
+X2349779Y-1174750D2*
+X2349779Y-1181100D1*
+X2355850Y-1260602D2*
+X2355850Y-1263650D1*
+X2279802Y-1181100D2*
+X2355850Y-1260602D1*
+X2279802Y-1174750D2*
+X2279802Y-1181100D1*
+X2305050Y-1260602D2*
+X2305050Y-1263650D1*
+X2209800Y-1181100D2*
+X2305050Y-1260602D1*
+X2209800Y-1174750D2*
+X2209800Y-1181100D1*
+X2279650Y-1260602D2*
+X2279650Y-1263650D1*
+X2174799Y-1181100D2*
+X2279650Y-1260602D1*
+X2174799Y-1174750D2*
+X2174799Y-1181100D1*
+X2330450Y-1260602D2*
+X2330450Y-1263650D1*
+X2244801Y-1181100D2*
+X2330450Y-1260602D1*
+X2244801Y-1174750D2*
+X2244801Y-1181100D1*
+X2381250Y-1260602D2*
+X2381250Y-1263650D1*
+X2314804Y-1181100D2*
+X2381250Y-1260602D1*
+X2314804Y-1174750D2*
+X2314804Y-1181100D1*
+X2432050Y-1260602D2*
+X2432050Y-1263650D1*
+X2384781Y-1181100D2*
+X2432050Y-1260602D1*
+X2384781Y-1174750D2*
+X2384781Y-1181100D1*
+X2482850Y-1260602D2*
+X2482850Y-1263650D1*
+X2454783Y-1181100D2*
+X2482850Y-1260602D1*
+X2454783Y-1174750D2*
+X2454783Y-1181100D1*
+X2342134Y-1370616D2*
+X2343150Y-1371600D1*
+X2338650Y-1370616D2*
+X2342134Y-1370616D1*
+X2334342Y-1367024D2*
+X2338650Y-1370616D1*
+X2305050Y-1342898D2*
+X2334342Y-1367024D1*
+X2305050Y-1339850D2*
+X2305050Y-1342898D1*
+X2355850Y-1342898D2*
+X2355850Y-1339850D1*
+X2366776Y-1360088D2*
+X2355850Y-1342898D1*
+X2366931Y-1360463D2*
+X2366776Y-1360088D1*
+X2368550Y-1364833D2*
+X2366931Y-1360463D1*
+X2368550Y-1367409D2*
+X2368550Y-1364833D1*
+X2368550Y-1371600D2*
+X2368550Y-1367409D1*
+X2406650Y-1342898D2*
+X2406650Y-1339850D1*
+X2395724Y-1360088D2*
+X2406650Y-1342898D1*
+X2395569Y-1360463D2*
+X2395724Y-1360088D1*
+X2393950Y-1364833D2*
+X2395569Y-1360463D1*
+X2393950Y-1367409D2*
+X2393950Y-1364833D1*
+X2393950Y-1371600D2*
+X2393950Y-1367409D1*
+X2457450Y-1342898D2*
+X2457450Y-1339850D1*
+X2437560Y-1355933D2*
+X2457450Y-1342898D1*
+X2420838Y-1363345D2*
+X2437560Y-1355933D1*
+X2419350Y-1364833D2*
+X2420838Y-1363345D1*
+X2419350Y-1365885D2*
+X2419350Y-1364833D1*
+X2419350Y-1367409D2*
+X2419350Y-1365885D1*
+X2419350Y-1371600D2*
+X2419350Y-1367409D1*
+X1962150Y-1342898D2*
+X1962150Y-1339850D1*
+X1946193Y-1352419D2*
+X1962150Y-1342898D1*
+X1938524Y-1360088D2*
+X1946193Y-1352419D1*
+X1938369Y-1360463D2*
+X1938524Y-1360088D1*
+X1936750Y-1364833D2*
+X1938369Y-1360463D1*
+X1936750Y-1367409D2*
+X1936750Y-1364833D1*
+X1936750Y-1371600D2*
+X1936750Y-1367409D1*
+X1911350Y-1342898D2*
+X1911350Y-1339850D1*
+X1911350Y-1367409D2*
+X1911350Y-1342898D1*
+X1911350Y-1371600D2*
+X1911350Y-1367409D1*
+X1860550Y-1342898D2*
+X1860550Y-1339850D1*
+X1884462Y-1363345D2*
+X1860550Y-1342898D1*
+X1885950Y-1364833D2*
+X1884462Y-1363345D1*
+X1885950Y-1365885D2*
+X1885950Y-1364833D1*
+X1885950Y-1367409D2*
+X1885950Y-1365885D1*
+X1885950Y-1371600D2*
+X1885950Y-1367409D1*
+X1816100Y-1346549D2*
+X1809750Y-1339850D1*
+X1819584Y-1346549D2*
+X1816100Y-1346549D1*
+X1822355Y-1349320D2*
+X1819584Y-1346549D1*
+X1885950Y-1428333D2*
+X1822355Y-1349320D1*
+X1885950Y-1430909D2*
+X1885950Y-1428333D1*
+X1885950Y-1435100D2*
+X1885950Y-1430909D1*
+X1987550Y-1260602D2*
+X1987550Y-1263650D1*
+X2045132Y-1181100D2*
+X1987550Y-1260602D1*
+X2045132Y-1174750D2*
+X2045132Y-1181100D1*
+X1936750Y-1260602D2*
+X1936750Y-1263650D1*
+X1975129Y-1181100D2*
+X1936750Y-1260602D1*
+X1975129Y-1174750D2*
+X1975129Y-1181100D1*
+X1885950Y-1260602D2*
+X1885950Y-1263650D1*
+X1905152Y-1181100D2*
+X1885950Y-1260602D1*
+X1905152Y-1174750D2*
+X1905152Y-1181100D1*
+X1835150Y-1260602D2*
+X1835150Y-1263650D1*
+X1835150Y-1181100D2*
+X1835150Y-1260602D1*
+X1835150Y-1174750D2*
+X1835150Y-1181100D1*
+X1809750Y-1260602D2*
+X1809750Y-1263650D1*
+X1800149Y-1181100D2*
+X1809750Y-1260602D1*
+X1800149Y-1174750D2*
+X1800149Y-1181100D1*
+X1860550Y-1260602D2*
+X1860550Y-1263650D1*
+X1870151Y-1181100D2*
+X1860550Y-1260602D1*
+X1870151Y-1174750D2*
+X1870151Y-1181100D1*
+X1911350Y-1260602D2*
+X1911350Y-1263650D1*
+X1940154Y-1181100D2*
+X1911350Y-1260602D1*
+X1940154Y-1174750D2*
+X1940154Y-1181100D1*
+X1962150Y-1260602D2*
+X1962150Y-1263650D1*
+X2010131Y-1181100D2*
+X1962150Y-1260602D1*
+X2010131Y-1174750D2*
+X2010131Y-1181100D1*
+X2012950Y-1260602D2*
+X2012950Y-1263650D1*
+X2080133Y-1181100D2*
+X2012950Y-1260602D1*
+X2080133Y-1174750D2*
+X2080133Y-1181100D1*
+X1872234Y-1370616D2*
+X1873250Y-1371600D1*
+X1868750Y-1370616D2*
+X1872234Y-1370616D1*
+X1835150Y-1342898D2*
+X1868750Y-1370616D1*
+X1835150Y-1339850D2*
+X1835150Y-1342898D1*
+X1885950Y-1342898D2*
+X1885950Y-1339850D1*
+X1896876Y-1360088D2*
+X1885950Y-1342898D1*
+X1897031Y-1360463D2*
+X1896876Y-1360088D1*
+X1898650Y-1364833D2*
+X1897031Y-1360463D1*
+X1898650Y-1367409D2*
+X1898650Y-1364833D1*
+X1898650Y-1371600D2*
+X1898650Y-1367409D1*
+X1936750Y-1342898D2*
+X1936750Y-1339850D1*
+X1925824Y-1360088D2*
+X1936750Y-1342898D1*
+X1925669Y-1360463D2*
+X1925824Y-1360088D1*
+X1924050Y-1364833D2*
+X1925669Y-1360463D1*
+X1924050Y-1367409D2*
+X1924050Y-1364833D1*
+X1924050Y-1371600D2*
+X1924050Y-1367409D1*
+X1987550Y-1342898D2*
+X1987550Y-1339850D1*
+X1967660Y-1355933D2*
+X1987550Y-1342898D1*
+X1950938Y-1363345D2*
+X1967660Y-1355933D1*
+X1949450Y-1364833D2*
+X1950938Y-1363345D1*
+X1949450Y-1365885D2*
+X1949450Y-1364833D1*
+X1949450Y-1367409D2*
+X1949450Y-1365885D1*
+X1949450Y-1371600D2*
+X1949450Y-1367409D1*
+X1985264Y-1434116D2*
+X1991360Y-1430020D1*
+X1963166Y-1434116D2*
+X1985264Y-1434116D1*
+X1962150Y-1435100D2*
+X1963166Y-1434116D1*
+X2196179Y-1329944D2*
+X2190750Y-1336040D1*
+X2196179Y-1326460D2*
+X2196179Y-1329944D1*
+X2198950Y-1323689D2*
+X2196179Y-1326460D1*
+X2212893Y-1314954D2*
+X2198950Y-1323689D1*
+X2213268Y-1314799D2*
+X2212893Y-1314954D1*
+X2224112Y-1314799D2*
+X2213268Y-1314799D1*
+X2244432Y-1314799D2*
+X2224112Y-1314799D1*
+X2289484Y-1323689D2*
+X2244432Y-1314799D1*
+X2292255Y-1326460D2*
+X2289484Y-1323689D1*
+X2292255Y-1330380D2*
+X2292255Y-1326460D1*
+X2292096Y-1331513D2*
+X2292255Y-1330380D1*
+X2292096Y-1337609D2*
+X2292096Y-1331513D1*
+X2292150Y-1348318D2*
+X2292096Y-1337609D1*
+X2299630Y-1355798D2*
+X2292150Y-1348318D1*
+X2338558Y-1379765D2*
+X2299630Y-1355798D1*
+X2339292Y-1380497D2*
+X2338558Y-1379765D1*
+X2342449Y-1382831D2*
+X2339292Y-1380497D1*
+X2354144Y-1394526D2*
+X2342449Y-1382831D1*
+X2366215Y-1415477D2*
+X2354144Y-1394526D1*
+X2368550Y-1421115D2*
+X2366215Y-1415477D1*
+X2368550Y-1429385D2*
+X2368550Y-1421115D1*
+X2368550Y-1430909D2*
+X2368550Y-1429385D1*
+X2368550Y-1435100D2*
+X2368550Y-1430909D1*
+X2263394Y-1453801D2*
+X2272030Y-1451610D1*
+X2154403Y-1453801D2*
+X2263394Y-1453801D1*
+X1944950Y-1445546D2*
+X2154403Y-1453801D1*
+X1938238Y-1443355D2*
+X1944950Y-1445546D1*
+X1936750Y-1441867D2*
+X1938238Y-1443355D1*
+X1936750Y-1440815D2*
+X1936750Y-1441867D1*
+X1936750Y-1439291D2*
+X1936750Y-1440815D1*
+X1936750Y-1435100D2*
+X1936750Y-1439291D1*
+X2280666Y-1454499D2*
+X2272030Y-1451610D1*
+X2284150Y-1454499D2*
+X2280666Y-1454499D1*
+X2357051Y-1472216D2*
+X2284150Y-1454499D1*
+X2374969Y-1472216D2*
+X2357051Y-1472216D1*
+X2377924Y-1471764D2*
+X2374969Y-1472216D1*
+X2386980Y-1468755D2*
+X2377924Y-1471764D1*
+X2392618Y-1466420D2*
+X2386980Y-1468755D1*
+X2404315Y-1454723D2*
+X2392618Y-1466420D1*
+X2406650Y-1449085D2*
+X2404315Y-1454723D1*
+X2406650Y-1440815D2*
+X2406650Y-1449085D1*
+X2406650Y-1439291D2*
+X2406650Y-1440815D1*
+X2406650Y-1435100D2*
+X2406650Y-1439291D1*
+X2196179Y-1375156D2*
+X2190750Y-1369060D1*
+X2196179Y-1378640D2*
+X2196179Y-1375156D1*
+X2197100Y-1416050D2*
+X2196179Y-1378640D1*
+X2197100Y-1422400D2*
+X2197100Y-1416050D1*
+X2263394Y-1421479D2*
+X2272030Y-1418590D1*
+X2259910Y-1421479D2*
+X2263394Y-1421479D1*
+X2257139Y-1424250D2*
+X2259910Y-1421479D1*
+X2247720Y-1435986D2*
+X2257139Y-1424250D1*
+X2239337Y-1444369D2*
+X2247720Y-1435986D1*
+X2238028Y-1444911D2*
+X2239337Y-1444369D1*
+X2226174Y-1444911D2*
+X2238028Y-1444911D1*
+X2156172Y-1444911D2*
+X2226174Y-1444911D1*
+X2154863Y-1444369D2*
+X2156172Y-1444911D1*
+X2127098Y-1428750D2*
+X2154863Y-1444369D1*
+X2127098Y-1422400D2*
+X2127098Y-1428750D1*
+X2012950Y-1336802D2*
+X2012950Y-1339850D1*
+X2115134Y-1181100D2*
+X2012950Y-1336802D1*
+X2115134Y-1174750D2*
+X2115134Y-1181100D1*
+X2012950Y-1342898D2*
+X2012950Y-1339850D1*
+X1982470Y-1376426D2*
+X2012950Y-1342898D1*
+X2482850Y-1336802D2*
+X2482850Y-1339850D1*
+X2495963Y-1272019D2*
+X2482850Y-1336802D1*
+X2495963Y-1261377D2*
+X2495963Y-1272019D1*
+X2495963Y-1255281D2*
+X2495963Y-1261377D1*
+X2489784Y-1181100D2*
+X2495963Y-1255281D1*
+X2489784Y-1174750D2*
+X2489784Y-1181100D1*
+X1962150Y-1375791D2*
+X1962150Y-1371600D1*
+X1962150Y-1378367D2*
+X1962150Y-1375791D1*
+X1960662Y-1379855D2*
+X1962150Y-1378367D1*
+X1923377Y-1408383D2*
+X1960662Y-1379855D1*
+X1913208Y-1418552D2*
+X1923377Y-1408383D1*
+X1911699Y-1422195D2*
+X1913208Y-1418552D1*
+X1911350Y-1428333D2*
+X1911699Y-1422195D1*
+X1911350Y-1430909D2*
+X1911350Y-1428333D1*
+X1911350Y-1435100D2*
+X1911350Y-1430909D1*
+X1963166Y-1372584D2*
+X1962150Y-1371600D1*
+X1966650Y-1372584D2*
+X1963166Y-1372584D1*
+X1982470Y-1376426D2*
+X1966650Y-1372584D1*
+X2432050Y-1375791D2*
+X2432050Y-1371600D1*
+X2432050Y-1378367D2*
+X2432050Y-1375791D1*
+X2430562Y-1379855D2*
+X2432050Y-1378367D1*
+X2382738Y-1426845D2*
+X2430562Y-1379855D1*
+X2381250Y-1428333D2*
+X2382738Y-1426845D1*
+X2381250Y-1429385D2*
+X2381250Y-1428333D1*
+X2381250Y-1430909D2*
+X2381250Y-1429385D1*
+X2381250Y-1435100D2*
+X2381250Y-1430909D1*
+X2433066Y-1370616D2*
+X2432050Y-1371600D1*
+X2436550Y-1370616D2*
+X2433066Y-1370616D1*
+X2462960Y-1355933D2*
+X2436550Y-1370616D1*
+X2482850Y-1342898D2*
+X2462960Y-1355933D1*
+X2482850Y-1339850D2*
+X2482850Y-1342898D1*
+X2489784Y-1168400D2*
+X2489784Y-1174750D1*
+X2462019Y-1152781D2*
+X2489784Y-1168400D1*
+X2460710Y-1152239D2*
+X2462019Y-1152781D1*
+X2180726Y-1152239D2*
+X2460710Y-1152239D1*
+X2168872Y-1152239D2*
+X2180726Y-1152239D1*
+X2115134Y-1168400D2*
+X2168872Y-1152239D1*
+X2115134Y-1174750D2*
+X2115134Y-1168400D1*
+X2096421Y-1375156D2*
+X2101850Y-1369060D1*
+X2096421Y-1378640D2*
+X2096421Y-1375156D1*
+X2092096Y-1416050D2*
+X2096421Y-1378640D1*
+X2092096Y-1422400D2*
+X2092096Y-1416050D1*
+X2327021Y-1384935D2*
+X2321560Y-1384935D1*
+X2334163Y-1384935D2*
+X2327021Y-1384935D1*
+X2334900Y-1385240D2*
+X2334163Y-1384935D1*
+X2339073Y-1387885D2*
+X2334900Y-1385240D1*
+X2349090Y-1397902D2*
+X2339073Y-1387885D1*
+X2361218Y-1420512D2*
+X2349090Y-1397902D1*
+X2362200Y-1422883D2*
+X2361218Y-1420512D1*
+X2362200Y-1442393D2*
+X2362200Y-1422883D1*
+X2364432Y-1444625D2*
+X2362200Y-1442393D1*
+X2366590Y-1445546D2*
+X2364432Y-1444625D1*
+X2369130Y-1445546D2*
+X2366590Y-1445546D1*
+X2373050Y-1445546D2*
+X2369130Y-1445546D1*
+X2379762Y-1443355D2*
+X2373050Y-1445546D1*
+X2381250Y-1441867D2*
+X2379762Y-1443355D1*
+X2381250Y-1440815D2*
+X2381250Y-1441867D1*
+X2381250Y-1439291D2*
+X2381250Y-1440815D1*
+X2381250Y-1435100D2*
+X2381250Y-1439291D1*
+X1984026Y-1383284D2*
+X1986280Y-1386205D1*
+X1984026Y-1379800D2*
+X1984026Y-1383284D1*
+X1982470Y-1376426D2*
+X1984026Y-1379800D1*
+G54D19*
+X2279650Y-1260602D2*
+X2279650Y-1266698D1*
+X2305050Y-1260602D2*
+X2305050Y-1266698D1*
+X2330450Y-1260602D2*
+X2330450Y-1266698D1*
+X2355850Y-1260602D2*
+X2355850Y-1266698D1*
+X2381250Y-1260602D2*
+X2381250Y-1266698D1*
+X2406650Y-1260602D2*
+X2406650Y-1266698D1*
+X2432050Y-1260602D2*
+X2432050Y-1266698D1*
+X2457450Y-1260602D2*
+X2457450Y-1266698D1*
+X2482850Y-1260602D2*
+X2482850Y-1266698D1*
+X2482850Y-1336802D2*
+X2482850Y-1342898D1*
+X2457450Y-1336802D2*
+X2457450Y-1342898D1*
+X2432050Y-1336802D2*
+X2432050Y-1342898D1*
+X2406650Y-1336802D2*
+X2406650Y-1342898D1*
+X2381250Y-1336802D2*
+X2381250Y-1342898D1*
+X2355850Y-1336802D2*
+X2355850Y-1342898D1*
+X2330450Y-1336802D2*
+X2330450Y-1342898D1*
+X2305050Y-1336802D2*
+X2305050Y-1342898D1*
+X1809750Y-1260602D2*
+X1809750Y-1266698D1*
+X1835150Y-1260602D2*
+X1835150Y-1266698D1*
+X1860550Y-1260602D2*
+X1860550Y-1266698D1*
+X1885950Y-1260602D2*
+X1885950Y-1266698D1*
+X1911350Y-1260602D2*
+X1911350Y-1266698D1*
+X1936750Y-1260602D2*
+X1936750Y-1266698D1*
+X1962150Y-1260602D2*
+X1962150Y-1266698D1*
+X1987550Y-1260602D2*
+X1987550Y-1266698D1*
+X2012950Y-1260602D2*
+X2012950Y-1266698D1*
+X2012950Y-1336802D2*
+X2012950Y-1342898D1*
+X1987550Y-1336802D2*
+X1987550Y-1342898D1*
+X1962150Y-1336802D2*
+X1962150Y-1342898D1*
+X1936750Y-1336802D2*
+X1936750Y-1342898D1*
+X1911350Y-1336802D2*
+X1911350Y-1342898D1*
+X1885950Y-1336802D2*
+X1885950Y-1342898D1*
+X1860550Y-1336802D2*
+X1860550Y-1342898D1*
+X1835150Y-1336802D2*
+X1835150Y-1342898D1*
+G54D22*
+X2162099Y-1428750D2*
+X2162099Y-1416050D1*
+X2197100Y-1428750D2*
+X2197100Y-1416050D1*
+X2232101Y-1428750D2*
+X2232101Y-1416050D1*
+X2127098Y-1428750D2*
+X2127098Y-1416050D1*
+X2057095Y-1428750D2*
+X2057095Y-1416050D1*
+X2092096Y-1428750D2*
+X2092096Y-1416050D1*
+X2244801Y-1168400D2*
+X2244801Y-1181100D1*
+X2209800Y-1168400D2*
+X2209800Y-1181100D1*
+X2174799Y-1168400D2*
+X2174799Y-1181100D1*
+X2279802Y-1168400D2*
+X2279802Y-1181100D1*
+X2314804Y-1168400D2*
+X2314804Y-1181100D1*
+X2489784Y-1168400D2*
+X2489784Y-1181100D1*
+X2454783Y-1168400D2*
+X2454783Y-1181100D1*
+X2349779Y-1168400D2*
+X2349779Y-1181100D1*
+X2384781Y-1168400D2*
+X2384781Y-1181100D1*
+X2419782Y-1168400D2*
+X2419782Y-1181100D1*
+X1870151Y-1168400D2*
+X1870151Y-1181100D1*
+X1835150Y-1168400D2*
+X1835150Y-1181100D1*
+X1800149Y-1168400D2*
+X1800149Y-1181100D1*
+X1905152Y-1168400D2*
+X1905152Y-1181100D1*
+X1940154Y-1168400D2*
+X1940154Y-1181100D1*
+X2115134Y-1168400D2*
+X2115134Y-1181100D1*
+X2080133Y-1168400D2*
+X2080133Y-1181100D1*
+X1975129Y-1168400D2*
+X1975129Y-1181100D1*
+X2010131Y-1168400D2*
+X2010131Y-1181100D1*
+X2045132Y-1168400D2*
+X2045132Y-1181100D1*
+M02*
diff --git a/gerbview/gerber_test_files/apertures_rotated_and_arcs_in_tracks.gbr b/gerbview/gerber_test_files/apertures_rotated_and_arcs_in_tracks.gbr
new file mode 100644
index 0000000..a335a27
--- /dev/null
+++ b/gerbview/gerber_test_files/apertures_rotated_and_arcs_in_tracks.gbr
@@ -0,0 +1,1417 @@
+%ICAS*%
+%FSLAX44Y44*%
+%OFA0B0*%
+%SFA1B1*%
+%MOMM*%
+%AMFRECTNOHOLE10*
+21,1,1.5748,2.2860,0.0000,0.0000,0*
+%
+%AMFRECTNOHOLE11*
+21,1,0.5080,1.1430,0.0000,0.0000,180*
+%
+%AMFRECTNOHOLE12*
+21,1,1.5240,2.0320,0.0000,0.0000,180*
+%
+%AMFRECTNOHOLE13*
+21,1,1.5240,2.0320,0.0000,0.0000,270*
+%
+%AMFRECTNOHOLE14*
+21,1,1.5240,2.0320,0.0000,0.0000,90*
+%
+%AMFRECTNOHOLE15*
+21,1,0.8890,1.3970,0.0000,0.0000,270*
+%
+%ADD10FRECTNOHOLE10*%
+%ADD11FRECTNOHOLE11*%
+%ADD12FRECTNOHOLE12*%
+%ADD13FRECTNOHOLE13*%
+%ADD14FRECTNOHOLE14*%
+%ADD15FRECTNOHOLE15*%
+%ADD17C,0.3048X0.0000X0.0000*%
+%ADD19C,1.6764X0.0000X0.0000*%
+%ADD22C,2.2860X0.0000X0.0000*%
+%LNBottom_arc*%
+G54D10*
+X2279650Y-1339850D3*
+X1809750Y-1339850D3*
+G54D11*
+X2355850Y-1435100D3*
+X2343150Y-1371600D3*
+X2355850Y-1371600D3*
+X2368550Y-1371600D3*
+X2381250Y-1371600D3*
+X2393950Y-1371600D3*
+X2406650Y-1371600D3*
+X2419350Y-1371600D3*
+X2432050Y-1371600D3*
+X2432050Y-1435100D3*
+X2419350Y-1435100D3*
+X2406650Y-1435100D3*
+X2393950Y-1435100D3*
+X2381250Y-1435100D3*
+X2368550Y-1435100D3*
+X2343150Y-1435100D3*
+X1885950Y-1435100D3*
+X1873250Y-1371600D3*
+X1885950Y-1371600D3*
+X1898650Y-1371600D3*
+X1911350Y-1371600D3*
+X1924050Y-1371600D3*
+X1936750Y-1371600D3*
+X1949450Y-1371600D3*
+X1962150Y-1371600D3*
+X1962150Y-1435100D3*
+X1949450Y-1435100D3*
+X1936750Y-1435100D3*
+X1924050Y-1435100D3*
+X1911350Y-1435100D3*
+X1898650Y-1435100D3*
+X1873250Y-1435100D3*
+G54D12*
+X2024380Y-1430020D3*
+X1991360Y-1430020D3*
+G54D13*
+X2272030Y-1418590D3*
+X2272030Y-1451610D3*
+G54D14*
+X2101850Y-1369060D3*
+X2101850Y-1336040D3*
+X2228850Y-1369060D3*
+X2228850Y-1336040D3*
+X2190750Y-1369060D3*
+X2190750Y-1336040D3*
+X2152650Y-1369060D3*
+X2152650Y-1336040D3*
+G54D15*
+X1986280Y-1386205D3*
+X1986280Y-1405255D3*
+X2321560Y-1384935D3*
+X2321560Y-1403985D3*
+X2059940Y-1339215D3*
+X2059940Y-1358265D3*
+G54D17*
+X1947035Y-1424656D2*
+X1948180Y-1424686D1*
+G75*
+G01X1947035Y-1424656D2*
+G03X1946910Y-1424654I-125J-4729D1*
+G74*
+X1939290Y-1424654D2*
+X1946910Y-1424654D1*
+G75*
+G01X1939290Y-1424654D2*
+G03X1938432Y-1424732I0J-4731D1*
+G74*
+X1933519Y-1425638D2*
+X1938432Y-1424732D1*
+G75*
+G01X1933519Y-1425638D2*
+G03X1930400Y-1429385I691J-3747D1*
+G74*
+X1930400Y-1440815D2*
+X1930400Y-1429385D1*
+G75*
+G01X1927972Y-1444366D2*
+G03X1930400Y-1440815I-1382J3551D1*
+G74*
+X1925765Y-1445224D2*
+X1927972Y-1444366D1*
+G75*
+G01X1924050Y-1445546D2*
+G03X1925765Y-1445224I0J4731D1*
+G74*
+X1911350Y-1445546D2*
+X1924050Y-1445546D1*
+G75*
+G01X1909635Y-1445224D2*
+G03X1911350Y-1445546I1715J4409D1*
+G74*
+X1907428Y-1444366D2*
+X1909635Y-1445224D1*
+G75*
+G01X1905000Y-1440815D2*
+G03X1907428Y-1444366I3810J0D1*
+G74*
+X1905000Y-1429385D2*
+X1905000Y-1440815D1*
+G75*
+G01X1905000Y-1429385D2*
+G03X1902572Y-1425834I-3810J0D1*
+G74*
+X1900365Y-1424976D2*
+X1902572Y-1425834D1*
+G75*
+G01X1900365Y-1424976D2*
+G03X1896935Y-1424976I-1715J-4409D1*
+G74*
+X1894728Y-1425834D2*
+X1896935Y-1424976D1*
+G75*
+G01X1894728Y-1425834D2*
+G03X1892300Y-1429385I1382J-3551D1*
+G74*
+X1892300Y-1440815D2*
+X1892300Y-1429385D1*
+G75*
+G01X1889872Y-1444366D2*
+G03X1892300Y-1440815I-1382J3551D1*
+G74*
+X1887665Y-1445224D2*
+X1889872Y-1444366D1*
+G75*
+G01X1885950Y-1445546D2*
+G03X1887665Y-1445224I0J4731D1*
+G74*
+X1883410Y-1445546D2*
+X1885950Y-1445546D1*
+G75*
+G01X1882050Y-1445346D2*
+G03X1883410Y-1445546I1360J4531D1*
+G74*
+X1875060Y-1443248D2*
+X1882050Y-1445346D1*
+G75*
+G01X1873250Y-1440815D2*
+G03X1875060Y-1443248I2540J0D1*
+G74*
+X1873250Y-1439291D2*
+X1873250Y-1440815D1*
+X1873250Y-1435100D2*
+X1873250Y-1439291D1*
+X1949348Y-1428671D2*
+X1948180Y-1424686D1*
+G75*
+G01X1949450Y-1429385D2*
+G03X1949348Y-1428671I-2540J0D1*
+G74*
+X1949450Y-1430909D2*
+X1949450Y-1429385D1*
+X1949450Y-1435100D2*
+X1949450Y-1430909D1*
+X2343150Y-1439291D2*
+X2343150Y-1440815D1*
+X2343150Y-1435100D2*
+X2343150Y-1439291D1*
+G75*
+G01X2343150Y-1440815D2*
+G03X2343586Y-1444115I12700J0D1*
+G74*
+X2344272Y-1446664D2*
+X2343586Y-1444115D1*
+G75*
+G01X2344272Y-1446664D2*
+G03X2366010Y-1463326I21738J5849D1*
+G74*
+X2371090Y-1463326D2*
+X2366010Y-1463326D1*
+G75*
+G01X2371090Y-1463326D2*
+G03X2373811Y-1463161I0J22511D1*
+G74*
+X2381320Y-1462247D2*
+X2373811Y-1463161D1*
+G75*
+G01X2381320Y-1462247D2*
+G03X2400300Y-1440815I-2610J21432D1*
+G74*
+X2400300Y-1429385D2*
+X2400300Y-1440815D1*
+G75*
+G01X2402728Y-1425834D2*
+G03X2400300Y-1429385I1382J-3551D1*
+G74*
+X2404935Y-1424976D2*
+X2402728Y-1425834D1*
+G75*
+G01X2406650Y-1424654D2*
+G03X2404935Y-1424976I0J-4731D1*
+G74*
+X2409190Y-1424654D2*
+X2406650Y-1424654D1*
+G75*
+G01X2410550Y-1424854D2*
+G03X2409190Y-1424654I-1360J-4531D1*
+G74*
+X2417540Y-1426952D2*
+X2410550Y-1424854D1*
+G75*
+G01X2419350Y-1429385D2*
+G03X2417540Y-1426952I-2540J0D1*
+G74*
+X2419350Y-1430909D2*
+X2419350Y-1429385D1*
+X2419350Y-1435100D2*
+X2419350Y-1430909D1*
+X2223421Y-1343660D2*
+X2223262Y-1348486D1*
+X2223421Y-1342136D2*
+X2223421Y-1343660D1*
+X2228850Y-1336040D2*
+X2223421Y-1342136D1*
+X2206079Y-1355801D2*
+X2223262Y-1348486D1*
+G75*
+G01X2200910Y-1356856D2*
+G03X2206079Y-1355801I0J13196D1*
+G74*
+X2180590Y-1356856D2*
+X2200910Y-1356856D1*
+G75*
+G01X2177658Y-1356526D2*
+G03X2180590Y-1356856I2932J12866D1*
+G74*
+X2141439Y-1348273D2*
+X2177658Y-1356526D1*
+G75*
+G01X2141021Y-1348157D2*
+G03X2141439Y-1348273I1469J4497D1*
+G74*
+X2113479Y-1339163D2*
+X2141021Y-1348157D1*
+G75*
+G01X2113479Y-1339163D2*
+G03X2112010Y-1338929I-1469J-4497D1*
+G74*
+X2110486Y-1338929D2*
+X2112010Y-1338929D1*
+X2101850Y-1336040D2*
+X2110486Y-1338929D1*
+X2090454Y-1339093D2*
+X2072640Y-1343914D1*
+G75*
+G01X2091690Y-1338929D2*
+G03X2090454Y-1339093I0J-4731D1*
+G74*
+X2093214Y-1338929D2*
+X2091690Y-1338929D1*
+X2101850Y-1336040D2*
+X2093214Y-1338929D1*
+X1991741Y-1405255D2*
+X1993265Y-1405255D1*
+X1986280Y-1405255D2*
+X1991741Y-1405255D1*
+G75*
+G01X1993265Y-1405255D2*
+G03X1995173Y-1404825I0J4445D1*
+G74*
+X1999113Y-1402952D2*
+X1995173Y-1404825D1*
+G75*
+G01X1999113Y-1402952D2*
+G03X2000651Y-1402095I-5848J12302D1*
+G74*
+X2055520Y-1366685D2*
+X2000651Y-1402095D1*
+G75*
+G01X2055520Y-1366685D2*
+G03X2057686Y-1362710I-2565J3975D1*
+G74*
+X2057686Y-1361186D2*
+X2057686Y-1362710D1*
+X2059940Y-1358265D2*
+X2057686Y-1361186D1*
+X2070716Y-1346491D2*
+X2072640Y-1343914D1*
+G75*
+G01X2068648Y-1348066D2*
+G03X2070716Y-1346491I-1723J4406D1*
+G74*
+X2065202Y-1349414D2*
+X2068648Y-1348066D1*
+G75*
+G01X2065202Y-1349414D2*
+G03X2062194Y-1353820I1723J-4406D1*
+G74*
+X2062194Y-1355344D2*
+X2062194Y-1353820D1*
+X2059940Y-1358265D2*
+X2062194Y-1355344D1*
+X2070500Y-1341018D2*
+X2072640Y-1343914D1*
+G75*
+G01X2070500Y-1341018D2*
+G03X2066925Y-1339215I-3575J-2642D1*
+G74*
+X2065401Y-1339215D2*
+X2066925Y-1339215D1*
+X2059940Y-1339215D2*
+X2065401Y-1339215D1*
+X2241086Y-1357189D2*
+X2223262Y-1348486D1*
+G75*
+G01X2241707Y-1357553D2*
+G03X2241086Y-1357189I-2697J-3887D1*
+G74*
+X2303714Y-1400585D2*
+X2241707Y-1357553D1*
+G75*
+G01X2303714Y-1400585D2*
+G03X2314575Y-1403985I10861J15650D1*
+G74*
+X2316099Y-1403985D2*
+X2314575Y-1403985D1*
+X2321560Y-1403985D2*
+X2316099Y-1403985D1*
+X2342134Y-1434116D2*
+X2340610Y-1434116D1*
+X2343150Y-1435100D2*
+X2342134Y-1434116D1*
+G75*
+G01X2336510Y-1431746D2*
+G03X2340610Y-1434116I4100J2361D1*
+G74*
+X2324445Y-1410791D2*
+X2336510Y-1431746D1*
+G75*
+G01X2323814Y-1408430D2*
+G03X2324445Y-1410791I4731J0D1*
+G74*
+X2323814Y-1406906D2*
+X2323814Y-1408430D1*
+X2321560Y-1403985D2*
+X2323814Y-1406906D1*
+X1976867Y-1405977D2*
+X1948180Y-1424686D1*
+G75*
+G01X1979295Y-1405255D2*
+G03X1976867Y-1405977I0J-4445D1*
+G74*
+X1980819Y-1405255D2*
+X1979295Y-1405255D1*
+X1986280Y-1405255D2*
+X1980819Y-1405255D1*
+X2057095Y-1422400D2*
+X2057095Y-1426210D1*
+X2032000Y-1426210D2*
+X2057095Y-1426210D1*
+X2030476Y-1426210D2*
+X2032000Y-1426210D1*
+X2024380Y-1430020D2*
+X2030476Y-1426210D1*
+X2162099Y-1422400D2*
+X2162099Y-1416050D1*
+X2158104Y-1377164D2*
+X2162099Y-1416050D1*
+G75*
+G01X2158079Y-1376680D2*
+G03X2158104Y-1377164I4731J0D1*
+G74*
+X2158079Y-1375156D2*
+X2158079Y-1376680D1*
+X2152650Y-1369060D2*
+X2158079Y-1375156D1*
+X2232101Y-1422400D2*
+X2232101Y-1416050D1*
+X2232101Y-1376680D2*
+X2232101Y-1416050D1*
+X2232101Y-1375156D2*
+X2232101Y-1376680D1*
+X2228850Y-1369060D2*
+X2232101Y-1375156D1*
+X2393950Y-1439291D2*
+X2393950Y-1440815D1*
+X2393950Y-1435100D2*
+X2393950Y-1439291D1*
+G75*
+G01X2393626Y-1442056D2*
+G03X2393950Y-1440815I-2216J1241D1*
+G74*
+X2390595Y-1447470D2*
+X2393626Y-1442056D1*
+G75*
+G01X2378710Y-1454436D2*
+G03X2390595Y-1447470I0J13621D1*
+G74*
+X2366010Y-1454436D2*
+X2378710Y-1454436D1*
+G75*
+G01X2355488Y-1449464D2*
+G03X2366010Y-1454436I10522J8649D1*
+G74*
+X2350367Y-1443234D2*
+X2355488Y-1449464D1*
+G75*
+G01X2349500Y-1440815D2*
+G03X2350367Y-1443234I3810J0D1*
+G74*
+X2349500Y-1429385D2*
+X2349500Y-1440815D1*
+G75*
+G01X2349500Y-1429385D2*
+G03X2348927Y-1427376I-3810J0D1*
+G74*
+X2330785Y-1398150D2*
+X2348927Y-1427376D1*
+G75*
+G01X2330785Y-1398150D2*
+G03X2328545Y-1396904I-2240J-1390D1*
+G74*
+X2314575Y-1396904D2*
+X2328545Y-1396904D1*
+G75*
+G01X2305992Y-1393277D2*
+G03X2314575Y-1396904I8583J8342D1*
+G74*
+X2268383Y-1354577D2*
+X2305992Y-1393277D1*
+G75*
+G01X2268227Y-1354409D2*
+G03X2268383Y-1354577I3549J3129D1*
+G74*
+X2242559Y-1325291D2*
+X2268227Y-1354409D1*
+G75*
+G01X2242559Y-1325291D2*
+G03X2239010Y-1323689I-3549J-3129D1*
+G74*
+X2218690Y-1323689D2*
+X2239010Y-1323689D1*
+G75*
+G01X2218690Y-1323689D2*
+G03X2214436Y-1326349I0J-4731D1*
+G74*
+X2205031Y-1345667D2*
+X2214436Y-1326349D1*
+G75*
+G01X2200910Y-1348244D2*
+G03X2205031Y-1345667I0J4584D1*
+G74*
+X2180590Y-1348244D2*
+X2200910Y-1348244D1*
+G75*
+G01X2178188Y-1347565D2*
+G03X2180590Y-1348244I2402J3905D1*
+G74*
+X2165289Y-1339630D2*
+X2178188Y-1347565D1*
+G75*
+G01X2165289Y-1339630D2*
+G03X2162810Y-1338929I-2479J-4030D1*
+G74*
+X2161286Y-1338929D2*
+X2162810Y-1338929D1*
+X2152650Y-1336040D2*
+X2161286Y-1338929D1*
+X1924050Y-1430909D2*
+X1924050Y-1429385D1*
+X1924050Y-1435100D2*
+X1924050Y-1430909D1*
+G75*
+G01X1931192Y-1417966D2*
+G03X1924050Y-1429385I5558J-11419D1*
+G74*
+X1973334Y-1397453D2*
+X1931192Y-1417966D1*
+G75*
+G01X1978636Y-1396095D2*
+G03X1973334Y-1397453I659J-13605D1*
+G74*
+X1993494Y-1395375D2*
+X1978636Y-1396095D1*
+G75*
+G01X1993494Y-1395375D2*
+G03X1996876Y-1393706I-229J4725D1*
+G74*
+X2049344Y-1331714D2*
+X1996876Y-1393706D1*
+G75*
+G01X2052190Y-1330101D2*
+G03X2049344Y-1331714I765J-4669D1*
+G74*
+X2090925Y-1323751D2*
+X2052190Y-1330101D1*
+G75*
+G01X2091690Y-1323689D2*
+G03X2090925Y-1323751I0J-4731D1*
+G74*
+X2112010Y-1323689D2*
+X2091690Y-1323689D1*
+G75*
+G01X2113479Y-1323923D2*
+G03X2112010Y-1323689I-1469J-4497D1*
+G74*
+X2141021Y-1332917D2*
+X2113479Y-1323923D1*
+G75*
+G01X2141021Y-1332917D2*
+G03X2142490Y-1333151I1469J4497D1*
+G74*
+X2144014Y-1333151D2*
+X2142490Y-1333151D1*
+X2152650Y-1336040D2*
+X2144014Y-1333151D1*
+X1898650Y-1439291D2*
+X1898650Y-1440815D1*
+X1898650Y-1435100D2*
+X1898650Y-1439291D1*
+G75*
+G01X1898650Y-1440815D2*
+G03X1906745Y-1452651I12700J0D1*
+G74*
+X1908951Y-1453509D2*
+X1906745Y-1452651D1*
+G75*
+G01X1908951Y-1453509D2*
+G03X1913087Y-1454412I4939J12694D1*
+G74*
+X2363633Y-1481036D2*
+X1913087Y-1454412D1*
+G75*
+G01X2363633Y-1481036D2*
+G03X2366010Y-1481106I2377J40221D1*
+G74*
+X2378710Y-1481106D2*
+X2366010Y-1481106D1*
+G75*
+G01X2378710Y-1481106D2*
+G03X2406914Y-1469589I0J40291D1*
+G74*
+X2413391Y-1463240D2*
+X2406914Y-1469589D1*
+G75*
+G01X2413391Y-1463240D2*
+G03X2415196Y-1461314I-21981J22425D1*
+G74*
+X2431434Y-1442473D2*
+X2415196Y-1461314D1*
+G75*
+G01X2431434Y-1442473D2*
+G03X2432050Y-1440815I-1924J1658D1*
+G74*
+X2432050Y-1439291D2*
+X2432050Y-1440815D1*
+X2432050Y-1435100D2*
+X2432050Y-1439291D1*
+X2406650Y-1367409D2*
+X2406650Y-1365885D1*
+X2406650Y-1371600D2*
+X2406650Y-1367409D1*
+G75*
+G01X2406974Y-1364644D2*
+G03X2406650Y-1365885I2216J-1241D1*
+G74*
+X2410005Y-1359230D2*
+X2406974Y-1364644D1*
+G75*
+G01X2414404Y-1354505D2*
+G03X2410005Y-1359230I7486J-11380D1*
+G74*
+X2432050Y-1342898D2*
+X2414404Y-1354505D1*
+X2432050Y-1339850D2*
+X2432050Y-1342898D1*
+X2381250Y-1367409D2*
+X2381250Y-1365885D1*
+X2381250Y-1371600D2*
+X2381250Y-1367409D1*
+X2381250Y-1342898D2*
+X2381250Y-1365885D1*
+X2381250Y-1339850D2*
+X2381250Y-1342898D1*
+X2355850Y-1367409D2*
+X2355850Y-1365885D1*
+X2355850Y-1371600D2*
+X2355850Y-1367409D1*
+G75*
+G01X2355850Y-1365885D2*
+G03X2354965Y-1363958I-2540J0D1*
+G74*
+X2330450Y-1342898D2*
+X2354965Y-1363958D1*
+X2330450Y-1339850D2*
+X2330450Y-1342898D1*
+X2355850Y-1430909D2*
+X2355850Y-1429385D1*
+X2355850Y-1435100D2*
+X2355850Y-1430909D1*
+G75*
+G01X2355850Y-1429385D2*
+G03X2353999Y-1422782I-12700J0D1*
+G74*
+X2338770Y-1397762D2*
+X2353999Y-1422782D1*
+G75*
+G01X2338770Y-1397762D2*
+G03X2328545Y-1392015I-10225J-6223D1*
+G74*
+X2314575Y-1392015D2*
+X2328545Y-1392015D1*
+G75*
+G01X2312497Y-1391000D2*
+G03X2314575Y-1392015I2078J1620D1*
+G74*
+X2283793Y-1354189D2*
+X2312497Y-1391000D1*
+G75*
+G01X2282793Y-1351280D2*
+G03X2283793Y-1354189I4731J0D1*
+G74*
+X2282793Y-1349756D2*
+X2282793Y-1351280D1*
+X2279650Y-1339850D2*
+X2282793Y-1349756D1*
+X2419782Y-1174750D2*
+X2419782Y-1181100D1*
+X2457450Y-1260602D2*
+X2419782Y-1181100D1*
+X2457450Y-1263650D2*
+X2457450Y-1260602D1*
+X2349779Y-1174750D2*
+X2349779Y-1181100D1*
+X2406650Y-1260602D2*
+X2349779Y-1181100D1*
+X2406650Y-1263650D2*
+X2406650Y-1260602D1*
+X2279802Y-1174750D2*
+X2279802Y-1181100D1*
+X2355850Y-1260602D2*
+X2279802Y-1181100D1*
+X2355850Y-1263650D2*
+X2355850Y-1260602D1*
+X2209800Y-1174750D2*
+X2209800Y-1181100D1*
+X2305050Y-1260602D2*
+X2209800Y-1181100D1*
+X2305050Y-1263650D2*
+X2305050Y-1260602D1*
+X2174799Y-1174750D2*
+X2174799Y-1181100D1*
+X2279650Y-1260602D2*
+X2174799Y-1181100D1*
+X2279650Y-1263650D2*
+X2279650Y-1260602D1*
+X2244801Y-1174750D2*
+X2244801Y-1181100D1*
+X2330450Y-1260602D2*
+X2244801Y-1181100D1*
+X2330450Y-1263650D2*
+X2330450Y-1260602D1*
+X2314804Y-1174750D2*
+X2314804Y-1181100D1*
+X2381250Y-1260602D2*
+X2314804Y-1181100D1*
+X2381250Y-1263650D2*
+X2381250Y-1260602D1*
+X2384781Y-1174750D2*
+X2384781Y-1181100D1*
+X2432050Y-1260602D2*
+X2384781Y-1181100D1*
+X2432050Y-1263650D2*
+X2432050Y-1260602D1*
+X2454783Y-1174750D2*
+X2454783Y-1181100D1*
+X2482850Y-1260602D2*
+X2454783Y-1181100D1*
+X2482850Y-1263650D2*
+X2482850Y-1260602D1*
+X2305050Y-1339850D2*
+X2305050Y-1342898D1*
+X2337614Y-1369546D2*
+X2305050Y-1342898D1*
+G75*
+G01X2337614Y-1369546D2*
+G03X2340610Y-1370616I2996J3661D1*
+G74*
+X2342134Y-1370616D2*
+X2340610Y-1370616D1*
+X2343150Y-1371600D2*
+X2342134Y-1370616D1*
+X2368550Y-1367409D2*
+X2368550Y-1365885D1*
+X2368550Y-1371600D2*
+X2368550Y-1367409D1*
+G75*
+G01X2368550Y-1365885D2*
+G03X2368226Y-1364644I-2540J0D1*
+G74*
+X2365195Y-1359230D2*
+X2368226Y-1364644D1*
+X2365195Y-1359230D2*
+X2365132Y-1359120D1*
+X2355850Y-1342898D2*
+X2365132Y-1359120D1*
+X2355850Y-1339850D2*
+X2355850Y-1342898D1*
+X2393950Y-1367409D2*
+X2393950Y-1365885D1*
+X2393950Y-1371600D2*
+X2393950Y-1367409D1*
+G75*
+G01X2394274Y-1364644D2*
+G03X2393950Y-1365885I2216J-1241D1*
+G74*
+X2397305Y-1359230D2*
+X2394274Y-1364644D1*
+X2397368Y-1359120D2*
+X2397305Y-1359230D1*
+X2406650Y-1342898D2*
+X2397368Y-1359120D1*
+X2406650Y-1339850D2*
+X2406650Y-1342898D1*
+X2419350Y-1367409D2*
+X2419350Y-1365885D1*
+X2419350Y-1371600D2*
+X2419350Y-1367409D1*
+G75*
+G01X2420712Y-1363635D2*
+G03X2419350Y-1365885I1178J-2250D1*
+G74*
+X2438132Y-1354515D2*
+X2420712Y-1363635D1*
+G75*
+G01X2438132Y-1354515D2*
+G03X2438820Y-1354128I-6082J11617D1*
+G74*
+X2457450Y-1342898D2*
+X2438820Y-1354128D1*
+X2457450Y-1339850D2*
+X2457450Y-1342898D1*
+X1936750Y-1367409D2*
+X1936750Y-1365885D1*
+X1936750Y-1371600D2*
+X1936750Y-1367409D1*
+G75*
+G01X1937074Y-1364644D2*
+G03X1936750Y-1365885I2216J-1241D1*
+G74*
+X1940105Y-1359230D2*
+X1937074Y-1364644D1*
+G75*
+G01X1944504Y-1354505D2*
+G03X1940105Y-1359230I7486J-11380D1*
+G74*
+X1962150Y-1342898D2*
+X1944504Y-1354505D1*
+X1962150Y-1339850D2*
+X1962150Y-1342898D1*
+X1911350Y-1367409D2*
+X1911350Y-1365885D1*
+X1911350Y-1371600D2*
+X1911350Y-1367409D1*
+X1911350Y-1342898D2*
+X1911350Y-1365885D1*
+X1911350Y-1339850D2*
+X1911350Y-1342898D1*
+X1885950Y-1367409D2*
+X1885950Y-1365885D1*
+X1885950Y-1371600D2*
+X1885950Y-1367409D1*
+G75*
+G01X1885950Y-1365885D2*
+G03X1885065Y-1363958I-2540J0D1*
+G74*
+X1860550Y-1342898D2*
+X1885065Y-1363958D1*
+X1860550Y-1339850D2*
+X1860550Y-1342898D1*
+X1885950Y-1430909D2*
+X1885950Y-1429385D1*
+X1885950Y-1435100D2*
+X1885950Y-1430909D1*
+G75*
+G01X1885950Y-1429385D2*
+G03X1885387Y-1427791I-2540J0D1*
+G74*
+X1821307Y-1348311D2*
+X1885387Y-1427791D1*
+G75*
+G01X1821307Y-1348311D2*
+G03X1817624Y-1346549I-3683J-2969D1*
+G74*
+X1816100Y-1346549D2*
+X1817624Y-1346549D1*
+X1809750Y-1339850D2*
+X1816100Y-1346549D1*
+X2045132Y-1174750D2*
+X2045132Y-1181100D1*
+X1987550Y-1260602D2*
+X2045132Y-1181100D1*
+X1987550Y-1263650D2*
+X1987550Y-1260602D1*
+X1975129Y-1174750D2*
+X1975129Y-1181100D1*
+X1936750Y-1260602D2*
+X1975129Y-1181100D1*
+X1936750Y-1263650D2*
+X1936750Y-1260602D1*
+X1905152Y-1174750D2*
+X1905152Y-1181100D1*
+X1885950Y-1260602D2*
+X1905152Y-1181100D1*
+X1885950Y-1263650D2*
+X1885950Y-1260602D1*
+X1835150Y-1174750D2*
+X1835150Y-1181100D1*
+X1835150Y-1260602D2*
+X1835150Y-1181100D1*
+X1835150Y-1263650D2*
+X1835150Y-1260602D1*
+X1800149Y-1174750D2*
+X1800149Y-1181100D1*
+X1809750Y-1260602D2*
+X1800149Y-1181100D1*
+X1809750Y-1263650D2*
+X1809750Y-1260602D1*
+X1870151Y-1174750D2*
+X1870151Y-1181100D1*
+X1860550Y-1260602D2*
+X1870151Y-1181100D1*
+X1860550Y-1263650D2*
+X1860550Y-1260602D1*
+X1940154Y-1174750D2*
+X1940154Y-1181100D1*
+X1911350Y-1260602D2*
+X1940154Y-1181100D1*
+X1911350Y-1263650D2*
+X1911350Y-1260602D1*
+X2010131Y-1174750D2*
+X2010131Y-1181100D1*
+X1962150Y-1260602D2*
+X2010131Y-1181100D1*
+X1962150Y-1263650D2*
+X1962150Y-1260602D1*
+X2080133Y-1174750D2*
+X2080133Y-1181100D1*
+X2012950Y-1260602D2*
+X2080133Y-1181100D1*
+X2012950Y-1263650D2*
+X2012950Y-1260602D1*
+X1835150Y-1339850D2*
+X1835150Y-1342898D1*
+X1867714Y-1369546D2*
+X1835150Y-1342898D1*
+G75*
+G01X1867714Y-1369546D2*
+G03X1870710Y-1370616I2996J3661D1*
+G74*
+X1872234Y-1370616D2*
+X1870710Y-1370616D1*
+X1873250Y-1371600D2*
+X1872234Y-1370616D1*
+X1898650Y-1367409D2*
+X1898650Y-1365885D1*
+X1898650Y-1371600D2*
+X1898650Y-1367409D1*
+G75*
+G01X1898650Y-1365885D2*
+G03X1898326Y-1364644I-2540J0D1*
+G74*
+X1895295Y-1359230D2*
+X1898326Y-1364644D1*
+X1895295Y-1359230D2*
+X1895232Y-1359120D1*
+X1885950Y-1342898D2*
+X1895232Y-1359120D1*
+X1885950Y-1339850D2*
+X1885950Y-1342898D1*
+X1924050Y-1367409D2*
+X1924050Y-1365885D1*
+X1924050Y-1371600D2*
+X1924050Y-1367409D1*
+G75*
+G01X1924374Y-1364644D2*
+G03X1924050Y-1365885I2216J-1241D1*
+G74*
+X1927405Y-1359230D2*
+X1924374Y-1364644D1*
+X1927468Y-1359120D2*
+X1927405Y-1359230D1*
+X1936750Y-1342898D2*
+X1927468Y-1359120D1*
+X1936750Y-1339850D2*
+X1936750Y-1342898D1*
+X1949450Y-1367409D2*
+X1949450Y-1365885D1*
+X1949450Y-1371600D2*
+X1949450Y-1367409D1*
+G75*
+G01X1950812Y-1363635D2*
+G03X1949450Y-1365885I1178J-2250D1*
+G74*
+X1968232Y-1354515D2*
+X1950812Y-1363635D1*
+G75*
+G01X1968232Y-1354515D2*
+G03X1968920Y-1354128I-6082J11617D1*
+G74*
+X1987550Y-1342898D2*
+X1968920Y-1354128D1*
+X1987550Y-1339850D2*
+X1987550Y-1342898D1*
+X1963166Y-1434116D2*
+X1964690Y-1434116D1*
+X1962150Y-1435100D2*
+X1963166Y-1434116D1*
+X1983740Y-1434116D2*
+X1964690Y-1434116D1*
+X1985264Y-1434116D2*
+X1983740Y-1434116D1*
+X1991360Y-1430020D2*
+X1985264Y-1434116D1*
+X2368550Y-1430909D2*
+X2368550Y-1429385D1*
+X2368550Y-1435100D2*
+X2368550Y-1430909D1*
+G75*
+G01X2368550Y-1429385D2*
+G03X2365950Y-1417614I-27940J0D1*
+G74*
+X2355802Y-1395769D2*
+X2365950Y-1417614D1*
+G75*
+G01X2355802Y-1395769D2*
+G03X2339520Y-1380452I-27257J-12661D1*
+G74*
+X2339398Y-1380404D2*
+X2339520Y-1380452D1*
+G75*
+G01X2338811Y-1380103D2*
+G03X2339398Y-1380404I1799J2788D1*
+G74*
+X2298026Y-1353782D2*
+X2338811Y-1380103D1*
+G75*
+G01X2292096Y-1342898D2*
+G03X2298026Y-1353782I12954J0D1*
+G74*
+X2292096Y-1336802D2*
+X2292096Y-1342898D1*
+G75*
+G01X2292112Y-1336162D2*
+G03X2292096Y-1336802I12938J-640D1*
+G74*
+X2292249Y-1333385D2*
+X2292112Y-1336162D1*
+G75*
+G01X2292249Y-1333385D2*
+G03X2292255Y-1333151I-4725J234D1*
+G74*
+X2292255Y-1328420D2*
+X2292255Y-1333151D1*
+G75*
+G01X2292255Y-1328420D2*
+G03X2288391Y-1323769I-4731J0D1*
+G74*
+X2241506Y-1315030D2*
+X2288391Y-1323769D1*
+G75*
+G01X2241506Y-1315030D2*
+G03X2239010Y-1314799I-2496J-13390D1*
+G74*
+X2218690Y-1314799D2*
+X2239010Y-1314799D1*
+G75*
+G01X2218690Y-1314799D2*
+G03X2211879Y-1316624I0J-13621D1*
+G74*
+X2198544Y-1324323D2*
+X2211879Y-1316624D1*
+G75*
+G01X2198544Y-1324323D2*
+G03X2196179Y-1328420I2366J-4097D1*
+G74*
+X2196179Y-1329944D2*
+X2196179Y-1328420D1*
+X2190750Y-1336040D2*
+X2196179Y-1329944D1*
+X1936750Y-1439291D2*
+X1936750Y-1440815D1*
+X1936750Y-1435100D2*
+X1936750Y-1439291D1*
+G75*
+G01X1936750Y-1440815D2*
+G03X1938560Y-1443248I2540J0D1*
+G74*
+X1945550Y-1445346D2*
+X1938560Y-1443248D1*
+G75*
+G01X1945550Y-1445346D2*
+G03X1946728Y-1445543I1360J4531D1*
+G74*
+X2161137Y-1453783D2*
+X1946728Y-1445543D1*
+G75*
+G01X2161137Y-1453783D2*
+G03X2162099Y-1453801I962J25033D1*
+G74*
+X2261870Y-1453801D2*
+X2162099Y-1453801D1*
+X2263394Y-1453801D2*
+X2261870Y-1453801D1*
+X2272030Y-1451610D2*
+X2263394Y-1453801D1*
+X2406650Y-1439291D2*
+X2406650Y-1440815D1*
+X2406650Y-1435100D2*
+X2406650Y-1439291D1*
+G75*
+G01X2391400Y-1465707D2*
+G03X2406650Y-1440815I-12690J24892D1*
+G74*
+X2385352Y-1468790D2*
+X2391400Y-1465707D1*
+G75*
+G01X2371090Y-1472216D2*
+G03X2385352Y-1468790I0J31401D1*
+G74*
+X2366010Y-1472216D2*
+X2371090Y-1472216D1*
+G75*
+G01X2359209Y-1471471D2*
+G03X2366010Y-1472216I6801J30656D1*
+G74*
+X2283215Y-1454611D2*
+X2359209Y-1471471D1*
+G75*
+G01X2283215Y-1454611D2*
+G03X2282190Y-1454499I-1025J-4619D1*
+G74*
+X2280666Y-1454499D2*
+X2282190Y-1454499D1*
+X2272030Y-1451610D2*
+X2280666Y-1454499D1*
+X2197100Y-1422400D2*
+X2197100Y-1416050D1*
+X2196180Y-1376791D2*
+X2197100Y-1416050D1*
+G75*
+G01X2196179Y-1376680D2*
+G03X2196180Y-1376791I4731J0D1*
+G74*
+X2196179Y-1375156D2*
+X2196179Y-1376680D1*
+X2190750Y-1369060D2*
+X2196179Y-1375156D1*
+X2127098Y-1422400D2*
+X2127098Y-1428750D1*
+X2154637Y-1443085D2*
+X2127098Y-1428750D1*
+G75*
+G01X2154637Y-1443085D2*
+G03X2162099Y-1444911I7462J14335D1*
+G74*
+X2232101Y-1444911D2*
+X2162099Y-1444911D1*
+G75*
+G01X2232101Y-1444911D2*
+G03X2244343Y-1439300I0J16161D1*
+G74*
+X2258286Y-1423121D2*
+X2244343Y-1439300D1*
+G75*
+G01X2261870Y-1421479D2*
+G03X2258286Y-1423121I0J-4731D1*
+G74*
+X2263394Y-1421479D2*
+X2261870Y-1421479D1*
+X2272030Y-1418590D2*
+X2263394Y-1421479D1*
+X2115134Y-1174750D2*
+X2115134Y-1181100D1*
+X2012950Y-1336802D2*
+X2115134Y-1181100D1*
+X2012950Y-1339850D2*
+X2012950Y-1336802D1*
+X2012950Y-1342898D2*
+X1982470Y-1376426D1*
+X2012950Y-1339850D2*
+X2012950Y-1342898D1*
+X2489784Y-1174750D2*
+X2489784Y-1181100D1*
+X2495923Y-1259579D2*
+X2489784Y-1181100D1*
+G75*
+G01X2495963Y-1260602D2*
+G03X2495923Y-1259579I-13113J0D1*
+G74*
+X2495963Y-1266698D2*
+X2495963Y-1260602D1*
+G75*
+G01X2495732Y-1269151D2*
+G03X2495963Y-1266698I-12882J2453D1*
+G74*
+X2482850Y-1336802D2*
+X2495732Y-1269151D1*
+X2482850Y-1339850D2*
+X2482850Y-1336802D1*
+X1911350Y-1430909D2*
+X1911350Y-1429385D1*
+X1911350Y-1435100D2*
+X1911350Y-1430909D1*
+G75*
+G01X1911394Y-1428916D2*
+G03X1911350Y-1429385I2496J-469D1*
+G74*
+X1912086Y-1425231D2*
+X1911394Y-1428916D1*
+G75*
+G01X1920235Y-1411738D2*
+G03X1912086Y-1425231I13975J-17647D1*
+G74*
+X1961187Y-1379306D2*
+X1920235Y-1411738D1*
+G75*
+G01X1961187Y-1379306D2*
+G03X1962150Y-1377315I-1577J1991D1*
+G74*
+X1962150Y-1375791D2*
+X1962150Y-1377315D1*
+X1962150Y-1371600D2*
+X1962150Y-1375791D1*
+X1965718Y-1372697D2*
+X1982470Y-1376426D1*
+G75*
+G01X1965718Y-1372697D2*
+G03X1964690Y-1372584I-1028J-4618D1*
+G74*
+X1963166Y-1372584D2*
+X1964690Y-1372584D1*
+X1962150Y-1371600D2*
+X1963166Y-1372584D1*
+X2381250Y-1430909D2*
+X2381250Y-1429385D1*
+X2381250Y-1435100D2*
+X2381250Y-1430909D1*
+G75*
+G01X2382009Y-1427574D2*
+G03X2381250Y-1429385I1781J-1811D1*
+G74*
+X2431291Y-1379126D2*
+X2382009Y-1427574D1*
+G75*
+G01X2431291Y-1379126D2*
+G03X2432050Y-1377315I-1781J1811D1*
+G74*
+X2432050Y-1375791D2*
+X2432050Y-1377315D1*
+X2432050Y-1371600D2*
+X2432050Y-1375791D1*
+X2482850Y-1339850D2*
+X2482850Y-1342898D1*
+X2464220Y-1354128D2*
+X2482850Y-1342898D1*
+G75*
+G01X2464041Y-1354234D2*
+G03X2464220Y-1354128I-6591J11336D1*
+G74*
+X2436968Y-1369975D2*
+X2464041Y-1354234D1*
+G75*
+G01X2434590Y-1370616D2*
+G03X2436968Y-1369975I0J4731D1*
+G74*
+X2433066Y-1370616D2*
+X2434590Y-1370616D1*
+X2432050Y-1371600D2*
+X2433066Y-1370616D1*
+X2115134Y-1174750D2*
+X2115134Y-1168400D1*
+X2170422Y-1152843D2*
+X2115134Y-1168400D1*
+G75*
+G01X2174799Y-1152239D2*
+G03X2170422Y-1152843I0J-16161D1*
+G74*
+X2454783Y-1152239D2*
+X2174799Y-1152239D1*
+G75*
+G01X2462245Y-1154065D2*
+G03X2454783Y-1152239I-7462J-14335D1*
+G74*
+X2489784Y-1168400D2*
+X2462245Y-1154065D1*
+X2489784Y-1174750D2*
+X2489784Y-1168400D1*
+X2092096Y-1422400D2*
+X2092096Y-1416050D1*
+X2096392Y-1377200D2*
+X2092096Y-1416050D1*
+G75*
+G01X2096392Y-1377200D2*
+G03X2096421Y-1376680I-4702J520D1*
+G74*
+X2096421Y-1375156D2*
+X2096421Y-1376680D1*
+X2101850Y-1369060D2*
+X2096421Y-1375156D1*
+X2381250Y-1439291D2*
+X2381250Y-1440815D1*
+X2381250Y-1435100D2*
+X2381250Y-1439291D1*
+G75*
+G01X2379440Y-1443248D2*
+G03X2381250Y-1440815I-730J2433D1*
+G74*
+X2372450Y-1445346D2*
+X2379440Y-1443248D1*
+G75*
+G01X2371090Y-1445546D2*
+G03X2372450Y-1445346I0J4731D1*
+G74*
+X2368550Y-1445546D2*
+X2371090Y-1445546D1*
+G75*
+G01X2366835Y-1445224D2*
+G03X2368550Y-1445546I1715J4409D1*
+G74*
+X2364628Y-1444366D2*
+X2366835Y-1445224D1*
+G75*
+G01X2362200Y-1440815D2*
+G03X2364628Y-1444366I3810J0D1*
+G74*
+X2362200Y-1429385D2*
+X2362200Y-1440815D1*
+G75*
+G01X2362200Y-1429385D2*
+G03X2360110Y-1420710I-19050J0D1*
+G74*
+X2348587Y-1398179D2*
+X2360110Y-1420710D1*
+G75*
+G01X2348587Y-1398179D2*
+G03X2342670Y-1390902I-20042J-10251D1*
+G74*
+X2340499Y-1389152D2*
+X2342670Y-1390902D1*
+G75*
+G01X2340499Y-1389152D2*
+G03X2328545Y-1384935I-11954J-14833D1*
+G74*
+X2327021Y-1384935D2*
+X2328545Y-1384935D1*
+X2321560Y-1384935D2*
+X2327021Y-1384935D1*
+X1983771Y-1380228D2*
+X1982470Y-1376426D1*
+G75*
+G01X1984026Y-1381760D2*
+G03X1983771Y-1380228I-4731J0D1*
+G74*
+X1984026Y-1383284D2*
+X1984026Y-1381760D1*
+X1986280Y-1386205D2*
+X1984026Y-1383284D1*
+G54D19*
+X2279650Y-1260602D2*
+X2279650Y-1266698D1*
+X2305050Y-1260602D2*
+X2305050Y-1266698D1*
+X2330450Y-1260602D2*
+X2330450Y-1266698D1*
+X2355850Y-1260602D2*
+X2355850Y-1266698D1*
+X2381250Y-1260602D2*
+X2381250Y-1266698D1*
+X2406650Y-1260602D2*
+X2406650Y-1266698D1*
+X2432050Y-1260602D2*
+X2432050Y-1266698D1*
+X2457450Y-1260602D2*
+X2457450Y-1266698D1*
+X2482850Y-1260602D2*
+X2482850Y-1266698D1*
+X2482850Y-1336802D2*
+X2482850Y-1342898D1*
+X2457450Y-1336802D2*
+X2457450Y-1342898D1*
+X2432050Y-1336802D2*
+X2432050Y-1342898D1*
+X2406650Y-1336802D2*
+X2406650Y-1342898D1*
+X2381250Y-1336802D2*
+X2381250Y-1342898D1*
+X2355850Y-1336802D2*
+X2355850Y-1342898D1*
+X2330450Y-1336802D2*
+X2330450Y-1342898D1*
+X2305050Y-1336802D2*
+X2305050Y-1342898D1*
+X1809750Y-1260602D2*
+X1809750Y-1266698D1*
+X1835150Y-1260602D2*
+X1835150Y-1266698D1*
+X1860550Y-1260602D2*
+X1860550Y-1266698D1*
+X1885950Y-1260602D2*
+X1885950Y-1266698D1*
+X1911350Y-1260602D2*
+X1911350Y-1266698D1*
+X1936750Y-1260602D2*
+X1936750Y-1266698D1*
+X1962150Y-1260602D2*
+X1962150Y-1266698D1*
+X1987550Y-1260602D2*
+X1987550Y-1266698D1*
+X2012950Y-1260602D2*
+X2012950Y-1266698D1*
+X2012950Y-1336802D2*
+X2012950Y-1342898D1*
+X1987550Y-1336802D2*
+X1987550Y-1342898D1*
+X1962150Y-1336802D2*
+X1962150Y-1342898D1*
+X1936750Y-1336802D2*
+X1936750Y-1342898D1*
+X1911350Y-1336802D2*
+X1911350Y-1342898D1*
+X1885950Y-1336802D2*
+X1885950Y-1342898D1*
+X1860550Y-1336802D2*
+X1860550Y-1342898D1*
+X1835150Y-1336802D2*
+X1835150Y-1342898D1*
+G54D22*
+X2162099Y-1428750D2*
+X2162099Y-1416050D1*
+X2197100Y-1428750D2*
+X2197100Y-1416050D1*
+X2232101Y-1428750D2*
+X2232101Y-1416050D1*
+X2127098Y-1428750D2*
+X2127098Y-1416050D1*
+X2057095Y-1428750D2*
+X2057095Y-1416050D1*
+X2092096Y-1428750D2*
+X2092096Y-1416050D1*
+X2244801Y-1168400D2*
+X2244801Y-1181100D1*
+X2209800Y-1168400D2*
+X2209800Y-1181100D1*
+X2174799Y-1168400D2*
+X2174799Y-1181100D1*
+X2279802Y-1168400D2*
+X2279802Y-1181100D1*
+X2314804Y-1168400D2*
+X2314804Y-1181100D1*
+X2489784Y-1168400D2*
+X2489784Y-1181100D1*
+X2454783Y-1168400D2*
+X2454783Y-1181100D1*
+X2349779Y-1168400D2*
+X2349779Y-1181100D1*
+X2384781Y-1168400D2*
+X2384781Y-1181100D1*
+X2419782Y-1168400D2*
+X2419782Y-1181100D1*
+X1870151Y-1168400D2*
+X1870151Y-1181100D1*
+X1835150Y-1168400D2*
+X1835150Y-1181100D1*
+X1800149Y-1168400D2*
+X1800149Y-1181100D1*
+X1905152Y-1168400D2*
+X1905152Y-1181100D1*
+X1940154Y-1168400D2*
+X1940154Y-1181100D1*
+X2115134Y-1168400D2*
+X2115134Y-1181100D1*
+X2080133Y-1168400D2*
+X2080133Y-1181100D1*
+X1975129Y-1168400D2*
+X1975129Y-1181100D1*
+X2010131Y-1168400D2*
+X2010131Y-1181100D1*
+X2045132Y-1168400D2*
+X2045132Y-1181100D1*
+M02*
diff --git a/gerbview/gerber_test_files/octogonal.gbr b/gerbview/gerber_test_files/octogonal.gbr
new file mode 100644
index 0000000..909872d
--- /dev/null
+++ b/gerbview/gerber_test_files/octogonal.gbr
@@ -0,0 +1,27 @@
+*
+%FSLAX26Y26*%
+%MOIN*%
+G04 A4 - i274x.oc8.d36 *
+%AMA4top*
+4,1,8,
+0.034500,0.014290,
+0.034500,-0.014290,
+0.014290,-0.034500,
+-0.014290,-0.034500,
+-0.034500,-0.014290,
+-0.034500,0.014290,
+-0.014290,0.034500,
+0.014290,0.034500,
+0.034500,0.014290,
+0.0000*
+%
+%ADD40A4top*%
+%IPPOS*%
+%LNfp0149448top.gbx*%
+%LPD*%
+G75*
+G54D40*
+X04750000Y00344900D03*
+X04856300Y00246400D03*
+X04750000Y00148000D03*
+M02*
diff --git a/gerbview/gerber_test_files/test-aperture-polygon-flash.gbr b/gerbview/gerber_test_files/test-aperture-polygon-flash.gbr
new file mode 100644
index 0000000..788a755
--- /dev/null
+++ b/gerbview/gerber_test_files/test-aperture-polygon-flash.gbr
@@ -0,0 +1,27 @@
+G04 Test flashing of polygon apertures*
+G04 Four groups of polygon apertures are arranged in a square*
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%ADD10P,0.050X3*%
+%ADD11P,0.050X6X-45X0.035*%
+%ADD12P,0.040X10X25X0.025X0.025X0.0150*%
+
+G04 Triangle, centered at 0,0 *
+G54D10*
+X0Y0D03*
+
+G04 Hexagon with round hole rotate 45 degreed ccwise, centered at 0.1,0 *
+G54D11*
+X00100Y0D03*
+
+G04 10-sided with square hole rotated 25 degrees, centered at 0,0.1 *
+G54D12*
+X0Y00100D03*
+
+G04 Two, with round holes, slightly overlapping, centered at 0.1,0.1 *
+G54D11*
+X00100Y00090D03*
+X00100Y00110D03*
+
+M02*
diff --git a/gerbview/gerber_test_files/test-aperture-rectangle-flash-with_hole.gbr b/gerbview/gerber_test_files/test-aperture-rectangle-flash-with_hole.gbr
new file mode 100644
index 0000000..8aeb79c
--- /dev/null
+++ b/gerbview/gerber_test_files/test-aperture-rectangle-flash-with_hole.gbr
@@ -0,0 +1,27 @@
+G04 Test flashing of rectangular apertures*
+G04 Four groups of rectangular apertures are arranged in a square*
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%ADD10R,0.050X0.080*%
+%ADD11R,0.080X0.050X0.025*%
+%ADD12R,0.050X0.025X0.025X0.0150*%
+
+G04 No hole, centered at 0,0 *
+G54D10*
+X0Y0D03*
+
+G04 Round hole, centered at 0.1,0 *
+G54D11*
+X00100Y0D03*
+
+G04 Square hole, centered at 0,0.1 *
+G54D12*
+X0Y00100D03*
+
+G04 Two, with round holes, slightly overlapping, centered at 0.1,0.1 *
+G54D11*
+X00100Y00090D03*
+X00100Y00110D03*
+
+M02*
diff --git a/gerbview/gerber_test_files/test-image-justify-with-offset.gbr b/gerbview/gerber_test_files/test-image-justify-with-offset.gbr
new file mode 100644
index 0000000..6e71d62
--- /dev/null
+++ b/gerbview/gerber_test_files/test-image-justify-with-offset.gbr
@@ -0,0 +1,19 @@
+G04 Test image justify 1*
+G04 Crosshairs should be justified to the X axis *
+G04 and 0.5 inches offset from Y axis *
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%IJB.5*%
+%ADD10C,0.050*%
+
+G04 Crosshairs *
+X-1000Y0D02*
+G54D10*
+X1000Y0D01*
+
+X0Y-1000D02*
+G54D10*
+X0Y1000D01*
+
+M02*
diff --git a/gerbview/gerber_test_files/test-image-offset.gbr b/gerbview/gerber_test_files/test-image-offset.gbr
new file mode 100644
index 0000000..11242cf
--- /dev/null
+++ b/gerbview/gerber_test_files/test-image-offset.gbr
@@ -0,0 +1,18 @@
+G04 Test image offset *
+G04 Crosshairs should be centered on 0,0 in final rendering*
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%IOA-2.0B-1.0*%
+%ADD10C,0.050*%
+
+G04 Crosshairs to be on 0,0 *
+X1000Y1000D02*
+G54D10*
+X3000Y1000D01*
+
+X2000Y0D02*
+G54D10*
+X2000Y2000D01*
+
+M02*
diff --git a/gerbview/gerber_test_files/test-image-polarity.gbr b/gerbview/gerber_test_files/test-image-polarity.gbr
new file mode 100644
index 0000000..e012966
--- /dev/null
+++ b/gerbview/gerber_test_files/test-image-polarity.gbr
@@ -0,0 +1,17 @@
+G04 Test image polarity *
+G04 Crosshairs should be cut out of a positive background*
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%IPNEG*%
+%ADD10C,0.050*%
+
+G04 Draw crosshairs *
+X-1000Y0D02*
+G54D10*
+X1000Y0D01*
+X0Y-1000D02*
+G54D10*
+X0Y1000D01*
+
+M02*
diff --git a/gerbview/gerber_test_files/test-image-rotation.gbr b/gerbview/gerber_test_files/test-image-rotation.gbr
new file mode 100644
index 0000000..c136b5b
--- /dev/null
+++ b/gerbview/gerber_test_files/test-image-rotation.gbr
@@ -0,0 +1,21 @@
+G04 Test image rotation *
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%IR270*%
+%ADD10C,0.050*%
+
+G04 Quarter star *
+X1000Y0D02*
+G54D10*
+X2000Y0D01*
+
+X1000Y0D02*
+G54D10*
+X2000Y1000D01*
+
+X1000Y0D02*
+G54D10*
+X1000Y1000D01*
+
+M02*
diff --git a/gerbview/gerber_test_files/test-layer-axis-select.gbr b/gerbview/gerber_test_files/test-layer-axis-select.gbr
new file mode 100644
index 0000000..d5f003e
--- /dev/null
+++ b/gerbview/gerber_test_files/test-layer-axis-select.gbr
@@ -0,0 +1,15 @@
+G04 Test layer axis select *
+G04 Line is drawn along A axis, then axis select switches it and renders *
+G04 line along y axis *
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%ASAYBX*%
+%ADD10C,0.050*%
+
+G04 Draw line *
+X-1000Y0D02*
+G54D10*
+X1000Y0D01*
+
+M02*
diff --git a/gerbview/gerber_test_files/test-layer-mixed_units_mode.gbr b/gerbview/gerber_test_files/test-layer-mixed_units_mode.gbr
new file mode 100644
index 0000000..95b8555
--- /dev/null
+++ b/gerbview/gerber_test_files/test-layer-mixed_units_mode.gbr
@@ -0,0 +1,68 @@
+G04 Test handling of unit changes within a RS274X file *
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+G04 Aperture 10 should be in Inches *
+%ADD10C,0.050*%
+%MOMM*%
+G04 Aperture 11 should be in MMs *
+%ADD11C,1.250*%
+G04 Aperture 12 should be in MMs *
+%AMTHERMAL*
+7,0,0,25.4,12.7,2.54,0*%
+%MOIN*%
+G04 Aperture 13 is in inches *
+%AMTHERMALTWO*
+7,0,0,1,0.5,0.1,0*%
+%MOMM*%
+%ADD12THERMAL*%
+%MOIN*%
+%ADD13THERMALTWO*%
+
+%MOIN*%
+G04 Box 1, using aperture 10*
+X0Y0D02*
+G54D10*
+X0Y0D01*
+X1000D01*
+Y1000D01*
+X0D01*
+Y0D01*
+
+G04 Box 2, using aperture 11*
+X2000Y0D02*
+G54D11*
+X2000Y0D01*
+X3000D01*
+Y1000D01*
+X2000D01*
+Y0D01*
+
+%MOMM*%
+G04 Box 3, using aperture 10*
+X100000Y0D02*
+G54D10*
+X100000Y0D01*
+X125000D01*
+Y25000D01*
+X100000D01*
+Y0D01*
+
+G04 Draw Thermal in box 1*
+G54D12*
+Y12000X12700D03*
+
+G04 Draw Thermal in box 2*
+G04 ..switch to inches for coordinates*
+G70*
+Y500X2500D02*
+G54D12*
+Y500X2500D03*
+
+G04 ..switch to mms for coordinates*
+G71*
+G04 Draw Thermal in box 3*
+G54D13*
+Y12000X112000D03*
+
+M02*
diff --git a/gerbview/gerber_test_files/test-layer-rotation.gbr b/gerbview/gerber_test_files/test-layer-rotation.gbr
new file mode 100644
index 0000000..1c3696a
--- /dev/null
+++ b/gerbview/gerber_test_files/test-layer-rotation.gbr
@@ -0,0 +1,23 @@
+G04 Test layer rotation 1 *
+G04 Quarter star should be rotated 45 degrees counterclockwise, pointing*
+G04 the center line straight up *
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%RO45.0*%
+%ADD10C,0.025*%
+
+G04 Quarter star *
+X1000Y0D02*
+G54D10*
+X2000Y0D01*
+
+X1000Y0D02*
+G54D10*
+X2000Y1000D01*
+
+X1000Y0D02*
+G54D10*
+X1000Y1000D01*
+
+M02*
diff --git a/gerbview/gerber_test_files/test-layer-scale-factor.gbr b/gerbview/gerber_test_files/test-layer-scale-factor.gbr
new file mode 100644
index 0000000..02a7b7d
--- /dev/null
+++ b/gerbview/gerber_test_files/test-layer-scale-factor.gbr
@@ -0,0 +1,17 @@
+G04 Test layer scale factor 1 *
+G04 Crosshairs should be centered on 0,0 and 2 inches wide and 1 inch tall*
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%SFA2B1*%
+%ADD10C,0.025*%
+
+G04 Crosshairs to be on 0,0 *
+X-500Y0D02*
+G54D10*
+X500Y0D01*
+X0Y-500D02*
+G54D10*
+X0Y500D01*
+
+M02*
diff --git a/gerbview/gerber_test_files/test-layer-step-and_repeat-cross.gbr b/gerbview/gerber_test_files/test-layer-step-and_repeat-cross.gbr
new file mode 100644
index 0000000..4f69391
--- /dev/null
+++ b/gerbview/gerber_test_files/test-layer-step-and_repeat-cross.gbr
@@ -0,0 +1,17 @@
+G04 Test step and repeat 1*
+G04 Repeat a crosshair 3 times in the x direction and 2 times in the Y *
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%SRX3Y2I5.0J2*%
+%ADD10C,0.050*%
+
+G04 Draw crosshairs *
+X-1000Y0D02*
+G54D10*
+X1000Y0D01*
+X0Y-1000D02*
+G54D10*
+X0Y1000D01*
+
+M02*
diff --git a/gerbview/gerber_test_files/test-layer-step-and_repeat-polygon.gbr b/gerbview/gerber_test_files/test-layer-step-and_repeat-polygon.gbr
new file mode 100644
index 0000000..392036f
--- /dev/null
+++ b/gerbview/gerber_test_files/test-layer-step-and_repeat-polygon.gbr
@@ -0,0 +1,18 @@
+G04 Test step and repeat 1*
+G04 Repeat a crosshair 3 times in the x direction and 2 times in the Y *
+G04 Handcoded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%SRX3Y2I1J1*%
+%ADD10C,0.050*%
+
+G04 Draw a simple square*
+G36*
+G01X00400Y0D02*
+X00600Y0D01*
+X00600Y00200D01*
+X00400Y00200D01*
+X00400Y0D01*
+G37*
+
+M02*
diff --git a/gerbview/gerber_test_files/test-polygon_with_arc-fill.gbr b/gerbview/gerber_test_files/test-polygon_with_arc-fill.gbr
new file mode 100644
index 0000000..4f08394
--- /dev/null
+++ b/gerbview/gerber_test_files/test-polygon_with_arc-fill.gbr
@@ -0,0 +1,18 @@
+G04 Draw a rectangle with a rounded right side
+G04 Hand coded by Julian Lamb *
+%MOIN*%
+%FSLAX23Y23*%
+%ADD10C,0.050*%
+
+G04 Draw a rectangle with a rounded right side*
+G36*
+G01X0Y0D02*
+X00200Y0D01*
+G75*
+G03X00200Y00200I0J00100D01*
+G01X0Y00200D01*
+G04 Do not close with a final line, so let gerbv automatically close*
+G37*
+
+
+M02*
diff --git a/gerbview/gerber_test_files/test2_line_with_rect_aperture.gbr b/gerbview/gerber_test_files/test2_line_with_rect_aperture.gbr
new file mode 100644
index 0000000..26c0735
--- /dev/null
+++ b/gerbview/gerber_test_files/test2_line_with_rect_aperture.gbr
@@ -0,0 +1,67 @@
+G04 start of page 2 for group 0 idx 0
+G04 Title: (unknown), component *
+G04 Creator: pcb 20080202 *
+G04 CreationDate: Sat 27 Feb 2010 07:29:32 PM GMT UTC *
+G04 For: randomplague *
+G04 Format: Gerber/RS-274X *
+G04 PCB-Dimensions: 70000 45000 *
+G04 PCB-Coordinate-Origin: lower left *
+%MOIN*%
+%FSLAX24Y24*%
+%LNFRONT*%
+%ADD11C,0.0200*%
+%ADD12C,0.0600*%
+%ADD13R,0.0200X0.0200*%
+%ADD14R,0.0512X0.0512*%
+%ADD15C,0.0380*%
+G54D11*X1900Y1250D02*X1250D01*
+X1900Y750D02*X750D01*
+X2550D02*X3250D01*
+X1250Y1250D02*X750Y1750D01*
+X1900Y2250D02*Y2600D01*
+X750Y3750D01*
+X1000Y2750D02*X750D01*
+X1000D02*X1500Y2250D01*
+Y1750D02*X1900D01*
+X1500D02*Y2250D01*
+X3250Y750D02*Y3069D01*
+X5750Y3750D02*X4000D01*
+X4600Y2250D02*Y2900D01*
+X4000Y3500D01*
+X3250Y3069D02*X2819Y3500D01*
+X4600Y750D02*X5750D01*
+X4600Y1250D02*X5250D01*
+X5750Y1750D01*
+X4600D02*X5000D01*
+X5750Y2750D02*X5250Y2250D01*
+X5000Y2000D02*Y1750D01*
+Y2000D02*X5250Y2250D01*
+G54D11*G36*
+X5450Y4050D02*Y3450D01*
+X6050D01*
+Y4050D01*
+X5450D01*
+G37*
+G54D12*X5750Y2750D03*
+Y1750D03*
+G54D11*G36*
+X450Y4050D02*Y3450D01*
+X1050D01*
+Y4050D01*
+X450D01*
+G37*
+G54D12*X750Y2750D03*
+Y1750D03*
+Y750D03*
+X5750D03*
+G54D13*X3950D02*X4600D01*
+X3950Y1250D02*X4600D01*
+X3950Y1750D02*X4600D01*
+X1900Y2250D02*X2550D01*
+X1900Y1750D02*X2550D01*
+X1900Y1250D02*X2550D01*
+X1900Y750D02*X2550D01*
+X3950Y2250D02*X4600D01*
+G54D14*X2819Y4051D02*Y3500D01*
+X4000Y4051D02*Y3500D01*
+G54D15*M02*
diff --git a/gerbview/gerber_test_files/test_line_with_rect_aperture.gbr b/gerbview/gerber_test_files/test_line_with_rect_aperture.gbr
new file mode 100644
index 0000000..b93e1c9
--- /dev/null
+++ b/gerbview/gerber_test_files/test_line_with_rect_aperture.gbr
@@ -0,0 +1,16 @@
+*
+%FSLAX23Y23*%
+%MOIN*%
+%ADD10R,0.025X0.025*%
+%ADD11R,0.03X0.06*%
+%IPPOS*%
+%LNtest_rect.gbr*%
+%LPD*%
+G75*
+G54D10*
+X04000Y00100D02*
+X04400Y00140D01*
+G54D11*
+X03000Y00100D02*
+X02400Y-00340D01*
+M02*
diff --git a/gerbview/gerber_test_files/test_polygons_with_arcs.gbr b/gerbview/gerber_test_files/test_polygons_with_arcs.gbr
new file mode 100644
index 0000000..3dc7927
--- /dev/null
+++ b/gerbview/gerber_test_files/test_polygons_with_arcs.gbr
@@ -0,0 +1,4163 @@
+*
+%FSLAX35Y35*%
+%MOMM*%
+%ADD10C,0.085000*%
+%ADD11C,1.000000*%
+%IPPOS*%
+%LNl2p*%
+%LPD*%
+%SRX1Y1I0J0*%
+G01*
+G75*
+G36*
+X-824649Y824737D02*
+X-824642Y824746D01*
+X-824637Y824748D01*
+X-600285Y824596D01*
+G02X-596337Y813997I0J-6035D01*
+G01X-596759Y813502D01*
+X-599070Y812402D01*
+X-599079Y812403D01*
+X-600633Y812842D01*
+G03X-591714Y760887I-18257J-29877D01*
+G01X-589396Y761987D01*
+X-587850Y761553D01*
+G03X-543350Y814584I18275J29851D01*
+G02X-538846Y824554I4504J3968D01*
+G01X-387906Y824445D01*
+X-387901Y824439D01*
+X-387898Y718310D01*
+X-387892Y718296D01*
+X-387887Y718290D01*
+X-337968Y678268D01*
+X-337966Y678263D01*
+X-337746Y625972D01*
+G02X-347743Y621473I-6001J-23D01*
+G03X-394478Y621365I-23307J-26119D01*
+G02X-402955Y621809I-4016J4477D01*
+G01X-407368Y626784D01*
+X-409076Y628288D01*
+G02X-406164Y638849I3817J4630D01*
+G03X-421754Y706900I-5285J34600D01*
+G01X-699601D01*
+G03X-766967Y720229I-35002J0D01*
+G02X-771614Y718929I-2844J1211D01*
+G03X-817118Y687087I-10523J-33398D01*
+G03X-817151Y685566I34972J-1522D01*
+G01X-823562D01*
+X-824649Y824737D01*
+G37*
+G36*
+X-823562Y685566D02*
+X-817151D01*
+G03X-749783Y672221I35006J0D01*
+G02X-745135Y673521I2845J-1211D01*
+G03X-699601Y706900I10532J33379D01*
+G01X-421754D01*
+G03X-433713Y646441I10305J-33451D01*
+G02X-436626Y635881I-3821J-4628D01*
+G03X-407912Y575275I5286J-34601D01*
+G02X-399435Y574831I4016J-4476D01*
+G01X-397154Y572042D01*
+G03X-379243Y561250I26239J23289D01*
+G01X-379141Y529918D01*
+X-474048D01*
+G03X-543414Y536656I-35010J0D01*
+G02X-546852Y534512I-2891J807D01*
+G03X-587886Y505152I-6401J-34409D01*
+G01X-601503D01*
+G03X-668659Y518983I-35003J0D01*
+G02X-670664Y517431I-2675J1384D01*
+G02X-673622Y517895I52J9992D01*
+G03X-695002Y516777I-8947J-33885D01*
+G02X-702296Y520311I-1717J5751D01*
+G03X-767799Y519300I-32561J-12864D01*
+G03X-812330Y488561I-9647J-33650D01*
+G03X-812451Y485651I34887J-2910D01*
+G01X-822000D01*
+X-823562Y685566D01*
+G37*
+G36*
+X-822000Y485651D02*
+X-812451D01*
+G03X-744501Y473801I35009J0D01*
+G03X-722388Y474726I9666J33715D01*
+G02X-715313Y471655I1713J-5739D01*
+G03X-650391Y470217I32751J12389D01*
+G02X-646837Y471709I2656J-1348D01*
+G03X-601872Y500077I10332J33443D01*
+G01X-588255D01*
+G03X-518896Y493354I35005J0D01*
+G02X-515458Y495498I2890J-806D01*
+G03X-474048Y529918I6400J34420D01*
+G01X-379141D01*
+X-378950Y471399D01*
+X-379636Y414481D01*
+G02X-389468Y410485I-5958J566D01*
+G03X-442629Y400682I-22547J-26775D01*
+G01X-523620D01*
+G03X-584299Y424470I-35002J0D01*
+G02X-586947Y423652I-2113J2146D01*
+G02X-589302Y424942I3781J9697D01*
+G03X-643324Y397426I-19082J-29325D01*
+G03X-643372Y395592I34957J-1835D01*
+G01X-821296D01*
+X-822000Y485651D01*
+G37*
+G36*
+X-821296Y395592D02*
+X-643372D01*
+G03X-582690Y371800I35005J0D01*
+G02X-580043Y372618I2111J-2139D01*
+G02X-577688Y371328I-3780J-9695D01*
+G03X-523620Y400682I19066J29354D01*
+G01X-442629D01*
+G03X-426828Y351995I30614J-16972D01*
+G03X-380460Y368307I14887J31742D01*
+G01X-336608Y352876D01*
+X-336605Y352871D01*
+X-336565Y345194D01*
+X-336559Y345186D01*
+X-336549Y345178D01*
+X-299824Y332640D01*
+X-299819Y332634D01*
+X-293878Y306411D01*
+X-296682Y299910D01*
+X-367926D01*
+X-368938Y308267D01*
+X-371917Y316141D01*
+X-376689Y323076D01*
+X-382979Y328670D01*
+X-390423Y332602D01*
+X-398590Y334642D01*
+X-402810Y334912D01*
+X-411164Y333871D01*
+X-419027Y330866D01*
+X-425946Y326071D01*
+X-431520Y319762D01*
+X-435426Y312305D01*
+X-437438Y304130D01*
+X-437694Y299910D01*
+X-585657D01*
+G03X-635902Y285301I-18631J-29633D01*
+G01X-651700D01*
+G03X-672543Y317315I-35008J0D01*
+G02X-674177Y319553I1344J2696D01*
+G02X-673724Y322193I11767J-660D01*
+G03X-742595Y333161I-33957J8489D01*
+G03X-742682Y330692I34923J-2469D01*
+G01X-820789D01*
+X-821296Y395592D01*
+G37*
+G36*
+X-820789Y330692D02*
+X-742682D01*
+G03X-721837Y298675I35011J0D01*
+G02X-720289Y295144I-1333J-2689D01*
+G03X-710025Y259188I33599J-9852D01*
+G02X-710457Y250354I-4231J-4221D01*
+G03X-664764Y249541I22375J-26924D01*
+G02X-664333Y258377I4263J4221D01*
+G03X-655092Y270269I-22375J26924D01*
+G01X-639292D01*
+G03X-624463Y241657I35017J0D01*
+G02X-623734Y237872I-1897J-2328D01*
+G03X-558138Y220849I30589J-17023D01*
+G01X-440238D01*
+G03X-426462Y195115I34899J2128D01*
+G02X-426268Y186271I-3929J-4510D01*
+G03X-367037Y161005I24227J-25266D01*
+G01X-348730D01*
+X-364649Y120947D01*
+X-364653Y98350D01*
+X-364656Y98344D01*
+X-390753Y66602D01*
+X-390758Y66601D01*
+X-556452Y67300D01*
+X-566659Y67028D01*
+G02X-572057Y75947I-151J6002D01*
+G03X-630900Y113652I-30522J17134D01*
+G02X-640643Y113702I-4854J3525D01*
+G03X-697256Y72485I-28550J-20274D01*
+G02X-702251Y63415I-5153J-3073D01*
+G01X-742203Y62348D01*
+X-751941Y58383D01*
+G02X-760167Y63303I-2249J5577D01*
+G03X-810810Y90813I-34830J-3748D01*
+G02X-818958Y96370I-2137J5619D01*
+G01X-819253Y134021D01*
+G02X-810377Y139331I6003J39D01*
+G03X-767009Y192811I16774J30722D01*
+G02X-766734Y200915I4559J3902D01*
+G03X-810894Y254821I-24669J24832D01*
+G02X-820235Y259759I-3343J4979D01*
+G01X-820789Y330692D01*
+G37*
+G36*
+X-655092Y270269D02*
+G03X-651700Y285301I-31616J15032D01*
+G01X-635902D01*
+G03X-639131Y273619I31615J-15024D01*
+G03X-639292Y270269I34856J-3351D01*
+G01X-655092D01*
+G37*
+G36*
+X-601872Y500077D02*
+G03X-601503Y505152I-34633J5075D01*
+G01X-587886D01*
+G03X-588030Y504037I34633J-5049D01*
+G03X-588255Y500077I34781J-3960D01*
+G01X-601872D01*
+G37*
+G36*
+X-585657Y299910D02*
+X-437694D01*
+X-436681Y291553D01*
+X-433703Y283679D01*
+X-428931Y276744D01*
+X-422641Y271149D01*
+X-415197Y267218D01*
+X-407030Y265177D01*
+X-402810Y264908D01*
+X-394456Y265948D01*
+X-386593Y268953D01*
+X-379674Y273749D01*
+X-374100Y280058D01*
+X-370194Y287515D01*
+X-368181Y295689D01*
+X-367926Y299910D01*
+X-296682D01*
+X-307312Y275263D01*
+X-308500Y273499D01*
+X-310150Y269702D01*
+X-337228Y232797D01*
+X-337414Y206733D01*
+X-342750Y176052D01*
+X-348730Y161005D01*
+X-367037D01*
+G03X-380888Y188895I-35005J0D01*
+G02X-381082Y197739I3958J4511D01*
+G03X-440260Y224704I-24217J25272D01*
+G03X-440303Y222976I34921J-1727D01*
+G01X-558202D01*
+G03X-572976Y249462I-34943J-2128D01*
+G02X-573706Y253248I1902J2330D01*
+G03X-585657Y299910I-30582J17029D01*
+G37*
+G36*
+X-558202Y222976D02*
+G01X-440303D01*
+G03X-440238Y220849I34963J0D01*
+G01X-558138D01*
+G03X-558202Y222976I-35007J-0D01*
+G37*
+G36*
+X-585361Y300069D02*
+G01X-437853D01*
+G02X-437853Y299751I0J-159D01*
+G01X-585361D01*
+G02X-585361Y300069I0J159D01*
+G37*
+G36*
+X-367767D02*
+G01X-296855D01*
+G02X-296855Y299751I0J-159D01*
+G01X-367767D01*
+G02X-367767Y300069I0J159D01*
+G37*
+G36*
+X-366878Y161164D02*
+G01X-348900D01*
+G02X-348900Y160846I0J-159D01*
+G01X-366878D01*
+G02X-366878Y161164I0J159D01*
+G37*
+G36*
+X-558043Y223135D02*
+G01X-440462D01*
+G02X-440462Y222818I0J-159D01*
+G01X-558043D01*
+G02X-558043Y223135I0J159D01*
+G37*
+G36*
+X-473889Y530077D02*
+G01X-379299D01*
+G02X-379299Y529759I0J-159D01*
+G01X-473889D01*
+G02X-473889Y530077I0J159D01*
+G37*
+G36*
+X-601712Y500236D02*
+G01X-588414D01*
+G02X-588414Y499918I0J-159D01*
+G01X-601712D01*
+G02X-601712Y500236I0J159D01*
+G37*
+G36*
+X-557979Y221007D02*
+G01X-440397D01*
+G02X-440397Y220690I0J-159D01*
+G01X-557979D01*
+G02X-557979Y221007I0J159D01*
+G37*
+G36*
+X-654917Y270427D02*
+G01X-639451D01*
+G02X-639451Y270110I0J-159D01*
+G01X-654917D01*
+G02X-654917Y270427I0J159D01*
+G37*
+G36*
+X-523461Y400841D02*
+G01X-442811D01*
+G02X-442811Y400523I0J-159D01*
+G01X-523461D01*
+G02X-523461Y400841I0J159D01*
+G37*
+G36*
+X-821138Y395750D02*
+G01X-643531D01*
+G02X-643531Y395433I0J-159D01*
+G01X-821138D01*
+G02X-821138Y395750I0J159D01*
+G37*
+G36*
+X-651541Y285460D02*
+G01X-636078D01*
+G02X-636078Y285142I0J-159D01*
+G01X-651541D01*
+G02X-651541Y285460I0J159D01*
+G37*
+G36*
+X-820631Y330851D02*
+G01X-742841D01*
+G02X-742841Y330533I0J-159D01*
+G01X-820631D01*
+G02X-820631Y330851I0J159D01*
+G37*
+G36*
+X-601344Y505310D02*
+G01X-588046D01*
+G02X-588046Y504993I0J-159D01*
+G01X-601344D01*
+G02X-601344Y505310I0J159D01*
+G37*
+G36*
+X-821841Y485810D02*
+G01X-812610D01*
+G02X-812610Y485492I0J-159D01*
+G01X-821841D01*
+G02X-821841Y485810I0J159D01*
+G37*
+G36*
+X-699443Y707059D02*
+G01X-422282D01*
+G02X-422282Y706741I0J-159D01*
+G01X-699443D01*
+G02X-699443Y707059I0J159D01*
+G37*
+G36*
+X-823403Y685724D02*
+G01X-817310D01*
+G02X-817310Y685407I0J-159D01*
+G01X-823403D01*
+G02X-823403Y685724I0J159D01*
+G37*
+G36*
+X-817138Y-494161D02*
+G01X-817137Y-492155D01*
+G02X-809582Y-486361I6005J-7D01*
+G03X-809561Y-420931I12532J32711D01*
+G02X-817119Y-415136I-1559J5794D01*
+G01X-817115Y-399500D01*
+X-762202D01*
+X-761190Y-407857D01*
+X-758211Y-415731D01*
+X-753439Y-422666D01*
+X-747149Y-428260D01*
+X-739705Y-432192D01*
+X-731538Y-434232D01*
+X-727200Y-434502D01*
+X-718843Y-433490D01*
+X-710969Y-430511D01*
+X-704034Y-425739D01*
+X-698439Y-419449D01*
+X-694508Y-412005D01*
+X-692468Y-403838D01*
+X-692198Y-399500D01*
+X-678475D01*
+X-678849Y-421921D01*
+X-679243Y-427151D01*
+X-692851Y-444036D01*
+X-713002Y-463005D01*
+X-724312Y-492342D01*
+X-724320Y-492348D01*
+X-739665Y-494000D01*
+X-747006Y-494004D01*
+X-764366Y-506933D01*
+G03X-808184Y-499385I-26510J-22937D01*
+G02X-817120Y-494631I-2955J5221D01*
+G01X-817138Y-494161D01*
+G37*
+G36*
+X-817115Y-399500D02*
+X-817098Y-331697D01*
+X-809495Y-320299D01*
+X-784004Y-316501D01*
+X-783996Y-316504D01*
+X-769505Y-330645D01*
+X-769492Y-330650D01*
+X-766159Y-330772D01*
+X-765403Y-331378D01*
+X-752004Y-331277D01*
+X-676050Y-334003D01*
+X-678450Y-398000D01*
+X-678475Y-399500D01*
+X-692198D01*
+X-693210Y-391143D01*
+X-696189Y-383269D01*
+X-700961Y-376334D01*
+X-707251Y-370739D01*
+X-714694Y-366808D01*
+X-722862Y-364768D01*
+X-727200Y-364498D01*
+X-735557Y-365510D01*
+X-743431Y-368489D01*
+X-750365Y-373261D01*
+X-755960Y-379551D01*
+X-759892Y-386995D01*
+X-761932Y-395162D01*
+X-762202Y-399500D01*
+X-817115D01*
+G37*
+G36*
+X-816956Y-399341D02*
+X-762361D01*
+G02X-762361Y-399659I0J-159D01*
+G01X-816956D01*
+G02X-816956Y-399341I0J159D01*
+G37*
+G36*
+X-692039D02*
+G01X-678634D01*
+G02X-678634Y-399659I0J-159D01*
+G01X-692039D01*
+G02X-692039Y-399341I0J159D01*
+G37*
+G36*
+X-816000Y-16537D02*
+G02X-816000Y-16535I5999J0D01*
+G01Y-12898D01*
+X-814047Y5549D01*
+X-814044Y5553D01*
+X-740047Y49549D01*
+X-681904Y50748D01*
+X-681900Y50746D01*
+X-644297Y3204D01*
+X-644290Y3201D01*
+G02X-638532Y-5596I430J-6002D01*
+G03X-576813Y-5213I30962J-16325D01*
+G02X-571576Y3650I5283J2857D01*
+G01X-422562Y4569D01*
+G03X-364093Y4932I29115J19510D01*
+G01X-339385Y5079D01*
+G03X-325795Y-25183I35003J-2463D01*
+G02X-325003Y-33927I-3650J-4739D01*
+G03X-329352Y-74590I26059J-23351D01*
+G02X-330354Y-81827I-5222J-2965D01*
+G02X-333299Y-83767I-15176J19833D01*
+G02X-337538Y-82630I-1589J2546D01*
+G03X-401400Y-110856I-30914J-16415D01*
+G02X-405567Y-118693I-5650J-2022D01*
+G03X-431452Y-158328I8647J-33917D01*
+G01X-660059D01*
+G03X-670904Y-132990I-35021J0D01*
+G03X-681631Y-83813I-29157J19398D01*
+G02X-682874Y-75053I3367J4946D01*
+G02X-680106Y-72964I9903J-10243D01*
+G03X-717520Y-73348I-19011J29394D01*
+G02X-718243Y-83693I-3386J-4961D01*
+G03X-724217Y-138923I18206J-29907D01*
+G03X-711494Y-189235I29134J-19397D01*
+G02X-712604Y-200287I-2819J-5299D01*
+G03X-737625Y-232041I9945J-33571D01*
+G03X-737672Y-233854I34958J-1813D01*
+G01X-766592D01*
+G03X-770380Y-184011I-26324J23065D01*
+G02X-772046Y-174462I2783J5405D01*
+G03X-808728Y-117499I-25794J23682D01*
+G02X-815995Y-111871I-1302J5825D01*
+G01X-816000Y-111636D01*
+Y-96062D01*
+G02X-808537Y-90245I6000J-2D01*
+G03X-808538Y-22355I8538J33945D01*
+G02X-816000Y-16537I-1463J5819D01*
+G37*
+G36*
+X-792630Y-293580D02*
+G02X-792626Y-293372I6005J0D01*
+G01X-457899D01*
+G03X-393888Y-312989I35012J0D01*
+G02X-383370Y-314553I4847J-3557D01*
+G03X-318688Y-312229I31862J14487D01*
+G02X-316297Y-310417I2756J-1153D01*
+G02X-313968Y-310737I-621J-13151D01*
+G03X-295478Y-309237I6516J34389D01*
+G02X-288282Y-312970I1563J-5789D01*
+G03X-242255Y-337205I33938J8630D01*
+G02X-234386Y-343991I1986J-5652D01*
+G03X-166973Y-362180I34398J-6533D01*
+G01X366616D01*
+X367628Y-370537D01*
+X370607Y-378411D01*
+X375379Y-385346D01*
+X378138Y-387800D01*
+X-378466D01*
+X-379478Y-379443D01*
+X-382457Y-371569D01*
+X-387229Y-364634D01*
+X-393519Y-359039D01*
+X-400963Y-355108D01*
+X-409130Y-353068D01*
+X-413350Y-352798D01*
+X-421704Y-353839D01*
+X-429567Y-356844D01*
+X-436486Y-361639D01*
+X-440365Y-366030D01*
+X-462486D01*
+X-463498Y-357673D01*
+X-466477Y-349799D01*
+X-471249Y-342864D01*
+X-477539Y-337269D01*
+X-484983Y-333338D01*
+X-493150Y-331298D01*
+X-497370Y-331028D01*
+X-505724Y-332069D01*
+X-513587Y-335074D01*
+X-520506Y-339869D01*
+X-526079Y-346178D01*
+X-529985Y-353635D01*
+X-531998Y-361809D01*
+X-532254Y-366030D01*
+X-620995D01*
+X-622653Y-320319D01*
+X-622673Y-320300D01*
+X-761902Y-321347D01*
+X-761907Y-321344D01*
+X-790414Y-298238D01*
+G02X-792630Y-293580I3789J4658D01*
+G37*
+G36*
+X-792626Y-293372D02*
+G02X-788781Y-287975I6001J-208D01*
+G03X-770460Y-237635I-11995J32869D01*
+G03X-766592Y-233854I-22456J26846D01*
+G01X-737672D01*
+G03X-686256Y-202935I35005J0D01*
+G02X-685639Y-192052I2818J5299D01*
+G03X-660059Y-158328I-9440J33724D01*
+G01X-431452D01*
+G03X-420064Y-178869I34532J5717D01*
+G02X-421075Y-188591I-3948J-4503D01*
+G03X-380686Y-192791I17245J-30460D01*
+G02X-379675Y-183069I3978J4500D01*
+G03X-364125Y-140302I-17255J30484D01*
+G02X-359803Y-132967I5807J1519D01*
+G01X-354042Y-130950D01*
+X-352193Y-130047D01*
+G02X-344335Y-132155I2782J-5329D01*
+G03X-282154Y-126204I29585J18710D01*
+G02X-272599Y-123891I5588J-2190D01*
+G03X-221681Y-124363I25682J23802D01*
+G02X-212873Y-124541I4322J-4164D01*
+G03X-211918Y-77027I26162J23241D01*
+G02X-220727Y-76849I-4322J4169D01*
+G03X-256432Y-66411I-26175J-23249D01*
+G02X-264046Y-60146I-1635J5772D01*
+G03X-277485Y-29617I-34892J2863D01*
+G02X-278277Y-20873I3687J4742D01*
+G01X-274616Y-15989D01*
+G02X-264209Y-14639I5588J-2287D01*
+G03X-219054Y-23880I27861J21199D01*
+G02X-210538Y-26823I2961J-5224D01*
+G03X-195446Y16880I32387J13273D01*
+G02X-203962Y19823I-2961J5225D01*
+G03X-205508Y23100I-32388J-13276D01*
+G01X-32384D01*
+X-31372Y14743D01*
+X-28393Y6869D01*
+X-23621Y-66D01*
+X-17331Y-5661D01*
+X-9887Y-9592D01*
+X-1720Y-11632D01*
+X2500Y-11902D01*
+X10854Y-10861D01*
+X18717Y-7856D01*
+X25636Y-3061D01*
+X31209Y3248D01*
+X35116Y10705D01*
+X37128Y18879D01*
+X37384Y23100D01*
+X174268D01*
+G03X184282Y5427I34151J7678D01*
+G02X184502Y-2281I-4484J-3985D01*
+G03X178010Y-15450I27461J-21724D01*
+G01X119784D01*
+X118772Y-7093D01*
+X115793Y781D01*
+X111021Y7716D01*
+X104731Y13311D01*
+X97287Y17242D01*
+X89120Y19282D01*
+X84900Y19552D01*
+X76546Y18511D01*
+X68683Y15506D01*
+X61764Y10711D01*
+X56190Y4402D01*
+X52284Y-3055D01*
+X50271Y-11229D01*
+X50016Y-15450D01*
+X-91652D01*
+G03X-92685Y-83669I-8347J-33991D01*
+G02X-85838Y-91705I1260J-5861D01*
+G03X-87910Y-108869I32636J-12647D01*
+G02X-94769Y-115471I-5948J-685D01*
+G03X-132904Y-162016I-5233J-34608D01*
+G02X-137051Y-169873I-5617J-2058D01*
+G02X-141806Y-169269I-1670J5871D01*
+G03X-187884Y-200273I-11147J-33176D01*
+G03X-187951Y-202440I34941J-2167D01*
+G01X-236876D01*
+G03X-302943Y-182801I-34780J3944D01*
+G02X-306338Y-184145I-2567J1524D01*
+G03X-337228Y-246682I-12710J-32620D01*
+G02X-335536Y-255399I-3098J-5124D01*
+G03X-340312Y-264171I28076J-20973D01*
+G02X-343742Y-265931I-2773J1182D01*
+G03X-380522Y-280471I-7773J-34128D01*
+G02X-389696Y-281062I-4835J3557D01*
+G02X-391346Y-278254I9849J7676D01*
+G03X-457800Y-290742I-31554J-15144D01*
+G03X-457899Y-293372I34912J-2630D01*
+G01X-792626D01*
+G37*
+G36*
+X-620995Y-366030D02*
+X-532254D01*
+X-531241Y-374387D01*
+X-528263Y-382261D01*
+X-523491Y-389196D01*
+X-517201Y-394791D01*
+X-509757Y-398722D01*
+X-501590Y-400762D01*
+X-497370Y-401032D01*
+X-489016Y-399991D01*
+X-481153Y-396986D01*
+X-474234Y-392191D01*
+X-470355Y-387800D01*
+X-448234D01*
+X-447221Y-396157D01*
+X-444243Y-404031D01*
+X-439471Y-410966D01*
+X-433181Y-416561D01*
+X-425737Y-420492D01*
+X-417570Y-422532D01*
+X-413350Y-422802D01*
+X-404996Y-421761D01*
+X-397133Y-418756D01*
+X-390214Y-413961D01*
+X-384640Y-407652D01*
+X-380734Y-400195D01*
+X-378721Y-392021D01*
+X-378466Y-387800D01*
+X378138D01*
+X381669Y-390940D01*
+X389113Y-394872D01*
+X397280Y-396912D01*
+X401500Y-397182D01*
+X409380Y-396200D01*
+X481666D01*
+X482678Y-404557D01*
+X485657Y-412431D01*
+X490429Y-419366D01*
+X496719Y-424960D01*
+X504163Y-428892D01*
+X512330Y-430932D01*
+X516550Y-431202D01*
+X524904Y-430161D01*
+X532767Y-427156D01*
+X533145Y-426894D01*
+X561648D01*
+G03X588999Y-461048I35000J0D01*
+G01X-464047D01*
+G03X-525992Y-483418I-35012J0D01*
+G01X-529511Y-488391D01*
+X-532118Y-493907D01*
+X-533728Y-499792D01*
+X-534142Y-502818D01*
+G03X-534292Y-506058I34862J-3240D01*
+G01X-543860D01*
+X-544899Y-455599D01*
+X-535303Y-423994D01*
+X-535304Y-423989D01*
+X-541249Y-406017D01*
+X-541257Y-406009D01*
+X-541266Y-406004D01*
+X-541272Y-406002D01*
+X-541278Y-406001D01*
+X-619394Y-409996D01*
+X-619399Y-409989D01*
+X-619401Y-409984D01*
+X-620995Y-366030D01*
+G37*
+G36*
+X-543860Y-506058D02*
+X-534292D01*
+G03X-464966Y-499100I35013J0D01*
+G01X-332834D01*
+X-331821Y-507457D01*
+X-328843Y-515331D01*
+X-324071Y-522266D01*
+X-317781Y-527861D01*
+X-310337Y-531792D01*
+X-302169Y-533832D01*
+X-297950Y-534102D01*
+X-289596Y-533061D01*
+X-281733Y-530056D01*
+X-274814Y-525261D01*
+X-269240Y-518952D01*
+X-265334Y-511495D01*
+X-263488Y-504000D01*
+X-252284D01*
+X-251271Y-512357D01*
+X-248293Y-520231D01*
+X-243521Y-527166D01*
+X-237231Y-532761D01*
+X-229787Y-536692D01*
+X-221619Y-538732D01*
+X-217400Y-539002D01*
+X-209046Y-537961D01*
+X-201183Y-534956D01*
+X-194264Y-530161D01*
+X-188690Y-523852D01*
+X-184784Y-516395D01*
+X-182771Y-508221D01*
+X-182516Y-504000D01*
+X80350D01*
+X80848Y-508117D01*
+X83827Y-515991D01*
+X88599Y-522926D01*
+X94889Y-528520D01*
+X102333Y-532452D01*
+X110500Y-534492D01*
+X114720Y-534762D01*
+X123074Y-533721D01*
+X130937Y-530716D01*
+X137856Y-525921D01*
+X143430Y-519612D01*
+X145856Y-514980D01*
+X450816D01*
+X451828Y-523337D01*
+X454807Y-531211D01*
+X459579Y-538146D01*
+X465869Y-543740D01*
+X473313Y-547672D01*
+X481480Y-549712D01*
+X485700Y-549982D01*
+X494054Y-548941D01*
+X501917Y-545936D01*
+X508836Y-541140D01*
+X514410Y-534832D01*
+X518316Y-527374D01*
+X520328Y-519200D01*
+X520584Y-514980D01*
+X645159D01*
+G03X695764Y-514783I25209J24293D01*
+G02X699816Y-514846I1992J-2221D01*
+G03X758853Y-489393I24031J25454D01*
+G01X822449D01*
+X822449Y-586049D01*
+X756953D01*
+G03X689354Y-573295I-35003J0D01*
+G02X678643Y-574298I-5608J2190D01*
+G03X616514Y-592268I-27339J-21866D01*
+G03X616300Y-596137I34790J-3869D01*
+G01X566455D01*
+X564443Y-590819D01*
+X559671Y-583884D01*
+X553381Y-578289D01*
+X545937Y-574358D01*
+X537770Y-572317D01*
+X533550Y-572048D01*
+X525196Y-573089D01*
+X517333Y-576094D01*
+X510414Y-580889D01*
+X504840Y-587198D01*
+X500934Y-594655D01*
+X500049Y-598248D01*
+X491981D01*
+G03X430465Y-575396I-35003J0D01*
+G02X421620Y-575462I-4453J4009D01*
+G03X373063Y-572833I-25641J-23845D01*
+G03X316077Y-597499I-22075J-27160D01*
+G03X315987Y-600009I34916J-2511D01*
+G01X253962D01*
+X251443Y-593349D01*
+X246671Y-586414D01*
+X240381Y-580819D01*
+X232937Y-576888D01*
+X224770Y-574847D01*
+X220550Y-574578D01*
+X212196Y-575618D01*
+X204333Y-578623D01*
+X197414Y-583419D01*
+X191840Y-589728D01*
+X187934Y-597185D01*
+X186711Y-602150D01*
+X170364D01*
+X169351Y-593793D01*
+X166373Y-585919D01*
+X161601Y-578984D01*
+X155311Y-573389D01*
+X147867Y-569458D01*
+X139700Y-567417D01*
+X135480Y-567148D01*
+X127126Y-568188D01*
+X119263Y-571193D01*
+X112344Y-575989D01*
+X106770Y-582298D01*
+X102864Y-589755D01*
+X100851Y-597929D01*
+X100596Y-602150D01*
+X53903D01*
+X53401Y-598013D01*
+X50423Y-590139D01*
+X45651Y-583204D01*
+X39361Y-577609D01*
+X31917Y-573678D01*
+X23750Y-571637D01*
+X19530Y-571368D01*
+X11176Y-572408D01*
+X3313Y-575413D01*
+X-3606Y-580209D01*
+X-9180Y-586518D01*
+X-13086Y-593975D01*
+X-15098Y-602149D01*
+X-15132Y-602710D01*
+X-31386D01*
+X-32398Y-594353D01*
+X-35377Y-586479D01*
+X-40149Y-579544D01*
+X-46439Y-573949D01*
+X-53883Y-570018D01*
+X-62050Y-567978D01*
+X-66270Y-567708D01*
+X-74624Y-568749D01*
+X-82487Y-571754D01*
+X-89406Y-576549D01*
+X-94979Y-582858D01*
+X-98885Y-590315D01*
+X-100667Y-597550D01*
+X-149916D01*
+X-150928Y-589193D01*
+X-153907Y-581319D01*
+X-158679Y-574384D01*
+X-164969Y-568789D01*
+X-172413Y-564858D01*
+X-180580Y-562818D01*
+X-184800Y-562548D01*
+X-193154Y-563589D01*
+X-201017Y-566594D01*
+X-207936Y-571389D01*
+X-213509Y-577698D01*
+X-217415Y-585155D01*
+X-219428Y-593329D01*
+X-219684Y-597550D01*
+X-248195D01*
+X-249128Y-589843D01*
+X-252107Y-581969D01*
+X-256879Y-575034D01*
+X-263169Y-569439D01*
+X-270613Y-565508D01*
+X-278780Y-563468D01*
+X-283000Y-563198D01*
+X-291354Y-564239D01*
+X-299217Y-567244D01*
+X-306136Y-572039D01*
+X-311709Y-578348D01*
+X-315615Y-585805D01*
+X-317628Y-593979D01*
+X-317883Y-598190D01*
+X-328076D01*
+X-329088Y-589833D01*
+X-332067Y-581959D01*
+X-336839Y-575024D01*
+X-343129Y-569429D01*
+X-350573Y-565498D01*
+X-358740Y-563458D01*
+X-362960Y-563188D01*
+X-371314Y-564229D01*
+X-379177Y-567234D01*
+X-386096Y-572029D01*
+X-391669Y-578338D01*
+X-395575Y-585795D01*
+X-397588Y-593969D01*
+X-397844Y-598190D01*
+X-488883D01*
+G03X-535293Y-565655I-35006J-566D01*
+G02X-543243Y-559858I-1945J5682D01*
+G01X-543000Y-547799D01*
+X-543860Y-506058D01*
+G37*
+G36*
+X-541750Y-823634D02*
+X-541332Y-692300D01*
+X-504334D01*
+X-503321Y-700657D01*
+X-500343Y-708531D01*
+X-495571Y-715466D01*
+X-489281Y-721061D01*
+X-481837Y-724992D01*
+X-473669Y-727032D01*
+X-469450Y-727302D01*
+X-461096Y-726261D01*
+X-453233Y-723256D01*
+X-446314Y-718461D01*
+X-440740Y-712152D01*
+X-436834Y-704695D01*
+X-435136Y-697800D01*
+X-396884D01*
+X-395871Y-706157D01*
+X-392893Y-714031D01*
+X-388121Y-720966D01*
+X-381831Y-726561D01*
+X-374387Y-730492D01*
+X-366219Y-732532D01*
+X-362000Y-732802D01*
+X-353646Y-731761D01*
+X-345783Y-728756D01*
+X-338864Y-723961D01*
+X-333290Y-717652D01*
+X-329384Y-710195D01*
+X-327371Y-702021D01*
+X-327119Y-697855D01*
+X-282503D01*
+G03X-215973Y-713109I35014J0D01*
+G02X-205856Y-712891I5128J-3119D01*
+G03X-142607Y-701170I29103J19465D01*
+G01X-95644D01*
+X-94631Y-709527D01*
+X-91653Y-717401D01*
+X-86881Y-724336D01*
+X-80591Y-729931D01*
+X-73147Y-733862D01*
+X-64979Y-735902D01*
+X-60760Y-736172D01*
+X-52406Y-735131D01*
+X-44543Y-732126D01*
+X-37624Y-727331D01*
+X-32050Y-721022D01*
+X-28144Y-713565D01*
+X-26192Y-705640D01*
+X-7974D01*
+X-6961Y-713997D01*
+X-3983Y-721871D01*
+X789Y-728806D01*
+X7079Y-734400D01*
+X14523Y-738332D01*
+X22690Y-740372D01*
+X26910Y-740642D01*
+X35264Y-739601D01*
+X43127Y-736596D01*
+X50046Y-731801D01*
+X55620Y-725492D01*
+X59526Y-718035D01*
+X61538Y-709860D01*
+X61794Y-705640D01*
+X107329D01*
+G03X172955Y-714760I34367J6625D01*
+G02X182356Y-713250I5281J-2861D01*
+G03X238168Y-709548I26511J22882D01*
+G02X248651Y-710835I4888J-3526D01*
+G03X309528Y-710143I30242J17646D01*
+G02X319890Y-710918I4958J-3370D01*
+G03X386318Y-698400I31529J15198D01*
+G01X415116D01*
+X416128Y-706757D01*
+X419107Y-714631D01*
+X423879Y-721566D01*
+X430169Y-727160D01*
+X437613Y-731092D01*
+X445780Y-733132D01*
+X450000Y-733402D01*
+X458354Y-732361D01*
+X466217Y-729356D01*
+X473136Y-724560D01*
+X478710Y-718252D01*
+X482616Y-710794D01*
+X484628Y-702620D01*
+X484884Y-698400D01*
+X585084D01*
+X588329Y-703116D01*
+X594619Y-708710D01*
+X602063Y-712642D01*
+X610230Y-714682D01*
+X614450Y-714952D01*
+X622804Y-713911D01*
+X630667Y-710906D01*
+X637586Y-706110D01*
+X643160Y-699802D01*
+X647066Y-692344D01*
+X648911Y-684850D01*
+X683316D01*
+X684328Y-693207D01*
+X687307Y-701081D01*
+X692079Y-708016D01*
+X698369Y-713610D01*
+X705813Y-717542D01*
+X713980Y-719582D01*
+X718200Y-719852D01*
+X726554Y-718811D01*
+X734417Y-715806D01*
+X741336Y-711010D01*
+X746910Y-704702D01*
+X750816Y-697244D01*
+X752828Y-689070D01*
+X753084Y-684850D01*
+X822449D01*
+X822448Y-822490D01*
+X822443Y-822496D01*
+X822439Y-822499D01*
+X822434Y-822500D01*
+X740055D01*
+G02X736815Y-811451I0J5999D01*
+G03X698986Y-811451I-18915J29450D01*
+G02X695742Y-822500I-3244J-5048D01*
+G01X640368D01*
+G02X636921Y-811591I0J5999D01*
+G03X584671Y-769062I-20123J28638D01*
+G02X574896Y-770896I-5507J2382D01*
+G03X519938Y-813428I-24896J-24604D01*
+G02X514784Y-822500I-5154J-3072D01*
+G01X482913D01*
+G02X477573Y-813770I0J5998D01*
+G03X415228Y-813771I-31173J15917D01*
+G02X409884Y-822500I-5344J-2729D01*
+G01X364596D01*
+G02X359541Y-813272I0J5999D01*
+G03X300783Y-813729I-29527J18819D01*
+G02X295461Y-822500I-5322J-2771D01*
+G01X287141D01*
+G02X281906Y-813573I0J5999D01*
+G03X220794Y-813573I-30556J17074D01*
+G02X215556Y-822500I-5238J-2927D01*
+G01X182062D01*
+G02X176641Y-813933I0J5999D01*
+G03X113731Y-813874I-31441J15394D01*
+G02X108336Y-822500I-5395J-2626D01*
+G01X68064D01*
+G02X63152Y-813057I0J5999D01*
+G03X6310Y-813004I-28402J20456D01*
+G02X1433Y-822500I-4877J-3495D01*
+G01X-31738Y-822476D01*
+G02X-36229Y-813208I508J5968D01*
+G03X-94750Y-813209I-29261J19207D01*
+G02X-99768Y-822500I-5018J-3290D01*
+G01X-146118D01*
+G02X-150533Y-812438I-14J5993D01*
+G03X-207321Y-772540I-25752J23710D01*
+G03X-201728Y-812842I31038J-16232D01*
+G02X-206485Y-822500I-4757J-3657D01*
+G01X-243902Y-822476D01*
+G02X-247972Y-812642I508J5970D01*
+G03X-300363Y-812531I-26146J23272D01*
+G02X-304863Y-822500I-4500J-3969D01*
+G01X-328202D01*
+G02X-333900Y-814625I-13J5989D01*
+G03X-400350Y-814777I-33250J10927D01*
+G02X-405999Y-822677I-5689J-1902D01*
+G01X-438477Y-822910D01*
+G02X-443185Y-813139I-42J6000D01*
+G03X-497317Y-813527I-27225J22007D01*
+G02X-501888Y-823364I-4571J-3857D01*
+G01X-541740Y-823648D01*
+X-541749Y-823640D01*
+X-541750Y-823634D01*
+G37*
+G36*
+X-541639Y-631272D02*
+X-537894Y-630844D01*
+G03X-488883Y-598190I14005J32087D01*
+G01X-397844D01*
+X-396831Y-606547D01*
+X-393853Y-614421D01*
+X-389081Y-621356D01*
+X-382791Y-626951D01*
+X-375347Y-630882D01*
+X-367179Y-632922D01*
+X-362960Y-633192D01*
+X-354606Y-632151D01*
+X-346743Y-629146D01*
+X-339824Y-624351D01*
+X-334250Y-618042D01*
+X-330344Y-610585D01*
+X-328331Y-602411D01*
+X-328077Y-598200D01*
+X-317884D01*
+X-316871Y-606557D01*
+X-313893Y-614431D01*
+X-309121Y-621366D01*
+X-302831Y-626961D01*
+X-295387Y-630892D01*
+X-287219Y-632932D01*
+X-283000Y-633202D01*
+X-274646Y-632161D01*
+X-266783Y-629156D01*
+X-259864Y-624361D01*
+X-254290Y-618052D01*
+X-250384Y-610595D01*
+X-248371Y-602421D01*
+X-248116Y-598200D01*
+X-219605D01*
+X-218671Y-605907D01*
+X-215693Y-613781D01*
+X-210921Y-620716D01*
+X-204631Y-626311D01*
+X-197187Y-630242D01*
+X-189019Y-632282D01*
+X-184800Y-632552D01*
+X-176446Y-631511D01*
+X-168583Y-628506D01*
+X-161664Y-623711D01*
+X-156090Y-617402D01*
+X-152184Y-609945D01*
+X-150402Y-602710D01*
+X-101154D01*
+X-100141Y-611067D01*
+X-97163Y-618941D01*
+X-92391Y-625876D01*
+X-86101Y-631471D01*
+X-78657Y-635402D01*
+X-70489Y-637442D01*
+X-66270Y-637712D01*
+X-57916Y-636671D01*
+X-50053Y-633666D01*
+X-43134Y-628871D01*
+X-37560Y-622562D01*
+X-33654Y-615105D01*
+X-31641Y-606931D01*
+X-31607Y-606370D01*
+X-15354D01*
+X-14341Y-614727D01*
+X-11363Y-622601D01*
+X-6591Y-629536D01*
+X-301Y-635130D01*
+X7143Y-639062D01*
+X15310Y-641102D01*
+X19530Y-641372D01*
+X27884Y-640331D01*
+X35747Y-637326D01*
+X42666Y-632531D01*
+X48240Y-626222D01*
+X52146Y-618765D01*
+X54158Y-610590D01*
+X54414Y-606370D01*
+X101107D01*
+X101608Y-610507D01*
+X104587Y-618381D01*
+X109359Y-625316D01*
+X115649Y-630910D01*
+X123093Y-634842D01*
+X131260Y-636882D01*
+X135480Y-637152D01*
+X143834Y-636111D01*
+X151697Y-633106D01*
+X158616Y-628311D01*
+X164190Y-622002D01*
+X168096Y-614545D01*
+X169318Y-609580D01*
+X185666D01*
+X186678Y-617937D01*
+X189657Y-625811D01*
+X194429Y-632746D01*
+X200719Y-638340D01*
+X208163Y-642272D01*
+X216330Y-644312D01*
+X220550Y-644582D01*
+X228904Y-643541D01*
+X236767Y-640536D01*
+X243686Y-635741D01*
+X249260Y-629432D01*
+X253166Y-621975D01*
+X255178Y-613801D01*
+X255434Y-609580D01*
+X317321D01*
+G03X373915Y-626466I33672J9570D01*
+G03X422505Y-622153I22074J27172D01*
+G02X431822Y-622586I4481J-4030D01*
+G03X490856Y-607050I25157J24338D01*
+G01X498666D01*
+X499678Y-615407D01*
+X502657Y-623281D01*
+X507429Y-630216D01*
+X513719Y-635810D01*
+X521163Y-639742D01*
+X529330Y-641782D01*
+X533550Y-642052D01*
+X541904Y-641011D01*
+X549767Y-638006D01*
+X556686Y-633210D01*
+X562260Y-626902D01*
+X566166Y-619444D01*
+X568178Y-611270D01*
+X568434Y-607050D01*
+X618044D01*
+G03X683935Y-608808I33260J10913D01*
+G02X694607Y-607902I5566J-2252D01*
+G03X756953Y-586049I27343J21853D01*
+G01X822449D01*
+X822449Y-684850D01*
+X753084D01*
+X752071Y-676493D01*
+X749093Y-668619D01*
+X744321Y-661684D01*
+X738031Y-656089D01*
+X730587Y-652158D01*
+X722420Y-650117D01*
+X718200Y-649848D01*
+X709846Y-650889D01*
+X701983Y-653894D01*
+X695064Y-658689D01*
+X689490Y-664998D01*
+X685584Y-672455D01*
+X683738Y-679950D01*
+X649334D01*
+X648321Y-671593D01*
+X645343Y-663719D01*
+X640571Y-656784D01*
+X634281Y-651189D01*
+X626837Y-647258D01*
+X618670Y-645217D01*
+X614450Y-644948D01*
+X606096Y-645989D01*
+X598233Y-648994D01*
+X591314Y-653789D01*
+X585740Y-660098D01*
+X581834Y-667555D01*
+X579821Y-675729D01*
+X579566Y-679950D01*
+X479366D01*
+X476121Y-675234D01*
+X469831Y-669639D01*
+X462387Y-665708D01*
+X454220Y-663667D01*
+X450000Y-663398D01*
+X441646Y-664439D01*
+X433783Y-667444D01*
+X426864Y-672239D01*
+X421290Y-678548D01*
+X417384Y-686005D01*
+X415371Y-694179D01*
+X415278Y-695720D01*
+X386420D01*
+G03X321025Y-678362I-35001J0D01*
+G02X310238Y-677639I-5218J2983D01*
+G03X249592Y-674012I-31361J-15549D01*
+G02X239491Y-673396I-4854J3529D01*
+G03X177625Y-674610I-30612J-16951D01*
+G02X167303Y-675133I-5319J2860D01*
+G03X106958Y-694740I-25600J-23877D01*
+G03X106696Y-699014I34738J-4275D01*
+G01X60991D01*
+X60781Y-697283D01*
+X57803Y-689409D01*
+X53031Y-682474D01*
+X46741Y-676879D01*
+X39297Y-672948D01*
+X31130Y-670907D01*
+X26910Y-670638D01*
+X18556Y-671678D01*
+X10693Y-674683D01*
+X3774Y-679479D01*
+X-1800Y-685788D01*
+X-5706Y-693245D01*
+X-7657Y-701170D01*
+X-25876D01*
+X-26888Y-692813D01*
+X-29867Y-684939D01*
+X-34639Y-678004D01*
+X-40929Y-672409D01*
+X-48373Y-668478D01*
+X-56540Y-666438D01*
+X-60760Y-666168D01*
+X-69114Y-667209D01*
+X-76977Y-670214D01*
+X-83896Y-675009D01*
+X-89469Y-681318D01*
+X-93375Y-688775D01*
+X-94521Y-693426D01*
+X-141740D01*
+G03X-208277Y-678191I-35013J0D01*
+G02X-218394Y-678409I-5128J3120D01*
+G03X-282269Y-693815I-29107J-19437D01*
+G03X-282503Y-697800I34780J-4040D01*
+G01X-327116D01*
+X-328128Y-689443D01*
+X-331107Y-681569D01*
+X-335879Y-674634D01*
+X-342169Y-669039D01*
+X-349613Y-665108D01*
+X-357780Y-663068D01*
+X-362000Y-662798D01*
+X-370354Y-663839D01*
+X-378217Y-666844D01*
+X-385136Y-671639D01*
+X-390709Y-677948D01*
+X-394615Y-685405D01*
+X-396313Y-692300D01*
+X-434566D01*
+X-435578Y-683943D01*
+X-438557Y-676069D01*
+X-443329Y-669134D01*
+X-449619Y-663539D01*
+X-457063Y-659608D01*
+X-465230Y-657568D01*
+X-469450Y-657298D01*
+X-477804Y-658339D01*
+X-485667Y-661344D01*
+X-492586Y-666139D01*
+X-498159Y-672448D01*
+X-502065Y-679905D01*
+X-504078Y-688079D01*
+X-504334Y-692300D01*
+X-541332D01*
+X-541151Y-635546D01*
+X-541639Y-631272D01*
+G37*
+G36*
+X-472349Y-483684D02*
+G03X-464047Y-461048I-26710J22636D01*
+G01X588999D01*
+G03X613632Y-396290I7650J34154D01*
+G02X611096Y-393300I3094J5195D01*
+G01X696466D01*
+X697478Y-401657D01*
+X700457Y-409531D01*
+X705229Y-416466D01*
+X711519Y-422060D01*
+X718963Y-425992D01*
+X727130Y-428032D01*
+X731350Y-428302D01*
+X739704Y-427261D01*
+X747567Y-424256D01*
+X754486Y-419460D01*
+X760060Y-413152D01*
+X763966Y-405694D01*
+X765978Y-397520D01*
+X766234Y-393300D01*
+X822450D01*
+X822449Y-489393D01*
+X758853D01*
+G03X698445Y-465307I-35006J0D01*
+G02X694590Y-465414I-1991J2221D01*
+G03X635438Y-488329I-24226J-25268D01*
+G03X635359Y-490687I34929J-2358D01*
+G01X510554D01*
+X505531Y-486219D01*
+X498087Y-482288D01*
+X489920Y-480247D01*
+X485700Y-479978D01*
+X477346Y-481019D01*
+X469483Y-484024D01*
+X462564Y-488819D01*
+X456990Y-495128D01*
+X454564Y-499760D01*
+X149604D01*
+X148591Y-491403D01*
+X145613Y-483529D01*
+X140841Y-476594D01*
+X134551Y-470999D01*
+X127107Y-467068D01*
+X118940Y-465027D01*
+X114720Y-464758D01*
+X106366Y-465798D01*
+X98503Y-468803D01*
+X91584Y-473599D01*
+X86010Y-479908D01*
+X82104Y-487365D01*
+X80091Y-495539D01*
+X79836Y-499760D01*
+X-183029D01*
+X-183528Y-495643D01*
+X-186507Y-487769D01*
+X-191279Y-480834D01*
+X-197569Y-475239D01*
+X-205013Y-471308D01*
+X-213180Y-469268D01*
+X-217400Y-468998D01*
+X-225754Y-470039D01*
+X-233617Y-473044D01*
+X-240536Y-477839D01*
+X-246109Y-484148D01*
+X-250015Y-491605D01*
+X-251861Y-499100D01*
+X-263066D01*
+X-264078Y-490743D01*
+X-267057Y-482869D01*
+X-271829Y-475934D01*
+X-278119Y-470339D01*
+X-285563Y-466408D01*
+X-293730Y-464368D01*
+X-297950Y-464098D01*
+X-306304Y-465139D01*
+X-314167Y-468144D01*
+X-321086Y-472939D01*
+X-326659Y-479248D01*
+X-330565Y-486705D01*
+X-332578Y-494879D01*
+X-332834Y-499100D01*
+X-464966D01*
+G03X-472349Y-483684I-34314J-6959D01*
+G37*
+G36*
+X-470355Y-387800D02*
+G01X-468660Y-385882D01*
+X-464754Y-378425D01*
+X-462741Y-370250D01*
+X-462486Y-366030D01*
+X-440365D01*
+X-442059Y-367948D01*
+X-445965Y-375405D01*
+X-447978Y-383579D01*
+X-448234Y-387800D01*
+X-470355D01*
+G37*
+G36*
+X-435136Y-697800D02*
+X-434821Y-696520D01*
+X-434566Y-692300D01*
+X-396313D01*
+X-396628Y-693579D01*
+X-396884Y-697800D01*
+X-435136D01*
+G37*
+G36*
+X-328607Y39190D02*
+G02X-328607Y39237I5998J0D01*
+G01X-328551Y47087D01*
+G02X-319576Y52254I5998J-40D01*
+G03X-269590Y69983I17357J30393D01*
+G02X-265956Y71777I2798J-1091D01*
+G03X-220388Y102449I10665J33341D01*
+G01X-159683D01*
+G03X-90485Y109934I35004J0D01*
+G02X-89641Y112574I2989J499D01*
+G02X-87186Y113787I6098J-9251D01*
+G03X-66959Y156537I-13221J32415D01*
+G02X-60901Y164300I5735J1770D01*
+G03X-45825Y166800I1949J34954D01*
+G02X-38216Y159723I1763J-5733D01*
+G03X-35732Y136892I34143J-7836D01*
+G02X-38604Y129312I-5572J-2223D01*
+G03X10593Y87653I15769J-31257D01*
+G01X41948D01*
+G03X106970Y69646I35004J0D01*
+G02X111264Y70481I2554J-1674D01*
+G03X134975Y136277I13431J32330D01*
+G02X133408Y140665I1131J2877D01*
+G03X129546Y164544I-34382J6691D01*
+G02X133722Y173100I5376J2674D01*
+G03X161751Y207403I-6977J34304D01*
+G01X199269D01*
+G03X199956Y200251I35014J-245D01*
+G02X194839Y193117I-5879J-1185D01*
+G03X233614Y165308I4461J-34717D01*
+G02X238731Y172443I5871J1192D01*
+G03X239382Y241787I-4461J34717D01*
+G02X234477Y249328I866J5929D01*
+G03X235751Y259005I-33768J9368D01*
+G02X242372Y265026I6004J48D01*
+G03X273185Y277804I3611J34833D01*
+G02X282938Y277197I4662J-3748D01*
+G03X294754Y265620I29685J18480D01*
+G02X294709Y255281I-3070J-5156D01*
+G03X283773Y204840I17634J-30229D01*
+G02X283158Y194917I-3867J-4741D01*
+G03X268485Y151840I17843J-30115D01*
+G02X263781Y143683I-5572J-2222D01*
+G03X261015Y74936I5081J-34634D01*
+G02X265467Y67537I-1337J-5844D01*
+G03X270153Y39080I33797J-9049D01*
+G02X268063Y30502I-4997J-3326D01*
+G03X259393Y-24005I16949J-30639D01*
+G01X246977D01*
+G03X236088Y1372I-35014J0D01*
+G02X235868Y9081I4462J3985D01*
+G03X173514Y33406I-27448J21721D01*
+G03X173415Y30778I34904J-2628D01*
+G01X36454D01*
+X36372Y31457D01*
+X33393Y39331D01*
+X28621Y46266D01*
+X22331Y51861D01*
+X14887Y55792D01*
+X6720Y57832D01*
+X2500Y58102D01*
+X-5854Y57061D01*
+X-13717Y54056D01*
+X-20636Y49261D01*
+X-26210Y42952D01*
+X-30116Y35495D01*
+X-32129Y27321D01*
+X-32384Y23100D01*
+X-205508D01*
+G03X-266540Y24263I-30843J-16553D01*
+G02X-276491Y23669I-5173J3011D01*
+G03X-319935Y33821I-27874J-21250D01*
+G02X-328607Y39190I-2674J5369D01*
+G37*
+G36*
+X-328498Y806488D02*
+G01X-328493Y806497D01*
+X-328487Y806499D01*
+X380901Y807197D01*
+X478098Y715549D01*
+X478099Y715544D01*
+X478058Y712167D01*
+X413015D01*
+G03X346590Y727631I-35013J0D01*
+G02X342087Y726526I-2737J1425D01*
+G03X310178Y720630I-10319J-33445D01*
+G02X301239Y722776I-3567J4833D01*
+G03X235189Y711502I-31319J-15632D01*
+G03X234920Y707171I34744J-4331D01*
+G01X221102D01*
+G03X161603Y724254I-34261J-7173D01*
+G02X157767Y723843I-2161J2064D01*
+G03X107739Y714828I-20746J-28194D01*
+G02X97496Y715166I-5019J3286D01*
+G03X38310Y717972I-30476J-17227D01*
+G02X27985Y718798I-4921J3432D01*
+G03X-30036Y726461I-31526J-15218D01*
+G02X-33846Y725846I-2273J1974D01*
+G03X-71361Y726410I-19202J-29305D01*
+G02X-80020Y729172I-3138J5116D01*
+G03X-142499Y733010I-32202J-13746D01*
+G02X-146127Y731699I-2590J1491D01*
+G03X-178963Y728518I-13439J-32344D01*
+G02X-187645Y730815I-3324J4994D01*
+G03X-247567Y735144I-31255J-15751D01*
+G02X-251294Y734148I-2454J1710D01*
+G03X-285587Y733042I-16161J-31110D01*
+G02X-293440Y734503I-3107J5134D01*
+G03X-322111Y748068I-27691J-21445D01*
+G02X-328281Y754040I-155J6013D01*
+G01X-328498Y806488D01*
+G37*
+G36*
+X-327938Y672078D02*
+G02X-321817Y678085I6009J0D01*
+G03X-302992Y683139I697J34990D01*
+G02X-295140Y681677I3104J-5146D01*
+G03X-238793Y683017I27680J21414D01*
+G02X-235066Y684012I2449J-1695D01*
+G03X-199507Y685922I16164J31027D01*
+G02X-190825Y683625I3323J-4996D01*
+G03X-129291Y681820I31255J15751D01*
+G02X-125662Y683130I2597J-1513D01*
+G03X-93909Y685620I13441J32310D01*
+G02X-85250Y682858I3139J-5114D01*
+G03X-26553Y673710I32200J13724D01*
+G02X-22744Y674324I2270J-1961D01*
+G03X25170Y683568I19208J29236D01*
+G02X35495Y682742I4921J-3437D01*
+G03X96301Y678773I31525J15208D01*
+G02X106544Y678434I5019J-3269D01*
+G03X162257Y671397I30479J17242D01*
+G02X166092Y671807I2163J-2090D01*
+G03X221102Y707171I20749J28191D01*
+G01X234920D01*
+G03X291512Y679599I35013J0D01*
+G02X300451Y677454I3569J-4826D01*
+G03X363170Y677608I31321J15624D01*
+G02X366763Y679007I2629J-1439D01*
+G03X413015Y712167I11239J33160D01*
+G01X478058D01*
+X477699Y682156D01*
+X477694Y682147D01*
+X453104Y662697D01*
+X453101Y662690D01*
+X453100Y662686D01*
+Y623793D01*
+G02X442855Y619555I-6000J2D01*
+G03X380530Y597137I-27313J-21911D01*
+G01X373549D01*
+G03X313750Y621852I-35007J0D01*
+G02X304390Y623585I-4016J4453D01*
+G03X246490Y630304I-31182J-15877D01*
+G02X242443Y630120I-2124J2131D01*
+G03X185166Y606687I-22455J-26832D01*
+G03X184998Y603256I34838J-3431D01*
+G01X171739D01*
+G03X104929Y615618I-34946J-2146D01*
+G02X94837Y614871I-5284J2843D01*
+G03X54337Y626645I-28046J-20929D01*
+G02X51603Y627088I-938J2869D01*
+G02X50065Y629289I7274J6721D01*
+G03X-14951Y614109I-30118J-17829D01*
+G03X-15050Y611480I34926J-2629D01*
+G01X-38020D01*
+G03X-100527Y614591I-32033J-14106D01*
+G02X-111108Y615225I-5118J3198D01*
+G03X-151688Y628553I-28944J-19686D01*
+G02X-154411Y629063I-867J2895D01*
+G02X-155893Y631298I8561J7286D01*
+G03X-221264Y617733I-30548J-17083D01*
+G03X-221441Y614212I34827J-3522D01*
+G01X-327696D01*
+X-327938Y672063D01*
+G02X-327938Y672078I6009J7D01*
+G37*
+G36*
+X-327696Y614212D02*
+G01X-221441D01*
+G03X-174802Y581197I35005J0D01*
+G02X-171254Y579685I871J-2876D01*
+G03X-170578Y578420I31208J15861D01*
+G01X-250196D01*
+X-251208Y586777D01*
+X-254187Y594651D01*
+X-258959Y601586D01*
+X-265249Y607180D01*
+X-272693Y611112D01*
+X-280860Y613152D01*
+X-285080Y613422D01*
+X-293434Y612381D01*
+X-301297Y609376D01*
+X-308216Y604581D01*
+X-313790Y598272D01*
+X-317696Y590815D01*
+X-319708Y582640D01*
+X-319964Y578420D01*
+X-327546D01*
+X-327696Y614212D01*
+G37*
+G36*
+X-327645Y174105D02*
+G02X-327645Y174155I5997J0D01*
+G01X-327246Y229505D01*
+X-321357Y237529D01*
+X-236572D01*
+G03X-222407Y209406I34999J0D01*
+G02X-221654Y205397I-1772J-2408D01*
+G03X-173063Y212174I27746J-21348D01*
+G02X-173668Y216396I1770J2408D01*
+G03X-177542Y263008I-27909J21147D01*
+G02X-173771Y272961I4478J3994D01*
+G03X-142913Y307717I-4144J34756D01*
+G01X-121570D01*
+G03X-116714Y303779I24392J25113D01*
+G02X-115982Y294962I-3665J-4743D01*
+G02X-118507Y293238I-7371J8084D01*
+G03X-130550Y242902I16907J-30654D01*
+G02X-130694Y239682I-2630J-1496D01*
+G02X-132495Y238170I-8182J7917D01*
+G03X-127274Y179067I21132J-27916D01*
+G02X-125775Y170347I-3262J-5050D01*
+G03X-134595Y138716I25368J-24119D01*
+G02X-135439Y136076I-2966J-506D01*
+G02X-137875Y134870I-6760J10591D01*
+G03X-159639Y104193I13198J-32422D01*
+G03X-159683Y102449I34960J-1744D01*
+G01X-220388D01*
+G03X-258315Y139992I-34903J2669D01*
+G02X-264741Y144937I-509J5986D01*
+G03X-318382Y169075I-34610J-5242D01*
+G02X-321648Y168108I-3266J5030D01*
+G02X-327645Y174105I-0J5997D01*
+G37*
+G36*
+X-327546Y578420D02*
+G01X-319964D01*
+X-318951Y570063D01*
+X-315973Y562189D01*
+X-311201Y555254D01*
+X-304911Y549659D01*
+X-297467Y545728D01*
+X-289300Y543687D01*
+X-285080Y543418D01*
+X-276726Y544458D01*
+X-268863Y547463D01*
+X-261944Y552259D01*
+X-256370Y558568D01*
+X-252464Y566025D01*
+X-250451Y574199D01*
+X-250196Y578420D01*
+X-170578D01*
+G03X-109572Y578319I30532J17126D01*
+G02X-100465Y579571I5080J-3204D01*
+G02X-98672Y577224I-13561J-12218D01*
+G03X-35052Y597374I28619J20150D01*
+G01X-12084D01*
+G03X32402Y578734I32059J14106D01*
+G02X36463Y576454I1035J-2913D01*
+G03X98651Y579412I30333J17475D01*
+G02X108743Y580158I5286J-2874D01*
+G03X171805Y601110I28050J20952D01*
+G01X185063D01*
+G03X246720Y580636I34941J2146D01*
+G02X250767Y580820I2124J-2118D01*
+G03X297999Y582958I22449J26857D01*
+G02X307360Y581226I4019J-4443D01*
+G03X373549Y597137I31182J15911D01*
+G01X380530D01*
+G03X442483Y575276I35012J506D01*
+G02X453100Y571443I4610J-3852D01*
+G01X453099Y550755D01*
+X453095Y550746D01*
+X407650Y507648D01*
+X403452Y499999D01*
+X285008D01*
+G03X221625Y520493I-35005J0D01*
+G02X211085Y522007I-4874J3516D01*
+G03X144330Y511239I-31935J-14327D01*
+G03X144148Y507675I34818J-3564D01*
+G01X83264D01*
+X83181Y508357D01*
+X80203Y516231D01*
+X75431Y523166D01*
+X69141Y528761D01*
+X61697Y532692D01*
+X53529Y534732D01*
+X49310Y535002D01*
+X40956Y533961D01*
+X33093Y530956D01*
+X26174Y526161D01*
+X20600Y519852D01*
+X16694Y512395D01*
+X14725Y504400D01*
+X6484D01*
+X5471Y512757D01*
+X2493Y520631D01*
+X-2279Y527566D01*
+X-8569Y533160D01*
+X-16013Y537092D01*
+X-24180Y539132D01*
+X-28400Y539402D01*
+X-36754Y538361D01*
+X-44617Y535356D01*
+X-51536Y530561D01*
+X-57110Y524252D01*
+X-61016Y516795D01*
+X-62236Y511840D01*
+X-147436D01*
+X-148448Y520197D01*
+X-151427Y528071D01*
+X-156199Y535006D01*
+X-162489Y540600D01*
+X-169933Y544532D01*
+X-178100Y546572D01*
+X-182320Y546842D01*
+X-190674Y545801D01*
+X-198537Y542796D01*
+X-205456Y538000D01*
+X-211030Y531692D01*
+X-214936Y524234D01*
+X-216948Y516060D01*
+X-217204Y511840D01*
+X-226893D01*
+X-228857Y517031D01*
+X-233629Y523966D01*
+X-239919Y529560D01*
+X-247363Y533492D01*
+X-255530Y535532D01*
+X-259750Y535802D01*
+X-268104Y534761D01*
+X-275967Y531756D01*
+X-282886Y526961D01*
+X-288460Y520652D01*
+X-292366Y513195D01*
+X-294378Y505020D01*
+X-294634Y500800D01*
+X-327221D01*
+X-327546Y578420D01*
+G37*
+G36*
+X-327221Y500800D02*
+X-294634D01*
+X-293621Y492443D01*
+X-290643Y484569D01*
+X-285871Y477634D01*
+X-279581Y472039D01*
+X-272137Y468108D01*
+X-263970Y466067D01*
+X-259750Y465798D01*
+X-251396Y466838D01*
+X-243533Y469843D01*
+X-236614Y474639D01*
+X-231040Y480948D01*
+X-227134Y488405D01*
+X-225121Y496579D01*
+X-224866Y500800D01*
+X-215176D01*
+X-213213Y495609D01*
+X-208441Y488674D01*
+X-202151Y483079D01*
+X-194707Y479148D01*
+X-186540Y477107D01*
+X-182320Y476838D01*
+X-173966Y477878D01*
+X-166103Y480883D01*
+X-159184Y485679D01*
+X-153610Y491988D01*
+X-149704Y499445D01*
+X-148484Y504400D01*
+X-63284D01*
+X-62271Y496043D01*
+X-59293Y488169D01*
+X-54521Y481234D01*
+X-48231Y475639D01*
+X-40787Y471708D01*
+X-32620Y469667D01*
+X-28400Y469398D01*
+X-20046Y470438D01*
+X-12183Y473443D01*
+X-5264Y478239D01*
+X310Y484548D01*
+X4216Y492005D01*
+X6184Y500000D01*
+X14426D01*
+X15438Y491643D01*
+X18417Y483769D01*
+X23189Y476834D01*
+X29479Y471239D01*
+X36923Y467308D01*
+X45090Y465268D01*
+X49310Y464998D01*
+X57664Y466039D01*
+X65527Y469044D01*
+X72446Y473839D01*
+X78019Y480148D01*
+X81926Y487605D01*
+X83938Y495779D01*
+X84194Y500000D01*
+X145000D01*
+G03X207568Y487246I34149J7675D01*
+G02X218065Y485672I4832J-3566D01*
+G03X285008Y499999I31938J14327D01*
+G01X403452D01*
+X398047Y490151D01*
+X367198Y473095D01*
+X340150Y433849D01*
+X337331Y427970D01*
+X337326Y427968D01*
+G03X287546Y408074I-16496J-30950D01*
+G03X307025Y364666I33253J-11152D01*
+G01X302902Y356050D01*
+Y356043D01*
+X307263Y330406D01*
+G03X285455Y317737I5544J-34648D01*
+G02X275702Y318343I-4660J3778D01*
+G03X210989Y299526I-29714J-18495D01*
+G02X210974Y299056I-6003J-51D01*
+G01X158961D01*
+G03X93444Y316221I-35007J0D01*
+G02X83058Y316537I-5102J3147D01*
+G03X38125Y332016I-30839J-16564D01*
+G02X30241Y338359I-1905J5704D01*
+G03X-39527Y340889I-34790J3860D01*
+G02X-45807Y334650I-6026J-215D01*
+G03X-55219Y332957I1442J-35023D01*
+G02X-62756Y339217I-1455J5915D01*
+G03X-121570Y307717I-34421J-6387D01*
+G01X-142913D01*
+G03X-201918Y282241I-35003J0D01*
+G02X-203239Y273144I-4488J-3993D01*
+G02X-206724Y272150I-4542J9318D01*
+G03X-236345Y241511I5170J-34636D01*
+G03X-236572Y237529I34771J-3982D01*
+G01X-321357D01*
+X-300351Y266150D01*
+X-290275Y289508D01*
+G03X-317419Y349216I-24717J24787D01*
+G01X-326592Y352349D01*
+X-326599Y352358D01*
+X-326600Y352362D01*
+X-327221Y500800D01*
+G37*
+G36*
+X-327119Y-697855D02*
+X-327116Y-697800D01*
+X-282503D01*
+G03X-282503Y-697855I35014J-55D01*
+G01X-327119D01*
+G37*
+G36*
+X-292194Y-241299D02*
+G02X-291004Y-237711I6006J0D01*
+G01X-287757Y-232469D01*
+G02X-284115Y-231207I2566J-1518D01*
+G03X-236876Y-202440I12459J32711D01*
+G01X-187951D01*
+G03X-134618Y-232269I35008J0D01*
+G02X-130823Y-232960I1486J-2608D01*
+G03X-73128Y-233196I28929J19735D01*
+G02X-69357Y-232397I2362J-1848D01*
+G03X-43203Y-235149I16474J30904D01*
+G02X-36450Y-238874I1154J-5892D01*
+G03X22570Y-203224I32654J12620D01*
+G02X23333Y-195155I4788J3618D01*
+G03X34862Y-169188I-23477J25967D01*
+G01X52049D01*
+G03X98604Y-219601I28362J-20511D01*
+G02X102689Y-220548I1557J-2565D01*
+G03X133933Y-166722I29480J18869D01*
+G02X129073Y-157671I304J5993D01*
+G03X133948Y-138835I-30111J17842D01*
+G02X139777Y-132668I5999J168D01*
+G03X166567Y-122935I2468J34943D01*
+G02X175346Y-123424I4162J-4328D01*
+G03X228599Y-124145I26934J22357D01*
+G02X237726Y-124266I4512J-3978D01*
+G03X281190Y-132747I26923J22360D01*
+G02X289159Y-134929I2833J-5298D01*
+G03X351994Y-128762I29941J18125D01*
+G02X360170Y-125376I5629J-2029D01*
+G03X368881Y-128969I17582J30269D01*
+G02X372991Y-136805I-1532J-5800D01*
+G03X369882Y-156541I31594J-15090D01*
+G02X367558Y-159863I-2977J-392D01*
+G03X339456Y-193440I6912J-34333D01*
+G02X329910Y-198150I-5988J107D01*
+G03X299058Y-190060I-23329J-26092D01*
+G02X295566Y-188064I-639J2936D01*
+G03X245390Y-168324I-33264J-10912D01*
+G02X241847Y-167434I-1191J2754D01*
+G03X229320Y-217036I-29450J-18945D01*
+G02X232863Y-217926I1191J-2755D01*
+G03X270062Y-233125I29452J18962D01*
+G02X273294Y-235166I376J-2984D01*
+G03X341578Y-224466I33269J10919D01*
+G02X351480Y-220591I5965J-653D01*
+G03X398528Y-219585I22970J26420D01*
+G02X407308Y-220151I4128J-4342D01*
+G03X450317Y-166850I27144J22100D01*
+G01X663566D01*
+X664578Y-175207D01*
+X667557Y-183081D01*
+X672329Y-190016D01*
+X678619Y-195610D01*
+X686063Y-199542D01*
+X694230Y-201582D01*
+X698450Y-201852D01*
+X706804Y-200811D01*
+X714667Y-197806D01*
+X721586Y-193010D01*
+X727160Y-186702D01*
+X731066Y-179244D01*
+X733078Y-171070D01*
+X733334Y-166850D01*
+X767667D01*
+G03X813490Y-177045I28551J20250D01*
+G02X822450Y-182265I2960J-5219D01*
+G01Y-238465D01*
+G02X812852Y-243264I-5992J-14D01*
+G03X757157Y-275740I-20980J-28016D01*
+G01X722574D01*
+X721562Y-267383D01*
+X718583Y-259509D01*
+X713811Y-252574D01*
+X707521Y-246979D01*
+X700077Y-243048D01*
+X691910Y-241007D01*
+X687690Y-240738D01*
+X679336Y-241779D01*
+X671473Y-244784D01*
+X664554Y-249579D01*
+X658980Y-255888D01*
+X655074Y-263345D01*
+X653061Y-271519D01*
+X652806Y-275740D01*
+X367347D01*
+X361511Y-270549D01*
+X354067Y-266618D01*
+X345900Y-264577D01*
+X341680Y-264308D01*
+X333326Y-265348D01*
+X325463Y-268353D01*
+X318544Y-273149D01*
+X312970Y-279458D01*
+X309064Y-286915D01*
+X307051Y-295089D01*
+X306796Y-299310D01*
+X246876D01*
+X246263Y-297689D01*
+X241491Y-290754D01*
+X235201Y-285159D01*
+X227757Y-281228D01*
+X219590Y-279187D01*
+X215370Y-278918D01*
+X207016Y-279958D01*
+X199153Y-282963D01*
+X192234Y-287759D01*
+X191906Y-288130D01*
+X117754D01*
+X116742Y-279773D01*
+X113763Y-271899D01*
+X108991Y-264964D01*
+X102701Y-259369D01*
+X95257Y-255438D01*
+X87090Y-253397D01*
+X82870Y-253128D01*
+X74516Y-254168D01*
+X66653Y-257173D01*
+X59734Y-261969D01*
+X54160Y-268278D01*
+X50254Y-275735D01*
+X48241Y-283909D01*
+X47986Y-288130D01*
+X-48114D01*
+X-50829Y-284184D01*
+X-57119Y-278589D01*
+X-64563Y-274658D01*
+X-72730Y-272618D01*
+X-76950Y-272348D01*
+X-85304Y-273389D01*
+X-93167Y-276394D01*
+X-100086Y-281189D01*
+X-105659Y-287498D01*
+X-107244Y-290524D01*
+X-159323D01*
+G03X-225250Y-274113I-35006J0D01*
+G02X-233473Y-276207I-5153J3044D01*
+G03X-266342Y-271453I-20849J-28145D01*
+G02X-273696Y-267223I-1556J5803D01*
+G03X-289312Y-246428I-33784J-9109D01*
+G02X-292194Y-241299I3124J5129D01*
+G37*
+G36*
+X-263488Y-504000D02*
+G01X-263321Y-503321D01*
+X-263066Y-499100D01*
+X-251861D01*
+X-252028Y-499779D01*
+X-252284Y-504000D01*
+X-263488D01*
+G37*
+G36*
+X-248195Y-597550D02*
+X-219684D01*
+X-219605Y-598200D01*
+X-248116D01*
+X-248195Y-597550D01*
+G37*
+G36*
+X-226893Y511840D02*
+X-217204D01*
+X-216191Y503483D01*
+X-215176Y500800D01*
+X-224866D01*
+X-225878Y509157D01*
+X-226893Y511840D01*
+G37*
+G36*
+X-183029Y-499760D02*
+X79836D01*
+X80350Y-504000D01*
+X-182516D01*
+X-183029Y-499760D01*
+G37*
+G36*
+X-175484Y-323145D02*
+G02X-173119Y-318373I5997J0D01*
+G03X-163632Y-307350I-21210J27849D01*
+G01X-111834D01*
+X-110821Y-315707D01*
+X-107843Y-323581D01*
+X-103071Y-330516D01*
+X-96781Y-336111D01*
+X-89337Y-340042D01*
+X-81170Y-342082D01*
+X-76950Y-342352D01*
+X-68596Y-341311D01*
+X-60733Y-338306D01*
+X-53814Y-333511D01*
+X-48240Y-327202D01*
+X-46762Y-324380D01*
+X-28744D01*
+X-27731Y-332737D01*
+X-24753Y-340611D01*
+X-19981Y-347546D01*
+X-13691Y-353140D01*
+X-6247Y-357072D01*
+X1920Y-359112D01*
+X6140Y-359382D01*
+X14494Y-358341D01*
+X22357Y-355336D01*
+X29276Y-350541D01*
+X34850Y-344232D01*
+X38756Y-336775D01*
+X40768Y-328600D01*
+X41024Y-324380D01*
+X182294D01*
+X184477Y-330151D01*
+X189249Y-337086D01*
+X195539Y-342680D01*
+X202983Y-346612D01*
+X211150Y-348652D01*
+X215370Y-348922D01*
+X223724Y-347881D01*
+X231587Y-344876D01*
+X238506Y-340081D01*
+X244080Y-333772D01*
+X247986Y-326315D01*
+X249998Y-318141D01*
+X250254Y-313920D01*
+X310174D01*
+X310787Y-315541D01*
+X315559Y-322476D01*
+X321849Y-328070D01*
+X329293Y-332002D01*
+X337460Y-334042D01*
+X341680Y-334312D01*
+X350034Y-333271D01*
+X357897Y-330266D01*
+X364816Y-325471D01*
+X370390Y-319162D01*
+X374296Y-311705D01*
+X376308Y-303531D01*
+X376564Y-299310D01*
+X662023D01*
+X667859Y-304500D01*
+X675303Y-308432D01*
+X683470Y-310472D01*
+X687690Y-310742D01*
+X696044Y-309701D01*
+X703907Y-306696D01*
+X710826Y-301900D01*
+X716400Y-295592D01*
+X720306Y-288134D01*
+X722318Y-279960D01*
+X722574Y-275740D01*
+X757157D01*
+G03X812853Y-299295I34715J4460D01*
+G02X822450Y-304098I3605J-4785D01*
+G01X822450Y-353751D01*
+X634860D01*
+G03X582878Y-384360I-35003J0D01*
+G02X581456Y-395367I-3056J-5201D01*
+G03X579838Y-396200I15220J-31550D01*
+G01X551434D01*
+X550422Y-387843D01*
+X547443Y-379969D01*
+X542671Y-373034D01*
+X536381Y-367439D01*
+X528937Y-363508D01*
+X520770Y-361467D01*
+X516550Y-361198D01*
+X508670Y-362180D01*
+X436384D01*
+X435372Y-353823D01*
+X432393Y-345949D01*
+X427621Y-339014D01*
+X421331Y-333419D01*
+X413887Y-329488D01*
+X405720Y-327447D01*
+X401500Y-327178D01*
+X393146Y-328218D01*
+X385283Y-331223D01*
+X378364Y-336019D01*
+X372790Y-342328D01*
+X368884Y-349785D01*
+X366871Y-357959D01*
+X366616Y-362180D01*
+X-166973D01*
+G03X-174257Y-326780I-33015J11656D01*
+G02X-175484Y-323145I4770J3635D01*
+G37*
+G36*
+X-163632Y-307350D02*
+G03X-159323Y-290524I-30697J16826D01*
+G01X-107244D01*
+X-109565Y-294955D01*
+X-111578Y-303129D01*
+X-111834Y-307350D01*
+X-163632D01*
+G37*
+G36*
+X-150402Y-602710D02*
+X-150171Y-601771D01*
+X-149916Y-597550D01*
+X-100667D01*
+X-100898Y-598489D01*
+X-101154Y-602710D01*
+X-150402D01*
+G37*
+G36*
+X-148484Y504400D02*
+X-147691Y507619D01*
+X-147436Y511840D01*
+X-62236D01*
+X-63028Y508620D01*
+X-63284Y504400D01*
+X-148484D01*
+G37*
+G36*
+X-142607Y-701170D02*
+G03X-141740Y-693426I-34146J7744D01*
+G01X-94521D01*
+X-95388Y-696949D01*
+X-95644Y-701170D01*
+X-142607D01*
+G37*
+G36*
+X-91652Y-15450D02*
+X50016D01*
+X51028Y-23807D01*
+X54007Y-31681D01*
+X58779Y-38616D01*
+X65069Y-44210D01*
+X72513Y-48142D01*
+X80680Y-50182D01*
+X84900Y-50452D01*
+X93254Y-49411D01*
+X101117Y-46406D01*
+X108036Y-41611D01*
+X113610Y-35302D01*
+X117516Y-27845D01*
+X119528Y-19670D01*
+X119784Y-15450D01*
+X178010D01*
+G03X246977Y-24005I33953J-8555D01*
+G01X259393D01*
+G03X315285Y-17732I25620J23868D01*
+G02X325243Y-18117I4850J-3534D01*
+G03X358633Y-34567I29801J18377D01*
+G02X365247Y-40444I612J-5971D01*
+G03X368260Y-54556I34977J90D01*
+G02X364979Y-62573I-5482J-2436D01*
+G03X344936Y-83168I12853J-32559D01*
+G02X336759Y-86554I-5640J2054D01*
+G03X302559Y-85953I-17637J-30275D01*
+G02X294591Y-83771I-2834J5292D01*
+G03X238330Y-78826I-29940J-18122D01*
+G02X229204Y-78704I-4511J3975D01*
+G03X177994Y-75864I-26925J-22381D01*
+G02X169214Y-75376I-4163J4332D01*
+G03X107292Y-98725I-26934J-22356D01*
+G02X101463Y-104892I-6022J-146D01*
+G01X97897Y-104844D01*
+G03X90210Y-105939I1066J-35009D01*
+G02X82724Y-99729I-1511J5796D01*
+G03X56549Y-131291I-34926J2331D01*
+G02X64036Y-137501I1500J-5809D01*
+G03X66991Y-154084I35007J-2317D01*
+G02X65527Y-158020I-2743J-1220D01*
+G03X52049Y-169188I14884J-31679D01*
+G01X34862D01*
+G03X-34717Y-163698I-35006J0D01*
+G02X-42380Y-168119I-5861J1307D01*
+G03X-59576Y-167135I-10537J-33404D01*
+G02X-66313Y-159584I-964J5921D01*
+G03X-65290Y-145561I-33613J9501D01*
+G02X-58032Y-139017I5971J675D01*
+G03X-60849Y-70182I4831J34673D01*
+G02X-67362Y-62085I-917J5930D01*
+G03X-91652Y-15450I-32637J12644D01*
+G37*
+G36*
+X-82808Y231451D02*
+G02X-81531Y233913I3010J0D01*
+G03X-66591Y262412I-20069J28686D01*
+G02X-58218Y267560I5980J-343D01*
+G03X-9333Y300991I13907J32121D01*
+G02X-2712Y307246I6041J238D01*
+G03X9555Y310143I-1781J34960D01*
+G02X17305Y305878I1920J-5685D01*
+G02X17347Y302840I-10874J-1670D01*
+G03X82736Y282789I34885J-2883D01*
+G02X91833Y284107I5102J-3160D01*
+G02X93724Y281402I-9665J-8770D01*
+G03X158961Y299056I30230J17654D01*
+G01X210974D01*
+G02X204368Y293504I-5988J419D01*
+G03X195639Y224063I-3618J-34815D01*
+G02X200543Y216522I-897J-5949D01*
+G03X199269Y207403I33740J-9363D01*
+G01X161751D01*
+G03X96255Y190206I-35006J0D01*
+G02X92079Y181651I-5373J-2674D01*
+G03X69021Y129358I6958J-34298D01*
+G02X66177Y120982I-5251J-2888D01*
+G01X60065Y118310D01*
+X54998Y114913D01*
+G03X42150Y91405I21922J-27246D01*
+G03X41948Y87653I34803J-3752D01*
+G01X10593D01*
+G03X8792Y113068I-33428J10402D01*
+G02X11663Y120648I5574J2223D01*
+G03X23948Y172847I-15776J31258D01*
+G02X23712Y179289I4953J3407D01*
+G02X26882Y182211I13361J-11315D01*
+G03X-25431Y226191I-21273J27799D01*
+G02X-35505Y225195I-5360J2770D01*
+G03X-78198Y228530I-23505J-25964D01*
+G02X-82631Y230433I-1472J2685D01*
+G02X-82808Y231451I2832J1018D01*
+G37*
+G36*
+X-48114Y-288130D02*
+G01X47986D01*
+X48998Y-296487D01*
+X51977Y-304361D01*
+X56749Y-311296D01*
+X63039Y-316890D01*
+X70483Y-320822D01*
+X78650Y-322862D01*
+X82870Y-323132D01*
+X91224Y-322091D01*
+X99087Y-319086D01*
+X106006Y-314291D01*
+X106334Y-313920D01*
+X180486D01*
+X181498Y-322277D01*
+X182294Y-324380D01*
+X41024D01*
+X40012Y-316023D01*
+X37033Y-308149D01*
+X32261Y-301214D01*
+X25971Y-295619D01*
+X18527Y-291688D01*
+X10360Y-289647D01*
+X6140Y-289378D01*
+X-2214Y-290418D01*
+X-10077Y-293423D01*
+X-16996Y-298219D01*
+X-22570Y-304528D01*
+X-24048Y-307350D01*
+X-42066D01*
+X-43078Y-298993D01*
+X-46057Y-291119D01*
+X-48114Y-288130D01*
+G37*
+G36*
+X-46762Y-324380D02*
+X-44334Y-319745D01*
+X-42321Y-311571D01*
+X-42066Y-307350D01*
+X-24048D01*
+X-26476Y-311985D01*
+X-28488Y-320159D01*
+X-28744Y-324380D01*
+X-46762D01*
+G37*
+G36*
+X-38020Y611480D02*
+X-15050D01*
+G03X-12084Y597374I35025J0D01*
+G01X-35052D01*
+G03X-38020Y611480I-35001J0D01*
+G37*
+G36*
+X-31607Y-606370D02*
+G01X-31386Y-602710D01*
+X-15132D01*
+X-15354Y-606370D01*
+X-31607D01*
+G37*
+G36*
+X-26192Y-705640D02*
+X-26131Y-705391D01*
+X-25876Y-701170D01*
+X-7657D01*
+X-7718Y-701419D01*
+X-7974Y-705640D01*
+X-26192D01*
+G37*
+G36*
+X6184Y500000D02*
+X6228Y500179D01*
+X6484Y504400D01*
+X14725D01*
+X14681Y504221D01*
+X14426Y500000D01*
+X6184D01*
+G37*
+G36*
+X36454Y30778D02*
+X173415D01*
+G03X174268Y23100I35003J0D01*
+G01X37384D01*
+X36454Y30778D01*
+G37*
+G36*
+X53903Y-602150D02*
+X100596D01*
+X101107Y-606370D01*
+X54414D01*
+X53903Y-602150D01*
+G37*
+G36*
+X60991Y-699014D02*
+X106696D01*
+G03X107329Y-705640I35000J0D01*
+G01X61794D01*
+X60991Y-699014D01*
+G37*
+G36*
+X83264Y507675D02*
+X144148D01*
+G03X145000Y500000I35000J0D01*
+G01X84194D01*
+X83264Y507675D01*
+G37*
+G36*
+X106334Y-313920D02*
+X111580Y-307982D01*
+X115486Y-300525D01*
+X117498Y-292350D01*
+X117754Y-288130D01*
+X191906D01*
+X186660Y-294068D01*
+X182754Y-301525D01*
+X180741Y-309699D01*
+X180486Y-313920D01*
+X106334D01*
+G37*
+G36*
+X145856Y-514980D02*
+X147336Y-512155D01*
+X149348Y-503980D01*
+X149604Y-499760D01*
+X454564D01*
+X453084Y-502585D01*
+X451071Y-510759D01*
+X450816Y-514980D01*
+X145856D01*
+G37*
+G36*
+X169318Y-609580D02*
+X170108Y-606370D01*
+X170364Y-602150D01*
+X186711D01*
+X185921Y-605359D01*
+X185666Y-609580D01*
+X169318D01*
+G37*
+G36*
+X171739Y603256D02*
+X184998D01*
+G03X185063Y601110I35006J0D01*
+G01X171805D01*
+G03X171739Y603256I-35012J1D01*
+G37*
+G36*
+X246876Y-299310D02*
+G01X306796D01*
+X307808Y-307667D01*
+X310174Y-313920D01*
+X250254D01*
+X249242Y-305563D01*
+X246876Y-299310D01*
+G37*
+G36*
+X253962Y-600009D02*
+X315987D01*
+G03X317321Y-609580I35006J0D01*
+G01X255434D01*
+X254421Y-601223D01*
+X253962Y-600009D01*
+G37*
+G36*
+X367347Y-275740D02*
+X652806D01*
+X653818Y-284097D01*
+X656797Y-291971D01*
+X661569Y-298906D01*
+X662023Y-299310D01*
+X376564D01*
+X375552Y-290953D01*
+X372573Y-283079D01*
+X367801Y-276144D01*
+X367347Y-275740D01*
+G37*
+G36*
+X386318Y-698400D02*
+G03X386420Y-695720I-34899J2681D01*
+G01X415278D01*
+X415116Y-698400D01*
+X386318D01*
+G37*
+G36*
+X409061Y-112304D02*
+G02X409419Y-110264I5995J0D01*
+G03X412376Y-89501I-31620J15095D01*
+G02X417888Y-82550I5929J960D01*
+G01X565974Y-72343D01*
+X565984Y-72347D01*
+G03X635463Y-76893I35016J1951D01*
+G01X662699Y-41555D01*
+X662708Y-41550D01*
+X664956Y-41471D01*
+G02X670460Y-50286I199J-6002D01*
+G03X727203Y-48297I29090J-19510D01*
+G02X732084Y-39123I5091J3177D01*
+G01X761599Y-38090D01*
+G02X766906Y-47250I195J-6004D01*
+G03X813554Y-96349I29745J-18450D01*
+G02X822450Y-101605I2890J-5265D01*
+G01Y-110938D01*
+G02X813490Y-116155I-5996J-6D01*
+G03X767667Y-166850I-17272J-30445D01*
+G01X733334D01*
+X732322Y-158493D01*
+X729343Y-150619D01*
+X724571Y-143684D01*
+X718281Y-138089D01*
+X710837Y-134158D01*
+X702670Y-132117D01*
+X698450Y-131848D01*
+X690096Y-132889D01*
+X682233Y-135894D01*
+X675314Y-140689D01*
+X669740Y-146998D01*
+X665834Y-154455D01*
+X663821Y-162629D01*
+X663566Y-166850D01*
+X450317D01*
+G03X443509Y-164240I-15865J-31201D01*
+G02X439139Y-157493I1580J5812D01*
+G03X413529Y-118101I-34566J5549D01*
+G02X409061Y-112304I1527J5797D01*
+G37*
+G36*
+X409380Y-396200D02*
+G01X409854Y-396141D01*
+X417717Y-393136D01*
+X424636Y-388341D01*
+X430210Y-382032D01*
+X434116Y-374575D01*
+X436128Y-366401D01*
+X436384Y-362180D01*
+X508670D01*
+X508196Y-362239D01*
+X500333Y-365244D01*
+X493414Y-370039D01*
+X487840Y-376348D01*
+X483934Y-383805D01*
+X481921Y-391979D01*
+X481666Y-396200D01*
+X409380D01*
+G37*
+G36*
+X479366Y-679950D02*
+X579566D01*
+X580578Y-688307D01*
+X583557Y-696181D01*
+X585084Y-698400D01*
+X484884D01*
+X483871Y-690043D01*
+X480893Y-682169D01*
+X479366Y-679950D01*
+G37*
+G36*
+X490856Y-607050D02*
+G03X491981Y-598248I-33878J8802D01*
+G01X500049D01*
+X498921Y-602829D01*
+X498666Y-607050D01*
+X490856D01*
+G37*
+G36*
+X510554Y-490687D02*
+X635359D01*
+G03X645159Y-514980I35009J0D01*
+G01X520584D01*
+X519571Y-506623D01*
+X516593Y-498749D01*
+X511821Y-491814D01*
+X510554Y-490687D01*
+G37*
+G36*
+X533145Y-426894D02*
+X539686Y-422360D01*
+X545260Y-416052D01*
+X549166Y-408594D01*
+X551178Y-400420D01*
+X551434Y-396200D01*
+X579838D01*
+G03X561745Y-424293I16838J-30717D01*
+G03X561648Y-426894I34904J-2601D01*
+G01X533145D01*
+G37*
+G36*
+X566455Y-596137D02*
+X616300D01*
+G03X618044Y-607050I35005J0D01*
+G01X568434D01*
+X567421Y-598693D01*
+X566455Y-596137D01*
+G37*
+G36*
+X610679Y-391095D02*
+G02X615054Y-385283I6047J0D01*
+G03X634860Y-353751I-15197J31532D01*
+G01X822450D01*
+Y-393300D01*
+X766234D01*
+X765222Y-384943D01*
+X762243Y-377069D01*
+X757471Y-370134D01*
+X751181Y-364539D01*
+X743737Y-360608D01*
+X735570Y-358567D01*
+X731350Y-358298D01*
+X722996Y-359339D01*
+X715133Y-362344D01*
+X708214Y-367139D01*
+X702640Y-373448D01*
+X698734Y-380905D01*
+X696721Y-389079D01*
+X696466Y-393300D01*
+X611096D01*
+G02X610679Y-391095I5630J2206D01*
+G37*
+G36*
+X648911Y-684850D02*
+G01X649078Y-684170D01*
+X649334Y-679950D01*
+X683738D01*
+X683571Y-680629D01*
+X683316Y-684850D01*
+X648911D01*
+G37*
+G36*
+X611267Y-393141D02*
+X696307D01*
+G02X696307Y-393459I0J-159D01*
+G01X611267D01*
+G02X611267Y-393141I0J159D01*
+G37*
+G36*
+X766393D02*
+G01X822291D01*
+G02X822291Y-393459I0J-159D01*
+G01X766393D01*
+G02X766393Y-393141I0J159D01*
+G37*
+G36*
+X649074Y-684691D02*
+G01X683157D01*
+G02X683157Y-685009I0J-159D01*
+G01X649074D01*
+G02X649074Y-684691I0J159D01*
+G37*
+G36*
+X753243D02*
+G01X822290D01*
+G02X822290Y-685009I0J-159D01*
+G01X753243D01*
+G02X753243Y-684691I0J159D01*
+G37*
+G36*
+X450665Y-166691D02*
+G01X663407D01*
+G02X663407Y-167009I0J-159D01*
+G01X450665D01*
+G02X450665Y-166691I0J159D01*
+G37*
+G36*
+X733493D02*
+G01X767473D01*
+G02X767473Y-167009I0J-159D01*
+G01X733493D01*
+G02X733493Y-166691I0J159D01*
+G37*
+G36*
+X367585Y-275581D02*
+G01X652647D01*
+G02X652647Y-275899I0J-159D01*
+G01X367585D01*
+G02X367585Y-275581I0J159D01*
+G37*
+G36*
+X722733D02*
+G01X756997D01*
+G02X756997Y-275899I0J-159D01*
+G01X722733D01*
+G02X722733Y-275581I0J159D01*
+G37*
+G36*
+X759012Y-489233D02*
+G01X822290D01*
+G02X822290Y-489551I0J-159D01*
+G01X759012D01*
+G02X759012Y-489233I0J159D01*
+G37*
+G36*
+X510793Y-490528D02*
+G01X635200D01*
+G02X635200Y-490846I0J-159D01*
+G01X510793D01*
+G02X510793Y-490528I0J159D01*
+G37*
+G36*
+X757111Y-585890D02*
+G01X822290D01*
+G02X822290Y-586208I0J-159D01*
+G01X757111D01*
+G02X757111Y-585890I0J159D01*
+G37*
+G36*
+X566624Y-595978D02*
+G01X616141D01*
+G02X616141Y-596296I0J-159D01*
+G01X566624D01*
+G02X566624Y-595978I0J159D01*
+G37*
+G36*
+X479559Y-679791D02*
+G01X579407D01*
+G02X579407Y-680109I0J-159D01*
+G01X479559D01*
+G02X479559Y-679791I0J159D01*
+G37*
+G36*
+X649493D02*
+G01X683575D01*
+G02X683575Y-680109I0J-159D01*
+G01X649493D01*
+G02X649493Y-679791I0J159D01*
+G37*
+G36*
+X635019Y-353592D02*
+G01X822291D01*
+G02X822291Y-353910I0J-159D01*
+G01X635019D01*
+G02X635019Y-353592I0J159D01*
+G37*
+G36*
+X533424Y-426735D02*
+G01X561490D01*
+G02X561490Y-427053I0J-159D01*
+G01X533424D01*
+G02X533424Y-426735I0J159D01*
+G37*
+G36*
+X491020Y-606891D02*
+G01X498507D01*
+G02X498507Y-607209I0J-159D01*
+G01X491020D01*
+G02X491020Y-606891I0J159D01*
+G37*
+G36*
+X568593D02*
+G01X617877D01*
+G02X617877Y-607209I0J-159D01*
+G01X568593D01*
+G02X568593Y-606891I0J159D01*
+G37*
+G36*
+X410145Y-396041D02*
+G01X481507D01*
+G02X481507Y-396359I0J-159D01*
+G01X410145D01*
+G02X410145Y-396041I0J159D01*
+G37*
+G36*
+X551593D02*
+G01X579510D01*
+G02X579510Y-396359I0J-159D01*
+G01X551593D01*
+G02X551593Y-396041I0J159D01*
+G37*
+G36*
+X146036Y-514821D02*
+G01X450657D01*
+G02X450657Y-515139I0J-159D01*
+G01X146036D01*
+G02X146036Y-514821I0J159D01*
+G37*
+G36*
+X520743D02*
+G01X644939D01*
+G02X644939Y-515139I0J-159D01*
+G01X520743D01*
+G02X520743Y-514821I0J159D01*
+G37*
+G36*
+X386477Y-698241D02*
+G01X414957D01*
+G02X414957Y-698559I0J-159D01*
+G01X386477D01*
+G02X386477Y-698241I0J159D01*
+G37*
+G36*
+X485043D02*
+G01X584891D01*
+G02X584891Y-698559I0J-159D01*
+G01X485043D01*
+G02X485043Y-698241I0J159D01*
+G37*
+G36*
+X-166805Y-362021D02*
+G01X366457D01*
+G02X366457Y-362339I0J-159D01*
+G01X-166805D01*
+G02X-166805Y-362021I0J159D01*
+G37*
+G36*
+X436543D02*
+G01X507905D01*
+G02X507905Y-362339I0J-159D01*
+G01X436543D01*
+G02X436543Y-362021I0J159D01*
+G37*
+G36*
+X492140Y-598089D02*
+G01X499886D01*
+G02X499886Y-598407I0J-159D01*
+G01X492140D01*
+G02X492140Y-598089I0J159D01*
+G37*
+G36*
+X254132Y-599851D02*
+G01X315828D01*
+G02X315828Y-600168I0J-159D01*
+G01X254132D01*
+G02X254132Y-599851I0J159D01*
+G37*
+G36*
+X247046Y-299151D02*
+G01X306637D01*
+G02X306637Y-299469I0J-159D01*
+G01X247046D01*
+G02X247046Y-299151I0J159D01*
+G37*
+G36*
+X376723D02*
+G01X661784D01*
+G02X661784Y-299469I0J-159D01*
+G01X376723D01*
+G02X376723Y-299151I0J159D01*
+G37*
+G36*
+X413174Y712325D02*
+G01X477900D01*
+G02X477900Y712008I0J-159D01*
+G01X413174D01*
+G02X413174Y712325I0J159D01*
+G37*
+G36*
+X221265Y707330D02*
+G01X234761D01*
+G02X234761Y707013I0J-159D01*
+G01X221265D01*
+G02X221265Y707330I0J159D01*
+G37*
+G36*
+X169482Y-609421D02*
+G01X185507D01*
+G02X185507Y-609739I0J-159D01*
+G01X169482D01*
+G02X169482Y-609421I0J159D01*
+G37*
+G36*
+X255593D02*
+G01X317155D01*
+G02X317155Y-609739I0J-159D01*
+G01X255593D01*
+G02X255593Y-609421I0J159D01*
+G37*
+G36*
+X373708Y597296D02*
+G01X380372D01*
+G02X380372Y596978I0J-159D01*
+G01X373708D01*
+G02X373708Y597296I0J159D01*
+G37*
+G36*
+X171898Y603415D02*
+G01X184839D01*
+G02X184839Y603098I0J-159D01*
+G01X171898D01*
+G02X171898Y603415I0J159D01*
+G37*
+G36*
+X106546Y-313761D02*
+G01X180327D01*
+G02X180327Y-314079I0J-159D01*
+G01X106546D01*
+G02X106546Y-313761I0J159D01*
+G37*
+G36*
+X250413D02*
+G01X310004D01*
+G02X310004Y-314079I0J-159D01*
+G01X250413D01*
+G02X250413Y-313761I0J159D01*
+G37*
+G36*
+X247136Y-23846D02*
+G01X259176D01*
+G02X259176Y-24164I0J-159D01*
+G01X247136D01*
+G02X247136Y-23846I0J159D01*
+G37*
+G36*
+X36614Y30936D02*
+G01X173257D01*
+G02X173257Y30619I0J-159D01*
+G01X36614D01*
+G02X36614Y30936I0J159D01*
+G37*
+G36*
+X285166Y500158D02*
+G01X403271D01*
+G02X403271Y499840I0J-159D01*
+G01X285166D01*
+G02X285166Y500158I0J159D01*
+G37*
+G36*
+X83424Y507833D02*
+G01X143989D01*
+G02X143989Y507516I0J-159D01*
+G01X83424D01*
+G02X83424Y507833I0J159D01*
+G37*
+G36*
+X386579Y-695560D02*
+G01X415119D01*
+G02X415119Y-695878I0J-159D01*
+G01X386579D01*
+G02X386579Y-695560I0J159D01*
+G37*
+G36*
+X61151Y-698856D02*
+G01X106537D01*
+G02X106537Y-699173I0J-159D01*
+G01X61151D01*
+G02X61151Y-698856I0J159D01*
+G37*
+G36*
+X54062Y-601991D02*
+G01X100437D01*
+G02X100437Y-602309I0J-159D01*
+G01X54062D01*
+G02X54062Y-601991I0J159D01*
+G37*
+G36*
+X170523D02*
+G01X186548D01*
+G02X186548Y-602309I0J-159D01*
+G01X170523D01*
+G02X170523Y-601991I0J159D01*
+G37*
+G36*
+X-182870Y-499601D02*
+G01X79677D01*
+G02X79677Y-499919I0J-159D01*
+G01X-182870D01*
+G02X-182870Y-499601I0J159D01*
+G37*
+G36*
+X149763D02*
+G01X454384D01*
+G02X454384Y-499919I0J-159D01*
+G01X149763D01*
+G02X149763Y-499601I0J159D01*
+G37*
+G36*
+X-91009Y-15291D02*
+G01X49857D01*
+G02X49857Y-15609I0J-159D01*
+G01X-91009D01*
+G02X-91009Y-15291I0J159D01*
+G37*
+G36*
+X119943D02*
+G01X177846D01*
+G02X177846Y-15609I0J-159D01*
+G01X119943D01*
+G02X119943Y-15291I0J159D01*
+G37*
+G36*
+X-47921Y-287971D02*
+G01X47827D01*
+G02X47827Y-288289I0J-159D01*
+G01X-47921D01*
+G02X-47921Y-287971I0J159D01*
+G37*
+G36*
+X117913D02*
+G01X191695D01*
+G02X191695Y-288289I0J-159D01*
+G01X117913D01*
+G02X117913Y-287971I0J159D01*
+G37*
+G36*
+X161910Y207562D02*
+G01X199110D01*
+G02X199110Y207245I0J-159D01*
+G01X161910D01*
+G02X161910Y207562I0J159D01*
+G37*
+G36*
+X10759Y87812D02*
+G01X41789D01*
+G02X41789Y87494I0J-159D01*
+G01X10759D01*
+G02X10759Y87812I0J159D01*
+G37*
+G36*
+X6347Y500159D02*
+G01X14267D01*
+G02X14267Y499841I0J-159D01*
+G01X6347D01*
+G02X6347Y500159I0J159D01*
+G37*
+G36*
+X84353D02*
+G01X144837D01*
+G02X144837Y499841I0J-159D01*
+G01X84353D01*
+G02X84353Y500159I0J159D01*
+G37*
+G36*
+X-26029Y-705481D02*
+G01X-8133D01*
+G02X-8133Y-705799I0J-159D01*
+G01X-26029D01*
+G02X-26029Y-705481I0J159D01*
+G37*
+G36*
+X61953D02*
+G01X107167D01*
+G02X107167Y-705799I0J-159D01*
+G01X61953D01*
+G02X61953Y-705481I0J159D01*
+G37*
+G36*
+X171964Y601269D02*
+G01X184904D01*
+G02X184904Y600951I0J-159D01*
+G01X171964D01*
+G02X171964Y601269I0J159D01*
+G37*
+G36*
+X-37847Y611639D02*
+G01X-15209D01*
+G02X-15209Y611321I0J-159D01*
+G01X-37847D01*
+G02X-37847Y611639I0J159D01*
+G37*
+G36*
+X-31448Y-606211D02*
+G01X-15513D01*
+G02X-15513Y-606529I0J-159D01*
+G01X-31448D01*
+G02X-31448Y-606211I0J159D01*
+G37*
+G36*
+X54573D02*
+G01X100947D01*
+G02X100947Y-606529I0J-159D01*
+G01X54573D01*
+G02X54573Y-606211I0J159D01*
+G37*
+G36*
+X-46582Y-324221D02*
+G01X-28903D01*
+G02X-28903Y-324539I0J-159D01*
+G01X-46582D01*
+G02X-46582Y-324221I0J159D01*
+G37*
+G36*
+X41183D02*
+G01X182124D01*
+G02X182124Y-324539I0J-159D01*
+G01X41183D01*
+G02X41183Y-324221I0J159D01*
+G37*
+G36*
+X-205328Y23259D02*
+G01X-32543D01*
+G02X-32543Y22941I0J-159D01*
+G01X-205328D01*
+G02X-205328Y23259I0J159D01*
+G37*
+G36*
+X37543D02*
+G01X174105D01*
+G02X174105Y22941I0J-159D01*
+G01X37543D01*
+G02X37543Y23259I0J159D01*
+G37*
+G36*
+X-148320Y504559D02*
+G01X-63443D01*
+G02X-63443Y504241I0J-159D01*
+G01X-148320D01*
+G02X-148320Y504559I0J159D01*
+G37*
+G36*
+X6643D02*
+G01X14562D01*
+G02X14562Y504241I0J-159D01*
+G01X6643D01*
+G02X6643Y504559I0J159D01*
+G37*
+G36*
+X-142445Y-701011D02*
+G01X-95803D01*
+G02X-95803Y-701329I0J-159D01*
+G01X-142445D01*
+G02X-142445Y-701011I0J159D01*
+G37*
+G36*
+X-25717D02*
+G01X-7820D01*
+G02X-7820Y-701329I0J-159D01*
+G01X-25717D01*
+G02X-25717Y-701011I0J159D01*
+G37*
+G36*
+X-150239Y-602551D02*
+G01X-101313D01*
+G02X-101313Y-602869I0J-159D01*
+G01X-150239D01*
+G02X-150239Y-602551I0J159D01*
+G37*
+G36*
+X-31227D02*
+G01X-15291D01*
+G02X-15291Y-602869I0J-159D01*
+G01X-31227D01*
+G02X-31227Y-602551I0J159D01*
+G37*
+G36*
+X-163451Y-307191D02*
+G01X-111993D01*
+G02X-111993Y-307509I0J-159D01*
+G01X-163451D01*
+G02X-163451Y-307191I0J159D01*
+G37*
+G36*
+X-41907D02*
+G01X-24228D01*
+G02X-24228Y-307509I0J-159D01*
+G01X-41907D01*
+G02X-41907Y-307191I0J159D01*
+G37*
+G36*
+X159120Y299214D02*
+G01X210816D01*
+G02X210816Y298897I0J-159D01*
+G01X159120D01*
+G02X159120Y299214I0J159D01*
+G37*
+G36*
+X-220229Y102608D02*
+G01X-159841D01*
+G02X-159841Y102290I0J-159D01*
+G01X-220229D01*
+G02X-220229Y102608I0J159D01*
+G37*
+G36*
+X35021Y-169030D02*
+G01X51853D01*
+G02X51853Y-169347I0J-159D01*
+G01X35021D01*
+G02X35021Y-169030I0J159D01*
+G37*
+G36*
+X-236716Y-202281D02*
+G01X-188110D01*
+G02X-188110Y-202598I0J-159D01*
+G01X-236716D01*
+G02X-236716Y-202281I0J159D01*
+G37*
+G36*
+X-226723Y511999D02*
+G01X-217363D01*
+G02X-217363Y511681I0J-159D01*
+G01X-226723D01*
+G02X-226723Y511999I0J159D01*
+G37*
+G36*
+X-147277D02*
+G01X-62399D01*
+G02X-62399Y511681I0J-159D01*
+G01X-147277D01*
+G02X-147277Y511999I0J159D01*
+G37*
+G36*
+X-248035Y-597391D02*
+G01X-219843D01*
+G02X-219843Y-597709I0J-159D01*
+G01X-248035D01*
+G02X-248035Y-597391I0J159D01*
+G37*
+G36*
+X-149757D02*
+G01X-100830D01*
+G02X-100830Y-597709I0J-159D01*
+G01X-149757D01*
+G02X-149757Y-597391I0J159D01*
+G37*
+G36*
+X-34893Y597533D02*
+G01X-12257D01*
+G02X-12257Y597216I0J-159D01*
+G01X-34893D01*
+G02X-34893Y597533I0J159D01*
+G37*
+G36*
+X-327537Y614370D02*
+G01X-221600D01*
+G02X-221600Y614053I0J-159D01*
+G01X-327537D01*
+G02X-327537Y614370I0J159D01*
+G37*
+G36*
+X-142754Y307876D02*
+G01X-121797D01*
+G02X-121797Y307558I0J-159D01*
+G01X-142754D01*
+G02X-142754Y307876I0J159D01*
+G37*
+G36*
+X-321160Y237687D02*
+G01X-236731D01*
+G02X-236731Y237370I0J-159D01*
+G01X-321160D01*
+G02X-321160Y237687I0J159D01*
+G37*
+G36*
+X-263325Y-503841D02*
+G01X-252443D01*
+G02X-252443Y-504159I0J-159D01*
+G01X-263325D01*
+G02X-263325Y-503841I0J159D01*
+G37*
+G36*
+X-182357D02*
+G01X80190D01*
+G02X80190Y-504159I0J-159D01*
+G01X-182357D01*
+G02X-182357Y-503841I0J159D01*
+G37*
+G36*
+X-141581Y-693267D02*
+G01X-94684D01*
+G02X-94684Y-693585I0J-159D01*
+G01X-141581D01*
+G02X-141581Y-693267I0J159D01*
+G37*
+G36*
+X-326960Y-697696D02*
+G01X-282662D01*
+G02X-282662Y-698014I0J-159D01*
+G01X-326960D01*
+G02X-326960Y-697696I0J159D01*
+G37*
+G36*
+X-327063Y500959D02*
+G01X-294793D01*
+G02X-294793Y500641I0J-159D01*
+G01X-327063D01*
+G02X-327063Y500959I0J159D01*
+G37*
+G36*
+X-224707D02*
+G01X-215346D01*
+G02X-215346Y500641I0J-159D01*
+G01X-224707D01*
+G02X-224707Y500959I0J159D01*
+G37*
+G36*
+X-327918Y-598041D02*
+G01X-318043D01*
+G02X-318043Y-598359I0J-159D01*
+G01X-327918D01*
+G02X-327918Y-598041I0J159D01*
+G37*
+G36*
+X-247957D02*
+G01X-219765D01*
+G02X-219765Y-598359I0J-159D01*
+G01X-247957D01*
+G02X-247957Y-598041I0J159D01*
+G37*
+G36*
+X-327387Y578579D02*
+G01X-320123D01*
+G02X-320123Y578261I0J-159D01*
+G01X-327387D01*
+G02X-327387Y578579I0J159D01*
+G37*
+G36*
+X-250037D02*
+G01X-170760D01*
+G02X-170760Y578261I0J-159D01*
+G01X-250037D01*
+G02X-250037Y578579I0J159D01*
+G37*
+G36*
+X-464804Y-498941D02*
+G01X-332993D01*
+G02X-332993Y-499259I0J-159D01*
+G01X-464804D01*
+G02X-464804Y-498941I0J159D01*
+G37*
+G36*
+X-262907D02*
+G01X-252024D01*
+G02X-252024Y-499259I0J-159D01*
+G01X-262907D01*
+G02X-262907Y-498941I0J159D01*
+G37*
+G36*
+X-434973Y-697641D02*
+G01X-397043D01*
+G02X-397043Y-697959I0J-159D01*
+G01X-434973D01*
+G02X-434973Y-697641I0J159D01*
+G37*
+G36*
+X-326957D02*
+G01X-282662D01*
+G02X-282662Y-697959I0J-159D01*
+G01X-326957D01*
+G02X-326957Y-697641I0J159D01*
+G37*
+G36*
+X-488724Y-598031D02*
+G01X-398003D01*
+G02X-398003Y-598349I0J-159D01*
+G01X-488724D01*
+G02X-488724Y-598031I0J159D01*
+G37*
+G36*
+X-327917D02*
+G01X-318042D01*
+G02X-318042Y-598349I0J-159D01*
+G01X-327917D01*
+G02X-327917Y-598031I0J159D01*
+G37*
+G36*
+X-470143Y-387641D02*
+G01X-448393D01*
+G02X-448393Y-387959I0J-159D01*
+G01X-470143D01*
+G02X-470143Y-387641I0J159D01*
+G37*
+G36*
+X-378307D02*
+G01X377900D01*
+G02X377900Y-387959I0J-159D01*
+G01X-378307D01*
+G02X-378307Y-387641I0J159D01*
+G37*
+G36*
+X-159165Y-290365D02*
+G01X-107424D01*
+G02X-107424Y-290683I0J-159D01*
+G01X-159165D01*
+G02X-159165Y-290365I0J159D01*
+G37*
+G36*
+X-792467Y-293213D02*
+G01X-458058D01*
+G02X-458058Y-293530I0J-159D01*
+G01X-792467D01*
+G02X-792467Y-293213I0J159D01*
+G37*
+G36*
+X-541173Y-692141D02*
+G01X-504493D01*
+G02X-504493Y-692459I0J-159D01*
+G01X-541173D01*
+G02X-541173Y-692141I0J159D01*
+G37*
+G36*
+X-434407D02*
+G01X-396476D01*
+G02X-396476Y-692459I0J-159D01*
+G01X-434407D01*
+G02X-434407Y-692141I0J159D01*
+G37*
+G36*
+X-620836Y-365871D02*
+G01X-532413D01*
+G02X-532413Y-366189I0J-159D01*
+G01X-620836D01*
+G02X-620836Y-365871I0J159D01*
+G37*
+G36*
+X-462327D02*
+G01X-440577D01*
+G02X-440577Y-366189I0J-159D01*
+G01X-462327D01*
+G02X-462327Y-365871I0J159D01*
+G37*
+G36*
+X-463889Y-460889D02*
+G01X588302D01*
+G02X588302Y-461207I0J-159D01*
+G01X-463889D01*
+G02X-463889Y-460889I0J159D01*
+G37*
+G36*
+X-543701Y-505899D02*
+G01X-534451D01*
+G02X-534451Y-506217I0J-159D01*
+G01X-543701D01*
+G02X-543701Y-505899I0J159D01*
+G37*
+G36*
+X-659900Y-158169D02*
+G01X-431613D01*
+G02X-431613Y-158486I0J-159D01*
+G01X-659900D01*
+G02X-659900Y-158169I0J159D01*
+G37*
+G36*
+X-766381Y-233695D02*
+G01X-737831D01*
+G02X-737831Y-234013I0J-159D01*
+G01X-766381D01*
+G02X-766381Y-233695I0J159D01*
+G37*
+G36*
+X-815200Y-751279D02*
+G01X-815199Y-599851D01*
+X-772852D01*
+G03X-737170Y-634857I35012J0D01*
+G02X-732721Y-644527I-291J-5992D01*
+G03X-699427Y-702817I25350J-24174D01*
+G02X-692944Y-706995I749J-5958D01*
+G03X-623549Y-700107I34356J6888D01*
+G01X-612726D01*
+G03X-600370Y-735445I34132J-7894D01*
+G01X-599747Y-816870D01*
+G02X-605830Y-822915I-6003J-43D01*
+G01X-659051Y-822174D01*
+G02X-662513Y-811334I69J5995D01*
+G03X-704665Y-810748I-20688J28232D01*
+G02X-708428Y-821486I-3692J-4735D01*
+G01X-757444Y-820804D01*
+G02X-761151Y-810154I88J6001D01*
+G03X-805337Y-755869I-21649J27503D01*
+G02X-815176Y-751807I-3861J4594D01*
+G01X-815200Y-751279D01*
+G37*
+G36*
+X-815199Y-599851D02*
+X-815199Y-562051D01*
+X-810915Y-558676D01*
+G03X-758248Y-517181I19949J28851D01*
+G01X-741898Y-504301D01*
+X-711261Y-500999D01*
+X-711245Y-500987D01*
+X-696901Y-465003D01*
+X-669499Y-430992D01*
+X-662296Y-335003D01*
+X-662289Y-335000D01*
+X-634308Y-336001D01*
+X-634302Y-336004D01*
+X-634299Y-336011D01*
+X-630098Y-409989D01*
+X-630087Y-410006D01*
+X-629398Y-410321D01*
+X-629397Y-410326D01*
+X-629024Y-420487D01*
+X-629003Y-420506D01*
+X-609087Y-419488D01*
+X-603151Y-422168D01*
+X-601754Y-423797D01*
+X-602344Y-557257D01*
+X-574053Y-589997D01*
+X-574051Y-590006D01*
+X-577653Y-620004D01*
+X-603848Y-653005D01*
+Y-653010D01*
+X-600900Y-666000D01*
+X-600790Y-680897D01*
+G03X-612726Y-700107I22196J-27105D01*
+G01X-623549D01*
+G03X-666543Y-665983I-35039J0D01*
+G02X-673159Y-661299I-740J5970D01*
+G03X-708050Y-633693I-34213J-7390D01*
+G02X-712161Y-623624I295J5994D01*
+G03X-772746Y-597130I-25689J23775D01*
+G03X-772852Y-599851I34906J-2721D01*
+G01X-815199D01*
+G37*
+G36*
+X-623391Y-699949D02*
+X-612889D01*
+G02X-612889Y-700266I0J-159D01*
+G01X-623391D01*
+G02X-623391Y-699949I0J159D01*
+G37*
+G36*
+X-815040Y-599693D02*
+G01X-773011D01*
+G02X-773011Y-600010I0J-159D01*
+G01X-815040D01*
+G02X-815040Y-599693I0J159D01*
+G37*
+G36*
+X313531Y354562D02*
+G01X313532Y354566D01*
+X313955Y355448D01*
+X324649Y362207D01*
+G03X349901Y377603I-3899J34801D01*
+G01X557709D01*
+G03X621728Y397176I35002J0D01*
+G02X621536Y399940I2565J1567D01*
+G02X623329Y401940I8853J-6133D01*
+G03X634101Y427200I-24231J25260D01*
+G01X671995D01*
+X672839Y424969D01*
+X677611Y418034D01*
+X683901Y412439D01*
+X691345Y408508D01*
+X699512Y406468D01*
+X703850Y406198D01*
+X712207Y407210D01*
+X720081Y410189D01*
+X727015Y414961D01*
+X732610Y421251D01*
+X736542Y428695D01*
+X738582Y436862D01*
+X738852Y441200D01*
+X824012D01*
+X823819Y271250D01*
+X745204D01*
+G03X713925Y306053I-35001J0D01*
+G02X711284Y309130I360J2981D01*
+G03X710684Y321311I-34727J4395D01*
+G02X712609Y324652I2964J518D01*
+G03X666466Y349769I-12011J32878D01*
+G02X664541Y346428I-2935J-534D01*
+G03X644354Y299833I12017J-32877D01*
+G01X480857D01*
+G03X426908Y329253I-34996J0D01*
+G02X418023Y332539I-3140J5166D01*
+G03X352283Y320888I-31032J-16193D01*
+G03X351989Y316357I34712J-4531D01*
+G01X340959D01*
+G03X317642Y330402I-28337J-20667D01*
+G01X313531Y354562D01*
+G37*
+G36*
+X328632Y264485D02*
+G03X340959Y316357I-16010J31205D01*
+G01X351989D01*
+G03X405952Y286927I35007J0D01*
+G02X414837Y283640I3138J-5169D01*
+G03X480857Y299833I31024J16194D01*
+G01X644354D01*
+G03X672825Y278747I32204J13718D01*
+G02X675226Y276947I-356J-2976D01*
+G02X675306Y273996I-9893J-1745D01*
+G03X676500Y261780I34857J-2760D01*
+G02X674763Y258338I-2920J-686D01*
+G03X654438Y233990I13802J-32179D01*
+G01X637632D01*
+X636619Y242347D01*
+X633641Y250221D01*
+X628869Y257156D01*
+X622579Y262751D01*
+X615135Y266682D01*
+X606967Y268722D01*
+X602630Y268992D01*
+X594273Y267980D01*
+X586399Y265001D01*
+X579464Y260229D01*
+X573869Y253939D01*
+X569938Y246495D01*
+X567898Y238328D01*
+X567628Y233990D01*
+X346221D01*
+G03X330213Y255186I-33873J-8939D01*
+G01X328632Y264485D01*
+G37*
+G36*
+X339178Y202525D02*
+G03X346221Y233990I-26830J22526D01*
+G01X567628D01*
+X568640Y225633D01*
+X571619Y217759D01*
+X576391Y210824D01*
+X582681Y205229D01*
+X590125Y201298D01*
+X598292Y199258D01*
+X602630Y198988D01*
+X610987Y200000D01*
+X618861Y202979D01*
+X625795Y207751D01*
+X631390Y214041D01*
+X635322Y221485D01*
+X637362Y229652D01*
+X637632Y233990D01*
+X654438D01*
+G03X675080Y193847I34127J-7831D01*
+G02X677356Y185299I-2784J-5318D01*
+G03X675293Y151275I29481J-18862D01*
+G03X662358Y133686I20385J-28542D01*
+G02X653534Y131111I-5492J2415D01*
+G03X604465Y120653I-19443J-29118D01*
+G03X552322Y94667I-17415J-30363D01*
+G03X552047Y90286I34733J-4381D01*
+G01X473369D01*
+G03X439745Y133870I-33933J8583D01*
+G02X434387Y142457I56J6000D01*
+G03X402676Y122950I-31382J15487D01*
+G02X408011Y114317I-59J-6002D01*
+G03X404488Y96654I31411J-15448D01*
+G02X398719Y90279I-5991J-376D01*
+G03X370279Y73838I1265J-35006D01*
+G02X359638Y76437I-4738J3684D01*
+G01X355606Y98441D01*
+G03X351265Y122104I-34521J5897D01*
+G01X340781Y179291D01*
+X341402Y189445D01*
+X339178Y202525D01*
+G37*
+G36*
+X346544Y423516D02*
+X349030Y428708D01*
+X368675Y457213D01*
+X386044Y470600D01*
+X386048Y470608D01*
+X386050Y470616D01*
+X386049Y471822D01*
+X386054Y471831D01*
+X405594Y482636D01*
+X410166Y490970D01*
+X436418D01*
+X437430Y482613D01*
+X440409Y474739D01*
+X445181Y467804D01*
+X451471Y462209D01*
+X458915Y458278D01*
+X467082Y456238D01*
+X471420Y455968D01*
+X479777Y456980D01*
+X487651Y459959D01*
+X494585Y464731D01*
+X500180Y471021D01*
+X504112Y478465D01*
+X506152Y486632D01*
+X506422Y490970D01*
+X640085D01*
+G03X696627Y486950I29729J18496D01*
+G02X700454Y487416I2191J-2046D01*
+G03X754552Y516753I19094J29337D01*
+G01X824099D01*
+X824012Y441200D01*
+X738852D01*
+X737839Y449557D01*
+X734861Y457431D01*
+X730089Y464366D01*
+X723799Y469961D01*
+X716355Y473892D01*
+X708188Y475932D01*
+X703850Y476202D01*
+X695493Y475190D01*
+X687619Y472211D01*
+X680684Y467439D01*
+X675089Y461149D01*
+X671158Y453705D01*
+X669118Y445538D01*
+X668848Y441200D01*
+X631179D01*
+G03X570081Y407624I-32081J-14000D01*
+G02X570274Y404860I-2574J-1568D01*
+G02X568481Y402860I-8870J6149D01*
+G03X557913Y381375I24242J-25265D01*
+G03X557709Y377603I34798J-3772D01*
+G01X349901D01*
+G03X346567Y420668I-29150J19405D01*
+G01X346544Y423516D01*
+G37*
+G36*
+X385303Y824194D02*
+X385310Y824199D01*
+X554613Y824316D01*
+G02X558340Y813612I0J-6001D01*
+G03X567651Y753456I21738J-27434D01*
+G01X569583Y750654D01*
+X568945Y746972D01*
+G03X616026Y774777I34659J-4923D01*
+G01X614097Y777576D01*
+X614096Y777581D01*
+X614735Y781257D01*
+G03X601383Y813986I-34712J4927D01*
+G02X605498Y824350I4115J4365D01*
+G01X824444Y824497D01*
+X824449Y824491D01*
+X824213Y617657D01*
+X752948D01*
+G03X690817Y639783I-35006J0D01*
+G03X637042Y612866I-18870J-29477D01*
+G03X636947Y610292I34911J-2574D01*
+G01X599537D01*
+G03X532994Y618961I-34560J-5552D01*
+G02X530753Y617331I-2708J1368D01*
+G02X528115Y617788I554J11041D01*
+G03X484640Y586391I-8563J-33942D01*
+G03X484548Y583852I34912J-2539D01*
+G01X463102D01*
+Y621088D01*
+X463330Y623796D01*
+X463331Y657741D01*
+X463335Y657749D01*
+X487864Y677151D01*
+X487868Y677159D01*
+X487870Y677167D01*
+X488377Y719918D01*
+X488372Y719925D01*
+X385318Y817096D01*
+X385315Y817104D01*
+X385303Y824194D01*
+G37*
+G36*
+X406659Y16289D02*
+G02X410804Y22007I6016J0D01*
+G03X434932Y57517I-10816J33301D01*
+G02X440701Y63891I6005J363D01*
+G03X473369Y90286I-1266J34979D01*
+G01X552047D01*
+G03X616683Y71637I35009J0D01*
+G03X655114Y74001I17421J30352D01*
+G02X663959Y71496I3372J-4963D01*
+G02X664584Y68230I-12350J-4056D01*
+G03X723434Y97474I34795J3815D01*
+G02X723291Y101327I2253J2013D01*
+G03X727206Y137973I-27637J21485D01*
+G03X720330Y198773I-20361J28486D01*
+G02X718054Y207321I2783J5318D01*
+G03X722260Y235639I-29567J18863D01*
+G02X723997Y239082I2916J689D01*
+G03X745204Y271250I-13795J32168D01*
+G01X823819D01*
+X823504Y-5272D01*
+X823494Y-5278D01*
+X782134Y-6491D01*
+X782127Y-6495D01*
+X782120Y-6500D01*
+X773702Y-17026D01*
+X757092Y-28011D01*
+X757086Y-28012D01*
+X730310Y-29011D01*
+X729024Y-29222D01*
+X657530Y-31502D01*
+X657524Y-31508D01*
+X638646Y-56005D01*
+X635661Y-58986D01*
+X635655Y-58988D01*
+X635649Y-58986D01*
+X633148Y-56480D01*
+G03X567043Y-61842I-32137J-13972D01*
+G01X468402Y-62498D01*
+X468395Y-62494D01*
+X452164Y-43635D01*
+G02X457683Y-33800I4551J3912D01*
+G03X494638Y-16594I6467J34399D01*
+G01X497259Y-15063D01*
+X498361Y-15274D01*
+G03X480803Y34434I12942J32526D01*
+G01X478189Y32913D01*
+X477083Y33126D01*
+G03X429204Y2574I-12935J-32522D01*
+G02X418370Y-629I-5991J339D01*
+G01X409893Y10955D01*
+G02X406659Y16289I2781J5334D01*
+G37*
+G36*
+X410166Y490970D02*
+G01X415847Y501324D01*
+X463325Y546353D01*
+X463328Y546360D01*
+X463330Y546368D01*
+X463268Y572858D01*
+X463102Y574156D01*
+Y583852D01*
+X484548D01*
+G03X551536Y569629I35004J0D01*
+G02X553777Y571259I2689J-1341D01*
+G02X556415Y570801I-514J-10787D01*
+G03X599980Y604740I8563J33939D01*
+G01X637390D01*
+G03X699081Y588167I34563J5552D01*
+G03X752948Y617657I18862J29489D01*
+G01X824213D01*
+X824099Y516753D01*
+X754552D01*
+G03X692723Y539240I-35004J0D01*
+G02X688896Y538774I-2189J2033D01*
+G03X634943Y512622I-19085J-29358D01*
+G03X634801Y509466I34871J-3156D01*
+G01X500872D01*
+X497659Y514136D01*
+X491369Y519731D01*
+X483925Y523662D01*
+X475758Y525702D01*
+X471420Y525972D01*
+X463063Y524960D01*
+X455189Y521981D01*
+X448254Y517209D01*
+X442659Y510919D01*
+X438728Y503475D01*
+X436688Y495308D01*
+X436418Y490970D01*
+X410166D01*
+G37*
+G36*
+X500872Y509466D02*
+X634801D01*
+G03X640085Y490970I35013J0D01*
+G01X506422D01*
+X505409Y499327D01*
+X502431Y507201D01*
+X500872Y509466D01*
+G37*
+G36*
+X599537Y610292D02*
+X636947D01*
+G03X637390Y604740I35006J0D01*
+G01X599980D01*
+G03X599537Y610292I-35003J1D01*
+G37*
+G36*
+X631179Y441200D02*
+G01X668848D01*
+X669860Y432843D01*
+X671995Y427200D01*
+X634101D01*
+G03X631179Y441200I-35003J-1D01*
+G37*
+G36*
+X631353Y441359D02*
+G01X668689D01*
+G02X668689Y441041I0J-159D01*
+G01X631353D01*
+G02X631353Y441359I0J159D01*
+G37*
+G36*
+X739011D02*
+G01X823854D01*
+G02X823854Y441041I0J-159D01*
+G01X739011D01*
+G02X739011Y441359I0J159D01*
+G37*
+G36*
+X753107Y617815D02*
+G01X824055D01*
+G02X824055Y617498I0J-159D01*
+G01X753107D01*
+G02X753107Y617815I0J159D01*
+G37*
+G36*
+X599698Y610451D02*
+G01X636789D01*
+G02X636789Y610133I0J-159D01*
+G01X599698D01*
+G02X599698Y610451I0J159D01*
+G37*
+G36*
+X754710Y516912D02*
+G01X823940D01*
+G02X823940Y516594I0J-159D01*
+G01X754710D01*
+G02X754710Y516912I0J159D01*
+G37*
+G36*
+X501065Y509625D02*
+G01X634642D01*
+G02X634642Y509307I0J-159D01*
+G01X501065D01*
+G02X501065Y509625I0J159D01*
+G37*
+G36*
+X346385Y234149D02*
+G01X567469D01*
+G02X567469Y233831I0J-159D01*
+G01X346385D01*
+G02X346385Y234149I0J159D01*
+G37*
+G36*
+X637791D02*
+G01X654275D01*
+G02X654275Y233831I0J-159D01*
+G01X637791D01*
+G02X637791Y234149I0J159D01*
+G37*
+G36*
+X634260Y427359D02*
+G01X671825D01*
+G02X671825Y427041I0J-159D01*
+G01X634260D01*
+G02X634260Y427359I0J159D01*
+G37*
+G36*
+X350091Y377761D02*
+G01X557551D01*
+G02X557551Y377444I0J-159D01*
+G01X350091D01*
+G02X350091Y377761I0J159D01*
+G37*
+G36*
+X745362Y271409D02*
+G01X823660D01*
+G02X823660Y271091I0J-159D01*
+G01X745362D01*
+G02X745362Y271409I0J159D01*
+G37*
+G36*
+X473532Y90445D02*
+G01X551888D01*
+G02X551888Y90128I0J-159D01*
+G01X473532D01*
+G02X473532Y90445I0J159D01*
+G37*
+G36*
+X600139Y604899D02*
+G01X637229D01*
+G02X637229Y604581I0J-159D01*
+G01X600139D01*
+G02X600139Y604899I0J159D01*
+G37*
+G36*
+X463261Y584011D02*
+G01X484389D01*
+G02X484389Y583693I0J-159D01*
+G01X463261D01*
+G02X463261Y584011I0J159D01*
+G37*
+G36*
+X410347Y491129D02*
+G01X436259D01*
+G02X436259Y490811I0J-159D01*
+G01X410347D01*
+G02X410347Y491129I0J159D01*
+G37*
+G36*
+X506581D02*
+G01X639898D01*
+G02X639898Y490811I0J-159D01*
+G01X506581D01*
+G02X506581Y491129I0J159D01*
+G37*
+G36*
+X481016Y299992D02*
+G01X644182D01*
+G02X644182Y299675I0J-159D01*
+G01X481016D01*
+G02X481016Y299992I0J159D01*
+G37*
+G36*
+X341155Y316516D02*
+G01X351830D01*
+G02X351830Y316198I0J-159D01*
+G01X341155D01*
+G02X341155Y316516I0J159D01*
+G37*
+G36*
+X-826956Y564701D02*
+G02X-826956Y564701I27006J0D01*
+G37*
+G36*
+X-826456Y-347199D02*
+G02X-826456Y-347199I27006J0D01*
+G37*
+G36*
+X-824606Y334651D02*
+G02X-824606Y334651I27006J0D01*
+G37*
+G36*
+X-728406Y624001D02*
+G02X-728406Y624001I27006J0D01*
+G37*
+G36*
+X-723996Y26431D02*
+G02X-723996Y26431I27006J0D01*
+G37*
+G36*
+X-610856Y-606399D02*
+G02X-610856Y-606399I27006J0D01*
+G37*
+G36*
+X-603026Y-400039D02*
+G02X-603026Y-400039I27006J0D01*
+G37*
+G36*
+X-556756Y702251D02*
+G02X-556756Y702251I27006J0D01*
+G37*
+G36*
+X-526306Y-185699D02*
+G02X-526306Y-185699I27006J0D01*
+G37*
+G36*
+X-523906Y240201D02*
+G02X-523906Y240201I27006J0D01*
+G37*
+G36*
+X-490846Y-597749D02*
+G02X-490846Y-597749I27006J0D01*
+G37*
+G36*
+X-452006Y790051D02*
+G02X-452006Y790051I27006J0D01*
+G37*
+G36*
+X-407206Y104851D02*
+G02X-407206Y104851I27006J0D01*
+G37*
+G36*
+X-390846Y-498049D02*
+G02X-390846Y-498049I27006J0D01*
+G37*
+G36*
+X-342006Y314291D02*
+G02X-342006Y314291I27006J0D01*
+G37*
+G36*
+X-326766Y645011D02*
+G02X-326766Y645011I27006J0D01*
+G37*
+G36*
+X-239406Y-210799D02*
+G02X-239406Y-210799I27006J0D01*
+G37*
+G36*
+X-211406Y83701D02*
+G02X-211406Y83701I27006J0D01*
+G37*
+G36*
+X-154406Y-499909D02*
+G02X-154406Y-499909I27006J0D01*
+G37*
+G36*
+X-126956Y500651D02*
+G02X-126956Y500651I27006J0D01*
+G37*
+G36*
+X-123456Y49501D02*
+G02X-123456Y49501I27006J0D01*
+G37*
+G36*
+X-70556Y-499589D02*
+G02X-70556Y-499589I27006J0D01*
+G37*
+G36*
+X-26116Y-40559D02*
+G02X-26116Y-40559I27006J0D01*
+G37*
+G36*
+X-316Y-505759D02*
+G02X-316Y-505759I27006J0D01*
+G37*
+G36*
+X39094Y205551D02*
+G02X39094Y205551I27006J0D01*
+G37*
+G36*
+X92304Y503211D02*
+G02X92304Y503211I27006J0D01*
+G37*
+G36*
+X147634Y-503009D02*
+G02X147634Y-503009I27006J0D01*
+G37*
+G36*
+X155924Y88401D02*
+G02X155924Y88401I27006J0D01*
+G37*
+G36*
+X264064Y-495769D02*
+G02X264064Y-495769I27006J0D01*
+G37*
+G36*
+X282994Y502411D02*
+G02X282994Y502411I27006J0D01*
+G37*
+G36*
+X352544Y-502999D02*
+G02X352544Y-502999I27006J0D01*
+G37*
+G36*
+X425894Y696551D02*
+G02X425894Y696551I27006J0D01*
+G37*
+G36*
+X439844Y798601D02*
+G02X439844Y798601I27006J0D01*
+G37*
+G36*
+X451194Y191301D02*
+G02X451194Y191301I27006J0D01*
+G37*
+G36*
+X467344Y258401D02*
+G02X467344Y258401I27006J0D01*
+G37*
+G36*
+X482164Y-321129D02*
+G02X482164Y-321129I27006J0D01*
+G37*
+G36*
+X547434Y-507049D02*
+G02X547434Y-507049I27006J0D01*
+G37*
+G36*
+X563194Y-289599D02*
+G02X563194Y-289599I27006J0D01*
+G37*
+G36*
+X572414Y-157639D02*
+G02X572414Y-157639I27006J0D01*
+G37*
+G36*
+X574644Y-3249D02*
+G02X574644Y-3249I27006J0D01*
+G37*
+G36*
+X759594Y780121D02*
+G02X759594Y780121I27006J0D01*
+G37*
+G54D10*
+X677798Y470923D02*
+G01X695313Y479606D01*
+X703897Y480661D02*
+X719844Y477098D01*
+X-819420Y699353D02*
+X-819155Y665400D01*
+X-630813Y820367D02*
+X-606585Y820350D01*
+X-803079Y-492580D02*
+X-784575Y-491054D01*
+X-421767Y-253926D02*
+X-403901Y-258607D01*
+X245726Y-3652D02*
+X251127Y-20112D01*
+X201196Y-61699D02*
+X213953Y-63282D01*
+X-411985Y261809D02*
+X-396470Y261204D01*
+X377123Y605950D02*
+Y588652D01*
+X347733Y313961D02*
+X351770Y299450D01*
+X496222Y-595050D02*
+X494492Y-610810D01*
+X-323360Y593580D02*
+X-323241Y565226D01*
+X10862Y506459D02*
+X9901Y496176D01*
+M02*
diff --git a/gerbview/gerber_test_files/test_polygons_with_arcs_simple.gbr b/gerbview/gerber_test_files/test_polygons_with_arcs_simple.gbr
new file mode 100644
index 0000000..7b03ab5
--- /dev/null
+++ b/gerbview/gerber_test_files/test_polygons_with_arcs_simple.gbr
@@ -0,0 +1,51 @@
+*
+%FSLAX35Y35*%
+%MOMM*%
+%ADD10C,0.085000*%
+%ADD11C,1.000000*%
+%IPPOS*%
+%LNl2p*%
+%LPD*%
+%SRX1Y1I0J0*%
+G01*
+G75*
+G36*
+X-824649Y824737D02*
+X-824642Y824746D01*
+X-824637Y824748D01*
+X-600285Y824596D01*
+G02X-596337Y813997I0J-6035D01*
+G01X-596759Y813502D01*
+X-599070Y812402D01*
+X-599079Y812403D01*
+X-600633Y812842D01*
+G03X-591714Y760887I-18257J-29877D01*
+G01X-589396Y761987D01*
+X-587850Y761553D01*
+G03X-543350Y814584I18275J29851D01*
+G02X-538846Y824554I4504J3968D01*
+G01X-387906Y824445D01*
+X-387901Y824439D01*
+X-387898Y718310D01*
+X-387892Y718296D01*
+X-387887Y718290D01*
+X-337968Y678268D01*
+X-337966Y678263D01*
+X-337746Y625972D01*
+G02X-347743Y621473I-6001J-23D01*
+G03X-394478Y621365I-23307J-26119D01*
+G02X-402955Y621809I-4016J4477D01*
+G01X-407368Y626784D01*
+X-409076Y628288D01*
+G02X-406164Y638849I3817J4630D01*
+G03X-421754Y706900I-5285J34600D01*
+G01X-699601D01*
+G03X-766967Y720229I-35002J0D01*
+G02X-771614Y718929I-2844J1211D01*
+G03X-817118Y687087I-10523J-33398D01*
+G03X-817151Y685566I34972J-1522D01*
+G01X-823562D01*
+X-824649Y824737D01*
+G37*
+
+M02*
diff --git a/gerbview/gerbview.cpp b/gerbview/gerbview.cpp
new file mode 100644
index 0000000..b128869
--- /dev/null
+++ b/gerbview/gerbview.cpp
@@ -0,0 +1,152 @@
+/**
+ * @file gerbview.cpp
+ * @brief GERBVIEW main file.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <gestfich.h>
+
+#include <gerbview.h>
+#include <gerbview_id.h>
+#include <hotkeys.h>
+#include <gerbview_frame.h>
+
+#include <build_version.h>
+
+#include <wx/file.h>
+#include <wx/snglinst.h>
+
+// Colors for layers and items
+COLORS_DESIGN_SETTINGS g_ColorsSettings;
+
+
+const wxChar* g_GerberPageSizeList[] = {
+ wxT( "GERBER" ), // index 0: full size page selection, and do not show page limits
+ wxT( "GERBER" ), // index 1: full size page selection, and show page limits
+ wxT( "A4" ),
+ wxT( "A3" ),
+ wxT( "A2" ),
+ wxT( "A" ),
+ wxT( "B" ),
+ wxT( "C" ),
+};
+
+
+namespace GERBV {
+
+static struct IFACE : public KIFACE_I
+{
+ // Of course all are virtual overloads, implementations of the KIFACE.
+
+ IFACE( const char* aName, KIWAY::FACE_T aType ) :
+ KIFACE_I( aName, aType )
+ {}
+
+ bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits );
+
+ void OnKifaceEnd();
+
+ wxWindow* CreateWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 )
+ {
+ switch( aClassId )
+ {
+ case FRAME_GERBER:
+ {
+ GERBVIEW_FRAME* frame = new GERBVIEW_FRAME( aKiway, aParent );
+ return frame;
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ return NULL;
+ }
+
+ /**
+ * Function IfaceOrAddress
+ * return a pointer to the requested object. The safest way to use this
+ * is to retrieve a pointer to a static instance of an interface, similar to
+ * how the KIFACE interface is exported. But if you know what you are doing
+ * use it to retrieve anything you want.
+ *
+ * @param aDataId identifies which object you want the address of.
+ *
+ * @return void* - and must be cast into the know type.
+ */
+ void* IfaceOrAddress( int aDataId )
+ {
+ return NULL;
+ }
+
+} kiface( "gerbview", KIWAY::FACE_GERBVIEW );
+
+} // namespace
+
+using namespace GERBV;
+
+static PGM_BASE* process;
+
+KIFACE_I& Kiface() { return kiface; }
+
+
+// KIFACE_GETTER's actual spelling is a substitution macro found in kiway.h.
+// KIFACE_GETTER will not have name mangling due to declaration in kiway.h.
+MY_API( KIFACE* ) KIFACE_GETTER( int* aKIFACEversion, int aKiwayVersion, PGM_BASE* aProgram )
+{
+ process = (PGM_BASE*) aProgram;
+ return &kiface;
+}
+
+
+PGM_BASE& Pgm()
+{
+ wxASSERT( process ); // KIFACE_GETTER has already been called.
+ return *process;
+}
+
+
+bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
+{
+ start_common( aCtlBits );
+
+ // Must be called before creating the main frame in order to
+ // display the real hotkeys in menus or tool tips
+ ReadHotkeyConfig( GERBVIEW_FRAME_NAME, GerbviewHokeysDescr );
+
+ return true;
+}
+
+
+void IFACE::OnKifaceEnd()
+{
+ end_common();
+}
diff --git a/gerbview/gerbview.h b/gerbview/gerbview.h
new file mode 100644
index 0000000..d54ec58
--- /dev/null
+++ b/gerbview/gerbview.h
@@ -0,0 +1,109 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef GERBVIEW_H
+#define GERBVIEW_H
+
+#include <vector>
+#include <set>
+
+
+#define CURSEUR_ON_GRILLE 0
+#define CURSEUR_OFF_GRILLE 1
+
+/**
+* size of single line of a text from a gerber file.
+* warning: some files can have very long lines, so the buffer must be large.
+*/
+#define GERBER_BUFZ 4000
+
+/// List of page sizes
+extern const wxChar* g_GerberPageSizeList[8];
+
+// Type of photoplotter action:
+#define GERB_ACTIVE_DRAW 1 // Activate light (lower pen)
+#define GERB_STOP_DRAW 2 // Extinguish light (lift pen)
+#define GERB_FLASH 3 // Flash
+
+// number fo draw layers in Gerbview
+#define GERBER_DRAWLAYERS_COUNT 32
+
+/**
+ * Enum GERBER_VISIBLE_ID
+ * is a set of visible GERBVIEW elements.
+ */
+enum GERBER_VISIBLE_ID
+{
+ DCODES_VISIBLE = 1, // visible item id cannot be 0
+ // because this id is used as wxWidget id
+ GERBER_GRID_VISIBLE,
+ NEGATIVE_OBJECTS_VISIBLE, // use the selected color to draw negative objects
+ // instaed of background color, to make them visible
+ END_GERBER_VISIBLE_LIST // sentinel
+};
+
+// Interpolation type
+enum Gerb_Interpolation
+{
+ GERB_INTERPOL_LINEAR_1X = 0,
+ GERB_INTERPOL_LINEAR_10X,
+ GERB_INTERPOL_LINEAR_01X,
+ GERB_INTERPOL_LINEAR_001X,
+ GERB_INTERPOL_ARC_NEG,
+ GERB_INTERPOL_ARC_POS
+};
+
+
+// Command Type (GCodes)
+enum Gerb_GCommand
+{
+ GC_MOVE = 0,
+ GC_LINEAR_INTERPOL_1X = 1,
+ GC_CIRCLE_NEG_INTERPOL = 2,
+ GC_CIRCLE_POS_INTERPOL = 3,
+ GC_COMMENT = 4,
+ GC_LINEAR_INTERPOL_10X = 10,
+ GC_LINEAR_INTERPOL_0P1X = 11,
+ GC_LINEAR_INTERPOL_0P01X = 12,
+ GC_TURN_ON_POLY_FILL = 36,
+ GC_TURN_OFF_POLY_FILL = 37,
+ GC_SELECT_TOOL = 54,
+ GC_PHOTO_MODE = 55, // can start a D03 flash command: redundant with D03
+ GC_SPECIFY_INCHES = 70,
+ GC_SPECIFY_MILLIMETERS = 71,
+ GC_TURN_OFF_360_INTERPOL = 74,
+ GC_TURN_ON_360_INTERPOL = 75,
+ GC_SPECIFY_ABSOLUES_COORD = 90,
+ GC_SPECIFY_RELATIVEES_COORD = 91
+};
+
+
+enum Gerb_Analyse_Cmd
+{
+ CMD_IDLE = 0,
+ END_BLOCK,
+ ENTER_RS274X_CMD
+};
+
+#endif // ifndef GERBVIEW_H
diff --git a/gerbview/gerbview.icns b/gerbview/gerbview.icns
new file mode 100644
index 0000000..4ba9792
--- /dev/null
+++ b/gerbview/gerbview.icns
Binary files differ
diff --git a/gerbview/gerbview.rc b/gerbview/gerbview.rc
new file mode 100644
index 0000000..05e745b
--- /dev/null
+++ b/gerbview/gerbview.rc
@@ -0,0 +1,3 @@
+icon_gerbview ICON "../bitmaps_png/icons/icon_gerbview.ico"
+
+#include "wx/msw/wx.rc"
diff --git a/gerbview/gerbview_config.cpp b/gerbview/gerbview_config.cpp
new file mode 100644
index 0000000..7bca894
--- /dev/null
+++ b/gerbview/gerbview_config.cpp
@@ -0,0 +1,148 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file gerbview_config.cpp
+ * @brief GerbView configuration.
+*/
+
+#include <fctsys.h>
+#include <macros.h>
+#include <id.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <gestfich.h>
+#include <config_params.h>
+#include <colors_selection.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <hotkeys.h>
+#include <dialog_hotkeys_editor.h>
+
+
+#define GROUP wxT("/gerbview")
+
+
+void GERBVIEW_FRAME::Process_Config( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ wxString FullFileName;
+
+ switch( id )
+ {
+ // Hotkey IDs
+ case ID_PREFERENCES_HOTKEY_EXPORT_CONFIG:
+ ExportHotkeyConfigToFile( GerbviewHokeysDescr, wxT( "gerbview" ) );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_IMPORT_CONFIG:
+ ImportHotkeyConfigFromFile( GerbviewHokeysDescr, wxT( "gerbview" ) );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_SHOW_EDITOR:
+ InstallHotkeyFrame( this, GerbviewHokeysDescr );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST:
+
+ // Display current hotkey list for GerbView.
+ DisplayHotkeyList( this, GerbviewHokeysDescr );
+ break;
+
+ default:
+ wxMessageBox( wxT( "GERBVIEW_FRAME::Process_Config error" ) );
+ break;
+ }
+}
+
+
+PARAM_CFG_ARRAY& GERBVIEW_FRAME::GetConfigurationSettings()
+{
+ if( !m_configSettings.empty() )
+ return m_configSettings;
+
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "Units" ),
+ (int*) &g_UserUnit, 0, 0, 1 ) );
+
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "DrawModeOption" ),
+ &m_displayMode, 2, 0, 2 ) );
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true,
+ wxT( "DCodeColorEx" ),
+ &g_ColorsSettings.m_ItemsColors[
+ DCODES_VISIBLE],
+ WHITE ) );
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true,
+ wxT( "NegativeObjectsColorEx" ),
+ &g_ColorsSettings.m_ItemsColors[
+ NEGATIVE_OBJECTS_VISIBLE],
+ DARKGRAY ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true,
+ wxT( "DisplayPolarCoordinates" ),
+ &m_DisplayOptions.m_DisplayPolarCood,
+ false ) );
+
+ // Default colors for layers 0 to 31
+ static const EDA_COLOR_T color_default[] = {
+ GREEN, BLUE, LIGHTGRAY, MAGENTA,
+ RED, DARKGREEN, BROWN, MAGENTA,
+ LIGHTGRAY, BLUE, GREEN, CYAN,
+ LIGHTRED, LIGHTMAGENTA, YELLOW, RED,
+ BLUE, BROWN, LIGHTCYAN, RED,
+ MAGENTA, CYAN, BROWN, MAGENTA,
+ LIGHTGRAY, BLUE, GREEN, DARKCYAN,
+ YELLOW, LIGHTMAGENTA, YELLOW, LIGHTGRAY,
+ };
+
+ // List of keywords used as identifiers in config.
+ // They *must* be static const and not temporarily created,
+ // because the parameter list that use these keywords does not store them,
+ // just points to them.
+ static const wxChar* keys[] = {
+ wxT("ColorLayer0Ex"), wxT("ColorLayer1Ex"), wxT("ColorLayer2Ex"), wxT("ColorLayer3Ex"),
+ wxT("ColorLayer4Ex"), wxT("ColorLayer5Ex"), wxT("ColorLayer6Ex"), wxT("ColorLayer7Ex"),
+ wxT("ColorLayer8Ex"), wxT("ColorLayer9Ex"), wxT("ColorLayer10Ex"), wxT("ColorLayer11Ex"),
+ wxT("ColorLayer12Ex"), wxT("ColorLayer13Ex"), wxT("ColorLayer14Ex"), wxT("ColorLayer15Ex"),
+ wxT("ColorLayer16Ex"), wxT("ColorLayer17Ex"), wxT("ColorLayer18Ex"), wxT("ColorLayer19Ex"),
+ wxT("ColorLayer20Ex"), wxT("ColorLayer21Ex"), wxT("ColorLayer22Ex"), wxT("ColorLayer23Ex"),
+ wxT("ColorLayer24Ex"), wxT("ColorLayer25Ex"), wxT("ColorLayer26Ex"), wxT("ColorLayer27Ex"),
+ wxT("ColorLayer28Ex"), wxT("ColorLayer29Ex"), wxT("ColorLayer30Ex"), wxT("ColorLayer31Ex"),
+ };
+
+ wxASSERT( DIM(keys) == DIM(color_default) );
+ wxASSERT( DIM(keys) <= DIM(g_ColorsSettings.m_LayersColors) && DIM(keys) <= DIM(color_default) );
+
+ for( unsigned i = 0; i < DIM(keys); ++i )
+ {
+ EDA_COLOR_T* prm = &g_ColorsSettings.m_LayersColors[i];
+
+ PARAM_CFG_SETCOLOR* prm_entry =
+ new PARAM_CFG_SETCOLOR( true, keys[i], prm, color_default[i] );
+
+ m_configSettings.push_back( prm_entry );
+ }
+
+ return m_configSettings;
+}
diff --git a/gerbview/gerbview_doc.icns b/gerbview/gerbview_doc.icns
new file mode 100644
index 0000000..4b6de4a
--- /dev/null
+++ b/gerbview/gerbview_doc.icns
Binary files differ
diff --git a/gerbview/gerbview_frame.cpp b/gerbview/gerbview_frame.cpp
new file mode 100644
index 0000000..68ddadc
--- /dev/null
+++ b/gerbview/gerbview_frame.cpp
@@ -0,0 +1,835 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file gerbview_frame.cpp
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <pgm_base.h>
+#include <wxstruct.h>
+#include <class_drawpanel.h>
+#include <build_version.h>
+#include <macros.h>
+#include <trigo.h>
+#include <base_units.h>
+#include <colors_selection.h>
+#include <class_gbr_layer_box_selector.h>
+#include <msgpanel.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <class_gerber_draw_item.h>
+#include <pcbplot.h>
+#include <gerbview_id.h>
+#include <hotkeys.h>
+#include <class_GERBER.h>
+#include <dialog_helpers.h>
+#include <class_DCodeSelectionbox.h>
+#include <class_gerbview_layer_widget.h>
+#include <class_gbr_screen.h>
+
+
+// Config keywords
+static const wxString cfgShowPageSizeOption( wxT( "PageSizeOpt" ) );
+static const wxString cfgShowDCodes( wxT( "ShowDCodesOpt" ) );
+static const wxString cfgShowNegativeObjects( wxT( "ShowNegativeObjectsOpt" ) );
+static const wxString cfgShowBorderAndTitleBlock( wxT( "ShowBorderAndTitleBlock" ) );
+
+
+GERBVIEW_FRAME::GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent ):
+ EDA_DRAW_FRAME( aKiway, aParent, FRAME_GERBER, wxT( "GerbView" ),
+ wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GERBVIEW_FRAME_NAME )
+{
+ m_colorsSettings = &g_ColorsSettings;
+ m_gerberLayout = NULL;
+ m_zoomLevelCoeff = ZOOM_FACTOR( 110 ); // Adjusted to roughly displays zoom level = 1
+ // when the screen shows a 1:1 image
+ // obviously depends on the monitor,
+ // but this is an acceptable value
+
+ PAGE_INFO pageInfo( wxT( "GERBER" ) );
+ SetPageSettings( pageInfo );
+
+ m_show_layer_manager_tools = true;
+
+ m_showAxis = true; // true to show X and Y axis on screen
+ m_showBorderAndTitleBlock = false; // true for reference drawings.
+ m_hotkeysDescrList = GerbviewHokeysDescr;
+ m_SelLayerBox = NULL;
+ m_DCodeSelector = NULL;
+ m_displayMode = 0;
+ m_drillFileHistory.SetBaseId( ID_GERBVIEW_DRILL_FILE1 );
+
+ if( m_canvas )
+ m_canvas->SetEnableBlockCommands( true );
+
+ // Give an icon
+ wxIcon icon;
+ icon.CopyFromBitmap( KiBitmap( icon_gerbview_xpm ) );
+ SetIcon( icon );
+
+ SetLayout( new GBR_LAYOUT() );
+
+ SetVisibleLayers( -1 ); // All draw layers visible.
+
+ SetScreen( new GBR_SCREEN( GetPageSettings().GetSizeIU() ) );
+
+ // Create the PCB_LAYER_WIDGET *after* SetLayout():
+ wxFont font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
+ int pointSize = font.GetPointSize();
+ int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
+
+ if( screenHeight <= 900 )
+ pointSize = (pointSize * 8) / 10;
+
+ m_LayersManager = new GERBER_LAYER_WIDGET( this, m_canvas, pointSize );
+
+ // LoadSettings() *after* creating m_LayersManager, because LoadSettings()
+ // initialize parameters in m_LayersManager
+ LoadSettings( config() );
+
+ SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
+
+ if( m_LastGridSizeId < 0 )
+ m_LastGridSizeId = 0;
+ if( m_LastGridSizeId > ID_POPUP_GRID_LEVEL_0_0_1MM-ID_POPUP_GRID_LEVEL_1000 )
+ m_LastGridSizeId = ID_POPUP_GRID_LEVEL_0_0_1MM-ID_POPUP_GRID_LEVEL_1000;
+ GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
+
+ ReCreateMenuBar();
+ ReCreateHToolbar();
+ ReCreateOptToolbar();
+
+ m_auimgr.SetManagedWindow( this );
+
+ EDA_PANEINFO horiz;
+ horiz.HorizontalToolbarPane();
+
+ EDA_PANEINFO vert;
+ vert.VerticalToolbarPane();
+
+ EDA_PANEINFO mesg;
+ mesg.MessageToolbarPane();
+
+ // Create a wxAuiPaneInfo for the Layers Manager, not derived from the template.
+ // the Layers Manager is floatable, but initially docked at far right
+ EDA_PANEINFO lyrs;
+ lyrs.LayersToolbarPane();
+ lyrs.MinSize( m_LayersManager->GetBestSize() );
+ lyrs.BestSize( m_LayersManager->GetBestSize() );
+ lyrs.Caption( _( "Visibles" ) );
+ lyrs.TopDockable( false ).BottomDockable( false );
+
+
+ if( m_mainToolBar )
+ m_auimgr.AddPane( m_mainToolBar,
+ wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top().Row( 0 ) );
+
+ if( m_drawToolBar )
+ m_auimgr.AddPane( m_drawToolBar,
+ wxAuiPaneInfo( vert ).Name( wxT( "m_drawToolBar" ) ).Right().Row( 1 ) );
+
+ m_auimgr.AddPane( m_LayersManager,
+ lyrs.Name( wxT( "m_LayersManagerToolBar" ) ).Right().Layer( 0 ) );
+
+ if( m_optionsToolBar )
+ m_auimgr.AddPane( m_optionsToolBar,
+ wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ).Left() );
+
+ if( m_canvas )
+ m_auimgr.AddPane( m_canvas,
+ wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
+
+ if( m_messagePanel )
+ m_auimgr.AddPane( m_messagePanel,
+ wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer( 10 ) );
+
+ ReFillLayerWidget(); // this is near end because contents establish size
+ m_LayersManager->ReFillRender(); // Update colors in Render after the config is read
+ m_auimgr.Update();
+
+ setActiveLayer( 0, true );
+ Zoom_Automatique( false ); // Gives a default zoom value
+}
+
+
+GERBVIEW_FRAME::~GERBVIEW_FRAME()
+{
+}
+
+
+void GERBVIEW_FRAME::OnCloseWindow( wxCloseEvent& Event )
+{
+ Destroy();
+}
+
+
+bool GERBVIEW_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
+{
+ // The current project path is also a valid command parameter. Check if a single path
+ // rather than a file name was passed to GerbView and use it as the initial MRU path.
+ if( aFileSet.size() > 0 )
+ {
+ wxString path = aFileSet[0];
+
+ // For some reason wxApp appears to leave the trailing double quote on quoted
+ // parameters which are required for paths with spaces. Maybe this should be
+ // pushed back into PGM_SINGLE_TOP::OnPgmInit() but that may cause other issues.
+ // We can't buy a break!
+ if( path.Last() == wxChar( '\"' ) )
+ path.RemoveLast();
+
+ if( !wxFileExists( path ) && wxDirExists( path ) )
+ {
+ wxLogDebug( wxT( "MRU path: %s." ), GetChars( path ) );
+ m_mruPath = path;
+ return true;
+ }
+
+ const unsigned limit = std::min( unsigned( aFileSet.size() ),
+ unsigned( GERBER_DRAWLAYERS_COUNT ) );
+
+ int layer = 0;
+
+ for( unsigned i=0; i<limit; ++i, ++layer )
+ {
+ setActiveLayer( layer );
+ LoadGerberFiles( aFileSet[i] );
+ }
+ }
+
+ Zoom_Automatique( true ); // Zoom fit in frame
+
+ UpdateTitleAndInfo();
+
+ return true;
+}
+
+
+double GERBVIEW_FRAME::BestZoom()
+{
+ GERBER_DRAW_ITEM* item = GetGerberLayout()->m_Drawings;
+
+ // gives a minimal value to zoom, if no item in list
+ if( item == NULL )
+ return ZOOM_FACTOR( 350.0 );
+
+ EDA_RECT bbox = GetGerberLayout()->ComputeBoundingBox();
+
+ wxSize size = m_canvas->GetClientSize();
+
+ double x = (double) bbox.GetWidth() / (double) size.x;
+ double y = (double) bbox.GetHeight() / (double) size.y;
+ SetScrollCenterPosition( bbox.Centre() );
+
+ double best_zoom = std::max( x, y );
+ return best_zoom;
+}
+
+
+void GERBVIEW_FRAME::LoadSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::LoadSettings( aCfg );
+
+ // was: wxGetApp().ReadCurrentSetupValues( GetConfigurationSettings() );
+ wxConfigLoadSetups( aCfg, GetConfigurationSettings() );
+
+ PAGE_INFO pageInfo( wxT( "GERBER" ) );
+
+ aCfg->Read( cfgShowBorderAndTitleBlock, &m_showBorderAndTitleBlock, false );
+
+ if( m_showBorderAndTitleBlock )
+ {
+ wxString pageType;
+
+ aCfg->Read( cfgShowPageSizeOption, &pageType, wxT( "GERBER" ) );
+
+ pageInfo.SetType( pageType );
+ }
+
+ SetPageSettings( pageInfo );
+
+ GetScreen()->InitDataPoints( pageInfo.GetSizeIU() );
+
+ bool tmp;
+ aCfg->Read( cfgShowDCodes, &tmp, true );
+ SetElementVisibility( DCODES_VISIBLE, tmp );
+ aCfg->Read( cfgShowNegativeObjects, &tmp, false );
+ SetElementVisibility( NEGATIVE_OBJECTS_VISIBLE, tmp );
+
+ // because we have 2 file histories, we must read this one
+ // using a specific path
+ aCfg->SetPath( wxT( "drl_files" ) );
+ m_drillFileHistory.Load( *aCfg );
+ aCfg->SetPath( wxT( ".." ) );
+}
+
+
+void GERBVIEW_FRAME::SaveSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::SaveSettings( aCfg );
+
+ // was: wxGetApp().SaveCurrentSetupValues( GetConfigurationSettings() );
+ wxConfigSaveSetups( aCfg, GetConfigurationSettings() );
+
+ aCfg->Write( cfgShowPageSizeOption, GetPageSettings().GetType() );
+ aCfg->Write( cfgShowBorderAndTitleBlock, m_showBorderAndTitleBlock );
+ aCfg->Write( cfgShowDCodes, IsElementVisible( DCODES_VISIBLE ) );
+ aCfg->Write( cfgShowNegativeObjects,
+ IsElementVisible( NEGATIVE_OBJECTS_VISIBLE ) );
+
+ // Save the drill file history list.
+ // Because we have 2 file histories, we must save this one
+ // in a specific path
+ aCfg->SetPath( wxT( "drl_files" ) );
+ m_drillFileHistory.Save( *aCfg );
+ aCfg->SetPath( wxT( ".." ) );
+}
+
+
+void GERBVIEW_FRAME::ReFillLayerWidget()
+{
+ m_LayersManager->ReFill();
+
+ wxAuiPaneInfo& lyrs = m_auimgr.GetPane( m_LayersManager );
+
+ wxSize bestz = m_LayersManager->GetBestSize();
+
+ lyrs.MinSize( bestz );
+ lyrs.BestSize( bestz );
+ lyrs.FloatingSize( bestz );
+
+ if( lyrs.IsDocked() )
+ m_auimgr.Update();
+ else
+ m_LayersManager->SetSize( bestz );
+
+ syncLayerWidget();
+}
+
+
+void GERBVIEW_FRAME::SetElementVisibility( GERBER_VISIBLE_ID aItemIdVisible,
+ bool aNewState )
+{
+ switch( aItemIdVisible )
+ {
+ case DCODES_VISIBLE:
+ m_DisplayOptions.m_DisplayDCodes = aNewState;
+ break;
+
+ case NEGATIVE_OBJECTS_VISIBLE:
+ m_DisplayOptions.m_DisplayNegativeObjects = aNewState;
+ break;
+
+ case GERBER_GRID_VISIBLE:
+ SetGridVisibility( aNewState );
+ break;
+
+ default:
+ wxLogDebug( wxT( "GERBVIEW_FRAME::SetElementVisibility(): bad arg %d" ), aItemIdVisible );
+ }
+
+ m_LayersManager->SetRenderState( aItemIdVisible, aNewState );
+}
+
+
+int GERBVIEW_FRAME::getNextAvailableLayer( int aLayer ) const
+{
+ int layer = aLayer;
+
+ for( int i = 0; i < GERBER_DRAWLAYERS_COUNT; ++i )
+ {
+ GERBER_IMAGE* gerber = g_GERBER_List.GetGbrImage( layer );
+
+ if( gerber == NULL || gerber->m_FileName.IsEmpty() )
+ return layer;
+
+ ++layer;
+
+ if( layer >= GERBER_DRAWLAYERS_COUNT )
+ layer = 0;
+ }
+
+ return NO_AVAILABLE_LAYERS;
+}
+
+
+void GERBVIEW_FRAME::syncLayerWidget()
+{
+ m_LayersManager->SelectLayer( getActiveLayer() );
+ UpdateTitleAndInfo();
+}
+
+
+void GERBVIEW_FRAME::syncLayerBox()
+{
+ m_SelLayerBox->Resync();
+ m_SelLayerBox->SetSelection( getActiveLayer() );
+
+ int dcodeSelected = -1;
+ GERBER_IMAGE* gerber = g_GERBER_List.GetGbrImage( getActiveLayer() );
+
+ if( gerber )
+ dcodeSelected = gerber->m_Selected_Tool;
+
+ if( m_DCodeSelector )
+ {
+ m_DCodeSelector->SetDCodeSelection( dcodeSelected );
+ m_DCodeSelector->Enable( gerber != NULL );
+ }
+
+ UpdateTitleAndInfo();
+}
+
+
+void GERBVIEW_FRAME::Liste_D_Codes()
+{
+ int ii, jj;
+ D_CODE* pt_D_code;
+ wxString Line;
+ wxArrayString list;
+ double scale = g_UserUnit == INCHES ? IU_PER_MILS * 1000 :
+ IU_PER_MM;
+ int curr_layer = getActiveLayer();
+
+ for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
+ {
+ GERBER_IMAGE* gerber = g_GERBER_List.GetGbrImage( layer );
+
+ if( gerber == NULL )
+ continue;
+
+ if( gerber->UsedDcodeNumber() == 0 )
+ continue;
+
+ if( layer == curr_layer )
+ Line.Printf( wxT( "*** Active layer (%2.2d) ***" ), layer + 1 );
+ else
+ Line.Printf( wxT( "*** layer %2.2d ***" ), layer + 1 );
+
+ list.Add( Line );
+
+ const char* units = g_UserUnit == INCHES ? "\"" : "mm";
+ for( ii = 0, jj = 1; ii < TOOLS_MAX_COUNT; ii++ )
+ {
+ pt_D_code = gerber->GetDCODE( ii + FIRST_DCODE, false );
+
+ if( pt_D_code == NULL )
+ continue;
+
+ if( !pt_D_code->m_InUse && !pt_D_code->m_Defined )
+ continue;
+
+ Line.Printf( wxT( "tool %2.2d: D%2.2d V %.4f %s H %.4f %s %s " ),
+ jj,
+ pt_D_code->m_Num_Dcode,
+ pt_D_code->m_Size.y / scale, units,
+ pt_D_code->m_Size.x / scale, units,
+ D_CODE::ShowApertureType( pt_D_code->m_Shape )
+ );
+
+ if( !pt_D_code->m_Defined )
+ Line += wxT( "(not used)" );
+
+ if( !pt_D_code->m_InUse )
+ Line += wxT( "(in use)" );
+
+ list.Add( Line );
+ jj++;
+ }
+ }
+
+ wxSingleChoiceDialog dlg( this, wxEmptyString, _( "D Codes" ), list, (void**) NULL,
+ wxCHOICEDLG_STYLE & ~wxCANCEL );
+
+ dlg.ShowModal();
+}
+
+
+
+void GERBVIEW_FRAME::UpdateTitleAndInfo()
+{
+ GERBER_IMAGE* gerber = g_GERBER_List.GetGbrImage( getActiveLayer() );
+ wxString text;
+
+ // Display the gerber filename
+ if( gerber == NULL )
+ {
+ text.Printf( wxT( "GerbView %s" ), GetChars( GetBuildVersion() ) );
+ SetTitle( text );
+ SetStatusText( wxEmptyString, 0 );
+ text.Printf( _( "Layer %d not in use" ), getActiveLayer() + 1 );
+ m_TextInfo->SetValue( text );
+ ClearMsgPanel();
+ return;
+ }
+
+ text = _( "File:" );
+ text << wxT( " " ) << gerber->m_FileName;
+
+ if( gerber->m_IsX2_file )
+ text << wxT( " " ) << _( "(with X2 Attributes)" );
+
+ SetTitle( text );
+
+ gerber->DisplayImageInfo();
+
+ // Display Image Name and Layer Name (from the current gerber data):
+ text.Printf( _( "Image name: '%s' Layer name: '%s'" ),
+ GetChars( gerber->m_ImageName ),
+ GetChars( gerber->GetLayerParams().m_LayerName ) );
+ SetStatusText( text, 0 );
+
+ // Display data format like fmt in X3.4Y3.4 no LZ or fmt mm X2.3 Y3.5 no TZ in main toolbar
+ text.Printf( wxT( "fmt: %s X%d.%d Y%d.%d no %cZ" ),
+ gerber->m_GerbMetric ? wxT( "mm" ) : wxT( "in" ),
+ gerber->m_FmtLen.x - gerber->m_FmtScale.x, gerber->m_FmtScale.x,
+ gerber->m_FmtLen.y - gerber->m_FmtScale.y, gerber->m_FmtScale.y,
+ gerber->m_NoTrailingZeros ? 'T' : 'L' );
+
+ if( gerber->m_IsX2_file )
+ text << wxT(" ") << _( "X2 attr" );
+
+ m_TextInfo->SetValue( text );
+
+ if( EnsureTextCtrlWidth( m_TextInfo, &text ) ) // Resized
+ m_auimgr.Update();
+}
+
+
+bool GERBVIEW_FRAME::IsElementVisible( GERBER_VISIBLE_ID aItemIdVisible ) const
+{
+ switch( aItemIdVisible )
+ {
+ case DCODES_VISIBLE:
+ return m_DisplayOptions.m_DisplayDCodes;
+ break;
+
+ case NEGATIVE_OBJECTS_VISIBLE:
+ return m_DisplayOptions.m_DisplayNegativeObjects;
+ break;
+
+ case GERBER_GRID_VISIBLE:
+ return IsGridVisible();
+ break;
+
+ default:
+ wxLogDebug( wxT( "GERBVIEW_FRAME::IsElementVisible(): bad arg %d" ), aItemIdVisible );
+ }
+
+ return true;
+}
+
+
+long GERBVIEW_FRAME::GetVisibleLayers() const
+{
+ return -1; // TODO
+}
+
+
+void GERBVIEW_FRAME::SetVisibleLayers( long aLayerMask )
+{
+// GetGerberLayout()->SetVisibleLayers( aLayerMask );
+}
+
+
+bool GERBVIEW_FRAME::IsLayerVisible( int aLayer ) const
+{
+ if( ! m_DisplayOptions.m_IsPrinting )
+ return m_LayersManager->IsLayerVisible( aLayer );
+ else
+ return GetGerberLayout()->IsLayerPrintable( aLayer );
+}
+
+
+EDA_COLOR_T GERBVIEW_FRAME::GetVisibleElementColor( GERBER_VISIBLE_ID aItemIdVisible ) const
+{
+ EDA_COLOR_T color = UNSPECIFIED_COLOR;
+
+ switch( aItemIdVisible )
+ {
+ case NEGATIVE_OBJECTS_VISIBLE:
+ case DCODES_VISIBLE:
+ color = m_colorsSettings->GetItemColor( aItemIdVisible );
+ break;
+
+ case GERBER_GRID_VISIBLE:
+ color = GetGridColor();
+ break;
+
+ default:
+ wxLogDebug( wxT( "GERBVIEW_FRAME::GetVisibleElementColor(): bad arg %d" ),
+ (int)aItemIdVisible );
+ }
+
+ return color;
+}
+
+
+void GERBVIEW_FRAME::SetGridVisibility( bool aVisible )
+{
+ EDA_DRAW_FRAME::SetGridVisibility( aVisible );
+ m_LayersManager->SetRenderState( GERBER_GRID_VISIBLE, aVisible );
+}
+
+
+void GERBVIEW_FRAME::SetVisibleElementColor( GERBER_VISIBLE_ID aItemIdVisible,
+ EDA_COLOR_T aColor )
+{
+ switch( aItemIdVisible )
+ {
+ case NEGATIVE_OBJECTS_VISIBLE:
+ case DCODES_VISIBLE:
+ m_colorsSettings->SetItemColor( aItemIdVisible, aColor );
+ break;
+
+ case GERBER_GRID_VISIBLE:
+ SetGridColor( aColor );
+ m_colorsSettings->SetItemColor( aItemIdVisible, aColor );
+ break;
+
+ default:
+ wxLogDebug( wxT( "GERBVIEW_FRAME::SetVisibleElementColor(): bad arg %d" ),
+ (int) aItemIdVisible );
+ }
+}
+
+EDA_COLOR_T GERBVIEW_FRAME::GetNegativeItemsColor() const
+{
+ if( IsElementVisible( NEGATIVE_OBJECTS_VISIBLE ) )
+ return GetVisibleElementColor( NEGATIVE_OBJECTS_VISIBLE );
+ else
+ return GetDrawBgColor();
+}
+
+
+EDA_COLOR_T GERBVIEW_FRAME::GetLayerColor( int aLayer ) const
+{
+ return m_colorsSettings->GetLayerColor( aLayer );
+}
+
+
+void GERBVIEW_FRAME::SetLayerColor( int aLayer, EDA_COLOR_T aColor )
+{
+ m_colorsSettings->SetLayerColor( aLayer, aColor );
+}
+
+
+int GERBVIEW_FRAME::getActiveLayer()
+{
+ return ( (GBR_SCREEN*) GetScreen() )->m_Active_Layer;
+}
+
+
+void GERBVIEW_FRAME::setActiveLayer( int aLayer, bool doLayerWidgetUpdate )
+{
+ ( (GBR_SCREEN*) GetScreen() )->m_Active_Layer = aLayer;
+
+ if( doLayerWidgetUpdate )
+ m_LayersManager->SelectLayer( getActiveLayer() );
+}
+
+
+void GERBVIEW_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
+{
+ m_paper = aPageSettings;
+
+ if( GetScreen() )
+ GetScreen()->InitDataPoints( aPageSettings.GetSizeIU() );
+}
+
+
+const PAGE_INFO& GERBVIEW_FRAME::GetPageSettings() const
+{
+ return m_paper;
+}
+
+
+const wxSize GERBVIEW_FRAME::GetPageSizeIU() const
+{
+ // this function is only needed because EDA_DRAW_FRAME is not compiled
+ // with either -DPCBNEW or -DEESCHEMA, so the virtual is used to route
+ // into an application specific source file.
+ return GetPageSettings().GetSizeIU();
+}
+
+
+const TITLE_BLOCK& GERBVIEW_FRAME::GetTitleBlock() const
+{
+ wxASSERT( m_gerberLayout );
+ return m_gerberLayout->GetTitleBlock();
+}
+
+
+void GERBVIEW_FRAME::SetTitleBlock( const TITLE_BLOCK& aTitleBlock )
+{
+ wxASSERT( m_gerberLayout );
+ m_gerberLayout->SetTitleBlock( aTitleBlock );
+}
+
+
+const wxPoint& GERBVIEW_FRAME::GetAuxOrigin() const
+{
+ wxASSERT( m_gerberLayout );
+ return m_gerberLayout->GetAuxOrigin();
+}
+
+
+void GERBVIEW_FRAME::SetAuxOrigin( const wxPoint& aPosition )
+{
+ wxASSERT( m_gerberLayout );
+ m_gerberLayout->SetAuxOrigin( aPosition );
+}
+
+
+void GERBVIEW_FRAME::SetCurItem( GERBER_DRAW_ITEM* aItem, bool aDisplayInfo )
+{
+ GetScreen()->SetCurItem( aItem );
+
+ if( aItem )
+ {
+ if( aDisplayInfo )
+ {
+ MSG_PANEL_ITEMS items;
+ aItem->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+ }
+ }
+ else
+ {
+ EraseMsgBox();
+ }
+}
+
+
+EDA_RECT GERBVIEW_FRAME::GetGerberLayoutBoundingBox()
+{
+ GetGerberLayout()->ComputeBoundingBox();
+ return GetGerberLayout()->GetBoundingBox();
+}
+
+void GERBVIEW_FRAME::UpdateStatusBar()
+{
+ EDA_DRAW_FRAME::UpdateStatusBar();
+
+ GBR_SCREEN* screen = (GBR_SCREEN*) GetScreen();
+
+ if( !screen )
+ return;
+
+ int dx;
+ int dy;
+ double dXpos;
+ double dYpos;
+ wxString line;
+ wxString locformatter;
+
+ if( m_DisplayOptions.m_DisplayPolarCood ) // display relative polar coordinates
+ {
+ double theta, ro;
+
+ dx = GetCrossHairPosition().x - screen->m_O_Curseur.x;
+ dy = GetCrossHairPosition().y - screen->m_O_Curseur.y;
+
+ // atan2 in the 0,0 case returns 0
+ theta = RAD2DEG( atan2( -dy, dx ) );
+
+ ro = hypot( dx, dy );
+ wxString formatter;
+ switch( g_UserUnit )
+ {
+ case INCHES:
+ formatter = wxT( "Ro %.6f Th %.1f" );
+ break;
+
+ case MILLIMETRES:
+ formatter = wxT( "Ro %.5f Th %.1f" );
+ break;
+
+ case UNSCALED_UNITS:
+ formatter = wxT( "Ro %f Th %f" );
+ break;
+
+ case DEGREES:
+ wxASSERT( false );
+ break;
+ }
+
+ line.Printf( formatter, To_User_Unit( g_UserUnit, ro ), theta );
+
+ SetStatusText( line, 3 );
+ }
+
+ // Display absolute coordinates:
+ dXpos = To_User_Unit( g_UserUnit, GetCrossHairPosition().x );
+ dYpos = To_User_Unit( g_UserUnit, GetCrossHairPosition().y );
+
+ wxString absformatter;
+
+ switch( g_UserUnit )
+ {
+ case INCHES:
+ absformatter = wxT( "X %.6f Y %.6f" );
+ locformatter = wxT( "dx %.6f dy %.6f dist %.4f" );
+ break;
+
+ case MILLIMETRES:
+ absformatter = wxT( "X %.5f Y %.5f" );
+ locformatter = wxT( "dx %.5f dy %.5f dist %.3f" );
+ break;
+
+ case UNSCALED_UNITS:
+ absformatter = wxT( "X %f Y %f" );
+ locformatter = wxT( "dx %f dy %f dist %f" );
+ break;
+
+ case DEGREES:
+ wxASSERT( false );
+ break;
+ }
+
+ line.Printf( absformatter, dXpos, dYpos );
+ SetStatusText( line, 2 );
+
+ if( !m_DisplayOptions.m_DisplayPolarCood ) // display relative cartesian coordinates
+ {
+ // Display relative coordinates:
+ dx = GetCrossHairPosition().x - screen->m_O_Curseur.x;
+ dy = GetCrossHairPosition().y - screen->m_O_Curseur.y;
+ dXpos = To_User_Unit( g_UserUnit, dx );
+ dYpos = To_User_Unit( g_UserUnit, dy );
+
+ // We already decided the formatter above
+ line.Printf( locformatter, dXpos, dYpos, hypot( dXpos, dYpos ) );
+ SetStatusText( line, 3 );
+ }
+}
+
+
+const wxString GERBVIEW_FRAME::GetZoomLevelIndicator() const
+{
+ return EDA_DRAW_FRAME::GetZoomLevelIndicator();
+}
diff --git a/gerbview/gerbview_frame.h b/gerbview/gerbview_frame.h
new file mode 100644
index 0000000..383ab54
--- /dev/null
+++ b/gerbview/gerbview_frame.h
@@ -0,0 +1,694 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file gerbview_frame.h
+ */
+
+#ifndef WX_GERBER_STRUCT_H
+#define WX_GERBER_STRUCT_H
+
+
+#include <config_params.h>
+#include <draw_frame.h>
+
+#include <gerbview.h>
+#include <class_gbr_layout.h>
+#include <class_gbr_screen.h>
+#include <class_page_info.h>
+
+#define NO_AVAILABLE_LAYERS UNDEFINED_LAYER
+
+class DCODE_SELECTION_BOX;
+class GERBER_LAYER_WIDGET;
+class GBR_LAYER_BOX_SELECTOR;
+class GERBER_DRAW_ITEM;
+
+
+/**
+ * Class GBR_DISPLAY_OPTIONS
+ * A helper class to handle display options.
+ */
+class GBR_DISPLAY_OPTIONS
+{
+public:
+ bool m_DisplayFlashedItemsFill;
+ bool m_DisplayLinesFill;
+ bool m_DisplayPolygonsFill;
+ bool m_DisplayPolarCood;
+ bool m_DisplayDCodes;
+ bool m_DisplayNegativeObjects;
+ bool m_IsPrinting;
+
+public:
+ GBR_DISPLAY_OPTIONS()
+ {
+ m_DisplayFlashedItemsFill = true;
+ m_DisplayLinesFill = true;
+ m_DisplayPolygonsFill = true;
+ m_DisplayPolarCood = false;
+ m_DisplayDCodes = true;
+ m_IsPrinting = false;
+ m_DisplayNegativeObjects = false;
+ }
+};
+
+
+/**
+ * Class GERBVIEW_FRAME
+ * is the main window used in GerbView.
+ */
+
+#define GERBVIEW_FRAME_NAME wxT( "GerberFrame" )
+
+class GERBVIEW_FRAME : public EDA_DRAW_FRAME // PCB_BASE_FRAME
+{
+ GBR_LAYOUT* m_gerberLayout;
+ wxPoint m_grid_origin;
+ PAGE_INFO m_paper; // used only to show paper limits to screen
+
+public:
+ GBR_DISPLAY_OPTIONS m_DisplayOptions;
+
+ /**
+ * Function SetLayout
+ * sets the m_gerberLayout member in such as way as to ensure deleting any previous
+ * GBR_LAYOUT.
+ * @param aLayout The GBR_LAYOUT to put into the frame.
+ */
+ void SetLayout( GBR_LAYOUT* aLayout )
+ {
+ delete m_gerberLayout;
+ m_gerberLayout = aLayout;
+ }
+
+ GBR_LAYOUT* GetGerberLayout() const
+ {
+ wxASSERT( m_gerberLayout );
+ return m_gerberLayout;
+ }
+
+ /**
+ * Function GetItemsList
+ * @return the first GERBER_DRAW_ITEM * item of the items list
+ */
+ GERBER_DRAW_ITEM* GetItemsList()
+ {
+ GERBER_DRAW_ITEM* item = GetGerberLayout()->m_Drawings;
+
+ return (GERBER_DRAW_ITEM*) item;
+ }
+
+ /**
+ * Function GetGerberLayoutBoundingBox
+ * calculates the bounding box containing all gerber items.
+ * @return EDA_RECT - the items bounding box
+ */
+ EDA_RECT GetGerberLayoutBoundingBox();
+
+ void SetPageSettings( const PAGE_INFO& aPageSettings ); // overload
+ const PAGE_INFO& GetPageSettings() const; // overload
+ const wxSize GetPageSizeIU() const; // overload
+
+ const wxPoint& GetAuxOrigin() const; // overload
+ void SetAuxOrigin( const wxPoint& aPoint ); // overload
+
+ const wxPoint& GetGridOrigin() const { return m_grid_origin; } // overload
+ void SetGridOrigin( const wxPoint& aPoint ) // overload
+ {
+ m_grid_origin = aPoint;
+ }
+
+ const TITLE_BLOCK& GetTitleBlock() const; // overload
+ void SetTitleBlock( const TITLE_BLOCK& aTitleBlock ); // overload
+
+ /**
+ * Function SetCurItem
+ * sets the currently selected item and displays it in the MsgPanel.
+ * If the given item is NULL then the MsgPanel is erased and there is no
+ * currently selected item. This function is intended to make the process
+ * of "selecting" an item more formal, and to indivisibly tie the operation
+ * of selecting an item to displaying it using GERBER_DRAW_ITEM::Display_Infos().
+ * @param aItem The GERBER_DRAW_ITEM to make the selected item or NULL if none.
+ * @param aDisplayInfo = true to display item info, false if not (default = true)
+ */
+ void SetCurItem( GERBER_DRAW_ITEM* aItem, bool aDisplayInfo = true );
+
+ /** Install the dialog box for layer selection
+ * @param aDefaultLayer = Preselection (NB_PCB_LAYERS for "(Deselect)" layer)
+ * @param aCopperLayerCount = number of copper layers
+ * @param aShowDeselectOption = display a "(Deselect)" radiobutton (when set to true)
+ * @return new layer value (NB_PCB_LAYERS when "(Deselect)" radiobutton selected),
+ * or -1 if canceled
+ *
+ * Providing the option to also display a "(Deselect)" radiobutton makes the
+ * GerbView's "Export to Pcbnew" command) more "user friendly",
+ * by permitting any layer to be "deselected" immediately after its
+ * corresponding radiobutton has been clicked on. (It would otherwise be
+ * necessary to first cancel the "Select Layer:" dialog box (invoked after a
+ * different radiobutton is clicked on) prior to then clicking on the "Deselect"
+ * button provided within the "Layer selection:" dialog box).
+ */
+ int SelectPCBLayer( int aDefaultLayer, int aOpperLayerCount, bool aNullLayer = false );
+
+protected:
+ GERBER_LAYER_WIDGET* m_LayersManager;
+
+ // Auxiliary file history used to store drill files history.
+ wxFileHistory m_drillFileHistory;
+ /// The last filename chosen to be proposed to the user
+ wxString m_lastFileName;
+public:
+ GBR_LAYER_BOX_SELECTOR* m_SelLayerBox;
+ DCODE_SELECTION_BOX* m_DCodeSelector; // a list box to select the dcode Id to highlight.
+ wxTextCtrl* m_TextInfo; // a wxTextCtrl used to display some info about
+ // gerber data (format..)
+ wxArrayString m_DCodesList; // an array string containing all decodes Id (10 to 999)
+private:
+ // list of PARAM_CFG_xxx to read/write parameters saved in config
+ PARAM_CFG_ARRAY m_configSettings;
+ COLORS_DESIGN_SETTINGS* m_colorsSettings;
+
+ int m_displayMode; // Gerber images ("layers" in Gerbview) can be drawn:
+ // - in fast mode (write mode) but if there are negative
+ // items only the last image is correctly drawn (no
+ // problem to see only one image or when no negative items)
+ // - in "exact" mode (but slower) in write mode:
+ // last image covers previous images
+ // - in "exact" mode (also slower) in OR mode
+ // (transparency mode)
+ // m_displayMode = 0, 1 or 2
+
+ bool m_show_layer_manager_tools;
+
+ // An array sting to store warning messages when reaging a gerber file.
+ wxArrayString m_Messages;
+
+public:
+ GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent );
+ ~GERBVIEW_FRAME();
+
+ void OnCloseWindow( wxCloseEvent& Event );
+
+ bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl ); // overload KIWAY_PLAYER
+
+ // Virtual basic functions:
+ void RedrawActiveWindow( wxDC* DC, bool EraseBg );
+ void ReCreateHToolbar();
+
+ /**
+ * Function ReCreateVToolbar
+ * creates or updates the right vertical toolbar.
+ *
+ * @note This is currently not used.
+ */
+ void ReCreateVToolbar();
+
+ /**
+ * Create or update the left vertical toolbar (option toolbar
+ */
+ void ReCreateOptToolbar();
+
+ void ReCreateMenuBar();
+ void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
+ void OnLeftDClick( wxDC* DC, const wxPoint& MousePos );
+ bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
+ double BestZoom();
+ void UpdateStatusBar();
+
+ /**
+ * Function GetZoomLevelIndicator
+ * returns a human readable value which can be displayed as zoom
+ * level indicator in dialogs.
+ * Virtual from the base class
+ */
+ const wxString GetZoomLevelIndicator() const;
+
+ /**
+ * Function ReportMessage
+ * Add a message (a string) in message list
+ * for instance when reading a Gerber file
+ * @param aMessage = the string to add in list
+ */
+ void ReportMessage( const wxString aMessage )
+ {
+ m_Messages.Add( aMessage );
+ }
+
+ /**
+ * Function ClearMessageList
+ * Clear the message list
+ * Call it before reading a Gerber file
+ */
+ void ClearMessageList()
+ {
+ m_Messages.Clear();
+ }
+
+ /**
+ * Function GetDisplayMode
+ * @return 0 for fast mode (not fully compatible with negative objects)
+ * 1 for exact mode, write mode
+ * 2 for exact mode, OR mode (transparency mode)
+ */
+ int GetDisplayMode() { return m_displayMode; }
+
+ /**
+ * Function SetDisplayMode
+ * @param aMode = 0 for fast mode
+ * 1 for exact mode, write mode
+ * 2 for exact mode, OR mode (transparency mode)
+ */
+ void SetDisplayMode( int aMode ) { m_displayMode = aMode; }
+
+ /**
+ * Function IsElementVisible
+ * tests whether a given element category is visible. Keep this as an
+ * inline function.
+ * @param aItemIdVisible is an item id from the enum GERBER_VISIBLE_ID
+ * @return bool - true if the element is visible.
+ */
+ bool IsElementVisible( GERBER_VISIBLE_ID aItemIdVisible ) const;
+
+ /**
+ * Function SetElementVisibility
+ * changes the visibility of an element category
+ * @param aItemIdVisible is an item id from the enum GERBER_VISIBLE_ID
+ * @param aNewState = The new visibility state of the element category
+ * (see enum PCB_VISIBLE)
+ */
+ void SetElementVisibility( GERBER_VISIBLE_ID aItemIdVisible, bool aNewState );
+
+ /**
+ * Function SetGridVisibility(), virtual from EDA_DRAW_FRAME
+ * It may be overloaded by derived classes
+ * @param aVisible = true if the grid must be shown
+ */
+ void SetGridVisibility( bool aVisible );
+
+ /**
+ * Function GetVisibleLayers
+ * is a proxy function that calls the correspondent function in m_BoardSettings
+ * Returns a bit-mask of all the layers that are visible
+ * @return long - the visible layers in bit-mapped form.
+ */
+ long GetVisibleLayers() const;
+
+ /**
+ * Function SetVisibleLayers
+ * is a proxy function that calls the correspondent function in m_BoardSettings
+ * changes the bit-mask of visible layers
+ * @param aLayerMask = The new bit-mask of visible layers
+ */
+ void SetVisibleLayers( long aLayerMask );
+
+ /**
+ * Function IsLayerVisible
+ * tests whether a given layer is visible
+ * @param aLayer = The layer to be tested
+ * @return bool - true if the layer is visible.
+ */
+ bool IsLayerVisible( int aLayer ) const;
+
+ /**
+ * Function GetVisibleElementColor
+ * returns the color of a gerber visible element.
+ */
+ EDA_COLOR_T GetVisibleElementColor( GERBER_VISIBLE_ID aItemIdVisible ) const;
+
+ void SetVisibleElementColor( GERBER_VISIBLE_ID aItemIdVisible, EDA_COLOR_T aColor );
+
+ /**
+ * Function GetLayerColor
+ * gets a layer color for any valid layer.
+ */
+ EDA_COLOR_T GetLayerColor( int aLayer ) const;
+
+ /**
+ * Function SetLayerColor
+ * changes a layer color for any valid layer.
+ */
+ void SetLayerColor( int aLayer, EDA_COLOR_T aColor );
+
+ /**
+ * Function GetNegativeItemsColor
+ * @return the color of negative items.
+ * This is usually the background color, but can be an other color
+ * in order to see negative objects
+ */
+ EDA_COLOR_T GetNegativeItemsColor() const;
+
+ /**
+ * Function DisplayLinesSolidMode
+ * @return true to draw gerber lines in solid (filled) mode,
+ * false to draw gerber lines in sketch mode
+ */
+ bool DisplayLinesSolidMode()
+ {
+ return m_DisplayOptions.m_DisplayLinesFill;
+ }
+
+ /**
+ * Function DisplayPolygonsSolidMode
+ * @return true to draw polygon in solid (filled) mode,
+ * false to draw polygon outlines only
+ */
+ bool DisplayPolygonsSolidMode()
+ {
+ return m_DisplayOptions.m_DisplayPolygonsFill;
+ }
+
+ /**
+ * Function DisplayFlashedItemsSolidMode
+ * @return true to draw flashed items in solid (filled) mode,
+ * false to draw draw flashed in sketch mode
+ */
+ bool DisplayFlashedItemsSolidMode()
+ {
+ return m_DisplayOptions.m_DisplayFlashedItemsFill;
+ }
+
+ /**
+ * Function ReFillLayerWidget
+ * changes out all the layers in m_Layers and may be called upon
+ * loading new gerber files.
+ */
+ void ReFillLayerWidget();
+
+ /**
+ * Function setActiveLayer
+ * will change the currently active layer to \a aLayer and also
+ * update the GERBER_LAYER_WIDGET.
+ */
+ void setActiveLayer( int aLayer, bool doLayerWidgetUpdate = true );
+
+ /**
+ * Function getActiveLayer
+ * returns the active layer
+ */
+ int getActiveLayer();
+
+ /**
+ * Function getNextAvailableLayer
+ * finds the next empty layer starting at \a aLayer and returns it to the caller. If no
+ * empty layers are found, NO_AVAILABLE_LAYERS is return.
+ * @param aLayer The first layer to search.
+ * @return The first empty layer found or NO_AVAILABLE_LAYERS.
+ */
+ int getNextAvailableLayer( int aLayer = 0 ) const;
+
+ bool hasAvailableLayers() const
+ {
+ return getNextAvailableLayer() != NO_AVAILABLE_LAYERS;
+ }
+
+ /**
+ * Function syncLayerWidget
+ * updates the currently "selected" layer within the GERBER_LAYER_WIDGET.
+ * The currently active layer is defined by the return value of getActiveLayer().
+ * <p>
+ * This function cannot be inline without including layer_widget.h in
+ * here and we do not want to do that.
+ */
+ void syncLayerWidget();
+
+ /**
+ * Function syncLayerBox
+ * updates the currently "selected" layer within m_SelLayerBox
+ * The currently active layer, as defined by the return value of
+ * getActiveLayer(). And updates the colored icon in the toolbar.
+ */
+ void syncLayerBox();
+
+ /**
+ * Function UpdateTitleAndInfo
+ * displays the short filename (if exists) of the selected layer
+ * on the caption of the main GerbView window
+ * and some other parameters
+ * Name of the layer (found in the gerber file: LN &ltname&gt command) in the status bar
+ * Name of the Image (found in the gerber file: IN &ltname&gt command) in the status bar
+ * and other data in toolbar
+ */
+ void UpdateTitleAndInfo();
+
+ /**
+ * Function GetConfigurationSettings
+ * Populates the GerbView applications settings list.
+ * (list of parameters that must be saved in GerbView parameters)
+ * Currently, only the settings that are needed at start up by the main window are
+ * defined here. There are other locally used settings scattered throughout the
+ * GerbView source code (mainly in dialogs). If you need to define a configuration
+ * setting that need to be loaded at run time, this is the place to define it.
+ */
+ PARAM_CFG_ARRAY& GetConfigurationSettings( void );
+
+ void LoadSettings( wxConfigBase* aCfg ); // override virtual
+
+ void SaveSettings( wxConfigBase* aCfg ); // override virtual
+
+ void ShowChangedLanguage(); // override EDA_BASE_FRAME virtual
+
+ void Process_Special_Functions( wxCommandEvent& event );
+ void OnSelectOptionToolbar( wxCommandEvent& event );
+
+ /**
+ * Function OnSelectActiveDCode
+ * Selects the active DCode for the current active layer.
+ * Items using this DCode are highlighted.
+ */
+ void OnSelectActiveDCode( wxCommandEvent& event );
+
+ /**
+ * Function OnSelectActiveLayer
+ * Selects the active layer:
+ * - if a file is loaded, it is loaded in this layer
+ * _ this layer is displayed on top of other layers
+ */
+ void OnSelectActiveLayer( wxCommandEvent& event );
+
+ /**
+ * Function OnShowGerberSourceFile
+ * Call the preferred editor to show (and edit) the gerber source file
+ * loaded in the active layer
+ */
+ void OnShowGerberSourceFile( wxCommandEvent& event );
+
+ /**
+ * Function OnSelectDisplayMode
+ * called on a display mode selection
+ * Mode selection can be fast display,
+ * or exact mode with stacked images or with transparency
+ */
+ void OnSelectDisplayMode( wxCommandEvent& event );
+
+ /**
+ * Function OnQuit
+ * called on request of application quit
+ */
+ void OnQuit( wxCommandEvent& event );
+
+ ///> @copydoc EDA_DRAW_FRAME::GetHotKeyDescription()
+ EDA_HOTKEY* GetHotKeyDescription( int aCommand ) const;
+
+ /**
+ * Function OnHotKey.
+ * ** Commands are case insensitive **
+ * Some commands are relatives to the item under the mouse cursor
+ * @param aDC = current device context
+ * @param aHotkeyCode = hotkey code (ascii or wxWidget code for special keys)
+ * @param aPosition The cursor position in logical (drawing) units.
+ * @param aItem = NULL or pointer on a EDA_ITEM under the mouse cursor
+ */
+ bool OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosition, EDA_ITEM* aItem = NULL );
+
+ GERBER_DRAW_ITEM* GerberGeneralLocateAndDisplay();
+ GERBER_DRAW_ITEM* Locate( const wxPoint& aPosition, int typeloc );
+
+ void Process_Settings( wxCommandEvent& event );
+ void Process_Config( wxCommandEvent& event );
+ void InstallGerberOptionsDialog( wxCommandEvent& event );
+
+ void OnUpdateDrawMode( wxUpdateUIEvent& aEvent );
+ void OnUpdateCoordType( wxUpdateUIEvent& aEvent );
+ void OnUpdateFlashedItemsDrawMode( wxUpdateUIEvent& aEvent );
+ void OnUpdateLinesDrawMode( wxUpdateUIEvent& aEvent );
+ void OnUpdatePolygonsDrawMode( wxUpdateUIEvent& aEvent );
+ void OnUpdateShowDCodes( wxUpdateUIEvent& aEvent );
+ void OnUpdateShowNegativeItems( wxUpdateUIEvent& aEvent );
+ void OnUpdateShowLayerManager( wxUpdateUIEvent& aEvent );
+ void OnUpdateSelectDCode( wxUpdateUIEvent& aEvent );
+ void OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent );
+
+ /**
+ * Function BlockCommand
+ * returns the block command (BLOCK_MOVE, BLOCK_COPY...) corresponding to
+ * the \a aKey (ALT, SHIFT ALT ..)
+ */
+ virtual int BlockCommand( int key );
+
+ /**
+ * Function HandleBlockPlace
+ * handles the block place command.
+ */
+ virtual void HandleBlockPlace( wxDC* DC );
+
+ /**
+ * Function HandleBlockEnd( )
+ * handles the end of a block command,
+ * It is called at the end of the definition of the area of a block.
+ * Depending on the current block command, this command is executed
+ * or parameters are initialized to prepare a call to HandleBlockPlace
+ * in GetScreen()->m_BlockLocate
+ *
+ * @return false if no item selected, or command finished,
+ * true if some items found and HandleBlockPlace must be called later.
+ */
+ virtual bool HandleBlockEnd( wxDC* DC );
+
+ /**
+ * Function Block_Move
+ * moves all tracks and segments within the selected block.
+ * New location is determined by the current offset from the selected
+ * block's original location.
+ * Defined separately in Pcbnew and GerbView
+ *
+ * @param DC A device context to draw on.
+ */
+ void Block_Move( wxDC* DC );
+
+ /**
+ * Function ToPlotter
+ * Open a dialog frame to create plot and drill files
+ * relative to the current board
+ */
+ void ToPlotter( wxCommandEvent& event );
+
+ /**
+ * Function ToPrinter
+ * Open a dialog frame to print layers
+ */
+ void ToPrinter( wxCommandEvent& event );
+
+ void Files_io( wxCommandEvent& event );
+
+ /**
+ * Function OnGbrFileHistory
+ * deletes the current data and loads a Gerber file selected from history list on
+ * current layer.
+ */
+ void OnGbrFileHistory( wxCommandEvent& event );
+
+ /**
+ * Function OnDrlFileHistory
+ * deletes the current data and load a drill file in Excellon format selected from
+ * history list on current layer.
+ */
+ void OnDrlFileHistory( wxCommandEvent& event );
+
+ /**
+ * function LoadGerberFiles
+ * Load a photoplot (Gerber) file or many files.
+ * @param aFileName - void string or file name with full path to open or empty string to
+ * open a new file. In this case one one file is loaded
+ * if void string: user will be prompted for filename(s)
+ * @return true if file was opened successfully.
+ */
+ bool LoadGerberFiles( const wxString& aFileName );
+ int ReadGerberFile( FILE* File, bool Append );
+ bool Read_GERBER_File( const wxString& GERBER_FullFileName,
+ const wxString& D_Code_FullFileName );
+
+ /**
+ * function LoadDrllFiles
+ * Load a drill (EXCELLON) file or many files.
+ * @param aFileName - void string or file name with full path to open or empty string to
+ * open a new file. In this case one one file is loaded
+ * if void string: user will be prompted for filename(s)
+ * @return true if file was opened successfully.
+ */
+ bool LoadExcellonFiles( const wxString& aFileName );
+ bool Read_EXCELLON_File( const wxString& aFullFileName );
+
+ bool GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey = 0 );
+
+ /**
+ * Set Size Items (Lines, Flashes) from DCodes List
+ */
+ void CopyDCodesSizeToItems();
+ void Liste_D_Codes();
+
+ // PCB handling
+ bool Clear_DrawLayers( bool query );
+ void Erase_Current_DrawLayer( bool query );
+
+ // Conversion function
+ void ExportDataInPcbnewFormat( wxCommandEvent& event );
+
+ /* SaveCopyInUndoList() virtual
+ * currently: do nothing in GerbView.
+ */
+ void SaveCopyInUndoList( GERBER_DRAW_ITEM* aItemToCopy,
+ UNDO_REDO_T aTypeCommand = UR_UNSPECIFIED,
+ const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) { }
+
+ /**
+ * Function SaveCopyInUndoList (overloaded).
+ * Creates a new entry in undo list of commands.
+ * add a list of pickers to handle a list of items
+ * @param aItemsList = the list of items modified by the command to undo
+ * @param aTypeCommand = command type (see enum UNDO_REDO_T)
+ * @param aTransformPoint = the reference point of the transformation,
+ * for commands like move
+ */
+ void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
+ UNDO_REDO_T aTypeCommand,
+ const wxPoint& aTransformPoint = wxPoint( 0, 0 ) )
+ {
+ // currently: do nothing in GerbView.
+ }
+
+ /** Virtual function PrintPage
+ * used to print a page
+ * @param aDC = wxDC given by the calling print function
+ * @param aPrintMasklayer = a 32 bits mask: bit n = 1 -> layer n is printed
+ * @param aPrintMirrorMode = not used here (Set when printing in mirror mode)
+ * @param aData = a pointer on an auxiliary data (not always used, NULL if not used)
+ */
+ virtual void PrintPage( wxDC* aDC, LSET aPrintMasklayer, bool aPrintMirrorMode,
+ void* aData = NULL );
+
+ /**
+ * Function DrawItemsDCodeID
+ * Draw the DCode value (if exists) corresponding to gerber item
+ * (polygons do not have a DCode)
+ * @param aDC = the current device context
+ * @param aDrawMode = GR_COPY, GR_OR ...
+ */
+ void DrawItemsDCodeID( wxDC* aDC, GR_DRAWMODE aDrawMode );
+
+ DECLARE_EVENT_TABLE()
+};
+
+#endif /* WX_GERBER_STRUCT_H */
diff --git a/gerbview/gerbview_id.h b/gerbview/gerbview_id.h
new file mode 100644
index 0000000..a69cbcd
--- /dev/null
+++ b/gerbview/gerbview_id.h
@@ -0,0 +1,81 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __GERBVIEW_ID_H__
+#define __GERBVIEW_ID_H__
+
+#include <id.h>
+
+/**
+ * Command IDs for the printed circuit board editor.
+ *
+ * Please add IDs that are unique to the gerber file viewer (GerbView) here and not in
+ * the global id.h file. This will prevent the entire project from being rebuilt when
+ * adding new commands to the GerbView.
+ */
+
+enum gerbview_ids
+{
+ ID_MAIN_MENUBAR = ID_END_LIST,
+
+ ID_GERBVIEW_SHOW_LIST_DCODES,
+ ID_GERBVIEW_LOAD_DRILL_FILE,
+ ID_GERBVIEW_ERASE_ALL,
+ ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE,
+ ID_GERBVIEW_SHOW_SOURCE,
+ ID_GERBVIEW_EXPORT_TO_PCBNEW,
+
+ ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
+ ID_MENU_GERBVIEW_SELECT_PREFERED_EDITOR,
+
+ // IDs for drill file history (wxID_FILEnn is already in use)
+ ID_GERBVIEW_DRILL_FILE,
+ ID_GERBVIEW_DRILL_FILE1,
+ ID_GERBVIEW_DRILL_FILE2,
+ ID_GERBVIEW_DRILL_FILE3,
+ ID_GERBVIEW_DRILL_FILE4,
+ ID_GERBVIEW_DRILL_FILE5,
+ ID_GERBVIEW_DRILL_FILE6,
+ ID_GERBVIEW_DRILL_FILE7,
+ ID_GERBVIEW_DRILL_FILE8,
+ ID_GERBVIEW_DRILL_FILE9,
+
+ ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER,
+ ID_GERBVIEW_GLOBAL_DELETE,
+ ID_GERBVIEW_OPTIONS_SETUP,
+ ID_GERBVIEW_SET_PAGE_BORDER,
+ ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR,
+ ID_TB_OPTIONS_SHOW_DCODES,
+ ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH,
+ ID_TB_OPTIONS_SHOW_LINES_SKETCH,
+ ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH,
+ ID_TB_OPTIONS_SHOW_NEGATIVE_ITEMS,
+ ID_TB_OPTIONS_SHOW_GBR_MODE_0,
+ ID_TB_OPTIONS_SHOW_GBR_MODE_1,
+ ID_TB_OPTIONS_SHOW_GBR_MODE_2,
+
+ ID_GERBER_END_LIST
+};
+
+#endif /* __GERBVIEW_IDS_H__ */
diff --git a/gerbview/hotkeys.cpp b/gerbview/hotkeys.cpp
new file mode 100644
index 0000000..eae1ad0
--- /dev/null
+++ b/gerbview/hotkeys.cpp
@@ -0,0 +1,216 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 <Jean-Pierre Charras>
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file gerbview/hotkeys.cpp
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <kicad_device_context.h>
+#include <id.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <class_drawpanel.h>
+#include <hotkeys.h>
+#include <gerbview_id.h>
+
+
+/* How to add a new hotkey:
+ * add a new id in the enum hotkey_id_commnand like MY_NEW_ID_FUNCTION.
+ * add a new EDA_HOTKEY entry like:
+ * static EDA_HOTKEY HkMyNewEntry(wxT("Command Label"), MY_NEW_ID_FUNCTION, default key value);
+ * "Command Label" is the name used in hotkey list display, and the identifier in the
+ * hotkey list file MY_NEW_ID_FUNCTION is an equivalent id function used in the switch
+ * in OnHotKey() function. default key value is the default hotkey for this command.
+ * Can be overrided by the user hotkey list file add the HkMyNewEntry pointer in the
+ * s_board_edit_Hotkey_List list ( or/and the s_module_edit_Hotkey_List list) Add the
+ * new code in the switch in OnHotKey() function. when the variable PopupOn is true,
+ * an item is currently edited. This can be usefull if the new function cannot be
+ * executed while an item is currently being edited
+ * ( For example, one cannot start a new wire when a component is moving.)
+ *
+ * Note: If an hotkey is a special key, be sure the corresponding wxWidget keycode (WXK_XXXX)
+ * is handled in the hotkey_name_descr s_Hotkey_Name_List list (see hotkeys_basic.cpp)
+ * and see this list for some ascii keys (space ...)
+ */
+
+// local variables
+// Hotkey list:
+static EDA_HOTKEY HkZoomAuto( _HKI( "Zoom Auto" ), HK_ZOOM_AUTO, WXK_HOME );
+static EDA_HOTKEY HkZoomCenter( _HKI( "Zoom Center" ), HK_ZOOM_CENTER, WXK_F4 );
+static EDA_HOTKEY HkZoomRedraw( _HKI( "Zoom Redraw" ), HK_ZOOM_REDRAW, WXK_F3 );
+static EDA_HOTKEY HkZoomOut( _HKI( "Zoom Out" ), HK_ZOOM_OUT, WXK_F2 );
+static EDA_HOTKEY HkZoomIn( _HKI( "Zoom In" ), HK_ZOOM_IN, WXK_F1 );
+static EDA_HOTKEY HkHelp( _HKI( "Help (this window)" ), HK_HELP, '?' );
+static EDA_HOTKEY HkSwitchUnits( _HKI( "Switch Units" ), HK_SWITCH_UNITS, 'U' );
+static EDA_HOTKEY HkResetLocalCoord( _HKI( "Reset Local Coordinates" ), HK_RESET_LOCAL_COORD, ' ' );
+
+static EDA_HOTKEY HkLinesDisplayMode( _HKI( "Gbr Lines Display Mode" ), HK_GBR_LINES_DISPLAY_MODE, 'L' );
+static EDA_HOTKEY HkFlashedDisplayMode( _HKI( "Gbr Flashed Display Mode" ), HK_GBR_FLASHED_DISPLAY_MODE, 'F' );
+static EDA_HOTKEY HkPolygonDisplayMode( _HKI( "Gbr Polygons Display Mode" ), HK_GBR_POLYGON_DISPLAY_MODE, 'P' );
+static EDA_HOTKEY HkNegativeObjDisplayMode( _HKI( "Gbr Negative Obj Display Mode" ), HK_GBR_NEGATIVE_DISPLAY_ONOFF, 'N' );
+static EDA_HOTKEY HkDCodesDisplayMode( _HKI( "DCodes Display Mode" ), HK_GBR_DCODE_DISPLAY_ONOFF, 'D' );
+
+static EDA_HOTKEY HkSwitch2NextCopperLayer( _HKI( "Switch to Next Layer" ), HK_SWITCH_LAYER_TO_NEXT, '+' );
+static EDA_HOTKEY HkSwitch2PreviousCopperLayer( _HKI( "Switch to Previous Layer" ), HK_SWITCH_LAYER_TO_PREVIOUS, '-' );
+
+// List of common hotkey descriptors
+EDA_HOTKEY* gerbviewHotkeyList[] = {
+ &HkHelp,
+ &HkZoomIn, &HkZoomOut, &HkZoomRedraw, &HkZoomCenter,
+ &HkZoomAuto, &HkSwitchUnits, &HkResetLocalCoord,
+ &HkLinesDisplayMode, &HkFlashedDisplayMode, &HkPolygonDisplayMode,
+ &HkDCodesDisplayMode, &HkNegativeObjDisplayMode,
+ &HkSwitch2NextCopperLayer,
+ &HkSwitch2PreviousCopperLayer,
+ NULL
+};
+
+
+// list of sections and corresponding hotkey list for GerbView (used to create an hotkey
+// config file)
+static wxString gerbviewSectionTag( wxT( "[gerbview]" ) );
+static wxString gerbviewSectionTitle( _HKI( "Gerbview Hotkeys" ) );
+
+struct EDA_HOTKEY_CONFIG GerbviewHokeysDescr[] =
+{
+ { &gerbviewSectionTag, gerbviewHotkeyList, &gerbviewSectionTitle },
+ { NULL, NULL, NULL }
+};
+
+
+EDA_HOTKEY* GERBVIEW_FRAME::GetHotKeyDescription( int aCommand ) const
+{
+ EDA_HOTKEY* HK_Descr = GetDescriptorFromCommand( aCommand, gerbviewHotkeyList );
+
+ return HK_Descr;
+}
+
+
+bool GERBVIEW_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosition, EDA_ITEM* aItem )
+{
+ #define CHANGE( x ) ( x ) = not (x )
+
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+ cmd.SetEventObject( this );
+
+ /* Convert lower to upper case (the usual toupper function has problem with non ascii
+ * codes like function keys */
+ if( (aHotkeyCode >= 'a') && (aHotkeyCode <= 'z') )
+ aHotkeyCode += 'A' - 'a';
+
+ EDA_HOTKEY * HK_Descr = GetDescriptorFromHotkey( aHotkeyCode, gerbviewHotkeyList );
+
+ if( HK_Descr == NULL )
+ return false;
+
+ switch( HK_Descr->m_Idcommand )
+ {
+ default:
+ case HK_NOT_FOUND:
+ return false;
+
+ case HK_HELP: // Display Current hotkey list
+ DisplayHotkeyList( this, GerbviewHokeysDescr );
+ break;
+
+ case HK_ZOOM_IN:
+ cmd.SetId( ID_POPUP_ZOOM_IN );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_OUT:
+ cmd.SetId( ID_POPUP_ZOOM_OUT );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_REDRAW:
+ cmd.SetId( ID_ZOOM_REDRAW );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_CENTER:
+ cmd.SetId( ID_POPUP_ZOOM_CENTER );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_AUTO:
+ cmd.SetId( ID_ZOOM_PAGE );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_RESET_LOCAL_COORD: // Reset the relative coord
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ break;
+
+ case HK_SWITCH_UNITS:
+ g_UserUnit = (g_UserUnit == INCHES ) ? MILLIMETRES : INCHES;
+ break;
+
+ case HK_GBR_LINES_DISPLAY_MODE:
+ CHANGE( m_DisplayOptions.m_DisplayLinesFill );
+ m_canvas->Refresh();
+ break;
+
+ case HK_GBR_FLASHED_DISPLAY_MODE:
+ CHANGE( m_DisplayOptions.m_DisplayFlashedItemsFill );
+ m_canvas->Refresh( true );
+ break;
+
+ case HK_GBR_POLYGON_DISPLAY_MODE:
+ CHANGE( m_DisplayOptions.m_DisplayPolygonsFill );
+ m_canvas->Refresh();
+ break;
+
+ case HK_GBR_NEGATIVE_DISPLAY_ONOFF:
+ SetElementVisibility( NEGATIVE_OBJECTS_VISIBLE, not IsElementVisible( NEGATIVE_OBJECTS_VISIBLE ) );
+ m_canvas->Refresh();
+ break;
+
+ case HK_GBR_DCODE_DISPLAY_ONOFF:
+ SetElementVisibility( DCODES_VISIBLE, not IsElementVisible( DCODES_VISIBLE ) );
+ m_canvas->Refresh();
+ break;
+
+ case HK_SWITCH_LAYER_TO_PREVIOUS:
+ if( getActiveLayer() > 0 )
+ {
+ setActiveLayer( getActiveLayer() - 1 );
+ m_canvas->Refresh();
+ }
+ break;
+
+ case HK_SWITCH_LAYER_TO_NEXT:
+ if( getActiveLayer() < 31 )
+ {
+ setActiveLayer( getActiveLayer() + 1 );
+ m_canvas->Refresh();
+ }
+ break;
+ }
+
+ return true;
+}
diff --git a/gerbview/hotkeys.h b/gerbview/hotkeys.h
new file mode 100644
index 0000000..206d537
--- /dev/null
+++ b/gerbview/hotkeys.h
@@ -0,0 +1,51 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * gerbview/hotkeys.h
+ */
+
+#ifndef GERBVIEW_KOTKEYS_H_
+#define GERBVIEW_KOTKEYS_H_
+
+#include <hotkeys_basic.h>
+
+// List of hot keys id.
+// see also enum common_hotkey_id_commnand in hotkeys_basic.h
+// for shared hotkeys id
+enum hotkey_id_commnand {
+ HK_SWITCH_UNITS = HK_COMMON_END,
+ HK_GBR_LINES_DISPLAY_MODE,
+ HK_GBR_FLASHED_DISPLAY_MODE,
+ HK_GBR_POLYGON_DISPLAY_MODE,
+ HK_GBR_NEGATIVE_DISPLAY_ONOFF,
+ HK_GBR_DCODE_DISPLAY_ONOFF,
+ HK_SWITCH_LAYER_TO_NEXT,
+ HK_SWITCH_LAYER_TO_PREVIOUS
+};
+
+// List of hotkey descriptors for GerbView.
+extern struct EDA_HOTKEY_CONFIG GerbviewHokeysDescr[];
+
+#endif // GERBVIEW_KOTKEYS_H_
diff --git a/gerbview/init_gbr_drawlayers.cpp b/gerbview/init_gbr_drawlayers.cpp
new file mode 100644
index 0000000..87773b0
--- /dev/null
+++ b/gerbview/init_gbr_drawlayers.cpp
@@ -0,0 +1,98 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file init_gbr_drawlayers.cpp
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <class_gerber_draw_item.h>
+#include <class_GERBER.h>
+#include <class_gerbview_layer_widget.h>
+#include <class_gbr_layout.h>
+
+bool GERBVIEW_FRAME::Clear_DrawLayers( bool query )
+{
+ if( GetGerberLayout() == NULL )
+ return false;
+
+ if( query && GetScreen()->IsModify() )
+ {
+ if( !IsOK( this, _( "Current data will be lost?" ) ) )
+ return false;
+ }
+
+ GetGerberLayout()->m_Drawings.DeleteAll();
+
+ g_GERBER_List.ClearList();
+
+ GetGerberLayout()->SetBoundingBox( EDA_RECT() );
+
+ SetScreen( new GBR_SCREEN( GetPageSettings().GetSizeIU() ) );
+
+ setActiveLayer( 0 );
+ m_LayersManager->UpdateLayerIcons();
+ syncLayerBox();
+ return true;
+}
+
+
+void GERBVIEW_FRAME::Erase_Current_DrawLayer( bool query )
+{
+ int layer = getActiveLayer();
+ wxString msg;
+
+ msg.Printf( _( "Clear layer %d?" ), layer + 1 );
+
+ if( query && !IsOK( this, msg ) )
+ return;
+
+ SetCurItem( NULL );
+
+ GERBER_DRAW_ITEM* item = GetGerberLayout()->m_Drawings;
+ GERBER_DRAW_ITEM * next;
+
+ for( ; item; item = next )
+ {
+ next = item->Next();
+
+ if( item->GetLayer() != layer )
+ continue;
+
+ item->DeleteStructure();
+ }
+
+ g_GERBER_List.ClearImage( layer );
+
+ GetScreen()->SetModify();
+ m_canvas->Refresh();
+ m_LayersManager->UpdateLayerIcons();
+ syncLayerBox();
+}
diff --git a/gerbview/locate.cpp b/gerbview/locate.cpp
new file mode 100644
index 0000000..f2fb2a4
--- /dev/null
+++ b/gerbview/locate.cpp
@@ -0,0 +1,88 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file locate.cpp
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <msgpanel.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <class_gerber_draw_item.h>
+
+
+/* localize a gerber item and return a pointer to it.
+ * Display info about this item
+ */
+GERBER_DRAW_ITEM* GERBVIEW_FRAME::Locate( const wxPoint& aPosition, int aTypeloc )
+{
+ m_messagePanel->EraseMsgBox();
+ wxPoint ref = aPosition;
+ bool found = false;
+
+ if( aTypeloc == CURSEUR_ON_GRILLE )
+ ref = GetNearestGridPosition( ref );
+
+ int layer = getActiveLayer();
+
+ // Search first on active layer
+ GERBER_DRAW_ITEM* gerb_item = GetItemsList();
+
+ for( ; gerb_item; gerb_item = gerb_item->Next() )
+ {
+ if( gerb_item->GetLayer()!= layer )
+ continue;
+
+ if( gerb_item->HitTest( ref ) )
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if( !found ) // Search on all layers
+ {
+ for( gerb_item = GetItemsList(); gerb_item; gerb_item = gerb_item->Next() )
+ {
+ if( gerb_item->HitTest( ref ) )
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if( found )
+ {
+ MSG_PANEL_ITEMS items;
+ gerb_item->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+ return gerb_item;
+ }
+
+ return NULL;
+}
diff --git a/gerbview/menubar.cpp b/gerbview/menubar.cpp
new file mode 100644
index 0000000..e9ad2bd
--- /dev/null
+++ b/gerbview/menubar.cpp
@@ -0,0 +1,257 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2009-2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file gerbview/menubar.cpp
+ * @brief (Re)Create the main menubar for GerbView
+ */
+#include <fctsys.h>
+
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <gerbview_id.h>
+#include <hotkeys.h>
+#include <menus_helpers.h>
+
+
+void GERBVIEW_FRAME::ReCreateMenuBar()
+{
+ // Create and try to get the current menubar
+ wxMenuBar* menuBar = GetMenuBar();
+
+ if( !menuBar )
+ menuBar = new wxMenuBar();
+
+ // Delete all existing menus so they can be rebuilt.
+ // This allows language changes of the menu text on the fly.
+ menuBar->Freeze();
+
+ while( menuBar->GetMenuCount() )
+ delete menuBar->Remove( 0 );
+
+ // Recreate all menus:
+
+ // Menu File:
+ wxMenu* fileMenu = new wxMenu;
+
+ // Load
+ AddMenuItem( fileMenu,
+ wxID_FILE,
+ _( "Load &Gerber File" ),
+ _( "Load a new Gerber file on the current layer. Previous data will be deleted" ),
+ KiBitmap( gerber_file_xpm ) );
+
+ // Excellon
+ AddMenuItem( fileMenu,
+ ID_GERBVIEW_LOAD_DRILL_FILE,
+ _( "Load &EXCELLON Drill File" ),
+ _( "Load excellon drill file" ),
+ KiBitmap( gerbview_drill_file_xpm ) );
+
+ // Recent gerber files
+ static wxMenu* openRecentGbrMenu;
+
+ // Add this menu to list menu managed by m_fileHistory
+ // (the file history will be updated when adding/removing files in history
+ if( openRecentGbrMenu )
+ Kiface().GetFileHistory().RemoveMenu( openRecentGbrMenu );
+
+ openRecentGbrMenu = new wxMenu();
+
+ Kiface().GetFileHistory().UseMenu( openRecentGbrMenu );
+ Kiface().GetFileHistory().AddFilesToMenu();
+
+ AddMenuItem( fileMenu, openRecentGbrMenu,
+ wxID_ANY,
+ _( "Open &Recent Gerber File" ),
+ _( "Open a recent opened Gerber file" ),
+ KiBitmap( gerber_recent_files_xpm ) );
+
+ // Recent drill files
+ static wxMenu* openRecentDrlMenu;
+
+ if( openRecentDrlMenu )
+ m_drillFileHistory.RemoveMenu( openRecentDrlMenu );
+
+ openRecentDrlMenu = new wxMenu();
+ m_drillFileHistory.UseMenu( openRecentDrlMenu );
+ m_drillFileHistory.AddFilesToMenu( );
+ AddMenuItem( fileMenu, openRecentDrlMenu,
+ wxID_ANY,
+ _( "Open Recent Dri&ll File" ),
+ _( "Open a recent opened drill file" ),
+ KiBitmap( gerbview_open_recent_drill_files_xpm ) );
+
+ // Separator
+ fileMenu->AppendSeparator();
+
+ // Clear all
+ AddMenuItem( fileMenu,
+ ID_GERBVIEW_ERASE_ALL,
+ _( "Clear &All" ),
+ _( "Clear all layers. All data will be deleted" ),
+ KiBitmap( gerbview_clear_layers_xpm ) );
+
+ // Separator
+ fileMenu->AppendSeparator();
+
+ // Export to Pcbnew
+ AddMenuItem( fileMenu,
+ ID_GERBVIEW_EXPORT_TO_PCBNEW,
+ _( "E&xport to Pcbnew" ),
+ _( "Export data in Pcbnew format" ),
+ KiBitmap( export_xpm ) );
+
+ // Separator
+ fileMenu->AppendSeparator();
+
+ // Print
+ AddMenuItem( fileMenu,
+ wxID_PRINT,
+ _( "&Print" ),
+ _( "Print gerber" ),
+ KiBitmap( print_button_xpm ) );
+
+ // Separator
+ fileMenu->AppendSeparator();
+
+ // Exit
+ AddMenuItem( fileMenu,
+ wxID_EXIT,
+ _( "&Close" ),
+ _( "Close GerbView" ),
+ KiBitmap( exit_xpm ) );
+
+ // Menu for configuration and preferences
+ wxMenu* configMenu = new wxMenu;
+
+ // Hide layer manager
+ AddMenuItem( configMenu,
+ ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
+ _( "Hide &Layers Manager" ),
+ m_show_layer_manager_tools ?
+ _( "Hide &Layers Manager" ) : _("Show &Layers Manager" ),
+ KiBitmap( layers_manager_xpm ) );
+
+ // Options (Preferences on WXMAC)
+
+#ifdef __WXMAC__
+ configMenu->Append(wxID_PREFERENCES);
+#else
+ AddMenuItem( configMenu,
+ wxID_PREFERENCES,
+ _( "&Options" ),
+ _( "Set options to draw items" ),
+ KiBitmap( preference_xpm ) );
+#endif // __WXMAC__
+
+ // Language submenu
+ Pgm().AddMenuLanguageList( configMenu );
+
+ // Hotkey submenu
+ AddHotkeyConfigMenu( configMenu );
+
+ // Menu miscellaneous
+ wxMenu* miscellaneousMenu = new wxMenu;
+
+ // List dcodes
+ AddMenuItem( miscellaneousMenu,
+ ID_GERBVIEW_SHOW_LIST_DCODES,
+ _( "&List DCodes" ),
+ _( "List and edit D-codes" ),
+ KiBitmap( show_dcodenumber_xpm ) );
+
+ // Show source
+ AddMenuItem( miscellaneousMenu,
+ ID_GERBVIEW_SHOW_SOURCE,
+ _( "&Show Source" ),
+ _( "Show source file for the current layer" ),
+ KiBitmap( tools_xpm ) );
+
+ // Separator
+ miscellaneousMenu->AppendSeparator();
+
+ // Clear layer
+ AddMenuItem( miscellaneousMenu,
+ ID_GERBVIEW_GLOBAL_DELETE,
+ _( "&Clear Layer" ),
+ _( "Clear current layer" ),
+ KiBitmap( general_deletions_xpm ) );
+
+ // Separator
+ miscellaneousMenu->AppendSeparator();
+
+ // Text editor
+ AddMenuItem( miscellaneousMenu,
+ ID_MENU_GERBVIEW_SELECT_PREFERED_EDITOR,
+ _( "&Text Editor" ),
+ _( "Select your preferred text editor" ),
+ KiBitmap( editor_xpm ) );
+
+ // Menu Help
+ wxMenu* helpMenu = new wxMenu;
+
+ // Version info
+ AddHelpVersionInfoMenuEntry( helpMenu );
+
+ // Contents
+ AddMenuItem( helpMenu,
+ wxID_HELP,
+ _( "Gerbview &Manual" ),
+ _( "Open the GerbView Manual" ),
+ KiBitmap( online_help_xpm ) );
+
+ AddMenuItem( helpMenu,
+ wxID_INDEX,
+ _( "&Getting Started in KiCad" ),
+ _( "Open \"Getting Started in KiCad\" guide for beginners" ),
+ KiBitmap( help_xpm ) );
+
+ // Separator
+ helpMenu->AppendSeparator();
+
+ // About Kicad
+ AddMenuItem( helpMenu,
+ wxID_ABOUT,
+ _( "&About Kicad" ),
+ _( "About KiCad" ),
+ KiBitmap( info_xpm ) );
+
+ // Append menus to the menubar
+ menuBar->Append( fileMenu, _( "&File" ) );
+ menuBar->Append( configMenu, _( "&Preferences" ) );
+ menuBar->Append( miscellaneousMenu, _( "&Miscellaneous" ) );
+ menuBar->Append( helpMenu, _( "&Help" ) );
+
+ menuBar->Thaw();
+
+ // Associate the menu bar with the frame, if no previous menubar
+ if( GetMenuBar() == NULL )
+ SetMenuBar( menuBar );
+ else
+ menuBar->Refresh();
+}
diff --git a/gerbview/onleftclick.cpp b/gerbview/onleftclick.cpp
new file mode 100644
index 0000000..55b47df
--- /dev/null
+++ b/gerbview/onleftclick.cpp
@@ -0,0 +1,60 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <common.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <gerbview_id.h>
+#include <class_GERBER.h>
+#include <dialog_helpers.h>
+#include <class_DCodeSelectionbox.h>
+
+/* Process the command triggered by the left button of the mouse
+ * currently: just display info in the message panel.
+ */
+void GERBVIEW_FRAME::OnLeftClick( wxDC* DC, const wxPoint& aPosition )
+{
+ GERBER_DRAW_ITEM* DrawStruct = Locate( aPosition, CURSEUR_OFF_GRILLE );
+
+ GetScreen()->SetCurItem( DrawStruct );
+
+ if( DrawStruct == NULL )
+ {
+ GERBER_IMAGE* gerber = g_GERBER_List.GetGbrImage( getActiveLayer() );
+
+ if( gerber )
+ gerber->DisplayImageInfo( );
+ }
+}
+
+
+/* Called on a double click of left mouse button.
+ */
+void GERBVIEW_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& aPosition )
+{
+ // Currently: no nothing
+}
diff --git a/gerbview/onrightclick.cpp b/gerbview/onrightclick.cpp
new file mode 100644
index 0000000..8f5cfe3
--- /dev/null
+++ b/gerbview/onrightclick.cpp
@@ -0,0 +1,95 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <id.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <menus_helpers.h>
+
+
+/* Prepare the right-click pullup menu.
+ * The menu already has a list of zoom commands.
+ */
+bool GERBVIEW_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
+{
+ GERBER_DRAW_ITEM* DrawStruct = (GERBER_DRAW_ITEM*) GetScreen()->GetCurItem();
+ wxString msg;
+ bool BlockActive = !GetScreen()->m_BlockLocate.IsIdle();
+ bool busy = DrawStruct && DrawStruct->GetFlags();
+
+ // Do not initiate a start block validation on menu.
+ m_canvas->SetCanStartBlock( -1 );
+
+ // Simple location of elements where possible.
+ if( !busy )
+ {
+ DrawStruct = Locate( aPosition, CURSEUR_OFF_GRILLE );
+ busy = DrawStruct && DrawStruct->GetFlags();
+ }
+
+ // If command in progress, end command.
+ if( GetToolId() != ID_NO_TOOL_SELECTED )
+ {
+ if( busy )
+ AddMenuItem( PopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND,
+ _( "Cancel" ), KiBitmap( cancel_xpm ) );
+ else
+ AddMenuItem( PopMenu, ID_POPUP_CLOSE_CURRENT_TOOL,
+ _( "End Tool" ), KiBitmap( cursor_xpm ) );
+
+ PopMenu->AppendSeparator();
+ }
+ else
+ {
+ if( busy || BlockActive )
+ {
+ if( BlockActive )
+ {
+ AddMenuItem( PopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND,
+ _( "Cancel Block" ), KiBitmap( cancel_xpm ) );
+ PopMenu->AppendSeparator();
+ AddMenuItem( PopMenu, ID_POPUP_PLACE_BLOCK,
+ _( "Place Block" ), KiBitmap( checked_ok_xpm ) );
+ }
+ else
+ {
+ AddMenuItem( PopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND,
+ _( "Cancel" ), KiBitmap( cancel_xpm ) );
+ }
+
+ PopMenu->AppendSeparator();
+ }
+ }
+
+ if( BlockActive )
+ return true;
+
+ if( DrawStruct )
+ GetScreen()->SetCurItem( DrawStruct );
+
+ return true;
+}
diff --git a/gerbview/options.cpp b/gerbview/options.cpp
new file mode 100644
index 0000000..741d00f
--- /dev/null
+++ b/gerbview/options.cpp
@@ -0,0 +1,97 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file options.cpp
+ * @brief Set some general options of GerbView.
+ */
+
+
+#include <fctsys.h>
+#include <common.h>
+#include <class_drawpanel.h>
+
+#include <gerbview.h>
+#include <gerbview_id.h>
+
+
+/**
+ * Function OnSelectOptionToolbar
+ * called to validate current choices
+ */
+void GERBVIEW_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ bool state;
+
+ switch( id )
+ {
+ case ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG:
+ state = ! m_show_layer_manager_tools;
+ id = ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR;
+ break;
+
+ default:
+ state = m_optionsToolBar->GetToolToggled( id );
+ break;
+ }
+
+ switch( id )
+ {
+ case ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH:
+ m_DisplayOptions.m_DisplayFlashedItemsFill = not state;
+ m_canvas->Refresh( true );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_LINES_SKETCH:
+ m_DisplayOptions.m_DisplayLinesFill = not state;
+ m_canvas->Refresh( true );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH:
+ m_DisplayOptions.m_DisplayPolygonsFill = not state;
+ m_canvas->Refresh( true );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_DCODES:
+ SetElementVisibility( DCODES_VISIBLE, state );
+ m_canvas->Refresh( true );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR:
+ // show/hide auxiliary Vertical layers and visibility manager toolbar
+ m_show_layer_manager_tools = state;
+ m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( m_show_layer_manager_tools );
+ m_auimgr.Update();
+ GetMenuBar()->SetLabel( ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
+ m_show_layer_manager_tools ?
+ _("Hide &Layers Manager" ) : _("Show &Layers Manager" ));
+ break;
+
+ default:
+ wxMessageBox( wxT( "GERBVIEW_FRAME::OnSelectOptionToolbar error" ) );
+ break;
+ }
+}
+
diff --git a/gerbview/pcbplot.cpp b/gerbview/pcbplot.cpp
new file mode 100644
index 0000000..2c7ca24
--- /dev/null
+++ b/gerbview/pcbplot.cpp
@@ -0,0 +1,36 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <pcbplot.h>
+
+/** TODO */
+void GERBVIEW_FRAME::ToPlotter(wxCommandEvent& event)
+{
+}
+
diff --git a/gerbview/pcbplot.h b/gerbview/pcbplot.h
new file mode 100644
index 0000000..72eeecf
--- /dev/null
+++ b/gerbview/pcbplot.h
@@ -0,0 +1,40 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file gerbview/pcbplot.h
+ */
+
+#ifndef PCBPLOT_H
+#define PCBPLOT_H
+
+/* Shared Config keys for plot and print */
+#define OPTKEY_LAYERBASE wxT( "PlotLayer_%d" )
+#define OPTKEY_PRINT_X_FINESCALE_ADJ wxT( "PrintXFineScaleAdj" )
+#define OPTKEY_PRINT_Y_FINESCALE_ADJ wxT( "PrintYFineScaleAdj" )
+#define OPTKEY_PRINT_SCALE wxT( "PrintScale" )
+#define OPTKEY_PRINT_PAGE_FRAME wxT( "PrintPageFrame" )
+#define OPTKEY_PRINT_MONOCHROME_MODE wxT( "PrintMonochrome" )
+
+#endif // ifndef PCBPLOT_H
diff --git a/gerbview/printout_control.cpp b/gerbview/printout_control.cpp
new file mode 100644
index 0000000..1eb8ad1
--- /dev/null
+++ b/gerbview/printout_control.cpp
@@ -0,0 +1,269 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file printout_control.cpp
+ * @brief Board print handler implementation file.
+ */
+
+
+// Set this to 1 if you want to test PostScript printing under MSW.
+#define wxTEST_POSTSCRIPT_IN_MSW 1
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <base_units.h>
+#include <wxstruct.h>
+#include <class_base_screen.h>
+#include <layers_id_colors_and_visibility.h>
+
+#include <gerbview_frame.h>
+
+#include <printout_controler.h>
+
+
+
+PRINT_PARAMETERS::PRINT_PARAMETERS()
+{
+ m_PenDefaultSize = Millimeter2iu( 0.2 ); // A reasonable default value to draw items
+ // which do not have a specified line width
+ m_PrintScale = 1.0;
+ m_XScaleAdjust = 1.0;
+ m_YScaleAdjust = 1.0;
+ m_Print_Sheet_Ref = false;
+ m_PrintMaskLayer.set();
+ m_PrintMirror = false;
+ m_Print_Black_and_White = true;
+ m_OptionPrintPage = 1;
+ m_PageCount = 1;
+ m_ForceCentered = false;
+ m_Flags = 0;
+ m_DrillShapeOpt = PRINT_PARAMETERS::SMALL_DRILL_SHAPE;
+ m_PageSetupData = NULL;
+}
+
+
+BOARD_PRINTOUT_CONTROLLER::BOARD_PRINTOUT_CONTROLLER( const PRINT_PARAMETERS& aParams,
+ EDA_DRAW_FRAME* aParent,
+ const wxString& aTitle ) :
+ wxPrintout( aTitle )
+{
+ m_PrintParams = aParams; // Make a local copy of the print parameters.
+ m_Parent = aParent;
+}
+
+
+bool BOARD_PRINTOUT_CONTROLLER::OnPrintPage( int aPage )
+{
+ // in gerbview, draw layers are always printed on separate pages
+ // because handling negative objects when using only one page is tricky
+ m_PrintParams.m_Flags = aPage;
+ DrawPage();
+
+ return true;
+}
+
+
+void BOARD_PRINTOUT_CONTROLLER::GetPageInfo( int* minPage, int* maxPage,
+ int* selPageFrom, int* selPageTo )
+{
+ *minPage = 1;
+ *selPageFrom = 1;
+
+ int icnt = 1;
+
+ if( m_PrintParams.m_OptionPrintPage == 0 )
+ icnt = m_PrintParams.m_PageCount;
+
+ *maxPage = icnt;
+ *selPageTo = icnt;
+}
+
+
+void BOARD_PRINTOUT_CONTROLLER::DrawPage()
+{
+ wxPoint offset;
+ double userscale;
+ EDA_RECT boardBoundingBox;
+ EDA_RECT drawRect;
+ wxDC* dc = GetDC();
+ BASE_SCREEN* screen = m_Parent->GetScreen();
+ bool printMirror = m_PrintParams.m_PrintMirror;
+ wxSize pageSizeIU = m_Parent->GetPageSizeIU();
+
+ wxBusyCursor dummy;
+
+ boardBoundingBox = ((GERBVIEW_FRAME*) m_Parent)->GetGerberLayoutBoundingBox();
+ wxString titleblockFilename; // TODO see if we uses the gerber file name
+
+ // Use the page size as the drawing area when the board is shown or the user scale
+ // is less than 1.
+ if( m_PrintParams.PrintBorderAndTitleBlock() )
+ boardBoundingBox = EDA_RECT( wxPoint( 0, 0 ), pageSizeIU );
+
+ // Compute the PCB size in internal units
+ userscale = m_PrintParams.m_PrintScale;
+
+ if( m_PrintParams.m_PrintScale == 0 ) // fit in page option
+ {
+ if(boardBoundingBox.GetWidth() && boardBoundingBox.GetHeight())
+ {
+ int margin = Millimeter2iu( 10.0 ); // add a margin around the drawings
+ double scaleX = (double)(pageSizeIU.x - (2 * margin)) /
+ boardBoundingBox.GetWidth();
+ double scaleY = (double)(pageSizeIU.y - (2 * margin)) /
+ boardBoundingBox.GetHeight();
+ userscale = (scaleX < scaleY) ? scaleX : scaleY;
+ }
+ else
+ userscale = 1.0;
+ }
+
+ wxSize scaledPageSize = pageSizeIU;
+ drawRect.SetSize( scaledPageSize );
+ scaledPageSize.x = wxRound( scaledPageSize.x / userscale );
+ scaledPageSize.y = wxRound( scaledPageSize.y / userscale );
+
+
+ if( m_PrintParams.m_PageSetupData )
+ {
+ // Always scale to the size of the paper.
+ FitThisSizeToPageMargins( scaledPageSize, *m_PrintParams.m_PageSetupData );
+ }
+
+ // Compute Accurate scale 1
+ if( m_PrintParams.m_PrintScale == 1.0 )
+ {
+ // We want a 1:1 scale, regardless the page setup
+ // like page size, margin ...
+ MapScreenSizeToPaper(); // set best scale and offset (scale is not used)
+ int w, h;
+ GetPPIPrinter( &w, &h );
+ double accurate_Xscale = (double) w / (IU_PER_MILS*1000);
+ double accurate_Yscale = (double) h / (IU_PER_MILS*1000);
+
+ if( IsPreview() ) // Scale must take in account the DC size in Preview
+ {
+ // Get the size of the DC in pixels
+ wxSize PlotAreaSize;
+ dc->GetSize( &PlotAreaSize.x, &PlotAreaSize.y );
+ GetPageSizePixels( &w, &h );
+ accurate_Xscale *= (double)PlotAreaSize.x / w;
+ accurate_Yscale *= (double)PlotAreaSize.y / h;
+ }
+ // Fine scale adjust
+ accurate_Xscale *= m_PrintParams.m_XScaleAdjust;
+ accurate_Yscale *= m_PrintParams.m_YScaleAdjust;
+
+ // Set print scale for 1:1 exact scale
+ dc->SetUserScale( accurate_Xscale, accurate_Yscale );
+ }
+
+ // Get the final size of the DC in pixels
+ wxSize PlotAreaSizeInPixels;
+ dc->GetSize( &PlotAreaSizeInPixels.x, &PlotAreaSizeInPixels.y );
+
+ double scalex, scaley;
+ dc->GetUserScale( &scalex, &scaley );
+
+ wxSize PlotAreaSizeInUserUnits;
+ PlotAreaSizeInUserUnits.x = KiROUND( PlotAreaSizeInPixels.x / scalex );
+ PlotAreaSizeInUserUnits.y = KiROUND( PlotAreaSizeInPixels.y / scaley );
+
+ // In some cases the plot origin is the centre of the board outline rather than the center
+ // of the selected paper size.
+ if( m_PrintParams.CenterOnBoardOutline() )
+ {
+ // Here we are only drawing the board and it's contents.
+ drawRect = boardBoundingBox;
+ offset.x += wxRound( (double) -scaledPageSize.x / 2.0 );
+ offset.y += wxRound( (double) -scaledPageSize.y / 2.0 );
+
+ wxPoint center = boardBoundingBox.Centre();
+
+ if( printMirror )
+ {
+ // Calculate the mirrored center of the board.
+ center.x = m_Parent->GetPageSizeIU().x - boardBoundingBox.Centre().x;
+ }
+
+ offset += center;
+ }
+
+ GRResetPenAndBrush( dc );
+
+ EDA_DRAW_PANEL* panel = m_Parent->GetCanvas();
+ EDA_RECT tmp = *panel->GetClipBox();
+
+ // Set clip box to the max size
+ #define MAX_VALUE (INT_MAX/2) // MAX_VALUE is the max we can use in an integer
+ // and that allows calculations without overflow
+ panel->SetClipBox( EDA_RECT( wxPoint( 0, 0 ), wxSize( MAX_VALUE, MAX_VALUE ) ) );
+
+ screen->m_IsPrinting = true;
+ EDA_COLOR_T bg_color = m_Parent->GetDrawBgColor();
+
+ // Print frame reference, if requested, before printing draw layers
+ if( m_PrintParams.m_Print_Black_and_White )
+ GRForceBlackPen( true );
+
+ if( m_PrintParams.PrintBorderAndTitleBlock() )
+ m_Parent->DrawWorkSheet( dc, screen, m_PrintParams.m_PenDefaultSize,
+ IU_PER_MILS, titleblockFilename );
+
+ if( printMirror )
+ {
+ // To plot mirror, we reverse the x axis, and modify the plot x origin
+ dc->SetAxisOrientation( false, false );
+
+ /* Plot offset x is moved by the x plot area size in order to have
+ * the old draw area in the new draw area, because the draw origin has not moved
+ * (this is the upper left corner) but the X axis is reversed, therefore the plotting area
+ * is the x coordinate values from - PlotAreaSize.x to 0 */
+ int x_dc_offset = PlotAreaSizeInPixels.x;
+ x_dc_offset = KiROUND( x_dc_offset * userscale );
+ dc->SetDeviceOrigin( x_dc_offset, 0 );
+
+ panel->SetClipBox( EDA_RECT( wxPoint( -MAX_VALUE / 2, -MAX_VALUE / 2 ),
+ panel->GetClipBox()->GetSize() ) );
+ }
+
+ // screen->m_DrawOrg = offset;
+ dc->SetLogicalOrigin( offset.x, offset.y );
+ m_Parent->SetDrawBgColor( WHITE );
+
+ // Never force black pen to print draw layers
+ // because negative objects need a white pen, not a black pen
+ // B&W mode is handled in print page function
+ GRForceBlackPen( false );
+
+ m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror, &m_PrintParams );
+
+ m_Parent->SetDrawBgColor( bg_color );
+ screen->m_IsPrinting = false;
+ panel->SetClipBox( tmp );
+}
diff --git a/gerbview/readgerb.cpp b/gerbview/readgerb.cpp
new file mode 100644
index 0000000..3a6f968
--- /dev/null
+++ b/gerbview/readgerb.cpp
@@ -0,0 +1,199 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <class_GERBER.h>
+
+#include <html_messagebox.h>
+#include <macros.h>
+
+/* Read a gerber file, RS274D, RS274X or RS274X2 format.
+ */
+bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName,
+ const wxString& D_Code_FullFileName )
+{
+ int G_command = 0; // command number for G commands like G04
+ int D_commande = 0; // command number for D commands like D02
+
+ char line[GERBER_BUFZ];
+
+ wxString msg;
+ char* text;
+ int layer; // current layer used in GerbView
+
+ layer = getActiveLayer();
+ GERBER_IMAGE* gerber = g_GERBER_List.GetGbrImage( layer );
+
+ if( gerber == NULL )
+ {
+ gerber = new GERBER_IMAGE( this, layer );
+ g_GERBER_List.AddGbrImage( gerber, layer );
+ }
+
+ ClearMessageList( );
+
+ /* Set the gerber scale: */
+ gerber->ResetDefaultValues();
+
+ /* Read the gerber file */
+ gerber->m_Current_File = wxFopen( GERBER_FullFileName, wxT( "rt" ) );
+ if( gerber->m_Current_File == 0 )
+ {
+ msg.Printf( _( "File <%s> not found" ), GetChars( GERBER_FullFileName ) );
+ DisplayError( this, msg, 10 );
+ return false;
+ }
+
+ gerber->m_FileName = GERBER_FullFileName;
+
+ wxString path = wxPathOnly( GERBER_FullFileName );
+ if( path != wxEmptyString )
+ wxSetWorkingDirectory( path );
+
+ LOCALE_IO toggleIo;
+
+ while( true )
+ {
+ if( fgets( line, sizeof(line), gerber->m_Current_File ) == NULL )
+ {
+ if( gerber->m_FilesPtr == 0 )
+ break;
+
+ fclose( gerber->m_Current_File );
+
+ gerber->m_FilesPtr--;
+ gerber->m_Current_File =
+ gerber->m_FilesList[gerber->m_FilesPtr];
+
+ continue;
+ }
+
+ text = StrPurge( line );
+
+ while( text && *text )
+ {
+ switch( *text )
+ {
+ case ' ':
+ case '\r':
+ case '\n':
+ text++;
+ break;
+
+ case '*': // End command
+ gerber->m_CommandState = END_BLOCK;
+ text++;
+ break;
+
+ case 'M': // End file
+ gerber->m_CommandState = CMD_IDLE;
+ while( *text )
+ text++;
+ break;
+
+ case 'G': /* Line type Gxx : command */
+ G_command = gerber->GCodeNumber( text );
+ gerber->Execute_G_Command( text, G_command );
+ break;
+
+ case 'D': /* Line type Dxx : Tool selection (xx > 0) or
+ * command if xx = 0..9 */
+ D_commande = gerber->DCodeNumber( text );
+ gerber->Execute_DCODE_Command( text, D_commande );
+ break;
+
+ case 'X':
+ case 'Y': /* Move or draw command */
+ gerber->m_CurrentPos = gerber->ReadXYCoord( text );
+ if( *text == '*' ) // command like X12550Y19250*
+ {
+ gerber->Execute_DCODE_Command( text,
+ gerber->m_Last_Pen_Command );
+ }
+ break;
+
+ case 'I':
+ case 'J': /* Auxiliary Move command */
+ gerber->m_IJPos = gerber->ReadIJCoord( text );
+ if( *text == '*' ) // command like X35142Y15945J504*
+ {
+ gerber->Execute_DCODE_Command( text,
+ gerber->m_Last_Pen_Command );
+ }
+ break;
+
+ case '%':
+ if( gerber->m_CommandState != ENTER_RS274X_CMD )
+ {
+ gerber->m_CommandState = ENTER_RS274X_CMD;
+ gerber->ReadRS274XCommand( line, text );
+ }
+ else //Error
+ {
+ ReportMessage( wxT("Expected RS274X Command") );
+ gerber->m_CommandState = CMD_IDLE;
+ text++;
+ }
+ break;
+
+ default:
+ text++;
+ msg.Printf( wxT("Unexpected symbol <%c>"), *text );
+ ReportMessage( msg );
+ break;
+ }
+ }
+ }
+
+ fclose( gerber->m_Current_File );
+
+ gerber->m_InUse = true;
+
+ // Display errors list
+ if( m_Messages.size() > 0 )
+ {
+ HTML_MESSAGE_BOX dlg( this, _("Errors") );
+ dlg.ListSet(m_Messages);
+ dlg.ShowModal();
+ }
+
+ /* if the gerber file is only a RS274D file
+ * (i.e. without any aperture information), wran the user:
+ */
+ if( !gerber->m_Has_DCode )
+ {
+ msg = _("Warning: this file has no D-Code definition\n"
+ "It is perhaps an old RS274D file\n"
+ "Therefore the size of items is undefined");
+ wxMessageBox( msg );
+ }
+
+ return true;
+}
diff --git a/gerbview/rs274_read_XY_and_IJ_coordinates.cpp b/gerbview/rs274_read_XY_and_IJ_coordinates.cpp
new file mode 100644
index 0000000..f9a2fb7
--- /dev/null
+++ b/gerbview/rs274_read_XY_and_IJ_coordinates.cpp
@@ -0,0 +1,305 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+
+#include <gerbview.h>
+#include <macros.h>
+#include <class_GERBER.h>
+#include <base_units.h>
+
+
+/* These routines read the text string point from Text.
+ * On exit, Text points the beginning of the sequence unread
+ */
+
+// convertion scale from gerber file units to Gerbview internal units
+// depending on the gerber file format
+// this scale list assumes gerber units are imperial.
+// for metric gerber units, the imperial to metric conversion is made in read functions
+#define SCALE_LIST_SIZE 9
+static double scale_list[SCALE_LIST_SIZE] =
+{
+ 1000.0 * IU_PER_MILS, // x.1 format (certainly useless)
+ 100.0 * IU_PER_MILS, // x.2 format (certainly useless)
+ 10.0 * IU_PER_MILS, // x.3 format
+ 1.0 * IU_PER_MILS, // x.4 format
+ 0.1 * IU_PER_MILS, // x.5 format
+ 0.01 * IU_PER_MILS, // x.6 format
+ 0.001 * IU_PER_MILS, // x.7 format (currently the max allowed precision)
+ 0.0001 * IU_PER_MILS, // provided, but not used
+ 0.00001 * IU_PER_MILS, // provided, but not used
+};
+
+/*
+ * Function scale
+ * converts a coordinate given in floating point to Gerbvies internal units
+ * (currently = 10 nanometers)
+ */
+int scaletoIU( double aCoord, bool isMetric )
+{
+ int ret;
+
+ if( isMetric ) // gerber are units in mm
+ ret = KiROUND( aCoord * IU_PER_MM );
+ else // gerber are units in inches
+ ret = KiROUND( aCoord * IU_PER_MILS * 1000.0 );
+
+ return ret;
+}
+
+
+wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text )
+{
+ wxPoint pos;
+ int type_coord = 0, current_coord, nbdigits;
+ bool is_float = m_DecimalFormat;
+ char* text;
+ char line[256];
+
+
+ if( m_Relative )
+ pos.x = pos.y = 0;
+ else
+ pos = m_CurrentPos;
+
+ if( Text == NULL )
+ return pos;
+
+ text = line;
+ while( *Text )
+ {
+ if( (*Text == 'X') || (*Text == 'Y') )
+ {
+ type_coord = *Text;
+ Text++;
+ text = line;
+ nbdigits = 0;
+
+ while( IsNumber( *Text ) )
+ {
+ if( *Text == '.' ) // Force decimat format if reading a floating point number
+ is_float = true;
+
+ // count digits only (sign and decimal point are not counted)
+ if( (*Text >= '0') && (*Text <='9') )
+ nbdigits++;
+ *(text++) = *(Text++);
+ }
+
+ *text = 0;
+
+ if( is_float )
+ {
+ // When X or Y values are float numbers, they are given in mm or inches
+ if( m_GerbMetric ) // units are mm
+ current_coord = KiROUND( atof( line ) * IU_PER_MILS / 0.0254 );
+ else // units are inches
+ current_coord = KiROUND( atof( line ) * IU_PER_MILS * 1000 );
+ }
+ else
+ {
+ int fmt_scale = (type_coord == 'X') ? m_FmtScale.x : m_FmtScale.y;
+
+ if( m_NoTrailingZeros )
+ {
+ int min_digit =
+ (type_coord == 'X') ? m_FmtLen.x : m_FmtLen.y;
+ while( nbdigits < min_digit )
+ {
+ *(text++) = '0';
+ nbdigits++;
+ }
+
+ *text = 0;
+ }
+
+ current_coord = atoi( line );
+ double real_scale = scale_list[fmt_scale];
+
+ if( m_GerbMetric )
+ real_scale = real_scale / 25.4;
+
+ current_coord = KiROUND( current_coord * real_scale );
+ }
+
+ if( type_coord == 'X' )
+ pos.x = current_coord;
+ else if( type_coord == 'Y' )
+ pos.y = current_coord;
+
+ continue;
+ }
+ else
+ break;
+ }
+
+ if( m_Relative )
+ {
+ pos.x += m_CurrentPos.x;
+ pos.y += m_CurrentPos.y;
+ }
+
+ m_CurrentPos = pos;
+ return pos;
+}
+
+
+/* Returns the current coordinate type pointed to by InnJnn Text (InnnnJmmmm)
+ * These coordinates are relative, so if coordinate is absent, it's value
+ * defaults to 0
+ */
+wxPoint GERBER_IMAGE::ReadIJCoord( char*& Text )
+{
+ wxPoint pos( 0, 0 );
+
+ int type_coord = 0, current_coord, nbdigits;
+ bool is_float = false;
+ char* text;
+ char line[256];
+
+ if( Text == NULL )
+ return pos;
+
+ text = line;
+ while( *Text )
+ {
+ if( (*Text == 'I') || (*Text == 'J') )
+ {
+ type_coord = *Text;
+ Text++;
+ text = line;
+ nbdigits = 0;
+ while( IsNumber( *Text ) )
+ {
+ if( *Text == '.' )
+ is_float = true;
+
+ // count digits only (sign and decimal point are not counted)
+ if( (*Text >= '0') && (*Text <='9') )
+ nbdigits++;
+
+ *(text++) = *(Text++);
+ }
+
+ *text = 0;
+ if( is_float )
+ {
+ // When X or Y values are float numbers, they are given in mm or inches
+ if( m_GerbMetric ) // units are mm
+ current_coord = KiROUND( atof( line ) * IU_PER_MILS / 0.0254 );
+ else // units are inches
+ current_coord = KiROUND( atof( line ) * IU_PER_MILS * 1000 );
+ }
+ else
+ {
+ int fmt_scale =
+ (type_coord == 'I') ? m_FmtScale.x : m_FmtScale.y;
+
+ if( m_NoTrailingZeros )
+ {
+ int min_digit =
+ (type_coord == 'I') ? m_FmtLen.x : m_FmtLen.y;
+ while( nbdigits < min_digit )
+ {
+ *(text++) = '0';
+ nbdigits++;
+ }
+
+ *text = 0;
+ }
+
+ current_coord = atoi( line );
+
+ double real_scale = scale_list[fmt_scale];
+
+ if( m_GerbMetric )
+ real_scale = real_scale / 25.4;
+
+ current_coord = KiROUND( current_coord * real_scale );
+ }
+ if( type_coord == 'I' )
+ pos.x = current_coord;
+ else if( type_coord == 'J' )
+ pos.y = current_coord;
+
+ continue;
+ }
+ else
+ break;
+ }
+
+ m_IJPos = pos;
+ return pos;
+}
+
+
+// Helper functions:
+
+/**
+ * Function ReadInt
+ * reads an int from an ASCII character buffer. If there is a comma after the
+ * int, then skip over that.
+ * @param text A reference to a character pointer from which bytes are read
+ * and the pointer is advanced for each byte read.
+ * @param aSkipSeparator = true (default) to skip comma
+ * @return int - The int read in.
+ */
+int ReadInt( char*& text, bool aSkipSeparator = true )
+{
+ int ret = (int) strtol( text, &text, 10 );
+
+ if( *text == ',' || isspace( *text ) )
+ {
+ if( aSkipSeparator )
+ ++text;
+ }
+
+ return ret;
+}
+
+
+/**
+ * Function ReadDouble
+ * reads a double from an ASCII character buffer. If there is a comma after
+ * the double, then skip over that.
+ * @param text A reference to a character pointer from which the ASCII double
+ * is read from and the pointer advanced for each character read.
+ * @param aSkipSeparator = true (default) to skip comma
+ * @return double
+ */
+double ReadDouble( char*& text, bool aSkipSeparator = true )
+{
+ double ret = strtod( text, &text );
+
+ if( *text == ',' || isspace( *text ) )
+ {
+ if( aSkipSeparator )
+ ++text;
+ }
+
+ return ret;
+}
+
diff --git a/gerbview/rs274d.cpp b/gerbview/rs274d.cpp
new file mode 100644
index 0000000..3d8ec54
--- /dev/null
+++ b/gerbview/rs274d.cpp
@@ -0,0 +1,771 @@
+/**
+ * @file rs274d.cpp
+ * @brief functions to read the rs274d commands from a rs274d/rs274x file
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <trigo.h>
+#include <macros.h>
+#include <class_gerber_draw_item.h>
+#include <class_GERBER.h>
+#include <class_X2_gerber_attributes.h>
+
+#include <cmath>
+
+/* Gerber: NOTES about some important commands found in RS274D and RS274X (G codes):
+ * Gn =
+ * G01 linear interpolation (right trace)
+ * G02, G20, G21 Circular interpolation, meaning trig <0 (clockwise)
+ * G03, G30, G31 Circular interpolation, meaning trigo> 0 (counterclockwise)
+ * G04 = comment. Since Sept 2014, file attributes can be found here
+ * if the line starts by G04 #@!
+ * G06 parabolic interpolation
+ * G07 Cubic Interpolation
+ * G10 linear interpolation (scale x10)
+ * G11 linear interpolation (0.1x range)
+ * G12 linear interpolation (0.01x scale)
+ * G36 Start polygon mode
+ * G37 Stop polygon mode (and close it)
+ * G54 Selection Tool
+ * G60 linear interpolation (scale x100)
+ * G70 Select Units = Inches
+ * G71 Select Units = Millimeters
+ * G74 disable 360 degrees circular interpolation (return to 90 deg mode)
+ * and perhaps circular interpolation (return to linear interpolation )
+ * see rs274xrevd_e.pdf pages 47 and 48
+ * Unfortunately page 47 said G74 disable G02 or G03
+ * and page 48 said G01 must be used to disable G02 or G03.
+ * Currently GerbView disable G02 or G03 after a G74 command (tests using 2 gerber files).
+ * G75 enable 360 degrees circular interpolation
+ * G90 mode absolute coordinates
+ *
+ * X, Y
+ * X and Y are followed by + or - and m + n digits (not separated)
+ * m = integer part
+ * n = part after the comma
+ * Classic formats: m = 2, n = 3 (size 2.3)
+ * m = 3, n = 4 (size 3.4)
+ * eg
+ * GxxX00345Y-06123*
+ *
+ * Tools and D_CODES
+ * Tool number (identification of shapes)
+ * 10 to 999
+ * D_CODES:
+ * D01 ... D9 = command codes:
+ * D01 = activating light (pen down) when placement
+ * D02 = light extinction (pen up) when placement
+ * D03 = Flash
+ * D09 = VAPE Flash (I never see this command in gerber file)
+ * D51 = G54 preceded by -> Select VAPE
+ *
+ * D10 ... D999 = Identification Tool: tool selection
+ */
+
+
+/* Local Functions (are lower case since they are private to this source file)
+**/
+
+
+/**
+ * Function fillFlashedGBRITEM
+ * initializes a given GBRITEM so that it can draw a circle which is filled and
+ * has no pen border.
+ *
+ * @param aGbrItem The GBRITEM to fill in.
+ * @param aAperture the associated type of aperture
+ * @param Dcode_index The DCODE value, like D14
+ * @param aLayer The layer index to set into the GBRITEM
+ * @param aPos The center point of the flash
+ * @param aSize The diameter of the round flash
+ * @param aLayerNegative = true if the current layer is negative
+ */
+void fillFlashedGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
+ APERTURE_T aAperture,
+ int Dcode_index,
+ int aLayer,
+ const wxPoint& aPos,
+ wxSize aSize,
+ bool aLayerNegative )
+{
+ aGbrItem->SetLayer( aLayer );
+ aGbrItem->m_Size = aSize;
+ aGbrItem->m_Start = aPos;
+ aGbrItem->m_End = aGbrItem->m_Start;
+ aGbrItem->m_DCode = Dcode_index;
+ aGbrItem->SetLayerPolarity( aLayerNegative );
+ aGbrItem->m_Flashed = true;
+ switch( aAperture )
+ {
+ case APT_POLYGON: // flashed regular polygon
+ aGbrItem->m_Shape = GBR_SPOT_POLY;
+ break;
+
+ case APT_CIRCLE:
+ aGbrItem->m_Shape = GBR_SPOT_CIRCLE;
+ aGbrItem->m_Size.y = aGbrItem->m_Size.x;
+ break;
+
+ case APT_OVAL:
+ aGbrItem->m_Shape = GBR_SPOT_OVAL;
+ break;
+
+ case APT_RECT:
+ aGbrItem->m_Shape = GBR_SPOT_RECT;
+ break;
+
+ case APT_MACRO:
+ aGbrItem->m_Shape = GBR_SPOT_MACRO;
+ break;
+ }
+}
+
+
+/**
+ * Function fillLineGBRITEM
+ * initializes a given GBRITEM so that it can draw a linear D code.
+ *
+ * @param aGbrItem The GERBER_DRAW_ITEM to fill in.
+ * @param Dcode_index The DCODE value, like D14
+ * @param aLayer The layer index to set into the GBRITEM
+ * @param aStart The starting point of the line
+ * @param aEnd The ending point of the line
+ * @param aPenSize The size of the flash. Note rectangular shapes are legal.
+ * @param aLayerNegative = true if the current layer is negative
+ */
+void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
+ int Dcode_index,
+ int aLayer,
+ const wxPoint& aStart,
+ const wxPoint& aEnd,
+ wxSize aPenSize,
+ bool aLayerNegative )
+{
+ aGbrItem->SetLayer( aLayer );
+ aGbrItem->m_Flashed = false;
+
+ aGbrItem->m_Size = aPenSize;
+
+ aGbrItem->m_Start = aStart;
+ aGbrItem->m_End = aEnd;
+
+ aGbrItem->m_DCode = Dcode_index;
+ aGbrItem->SetLayerPolarity( aLayerNegative );
+}
+
+
+/**
+ * Function fillArcGBRITEM
+ * initializes a given GBRITEM so that it can draw an arc G code.
+ * <p>
+ * if multiquadrant == true : arc can be 0 to 360 degrees
+ * and \a rel_center is the center coordinate relative to start point.
+ * <p>
+ * if multiquadrant == false arc can be only 0 to 90 deg,
+ * and only in the same quadrant :
+ * <ul>
+ * <li> absolute angle 0 to 90 (quadrant 1) or
+ * <li> absolute angle 90 to 180 (quadrant 2) or
+ * <li> absolute angle 180 to 270 (quadrant 3) or
+ * <li> absolute angle 270 to 0 (quadrant 4)
+ * </ul><p>
+ * @param aGbrItem is the GBRITEM to fill in.
+ * @param Dcode_index is the DCODE value, like D14
+ * @param aLayer is the layer index to set into the GBRITEM
+ * @param aStart is the starting point
+ * @param aEnd is the ending point
+ * @param aRelCenter is the center coordinate relative to start point,
+ * given in ABSOLUTE VALUE and the sign of values x et y de rel_center
+ * must be calculated from the previously given constraint: arc only in the
+ * same quadrant.
+ * @param aClockwise true if arc must be created clockwise
+ * @param aPenSize The size of the flash. Note rectangular shapes are legal.
+ * @param aMultiquadrant = true to create arcs upto 360 deg,
+ * false when arc is inside one quadrant
+ * @param aLayerNegative = true if the current layer is negative
+ */
+static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aLayer,
+ const wxPoint& aStart, const wxPoint& aEnd,
+ const wxPoint& aRelCenter, wxSize aPenSize,
+ bool aClockwise, bool aMultiquadrant,
+ bool aLayerNegative )
+{
+ wxPoint center, delta;
+
+ aGbrItem->m_Shape = GBR_ARC;
+ aGbrItem->SetLayer( aLayer );
+ aGbrItem->m_Size = aPenSize;
+ aGbrItem->m_Flashed = false;
+
+ if( aMultiquadrant )
+ center = aStart + aRelCenter;
+ else
+ {
+ // in single quadrant mode the relative coordinate aRelCenter is always >= 0
+ // So we must recalculate the actual sign of aRelCenter.x and aRelCenter.y
+ center = aRelCenter;
+
+ // calculate arc end coordinate relative to the starting point,
+ // because center is relative to the center point
+ delta = aEnd - aStart;
+
+ // now calculate the relative to aStart center position, for a draw function
+ // that use trigonometric arc angle (or counter-clockwise)
+ /* Quadrants:
+ * Y
+ * 2 | 1
+ * -------X
+ * 3 | 4
+ * C = actual relative arc center, S = arc start (axis origin) E = relative arc end
+ */
+ if( (delta.x >= 0) && (delta.y >= 0) )
+ {
+ /* Quadrant 1 (trigo or cclockwise):
+ * C | E
+ * ---S---
+ * 3 | 4
+ */
+ center.x = -center.x;
+ }
+ else if( (delta.x >= 0) && (delta.y < 0) )
+ {
+ /* Quadrant 4 (trigo or cclockwise):
+ * 2 | C
+ * ---S---
+ * 3 | E
+ */
+ // Nothing to do
+ }
+ else if( (delta.x < 0) && (delta.y >= 0) )
+ {
+ /* Quadrant 2 (trigo or cclockwise):
+ * E | 1
+ * ---S---
+ * C | 4
+ */
+ center.x = -center.x;
+ center.y = -center.y;
+ }
+ else
+ {
+ /* Quadrant 3 (trigo or cclockwise):
+ * 2 | 1
+ * ---S---
+ * E | C
+ */
+ center.y = -center.y;
+ }
+
+ // Due to your draw arc function, we need this:
+ if( !aClockwise )
+ center = - center;
+
+ // Calculate actual arc center coordinate:
+ center += aStart;
+ }
+
+ if( aClockwise )
+ {
+ aGbrItem->m_Start = aStart;
+ aGbrItem->m_End = aEnd;
+ }
+ else
+ {
+ aGbrItem->m_Start = aEnd;
+ aGbrItem->m_End = aStart;
+ }
+
+ aGbrItem->m_ArcCentre = center;
+
+ aGbrItem->m_DCode = Dcode_index;
+ aGbrItem->SetLayerPolarity( aLayerNegative );
+}
+
+
+/**
+ * Function fillArcPOLY
+ * creates an arc G code when found in poly outlines.
+ * <p>
+ * if multiquadrant == true : arc can be 0 to 360 degrees
+ * and \a rel_center is the center coordinate relative to start point.
+ * <p>
+ * if multiquadrant == false arc can be only 0 to 90 deg,
+ * and only in the same quadrant :
+ * <ul>
+ * <li> absolute angle 0 to 90 (quadrant 1) or
+ * <li> absolute angle 90 to 180 (quadrant 2) or
+ * <li> absolute angle 180 to 270 (quadrant 3) or
+ * <li> absolute angle 270 to 0 (quadrant 4)
+ * </ul><p>
+ * @param aGbrItem is the GBRITEM to fill in.
+ * @param aStart is the starting point
+ * @param aEnd is the ending point
+ * @param rel_center is the center coordinate relative to start point,
+ * given in ABSOLUTE VALUE and the sign of values x et y de rel_center
+ * must be calculated from the previously given constraint: arc only in the
+ * same quadrant.
+ * @param aClockwise true if arc must be created clockwise
+ * @param aMultiquadrant = true to create arcs upto 360 deg,
+ * false when arc is inside one quadrant
+ * @param aLayerNegative = true if the current layer is negative
+ */
+static void fillArcPOLY( GERBER_DRAW_ITEM* aGbrItem,
+ const wxPoint& aStart, const wxPoint& aEnd,
+ const wxPoint& rel_center,
+ bool aClockwise, bool aMultiquadrant,
+ bool aLayerNegative )
+{
+ /* in order to calculate arc parameters, we use fillArcGBRITEM
+ * so we muse create a dummy track and use its geometric parameters
+ */
+ static GERBER_DRAW_ITEM dummyGbrItem( NULL, NULL );
+ static const int drawlayer = 0;
+
+ aGbrItem->SetLayerPolarity( aLayerNegative );
+
+ fillArcGBRITEM( &dummyGbrItem, 0, drawlayer,
+ aStart, aEnd, rel_center, wxSize(0, 0),
+ aClockwise, aMultiquadrant, aLayerNegative );
+
+ wxPoint center;
+ center = dummyGbrItem.m_ArcCentre;
+
+ // Calculate coordinates relative to arc center;
+ wxPoint start = dummyGbrItem.m_Start - center;
+ wxPoint end = dummyGbrItem.m_End - center;
+
+ /* Calculate angle arc
+ * angles are in 0.1 deg
+ * angle is trigonometrical (counter-clockwise),
+ * and axis is the X,Y gerber coordinates
+ */
+ double start_angle = ArcTangente( start.y, start.x );
+ double end_angle = ArcTangente( end.y, end.x );
+
+ // dummyTrack has right geometric parameters, but
+ // fillArcGBRITEM calculates arc parameters for a draw function that expects
+ // start_angle < end_angle. So ensure this is the case here:
+ // Due to the fact atan2 returns angles between -180 to + 180 degrees,
+ // this is not always the case ( a modulo 360.0 degrees can be lost )
+ if( start_angle > end_angle )
+ end_angle += 3600;
+
+ double arc_angle = start_angle - end_angle;
+ // Approximate arc by 36 segments per 360 degree
+ const int increment_angle = 3600 / 36;
+ int count = std::abs( arc_angle / increment_angle );
+
+ // calculate polygon corners
+ // when arc is counter-clockwise, dummyGbrItem arc goes from end to start
+ // and we must always create a polygon from start to end.
+ wxPoint start_arc = start;
+ for( int ii = 0; ii <= count; ii++ )
+ {
+ double rot;
+ wxPoint end_arc = start;
+ if( aClockwise )
+ rot = ii * increment_angle; // rot is in 0.1 deg
+ else
+ rot = (count - ii) * increment_angle; // rot is in 0.1 deg
+
+ if( ii < count )
+ RotatePoint( &end_arc, -rot );
+ else // last point
+ end_arc = aClockwise ? end : start;
+
+ aGbrItem->m_PolyCorners.push_back( end_arc + center );
+
+ start_arc = end_arc;
+ }
+}
+
+
+/* Read the Gnn sequence and returns the value nn.
+ */
+int GERBER_IMAGE::GCodeNumber( char*& Text )
+{
+ int ii = 0;
+ char* text;
+ char line[1024];
+
+ if( Text == NULL )
+ return 0;
+ Text++;
+ text = line;
+ while( IsNumber( *Text ) )
+ {
+ *(text++) = *(Text++);
+ }
+
+ *text = 0;
+ ii = atoi( line );
+ return ii;
+}
+
+
+/* Get the sequence Dnn and returns the value nn
+ */
+int GERBER_IMAGE::DCodeNumber( char*& Text )
+{
+ int ii = 0;
+ char* text;
+ char line[1024];
+
+ if( Text == NULL )
+ return 0;
+
+ Text++;
+ text = line;
+ while( IsNumber( *Text ) )
+ *(text++) = *(Text++);
+
+ *text = 0;
+ ii = atoi( line );
+ return ii;
+}
+
+
+bool GERBER_IMAGE::Execute_G_Command( char*& text, int G_command )
+{
+// D( printf( "%22s: G_CODE<%d>\n", __func__, G_command ); )
+
+ switch( G_command )
+ {
+ case GC_PHOTO_MODE: // can starts a D03 flash command: redundant, can
+ // be safely ignored
+ break;
+
+ case GC_LINEAR_INTERPOL_1X:
+ m_Iterpolation = GERB_INTERPOL_LINEAR_1X;
+ break;
+
+ case GC_CIRCLE_NEG_INTERPOL:
+ m_Iterpolation = GERB_INTERPOL_ARC_NEG;
+ break;
+
+ case GC_CIRCLE_POS_INTERPOL:
+ m_Iterpolation = GERB_INTERPOL_ARC_POS;
+ break;
+
+ case GC_COMMENT:
+ // Skip comment, but only if the line does not start by "G04 #@! TF"
+ // which is a metadata
+ if( strncmp( text, " #@! TF", 7 ) == 0 )
+ {
+ text += 7;
+ X2_ATTRIBUTE dummy;
+ dummy.ParseAttribCmd( m_Current_File, NULL, 0, text );
+ if( dummy.IsFileFunction() )
+ {
+ delete m_FileFunction;
+ m_FileFunction = new X2_ATTRIBUTE_FILEFUNCTION( dummy );
+ }
+ }
+
+ while ( *text && (*text != '*') )
+ text++;
+ break;
+
+ case GC_LINEAR_INTERPOL_10X:
+ m_Iterpolation = GERB_INTERPOL_LINEAR_10X;
+ break;
+
+ case GC_LINEAR_INTERPOL_0P1X:
+ m_Iterpolation = GERB_INTERPOL_LINEAR_01X;
+ break;
+
+ case GC_LINEAR_INTERPOL_0P01X:
+ m_Iterpolation = GERB_INTERPOL_LINEAR_001X;
+ break;
+
+ case GC_SELECT_TOOL:
+ {
+ int D_commande = DCodeNumber( text );
+ if( D_commande < FIRST_DCODE )
+ return false;
+ if( D_commande > (TOOLS_MAX_COUNT - 1) )
+ D_commande = TOOLS_MAX_COUNT - 1;
+ m_Current_Tool = D_commande;
+ D_CODE* pt_Dcode = GetDCODE( D_commande, false );
+ if( pt_Dcode )
+ pt_Dcode->m_InUse = true;
+ break;
+ }
+
+ case GC_SPECIFY_INCHES:
+ m_GerbMetric = false; // false = Inches, true = metric
+ break;
+
+ case GC_SPECIFY_MILLIMETERS:
+ m_GerbMetric = true; // false = Inches, true = metric
+ break;
+
+ case GC_TURN_OFF_360_INTERPOL: // disable Multi cadran arc and Arc interpol
+ m_360Arc_enbl = false;
+ m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // not sure it should be done
+ break;
+
+ case GC_TURN_ON_360_INTERPOL:
+ m_360Arc_enbl = true;
+ break;
+
+ case GC_SPECIFY_ABSOLUES_COORD:
+ m_Relative = false; // false = absolute Coord, true = relative
+ // Coord
+ break;
+
+ case GC_SPECIFY_RELATIVEES_COORD:
+ m_Relative = true; // false = absolute Coord, true = relative
+ // Coord
+ break;
+
+ case GC_TURN_ON_POLY_FILL:
+ m_PolygonFillMode = true;
+ break;
+
+ case GC_TURN_OFF_POLY_FILL:
+ if( m_Exposure && m_Parent->GetGerberLayout()->m_Drawings ) // End of polygon
+ {
+ GERBER_DRAW_ITEM * gbritem = m_Parent->GetGerberLayout()->m_Drawings.GetLast();
+ StepAndRepeatItem( *gbritem );
+ }
+ m_Exposure = false;
+ m_PolygonFillMode = false;
+ m_PolygonFillModeState = 0;
+ break;
+
+ case GC_MOVE: // Non existent
+ default:
+ {
+ wxString msg;
+ msg.Printf( wxT( "G%0.2d command not handled" ), G_command );
+ ReportMessage( msg );
+ return false;
+ }
+ }
+
+
+ return true;
+}
+
+
+bool GERBER_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
+{
+ wxSize size( 15, 15 );
+
+ APERTURE_T aperture = APT_CIRCLE;
+ GERBER_DRAW_ITEM* gbritem;
+ GBR_LAYOUT* layout = m_Parent->GetGerberLayout();
+
+ int activeLayer = m_Parent->getActiveLayer();
+
+ int dcode = 0;
+ D_CODE* tool = NULL;
+ wxString msg;
+
+// D( printf( "%22s: D_CODE<%d>\n", __func__, D_commande ); )
+
+ if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command
+ {
+ if( D_commande > (TOOLS_MAX_COUNT - 1) )
+ D_commande = TOOLS_MAX_COUNT - 1;
+
+ // remember which tool is selected, nothing is done with it in this
+ // call
+ m_Current_Tool = D_commande;
+
+ D_CODE* pt_Dcode = GetDCODE( D_commande, false );
+ if( pt_Dcode )
+ pt_Dcode->m_InUse = true;
+
+ return true;
+ }
+ else // D_commande = 0..9: this is a pen command (usually D1, D2 or D3)
+ {
+ m_Last_Pen_Command = D_commande;
+ }
+
+ if( m_PolygonFillMode ) // Enter a polygon description:
+ {
+ switch( D_commande )
+ {
+ case 1: // code D01 Draw line, exposure ON
+ if( !m_Exposure )
+ {
+ m_Exposure = true;
+ gbritem = new GERBER_DRAW_ITEM( layout, this );
+ layout->m_Drawings.Append( gbritem );
+ gbritem->m_Shape = GBR_POLYGON;
+ gbritem->SetLayer( activeLayer );
+ gbritem->m_Flashed = false;
+ }
+
+ switch( m_Iterpolation )
+ {
+ case GERB_INTERPOL_ARC_NEG:
+ case GERB_INTERPOL_ARC_POS:
+ gbritem = layout->m_Drawings.GetLast();
+
+ // D( printf( "Add arc poly %d,%d to %d,%d fill %d interpol %d 360_enb %d\n",
+ // m_PreviousPos.x, m_PreviousPos.y, m_CurrentPos.x,
+ // m_CurrentPos.y, m_PolygonFillModeState,
+// m_Iterpolation, m_360Arc_enbl ); )
+ fillArcPOLY( gbritem, m_PreviousPos,
+ m_CurrentPos, m_IJPos,
+ ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? false : true,
+ m_360Arc_enbl, GetLayerParams().m_LayerNegative );
+ break;
+
+ default:
+ gbritem = layout->m_Drawings.GetLast();
+
+// D( printf( "Add poly edge %d,%d to %d,%d fill %d\n",
+// m_PreviousPos.x, m_PreviousPos.y,
+// m_CurrentPos.x, m_CurrentPos.y, m_Iterpolation ); )
+
+ gbritem->m_Start = m_PreviousPos; // m_Start is used as temporary storage
+ if( gbritem->m_PolyCorners.size() == 0 )
+ gbritem->m_PolyCorners.push_back( gbritem->m_Start );
+
+ gbritem->m_End = m_CurrentPos; // m_End is used as temporary storage
+ gbritem->m_PolyCorners.push_back( gbritem->m_End );
+ break;
+ }
+
+ m_PreviousPos = m_CurrentPos;
+ m_PolygonFillModeState = 1;
+ break;
+
+ case 2: // code D2: exposure OFF (i.e. "move to")
+ if( m_Exposure && layout->m_Drawings ) // End of polygon
+ {
+ gbritem = layout->m_Drawings.GetLast();
+ StepAndRepeatItem( *gbritem );
+ }
+ m_Exposure = false;
+ m_PreviousPos = m_CurrentPos;
+ m_PolygonFillModeState = 0;
+ break;
+
+ default:
+ return false;
+ }
+ }
+ else
+ {
+ switch( D_commande )
+ {
+ case 1: // code D01 Draw line, exposure ON
+ m_Exposure = true;
+
+ tool = GetDCODE( m_Current_Tool, false );
+ if( tool )
+ {
+ size = tool->m_Size;
+ dcode = tool->m_Num_Dcode;
+ aperture = tool->m_Shape;
+ }
+
+ switch( m_Iterpolation )
+ {
+ case GERB_INTERPOL_LINEAR_1X:
+ gbritem = new GERBER_DRAW_ITEM( layout, this );
+ layout->m_Drawings.Append( gbritem );
+
+// D( printf( "Add line %d,%d to %d,%d\n",
+// m_PreviousPos.x, m_PreviousPos.y,
+// m_CurrentPos.x, m_CurrentPos.y ); )
+ fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
+ m_CurrentPos, size, GetLayerParams().m_LayerNegative );
+ StepAndRepeatItem( *gbritem );
+ break;
+
+ case GERB_INTERPOL_LINEAR_01X:
+ case GERB_INTERPOL_LINEAR_001X:
+ case GERB_INTERPOL_LINEAR_10X:
+ wxBell();
+ break;
+
+ case GERB_INTERPOL_ARC_NEG:
+ case GERB_INTERPOL_ARC_POS:
+ gbritem = new GERBER_DRAW_ITEM( layout, this );
+ layout->m_Drawings.Append( gbritem );
+
+// D( printf( "Add arc %d,%d to %d,%d center %d, %d interpol %d 360_enb %d\n",
+// m_PreviousPos.x, m_PreviousPos.y, m_CurrentPos.x,
+// m_CurrentPos.y, m_IJPos.x,
+// m_IJPos.y, m_Iterpolation, m_360Arc_enbl ); )
+ fillArcGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
+ m_CurrentPos, m_IJPos, size,
+ ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
+ false : true, m_360Arc_enbl, GetLayerParams().m_LayerNegative );
+ StepAndRepeatItem( *gbritem );
+ break;
+
+ default:
+ msg.Printf( wxT( "RS274D: DCODE Command: interpol error (type %X)" ),
+ m_Iterpolation );
+ ReportMessage( msg );
+ break;
+ }
+
+ m_PreviousPos = m_CurrentPos;
+ break;
+
+ case 2: // code D2: exposure OFF (i.e. "move to")
+ m_Exposure = false;
+ m_PreviousPos = m_CurrentPos;
+ break;
+
+ case 3: // code D3: flash aperture
+ tool = GetDCODE( m_Current_Tool, false );
+ if( tool )
+ {
+ size = tool->m_Size;
+ dcode = tool->m_Num_Dcode;
+ aperture = tool->m_Shape;
+ }
+
+ gbritem = new GERBER_DRAW_ITEM( layout, this );
+ layout->m_Drawings.Append( gbritem );
+ fillFlashedGBRITEM( gbritem, aperture,
+ dcode, activeLayer, m_CurrentPos,
+ size, GetLayerParams().m_LayerNegative );
+ StepAndRepeatItem( *gbritem );
+ m_PreviousPos = m_CurrentPos;
+ break;
+
+ default:
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/gerbview/rs274x.cpp b/gerbview/rs274x.cpp
new file mode 100644
index 0000000..6371404
--- /dev/null
+++ b/gerbview/rs274x.cpp
@@ -0,0 +1,1064 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file rs274x.cpp
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <macros.h>
+#include <base_units.h>
+
+#include <gerbview.h>
+#include <class_GERBER.h>
+#include <class_X2_gerber_attributes.h>
+
+extern int ReadInt( char*& text, bool aSkipSeparator = true );
+extern double ReadDouble( char*& text, bool aSkipSeparator = true );
+extern bool GetEndOfBlock( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file );
+
+
+#define CODE( x, y ) ( ( (x) << 8 ) + (y) )
+
+// See rs274xrevd_e.pdf, table 1: RS-274X parameters order of entry
+// in gerber files, when a coordinate is given (like X78Y600 or I0J80):
+// Y and Y are logical coordinates
+// A and B are plotter coordiantes
+// Usually A = X, B = Y
+// But we can have A = Y, B = X and/or offset, mirror, scale;
+// Also:
+// Image is what you must plot (the entire data of the file).
+// Layer is just a set of data blocks with their parameters. An image can have more than one
+// layer so a gerber layer is not like a board layer or the graphic layers used in GerbView
+// to show a file.
+enum RS274X_PARAMETERS {
+ // Directive parameters: single usage recommended
+ // Must be at the beginning of the file
+ AXIS_SELECT = CODE( 'A', 'S' ), // Default: A=X, B=Y
+ FORMAT_STATEMENT = CODE( 'F', 'S' ), // no default: this command must exists
+ MIRROR_IMAGE = CODE( 'M', 'I' ), // Default: mo mirror
+ MODE_OF_UNITS = CODE( 'M', 'O' ), // Default: inch
+ INCH = CODE( 'I', 'N' ),
+ MILLIMETER = CODE( 'M', 'M' ),
+ OFFSET = CODE( 'O', 'F' ), // Default: A = 0, B = 0
+ SCALE_FACTOR = CODE( 'S', 'F' ), // Default: A = 1.0, B = 1.0
+
+ // Image parameters:
+ // commands used only once at the beginning of the file
+ IMAGE_JUSTIFY = CODE( 'I', 'J' ), // Default: no justification
+ IMAGE_NAME = CODE( 'I', 'N' ), // Default: void
+ IMAGE_OFFSET = CODE( 'I', 'O' ), // Default: A = 0, B = 0
+ IMAGE_POLARITY = CODE( 'I', 'P' ), // Default: Positive
+ IMAGE_ROTATION = CODE( 'I', 'R' ), // Default: 0
+ PLOTTER_FILM = CODE( 'P', 'M' ),
+
+ // Aperture parameters:
+ // Usually for the whole file
+ AP_DEFINITION = CODE( 'A', 'D' ),
+ AP_MACRO = CODE( 'A', 'M' ),
+
+ // X2 extention attribute commands
+ // Mainly are found standard attributes and user attributes
+ // standard attributes commands are:
+ // TF (file attribute)
+ // TA (aperture attribute) and TD (delete aperture attribute)
+ FILE_ATTRIBUTE = CODE( 'T', 'F' ),
+
+ // Layer specific parameters
+ // May be used singly or may be layer specfic
+ // theses parameters are at the beginning of the file or layer
+ // and reset some layer parameters (like interpolation)
+ LAYER_NAME = CODE( 'L', 'N' ), // Default: Positive
+ LAYER_POLARITY = CODE( 'L', 'P' ),
+ KNOCKOUT = CODE( 'K', 'O' ), // Default: off
+ STEP_AND_REPEAT = CODE( 'S', 'R' ), // Default: A = 1, B = 1
+ ROTATE = CODE( 'R', 'O' ), // Default: 0
+
+ // Miscellaneous parameters:
+ INCLUDE_FILE = CODE( 'I', 'F' )
+};
+
+
+/**
+ * Function ReadXCommand
+ * reads in two bytes of data and assembles them into an int with the first
+ * byte in the sequence put into the most significant part of a 16 bit value
+ * and the second byte put into the least significant part of the 16 bit value.
+ * @param text A reference to a pointer to read bytes from and to advance as
+ * they are read.
+ * @return int - with 16 bits of data in the ls bits, upper bits zeroed.
+ */
+static int ReadXCommand( char*& text )
+{
+ int result;
+
+ if( text && *text )
+ result = *text++ << 8;
+ else
+ return -1;
+
+ if( text && *text )
+ result += *text++;
+ else
+ return -1;
+
+ return result;
+}
+
+
+bool GERBER_IMAGE::ReadRS274XCommand( char buff[GERBER_BUFZ], char*& text )
+{
+ bool ok = true;
+ int code_command;
+
+ text++;
+
+ for( ; ; )
+ {
+ while( *text )
+ {
+ switch( *text )
+ {
+ case '%': // end of command
+ text++;
+ m_CommandState = CMD_IDLE;
+ goto exit; // success completion
+
+ case ' ':
+ case '\r':
+ case '\n':
+ text++;
+ break;
+
+ case '*':
+ text++;
+ break;
+
+ default:
+ code_command = ReadXCommand( text );
+ ok = ExecuteRS274XCommand( code_command, buff, text );
+ if( !ok )
+ goto exit;
+ break;
+ }
+ }
+
+ // end of current line, read another one.
+ if( fgets( buff, GERBER_BUFZ, m_Current_File ) == NULL )
+ {
+ // end of file
+ ok = false;
+ break;
+ }
+
+ text = buff;
+ }
+
+exit:
+ return ok;
+}
+
+
+bool GERBER_IMAGE::ExecuteRS274XCommand( int command,
+ char buff[GERBER_BUFZ],
+ char*& text )
+{
+ int code;
+ int seq_len; // not used, just provided
+ int seq_char;
+ bool ok = true;
+ char line[GERBER_BUFZ];
+ wxString msg;
+ double fcoord;
+ bool x_fmt_known = false;
+ bool y_fmt_known = false;
+
+ // conv_scale = scaling factor from inch to Internal Unit
+ double conv_scale = IU_PER_MILS * 1000;
+ if( m_GerbMetric )
+ conv_scale /= 25.4;
+
+// DBG( printf( "%22s: Command <%c%c>\n", __func__, (command >> 8) & 0xFF, command & 0xFF ); )
+
+ switch( command )
+ {
+ case FORMAT_STATEMENT:
+ seq_len = 2;
+
+ while( *text != '*' )
+ {
+ switch( *text )
+ {
+ case ' ':
+ text++;
+ break;
+
+ case 'L': // No Leading 0
+ m_DecimalFormat = false;
+ m_NoTrailingZeros = false;
+ text++;
+ break;
+
+ case 'T': // No trailing 0
+ m_DecimalFormat = false;
+ m_NoTrailingZeros = true;
+ text++;
+ break;
+
+ case 'A': // Absolute coord
+ m_Relative = false;
+ text++;
+ break;
+
+ case 'I': // Relative coord
+ m_Relative = true;
+ text++;
+ break;
+
+ case 'G':
+ case 'N': // Sequence code (followed by one digit: the sequence len)
+ // (sometimes found before the X,Y sequence)
+ // Obscure option
+ text++;
+ seq_char = *text++;
+ if( (seq_char >= '0') && (seq_char <= '9') )
+ seq_len = seq_char - '0';
+ break;
+
+ case 'D':
+ case 'M': // Sequence code (followed by one digit: the sequence len)
+ // (sometimes found after the X,Y sequence)
+ // Obscure option
+ code = *text++;
+ if( ( *text >= '0' ) && ( *text<= '9' ) )
+ text++; // skip the digit
+ else if( code == 'D' )
+ // Decimal format: sometimes found, but not really documented
+ m_DecimalFormat = true;
+ break;
+
+ case 'X':
+ case 'Y':
+ {
+ code = *(text++);
+ char ctmp = *(text++) - '0';
+ if( code == 'X' )
+ {
+ x_fmt_known = true;
+ // number of digits after the decimal point (0 to 7 allowed)
+ m_FmtScale.x = *text - '0';
+ m_FmtLen.x = ctmp + m_FmtScale.x;
+
+ // m_FmtScale is 0 to 7
+ // (Old Gerber specification was 0 to 6)
+ if( m_FmtScale.x < 0 )
+ m_FmtScale.x = 0;
+ if( m_FmtScale.x > 7 )
+ m_FmtScale.x = 7;
+ }
+ else
+ {
+ y_fmt_known = true;
+ m_FmtScale.y = *text - '0';
+ m_FmtLen.y = ctmp + m_FmtScale.y;
+ if( m_FmtScale.y < 0 )
+ m_FmtScale.y = 0;
+ if( m_FmtScale.y > 7 )
+ m_FmtScale.y = 7;
+ }
+ text++;
+ }
+ break;
+
+ case '*':
+ break;
+
+ default:
+ msg.Printf( wxT( "Unknown id (%c) in FS command" ),
+ *text );
+ ReportMessage( msg );
+ GetEndOfBlock( buff, text, m_Current_File );
+ ok = false;
+ break;
+ }
+ }
+ if( !x_fmt_known || !y_fmt_known )
+ ReportMessage( wxT( "RS274X: Format Statement (FS) without X or Y format" ) );
+
+ break;
+
+ case AXIS_SELECT: // command ASAXBY*% or %ASAYBX*%
+ m_SwapAxis = false;
+ if( strnicmp( text, "AYBX", 4 ) == 0 )
+ m_SwapAxis = true;
+ break;
+
+ case MIRROR_IMAGE: // command %MIA0B0*%, %MIA0B1*%, %MIA1B0*%, %MIA1B1*%
+ m_MirrorA = m_MirrorB = 0;
+ while( *text && *text != '*' )
+ {
+ switch( *text )
+ {
+ case 'A': // Mirror A axis ?
+ text++;
+ if( *text == '1' )
+ m_MirrorA = true;
+ break;
+
+ case 'B': // Mirror B axis ?
+ text++;
+ if( *text == '1' )
+ m_MirrorB = true;
+ break;
+
+ default:
+ text++;
+ break;
+ }
+ }
+ break;
+
+ case MODE_OF_UNITS:
+ code = ReadXCommand( text );
+ if( code == INCH )
+ m_GerbMetric = false;
+ else if( code == MILLIMETER )
+ m_GerbMetric = true;
+ conv_scale = m_GerbMetric ? IU_PER_MILS / 25.4 : IU_PER_MILS;
+ break;
+
+ case FILE_ATTRIBUTE: // Command %TF ...
+ m_IsX2_file = true;
+ {
+ X2_ATTRIBUTE dummy;
+ dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text );
+ if( dummy.IsFileFunction() )
+ {
+ delete m_FileFunction;
+ m_FileFunction = new X2_ATTRIBUTE_FILEFUNCTION( dummy );
+ }
+ else if( dummy.IsFileMD5() )
+ {
+ m_MD5_value = dummy.GetPrm( 1 );
+ }
+ else if( dummy.IsFilePart() )
+ {
+ m_PartString = dummy.GetPrm( 1 );
+ }
+ }
+ break;
+
+ case OFFSET: // command: OFAnnBnn (nn = float number) = layer Offset
+ m_Offset.x = m_Offset.y = 0;
+ while( *text != '*' )
+ {
+ switch( *text )
+ {
+ case 'A': // A axis offset in current unit (inch or mm)
+ text++;
+ fcoord = ReadDouble( text );
+ m_Offset.x = KiROUND( fcoord * conv_scale );
+ break;
+
+ case 'B': // B axis offset in current unit (inch or mm)
+ text++;
+ fcoord = ReadDouble( text );
+ m_Offset.y = KiROUND( fcoord * conv_scale );
+ break;
+ }
+ }
+ break;
+
+ case SCALE_FACTOR:
+ m_Scale.x = m_Scale.y = 1.0;
+ while( *text != '*' )
+ {
+ switch( *text )
+ {
+ case 'A': // A axis scale
+ text++;
+ m_Scale.x = ReadDouble( text );
+ break;
+
+ case 'B': // B axis scale
+ text++;
+ m_Scale.y = ReadDouble( text );
+ break;
+ }
+ }
+ break;
+
+ case IMAGE_OFFSET: // command: IOAnnBnn (nn = float number) = Image Offset
+ m_ImageOffset.x = m_ImageOffset.y = 0;
+ while( *text != '*' )
+ {
+ switch( *text )
+ {
+ case 'A': // A axis offset in current unit (inch or mm)
+ text++;
+ fcoord = ReadDouble( text );
+ m_ImageOffset.x = KiROUND( fcoord * conv_scale );
+ break;
+
+ case 'B': // B axis offset in current unit (inch or mm)
+ text++;
+ fcoord = ReadDouble( text );
+ m_ImageOffset.y = KiROUND( fcoord * conv_scale );
+ break;
+ }
+ }
+ break;
+
+ case IMAGE_ROTATION: // command IR0* or IR90* or IR180* or IR270*
+ if( strnicmp( text, "0*", 2 ) == 0 )
+ m_ImageRotation = 0;
+ else if( strnicmp( text, "90*", 3 ) == 0 )
+ m_ImageRotation = 90;
+ else if( strnicmp( text, "180*", 4 ) == 0 )
+ m_ImageRotation = 180;
+ else if( strnicmp( text, "270*", 4 ) == 0 )
+ m_ImageRotation = 270;
+ else
+ ReportMessage( _( "RS274X: Command \"IR\" rotation value not allowed" ) );
+ break;
+
+ case STEP_AND_REPEAT: // command SR, like %SRX3Y2I5.0J2*%
+ m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // Start a new Gerber layer
+ GetLayerParams().m_StepForRepeat.x = 0.0;
+ GetLayerParams().m_StepForRepeat.x = 0.0; // offset for Step and Repeat command
+ GetLayerParams().m_XRepeatCount = 1;
+ GetLayerParams().m_YRepeatCount = 1; // The repeat count
+ GetLayerParams().m_StepForRepeatMetric = m_GerbMetric; // the step units
+ while( *text && *text != '*' )
+ {
+ switch( *text )
+ {
+ case 'I': // X axis offset
+ text++;
+ GetLayerParams().m_StepForRepeat.x = ReadDouble( text );
+ break;
+
+ case 'J': // Y axis offset
+ text++;
+ GetLayerParams().m_StepForRepeat.y = ReadDouble( text );
+ break;
+
+ case 'X': // X axis repeat count
+ text++;
+ GetLayerParams().m_XRepeatCount = ReadInt( text );
+ break;
+
+ case 'Y': // Y axis offset
+ text++;
+ GetLayerParams().m_YRepeatCount = ReadInt( text );
+ break;
+ default:
+ text++;
+ break;
+ }
+ }
+ break;
+
+ case IMAGE_JUSTIFY: // Command IJAnBn*
+ m_ImageJustifyXCenter = false; // Image Justify Center on X axis (default = false)
+ m_ImageJustifyYCenter = false; // Image Justify Center on Y axis (default = false)
+ m_ImageJustifyOffset = wxPoint(0,0); // Image Justify Offset on XY axis (default = 0,0)
+ while( *text && *text != '*' )
+ {
+ // IJ command is (for A or B axis) AC or AL or A<coordinate>
+ switch( *text )
+ {
+ case 'A': // A axis justify
+ text++;
+ if( *text == 'C' )
+ {
+ m_ImageJustifyXCenter = true;
+ text++;
+ }
+ else if( *text == 'L' )
+ {
+ m_ImageJustifyXCenter = true;
+ text++;
+ }
+ else m_ImageJustifyOffset.x = KiROUND( ReadDouble( text ) * conv_scale);
+ break;
+
+ case 'B': // B axis justify
+ text++;
+ if( *text == 'C' )
+ {
+ m_ImageJustifyYCenter = true;
+ text++;
+ }
+ else if( *text == 'L' )
+ {
+ m_ImageJustifyYCenter = true;
+ text++;
+ }
+ else m_ImageJustifyOffset.y = KiROUND( ReadDouble( text ) * conv_scale);
+ break;
+ default:
+ text++;
+ break;
+ }
+ }
+ if( m_ImageJustifyXCenter )
+ m_ImageJustifyOffset.x = 0;
+ if( m_ImageJustifyYCenter )
+ m_ImageJustifyOffset.y = 0;
+ break;
+
+ case KNOCKOUT:
+ m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // Start a new Gerber layer
+ msg = _( "RS274X: Command KNOCKOUT ignored by GerbView" ) ;
+ ReportMessage( msg );
+ break;
+
+ case PLOTTER_FILM: // Command PF <string>
+ // This is an info about film that must be used to plot this file
+ // Has no meaning here. We just display this string
+ msg = wxT( "Plotter Film info:<br>" );
+ while( *text != '*' )
+ {
+ msg.Append( *text++ );
+ }
+ ReportMessage( msg );
+ break;
+
+ case ROTATE: // Layer rotation: command like %RO45*%
+ m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // Start a new Gerber layer
+ m_LocalRotation =ReadDouble( text ); // Store layer rotation in degrees
+ break;
+
+ case IMAGE_NAME:
+ m_ImageName.Empty();
+ while( *text != '*' )
+ {
+ m_ImageName.Append( *text++ );
+ }
+
+ break;
+
+ case LAYER_NAME:
+ m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // Start a new Gerber layer
+ GetLayerParams( ).m_LayerName.Empty();
+ while( *text != '*' )
+ {
+ GetLayerParams( ).m_LayerName.Append( *text++ );
+ }
+
+ break;
+
+ case IMAGE_POLARITY:
+ if( strnicmp( text, "NEG", 3 ) == 0 )
+ m_ImageNegative = true;
+ else
+ m_ImageNegative = false;
+ DBG( printf( "%22s: IMAGE_POLARITY m_ImageNegative=%s\n", __func__,
+ m_ImageNegative ? "true" : "false" ); )
+ break;
+
+ case LAYER_POLARITY:
+ if( *text == 'C' )
+ GetLayerParams().m_LayerNegative = true;
+
+ else
+ GetLayerParams().m_LayerNegative = false;
+ DBG( printf( "%22s: LAYER_POLARITY m_LayerNegative=%s\n", __func__,
+ GetLayerParams().m_LayerNegative ? "true" : "false" ); )
+ break;
+
+ case INCLUDE_FILE:
+ if( m_FilesPtr >= INCLUDE_FILES_CNT_MAX )
+ {
+ ok = false;
+ ReportMessage( _( "Too many include files!!" ) );
+ break;
+ }
+
+ strncpy( line, text, sizeof(line)-1 );
+ line[sizeof(line)-1] = '\0';
+
+ strtok( line, "*%%\n\r" );
+ m_FilesList[m_FilesPtr] = m_Current_File;
+
+ m_Current_File = fopen( line, "rt" );
+ if( m_Current_File == 0 )
+ {
+ msg.Printf( wxT( "include file <%s> not found." ), line );
+ ReportMessage( msg );
+ ok = false;
+ m_Current_File = m_FilesList[m_FilesPtr];
+ break;
+ }
+ m_FilesPtr++;
+ break;
+
+ case AP_MACRO: // lines like %AMMYMACRO*
+ // 5,1,8,0,0,1.08239X$1,22.5*
+ // %
+ /*ok = */ReadApertureMacro( buff, text, m_Current_File );
+ break;
+
+ case AP_DEFINITION:
+
+ /* input example: %ADD30R,0.081800X0.101500*%
+ * Aperture definition has 4 options: C, R, O, P
+ * (Circle, Rect, Oval, regular Polygon)
+ * and shapes can have a hole (round or rectangular).
+ * All optional parameters values start by X
+ * at this point, text points to 2nd 'D'
+ */
+ if( *text++ != 'D' )
+ {
+ ok = false;
+ break;
+ }
+
+ m_Has_DCode = true;
+
+ code = ReadInt( text );
+
+ D_CODE* dcode;
+ dcode = GetDCODE( code );
+ if( dcode == NULL )
+ break;
+
+ // at this point, text points to character after the ADD<num>,
+ // i.e. R in example above. If text[0] is one of the usual
+ // apertures: (C,R,O,P), there is a comma after it.
+ if( text[1] == ',' )
+ {
+ char stdAperture = *text;
+
+ text += 2; // skip "C," for example
+
+ dcode->m_Size.x = KiROUND( ReadDouble( text ) * conv_scale );
+ dcode->m_Size.y = dcode->m_Size.x;
+
+ switch( stdAperture ) // Aperture desceiption has optional parameters. Read them
+ {
+ case 'C': // Circle
+ dcode->m_Shape = APT_CIRCLE;
+ while( *text == ' ' )
+ text++;
+
+ if( *text == 'X' )
+ {
+ text++;
+ dcode->m_Drill.x = dcode->m_Drill.y =
+ KiROUND( ReadDouble( text ) * conv_scale );
+ dcode->m_DrillShape = APT_DEF_ROUND_HOLE;
+ }
+
+ while( *text == ' ' )
+ text++;
+
+ if( *text == 'X' )
+ {
+ text++;
+ dcode->m_Drill.y =
+ KiROUND( ReadDouble( text ) * conv_scale );
+
+ dcode->m_DrillShape = APT_DEF_RECT_HOLE;
+ }
+ dcode->m_Defined = true;
+ break;
+
+ case 'O': // oval
+ case 'R': // rect
+ dcode->m_Shape = (stdAperture == 'O') ? APT_OVAL : APT_RECT;
+
+ while( *text == ' ' )
+ text++;
+
+ if( *text == 'X' )
+ {
+ text++;
+ dcode->m_Size.y =
+ KiROUND( ReadDouble( text ) * conv_scale );
+ }
+
+ while( *text == ' ' )
+ text++;
+
+ if( *text == 'X' )
+ {
+ text++;
+ dcode->m_Drill.x = KiROUND( ReadDouble( text ) * conv_scale );
+ dcode->m_Drill.y = dcode->m_Drill.x;
+ dcode->m_DrillShape = APT_DEF_ROUND_HOLE;
+ }
+
+ while( *text == ' ' )
+ text++;
+
+ if( *text == 'X' )
+ {
+ text++;
+ dcode->m_Drill.y =
+ KiROUND( ReadDouble( text ) * conv_scale );
+ dcode->m_DrillShape = APT_DEF_RECT_HOLE;
+ }
+ dcode->m_Defined = true;
+ break;
+
+ case 'P':
+
+ /* Regular polygon: a command line like %ADD12P,0.040X10X25X0.025X0.025X0.0150*%
+ * params are: <diameter>, X<edge count>, X<Rotation>, X<X hole dim>, X<Y hole dim>
+ */
+ dcode->m_Shape = APT_POLYGON;
+ while( *text == ' ' )
+ text++;
+
+ if( *text == 'X' )
+ {
+ text++;
+ dcode->m_EdgesCount = ReadInt( text );
+ }
+
+ while( *text == ' ' )
+ text++;
+
+ if( *text == 'X' )
+ {
+ text++;
+ dcode->m_Rotation = ReadDouble( text );
+ }
+
+ while( *text == ' ' )
+ text++;
+
+ if( *text == 'X' )
+ {
+ text++;
+ dcode->m_Drill.x = KiROUND( ReadDouble( text ) * conv_scale );
+ dcode->m_Drill.y = dcode->m_Drill.x =
+ dcode->m_DrillShape = APT_DEF_ROUND_HOLE;
+ }
+
+ while( *text == ' ' )
+ text++;
+
+ if( *text == 'X' )
+ {
+ text++;
+ dcode->m_Drill.y = KiROUND( ReadDouble( text ) * conv_scale );
+ dcode->m_DrillShape = APT_DEF_RECT_HOLE;
+ }
+ dcode->m_Defined = true;
+ break;
+ }
+ }
+ else // text[0] starts an aperture macro name
+ {
+ APERTURE_MACRO am_lookup;
+
+ while( *text && *text != '*' && *text != ',' )
+ am_lookup.name.Append( *text++ );
+
+ // When an aperture definition is like %AMLINE2* 22,1,$1,$2,0,0,-45*
+ // the ADDxx<MACRO_NAME> command has parameters, like %ADD14LINE2,0.8X0.5*%
+ if( *text == ',' )
+ { // Read aperture macro parameters and store them
+ text++; // text points the first parameter
+ while( *text && *text != '*' )
+ {
+ double param = ReadDouble( text );
+ dcode->AppendParam( param );
+ while( isspace( *text ) ) text++;
+ if( *text == 'X' )
+ ++text;
+ }
+ }
+
+ // lookup the aperture macro here.
+ APERTURE_MACRO* pam = FindApertureMacro( am_lookup );
+ if( !pam )
+ {
+ msg.Printf( wxT( "RS274X: aperture macro %s not found\n" ),
+ TO_UTF8( am_lookup.name ) );
+ ReportMessage( msg );
+ ok = false;
+ break;
+ }
+
+ dcode->m_Shape = APT_MACRO;
+ dcode->SetMacro( (APERTURE_MACRO*) pam );
+ }
+ break;
+
+ default:
+ ok = false;
+ break;
+ }
+
+ (void) seq_len; // quiet g++, or delete the unused variable.
+
+ ok = GetEndOfBlock( buff, text, m_Current_File );
+
+ return ok;
+}
+
+
+bool GetEndOfBlock( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file )
+{
+ for( ; ; )
+ {
+ while( (text < buff + GERBER_BUFZ) && *text )
+ {
+ if( *text == '*' )
+ return true;
+
+ if( *text == '%' )
+ return true;
+
+ text++;
+ }
+
+ if( fgets( buff, GERBER_BUFZ, gerber_file ) == NULL )
+ break;
+
+ text = buff;
+ }
+
+ return false;
+}
+
+
+/**
+ * Function GetNextLine
+ * test for an end of line
+ * if an end of line is found:
+ * read a new line
+ * @param aBuff = buffer (size = GERBER_BUFZ) to fill with a new line
+ * @param aText = pointer to the last useful char in aBuff
+ * on return: points the beginning of the next line.
+ * @param aFile = the opened GERBER file to read
+ * @return a pointer to the beginning of the next line or NULL if end of file
+*/
+static char* GetNextLine( char aBuff[GERBER_BUFZ], char* aText, FILE* aFile )
+{
+ for( ; ; )
+ {
+ switch (*aText )
+ {
+ case ' ': // skip blanks
+ case '\n':
+ case '\r': // Skip line terminators
+ ++aText;
+ break;
+
+ case 0: // End of text found in aBuff: Read a new string
+ if( fgets( aBuff, GERBER_BUFZ, aFile ) == NULL )
+ return NULL;
+ aText = aBuff;
+ return aText;
+
+ default:
+ return aText;
+ }
+ }
+ return aText;
+}
+
+
+bool GERBER_IMAGE::ReadApertureMacro( char buff[GERBER_BUFZ],
+ char*& text,
+ FILE* gerber_file )
+{
+ wxString msg;
+ APERTURE_MACRO am;
+
+ // read macro name
+ while( *text )
+ {
+ if( *text == '*' )
+ {
+ ++text;
+ break;
+ }
+
+ am.name.Append( *text++ );
+ }
+
+ // Read aperture macro parameters
+ for( ; ; )
+ {
+ if( *text == '*' )
+ ++text;
+
+ text = GetNextLine( buff, text, gerber_file ); // Get next line
+ if( text == NULL ) // End of File
+ return false;
+
+ // text points the beginning of a new line.
+
+ // Test for the last line in aperture macro lis:
+ // last line is % or *% sometime found.
+ if( *text == '*' )
+ ++text;
+ if( *text == '%' )
+ break; // exit with text still pointing at %
+
+ int paramCount = 0;
+ int primitive_type = AMP_UNKNOWN;
+ // Test for a valid symbol at the beginning of a description:
+ // it can be: a parameter declaration like $1=$2/4
+ // or a digit (macro primitive selection)
+ // all other symbols are illegal.
+ if( *text == '$' ) // local parameter declaration, inside the aperture macro
+ {
+ am.m_localparamStack.push_back( AM_PARAM() );
+ AM_PARAM& param = am.m_localparamStack.back();
+ text = GetNextLine( buff, text, gerber_file );
+ if( text == NULL) // End of File
+ return false;
+ param.ReadParam( text );
+ continue;
+ }
+ else if( !isdigit(*text) ) // Ill. symbol
+ {
+ msg.Printf( wxT( "RS274X: Aperture Macro \"%s\": ill. symbol, line: \"%s\"" ),
+ GetChars( am.name ), GetChars( FROM_UTF8( buff ) ) );
+ ReportMessage( msg );
+ primitive_type = AMP_COMMENT;
+ }
+ else
+ primitive_type = ReadInt( text );
+
+ switch( primitive_type )
+ {
+ case AMP_COMMENT: // lines starting by 0 are a comment
+ paramCount = 0;
+ // Skip comment
+ while( *text && (*text != '*') )
+ text++;
+ break;
+
+ case AMP_CIRCLE:
+ paramCount = 4;
+ break;
+
+ case AMP_LINE2:
+ case AMP_LINE20:
+ paramCount = 7;
+ break;
+
+ case AMP_LINE_CENTER:
+ case AMP_LINE_LOWER_LEFT:
+ paramCount = 6;
+ break;
+
+ case AMP_EOF:
+ paramCount = 0;
+ break;
+
+ case AMP_OUTLINE:
+ paramCount = 4;
+ break;
+
+ case AMP_POLYGON:
+ paramCount = 6;
+ break;
+
+ case AMP_MOIRE:
+ paramCount = 9;
+ break;
+
+ case AMP_THERMAL:
+ paramCount = 6;
+ break;
+
+ default:
+ // @todo, there needs to be a way of reporting the line number
+ msg.Printf( wxT( "RS274X: Aperture Macro \"%s\": Invalid primitive id code %d, line: \"%s\"" ),
+ GetChars( am.name ), primitive_type, GetChars( FROM_UTF8( buff ) ) );
+ ReportMessage( msg );
+ return false;
+ }
+
+ AM_PRIMITIVE prim( m_GerbMetric );
+ prim.primitive_id = (AM_PRIMITIVE_ID) primitive_type;
+ int i;
+
+ for( i = 0; i < paramCount && *text && *text != '*'; ++i )
+ {
+ prim.params.push_back( AM_PARAM() );
+
+ AM_PARAM& param = prim.params.back();
+
+ text = GetNextLine( buff, text, gerber_file );
+
+ if( text == NULL) // End of File
+ return false;
+
+ param.ReadParam( text );
+ }
+
+ if( i < paramCount )
+ {
+ // maybe some day we can throw an exception and track a line number
+ msg.Printf( wxT( "RS274X: read macro descr type %d: read %d parameters, insufficient parameters\n" ),
+ prim.primitive_id, i );
+ ReportMessage( msg );
+
+ }
+ // there are more parameters to read if this is an AMP_OUTLINE
+ if( prim.primitive_id == AMP_OUTLINE )
+ {
+ // so far we have read [0]:exposure, [1]:#points, [2]:X start, [3]: Y start
+ // Now read all the points, plus trailing rotation in degrees.
+
+ // params[1] is a count of polygon points, so it must be given
+ // in advance, i.e. be immediate.
+ wxASSERT( prim.params[1].IsImmediate() );
+
+ paramCount = (int) prim.params[1].GetValue( 0 ) * 2 + 1;
+
+ for( int i = 0; i < paramCount && *text != '*'; ++i )
+ {
+ prim.params.push_back( AM_PARAM() );
+
+ AM_PARAM& param = prim.params.back();
+
+ text = GetNextLine( buff, text, gerber_file );
+
+ if( text == NULL ) // End of File
+ return false;
+
+ param.ReadParam( text );
+ }
+ }
+
+ am.primitives.push_back( prim );
+ }
+
+ m_aperture_macros.insert( am );
+
+ return true;
+}
+
diff --git a/gerbview/select_layers_to_pcb.cpp b/gerbview/select_layers_to_pcb.cpp
new file mode 100644
index 0000000..4fa8938
--- /dev/null
+++ b/gerbview/select_layers_to_pcb.cpp
@@ -0,0 +1,428 @@
+/**
+ * @file select_layers_to_pcb.cpp
+ * @brief Dialog to choose equivalence between gerber layers and pcb layers
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <gerbview_id.h>
+#include <class_GERBER.h>
+
+#include <select_layers_to_pcb.h>
+
+// Imported function
+extern const wxString GetPCBDefaultLayerName( LAYER_NUM aLayerNumber );
+
+enum swap_layer_id {
+ ID_LAYERS_MAP_DIALOG = ID_GERBER_END_LIST,
+ ID_BUTTON_0,
+ ID_TEXT_0 = ID_BUTTON_0 + GERBER_DRAWLAYERS_COUNT
+};
+
+
+/*
+ * This dialog shows the gerber files loaded, and allows user to choose:
+ * what gerber file and what board layer are used
+ * the number of copper layers
+ */
+
+int LAYERS_MAP_DIALOG::m_exportBoardCopperLayersCount = 2;
+
+
+BEGIN_EVENT_TABLE( LAYERS_MAP_DIALOG, LAYERS_MAP_DIALOG_BASE )
+ EVT_COMMAND_RANGE( ID_BUTTON_0, ID_BUTTON_0 + GERBER_DRAWLAYERS_COUNT-1,
+ wxEVT_COMMAND_BUTTON_CLICKED,
+ LAYERS_MAP_DIALOG::OnSelectLayer )
+END_EVENT_TABLE()
+
+
+LAYERS_MAP_DIALOG::LAYERS_MAP_DIALOG( GERBVIEW_FRAME* parent ) :
+ LAYERS_MAP_DIALOG_BASE( parent )
+{
+ m_Parent = parent;
+ initDialog();
+
+ // Resize the dialog
+ Layout();
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+
+void LAYERS_MAP_DIALOG::initDialog()
+{
+ wxStaticText* label;
+ wxStaticText* text;
+ int item_ID;
+ wxString msg;
+ wxSize goodSize;
+
+ m_flexRightColumnBoxSizer = NULL;
+
+ // Experimentation has shown that buttons in the Windows version can be 20
+ // pixels wide and 20 pixels high, but that they need to be 26 pixels wide
+ // and 26 pixels high in the Linux version. (And although the dimensions
+ // of those buttons could be set to 26 pixels wide and 26 pixels high in
+ // both of those versions, that would result in a dialog box which would
+ // be excessively high in the Windows version.)
+#ifdef __WINDOWS__
+ int w = 20;
+ int h = 20;
+#else
+ int w = 26;
+ int h = 26;
+#endif
+
+ // As currently implemented, the dimensions of the buttons in the Mac
+ // version are also 26 pixels wide and 26 pixels high. If appropriate,
+ // the above code should be modified as required in the event that those
+ // buttons should be some other size in that version.
+ for( int ii = 0; ii < GERBER_DRAWLAYERS_COUNT; ++ii )
+ {
+ // Specify the default value for each member of these arrays.
+ m_buttonTable[ii] = -1;
+ m_layersLookUpTable[ii] = UNSELECTED_LAYER;
+ }
+
+ // Ensure we have:
+ // at least 2 copper layers and less than max pacb copper layers count
+ // and even layers count because a board *must* have even layers count
+ normalizeBrdLayersCount();
+
+ int idx = ( m_exportBoardCopperLayersCount / 2 ) - 1;
+ m_comboCopperLayersCount->SetSelection( idx );
+
+ LAYER_NUM pcb_layer_num = 0;
+ m_gerberActiveLayersCount = 0;
+ for( int ii = 0; ii < GERBER_DRAWLAYERS_COUNT; ++ii )
+ {
+ if( g_GERBER_List.GetGbrImage( ii ) == NULL )
+ break;
+
+ if( (pcb_layer_num == m_exportBoardCopperLayersCount - 1)
+ && (m_exportBoardCopperLayersCount > 1) )
+ pcb_layer_num = F_Cu;
+
+ m_buttonTable[m_gerberActiveLayersCount] = ii;
+ m_layersLookUpTable[ii] = pcb_layer_num;
+ m_gerberActiveLayersCount++;
+ ++pcb_layer_num;
+ }
+
+ if( m_gerberActiveLayersCount <= GERBER_DRAWLAYERS_COUNT/2 ) // Only one list is enough
+ {
+ m_staticlineSep->Hide();
+ }
+ else // Add the second list of gerber files
+ {
+ m_flexRightColumnBoxSizer = new wxFlexGridSizer( 16, 4, 0, 0 );
+ for( int ii = 0; ii < 4; ii++ )
+ m_flexRightColumnBoxSizer->AddGrowableCol( ii );
+ m_flexRightColumnBoxSizer->SetFlexibleDirection( wxBOTH );
+ m_flexRightColumnBoxSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+ sbSizerLayersTable->Add( m_flexRightColumnBoxSizer, 1, wxEXPAND, 5 );
+ }
+
+ wxFlexGridSizer* flexColumnBoxSizer = m_flexLeftColumnBoxSizer;
+ for( int ii = 0; ii < m_gerberActiveLayersCount; ii++ )
+ {
+ // Each Gerber layer has an associated static text string (to
+ // identify that layer), a button (for invoking a child dialog
+ // box to change which Pcbnew layer that the Gerber layer is
+ // mapped to), and a second static text string (to depict which
+ // Pcbnew layer that the Gerber layer has been mapped to). Each
+ // of those items are placed into the left hand column, middle
+ // column, and right hand column (respectively) of the Flexgrid
+ // sizer, and the color of the second text string is set to
+ // fuchsia or blue (to respectively indicate whether the Gerber
+ // layer has been mapped to a Pcbnew layer or is not being
+ // exported at all). (Experimentation has shown that if a text
+ // control is used to depict which Pcbnew layer that each Gerber
+ // layer is mapped to (instead of a static text string), then
+ // those controls do not behave in a fully satisfactory manner
+ // in the Linux version. Even when the read-only attribute is
+ // specified for all of those controls, they can still be selected
+ // when the arrow keys or Tab key is used to step through all of
+ // the controls within the dialog box, and directives to set the
+ // foreground color of the text of each such control to blue (to
+ // indicate that the text is of a read-only nature) are disregarded.
+ // Specify a FlexGrid sizer with an appropriate number of rows
+ // and three columns. If nb_items < 16, then the number of rows
+ // is nb_items; otherwise, the number of rows is 16 (with two
+ // separate columns of controls being used if nb_items > 16).
+
+ if( ii == GERBER_DRAWLAYERS_COUNT/2 )
+ flexColumnBoxSizer = m_flexRightColumnBoxSizer;
+
+ // Provide a text string to identify the Gerber layer
+ msg.Printf( _( "Layer %d" ), m_buttonTable[ii] + 1 );
+
+ label = new wxStaticText( this, wxID_STATIC, msg, wxDefaultPosition,
+ wxDefaultSize, wxALIGN_RIGHT );
+ flexColumnBoxSizer->Add( label, 0,
+ wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL |
+ wxRIGHT | wxLEFT, 5 );
+
+ /* Add file name and extension without path. */
+ wxFileName fn( g_GERBER_List.GetGbrImage( ii )->m_FileName );
+ label = new wxStaticText( this, wxID_STATIC, fn.GetFullName(),
+ wxDefaultPosition, wxDefaultSize );
+ flexColumnBoxSizer->Add( label, 0,
+ wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL |
+ wxRIGHT | wxLEFT, 5 );
+
+ // Provide a button for this layer (which will invoke a child dialog box)
+ item_ID = ID_BUTTON_0 + ii;
+ wxButton * Button = new wxButton( this, item_ID, wxT( "..." ),
+ wxDefaultPosition, wxSize( w, h ), 0 );
+
+ flexColumnBoxSizer->Add( Button, 0,
+ wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL );
+
+ // Provide another text string to specify which Pcbnew layer that this
+ // Gerber layer is initially mapped to, and set the initial text to
+ // specify the appropriate Pcbnew layer, and set the foreground color
+ // of the text to fuchsia (to indicate that the layer is being exported).
+ item_ID = ID_TEXT_0 + ii;
+
+ // When the first of these text strings is being added, determine what
+ // size is necessary to to be able to display any possible string
+ // without it being truncated. Then specify that size as the minimum
+ // size for all of these text strings. (If this minimum size is not
+ // determined in this fashion, then it is possible for the display of
+ // one or more of these strings to be truncated after different Pcbnew
+ // layers are selected.)
+ if( ii == 0 )
+ {
+ msg = _( "Do not export" );
+ text = new wxStaticText( this, item_ID, msg, wxDefaultPosition,
+ wxDefaultSize, 0 );
+ goodSize = text->GetSize();
+
+ for( LAYER_NUM jj = 0; jj < GERBER_DRAWLAYERS_COUNT; ++jj )
+ {
+ text->SetLabel( GetPCBDefaultLayerName( jj ) );
+ if( goodSize.x < text->GetSize().x )
+ goodSize.x = text->GetSize().x;
+ }
+
+ msg = GetPCBDefaultLayerName( m_layersLookUpTable[m_buttonTable[ii]] );
+ text->SetLabel( msg );
+ }
+ else
+ {
+ msg = GetPCBDefaultLayerName( m_layersLookUpTable[m_buttonTable[ii]] );
+ text = new wxStaticText( this, item_ID, msg, wxDefaultPosition,
+ wxDefaultSize, 0 );
+ }
+ text->SetMinSize( goodSize );
+ flexColumnBoxSizer->Add( text, 1,
+ wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT,
+ 5 );
+
+ m_layersList[ii] = text;
+ }
+}
+
+/* Ensure m_exportBoardCopperLayersCount = 2 to BOARD_COPPER_LAYERS_MAX_COUNT
+ * and it is an even value because Boards have always an even layer count
+ */
+void LAYERS_MAP_DIALOG::normalizeBrdLayersCount()
+{
+ if( ( m_exportBoardCopperLayersCount & 1 ) )
+ m_exportBoardCopperLayersCount++;
+
+ if( m_exportBoardCopperLayersCount > GERBER_DRAWLAYERS_COUNT )
+ m_exportBoardCopperLayersCount = GERBER_DRAWLAYERS_COUNT;
+
+ if( m_exportBoardCopperLayersCount < 2 )
+ m_exportBoardCopperLayersCount = 2;
+
+}
+
+/*
+ * Called when user change the current board copper layers count
+ */
+void LAYERS_MAP_DIALOG::OnBrdLayersCountSelection( wxCommandEvent& event )
+{
+ int id = event.GetSelection();
+ m_exportBoardCopperLayersCount = (id+1) * 2;
+}
+
+/*
+ * reset pcb layers selection to the default value
+ */
+void LAYERS_MAP_DIALOG::OnResetClick( wxCommandEvent& event )
+{
+ wxString msg;
+ int ii;
+ LAYER_NUM layer;
+ for( ii = 0, layer = 0; ii < m_gerberActiveLayersCount; ii++, ++layer )
+ {
+ if( (layer == m_exportBoardCopperLayersCount - 1)
+ && (m_exportBoardCopperLayersCount > 1) )
+ layer = F_Cu;
+ m_layersLookUpTable[ii] = layer;
+ msg = GetPCBDefaultLayerName( layer );
+ m_layersList[ii]->SetLabel( msg );
+ m_layersList[ii]->SetForegroundColour( wxNullColour );
+ m_buttonTable[ii] = ii;
+ }
+}
+
+
+/* Stores the current layers selection in config
+ */
+void LAYERS_MAP_DIALOG::OnStoreSetup( wxCommandEvent& event )
+{
+ wxConfigBase* config = Kiface().KifaceSettings();
+ config->Write( wxT("BrdLayersCount"), m_exportBoardCopperLayersCount );
+
+ wxString key;
+ for( int ii = 0; ii < GERBER_DRAWLAYERS_COUNT; ++ii )
+ {
+ key.Printf( wxT("GbrLyr%dToPcb"), ii );
+ config->Write( key, m_layersLookUpTable[ii] );
+ }
+}
+
+void LAYERS_MAP_DIALOG::OnGetSetup( wxCommandEvent& event )
+{
+ wxConfigBase* config = Kiface().KifaceSettings();
+
+ config->Read( wxT("BrdLayersCount"), &m_exportBoardCopperLayersCount );
+ normalizeBrdLayersCount();
+
+ int idx = ( m_exportBoardCopperLayersCount / 2 ) - 1;
+ m_comboCopperLayersCount->SetSelection( idx );
+
+ wxString key;
+ for( int ii = 0; ii < GERBER_DRAWLAYERS_COUNT; ++ii )
+ {
+ key.Printf( wxT("GbrLyr%dToPcb"), ii );
+ int ilayer;
+ config->Read( key, &ilayer);
+ m_layersLookUpTable[ii] = ilayer;
+ }
+
+ for( int ii = 0; ii < m_gerberActiveLayersCount; ii++ )
+ {
+ LAYER_NUM layer = m_layersLookUpTable[ii];
+ if( layer == UNSELECTED_LAYER )
+ {
+ m_layersList[ii]->SetLabel( _( "Do not export" ) );
+ m_layersList[ii]->SetForegroundColour( *wxBLUE );
+ }
+ else
+ {
+ m_layersList[ii]->SetLabel( GetPCBDefaultLayerName( layer ) );
+ m_layersList[ii]->SetForegroundColour( wxColour( 255, 0, 128 ) );
+ }
+ }
+}
+
+void LAYERS_MAP_DIALOG::OnSelectLayer( wxCommandEvent& event )
+{
+ int ii;
+
+ ii = event.GetId() - ID_BUTTON_0;
+
+ if( (ii < 0) || (ii >= GERBER_DRAWLAYERS_COUNT) )
+ {
+ wxFAIL_MSG( wxT("Bad layer id") );
+ return;
+ }
+
+ LAYER_NUM jj = m_layersLookUpTable[m_buttonTable[ii]];
+
+ if( jj != UNSELECTED_LAYER && !IsValidLayer( jj ) )
+ jj = B_Cu; // (Defaults to "Copper" layer.)
+
+ jj = m_Parent->SelectPCBLayer( jj, m_exportBoardCopperLayersCount, true );
+
+ if( jj != UNSELECTED_LAYER && !IsValidLayer( jj ) )
+ return;
+
+ if( jj != m_layersLookUpTable[m_buttonTable[ii]] )
+ {
+ m_layersLookUpTable[m_buttonTable[ii]] = jj;
+
+ if( jj == UNSELECTED_LAYER )
+ {
+ m_layersList[ii]->SetLabel( _( "Do not export" ) );
+
+ // Change the text color to blue (to highlight
+ // that this layer is *not* being exported)
+ m_layersList[ii]->SetForegroundColour( *wxBLUE );
+ }
+ else
+ {
+ m_layersList[ii]->SetLabel( GetPCBDefaultLayerName( jj ) );
+
+ // Change the text color to fuchsia (to highlight
+ // that this layer *is* being exported)
+ m_layersList[ii]->SetForegroundColour( wxColour( 255, 0, 128 ) );
+ }
+ }
+}
+
+
+void LAYERS_MAP_DIALOG::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+void LAYERS_MAP_DIALOG::OnOkClick( wxCommandEvent& event )
+{
+ /* Make some test about copper layers:
+ * Board must have enough copper layers to handle selected internal layers
+ */
+ normalizeBrdLayersCount();
+
+ int inner_layer_max = 0;
+ for( int ii = 0; ii < GERBER_DRAWLAYERS_COUNT; ++ii )
+ {
+ if( m_layersLookUpTable[ii] < F_Cu )
+ {
+ if( m_layersLookUpTable[ii ] > inner_layer_max )
+ inner_layer_max = m_layersLookUpTable[ii];
+ }
+ }
+
+ // inner_layer_max must be less than (or equal to) the number of
+ // internal copper layers
+ // internal copper layers = m_exportBoardCopperLayersCount-2
+ if( inner_layer_max > m_exportBoardCopperLayersCount-2 )
+ {
+ wxMessageBox(
+ _("The exported board has not enough copper layers to handle selected inner layers") );
+ return;
+ }
+ EndModal( wxID_OK );
+}
diff --git a/gerbview/select_layers_to_pcb.h b/gerbview/select_layers_to_pcb.h
new file mode 100644
index 0000000..e9a6eda
--- /dev/null
+++ b/gerbview/select_layers_to_pcb.h
@@ -0,0 +1,72 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file select_layers_to_pcb.h
+ */
+
+#ifndef _SELECT_LAYERS_TO_PCB_H_
+#define _SELECT_LAYERS_TO_PCB_H_
+
+#include <dialogs/dialog_layers_select_to_pcb_base.h>
+
+/*
+ * This dialog shows the gerber files loaded, and allows user to choose
+ * equivalence between gerber layers and pcb layers
+ */
+class LAYERS_MAP_DIALOG : public LAYERS_MAP_DIALOG_BASE
+{
+private:
+ GERBVIEW_FRAME* m_Parent;
+ int m_gerberActiveLayersCount; // Number of initialized gerber layers
+ static int m_exportBoardCopperLayersCount;
+ wxFlexGridSizer* m_flexRightColumnBoxSizer; // An extra wxFlexGridSizer used
+ // when we have more than 16 gerber files loaded
+ LAYER_NUM m_layersLookUpTable[GERBER_DRAWLAYERS_COUNT]; // Indexes Gerber layers to PCB file layers
+ // the last value in table is the number of copper layers
+ int m_buttonTable[int(GERBER_DRAWLAYERS_COUNT)+1]; // Indexes buttons to Gerber layers
+ wxStaticText* m_layersList[int(GERBER_DRAWLAYERS_COUNT)+1]; // Indexes text strings to buttons
+
+public: LAYERS_MAP_DIALOG( GERBVIEW_FRAME* parent );
+ ~LAYERS_MAP_DIALOG() {};
+
+ LAYER_NUM * GetLayersLookUpTable() { return m_layersLookUpTable; }
+ static int GetCopperLayersCount() { return m_exportBoardCopperLayersCount; }
+
+private:
+ void initDialog();
+ void normalizeBrdLayersCount();
+ void OnBrdLayersCountSelection( wxCommandEvent& event );
+ void OnSelectLayer( wxCommandEvent& event );
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+
+ void OnStoreSetup( wxCommandEvent& event );
+ void OnGetSetup( wxCommandEvent& event );
+ void OnResetClick( wxCommandEvent& event );
+
+ DECLARE_EVENT_TABLE()
+};
+
+#endif // _SELECT_LAYERS_TO_PCB_H_
diff --git a/gerbview/toolbars_gerber.cpp b/gerbview/toolbars_gerber.cpp
new file mode 100644
index 0000000..9858655
--- /dev/null
+++ b/gerbview/toolbars_gerber.cpp
@@ -0,0 +1,313 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file toolbars_gerber.cpp
+ * @brief Build tool bars
+ */
+
+#include <fctsys.h>
+
+#include <common.h>
+#include <macros.h>
+#include <gerbview.h>
+#include <gerbview_frame.h>
+#include <bitmaps.h>
+#include <gerbview_id.h>
+#include <hotkeys.h>
+#include <class_GERBER.h>
+#include <class_gbr_layer_box_selector.h>
+#include <class_DCodeSelectionbox.h>
+#include <dialog_helpers.h>
+
+void GERBVIEW_FRAME::ReCreateHToolbar( void )
+{
+ int ii;
+ wxString msg;
+
+ if( m_mainToolBar != NULL )
+ return;
+
+ m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
+
+ // Set up toolbar
+ m_mainToolBar->AddTool( ID_GERBVIEW_ERASE_ALL, wxEmptyString,
+ KiBitmap( gerbview_clear_layers_xpm ),
+ _( "Erase all layers" ) );
+
+ m_mainToolBar->AddTool( wxID_FILE, wxEmptyString, KiBitmap( gerber_file_xpm ),
+ _( "Load a new Gerber file on the current layer. Previous data will be deleted" ) );
+
+ m_mainToolBar->AddTool( ID_GERBVIEW_LOAD_DRILL_FILE, wxEmptyString,
+ KiBitmap( gerbview_drill_file_xpm ),
+ _( "Load an excellon drill file on the current layer. Previous data will be deleted" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_GERBVIEW_SET_PAGE_BORDER, wxEmptyString, KiBitmap( sheetset_xpm ),
+ _( "Show/hide frame reference and select paper size for printing" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( wxID_PRINT, wxEmptyString, KiBitmap( print_button_xpm ),
+ _( "Print layers" ) );
+
+ m_mainToolBar->AddSeparator();
+ msg = AddHotkeyName( _( "Zoom in" ), GerbviewHokeysDescr, HK_ZOOM_IN, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_IN, wxEmptyString, KiBitmap( zoom_in_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Zoom out" ), GerbviewHokeysDescr, HK_ZOOM_OUT, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_OUT, wxEmptyString, KiBitmap( zoom_out_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Redraw view" ), GerbviewHokeysDescr, HK_ZOOM_REDRAW, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_REDRAW, wxEmptyString, KiBitmap( zoom_redraw_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Zoom auto" ), GerbviewHokeysDescr, HK_ZOOM_AUTO, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ), msg );
+
+ m_mainToolBar->AddSeparator();
+
+ m_SelLayerBox = new GBR_LAYER_BOX_SELECTOR( m_mainToolBar,
+ ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER,
+ wxDefaultPosition, wxSize( 150, -1 ), 0,NULL);
+ m_SelLayerBox->Resync();
+
+ m_mainToolBar->AddControl( m_SelLayerBox );
+
+ m_mainToolBar->AddSeparator();
+
+ m_DCodesList.Alloc(TOOLS_MAX_COUNT+1);
+ m_DCodesList.Add( _( "No tool" ) );
+
+ for( ii = FIRST_DCODE; ii < TOOLS_MAX_COUNT; ii++ )
+ {
+ msg = _( "Tool " );
+ msg << ii;
+ m_DCodesList.Add( msg );
+ }
+
+ m_DCodeSelector = new DCODE_SELECTION_BOX( m_mainToolBar,
+ ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE,
+ wxDefaultPosition, wxSize( 150, -1 ),
+ m_DCodesList );
+ m_mainToolBar->AddControl( m_DCodeSelector );
+
+ m_TextInfo = new wxTextCtrl( m_mainToolBar, wxID_ANY, wxEmptyString, wxDefaultPosition,
+ wxSize(150,-1), wxTE_READONLY );
+ m_mainToolBar->AddControl( m_TextInfo );
+
+ // after adding the buttons to the toolbar, must call Realize() to reflect the changes
+ m_mainToolBar->Realize();
+}
+
+
+void GERBVIEW_FRAME::ReCreateVToolbar( void )
+{
+ if( m_drawToolBar )
+ return;
+
+ m_drawToolBar = new wxAuiToolBar( this, ID_V_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
+
+ // Set up toolbar
+ m_drawToolBar->AddTool( ID_NO_TOOL_SELECTED, wxEmptyString, KiBitmap( cursor_xpm ) );
+ m_drawToolBar->AddSeparator();
+
+ m_drawToolBar->Realize();
+}
+
+
+void GERBVIEW_FRAME::ReCreateOptToolbar( void )
+{
+ if( m_optionsToolBar )
+ return;
+
+ // creation of tool bar options
+ m_optionsToolBar = new wxAuiToolBar( this, ID_OPT_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GRID, wxEmptyString, KiBitmap( grid_xpm ),
+ _( "Turn grid off" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_POLAR_COORD, wxEmptyString,
+ KiBitmap( polar_coord_xpm ),
+ _( "Turn polar coordinate on" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_INCH, wxEmptyString,
+ KiBitmap( unit_inch_xpm ),
+ _( "Set units to inches" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_MM, wxEmptyString,
+ KiBitmap( unit_mm_xpm ),
+ _( "Set units to millimeters" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_CURSOR, wxEmptyString,
+ KiBitmap( cursor_shape_xpm ),
+ _( "Change cursor shape" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH, wxEmptyString,
+ KiBitmap( pad_sketch_xpm ),
+ _( "Show spots in sketch mode" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_LINES_SKETCH, wxEmptyString,
+ KiBitmap( showtrack_xpm ),
+ _( "Show lines in sketch mode" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH, wxEmptyString,
+ KiBitmap( opt_show_polygon_xpm ),
+ _( "Show polygons in sketch mode" ),
+ wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_NEGATIVE_ITEMS, wxEmptyString,
+ KiBitmap( gerbview_show_negative_objects_xpm ),
+ _( "Show negatives objects in ghost color" ),
+ wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_DCODES, wxEmptyString,
+ KiBitmap( show_dcodenumber_xpm ),
+ _( "Show dcode number" ), wxITEM_CHECK );
+
+ // tools to select draw mode in GerbView
+ m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_0, wxEmptyString,
+ KiBitmap( gbr_select_mode0_xpm ),
+ _( "Show layers in raw mode \
+(could have problems with negative items when more than one gerber file is shown)" ),
+ wxITEM_CHECK );
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_1, wxEmptyString,
+ KiBitmap( gbr_select_mode1_xpm ),
+ _( "Show layers in stacked mode \
+(show negative items without artifacts, sometimes slow)" ),
+ wxITEM_CHECK );
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GBR_MODE_2, wxEmptyString,
+ KiBitmap( gbr_select_mode2_xpm ),
+ _( "Show layers in transparency mode \
+(show negative items without artifacts, sometimes slow)" ),
+ wxITEM_CHECK );
+
+ // Tools to show/hide toolbars:
+ m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR,
+ wxEmptyString,
+ KiBitmap( layers_manager_xpm ),
+ _( "Show/hide the layers manager toolbar" ),
+ wxITEM_CHECK );
+
+
+ m_optionsToolBar->Realize();
+}
+
+
+void GERBVIEW_FRAME::OnUpdateDrawMode( wxUpdateUIEvent& aEvent )
+{
+ switch( aEvent.GetId() )
+ {
+ case ID_TB_OPTIONS_SHOW_GBR_MODE_0:
+ aEvent.Check( GetDisplayMode() == 0 );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_GBR_MODE_1:
+ aEvent.Check( GetDisplayMode() == 1 );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_GBR_MODE_2:
+ aEvent.Check( GetDisplayMode() == 2 );
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void GERBVIEW_FRAME::OnUpdateCoordType( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( m_DisplayOptions.m_DisplayPolarCood );
+}
+
+void GERBVIEW_FRAME::OnUpdateFlashedItemsDrawMode( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( !m_DisplayOptions.m_DisplayFlashedItemsFill );
+}
+
+
+void GERBVIEW_FRAME::OnUpdateLinesDrawMode( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( !m_DisplayOptions.m_DisplayLinesFill );
+}
+
+
+void GERBVIEW_FRAME::OnUpdatePolygonsDrawMode( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( !m_DisplayOptions.m_DisplayPolygonsFill );
+}
+
+
+void GERBVIEW_FRAME::OnUpdateShowDCodes( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( IsElementVisible( DCODES_VISIBLE ) );
+}
+
+
+void GERBVIEW_FRAME::OnUpdateShowNegativeItems( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( IsElementVisible( NEGATIVE_OBJECTS_VISIBLE ) );
+}
+
+
+void GERBVIEW_FRAME::OnUpdateShowLayerManager( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( m_show_layer_manager_tools );
+
+ if( m_optionsToolBar )
+ {
+ if( m_show_layer_manager_tools )
+ m_optionsToolBar->SetToolShortHelp( aEvent.GetId(), _("Hide layers manager" ) );
+ else
+ m_optionsToolBar->SetToolShortHelp( aEvent.GetId(), _("Show layers manager" ) );
+ }
+}
+
+
+void GERBVIEW_FRAME::OnUpdateSelectDCode( wxUpdateUIEvent& aEvent )
+{
+ int layer = getActiveLayer();
+ GERBER_IMAGE* gerber = g_GERBER_List.GetGbrImage( layer );
+ int selected = ( gerber ) ? gerber->m_Selected_Tool : 0;
+
+ if( m_DCodeSelector && m_DCodeSelector->GetSelectedDCodeId() != selected )
+ m_DCodeSelector->SetDCodeSelection( selected );
+
+ aEvent.Enable( gerber != NULL );
+}
+
+
+void GERBVIEW_FRAME::OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent )
+{
+ if( m_SelLayerBox && (m_SelLayerBox->GetSelection() != getActiveLayer()) )
+ {
+ m_SelLayerBox->SetSelection( getActiveLayer() );
+ }
+}
diff --git a/license_for_documentation.txt b/license_for_documentation.txt
new file mode 100644
index 0000000..950da0f
--- /dev/null
+++ b/license_for_documentation.txt
@@ -0,0 +1,61 @@
+ KiCad Free Documentation Licence
+ ================================
+
+ Copyright (c) jean-pierre Charras
+ Copyright (C) KiCad Developers
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this licence document, but changing it is not allowed.
+
+ KICAD FREE DOCUMENTATION LICENCE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 1. Permission is granted to make and distribute verbatim copies of this
+ manual or piece of documentation provided any copyright notice and this
+ permission notice are preserved on all copies.
+
+ 2. Permission is granted to process this file or document through a
+ document processing system and, at your option and the option of any third
+ party, print the results, provided a printed document carries a copying
+ permission notice identical to this one.
+
+ 3. Permission is granted to copy and distribute modified versions of this
+ manual or piece of documentation under the conditions for verbatim
+ copying, provided also that any sections describing licensing conditions
+ for this manual, such as, in particular, the GNU General Public Licence,
+ the GNU Library General Public Licence, and any wxWindows Licence are
+ included exactly as in the original, and provided that the entire
+ resulting derived work is distributed under the terms of a permission
+ notice identical to this one.
+
+ 4. Permission is granted to copy and distribute translations of this
+ manual or piece of documentation into another language, under the above
+ conditions for modified versions, except that sections related to
+ licensing, including this paragraph, may also be included in translations
+ approved by the copyright holders of the respective licence documents in
+ addition to the original French or English.
+
+ WARRANTY DISCLAIMER
+
+ 5. BECAUSE THIS MANUAL OR PIECE OF DOCUMENTATION IS LICENSED FREE OF CHARGE,
+ THERE IS NO WARRANTY FOR IT, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+ EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
+ PARTIES PROVIDE THIS MANUAL OR PIECE OF DOCUMENTATION "AS IS" WITHOUT
+ WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF
+ THE MANUAL OR PIECE OF DOCUMENTATION IS WITH YOU. SHOULD THE MANUAL OR
+ PIECE OF DOCUMENTATION PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+ NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 6. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
+ ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+ REDISTRIBUTE THE MANUAL OR PIECE OF DOCUMENTATION AS PERMITTED ABOVE, BE
+ LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ MANUAL OR PIECE OF DOCUMENTATION (INCLUDING BUT NOT LIMITED TO LOSS OF
+ DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+ PARTIES OR A FAILURE OF A PROGRAM BASED ON THE MANUAL OR PIECE OF
+ DOCUMENTATION TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
+ OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt
new file mode 100644
index 0000000..acffe80
--- /dev/null
+++ b/pcbnew/CMakeLists.txt
@@ -0,0 +1,746 @@
+# the map generation creates on Windows/gcc a lot of useless warnings
+# so disable it on windows
+if( WIN32 AND NOT CMAKE_CROSSCOMPILING )
+ set( MAKE_LINK_MAPS false )
+else()
+ set( MAKE_LINK_MAPS true )
+endif()
+
+add_definitions( -DPCBNEW )
+add_subdirectory(router)
+
+# psnrouter depends on make_lexer outputs in common (bug # 1285878 )
+add_dependencies( pnsrouter pcbcommon )
+
+
+if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
+ file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/scripting )
+ find_package( SWIG REQUIRED )
+ include( ${SWIG_USE_FILE} )
+
+ # Infrequently needed headers go at end of search paths, append to INC_AFTER
+ set( INC_AFTER ${INC_AFTER} ${CMAKE_CURRENT_SOURCE_DIR}/scripting )
+
+ #message( STATUS "pcbnew INC_AFTER:${INC_AFTER}" )
+endif()
+
+
+if( BUILD_GITHUB_PLUGIN )
+ set( GITHUB_3DLIBRARIES_WIZARD
+ dialogs/wizard_3DShape_Libs_downloader_base.cpp
+ dialogs/wizard_3DShape_Libs_downloader.cpp )
+endif()
+
+include_directories( BEFORE ${INC_BEFORE} )
+include_directories(
+ ./dialogs
+ ./autorouter
+ ../3d-viewer
+ ../common
+ ../polygon
+ ../common/dialogs
+ ./exporters
+ ../lib_dxf
+ ./import_dxf
+ ../utils/idftools
+ ${INC_AFTER}
+ )
+
+set( PCBNEW_DIALOGS
+ dialogs/dialog_block_options_base.cpp
+ dialogs/dialog_cleaning_options_base.cpp
+ dialogs/dialog_cleaning_options.cpp
+ dialogs/dialog_copper_zones.cpp
+ dialogs/dialog_copper_zones_base.cpp
+ dialogs/dialog_create_array.cpp
+ dialogs/dialog_create_array_base.cpp
+ dialogs/dialog_design_rules.cpp
+ dialogs/dialog_design_rules_base.cpp
+ dialogs/dialog_dimension_editor_base.cpp
+ dialogs/dialog_display_options.cpp
+ dialogs/dialog_display_options_base.cpp
+ dialogs/dialog_drc_base.cpp
+ dialogs/dialog_drc.cpp
+ dialogs/dialog_edit_module_for_BoardEditor.cpp
+ dialogs/dialog_edit_module_for_BoardEditor_base.cpp
+ dialogs/dialog_edit_module_for_Modedit_base.cpp
+ dialogs/dialog_edit_module_for_Modedit.cpp
+ dialogs/dialog_edit_module_text.cpp
+ dialogs/dialog_edit_module_text_base.cpp
+ dialogs/dialog_enum_pads.cpp
+ dialogs/dialog_enum_pads_base.cpp
+ dialogs/dialog_exchange_modules_base.cpp
+ dialogs/dialog_export_idf.cpp
+ dialogs/dialog_export_idf_base.cpp
+ dialogs/dialog_export_vrml_base.cpp
+ dialogs/dialog_export_vrml.cpp
+ dialogs/dialog_find_base.cpp
+ dialogs/dialog_find.cpp
+ dialogs/dialog_fp_lib_table_base.cpp
+ dialogs/dialog_fp_lib_table.cpp
+ dialogs/dialog_fp_plugin_options_base.cpp
+ dialogs/dialog_fp_plugin_options.cpp
+ dialogs/dialog_freeroute_exchange.cpp
+ dialogs/dialog_freeroute_exchange_base.cpp
+ dialogs/dialog_gendrill.cpp
+ dialogs/dialog_gendrill_base.cpp
+ dialogs/dialog_gen_module_position_file_base.cpp
+ dialogs/dialog_general_options.cpp
+ dialogs/dialog_general_options_BoardEditor_base.cpp
+ dialogs/dialog_global_edit_tracks_and_vias.cpp
+ dialogs/dialog_global_edit_tracks_and_vias_base.cpp
+ dialogs/dialog_global_modules_fields_edition.cpp
+ dialogs/dialog_global_modules_fields_edition_base.cpp
+ dialogs/dialog_global_pads_edition_base.cpp
+ dialogs/dialog_graphic_items_options.cpp
+ dialogs/dialog_graphic_items_options_base.cpp
+ dialogs/dialog_graphic_item_properties.cpp
+ dialogs/dialog_graphic_item_properties_base.cpp
+ dialogs/dialog_graphic_item_properties_for_Modedit.cpp
+ dialogs/dialog_global_deletion.cpp
+ dialogs/dialog_global_deletion_base.cpp
+ dialogs/dialog_keepout_area_properties.cpp
+ dialogs/dialog_keepout_area_properties_base.cpp
+ dialogs/dialog_layer_selection_base.cpp
+ dialogs/dialog_layers_setup.cpp
+ dialogs/dialog_layers_setup_base.cpp
+ dialogs/dialog_modedit_options.cpp
+ dialogs/dialog_modedit_options_base.cpp
+ dialogs/dialog_netlist.cpp
+ dialogs/dialog_netlist_fbp.cpp
+ dialogs/dialog_pcb_text_properties.cpp
+ dialogs/dialog_pcb_text_properties_base.cpp
+ dialogs/dialog_pns_settings.cpp
+ dialogs/dialog_pns_settings_base.cpp
+ dialogs/dialog_move_exact.cpp
+ dialogs/dialog_move_exact_base.cpp
+ dialogs/dialog_pns_diff_pair_dimensions.cpp
+ dialogs/dialog_pns_diff_pair_dimensions_base.cpp
+ dialogs/dialog_pns_length_tuning_settings.cpp
+ dialogs/dialog_pns_length_tuning_settings_base.cpp
+ dialogs/dialog_non_copper_zones_properties.cpp
+ dialogs/dialog_non_copper_zones_properties_base.cpp
+ dialogs/dialog_pad_properties.cpp
+ dialogs/dialog_pad_properties_base.cpp
+ dialogs/dialog_plot_base.cpp
+ dialogs/dialog_plot.cpp
+ dialogs/dialog_print_for_modedit.cpp
+ dialogs/dialog_print_for_modedit_base.cpp
+ dialogs/dialog_print_using_printer.cpp
+ dialogs/dialog_print_using_printer_base.cpp
+ dialogs/dialog_orient_footprints.cpp
+ dialogs/dialog_orient_footprints_base.cpp
+ dialogs/dialog_mask_clearance.cpp
+ dialogs/dialog_mask_clearance_base.cpp
+ dialogs/dialog_SVG_print.cpp
+ dialogs/dialog_SVG_print_base.cpp
+ dialogs/dialog_select_pretty_lib.cpp
+ dialogs/dialog_select_pretty_lib_base.cpp
+ dialogs/dialog_set_grid.cpp
+ dialogs/dialog_set_grid_base.cpp
+ dialogs/dialog_target_properties_base.cpp
+ dialogs/dialog_track_via_properties.cpp
+ dialogs/dialog_track_via_properties_base.cpp
+ dialogs/dialog_track_via_size.cpp
+ dialogs/dialog_track_via_size_base.cpp
+ footprint_wizard.cpp
+ footprint_wizard_frame.cpp
+ dialogs/dialog_footprint_wizard_list_base.cpp
+ dialogs/dialog_footprint_wizard_list.cpp
+ dialogs/wizard_add_fplib_base.cpp
+ dialogs/wizard_add_fplib.cpp
+ ${GITHUB_3DLIBRARIES_WIZARD}
+ )
+
+set( PCBNEW_IMPORT_DXF
+ import_dxf/dialog_dxf_import_base.cpp
+ import_dxf/dialog_dxf_import.cpp
+ import_dxf/dxf2brd_items.cpp
+ )
+
+set( PCBNEW_EXPORTERS
+ exporters/export_d356.cpp
+ exporters/export_gencad.cpp
+ exporters/export_idf.cpp
+ exporters/export_vrml.cpp
+ exporters/gen_drill_report_files.cpp
+ exporters/gen_modules_placefile.cpp
+ exporters/gendrill_Excellon_writer.cpp
+ )
+
+set( PCBNEW_AUTOROUTER_SRCS
+ autorouter/rect_placement/rect_placement.cpp
+ autorouter/move_and_route_event_functions.cpp
+ autorouter/auto_place_footprints.cpp
+ autorouter/autorout.cpp
+ autorouter/routing_matrix.cpp
+ autorouter/dist.cpp
+ autorouter/queue.cpp
+ autorouter/spread_footprints.cpp
+ autorouter/solve.cpp
+ autorouter/graphpcb.cpp
+ autorouter/work.cpp
+ )
+
+set( PCBNEW_CLASS_SRCS
+ tool_modview.cpp
+ modview_frame.cpp
+ pcbframe.cpp
+ pcb_base_edit_frame.cpp
+ append_board_to_current.cpp
+ attribut.cpp
+ board_items_to_polygon_shape_transform.cpp
+ board_undo_redo.cpp
+ block.cpp
+ block_module_editor.cpp
+ build_BOM_from_board.cpp
+ class_pcb_layer_widget.cpp
+ class_pcb_layer_box_selector.cpp
+ clean.cpp
+ connect.cpp
+ controle.cpp
+ dimension.cpp
+ cross-probing.cpp
+ deltrack.cpp
+ ${PCBNEW_DIALOGS}
+ ${PCBNEW_IMPORT_DXF}
+ ${PCBNEW_EXPORTERS}
+ dragsegm.cpp
+ drc.cpp
+ drc_clearance_test_functions.cpp
+ drc_marker_functions.cpp
+ edgemod.cpp
+ edit.cpp
+ editedge.cpp
+ editmod.cpp
+ editrack.cpp
+ editrack-part2.cpp
+ edit_pcb_text.cpp
+ edit_track_width.cpp
+ edtxtmod.cpp
+ event_handlers_tracks_vias_sizes.cpp
+ files.cpp
+ globaleditpad.cpp
+ highlight.cpp
+ hotkeys.cpp
+ hotkeys_board_editor.cpp
+ hotkeys_module_editor.cpp
+ initpcb.cpp
+ layer_widget.cpp
+ librairi.cpp
+ loadcmp.cpp
+ magnetic_tracks_functions.cpp
+ menubar_modedit.cpp
+ menubar_pcbframe.cpp
+ minimun_spanning_tree.cpp
+ modedit.cpp
+ modedit_onclick.cpp
+ modeditoptions.cpp
+ modedit_undo_redo.cpp
+ moduleframe.cpp
+ modules.cpp
+ move-drag_pads.cpp
+ move_or_drag_track.cpp
+ muonde.cpp
+ muwave_command.cpp
+ netlist.cpp
+ onleftclick.cpp
+ onrightclick.cpp
+ pad_edition_functions.cpp
+ pcbnew_config.cpp
+ pcbplot.cpp
+ pcb_draw_panel_gal.cpp
+ plot_board_layers.cpp
+ plot_brditems_plotter.cpp
+ print_board_functions.cpp
+ printout_controler.cpp
+ ratsnest.cpp
+ ratsnest_viewitem.cpp
+ specctra_import.cpp
+ swap_layers.cpp
+ target_edit.cpp
+ tool_modedit.cpp
+ tool_onrightclick.cpp
+ tool_pcb.cpp
+ toolbars_update_user_interface.cpp
+ tracepcb.cpp
+ tr_modif.cpp
+ xchgmod.cpp
+ zones_convert_brd_items_to_polygons_with_Boost.cpp
+ zones_convert_to_polygons_aux_functions.cpp
+ zones_by_polygon.cpp
+ zones_by_polygon_fill_functions.cpp
+ zone_filling_algorithm.cpp
+ zones_functions_for_undo_redo.cpp
+ zones_polygons_insulated_copper_islands.cpp
+ zones_polygons_test_connections.cpp
+ zones_test_and_combine_areas.cpp
+ class_footprint_wizard.cpp
+
+ tools/selection_tool.cpp
+ tools/selection_area.cpp
+ tools/selection_conditions.cpp
+ tools/conditional_menu.cpp
+ tools/bright_box.cpp
+ tools/edit_points.cpp
+ tools/edit_constraints.cpp
+ tools/point_editor.cpp
+ tools/drawing_tool.cpp
+ tools/edit_tool.cpp
+ tools/pcbnew_control.cpp
+ tools/pcb_editor_control.cpp
+ tools/module_tools.cpp
+ tools/placement_tool.cpp
+ tools/common_actions.cpp
+ tools/grid_helper.cpp
+ tools/picker_tool.cpp
+ tools/tools_common.cpp
+
+ tools/grid_menu.cpp
+ tools/zoom_menu.cpp
+ tools/size_menu.cpp
+ )
+
+set( PCBNEW_SRCS ${PCBNEW_AUTOROUTER_SRCS} ${PCBNEW_CLASS_SRCS} ${PCBNEW_DIALOGS} )
+
+
+# extra sources from common
+set( PCBNEW_COMMON_SRCS
+ ../common/dialogs/dialog_page_settings.cpp
+ ../common/base_units.cpp
+ )
+
+set( PCBNEW_SCRIPTING_DIALOGS
+ dialogs/dialog_scripting_base.cpp
+ dialogs/dialog_scripting.cpp
+ )
+
+set( PCBNEW_SCRIPTING_PYTHON_HELPERS
+ ../scripting/wx_python_helpers.cpp
+ ../scripting/python_scripting.cpp
+ scripting/pcbnew_scripting_helpers.cpp
+ scripting/pcbnew_footprint_wizards.cpp
+ )
+
+if( KICAD_SCRIPTING )
+ set( PCBNEW_SCRIPTING_SRCS
+ ${PCBNEW_SCRIPTING_DIALOGS}
+ pcbnew_wrap.cxx
+ ${PCBNEW_SCRIPTING_PYTHON_HELPERS}
+ )
+endif()
+
+
+if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
+
+ set( SWIG_FLAGS
+ -I${CMAKE_CURRENT_SOURCE_DIR}/../..
+ -I${CMAKE_CURRENT_SOURCE_DIR}
+ -I${CMAKE_CURRENT_SOURCE_DIR}/../include
+ -I${CMAKE_CURRENT_SOURCE_DIR}/../scripting
+ )
+
+ if( DEBUG )
+ set( SWIG_FLAGS ${SWIG_FLAGS} -DDEBUG )
+ endif()
+
+ # collect CFLAGS , and pass them to swig later
+
+ get_directory_property( DirDefs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS )
+ foreach( d ${DirDefs} )
+ set( SWIG_FLAGS ${SWIG_FLAGS} -D${d} )
+ endforeach()
+
+endif()
+
+
+if( KICAD_SCRIPTING )
+
+ set( SWIG_OPTS -python -c++ -outdir ${CMAKE_CURRENT_BINARY_DIR} ${SWIG_FLAGS} )
+
+ if( EXISTS ${CMAKE_CURRENT_BINARY_DIR}/doxygen-xml )
+ set( SWIG_OPTS ${SWIG_OPTS} -DENABLE_DOCSTRINGS_FROM_DOXYGEN )
+ set( SWIG_OPTS ${SWIG_OPTS} -I${CMAKE_CURRENT_BINARY_DIR}/docstrings )
+ endif()
+
+ add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
+
+ DEPENDS pcbcommon
+ DEPENDS plotcontroller.h
+ DEPENDS exporters/gendrill_Excellon_writer.h
+ DEPENDS scripting/pcbnew.i
+ DEPENDS scripting/board.i
+ DEPENDS scripting/board_item.i
+ DEPENDS scripting/module.i
+ DEPENDS scripting/plugins.i
+ DEPENDS scripting/units.i
+ DEPENDS ../scripting/dlist.i
+ DEPENDS ../scripting/kicad.i
+ DEPENDS ../scripting/wx.i
+ DEPENDS ../scripting/kicadplugins.i
+
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/docstrings
+ COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/docstrings/docstrings.i # this makes docstrings.i available if it doesn't exist
+
+ COMMAND ${SWIG_EXECUTABLE} ${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx scripting/pcbnew.i
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripting/build_tools/fix_swig_imports.py ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+
+endif()
+
+
+if( BUILD_GITHUB_PLUGIN )
+ set( GITHUB_PLUGIN_LIBRARIES github_plugin )
+endif()
+
+if( UNIX AND NOT APPLE )
+ list( APPEND PCBNEW_EXTRA_LIBS rt )
+endif()
+
+
+if( KICAD_SCRIPTING_MODULES )
+
+ #message( "building pcbnew scripting" )
+
+ set( CMAKE_SWIG_FLAGS ${SWIG_FLAGS} )
+ set_source_files_properties( scripting/pcbnew.i PROPERTIES CPLUSPLUS ON )
+
+ swig_add_module( pcbnew
+ python
+ scripting/pcbnew.i
+ ${PCBNEW_SCRIPTING_PYTHON_HELPERS}
+ pcbnew.cpp
+ ${PCBNEW_SRCS}
+ ${PCBNEW_COMMON_SRCS}
+ )
+
+ swig_link_libraries( pcbnew
+ 3d-viewer
+ pcbcommon
+ pnsrouter
+ common
+ pcad2kicadpcb
+ lib_dxf
+ idf3
+ polygon
+ bitmaps
+ gal
+ ${wxWidgets_LIBRARIES}
+ ${GITHUB_PLUGIN_LIBRARIES}
+ ${GDI_PLUS_LIBRARIES}
+ ${PYTHON_LIBRARIES}
+ ${PCBNEW_EXTRA_LIBS}
+ ${Boost_LIBRARIES} # must follow GITHUB
+ )
+
+ if( MAKE_LINK_MAPS )
+ set_target_properties( _pcbnew PROPERTIES
+ LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=pcbnew.so.map"
+ )
+ endif()
+
+ if( ${OPENMP_FOUND} )
+ set_property( TARGET _pcbnew APPEND_STRING
+ PROPERTY LINK_FLAGS " ${OpenMP_CXX_FLAGS}"
+ )
+ endif()
+endif()
+
+
+###
+# Doxygen python documentation
+###
+
+find_package( Doxygen )
+if( DOXYGEN_FOUND )
+ if( KICAD_SCRIPTING )
+
+ # create XML files from doxygen parsing
+ add_custom_target( doxygen-python-xml
+ ${CMAKE_COMMAND} -E remove_directory doxygen-python-xml
+ COMMAND SOURCES_DIR=${CMAKE_SOURCE_DIR} ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile_xml
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS Doxyfile_xml
+ COMMENT "building doxygen docs into directory doxygen-python/html"
+ )
+
+ # create .i files from XML doxygen parsing, docstrings.i will include all of them
+ add_custom_target( xml-to-docstrings
+ COMMAND ${CMAKE_COMMAND} -E remove_directory docstrings
+ COMMAND ${CMAKE_COMMAND} -E make_directory docstrings
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripting/build_tools/extract_docstrings.py pcbnew.py doxygen-xml/xml docstrings
+ COMMAND ${CMAKE_COMMAND} -E remove pcbnew.py # force removal so it will be recreated later with the new docstrings
+ COMMENT "building docstring files"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS pcbnew.py
+ DEPENDS doxygen-python-xml
+ )
+
+ # create doxygen-python html
+ add_custom_target( doxygen-python
+ ${CMAKE_COMMAND} -E remove_directory doxygen-python
+ COMMAND PYTHON_SOURCES_TO_DOC=${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile_python
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS Doxyfile_python
+ DEPENDS xml-to-docstrings
+ DEPENDS pcbnew.py
+ COMMENT "building doxygen docs into directory doxygen-python/html"
+ )
+ endif()
+else()
+ message( STATUS "WARNING: Doxygen not found - doxygen-docs (Source Docs) target not created" )
+endif()
+
+
+if( MINGW )
+ # PCBNEW_RESOURCES variable is set by the macro.
+ mingw_resource_compiler( pcbnew )
+else()
+ set( PCBNEW_RESOURCES pcbnew.rc )
+endif()
+
+
+if( APPLE )
+ # setup bundle
+ set( PCBNEW_RESOURCES pcbnew.icns pcbnew_doc.icns )
+ set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/pcbnew.icns" PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+ set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/pcbnew_doc.icns" PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+ set( MACOSX_BUNDLE_ICON_FILE pcbnew.icns )
+ set( MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-pcb.kicad )
+ set( MACOSX_BUNDLE_NAME pcbnew )
+endif()
+
+
+# Create a C++ compilable string initializer containing html text into a *.h file:
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help_html.h
+ COMMAND ${CMAKE_COMMAND}
+ -DinputFile=${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help.html
+ -DoutputFile=${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help_html.h
+ -P ${CMAKE_MODULE_PATH}/Html2C.cmake
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help.html
+ COMMENT "creating ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help_html.h
+ from ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help.html"
+ )
+
+set_source_files_properties( dialogs/dialog_freeroute_exchange.cpp PROPERTIES
+ OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help_html.h
+ )
+
+add_subdirectory( pcad2kicadpcb_plugin )
+
+if( BUILD_GITHUB_PLUGIN )
+ add_subdirectory( github )
+ add_dependencies( github_plugin lib-dependencies )
+endif()
+
+
+# a very small program launcher for pcbnew_kiface
+add_executable( pcbnew WIN32 MACOSX_BUNDLE
+ ../common/single_top.cpp
+ ${PCBNEW_RESOURCES}
+ )
+set_source_files_properties( ../common/single_top.cpp pcbnew.cpp PROPERTIES
+ COMPILE_DEFINITIONS "TOP_FRAME=FRAME_PCB;PGM_DATA_FILE_EXT=\"kicad_pcb\";BUILD_KIWAY_DLL"
+ )
+target_link_libraries( pcbnew
+ #singletop # replaces common, giving us restrictive control and link warnings.
+ # There's way too much crap coming in from common yet.
+ common
+ bitmaps
+ ${wxWidgets_LIBRARIES}
+ )
+
+if( MAKE_LINK_MAPS )
+ set_target_properties( pcbnew PROPERTIES
+ LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=pcbnew.map" )
+endif()
+
+# the main pcbnew program, in DSO form.
+add_library( pcbnew_kiface MODULE
+ pcbnew.cpp
+ ${PCBNEW_SRCS}
+ ${PCBNEW_COMMON_SRCS}
+ ${PCBNEW_SCRIPTING_SRCS}
+ )
+set_target_properties( pcbnew_kiface PROPERTIES
+ # Decorate OUTPUT_NAME with PREFIX and SUFFIX, creating something like
+ # _pcbnew.so, _pcbnew.dll, or _pcbnew.kiface
+ OUTPUT_NAME pcbnew
+ PREFIX ${KIFACE_PREFIX}
+ SUFFIX ${KIFACE_SUFFIX}
+ )
+
+if( ${OPENMP_FOUND} )
+ set_target_properties( pcbnew_kiface PROPERTIES
+ COMPILE_FLAGS ${OpenMP_CXX_FLAGS}
+ )
+endif()
+
+target_link_libraries( pcbnew_kiface
+ 3d-viewer
+ pcbcommon
+ pnsrouter
+ common
+ pcad2kicadpcb
+ polygon
+ bitmaps
+ gal
+ lib_dxf
+ idf3
+ ${wxWidgets_LIBRARIES}
+ ${GITHUB_PLUGIN_LIBRARIES}
+ ${GDI_PLUS_LIBRARIES}
+ ${PYTHON_LIBRARIES}
+ ${Boost_LIBRARIES} # must follow GITHUB
+ ${PCBNEW_EXTRA_LIBS} # -lrt must follow Boost
+ ${OPENMP_LIBRARIES}
+ )
+set_source_files_properties( pcbnew.cpp PROPERTIES
+ # The KIFACE is in pcbnew.cpp, export it:
+ COMPILE_DEFINITIONS "BUILD_KIWAY_DLL;COMPILING_DLL"
+ )
+
+if( MAKE_LINK_MAPS )
+ set_target_properties( pcbnew_kiface PROPERTIES
+ LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=_pcbnew.kiface.map"
+ )
+ set_target_properties( pcbnew PROPERTIES
+ LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=pcbnew.map"
+ )
+endif()
+
+# if building pcbnew, then also build pcbnew_kiface if out of date.
+add_dependencies( pcbnew pcbnew_kiface )
+
+# these 2 binaries are a matched set, keep them together:
+if( APPLE )
+ set_target_properties( pcbnew PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
+ )
+
+ # puts binaries into the *.app bundle while linking
+ set_target_properties( pcbnew_kiface PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_KIFACE_DIR}
+ )
+ # put individual bundle outside of main bundle as a first step
+ # will be pulled into the main bundle when creating main bundle
+ install( TARGETS pcbnew
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+ install( CODE "
+ # override default embedded path settings
+ ${OSX_BUNDLE_OVERRIDE_PATHS}
+
+ # do all the work
+ include( BundleUtilities )
+ fixup_bundle( ${KICAD_BIN}/pcbnew.app/Contents/MacOS/pcbnew
+ \"\"
+ \"\"
+ )
+ " COMPONENT Runtime
+ )
+else()
+ install( TARGETS pcbnew
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+ install( TARGETS pcbnew_kiface
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+endif()
+
+add_dependencies( pcbnew lib-dependencies )
+
+
+if( KICAD_SCRIPTING )
+ if( NOT APPLE )
+ install( FILES ${CMAKE_BINARY_DIR}/pcbnew/pcbnew.py DESTINATION ${PYTHON_DEST} )
+ else()
+ # put into bundle at build time, it is relocated at install
+ add_custom_target( ScriptingPcbnewPyCopy ALL
+ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_BINARY_DIR}/pcbnew/pcbnew.py" "${PYTHON_DEST}/"
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
+ COMMENT "Copying pcbnew.py into ${PYTHON_DEST}"
+ )
+ add_dependencies( ScriptingPcbnewPyCopy ScriptingWxpythonCopy )
+ endif()
+
+ # scripting plugins
+ install( DIRECTORY ${PROJECT_SOURCE_DIR}/pcbnew/scripting/plugins/
+ DESTINATION ${KICAD_DATA}/scripting/plugins
+ FILE_PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+ )
+endif()
+
+if( KICAD_SCRIPTING_MODULES )
+ add_custom_target( FixSwigImportsModuleScripting ALL
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripting/build_tools/fix_swig_imports.py ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
+ DEPENDS _pcbnew
+ COMMENT "Fixing swig_import_helper in Kicad scripting modules"
+ )
+
+ if( NOT APPLE )
+ install( FILES ${CMAKE_BINARY_DIR}/pcbnew/pcbnew.py DESTINATION ${PYTHON_DEST} )
+ else()
+ # put everything into bundle at build time, it is relocated at install
+ add_custom_target( ScriptingModulesPcbnewPyCopy ALL
+ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_BINARY_DIR}/pcbnew/pcbnew.py" "${PYTHON_DEST}/"
+ DEPENDS FixSwigImportsModuleScripting
+ COMMENT "Copying pcbnew.py into ${PYTHON_DEST}"
+ )
+ add_dependencies( ScriptingModulesPcbnewPyCopy ScriptingWxpythonCopy )
+ endif()
+
+ if( MINGW )
+ install( FILES ${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.pyd DESTINATION ${PYTHON_DEST} )
+ elseif( APPLE )
+ # put everything into bundle at build time, it is relocated at install
+ add_custom_target( ScriptingModulesPcbnewSoCopy ALL
+ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.so" "${PYTHON_DEST}/"
+ DEPENDS _pcbnew
+ COMMENT "Copying _pcbnew.so into ${PYTHON_DEST}"
+ )
+ add_dependencies( ScriptingModulesPcbnewSoCopy ScriptingWxpythonCopy )
+ else()
+ install( FILES ${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.so DESTINATION ${PYTHON_DEST} )
+ endif()
+endif()
+
+if( APPLE )
+ if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
+ # find wx-X.Y-osx_cocoa path below PYTHON_SITE_PACKAGE_PATH
+ file( GLOB WXPYTHON_DIR RELATIVE ${PYTHON_SITE_PACKAGE_PATH} ${PYTHON_SITE_PACKAGE_PATH}/wx-?.?-osx_cocoa )
+ if( NOT WXPYTHON_DIR )
+ message( FATAL_ERROR "Could not find 'wx-?.?-osx_cocoa' in '${PYTHON_SITE_PACKAGE_PATH}'" )
+ endif()
+ # copy contents
+ add_custom_target( ScriptingWxpythonCopy ALL
+ COMMAND ${CMAKE_COMMAND} -E copy_directory "${PYTHON_SITE_PACKAGE_PATH}/${WXPYTHON_DIR}" "${PYTHON_DEST}/${WXPYTHON_DIR}"
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_SITE_PACKAGE_PATH}/wxversion.py" "${PYTHON_DEST}"
+ COMMENT "Copying wxPython into ${PYTHON_DEST}"
+ )
+ endif()
+endif()
+
+
+if( false ) # haven't been used in years.
+ # This one gets made only when testing.
+ add_executable( specctra_test EXCLUDE_FROM_ALL specctra_test.cpp specctra.cpp )
+ target_link_libraries( specctra_test common ${wxWidgets_LIBRARIES} )
+
+
+ # This one gets made only when testing.
+ add_executable( layer_widget_test WIN32 EXCLUDE_FROM_ALL
+ layer_widget.cpp
+ )
+ target_link_libraries( layer_widget_test common ${wxWidgets_LIBRARIES} )
+endif()
diff --git a/pcbnew/Doxyfile_python b/pcbnew/Doxyfile_python
new file mode 100644
index 0000000..5093cf0
--- /dev/null
+++ b/pcbnew/Doxyfile_python
@@ -0,0 +1,2281 @@
+# Doxyfile 1.8.5
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = "KiCAD pcbnew scripting"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doxygen-python
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-
+# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en,
+# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish,
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,
+# Turkish, Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C.
+#
+# Note For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = YES
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order. Note the this
+# will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. Do not use file names with spaces, bibtex cannot handle them. See
+# also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = $(PYTHON_SOURCES_TO_DOC)
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS = _object,SwigPyIterator
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
+# defined cascading style sheet that is included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet file to the output directory. For an example
+# see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavours of web server based searching depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools. See
+# the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
+# replace them by respectively the title of the page, the current date and time,
+# only the current date, the version number of doxygen, the project name (see
+# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS = YES
+
+# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT = docbook
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all refrences to function-like macros that are alone on a line, have an
+# all uppercase name, and do not end with a semicolon. Such function macros are
+# typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have an unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS = NO
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS = 0
+
+# When you want a differently looking font n the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH = NO
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH =NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP = YES
diff --git a/pcbnew/Doxyfile_xml b/pcbnew/Doxyfile_xml
new file mode 100644
index 0000000..189b5a1
--- /dev/null
+++ b/pcbnew/Doxyfile_xml
@@ -0,0 +1,315 @@
+# Doxyfile 1.8.5
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = "KiCad PCB EDA Suite"
+PROJECT_NUMBER =
+PROJECT_BRIEF =
+PROJECT_LOGO =
+OUTPUT_DIRECTORY = doxygen-xml
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = YES
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = YES
+QT_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 4
+ALIASES =
+TCL_SUBST =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+OPTIMIZE_FOR_FORTRAN = NO
+OPTIMIZE_OUTPUT_VHDL = NO
+EXTENSION_MAPPING =
+MARKDOWN_SUPPORT = YES
+AUTOLINK_SUPPORT = YES
+BUILTIN_STL_SUPPORT = NO
+CPP_CLI_SUPPORT = NO
+SIP_SUPPORT = NO
+IDL_PROPERTY_SUPPORT = YES
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+INLINE_GROUPED_CLASSES = NO
+INLINE_SIMPLE_STRUCTS = NO
+TYPEDEF_HIDES_STRUCT = NO
+LOOKUP_CACHE_SIZE = 0
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_PACKAGE = NO
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+EXTRACT_ANON_NSPACES = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+FORCE_LOCAL_INCLUDES = NO
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_MEMBERS_CTORS_1ST = NO
+SORT_GROUP_NAMES = NO
+SORT_BY_SCOPE_NAME = NO
+STRICT_PROTO_MATCHING = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_FILES = YES
+SHOW_NAMESPACES = YES
+FILE_VERSION_FILTER =
+LAYOUT_FILE =
+CITE_BIB_FILES =
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text "
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = $(SOURCES_DIR)/kicad \
+ $(SOURCES_DIR)/pcbnew \
+ $(SOURCES_DIR)/3d-viewer \
+ $(SOURCES_DIR)/common \
+ $(SOURCES_DIR)/include \
+ $(SOURCES_DIR)/polygon \
+ $(SOURCES_DIR)/potrace
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS = *.h \
+ *.cpp
+RECURSIVE = YES
+EXCLUDE = $(SOURCES_DIR)/include/boost
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXCLUDE_SYMBOLS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+FILTER_SOURCE_PATTERNS =
+USE_MDFILE_AS_MAINPAGE =
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = YES
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+REFERENCES_LINK_SOURCE = YES
+SOURCE_TOOLTIPS = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = NO
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_EXTRA_STYLESHEET =
+HTML_EXTRA_FILES =
+HTML_COLORSTYLE_HUE = 220
+HTML_COLORSTYLE_SAT = 100
+HTML_COLORSTYLE_GAMMA = 80
+HTML_TIMESTAMP = YES
+HTML_DYNAMIC_SECTIONS = NO
+HTML_INDEX_NUM_ENTRIES = 100
+GENERATE_DOCSET = NO
+DOCSET_FEEDNAME = "Doxygen generated docs"
+DOCSET_BUNDLE_ID = org.doxygen.Project
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+DOCSET_PUBLISHER_NAME = Publisher
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+CHM_INDEX_ENCODING =
+BINARY_TOC = NO
+TOC_EXPAND = NO
+GENERATE_QHP = NO
+QCH_FILE =
+QHP_NAMESPACE = org.doxygen.Project
+QHP_VIRTUAL_FOLDER = doc
+QHP_CUST_FILTER_NAME =
+QHP_CUST_FILTER_ATTRS =
+QHP_SECT_FILTER_ATTRS =
+QHG_LOCATION =
+GENERATE_ECLIPSEHELP = NO
+ECLIPSE_DOC_ID = org.doxygen.Project
+DISABLE_INDEX = NO
+GENERATE_TREEVIEW = YES
+ENUM_VALUES_PER_LINE = 4
+TREEVIEW_WIDTH = 250
+EXT_LINKS_IN_WINDOW = NO
+FORMULA_FONTSIZE = 10
+FORMULA_TRANSPARENT = YES
+USE_MATHJAX = NO
+MATHJAX_FORMAT = HTML-CSS
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+MATHJAX_EXTENSIONS =
+MATHJAX_CODEFILE =
+SEARCHENGINE = NO
+SERVER_BASED_SEARCH = NO
+EXTERNAL_SEARCH = NO
+SEARCHENGINE_URL =
+SEARCHDATA_FILE = searchdata.xml
+EXTERNAL_SEARCH_ID =
+EXTRA_SEARCH_MAPPINGS =
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+LATEX_FOOTER =
+LATEX_EXTRA_FILES =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+LATEX_SOURCE_CODE = NO
+LATEX_BIB_STYLE = plain
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = YES
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+GENERATE_DOCBOOK = NO
+DOCBOOK_OUTPUT = docbook
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH = $(SOURCES_DIR)/include \
+ $(SOURCES_DIR)/pcbnew \
+ $(SOURCES_DIR)/eeschema \
+ $(SOURCES_DIR)/gerbview
+INCLUDE_FILE_PATTERNS = *.h
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+EXTERNAL_PAGES = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+MSCGEN_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+DOT_NUM_THREADS = 0
+DOT_FONTNAME = Helvetica
+DOT_FONTSIZE = 10
+DOT_FONTPATH =
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+UML_LIMIT_NUM_FIELDS = 10
+TEMPLATE_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+CALLER_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+INTERACTIVE_SVG = NO
+DOT_PATH =
+DOTFILE_DIRS =
+MSCFILE_DIRS =
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
diff --git a/pcbnew/Info.plist b/pcbnew/Info.plist
new file mode 100644
index 0000000..f9da1a7
--- /dev/null
+++ b/pcbnew/Info.plist
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeRole</key> <string>Editor</string>
+ <key>CFBundleTypeIconFile</key> <string>pcbnew_doc.icns</string>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>kicad_pcb</string>
+ <string>brd</string>
+ </array>
+
+ <key>CFBundleTypeName</key> <string>pcbnew board</string>
+ <key>LSHandlerRank</key> <string>Owner</string>
+ </dict>
+ </array>
+
+ <key>CFBundleExecutable</key> <string>pcbnew</string>
+ <key>CFBundleGetInfoString</key> <string></string>
+ <key>CFBundleIconFile</key> <string>pcbnew.icns</string>
+ <key>CFBundleIdentifier</key> <string>org.kicad-pcb.pcbnew</string>
+ <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string>
+ <key>CFBundleLongVersionString</key> <string></string>
+ <key>CFBundleName</key> <string>PCBNew</string>
+ <key>CFBundlePackageType</key> <string>APPL</string>
+ <key>CFBundleShortVersionString</key> <string></string>
+ <key>CFBundleSignature</key> <string>????</string>
+ <key>CFBundleVersion</key> <string></string>
+ <key>CSResourcesFileMapped</key> <true/>
+ <key>LSRequiresCarbon</key> <true/>
+ <key>NSHumanReadableCopyright</key> <string></string>
+ <key>NSHighResolutionCapable</key> <string>True</string>
+</dict>
+</plist>
diff --git a/pcbnew/append_board_to_current.cpp b/pcbnew/append_board_to_current.cpp
new file mode 100644
index 0000000..06e0630
--- /dev/null
+++ b/pcbnew/append_board_to_current.cpp
@@ -0,0 +1,221 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file append_board_to_current.cpp
+ * @brief append a board to the currently edited board.
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <pcbnew.h>
+#include <io_mgr.h>
+#include <class_module.h>
+#include <class_zone.h>
+#include <class_board.h>
+#include <pcb_draw_panel_gal.h>
+
+// Defined in files.cpp:
+extern IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl );
+
+
+bool PCB_EDIT_FRAME::AppendBoardFile( const wxString& aFullFileName, int aCtl )
+{
+ IO_MGR::PCB_FILE_T pluginType = plugin_type( aFullFileName, aCtl );
+ PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
+
+ // keep trace of existing items, in order to know what are the new items
+ // (for undo command for instance)
+
+ // Tracks are inserted, not append, so mark existing tracks to know what are
+ // the new tracks
+ for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() )
+ track->SetFlags( FLAG0 );
+
+ // Other items are append to the item list, so keep trace to the
+ // last existing item is enough
+ MODULE* module = GetBoard()->m_Modules.GetLast();
+ BOARD_ITEM* drawing = GetBoard()->m_Drawings.GetLast();
+ int zonescount = GetBoard()->GetAreaCount();
+
+ // Keep also the count of copper layers, because we can happen boards
+ // with different copper layers counts,
+ // and the enabled layers
+ int initialCopperLayerCount = GetBoard()->GetCopperLayerCount();
+ LSET initialEnabledLayers = GetBoard()->GetEnabledLayers();
+
+ try
+ {
+ PROPERTIES props;
+ char xbuf[30];
+ char ybuf[30];
+
+ // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
+ sprintf( xbuf, "%d", GetPageSizeIU().x );
+ sprintf( ybuf, "%d", GetPageSizeIU().y );
+
+ props["page_width"] = xbuf;
+ props["page_height"] = ybuf;
+
+ GetDesignSettings().m_NetClasses.Clear();
+ pi->Load( aFullFileName, GetBoard(), &props );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() )
+ track->ClearFlags( FLAG0 );
+
+ wxString msg = wxString::Format( _(
+ "Error loading board.\n%s" ),
+ GetChars( ioe.errorText )
+ );
+ DisplayError( this, msg );
+
+ return false;
+ }
+
+ // Now prepare a block move command to place the new items, and
+ // prepare the undo command.
+ BLOCK_SELECTOR& blockmove = GetScreen()->m_BlockLocate;
+ HandleBlockBegin( NULL, BLOCK_PRESELECT_MOVE, wxPoint( 0, 0) );
+ PICKED_ITEMS_LIST& blockitemsList = blockmove.GetItems();
+ PICKED_ITEMS_LIST undoListPicker;
+ ITEM_PICKER picker( NULL, UR_NEW );
+
+ EDA_RECT bbox; // the new items bounding box, for block move
+ bool bboxInit = true; // true until the bounding box is initialized
+
+ for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() )
+ {
+ if( track->GetFlags() & FLAG0 )
+ {
+ track->ClearFlags( FLAG0 );
+ continue;
+ }
+
+ track->SetFlags( IS_MOVED );
+ picker.SetItem( track );
+ undoListPicker.PushItem( picker );
+ blockitemsList.PushItem( picker );
+
+ if( bboxInit )
+ bbox = track->GetBoundingBox();
+ else
+ bbox.Merge( track->GetBoundingBox() );
+
+ bboxInit = false;
+ }
+
+ if( module )
+ module = module->Next();
+ else
+ module = GetBoard()->m_Modules;
+
+ for( ; module; module = module->Next() )
+ {
+ module->SetFlags( IS_MOVED );
+ picker.SetItem( module );
+ undoListPicker.PushItem( picker );
+ blockitemsList.PushItem( picker );
+
+ if( bboxInit )
+ bbox = module->GetBoundingBox();
+ else
+ bbox.Merge( module->GetBoundingBox() );
+
+ bboxInit = false;
+ }
+
+ if( drawing )
+ drawing = drawing->Next();
+ else
+ drawing = GetBoard()->m_Drawings;
+
+ for( ; drawing; drawing = drawing->Next() )
+ {
+ drawing->SetFlags( IS_MOVED );
+ picker.SetItem( drawing );
+ undoListPicker.PushItem( picker );
+ blockitemsList.PushItem( picker );
+
+ if( bboxInit )
+ bbox = drawing->GetBoundingBox();
+ else
+ bbox.Merge( drawing->GetBoundingBox() );
+
+ bboxInit = false;
+ }
+
+ for( ZONE_CONTAINER* zone = GetBoard()->GetArea( zonescount ); zone;
+ zone = GetBoard()->GetArea( zonescount ) )
+ {
+ zone->SetFlags( IS_MOVED );
+ picker.SetItem( zone );
+ undoListPicker.PushItem( picker );
+ blockitemsList.PushItem( picker );
+ zonescount++;
+
+ if( bboxInit )
+ bbox = zone->GetBoundingBox();
+ else
+ bbox.Merge( zone->GetBoundingBox() );
+
+ bboxInit = false;
+ }
+
+ SaveCopyInUndoList( undoListPicker, UR_NEW );
+
+ // we should not ask PLUGINs to do these items:
+ int copperLayerCount = GetBoard()->GetCopperLayerCount();
+
+ if( copperLayerCount > initialCopperLayerCount )
+ GetBoard()->SetCopperLayerCount( copperLayerCount );
+
+ // Enable all used layers, and make them visible:
+ LSET enabledLayers = GetBoard()->GetEnabledLayers();
+ enabledLayers |= initialEnabledLayers;
+ GetBoard()->SetEnabledLayers( enabledLayers );
+ GetBoard()->SetVisibleLayers( enabledLayers );
+ ReCreateLayerBox();
+ ReFillLayerWidget();
+
+ if( IsGalCanvasActive() )
+ static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() )->SyncLayersVisibility( GetBoard() );
+
+ GetBoard()->BuildListOfNets();
+ GetBoard()->SynchronizeNetsAndNetClasses();
+
+ SetStatusText( wxEmptyString );
+ BestZoom();
+
+ // Finish block move command:
+ wxPoint cpos = GetNearestGridPosition( bbox.Centre() );
+ blockmove.SetOrigin( bbox.GetOrigin() );
+ blockmove.SetSize( bbox.GetSize() );
+ blockmove.SetLastCursorPosition( cpos );
+ HandleBlockEnd( NULL );
+
+ return true;
+}
diff --git a/pcbnew/attribut.cpp b/pcbnew/attribut.cpp
new file mode 100644
index 0000000..c56f09d
--- /dev/null
+++ b/pcbnew/attribut.cpp
@@ -0,0 +1,126 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file attribut.cpp
+ * @brief Track attribute flags editing.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <gr_basic.h>
+#include <wxPcbStruct.h>
+#include <msgpanel.h>
+
+#include <pcbnew.h>
+#include <protos.h>
+
+#include <class_track.h>
+#include <class_board.h>
+
+
+/* Attribute change for 1 track segment.
+ * Attributes are
+ * TRACK_LOCKED protection against global delete
+ * TRACK_AR AutoRouted segment
+ */
+void PCB_EDIT_FRAME::Attribut_Segment( TRACK* track, wxDC* DC, bool Flag_On )
+{
+ if( track == NULL )
+ return;
+
+ OnModify();
+ m_canvas->CrossHairOff( DC ); // Erase cursor shape
+ track->SetState( TRACK_LOCKED, Flag_On );
+ track->Draw( m_canvas, DC, GR_OR | GR_HIGHLIGHT );
+ m_canvas->CrossHairOn( DC ); // Display cursor shape
+
+ MSG_PANEL_ITEMS items;
+ track->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+}
+
+
+/* Attribute change for an entire track */
+void PCB_EDIT_FRAME::Attribut_Track( TRACK* track, wxDC* DC, bool Flag_On )
+{
+ TRACK* Track;
+ int nb_segm;
+
+ if( (track == NULL ) || (track->Type() == PCB_ZONE_T) )
+ return;
+
+ m_canvas->CrossHairOff( DC ); // Erase cursor shape
+ Track = GetBoard()->MarkTrace( track, &nb_segm, NULL, NULL, true );
+ DrawTraces( m_canvas, DC, Track, nb_segm, GR_OR | GR_HIGHLIGHT );
+
+ for( ; (Track != NULL) && (nb_segm > 0); nb_segm-- )
+ {
+ Track->SetState( TRACK_LOCKED, Flag_On );
+ Track->SetState( BUSY, false );
+ Track = Track->Next();
+ }
+
+ m_canvas->CrossHairOn( DC ); // Display cursor shape
+
+ OnModify();
+}
+
+
+/* Modify the flag TRACK_LOCKED according to Flag_On value,
+ * for all the segments related to net_code.
+ * if net_code < 0 all the segments are modified.
+ */
+void PCB_EDIT_FRAME::Attribut_net( wxDC* DC, int net_code, bool Flag_On )
+{
+ TRACK* Track = GetBoard()->m_Track;
+
+ /* search the first segment for the selected net_code */
+ if( net_code >= 0 )
+ {
+ for( ; Track != NULL; Track = Track->Next() )
+ {
+ if( net_code == Track->GetNetCode() )
+ break;
+ }
+ }
+
+ m_canvas->CrossHairOff( DC ); // Erase cursor shape
+
+ while( Track ) /* Flag change */
+ {
+ if( ( net_code >= 0 ) && ( net_code != Track->GetNetCode() ) )
+ break;
+
+ OnModify();
+ Track->SetState( TRACK_LOCKED, Flag_On );
+ Track->Draw( m_canvas, DC, GR_OR | GR_HIGHLIGHT );
+ Track = Track->Next();
+ }
+
+ m_canvas->CrossHairOn( DC ); // Display cursor shape
+ OnModify();
+}
diff --git a/pcbnew/autorouter/auto_place_footprints.cpp b/pcbnew/autorouter/auto_place_footprints.cpp
new file mode 100644
index 0000000..d6d25a1
--- /dev/null
+++ b/pcbnew/autorouter/auto_place_footprints.cpp
@@ -0,0 +1,1299 @@
+/**
+ * @file auto_place_footprints.cpp
+ * @brief Functions to automatically place Footprints on a board.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <msgpanel.h>
+
+#include <autorout.h>
+#include <cell.h>
+#include <colors_selection.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_drawsegment.h>
+#include <convert_to_biu.h>
+#include <base_units.h>
+#include <protos.h>
+
+
+#define GAIN 16
+#define KEEP_OUT_MARGIN 500
+
+
+/* Penalty (cost) for CntRot90 and CntRot180:
+ * CntRot90 and CntRot180 are from 0 (rotation allowed) to 10 (rotation not allowed)
+ */
+static const double OrientPenality[11] =
+{
+ 2.0, // CntRot = 0 rotation prohibited
+ 1.9, // CntRot = 1
+ 1.8, // CntRot = 2
+ 1.7, // CntRot = 3
+ 1.6, // CntRot = 4
+ 1.5, // CntRot = 5
+ 1.4, // CntRot = 5
+ 1.3, // CntRot = 7
+ 1.2, // CntRot = 8
+ 1.1, // CntRot = 9
+ 1.0 // CntRot = 10 rotation authorized, no penalty
+};
+
+// Cell states.
+#define OUT_OF_BOARD -2
+#define OCCUPED_By_MODULE -1
+#define FREE_CELL 0
+
+
+static wxPoint CurrPosition; // Current position of the current module placement
+double MinCout;
+
+
+/* generates the Routing matrix, used to fing the best placement
+ * of a footprint.
+ * Allocate a "bitmap" which is an image of the real board
+ * the bitmap handles:
+ * - The free areas
+ * - penalties (cell not occupied, but near occupied areas)
+ * - cells occupied by footprints, board cutout ...
+ */
+int genPlacementRoutingMatrix( BOARD* aBrd, EDA_MSG_PANEL* messagePanel );
+
+/* searches for the optimal position of aModule.
+ * return 1 if placement impossible or 0 if OK.
+ */
+static int getOptimalModulePlacement( PCB_EDIT_FRAME* aFrame,
+ MODULE* aModule, wxDC* aDC );
+
+/*
+ * Function compute_Ratsnest_PlaceModule
+ * displays the module's ratsnest during displacement, and assess the "cost"
+ * of the position.
+ *
+ * The cost is the longest ratsnest distance with penalty for connections
+ * approaching 45 degrees.
+ */
+static double compute_Ratsnest_PlaceModule( BOARD* aBrd );
+
+/* Place a footprint on the Routing matrix.
+ */
+void genModuleOnRoutingMatrix( MODULE* Module );
+/*
+ * Displays the Placement/Routing matrix on the screen
+ */
+static void drawPlacementRoutingMatrix( BOARD* aBrd, wxDC* DC );
+
+static int TstModuleOnBoard( BOARD* Pcb, MODULE* Module, bool TstOtherSide );
+
+static void CreateKeepOutRectangle( int ux0, int uy0, int ux1, int uy1,
+ int marge, int aKeepOut, LSET aLayerMask );
+
+static MODULE* PickModule( PCB_EDIT_FRAME* pcbframe, wxDC* DC );
+static int propagate();
+
+void PCB_EDIT_FRAME::AutoPlaceModule( MODULE* Module, int place_mode, wxDC* DC )
+{
+ MODULE* currModule = NULL;
+ wxPoint PosOK;
+ wxPoint memopos;
+ int error;
+ LAYER_ID lay_tmp_TOP, lay_tmp_BOTTOM;
+
+ // Undo: init list
+ PICKED_ITEMS_LIST newList;
+
+ newList.m_Status = UR_CHANGED;
+ ITEM_PICKER picker( NULL, UR_CHANGED );
+
+ if( GetBoard()->m_Modules == NULL )
+ return;
+
+ m_canvas->SetAbortRequest( false );
+
+ switch( place_mode )
+ {
+ case PLACE_1_MODULE:
+ currModule = Module;
+
+ if( currModule == NULL )
+ return;
+
+ currModule->SetIsPlaced( false );
+ currModule->SetNeedsPlaced( false );
+ break;
+
+ case PLACE_OUT_OF_BOARD:
+ break;
+
+ case PLACE_ALL:
+
+ if( !IsOK( this, _( "Footprints NOT LOCKED will be moved" ) ) )
+ return;
+
+ break;
+
+ case PLACE_INCREMENTAL:
+
+ if( !IsOK( this, _( "Footprints NOT PLACED will be moved" ) ) )
+ return;
+
+ break;
+ }
+
+ memopos = CurrPosition;
+ lay_tmp_BOTTOM = g_Route_Layer_BOTTOM;
+ lay_tmp_TOP = g_Route_Layer_TOP;
+
+ RoutingMatrix.m_GridRouting = (int) GetScreen()->GetGridSize().x;
+
+ // Ensure Board.m_GridRouting has a reasonable value:
+ if( RoutingMatrix.m_GridRouting < Millimeter2iu( 0.25 ) )
+ RoutingMatrix.m_GridRouting = Millimeter2iu( 0.25 );
+
+ // Compute module parameters used in auto place
+ if( genPlacementRoutingMatrix( GetBoard(), m_messagePanel ) == 0 )
+ return;
+
+ int moduleCount = 0;
+ Module = GetBoard()->m_Modules;
+
+ for( ; Module != NULL; Module = Module->Next() )
+ {
+ Module->SetNeedsPlaced( false );
+
+ switch( place_mode )
+ {
+ case PLACE_1_MODULE:
+
+ if( currModule == Module )
+ {
+ // Module will be placed, add to undo.
+ picker.SetItem( currModule );
+ newList.PushItem( picker );
+ Module->SetNeedsPlaced( true );
+ }
+
+ break;
+
+ case PLACE_OUT_OF_BOARD:
+ Module->SetIsPlaced( false );
+
+ if( Module->IsLocked() )
+ break;
+
+ if( !RoutingMatrix.m_BrdBox.Contains( Module->GetPosition() ) )
+ {
+ // Module will be placed, add to undo.
+ picker.SetItem( Module );
+ newList.PushItem( picker );
+ Module->SetNeedsPlaced( true );
+ }
+
+ break;
+
+ case PLACE_ALL:
+ Module->SetIsPlaced( false );
+
+ if( Module->IsLocked() )
+ break;
+
+ // Module will be placed, add to undo.
+ picker.SetItem( Module );
+ newList.PushItem( picker );
+ Module->SetNeedsPlaced( true );
+ break;
+
+ case PLACE_INCREMENTAL:
+
+ if( Module->IsLocked() )
+ {
+ Module->SetIsPlaced( false );
+ break;
+ }
+
+ if( !Module->NeedsPlaced() )
+ {
+ // Module will be placed, add to undo.
+ picker.SetItem( Module );
+ newList.PushItem( picker );
+ Module->SetNeedsPlaced( true );
+ }
+
+ break;
+ }
+
+ if( Module->NeedsPlaced() ) // Erase from screen
+ {
+ moduleCount++;
+ Module->Draw( m_canvas, DC, GR_XOR );
+ }
+ else
+ {
+ genModuleOnRoutingMatrix( Module );
+ }
+ }
+
+ // Undo command: prepare list
+ if( newList.GetCount() )
+ SaveCopyInUndoList( newList, UR_CHANGED );
+
+ int cnt = 0;
+ wxString msg;
+
+ while( ( Module = PickModule( this, DC ) ) != NULL )
+ {
+ // Display some info about activity, module placement can take a while:
+ msg.Printf( _( "Place footprint %d of %d" ), cnt, moduleCount );
+ SetStatusText( msg );
+
+ double initialOrient = Module->GetOrientation();
+ // Display fill area of interest, barriers, penalties.
+ drawPlacementRoutingMatrix( GetBoard(), DC );
+
+ error = getOptimalModulePlacement( this, Module, DC );
+ double bestScore = MinCout;
+ double bestRotation = 0.0;
+ int rotAllowed;
+ PosOK = CurrPosition;
+
+ if( error == ESC )
+ goto end_of_tst;
+
+ // Try orientations 90, 180, 270 degrees from initial orientation
+ rotAllowed = Module->GetPlacementCost180();
+
+ if( rotAllowed != 0 )
+ {
+ Rotate_Module( DC, Module, 1800.0, true );
+ error = getOptimalModulePlacement( this, Module, DC );
+ MinCout *= OrientPenality[rotAllowed];
+
+ if( bestScore > MinCout ) // This orientation is better.
+ {
+ PosOK = CurrPosition;
+ bestScore = MinCout;
+ bestRotation = 1800.0;
+ }
+ else
+ {
+ Rotate_Module( DC, Module, initialOrient, false );
+ }
+
+ if( error == ESC )
+ goto end_of_tst;
+ }
+
+ // Determine if the best orientation of a module is 90.
+ rotAllowed = Module->GetPlacementCost90();
+
+ if( rotAllowed != 0 )
+ {
+ Rotate_Module( DC, Module, 900.0, true );
+ error = getOptimalModulePlacement( this, Module, DC );
+ MinCout *= OrientPenality[rotAllowed];
+
+ if( bestScore > MinCout ) // This orientation is better.
+ {
+ PosOK = CurrPosition;
+ bestScore = MinCout;
+ bestRotation = 900.0;
+ }
+ else
+ {
+ Rotate_Module( DC, Module, initialOrient, false );
+ }
+
+ if( error == ESC )
+ goto end_of_tst;
+ }
+
+ // Determine if the best orientation of a module is -90.
+ if( rotAllowed != 0 )
+ {
+ Rotate_Module( DC, Module, 2700.0, true );
+ error = getOptimalModulePlacement( this, Module, DC );
+ MinCout *= OrientPenality[rotAllowed];
+
+ if( bestScore > MinCout ) // This orientation is better.
+ {
+ PosOK = CurrPosition;
+ bestScore = MinCout;
+ bestRotation = 2700.0;
+ }
+ else
+ {
+ Rotate_Module( DC, Module, initialOrient, false );
+ }
+
+ if( error == ESC )
+ goto end_of_tst;
+ }
+
+end_of_tst:
+
+ if( error == ESC )
+ break;
+
+ // Place module.
+ CurrPosition = GetCrossHairPosition();
+ SetCrossHairPosition( PosOK );
+
+ PlaceModule( Module, DC );
+
+ bestRotation += initialOrient;
+
+ if( bestRotation != Module->GetOrientation() )
+ Rotate_Module( DC, Module, bestRotation, false );
+
+ SetCrossHairPosition( CurrPosition );
+
+ Module->CalculateBoundingBox();
+
+ genModuleOnRoutingMatrix( Module );
+ Module->SetIsPlaced( true );
+ Module->SetNeedsPlaced( false );
+ }
+
+ CurrPosition = memopos;
+
+ RoutingMatrix.UnInitRoutingMatrix();
+
+ g_Route_Layer_TOP = lay_tmp_TOP;
+ g_Route_Layer_BOTTOM = lay_tmp_BOTTOM;
+
+ Module = GetBoard()->m_Modules;
+
+ for( ; Module != NULL; Module = Module->Next() )
+ {
+ Module->CalculateBoundingBox();
+ }
+
+ GetBoard()->m_Status_Pcb = 0;
+ Compile_Ratsnest( DC, true );
+ m_canvas->ReDraw( DC, true );
+}
+
+
+void drawPlacementRoutingMatrix( BOARD* aBrd, wxDC* DC )
+{
+ int ii, jj;
+ EDA_COLOR_T color;
+ int ox, oy;
+ MATRIX_CELL top_state, bottom_state;
+
+ GRSetDrawMode( DC, GR_COPY );
+
+ for( ii = 0; ii < RoutingMatrix.m_Nrows; ii++ )
+ {
+ oy = RoutingMatrix.m_BrdBox.GetY() + ( ii * RoutingMatrix.m_GridRouting );
+
+ for( jj = 0; jj < RoutingMatrix.m_Ncols; jj++ )
+ {
+ ox = RoutingMatrix.m_BrdBox.GetX() + (jj * RoutingMatrix.m_GridRouting);
+ color = BLACK;
+
+ top_state = RoutingMatrix.GetCell( ii, jj, TOP );
+ bottom_state = RoutingMatrix.GetCell( ii, jj, BOTTOM );
+
+ if( top_state & CELL_is_ZONE )
+ color = BLUE;
+
+ // obstacles
+ if( ( top_state & CELL_is_EDGE ) || ( bottom_state & CELL_is_EDGE ) )
+ color = WHITE;
+ else if( top_state & ( HOLE | CELL_is_MODULE ) )
+ color = LIGHTRED;
+ else if( bottom_state & (HOLE | CELL_is_MODULE) )
+ color = LIGHTGREEN;
+ else // Display the filling and keep out regions.
+ {
+ if( RoutingMatrix.GetDist( ii, jj, TOP )
+ || RoutingMatrix.GetDist( ii, jj, BOTTOM ) )
+ color = DARKGRAY;
+ }
+
+ GRPutPixel( NULL, DC, ox, oy, color );
+ }
+ }
+}
+
+
+int genPlacementRoutingMatrix( BOARD* aBrd, EDA_MSG_PANEL* messagePanel )
+{
+ wxString msg;
+
+ RoutingMatrix.UnInitRoutingMatrix();
+
+ EDA_RECT bbox = aBrd->ComputeBoundingBox( true );
+
+ if( bbox.GetWidth() == 0 || bbox.GetHeight() == 0 )
+ {
+ DisplayError( NULL, _( "No PCB edge found, unknown board size!" ) );
+ return 0;
+ }
+
+ RoutingMatrix.ComputeMatrixSize( aBrd, true );
+ int nbCells = RoutingMatrix.m_Ncols * RoutingMatrix.m_Nrows;
+
+ messagePanel->EraseMsgBox();
+ msg.Printf( wxT( "%d" ), RoutingMatrix.m_Ncols );
+ messagePanel->SetMessage( 1, _( "Cols" ), msg, GREEN );
+ msg.Printf( wxT( "%d" ), RoutingMatrix.m_Nrows );
+ messagePanel->SetMessage( 7, _( "Lines" ), msg, GREEN );
+ msg.Printf( wxT( "%d" ), nbCells );
+ messagePanel->SetMessage( 14, _( "Cells." ), msg, YELLOW );
+
+ // Choose the number of board sides.
+ RoutingMatrix.m_RoutingLayersCount = 2;
+
+ RoutingMatrix.InitRoutingMatrix();
+
+ // Display memory usage.
+ msg.Printf( wxT( "%d" ), RoutingMatrix.m_MemSize / 1024 );
+ messagePanel->SetMessage( 24, wxT( "Mem(Kb)" ), msg, CYAN );
+
+ g_Route_Layer_BOTTOM = F_Cu;
+
+ if( RoutingMatrix.m_RoutingLayersCount > 1 )
+ g_Route_Layer_BOTTOM = B_Cu;
+
+ g_Route_Layer_TOP = F_Cu;
+
+ // Place the edge layer segments
+ TRACK TmpSegm( NULL );
+
+ TmpSegm.SetLayer( UNDEFINED_LAYER );
+ TmpSegm.SetNetCode( -1 );
+ TmpSegm.SetWidth( RoutingMatrix.m_GridRouting / 2 );
+
+ EDA_ITEM* PtStruct = aBrd->m_Drawings;
+
+ for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
+ {
+ DRAWSEGMENT* DrawSegm;
+
+ switch( PtStruct->Type() )
+ {
+ case PCB_LINE_T:
+ DrawSegm = (DRAWSEGMENT*) PtStruct;
+
+ if( DrawSegm->GetLayer() != Edge_Cuts )
+ break;
+
+ TraceSegmentPcb( DrawSegm, HOLE | CELL_is_EDGE,
+ RoutingMatrix.m_GridRouting, WRITE_CELL );
+ break;
+
+ case PCB_TEXT_T:
+ default:
+ break;
+ }
+ }
+
+ // Mark cells of the routing matrix to CELL_is_ZONE
+ // (i.e. availlable cell to place a module )
+ // Init a starting point of attachment to the area.
+ RoutingMatrix.OrCell( RoutingMatrix.m_Nrows / 2, RoutingMatrix.m_Ncols / 2,
+ BOTTOM, CELL_is_ZONE );
+
+ // find and mark all other availlable cells:
+ for( int ii = 1; ii != 0; )
+ ii = propagate();
+
+ // Initialize top layer. to the same value as the bottom layer
+ if( RoutingMatrix.m_BoardSide[TOP] )
+ memcpy( RoutingMatrix.m_BoardSide[TOP], RoutingMatrix.m_BoardSide[BOTTOM],
+ nbCells * sizeof(MATRIX_CELL) );
+
+ return 1;
+}
+
+
+/* Place module on Routing matrix.
+ */
+void genModuleOnRoutingMatrix( MODULE* Module )
+{
+ int ox, oy, fx, fy;
+ LSET layerMask;
+ D_PAD* Pad;
+
+ EDA_RECT fpBBox = Module->GetBoundingBox();
+
+ fpBBox.Inflate( RoutingMatrix.m_GridRouting / 2 );
+ ox = fpBBox.GetX();
+ fx = fpBBox.GetRight();
+ oy = fpBBox.GetY();
+ fy = fpBBox.GetBottom();
+
+ if( ox < RoutingMatrix.m_BrdBox.GetX() )
+ ox = RoutingMatrix.m_BrdBox.GetX();
+
+ if( ox > RoutingMatrix.m_BrdBox.GetRight() )
+ ox = RoutingMatrix.m_BrdBox.GetRight();
+
+ if( fx < RoutingMatrix.m_BrdBox.GetX() )
+ fx = RoutingMatrix.m_BrdBox.GetX();
+
+ if( fx > RoutingMatrix.m_BrdBox.GetRight() )
+ fx = RoutingMatrix.m_BrdBox.GetRight();
+
+ if( oy < RoutingMatrix.m_BrdBox.GetY() )
+ oy = RoutingMatrix.m_BrdBox.GetY();
+
+ if( oy > RoutingMatrix.m_BrdBox.GetBottom() )
+ oy = RoutingMatrix.m_BrdBox.GetBottom();
+
+ if( fy < RoutingMatrix.m_BrdBox.GetY() )
+ fy = RoutingMatrix.m_BrdBox.GetY();
+
+ if( fy > RoutingMatrix.m_BrdBox.GetBottom() )
+ fy = RoutingMatrix.m_BrdBox.GetBottom();
+
+ if( Module->GetLayer() == F_Cu )
+ layerMask.set( F_Cu );
+
+ if( Module->GetLayer() == B_Cu )
+ layerMask.set( B_Cu );
+
+ TraceFilledRectangle( ox, oy, fx, fy, layerMask,
+ CELL_is_MODULE, WRITE_OR_CELL );
+
+ // Trace pads + clearance areas.
+ for( Pad = Module->Pads(); Pad != NULL; Pad = Pad->Next() )
+ {
+ int margin = (RoutingMatrix.m_GridRouting / 2) + Pad->GetClearance();
+ ::PlacePad( Pad, CELL_is_MODULE, margin, WRITE_OR_CELL );
+ }
+
+ // Trace clearance.
+ int margin = ( RoutingMatrix.m_GridRouting * Module->GetPadCount() ) / GAIN;
+ CreateKeepOutRectangle( ox, oy, fx, fy, margin, KEEP_OUT_MARGIN, layerMask );
+}
+
+// A minor helper function to draw a bounding box:
+inline void draw_FootprintRect(EDA_RECT * aClipBox, wxDC* aDC, EDA_RECT& fpBBox, EDA_COLOR_T aColor)
+{
+#ifndef USE_WX_OVERLAY
+ GRRect( aClipBox, aDC, fpBBox, 0, aColor );
+#endif
+}
+
+int getOptimalModulePlacement( PCB_EDIT_FRAME* aFrame, MODULE* aModule, wxDC* aDC )
+{
+ int error = 1;
+ wxPoint LastPosOK;
+ double min_cost, curr_cost, Score;
+ bool TstOtherSide;
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)aFrame->GetDisplayOptions();
+ BOARD* brd = aFrame->GetBoard();
+
+ aModule->CalculateBoundingBox();
+
+ bool showRats = displ_opts->m_Show_Module_Ratsnest;
+ displ_opts->m_Show_Module_Ratsnest = false;
+
+ brd->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK;
+ aFrame->SetMsgPanel( aModule );
+
+ LastPosOK = RoutingMatrix.m_BrdBox.GetOrigin();
+
+ wxPoint mod_pos = aModule->GetPosition();
+ EDA_RECT fpBBox = aModule->GetFootprintRect();
+
+ // Move fpBBox to have the footprint position at (0,0)
+ fpBBox.Move( -mod_pos );
+ wxPoint fpBBoxOrg = fpBBox.GetOrigin();
+
+ // Calculate the limit of the footprint position, relative
+ // to the routing matrix area
+ wxPoint xylimit = RoutingMatrix.m_BrdBox.GetEnd() - fpBBox.GetEnd();
+
+ wxPoint initialPos = RoutingMatrix.m_BrdBox.GetOrigin() - fpBBoxOrg;
+
+ // Stay on grid.
+ initialPos.x -= initialPos.x % RoutingMatrix.m_GridRouting;
+ initialPos.y -= initialPos.y % RoutingMatrix.m_GridRouting;
+
+ CurrPosition = initialPos;
+
+ // Undraw the current footprint
+ aModule->DrawOutlinesWhenMoving( aFrame->GetCanvas(), aDC, wxPoint( 0, 0 ) );
+
+ g_Offset_Module = mod_pos - CurrPosition;
+
+ /* Examine pads, and set TstOtherSide to true if a footprint
+ * has at least 1 pad through.
+ */
+ TstOtherSide = false;
+
+ if( RoutingMatrix.m_RoutingLayersCount > 1 )
+ {
+ LSET other( aModule->GetLayer() == B_Cu ? F_Cu : B_Cu );
+
+ for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
+ {
+ if( !( pad->GetLayerSet() & other ).any() )
+ continue;
+
+ TstOtherSide = true;
+ break;
+ }
+ }
+
+ // Draw the initial bounding box position
+ EDA_COLOR_T color = BROWN;
+ fpBBox.SetOrigin( fpBBoxOrg + CurrPosition );
+ draw_FootprintRect(aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, color);
+
+ min_cost = -1.0;
+ aFrame->SetStatusText( wxT( "Score ??, pos ??" ) );
+
+ for( ; CurrPosition.x < xylimit.x; CurrPosition.x += RoutingMatrix.m_GridRouting )
+ {
+ wxYield();
+
+ if( aFrame->GetCanvas()->GetAbortRequest() )
+ {
+ if( IsOK( aFrame, _( "OK to abort?" ) ) )
+ {
+ displ_opts->m_Show_Module_Ratsnest = showRats;
+ return ESC;
+ }
+ else
+ aFrame->GetCanvas()->SetAbortRequest( false );
+ }
+
+ CurrPosition.y = initialPos.y;
+
+ for( ; CurrPosition.y < xylimit.y; CurrPosition.y += RoutingMatrix.m_GridRouting )
+ {
+ // Erase traces.
+ draw_FootprintRect( aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, color );
+
+ fpBBox.SetOrigin( fpBBoxOrg + CurrPosition );
+ g_Offset_Module = mod_pos - CurrPosition;
+ int keepOutCost = TstModuleOnBoard( brd, aModule, TstOtherSide );
+
+ // Draw at new place
+ color = keepOutCost >= 0 ? BROWN : RED;
+ draw_FootprintRect( aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, color );
+
+ if( keepOutCost >= 0 ) // i.e. if the module can be put here
+ {
+ error = 0;
+ aFrame->build_ratsnest_module( aModule );
+ curr_cost = compute_Ratsnest_PlaceModule( brd );
+ Score = curr_cost + keepOutCost;
+
+ if( (min_cost >= Score ) || (min_cost < 0 ) )
+ {
+ LastPosOK = CurrPosition;
+ min_cost = Score;
+ wxString msg;
+ msg.Printf( wxT( "Score %g, pos %s, %s" ),
+ min_cost,
+ GetChars( ::CoordinateToString( LastPosOK.x ) ),
+ GetChars( ::CoordinateToString( LastPosOK.y ) ) );
+ aFrame->SetStatusText( msg );
+ }
+ }
+ }
+ }
+
+ // erasing the last traces
+ GRRect( aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, 0, BROWN );
+
+ displ_opts->m_Show_Module_Ratsnest = showRats;
+
+ // Regeneration of the modified variable.
+ CurrPosition = LastPosOK;
+
+ brd->m_Status_Pcb &= ~( RATSNEST_ITEM_LOCAL_OK | LISTE_PAD_OK );
+
+ MinCout = min_cost;
+ return error;
+}
+
+
+/* Test if the rectangular area (ux, ux .. y0, y1):
+ * - is a free zone (except OCCUPED_By_MODULE returns)
+ * - is on the working surface of the board (otherwise returns OUT_OF_BOARD)
+ *
+ * Returns OUT_OF_BOARD, or OCCUPED_By_MODULE or FREE_CELL if OK
+ */
+int TstRectangle( BOARD* Pcb, const EDA_RECT& aRect, int side )
+{
+ EDA_RECT rect = aRect;
+
+ rect.Inflate( RoutingMatrix.m_GridRouting / 2 );
+
+ wxPoint start = rect.GetOrigin();
+ wxPoint end = rect.GetEnd();
+
+ start -= RoutingMatrix.m_BrdBox.GetOrigin();
+ end -= RoutingMatrix.m_BrdBox.GetOrigin();
+
+ int row_min = start.y / RoutingMatrix.m_GridRouting;
+ int row_max = end.y / RoutingMatrix.m_GridRouting;
+ int col_min = start.x / RoutingMatrix.m_GridRouting;
+ int col_max = end.x / RoutingMatrix.m_GridRouting;
+
+ if( start.y > row_min * RoutingMatrix.m_GridRouting )
+ row_min++;
+
+ if( start.x > col_min * RoutingMatrix.m_GridRouting )
+ col_min++;
+
+ if( row_min < 0 )
+ row_min = 0;
+
+ if( row_max >= ( RoutingMatrix.m_Nrows - 1 ) )
+ row_max = RoutingMatrix.m_Nrows - 1;
+
+ if( col_min < 0 )
+ col_min = 0;
+
+ if( col_max >= ( RoutingMatrix.m_Ncols - 1 ) )
+ col_max = RoutingMatrix.m_Ncols - 1;
+
+ for( int row = row_min; row <= row_max; row++ )
+ {
+ for( int col = col_min; col <= col_max; col++ )
+ {
+ unsigned int data = RoutingMatrix.GetCell( row, col, side );
+
+ if( ( data & CELL_is_ZONE ) == 0 )
+ return OUT_OF_BOARD;
+
+ if( (data & CELL_is_MODULE) )
+ return OCCUPED_By_MODULE;
+ }
+ }
+
+ return FREE_CELL;
+}
+
+
+/* Calculates and returns the clearance area of the rectangular surface
+ * aRect):
+ * (Sum of cells in terms of distance)
+ */
+unsigned int CalculateKeepOutArea( const EDA_RECT& aRect, int side )
+{
+ wxPoint start = aRect.GetOrigin();
+ wxPoint end = aRect.GetEnd();
+
+ start -= RoutingMatrix.m_BrdBox.GetOrigin();
+ end -= RoutingMatrix.m_BrdBox.GetOrigin();
+
+ int row_min = start.y / RoutingMatrix.m_GridRouting;
+ int row_max = end.y / RoutingMatrix.m_GridRouting;
+ int col_min = start.x / RoutingMatrix.m_GridRouting;
+ int col_max = end.x / RoutingMatrix.m_GridRouting;
+
+ if( start.y > row_min * RoutingMatrix.m_GridRouting )
+ row_min++;
+
+ if( start.x > col_min * RoutingMatrix.m_GridRouting )
+ col_min++;
+
+ if( row_min < 0 )
+ row_min = 0;
+
+ if( row_max >= ( RoutingMatrix.m_Nrows - 1 ) )
+ row_max = RoutingMatrix.m_Nrows - 1;
+
+ if( col_min < 0 )
+ col_min = 0;
+
+ if( col_max >= ( RoutingMatrix.m_Ncols - 1 ) )
+ col_max = RoutingMatrix.m_Ncols - 1;
+
+ unsigned int keepOutCost = 0;
+
+ for( int row = row_min; row <= row_max; row++ )
+ {
+ for( int col = col_min; col <= col_max; col++ )
+ {
+ // RoutingMatrix.GetDist returns the "cost" of the cell
+ // at position (row, col)
+ // in autoplace this is the cost of the cell, if it is
+ // inside aRect
+ keepOutCost += RoutingMatrix.GetDist( row, col, side );
+ }
+ }
+
+ return keepOutCost;
+}
+
+
+/* Test if the module can be placed on the board.
+ * Returns the value TstRectangle().
+ * Module is known by its bounding box
+ */
+int TstModuleOnBoard( BOARD* Pcb, MODULE* aModule, bool TstOtherSide )
+{
+ int side = TOP;
+ int otherside = BOTTOM;
+
+ if( aModule->GetLayer() == B_Cu )
+ {
+ side = BOTTOM; otherside = TOP;
+ }
+
+ EDA_RECT fpBBox = aModule->GetFootprintRect();
+ fpBBox.Move( -g_Offset_Module );
+
+ int diag = TstRectangle( Pcb, fpBBox, side );
+
+ if( diag != FREE_CELL )
+ return diag;
+
+ if( TstOtherSide )
+ {
+ diag = TstRectangle( Pcb, fpBBox, otherside );
+
+ if( diag != FREE_CELL )
+ return diag;
+ }
+
+ int marge = ( RoutingMatrix.m_GridRouting * aModule->GetPadCount() ) / GAIN;
+
+ fpBBox.Inflate( marge );
+ return CalculateKeepOutArea( fpBBox, side );
+}
+
+
+double compute_Ratsnest_PlaceModule( BOARD* aBrd )
+{
+ double curr_cost;
+ wxPoint start; // start point of a ratsnest
+ wxPoint end; // end point of a ratsnest
+ int dx, dy;
+
+ if( ( aBrd->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK ) == 0 )
+ return -1;
+
+ curr_cost = 0;
+
+ for( unsigned ii = 0; ii < aBrd->m_LocalRatsnest.size(); ii++ )
+ {
+ RATSNEST_ITEM* pt_local_rats_nest = &aBrd->m_LocalRatsnest[ii];
+
+ if( ( pt_local_rats_nest->m_Status & LOCAL_RATSNEST_ITEM ) )
+ continue; // Skip ratsnest between 2 pads of the current module
+
+ // Skip modules not inside the board area
+ MODULE* module = pt_local_rats_nest->m_PadEnd->GetParent();
+
+ if( !RoutingMatrix.m_BrdBox.Contains( module->GetPosition() ) )
+ continue;
+
+ start = pt_local_rats_nest->m_PadStart->GetPosition() - g_Offset_Module;
+ end = pt_local_rats_nest->m_PadEnd->GetPosition();
+
+ // Cost of the ratsnest.
+ dx = end.x - start.x;
+ dy = end.y - start.y;
+
+ dx = abs( dx );
+ dy = abs( dy );
+
+ // ttry to have always dx >= dy to calculate the cost of the rastsnet
+ if( dx < dy )
+ std::swap( dx, dy );
+
+ // Cost of the connection = lenght + penalty due to the slope
+ // dx is the biggest lenght relative to the X or Y axis
+ // the penalty is max for 45 degrees ratsnests,
+ // and 0 for horizontal or vertical ratsnests.
+ // For Horizontal and Vertical ratsnests, dy = 0;
+ double conn_cost = hypot( dx, dy * 2.0 );
+ curr_cost += conn_cost; // Total cost = sum of costs of each connection
+ }
+
+ return curr_cost;
+}
+
+
+/**
+ * Function CreateKeepOutRectangle
+ * builds the cost map:
+ * Cells ( in Dist map ) inside the rect x0,y0 a x1,y1 are
+ * incremented by value aKeepOut
+ * Cell outside this rectangle, but inside the rectangle
+ * x0,y0 -marge to x1,y1 + marge are incremented by a decreasing value
+ * (aKeepOut ... 0). The decreasing value depends on the distance to the first rectangle
+ * Therefore the cost is high in rect x0,y0 to x1,y1, and decrease outside this rectangle
+ */
+void CreateKeepOutRectangle( int ux0, int uy0, int ux1, int uy1,
+ int marge, int aKeepOut, LSET aLayerMask )
+{
+ int row, col;
+ int row_min, row_max, col_min, col_max, pmarge;
+ int trace = 0;
+ DIST_CELL data, LocalKeepOut;
+ int lgain, cgain;
+
+ if( aLayerMask[g_Route_Layer_BOTTOM] )
+ trace = 1; // Trace on bottom layer.
+
+ if( aLayerMask[g_Route_Layer_TOP] && RoutingMatrix.m_RoutingLayersCount )
+ trace |= 2; // Trace on top layer.
+
+ if( trace == 0 )
+ return;
+
+ ux0 -= RoutingMatrix.m_BrdBox.GetX();
+ uy0 -= RoutingMatrix.m_BrdBox.GetY();
+ ux1 -= RoutingMatrix.m_BrdBox.GetX();
+ uy1 -= RoutingMatrix.m_BrdBox.GetY();
+
+ ux0 -= marge; ux1 += marge;
+ uy0 -= marge; uy1 += marge;
+
+ pmarge = marge / RoutingMatrix.m_GridRouting;
+
+ if( pmarge < 1 )
+ pmarge = 1;
+
+ // Calculate the coordinate limits of the rectangle.
+ row_max = uy1 / RoutingMatrix.m_GridRouting;
+ col_max = ux1 / RoutingMatrix.m_GridRouting;
+ row_min = uy0 / RoutingMatrix.m_GridRouting;
+
+ if( uy0 > row_min * RoutingMatrix.m_GridRouting )
+ row_min++;
+
+ col_min = ux0 / RoutingMatrix.m_GridRouting;
+
+ if( ux0 > col_min * RoutingMatrix.m_GridRouting )
+ col_min++;
+
+ if( row_min < 0 )
+ row_min = 0;
+
+ if( row_max >= (RoutingMatrix.m_Nrows - 1) )
+ row_max = RoutingMatrix.m_Nrows - 1;
+
+ if( col_min < 0 )
+ col_min = 0;
+
+ if( col_max >= (RoutingMatrix.m_Ncols - 1) )
+ col_max = RoutingMatrix.m_Ncols - 1;
+
+ for( row = row_min; row <= row_max; row++ )
+ {
+ lgain = 256;
+
+ if( row < pmarge )
+ lgain = ( 256 * row ) / pmarge;
+ else if( row > row_max - pmarge )
+ lgain = ( 256 * ( row_max - row ) ) / pmarge;
+
+ for( col = col_min; col <= col_max; col++ )
+ {
+ // RoutingMatrix Dist map containt the "cost" of the cell
+ // at position (row, col)
+ // in autoplace this is the cost of the cell, when
+ // a footprint overlaps it, near a "master" footprint
+ // this cost is hight near the "master" footprint
+ // and decrease with the distance
+ cgain = 256;
+ LocalKeepOut = aKeepOut;
+
+ if( col < pmarge )
+ cgain = ( 256 * col ) / pmarge;
+ else if( col > col_max - pmarge )
+ cgain = ( 256 * ( col_max - col ) ) / pmarge;
+
+ cgain = ( cgain * lgain ) / 256;
+
+ if( cgain != 256 )
+ LocalKeepOut = ( LocalKeepOut * cgain ) / 256;
+
+ if( trace & 1 )
+ {
+ data = RoutingMatrix.GetDist( row, col, BOTTOM ) + LocalKeepOut;
+ RoutingMatrix.SetDist( row, col, BOTTOM, data );
+ }
+
+ if( trace & 2 )
+ {
+ data = RoutingMatrix.GetDist( row, col, TOP );
+ data = std::max( data, LocalKeepOut );
+ RoutingMatrix.SetDist( row, col, TOP, data );
+ }
+ }
+ }
+}
+
+
+// Sort routines
+static bool Tri_PlaceModules( MODULE* ref, MODULE* compare )
+{
+ double ff1, ff2;
+
+ ff1 = ref->GetArea() * ref->GetPadCount();
+ ff2 = compare->GetArea() * compare->GetPadCount();
+
+ return ff2 < ff1;
+}
+
+
+static bool sortFootprintsByRatsnestSize( MODULE* ref, MODULE* compare )
+{
+ double ff1, ff2;
+
+ ff1 = ref->GetArea() * ref->GetFlag();
+ ff2 = compare->GetArea() * compare->GetFlag();
+ return ff2 < ff1;
+}
+
+
+/**
+ * Function PickModule
+ * find the "best" module place
+ * The criteria are:
+ * - Maximum ratsnest with modules already placed
+ * - Max size, and number of pads max
+ */
+static MODULE* PickModule( PCB_EDIT_FRAME* pcbframe, wxDC* DC )
+{
+ MODULE* Module;
+ std::vector <MODULE*> moduleList;
+
+ // Build sorted footprints list (sort by decreasing size )
+ Module = pcbframe->GetBoard()->m_Modules;
+
+ for( ; Module != NULL; Module = Module->Next() )
+ {
+ Module->CalculateBoundingBox();
+ moduleList.push_back( Module );
+ }
+
+ sort( moduleList.begin(), moduleList.end(), Tri_PlaceModules );
+
+ for( unsigned ii = 0; ii < moduleList.size(); ii++ )
+ {
+ Module = moduleList[ii];
+ Module->SetFlag( 0 );
+
+ if( !Module->NeedsPlaced() )
+ continue;
+
+ pcbframe->GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK;
+ pcbframe->SetMsgPanel( Module );
+ pcbframe->build_ratsnest_module( Module );
+
+ // Calculate external ratsnest.
+ for( unsigned ii = 0; ii < pcbframe->GetBoard()->m_LocalRatsnest.size(); ii++ )
+ {
+ if( ( pcbframe->GetBoard()->m_LocalRatsnest[ii].m_Status &
+ LOCAL_RATSNEST_ITEM ) == 0 )
+ Module->IncrementFlag();
+ }
+ }
+
+ pcbframe->GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK;
+
+ sort( moduleList.begin(), moduleList.end(), sortFootprintsByRatsnestSize );
+
+ // Search for "best" module.
+ MODULE* bestModule = NULL;
+ MODULE* altModule = NULL;
+
+ for( unsigned ii = 0; ii < moduleList.size(); ii++ )
+ {
+ Module = moduleList[ii];
+
+ if( !Module->NeedsPlaced() )
+ continue;
+
+ altModule = Module;
+
+ if( Module->GetFlag() == 0 )
+ continue;
+
+ bestModule = Module;
+ break;
+ }
+
+ if( bestModule )
+ return bestModule;
+ else
+ return altModule;
+}
+
+
+/**
+ * Function propagate
+ * Used only in autoplace calculations
+ * Uses the routing matrix to fill the cells within the zone
+ * Search and mark cells within the zone, and agree with DRC options.
+ * Requirements:
+ * Start from an initial point, to fill zone
+ * The zone must have no "copper island"
+ * Algorithm:
+ * If the current cell has a neighbor flagged as "cell in the zone", it
+ * become a cell in the zone
+ * The first point in the zone is the starting point
+ * 4 searches within the matrix are made:
+ * 1 - Left to right and top to bottom
+ * 2 - Right to left and top to bottom
+ * 3 - bottom to top and Right to left
+ * 4 - bottom to top and Left to right
+ * Given the current cell, for each search, we consider the 2 neighbor cells
+ * the previous cell on the same line and the previous cell on the same column.
+ *
+ * This function can request some iterations
+ * Iterations are made until no cell is added to the zone.
+ * @return added cells count (i.e. which the attribute CELL_is_ZONE is set)
+ */
+int propagate()
+{
+ int row, col;
+ long current_cell, old_cell_H;
+ std::vector<long> pt_cell_V;
+ int nbpoints = 0;
+
+#define NO_CELL_ZONE (HOLE | CELL_is_EDGE | CELL_is_ZONE)
+
+ pt_cell_V.reserve( std::max( RoutingMatrix.m_Nrows, RoutingMatrix.m_Ncols ) );
+ fill( pt_cell_V.begin(), pt_cell_V.end(), 0 );
+
+ // Search from left to right and top to bottom.
+ for( row = 0; row < RoutingMatrix.m_Nrows; row++ )
+ {
+ old_cell_H = 0;
+
+ for( col = 0; col < RoutingMatrix.m_Ncols; col++ )
+ {
+ current_cell = RoutingMatrix.GetCell( row, col, BOTTOM ) & NO_CELL_ZONE;
+
+ if( current_cell == 0 ) // a free cell is found
+ {
+ if( (old_cell_H & CELL_is_ZONE) || (pt_cell_V[col] & CELL_is_ZONE) )
+ {
+ RoutingMatrix.OrCell( row, col, BOTTOM, CELL_is_ZONE );
+ current_cell = CELL_is_ZONE;
+ nbpoints++;
+ }
+ }
+
+ pt_cell_V[col] = old_cell_H = current_cell;
+ }
+ }
+
+ // Search from right to left and top to bottom/
+ fill( pt_cell_V.begin(), pt_cell_V.end(), 0 );
+
+ for( row = 0; row < RoutingMatrix.m_Nrows; row++ )
+ {
+ old_cell_H = 0;
+
+ for( col = RoutingMatrix.m_Ncols - 1; col >= 0; col-- )
+ {
+ current_cell = RoutingMatrix.GetCell( row, col, BOTTOM ) & NO_CELL_ZONE;
+
+ if( current_cell == 0 ) // a free cell is found
+ {
+ if( (old_cell_H & CELL_is_ZONE) || (pt_cell_V[col] & CELL_is_ZONE) )
+ {
+ RoutingMatrix.OrCell( row, col, BOTTOM, CELL_is_ZONE );
+ current_cell = CELL_is_ZONE;
+ nbpoints++;
+ }
+ }
+
+ pt_cell_V[col] = old_cell_H = current_cell;
+ }
+ }
+
+ // Search from bottom to top and right to left.
+ fill( pt_cell_V.begin(), pt_cell_V.end(), 0 );
+
+ for( col = RoutingMatrix.m_Ncols - 1; col >= 0; col-- )
+ {
+ old_cell_H = 0;
+
+ for( row = RoutingMatrix.m_Nrows - 1; row >= 0; row-- )
+ {
+ current_cell = RoutingMatrix.GetCell( row, col, BOTTOM ) & NO_CELL_ZONE;
+
+ if( current_cell == 0 ) // a free cell is found
+ {
+ if( (old_cell_H & CELL_is_ZONE) || (pt_cell_V[row] & CELL_is_ZONE) )
+ {
+ RoutingMatrix.OrCell( row, col, BOTTOM, CELL_is_ZONE );
+ current_cell = CELL_is_ZONE;
+ nbpoints++;
+ }
+ }
+
+ pt_cell_V[row] = old_cell_H = current_cell;
+ }
+ }
+
+ // Search from bottom to top and left to right.
+ fill( pt_cell_V.begin(), pt_cell_V.end(), 0 );
+
+ for( col = 0; col < RoutingMatrix.m_Ncols; col++ )
+ {
+ old_cell_H = 0;
+
+ for( row = RoutingMatrix.m_Nrows - 1; row >= 0; row-- )
+ {
+ current_cell = RoutingMatrix.GetCell( row, col, BOTTOM ) & NO_CELL_ZONE;
+
+ if( current_cell == 0 ) // a free cell is found
+ {
+ if( (old_cell_H & CELL_is_ZONE) || (pt_cell_V[row] & CELL_is_ZONE) )
+ {
+ RoutingMatrix.OrCell( row, col, BOTTOM, CELL_is_ZONE );
+ current_cell = CELL_is_ZONE;
+ nbpoints++;
+ }
+ }
+
+ pt_cell_V[row] = old_cell_H = current_cell;
+ }
+ }
+
+ return nbpoints;
+}
diff --git a/pcbnew/autorouter/autorout.cpp b/pcbnew/autorouter/autorout.cpp
new file mode 100644
index 0000000..7c53f0e
--- /dev/null
+++ b/pcbnew/autorouter/autorout.cpp
@@ -0,0 +1,277 @@
+/**
+ * @file autorout.cpp
+ * @brief Autorouting command and control.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+#include <gr_basic.h>
+#include <msgpanel.h>
+
+#include <pcbnew.h>
+#include <cell.h>
+#include <zones.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <convert_to_biu.h>
+
+#include <autorout.h>
+
+
+MATRIX_ROUTING_HEAD RoutingMatrix; // routing matrix (grid) to route 2-sided boards
+
+/* init board, route traces*/
+void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode )
+{
+ int start, stop;
+ MODULE* Module = NULL;
+ D_PAD* Pad = NULL;
+ int autoroute_net_code = -1;
+ wxString msg;
+
+ if( GetBoard()->GetCopperLayerCount() > 1 )
+ {
+ g_Route_Layer_TOP = GetScreen()->m_Route_Layer_TOP;
+ g_Route_Layer_BOTTOM = GetScreen()->m_Route_Layer_BOTTOM;
+ }
+ else
+ {
+ g_Route_Layer_TOP = g_Route_Layer_BOTTOM = B_Cu;
+ }
+
+ switch( mode )
+ {
+ case ROUTE_NET:
+ if( GetScreen()->GetCurItem() )
+ {
+ switch( GetScreen()->GetCurItem()->Type() )
+ {
+ case PCB_PAD_T:
+ Pad = (D_PAD*) GetScreen()->GetCurItem();
+ autoroute_net_code = Pad->GetNetCode();
+ break;
+
+ default:
+ break;
+ }
+ }
+ if( autoroute_net_code <= 0 )
+ {
+ wxMessageBox( _( "Net not selected" ) ); return;
+ }
+ break;
+
+ case ROUTE_MODULE:
+ Module = (MODULE*) GetScreen()->GetCurItem();
+ if( (Module == NULL) || (Module->Type() != PCB_MODULE_T) )
+ {
+ wxMessageBox( _( "Footprint not selected" ) );
+ return;
+ }
+ break;
+
+ case ROUTE_PAD:
+ Pad = (D_PAD*) GetScreen()->GetCurItem();
+
+ if( (Pad == NULL) || (Pad->Type() != PCB_PAD_T) )
+ {
+ wxMessageBox( _( "Pad not selected" ) );
+ return;
+ }
+
+ break;
+ }
+
+ if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
+ Compile_Ratsnest( DC, true );
+
+ /* Set the flag on the ratsnest to CH_ROUTE_REQ. */
+ for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
+ {
+ RATSNEST_ITEM* ptmp = &GetBoard()->m_FullRatsnest[ii];
+ ptmp->m_Status &= ~CH_ROUTE_REQ;
+
+ switch( mode )
+ {
+ case ROUTE_ALL:
+ ptmp->m_Status |= CH_ROUTE_REQ;
+ break;
+
+ case ROUTE_NET:
+ if( autoroute_net_code == ptmp->GetNet() )
+ ptmp->m_Status |= CH_ROUTE_REQ;
+ break;
+
+ case ROUTE_MODULE:
+ {
+ D_PAD* pt_pad = (D_PAD*) Module->Pads();
+ for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
+ {
+ if( ptmp->m_PadStart == pt_pad )
+ ptmp->m_Status |= CH_ROUTE_REQ;
+
+ if( ptmp->m_PadEnd == pt_pad )
+ ptmp->m_Status |= CH_ROUTE_REQ;
+ }
+
+ break;
+ }
+
+ case ROUTE_PAD:
+ if( ( ptmp->m_PadStart == Pad ) || ( ptmp->m_PadEnd == Pad ) )
+ ptmp->m_Status |= CH_ROUTE_REQ;
+
+ break;
+ }
+ }
+
+ start = time( NULL );
+
+ /* Calculation of no fixed routing to 5 mils and more. */
+ RoutingMatrix.m_GridRouting = (int)GetScreen()->GetGridSize().x;
+
+ if( RoutingMatrix.m_GridRouting < (5*IU_PER_MILS) )
+ RoutingMatrix.m_GridRouting = 5*IU_PER_MILS;
+
+
+ /* Calculated ncol and nrow, matrix size for routing. */
+ RoutingMatrix.ComputeMatrixSize( GetBoard() );
+
+ m_messagePanel->EraseMsgBox();
+
+ /* Map the board */
+ RoutingMatrix.m_RoutingLayersCount = 1;
+
+ if( g_Route_Layer_TOP != g_Route_Layer_BOTTOM )
+ RoutingMatrix.m_RoutingLayersCount = 2;
+
+ if( RoutingMatrix.InitRoutingMatrix() < 0 )
+ {
+ wxMessageBox( _( "No memory for autorouting" ) );
+ RoutingMatrix.UnInitRoutingMatrix(); /* Free memory. */
+ return;
+ }
+
+ SetStatusText( _( "Place Cells" ) );
+ PlaceCells( GetBoard(), -1, FORCE_PADS );
+
+ /* Construction of the track list for router. */
+ RoutingMatrix.m_RouteCount = Build_Work( GetBoard() );
+
+ // DisplayRoutingMatrix( m_canvas, DC );
+
+ Solve( DC, RoutingMatrix.m_RoutingLayersCount );
+
+ /* Free memory. */
+ FreeQueue();
+ InitWork(); /* Free memory for the list of router connections. */
+ RoutingMatrix.UnInitRoutingMatrix();
+ stop = time( NULL ) - start;
+ msg.Printf( wxT( "time = %d second%s" ), stop, ( stop == 1 ) ? wxT( "" ) : wxT( "s" ) );
+ SetStatusText( msg );
+}
+
+
+/* Clear the flag CH_NOROUTABLE which is set to 1 by Solve(),
+ * when a track was not routed.
+ * (If this flag is 1 the corresponding track it is not rerouted)
+ */
+void PCB_EDIT_FRAME::Reset_Noroutable( wxDC* DC )
+{
+ if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK )== 0 )
+ Compile_Ratsnest( DC, true );
+
+ for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
+ {
+ GetBoard()->m_FullRatsnest[ii].m_Status &= ~CH_UNROUTABLE;
+ }
+}
+
+
+/* DEBUG Function: displays the routing matrix */
+void DisplayRoutingMatrix( EDA_DRAW_PANEL* panel, wxDC* DC )
+{
+ int dcell0;
+ EDA_COLOR_T color;
+
+ int maxi = 600 / RoutingMatrix.m_Ncols;
+ maxi = ( maxi * 3 ) / 4;
+
+ if( !maxi )
+ maxi = 1;
+
+ GRSetDrawMode( DC, GR_COPY );
+
+ for( int col = 0; col < RoutingMatrix.m_Ncols; col++ )
+ {
+ for( int row = 0; row < RoutingMatrix.m_Nrows; row++ )
+ {
+ color = BLACK;
+ dcell0 = RoutingMatrix.GetCell( row, col, BOTTOM );
+
+ if( dcell0 & HOLE )
+ color = GREEN;
+
+#if 0
+ int dcell1 = 0;
+
+ if( RoutingMatrix.m_RoutingLayersCount )
+ dcell1 = GetCell( row, col, TOP );
+
+ if( dcell1 & HOLE )
+ color = RED;
+
+ dcell0 |= dcell1;
+#endif
+ if( !color && ( dcell0 & VIA_IMPOSSIBLE ) )
+ color = BLUE;
+
+ if( dcell0 & CELL_is_EDGE )
+ color = YELLOW;
+ else if( dcell0 & CELL_is_ZONE )
+ color = YELLOW;
+
+ #define DRAW_OFFSET_X -20
+ #define DRAW_OFFSET_Y 20
+// if( color )
+ {
+ for( int i = 0; i < maxi; i++ )
+ for( int j = 0; j < maxi; j++ )
+ GRPutPixel( panel->GetClipBox(), DC,
+ ( col * maxi ) + i + DRAW_OFFSET_X,
+ ( row * maxi ) + j + DRAW_OFFSET_Y, color );
+
+ }
+ }
+ }
+}
diff --git a/pcbnew/autorouter/autorout.h b/pcbnew/autorouter/autorout.h
new file mode 100644
index 0000000..348191f
--- /dev/null
+++ b/pcbnew/autorouter/autorout.h
@@ -0,0 +1,236 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file autorout.h
+ */
+
+#ifndef AUTOROUT_H
+#define AUTOROUT_H
+
+
+#include <base_struct.h>
+#include <layers_id_colors_and_visibility.h>
+
+
+class BOARD;
+class DRAWSEGMENT;
+
+
+#define TOP 0
+#define BOTTOM 1
+#define EMPTY 0
+#define ILLEGAL -1
+
+
+/* Autorouter commands. */
+enum AUTOPLACEROUTE_OPTIONS
+{
+ PLACE_ALL,
+ PLACE_OUT_OF_BOARD,
+ PLACE_INCREMENTAL,
+ PLACE_1_MODULE,
+
+ ROUTE_ALL,
+ ROUTE_NET,
+ ROUTE_MODULE,
+ ROUTE_PAD
+};
+
+#define MAX_ROUTING_LAYERS_COUNT 2
+
+#define FORCE_PADS 1 /* Force placement of pads for any Netcode */
+
+/* search statistics */
+extern int OpenNodes; /* total number of nodes opened */
+extern int ClosNodes; /* total number of nodes closed */
+extern int MoveNodes; /* total number of nodes moved */
+extern int MaxNodes; /* maximum number of nodes opened at one time */
+
+
+/* Structures useful to the generation of board as bitmap. */
+typedef char MATRIX_CELL;
+typedef int DIST_CELL;
+typedef char DIR_CELL;
+
+
+/**
+ * class MATRIX_ROUTING_HEAD
+ * handle the matrix routing that describes the actual board
+ */
+class MATRIX_ROUTING_HEAD
+{
+public:
+ MATRIX_CELL* m_BoardSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides
+ DIST_CELL* m_DistSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
+ // distance to cells
+ DIR_CELL* m_DirSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
+ // pointers back to source
+ bool m_InitMatrixDone;
+ int m_RoutingLayersCount; // Number of layers for autorouting (0 or 1)
+ int m_GridRouting; // Size of grid for autoplace/autoroute
+ EDA_RECT m_BrdBox; // Actual board bounding box
+ int m_Nrows, m_Ncols; // Matrix size
+ int m_MemSize; // Memory requirement, just for statistics
+ int m_RouteCount; // Number of routes
+
+private:
+ // a pointer to the current selected cell operation
+ void (MATRIX_ROUTING_HEAD::* m_opWriteCell)( int aRow, int aCol,
+ int aSide, MATRIX_CELL aCell);
+
+public:
+ MATRIX_ROUTING_HEAD();
+ ~MATRIX_ROUTING_HEAD();
+
+ void WriteCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell)
+ {
+ (*this.*m_opWriteCell)( aRow, aCol, aSide, aCell );
+ }
+
+ /**
+ * function GetBrdCoordOrigin
+ * @return the board coordinate corresponding to the
+ * routing matrix origin ( board coordinate offset )
+ */
+ wxPoint GetBrdCoordOrigin()
+ {
+ return m_BrdBox.GetOrigin();
+ }
+
+ /**
+ * Function ComputeMatrixSize
+ * calculates the number of rows and columns of dimensions of \a aPcb for routing and
+ * automatic calculation of area.
+ * @param aPcb = the physical board
+ * @param aUseBoardEdgesOnly = true to use board edges only,
+ * = false to use the full board bounding box (default)
+ */
+ bool ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnly = false );
+
+ /**
+ * Function InitBoard
+ * initializes the data structures.
+ *
+ * @return the amount of memory used or -1 if default.
+ */
+ int InitRoutingMatrix();
+
+ void UnInitRoutingMatrix();
+
+ // Initialize WriteCell to make the aLogicOp
+ void SetCellOperation( int aLogicOp );
+
+ // functions to read/write one cell ( point on grid routing matrix:
+ MATRIX_CELL GetCell( int aRow, int aCol, int aSide);
+ void SetCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
+ void OrCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
+ void XorCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
+ void AndCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
+ void AddCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
+ DIST_CELL GetDist( int aRow, int aCol, int aSide );
+ void SetDist( int aRow, int aCol, int aSide, DIST_CELL );
+ int GetDir( int aRow, int aCol, int aSide );
+ void SetDir( int aRow, int aCol, int aSide, int aDir);
+
+ // calculate distance (with penalty) of a trace through a cell
+ int CalcDist(int x,int y,int z ,int side );
+
+ // calculate approximate distance (manhattan distance)
+ int GetApxDist( int r1, int c1, int r2, int c2 );
+};
+
+extern MATRIX_ROUTING_HEAD RoutingMatrix; /* 2-sided board */
+
+
+/* Constants used to trace the cells on the BOARD */
+#define WRITE_CELL 0
+#define WRITE_OR_CELL 1
+#define WRITE_XOR_CELL 2
+#define WRITE_AND_CELL 3
+#define WRITE_ADD_CELL 4
+
+// Functions:
+
+class PCB_EDIT_FRAME;
+class BOARD;
+class D_PAD;
+class RATSNEST_ITEM;
+class TRACK;
+
+
+/* Initialize a color value, the cells included in the board edge of the
+ * pad surface by pt_pad, with the margin reserved for isolation and the
+ * half width of the runway
+ * Parameters:
+ * Pt_pad: pointer to the description of the pad
+ * color: mask write in cells
+ * margin: add a value to the radius or half the score pad
+ * op_logic: type of writing in the cell (WRITE, OR)
+ */
+void PlacePad( D_PAD* pt_pad, int type, int marge, int op_logic );
+
+/* Draws a segment of track on the board. */
+void TraceSegmentPcb( TRACK* pt_segm, int type, int marge, int op_logic );
+void TraceSegmentPcb( DRAWSEGMENT* pt_segm, int type, int marge, int op_logic );
+
+/* Uses the color value of all cells included in the board
+ * coord of the rectangle ux0, uy0 (top right corner)
+ * a ux1, uy1 (lower left corner) (coord PCB)
+ * the rectangle is horizontal (or vertical)
+ * masque_layer = mask layers;
+ * op_logic = WRITE_CELL, WRITE_OR_CELL, WRITE_XOR_CELL, WRITE_AND_CELL
+ */
+void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
+ LSET side, int color, int op_logic);
+
+
+/* Same as above, but the rectangle is inclined angle angle. */
+void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
+ double angle, LSET masque_layer,
+ int color, int op_logic );
+
+/* QUEUE.CPP */
+void FreeQueue();
+void InitQueue();
+void GetQueue( int *, int *, int *, int *, int * );
+bool SetQueue( int, int, int, int, int, int, int );
+void ReSetQueue( int, int, int, int, int, int, int );
+
+/* WORK.CPP */
+void InitWork();
+void ReInitWork();
+int SetWork( int, int, int , int, int, RATSNEST_ITEM *, int );
+void GetWork( int *, int *, int *, int *, int *, RATSNEST_ITEM ** );
+void SortWork(); /* order the work items; shortest first */
+
+/* routing_matrix.cpp */
+int Build_Work( BOARD * Pcb );
+void PlaceCells( BOARD * Pcb, int net_code, int flag = 0 );
+
+
+#endif // AUTOROUT_H
diff --git a/pcbnew/autorouter/cell.h b/pcbnew/autorouter/cell.h
new file mode 100644
index 0000000..63b76ae
--- /dev/null
+++ b/pcbnew/autorouter/cell.h
@@ -0,0 +1,116 @@
+/**
+ * @file cell.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * First copyright (C) Randy Nevin, 1989 (see PCBCA package)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef _CELL_H_
+#define _CELL_H_
+
+
+/* Bits characterizing cell */
+#define HOLE 0x01 /* a conducting hole or obstacle */
+#define CELL_is_MODULE 0x02 /* auto placement occupied by a module */
+#define CELL_is_EDGE 0x20 /* Area and auto-placement: limiting cell contour (Board, Zone) */
+#define CELL_is_FRIEND 0x40 /* Area and auto-placement: cell part of the net */
+#define CELL_is_ZONE 0x80 /* Area and auto-placement: cell available */
+
+/* Bit masks for presence of obstacles to autorouting */
+#define OCCUPE 1 /* Autorouting: obstacle tracks and vias. */
+#define VIA_IMPOSSIBLE 2 /* Autorouting: obstacle for vias. */
+#define CURRENT_PAD 4
+
+
+/* traces radiating outward from a hole to a side or corner */
+#define HOLE_NORTH 0x00000002L /* upward */
+#define HOLE_NORTHEAST 0x00000004L /* upward and right */
+#define HOLE_EAST 0x00000008L /* to the right */
+#define HOLE_SOUTHEAST 0x00000010L /* downward and right */
+#define HOLE_SOUTH 0x00000020L /* downward */
+#define HOLE_SOUTHWEST 0x00000040L /* downward and left */
+#define HOLE_WEST 0x00000080L /* to the left */
+#define HOLE_NORTHWEST 0x00000100L /* upward and left */
+
+/* straight lines through the center */
+#define LINE_HORIZONTAL 0x00000002L /* left-to-right line */
+#define LINE_VERTICAL 0x00000004L /* top-to-bottom line */
+
+/* lines cutting across a corner, connecting adjacent sides */
+#define CORNER_NORTHEAST 0x00000008L /* upper right corner */
+#define CORNER_SOUTHEAST 0x00000010L /* lower right corner */
+#define CORNER_SOUTHWEST 0x00000020L /* lower left corner */
+#define CORNER_NORTHWEST 0x00000040L /* upper left corner */
+
+/* diagonal lines through the center */
+#define DIAG_NEtoSW 0x00000080L /* northeast to southwest */
+#define DIAG_SEtoNW 0x00000100L /* southeast to northwest */
+
+/* 135 degree angle side-to-far-corner lines */
+#define BENT_NtoSE 0x00000200L /* north to southeast */
+#define BENT_NtoSW 0x00000400L /* north to southwest */
+#define BENT_EtoSW 0x00000800L /* east to southwest */
+#define BENT_EtoNW 0x00001000L /* east to northwest */
+#define BENT_StoNW 0x00002000L /* south to northwest */
+#define BENT_StoNE 0x00004000L /* south to northeast */
+#define BENT_WtoNE 0x00008000L /* west to northeast */
+#define BENT_WtoSE 0x00010000L /* west to southeast */
+
+/* 90 degree corner-to-adjacent-corner lines */
+#define ANGLE_NEtoSE 0x00020000L /* northeast to southeast */
+#define ANGLE_SEtoSW 0x00040000L /* southeast to southwest */
+#define ANGLE_SWtoNW 0x00080000L /* southwest to northwest */
+#define ANGLE_NWtoNE 0x00100000L /* northwest to northeast */
+
+/* 45 degree angle side-to-near-corner lines */
+#define SHARP_NtoNE 0x00200000L /* north to northeast */
+#define SHARP_EtoNE 0x00400000L /* east to northeast */
+#define SHARP_EtoSE 0x00800000L /* east to southeast */
+#define SHARP_StoSE 0x01000000L /* south to southeast */
+#define SHARP_StoSW 0x02000000L /* south to southwest */
+#define SHARP_WtoSW 0x04000000L /* west to southwest */
+#define SHARP_WtoNW 0x08000000L /* west to northwest */
+#define SHARP_NtoNW 0x10000000L /* north to northwest */
+
+/* directions the cell can be reached from (point to previous cell) */
+#define FROM_NOWHERE 0
+#define FROM_NORTH 1
+#define FROM_NORTHEAST 2
+#define FROM_EAST 3
+#define FROM_SOUTHEAST 4
+#define FROM_SOUTH 5
+#define FROM_SOUTHWEST 6
+#define FROM_WEST 7
+#define FROM_NORTHWEST 8
+#define FROM_OTHERSIDE 9
+
+
+#endif // _CELL_H_
+
diff --git a/pcbnew/autorouter/dist.cpp b/pcbnew/autorouter/dist.cpp
new file mode 100644
index 0000000..5841073
--- /dev/null
+++ b/pcbnew/autorouter/dist.cpp
@@ -0,0 +1,171 @@
+/**
+ * @file dist.cpp
+ * @brief Routines to calculate PCB editor auto routing distances.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * First copyright (C) Randy Nevin, 1989 (see PCBCA package)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include <autorout.h>
+#include <cell.h>
+
+
+/* The tables of distances and keep out areas are established on the basis of a
+ * 50 units grid size (the pitch between the cells is 50 units).
+ * The actual distance could be computed by a scaling factor, but this is
+ * not needed, we can use only reduced values
+ */
+
+ /* calculate approximate distance (manhattan distance)
+ */
+int MATRIX_ROUTING_HEAD::GetApxDist( int r1, int c1, int r2, int c2 )
+{
+ int d1, d2; /* row and column deltas */
+
+ if( ( d1 = r1 - r2 ) < 0 ) /* get absolute row delta */
+ d1 = -d1;
+
+ if( ( d2 = c1 - c2 ) < 0 ) /* get absolute column delta */
+ d2 = -d2;
+
+ return ( d1+d2 ) * 50;
+}
+
+
+/* distance to go thru a cell (en mils) */
+static const int dist[10][10] =
+{ /* OT=Otherside, OR=Origin (source) cell */
+/*..........N, NE, E, SE, S, SW, W, NW, OT, OR */
+/* N */ { 50, 60, 35, 60, 99, 60, 35, 60, 12, 12 },
+/* NE */ { 60, 71, 60, 71, 60, 99, 60, 71, 23, 23 },
+/* E */ { 35, 60, 50, 60, 35, 60, 99, 60, 12, 12 },
+/* SE */ { 60, 71, 60, 71, 60, 71, 60, 99, 23, 23 },
+/* S */ { 99, 60, 35, 60, 50, 60, 35, 60, 12, 12 },
+/* SW */ { 60, 99, 60, 71, 60, 71, 60, 71, 23, 23 },
+/* W */ { 35, 60, 99, 60, 35, 60, 50, 60, 12, 12 },
+/* NW */ { 60, 71, 60, 99, 60, 71, 60, 71, 23, 23 },
+
+/* OT */ { 12, 23, 12, 23, 12, 23, 12, 23, 99, 99 },
+/* OR */ { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }
+};
+
+/* penalty for extraneous holes and corners, scaled by sharpness of turn */
+static const int penalty[10][10] =
+{ /* OT=Otherside, OR=Origin (source) cell */
+/*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
+/* N */ { 0, 5, 10, 15, 20, 15, 10, 5, 50, 0 },
+/* NE */ { 5, 0, 5, 10, 15, 20, 15, 10, 50, 0 },
+/* E */ { 10, 5, 0, 5, 10, 15, 20, 15, 50, 0 },
+/* SE */ { 15, 10, 5, 0, 5, 10, 15, 20, 50, 0 },
+/* S */ { 20, 15, 10, 5, 0, 5, 10, 15, 50, 0 },
+/* SW */ { 15, 20, 15, 10, 5, 0, 5, 10, 50, 0 },
+/* W */ { 10, 15, 20, 15, 10, 5, 0, 5, 50, 0 },
+/* NW */ { 5, 10, 15, 20, 15, 10, 5, 0, 50, 0 },
+
+/* OT */ { 50, 50, 50, 50, 50, 50, 50, 50, 100, 0 },
+/* OR */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+};
+
+/* penalty pour directions preferencielles */
+#define PN 20
+static const int dir_penalty_TOP[10][10] =
+{
+/* OT=Otherside, OR=Origin (source) cell */
+/*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
+/* N */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
+/* NE */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
+/* E */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
+/* SE */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
+/* S */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
+/* SW */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
+/* W */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
+/* NW */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
+
+/* OT */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
+/* OR */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 }
+};
+
+static int dir_penalty_BOTTOM[10][10] =
+{
+/* OT=Otherside, OR=Origin (source) cell */
+/*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
+/* N */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
+/* NE */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
+/* E */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
+/* SE */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
+/* S */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
+/* SW */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
+/* W */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
+/* NW */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
+
+/* OT */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
+/* OR */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 }
+};
+
+/*
+** x is the direction to enter the cell of interest.
+** y is the direction to exit the cell of interest.
+** z is the direction to really exit the cell, if y=FROM_OTHERSIDE.
+**
+** return the distance of the trace through the cell of interest.
+** the calculation is driven by the tables above.
+*/
+
+
+/* calculate distance (with penalty) of a trace through a cell
+*/
+int MATRIX_ROUTING_HEAD::CalcDist(int x,int y,int z ,int side )
+{
+ int adjust, ldist;
+
+ adjust = 0; /* set if hole is encountered */
+
+ if( x == EMPTY )
+ x = 10;
+
+ if( y == EMPTY )
+ {
+ y = 10;
+ }
+ else if( y == FROM_OTHERSIDE )
+ {
+ if( z == EMPTY )
+ z = 10;
+
+ adjust = penalty[x-1][z-1];
+ }
+
+ ldist = dist[x-1][y-1] + penalty[x-1][y-1] + adjust;
+
+ if( m_RouteCount > 1 )
+ {
+ if( side == BOTTOM )
+ ldist += dir_penalty_TOP[x-1][y-1];
+
+ if( side == TOP )
+ ldist += dir_penalty_BOTTOM[x-1][y-1];
+ }
+
+ return ldist * 10;
+}
diff --git a/pcbnew/autorouter/graphpcb.cpp b/pcbnew/autorouter/graphpcb.cpp
new file mode 100644
index 0000000..840bfcb
--- /dev/null
+++ b/pcbnew/autorouter/graphpcb.cpp
@@ -0,0 +1,843 @@
+/**
+ * @file graphpcb.cpp
+ * @brief PCB editor autorouting and "graphics" routines.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <macros.h>
+#include <trigo.h>
+#include <math_for_graphics.h>
+#include <class_board.h>
+#include <class_track.h>
+#include <class_drawsegment.h>
+
+#include <pcbnew.h>
+#include <autorout.h>
+#include <cell.h>
+
+void TracePcbLine( int x0, int y0, int x1, int y1, LAYER_NUM layer, int color );
+
+void TraceArc( int ux0, int uy0,
+ int ux1, int uy1,
+ double ArcAngle,
+ int lg, LAYER_NUM layer, int color,
+ int op_logic );
+
+
+static void DrawSegmentQcq( int ux0, int uy0,
+ int ux1, int uy1,
+ int lg, LAYER_NUM layer, int color,
+ int op_logic );
+
+static void TraceFilledCircle( int cx, int cy, int radius,
+ LSET aLayerMask,
+ int color,
+ int op_logic );
+
+static void TraceCircle( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer,
+ int color, int op_logic );
+
+// Macro call to update cell.
+#define OP_CELL( layer, dy, dx ) \
+ { \
+ if( layer == UNDEFINED_LAYER ) \
+ { \
+ RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \
+ if( RoutingMatrix.m_RoutingLayersCount > 1 ) \
+ RoutingMatrix.WriteCell( dy, dx, TOP, color ); \
+ } \
+ else \
+ { \
+ if( layer == g_Route_Layer_BOTTOM ) \
+ RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \
+ if( RoutingMatrix.m_RoutingLayersCount > 1 ) \
+ if( layer == g_Route_Layer_TOP ) \
+ RoutingMatrix.WriteCell( dy, dx, TOP, color ); \
+ } \
+ }
+
+void PlacePad( D_PAD* aPad, int color, int marge, int op_logic )
+{
+ int dx, dy;
+ wxPoint shape_pos = aPad->ShapePos();
+
+ dx = aPad->GetSize().x / 2;
+ dx += marge;
+
+ if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
+ {
+ TraceFilledCircle( shape_pos.x, shape_pos.y, dx,
+ aPad->GetLayerSet(), color, op_logic );
+ return;
+ }
+
+ dy = aPad->GetSize().y / 2;
+ dy += marge;
+
+ if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID )
+ {
+ dx += abs( aPad->GetDelta().y ) / 2;
+ dy += abs( aPad->GetDelta().x ) / 2;
+ }
+
+ // The pad is a rectangle ( horizontal or vertical )
+ if( int( aPad->GetOrientation() ) % 900 == 0 )
+ {
+ // Orientation turned 90 deg.
+ if( aPad->GetOrientation() == 900 || aPad->GetOrientation() == 2700 )
+ {
+ std::swap( dx, dy );
+ }
+
+ TraceFilledRectangle( shape_pos.x - dx, shape_pos.y - dy,
+ shape_pos.x + dx, shape_pos.y + dy,
+ aPad->GetLayerSet(), color, op_logic );
+ }
+ else
+ {
+ TraceFilledRectangle( shape_pos.x - dx, shape_pos.y - dy,
+ shape_pos.x + dx, shape_pos.y + dy,
+ aPad->GetOrientation(),
+ aPad->GetLayerSet(), color, op_logic );
+ }
+}
+
+
+/* Set to color the cells included in the circle
+ * Parameters:
+ * center: cx, cy.
+ * radius: a value add to the radius or half the score pad
+ * aLayerMask: layer occupied
+ * color: mask write in cells
+ * op_logic: type of writing in the cell (WRITE, OR)
+ */
+void TraceFilledCircle( int cx, int cy, int radius,
+ LSET aLayerMask, int color, int op_logic )
+{
+ int row, col;
+ int ux0, uy0, ux1, uy1;
+ int row_max, col_max, row_min, col_min;
+ int trace = 0;
+ double fdistmin, fdistx, fdisty;
+ int tstwrite = 0;
+ int distmin;
+
+ if( aLayerMask[g_Route_Layer_BOTTOM] )
+ trace = 1; // Trace on BOTTOM
+
+ if( aLayerMask[g_Route_Layer_TOP] )
+ if( RoutingMatrix.m_RoutingLayersCount > 1 )
+ trace |= 2; // Trace on TOP
+
+ if( trace == 0 )
+ return;
+
+ RoutingMatrix.SetCellOperation( op_logic );
+
+ cx -= RoutingMatrix.GetBrdCoordOrigin().x;
+ cy -= RoutingMatrix.GetBrdCoordOrigin().y;
+
+ distmin = radius;
+
+ // Calculate the bounding rectangle of the circle.
+ ux0 = cx - radius;
+ uy0 = cy - radius;
+ ux1 = cx + radius;
+ uy1 = cy + radius;
+
+ // Calculate limit coordinates of cells belonging to the rectangle.
+ row_max = uy1 / RoutingMatrix.m_GridRouting;
+ col_max = ux1 / RoutingMatrix.m_GridRouting;
+ row_min = uy0 / RoutingMatrix.m_GridRouting; // if (uy0 > row_min*Board.m_GridRouting) row_min++;
+ col_min = ux0 / RoutingMatrix.m_GridRouting; // if (ux0 > col_min*Board.m_GridRouting) col_min++;
+
+ if( row_min < 0 )
+ row_min = 0;
+
+ if( row_max >= (RoutingMatrix.m_Nrows - 1) )
+ row_max = RoutingMatrix.m_Nrows - 1;
+
+ if( col_min < 0 )
+ col_min = 0;
+
+ if( col_max >= (RoutingMatrix.m_Ncols - 1) )
+ col_max = RoutingMatrix.m_Ncols - 1;
+
+ // Calculate coordinate limits of cell belonging to the rectangle.
+ if( row_min > row_max )
+ row_max = row_min;
+
+ if( col_min > col_max )
+ col_max = col_min;
+
+ fdistmin = (double) distmin * distmin;
+
+ for( row = row_min; row <= row_max; row++ )
+ {
+ fdisty = (double) ( cy - ( row * RoutingMatrix.m_GridRouting ) );
+ fdisty *= fdisty;
+
+ for( col = col_min; col <= col_max; col++ )
+ {
+ fdistx = (double) ( cx - ( col * RoutingMatrix.m_GridRouting ) );
+ fdistx *= fdistx;
+
+ if( fdistmin <= ( fdistx + fdisty ) )
+ continue;
+
+ if( trace & 1 )
+ RoutingMatrix.WriteCell( row, col, BOTTOM, color );
+
+ if( trace & 2 )
+ RoutingMatrix.WriteCell( row, col, TOP, color );
+
+ tstwrite = 1;
+ }
+ }
+
+ if( tstwrite )
+ return;
+
+ /* If no cell has been written, it affects the 4 neighboring diagonal
+ * (Adverse event: pad off grid in the center of the 4 neighboring
+ * diagonal) */
+ distmin = RoutingMatrix.m_GridRouting / 2 + 1;
+ fdistmin = ( (double) distmin * distmin ) * 2; // Distance to center point diagonally
+
+ for( row = row_min; row <= row_max; row++ )
+ {
+ fdisty = (double) ( cy - ( row * RoutingMatrix.m_GridRouting ) );
+ fdisty *= fdisty;
+
+ for( col = col_min; col <= col_max; col++ )
+ {
+ fdistx = (double) ( cx - ( col * RoutingMatrix.m_GridRouting ) );
+ fdistx *= fdistx;
+
+ if( fdistmin <= ( fdistx + fdisty ) )
+ continue;
+
+ if( trace & 1 )
+ RoutingMatrix.WriteCell( row, col, BOTTOM, color );
+
+ if( trace & 2 )
+ RoutingMatrix.WriteCell( row, col, TOP, color );
+ }
+ }
+}
+
+void TraceSegmentPcb( DRAWSEGMENT* pt_segm, int color, int marge, int op_logic )
+{
+ int half_width = ( pt_segm->GetWidth() / 2 ) + marge;
+
+ // Calculate the bounding rectangle of the segment (if H, V or Via)
+ int ux0 = pt_segm->GetStart().x - RoutingMatrix.GetBrdCoordOrigin().x;
+ int uy0 = pt_segm->GetStart().y - RoutingMatrix.GetBrdCoordOrigin().y;
+ int ux1 = pt_segm->GetEnd().x - RoutingMatrix.GetBrdCoordOrigin().x;
+ int uy1 = pt_segm->GetEnd().y - RoutingMatrix.GetBrdCoordOrigin().y;
+
+ LAYER_NUM layer = pt_segm->GetLayer();
+
+ if( color == VIA_IMPOSSIBLE )
+ layer = UNDEFINED_LAYER;
+
+ switch( pt_segm->GetShape() )
+ {
+ // The segment is here a straight line or a circle or an arc.:
+ case S_CIRCLE:
+ TraceCircle( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic );
+ break;
+
+ case S_ARC:
+ TraceArc( ux0, uy0, ux1, uy1, pt_segm->GetAngle(), half_width, layer, color, op_logic );
+ break;
+
+ // The segment is here a line segment.
+ default:
+ DrawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic );
+ break;
+ }
+}
+
+void TraceSegmentPcb( TRACK* aTrack, int color, int marge, int op_logic )
+{
+ int half_width = ( aTrack->GetWidth() / 2 ) + marge;
+
+ // Test if VIA (filled circle need to be drawn)
+ if( aTrack->Type() == PCB_VIA_T )
+ {
+ LSET layer_mask;
+
+ if( aTrack->IsOnLayer( g_Route_Layer_BOTTOM ) )
+ layer_mask.set( g_Route_Layer_BOTTOM );
+
+ if( aTrack->IsOnLayer( g_Route_Layer_TOP ) )
+ {
+ if( !layer_mask.any() )
+ layer_mask = LSET( g_Route_Layer_TOP );
+ else
+ layer_mask.set();
+ }
+
+ if( color == VIA_IMPOSSIBLE )
+ layer_mask.set();
+
+ if( layer_mask.any() )
+ TraceFilledCircle( aTrack->GetStart().x, aTrack->GetStart().y,
+ half_width, layer_mask, color, op_logic );
+ }
+ else
+ {
+ // Calculate the bounding rectangle of the segment
+ int ux0 = aTrack->GetStart().x - RoutingMatrix.GetBrdCoordOrigin().x;
+ int uy0 = aTrack->GetStart().y - RoutingMatrix.GetBrdCoordOrigin().y;
+ int ux1 = aTrack->GetEnd().x - RoutingMatrix.GetBrdCoordOrigin().x;
+ int uy1 = aTrack->GetEnd().y - RoutingMatrix.GetBrdCoordOrigin().y;
+
+ // Ordinary track
+ LAYER_ID layer = aTrack->GetLayer();
+
+ if( color == VIA_IMPOSSIBLE )
+ layer = UNDEFINED_LAYER;
+
+ DrawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic );
+ }
+}
+
+
+/* Draws a line, if layer = -1 on all layers
+ */
+void TracePcbLine( int x0, int y0, int x1, int y1, LAYER_NUM layer, int color, int op_logic )
+{
+ int dx, dy, lim;
+ int cumul, inc, il, delta;
+
+ RoutingMatrix.SetCellOperation( op_logic );
+
+ if( x0 == x1 ) // Vertical.
+ {
+ if( y1 < y0 )
+ std::swap( y0, y1 );
+
+ dy = y0 / RoutingMatrix.m_GridRouting;
+ lim = y1 / RoutingMatrix.m_GridRouting;
+ dx = x0 / RoutingMatrix.m_GridRouting;
+
+ // Clipping limits of board.
+ if( ( dx < 0 ) || ( dx >= RoutingMatrix.m_Ncols ) )
+ return;
+
+ if( dy < 0 )
+ dy = 0;
+
+ if( lim >= RoutingMatrix.m_Nrows )
+ lim = RoutingMatrix.m_Nrows - 1;
+
+ for( ; dy <= lim; dy++ )
+ {
+ OP_CELL( layer, dy, dx );
+ }
+
+ return;
+ }
+
+ if( y0 == y1 ) // Horizontal
+ {
+ if( x1 < x0 )
+ std::swap( x0, x1 );
+
+ dx = x0 / RoutingMatrix.m_GridRouting;
+ lim = x1 / RoutingMatrix.m_GridRouting;
+ dy = y0 / RoutingMatrix.m_GridRouting;
+
+ // Clipping limits of board.
+ if( ( dy < 0 ) || ( dy >= RoutingMatrix.m_Nrows ) )
+ return;
+
+ if( dx < 0 )
+ dx = 0;
+
+ if( lim >= RoutingMatrix.m_Ncols )
+ lim = RoutingMatrix.m_Ncols - 1;
+
+ for( ; dx <= lim; dx++ )
+ {
+ OP_CELL( layer, dy, dx );
+ }
+
+ return;
+ }
+
+ // Here is some perspective: using the algorithm LUCAS.
+ if( abs( x1 - x0 ) >= abs( y1 - y0 ) ) // segment slightly inclined/
+ {
+ if( x1 < x0 )
+ {
+ std::swap( x1, x0 );
+ std::swap( y1, y0 );
+ }
+
+ dx = x0 / RoutingMatrix.m_GridRouting;
+ lim = x1 / RoutingMatrix.m_GridRouting;
+ dy = y0 / RoutingMatrix.m_GridRouting;
+ inc = 1;
+
+ if( y1 < y0 )
+ inc = -1;
+
+ il = lim - dx; cumul = il / 2;
+ delta = abs( y1 - y0 ) / RoutingMatrix.m_GridRouting;
+
+ for( ; dx <= lim; )
+ {
+ if( ( dx >= 0 ) && ( dy >= 0 ) &&
+ ( dx < RoutingMatrix.m_Ncols ) &&
+ ( dy < RoutingMatrix.m_Nrows ) )
+ {
+ OP_CELL( layer, dy, dx );
+ }
+
+ dx++;
+ cumul += delta;
+
+ if( cumul > il )
+ {
+ cumul -= il;
+ dy += inc;
+ }
+ }
+ }
+ else
+ {
+ if( y1 < y0 )
+ {
+ std::swap( x1, x0 );
+ std::swap( y1, y0 );
+ }
+
+ dy = y0 / RoutingMatrix.m_GridRouting;
+ lim = y1 / RoutingMatrix.m_GridRouting;
+ dx = x0 / RoutingMatrix.m_GridRouting;
+ inc = 1;
+
+ if( x1 < x0 )
+ inc = -1;
+
+ il = lim - dy;
+ cumul = il / 2;
+ delta = abs( x1 - x0 ) / RoutingMatrix.m_GridRouting;
+
+ for( ; dy <= lim; )
+ {
+ if( ( dx >= 0 ) && ( dy >= 0 ) && ( dx < RoutingMatrix.m_Ncols ) && ( dy < RoutingMatrix.m_Nrows ) )
+ {
+ OP_CELL( layer, dy, dx );
+ }
+
+ dy++;
+ cumul += delta;
+
+ if( cumul > il )
+ {
+ cumul -= il;
+ dx += inc;
+ }
+ }
+ }
+}
+
+
+void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
+ LSET aLayerMask, int color, int op_logic )
+{
+ int row, col;
+ int row_min, row_max, col_min, col_max;
+ int trace = 0;
+
+ if( aLayerMask[g_Route_Layer_BOTTOM] )
+ trace = 1; // Trace on BOTTOM
+
+ if( aLayerMask[g_Route_Layer_TOP] && RoutingMatrix.m_RoutingLayersCount > 1 )
+ trace |= 2; // Trace on TOP
+
+ if( trace == 0 )
+ return;
+
+ RoutingMatrix.SetCellOperation( op_logic );
+
+ ux0 -= RoutingMatrix.GetBrdCoordOrigin().x;
+ uy0 -= RoutingMatrix.GetBrdCoordOrigin().y;
+ ux1 -= RoutingMatrix.GetBrdCoordOrigin().x;
+ uy1 -= RoutingMatrix.GetBrdCoordOrigin().y;
+
+ // Calculating limits coord cells belonging to the rectangle.
+ row_max = uy1 / RoutingMatrix.m_GridRouting;
+ col_max = ux1 / RoutingMatrix.m_GridRouting;
+ row_min = uy0 / RoutingMatrix.m_GridRouting;
+
+ if( uy0 > row_min * RoutingMatrix.m_GridRouting )
+ row_min++;
+
+ col_min = ux0 / RoutingMatrix.m_GridRouting;
+
+ if( ux0 > col_min * RoutingMatrix.m_GridRouting )
+ col_min++;
+
+ if( row_min < 0 )
+ row_min = 0;
+
+ if( row_max >= ( RoutingMatrix.m_Nrows - 1 ) )
+ row_max = RoutingMatrix.m_Nrows - 1;
+
+ if( col_min < 0 )
+ col_min = 0;
+
+ if( col_max >= ( RoutingMatrix.m_Ncols - 1 ) )
+ col_max = RoutingMatrix.m_Ncols - 1;
+
+ for( row = row_min; row <= row_max; row++ )
+ {
+ for( col = col_min; col <= col_max; col++ )
+ {
+ if( trace & 1 )
+ RoutingMatrix.WriteCell( row, col, BOTTOM, color );
+
+ if( trace & 2 )
+ RoutingMatrix.WriteCell( row, col, TOP, color );
+ }
+ }
+}
+
+
+void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
+ double angle, LSET aLayerMask, int color, int op_logic )
+{
+ int row, col;
+ int cx, cy; // Center of rectangle
+ int radius; // Radius of the circle
+ int row_min, row_max, col_min, col_max;
+ int rotrow, rotcol;
+ int trace = 0;
+
+ if( aLayerMask[g_Route_Layer_BOTTOM] )
+ trace = 1; // Trace on BOTTOM
+
+ if( aLayerMask[g_Route_Layer_TOP] )
+ {
+ if( RoutingMatrix.m_RoutingLayersCount > 1 )
+ trace |= 2; // Trace on TOP
+ }
+
+ if( trace == 0 )
+ return;
+
+ RoutingMatrix.SetCellOperation( op_logic );
+
+ ux0 -= RoutingMatrix.GetBrdCoordOrigin().x;
+ uy0 -= RoutingMatrix.GetBrdCoordOrigin().y;
+ ux1 -= RoutingMatrix.GetBrdCoordOrigin().x;
+ uy1 -= RoutingMatrix.GetBrdCoordOrigin().y;
+
+ cx = (ux0 + ux1) / 2;
+ cy = (uy0 + uy1) / 2;
+ radius = KiROUND( Distance( ux0, uy0, cx, cy ) );
+
+ // Calculating coordinate limits belonging to the rectangle.
+ row_max = ( cy + radius ) / RoutingMatrix.m_GridRouting;
+ col_max = ( cx + radius ) / RoutingMatrix.m_GridRouting;
+ row_min = ( cy - radius ) / RoutingMatrix.m_GridRouting;
+
+ if( uy0 > row_min * RoutingMatrix.m_GridRouting )
+ row_min++;
+
+ col_min = ( cx - radius ) / RoutingMatrix.m_GridRouting;
+
+ if( ux0 > col_min * RoutingMatrix.m_GridRouting )
+ col_min++;
+
+ if( row_min < 0 )
+ row_min = 0;
+
+ if( row_max >= ( RoutingMatrix.m_Nrows - 1 ) )
+ row_max = RoutingMatrix.m_Nrows - 1;
+
+ if( col_min < 0 )
+ col_min = 0;
+
+ if( col_max >= ( RoutingMatrix.m_Ncols - 1 ) )
+ col_max = RoutingMatrix.m_Ncols - 1;
+
+ for( row = row_min; row <= row_max; row++ )
+ {
+ for( col = col_min; col <= col_max; col++ )
+ {
+ rotrow = row * RoutingMatrix.m_GridRouting;
+ rotcol = col * RoutingMatrix.m_GridRouting;
+ RotatePoint( &rotcol, &rotrow, cx, cy, -angle );
+
+ if( rotrow <= uy0 )
+ continue;
+
+ if( rotrow >= uy1 )
+ continue;
+
+ if( rotcol <= ux0 )
+ continue;
+
+ if( rotcol >= ux1 )
+ continue;
+
+ if( trace & 1 )
+ RoutingMatrix.WriteCell( row, col, BOTTOM, color );
+
+ if( trace & 2 )
+ RoutingMatrix.WriteCell( row, col, TOP, color );
+ }
+ }
+}
+
+
+/* Fills all cells inside a segment
+ * half-width = lg, org = ux0,uy0 end = ux1,uy1
+ * coordinates are in PCB units
+ */
+void DrawSegmentQcq( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer,
+ int color, int op_logic )
+{
+ int row, col;
+ int inc;
+ int row_max, col_max, row_min, col_min;
+ int demi_pas;
+
+ int cx, cy, dx, dy;
+
+ RoutingMatrix.SetCellOperation( op_logic );
+
+ // Make coordinate ux1 tj > ux0 to simplify calculations
+ if( ux1 < ux0 )
+ {
+ std::swap( ux1, ux0 );
+ std::swap( uy1, uy0 );
+ }
+
+ // Calculating the incrementing the Y axis
+ inc = 1;
+
+ if( uy1 < uy0 )
+ inc = -1;
+
+ demi_pas = RoutingMatrix.m_GridRouting / 2;
+
+ col_min = ( ux0 - lg ) / RoutingMatrix.m_GridRouting;
+
+ if( col_min < 0 )
+ col_min = 0;
+
+ col_max = ( ux1 + lg + demi_pas ) / RoutingMatrix.m_GridRouting;
+
+ if( col_max > ( RoutingMatrix.m_Ncols - 1 ) )
+ col_max = RoutingMatrix.m_Ncols - 1;
+
+ if( inc > 0 )
+ {
+ row_min = ( uy0 - lg ) / RoutingMatrix.m_GridRouting;
+ row_max = ( uy1 + lg + demi_pas ) / RoutingMatrix.m_GridRouting;
+ }
+ else
+ {
+ row_min = ( uy1 - lg ) / RoutingMatrix.m_GridRouting;
+ row_max = ( uy0 + lg + demi_pas ) / RoutingMatrix.m_GridRouting;
+ }
+
+ if( row_min < 0 )
+ row_min = 0;
+
+ if( row_min > ( RoutingMatrix.m_Nrows - 1 ) )
+ row_min = RoutingMatrix.m_Nrows - 1;
+
+ if( row_max < 0 )
+ row_max = 0;
+
+ if( row_max > ( RoutingMatrix.m_Nrows - 1 ) )
+ row_max = RoutingMatrix.m_Nrows - 1;
+
+ dx = ux1 - ux0;
+ dy = uy1 - uy0;
+
+ double angle;
+ if( dx )
+ {
+ angle = ArcTangente( dy, dx );
+ }
+ else
+ {
+ angle = 900;
+
+ if( dy < 0 )
+ angle = -900;
+ }
+
+ RotatePoint( &dx, &dy, angle ); // dx = length, dy = 0
+
+ for( col = col_min; col <= col_max; col++ )
+ {
+ int cxr;
+ cxr = ( col * RoutingMatrix.m_GridRouting ) - ux0;
+
+ for( row = row_min; row <= row_max; row++ )
+ {
+ cy = (row * RoutingMatrix.m_GridRouting) - uy0;
+ cx = cxr;
+ RotatePoint( &cx, &cy, angle );
+
+ if( abs( cy ) > lg )
+ continue; // The point is too far on the Y axis.
+
+ /* This point a test is close to the segment: the position
+ * along the X axis must be tested.
+ */
+ if( ( cx >= 0 ) && ( cx <= dx ) )
+ {
+ OP_CELL( layer, row, col );
+ continue;
+ }
+
+ // Examination of extremities are rounded.
+ if( ( cx < 0 ) && ( cx >= -lg ) )
+ {
+ if( ( ( cx * cx ) + ( cy * cy ) ) <= ( lg * lg ) )
+ OP_CELL( layer, row, col );
+
+ continue;
+ }
+
+ if( ( cx > dx ) && ( cx <= ( dx + lg ) ) )
+ {
+ if( ( ( ( cx - dx ) * ( cx - dx ) ) + ( cy * cy ) ) <= ( lg * lg ) )
+ OP_CELL( layer, row, col );
+
+ continue;
+ }
+ }
+ }
+}
+
+
+/* Fills all cells of the routing matrix contained in the circle
+ * half-width = lg, center = ux0, uy0, ux1,uy1 is a point on the circle.
+ * coord are in PCB units.
+ */
+void TraceCircle( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer,
+ int color, int op_logic )
+{
+ int radius, nb_segm;
+ int x0, y0, // Starting point of the current segment trace.
+ x1, y1; // End point.
+ int ii;
+ int angle;
+
+ radius = KiROUND( Distance( ux0, uy0, ux1, uy1 ) );
+
+ x0 = x1 = radius;
+ y0 = y1 = 0;
+
+ if( lg < 1 )
+ lg = 1;
+
+ nb_segm = ( 2 * radius ) / lg;
+
+ if( nb_segm < 5 )
+ nb_segm = 5;
+
+ if( nb_segm > 100 )
+ nb_segm = 100;
+
+ for( ii = 1; ii < nb_segm; ii++ )
+ {
+ angle = (3600 * ii) / nb_segm;
+ x1 = KiROUND( cosdecideg( radius, angle ) );
+ y1 = KiROUND( sindecideg( radius, angle ) );
+ DrawSegmentQcq( x0 + ux0, y0 + uy0, x1 + ux0, y1 + uy0, lg, layer, color, op_logic );
+ x0 = x1;
+ y0 = y1;
+ }
+
+ DrawSegmentQcq( x1 + ux0, y1 + uy0, ux0 + radius, uy0, lg, layer, color, op_logic );
+}
+
+
+/* Fills all routing matrix cells contained in the arc
+ * angle = ArcAngle, half-width lg
+ * center = ux0,uy0, starting at ux1, uy1. Coordinates are in
+ * PCB units.
+ */
+void TraceArc( int ux0, int uy0, int ux1, int uy1, double ArcAngle, int lg,
+ LAYER_NUM layer, int color, int op_logic )
+{
+ int radius, nb_segm;
+ int x0, y0, // Starting point of the current segment trace
+ x1, y1; // End point
+ int ii;
+ double angle, StAngle;
+
+
+ radius = KiROUND( Distance( ux0, uy0, ux1, uy1 ) );
+
+ x0 = ux1 - ux0;
+ y0 = uy1 - uy0;
+ StAngle = ArcTangente( uy1 - uy0, ux1 - ux0 );
+
+ if( lg < 1 )
+ lg = 1;
+
+ nb_segm = ( 2 * radius ) / lg;
+ nb_segm = ( nb_segm * std::abs( ArcAngle ) ) / 3600;
+
+ if( nb_segm < 5 )
+ nb_segm = 5;
+
+ if( nb_segm > 100 )
+ nb_segm = 100;
+
+ for( ii = 1; ii <= nb_segm; ii++ )
+ {
+ angle = ( ArcAngle * ii ) / nb_segm;
+ angle += StAngle;
+
+ NORMALIZE_ANGLE_POS( angle );
+
+ x1 = KiROUND( cosdecideg( radius, angle ) );
+ y1 = KiROUND( cosdecideg( radius, angle ) );
+ DrawSegmentQcq( x0 + ux0, y0 + uy0, x1 + ux0, y1 + uy0, lg, layer, color, op_logic );
+ x0 = x1;
+ y0 = y1;
+ }
+}
diff --git a/pcbnew/autorouter/move_and_route_event_functions.cpp b/pcbnew/autorouter/move_and_route_event_functions.cpp
new file mode 100644
index 0000000..5e9f319
--- /dev/null
+++ b/pcbnew/autorouter/move_and_route_event_functions.cpp
@@ -0,0 +1,200 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file move_and_route_event_functions.cpp
+ * @brief Routines for automatic displacement and rotation of modules.
+ */
+
+#include <algorithm>
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <kicad_device_context.h>
+
+#include <autorout.h>
+#include <cell.h>
+#include <pcbnew_id.h>
+#include <class_board.h>
+#include <class_module.h>
+
+
+typedef enum {
+ FIXE_MODULE,
+ FREE_MODULE,
+ FIXE_ALL_MODULES,
+ FREE_ALL_MODULES
+} SelectFixeFct;
+
+
+
+wxString ModulesMaskSelection = wxT( "*" );
+
+
+/* Called on events (popup menus) relative to automove and autoplace footprints
+ */
+void PCB_EDIT_FRAME::OnPlaceOrRouteFootprints( wxCommandEvent& event )
+{
+ int id = event.GetId();
+
+ if( m_mainToolBar == NULL )
+ return;
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ switch( id )
+ {
+ case ID_POPUP_PCB_AUTOROUTE_SELECT_LAYERS:
+ return;
+
+ case ID_POPUP_PCB_AUTOPLACE_FIXE_MODULE:
+ LockModule( (MODULE*) GetScreen()->GetCurItem(), true );
+ return;
+
+ case ID_POPUP_PCB_AUTOPLACE_FREE_MODULE:
+ LockModule( (MODULE*) GetScreen()->GetCurItem(), false );
+ return;
+
+ case ID_POPUP_PCB_AUTOPLACE_FREE_ALL_MODULES:
+ LockModule( NULL, false );
+ return;
+
+ case ID_POPUP_PCB_AUTOPLACE_FIXE_ALL_MODULES:
+ LockModule( NULL, true );
+ return;
+
+ case ID_POPUP_CANCEL_CURRENT_COMMAND:
+ if( m_canvas->IsMouseCaptured() )
+ {
+ m_canvas->CallEndMouseCapture( &dc );
+ }
+
+ break;
+
+ default: // Abort a current command (if any)
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+ break;
+ }
+
+ // Erase ratsnest if needed
+ if( GetBoard()->IsElementVisible(RATSNEST_VISIBLE) )
+ DrawGeneralRatsnest( &dc );
+
+ GetBoard()->m_Status_Pcb |= DO_NOT_SHOW_GENERAL_RASTNEST;
+
+ switch( id )
+ {
+ case ID_POPUP_PCB_AUTOPLACE_CURRENT_MODULE:
+ AutoPlaceModule( (MODULE*) GetScreen()->GetCurItem(), PLACE_1_MODULE, &dc );
+ break;
+
+ case ID_POPUP_PCB_AUTOPLACE_ALL_MODULES:
+ AutoPlaceModule( NULL, PLACE_ALL, &dc );
+ break;
+
+ case ID_POPUP_PCB_AUTOPLACE_NEW_MODULES:
+ AutoPlaceModule( NULL, PLACE_OUT_OF_BOARD, &dc );
+ break;
+
+ case ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE:
+ AutoPlaceModule( NULL, PLACE_INCREMENTAL, &dc );
+ break;
+
+ case ID_POPUP_PCB_SPREAD_ALL_MODULES:
+ if( !IsOK( this,
+ _("Not locked footprints inside the board will be moved. OK?") ) )
+ break;
+ // Fall through
+ case ID_POPUP_PCB_SPREAD_NEW_MODULES:
+ if( GetBoard()->m_Modules == NULL )
+ {
+ DisplayError( this, _( "No footprint found!" ) );
+ return;
+ }
+
+ SpreadFootprints( id == ID_POPUP_PCB_SPREAD_NEW_MODULES );
+ break;
+
+ case ID_POPUP_PCB_AUTOROUTE_ALL_MODULES:
+ Autoroute( &dc, ROUTE_ALL );
+ break;
+
+ case ID_POPUP_PCB_AUTOROUTE_MODULE:
+ Autoroute( &dc, ROUTE_MODULE );
+ break;
+
+ case ID_POPUP_PCB_AUTOROUTE_PAD:
+ Autoroute( &dc, ROUTE_PAD );
+ break;
+
+ case ID_POPUP_PCB_AUTOROUTE_NET:
+ Autoroute( &dc, ROUTE_NET );
+ break;
+
+ case ID_POPUP_PCB_AUTOROUTE_RESET_UNROUTED:
+ Reset_Noroutable( &dc );
+ break;
+
+ default:
+ wxMessageBox( wxT( "OnPlaceOrRouteFootprints command error" ) );
+ break;
+ }
+
+ GetBoard()->m_Status_Pcb &= ~DO_NOT_SHOW_GENERAL_RASTNEST;
+ Compile_Ratsnest( &dc, true );
+}
+
+
+/* Set or reset (true or false) Lock attribute of aModule or all modules if aModule == NULL
+ */
+void PCB_EDIT_FRAME::LockModule( MODULE* aModule, bool aLocked )
+{
+ if( aModule )
+ {
+ aModule->SetLocked( aLocked );
+ SetMsgPanel( aModule );
+ OnModify();
+ }
+ else
+ {
+ aModule = GetBoard()->m_Modules;
+
+ for( ; aModule != NULL; aModule = aModule->Next() )
+ {
+ if( WildCompareString( ModulesMaskSelection, aModule->GetReference() ) )
+ {
+ aModule->SetLocked( aLocked );
+ OnModify();
+ }
+ }
+ }
+}
+
diff --git a/pcbnew/autorouter/queue.cpp b/pcbnew/autorouter/queue.cpp
new file mode 100644
index 0000000..0cf1977
--- /dev/null
+++ b/pcbnew/autorouter/queue.cpp
@@ -0,0 +1,220 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * First copyright (C) Randy Nevin, 1989 (see PCBCA package)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/**
+ * @file queue.cpp
+ */
+
+#include <fctsys.h>
+#include <common.h>
+
+#include <pcbnew.h>
+#include <autorout.h>
+#include <cell.h>
+
+
+struct PcbQueue /* search queue structure */
+{
+ struct PcbQueue* Next;
+ int Row; /* current row */
+ int Col; /* current column */
+ int Side; /* 0=top, 1=bottom */
+ int Dist; /* path distance to this cell so far */
+ int ApxDist; /* approximate distance to target from here */
+};
+
+static long qlen = 0; /* current queue length */
+static struct PcbQueue* Head = NULL;
+static struct PcbQueue* Tail = NULL;
+static struct PcbQueue* Save = NULL; /* hold empty queue structs */
+
+
+/* Free the memory used for storing all the queue */
+void FreeQueue()
+{
+ struct PcbQueue* p;
+
+ InitQueue();
+
+ while( (p = Save) != NULL )
+ {
+ Save = p->Next;
+ delete p;
+ }
+}
+
+
+/* initialize the search queue */
+void InitQueue()
+{
+ struct PcbQueue* p;
+
+ while( (p = Head) != NULL )
+ {
+ Head = p->Next;
+ p->Next = Save; Save = p;
+ }
+
+ Tail = NULL;
+ OpenNodes = ClosNodes = MoveNodes = MaxNodes = qlen = 0;
+}
+
+
+/* get search queue item from list */
+void GetQueue( int* r, int* c, int* s, int* d, int* a )
+{
+ struct PcbQueue* p;
+
+ if( (p = Head) != NULL ) /* return first item in list */
+ {
+ *r = p->Row; *c = p->Col;
+ *s = p->Side;
+ *d = p->Dist; *a = p->ApxDist;
+
+ if( (Head = p->Next) == NULL )
+ Tail = NULL;
+
+ /* put node on free list */
+ p->Next = Save; Save = p;
+ ClosNodes++; qlen--;
+ }
+ else /* empty list */
+ {
+ *r = *c = *s = *d = *a = ILLEGAL;
+ }
+}
+
+
+/* add a search node to the list
+ * :
+ * 1 - OK
+ * 0 - Failed to allocate memory.
+ */
+bool SetQueue( int r, int c, int side, int d, int a, int r2, int c2 )
+{
+ struct PcbQueue* p, * q, * t;
+ int i, j;
+
+ j = 0; // gcc warning fix
+
+ if( (p = Save) != NULL ) /* try free list first */
+ {
+ Save = p->Next;
+ }
+ else if( ( p = (PcbQueue*) operator new( sizeof( PcbQueue ), std::nothrow ) ) == NULL )
+ {
+ return 0;
+ }
+
+ p->Row = r;
+ p->Col = c;
+ p->Side = side;
+ i = (p->Dist = d) + (p->ApxDist = a);
+ p->Next = NULL;
+
+ if( (q = Head) != NULL ) /* insert in proper position in list */
+ {
+ if( q->Dist + q->ApxDist > i ) /* insert at head */
+ {
+ p->Next = q; Head = p;
+ }
+ else /* search for proper position */
+ {
+ for( t = q, q = q->Next; q && i > ( j = q->Dist + q->ApxDist ); t = q, q = q->Next )
+ ;
+
+ if( q && i == j && q->Row == r2 && q->Col == c2 )
+ {
+ /* insert after q, which is a goal node */
+ if( ( p->Next = q->Next ) == NULL )
+ Tail = p;
+
+ q->Next = p;
+ }
+ else /* insert in front of q */
+ {
+ if( ( p->Next = q ) == NULL )
+ Tail = p;
+
+ t->Next = p;
+ }
+ }
+ }
+ else /* empty search list */
+ {
+ Head = Tail = p;
+ }
+
+ OpenNodes++;
+
+ if( ++qlen > MaxNodes )
+ MaxNodes = qlen;
+
+ return 1;
+}
+
+
+/* reposition node in list */
+void ReSetQueue( int r, int c, int s, int d, int a, int r2, int c2 )
+{
+ struct PcbQueue* p, * q;
+
+ /* first, see if it is already in the list */
+ for( q = NULL, p = Head; p; q = p, p = p->Next )
+ {
+ if( p->Row == r && p->Col == c && p->Side == s )
+ {
+ /* old one to remove */
+ if( q )
+ {
+ if( ( q->Next = p->Next ) == NULL )
+ Tail = q;
+ }
+ else if( ( Head = p->Next ) == NULL )
+ {
+ Tail = NULL;
+ }
+
+ p->Next = Save;
+ Save = p;
+ OpenNodes--;
+ MoveNodes++;
+ qlen--;
+ break;
+ }
+ }
+
+ if( !p ) /* not found, it has already been closed once */
+ ClosNodes--; /* we will close it again, but just count once */
+
+ /* if it was there, it's gone now; insert it at the proper position */
+ bool res = SetQueue( r, c, s, d, a, r2, c2 );
+ (void) res;
+}
diff --git a/pcbnew/autorouter/rect_placement/RectanglePlacement.txt b/pcbnew/autorouter/rect_placement/RectanglePlacement.txt
new file mode 100644
index 0000000..cecbf2e
--- /dev/null
+++ b/pcbnew/autorouter/rect_placement/RectanglePlacement.txt
@@ -0,0 +1,38 @@
+A class that fits subrectangles into a power-of-2 rectangle
+
+(C) Copyright 2000-2002 by Javier Arevalo
+This code is free to use and modify for all purposes
+
+You have a bunch of rectangular pieces. You need to arrange them in a
+rectangular surface so that they don't overlap, keeping the total area of the
+rectangle as small as possible. This is fairly common when arranging characters
+in a bitmapped font, lightmaps for a 3D engine, and I guess other situations as
+well.
+
+The idea of this algorithm is that, as we add rectangles, we can pre-select
+"interesting" places where we can try to add the next rectangles. For optimal
+results, the rectangles should be added in order. I initially tried using area
+as a sorting criteria, but it didn't work well with very tall or very flat
+rectangles. I then tried using the longest dimension as a selector, and it
+worked much better. So much for intuition...
+
+These "interesting" places are just to the right and just below the currently
+added rectangle. The first rectangle, obviously, goes at the top left, the next
+one would go either to the right or below this one, and so on. It is a weird way
+to do it, but it seems to work very nicely.
+
+The way we search here is fairly brute-force, the fact being that for most off-
+line purposes the performance seems more than adequate. I have generated a
+japanese font with around 8500 characters and all the time was spent generating
+the bitmaps.
+
+Also, for all we care, we could grow the parent rectangle in a different way
+than power of two. It just happens that power of 2 is very convenient for
+graphics hardware textures.
+
+I'd be interested in hearing of other approaches to this problem. Make sure
+to post them on http://www.flipcode.com
+
+See also
+http://www.flipcode.com/archives/Rectangle_Placement.shtml
+http://kossovsky.net/index.php/2009/07/cshar-rectangle-packing
diff --git a/pcbnew/autorouter/rect_placement/rect_placement.cpp b/pcbnew/autorouter/rect_placement/rect_placement.cpp
new file mode 100644
index 0000000..f562c2b
--- /dev/null
+++ b/pcbnew/autorouter/rect_placement/rect_placement.cpp
@@ -0,0 +1,259 @@
+// ----------------------------------------------------------------------------------------
+// Name : rect_placement.cpp
+// Description : A class that fits subrectangles into a power-of-2 rectangle
+// (C) Copyright 2000-2002 by Javier Arevalo
+// This code is free to use and modify for all purposes
+// ----------------------------------------------------------------------------------------
+
+/*
+ * You have a bunch of rectangular pieces. You need to arrange them in a
+ * rectangular surface so that they don't overlap, keeping the total area of the
+ * rectangle as small as possible. This is fairly common when arranging characters
+ * in a bitmapped font, lightmaps for a 3D engine, and I guess other situations as
+ * well.
+ *
+ * The idea of this algorithm is that, as we add rectangles, we can pre-select
+ * "interesting" places where we can try to add the next rectangles. For optimal
+ * results, the rectangles should be added in order. I initially tried using area
+ * as a sorting criteria, but it didn't work well with very tall or very flat
+ * rectangles. I then tried using the longest dimension as a selector, and it
+ * worked much better. So much for intuition...
+ *
+ * These "interesting" places are just to the right and just below the currently
+ * added rectangle. The first rectangle, obviously, goes at the top left, the next
+ * one would go either to the right or below this one, and so on. It is a weird way
+ * to do it, but it seems to work very nicely.
+ *
+ * The way we search here is fairly brute-force, the fact being that for most off-
+ * line purposes the performance seems more than adequate. I have generated a
+ * japanese font with around 8500 characters and all the time was spent generating
+ * the bitmaps.
+ *
+ * Also, for all we care, we could grow the parent rectangle.
+ *
+ * I'd be interested in hearing of other approaches to this problem. Make sure
+ * to post them on http://www.flipcode.com
+ */
+
+#include "rect_placement.h"
+
+// --------------------------------------------------------------------------------
+// Name :
+// Description :
+// --------------------------------------------------------------------------------
+void CRectPlacement::Init( int w, int h )
+{
+ End();
+ m_size = TRect( 0, 0, w, h );
+ m_vPositions.push_back( TPos( 0, 0 ) );
+ m_area = 0;
+}
+
+
+// --------------------------------------------------------------------------------
+// Name :
+// Description :
+// --------------------------------------------------------------------------------
+void CRectPlacement::End()
+{
+ m_vPositions.clear();
+ m_vRects.clear();
+ m_size.w = 0;
+}
+
+
+// --------------------------------------------------------------------------------
+// Name : IsFree
+// Description : Check if the given rectangle is partially or totally used
+// --------------------------------------------------------------------------------
+bool CRectPlacement::IsFree( const TRect& r ) const
+{
+ if( !m_size.Contains( r ) )
+ return false;
+
+ for( CRectArray::const_iterator it = m_vRects.begin();
+ it != m_vRects.end(); ++it )
+ {
+ if( it->Intersects( r ) )
+ return false;
+ }
+
+ return true;
+}
+
+
+// --------------------------------------------------------------------------------
+// Name : AddPosition
+// Description : Add new anchor point
+// --------------------------------------------------------------------------------
+void CRectPlacement::AddPosition( const TPos& p )
+{
+ // Try to insert anchor as close as possible to the top left corner
+ // So it will be tried first
+ bool bFound = false;
+ CPosArray::iterator it;
+
+ for( it = m_vPositions.begin();
+ !bFound && it != m_vPositions.end();
+ ++it )
+ {
+ if( p.x + p.y < it->x + it->y )
+ bFound = true;
+ }
+
+ if( bFound )
+ m_vPositions.insert( it, p );
+ else
+ m_vPositions.push_back( p );
+}
+
+
+// --------------------------------------------------------------------------------
+// Name : AddRect
+// Description : Add the given rect and updates anchor points
+// --------------------------------------------------------------------------------
+void CRectPlacement::AddRect( const TRect& r )
+{
+ m_vRects.push_back( r );
+ m_area += r.w * r.h;
+
+ // Add two new anchor points
+ AddPosition( TPos( r.x, r.y + r.h ) );
+ AddPosition( TPos( r.x + r.w, r.y ) );
+}
+
+
+// --------------------------------------------------------------------------------
+// Name : AddAtEmptySpot
+// Description : Add the given rectangle
+// --------------------------------------------------------------------------------
+bool CRectPlacement::AddAtEmptySpot( TRect& r )
+{
+ // Find a valid spot among available anchors.
+ bool bFound = false;
+ CPosArray::iterator it;
+
+ for( it = m_vPositions.begin();
+ !bFound && it != m_vPositions.end();
+ ++it )
+ {
+ TRect Rect( it->x, it->y, r.w, r.h );
+
+ if( IsFree( Rect ) )
+ {
+ r = Rect;
+ bFound = true;
+ break; // Don't let the loop increase the iterator.
+ }
+ }
+
+ if( bFound )
+ {
+ int x, y;
+
+ // Remove the used anchor point
+ m_vPositions.erase( it );
+
+ // Sometimes, anchors end up displaced from the optimal position
+ // due to irregular sizes of the subrects.
+ // So, try to adjut it up & left as much as possible.
+ for( x = 1; x <= r.x; x++ )
+ {
+ if( !IsFree( TRect( r.x - x, r.y, r.w, r.h ) ) )
+ break;
+ }
+
+ for( y = 1; y <= r.y; y++ )
+ {
+ if( !IsFree( TRect( r.x, r.y - y, r.w, r.h ) ) )
+ break;
+ }
+
+ if( y > x )
+ r.y -= y - 1;
+ else
+ r.x -= x - 1;
+
+ AddRect( r );
+ }
+
+ return bFound;
+}
+
+#include <stdio.h>
+// --------------------------------------------------------------------------------
+// Name : AddAtEmptySpotAutoGrow
+// Description : Add a rectangle of the given size, growing our area if needed
+// Area grows only until the max given.
+// Returns the placement of the rect in the rect's x,y coords
+// --------------------------------------------------------------------------------
+bool CRectPlacement::AddAtEmptySpotAutoGrow( TRect* pRect, int maxW, int maxH )
+{
+ double growing_factor = 1.2; // Must be > 1.0, and event > 1.1 for fast optimization
+
+ #define GROW(x) ((x * growing_factor) + 1)
+
+ if( pRect->w <= 0 )
+ return true;
+
+ int orgW = m_size.w;
+ int orgH = m_size.h;
+
+ // Try to add it in the existing space
+ while( !AddAtEmptySpot( *pRect ) )
+ {
+ int pw = m_size.w;
+ int ph = m_size.h;
+
+ // Sanity check - if area is complete.
+ if( pw >= maxW && ph >= maxH )
+ {
+ m_size.w = orgW;
+ m_size.h = orgH;
+ return false;
+ }
+
+ // Try growing the smallest dim
+ if( pw < maxW && ( pw < ph || ( (pw == ph) && (pRect->w >= pRect->h) ) ) )
+ m_size.w = GROW( pw );
+ else
+ m_size.h = GROW( ph );
+
+ if( AddAtEmptySpot( *pRect ) )
+ break;
+
+ // Try growing the other dim instead
+ if( pw != m_size.w )
+ {
+ m_size.w = pw;
+
+ if( ph < maxW )
+ m_size.h = GROW( ph );
+ }
+ else
+ {
+ m_size.h = ph;
+
+ if( pw < maxW )
+ m_size.w = GROW( pw );
+ }
+
+ if( pw != m_size.w || ph != m_size.h )
+ if( AddAtEmptySpot( *pRect ) )
+ break;
+
+
+
+ // Grow both if possible, and reloop.
+ m_size.w = pw;
+ m_size.h = ph;
+
+ if( pw < maxW )
+ m_size.w = GROW( pw );
+
+ if( ph < maxH )
+ m_size.h = GROW( ph );
+ }
+
+ return true;
+}
diff --git a/pcbnew/autorouter/rect_placement/rect_placement.h b/pcbnew/autorouter/rect_placement/rect_placement.h
new file mode 100644
index 0000000..b89b538
--- /dev/null
+++ b/pcbnew/autorouter/rect_placement/rect_placement.h
@@ -0,0 +1,104 @@
+// --------------------------------------------------------------------------------
+// Name : rect_placement.h
+// Description : A class that allocates subrectangles into power-of-2 rectangles
+// (C) Copyright 2000-2002 by Javier Arevalo
+// This code is free to use and modify for all purposes
+// --------------------------------------------------------------------------------
+
+/**
+ * @file rect_placement.h
+ */
+
+#ifndef _RECT_PLACEMENT_H_
+#define _RECT_PLACEMENT_H_
+
+#include <vector>
+
+// --------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
+
+class CRectPlacement
+{
+public:
+
+ // Helper classes
+ struct TPos
+ {
+ int x, y;
+
+ TPos() : x( 0 ), y( 0 ) { }
+ TPos( int _x, int _y ) : x( _x ), y( _y ) { }
+
+ bool operator ==( const TPos& p ) const { return x == p.x && y == p.y; }
+ };
+
+ struct TRect : public TPos
+ {
+ int w, h;
+
+ TRect() : w( 0 ), h( 0 ) { }
+ TRect( int _x, int _y, int _w, int _h ) : TPos( _x, _y ), w( _w > 0 ? _w : 0 ), h(
+ _h > 0 ? _h : 0 ) { }
+
+ bool Contains( const TPos& p ) const
+ {
+ return p.x >= x && p.y >= y && p.x < (x + w) && p.y < (y + h);
+ }
+ bool Contains( const TRect& r ) const
+ {
+ return r.x >= x && r.y >= y &&
+ (r.x + r.w) <= (x + w) && (r.y + r.h) <= (y + h);
+ }
+ bool Intersects( const TRect& r ) const
+ {
+ return w > 0 && h > 0 && r.w > 0 && r.h > 0
+ && ( (r.x + r.w) > x && r.x < (x + w) && (r.y + r.h) > y && r.y < (y + h) );
+ }
+
+ // static bool Greater(const TRect &a, const TRect &b)
+ // { return a.w*a.h > b.w*b.h; }
+ // Greater rect area. Not as good as the next heuristic:
+ // Greater size in at least one dim.
+ static bool Greater( const TRect& a, const TRect& b )
+ {
+ return (a.w > b.w && a.w > b.h) || (a.h > b.w && a.h > b.h);
+ }
+ };
+
+ // ---------------------
+
+ typedef std::vector<TPos> CPosArray;
+ typedef std::vector<TRect> CRectArray;
+
+ // ---------------------
+
+ CRectPlacement() { Init(); }
+ ~CRectPlacement() { End(); }
+
+ void Init( int w = 1, int h = 1 );
+ void End();
+
+ bool IsOk() const { return m_size.w > 0; }
+
+ int GetW() const { return m_size.w; }
+ int GetH() const { return m_size.h; }
+ double GetArea() const { return m_area; }
+ double GetTotalArea() const { return (double)m_size.w * m_size.h; }
+
+ bool AddAtEmptySpotAutoGrow( TRect* pRect, int maxW, int maxH );
+
+private:
+ TRect m_size;
+ CRectArray m_vRects;
+ CPosArray m_vPositions;
+ double m_area;
+
+ // ---------------------
+
+ bool IsFree( const TRect& r ) const;
+ void AddPosition( const TPos& p );
+ void AddRect( const TRect& r );
+ bool AddAtEmptySpot( TRect& r );
+};
+
+#endif // _RECT_PLACEMENT_H_
diff --git a/pcbnew/autorouter/routing_matrix.cpp b/pcbnew/autorouter/routing_matrix.cpp
new file mode 100644
index 0000000..2c97f0d
--- /dev/null
+++ b/pcbnew/autorouter/routing_matrix.cpp
@@ -0,0 +1,550 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file routing_matrix.cpp
+ * @brief Functions to create autorouting maps
+ */
+
+#include <fctsys.h>
+#include <common.h>
+
+#include <pcbnew.h>
+#include <cell.h>
+#include <autorout.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_drawsegment.h>
+#include <class_edge_mod.h>
+#include <class_pcb_text.h>
+
+
+MATRIX_ROUTING_HEAD::MATRIX_ROUTING_HEAD()
+{
+ m_BoardSide[0] = m_BoardSide[1] = NULL;
+ m_DistSide[0] = m_DistSide[1] = NULL;
+ m_DirSide[0] = m_DirSide[1] = NULL;
+ m_opWriteCell = NULL;
+ m_InitMatrixDone = false;
+ m_Nrows = 0;
+ m_Ncols = 0;
+ m_MemSize = 0;
+ m_RoutingLayersCount = 1;
+ m_GridRouting = 0;
+ m_RouteCount = 0;
+}
+
+
+MATRIX_ROUTING_HEAD::~MATRIX_ROUTING_HEAD()
+{
+}
+
+
+bool MATRIX_ROUTING_HEAD::ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnly )
+{
+ aPcb->ComputeBoundingBox( aUseBoardEdgesOnly );
+
+ // The boundary box must have its start point on routing grid:
+ m_BrdBox = aPcb->GetBoundingBox();
+
+ m_BrdBox.SetX( m_BrdBox.GetX() - ( m_BrdBox.GetX() % m_GridRouting ) );
+ m_BrdBox.SetY( m_BrdBox.GetY() - ( m_BrdBox.GetY() % m_GridRouting ) );
+
+ // The boundary box must have its end point on routing grid:
+ wxPoint end = m_BrdBox.GetEnd();
+
+ end.x -= end.x % m_GridRouting;
+ end.x += m_GridRouting;
+
+ end.y -= end.y % m_GridRouting;
+ end.y += m_GridRouting;
+
+ m_BrdBox.SetEnd( end );
+
+ aPcb->SetBoundingBox( m_BrdBox );
+
+ m_Nrows = m_BrdBox.GetHeight() / m_GridRouting;
+ m_Ncols = m_BrdBox.GetWidth() / m_GridRouting;
+
+ // gives a small margin
+ m_Ncols += 1;
+ m_Nrows += 1;
+
+ return true;
+}
+
+
+int MATRIX_ROUTING_HEAD::InitRoutingMatrix()
+{
+ if( m_Nrows <= 0 || m_Ncols <= 0 )
+ return 0;
+
+ m_InitMatrixDone = true; // we have been called
+
+ // give a small margin for memory allocation:
+ int ii = (RoutingMatrix.m_Nrows + 1) * (RoutingMatrix.m_Ncols + 1);
+
+ int side = BOTTOM;
+ for( int jj = 0; jj < m_RoutingLayersCount; jj++ ) // m_RoutingLayersCount = 1 or 2
+ {
+ m_BoardSide[side] = NULL;
+ m_DistSide[side] = NULL;
+ m_DirSide[side] = NULL;
+
+ // allocate matrix & initialize everything to empty
+ m_BoardSide[side] = (MATRIX_CELL*) operator new( ii * sizeof(MATRIX_CELL) );
+ memset( m_BoardSide[side], 0, ii * sizeof(MATRIX_CELL) );
+
+ if( m_BoardSide[side] == NULL )
+ return -1;
+
+ // allocate Distances
+ m_DistSide[side] = (DIST_CELL*) operator new( ii * sizeof(DIST_CELL) );
+ memset( m_DistSide[side], 0, ii * sizeof(DIST_CELL) );
+
+ if( m_DistSide[side] == NULL )
+ return -1;
+
+ // allocate Dir (chars)
+ m_DirSide[side] = (char*) operator new( ii );
+ memset( m_DirSide[side], 0, ii );
+
+ if( m_DirSide[side] == NULL )
+ return -1;
+
+ side = TOP;
+ }
+
+ m_MemSize = m_RouteCount * ii * ( sizeof(MATRIX_CELL)
+ + sizeof(DIST_CELL) + sizeof(char) );
+
+ return m_MemSize;
+}
+
+
+void MATRIX_ROUTING_HEAD::UnInitRoutingMatrix()
+{
+ int ii;
+
+ m_InitMatrixDone = false;
+
+ for( ii = 0; ii < MAX_ROUTING_LAYERS_COUNT; ii++ )
+ {
+ // de-allocate Dir matrix
+ if( m_DirSide[ii] )
+ {
+ delete m_DirSide[ii];
+ m_DirSide[ii] = NULL;
+ }
+
+ // de-allocate Distances matrix
+ if( m_DistSide[ii] )
+ {
+ delete m_DistSide[ii];
+ m_DistSide[ii] = NULL;
+ }
+
+ // de-allocate cells matrix
+ if( m_BoardSide[ii] )
+ {
+ delete m_BoardSide[ii];
+ m_BoardSide[ii] = NULL;
+ }
+ }
+
+ m_Nrows = m_Ncols = 0;
+}
+
+
+/**
+ * Function PlaceCells
+ * Initialize the matrix routing by setting obstacles for each occupied cell
+ * a cell set to HOLE is an obstacle for tracks and vias
+ * a cell set to VIA_IMPOSSIBLE is an obstacle for vias only.
+ * a cell set to CELL_is_EDGE is a frontier.
+ * Tracks and vias having the same net code as net_code are skipped
+ * (htey do not are obstacles)
+ *
+ * For single-sided Routing 1:
+ * BOTTOM side is used, and Route_Layer_BOTTOM = Route_Layer_TOP
+ *
+ * If flag == FORCE_PADS: all pads will be put in matrix as obstacles.
+ */
+void PlaceCells( BOARD* aPcb, int net_code, int flag )
+{
+ int ux0 = 0, uy0 = 0, ux1, uy1, dx, dy;
+ int marge, via_marge;
+ LSET layerMask;
+
+ // use the default NETCLASS?
+ NETCLASSPTR nc = aPcb->GetDesignSettings().GetDefault();
+
+ int trackWidth = nc->GetTrackWidth();
+ int clearance = nc->GetClearance();
+ int viaSize = nc->GetViaDiameter();
+
+ marge = clearance + (trackWidth / 2);
+ via_marge = clearance + (viaSize / 2);
+
+ // Place PADS on matrix routing:
+ for( unsigned i = 0; i < aPcb->GetPadCount(); ++i )
+ {
+ D_PAD* pad = aPcb->GetPad( i );
+
+ if( net_code != pad->GetNetCode() || (flag & FORCE_PADS) )
+ {
+ ::PlacePad( pad, HOLE, marge, WRITE_CELL );
+ }
+
+ ::PlacePad( pad, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
+ }
+
+ // Place outlines of modules on matrix routing, if they are on a copper layer
+ // or on the edge layer
+
+ for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
+ {
+ for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case PCB_MODULE_EDGE_T:
+ {
+ EDGE_MODULE* edge = (EDGE_MODULE*) item;
+ EDGE_MODULE tmpEdge( *edge );
+
+ if( tmpEdge.GetLayer() == Edge_Cuts )
+ tmpEdge.SetLayer( UNDEFINED_LAYER );
+
+ TraceSegmentPcb( &tmpEdge, HOLE, marge, WRITE_CELL );
+ TraceSegmentPcb( &tmpEdge, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ // Place board outlines and texts on copper layers:
+ for( BOARD_ITEM* item = aPcb->m_Drawings; item; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case PCB_LINE_T:
+ {
+ DRAWSEGMENT* DrawSegm;
+
+ int type_cell = HOLE;
+ DrawSegm = (DRAWSEGMENT*) item;
+ DRAWSEGMENT tmpSegm( DrawSegm );
+
+ if( DrawSegm->GetLayer() == Edge_Cuts )
+ {
+ tmpSegm.SetLayer( UNDEFINED_LAYER );
+ type_cell |= CELL_is_EDGE;
+ }
+
+ TraceSegmentPcb( &tmpSegm, type_cell, marge, WRITE_CELL );
+ }
+ break;
+
+ case PCB_TEXT_T:
+ {
+ TEXTE_PCB* PtText = (TEXTE_PCB*) item;
+
+ if( PtText->GetText().Length() == 0 )
+ break;
+
+ EDA_RECT textbox = PtText->GetTextBox( -1 );
+ ux0 = textbox.GetX();
+ uy0 = textbox.GetY();
+ dx = textbox.GetWidth();
+ dy = textbox.GetHeight();
+
+ // Put bounding box (rectangle) on matrix
+ dx /= 2;
+ dy /= 2;
+
+ ux1 = ux0 + dx;
+ uy1 = uy0 + dy;
+
+ ux0 -= dx;
+ uy0 -= dy;
+
+ layerMask = LSET( PtText->GetLayer() );
+
+ TraceFilledRectangle( ux0 - marge, uy0 - marge, ux1 + marge,
+ uy1 + marge, PtText->GetOrientation(),
+ layerMask, HOLE, WRITE_CELL );
+
+ TraceFilledRectangle( ux0 - via_marge, uy0 - via_marge,
+ ux1 + via_marge, uy1 + via_marge,
+ PtText->GetOrientation(),
+ layerMask, VIA_IMPOSSIBLE, WRITE_OR_CELL );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Put tracks and vias on matrix
+ for( TRACK* track = aPcb->m_Track; track; track = track->Next() )
+ {
+ if( net_code == track->GetNetCode() )
+ continue;
+
+ TraceSegmentPcb( track, HOLE, marge, WRITE_CELL );
+ TraceSegmentPcb( track, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
+ }
+}
+
+
+int Build_Work( BOARD* Pcb )
+{
+ RATSNEST_ITEM* pt_rats;
+ D_PAD* pt_pad;
+ int r1, r2, c1, c2, current_net_code;
+ RATSNEST_ITEM* pt_ch;
+ int demi_pas = RoutingMatrix.m_GridRouting / 2;
+ wxString msg;
+
+ InitWork(); // clear work list
+ int cellCount = 0;
+
+ for( unsigned ii = 0; ii < Pcb->GetRatsnestsCount(); ii++ )
+ {
+ pt_rats = &Pcb->m_FullRatsnest[ii];
+
+ /* We consider here only ratsnest that are active ( obviously not yet routed)
+ * and routables (that are not yet attempt to be routed and fail
+ */
+ if( (pt_rats->m_Status & CH_ACTIF) == 0 )
+ continue;
+
+ if( pt_rats->m_Status & CH_UNROUTABLE )
+ continue;
+
+ if( (pt_rats->m_Status & CH_ROUTE_REQ) == 0 )
+ continue;
+
+ pt_pad = pt_rats->m_PadStart;
+
+ current_net_code = pt_pad->GetNetCode();
+ pt_ch = pt_rats;
+
+ r1 = ( pt_pad->GetPosition().y - RoutingMatrix.m_BrdBox.GetY() + demi_pas )
+ / RoutingMatrix.m_GridRouting;
+
+ if( r1 < 0 || r1 >= RoutingMatrix.m_Nrows )
+ {
+ msg.Printf( wxT( "error : row = %d ( padY %d pcbY %d) " ), r1,
+ pt_pad->GetPosition().y, RoutingMatrix.m_BrdBox.GetY() );
+ wxMessageBox( msg );
+ return 0;
+ }
+
+ c1 = ( pt_pad->GetPosition().x - RoutingMatrix.m_BrdBox.GetX() + demi_pas ) / RoutingMatrix.m_GridRouting;
+
+ if( c1 < 0 || c1 >= RoutingMatrix.m_Ncols )
+ {
+ msg.Printf( wxT( "error : col = %d ( padX %d pcbX %d) " ), c1,
+ pt_pad->GetPosition().x, RoutingMatrix.m_BrdBox.GetX() );
+ wxMessageBox( msg );
+ return 0;
+ }
+
+ pt_pad = pt_rats->m_PadEnd;
+
+ r2 = ( pt_pad->GetPosition().y - RoutingMatrix.m_BrdBox.GetY()
+ + demi_pas ) / RoutingMatrix.m_GridRouting;
+
+ if( r2 < 0 || r2 >= RoutingMatrix.m_Nrows )
+ {
+ msg.Printf( wxT( "error : row = %d ( padY %d pcbY %d) " ), r2,
+ pt_pad->GetPosition().y, RoutingMatrix.m_BrdBox.GetY() );
+ wxMessageBox( msg );
+ return 0;
+ }
+
+ c2 = ( pt_pad->GetPosition().x - RoutingMatrix.m_BrdBox.GetX() + demi_pas )
+ / RoutingMatrix.m_GridRouting;
+
+ if( c2 < 0 || c2 >= RoutingMatrix.m_Ncols )
+ {
+ msg.Printf( wxT( "error : col = %d ( padX %d pcbX %d) " ), c2,
+ pt_pad->GetPosition().x, RoutingMatrix.m_BrdBox.GetX() );
+ wxMessageBox( msg );
+ return 0;
+ }
+
+ SetWork( r1, c1, current_net_code, r2, c2, pt_ch, 0 );
+ cellCount++;
+ }
+
+ SortWork();
+ return cellCount;
+}
+
+// Initialize m_opWriteCell member to make the aLogicOp
+void MATRIX_ROUTING_HEAD::SetCellOperation( int aLogicOp )
+{
+ switch( aLogicOp )
+ {
+ default:
+ case WRITE_CELL:
+ m_opWriteCell = &MATRIX_ROUTING_HEAD::SetCell;
+ break;
+
+ case WRITE_OR_CELL:
+ m_opWriteCell = &MATRIX_ROUTING_HEAD::OrCell;
+ break;
+
+ case WRITE_XOR_CELL:
+ m_opWriteCell = &MATRIX_ROUTING_HEAD::XorCell;
+ break;
+
+ case WRITE_AND_CELL:
+ m_opWriteCell = &MATRIX_ROUTING_HEAD::AndCell;
+ break;
+
+ case WRITE_ADD_CELL:
+ m_opWriteCell = &MATRIX_ROUTING_HEAD::AddCell;
+ break;
+ }
+}
+
+
+/* return the value stored in a cell
+ */
+MATRIX_CELL MATRIX_ROUTING_HEAD::GetCell( int aRow, int aCol, int aSide )
+{
+ MATRIX_CELL* p;
+
+ p = RoutingMatrix.m_BoardSide[aSide];
+ return p[aRow * m_Ncols + aCol];
+}
+
+
+/* basic cell operation : WRITE operation
+ */
+void MATRIX_ROUTING_HEAD::SetCell( int aRow, int aCol, int aSide, MATRIX_CELL x )
+{
+ MATRIX_CELL* p;
+
+ p = RoutingMatrix.m_BoardSide[aSide];
+ p[aRow * m_Ncols + aCol] = x;
+}
+
+
+/* basic cell operation : OR operation
+ */
+void MATRIX_ROUTING_HEAD::OrCell( int aRow, int aCol, int aSide, MATRIX_CELL x )
+{
+ MATRIX_CELL* p;
+
+ p = RoutingMatrix.m_BoardSide[aSide];
+ p[aRow * m_Ncols + aCol] |= x;
+}
+
+
+/* basic cell operation : XOR operation
+ */
+void MATRIX_ROUTING_HEAD::XorCell( int aRow, int aCol, int aSide, MATRIX_CELL x )
+{
+ MATRIX_CELL* p;
+
+ p = RoutingMatrix.m_BoardSide[aSide];
+ p[aRow * m_Ncols + aCol] ^= x;
+}
+
+
+/* basic cell operation : AND operation
+ */
+void MATRIX_ROUTING_HEAD::AndCell( int aRow, int aCol, int aSide, MATRIX_CELL x )
+{
+ MATRIX_CELL* p;
+
+ p = RoutingMatrix.m_BoardSide[aSide];
+ p[aRow * m_Ncols + aCol] &= x;
+}
+
+
+/* basic cell operation : ADD operation
+ */
+void MATRIX_ROUTING_HEAD::AddCell( int aRow, int aCol, int aSide, MATRIX_CELL x )
+{
+ MATRIX_CELL* p;
+
+ p = RoutingMatrix.m_BoardSide[aSide];
+ p[aRow * m_Ncols + aCol] += x;
+}
+
+
+// fetch distance cell
+DIST_CELL MATRIX_ROUTING_HEAD::GetDist( int aRow, int aCol, int aSide ) // fetch distance cell
+{
+ DIST_CELL* p;
+
+ p = RoutingMatrix.m_DistSide[aSide];
+ return p[aRow * m_Ncols + aCol];
+}
+
+
+// store distance cell
+void MATRIX_ROUTING_HEAD::SetDist( int aRow, int aCol, int aSide, DIST_CELL x )
+{
+ DIST_CELL* p;
+
+ p = RoutingMatrix.m_DistSide[aSide];
+ p[aRow * m_Ncols + aCol] = x;
+}
+
+
+// fetch direction cell
+int MATRIX_ROUTING_HEAD::GetDir( int aRow, int aCol, int aSide )
+{
+ DIR_CELL* p;
+
+ p = RoutingMatrix.m_DirSide[aSide];
+ return (int) (p[aRow * m_Ncols + aCol]);
+}
+
+
+// store direction cell
+void MATRIX_ROUTING_HEAD::SetDir( int aRow, int aCol, int aSide, int x )
+{
+ DIR_CELL* p;
+
+ p = RoutingMatrix.m_DirSide[aSide];
+ p[aRow * m_Ncols + aCol] = (char) x;
+}
diff --git a/pcbnew/autorouter/solve.cpp b/pcbnew/autorouter/solve.cpp
new file mode 100644
index 0000000..c10e57f
--- /dev/null
+++ b/pcbnew/autorouter/solve.cpp
@@ -0,0 +1,1348 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * First copyright (C) Randy Nevin, 1989 (see PCBCA package)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* see "Autorouting With the A* Algorithm" (Dr.Dobbs journal)
+*/
+
+/**
+ * @file solve.cpp
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <gr_basic.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_track.h>
+
+#include <pcbnew.h>
+#include <protos.h>
+#include <autorout.h>
+#include <cell.h>
+
+
+static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
+ wxDC* DC,
+ int two_sides,
+ int row_source,
+ int col_source,
+ int row_target,
+ int col_target,
+ RATSNEST_ITEM* pt_rat );
+
+static int Retrace( PCB_EDIT_FRAME* pcbframe,
+ wxDC* DC,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int net_code );
+
+static void OrCell_Trace( BOARD* pcb,
+ int col,
+ int row,
+ int side,
+ int orient,
+ int current_net_code );
+
+static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC );
+
+
+static int segm_oX, segm_oY;
+static int segm_fX, segm_fY; /* Origin and position of the current
+ * trace segment. */
+static RATSNEST_ITEM* pt_cur_ch;
+static int s_Clearance; // Clearance value used in autorouter
+
+static PICKED_ITEMS_LIST s_ItemsListPicker;
+
+int OpenNodes; // total number of nodes opened
+int ClosNodes; // total number of nodes closed
+int MoveNodes; // total number of nodes moved
+int MaxNodes; // maximum number of nodes opened at one time
+
+#define NOSUCCESS 0
+#define STOP_FROM_ESC -1
+#define ERR_MEMORY -2
+#define SUCCESS 1
+#define TRIVIAL_SUCCESS 2
+
+/*
+** visit neighboring cells like this (where [9] is on the other side):
+**
+** +---+---+---+
+** | 1 | 2 | 3 |
+** +---+---+---+
+** | 4 |[9]| 5 |
+** +---+---+---+
+** | 6 | 7 | 8 |
+** +---+---+---+
+*/
+
+/* for visiting neighbors on the same side: increments/decrements coord of
+ * [] [0] = row [] (1] = col was added to the coord of the midpoint for
+ * Get the coord of the 8 neighboring points.
+ */
+static const int delta[8][2] =
+{
+ { 1, -1 }, // northwest
+ { 1, 0 }, // north
+ { 1, 1 }, // northeast
+ { 0, -1 }, // west
+ { 0, 1 }, // east
+ { -1, -1 }, // southwest
+ { -1, 0 }, // south
+ { -1, 1 } // southeast
+};
+
+static const int ndir[8] =
+{
+ // for building paths back to source
+ FROM_SOUTHEAST, FROM_SOUTH, FROM_SOUTHWEST,
+ FROM_EAST, FROM_WEST,
+ FROM_NORTHEAST, FROM_NORTH, FROM_NORTHWEST
+};
+
+// blocking masks for neighboring cells
+#define BLOCK_NORTHEAST ( DIAG_NEtoSW | BENT_StoNE | BENT_WtoNE \
+ | ANGLE_NEtoSE | ANGLE_NWtoNE \
+ | SHARP_NtoNE | SHARP_EtoNE | HOLE )
+#define BLOCK_SOUTHEAST ( DIAG_SEtoNW | BENT_NtoSE | BENT_WtoSE \
+ | ANGLE_NEtoSE | ANGLE_SEtoSW \
+ | SHARP_EtoSE | SHARP_StoSE | HOLE )
+#define BLOCK_SOUTHWEST ( DIAG_NEtoSW | BENT_NtoSW | BENT_EtoSW \
+ | ANGLE_SEtoSW | ANGLE_SWtoNW \
+ | SHARP_StoSW | SHARP_WtoSW | HOLE )
+#define BLOCK_NORTHWEST ( DIAG_SEtoNW | BENT_EtoNW | BENT_StoNW \
+ | ANGLE_SWtoNW | ANGLE_NWtoNE \
+ | SHARP_WtoNW | SHARP_NtoNW | HOLE )
+#define BLOCK_NORTH ( LINE_VERTICAL | BENT_NtoSE | BENT_NtoSW \
+ | BENT_EtoNW | BENT_WtoNE \
+ | BENT_StoNE | BENT_StoNW \
+ | CORNER_NORTHEAST | CORNER_NORTHWEST \
+ | ANGLE_NEtoSE | ANGLE_SWtoNW | ANGLE_NWtoNE \
+ | DIAG_NEtoSW | DIAG_SEtoNW \
+ | SHARP_NtoNE | SHARP_NtoNW \
+ | SHARP_EtoNE | SHARP_WtoNW | HOLE )
+#define BLOCK_EAST ( LINE_HORIZONTAL | BENT_EtoSW | BENT_EtoNW \
+ | BENT_NtoSE | BENT_StoNE \
+ | BENT_WtoNE | BENT_WtoSE \
+ | CORNER_NORTHEAST | CORNER_SOUTHEAST \
+ | ANGLE_NEtoSE | ANGLE_SEtoSW | ANGLE_NWtoNE \
+ | DIAG_NEtoSW | DIAG_SEtoNW \
+ | SHARP_EtoNE | SHARP_EtoSE \
+ | SHARP_NtoNE | SHARP_StoSE | HOLE )
+#define BLOCK_SOUTH ( LINE_VERTICAL | BENT_StoNE | BENT_StoNW \
+ | BENT_EtoSW | BENT_WtoSE \
+ | BENT_NtoSE | BENT_NtoSW \
+ | CORNER_SOUTHEAST | CORNER_SOUTHWEST \
+ | ANGLE_NEtoSE | ANGLE_SWtoNW | ANGLE_SEtoSW \
+ | DIAG_NEtoSW | DIAG_SEtoNW \
+ | SHARP_StoSE | SHARP_StoSW \
+ | SHARP_EtoSE | SHARP_WtoSW | HOLE )
+#define BLOCK_WEST ( LINE_HORIZONTAL | BENT_WtoNE | BENT_WtoSE \
+ | BENT_NtoSW | BENT_StoNW \
+ | BENT_EtoSW | BENT_EtoNW \
+ | CORNER_SOUTHWEST | CORNER_NORTHWEST \
+ | ANGLE_SWtoNW | ANGLE_SEtoSW | ANGLE_NWtoNE \
+ | DIAG_NEtoSW | DIAG_SEtoNW \
+ | SHARP_WtoSW | SHARP_WtoNW \
+ | SHARP_NtoNW | SHARP_StoSW | HOLE )
+
+struct block
+{
+ int r1, c1;
+ long b1;
+ int r2, c2;
+ long b2;
+};
+
+// blocking masks for diagonal traces
+static struct block blocking[8] =
+{ {
+ 0, -1,
+ BLOCK_NORTHEAST,
+ 1, 0,
+ BLOCK_SOUTHWEST
+ },
+ {
+ 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ 1, 0,
+ BLOCK_SOUTHEAST,
+ 0, 1,
+ BLOCK_NORTHWEST
+ },
+ {
+ 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ 0, -1,
+ BLOCK_SOUTHEAST,
+ -1, 0,
+ BLOCK_NORTHWEST
+ },
+ {
+ 0, 0, 0,
+ 0, 0, 0
+ },
+ {
+ -1, 0,
+ BLOCK_NORTHEAST,
+ 0, 1,
+ BLOCK_SOUTHWEST
+ } };
+
+// mask for hole-related blocking effects
+static struct
+{
+ long trace;
+ int present;
+} selfok2[8] =
+{
+ { HOLE_NORTHWEST, 0 },
+ { HOLE_NORTH, 0 },
+ { HOLE_NORTHEAST, 0 },
+ { HOLE_WEST, 0 },
+ { HOLE_EAST, 0 },
+ { HOLE_SOUTHWEST, 0 },
+ { HOLE_SOUTH, 0 },
+ { HOLE_SOUTHEAST, 0 }
+};
+
+static long newmask[8] =
+{
+ // patterns to mask out in neighbor cells
+ 0,
+ CORNER_NORTHWEST | CORNER_NORTHEAST,
+ 0,
+ CORNER_NORTHWEST | CORNER_SOUTHWEST,
+ CORNER_NORTHEAST | CORNER_SOUTHEAST,
+ 0,
+ CORNER_SOUTHWEST | CORNER_SOUTHEAST,
+ 0
+};
+
+
+/* Route all traces
+ * :
+ * 1 if OK
+ * -1 if escape (stop being routed) request
+ * -2 if default memory allocation
+ */
+int PCB_EDIT_FRAME::Solve( wxDC* DC, int aLayersCount )
+{
+ int current_net_code;
+ int row_source, col_source, row_target, col_target;
+ int success, nbsucces = 0, nbunsucces = 0;
+ NETINFO_ITEM* net;
+ bool stop = false;
+ wxString msg;
+ int routedCount = 0; // routed ratsnest count
+ bool two_sides = aLayersCount == 2;
+
+ m_canvas->SetAbortRequest( false );
+
+ s_Clearance = GetBoard()->GetDesignSettings().GetDefault()->GetClearance();
+
+ // Prepare the undo command info
+ s_ItemsListPicker.ClearListAndDeleteItems(); // Should not be necessary, but...
+
+ // go until no more work to do
+ GetWork( &row_source, &col_source, &current_net_code,
+ &row_target, &col_target, &pt_cur_ch ); // First net to route.
+
+ for( ; row_source != ILLEGAL; GetWork( &row_source, &col_source,
+ &current_net_code, &row_target,
+ &col_target,
+ &pt_cur_ch ) )
+ {
+ // Test to stop routing ( escape key pressed )
+ wxYield();
+
+ if( m_canvas->GetAbortRequest() )
+ {
+ if( IsOK( this, _( "Abort routing?" ) ) )
+ {
+ success = STOP_FROM_ESC;
+ stop = true;
+ break;
+ }
+ else
+ {
+ m_canvas->SetAbortRequest( false );
+ }
+ }
+
+ EraseMsgBox();
+
+ routedCount++;
+ net = GetBoard()->FindNet( current_net_code );
+
+ if( net )
+ {
+ msg.Printf( wxT( "[%8.8s]" ), GetChars( net->GetNetname() ) );
+ AppendMsgPanel( wxT( "Net route" ), msg, BROWN );
+ msg.Printf( wxT( "%d / %d" ), routedCount, RoutingMatrix.m_RouteCount );
+ AppendMsgPanel( wxT( "Activity" ), msg, BROWN );
+ }
+
+ segm_oX = GetBoard()->GetBoundingBox().GetX() + (RoutingMatrix.m_GridRouting * col_source);
+ segm_oY = GetBoard()->GetBoundingBox().GetY() + (RoutingMatrix.m_GridRouting * row_source);
+ segm_fX = GetBoard()->GetBoundingBox().GetX() + (RoutingMatrix.m_GridRouting * col_target);
+ segm_fY = GetBoard()->GetBoundingBox().GetY() + (RoutingMatrix.m_GridRouting * row_target);
+
+ // Draw segment.
+ GRLine( m_canvas->GetClipBox(), DC,
+ segm_oX, segm_oY, segm_fX, segm_fY,
+ 0, WHITE );
+ pt_cur_ch->m_PadStart->Draw( m_canvas, DC, GR_OR | GR_HIGHLIGHT );
+ pt_cur_ch->m_PadEnd->Draw( m_canvas, DC, GR_OR | GR_HIGHLIGHT );
+
+ success = Autoroute_One_Track( this, DC,
+ two_sides, row_source, col_source,
+ row_target, col_target, pt_cur_ch );
+
+ switch( success )
+ {
+ case NOSUCCESS:
+ pt_cur_ch->m_Status |= CH_UNROUTABLE;
+ nbunsucces++;
+ break;
+
+ case STOP_FROM_ESC:
+ stop = true;
+ break;
+
+ case ERR_MEMORY:
+ stop = true;
+ break;
+
+ default:
+ nbsucces++;
+ break;
+ }
+
+ msg.Printf( wxT( "%d" ), nbsucces );
+ AppendMsgPanel( wxT( "OK" ), msg, GREEN );
+ msg.Printf( wxT( "%d" ), nbunsucces );
+ AppendMsgPanel( wxT( "Fail" ), msg, RED );
+ msg.Printf( wxT( " %d" ), GetBoard()->GetUnconnectedNetCount() );
+ AppendMsgPanel( wxT( "Not Connected" ), msg, CYAN );
+
+ // Delete routing from display.
+ pt_cur_ch->m_PadStart->Draw( m_canvas, DC, GR_AND );
+ pt_cur_ch->m_PadEnd->Draw( m_canvas, DC, GR_AND );
+
+ if( stop )
+ break;
+ }
+
+ SaveCopyInUndoList( s_ItemsListPicker, UR_UNSPECIFIED );
+ s_ItemsListPicker.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
+
+ return SUCCESS;
+}
+
+
+/* Route a trace on the BOARD.
+ * Parameters:
+ * 1 side / 2 sides (0 / 1)
+ * Coord source (row, col)
+ * Coord destination (row, col)
+ * Net_code
+ * Pointer to the ratsnest reference
+ *
+ * Returns:
+ * SUCCESS if routed
+ * TRIVIAL_SUCCESS if pads are connected by overlay (no track needed)
+ * If failure NOSUCCESS
+ * Escape STOP_FROM_ESC if demand
+ * ERR_MEMORY if memory allocation failed.
+ */
+static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
+ wxDC* DC,
+ int two_sides,
+ int row_source,
+ int col_source,
+ int row_target,
+ int col_target,
+ RATSNEST_ITEM* pt_rat )
+{
+ int r, c, side, d, apx_dist, nr, nc;
+ int result, skip;
+ int i;
+ long curcell, newcell, buddy, lastopen, lastclos, lastmove;
+ int newdist, olddir, _self;
+ int current_net_code;
+ int marge;
+ LSET padLayerMaskStart; // Mask layers belonging to the starting pad.
+ LSET padLayerMaskEnd; // Mask layers belonging to the ending pad.
+
+ LSET topLayerMask( g_Route_Layer_TOP );
+
+ LSET bottomLayerMask( g_Route_Layer_BOTTOM );
+
+ LSET routeLayerMask; // Mask two layers for routing.
+
+ LSET tab_mask[2]; // Enables the calculation of the mask layer being
+ // tested. (side = TOP or BOTTOM)
+ int start_mask_layer = 0;
+ wxString msg;
+
+ // @todo this could be a bottle neck
+ LSET all_cu = LSET::AllCuMask( pcbframe->GetBoard()->GetCopperLayerCount() );
+
+ wxBusyCursor dummy_cursor; // Set an hourglass cursor while routing a
+ // track
+
+ result = NOSUCCESS;
+
+ marge = s_Clearance + ( pcbframe->GetDesignSettings().GetCurrentTrackWidth() / 2 );
+
+ // clear direction flags
+ i = RoutingMatrix.m_Nrows * RoutingMatrix.m_Ncols * sizeof(DIR_CELL);
+
+ if( two_sides )
+ memset( RoutingMatrix.m_DirSide[TOP], FROM_NOWHERE, i );
+ memset( RoutingMatrix.m_DirSide[BOTTOM], FROM_NOWHERE, i );
+
+ lastopen = lastclos = lastmove = 0;
+
+ // Set tab_masque[side] for final test of routing.
+ if( two_sides )
+ tab_mask[TOP] = topLayerMask;
+ tab_mask[BOTTOM] = bottomLayerMask;
+
+ // Set active layers mask.
+ routeLayerMask = topLayerMask | bottomLayerMask;
+
+ pt_cur_ch = pt_rat;
+
+ current_net_code = pt_rat->GetNet();
+ padLayerMaskStart = pt_cur_ch->m_PadStart->GetLayerSet();
+
+ padLayerMaskEnd = pt_cur_ch->m_PadEnd->GetLayerSet();
+
+
+ /* First Test if routing possible ie if the pads are accessible
+ * on the routing layers.
+ */
+ if( ( routeLayerMask & padLayerMaskStart ) == 0 )
+ goto end_of_route;
+
+ if( ( routeLayerMask & padLayerMaskEnd ) == 0 )
+ goto end_of_route;
+
+ /* Then test if routing possible ie if the pads are accessible
+ * On the routing grid (1 grid point must be in the pad)
+ */
+ {
+ int cX = ( RoutingMatrix.m_GridRouting * col_source )
+ + pcbframe->GetBoard()->GetBoundingBox().GetX();
+ int cY = ( RoutingMatrix.m_GridRouting * row_source )
+ + pcbframe->GetBoard()->GetBoundingBox().GetY();
+ int dx = pt_cur_ch->m_PadStart->GetSize().x / 2;
+ int dy = pt_cur_ch->m_PadStart->GetSize().y / 2;
+ int px = pt_cur_ch->m_PadStart->GetPosition().x;
+ int py = pt_cur_ch->m_PadStart->GetPosition().y;
+
+ if( ( ( int( pt_cur_ch->m_PadStart->GetOrientation() ) / 900 ) & 1 ) != 0 )
+ std::swap( dx, dy );
+
+ if( ( abs( cX - px ) > dx ) || ( abs( cY - py ) > dy ) )
+ goto end_of_route;
+
+ cX = ( RoutingMatrix.m_GridRouting * col_target )
+ + pcbframe->GetBoard()->GetBoundingBox().GetX();
+ cY = ( RoutingMatrix.m_GridRouting * row_target )
+ + pcbframe->GetBoard()->GetBoundingBox().GetY();
+ dx = pt_cur_ch->m_PadEnd->GetSize().x / 2;
+ dy = pt_cur_ch->m_PadEnd->GetSize().y / 2;
+ px = pt_cur_ch->m_PadEnd->GetPosition().x;
+ py = pt_cur_ch->m_PadEnd->GetPosition().y;
+
+ if( ( ( int( pt_cur_ch->m_PadEnd->GetOrientation() ) / 900) & 1 ) != 0 )
+ std::swap( dx, dy );
+
+ if( ( abs( cX - px ) > dx ) || ( abs( cY - py ) > dy ) )
+ goto end_of_route;
+ }
+
+ // Test the trivial case: direct connection overlay pads.
+ if( row_source == row_target && col_source == col_target &&
+ ( padLayerMaskEnd & padLayerMaskStart & all_cu ).any() )
+ {
+ result = TRIVIAL_SUCCESS;
+ goto end_of_route;
+ }
+
+ // Placing the bit to remove obstacles on 2 pads to a link.
+ pcbframe->SetStatusText( wxT( "Gen Cells" ) );
+
+ PlacePad( pt_cur_ch->m_PadStart, CURRENT_PAD, marge, WRITE_OR_CELL );
+ PlacePad( pt_cur_ch->m_PadEnd, CURRENT_PAD, marge, WRITE_OR_CELL );
+
+ // Regenerates the remaining barriers (which may encroach on the
+ // placement bits precedent)
+ i = pcbframe->GetBoard()->GetPadCount();
+
+ for( unsigned ii = 0; ii < pcbframe->GetBoard()->GetPadCount(); ii++ )
+ {
+ D_PAD* ptr = pcbframe->GetBoard()->GetPad( ii );
+
+ if( ( pt_cur_ch->m_PadStart != ptr ) && ( pt_cur_ch->m_PadEnd != ptr ) )
+ {
+ PlacePad( ptr, ~CURRENT_PAD, marge, WRITE_AND_CELL );
+ }
+ }
+
+ InitQueue(); // initialize the search queue
+ apx_dist = RoutingMatrix.GetApxDist( row_source, col_source, row_target, col_target );
+
+ // Initialize first search.
+ if( two_sides ) // Preferred orientation.
+ {
+ if( abs( row_target - row_source ) > abs( col_target - col_source ) )
+ {
+ if( ( padLayerMaskStart & topLayerMask ).any() )
+ {
+ start_mask_layer = 2;
+
+ if( SetQueue( row_source, col_source, TOP, 0, apx_dist,
+ row_target, col_target ) == 0 )
+ {
+ return ERR_MEMORY;
+ }
+ }
+
+ if( ( padLayerMaskStart & bottomLayerMask ).any() )
+ {
+ start_mask_layer |= 1;
+
+ if( SetQueue( row_source, col_source, BOTTOM, 0, apx_dist,
+ row_target, col_target ) == 0 )
+ {
+ return ERR_MEMORY;
+ }
+ }
+ }
+ else
+ {
+ if( ( padLayerMaskStart & bottomLayerMask ).any() )
+ {
+ start_mask_layer = 1;
+
+ if( SetQueue( row_source, col_source, BOTTOM, 0, apx_dist,
+ row_target, col_target ) == 0 )
+ {
+ return ERR_MEMORY;
+ }
+ }
+
+ if( ( padLayerMaskStart & topLayerMask ).any() )
+ {
+ start_mask_layer |= 2;
+
+ if( SetQueue( row_source, col_source, TOP, 0, apx_dist,
+ row_target, col_target ) == 0 )
+ {
+ return ERR_MEMORY;
+ }
+ }
+ }
+ }
+ else if( ( padLayerMaskStart & bottomLayerMask ).any() )
+ {
+ start_mask_layer = 1;
+
+ if( SetQueue( row_source, col_source, BOTTOM, 0, apx_dist, row_target, col_target ) == 0 )
+ {
+ return ERR_MEMORY;
+ }
+ }
+
+ // search until success or we exhaust all possibilities
+ GetQueue( &r, &c, &side, &d, &apx_dist );
+
+ for( ; r != ILLEGAL; GetQueue( &r, &c, &side, &d, &apx_dist ) )
+ {
+ curcell = RoutingMatrix.GetCell( r, c, side );
+
+ if( curcell & CURRENT_PAD )
+ curcell &= ~HOLE;
+
+ if( (r == row_target) && (c == col_target) // success if layer OK
+ && (tab_mask[side] & padLayerMaskEnd).any() )
+ {
+ // Remove link.
+ GRSetDrawMode( DC, GR_XOR );
+ GRLine( pcbframe->GetCanvas()->GetClipBox(),
+ DC,
+ segm_oX,
+ segm_oY,
+ segm_fX,
+ segm_fY,
+ 0,
+ WHITE );
+
+ // Generate trace.
+ if( Retrace( pcbframe, DC, row_source, col_source,
+ row_target, col_target, side, current_net_code ) )
+ {
+ result = SUCCESS; // Success : Route OK
+ }
+
+ break; // Routing complete.
+ }
+
+ if( pcbframe->GetCanvas()->GetAbortRequest() )
+ {
+ result = STOP_FROM_ESC;
+ break;
+ }
+
+ // report every COUNT new nodes or so
+ #define COUNT 20000
+
+ if( ( OpenNodes - lastopen > COUNT )
+ || ( ClosNodes - lastclos > COUNT )
+ || ( MoveNodes - lastmove > COUNT ) )
+ {
+ lastopen = OpenNodes;
+ lastclos = ClosNodes;
+ lastmove = MoveNodes;
+ msg.Printf( wxT( "Activity: Open %d Closed %d Moved %d" ),
+ OpenNodes, ClosNodes, MoveNodes );
+ pcbframe->SetStatusText( msg );
+ }
+
+ _self = 0;
+
+ if( curcell & HOLE )
+ {
+ _self = 5;
+
+ // set 'present' bits
+ for( i = 0; i < 8; i++ )
+ {
+ selfok2[i].present = 0;
+
+ if( curcell & selfok2[i].trace )
+ selfok2[i].present = 1;
+ }
+ }
+
+ for( i = 0; i < 8; i++ ) // consider neighbors
+ {
+ nr = r + delta[i][0];
+ nc = c + delta[i][1];
+
+ // off the edge?
+ if( nr < 0 || nr >= RoutingMatrix.m_Nrows ||
+ nc < 0 || nc >= RoutingMatrix.m_Ncols )
+ continue; // off the edge
+
+ if( _self == 5 && selfok2[i].present )
+ continue;
+
+ newcell = RoutingMatrix.GetCell( nr, nc, side );
+
+ if( newcell & CURRENT_PAD )
+ newcell &= ~HOLE;
+
+ // check for non-target hole
+ if( newcell & HOLE )
+ {
+ if( nr != row_target || nc != col_target )
+ continue;
+ }
+ // check for traces
+ else if( newcell & HOLE & ~(newmask[i]) )
+ {
+ continue;
+ }
+
+ // check blocking on corner neighbors
+ if( delta[i][0] && delta[i][1] )
+ {
+ // check first buddy
+ buddy = RoutingMatrix.GetCell( r + blocking[i].r1, c + blocking[i].c1, side );
+
+ if( buddy & CURRENT_PAD )
+ buddy &= ~HOLE;
+
+ if( buddy & HOLE )
+ continue;
+
+// if (buddy & (blocking[i].b1)) continue;
+ // check second buddy
+ buddy = RoutingMatrix.GetCell( r + blocking[i].r2, c + blocking[i].c2, side );
+
+ if( buddy & CURRENT_PAD )
+ buddy &= ~HOLE;
+
+ if( buddy & HOLE )
+ continue;
+
+// if (buddy & (blocking[i].b2)) continue;
+ }
+
+ olddir = RoutingMatrix.GetDir( r, c, side );
+ newdist = d + RoutingMatrix.CalcDist( ndir[i], olddir,
+ ( olddir == FROM_OTHERSIDE ) ?
+ RoutingMatrix.GetDir( r, c, 1 - side ) : 0, side );
+
+ // if (a) not visited yet, or (b) we have
+ // found a better path, add it to queue
+ if( !RoutingMatrix.GetDir( nr, nc, side ) )
+ {
+ RoutingMatrix.SetDir( nr, nc, side, ndir[i] );
+ RoutingMatrix.SetDist( nr, nc, side, newdist );
+
+ if( SetQueue( nr, nc, side, newdist,
+ RoutingMatrix.GetApxDist( nr, nc, row_target, col_target ),
+ row_target, col_target ) == 0 )
+ {
+ return ERR_MEMORY;
+ }
+ }
+ else if( newdist < RoutingMatrix.GetDist( nr, nc, side ) )
+ {
+ RoutingMatrix.SetDir( nr, nc, side, ndir[i] );
+ RoutingMatrix.SetDist( nr, nc, side, newdist );
+ ReSetQueue( nr, nc, side, newdist,
+ RoutingMatrix.GetApxDist( nr, nc, row_target, col_target ),
+ row_target, col_target );
+ }
+ }
+
+ //* Test the other layer. *
+ if( two_sides )
+ {
+ olddir = RoutingMatrix.GetDir( r, c, side );
+
+ if( olddir == FROM_OTHERSIDE )
+ continue; // useless move, so don't bother
+
+ if( curcell ) // can't drill via if anything here
+ continue;
+
+ // check for holes or traces on other side
+ if( ( newcell = RoutingMatrix.GetCell( r, c, 1 - side ) ) != 0 )
+ continue;
+
+ // check for nearby holes or traces on both sides
+ for( skip = 0, i = 0; i < 8; i++ )
+ {
+ nr = r + delta[i][0]; nc = c + delta[i][1];
+
+ if( nr < 0 || nr >= RoutingMatrix.m_Nrows ||
+ nc < 0 || nc >= RoutingMatrix.m_Ncols )
+ continue; // off the edge !!
+
+ if( RoutingMatrix.GetCell( nr, nc, side ) /* & blocking2[i] */ )
+ {
+ skip = 1; // can't drill via here
+ break;
+ }
+
+ if( RoutingMatrix.GetCell( nr, nc, 1 - side ) /* & blocking2[i] */ )
+ {
+ skip = 1; // can't drill via here
+ break;
+ }
+ }
+
+ if( skip ) // neighboring hole or trace?
+ continue; // yes, can't drill via here
+
+ newdist = d + RoutingMatrix.CalcDist( FROM_OTHERSIDE, olddir, 0, side );
+
+ /* if (a) not visited yet,
+ * or (b) we have found a better path,
+ * add it to queue */
+ if( !RoutingMatrix.GetDir( r, c, 1 - side ) )
+ {
+ RoutingMatrix.SetDir( r, c, 1 - side, FROM_OTHERSIDE );
+ RoutingMatrix.SetDist( r, c, 1 - side, newdist );
+
+ if( SetQueue( r, c, 1 - side, newdist, apx_dist, row_target, col_target ) == 0 )
+ {
+ return ERR_MEMORY;
+ }
+ }
+ else if( newdist < RoutingMatrix.GetDist( r, c, 1 - side ) )
+ {
+ RoutingMatrix.SetDir( r, c, 1 - side, FROM_OTHERSIDE );
+ RoutingMatrix.SetDist( r, c, 1 - side, newdist );
+ ReSetQueue( r, c,
+ 1 - side,
+ newdist,
+ apx_dist,
+ row_target,
+ col_target );
+ }
+ } // Finished attempt to route on other layer.
+ }
+
+end_of_route:
+ PlacePad( pt_cur_ch->m_PadStart, ~CURRENT_PAD, marge, WRITE_AND_CELL );
+ PlacePad( pt_cur_ch->m_PadEnd, ~CURRENT_PAD, marge, WRITE_AND_CELL );
+
+ msg.Printf( wxT( "Activity: Open %d Closed %d Moved %d"),
+ OpenNodes, ClosNodes, MoveNodes );
+ pcbframe->SetStatusText( msg );
+
+ return result;
+}
+
+
+static long bit[8][9] =
+{
+ // OT=Otherside
+ // N, NE, E, SE, S, SW, W, NW, OT
+// N
+ { LINE_VERTICAL,
+ BENT_StoNE,
+ CORNER_SOUTHEAST,
+ SHARP_StoSE,
+ 0,
+ SHARP_StoSW,
+ CORNER_SOUTHWEST,
+ BENT_StoNW,
+ ( HOLE | HOLE_SOUTH )
+ },
+// NE
+ {
+ BENT_NtoSW,
+ DIAG_NEtoSW,
+ BENT_EtoSW,
+ ANGLE_SEtoSW,
+ SHARP_StoSW,
+ 0,
+ SHARP_WtoSW,
+ ANGLE_SWtoNW,
+ ( HOLE | HOLE_SOUTHWEST )
+ },
+// E
+ {
+ CORNER_NORTHWEST,
+ BENT_WtoNE,
+ LINE_HORIZONTAL,
+ BENT_WtoSE,
+ CORNER_SOUTHWEST,
+ SHARP_WtoSW,
+ 0,
+ SHARP_WtoNW,
+ ( HOLE | HOLE_WEST )
+ },
+// SE
+ {
+ SHARP_NtoNW,
+ ANGLE_NWtoNE,
+ BENT_EtoNW,
+ DIAG_SEtoNW,
+ BENT_StoNW,
+ ANGLE_SWtoNW,
+ SHARP_WtoNW,
+ 0,
+ ( HOLE | HOLE_NORTHWEST )
+ },
+// S
+ {
+ 0,
+ SHARP_NtoNE,
+ CORNER_NORTHEAST,
+ BENT_NtoSE,
+ LINE_VERTICAL,
+ BENT_NtoSW,
+ CORNER_NORTHWEST,
+ SHARP_NtoNW,
+ ( HOLE | HOLE_NORTH )
+ },
+// SW
+ {
+ SHARP_NtoNE,
+ 0,
+ SHARP_EtoNE,
+ ANGLE_NEtoSE,
+ BENT_StoNE,
+ DIAG_NEtoSW,
+ BENT_WtoNE,
+ ANGLE_NWtoNE,
+ ( HOLE | HOLE_NORTHEAST )
+ },
+// W
+ {
+ CORNER_NORTHEAST,
+ SHARP_EtoNE,
+ 0,
+ SHARP_EtoSE,
+ CORNER_SOUTHEAST,
+ BENT_EtoSW,
+ LINE_HORIZONTAL,
+ BENT_EtoNW,
+ ( HOLE | HOLE_EAST )
+ },
+// NW
+ {
+ BENT_NtoSE,
+ ANGLE_NEtoSE,
+ SHARP_EtoSE,
+ 0,
+ SHARP_StoSE,
+ ANGLE_SEtoSW,
+ BENT_WtoSE,
+ DIAG_SEtoNW,
+ ( HOLE | HOLE_SOUTHEAST )
+ }
+};
+
+
+/* work from target back to source, actually laying the traces
+ * Parameters:
+ * start on side target_side, of coordinates row_target, col_target.
+ * arrive on side masque_layer_start, coordinate row_source, col_source
+ * The search is done in reverse routing, the point of arrival (target) to
+ * the starting point (source)
+ * The router.
+ *
+ * Target_side = symbol (TOP / BOTTOM) of departure
+ * = Mask_layer_source mask layers Arrival
+ *
+ * Returns:
+ * 0 if error
+ * > 0 if Ok
+ */
+static int Retrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC,
+ int row_source, int col_source,
+ int row_target, int col_target, int target_side,
+ int current_net_code )
+{
+ int r0, c0, s0;
+ int r1, c1, s1; // row, col, starting side.
+ int r2, c2, s2; // row, col, ending side.
+ int x, y = -1;
+ long b;
+
+ r1 = row_target;
+ c1 = col_target; // start point is target ( end point is source )
+ s1 = target_side;
+ r0 = c0 = s0 = ILLEGAL;
+
+ wxASSERT( g_CurrentTrackList.GetCount() == 0 );
+
+ do
+ {
+ // find where we came from to get here
+ r2 = r1; c2 = c1; s2 = s1;
+ x = RoutingMatrix.GetDir( r1, c1, s1 );
+
+ switch( x )
+ {
+ case FROM_NORTH:
+ r2++;
+ break;
+
+ case FROM_EAST:
+ c2++;
+ break;
+
+ case FROM_SOUTH:
+ r2--;
+ break;
+
+ case FROM_WEST:
+ c2--;
+ break;
+
+ case FROM_NORTHEAST:
+ r2++;
+ c2++;
+ break;
+
+ case FROM_SOUTHEAST:
+ r2--;
+ c2++;
+ break;
+
+ case FROM_SOUTHWEST:
+ r2--;
+ c2--;
+ break;
+
+ case FROM_NORTHWEST:
+ r2++;
+ c2--;
+ break;
+
+ case FROM_OTHERSIDE:
+ s2 = 1 - s2;
+ break;
+
+ default:
+ wxMessageBox( wxT( "Retrace: internal error: no way back" ) );
+ return 0;
+ }
+
+ if( r0 != ILLEGAL )
+ y = RoutingMatrix.GetDir( r0, c0, s0 );
+
+ // see if target or hole
+ if( ( ( r1 == row_target ) && ( c1 == col_target ) ) || ( s1 != s0 ) )
+ {
+ int p_dir;
+
+ switch( x )
+ {
+ case FROM_NORTH:
+ p_dir = HOLE_NORTH;
+ break;
+
+ case FROM_EAST:
+ p_dir = HOLE_EAST;
+ break;
+
+ case FROM_SOUTH:
+ p_dir = HOLE_SOUTH;
+ break;
+
+ case FROM_WEST:
+ p_dir = HOLE_WEST;
+ break;
+
+ case FROM_NORTHEAST:
+ p_dir = HOLE_NORTHEAST;
+ break;
+
+ case FROM_SOUTHEAST:
+ p_dir = HOLE_SOUTHEAST;
+ break;
+
+ case FROM_SOUTHWEST:
+ p_dir = HOLE_SOUTHWEST;
+ break;
+
+ case FROM_NORTHWEST:
+ p_dir = HOLE_NORTHWEST;
+ break;
+
+ case FROM_OTHERSIDE:
+ default:
+ DisplayError( pcbframe, wxT( "Retrace: error 1" ) );
+ return 0;
+ }
+
+ OrCell_Trace( pcbframe->GetBoard(), r1, c1, s1, p_dir, current_net_code );
+ }
+ else
+ {
+ if( ( y == FROM_NORTH || y == FROM_NORTHEAST
+ || y == FROM_EAST || y == FROM_SOUTHEAST
+ || y == FROM_SOUTH || y == FROM_SOUTHWEST
+ || y == FROM_WEST || y == FROM_NORTHWEST )
+ && ( x == FROM_NORTH || x == FROM_NORTHEAST
+ || x == FROM_EAST || x == FROM_SOUTHEAST
+ || x == FROM_SOUTH || x == FROM_SOUTHWEST
+ || x == FROM_WEST || x == FROM_NORTHWEST
+ || x == FROM_OTHERSIDE )
+ && ( ( b = bit[y - 1][x - 1] ) != 0 ) )
+ {
+ OrCell_Trace( pcbframe->GetBoard(), r1, c1, s1, b, current_net_code );
+
+ if( b & HOLE )
+ OrCell_Trace( pcbframe->GetBoard(), r2, c2, s2, HOLE, current_net_code );
+ }
+ else
+ {
+ wxMessageBox( wxT( "Retrace: error 2" ) );
+ return 0;
+ }
+ }
+
+ if( ( r2 == row_source ) && ( c2 == col_source ) ) // see if source
+ {
+ int p_dir;
+
+ switch( x )
+ {
+ case FROM_NORTH:
+ p_dir = HOLE_SOUTH;
+ break;
+
+ case FROM_EAST:
+ p_dir = HOLE_WEST;
+ break;
+
+ case FROM_SOUTH:
+ p_dir = HOLE_NORTH;
+ break;
+
+ case FROM_WEST:
+ p_dir = HOLE_EAST;
+ break;
+
+ case FROM_NORTHEAST:
+ p_dir = HOLE_SOUTHWEST;
+ break;
+
+ case FROM_SOUTHEAST:
+ p_dir = HOLE_NORTHWEST;
+ break;
+
+ case FROM_SOUTHWEST:
+ p_dir = HOLE_NORTHEAST;
+ break;
+
+ case FROM_NORTHWEST:
+ p_dir = HOLE_SOUTHEAST;
+ break;
+
+ case FROM_OTHERSIDE:
+ default:
+ wxMessageBox( wxT( "Retrace: error 3" ) );
+ return 0;
+ }
+
+ OrCell_Trace( pcbframe->GetBoard(), r2, c2, s2, p_dir, current_net_code );
+ }
+
+ // move to next cell
+ r0 = r1;
+ c0 = c1;
+ s0 = s1;
+ r1 = r2;
+ c1 = c2;
+ s1 = s2;
+ } while( !( ( r2 == row_source ) && ( c2 == col_source ) ) );
+
+ AddNewTrace( pcbframe, DC );
+ return 1;
+}
+
+
+/* This function is used by Retrace and read the autorouting matrix data cells to create
+ * the real track on the physical board
+ */
+static void OrCell_Trace( BOARD* pcb, int col, int row,
+ int side, int orient, int current_net_code )
+{
+ if( orient == HOLE ) // placement of a via
+ {
+ VIA *newVia = new VIA( pcb );
+
+ g_CurrentTrackList.PushBack( newVia );
+
+ g_CurrentTrackSegment->SetState( TRACK_AR, true );
+ g_CurrentTrackSegment->SetLayer( F_Cu );
+
+ g_CurrentTrackSegment->SetStart(wxPoint( pcb->GetBoundingBox().GetX() +
+ ( RoutingMatrix.m_GridRouting * row ),
+ pcb->GetBoundingBox().GetY() +
+ ( RoutingMatrix.m_GridRouting * col )));
+ g_CurrentTrackSegment->SetEnd( g_CurrentTrackSegment->GetStart() );
+
+ g_CurrentTrackSegment->SetWidth( pcb->GetDesignSettings().GetCurrentViaSize() );
+ newVia->SetViaType( pcb->GetDesignSettings().m_CurrentViaType );
+
+ g_CurrentTrackSegment->SetNetCode( current_net_code );
+ }
+ else // placement of a standard segment
+ {
+ TRACK *newTrack = new TRACK( pcb );
+ int dx0, dy0, dx1, dy1;
+
+
+ g_CurrentTrackList.PushBack( newTrack );
+
+ g_CurrentTrackSegment->SetLayer( g_Route_Layer_BOTTOM );
+
+ if( side == TOP )
+ g_CurrentTrackSegment->SetLayer( g_Route_Layer_TOP );
+
+ g_CurrentTrackSegment->SetState( TRACK_AR, true );
+ g_CurrentTrackSegment->SetEnd( wxPoint( pcb->GetBoundingBox().GetX() +
+ ( RoutingMatrix.m_GridRouting * row ),
+ pcb->GetBoundingBox().GetY() +
+ ( RoutingMatrix.m_GridRouting * col )));
+ g_CurrentTrackSegment->SetNetCode( current_net_code );
+
+ if( g_CurrentTrackSegment->Back() == NULL ) // Start trace.
+ {
+ g_CurrentTrackSegment->SetStart( wxPoint( segm_fX, segm_fY ) );
+
+ // Placement on the center of the pad if outside grid.
+ dx1 = g_CurrentTrackSegment->GetEnd().x - g_CurrentTrackSegment->GetStart().x;
+ dy1 = g_CurrentTrackSegment->GetEnd().y - g_CurrentTrackSegment->GetStart().y;
+
+ dx0 = pt_cur_ch->m_PadEnd->GetPosition().x - g_CurrentTrackSegment->GetStart().x;
+ dy0 = pt_cur_ch->m_PadEnd->GetPosition().y - g_CurrentTrackSegment->GetStart().y;
+
+ // If aligned, change the origin point.
+ if( abs( dx0 * dy1 ) == abs( dx1 * dy0 ) )
+ {
+ g_CurrentTrackSegment->SetStart( pt_cur_ch->m_PadEnd->GetPosition() );
+ }
+ else // Creation of a supplemental segment
+ {
+ g_CurrentTrackSegment->SetStart( pt_cur_ch->m_PadEnd->GetPosition() );
+
+ newTrack = (TRACK*)g_CurrentTrackSegment->Clone();
+ newTrack->SetStart( g_CurrentTrackSegment->GetEnd());
+
+ g_CurrentTrackList.PushBack( newTrack );
+ }
+ }
+ else
+ {
+ if( g_CurrentTrackSegment->Back() )
+ {
+ g_CurrentTrackSegment->SetStart( g_CurrentTrackSegment->Back()->GetEnd() );
+ }
+ }
+
+ g_CurrentTrackSegment->SetWidth( pcb->GetDesignSettings().GetCurrentTrackWidth() );
+
+ if( g_CurrentTrackSegment->GetStart() != g_CurrentTrackSegment->GetEnd() )
+ {
+ // Reduce aligned segments by one.
+ TRACK* oldTrack = g_CurrentTrackSegment->Back();
+
+ if( oldTrack && oldTrack->Type() != PCB_VIA_T )
+ {
+ dx1 = g_CurrentTrackSegment->GetEnd().x - g_CurrentTrackSegment->GetStart().x;
+ dy1 = g_CurrentTrackSegment->GetEnd().y - g_CurrentTrackSegment->GetStart().y;
+
+ dx0 = oldTrack->GetEnd().x - oldTrack->GetStart().x;
+ dy0 = oldTrack->GetEnd().y - oldTrack->GetStart().y;
+
+ if( abs( dx0 * dy1 ) == abs( dx1 * dy0 ) )
+ {
+ oldTrack->SetEnd( g_CurrentTrackSegment->GetEnd() );
+
+ delete g_CurrentTrackList.PopBack();
+ }
+ }
+ }
+ }
+}
+
+
+/* Insert the new track created in the list of tracks.
+ * amend the points of beginning and end of the track so that they are
+ * connected
+ * Center on pads even if they are off grid.
+ */
+static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC )
+{
+ if( g_FirstTrackSegment == NULL )
+ return;
+
+ int dx0, dy0, dx1, dy1;
+ int marge, via_marge;
+ EDA_DRAW_PANEL* panel = pcbframe->GetCanvas();
+ PCB_SCREEN* screen = pcbframe->GetScreen();
+
+ marge = s_Clearance + ( pcbframe->GetDesignSettings().GetCurrentTrackWidth() / 2 );
+ via_marge = s_Clearance + ( pcbframe->GetDesignSettings().GetCurrentViaSize() / 2 );
+
+ dx1 = g_CurrentTrackSegment->GetEnd().x - g_CurrentTrackSegment->GetStart().x;
+ dy1 = g_CurrentTrackSegment->GetEnd().y - g_CurrentTrackSegment->GetStart().y;
+
+ // Place on center of pad if off grid.
+ dx0 = pt_cur_ch->m_PadStart->GetPosition().x - g_CurrentTrackSegment->GetStart().x;
+ dy0 = pt_cur_ch->m_PadStart->GetPosition().y - g_CurrentTrackSegment->GetStart().y;
+
+ // If aligned, change the origin point.
+ if( abs( dx0 * dy1 ) == abs( dx1 * dy0 ) )
+ {
+ g_CurrentTrackSegment->SetEnd( pt_cur_ch->m_PadStart->GetPosition() );
+ }
+ else
+ {
+ TRACK* newTrack = (TRACK*)g_CurrentTrackSegment->Clone();
+
+ newTrack->SetEnd( pt_cur_ch->m_PadStart->GetPosition() );
+ newTrack->SetStart( g_CurrentTrackSegment->GetEnd() );
+
+ g_CurrentTrackList.PushBack( newTrack );
+ }
+
+ g_FirstTrackSegment->start = pcbframe->GetBoard()->GetPad( g_FirstTrackSegment,
+ ENDPOINT_START );
+
+ if( g_FirstTrackSegment->start )
+ g_FirstTrackSegment->SetState( BEGIN_ONPAD, true );
+
+ g_CurrentTrackSegment->end = pcbframe->GetBoard()->GetPad( g_CurrentTrackSegment,
+ ENDPOINT_END );
+
+ if( g_CurrentTrackSegment->end )
+ g_CurrentTrackSegment->SetState( END_ONPAD, true );
+
+ // Out the new track on the matrix board
+ for( TRACK* track = g_FirstTrackSegment; track; track = track->Next() )
+ {
+ TraceSegmentPcb( track, HOLE, marge, WRITE_CELL );
+ TraceSegmentPcb( track, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
+ }
+
+ // Insert new segments in real board
+ int netcode = g_FirstTrackSegment->GetNetCode();
+ TRACK* firstTrack = g_FirstTrackSegment;
+ int newCount = g_CurrentTrackList.GetCount();
+
+ // Put entire new current segment list in BOARD
+ TRACK* track;
+ TRACK* insertBeforeMe = g_CurrentTrackSegment->GetBestInsertPoint( pcbframe->GetBoard() );
+
+ while( ( track = g_CurrentTrackList.PopFront() ) != NULL )
+ {
+ ITEM_PICKER picker( track, UR_NEW );
+ s_ItemsListPicker.PushItem( picker );
+ pcbframe->GetBoard()->m_Track.Insert( track, insertBeforeMe );
+ }
+
+ DrawTraces( panel, DC, firstTrack, newCount, GR_OR );
+
+ pcbframe->TestNetConnection( DC, netcode );
+
+ screen->SetModify();
+}
diff --git a/pcbnew/autorouter/spread_footprints.cpp b/pcbnew/autorouter/spread_footprints.cpp
new file mode 100644
index 0000000..52b7106
--- /dev/null
+++ b/pcbnew/autorouter/spread_footprints.cpp
@@ -0,0 +1,362 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file spread_footprints.cpp
+ * @brief functions to spread footprints on free areas outside a board.
+ * this is usefull after reading a netlist, when new footprints are loaded
+ * and stacked at 0,0 coordinate.
+ * Often, spread them on a free area near the board being edited make more easy
+ * their selection.
+ */
+
+#include <algorithm>
+
+#include <fctsys.h>
+#include <convert_to_biu.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <class_board.h>
+#include <class_module.h>
+
+#include <rect_placement/rect_placement.h>
+
+struct TSubRect : public CRectPlacement::TRect
+{
+ int n; // Original index of this subrect, before sorting
+
+ TSubRect() : TRect(),
+ n( 0 )
+ {
+ }
+
+ TSubRect( int _w, int _h, int _n ) :
+ TRect( 0, 0, _w, _h ), n( _n ) { }
+};
+
+typedef std::vector<TSubRect> CSubRectArray;
+
+// Use 0.01 mm units to calculate placement, to avoid long calculation time
+const int scale = (int)(0.01 * IU_PER_MM);
+
+// Populates a list of rectangles, from a list of modules
+void fillRectList( CSubRectArray& vecSubRects, std::vector <MODULE*>& aModuleList )
+{
+ vecSubRects.clear();
+
+ for( unsigned ii = 0; ii < aModuleList.size(); ii++ )
+ {
+ EDA_RECT fpBox = aModuleList[ii]->GetBoundingBox();
+ TSubRect fpRect( fpBox.GetWidth()/scale, fpBox.GetHeight()/scale, ii );
+ vecSubRects.push_back( fpRect );
+ }
+}
+
+// Populates a list of rectangles, from a list of EDA_RECT
+void fillRectList( CSubRectArray& vecSubRects, std::vector <EDA_RECT>& aRectList )
+{
+ vecSubRects.clear();
+
+ for( unsigned ii = 0; ii < aRectList.size(); ii++ )
+ {
+ EDA_RECT& rect = aRectList[ii];
+ TSubRect fpRect( rect.GetWidth()/scale, rect.GetHeight()/scale, ii );
+ vecSubRects.push_back( fpRect );
+ }
+}
+
+
+
+// Spread a list of rectangles inside a placement area
+void spreadRectangles( CRectPlacement& aPlacementArea,
+ CSubRectArray& vecSubRects,
+ int areaSizeX, int areaSizeY )
+{
+ areaSizeX/= scale;
+ areaSizeY/= scale;
+
+ // Sort the subRects based on dimensions, larger dimension goes first.
+ std::sort( vecSubRects.begin(), vecSubRects.end(), CRectPlacement::TRect::Greater );
+
+ // gives the initial size to the area
+ aPlacementArea.Init( areaSizeX, areaSizeY );
+
+ // Add all subrects
+ CSubRectArray::iterator it;
+ for( it = vecSubRects.begin(); it != vecSubRects.end(); )
+ {
+ CRectPlacement::TRect r( 0, 0, it->w, it->h );
+
+ bool bPlaced = aPlacementArea.AddAtEmptySpotAutoGrow( &r, areaSizeX, areaSizeY );
+
+ if( !bPlaced ) // No room to place the rectangle: enlarge area and retry
+ {
+ areaSizeX = ceil(areaSizeX * 1.1);
+ areaSizeY = ceil(areaSizeY * 1.1);
+ aPlacementArea.Init( areaSizeX, areaSizeY );
+ it = vecSubRects.begin();
+ continue;
+ }
+
+ // When correctly placed in a placement area, the coords are returned in r.x and r.y
+ // Store them.
+ it->x = r.x;
+ it->y = r.y;
+
+ it++;
+ }
+}
+
+
+void moveFootprintsInArea( CRectPlacement& aPlacementArea,
+ std::vector <MODULE*>& aModuleList, EDA_RECT& aFreeArea,
+ bool aFindAreaOnly )
+{
+ CSubRectArray vecSubRects;
+
+ fillRectList( vecSubRects, aModuleList );
+ spreadRectangles( aPlacementArea, vecSubRects,
+ aFreeArea.GetWidth(), aFreeArea.GetHeight() );
+
+ if( aFindAreaOnly )
+ return;
+
+ for( unsigned it = 0; it < vecSubRects.size(); ++it )
+ {
+ wxPoint pos( vecSubRects[it].x, vecSubRects[it].y );
+ pos.x *= scale;
+ pos.y *= scale;
+
+ MODULE * module = aModuleList[vecSubRects[it].n];
+
+ EDA_RECT fpBBox = module->GetBoundingBox();
+ wxPoint mod_pos = pos + ( module->GetPosition() - fpBBox.GetOrigin() )
+ + aFreeArea.GetOrigin();
+
+ module->Move( mod_pos - module->GetPosition() );
+ }
+}
+
+static bool sortModulesbySheetPath( MODULE* ref, MODULE* compare );
+
+/* Function to move components in a rectangular area format 4 / 3,
+ * starting from the mouse cursor
+ * The components with the FIXED status set are not moved
+ */
+void PCB_EDIT_FRAME::SpreadFootprints( bool aFootprintsOutsideBoardOnly )
+{
+ EDA_RECT bbox = GetBoard()->ComputeBoundingBox( true );
+ bool edgesExist = ( bbox.GetWidth() || bbox.GetHeight() );
+
+ // no edges exist
+ if( aFootprintsOutsideBoardOnly && !edgesExist )
+ {
+ DisplayError( this,
+ _( "Could not automatically place footprints. No board outlines detected." ) );
+ return;
+ }
+
+ // if aFootprintsOutsideBoardOnly is true, and if board outline exists,
+ // wue have to filter footprints to move:
+ bool outsideBrdFilter = aFootprintsOutsideBoardOnly && edgesExist;
+
+ // Build candidate list
+ // calculate also the area needed by these footprints
+ MODULE* module = GetBoard()->m_Modules;
+ std::vector <MODULE*> moduleList;
+
+ for( ; module != NULL; module = module->Next() )
+ {
+ module->CalculateBoundingBox();
+
+ if( outsideBrdFilter )
+ {
+ if( bbox.Contains( module->GetPosition() ) )
+ continue;
+ }
+
+ if( module->IsLocked() )
+ continue;
+
+ moduleList.push_back(module);
+ }
+
+ if( moduleList.size() == 0 ) // Nothing to do
+ return;
+
+ // sort footprints by sheet path. we group them later by sheet
+ sort( moduleList.begin(), moduleList.end(), sortModulesbySheetPath );
+
+ // Undo command: init undo list
+ PICKED_ITEMS_LIST undoList;
+ undoList.m_Status = UR_CHANGED;
+ ITEM_PICKER picker( NULL, UR_CHANGED );
+
+ for( unsigned ii = 0; ii < moduleList.size(); ii++ )
+ {
+ module = moduleList[ii];
+
+ // Undo: add copy of module to undo list
+ picker.SetItem( module );
+ picker.SetLink( module->Clone() );
+ undoList.PushItem( picker );
+ }
+
+ // Extract and place footprints by sheet
+ std::vector <MODULE*> moduleListBySheet;
+ std::vector <EDA_RECT> placementSheetAreas;
+ double subsurface;
+ double placementsurface = 0.0;
+
+ wxPoint placementAreaPosition = GetCrossHairPosition();
+
+ // We do not want to move footprints inside an existing board.
+ // move the placement area position outside the board bounding box
+ // to the left of the board
+ if( edgesExist )
+ {
+ if( placementAreaPosition.x < bbox.GetEnd().x &&
+ placementAreaPosition.y < bbox.GetEnd().y )
+ {
+ placementAreaPosition.x = bbox.GetEnd().x;
+ placementAreaPosition.y = bbox.GetOrigin().y;
+ }
+ }
+
+ // The placement uses 2 passes:
+ // the first pass creates the rectangular areas to place footprints
+ // each sheet in schematic creates one rectangular area.
+ // the second pass moves footprints inside these areas
+ for( int pass = 0; pass < 2; pass++ )
+ {
+ int subareaIdx = 0;
+ moduleListBySheet.clear();
+ subsurface = 0.0;
+
+ for( unsigned ii = 0; ii < moduleList.size(); ii++ )
+ {
+ module = moduleList[ii];
+ bool islastItem = false;
+
+ if( ii == moduleList.size() - 1 ||
+ ( moduleList[ii]->GetPath().BeforeLast( '/' ) !=
+ moduleList[ii+1]->GetPath().BeforeLast( '/' ) ) )
+ islastItem = true;
+
+ moduleListBySheet.push_back( module );
+ subsurface += module->GetArea();
+
+ if( islastItem )
+ {
+ // end of the footprint sublist relative to the same sheet path
+ // calculate placement of the current sublist
+ EDA_RECT freeArea;
+ int Xsize_allowed = (int) ( sqrt( subsurface ) * 4.0 / 3.0 );
+ int Ysize_allowed = (int) ( subsurface / Xsize_allowed );
+
+ freeArea.SetWidth( Xsize_allowed );
+ freeArea.SetHeight( Ysize_allowed );
+ CRectPlacement placementArea;
+
+ if( pass == 1 )
+ {
+ wxPoint areapos = placementSheetAreas[subareaIdx].GetOrigin()
+ + placementAreaPosition;
+ freeArea.SetOrigin( areapos );
+ }
+
+ bool findAreaOnly = pass == 0;
+ moveFootprintsInArea( placementArea, moduleListBySheet,
+ freeArea, findAreaOnly );
+
+ if( pass == 0 )
+ {
+ // Populate sheet placement areas list
+ EDA_RECT sub_area;
+ sub_area.SetWidth( placementArea.GetW()*scale );
+ sub_area.SetHeight( placementArea.GetH()*scale );
+ // Add a margin around the sheet placement area:
+ sub_area.Inflate( Millimeter2iu( 1.5 ) );
+
+ placementSheetAreas.push_back( sub_area );
+
+ placementsurface += (double) sub_area.GetWidth()*
+ sub_area.GetHeight();
+ }
+
+ // Prepare buffers for next sheet
+ subsurface = 0.0;
+ moduleListBySheet.clear();
+ subareaIdx++;
+ }
+ }
+
+ // End of pass:
+ // At the end of the first pass, we have to find position of each sheet
+ // placement area
+ if( pass == 0 )
+ {
+ int Xsize_allowed = (int) ( sqrt( placementsurface ) * 4.0 / 3.0 );
+ int Ysize_allowed = (int) ( placementsurface / Xsize_allowed );
+ CRectPlacement placementArea;
+ CSubRectArray vecSubRects;
+
+ fillRectList( vecSubRects, placementSheetAreas );
+ spreadRectangles( placementArea, vecSubRects, Xsize_allowed, Ysize_allowed );
+
+ for( unsigned it = 0; it < vecSubRects.size(); ++it )
+ {
+ TSubRect& srect = vecSubRects[it];
+ wxPoint pos( srect.x*scale, srect.y*scale );
+ wxSize size( srect.w*scale, srect.h*scale );
+ placementSheetAreas[srect.n].SetOrigin( pos );
+ placementSheetAreas[srect.n].SetSize( size );
+ }
+ }
+ } // End pass
+
+ // Undo: commit list
+ SaveCopyInUndoList( undoList, UR_CHANGED );
+ OnModify();
+
+ m_canvas->Refresh();
+}
+
+
+// Sort function, used to group footprints by sheet.
+// Footprints are sorted by their sheet path.
+// (the full sheet path restricted to the time stamp of the sheet itself,
+// without the time stamp of the footprint ).
+static bool sortModulesbySheetPath( MODULE* ref, MODULE* compare )
+{
+ if( ref->GetPath().Length() == compare->GetPath().Length() )
+ return ref->GetPath().BeforeLast( '/' ).Cmp( compare->GetPath().BeforeLast( '/' ) ) < 0;
+
+ return ref->GetPath().Length() < compare->GetPath().Length();
+}
diff --git a/pcbnew/autorouter/work.cpp b/pcbnew/autorouter/work.cpp
new file mode 100644
index 0000000..68aa48c
--- /dev/null
+++ b/pcbnew/autorouter/work.cpp
@@ -0,0 +1,164 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * First copyright (C) Randy Nevin, 1989 (see PCBCA package)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/**
+ * @file work.cpp
+ * @brief Automatic routing routines
+ */
+
+#include <fctsys.h>
+#include <common.h>
+
+#include <pcbnew.h>
+#include <autorout.h>
+#include <cell.h>
+
+
+struct CWORK // a unit of work is a source-target to connect
+ // this is a ratsnest item in the routing matrix world
+{
+ int m_FromRow; // source row
+ int m_FromCol; // source column
+ int m_ToRow; // target row
+ int m_ToCol; // target column
+ RATSNEST_ITEM* m_Ratsnest; // Corresponding ratsnest
+ int m_NetCode; // m_NetCode
+ int m_ApxDist; // approximate distance
+ int m_Cost; // cost for sort by length
+ int m_Priority; // route priority
+
+ // the function that calculates the cost of this ratsnest:
+ void CalculateCost();
+};
+
+
+// the list of ratsnests
+static std::vector <CWORK> WorkList;
+static unsigned Current = 0;
+
+
+// initialize the work list
+void InitWork()
+{
+ WorkList.clear();
+ Current = 0;
+}
+
+
+/* add a unit of work to the work list
+ * :
+ * 1 if OK
+ * 0 if memory allocation failed
+ */
+
+int SetWork( int r1, int c1,
+ int n_c,
+ int r2, int c2,
+ RATSNEST_ITEM* pt_ch, int pri )
+{
+ CWORK item;
+ item.m_FromRow = r1;
+ item.m_FromCol = c1;
+ item.m_NetCode = n_c;
+ item.m_ToRow = r2;
+ item.m_ToCol = c2;
+ item.m_Ratsnest = pt_ch;
+ item.m_ApxDist = RoutingMatrix.GetApxDist( r1, c1, r2, c2 );
+ item.CalculateCost();
+ item.m_Priority = pri;
+ WorkList.push_back( item );
+ return 1;
+}
+
+
+/* fetch a unit of work from the work list */
+void GetWork( int* r1, int* c1,
+ int* n_c,
+ int* r2, int* c2,
+ RATSNEST_ITEM** pt_ch )
+{
+ if( Current < WorkList.size() )
+ {
+ *r1 = WorkList[Current].m_FromRow;
+ *c1 = WorkList[Current].m_FromCol;
+ *n_c = WorkList[Current].m_NetCode;
+ *r2 = WorkList[Current].m_ToRow;
+ *c2 = WorkList[Current].m_ToCol;
+ *pt_ch = WorkList[Current].m_Ratsnest;
+ Current++;
+ }
+ else /* none left */
+ {
+ *r1 = *c1 = *r2 = *c2 = ILLEGAL;
+ *n_c = 0;
+ *pt_ch = NULL;
+ }
+}
+
+
+// order the work items; shortest (low cost) first:
+bool sort_by_cost( const CWORK& ref, const CWORK& item )
+{
+ if( ref.m_Priority == item.m_Priority )
+ return ref.m_Cost < item.m_Cost;
+
+ return ref.m_Priority >= item.m_Priority;
+}
+
+void SortWork()
+{
+ sort( WorkList.begin(), WorkList.end(), sort_by_cost );
+}
+
+
+/* Calculate the cost of a ratsnest:
+ * cost = (| dx | + | dy |) * disability
+ * disability = 1 if dx or dy = 0, max if | dx | # | dy |
+ */
+void CWORK::CalculateCost()
+{
+ int dx, dy, mx, my;
+ double incl = 1.0;
+
+ dx = abs( m_ToCol - m_FromCol );
+ dy = abs( m_ToRow - m_FromRow );
+ mx = dx;
+ my = dy;
+
+ if( mx < my )
+ {
+ mx = dy; my = dx;
+ }
+
+ if( mx )
+ incl += (2 * (double) my / mx);
+
+ m_Cost = (int) ( ( dx + dy ) * incl );
+}
diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp
new file mode 100644
index 0000000..a5a5f5f
--- /dev/null
+++ b/pcbnew/basepcbframe.cpp
@@ -0,0 +1,1020 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file basepcbframe.cpp
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <wxstruct.h>
+#include <confirm.h>
+#include <kiface_i.h>
+#include <dialog_helpers.h>
+#include <kicad_device_context.h>
+#include <wxBasePcbFrame.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+#include <pcbnew.h>
+#include <fp_lib_table.h>
+#include <pcbnew_id.h>
+#include <class_board.h>
+#include <class_track.h>
+#include <class_module.h>
+#include <class_drawsegment.h>
+
+#include <collectors.h>
+#include <class_drawpanel.h>
+#include <pcb_draw_panel_gal.h>
+#include <view/view.h>
+#include <math/vector2d.h>
+#include <trigo.h>
+#include <pcb_painter.h>
+#include <worksheet_viewitem.h>
+#include <ratsnest_data.h>
+#include <ratsnest_viewitem.h>
+
+#include <tool/tool_manager.h>
+#include <tool/tool_dispatcher.h>
+
+const wxChar PCB_BASE_FRAME::CANVAS_TYPE_KEY[] = wxT( "canvas_type" );
+
+// Configuration entry names.
+static const wxChar UserGridSizeXEntry[] = wxT( "PcbUserGrid_X" );
+static const wxChar UserGridSizeYEntry[] = wxT( "PcbUserGrid_Y" );
+static const wxChar UserGridUnitsEntry[] = wxT( "PcbUserGrid_Unit" );
+static const wxChar DisplayPadFillEntry[] = wxT( "DiPadFi" );
+static const wxChar DisplayViaFillEntry[] = wxT( "DiViaFi" );
+static const wxChar DisplayPadNumberEntry[] = wxT( "DiPadNu" );
+static const wxChar DisplayModuleEdgeEntry[] = wxT( "DiModEd" );
+static const wxChar DisplayModuleTextEntry[] = wxT( "DiModTx" );
+static const wxChar FastGrid1Entry[] = wxT( "FastGrid1" );
+static const wxChar FastGrid2Entry[] = wxT( "FastGrid2" );
+
+
+BEGIN_EVENT_TABLE( PCB_BASE_FRAME, EDA_DRAW_FRAME )
+ EVT_MENU_RANGE( ID_POPUP_PCB_ITEM_SELECTION_START, ID_POPUP_PCB_ITEM_SELECTION_END,
+ PCB_BASE_FRAME::ProcessItemSelection )
+
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_POLAR_COORD, PCB_BASE_FRAME::OnTogglePolarCoords )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_PADS_SKETCH, PCB_BASE_FRAME::OnTogglePadDrawMode )
+
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_POLAR_COORD, PCB_BASE_FRAME::OnUpdateCoordType )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_PADS_SKETCH, PCB_BASE_FRAME::OnUpdatePadDrawMode )
+ EVT_UPDATE_UI( ID_ON_GRID_SELECT, PCB_BASE_FRAME::OnUpdateSelectGrid )
+ EVT_UPDATE_UI( ID_ON_ZOOM_SELECT, PCB_BASE_FRAME::OnUpdateSelectZoom )
+
+ EVT_UPDATE_UI_RANGE( ID_ZOOM_IN, ID_ZOOM_PAGE, PCB_BASE_FRAME::OnUpdateSelectZoom )
+END_EVENT_TABLE()
+
+
+PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
+ const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
+ long aStyle, const wxString & aFrameName ) :
+ EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName )
+{
+ m_Pcb = NULL;
+ m_Draw3DFrame = NULL; // Display Window in 3D mode (OpenGL)
+
+ m_UserGridSize = wxRealPoint( 100.0, 100.0 );
+ m_UserGridUnit = INCHES;
+ m_Collector = new GENERAL_COLLECTOR();
+
+ m_FastGrid1 = 0;
+ m_FastGrid2 = 0;
+
+ m_auxiliaryToolBar = NULL;
+
+ m_zoomLevelCoeff = 110.0 * IU_PER_DECIMILS; // Adjusted to roughly displays zoom level = 1
+ // when the screen shows a 1:1 image
+ // obviously depends on the monitor,
+ // but this is an acceptable value
+}
+
+
+PCB_BASE_FRAME::~PCB_BASE_FRAME()
+{
+ delete m_Collector;
+ delete m_Pcb;
+}
+
+
+FP_LIB_TABLE* PROJECT::PcbFootprintLibs()
+{
+ // This is a lazy loading function, it loads the project specific table when
+ // that table is asked for, not before.
+
+ FP_LIB_TABLE* tbl = (FP_LIB_TABLE*) GetElem( ELEM_FPTBL );
+
+ // its gotta be NULL or a FP_LIB_TABLE, or a bug.
+ wxASSERT( !tbl || dynamic_cast<FP_LIB_TABLE*>( tbl ) );
+
+ if( !tbl )
+ {
+ // Stack the project specific FP_LIB_TABLE overlay on top of the global table.
+ // ~FP_LIB_TABLE() will not touch the fallback table, so multiple projects may
+ // stack this way, all using the same global fallback table.
+ tbl = new FP_LIB_TABLE( &GFootprintTable );
+
+ SetElem( ELEM_FPTBL, tbl );
+
+ wxString projectFpLibTableFileName = FootprintLibTblName();
+
+ try
+ {
+ tbl->Load( projectFpLibTableFileName );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( NULL, ioe.errorText );
+ }
+ }
+
+ return tbl;
+}
+
+
+void PCB_BASE_FRAME::SetBoard( BOARD* aBoard )
+{
+ if( m_Pcb != aBoard )
+ {
+ delete m_Pcb;
+ m_Pcb = aBoard;
+ }
+}
+
+
+void PCB_BASE_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
+{
+ wxASSERT( m_Pcb );
+ m_Pcb->SetPageSettings( aPageSettings );
+
+ if( GetScreen() )
+ GetScreen()->InitDataPoints( aPageSettings.GetSizeIU() );
+}
+
+
+const PAGE_INFO& PCB_BASE_FRAME::GetPageSettings() const
+{
+ wxASSERT( m_Pcb );
+ return m_Pcb->GetPageSettings();
+}
+
+
+const wxSize PCB_BASE_FRAME::GetPageSizeIU() const
+{
+ wxASSERT( m_Pcb );
+
+ // this function is only needed because EDA_DRAW_FRAME is not compiled
+ // with either -DPCBNEW or -DEESCHEMA, so the virtual is used to route
+ // into an application specific source file.
+ return m_Pcb->GetPageSettings().GetSizeIU();
+}
+
+
+const wxPoint& PCB_BASE_FRAME::GetAuxOrigin() const
+{
+ wxASSERT( m_Pcb );
+ return m_Pcb->GetAuxOrigin();
+}
+
+
+void PCB_BASE_FRAME::SetAuxOrigin( const wxPoint& aPoint )
+{
+ wxASSERT( m_Pcb );
+ m_Pcb->SetAuxOrigin( aPoint );
+}
+
+
+const wxPoint& PCB_BASE_FRAME::GetGridOrigin() const
+{
+ wxASSERT( m_Pcb );
+ return m_Pcb->GetGridOrigin();
+}
+
+
+void PCB_BASE_FRAME::SetGridOrigin( const wxPoint& aPoint )
+{
+ wxASSERT( m_Pcb );
+ m_Pcb->SetGridOrigin( aPoint );
+}
+
+
+const TITLE_BLOCK& PCB_BASE_FRAME::GetTitleBlock() const
+{
+ wxASSERT( m_Pcb );
+ return m_Pcb->GetTitleBlock();
+}
+
+
+void PCB_BASE_FRAME::SetTitleBlock( const TITLE_BLOCK& aTitleBlock )
+{
+ wxASSERT( m_Pcb );
+ m_Pcb->SetTitleBlock( aTitleBlock );
+}
+
+
+BOARD_DESIGN_SETTINGS& PCB_BASE_FRAME::GetDesignSettings() const
+{
+ wxASSERT( m_Pcb );
+ return m_Pcb->GetDesignSettings();
+}
+
+
+void PCB_BASE_FRAME::SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings )
+{
+ wxASSERT( m_Pcb );
+ m_Pcb->SetDesignSettings( aSettings );
+}
+
+
+const ZONE_SETTINGS& PCB_BASE_FRAME::GetZoneSettings() const
+{
+ wxASSERT( m_Pcb );
+ return m_Pcb->GetZoneSettings();
+}
+
+
+void PCB_BASE_FRAME::SetZoneSettings( const ZONE_SETTINGS& aSettings )
+{
+ wxASSERT( m_Pcb );
+ m_Pcb->SetZoneSettings( aSettings );
+}
+
+
+const PCB_PLOT_PARAMS& PCB_BASE_FRAME::GetPlotSettings() const
+{
+ wxASSERT( m_Pcb );
+ return m_Pcb->GetPlotOptions();
+}
+
+
+void PCB_BASE_FRAME::SetPlotSettings( const PCB_PLOT_PARAMS& aSettings )
+{
+ wxASSERT( m_Pcb );
+ m_Pcb->SetPlotOptions( aSettings );
+}
+
+
+EDA_RECT PCB_BASE_FRAME::GetBoardBoundingBox( bool aBoardEdgesOnly ) const
+{
+ wxASSERT( m_Pcb );
+
+ EDA_RECT area = m_Pcb->ComputeBoundingBox( aBoardEdgesOnly );
+
+ if( area.GetWidth() == 0 && area.GetHeight() == 0 )
+ {
+ wxSize pageSize = GetPageSizeIU();
+
+ if( m_showBorderAndTitleBlock )
+ {
+ area.SetOrigin( 0, 0 );
+ area.SetEnd( pageSize.x, pageSize.y );
+ }
+ else
+ {
+ area.SetOrigin( -pageSize.x / 2, -pageSize.y / 2 );
+ area.SetEnd( pageSize.x / 2, pageSize.y / 2 );
+ }
+ }
+
+ return area;
+}
+
+
+double PCB_BASE_FRAME::BestZoom()
+{
+ if( m_Pcb == NULL )
+ return 1.0;
+
+ EDA_RECT ibbbox = GetBoardBoundingBox();
+ DSIZE clientz = m_canvas->GetClientSize();
+ DSIZE boardz( ibbbox.GetWidth(), ibbbox.GetHeight() );
+
+ double iu_per_du_X = clientz.x ? boardz.x / clientz.x : 1.0;
+ double iu_per_du_Y = clientz.y ? boardz.y / clientz.y : 1.0;
+
+ double bestzoom = std::max( iu_per_du_X, iu_per_du_Y );
+
+ SetScrollCenterPosition( ibbbox.Centre() );
+
+ return bestzoom;
+}
+
+
+void PCB_BASE_FRAME::CursorGoto( const wxPoint& aPos, bool aWarp )
+{
+ // factored out of pcbnew/find.cpp
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ // There may be need to reframe the drawing.
+ if( !m_canvas->IsPointOnDisplay( aPos ) )
+ {
+ SetCrossHairPosition( aPos );
+ RedrawScreen( aPos, aWarp );
+ }
+ else
+ {
+ // Put cursor on item position
+ m_canvas->CrossHairOff( &dc );
+ SetCrossHairPosition( aPos );
+
+ if( aWarp )
+ m_canvas->MoveCursorToCrossHair();
+ }
+ m_canvas->CrossHairOn( &dc );
+ m_canvas->CrossHairOn( &dc );
+}
+
+
+// Virtual function
+void PCB_BASE_FRAME::ReCreateMenuBar( void )
+{
+}
+
+
+// Virtual functions: Do nothing for PCB_BASE_FRAME window
+void PCB_BASE_FRAME::Show3D_Frame( wxCommandEvent& event )
+{
+}
+
+
+// Note: virtual, overridden in PCB_EDIT_FRAME;
+void PCB_BASE_FRAME::SwitchLayer( wxDC* DC, LAYER_ID layer )
+{
+ LAYER_ID preslayer = GetActiveLayer();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ // Check if the specified layer matches the present layer
+ if( layer == preslayer )
+ return;
+
+ // Copper layers cannot be selected unconditionally; how many
+ // of those layers are currently enabled needs to be checked.
+ if( IsCopperLayer( layer ) )
+ {
+ // If only one copper layer is enabled, the only such layer
+ // that can be selected to is the "Copper" layer (so the
+ // selection of any other copper layer is disregarded).
+ if( m_Pcb->GetCopperLayerCount() < 2 )
+ {
+ if( layer != B_Cu )
+ {
+ return;
+ }
+ }
+
+ // If more than one copper layer is enabled, the "Copper"
+ // and "Component" layers can be selected, but the total
+ // number of copper layers determines which internal
+ // layers are also capable of being selected.
+ else
+ {
+ if( ( layer != B_Cu ) && ( layer != F_Cu )
+ && ( layer >= m_Pcb->GetCopperLayerCount() - 1 ) )
+ {
+ return;
+ }
+ }
+ }
+
+ // Is yet more checking required? E.g. when the layer to be selected
+ // is a non-copper layer, or when switching between a copper layer
+ // and a non-copper layer, or vice-versa?
+ // ...
+
+ GetScreen()->m_Active_Layer = layer;
+
+ if( displ_opts->m_ContrastModeDisplay )
+ m_canvas->Refresh();
+}
+
+
+void PCB_BASE_FRAME::OnTogglePolarCoords( wxCommandEvent& aEvent )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+ SetStatusText( wxEmptyString );
+
+ displ_opts->m_DisplayPolarCood = !displ_opts->m_DisplayPolarCood;
+
+ UpdateStatusBar();
+}
+
+
+void PCB_BASE_FRAME::OnTogglePadDrawMode( wxCommandEvent& aEvent )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ displ_opts->m_DisplayPadFill = !displ_opts->m_DisplayPadFill;
+ EDA_DRAW_PANEL_GAL* gal = GetGalCanvas();
+
+ if( gal )
+ {
+ // Apply new display options to the GAL canvas
+ KIGFX::PCB_PAINTER* painter =
+ static_cast<KIGFX::PCB_PAINTER*> ( gal->GetView()->GetPainter() );
+ KIGFX::PCB_RENDER_SETTINGS* settings =
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*> ( painter->GetSettings() );
+ settings->LoadDisplayOptions( displ_opts );
+
+ // Update pads
+ BOARD* board = GetBoard();
+ for( MODULE* module = board->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ pad->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ m_canvas->Refresh();
+}
+
+
+void PCB_BASE_FRAME::OnUpdateCoordType( wxUpdateUIEvent& aEvent )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ aEvent.Check( displ_opts->m_DisplayPolarCood );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_SHOW_POLAR_COORD,
+ displ_opts->m_DisplayPolarCood ?
+ _( "Display rectangular coordinates" ) :
+ _( "Display polar coordinates" ) );
+}
+
+
+void PCB_BASE_FRAME::OnUpdatePadDrawMode( wxUpdateUIEvent& aEvent )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+ aEvent.Check( !displ_opts->m_DisplayPadFill );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_SHOW_PADS_SKETCH,
+ displ_opts->m_DisplayPadFill ?
+ _( "Show pads in outline mode" ) :
+ _( "Show pads in fill mode" ) );
+}
+
+
+void PCB_BASE_FRAME::OnUpdateSelectGrid( wxUpdateUIEvent& aEvent )
+{
+ // No need to update the grid select box if it doesn't exist or the grid setting change
+ // was made using the select box.
+ if( m_gridSelectBox == NULL || m_auxiliaryToolBar == NULL )
+ return;
+
+ int select = wxNOT_FOUND;
+
+ for( size_t i = 0; i < GetScreen()->GetGridCount(); i++ )
+ {
+ if( GetScreen()->GetGridCmdId() == GetScreen()->GetGrid( i ).m_CmdId )
+ {
+ select = (int) i;
+ break;
+ }
+ }
+
+ if( select != m_gridSelectBox->GetSelection() )
+ m_gridSelectBox->SetSelection( select );
+}
+
+
+void PCB_BASE_FRAME::OnUpdateSelectZoom( wxUpdateUIEvent& aEvent )
+{
+ if( m_zoomSelectBox == NULL || m_auxiliaryToolBar == NULL )
+ return;
+
+ int current = 0;
+ double zoom = IsGalCanvasActive() ? GetGalCanvas()->GetLegacyZoom() : GetScreen()->GetZoom();
+
+ for( unsigned i = 0; i < GetScreen()->m_ZoomList.size(); i++ )
+ {
+ if( std::fabs( zoom - GetScreen()->m_ZoomList[i] ) < 1e-6 )
+ {
+ current = i + 1;
+ break;
+ }
+ }
+
+ if( current != m_zoomSelectBox->GetSelection() )
+ m_zoomSelectBox->SetSelection( current );
+}
+
+
+void PCB_BASE_FRAME::ProcessItemSelection( wxCommandEvent& aEvent )
+{
+ int id = aEvent.GetId();
+
+ // index into the collector list:
+ int itemNdx = id - ID_POPUP_PCB_ITEM_SELECTION_START;
+
+ if( id >= ID_POPUP_PCB_ITEM_SELECTION_START && id <= ID_POPUP_PCB_ITEM_SELECTION_END )
+ {
+ BOARD_ITEM* item = (*m_Collector)[itemNdx];
+ m_canvas->SetAbortRequest( false );
+
+#if 0 && defined (DEBUG)
+ item->Show( 0, std::cout );
+#endif
+
+ SetCurItem( item );
+ }
+}
+
+
+void PCB_BASE_FRAME::SetCurItem( BOARD_ITEM* aItem, bool aDisplayInfo )
+{
+ GetScreen()->SetCurItem( aItem );
+
+ if( aDisplayInfo )
+ UpdateMsgPanel();
+}
+
+
+void PCB_BASE_FRAME::UpdateMsgPanel()
+{
+ BOARD_ITEM* item = GetScreen()->GetCurItem();
+ MSG_PANEL_ITEMS items;
+
+ if( item )
+ {
+ item->GetMsgPanelInfo( items );
+ }
+ else // show general information about the board
+ {
+ if( IsGalCanvasActive() )
+ GetGalCanvas()->GetMsgPanelInfo( items );
+ else
+ m_Pcb->GetMsgPanelInfo( items );
+ }
+
+ SetMsgPanel( items );
+}
+
+
+BOARD_ITEM* PCB_BASE_FRAME::GetCurItem()
+{
+ return GetScreen()->GetCurItem();
+}
+
+
+GENERAL_COLLECTORS_GUIDE PCB_BASE_FRAME::GetCollectorsGuide()
+{
+ GENERAL_COLLECTORS_GUIDE guide( m_Pcb->GetVisibleLayers(),
+ GetActiveLayer() );
+
+ // account for the globals
+ guide.SetIgnoreMTextsMarkedNoShow( ! m_Pcb->IsElementVisible( MOD_TEXT_INVISIBLE ));
+ guide.SetIgnoreMTextsOnBack( ! m_Pcb->IsElementVisible( MOD_TEXT_BK_VISIBLE ));
+ guide.SetIgnoreMTextsOnFront( ! m_Pcb->IsElementVisible( MOD_TEXT_FR_VISIBLE ));
+ guide.SetIgnoreModulesOnBack( ! m_Pcb->IsElementVisible( MOD_BK_VISIBLE ) );
+ guide.SetIgnoreModulesOnFront( ! m_Pcb->IsElementVisible( MOD_FR_VISIBLE ) );
+ guide.SetIgnorePadsOnBack( ! m_Pcb->IsElementVisible( PAD_BK_VISIBLE ) );
+ guide.SetIgnorePadsOnFront( ! m_Pcb->IsElementVisible( PAD_FR_VISIBLE ) );
+ guide.SetIgnoreModulesVals( ! m_Pcb->IsElementVisible( MOD_VALUES_VISIBLE ) );
+ guide.SetIgnoreModulesRefs( ! m_Pcb->IsElementVisible( MOD_REFERENCES_VISIBLE ) );
+
+ return guide;
+}
+
+void PCB_BASE_FRAME::SetToolID( int aId, int aCursor, const wxString& aToolMsg )
+{
+ bool redraw = false;
+
+ EDA_DRAW_FRAME::SetToolID( aId, aCursor, aToolMsg );
+
+ if( aId < 0 )
+ return;
+
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ // handle color changes for transitions in and out of ID_TRACK_BUTT
+ if( ( GetToolId() == ID_TRACK_BUTT && aId != ID_TRACK_BUTT )
+ || ( GetToolId() != ID_TRACK_BUTT && aId == ID_TRACK_BUTT ) )
+ {
+ if( displ_opts->m_ContrastModeDisplay )
+ redraw = true;
+ }
+
+ // must do this after the tool has been set, otherwise pad::Draw() does
+ // not show proper color when GetDisplayOptions().ContrastModeDisplay is true.
+ if( redraw && m_canvas )
+ m_canvas->Refresh();
+}
+
+
+/*
+ * Update the status bar information.
+ */
+void PCB_BASE_FRAME::UpdateStatusBar()
+{
+ PCB_SCREEN* screen = GetScreen();
+
+ if( !screen )
+ return;
+
+ int dx;
+ int dy;
+ double dXpos;
+ double dYpos;
+ wxString line;
+ wxString locformatter;
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ EDA_DRAW_FRAME::UpdateStatusBar();
+
+ if( displ_opts->m_DisplayPolarCood ) // display polar coordinates
+ {
+ double theta, ro;
+
+ dx = GetCrossHairPosition().x - screen->m_O_Curseur.x;
+ dy = GetCrossHairPosition().y - screen->m_O_Curseur.y;
+
+ theta = ArcTangente( -dy, dx ) / 10;
+
+ ro = hypot( dx, dy );
+ wxString formatter;
+ switch( g_UserUnit )
+ {
+ case INCHES:
+ formatter = wxT( "Ro %.6f Th %.1f" );
+ break;
+
+ case MILLIMETRES:
+ formatter = wxT( "Ro %.6f Th %.1f" );
+ break;
+
+ case UNSCALED_UNITS:
+ formatter = wxT( "Ro %f Th %f" );
+ break;
+
+ case DEGREES:
+ wxASSERT( false );
+ break;
+ }
+
+ line.Printf( formatter, To_User_Unit( g_UserUnit, ro ), theta );
+
+ SetStatusText( line, 3 );
+ }
+
+ // Display absolute coordinates:
+ dXpos = To_User_Unit( g_UserUnit, GetCrossHairPosition().x );
+ dYpos = To_User_Unit( g_UserUnit, GetCrossHairPosition().y );
+
+ // The following sadly is an if Eeschema/if Pcbnew
+ wxString absformatter;
+
+ switch( g_UserUnit )
+ {
+ case INCHES:
+ absformatter = wxT( "X %.6f Y %.6f" );
+ locformatter = wxT( "dx %.6f dy %.6f dist %.4f" );
+ break;
+
+ case MILLIMETRES:
+ absformatter = wxT( "X %.6f Y %.6f" );
+ locformatter = wxT( "dx %.6f dy %.6f dist %.3f" );
+ break;
+
+ case UNSCALED_UNITS:
+ absformatter = wxT( "X %f Y %f" );
+ locformatter = wxT( "dx %f dy %f dist %f" );
+ break;
+
+ case DEGREES:
+ wxASSERT( false );
+ break;
+ }
+
+ line.Printf( absformatter, dXpos, dYpos );
+ SetStatusText( line, 2 );
+
+ if( !displ_opts->m_DisplayPolarCood ) // display relative cartesian coordinates
+ {
+ // Display relative coordinates:
+ dx = GetCrossHairPosition().x - screen->m_O_Curseur.x;
+ dy = GetCrossHairPosition().y - screen->m_O_Curseur.y;
+ dXpos = To_User_Unit( g_UserUnit, dx );
+ dYpos = To_User_Unit( g_UserUnit, dy );
+
+ // We already decided the formatter above
+ line.Printf( locformatter, dXpos, dYpos, hypot( dXpos, dYpos ) );
+ SetStatusText( line, 3 );
+ }
+}
+
+
+void PCB_BASE_FRAME::unitsChangeRefresh()
+{
+ EDA_DRAW_FRAME::unitsChangeRefresh(); // Update the status bar.
+
+ updateGridSelectBox();
+}
+
+
+void PCB_BASE_FRAME::LoadSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::LoadSettings( aCfg );
+
+ // Ensure grid id is an existent grid id:
+ if( (m_LastGridSizeId <= 0) ||
+ (m_LastGridSizeId > (ID_POPUP_GRID_USER - ID_POPUP_GRID_LEVEL_1000)) )
+ m_LastGridSizeId = ID_POPUP_GRID_LEVEL_500 - ID_POPUP_GRID_LEVEL_1000;
+
+ wxString baseCfgName = GetName();
+
+ aCfg->Read( baseCfgName + UserGridSizeXEntry, &m_UserGridSize.x, 0.01 );
+ aCfg->Read( baseCfgName + UserGridSizeYEntry, &m_UserGridSize.y, 0.01 );
+
+ long itmp;
+ aCfg->Read( baseCfgName + UserGridUnitsEntry, &itmp, ( long )INCHES );
+ m_UserGridUnit = (EDA_UNITS_T) itmp;
+ aCfg->Read( baseCfgName + DisplayPadFillEntry, &m_DisplayOptions.m_DisplayPadFill, true );
+ aCfg->Read( baseCfgName + DisplayViaFillEntry, &m_DisplayOptions.m_DisplayViaFill, true );
+ aCfg->Read( baseCfgName + DisplayPadNumberEntry, &m_DisplayOptions.m_DisplayPadNum, true );
+ aCfg->Read( baseCfgName + DisplayModuleEdgeEntry, &m_DisplayOptions.m_DisplayModEdgeFill, true );
+
+ aCfg->Read( baseCfgName + FastGrid1Entry, &itmp, ( long )0);
+ m_FastGrid1 = itmp;
+ aCfg->Read( baseCfgName + FastGrid2Entry, &itmp, ( long )0);
+ m_FastGrid2 = itmp;
+
+ aCfg->Read( baseCfgName + DisplayModuleTextEntry, &m_DisplayOptions.m_DisplayModTextFill, true );
+}
+
+
+void PCB_BASE_FRAME::SaveSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::SaveSettings( aCfg );
+
+ wxString baseCfgName = GetName();
+
+ aCfg->Write( baseCfgName + UserGridSizeXEntry, m_UserGridSize.x );
+ aCfg->Write( baseCfgName + UserGridSizeYEntry, m_UserGridSize.y );
+ aCfg->Write( baseCfgName + UserGridUnitsEntry, ( long )m_UserGridUnit );
+ aCfg->Write( baseCfgName + DisplayPadFillEntry, m_DisplayOptions.m_DisplayPadFill );
+ aCfg->Write( baseCfgName + DisplayViaFillEntry, m_DisplayOptions.m_DisplayViaFill );
+ aCfg->Write( baseCfgName + DisplayPadNumberEntry, m_DisplayOptions.m_DisplayPadNum );
+ aCfg->Write( baseCfgName + DisplayModuleEdgeEntry, m_DisplayOptions.m_DisplayModEdgeFill );
+ aCfg->Write( baseCfgName + DisplayModuleTextEntry, m_DisplayOptions.m_DisplayModTextFill );
+ aCfg->Write( baseCfgName + FastGrid1Entry, ( long )m_FastGrid1 );
+ aCfg->Write( baseCfgName + FastGrid2Entry, ( long )m_FastGrid2 );
+}
+
+
+void PCB_BASE_FRAME::OnModify()
+{
+ GetScreen()->SetModify();
+ GetScreen()->SetSave();
+
+ if( IsGalCanvasActive() )
+ {
+ UpdateStatusBar();
+ UpdateMsgPanel();
+ }
+}
+
+
+const wxString PCB_BASE_FRAME::GetZoomLevelIndicator() const
+{
+ return EDA_DRAW_FRAME::GetZoomLevelIndicator();
+}
+
+
+void PCB_BASE_FRAME::updateGridSelectBox()
+{
+ UpdateStatusBar();
+ DisplayUnitsMsg();
+
+ if( m_gridSelectBox == NULL )
+ return;
+
+ // Update grid values with the current units setting.
+ m_gridSelectBox->Clear();
+ wxArrayString gridsList;
+ int icurr = GetScreen()->BuildGridsChoiceList( gridsList, g_UserUnit != INCHES );
+
+ for( size_t i = 0; i < GetScreen()->GetGridCount(); i++ )
+ {
+ GRID_TYPE& grid = GetScreen()->GetGrid( i );
+ m_gridSelectBox->Append( gridsList[i], (void*) &grid.m_CmdId );
+ }
+
+ m_gridSelectBox->SetSelection( icurr );
+}
+
+void PCB_BASE_FRAME::updateZoomSelectBox()
+{
+ if( m_zoomSelectBox == NULL )
+ return;
+
+ wxString msg;
+
+ m_zoomSelectBox->Clear();
+ m_zoomSelectBox->Append( _( "Zoom Auto" ) );
+ m_zoomSelectBox->SetSelection( 0 );
+
+ for( unsigned i = 0; i < GetScreen()->m_ZoomList.size(); ++i )
+ {
+ msg = _( "Zoom " );
+
+ double level = m_zoomLevelCoeff / (double)GetScreen()->m_ZoomList[i];
+ wxString value = wxString::Format( wxT( "%.2f" ), level );
+ msg += value;
+
+ m_zoomSelectBox->Append( msg );
+
+ if( GetScreen()->GetZoom() == GetScreen()->m_ZoomList[i] )
+ m_zoomSelectBox->SetSelection( i + 1 );
+ }
+}
+
+
+void PCB_BASE_FRAME::SetFastGrid1()
+{
+ if( m_FastGrid1 >= (int)GetScreen()->GetGridCount() )
+ return;
+
+ int cmdId = GetScreen()->GetGrids()[m_FastGrid1].m_CmdId;
+ SetPresetGrid( cmdId - ID_POPUP_GRID_LEVEL_1000 );
+
+ if( m_gridSelectBox )
+ {
+ wxCommandEvent cmd( wxEVT_CHOICE );
+ cmd.SetEventObject( this );
+ OnSelectGrid( cmd );
+ }
+ else
+ GetCanvas()->Refresh();
+}
+
+
+void PCB_BASE_FRAME::SetFastGrid2()
+{
+ if( m_FastGrid2 >= (int)GetScreen()->GetGridCount() )
+ return;
+
+ int cmdId = GetScreen()->GetGrids()[m_FastGrid2].m_CmdId;
+ SetPresetGrid( cmdId - ID_POPUP_GRID_LEVEL_1000 );
+
+ if( m_gridSelectBox )
+ {
+ wxCommandEvent cmd( wxEVT_CHOICE );
+ cmd.SetEventObject( this );
+ OnSelectGrid( cmd );
+ }
+ else
+ GetCanvas()->Refresh();
+}
+
+void PCB_BASE_FRAME::SetNextGrid()
+{
+ EDA_DRAW_FRAME::SetNextGrid();
+
+ if( m_gridSelectBox )
+ {
+ wxCommandEvent cmd( wxEVT_CHOICE );
+ cmd.SetEventObject( this );
+ OnSelectGrid( cmd );
+ }
+ else
+ GetCanvas()->Refresh();
+}
+
+
+void PCB_BASE_FRAME::SetPrevGrid()
+{
+ EDA_DRAW_FRAME::SetPrevGrid();
+
+ if( m_gridSelectBox )
+ {
+ wxCommandEvent cmd( wxEVT_CHOICE );
+ cmd.SetEventObject( this );
+ OnSelectGrid( cmd );
+ }
+ else
+ GetCanvas()->Refresh();
+}
+
+
+void PCB_BASE_FRAME::SwitchCanvas( wxCommandEvent& aEvent )
+{
+ bool use_gal = false;
+ EDA_DRAW_PANEL_GAL::GAL_TYPE canvasType = EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE;
+
+ switch( aEvent.GetId() )
+ {
+ case ID_MENU_CANVAS_DEFAULT:
+ break;
+
+ case ID_MENU_CANVAS_CAIRO:
+ use_gal = GetGalCanvas()->SwitchBackend( EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO );
+
+ if( use_gal )
+ canvasType = EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO;
+ break;
+
+ case ID_MENU_CANVAS_OPENGL:
+ use_gal = GetGalCanvas()->SwitchBackend( EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL );
+
+ if( use_gal )
+ canvasType = EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL;
+ break;
+ }
+
+ SaveCanvasTypeSetting( canvasType );
+ UseGalCanvas( use_gal );
+}
+
+
+void PCB_BASE_FRAME::UseGalCanvas( bool aEnable )
+{
+ EDA_DRAW_FRAME::UseGalCanvas( aEnable );
+
+ EDA_DRAW_PANEL_GAL* galCanvas = GetGalCanvas();
+
+ if( m_toolManager )
+ m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(),
+ GetGalCanvas()->GetViewControls(), this );
+
+ if( aEnable )
+ {
+ SetBoard( m_Pcb );
+
+ if( m_toolManager )
+ m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH );
+
+ galCanvas->GetView()->RecacheAllItems( true );
+ galCanvas->SetEventDispatcher( m_toolDispatcher );
+ galCanvas->StartDrawing();
+ }
+ else
+ {
+ if( m_toolManager )
+ m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH );
+
+ // Redirect all events to the legacy canvas
+ galCanvas->SetEventDispatcher( NULL );
+ }
+}
+
+
+EDA_DRAW_PANEL_GAL::GAL_TYPE PCB_BASE_FRAME::LoadCanvasTypeSetting() const
+{
+ EDA_DRAW_PANEL_GAL::GAL_TYPE canvasType = EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE;
+ wxConfigBase* cfg = Kiface().KifaceSettings();
+
+ if( cfg )
+ canvasType = (EDA_DRAW_PANEL_GAL::GAL_TYPE) cfg->ReadLong( CANVAS_TYPE_KEY,
+ EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE );
+
+ if( canvasType < EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE
+ || canvasType >= EDA_DRAW_PANEL_GAL::GAL_TYPE_LAST )
+ {
+ assert( false );
+ canvasType = EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE;
+ }
+
+ return canvasType;
+}
+
+
+bool PCB_BASE_FRAME::SaveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType )
+{
+ if( aCanvasType < EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE
+ || aCanvasType >= EDA_DRAW_PANEL_GAL::GAL_TYPE_LAST )
+ {
+ assert( false );
+ return false;
+ }
+
+ wxConfigBase* cfg = Kiface().KifaceSettings();
+
+ if( cfg )
+ return cfg->Write( CANVAS_TYPE_KEY, (long) aCanvasType );
+
+ return false;
+}
diff --git a/pcbnew/block.cpp b/pcbnew/block.cpp
new file mode 100644
index 0000000..ae09495
--- /dev/null
+++ b/pcbnew/block.cpp
@@ -0,0 +1,890 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/block.cpp
+ */
+
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <block_commande.h>
+#include <wxPcbStruct.h>
+#include <trigo.h>
+
+#include <class_board.h>
+#include <class_track.h>
+#include <class_drawsegment.h>
+#include <class_pcb_text.h>
+#include <class_mire.h>
+#include <class_module.h>
+#include <class_dimension.h>
+#include <class_zone.h>
+
+#include <dialog_block_options_base.h>
+
+#include <pcbnew.h>
+#include <protos.h>
+
+#define BLOCK_OUTLINE_COLOR YELLOW
+
+/**
+ * Function drawPickedItems
+ * draws items currently selected in a block
+ * @param aPanel = Current draw panel
+ * @param aDC = Current device context
+ * @param aOffset = Drawing offset
+ **/
+static void drawPickedItems( EDA_DRAW_PANEL* aPanel, wxDC* aDC, wxPoint aOffset );
+
+/**
+ * Function drawMovingBlock
+ * handles drawing of a moving block
+ * @param aPanel = Current draw panel
+ * @param aDC = Current device context
+ * @param aPosition The cursor position in logical (drawing) units.
+ * @param aErase = Erase block at current position
+ **/
+static void drawMovingBlock( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase );
+
+
+static bool blockIncludeModules = true;
+static bool blockIncludeLockedModules = true;
+static bool blockIncludeTracks = true;
+static bool blockIncludeZones = true;
+static bool blockIncludeItemsOnTechLayers = true;
+static bool blockIncludeBoardOutlineLayer = true;
+static bool blockIncludePcbTexts = true;
+static bool blockDrawItems = true;
+static bool blockIncludeItemsOnInvisibleLayers = false;
+
+
+/************************************/
+/* class DIALOG_BLOCK_OPTIONS */
+/************************************/
+
+class DIALOG_BLOCK_OPTIONS : public DIALOG_BLOCK_OPTIONS_BASE
+{
+private:
+ PCB_BASE_FRAME* m_Parent;
+
+public:
+
+ DIALOG_BLOCK_OPTIONS( PCB_BASE_FRAME* parent, const wxString& title );
+ ~DIALOG_BLOCK_OPTIONS()
+ {
+ }
+
+
+private:
+ void ExecuteCommand( wxCommandEvent& event );
+ void OnCancel( wxCommandEvent& event )
+ {
+ EndModal( wxID_CANCEL );
+ }
+ void checkBoxClicked( wxCommandEvent& aEvent )
+ {
+ if( m_Include_Modules->GetValue() )
+ m_IncludeLockedModules->Enable();
+ else
+ m_IncludeLockedModules->Disable();
+ }
+};
+
+
+static bool InstallBlockCmdFrame( PCB_BASE_FRAME* parent, const wxString& title )
+{
+ wxPoint oldpos = parent->GetCrossHairPosition();
+
+ parent->GetCanvas()->SetIgnoreMouseEvents( true );
+ DIALOG_BLOCK_OPTIONS * dlg = new DIALOG_BLOCK_OPTIONS( parent, title );
+
+ int cmd = dlg->ShowModal();
+ dlg->Destroy();
+
+ parent->SetCrossHairPosition( oldpos );
+ parent->GetCanvas()->MoveCursorToCrossHair();
+ parent->GetCanvas()->SetIgnoreMouseEvents( false );
+
+ return cmd == wxID_OK;
+}
+
+
+DIALOG_BLOCK_OPTIONS::DIALOG_BLOCK_OPTIONS( PCB_BASE_FRAME* aParent, const wxString& aTitle ) :
+ DIALOG_BLOCK_OPTIONS_BASE( aParent, -1, aTitle )
+{
+ m_Parent = aParent;
+
+ m_Include_Modules->SetValue( blockIncludeModules );
+ m_IncludeLockedModules->SetValue( blockIncludeLockedModules );
+
+ if( m_Include_Modules->GetValue() )
+ m_IncludeLockedModules->Enable();
+ else
+ m_IncludeLockedModules->Disable();
+
+ m_Include_Tracks->SetValue( blockIncludeTracks );
+ m_Include_Zones->SetValue( blockIncludeZones );
+ m_Include_Draw_Items->SetValue( blockIncludeItemsOnTechLayers );
+ m_Include_Edges_Items->SetValue( blockIncludeBoardOutlineLayer );
+ m_Include_PcbTextes->SetValue( blockIncludePcbTexts );
+ m_DrawBlockItems->SetValue( blockDrawItems );
+ m_checkBoxIncludeInvisible->SetValue( blockIncludeItemsOnInvisibleLayers );
+ m_sdbSizer1OK->SetDefault();
+ SetFocus();
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+
+void DIALOG_BLOCK_OPTIONS::ExecuteCommand( wxCommandEvent& event )
+{
+ blockIncludeModules = m_Include_Modules->GetValue();
+ blockIncludeLockedModules = m_IncludeLockedModules->GetValue();
+ blockIncludeTracks = m_Include_Tracks->GetValue();
+ blockIncludeZones = m_Include_Zones->GetValue();
+ blockIncludeItemsOnTechLayers = m_Include_Draw_Items->GetValue();
+ blockIncludeBoardOutlineLayer = m_Include_Edges_Items->GetValue();
+ blockIncludePcbTexts = m_Include_PcbTextes->GetValue();
+ blockDrawItems = m_DrawBlockItems->GetValue();
+ blockIncludeItemsOnInvisibleLayers = m_checkBoxIncludeInvisible->GetValue();
+
+ EndModal( wxID_OK );
+}
+
+
+int PCB_EDIT_FRAME::BlockCommand( int aKey )
+{
+ int cmd = 0;
+
+ switch( aKey )
+ {
+ default:
+ cmd = aKey & 0xFF;
+ break;
+
+ case 0:
+ cmd = BLOCK_MOVE;
+ break;
+
+ case GR_KB_SHIFT:
+ cmd = BLOCK_COPY;
+ break;
+
+ case GR_KB_CTRL:
+ cmd = BLOCK_ROTATE;
+ break;
+
+ case GR_KB_SHIFTCTRL:
+ cmd = BLOCK_DELETE;
+ break;
+
+ case GR_KB_ALT:
+ cmd = BLOCK_FLIP;
+ break;
+
+ case MOUSE_MIDDLE:
+ cmd = BLOCK_ZOOM;
+ break;
+ }
+
+ return cmd;
+}
+
+
+void PCB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
+{
+ GetBoard()->m_Status_Pcb &= ~DO_NOT_SHOW_GENERAL_RASTNEST;
+
+ if( !m_canvas->IsMouseCaptured() )
+ {
+ DisplayError( this, wxT( "Error in HandleBlockPLace : m_mouseCaptureCallback = NULL" ) );
+ }
+
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP );
+
+ const BLOCK_COMMAND_T command = GetScreen()->m_BlockLocate.GetCommand();
+
+ switch( command )
+ {
+ case BLOCK_IDLE:
+ break;
+
+ case BLOCK_DRAG: // Drag
+ case BLOCK_MOVE: // Move
+ case BLOCK_PRESELECT_MOVE: // Move with preselection list
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ Block_Move();
+ GetScreen()->m_BlockLocate.ClearItemsList();
+ break;
+
+ case BLOCK_COPY: // Copy
+ case BLOCK_COPY_AND_INCREMENT:
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ Block_Duplicate( command == BLOCK_COPY_AND_INCREMENT );
+ GetScreen()->m_BlockLocate.ClearItemsList();
+ break;
+
+ case BLOCK_PASTE:
+ break;
+
+ case BLOCK_ZOOM: // Handled by HandleBlockEnd()
+ default:
+ break;
+ }
+
+ OnModify();
+
+ m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false );
+ GetScreen()->ClearBlockCommand();
+
+ if( GetScreen()->m_BlockLocate.GetCount() )
+ {
+ DisplayError( this, wxT( "Error in HandleBlockPLace some items left in list" ) );
+ GetScreen()->m_BlockLocate.ClearItemsList();
+ }
+}
+
+
+bool PCB_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
+{
+ bool nextcmd = false; // Will be set to true if a block place is needed
+ bool cancelCmd = false;
+ // If coming here after cancel block, clean up and exit
+ if( GetScreen()->m_BlockLocate.GetState() == STATE_NO_BLOCK )
+ {
+ m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString,
+ false );
+ GetScreen()->ClearBlockCommand();
+ return false;
+ }
+
+ // Show dialog if there are no selected items and we're not zooming
+ if( !GetScreen()->m_BlockLocate.GetCount()
+ && GetScreen()->m_BlockLocate.GetCommand() != BLOCK_ZOOM )
+ {
+ if( InstallBlockCmdFrame( this, _( "Block Operation" ) ) == false )
+ {
+ cancelCmd = true;
+
+ // undraw block outline
+ if( DC )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ }
+ else
+ {
+ DrawAndSizingBlockOutlines( m_canvas, DC, wxDefaultPosition, false );
+ Block_SelectItems();
+
+ // Exit if no items found
+ if( !GetScreen()->m_BlockLocate.GetCount() )
+ cancelCmd = true;
+ }
+ }
+
+ if( !cancelCmd && m_canvas->IsMouseCaptured() )
+ {
+ switch( GetScreen()->m_BlockLocate.GetCommand() )
+ {
+ case BLOCK_IDLE:
+ DisplayError( this, wxT( "Error in HandleBlockPLace" ) );
+ break;
+
+ case BLOCK_DRAG: // Drag (not used, for future enhancements)
+ case BLOCK_MOVE: // Move
+ case BLOCK_COPY: // Copy
+ case BLOCK_COPY_AND_INCREMENT: // Copy and increment relevant references
+ case BLOCK_PRESELECT_MOVE: // Move with preselection list
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE );
+ nextcmd = true;
+ m_canvas->SetMouseCaptureCallback( drawMovingBlock );
+ if( DC )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ break;
+
+ case BLOCK_DELETE: // Delete
+ m_canvas->SetMouseCaptureCallback( NULL );
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP );
+ Block_Delete();
+ break;
+
+ case BLOCK_ROTATE: // Rotation
+ m_canvas->SetMouseCaptureCallback( NULL );
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP );
+ Block_Rotate();
+ break;
+
+ case BLOCK_FLIP: // Flip
+ m_canvas->SetMouseCaptureCallback( NULL );
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP );
+ Block_Flip();
+ break;
+
+ case BLOCK_SAVE: // Save (not used, for future enhancements)
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP );
+
+ if( GetScreen()->m_BlockLocate.GetCount() )
+ {
+ // @todo (if useful) Save_Block( );
+ }
+ break;
+
+ case BLOCK_PASTE:
+ break;
+
+ case BLOCK_ZOOM: // Window Zoom
+
+ // Turn off the redraw block routine now so it is not displayed
+ // with one corner at the new center of the screen
+ m_canvas->SetMouseCaptureCallback( NULL );
+ Window_Zoom( GetScreen()->m_BlockLocate );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( ! nextcmd )
+ {
+ GetBoard()->m_Status_Pcb |= DO_NOT_SHOW_GENERAL_RASTNEST;
+ GetScreen()->ClearBlockCommand();
+ m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString,
+ false );
+ }
+
+ return nextcmd;
+}
+
+
+void PCB_EDIT_FRAME::Block_SelectItems()
+{
+ LSET layerMask;
+ bool selectOnlyComplete = GetScreen()->m_BlockLocate.GetWidth() > 0 ;
+
+ GetScreen()->m_BlockLocate.Normalize();
+
+ PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems();
+ ITEM_PICKER picker( NULL, UR_UNSPECIFIED );
+
+ // Add modules
+ if( blockIncludeModules )
+ {
+ for( MODULE* module = m_Pcb->m_Modules; module; module = module->Next() )
+ {
+ LAYER_ID layer = module->GetLayer();
+
+ if( module->HitTest( GetScreen()->m_BlockLocate, selectOnlyComplete )
+ && ( !module->IsLocked() || blockIncludeLockedModules ) )
+ {
+ if( blockIncludeItemsOnInvisibleLayers || m_Pcb->IsModuleLayerVisible( layer ) )
+ {
+ picker.SetItem ( module );
+ itemsList->PushItem( picker );
+ }
+ }
+ }
+ }
+
+ // Add tracks and vias
+ if( blockIncludeTracks )
+ {
+ for( TRACK* track = m_Pcb->m_Track; track != NULL; track = track->Next() )
+ {
+ if( track->HitTest( GetScreen()->m_BlockLocate, selectOnlyComplete ) )
+ {
+ if( blockIncludeItemsOnInvisibleLayers
+ || m_Pcb->IsLayerVisible( track->GetLayer() ) )
+ {
+ picker.SetItem( track );
+ itemsList->PushItem( picker );
+ }
+ }
+ }
+ }
+
+ // Add graphic items
+ layerMask = LSET( Edge_Cuts );
+
+ if( blockIncludeItemsOnTechLayers )
+ layerMask.set();
+
+ if( !blockIncludeBoardOutlineLayer )
+ layerMask.set( Edge_Cuts, false );
+
+ for( BOARD_ITEM* PtStruct = m_Pcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() )
+ {
+ if( !m_Pcb->IsLayerVisible( PtStruct->GetLayer() ) && ! blockIncludeItemsOnInvisibleLayers)
+ continue;
+
+ bool select_me = false;
+
+ switch( PtStruct->Type() )
+ {
+ case PCB_LINE_T:
+ if( !layerMask[PtStruct->GetLayer()] )
+ break;
+
+ if( !PtStruct->HitTest( GetScreen()->m_BlockLocate, selectOnlyComplete ) )
+ break;
+
+ select_me = true; // This item is in bloc: select it
+ break;
+
+ case PCB_TEXT_T:
+ if( !blockIncludePcbTexts )
+ break;
+
+ if( !PtStruct->HitTest( GetScreen()->m_BlockLocate, selectOnlyComplete ) )
+ break;
+
+ select_me = true; // This item is in bloc: select it
+ break;
+
+ case PCB_TARGET_T:
+ if( !layerMask[PtStruct->GetLayer()] )
+ break;
+
+ if( !PtStruct->HitTest( GetScreen()->m_BlockLocate, selectOnlyComplete ) )
+ break;
+
+ select_me = true; // This item is in bloc: select it
+ break;
+
+ case PCB_DIMENSION_T:
+ if( !layerMask[PtStruct->GetLayer()] )
+ break;
+
+ if( !PtStruct->HitTest( GetScreen()->m_BlockLocate, selectOnlyComplete ) )
+ break;
+
+ select_me = true; // This item is in bloc: select it
+ break;
+
+ default:
+ break;
+ }
+
+ if( select_me )
+ {
+ picker.SetItem ( PtStruct );
+ itemsList->PushItem( picker );
+ }
+ }
+
+ // Add zones
+ if( blockIncludeZones )
+ {
+ for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* area = m_Pcb->GetArea( ii );
+
+ if( area->HitTest( GetScreen()->m_BlockLocate, selectOnlyComplete ) )
+ {
+ if( blockIncludeItemsOnInvisibleLayers
+ || m_Pcb->IsLayerVisible( area->GetLayer() ) )
+ {
+ BOARD_ITEM* zone_c = (BOARD_ITEM*) area;
+ picker.SetItem ( zone_c );
+ itemsList->PushItem( picker );
+ }
+ }
+ }
+ }
+}
+
+
+static void drawPickedItems( EDA_DRAW_PANEL* aPanel, wxDC* aDC, wxPoint aOffset )
+{
+ PICKED_ITEMS_LIST* itemsList = &aPanel->GetScreen()->m_BlockLocate.GetItems();
+ PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent();
+
+ g_Offset_Module = -aOffset;
+
+ for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ )
+ {
+ BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii );
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_T:
+ frame->GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK;
+ ((MODULE*) item)->DrawOutlinesWhenMoving( aPanel, aDC, g_Offset_Module );
+ break;
+
+ case PCB_LINE_T:
+ case PCB_TEXT_T:
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ case PCB_TARGET_T:
+ case PCB_DIMENSION_T: // Currently markers are not affected by block commands
+ case PCB_MARKER_T:
+ item->Draw( aPanel, aDC, GR_XOR, aOffset );
+ break;
+
+ case PCB_ZONE_AREA_T:
+ item->Draw( aPanel, aDC, GR_XOR, aOffset );
+ ((ZONE_CONTAINER*) item)->DrawFilledArea( aPanel, aDC, GR_XOR, aOffset );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ g_Offset_Module = wxPoint( 0, 0 );
+}
+
+
+static void drawMovingBlock( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ BASE_SCREEN* screen = aPanel->GetScreen();
+
+ // do not show local module rastnest in block move, it is not usable.
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)aPanel->GetDisplayOptions();
+ bool showRats = displ_opts->m_Show_Module_Ratsnest;
+ displ_opts->m_Show_Module_Ratsnest = false;
+
+ if( aErase )
+ {
+ if( screen->m_BlockLocate.GetMoveVector().x || screen->m_BlockLocate.GetMoveVector().y )
+ {
+ screen->m_BlockLocate.Draw( aPanel, aDC, screen->m_BlockLocate.GetMoveVector(),
+ GR_XOR, BLOCK_OUTLINE_COLOR );
+
+ if( blockDrawItems )
+ drawPickedItems( aPanel, aDC, screen->m_BlockLocate.GetMoveVector() );
+ }
+ }
+
+
+ if( screen->m_BlockLocate.GetState() != STATE_BLOCK_STOP )
+ {
+ screen->m_BlockLocate.SetMoveVector( aPanel->GetParent()->GetCrossHairPosition() -
+ screen->m_BlockLocate.GetLastCursorPosition() );
+ }
+
+ if( screen->m_BlockLocate.GetMoveVector().x || screen->m_BlockLocate.GetMoveVector().y )
+ {
+ screen->m_BlockLocate.Draw( aPanel, aDC, screen->m_BlockLocate.GetMoveVector(),
+ GR_XOR, BLOCK_OUTLINE_COLOR );
+
+ if( blockDrawItems )
+ drawPickedItems( aPanel, aDC, screen->m_BlockLocate.GetMoveVector() );
+ }
+
+ displ_opts->m_Show_Module_Ratsnest = showRats;
+}
+
+
+void PCB_EDIT_FRAME::Block_Delete()
+{
+ OnModify();
+ SetCurItem( NULL );
+
+ PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems();
+ itemsList->m_Status = UR_DELETED;
+
+ // unlink items and clear flags
+ for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ )
+ {
+ BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii );
+ itemsList->SetPickedItemStatus( UR_DELETED, ii );
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_T:
+ {
+ MODULE* module = (MODULE*) item;
+ module->ClearFlags();
+ module->UnLink();
+ m_Pcb->m_Status_Pcb = 0;
+ }
+ break;
+
+ case PCB_ZONE_AREA_T: // a zone area
+ m_Pcb->Remove( item );
+ break;
+
+ case PCB_LINE_T: // a segment not on copper layers
+ case PCB_TEXT_T: // a text on a layer
+ case PCB_TRACE_T: // a track segment (segment on a copper layer)
+ case PCB_VIA_T: // a via (like track segment on a copper layer)
+ case PCB_DIMENSION_T: // a dimension (graphic item)
+ case PCB_TARGET_T: // a target (graphic item)
+ item->UnLink();
+ break;
+
+ // These items are deleted, but not put in undo list
+ case PCB_MARKER_T: // a marker used to show something
+ case PCB_ZONE_T: // SEG_ZONE items are now deprecated
+ item->UnLink();
+ itemsList->RemovePicker( ii );
+ ii--;
+ item->DeleteStructure();
+ break;
+
+ default:
+ wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Delete( ) error: unexpected type" ) );
+ break;
+ }
+ }
+
+ SaveCopyInUndoList( *itemsList, UR_DELETED );
+
+ Compile_Ratsnest( NULL, true );
+ m_canvas->Refresh( true );
+}
+
+
+void PCB_EDIT_FRAME::Block_Rotate()
+{
+ wxPoint centre; // rotation cent-re for the rotation transform
+ int rotAngle = m_rotationAngle; // rotation angle in 0.1 deg.
+
+ centre = GetScreen()->m_BlockLocate.Centre();
+
+ OnModify();
+
+ PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems();
+ itemsList->m_Status = UR_CHANGED;
+
+ for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ )
+ {
+ BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii );
+ wxASSERT( item );
+ itemsList->SetPickedItemStatus( UR_CHANGED, ii );
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_T:
+ ( (MODULE*) item )->ClearFlags();
+ m_Pcb->m_Status_Pcb = 0;
+ break;
+
+ // Move and rotate the track segments
+ case PCB_TRACE_T: // a track segment (segment on a copper layer)
+ case PCB_VIA_T: // a via (like track segment on a copper layer)
+ m_Pcb->m_Status_Pcb = 0;
+ break;
+
+ case PCB_ZONE_AREA_T:
+ case PCB_LINE_T:
+ case PCB_TEXT_T:
+ case PCB_TARGET_T:
+ case PCB_DIMENSION_T:
+ break;
+
+ // This item is not put in undo list
+ case PCB_ZONE_T: // SEG_ZONE items are now deprecated
+ itemsList->RemovePicker( ii );
+ ii--;
+ break;
+
+ default:
+ wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Rotate( ) error: unexpected type" ) );
+ break;
+ }
+ }
+
+ // Save all the block items in there current state before applying the rotation.
+ SaveCopyInUndoList( *itemsList, UR_CHANGED, centre );
+
+ // Now perform the rotation.
+ for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ )
+ {
+ BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii );
+ wxASSERT( item );
+ item->Rotate( centre, rotAngle );
+ }
+
+ Compile_Ratsnest( NULL, true );
+ m_canvas->Refresh( true );
+}
+
+
+void PCB_EDIT_FRAME::Block_Flip()
+{
+#define INVERT( pos ) (pos) = center.y - ( (pos) - center.y )
+ wxPoint center; // Position of the axis for inversion of all elements
+
+ OnModify();
+
+ PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems();
+ itemsList->m_Status = UR_FLIPPED;
+
+ center = GetScreen()->m_BlockLocate.Centre();
+
+ for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ )
+ {
+ BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii );
+ wxASSERT( item );
+ itemsList->SetPickedItemStatus( UR_FLIPPED, ii );
+ item->Flip( center );
+
+ // If a connected item is flipped, the ratsnest is no more OK
+ switch( item->Type() )
+ {
+ case PCB_MODULE_T:
+ item->ClearFlags();
+ m_Pcb->m_Status_Pcb = 0;
+ break;
+
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ m_Pcb->m_Status_Pcb = 0;
+ break;
+
+ case PCB_ZONE_AREA_T:
+ case PCB_LINE_T:
+ case PCB_TEXT_T:
+ case PCB_TARGET_T:
+ case PCB_DIMENSION_T:
+ break;
+
+ // This item is not put in undo list
+ case PCB_ZONE_T: // SEG_ZONE items are now deprecated
+ itemsList->RemovePicker( ii );
+ ii--;
+ break;
+
+
+ default:
+ wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Flip( ) error: unexpected type" ) );
+ break;
+ }
+ }
+
+ SaveCopyInUndoList( *itemsList, UR_FLIPPED, center );
+ Compile_Ratsnest( NULL, true );
+ m_canvas->Refresh( true );
+}
+
+
+void PCB_EDIT_FRAME::Block_Move()
+{
+ OnModify();
+
+ wxPoint MoveVector = GetScreen()->m_BlockLocate.GetMoveVector();
+
+ PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems();
+ itemsList->m_Status = UR_MOVED;
+
+ for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ )
+ {
+ BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii );
+ itemsList->SetPickedItemStatus( UR_MOVED, ii );
+ item->Move( MoveVector );
+ item->ClearFlags( IS_MOVED );
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_T:
+ m_Pcb->m_Status_Pcb = 0;
+ item->ClearFlags();
+ break;
+
+ // Move track segments
+ case PCB_TRACE_T: // a track segment (segment on a copper layer)
+ case PCB_VIA_T: // a via (like a track segment on a copper layer)
+ m_Pcb->m_Status_Pcb = 0;
+ break;
+
+ case PCB_ZONE_AREA_T:
+ case PCB_LINE_T:
+ case PCB_TEXT_T:
+ case PCB_TARGET_T:
+ case PCB_DIMENSION_T:
+ break;
+
+ // This item is not put in undo list
+ case PCB_ZONE_T: // SEG_ZONE items are now deprecated
+ itemsList->RemovePicker( ii );
+ ii--;
+ break;
+
+ default:
+ wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Move( ) error: unexpected type" ) );
+ break;
+ }
+ }
+
+ SaveCopyInUndoList( *itemsList, UR_MOVED, MoveVector );
+
+ Compile_Ratsnest( NULL, true );
+ m_canvas->Refresh( true );
+}
+
+
+void PCB_EDIT_FRAME::Block_Duplicate( bool aIncrement )
+{
+ wxPoint MoveVector = GetScreen()->m_BlockLocate.GetMoveVector();
+
+ OnModify();
+
+ PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems();
+
+ PICKED_ITEMS_LIST newList;
+ newList.m_Status = UR_NEW;
+
+ ITEM_PICKER picker( NULL, UR_NEW );
+ BOARD_ITEM* newitem;
+
+ for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ )
+ {
+ BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii );
+
+ newitem = (BOARD_ITEM*)item->Clone();
+
+ if( aIncrement )
+ newitem->IncrementItemReference();
+
+ if( item->Type() == PCB_MODULE_T )
+ m_Pcb->m_Status_Pcb = 0;
+
+ m_Pcb->Add( newitem );
+
+ if( newitem )
+ {
+ newitem->Move( MoveVector );
+ picker.SetItem ( newitem );
+ newList.PushItem( picker );
+ }
+ }
+
+ if( newList.GetCount() )
+ SaveCopyInUndoList( newList, UR_NEW );
+
+ Compile_Ratsnest( NULL, true );
+ m_canvas->Refresh( true );
+}
diff --git a/pcbnew/block_module_editor.cpp b/pcbnew/block_module_editor.cpp
new file mode 100644
index 0000000..fdf2d5a
--- /dev/null
+++ b/pcbnew/block_module_editor.cpp
@@ -0,0 +1,872 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file block_module_editor.cpp
+ * @brief Footprint editor block handling implementation.
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <block_commande.h>
+#include <macros.h>
+
+#include <wxPcbStruct.h>
+#include <module_editor_frame.h>
+#include <pcbplot.h>
+#include <trigo.h>
+
+#include <pcbnew.h>
+
+#include <class_board.h>
+#include <class_track.h>
+#include <class_drawsegment.h>
+#include <class_pcb_text.h>
+#include <class_mire.h>
+#include <class_module.h>
+#include <class_dimension.h>
+#include <class_edge_mod.h>
+
+#include <dialogs/dialog_move_exact.h>
+
+
+#define BLOCK_COLOR BROWN
+
+// Functions defined here, but used also in other files
+// These 3 functions are used in modedit to rotate, mirror or move the
+// whole footprint so they are called with force_all = true
+void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
+void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
+void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre,
+ const wxPoint& translation, double rotation,
+ bool force_all = false );
+
+// Local functions:
+static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase );
+static int MarkItemsInBloc( MODULE* module, EDA_RECT& Rect );
+
+static void ClearMarkItems( MODULE* module );
+static void CopyMarkedItems( MODULE* module, wxPoint offset, bool aIncrement );
+static void MoveMarkedItems( MODULE* module, wxPoint offset );
+static void DeleteMarkedItems( MODULE* module );
+
+
+int FOOTPRINT_EDIT_FRAME::BlockCommand( int key )
+{
+ int cmd;
+
+ switch( key )
+ {
+ default:
+ cmd = key & 0xFF;
+ break;
+
+ case - 1:
+ cmd = BLOCK_PRESELECT_MOVE;
+ break;
+
+ case 0:
+ cmd = BLOCK_MOVE;
+ break;
+
+ case GR_KB_ALT:
+ cmd = BLOCK_MIRROR_Y;
+ break;
+
+ case GR_KB_SHIFTCTRL:
+ cmd = BLOCK_DELETE;
+ break;
+
+ case GR_KB_SHIFT:
+ cmd = BLOCK_COPY;
+ break;
+
+ case GR_KB_CTRL:
+ cmd = BLOCK_ROTATE;
+ break;
+
+ case MOUSE_MIDDLE:
+ cmd = BLOCK_ZOOM;
+ break;
+ }
+
+ return cmd;
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
+{
+ int itemsCount = 0;
+ bool nextcmd = false;
+ MODULE* currentModule = GetBoard()->m_Modules;
+
+ if( GetScreen()->m_BlockLocate.GetCount() )
+ {
+ // Set the SELECTED flag of all preselected items, and clear preselect list
+ ClearMarkItems( currentModule );
+ PICKED_ITEMS_LIST* list = &GetScreen()->m_BlockLocate.GetItems();
+
+ for( unsigned ii = 0, e = list->GetCount(); ii < e; ++ii )
+ {
+ BOARD_ITEM* item = (BOARD_ITEM*) list->GetPickedItem( ii );
+ item->SetFlags( SELECTED );
+ ++itemsCount;
+ }
+
+ GetScreen()->m_BlockLocate.ClearItemsList();
+ }
+
+ switch( GetScreen()->m_BlockLocate.GetCommand() )
+ {
+ case BLOCK_IDLE:
+ DisplayError( this, wxT( "Error in HandleBlockPLace" ) );
+ break;
+
+ case BLOCK_DRAG: // Drag
+ case BLOCK_DRAG_ITEM: // Drag a given item (not used here)
+ case BLOCK_MOVE: // Move
+ case BLOCK_COPY: // Copy
+ case BLOCK_COPY_AND_INCREMENT: // Specific to duplicate with increment command
+
+ // Find selected items if we didn't already set them manually
+ if( itemsCount == 0 )
+ itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
+
+ if( itemsCount )
+ {
+ nextcmd = true;
+
+ if( m_canvas->IsMouseCaptured() )
+ {
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ }
+
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE );
+ m_canvas->Refresh( true );
+ }
+
+ break;
+
+ case BLOCK_MOVE_EXACT:
+ itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
+
+ if( itemsCount )
+ {
+ wxPoint translation;
+ double rotation = 0;
+
+ DIALOG_MOVE_EXACT dialog( this, translation, rotation );
+ int ret = dialog.ShowModal();
+
+ if( ret == wxID_OK )
+ {
+ SaveCopyInUndoList( currentModule, UR_MODEDIT );
+ const wxPoint blockCentre = GetScreen()->m_BlockLocate.Centre();
+ MoveMarkedItemsExactly( currentModule, blockCentre, translation, rotation );
+ }
+ }
+ break;
+
+ case BLOCK_PRESELECT_MOVE: // Move with preselection list
+ nextcmd = true;
+ m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE );
+ break;
+
+ case BLOCK_DELETE: // Delete
+ itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
+
+ if( itemsCount )
+ SaveCopyInUndoList( currentModule, UR_MODEDIT );
+
+ DeleteMarkedItems( currentModule );
+ break;
+
+ case BLOCK_SAVE: // Save
+ case BLOCK_PASTE:
+ break;
+
+ case BLOCK_ROTATE:
+ itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
+
+ if( itemsCount )
+ SaveCopyInUndoList( currentModule, UR_MODEDIT );
+
+ RotateMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
+ break;
+
+ case BLOCK_MIRROR_X:
+ case BLOCK_MIRROR_Y:
+ case BLOCK_FLIP: // mirror
+ itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
+
+ if( itemsCount )
+ SaveCopyInUndoList( currentModule, UR_MODEDIT );
+
+ MirrorMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
+ break;
+
+ case BLOCK_ZOOM: // Window Zoom
+ Window_Zoom( GetScreen()->m_BlockLocate );
+ break;
+
+ case BLOCK_ABORT:
+ break;
+
+ case BLOCK_SELECT_ITEMS_ONLY:
+ break;
+ }
+
+ if( !nextcmd )
+ {
+ if( GetScreen()->m_BlockLocate.GetCommand() != BLOCK_SELECT_ITEMS_ONLY )
+ {
+ ClearMarkItems( currentModule );
+ }
+
+ GetScreen()->ClearBlockCommand();
+ SetCurItem( NULL );
+ m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString,
+ false );
+ m_canvas->Refresh( true );
+ }
+
+ return nextcmd;
+}
+
+
+void FOOTPRINT_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
+{
+ MODULE* currentModule = GetBoard()->m_Modules;
+
+ if( !m_canvas->IsMouseCaptured() )
+ {
+ DisplayError( this, wxT( "HandleBlockPLace : m_mouseCaptureCallback = NULL" ) );
+ }
+
+ GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP );
+
+ const BLOCK_COMMAND_T command = GetScreen()->m_BlockLocate.GetCommand();
+
+ switch( command )
+ {
+ case BLOCK_IDLE:
+ break;
+
+ case BLOCK_DRAG: // Drag
+ case BLOCK_MOVE: // Move
+ case BLOCK_PRESELECT_MOVE: // Move with preselection list
+ GetScreen()->m_BlockLocate.ClearItemsList();
+ SaveCopyInUndoList( currentModule, UR_MODEDIT );
+ MoveMarkedItems( currentModule, GetScreen()->m_BlockLocate.GetMoveVector() );
+ m_canvas->Refresh( true );
+ break;
+
+ case BLOCK_COPY: // Copy
+ case BLOCK_COPY_AND_INCREMENT: // Copy and increment references
+ GetScreen()->m_BlockLocate.ClearItemsList();
+ SaveCopyInUndoList( currentModule, UR_MODEDIT );
+ CopyMarkedItems( currentModule, GetScreen()->m_BlockLocate.GetMoveVector(),
+ command == BLOCK_COPY_AND_INCREMENT );
+ break;
+
+ case BLOCK_PASTE: // Paste
+ GetScreen()->m_BlockLocate.ClearItemsList();
+ break;
+
+ case BLOCK_MIRROR_X:
+ case BLOCK_MIRROR_Y:
+ case BLOCK_FLIP: // Mirror by popup menu, from block move
+ SaveCopyInUndoList( currentModule, UR_MODEDIT );
+ MirrorMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
+ break;
+
+ case BLOCK_ROTATE:
+ SaveCopyInUndoList( currentModule, UR_MODEDIT );
+ RotateMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
+ break;
+
+ case BLOCK_ZOOM: // Handled by HandleBlockEnd
+ case BLOCK_DELETE:
+ case BLOCK_SAVE:
+ case BLOCK_ABORT:
+ default:
+ break;
+ }
+
+ OnModify();
+
+ GetScreen()->m_BlockLocate.SetState( STATE_NO_BLOCK );
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_IDLE );
+ SetCurItem( NULL );
+ m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false );
+ m_canvas->Refresh( true );
+}
+
+
+/* Traces the outline of the search block structures
+ * The entire block follows the cursor
+ */
+static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ BASE_SCREEN* screen = aPanel->GetScreen();
+ FOOTPRINT_EDIT_FRAME* moduleEditFrame = static_cast<FOOTPRINT_EDIT_FRAME*>( aPanel->GetParent() );
+
+ wxASSERT( moduleEditFrame );
+ MODULE* currentModule = moduleEditFrame->GetBoard()->m_Modules;
+
+ BLOCK_SELECTOR* block = &screen->m_BlockLocate;
+ GRSetDrawMode( aDC, g_XorMode );
+
+ if( aErase )
+ {
+ block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
+
+ if( currentModule )
+ {
+ wxPoint move_offset = -block->GetMoveVector();
+ BOARD_ITEM* item = currentModule->GraphicalItems();
+
+ for( ; item != NULL; item = item->Next() )
+ {
+ if( !item->IsSelected() )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ case PCB_MODULE_EDGE_T:
+ item->Draw( aPanel, aDC, g_XorMode, move_offset );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ D_PAD* pad = currentModule->Pads();
+
+ for( ; pad != NULL; pad = pad->Next() )
+ {
+ if( !pad->IsSelected() )
+ continue;
+
+ pad->Draw( aPanel, aDC, g_XorMode, move_offset );
+ }
+ }
+ }
+
+ // Repaint new view.
+ block->SetMoveVector( moduleEditFrame->GetCrossHairPosition() - block->GetLastCursorPosition() );
+
+ block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
+
+ if( currentModule )
+ {
+ BOARD_ITEM* item = currentModule->GraphicalItems();
+ wxPoint move_offset = - block->GetMoveVector();
+
+ for( ; item != NULL; item = item->Next() )
+ {
+ if( !item->IsSelected() )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ case PCB_MODULE_EDGE_T:
+ item->Draw( aPanel, aDC, g_XorMode, move_offset );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ D_PAD* pad = currentModule->Pads();
+
+ for( ; pad != NULL; pad = pad->Next() )
+ {
+ if( !pad->IsSelected() )
+ continue;
+
+ pad->Draw( aPanel, aDC, g_XorMode, move_offset );
+ }
+ }
+}
+
+
+/* Copy marked items, at new position = old position + offset
+ */
+void CopyMarkedItems( MODULE* module, wxPoint offset, bool aIncrement )
+{
+ if( module == NULL )
+ return;
+
+ // Reference and value cannot be copied, they are unique.
+ // Ensure they are not selected
+ module->Reference().ClearFlags();
+ module->Value().ClearFlags();
+
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ if( !pad->IsSelected() )
+ continue;
+
+ pad->ClearFlags( SELECTED );
+ D_PAD* NewPad = new D_PAD( *pad );
+ NewPad->SetParent( module );
+ NewPad->SetFlags( SELECTED );
+ module->Pads().PushFront( NewPad );
+
+ if( aIncrement )
+ NewPad->IncrementItemReference();
+ }
+
+ BOARD_ITEM* newItem;
+
+ for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item->Next() )
+ {
+ if( !item->IsSelected() )
+ continue;
+
+ item->ClearFlags( SELECTED );
+
+ newItem = (BOARD_ITEM*)item->Clone();
+ newItem->SetParent( module );
+ newItem->SetFlags( SELECTED );
+ module->GraphicalItems().PushFront( newItem );
+
+ if( aIncrement )
+ newItem->IncrementItemReference();
+ }
+
+ MoveMarkedItems( module, offset );
+}
+
+
+/* Move marked items, at new position = old position + offset
+ */
+void MoveMarkedItems( MODULE* module, wxPoint offset )
+{
+ EDA_ITEM* item;
+
+ if( module == NULL )
+ return;
+
+ if( module->Reference().IsSelected() )
+ module->Reference().Move( offset );
+
+ if( module->Value().IsSelected() )
+ module->Value().Move( offset );
+
+ D_PAD* pad = module->Pads();
+
+ for( ; pad != NULL; pad = pad->Next() )
+ {
+ if( !pad->IsSelected() )
+ continue;
+
+ pad->SetPosition( pad->GetPosition() + offset );
+ pad->SetPos0( pad->GetPos0() + offset );
+ }
+
+ item = module->GraphicalItems();
+
+ for( ; item != NULL; item = item->Next() )
+ {
+ if( !item->IsSelected() )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ static_cast<TEXTE_MODULE*>( item )->Move( offset );
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ {
+ EDGE_MODULE* em = (EDGE_MODULE*) item;
+ em->SetStart( em->GetStart() + offset );
+ em->SetEnd( em->GetEnd() + offset );
+ em->SetStart0( em->GetStart0() + offset );
+ em->SetEnd0( em->GetEnd0() + offset );
+ }
+ break;
+
+ default:
+ ;
+ }
+ }
+
+ ClearMarkItems( module );
+}
+
+
+/* Delete marked items
+ */
+void DeleteMarkedItems( MODULE* module )
+{
+ if( module == NULL )
+ return;
+
+ D_PAD* next_pad;
+ BOARD* board = module->GetBoard();
+
+ for( D_PAD* pad = module->Pads(); pad; pad = next_pad )
+ {
+ next_pad = pad->Next();
+
+ if( !pad->IsSelected() )
+ continue;
+
+ if( board )
+ board->PadDelete( pad );
+ else
+ pad->DeleteStructure();
+ }
+
+ BOARD_ITEM* next_item;
+
+ for( BOARD_ITEM* item = module->GraphicalItems(); item; item = next_item )
+ {
+ next_item = item->Next();
+
+ if( !item->IsSelected() )
+ continue;
+
+ item->DeleteStructure();
+ }
+
+ // Ref and value can be flagged, but cannot be deleted
+ ClearMarkItems( module );
+}
+
+
+/** Mirror marked items, refer to a Vertical axis at position offset
+ * Note: because this function is used in global transform,
+ * if force_all is true, all items will be mirrored
+ */
+void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all )
+{
+#define SETMIRROR( z ) (z) -= offset.x; (z) = -(z); (z) += offset.x;
+ wxPoint tmp;
+ wxSize tmpz;
+
+ if( module == NULL )
+ return;
+
+ if( module->Reference().IsSelected() || force_all )
+ module->Reference().Mirror( offset, false );
+
+ if( module->Value().IsSelected() || force_all )
+ module->Value().Mirror( offset, false );
+
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ // Skip pads not selected, i.e. not inside the block to mirror:
+ if( !pad->IsSelected() && !force_all )
+ continue;
+
+ tmp = pad->GetPosition();
+ SETMIRROR( tmp.x );
+ pad->SetPosition( tmp );
+
+ pad->SetX0( pad->GetPosition().x );
+
+ tmp = pad->GetOffset();
+ tmp.x = -tmp.x;
+ pad->SetOffset( tmp );
+
+ tmpz = pad->GetDelta();
+ tmpz.x = -tmpz.x;
+ pad->SetDelta( tmpz );
+
+ pad->SetOrientation( - pad->GetOrientation() );
+ }
+
+ for( EDA_ITEM* item = module->GraphicalItems(); item; item = item->Next() )
+ {
+ // Skip items not selected, i.e. not inside the block to mirror:
+ if( !item->IsSelected() && !force_all )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_EDGE_T:
+ ((EDGE_MODULE*) item)->Mirror( offset, false );
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ static_cast<TEXTE_MODULE*>( item )->Mirror( offset, false );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ ClearMarkItems( module );
+}
+
+
+/** Rotate marked items, refer to a rotation point at position offset
+ * Note: because this function is used in global transform,
+ * if force_all is true, all items will be rotated
+ */
+void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all )
+{
+#define ROTATE( z ) RotatePoint( (&z), offset, 900 )
+
+ if( module == NULL )
+ return;
+
+ if( module->Reference().IsSelected() || force_all )
+ module->Reference().Rotate( offset, 900 );
+
+ if( module->Value().IsSelected() || force_all )
+ module->Value().Rotate( offset, 900 );
+
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ if( !pad->IsSelected() && !force_all )
+ continue;
+
+ wxPoint pos = pad->GetPos0();
+ ROTATE( pos );
+ pad->SetPos0( pos );
+ pad->SetOrientation( pad->GetOrientation() + 900 );
+
+ pad->SetDrawCoord();
+ }
+
+ for( EDA_ITEM* item = module->GraphicalItems(); item; item = item->Next() )
+ {
+ if( !item->IsSelected() && !force_all )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_EDGE_T:
+ ((EDGE_MODULE*) item)->Rotate( offset, 900 );
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ static_cast<TEXTE_MODULE*>( item )->Rotate( offset, 900 );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ ClearMarkItems( module );
+}
+
+
+void ClearMarkItems( MODULE* module )
+{
+ if( module == NULL )
+ return;
+
+ module->Reference().ClearFlags();
+ module->Value().ClearFlags();
+
+ EDA_ITEM* item = module->GraphicalItems();
+
+ for( ; item != NULL; item = item->Next() )
+ {
+ item->ClearFlags();
+ }
+
+ item = module->Pads();
+
+ for( ; item != NULL; item = item->Next() )
+ {
+ item->ClearFlags();
+ }
+}
+
+
+void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre,
+ const wxPoint& translation,
+ double rotation, bool force_all )
+{
+ if( module == NULL )
+ return;
+
+ if( module->Reference().IsSelected() || force_all )
+ {
+ module->Reference().Rotate( centre, rotation );
+ module->Reference().Move( translation );
+ }
+
+ if( module->Value().IsSelected() || force_all )
+ {
+ module->Value().Rotate( centre, rotation );
+ module->Value().Move( translation );
+ }
+
+ D_PAD* pad = module->Pads();
+
+ for( ; pad != NULL; pad = pad->Next() )
+ {
+ if( !pad->IsSelected() && !force_all )
+ continue;
+
+ // rotate about centre point,
+ wxPoint newPos = pad->GetPosition();
+ RotatePoint( &newPos, centre, rotation );
+
+ // shift and update
+ newPos += translation;
+ pad->SetPosition( newPos );
+ pad->SetPos0( newPos );
+
+ // finally apply rotation to the pad itself
+ pad->Rotate( newPos, rotation );
+ }
+
+ EDA_ITEM* item = module->GraphicalItems();
+
+ for( ; item != NULL; item = item->Next() )
+ {
+ if( !item->IsSelected() && !force_all )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ {
+ TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
+
+ text->Rotate( centre, rotation );
+ text->Move( translation );
+ break;
+ }
+ case PCB_MODULE_EDGE_T:
+ {
+ EDGE_MODULE* em = static_cast<EDGE_MODULE*>( item );
+ em->Rotate( centre, rotation );
+ em->Move( translation );
+ break;
+ }
+ default:
+ ;
+ }
+ }
+
+ ClearMarkItems( module );
+}
+
+
+/* Mark items inside rect.
+ * Items are inside rect when an end point is inside rect
+ */
+int MarkItemsInBloc( MODULE* module, EDA_RECT& Rect )
+{
+ EDA_ITEM* item;
+ int ItemsCount = 0;
+ wxPoint pos;
+ D_PAD* pad;
+
+ if( module == NULL )
+ return 0;
+
+ ClearMarkItems( module ); // Just in case ...
+
+ pos = module->Reference().GetTextPosition();
+
+ if( Rect.Contains( pos ) )
+ {
+ module->Reference().SetFlags( SELECTED );
+ ItemsCount++;
+ }
+
+ pos = module->Value().GetTextPosition();
+
+ if( Rect.Contains( pos ) )
+ {
+ module->Value().SetFlags( SELECTED );
+ ItemsCount++;
+ }
+
+ pad = module->Pads();
+
+ for( ; pad != NULL; pad = pad->Next() )
+ {
+ pad->ClearFlags( SELECTED );
+ pos = pad->GetPosition();
+
+ if( Rect.Contains( pos ) )
+ {
+ pad->SetFlags( SELECTED );
+ ItemsCount++;
+ }
+ }
+
+ item = module->GraphicalItems();
+
+ for( ; item != NULL; item = item->Next() )
+ {
+ item->ClearFlags( SELECTED );
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_EDGE_T:
+ if( ((EDGE_MODULE*)item )->HitTest( Rect ) )
+ {
+ item->SetFlags( SELECTED );
+ ItemsCount++;
+ }
+
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ pos = static_cast<TEXTE_MODULE*>( item )->GetTextPosition();
+
+ if( Rect.Contains( pos ) )
+ {
+ item->SetFlags( SELECTED );
+ ItemsCount++;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return ItemsCount;
+}
diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp
new file mode 100644
index 0000000..275006e
--- /dev/null
+++ b/pcbnew/board_items_to_polygon_shape_transform.cpp
@@ -0,0 +1,1152 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/***
+ * @file board_items_to_polygon_shape_transform.cpp
+ * @brief function to convert shapes of items ( pads, tracks... ) to polygons
+ */
+
+/* Function to convert pad and track shapes to polygons
+ * Used to fill zones areas and in 3D viewer
+ */
+#include <vector>
+
+#include <fctsys.h>
+#include <drawtxt.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <trigo.h>
+#include <class_board.h>
+#include <class_pad.h>
+#include <class_track.h>
+#include <class_drawsegment.h>
+#include <class_pcb_text.h>
+#include <class_zone.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+#include <convert_basic_shapes_to_polygon.h>
+
+// These variables are parameters used in addTextSegmToPoly.
+// But addTextSegmToPoly is a call-back function,
+// so we cannot send them as arguments.
+static int s_textWidth;
+static int s_textCircle2SegmentCount;
+static SHAPE_POLY_SET* s_cornerBuffer;
+
+// This is a call back function, used by DrawGraphicText to draw the 3D text shape:
+static void addTextSegmToPoly( int x0, int y0, int xf, int yf )
+{
+ TransformRoundedEndsSegmentToPolygon( *s_cornerBuffer,
+ wxPoint( x0, y0), wxPoint( xf, yf ),
+ s_textCircle2SegmentCount, s_textWidth );
+}
+
+
+void BOARD::ConvertBrdLayerToPolygonalContours( LAYER_ID aLayer, SHAPE_POLY_SET& aOutlines )
+{
+ // Number of segments to convert a circle to a polygon
+ const int segcountforcircle = 18;
+ double correctionFactor = 1.0 / cos( M_PI / (segcountforcircle * 2) );
+
+ // convert tracks and vias:
+ for( TRACK* track = m_Track; track != NULL; track = track->Next() )
+ {
+ if( !track->IsOnLayer( aLayer ) )
+ continue;
+
+ track->TransformShapeWithClearanceToPolygon( aOutlines,
+ 0, segcountforcircle, correctionFactor );
+ }
+
+ // convert pads
+ for( MODULE* module = m_Modules; module != NULL; module = module->Next() )
+ {
+ module->TransformPadsShapesWithClearanceToPolygon( aLayer,
+ aOutlines, 0, segcountforcircle, correctionFactor );
+
+ // Micro-wave modules may have items on copper layers
+ module->TransformGraphicShapesWithClearanceToPolygonSet( aLayer,
+ aOutlines, 0, segcountforcircle, correctionFactor );
+ }
+
+ // convert copper zones
+ for( int ii = 0; ii < GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* zone = GetArea( ii );
+ LAYER_ID zonelayer = zone->GetLayer();
+
+ if( zonelayer == aLayer )
+ zone->TransformSolidAreasShapesToPolygonSet(
+ aOutlines, segcountforcircle, correctionFactor );
+ }
+
+ // convert graphic items on copper layers (texts)
+ for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
+ {
+ if( !item->IsOnLayer( aLayer ) )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_LINE_T: // should not exist on copper layers
+ ( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon(
+ aOutlines, 0, segcountforcircle, correctionFactor );
+ break;
+
+ case PCB_TEXT_T:
+ ( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet(
+ aOutlines, 0, segcountforcircle, correctionFactor );
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+void MODULE::TransformPadsShapesWithClearanceToPolygon( LAYER_ID aLayer,
+ SHAPE_POLY_SET& aCornerBuffer,
+ int aInflateValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor,
+ bool aSkipNPTHPadsWihNoCopper )
+{
+ D_PAD* pad = Pads();
+
+ wxSize margin;
+ for( ; pad != NULL; pad = pad->Next() )
+ {
+ if( !pad->IsOnLayer(aLayer) )
+ continue;
+
+ // NPTH pads are not drawn on layers if the shape size and pos is the same
+ // as their hole:
+ if( aSkipNPTHPadsWihNoCopper && pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
+ {
+ if( pad->GetDrillSize() == pad->GetSize() && pad->GetOffset() == wxPoint( 0, 0 ) )
+ {
+ switch( pad->GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+ if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
+ continue;
+ break;
+
+ case PAD_SHAPE_OVAL:
+ if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
+ continue;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ switch( aLayer )
+ {
+ case F_Mask:
+ case B_Mask:
+ margin.x = margin.y = pad->GetSolderMaskMargin() + aInflateValue;
+ break;
+
+ case F_Paste:
+ case B_Paste:
+ margin = pad->GetSolderPasteMargin();
+ margin.x += aInflateValue;
+ margin.y += aInflateValue;
+ break;
+
+ default:
+ margin.x = margin.y = aInflateValue;
+ break;
+ }
+
+ pad->BuildPadShapePolygon( aCornerBuffer, margin,
+ aCircleToSegmentsCount, aCorrectionFactor );
+ }
+}
+
+/* generate shapes of graphic items (outlines) on layer aLayer as polygons,
+ * and adds these polygons to aCornerBuffer
+ * aCornerBuffer = the buffer to store polygons
+ * aInflateValue = a value to inflate shapes
+ * aCircleToSegmentsCount = number of segments to approximate a circle
+ * aCorrectionFactor = the correction to apply to the circle radius
+ * to generate the polygon.
+ * if aCorrectionFactor = 1.0, the polygon is inside the circle
+ * the radius of circle approximated by segments is
+ * initial radius * aCorrectionFactor
+ */
+void MODULE::TransformGraphicShapesWithClearanceToPolygonSet(
+ LAYER_ID aLayer,
+ SHAPE_POLY_SET& aCornerBuffer,
+ int aInflateValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor,
+ int aCircleToSegmentsCountForTexts )
+{
+ std::vector<TEXTE_MODULE *> texts; // List of TEXTE_MODULE to convert
+ EDGE_MODULE* outline;
+
+ for( EDA_ITEM* item = GraphicalItems(); item != NULL; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ {
+ TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
+
+ if( text->GetLayer() == aLayer && text->IsVisible() )
+ texts.push_back( text );
+
+ break;
+ }
+
+ case PCB_MODULE_EDGE_T:
+ outline = (EDGE_MODULE*) item;
+
+ if( outline->GetLayer() != aLayer )
+ break;
+
+ outline->TransformShapeWithClearanceToPolygon( aCornerBuffer,
+ 0,
+ aCircleToSegmentsCount,
+ aCorrectionFactor );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Convert texts sur modules
+ if( Reference().GetLayer() == aLayer && Reference().IsVisible() )
+ texts.push_back( &Reference() );
+
+ if( Value().GetLayer() == aLayer && Value().IsVisible() )
+ texts.push_back( &Value() );
+
+ s_cornerBuffer = &aCornerBuffer;
+
+ // To allow optimization of circles approximated by segments,
+ // aCircleToSegmentsCountForTexts, when not 0, is used.
+ // if 0 (default value) the aCircleToSegmentsCount is used
+ s_textCircle2SegmentCount = aCircleToSegmentsCountForTexts ?
+ aCircleToSegmentsCountForTexts : aCircleToSegmentsCount;
+
+ for( unsigned ii = 0; ii < texts.size(); ii++ )
+ {
+ TEXTE_MODULE *textmod = texts[ii];
+ s_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
+ wxSize size = textmod->GetSize();
+
+ if( textmod->IsMirrored() )
+ size.x = -size.x;
+
+ DrawGraphicText( NULL, NULL, textmod->GetTextPosition(), BLACK,
+ textmod->GetShownText(), textmod->GetDrawRotation(), size,
+ textmod->GetHorizJustify(), textmod->GetVertJustify(),
+ textmod->GetThickness(), textmod->IsItalic(),
+ true, addTextSegmToPoly );
+ }
+
+}
+
+ /* Function TransformSolidAreasShapesToPolygonSet
+ * Convert solid areas full shapes to polygon set
+ * (the full shape is the polygon area with a thick outline)
+ * Used in 3D view
+ * Arcs (ends of segments) are approximated by segments
+ * aCornerBuffer = a buffer to store the polygons
+ * aCircleToSegmentsCount = the number of segments to approximate a circle
+ * aCorrectionFactor = the correction to apply to arcs radius to roughly
+ * keep arc radius when approximated by segments
+ */
+void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet(
+ SHAPE_POLY_SET& aCornerBuffer,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor )
+{
+ if( GetFilledPolysList().IsEmpty() )
+ return;
+
+ // add filled areas polygons
+ aCornerBuffer.Append( m_FilledPolysList );
+
+ // add filled areas outlines, which are drawn with thick lines
+ for( int i = 0; i < m_FilledPolysList.OutlineCount(); i++ )
+ {
+ const SHAPE_LINE_CHAIN& path = m_FilledPolysList.COutline( i );
+
+ for( int j = 0; j < path.PointCount(); j++ )
+ {
+ const VECTOR2I& a = path.CPoint( j );
+ const VECTOR2I& b = path.CPoint( j + 1 );
+
+ TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ), wxPoint( b.x, b.y ),
+ aCircleToSegmentsCount,
+ GetMinThickness() );
+ }
+ }
+}
+
+/**
+ * Function TransformBoundingBoxWithClearanceToPolygon
+ * Convert the text bounding box to a rectangular polygon
+ * Used in filling zones calculations
+ * Circles and arcs are approximated by segments
+ * @param aCornerBuffer = a buffer to store the polygon
+ * @param aClearanceValue = the clearance around the text bounding box
+ */
+void TEXTE_PCB::TransformBoundingBoxWithClearanceToPolygon(
+ SHAPE_POLY_SET& aCornerBuffer,
+ int aClearanceValue ) const
+{
+ if( GetText().Length() == 0 )
+ return;
+
+ wxPoint corners[4]; // Buffer of polygon corners
+
+ EDA_RECT rect = GetTextBox( -1 );
+ rect.Inflate( aClearanceValue );
+ corners[0].x = rect.GetOrigin().x;
+ corners[0].y = rect.GetOrigin().y;
+ corners[1].y = corners[0].y;
+ corners[1].x = rect.GetRight();
+ corners[2].x = corners[1].x;
+ corners[2].y = rect.GetBottom();
+ corners[3].y = corners[2].y;
+ corners[3].x = corners[0].x;
+
+ aCornerBuffer.NewOutline();
+
+ for( int ii = 0; ii < 4; ii++ )
+ {
+ // Rotate polygon
+ RotatePoint( &corners[ii].x, &corners[ii].y, m_Pos.x, m_Pos.y, m_Orient );
+ aCornerBuffer.Append( corners[ii].x, corners[ii].y );
+ }
+}
+
+
+/* Function TransformShapeWithClearanceToPolygonSet
+ * Convert the text shape to a set of polygons (one by segment)
+ * Used in filling zones calculations and 3D view
+ * Circles and arcs are approximated by segments
+ * aCornerBuffer = SHAPE_POLY_SET to store the polygon corners
+ * aClearanceValue = the clearance around the text
+ * aCircleToSegmentsCount = the number of segments to approximate a circle
+ * aCorrectionFactor = the correction to apply to circles radius to keep
+ * clearance when the circle is approximated by segment bigger or equal
+ * to the real clearance value (usually near from 1.0)
+ */
+
+void TEXTE_PCB::TransformShapeWithClearanceToPolygonSet(
+ SHAPE_POLY_SET& aCornerBuffer,
+ int aClearanceValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor ) const
+{
+ wxSize size = GetSize();
+
+ if( IsMirrored() )
+ size.x = -size.x;
+
+ s_cornerBuffer = &aCornerBuffer;
+ s_textWidth = GetThickness() + ( 2 * aClearanceValue );
+ s_textCircle2SegmentCount = aCircleToSegmentsCount;
+ EDA_COLOR_T color = BLACK; // not actually used, but needed by DrawGraphicText
+
+ if( IsMultilineAllowed() )
+ {
+ wxArrayString strings_list;
+ wxStringSplit( GetShownText(), strings_list, '\n' );
+ std::vector<wxPoint> positions;
+ positions.reserve( strings_list.Count() );
+ GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() );
+
+ for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
+ {
+ wxString txt = strings_list.Item( ii );
+ DrawGraphicText( NULL, NULL, positions[ii], color,
+ txt, GetOrientation(), size,
+ GetHorizJustify(), GetVertJustify(),
+ GetThickness(), IsItalic(),
+ true, addTextSegmToPoly );
+ }
+ }
+ else
+ {
+ DrawGraphicText( NULL, NULL, GetTextPosition(), color,
+ GetShownText(), GetOrientation(), size,
+ GetHorizJustify(), GetVertJustify(),
+ GetThickness(), IsItalic(),
+ true, addTextSegmToPoly );
+ }
+}
+
+
+/**
+ * Function TransformShapeWithClearanceToPolygon
+ * Convert the track shape to a closed polygon
+ * Used in filling zones calculations
+ * Circles and arcs are approximated by segments
+ * @param aCornerBuffer = a buffer to store the polygon
+ * @param aClearanceValue = the clearance around the pad
+ * @param aCircleToSegmentsCount = the number of segments to approximate a circle
+ * @param aCorrectionFactor = the correction to apply to circles radius to keep
+ * clearance when the circle is approxiamted by segment bigger or equal
+ * to the real clearance value (usually near from 1.0)
+ */
+void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
+ int aClearanceValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor ) const
+{
+ // The full width of the lines to create:
+ int linewidth = m_Width + (2 * aClearanceValue);
+
+ switch( m_Shape )
+ {
+ case S_CIRCLE:
+ TransformRingToPolygon( aCornerBuffer, GetCenter(), GetRadius(),
+ aCircleToSegmentsCount, linewidth ) ;
+ break;
+
+ case S_ARC:
+ TransformArcToPolygon( aCornerBuffer, GetCenter(),
+ GetArcStart(), m_Angle,
+ aCircleToSegmentsCount, linewidth );
+ break;
+
+ case S_SEGMENT:
+ TransformRoundedEndsSegmentToPolygon( aCornerBuffer, m_Start, m_End,
+ aCircleToSegmentsCount, linewidth );
+ break;
+
+ case S_POLYGON:
+ if ( GetPolyPoints().size() < 2 )
+ break; // Malformed polygon.
+ {
+ // The polygon is expected to be a simple polygon
+ // not self intersecting, no hole.
+ MODULE* module = GetParentModule(); // NULL for items not in footprints
+ double orientation = module ? module->GetOrientation() : 0.0;
+
+ // Build the polygon with the actual position and orientation:
+ std::vector< wxPoint> poly;
+ poly = GetPolyPoints();
+
+ for( unsigned ii = 0; ii < poly.size(); ii++ )
+ {
+ RotatePoint( &poly[ii], orientation );
+ poly[ii] += GetPosition();
+ }
+
+ // Generate polygons for the outline + clearance
+ // This code is compatible with a polygon with holes linked to external outline
+ // by overlapping segments.
+
+ // Insert the initial polygon:
+ aCornerBuffer.NewOutline();
+
+ for( unsigned ii = 0; ii < poly.size(); ii++ )
+ aCornerBuffer.Append( poly[ii].x, poly[ii].y );
+
+ if( linewidth ) // Add thick outlines
+ {
+ CPolyPt corner1( poly[poly.size()-1] );
+
+ for( unsigned ii = 0; ii < poly.size(); ii++ )
+ {
+ CPolyPt corner2( poly[ii] );
+
+ if( corner2 != corner1 )
+ {
+ TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
+ corner1, corner2, aCircleToSegmentsCount, linewidth );
+ }
+
+ corner1 = corner2;
+ }
+ }
+ }
+ break;
+
+ case S_CURVE: // Bezier curve (TODO: not yet in use)
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**
+ * Function TransformShapeWithClearanceToPolygon
+ * Convert the track shape to a closed polygon
+ * Used in filling zones calculations
+ * Circles (vias) and arcs (ends of tracks) are approximated by segments
+ * @param aCornerBuffer = a buffer to store the polygon
+ * @param aClearanceValue = the clearance around the pad
+ * @param aCircleToSegmentsCount = the number of segments to approximate a circle
+ * @param aCorrectionFactor = the correction to apply to circles radius to keep
+ * clearance when the circle is approximated by segment bigger or equal
+ * to the real clearance value (usually near from 1.0)
+ */
+void TRACK::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
+ int aClearanceValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor ) const
+{
+ switch( Type() )
+ {
+ case PCB_VIA_T:
+ {
+ int radius = (m_Width / 2) + aClearanceValue;
+ radius = KiROUND( radius * aCorrectionFactor );
+ TransformCircleToPolygon( aCornerBuffer, m_Start, radius, aCircleToSegmentsCount );
+ }
+ break;
+
+ default:
+ TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
+ m_Start, m_End,
+ aCircleToSegmentsCount,
+ m_Width + ( 2 * aClearanceValue) );
+ break;
+ }
+}
+
+
+/* Function TransformShapeWithClearanceToPolygon
+ * Convert the pad shape to a closed polygon
+ * Used in filling zones calculations and 3D view generation
+ * Circles and arcs are approximated by segments
+ * aCornerBuffer = a SHAPE_POLY_SET to store the polygon corners
+ * aClearanceValue = the clearance around the pad
+ * aCircleToSegmentsCount = the number of segments to approximate a circle
+ * aCorrectionFactor = the correction to apply to circles radius to keep
+ * clearance when the circle is approximated by segment bigger or equal
+ * to the real clearance value (usually near from 1.0)
+ */
+void D_PAD:: TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
+ int aClearanceValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor ) const
+{
+ double angle = m_Orient;
+ int dx = (m_Size.x / 2) + aClearanceValue;
+ int dy = (m_Size.y / 2) + aClearanceValue;
+
+ wxPoint PadShapePos = ShapePos(); /* Note: for pad having a shape offset,
+ * the pad position is NOT the shape position */
+
+ switch( GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+ dx = KiROUND( dx * aCorrectionFactor );
+ TransformCircleToPolygon( aCornerBuffer, PadShapePos, dx,
+ aCircleToSegmentsCount );
+ break;
+
+ case PAD_SHAPE_OVAL:
+ // An oval pad has the same shape as a segment with rounded ends
+ {
+ int width;
+ wxPoint shape_offset;
+ if( dy > dx ) // Oval pad X/Y ratio for choosing translation axis
+ {
+ dy = KiROUND( dy * aCorrectionFactor );
+ shape_offset.y = dy - dx;
+ width = dx * 2;
+ }
+ else //if( dy <= dx )
+ {
+ dx = KiROUND( dx * aCorrectionFactor );
+ shape_offset.x = dy - dx;
+ width = dy * 2;
+ }
+
+ RotatePoint( &shape_offset, angle );
+ wxPoint start = PadShapePos - shape_offset;
+ wxPoint end = PadShapePos + shape_offset;
+ TransformRoundedEndsSegmentToPolygon( aCornerBuffer, start, end,
+ aCircleToSegmentsCount, width );
+ }
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ case PAD_SHAPE_RECT:
+ {
+ wxPoint corners[4];
+ BuildPadPolygon( corners, wxSize( 0, 0 ), angle );
+
+ SHAPE_POLY_SET outline;
+
+ outline.NewOutline();
+
+ for( int ii = 0; ii < 4; ii++ )
+ {
+ corners[ii] += PadShapePos;
+ outline.Append( corners[ii].x, corners[ii].y );
+ }
+
+ double rounding_radius = aClearanceValue * aCorrectionFactor;
+
+ outline.Inflate( (int) rounding_radius, aCircleToSegmentsCount );
+
+ aCornerBuffer.Append( outline );
+ }
+ break;
+ }
+}
+
+/*
+ * Function BuildPadShapePolygon
+ * Build the Corner list of the polygonal shape,
+ * depending on shape, extra size (clearance ...) pad and orientation
+ * Note: for Round and oval pads this function is equivalent to
+ * TransformShapeWithClearanceToPolygon, but not for other shapes
+ */
+void D_PAD::BuildPadShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
+ wxSize aInflateValue, int aSegmentsPerCircle,
+ double aCorrectionFactor ) const
+{
+ wxPoint corners[4];
+ wxPoint PadShapePos = ShapePos(); /* Note: for pad having a shape offset,
+ * the pad position is NOT the shape position */
+ switch( GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+ case PAD_SHAPE_OVAL:
+ TransformShapeWithClearanceToPolygon( aCornerBuffer, aInflateValue.x,
+ aSegmentsPerCircle, aCorrectionFactor );
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ case PAD_SHAPE_RECT:
+ aCornerBuffer.NewOutline();
+
+ BuildPadPolygon( corners, aInflateValue, m_Orient );
+ for( int ii = 0; ii < 4; ii++ )
+ {
+ corners[ii] += PadShapePos; // Shift origin to position
+ aCornerBuffer.Append( corners[ii].x, corners[ii].y );
+ }
+
+ break;
+ }
+}
+
+/*
+ * Function BuildPadDrillShapePolygon
+ * Build the Corner list of the polygonal drill shape,
+ * depending on shape pad hole and orientation
+ * return false if the pad has no hole, true otherwise
+ */
+bool D_PAD::BuildPadDrillShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
+ int aInflateValue, int aSegmentsPerCircle ) const
+{
+ wxSize drillsize = GetDrillSize();
+
+ if( !drillsize.x || !drillsize.y )
+ return false;
+
+ if( drillsize.x == drillsize.y ) // usual round hole
+ {
+ TransformCircleToPolygon( aCornerBuffer, GetPosition(),
+ (drillsize.x / 2) + aInflateValue, aSegmentsPerCircle );
+ }
+ else // Oblong hole
+ {
+ wxPoint start, end;
+ int width;
+
+ GetOblongDrillGeometry( start, end, width );
+
+ width += aInflateValue * 2;
+
+ TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
+ GetPosition() + start, GetPosition() + end, aSegmentsPerCircle, width );
+ }
+
+ return true;
+}
+
+/**
+ * Function CreateThermalReliefPadPolygon
+ * Add holes around a pad to create a thermal relief
+ * copper thickness is min (dx/2, aCopperWitdh) or min (dy/2, aCopperWitdh)
+ * @param aCornerBuffer = a buffer to store the polygon
+ * @param aPad = the current pad used to create the thermal shape
+ * @param aThermalGap = gap in thermal shape
+ * @param aCopperThickness = stubs thickness in thermal shape
+ * @param aMinThicknessValue = min copper thickness allowed
+ * @param aCircleToSegmentsCount = the number of segments to approximate a circle
+ * @param aCorrectionFactor = the correction to apply to circles radius to keep
+ * @param aThermalRot = for rond pads the rotation of thermal stubs (450 usually for 45 deg.)
+ */
+
+/* thermal reliefs are created as 4 polygons.
+ * each corner of a polygon if calculated for a pad at position 0, 0, orient 0,
+ * and then moved and rotated acroding to the pad position and orientation
+ */
+
+/*
+ * Note 1: polygons are drawm using outlines witk a thickness = aMinThicknessValue
+ * so shapes must take in account this outline thickness
+ *
+ * Note 2:
+ * Trapezoidal pads are not considered here because they are very special case
+ * and are used in microwave applications and they *DO NOT* have a thermal relief that
+ * change the shape by creating stubs and destroy their properties.
+ */
+void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
+ D_PAD& aPad,
+ int aThermalGap,
+ int aCopperThickness,
+ int aMinThicknessValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor,
+ double aThermalRot )
+{
+ wxPoint corner, corner_end;
+ wxPoint PadShapePos = aPad.ShapePos(); // Note: for pad having a shape offset,
+ // the pad position is NOT the shape position
+ wxSize copper_thickness;
+
+ int dx = aPad.GetSize().x / 2;
+ int dy = aPad.GetSize().y / 2;
+
+ double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
+
+ /* Keep in account the polygon outline thickness
+ * aThermalGap must be increased by aMinThicknessValue/2 because drawing external outline
+ * with a thickness of aMinThicknessValue will reduce gap by aMinThicknessValue/2
+ */
+ aThermalGap += aMinThicknessValue / 2;
+
+ /* Keep in account the polygon outline thickness
+ * copper_thickness must be decreased by aMinThicknessValue because drawing outlines
+ * with a thickness of aMinThicknessValue will increase real thickness by aMinThicknessValue
+ */
+ aCopperThickness -= aMinThicknessValue;
+
+ if( aCopperThickness < 0 )
+ aCopperThickness = 0;
+
+ copper_thickness.x = std::min( dx, aCopperThickness );
+ copper_thickness.y = std::min( dy, aCopperThickness );
+
+ switch( aPad.GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE: // Add 4 similar holes
+ {
+ /* we create 4 copper holes and put them in position 1, 2, 3 and 4
+ * here is the area of the rectangular pad + its thermal gap
+ * the 4 copper holes remove the copper in order to create the thermal gap
+ * 4 ------ 1
+ * | |
+ * | |
+ * | |
+ * | |
+ * 3 ------ 2
+ * holes 2, 3, 4 are the same as hole 1, rotated 90, 180, 270 deg
+ */
+
+ // Build the hole pattern, for the hole in the X >0, Y > 0 plane:
+ // The pattern roughtly is a 90 deg arc pie
+ std::vector <wxPoint> corners_buffer;
+
+ // Radius of outer arcs of the shape corrected for arc approximation by lines
+ int outer_radius = KiROUND( (dx + aThermalGap) * aCorrectionFactor );
+
+ // Crosspoint of thermal spoke sides, the first point of polygon buffer
+ corners_buffer.push_back( wxPoint( copper_thickness.x / 2, copper_thickness.y / 2 ) );
+
+ // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side
+ // and first seg of arc approx
+ corner.x = copper_thickness.x / 2;
+ int y = outer_radius - (aThermalGap / 4);
+ corner.y = KiROUND( sqrt( ( (double) y * y - (double) corner.x * corner.x ) ) );
+
+ if( aThermalRot != 0 )
+ corners_buffer.push_back( corner );
+
+ // calculate the starting point of the outter arc
+ corner.x = copper_thickness.x / 2;
+
+ corner.y = KiROUND( sqrt( ( (double) outer_radius * outer_radius ) -
+ ( (double) corner.x * corner.x ) ) );
+ RotatePoint( &corner, 90 ); // 9 degrees is the spoke fillet size
+
+ // calculate the ending point of the outter arc
+ corner_end.x = corner.y;
+ corner_end.y = corner.x;
+
+ // calculate intermediate points (y coordinate from corner.y to corner_end.y
+ while( (corner.y > corner_end.y) && (corner.x < corner_end.x) )
+ {
+ corners_buffer.push_back( corner );
+ RotatePoint( &corner, delta );
+ }
+
+ corners_buffer.push_back( corner_end );
+
+ /* add an intermediate point, to avoid angles < 90 deg between last arc approx line
+ * and radius line
+ */
+ corner.x = corners_buffer[1].y;
+ corner.y = corners_buffer[1].x;
+ corners_buffer.push_back( corner );
+
+ // Now, add the 4 holes ( each is the pattern, rotated by 0, 90, 180 and 270 deg
+ // aThermalRot = 450 (45.0 degrees orientation) work fine.
+ double angle_pad = aPad.GetOrientation(); // Pad orientation
+ double th_angle = aThermalRot;
+
+ for( unsigned ihole = 0; ihole < 4; ihole++ )
+ {
+ aCornerBuffer.NewOutline();
+
+ for( unsigned ii = 0; ii < corners_buffer.size(); ii++ )
+ {
+ corner = corners_buffer[ii];
+ RotatePoint( &corner, th_angle + angle_pad ); // Rotate by segment angle and pad orientation
+ corner += PadShapePos;
+ aCornerBuffer.Append( corner.x, corner.y );
+ }
+
+ th_angle += 900; // Note: th_angle in in 0.1 deg.
+ }
+ }
+ break;
+
+ case PAD_SHAPE_OVAL:
+ {
+ // Oval pad support along the lines of round and rectangular pads
+ std::vector <wxPoint> corners_buffer; // Polygon buffer as vector
+
+ int dx = (aPad.GetSize().x / 2) + aThermalGap; // Cutout radius x
+ int dy = (aPad.GetSize().y / 2) + aThermalGap; // Cutout radius y
+
+ wxPoint shape_offset;
+
+ // We want to calculate an oval shape with dx > dy.
+ // if this is not the case, exchange dx and dy, and rotate the shape 90 deg.
+ int supp_angle = 0;
+
+ if( dx < dy )
+ {
+ std::swap( dx, dy );
+ supp_angle = 900;
+ std::swap( copper_thickness.x, copper_thickness.y );
+ }
+
+ int deltasize = dx - dy; // = distance between shape position and the 2 demi-circle ends centre
+ // here we have dx > dy
+ // Radius of outer arcs of the shape:
+ int outer_radius = dy; // The radius of the outer arc is radius end + aThermalGap
+
+ // Some coordinate fiddling, depending on the shape offset direction
+ shape_offset = wxPoint( deltasize, 0 );
+
+ // Crosspoint of thermal spoke sides, the first point of polygon buffer
+ corner.x = copper_thickness.x / 2;
+ corner.y = copper_thickness.y / 2;
+ corners_buffer.push_back( corner );
+
+ // Arc start point calculation, the intersecting point of cutout arc and thermal spoke edge
+ // If copper thickness is more than shape offset, we need to calculate arc intercept point.
+ if( copper_thickness.x > deltasize )
+ {
+ corner.x = copper_thickness.x / 2;
+ corner.y = KiROUND( sqrt( ( (double) outer_radius * outer_radius ) -
+ ( (double) ( corner.x - delta ) * ( corner.x - deltasize ) ) ) );
+ corner.x -= deltasize;
+
+ /* creates an intermediate point, to have a > 90 deg angle
+ * between the side and the first segment of arc approximation
+ */
+ wxPoint intpoint = corner;
+ intpoint.y -= aThermalGap / 4;
+ corners_buffer.push_back( intpoint + shape_offset );
+ RotatePoint( &corner, 90 ); // 9 degrees of thermal fillet
+ }
+ else
+ {
+ corner.x = copper_thickness.x / 2;
+ corner.y = outer_radius;
+ corners_buffer.push_back( corner );
+ }
+
+ // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side
+ // and first seg of arc approx
+ wxPoint last_corner;
+ last_corner.y = copper_thickness.y / 2;
+ int px = outer_radius - (aThermalGap / 4);
+ last_corner.x =
+ KiROUND( sqrt( ( ( (double) px * px ) - (double) last_corner.y * last_corner.y ) ) );
+
+ // Arc stop point calculation, the intersecting point of cutout arc and thermal spoke edge
+ corner_end.y = copper_thickness.y / 2;
+ corner_end.x =
+ KiROUND( sqrt( ( (double) outer_radius *
+ outer_radius ) - ( (double) corner_end.y * corner_end.y ) ) );
+ RotatePoint( &corner_end, -90 ); // 9 degrees of thermal fillet
+
+ // calculate intermediate arc points till limit is reached
+ while( (corner.y > corner_end.y) && (corner.x < corner_end.x) )
+ {
+ corners_buffer.push_back( corner + shape_offset );
+ RotatePoint( &corner, delta );
+ }
+
+ //corners_buffer.push_back(corner + shape_offset); // TODO: about one mil geometry error forms somewhere.
+ corners_buffer.push_back( corner_end + shape_offset );
+ corners_buffer.push_back( last_corner + shape_offset ); // Enabling the line above shows intersection point.
+
+ /* Create 2 holes, rotated by pad rotation.
+ */
+ double angle = aPad.GetOrientation() + supp_angle;
+
+ for( int irect = 0; irect < 2; irect++ )
+ {
+ aCornerBuffer.NewOutline();
+ for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
+ {
+ wxPoint cpos = corners_buffer[ic];
+ RotatePoint( &cpos, angle );
+ cpos += PadShapePos;
+ aCornerBuffer.Append( cpos.x, cpos.y );
+ }
+
+ angle = AddAngles( angle, 1800 ); // this is calculate hole 3
+ }
+
+ // Create holes, that are the mirrored from the previous holes
+ for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
+ {
+ wxPoint swap = corners_buffer[ic];
+ swap.x = -swap.x;
+ corners_buffer[ic] = swap;
+ }
+
+ // Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg
+ angle = aPad.GetOrientation() + supp_angle;
+
+ for( int irect = 0; irect < 2; irect++ )
+ {
+ aCornerBuffer.NewOutline();
+
+ for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
+ {
+ wxPoint cpos = corners_buffer[ic];
+ RotatePoint( &cpos, angle );
+ cpos += PadShapePos;
+ aCornerBuffer.Append( cpos.x, cpos.y );
+ }
+
+ angle = AddAngles( angle, 1800 );
+ }
+ }
+ break;
+
+ case PAD_SHAPE_RECT: // draw 4 Holes
+ {
+ /* we create 4 copper holes and put them in position 1, 2, 3 and 4
+ * here is the area of the rectangular pad + its thermal gap
+ * the 4 copper holes remove the copper in order to create the thermal gap
+ * 4 ------ 1
+ * | |
+ * | |
+ * | |
+ * | |
+ * 3 ------ 2
+ * hole 3 is the same as hole 1, rotated 180 deg
+ * hole 4 is the same as hole 2, rotated 180 deg and is the same as hole 1, mirrored
+ */
+
+ // First, create a rectangular hole for position 1 :
+ // 2 ------- 3
+ // | |
+ // | |
+ // | |
+ // 1 -------4
+
+ // Modified rectangles with one corner rounded. TODO: merging with oval thermals
+ // and possibly round too.
+
+ std::vector <wxPoint> corners_buffer; // Polygon buffer as vector
+
+ int dx = (aPad.GetSize().x / 2) + aThermalGap; // Cutout radius x
+ int dy = (aPad.GetSize().y / 2) + aThermalGap; // Cutout radius y
+
+ // The first point of polygon buffer is left lower corner, second the crosspoint of
+ // thermal spoke sides, the third is upper right corner and the rest are rounding
+ // vertices going anticlockwise. Note the inveted Y-axis in CG.
+ corners_buffer.push_back( wxPoint( -dx, -(aThermalGap / 4 + copper_thickness.y / 2) ) ); // Adds small miters to zone
+ corners_buffer.push_back( wxPoint( -(dx - aThermalGap / 4), -copper_thickness.y / 2 ) ); // fill and spoke corner
+ corners_buffer.push_back( wxPoint( -copper_thickness.x / 2, -copper_thickness.y / 2 ) );
+ corners_buffer.push_back( wxPoint( -copper_thickness.x / 2, -(dy - aThermalGap / 4) ) );
+ corners_buffer.push_back( wxPoint( -(aThermalGap / 4 + copper_thickness.x / 2), -dy ) );
+
+ double angle = aPad.GetOrientation();
+ int rounding_radius = KiROUND( aThermalGap * aCorrectionFactor ); // Corner rounding radius
+
+ for( int i = 0; i < aCircleToSegmentsCount / 4 + 1; i++ )
+ {
+ wxPoint corner_position = wxPoint( 0, -rounding_radius );
+
+ // Start at half increment offset
+ RotatePoint( &corner_position, 1800.0 / aCircleToSegmentsCount );
+ double angle_pg = i * delta;
+
+ RotatePoint( &corner_position, angle_pg ); // Rounding vector rotation
+ corner_position -= aPad.GetSize() / 2; // Rounding vector + Pad corner offset
+
+ corners_buffer.push_back( wxPoint( corner_position.x, corner_position.y ) );
+ }
+
+ for( int irect = 0; irect < 2; irect++ )
+ {
+ aCornerBuffer.NewOutline();
+
+ for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
+ {
+ wxPoint cpos = corners_buffer[ic];
+ RotatePoint( &cpos, angle ); // Rotate according to module orientation
+ cpos += PadShapePos; // Shift origin to position
+ aCornerBuffer.Append( cpos.x, cpos.y );
+ }
+
+ angle = AddAngles( angle, 1800 ); // this is calculate hole 3
+ }
+
+ // Create holes, that are the mirrored from the previous holes
+ for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
+ {
+ wxPoint swap = corners_buffer[ic];
+ swap.x = -swap.x;
+ corners_buffer[ic] = swap;
+ }
+
+ // Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg
+ for( int irect = 0; irect < 2; irect++ )
+ {
+ aCornerBuffer.NewOutline();
+
+ for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
+ {
+ wxPoint cpos = corners_buffer[ic];
+ RotatePoint( &cpos, angle );
+ cpos += PadShapePos;
+ aCornerBuffer.Append( cpos.x, cpos.y );
+ }
+
+ angle = AddAngles( angle, 1800 );
+ }
+ }
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ {
+ SHAPE_POLY_SET antipad; // The full antipad area
+
+ // We need a length to build the stubs of the thermal reliefs
+ // the value is not very important. The pad bounding box gives a reasonable value
+ EDA_RECT bbox = aPad.GetBoundingBox();
+ int stub_len = std::max( bbox.GetWidth(), bbox.GetHeight() );
+
+ aPad.TransformShapeWithClearanceToPolygon( antipad, aThermalGap,
+ aCircleToSegmentsCount, aCorrectionFactor );
+
+ SHAPE_POLY_SET stub; // A basic stub ( a rectangle)
+ SHAPE_POLY_SET stubs; // the full stubs shape
+
+
+ // We now substract the stubs (connections to the copper zone)
+ //ClipperLib::Clipper clip_engine;
+ // Prepare a clipping transform
+ //clip_engine.AddPath( antipad, ClipperLib::ptSubject, true );
+
+ // Create stubs and add them to clipper engine
+ wxPoint stubBuffer[4];
+ stubBuffer[0].x = stub_len;
+ stubBuffer[0].y = copper_thickness.y/2;
+ stubBuffer[1] = stubBuffer[0];
+ stubBuffer[1].y = -copper_thickness.y/2;
+ stubBuffer[2] = stubBuffer[1];
+ stubBuffer[2].x = -stub_len;
+ stubBuffer[3] = stubBuffer[2];
+ stubBuffer[3].y = copper_thickness.y/2;
+
+ stub.NewOutline();
+
+ for( unsigned ii = 0; ii < DIM( stubBuffer ); ii++ )
+ {
+ wxPoint cpos = stubBuffer[ii];
+ RotatePoint( &cpos, aPad.GetOrientation() );
+ cpos += PadShapePos;
+ stub.Append( cpos.x, cpos.y );
+ }
+
+ stubs.Append( stub );
+
+ stubBuffer[0].y = stub_len;
+ stubBuffer[0].x = copper_thickness.x/2;
+ stubBuffer[1] = stubBuffer[0];
+ stubBuffer[1].x = -copper_thickness.x/2;
+ stubBuffer[2] = stubBuffer[1];
+ stubBuffer[2].y = -stub_len;
+ stubBuffer[3] = stubBuffer[2];
+ stubBuffer[3].x = copper_thickness.x/2;
+
+ stub.RemoveAllContours();
+ stub.NewOutline();
+
+ for( unsigned ii = 0; ii < DIM( stubBuffer ); ii++ )
+ {
+ wxPoint cpos = stubBuffer[ii];
+ RotatePoint( &cpos, aPad.GetOrientation() );
+ cpos += PadShapePos;
+ stub.Append( cpos.x, cpos.y );
+ }
+
+ stubs.Append( stub );
+ stubs.Simplify();
+
+ antipad.BooleanSubtract( stubs );
+ aCornerBuffer.Append( antipad );
+
+ break;
+ }
+
+ default:
+ ;
+ }
+}
diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp
new file mode 100644
index 0000000..48bf7eb
--- /dev/null
+++ b/pcbnew/board_undo_redo.cpp
@@ -0,0 +1,713 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <boost/bind.hpp>
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <class_draw_panel_gal.h>
+#include <macros.h>
+
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+
+#include <class_board.h>
+#include <class_track.h>
+#include <class_drawsegment.h>
+#include <class_pcb_text.h>
+#include <class_mire.h>
+#include <class_module.h>
+#include <class_dimension.h>
+#include <class_zone.h>
+#include <class_edge_mod.h>
+
+#include <ratsnest_data.h>
+
+#include <tools/selection_tool.h>
+#include <tool/tool_manager.h>
+
+/* Functions to undo and redo edit commands.
+ * commands to undo are stored in CurrentScreen->m_UndoList
+ * commands to redo are stored in CurrentScreen->m_RedoList
+ *
+ * m_UndoList and m_RedoList handle a std::vector of PICKED_ITEMS_LIST
+ * Each PICKED_ITEMS_LIST handle a std::vector of pickers (class ITEM_PICKER),
+ * that store the list of schematic items that are concerned by the command to undo or redo
+ * and is created for each command to undo (handle also a command to redo).
+ * each picker has a pointer pointing to an item to undo or redo (in fact: deleted, added or
+ * modified),
+ * and has a pointer to a copy of this item, when this item has been modified
+ * (the old values of parameters are therefore saved)
+ *
+ * there are 3 cases:
+ * - delete item(s) command
+ * - change item(s) command
+ * - add item(s) command
+ * and 3 cases for block:
+ * - move list of items
+ * - mirror (Y) list of items
+ * - Flip list of items
+ *
+ * Undo command
+ * - delete item(s) command:
+ * => deleted items are moved in undo list
+ *
+ * - change item(s) command
+ * => A copy of item(s) is made (a DrawPickedStruct list of wrappers)
+ * the .m_Link member of each wrapper points the modified item.
+ * the .m_Item member of each wrapper points the old copy of this item.
+ *
+ * - add item(s) command
+ * =>A list of item(s) is made. The .m_Item member of each wrapper points the new item.
+ *
+ * Redo command
+ * - delete item(s) old command:
+ * => deleted items are moved in EEDrawList list, and in
+ *
+ * - change item(s) command
+ * => the copy of item(s) is moved in Undo list
+ *
+ * - add item(s) command
+ * => The list of item(s) is used to create a deleted list in undo list(same as a delete
+ * command)
+ *
+ * Some block operations that change items can be undone without memorize items, just the
+ * coordinates of the transform:
+ * move list of items (undo/redo is made by moving with the opposite move vector)
+ * mirror (Y) and flip list of items (undo/redo is made by mirror or flip items)
+ * so they are handled specifically.
+ *
+ */
+
+
+/**
+ * Function TestForExistingItem
+ * test if aItem exists somewhere in lists of items
+ * This is a function used by PutDataInPreviousState to be sure an item was not deleted
+ * since an undo or redo.
+ * This could be possible:
+ * - if a call to SaveCopyInUndoList was forgotten in Pcbnew
+ * - in zones outlines, when a change in one zone merges this zone with an other
+ * This function avoids a Pcbnew crash
+ * Before using this function to test existence of items,
+ * it must be called with aItem = NULL to prepare the list
+ * @param aPcb = board to test
+ * @param aItem = item to find
+ * = NULL to build the list of existing items
+ */
+static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem )
+{
+ static std::vector<BOARD_ITEM*> itemsList;
+
+ if( aItem == NULL ) // Build list
+ {
+ // Count items to store in itemsList:
+ int icnt = 0;
+ BOARD_ITEM* item;
+
+ // Count tracks:
+ for( item = aPcb->m_Track; item != NULL; item = item->Next() )
+ icnt++;
+
+ // Count modules:
+ for( item = aPcb->m_Modules; item != NULL; item = item->Next() )
+ icnt++;
+
+ // Count drawings
+ for( item = aPcb->m_Drawings; item != NULL; item = item->Next() )
+ icnt++;
+
+ // Count zones outlines
+ icnt += aPcb->GetAreaCount();
+
+ // Count zones segm (now obsolete):
+ for( item = aPcb->m_Zone; item != NULL; item = item->Next() )
+ icnt++;
+
+ // Build candidate list:
+ itemsList.clear();
+ itemsList.reserve(icnt);
+
+ // Store items in list:
+ // Append tracks:
+ for( item = aPcb->m_Track; item != NULL; item = item->Next() )
+ itemsList.push_back( item );
+
+ // Append modules:
+ for( item = aPcb->m_Modules; item != NULL; item = item->Next() )
+ itemsList.push_back( item );
+
+ // Append drawings
+ for( item = aPcb->m_Drawings; item != NULL; item = item->Next() )
+ itemsList.push_back( item );
+
+ // Append zones outlines
+ for( int ii = 0; ii < aPcb->GetAreaCount(); ii++ )
+ itemsList.push_back( aPcb->GetArea( ii ) );
+
+ // Append zones segm:
+ for( item = aPcb->m_Zone; item != NULL; item = item->Next() )
+ itemsList.push_back( item );
+
+ // Sort list
+ std::sort( itemsList.begin(), itemsList.end() );
+ return false;
+ }
+
+ // search in list:
+ return std::binary_search( itemsList.begin(), itemsList.end(), aItem );
+}
+
+
+void BOARD_ITEM::SwapData( BOARD_ITEM* aImage )
+{
+ if( aImage == NULL )
+ return;
+
+ // Remark: to create images of edited items to undo, we are using Clone method
+ // which can duplication of items foe copy, but does not clone all members
+ // mainly pointers in chain and time stamp, which is set to new, unique value.
+ // So we have to use the current values of these parameters.
+
+ EDA_ITEM * pnext = Next();
+ EDA_ITEM * pback = Back();
+ DHEAD* mylist = m_List;
+ time_t timestamp = GetTimeStamp();
+
+ switch( Type() )
+ {
+ case PCB_MODULE_T:
+ {
+ MODULE* tmp = (MODULE*) aImage->Clone();
+ ( (MODULE*) aImage )->Copy( (MODULE*) this );
+ ( (MODULE*) this )->Copy( tmp );
+ delete tmp;
+ }
+ break;
+
+ case PCB_ZONE_AREA_T:
+ {
+ ZONE_CONTAINER* tmp = (ZONE_CONTAINER*) aImage->Clone();
+ ( (ZONE_CONTAINER*) aImage )->Copy( (ZONE_CONTAINER*) this );
+ ( (ZONE_CONTAINER*) this )->Copy( tmp );
+ delete tmp;
+ }
+ break;
+
+ case PCB_LINE_T:
+ std::swap( *((DRAWSEGMENT*)this), *((DRAWSEGMENT*)aImage) );
+ break;
+
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ {
+ TRACK* track = (TRACK*) this;
+ TRACK* image = (TRACK*) aImage;
+
+ std::swap(track->m_Layer, image->m_Layer );
+
+ // swap start, end, width and shape for track and image.
+ wxPoint exchp = track->GetStart();
+ track->SetStart( image->GetStart() );
+ image->SetStart( exchp );
+ exchp = track->GetEnd();
+ track->SetEnd( image->GetEnd() );
+ image->SetEnd( exchp );
+
+ int atmp = track->GetWidth();
+ track->SetWidth( image->GetWidth() );
+ image->SetWidth( atmp );
+
+ if( Type() == PCB_VIA_T )
+ {
+ VIA *via = static_cast<VIA*>( this );
+ VIA *viaimage = static_cast<VIA*>( aImage );
+
+ VIATYPE_T viatmp = via->GetViaType();
+ via->SetViaType( viaimage->GetViaType() );
+ viaimage->SetViaType( viatmp );
+
+ int drilltmp = via->GetDrillValue();
+
+ if( via->IsDrillDefault() )
+ drilltmp = -1;
+
+ int itmp = viaimage->GetDrillValue();
+
+ if( viaimage->IsDrillDefault() )
+ itmp = -1;
+
+ std::swap(itmp, drilltmp );
+
+ if( drilltmp > 0 )
+ via->SetDrill( drilltmp );
+ else
+ via->SetDrillDefault();
+
+ if( itmp > 0 )
+ viaimage->SetDrill( itmp );
+ else
+ viaimage->SetDrillDefault();
+ }
+ }
+ break;
+
+ case PCB_TEXT_T:
+ std::swap( *((TEXTE_PCB*)this), *((TEXTE_PCB*)aImage) );
+ break;
+
+ case PCB_TARGET_T:
+ std::swap( *((PCB_TARGET*)this), *((PCB_TARGET*)aImage) );
+ break;
+
+ case PCB_DIMENSION_T:
+ std::swap( *((DIMENSION*)this), *((DIMENSION*)aImage) );
+ break;
+
+ case PCB_ZONE_T:
+ default:
+ wxLogMessage( wxT( "SwapData() error: unexpected type %d" ), Type() );
+ break;
+ }
+
+ // Restore pointers and time stamp, to be sure they are not broken
+ Pnext = pnext;
+ Pback = pback;
+ m_List = mylist;
+ SetTimeStamp( timestamp );
+}
+
+
+void PCB_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem,
+ UNDO_REDO_T aCommandType,
+ const wxPoint& aTransformPoint )
+{
+ if( aItem == NULL ) // Nothing to save
+ return;
+
+ // For texts belonging to modules, we need to save state of the parent module
+ if( aItem->Type() == PCB_MODULE_TEXT_T )
+ {
+ aItem = aItem->GetParent();
+
+ if( aItem == NULL )
+ return;
+
+ wxASSERT( aItem->Type() == PCB_MODULE_T );
+ aCommandType = UR_CHANGED;
+ }
+
+ PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
+
+ commandToUndo->m_TransformPoint = aTransformPoint;
+
+ ITEM_PICKER itemWrapper( aItem, aCommandType );
+
+ switch( aCommandType )
+ {
+ case UR_CHANGED: // Create a copy of item
+ if( itemWrapper.GetLink() == NULL ) // When not null, the copy is already done
+ itemWrapper.SetLink( aItem->Clone() );
+ commandToUndo->PushItem( itemWrapper );
+ break;
+
+ case UR_NEW:
+ case UR_DELETED:
+#ifdef USE_WX_OVERLAY
+ // Avoid to redraw when autoplacing
+ if( aItem->Type() == PCB_MODULE_T )
+ if( ((MODULE*)aItem)->GetFlags() & MODULE_to_PLACE )
+ break;
+ m_canvas->Refresh();
+#endif
+ case UR_MOVED:
+ case UR_FLIPPED:
+ case UR_ROTATED:
+ case UR_ROTATED_CLOCKWISE:
+ commandToUndo->PushItem( itemWrapper );
+ break;
+
+ default:
+ {
+ wxString msg;
+ msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), aCommandType );
+ wxMessageBox( msg );
+ }
+ break;
+ }
+
+ if( commandToUndo->GetCount() )
+ {
+ /* Save the copy in undo list */
+ GetScreen()->PushCommandToUndoList( commandToUndo );
+
+ /* Clear redo list, because after new save there is no redo to do */
+ GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
+ }
+ else
+ {
+ delete commandToUndo;
+ }
+}
+
+
+void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
+ UNDO_REDO_T aTypeCommand,
+ const wxPoint& aTransformPoint )
+{
+ PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
+
+ commandToUndo->m_TransformPoint = aTransformPoint;
+
+ // Copy picker list:
+ commandToUndo->CopyList( aItemsList );
+
+ // Verify list, and creates data if needed
+ for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ )
+ {
+ BOARD_ITEM* item = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii );
+
+ // For texts belonging to modules, we need to save state of the parent module
+ if( item->Type() == PCB_MODULE_TEXT_T || item->Type() == PCB_PAD_T )
+ {
+ item = item->GetParent();
+
+ if( item == NULL )
+ continue;
+
+ wxASSERT( item->Type() == PCB_MODULE_T );
+
+ commandToUndo->SetPickedItem( item, ii );
+ commandToUndo->SetPickedItemStatus( UR_CHANGED, ii );
+ }
+
+ UNDO_REDO_T command = commandToUndo->GetPickedItemStatus( ii );
+
+ if( command == UR_UNSPECIFIED )
+ {
+ command = aTypeCommand;
+ commandToUndo->SetPickedItemStatus( command, ii );
+ }
+
+ wxASSERT( item );
+
+ switch( command )
+ {
+ case UR_CHANGED:
+
+ /* If needed, create a copy of item, and put in undo list
+ * in the picker, as link
+ * If this link is not null, the copy is already done
+ */
+ if( commandToUndo->GetPickedItemLink( ii ) == NULL )
+ commandToUndo->SetPickedItemLink( item->Clone(), ii );
+ break;
+
+ case UR_MOVED:
+ case UR_ROTATED:
+ case UR_ROTATED_CLOCKWISE:
+ case UR_FLIPPED:
+ case UR_NEW:
+ case UR_DELETED:
+ break;
+
+ default:
+ {
+ wxString msg;
+ msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), command );
+ wxMessageBox( msg );
+ }
+
+ break;
+
+ }
+ }
+
+ if( commandToUndo->GetCount() )
+ {
+ /* Save the copy in undo list */
+ GetScreen()->PushCommandToUndoList( commandToUndo );
+
+ /* Clear redo list, because after a new command one cannot redo a command */
+ GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
+ }
+ else // Should not occur
+ {
+ delete commandToUndo;
+ }
+}
+
+
+void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRedoCommand,
+ bool aRebuildRatsnet )
+{
+ BOARD_ITEM* item;
+ bool not_found = false;
+ bool reBuild_ratsnest = false;
+ KIGFX::VIEW* view = GetGalCanvas()->GetView();
+ RN_DATA* ratsnest = GetBoard()->GetRatsnest();
+
+ // Undo in the reverse order of list creation: (this can allow stacked changes
+ // like the same item can be changes and deleted in the same complex command
+
+ bool build_item_list = true; // if true the list of existing items must be rebuilt
+
+ for( int ii = aList->GetCount() - 1; ii >= 0 ; ii-- )
+ {
+ item = (BOARD_ITEM*) aList->GetPickedItem( ii );
+ wxASSERT( item );
+
+ /* Test for existence of item on board.
+ * It could be deleted, and no more on board:
+ * - if a call to SaveCopyInUndoList was forgotten in Pcbnew
+ * - in zones outlines, when a change in one zone merges this zone with an other
+ * This test avoids a Pcbnew crash
+ * Obviously, this test is not made for deleted items
+ */
+ UNDO_REDO_T status = aList->GetPickedItemStatus( ii );
+
+ if( status != UR_DELETED )
+ {
+ if( build_item_list )
+ // Build list of existing items, for integrity test
+ TestForExistingItem( GetBoard(), NULL );
+
+ build_item_list = false;
+
+ if( !TestForExistingItem( GetBoard(), item ) )
+ {
+ // Remove this non existent item
+ aList->RemovePicker( ii );
+ ii++; // the current item was removed, ii points now the next item
+ // decrement it because it will be incremented later
+ not_found = true;
+ continue;
+ }
+ }
+
+ item->ClearFlags();
+
+ // see if we must rebuild ratsnets and pointers lists
+ switch( item->Type() )
+ {
+ case PCB_MODULE_T:
+ case PCB_ZONE_AREA_T:
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ reBuild_ratsnest = true;
+ break;
+
+ default:
+ break;
+ }
+
+ switch( aList->GetPickedItemStatus( ii ) )
+ {
+ case UR_CHANGED: /* Exchange old and new data for each item */
+ {
+ BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii );
+
+ // Remove all pads/drawings/texts, as they become invalid
+ // for the VIEW after SwapData() called for modules
+ if( item->Type() == PCB_MODULE_T )
+ {
+ MODULE* oldModule = static_cast<MODULE*>( item );
+ oldModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
+ }
+ view->Remove( item );
+ ratsnest->Remove( item );
+
+ item->SwapData( image );
+
+ // Update all pads/drawings/texts, as they become invalid
+ // for the VIEW after SwapData() called for modules
+ if( item->Type() == PCB_MODULE_T )
+ {
+ MODULE* newModule = static_cast<MODULE*>( item );
+ newModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
+ }
+ view->Add( item );
+ ratsnest->Add( item );
+
+ item->ClearFlags( SELECTED );
+ item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS );
+ }
+ break;
+
+ case UR_NEW: /* new items are deleted */
+ aList->SetPickedItemStatus( UR_DELETED, ii );
+ GetBoard()->Remove( item );
+
+ if( item->Type() == PCB_MODULE_T )
+ {
+ MODULE* module = static_cast<MODULE*>( item );
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
+ }
+ view->Remove( item );
+
+ item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ break;
+
+ case UR_DELETED: /* deleted items are put in List, as new items */
+ aList->SetPickedItemStatus( UR_NEW, ii );
+ GetBoard()->Add( item );
+
+ if( item->Type() == PCB_MODULE_T )
+ {
+ MODULE* module = static_cast<MODULE*>( item );
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1) );
+ }
+ view->Add( item );
+
+ item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ build_item_list = true;
+ break;
+
+ case UR_MOVED:
+ item->Move( aRedoCommand ? aList->m_TransformPoint : -aList->m_TransformPoint );
+ item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ ratsnest->Update( item );
+ break;
+
+ case UR_ROTATED:
+ item->Rotate( aList->m_TransformPoint,
+ aRedoCommand ? m_rotationAngle : -m_rotationAngle );
+ item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ ratsnest->Update( item );
+ break;
+
+ case UR_ROTATED_CLOCKWISE:
+ item->Rotate( aList->m_TransformPoint,
+ aRedoCommand ? -m_rotationAngle : m_rotationAngle );
+ item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ ratsnest->Update( item );
+ break;
+
+ case UR_FLIPPED:
+ item->Flip( aList->m_TransformPoint );
+ item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS );
+ ratsnest->Update( item );
+ break;
+
+ default:
+ {
+ wxString msg;
+ msg.Printf( wxT( "PutDataInPreviousState() error (unknown code %X)" ),
+ aList->GetPickedItemStatus( ii ) );
+ wxMessageBox( msg );
+ }
+ break;
+ }
+ }
+
+ if( not_found )
+ wxMessageBox( wxT( "Incomplete undo/redo operation: some items not found" ) );
+
+ // Rebuild pointers and ratsnest that can be changed.
+ if( reBuild_ratsnest && aRebuildRatsnet )
+ {
+ if( IsGalCanvasActive() )
+ ratsnest->Recalculate();
+ else
+ Compile_Ratsnest( NULL, true );
+ }
+}
+
+
+void PCB_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent )
+{
+ if( UndoRedoBlocked() )
+ return;
+
+ if( GetScreen()->GetUndoCommandCount() <= 0 )
+ return;
+
+ // Inform tools that undo command was issued
+ TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
+ m_toolManager->ProcessEvent( event );
+
+ /* Get the old list */
+ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
+
+ /* Undo the command */
+ PutDataInPreviousState( List, false );
+
+ /* Put the old list in RedoList */
+ List->ReversePickersListOrder();
+ GetScreen()->PushCommandToRedoList( List );
+
+ OnModify();
+ m_canvas->Refresh();
+}
+
+
+void PCB_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent )
+{
+ if( UndoRedoBlocked() )
+ return;
+
+ if( GetScreen()->GetRedoCommandCount() == 0 )
+ return;
+
+ // Inform tools that redo command was issued
+ TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
+ m_toolManager->ProcessEvent( event );
+
+ /* Get the old list */
+ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromRedoList();
+
+ /* Redo the command: */
+ PutDataInPreviousState( List, true );
+
+ /* Put the old list in UndoList */
+ List->ReversePickersListOrder();
+ GetScreen()->PushCommandToUndoList( List );
+
+ OnModify();
+ m_canvas->Refresh();
+}
+
+
+void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount )
+{
+ if( aItemCount == 0 )
+ return;
+
+ unsigned icnt = aList.m_CommandsList.size();
+
+ if( aItemCount > 0 )
+ icnt = aItemCount;
+
+ for( unsigned ii = 0; ii < icnt; ii++ )
+ {
+ if( aList.m_CommandsList.size() == 0 )
+ break;
+
+ PICKED_ITEMS_LIST* curr_cmd = aList.m_CommandsList[0];
+ aList.m_CommandsList.erase( aList.m_CommandsList.begin() );
+
+ curr_cmd->ClearListAndDeleteItems();
+ delete curr_cmd; // Delete command
+ }
+}
diff --git a/pcbnew/build_BOM_from_board.cpp b/pcbnew/build_BOM_from_board.cpp
new file mode 100644
index 0000000..ade7ef2
--- /dev/null
+++ b/pcbnew/build_BOM_from_board.cpp
@@ -0,0 +1,187 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009-2014 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* build_BOM_from_board.cpp */
+
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <macros.h>
+#include <project.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <wx/listimpl.cpp>
+
+/* creates a BOM list rom board
+ * The format is:
+ * "Id";"Designator";"Package";"Number";"Designation";"Supplier and ref";
+ * 1;"P1";"DB25FC";1;"DB25FEMELLE";;;
+ * 2;"U9";"PGA120";1;"4003APG120";;;
+ * 3;"JP1";"pin_array_8x2";1;"CONN_8X2";;;
+ * 4;"RR1";"r_pack9";1;"9x1K";;;
+ * 5;"X1";"HC-18UH";1;"8MHz";;;
+ * 6;"U8";"24dip300";1;"EP600";;;
+ * 7;"U5";"32dip600";1;"628128";;;
+ * 8;"C2,C3";"C1";2;"47pF";;;
+ * 9;"U1";"20dip300";1;"74LS245";;;
+ * 10;"U3";"20dip300";1;"74LS541";;;
+ * 11;"U2";"20dip300";1;"74LS688";;;
+ * 12;"C1,C4,C5,C6";"CP6";4;"47uF";;;
+ */
+
+const wxString CsvFileExtension( wxT( "csv" ) ); // BOM file extension
+
+const wxString CsvFileWildcard( _( "Comma separated value files (*.csv)|*.csv" ) );
+
+
+class cmp
+{
+public:
+ wxString m_Ref;
+ wxString m_Val;
+ FPID m_fpid;
+ int m_Id;
+ int m_CmpCount;
+};
+WX_DECLARE_LIST( cmp, CmpList );
+
+WX_DEFINE_LIST( CmpList )
+
+void PCB_EDIT_FRAME::RecreateBOMFileFromBoard( wxCommandEvent& aEvent )
+{
+ wxFileName fn;
+ FILE* fp_bom;
+ MODULE* module = GetBoard()->m_Modules;
+ wxString msg;
+
+ if( module == NULL )
+ {
+ DisplayError( this, _( "Cannot export BOM: there are no footprints in the PCB" ) );
+ return;
+ }
+
+ /* Set the file extension: */
+ fn = GetBoard()->GetFileName();
+ fn.SetExt( CsvFileExtension );
+
+ wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
+
+ wxFileDialog dlg( this, _( "Save Bill of Materials" ), pro_dir,
+ fn.GetFullName(), CsvFileWildcard,
+ wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ fn = dlg.GetPath();
+
+ fp_bom = wxFopen( fn.GetFullPath(), wxT( "wt" ) );
+
+ if( fp_bom == NULL )
+ {
+ msg.Printf( _( "Unable to create file <%s>" ), GetChars( fn.GetFullPath() ) );
+ DisplayError( this, msg );
+ return;
+ }
+
+ // Write header:
+ msg = wxT( "\"" );
+ msg << _( "Id" ) << wxT( "\";\"" );
+ msg << _( "Designator" ) << wxT( "\";\"" );
+ msg << _( "Package" ) << wxT( "\";\"" );
+ msg << _( "Quantity" ) << wxT( "\";\"" );
+ msg << _( "Designation" ) << wxT( "\";\"" );
+ msg << _( "Supplier and ref" ) << wxT( "\";\n" );
+ fprintf( fp_bom, "%s", TO_UTF8( msg ) );
+
+ // Build list
+ CmpList list;
+ cmp* comp = NULL;
+ CmpList::iterator iter;
+ int i = 1;
+
+ while( module != NULL )
+ {
+ bool valExist = false;
+
+ // try to find component in existing list
+ for( iter = list.begin(); iter != list.end(); ++iter )
+ {
+ cmp* current = *iter;
+
+ if( (current->m_Val == module->GetValue()) && (current->m_fpid == module->GetFPID()) )
+ {
+ current->m_Ref.Append( wxT( ", " ), 1 );
+ current->m_Ref.Append( module->GetReference() );
+ current->m_CmpCount++;
+
+ valExist = true;
+ break;
+ }
+ }
+
+ // If component does not exist yet, create new one and append it to the list.
+ if( valExist == false )
+ {
+ comp = new cmp();
+ comp->m_Id = i++;
+ comp->m_Val = module->GetValue();
+ comp->m_Ref = module->GetReference();
+ comp->m_fpid = module->GetFPID();
+ comp->m_CmpCount = 1;
+ list.Append( comp );
+ }
+
+ // increment module
+ module = module->Next();
+ }
+
+ // Print list. Also delete temporary created objects.
+ for( size_t ii = list.GetCount(); ii > 0; ii-- )
+ {
+ cmp* current = *list.begin(); // Because the first object will be removed
+ // from list, all objects will be get here
+
+ msg.Empty();
+
+ msg << current->m_Id << wxT( ";\"" );
+ msg << current->m_Ref << wxT( "\";\"" );
+ msg << FROM_UTF8( current->m_fpid.GetFootprintName().c_str() ) << wxT( "\";" );
+ msg << current->m_CmpCount << wxT( ";\"" );
+ msg << current->m_Val << wxT( "\";;;\n" );
+ fprintf( fp_bom, "%s", TO_UTF8( msg ) );
+
+ // We do not need this object, now: remove it from list and delete it
+ list.DeleteObject( current );
+ delete (current);
+ }
+
+ fclose( fp_bom );
+}
diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp
new file mode 100644
index 0000000..a909050
--- /dev/null
+++ b/pcbnew/class_board.cpp
@@ -0,0 +1,2764 @@
+/**
+ * @file class_board.cpp
+ * @brief BOARD class functions.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <limits.h>
+#include <algorithm>
+
+#include <fctsys.h>
+#include <common.h>
+#include <kicad_string.h>
+#include <wxBasePcbFrame.h>
+#include <msgpanel.h>
+#include <pcb_netlist.h>
+#include <reporter.h>
+#include <base_units.h>
+#include <ratsnest_data.h>
+#include <ratsnest_viewitem.h>
+#include <worksheet_viewitem.h>
+
+#include <pcbnew.h>
+#include <colors_selection.h>
+#include <collectors.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_zone.h>
+#include <class_marker_pcb.h>
+#include <class_drawsegment.h>
+#include <class_pcb_text.h>
+#include <class_mire.h>
+#include <class_dimension.h>
+
+
+/* This is an odd place for this, but CvPcb won't link if it is
+ * in class_board_item.cpp like I first tried it.
+ */
+wxPoint BOARD_ITEM::ZeroOffset( 0, 0 );
+
+
+BOARD::BOARD() :
+ BOARD_ITEM( (BOARD_ITEM*) NULL, PCB_T ),
+ m_NetInfo( this ),
+ m_paper( PAGE_INFO::A4 )
+{
+ // we have not loaded a board yet, assume latest until then.
+ m_fileFormatVersionAtLoad = LEGACY_BOARD_FILE_VERSION;
+
+ m_Status_Pcb = 0; // Status word: bit 1 = calculate.
+ SetColorsSettings( &g_ColorsSettings );
+ m_nodeCount = 0; // Number of connected pads.
+ m_unconnectedNetCount = 0; // Number of unconnected nets.
+
+ m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the
+ // zone contour currently in progress
+
+ BuildListOfNets(); // prepare pad and netlist containers.
+
+ for( LAYER_NUM layer = 0; layer < LAYER_ID_COUNT; ++layer )
+ {
+ m_Layer[layer].m_name = GetStandardLayerName( ToLAYER_ID( layer ) );
+
+ if( IsCopperLayer( layer ) )
+ m_Layer[layer].m_type = LT_SIGNAL;
+ else
+ m_Layer[layer].m_type = LT_UNDEFINED;
+ }
+
+ // Initialize default netclass.
+ NETCLASSPTR defaultClass = m_designSettings.GetDefault();
+ defaultClass->SetDescription( _( "This is the default net class." ) );
+ m_designSettings.SetCurrentNetClass( defaultClass->GetName() );
+
+ // Set sensible initial values for custom track width & via size
+ m_designSettings.UseCustomTrackViaSize( false );
+ m_designSettings.SetCustomTrackWidth( m_designSettings.GetCurrentTrackWidth() );
+ m_designSettings.SetCustomViaSize( m_designSettings.GetCurrentViaSize() );
+ m_designSettings.SetCustomViaDrill( m_designSettings.GetCurrentViaDrill() );
+
+ // Initialize ratsnest
+ m_ratsnest = new RN_DATA( this );
+}
+
+
+BOARD::~BOARD()
+{
+ while( m_ZoneDescriptorList.size() )
+ {
+ ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0];
+ Delete( area_to_remove );
+ }
+
+ delete m_ratsnest;
+
+ m_FullRatsnest.clear();
+ m_LocalRatsnest.clear();
+
+ DeleteMARKERs();
+ DeleteZONEOutlines();
+
+ delete m_CurrentZoneContour;
+ m_CurrentZoneContour = NULL;
+}
+
+
+const wxPoint& BOARD::GetPosition() const
+{
+ wxLogWarning( wxT( "This should not be called on the BOARD object") );
+
+ return ZeroOffset;
+}
+
+void BOARD::SetPosition( const wxPoint& aPos )
+{
+ wxLogWarning( wxT( "This should not be called on the BOARD object") );
+}
+
+
+void BOARD::Move( const wxPoint& aMoveVector ) // overload
+{
+ // Implement 'interface INSPECTOR' which is only INSPECTOR::Inspect(),
+ // here it does the moving.
+ struct MOVER : public INSPECTOR
+ {
+ SEARCH_RESULT Inspect( EDA_ITEM* item, const void* data )
+ {
+ BOARD_ITEM* brd_item = (BOARD_ITEM*) item;
+ const wxPoint* vector = (const wxPoint*) data;
+
+ brd_item->Move( *vector );
+
+ return SEARCH_CONTINUE;
+ }
+ } inspector;
+
+ // @todo : anything like this elsewhere? maybe put into GENERAL_COLLECTOR class.
+ static const KICAD_T top_level_board_stuff[] = {
+ PCB_MARKER_T,
+ PCB_TEXT_T,
+ PCB_LINE_T,
+ PCB_DIMENSION_T,
+ PCB_TARGET_T,
+ PCB_VIA_T,
+ PCB_TRACE_T,
+ // PCB_PAD_T, Can't be at board level
+ // PCB_MODULE_TEXT_T, Can't be at board level
+ PCB_MODULE_T,
+ PCB_ZONE_AREA_T,
+ EOT
+ };
+
+ // visit this BOARD with the above inspector, which moves all items.
+ Visit( &inspector, &aMoveVector, top_level_board_stuff );
+}
+
+
+void BOARD::chainMarkedSegments( wxPoint aPosition, const LSET& aLayerMask, TRACK_PTRS* aList )
+{
+ TRACK* segment; // The current segment being analyzed.
+ TRACK* via; // The via identified, eventually destroy
+ TRACK* candidate; // The end segment to destroy (or NULL = segment)
+ int NbSegm;
+ LSET layer_set = aLayerMask;
+
+ if( !m_Track )
+ return;
+
+ /* Set the BUSY flag of all connected segments, first search starting at
+ * aPosition. The search ends when a pad is found (end of a track), a
+ * segment end has more than one other segment end connected, or when no
+ * connected item found.
+ *
+ * Vias are a special case because they must look for segments connected
+ * on other layers and they change the layer mask. They can be a track
+ * end or not. They will be analyzer later and vias on terminal points
+ * of the track will be considered as part of this track if they do not
+ * connect segments of another track together and will be considered as
+ * part of an other track when removing the via, the segments of that other
+ * track are disconnected.
+ */
+ for( ; ; )
+ {
+ if( GetPad( aPosition, layer_set ) != NULL )
+ return;
+
+ /* Test for a via: a via changes the layer mask and can connect a lot
+ * of segments at location aPosition. When found, the via is just
+ * pushed in list. Vias will be examined later, when all connected
+ * segment are found and push in list. This is because when a via
+ * is found we do not know at this time the number of connected items
+ * and we do not know if this via is on the track or finish the track
+ */
+ via = m_Track->GetVia( NULL, aPosition, layer_set );
+
+ if( via )
+ {
+ layer_set = via->GetLayerSet();
+
+ aList->push_back( via );
+ }
+
+ /* Now we search all segments connected to point aPosition
+ * if only 1 segment: this segment is candidate
+ * if > 1 segment:
+ * end of track (more than 2 segment connected at this location)
+ */
+ segment = m_Track;
+ candidate = NULL;
+ NbSegm = 0;
+
+ while( ( segment = ::GetTrack( segment, NULL, aPosition, layer_set ) ) != NULL )
+ {
+ if( segment->GetState( BUSY ) ) // already found and selected: skip it
+ {
+ segment = segment->Next();
+ continue;
+ }
+
+ if( segment == via ) // just previously found: skip it
+ {
+ segment = segment->Next();
+ continue;
+ }
+
+ NbSegm++;
+
+ if( NbSegm == 1 ) // First time we found a connected item: segment is candidate
+ {
+ candidate = segment;
+ segment = segment->Next();
+ }
+ else // More than 1 segment connected -> this location is an end of the track
+ {
+ return;
+ }
+ }
+
+ if( candidate ) // A candidate is found: flag it and push it in list
+ {
+ /* Initialize parameters to search items connected to this
+ * candidate:
+ * we must analyze connections to its other end
+ */
+ if( aPosition == candidate->GetStart() )
+ {
+ aPosition = candidate->GetEnd();
+ }
+ else
+ {
+ aPosition = candidate->GetStart();
+ }
+
+ layer_set = candidate->GetLayerSet();
+
+ // flag this item and push it in list of selected items
+ aList->push_back( candidate );
+ candidate->SetState( BUSY, true );
+ }
+ else
+ {
+ return;
+ }
+ }
+}
+
+
+void BOARD::PushHighLight()
+{
+ m_highLightPrevious = m_highLight;
+}
+
+
+void BOARD::PopHighLight()
+{
+ m_highLight = m_highLightPrevious;
+ m_highLightPrevious.Clear();
+}
+
+
+bool BOARD::SetLayerDescr( LAYER_ID aIndex, const LAYER& aLayer )
+{
+ if( unsigned( aIndex ) < DIM( m_Layer ) )
+ {
+ m_Layer[ aIndex ] = aLayer;
+ return true;
+ }
+
+ return false;
+}
+
+#include <stdio.h>
+
+const LAYER_ID BOARD::GetLayerID( const wxString& aLayerName ) const
+{
+
+ // Look for the BOARD specific copper layer names
+ for( LAYER_NUM layer = 0; layer < LAYER_ID_COUNT; ++layer )
+ {
+ if ( IsCopperLayer( layer ) && ( m_Layer[ layer ].m_name == aLayerName ) )
+ {
+ return ToLAYER_ID( layer );
+ }
+ }
+
+ // Otherwise fall back to the system standard layer names
+ for( LAYER_NUM layer = 0; layer < LAYER_ID_COUNT; ++layer )
+ {
+ if( GetStandardLayerName( ToLAYER_ID( layer ) ) == aLayerName )
+ {
+ return ToLAYER_ID( layer );
+ }
+ }
+
+ return UNDEFINED_LAYER;
+}
+
+const wxString BOARD::GetLayerName( LAYER_ID aLayer ) const
+{
+ // All layer names are stored in the BOARD.
+ if( IsLayerEnabled( aLayer ) )
+ {
+ // Standard names were set in BOARD::BOARD() but they may be
+ // over-ridden by BOARD::SetLayerName().
+ // For copper layers, return the actual copper layer name,
+ // otherwise return the Standard English layer name.
+ if( IsCopperLayer( aLayer ) )
+ return m_Layer[aLayer].m_name;
+ }
+
+ return GetStandardLayerName( aLayer );
+}
+
+bool BOARD::SetLayerName( LAYER_ID aLayer, const wxString& aLayerName )
+{
+ if( !IsCopperLayer( aLayer ) )
+ return false;
+
+ if( aLayerName == wxEmptyString || aLayerName.Len() > 20 )
+ return false;
+
+ // no quote chars in the name allowed
+ if( aLayerName.Find( wxChar( '"' ) ) != wxNOT_FOUND )
+ return false;
+
+ wxString nameTemp = aLayerName;
+
+ // replace any spaces with underscores before we do any comparing
+ nameTemp.Replace( wxT( " " ), wxT( "_" ) );
+
+ if( IsLayerEnabled( aLayer ) )
+ {
+#if 0
+ for( LAYER_NUM i = FIRST_COPPER_LAYER; i < NB_COPPER_LAYERS; ++i )
+ {
+ if( i != aLayer && IsLayerEnabled( i ) && nameTemp == m_Layer[i].m_Name )
+ return false;
+ }
+#else
+ for( LSEQ cu = GetEnabledLayers().CuStack(); cu; ++cu )
+ {
+ LAYER_ID id = *cu;
+
+ // veto changing the name if it exists elsewhere.
+ if( id != aLayer && nameTemp == m_Layer[id].m_name )
+// if( id != aLayer && nameTemp == wxString( m_Layer[id].m_name ) )
+ return false;
+ }
+#endif
+
+ m_Layer[aLayer].m_name = nameTemp;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+LAYER_T BOARD::GetLayerType( LAYER_ID aLayer ) const
+{
+ if( !IsCopperLayer( aLayer ) )
+ return LT_SIGNAL;
+
+ //@@IMB: The original test was broken due to the discontinuity
+ // in the layer sequence.
+ if( IsLayerEnabled( aLayer ) )
+ return m_Layer[aLayer].m_type;
+
+ return LT_SIGNAL;
+}
+
+
+bool BOARD::SetLayerType( LAYER_ID aLayer, LAYER_T aLayerType )
+{
+ if( !IsCopperLayer( aLayer ) )
+ return false;
+
+ //@@IMB: The original test was broken due to the discontinuity
+ // in the layer sequence.
+ if( IsLayerEnabled( aLayer ) )
+ {
+ m_Layer[aLayer].m_type = aLayerType;
+ return true;
+ }
+
+ return false;
+}
+
+
+const char* LAYER::ShowType( LAYER_T aType )
+{
+ const char* cp;
+
+ switch( aType )
+ {
+ default:
+ case LT_SIGNAL:
+ cp = "signal";
+ break;
+
+ case LT_POWER:
+ cp = "power";
+ break;
+
+ case LT_MIXED:
+ cp = "mixed";
+ break;
+
+ case LT_JUMPER:
+ cp = "jumper";
+ break;
+ }
+
+ return cp;
+}
+
+
+LAYER_T LAYER::ParseType( const char* aType )
+{
+ if( strcmp( aType, "signal" ) == 0 )
+ return LT_SIGNAL;
+ else if( strcmp( aType, "power" ) == 0 )
+ return LT_POWER;
+ else if( strcmp( aType, "mixed" ) == 0 )
+ return LT_MIXED;
+ else if( strcmp( aType, "jumper" ) == 0 )
+ return LT_JUMPER;
+ else
+ return LT_UNDEFINED;
+}
+
+
+int BOARD::GetCopperLayerCount() const
+{
+ return m_designSettings.GetCopperLayerCount();
+}
+
+
+void BOARD::SetCopperLayerCount( int aCount )
+{
+ m_designSettings.SetCopperLayerCount( aCount );
+}
+
+
+LSET BOARD::GetEnabledLayers() const
+{
+ return m_designSettings.GetEnabledLayers();
+}
+
+
+LSET BOARD::GetVisibleLayers() const
+{
+ return m_designSettings.GetVisibleLayers();
+}
+
+
+void BOARD::SetEnabledLayers( LSET aLayerMask )
+{
+ m_designSettings.SetEnabledLayers( aLayerMask );
+}
+
+
+void BOARD::SetVisibleLayers( LSET aLayerMask )
+{
+ m_designSettings.SetVisibleLayers( aLayerMask );
+}
+
+
+void BOARD::SetVisibleElements( int aMask )
+{
+ // Call SetElementVisibility for each item
+ // to ensure specific calculations that can be needed by some items,
+ // just changing the visibility flags could be not sufficient.
+ for( int ii = 0; ii < PCB_VISIBLE( END_PCB_VISIBLE_LIST ); ii++ )
+ {
+ int item_mask = 1 << ii;
+ SetElementVisibility( ii, aMask & item_mask );
+ }
+}
+
+
+void BOARD::SetVisibleAlls()
+{
+ SetVisibleLayers( LSET().set() );
+
+ // Call SetElementVisibility for each item,
+ // to ensure specific calculations that can be needed by some items
+ for( int ii = 0; ii < PCB_VISIBLE(END_PCB_VISIBLE_LIST); ii++ )
+ SetElementVisibility( ii, true );
+}
+
+
+int BOARD::GetVisibleElements() const
+{
+ return m_designSettings.GetVisibleElements();
+}
+
+
+bool BOARD::IsElementVisible( int aPCB_VISIBLE ) const
+{
+ return m_designSettings.IsElementVisible( aPCB_VISIBLE );
+}
+
+
+void BOARD::SetElementVisibility( int aPCB_VISIBLE, bool isEnabled )
+{
+ m_designSettings.SetElementVisibility( aPCB_VISIBLE, isEnabled );
+
+ switch( aPCB_VISIBLE )
+ {
+ case RATSNEST_VISIBLE:
+
+ // we must clear or set the CH_VISIBLE flags to hide/show ratsnest
+ // because we have a tool to show/hide ratsnest relative to a pad or a module
+ // so the hide/show option is a per item selection
+ if( IsElementVisible( RATSNEST_VISIBLE ) )
+ {
+ for( unsigned ii = 0; ii < GetRatsnestsCount(); ii++ )
+ m_FullRatsnest[ii].m_Status |= CH_VISIBLE;
+ }
+ else
+ {
+ for( unsigned ii = 0; ii < GetRatsnestsCount(); ii++ )
+ m_FullRatsnest[ii].m_Status &= ~CH_VISIBLE;
+ }
+ break;
+
+ default:
+ ;
+ }
+}
+
+
+EDA_COLOR_T BOARD::GetVisibleElementColor( int aPCB_VISIBLE )
+{
+ EDA_COLOR_T color = UNSPECIFIED_COLOR;
+
+ switch( aPCB_VISIBLE )
+ {
+ case NON_PLATED_VISIBLE:
+ case VIA_THROUGH_VISIBLE:
+ case VIA_MICROVIA_VISIBLE:
+ case VIA_BBLIND_VISIBLE:
+ case MOD_TEXT_FR_VISIBLE:
+ case MOD_TEXT_BK_VISIBLE:
+ case MOD_TEXT_INVISIBLE:
+ case ANCHOR_VISIBLE:
+ case PAD_FR_VISIBLE:
+ case PAD_BK_VISIBLE:
+ case RATSNEST_VISIBLE:
+ case GRID_VISIBLE:
+ color = GetColorsSettings()->GetItemColor( aPCB_VISIBLE );
+ break;
+
+ default:
+ wxLogDebug( wxT( "BOARD::GetVisibleElementColor(): bad arg %d" ), aPCB_VISIBLE );
+ }
+
+ return color;
+}
+
+
+void BOARD::SetVisibleElementColor( int aPCB_VISIBLE, EDA_COLOR_T aColor )
+{
+ switch( aPCB_VISIBLE )
+ {
+ case NON_PLATED_VISIBLE:
+ case VIA_THROUGH_VISIBLE:
+ case VIA_MICROVIA_VISIBLE:
+ case VIA_BBLIND_VISIBLE:
+ case MOD_TEXT_FR_VISIBLE:
+ case MOD_TEXT_BK_VISIBLE:
+ case MOD_TEXT_INVISIBLE:
+ case ANCHOR_VISIBLE:
+ case PAD_FR_VISIBLE:
+ case PAD_BK_VISIBLE:
+ case GRID_VISIBLE:
+ case RATSNEST_VISIBLE:
+ GetColorsSettings()->SetItemColor( aPCB_VISIBLE, aColor );
+ break;
+
+ default:
+ wxLogDebug( wxT( "BOARD::SetVisibleElementColor(): bad arg %d" ), aPCB_VISIBLE );
+ }
+}
+
+
+void BOARD::SetLayerColor( LAYER_ID aLayer, EDA_COLOR_T aColor )
+{
+ GetColorsSettings()->SetLayerColor( aLayer, aColor );
+}
+
+
+EDA_COLOR_T BOARD::GetLayerColor( LAYER_ID aLayer ) const
+{
+ return GetColorsSettings()->GetLayerColor( aLayer );
+}
+
+
+bool BOARD::IsModuleLayerVisible( LAYER_ID layer )
+{
+ switch( layer )
+ {
+ case F_Cu:
+ return IsElementVisible( PCB_VISIBLE(MOD_FR_VISIBLE) );
+
+ case B_Cu:
+ return IsElementVisible( PCB_VISIBLE(MOD_BK_VISIBLE) );
+
+ default:
+ wxFAIL_MSG( wxT( "BOARD::IsModuleLayerVisible() param error: bad layer" ) );
+ return true;
+ }
+}
+
+
+void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
+{
+ if( aBoardItem == NULL )
+ {
+ wxFAIL_MSG( wxT( "BOARD::Add() param error: aBoardItem NULL" ) );
+ return;
+ }
+
+ switch( aBoardItem->Type() )
+ {
+ // this one uses a vector
+ case PCB_MARKER_T:
+ aBoardItem->SetParent( this );
+ m_markers.push_back( (MARKER_PCB*) aBoardItem );
+ break;
+
+ // this one uses a vector
+ case PCB_ZONE_AREA_T:
+ aBoardItem->SetParent( this );
+ m_ZoneDescriptorList.push_back( (ZONE_CONTAINER*) aBoardItem );
+ break;
+
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ if( aControl & ADD_APPEND )
+ {
+ m_Track.PushBack( (TRACK*) aBoardItem );
+ }
+ else
+ {
+ TRACK* insertAid;
+ insertAid = ( (TRACK*) aBoardItem )->GetBestInsertPoint( this );
+ m_Track.Insert( (TRACK*) aBoardItem, insertAid );
+ }
+
+ aBoardItem->SetParent( this );
+ break;
+
+ case PCB_ZONE_T:
+ if( aControl & ADD_APPEND )
+ m_Zone.PushBack( (SEGZONE*) aBoardItem );
+ else
+ m_Zone.PushFront( (SEGZONE*) aBoardItem );
+
+ aBoardItem->SetParent( this );
+ break;
+
+ case PCB_MODULE_T:
+ if( aControl & ADD_APPEND )
+ m_Modules.PushBack( (MODULE*) aBoardItem );
+ else
+ m_Modules.PushFront( (MODULE*) aBoardItem );
+
+ aBoardItem->SetParent( this );
+
+ // Because the list of pads has changed, reset the status
+ // This indicate the list of pad and nets must be recalculated before use
+ m_Status_Pcb = 0;
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ assert( false ); // TODO Orson: I am just checking if it is supposed to be here
+
+ case PCB_DIMENSION_T:
+ case PCB_LINE_T:
+ case PCB_TEXT_T:
+ case PCB_TARGET_T:
+ if( aControl & ADD_APPEND )
+ m_Drawings.PushBack( aBoardItem );
+ else
+ m_Drawings.PushFront( aBoardItem );
+
+ aBoardItem->SetParent( this );
+ break;
+
+ // other types may use linked list
+ default:
+ {
+ wxString msg;
+ msg.Printf( wxT( "BOARD::Add() needs work: BOARD_ITEM type (%d) not handled" ),
+ aBoardItem->Type() );
+ wxFAIL_MSG( msg );
+ }
+ break;
+ }
+
+ m_ratsnest->Add( aBoardItem );
+}
+
+
+BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem )
+{
+ // find these calls and fix them! Don't send me no stinking' NULL.
+ wxASSERT( aBoardItem );
+
+ switch( aBoardItem->Type() )
+ {
+ case PCB_MARKER_T:
+
+ // find the item in the vector, then remove it
+ for( unsigned i = 0; i<m_markers.size(); ++i )
+ {
+ if( m_markers[i] == (MARKER_PCB*) aBoardItem )
+ {
+ m_markers.erase( m_markers.begin() + i );
+ break;
+ }
+ }
+
+ break;
+
+ case PCB_ZONE_AREA_T: // this one uses a vector
+ // find the item in the vector, then delete then erase it.
+ for( unsigned i = 0; i<m_ZoneDescriptorList.size(); ++i )
+ {
+ if( m_ZoneDescriptorList[i] == (ZONE_CONTAINER*) aBoardItem )
+ {
+ m_ZoneDescriptorList.erase( m_ZoneDescriptorList.begin() + i );
+ break;
+ }
+ }
+
+ break;
+
+ case PCB_MODULE_T:
+ m_Modules.Remove( (MODULE*) aBoardItem );
+ break;
+
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ m_Track.Remove( (TRACK*) aBoardItem );
+ break;
+
+ case PCB_ZONE_T:
+ m_Zone.Remove( (SEGZONE*) aBoardItem );
+ break;
+
+ case PCB_DIMENSION_T:
+ case PCB_LINE_T:
+ case PCB_TEXT_T:
+ case PCB_MODULE_EDGE_T:
+ case PCB_TARGET_T:
+ m_Drawings.Remove( aBoardItem );
+ break;
+
+ // other types may use linked list
+ default:
+ wxFAIL_MSG( wxT( "BOARD::Remove() needs more ::Type() support" ) );
+ }
+
+ m_ratsnest->Remove( aBoardItem );
+
+ return aBoardItem;
+}
+
+
+void BOARD::DeleteMARKERs()
+{
+ // the vector does not know how to delete the MARKER_PCB, it holds pointers
+ for( unsigned i = 0; i<m_markers.size(); ++i )
+ delete m_markers[i];
+
+ m_markers.clear();
+}
+
+
+void BOARD::DeleteZONEOutlines()
+{
+ // the vector does not know how to delete the ZONE Outlines, it holds
+ // pointers
+ for( unsigned i = 0; i<m_ZoneDescriptorList.size(); ++i )
+ delete m_ZoneDescriptorList[i];
+
+ m_ZoneDescriptorList.clear();
+}
+
+
+int BOARD::GetNumSegmTrack() const
+{
+ return m_Track.GetCount();
+}
+
+
+int BOARD::GetNumSegmZone() const
+{
+ return m_Zone.GetCount();
+}
+
+
+unsigned BOARD::GetNodesCount() const
+{
+ return m_nodeCount;
+}
+
+
+EDA_RECT BOARD::ComputeBoundingBox( bool aBoardEdgesOnly )
+{
+ bool hasItems = false;
+ EDA_RECT area;
+
+ // Check segments, dimensions, texts, and fiducials
+ for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
+ {
+ if( aBoardEdgesOnly && (item->Type() != PCB_LINE_T || item->GetLayer() != Edge_Cuts ) )
+ continue;
+
+ if( !hasItems )
+ area = item->GetBoundingBox();
+ else
+ area.Merge( item->GetBoundingBox() );
+
+ hasItems = true;
+ }
+
+ if( !aBoardEdgesOnly )
+ {
+ // Check modules
+ for( MODULE* module = m_Modules; module; module = module->Next() )
+ {
+ if( !hasItems )
+ area = module->GetBoundingBox();
+ else
+ area.Merge( module->GetBoundingBox() );
+
+ hasItems = true;
+ }
+
+ // Check tracks
+ for( TRACK* track = m_Track; track; track = track->Next() )
+ {
+ if( !hasItems )
+ area = track->GetBoundingBox();
+ else
+ area.Merge( track->GetBoundingBox() );
+
+ hasItems = true;
+ }
+
+ // Check segment zones
+ for( TRACK* track = m_Zone; track; track = track->Next() )
+ {
+ if( !hasItems )
+ area = track->GetBoundingBox();
+ else
+ area.Merge( track->GetBoundingBox() );
+
+ hasItems = true;
+ }
+
+ // Check polygonal zones
+ for( unsigned int i = 0; i < m_ZoneDescriptorList.size(); i++ )
+ {
+ ZONE_CONTAINER* aZone = m_ZoneDescriptorList[i];
+
+ if( !hasItems )
+ area = aZone->GetBoundingBox();
+ else
+ area.Merge( aZone->GetBoundingBox() );
+
+ area.Merge( aZone->GetBoundingBox() );
+ hasItems = true;
+ }
+ }
+
+ m_BoundingBox = area; // save for BOARD::GetBoundingBox()
+
+ return area;
+}
+
+
+// virtual, see pcbstruct.h
+void BOARD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString txt;
+ int viasCount = 0;
+ int trackSegmentsCount = 0;
+
+ for( BOARD_ITEM* item = m_Track; item; item = item->Next() )
+ {
+ if( item->Type() == PCB_VIA_T )
+ viasCount++;
+ else
+ trackSegmentsCount++;
+ }
+
+ txt.Printf( wxT( "%d" ), GetPadCount() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Pads" ), txt, DARKGREEN ) );
+
+ txt.Printf( wxT( "%d" ), viasCount );
+ aList.push_back( MSG_PANEL_ITEM( _( "Vias" ), txt, DARKGREEN ) );
+
+ txt.Printf( wxT( "%d" ), trackSegmentsCount );
+ aList.push_back( MSG_PANEL_ITEM( _( "Track Segments" ), txt, DARKGREEN ) );
+
+ txt.Printf( wxT( "%d" ), GetNodesCount() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Nodes" ), txt, DARKCYAN ) );
+
+ txt.Printf( wxT( "%d" ), m_NetInfo.GetNetCount() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Nets" ), txt, RED ) );
+
+ /* These parameters are known only if the full ratsnest is available,
+ * so, display them only if this is the case
+ */
+ if( (m_Status_Pcb & NET_CODES_OK) )
+ {
+ txt.Printf( wxT( "%d" ), GetRatsnestsCount() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Links" ), txt, DARKGREEN ) );
+
+ txt.Printf( wxT( "%d" ), GetRatsnestsCount() - GetUnconnectedNetCount() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Connections" ), txt, DARKGREEN ) );
+
+ txt.Printf( wxT( "%d" ), GetUnconnectedNetCount() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Unconnected" ), txt, BLUE ) );
+ }
+}
+
+
+// virtual, see pcbstruct.h
+SEARCH_RESULT BOARD::Visit( INSPECTOR* inspector, const void* testData,
+ const KICAD_T scanTypes[] )
+{
+ KICAD_T stype;
+ SEARCH_RESULT result = SEARCH_CONTINUE;
+ const KICAD_T* p = scanTypes;
+ bool done = false;
+
+#if 0 && defined(DEBUG)
+ std::cout << GetClass().mb_str() << ' ';
+#endif
+
+ while( !done )
+ {
+ stype = *p;
+
+ switch( stype )
+ {
+ case PCB_T:
+ result = inspector->Inspect( this, testData ); // inspect me
+ // skip over any types handled in the above call.
+ ++p;
+ break;
+
+ /* Instances of the requested KICAD_T live in a list, either one
+ * that I manage, or that my modules manage. If it's a type managed
+ * by class MODULE, then simply pass it on to each module's
+ * MODULE::Visit() function by way of the
+ * IterateForward( m_Modules, ... ) call.
+ */
+
+ case PCB_MODULE_T:
+ case PCB_PAD_T:
+ case PCB_MODULE_TEXT_T:
+ case PCB_MODULE_EDGE_T:
+
+ // this calls MODULE::Visit() on each module.
+ result = IterateForward( m_Modules, inspector, testData, p );
+
+ // skip over any types handled in the above call.
+ for( ; ; )
+ {
+ switch( stype = *++p )
+ {
+ case PCB_MODULE_T:
+ case PCB_PAD_T:
+ case PCB_MODULE_TEXT_T:
+ case PCB_MODULE_EDGE_T:
+ continue;
+
+ default:
+ ;
+ }
+
+ break;
+ }
+
+ break;
+
+ case PCB_LINE_T:
+ case PCB_TEXT_T:
+ case PCB_DIMENSION_T:
+ case PCB_TARGET_T:
+ result = IterateForward( m_Drawings, inspector, testData, p );
+
+ // skip over any types handled in the above call.
+ for( ; ; )
+ {
+ switch( stype = *++p )
+ {
+ case PCB_LINE_T:
+ case PCB_TEXT_T:
+ case PCB_DIMENSION_T:
+ case PCB_TARGET_T:
+ continue;
+
+ default:
+ ;
+ }
+
+ break;
+ }
+
+ ;
+ break;
+
+#if 0 // both these are on same list, so we must scan it twice in order
+ // to get VIA priority, using new #else code below.
+ // But we are not using separate lists for TRACKs and VIA, because
+ // items are ordered (sorted) in the linked
+ // list by netcode AND by physical distance:
+ // when created, if a track or via is connected to an existing track or
+ // via, it is put in linked list after this existing track or via
+ // So usually, connected tracks or vias are grouped in this list
+ // So the algorithm (used in ratsnest computations) which computes the
+ // track connectivity is faster (more than 100 time regarding to
+ // a non ordered list) because when it searches for a connection, first
+ // it tests the near (near in term of linked list) 50 items
+ // from the current item (track or via) in test.
+ // Usually, because of this sort, a connected item (if exists) is
+ // found.
+ // If not found (and only in this case) an exhaustive (and time
+ // consuming) search is made, but this case is statistically rare.
+ case PCB_VIA_T:
+ case PCB_TRACE_T:
+ result = IterateForward( m_Track, inspector, testData, p );
+
+ // skip over any types handled in the above call.
+ for( ; ; )
+ {
+ switch( stype = *++p )
+ {
+ case PCB_VIA_T:
+ case PCB_TRACE_T:
+ continue;
+
+ default:
+ ;
+ }
+
+ break;
+ }
+
+ break;
+
+#else
+ case PCB_VIA_T:
+ result = IterateForward( m_Track, inspector, testData, p );
+ ++p;
+ break;
+
+ case PCB_TRACE_T:
+ result = IterateForward( m_Track, inspector, testData, p );
+ ++p;
+ break;
+#endif
+
+ case PCB_MARKER_T:
+
+ // MARKER_PCBS are in the m_markers std::vector
+ for( unsigned i = 0; i<m_markers.size(); ++i )
+ {
+ result = m_markers[i]->Visit( inspector, testData, p );
+
+ if( result == SEARCH_QUIT )
+ break;
+ }
+
+ ++p;
+ break;
+
+ case PCB_ZONE_AREA_T:
+
+ // PCB_ZONE_AREA_T are in the m_ZoneDescriptorList std::vector
+ for( unsigned i = 0; i< m_ZoneDescriptorList.size(); ++i )
+ {
+ result = m_ZoneDescriptorList[i]->Visit( inspector, testData, p );
+
+ if( result == SEARCH_QUIT )
+ break;
+ }
+
+ ++p;
+ break;
+
+ case PCB_ZONE_T:
+ result = IterateForward( m_Zone, inspector, testData, p );
+ ++p;
+ break;
+
+ default: // catch EOT or ANY OTHER type here and return.
+ done = true;
+ break;
+ }
+
+ if( result == SEARCH_QUIT )
+ break;
+ }
+
+ return result;
+}
+
+
+/* now using PcbGeneralLocateAndDisplay(), but this remains a useful example
+ * of how the INSPECTOR can be used in a lightweight way.
+ * // see pcbstruct.h
+ * BOARD_ITEM* BOARD::FindPadOrModule( const wxPoint& refPos, LAYER_NUM layer )
+ * {
+ * class PadOrModule : public INSPECTOR
+ * {
+ * public:
+ * BOARD_ITEM* found;
+ * LAYER_NUM layer;
+ * int layer_mask;
+ *
+ * PadOrModule( LAYER_NUM alayer ) :
+ * found(0), layer(alayer), layer_mask( g_TabOneLayerMask[alayer] )
+ * {}
+ *
+ * SEARCH_RESULT Inspect( EDA_ITEM* testItem, const void* testData
+ * )
+ * {
+ * BOARD_ITEM* item = (BOARD_ITEM*) testItem;
+ * const wxPoint& refPos = *(const wxPoint*) testData;
+ *
+ * if( item->Type() == PCB_PAD_T )
+ * {
+ * D_PAD* pad = (D_PAD*) item;
+ * if( pad->HitTest( refPos ) )
+ * {
+ * if( layer_mask & pad->GetLayerSet() )
+ * {
+ * found = item;
+ * return SEARCH_QUIT;
+ * }
+ * else if( !found )
+ * {
+ * MODULE* parent = (MODULE*) pad->m_Parent;
+ * if( IsModuleLayerVisible( parent->GetLayer() ) )
+ * found = item;
+ * }
+ * }
+ * }
+ *
+ * else if( item->Type() == PCB_MODULE_T )
+ * {
+ * MODULE* module = (MODULE*) item;
+ *
+ * // consider only visible modules
+ * if( IsModuleLayerVisible( module->GetLayer() ) )
+ * {
+ * if( module->HitTest( refPos ) )
+ * {
+ * if( layer == module->GetLayer() )
+ * {
+ * found = item;
+ * return SEARCH_QUIT;
+ * }
+ *
+ * // layer mismatch, save in case we don't find a
+ * // future layer match hit.
+ * if( !found )
+ * found = item;
+ * }
+ * }
+ * }
+ * return SEARCH_CONTINUE;
+ * }
+ * };
+ *
+ * PadOrModule inspector( layer );
+ *
+ * // search only for PADs first, then MODULES, and preferably a layer match
+ * static const KICAD_T scanTypes[] = { PCB_PAD_T, PCB_MODULE_T, EOT };
+ *
+ * // visit this BOARD with the above inspector
+ * Visit( &inspector, &refPos, scanTypes );
+ *
+ * return inspector.found;
+ * }
+ */
+
+
+NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
+{
+ // the first valid netcode is 1 and the last is m_NetInfo.GetCount()-1.
+ // zero is reserved for "no connection" and is not actually a net.
+ // NULL is returned for non valid netcodes
+
+ wxASSERT( m_NetInfo.GetNetCount() > 0 ); // net zero should exist
+
+ if( aNetcode == NETINFO_LIST::UNCONNECTED && m_NetInfo.GetNetCount() == 0 )
+ return &NETINFO_LIST::ORPHANED;
+ else
+ return m_NetInfo.GetNetItem( aNetcode );
+}
+
+
+NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
+{
+ return m_NetInfo.GetNetItem( aNetname );
+}
+
+
+MODULE* BOARD::FindModuleByReference( const wxString& aReference ) const
+{
+ struct FINDER : public INSPECTOR
+ {
+ MODULE* found;
+
+ FINDER() : found( 0 ) {}
+
+ // implement interface INSPECTOR
+ SEARCH_RESULT Inspect( EDA_ITEM* item, const void* data )
+ {
+ MODULE* module = (MODULE*) item;
+ const wxString& ref = *(const wxString*) data;
+
+ if( ref == module->GetReference() )
+ {
+ found = module;
+ return SEARCH_QUIT;
+ }
+
+ return SEARCH_CONTINUE;
+ }
+ } inspector;
+
+ // search only for MODULES
+ static const KICAD_T scanTypes[] = { PCB_MODULE_T, EOT };
+
+ // visit this BOARD with the above inspector
+ BOARD* nonconstMe = (BOARD*) this;
+ nonconstMe->Visit( &inspector, &aReference, scanTypes );
+
+ return inspector.found;
+}
+
+
+MODULE* BOARD::FindModule( const wxString& aRefOrTimeStamp, bool aSearchByTimeStamp ) const
+{
+ if( aSearchByTimeStamp )
+ {
+ for( MODULE* module = m_Modules; module; module = module->Next() )
+ {
+ if( aRefOrTimeStamp.CmpNoCase( module->GetPath() ) == 0 )
+ return module;
+ }
+ }
+ else
+ {
+
+#if 0 // case independent compare, why?
+ for( MODULE* module = m_Modules; module; module = module->Next() )
+ {
+ if( aRefOrTimeStamp.CmpNoCase( module->GetReference() ) == 0 )
+ return module;
+ }
+#else
+ return FindModuleByReference( aRefOrTimeStamp );
+#endif
+
+ }
+
+ return NULL;
+}
+
+
+// Sort nets by decreasing pad count. For same pad count, sort by alphabetic names
+static bool sortNetsByNodes( const NETINFO_ITEM* a, const NETINFO_ITEM* b )
+{
+ if( b->GetNodesCount() == a->GetNodesCount() )
+ return a->GetNetname() < b->GetNetname();
+
+ return b->GetNodesCount() < a->GetNodesCount();
+}
+
+// Sort nets by alphabetic names
+static bool sortNetsByNames( const NETINFO_ITEM* a, const NETINFO_ITEM* b )
+{
+ return a->GetNetname() < b->GetNetname();
+}
+
+int BOARD::SortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount )
+{
+ if( m_NetInfo.GetNetCount() == 0 )
+ return 0;
+
+ // Build the list
+ std::vector <NETINFO_ITEM*> netBuffer;
+
+ netBuffer.reserve( m_NetInfo.GetNetCount() );
+
+ for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
+ net != netEnd; ++net )
+ {
+ if( net->GetNet() > 0 )
+ netBuffer.push_back( *net );
+ }
+
+ // sort the list
+ if( aSortbyPadsCount )
+ sort( netBuffer.begin(), netBuffer.end(), sortNetsByNodes );
+ else
+ sort( netBuffer.begin(), netBuffer.end(), sortNetsByNames );
+
+ for( unsigned ii = 0; ii < netBuffer.size(); ii++ )
+ aNames.Add( netBuffer[ii]->GetNetname() );
+
+ return netBuffer.size();
+}
+
+
+void BOARD::RedrawAreasOutlines( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, LAYER_ID aLayer )
+{
+ if( !aDC )
+ return;
+
+ for( int ii = 0; ii < GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* edge_zone = GetArea( ii );
+
+ if( (aLayer < 0) || ( aLayer == edge_zone->GetLayer() ) )
+ edge_zone->Draw( panel, aDC, aDrawMode );
+ }
+}
+
+
+void BOARD::RedrawFilledAreas( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, LAYER_ID aLayer )
+{
+ if( !aDC )
+ return;
+
+ for( int ii = 0; ii < GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* edge_zone = GetArea( ii );
+
+ if( (aLayer < 0) || ( aLayer == edge_zone->GetLayer() ) )
+ edge_zone->DrawFilledArea( panel, aDC, aDrawMode );
+ }
+}
+
+
+ZONE_CONTAINER* BOARD::HitTestForAnyFilledArea( const wxPoint& aRefPos,
+ LAYER_ID aStartLayer, LAYER_ID aEndLayer, int aNetCode )
+{
+ if( aEndLayer < 0 )
+ aEndLayer = aStartLayer;
+
+ if( aEndLayer < aStartLayer )
+ std::swap( aEndLayer, aStartLayer );
+
+ for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
+ {
+ ZONE_CONTAINER* area = m_ZoneDescriptorList[ia];
+ LAYER_NUM layer = area->GetLayer();
+
+ if( layer < aStartLayer || layer > aEndLayer )
+ continue;
+
+ // In locate functions we must skip tagged items with BUSY flag set.
+ if( area->GetState( BUSY ) )
+ continue;
+
+ if( aNetCode >= 0 && area->GetNetCode() != aNetCode )
+ continue;
+
+ if( area->HitTestFilledArea( aRefPos ) )
+ return area;
+ }
+
+ return NULL;
+}
+
+
+int BOARD::SetAreasNetCodesFromNetNames()
+{
+ int error_count = 0;
+
+ for( int ii = 0; ii < GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* it = GetArea( ii );
+
+ if( !it->IsOnCopperLayer() )
+ {
+ it->SetNetCode( NETINFO_LIST::UNCONNECTED );
+ continue;
+ }
+
+ if( it->GetNetCode() != 0 ) // i.e. if this zone is connected to a net
+ {
+ const NETINFO_ITEM* net = it->GetNet();
+
+ if( net )
+ {
+ it->SetNetCode( net->GetNet() );
+ }
+ else
+ {
+ error_count++;
+
+ // keep Net Name and set m_NetCode to -1 : error flag.
+ it->SetNetCode( -1 );
+ }
+ }
+ }
+
+ return error_count;
+}
+
+
+VIA* BOARD::GetViaByPosition( const wxPoint& aPosition, LAYER_ID aLayer) const
+{
+ for( VIA *via = GetFirstVia( m_Track); via; via = GetFirstVia( via->Next() ) )
+ {
+ if( (via->GetStart() == aPosition) &&
+ (via->GetState( BUSY | IS_DELETED ) == 0) &&
+ ((aLayer == UNDEFINED_LAYER) || (via->IsOnLayer( aLayer ))) )
+ return via;
+ }
+
+ return NULL;
+}
+
+
+D_PAD* BOARD::GetPad( const wxPoint& aPosition, LSET aLayerMask )
+{
+ if( !aLayerMask.any() )
+ aLayerMask = LSET::AllCuMask();
+
+ for( MODULE* module = m_Modules; module; module = module->Next() )
+ {
+ D_PAD* pad = module->GetPad( aPosition, aLayerMask );
+
+ if( pad )
+ return pad;
+ }
+
+ return NULL;
+}
+
+
+D_PAD* BOARD::GetPad( TRACK* aTrace, ENDPOINT_T aEndPoint )
+{
+ const wxPoint& aPosition = aTrace->GetEndPoint( aEndPoint );
+
+ LSET aLayerMask( aTrace->GetLayer() );
+
+ for( MODULE* module = m_Modules; module; module = module->Next() )
+ {
+ D_PAD* pad = module->GetPad( aPosition, aLayerMask );
+
+ if( pad )
+ return pad;
+ }
+
+ return NULL;
+}
+
+
+D_PAD* BOARD::GetPadFast( const wxPoint& aPosition, LSET aLayerMask )
+{
+ for( unsigned i=0; i<GetPadCount(); ++i )
+ {
+ D_PAD* pad = m_NetInfo.GetPad(i);
+
+ if( pad->GetPosition() != aPosition )
+ continue;
+
+ // Pad found, it must be on the correct layer
+ if( ( pad->GetLayerSet() & aLayerMask ).any() )
+ return pad;
+ }
+
+ return NULL;
+}
+
+
+D_PAD* BOARD::GetPad( std::vector<D_PAD*>& aPadList, const wxPoint& aPosition, LSET aLayerMask )
+{
+ // Search the aPoint coordinates in aPadList
+ // aPadList is sorted by X then Y values, and a fast binary search is used
+ int idxmax = aPadList.size()-1;
+
+ int delta = aPadList.size();
+
+ int idx = 0; // Starting index is the beginning of list
+
+ while( delta )
+ {
+ // Calculate half size of remaining interval to test.
+ // Ensure the computed value is not truncated (too small)
+ if( (delta & 1) && ( delta > 1 ) )
+ delta++;
+
+ delta /= 2;
+
+ D_PAD* pad = aPadList[idx];
+
+ if( pad->GetPosition() == aPosition ) // candidate found
+ {
+ // The pad must match the layer mask:
+ if( ( aLayerMask & pad->GetLayerSet() ).any() )
+ return pad;
+
+ // More than one pad can be at aPosition
+ // search for a pad at aPosition that matched this mask
+
+ // search next
+ for( int ii = idx+1; ii <= idxmax; ii++ )
+ {
+ pad = aPadList[ii];
+
+ if( pad->GetPosition() != aPosition )
+ break;
+
+ if( (aLayerMask & pad->GetLayerSet()) != 0 )
+ return pad;
+ }
+ // search previous
+ for( int ii = idx-1 ;ii >=0; ii-- )
+ {
+ pad = aPadList[ii];
+
+ if( pad->GetPosition() != aPosition )
+ break;
+
+ if( (aLayerMask & pad->GetLayerSet()) != 0 )
+ return pad;
+ }
+
+ // Not found:
+ return 0;
+ }
+
+ if( pad->GetPosition().x == aPosition.x ) // Must search considering Y coordinate
+ {
+ if(pad->GetPosition().y < aPosition.y) // Must search after this item
+ {
+ idx += delta;
+
+ if( idx > idxmax )
+ idx = idxmax;
+ }
+ else // Must search before this item
+ {
+ idx -= delta;
+
+ if( idx < 0 )
+ idx = 0;
+ }
+ }
+ else if( pad->GetPosition().x < aPosition.x ) // Must search after this item
+ {
+ idx += delta;
+
+ if( idx > idxmax )
+ idx = idxmax;
+ }
+ else // Must search before this item
+ {
+ idx -= delta;
+
+ if( idx < 0 )
+ idx = 0;
+ }
+ }
+
+ return NULL;
+}
+
+
+/**
+ * Function SortPadsByXCoord
+ * is used by GetSortedPadListByXCoord to Sort a pad list by x coordinate value.
+ * This function is used to build ordered pads lists
+ */
+bool sortPadsByXthenYCoord( D_PAD* const & ref, D_PAD* const & comp )
+{
+ if( ref->GetPosition().x == comp->GetPosition().x )
+ return ref->GetPosition().y < comp->GetPosition().y;
+ return ref->GetPosition().x < comp->GetPosition().x;
+}
+
+
+void BOARD::GetSortedPadListByXthenYCoord( std::vector<D_PAD*>& aVector, int aNetCode )
+{
+ if( aNetCode < 0 )
+ {
+ aVector.insert( aVector.end(), m_NetInfo.m_PadsFullList.begin(),
+ m_NetInfo.m_PadsFullList.end() );
+ }
+ else
+ {
+ const NETINFO_ITEM* net = m_NetInfo.GetNetItem( aNetCode );
+ if( net )
+ {
+ aVector.insert( aVector.end(), net->m_PadInNetList.begin(),
+ net->m_PadInNetList.end() );
+ }
+ }
+
+ sort( aVector.begin(), aVector.end(), sortPadsByXthenYCoord );
+}
+
+
+void BOARD::PadDelete( D_PAD* aPad )
+{
+ m_NetInfo.DeletePad( aPad );
+
+ aPad->DeleteStructure();
+}
+
+
+TRACK* BOARD::GetTrack( TRACK* aTrace, const wxPoint& aPosition,
+ LSET aLayerMask ) const
+{
+ for( TRACK* track = aTrace; track; track = track->Next() )
+ {
+ LAYER_ID layer = track->GetLayer();
+
+ if( track->GetState( BUSY | IS_DELETED ) )
+ continue;
+
+ if( m_designSettings.IsLayerVisible( layer ) == false )
+ continue;
+
+ if( track->Type() == PCB_VIA_T ) // VIA encountered.
+ {
+ if( track->HitTest( aPosition ) )
+ return track;
+ }
+ else
+ {
+ if( !aLayerMask[layer] )
+ continue; // Segments on different layers.
+
+ if( track->HitTest( aPosition ) )
+ return track;
+ }
+ }
+
+ return NULL;
+}
+
+
+#if defined(DEBUG) && 0
+static void dump_tracks( const char* aName, const TRACK_PTRS& aList )
+{
+ printf( "%s: count=%zd\n", aName, aList.size() );
+
+ for( unsigned i = 0; i < aList.size(); ++i )
+ {
+ TRACK* seg = aList[i];
+ ::VIA* via = dynamic_cast< ::VIA* >( seg );
+
+ if( via )
+ printf( " via[%u]: (%d, %d)\n", i, via->GetStart().x, via->GetStart().y );
+ else
+ printf( " seg[%u]: (%d, %d) (%d, %d)\n", i,
+ seg->GetStart().x, seg->GetStart().y,
+ seg->GetEnd().x, seg->GetEnd().y );
+ }
+}
+#endif
+
+
+TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount,
+ double* aTraceLength, double* aPadToDieLength,
+ bool aReorder )
+{
+ int NbSegmBusy;
+ TRACK_PTRS trackList;
+
+ if( aCount )
+ *aCount = 0;
+
+ if( aTraceLength )
+ *aTraceLength = 0;
+
+ if( aTrace == NULL )
+ return NULL;
+
+ // Ensure the flag BUSY of all tracks of the board is cleared
+ // because we use it to mark segments of the track
+ for( TRACK* track = m_Track; track; track = track->Next() )
+ track->SetState( BUSY, false );
+
+ // Set flags of the initial track segment
+ aTrace->SetState( BUSY, true );
+ LSET layer_set = aTrace->GetLayerSet();
+
+ trackList.push_back( aTrace );
+
+ /* Examine the initial track segment : if it is really a segment, this is
+ * easy.
+ * If it is a via, one must search for connected segments.
+ * If <=2, this via connect 2 segments (or is connected to only one
+ * segment) and this via and these 2 segments are a part of a track.
+ * If > 2 only this via is flagged (the track has only this via)
+ */
+ if( aTrace->Type() == PCB_VIA_T )
+ {
+ TRACK* segm1 = ::GetTrack( m_Track, NULL, aTrace->GetStart(), layer_set );
+ TRACK* segm2 = NULL;
+ TRACK* segm3 = NULL;
+
+ if( segm1 )
+ {
+ segm2 = ::GetTrack( segm1->Next(), NULL, aTrace->GetStart(), layer_set );
+ }
+
+ if( segm2 )
+ {
+ segm3 = ::GetTrack( segm2->Next(), NULL, aTrace->GetStart(), layer_set );
+ }
+
+ if( segm3 )
+ {
+ // More than 2 segments are connected to this via.
+ // The "track" is only this via.
+
+ if( aCount )
+ *aCount = 1;
+
+ return aTrace;
+ }
+
+ if( segm1 ) // search for other segments connected to the initial segment start point
+ {
+ layer_set = segm1->GetLayerSet();
+ chainMarkedSegments( aTrace->GetStart(), layer_set, &trackList );
+ }
+
+ if( segm2 ) // search for other segments connected to the initial segment end point
+ {
+ layer_set = segm2->GetLayerSet();
+ chainMarkedSegments( aTrace->GetStart(), layer_set, &trackList );
+ }
+ }
+ else // mark the chain using both ends of the initial segment
+ {
+ TRACK_PTRS from_start;
+ TRACK_PTRS from_end;
+
+ chainMarkedSegments( aTrace->GetStart(), layer_set, &from_start );
+ chainMarkedSegments( aTrace->GetEnd(), layer_set, &from_end );
+
+ // DBG( dump_tracks( "first_clicked", trackList ); )
+ // DBG( dump_tracks( "from_start", from_start ); )
+ // DBG( dump_tracks( "from_end", from_end ); )
+
+ // combine into one trackList:
+ trackList.insert( trackList.end(), from_start.begin(), from_start.end() );
+ trackList.insert( trackList.end(), from_end.begin(), from_end.end() );
+ }
+
+ // Now examine selected vias and flag them if they are on the track
+ // If a via is connected to only one or 2 segments, it is flagged (is on the track)
+ // If a via is connected to more than 2 segments, it is a track end, and it
+ // is removed from the list.
+ // Go through the list backwards.
+ for( int i = trackList.size() - 1; i>=0; --i )
+ {
+ ::VIA* via = dynamic_cast< ::VIA* >( trackList[i] );
+
+ if( !via )
+ continue;
+
+ if( via == aTrace )
+ continue;
+
+ via->SetState( BUSY, true ); // Try to flag it. the flag will be cleared later if needed
+
+ layer_set = via->GetLayerSet();
+
+ TRACK* track = ::GetTrack( m_Track, NULL, via->GetStart(), layer_set );
+
+ // GetTrace does not consider tracks flagged BUSY.
+ // So if no connected track found, this via is on the current track
+ // only: keep it
+ if( track == NULL )
+ continue;
+
+ /* If a track is found, this via connects also other segments of
+ * another track. This case happens when a via ends the selected
+ * track but must we consider this via is on the selected track, or
+ * on another track.
+ * (this is important when selecting a track for deletion: must this
+ * via be deleted or not?)
+ * We consider this via to be on our track if other segments connected
+ * to this via remain connected when removing this via.
+ * We search for all other segments connected together:
+ * if they are on the same layer, then the via is on the selected track;
+ * if they are on different layers, the via is on another track.
+ */
+ LAYER_NUM layer = track->GetLayer();
+
+ while( ( track = ::GetTrack( track->Next(), NULL, via->GetStart(), layer_set ) ) != NULL )
+ {
+ if( layer != track->GetLayer() )
+ {
+ // The via connects segments of another track: it is removed
+ // from list because it is member of another track
+
+ DBG(printf( "%s: omit track (%d, %d) (%d, %d) on layer:%d (!= our_layer:%d)\n",
+ __func__,
+ track->GetStart().x, track->GetStart().y,
+ track->GetEnd().x, track->GetEnd().y,
+ track->GetLayer(), layer
+ ); )
+
+ via->SetState( BUSY, false );
+ break;
+ }
+ }
+ }
+
+ /* Rearrange the track list in order to have flagged segments linked
+ * from firstTrack so the NbSegmBusy segments are consecutive segments
+ * in list, the first item in the full track list is firstTrack, and
+ * the NbSegmBusy-1 next items (NbSegmBusy when including firstTrack)
+ * are the flagged segments
+ */
+ NbSegmBusy = 0;
+ TRACK* firstTrack;
+
+ for( firstTrack = m_Track; firstTrack; firstTrack = firstTrack->Next() )
+ {
+ // Search for the first flagged BUSY segments
+ if( firstTrack->GetState( BUSY ) )
+ {
+ NbSegmBusy = 1;
+ break;
+ }
+ }
+
+ if( firstTrack == NULL )
+ return NULL;
+
+ double full_len = 0;
+ double lenPadToDie = 0;
+
+ if( aReorder )
+ {
+ DLIST<TRACK>* list = (DLIST<TRACK>*)firstTrack->GetList();
+ wxASSERT( list );
+
+ /* Rearrange the chain starting at firstTrack
+ * All others flagged items are moved from their position to the end
+ * of the flagged list
+ */
+ TRACK* next;
+
+ for( TRACK* track = firstTrack->Next(); track; track = next )
+ {
+ next = track->Next();
+
+ if( track->GetState( BUSY ) ) // move it!
+ {
+ NbSegmBusy++;
+ track->UnLink();
+ list->Insert( track, firstTrack->Next() );
+
+ if( aTraceLength )
+ full_len += track->GetLength();
+
+ if( aPadToDieLength ) // Add now length die.
+ {
+ // In fact only 2 pads (maximum) will be taken in account:
+ // that are on each end of the track, if any
+ if( track->GetState( BEGIN_ONPAD ) )
+ {
+ D_PAD * pad = (D_PAD *) track->start;
+ lenPadToDie += (double) pad->GetPadToDieLength();
+ }
+
+ if( track->GetState( END_ONPAD ) )
+ {
+ D_PAD * pad = (D_PAD *) track->end;
+ lenPadToDie += (double) pad->GetPadToDieLength();
+ }
+ }
+ }
+ }
+ }
+ else if( aTraceLength )
+ {
+ NbSegmBusy = 0;
+
+ for( TRACK* track = firstTrack; track; track = track->Next() )
+ {
+ if( track->GetState( BUSY ) )
+ {
+ NbSegmBusy++;
+ track->SetState( BUSY, false );
+ full_len += track->GetLength();
+
+ // Add now length die.
+ // In fact only 2 pads (maximum) will be taken in account:
+ // that are on each end of the track, if any
+ if( track->GetState( BEGIN_ONPAD ) )
+ {
+ D_PAD * pad = (D_PAD *) track->start;
+ lenPadToDie += (double) pad->GetPadToDieLength();
+ }
+
+ if( track->GetState( END_ONPAD ) )
+ {
+ D_PAD * pad = (D_PAD *) track->end;
+ lenPadToDie += (double) pad->GetPadToDieLength();
+ }
+ }
+ }
+
+ DBG( printf( "%s: NbSegmBusy:%d\n", __func__, NbSegmBusy ); )
+ }
+
+ if( aTraceLength )
+ *aTraceLength = full_len;
+
+ if( aPadToDieLength )
+ *aPadToDieLength = lenPadToDie;
+
+ if( aCount )
+ *aCount = NbSegmBusy;
+
+ return firstTrack;
+}
+
+
+MODULE* BOARD::GetFootprint( const wxPoint& aPosition, LAYER_ID aActiveLayer,
+ bool aVisibleOnly, bool aIgnoreLocked )
+{
+ MODULE* pt_module;
+ MODULE* module = NULL;
+ MODULE* alt_module = NULL;
+ int min_dim = 0x7FFFFFFF;
+ int alt_min_dim = 0x7FFFFFFF;
+ bool current_layer_back = IsBackLayer( aActiveLayer );
+
+ for( pt_module = m_Modules; pt_module; pt_module = pt_module->Next() )
+ {
+ // is the ref point within the module's bounds?
+ if( !pt_module->HitTest( aPosition ) )
+ continue;
+
+ // if caller wants to ignore locked modules, and this one is locked, skip it.
+ if( aIgnoreLocked && pt_module->IsLocked() )
+ continue;
+
+ LAYER_ID layer = pt_module->GetLayer();
+
+ // Filter non visible modules if requested
+ if( !aVisibleOnly || IsModuleLayerVisible( layer ) )
+ {
+ EDA_RECT bb = pt_module->GetFootprintRect();
+
+ int offx = bb.GetX() + bb.GetWidth() / 2;
+ int offy = bb.GetY() + bb.GetHeight() / 2;
+
+ // off x & offy point to the middle of the box.
+ int dist = ( aPosition.x - offx ) * ( aPosition.x - offx ) +
+ ( aPosition.y - offy ) * ( aPosition.y - offy );
+
+ if( current_layer_back == IsBackLayer( layer ) )
+ {
+ if( dist <= min_dim )
+ {
+ // better footprint shown on the active side
+ module = pt_module;
+ min_dim = dist;
+ }
+ }
+ else if( aVisibleOnly && IsModuleLayerVisible( layer ) )
+ {
+ if( dist <= alt_min_dim )
+ {
+ // better footprint shown on the other side
+ alt_module = pt_module;
+ alt_min_dim = dist;
+ }
+ }
+ }
+ }
+
+ if( module )
+ {
+ return module;
+ }
+
+ if( alt_module)
+ {
+ return alt_module;
+ }
+
+ return NULL;
+}
+
+
+BOARD_CONNECTED_ITEM* BOARD::GetLockPoint( const wxPoint& aPosition, LSET aLayerMask )
+{
+ for( MODULE* module = m_Modules; module; module = module->Next() )
+ {
+ D_PAD* pad = module->GetPad( aPosition, aLayerMask );
+
+ if( pad )
+ return pad;
+ }
+
+ // No pad has been located so check for a segment of the trace.
+ TRACK* segment = ::GetTrack( m_Track, NULL, aPosition, aLayerMask );
+
+ if( segment == NULL )
+ segment = GetTrack( m_Track, aPosition, aLayerMask );
+
+ return segment;
+}
+
+
+TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS_LIST* aList )
+{
+ /* creates an intermediate point on aSegment and break it into two segments
+ * at aPosition.
+ * The new segment starts from aPosition and ends at the end point of
+ * aSegment. The original segment now ends at aPosition.
+ */
+ if( aSegment->GetStart() == aPosition || aSegment->GetEnd() == aPosition )
+ return NULL;
+
+ // A via is a good lock point
+ if( aSegment->Type() == PCB_VIA_T )
+ {
+ aPosition = aSegment->GetStart();
+ return aSegment;
+ }
+
+ // Calculation coordinate of intermediate point relative to the start point of aSegment
+ wxPoint delta = aSegment->GetEnd() - aSegment->GetStart();
+
+ // calculate coordinates of aPosition relative to aSegment->GetStart()
+ wxPoint lockPoint = aPosition - aSegment->GetStart();
+
+ // lockPoint must be on aSegment:
+ // Ensure lockPoint.y/lockPoint.y = delta.y/delta.x
+ if( delta.x == 0 )
+ lockPoint.x = 0; // horizontal segment
+ else
+ lockPoint.y = KiROUND( ( (double)lockPoint.x * delta.y ) / delta.x );
+
+ /* Create the intermediate point (that is to say creation of a new
+ * segment, beginning at the intermediate point.
+ */
+ lockPoint += aSegment->GetStart();
+
+ TRACK* newTrack = (TRACK*)aSegment->Clone();
+ // The new segment begins at the new point,
+ newTrack->SetStart(lockPoint);
+ newTrack->start = aSegment;
+ newTrack->SetState( BEGIN_ONPAD, false );
+
+ DLIST<TRACK>* list = (DLIST<TRACK>*)aSegment->GetList();
+ wxASSERT( list );
+ list->Insert( newTrack, aSegment->Next() );
+
+ if( aList )
+ {
+ // Prepare the undo command for the now track segment
+ ITEM_PICKER picker( newTrack, UR_NEW );
+ aList->PushItem( picker );
+ // Prepare the undo command for the old track segment
+ // before modifications
+ picker.SetItem( aSegment );
+ picker.SetStatus( UR_CHANGED );
+ picker.SetLink( aSegment->Clone() );
+ aList->PushItem( picker );
+ }
+
+ // Old track segment now ends at new point.
+ aSegment->SetEnd(lockPoint);
+ aSegment->end = newTrack;
+ aSegment->SetState( END_ONPAD, false );
+
+ D_PAD * pad = GetPad( newTrack, ENDPOINT_START );
+
+ if( pad )
+ {
+ newTrack->start = pad;
+ newTrack->SetState( BEGIN_ONPAD, true );
+ aSegment->end = pad;
+ aSegment->SetState( END_ONPAD, true );
+ }
+
+ aPosition = lockPoint;
+ return newTrack;
+}
+
+
+ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode,
+ LAYER_ID aLayer, wxPoint aStartPointPosition, int aHatch )
+{
+ ZONE_CONTAINER* new_area = InsertArea( aNetcode,
+ m_ZoneDescriptorList.size( ) - 1,
+ aLayer, aStartPointPosition.x,
+ aStartPointPosition.y, aHatch );
+
+ if( aNewZonesList )
+ {
+ ITEM_PICKER picker( new_area, UR_NEW );
+ aNewZonesList->PushItem( picker );
+ }
+
+ return new_area;
+}
+
+
+void BOARD::RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to_remove )
+{
+ if( area_to_remove == NULL )
+ return;
+
+ if( aDeletedList )
+ {
+ ITEM_PICKER picker( area_to_remove, UR_DELETED );
+ aDeletedList->PushItem( picker );
+ Remove( area_to_remove ); // remove from zone list, but does not delete it
+ }
+ else
+ {
+ Delete( area_to_remove );
+ }
+}
+
+
+ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, LAYER_ID layer, int x, int y, int hatch )
+{
+ ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this );
+
+ new_area->SetNetCode( netcode );
+ new_area->SetLayer( layer );
+ new_area->SetTimeStamp( GetNewTimeStamp() );
+
+ if( iarea < (int) ( m_ZoneDescriptorList.size() - 1 ) )
+ m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + iarea + 1, new_area );
+ else
+ m_ZoneDescriptorList.push_back( new_area );
+
+ new_area->Outline()->Start( layer, x, y, hatch );
+ return new_area;
+}
+
+
+bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAINER* aCurrArea )
+{
+ CPolyLine* curr_polygon = aCurrArea->Outline();
+
+ // mark all areas as unmodified except this one, if modified
+ for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
+ m_ZoneDescriptorList[ia]->SetLocalFlags( 0 );
+
+ aCurrArea->SetLocalFlags( 1 );
+
+ if( curr_polygon->IsPolygonSelfIntersecting() )
+ {
+ std::vector<CPolyLine*>* pa = new std::vector<CPolyLine*>;
+ curr_polygon->UnHatch();
+ int n_poly = aCurrArea->Outline()->NormalizeAreaOutlines( pa );
+
+ // If clipping has created some polygons, we must add these new copper areas.
+ if( n_poly > 1 )
+ {
+ ZONE_CONTAINER* NewArea;
+
+ for( int ip = 1; ip < n_poly; ip++ )
+ {
+ // create new copper area and copy poly into it
+ CPolyLine* new_p = (*pa)[ip - 1];
+ NewArea = AddArea( aNewZonesList, aCurrArea->GetNetCode(), aCurrArea->GetLayer(),
+ wxPoint(0, 0), CPolyLine::NO_HATCH );
+
+ // remove the poly that was automatically created for the new area
+ // and replace it with a poly from NormalizeAreaOutlines
+ delete NewArea->Outline();
+ NewArea->SetOutline( new_p );
+ NewArea->Outline()->Hatch();
+ NewArea->SetLocalFlags( 1 );
+ }
+ }
+
+ delete pa;
+ }
+
+ curr_polygon->Hatch();
+
+ return true;
+}
+
+
+void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
+ REPORTER* aReporter )
+{
+ unsigned i;
+ wxPoint bestPosition;
+ wxString msg;
+ D_PAD* pad;
+ MODULE* footprint;
+
+ if( !IsEmpty() )
+ {
+ // Position new components below any existing board features.
+ EDA_RECT bbbox = ComputeBoundingBox( true );
+
+ if( bbbox.GetWidth() || bbbox.GetHeight() )
+ {
+ bestPosition.x = bbbox.Centre().x;
+ bestPosition.y = bbbox.GetBottom() + Millimeter2iu( 10 );
+ }
+ }
+ else
+ {
+ // Position new components in the center of the page when the board is empty.
+ wxSize pageSize = m_paper.GetSizeIU();
+
+ bestPosition.x = pageSize.GetWidth() / 2;
+ bestPosition.y = pageSize.GetHeight() / 2;
+ }
+
+ m_Status_Pcb = 0;
+
+ for( i = 0; i < aNetlist.GetCount(); i++ )
+ {
+ COMPONENT* component = aNetlist.GetComponent( i );
+
+ if( aReporter )
+ {
+
+ msg.Printf( _( "Checking netlist component footprint \"%s:%s:%s\".\n" ),
+ GetChars( component->GetReference() ),
+ GetChars( component->GetTimeStamp() ),
+ GetChars( component->GetFPID().Format() ) );
+ aReporter->Report( msg, REPORTER::RPT_INFO );
+ }
+
+ if( aNetlist.IsFindByTimeStamp() )
+ footprint = FindModule( aNetlist.GetComponent( i )->GetTimeStamp(), true );
+ else
+ footprint = FindModule( aNetlist.GetComponent( i )->GetReference() );
+
+ if( footprint == NULL ) // A new footprint.
+ {
+ if( aReporter )
+ {
+ if( component->GetModule() != NULL )
+ {
+ msg.Printf( _( "Adding new component \"%s:%s\" footprint \"%s\".\n" ),
+ GetChars( component->GetReference() ),
+ GetChars( component->GetTimeStamp() ),
+ GetChars( component->GetFPID().Format() ) );
+
+ aReporter->Report( msg, REPORTER::RPT_ACTION );
+ }
+ else
+ {
+ msg.Printf( _( "Cannot add new component \"%s:%s\" due to missing "
+ "footprint \"%s\".\n" ),
+ GetChars( component->GetReference() ),
+ GetChars( component->GetTimeStamp() ),
+ GetChars( component->GetFPID().Format() ) );
+
+ aReporter->Report( msg, REPORTER::RPT_ERROR );
+ }
+ }
+
+ if( !aNetlist.IsDryRun() && (component->GetModule() != NULL) )
+ {
+ // Owned by NETLIST, can only copy it.
+ footprint = new MODULE( *component->GetModule() );
+ footprint->SetParent( this );
+ footprint->SetPosition( bestPosition );
+ footprint->SetTimeStamp( GetNewTimeStamp() );
+ Add( footprint, ADD_APPEND );
+ }
+ }
+ else // An existing footprint.
+ {
+ // Test for footprint change.
+ if( !component->GetFPID().empty() &&
+ footprint->GetFPID() != component->GetFPID() )
+ {
+ if( aNetlist.GetReplaceFootprints() )
+ {
+ if( aReporter )
+ {
+ if( component->GetModule() != NULL )
+ {
+ msg.Printf( _( "Replacing component \"%s:%s\" footprint \"%s\" with "
+ "\"%s\".\n" ),
+ GetChars( footprint->GetReference() ),
+ GetChars( footprint->GetPath() ),
+ GetChars( footprint->GetFPID().Format() ),
+ GetChars( component->GetFPID().Format() ) );
+
+ aReporter->Report( msg, REPORTER::RPT_ACTION );
+ }
+ else
+ {
+ msg.Printf( _( "Cannot replace component \"%s:%s\" due to missing "
+ "footprint \"%s\".\n" ),
+ GetChars( footprint->GetReference() ),
+ GetChars( footprint->GetPath() ),
+ GetChars( component->GetFPID().Format() ) );
+
+ aReporter->Report( msg, REPORTER::RPT_ERROR );
+ }
+ }
+
+ if( !aNetlist.IsDryRun() && (component->GetModule() != NULL) )
+ {
+ wxASSERT( footprint != NULL );
+ MODULE* newFootprint = new MODULE( *component->GetModule() );
+
+ if( aNetlist.IsFindByTimeStamp() )
+ newFootprint->SetReference( footprint->GetReference() );
+ else
+ newFootprint->SetPath( footprint->GetPath() );
+
+ // Copy placement and pad net names.
+ // optionally, copy or not local settings (like local clearances)
+ // if the second parameter is "true", previous values will be used.
+ // if "false", the default library values of the new footprint
+ // will be used
+ footprint->CopyNetlistSettings( newFootprint, false );
+
+ Remove( footprint );
+ Add( newFootprint, ADD_APPEND );
+ footprint = newFootprint;
+ }
+ }
+ }
+
+ // Test for reference designator field change.
+ if( footprint->GetReference() != component->GetReference() )
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "Changing component \"%s:%s\" reference to \"%s\".\n" ),
+ GetChars( footprint->GetReference() ),
+ GetChars( footprint->GetPath() ),
+ GetChars( component->GetReference() ) );
+ aReporter->Report( msg, REPORTER::RPT_ACTION );
+ }
+
+ if( !aNetlist.IsDryRun() )
+ footprint->SetReference( component->GetReference() );
+ }
+
+ // Test for value field change.
+ if( footprint->GetValue() != component->GetValue() )
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "Changing component \"%s:%s\" value from \"%s\" to \"%s\".\n" ),
+ GetChars( footprint->GetReference() ),
+ GetChars( footprint->GetPath() ),
+ GetChars( footprint->GetValue() ),
+ GetChars( component->GetValue() ) );
+ aReporter->Report( msg, REPORTER::RPT_ACTION );
+ }
+
+ if( !aNetlist.IsDryRun() )
+ footprint->SetValue( component->GetValue() );
+ }
+
+ // Test for time stamp change.
+ if( footprint->GetPath() != component->GetTimeStamp() )
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "Changing component path \"%s:%s\" to \"%s\".\n" ),
+ GetChars( footprint->GetReference() ),
+ GetChars( footprint->GetPath() ),
+ GetChars( component->GetTimeStamp() ) );
+ aReporter->Report( msg, REPORTER::RPT_INFO );
+ }
+
+ if( !aNetlist.IsDryRun() )
+ footprint->SetPath( component->GetTimeStamp() );
+ }
+ }
+
+ if( footprint == NULL )
+ continue;
+
+ // At this point, the component footprint is updated. Now update the nets.
+ for( pad = footprint->Pads(); pad; pad = pad->Next() )
+ {
+ COMPONENT_NET net = component->GetNet( pad->GetPadName() );
+
+ if( !net.IsValid() ) // Footprint pad had no net.
+ {
+ if( aReporter && !pad->GetNetname().IsEmpty() )
+ {
+ msg.Printf( _( "Clearing component \"%s:%s\" pin \"%s\" net name.\n" ),
+ GetChars( footprint->GetReference() ),
+ GetChars( footprint->GetPath() ),
+ GetChars( pad->GetPadName() ) );
+ aReporter->Report( msg, REPORTER::RPT_ACTION );
+ }
+
+ if( !aNetlist.IsDryRun() )
+ pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
+ }
+ else // Footprint pad has a net.
+ {
+ if( net.GetNetName() != pad->GetNetname() )
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "Changing component \"%s:%s\" pin \"%s\" net name from "
+ "\"%s\" to \"%s\".\n" ),
+ GetChars( footprint->GetReference() ),
+ GetChars( footprint->GetPath() ),
+ GetChars( pad->GetPadName() ),
+ GetChars( pad->GetNetname() ),
+ GetChars( net.GetNetName() ) );
+ aReporter->Report( msg, REPORTER::RPT_ACTION );
+ }
+
+ if( !aNetlist.IsDryRun() )
+ {
+ NETINFO_ITEM* netinfo = FindNet( net.GetNetName() );
+ if( netinfo == NULL )
+ {
+ // It is a new net, we have to add it
+ netinfo = new NETINFO_ITEM( this, net.GetNetName() );
+ m_NetInfo.AppendNet( netinfo );
+ }
+
+ pad->SetNetCode( netinfo->GetNet() );
+ }
+ }
+ }
+ }
+ }
+
+ // Remove all components not in the netlist.
+ if( aNetlist.GetDeleteExtraFootprints() )
+ {
+ MODULE* nextModule;
+ const COMPONENT* component;
+
+ for( MODULE* module = m_Modules; module != NULL; module = nextModule )
+ {
+ nextModule = module->Next();
+
+ if( module->IsLocked() )
+ continue;
+
+ if( aNetlist.IsFindByTimeStamp() )
+ component = aNetlist.GetComponentByTimeStamp( module->GetPath() );
+ else
+ component = aNetlist.GetComponentByReference( module->GetReference() );
+
+ if( component == NULL )
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "Removing unused component \"%s:%s\".\n" ),
+ GetChars( module->GetReference() ),
+ GetChars( module->GetPath() ) );
+ aReporter->Report( msg, REPORTER::RPT_ACTION );
+ }
+
+ if( !aNetlist.IsDryRun() )
+ module->DeleteStructure();
+ }
+ }
+ }
+
+ // We need the pad list, for next tests.
+ // padlist is the list of pads, sorted by netname.
+ BuildListOfNets();
+ std::vector<D_PAD*> padlist = GetPads();
+
+ // If needed, remove the single pad nets:
+ if( aDeleteSinglePadNets && !aNetlist.IsDryRun() )
+ {
+ int count = 0;
+ wxString netname;
+ D_PAD* pad = NULL;
+ D_PAD* previouspad = NULL;
+
+ for( unsigned ii = 0; ii < padlist.size(); ii++ )
+ {
+ pad = padlist[ii];
+
+ if( pad->GetNetname().IsEmpty() )
+ continue;
+
+ if( netname != pad->GetNetname() ) // End of net
+ {
+ if( previouspad && count == 1 )
+ {
+ // First, see if we have a copper zone attached to this pad.
+ // If so, this is not really a single pad net
+
+ for( int ii = 0; ii < GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* zone = GetArea( ii );
+
+ if( !zone->IsOnCopperLayer() )
+ continue;
+
+ if( zone->GetIsKeepout() )
+ continue;
+
+ if( zone->GetNet() == previouspad->GetNet() )
+ {
+ count++;
+ break;
+ }
+ }
+
+ if( count == 1 ) // Really one pad, and nothing else
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "Remove single pad net \"%s\" on \"%s\" pad '%s'\n" ),
+ GetChars( previouspad->GetNetname() ),
+ GetChars( previouspad->GetParent()->GetReference() ),
+ GetChars( previouspad->GetPadName() ) );
+ aReporter->Report( msg, REPORTER::RPT_ACTION );
+ }
+
+ previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED );
+ }
+ }
+
+ netname = pad->GetNetname();
+ count = 1;
+ }
+ else
+ count++;
+
+ previouspad = pad;
+ }
+
+ // Examine last pad
+ if( pad && count == 1 )
+ pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
+ }
+
+ // Last step: Some tests:
+ // verify all pads found in netlist:
+ // They should exist in footprints, otherwise the footprint is wrong
+ // note also references or time stamps are updated, so we use only
+ // the reference to find a footprint
+ //
+ // Also verify if zones have acceptable nets, i.e. nets with pads.
+ // Zone with no pad belongs to a "dead" net which happens after changes in schematic
+ // when no more pad use this net name.
+ if( aReporter )
+ {
+ wxString padname;
+ for( i = 0; i < aNetlist.GetCount(); i++ )
+ {
+ const COMPONENT* component = aNetlist.GetComponent( i );
+ MODULE* footprint = FindModuleByReference( component->GetReference() );
+
+ if( footprint == NULL ) // It can be missing in partial designs
+ continue;
+
+ // Explore all pins/pads in component
+ for( unsigned jj = 0; jj < component->GetNetCount(); jj++ )
+ {
+ COMPONENT_NET net = component->GetNet( jj );
+ padname = net.GetPinName();
+
+ if( footprint->FindPadByName( padname ) )
+ continue; // OK, pad found
+
+ // not found: bad footprint, report error
+ msg.Printf( _( "Component '%s' pad '%s' not found in footprint '%s'\n" ),
+ GetChars( component->GetReference() ),
+ GetChars( padname ),
+ GetChars( footprint->GetFPID().Format() ) );
+ aReporter->Report( msg, REPORTER::RPT_ERROR );
+ }
+ }
+
+ // Test copper zones to detect "dead" nets (nets without any pad):
+ for( int ii = 0; ii < GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* zone = GetArea( ii );
+
+ if( !zone->IsOnCopperLayer() || zone->GetIsKeepout() )
+ continue;
+
+ if( zone->GetNet()->GetNodesCount() == 0 )
+ {
+ msg.Printf( _( "Copper zone (net name '%s'): net has no pads connected." ),
+ GetChars( zone->GetNet()->GetNetname() ) );
+ aReporter->Report( msg, REPORTER::RPT_WARNING );
+ }
+ }
+ }
+}
+
+
+BOARD_ITEM* BOARD::DuplicateAndAddItem( const BOARD_ITEM* aItem,
+ bool aIncrementReferences )
+{
+ BOARD_ITEM* new_item = NULL;
+
+ switch( aItem->Type() )
+ {
+ case PCB_MODULE_T:
+ {
+ MODULE* new_module = new MODULE( *static_cast<const MODULE*>( aItem ) );
+ new_item = new_module;
+ break;
+ }
+ case PCB_TEXT_T:
+ case PCB_LINE_T:
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ case PCB_ZONE_AREA_T:
+ case PCB_TARGET_T:
+ case PCB_DIMENSION_T:
+ new_item = static_cast<BOARD_ITEM*>( aItem->Clone() );
+ break;
+
+ default:
+ // Un-handled item for duplication
+ wxASSERT_MSG( false, "Duplication not supported for items of class "
+ + aItem->GetClass() );
+ break;
+ }
+
+ if( new_item )
+ {
+ if( aIncrementReferences )
+ new_item->IncrementItemReference();
+
+ Add( new_item );
+ }
+
+ return new_item;
+}
+
+
+wxString BOARD::GetNextModuleReferenceWithPrefix( const wxString& aPrefix,
+ bool aFillSequenceGaps )
+{
+ wxString nextRef;
+
+ std::set<int> usedNumbers;
+
+ for( MODULE* module = m_Modules; module; module = module->Next() )
+ {
+ const wxString ref = module->GetReference();
+ wxString remainder;
+
+ // ONly interested in modules with the right prefix
+ if( !ref.StartsWith( aPrefix, &remainder ) )
+ continue;
+
+ // the suffix must be a number
+ if( !remainder.IsNumber() )
+ continue;
+
+ long number;
+ if( remainder.ToCLong( &number ) )
+ usedNumbers.insert( number );
+ }
+
+ if( usedNumbers.size() )
+ {
+ int nextNum = getNextNumberInSequence( usedNumbers, aFillSequenceGaps );
+ nextRef = wxString::Format( wxT( "%s%i" ), aPrefix, nextNum );
+ }
+
+ return nextRef;
+}
+
+
+/* Extracts the board outlines and build a closed polygon
+ * from lines, arcs and circle items on edge cut layer
+ * Any closed outline inside the main outline is a hole
+ * All contours should be closed, i.e. are valid vertices for a closed polygon
+ * return true if success, false if a contour is not valid
+ */
+#include <specctra.h>
+bool BOARD::GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines,
+ SHAPE_POLY_SET& aHoles,
+ wxString* aErrorText )
+{
+ // the SPECCTRA_DB function to extract board outlines:
+ DSN::SPECCTRA_DB dummy;
+ return dummy.GetBoardPolygonOutlines( this, aOutlines,
+ aHoles, aErrorText );
+}
diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h
new file mode 100644
index 0000000..8836e15
--- /dev/null
+++ b/pcbnew/class_board.h
@@ -0,0 +1,1391 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_board.h
+ * @brief Class BOARD to handle a board.
+ */
+
+#ifndef CLASS_BOARD_H_
+#define CLASS_BOARD_H_
+
+
+#include <dlist.h>
+
+#include <common.h> // PAGE_INFO
+#include <layers_id_colors_and_visibility.h>
+#include <class_netinfo.h>
+#include <class_pad.h>
+#include <class_colors_design_settings.h>
+#include <class_board_design_settings.h>
+#include <class_title_block.h>
+#include <class_zone_settings.h>
+#include <pcb_plot_params.h>
+
+
+class PCB_BASE_FRAME;
+class PCB_EDIT_FRAME;
+class PICKED_ITEMS_LIST;
+class BOARD;
+class ZONE_CONTAINER;
+class SEGZONE;
+class TRACK;
+class D_PAD;
+class MARKER_PCB;
+class MSG_PANEL_ITEM;
+class NETLIST;
+class REPORTER;
+class RN_DATA;
+class SHAPE_POLY_SET;
+
+// non-owning container of item candidates when searching for items on the same track.
+typedef std::vector< TRACK* > TRACK_PTRS;
+
+
+/**
+ * Enum LAYER_T
+ * gives the allowed types of layers, same as Specctra DSN spec.
+ */
+enum LAYER_T
+{
+ LT_UNDEFINED = -1,
+ LT_SIGNAL,
+ LT_POWER,
+ LT_MIXED,
+ LT_JUMPER
+};
+
+
+/**
+ * Class LAYER
+ * holds information pertinent to a layer of a BOARD.
+ */
+struct LAYER
+{
+ LAYER()
+ {
+ clear();
+ }
+
+ void clear()
+ {
+ m_type = LT_SIGNAL;
+ m_visible = true;
+ m_number = 0;
+ m_name.clear();
+ }
+
+ /*
+ LAYER( const wxString& aName = wxEmptyString,
+ LAYER_T aType = LT_SIGNAL, bool aVisible = true, int aNumber = -1 ) :
+ m_name( aName ),
+ m_type( aType ),
+ m_visible( aVisible ),
+ m_number( aNumber )
+ {
+ }
+ */
+
+ wxString m_name; ///< The name of the layer, there should be no spaces in this name.
+
+ LAYER_T m_type; ///< The type of the layer
+
+ bool m_visible;
+
+ int m_number;
+
+ /**
+ * Function ShowType
+ * converts a LAYER_T enum to a const char*
+ * @param aType The LAYER_T to convert
+ * @return const char* - The string representation of the layer type.
+ */
+ static const char* ShowType( LAYER_T aType );
+
+ /**
+ * Function ParseType
+ * converts a string to a LAYER_T
+ * @param aType The const char* to convert
+ * @return LAYER_T - The binary representation of the layer type, or
+ * LAYER_T(-1) if the string is invalid
+ */
+ static LAYER_T ParseType( const char* aType );
+};
+
+
+// Helper class to handle high light nets
+class HIGH_LIGHT_INFO
+{
+ friend class BOARD;
+
+protected:
+ int m_netCode; // net selected for highlight (-1 when no net selected )
+ bool m_highLightOn; // highlight active
+
+ void Clear()
+ {
+ m_netCode = -1;
+ m_highLightOn = false;
+ }
+
+ HIGH_LIGHT_INFO()
+ {
+ Clear();
+ }
+};
+
+
+/**
+ * Class BOARD
+ * holds information pertinent to a Pcbnew printed circuit board.
+ */
+class BOARD : public BOARD_ITEM
+{
+ friend class PCB_EDIT_FRAME;
+
+private:
+ /// the board filename
+ wxString m_fileName;
+
+ // @todo: switch to boost:ptr_vector, and change ~BOARD()
+ typedef std::vector<MARKER_PCB*> MARKERS;
+
+ /// MARKER_PCBs for clearance problems, owned by pointer.
+ MARKERS m_markers;
+
+ // @todo: switch to boost::ptr_vector, and change ~BOARD()
+ typedef std::vector<ZONE_CONTAINER*> ZONE_CONTAINERS;
+
+ /// edge zone descriptors, owned by pointer.
+ ZONE_CONTAINERS m_ZoneDescriptorList;
+
+ LAYER m_Layer[LAYER_ID_COUNT];
+
+ // if true m_highLight_NetCode is used
+ HIGH_LIGHT_INFO m_highLight; // current high light data
+ HIGH_LIGHT_INFO m_highLightPrevious; // a previously stored high light data
+
+ int m_fileFormatVersionAtLoad; ///< the version loaded from the file
+
+ EDA_RECT m_BoundingBox;
+ NETINFO_LIST m_NetInfo; ///< net info list (name, design constraints ..
+ RN_DATA* m_ratsnest;
+
+ BOARD_DESIGN_SETTINGS m_designSettings;
+ ZONE_SETTINGS m_zoneSettings;
+ COLORS_DESIGN_SETTINGS* m_colorsSettings;
+ PAGE_INFO m_paper;
+ TITLE_BLOCK m_titles; ///< text in lower right of screen and plots
+ PCB_PLOT_PARAMS m_plotOptions;
+
+ /// Number of pads connected to the current net.
+ int m_nodeCount;
+
+ /// Number of unconnected nets in the current rats nest.
+ int m_unconnectedNetCount;
+
+ /**
+ * Function chainMarkedSegments
+ * is used by MarkTrace() to set the BUSY flag of connected segments of the trace
+ * segment located at \a aPosition on aLayerMask.
+ * Vias are put in list but their flags BUSY is not set
+ * @param aPosition A wxPoint object containing the position of the starting search.
+ * @param aLayerSet The allowed layers for segments to search.
+ * @param aList The track list to fill with points of flagged segments.
+ */
+ void chainMarkedSegments( wxPoint aPosition, const LSET& aLayerSet, TRACK_PTRS* aList );
+
+public:
+ static inline bool ClassOf( const EDA_ITEM* aItem )
+ {
+ return aItem && PCB_T == aItem->Type();
+ }
+
+ void SetFileName( const wxString& aFileName ) { m_fileName = aFileName; }
+
+ const wxString &GetFileName() const { return m_fileName; }
+
+ /// Flags used in ratsnest calculation and update.
+ int m_Status_Pcb;
+
+ DLIST<BOARD_ITEM> m_Drawings; // linked list of lines & texts
+ DLIST<MODULE> m_Modules; // linked list of MODULEs
+ DLIST<TRACK> m_Track; // linked list of TRACKs and VIAs
+ DLIST<SEGZONE> m_Zone; // linked list of SEGZONEs
+
+ /// Ratsnest list for the BOARD
+ std::vector<RATSNEST_ITEM> m_FullRatsnest;
+
+ /// Ratsnest list relative to a given footprint (used while moving a footprint).
+ std::vector<RATSNEST_ITEM> m_LocalRatsnest;
+
+ /// zone contour currently in progress
+ ZONE_CONTAINER* m_CurrentZoneContour;
+
+ BOARD();
+ ~BOARD();
+
+ virtual const wxPoint& GetPosition() const;
+
+ virtual void SetPosition( const wxPoint& aPos );
+
+ bool IsEmpty() const
+ {
+ return m_Drawings.GetCount() == 0 && m_Modules.GetCount() == 0 &&
+ m_Track.GetCount() == 0 && m_Zone.GetCount() == 0;
+ }
+
+ void Move( const wxPoint& aMoveVector ); // overload
+
+ void SetFileFormatVersionAtLoad( int aVersion ) { m_fileFormatVersionAtLoad = aVersion; }
+ int GetFileFormatVersionAtLoad() const { return m_fileFormatVersionAtLoad; }
+
+ /**
+ * Function Add
+ * adds the given item to this BOARD and takes ownership of its memory.
+ * @param aBoardItem The item to add to this board.
+ * @param aControl An int which can vary how the item is added.
+ */
+ void Add( BOARD_ITEM* aBoardItem, int aControl = 0 );
+
+#define ADD_APPEND 1 ///< aControl flag for Add( aControl ), appends not inserts
+
+ /**
+ * Function Delete
+ * removes the given single item from this BOARD and deletes its memory.
+ * @param aBoardItem The item to remove from this board and delete
+ */
+ void Delete( BOARD_ITEM* aBoardItem )
+ {
+ // developers should run DEBUG versions and fix such calls with NULL
+ wxASSERT( aBoardItem );
+
+ if( aBoardItem )
+ delete Remove( aBoardItem );
+ }
+
+
+ /**
+ * Function Remove
+ * removes \a aBoardItem from this BOARD and returns it to caller without deleting it.
+ * @param aBoardItem The item to remove from this board.
+ * @return BOARD_ITEM* \a aBoardItem which was passed in.
+ */
+ BOARD_ITEM* Remove( BOARD_ITEM* aBoardItem );
+
+ BOARD_ITEM* DuplicateAndAddItem( const BOARD_ITEM* aItem,
+ bool aIncrementReferences );
+
+ /**
+ * Function GetNextModuleReferenceWithPrefix
+ * Get the next available module reference with this prefix
+ */
+ wxString GetNextModuleReferenceWithPrefix( const wxString& aPrefix,
+ bool aFillSequenceGaps );
+
+ /**
+ * Function GetRatsnest()
+ * returns list of missing connections between components/tracks.
+ * @return RATSNEST* is an object that contains informations about missing connections.
+ */
+ RN_DATA* GetRatsnest() const
+ {
+ return m_ratsnest;
+ }
+
+ /**
+ * Function DeleteMARKERs
+ * deletes ALL MARKERS from the board.
+ */
+ void DeleteMARKERs();
+
+ /**
+ * Function DeleteZONEOutlines
+ * deletes ALL zone outlines from the board.
+ */
+ void DeleteZONEOutlines();
+
+ /**
+ * Function GetMARKER
+ * returns the MARKER at a given index.
+ * @param index The array type index into a collection of MARKER_PCBS.
+ * @return MARKER_PCB* - a pointer to the MARKER_PCB or NULL if index out of range.
+ */
+ MARKER_PCB* GetMARKER( int index ) const
+ {
+ if( (unsigned) index < m_markers.size() )
+ return m_markers[index];
+
+ return NULL;
+ }
+
+ /**
+ * Function GetMARKERCount
+ * @return int - The number of MARKER_PCBS.
+ */
+ int GetMARKERCount() const
+ {
+ return (int) m_markers.size();
+ }
+
+ /**
+ * Function SetAuxOrigin
+ * sets the origin point used for plotting.
+ */
+ void SetAuxOrigin( const wxPoint& aPoint ) { m_designSettings.m_AuxOrigin = aPoint; }
+ const wxPoint& GetAuxOrigin() const { return m_designSettings.m_AuxOrigin; }
+
+ /**
+ * Function SetGridOrigin
+ * sets the origin point of the grid.
+ */
+ void SetGridOrigin( const wxPoint& aPoint ) { m_designSettings.m_GridOrigin = aPoint; }
+ const wxPoint& GetGridOrigin() const { return m_designSettings.m_GridOrigin; }
+
+ /**
+ * Function ResetHighLight
+ * Reset all high light data to the init state
+ */
+ void ResetHighLight()
+ {
+ m_highLight.Clear();
+ m_highLightPrevious.Clear();
+ }
+
+ /**
+ * Function GetHighLightNetCode
+ * @return netcode of net to highlight (-1 when no net selected)
+ */
+ int GetHighLightNetCode() { return m_highLight.m_netCode; }
+
+ /**
+ * Function SetHighLightNet
+ * @param aNetCode = netcode of net to highlight
+ */
+ void SetHighLightNet( int aNetCode)
+ {
+ m_highLight.m_netCode = aNetCode;
+ }
+
+ /**
+ * Function IsHighLightNetON
+ * @return true if a net is currently highlighted
+ */
+ bool IsHighLightNetON() { return m_highLight.m_highLightOn; }
+
+ /**
+ * Function HighLightOFF
+ * Disable highlight.
+ */
+ void HighLightOFF() { m_highLight.m_highLightOn = false; }
+
+ /**
+ * Function HighLightON
+ * Enable highlight.
+ * if m_highLight_NetCode >= 0, this net will be highlighted
+ */
+ void HighLightON() { m_highLight.m_highLightOn = true; }
+
+ /**
+ * Function PushHighLight
+ * save current high light info for later use
+ */
+ void PushHighLight();
+
+ /**
+ * Function PopHighLight
+ * retrieve a previously saved high light info
+ */
+ void PopHighLight();
+
+ /**
+ * Function GetCopperLayerCount
+ * @return int - The number of copper layers in the BOARD.
+ */
+ int GetCopperLayerCount() const;
+
+ void SetCopperLayerCount( int aCount );
+
+ /**
+ * Function GetEnabledLayers
+ * is a proxy function that calls the corresponding function in m_BoardSettings
+ * Returns a bit-mask of all the layers that are enabled
+ * @return int - the enabled layers in bit-mapped form.
+ */
+ LSET GetEnabledLayers() const;
+
+ /**
+ * Function SetEnabledLayers
+ * is a proxy function that calls the correspondent function in m_BoardSettings
+ * Changes the bit-mask of enabled layers
+ * @param aLayerMask = The new bit-mask of enabled layers
+ */
+ void SetEnabledLayers( LSET aLayerMask );
+
+ /**
+ * Function IsLayerEnabled
+ * is a proxy function that calls the correspondent function in m_BoardSettings
+ * tests whether a given layer is enabled
+ * @param aLayer = The layer to be tested
+ * @return bool - true if the layer is visible.
+ */
+ bool IsLayerEnabled( LAYER_ID aLayer ) const
+ {
+ return m_designSettings.IsLayerEnabled( aLayer );
+ }
+
+ /**
+ * Function IsLayerVisible
+ * is a proxy function that calls the correspondent function in m_BoardSettings
+ * tests whether a given layer is visible
+ * @param aLayer = The layer to be tested
+ * @return bool - true if the layer is visible.
+ */
+ bool IsLayerVisible( LAYER_ID aLayer ) const
+ {
+ return m_designSettings.IsLayerVisible( aLayer );
+ }
+
+ /**
+ * Function GetVisibleLayers
+ * is a proxy function that calls the correspondent function in m_BoardSettings
+ * Returns a bit-mask of all the layers that are visible
+ * @return int - the visible layers in bit-mapped form.
+ */
+ LSET GetVisibleLayers() const;
+
+ /**
+ * Function SetVisibleLayers
+ * is a proxy function that calls the correspondent function in m_BoardSettings
+ * changes the bit-mask of visible layers
+ * @param aLayerMask = The new bit-mask of visible layers
+ */
+ void SetVisibleLayers( LSET aLayerMask );
+
+ // these 2 functions are not tidy at this time, since there are PCB_VISIBLEs that
+ // are not stored in the bitmap.
+
+ /**
+ * Function GetVisibleElements
+ * is a proxy function that calls the correspondent function in m_BoardSettings
+ * returns a bit-mask of all the element categories that are visible
+ * @return int - the visible element bitmap or-ed from enum PCB_VISIBLE
+ * @see enum PCB_VISIBLE
+ */
+ int GetVisibleElements() const;
+
+ /**
+ * Function SetVisibleElements
+ * is a proxy function that calls the correspondent function in m_BoardSettings
+ * changes the bit-mask of visible element categories
+ * @param aMask = The new bit-mask of visible element bitmap or-ed from enum PCB_VISIBLE
+ * @see enum PCB_VISIBLE
+ */
+ void SetVisibleElements( int aMask );
+
+ /**
+ * Function SetVisibleAlls
+ * changes the bit-mask of visible element categories and layers
+ * @see enum PCB_VISIBLE
+ */
+ void SetVisibleAlls();
+
+ /**
+ * Function IsElementVisible
+ * tests whether a given element category is visible. Keep this as an
+ * inline function.
+ * @param aPCB_VISIBLE is from the enum by the same name
+ * @return bool - true if the element is visible.
+ * @see enum PCB_VISIBLE
+ */
+ bool IsElementVisible( int aPCB_VISIBLE ) const;
+
+ /**
+ * Function SetElementVisibility
+ * changes the visibility of an element category
+ * @param aPCB_VISIBLE is from the enum by the same name
+ * @param aNewState = The new visibility state of the element category
+ * @see enum PCB_VISIBLE
+ */
+ void SetElementVisibility( int aPCB_VISIBLE, bool aNewState );
+
+ /**
+ * Function IsModuleLayerVisible
+ * expects either of the two layers on which a module can reside, and returns
+ * whether that layer is visible.
+ * @param layer One of the two allowed layers for modules: F_Cu or B_Cu
+ * @return bool - true if the layer is visible, else false.
+ */
+ bool IsModuleLayerVisible( LAYER_ID layer );
+
+ /**
+ * Function GetVisibleElementColor
+ * returns the color of a pcb visible element.
+ * @see enum PCB_VISIBLE
+ */
+ EDA_COLOR_T GetVisibleElementColor( int aPCB_VISIBLE );
+
+ void SetVisibleElementColor( int aPCB_VISIBLE, EDA_COLOR_T aColor );
+
+ /**
+ * Function GetDesignSettings
+ * @return the BOARD_DESIGN_SETTINGS for this BOARD
+ */
+ BOARD_DESIGN_SETTINGS& GetDesignSettings() const
+ {
+ // remove const-ness with cast.
+ return (BOARD_DESIGN_SETTINGS&) m_designSettings;
+ }
+
+ /**
+ * Function SetDesignSettings
+ * @param aDesignSettings the new BOARD_DESIGN_SETTINGS to use
+ */
+ void SetDesignSettings( const BOARD_DESIGN_SETTINGS& aDesignSettings )
+ {
+ m_designSettings = aDesignSettings;
+ }
+
+ const PAGE_INFO& GetPageSettings() const { return m_paper; }
+ void SetPageSettings( const PAGE_INFO& aPageSettings ) { m_paper = aPageSettings; }
+
+ const PCB_PLOT_PARAMS& GetPlotOptions() const { return m_plotOptions; }
+ void SetPlotOptions( const PCB_PLOT_PARAMS& aOptions ) { m_plotOptions = aOptions; }
+
+ TITLE_BLOCK& GetTitleBlock() { return m_titles; }
+ void SetTitleBlock( const TITLE_BLOCK& aTitleBlock ) { m_titles = aTitleBlock; }
+
+ const ZONE_SETTINGS& GetZoneSettings() const { return m_zoneSettings; }
+ void SetZoneSettings( const ZONE_SETTINGS& aSettings ) { m_zoneSettings = aSettings; }
+
+ /**
+ * Function GetColorSettings
+ * @return the current COLORS_DESIGN_SETTINGS in use
+ */
+ COLORS_DESIGN_SETTINGS* GetColorsSettings() const { return m_colorsSettings; }
+
+ /**
+ * Function SetColorsSettings
+ * @param aColorsSettings = the new COLORS_DESIGN_SETTINGS to use
+ */
+ void SetColorsSettings( COLORS_DESIGN_SETTINGS* aColorsSettings )
+ {
+ m_colorsSettings = aColorsSettings;
+ }
+
+ /**
+ * Function GetBoardPolygonOutlines
+ * Extracts the board outlines and build a closed polygon
+ * from lines, arcs and circle items on edge cut layer
+ * Any closed outline inside the main outline is a hole
+ * All contours should be closed, i.e. have valid vertices to build a closed polygon
+ * @param aPoly The SHAPE_POLY_SET to fill in with outlines/holes.
+ * @param aErrorText = a wxString reference to display an error message
+ * with the coordinate of the point which creates the error
+ * (default = NULL , no message returned on error)
+ * @return true if success, false if a contour is not valid
+ */
+ bool GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines,
+ SHAPE_POLY_SET& aHoles,
+ wxString* aErrorText = NULL );
+
+ /**
+ * Function ConvertBrdLayerToPolygonalContours
+ * Build a set of polygons which are the outlines of copper items
+ * (pads, tracks, vias, texts, zones)
+ * Holes in vias or pads are ignored
+ * Usefull to export the shape of copper layers to dxf polygons
+ * or 3D viewer
+ * the polygons are not merged.
+ * @param aLayer = A copper layer, like B_Cu, etc.
+ * @param aOutlines The SHAPE_POLY_SET to fill in with items outline.
+ */
+ void ConvertBrdLayerToPolygonalContours( LAYER_ID aLayer, SHAPE_POLY_SET& aOutlines );
+
+ /**
+ * Function GetLayerID
+ * returns the ID of a layer given by aLayerName. Copper layers may
+ * have custom names.
+ *
+ * @param aLayerName = A layer name, like wxT("B.Cu"), etc.
+ *
+ * @return LAYER_ID - the layer id, which for copper layers may
+ * be custom, else standard.
+ */
+ const LAYER_ID GetLayerID( const wxString& aLayerName ) const;
+
+ /**
+ * Function GetLayerName
+ * returns the name of a layer given by aLayer. Copper layers may
+ * have custom names.
+ *
+ * @param aLayer = A layer, like B_Cu, etc.
+ *
+ * @return wxString - the layer name, which for copper layers may
+ * be custom, else standard.
+ */
+ const wxString GetLayerName( LAYER_ID aLayer ) const;
+
+ /**
+ * Function SetLayerName
+ * changes the name of the layer given by aLayer.
+ *
+ * @param aLayer A layer, like B_Cu, etc.
+ * @param aLayerName The new layer name
+ * @return bool - true if aLayerName was legal and unique among other
+ * layer names at other layer indices and aLayer was within range, else false.
+ */
+ bool SetLayerName( LAYER_ID aLayer, const wxString& aLayerName );
+
+ /**
+ * Function GetStandardLayerName
+ * returns an "English Standard" name of a PCB layer when given \a aLayerNumber.
+ * This function is static so it can be called without a BOARD instance. Use
+ * GetLayerName() if want the layer names of a specific BOARD, which could
+ * be different than the default if the user has renamed any copper layers.
+ *
+ * @param aLayerId is the layer identifier (index) to fetch
+ * @return const wxString - containing the layer name or "BAD INDEX" if aLayerId
+ * is not legal
+ */
+ static const wxString GetStandardLayerName( LAYER_ID aLayerId )
+ {
+ // a BOARD's standard layer name is the LAYER_ID fixed name
+ return LSET::Name( aLayerId );
+ }
+
+ /**
+ * Function SetLayerDescr
+ * returns the type of the copper layer given by aLayer.
+ *
+ * @param aIndex A layer index in m_Layer
+ * @param aLayer A reference to a LAYER description.
+ * @return false if the index was out of range.
+ */
+ bool SetLayerDescr( LAYER_ID aIndex, const LAYER& aLayer );
+
+ /**
+ * Function GetLayerType
+ * returns the type of the copper layer given by aLayer.
+ *
+ * @param aLayer A layer index, like B_Cu, etc.
+ * @return LAYER_T - the layer type, or LAYER_T(-1) if the
+ * index was out of range.
+ */
+ LAYER_T GetLayerType( LAYER_ID aLayer ) const;
+
+ /**
+ * Function SetLayerType
+ * changes the type of the layer given by aLayer.
+ *
+ * @param aLayer A layer index, like B_Cu, etc.
+ * @param aLayerType The new layer type.
+ * @return bool - true if aLayerType was legal and aLayer was within range, else false.
+ */
+ bool SetLayerType( LAYER_ID aLayer, LAYER_T aLayerType );
+
+ /**
+ * Function SetLayerColor
+ * changes a layer color for any valid layer, including non-copper ones.
+ */
+ void SetLayerColor( LAYER_ID aLayer, EDA_COLOR_T aColor );
+
+ /**
+ * Function GetLayerColor
+ * gets a layer color for any valid layer, including non-copper ones.
+ */
+ EDA_COLOR_T GetLayerColor( LAYER_ID aLayer ) const;
+
+ /** Functions to get some items count */
+ int GetNumSegmTrack() const;
+
+ /** Calculate the zone segment count */
+ int GetNumSegmZone() const;
+
+ /**
+ * Function GetNumRatsnests
+ * @return int - The number of rats
+ */
+ unsigned GetRatsnestsCount() const
+ {
+ return m_FullRatsnest.size();
+ }
+
+ /**
+ * Function GetNodesCount
+ * @return the number of pads members of nets (i.e. with netcode > 0)
+ */
+ unsigned GetNodesCount() const;
+
+ /**
+ * Function SetNodeCount
+ * set the number of nodes of the current net to \a aCount.
+ *
+ * @param aCount is the number of nodes attached to the current net.
+ */
+ void SetNodeCount( unsigned aCount ) { m_nodeCount = aCount; }
+
+ /**
+ * Function GetUnconnectedNetCount
+ * @return the number of unconnected nets in the current rats nest.
+ */
+ unsigned GetUnconnectedNetCount() const { return m_unconnectedNetCount; }
+
+ /**
+ * Function SetUnconnectedNetCount
+ * sets the number of unconnected nets in the current rats nest to \a aCount.
+ *
+ * @param aCount is the number of unconneceted nets in the current rats nest.
+ */
+ void SetUnconnectedNetCount( unsigned aCount ) { m_unconnectedNetCount = aCount; }
+
+ /**
+ * Function GetPadCount
+ * @return the number of pads in board
+ */
+ unsigned GetPadCount() const
+ {
+ return m_NetInfo.GetPadCount();
+ }
+
+ /**
+ * Function GetPad
+ * @return D_PAD* - at the \a aIndex from m_NetInfo
+ */
+ D_PAD* GetPad( unsigned aIndex ) const
+ {
+ return m_NetInfo.GetPad( aIndex );
+ }
+
+ /**
+ * Function GetPads
+ * returns a list of all the pads by value. The returned list is not
+ * sorted and contains pointers to PADS, but those pointers do not convey
+ * ownership of the respective PADs.
+ * @return std::vector<D_PAD*> - a full list of pads
+ */
+ std::vector<D_PAD*> GetPads()
+ {
+ return m_NetInfo.m_PadsFullList;
+ }
+
+ void BuildListOfNets()
+ {
+ m_NetInfo.buildListOfNets();
+ }
+
+ /**
+ * Function FindNet
+ * searches for a net with the given netcode.
+ * @param aNetcode A netcode to search for.
+ * @return NETINFO_ITEM_ITEM* - the net or NULL if not found.
+ */
+ NETINFO_ITEM* FindNet( int aNetcode ) const;
+
+ /**
+ * Function FindNet overloaded
+ * searches for a net with the given name.
+ * @param aNetname A Netname to search for.
+ * @return NETINFO_ITEM* - the net or NULL if not found.
+ */
+ NETINFO_ITEM* FindNet( const wxString& aNetname ) const;
+
+ /**
+ * Function AppendNet
+ * adds a new net description item to the current board.
+ * @param aNewNet is the new description item.
+ */
+ void AppendNet( NETINFO_ITEM* aNewNet )
+ {
+ m_NetInfo.AppendNet( aNewNet );
+ }
+
+#ifndef SWIG
+ /**
+ * Function BeginNets
+ * @return iterator to the first element of the NETINFO_ITEMs list
+ */
+ NETINFO_LIST::iterator BeginNets() const
+ {
+ return m_NetInfo.begin();
+ }
+
+ /**
+ * Function EndNets
+ * @return iterator to the last element of the NETINFO_ITEMs list
+ */
+ NETINFO_LIST::iterator EndNets() const
+ {
+ return m_NetInfo.end();
+ }
+#endif
+
+ /**
+ * Function GetNetCount
+ * @return the number of nets (NETINFO_ITEM)
+ */
+ unsigned GetNetCount() const
+ {
+ return m_NetInfo.GetNetCount();
+ }
+
+ /**
+ * Function ComputeBoundingBox
+ * calculates the bounding box containing all board items (or board edge segments).
+ * @param aBoardEdgesOnly is true if we are interested in board edge segments only.
+ * @return EDA_RECT - the board's bounding box
+ * @see PCB_BASE_FRAME::GetBoardBoundingBox() which calls this and doctors the result
+ */
+ EDA_RECT ComputeBoundingBox( bool aBoardEdgesOnly = false );
+
+ /**
+ * Function GetBoundingBox
+ * may be called soon after ComputeBoundingBox() to return the same EDA_RECT,
+ * as long as the BOARD has not changed. Remember, ComputeBoundingBox()'s
+ * aBoardEdgesOnly argument is considered in this return value also.
+ */
+ const EDA_RECT GetBoundingBox() const { return m_BoundingBox; } // override
+
+ void SetBoundingBox( const EDA_RECT& aBox ) { m_BoundingBox = aBox; }
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ /**
+ * Function Draw.
+ * Redraw the BOARD items but not cursors, axis or grid.
+ * @param aPanel = the panel relative to the board
+ * @param aDC = the current device context
+ * @param aDrawMode = GR_COPY, GR_OR ... (not always used)
+ * @param aOffset = an draw offset value (default = 0,0)
+ */
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset );
+
+ /**
+ * Function DrawHighLight
+ * redraws the objects in the board that are associated with the given aNetCode
+ * and turns on or off the brilliance associated with that net according to the
+ * current value of global g_HighLight_Status
+ * @param aDrawPanel is needed for the clipping support.
+ * @param aDC = the current device context
+ * @param aNetCode is the net number to highlight or to dim.
+ */
+ void DrawHighLight( EDA_DRAW_PANEL* aDrawPanel, wxDC* aDC, int aNetCode );
+
+ /**
+ * Function Visit
+ * may be re-implemented for each derived class in order to handle
+ * all the types given by its member data. Implementations should call
+ * inspector->Inspect() on types in scanTypes[], and may use IterateForward()
+ * to do so on lists of such data.
+ * @param inspector An INSPECTOR instance to use in the inspection.
+ * @param testData Arbitrary data used by the inspector.
+ * @param scanTypes Which KICAD_T types are of interest and the order
+ * is significant too, terminated by EOT.
+ * @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
+ * else SCAN_CONTINUE, and determined by the inspector.
+ */
+ SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
+ const KICAD_T scanTypes[] );
+
+ /**
+ * Function FindModuleByReference
+ * searches for a MODULE within this board with the given
+ * reference designator. Finds only the first one, if there
+ * is more than one such MODULE.
+ * @param aReference The reference designator of the MODULE to find.
+ * @return MODULE* - If found, the MODULE having the given reference
+ * designator, else NULL.
+ */
+ MODULE* FindModuleByReference( const wxString& aReference ) const;
+
+ /**
+ * Function FindModule
+ * searches for a module matching \a aRefOrTimeStamp depending on the state of
+ * \a aSearchByTimeStamp.
+ * @param aRefOrTimeStamp is the search string.
+ * @param aSearchByTimeStamp searches by the module time stamp value if true. Otherwise
+ * search by reference designator.
+ * @return MODULE* - If found, the module meeting the search criteria, else NULL.
+ */
+ MODULE* FindModule( const wxString& aRefOrTimeStamp, bool aSearchByTimeStamp = false ) const;
+
+ /**
+ * Function ReplaceNetlist
+ * updates the #BOARD according to \a aNetlist.
+ *
+ * The changes are made to the board are as follows they are not disabled in the status
+ * settings in the #NETLIST:
+ * - If a new component is found in the #NETLIST and not in the #BOARD, it is added
+ * to the #BOARD.
+ * - If a the component in the #NETLIST is already on the #BOARD, then one or more of the
+ * following actions can occur:
+ * + If the footprint name in the #NETLIST does not match the footprint name on the
+ * #BOARD, the footprint on the #BOARD is replaced with the footprint specified in
+ * the #NETLIST and the proper parameters are copied from the existing footprint.
+ * + If the reference designator in the #NETLIST does not match the reference designator
+ * on the #BOARD, the reference designator is updated from the #NETLIST.
+ * + If the value field in the #NETLIST does not match the value field on the #BOARD,
+ * the value field is updated from the #NETLIST.
+ * + If the time stamp in the #NETLIST does not match the time stamp on the #BOARD,
+ * the time stamp is updated from the #NETLIST.
+ * - After each footprint is added or update as described above, each footprint pad net
+ * name is compared and updated to the value defined in the #NETLIST.
+ * - After all of the footprints have been added, updated, and net names properly set,
+ * any extra unlock footprints are removed from the #BOARD.
+ *
+ * @param aNetlist is the new netlist to revise the contents of the #BOARD with.
+ * @param aDeleteSinglePadNets if true, remove nets counting only one pad
+ * and set net code to 0 for these pads
+ * @param aReporter is a #REPORTER object to report the changes \a aNetlist makes to
+ * the #BOARD. If NULL, no change reporting occurs.
+ */
+ void ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
+ REPORTER* aReporter = NULL );
+
+ /**
+ * Function SortedNetnamesList
+ * @param aNames An array string to fill with net names.
+ * @param aSortbyPadsCount true = sort by active pads count, false = no sort (i.e.
+ * leave the sort by net names)
+ * @return int - net names count.
+ */
+ int SortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount );
+
+ /**
+ * Function SynchronizeNetsAndNetClasses
+ * copies NETCLASS info to each NET, based on NET membership in a NETCLASS.
+ * Must be called after a Design Rules edition, or after reading a netlist (or editing
+ * the list of nets) Also this function removes the non existing nets in netclasses
+ * and add net nets in default netclass (this happens after reading a netlist)
+ */
+ void SynchronizeNetsAndNetClasses();
+
+ /***************************************************************************/
+
+ wxString GetClass() const
+ {
+ return wxT( "BOARD" );
+ }
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+
+
+ /*************************/
+ /* Copper Areas handling */
+ /*************************/
+
+ /**
+ * Function HitTestForAnyFilledArea
+ * tests if the given wxPoint is within the bounds of a filled area of this zone.
+ * the test is made on zones on layer from aStartLayer to aEndLayer
+ * Note: if a zone has its flag BUSY (in .m_State) is set, it is ignored.
+ * @param aRefPos A wxPoint to test
+ * @param aStartLayer the first layer to test
+ * @param aEndLayer the last layer to test
+ * @param aNetCode = the netcode used to filter zones (-1 to to test all zones)
+ * @return ZONE_CONTAINER* return a pointer to the ZONE_CONTAINER found, else NULL
+ */
+ ZONE_CONTAINER* HitTestForAnyFilledArea( const wxPoint& aRefPos,
+ LAYER_ID aStartLayer,
+ LAYER_ID aEndLayer,
+ int aNetCode );
+
+ /**
+ * Function RedrawAreasOutlines
+ * Redraw all areas outlines on layer aLayer ( redraw all if aLayer < 0 )
+ */
+ void RedrawAreasOutlines( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC,
+ GR_DRAWMODE aDrawMode,
+ LAYER_ID aLayer );
+
+ /**
+ * Function RedrawFilledAreas
+ * Redraw all filled areas on layer aLayer ( redraw all if aLayer < 0 )
+ */
+ void RedrawFilledAreas( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
+ LAYER_ID aLayer );
+
+ /**
+ * Function SetAreasNetCodesFromNetNames
+ * Set the .m_NetCode member of all copper areas, according to the area Net Name
+ * The SetNetCodesFromNetNames is an equivalent to net name, for fast comparisons.
+ * However the Netcode is an arbitrary equivalence, it must be set after each netlist read
+ * or net change
+ * Must be called after pad netcodes are calculated
+ * @return : error count
+ * For non copper areas, netcode is set to 0
+ */
+ int SetAreasNetCodesFromNetNames( void );
+
+ /**
+ * Function GetArea
+ * returns the Area (Zone Container) at a given index.
+ * @param index The array type index into a collection of ZONE_CONTAINER *.
+ * @return ZONE_CONTAINER* - a pointer to the Area or NULL if index out of range.
+ */
+ ZONE_CONTAINER* GetArea( int index ) const
+ {
+ if( (unsigned) index < m_ZoneDescriptorList.size() )
+ return m_ZoneDescriptorList[index];
+
+ return NULL;
+ }
+
+ /**
+ * Function GetAreaIndex
+ * returns the Area Index for the given Zone Container.
+ * @param aArea :The ZONE_CONTAINER to find.
+ * @return an Area Index in m_ZoneDescriptorList or -1 if non found.
+ */
+ int GetAreaIndex( const ZONE_CONTAINER* aArea ) const
+ {
+ for( int ii = 0; ii < GetAreaCount(); ii++ ) // Search for aArea in list
+ {
+ if( aArea == GetArea( ii ) ) // Found !
+ return ii;
+ }
+
+ return -1;
+ }
+
+ /**
+ * Function GetAreaCount
+ * @return int - The number of Areas or ZONE_CONTAINER.
+ */
+ int GetAreaCount() const
+ {
+ return (int) m_ZoneDescriptorList.size();
+ }
+
+ /* Functions used in test, merge and cut outlines */
+
+ /**
+ * Function AddArea
+ * Add an empty copper area to board areas list
+ * @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new areas pickers (useful
+ * in undo commands) can be NULL
+ * @param aNetcode = the netcode of the copper area (0 = no net)
+ * @param aLayer = the layer of area
+ * @param aStartPointPosition = position of the first point of the polygon outline of this area
+ * @param aHatch = hatch option
+ * @return a reference to the new area
+ */
+ ZONE_CONTAINER* AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode,
+ LAYER_ID aLayer, wxPoint aStartPointPosition, int aHatch );
+
+ /**
+ * Function InsertArea
+ * add empty copper area to net, inserting after m_ZoneDescriptorList[iarea]
+ * @return pointer to the new area
+ */
+ ZONE_CONTAINER* InsertArea( int netcode, int iarea, LAYER_ID layer, int x, int y, int hatch );
+
+ /**
+ * Function NormalizeAreaPolygon
+ * Process an area that has been modified, by normalizing its polygon against itself.
+ * i.e. convert a self-intersecting polygon to one (or more) non self-intersecting polygon(s)
+ * This may change the number and order of copper areas in the net.
+ * @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new created areas pickers
+ * @param aCurrArea = the zone to process
+ * @return true if changes are made
+ */
+ bool NormalizeAreaPolygon( PICKED_ITEMS_LIST* aNewZonesList, ZONE_CONTAINER* aCurrArea );
+
+ /**
+ * Function OnAreaPolygonModified
+ * Process an area that has been modified, by normalizing its polygon
+ * and merging the intersecting polygons for any other areas on the same net.
+ * This may change the number and order of copper areas in the net.
+ * @param aModifiedZonesList = a PICKED_ITEMS_LIST * where to store deleted or added areas
+ * (useful in undo commands can be NULL
+ * @param modified_area = area to test
+ * @return true if some areas modified
+ */
+ bool OnAreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList,
+ ZONE_CONTAINER* modified_area );
+
+ /**
+ * Function CombineAllAreasInNet
+ * Checks all copper areas in net for intersections, combining them if found
+ * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful
+ * in undo commands can be NULL
+ * @param aNetCode = net to consider
+ * @param aUseLocalFlags : if true, don't check areas if both local flags are 0
+ * Sets local flag = 1 for any areas modified
+ * @return true if some areas modified
+ */
+ bool CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList,
+ int aNetCode,
+ bool aUseLocalFlags );
+
+ /**
+ * Function RemoveArea
+ * remove copper area from net, and put it in a deleted list (if exists)
+ * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful
+ * in undo commands can be NULL
+ * @param area_to_remove = area to delete or put in deleted list
+ */
+ void RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to_remove );
+
+ /**
+ * Function TestAreaIntersections
+ * Check for intersection of a given copper area with other areas in same net
+ * @param area_to_test = area to compare to all other areas in the same net
+ */
+ bool TestAreaIntersections( ZONE_CONTAINER* area_to_test );
+
+ /**
+ * Function TestAreaIntersection
+ * Test for intersection of 2 copper areas
+ * area_to_test must be after area_ref in m_ZoneDescriptorList
+ * @param area_ref = area reference
+ * @param area_to_test = area to compare for intersection calculations
+ * @return : false if no intersection, true if intersection
+ */
+ bool TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test );
+
+ /**
+ * Function CombineAreas
+ * If possible, combine 2 copper areas
+ * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas
+ * (useful for undo).
+ * @param area_ref = the main area (zone)
+ * @param area_to_combine = the zone that can be merged with area_ref
+ * area_ref must be BEFORE area_to_combine
+ * area_to_combine will be deleted, if areas are combined
+ * @return : true if area_to_combine is combined with area_ref (and therefore be deleted)
+ */
+ bool CombineAreas( PICKED_ITEMS_LIST* aDeletedList,
+ ZONE_CONTAINER* area_ref,
+ ZONE_CONTAINER* area_to_combine );
+
+ /**
+ * Function Test_Drc_Areas_Outlines_To_Areas_Outlines
+ * tests area outlines for DRC:
+ * Tests areas inside other areas.
+ * Tests areas too close.
+ *
+ * @param aArea_To_Examine: area to compare with other areas, or if NULL then
+ * all areas are compared to all others.
+ * @param aCreate_Markers: if true create DRC markers. False: do not creates anything
+ * @return errors count
+ */
+ int Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine,
+ bool aCreate_Markers );
+
+ /****** function relative to ratsnest calculations: */
+
+ /**
+ * Function Test_Connection_To_Copper_Areas
+ * init .m_ZoneSubnet parameter in tracks and pads according to the connections to areas found
+ * @param aNetcode = netcode to analyze. if -1, analyze all nets
+ */
+ void Test_Connections_To_Copper_Areas( int aNetcode = -1 );
+
+ /**
+ * Function GetViaByPosition
+ * finds the first via at \a aPosition on \a aLayer.
+ * <p>
+ * This function does not use the normal hit test to locate a via which which tests
+ * if a position is within the via's bounding box. It tests for the actual locate
+ * of the via.
+ * </p>
+ * @param aPosition The wxPoint to HitTest() against.
+ * @param aLayer The layer to search. Use -1 for a don't care.
+ * @return VIA* A point a to the VIA object if found, else NULL.
+ */
+ VIA* GetViaByPosition( const wxPoint& aPosition, LAYER_ID aLayer = UNDEFINED_LAYER ) const;
+
+ /**
+ * Function GetPad
+ * finds a pad \a aPosition on \a aLayer.
+ *
+ * @param aPosition A wxPoint object containing the position to hit test.
+ * @param aLayerMask A layer or layers to mask the hit test.
+ * @return A pointer to a D_PAD object if found or NULL if not found.
+ */
+ D_PAD* GetPad( const wxPoint& aPosition, LSET aLayerMask );
+ D_PAD* GetPad( const wxPoint& aPosition )
+ {
+ return GetPad( aPosition, LSET().set() );
+ }
+
+ /**
+ * Function GetPad
+ * finds a pad connected to \a aEndPoint of \a aTrace.
+ *
+ * @param aTrace A pointer to a TRACK object to hit test against.
+ * @param aEndPoint The end point of \a aTrace the hit test against.
+ * @return A pointer to a D_PAD object if found or NULL if not found.
+ */
+ D_PAD* GetPad( TRACK* aTrace, ENDPOINT_T aEndPoint );
+
+ /**
+ * Function GetPadFast
+ * return pad found at \a aPosition on \a aLayerMask using the fast search method.
+ * <p>
+ * The fast search method only works if the pad list has already been built.
+ * </p>
+ * @param aPosition A wxPoint object containing the position to hit test.
+ * @param aLayerMask A layer or layers to mask the hit test.
+ * @return A pointer to a D_PAD object if found or NULL if not found.
+ */
+ D_PAD* GetPadFast( const wxPoint& aPosition, LSET aLayerMask );
+
+ /**
+ * Function GetPad
+ * locates the pad connected at \a aPosition on \a aLayer starting at list position
+ * \a aPad
+ * <p>
+ * This function uses a fast search in this sorted pad list and it is faster than
+ * GetPadFast(). This list is a sorted pad list must be built before calling this
+ * function.
+ * </p>
+ * @note The normal pad list is sorted by increasing netcodes.
+ * @param aPadList = the list of pads candidates (a std::vector<D_PAD*>)
+ * @param aPosition A wxPoint object containing the position to test.
+ * @param aLayerMask A layer or layers to mask the hit test.
+ * @return a D_PAD object pointer to the connected pad.
+ */
+ D_PAD* GetPad( std::vector<D_PAD*>& aPadList, const wxPoint& aPosition, LSET aLayerMask );
+
+ /**
+ * Function PadDelete
+ * deletes a given bad from the BOARD by removing it from its module and
+ * from the m_NetInfo. Makes no UI calls.
+ * @param aPad is the pad to delete.
+ */
+ void PadDelete( D_PAD* aPad );
+
+ /**
+ * Function GetSortedPadListByXthenYCoord
+ * first empties then fills the vector with all pads and sorts them by
+ * increasing x coordinate, and for increasing y coordinate for same values of x coordinates.
+ * The vector only holds pointers to the pads and
+ * those pointers are only references to pads which are owned by the BOARD
+ * through other links.
+ * @param aVector Where to put the pad pointers.
+ * @param aNetCode = the netcode filter:
+ * = -1 to build the full pad list.
+ * = a given netcode to build the pad list relative to the given net
+ */
+ void GetSortedPadListByXthenYCoord( std::vector<D_PAD*>& aVector, int aNetCode = -1 );
+
+ /**
+ * Function GetTrack
+ * find the segment of \a aTrace at \a aPosition on \a aLayer if \a Layer is visible.
+ * Traces that are flagged as deleted or busy are ignored.
+ *
+ * @param aTrace A pointer to the TRACK object to search.
+ * @param aPosition A wxPoint object containing the position to test.
+ * @param aLayerMask A layer or layers to mask the hit test. Use -1 to ignore
+ * layer mask.
+ * @return A TRACK object pointer if found otherwise NULL.
+ */
+ TRACK* GetTrack( TRACK* aTrace, const wxPoint& aPosition, LSET aLayerMask ) const;
+
+ /**
+ * Function MarkTrace
+ * marks a chain of trace segments, connected to \a aTrace.
+ * <p>
+ * Each segment is marked by setting the BUSY bit into m_Flags. Electrical
+ * continuity is detected by walking each segment, and finally the segments
+ * are rearranged into a contiguous chain within the given list.
+ * </p>
+ *
+ * @param aTrace The segment within a list of trace segments to test.
+ * @param aCount A pointer to an integer where to return the number of
+ * marked segments.
+ * @param aTraceLength A pointer to an double where to return the length of the
+ * trace.
+ * @param aInPackageLength A pointer to an double where to return the extra lengths inside
+ * integrated circuits from the pads connected to this track to the
+ * die (if any).
+ * @param aReorder true for reorder the interesting segments (useful for
+ * track edition/deletion) in this case the flag BUSY is
+ * set (the user is responsible of flag clearing). False
+ * for no reorder : useful when we want just calculate the
+ * track length in this case, flags are reset
+ * @return TRACK* The first in the chain of interesting segments.
+ */
+ TRACK* MarkTrace( TRACK* aTrace, int* aCount, double* aTraceLength,
+ double* aInPackageLength, bool aReorder );
+
+ /**
+ * Function GetFootprint
+ * get a footprint by its bounding rectangle at \a aPosition on \a aLayer.
+ * <p>
+ * If more than one footprint is at \a aPosition, then the closest footprint on the
+ * active layer is returned. The distance is calculated via manhattan distance from
+ * the center of the bounding rectangle to \a aPosition.
+ *
+ * @param aPosition A wxPoint object containing the position to test.
+ * @param aActiveLayer Layer to test.
+ * @param aVisibleOnly Search only the visible layers if true.
+ * @param aIgnoreLocked Ignore locked modules when true.
+ * @return MODULE* The best module or NULL if none.
+ */
+ MODULE* GetFootprint( const wxPoint& aPosition, LAYER_ID aActiveLayer,
+ bool aVisibleOnly, bool aIgnoreLocked = false );
+
+ /**
+ * Function GetLockPoint
+ * returns the item at the "attachment" point at the end of a trace at \a aPosition
+ * on \a aLayerMask.
+ * <p>
+ * This may be a PAD or another trace segment.
+ * </p>
+ *
+ * @param aPosition A wxPoint object containing the position to test.
+ * @param aLayerMask A layer or layers to mask the hit test. Use -1 to ignore
+ * layer mask.
+ * @return A pointer to a BOARD_ITEM object if found otherwise NULL.
+ */
+ BOARD_CONNECTED_ITEM* GetLockPoint( const wxPoint& aPosition, LSET aLayerMask );
+
+ /**
+ * Function CreateLockPoint
+ * creates an intermediate point on \a aSegment and break it into two segments
+ * at \a aPosition.
+ * <p>
+ * The new segment starts from \a aPosition and ends at the end point of \a
+ * aSegment. The original segment now ends at \a aPosition.
+ * </p>
+ *
+ * @param aPosition A wxPoint object containing the position to test and the new
+ * segment start position if the return value is not NULL.
+ * @param aSegment The trace segment to create the lock point on.
+ * @param aList The pick list to add the created items to.
+ * @return NULL if no new point was created or a pointer to a TRACK ojbect of the
+ * created segment. If \a aSegment points to a via the exact value of \a
+ * aPosition and a pointer to the via are returned.
+ */
+ TRACK* CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS_LIST* aList );
+};
+
+#endif // CLASS_BOARD_H_
diff --git a/pcbnew/class_board_connected_item.cpp b/pcbnew/class_board_connected_item.cpp
new file mode 100644
index 0000000..1666674
--- /dev/null
+++ b/pcbnew/class_board_connected_item.cpp
@@ -0,0 +1,144 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_board_connected_item.cpp
+ * @brief BOARD_CONNECTED_ITEM class functions.
+ */
+
+#include <fctsys.h>
+#include <pcbnew.h>
+
+#include <class_board.h>
+#include <class_board_item.h>
+
+BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) :
+ BOARD_ITEM( aParent, idtype ), m_netinfo( &NETINFO_LIST::ORPHANED ),
+ m_Subnet( 0 ), m_ZoneSubnet( 0 )
+{
+}
+
+
+BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem ) :
+ BOARD_ITEM( aItem ), m_netinfo( aItem.m_netinfo ), m_Subnet( aItem.m_Subnet ),
+ m_ZoneSubnet( aItem.m_ZoneSubnet )
+{
+}
+
+
+bool BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode, bool aNoAssert )
+{
+ // if aNetCode < 0 ( typically NETINFO_LIST::FORCE_ORPHANED )
+ // or no parent board,
+ // set the m_netinfo to the dummy NETINFO_LIST::ORPHANED
+
+ BOARD* board = GetBoard();
+
+ if( ( aNetCode >= 0 ) && board )
+ m_netinfo = board->FindNet( aNetCode );
+ else
+ m_netinfo = &NETINFO_LIST::ORPHANED;
+
+ if( !aNoAssert )
+ assert( m_netinfo );
+
+ return ( m_netinfo != NULL );
+}
+
+
+int BOARD_CONNECTED_ITEM::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
+{
+ NETCLASSPTR myclass = GetNetClass();
+
+ // DO NOT use wxASSERT, because GetClearance is called inside an OnPaint event
+ // and a call to wxASSERT can crash the application.
+ if( myclass )
+ {
+ int myClearance = myclass->GetClearance();
+ // @todo : after GetNetClass() is reliably not returning NULL, remove the
+ // tests for if( myclass )
+
+ if( aItem )
+ {
+ int hisClearance = aItem->GetClearance();
+ return std::max( hisClearance, myClearance );
+ }
+
+ return myClearance;
+ }
+ else
+ {
+ DBG(printf( "%s: NULL netclass,type %d", __func__, Type() );)
+ }
+
+ return 0;
+}
+
+
+NETCLASSPTR BOARD_CONNECTED_ITEM::GetNetClass() const
+{
+ // It is important that this be implemented without any sequential searching.
+ // Simple array lookups should be fine, performance-wise.
+ BOARD* board = GetBoard();
+
+ // DO NOT use wxASSERT, because GetNetClass is called inside an OnPaint event
+ // and a call to wxASSERT can crash the application.
+
+ if( board == NULL ) // Should not occur
+ {
+ DBG(printf( "%s: NULL board,type %d", __func__, Type() );)
+
+ return NETCLASSPTR();
+ }
+
+ NETCLASSPTR netclass;
+ NETINFO_ITEM* net = board->FindNet( GetNetCode() );
+
+ if( net )
+ {
+ netclass = net->GetNetClass();
+
+ //DBG( if(!netclass) printf( "%s: NULL netclass,type %d", __func__, Type() );)
+ }
+
+ if( netclass )
+ return netclass;
+ else
+ return board->GetDesignSettings().GetDefault();
+}
+
+
+wxString BOARD_CONNECTED_ITEM::GetNetClassName() const
+{
+ wxString name;
+ NETCLASSPTR myclass = GetNetClass();
+
+ if( myclass )
+ name = myclass->GetName();
+ else
+ name = NETCLASS::Default;
+
+ return name;
+}
diff --git a/pcbnew/class_board_connected_item.h b/pcbnew/class_board_connected_item.h
new file mode 100644
index 0000000..fea4554
--- /dev/null
+++ b/pcbnew/class_board_connected_item.h
@@ -0,0 +1,310 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_board_connected_item.h
+ * @brief Class BOARD_CONNECTED_ITEM.
+ */
+
+#ifndef BOARD_CONNECTED_ITEM_H
+#define BOARD_CONNECTED_ITEM_H
+
+#include <class_board_item.h>
+#include <class_netinfo.h>
+
+class NETCLASS;
+class TRACK;
+class D_PAD;
+
+/**
+ * Class BOARD_CONNECTED_ITEM
+ * is a base class derived from BOARD_ITEM for items that can be connected
+ * and have a net, a netname, a clearance ...
+ * mainly: tracks, pads and zones
+ * Handle connection info
+ */
+class BOARD_CONNECTED_ITEM : public BOARD_ITEM
+{
+ friend class CONNECTIONS;
+
+public:
+ // These 2 members are used for temporary storage during connections calculations:
+ std::vector<TRACK*> m_TracksConnected; // list of other tracks connected to me
+ std::vector<D_PAD*> m_PadsConnected; // list of other pads connected to me
+
+ BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype );
+
+ BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem );
+
+ static inline bool ClassOf( const EDA_ITEM* aItem )
+ {
+ if( aItem == NULL )
+ return false;
+
+ switch( aItem->Type() )
+ {
+ case PCB_PAD_T:
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ case PCB_ZONE_AREA_T:
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ ///> @copydoc BOARD_ITEM::IsConnected()
+ bool IsConnected() const
+ {
+ return true;
+ }
+
+ /**
+ * Function GetNet
+ * Returns NET_INFO object for a given item.
+ */
+ NETINFO_ITEM* GetNet() const
+ {
+ return m_netinfo;
+ }
+
+ /**
+ * Function GetNetCode
+ * @return int - the net code.
+ */
+ int GetNetCode() const
+ {
+ return m_netinfo->GetNet();
+ }
+
+ /**
+ * Function SetNetCode
+ * sets net using a net code.
+ * @param aNetCode is a net code for the new net. It has to exist in NETINFO_LIST held by BOARD.
+ * @param aNoAssert if true, do not assert that the net exists.
+ * Otherwise, item is assigned to the unconnected net.
+ * @return true on success, false if the net did not exist
+ */
+ bool SetNetCode( int aNetCode, bool aNoAssert=false );
+
+ /**
+ * Function GetSubNet
+ * @return int - the sub net code.
+ */
+ int GetSubNet() const
+ {
+ return m_Subnet;
+ }
+
+ void SetSubNet( int aSubNetCode )
+ {
+ m_Subnet = aSubNetCode;
+ }
+
+ /**
+ * Function GetZoneSubNet
+ * @return int - the sub net code in zone connections.
+ */
+ int GetZoneSubNet() const
+ {
+ return m_ZoneSubnet;
+ }
+
+ void SetZoneSubNet( int aSubNetCode )
+ {
+ m_ZoneSubnet = aSubNetCode;
+ }
+
+ /**
+ * Function GetNetname
+ * @return wxString - the full netname
+ */
+ const wxString& GetNetname() const
+ {
+ return m_netinfo->GetNetname();
+ }
+
+ /**
+ * Function GetShortNetname
+ * @return wxString - the short netname
+ */
+ const wxString& GetShortNetname() const
+ {
+ return m_netinfo->GetShortNetname();
+ }
+
+ /**
+ * Function GetClearance
+ * returns the clearance in 1/10000 inches. If \a aItem is not NULL then the
+ * returned clearance is the greater of this object's NETCLASS clearance and
+ * aItem's NETCLASS clearance. If \a aItem is NULL, then this objects clearance
+ * is returned.
+ * @param aItem is another BOARD_CONNECTED_ITEM or NULL
+ * @return int - the clearance in 1/10000 inches.
+ */
+ virtual int GetClearance( BOARD_CONNECTED_ITEM* aItem = NULL ) const;
+
+ /**
+ * Function GetNetClass
+ * returns the NETCLASS for this item.
+ */
+ boost::shared_ptr<NETCLASS> GetNetClass() const;
+
+ /**
+ * Function GetNetClassName
+ * returns a pointer to the netclass of the zone.
+ * If the net is not found (can happen when a netlist is reread,
+ * and the net name does not exist, return the default net class
+ * (should not return a null pointer).
+ * @return the Net Class name of this item
+ */
+ wxString GetNetClassName() const;
+
+protected:
+ /// Stores all informations about the net that item belongs to
+ NETINFO_ITEM* m_netinfo;
+
+private:
+ int m_Subnet; /* In rastnest routines : for the current net, block number
+ * (number common to the current connected items found)
+ */
+
+ int m_ZoneSubnet; // used in rastnest computations : for the current net,
+ // handle cluster number in zone connection
+};
+
+
+#if 0 // template for future
+/**
+ * Class BOARD_ITEM_LIST
+ * is a container for a list of BOARD_ITEMs.
+ */
+class BOARD_ITEM_LIST : public BOARD_ITEM
+{
+ typedef boost::ptr_vector<BOARD_ITEM> ITEM_ARRAY;
+
+ ITEM_ARRAY myItems;
+
+ BOARD_ITEM_LIST( const BOARD_ITEM_LIST& other ) :
+ BOARD_ITEM( NULL, PCB_ITEM_LIST_T )
+ {
+ // copy constructor is not supported, is private to cause compiler error
+ }
+
+public:
+
+ BOARD_ITEM_LIST( BOARD_ITEM* aParent = NULL ) :
+ BOARD_ITEM( aParent, PCB_ITEM_LIST_T )
+ {}
+
+ //-----< satisfy some virtual functions >------------------------------
+ const wxPoint GetPosition()
+ {
+ return wxPoint(0, 0); // dummy
+ }
+
+ void Draw( EDA_DRAW_PANEL* DrawPanel, wxDC* DC,
+ GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset )
+ {
+ }
+
+ void UnLink()
+ {
+ /* if it were needed:
+ DHEAD* list = GetList();
+
+ wxASSERT( list );
+
+ list->remove( this );
+ */
+ }
+
+ //-----</ satisfy some virtual functions >-----------------------------
+
+ /**
+ * Function GetCount
+ * returns the number of BOARD_ITEMs.
+ */
+ int GetCount() const
+ {
+ return myItems.size();
+ }
+
+ void Append( BOARD_ITEM* aItem )
+ {
+ myItems.push_back( aItem );
+ }
+
+ BOARD_ITEM* Replace( int aIndex, BOARD_ITEM* aItem )
+ {
+ ITEM_ARRAY::auto_type ret = myItems.replace( aIndex, aItem );
+ return ret.release();
+ }
+
+ BOARD_ITEM* Remove( int aIndex )
+ {
+ ITEM_ARRAY::auto_type ret = myItems.release( myItems.begin()+aIndex );
+ return ret.release();
+ }
+
+ void Insert( int aIndex, BOARD_ITEM* aItem )
+ {
+ myItems.insert( myItems.begin()+aIndex, aItem );
+ }
+
+ BOARD_ITEM* At( int aIndex ) const
+ {
+ // we have varying sized objects and are using polymorphism, so we
+ // must return a pointer not a reference.
+ return (BOARD_ITEM*) &myItems[aIndex];
+ }
+
+ BOARD_ITEM* operator[]( int aIndex ) const
+ {
+ return At( aIndex );
+ }
+
+ void Delete( int aIndex )
+ {
+ myItems.erase( myItems.begin()+aIndex );
+ }
+
+ void PushBack( BOARD_ITEM* aItem )
+ {
+ Append( aItem );
+ }
+
+ BOARD_ITEM* PopBack()
+ {
+ if( GetCount() )
+ return Remove( GetCount()-1 );
+
+ return NULL;
+ }
+};
+#endif // future
+
+#endif // BOARD_CONNECTED_ITEM_H
diff --git a/pcbnew/class_board_design_settings.cpp b/pcbnew/class_board_design_settings.cpp
new file mode 100644
index 0000000..49b3de0
--- /dev/null
+++ b/pcbnew/class_board_design_settings.cpp
@@ -0,0 +1,396 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_board_design_settings.cpp
+ * BOARD_DESIGN_SETTINGS class functions.
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <layers_id_colors_and_visibility.h>
+
+#include <pcbnew.h>
+#include <class_board_design_settings.h>
+
+#include <class_track.h>
+#include <convert_from_iu.h>
+
+
+BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS() :
+ m_Pad_Master( NULL )
+{
+ LSET all_set = LSET().set();
+
+ m_enabledLayers = all_set; // All layers enabled at first.
+ // SetCopperLayerCount() will adjust this.
+ SetVisibleLayers( all_set );
+
+ // set all but hidden text as visible.
+ m_visibleElements = ~( 1 << MOD_TEXT_INVISIBLE );
+
+ SetCopperLayerCount( 2 ); // Default design is a double sided board
+
+ // via type (VIA_BLIND_BURIED, VIA_THROUGH VIA_MICROVIA).
+ m_CurrentViaType = VIA_THROUGH;
+
+ // if true, when creating a new track starting on an existing track, use this track width
+ m_UseConnectedTrackWidth = false;
+
+ m_BlindBuriedViaAllowed = false; // true to allow blind/buried vias
+ m_MicroViasAllowed = false; // true to allow micro vias
+
+ m_DrawSegmentWidth = Millimeter2iu( DEFAULT_GRAPHIC_THICKNESS ); // current graphic line width (not EDGE layer)
+
+ m_EdgeSegmentWidth = Millimeter2iu( DEFAULT_PCB_EDGE_THICKNESS ); // current graphic line width (EDGE layer only)
+ m_PcbTextWidth = Millimeter2iu( DEFAULT_TEXT_PCB_THICKNESS ); // current Pcb (not module) Text width
+
+ m_PcbTextSize = wxSize( Millimeter2iu( DEFAULT_TEXT_PCB_SIZE ),
+ Millimeter2iu( DEFAULT_TEXT_PCB_SIZE ) ); // current Pcb (not module) Text size
+
+ m_useCustomTrackVia = false;
+ m_customTrackWidth = Millimeter2iu( DEFAULT_CUSTOMTRACKWIDTH );
+ m_customViaSize.m_Diameter = Millimeter2iu( DEFAULT_VIASMINSIZE );
+ m_customViaSize.m_Drill = Millimeter2iu( DEFAULT_VIASMINDRILL );
+
+ m_TrackMinWidth = Millimeter2iu( DEFAULT_TRACKMINWIDTH ); // track min width
+ m_ViasMinSize = Millimeter2iu( DEFAULT_VIASMINSIZE ); // via (not uvia) min diam
+ m_ViasMinDrill = Millimeter2iu( DEFAULT_VIASMINDRILL ); // via (not uvia) min drill diam
+ m_MicroViasMinSize = Millimeter2iu( DEFAULT_MICROVIASMINSIZE );// uvia (not via) min diam
+ m_MicroViasMinDrill = Millimeter2iu( DEFAULT_MICROVIASMINDRILL );// uvia (not via) min drill diam
+
+ // Global mask margins:
+ m_SolderMaskMargin = Millimeter2iu( DEFAULT_SOLDERMASK_CLEARANCE ); // Solder mask margin
+ m_SolderMaskMinWidth = Millimeter2iu( DEFAULT_SOLDERMASK_MIN_WIDTH ); // Solder mask min width
+ m_SolderPasteMargin = 0; // Solder paste margin absolute value
+ m_SolderPasteMarginRatio = 0.0; // Solder pask margin ratio value of pad size
+ // The final margin is the sum of these 2 values
+ // Usually < 0 because the mask is smaller than pad
+
+ // Layer thickness for 3D viewer
+ m_boardThickness = Millimeter2iu( DEFAULT_BOARD_THICKNESS_MM );
+
+ m_viaSizeIndex = 0;
+ m_trackWidthIndex = 0;
+
+ // Default values for the footprint editor and fp creation
+ // (also covers footprints created on the fly by micor-waves tools)
+ m_ModuleTextSize = wxSize( Millimeter2iu( DEFAULT_TEXT_MODULE_SIZE ),
+ Millimeter2iu( DEFAULT_TEXT_MODULE_SIZE ) );
+ m_ModuleTextWidth = Millimeter2iu( DEFAULT_GR_MODULE_THICKNESS );
+ m_ModuleSegmentWidth = Millimeter2iu( DEFAULT_GR_MODULE_THICKNESS );
+
+ // These values will be overriden by config values after reading the config
+ // Default ref text on fp creation. if empty, use footprint name as default
+ m_RefDefaultText = wxT( "REF**" );
+ m_RefDefaultVisibility = true; // Default ref text visibility on fp creation
+ m_RefDefaultlayer = int( F_SilkS ); // Default ref text layer on fp creation
+ // Default value text on fp creation. if empty, use footprint name as default
+ m_ValueDefaultText = wxEmptyString;
+ m_ValueDefaultVisibility = true;
+ m_ValueDefaultlayer = int( F_Fab );
+}
+
+// Add parameters to save in project config.
+// values are saved in mm
+void BOARD_DESIGN_SETTINGS::AppendConfigs( PARAM_CFG_ARRAY* aResult )
+{
+ m_Pad_Master.AppendConfigs( aResult );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PcbTextSizeV" ),
+ &m_PcbTextSize.y,
+ Millimeter2iu( DEFAULT_TEXT_PCB_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PcbTextSizeH" ),
+ &m_PcbTextSize.x,
+ Millimeter2iu( DEFAULT_TEXT_PCB_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PcbTextThickness" ),
+ &m_PcbTextWidth,
+ Millimeter2iu(DEFAULT_TEXT_PCB_THICKNESS ),
+ Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "ModuleTextSizeV" ),
+ &m_ModuleTextSize.y,
+ DEFAULT_TEXT_MODULE_SIZE, TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "ModuleTextSizeH" ),
+ &m_ModuleTextSize.x,
+ DEFAULT_TEXT_MODULE_SIZE, TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "ModuleTextSizeThickness" ),
+ &m_ModuleTextWidth,
+ Millimeter2iu( DEFAULT_GR_MODULE_THICKNESS ), 1, TEXTS_MAX_WIDTH,
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "SolderMaskClearance" ),
+ &m_SolderMaskMargin,
+ Millimeter2iu( DEFAULT_SOLDERMASK_CLEARANCE ), 0, Millimeter2iu( 1.0 ),
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "SolderMaskMinWidth" ),
+ &m_SolderMaskMinWidth,
+ Millimeter2iu( DEFAULT_SOLDERMASK_MIN_WIDTH ), 0, Millimeter2iu( 0.5 ),
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "DrawSegmentWidth" ),
+ &m_DrawSegmentWidth,
+ Millimeter2iu( DEFAULT_GRAPHIC_THICKNESS ),
+ Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "BoardOutlineThickness" ),
+ &m_EdgeSegmentWidth,
+ Millimeter2iu( DEFAULT_PCB_EDGE_THICKNESS ),
+ Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "ModuleOutlineThickness" ),
+ &m_ModuleSegmentWidth,
+ Millimeter2iu( DEFAULT_GR_MODULE_THICKNESS ),
+ Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ),
+ NULL, MM_PER_IU ) );
+}
+
+
+bool BOARD_DESIGN_SETTINGS::SetCurrentNetClass( const wxString& aNetClassName )
+{
+ NETCLASSPTR netClass = m_NetClasses.Find( aNetClassName );
+ bool lists_sizes_modified = false;
+
+ // if not found (should not happen) use the default
+ if( netClass == NULL )
+ netClass = m_NetClasses.GetDefault();
+
+ m_currentNetClassName = netClass->GetName();
+
+ // Initialize others values:
+ if( m_ViasDimensionsList.size() == 0 )
+ {
+ VIA_DIMENSION viadim;
+ lists_sizes_modified = true;
+ m_ViasDimensionsList.push_back( viadim );
+ }
+
+ if( m_TrackWidthList.size() == 0 )
+ {
+ lists_sizes_modified = true;
+ m_TrackWidthList.push_back( 0 );
+ }
+
+ /* note the m_ViasDimensionsList[0] and m_TrackWidthList[0] values
+ * are always the Netclass values
+ */
+ if( m_ViasDimensionsList[0].m_Diameter != netClass->GetViaDiameter() )
+ {
+ lists_sizes_modified = true;
+ m_ViasDimensionsList[0].m_Diameter = netClass->GetViaDiameter();
+ }
+
+ if( m_ViasDimensionsList[0].m_Drill != netClass->GetViaDrill() )
+ {
+ lists_sizes_modified = true;
+ m_ViasDimensionsList[0].m_Drill = netClass->GetViaDrill();
+ }
+
+ if( m_TrackWidthList[0] != netClass->GetTrackWidth() )
+ {
+ lists_sizes_modified = true;
+ m_TrackWidthList[0] = netClass->GetTrackWidth();
+ }
+
+ if( GetViaSizeIndex() >= m_ViasDimensionsList.size() )
+ SetViaSizeIndex( m_ViasDimensionsList.size() );
+
+ if( GetTrackWidthIndex() >= m_TrackWidthList.size() )
+ SetTrackWidthIndex( m_TrackWidthList.size() );
+
+ return lists_sizes_modified;
+}
+
+
+int BOARD_DESIGN_SETTINGS::GetBiggestClearanceValue()
+{
+ int clearance = m_NetClasses.GetDefault()->GetClearance();
+
+ //Read list of Net Classes
+ for( NETCLASSES::const_iterator nc = m_NetClasses.begin(); nc != m_NetClasses.end(); ++nc )
+ {
+ NETCLASSPTR netclass = nc->second;
+ clearance = std::max( clearance, netclass->GetClearance() );
+ }
+
+ return clearance;
+}
+
+
+int BOARD_DESIGN_SETTINGS::GetSmallestClearanceValue()
+{
+ int clearance = m_NetClasses.GetDefault()->GetClearance();
+
+ //Read list of Net Classes
+ for( NETCLASSES::const_iterator nc = m_NetClasses.begin(); nc != m_NetClasses.end(); ++nc )
+ {
+ NETCLASSPTR netclass = nc->second;
+ clearance = std::min( clearance, netclass->GetClearance() );
+ }
+
+ return clearance;
+}
+
+
+int BOARD_DESIGN_SETTINGS::GetCurrentMicroViaSize()
+{
+ NETCLASSPTR netclass = m_NetClasses.Find( m_currentNetClassName );
+
+ return netclass->GetuViaDiameter();
+}
+
+
+int BOARD_DESIGN_SETTINGS::GetCurrentMicroViaDrill()
+{
+ NETCLASSPTR netclass = m_NetClasses.Find( m_currentNetClassName );
+
+ return netclass->GetuViaDrill();
+}
+
+
+void BOARD_DESIGN_SETTINGS::SetViaSizeIndex( unsigned aIndex )
+{
+ if( aIndex >= m_ViasDimensionsList.size() )
+ m_viaSizeIndex = m_ViasDimensionsList.size();
+ else
+ m_viaSizeIndex = aIndex;
+
+ m_useCustomTrackVia = false;
+}
+
+
+int BOARD_DESIGN_SETTINGS::GetCurrentViaDrill() const
+{
+ int drill;
+
+ if( m_useCustomTrackVia )
+ drill = m_customViaSize.m_Drill;
+ else
+ drill = m_ViasDimensionsList[m_viaSizeIndex].m_Drill;
+
+ return drill > 0 ? drill : -1;
+}
+
+
+void BOARD_DESIGN_SETTINGS::SetTrackWidthIndex( unsigned aIndex )
+{
+ if( aIndex >= m_TrackWidthList.size() )
+ m_trackWidthIndex = m_TrackWidthList.size();
+ else
+ m_trackWidthIndex = aIndex;
+
+ m_useCustomTrackVia = false;
+}
+
+
+void BOARD_DESIGN_SETTINGS::SetVisibleAlls()
+{
+ SetVisibleLayers( LSET().set() );
+ m_visibleElements = -1;
+}
+
+
+void BOARD_DESIGN_SETTINGS::SetLayerVisibility( LAYER_ID aLayer, bool aNewState )
+{
+ if( aNewState && IsLayerEnabled( aLayer ) )
+ m_visibleLayers.set( aLayer, true );
+ else
+ m_visibleLayers.set( aLayer, false );
+}
+
+
+void BOARD_DESIGN_SETTINGS::SetElementVisibility( int aElementCategory, bool aNewState )
+{
+ if( aElementCategory < 0 || aElementCategory >= END_PCB_VISIBLE_LIST )
+ return;
+
+ if( aNewState )
+ m_visibleElements |= 1 << aElementCategory;
+ else
+ m_visibleElements &= ~( 1 << aElementCategory );
+}
+
+
+void BOARD_DESIGN_SETTINGS::SetCopperLayerCount( int aNewLayerCount )
+{
+ // if( aNewLayerCount < 2 ) aNewLayerCount = 2;
+
+ m_copperLayerCount = aNewLayerCount;
+
+ // ensure consistency with the m_EnabledLayers member
+#if 0
+ // was:
+ m_enabledLayers &= ~ALL_CU_LAYERS;
+ m_enabledLayers |= LAYER_BACK;
+
+ if( m_copperLayerCount > 1 )
+ m_enabledLayers |= LAYER_FRONT;
+
+ for( LAYER_NUM ii = LAYER_N_2; ii < aNewLayerCount - 1; ++ii )
+ m_enabledLayers |= GetLayerSet( ii );
+#else
+ // Update only enabled copper layers mask
+ m_enabledLayers &= ~LSET::AllCuMask();
+ m_enabledLayers |= LSET::AllCuMask( aNewLayerCount );
+#endif
+}
+
+
+void BOARD_DESIGN_SETTINGS::SetEnabledLayers( LSET aMask )
+{
+ // Back and front layers are always enabled.
+ aMask.set( B_Cu ).set( F_Cu );
+
+ m_enabledLayers = aMask;
+
+ // A disabled layer cannot be visible
+ m_visibleLayers &= aMask;
+
+ // update m_CopperLayerCount to ensure its consistency with m_EnabledLayers
+ m_copperLayerCount = ( aMask & LSET::AllCuMask() ).count();
+}
+
+
+#ifndef NDEBUG
+struct list_size_check {
+ list_size_check()
+ {
+ // Int (the type used for saving visibility settings) is only 32 bits guaranteed,
+ // be sure that we do not cross the limit
+ assert( END_PCB_VISIBLE_LIST <= 32 );
+ };
+};
+static list_size_check check;
+#endif
diff --git a/pcbnew/class_board_item.cpp b/pcbnew/class_board_item.cpp
new file mode 100644
index 0000000..1ae6f8a
--- /dev/null
+++ b/pcbnew/class_board_item.cpp
@@ -0,0 +1,245 @@
+/**
+ * @file class_board_item.cpp
+ * @brief Class BOARD_ITEM definition and some basic functions.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <pcbnew.h>
+
+#include <class_board.h>
+#include <string>
+
+wxString BOARD_ITEM::ShowShape( STROKE_T aShape )
+{
+ switch( aShape )
+ {
+ case S_SEGMENT: return _( "Line" );
+ case S_RECT: return _( "Rect" );
+ case S_ARC: return _( "Arc" );
+ case S_CIRCLE: return _( "Circle" );
+ case S_CURVE: return _( "Bezier Curve" );
+ case S_POLYGON: return _( "Polygon" );
+ default: return wxT( "??" );
+ }
+}
+
+
+void BOARD_ITEM::UnLink()
+{
+ DLIST<BOARD_ITEM>* list = (DLIST<BOARD_ITEM>*) GetList();
+ wxASSERT( list );
+
+ if( list )
+ list->Remove( this );
+}
+
+
+BOARD* BOARD_ITEM::GetBoard() const
+{
+ if( Type() == PCB_T )
+ return (BOARD*) this;
+
+ BOARD_ITEM* parent = GetParent();
+
+ if( parent )
+ return parent->GetBoard();
+
+ return NULL;
+}
+
+
+wxString BOARD_ITEM::GetLayerName() const
+{
+ BOARD* board = GetBoard();
+
+ if( board )
+ return board->GetLayerName( m_Layer );
+
+ // If no parent, return standard name
+ return BOARD::GetStandardLayerName( m_Layer );
+}
+
+
+std::string BOARD_ITEM::FormatInternalUnits( int aValue )
+{
+#if 1
+
+ char buf[50];
+ int len;
+ double mm = aValue / IU_PER_MM;
+
+ if( mm != 0.0 && fabs( mm ) <= 0.0001 )
+ {
+ len = sprintf( buf, "%.10f", mm );
+
+ while( --len > 0 && buf[len] == '0' )
+ buf[len] = '\0';
+
+ if( buf[len] == '.' )
+ buf[len] = '\0';
+ else
+ ++len;
+ }
+ else
+ {
+ len = sprintf( buf, "%.10g", mm );
+ }
+
+ return std::string( buf, len );
+
+#else
+
+ // Assume aValue is in nanometers, and that we want the result in millimeters,
+ // and that int is 32 bits wide. Then perform an alternative algorithm.
+ // Can be used to verify that the above algorithm is correctly generating text.
+ // Convert aValue into an integer string, then insert a decimal point manually.
+ // Results are the same as above general purpose algorithm.
+
+ wxASSERT( sizeof(int) == 4 );
+
+ if( aValue == 0 )
+ return std::string( 1, '0' );
+ else
+ {
+ char buf[50];
+ int len = sprintf( buf, aValue > 0 ? "%06d" : "%07d", aValue ); // optionally pad w/leading zeros
+
+ std::string ret( buf, len );
+
+ std::string::iterator it = ret.end() - 1; // last byte
+
+ // insert '.' at 6 positions from end, dividing by 10e6 (a million), nm => mm
+ std::string::iterator decpoint = ret.end() - 6;
+
+ // truncate trailing zeros, up to decimal point position
+ for( ; *it=='0' && it >= decpoint; --it )
+ ret.erase( it ); // does not invalidate iterators it or decpoint
+
+ if( it >= decpoint )
+ {
+ ret.insert( decpoint, '.' );
+
+ // decpoint is invalidated here, after insert()
+
+#if 1 // want a leading zero when decimal point is in first position?
+ if( ret[0] == '.' )
+ {
+ // insert leading zero ahead of decimal point.
+ ret.insert( ret.begin(), '0' );
+ }
+ else if( ret[0]=='-' && ret[1]=='.' )
+ {
+ ret.insert( ret.begin() + 1, '0' );
+ }
+#endif
+ }
+
+ return ret;
+ }
+
+#endif
+}
+
+
+std::string BOARD_ITEM::FormatAngle( double aAngle )
+{
+ char temp[50];
+
+ int len = snprintf( temp, sizeof(temp), "%.10g", aAngle / 10.0 );
+
+ return std::string( temp, len );
+}
+
+
+std::string BOARD_ITEM::FormatInternalUnits( const wxPoint& aPoint )
+{
+ return FormatInternalUnits( aPoint.x ) + " " + FormatInternalUnits( aPoint.y );
+}
+
+
+std::string BOARD_ITEM::FormatInternalUnits( const wxSize& aSize )
+{
+ return FormatInternalUnits( aSize.GetWidth() ) + " " + FormatInternalUnits( aSize.GetHeight() );
+}
+
+
+void BOARD_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const
+{
+ // Basic fallback
+ aCount = 1;
+ aLayers[0] = m_Layer;
+}
+
+
+int BOARD_ITEM::getTrailingInt( wxString aStr )
+{
+ int number = 0;
+ int base = 1;
+
+ // Trim and extract the trailing numeric part
+ int index = aStr.Len() - 1;
+ while( index >= 0 )
+ {
+ const char chr = aStr.GetChar( index );
+
+ if( chr < '0' || chr > '9' )
+ break;
+
+ number += ( chr - '0' ) * base;
+ base *= 10;
+ index--;
+ }
+
+ return number;
+}
+
+int BOARD_ITEM::getNextNumberInSequence( std::set<int> aSeq, bool aFillSequenceGaps)
+{
+ // By default go to the end of the sequence
+ int candidate = *aSeq.rbegin();
+
+ // Filling in gaps in pad numbering
+ if( aFillSequenceGaps )
+ {
+ // start at the beginning
+ candidate = *aSeq.begin();
+
+ for( std::set<int>::iterator it = aSeq.begin(),
+ itEnd = aSeq.end(); it != itEnd; ++it )
+ {
+ if( *it - candidate > 1 )
+ break;
+
+ candidate = *it;
+ }
+ }
+
+ candidate++;
+ return candidate;
+}
diff --git a/pcbnew/class_dimension.cpp b/pcbnew/class_dimension.cpp
new file mode 100644
index 0000000..0367c14
--- /dev/null
+++ b/pcbnew/class_dimension.cpp
@@ -0,0 +1,523 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_dimension.cpp
+ */
+
+#include <fctsys.h>
+#include <macros.h>
+#include <gr_basic.h>
+#include <trigo.h>
+#include <wxstruct.h>
+#include <class_drawpanel.h>
+#include <colors_selection.h>
+#include <kicad_string.h>
+#include <richio.h>
+
+#include <class_board.h>
+#include <class_pcb_text.h>
+#include <class_dimension.h>
+#include <base_units.h>
+
+
+DIMENSION::DIMENSION( BOARD_ITEM* aParent ) :
+ BOARD_ITEM( aParent, PCB_DIMENSION_T ),
+ m_Width( Millimeter2iu( 0.2 ) ), m_Unit( INCHES ), m_Value( 0 ), m_Height( 0 ), m_Text( this )
+{
+ m_Layer = Dwgs_User;
+ m_Shape = 0;
+}
+
+
+DIMENSION::~DIMENSION()
+{
+}
+
+
+void DIMENSION::SetPosition( const wxPoint& aPos )
+{
+ m_Text.SetTextPosition( aPos );
+}
+
+
+const wxPoint& DIMENSION::GetPosition() const
+{
+ return m_Text.GetTextPosition();
+}
+
+
+void DIMENSION::SetText( const wxString& aNewText )
+{
+ m_Text.SetText( aNewText );
+}
+
+
+const wxString DIMENSION::GetText() const
+{
+ return m_Text.GetText();
+}
+
+
+void DIMENSION::SetLayer( LAYER_ID aLayer )
+{
+ m_Layer = aLayer;
+ m_Text.SetLayer( aLayer );
+}
+
+
+void DIMENSION::Copy( DIMENSION* source )
+{
+ m_Value = source->m_Value;
+ SetLayer( source->GetLayer() );
+ m_Width = source->m_Width;
+ m_Shape = source->m_Shape;
+ m_Height = source->m_Height;
+ m_Unit = source->m_Unit;
+ SetTimeStamp( GetNewTimeStamp() );
+ m_Text.Copy( &source->m_Text );
+
+ m_crossBarO = source->m_crossBarO;
+ m_crossBarF = source->m_crossBarF;
+ m_featureLineGO = source->m_featureLineGO;
+ m_featureLineGF = source->m_featureLineGF;
+ m_featureLineDO = source->m_featureLineDO;
+ m_featureLineDF = source->m_featureLineDF;
+ m_arrowD1F = source->m_arrowD1F;
+ m_arrowD2F = source->m_arrowD2F;
+ m_arrowG1F = source->m_arrowG1F;
+ m_arrowG2F = source->m_arrowG2F;
+}
+
+
+void DIMENSION::Move( const wxPoint& offset )
+{
+ m_Text.SetTextPosition( m_Text.GetTextPosition() + offset );
+ m_crossBarO += offset;
+ m_crossBarF += offset;
+ m_featureLineGO += offset;
+ m_featureLineGF += offset;
+ m_featureLineDO += offset;
+ m_featureLineDF += offset;
+ m_arrowG1F += offset;
+ m_arrowG2F += offset;
+ m_arrowD1F += offset;
+ m_arrowD2F += offset;
+}
+
+
+void DIMENSION::Rotate( const wxPoint& aRotCentre, double aAngle )
+{
+ wxPoint tmp = m_Text.GetTextPosition();
+ RotatePoint( &tmp, aRotCentre, aAngle );
+ m_Text.SetTextPosition( tmp );
+
+ double newAngle = m_Text.GetOrientation() + aAngle;
+
+ if( newAngle >= 3600 )
+ newAngle -= 3600;
+
+ if( newAngle > 900 && newAngle < 2700 )
+ newAngle -= 1800;
+
+ m_Text.SetOrientation( newAngle );
+
+ RotatePoint( &m_crossBarO, aRotCentre, aAngle );
+ RotatePoint( &m_crossBarF, aRotCentre, aAngle );
+ RotatePoint( &m_featureLineGO, aRotCentre, aAngle );
+ RotatePoint( &m_featureLineGF, aRotCentre, aAngle );
+ RotatePoint( &m_featureLineDO, aRotCentre, aAngle );
+ RotatePoint( &m_featureLineDF, aRotCentre, aAngle );
+ RotatePoint( &m_arrowG1F, aRotCentre, aAngle );
+ RotatePoint( &m_arrowG2F, aRotCentre, aAngle );
+ RotatePoint( &m_arrowD1F, aRotCentre, aAngle );
+ RotatePoint( &m_arrowD2F, aRotCentre, aAngle );
+}
+
+
+void DIMENSION::Flip( const wxPoint& aCentre )
+{
+ Mirror( aCentre );
+
+ // DIMENSION items are not usually on copper layers, so
+ // copper layers count is not taken in accoun in Flip transform
+ SetLayer( FlipLayer( GetLayer() ) );
+}
+
+
+void DIMENSION::Mirror( const wxPoint& axis_pos )
+{
+ wxPoint newPos = m_Text.GetTextPosition();
+
+#define INVERT( pos ) (pos) = axis_pos.y - ( (pos) - axis_pos.y )
+ INVERT( newPos.y );
+
+ m_Text.SetTextPosition( newPos );
+
+ // invert angle
+ m_Text.SetOrientation( -m_Text.GetOrientation() );
+
+ INVERT( m_crossBarO.y );
+ INVERT( m_crossBarF.y );
+ INVERT( m_featureLineGO.y );
+ INVERT( m_featureLineGF.y );
+ INVERT( m_featureLineDO.y );
+ INVERT( m_featureLineDF.y );
+ INVERT( m_arrowG1F.y );
+ INVERT( m_arrowG2F.y );
+ INVERT( m_arrowD1F.y );
+ INVERT( m_arrowD2F.y );
+}
+
+
+void DIMENSION::SetOrigin( const wxPoint& aOrigin )
+{
+ m_featureLineGO = aOrigin;
+
+ AdjustDimensionDetails();
+}
+
+
+void DIMENSION::SetEnd( const wxPoint& aEnd )
+{
+ m_featureLineDO = aEnd;
+
+ AdjustDimensionDetails();
+}
+
+
+void DIMENSION::SetHeight( int aHeight )
+{
+ m_Height = aHeight;
+
+ AdjustDimensionDetails();
+}
+
+
+void DIMENSION::UpdateHeight()
+{
+ VECTOR2D featureLine( m_crossBarO - m_featureLineGO );
+ VECTOR2D crossBar( m_featureLineDO - m_featureLineGO );
+
+ if( featureLine.Cross( crossBar ) > 0 )
+ m_Height = -featureLine.EuclideanNorm();
+ else
+ m_Height = featureLine.EuclideanNorm();
+}
+
+
+void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText )
+{
+ const int arrowz = DMils2iu( 500 ); // size of arrows
+ int ii;
+ int measure, deltax, deltay; // value of the measure on X and Y axes
+ int arrow_up_X = 0, arrow_up_Y = 0; // coordinates of arrow line /
+ int arrow_dw_X = 0, arrow_dw_Y = 0; // coordinates of arrow line '\'
+ int hx, hy; // dimension line interval
+ double angle, angle_f;
+ wxString msg;
+
+ // Init layer :
+ m_Text.SetLayer( GetLayer() );
+
+ // calculate the size of the dimension (text + line above the text)
+ ii = m_Text.GetSize().y + m_Text.GetThickness() + (m_Width * 3);
+
+ deltax = m_featureLineDO.x - m_featureLineGO.x;
+ deltay = m_featureLineDO.y - m_featureLineGO.y;
+
+ // Calculate dimension value
+ measure = KiROUND( hypot( deltax, deltay ) );
+
+ angle = atan2( deltay, deltax );
+
+ // Calculation of parameters X and Y dimensions of the arrows and lines.
+ hx = hy = ii;
+
+ // Taking into account the slope of the side lines.
+ if( measure )
+ {
+ hx = abs( KiROUND( ( (double) deltay * hx ) / measure ) );
+ hy = abs( KiROUND( ( (double) deltax * hy ) / measure ) );
+
+ if( m_featureLineGO.x > m_crossBarO.x )
+ hx = -hx;
+
+ if( m_featureLineGO.x == m_crossBarO.x )
+ hx = 0;
+
+ if( m_featureLineGO.y > m_crossBarO.y )
+ hy = -hy;
+
+ if( m_featureLineGO.y == m_crossBarO.y )
+ hy = 0;
+
+ angle_f = angle + DEG2RAD( 27.5 );
+ arrow_up_X = wxRound( arrowz * cos( angle_f ) );
+ arrow_up_Y = wxRound( arrowz * sin( angle_f ) );
+ angle_f = angle - DEG2RAD( 27.5 );
+ arrow_dw_X = wxRound( arrowz * cos( angle_f ) );
+ arrow_dw_Y = wxRound( arrowz * sin( angle_f ) );
+ }
+
+ int dx = KiROUND( m_Height * cos( angle + M_PI / 2 ) );
+ int dy = KiROUND( m_Height * sin( angle + M_PI / 2 ) );
+ m_crossBarO.x = m_featureLineGO.x + dx;
+ m_crossBarO.y = m_featureLineGO.y + dy;
+ m_crossBarF.x = m_featureLineDO.x + dx;
+ m_crossBarF.y = m_featureLineDO.y + dy;
+
+ m_arrowG1F.x = m_crossBarO.x + arrow_up_X;
+ m_arrowG1F.y = m_crossBarO.y + arrow_up_Y;
+
+ m_arrowG2F.x = m_crossBarO.x + arrow_dw_X;
+ m_arrowG2F.y = m_crossBarO.y + arrow_dw_Y;
+
+ /* The right arrow is symmetrical to the left.
+ * / = -\ and \ = -/
+ */
+ m_arrowD1F.x = m_crossBarF.x - arrow_dw_X;
+ m_arrowD1F.y = m_crossBarF.y - arrow_dw_Y;
+
+ m_arrowD2F.x = m_crossBarF.x - arrow_up_X;
+ m_arrowD2F.y = m_crossBarF.y - arrow_up_Y;
+
+ m_featureLineGF.x = m_crossBarO.x + hx;
+ m_featureLineGF.y = m_crossBarO.y + hy;
+
+ m_featureLineDF.x = m_crossBarF.x + hx;
+ m_featureLineDF.y = m_crossBarF.y + hy;
+
+ // Calculate the better text position and orientation:
+ wxPoint textPos;
+ textPos.x = (m_crossBarF.x + m_featureLineGF.x) / 2;
+ textPos.y = (m_crossBarF.y + m_featureLineGF.y) / 2;
+ m_Text.SetTextPosition( textPos );
+
+ double newAngle = -RAD2DECIDEG( angle );
+
+ NORMALIZE_ANGLE_POS( newAngle );
+
+ if( newAngle > 900 && newAngle < 2700 )
+ newAngle -= 1800;
+
+ m_Text.SetOrientation( newAngle );
+
+ if( !aDoNotChangeText )
+ {
+ m_Value = measure;
+ msg = ::CoordinateToString( m_Value );
+ SetText( msg );
+ }
+}
+
+
+void DIMENSION::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE mode_color,
+ const wxPoint& offset )
+{
+ EDA_COLOR_T gcolor;
+ BOARD* brd = GetBoard();
+
+ if( brd->IsLayerVisible( m_Layer ) == false )
+ return;
+
+ m_Text.Draw( panel, DC, mode_color, offset );
+
+ gcolor = brd->GetLayerColor( m_Layer );
+
+ GRSetDrawMode( DC, mode_color );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
+ bool filled = displ_opts ? displ_opts->m_DisplayDrawItemsFill : FILLED;
+ int width = m_Width;
+
+ if( filled )
+ {
+ GRLine( panel->GetClipBox(), DC, m_crossBarO + offset,
+ m_crossBarF + offset, width, gcolor );
+ GRLine( panel->GetClipBox(), DC, m_featureLineGO + offset,
+ m_featureLineGF + offset, width, gcolor );
+ GRLine( panel->GetClipBox(), DC, m_featureLineDO + offset,
+ m_featureLineDF + offset, width, gcolor );
+ GRLine( panel->GetClipBox(), DC, m_crossBarF + offset,
+ m_arrowD1F + offset, width, gcolor );
+ GRLine( panel->GetClipBox(), DC, m_crossBarF + offset,
+ m_arrowD2F + offset, width, gcolor );
+ GRLine( panel->GetClipBox(), DC, m_crossBarO + offset,
+ m_arrowG1F + offset, width, gcolor );
+ GRLine( panel->GetClipBox(), DC, m_crossBarO + offset,
+ m_arrowG2F + offset, width, gcolor );
+ }
+ else
+ {
+ GRCSegm( panel->GetClipBox(), DC, m_crossBarO + offset,
+ m_crossBarF + offset, width, gcolor );
+ GRCSegm( panel->GetClipBox(), DC, m_featureLineGO + offset,
+ m_featureLineGF + offset, width, gcolor );
+ GRCSegm( panel->GetClipBox(), DC, m_featureLineDO + offset,
+ m_featureLineDF + offset, width, gcolor );
+ GRCSegm( panel->GetClipBox(), DC, m_crossBarF + offset,
+ m_arrowD1F + offset, width, gcolor );
+ GRCSegm( panel->GetClipBox(), DC, m_crossBarF + offset,
+ m_arrowD2F + offset, width, gcolor );
+ GRCSegm( panel->GetClipBox(), DC, m_crossBarO + offset,
+ m_arrowG1F + offset, width, gcolor );
+ GRCSegm( panel->GetClipBox(), DC, m_crossBarO + offset,
+ m_arrowG2F + offset, width, gcolor );
+ }
+}
+
+
+// see class_cotation.h
+void DIMENSION::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ // for now, display only the text within the DIMENSION using class TEXTE_PCB.
+ m_Text.GetMsgPanelInfo( aList );
+}
+
+
+bool DIMENSION::HitTest( const wxPoint& aPosition ) const
+{
+ if( m_Text.TextHitTest( aPosition ) )
+ return true;
+
+ int dist_max = m_Width / 2;
+
+ // Locate SEGMENTS
+
+ if( TestSegmentHit( aPosition, m_crossBarO, m_crossBarF, dist_max ) )
+ return true;
+
+ if( TestSegmentHit( aPosition, m_featureLineGO, m_featureLineGF, dist_max ) )
+ return true;
+
+ if( TestSegmentHit( aPosition, m_featureLineDO, m_featureLineDF, dist_max ) )
+ return true;
+
+ if( TestSegmentHit( aPosition, m_crossBarF, m_arrowD1F, dist_max ) )
+ return true;
+
+ if( TestSegmentHit( aPosition, m_crossBarF, m_arrowD2F, dist_max ) )
+ return true;
+
+ if( TestSegmentHit( aPosition, m_crossBarO, m_arrowG1F, dist_max ) )
+ return true;
+
+ if( TestSegmentHit( aPosition, m_crossBarO, m_arrowG2F, dist_max ) )
+ return true;
+
+ return false;
+}
+
+
+bool DIMENSION::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ EDA_RECT arect = aRect;
+ arect.Inflate( aAccuracy );
+
+ EDA_RECT rect = GetBoundingBox();
+ if( aAccuracy )
+ rect.Inflate( aAccuracy );
+
+ if( aContained )
+ return arect.Contains( rect );
+
+ return arect.Intersects( rect );
+}
+
+
+const EDA_RECT DIMENSION::GetBoundingBox() const
+{
+ EDA_RECT bBox;
+ int xmin, xmax, ymin, ymax;
+
+ bBox = m_Text.GetTextBox( -1 );
+ xmin = bBox.GetX();
+ xmax = bBox.GetRight();
+ ymin = bBox.GetY();
+ ymax = bBox.GetBottom();
+
+ xmin = std::min( xmin, m_crossBarO.x );
+ xmin = std::min( xmin, m_crossBarF.x );
+ ymin = std::min( ymin, m_crossBarO.y );
+ ymin = std::min( ymin, m_crossBarF.y );
+ xmax = std::max( xmax, m_crossBarO.x );
+ xmax = std::max( xmax, m_crossBarF.x );
+ ymax = std::max( ymax, m_crossBarO.y );
+ ymax = std::max( ymax, m_crossBarF.y );
+
+ xmin = std::min( xmin, m_featureLineGO.x );
+ xmin = std::min( xmin, m_featureLineGF.x );
+ ymin = std::min( ymin, m_featureLineGO.y );
+ ymin = std::min( ymin, m_featureLineGF.y );
+ xmax = std::max( xmax, m_featureLineGO.x );
+ xmax = std::max( xmax, m_featureLineGF.x );
+ ymax = std::max( ymax, m_featureLineGO.y );
+ ymax = std::max( ymax, m_featureLineGF.y );
+
+ xmin = std::min( xmin, m_featureLineDO.x );
+ xmin = std::min( xmin, m_featureLineDF.x );
+ ymin = std::min( ymin, m_featureLineDO.y );
+ ymin = std::min( ymin, m_featureLineDF.y );
+ xmax = std::max( xmax, m_featureLineDO.x );
+ xmax = std::max( xmax, m_featureLineDF.x );
+ ymax = std::max( ymax, m_featureLineDO.y );
+ ymax = std::max( ymax, m_featureLineDF.y );
+
+ bBox.SetX( xmin );
+ bBox.SetY( ymin );
+ bBox.SetWidth( xmax - xmin + 1 );
+ bBox.SetHeight( ymax - ymin + 1 );
+
+ bBox.Normalize();
+
+ return bBox;
+}
+
+
+wxString DIMENSION::GetSelectMenuText() const
+{
+ wxString text;
+ text.Printf( _( "Dimension \"%s\" on %s" ),
+ GetChars( GetText() ), GetChars( GetLayerName() ) );
+
+ return text;
+}
+
+
+const BOX2I DIMENSION::ViewBBox() const
+{
+ BOX2I dimBBox = BOX2I( VECTOR2I( GetBoundingBox().GetPosition() ),
+ VECTOR2I( GetBoundingBox().GetSize() ) );
+ dimBBox.Merge( m_Text.ViewBBox() );
+
+ return dimBBox;
+}
+
+
+EDA_ITEM* DIMENSION::Clone() const
+{
+ return new DIMENSION( *this );
+}
diff --git a/pcbnew/class_dimension.h b/pcbnew/class_dimension.h
new file mode 100644
index 0000000..d12a597
--- /dev/null
+++ b/pcbnew/class_dimension.h
@@ -0,0 +1,240 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_dimension.h
+ * @brief DIMENSION class definition.
+ */
+
+#ifndef DIMENSION_H_
+#define DIMENSION_H_
+
+
+#include <class_board_item.h>
+#include <class_pcb_text.h>
+
+
+class LINE_READER;
+class EDA_DRAW_PANEL;
+class TEXTE_PCB;
+class MSG_PANEL_ITEM;
+
+
+/**
+ * Class DIMENSION
+ *
+ * For better understanding of the points that make a dimension:
+ *
+ * m_featureLineGO m_featureLineDO
+ * | |
+ * | |
+ * | |
+ * | m_arrowG2F m_arrowD2F |
+ * | / \ |
+ * m_crossBarO|/____________________________\|m_crossBarF
+ * |\ m_Text /|
+ * | \ / |
+ * | m_arrowG1F m_arrowD1F |
+ * | |
+ * m_featureLineGF m_featureLineDF
+ */
+class DIMENSION : public BOARD_ITEM
+{
+ int m_Width; ///< Line width
+ int m_Shape; ///< Currently always 0.
+ EDA_UNITS_T m_Unit; ///< 0 = inches, 1 = mm
+ int m_Value; ///< value of PCB dimensions.
+ int m_Height; ///< length of feature lines
+ TEXTE_PCB m_Text;
+
+public:
+// TODO private: These member should be private. they are public only due to legacy code
+ wxPoint m_crossBarO, m_crossBarF;
+ wxPoint m_featureLineGO, m_featureLineGF;
+ wxPoint m_featureLineDO, m_featureLineDF;
+ wxPoint m_arrowD1F, m_arrowD2F;
+ wxPoint m_arrowG1F, m_arrowG2F;
+
+ DIMENSION( BOARD_ITEM* aParent );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~DIMENSION();
+
+ void SetValue( int aValue ) { m_Value = aValue; }
+
+ int GetValue() const { return m_Value; }
+
+ const wxPoint& GetPosition() const;
+
+ void SetPosition( const wxPoint& aPos ); // override, sets m_Text's position too
+
+ void SetTextSize( const wxSize& aTextSize )
+ {
+ m_Text.SetSize( aTextSize );
+ }
+
+ void SetLayer( LAYER_ID aLayer );
+
+ void SetShape( int aShape ) { m_Shape = aShape; }
+ int GetShape() const { return m_Shape; }
+
+ int GetWidth() const { return m_Width; }
+ void SetWidth( int aWidth ) { m_Width = aWidth; }
+
+ /**
+ * Function SetOrigin
+ * Sets a new origin of the crossbar line. All remaining lines are adjusted after that.
+ * @param aOrigin is the new point to be used as the new origin of the crossbar line.
+ */
+ void SetOrigin( const wxPoint& aOrigin );
+
+ /**
+ * Function GetOrigin
+ * @return Origin of the crossbar line.
+ */
+ const wxPoint& GetOrigin() const
+ {
+ return m_featureLineGO;
+ }
+
+ /**
+ * Function SetEnd
+ * Sets a new end of the crossbar line. All remaining lines are adjusted after that.
+ * @param aEnd is the new point to be used as the new end of the crossbar line.
+ */
+ void SetEnd( const wxPoint& aEnd );
+
+ /**
+ * Function GetEnd
+ * @return End of the crossbar line.
+ */
+ const wxPoint& GetEnd()
+ {
+ return m_featureLineDO;
+ }
+
+ /**
+ * Function SetHeight
+ * Sets the length of feature lines.
+ * @param aHeight is the new height.
+ */
+ void SetHeight( int aHeight );
+
+ /**
+ * Function GetHeight
+ * Returns the length of feature lines.
+ */
+ int GetHeight() const
+ {
+ return m_Height;
+ }
+
+ /**
+ * Function UpdateHeight
+ * Updates stored height basing on points coordinates.
+ */
+ void UpdateHeight();
+
+ /**
+ * Function GetAngle
+ * Returns angle of the crossbar.
+ * @return Angle of the crossbar line expressed in radians.
+ */
+ double GetAngle() const
+ {
+ wxPoint delta( m_featureLineDO - m_featureLineGO );
+
+ return atan2( delta.y, delta.x );
+ }
+
+ /**
+ * Function AdjustDimensionDetails
+ * Calculate coordinates of segments used to draw the dimension.
+ * @param aDoNotChangeText (bool) if false, the dimension text is initialized
+ */
+ void AdjustDimensionDetails( bool aDoNotChangeText = false );
+
+ void SetText( const wxString& NewText );
+ const wxString GetText() const;
+
+ TEXTE_PCB& Text() { return m_Text; }
+ TEXTE_PCB& Text() const { return *(const_cast<TEXTE_PCB*> (&m_Text)); }
+
+ void Copy( DIMENSION* source );
+
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
+ GR_DRAWMODE aColorMode, const wxPoint& offset = ZeroOffset );
+
+ /**
+ * Function Move
+ * @param offset : moving vector
+ */
+ void Move( const wxPoint& offset );
+
+ void Rotate( const wxPoint& aRotCentre, double aAngle );
+
+ void Flip( const wxPoint& aCentre );
+
+ /**
+ * Function Mirror
+ * Mirror the Dimension , relative to a given horizontal axis
+ * the text is not mirrored. only its position (and angle) is mirrored
+ * the layer is not changed
+ * @param axis_pos : vertical axis position
+ */
+ void Mirror( const wxPoint& axis_pos );
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
+ * bool aContained = true, int aAccuracy ) const
+ */
+ bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const;
+
+ wxString GetClass() const
+ {
+ return wxT( "DIMENSION" );
+ }
+
+ // Virtual function
+ const EDA_RECT GetBoundingBox() const;
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_dimension_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+ /// @copydoc VIEW_ITEM::ViewBBox()
+ virtual const BOX2I ViewBBox() const;
+
+#if defined(DEBUG)
+ virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+};
+
+#endif // DIMENSION_H_
diff --git a/pcbnew/class_drawsegment.cpp b/pcbnew/class_drawsegment.cpp
new file mode 100644
index 0000000..bd1ac73
--- /dev/null
+++ b/pcbnew/class_drawsegment.cpp
@@ -0,0 +1,709 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_drawsegment.cpp
+ * @brief Class and functions to handle a graphic segments.
+ */
+
+#include <fctsys.h>
+#include <macros.h>
+#include <wxstruct.h>
+#include <gr_basic.h>
+#include <bezier_curves.h>
+#include <class_drawpanel.h>
+#include <class_pcb_screen.h>
+#include <colors_selection.h>
+#include <trigo.h>
+#include <msgpanel.h>
+
+#include <pcbnew.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_drawsegment.h>
+#include <base_units.h>
+
+
+DRAWSEGMENT::DRAWSEGMENT( BOARD_ITEM* aParent, KICAD_T idtype ) :
+ BOARD_ITEM( aParent, idtype )
+{
+ m_Type = 0;
+ m_Angle = 0;
+ m_Flags = 0;
+ m_Shape = S_SEGMENT;
+ m_Width = Millimeter2iu( 0.15 ); // Gives a decent width
+}
+
+
+DRAWSEGMENT::~DRAWSEGMENT()
+{
+}
+
+
+const DRAWSEGMENT& DRAWSEGMENT::operator = ( const DRAWSEGMENT& rhs )
+{
+ // skip the linked list stuff, and parent
+
+ m_Type = rhs.m_Type;
+ m_Layer = rhs.m_Layer;
+ m_Width = rhs.m_Width;
+ m_Start = rhs.m_Start;
+ m_End = rhs.m_End;
+ m_Shape = rhs.m_Shape;
+ m_Angle = rhs.m_Angle;
+ m_TimeStamp = rhs.m_TimeStamp;
+ m_BezierC1 = rhs.m_BezierC1;
+ m_BezierC2 = rhs.m_BezierC1;
+ m_BezierPoints = rhs.m_BezierPoints;
+
+ return *this;
+}
+
+
+void DRAWSEGMENT::Copy( DRAWSEGMENT* source )
+{
+ if( source == NULL ) // who would do this?
+ return;
+
+ *this = *source; // operator = ()
+}
+
+void DRAWSEGMENT::Rotate( const wxPoint& aRotCentre, double aAngle )
+{
+ switch( m_Shape )
+ {
+ case S_ARC:
+ case S_SEGMENT:
+ case S_CIRCLE:
+ // these can all be done by just rotating the start and end points
+ RotatePoint( &m_Start, aRotCentre, aAngle);
+ RotatePoint( &m_End, aRotCentre, aAngle);
+ break;
+
+ case S_POLYGON:
+ for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
+ {
+ RotatePoint( &m_PolyPoints[ii], aRotCentre, aAngle);
+ }
+ break;
+
+ case S_CURVE:
+ RotatePoint( &m_Start, aRotCentre, aAngle);
+ RotatePoint( &m_End, aRotCentre, aAngle);
+
+ for( unsigned int ii = 0; ii < m_BezierPoints.size(); ii++ )
+ {
+ RotatePoint( &m_BezierPoints[ii], aRotCentre, aAngle);
+ }
+ break;
+
+ case S_RECT:
+ default:
+ // un-handled edge transform
+ wxASSERT_MSG( false, wxT( "DRAWSEGMENT::Rotate not implemented for "
+ + ShowShape( m_Shape ) ) );
+ break;
+ }
+};
+
+void DRAWSEGMENT::Flip( const wxPoint& aCentre )
+{
+ m_Start.y = aCentre.y - (m_Start.y - aCentre.y);
+ m_End.y = aCentre.y - (m_End.y - aCentre.y);
+
+ if( m_Shape == S_ARC )
+ m_Angle = -m_Angle;
+
+ // DRAWSEGMENT items are not allowed on copper layers, so
+ // copper layers count is not taken in accoun in Flip transform
+ SetLayer( FlipLayer( GetLayer() ) );
+}
+
+const wxPoint DRAWSEGMENT::GetCenter() const
+{
+ wxPoint c;
+
+ switch( m_Shape )
+ {
+ case S_ARC:
+ case S_CIRCLE:
+ c = m_Start;
+ break;
+
+ case S_SEGMENT:
+ // Midpoint of the line
+ c = ( GetStart() + GetEnd() ) / 2;
+ break;
+
+ case S_POLYGON:
+ case S_RECT:
+ case S_CURVE:
+ c = GetBoundingBox().Centre();
+ break;
+
+ default:
+ wxASSERT_MSG( false, "DRAWSEGMENT::GetCentre not implemented for shape"
+ + ShowShape( GetShape() ) );
+ break;
+ }
+
+ return c;
+}
+
+const wxPoint DRAWSEGMENT::GetArcEnd() const
+{
+ wxPoint endPoint; // start of arc
+
+ switch( m_Shape )
+ {
+ case S_ARC:
+ // rotate the starting point of the arc, given by m_End, through the
+ // angle m_Angle to get the ending point of the arc.
+ // m_Start is the arc centre
+ endPoint = m_End; // m_End = start point of arc
+ RotatePoint( &endPoint, m_Start, -m_Angle );
+ break;
+
+ default:
+ ;
+ }
+
+ return endPoint; // after rotation, the end of the arc.
+}
+
+double DRAWSEGMENT::GetArcAngleStart() const
+{
+ // due to the Y axis orient atan2 needs - y value
+ double angleStart = ArcTangente( GetArcStart().y - GetCenter().y,
+ GetArcStart().x - GetCenter().x );
+
+ // Normalize it to 0 ... 360 deg, to avoid discontinuity for angles near 180 deg
+ // because 180 deg and -180 are very near angles when ampping betewwen -180 ... 180 deg.
+ // and this is not easy to handle in calculations
+ NORMALIZE_ANGLE_POS( angleStart );
+
+ return angleStart;
+}
+
+
+void DRAWSEGMENT::SetAngle( double aAngle )
+{
+ NORMALIZE_ANGLE_360( aAngle );
+
+ m_Angle = aAngle;
+}
+
+
+MODULE* DRAWSEGMENT::GetParentModule() const
+{
+ if( m_Parent->Type() != PCB_MODULE_T )
+ return NULL;
+
+ return (MODULE*) m_Parent;
+}
+
+
+void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
+ const wxPoint& aOffset )
+{
+ int ux0, uy0, dx, dy;
+ int l_trace;
+ int radius;
+
+ LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
+ EDA_COLOR_T color;
+
+ BOARD * brd = GetBoard( );
+
+ if( brd->IsLayerVisible( GetLayer() ) == false )
+ return;
+
+ color = brd->GetLayerColor( GetLayer() );
+
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
+
+ if( ( draw_mode & GR_ALLOW_HIGHCONTRAST ) && displ_opts && displ_opts->m_ContrastModeDisplay )
+ {
+ if( !IsOnLayer( curr_layer ) && !IsOnLayer( Edge_Cuts ) )
+ ColorTurnToDarkDarkGray( &color );
+ }
+
+ GRSetDrawMode( DC, draw_mode );
+ l_trace = m_Width >> 1; // half trace width
+
+ // Line start point or Circle and Arc center
+ ux0 = m_Start.x + aOffset.x;
+ uy0 = m_Start.y + aOffset.y;
+
+ // Line end point or circle and arc start point
+ dx = m_End.x + aOffset.x;
+ dy = m_End.y + aOffset.y;
+
+ bool filled = displ_opts ? displ_opts->m_DisplayDrawItemsFill : FILLED;
+
+ if( m_Flags & FORCE_SKETCH )
+ filled = SKETCH;
+
+ switch( m_Shape )
+ {
+ case S_CIRCLE:
+ radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
+
+ if( filled )
+ {
+ GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius, m_Width, color );
+ }
+ else
+ {
+ GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius - l_trace, color );
+ GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius + l_trace, color );
+ }
+
+ break;
+
+ case S_ARC:
+ double StAngle, EndAngle;
+ radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
+ StAngle = ArcTangente( dy - uy0, dx - ux0 );
+ EndAngle = StAngle + m_Angle;
+
+ if( !panel->GetPrintMirrored() )
+ {
+ if( StAngle > EndAngle )
+ std::swap( StAngle, EndAngle );
+ }
+ else // Mirrored mode: arc orientation is reversed
+ {
+ if( StAngle < EndAngle )
+ std::swap( StAngle, EndAngle );
+ }
+
+ if( filled )
+ {
+ GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
+ radius, m_Width, color );
+ }
+ else
+ {
+ GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
+ radius - l_trace, color );
+ GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
+ radius + l_trace, color );
+ }
+
+ break;
+
+ case S_CURVE:
+ m_BezierPoints = Bezier2Poly( m_Start, m_BezierC1, m_BezierC2, m_End );
+
+ for( unsigned int i=1; i < m_BezierPoints.size(); i++ )
+ {
+ if( filled )
+ {
+ GRFillCSegm( panel->GetClipBox(), DC,
+ m_BezierPoints[i].x, m_BezierPoints[i].y,
+ m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
+ m_Width, color );
+ }
+ else
+ {
+ GRCSegm( panel->GetClipBox(), DC,
+ m_BezierPoints[i].x, m_BezierPoints[i].y,
+ m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
+ m_Width, color );
+ }
+ }
+
+ break;
+
+ default:
+ if( filled )
+ {
+ GRFillCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
+ }
+ else
+ {
+ GRCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
+ }
+
+ break;
+ }
+}
+
+
+// see pcbstruct.h
+void DRAWSEGMENT::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString msg;
+ wxASSERT( m_Parent );
+
+ msg = _( "Drawing" );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) );
+
+ wxString shape = _( "Shape" );
+
+ switch( m_Shape )
+ {
+ case S_CIRCLE:
+ aList.push_back( MSG_PANEL_ITEM( shape, _( "Circle" ), RED ) );
+ break;
+
+ case S_ARC:
+ aList.push_back( MSG_PANEL_ITEM( shape, _( "Arc" ), RED ) );
+ msg.Printf( wxT( "%.1f" ), m_Angle / 10.0 );
+ aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), msg, RED ) );
+ break;
+
+ case S_CURVE:
+ aList.push_back( MSG_PANEL_ITEM( shape, _( "Curve" ), RED ) );
+ break;
+
+ default:
+ {
+ aList.push_back( MSG_PANEL_ITEM( shape, _( "Segment" ), RED ) );
+
+ msg = ::CoordinateToString( GetLineLength( m_Start, m_End ) );
+ aList.push_back( MSG_PANEL_ITEM( _( "Length" ), msg, DARKGREEN ) );
+
+ // angle counter-clockwise from 3'o-clock
+ const double deg = RAD2DEG( atan2( m_Start.y - m_End.y,
+ m_End.x - m_Start.x ) );
+ msg.Printf( wxT( "%.1f" ), deg );
+ aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), msg, DARKGREEN ) );
+ }
+ }
+
+ wxString start;
+ start << GetStart();
+
+ wxString end;
+ end << GetEnd();
+
+ aList.push_back( MSG_PANEL_ITEM( start, end, DARKGREEN ) );
+ aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), GetLayerName(), DARKBROWN ) );
+ msg = ::CoordinateToString( m_Width );
+ aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, DARKCYAN ) );
+}
+
+
+const EDA_RECT DRAWSEGMENT::GetBoundingBox() const
+{
+ EDA_RECT bbox;
+
+ bbox.SetOrigin( m_Start );
+
+ switch( m_Shape )
+ {
+ case S_SEGMENT:
+ bbox.SetEnd( m_End );
+ break;
+
+ case S_CIRCLE:
+ bbox.Inflate( GetRadius() );
+ break;
+
+ case S_ARC:
+ computeArcBBox( bbox );
+ break;
+
+ case S_POLYGON:
+ {
+ wxPoint p_end;
+ MODULE* module = GetParentModule();
+
+ for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
+ {
+ wxPoint pt = m_PolyPoints[ii];
+
+ if( module ) // Transform, if we belong to a module
+ {
+ RotatePoint( &pt, module->GetOrientation() );
+ pt += module->GetPosition();
+ }
+
+ if( ii == 0 )
+ p_end = pt;
+
+ bbox.SetX( std::min( bbox.GetX(), pt.x ) );
+ bbox.SetY( std::min( bbox.GetY(), pt.y ) );
+ p_end.x = std::max( p_end.x, pt.x );
+ p_end.y = std::max( p_end.y, pt.y );
+ }
+
+ bbox.SetEnd( p_end );
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ bbox.Inflate( ((m_Width+1) / 2) + 1 );
+ bbox.Normalize();
+
+ return bbox;
+}
+
+
+bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const
+{
+ switch( m_Shape )
+ {
+ case S_CIRCLE:
+ case S_ARC:
+ {
+ wxPoint relPos = aPosition - GetCenter();
+ int radius = GetRadius();
+ int dist = KiROUND( EuclideanNorm( relPos ) );
+
+ if( abs( radius - dist ) <= ( m_Width / 2 ) )
+ {
+ if( m_Shape == S_CIRCLE )
+ return true;
+
+ // For arcs, the test point angle must be >= arc angle start
+ // and <= arc angle end
+ // However angle values > 360 deg are not easy to handle
+ // so we calculate the relative angle between arc start point and teast point
+ // this relative arc should be < arc angle if arc angle > 0 (CW arc)
+ // and > arc angle if arc angle < 0 (CCW arc)
+ double arc_angle_start = GetArcAngleStart(); // Always 0.0 ... 360 deg, in 0.1 deg
+
+ double arc_hittest = ArcTangente( relPos.y, relPos.x );
+
+ // Calculate relative angle between the starting point of the arc, and the test point
+ arc_hittest -= arc_angle_start;
+
+ // Normalise arc_hittest between 0 ... 360 deg
+ NORMALIZE_ANGLE_POS( arc_hittest );
+
+ // Check angle: inside the arc angle when it is > 0
+ // and outside the not drawn arc when it is < 0
+ if( GetAngle() >= 0.0 )
+ {
+ if( arc_hittest <= GetAngle() )
+ return true;
+ }
+ else
+ {
+ if( arc_hittest >= (3600.0 + GetAngle()) )
+ return true;
+ }
+ }
+ }
+ break;
+
+ case S_CURVE:
+ for( unsigned int i= 1; i < m_BezierPoints.size(); i++)
+ {
+ if( TestSegmentHit( aPosition, m_BezierPoints[i-1], m_BezierPoints[i-1], m_Width / 2 ) )
+ return true;
+ }
+ break;
+
+ case S_SEGMENT:
+ if( TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 ) )
+ return true;
+ break;
+
+ case S_POLYGON: // not yet handled
+ break;
+
+ default:
+ wxASSERT_MSG( 0, wxString::Format( "unknown DRAWSEGMENT shape: %d", m_Shape ) );
+ break;
+ }
+
+ return false;
+}
+
+
+bool DRAWSEGMENT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ wxPoint p1, p2;
+ int radius;
+ float theta;
+ EDA_RECT arect = aRect;
+ arect.Inflate( aAccuracy );
+
+ switch( m_Shape )
+ {
+ case S_CIRCLE:
+ // Test if area intersects or contains the circle:
+ if( aContained )
+ return arect.Contains( GetBoundingBox() );
+ else
+ return arect.Intersects( GetBoundingBox() );
+ break;
+
+ case S_ARC:
+ radius = hypot( (double)( GetEnd().x - GetStart().x ),
+ (double)( GetEnd().y - GetStart().y ) );
+ theta = std::atan2( GetEnd().y - GetStart().y , GetEnd().x - GetStart().x );
+
+ //Approximate the arc with two lines. This should be accurate enough for selection.
+ p1.x = radius * std::cos( theta + M_PI/4 ) + GetStart().x;
+ p1.y = radius * std::sin( theta + M_PI/4 ) + GetStart().y;
+ p2.x = radius * std::cos( theta + M_PI/2 ) + GetStart().x;
+ p2.y = radius * std::sin( theta + M_PI/2 ) + GetStart().y;
+
+ if( aContained )
+ return arect.Contains( GetEnd() ) && aRect.Contains( p1 ) && aRect.Contains( p2 );
+ else
+ return arect.Intersects( GetEnd(), p1 ) || aRect.Intersects( p1, p2 );
+
+ break;
+
+ case S_SEGMENT:
+ if( aContained )
+ return arect.Contains( GetStart() ) && aRect.Contains( GetEnd() );
+ else
+ return arect.Intersects( GetStart(), GetEnd() );
+
+ break;
+
+ case S_CURVE:
+ case S_POLYGON: // not yet handled
+ break;
+
+ default:
+ wxASSERT_MSG( 0, wxString::Format( "unknown DRAWSEGMENT shape: %d", m_Shape ) );
+ break;
+ }
+
+ return false;
+}
+
+
+wxString DRAWSEGMENT::GetSelectMenuText() const
+{
+ wxString text;
+ wxString temp = ::LengthDoubleToString( GetLength() );
+
+ text.Printf( _( "Pcb Graphic: %s, length %s on %s" ),
+ GetChars( ShowShape( m_Shape ) ),
+ GetChars( temp ), GetChars( GetLayerName() ) );
+
+ return text;
+}
+
+
+EDA_ITEM* DRAWSEGMENT::Clone() const
+{
+ return new DRAWSEGMENT( *this );
+}
+
+
+const BOX2I DRAWSEGMENT::ViewBBox() const
+{
+ // For arcs - do not include the center point in the bounding box,
+ // it is redundant for displaying an arc
+ if( m_Shape == S_ARC )
+ {
+ EDA_RECT bbox;
+ bbox.SetOrigin( m_End );
+ computeArcBBox( bbox );
+ return BOX2I( bbox.GetOrigin(), bbox.GetSize() );
+ }
+
+ return EDA_ITEM::ViewBBox();
+}
+
+
+void DRAWSEGMENT::computeArcBBox( EDA_RECT& aBBox ) const
+{
+ aBBox.Merge( m_End );
+ // TODO perhaps the above line can be replaced with this one, so we do not include the center
+ //aBBox.SetOrigin( m_End );
+ wxPoint end = m_End;
+ RotatePoint( &end, m_Start, -m_Angle );
+ aBBox.Merge( end );
+
+ // Determine the starting quarter
+ // 0 right-bottom
+ // 1 left-bottom
+ // 2 left-top
+ // 3 right-top
+ unsigned int quarter = 0; // assume right-bottom
+
+ if( m_End.x < m_Start.x )
+ {
+ if( m_End.y <= m_Start.y )
+ quarter = 2;
+ else // ( m_End.y > m_Start.y )
+ quarter = 1;
+ }
+ else if( m_End.x >= m_Start.x )
+ {
+ if( m_End.y < m_Start.y )
+ quarter = 3;
+ else if( m_End.x == m_Start.x )
+ quarter = 1;
+ }
+
+ int radius = GetRadius();
+ int angle = (int) GetArcAngleStart() % 900 + m_Angle;
+ bool directionCW = ( m_Angle > 0 ); // Is the direction of arc clockwise?
+
+ // Make the angle positive, so we go clockwise and merge points belonging to the arc
+ if( !directionCW )
+ {
+ angle = 900 - angle;
+ quarter = ( quarter + 3 ) % 4; // -1 modulo arithmetic
+ }
+
+ while( angle > 900 )
+ {
+ switch( quarter )
+ {
+ case 0:
+ aBBox.Merge( wxPoint( m_Start.x, m_Start.y + radius ) ); // down
+ break;
+
+ case 1:
+ aBBox.Merge( wxPoint( m_Start.x - radius, m_Start.y ) ); // left
+ break;
+
+ case 2:
+ aBBox.Merge( wxPoint( m_Start.x, m_Start.y - radius ) ); // up
+ break;
+
+ case 3:
+ aBBox.Merge( wxPoint( m_Start.x + radius, m_Start.y ) ); // right
+ break;
+ }
+
+ if( directionCW )
+ ++quarter;
+ else
+ quarter += 3; // -1 modulo arithmetic
+
+ quarter %= 4;
+ angle -= 900;
+ }
+}
diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h
new file mode 100644
index 0000000..411a5a2
--- /dev/null
+++ b/pcbnew/class_drawsegment.h
@@ -0,0 +1,256 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_drawsegment.h
+ * @brief Class to handle a graphic segment.
+ */
+
+#ifndef CLASS_DRAWSEGMENT_H_
+#define CLASS_DRAWSEGMENT_H_
+
+#include <class_board_item.h>
+#include <PolyLine.h>
+#include <math_for_graphics.h>
+#include <trigo.h>
+#include <common.h>
+
+
+class LINE_READER;
+class EDA_DRAW_FRAME;
+class MODULE;
+class MSG_PANEL_ITEM;
+
+
+class DRAWSEGMENT : public BOARD_ITEM
+{
+protected:
+ int m_Width; ///< thickness of lines ...
+ wxPoint m_Start; ///< Line start point or Circle and Arc center
+ wxPoint m_End; ///< Line end point or circle and arc start point
+
+ STROKE_T m_Shape; ///< Shape: line, Circle, Arc
+ int m_Type; ///< Used in complex associations ( Dimensions.. )
+ double m_Angle; ///< Used only for Arcs: Arc angle in 1/10 deg
+ wxPoint m_BezierC1; ///< Bezier Control Point 1
+ wxPoint m_BezierC2; ///< Bezier Control Point 2
+
+ std::vector<wxPoint> m_BezierPoints;
+ std::vector<wxPoint> m_PolyPoints;
+
+ // Computes the bounding box for an arc
+ void computeArcBBox( EDA_RECT& aBBox ) const;
+
+public:
+ DRAWSEGMENT( BOARD_ITEM* aParent = NULL, KICAD_T idtype = PCB_LINE_T );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~DRAWSEGMENT();
+
+ /// skip the linked list stuff, and parent
+ const DRAWSEGMENT& operator = ( const DRAWSEGMENT& rhs );
+
+ static inline bool ClassOf( const EDA_ITEM* aItem )
+ {
+ return aItem && PCB_LINE_T == aItem->Type();
+ }
+
+ void SetWidth( int aWidth ) { m_Width = aWidth; }
+ int GetWidth() const { return m_Width; }
+
+ /**
+ * Function SetAngle
+ * sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
+ * @param aAngle is tenths of degrees, but will soon be degrees.
+ */
+ void SetAngle( double aAngle ); // encapsulates the transition to degrees
+ double GetAngle() const { return m_Angle; }
+
+ void SetType( int aType ) { m_Type = aType; }
+ int GetType() const { return m_Type; }
+
+ void SetShape( STROKE_T aShape ) { m_Shape = aShape; }
+ STROKE_T GetShape() const { return m_Shape; }
+
+ void SetBezControl1( const wxPoint& aPoint ) { m_BezierC1 = aPoint; }
+ const wxPoint& GetBezControl1() const { return m_BezierC1; }
+
+ void SetBezControl2( const wxPoint& aPoint ) { m_BezierC2 = aPoint; }
+ const wxPoint& GetBezControl2() const { return m_BezierC2; }
+
+ void SetPosition( const wxPoint& aPos ) { m_Start = aPos; } // override
+ const wxPoint& GetPosition() const { return m_Start; } // override
+
+ /**
+ * Function GetStart
+ * returns the starting point of the graphic
+ */
+ const wxPoint& GetStart() const { return m_Start; }
+ void SetStart( const wxPoint& aStart ) { m_Start = aStart; }
+ void SetStartY( int y ) { m_Start.y = y; }
+ void SetStartX( int x ) { m_Start.x = x; }
+
+ /**
+ * Function GetEnd
+ * returns the ending point of the graphic
+ */
+ const wxPoint& GetEnd() const { return m_End; }
+ void SetEnd( const wxPoint& aEnd ) { m_End = aEnd; }
+ void SetEndY( int y ) { m_End.y = y; }
+ void SetEndX( int x ) { m_End.x = x; }
+
+ // Some attributes are read only, since they are "calculated" from
+ // m_Start, m_End, and m_Angle.
+ // No Set...() function for these attributes.
+
+ const wxPoint GetCenter() const; //override
+ const wxPoint& GetArcStart() const { return m_End; }
+ const wxPoint GetArcEnd() const;
+
+ /**
+ * function GetArcAngleStart()
+ * @return the angle of the starting point of this arc, between 0 and 3600 in 0.1 deg
+ */
+ double GetArcAngleStart() const;
+
+ /**
+ * Function GetRadius
+ * returns the radius of this item
+ * Has meaning only for arc and circle
+ */
+ int GetRadius() const
+ {
+ double radius = GetLineLength( m_Start, m_End );
+ return KiROUND( radius );
+ }
+
+ /**
+ * Initialize the start arc point. can be used for circles
+ * to initialize one point of the cicumference
+ */
+ void SetArcStart( const wxPoint& aArcStartPoint )
+ { m_End = aArcStartPoint; }
+
+ /** For arcs and circles:
+ */
+ void SetCenter( const wxPoint& aCenterPoint ) { m_Start = aCenterPoint; }
+
+ /**
+ * Function GetParentModule
+ * returns a pointer to the parent module, or NULL if DRAWSEGMENT does not
+ * belong to a module.
+ * @return MODULE* - pointer to the parent module or NULL.
+ */
+ MODULE* GetParentModule() const;
+
+ // Accessors:
+ const std::vector<wxPoint>& GetBezierPoints() const { return m_BezierPoints; }
+ const std::vector<wxPoint>& GetPolyPoints() const { return m_PolyPoints; }
+ // same accessor, to add/change corners of the polygon
+ std::vector<wxPoint>& GetPolyPoints() { return m_PolyPoints; }
+
+ void SetBezierPoints( const std::vector<wxPoint>& aPoints )
+ {
+ m_BezierPoints = aPoints;
+ }
+
+ void SetPolyPoints( const std::vector<wxPoint>& aPoints )
+ {
+ m_PolyPoints = aPoints;
+ }
+
+ void Copy( DRAWSEGMENT* source );
+
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
+ GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset );
+
+ virtual void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ virtual const EDA_RECT GetBoundingBox() const;
+
+ virtual bool HitTest( const wxPoint& aPosition ) const;
+
+ /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
+ * bool aContained = true, int aAccuracy ) const
+ */
+ bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const;
+
+ wxString GetClass() const
+ {
+ return wxT( "DRAWSEGMENT" );
+ }
+
+ /**
+ * Function GetLength
+ * returns the length of the track using the hypotenuse calculation.
+ * @return double - the length of the track
+ */
+ double GetLength() const
+ {
+ return GetLineLength( GetStart(), GetEnd() );
+ }
+
+ virtual void Move( const wxPoint& aMoveVector )
+ {
+ m_Start += aMoveVector;
+ m_End += aMoveVector;
+ }
+
+ virtual void Rotate( const wxPoint& aRotCentre, double aAngle );
+
+ virtual void Flip( const wxPoint& aCentre );
+
+ /**
+ * Function TransformShapeWithClearanceToPolygon
+ * Convert the track shape to a closed polygon
+ * Used in filling zones calculations
+ * Circles and arcs are approximated by segments
+ * @param aCornerBuffer = a buffer to store the polygon
+ * @param aClearanceValue = the clearance around the pad
+ * @param aCircleToSegmentsCount = the number of segments to approximate a circle
+ * @param aCorrectionFactor = the correction to apply to circles radius to keep
+ * clearance when the circle is approximated by segment bigger or equal
+ * to the real clearance value (usually near from 1.0)
+ */
+ void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
+ int aClearanceValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor ) const;
+
+ virtual wxString GetSelectMenuText() const;
+
+ virtual BITMAP_DEF GetMenuImage() const { return add_dashed_line_xpm; }
+
+ virtual EDA_ITEM* Clone() const;
+
+ /// @copydoc VIEW_ITEM::ViewBBox()
+ virtual const BOX2I ViewBBox() const;
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+};
+
+#endif // CLASS_DRAWSEGMENT_H_
diff --git a/pcbnew/class_drc_item.cpp b/pcbnew/class_drc_item.cpp
new file mode 100644
index 0000000..ff145f4
--- /dev/null
+++ b/pcbnew/class_drc_item.cpp
@@ -0,0 +1,137 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/*************************************************/
+/* class_drc_item.cpp - DRC_ITEM class functions */
+/*************************************************/
+#include <fctsys.h>
+#include <common.h>
+
+#include <pcbnew.h>
+#include <drc_stuff.h>
+#include <class_drc_item.h>
+#include <base_units.h>
+
+
+wxString DRC_ITEM::GetErrorText() const
+{
+ switch( m_ErrorCode )
+ {
+ case DRCE_UNCONNECTED_PADS:
+ return wxString( _( "Unconnected pads" ) );
+ case DRCE_TRACK_NEAR_THROUGH_HOLE:
+ return wxString( _( "Track near thru-hole" ) );
+ case DRCE_TRACK_NEAR_PAD:
+ return wxString( _( "Track near pad" ) );
+ case DRCE_TRACK_NEAR_VIA:
+ return wxString( _( "Track near via" ) );
+ case DRCE_VIA_NEAR_VIA:
+ return wxString( _( "Via near via" ) );
+ case DRCE_VIA_NEAR_TRACK:
+ return wxString( _( "Via near track" ) );
+ case DRCE_TRACK_ENDS1:
+ case DRCE_TRACK_ENDS2:
+ case DRCE_TRACK_ENDS3:
+ case DRCE_TRACK_ENDS4:
+ case DRCE_ENDS_PROBLEM1:
+ case DRCE_ENDS_PROBLEM2:
+ case DRCE_ENDS_PROBLEM3:
+ case DRCE_ENDS_PROBLEM4:
+ case DRCE_ENDS_PROBLEM5:
+ return wxString( _( "Two track ends too close" ) );
+ case DRCE_TRACK_SEGMENTS_TOO_CLOSE:
+ return wxString( _( "Two parallel track segments too close" ) );
+ case DRCE_TRACKS_CROSSING:
+ return wxString( _( "Tracks crossing" ) );
+ case DRCE_PAD_NEAR_PAD1:
+ return wxString( _( "Pad near pad" ) );
+ case DRCE_VIA_HOLE_BIGGER:
+ return wxString( _( "Via hole > diameter" ) );
+ case DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR:
+ return wxString( _( "Micro Via: incorrect layer pairs (not adjacent)" ) );
+ case COPPERAREA_INSIDE_COPPERAREA:
+ return wxString( _( "Copper area inside copper area" ) );
+ case COPPERAREA_CLOSE_TO_COPPERAREA:
+ return wxString( _( "Copper areas intersect or are too close" ) );
+
+ case DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE:
+ return wxString( _( "Copper area belongs a net which has no pads. This is strange" ) );
+
+ case DRCE_HOLE_NEAR_PAD:
+ return wxString( _( "Hole near pad" ) );
+ case DRCE_HOLE_NEAR_TRACK:
+ return wxString( _( "Hole near track" ) );
+ case DRCE_TOO_SMALL_TRACK_WIDTH:
+ return wxString( _( "Too small track width" ) );
+ case DRCE_TOO_SMALL_VIA:
+ return wxString( _( "Too small via size" ) );
+ case DRCE_TOO_SMALL_MICROVIA:
+ return wxString( _( "Too small micro via size" ) );
+
+ // use &lt; since this is text ultimately embedded in HTML
+ case DRCE_NETCLASS_TRACKWIDTH:
+ return wxString( _( "NetClass Track Width &lt; global limit" ) );
+ case DRCE_NETCLASS_CLEARANCE:
+ return wxString( _( "NetClass Clearance &lt; global limit" ) );
+ case DRCE_NETCLASS_VIASIZE:
+ return wxString( _( "NetClass Via Dia &lt; global limit" ) );
+ case DRCE_NETCLASS_VIADRILLSIZE:
+ return wxString( _( "NetClass Via Drill &lt; global limit" ) );
+ case DRCE_NETCLASS_uVIASIZE:
+ return wxString( _( "NetClass uVia Dia &lt; global limit" ) );
+ case DRCE_NETCLASS_uVIADRILLSIZE:
+ return wxString( _( "NetClass uVia Drill &lt; global limit" ) );
+
+ case DRCE_VIA_INSIDE_KEEPOUT:
+ return wxString( _( "Via inside a keepout area" ) );
+
+ case DRCE_TRACK_INSIDE_KEEPOUT:
+ return wxString( _( "Track inside a keepout area" ) );
+
+ case DRCE_PAD_INSIDE_KEEPOUT:
+ return wxString( _( "Pad inside a keepout area" ) );
+
+ case DRCE_VIA_INSIDE_TEXT:
+ return wxString( _( "Via inside a text" ) );
+
+ case DRCE_TRACK_INSIDE_TEXT:
+ return wxString( _( "Track inside a text" ) );
+
+ case DRCE_PAD_INSIDE_TEXT:
+ return wxString( _( "Pad inside a text" ) );
+
+ default:
+ return wxString::Format( wxT( "Unknown DRC error code %d" ), m_ErrorCode );
+ }
+}
+
+
+wxString DRC_ITEM::ShowCoord( const wxPoint& aPos )
+{
+ wxString ret;
+
+ ret << aPos;
+ return ret;
+}
diff --git a/pcbnew/class_edge_mod.cpp b/pcbnew/class_edge_mod.cpp
new file mode 100644
index 0000000..04376bb
--- /dev/null
+++ b/pcbnew/class_edge_mod.cpp
@@ -0,0 +1,400 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_edge_mod.cpp
+ * @brief EDGE_MODULE class definition.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <wxstruct.h>
+#include <trigo.h>
+#include <class_drawpanel.h>
+#include <class_pcb_screen.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <colors_selection.h>
+#include <richio.h>
+#include <macros.h>
+#include <math_for_graphics.h>
+#include <wxBasePcbFrame.h>
+#include <msgpanel.h>
+#include <base_units.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+
+#include <stdio.h>
+
+EDGE_MODULE::EDGE_MODULE( MODULE* parent, STROKE_T aShape ) :
+ DRAWSEGMENT( parent, PCB_MODULE_EDGE_T )
+{
+ m_Shape = aShape;
+ m_Angle = 0;
+ m_Layer = F_SilkS;
+}
+
+
+EDGE_MODULE::~EDGE_MODULE()
+{
+}
+
+
+const EDGE_MODULE& EDGE_MODULE::operator = ( const EDGE_MODULE& rhs )
+{
+ if( &rhs == this )
+ return *this;
+
+ DRAWSEGMENT::operator=( rhs );
+
+ m_Start0 = rhs.m_Start0;
+ m_End0 = rhs.m_End0;
+
+ m_PolyPoints = rhs.m_PolyPoints; // std::vector copy
+ return *this;
+}
+
+
+void EDGE_MODULE::Copy( EDGE_MODULE* source )
+{
+ if( source == NULL )
+ return;
+
+ *this = *source;
+}
+
+
+void EDGE_MODULE::SetLocalCoord()
+{
+ MODULE* module = (MODULE*) m_Parent;
+
+ if( module == NULL )
+ {
+ m_Start0 = m_Start;
+ m_End0 = m_End;
+ return;
+ }
+
+ m_Start0 = m_Start - module->GetPosition();
+ m_End0 = m_End - module->GetPosition();
+ double angle = module->GetOrientation();
+ RotatePoint( &m_Start0.x, &m_Start0.y, -angle );
+ RotatePoint( &m_End0.x, &m_End0.y, -angle );
+}
+
+
+void EDGE_MODULE::SetDrawCoord()
+{
+ MODULE* module = (MODULE*) m_Parent;
+
+ m_Start = m_Start0;
+ m_End = m_End0;
+
+ if( module )
+ {
+ RotatePoint( &m_Start.x, &m_Start.y, module->GetOrientation() );
+ RotatePoint( &m_End.x, &m_End.y, module->GetOrientation() );
+
+ m_Start += module->GetPosition();
+ m_End += module->GetPosition();
+ }
+}
+
+
+void EDGE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
+ const wxPoint& offset )
+{
+ int ux0, uy0, dx, dy, radius, StAngle, EndAngle;
+ LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
+
+ MODULE* module = (MODULE*) m_Parent;
+
+ if( !module )
+ return;
+
+ BOARD* brd = GetBoard( );
+
+ if( brd->IsLayerVisible( m_Layer ) == false )
+ return;
+
+ EDA_COLOR_T color = brd->GetLayerColor( m_Layer );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
+
+ if(( draw_mode & GR_ALLOW_HIGHCONTRAST ) && displ_opts && displ_opts->m_ContrastModeDisplay )
+ {
+ if( !IsOnLayer( curr_layer ) )
+ ColorTurnToDarkDarkGray( &color );
+ }
+
+ ux0 = m_Start.x - offset.x;
+ uy0 = m_Start.y - offset.y;
+
+ dx = m_End.x - offset.x;
+ dy = m_End.y - offset.y;
+
+ GRSetDrawMode( DC, draw_mode );
+ bool filled = displ_opts ? displ_opts->m_DisplayModEdgeFill : FILLED;
+
+ if( IsCopperLayer( m_Layer ) )
+ filled = displ_opts ? displ_opts->m_DisplayPcbTrackFill : FILLED;
+
+ switch( m_Shape )
+ {
+ case S_SEGMENT:
+ if( filled )
+ GRLine( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
+ else
+ // SKETCH Mode
+ GRCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
+
+ break;
+
+ case S_CIRCLE:
+ radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
+
+ if( filled )
+ {
+ GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius, m_Width, color );
+ }
+ else // SKETCH Mode
+ {
+ GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius + (m_Width / 2), color );
+ GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius - (m_Width / 2), color );
+ }
+
+ break;
+
+ case S_ARC:
+ radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
+ StAngle = ArcTangente( dy - uy0, dx - ux0 );
+ EndAngle = StAngle + m_Angle;
+
+ if( !panel->GetPrintMirrored() )
+ {
+ if( StAngle > EndAngle )
+ std::swap( StAngle, EndAngle );
+ }
+ else // Mirrored mode: arc orientation is reversed
+ {
+ if( StAngle < EndAngle )
+ std::swap( StAngle, EndAngle );
+ }
+
+ if( filled )
+ {
+ GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius, m_Width, color );
+ }
+ else // SKETCH Mode
+ {
+ GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
+ radius + (m_Width / 2), color );
+ GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
+ radius - (m_Width / 2), color );
+ }
+ break;
+
+ case S_POLYGON:
+ {
+ // We must compute absolute coordinates from m_PolyPoints
+ // which are relative to module position, orientation 0
+ std::vector<wxPoint> points = m_PolyPoints;
+
+ for( unsigned ii = 0; ii < points.size(); ii++ )
+ {
+ wxPoint& pt = points[ii];
+
+ RotatePoint( &pt.x, &pt.y, module->GetOrientation() );
+ pt += module->GetPosition() - offset;
+ }
+
+ GRPoly( panel->GetClipBox(), DC, points.size(), &points[0], true, m_Width, color, color );
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+// see class_edge_mod.h
+void EDGE_MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString msg;
+
+ MODULE* module = (MODULE*) m_Parent;
+
+ if( !module )
+ return;
+
+ BOARD* board = (BOARD*) module->GetParent();
+
+ if( !board )
+ return;
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), module->GetReference(), DARKCYAN ) );
+ aList.push_back( MSG_PANEL_ITEM( _( "Value" ), module->GetValue(), BLUE ) );
+ msg.Printf( wxT( "%8.8lX" ), module->GetTimeStamp() );
+ aList.push_back( MSG_PANEL_ITEM( _( "TimeStamp" ), msg, BROWN ) );
+ aList.push_back( MSG_PANEL_ITEM( _( "Footprint Layer" ),
+ module->GetLayerName(), RED ) );
+
+ // append the features shared with the base class
+ DRAWSEGMENT::GetMsgPanelInfo( aList );
+}
+
+
+
+wxString EDGE_MODULE::GetSelectMenuText() const
+{
+ wxString text;
+ text.Printf( _( "Graphic (%s) on %s of %s" ),
+ GetChars( ShowShape( m_Shape ) ),
+ GetChars( GetLayerName() ),
+ GetChars( ((MODULE*) GetParent())->GetReference() ) );
+
+ return text;
+}
+
+
+EDA_ITEM* EDGE_MODULE::Clone() const
+{
+ return new EDGE_MODULE( *this );
+}
+
+
+void EDGE_MODULE::Flip( const wxPoint& aCentre )
+{
+ wxPoint pt;
+
+ switch( GetShape() )
+ {
+ case S_ARC:
+ SetAngle( -GetAngle() );
+ //Fall through
+ default:
+ case S_SEGMENT:
+ pt = GetStart();
+ MIRROR( pt.y, aCentre.y );
+ SetStart( pt );
+
+ pt = GetEnd();
+ MIRROR( pt.y, aCentre.y );
+ SetEnd( pt );
+
+ MIRROR( m_Start0.y, 0 );
+ MIRROR( m_End0.y, 0 );
+ break;
+
+ case S_POLYGON:
+ // polygon corners coordinates are always relative to the
+ // footprint position, orientation 0
+ for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
+ MIRROR( m_PolyPoints[ii].y, 0 );
+ }
+
+ // DRAWSEGMENT items are not usually on copper layers, but
+ // it can happen in microwave apps.
+ // However, currently, only on Front or Back layers.
+ // So the copper layers count is not taken in account
+ SetLayer( FlipLayer( GetLayer() ) );
+}
+
+
+void EDGE_MODULE::Mirror( wxPoint aCentre, bool aMirrorAroundXAxis )
+{
+ // Mirror an edge of the footprint. the layer is not modified
+ // This is a footprint shape modification.
+ switch( GetShape() )
+ {
+ case S_ARC:
+ SetAngle( -GetAngle() );
+ //Fall through
+ default:
+ case S_SEGMENT:
+ if( aMirrorAroundXAxis )
+ {
+ MIRROR( m_Start0.y, aCentre.y );
+ MIRROR( m_End0.y, aCentre.y );
+ }
+ else
+ {
+ MIRROR( m_Start0.x, aCentre.x );
+ MIRROR( m_End0.x, aCentre.x );
+ }
+ break;
+
+ case S_POLYGON:
+ // polygon corners coordinates are always relative to the
+ // footprint position, orientation 0
+ for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
+ {
+ if( aMirrorAroundXAxis )
+ MIRROR( m_PolyPoints[ii].y, aCentre.y );
+ else
+ MIRROR( m_PolyPoints[ii].x, aCentre.x );
+ }
+ }
+
+ SetDrawCoord();
+}
+
+void EDGE_MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
+{
+ // We should rotate the relative coordinates, but to avoid duplicate code,
+ // do the base class rotation of draw coordinates, which is acceptable
+ // because in module editor, m_Pos0 = m_Pos
+ DRAWSEGMENT::Rotate( aRotCentre, aAngle );
+
+ // and now update the relative coordinates, which are
+ // the reference in most transforms.
+ SetLocalCoord();
+}
+
+
+void EDGE_MODULE::Move( const wxPoint& aMoveVector )
+{
+ // Move an edge of the footprint.
+ // This is a footprint shape modification.
+ m_Start0 += aMoveVector;
+ m_End0 += aMoveVector;
+
+ switch( GetShape() )
+ {
+ default:
+ break;
+
+ case S_POLYGON:
+ // polygon corners coordinates are always relative to the
+ // footprint position, orientation 0
+ for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
+ m_PolyPoints[ii] += aMoveVector;
+ }
+
+ SetDrawCoord();
+}
diff --git a/pcbnew/class_edge_mod.h b/pcbnew/class_edge_mod.h
new file mode 100644
index 0000000..b2eebc5
--- /dev/null
+++ b/pcbnew/class_edge_mod.h
@@ -0,0 +1,145 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_edge_mod.h
+ * @brief EDGE_MODULE class definition.
+ */
+
+#ifndef CLASS_EDGE_MOD_H_
+#define CLASS_EDGE_MOD_H_
+
+
+#include <wx/gdicmn.h>
+
+#include <class_drawsegment.h>
+
+
+class LINE_READER;
+class MSG_PANEL_ITEM;
+
+
+class EDGE_MODULE : public DRAWSEGMENT
+{
+public:
+ EDGE_MODULE( MODULE* parent, STROKE_T aShape = S_SEGMENT );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+ // EDGE_MODULE( const EDGE_MODULE& );
+
+ ~EDGE_MODULE();
+
+ /// skip the linked list stuff, and parent
+ const EDGE_MODULE& operator = ( const EDGE_MODULE& rhs );
+
+ static inline bool ClassOf( const EDA_ITEM* aItem )
+ {
+ return aItem && PCB_MODULE_EDGE_T == aItem->Type();
+ }
+
+ void Copy( EDGE_MODULE* source ); // copy structure
+
+ /**
+ * Move an edge of the footprint.
+ * This is a footprint shape modification.
+ * (should be only called by a footprint editing function)
+ */
+ void Move( const wxPoint& aMoveVector );
+
+ /**
+ * Mirror an edge of the footprint.
+ * Do not change the layer
+ * This is a footprint shape modification.
+ * (should be only called by a footprint editing function)
+ */
+ void Mirror( const wxPoint aCentre, bool aMirrorAroundXAxis );
+
+ /**
+ * Rotate an edge of the footprint.
+ * This is a footprint shape modification.
+ * (should be only called by a footprint editing function )
+ */
+ void Rotate( const wxPoint& aRotCentre, double aAngle );
+
+ /**
+ * Flip entity relative to aCentre.
+ * The item is mirrored, and layer changed to the paired corresponding layer
+ * if it is on a paired layer
+ * This function should be called only from MODULE::Flip because there is
+ * not usual to flip an item alone, without flipping the parent footprint.
+ * (consider Mirror for a mirror transform).
+ */
+ void Flip( const wxPoint& aCentre );
+
+ void SetStart0( const wxPoint& aPoint ) { m_Start0 = aPoint; }
+ const wxPoint& GetStart0() const { return m_Start0; }
+
+ void SetEnd0( const wxPoint& aPoint ) { m_End0 = aPoint; }
+ const wxPoint& GetEnd0() const { return m_End0; }
+
+ /**
+ * Set relative coordinates from draw coordinates.
+ * Call in only when the geometry ov the footprint is modified
+ * and therefore the relative coordinates have to be updated from
+ * the draw coordinates
+ */
+ void SetLocalCoord();
+
+ /**
+ * Set draw coordinates (absolute values ) from relative coordinates.
+ * Must be called when a relative coordinate has changed, in order
+ * to see the changes on screen
+ */
+ void SetDrawCoord();
+
+ /* drawing functions */
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
+ GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset );
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ wxString GetClass() const
+ {
+ return wxT( "MGRAPHIC" );
+ }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return show_mod_edge_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+
+//protected: @todo: is it just me?
+
+ wxPoint m_Start0; // Start point or center, relative to module origin, orient 0.
+ wxPoint m_End0; // End point, relative to module origin, orient 0.
+};
+
+#endif // CLASS_EDGE_MOD_H_
diff --git a/pcbnew/class_footprint_wizard.cpp b/pcbnew/class_footprint_wizard.cpp
new file mode 100644
index 0000000..2d503c2
--- /dev/null
+++ b/pcbnew/class_footprint_wizard.cpp
@@ -0,0 +1,100 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 NBEE Embedded Systems SL, Miguel Angel Ajo <miguelangel@ajo.es>
+ * Copyright (C) 2013 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/**
+ * @file class_footprint_wizard.cpp
+ * @brief Class FOOTPRINT_WIZARD and FOOTPRINT_WIZARDS
+ */
+
+#include "class_footprint_wizard.h"
+
+
+FOOTPRINT_WIZARD::~FOOTPRINT_WIZARD()
+{
+}
+
+
+void FOOTPRINT_WIZARD::register_wizard()
+{
+ FOOTPRINT_WIZARDS::register_wizard( this );
+}
+
+
+std::vector<FOOTPRINT_WIZARD*> FOOTPRINT_WIZARDS::m_FootprintWizards;
+
+FOOTPRINT_WIZARD* FOOTPRINT_WIZARDS::GetWizard( int aIndex )
+{
+ return m_FootprintWizards[aIndex];
+}
+
+
+FOOTPRINT_WIZARD* FOOTPRINT_WIZARDS::GetWizard( wxString aName )
+{
+ int max = GetWizardsCount();
+
+ for( int i = 0; i<max; i++ )
+ {
+ FOOTPRINT_WIZARD* wizard = GetWizard( i );
+
+ wxString name = wizard->GetName();
+
+ if( name.Cmp( aName )==0 )
+ return wizard;
+ }
+
+ return NULL;
+}
+
+
+int FOOTPRINT_WIZARDS::GetWizardsCount()
+{
+ return m_FootprintWizards.size();
+}
+
+
+void FOOTPRINT_WIZARDS::register_wizard( FOOTPRINT_WIZARD* aWizard )
+{
+ m_FootprintWizards.push_back( aWizard );
+}
+
+
+bool FOOTPRINT_WIZARDS::deregister_object( void* aObject )
+{
+ int max = GetWizardsCount();
+
+ for( int i = 0; i<max; i++ )
+ {
+ FOOTPRINT_WIZARD* wizard = GetWizard( i );
+
+ if( wizard->GetObject() == aObject )
+ {
+ m_FootprintWizards.erase( m_FootprintWizards.begin() + i );
+ delete wizard;
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/pcbnew/class_footprint_wizard.h b/pcbnew/class_footprint_wizard.h
new file mode 100644
index 0000000..20fc1d4
--- /dev/null
+++ b/pcbnew/class_footprint_wizard.h
@@ -0,0 +1,190 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 NBEE Embedded Systems SL, Miguel Angel Ajo <miguelangel@ajo.es>
+ * Copyright (C) 2013 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/**
+ * @file class_footprint_wizard.h
+ * @brief Class PCBNEW_FOOTPRINT_WIZARDS
+ */
+
+#ifndef CLASS_FOOTPRINT_WIZARD_H
+#define CLASS_FOOTPRINT_WIZARD_H
+#include <vector>
+#include <wxPcbStruct.h>
+
+/**
+ * Class FOOTPRINT_WIZARD
+ * This is the parent class from where any footprint wizard class must
+ * derive */
+class FOOTPRINT_WIZARD
+{
+public:
+ FOOTPRINT_WIZARD() {}
+ virtual ~FOOTPRINT_WIZARD();
+
+ /**
+ * Function GetName
+ * @return the name of the wizard
+ */
+ virtual wxString GetName() = 0;
+
+ /**
+ * Function GetImage
+ * @return an svg image of the wizard to be rendered
+ */
+ virtual wxString GetImage() = 0;
+
+ /**
+ * Function GetDescription
+ * @return a description of the footprint wizard
+ */
+ virtual wxString GetDescription() = 0;
+
+ /**
+ * Function GetNumParameterPages
+ * @return the number of parameter pages that this wizard will show to the user
+ */
+ virtual int GetNumParameterPages() = 0;
+
+ /**
+ * Function GetParameterPageName
+ * @param aPage is the page we want the name of
+ * @return a string with the page name
+ */
+ virtual wxString GetParameterPageName( int aPage ) = 0;
+
+ /**
+ * Function GetParameterNames
+ * @param aPage is the page we want the parameter names of
+ * @return an array string with the parameter names on a certain page
+ */
+ virtual wxArrayString GetParameterNames( int aPage ) = 0;
+
+ /**
+ * Function GetParameterTypes
+ * @param aPage is the page we want the parameter types of
+ * @return an array string with the parameter types on a certain page
+ * "IU" for internal units, "UNITS" for units (0,1,2,3...,N)
+ */
+ virtual wxArrayString GetParameterTypes( int aPage ) = 0;
+
+
+ /**
+ * Function GetParameterValues
+ * @param aPage is the page we want the parameter values of
+ * @return an array of parameter values
+ */
+ virtual wxArrayString GetParameterValues( int aPage ) = 0;
+
+ /**
+ * Function GetParameterErrors
+ * @param aPage is the page we want to know the errors of
+ * @return an array of errors (if any) for the parameters, empty strings for OK parameters
+ */
+ virtual wxArrayString GetParameterErrors( int aPage ) = 0;
+
+ /**
+ * Function SetParameterValues
+ * @param aPage is the page we want to set the parameters in
+ * @param aValues are the values we want to set into the parameters
+ * @return an array of parameter values
+ */
+ virtual wxString SetParameterValues( int aPage, wxArrayString& aValues ) = 0;
+
+ /**
+ * Function GetModule
+ * This method builds the module itself and returns it to the caller function
+ * @return PCB module built from the parameters given to the class
+ * @param aMessage a wxString to store messages (if any) generated by the
+ * footprint generator
+ */
+ virtual MODULE* GetFootprint( wxString* aMessage ) = 0;
+
+ /**
+ * Function GetObject
+ * This method gets the pointer to the object from where this wizard constructs
+ * @return it's a void pointer, as it could be a PyObject or any other
+ */
+ virtual void* GetObject() = 0;
+
+ /**
+ * Function register_wizard
+ * It's the standard method of a "FOOTPRINT_WIZARD" to register itself into
+ * the FOOTPRINT_WIZARDS singleton manager
+ */
+ void register_wizard();
+};
+
+
+class FOOTPRINT_WIZARDS
+{
+private:
+ /**
+ * FOOTPRINT_WIZARD system wide static list
+ */
+ static std::vector<FOOTPRINT_WIZARD*> m_FootprintWizards;
+
+public:
+
+ /**
+ * Function register_wizard
+ * A footprint wizard calls this static method when it wants to register itself
+ * into the system wizards
+ *
+ * @param aWizard is the footprint wizard to be registered
+ */
+ static void register_wizard( FOOTPRINT_WIZARD* aWizard );
+
+ /**
+ * Function deregister_object
+ * Anyone calls this method to deregister an object which builds a wizard,
+ * it will lookup on the vector calling GetObject until find, then removed
+ * and deleted
+ *
+ * @param aObject is the footprint wizard object to be deregistered
+ */
+ static bool deregister_object( void* aObject );
+
+ /**
+ * Function GetWizard
+ * @param aName is the footprint wizard name
+ * @return a wizard object by it's name or NULL if it isn't available.
+ */
+ static FOOTPRINT_WIZARD* GetWizard( wxString aName );
+
+ /**
+ * Function GetWizard
+ * @return a wizard object by it's number or NULL if it isn't available.
+ * @param aIndex is the wizard index in list
+ */
+ static FOOTPRINT_WIZARD* GetWizard( int aIndex );
+
+ /**
+ * Function GetWizardsCount
+ * @return the number of wizards available into the system
+ */
+ static int GetWizardsCount();
+};
+
+#endif /* PCBNEW_FOOTPRINT_WIZARDS_H */
diff --git a/pcbnew/class_marker_pcb.cpp b/pcbnew/class_marker_pcb.cpp
new file mode 100644
index 0000000..dd7d4e1
--- /dev/null
+++ b/pcbnew/class_marker_pcb.cpp
@@ -0,0 +1,144 @@
+/**
+ * @file class_marker_pcb.cpp
+ * @brief Functions to handle markers used to show something (usually a drc problem)
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <wxstruct.h>
+#include <trigo.h>
+#include <msgpanel.h>
+
+#include <pcbnew.h>
+#include <class_marker_pcb.h>
+#include <layers_id_colors_and_visibility.h>
+
+
+/// Adjust the actual size of markers, when using default shape
+#define SCALING_FACTOR DMils2iu( 30 )
+
+
+MARKER_PCB::MARKER_PCB( BOARD_ITEM* aParent ) :
+ BOARD_ITEM( aParent, PCB_MARKER_T ),
+ MARKER_BASE(), m_item( NULL )
+{
+ m_Color = WHITE;
+ m_ScalingFactor = SCALING_FACTOR;
+}
+
+
+MARKER_PCB::MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos,
+ const wxString& aText, const wxPoint& aPos,
+ const wxString& bText, const wxPoint& bPos ) :
+ BOARD_ITEM( NULL, PCB_MARKER_T ), // parent set during BOARD::Add()
+ MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos, bText, bPos ), m_item( NULL )
+{
+ m_Color = WHITE;
+ m_ScalingFactor = SCALING_FACTOR;
+}
+
+MARKER_PCB::MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos,
+ const wxString& aText, const wxPoint& aPos ) :
+ BOARD_ITEM( NULL, PCB_MARKER_T ), // parent set during BOARD::Add()
+ MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos ), m_item( NULL )
+{
+ m_Color = WHITE;
+ m_ScalingFactor = SCALING_FACTOR;
+}
+
+
+/* destructor */
+MARKER_PCB::~MARKER_PCB()
+{
+}
+
+/* tests to see if this object is on the given layer.
+ * DRC markers are not really on a copper layer, but
+ * MARKER_PCB::IsOnCopperLayer return true if aLayer is a cooper layer,
+ * because this test is often used to locad a marker
+ * param aLayer The layer to test for.
+ * return bool - true if on given layer, else false.
+ */
+bool MARKER_PCB::IsOnLayer( LAYER_ID aLayer ) const
+{
+ return IsCopperLayer( aLayer );
+}
+
+void MARKER_PCB::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ const DRC_ITEM& rpt = m_drc;
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Type" ), _( "Marker" ), DARKCYAN ) );
+
+ wxString errorTxt;
+
+ errorTxt.Printf( _( "ErrType (%d)- %s:" ),
+ rpt.GetErrorCode(),
+ GetChars( rpt.GetErrorText() ) );
+
+ aList.push_back( MSG_PANEL_ITEM( errorTxt, wxEmptyString, RED ) );
+
+ wxString txtA;
+ txtA << DRC_ITEM::ShowCoord( rpt.GetPointA() ) << wxT( ": " ) << rpt.GetTextA();
+
+ wxString txtB;
+
+ if ( rpt.HasSecondItem() )
+ txtB << DRC_ITEM::ShowCoord( rpt.GetPointB() ) << wxT( ": " ) << rpt.GetTextB();
+
+ aList.push_back( MSG_PANEL_ITEM( txtA, txtB, DARKBROWN ) );
+}
+
+
+void MARKER_PCB::Rotate(const wxPoint& aRotCentre, double aAngle)
+{
+ RotatePoint( &m_Pos, aRotCentre, aAngle );
+}
+
+
+void MARKER_PCB::Flip(const wxPoint& aCentre )
+{
+ m_Pos.y = aCentre.y - (m_Pos.y - aCentre.y);
+}
+
+
+wxString MARKER_PCB::GetSelectMenuText() const
+{
+ wxString text;
+ text.Printf( _( "Marker @(%d,%d)" ), GetPos().x, GetPos().y );
+
+ return text;
+}
+
+
+void MARKER_PCB::ViewGetLayers( int aLayers[], int& aCount ) const
+{
+ aCount = 1;
+ aLayers[0] = ITEM_GAL_LAYER( DRC_VISIBLE );
+}
diff --git a/pcbnew/class_marker_pcb.h b/pcbnew/class_marker_pcb.h
new file mode 100644
index 0000000..e524ae7
--- /dev/null
+++ b/pcbnew/class_marker_pcb.h
@@ -0,0 +1,140 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009-2014 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_marker_pcb.h
+ * @brief Markers used to show a drc problem on boards.
+ */
+
+#ifndef CLASS_MARKER_PCB_H
+#define CLASS_MARKER_PCB_H
+
+
+#include <class_board_item.h>
+#include <class_marker_base.h>
+
+
+class MSG_PANEL_ITEM;
+
+
+class MARKER_PCB : public BOARD_ITEM, public MARKER_BASE
+{
+
+public:
+
+ MARKER_PCB( BOARD_ITEM* aParent );
+
+ /**
+ * Constructor
+ * @param aErrorCode The categorizing identifier for an error
+ * @param aMarkerPos The position of the MARKER_PCB on the BOARD
+ * @param aText Text describing the first of two objects
+ * @param aPos The position of the first of two objects
+ * @param bText Text describing the second of the two conflicting objects
+ * @param bPos The position of the second of two objects
+ */
+ MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos,
+ const wxString& aText, const wxPoint& aPos,
+ const wxString& bText, const wxPoint& bPos );
+
+ /**
+ * Constructor
+ * @param aErrorCode The categorizing identifier for an error
+ * @param aMarkerPos The position of the MARKER_PCB on the BOARD
+ * @param aText Text describing the object
+ * @param aPos The position of the object
+ */
+ MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos,
+ const wxString& aText, const wxPoint& aPos );
+
+ ~MARKER_PCB();
+
+ void Move(const wxPoint& aMoveVector)
+ {
+ m_Pos += aMoveVector;
+ }
+
+ void Rotate( const wxPoint& aRotCentre, double aAngle );
+
+ void Flip( const wxPoint& aCentre );
+
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset )
+ {
+ DrawMarker( aPanel, aDC, aDrawMode, aOffset );
+ }
+
+ const wxPoint& GetPosition() const { return m_Pos; }
+ void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; }
+
+ void SetItem( const BOARD_ITEM* aItem )
+ {
+ m_item = aItem;
+ }
+
+ const BOARD_ITEM* GetItem() const
+ {
+ return m_item;
+ }
+
+ bool HitTest( const wxPoint& aPosition ) const
+ {
+ return HitTestMarker( aPosition );
+ }
+
+ bool IsOnLayer( LAYER_ID aLayer ) const;
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return drc_xpm; }
+
+ ///> @copydoc VIEW_ITEM::ViewBBox()
+ virtual const BOX2I ViewBBox() const
+ {
+ return GetParent()->ViewBBox();
+ }
+
+ ///> @copydoc VIEW_ITEM::ViewGetLayers()
+ virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+
+ /** Get class name
+ * @return string "MARKER_PCB"
+ */
+ virtual wxString GetClass() const
+ {
+ return wxT( "MARKER_PCB" );
+ }
+
+protected:
+ ///> Pointer to BOARD_ITEM that causes DRC error.
+ const BOARD_ITEM* m_item;
+};
+
+#endif // CLASS_MARKER_PCB_H
diff --git a/pcbnew/class_mire.cpp b/pcbnew/class_mire.cpp
new file mode 100644
index 0000000..63c2dc1
--- /dev/null
+++ b/pcbnew/class_mire.cpp
@@ -0,0 +1,211 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_mire.cpp
+ * MIRE class definition (targets for photo plots)
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <kicad_string.h>
+#include <colors_selection.h>
+#include <trigo.h>
+#include <macros.h>
+#include <richio.h>
+
+#include <class_board.h>
+#include <class_mire.h>
+#include <base_units.h>
+
+
+PCB_TARGET::PCB_TARGET( BOARD_ITEM* aParent ) :
+ BOARD_ITEM( aParent, PCB_TARGET_T )
+{
+ m_Shape = 0;
+ m_Size = Millimeter2iu( 5 ); // Gives a decent size
+ m_Width = Millimeter2iu( 0.15 ); // Gives a decent width
+ m_Layer = Edge_Cuts; // a target is on all layers
+}
+
+PCB_TARGET::PCB_TARGET( BOARD_ITEM* aParent, int aShape, LAYER_ID aLayer,
+ const wxPoint& aPos, int aSize, int aWidth ) :
+ BOARD_ITEM( aParent, PCB_TARGET_T )
+{
+ m_Shape = aShape;
+ m_Layer = aLayer;
+ m_Pos = aPos;
+ m_Size = aSize;
+ m_Width = aWidth;
+}
+
+
+PCB_TARGET::~PCB_TARGET()
+{
+}
+
+void PCB_TARGET::Copy( PCB_TARGET* source )
+{
+ m_Layer = source->m_Layer;
+ m_Width = source->m_Width;
+ m_Pos = source->m_Pos;
+ m_Shape = source->m_Shape;
+ m_Size = source->m_Size;
+ SetTimeStamp( GetNewTimeStamp() );
+}
+
+
+/* Draw PCB_TARGET object: 2 segments + 1 circle
+ * The circle radius is half the radius of the target
+ * 2 lines have length the diameter of the target
+ */
+void PCB_TARGET::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE mode_color,
+ const wxPoint& offset )
+{
+ int radius, ox, oy, width;
+ int dx1, dx2, dy1, dy2;
+
+ ox = m_Pos.x + offset.x;
+ oy = m_Pos.y + offset.y;
+
+ BOARD * brd = GetBoard( );
+
+ if( brd->IsLayerVisible( m_Layer ) == false )
+ return;
+
+ EDA_COLOR_T gcolor = brd->GetLayerColor( m_Layer );
+
+ GRSetDrawMode( DC, mode_color );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
+ bool filled = displ_opts ? displ_opts->m_DisplayDrawItemsFill : FILLED;
+ width = m_Width;
+
+ radius = m_Size / 3;
+
+ if( GetShape() ) // shape X
+ radius = m_Size / 2;
+
+ if( filled )
+ GRCircle( panel->GetClipBox(), DC, ox, oy, radius, width, gcolor );
+ else
+ {
+ GRCircle( panel->GetClipBox(), DC, ox, oy, radius + (width / 2), gcolor );
+ GRCircle( panel->GetClipBox(), DC, ox, oy, radius - (width / 2), gcolor );
+ }
+
+
+ radius = m_Size / 2;
+ dx1 = radius;
+ dy1 = 0;
+ dx2 = 0;
+ dy2 = radius;
+
+ if( GetShape() ) // shape X
+ {
+ dx1 = dy1 = radius;
+ dx2 = dx1;
+ dy2 = -dy1;
+ }
+
+ if( filled )
+ {
+ GRLine( panel->GetClipBox(), DC, ox - dx1, oy - dy1, ox + dx1, oy + dy1, width, gcolor );
+ GRLine( panel->GetClipBox(), DC, ox - dx2, oy - dy2, ox + dx2, oy + dy2, width, gcolor );
+ }
+ else
+ {
+ GRCSegm( panel->GetClipBox(), DC, ox - dx1, oy - dy1, ox + dx1, oy + dy1, width, gcolor );
+ GRCSegm( panel->GetClipBox(), DC, ox - dx2, oy - dy2, ox + dx2, oy + dy2, width, gcolor );
+ }
+}
+
+
+bool PCB_TARGET::HitTest( const wxPoint& aPosition ) const
+{
+ int dX = aPosition.x - m_Pos.x;
+ int dY = aPosition.y - m_Pos.y;
+ int radius = m_Size / 2;
+ return abs( dX ) <= radius && abs( dY ) <= radius;
+}
+
+
+bool PCB_TARGET::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ EDA_RECT arect = aRect;
+ arect.Inflate( aAccuracy );
+
+ if( aContained )
+ return arect.Contains( GetBoundingBox() );
+ else
+ return GetBoundingBox().Intersects( arect );
+}
+
+
+void PCB_TARGET::Rotate(const wxPoint& aRotCentre, double aAngle)
+{
+ RotatePoint( &m_Pos, aRotCentre, aAngle );
+}
+
+
+void PCB_TARGET::Flip(const wxPoint& aCentre )
+{
+ m_Pos.y = aCentre.y - ( m_Pos.y - aCentre.y );
+ SetLayer( FlipLayer( GetLayer() ) );
+}
+
+
+const EDA_RECT PCB_TARGET::GetBoundingBox() const
+{
+ EDA_RECT bBox;
+ bBox.SetX( m_Pos.x - m_Size/2 );
+ bBox.SetY( m_Pos.y - m_Size/2 );
+ bBox.SetWidth( m_Size );
+ bBox.SetHeight( m_Size );
+
+ return bBox;
+}
+
+
+wxString PCB_TARGET::GetSelectMenuText() const
+{
+ wxString text;
+ wxString msg;
+
+ msg = ::CoordinateToString( m_Size );
+
+ // Targets are on *every* layer by definition
+ text.Printf( _( "Target size %s" ), GetChars( msg ) );
+
+ return text;
+}
+
+
+EDA_ITEM* PCB_TARGET::Clone() const
+{
+ return new PCB_TARGET( *this );
+}
diff --git a/pcbnew/class_mire.h b/pcbnew/class_mire.h
new file mode 100644
index 0000000..03bebba
--- /dev/null
+++ b/pcbnew/class_mire.h
@@ -0,0 +1,112 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_mire.h
+ * @brief PCB_TARGET class definition. (targets for photo plots).
+ */
+
+#ifndef MIRE_H
+#define MIRE_H
+
+
+#include <class_board_item.h>
+
+
+class EDA_RECT;
+class LINE_READER;
+class EDA_DRAW_PANEL;
+
+
+class PCB_TARGET : public BOARD_ITEM
+{
+ int m_Shape; // bit 0 : 0 = draw +, 1 = draw X
+ int m_Size;
+ int m_Width;
+ wxPoint m_Pos;
+
+public:
+ PCB_TARGET( BOARD_ITEM* aParent );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ PCB_TARGET( BOARD_ITEM* aParent, int aShape, LAYER_ID aLayer,
+ const wxPoint& aPos, int aSize, int aWidth );
+
+ ~PCB_TARGET();
+
+ void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; } // override
+ const wxPoint& GetPosition() const { return m_Pos; } // override
+
+ void SetShape( int aShape ) { m_Shape = aShape; }
+ int GetShape() const { return m_Shape; }
+
+ void SetSize( int aSize ) { m_Size = aSize; }
+ int GetSize() const { return m_Size; }
+
+ void SetWidth( int aWidth ) { m_Width = aWidth; }
+ int GetWidth() const { return m_Width; }
+
+ void Move( const wxPoint& aMoveVector )
+ {
+ m_Pos += aMoveVector;
+ }
+
+ void Rotate( const wxPoint& aRotCentre, double aAngle );
+
+ void Flip( const wxPoint& aCentre );
+
+ void Copy( PCB_TARGET* source );
+
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
+ GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset );
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ wxString GetClass() const
+ {
+ return wxT( "PCB_TARGET" );
+ }
+
+ /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
+ * bool aContained = true, int aAccuracy ) const
+ */
+ bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const;
+
+ // Virtual function
+ const EDA_RECT GetBoundingBox() const;
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_mires_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+};
+
+
+#endif // #define MIRE_H
diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp
new file mode 100644
index 0000000..c1bc66b
--- /dev/null
+++ b/pcbnew/class_module.cpp
@@ -0,0 +1,1307 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_module.cpp
+ * @brief MODULE class implementation.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <wxstruct.h>
+#include <plot_common.h>
+#include <class_drawpanel.h>
+#include <trigo.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <pcbnew.h>
+#include <colors_selection.h>
+#include <richio.h>
+#include <filter_reader.h>
+#include <macros.h>
+#include <3d_struct.h>
+#include <msgpanel.h>
+
+#include <class_board.h>
+#include <class_edge_mod.h>
+#include <class_module.h>
+
+
+MODULE::MODULE( BOARD* parent ) :
+ BOARD_ITEM( (BOARD_ITEM*) parent, PCB_MODULE_T ),
+ m_initial_comments( 0 )
+{
+ m_Attributs = MOD_DEFAULT;
+ m_Layer = F_Cu;
+ m_Orient = 0;
+ m_ModuleStatus = MODULE_PADS_LOCKED;
+ m_arflag = 0;
+ m_CntRot90 = m_CntRot180 = 0;
+ m_Surface = 0.0;
+ m_Link = 0;
+ m_LastEditTime = 0;
+ m_LocalClearance = 0;
+ m_LocalSolderMaskMargin = 0;
+ m_LocalSolderPasteMargin = 0;
+ m_LocalSolderPasteMarginRatio = 0.0;
+ m_ZoneConnection = PAD_ZONE_CONN_INHERITED; // Use zone setting by default
+ m_ThermalWidth = 0; // Use zone setting by default
+ m_ThermalGap = 0; // Use zone setting by default
+
+ // These are special and mandatory text fields
+ m_Reference = new TEXTE_MODULE( this, TEXTE_MODULE::TEXT_is_REFERENCE );
+ m_Value = new TEXTE_MODULE( this, TEXTE_MODULE::TEXT_is_VALUE );
+
+ // Reserve one void 3D entry, to avoid problems with void list
+ m_3D_Drawings.PushBack( new S3D_MASTER( this ) );
+}
+
+
+MODULE::MODULE( const MODULE& aModule ) :
+ BOARD_ITEM( aModule )
+{
+ m_Pos = aModule.m_Pos;
+ m_fpid = aModule.m_fpid;
+ m_Layer = aModule.m_Layer;
+ m_Attributs = aModule.m_Attributs;
+ m_ModuleStatus = aModule.m_ModuleStatus;
+ m_Orient = aModule.m_Orient;
+ m_BoundaryBox = aModule.m_BoundaryBox;
+ m_CntRot90 = aModule.m_CntRot90;
+ m_CntRot180 = aModule.m_CntRot180;
+ m_LastEditTime = aModule.m_LastEditTime;
+ m_Link = aModule.m_Link;
+ m_Path = aModule.m_Path; //is this correct behavior?
+
+ m_LocalClearance = aModule.m_LocalClearance;
+ m_LocalSolderMaskMargin = aModule.m_LocalSolderMaskMargin;
+ m_LocalSolderPasteMargin = aModule.m_LocalSolderPasteMargin;
+ m_LocalSolderPasteMarginRatio = aModule.m_LocalSolderPasteMarginRatio;
+ m_ZoneConnection = aModule.m_ZoneConnection;
+ m_ThermalWidth = aModule.m_ThermalWidth;
+ m_ThermalGap = aModule.m_ThermalGap;
+
+ // Copy reference and value.
+ m_Reference = new TEXTE_MODULE( *aModule.m_Reference );
+ m_Reference->SetParent( this );
+
+ m_Value = new TEXTE_MODULE( *aModule.m_Value );
+ m_Value->SetParent( this );
+
+ // Copy auxiliary data: Pads
+ for( D_PAD* pad = aModule.m_Pads; pad; pad = pad->Next() )
+ {
+ D_PAD* newpad = new D_PAD( *pad );
+ newpad->SetParent( this );
+ m_Pads.PushBack( newpad );
+ }
+
+ // Copy auxiliary data: Drawings
+ for( BOARD_ITEM* item = aModule.m_Drawings; item; item = item->Next() )
+ {
+ BOARD_ITEM* newItem;
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ case PCB_MODULE_EDGE_T:
+ newItem = static_cast<BOARD_ITEM*>( item->Clone() );
+ newItem->SetParent( this );
+ m_Drawings.PushBack( newItem );
+ break;
+
+ default:
+ wxLogMessage( wxT( "MODULE::Copy() Internal Err: unknown type" ) );
+ break;
+ }
+ }
+
+ // Copy auxiliary data: 3D_Drawings info
+ for( S3D_MASTER* item = aModule.m_3D_Drawings; item; item = item->Next() )
+ {
+ if( item->GetShape3DName().IsEmpty() ) // do not copy empty shapes.
+ continue;
+
+ S3D_MASTER* t3d = new S3D_MASTER( this );
+ t3d->Copy( item );
+ m_3D_Drawings.PushBack( t3d );
+ }
+
+ // Ensure there is at least one item in m_3D_Drawings.
+ if( m_3D_Drawings.GetCount() == 0 )
+ m_3D_Drawings.PushBack( new S3D_MASTER( this ) ); // push a void item
+
+ m_Doc = aModule.m_Doc;
+ m_KeyWord = aModule.m_KeyWord;
+
+ m_arflag = 0;
+
+ // Ensure auxiliary data is up to date
+ CalculateBoundingBox();
+
+ m_initial_comments = aModule.m_initial_comments ?
+ new wxArrayString( *aModule.m_initial_comments ) : 0;
+}
+
+
+MODULE::~MODULE()
+{
+ delete m_Reference;
+ delete m_Value;
+ delete m_initial_comments;
+}
+
+ /**
+ * Function ClearAllNets
+ * Clear (i.e. force the ORPHANED dummy net info) the net info which
+ * depends on a given board for all pads of the footprint.
+ * This is needed when a footprint is copied between the fp editor and
+ * the board editor for instance, because net info become fully broken
+ */
+void MODULE::ClearAllNets()
+{
+ // Force the ORPHANED dummy net info for all pads.
+ // ORPHANED dummy net does not depend on a board
+ for( D_PAD* pad = Pads(); pad; pad = pad->Next() )
+ pad->SetNetCode( NETINFO_LIST::FORCE_ORPHANED );
+}
+
+
+/* Draw the anchor cross (vertical)
+ * Must be done after the pads, because drawing the hole will erase overwrite
+ * every thing already drawn.
+ */
+void MODULE::DrawAncre( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
+ int dim_ancre, GR_DRAWMODE draw_mode )
+{
+ GRSetDrawMode( DC, draw_mode );
+
+ if( GetBoard()->IsElementVisible( ANCHOR_VISIBLE ) )
+ {
+ GRDrawAnchor( panel->GetClipBox(), DC, m_Pos.x, m_Pos.y,
+ dim_ancre,
+ g_ColorsSettings.GetItemColor( ANCHOR_VISIBLE ) );
+ }
+}
+
+
+void MODULE::Copy( MODULE* aModule )
+{
+ m_Pos = aModule->m_Pos;
+ m_Layer = aModule->m_Layer;
+ m_fpid = aModule->m_fpid;
+ m_Attributs = aModule->m_Attributs;
+ m_ModuleStatus = aModule->m_ModuleStatus;
+ m_Orient = aModule->m_Orient;
+ m_BoundaryBox = aModule->m_BoundaryBox;
+ m_CntRot90 = aModule->m_CntRot90;
+ m_CntRot180 = aModule->m_CntRot180;
+ m_LastEditTime = aModule->m_LastEditTime;
+ m_Link = aModule->m_Link;
+ m_Path = aModule->m_Path; //is this correct behavior?
+ SetTimeStamp( GetNewTimeStamp() );
+
+ m_LocalClearance = aModule->m_LocalClearance;
+ m_LocalSolderMaskMargin = aModule->m_LocalSolderMaskMargin;
+ m_LocalSolderPasteMargin = aModule->m_LocalSolderPasteMargin;
+ m_LocalSolderPasteMarginRatio = aModule->m_LocalSolderPasteMarginRatio;
+ m_ZoneConnection = aModule->m_ZoneConnection;
+ m_ThermalWidth = aModule->m_ThermalWidth;
+ m_ThermalGap = aModule->m_ThermalGap;
+
+ // Copy reference and value.
+ m_Reference->Copy( aModule->m_Reference );
+ m_Value->Copy( aModule->m_Value );
+
+ // Copy auxiliary data: Pads
+ m_Pads.DeleteAll();
+
+ for( D_PAD* pad = aModule->m_Pads; pad; pad = pad->Next() )
+ {
+ D_PAD* newpad = new D_PAD( this );
+ newpad->Copy( pad );
+ m_Pads.PushBack( newpad );
+ }
+
+ // Copy auxiliary data: Drawings
+ m_Drawings.DeleteAll();
+
+ for( BOARD_ITEM* item = aModule->m_Drawings; item; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ {
+ TEXTE_MODULE* textm = new TEXTE_MODULE( this );
+ textm->Copy( static_cast<TEXTE_MODULE*>( item ) );
+ m_Drawings.PushBack( textm );
+ break;
+ }
+
+ case PCB_MODULE_EDGE_T:
+ {
+ EDGE_MODULE * edge;
+ edge = new EDGE_MODULE( this );
+ edge->Copy( (EDGE_MODULE*) item );
+ m_Drawings.PushBack( edge );
+ break;
+ }
+
+ default:
+ wxLogMessage( wxT( "MODULE::Copy() Internal Err: unknown type" ) );
+ break;
+ }
+ }
+
+ // Copy auxiliary data: 3D_Drawings info
+ m_3D_Drawings.DeleteAll();
+
+ // Ensure there is one (or more) item in m_3D_Drawings
+ m_3D_Drawings.PushBack( new S3D_MASTER( this ) ); // push a void item
+
+ for( S3D_MASTER* item = aModule->m_3D_Drawings; item; item = item->Next() )
+ {
+ if( item->GetShape3DName().IsEmpty() ) // do not copy empty shapes.
+ continue;
+
+ S3D_MASTER* t3d = m_3D_Drawings;
+
+ if( t3d && t3d->GetShape3DName().IsEmpty() ) // The first entry can
+ { // exist, but is empty : use it.
+ t3d->Copy( item );
+ }
+ else
+ {
+ t3d = new S3D_MASTER( this );
+ t3d->Copy( item );
+ m_3D_Drawings.PushBack( t3d );
+ }
+ }
+
+ m_Doc = aModule->m_Doc;
+ m_KeyWord = aModule->m_KeyWord;
+
+ // Ensure auxiliary data is up to date
+ CalculateBoundingBox();
+}
+
+
+void MODULE::Add( BOARD_ITEM* aBoardItem, bool doAppend )
+{
+ switch( aBoardItem->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ // Only user texts can be added this way. Reference and value are not hold in the DLIST.
+ assert( static_cast<TEXTE_MODULE*>( aBoardItem )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS );
+
+ // no break
+
+ case PCB_MODULE_EDGE_T:
+ if( doAppend )
+ m_Drawings.PushBack( aBoardItem );
+ else
+ m_Drawings.PushFront( aBoardItem );
+ break;
+
+ case PCB_PAD_T:
+ if( doAppend )
+ m_Pads.PushBack( static_cast<D_PAD*>( aBoardItem ) );
+ else
+ m_Pads.PushFront( static_cast<D_PAD*>( aBoardItem ) );
+ break;
+
+ default:
+ {
+ wxString msg;
+ msg.Printf( wxT( "MODULE::Add() needs work: BOARD_ITEM type (%d) not handled" ),
+ aBoardItem->Type() );
+ wxFAIL_MSG( msg );
+
+ return;
+ }
+ }
+
+ aBoardItem->SetParent( this );
+}
+
+
+BOARD_ITEM* MODULE::Remove( BOARD_ITEM* aBoardItem )
+{
+ switch( aBoardItem->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ // Only user texts can be removed this way. Reference and value are not hold in the DLIST.
+ assert( static_cast<TEXTE_MODULE*>( aBoardItem )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS );
+
+ // no break
+
+ case PCB_MODULE_EDGE_T:
+ return m_Drawings.Remove( aBoardItem );
+
+ case PCB_PAD_T:
+ return m_Pads.Remove( static_cast<D_PAD*>( aBoardItem ) );
+
+ default:
+ {
+ wxString msg;
+ msg.Printf( wxT( "MODULE::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
+ aBoardItem->Type() );
+ wxFAIL_MSG( msg );
+ }
+ }
+
+ return NULL;
+}
+
+
+void MODULE::CopyNetlistSettings( MODULE* aModule, bool aCopyLocalSettings )
+{
+ // Don't do anything foolish like trying to copy to yourself.
+ wxCHECK_RET( aModule != NULL && aModule != this, wxT( "Cannot copy to NULL or yourself." ) );
+
+ // Not sure what to do with the value field. Use netlist for now.
+ aModule->SetPosition( GetPosition() );
+
+ if( aModule->GetLayer() != GetLayer() )
+ aModule->Flip( aModule->GetPosition() );
+
+ if( aModule->GetOrientation() != GetOrientation() )
+ aModule->Rotate( aModule->GetPosition(), GetOrientation() );
+
+ aModule->SetLocked( IsLocked() );
+
+ if( aCopyLocalSettings )
+ {
+ aModule->SetLocalSolderMaskMargin( GetLocalSolderMaskMargin() );
+ aModule->SetLocalClearance( GetLocalClearance() );
+ aModule->SetLocalSolderPasteMargin( GetLocalSolderPasteMargin() );
+ aModule->SetLocalSolderPasteMarginRatio( GetLocalSolderPasteMarginRatio() );
+ aModule->SetZoneConnection( GetZoneConnection() );
+ aModule->SetThermalWidth( GetThermalWidth() );
+ aModule->SetThermalGap( GetThermalGap() );
+ }
+
+ for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
+ {
+ // Fix me: if aCopyLocalSettings == true, for "multiple" pads
+ // (set of pads having the same name/number) this is broken
+ // because we copy settings from the first pad found.
+ // When old and new footprints have very few differences, a better
+ // algo can be used.
+ D_PAD* oldPad = FindPadByName( pad->GetPadName() );
+
+ if( oldPad )
+ oldPad->CopyNetlistSettings( pad, aCopyLocalSettings );
+ }
+
+ // Not sure about copying description, keywords, 3D models or any other
+ // local user changes to footprint. Stick with the new footprint settings
+ // called out in the footprint loaded in the netlist.
+ aModule->CalculateBoundingBox();
+}
+
+
+void MODULE::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
+ const wxPoint& aOffset )
+{
+ if( (m_Flags & DO_NOT_DRAW) || (IsMoving()) )
+ return;
+
+ for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
+ {
+ if( pad->IsMoving() )
+ continue;
+
+ pad->Draw( aPanel, aDC, aDrawMode, aOffset );
+ }
+
+ BOARD* brd = GetBoard();
+
+ // Draws footprint anchor
+ DrawAncre( aPanel, aDC, aOffset, DIM_ANCRE_MODULE, aDrawMode );
+
+ // Draw graphic items
+ if( brd->IsElementVisible( MOD_REFERENCES_VISIBLE ) )
+ {
+ if( !(m_Reference->IsMoving()) )
+ m_Reference->Draw( aPanel, aDC, aDrawMode, aOffset );
+ }
+
+ if( brd->IsElementVisible( MOD_VALUES_VISIBLE ) )
+ {
+ if( !(m_Value->IsMoving()) )
+ m_Value->Draw( aPanel, aDC, aDrawMode, aOffset );
+ }
+
+ for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
+ {
+ if( item->IsMoving() )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ case PCB_MODULE_EDGE_T:
+ item->Draw( aPanel, aDC, aDrawMode, aOffset );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Enable these line to draw m_BoundaryBox (debug tests purposes only)
+#if 0
+ GRRect( aPanel->GetClipBox(), aDC, m_BoundaryBox, 0, BROWN );
+#endif
+
+}
+
+
+void MODULE::DrawEdgesOnly( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
+ GR_DRAWMODE draw_mode )
+{
+ for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case PCB_MODULE_EDGE_T:
+ item->Draw( panel, DC, draw_mode, offset );
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+void MODULE::CalculateBoundingBox()
+{
+ m_BoundaryBox = GetFootprintRect();
+ m_Surface = std::abs( (double) m_BoundaryBox.GetWidth() * m_BoundaryBox.GetHeight() );
+}
+
+
+EDA_RECT MODULE::GetFootprintRect() const
+{
+ EDA_RECT area;
+
+ area.SetOrigin( m_Pos );
+ area.SetEnd( m_Pos );
+ area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area
+
+ for( const BOARD_ITEM* item = m_Drawings.GetFirst(); item; item = item->Next() )
+ {
+ const EDGE_MODULE* edge = dyn_cast<const EDGE_MODULE*>( item );
+
+ if( edge )
+ area.Merge( edge->GetBoundingBox() );
+ }
+
+ for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
+ area.Merge( pad->GetBoundingBox() );
+
+ return area;
+}
+
+
+const EDA_RECT MODULE::GetBoundingBox() const
+{
+ EDA_RECT area = GetFootprintRect();
+
+ // Calculate extended area including text fields
+ area.Merge( m_Reference->GetBoundingBox() );
+ area.Merge( m_Value->GetBoundingBox() );
+
+ // Add the Clearance shape size: (shape around the pads when the
+ // clearance is shown. Not optimized, but the draw cost is small
+ // (perhaps smaller than optimization).
+ BOARD* board = GetBoard();
+ if( board )
+ {
+ int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue();
+ area.Inflate( biggest_clearance );
+ }
+
+ return area;
+}
+
+
+/* Virtual function, from EDA_ITEM.
+ * display module info on MsgPanel
+ */
+void MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ int nbpad;
+ wxString msg;
+
+ aList.push_back( MSG_PANEL_ITEM( m_Reference->GetShownText(), m_Value->GetShownText(), DARKCYAN ) );
+
+ // Display last date the component was edited (useful in Module Editor).
+ wxDateTime date( m_LastEditTime );
+
+ if( m_LastEditTime && date.IsValid() )
+ // Date format: see http://www.cplusplus.com/reference/ctime/strftime
+ msg = date.Format( wxT( "%b %d, %Y" ) ); // Abbreviated_month_name Day, Year
+ else
+ msg = _( "Unknown" );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Last Change" ), msg, BROWN ) );
+
+ // display schematic path
+ aList.push_back( MSG_PANEL_ITEM( _( "Netlist Path" ), m_Path, BROWN ) );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), GetLayerName(), RED ) );
+
+ EDA_ITEM* PtStruct = m_Pads;
+ nbpad = 0;
+
+ while( PtStruct )
+ {
+ nbpad++;
+ PtStruct = PtStruct->Next();
+ }
+
+ msg.Printf( wxT( "%d" ), nbpad );
+ aList.push_back( MSG_PANEL_ITEM( _( "Pads" ), msg, BLUE ) );
+
+ msg = wxT( ".." );
+
+ if( IsLocked() )
+ msg[0] = 'L';
+
+ if( m_ModuleStatus & MODULE_is_PLACED )
+ msg[1] = 'P';
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Status" ), msg, MAGENTA ) );
+
+ msg.Printf( wxT( "%.1f" ), m_Orient / 10.0 );
+ aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), msg, BROWN ) );
+
+ // Controls on right side of the dialog
+ switch( m_Attributs & 255 )
+ {
+ case 0:
+ msg = _( "Normal" );
+ break;
+
+ case MOD_CMS:
+ msg = _( "Insert" );
+ break;
+
+ case MOD_VIRTUAL:
+ msg = _( "Virtual" );
+ break;
+
+ default:
+ msg = wxT( "???" );
+ break;
+ }
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Attributes" ), msg, BROWN ) );
+ aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), FROM_UTF8( m_fpid.Format().c_str() ), BLUE ) );
+
+ msg = _( "No 3D shape" );
+ // Search the first active 3D shape in list
+ for( S3D_MASTER* struct3D = m_3D_Drawings; struct3D; struct3D = struct3D->Next() )
+ {
+ if( !struct3D->GetShape3DName().IsEmpty() )
+ {
+ msg = struct3D->GetShape3DName();
+ break;
+ }
+ }
+
+ aList.push_back( MSG_PANEL_ITEM( _( "3D-Shape" ), msg, RED ) );
+
+ wxString doc, keyword;
+ doc.Printf( _( "Doc: %s" ), GetChars( m_Doc ) );
+ keyword.Printf( _( "Key Words: %s" ), GetChars( m_KeyWord ) );
+ aList.push_back( MSG_PANEL_ITEM( doc, keyword, BLACK ) );
+}
+
+
+bool MODULE::HitTest( const wxPoint& aPosition ) const
+{
+ return m_BoundaryBox.Contains( aPosition );
+}
+
+
+bool MODULE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ EDA_RECT arect = aRect;
+ arect.Inflate( aAccuracy );
+
+ if( aContained )
+ return arect.Contains( m_BoundaryBox );
+ else
+ return m_BoundaryBox.Intersects( arect );
+}
+
+
+D_PAD* MODULE::FindPadByName( const wxString& aPadName ) const
+{
+ wxString buf;
+
+ for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
+ {
+ pad->StringPadName( buf );
+#if 1
+ if( buf.CmpNoCase( aPadName ) == 0 ) // why case insensitive?
+#else
+ if( buf == aPadName )
+#endif
+ return pad;
+ }
+
+ return NULL;
+}
+
+
+D_PAD* MODULE::GetPad( const wxPoint& aPosition, LSET aLayerMask )
+{
+ for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
+ {
+ // ... and on the correct layer.
+ if( !( pad->GetLayerSet() & aLayerMask ).any() )
+ continue;
+
+ if( pad->HitTest( aPosition ) )
+ return pad;
+ }
+
+ return NULL;
+}
+
+
+unsigned MODULE::GetPadCount( INCLUDE_NPTH_T aIncludeNPTH ) const
+{
+ if( aIncludeNPTH )
+ return m_Pads.GetCount();
+
+ unsigned cnt = 0;
+
+ for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
+ {
+ if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
+ continue;
+
+ cnt++;
+ }
+
+ return cnt;
+}
+
+
+unsigned MODULE::GetUniquePadCount( INCLUDE_NPTH_T aIncludeNPTH ) const
+{
+ std::set<wxUint32> usedNames;
+
+ // Create a set of used pad numbers
+ for( D_PAD* pad = Pads(); pad; pad = pad->Next() )
+ {
+ // Skip pads not on copper layers (used to build complex
+ // solder paste shapes for instance)
+ if( ( pad->GetLayerSet() & LSET::AllCuMask() ).none() )
+ continue;
+
+ // Skip pads with no name, because they are usually "mechanical"
+ // pads, not "electrical" pads
+ if( pad->GetPadName().IsEmpty() )
+ continue;
+
+ if( !aIncludeNPTH )
+ {
+ // skip NPTH
+ if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
+ {
+ continue;
+ }
+ }
+
+ usedNames.insert( pad->GetPackedPadName() );
+ }
+
+ return usedNames.size();
+}
+
+
+void MODULE::Add3DModel( S3D_MASTER* a3DModel )
+{
+ a3DModel->SetParent( this );
+ m_3D_Drawings.PushBack( a3DModel );
+}
+
+
+// see class_module.h
+SEARCH_RESULT MODULE::Visit( INSPECTOR* inspector, const void* testData,
+ const KICAD_T scanTypes[] )
+{
+ KICAD_T stype;
+ SEARCH_RESULT result = SEARCH_CONTINUE;
+ const KICAD_T* p = scanTypes;
+ bool done = false;
+
+#if 0 && defined(DEBUG)
+ std::cout << GetClass().mb_str() << ' ';
+#endif
+
+ while( !done )
+ {
+ stype = *p;
+
+ switch( stype )
+ {
+ case PCB_MODULE_T:
+ result = inspector->Inspect( this, testData ); // inspect me
+ ++p;
+ break;
+
+ case PCB_PAD_T:
+ result = IterateForward( m_Pads, inspector, testData, p );
+ ++p;
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ result = inspector->Inspect( m_Reference, testData );
+
+ if( result == SEARCH_QUIT )
+ break;
+
+ result = inspector->Inspect( m_Value, testData );
+
+ if( result == SEARCH_QUIT )
+ break;
+
+ // m_Drawings can hold TYPETEXTMODULE also, so fall thru
+
+ case PCB_MODULE_EDGE_T:
+ result = IterateForward( m_Drawings, inspector, testData, p );
+
+ // skip over any types handled in the above call.
+ for( ; ; )
+ {
+ switch( stype = *++p )
+ {
+ case PCB_MODULE_TEXT_T:
+ case PCB_MODULE_EDGE_T:
+ continue;
+
+ default:
+ ;
+ }
+
+ break;
+ }
+
+ break;
+
+ default:
+ done = true;
+ break;
+ }
+
+ if( result == SEARCH_QUIT )
+ break;
+ }
+
+ return result;
+}
+
+
+wxString MODULE::GetSelectMenuText() const
+{
+ wxString text;
+ text.Printf( _( "Footprint %s on %s" ),
+ GetChars ( GetReference() ),
+ GetChars ( GetLayerName() ) );
+
+ return text;
+}
+
+
+EDA_ITEM* MODULE::Clone() const
+{
+ return new MODULE( *this );
+}
+
+
+void MODULE::RunOnChildren( boost::function<void (BOARD_ITEM*)> aFunction )
+{
+ try
+ {
+ for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
+ aFunction( static_cast<BOARD_ITEM*>( pad ) );
+
+ for( BOARD_ITEM* drawing = m_Drawings; drawing; drawing = drawing->Next() )
+ aFunction( drawing );
+
+ aFunction( static_cast<BOARD_ITEM*>( m_Reference ) );
+ aFunction( static_cast<BOARD_ITEM*>( m_Value ) );
+ }
+ catch( boost::bad_function_call& e )
+ {
+ DisplayError( NULL, wxT( "Error running MODULE::RunOnChildren" ) );
+ }
+}
+
+
+void MODULE::ViewUpdate( int aUpdateFlags )
+{
+ if( !m_view )
+ return;
+
+ // Update the module itself
+ VIEW_ITEM::ViewUpdate( aUpdateFlags );
+
+ // Update pads
+ for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() )
+ pad->ViewUpdate( aUpdateFlags );
+
+ // Update module's drawing (mostly silkscreen)
+ for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() )
+ drawing->ViewUpdate( aUpdateFlags );
+
+ // Update module's texts
+ m_Reference->ViewUpdate( aUpdateFlags );
+ m_Value->ViewUpdate( aUpdateFlags );
+}
+
+
+void MODULE::ViewGetLayers( int aLayers[], int& aCount ) const
+{
+ aCount = 2;
+ aLayers[0] = ITEM_GAL_LAYER( ANCHOR_VISIBLE );
+
+ switch( m_Layer )
+ {
+
+ default:
+ wxASSERT_MSG( false, "Illegal layer" ); // do you really have modules placed on other layers?
+ // pass through
+ case F_Cu:
+ aLayers[1] = ITEM_GAL_LAYER( MOD_FR_VISIBLE );
+ break;
+
+ case B_Cu:
+ aLayers[1] = ITEM_GAL_LAYER( MOD_BK_VISIBLE );
+ break;
+ }
+}
+
+
+unsigned int MODULE::ViewGetLOD( int aLayer ) const
+{
+ // Currently there is only one layer, so there is nothing to check
+// if( aLayer == ITEM_GAL_LAYER( ANCHOR_VISIBLE ) )
+ return 30;
+}
+
+
+const BOX2I MODULE::ViewBBox() const
+{
+ EDA_RECT fpRect = GetFootprintRect();
+
+ return BOX2I( VECTOR2I( fpRect.GetOrigin() ), VECTOR2I( fpRect.GetSize() ) );
+}
+
+
+/* Test for validity of the name in a library of the footprint
+ * ( no spaces, dir separators ... )
+ * return true if the given name is valid
+ * static function
+ */
+bool MODULE::IsLibNameValid( const wxString & aName )
+{
+ const wxChar * invalids = StringLibNameInvalidChars( false );
+
+ if( aName.find_first_of( invalids ) != std::string::npos )
+ return false;
+
+ return true;
+}
+
+
+/* Test for validity of the name of a footprint to be used in a footprint library
+ * ( no spaces, dir separators ... )
+ * param bool aUserReadable = false to get the list of invalid chars
+ * true to get a readable form (i.e ' ' = 'space' '\t'= 'tab')
+ * return a constant string giving the list of invalid chars in lib name
+ * static function
+ */
+const wxChar* MODULE::StringLibNameInvalidChars( bool aUserReadable )
+{
+ static const wxChar invalidChars[] = wxT("%$\t \"\\/");
+ static const wxChar invalidCharsReadable[] = wxT("% $ 'tab' 'space' \\ \" /");
+
+ if( aUserReadable )
+ return invalidCharsReadable;
+ else
+ return invalidChars;
+}
+
+
+void MODULE::Move( const wxPoint& aMoveVector )
+{
+ wxPoint newpos = m_Pos + aMoveVector;
+ SetPosition( newpos );
+}
+
+
+void MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
+{
+ wxPoint newpos = m_Pos;
+ RotatePoint( &newpos, aRotCentre, aAngle );
+ SetPosition( newpos );
+ SetOrientation( GetOrientation() + aAngle );
+}
+
+
+void MODULE::Flip( const wxPoint& aCentre )
+{
+ // Move module to its final position:
+ wxPoint finalPos = m_Pos;
+ MIRROR( finalPos.y, aCentre.y ); /// Mirror the Y position
+ SetPosition( finalPos );
+
+ // Flip layer
+ SetLayer( FlipLayer( GetLayer() ) );
+
+ // Reverse mirror orientation.
+ m_Orient = -m_Orient;
+ NORMALIZE_ANGLE_POS( m_Orient );
+
+ // Mirror pads to other side of board about the x axis, i.e. vertically.
+ for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
+ pad->Flip( m_Pos );
+
+ // Mirror reference and value.
+ m_Reference->Flip( m_Pos );
+ m_Value->Flip( m_Pos );
+
+ // Reverse mirror module graphics and texts.
+ for( EDA_ITEM* item = m_Drawings; item; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case PCB_MODULE_EDGE_T:
+ ( (EDGE_MODULE*) item )->Flip( m_Pos );
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ static_cast<TEXTE_MODULE*>( item )->Flip( m_Pos );
+ break;
+
+ default:
+ wxMessageBox( wxT( "MODULE::Flip() error: Unknown Draw Type" ) );
+ break;
+ }
+ }
+
+ CalculateBoundingBox();
+}
+
+
+void MODULE::SetPosition( const wxPoint& newpos )
+{
+ wxPoint delta = newpos - m_Pos;
+
+ m_Pos += delta;
+ m_Reference->SetTextPosition( m_Reference->GetTextPosition() + delta );
+ m_Value->SetTextPosition( m_Value->GetTextPosition() + delta );
+
+ for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
+ {
+ pad->SetPosition( pad->GetPosition() + delta );
+ }
+
+ for( EDA_ITEM* item = m_Drawings; item; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case PCB_MODULE_EDGE_T:
+ {
+ EDGE_MODULE* pt_edgmod = (EDGE_MODULE*) item;
+ pt_edgmod->SetDrawCoord();
+ break;
+ }
+
+ case PCB_MODULE_TEXT_T:
+ {
+ TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
+ text->SetTextPosition( text->GetTextPosition() + delta );
+ break;
+ }
+
+ default:
+ wxMessageBox( wxT( "Draw type undefined." ) );
+ break;
+ }
+ }
+
+ CalculateBoundingBox();
+}
+
+
+void MODULE::MoveAnchorPosition( const wxPoint& aMoveVector )
+{
+ /* Move the reference point of the footprint
+ * the footprints elements (pads, outlines, edges .. ) are moved
+ * but:
+ * - the footprint position is not modified.
+ * - the relative (local) coordinates of these items are modified
+ * - Draw coordinates are updated
+ */
+
+
+ // Update (move) the relative coordinates relative to the new anchor point.
+ wxPoint moveVector = aMoveVector;
+ RotatePoint( &moveVector, -GetOrientation() );
+
+ // Update of the reference and value.
+ m_Reference->SetPos0( m_Reference->GetPos0() + moveVector );
+ m_Reference->SetDrawCoord();
+ m_Value->SetPos0( m_Value->GetPos0() + moveVector );
+ m_Value->SetDrawCoord();
+
+ // Update the pad local coordinates.
+ for( D_PAD* pad = Pads(); pad; pad = pad->Next() )
+ {
+ pad->SetPos0( pad->GetPos0() + moveVector );
+ pad->SetDrawCoord();
+ }
+
+ // Update the draw element coordinates.
+ for( EDA_ITEM* item = GraphicalItems(); item; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case PCB_MODULE_EDGE_T:
+ {
+ EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( item );
+ edge->m_Start0 += moveVector;
+ edge->m_End0 += moveVector;
+ edge->SetDrawCoord();
+ break;
+ }
+
+ case PCB_MODULE_TEXT_T:
+ {
+ TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
+ text->SetPos0( text->GetPos0() + moveVector );
+ text->SetDrawCoord();
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ CalculateBoundingBox();
+}
+
+
+void MODULE::SetOrientation( double newangle )
+{
+ double angleChange = newangle - m_Orient; // change in rotation
+
+ NORMALIZE_ANGLE_POS( newangle );
+
+ m_Orient = newangle;
+
+ for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
+ {
+ pad->SetOrientation( pad->GetOrientation() + angleChange );
+ pad->SetDrawCoord();
+ }
+
+ // Update of the reference and value.
+ m_Reference->SetDrawCoord();
+ m_Value->SetDrawCoord();
+
+ // Displace contours and text of the footprint.
+ for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
+ {
+ if( item->Type() == PCB_MODULE_EDGE_T )
+ {
+ static_cast<EDGE_MODULE*>( item )->SetDrawCoord();
+ }
+ else if( item->Type() == PCB_MODULE_TEXT_T )
+ {
+ static_cast<TEXTE_MODULE*>( item )->SetDrawCoord();
+ }
+ }
+
+ CalculateBoundingBox();
+}
+
+BOARD_ITEM* MODULE::DuplicateAndAddItem( const BOARD_ITEM* aItem,
+ bool aIncrementPadNumbers )
+{
+ BOARD_ITEM* new_item = NULL;
+
+ switch( aItem->Type() )
+ {
+ case PCB_PAD_T:
+ {
+ D_PAD* new_pad = new D_PAD( *static_cast<const D_PAD*>( aItem ) );
+
+ Pads().PushBack( new_pad );
+ new_item = new_pad;
+ break;
+ }
+
+ case PCB_MODULE_TEXT_T:
+ {
+ const TEXTE_MODULE* old_text = static_cast<const TEXTE_MODULE*>( aItem );
+
+ // do not duplicate value or reference fields
+ // (there can only be one of each)
+ if( old_text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
+ {
+ TEXTE_MODULE* new_text = new TEXTE_MODULE( *old_text );
+
+ GraphicalItems().PushBack( new_text );
+ new_item = new_text;
+ }
+ break;
+ }
+
+ case PCB_MODULE_EDGE_T:
+ {
+ EDGE_MODULE* new_edge = new EDGE_MODULE(
+ *static_cast<const EDGE_MODULE*>(aItem) );
+
+ GraphicalItems().PushBack( new_edge );
+ new_item = new_edge;
+ break;
+ }
+
+ case PCB_MODULE_T:
+ // Ignore the module itself
+ break;
+
+ default:
+ // Un-handled item for duplication
+ wxASSERT_MSG( false, "Duplication not supported for items of class "
+ + aItem->GetClass() );
+ break;
+ }
+
+ if( aIncrementPadNumbers && new_item )
+ {
+ new_item->IncrementItemReference();
+ }
+
+ return new_item;
+}
+
+
+wxString MODULE::GetNextPadName( bool aFillSequenceGaps ) const
+{
+ std::set<int> usedNumbers;
+
+ // Create a set of used pad numbers
+ for( D_PAD* pad = Pads(); pad; pad = pad->Next() )
+ {
+ int padNumber = getTrailingInt( pad->GetPadName() );
+ usedNumbers.insert( padNumber );
+ }
+
+ const int nextNum = getNextNumberInSequence( usedNumbers, aFillSequenceGaps );
+
+ return wxString::Format( wxT( "%i" ), nextNum );
+}
+
+
+wxString MODULE::GetReferencePrefix() const
+{
+ wxString prefix = GetReference();
+
+ int strIndex = prefix.length() - 1;
+ while( strIndex >= 0 )
+ {
+ const wxUniChar chr = prefix.GetChar( strIndex );
+
+ // numeric suffix
+ if( chr >= '0' && chr <= '9' )
+ break;
+
+ strIndex--;
+ }
+
+ prefix = prefix.Mid( 0, strIndex );
+
+ return prefix;
+}
+
+
+bool MODULE::IncrementItemReference()
+{
+ // Take the next available module number
+ return IncrementReference( true );
+}
+
+
+bool MODULE::IncrementReference( bool aFillSequenceGaps )
+{
+ BOARD* board = GetBoard();
+
+ if( !board )
+ return false;
+
+ bool success = false;
+ const wxString prefix = GetReferencePrefix();
+ const wxString newReference = board->GetNextModuleReferenceWithPrefix(
+ prefix, aFillSequenceGaps );
+
+ if( !newReference.IsEmpty() )
+ {
+ SetReference( newReference );
+ success = true;
+ }
+
+ return success;
+}
+
+
+double MODULE::PadCoverageRatio() const
+{
+ double padArea = 0.0;
+ double moduleArea = GetFootprintRect().GetArea();
+
+ for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
+ padArea += pad->GetBoundingBox().GetArea();
+
+ if( moduleArea == 0.0 )
+ return 1.0;
+
+ double ratio = padArea / moduleArea;
+
+ return std::min( ratio, 1.0 );
+}
diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h
new file mode 100644
index 0000000..fedc62e
--- /dev/null
+++ b/pcbnew/class_module.h
@@ -0,0 +1,697 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_module.h
+ * @brief Module description (excepted pads)
+ */
+
+
+#ifndef MODULE_H_
+#define MODULE_H_
+
+
+#include <dlist.h>
+#include <layers_id_colors_and_visibility.h> // ALL_LAYERS definition.
+#include <class_board_item.h>
+#include <fpid.h>
+
+#include <class_text_mod.h>
+#include <PolyLine.h>
+#include "zones.h"
+
+#include <boost/function.hpp>
+
+class LINE_READER;
+class EDA_3D_CANVAS;
+class S3D_MASTER;
+class EDA_DRAW_PANEL;
+class D_PAD;
+class BOARD;
+class MSG_PANEL_ITEM;
+
+
+enum INCLUDE_NPTH_T
+{
+ DO_NOT_INCLUDE_NPTH = false,
+ INCLUDE_NPTH = true
+};
+
+/**
+ * Enum MODULE_ATTR_T
+ * is the set of attributes allowed within a MODULE, using MODULE::SetAttributes()
+ * and MODULE::GetAttributes(). These are to be ORed together when calling
+ * MODULE::SetAttributes()
+ */
+enum MODULE_ATTR_T
+{
+ MOD_DEFAULT = 0, ///< default
+ MOD_CMS = 1, ///< Set for modules listed in the automatic insertion list
+ ///< (usually SMD footprints)
+ MOD_VIRTUAL = 2 ///< Virtual component: when created by copper shapes on
+ ///< board (Like edge card connectors, mounting hole...)
+};
+
+
+class MODULE : public BOARD_ITEM
+{
+public:
+ MODULE( BOARD* parent );
+
+ MODULE( const MODULE& aModule );
+
+ ~MODULE();
+
+ static inline bool ClassOf( const EDA_ITEM* aItem )
+ {
+ return PCB_MODULE_T == aItem->Type();
+ }
+
+ MODULE* Next() const { return static_cast<MODULE*>( Pnext ); }
+ MODULE* Back() const { return static_cast<MODULE*>( Pback ); }
+
+ void Copy( MODULE* Module ); // Copy structure
+
+ /**
+ * Function Add
+ * adds the given item to this MODULE and takes ownership of its memory.
+ * @param aBoardItem The item to add to this board.
+ * @param doAppend If true, then append, else insert.
+ */
+ void Add( BOARD_ITEM* aBoardItem, bool doAppend = true );
+
+ /**
+ * Function Delete
+ * removes the given single item from this MODULE and deletes its memory.
+ * @param aBoardItem The item to remove from this module and delete
+ */
+ void Delete( BOARD_ITEM* aBoardItem )
+ {
+ // developers should run DEBUG versions and fix such calls with NULL
+ wxASSERT( aBoardItem );
+
+ if( aBoardItem )
+ delete Remove( aBoardItem );
+ }
+
+ /**
+ * Function Remove
+ * removes \a aBoardItem from this MODULE and returns it to caller without deleting it.
+ * @param aBoardItem The item to remove from this module.
+ * @return BOARD_ITEM* \a aBoardItem which was passed in.
+ */
+ BOARD_ITEM* Remove( BOARD_ITEM* aBoardItem );
+
+ /**
+ * Function ClearAllNets
+ * Clear (i.e. force the ORPHANED dummy net info) the net info which
+ * depends on a given board for all pads of the footprint.
+ * This is needed when a footprint is copied between the fp editor and
+ * the board editor for instance, because net info become fully broken
+ */
+ void ClearAllNets();
+
+ /**
+ * Function CalculateBoundingBox
+ * calculates the bounding box in board coordinates.
+ */
+ void CalculateBoundingBox();
+
+ /**
+ * Function GetFootprintRect()
+ * Returns the area of the module footprint excluding any text.
+ * @return EDA_RECT - The rectangle containing the footprint.
+ */
+ EDA_RECT GetFootprintRect() const;
+
+ // Virtual function
+ const EDA_RECT GetBoundingBox() const;
+
+ DLIST<D_PAD>& Pads() { return m_Pads; }
+ const DLIST<D_PAD>& Pads() const { return m_Pads; }
+
+ DLIST<BOARD_ITEM>& GraphicalItems() { return m_Drawings; }
+ const DLIST<BOARD_ITEM>& GraphicalItems() const { return m_Drawings; }
+
+ DLIST<S3D_MASTER>& Models() { return m_3D_Drawings; }
+ const DLIST<S3D_MASTER>& Models() const { return m_3D_Drawings; }
+
+ void SetPosition( const wxPoint& aPos ); // was overload
+ const wxPoint& GetPosition() const { return m_Pos; } // was overload
+
+ void SetOrientation( double newangle );
+ double GetOrientation() const { return m_Orient; }
+
+ const FPID& GetFPID() const { return m_fpid; }
+ void SetFPID( const FPID& aFPID ) { m_fpid = aFPID; }
+
+ const wxString& GetDescription() const { return m_Doc; }
+ void SetDescription( const wxString& aDoc ) { m_Doc = aDoc; }
+
+ const wxString& GetKeywords() const { return m_KeyWord; }
+ void SetKeywords( const wxString& aKeywords ) { m_KeyWord = aKeywords; }
+
+ const wxString& GetPath() const { return m_Path; }
+ void SetPath( const wxString& aPath ) { m_Path = aPath; }
+
+ int GetLocalSolderMaskMargin() const { return m_LocalSolderMaskMargin; }
+ void SetLocalSolderMaskMargin( int aMargin ) { m_LocalSolderMaskMargin = aMargin; }
+
+ int GetLocalClearance() const { return m_LocalClearance; }
+ void SetLocalClearance( int aClearance ) { m_LocalClearance = aClearance; }
+
+ int GetLocalSolderPasteMargin() const { return m_LocalSolderPasteMargin; }
+ void SetLocalSolderPasteMargin( int aMargin ) { m_LocalSolderPasteMargin = aMargin; }
+
+ double GetLocalSolderPasteMarginRatio() const { return m_LocalSolderPasteMarginRatio; }
+ void SetLocalSolderPasteMarginRatio( double aRatio ) { m_LocalSolderPasteMarginRatio = aRatio; }
+
+ void SetZoneConnection( ZoneConnection aType ) { m_ZoneConnection = aType; }
+ ZoneConnection GetZoneConnection() const { return m_ZoneConnection; }
+
+ void SetThermalWidth( int aWidth ) { m_ThermalWidth = aWidth; }
+ int GetThermalWidth() const { return m_ThermalWidth; }
+
+ void SetThermalGap( int aGap ) { m_ThermalGap = aGap; }
+ int GetThermalGap() const { return m_ThermalGap; }
+
+ int GetAttributes() const { return m_Attributs; }
+ void SetAttributes( int aAttributes ) { m_Attributs = aAttributes; }
+
+ void SetFlag( int aFlag ) { m_arflag = aFlag; }
+ void IncrementFlag() { m_arflag += 1; }
+ int GetFlag() const { return m_arflag; }
+
+ void Move( const wxPoint& aMoveVector );
+
+ void Rotate( const wxPoint& aRotCentre, double aAngle );
+
+ void Flip( const wxPoint& aCentre );
+
+ /**
+ * Function MoveAnchorPosition
+ * Move the reference point of the footprint
+ * It looks like a move footprint:
+ * the footprints elements (pads, outlines, edges .. ) are moved
+ * However:
+ * - the footprint position is not modified.
+ * - the relative (local) coordinates of these items are modified
+ * (a move footprint does not change these local coordinates,
+ * but changes the footprint position)
+ */
+ void MoveAnchorPosition( const wxPoint& aMoveVector );
+
+ /**
+ * function IsFlipped
+ * @return true if the module is flipped, i.e. on the back side of the board
+ */
+ bool IsFlipped() const {return GetLayer() == B_Cu; }
+
+// m_ModuleStatus bits:
+#define MODULE_is_LOCKED 0x01 ///< module LOCKED: no autoplace allowed
+#define MODULE_is_PLACED 0x02 ///< In autoplace: module automatically placed
+#define MODULE_to_PLACE 0x04 ///< In autoplace: module waiting for autoplace
+#define MODULE_PADS_LOCKED 0x08 ///< In autoplace: module waiting for autoplace
+
+
+ bool IsLocked() const
+ {
+ return (m_ModuleStatus & MODULE_is_LOCKED) != 0;
+ }
+
+ /**
+ * Function SetLocked
+ * sets the MODULE_is_LOCKED bit in the m_ModuleStatus
+ * @param isLocked When true means turn on locked status, else unlock
+ */
+ void SetLocked( bool isLocked )
+ {
+ if( isLocked )
+ m_ModuleStatus |= MODULE_is_LOCKED;
+ else
+ m_ModuleStatus &= ~MODULE_is_LOCKED;
+ }
+
+ bool IsPlaced() const { return (m_ModuleStatus & MODULE_is_PLACED); }
+ void SetIsPlaced( bool isPlaced )
+ {
+ if( isPlaced )
+ m_ModuleStatus |= MODULE_is_PLACED;
+ else
+ m_ModuleStatus &= ~MODULE_is_PLACED;
+ }
+
+ bool NeedsPlaced() const { return (m_ModuleStatus & MODULE_to_PLACE); }
+ void SetNeedsPlaced( bool needsPlaced )
+ {
+ if( needsPlaced )
+ m_ModuleStatus |= MODULE_to_PLACE;
+ else
+ m_ModuleStatus &= ~MODULE_to_PLACE;
+ }
+
+ bool PadsLocked() const { return ( m_ModuleStatus & MODULE_PADS_LOCKED ); }
+
+ void SetPadsLocked( bool aPadsLocked )
+ {
+ if( aPadsLocked )
+ m_ModuleStatus |= MODULE_PADS_LOCKED;
+ else
+ m_ModuleStatus &= ~MODULE_PADS_LOCKED;
+ }
+
+ void SetLastEditTime( time_t aTime ) { m_LastEditTime = aTime; }
+ void SetLastEditTime( ) { m_LastEditTime = time( NULL ); }
+ time_t GetLastEditTime() const { return m_LastEditTime; }
+
+ /* drawing functions */
+
+ /**
+ * Function Draw
+ * draws the footprint to the \a aDC.
+ * @param aPanel = draw panel, Used to know the clip box
+ * @param aDC = Current Device Context
+ * @param aDrawMode = GR_OR, GR_XOR..
+ * @param aOffset = draw offset (usually wxPoint(0,0)
+ */
+ void Draw( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC,
+ GR_DRAWMODE aDrawMode,
+ const wxPoint& aOffset = ZeroOffset );
+
+ /**
+ * Function DrawOutlinesWhenMoving
+ * draws in XOR mode the footprint when moving it to the \a aDC.
+ * To speed up the drawing, only a simplified shape is drawn
+ * @param aPanel = draw panel, Used to know the clip box
+ * @param aDC = Current Device Context
+ * @param aMoveVector = the offset between the curr position and
+ * the draw position.
+ */
+ void DrawOutlinesWhenMoving( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC, const wxPoint& aMoveVector );
+
+ /**
+ * function TransformPadsShapesWithClearanceToPolygon
+ * generate pads shapes on layer aLayer as polygons,
+ * and adds these polygons to aCornerBuffer
+ * Useful to generate a polygonal representation of a footprint
+ * in 3D view and plot functions, when a full polygonal approach is needed
+ * @param aLayer = the current layer: pads on this layer are considered
+ * @param aCornerBuffer = the buffer to store polygons
+ * @param aInflateValue = an additionnal size to add to pad shapes
+ * aInflateValue = 0 to have the exact pad size
+ * @param aCircleToSegmentsCount = number of segments to generate a circle
+ * @param aCorrectionFactor = the correction to apply to a circle radius
+ * to approximate a circle by the polygon.
+ * if aCorrectionFactor = 1.0, the polygon is inside the circle
+ * the radius of circle approximated by segments is
+ * initial radius * aCorrectionFactor
+ * @param aSkipNPTHPadsWihNoCopper = if true, do not add a NPTH pad shape,
+ * if the shape has same size and position as the hole. Usually, these
+ * pads are not drawn on copper layers, because there is actually no copper
+ * Due to diff between layers and holes, these pads must be skipped to be sure
+ * there is no copper left on the board (for instance when creating Gerber Files or 3D shapes)
+ * default = false
+ */
+ void TransformPadsShapesWithClearanceToPolygon( LAYER_ID aLayer,
+ SHAPE_POLY_SET& aCornerBuffer,
+ int aInflateValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor,
+ bool aSkipNPTHPadsWihNoCopper = false );
+
+ /**
+ * function TransformGraphicShapesWithClearanceToPolygonSet
+ * generate shapes of graphic items (outlines) on layer aLayer as polygons,
+ * and adds these polygons to aCornerBuffer
+ * Useful to generate a polygonal representation of a footprint
+ * in 3D view and plot functions, when a full polygonal approach is needed
+ * @param aLayer = the current layer: items on this layer are considered
+ * @param aCornerBuffer = the buffer to store polygons
+ * @param aInflateValue = a value to inflate shapes
+ * aInflateValue = 0 to have the exact shape size
+ * @param aCircleToSegmentsCount = number of segments to generate a circle
+ * @param aCorrectionFactor = the correction to apply to a circle radius
+ * to approximate a circle by the polygon.
+ * if aCorrectionFactor = 1.0, the polygon is inside the circle
+ * the radius of circle approximated by segments is
+ * initial radius * aCorrectionFactor
+ * @param aCircleToSegmentsCountForTexts = number of segments to generate
+ * a circle when building the texts polygonal shapes of the stroke font
+ * if 0, use the aCircleToSegmentsCount value
+ */
+ void TransformGraphicShapesWithClearanceToPolygonSet(
+ LAYER_ID aLayer,
+ SHAPE_POLY_SET& aCornerBuffer,
+ int aInflateValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor,
+ int aCircleToSegmentsCountForTexts = 0 );
+
+ /**
+ * Function DrawEdgesOnly
+ * Draws the footprint edges only to the current Device Context
+ * @param panel = The active Draw Panel (used to know the clip box)
+ * @param DC = current Device Context
+ * @param offset = draw offset (usually wxPoint(0,0)
+ * @param draw_mode = GR_OR, GR_XOR, GR_AND
+ */
+ void DrawEdgesOnly( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
+ GR_DRAWMODE draw_mode );
+
+ void DrawAncre( EDA_DRAW_PANEL* panel, wxDC* DC,
+ const wxPoint& offset, int dim_ancre, GR_DRAWMODE draw_mode );
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
+ * bool aContained = true, int aAccuracy ) const
+ */
+ bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const;
+
+ /**
+ * Function GetReference
+ * @return const wxString& - the reference designator text.
+ */
+ const wxString& GetReference() const
+ {
+ return m_Reference->GetText();
+ }
+
+ /**
+ * Function SetReference
+ * @param aReference A reference to a wxString object containing the reference designator
+ * text.
+ */
+ void SetReference( const wxString& aReference )
+ {
+ m_Reference->SetText( aReference );
+ }
+
+ /**
+ * Function GetReference prefix
+ * Gets the alphabetic prefix of the module reference - e.g.
+ * R1 -> R
+ * IC34 -> IC
+ * @return the reference prefix (may be empty)
+ */
+ wxString GetReferencePrefix() const;
+
+ /**
+ * Function GetValue
+ * @return const wxString& - the value text.
+ */
+ const wxString& GetValue() const
+ {
+ return m_Value->GetText();
+ }
+
+ /**
+ * Function SetValue
+ * @param aValue A reference to a wxString object containing the value text.
+ */
+ void SetValue( const wxString& aValue )
+ {
+ m_Value->SetText( aValue );
+ }
+
+ /// read/write accessors:
+ TEXTE_MODULE& Value() { return *m_Value; }
+ TEXTE_MODULE& Reference() { return *m_Reference; }
+
+ /// The const versions to keep the compiler happy.
+ TEXTE_MODULE& Value() const { return *m_Value; }
+ TEXTE_MODULE& Reference() const { return *m_Reference; }
+
+ /*!
+ * Function IncrementItemReference
+ * Implementation of the generic "reference" incrementing interface
+ * Increments the numeric suffix, filling any sequence gaps
+ */
+ bool IncrementItemReference(); //override
+
+ /**
+ * Function IncrementReference
+ * Increments the module's reference, if possible. A reference with
+ * a numerical suffix and an optional alphabetical prefix can be
+ * incremented: "A1" and "1" can be, "B" can't.
+ *
+ * @param aFillSequenceGaps if true, the next reference in a sequence
+ * like A1,A3,A4 will be A2. If false, it will be A5.
+ * @return true if the reference was incremented.
+ */
+ bool IncrementReference( bool aFillSequenceGaps );
+
+ /**
+ * Function FindPadByName
+ * returns a D_PAD* with a matching name. Note that names may not be
+ * unique, depending on how the foot print was created.
+ * @param aPadName the pad name to find
+ * @return D_PAD* - The first matching name is returned, or NULL if not
+ * found.
+ */
+ D_PAD* FindPadByName( const wxString& aPadName ) const;
+
+ /**
+ * Function GetPad
+ * get a pad at \a aPosition on \a aLayerMask in the footprint.
+ *
+ * @param aPosition A wxPoint object containing the position to hit test.
+ * @param aLayerMask A layer or layers to mask the hit test.
+ * @return A pointer to a D_PAD object if found otherwise NULL.
+ */
+ D_PAD* GetPad( const wxPoint& aPosition, LSET aLayerMask = LSET::AllLayersMask() );
+
+ /**
+ * GetPadCount
+ * returns the number of pads.
+ *
+ * @param aIncludeNPTH includes non-plated through holes when true. Does not include
+ * non-plated through holes when false.
+ * @return the number of pads according to \a aIncludeNPTH.
+ */
+ unsigned GetPadCount( INCLUDE_NPTH_T aIncludeNPTH = INCLUDE_NPTH_T( INCLUDE_NPTH ) ) const;
+
+ /**
+ * GetUniquePadCount
+ * returns the number of unique pads.
+ * A complex pad can be built with many pads having the same pad name
+ * to create a complex shape or fragmented solder paste areas.
+ *
+ * GetUniquePadCount calculate the count of not blank pad names
+ *
+ * @param aIncludeNPTH includes non-plated through holes when true. Does not include
+ * non-plated through holes when false.
+ * @return the number of unique pads according to \a aIncludeNPTH.
+ */
+ unsigned GetUniquePadCount( INCLUDE_NPTH_T aIncludeNPTH = INCLUDE_NPTH_T( INCLUDE_NPTH ) ) const;
+
+ /**
+ * Function GetNextPadName
+ * returns the next available pad name in the module
+ *
+ * @param aFillSequenceGaps true if the numbering should "fill in" gaps in
+ * the sequence, else return the highest value + 1
+ * @return the next available pad name
+ */
+ wxString GetNextPadName( bool aFillSequenceGaps ) const;
+
+ double GetArea() const { return m_Surface; }
+
+ time_t GetLink() const { return m_Link; }
+ void SetLink( time_t aLink ) { m_Link = aLink; }
+
+ int GetPlacementCost180() const { return m_CntRot180; }
+ void SetPlacementCost180( int aCost ) { m_CntRot180 = aCost; }
+
+ int GetPlacementCost90() const { return m_CntRot90; }
+ void SetPlacementCost90( int aCost ) { m_CntRot90 = aCost; }
+
+ /**
+ * Function DuplicateAndAddItem
+ * Duplicate a given item within the module
+ * @return the new item, or NULL if the item could not be duplicated
+ */
+ BOARD_ITEM* DuplicateAndAddItem( const BOARD_ITEM* item,
+ bool aIncrementPadNumbers );
+
+ /**
+ * Function Add3DModel
+ * adds \a a3DModel definition to the end of the 3D model list.
+ *
+ * @param a3DModel A pointer to a #S3D_MASTER to add to the list.
+ */
+ void Add3DModel( S3D_MASTER* a3DModel );
+
+ SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
+ const KICAD_T scanTypes[] );
+
+ wxString GetClass() const
+ {
+ return wxT( "MODULE" );
+ }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return module_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+ /**
+ * Function RunOnChildren
+ *
+ * Invokes a function on all BOARD_ITEMs that belong to the module (pads, drawings, texts).
+ * @param aFunction is the function to be invoked.
+ */
+ void RunOnChildren( boost::function<void (BOARD_ITEM*)> aFunction );
+
+ /// @copydoc VIEW_ITEM::ViewUpdate()
+ void ViewUpdate( int aUpdateFlags = KIGFX::VIEW_ITEM::ALL );
+
+ /// @copydoc VIEW_ITEM::ViewGetLayers()
+ virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
+
+ /// @copydoc VIEW_ITEM::ViewGetLOD()
+ virtual unsigned int ViewGetLOD( int aLayer ) const;
+
+ /// @copydoc VIEW_ITEM::ViewBBox()
+ virtual const BOX2I ViewBBox() const;
+
+ /**
+ * Function CopyNetlistSettings
+ * copies the netlist settings to \a aModule.
+ * Used to copy some footprint parameters when replacing a footprint by an other
+ * footprint when reading a netlist, or in exchange footprint dialog
+ *
+ * The netlist settings are all of the #MODULE settings not define by a #MODULE in
+ * a netlist. These setting include placement prms (position, orientation, side)
+ * and optionally local prms( clearances, zone connection type, etc).
+ * The reference designator, value, path, and physical geometry settings are not
+ * copied.
+ *
+ * @param aModule is the #MODULE to copy the settings to.
+ * @param aCopyLocalSettings = false to copy only module placement
+ * true to also copy local prms
+ */
+ void CopyNetlistSettings( MODULE* aModule, bool aCopyLocalSettings );
+
+ /**
+ * static function IsLibNameValid
+ * Test for validity of a name of a footprint to be used in a footprint library
+ * ( no spaces, dir separators ... )
+ * @param aName = the name in library to validate
+ * @return true if the given name is valid
+ */
+ static bool IsLibNameValid( const wxString & aName );
+
+ /**
+ * static function StringLibNameInvalidChars
+ * Test for validity of the name in a library of the footprint
+ * ( no spaces, dir separators ... )
+ * @param aUserReadable = false to get the list of invalid chars
+ * true to get a readable form (i.e ' ' = 'space' '\\t'= 'tab')
+ * @return a constant std::string giving the list of invalid chars in lib name
+ */
+ static const wxChar* StringLibNameInvalidChars( bool aUserReadable );
+
+ /**
+ * Function SetInitialComments
+ * takes ownership of caller's heap allocated aInitialComments block. The comments
+ * are single line strings already containing the s-expression comments with
+ * optional leading whitespace and then a '#' character followed by optional
+ * single line text (text with no line endings, not even one).
+ * This block of single line comments will be output upfront of any generated
+ * s-expression text in the PCBIO::Format() function.
+ * <p>
+ * Note that a block of single line comments constitutes a multiline block of
+ * single line comments. That is, the block is made of consecutive single line
+ * comments.
+ * @param aInitialComments is a heap allocated wxArrayString or NULL, which the caller
+ * gives up ownership of over to this MODULE.
+ */
+ void SetInitialComments( wxArrayString* aInitialComments )
+ {
+ delete m_initial_comments;
+ m_initial_comments = aInitialComments;
+ }
+
+ /**
+ * Function PadCoverageRatio
+ * Calculates the ratio of total area of the footprint pads to the area of the
+ * footprint. Used by selection tool heuristics.
+ * @return the ratio
+ */
+ double PadCoverageRatio() const;
+
+ /// Return the initial comments block or NULL if none, without transfer of ownership.
+ const wxArrayString* GetInitialComments() const { return m_initial_comments; }
+
+#if defined(DEBUG)
+ virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+
+private:
+ DLIST<D_PAD> m_Pads; ///< Linked list of pads.
+ DLIST<BOARD_ITEM> m_Drawings; ///< Linked list of graphical items.
+ DLIST<S3D_MASTER> m_3D_Drawings; ///< Linked list of 3D models.
+ double m_Orient; ///< Orientation in tenths of a degree, 900=90.0 degrees.
+ wxPoint m_Pos; ///< Position of module on the board in internal units.
+ TEXTE_MODULE* m_Reference; ///< Component reference designator value (U34, R18..)
+ TEXTE_MODULE* m_Value; ///< Component value (74LS00, 22K..)
+ FPID m_fpid; ///< The #FPID of the MODULE.
+ int m_Attributs; ///< Flag bits ( see Mod_Attribut )
+ int m_ModuleStatus; ///< For autoplace: flags (LOCKED, AUTOPLACED)
+ EDA_RECT m_BoundaryBox; ///< Bounding box : coordinates on board, real orientation.
+
+ // The final margin is the sum of these 2 values
+ int m_ThermalWidth;
+ int m_ThermalGap;
+ wxString m_Doc; ///< File name and path for documentation file.
+ wxString m_KeyWord; ///< Search keywords to find module in library.
+ wxString m_Path;
+ ZoneConnection m_ZoneConnection;
+ time_t m_LastEditTime;
+ int m_arflag; ///< Use to trace ratsnest and auto routing.
+ double m_Surface; ///< Bounding box area
+ time_t m_Link; ///< Temporary logical link used in edition
+ int m_CntRot90; ///< Horizontal automatic placement cost ( 0..10 ).
+ int m_CntRot180; ///< Vertical automatic placement cost ( 0..10 ).
+
+ // Local tolerances. When zero, this means the corresponding netclass value
+ // is used. Usually theses local tolerances zero, in deference to the
+ // corresponding netclass values.
+ int m_LocalClearance;
+ int m_LocalSolderMaskMargin; ///< Solder mask margin
+ int m_LocalSolderPasteMargin; ///< Solder paste margin absolute value
+ double m_LocalSolderPasteMarginRatio; ///< Solder mask margin ratio
+ ///< value of pad size
+
+ wxArrayString* m_initial_comments; ///< leading s-expression comments in the module,
+ ///< lazily allocated only if needed for speed
+};
+
+#endif // MODULE_H_
diff --git a/pcbnew/class_netclass.cpp b/pcbnew/class_netclass.cpp
new file mode 100644
index 0000000..1dfeac0
--- /dev/null
+++ b/pcbnew/class_netclass.cpp
@@ -0,0 +1,266 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@inpg.fr
+ * Copyright (C) 2009 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <boost/make_shared.hpp>
+
+#include <fctsys.h>
+#include <common.h>
+#include <kicad_string.h>
+#include <pcbnew.h>
+#include <richio.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_netclass.h>
+
+
+// This will get mapped to "kicad_default" in the specctra_export.
+const wxChar NETCLASS::Default[] = wxT( "Default" );
+
+// Initial values for netclass initialization
+const int NETCLASS::DEFAULT_CLEARANCE = Millimeter2iu( 0.2 ); // track to track and track to pads clearance
+const int NETCLASS::DEFAULT_VIA_DIAMETER = Millimeter2iu( 0.6 );
+const int NETCLASS::DEFAULT_VIA_DRILL = Millimeter2iu( 0.4 );
+const int NETCLASS::DEFAULT_UVIA_DIAMETER = Millimeter2iu( 0.3 );
+const int NETCLASS::DEFAULT_UVIA_DRILL = Millimeter2iu( 0.1 );
+const int NETCLASS::DEFAULT_TRACK_WIDTH = Millimeter2iu( 0.25 );
+
+
+NETCLASS::NETCLASS( const wxString& aName ) :
+ m_Name( aName )
+{
+ // Default settings
+ SetClearance( DEFAULT_CLEARANCE );
+ SetViaDrill( DEFAULT_VIA_DRILL );
+ SetuViaDrill( DEFAULT_UVIA_DRILL );
+ // These defaults will be overwritten by SetParams,
+ // from the board design parameters, later
+ SetTrackWidth( DEFAULT_TRACK_WIDTH );
+ SetViaDiameter( DEFAULT_VIA_DIAMETER );
+ SetuViaDiameter( DEFAULT_UVIA_DIAMETER );
+}
+
+
+void NETCLASS::SetParams( const NETCLASS& aDefaults )
+{
+ SetClearance( aDefaults.GetClearance() );
+ SetTrackWidth( aDefaults.GetTrackWidth() );
+ SetViaDiameter( aDefaults.GetViaDiameter() );
+ SetViaDrill( aDefaults.GetViaDrill() );
+ SetuViaDiameter( aDefaults.GetuViaDiameter() );
+ SetuViaDrill( aDefaults.GetuViaDrill() );
+}
+
+
+NETCLASS::~NETCLASS()
+{
+}
+
+
+NETCLASSES::NETCLASSES()
+{
+ m_Default = boost::make_shared<NETCLASS>( NETCLASS::Default );
+}
+
+
+NETCLASSES::~NETCLASSES()
+{
+}
+
+
+bool NETCLASSES::Add( NETCLASSPTR aNetClass )
+{
+ const wxString& name = aNetClass->GetName();
+
+ if( name == NETCLASS::Default )
+ {
+ // invoke operator=(), which is currently generated by compiler.
+ m_Default = aNetClass;
+
+ return true;
+ }
+
+ // Test for an existing netclass:
+ if( !Find( name ) )
+ {
+ // name not found, take ownership
+ m_NetClasses[name] = aNetClass;
+
+ return true;
+ }
+ else
+ {
+ // name already exists
+ // do not "take ownership" and return false telling caller such.
+ return false;
+ }
+}
+
+
+NETCLASSPTR NETCLASSES::Remove( const wxString& aNetName )
+{
+ NETCLASSMAP::iterator found = m_NetClasses.find( aNetName );
+
+ if( found != m_NetClasses.end() )
+ {
+ boost::shared_ptr<NETCLASS> netclass = found->second;
+ m_NetClasses.erase( found );
+ return netclass;
+ }
+
+ return NETCLASSPTR();
+}
+
+
+NETCLASSPTR NETCLASSES::Find( const wxString& aName ) const
+{
+ if( aName == NETCLASS::Default )
+ return m_Default;
+
+ NETCLASSMAP::const_iterator found = m_NetClasses.find( aName );
+
+ if( found == m_NetClasses.end() )
+ return NETCLASSPTR();
+ else
+ return found->second;
+}
+
+
+void BOARD::SynchronizeNetsAndNetClasses()
+{
+ NETCLASSES& netClasses = m_designSettings.m_NetClasses;
+ NETCLASSPTR defaultNetClass = netClasses.GetDefault();
+
+ // set all NETs to the default NETCLASS, then later override some
+ // as we go through the NETCLASSes.
+
+ for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
+ net != netEnd; ++net )
+ {
+ net->SetClass( defaultNetClass );
+ }
+
+ // Add netclass name and pointer to nets. If a net is in more than one netclass,
+ // set the net's name and pointer to only the first netclass. Subsequent
+ // and therefore bogus netclass memberships will be deleted in logic below this loop.
+ for( NETCLASSES::iterator clazz = netClasses.begin(); clazz != netClasses.end(); ++clazz )
+ {
+ NETCLASSPTR netclass = clazz->second;
+
+ for( NETCLASS::const_iterator member = netclass->begin(); member != netclass->end(); ++member )
+ {
+ const wxString& netname = *member;
+
+ // although this overall function seems to be adequately fast,
+ // FindNet( wxString ) uses now a fast binary search and is fast
+ // event for large net lists
+ NETINFO_ITEM* net = FindNet( netname );
+
+ if( net && net->GetClassName() == NETCLASS::Default )
+ {
+ net->SetClass( netclass );
+ }
+ }
+ }
+
+ // Finally, make sure that every NET is in a NETCLASS, even if that
+ // means the Default NETCLASS. And make sure that all NETCLASSes do not
+ // contain netnames that do not exist, by deleting all netnames from
+ // every netclass and re-adding them.
+
+ for( NETCLASSES::iterator clazz = netClasses.begin(); clazz != netClasses.end(); ++clazz )
+ {
+ NETCLASSPTR netclass = clazz->second;
+
+ netclass->Clear();
+ }
+
+ defaultNetClass->Clear();
+
+ for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
+ net != netEnd; ++net )
+ {
+ const wxString& classname = net->GetClassName();
+
+ // because of the std:map<> this should be fast, and because of
+ // prior logic, netclass should not be NULL.
+ NETCLASSPTR netclass = netClasses.Find( classname );
+
+ wxASSERT( netclass );
+
+ netclass->Add( net->GetNetname() );
+ }
+
+ // Set initial values for custom track width & via size to match the default netclass settings
+ m_designSettings.UseCustomTrackViaSize( false );
+ m_designSettings.SetCustomTrackWidth( defaultNetClass->GetTrackWidth() );
+ m_designSettings.SetCustomViaSize( defaultNetClass->GetViaDiameter() );
+ m_designSettings.SetCustomViaDrill( defaultNetClass->GetViaDrill() );
+}
+
+
+#if defined(DEBUG)
+
+void NETCLASS::Show( int nestLevel, std::ostream& os ) const
+{
+ // for now, make it look like XML:
+ //NestedSpace( nestLevel, os )
+
+ os << '<' << GetClass().Lower().mb_str() << ">\n";
+
+ for( const_iterator i = begin(); i!=end(); ++i )
+ {
+ // NestedSpace( nestLevel+1, os ) << *i;
+ os << TO_UTF8( *i );
+ }
+
+ // NestedSpace( nestLevel, os )
+ os << "</" << GetClass().Lower().mb_str() << ">\n";
+}
+
+#endif
+
+
+void NETCLASS::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
+ throw( IO_ERROR )
+{
+ aFormatter->Print( aNestLevel, "(net_class %s %s\n",
+ aFormatter->Quotew( GetName() ).c_str(),
+ aFormatter->Quotew( GetDescription() ).c_str() );
+
+ aFormatter->Print( aNestLevel+1, "(clearance %s)\n", FMT_IU( GetClearance() ).c_str() );
+ aFormatter->Print( aNestLevel+1, "(trace_width %s)\n", FMT_IU( GetTrackWidth() ).c_str() );
+
+ aFormatter->Print( aNestLevel+1, "(via_dia %s)\n", FMT_IU( GetViaDiameter() ).c_str() );
+ aFormatter->Print( aNestLevel+1, "(via_drill %s)\n", FMT_IU( GetViaDrill() ).c_str() );
+
+ aFormatter->Print( aNestLevel+1, "(uvia_dia %s)\n", FMT_IU( GetuViaDiameter() ).c_str() );
+ aFormatter->Print( aNestLevel+1, "(uvia_drill %s)\n", FMT_IU( GetuViaDrill() ).c_str() );
+
+ for( NETCLASS::const_iterator it = begin(); it != end(); ++it )
+ aFormatter->Print( aNestLevel+1, "(add_net %s)\n", aFormatter->Quotew( *it ).c_str() );
+
+ aFormatter->Print( aNestLevel, ")\n\n" );
+}
diff --git a/pcbnew/class_netclass.h b/pcbnew/class_netclass.h
new file mode 100644
index 0000000..5b6bbe1
--- /dev/null
+++ b/pcbnew/class_netclass.h
@@ -0,0 +1,294 @@
+/**
+ * @file class_netclass.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@inpg.fr
+ * Copyright (C) 2009 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef CLASS_NETCLASS_H
+#define CLASS_NETCLASS_H
+
+#include <set>
+#include <map>
+#include <boost/shared_ptr.hpp>
+
+#include <wx/string.h>
+
+#include <richio.h>
+
+
+class LINE_READER;
+class BOARD;
+class BOARD_DESIGN_SETTINGS;
+
+
+/**
+ * Class NETCLASS
+ * handles a collection of nets and the parameters used to route or
+ * test these nets.
+ */
+
+class NETCLASS
+{
+private:
+ // Default values used to init a NETCLASS
+ static const int DEFAULT_CLEARANCE;
+ static const int DEFAULT_VIA_DRILL;
+ static const int DEFAULT_UVIA_DRILL;
+ static const int DEFAULT_VIA_DIAMETER;
+ static const int DEFAULT_UVIA_DIAMETER;
+ static const int DEFAULT_TRACK_WIDTH;
+
+protected:
+ wxString m_Name; ///< Name of the net class
+ wxString m_Description; ///< what this NETCLASS is for.
+
+ typedef std::set<wxString> STRINGSET;
+
+ STRINGSET m_Members; ///< names of NET members of this class
+
+ /// The units on these parameters is Internal Units (1 nm)
+
+ int m_Clearance; ///< clearance when routing
+
+ int m_TrackWidth; ///< track width used to route NETs in this NETCLASS
+ int m_ViaDia; ///< via diameter
+ int m_ViaDrill; ///< via drill hole diameter
+
+ int m_uViaDia; ///< microvia diameter
+ int m_uViaDrill; ///< microvia drill hole diameter
+
+public:
+
+ static const wxChar Default[]; ///< the name of the default NETCLASS
+
+ /**
+ * Constructor
+ * stuffs a NETCLASS instance with aParent, aName, and optionally the initialParameters
+ * @param aName = the name of this new netclass
+ */
+ NETCLASS( const wxString& aName );
+
+ ~NETCLASS();
+
+ wxString GetClass() const
+ {
+ return wxT( "NETCLASS" );
+ }
+
+ const wxString& GetName() const
+ {
+ return m_Name;
+ }
+
+ void SetName( const wxString& aName ) { m_Name = aName; }
+
+ /**
+ * Function GetCount
+ * returns the number of nets in this NETCLASS, i.e. using these rules.
+ */
+ unsigned GetCount() const
+ {
+ return m_Members.size();
+ }
+
+ /**
+ * Function Clear
+ * empties the collection of members.
+ */
+ void Clear()
+ {
+ m_Members.clear();
+ }
+
+ /**
+ * Function Add
+ * adds \a aNetname to this NETCLASS if it is not already in this NETCLASS.
+ * It is harmless to try and add a second identical name.
+ */
+ void Add( const wxString& aNetname )
+ {
+ m_Members.insert( aNetname );
+ }
+
+ typedef STRINGSET::iterator iterator;
+ iterator begin() { return m_Members.begin(); }
+ iterator end() { return m_Members.end(); }
+
+ typedef STRINGSET::const_iterator const_iterator;
+ const_iterator begin() const { return m_Members.begin(); }
+ const_iterator end() const { return m_Members.end(); }
+
+ /**
+ * Function Remove
+ * will remove NET name \a aName from the collection of members.
+ */
+ void Remove( iterator aName )
+ {
+ m_Members.erase( aName );
+ }
+
+ /**
+ * Function Remove
+ * will remove NET name \a aName from the collection of members.
+ */
+ void Remove( const wxString& aName )
+ {
+ m_Members.erase( aName );
+ }
+
+ const wxString& GetDescription() const { return m_Description; }
+ void SetDescription( const wxString& aDesc ) { m_Description = aDesc; }
+
+ int GetClearance() const { return m_Clearance; }
+ void SetClearance( int aClearance ) { m_Clearance = aClearance; }
+
+ int GetTrackWidth() const { return m_TrackWidth; }
+ void SetTrackWidth( int aWidth ) { m_TrackWidth = aWidth; }
+
+ int GetViaDiameter() const { return m_ViaDia; }
+ void SetViaDiameter( int aDia ) { m_ViaDia = aDia; }
+
+ int GetViaDrill() const { return m_ViaDrill; }
+ void SetViaDrill( int aSize ) { m_ViaDrill = aSize; }
+
+ int GetuViaDiameter() const { return m_uViaDia; }
+ void SetuViaDiameter( int aSize ) { m_uViaDia = aSize; }
+
+ int GetuViaDrill() const { return m_uViaDrill; }
+ void SetuViaDrill( int aSize ) { m_uViaDrill = aSize; }
+
+ /**
+ * Function SetParams
+ * will set all the parameters by copying them from \a defaults.
+ * Parameters are the values like m_ViaSize, etc, but do not include m_Description.
+ * @param aDefaults is another NETCLASS object to copy from.
+ */
+ void SetParams( const NETCLASS& aDefaults );
+
+ /**
+ * Function Format
+ * outputs the net class to \a aFormatter in s-expression form.
+ *
+ * @param aFormatter The #OUTPUTFORMATTER object to write to.
+ * @param aNestLevel The indentation next level.
+ * @param aControlBits The control bit definition for object specific formatting.
+ * @throw IO_ERROR on write error.
+ */
+ void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
+ throw( IO_ERROR );
+
+#if defined(DEBUG)
+ void Show( int nestLevel, std::ostream& os ) const; // overload
+#endif
+};
+
+typedef boost::shared_ptr<NETCLASS> NETCLASSPTR;
+
+/**
+ * Class NETCLASSES
+ * is a container for NETCLASS instances. It owns all its NETCLASSes
+ * (=> it will delete them at time of destruction). This container will always have
+ * a default NETCLASS with the name given by const NETCLASS::Default.
+ */
+class NETCLASSES
+{
+private:
+ typedef std::map<wxString, NETCLASSPTR> NETCLASSMAP;
+
+ /// all the NETCLASSes except the default one.
+ NETCLASSMAP m_NetClasses;
+
+ /// the default NETCLASS.
+ NETCLASSPTR m_Default;
+
+public:
+ NETCLASSES();
+ ~NETCLASSES();
+
+ /**
+ * Function Clear
+ * destroys any contained NETCLASS instances except the Default one.
+ */
+ void Clear()
+ {
+ m_NetClasses.clear();
+ }
+
+ typedef NETCLASSMAP::iterator iterator;
+ iterator begin() { return m_NetClasses.begin(); }
+ iterator end() { return m_NetClasses.end(); }
+
+ typedef NETCLASSMAP::const_iterator const_iterator;
+ const_iterator begin() const { return m_NetClasses.begin(); }
+ const_iterator end() const { return m_NetClasses.end(); }
+
+ /**
+ * Function GetCount
+ * @return the number of netclasses, excluding the default one.
+ */
+ unsigned GetCount() const
+ {
+ return m_NetClasses.size();
+ }
+
+ /**
+ * Function GetDefault
+ * @return the default net class.
+ */
+ NETCLASSPTR GetDefault() const
+ {
+ return m_Default;
+ }
+
+ /**
+ * Function Add
+ * takes ownership of \a aNetclass and puts it into this NETCLASSES container.
+ * @param aNetclass is netclass to add
+ * @return true if the name within aNetclass is unique and it could be inserted OK,
+ * else false because the name was not unique and caller still owns aNetclass.
+ */
+ bool Add( NETCLASSPTR aNetclass );
+
+ /**
+ * Function Remove
+ * removes a NETCLASS from this container but does not destroy/delete it.
+ * @param aNetName is the name of the net to delete, and it may not be NETCLASS::Default.
+ * @return NETCLASSPTR - the NETCLASS associated with aNetName if found and removed, else NULL.
+ */
+ NETCLASSPTR Remove( const wxString& aNetName );
+
+ /**
+ * Function Find
+ * searches this container for a NETCLASS given by \a aName.
+ * @param aName is the name of the NETCLASS to search for.
+ * @return NETCLASSPTR - if found, else NULL.
+ */
+ NETCLASSPTR Find( const wxString& aName ) const;
+
+};
+
+#endif // CLASS_NETCLASS_H
diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h
new file mode 100644
index 0000000..8fb74d5
--- /dev/null
+++ b/pcbnew/class_netinfo.h
@@ -0,0 +1,691 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_netinfo.h
+ */
+
+/*
+ * Classes to handle info on nets
+ */
+
+#ifndef __CLASSES_NETINFO__
+#define __CLASSES_NETINFO__
+
+
+#include <gr_basic.h>
+#include <class_netclass.h>
+#include <boost/unordered_map.hpp>
+#include <hashtables.h>
+
+
+class wxDC;
+class wxPoint;
+class LINE_READER;
+class EDA_DRAW_PANEL;
+class EDA_DRAW_FRAME;
+class NETINFO_ITEM;
+class D_PAD;
+class BOARD;
+class BOARD_ITEM;
+class MSG_PANEL_ITEM;
+
+
+/*****************************/
+/* flags for a RATSNEST_ITEM */
+/*****************************/
+#define CH_VISIBLE 1 /* Visible */
+#define CH_UNROUTABLE 2 /* Don't use autorouter. */
+#define CH_ROUTE_REQ 4 /* Must be routed by the autorouter. */
+#define CH_ACTIF 8 /* Not routed. */
+#define LOCAL_RATSNEST_ITEM 0x8000 /* Line between two pads of a single module. */
+
+
+/**
+ * Class RATSNEST_ITEM
+ * describes a ratsnest line: a straight line connecting 2 pads
+ */
+class RATSNEST_ITEM
+{
+private:
+ int m_NetCode; // netcode ( = 1.. n , 0 is the value used for not connected items)
+
+public:
+ int m_Status; // State: see previous defines (CH_ ...)
+ D_PAD* m_PadStart; // pointer to the starting pad
+ D_PAD* m_PadEnd; // pointer to ending pad
+ int m_Lenght; // length of the line (used in some calculations)
+
+ RATSNEST_ITEM();
+
+ /**
+ * Function GetNet
+ * @return int - the net code.
+ */
+ int GetNet() const
+ {
+ return m_NetCode;
+ }
+
+ void SetNet( int aNetCode )
+ {
+ m_NetCode = aNetCode;
+ }
+
+ bool IsVisible()
+ {
+ return (m_Status & CH_VISIBLE) != 0;
+ }
+
+ bool IsActive()
+ {
+ return (m_Status & CH_ACTIF) != 0;
+ }
+
+ bool IsLocal()
+ {
+ return (m_Status & LOCAL_RATSNEST_ITEM) != 0;
+ }
+
+ /**
+ * Function Draw
+ */
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode,
+ const wxPoint& offset );
+};
+
+
+class NETINFO_MAPPING
+{
+public:
+ NETINFO_MAPPING()
+ {
+ m_board = NULL;
+ }
+
+
+ /**
+ * Function SetBoard
+ * Sets a BOARD object that is used to prepare the net code map.
+ */
+ void SetBoard( const BOARD* aBoard )
+ {
+ m_board = aBoard;
+ Update();
+ }
+
+ /**
+ * Function Update
+ * Prepares a mapping for net codes so they can be saved as consecutive numbers.
+ * To retrieve a mapped net code, use translateNet() function after calling this.
+ */
+ void Update();
+
+ /**
+ * Function Translate
+ * Translates net number according to the map prepared by Update() function. It
+ * allows to have items stored with consecutive net codes.
+ * @param aNetCode is an old net code.
+ * @return Net code that follows the mapping.
+ */
+ int Translate( int aNetCode ) const;
+
+#ifndef SWIG
+ ///> Wrapper class, so you can iterate through NETINFO_ITEM*s, not
+ ///> std::pair<int/wxString, NETINFO_ITEM*>
+ class iterator
+ {
+ public:
+ iterator( std::map<int, int>::const_iterator aIter, const NETINFO_MAPPING* aMapping ) :
+ m_iterator( aIter ), m_mapping( aMapping )
+ {
+ }
+
+ /// pre-increment operator
+ const iterator& operator++()
+ {
+ ++m_iterator;
+
+ return *this;
+ }
+
+ /// post-increment operator
+ iterator operator++( int )
+ {
+ iterator ret = *this;
+ ++m_iterator;
+
+ return ret;
+ }
+
+ NETINFO_ITEM* operator*() const;
+
+ NETINFO_ITEM* operator->() const;
+
+ bool operator!=( const iterator& aOther ) const
+ {
+ return m_iterator != aOther.m_iterator;
+ }
+
+ bool operator==( const iterator& aOther ) const
+ {
+ return m_iterator == aOther.m_iterator;
+ }
+
+ private:
+ std::map<int, int>::const_iterator m_iterator;
+ const NETINFO_MAPPING* m_mapping;
+ };
+
+ /**
+ * Function begin()
+ * Returns iterator to the first entry in the mapping.
+ * NOTE: The entry is a pointer to the original NETINFO_ITEM object, this it contains
+ * not mapped net code.
+ */
+ iterator begin() const
+ {
+ return iterator( m_netMapping.begin(), this );
+ }
+
+ /**
+ * Function end()
+ * Returns iterator to the last entry in the mapping.
+ * NOTE: The entry is a pointer to the original NETINFO_ITEM object, this it contains
+ * not mapped net code.
+ */
+ iterator end() const
+ {
+ return iterator( m_netMapping.end(), this );
+ }
+#endif
+
+ /**
+ * Function GetSize
+ * @return Number of mapped nets (i.e. not empty nets for a given BOARD object).
+ */
+ int GetSize() const
+ {
+ return m_netMapping.size();
+ }
+
+private:
+ ///> Board for which mapping is prepared
+ const BOARD* m_board;
+
+ ///> Map that allows saving net codes with consecutive numbers (for compatibility reasons)
+ std::map<int, int> m_netMapping;
+};
+
+
+/**
+ * Class NETINFO_LIST
+ * is a container class for NETINFO_ITEM elements, which are the nets. That makes
+ * this class a container for the nets.
+ */
+class NETINFO_LIST
+{
+ friend class BOARD;
+
+public:
+ NETINFO_LIST( BOARD* aParent );
+ ~NETINFO_LIST();
+
+ /**
+ * Function GetItem
+ * @param aNetCode = netcode to identify a given NETINFO_ITEM
+ * @return NETINFO_ITEM* - by \a aNetCode, or NULL if not found
+ */
+ NETINFO_ITEM* GetNetItem( int aNetCode ) const
+ {
+ NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode );
+
+ if( result != m_netCodes.end() )
+ return (*result).second;
+
+ return NULL;
+ }
+
+ /**
+ * Function GetItem
+ * @param aNetName = net name to identify a given NETINFO_ITEM
+ * @return NETINFO_ITEM* - by \a aNetName, or NULL if not found
+ */
+ NETINFO_ITEM* GetNetItem( const wxString& aNetName ) const
+ {
+ NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName );
+
+ if( result != m_netNames.end() )
+ return (*result).second;
+
+ return NULL;
+ }
+
+ /**
+ * Function GetNetCount
+ * @return the number of nets ( always >= 1 )
+ * because the first net is the "not connected" net and always exists
+ */
+ unsigned GetNetCount() const { return m_netNames.size(); }
+
+ /**
+ * Function Append
+ * adds \a aNewElement to the end of the list. Negative net code means it is going to be
+ * auto-assigned.
+ */
+ void AppendNet( NETINFO_ITEM* aNewElement );
+
+ /**
+ * Function GetPadCount
+ * @return the number of pads in board
+ */
+ unsigned GetPadCount() const { return m_PadsFullList.size(); }
+
+ /**
+ * Function GetPads
+ * returns a list of all the pads (so long as buildPadsFullList() has
+ * been recently called). Returned list contains non-owning pointers.
+ * @return std::vector<D_PAD*>& - a full list of pads
+ std::vector<D_PAD*>& GetPads()
+ {
+ return m_PadsFullList;
+ }
+ */
+
+ /**
+ * Function GetPad
+ * @return the pad idx from m_PadsFullList
+ */
+ D_PAD* GetPad( unsigned aIdx ) const
+ {
+ if( aIdx < m_PadsFullList.size() )
+ return m_PadsFullList[aIdx];
+ else
+ return NULL;
+ }
+
+ bool DeletePad( D_PAD* aPad )
+ {
+ std::vector<D_PAD*>::iterator it = m_PadsFullList.begin();
+ std::vector<D_PAD*>::iterator end = m_PadsFullList.end();
+
+ for( ; it != end; ++it )
+ {
+ if( *it == aPad )
+ {
+ m_PadsFullList.erase( it );
+ return true;
+ }
+ }
+ return false;
+ }
+
+ ///> Constant that holds the "unconnected net" number (typically 0)
+ ///> all items "connected" to this net are actually not connected items
+ static const int UNCONNECTED;
+
+ ///> Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED
+ ///> (typically -1) when calling SetNetCode od board connected items
+ static const int FORCE_ORPHANED;
+
+ ///> NETINFO_ITEM meaning that there was no net assigned for an item, as there was no
+ ///> board storing net list available.
+ static NETINFO_ITEM ORPHANED;
+
+#if defined(DEBUG)
+ void Show() const;
+#endif
+
+ typedef boost::unordered_map<const wxString, NETINFO_ITEM*, WXSTRING_HASH> NETNAMES_MAP;
+ typedef boost::unordered_map<const int, NETINFO_ITEM*> NETCODES_MAP;
+
+#ifndef SWIG
+ ///> Wrapper class, so you can iterate through NETINFO_ITEM*s, not
+ ///> std::pair<int/wxString, NETINFO_ITEM*>
+ class iterator
+ {
+ public:
+ iterator( NETNAMES_MAP::const_iterator aIter ) : m_iterator( aIter )
+ {
+ }
+
+ /// pre-increment operator
+ const iterator& operator++()
+ {
+ ++m_iterator;
+
+ return *this;
+ }
+
+ /// post-increment operator
+ iterator operator++( int )
+ {
+ iterator ret = *this;
+ ++m_iterator;
+
+ return ret;
+ }
+
+ NETINFO_ITEM* operator*() const
+ {
+ return m_iterator->second;
+ }
+
+ NETINFO_ITEM* operator->() const
+ {
+ return m_iterator->second;
+ }
+
+ bool operator!=( const iterator& aOther ) const
+ {
+ return m_iterator != aOther.m_iterator;
+ }
+
+ bool operator==( const iterator& aOther ) const
+ {
+ return m_iterator == aOther.m_iterator;
+ }
+
+ private:
+ NETNAMES_MAP::const_iterator m_iterator;
+ };
+
+ iterator begin() const
+ {
+ return iterator( m_netNames.begin() );
+ }
+
+ iterator end() const
+ {
+ return iterator( m_netNames.end() );
+ }
+#endif
+
+private:
+ /**
+ * Function clear
+ * deletes the list of nets (and free memory)
+ */
+ void clear();
+
+ /**
+ * Function buildListOfNets
+ * builds or rebuilds the list of NETINFO_ITEMs
+ * The list is sorted by names.
+ */
+ void buildListOfNets();
+
+ /**
+ * Function buildPadsFullList
+ * creates the pad list, and initializes:
+ * m_Pads (list of pads)
+ * set m_Status_Pcb = LISTE_PAD_OK;
+ * and clear for all pads in list the m_SubRatsnest member;
+ * clear m_Pcb->m_FullRatsnest
+ */
+ void buildPadsFullList();
+
+ /**
+ * Function getFreeNetCode
+ * returns the first available net code that is not used by any other net.
+ */
+ int getFreeNetCode();
+
+ BOARD* m_Parent;
+
+ NETNAMES_MAP m_netNames; ///< map for a fast look up by net names
+ NETCODES_MAP m_netCodes; ///< map for a fast look up by net codes
+
+ std::vector<D_PAD*> m_PadsFullList; ///< contains all pads, sorted by pad's netname.
+ ///< can be used in ratsnest calculations.
+
+ int m_newNetCode; ///< possible value for new net code assignment
+};
+
+
+/**
+ * Class NETINFO_ITEM
+ * handles the data for a net
+ */
+class NETINFO_ITEM
+{
+ friend class NETINFO_LIST;
+
+private:
+ int m_NetCode; ///< A number equivalent to the net name.
+ ///< Used for fast comparisons in ratsnest and DRC computations.
+
+ wxString m_Netname; ///< Full net name like /mysheet/mysubsheet/vout used by Eeschema
+
+ wxString m_ShortNetname; ///< short net name, like vout from /mysheet/mysubsheet/vout
+
+ wxString m_NetClassName; // Net Class name. if void this is equivalent
+ // to "default" (the first
+ // item of the net classes list
+ NETCLASSPTR m_NetClass;
+
+ BOARD_ITEM* m_parent; ///< The parent board item object the net belongs to.
+
+public:
+ std::vector<D_PAD*> m_PadInNetList; ///< List of pads connected to this net
+
+ unsigned m_RatsnestStartIdx; /* Starting point of ratsnests of this
+ * net (included) in a general buffer of
+ * ratsnest (a vector<RATSNEST_ITEM*>
+ * buffer) */
+
+ unsigned m_RatsnestEndIdx; // Ending point of ratsnests of this net
+ // (excluded) in this buffer
+
+ NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName = wxEmptyString, int aNetCode = -1 );
+ ~NETINFO_ITEM();
+
+ /**
+ * Function SetClass
+ * sets \a aNetclass into this NET
+ */
+ void SetClass( NETCLASSPTR aNetClass )
+ {
+ m_NetClass = aNetClass;
+
+ if( aNetClass )
+ m_NetClassName = aNetClass->GetName();
+ else
+ m_NetClassName = NETCLASS::Default;
+ }
+
+ NETCLASSPTR GetNetClass()
+ {
+ return m_NetClass;
+ }
+
+ /**
+ * Function GetClassName
+ * returns the class name
+ */
+ const wxString& GetClassName() const
+ {
+ return m_NetClassName;
+ }
+
+#if 1
+
+ /**
+ * Function GetTrackWidth
+ * returns the width of tracks used to route this net.
+ */
+ int GetTrackWidth()
+ {
+ wxASSERT( m_NetClass );
+ return m_NetClass->GetTrackWidth();
+ }
+
+ /**
+ * Function GetViaSize
+ * returns the size of vias used to route this net
+ */
+ int GetViaSize()
+ {
+ wxASSERT( m_NetClass );
+ return m_NetClass->GetViaDiameter();
+ }
+
+ /**
+ * Function GetMicroViaSize
+ * returns the size of vias used to route this net
+ */
+ int GetMicroViaSize()
+ {
+ wxASSERT( m_NetClass );
+ return m_NetClass->GetuViaDiameter();
+ }
+
+ /**
+ * Function GetViaDrillSize
+ * returns the size of via drills used to route this net
+ */
+ int GetViaDrillSize()
+ {
+ wxASSERT( m_NetClass );
+ return m_NetClass->GetViaDrill();
+ }
+
+ /**
+ * Function GetViaDrillSize
+ * returns the size of via drills used to route this net
+ */
+ int GetMicroViaDrillSize()
+ {
+ wxASSERT( m_NetClass );
+ return m_NetClass->GetuViaDrill();
+ }
+
+
+#if 0
+
+ /**
+ * Function GetViaMinSize
+ * returns the Minimum value for via sizes (used in DRC)
+ */
+ int GetViaMinSize()
+ {
+ wxASSERT( m_NetClass );
+ return m_NetClass->GetViaMinSize();
+ }
+
+#endif
+
+ /**
+ * Function GetClearance
+ * returns the clearance when routing near aBoardItem
+ */
+ int GetClearance( BOARD_ITEM* aBoardItem )
+ {
+ wxASSERT( m_NetClass );
+ return m_NetClass->GetClearance();
+ }
+
+#endif
+
+ /**
+ * Function Draw
+ * @todo we actually could show a NET, simply show all the tracks and
+ * a pads or net name on pad and vias
+ */
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode,
+ const wxPoint& offset );
+
+ /**
+ * Function GetNet
+ * @return int - the netcode
+ */
+ int GetNet() const { return m_NetCode; }
+
+ /**
+ * Function GetNodesCount
+ * @return int - number of nodes in the net
+ */
+ int GetNodesCount() const { return m_PadInNetList.size(); }
+
+ /**
+ * Function GetNetname
+ * @return const wxString&, a reference to the full netname
+ */
+ const wxString& GetNetname() const { return m_Netname; }
+
+ /**
+ * Function GetShortNetname
+ * @return const wxString &, a reference to the short netname
+ */
+ const wxString& GetShortNetname() const { return m_ShortNetname; }
+
+ /**
+ * Function GetMsgPanelInfo
+ * returns the information about the #NETINFO_ITEM in \a aList to display in the
+ * message panel.
+ *
+ * @param aList is the list in which to place the status information.
+ */
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ /**
+ * Function Clear
+ * sets all fields to their defaults values.
+ */
+ void Clear()
+ {
+ m_PadInNetList.clear();
+
+ m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a
+ // general buffer of ratsnest
+ m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net
+
+ SetClass( NETCLASSPTR() );
+ }
+};
+
+
+/***********************************************************/
+/* Description of a trace point for monitoring connections */
+/***********************************************************/
+#define START_ON_PAD 0x10
+#define END_ON_PAD 0x20
+#define START_ON_TRACK 0x40
+#define END_ON_TRACK 0x80
+
+
+/* Status bit (OR'ed bits) for class BOARD member .m_Status_Pcb */
+enum StatusPcbFlags {
+ LISTE_PAD_OK = 1, /* Pad list is Ok */
+ LISTE_RATSNEST_ITEM_OK = 2, /* General Ratsnest is Ok */
+ RATSNEST_ITEM_LOCAL_OK = 4, /* current MODULE ratsnest is Ok */
+ CONNEXION_OK = 8, /* List of connections exists. */
+ NET_CODES_OK = 0x10, /* Bit indicating that Netcode is OK,
+ * do not change net name. */
+ DO_NOT_SHOW_GENERAL_RASTNEST = 0x20 /* Do not display the general
+ * ratsnest (used in module moves) */
+};
+
+
+#endif // __CLASSES_NETINFO__
diff --git a/pcbnew/class_netinfo_item.cpp b/pcbnew/class_netinfo_item.cpp
new file mode 100644
index 0000000..1f1f267
--- /dev/null
+++ b/pcbnew/class_netinfo_item.cpp
@@ -0,0 +1,181 @@
+/**
+ * @brief NETINFO_ITEM class, to handle info on nets: netnames, net constraints
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <wxBasePcbFrame.h>
+#include <common.h>
+#include <kicad_string.h>
+#include <pcbnew.h>
+#include <colors_selection.h>
+#include <richio.h>
+#include <macros.h>
+#include <msgpanel.h>
+#include <base_units.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+
+
+/*********************************************************/
+/* class NETINFO_ITEM: handle data relative to a given net */
+/*********************************************************/
+
+NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName, int aNetCode ) :
+ m_NetCode( aNetCode ), m_Netname( aNetName ), m_ShortNetname( m_Netname.AfterLast( '/' ) )
+{
+ m_parent = aParent;
+ m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a
+ // general buffer of ratsnest
+ m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net
+
+ m_NetClassName = NETCLASS::Default;
+}
+
+
+NETINFO_ITEM::~NETINFO_ITEM()
+{
+ // m_NetClass is not owned by me.
+}
+
+
+/**
+ * Function Draw (TODO)
+ */
+void NETINFO_ITEM::Draw( EDA_DRAW_PANEL* panel,
+ wxDC* DC,
+ GR_DRAWMODE aDrawMode,
+ const wxPoint& aOffset )
+{
+}
+
+
+void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString txt;
+ double lengthnet = 0.0; // This is the lenght of tracks on pcb
+ double lengthPadToDie = 0.0; // this is the lenght of internal ICs connections
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Net Name" ), GetNetname(), RED ) );
+
+ txt.Printf( wxT( "%d" ), GetNet() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Net Code" ), txt, RED ) );
+
+ // Warning: for netcode == NETINFO_LIST::ORPHANED, the parent or the board
+ // can be NULL
+ BOARD * board = m_parent ? m_parent->GetBoard() : NULL;
+
+ if( board == NULL )
+ return;
+
+ int count = 0;
+ for( MODULE* module = board->m_Modules; module != NULL; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad != 0; pad = pad->Next() )
+ {
+ if( pad->GetNetCode() == GetNet() )
+ {
+ count++;
+ lengthPadToDie += pad->GetPadToDieLength();
+ }
+ }
+ }
+
+ txt.Printf( wxT( "%d" ), count );
+ aList.push_back( MSG_PANEL_ITEM( _( "Pads" ), txt, DARKGREEN ) );
+
+ count = 0;
+
+ for( const TRACK *track = board->m_Track; track != NULL; track = track->Next() )
+ {
+ if( track->Type() == PCB_VIA_T )
+ {
+ if( track->GetNetCode() == GetNet() )
+ count++;
+ }
+
+ if( track->Type() == PCB_TRACE_T )
+ {
+ if( track->GetNetCode() == GetNet() )
+ lengthnet += track->GetLength();
+ }
+ }
+
+ txt.Printf( wxT( "%d" ), count );
+ aList.push_back( MSG_PANEL_ITEM( _( "Vias" ), txt, BLUE ) );
+
+ // Displays the full net length (tracks on pcb + internal ICs connections ):
+ txt = ::LengthDoubleToString( lengthnet + lengthPadToDie );
+ aList.push_back( MSG_PANEL_ITEM( _( "Net Length" ), txt, RED ) );
+
+ // Displays the net length of tracks only:
+ txt = ::LengthDoubleToString( lengthnet );
+ aList.push_back( MSG_PANEL_ITEM( _( "On Board" ), txt, RED ) );
+
+ // Displays the net length of internal ICs connections (wires inside ICs):
+ txt = ::LengthDoubleToString( lengthPadToDie );
+ aList.push_back( MSG_PANEL_ITEM( _( "In Package" ), txt, RED ) );
+}
+
+
+/***********************/
+/* class RATSNEST_ITEM */
+/***********************/
+
+RATSNEST_ITEM::RATSNEST_ITEM()
+{
+ m_NetCode = 0; // netcode ( = 1.. n , 0 is the value used for not
+ // connected items)
+ m_Status = 0; // state
+ m_PadStart = NULL; // pointer to the starting pad
+ m_PadEnd = NULL; // pointer to ending pad
+ m_Lenght = 0; // length of the line (temporary used in some
+ // calculations)
+}
+
+
+/**
+ * Function Draw
+ * Draws a line (a ratsnest) from the starting pad to the ending pad
+ */
+void RATSNEST_ITEM::Draw( EDA_DRAW_PANEL* panel,
+ wxDC* DC,
+ GR_DRAWMODE aDrawMode,
+ const wxPoint& aOffset )
+{
+ GRSetDrawMode( DC, aDrawMode );
+
+ EDA_COLOR_T color = g_ColorsSettings.GetItemColor(RATSNEST_VISIBLE);
+
+ GRLine( panel->GetClipBox(), DC,
+ m_PadStart->GetPosition() - aOffset,
+ m_PadEnd->GetPosition() - aOffset, 0, color );
+}
diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp
new file mode 100644
index 0000000..74b11bf
--- /dev/null
+++ b/pcbnew/class_netinfolist.cpp
@@ -0,0 +1,300 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_netinfolist.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <macros.h>
+#include <pcbnew.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_pad.h>
+#include <class_track.h>
+#include <class_zone.h>
+#include <class_netinfo.h>
+
+
+// Constructor and destructor
+NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) : m_Parent( aParent )
+{
+ // Make sure that the unconnected net has number 0
+ AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) );
+
+ m_newNetCode = 0;
+}
+
+
+NETINFO_LIST::~NETINFO_LIST()
+{
+ clear();
+}
+
+
+void NETINFO_LIST::clear()
+{
+ NETNAMES_MAP::iterator it, itEnd;
+ for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
+ delete it->second;
+
+ m_PadsFullList.clear();
+ m_netNames.clear();
+ m_netCodes.clear();
+ m_newNetCode = 0;
+}
+
+
+void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement )
+{
+ // if there is a net with such name then just assign the correct number
+ NETINFO_ITEM* sameName = GetNetItem( aNewElement->GetNetname() );
+
+ if( sameName != NULL )
+ {
+ aNewElement->m_NetCode = sameName->GetNet();
+
+ return;
+ }
+ // be sure that net codes are consecutive
+ // negative net code means that it has to be auto assigned
+ else if( ( aNewElement->m_NetCode != (int) m_netCodes.size() ) || ( aNewElement->m_NetCode < 0 ) )
+ {
+ aNewElement->m_NetCode = getFreeNetCode();
+ }
+
+ // net names & codes are supposed to be unique
+ assert( GetNetItem( aNewElement->GetNetname() ) == NULL );
+ assert( GetNetItem( aNewElement->GetNet() ) == NULL );
+
+ // add an entry for fast look up by a net name using a map
+ m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) );
+ m_netCodes.insert( std::make_pair( aNewElement->GetNet(), aNewElement ) );
+}
+
+
+/* sort function, to sort pad list by netnames
+ * this is a case sensitive sort.
+ * DO NOT change it because NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname )
+ * when search a net by its net name does a binary search
+ * and expects to have a nets list sorted by an alphabetic case sensitive sort
+ */
+
+static bool padlistSortByNetnames( const D_PAD* a, const D_PAD* b )
+{
+ return ( a->GetNetname().Cmp( b->GetNetname() ) ) < 0;
+}
+
+
+/**
+ * Compute and update the net_codes for PADS et and equipots (.m_NetCode member)
+ * net_codes are >= 1 (net_code = 0 means not connected)
+ * Update the net buffer
+ * Must be called after editing pads (netname, or deleting) or after read a netlist
+ * set to 1 flag NET_CODE_OK of m_Pcb->m_Status_Pcb;
+ * m_Pcb->m_NbNodes and m_Pcb->m_NbNets are updated
+ * Be aware NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname )
+ * when search a net by its net name does a binary search
+ * and expects to have a nets list sorted by an alphabetic case sensitive sort
+ * So do not change Build_Pads_Full_List() which build a sorted list of pads
+ */
+void NETINFO_LIST::buildListOfNets()
+{
+ D_PAD* pad;
+ int nodes_count = 0;
+
+ // Build the PAD list, sorted by net
+ buildPadsFullList();
+
+ // Restore the initial state of NETINFO_ITEMs
+ for( NETINFO_LIST::iterator net( begin() ), netEnd( end() ); net != netEnd; ++net )
+ net->Clear();
+
+ // Assign pads to appropriate NETINFO_ITEMs
+ for( unsigned ii = 0; ii < m_PadsFullList.size(); ii++ )
+ {
+ pad = m_PadsFullList[ii];
+
+ if( pad->GetNetCode() == NETINFO_LIST::UNCONNECTED ) // pad not connected
+ continue;
+
+ // Add pad to the appropriate list of pads
+ NETINFO_ITEM* net = pad->GetNet();
+
+ // it should not be possible for BOARD_CONNECTED_ITEM to return NULL as a result of GetNet()
+ wxASSERT( net );
+
+ if( net )
+ net->m_PadInNetList.push_back( pad );
+
+ ++nodes_count;
+ }
+
+ m_Parent->SetNodeCount( nodes_count );
+
+ m_Parent->SynchronizeNetsAndNetClasses( );
+
+ m_Parent->m_Status_Pcb |= NET_CODES_OK;
+
+ m_Parent->SetAreasNetCodesFromNetNames();
+}
+
+
+#if defined(DEBUG)
+void NETINFO_LIST::Show() const
+{
+ int i = 0;
+ NETNAMES_MAP::const_iterator it, itEnd;
+ for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
+ {
+ printf( "[%d]: netcode:%d netname:<%s>\n",
+ i++, it->second->GetNet(),
+ TO_UTF8( it->second->GetNetname() ) );
+ }
+}
+#endif
+
+
+void NETINFO_LIST::buildPadsFullList()
+{
+ /*
+ * initialize:
+ * m_Pads (list of pads)
+ * set m_Status_Pcb = LISTE_PAD_OK;
+ * also clear m_Pcb->m_FullRatsnest that could have bad data
+ * (m_Pcb->m_FullRatsnest uses pointer to pads)
+ * Be aware NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname )
+ * when search a net by its net name does a binary search
+ * and expects to have a nets list sorted by an alphabetic case sensitive sort
+ * So do not change the sort function used here
+ */
+
+ if( m_Parent->m_Status_Pcb & LISTE_PAD_OK )
+ return;
+
+ // empty the old list
+ m_PadsFullList.clear();
+ m_Parent->m_FullRatsnest.clear();
+
+ // Clear variables used in ratsnest computation
+ for( MODULE* module = m_Parent->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ m_PadsFullList.push_back( pad );
+
+ pad->SetSubRatsnest( 0 );
+ pad->SetParent( module );
+ }
+ }
+
+ // Sort pad list per net
+ sort( m_PadsFullList.begin(), m_PadsFullList.end(), padlistSortByNetnames );
+
+ m_Parent->m_Status_Pcb = LISTE_PAD_OK;
+}
+
+
+int NETINFO_LIST::getFreeNetCode()
+{
+ do {
+ if( m_newNetCode < 0 )
+ m_newNetCode = 0;
+ } while( m_netCodes.count( ++m_newNetCode ) != 0 );
+
+ return m_newNetCode;
+}
+
+
+int NETINFO_MAPPING::Translate( int aNetCode ) const
+{
+ std::map<int, int>::const_iterator value = m_netMapping.find( aNetCode );
+
+ if( value != m_netMapping.end() )
+ return value->second;
+
+ // There was no entry for the given net code
+ return aNetCode;
+}
+
+
+void NETINFO_MAPPING::Update()
+{
+ // Collect all the used nets
+ std::set<int> nets;
+
+ // Be sure that the unconnected gets 0 and is mapped as 0
+ nets.insert( 0 );
+
+ // Zones
+ for( int i = 0; i < m_board->GetAreaCount(); ++i )
+ nets.insert( m_board->GetArea( i )->GetNetCode() );
+
+ // Tracks
+ for( TRACK* track = m_board->m_Track; track; track = track->Next() )
+ nets.insert( track->GetNetCode() );
+
+ // Modules/pads
+ for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
+ {
+ nets.insert( pad->GetNetCode() );
+ }
+ }
+
+ // Segzones
+ for( SEGZONE* zone = m_board->m_Zone; zone; zone = zone->Next() )
+ nets.insert( zone->GetNetCode() );
+
+ // Prepare the new mapping
+ m_netMapping.clear();
+
+ // Now the nets variable stores all the used net codes (not only for pads) and we are ready to
+ // assign new consecutive net numbers
+ int newNetCode = 0;
+ for( std::set<int>::const_iterator it = nets.begin(), itEnd = nets.end(); it != itEnd; ++it )
+ m_netMapping[*it] = newNetCode++;
+}
+
+
+NETINFO_ITEM* NETINFO_MAPPING::iterator::operator*() const
+{
+ return m_mapping->m_board->FindNet( m_iterator->first );
+}
+
+
+NETINFO_ITEM* NETINFO_MAPPING::iterator::operator->() const
+{
+ return m_mapping->m_board->FindNet( m_iterator->first );
+}
+
+
+const int NETINFO_LIST::UNCONNECTED = 0;
+const int NETINFO_LIST::FORCE_ORPHANED = -1;
+
+NETINFO_ITEM NETINFO_LIST::ORPHANED = NETINFO_ITEM( NULL, wxEmptyString, NETINFO_LIST::UNCONNECTED );
diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp
new file mode 100644
index 0000000..60b1f77
--- /dev/null
+++ b/pcbnew/class_pad.cpp
@@ -0,0 +1,994 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_pad.cpp
+ * D_PAD class implementation.
+ */
+
+#include <fctsys.h>
+#include <PolyLine.h>
+#include <common.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <trigo.h>
+#include <richio.h>
+#include <wxstruct.h>
+#include <macros.h>
+#include <msgpanel.h>
+#include <base_units.h>
+
+#include <pcbnew.h>
+#include <pcbnew_id.h> // ID_TRACK_BUTT
+
+#include <class_board.h>
+#include <class_module.h>
+#include <polygon_test_point_inside.h>
+#include <convert_from_iu.h>
+#include <boost/foreach.hpp>
+
+
+int D_PAD::m_PadSketchModePenSize = 0; // Pen size used to draw pads in sketch mode
+
+
+D_PAD::D_PAD( MODULE* parent ) :
+ BOARD_CONNECTED_ITEM( parent, PCB_PAD_T )
+{
+ m_NumPadName = 0;
+ m_Size.x = m_Size.y = DMils2iu( 600 ); // Default pad size 60 mils.
+ m_Drill.x = m_Drill.y = DMils2iu( 300 ); // Default drill size 30 mils.
+ m_Orient = 0; // Pad rotation in 1/10 degrees.
+ m_LengthPadToDie = 0;
+
+ if( m_Parent && m_Parent->Type() == PCB_MODULE_T )
+ {
+ m_Pos = GetParent()->GetPosition();
+ }
+
+ SetShape( PAD_SHAPE_CIRCLE ); // Default pad shape is PAD_CIRCLE.
+ SetDrillShape( PAD_DRILL_SHAPE_CIRCLE ); // Default pad drill shape is a circle.
+ m_Attribute = PAD_ATTRIB_STANDARD; // Default pad type is NORMAL (thru hole)
+ m_LocalClearance = 0;
+ m_LocalSolderMaskMargin = 0;
+ m_LocalSolderPasteMargin = 0;
+ m_LocalSolderPasteMarginRatio = 0.0;
+ m_ZoneConnection = PAD_ZONE_CONN_INHERITED; // Use parent setting by default
+ m_ThermalWidth = 0; // Use parent setting by default
+ m_ThermalGap = 0; // Use parent setting by default
+
+ // Set layers mask to default for a standard thru hole pad.
+ m_layerMask = StandardMask();
+
+ SetSubRatsnest( 0 ); // used in ratsnest calculations
+
+ m_boundingRadius = -1;
+}
+
+
+LSET D_PAD::StandardMask()
+{
+ static LSET saved = LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask );
+ return saved;
+}
+
+
+LSET D_PAD::SMDMask()
+{
+ static LSET saved( 3, F_Cu, F_Paste, F_Mask );
+ return saved;
+}
+
+
+LSET D_PAD::ConnSMDMask()
+{
+ static LSET saved( 2, F_Cu, F_Mask );
+ return saved;
+}
+
+
+LSET D_PAD::UnplatedHoleMask()
+{
+ // was #define PAD_ATTRIB_HOLE_NOT_PLATED_DEFAULT_LAYERS ALL_CU_LAYERS |
+ // SILKSCREEN_LAYER_FRONT | SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT
+ static LSET saved = LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask );
+ return saved;
+}
+
+
+int D_PAD::boundingRadius() const
+{
+ int x, y;
+ int radius;
+
+ switch( GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+ radius = m_Size.x / 2;
+ break;
+
+ case PAD_SHAPE_OVAL:
+ radius = std::max( m_Size.x, m_Size.y ) / 2;
+ break;
+
+ case PAD_SHAPE_RECT:
+ radius = 1 + KiROUND( EuclideanNorm( m_Size ) / 2 );
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ x = m_Size.x + std::abs( m_DeltaSize.y ); // Remember: m_DeltaSize.y is the m_Size.x change
+ y = m_Size.y + std::abs( m_DeltaSize.x ); // Remember: m_DeltaSize.x is the m_Size.y change
+ radius = 1 + KiROUND( hypot( x, y ) / 2 );
+ break;
+
+ default:
+ radius = 0;
+ }
+
+ return radius;
+}
+
+
+const EDA_RECT D_PAD::GetBoundingBox() const
+{
+ EDA_RECT area;
+ wxPoint quadrant1, quadrant2, quadrant3, quadrant4;
+ int x, y, dx, dy;
+
+ switch( GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+ area.SetOrigin( m_Pos );
+ area.Inflate( m_Size.x / 2 );
+ break;
+
+ case PAD_SHAPE_OVAL:
+ //Use the maximal two most distant points and track their rotation
+ // (utilise symmetry to avoid four points)
+ quadrant1.x = m_Size.x/2;
+ quadrant1.y = 0;
+ quadrant2.x = 0;
+ quadrant2.y = m_Size.y/2;
+
+ RotatePoint( &quadrant1, m_Orient );
+ RotatePoint( &quadrant2, m_Orient );
+ dx = std::max( std::abs( quadrant1.x ) , std::abs( quadrant2.x ) );
+ dy = std::max( std::abs( quadrant1.y ) , std::abs( quadrant2.y ) );
+ area.SetOrigin( m_Pos.x-dx, m_Pos.y-dy );
+ area.SetSize( 2*dx, 2*dy );
+ break;
+
+ case PAD_SHAPE_RECT:
+ //Use two corners and track their rotation
+ // (utilise symmetry to avoid four points)
+ quadrant1.x = m_Size.x/2;
+ quadrant1.y = m_Size.y/2;
+ quadrant2.x = -m_Size.x/2;
+ quadrant2.y = m_Size.y/2;
+
+ RotatePoint( &quadrant1, m_Orient );
+ RotatePoint( &quadrant2, m_Orient );
+ dx = std::max( std::abs( quadrant1.x ) , std::abs( quadrant2.x ) );
+ dy = std::max( std::abs( quadrant1.y ) , std::abs( quadrant2.y ) );
+ area.SetOrigin( m_Pos.x-dx, m_Pos.y-dy );
+ area.SetSize( 2*dx, 2*dy );
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ //Use the four corners and track their rotation
+ // (Trapezoids will not be symmetric)
+ quadrant1.x = (m_Size.x + m_DeltaSize.y)/2;
+ quadrant1.y = (m_Size.y - m_DeltaSize.x)/2;
+ quadrant2.x = -(m_Size.x + m_DeltaSize.y)/2;
+ quadrant2.y = (m_Size.y + m_DeltaSize.x)/2;
+ quadrant3.x = -(m_Size.x - m_DeltaSize.y)/2;
+ quadrant3.y = -(m_Size.y + m_DeltaSize.x)/2;
+ quadrant4.x = (m_Size.x - m_DeltaSize.y)/2;
+ quadrant4.y = -(m_Size.y - m_DeltaSize.x)/2;
+
+ RotatePoint( &quadrant1, m_Orient );
+ RotatePoint( &quadrant2, m_Orient );
+ RotatePoint( &quadrant3, m_Orient );
+ RotatePoint( &quadrant4, m_Orient );
+
+ x = std::min( quadrant1.x, std::min( quadrant2.x, std::min( quadrant3.x, quadrant4.x) ) );
+ y = std::min( quadrant1.y, std::min( quadrant2.y, std::min( quadrant3.y, quadrant4.y) ) );
+ dx = std::max( quadrant1.x, std::max( quadrant2.x, std::max( quadrant3.x, quadrant4.x) ) );
+ dy = std::max( quadrant1.y, std::max( quadrant2.y, std::max( quadrant3.y, quadrant4.y) ) );
+ area.SetOrigin( m_Pos.x+x, m_Pos.y+y );
+ area.SetSize( dx-x, dy-y );
+ break;
+
+ default:
+ break;
+ }
+
+ return area;
+}
+
+
+void D_PAD::SetDrawCoord()
+{
+ MODULE* module = (MODULE*) m_Parent;
+
+ m_Pos = m_Pos0;
+
+ if( module == NULL )
+ return;
+
+ double angle = module->GetOrientation();
+
+ RotatePoint( &m_Pos.x, &m_Pos.y, angle );
+ m_Pos += module->GetPosition();
+}
+
+
+void D_PAD::SetLocalCoord()
+{
+ MODULE* module = (MODULE*) m_Parent;
+
+ if( module == NULL )
+ {
+ m_Pos0 = m_Pos;
+ return;
+ }
+
+ m_Pos0 = m_Pos - module->GetPosition();
+ RotatePoint( &m_Pos0.x, &m_Pos0.y, -module->GetOrientation() );
+}
+
+
+void D_PAD::SetAttribute( PAD_ATTR_T aAttribute )
+{
+ m_Attribute = aAttribute;
+
+ if( aAttribute == PAD_ATTRIB_SMD )
+ m_Drill = wxSize( 0, 0 );
+}
+
+
+void D_PAD::SetOrientation( double aAngle )
+{
+ NORMALIZE_ANGLE_POS( aAngle );
+ m_Orient = aAngle;
+}
+
+
+void D_PAD::Flip( const wxPoint& aCentre )
+{
+ int y = GetPosition().y - aCentre.y;
+
+ y = -y; // invert about x axis.
+
+ y += aCentre.y;
+
+ SetY( y );
+
+ m_Pos0.y = -m_Pos0.y;
+ m_Offset.y = -m_Offset.y;
+ m_DeltaSize.y = -m_DeltaSize.y;
+
+ SetOrientation( -GetOrientation() );
+
+ // flip pads layers
+ // PADS items are currently on all copper layers, or
+ // currently, only on Front or Back layers.
+ // So the copper layers count is not taken in account
+ SetLayerSet( FlipLayerMask( m_layerMask ) );
+
+ // m_boundingRadius = -1; the shape has not been changed
+}
+
+
+void D_PAD::AppendConfigs( PARAM_CFG_ARRAY* aResult )
+{
+ // Parameters stored in config are only significant parameters
+ // for a template.
+ // So not all parameters are stored, just few.
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadDrill" ),
+ &m_Drill.x,
+ Millimeter2iu( 0.6 ),
+ Millimeter2iu( 0.1 ), Millimeter2iu( 10.0 ),
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadDrillOvalY" ),
+ &m_Drill.y,
+ Millimeter2iu( 0.6 ),
+ Millimeter2iu( 0.1 ), Millimeter2iu( 10.0 ),
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadSizeH" ),
+ &m_Size.x,
+ Millimeter2iu( 1.4 ),
+ Millimeter2iu( 0.1 ), Millimeter2iu( 20.0 ),
+ NULL, MM_PER_IU ) );
+
+ aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadSizeV" ),
+ &m_Size.y,
+ Millimeter2iu( 1.4 ),
+ Millimeter2iu( 0.1 ), Millimeter2iu( 20.0 ),
+ NULL, MM_PER_IU ) );
+}
+
+
+// Returns the position of the pad.
+const wxPoint D_PAD::ShapePos() const
+{
+ if( m_Offset.x == 0 && m_Offset.y == 0 )
+ return m_Pos;
+
+ wxPoint loc_offset = m_Offset;
+
+ RotatePoint( &loc_offset, m_Orient );
+
+ wxPoint shape_pos = m_Pos + loc_offset;
+
+ return shape_pos;
+}
+
+
+const wxString D_PAD::GetPadName() const
+{
+ wxString name;
+
+ StringPadName( name );
+ return name;
+}
+
+
+void D_PAD::StringPadName( wxString& text ) const
+{
+ text.Empty();
+
+ for( int ii = 0; ii < PADNAMEZ && m_Padname[ii]; ii++ )
+ {
+ // m_Padname is 8 bit KiCad font junk, do not sign extend
+ text.Append( (unsigned char) m_Padname[ii] );
+ }
+}
+
+
+// Change pad name
+void D_PAD::SetPadName( const wxString& name )
+{
+ int ii, len;
+
+ len = name.Length();
+
+ if( len > PADNAMEZ )
+ len = PADNAMEZ;
+
+ // m_Padname[] is not UTF8, it is an 8 bit character that matches the KiCad font,
+ // so only copy the lower 8 bits of each character.
+
+ for( ii = 0; ii < len; ii++ )
+ m_Padname[ii] = (char) name.GetChar( ii );
+
+ for( ii = len; ii < PADNAMEZ; ii++ )
+ m_Padname[ii] = '\0';
+}
+
+
+bool D_PAD::IncrementItemReference()
+{
+ // Take the next available pad number
+ return IncrementPadName( true, true );
+}
+
+
+bool D_PAD::IncrementPadName( bool aSkipUnconnectable, bool aFillSequenceGaps )
+{
+ bool skip = aSkipUnconnectable && ( GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED );
+
+ if( !skip )
+ SetPadName( GetParent()->GetNextPadName( aFillSequenceGaps ) );
+
+ return !skip;
+}
+
+
+void D_PAD::Copy( D_PAD* source )
+{
+ if( source == NULL )
+ return;
+
+ m_Pos = source->m_Pos;
+ m_layerMask = source->m_layerMask;
+
+ m_NumPadName = source->m_NumPadName;
+ m_netinfo = source->m_netinfo;
+ m_Drill = source->m_Drill;
+ m_drillShape = source->m_drillShape;
+ m_Offset = source->m_Offset;
+ m_Size = source->m_Size;
+ m_DeltaSize = source->m_DeltaSize;
+ m_Pos0 = source->m_Pos0;
+ m_boundingRadius = source->m_boundingRadius;
+ m_padShape = source->m_padShape;
+ m_Attribute = source->m_Attribute;
+ m_Orient = source->m_Orient;
+ m_LengthPadToDie = source->m_LengthPadToDie;
+ m_LocalClearance = source->m_LocalClearance;
+ m_LocalSolderMaskMargin = source->m_LocalSolderMaskMargin;
+ m_LocalSolderPasteMargin = source->m_LocalSolderPasteMargin;
+ m_LocalSolderPasteMarginRatio = source->m_LocalSolderPasteMarginRatio;
+ m_ZoneConnection = source->m_ZoneConnection;
+ m_ThermalWidth = source->m_ThermalWidth;
+ m_ThermalGap = source->m_ThermalGap;
+
+ SetSubRatsnest( 0 );
+ SetSubNet( 0 );
+}
+
+
+void D_PAD::CopyNetlistSettings( D_PAD* aPad, bool aCopyLocalSettings )
+{
+ // Don't do anything foolish like trying to copy to yourself.
+ wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) );
+
+ aPad->SetNetCode( GetNetCode() );
+
+ if( aCopyLocalSettings )
+ {
+ aPad->SetLocalClearance( m_LocalClearance );
+ aPad->SetLocalSolderMaskMargin( m_LocalSolderMaskMargin );
+ aPad->SetLocalSolderPasteMargin( m_LocalSolderPasteMargin );
+ aPad->SetLocalSolderPasteMarginRatio( m_LocalSolderPasteMarginRatio );
+ aPad->SetZoneConnection( m_ZoneConnection );
+ aPad->SetThermalWidth( m_ThermalWidth );
+ aPad->SetThermalGap( m_ThermalGap );
+ }
+}
+
+
+int D_PAD::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
+{
+ // A pad can have specific clearance parameters that
+ // overrides its NETCLASS clearance value
+ int clearance = m_LocalClearance;
+
+ if( clearance == 0 )
+ {
+ // If local clearance is 0, use the parent footprint clearance value
+ if( GetParent() && GetParent()->GetLocalClearance() )
+ clearance = GetParent()->GetLocalClearance();
+ }
+
+ if( clearance == 0 ) // If the parent footprint clearance value = 0, use NETCLASS value
+ return BOARD_CONNECTED_ITEM::GetClearance( aItem );
+
+ // We have a specific clearance.
+ // if aItem, return the biggest clearance
+ if( aItem )
+ {
+ int hisClearance = aItem->GetClearance();
+ return std::max( hisClearance, clearance );
+ }
+
+ // Return the specific clearance.
+ return clearance;
+}
+
+
+// Mask margins handling:
+
+int D_PAD::GetSolderMaskMargin() const
+{
+ int margin = m_LocalSolderMaskMargin;
+ MODULE* module = GetParent();
+
+ if( module )
+ {
+ if( margin == 0 )
+ {
+ if( module->GetLocalSolderMaskMargin() )
+ margin = module->GetLocalSolderMaskMargin();
+ }
+
+ if( margin == 0 )
+ {
+ BOARD* brd = GetBoard();
+ margin = brd->GetDesignSettings().m_SolderMaskMargin;
+ }
+ }
+
+ // ensure mask have a size always >= 0
+ if( margin < 0 )
+ {
+ int minsize = -std::min( m_Size.x, m_Size.y ) / 2;
+
+ if( margin < minsize )
+ margin = minsize;
+ }
+
+ return margin;
+}
+
+
+wxSize D_PAD::GetSolderPasteMargin() const
+{
+ int margin = m_LocalSolderPasteMargin;
+ double mratio = m_LocalSolderPasteMarginRatio;
+ MODULE* module = GetParent();
+
+ if( module )
+ {
+ if( margin == 0 )
+ margin = module->GetLocalSolderPasteMargin();
+
+ BOARD * brd = GetBoard();
+
+ if( margin == 0 )
+ margin = brd->GetDesignSettings().m_SolderPasteMargin;
+
+ if( mratio == 0.0 )
+ mratio = module->GetLocalSolderPasteMarginRatio();
+
+ if( mratio == 0.0 )
+ {
+ mratio = brd->GetDesignSettings().m_SolderPasteMarginRatio;
+ }
+ }
+
+ wxSize pad_margin;
+ pad_margin.x = margin + KiROUND( m_Size.x * mratio );
+ pad_margin.y = margin + KiROUND( m_Size.y * mratio );
+
+ // ensure mask have a size always >= 0
+ if( pad_margin.x < -m_Size.x / 2 )
+ pad_margin.x = -m_Size.x / 2;
+
+ if( pad_margin.y < -m_Size.y / 2 )
+ pad_margin.y = -m_Size.y / 2;
+
+ return pad_margin;
+}
+
+
+ZoneConnection D_PAD::GetZoneConnection() const
+{
+ MODULE* module = GetParent();
+
+ if( m_ZoneConnection == PAD_ZONE_CONN_INHERITED && module )
+ return module->GetZoneConnection();
+ else
+ return m_ZoneConnection;
+}
+
+
+int D_PAD::GetThermalWidth() const
+{
+ MODULE* module = GetParent();
+
+ if( m_ThermalWidth == 0 && module )
+ return module->GetThermalWidth();
+ else
+ return m_ThermalWidth;
+}
+
+
+int D_PAD::GetThermalGap() const
+{
+ MODULE* module = GetParent();
+
+ if( m_ThermalGap == 0 && module )
+ return module->GetThermalGap();
+ else
+ return m_ThermalGap;
+}
+
+
+void D_PAD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM>& aList )
+{
+ MODULE* module;
+ wxString Line;
+ BOARD* board;
+
+ module = (MODULE*) m_Parent;
+
+ if( module )
+ {
+ wxString msg = module->GetReference();
+ aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), msg, DARKCYAN ) );
+ StringPadName( Line );
+ aList.push_back( MSG_PANEL_ITEM( _( "Pad" ), Line, BROWN ) );
+ }
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Net" ), GetNetname(), DARKCYAN ) );
+
+ /* For test and debug only: display m_physical_connexion and
+ * m_logical_connexion */
+#if 1 // Used only to debug connectivity calculations
+ Line.Printf( wxT( "%d-%d-%d " ), GetSubRatsnest(), GetSubNet(), GetZoneSubNet() );
+ aList.push_back( MSG_PANEL_ITEM( wxT( "L-P-Z" ), Line, DARKGREEN ) );
+#endif
+
+ board = GetBoard();
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Layer" ),
+ LayerMaskDescribe( board, m_layerMask ), DARKGREEN ) );
+
+ aList.push_back( MSG_PANEL_ITEM( ShowPadShape(), ShowPadAttr(), DARKGREEN ) );
+
+ Line = ::CoordinateToString( m_Size.x );
+ aList.push_back( MSG_PANEL_ITEM( _( "Width" ), Line, RED ) );
+
+ Line = ::CoordinateToString( m_Size.y );
+ aList.push_back( MSG_PANEL_ITEM( _( "Height" ), Line, RED ) );
+
+ Line = ::CoordinateToString( (unsigned) m_Drill.x );
+
+ if( GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
+ {
+ aList.push_back( MSG_PANEL_ITEM( _( "Drill" ), Line, RED ) );
+ }
+ else
+ {
+ Line = ::CoordinateToString( (unsigned) m_Drill.x );
+ wxString msg;
+ msg = ::CoordinateToString( (unsigned) m_Drill.y );
+ Line += wxT( "/" ) + msg;
+ aList.push_back( MSG_PANEL_ITEM( _( "Drill X / Y" ), Line, RED ) );
+ }
+
+ double module_orient = module ? module->GetOrientation() : 0;
+
+ if( module_orient )
+ Line.Printf( wxT( "%3.1f(+%3.1f)" ),
+ ( m_Orient - module_orient ) / 10.0,
+ module_orient / 10.0 );
+ else
+ Line.Printf( wxT( "%3.1f" ), m_Orient / 10.0 );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), Line, LIGHTBLUE ) );
+
+ Line = ::CoordinateToString( m_Pos.x ) + wxT( ", " ) + ::CoordinateToString( m_Pos.y );
+ aList.push_back( MSG_PANEL_ITEM( _( "Position" ), Line, LIGHTBLUE ) );
+
+ if( GetPadToDieLength() )
+ {
+ Line = ::CoordinateToString( GetPadToDieLength() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Length in package" ), Line, CYAN ) );
+ }
+}
+
+
+void D_PAD::GetOblongDrillGeometry( wxPoint& aStartPoint,
+ wxPoint& aEndPoint, int& aWidth ) const
+{
+ // calculates the start point, end point and width
+ // of an equivalent segment which have the same position and width as the hole
+ int delta_cx, delta_cy;
+
+ wxSize halfsize = GetDrillSize();
+ halfsize.x /= 2;
+ halfsize.y /= 2;
+
+ if( m_Drill.x > m_Drill.y ) // horizontal
+ {
+ delta_cx = halfsize.x - halfsize.y;
+ delta_cy = 0;
+ aWidth = m_Drill.y;
+ }
+ else // vertical
+ {
+ delta_cx = 0;
+ delta_cy = halfsize.y - halfsize.x;
+ aWidth = m_Drill.x;
+ }
+
+ RotatePoint( &delta_cx, &delta_cy, m_Orient );
+
+ aStartPoint.x = delta_cx;
+ aStartPoint.y = delta_cy;
+
+ aEndPoint.x = - delta_cx;
+ aEndPoint.y = - delta_cy;
+}
+
+bool D_PAD::HitTest( const wxPoint& aPosition ) const
+{
+ int dx, dy;
+
+ wxPoint shape_pos = ShapePos();
+
+ wxPoint delta = aPosition - shape_pos;
+
+ // first test: a test point must be inside a minimum sized bounding circle.
+ int radius = GetBoundingRadius();
+
+ if( ( abs( delta.x ) > radius ) || ( abs( delta.y ) > radius ) )
+ return false;
+
+ dx = m_Size.x >> 1; // dx also is the radius for rounded pads
+ dy = m_Size.y >> 1;
+
+ switch( GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+ if( KiROUND( EuclideanNorm( delta ) ) <= dx )
+ return true;
+
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ {
+ wxPoint poly[4];
+ BuildPadPolygon( poly, wxSize(0,0), 0 );
+ RotatePoint( &delta, -m_Orient );
+ return TestPointInsidePolygon( poly, 4, delta );
+ }
+
+ case PAD_SHAPE_OVAL:
+ {
+ RotatePoint( &delta, -m_Orient );
+ // An oval pad has the same shape as a segment with rounded ends
+ // After rotation, the test point is relative to an horizontal pad
+ int dist;
+ wxPoint offset;
+ if( dy > dx ) // shape is a vertical oval
+ {
+ offset.y = dy - dx;
+ dist = dx;
+ }
+ else //if( dy <= dx ) shape is an horizontal oval
+ {
+ offset.x = dy - dx;
+ dist = dy;
+ }
+ return TestSegmentHit( delta, - offset, offset, dist );
+ }
+ break;
+
+ case PAD_SHAPE_RECT:
+ RotatePoint( &delta, -m_Orient );
+
+ if( (abs( delta.x ) <= dx ) && (abs( delta.y ) <= dy) )
+ return true;
+
+ break;
+ }
+
+ return false;
+}
+
+
+int D_PAD::Compare( const D_PAD* padref, const D_PAD* padcmp )
+{
+ int diff;
+
+ if( ( diff = padref->GetShape() - padcmp->GetShape() ) != 0 )
+ return diff;
+
+ if( ( diff = padref->GetDrillShape() - padcmp->GetDrillShape() ) != 0)
+ return diff;
+
+ if( ( diff = padref->m_Drill.x - padcmp->m_Drill.x ) != 0 )
+ return diff;
+
+ if( ( diff = padref->m_Drill.y - padcmp->m_Drill.y ) != 0 )
+ return diff;
+
+ if( ( diff = padref->m_Size.x - padcmp->m_Size.x ) != 0 )
+ return diff;
+
+ if( ( diff = padref->m_Size.y - padcmp->m_Size.y ) != 0 )
+ return diff;
+
+ if( ( diff = padref->m_Offset.x - padcmp->m_Offset.x ) != 0 )
+ return diff;
+
+ if( ( diff = padref->m_Offset.y - padcmp->m_Offset.y ) != 0 )
+ return diff;
+
+ if( ( diff = padref->m_DeltaSize.x - padcmp->m_DeltaSize.x ) != 0 )
+ return diff;
+
+ if( ( diff = padref->m_DeltaSize.y - padcmp->m_DeltaSize.y ) != 0 )
+ return diff;
+
+ // Dick: specctra_export needs this
+ // Lorenzo: gencad also needs it to implement padstacks!
+
+#if __cplusplus >= 201103L
+ long long d = padref->m_layerMask.to_ullong() - padcmp->m_layerMask.to_ullong();
+ if( d < 0 )
+ return -1;
+ else if( d > 0 )
+ return 1;
+
+ return 0;
+#else
+ // these strings are not typically constructed, since we don't get here often.
+ std::string s1 = padref->m_layerMask.to_string();
+ std::string s2 = padcmp->m_layerMask.to_string();
+ return s1.compare( s2 );
+#endif
+}
+
+
+void D_PAD::Rotate( const wxPoint& aRotCentre, double aAngle )
+{
+ RotatePoint( &m_Pos, aRotCentre, aAngle );
+ m_Orient += aAngle;
+ NORMALIZE_ANGLE_360( m_Orient );
+
+ SetLocalCoord();
+}
+
+
+wxString D_PAD::ShowPadShape() const
+{
+ switch( GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+ return _( "Circle" );
+
+ case PAD_SHAPE_OVAL:
+ return _( "Oval" );
+
+ case PAD_SHAPE_RECT:
+ return _( "Rect" );
+
+ case PAD_SHAPE_TRAPEZOID:
+ return _( "Trap" );
+
+ default:
+ return wxT( "???" );
+ }
+}
+
+
+wxString D_PAD::ShowPadAttr() const
+{
+ switch( GetAttribute() )
+ {
+ case PAD_ATTRIB_STANDARD:
+ return _( "Std" );
+
+ case PAD_ATTRIB_SMD:
+ return _( "SMD" );
+
+ case PAD_ATTRIB_CONN:
+ return _( "Conn" );
+
+ case PAD_ATTRIB_HOLE_NOT_PLATED:
+ return _( "Not Plated" );
+
+ default:
+ return wxT( "???" );
+ }
+}
+
+
+wxString D_PAD::GetSelectMenuText() const
+{
+ wxString text;
+ wxString padlayers( LayerMaskDescribe( GetBoard(), m_layerMask ) );
+ wxString padname( GetPadName() );
+
+ if( padname.IsEmpty() )
+ {
+ text.Printf( _( "Pad on %s of %s" ),
+ GetChars( padlayers ),
+ GetChars(GetParent()->GetReference() ) );
+ }
+ else
+ {
+ text.Printf( _( "Pad %s on %s of %s" ),
+ GetChars(GetPadName() ), GetChars( padlayers ),
+ GetChars(GetParent()->GetReference() ) );
+ }
+
+ return text;
+}
+
+
+EDA_ITEM* D_PAD::Clone() const
+{
+ return new D_PAD( *this );
+}
+
+
+void D_PAD::ViewGetLayers( int aLayers[], int& aCount ) const
+{
+ aCount = 0;
+
+ // These types of pads contain a hole
+ if( m_Attribute == PAD_ATTRIB_STANDARD || m_Attribute == PAD_ATTRIB_HOLE_NOT_PLATED )
+ aLayers[aCount++] = ITEM_GAL_LAYER( PADS_HOLES_VISIBLE );
+
+ if( IsOnLayer( F_Cu ) && IsOnLayer( B_Cu ) )
+ {
+ // Multi layer pad
+ aLayers[aCount++] = ITEM_GAL_LAYER( PADS_VISIBLE );
+ aLayers[aCount++] = NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE );
+ }
+ else if( IsOnLayer( F_Cu ) )
+ {
+ aLayers[aCount++] = ITEM_GAL_LAYER( PAD_FR_VISIBLE );
+ aLayers[aCount++] = NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE );
+ }
+ else if( IsOnLayer( B_Cu ) )
+ {
+ aLayers[aCount++] = ITEM_GAL_LAYER( PAD_BK_VISIBLE );
+ aLayers[aCount++] = NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE );
+ }
+
+ // Check non-copper layers. This list should include all the layers that the
+ // footprint editor allows a pad to be placed on.
+ static const LAYER_ID layers_mech[] = { F_Mask, B_Mask, F_Paste, B_Paste,
+ F_Adhes, B_Adhes, F_SilkS, B_SilkS, Dwgs_User, Eco1_User, Eco2_User };
+
+ BOOST_FOREACH( LAYER_ID each_layer, layers_mech )
+ {
+ if( IsOnLayer( each_layer ) )
+ aLayers[aCount++] = each_layer;
+ }
+
+#ifdef __WXDEBUG__
+ if( aCount == 0 ) // Should not occur
+ {
+ wxString msg;
+ msg.Printf( wxT( "footprint %s, pad %s: could not find valid layer for pad" ),
+ GetParent() ? GetParent()->GetReference() : "<null>",
+ GetPadName().IsEmpty() ? "(unnamed)" : GetPadName() );
+ wxLogWarning( msg );
+ }
+#endif
+}
+
+
+unsigned int D_PAD::ViewGetLOD( int aLayer ) const
+{
+ // Netnames will be shown only if zoom is appropriate
+ if( IsNetnameLayer( aLayer ) )
+ {
+ // Pad sizes can be zero briefly when someone is typing a number like "0.5" in the pad properties dialog.
+ // Fail gracefully if this happens.
+ if( ( m_Size.x == 0 ) && ( m_Size.y == 0 ) )
+ return UINT_MAX;
+
+ return ( Millimeter2iu( 100 ) / std::max( m_Size.x, m_Size.y ) );
+ }
+
+ // Other layers are shown without any conditions
+ return 0;
+}
+
+
+const BOX2I D_PAD::ViewBBox() const
+{
+ // Bounding box includes soldermask too
+ int solderMaskMargin = GetSolderMaskMargin();
+ VECTOR2I solderPasteMargin = VECTOR2D( GetSolderPasteMargin() );
+ EDA_RECT bbox = GetBoundingBox();
+
+ // Look for the biggest possible bounding box
+ int xMargin = std::max( solderMaskMargin, solderPasteMargin.x );
+ int yMargin = std::max( solderMaskMargin, solderPasteMargin.y );
+
+ return BOX2I( VECTOR2I( bbox.GetOrigin() ) - VECTOR2I( xMargin, yMargin ),
+ VECTOR2I( bbox.GetSize() ) + VECTOR2I( 2 * xMargin, 2 * yMargin ) );
+}
diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h
new file mode 100644
index 0000000..03340d7
--- /dev/null
+++ b/pcbnew/class_pad.h
@@ -0,0 +1,597 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_pad.h
+ * @brief Pad object description
+ */
+
+#ifndef PAD_H_
+#define PAD_H_
+
+
+#include <class_board_item.h>
+#include <class_board_connected_item.h>
+#include <pad_shapes.h>
+#include <PolyLine.h>
+#include <config_params.h> // PARAM_CFG_ARRAY
+#include "zones.h"
+
+
+class LINE_READER;
+class EDA_3D_CANVAS;
+class EDA_DRAW_PANEL;
+class MODULE;
+class TRACK;
+class MSG_PANEL_INFO;
+
+
+// Helper class to store parameters used to draw a pad
+class PAD_DRAWINFO
+{
+public:
+ EDA_DRAW_PANEL* m_DrawPanel; // the EDA_DRAW_PANEL used to draw a PAD ; can be null
+ GR_DRAWMODE m_DrawMode; // the draw mode
+ EDA_COLOR_T m_Color; // color used to draw the pad shape , from pad layers and
+ // visible layers
+ EDA_COLOR_T m_HoleColor; // color used to draw the pad hole
+ EDA_COLOR_T m_NPHoleColor; // color used to draw a pad Not Plated hole
+ int m_PadClearance; // clearance value, used to draw the pad area outlines
+ wxSize m_Mask_margin; // margin, used to draw solder paste when only one layer is shown
+ bool m_Display_padnum; // true to show pad number
+ bool m_Display_netname; // true to show net name
+ bool m_ShowPadFilled; // true to show pad as solid area, false to show pas in
+ // sketch mode
+ bool m_ShowNCMark; // true to show pad not connected mark
+ bool m_ShowNotPlatedHole; // true when the pad hole in not plated, to draw a specific
+ // pad shape
+ bool m_IsPrinting; // true to print, false to display on screen.
+ wxPoint m_Offset; // general draw offset
+
+ PAD_DRAWINFO();
+};
+
+
+class D_PAD : public BOARD_CONNECTED_ITEM
+{
+public:
+ static int m_PadSketchModePenSize; ///< Pen size used to draw pads in sketch mode
+ ///< (mode used to print pads on silkscreen layer)
+
+public:
+ D_PAD( MODULE* parent );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+ // D_PAD( const D_PAD& o );
+
+ /* Default layers used for pads, according to the pad type.
+ * this is default values only, they can be changed for a given pad
+ */
+ static LSET StandardMask(); ///< layer set for a through hole pad
+ static LSET SMDMask(); ///< layer set for a SMD pad on Front layer
+ static LSET ConnSMDMask(); ///< layer set for a SMD pad on Front layer
+ ///< used for edge board connectors
+ static LSET UnplatedHoleMask(); ///< layer set for a mechanical unplated through hole pad
+
+ static inline bool ClassOf( const EDA_ITEM* aItem )
+ {
+ return aItem && PCB_PAD_T == aItem->Type();
+ }
+
+ void Copy( D_PAD* source );
+
+ D_PAD* Next() const { return static_cast<D_PAD*>( Pnext ); }
+
+ MODULE* GetParent() const { return (MODULE*) m_Parent; }
+
+ /**
+ * Set the pad name (sometimes called pad number, although
+ * it can be an array ref like AA12
+ * the pad name is limited to 4 ASCII chars
+ */
+ void SetPadName( const wxString& name ); // Change pad name
+
+ /**
+ * @return the pad name
+ * the pad name is limited to 4 ASCII chars
+ */
+ const wxString GetPadName() const;
+
+ /**
+ * @return the pad name in a wxUint32 which is possible
+ * because the pad name is limited to 4 ASCII chars
+ * The packed pad name should be used only to compare 2
+ * pad names, not to try to print this name
+ */
+ const wxUint32 GetPackedPadName() const { return m_NumPadName; }
+
+ /*!
+ * Function IncrementItemReference
+ * Implementation of the generic "reference" incrementing interface
+ * Increments the numeric suffix, filling any sequence gaps and skipping
+ * pads that aren't connectable
+ */
+ bool IncrementItemReference(); // override
+
+ /**
+ * Function IncrementPadName
+ *
+ * Increments the pad name to the next available name in the module.
+ *
+ * @param aSkipUnconnectable skips any pads that are not connectable (for example NPTH)
+ * @return pad name incremented
+ */
+ bool IncrementPadName( bool aSkipUnconnectable, bool aFillSequenceGaps );
+
+ bool PadNameEqual( const D_PAD* other ) const
+ {
+ return m_NumPadName == other->m_NumPadName; // hide tricks behind sensible API
+ }
+
+ /**
+ * Function GetShape
+ * @return the shape of this pad.
+ */
+ PAD_SHAPE_T GetShape() const { return m_padShape; }
+ void SetShape( PAD_SHAPE_T aShape ) { m_padShape = aShape; m_boundingRadius = -1; }
+
+ void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; } // was overload
+ const wxPoint& GetPosition() const { return m_Pos; } // was overload
+
+ void SetY( int y ) { m_Pos.y = y; }
+ void SetX( int x ) { m_Pos.x = x; }
+
+ void SetPos0( const wxPoint& aPos ) { m_Pos0 = aPos; }
+ const wxPoint& GetPos0() const { return m_Pos0; }
+
+ void SetY0( int y ) { m_Pos0.y = y; }
+ void SetX0( int x ) { m_Pos0.x = x; }
+
+ void SetSize( const wxSize& aSize ) { m_Size = aSize; m_boundingRadius = -1; }
+ const wxSize& GetSize() const { return m_Size; }
+
+ void SetDelta( const wxSize& aSize ) { m_DeltaSize = aSize; m_boundingRadius = -1; }
+ const wxSize& GetDelta() const { return m_DeltaSize; }
+
+ void SetDrillSize( const wxSize& aSize ) { m_Drill = aSize; }
+ const wxSize& GetDrillSize() const { return m_Drill; }
+
+ void SetOffset( const wxPoint& aOffset ) { m_Offset = aOffset; }
+ const wxPoint& GetOffset() const { return m_Offset; }
+
+ void Flip( const wxPoint& aCentre ); // Virtual function
+
+ /**
+ * Function SetOrientation
+ * sets the rotation angle of the pad.
+ * @param aAngle is tenths of degrees, but will soon be degrees. If it is
+ * outside of 0 - 3600, then it will be normalized before being saved.
+ */
+ void SetOrientation( double aAngle );
+
+ /**
+ * Function GetOrientation
+ * returns the rotation angle of the pad in tenths of degrees, but soon degrees.
+ */
+ double GetOrientation() const { return m_Orient; }
+
+ void SetDrillShape( PAD_DRILL_SHAPE_T aDrillShape )
+ { m_drillShape = aDrillShape; }
+ PAD_DRILL_SHAPE_T GetDrillShape() const { return m_drillShape; }
+
+ /**
+ * Function GetOblongDrillGeometry calculates the start point, end point and width
+ * of an equivalent segment which have the same position and width as the hole
+ * Usefull to plot/draw oblong holes like segments with rounded ends
+ * used in draw and plot functions
+ * @param aStartPoint = first point of the equivalent segment, relative to the pad position.
+ * @param aEndPoint = second point of the equivalent segment, relative to the pad position.
+ * @param aWidth = width equivalent segment.
+ */
+ void GetOblongDrillGeometry( wxPoint& aStartPoint, wxPoint& aEndPoint, int& aWidth ) const;
+
+ void SetLayerSet( LSET aLayerMask ) { m_layerMask = aLayerMask; }
+ LSET GetLayerSet() const { return m_layerMask; }
+
+ void SetAttribute( PAD_ATTR_T aAttribute );
+ PAD_ATTR_T GetAttribute() const { return m_Attribute; }
+
+ void SetPadToDieLength( int aLength ) { m_LengthPadToDie = aLength; }
+ int GetPadToDieLength() const { return m_LengthPadToDie; }
+
+ int GetLocalSolderMaskMargin() const { return m_LocalSolderMaskMargin; }
+ void SetLocalSolderMaskMargin( int aMargin ) { m_LocalSolderMaskMargin = aMargin; }
+
+ int GetLocalClearance() const { return m_LocalClearance; }
+ void SetLocalClearance( int aClearance ) { m_LocalClearance = aClearance; }
+
+ int GetLocalSolderPasteMargin() const { return m_LocalSolderPasteMargin; }
+ void SetLocalSolderPasteMargin( int aMargin ) { m_LocalSolderPasteMargin = aMargin; }
+
+ double GetLocalSolderPasteMarginRatio() const { return m_LocalSolderPasteMarginRatio; }
+ void SetLocalSolderPasteMarginRatio( double aRatio ) { m_LocalSolderPasteMarginRatio = aRatio; }
+
+
+ /**
+ * Function TransformShapeWithClearanceToPolygon
+ * Convert the pad shape to a closed polygon
+ * Used in filling zones calculations
+ * Circles and arcs are approximated by segments
+ * @param aCornerBuffer = a buffer to store the polygon
+ * @param aClearanceValue = the clearance around the pad
+ * @param aCircleToSegmentsCount = the number of segments to approximate a circle
+ * @param aCorrectionFactor = the correction to apply to circles radius to keep
+ * clearance when the circle is approximated by segment bigger or equal
+ * to the real clearance value (usually near from 1.0)
+ */
+ void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
+ int aClearanceValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor ) const;
+
+ /**
+ * Function GetClearance
+ * returns the clearance in internal units. If \a aItem is not NULL then the
+ * returned clearance is the greater of this object's clearance and
+ * aItem's clearance. If \a aItem is NULL, then this objects clearance
+ * is returned.
+ * @param aItem is another BOARD_CONNECTED_ITEM or NULL
+ * @return int - the clearance in internal units.
+ */
+ int GetClearance( BOARD_CONNECTED_ITEM* aItem = NULL ) const;
+
+ // Mask margins handling:
+
+ /**
+ * Function GetSolderMaskMargin
+ * @return the margin for the solder mask layer
+ * usually > 0 (mask shape bigger than pad
+ * value is
+ * 1 - the local value
+ * 2 - if null, the parent footprint value
+ * 1 - if null, the global value
+ */
+ int GetSolderMaskMargin() const;
+
+ /**
+ * Function GetSolderPasteMargin
+ * @return the margin for the solder mask layer
+ * usually < 0 (mask shape smaller than pad
+ * because the margin can be dependent on the pad size, the margin has a x and a y value
+ * value is
+ * 1 - the local value
+ * 2 - if null, the parent footprint value
+ * 1 - if null, the global value
+ */
+ wxSize GetSolderPasteMargin() const;
+
+ void SetZoneConnection( ZoneConnection aType ) { m_ZoneConnection = aType; }
+ ZoneConnection GetZoneConnection() const;
+
+ void SetThermalWidth( int aWidth ) { m_ThermalWidth = aWidth; }
+ int GetThermalWidth() const;
+
+ void SetThermalGap( int aGap ) { m_ThermalGap = aGap; }
+ int GetThermalGap() const;
+
+ /* drawing functions */
+ void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset );
+
+ /**
+ * Function DrawShape
+ * basic function to draw a pad.
+ * <p>
+ * This function is used by Draw after calculation of parameters (color, ) final
+ * orientation transforms are set. It can also be called to draw a pad on any panel
+ * even if this panel is not a EDA_DRAW_PANEL for instance on a wxPanel inside the
+ * pad editor.
+ * </p>
+ */
+ void DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo );
+
+ /**
+ * Function BuildPadPolygon
+ * Has meaning only for polygonal pads (trapezoid and rectangular)
+ * Build the Corner list of the polygonal shape,
+ * depending on shape, extra size (clearance ...) and orientation
+ * @param aCoord = a buffer to fill (4 corners).
+ * @param aInflateValue = wxSize: the clearance or margin value. value > 0:
+ * inflate, < 0 deflate
+ * @param aRotation = full rotation of the polygon
+ */
+ void BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue, double aRotation ) const;
+
+ /**
+ * Function BuildPadShapePolygon
+ * Build the Corner list of the polygonal shape,
+ * depending on shape, extra size (clearance ...) pad and orientation
+ * This function is similar to TransformShapeWithClearanceToPolygon,
+ * but the difference is BuildPadShapePolygon creates a polygon shape exactly
+ * similar to pad shape, which a size inflated by aInflateValue
+ * and TransformShapeWithClearanceToPolygon creates a more complex shape (for instance
+ * a rectangular pad is converted in a rectangulr shape with ronded corners)
+ * @param aCornerBuffer = a buffer to fill.
+ * @param aInflateValue = the clearance or margin value.
+ * value > 0: inflate, < 0 deflate, = 0 : no change
+ * the clearance can have different values for x and y directions
+ * (relative to the pad)
+ * @param aSegmentsPerCircle = number of segments to approximate a circle
+ * (used for round and oblong shapes only (16 to 32 is a good value)
+ * @param aCorrectionFactor = the correction to apply to circles radius to keep
+ * the pad size when the circle is approximated by segments
+ */
+ void BuildPadShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
+ wxSize aInflateValue, int aSegmentsPerCircle,
+ double aCorrectionFactor ) const;
+
+ /**
+ * Function BuildPadDrillShapePolygon
+ * Build the Corner list of the polygonal drill shape,
+ * depending on shape pad hole and orientation
+ * @param aCornerBuffer = a buffer to fill.
+ * @param aInflateValue = the clearance or margin value.
+ * value > 0: inflate, < 0 deflate, = 0 : no change
+ * @param aSegmentsPerCircle = number of segments to approximate a circle
+ * (used for round and oblong shapes only(16 to 32 is a good value)
+ * @return false if the pad has no hole, true otherwise
+ */
+ bool BuildPadDrillShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
+ int aInflateValue, int aSegmentsPerCircle ) const;
+
+ /**
+ * Function BuildSegmentFromOvalShape
+ * Has meaning only for OVAL (and ROUND) pads
+ * Build an equivalent segment having the same shape as the OVAL shape,
+ * Useful in draw function and in DRC and HitTest functions,
+ * because segments are already well handled by track tests
+ * @param aSegStart = the starting point of the equivalent segment relative to the shape
+ * position.
+ * @param aSegEnd = the ending point of the equivalent segment, relative to the shape position
+ * @param aRotation = full rotation of the segment
+ * @param aRotation = full rotation of the segment
+ * @param aMargin = a margin around the shape (for instance mask margin)
+ * @return the width of the segment
+ */
+ int BuildSegmentFromOvalShape( wxPoint& aSegStart, wxPoint& aSegEnd,
+ double aRotation, const wxSize& aMargin ) const;
+
+ void StringPadName( wxString& text ) const; // Return pad name as string in a buffer
+
+ /**
+ * Function GetBoundingRadius
+ * returns the radius of a minimum sized circle which fully encloses this pad.
+ */
+ int GetBoundingRadius() const
+ {
+ // Any member function which would affect this calculation should set
+ // m_boundingRadius to -1 to re-trigger the calculation from here.
+ // Currently that is only m_Size, m_DeltaSize, and m_padShape accessors.
+ if( m_boundingRadius == -1 )
+ {
+ m_boundingRadius = boundingRadius();
+ }
+
+ return m_boundingRadius;
+ }
+
+ const wxPoint ShapePos() const;
+
+ /**
+ * Function GetSubRatsnest
+ * @return int - the netcode
+ */
+ int GetSubRatsnest() const { return m_SubRatsnest; }
+ void SetSubRatsnest( int aSubRatsnest ) { m_SubRatsnest = aSubRatsnest; }
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ bool IsOnLayer( LAYER_ID aLayer ) const
+ {
+ return m_layerMask[aLayer];
+ }
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ wxString GetClass() const
+ {
+ return wxT( "PAD" );
+ }
+
+ // Virtual function:
+ const EDA_RECT GetBoundingBox() const;
+
+ ///> Set absolute coordinates.
+ void SetDrawCoord();
+
+ ///> Set relative coordinates.
+ void SetLocalCoord();
+
+ /**
+ * Function Compare
+ * compares two pads and return 0 if they are equal.
+ * @return int - <0 if left less than right, 0 if equal, >0 if left greater than right.
+ */
+ static int Compare( const D_PAD* padref, const D_PAD* padcmp );
+
+ void Move( const wxPoint& aMoveVector )
+ {
+ m_Pos += aMoveVector;
+ SetLocalCoord();
+ }
+
+ void Rotate( const wxPoint& aRotCentre, double aAngle );
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return pad_xpm; }
+
+ /**
+ * Function ShowPadShape
+ * @return the name of the shape
+ */
+ wxString ShowPadShape() const;
+
+ /**
+ * Function ShowPadAttr
+ * @return the name of the pad type (attribute) : STD, SMD ...
+ */
+ wxString ShowPadAttr() const;
+
+ /**
+ * Function AppendConfigs
+ * appends to @a aResult the configuration setting accessors which will later
+ * allow reading or writing of configuration file information directly into
+ * this object.
+ */
+ void AppendConfigs( PARAM_CFG_ARRAY* aResult );
+
+ EDA_ITEM* Clone() const;
+
+ /**
+ * same as Clone, but returns a D_PAD item.
+ * Useful mainly for pythons scripts, because Clone (virtual function)
+ * returns an EDA_ITEM.
+ */
+ D_PAD* Duplicate() const
+ {
+ return (D_PAD*) Clone();
+ }
+
+ /// @copydoc VIEW_ITEM::ViewGetLayers()
+ virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
+
+ /// @copydoc VIEW_ITEM::ViewGetLOD()
+ virtual unsigned int ViewGetLOD( int aLayer ) const;
+
+ /// @copydoc VIEW_ITEM::ViewBBox()
+ virtual const BOX2I ViewBBox() const;
+
+ /**
+ * Function CopyNetlistSettings
+ * copies the netlist settings to \a aPad, and the net name.
+ * Used to copy some pad parameters when replacing a footprint by an other
+ * footprint when reading a netlist, or in exchange footprint dialog
+ *
+ * The netlist settings are all of the #D_PAD settings not define by a #D_PAD in
+ * a netlist.
+ * The copied settings are the net name and optionally include local clearance, etc.
+ * The pad physical geometry settings are not copied.
+ *
+ * @param aPad is the #D_PAD to copy the settings to.
+ * @param aCopyLocalSettings = false to copy only the net name
+ * true to also copy local prms
+ */
+ void CopyNetlistSettings( D_PAD* aPad, bool aCopyLocalSettings );
+
+#if defined(DEBUG)
+ virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+
+
+private:
+ /**
+ * Function boundingRadius
+ * returns a calculated radius of a bounding circle for this pad.
+ */
+ int boundingRadius() const;
+
+ // Actually computed and cached on demand by the accessor
+ mutable int m_boundingRadius; ///< radius of the circle containing the pad shape
+
+ /// Pad name (4 char) or a long identifier (used in pad name
+ /// comparisons because this is faster than string comparison)
+ union
+ {
+#define PADNAMEZ 4
+ char m_Padname[PADNAMEZ]; // zero padded at end to full size
+ wxUint32 m_NumPadName; // same number of bytes as m_Padname[]
+ };
+
+ wxPoint m_Pos; ///< pad Position on board
+
+ PAD_SHAPE_T m_padShape; ///< Shape: PAD_CIRCLE, PAD_RECT, PAD_OVAL, PAD_TRAPEZOID
+
+
+ int m_SubRatsnest; ///< variable used in rats nest computations
+ ///< handle subnet (block) number in ratsnest connection
+
+ wxSize m_Drill; ///< Drill diam (drill shape = PAD_CIRCLE) or drill size
+ ///< (shape = OVAL) for drill shape = PAD_CIRCLE, drill
+ ///< diam = m_Drill.x
+
+ wxSize m_Size; ///< X and Y size ( relative to orient 0)
+
+ PAD_DRILL_SHAPE_T m_drillShape; ///< PAD_DRILL_SHAPE_CIRCLE, PAD_DRILL_SHAPE_OBLONG
+
+
+ /**
+ * m_Offset is useful only for oblong pads (it can be used for other
+ * shapes, but without any interest).
+ * This is the offset between the pad hole and the pad shape (you must
+ * understand here pad shape = copper area around the hole)
+ * Most of cases, the hole is the center of the shape (m_Offset = 0).
+ * But some board designers use oblong pads with a hole moved to one of the
+ * oblong pad shape ends.
+ * In all cases the pad position is the pad hole.
+ * The physical shape position (used to draw it for instance) is pad
+ * position (m_Pos) + m_Offset.
+ * D_PAD::ShapePos() returns the physical shape position according to
+ * the offset and the pad rotation.
+ */
+ wxPoint m_Offset;
+
+ LSET m_layerMask; ///< Bitwise layer :1= copper layer, 15= cmp,
+ ///< 2..14 = internal layers
+ ///< 16 .. 31 = technical layers
+
+ wxSize m_DeltaSize; ///< delta on rectangular shapes
+
+ wxPoint m_Pos0; ///< Initial Pad position (i.e. pad position relative to the
+ ///< module anchor, orientation 0)
+
+ PAD_ATTR_T m_Attribute; ///< PAD_ATTRIB_NORMAL, PAD_ATTRIB_SMD,
+ ///< PAD_ATTRIB_CONN, PAD_ATTRIB_HOLE_NOT_PLATED
+ double m_Orient; ///< in 1/10 degrees
+
+ int m_LengthPadToDie; ///< Length net from pad to die, inside the package
+
+ /// Local clearance. When null, the module default value is used.
+ /// when the module default value is null, the netclass value is used
+ /// Usually the local clearance is null
+ int m_LocalClearance;
+
+ // Local mask margins: when 0, the parent footprint design values are used
+
+ int m_LocalSolderMaskMargin; ///< Local solder mask margin
+ int m_LocalSolderPasteMargin; ///< Local solder paste margin absolute value
+
+ double m_LocalSolderPasteMarginRatio; ///< Local solder mask margin ratio value of pad size
+ ///< The final margin is the sum of these 2 values
+ ZoneConnection m_ZoneConnection;
+ int m_ThermalWidth;
+ int m_ThermalGap;
+};
+
+#endif // PAD_H_
diff --git a/pcbnew/class_pad_draw_functions.cpp b/pcbnew/class_pad_draw_functions.cpp
new file mode 100644
index 0000000..184d089
--- /dev/null
+++ b/pcbnew/class_pad_draw_functions.cpp
@@ -0,0 +1,762 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_pad_draw_functions.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <common.h>
+#include <trigo.h>
+#include <class_pcb_screen.h>
+#include <class_drawpanel.h>
+#include <drawtxt.h>
+#include <layers_id_colors_and_visibility.h>
+#include <wxBasePcbFrame.h>
+#include <pcbnew_id.h> // ID_TRACK_BUTT
+#include <pcbnew.h>
+#include <class_board.h>
+
+
+/* uncomment this line to show this pad with its specfic size and color
+ * when it is not on copper layers, and only one solder mask layer or solder paste layer
+ * is displayed for this pad
+ * After testing this feature,I am not sure this is a good idea
+ * but the code is left here.
+ */
+
+//#define SHOW_PADMASK_REAL_SIZE_AND_COLOR
+
+
+// Helper class to store parameters used to draw a pad
+PAD_DRAWINFO::PAD_DRAWINFO()
+{
+ m_DrawPanel = NULL;
+ m_DrawMode = GR_COPY;
+ m_Color = BLACK;
+ m_HoleColor = BLACK; // could be DARKGRAY;
+ m_NPHoleColor = YELLOW;
+ m_PadClearance = 0;
+ m_Display_padnum = true;
+ m_Display_netname = true;
+ m_ShowPadFilled = true;
+ m_ShowNCMark = true;
+ m_ShowNotPlatedHole = false;
+ m_IsPrinting = false;
+}
+
+
+void D_PAD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDraw_mode,
+ const wxPoint& aOffset )
+{
+ wxSize mask_margin; // margin (clearance) used for some non copper layers
+
+#ifdef SHOW_PADMASK_REAL_SIZE_AND_COLOR
+ int showActualMaskSize = 0; /* Layer number if the actual pad size on mask layer can
+ * be displayed i.e. if only one layer is shown for this pad
+ * and this layer is a mask (solder mask or solder paste
+ */
+#endif
+
+ if( m_Flags & DO_NOT_DRAW )
+ return;
+
+ PAD_DRAWINFO drawInfo;
+
+ drawInfo.m_Offset = aOffset;
+
+ /* We can show/hide pads from the layer manager.
+ * options are show/hide pads on front and/or back side of the board
+ * For through pads, we hide them only if both sides are hidden.
+ * smd pads on back are hidden for all layers (copper and technical layers)
+ * on back side of the board
+ * smd pads on front are hidden for all layers (copper and technical layers)
+ * on front side of the board
+ * ECO, edge and Draw layers and not considered
+ */
+
+ BOARD* brd = GetBoard();
+ bool frontVisible = brd->IsElementVisible( PCB_VISIBLE( PAD_FR_VISIBLE ) );
+ bool backVisible = brd->IsElementVisible( PCB_VISIBLE( PAD_BK_VISIBLE ) );
+
+ if( !frontVisible && !backVisible )
+ return;
+
+ // If pad is only on front side (no layer on back side)
+ // and if hide front side pads is enabled, do not draw
+ if( !frontVisible && !( m_layerMask & LSET::BackMask() ).any() )
+ return;
+
+ // If pad is only on back side (no layer on front side)
+ // and if hide back side pads is enabled, do not draw
+ if( !backVisible && !( m_layerMask & LSET::FrontMask() ).any() )
+ return;
+
+ PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent();
+
+ wxCHECK_RET( frame != NULL, wxT( "Panel has no parent frame window." ) );
+
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)frame->GetDisplayOptions();
+ PCB_SCREEN* screen = frame->GetScreen();
+
+ if( displ_opts && displ_opts->m_DisplayPadFill == SKETCH )
+ drawInfo.m_ShowPadFilled = false;
+ else
+ drawInfo.m_ShowPadFilled = true;
+
+ EDA_COLOR_T color = BLACK;
+
+ if( m_layerMask[F_Cu] )
+ {
+ color = brd->GetVisibleElementColor( PAD_FR_VISIBLE );
+ }
+
+ if( m_layerMask[B_Cu] )
+ {
+ color = ColorMix( color, brd->GetVisibleElementColor( PAD_BK_VISIBLE ) );
+ }
+
+ if( color == BLACK ) // Not on a visible copper layer (i.e. still nothing to show)
+ {
+ // If the pad is on only one tech layer, use the layer color else use DARKGRAY
+ LSET mask_non_copper_layers = m_layerMask & ~LSET::AllCuMask();
+
+#ifdef SHOW_PADMASK_REAL_SIZE_AND_COLOR
+ mask_non_copper_layers &= brd->GetVisibleLayers();
+#endif
+ LAYER_ID pad_layer = mask_non_copper_layers.ExtractLayer();
+
+ switch( (int) pad_layer )
+ {
+ case UNDEFINED_LAYER: // More than one layer
+ color = DARKGRAY;
+ break;
+
+ case UNSELECTED_LAYER: // Shouldn't really happen...
+ break;
+
+ default:
+ color = brd->GetLayerColor( pad_layer );
+#ifdef SHOW_PADMASK_REAL_SIZE_AND_COLOR
+ showActualMaskSize = pad_layer;
+#endif
+ }
+ }
+
+ // if SMD or connector pad and high contrast mode
+ if( ( aDraw_mode & GR_ALLOW_HIGHCONTRAST ) &&
+ ( GetAttribute() == PAD_ATTRIB_SMD || GetAttribute() == PAD_ATTRIB_CONN ) &&
+ displ_opts && displ_opts->m_ContrastModeDisplay )
+ {
+ // when routing tracks
+ if( frame->GetToolId() == ID_TRACK_BUTT )
+ {
+ LAYER_ID routeTop = screen->m_Route_Layer_TOP;
+ LAYER_ID routeBot = screen->m_Route_Layer_BOTTOM;
+
+ // if routing between copper and component layers,
+ // or the current layer is one of said 2 external copper layers,
+ // then highlight only the current layer.
+ if( ( screen->m_Active_Layer == F_Cu || screen->m_Active_Layer == B_Cu ) ||
+ ( routeTop==F_Cu && routeBot==B_Cu ) ||
+ ( routeTop==B_Cu && routeBot==F_Cu )
+ )
+ {
+ if( !IsOnLayer( screen->m_Active_Layer ) )
+ ColorTurnToDarkDarkGray( &color );
+ }
+ // else routing between an internal signal layer and some other
+ // layer. Grey out all PAD_ATTRIB_SMD pads not on current or the single
+ // selected external layer.
+ else if( !IsOnLayer( screen->m_Active_Layer )
+ && !IsOnLayer( routeTop )
+ && !IsOnLayer( routeBot ) )
+ {
+ ColorTurnToDarkDarkGray( &color );
+ }
+ }
+ // when not edting tracks, show PAD_ATTRIB_SMD components not on active layer
+ // as greyed out
+ else
+ {
+ if( !IsOnLayer( screen->m_Active_Layer ) )
+ ColorTurnToDarkDarkGray( &color );
+ }
+ }
+
+#ifdef SHOW_PADMASK_REAL_SIZE_AND_COLOR
+ if( showActualMaskSize )
+ {
+ switch( showActualMaskSize )
+ {
+ case B_Mask:
+ case F_Mask:
+ mask_margin.x = mask_margin.y = GetSolderMaskMargin();
+ break;
+
+ case B_Paste:
+ case F_Paste:
+ mask_margin = GetSolderPasteMargin();
+ break;
+
+ default:
+ // Another layer which has no margin to handle
+ break;
+ }
+ }
+#endif
+
+ // if Contrast mode is ON and a technical layer active, show pads on this
+ // layer so we can see pads on paste or solder layer and the size of the
+ // mask
+ if( ( aDraw_mode & GR_ALLOW_HIGHCONTRAST ) &&
+ displ_opts && displ_opts->m_ContrastModeDisplay && !IsCopperLayer( screen->m_Active_Layer ) )
+ {
+ if( IsOnLayer( screen->m_Active_Layer ) )
+ {
+ color = brd->GetLayerColor( screen->m_Active_Layer );
+
+ // In high contrast mode, and if the active layer is the mask
+ // layer shows the pad size with the mask clearance
+ switch( screen->m_Active_Layer )
+ {
+ case B_Mask:
+ case F_Mask:
+ mask_margin.x = mask_margin.y = GetSolderMaskMargin();
+ break;
+
+ case B_Paste:
+ case F_Paste:
+ mask_margin = GetSolderPasteMargin();
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ color = DARKDARKGRAY;
+ }
+
+
+ if( aDraw_mode & GR_HIGHLIGHT )
+ ColorChangeHighlightFlag( &color, !(aDraw_mode & GR_AND) );
+
+ ColorApplyHighlightFlag( &color );
+
+ bool DisplayIsol = displ_opts && displ_opts->m_DisplayPadIsol;
+
+ if( !( m_layerMask & LSET::AllCuMask() ).any() )
+ DisplayIsol = false;
+
+ if( ( GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED ) &&
+ brd->IsElementVisible( NON_PLATED_VISIBLE ) )
+ {
+ drawInfo.m_ShowNotPlatedHole = true;
+ drawInfo.m_NPHoleColor = brd->GetVisibleElementColor( NON_PLATED_VISIBLE );
+ }
+
+ drawInfo.m_DrawMode = aDraw_mode;
+ drawInfo.m_Color = color;
+ drawInfo.m_DrawPanel = aPanel;
+ drawInfo.m_Mask_margin = mask_margin;
+ drawInfo.m_ShowNCMark = brd->IsElementVisible( PCB_VISIBLE( NO_CONNECTS_VISIBLE ) );
+ drawInfo.m_IsPrinting = screen->m_IsPrinting;
+ SetAlpha( &color, 170 );
+
+ /* Get the pad clearance. This has a meaning only for Pcbnew.
+ * for CvPcb GetClearance() creates debug errors because
+ * there is no net classes so a call to GetClearance() is made only when
+ * needed (never needed in CvPcb)
+ */
+ drawInfo.m_PadClearance = DisplayIsol ? GetClearance() : 0;
+
+ // Draw the pad number
+ if( displ_opts && !displ_opts->m_DisplayPadNum )
+ drawInfo.m_Display_padnum = false;
+
+ if( displ_opts &&
+ (( displ_opts ->m_DisplayNetNamesMode == 0 ) || ( displ_opts->m_DisplayNetNamesMode == 2 )) )
+ drawInfo.m_Display_netname = false;
+
+ // Display net names is restricted to pads that are on the active layer
+ // in high contrast mode display
+ if( ( aDraw_mode & GR_ALLOW_HIGHCONTRAST ) &&
+ !IsOnLayer( screen->m_Active_Layer ) && displ_opts && displ_opts->m_ContrastModeDisplay )
+ drawInfo.m_Display_netname = false;
+
+ DrawShape( aPanel->GetClipBox(), aDC, drawInfo );
+}
+
+
+void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
+{
+ wxPoint coord[4];
+ double angle = m_Orient;
+ int seg_width;
+
+ GRSetDrawMode( aDC, aDrawInfo.m_DrawMode );
+
+ // calculate pad shape position :
+ wxPoint shape_pos = ShapePos() - aDrawInfo.m_Offset;
+
+ wxSize halfsize = m_Size;
+ halfsize.x >>= 1;
+ halfsize.y >>= 1;
+
+ switch( GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+ if( aDrawInfo.m_ShowPadFilled )
+ GRFilledCircle( aClipBox, aDC, shape_pos.x, shape_pos.y,
+ halfsize.x + aDrawInfo.m_Mask_margin.x, 0,
+ aDrawInfo.m_Color, aDrawInfo.m_Color );
+ else
+ GRCircle( aClipBox, aDC, shape_pos.x, shape_pos.y,
+ halfsize.x + aDrawInfo.m_Mask_margin.x,
+ m_PadSketchModePenSize, aDrawInfo.m_Color );
+
+ if( aDrawInfo.m_PadClearance )
+ {
+ GRCircle( aClipBox,
+ aDC, shape_pos.x, shape_pos.y,
+ halfsize.x + aDrawInfo.m_PadClearance,
+ 0, aDrawInfo.m_Color );
+ }
+
+ break;
+
+ case PAD_SHAPE_OVAL:
+ {
+ wxPoint segStart, segEnd;
+ seg_width = BuildSegmentFromOvalShape(segStart, segEnd, angle,
+ aDrawInfo.m_Mask_margin);
+ segStart += shape_pos;
+ segEnd += shape_pos;
+
+ if( aDrawInfo.m_ShowPadFilled )
+ {
+ GRFillCSegm( aClipBox, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y,
+ seg_width, aDrawInfo.m_Color );
+ }
+ else
+ {
+ GRCSegm( aClipBox, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y,
+ seg_width, m_PadSketchModePenSize, aDrawInfo.m_Color );
+ }
+
+ // Draw the clearance line
+ if( aDrawInfo.m_PadClearance )
+ {
+ seg_width += 2 * aDrawInfo.m_PadClearance;
+ GRCSegm( aClipBox, aDC, segStart.x, segStart.y, segEnd.x, segEnd.y,
+ seg_width, aDrawInfo.m_Color );
+ }
+ }
+ break;
+
+ case PAD_SHAPE_RECT:
+ case PAD_SHAPE_TRAPEZOID:
+ BuildPadPolygon( coord, aDrawInfo.m_Mask_margin, angle );
+
+ for( int ii = 0; ii < 4; ii++ )
+ coord[ii] += shape_pos;
+
+ GRClosedPoly( aClipBox, aDC, 4, coord, aDrawInfo.m_ShowPadFilled,
+ aDrawInfo.m_ShowPadFilled ? 0 : m_PadSketchModePenSize,
+ aDrawInfo.m_Color, aDrawInfo.m_Color );
+
+ if( aDrawInfo.m_PadClearance )
+ {
+ BuildPadPolygon( coord, wxSize( aDrawInfo.m_PadClearance,
+ aDrawInfo.m_PadClearance ), angle );
+ for( int ii = 0; ii < 4; ii++ )
+ coord[ii] += shape_pos;
+
+ GRClosedPoly( aClipBox, aDC, 4, coord, 0, aDrawInfo.m_Color, aDrawInfo.m_Color );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Draw the pad hole
+ wxPoint holepos = m_Pos - aDrawInfo.m_Offset;
+ int hole = m_Drill.x >> 1;
+
+ bool drawhole = hole > 0;
+
+ if( !aDrawInfo.m_ShowPadFilled && !aDrawInfo.m_ShowNotPlatedHole )
+ drawhole = false;
+
+ if( drawhole )
+ {
+ bool blackpenstate = false;
+
+ if( aDrawInfo.m_IsPrinting )
+ {
+ blackpenstate = GetGRForceBlackPenState();
+ GRForceBlackPen( false );
+ aDrawInfo.m_HoleColor = WHITE;
+ }
+ else
+ {
+ GRSetDrawMode( aDC, ( aDrawInfo.m_DrawMode != GR_XOR ) ? GR_COPY : GR_XOR );
+ }
+
+ EDA_COLOR_T hole_color = aDrawInfo.m_HoleColor;
+
+ if( aDrawInfo. m_ShowNotPlatedHole ) // Draw a specific hole color
+ hole_color = aDrawInfo.m_NPHoleColor;
+
+ switch( GetDrillShape() )
+ {
+ case PAD_DRILL_SHAPE_CIRCLE:
+ if( aDC->LogicalToDeviceXRel( hole ) > MIN_DRAW_WIDTH )
+ GRFilledCircle( aClipBox, aDC, holepos.x, holepos.y, hole, 0,
+ hole_color, hole_color );
+ break;
+
+ case PAD_DRILL_SHAPE_OBLONG:
+ {
+ wxPoint drl_start, drl_end;
+ GetOblongDrillGeometry( drl_start, drl_end, seg_width );
+ GRFilledSegment( aClipBox, aDC, holepos + drl_start,
+ holepos + drl_end, seg_width, hole_color );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if( aDrawInfo.m_IsPrinting )
+ GRForceBlackPen( blackpenstate );
+ }
+
+ GRSetDrawMode( aDC, aDrawInfo.m_DrawMode );
+
+ // Draw "No connect" ( / or \ or cross X ) if necessary
+ if( GetNetCode() == 0 && aDrawInfo.m_ShowNCMark )
+ {
+ int dx0 = std::min( halfsize.x, halfsize.y );
+ EDA_COLOR_T nc_color = BLUE;
+
+ if( m_layerMask[F_Cu] ) /* Draw \ */
+ GRLine( aClipBox, aDC, holepos.x - dx0, holepos.y - dx0,
+ holepos.x + dx0, holepos.y + dx0, 0, nc_color );
+
+ if( m_layerMask[B_Cu] ) // Draw /
+ GRLine( aClipBox, aDC, holepos.x + dx0, holepos.y - dx0,
+ holepos.x - dx0, holepos.y + dx0, 0, nc_color );
+ }
+
+ if( !aDrawInfo.m_IsPrinting )
+ GRSetDrawMode( aDC, ( aDrawInfo.m_DrawMode != GR_XOR ) ? GR_COPY : GR_XOR );
+
+ // Draw the pad number
+ if( !aDrawInfo.m_Display_padnum && !aDrawInfo.m_Display_netname )
+ return;
+
+ wxPoint tpos0 = shape_pos; // Position of the centre of text
+ wxPoint tpos = tpos0;
+ wxSize AreaSize; // size of text area, normalized to AreaSize.y < AreaSize.x
+ int shortname_len = 0;
+
+ if( aDrawInfo.m_Display_netname )
+ shortname_len = GetShortNetname().Len();
+
+ if( GetShape() == PAD_SHAPE_CIRCLE )
+ angle = 0;
+
+ AreaSize = m_Size;
+
+ if( m_Size.y > m_Size.x )
+ {
+ angle += 900;
+ AreaSize.x = m_Size.y;
+ AreaSize.y = m_Size.x;
+ }
+
+ if( shortname_len > 0 ) // if there is a netname, provides room to display this netname
+ {
+ AreaSize.y /= 2; // Text used only the upper area of the
+ // pad. The lower area displays the net name
+ tpos.y -= AreaSize.y / 2;
+ }
+
+ // Calculate the position of text, that is the middle point of the upper
+ // area of the pad
+ RotatePoint( &tpos, shape_pos, angle );
+
+ // Draw text with an angle between -90 deg and + 90 deg
+ double t_angle = angle;
+ NORMALIZE_ANGLE_90( t_angle );
+
+ /* Note: in next calculations, texte size is calculated for 3 or more
+ * chars. Of course, pads numbers and nets names can have less than 3
+ * chars. but after some tries, i found this is gives the best look
+ */
+ #define MIN_CHAR_COUNT 3
+ wxString buffer;
+
+ int tsize;
+ EDA_RECT* clipBox = aDrawInfo.m_DrawPanel?
+ aDrawInfo.m_DrawPanel->GetClipBox() : NULL;
+
+ if( aDrawInfo.m_Display_padnum )
+ {
+ StringPadName( buffer );
+ int numpad_len = buffer.Len();
+ numpad_len = std::max( numpad_len, MIN_CHAR_COUNT );
+
+ tsize = std::min( AreaSize.y, AreaSize.x / numpad_len );
+
+ if( aDC->LogicalToDeviceXRel( tsize ) >= MIN_TEXT_SIZE ) // Not drawable when size too small.
+ {
+ // tsize reserve room for marges and segments thickness
+ tsize = ( tsize * 7 ) / 10;
+ DrawGraphicHaloText( clipBox, aDC, tpos,
+ aDrawInfo.m_Color, BLACK, WHITE,
+ buffer, t_angle,
+ wxSize( tsize , tsize ), GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false );
+
+ }
+ }
+
+ // display the short netname, if exists
+ if( shortname_len == 0 )
+ return;
+
+ shortname_len = std::max( shortname_len, MIN_CHAR_COUNT );
+ tsize = std::min( AreaSize.y, AreaSize.x / shortname_len );
+
+ if( aDC->LogicalToDeviceXRel( tsize ) >= MIN_TEXT_SIZE ) // Not drawable in size too small.
+ {
+ tpos = tpos0;
+
+ if( aDrawInfo.m_Display_padnum )
+ tpos.y += AreaSize.y / 2;
+
+ RotatePoint( &tpos, shape_pos, angle );
+
+ // tsize reserve room for marges and segments thickness
+ tsize = ( tsize * 7 ) / 10;
+ DrawGraphicHaloText( clipBox, aDC, tpos,
+ aDrawInfo.m_Color, BLACK, WHITE,
+ GetShortNetname(), t_angle,
+ wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER,
+ GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false );
+ }
+}
+
+
+/**
+ * Function BuildSegmentFromOvalShape
+ * Has meaning only for OVAL (and ROUND) pads.
+ * Build an equivalent segment having the same shape as the OVAL shape,
+ * aSegStart and aSegEnd are the ending points of the equivalent segment of the shape
+ * aRotation is the asked rotation of the segment (usually m_Orient)
+ */
+int D_PAD::BuildSegmentFromOvalShape(wxPoint& aSegStart, wxPoint& aSegEnd,
+ double aRotation, const wxSize& aMargin) const
+{
+ int width;
+
+ if( m_Size.y < m_Size.x ) // Build an horizontal equiv segment
+ {
+ int delta = ( m_Size.x - m_Size.y ) / 2;
+ aSegStart.x = -delta - aMargin.x;
+ aSegStart.y = 0;
+ aSegEnd.x = delta + aMargin.x;
+ aSegEnd.y = 0;
+ width = m_Size.y + ( aMargin.y * 2 );
+ }
+ else // Vertical oval: build a vertical equiv segment
+ {
+ int delta = ( m_Size.y -m_Size.x ) / 2;
+ aSegStart.x = 0;
+ aSegStart.y = -delta - aMargin.y;
+ aSegEnd.x = 0;
+ aSegEnd.y = delta + aMargin.y;
+ width = m_Size.x + ( aMargin.x * 2 );
+ }
+
+ if( aRotation )
+ {
+ RotatePoint( &aSegStart, aRotation);
+ RotatePoint( &aSegEnd, aRotation);
+ }
+
+ return width;
+}
+
+
+void D_PAD::BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue,
+ double aRotation ) const
+{
+ wxSize delta;
+ wxSize halfsize;
+
+ halfsize.x = m_Size.x >> 1;
+ halfsize.y = m_Size.y >> 1;
+
+ switch( GetShape() )
+ {
+ case PAD_SHAPE_RECT:
+ // For rectangular shapes, inflate is easy
+ halfsize += aInflateValue;
+
+ // Verify if do not deflate more than than size
+ // Only possible for inflate negative values.
+ if( halfsize.x < 0 )
+ halfsize.x = 0;
+
+ if( halfsize.y < 0 )
+ halfsize.y = 0;
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ // Trapezoidal pad: verify delta values
+ delta.x = ( m_DeltaSize.x >> 1 );
+ delta.y = ( m_DeltaSize.y >> 1 );
+
+ // be sure delta values are not to large
+ if( (delta.x < 0) && (delta.x <= -halfsize.y) )
+ delta.x = -halfsize.y + 1;
+
+ if( (delta.x > 0) && (delta.x >= halfsize.y) )
+ delta.x = halfsize.y - 1;
+
+ if( (delta.y < 0) && (delta.y <= -halfsize.x) )
+ delta.y = -halfsize.x + 1;
+
+ if( (delta.y > 0) && (delta.y >= halfsize.x) )
+ delta.y = halfsize.x - 1;
+ break;
+
+ default: // is used only for rect and trap. pads
+ return;
+ }
+
+ // Build the basic rectangular or trapezoid shape
+ // delta is null for rectangular shapes
+ aCoord[0].x = -halfsize.x - delta.y; // lower left
+ aCoord[0].y = +halfsize.y + delta.x;
+
+ aCoord[1].x = -halfsize.x + delta.y; // upper left
+ aCoord[1].y = -halfsize.y - delta.x;
+
+ aCoord[2].x = +halfsize.x - delta.y; // upper right
+ aCoord[2].y = -halfsize.y + delta.x;
+
+ aCoord[3].x = +halfsize.x + delta.y; // lower right
+ aCoord[3].y = +halfsize.y - delta.x;
+
+ // Offsetting the trapezoid shape id needed
+ // It is assumed delta.x or/and delta.y == 0
+ if( GetShape() == PAD_SHAPE_TRAPEZOID && (aInflateValue.x != 0 || aInflateValue.y != 0) )
+ {
+ double angle;
+ wxSize corr;
+
+ if( delta.y ) // lower and upper segment is horizontal
+ {
+ // Calculate angle of left (or right) segment with vertical axis
+ angle = atan2( m_DeltaSize.y, m_Size.y );
+
+ // left and right sides are moved by aInflateValue.x in their perpendicular direction
+ // We must calculate the corresponding displacement on the horizontal axis
+ // that is delta.x +- corr.x depending on the corner
+ corr.x = KiROUND( tan( angle ) * aInflateValue.x );
+ delta.x = KiROUND( aInflateValue.x / cos( angle ) );
+
+ // Horizontal sides are moved up and down by aInflateValue.y
+ delta.y = aInflateValue.y;
+
+ // corr.y = 0 by the constructor
+ }
+ else if( delta.x ) // left and right segment is vertical
+ {
+ // Calculate angle of lower (or upper) segment with horizontal axis
+ angle = atan2( m_DeltaSize.x, m_Size.x );
+
+ // lower and upper sides are moved by aInflateValue.x in their perpendicular direction
+ // We must calculate the corresponding displacement on the vertical axis
+ // that is delta.y +- corr.y depending on the corner
+ corr.y = KiROUND( tan( angle ) * aInflateValue.y );
+ delta.y = KiROUND( aInflateValue.y / cos( angle ) );
+
+ // Vertical sides are moved left and right by aInflateValue.x
+ delta.x = aInflateValue.x;
+
+ // corr.x = 0 by the constructor
+ }
+ else // the trapezoid is a rectangle
+ {
+ delta = aInflateValue; // this pad is rectangular (delta null).
+ }
+
+ aCoord[0].x += -delta.x - corr.x; // lower left
+ aCoord[0].y += delta.y + corr.y;
+
+ aCoord[1].x += -delta.x + corr.x; // upper left
+ aCoord[1].y += -delta.y - corr.y;
+
+ aCoord[2].x += delta.x - corr.x; // upper right
+ aCoord[2].y += -delta.y + corr.y;
+
+ aCoord[3].x += delta.x + corr.x; // lower right
+ aCoord[3].y += delta.y - corr.y;
+
+ /* test coordinates and clamp them if the offset correction is too large:
+ * Note: if a coordinate is bad, the other "symmetric" coordinate is bad
+ * So when a bad coordinate is found, the 2 symmetric coordinates
+ * are set to the minimun value (0)
+ */
+
+ if( aCoord[0].x > 0 ) // lower left x coordinate must be <= 0
+ aCoord[0].x = aCoord[3].x = 0;
+
+ if( aCoord[1].x > 0 ) // upper left x coordinate must be <= 0
+ aCoord[1].x = aCoord[2].x = 0;
+
+ if( aCoord[0].y < 0 ) // lower left y coordinate must be >= 0
+ aCoord[0].y = aCoord[1].y = 0;
+
+ if( aCoord[3].y < 0 ) // lower right y coordinate must be >= 0
+ aCoord[3].y = aCoord[2].y = 0;
+ }
+
+ if( aRotation )
+ {
+ for( int ii = 0; ii < 4; ii++ )
+ RotatePoint( &aCoord[ii], aRotation );
+ }
+}
diff --git a/pcbnew/class_pcb_layer_box_selector.cpp b/pcbnew/class_pcb_layer_box_selector.cpp
new file mode 100644
index 0000000..ee02ba6
--- /dev/null
+++ b/pcbnew/class_pcb_layer_box_selector.cpp
@@ -0,0 +1,168 @@
+/**
+ * @file class_pcb_layer_box_selector.cpp
+ * @brief a derived class of LAYER_BOX_SELECTOR to handle the layer box selector
+ * in Pcbnew
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 Jean-Pierre Charras <jean-pierre.charras@ujf-grenoble.fr>
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include <common.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <class_board_design_settings.h>
+#include <colors_selection.h>
+#include <layers_id_colors_and_visibility.h>
+
+#include <class_board.h>
+#include <hotkeys.h>
+
+#include <class_pcb_layer_box_selector.h>
+
+// translate aLayer to its hotkey
+static int layer2hotkey_id( LAYER_ID aLayer )
+{
+ switch( aLayer )
+ {
+ case F_Cu: return HK_SWITCH_LAYER_TO_COMPONENT;
+
+ case B_Cu: return HK_SWITCH_LAYER_TO_COPPER;
+
+ case In1_Cu: return HK_SWITCH_LAYER_TO_INNER1;
+ case In2_Cu: return HK_SWITCH_LAYER_TO_INNER2;
+ case In3_Cu: return HK_SWITCH_LAYER_TO_INNER3;
+ case In4_Cu: return HK_SWITCH_LAYER_TO_INNER4;
+ case In5_Cu: return HK_SWITCH_LAYER_TO_INNER5;
+ case In6_Cu: return HK_SWITCH_LAYER_TO_INNER6;
+ case In7_Cu: return HK_SWITCH_LAYER_TO_INNER7;
+ case In8_Cu: return HK_SWITCH_LAYER_TO_INNER8;
+ case In9_Cu: return HK_SWITCH_LAYER_TO_INNER9;
+ case In10_Cu: return HK_SWITCH_LAYER_TO_INNER10;
+ case In11_Cu: return HK_SWITCH_LAYER_TO_INNER11;
+ case In12_Cu: return HK_SWITCH_LAYER_TO_INNER12;
+ case In13_Cu: return HK_SWITCH_LAYER_TO_INNER13;
+ case In14_Cu: return HK_SWITCH_LAYER_TO_INNER14;
+
+ default:
+ return -1;
+ }
+}
+
+
+// class to display a layer list in a wxBitmapComboBox.
+
+// Reload the Layers
+void PCB_LAYER_BOX_SELECTOR::Resync()
+{
+ Clear();
+
+ // Tray to fix a minimum width fot the BitmapComboBox
+ int minwidth = 80;
+
+ wxClientDC dc( GetParent() ); // The DC for "this" is not always initialized
+
+ const int BM_SIZE = 14;
+
+ LSET show = LSET::AllLayersMask() & ~m_layerMaskDisable;
+ LSET activated = getEnabledLayers() & ~m_layerMaskDisable;
+ wxString layerstatus;
+
+ for( LSEQ seq = show.UIOrder(); seq; ++seq )
+ {
+ LAYER_ID layerid = *seq;
+
+ if( !m_showNotEnabledBrdlayers && !activated[layerid] )
+ continue;
+ else if( !activated[layerid] )
+ layerstatus = wxT( " " ) + _( "(not activated)" );
+ else
+ layerstatus.Empty();
+
+ wxBitmap layerbmp( BM_SIZE, BM_SIZE );
+ SetBitmapLayer( layerbmp, layerid );
+
+ wxString layername = GetLayerName( layerid ) + layerstatus;
+
+ if( m_layerhotkeys && m_hotkeys )
+ {
+ int id = layer2hotkey_id( layerid );
+
+ if( id != -1 )
+ layername = AddHotkeyName( layername, m_hotkeys, id, IS_COMMENT );
+ }
+
+ Append( layername, layerbmp, (void*)(intptr_t) layerid );
+
+ int w, h;
+ dc.GetTextExtent ( layername, &w, &h );
+ minwidth = std::max( minwidth, w );
+ }
+
+ minwidth += BM_SIZE + 35; // Take in account the bitmap size and margins
+ SetMinSize( wxSize( minwidth, -1 ) );
+}
+
+
+// Returns true if the layer id is enabled (i.e. is it should be displayed)
+bool PCB_LAYER_BOX_SELECTOR::IsLayerEnabled( LAYER_NUM aLayer ) const
+{
+ wxASSERT( m_boardFrame != NULL );
+ BOARD* board = m_boardFrame->GetBoard();
+ wxASSERT( board != NULL );
+
+ return board->IsLayerEnabled( ToLAYER_ID( aLayer ) );
+}
+
+
+LSET PCB_LAYER_BOX_SELECTOR::getEnabledLayers() const
+{
+ wxASSERT( m_boardFrame != NULL );
+ BOARD* board = m_boardFrame->GetBoard();
+ wxASSERT( board != NULL );
+
+ return board->GetEnabledLayers();
+}
+
+
+// Returns a color index from the layer id
+EDA_COLOR_T PCB_LAYER_BOX_SELECTOR::GetLayerColor( LAYER_NUM aLayer ) const
+{
+ wxASSERT( m_boardFrame );
+ BOARD* board = m_boardFrame->GetBoard();
+ wxASSERT( board );
+
+ return board->GetLayerColor( ToLAYER_ID( aLayer ) );
+}
+
+
+// Returns the name of the layer id
+wxString PCB_LAYER_BOX_SELECTOR::GetLayerName( LAYER_NUM aLayer ) const
+{
+ wxASSERT( m_boardFrame );
+ BOARD* board = m_boardFrame->GetBoard();
+ wxASSERT( board );
+
+ return board->GetLayerName( ToLAYER_ID( aLayer ) );
+}
+
diff --git a/pcbnew/class_pcb_layer_box_selector.h b/pcbnew/class_pcb_layer_box_selector.h
new file mode 100644
index 0000000..196c891
--- /dev/null
+++ b/pcbnew/class_pcb_layer_box_selector.h
@@ -0,0 +1,105 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2015 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef CLASS_PCB_PCB_LAYER_BOX_SELECTOR_H
+#define CLASS_PCB_PCB_LAYER_BOX_SELECTOR_H 1
+
+#include <class_layer_box_selector.h>
+
+class PCB_BASE_FRAME;
+
+/**
+ * Class to display a pcb layer list in a wxBitmapComboBox.
+ */
+class PCB_LAYER_BOX_SELECTOR : public LAYER_BOX_SELECTOR
+{
+ PCB_BASE_FRAME* m_boardFrame;
+
+ LSET m_layerMaskDisable; // A mask to remove some (not allowed) layers
+ // from layer list
+ bool m_showNotEnabledBrdlayers; // true to list all allowed layers
+ // (with not activated layers flagged)
+
+public:
+ // Hotkey Info
+ EDA_HOTKEY_CONFIG* m_hotkeys;
+
+public:
+ // If you are thinking the constructor is a bit curious,
+ // just remember it is used by automatically generated by wxFormBuilder files,
+ // and it should mimic the wxBitmapComboBox constructor.
+ // Therefore, value, style are not yet used,
+ // but they are here for compatibility
+ PCB_LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id,
+ const wxString& value = wxEmptyString,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ int n = 0, const wxString choices[] = NULL, int style = 0 ) :
+ LAYER_BOX_SELECTOR( parent, id, pos, size, n, choices )
+ {
+ m_boardFrame = NULL;
+ m_hotkeys = NULL;
+ m_showNotEnabledBrdlayers = false;
+ }
+
+ // Accessors
+
+ // SetBoardFrame should be called after creating a PCB_LAYER_BOX_SELECTOR
+ // It is not passed through the constructor because when using wxFormBuilder
+ // we should use a constructor compatible with a wxBitmapComboBox
+ void SetBoardFrame( PCB_BASE_FRAME* aFrame ) { m_boardFrame = aFrame; };
+
+ // SetLayerSet allows disableing some layers, which are not
+ // shown in list
+ void SetLayerSet( LSET aMask ) { m_layerMaskDisable = aMask; }
+
+ // Reload the Layers names and bitmaps
+ // Virtual function
+ void Resync();
+
+ // Allow (or not) the layers not activated for the current board to be shown
+ // in layer selector. Not actavated layers are flagged
+ // ( "(not activated)" added to the layer name )
+ void ShowNonActivatedLayers( bool aShow )
+ {
+ m_showNotEnabledBrdlayers = aShow;
+ }
+
+private:
+ // Returns a color index from the layer id
+ // Virtual function
+ EDA_COLOR_T GetLayerColor( LAYER_NUM aLayer ) const;
+
+ // Returns true if the layer id is enabled (i.e. is it should be displayed)
+ // Virtual function
+ bool IsLayerEnabled( LAYER_NUM aLayer ) const;
+
+ // Returns the name of the layer id
+ // Virtual function
+ wxString GetLayerName( LAYER_NUM aLayer ) const;
+
+ LSET getEnabledLayers() const;
+};
+
+#endif // CLASS_PCB_PCB_LAYER_BOX_SELECTOR_H
diff --git a/pcbnew/class_pcb_layer_widget.cpp b/pcbnew/class_pcb_layer_widget.cpp
new file mode 100644
index 0000000..17d041f
--- /dev/null
+++ b/pcbnew/class_pcb_layer_widget.cpp
@@ -0,0 +1,528 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2015 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr
+ * Copyright (C) 2010-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2010-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/******************************************************/
+/* class_pcb_layer_widget.cpp - Pcbnew layers manager */
+/******************************************************/
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <class_draw_panel_gal.h>
+#include <view/view.h>
+#include <painter.h>
+
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <pcbstruct.h> // enum PCB_VISIBLE
+#include <layer_widget.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_pcb_layer_widget.h>
+
+#include <pcbnew.h>
+#include <collectors.h>
+#include <pcbnew_id.h>
+
+#include <gal/graphics_abstraction_layer.h>
+
+
+/// This is a read only template that is copied and modified before adding to LAYER_WIDGET
+const LAYER_WIDGET::ROW PCB_LAYER_WIDGET::s_render_rows[] = {
+
+#define RR LAYER_WIDGET::ROW // Render Row abbreviation to reduce source width
+
+ // text id color tooltip
+ RR( _( "Through Via" ), VIA_THROUGH_VISIBLE, WHITE, _( "Show through vias" ) ),
+ RR( _( "Bl/Buried Via" ), VIA_BBLIND_VISIBLE, WHITE, _( "Show blind or buried vias" ) ),
+ RR( _( "Micro Via" ), VIA_MICROVIA_VISIBLE, WHITE, _( "Show micro vias") ),
+ RR( _( "Non Plated" ), NON_PLATED_VISIBLE, WHITE, _( "Show non plated holes") ),
+ RR( _( "Ratsnest" ), RATSNEST_VISIBLE, WHITE, _( "Show unconnected nets as a ratsnest") ),
+
+ RR( _( "Pads Front" ), PAD_FR_VISIBLE, WHITE, _( "Show footprint pads on board's front" ) ),
+ RR( _( "Pads Back" ), PAD_BK_VISIBLE, WHITE, _( "Show footprint pads on board's back" ) ),
+
+ RR( _( "Text Front" ), MOD_TEXT_FR_VISIBLE, UNSPECIFIED_COLOR, _( "Show footprint text on board's front" ) ),
+ RR( _( "Text Back" ), MOD_TEXT_BK_VISIBLE, UNSPECIFIED_COLOR, _( "Show footprint text on board's back" ) ),
+ RR( _( "Hidden Text" ), MOD_TEXT_INVISIBLE, WHITE, _( "Show footprint text marked as invisible" ) ),
+
+ RR( _( "Anchors" ), ANCHOR_VISIBLE, WHITE, _( "Show footprint and text origins as a cross" ) ),
+ RR( _( "Grid" ), GRID_VISIBLE, WHITE, _( "Show the (x,y) grid dots" ) ),
+ RR( _( "No-Connects" ), NO_CONNECTS_VISIBLE, UNSPECIFIED_COLOR, _( "Show a marker on pads which have no net connected" ) ),
+ RR( _( "Footprints Front" ), MOD_FR_VISIBLE, UNSPECIFIED_COLOR, _( "Show footprints that are on board's front") ),
+ RR( _( "Footprints Back" ), MOD_BK_VISIBLE, UNSPECIFIED_COLOR, _( "Show footprints that are on board's back") ),
+ RR( _( "Values" ), MOD_VALUES_VISIBLE, UNSPECIFIED_COLOR, _( "Show footprint's values") ),
+ RR( _( "References" ), MOD_REFERENCES_VISIBLE, UNSPECIFIED_COLOR, _( "Show footprint's references") ),
+};
+
+static int s_allowed_in_FpEditor[] =
+{
+ MOD_TEXT_INVISIBLE, PAD_FR_VISIBLE, PAD_BK_VISIBLE,
+ GRID_VISIBLE, MOD_VALUES_VISIBLE, MOD_REFERENCES_VISIBLE
+};
+
+
+PCB_LAYER_WIDGET::PCB_LAYER_WIDGET( PCB_BASE_FRAME* aParent, wxWindow* aFocusOwner,
+ int aPointSize, bool aFpEditorMode ) :
+ LAYER_WIDGET( aParent, aFocusOwner, aPointSize ),
+ myframe( aParent )
+{
+ m_alwaysShowActiveCopperLayer = false;
+ m_fp_editor_mode = aFpEditorMode;
+ ReFillRender();
+
+ // Update default tabs labels
+ SetLayersManagerTabsText();
+
+ //-----<Popup menu>-------------------------------------------------
+ // handle the popup menu over the layer window.
+ m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN,
+ wxMouseEventHandler( PCB_LAYER_WIDGET::onRightDownLayers ), NULL, this );
+
+ // since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
+ // and not m_LayerScrolledWindow->Connect()
+ Connect( ID_SHOW_ALL_COPPERS, ID_ALWAYS_SHOW_NO_COPPERS_BUT_ACTIVE,
+ wxEVT_COMMAND_MENU_SELECTED,
+ wxCommandEventHandler( PCB_LAYER_WIDGET::onPopupSelection ), NULL, this );
+
+ // install the right click handler into each control at end of ReFill()
+ // using installRightLayerClickHandler
+}
+
+
+bool PCB_LAYER_WIDGET::isAllowedInFpMode( int aId )
+{
+ for( unsigned ii = 0; ii < DIM( s_allowed_in_FpEditor ); ii++ )
+ if( s_allowed_in_FpEditor[ii] == aId )
+ return true;
+
+ return false;
+}
+
+
+bool PCB_LAYER_WIDGET::isLayerAllowedInFpMode( LAYER_ID aLayer )
+{
+ static LSET allowed = LSET::AllTechMask();
+ // Currently not in use because putting a graphic item on a copper layer
+ // is not currently supported by DRC.
+ // allowed.set( F_Cu ).set( B_Cu );
+ return allowed.test( aLayer );
+}
+
+
+void PCB_LAYER_WIDGET::installRightLayerClickHandler()
+{
+ int rowCount = GetLayerRowCount();
+
+ for( int row=0; row < rowCount; ++row )
+ {
+ for( int col=0; col<LYR_COLUMN_COUNT; ++col )
+ {
+ wxWindow* w = getLayerComp( row, col );
+
+ w->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler(
+ PCB_LAYER_WIDGET::onRightDownLayers ), NULL, this );
+ }
+ }
+}
+
+
+void PCB_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event )
+{
+ wxMenu menu;
+
+ // menu text is capitalized:
+ // http://library.gnome.org/devel/hig-book/2.20/design-text-labels.html.en#layout-capitalization
+ menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_COPPERS,
+ _( "Show All Copper Layers" ) ) );
+ menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_COPPERS_BUT_ACTIVE,
+ _( "Hide All Copper Layers But Active" ) ) );
+ menu.Append( new wxMenuItem( &menu, ID_ALWAYS_SHOW_NO_COPPERS_BUT_ACTIVE,
+ _( "Always Hide All Copper Layers But Active" ) ) );
+ menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_COPPERS,
+ _( "Hide All Copper Layers" ) ) );
+
+ PopupMenu( &menu );
+
+ passOnFocus();
+}
+
+
+void PCB_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
+{
+ int rowCount;
+ int menuId = event.GetId();
+ bool visible;
+ bool force_active_layer_visible;
+
+ visible = menuId == ID_SHOW_ALL_COPPERS;
+ m_alwaysShowActiveCopperLayer = ( menuId == ID_ALWAYS_SHOW_NO_COPPERS_BUT_ACTIVE );
+ force_active_layer_visible = ( menuId == ID_SHOW_NO_COPPERS_BUT_ACTIVE ||
+ menuId == ID_ALWAYS_SHOW_NO_COPPERS_BUT_ACTIVE );
+
+ switch( menuId )
+ {
+ case ID_SHOW_ALL_COPPERS:
+ case ID_ALWAYS_SHOW_NO_COPPERS_BUT_ACTIVE:
+ case ID_SHOW_NO_COPPERS_BUT_ACTIVE:
+ case ID_SHOW_NO_COPPERS:
+ // Search the last copper layer row index:
+ int lastCu = -1;
+ rowCount = GetLayerRowCount();
+ for( int row = rowCount-1; row>=0; --row )
+ {
+ wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
+ LAYER_ID layer = ToLAYER_ID( getDecodedId( cb->GetId() ) );
+
+ if( IsCopperLayer( layer ) )
+ {
+ lastCu = row;
+ break;
+ }
+ }
+
+ // Enable/disable the copper layers visibility:
+ for( int row=0; row<rowCount; ++row )
+ {
+ wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
+ LAYER_ID layer = ToLAYER_ID( getDecodedId( cb->GetId() ) );
+
+ if( IsCopperLayer( layer ) )
+ {
+ bool loc_visible = visible;
+
+ if( force_active_layer_visible && (layer == myframe->GetActiveLayer() ) )
+ loc_visible = true;
+
+ cb->SetValue( loc_visible );
+
+ bool isLastCopperLayer = (row==lastCu);
+ OnLayerVisible( layer, loc_visible, isLastCopperLayer );
+
+ if( isLastCopperLayer )
+ break;
+ }
+ }
+ break;
+ }
+}
+
+
+void PCB_LAYER_WIDGET::SetLayersManagerTabsText()
+{
+ m_notebook->SetPageText( 0, _( "Layer" ) );
+ m_notebook->SetPageText( 1, _( "Render" ) );
+}
+
+
+void PCB_LAYER_WIDGET::ReFillRender()
+{
+ BOARD* board = myframe->GetBoard();
+ ClearRenderRows();
+
+ // Add "Render" tab rows to LAYER_WIDGET, after setting color and checkbox state.
+ // Because s_render_rows is created static, we must explicitly call
+ // wxGetTranslation for texts which are internationalized (tool tips
+ // and item names)
+ for( unsigned row=0; row<DIM(s_render_rows); ++row )
+ {
+ LAYER_WIDGET::ROW renderRow = s_render_rows[row];
+
+ if( m_fp_editor_mode && !isAllowedInFpMode( renderRow.id ) )
+ continue;
+
+ renderRow.tooltip = wxGetTranslation( s_render_rows[row].tooltip );
+ renderRow.rowName = wxGetTranslation( s_render_rows[row].rowName );
+
+ if( renderRow.color != -1 ) // does this row show a color?
+ {
+ // this window frame must have an established BOARD, i.e. after SetBoard()
+ renderRow.color = board->GetVisibleElementColor( renderRow.id );
+ }
+
+ renderRow.state = board->IsElementVisible( renderRow.id );
+
+ AppendRenderRow( renderRow );
+ }
+}
+
+
+void PCB_LAYER_WIDGET::SyncRenderStates()
+{
+ BOARD* board = myframe->GetBoard();
+
+ for( unsigned row=0; row<DIM(s_render_rows); ++row )
+ {
+ int rowId = s_render_rows[row].id;
+
+ if( m_fp_editor_mode && !isAllowedInFpMode( rowId ) )
+ continue;
+
+ // this does not fire a UI event
+ SetRenderState( rowId, board->IsElementVisible( rowId ) );
+ }
+}
+
+
+void PCB_LAYER_WIDGET::SyncLayerVisibilities()
+{
+ BOARD* board = myframe->GetBoard();
+ int count = GetLayerRowCount();
+
+ for( int row=0; row<count; ++row )
+ {
+ // this utilizes more implementation knowledge than ideal, eventually
+ // add member ROW getRow() or similar to base LAYER_WIDGET.
+
+ wxWindow* w = getLayerComp( row, COLUMN_ICON_ACTIVE );
+
+ LAYER_ID layerId = ToLAYER_ID( getDecodedId( w->GetId() ) );
+
+ // this does not fire a UI event
+ SetLayerVisible( layerId, board->IsLayerVisible( layerId ) );
+ }
+}
+
+
+void PCB_LAYER_WIDGET::ReFill()
+{
+ BOARD* brd = myframe->GetBoard();
+ LSET enabled = brd->GetEnabledLayers();
+
+ ClearLayerRows();
+
+ wxString dsc;
+
+ // show all coppers first, with front on top, back on bottom, then technical layers
+ for( LSEQ cu_stack = enabled.CuStack(); cu_stack; ++cu_stack )
+ {
+ LAYER_ID layer = *cu_stack;
+
+ switch( layer )
+ {
+ case F_Cu:
+ dsc = _( "Front copper layer" );
+ break;
+
+ case B_Cu:
+ dsc = _( "Back copper layer" );
+ break;
+
+ default:
+ dsc = _( "Inner copper layer" );
+ break;
+ }
+
+ AppendLayerRow( LAYER_WIDGET::ROW(
+ brd->GetLayerName( layer ), layer, brd->GetLayerColor( layer ),
+ dsc, true ) );
+
+ if( m_fp_editor_mode && !isLayerAllowedInFpMode( layer ) )
+ {
+ getLayerComp( GetLayerRowCount()-1, COLUMN_COLOR_LYRNAME )->Enable( false );
+ getLayerComp( GetLayerRowCount()-1,
+ COLUMN_COLORBM )->SetToolTip( wxEmptyString );
+ }
+ }
+
+
+ // technical layers are shown in this order:
+ // Because they are static, wxGetTranslation must be explicitly
+ // called for tooltips.
+ static const struct {
+ LAYER_ID layerId;
+ wxString tooltip;
+ } non_cu_seq[] = {
+ { F_Adhes, _( "Adhesive on board's front" ) },
+ { B_Adhes, _( "Adhesive on board's back" ) },
+ { F_Paste, _( "Solder paste on board's front" ) },
+ { B_Paste, _( "Solder paste on board's back" ) },
+ { F_SilkS, _( "Silkscreen on board's front" ) },
+ { B_SilkS, _( "Silkscreen on board's back" ) },
+ { F_Mask, _( "Solder mask on board's front" ) },
+ { B_Mask, _( "Solder mask on board's back" ) },
+ { Dwgs_User, _( "Explanatory drawings" ) },
+ { Cmts_User, _( "Explanatory comments" ) },
+ { Eco1_User, _( "User defined meaning" ) },
+ { Eco2_User, _( "User defined meaning" ) },
+ { Edge_Cuts, _( "Board's perimeter definition" ) },
+ { Margin, _( "Board's edge setback outline" ) },
+ { F_CrtYd, _( "Footprint courtyards on board's front" ) },
+ { B_CrtYd, _( "Footprint courtyards on board's back" ) },
+ { F_Fab, _( "Footprint assembly on board's front" ) },
+ { B_Fab, _( "Footprint assembly on board's back" ) }
+ };
+
+ for( unsigned i=0; i<DIM( non_cu_seq ); ++i )
+ {
+ LAYER_ID layer = non_cu_seq[i].layerId;
+
+ if( !enabled[layer] )
+ continue;
+
+ AppendLayerRow( LAYER_WIDGET::ROW(
+ brd->GetLayerName( layer ), layer, brd->GetLayerColor( layer ),
+ wxGetTranslation( non_cu_seq[i].tooltip ), true ) );
+
+ if( m_fp_editor_mode && !isLayerAllowedInFpMode( layer ) )
+ {
+ getLayerComp( GetLayerRowCount()-1, COLUMN_COLOR_LYRNAME )->Enable( false );
+ getLayerComp( GetLayerRowCount()-1,
+ COLUMN_COLORBM )->SetToolTip( wxEmptyString );
+ }
+ }
+
+ installRightLayerClickHandler();
+}
+
+
+//-----<LAYER_WIDGET callbacks>-------------------------------------------
+
+void PCB_LAYER_WIDGET::OnLayerColorChange( int aLayer, EDA_COLOR_T aColor )
+{
+ myframe->GetBoard()->SetLayerColor( ToLAYER_ID( aLayer ), aColor );
+
+ if( myframe->IsGalCanvasActive() )
+ {
+ KIGFX::VIEW* view = myframe->GetGalCanvas()->GetView();
+ view->GetPainter()->GetSettings()->ImportLegacyColors( myframe->GetBoard()->GetColorsSettings() );
+ view->UpdateLayerColor( aLayer );
+ }
+
+ myframe->GetCanvas()->Refresh();
+}
+
+
+bool PCB_LAYER_WIDGET::OnLayerSelect( int aLayer )
+{
+ // the layer change from the PCB_LAYER_WIDGET can be denied by returning
+ // false from this function.
+ LAYER_ID layer = ToLAYER_ID( aLayer );
+
+ if( m_fp_editor_mode && !isLayerAllowedInFpMode( layer ) )
+ return false;
+
+ myframe->SetActiveLayer( layer );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)myframe->GetDisplayOptions();
+
+ if( m_alwaysShowActiveCopperLayer )
+ OnLayerSelected();
+ else if( displ_opts->m_ContrastModeDisplay )
+ myframe->GetCanvas()->Refresh();
+
+ return true;
+}
+
+
+bool PCB_LAYER_WIDGET::OnLayerSelected()
+{
+ if( !m_alwaysShowActiveCopperLayer )
+ return false;
+
+ // postprocess after an active layer selection
+ // ensure active layer visible
+ wxCommandEvent event;
+ event.SetId( ID_ALWAYS_SHOW_NO_COPPERS_BUT_ACTIVE );
+ onPopupSelection( event );
+
+ return true;
+}
+
+
+void PCB_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal )
+{
+ BOARD* brd = myframe->GetBoard();
+
+ LSET visibleLayers = brd->GetVisibleLayers();
+
+ visibleLayers.set( aLayer, isVisible );
+
+ brd->SetVisibleLayers( visibleLayers );
+
+ EDA_DRAW_PANEL_GAL* galCanvas = myframe->GetGalCanvas();
+
+ if( galCanvas )
+ {
+ KIGFX::VIEW* view = galCanvas->GetView();
+ view->SetLayerVisible( aLayer, isVisible );
+ view->RecacheAllItems( true );
+ }
+
+ if( isFinal )
+ myframe->GetCanvas()->Refresh();
+}
+
+
+void PCB_LAYER_WIDGET::OnRenderColorChange( int aId, EDA_COLOR_T aColor )
+{
+ myframe->GetBoard()->SetVisibleElementColor( aId, aColor );
+
+ if( myframe->GetGalCanvas() )
+ {
+ KIGFX::VIEW* view = myframe->GetGalCanvas()->GetView();
+ view->GetPainter()->GetSettings()->ImportLegacyColors( myframe->GetBoard()->GetColorsSettings() );
+ view->UpdateLayerColor( aId );
+ }
+
+ myframe->GetCanvas()->Refresh();
+}
+
+
+void PCB_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
+{
+ BOARD* brd = myframe->GetBoard();
+
+ LSET visibleLayers = brd->GetVisibleLayers();
+ visibleLayers.set( aId, isEnabled );
+
+ // The layer visibility status is saved in the board file so set the board modified
+ // state so the user has the option to save the changes.
+ if( brd->IsElementVisible( aId ) != isEnabled )
+ myframe->OnModify();
+
+ brd->SetElementVisibility( aId, isEnabled );
+
+ EDA_DRAW_PANEL_GAL* galCanvas = myframe->GetGalCanvas();
+
+ if( galCanvas )
+ {
+ if( aId == GRID_VISIBLE )
+ {
+ galCanvas->GetGAL()->SetGridVisibility( myframe->IsGridVisible() );
+ galCanvas->GetView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
+ }
+ else
+ galCanvas->GetView()->SetLayerVisible( ITEM_GAL_LAYER( aId ), isEnabled );
+ }
+
+ if( galCanvas && myframe->IsGalCanvasActive() )
+ galCanvas->Refresh();
+ else
+ myframe->GetCanvas()->Refresh();
+}
+
+//-----</LAYER_WIDGET callbacks>------------------------------------------
diff --git a/pcbnew/class_pcb_layer_widget.h b/pcbnew/class_pcb_layer_widget.h
new file mode 100644
index 0000000..7908d80
--- /dev/null
+++ b/pcbnew/class_pcb_layer_widget.h
@@ -0,0 +1,158 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2015 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2010-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/************************************************************/
+/* class_pcb_layer_widget.h : header for the layers manager */
+/************************************************************/
+
+#ifndef CLASS_PCB_LAYER_WIDGET_H_
+#define CLASS_PCB_LAYER_WIDGET_H_
+
+#include <layer_widget.h>
+
+/**
+ * Class PCB_LAYER_WIDGET
+ * is here to implement the abstract functions of LAYER_WIDGET so they
+ * may be tied into the PCB_EDIT_FRAME's data and so we can add a popup
+ * menu which is specific to PCBNEW's needs.
+ */
+class PCB_LAYER_WIDGET : public LAYER_WIDGET
+{
+public:
+
+ /**
+ * Constructor
+ * @param aParent is the parent window
+ * @param aFocusOwner is the window that should be sent the focus after
+ * @param aPointSize is the font point size to use within the widget. This
+ * effectively sets the overall size of the widget via the row height and bitmap
+ * button sizes.
+ * @param aFpEditorMode false for the board editor (default), true for fp editor
+ * when true, some options or layers which cannot be used in editor mode are not
+ * displayed
+ */
+ PCB_LAYER_WIDGET( PCB_BASE_FRAME* aParent, wxWindow* aFocusOwner,
+ int aPointSize = 10, bool aFpEditorMode = false );
+
+ void ReFill();
+
+ /**
+ * Function ReFillRender
+ * rebuilds Render for instance after the config is read
+ */
+ void ReFillRender();
+
+ /**
+ * Function SyncRenderStates
+ * updates the checkboxes (checked or not) to be consistent with the current state
+ * of the visibility of the visible rendering elements.
+ */
+ void SyncRenderStates();
+
+ /**
+ * Function SyncLayerVisibilities
+ * updates each "Layer" checkbox in this layer widget according
+ * to each layer's current visibility determined by IsLayerVisible(), and is
+ * helpful immediately after loading a BOARD which may have state information in it.
+ */
+ void SyncLayerVisibilities();
+
+ /**
+ * Function SetLayersManagerTabsText
+ * Update the layer manager tabs labels
+ * Useful when changing Language or to set labels to a non default value
+ */
+ void SetLayersManagerTabsText();
+
+ //-----<implement LAYER_WIDGET abstract callback functions>-----------
+ void OnLayerColorChange( int aLayer, EDA_COLOR_T aColor );
+ bool OnLayerSelect( int aLayer );
+ void OnLayerVisible( int aLayer, bool isVisible, bool isFinal );
+ void OnRenderColorChange( int aId, EDA_COLOR_T aColor );
+ void OnRenderEnable( int aId, bool isEnabled );
+ //-----</implement LAYER_WIDGET abstract callback functions>----------
+
+ /**
+ * Function OnLayerSelected
+ * ensure the active layer is visible, and other layers not visible
+ * when m_alwaysShowActiveLayer is true
+ * Otherwise do nothing.
+ * @return true m_alwaysShowActiveLayer is true and the canvas is refreshed,
+ * and false if do nothing
+ */
+ bool OnLayerSelected(); // postprocess after an active layer selection
+ // ensure active layer visible if
+ // m_alwaysShowActiveCopperLayer is true;
+
+
+protected:
+
+ static const LAYER_WIDGET::ROW s_render_rows[];
+ bool m_alwaysShowActiveCopperLayer; // If true: Only shows the current active layer
+ // even if it is changed
+ bool m_fp_editor_mode;
+
+ PCB_BASE_FRAME* myframe;
+
+ // popup menu ids.
+#define ID_SHOW_ALL_COPPERS wxID_HIGHEST
+#define ID_SHOW_NO_COPPERS (wxID_HIGHEST+1)
+#define ID_SHOW_NO_COPPERS_BUT_ACTIVE (wxID_HIGHEST+2)
+#define ID_ALWAYS_SHOW_NO_COPPERS_BUT_ACTIVE (wxID_HIGHEST+3)
+
+ /**
+ * Function isAllowedInFpMode
+ * @return true if item aId has meaning in footprint editor mode.
+ * and therefore is shown in render panel
+ */
+ bool isAllowedInFpMode( int aId );
+
+ /**
+ * Function isLayerAllowedInFpMode
+ *
+ * User layers, which are not paired, are not shown in layers manager. However a not
+ * listed layer can be reachable in the graphic item properties dialog.
+ *
+ * @param aLayer is the layer id to test
+ * @return true if LAYER_ID aLayer has meaning in footprint editor mode.
+ * and therefore is shown in render panel
+ */
+ bool isLayerAllowedInFpMode( LAYER_ID aLayer );
+
+ /**
+ * Function OnRightDownLayers
+ * puts up a popup menu for the layer panel.
+ */
+ void onRightDownLayers( wxMouseEvent& event );
+
+ void onPopupSelection( wxCommandEvent& event );
+
+ /// this is for the popup menu, the right click handler has to be installed
+ /// on every child control within the layer panel.
+ void installRightLayerClickHandler();
+};
+
+#endif // CLASS_PCB_LAYER_WIDGET_H_
diff --git a/pcbnew/class_pcb_text.cpp b/pcbnew/class_pcb_text.cpp
new file mode 100644
index 0000000..c2e5ca6
--- /dev/null
+++ b/pcbnew/class_pcb_text.cpp
@@ -0,0 +1,202 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_pcb_text.cpp
+ * @brief Class TEXTE_PCB texts on copper or technical layers implementation
+ */
+
+#include <fctsys.h>
+#include <wxstruct.h>
+#include <gr_basic.h>
+#include <base_struct.h>
+#include <drawtxt.h>
+#include <kicad_string.h>
+#include <trigo.h>
+#include <colors_selection.h>
+#include <richio.h>
+#include <class_drawpanel.h>
+#include <macros.h>
+#include <wxBasePcbFrame.h>
+#include <msgpanel.h>
+#include <base_units.h>
+
+#include <class_board.h>
+#include <class_pcb_text.h>
+
+
+TEXTE_PCB::TEXTE_PCB( BOARD_ITEM* parent ) :
+ BOARD_ITEM( parent, PCB_TEXT_T ),
+ EDA_TEXT()
+{
+ m_MultilineAllowed = true;
+}
+
+
+TEXTE_PCB:: ~TEXTE_PCB()
+{
+}
+
+
+void TEXTE_PCB::Copy( TEXTE_PCB* source )
+{
+ m_Parent = source->m_Parent;
+ Pback = Pnext = NULL;
+ m_Mirror = source->m_Mirror;
+ m_Size = source->m_Size;
+ m_Orient = source->m_Orient;
+ m_Pos = source->m_Pos;
+ m_Layer = source->m_Layer;
+ m_Thickness = source->m_Thickness;
+ m_Attributs = source->m_Attributs;
+ m_Italic = source->m_Italic;
+ m_Bold = source->m_Bold;
+ m_HJustify = source->m_HJustify;
+ m_VJustify = source->m_VJustify;
+ m_MultilineAllowed = source->m_MultilineAllowed;
+
+ m_Text = source->m_Text;
+}
+
+
+void TEXTE_PCB::Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
+ GR_DRAWMODE DrawMode, const wxPoint& offset )
+{
+ BOARD* brd = GetBoard();
+
+ if( brd->IsLayerVisible( m_Layer ) == false )
+ return;
+
+ EDA_COLOR_T color = brd->GetLayerColor( m_Layer );
+
+ EDA_DRAW_MODE_T fillmode = FILLED;
+ DISPLAY_OPTIONS* displ_opts =
+ panel ? (DISPLAY_OPTIONS*)panel->GetDisplayOptions() : NULL;
+
+ if( displ_opts && displ_opts->m_DisplayDrawItemsFill == SKETCH )
+ fillmode = SKETCH;
+
+ // shade text if high contrast mode is active
+ if( ( DrawMode & GR_ALLOW_HIGHCONTRAST ) && displ_opts && displ_opts->m_ContrastModeDisplay )
+ {
+ LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
+
+ if( !IsOnLayer( curr_layer ) )
+ ColorTurnToDarkDarkGray( &color );
+ }
+
+ EDA_COLOR_T anchor_color = UNSPECIFIED_COLOR;
+
+ if( brd->IsElementVisible( ANCHOR_VISIBLE ) )
+ anchor_color = brd->GetVisibleElementColor( ANCHOR_VISIBLE );
+
+ EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL;
+ EDA_TEXT::Draw( clipbox, DC, offset, color,
+ DrawMode, fillmode, anchor_color );
+
+ // Enable these line to draw the bounding box (debug tests purposes only)
+#if 0
+ {
+ EDA_RECT BoundaryBox = GetBoundingBox();
+ GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
+ }
+#endif
+}
+
+
+void TEXTE_PCB::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString msg;
+
+ wxCHECK_RET( m_Parent != NULL, wxT( "TEXTE_PCB::GetMsgPanelInfo() m_Parent is NULL." ) );
+
+ if( m_Parent->Type() == PCB_DIMENSION_T )
+ aList.push_back( MSG_PANEL_ITEM( _( "Dimension" ), GetShownText(), DARKGREEN ) );
+ else
+ aList.push_back( MSG_PANEL_ITEM( _( "PCB Text" ), GetShownText(), DARKGREEN ) );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), GetLayerName(), BLUE ) );
+
+ if( !m_Mirror )
+ aList.push_back( MSG_PANEL_ITEM( _( "Mirror" ), _( "No" ), DARKGREEN ) );
+ else
+ aList.push_back( MSG_PANEL_ITEM( _( "Mirror" ), _( "Yes" ), DARKGREEN ) );
+
+ msg.Printf( wxT( "%.1f" ), m_Orient / 10.0 );
+ aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), msg, DARKGREEN ) );
+
+ msg = ::CoordinateToString( m_Thickness );
+ aList.push_back( MSG_PANEL_ITEM( _( "Thickness" ), msg, MAGENTA ) );
+
+ msg = ::CoordinateToString( m_Size.x );
+ aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, RED ) );
+
+ msg = ::CoordinateToString( m_Size.y );
+ aList.push_back( MSG_PANEL_ITEM( _( "Height" ), msg, RED ) );
+}
+
+const EDA_RECT TEXTE_PCB::GetBoundingBox() const
+{
+ EDA_RECT rect = GetTextBox( -1, -1 );
+
+ if( m_Orient )
+ rect = rect.GetBoundingBoxRotated( m_Pos, m_Orient );
+
+ return rect;
+}
+
+
+void TEXTE_PCB::Rotate( const wxPoint& aRotCentre, double aAngle )
+{
+ RotatePoint( &m_Pos, aRotCentre, aAngle );
+ m_Orient += aAngle;
+ NORMALIZE_ANGLE_360( m_Orient );
+}
+
+
+void TEXTE_PCB::Flip(const wxPoint& aCentre )
+{
+ m_Pos.y = aCentre.y - ( m_Pos.y - aCentre.y );
+ int copperLayerCount = GetBoard()->GetCopperLayerCount();
+ SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
+ m_Mirror = !m_Mirror;
+}
+
+
+wxString TEXTE_PCB::GetSelectMenuText() const
+{
+ wxString text;
+
+ text.Printf( _( "Pcb Text \"%s\" on %s"),
+ GetChars ( ShortenedShownText() ), GetChars( GetLayerName() ) );
+
+ return text;
+}
+
+
+EDA_ITEM* TEXTE_PCB::Clone() const
+{
+ return new TEXTE_PCB( *this );
+}
diff --git a/pcbnew/class_pcb_text.h b/pcbnew/class_pcb_text.h
new file mode 100644
index 0000000..b1f1d31
--- /dev/null
+++ b/pcbnew/class_pcb_text.h
@@ -0,0 +1,148 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_pcb_text.h
+ * @brief TEXTE_PCB class definition.
+ */
+
+#ifndef CLASS_PCB_TEXT_H
+#define CLASS_PCB_TEXT_H
+
+#include <eda_text.h>
+#include <class_board_item.h>
+#include <PolyLine.h>
+
+
+class LINE_READER;
+class EDA_DRAW_PANEL;
+class MSG_PANEL_ITEM;
+
+
+class TEXTE_PCB : public BOARD_ITEM, public EDA_TEXT
+{
+public:
+ TEXTE_PCB( BOARD_ITEM* parent );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~TEXTE_PCB();
+
+ static inline bool ClassOf( const EDA_ITEM* aItem )
+ {
+ return aItem && PCB_TEXT_T == aItem->Type();
+ }
+
+ virtual const wxPoint& GetPosition() const
+ {
+ return m_Pos;
+ }
+
+ virtual void SetPosition( const wxPoint& aPos )
+ {
+ m_Pos = aPos;
+ }
+
+ void Move( const wxPoint& aMoveVector )
+ {
+ m_Pos += aMoveVector;
+ }
+
+ void Rotate( const wxPoint& aRotCentre, double aAngle );
+
+ void Flip( const wxPoint& aCentre );
+
+ /* duplicate structure */
+ void Copy( TEXTE_PCB* source );
+
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
+ GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset );
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ bool HitTest( const wxPoint& aPosition ) const
+ {
+ return TextHitTest( aPosition );
+ }
+
+ /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
+ * bool aContained = true, int aAccuracy ) const
+ */
+ bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const
+ {
+ return TextHitTest( aRect, aContained, aAccuracy );
+ }
+
+ wxString GetClass() const
+ {
+ return wxT( "PTEXT" );
+ }
+
+ /**
+ * Function TransformBoundingBoxWithClearanceToPolygon
+ * Convert the text bounding box to a rectangular polygon
+ * depending on the text orientation, the bounding box
+ * is not always horizontal or vertical
+ * Used in filling zones calculations
+ * Circles and arcs are approximated by segments
+ * @param aCornerBuffer = a buffer to store the polygon
+ * @param aClearanceValue = the clearance around the text bounding box
+ * to the real clearance value (usually near from 1.0)
+ */
+ void TransformBoundingBoxWithClearanceToPolygon(
+ SHAPE_POLY_SET& aCornerBuffer,
+ int aClearanceValue ) const;
+
+ /**
+ * Function TransformShapeWithClearanceToPolygonSet
+ * Convert the text shape to a set of polygons (one by segment)
+ * Used in 3D viewer
+ * Circles and arcs are approximated by segments
+ * @param aCornerBuffer = a buffer to store the polygon
+ * @param aClearanceValue = the clearance around the text
+ * @param aCircleToSegmentsCount = the number of segments to approximate a circle
+ * @param aCorrectionFactor = the correction to apply to circles radius to keep
+ * clearance when the circle is approximated by segment bigger or equal
+ * to the real clearance value (usually near from 1.0)
+ */
+ void TransformShapeWithClearanceToPolygonSet( SHAPE_POLY_SET& aCornerBuffer,
+ int aClearanceValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor ) const;
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return add_text_xpm; }
+
+ // Virtual function
+ const EDA_RECT GetBoundingBox() const;
+
+ EDA_ITEM* Clone() const;
+
+#if defined(DEBUG)
+ virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+};
+
+#endif // #define CLASS_PCB_TEXT_H
diff --git a/pcbnew/class_text_mod.cpp b/pcbnew/class_text_mod.cpp
new file mode 100644
index 0000000..a51963f
--- /dev/null
+++ b/pcbnew/class_text_mod.cpp
@@ -0,0 +1,550 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_module.cpp
+ * @brief TEXT_MODULE class implementation.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <wxstruct.h>
+#include <trigo.h>
+#include <class_drawpanel.h>
+#include <drawtxt.h>
+#include <kicad_string.h>
+#include <colors_selection.h>
+#include <richio.h>
+#include <macros.h>
+#include <wxBasePcbFrame.h>
+#include <msgpanel.h>
+#include <base_units.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <pcbnew.h>
+
+
+TEXTE_MODULE::TEXTE_MODULE( MODULE* parent, TEXT_TYPE text_type ) :
+ BOARD_ITEM( parent, PCB_MODULE_TEXT_T ),
+ EDA_TEXT()
+{
+ MODULE* module = static_cast<MODULE*>( m_Parent );
+
+ m_Type = text_type;
+ m_NoShow = false;
+ // Set text tickness to a default value
+ m_Thickness = Millimeter2iu( 0.15 );
+ SetLayer( F_SilkS );
+
+ // Set position and give a default layer if a valid parent footprint exists
+ if( module && ( module->Type() == PCB_MODULE_T ) )
+ {
+ m_Pos = module->GetPosition();
+
+ if( IsBackLayer( module->GetLayer() ) )
+ {
+ SetLayer( B_SilkS );
+ m_Mirror = true;
+ }
+ }
+
+ SetDrawCoord();
+}
+
+
+TEXTE_MODULE::~TEXTE_MODULE()
+{
+}
+
+
+void TEXTE_MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
+{
+ // Used in footprint edition
+ // Note also in module editor, m_Pos0 = m_Pos
+ RotatePoint( &m_Pos, aRotCentre, aAngle );
+ SetOrientation( GetOrientation() + aAngle );
+ SetLocalCoord();
+}
+
+
+void TEXTE_MODULE::Flip( const wxPoint& aCentre )
+{
+ // flipping the footprint is relative to the X axis
+ MIRROR( m_Pos.y, aCentre.y );
+ NEGATE_AND_NORMALIZE_ANGLE_POS( m_Orient );
+ SetLayer( FlipLayer( GetLayer() ) );
+ m_Mirror = IsBackLayer( GetLayer() );
+ SetLocalCoord();
+}
+
+
+void TEXTE_MODULE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis )
+{
+ // Used in modedit, to transform the footprint
+ // the mirror is around the Y axis or X axis if aMirrorAroundXAxis = true
+ // the position is mirrored, but the text itself is not mirrored
+ if( aMirrorAroundXAxis )
+ MIRROR( m_Pos.y, aCentre.y );
+ else
+ MIRROR( m_Pos.x, aCentre.x );
+
+ NEGATE_AND_NORMALIZE_ANGLE_POS( m_Orient );
+ SetLocalCoord();
+}
+
+
+void TEXTE_MODULE::Move( const wxPoint& aMoveVector )
+{
+ m_Pos += aMoveVector;
+ SetLocalCoord();
+}
+
+void TEXTE_MODULE::Copy( TEXTE_MODULE* source )
+{
+ if( source == NULL )
+ return;
+
+ m_Pos = source->m_Pos;
+ SetLayer( source->GetLayer() );
+
+ m_Mirror = source->m_Mirror;
+ m_NoShow = source->m_NoShow;
+ m_Type = source->m_Type;
+ m_Orient = source->m_Orient;
+ m_Pos0 = source->m_Pos0;
+ m_Size = source->m_Size;
+ m_Thickness = source->m_Thickness;
+ m_Italic = source->m_Italic;
+ m_Bold = source->m_Bold;
+ m_Text = source->m_Text;
+}
+
+
+int TEXTE_MODULE::GetLength() const
+{
+ return m_Text.Len();
+}
+
+
+void TEXTE_MODULE::SetDrawCoord()
+{
+ const MODULE* module = static_cast<const MODULE*>( m_Parent );
+
+ m_Pos = m_Pos0;
+
+ if( module )
+ {
+ double angle = module->GetOrientation();
+
+ RotatePoint( &m_Pos.x, &m_Pos.y, angle );
+ m_Pos += module->GetPosition();
+ }
+}
+
+
+void TEXTE_MODULE::SetLocalCoord()
+{
+ const MODULE* module = static_cast<const MODULE*>( m_Parent );
+
+ if( module )
+ {
+ m_Pos0 = m_Pos - module->GetPosition();
+ double angle = module->GetOrientation();
+ RotatePoint( &m_Pos0.x, &m_Pos0.y, -angle );
+ }
+ else
+ {
+ m_Pos0 = m_Pos;
+ }
+}
+
+
+bool TEXTE_MODULE::HitTest( const wxPoint& aPosition ) const
+{
+ wxPoint rel_pos;
+ EDA_RECT area = GetTextBox( -1, -1 );
+
+ /* Rotate refPos to - angle to test if refPos is within area (which
+ * is relative to an horizontal text)
+ */
+ rel_pos = aPosition;
+ RotatePoint( &rel_pos, m_Pos, -GetDrawRotation() );
+
+ if( area.Contains( rel_pos ) )
+ return true;
+
+ return false;
+}
+
+
+/*
+ * Function GetBoundingBox (virtual)
+ * returns the bounding box of this Text (according to text and footprint
+ * orientation)
+ */
+const EDA_RECT TEXTE_MODULE::GetBoundingBox() const
+{
+ double angle = GetDrawRotation();
+ EDA_RECT text_area = GetTextBox( -1, -1 );
+
+ if( angle )
+ text_area = text_area.GetBoundingBoxRotated( m_Pos, angle );
+
+ return text_area;
+}
+
+
+/**
+ * Function Draw
+ * Draw the text according to the footprint pos and orient
+ * @param panel = draw panel, Used to know the clip box
+ * @param DC = Current Device Context
+ * @param offset = draw offset (usually wxPoint(0,0)
+ * @param draw_mode = GR_OR, GR_XOR..
+ */
+void TEXTE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
+ const wxPoint& offset )
+{
+ if( panel == NULL )
+ return;
+
+ /* parent must *not* be NULL (a footprint text without a footprint
+ parent has no sense) */
+ wxASSERT( m_Parent );
+
+ BOARD* brd = GetBoard( );
+ EDA_COLOR_T color = brd->GetLayerColor( GetLayer() );
+
+ /* For reference and value suppress the element if the layer it is
+ * on is on a disabled side, user text also has standard layer
+ * hiding.
+ * If the whole module side is disabled this isn't even called */
+ LAYER_ID text_layer = GetLayer();
+
+ if( (IsFrontLayer( text_layer ) && !brd->IsElementVisible( MOD_TEXT_FR_VISIBLE )) ||
+ (IsBackLayer( text_layer ) && !brd->IsElementVisible( MOD_TEXT_BK_VISIBLE )) )
+ return;
+
+ // text which are not ref or value are shown only if the layer is visible
+ // ref or value have a specific display option
+ if( GetType() == TEXT_is_DIVERS && ! brd->IsLayerVisible( m_Layer ) )
+ return;
+
+ // Invisible texts are still drawn (not plotted) in MOD_TEXT_INVISIBLE
+ // Just because we must have to edit them (at least to make them visible)
+ if( m_NoShow )
+ {
+ if( !brd->IsElementVisible( MOD_TEXT_INVISIBLE ) )
+ return;
+ color = brd->GetVisibleElementColor( MOD_TEXT_INVISIBLE );
+ }
+
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
+
+ // shade text if high contrast mode is active
+ if( ( draw_mode & GR_ALLOW_HIGHCONTRAST ) && displ_opts &&
+ displ_opts->m_ContrastModeDisplay )
+ {
+ LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
+
+ if( !IsOnLayer( curr_layer ) )
+ ColorTurnToDarkDarkGray( &color );
+ }
+
+ // Draw mode compensation for the width
+ int width = m_Thickness;
+
+ if( displ_opts && displ_opts->m_DisplayModTextFill == SKETCH )
+ width = -width;
+
+ GRSetDrawMode( DC, draw_mode );
+ wxPoint pos = m_Pos - offset;
+
+ // Draw the text anchor point
+ if( brd->IsElementVisible( ANCHOR_VISIBLE ) )
+ {
+ EDA_COLOR_T anchor_color = brd->GetVisibleElementColor(ANCHOR_VISIBLE);
+ GRDrawAnchor( panel->GetClipBox(), DC, pos.x, pos.y,
+ DIM_ANCRE_TEXTE, anchor_color );
+ }
+
+ // Draw the text proper, with the right attributes
+ wxSize size = m_Size;
+ double orient = GetDrawRotation();
+
+ // If the text is mirrored : negate size.x (mirror / Y axis)
+ if( m_Mirror )
+ size.x = -size.x;
+
+ DrawGraphicText( panel->GetClipBox(), DC, pos, color, GetShownText(), orient,
+ size, m_HJustify, m_VJustify, width, m_Italic, m_Bold );
+
+ // Enable these line to draw the bounding box (debug test purpose only)
+#if 0
+ {
+ EDA_RECT BoundaryBox = GetBoundingBox();
+ GRRect( panel->GetClipBox(), DC, BoundaryBox, 0, BROWN );
+ }
+#endif
+}
+
+/* Draws a line from the TEXTE_MODULE origin to parent MODULE origin.
+*/
+void TEXTE_MODULE::DrawUmbilical( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC,
+ GR_DRAWMODE aDrawMode,
+ const wxPoint& aOffset )
+{
+ MODULE* parent = static_cast<MODULE*>( GetParent() );
+
+ if( !parent )
+ return;
+
+ GRSetDrawMode( aDC, GR_XOR );
+ GRLine( aPanel->GetClipBox(), aDC,
+ parent->GetPosition(), GetTextPosition() + aOffset,
+ 0, UMBILICAL_COLOR);
+}
+
+/* Return text rotation for drawings and plotting
+ */
+double TEXTE_MODULE::GetDrawRotation() const
+{
+ MODULE* module = (MODULE*) m_Parent;
+ double rotation = m_Orient;
+
+ if( module )
+ rotation += module->GetOrientation();
+
+ NORMALIZE_ANGLE_POS( rotation );
+
+ // For angle = 0 .. 180 deg
+ while( rotation > 900 )
+ rotation -= 1800;
+
+ return rotation;
+}
+
+
+// see class_text_mod.h
+void TEXTE_MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ MODULE* module = (MODULE*) m_Parent;
+
+ if( module == NULL ) // Happens in modedit, and for new texts
+ return;
+
+ wxString msg, Line;
+
+ static const wxString text_type_msg[3] =
+ {
+ _( "Ref." ), _( "Value" ), _( "Text" )
+ };
+
+ Line = module->GetReference();
+ aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), Line, DARKCYAN ) );
+
+ Line = GetShownText();
+ aList.push_back( MSG_PANEL_ITEM( _( "Text" ), Line, BROWN ) );
+
+ wxASSERT( m_Type >= TEXT_is_REFERENCE && m_Type <= TEXT_is_DIVERS );
+ aList.push_back( MSG_PANEL_ITEM( _( "Type" ), text_type_msg[m_Type], DARKGREEN ) );
+
+ if( m_NoShow )
+ msg = _( "No" );
+ else
+ msg = _( "Yes" );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Display" ), msg, DARKGREEN ) );
+
+ // Display text layer
+ aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), GetLayerName(), DARKGREEN ) );
+
+ if( m_Mirror )
+ msg = _( " Yes" );
+ else
+ msg = _( " No" );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Mirror" ), msg, DARKGREEN ) );
+
+ msg.Printf( wxT( "%.1f" ), m_Orient / 10.0 );
+ aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), msg, DARKGREEN ) );
+
+ msg = ::CoordinateToString( m_Thickness );
+ aList.push_back( MSG_PANEL_ITEM( _( "Thickness" ), msg, DARKGREEN ) );
+
+ msg = ::CoordinateToString( m_Size.x );
+ aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, RED ) );
+
+ msg = ::CoordinateToString( m_Size.y );
+ aList.push_back( MSG_PANEL_ITEM( _( "Height" ), msg, RED ) );
+}
+
+
+wxString TEXTE_MODULE::GetSelectMenuText() const
+{
+ wxString text;
+ const wxChar *reference = GetChars( static_cast<MODULE*>( GetParent() )->GetReference() );
+
+ switch( m_Type )
+ {
+ case TEXT_is_REFERENCE:
+ text.Printf( _( "Reference %s" ), reference );
+ break;
+
+ case TEXT_is_VALUE:
+ text.Printf( _( "Value %s of %s" ), GetChars( GetShownText() ), reference );
+ break;
+
+ default: // wrap this one in quotes:
+ text.Printf( _( "Text \"%s\" on %s of %s" ), GetChars( ShortenedShownText() ),
+ GetChars( GetLayerName() ), reference );
+ break;
+ }
+
+ return text;
+}
+
+
+EDA_ITEM* TEXTE_MODULE::Clone() const
+{
+ return new TEXTE_MODULE( *this );
+}
+
+
+const BOX2I TEXTE_MODULE::ViewBBox() const
+{
+ double angle = GetDrawRotation();
+ EDA_RECT text_area = GetTextBox( -1, -1 );
+
+ if( angle )
+ text_area = text_area.GetBoundingBoxRotated( m_Pos, angle );
+
+ return BOX2I( text_area.GetPosition(), text_area.GetSize() );
+}
+
+
+void TEXTE_MODULE::ViewGetLayers( int aLayers[], int& aCount ) const
+{
+ if( m_NoShow ) // Hidden text
+ aLayers[0] = ITEM_GAL_LAYER( MOD_TEXT_INVISIBLE );
+ //else if( IsFrontLayer( m_Layer ) )
+ //aLayers[0] = ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE );
+ //else if( IsBackLayer( m_Layer ) )
+ //aLayers[0] = ITEM_GAL_LAYER( MOD_TEXT_BK_VISIBLE );
+ else
+ aLayers[0] = GetLayer();
+
+ aCount = 1;
+}
+
+
+unsigned int TEXTE_MODULE::ViewGetLOD( int aLayer ) const
+{
+ const int MAX = std::numeric_limits<unsigned int>::max();
+
+ if( !m_view )
+ return 0;
+
+ if( m_Type == TEXT_is_VALUE && !m_view->IsLayerVisible( ITEM_GAL_LAYER( MOD_VALUES_VISIBLE ) ) )
+ return MAX;
+
+ if( m_Type == TEXT_is_REFERENCE && !m_view->IsLayerVisible( ITEM_GAL_LAYER( MOD_REFERENCES_VISIBLE ) ) )
+ return MAX;
+
+ if( IsFrontLayer( m_Layer ) && ( !m_view->IsLayerVisible( ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ) ) ||
+ !m_view->IsLayerVisible( ITEM_GAL_LAYER( MOD_FR_VISIBLE ) ) ) )
+ return MAX;
+
+ if( IsBackLayer( m_Layer ) && ( !m_view->IsLayerVisible( ITEM_GAL_LAYER( MOD_TEXT_BK_VISIBLE ) ) ||
+ !m_view->IsLayerVisible( ITEM_GAL_LAYER( MOD_BK_VISIBLE ) ) ) )
+ return MAX;
+
+ return 0;
+}
+
+
+/**
+ * Macro-expansion for text in library modules
+ */
+wxString TEXTE_MODULE::GetShownText() const
+{
+ /* First order optimization: no % means that no processing is
+ * needed; just hope that RVO and copy constructor implementation
+ * avoid to copy the whole block; anyway it should be better than
+ * rebuild the string one character at a time...
+ * Also it seems wise to only expand macros in user text (but there
+ * is no technical reason, probably) */
+
+ if( (m_Type != TEXT_is_DIVERS) || (wxString::npos == m_Text.find('%')) )
+ return m_Text;
+
+ wxString newbuf;
+ const MODULE *module = static_cast<MODULE*>( GetParent() );
+
+ for( wxString::const_iterator it = m_Text.begin();
+ it != m_Text.end(); ++it )
+ {
+ // Process '%' and copy everything else
+ if( *it != '%' )
+ newbuf.append(*it);
+ else
+ {
+ /* Look at the next character (if is it there) and append
+ * its expansion */
+ ++it;
+ if( it != m_Text.end() )
+ {
+ switch( char(*it) )
+ {
+ case '%':
+ newbuf.append( '%' );
+ break;
+
+ case 'R':
+ if( module )
+ newbuf.append( module->GetReference() );
+ break;
+
+ case 'V':
+ if( module )
+ newbuf.append( module->GetValue() );
+ break;
+
+ default:
+ newbuf.append( '?' );
+ break;
+ }
+ }
+ else
+ break; // The string is over and we can't ++ anymore
+ }
+ }
+ return newbuf;
+}
+
+
diff --git a/pcbnew/class_text_mod.h b/pcbnew/class_text_mod.h
new file mode 100644
index 0000000..e4e3bca
--- /dev/null
+++ b/pcbnew/class_text_mod.h
@@ -0,0 +1,196 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_text_mod.h
+ * @brief Footprint text class description.
+ */
+
+
+#ifndef TEXT_MODULE_H_
+#define TEXT_MODULE_H_
+
+
+#include <eda_text.h>
+#include <class_board_item.h>
+
+
+class LINE_READER;
+class EDA_RECT;
+class EDA_DRAW_PANEL;
+class MODULE;
+class MSG_PANEL_ITEM;
+
+
+#define UMBILICAL_COLOR LIGHTBLUE
+
+
+class TEXTE_MODULE : public BOARD_ITEM, public EDA_TEXT
+{
+public:
+ /** Text module type: there must be only one (and only one) for each
+ * of the reference and value texts in one module; others could be
+ * added for the user (DIVERS is French for 'others'). Reference and
+ * value always live on silkscreen (on the module side); other texts
+ * are planned to go on whatever layer the user wants (except
+ * copper, probably) */
+ enum TEXT_TYPE
+ {
+ TEXT_is_REFERENCE = 0,
+ TEXT_is_VALUE = 1,
+ TEXT_is_DIVERS = 2
+ };
+
+ TEXTE_MODULE( MODULE* parent, TEXT_TYPE text_type = TEXT_is_DIVERS );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ ~TEXTE_MODULE();
+
+ static inline bool ClassOf( const EDA_ITEM* aItem )
+ {
+ return aItem && PCB_MODULE_TEXT_T == aItem->Type();
+ }
+
+ virtual const wxPoint& GetPosition() const
+ {
+ return m_Pos;
+ }
+
+ virtual void SetPosition( const wxPoint& aPos )
+ {
+ m_Pos = aPos;
+ SetLocalCoord();
+ }
+
+ /// Rotate text, in footprint editor
+ /// (for instance in footprint rotation transform)
+ void Rotate( const wxPoint& aOffset, double aAngle );
+
+ /// Flip entity during module flip
+ void Flip( const wxPoint& aCentre );
+
+ /// Mirror text position in footprint edition
+ /// the text itself is not mirrored, and the layer not modified,
+ /// only position is mirrored.
+ /// (use Flip to change layer to its paired and mirror the text in fp editor).
+ void Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis );
+
+ /// move text in move transform, in footprint editor
+ void Move( const wxPoint& aMoveVector );
+
+ /// @deprecated it seems (but the type is used to 'protect'
+ // reference and value from deletion, and for identification)
+ void SetType( TEXT_TYPE aType ) { m_Type = aType; }
+ TEXT_TYPE GetType() const { return m_Type; }
+
+ void SetVisible( bool isVisible ) { m_NoShow = !isVisible; }
+ bool IsVisible() const { return !m_NoShow; }
+
+ // The Pos0 accessors are for module-relative coordinates
+ void SetPos0( const wxPoint& aPos ) { m_Pos0 = aPos; SetDrawCoord(); }
+ const wxPoint& GetPos0() const { return m_Pos0; }
+
+ void Copy( TEXTE_MODULE* source ); // copy structure
+
+ int GetLength() const; // text length
+
+ /**
+ * @return the text rotation for drawings and plotting
+ * the footprint rotation is taken in account
+ */
+ double GetDrawRotation() const;
+
+ // Virtual function
+ const EDA_RECT GetBoundingBox() const;
+
+ ///> Set absolute coordinates.
+ void SetDrawCoord();
+
+ ///> Set relative coordinates.
+ void SetLocalCoord();
+
+ /* drawing functions */
+ void Draw( EDA_DRAW_PANEL* panel,
+ wxDC* DC,
+ GR_DRAWMODE aDrawMode,
+ const wxPoint& offset = ZeroOffset );
+
+ /**
+ * Function DrawUmbilical
+ * draws a line from the TEXTE_MODULE origin
+ * to parent MODULE origin.
+ * @param aPanel = the current DrawPanel
+ * @param aDC = the current device context
+ * @param aDrawMode = drawing mode, typically GR_XOR
+ * @param aOffset = offset for TEXTE_MODULE
+ */
+ void DrawUmbilical( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC,
+ GR_DRAWMODE aDrawMode,
+ const wxPoint& aOffset = ZeroOffset );
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ bool HitTest( const wxPoint& aPosition ) const;
+
+ wxString GetClass() const
+ {
+ return wxT( "MTEXT" );
+ }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return footprint_text_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+ virtual wxString GetShownText() const;
+
+ /// @copydoc VIEW_ITEM::ViewBBox()
+ virtual const BOX2I ViewBBox() const;
+
+ /// @copydoc VIEW_ITEM::ViewGetLayers()
+ virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
+
+ /// @copydoc VIEW_ITEM::ViewGetLOD()
+ virtual unsigned int ViewGetLOD( int aLayer ) const;
+
+#if defined(DEBUG)
+ virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+
+private:
+ /* Note: orientation in 1/10 deg relative to the footprint
+ * Physical orient is m_Orient + m_Parent->m_Orient
+ */
+
+ TEXT_TYPE m_Type; ///< 0=ref, 1=val, etc.
+ bool m_NoShow; ///< true = invisible
+
+ wxPoint m_Pos0; ///< text coordinates relatives to the footprint anchor, orient 0.
+ ///< text coordinate ref point is the text centre
+};
+
+#endif // TEXT_MODULE_H_
diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp
new file mode 100644
index 0000000..ff3c55d
--- /dev/null
+++ b/pcbnew/class_track.cpp
@@ -0,0 +1,1655 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_track.h
+ * @brief Functions relatives to tracks, vias and segments used to fill zones.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <common.h>
+#include <trigo.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <class_pcb_screen.h>
+#include <drawtxt.h>
+#include <colors_selection.h>
+#include <wxstruct.h>
+#include <wxBasePcbFrame.h>
+#include <class_board.h>
+#include <class_track.h>
+#include <pcbnew.h>
+#include <base_units.h>
+#include <msgpanel.h>
+
+
+/**
+ * Function ShowClearance
+ * tests to see if the clearance border is drawn on the given track.
+ * @return bool - true if should draw clearance, else false.
+ */
+static bool ShowClearance( DISPLAY_OPTIONS* aDisplOpts, const TRACK* aTrack )
+{
+ // maybe return true for tracks and vias, not for zone segments
+ return IsCopperLayer( aTrack->GetLayer() )
+ && ( aTrack->Type() == PCB_TRACE_T || aTrack->Type() == PCB_VIA_T )
+ && ( ( aDisplOpts->m_ShowTrackClearanceMode == SHOW_CLEARANCE_NEW_AND_EDITED_TRACKS_AND_VIA_AREAS
+ && ( aTrack->IsDragging() || aTrack->IsMoving() || aTrack->IsNew() ) )
+ || ( aDisplOpts->m_ShowTrackClearanceMode == SHOW_CLEARANCE_ALWAYS )
+ );
+
+}
+
+
+TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace,
+ const wxPoint& aPosition, LSET aLayerMask )
+{
+ for( TRACK *PtSegm = aStartTrace; PtSegm != NULL; PtSegm = PtSegm->Next() )
+ {
+ if( PtSegm->GetState( IS_DELETED | BUSY ) == 0 )
+ {
+ if( aPosition == PtSegm->GetStart() )
+ {
+ if( ( aLayerMask & PtSegm->GetLayerSet() ).any() )
+ return PtSegm;
+ }
+
+ if( aPosition == PtSegm->GetEnd() )
+ {
+ if( ( aLayerMask & PtSegm->GetLayerSet() ).any() )
+ return PtSegm;
+ }
+ }
+
+ if( PtSegm == aEndTrace )
+ break;
+ }
+
+ return NULL;
+}
+
+
+TRACK::TRACK( BOARD_ITEM* aParent, KICAD_T idtype ) :
+ BOARD_CONNECTED_ITEM( aParent, idtype )
+{
+ m_Width = Millimeter2iu( 0.2 );
+ start = end = NULL;
+ m_Param = 0;
+}
+
+
+EDA_ITEM* TRACK::Clone() const
+{
+ return new TRACK( *this );
+}
+
+
+wxString TRACK::ShowWidth() const
+{
+ wxString msg = ::CoordinateToString( m_Width );
+ return msg;
+}
+
+
+SEGZONE::SEGZONE( BOARD_ITEM* aParent ) :
+ TRACK( aParent, PCB_ZONE_T )
+{
+}
+
+
+EDA_ITEM* SEGZONE::Clone() const
+{
+ return new SEGZONE( *this );
+}
+
+
+wxString SEGZONE::GetSelectMenuText() const
+{
+ wxString text, nettxt;
+ BOARD* board = GetBoard();
+
+ if( board )
+ {
+ nettxt = GetNetname();
+ }
+ else
+ {
+ wxFAIL_MSG( wxT( "SEGZONE::GetSelectMenuText: BOARD is NULL" ) );
+ nettxt = wxT( "???" );
+ }
+
+ text.Printf( _( "Zone (%08lX) [%s] on %s" ),
+ m_TimeStamp, GetChars( nettxt ), GetChars( GetLayerName() ) );
+
+ return text;
+}
+
+
+VIA::VIA( BOARD_ITEM* aParent ) :
+ TRACK( aParent, PCB_VIA_T )
+{
+ SetViaType( VIA_THROUGH );
+ m_BottomLayer = B_Cu;
+ SetDrillDefault();
+}
+
+
+EDA_ITEM* VIA::Clone() const
+{
+ return new VIA( *this );
+}
+
+
+wxString VIA::GetSelectMenuText() const
+{
+ wxString text;
+ wxString format;
+ BOARD* board = GetBoard();
+
+ switch( GetViaType() )
+ {
+ case VIA_BLIND_BURIED:
+ format = _( "Blind/Buried Via %s, net[%s] (%d) on layers %s/%s" );
+ break;
+ case VIA_MICROVIA:
+ format = _( "Micro Via %s, Net [%s] (%d) on layers %s/%s" );
+ break;
+ // else say nothing about normal (through) vias
+ default:
+ format = _( "Via %s net [%s] (%d) on layers %s/%s" );
+ break;
+ }
+
+
+ if( board )
+ {
+ wxString netname = GetNetname();
+
+ // say which layers, only two for now
+ LAYER_ID topLayer;
+ LAYER_ID botLayer;
+ LayerPair( &topLayer, &botLayer );
+ text.Printf( format.GetData(), GetChars( ShowWidth() ),
+ GetChars( netname ), GetNetCode(),
+ GetChars( board->GetLayerName( topLayer ) ),
+ GetChars( board->GetLayerName( botLayer ) ) );
+
+ }
+ else
+ {
+ wxFAIL_MSG( wxT( "VIA::GetSelectMenuText: BOARD is NULL" ) );
+ text.Printf( format.GetData(), GetChars( ShowWidth() ),
+ wxT( "???" ), 0,
+ wxT( "??" ), wxT( "??" ) );
+ }
+
+ return text;
+}
+
+
+int TRACK::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
+{
+ // Currently tracks have no specific clearance parameter on a per track or per
+ // segment basis. The NETCLASS clearance is used.
+ return BOARD_CONNECTED_ITEM::GetClearance( aItem );
+}
+
+
+int VIA::GetDrillValue() const
+{
+ if( m_Drill > 0 ) // Use the specific value.
+ return m_Drill;
+
+ // Use the default value from the Netclass
+ NETCLASSPTR netclass = GetNetClass();
+
+ if( GetViaType() == VIA_MICROVIA )
+ return netclass->GetuViaDrill();
+
+ return netclass->GetViaDrill();
+}
+
+
+bool TRACK::IsNull()
+{
+ if( ( Type() != PCB_VIA_T ) && ( m_Start == m_End ) )
+ return true;
+ else
+ return false;
+}
+
+
+STATUS_FLAGS TRACK::IsPointOnEnds( const wxPoint& point, int min_dist )
+{
+ STATUS_FLAGS result = 0;
+
+ if( min_dist < 0 )
+ min_dist = m_Width / 2;
+
+ if( min_dist == 0 )
+ {
+ if( m_Start == point )
+ result |= STARTPOINT;
+
+ if( m_End == point )
+ result |= ENDPOINT;
+ }
+ else
+ {
+ double dist = GetLineLength( m_Start, point );
+
+ if( min_dist >= KiROUND( dist ) )
+ result |= STARTPOINT;
+
+ dist = GetLineLength( m_End, point );
+
+ if( min_dist >= KiROUND( dist ) )
+ result |= ENDPOINT;
+ }
+
+ return result;
+}
+
+
+const EDA_RECT TRACK::GetBoundingBox() const
+{
+ // end of track is round, this is its radius, rounded up
+ int radius;
+
+ int ymax;
+ int xmax;
+
+ int ymin;
+ int xmin;
+
+ if( Type() == PCB_VIA_T )
+ {
+ // Because vias are sometimes drawn larger than their m_Width would
+ // provide, erasing them using a dirty rect must also compensate for this
+ // possibility (that the via is larger on screen than its m_Width would provide).
+ // Because it is cheap to return a larger BoundingBox, do it so that
+ // the via gets erased properly. Do not divide width by 2 for this reason.
+ radius = m_Width;
+
+ ymax = m_Start.y;
+ xmax = m_Start.x;
+
+ ymin = m_Start.y;
+ xmin = m_Start.x;
+ }
+ else
+ {
+ radius = ( m_Width + 1 ) / 2;
+
+ ymax = std::max( m_Start.y, m_End.y );
+ xmax = std::max( m_Start.x, m_End.x );
+
+ ymin = std::min( m_Start.y, m_End.y );
+ xmin = std::min( m_Start.x, m_End.x );
+ }
+
+ // + 1 is for the clearance line itself.
+ radius += GetClearance() + 1;
+
+ ymax += radius;
+ xmax += radius;
+
+ ymin -= radius;
+ xmin -= radius;
+
+ // return a rectangle which is [pos,dim) in nature. therefore the +1
+ EDA_RECT ret( wxPoint( xmin, ymin ), wxSize( xmax - xmin + 1, ymax - ymin + 1 ) );
+
+ return ret;
+}
+
+
+void TRACK::Rotate( const wxPoint& aRotCentre, double aAngle )
+{
+ RotatePoint( &m_Start, aRotCentre, aAngle );
+ RotatePoint( &m_End, aRotCentre, aAngle );
+}
+
+
+void TRACK::Flip( const wxPoint& aCentre )
+{
+ m_Start.y = aCentre.y - (m_Start.y - aCentre.y);
+ m_End.y = aCentre.y - (m_End.y - aCentre.y);
+ int copperLayerCount = GetBoard()->GetCopperLayerCount();
+ SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
+}
+
+
+void VIA::Flip( const wxPoint& aCentre )
+{
+ m_Start.y = aCentre.y - (m_Start.y - aCentre.y);
+ m_End.y = aCentre.y - (m_End.y - aCentre.y);
+
+ if( GetViaType() != VIA_THROUGH )
+ {
+ int copperLayerCount = GetBoard()->GetCopperLayerCount();
+ LAYER_ID top_layer;
+ LAYER_ID bottom_layer;
+ LayerPair( &top_layer, &bottom_layer );
+ top_layer = FlipLayer( top_layer, copperLayerCount );
+ bottom_layer = FlipLayer( bottom_layer, copperLayerCount );
+ SetLayerPair( top_layer, bottom_layer );
+ }
+}
+
+
+// see class_track.h
+SEARCH_RESULT TRACK::Visit( INSPECTOR* inspector, const void* testData,
+ const KICAD_T scanTypes[] )
+{
+ KICAD_T stype = *scanTypes;
+
+ // If caller wants to inspect my type
+ if( stype == Type() )
+ {
+ if( SEARCH_QUIT == inspector->Inspect( this, testData ) )
+ return SEARCH_QUIT;
+ }
+
+ return SEARCH_CONTINUE;
+}
+
+
+bool VIA::IsOnLayer( LAYER_ID layer_number ) const
+{
+ LAYER_ID bottom_layer, top_layer;
+
+ LayerPair( &top_layer, &bottom_layer );
+
+ wxASSERT( top_layer <= bottom_layer );
+
+ if( top_layer <= layer_number && layer_number <= bottom_layer )
+ return true;
+ else
+ return false;
+}
+
+
+LSET VIA::GetLayerSet() const
+{
+ if( GetViaType() == VIA_THROUGH )
+ return LSET::AllCuMask();
+
+ // VIA_BLIND_BURIED or VIA_MICRVIA:
+
+ LSET layermask;
+
+ wxASSERT( m_Layer <= m_BottomLayer );
+
+ // LAYER_IDs are numbered from front to back, this is top to bottom.
+ for( LAYER_NUM id = m_Layer; id <= m_BottomLayer; ++id )
+ {
+ layermask.set( id );
+ }
+
+ return layermask;
+}
+
+
+void VIA::SetLayerPair( LAYER_ID aTopLayer, LAYER_ID aBottomLayer )
+{
+ if( GetViaType() == VIA_THROUGH )
+ {
+ aTopLayer = F_Cu;
+ aBottomLayer = B_Cu;
+ }
+
+ if( aBottomLayer < aTopLayer )
+ std::swap( aBottomLayer, aTopLayer );
+
+ m_Layer = aTopLayer;
+ m_BottomLayer = aBottomLayer;
+}
+
+
+void VIA::LayerPair( LAYER_ID* top_layer, LAYER_ID* bottom_layer ) const
+{
+ LAYER_ID t_layer = F_Cu;
+ LAYER_ID b_layer = B_Cu;
+
+ if( GetViaType() != VIA_THROUGH )
+ {
+ b_layer = m_BottomLayer;
+ t_layer = m_Layer;
+
+ if( b_layer < t_layer )
+ std::swap( b_layer, t_layer );
+ }
+
+ if( top_layer )
+ *top_layer = t_layer;
+
+ if( bottom_layer )
+ *bottom_layer = b_layer;
+}
+
+
+TRACK* TRACK::GetBestInsertPoint( BOARD* aPcb )
+{
+ TRACK* track;
+
+ if( Type() == PCB_ZONE_T )
+ track = aPcb->m_Zone;
+ else
+ track = aPcb->m_Track;
+
+ for( ; track; track = track->Next() )
+ {
+ if( GetNetCode() <= track->GetNetCode() )
+ return track;
+ }
+
+ return NULL;
+}
+
+
+TRACK* TRACK::GetStartNetCode( int NetCode )
+{
+ TRACK* Track = this;
+ int ii = 0;
+
+ if( NetCode == -1 )
+ NetCode = GetNetCode();
+
+ while( Track != NULL )
+ {
+ if( Track->GetNetCode() > NetCode )
+ break;
+
+ if( Track->GetNetCode() == NetCode )
+ {
+ ii++;
+ break;
+ }
+
+ Track = (TRACK*) Track->Pnext;
+ }
+
+ if( ii )
+ return Track;
+ else
+ return NULL;
+}
+
+
+TRACK* TRACK::GetEndNetCode( int NetCode )
+{
+ TRACK* NextS, * Track = this;
+ int ii = 0;
+
+ if( Track == NULL )
+ return NULL;
+
+ if( NetCode == -1 )
+ NetCode = GetNetCode();
+
+ while( Track != NULL )
+ {
+ NextS = (TRACK*) Track->Pnext;
+
+ if( Track->GetNetCode() == NetCode )
+ ii++;
+
+ if( NextS == NULL )
+ break;
+
+ if( NextS->GetNetCode() > NetCode )
+ break;
+
+ Track = NextS;
+ }
+
+ if( ii )
+ return Track;
+ else
+ return NULL;
+}
+
+void TRACK::DrawShortNetname( EDA_DRAW_PANEL* panel,
+ wxDC* aDC, GR_DRAWMODE aDrawMode, EDA_COLOR_T aBgColor )
+{
+ if( ! panel )
+ return;
+
+ /* we must filter tracks, to avoid a lot of texts.
+ * - only tracks with a length > 10 * thickness are eligible
+ * and, of course, if we are not printing the board
+ */
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
+
+ if( displ_opts->m_DisplayNetNamesMode == 0 || displ_opts->m_DisplayNetNamesMode == 1 )
+ return;
+
+ #define THRESHOLD 10
+
+ int len = KiROUND( GetLineLength( m_Start, m_End ) );
+
+ if( len < THRESHOLD * m_Width )
+ return;
+
+ // no room to display a text inside track
+ if( aDC->LogicalToDeviceXRel( m_Width ) < MIN_TEXT_SIZE )
+ return;
+
+ if( GetNetCode() == NETINFO_LIST::UNCONNECTED )
+ return;
+
+ NETINFO_ITEM* net = GetNet();
+
+ if( net == NULL )
+ return;
+
+ int textlen = net->GetShortNetname().Len();
+
+ if( textlen > 0 )
+ {
+ // calculate a good size for the text
+ int tsize = std::min( m_Width, len / textlen );
+ int dx = m_End.x - m_Start.x ;
+ int dy = m_End.y - m_Start.y ;
+ wxPoint tpos = m_Start + m_End;
+ tpos.x /= 2;
+ tpos.y /= 2;
+
+ // Calculate angle: if the track segment is vertical, angle = 90 degrees
+ // If horizontal 0 degrees, otherwise compute it
+ double angle; // angle is in 0.1 degree
+
+ if( dy == 0 ) // Horizontal segment
+ {
+ angle = 0;
+ }
+ else
+ {
+ if( dx == 0 ) // Vertical segment
+ {
+ angle = 900;
+ }
+ else
+ {
+ /* atan2 is *not* the solution here, since it can give upside
+ down text. We want to work only in the first and fourth quadrant */
+ angle = RAD2DECIDEG( -atan( double( dy ) / double( dx ) ) );
+ }
+ }
+
+ LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
+
+ if( ( aDC->LogicalToDeviceXRel( tsize ) >= MIN_TEXT_SIZE )
+ && ( !(!IsOnLayer( curr_layer )&& displ_opts->m_ContrastModeDisplay) ) )
+ {
+ if( (aDrawMode & GR_XOR) == 0 )
+ GRSetDrawMode( aDC, GR_COPY );
+
+ tsize = (tsize * 7) / 10; // small reduction to give a better look
+ DrawGraphicHaloText( panel->GetClipBox(), aDC, tpos,
+ aBgColor, BLACK, WHITE, net->GetShortNetname(), angle,
+ wxSize( tsize, tsize ),
+ GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
+ tsize / 7,
+ false, false );
+ }
+ }
+}
+
+
+void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode,
+ const wxPoint& aOffset )
+{
+ BOARD * brd = GetBoard( );
+ EDA_COLOR_T color = brd->GetLayerColor(m_Layer);
+
+ if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
+ return;
+
+#ifdef USE_WX_OVERLAY
+ // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay
+ if( (m_Flags & IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC)))
+ return;
+#endif
+
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) panel->GetDisplayOptions();
+
+ if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && displ_opts->m_ContrastModeDisplay )
+ {
+ LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
+
+ if( !IsOnLayer( curr_layer ) )
+ ColorTurnToDarkDarkGray( &color );
+ }
+
+ if( aDrawMode & GR_HIGHLIGHT )
+ ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) );
+
+ ColorApplyHighlightFlag( &color );
+
+ SetAlpha( &color, 150 );
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ int l_trace = m_Width / 2;
+
+ if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH )
+ {
+ GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, 0, color );
+ return;
+ }
+
+ if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
+ {
+ GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color );
+ }
+ else
+ {
+ GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x,
+ m_Start.y + aOffset.y,
+ m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color );
+ }
+
+ if( panel->GetScreen()->m_IsPrinting )
+ return;
+
+ // Show clearance for tracks, not for zone segments
+ if( ShowClearance( displ_opts, this ) )
+ {
+ GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset,
+ m_Width + (GetClearance() * 2), color );
+ }
+
+ DrawShortNetname( panel, aDC, aDrawMode, color );
+}
+
+
+void SEGZONE::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode,
+ const wxPoint& aOffset )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
+
+ if( displ_opts->m_DisplayZonesMode != 0 )
+ return;
+
+ BOARD * brd = GetBoard( );
+ EDA_COLOR_T color = brd->GetLayerColor(m_Layer);
+
+ if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
+ return;
+
+#ifdef USE_WX_OVERLAY
+ // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay
+ if( (m_Flags & IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC)))
+ return;
+#endif
+
+ if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && displ_opts->m_ContrastModeDisplay )
+ {
+ LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
+
+ if( !IsOnLayer( curr_layer ) )
+ ColorTurnToDarkDarkGray( &color );
+ }
+
+ if( aDrawMode & GR_HIGHLIGHT )
+ ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) );
+
+ ColorApplyHighlightFlag( &color );
+
+ SetAlpha( &color, 150 );
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ int l_trace = m_Width / 2;
+
+ if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH )
+ {
+ GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, 0, color );
+ return;
+ }
+
+ if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
+ {
+ GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color );
+ }
+ else
+ {
+ GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x,
+ m_Start.y + aOffset.y,
+ m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color );
+ }
+
+ // No clearance or netnames for zones
+}
+
+
+void TRACK::ViewGetLayers( int aLayers[], int& aCount ) const
+{
+ // Show the track and its netname on different layers
+ aLayers[0] = GetLayer();
+ aLayers[1] = GetNetnameLayer( aLayers[0] );
+ aCount = 2;
+}
+
+
+unsigned int TRACK::ViewGetLOD( int aLayer ) const
+{
+ // Netnames will be shown only if zoom is appropriate
+ if( IsNetnameLayer( aLayer ) )
+ {
+ return ( 20000000 / ( m_Width + 1 ) );
+ }
+
+ // Other layers are shown without any conditions
+ return 0;
+}
+
+
+void VIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset )
+{
+ wxCHECK_RET( panel != NULL, wxT( "VIA::Draw panel cannot be NULL." ) );
+
+ int radius;
+ LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
+
+ int fillvia = 0;
+ PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) panel->GetParent();
+ PCB_SCREEN* screen = frame->GetScreen();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)frame->GetDisplayOptions();
+
+ if( displ_opts->m_DisplayViaFill == FILLED )
+ fillvia = 1;
+
+ GRSetDrawMode( aDC, aDrawMode );
+
+ BOARD * brd = GetBoard();
+ EDA_COLOR_T color = brd->GetVisibleElementColor( VIAS_VISIBLE + GetViaType() );
+
+ if( brd->IsElementVisible( PCB_VISIBLE(VIAS_VISIBLE + GetViaType()) ) == false
+ && ( color & HIGHLIGHT_FLAG ) != HIGHLIGHT_FLAG )
+ return;
+
+ // Only draw the via if at least one of the layers it crosses is being displayed
+ if( !( brd->GetVisibleLayers() & GetLayerSet() ).any() )
+ return;
+
+ if( displ_opts->m_ContrastModeDisplay )
+ {
+ if( !IsOnLayer( curr_layer ) )
+ ColorTurnToDarkDarkGray( &color );
+ }
+
+ if( aDrawMode & GR_HIGHLIGHT )
+ ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) );
+
+ ColorApplyHighlightFlag( &color );
+
+ SetAlpha( &color, 150 );
+
+
+ radius = m_Width >> 1;
+ // for small via size on screen (radius < 4 pixels) draw a simplified shape
+
+ int radius_in_pixels = aDC->LogicalToDeviceXRel( radius );
+
+ bool fast_draw = false;
+
+ // Vias are drawn as a filled circle or a double circle. The hole will be drawn later
+ int drill_radius = GetDrillValue() / 2;
+
+ int inner_radius = radius - aDC->DeviceToLogicalXRel( 2 );
+
+ if( radius_in_pixels < MIN_VIA_DRAW_SIZE )
+ {
+ fast_draw = true;
+ fillvia = false;
+ }
+
+ if( fillvia )
+ {
+ GRFilledCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius, color );
+ }
+ else
+ {
+ GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius, 0, color );
+
+ if ( fast_draw )
+ return;
+
+ GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, inner_radius, 0, color );
+ }
+
+ // Draw the via hole if the display option allows it
+ if( displ_opts->m_DisplayViaMode != VIA_HOLE_NOT_SHOW )
+ {
+ // Display all drill holes requested or Display non default holes requested
+ bool show_hole = displ_opts->m_DisplayViaMode == ALL_VIA_HOLE_SHOW;
+
+ if( !show_hole )
+ {
+ NETINFO_ITEM* net = GetNet();
+ int drill_class_value = 0;
+ if( net )
+ {
+ if( GetViaType() == VIA_MICROVIA )
+ drill_class_value = net->GetMicroViaDrillSize();
+ else
+ drill_class_value = net->GetViaDrillSize();
+ }
+
+ show_hole = GetDrillValue() != drill_class_value;
+ }
+
+ if( show_hole )
+ {
+ if( fillvia )
+ {
+ bool blackpenstate = false;
+
+ if( screen->m_IsPrinting )
+ {
+ blackpenstate = GetGRForceBlackPenState();
+ GRForceBlackPen( false );
+ color = WHITE;
+ }
+ else
+ {
+ color = BLACK; // or DARKGRAY;
+ }
+
+ if( (aDrawMode & GR_XOR) == 0)
+ GRSetDrawMode( aDC, GR_COPY );
+
+ if( aDC->LogicalToDeviceXRel( drill_radius ) > MIN_DRAW_WIDTH ) // Draw hole if large enough.
+ GRFilledCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x,
+ m_Start.y + aOffset.y, drill_radius, 0, color, color );
+
+ if( screen->m_IsPrinting )
+ GRForceBlackPen( blackpenstate );
+ }
+ else
+ {
+ if( drill_radius < inner_radius ) // We can show the via hole
+ GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, drill_radius, 0, color );
+ }
+ }
+ }
+
+ if( ShowClearance( displ_opts, this ) )
+ {
+ GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius + GetClearance(), 0, color );
+ }
+
+ // for Micro Vias, draw a partial cross : X on component layer, or + on copper layer
+ // (so we can see 2 superimposed microvias ):
+ if( GetViaType() == VIA_MICROVIA )
+ {
+ int ax, ay, bx, by;
+
+ if( IsOnLayer( B_Cu ) )
+ {
+ ax = radius; ay = 0;
+ bx = drill_radius; by = 0;
+ }
+ else
+ {
+ ax = ay = (radius * 707) / 1000;
+ bx = by = (drill_radius * 707) / 1000;
+ }
+
+ // lines '|' or '\'
+ GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - ax,
+ m_Start.y + aOffset.y - ay,
+ m_Start.x + aOffset.x - bx,
+ m_Start.y + aOffset.y - by, 0, color );
+ GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x + bx,
+ m_Start.y + aOffset.y + by,
+ m_Start.x + aOffset.x + ax,
+ m_Start.y + aOffset.y + ay, 0, color );
+
+ // lines - or '/'
+ GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x + ay,
+ m_Start.y + aOffset.y - ax,
+ m_Start.x + aOffset.x + by,
+ m_Start.y + aOffset.y - bx, 0, color );
+ GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - by,
+ m_Start.y + aOffset.y + bx,
+ m_Start.x + aOffset.x - ay,
+ m_Start.y + aOffset.y + ax, 0, color );
+ }
+
+ // for Buried Vias, draw a partial line : orient depending on layer pair
+ // (so we can see superimposed buried vias ):
+ if( GetViaType() == VIA_BLIND_BURIED )
+ {
+ int ax = 0, ay = radius, bx = 0, by = drill_radius;
+ LAYER_ID layer_top, layer_bottom;
+
+ LayerPair( &layer_top, &layer_bottom );
+
+ // lines for the top layer
+ RotatePoint( &ax, &ay, layer_top * 3600.0 / brd->GetCopperLayerCount( ) );
+ RotatePoint( &bx, &by, layer_top * 3600.0 / brd->GetCopperLayerCount( ) );
+ GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - ax,
+ m_Start.y + aOffset.y - ay,
+ m_Start.x + aOffset.x - bx,
+ m_Start.y + aOffset.y - by, 0, color );
+
+ // lines for the bottom layer
+ ax = 0; ay = radius; bx = 0; by = drill_radius;
+ RotatePoint( &ax, &ay, layer_bottom * 3600.0 / brd->GetCopperLayerCount( ) );
+ RotatePoint( &bx, &by, layer_bottom * 3600.0 / brd->GetCopperLayerCount( ) );
+ GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - ax,
+ m_Start.y + aOffset.y - ay,
+ m_Start.x + aOffset.x - bx,
+ m_Start.y + aOffset.y - by, 0, color );
+ }
+
+ // Display the short netname:
+ if( GetNetCode() == NETINFO_LIST::UNCONNECTED )
+ return;
+
+ if( displ_opts->m_DisplayNetNamesMode == 0 || displ_opts->m_DisplayNetNamesMode == 1 )
+ return;
+
+ NETINFO_ITEM* net = GetNet();
+
+ if( net == NULL )
+ return;
+
+ int len = net->GetShortNetname().Len();
+
+ if( len > 0 )
+ {
+ // calculate a good size for the text
+ int tsize = m_Width / len;
+
+ if( aDC->LogicalToDeviceXRel( tsize ) >= MIN_TEXT_SIZE )
+ {
+ tsize = (tsize * 7) / 10; // small reduction to give a better look, inside via
+
+ if( (aDrawMode & GR_XOR) == 0 )
+ GRSetDrawMode( aDC, GR_COPY );
+
+ EDA_RECT* clipbox = panel->GetClipBox();
+ DrawGraphicHaloText( clipbox, aDC, m_Start,
+ color, WHITE, BLACK, net->GetShortNetname(), 0,
+ wxSize( tsize, tsize ),
+ GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
+ tsize / 7, false, false );
+ }
+ }
+}
+
+
+void VIA::ViewGetLayers( int aLayers[], int& aCount ) const
+{
+ aLayers[0] = ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE );
+ aCount = 2;
+
+ // Just show it on common via & via holes layers
+ switch( GetViaType() )
+ {
+ case VIA_THROUGH:
+ aLayers[1] = ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE );
+ break;
+
+ case VIA_BLIND_BURIED:
+ aLayers[1] = ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE );
+ aLayers[2] = m_Layer;
+ aLayers[3] = m_BottomLayer;
+ aCount += 2;
+ break;
+
+ case VIA_MICROVIA:
+ aLayers[1] = ITEM_GAL_LAYER( VIA_MICROVIA_VISIBLE );
+ break;
+
+ default:
+ assert( false );
+ break;
+ }
+}
+
+
+// see class_track.h
+void TRACK::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString msg;
+ BOARD* board = GetBoard();
+
+ // Display basic infos
+ GetMsgPanelInfoBase( aList );
+
+ // Display full track length (in Pcbnew)
+ if( board )
+ {
+ double trackLen = 0;
+ double lenPadToDie = 0;
+ board->MarkTrace( this, NULL, &trackLen, &lenPadToDie, false );
+ msg = ::LengthDoubleToString( trackLen );
+ aList.push_back( MSG_PANEL_ITEM( _( "Length" ), msg, DARKCYAN ) );
+
+ if( lenPadToDie != 0 )
+ {
+ msg = ::LengthDoubleToString( trackLen + lenPadToDie );
+ aList.push_back( MSG_PANEL_ITEM( _( "Full Length" ), msg, DARKCYAN ) );
+
+ msg = ::LengthDoubleToString( lenPadToDie );
+ aList.push_back( MSG_PANEL_ITEM( _( "Pad To Die Length" ), msg, DARKCYAN ) );
+ }
+ }
+
+ NETCLASSPTR netclass = GetNetClass();
+
+ if( netclass )
+ {
+ aList.push_back( MSG_PANEL_ITEM( _( "NC Name" ), netclass->GetName(), DARKMAGENTA ) );
+ aList.push_back( MSG_PANEL_ITEM( _( "NC Clearance" ),
+ ::CoordinateToString( netclass->GetClearance(), true ),
+ DARKMAGENTA ) );
+ aList.push_back( MSG_PANEL_ITEM( _( "NC Width" ),
+ ::CoordinateToString( netclass->GetTrackWidth(), true ),
+ DARKMAGENTA ) );
+ aList.push_back( MSG_PANEL_ITEM( _( "NC Via Size" ),
+ ::CoordinateToString( netclass->GetViaDiameter(), true ),
+ DARKMAGENTA ) );
+ aList.push_back( MSG_PANEL_ITEM( _( "NC Via Drill"),
+ ::CoordinateToString( netclass->GetViaDrill(), true ),
+ DARKMAGENTA ) );
+ }
+}
+
+void TRACK::GetMsgPanelInfoBase_Common( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString msg;
+
+ // Display Net Name
+ if( GetBoard() )
+ {
+ NETINFO_ITEM* net = GetNet();
+
+ if( net )
+ msg = net->GetNetname();
+ else
+ msg = wxT( "<noname>" );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) );
+
+ // Display net code : (useful in test or debug)
+ msg.Printf( wxT( "%d.%d" ), GetNetCode(), GetSubNet() );
+ aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) );
+ }
+
+#if defined(DEBUG)
+
+ // Display the flags
+ msg.Printf( wxT( "0x%08X" ), m_Flags );
+ aList.push_back( MSG_PANEL_ITEM( wxT( "Flags" ), msg, BLUE ) );
+
+#if 0
+ // Display start and end pointers:
+ msg.Printf( wxT( "%p" ), start );
+ aList.push_back( MSG_PANEL_ITEM( wxT( "start ptr" ), msg, BLUE ) );
+ msg.Printf( wxT( "%p" ), end );
+ aList.push_back( MSG_PANEL_ITEM( wxT( "end ptr" ), msg, BLUE ) );
+ // Display this ptr
+ msg.Printf( wxT( "%p" ), this );
+ aList.push_back( MSG_PANEL_ITEM( wxT( "this" ), msg, BLUE ) );
+#endif
+
+#if 0
+ // Display start and end positions:
+ msg.Printf( wxT( "%d %d" ), m_Start.x, m_Start.y );
+ aList.push_back( MSG_PANEL_ITEM( wxT( "Start pos" ), msg, BLUE ) );
+ msg.Printf( wxT( "%d %d" ), m_End.x, m_End.y );
+ aList.push_back( MSG_PANEL_ITEM( wxT( "End pos" ), msg, BLUE ) );
+#endif
+
+#endif // defined(DEBUG)
+
+ // Display the State member
+ msg = wxT( ". . " );
+
+ if( GetState( TRACK_LOCKED ) )
+ msg[0] = 'L';
+
+ if( GetState( TRACK_AR ) )
+ msg[2] = 'A';
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Status" ), msg, MAGENTA ) );
+}
+
+void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString msg;
+ BOARD* board = GetBoard();
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Type" ), _( "Track" ), DARKCYAN ) );
+
+ GetMsgPanelInfoBase_Common( aList );
+
+ // Display layer
+ if( board )
+ msg = board->GetLayerName( m_Layer );
+ else
+ msg.Printf(wxT("%d"), m_Layer );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), msg, BROWN ) );
+
+ // Display width
+ msg = ::CoordinateToString( (unsigned) m_Width );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, DARKCYAN ) );
+
+ // Display segment length
+ msg = ::LengthDoubleToString( GetLength() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Segment Length" ), msg, DARKCYAN ) );
+}
+
+void SEGZONE::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString msg;
+ BOARD* board = GetBoard();
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Type" ), _( "Zone " ), DARKCYAN ) );
+
+ GetMsgPanelInfoBase_Common( aList );
+
+ // Display layer
+ if( board )
+ msg = board->GetLayerName( m_Layer );
+ else
+ msg.Printf( wxT( "%d" ), m_Layer );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), msg, BROWN ) );
+
+ // Display width
+ msg = ::CoordinateToString( (unsigned) m_Width );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, DARKCYAN ) );
+
+ // Display segment length
+ msg = ::LengthDoubleToString( GetLength() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Segment Length" ), msg, DARKCYAN ) );
+}
+
+void VIA::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString msg;
+ BOARD* board = GetBoard();
+
+ switch( GetViaType() )
+ {
+ default:
+ case VIA_NOT_DEFINED:
+ msg = wxT( "???" ); // Not used yet, does not exist currently
+ break;
+
+ case VIA_MICROVIA:
+ msg = _( "Micro Via" ); // from external layer (TOP or BOTTOM) from
+ // the near neighbor inner layer only
+ break;
+
+ case VIA_BLIND_BURIED:
+ msg = _( "Blind/Buried Via" ); // from inner or external to inner
+ // or external layer (no restriction)
+ break;
+
+ case VIA_THROUGH:
+ msg = _( "Through Via" ); // Usual via (from TOP to BOTTOM layer only )
+ break;
+ }
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) );
+
+ GetMsgPanelInfoBase_Common( aList );
+
+
+ // Display layer pair
+ LAYER_ID top_layer, bottom_layer;
+
+ LayerPair( &top_layer, &bottom_layer );
+
+ if( board )
+ msg = board->GetLayerName( top_layer ) + wxT( "/" )
+ + board->GetLayerName( bottom_layer );
+ else
+ msg.Printf( wxT( "%d/%d" ), top_layer, bottom_layer );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Layers" ), msg, BROWN ) );
+
+ // Display width
+ msg = ::CoordinateToString( (unsigned) m_Width );
+
+ // Display diameter value:
+ aList.push_back( MSG_PANEL_ITEM( _( "Diameter" ), msg, DARKCYAN ) );
+
+ // Display drill value
+ int drill_value = GetDrillValue();
+
+ msg = ::CoordinateToString( drill_value );
+
+ wxString title = _( "Drill" );
+ title += wxT( " " );
+
+ bool drl_specific = true;
+
+ if( GetBoard() )
+ {
+ NETINFO_ITEM* net = GetNet();
+ int drill_class_value = 0;
+
+ if( net )
+ {
+ if( GetViaType() == VIA_MICROVIA )
+ drill_class_value = net->GetMicroViaDrillSize();
+ else
+ drill_class_value = net->GetViaDrillSize();
+ }
+
+ drl_specific = drill_value != drill_class_value;
+ }
+
+
+ if( drl_specific )
+ title += _( "(Specific)" );
+ else
+ title += _( "(NetClass)" );
+
+ aList.push_back( MSG_PANEL_ITEM( title, msg, RED ) );
+}
+
+
+bool TRACK::HitTest( const wxPoint& aPosition ) const
+{
+ return TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 );
+}
+
+bool VIA::HitTest( const wxPoint& aPosition ) const
+{
+ int max_dist = m_Width / 2;
+
+ // rel_pos is aPosition relative to m_Start (or the center of the via)
+ wxPoint rel_pos = aPosition - m_Start;
+ double dist = (double) rel_pos.x * rel_pos.x + (double) rel_pos.y * rel_pos.y;
+ return dist <= (double) max_dist * max_dist;
+}
+
+
+bool TRACK::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ EDA_RECT arect = aRect;
+ arect.Inflate( aAccuracy );
+
+ if( aContained )
+ /* Tracks are a special case:
+ * they are considered inside the rect if one end is inside the rect */
+ return arect.Contains( GetStart() ) || arect.Contains( GetEnd() );
+ else
+ return arect.Intersects( GetStart(), GetEnd() );
+}
+
+bool VIA::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ EDA_RECT box;
+ EDA_RECT arect = aRect;
+ arect.Inflate( aAccuracy );
+
+ box.SetOrigin( GetStart() );
+ box.Inflate( GetWidth() / 2 );
+
+ if( aContained )
+ return arect.Contains( box );
+ else
+ return arect.Intersects( box );
+}
+
+
+VIA* TRACK::GetVia( const wxPoint& aPosition, LAYER_ID aLayer)
+{
+ for( VIA* via = GetFirstVia( this ); via; via = GetFirstVia( via->Next() ) )
+ {
+ if( via->HitTest( aPosition ) &&
+ !via->GetState( BUSY | IS_DELETED ) &&
+ ((aLayer == UNDEFINED_LAYER) || (via->IsOnLayer( aLayer ))) )
+ return via;
+ }
+
+ return NULL;
+}
+
+
+VIA* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LSET aLayerMask )
+{
+ for( VIA* via = GetFirstVia( this, aEndTrace ); via; via = GetFirstVia( via->Next() ) )
+ {
+ if( via->HitTest( aPosition ) &&
+ !via->GetState( BUSY | IS_DELETED ) &&
+ ( aLayerMask & via->GetLayerSet() ).any()
+ )
+ {
+ return via;
+ }
+ }
+
+ return NULL;
+}
+
+
+TRACK* TRACK::GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint,
+ bool aSameNetOnly, bool aSequential )
+{
+ const wxPoint& position = GetEndPoint( aEndPoint );
+ LSET refLayers = GetLayerSet();
+ TRACK* previousSegment;
+ TRACK* nextSegment;
+
+ if( aSequential )
+ {
+ // Simple sequential search: from aStartTrace forward to aEndTrace
+ previousSegment = NULL;
+ nextSegment = aStartTrace;
+ }
+ else
+ {
+ /* Local bidirectional search: from this backward to aStartTrace
+ * AND forward to aEndTrace. The idea is that nearest segments
+ * are found (on average) faster in this way. In fact same-net
+ * segments are almost guaranteed to be found faster, in a global
+ * search, since they are grouped together in the track list */
+ previousSegment = this;
+ nextSegment = this;
+ }
+
+ while( nextSegment || previousSegment )
+ {
+ // Terminate the search in the direction if the netcode mismatches
+ if( aSameNetOnly )
+ {
+ if( nextSegment && (nextSegment->GetNetCode() != GetNetCode()) )
+ nextSegment = NULL;
+ if( previousSegment && (previousSegment->GetNetCode() != GetNetCode()) )
+ previousSegment = NULL;
+ }
+
+ if( nextSegment )
+ {
+ if ( (nextSegment != this) &&
+ !nextSegment->GetState( BUSY | IS_DELETED ) &&
+ ( refLayers & nextSegment->GetLayerSet() ).any() )
+ {
+ if( (position == nextSegment->m_Start) ||
+ (position == nextSegment->m_End) )
+ return nextSegment;
+ }
+
+ // Keep looking forward
+ if( nextSegment == aEndTrace )
+ nextSegment = NULL;
+ else
+ nextSegment = nextSegment->Next();
+ }
+
+ // Same as above, looking back. During sequential search this branch is inactive
+ if( previousSegment )
+ {
+ if( (previousSegment != this) &&
+ !previousSegment->GetState( BUSY | IS_DELETED ) &&
+ ( refLayers & previousSegment->GetLayerSet() ).any()
+ )
+ {
+ if( (position == previousSegment->m_Start) ||
+ (position == previousSegment->m_End) )
+ return previousSegment;
+ }
+
+ if( previousSegment == aStartTrace )
+ previousSegment = NULL;
+ else
+ previousSegment = previousSegment->Back();
+ }
+ }
+
+ return NULL;
+}
+
+
+int TRACK::GetEndSegments( int aCount, TRACK** aStartTrace, TRACK** aEndTrace )
+{
+ TRACK* Track, * via, * segm, * TrackListEnd;
+ int NbEnds, ii, ok = 0;
+ LSET layerMask;
+
+ if( aCount <= 1 )
+ {
+ *aStartTrace = *aEndTrace = this;
+ return 1;
+ }
+
+ // Calculation of the limit analysis.
+ *aStartTrace = *aEndTrace = NULL;
+ TrackListEnd = Track = this;
+ ii = 0;
+
+ for( ; ( Track != NULL ) && ( ii < aCount ); ii++, Track = Track->Next() )
+ {
+ TrackListEnd = Track;
+ Track->m_Param = 0;
+ }
+
+ // Calculate the extremes.
+ NbEnds = 0;
+ Track = this;
+ ii = 0;
+
+ for( ; ( Track != NULL ) && ( ii < aCount ); ii++, Track = Track->Next() )
+ {
+ if( Track->Type() == PCB_VIA_T )
+ continue;
+
+ layerMask = Track->GetLayerSet();
+ via = GetVia( TrackListEnd, Track->m_Start, layerMask );
+
+ if( via )
+ {
+ layerMask |= via->GetLayerSet();
+ via->SetState( BUSY, true );
+ }
+
+ Track->SetState( BUSY, true );
+ segm = ::GetTrack( this, TrackListEnd, Track->m_Start, layerMask );
+ Track->SetState( BUSY, false );
+
+ if( via )
+ via->SetState( BUSY, false );
+
+ if( segm == NULL )
+ {
+ switch( NbEnds )
+ {
+ case 0:
+ *aStartTrace = Track; NbEnds++;
+ break;
+
+ case 1:
+ int BeginPad, EndPad;
+ *aEndTrace = Track;
+
+ // Swap ox, oy with fx, fy
+ BeginPad = Track->GetState( BEGIN_ONPAD );
+ EndPad = Track->GetState( END_ONPAD );
+
+ Track->SetState( BEGIN_ONPAD | END_ONPAD, false );
+
+ if( BeginPad )
+ Track->SetState( END_ONPAD, true );
+
+ if( EndPad )
+ Track->SetState( BEGIN_ONPAD, true );
+
+ std::swap( Track->m_Start, Track->m_End );
+ std::swap( Track->start, Track->end );
+ ok = 1;
+ return ok;
+ }
+ }
+
+ layerMask = Track->GetLayerSet();
+ via = GetVia( TrackListEnd, Track->m_End, layerMask );
+
+ if( via )
+ {
+ layerMask |= via->GetLayerSet();
+ via->SetState( BUSY, true );
+ }
+
+ Track->SetState( BUSY, true );
+ segm = ::GetTrack( this, TrackListEnd, Track->m_End, layerMask );
+ Track->SetState( BUSY, false );
+
+ if( via )
+ via->SetState( BUSY, false );
+
+ if( segm == NULL )
+ {
+ switch( NbEnds )
+ {
+ case 0:
+ int BeginPad, EndPad;
+ *aStartTrace = Track;
+ NbEnds++;
+
+ // Swap ox, oy with fx, fy
+ BeginPad = Track->GetState( BEGIN_ONPAD );
+ EndPad = Track->GetState( END_ONPAD );
+
+ Track->SetState( BEGIN_ONPAD | END_ONPAD, false );
+
+ if( BeginPad )
+ Track->SetState( END_ONPAD, true );
+
+ if( EndPad )
+ Track->SetState( BEGIN_ONPAD, true );
+
+ std::swap( Track->m_Start, Track->m_End );
+ std::swap( Track->start, Track->end );
+ break;
+
+ case 1:
+ *aEndTrace = Track;
+ ok = 1;
+ return ok;
+ }
+ }
+ }
+
+ return ok;
+}
+
+
+wxString TRACK::GetSelectMenuText() const
+{
+ wxString text;
+ wxString netname;
+ NETINFO_ITEM* net;
+ BOARD* board = GetBoard();
+
+ // deleting tracks requires all the information we can get to
+ // disambiguate all the choices under the cursor!
+ if( board )
+ {
+ net = GetNet();
+
+ if( net )
+ netname = net->GetNetname();
+ else
+ netname = _("Not found");
+ }
+ else
+ {
+ wxFAIL_MSG( wxT( "TRACK::GetSelectMenuText: BOARD is NULL" ) );
+ netname = wxT( "???" );
+ }
+
+ text.Printf( _("Track %s, net [%s] (%d) on layer %s, length: %s" ),
+ GetChars( ShowWidth() ), GetChars( netname ),
+ GetNetCode(), GetChars( GetLayerName() ),
+ GetChars( ::LengthDoubleToString( GetLength() ) ) );
+
+ return text;
+}
+
+
+#if defined(DEBUG)
+
+wxString TRACK::ShowState( int stateBits )
+{
+ wxString ret;
+
+ if( stateBits & IS_LINKED )
+ ret << wxT( " | IS_LINKED" );
+
+ if( stateBits & TRACK_AR )
+ ret << wxT( " | TRACK_AR" );
+
+ if( stateBits & TRACK_LOCKED )
+ ret << wxT( " | TRACK_LOCKED" );
+
+ if( stateBits & IN_EDIT )
+ ret << wxT( " | IN_EDIT" );
+
+ if( stateBits & IS_DRAGGED )
+ ret << wxT( " | IS_DRAGGED" );
+
+ if( stateBits & DO_NOT_DRAW )
+ ret << wxT( " | DO_NOT_DRAW" );
+
+ if( stateBits & IS_DELETED )
+ ret << wxT( " | IS_DELETED" );
+
+ if( stateBits & BUSY )
+ ret << wxT( " | BUSY" );
+
+ if( stateBits & END_ONPAD )
+ ret << wxT( " | END_ONPAD" );
+
+ if( stateBits & BEGIN_ONPAD )
+ ret << wxT( " | BEGIN_ONPAD" );
+
+ if( stateBits & FLAG0 )
+ ret << wxT( " | FLAG0" );
+
+ if( stateBits & FLAG1 )
+ ret << wxT( " | FLAG1" );
+
+ return ret;
+}
+
+#endif
diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h
new file mode 100644
index 0000000..fd37d95
--- /dev/null
+++ b/pcbnew/class_track.h
@@ -0,0 +1,497 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_track.h
+ * @brief Definitions for tracks, vias and zones.
+ */
+
+#ifndef CLASS_TRACK_H
+#define CLASS_TRACK_H
+
+
+#include <pcbnew.h>
+#include <class_board_item.h>
+#include <class_board_connected_item.h>
+#include <PolyLine.h>
+#include <trigo.h>
+
+
+class TRACK;
+class VIA;
+class D_PAD;
+class MSG_PANEL_ITEM;
+
+
+// Via types
+enum VIATYPE_T
+{
+ VIA_THROUGH = 3, /* Always a through hole via */
+ VIA_BLIND_BURIED = 2, /* this via can be on internal layers */
+ VIA_MICROVIA = 1, /* this via which connect from an external layer
+ * to the near neighbor internal layer */
+ VIA_NOT_DEFINED = 0 /* not yet used */
+};
+
+#define UNDEFINED_DRILL_DIAMETER -1 //< Undefined via drill diameter.
+
+#define MIN_VIA_DRAW_SIZE 4 /// Minimum size in pixel for full drawing
+
+/**
+ * Function GetTrack
+ * is a helper function to locate a trace segment having an end point at \a aPosition
+ * on \a aLayerMask starting at \a aStartTrace and end at \a aEndTrace.
+ * <p>
+ * The segments of track that are flagged as deleted or busy are ignored. Layer
+ * visibility is also ignored.
+ * </p>
+ * @param aStartTrace A pointer to the TRACK object to begin searching.
+ * @param aEndTrace A pointer to the TRACK object to stop the search. A NULL value
+ * searches to the end of the list.
+ * @param aPosition A wxPoint object containing the position to test.
+ * @param aLayerMask A layer or layers to mask the hit test. Use -1 to ignore
+ * layer mask.
+ * @return A TRACK object pointer if found otherwise NULL.
+ */
+TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace,
+ const wxPoint& aPosition, LSET aLayerMask );
+
+class TRACK : public BOARD_CONNECTED_ITEM
+{
+public:
+ static inline bool ClassOf( const EDA_ITEM* aItem )
+ {
+ return aItem && PCB_TRACE_T == aItem->Type();
+ }
+
+ BOARD_CONNECTED_ITEM* start; // pointers to a connected item (pad or track)
+ BOARD_CONNECTED_ITEM* end;
+
+ double m_Param; // Auxiliary variable ( used in some computations )
+
+ TRACK( BOARD_ITEM* aParent, KICAD_T idtype = PCB_TRACE_T );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ TRACK* Next() const { return static_cast<TRACK*>( Pnext ); }
+ TRACK* Back() const { return static_cast<TRACK*>( Pback ); }
+
+ virtual void Move( const wxPoint& aMoveVector )
+ {
+ m_Start += aMoveVector;
+ m_End += aMoveVector;
+ }
+
+ virtual void Rotate( const wxPoint& aRotCentre, double aAngle );
+
+ virtual void Flip( const wxPoint& aCentre );
+
+ void SetPosition( const wxPoint& aPos ) { m_Start = aPos; } // was overload
+ const wxPoint& GetPosition() const { return m_Start; } // was overload
+
+ void SetWidth( int aWidth ) { m_Width = aWidth; }
+ int GetWidth() const { return m_Width; }
+
+ void SetEnd( const wxPoint& aEnd ) { m_End = aEnd; }
+ const wxPoint& GetEnd() const { return m_End; }
+
+ void SetStart( const wxPoint& aStart ) { m_Start = aStart; }
+ const wxPoint& GetStart() const { return m_Start; }
+
+
+ /// Return the selected endpoint (start or end)
+ const wxPoint& GetEndPoint( ENDPOINT_T aEndPoint ) const
+ {
+ if( aEndPoint == ENDPOINT_START )
+ return m_Start;
+ else
+ return m_End;
+ }
+
+ // Virtual function
+ const EDA_RECT GetBoundingBox() const;
+
+ /**
+ * Function GetBestInsertPoint
+ * searches the "best" insertion point within the track linked list.
+ * The best point is the begging of the corresponding net code section.
+ * (The BOARD::m_Track and BOARD::m_Zone lists are sorted by netcode.)
+ * @param aPcb The BOARD to search for the insertion point.
+ * @return TRACK* - the item found in the linked list (or NULL if no track)
+ */
+ TRACK* GetBestInsertPoint( BOARD* aPcb );
+
+ /* Search (within the track linked list) the first segment matching the netcode
+ * ( the linked list is always sorted by net codes )
+ */
+ TRACK* GetStartNetCode( int NetCode );
+
+ /* Search (within the track linked list) the last segment matching the netcode
+ * ( the linked list is always sorted by net codes )
+ */
+ TRACK* GetEndNetCode( int NetCode );
+
+ /**
+ * Function GetLength
+ * returns the length of the track using the hypotenuse calculation.
+ * @return double - the length of the track
+ */
+ double GetLength() const
+ {
+ return GetLineLength( m_Start, m_End );
+ }
+
+ /* Display on screen: */
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
+ GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset );
+
+ /**
+ * Function TransformShapeWithClearanceToPolygon
+ * Convert the track shape to a closed polygon
+ * Used in filling zones calculations
+ * Circles (vias) and arcs (ends of tracks) are approximated by segments
+ * @param aCornerBuffer = a buffer to store the polygon
+ * @param aClearanceValue = the clearance around the pad
+ * @param aCircleToSegmentsCount = the number of segments to approximate a circle
+ * @param aCorrectionFactor = the correction to apply to circles radius to keep
+ * clearance when the circle is approximated by segment bigger or equal
+ * to the real clearance value (usually near from 1.0)
+ */
+ void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
+ int aClearanceValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor ) const;
+ /**
+ * Function IsPointOnEnds
+ * returns STARTPOINT if point if near (dist = min_dist) start point, ENDPOINT if
+ * point if near (dist = min_dist) end point,STARTPOINT|ENDPOINT if point if near
+ * (dist = min_dist) both ends, or 0 if none of the above.
+ * if min_dist < 0: min_dist = track_width/2
+ */
+ STATUS_FLAGS IsPointOnEnds( const wxPoint& point, int min_dist = 0 );
+
+ /**
+ * Function IsNull
+ * returns true if segment length is zero.
+ */
+ bool IsNull();
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ /**
+ * Function ShowWidth
+ * returns the width of the track in displayable user units.
+ */
+ wxString ShowWidth() const;
+
+ SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
+ const KICAD_T scanTypes[] );
+
+
+ virtual bool HitTest( const wxPoint& aPosition ) const;
+
+ /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
+ * bool aContained = true, int aAccuracy ) const
+ */
+ virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const;
+
+ /**
+ * Function GetVia
+ * finds the first VIA object at \a aPosition on \a aLayer starting at the trace.
+ *
+ * @param aPosition The wxPoint to HitTest() against.
+ * @param aLayer The layer to match, pass -1 for a don't care.
+ * @return A pointer to a VIA object if found, else NULL.
+ */
+ VIA* GetVia( const wxPoint& aPosition, LAYER_ID aLayer = UNDEFINED_LAYER );
+
+ /**
+ * Function GetVia
+ * finds the first VIA object at \a aPosition on \a aLayer starting at the trace
+ * and ending at \a aEndTrace.
+ *
+ * @param aEndTrace Pointer to the last TRACK object to end search.
+ * @param aPosition The wxPoint to HitTest() against.
+ * @param aLayerMask The layers to match, pass -1 for a don't care.
+ * @return A pointer to a VIA object if found, else NULL.
+ */
+ VIA* GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LSET aLayerMask );
+
+ /**
+ * Function GetTrack
+ * return the trace segment connected to the segment at \a aEndPoint from \a
+ * aStartTrace to \a aEndTrace.
+ *
+ * @param aStartTrace A pointer to the TRACK object to begin searching.
+ * @param aEndTrace A pointer to the TRACK object to stop the search. A NULL value
+ * searches to the end of the list.
+ * @param aEndPoint The start or end point of the segment to test against.
+ * @param aSameNetOnly if true stop searching when the netcode changes
+ * @param aSequential If true, forces a forward sequential search,
+ * which is restartable; the default search can be faster but the
+ * position of the returned track in the list is unpredictable
+ * @return A TRACK object pointer if found otherwise NULL.
+ */
+ TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint,
+ bool aSameNetOnly, bool aSequential );
+
+ /**
+ * Function GetEndSegments
+ * get the segments connected to the end point of the track.
+ * return 1 if OK, 0 when a track is a closed loop
+ * and the beginning and the end of the track in *StartTrack and *EndTrack
+ * Modify *StartTrack en *EndTrack :
+ * (*StartTrack)->m_Start coordinate is the beginning of the track
+ * (*EndTrack)->m_End coordinate is the end of the track
+ * Segments connected must be consecutive in list
+ */
+ int GetEndSegments( int NbSegm, TRACK** StartTrack, TRACK** EndTrack );
+
+ wxString GetClass() const
+ {
+ return wxT( "TRACK" );
+ }
+
+ /**
+ * Function GetClearance
+ * returns the clearance in internal units. If \a aItem is not NULL then the
+ * returned clearance is the greater of this object's clearance and
+ * aItem's clearance. If \a aItem is NULL, then this objects clearance
+ * is returned.
+ * @param aItem is another BOARD_CONNECTED_ITEM or NULL
+ * @return int - the clearance in internal units.
+ */
+ virtual int GetClearance( BOARD_CONNECTED_ITEM* aItem = NULL ) const;
+
+ virtual wxString GetSelectMenuText() const;
+
+ virtual BITMAP_DEF GetMenuImage() const { return showtrack_xpm; }
+
+ virtual EDA_ITEM* Clone() const;
+
+ /// @copydoc VIEW_ITEM::ViewGetLayers()
+ virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
+
+ /// @copydoc VIEW_ITEM::ViewGetLOD()
+ virtual unsigned int ViewGetLOD( int aLayer ) const;
+
+#if defined (DEBUG)
+ virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+
+ /**
+ * Function ShowState
+ * converts a set of state bits to a wxString
+ * @param stateBits Is an OR-ed together set of bits like BUSY, EDIT, etc.
+ */
+ static wxString ShowState( int stateBits );
+
+#endif
+
+protected:
+ /**
+ * Function GetMsgPanelInfoBase
+ * Display info about the track segment only, and does not calculate the full track length
+ * @param aList A list of #MSG_PANEL_ITEM objects to add status information.
+ */
+ virtual void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList );
+
+
+ /**
+ * Helper function for the common panel info */
+ void GetMsgPanelInfoBase_Common( std::vector< MSG_PANEL_ITEM >& aList );
+
+ /**
+ * Helper for drawing the short netname in tracks */
+ void DrawShortNetname( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode,
+ EDA_COLOR_T aBgColor );
+
+ int m_Width; ///< Thickness of track, or via diameter
+ wxPoint m_Start; ///< Line start point
+ wxPoint m_End; ///< Line end point
+
+private:
+ // make SetNext() and SetBack() private so that they may not be called from anywhere.
+ // list management is done on TRACKs using DLIST<TRACK> only.
+ void SetNext( EDA_ITEM* aNext ) { Pnext = aNext; }
+ void SetBack( EDA_ITEM* aBack ) { Pback = aBack; }
+};
+
+
+class SEGZONE : public TRACK
+{
+public:
+ SEGZONE( BOARD_ITEM* aParent );
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ wxString GetClass() const
+ {
+ return wxT( "ZONE" );
+ }
+
+
+ SEGZONE* Next() const { return static_cast<SEGZONE*>( Pnext ); }
+
+ wxString GetSelectMenuText() const;
+
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
+ GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset );
+
+ BITMAP_DEF GetMenuImage() const { return add_zone_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+protected:
+ virtual void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList );
+};
+
+
+class VIA : public TRACK
+{
+public:
+ VIA( BOARD_ITEM* aParent );
+
+ static inline bool ClassOf( const EDA_ITEM *aItem )
+ {
+ return aItem && PCB_VIA_T == aItem->Type();
+ }
+
+ // Do not create a copy constructor. The one generated by the compiler is adequate.
+
+ void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
+ GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset );
+
+ bool IsOnLayer( LAYER_ID aLayer ) const;
+
+ virtual LSET GetLayerSet() const;
+
+ /**
+ * Function SetLayerPair
+ * For a via m_Layer contains the top layer, the other layer is in
+ * m_BottomLayer
+ * @param aTopLayer = first layer connected by the via
+ * @param aBottomLayer = last layer connected by the via
+ */
+ void SetLayerPair( LAYER_ID aTopLayer, LAYER_ID aBottomLayer );
+
+ /**
+ * Function LayerPair
+ * Return the 2 layers used by the via (the via actually uses
+ * all layers between these 2 layers)
+ * @param top_layer = pointer to the first layer (can be null)
+ * @param bottom_layer = pointer to the last layer (can be null)
+ */
+ void LayerPair( LAYER_ID* top_layer, LAYER_ID* bottom_layer ) const;
+
+ const wxPoint& GetPosition() const { return m_Start; } // was overload
+ void SetPosition( const wxPoint& aPoint ) { m_Start = aPoint; m_End = aPoint; } // was overload
+
+ virtual bool HitTest( const wxPoint& aPosition ) const;
+
+ virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const;
+
+ wxString GetClass() const
+ {
+ return wxT( "VIA" );
+ }
+
+ wxString GetSelectMenuText() const;
+
+ BITMAP_DEF GetMenuImage() const { return via_sketch_xpm; }
+
+ EDA_ITEM* Clone() const;
+
+ /// @copydoc VIEW_ITEM::ViewGetLayers()
+ virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
+
+ virtual void Flip( const wxPoint& aCentre );
+
+#if defined (DEBUG)
+ virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+
+ VIATYPE_T GetViaType() const { return m_ViaType; }
+ void SetViaType( VIATYPE_T aViaType ) { m_ViaType = aViaType; }
+
+ /**
+ * Function SetDrill
+ * sets the drill value for vias.
+ * @param aDrill is the new drill diameter
+ */
+ void SetDrill( int aDrill ) { m_Drill = aDrill; }
+
+ /**
+ * Function GetDrill
+ * returns the local drill setting for this VIA. If you want the calculated value,
+ * use GetDrillValue() instead.
+ */
+ int GetDrill() const { return m_Drill; }
+
+ /**
+ * Function GetDrillValue
+ * "calculates" the drill value for vias (m-Drill if > 0, or default
+ * drill value for the board.
+ * @return real drill_value
+ */
+ int GetDrillValue() const;
+
+ /**
+ * Function SetDrillDefault
+ * sets the drill value for vias to the default value #UNDEFINED_DRILL_DIAMETER.
+ */
+ void SetDrillDefault() { m_Drill = UNDEFINED_DRILL_DIAMETER; }
+
+ /**
+ * Function IsDrillDefault
+ * @return true if the drill value is default value (-1)
+ */
+ bool IsDrillDefault() const { return m_Drill <= 0; }
+
+protected:
+ virtual void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList );
+
+private:
+ /// The bottom layer of the via (the top layer is in m_Layer)
+ LAYER_ID m_BottomLayer;
+
+ VIATYPE_T m_ViaType; // Type of via
+
+ int m_Drill; // for vias: via drill (- 1 for default value)
+};
+
+
+/// Scan a track list for the first VIA o NULL if not found (or NULL passed)
+inline VIA* GetFirstVia( TRACK* aTrk, const TRACK* aStopPoint = NULL )
+{
+ while( aTrk && (aTrk != aStopPoint) && (aTrk->Type() != PCB_VIA_T) )
+ aTrk = aTrk->Next();
+
+ // It could stop because of the stop point, not on a via
+ if( aTrk && (aTrk->Type() == PCB_VIA_T) )
+ return static_cast<VIA*>( aTrk );
+ else
+ return NULL;
+}
+
+#endif // CLASS_TRACK_H
diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp
new file mode 100644
index 0000000..5a464fa
--- /dev/null
+++ b/pcbnew/class_zone.cpp
@@ -0,0 +1,856 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_zone.cpp
+ * @brief Implementation of class to handle copper zones.
+ */
+
+#include <fctsys.h>
+#include <wxstruct.h>
+#include <trigo.h>
+#include <class_pcb_screen.h>
+#include <class_drawpanel.h>
+#include <kicad_string.h>
+#include <pcbcommon.h>
+#include <colors_selection.h>
+#include <richio.h>
+#include <macros.h>
+#include <wxBasePcbFrame.h>
+#include <msgpanel.h>
+
+#include <class_board.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <zones.h>
+#include <math_for_graphics.h>
+#include <polygon_test_point_inside.h>
+
+
+ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) :
+ BOARD_CONNECTED_ITEM( aBoard, PCB_ZONE_AREA_T )
+{
+ m_CornerSelection = -1;
+ m_IsFilled = false; // fill status : true when the zone is filled
+ m_FillMode = 0; // How to fill areas: 0 = use filled polygons, != 0 fill with segments
+ m_priority = 0;
+ m_smoothedPoly = NULL;
+ m_cornerSmoothingType = ZONE_SETTINGS::SMOOTHING_NONE;
+ SetIsKeepout( false );
+ SetDoNotAllowCopperPour( false ); // has meaning only if m_isKeepout == true
+ SetDoNotAllowVias( true ); // has meaning only if m_isKeepout == true
+ SetDoNotAllowTracks( true ); // has meaning only if m_isKeepout == true
+ m_cornerRadius = 0;
+ SetLocalFlags( 0 ); // flags tempoarry used in zone calculations
+ m_Poly = new CPolyLine(); // Outlines
+ aBoard->GetZoneSettings().ExportSetting( *this );
+}
+
+
+ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone ) :
+ BOARD_CONNECTED_ITEM( aZone )
+{
+ m_smoothedPoly = NULL;
+
+ // Should the copy be on the same net?
+ SetNetCode( aZone.GetNetCode() );
+ m_Poly = new CPolyLine( *aZone.m_Poly );
+
+ // For corner moving, corner index to drag, or -1 if no selection
+ m_CornerSelection = -1;
+ m_IsFilled = aZone.m_IsFilled;
+ m_ZoneClearance = aZone.m_ZoneClearance; // clearance value
+ m_ZoneMinThickness = aZone.m_ZoneMinThickness;
+ m_FillMode = aZone.m_FillMode; // Filling mode (segments/polygons)
+ m_priority = aZone.m_priority;
+ m_ArcToSegmentsCount = aZone.m_ArcToSegmentsCount;
+ m_PadConnection = aZone.m_PadConnection;
+ m_ThermalReliefGap = aZone.m_ThermalReliefGap;
+ m_ThermalReliefCopperBridge = aZone.m_ThermalReliefCopperBridge;
+ m_FilledPolysList.Append( aZone.m_FilledPolysList );
+ m_FillSegmList = aZone.m_FillSegmList; // vector <> copy
+
+ m_isKeepout = aZone.m_isKeepout;
+ m_doNotAllowCopperPour = aZone.m_doNotAllowCopperPour;
+ m_doNotAllowVias = aZone.m_doNotAllowVias;
+ m_doNotAllowTracks = aZone.m_doNotAllowTracks;
+
+ m_cornerSmoothingType = aZone.m_cornerSmoothingType;
+ m_cornerRadius = aZone.m_cornerRadius;
+
+ SetLocalFlags( aZone.GetLocalFlags() );
+}
+
+
+ZONE_CONTAINER::~ZONE_CONTAINER()
+{
+ delete m_Poly;
+ m_Poly = NULL;
+}
+
+
+EDA_ITEM* ZONE_CONTAINER::Clone() const
+{
+ return new ZONE_CONTAINER( *this );
+}
+
+
+bool ZONE_CONTAINER::UnFill()
+{
+ bool change = ( !m_FilledPolysList.IsEmpty() ) ||
+ ( m_FillSegmList.size() > 0 );
+
+ m_FilledPolysList.RemoveAllContours();
+ m_FillSegmList.clear();
+ m_IsFilled = false;
+
+ return change;
+}
+
+
+const wxPoint& ZONE_CONTAINER::GetPosition() const
+{
+ static const wxPoint dummy;
+
+ return m_Poly ? GetCornerPosition( 0 ) : dummy;
+}
+
+
+void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode,
+ const wxPoint& offset )
+{
+ if( !DC )
+ return;
+
+ wxPoint seg_start, seg_end;
+ LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
+ BOARD* brd = GetBoard();
+
+ EDA_COLOR_T color = brd->GetLayerColor( m_Layer );
+
+ if( brd->IsLayerVisible( m_Layer ) == false && ( color & HIGHLIGHT_FLAG ) != HIGHLIGHT_FLAG )
+ return;
+
+ GRSetDrawMode( DC, aDrawMode );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
+
+ if( displ_opts->m_ContrastModeDisplay )
+ {
+ if( !IsOnLayer( curr_layer ) )
+ ColorTurnToDarkDarkGray( &color );
+ }
+
+ if( aDrawMode & GR_HIGHLIGHT )
+ ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) );
+
+ ColorApplyHighlightFlag( &color );
+
+ SetAlpha( &color, 150 );
+
+ // draw the lines
+ int i_start_contour = 0;
+ std::vector<wxPoint> lines;
+ lines.reserve( (GetNumCorners() * 2) + 2 );
+
+ for( int ic = 0; ic < GetNumCorners(); ic++ )
+ {
+ seg_start = GetCornerPosition( ic ) + offset;
+
+ if( !m_Poly->m_CornersList.IsEndContour( ic ) && ic < GetNumCorners() - 1 )
+ {
+ seg_end = GetCornerPosition( ic + 1 ) + offset;
+ }
+ else
+ {
+ seg_end = GetCornerPosition( i_start_contour ) + offset;
+ i_start_contour = ic + 1;
+ }
+
+ lines.push_back( seg_start );
+ lines.push_back( seg_end );
+ }
+
+ GRLineArray( panel->GetClipBox(), DC, lines, 0, color );
+
+ // draw hatches
+ lines.clear();
+ lines.reserve( (m_Poly->m_HatchLines.size() * 2) + 2 );
+
+ for( unsigned ic = 0; ic < m_Poly->m_HatchLines.size(); ic++ )
+ {
+ seg_start = m_Poly->m_HatchLines[ic].m_Start + offset;
+ seg_end = m_Poly->m_HatchLines[ic].m_End + offset;
+ lines.push_back( seg_start );
+ lines.push_back( seg_end );
+ }
+
+ GRLineArray( panel->GetClipBox(), DC, lines, 0, color );
+}
+
+
+void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel,
+ wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset )
+{
+ static std::vector <wxPoint> CornersBuffer;
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
+
+ // outline_mode is false to show filled polys,
+ // and true to show polygons outlines only (test and debug purposes)
+ bool outline_mode = displ_opts->m_DisplayZonesMode == 2 ? true : false;
+
+ if( DC == NULL )
+ return;
+
+ if( displ_opts->m_DisplayZonesMode == 1 ) // Do not show filled areas
+ return;
+
+ if( m_FilledPolysList.IsEmpty() ) // Nothing to draw
+ return;
+
+ BOARD* brd = GetBoard();
+ LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
+ EDA_COLOR_T color = brd->GetLayerColor( m_Layer );
+
+ if( brd->IsLayerVisible( m_Layer ) == false && ( color & HIGHLIGHT_FLAG ) != HIGHLIGHT_FLAG )
+ return;
+
+ GRSetDrawMode( DC, aDrawMode );
+
+ if( displ_opts->m_ContrastModeDisplay )
+ {
+ if( !IsOnLayer( curr_layer ) )
+ ColorTurnToDarkDarkGray( &color );
+ }
+
+ if( aDrawMode & GR_HIGHLIGHT )
+ ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) );
+
+ ColorApplyHighlightFlag( &color );
+
+ SetAlpha( &color, 150 );
+
+
+ for ( int ic = 0; ic < m_FilledPolysList.OutlineCount(); ic++ )
+ {
+ const SHAPE_LINE_CHAIN& path = m_FilledPolysList.COutline( ic );
+
+ CornersBuffer.clear();
+
+ wxPoint p0;
+
+ for( int j = 0; j < path.PointCount(); j++ )
+ {
+ const VECTOR2I& corner = path.CPoint( j );
+
+ wxPoint coord( corner.x + offset.x, corner.y + offset.y );
+
+ if( j == 0 )
+ p0 = coord;
+
+ CornersBuffer.push_back( coord );
+ }
+
+ CornersBuffer.push_back( p0 );
+
+ // Draw outlines:
+ if( ( m_ZoneMinThickness > 1 ) || outline_mode )
+ {
+ int ilim = CornersBuffer.size() - 1;
+
+ for( int is = 0, ie = ilim; is <= ilim; ie = is, is++ )
+ {
+ int x0 = CornersBuffer[is].x;
+ int y0 = CornersBuffer[is].y;
+ int x1 = CornersBuffer[ie].x;
+ int y1 = CornersBuffer[ie].y;
+
+ // Draw only basic outlines, not extra segments.
+ if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
+ GRCSegm( panel->GetClipBox(), DC,
+ x0, y0, x1, y1,
+ m_ZoneMinThickness, color );
+ else
+ GRFillCSegm( panel->GetClipBox(), DC,
+ x0, y0, x1, y1,
+ m_ZoneMinThickness, color );
+ }
+ }
+
+ // Draw areas:
+ if( m_FillMode == 0 && !outline_mode )
+ GRPoly( panel->GetClipBox(), DC, CornersBuffer.size(), &CornersBuffer[0],
+ true, 0, color, color );
+ }
+
+ if( m_FillMode == 1 && !outline_mode ) // filled with segments
+ {
+ for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
+ {
+ wxPoint start = m_FillSegmList[ic].m_Start + offset;
+ wxPoint end = m_FillSegmList[ic].m_End + offset;
+
+ if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
+ GRCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y,
+ m_ZoneMinThickness, color );
+ else
+ GRFillCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y,
+ m_ZoneMinThickness, color );
+ }
+ }
+}
+
+
+const EDA_RECT ZONE_CONTAINER::GetBoundingBox() const
+{
+ const int PRELOAD = 0x7FFFFFFF; // Biggest integer (32 bits)
+
+ int ymax = -PRELOAD;
+ int ymin = PRELOAD;
+ int xmin = PRELOAD;
+ int xmax = -PRELOAD;
+
+ int count = GetNumCorners();
+
+ for( int i = 0; i<count; ++i )
+ {
+ wxPoint corner = GetCornerPosition( i );
+
+ ymax = std::max( ymax, corner.y );
+ xmax = std::max( xmax, corner.x );
+ ymin = std::min( ymin, corner.y );
+ xmin = std::min( xmin, corner.x );
+ }
+
+ EDA_RECT ret( wxPoint( xmin, ymin ), wxSize( xmax - xmin + 1, ymax - ymin + 1 ) );
+
+ return ret;
+}
+
+
+void ZONE_CONTAINER::DrawWhileCreateOutline( EDA_DRAW_PANEL* panel, wxDC* DC,
+ GR_DRAWMODE draw_mode )
+{
+ GR_DRAWMODE current_gr_mode = draw_mode;
+ bool is_close_segment = false;
+
+ if( !DC )
+ return;
+
+ LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
+ BOARD* brd = GetBoard();
+ EDA_COLOR_T color = brd->GetLayerColor( m_Layer );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
+
+ if( displ_opts->m_ContrastModeDisplay )
+ {
+ if( !IsOnLayer( curr_layer ) )
+ ColorTurnToDarkDarkGray( &color );
+ }
+
+ // draw the lines
+ wxPoint start_contour_pos = GetCornerPosition( 0 );
+ int icmax = GetNumCorners() - 1;
+
+ for( int ic = 0; ic <= icmax; ic++ )
+ {
+ int xi = GetCornerPosition( ic ).x;
+ int yi = GetCornerPosition( ic ).y;
+ int xf, yf;
+
+ if( !m_Poly->m_CornersList.IsEndContour( ic ) && ic < icmax )
+ {
+ is_close_segment = false;
+ xf = GetCornerPosition( ic + 1 ).x;
+ yf = GetCornerPosition( ic + 1 ).y;
+
+ if( m_Poly->m_CornersList.IsEndContour( ic + 1 ) || (ic == icmax - 1) )
+ current_gr_mode = GR_XOR;
+ else
+ current_gr_mode = draw_mode;
+ }
+ else // Draw the line from last corner to the first corner of the current contour
+ {
+ is_close_segment = true;
+ current_gr_mode = GR_XOR;
+ xf = start_contour_pos.x;
+ yf = start_contour_pos.y;
+
+ // Prepare the next contour for drawing, if exists
+ if( ic < icmax )
+ start_contour_pos = GetCornerPosition( ic + 1 );
+ }
+
+ GRSetDrawMode( DC, current_gr_mode );
+
+ if( is_close_segment )
+ GRLine( panel->GetClipBox(), DC, xi, yi, xf, yf, 0, WHITE );
+ else
+ GRLine( panel->GetClipBox(), DC, xi, yi, xf, yf, 0, color );
+ }
+}
+
+
+int ZONE_CONTAINER::GetThermalReliefGap( D_PAD* aPad ) const
+{
+ if( aPad == NULL || aPad->GetThermalGap() == 0 )
+ return m_ThermalReliefGap;
+ else
+ return aPad->GetThermalGap();
+}
+
+
+int ZONE_CONTAINER::GetThermalReliefCopperBridge( D_PAD* aPad ) const
+{
+ if( aPad == NULL || aPad->GetThermalWidth() == 0 )
+ return m_ThermalReliefCopperBridge;
+ else
+ return aPad->GetThermalWidth();
+}
+
+
+void ZONE_CONTAINER::SetCornerRadius( unsigned int aRadius )
+{
+ m_cornerRadius = aRadius;
+ if( m_cornerRadius > (unsigned int) Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS ) )
+ m_cornerRadius = Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS );
+};
+
+
+bool ZONE_CONTAINER::HitTest( const wxPoint& aPosition ) const
+{
+ if( HitTestForCorner( aPosition ) >= 0 )
+ return true;
+
+ if( HitTestForEdge( aPosition ) >= 0 )
+ return true;
+
+ return false;
+}
+
+void ZONE_CONTAINER::SetSelectedCorner( const wxPoint& aPosition )
+{
+ m_CornerSelection = HitTestForCorner( aPosition );
+
+ if( m_CornerSelection < 0 )
+ m_CornerSelection = HitTestForEdge( aPosition );
+}
+
+
+// Zones outlines have no thickness, so it Hit Test functions
+// we must have a default distance between the test point
+// and a corner or a zone edge:
+#define MAX_DIST_IN_MM 0.25
+
+int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) const
+{
+ int distmax = Millimeter2iu( MAX_DIST_IN_MM );
+ return m_Poly->HitTestForCorner( refPos, distmax );
+}
+
+
+int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) const
+{
+ int distmax = Millimeter2iu( MAX_DIST_IN_MM );
+ return m_Poly->HitTestForEdge( refPos, distmax );
+}
+
+
+bool ZONE_CONTAINER::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
+{
+ EDA_RECT arect = aRect;
+ arect.Inflate( aAccuracy );
+ EDA_RECT bbox = m_Poly->GetBoundingBox();
+ bbox.Normalize();
+
+ if( aContained )
+ return arect.Contains( bbox );
+ else // Test for intersection between aRect and the polygon
+ // For a polygon, using its bounding box has no sense here
+ {
+ // Fast test: if aRect is outside the polygon bounding box,
+ // rectangles cannot intersect
+ if( ! bbox.Intersects( arect ) )
+ return false;
+
+ // aRect is inside the polygon bounding box,
+ // and can intersect the polygon: use a fine test.
+ // aRect intersects the polygon if at least one aRect corner
+ // is inside the polygon
+ wxPoint corner = arect.GetOrigin();
+
+ if( HitTestInsideZone( corner ) )
+ return true;
+
+ corner.x = arect.GetEnd().x;
+
+ if( HitTestInsideZone( corner ) )
+ return true;
+
+ corner = arect.GetEnd();
+
+ if( HitTestInsideZone( corner ) )
+ return true;
+
+ corner.x = arect.GetOrigin().x;
+
+ if( HitTestInsideZone( corner ) )
+ return true;
+
+ // No corner inside arect, but outlines can intersect arect
+ // if one of outline corners is inside arect
+ int count = m_Poly->GetCornersCount();
+ for( int ii =0; ii < count; ii++ )
+ {
+ if( arect.Contains( m_Poly->GetPos( ii ) ) )
+ return true;
+ }
+
+ return false;
+ }
+}
+
+
+int ZONE_CONTAINER::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
+{
+ int myClearance = m_ZoneClearance;
+
+#if 0 // Maybe the netclass clearance should not come into play for a zone?
+ // At least the policy decision can be controlled by the zone
+ // itself, i.e. here. On reasons of insufficient documentation,
+ // the user will be less bewildered if we simply respect the
+ // "zone clearance" setting in the zone properties dialog. (At least
+ // until there is a UI boolean for this.)
+
+ NETCLASSPTR myClass = GetNetClass();
+
+ if( myClass )
+ myClearance = std::max( myClearance, myClass->GetClearance() );
+#endif
+
+ if( aItem )
+ {
+ int hisClearance = aItem->GetClearance( NULL );
+ myClearance = std::max( hisClearance, myClearance );
+ }
+
+ return myClearance;
+}
+
+
+bool ZONE_CONTAINER::HitTestFilledArea( const wxPoint& aRefPos ) const
+{
+ return m_FilledPolysList.Contains( VECTOR2I( aRefPos.x, aRefPos.y ) );
+}
+
+
+void ZONE_CONTAINER::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
+{
+ wxString msg;
+
+ msg = _( "Zone Outline" );
+
+ // Display Cutout instead of Outline for holes inside a zone
+ // i.e. when num contour !=0
+ int ncont = m_Poly->GetContour( m_CornerSelection );
+
+ if( ncont )
+ msg << wxT( " " ) << _( "(Cutout)" );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) );
+
+ if( GetIsKeepout() )
+ {
+ msg.Empty();
+
+ if( GetDoNotAllowVias() )
+ AccumulateDescription( msg, _( "No via" ) );
+
+ if( GetDoNotAllowTracks() )
+ AccumulateDescription( msg, _("No track") );
+
+ if( GetDoNotAllowCopperPour() )
+ AccumulateDescription( msg, _("No copper pour") );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Keepout" ), msg, RED ) );
+ }
+ else if( IsOnCopperLayer() )
+ {
+ if( GetNetCode() >= 0 )
+ {
+ NETINFO_ITEM* net = GetNet();
+
+ if( net )
+ msg = net->GetNetname();
+ else // Should not occur
+ msg = _( "<unknown>" );
+ }
+ else // a netcode < 0 is an error
+ msg = wxT( "<error>" );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) );
+
+ // Display net code : (useful in test or debug)
+ msg.Printf( wxT( "%d" ), GetNetCode() );
+ aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) );
+
+ // Display priority level
+ msg.Printf( wxT( "%d" ), GetPriority() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Priority" ), msg, BLUE ) );
+ }
+ else
+ {
+ aList.push_back( MSG_PANEL_ITEM( _( "Non Copper Zone" ), wxEmptyString, RED ) );
+ }
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), GetLayerName(), BROWN ) );
+
+ msg.Printf( wxT( "%d" ), (int) m_Poly->m_CornersList.GetCornersCount() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Corners" ), msg, BLUE ) );
+
+ if( m_FillMode )
+ msg = _( "Segments" );
+ else
+ msg = _( "Polygons" );
+
+ aList.push_back( MSG_PANEL_ITEM( _( "Fill Mode" ), msg, BROWN ) );
+
+ // Useful for statistics :
+ msg.Printf( wxT( "%d" ), (int) m_Poly->m_HatchLines.size() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Hatch Lines" ), msg, BLUE ) );
+
+ if( !m_FilledPolysList.IsEmpty() )
+ {
+ msg.Printf( wxT( "%d" ), m_FilledPolysList.TotalVertices() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Corner Count" ), msg, BLUE ) );
+ }
+}
+
+
+/* Geometric transforms: */
+
+void ZONE_CONTAINER::Move( const wxPoint& offset )
+{
+ /* move outlines */
+ for( unsigned ii = 0; ii < m_Poly->m_CornersList.GetCornersCount(); ii++ )
+ {
+ SetCornerPosition( ii, GetCornerPosition( ii ) + offset );
+ }
+
+ m_Poly->Hatch();
+
+ m_FilledPolysList.Move( VECTOR2I( offset.x, offset.y ) );
+
+ for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
+ {
+ m_FillSegmList[ic].m_Start += offset;
+ m_FillSegmList[ic].m_End += offset;
+ }
+}
+
+
+void ZONE_CONTAINER::MoveEdge( const wxPoint& offset, int aEdge )
+{
+ // Move the start point of the selected edge:
+ SetCornerPosition( aEdge, GetCornerPosition( aEdge ) + offset );
+
+ // Move the end point of the selected edge:
+ if( m_Poly->m_CornersList.IsEndContour( aEdge ) || aEdge == GetNumCorners() - 1 )
+ {
+ int icont = m_Poly->GetContour( aEdge );
+ aEdge = m_Poly->GetContourStart( icont );
+ }
+ else
+ {
+ aEdge++;
+ }
+
+ SetCornerPosition( aEdge, GetCornerPosition( aEdge ) + offset );
+
+ m_Poly->Hatch();
+}
+
+
+void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle )
+{
+ wxPoint pos;
+
+ for( unsigned ic = 0; ic < m_Poly->m_CornersList.GetCornersCount(); ic++ )
+ {
+ pos = m_Poly->m_CornersList.GetPos( ic );
+ RotatePoint( &pos, centre, angle );
+ m_Poly->SetX( ic, pos.x );
+ m_Poly->SetY( ic, pos.y );
+ }
+
+ m_Poly->Hatch();
+
+ /* rotate filled areas: */
+ for( SHAPE_POLY_SET::ITERATOR ic = m_FilledPolysList.Iterate(); ic; ++ic )
+ RotatePoint( &ic->x, &ic->y, centre.x, centre.y, angle );
+
+ for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
+ {
+ RotatePoint( &m_FillSegmList[ic].m_Start, centre, angle );
+ RotatePoint( &m_FillSegmList[ic].m_End, centre, angle );
+ }
+}
+
+
+void ZONE_CONTAINER::Flip( const wxPoint& aCentre )
+{
+ Mirror( aCentre );
+ int copperLayerCount = GetBoard()->GetCopperLayerCount();
+ SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
+}
+
+
+void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref )
+{
+ for( unsigned ic = 0; ic < m_Poly->m_CornersList.GetCornersCount(); ic++ )
+ {
+ int py = mirror_ref.y - m_Poly->m_CornersList.GetY( ic );
+ m_Poly->m_CornersList.SetY( ic, py + mirror_ref.y );
+ }
+
+ m_Poly->Hatch();
+
+ for( SHAPE_POLY_SET::ITERATOR ic = m_FilledPolysList.Iterate(); ic; ++ic )
+ {
+ int py = mirror_ref.y - ic->y;
+ ic->y = py + mirror_ref.y;
+ }
+
+ for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
+ {
+ MIRROR( m_FillSegmList[ic].m_Start.y, mirror_ref.y );
+ MIRROR( m_FillSegmList[ic].m_End.y, mirror_ref.y );
+ }
+}
+
+
+void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src )
+{
+ m_Parent = src->m_Parent;
+ m_Layer = src->m_Layer;
+ SetNetCode( src->GetNetCode() );
+ SetTimeStamp( src->m_TimeStamp );
+ m_Poly->RemoveAllContours();
+ m_Poly->Copy( src->m_Poly ); // copy outlines
+ m_CornerSelection = -1; // For corner moving, corner index to drag,
+ // or -1 if no selection
+ m_ZoneClearance = src->m_ZoneClearance; // clearance value
+ m_ZoneMinThickness = src->m_ZoneMinThickness;
+ m_FillMode = src->m_FillMode; // Filling mode (segments/polygons)
+ m_ArcToSegmentsCount = src->m_ArcToSegmentsCount;
+ m_PadConnection = src->m_PadConnection;
+ m_ThermalReliefGap = src->m_ThermalReliefGap;
+ m_ThermalReliefCopperBridge = src->m_ThermalReliefCopperBridge;
+ m_Poly->SetHatchStyle( src->m_Poly->GetHatchStyle() );
+ m_Poly->SetHatchPitch( src->m_Poly->GetHatchPitch() );
+ m_Poly->m_HatchLines = src->m_Poly->m_HatchLines; // Copy vector <CSegment>
+ m_FilledPolysList.RemoveAllContours();
+ m_FilledPolysList.Append( src->m_FilledPolysList );
+ m_FillSegmList.clear();
+ m_FillSegmList = src->m_FillSegmList;
+}
+
+
+ZoneConnection ZONE_CONTAINER::GetPadConnection( D_PAD* aPad ) const
+{
+ if( aPad == NULL || aPad->GetZoneConnection() == PAD_ZONE_CONN_INHERITED )
+ return m_PadConnection;
+ else
+ return aPad->GetZoneConnection();
+}
+
+
+void ZONE_CONTAINER::AddPolygon( std::vector< wxPoint >& aPolygon )
+{
+ if( aPolygon.empty() )
+ return;
+
+ for( unsigned i = 0; i < aPolygon.size(); i++ )
+ {
+ if( i == 0 )
+ m_Poly->Start( GetLayer(), aPolygon[i].x, aPolygon[i].y, GetHatchStyle() );
+ else
+ AppendCorner( aPolygon[i] );
+ }
+
+ m_Poly->CloseLastContour();
+}
+
+
+
+wxString ZONE_CONTAINER::GetSelectMenuText() const
+{
+ wxString text;
+ NETINFO_ITEM* net;
+ BOARD* board = GetBoard();
+
+ int ncont = m_Poly->GetContour( m_CornerSelection );
+
+ if( ncont )
+ text << wxT( " " ) << _( "(Cutout)" );
+
+ if( GetIsKeepout() )
+ text << wxT( " " ) << _( "(Keepout)" );
+
+ text << wxString::Format( wxT( " (%08lX)" ), m_TimeStamp );
+
+ // Display net name for copper zones
+ if( !GetIsKeepout() )
+ {
+ if( GetNetCode() >= 0 )
+ {
+ if( board )
+ {
+ net = GetNet();
+
+ if( net )
+ {
+ text << wxT( " [" ) << net->GetNetname() << wxT( "]" );
+ }
+ }
+ else
+ {
+ text << _( "** NO BOARD DEFINED **" );
+ }
+ }
+ else
+ { // A netcode < 0 is an error:
+ // Netname not found or area not initialised
+ text << wxT( " [" ) << GetNetname() << wxT( "]" );
+ text << wxT( " <" ) << _( "Not Found" ) << wxT( ">" );
+ }
+ }
+
+ wxString msg;
+ msg.Printf( _( "Zone Outline %s on %s" ), GetChars( text ),
+ GetChars( GetLayerName() ) );
+
+ return msg;
+}
diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h
new file mode 100644
index 0000000..08d1259
--- /dev/null
+++ b/pcbnew/class_zone.h
@@ -0,0 +1,622 @@
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_zone.h
+ * @brief Classes to handle copper zones
+ */
+
+#ifndef CLASS_ZONE_H_
+#define CLASS_ZONE_H_
+
+
+#include <vector>
+#include <gr_basic.h>
+#include <class_board_item.h>
+#include <class_board_connected_item.h>
+#include <layers_id_colors_and_visibility.h>
+#include <PolyLine.h>
+#include <class_zone_settings.h>
+
+
+class EDA_RECT;
+class LINE_READER;
+class EDA_DRAW_PANEL;
+class PCB_EDIT_FRAME;
+class BOARD;
+class ZONE_CONTAINER;
+class MSG_PANEL_ITEM;
+
+
+/**
+ * Struct SEGMENT
+ * is a simple container used when filling areas with segments
+ */
+struct SEGMENT
+{
+ wxPoint m_Start; // starting point of a segment
+ wxPoint m_End; // ending point of a segment
+
+ SEGMENT() {}
+
+ SEGMENT( const wxPoint& aStart, const wxPoint& aEnd )
+ {
+ m_Start = aStart;
+ m_End = aEnd;
+ }
+};
+
+
+/**
+ * Class ZONE_CONTAINER
+ * handles a list of polygons defining a copper zone.
+ * A zone is described by a main polygon, a time stamp, a layer, and a net name.
+ * Other polygons inside the main polygon are holes in the zone.
+ */
+class ZONE_CONTAINER : public BOARD_CONNECTED_ITEM
+{
+public:
+
+ ZONE_CONTAINER( BOARD* parent );
+
+ ZONE_CONTAINER( const ZONE_CONTAINER& aZone );
+
+ ~ZONE_CONTAINER();
+
+ /**
+ * Function GetPosition
+ * @return a wxPoint, position of the first point of the outline
+ */
+ const wxPoint& GetPosition() const; // was overload
+ void SetPosition( const wxPoint& aPos ) {} // was overload
+
+ /**
+ * Function SetPriority
+ * @param aPriority = the priority level
+ */
+ void SetPriority( unsigned aPriority ) { m_priority = aPriority; }
+
+ /**
+ * Function GetPriority
+ * @return the priority level of this zone
+ */
+ unsigned GetPriority() const { return m_priority; }
+
+ /**
+ * Function copy
+ * copy useful data from the source.
+ * flags and linked list pointers are NOT copied
+ */
+ void Copy( ZONE_CONTAINER* src );
+
+ void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
+
+ /**
+ * Function Draw
+ * Draws the zone outline.
+ * @param panel = current Draw Panel
+ * @param DC = current Device Context
+ * @param aDrawMode = GR_OR, GR_XOR, GR_COPY ..
+ * @param offset = Draw offset (usually wxPoint(0,0))
+ */
+ void Draw( EDA_DRAW_PANEL* panel,
+ wxDC* DC,
+ GR_DRAWMODE aDrawMode,
+ const wxPoint& offset = ZeroOffset );
+
+ /**
+ * Function DrawDrawFilledArea
+ * Draws the filled area for this zone (polygon list .m_FilledPolysList)
+ * @param panel = current Draw Panel
+ * @param DC = current Device Context
+ * @param offset = Draw offset (usually wxPoint(0,0))
+ * @param aDrawMode = GR_OR, GR_XOR, GR_COPY ..
+ */
+ void DrawFilledArea( EDA_DRAW_PANEL* panel,
+ wxDC* DC,
+ GR_DRAWMODE aDrawMode,
+ const wxPoint& offset = ZeroOffset );
+
+ /**
+ * Function DrawWhileCreateOutline
+ * Draws the zone outline when it is created.
+ * The moving edges are in XOR graphic mode, old segment in draw_mode graphic mode
+ * (usually GR_OR). The closing edge has its own shape.
+ * @param panel = current Draw Panel
+ * @param DC = current Device Context
+ * @param draw_mode = draw mode: OR, XOR ..
+ */
+ void DrawWhileCreateOutline( EDA_DRAW_PANEL* panel, wxDC* DC,
+ GR_DRAWMODE draw_mode = GR_OR );
+
+ /** Function GetBoundingBox (virtual)
+ * @return an EDA_RECT that is the bounding box of the zone outline
+ */
+ const EDA_RECT GetBoundingBox() const;
+
+ int GetClearance( BOARD_CONNECTED_ITEM* aItem = NULL ) const;
+
+ /**
+ * Function TestForCopperIslandAndRemoveInsulatedIslands
+ * Remove insulated copper islands found in m_FilledPolysList.
+ * @param aPcb = the board to analyze
+ */
+ void TestForCopperIslandAndRemoveInsulatedIslands( BOARD* aPcb );
+
+ /**
+ * Function IsOnCopperLayer
+ * @return true if this zone is on a copper layer, false if on a technical layer
+ */
+ bool IsOnCopperLayer() const
+ {
+ return IsCopperLayer( GetLayer() );
+ }
+
+ /// How to fill areas: 0 = use filled polygons, 1 => fill with segments.
+ void SetFillMode( int aFillMode ) { m_FillMode = aFillMode; }
+ int GetFillMode() const { return m_FillMode; }
+
+ void SetThermalReliefGap( int aThermalReliefGap ) { m_ThermalReliefGap = aThermalReliefGap; }
+ int GetThermalReliefGap( D_PAD* aPad = NULL ) const;
+
+ void SetThermalReliefCopperBridge( int aThermalReliefCopperBridge )
+ {
+ m_ThermalReliefCopperBridge = aThermalReliefCopperBridge;
+ }
+ int GetThermalReliefCopperBridge( D_PAD* aPad = NULL ) const;
+
+ void SetArcSegmentCount( int aArcSegCount ) { m_ArcToSegmentsCount = aArcSegCount; }
+ int GetArcSegmentCount() const { return m_ArcToSegmentsCount; }
+
+ bool IsFilled() const { return m_IsFilled; }
+ void SetIsFilled( bool isFilled ) { m_IsFilled = isFilled; }
+
+ int GetZoneClearance() const { return m_ZoneClearance; }
+ void SetZoneClearance( int aZoneClearance ) { m_ZoneClearance = aZoneClearance; }
+
+ ZoneConnection GetPadConnection( D_PAD* aPad = NULL ) const;
+ void SetPadConnection( ZoneConnection aPadConnection ) { m_PadConnection = aPadConnection; }
+
+ int GetMinThickness() const { return m_ZoneMinThickness; }
+ void SetMinThickness( int aMinThickness ) { m_ZoneMinThickness = aMinThickness; }
+
+ int GetSelectedCorner() const { return m_CornerSelection; }
+ void SetSelectedCorner( int aCorner ) { m_CornerSelection = aCorner; }
+
+ ///
+ // Like HitTest but selects the current corner to be operated on
+ void SetSelectedCorner( const wxPoint& aPosition );
+
+ int GetLocalFlags() const { return m_localFlgs; }
+ void SetLocalFlags( int aFlags ) { m_localFlgs = aFlags; }
+
+ std::vector <SEGMENT>& FillSegments() { return m_FillSegmList; }
+ const std::vector <SEGMENT>& FillSegments() const { return m_FillSegmList; }
+
+ CPolyLine* Outline() { return m_Poly; }
+ const CPolyLine* Outline() const { return const_cast< CPolyLine* >( m_Poly ); }
+
+ void SetOutline( CPolyLine* aOutline ) { m_Poly = aOutline; }
+
+ /**
+ * Function HitTest
+ * tests if a point is near an outline edge or a corner of this zone.
+ * @param aPosition the wxPoint to test
+ * @return bool - true if a hit, else false
+ */
+ virtual bool HitTest( const wxPoint& aPosition ) const;
+
+ /**
+ * Function HitTest
+ * tests if a point is inside the zone area, i.e. inside the main outline
+ * and outside holes.
+ * @param aPosition : the wxPoint to test
+ * @return bool - true if a hit, else false
+ */
+ bool HitTestInsideZone( const wxPoint& aPosition ) const
+ {
+ return m_Poly->TestPointInside( aPosition.x, aPosition.y );
+ }
+
+ /**
+ * Function HitTestFilledArea
+ * tests if the given wxPoint is within the bounds of a filled area of this zone.
+ * @param aRefPos A wxPoint to test
+ * @return bool - true if a hit, else false
+ */
+ bool HitTestFilledArea( const wxPoint& aRefPos ) const;
+
+ /**
+ * Function TransformSolidAreasShapesToPolygonSet
+ * Convert solid areas full shapes to polygon set
+ * (the full shape is the polygon area with a thick outline)
+ * Used in 3D view
+ * Arcs (ends of segments) are approximated by segments
+ * @param aCornerBuffer = a buffer to store the polygons
+ * @param aCircleToSegmentsCount = the number of segments to approximate a circle
+ * @param aCorrectionFactor = the correction to apply to arcs radius to roughly
+ * keep arc radius when approximated by segments
+ */
+ void TransformSolidAreasShapesToPolygonSet( SHAPE_POLY_SET& aCornerBuffer,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor );
+ /**
+ * Function BuildFilledSolidAreasPolygons
+ * Build the filled solid areas data from real outlines (stored in m_Poly)
+ * The solid areas can be more than one on copper layers, and do not have holes
+ ( holes are linked by overlapping segments to the main outline)
+ * in order to have drawable (and plottable) filled polygons
+ * @return true if OK, false if the solid polygons cannot be built
+ * @param aPcb: the current board (can be NULL for non copper zones)
+ * @param aCornerBuffer: A reference to a buffer to store polygon corners, or NULL
+ * if NULL (default:
+ * - m_FilledPolysList is used to store solid areas polygons.
+ * - on copper layers, tracks and other items shapes of other nets are
+ * removed from solid areas
+ * if not null:
+ * Only the zone outline (with holes, if any) is stored in aOutlineBuffer
+ * with holes linked. Therefore only one polygon is created
+ *
+ * When aOutlineBuffer is not null, his function calls
+ * AddClearanceAreasPolygonsToPolysList() to add holes for pads and tracks
+ * and other items not in net.
+ */
+ bool BuildFilledSolidAreasPolygons( BOARD* aPcb, SHAPE_POLY_SET* aOutlineBuffer = NULL );
+
+ /**
+ * Function AddClearanceAreasPolygonsToPolysList
+ * Add non copper areas polygons (pads and tracks with clearance)
+ * to a filled copper area
+ * used in BuildFilledSolidAreasPolygons when calculating filled areas in a zone
+ * Non copper areas are pads and track and their clearance area
+ * The filled copper area must be computed before
+ * BuildFilledSolidAreasPolygons() call this function just after creating the
+ * filled copper area polygon (without clearance areas
+ * @param aPcb: the current board
+ * _NG version uses SHAPE_POLY_SET instead of Boost.Polygon
+ */
+ void AddClearanceAreasPolygonsToPolysList( BOARD* aPcb );
+ void AddClearanceAreasPolygonsToPolysList_NG( BOARD* aPcb );
+
+
+ /**
+ * Function TransformOutlinesShapeWithClearanceToPolygon
+ * Convert the outlines shape to a polygon with no holes
+ * inflated (optional) by max( aClearanceValue, the zone clearance)
+ * (holes are linked to external outline by overlapping segments)
+ * Used in filling zones calculations
+ * Circles (vias) and arcs (ends of tracks) are approximated by segments
+ * @param aCornerBuffer = a buffer to store the polygon
+ * @param aMinClearanceValue = the min clearance around outlines
+ * @param aUseNetClearance = true to use a clearance which is the max value between
+ * aMinClearanceValue and the net clearance
+ * false to use aMinClearanceValue only
+ * if both aMinClearanceValue = 0 and aUseNetClearance = false: create the zone outline polygon.
+ */
+ void TransformOutlinesShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
+ int aMinClearanceValue,
+ bool aUseNetClearance );
+ /**
+ * Function HitTestForCorner
+ * tests if the given wxPoint near a corner
+ * Set m_CornerSelection to -1 if nothing found, or index of corner
+ * @return true if found
+ * @param refPos : A wxPoint to test
+ */
+ int HitTestForCorner( const wxPoint& refPos ) const;
+
+ /**
+ * Function HitTestForEdge
+ * tests if the given wxPoint is near a segment defined by 2 corners.
+ * Set m_CornerSelection to -1 if nothing found, or index of the starting corner of vertice
+ * @return true if found
+ * @param refPos : A wxPoint to test
+ */
+ int HitTestForEdge( const wxPoint& refPos ) const;
+
+ /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect,
+ * bool aContained = true, int aAccuracy ) const
+ */
+ bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const;
+
+ /**
+ * Function FillZoneAreasWithSegments
+ * Fill sub areas in a zone with segments with m_ZoneMinThickness width
+ * A scan is made line per line, on the whole filled areas, with a step of m_ZoneMinThickness.
+ * all intersecting points with the horizontal infinite line and polygons to fill are calculated
+ * a list of SEGZONE items is built, line per line
+ * @return number of segments created
+ */
+ int FillZoneAreasWithSegments();
+
+ /**
+ * Function UnFill
+ * Removes the zone filling
+ * @return true if a previous filling is removed, false if no change
+ * (when no filling found)
+ */
+ bool UnFill();
+
+ /* Geometric transformations: */
+
+ /**
+ * Function Move
+ * Move the outlines
+ * @param offset = moving vector
+ */
+ void Move( const wxPoint& offset );
+
+ /**
+ * Function MoveEdge
+ * Move the outline Edge
+ * @param offset = moving vector
+ * @param aEdge = start point of the outline edge
+ */
+ void MoveEdge( const wxPoint& offset, int aEdge );
+
+ /**
+ * Function Rotate
+ * Move the outlines
+ * @param centre = rot centre
+ * @param angle = in 0.1 degree
+ */
+ void Rotate( const wxPoint& centre, double angle );
+
+ /**
+ * Function Flip
+ * Flip this object, i.e. change the board side for this object
+ * (like Mirror() but changes layer)
+ * @param aCentre - the rotation point.
+ */
+ virtual void Flip( const wxPoint& aCentre );
+
+ /**
+ * Function Mirror
+ * Mirror the outlines , relative to a given horizontal axis
+ * the layer is not changed
+ * @param mirror_ref = vertical axis position
+ */
+ void Mirror( const wxPoint& mirror_ref );
+
+ /**
+ * Function GetClass
+ * returns the class name.
+ * @return wxString
+ */
+ wxString GetClass() const
+ {
+ return wxT( "ZONE_CONTAINER" );
+ }
+
+ /** Access to m_Poly parameters
+ */
+
+
+ int GetNumCorners( void ) const
+ {
+ return m_Poly->GetCornersCount();
+ }
+
+ void RemoveAllContours( void )
+ {
+ m_Poly->RemoveAllContours();
+ }
+
+ const wxPoint& GetCornerPosition( int aCornerIndex ) const
+ {
+ return m_Poly->GetPos( aCornerIndex );
+ }
+
+ void SetCornerPosition( int aCornerIndex, wxPoint new_pos )
+ {
+ m_Poly->SetX( aCornerIndex, new_pos.x );
+ m_Poly->SetY( aCornerIndex, new_pos.y );
+ }
+
+ void AppendCorner( wxPoint position )
+ {
+ m_Poly->AppendCorner( position.x, position.y );
+ }
+
+ int GetHatchStyle() const
+ {
+ return m_Poly->GetHatchStyle();
+ }
+
+ void SetHatchStyle( CPolyLine::HATCH_STYLE aStyle )
+ {
+ m_Poly->SetHatchStyle( aStyle );
+ }
+
+ /**
+ * Function IsSame
+ * tests if 2 zones are equivalent:
+ * 2 zones are equivalent if they have same parameters and same outlines
+ * info, filling is not taken into account
+ * @param aZoneToCompare = zone to compare with "this"
+ */
+ bool IsSame( const ZONE_CONTAINER &aZoneToCompare );
+
+ /**
+ * Function ClearFilledPolysList
+ * clears the list of filled polygons.
+ */
+ void ClearFilledPolysList()
+ {
+ m_FilledPolysList.RemoveAllContours();
+ }
+
+ /**
+ * Function GetFilledPolysList
+ * returns a reference to the list of filled polygons.
+ * @return Reference to the list of filled polygons.
+ */
+ const SHAPE_POLY_SET& GetFilledPolysList() const
+ {
+ return m_FilledPolysList;
+ }
+
+ /**
+ * Function AddFilledPolysList
+ * sets the list of filled polygons.
+ */
+ void AddFilledPolysList( SHAPE_POLY_SET& aPolysList )
+ {
+ m_FilledPolysList = aPolysList;
+ }
+
+ /**
+ * Function GetSmoothedPoly
+ * returns a pointer to the corner-smoothed version of
+ * m_Poly if it exists, otherwise it returns m_Poly.
+ * @return CPolyLine* - pointer to the polygon.
+ */
+ CPolyLine* GetSmoothedPoly() const
+ {
+ if( m_smoothedPoly )
+ return m_smoothedPoly;
+ else
+ return m_Poly;
+ };
+
+ void SetCornerSmoothingType( int aType ) { m_cornerSmoothingType = aType; };
+
+ int GetCornerSmoothingType() const { return m_cornerSmoothingType; };
+
+ void SetCornerRadius( unsigned int aRadius );
+
+ unsigned int GetCornerRadius() const { return m_cornerRadius; };
+
+ void AddPolygon( std::vector< wxPoint >& aPolygon );
+
+ void AddFilledPolygon( SHAPE_POLY_SET& aPolygon )
+ {
+ m_FilledPolysList.Append( aPolygon );
+ }
+
+ void AddFillSegments( std::vector< SEGMENT >& aSegments )
+ {
+ m_FillSegmList.insert( m_FillSegmList.end(), aSegments.begin(), aSegments.end() );
+ }
+
+ virtual wxString GetSelectMenuText() const;
+
+ virtual BITMAP_DEF GetMenuImage() const { return add_zone_xpm; }
+
+ virtual EDA_ITEM* Clone() const;
+
+ /**
+ * Accessors to parameters used in Keepout zones:
+ */
+ bool GetIsKeepout() const { return m_isKeepout; }
+ bool GetDoNotAllowCopperPour() const { return m_doNotAllowCopperPour; }
+ bool GetDoNotAllowVias() const { return m_doNotAllowVias; }
+ bool GetDoNotAllowTracks() const { return m_doNotAllowTracks; }
+
+ void SetIsKeepout( bool aEnable ) { m_isKeepout = aEnable; }
+ void SetDoNotAllowCopperPour( bool aEnable ) { m_doNotAllowCopperPour = aEnable; }
+ void SetDoNotAllowVias( bool aEnable ) { m_doNotAllowVias = aEnable; }
+ void SetDoNotAllowTracks( bool aEnable ) { m_doNotAllowTracks = aEnable; }
+
+#if defined(DEBUG)
+ virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
+#endif
+
+
+
+private:
+ void buildFeatureHoleList( BOARD* aPcb, SHAPE_POLY_SET& aFeatures );
+
+ CPolyLine* m_Poly; ///< Outline of the zone.
+ CPolyLine* m_smoothedPoly; // Corner-smoothed version of m_Poly
+ int m_cornerSmoothingType;
+ unsigned int m_cornerRadius;
+
+ /* Priority: when a zone outline is inside and other zone, if its priority is higher
+ * the other zone priority, it will be created inside.
+ * if priorities are equal, a DRC error is set
+ */
+ unsigned m_priority;
+
+ /* A zone outline can be a keepout zone.
+ * It will be never filled, and DRC should test for pads, tracks and vias
+ */
+ bool m_isKeepout;
+
+ /* For keepout zones only:
+ * what is not allowed inside the keepout ( pads, tracks and vias )
+ */
+ bool m_doNotAllowCopperPour;
+ bool m_doNotAllowVias;
+ bool m_doNotAllowTracks;
+
+ ZoneConnection m_PadConnection;
+ int m_ZoneClearance; ///< Clearance value in internal units.
+ int m_ZoneMinThickness; ///< Minimum thickness value in filled areas.
+
+ /** The number of segments to convert a circle to a polygon. Valid values are
+ #ARC_APPROX_SEGMENTS_COUNT_LOW_DEF or #ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF. */
+ int m_ArcToSegmentsCount;
+
+ /** True when a zone was filled, false after deleting the filled areas. */
+ bool m_IsFilled;
+
+ ///< Width of the gap in thermal reliefs.
+ int m_ThermalReliefGap;
+
+ ///< Width of the copper bridge in thermal reliefs.
+ int m_ThermalReliefCopperBridge;
+
+
+ /// How to fill areas: 0 => use filled polygons, 1 => fill with segments.
+ int m_FillMode;
+
+ /// The index of the corner being moved or -1 if no corner is selected.
+ int m_CornerSelection;
+
+ /// Variable used in polygon calculations.
+ int m_localFlgs;
+
+ /** Segments used to fill the zone (#m_FillMode ==1 ), when fill zone by segment is used.
+ * In this case the segments have #m_ZoneMinThickness width.
+ */
+ std::vector <SEGMENT> m_FillSegmList;
+
+ /* set of filled polygons used to draw a zone as a filled area.
+ * from outlines (m_Poly) but unlike m_Poly these filled polygons have no hole
+ * (they are all in one piece) In very simple cases m_FilledPolysList is same
+ * as m_Poly. In less simple cases (when m_Poly has holes) m_FilledPolysList is
+
+
+
+ * a polygon equivalent to m_Poly, without holes but with extra outline segment
+ * connecting "holes" with external main outline. In complex cases an outline
+ * described by m_Poly can have many filled areas
+ */
+ SHAPE_POLY_SET m_FilledPolysList;
+};
+
+
+#endif // CLASS_ZONE_H_
diff --git a/pcbnew/class_zone_settings.cpp b/pcbnew/class_zone_settings.cpp
new file mode 100644
index 0000000..9dc88ba
--- /dev/null
+++ b/pcbnew/class_zone_settings.cpp
@@ -0,0 +1,135 @@
+/**
+ * @brief class ZONE_SETTINGS used to handle zones parameters
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+
+#include <convert_to_biu.h>
+#include <pcbnew.h>
+#include <zones.h>
+
+#include <class_zone.h>
+
+ZONE_SETTINGS::ZONE_SETTINGS()
+{
+ m_ZonePriority = 0;
+ m_FillMode = 0; // Mode for filling zone : 1 use segments, 0 use polygons
+ // Clearance value
+ m_ZoneClearance = Mils2iu( ZONE_CLEARANCE_MIL );
+ // Min thickness value in filled areas (this is the minimum width of copper to fill solid areas) :
+ m_ZoneMinThickness = Mils2iu( ZONE_THICKNESS_MIL );
+ m_NetcodeSelection = 0; // Net code selection for the current zone
+ m_CurrentZone_Layer = F_Cu; // Layer used to create the current zone
+ m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE; // Option to show the zone area (outlines only, short hatches or full hatches
+
+ m_ArcToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF; // Option to select number of segments to approximate a circle
+ // ARC_APPROX_SEGMENTS_COUNT_LOW_DEF
+ // or ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF segments
+
+ // thickness of the gap in thermal reliefs:
+ m_ThermalReliefGap = Mils2iu( ZONE_THERMAL_RELIEF_GAP_MIL );
+ // thickness of the copper bridge in thermal reliefs:
+ m_ThermalReliefCopperBridge = Mils2iu( ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL );
+
+ m_PadConnection = PAD_ZONE_CONN_THERMAL; // How pads are covered by copper in zone
+
+ m_Zone_45_Only = false;
+
+ m_cornerSmoothingType = SMOOTHING_NONE;
+ m_cornerRadius = 0;
+
+ SetIsKeepout( false );
+ SetDoNotAllowCopperPour( false );
+ SetDoNotAllowVias( true );
+ SetDoNotAllowTracks( true );
+}
+
+
+ZONE_SETTINGS& ZONE_SETTINGS::operator << ( const ZONE_CONTAINER& aSource )
+{
+ m_ZonePriority = aSource.GetPriority();
+ m_FillMode = aSource.GetFillMode();
+ m_ZoneClearance = aSource.GetClearance();
+ m_ZoneMinThickness = aSource.GetMinThickness();
+ m_NetcodeSelection = aSource.GetNetCode();
+ m_CurrentZone_Layer = aSource.GetLayer();
+ m_Zone_HatchingStyle = aSource.GetHatchStyle();
+ m_ArcToSegmentsCount = aSource.GetArcSegmentCount();
+ m_ThermalReliefGap = aSource.GetThermalReliefGap();
+ m_ThermalReliefCopperBridge = aSource.GetThermalReliefCopperBridge();
+ m_PadConnection = aSource.GetPadConnection();
+ m_cornerSmoothingType = aSource.GetCornerSmoothingType();
+ m_cornerRadius = aSource.GetCornerRadius();
+ m_isKeepout = aSource.GetIsKeepout();
+ m_keepoutDoNotAllowCopperPour = aSource.GetDoNotAllowCopperPour();
+ m_keepoutDoNotAllowVias = aSource.GetDoNotAllowVias();
+ m_keepoutDoNotAllowTracks = aSource.GetDoNotAllowTracks();
+
+ return *this;
+}
+
+
+void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) const
+{
+ aTarget.SetFillMode( m_FillMode );
+ aTarget.SetZoneClearance( m_ZoneClearance );
+ aTarget.SetMinThickness( m_ZoneMinThickness );
+ aTarget.SetArcSegmentCount( m_ArcToSegmentsCount );
+ aTarget.SetThermalReliefGap( m_ThermalReliefGap );
+ aTarget.SetThermalReliefCopperBridge( m_ThermalReliefCopperBridge );
+ aTarget.SetPadConnection( m_PadConnection );
+ aTarget.SetCornerSmoothingType( m_cornerSmoothingType );
+ aTarget.SetCornerRadius( m_cornerRadius );
+ aTarget.SetIsKeepout( GetIsKeepout() );
+ aTarget.SetDoNotAllowCopperPour( GetDoNotAllowCopperPour() );
+ aTarget.SetDoNotAllowVias( GetDoNotAllowVias() );
+ aTarget.SetDoNotAllowTracks( GetDoNotAllowTracks() );
+
+ if( aFullExport )
+ {
+ aTarget.SetPriority( m_ZonePriority );
+ aTarget.SetNetCode( m_NetcodeSelection );
+ aTarget.SetLayer( m_CurrentZone_Layer );
+ aTarget.Outline()->SetLayer( m_CurrentZone_Layer );
+ }
+
+ // call SetHatch last, because hatch lines will be rebuilt,
+ // using new parameters values
+ aTarget.Outline()->SetHatch( m_Zone_HatchingStyle, Mils2iu( 20 ), true );
+}
+
+
+void ZONE_SETTINGS::SetCornerRadius( int aRadius )
+{
+ if( aRadius > Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS ) )
+ m_cornerRadius = Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS );
+ else if( aRadius < 0 )
+ m_cornerRadius = 0;
+ else
+ m_cornerRadius = aRadius;
+};
diff --git a/pcbnew/class_zone_settings.h b/pcbnew/class_zone_settings.h
new file mode 100644
index 0000000..d2a4611
--- /dev/null
+++ b/pcbnew/class_zone_settings.h
@@ -0,0 +1,146 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2008-2014 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file class_zone_settings.h
+ * @brief Class ZONE_SETTINGS used to handle zones parameters in dialogs.
+ */
+
+#ifndef ZONE_SETTINGS_H_
+#define ZONE_SETTINGS_H_
+
+#include "zones.h"
+
+
+class ZONE_CONTAINER;
+
+
+#define MAX_ZONE_CORNER_RADIUS_MILS 400
+
+
+/**
+ * Class ZONE_SETTINGS
+ * handles zones parameters.
+ * Because a zone can be on copper or non copper layers, and can be also
+ * a keepout area, some parameters are irrelevant depending on the type of zone
+ */
+class ZONE_SETTINGS
+{
+public:
+ enum {
+ SMOOTHING_NONE,
+ SMOOTHING_CHAMFER,
+ SMOOTHING_FILLET,
+ SMOOTHING_LAST
+ };
+
+ /// Mode for filling zone : 1 use segments, 0 use polygons
+ int m_FillMode;
+
+ int m_ZonePriority; ///< Priority (0 ... N) of the zone
+
+ int m_ZoneClearance; ///< Clearance value
+ int m_ZoneMinThickness; ///< Min thickness value in filled areas
+ int m_NetcodeSelection; ///< Net code selection for the current zone
+
+ LAYER_ID m_CurrentZone_Layer; ///< Layer used to create the current zone
+
+ /// Option to show the zone area (outlines only, short hatches or full hatches
+ int m_Zone_HatchingStyle;
+
+ /// Option to select number of segments to approximate a circle 16 or 32 segments.
+ int m_ArcToSegmentsCount;
+
+ long m_ThermalReliefGap; ///< thickness of the gap in thermal reliefs
+ long m_ThermalReliefCopperBridge; ///< thickness of the copper bridge in thermal reliefs
+
+ bool m_Zone_45_Only;
+
+private:
+ int m_cornerSmoothingType; ///< Corner smoothing type
+ unsigned int m_cornerRadius; ///< Corner chamfer distance / fillet radius
+ ZoneConnection m_PadConnection;
+
+ /* A zone outline can be a keepout zone.
+ * It will be never filled, and DRC should test for pads, tracks and vias
+ */
+ bool m_isKeepout;
+
+ /* For keepout zones only:
+ * what is not allowed inside the keepout ( pads, tracks and vias )
+ */
+ bool m_keepoutDoNotAllowCopperPour;
+ bool m_keepoutDoNotAllowVias;
+ bool m_keepoutDoNotAllowTracks;
+
+
+public:
+ ZONE_SETTINGS();
+
+ /**
+ * operator << ( const ZONE_CONTAINER& )
+ * was Function ImportSetting
+ * copies settings from a given zone into this object.
+ * @param aSource: the given zone
+ */
+ ZONE_SETTINGS& operator << ( const ZONE_CONTAINER& aSource );
+
+ /**
+ * Function ExportSetting
+ * copy settings to a given zone
+ * @param aTarget: the given zone
+ * @param aFullExport: if false: some parameters are NOT exported
+ * because they must not be exported when export settings from a zone to others zones
+ * Currently:
+ * m_NetcodeSelection
+ */
+ void ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport = true ) const;
+
+ void SetCornerSmoothingType( int aType) { m_cornerSmoothingType = aType; }
+
+ int GetCornerSmoothingType() const { return m_cornerSmoothingType; }
+
+ void SetCornerRadius( int aRadius );
+
+ unsigned int GetCornerRadius() const { return m_cornerRadius; }
+
+ ZoneConnection GetPadConnection() const { return m_PadConnection; }
+ void SetPadConnection( ZoneConnection aPadConnection ) { m_PadConnection = aPadConnection; }
+
+ /**
+ * Accessors to parameters used in Keepout zones:
+ */
+ const bool GetIsKeepout() const { return m_isKeepout; }
+ const bool GetDoNotAllowCopperPour() const { return m_keepoutDoNotAllowCopperPour; }
+ const bool GetDoNotAllowVias() const { return m_keepoutDoNotAllowVias; }
+ const bool GetDoNotAllowTracks() const { return m_keepoutDoNotAllowTracks; }
+
+ void SetIsKeepout( bool aEnable ) { m_isKeepout = aEnable; }
+ void SetDoNotAllowCopperPour( bool aEnable ) { m_keepoutDoNotAllowCopperPour = aEnable; }
+ void SetDoNotAllowVias( bool aEnable ) { m_keepoutDoNotAllowVias = aEnable; }
+ void SetDoNotAllowTracks( bool aEnable ) { m_keepoutDoNotAllowTracks = aEnable; }
+};
+
+
+#endif // ZONE_SETTINGS_H_
diff --git a/pcbnew/classpcb.cpp b/pcbnew/classpcb.cpp
new file mode 100644
index 0000000..a856da9
--- /dev/null
+++ b/pcbnew/classpcb.cpp
@@ -0,0 +1,229 @@
+/**
+ * @file classpcb.cpp
+ * @brief Member functions of classes used in Pcbnew (see pcbstruct.h)
+ * except for tracks (see class_track.cpp).
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <macros.h>
+#include <trigo.h>
+#include <class_pcb_screen.h>
+#include <eda_text.h> // FILLED
+#include <base_units.h>
+
+#include <pcbnew.h>
+#include <class_board_design_settings.h>
+#include <layers_id_colors_and_visibility.h>
+
+#include <pcbnew_id.h>
+
+
+#define ZOOM_FACTOR( x ) ( x * IU_PER_DECIMILS )
+#define DMIL_GRID( x ) wxRealPoint( x * IU_PER_DECIMILS,\
+ x * IU_PER_DECIMILS )
+#define MM_GRID( x ) wxRealPoint( x * IU_PER_MM,\
+ x * IU_PER_MM )
+
+
+/**
+ Default Pcbnew zoom values.
+ Limited to 19 values to keep a decent size to menus.
+ Roughly a 1.5 progression.
+ The last 2 values are handy when somebody uses a library import of a module
+ (or foreign data) which has a bad coordinate.
+ Also useful in GerbView for this reason.
+ Zoom 5 and 10 can create artefacts when drawing (integer overflow in low level graphic
+ functions )
+*/
+#define DEFAULT_ZOOM ZOOM_FACTOR( 120 )
+
+static const double pcbZoomList[] =
+{
+ ZOOM_FACTOR( 0.1 ),
+ ZOOM_FACTOR( 0.2 ),
+ ZOOM_FACTOR( 0.3 ),
+ ZOOM_FACTOR( 0.5 ),
+ ZOOM_FACTOR( 1.0 ),
+ ZOOM_FACTOR( 1.5 ),
+ ZOOM_FACTOR( 2.0 ),
+ ZOOM_FACTOR( 3.0 ),
+ ZOOM_FACTOR( 4.5 ),
+ ZOOM_FACTOR( 6.0 ),
+ ZOOM_FACTOR( 8.0 ),
+ ZOOM_FACTOR( 11.0 ),
+ ZOOM_FACTOR( 15.0 ),
+ ZOOM_FACTOR( 22.0 ),
+ ZOOM_FACTOR( 35.0 ),
+ ZOOM_FACTOR( 50.0 ),
+ ZOOM_FACTOR( 80.0 ),
+ ZOOM_FACTOR( 110.0 ),
+ ZOOM_FACTOR( 150.0 ),
+ ZOOM_FACTOR( 200.0 ),
+ ZOOM_FACTOR( 300.0 ),
+/*
+ The largest distance that wx can support is INT_MAX, since it represents
+ distance often in a wxCoord or wxSize. As a scalar, a distance is always
+ positive. On most machines which run KiCad, int is 32 bits and INT_MAX is
+ 2147483647. The most difficult distance for a virtual (world) cartesian
+ space is the hypotenuse, or diagonal measurement at a 45 degree angle. This
+ puts the most stress on the distance magnitude within the bounded virtual
+ space. So if we allow this distance to be our constraint of <= INT_MAX, this
+ constraint then propagates to the maximum distance in X and in Y that can be
+ supported on each axis. Remember that the hypotenuse of a 1x1 square is
+ sqrt( 1x1 + 1x1 ) = sqrt(2) = 1.41421356.
+
+ hypotenuse of any square = sqrt(2) * deltaX;
+
+ Let maximum supported hypotenuse be INT_MAX, then:
+
+ MAX_AXIS = INT_MAX / sqrt(2) = 2147483647 / 1.41421356 = 1518500251
+
+ This maximum distance is imposed by wxWidgets, not by KiCad. The imposition
+ comes in the form of the data structures used in the graphics API at the
+ wxDC level. Obviously when we are not interacting with wx we can use double
+ to compute distances larger than this. For example the computation of the
+ total length of a net, can and should be done in double, since it might
+ actually be longer than a single diagonal line.
+
+ The next choice is what to use for internal units (IU), sometimes called
+ world units. If nanometers, then the virtual space must be limited to
+ about 1.5 x 1.5 meters square. This is 1518500251 divided by 1e9 nm/meter.
+
+ The maximum zoom factor then depends on the client window size. If we ask
+ wx to handle something outside INT_MIN to INT_MAX, there are unreported
+ problems in the non-Debug build because wxRound() goes silent.
+
+ Let:
+ const double MAX_AXIS = 1518500251;
+
+ Then a maximum zoom factor for a screen of 1920 pixels wide is
+ 1518500251 / 1920 = 790885.
+
+ The largest ZOOM_FACTOR in above table is ZOOM_FACTOR( 300 ), which computes
+ out to 762000 just below 790885.
+*/
+};
+
+
+// Default grid sizes for PCB editor screens.
+static GRID_TYPE pcbGridList[] =
+{
+ // predefined grid list in 0.0001 inches
+ { ID_POPUP_GRID_LEVEL_1000, DMIL_GRID( 1000 ) },
+ { ID_POPUP_GRID_LEVEL_500, DMIL_GRID( 500 ) },
+ { ID_POPUP_GRID_LEVEL_250, DMIL_GRID( 250 ) },
+ { ID_POPUP_GRID_LEVEL_200, DMIL_GRID( 200 ) },
+ { ID_POPUP_GRID_LEVEL_100, DMIL_GRID( 100 ) },
+ { ID_POPUP_GRID_LEVEL_50, DMIL_GRID( 50 ) },
+ { ID_POPUP_GRID_LEVEL_25, DMIL_GRID( 25 ) },
+ { ID_POPUP_GRID_LEVEL_20, DMIL_GRID( 20 ) },
+ { ID_POPUP_GRID_LEVEL_10, DMIL_GRID( 10 ) },
+ { ID_POPUP_GRID_LEVEL_5, DMIL_GRID( 5 ) },
+ { ID_POPUP_GRID_LEVEL_2, DMIL_GRID( 2 ) },
+ { ID_POPUP_GRID_LEVEL_1, DMIL_GRID( 1 ) },
+
+ // predefined grid list in mm
+ { ID_POPUP_GRID_LEVEL_5MM, MM_GRID( 5.0 ) },
+ { ID_POPUP_GRID_LEVEL_2_5MM, MM_GRID( 2.5 ) },
+ { ID_POPUP_GRID_LEVEL_1MM, MM_GRID( 1.0 ) },
+ { ID_POPUP_GRID_LEVEL_0_5MM, MM_GRID( 0.5 ) },
+ { ID_POPUP_GRID_LEVEL_0_25MM, MM_GRID( 0.25 ) },
+ { ID_POPUP_GRID_LEVEL_0_2MM, MM_GRID( 0.2 ) },
+ { ID_POPUP_GRID_LEVEL_0_1MM, MM_GRID( 0.1 ) },
+ { ID_POPUP_GRID_LEVEL_0_0_5MM, MM_GRID( 0.05 ) },
+ { ID_POPUP_GRID_LEVEL_0_0_25MM, MM_GRID( 0.025 ) },
+ { ID_POPUP_GRID_LEVEL_0_0_1MM, MM_GRID( 0.01 ) }
+};
+
+
+PCB_SCREEN::PCB_SCREEN( const wxSize& aPageSizeIU ) :
+ BASE_SCREEN( SCREEN_T )
+{
+ // D(wxSize displayz = wxGetDisplaySize();)
+ // D(printf( "displayz x:%d y:%d lastZoomFactor: %.16g\n", displayz.x, displayz.y, pcbZoomList[DIM(pcbZoomList)-1] );)
+
+ for( unsigned i = 0; i < DIM( pcbZoomList ); ++i )
+ m_ZoomList.push_back( pcbZoomList[i] );
+
+ for( unsigned i = 0; i < DIM( pcbGridList ); ++i )
+ AddGrid( pcbGridList[i] );
+
+ // Set the working grid size to a reasonable value (in 1/10000 inch)
+ SetGrid( DMIL_GRID( 500 ) );
+
+ m_Active_Layer = F_Cu; // default active layer = front layer
+ m_Route_Layer_TOP = F_Cu; // default layers pair for vias (bottom to top)
+ m_Route_Layer_BOTTOM = B_Cu;
+
+ SetZoom( DEFAULT_ZOOM ); // a default value for zoom
+
+ InitDataPoints( aPageSizeIU );
+}
+
+
+PCB_SCREEN::~PCB_SCREEN()
+{
+ ClearUndoRedoList();
+}
+
+
+int PCB_SCREEN::MilsToIuScalar()
+{
+ return (int)IU_PER_MILS;
+}
+
+
+DISPLAY_OPTIONS::DISPLAY_OPTIONS()
+{
+ m_DisplayPadFill = FILLED;
+ m_DisplayViaFill = FILLED;
+ m_DisplayPadNum = true;
+ m_DisplayPadIsol = true;
+
+ m_DisplayModEdgeFill = FILLED;
+ m_DisplayModTextFill = FILLED;
+ m_DisplayPcbTrackFill = FILLED; // false = sketch , true = filled
+ m_ShowTrackClearanceMode = SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS;
+ m_DisplayViaMode = VIA_HOLE_NOT_SHOW;
+
+ m_DisplayPolarCood = false; /* false = display absolute coordinates,
+ * true = display polar cordinates */
+ m_DisplayZonesMode = 0; /* 0 = Show filled areas outlines in zones,
+ * 1 = do not show filled areas outlines
+ * 2 = show outlines of filled areas */
+ m_DisplayNetNamesMode = 3; /* 0 do not show netnames,
+ * 1 show netnames on pads
+ * 2 show netnames on tracks
+ * 3 show netnames on tracks and pads */
+ m_DisplayDrawItemsFill = FILLED;
+ m_ContrastModeDisplay = false;
+ m_MaxLinksShowed = 3; // in track creation: number of hairwires shown
+ m_Show_Module_Ratsnest = true; // When moving a footprint: allows displaying a ratsnest
+}
diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp
new file mode 100644
index 0000000..7ee4083
--- /dev/null
+++ b/pcbnew/clean.cpp
@@ -0,0 +1,761 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file clean.cpp
+ * @brief functions to clean tracks: remove null length and redundant segments
+ */
+
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+#include <pcbnew.h>
+#include <class_board.h>
+#include <class_track.h>
+#include <connect.h>
+#include <dialog_cleaning_options.h>
+#include <ratsnest_data.h>
+
+// Helper class used to clean tracks and vias
+class TRACKS_CLEANER: CONNECTIONS
+{
+private:
+ BOARD *m_Brd;
+
+public:
+ TRACKS_CLEANER( BOARD * aPcb );
+
+ /**
+ * the cleanup function.
+ * return true if some item was modified
+ */
+ bool CleanupBoard( PCB_EDIT_FRAME *aFrame, bool aCleanVias,
+ bool aMergeSegments, bool aDeleteUnconnected);
+
+private:
+
+ /**
+ * Removes redundant vias like vias at same location
+ * or on pad through
+ */
+ bool clean_vias();
+
+ /**
+ * Removes all the following THT vias on the same position of the
+ * specified one
+ */
+ bool remove_duplicates_of_via( const VIA *aVia );
+
+ /**
+ * Removes all the following duplicates tracks of the specified one
+ */
+ bool remove_duplicates_of_track( const TRACK *aTrack );
+
+ /**
+ * Removes dangling tracks
+ */
+ bool deleteUnconnectedTracks();
+
+ /// Delete null length track segments
+ bool delete_null_segments();
+
+ /// Try to merge the segment to a following collinear one
+ bool merge_collinear_of_track( TRACK *aSegment );
+
+ /**
+ * Merge collinear segments and remove duplicated and null len segments
+ */
+ bool clean_segments();
+
+ /**
+ * helper function
+ * Rebuild list of tracks, and connected tracks
+ * this info must be rebuilt when tracks are erased
+ */
+ void buildTrackConnectionInfo();
+
+ /**
+ * helper function
+ * merge aTrackRef and aCandidate, when possible,
+ * i.e. when they are colinear, same width, and obviously same layer
+ */
+ TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef,
+ TRACK* aCandidate, ENDPOINT_T aEndType );
+
+ const ZONE_CONTAINER* zoneForTrackEndpoint( const TRACK *aTrack,
+ ENDPOINT_T aEndPoint );
+
+ bool testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPoint );
+};
+
+/* Install the cleanup dialog frame to know what should be cleaned
+*/
+void PCB_EDIT_FRAME::Clean_Pcb()
+{
+ DIALOG_CLEANING_OPTIONS dlg( this );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return;
+
+ // Old model has to be refreshed, GAL normally does not keep updating it
+ if( IsGalCanvasActive() )
+ Compile_Ratsnest( NULL, false );
+
+ wxBusyCursor( dummy );
+ TRACKS_CLEANER cleaner( GetBoard() );
+
+ cleaner.CleanupBoard( this, dlg.m_cleanVias, dlg.m_mergeSegments,
+ dlg.m_deleteUnconnectedSegm );
+
+ // There is a chance that some of tracks have changed their nets, so rebuild ratsnest from scratch
+ if( IsGalCanvasActive() )
+ GetBoard()->GetRatsnest()->ProcessBoard();
+
+ m_canvas->Refresh( true );
+}
+
+
+/* Main cleaning function.
+ * Delete
+ * - Redundant points on tracks (merge aligned segments)
+ * - vias on pad
+ * - null length segments
+ * Create segments when track ends are incorrectly connected:
+ * i.e. when a track end covers a pad or a via but is not exactly on the pad or the via center
+ */
+bool TRACKS_CLEANER::CleanupBoard( PCB_EDIT_FRAME *aFrame,
+ bool aCleanVias,
+ bool aMergeSegments,
+ bool aDeleteUnconnected )
+{
+ bool modified = false;
+
+ // delete redundant vias
+ modified |= (aCleanVias && clean_vias());
+
+ // Remove null segments and intermediate points on aligned segments
+ modified |= (aMergeSegments && clean_segments());
+
+ // Delete dangling tracks
+ if( aDeleteUnconnected && deleteUnconnectedTracks() )
+ {
+ modified = true ;
+
+ // Removed tracks can leave aligned segments
+ // (when a T was formed by tracks and the "vertical" segment
+ // is removed;
+ if( aMergeSegments )
+ clean_segments();
+ }
+
+ if( modified )
+ {
+ // Clear undo and redo lists to avoid inconsistencies between lists
+ aFrame->GetScreen()->ClearUndoRedoList();
+ aFrame->SetCurItem( NULL );
+ aFrame->Compile_Ratsnest( NULL, true );
+ aFrame->OnModify();
+ }
+
+ return modified;
+}
+
+TRACKS_CLEANER::TRACKS_CLEANER( BOARD * aPcb ): CONNECTIONS( aPcb )
+{
+ m_Brd = aPcb;
+
+ // Build connections info
+ BuildPadsList();
+ buildTrackConnectionInfo();
+}
+
+void TRACKS_CLEANER::buildTrackConnectionInfo()
+{
+ BuildTracksCandidatesList( m_Brd->m_Track, NULL);
+
+ // clear flags and variables used in cleanup
+ for( TRACK *track = m_Brd->m_Track; track != NULL; track = track->Next() )
+ {
+ track->start = NULL;
+ track->end = NULL;
+ track->m_PadsConnected.clear();
+ track->SetState( START_ON_PAD|END_ON_PAD|BUSY, false );
+ }
+
+ // Build connections info tracks to pads
+ SearchTracksConnectedToPads();
+ for( TRACK *track = m_Brd->m_Track; track != NULL; track = track->Next() )
+ {
+ // Mark track if connected to pads
+ for( unsigned jj = 0; jj < track->m_PadsConnected.size(); jj++ )
+ {
+ D_PAD * pad = track->m_PadsConnected[jj];
+
+ if( pad->HitTest( track->GetStart() ) )
+ {
+ track->start = pad;
+ track->SetState( START_ON_PAD, true );
+ }
+
+ if( pad->HitTest( track->GetEnd() ) )
+ {
+ track->end = pad;
+ track->SetState( END_ON_PAD, true );
+ }
+ }
+ }
+}
+
+bool TRACKS_CLEANER::remove_duplicates_of_via( const VIA *aVia )
+{
+ bool modified = false;
+
+ // Search and delete others vias at same location
+ VIA* next_via;
+ for( VIA* alt_via = GetFirstVia( aVia->Next() ); alt_via != NULL;
+ alt_via = next_via )
+ {
+ next_via = GetFirstVia( alt_via->Next() );
+
+ if( (alt_via->GetViaType() == VIA_THROUGH) &&
+ (alt_via->GetStart() == aVia->GetStart()) )
+ {
+ // delete via
+ m_Brd->GetRatsnest()->Remove( alt_via );
+ alt_via->ViewRelease();
+ alt_via->DeleteStructure();
+ modified = true;
+ }
+ }
+ return modified;
+}
+
+bool TRACKS_CLEANER::clean_vias()
+{
+ bool modified = false;
+
+ for( VIA* via = GetFirstVia( m_Brd->m_Track ); via != NULL;
+ via = GetFirstVia( via->Next() ) )
+ {
+ // Correct via m_End defects (if any), should never happen
+ if( via->GetStart() != via->GetEnd() )
+ {
+ wxFAIL_MSG( wxT( "Via with mismatching ends" ) );
+ via->SetEnd( via->GetStart() );
+ }
+
+ /* Important: these cleanups only do thru hole vias, they don't
+ * (yet) handle high density interconnects */
+ if( via->GetViaType() != VIA_THROUGH )
+ {
+ modified |= remove_duplicates_of_via( via );
+
+ /* To delete through Via on THT pads at same location
+ * Examine the list of connected pads:
+ * if one through pad is found, the via can be removed */
+ for( unsigned ii = 0; ii < via->m_PadsConnected.size(); ++ii )
+ {
+ const D_PAD *pad = via->m_PadsConnected[ii];
+
+ const LSET all_cu = LSET::AllCuMask();
+
+ if( (pad->GetLayerSet() & all_cu) == all_cu )
+ {
+ // redundant: delete the via
+ m_Brd->GetRatsnest()->Remove( via );
+ via->ViewRelease();
+ via->DeleteStructure();
+ modified = true;
+ break;
+ }
+ }
+ }
+ }
+
+ return modified;
+}
+
+/// Utility for checking if a track/via ends on a zone
+const ZONE_CONTAINER* TRACKS_CLEANER::zoneForTrackEndpoint( const TRACK *aTrack,
+ ENDPOINT_T aEndPoint )
+{
+ // Vias are special cased, since they get a layer range, not a single one
+ LAYER_ID top_layer, bottom_layer;
+ const VIA* via = dyn_cast<const VIA*>( aTrack );
+
+ if( via )
+ via->LayerPair( &top_layer, &bottom_layer );
+ else
+ {
+ top_layer = aTrack->GetLayer();
+ bottom_layer = top_layer;
+ }
+
+ return m_Brd->HitTestForAnyFilledArea( aTrack->GetEndPoint( aEndPoint ),
+ top_layer, bottom_layer, aTrack->GetNetCode() );
+}
+
+/** Utility: does the endpoint unconnected processed for one endpoint of one track
+ * Returns true if the track must be deleted, false if not necessarily */
+bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPoint )
+{
+ bool flag_erase = false;
+
+ TRACK* other = aTrack->GetTrack( m_Brd->m_Track, NULL, aEndPoint, true, false );
+
+ if( (other == NULL) && (zoneForTrackEndpoint( aTrack, aEndPoint ) == NULL) )
+ flag_erase = true; // Start endpoint is neither on pad, zone or other track
+ else // segment, via or zone connected to this end
+ {
+ // Fill connectivity informations
+ if( aEndPoint == ENDPOINT_START )
+ aTrack->start = other;
+ else
+ aTrack->end = other;
+
+ /* If a via is connected to this end, test if this via has a second item connected.
+ * If not, remove the current segment (the via would then become
+ * unconnected and remove on the following pass) */
+ VIA* via = dyn_cast<VIA*>( other );
+
+ if( via )
+ {
+ // search for another segment following the via
+ aTrack->SetState( BUSY, true );
+
+ other = via->GetTrack( m_Brd->m_Track, NULL, aEndPoint, true, false );
+
+ // There is a via on the start but it goes nowhere
+ if( (other == NULL) &&
+ (zoneForTrackEndpoint( via, aEndPoint ) == NULL) )
+ flag_erase = true;
+
+ aTrack->SetState( BUSY, false );
+ }
+ }
+
+ return flag_erase;
+}
+
+/*
+ * Delete dangling tracks
+ * Vias:
+ * If a via is only connected to a dangling track, it also will be removed
+ */
+bool TRACKS_CLEANER::deleteUnconnectedTracks()
+{
+ if( m_Brd->m_Track == NULL )
+ return false;
+
+ bool modified = false;
+ bool item_erased;
+ do // Iterate when at least one track is deleted
+ {
+ item_erased = false;
+ TRACK* next_track;
+ for( TRACK *track = m_Brd->m_Track; track != NULL; track = next_track )
+ {
+ next_track = track->Next();
+
+ bool flag_erase = false; // Start without a good reason to erase it
+
+ /* if a track endpoint is not connected to a pad, test if
+ * the endpoint is connected to another track or to a zone.
+ * For via test, an enhancement could be to test if
+ * connected to 2 items on different layers. Currently
+ * a via must be connected to 2 items, that can be on the
+ * same layer */
+
+ // Check if there is nothing attached on the start
+ if( !(track->GetState( START_ON_PAD )) )
+ flag_erase |= testTrackEndpointDangling( track, ENDPOINT_START );
+
+ // Check if there is nothing attached on the end
+ if( !(track->GetState( END_ON_PAD )) )
+ flag_erase |= testTrackEndpointDangling( track, ENDPOINT_END );
+
+ if( flag_erase )
+ {
+ // remove segment from board
+ m_Brd->GetRatsnest()->Remove( track );
+ track->ViewRelease();
+ track->DeleteStructure();
+
+ /* keep iterating, because a track connected to the deleted track
+ * now perhaps is not connected and should be deleted */
+ item_erased = true;
+ modified = true;
+ }
+ }
+ } while( item_erased );
+
+ return modified;
+}
+
+// Delete null length track segments
+bool TRACKS_CLEANER::delete_null_segments()
+{
+ TRACK *nextsegment;
+ bool modified = false;
+
+ // Delete null segments
+ for( TRACK *segment = m_Brd->m_Track; segment; segment = nextsegment )
+ {
+ nextsegment = segment->Next();
+
+ if( segment->IsNull() ) // Length segment = 0; delete it
+ {
+ m_Brd->GetRatsnest()->Remove( segment );
+ segment->ViewRelease();
+ segment->DeleteStructure();
+ modified = true;
+ }
+ }
+ return modified;
+}
+
+bool TRACKS_CLEANER::remove_duplicates_of_track( const TRACK *aTrack )
+{
+ bool modified = false;
+
+ TRACK *nextsegment;
+ for( TRACK *other = aTrack->Next(); other; other = nextsegment )
+ {
+ nextsegment = other->Next();
+
+ // New netcode, break out (can't be there any other)
+ if( aTrack->GetNetCode() != other->GetNetCode() )
+ break;
+
+ // Must be of the same type, on the same layer and the endpoints
+ // must be the same (maybe swapped)
+ if( (aTrack->Type() != other->Type()) &&
+ (aTrack->GetLayer() != other->GetLayer()) )
+ {
+ if( ((aTrack->GetStart() == other->GetStart()) &&
+ (aTrack->GetEnd() == other->GetEnd())) ||
+ ((aTrack->GetStart() == other->GetEnd()) &&
+ (aTrack->GetEnd() == other->GetStart())))
+ {
+ m_Brd->GetRatsnest()->Remove( other );
+ other->ViewRelease();
+ other->DeleteStructure();
+ modified = true;
+ }
+ }
+ }
+ return modified;
+}
+
+bool TRACKS_CLEANER::merge_collinear_of_track( TRACK *aSegment )
+{
+ bool merged_this = false;
+
+ // *WHY* doesn't C++ have prec and succ (or ++ --) like PASCAL?
+ for( ENDPOINT_T endpoint = ENDPOINT_START; endpoint <= ENDPOINT_END;
+ endpoint = ENDPOINT_T( endpoint + 1 ) )
+ {
+ // search for a possible segment connected to the current endpoint of the current one
+ TRACK *other = aSegment->Next();
+ if( other )
+ {
+ other = aSegment->GetTrack( other, NULL, endpoint, true, false );
+
+ if( other )
+ {
+ // the two segments must have the same width and the other
+ // cannot be a via
+ if( (aSegment->GetWidth() == other->GetWidth()) &&
+ (other->Type() == PCB_TRACE_T) )
+ {
+ // There can be only one segment connected
+ other->SetState( BUSY, true );
+ TRACK *yet_another = aSegment->GetTrack( m_Brd->m_Track, NULL,
+ endpoint, true, false );
+ other->SetState( BUSY, false );
+
+ if( !yet_another )
+ {
+ // Try to merge them
+ TRACK *segDelete = mergeCollinearSegmentIfPossible( aSegment,
+ other, endpoint );
+
+ // Merge succesful, the other one has to go away
+ if( segDelete )
+ {
+ m_Brd->GetRatsnest()->Remove( segDelete );
+ segDelete->ViewRelease();
+ segDelete->DeleteStructure();
+ merged_this = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return merged_this;
+}
+
+// Delete null length segments, and intermediate points ..
+bool TRACKS_CLEANER::clean_segments()
+{
+ bool modified = false;
+
+ // Easy things first
+ modified |= delete_null_segments();
+
+ // Delete redundant segments, i.e. segments having the same end points and layers
+ for( TRACK *segment = m_Brd->m_Track; segment; segment = segment->Next() )
+ modified |= remove_duplicates_of_track( segment );
+
+ // merge collinear segments:
+ TRACK *nextsegment;
+
+ for( TRACK *segment = m_Brd->m_Track; segment; segment = nextsegment )
+ {
+ nextsegment = segment->Next();
+
+ if( segment->Type() == PCB_TRACE_T )
+ {
+ bool merged_this = merge_collinear_of_track( segment );
+
+ if( merged_this ) // The current segment was modified, retry to merge it again
+ {
+ nextsegment = segment->Next();
+ modified = true;
+ }
+ }
+ }
+
+ return modified;
+}
+
+/* Utility: check for parallelism between two segments */
+static bool parallelism_test( int dx1, int dy1, int dx2, int dy2 )
+{
+ /* The following condition list is ugly and repetitive, but I have
+ * not a better way to express clearly the trivial cases. Hope the
+ * compiler optimize it better than always doing the product
+ * below... */
+
+ // test for vertical alignment (easy to handle)
+ if( dx1 == 0 )
+ return dx2 == 0;
+
+ if( dx2 == 0 )
+ return dx1 == 0;
+
+ // test for horizontal alignment (easy to handle)
+ if( dy1 == 0 )
+ return dy2 == 0;
+
+ if( dy2 == 0 )
+ return dy1 == 0;
+
+ /* test for alignment in other cases: Do the usual cross product test
+ * (the same as testing the slope, but without a division) */
+ return ((double)dy1 * dx2 == (double)dx1 * dy2);
+}
+
+/** Function used by clean_segments.
+ * Test if aTrackRef and aCandidate (which must have a common end) are collinear.
+ * and see if the common point is not on a pad (i.e. if this common point can be removed).
+ * the ending point of aTrackRef is the start point (aEndType == START)
+ * or the end point (aEndType != START)
+ * flags START_ON_PAD and END_ON_PAD must be set before calling this function
+ * if the common point can be deleted, this function
+ * change the common point coordinate of the aTrackRef segm
+ * (and therefore connect the 2 other ending points)
+ * and return aCandidate (which can be deleted).
+ * else return NULL
+ */
+TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aCandidate,
+ ENDPOINT_T aEndType )
+{
+ // First of all, they must be of the same width and must be both actual tracks
+ if( (aTrackRef->GetWidth() != aCandidate->GetWidth()) ||
+ (aTrackRef->Type() != PCB_TRACE_T) ||
+ (aCandidate->Type() != PCB_TRACE_T) )
+ return NULL;
+
+ // Trivial case: exactly the same track
+ if( ( aTrackRef->GetStart() == aCandidate->GetStart() ) &&
+ ( aTrackRef->GetEnd() == aCandidate->GetEnd() ) )
+ return aCandidate;
+
+ if( ( aTrackRef->GetStart() == aCandidate->GetEnd() ) &&
+ ( aTrackRef->GetEnd() == aCandidate->GetStart() ) )
+ return aCandidate;
+
+ // Weed out non-parallel tracks
+ if ( !parallelism_test( aTrackRef->GetEnd().x - aTrackRef->GetStart().x,
+ aTrackRef->GetEnd().y - aTrackRef->GetStart().y,
+ aCandidate->GetEnd().x - aCandidate->GetStart().x,
+ aCandidate->GetEnd().y - aCandidate->GetStart().y ) )
+ return NULL;
+
+ /* Here we have 2 aligned segments:
+ * We must change the pt_ref common point only if not on a pad
+ * (this function) is called when there is only 2 connected segments,
+ * and if this point is not on a pad, it can be removed and the 2 segments will be merged
+ */
+ if( aEndType == ENDPOINT_START )
+ {
+ // We do not have a pad, which is a always terminal point for a track
+ if( aTrackRef->GetState( START_ON_PAD) )
+ return NULL;
+
+ /* change the common point coordinate of pt_segm to use the other point
+ * of pt_segm (pt_segm will be removed later) */
+ if( aTrackRef->GetStart() == aCandidate->GetStart() )
+ {
+ aTrackRef->SetStart( aCandidate->GetEnd());
+ aTrackRef->start = aCandidate->end;
+ aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( END_ON_PAD) );
+ aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ return aCandidate;
+ }
+ else
+ {
+ aTrackRef->SetStart( aCandidate->GetStart() );
+ aTrackRef->start = aCandidate->start;
+ aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( START_ON_PAD) );
+ aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ return aCandidate;
+ }
+ }
+ else // aEndType == END
+ {
+ // We do not have a pad, which is a always terminal point for a track
+ if( aTrackRef->GetState( END_ON_PAD) )
+ return NULL;
+
+ /* change the common point coordinate of pt_segm to use the other point
+ * of pt_segm (pt_segm will be removed later) */
+ if( aTrackRef->GetEnd() == aCandidate->GetStart() )
+ {
+ aTrackRef->SetEnd( aCandidate->GetEnd() );
+ aTrackRef->end = aCandidate->end;
+ aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( END_ON_PAD) );
+ aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ return aCandidate;
+ }
+ else
+ {
+ aTrackRef->SetEnd( aCandidate->GetStart() );
+ aTrackRef->end = aCandidate->start;
+ aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( START_ON_PAD) );
+ aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ return aCandidate;
+ }
+ }
+
+ return NULL;
+}
+
+
+bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
+{
+ /* finds all track segments which are mis-connected (to more than one net).
+ * When such a bad segment is found, it is flagged to be removed.
+ * All tracks having at least one flagged segment are removed.
+ */
+ TRACK* segment;
+ TRACK* other;
+ TRACK* next;
+ int net_code_s, net_code_e;
+ bool isModified = false;
+
+ for( segment = GetBoard()->m_Track; segment; segment = segment->Next() )
+ {
+ segment->SetState( FLAG0, false );
+
+ // find the netcode for segment using anything connected to the "start" of "segment"
+ net_code_s = -1;
+
+ if( segment->start && segment->start->Type()==PCB_PAD_T )
+ {
+ // get the netcode of the pad to propagate.
+ net_code_s = ((D_PAD*)(segment->start))->GetNetCode();
+ }
+ else
+ {
+ other = segment->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START, false, false );
+
+ if( other )
+ net_code_s = other->GetNetCode();
+ }
+
+ if( net_code_s < 0 )
+ continue; // the "start" of segment is not connected
+
+ // find the netcode for segment using anything connected to the "end" of "segment"
+ net_code_e = -1;
+
+ if( segment->end && segment->end->Type()==PCB_PAD_T )
+ {
+ net_code_e = ((D_PAD*)(segment->end))->GetNetCode();
+ }
+ else
+ {
+ other = segment->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END, false, false );
+
+ if( other )
+ net_code_e = other->GetNetCode();
+ }
+
+ if( net_code_e < 0 )
+ continue; // the "end" of segment is not connected
+
+ // Netcodes do not agree, so mark the segment as "to be removed"
+ if( net_code_s != net_code_e )
+ {
+ segment->SetState( FLAG0, true );
+ }
+ }
+
+ // Remove tracks having a flagged segment
+ for( segment = GetBoard()->m_Track; segment; segment = next )
+ {
+ next = segment->Next();
+
+ if( segment->GetState( FLAG0 ) ) // Segment is flagged to be removed
+ {
+ segment->SetState( FLAG0, false );
+ isModified = true;
+ GetBoard()->m_Status_Pcb = 0;
+ Remove_One_Track( NULL, segment );
+
+ // the current segment is deleted,
+ // we do not know the next "not yet tested" segment,
+ // so restart to the beginning
+ next = GetBoard()->m_Track;
+ }
+ }
+
+ return isModified;
+}
diff --git a/pcbnew/collectors.cpp b/pcbnew/collectors.cpp
new file mode 100644
index 0000000..f58d4a3
--- /dev/null
+++ b/pcbnew/collectors.cpp
@@ -0,0 +1,501 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2004-2007 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <collectors.h>
+#include <class_board_item.h> // class BOARD_ITEM
+
+#include <class_module.h>
+#include <class_pad.h>
+#include <class_track.h>
+#include <class_marker_pcb.h>
+
+
+/* This module contains out of line member functions for classes given in
+ * collectors.h. Those classes augment the functionality of class PCB_EDIT_FRAME.
+ */
+
+
+// see collectors.h
+const KICAD_T GENERAL_COLLECTOR::AllBoardItems[] = {
+ // there are some restrictions on the order of items in the general case.
+ // all items in m_Drawings for instance should be contiguous.
+ // *** all items in a same list (shown here) must be contiguous ****
+ PCB_MARKER_T, // in m_markers
+ PCB_TEXT_T, // in m_Drawings
+ PCB_LINE_T, // in m_Drawings
+ PCB_DIMENSION_T, // in m_Drawings
+ PCB_TARGET_T, // in m_Drawings
+ PCB_VIA_T, // in m_Tracks
+ PCB_TRACE_T, // in m_Tracks
+ PCB_PAD_T, // in modules
+ PCB_MODULE_TEXT_T, // in modules
+ PCB_MODULE_T, // in m_Modules
+ PCB_ZONE_T, // in m_Zones
+ PCB_ZONE_AREA_T, // in m_ZoneDescriptorList
+ EOT
+};
+
+
+/*
+ * const KICAD_T GENERAL_COLLECTOR::PrimaryItems[] = {
+ * PCB_TEXT_T,
+ * PCB_LINE_T,
+ * PCB_DIMENSION_T,
+ * PCB_VIA_T,
+ * PCB_TRACE_T,
+ * PCB_MODULE_T,
+ * EOT
+ * };
+ */
+
+
+const KICAD_T GENERAL_COLLECTOR::AllButZones[] = {
+ PCB_MARKER_T,
+ PCB_TEXT_T,
+ PCB_LINE_T,
+ PCB_DIMENSION_T,
+ PCB_TARGET_T,
+ PCB_VIA_T,
+ PCB_TRACE_T,
+ PCB_PAD_T,
+ PCB_MODULE_TEXT_T,
+ PCB_MODULE_T,
+ PCB_ZONE_AREA_T, // if it is visible on screen, it should be selectable
+ EOT
+};
+
+
+const KICAD_T GENERAL_COLLECTOR::Modules[] = {
+ PCB_MODULE_T,
+ EOT
+};
+
+
+const KICAD_T GENERAL_COLLECTOR::PadsOrModules[] = {
+ PCB_PAD_T,
+ PCB_MODULE_T,
+ EOT
+};
+
+
+const KICAD_T GENERAL_COLLECTOR::PadsTracksOrZones[] = {
+ PCB_PAD_T,
+ PCB_VIA_T,
+ PCB_TRACE_T,
+ PCB_ZONE_T,
+ PCB_ZONE_AREA_T,
+ EOT
+};
+
+
+const KICAD_T GENERAL_COLLECTOR::ModulesAndTheirItems[] = {
+ PCB_MODULE_TEXT_T,
+ PCB_MODULE_EDGE_T,
+ PCB_PAD_T,
+ PCB_MODULE_T,
+ EOT
+};
+
+
+const KICAD_T GENERAL_COLLECTOR::ModuleItems[] = {
+ PCB_MODULE_TEXT_T,
+ PCB_MODULE_EDGE_T,
+ PCB_PAD_T,
+ EOT
+};
+
+
+const KICAD_T GENERAL_COLLECTOR::Tracks[] = {
+ PCB_TRACE_T,
+ PCB_VIA_T,
+ EOT
+};
+
+
+const KICAD_T GENERAL_COLLECTOR::Zones[] = {
+ PCB_ZONE_AREA_T,
+ EOT
+};
+
+
+
+/**
+ * Function Inspect
+ * is the examining function within the INSPECTOR which is passed to the
+ * Iterate function. Searches and collects all the objects that the old
+ * function PcbGeneralLocateAndDisplay() would find, except that it keeps all
+ * that it finds and does not do any displaying.
+ *
+ * @param testItem An EDA_ITEM to examine.
+ * @param testData The const void* testData, not used here.
+ * @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
+ * else SCAN_CONTINUE;
+ */
+SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, const void* testData )
+{
+ BOARD_ITEM* item = (BOARD_ITEM*) testItem;
+ MODULE* module = NULL;
+ D_PAD* pad = NULL;
+ bool pad_through = false;
+ VIA* via = NULL;
+ MARKER_PCB* marker = NULL;
+
+#if 0 // debugging
+ static int breakhere = 0;
+
+ switch( item->Type() )
+ {
+ case PCB_PAD_T:
+ {
+ MODULE* m = (MODULE*) item->GetParent();
+
+ if( m->GetReference() == wxT( "Y2" ) )
+ {
+ breakhere++;
+ }
+ }
+ break;
+
+ case PCB_VIA_T:
+ breakhere++;
+ break;
+
+ case PCB_TRACE_T:
+ breakhere++;
+ break;
+
+ case PCB_ZONE_T:
+ breakhere++;
+ break;
+
+ case PCB_TEXT_T:
+ breakhere++;
+ break;
+
+ case PCB_LINE_T:
+ breakhere++;
+ break;
+
+ case PCB_DIMENSION_T:
+ breakhere++;
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ {
+ TEXTE_MODULE* tm = (TEXTE_MODULE*) item;
+
+ if( tm->GetText() == wxT( "10uH" ) )
+ {
+ breakhere++;
+ }
+ }
+ break;
+
+ case PCB_MODULE_T:
+ {
+ MODULE* m = (MODULE*) item;
+
+ if( m->GetReference() == wxT( "C98" ) )
+ {
+ breakhere++;
+ }
+ }
+ break;
+
+ case PCB_MARKER_T:
+ breakhere++;
+ break;
+
+ default:
+ breakhere++;
+ break;
+ }
+
+#endif
+
+
+ switch( item->Type() )
+ {
+ case PCB_PAD_T:
+ // there are pad specific visibility controls.
+ // Criterias to select a pad is:
+ // for smd pads: the module parent must be seen, and pads on the corresponding
+ // board side must be seen
+ // if pad is a thru hole, then it can be visible when its parent module is not.
+ // for through pads: pads on Front or Back board sides must be seen
+ pad = (D_PAD*) item;
+
+ if( (pad->GetAttribute() != PAD_ATTRIB_SMD) &&
+ (pad->GetAttribute() != PAD_ATTRIB_CONN) ) // a hole is present, so multiple layers
+ {
+ // proceed to the common tests below, but without the parent module test,
+ // by leaving module==NULL, but having pad != null
+ pad_through = true;
+ }
+ else // smd, so use pads test after module test
+ {
+ module = static_cast<MODULE*>( item->GetParent() );
+ }
+
+ break;
+
+ case PCB_VIA_T: // vias are on many layers, so layer test is specific
+ via = static_cast<VIA*>( item );
+ break;
+
+ case PCB_TRACE_T:
+ break;
+
+ case PCB_ZONE_T:
+ break;
+
+ case PCB_ZONE_AREA_T:
+ break;
+
+ case PCB_TEXT_T:
+ break;
+
+ case PCB_LINE_T:
+ break;
+
+ case PCB_DIMENSION_T:
+ break;
+
+ case PCB_TARGET_T:
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ {
+ TEXTE_MODULE *text = static_cast<TEXTE_MODULE*>( item );
+ if( m_Guide->IgnoreMTextsMarkedNoShow() && !text->IsVisible() )
+ goto exit;
+
+ if( m_Guide->IgnoreMTextsOnBack() && IsBackLayer( text->GetLayer() ) )
+ goto exit;
+
+ if( m_Guide->IgnoreMTextsOnFront() && IsFrontLayer( text->GetLayer() ) )
+ goto exit;
+
+ /* The three text types have different criteria: reference
+ * and value have their own ignore flags; user text instead
+ * follows their layer visibility. Checking this here is
+ * simpler than later (when layer visibility is checked for
+ * other entities) */
+
+ switch( text->GetType() )
+ {
+ case TEXTE_MODULE::TEXT_is_REFERENCE:
+ if( m_Guide->IgnoreModulesRefs() )
+ goto exit;
+ break;
+
+ case TEXTE_MODULE::TEXT_is_VALUE:
+ if( m_Guide->IgnoreModulesVals() )
+ goto exit;
+ break;
+
+ case TEXTE_MODULE::TEXT_is_DIVERS:
+ if( !m_Guide->IsLayerVisible( text->GetLayer() )
+ && m_Guide->IgnoreNonVisibleLayers() )
+ goto exit;
+ break;
+ }
+
+ // Extract the module since it could be hidden
+ module = static_cast<MODULE*>( item->GetParent() );
+ }
+ break;
+
+ case PCB_MODULE_T:
+ module = static_cast<MODULE*>( item );
+ break;
+
+ case PCB_MARKER_T:
+ marker = static_cast<MARKER_PCB*>( item );
+ break;
+
+ default:
+ break;
+ }
+
+ // common tests:
+
+ if( module ) // true from case PCB_PAD_T, PCB_MODULE_TEXT_T, or PCB_MODULE_T
+ {
+ if( m_Guide->IgnoreModulesOnBack() && (module->GetLayer() == B_Cu) )
+ goto exit;
+
+ if( m_Guide->IgnoreModulesOnFront() && (module->GetLayer() == F_Cu) )
+ goto exit;
+ }
+
+ // Pads are not sensitive to the layer visibility controls.
+ // They all have their own separate visibility controls
+ // skip them if not visible
+ if( pad )
+ {
+ if( m_Guide->IgnorePads() )
+ goto exit;
+
+ if( ! pad_through )
+ {
+ if( m_Guide->IgnorePadsOnFront() && pad->IsOnLayer(F_Cu ) )
+ goto exit;
+
+ if( m_Guide->IgnorePadsOnBack() && pad->IsOnLayer(B_Cu ) )
+ goto exit;
+ }
+ }
+
+ if( marker )
+ {
+ // Markers are not sensitive to the layer
+ if( marker->HitTest( m_RefPos ) )
+ Append( item );
+
+ goto exit;
+ }
+
+ if( item->IsOnLayer( m_Guide->GetPreferredLayer() ) ||
+ m_Guide->IgnorePreferredLayer() )
+ {
+ LAYER_ID layer = item->GetLayer();
+
+ /* Modules and their subcomponents: reference, value and pads
+ * are not sensitive to the layer visibility controls. They all
+ * have their own separate visibility controls for vias,
+ * GetLayer() has no meaning, but IsOnLayer() works fine. User
+ * text in module *is* sensitive to layer visibility but that
+ * was already handled */
+
+ if( via || module || pad || m_Guide->IsLayerVisible( layer )
+ || !m_Guide->IgnoreNonVisibleLayers() )
+ {
+ if( !m_Guide->IsLayerLocked( layer ) || !m_Guide->IgnoreLockedLayers() )
+ {
+ if( !item->IsLocked() || !m_Guide->IgnoreLockedItems() )
+ {
+ if( item->HitTest( m_RefPos ) )
+ {
+ Append( item );
+ goto exit;
+ }
+ }
+ }
+ }
+ }
+
+
+ if( m_Guide->IncludeSecondary() )
+ {
+ // for now, "secondary" means "tolerate any layer". It has
+ // no effect on other criteria, since there is a separate "ignore" control for
+ // those in the COLLECTORS_GUIDE
+
+ LAYER_ID layer = item->GetLayer();
+
+ /* Modules and their subcomponents: reference, value and pads
+ * are not sensitive to the layer visibility controls. They all
+ * have their own separate visibility controls. User texts
+ * follows layer visibility controls (but that was already
+ * checked) */
+
+ if( via || module || pad || m_Guide->IsLayerVisible( layer )
+ || !m_Guide->IgnoreNonVisibleLayers() )
+ {
+ if( !m_Guide->IsLayerLocked( layer ) || !m_Guide->IgnoreLockedLayers() )
+ {
+ if( !item->IsLocked() || !m_Guide->IgnoreLockedItems() )
+ {
+ if( item->HitTest( m_RefPos ) )
+ {
+ Append2nd( item );
+ goto exit;
+ }
+ }
+ }
+ }
+ }
+
+exit:
+ return SEARCH_CONTINUE; // always when collecting
+}
+
+
+// see collectors.h
+void GENERAL_COLLECTOR::Collect( BOARD_ITEM* aItem, const KICAD_T aScanList[],
+ const wxPoint& aRefPos, const COLLECTORS_GUIDE& aGuide )
+{
+ Empty(); // empty the collection, primary criteria list
+ Empty2nd(); // empty the collection, secondary criteria list
+
+ // remember guide, pass it to Inspect()
+ SetGuide( &aGuide );
+
+ SetScanTypes( aScanList );
+
+ // remember where the snapshot was taken from and pass refPos to
+ // the Inspect() function.
+ SetRefPos( aRefPos );
+
+ // visit the board or module with the INSPECTOR (me).
+ aItem->Visit( this, // INSPECTOR* inspector
+ NULL, // const void* testData, not used here
+ m_ScanTypes );
+
+ SetTimeNow(); // when snapshot was taken
+
+ // record the length of the primary list before concatenating on to it.
+ m_PrimaryLength = m_List.size();
+
+ // append 2nd list onto end of the first list
+ for( unsigned i = 0; i<m_List2nd.size(); ++i )
+ Append( m_List2nd[i] );
+
+ Empty2nd();
+}
+
+
+// see collectors.h
+SEARCH_RESULT PCB_TYPE_COLLECTOR::Inspect( EDA_ITEM* testItem, const void* testData )
+{
+ // The Vist() function only visits the testItem if its type was in the
+ // the scanList, so therefore we can collect anything given to us here.
+ Append( testItem );
+
+ return SEARCH_CONTINUE; // always when collecting
+}
+
+
+void PCB_TYPE_COLLECTOR::Collect( BOARD_ITEM* aBoard, const KICAD_T aScanList[] )
+{
+ Empty(); // empty any existing collection
+
+ // visit the board with the INSPECTOR (me).
+ aBoard->Visit( this, // INSPECTOR* inspector
+ NULL, // const void* testData,
+ aScanList );
+}
+
+//EOF
diff --git a/pcbnew/collectors.h b/pcbnew/collectors.h
new file mode 100644
index 0000000..b2d5c9d
--- /dev/null
+++ b/pcbnew/collectors.h
@@ -0,0 +1,639 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2004-2007 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file collectors.h
+ */
+
+#ifndef COLLECTORS_H
+#define COLLECTORS_H
+
+
+/* This module contains a number of COLLECTOR implementations which are used
+ to augment the functionality of class PCB_EDIT_FRAME.
+*/
+
+
+#include <class_collector.h>
+#include <layers_id_colors_and_visibility.h> // LAYER_COUNT, layer defs
+
+
+class BOARD_ITEM;
+
+
+/**
+ * Class COLLECTORS_GUIDE
+ * is an abstract base class whose derivatives may be passed to a GENERAL_COLLECTOR,
+ * telling GENERAL_COLLECTOR what should be collected (aside from HitTest()ing
+ * and KICAD_T scanTypes[], information which are provided to the GENERAL_COLLECTOR
+ * through attributes or arguments separately).
+ * <p>
+ * A justification for this class is to keep the structural storage details of
+ * the program's "global preferences" or "configuration options" out of
+ * GENERAL_COLLECTOR::Inspect(). This class carries all the necessary details
+ * in with it to the Inspect() call. The constructors or other functions of
+ * this class's derivatives are then the only place where knowledge of the
+ * specific structure of the global preference storage is needed. Thus,
+ * GENERAL_COLLECTOR::Inspect() can be kept as simple as possible, and insulated
+ * from changes in global preference storage (and even then it is
+ * not simple enough).
+ * <p>
+ * This class introduces the notion of layer locking.
+ */
+class COLLECTORS_GUIDE
+{
+
+public:
+ virtual ~COLLECTORS_GUIDE() {}
+
+ /**
+ * Function IsLayerLocked
+ * @return bool - true if the given layer is locked, else false.
+ */
+ virtual bool IsLayerLocked( LAYER_ID layer ) const = 0;
+
+ /**
+ * Function IsLayerVisible
+ * @return bool - true if the given layer is visible, else false.
+ */
+ virtual bool IsLayerVisible( LAYER_ID layer ) const = 0;
+
+ /**
+ * Function IgnoreLockedLayers
+ * @return bool - true if should ignore locked layers, else false.
+ */
+ virtual bool IgnoreLockedLayers() const = 0;
+
+ /**
+ * Function IgnoredNonVisibleLayers
+ * @return bool - true if should ignore non-visible layers, else false.
+ */
+ virtual bool IgnoreNonVisibleLayers() const = 0;
+
+ /**
+ * Function GetPreferredLayer
+ * @return int - the preferred layer for HitTest()ing.
+ */
+ virtual LAYER_ID GetPreferredLayer() const = 0;
+
+ /**
+ * Function IgnorePreferredLayer
+ * provides wildcard behavior regarding the preferred layer.
+ * @return bool - true if should ignore preferred layer, else false.
+ */
+ virtual bool IgnorePreferredLayer() const = 0;
+
+ /**
+ * Function IgnoreLockedItems
+ * @return bool - true if should ignore locked items, else false.
+ */
+ virtual bool IgnoreLockedItems() const = 0;
+
+ /**
+ * Function IncludeSecondary
+ * determines if the secondary criteria, or 2nd choice items should be
+ * included.
+ * @return bool - true if should include, else false.
+ */
+ virtual bool IncludeSecondary() const = 0;
+
+ /**
+ * Function IgnoreMTextsMarkedNoShow
+ * @return bool - true if MTexts marked as "no show" should be ignored.
+ */
+ virtual bool IgnoreMTextsMarkedNoShow() const = 0;
+
+ /**
+ * Function IgnoreZones
+ * @return bool - true if should ignore zones.
+ virtual bool IgnoreZones() const = 0;
+ can simply omit from scanTypes[] PCB_ZONE_T */
+
+ /**
+ * Function IgnoreMTextsOnBack
+ * @return bool - true if should ignore MTexts on back layers
+ */
+ virtual bool IgnoreMTextsOnBack() const = 0;
+
+ /**
+ * Function IgnoreMTextsOnFront
+ * @return bool - true if should ignore MTexts on front layers.
+ */
+ virtual bool IgnoreMTextsOnFront() const = 0;
+
+ /**
+ * Function IgnoreModulesOnBack
+ * @return bool - true if should ignore MODULEs on Back Side.
+ */
+ virtual bool IgnoreModulesOnBack() const = 0;
+
+ /**
+ * Function IgnoreModulesOnFront
+ * @return bool - ture if should ignore MODULEs on Front Side.
+ */
+ virtual bool IgnoreModulesOnFront() const = 0;
+
+ /**
+ * Function IgnorePadsOnBack
+ * @return bool - true if should ignore Pads on Back Side.
+ */
+ virtual bool IgnorePadsOnBack() const = 0;
+
+ /**
+ * Function IgnorePadsOnFront
+ * @return bool - ture if should ignore PADSs on Front Side.
+ */
+ virtual bool IgnorePadsOnFront() const = 0;
+
+ /**
+ * Function IgnorePads
+ * @return bool - true if should ignore PADSs on Front side and Back side.
+ */
+ virtual bool IgnorePads() const
+ {
+ return IgnorePadsOnFront() && IgnorePadsOnBack();
+ }
+
+ /**
+ * Function IgnoreModulesVals
+ * @return bool - true if should ignore modules values.
+ */
+ virtual bool IgnoreModulesVals() const = 0;
+
+ /**
+ * Function IgnoreModulesRefs
+ * @return bool - true if should ignore module references.
+ */
+ virtual bool IgnoreModulesRefs() const = 0;
+
+ /**
+ * Function UseHitTesting
+ * @return bool - true if Inspect() should use BOARD_ITEM::HitTest()
+ * or false if Inspect() should use BOARD_ITEM::BoundsTest().
+ virtual bool UseHitTesting() const = 0;
+ */
+};
+
+
+
+/**
+ * Class GENERAL_COLLECTOR
+ * is intended for use when the right click button is pressed, or when the
+ * plain "arrow" tool is in effect. This class can be used by window classes
+ * such as PCB_EDIT_FRAME.
+ *
+ * Philosophy: this class knows nothing of the context in which a BOARD is used
+ * and that means it knows nothing about which layers are visible or current,
+ * but can handle those concerns by the SetPreferredLayer() function and the
+ * SetLayerSet() function.
+ */
+class GENERAL_COLLECTOR : public COLLECTOR
+{
+protected:
+ /**
+ * A place to hold collected objects which don't match precisely the search
+ * criteria, but would be acceptable if nothing else is found.
+ * "2nd" choice, which will be appended to the end of COLLECTOR's prime
+ * "list" at the end of the search.
+ */
+ std::vector<BOARD_ITEM*> m_List2nd;
+
+
+ /**
+ * Determines which items are to be collected by Inspect()
+ */
+ const COLLECTORS_GUIDE* m_Guide;
+
+
+ /**
+ * The number of items that were originally in the primary list before the
+ * m_List2nd was concatenated onto the end of it.
+ */
+ int m_PrimaryLength;
+
+
+public:
+
+ /**
+ * A scan list for all editable board items, like PcbGeneralLocateAndDisplay()
+ */
+ static const KICAD_T AllBoardItems[];
+
+
+ /**
+ * A scan list for all editable board items, except zones
+ */
+ static const KICAD_T AllButZones[];
+
+ /**
+ * A scan list for zones outlines only
+ */
+ static const KICAD_T Zones[];
+
+
+ /**
+ * A scan list for all primary board items, omitting items which are subordinate to
+ * a MODULE, such as D_PAD and TEXTEMODULE.
+ static const KICAD_T PrimaryItems[];
+ */
+
+
+ /**
+ * A scan list for only MODULEs
+ */
+ static const KICAD_T Modules[];
+
+
+ /**
+ * A scan list for PADs or MODULEs
+ */
+ static const KICAD_T PadsOrModules[];
+
+ /**
+ * A scan list for PADs, TRACKs, VIAs, or ZONEs
+ */
+ static const KICAD_T PadsTracksOrZones[];
+
+
+ /**
+ * A scan list for MODULEs and their items (for Modedit)
+ */
+ static const KICAD_T ModulesAndTheirItems[];
+
+
+ /**
+ * A scan list for primary module items.
+ */
+ static const KICAD_T ModuleItems[];
+
+
+ /**
+ * A scan list for only TRACKS
+ */
+ static const KICAD_T Tracks[];
+
+
+ /**
+ * Constructor GENERALCOLLECTOR
+ */
+ GENERAL_COLLECTOR()
+ {
+ m_Guide = NULL;
+ m_PrimaryLength = 0;
+ SetScanTypes( AllBoardItems );
+ }
+
+ void Empty2nd()
+ {
+ m_List2nd.clear();
+ }
+
+ void Append2nd( BOARD_ITEM* item )
+ {
+ m_List2nd.push_back( item );
+ }
+
+
+ /**
+ * Function SetGuide
+ * records which COLLECTORS_GUIDE to use.
+ * @param aGuide Which guide to use in the collection.
+ */
+ void SetGuide( const COLLECTORS_GUIDE* aGuide ) { m_Guide = aGuide; }
+
+
+ /**
+ * Function operator[int]
+ * overloads COLLECTOR::operator[](int) to return a BOARD_ITEM* instead of
+ * an EDA_ITEM* type.
+ * @param ndx The index into the list.
+ * @return BOARD_ITEM* - or something derived from it, or NULL.
+ */
+ BOARD_ITEM* operator[]( int ndx ) const
+ {
+ if( (unsigned)ndx < (unsigned)GetCount() )
+ return (BOARD_ITEM*) m_List[ ndx ];
+ return NULL;
+ }
+
+
+ /**
+ * Function GetPrimaryCount
+ * @return int - The number if items which met the primary search criteria
+ */
+ int GetPrimaryCount() { return m_PrimaryLength; }
+
+
+ /**
+ * Function Inspect
+ * is the examining function within the INSPECTOR which is passed to the
+ * Iterate function.
+ *
+ * @param testItem An EDA_ITEM to examine.
+ * @param testData is not used in this class.
+ * @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
+ * else SCAN_CONTINUE;
+ */
+ SEARCH_RESULT Inspect( EDA_ITEM* testItem, const void* testData );
+
+
+ /**
+ * Function Collect
+ * scans a BOARD_ITEM using this class's Inspector method, which does the collection.
+ * @param aItem A BOARD_ITEM to scan, may be a BOARD or MODULE, or whatever.
+ * @param aScanList A list of KICAD_Ts with a terminating EOT, that specs
+ * what is to be collected and the priority order of the resultant
+ * collection in "m_List".
+ * @param aRefPos A wxPoint to use in hit-testing.
+ * @param aGuide The COLLECTORS_GUIDE to use in collecting items.
+ */
+ void Collect( BOARD_ITEM* aItem, const KICAD_T aScanList[],
+ const wxPoint& aRefPos, const COLLECTORS_GUIDE& aGuide );
+};
+
+
+/**
+ * Class GENERAL_COLLECTORS_GUIDE
+ * is a general implementation of a COLLECTORS_GUIDE. One of its constructors is
+ * entitled to grab information from the program's global preferences.
+ */
+class GENERAL_COLLECTORS_GUIDE : public COLLECTORS_GUIDE
+{
+private:
+ // the storage architecture here is not important, since this is only
+ // a carrier object and its functions are what is used, and data only indirectly.
+
+ LAYER_ID m_PreferredLayer;
+ bool m_IgnorePreferredLayer;
+
+ LSET m_LayerLocked; ///< bit-mapped layer locked bits
+ bool m_IgnoreLockedLayers;
+
+ LSET m_LayerVisible; ///< bit-mapped layer visible bits
+ bool m_IgnoreNonVisibleLayers;
+
+ bool m_IgnoreLockedItems;
+ bool m_IncludeSecondary;
+
+ bool m_IgnoreMTextsMarkedNoShow;
+ bool m_IgnoreMTextsOnBack;
+ bool m_IgnoreMTextsOnFront;
+ bool m_IgnoreModulesOnBack;
+ bool m_IgnoreModulesOnFront;
+ bool m_IgnorePadsOnFront;
+ bool m_IgnorePadsOnBack;
+ bool m_IgnoreModulesVals;
+ bool m_IgnoreModulesRefs;
+
+public:
+
+ /**
+ * Constructor GENERAL_COLLECTORS_GUIDE
+ * grabs stuff from global preferences and uses reasonable defaults.
+ * Add more constructors as needed.
+ * @param aVisibleLayerMask = current visible layers (bit mask)
+ * @param aPreferredLayer = the layer to search first
+ */
+ GENERAL_COLLECTORS_GUIDE( LSET aVisibleLayerMask, LAYER_ID aPreferredLayer )
+ {
+ m_PreferredLayer = aPreferredLayer;
+ m_IgnorePreferredLayer = false;
+ m_LayerVisible = aVisibleLayerMask;
+ m_IgnoreLockedLayers = true;
+ m_IgnoreNonVisibleLayers = true;
+ m_IgnoreLockedItems = false;
+
+#if defined(USE_MATCH_LAYER)
+ m_IncludeSecondary = false;
+#else
+ m_IncludeSecondary = true;
+#endif
+
+ m_IgnoreMTextsMarkedNoShow = true; // g_ModuleTextNOVColor;
+ m_IgnoreMTextsOnBack = true;
+ m_IgnoreMTextsOnFront = false;
+ m_IgnoreModulesOnBack = true; // !Show_Modules_Cmp;
+ m_IgnoreModulesOnFront = false;
+
+ m_IgnorePadsOnFront = false;
+ m_IgnorePadsOnBack = false;
+
+ m_IgnoreModulesVals = false;
+ m_IgnoreModulesRefs = false;
+ }
+
+
+ /**
+ * Function IsLayerLocked
+ * @return bool - true if the given layer is locked, else false.
+ */
+ bool IsLayerLocked( LAYER_ID aLayerId ) const
+ {
+ return m_LayerLocked[aLayerId];
+ }
+
+ void SetLayerLocked( LAYER_ID aLayerId, bool isLocked )
+ {
+ m_LayerLocked.set( aLayerId, isLocked );
+ }
+
+ /**
+ * Function IsLayerVisible
+ * @return bool - true if the given layer is visible, else false.
+ */
+ bool IsLayerVisible( LAYER_ID aLayerId ) const
+ {
+ return m_LayerVisible[aLayerId];
+ }
+ void SetLayerVisible( LAYER_ID aLayerId, bool isVisible )
+ {
+ m_LayerVisible.set( aLayerId, isVisible );
+ }
+ void SetLayerVisibleBits( LSET aLayerBits ) { m_LayerVisible = aLayerBits; }
+
+ /**
+ * Function IgnoreLockedLayers
+ * @return bool - true if should ignore locked layers, else false.
+ */
+ bool IgnoreLockedLayers() const { return m_IgnoreLockedLayers; }
+ void SetIgnoreLockedLayers( bool ignore ) { m_IgnoreLockedLayers = ignore; }
+
+
+ /**
+ * Function IgnoredNonVisibleLayers
+ * @return bool - true if should ignore non-visible layers, else false.
+ */
+ bool IgnoreNonVisibleLayers() const { return m_IgnoreNonVisibleLayers; }
+ void SetIgnoreNonVisibleLayers( bool ignore ) { m_IgnoreLockedLayers = ignore; }
+
+
+ /**
+ * Function GetPreferredLayer
+ * @return int - the preferred layer for HitTest()ing.
+ */
+ LAYER_ID GetPreferredLayer() const { return m_PreferredLayer; }
+ void SetPreferredLayer( LAYER_ID aLayer ) { m_PreferredLayer = aLayer; }
+
+
+ /**
+ * Function IgnorePreferredLayer
+ * provides wildcard behavior regarding the preferred layer.
+ * @return bool - true if should ignore preferred layer, else false.
+ */
+ bool IgnorePreferredLayer() const { return m_IgnorePreferredLayer; }
+ void SetIgnorePreferredLayer( bool ignore ) { m_IgnorePreferredLayer = ignore; }
+
+
+ /**
+ * Function IgnoreLockedItems
+ * @return bool - true if should ignore locked items, else false.
+ */
+ bool IgnoreLockedItems() const { return m_IgnoreLockedItems; }
+ void SetIgnoreLockedItems( bool ignore ) { m_IgnoreLockedItems = ignore; }
+
+
+ /**
+ * Function IncludeSecondary
+ * determines if the secondary criteria, or 2nd choice items should be
+ * included.
+ * @return bool - true if should include, else false.
+ */
+ bool IncludeSecondary() const { return m_IncludeSecondary; }
+ void SetIncludeSecondary( bool include ) { m_IncludeSecondary = include; }
+
+
+ /**
+ * Function IgnoreMTextsMarkedNoShow
+ * @return bool - true if MTexts marked as "no show" should be ignored.
+ */
+ bool IgnoreMTextsMarkedNoShow() const { return m_IgnoreMTextsMarkedNoShow; }
+ void SetIgnoreMTextsMarkedNoShow( bool ignore ) { m_IgnoreMTextsMarkedNoShow = ignore; }
+
+ /**
+ * Function IgnoreMTextsOnCu
+ * @return bool - true if should ignore MTexts on back layers
+ */
+ bool IgnoreMTextsOnBack() const { return m_IgnoreMTextsOnBack; }
+ void SetIgnoreMTextsOnBack( bool ignore ) { m_IgnoreMTextsOnBack = ignore; }
+
+ /**
+ * Function IgnoreMTextsOnFront
+ * @return bool - true if should ignore MTexts on front layers
+ */
+ bool IgnoreMTextsOnFront() const { return m_IgnoreMTextsOnFront; }
+ void SetIgnoreMTextsOnFront( bool ignore ) { m_IgnoreMTextsOnFront = ignore; }
+
+ /**
+ * Function IgnoreModulesOnBack
+ * @return bool - true if should ignore MODULEs on the back side
+ */
+ bool IgnoreModulesOnBack() const { return m_IgnoreModulesOnBack; }
+ void SetIgnoreModulesOnBack( bool ignore ) { m_IgnoreModulesOnBack = ignore; }
+
+ /**
+ * Function IgnoreModulesOnFront
+ * @return bool - true if should ignore MODULEs on component layer.
+ */
+ bool IgnoreModulesOnFront() const { return m_IgnoreModulesOnFront; }
+ void SetIgnoreModulesOnFront( bool ignore ) { m_IgnoreModulesOnFront = ignore; }
+
+ /**
+ * Function IgnorePadsOnBack
+ * @return bool - true if should ignore Pads on Back Side.
+ */
+ bool IgnorePadsOnBack() const { return m_IgnorePadsOnBack; }
+ void SetIgnorePadsOnBack(bool ignore) { m_IgnorePadsOnBack = ignore; }
+
+ /**
+ * Function IgnorePadsOnFront
+ * @return bool - true if should ignore PADSs on Front Side.
+ */
+ bool IgnorePadsOnFront() const { return m_IgnorePadsOnFront; }
+ void SetIgnorePadsOnFront(bool ignore) { m_IgnorePadsOnFront = ignore; }
+
+ /**
+ * Function IgnoreModulesVals
+ * @return bool - true if should ignore modules values.
+ */
+ bool IgnoreModulesVals() const { return m_IgnoreModulesVals; }
+ void SetIgnoreModulesVals(bool ignore) { m_IgnoreModulesVals = ignore; }
+
+ /**
+ * Function IgnoreModulesRefs
+ * @return bool - true if should ignore modules references.
+ */
+ bool IgnoreModulesRefs() const { return m_IgnoreModulesRefs; }
+ void SetIgnoreModulesRefs(bool ignore) { m_IgnoreModulesRefs = ignore; }
+};
+
+
+/**
+ * Class PCB_TYPE_COLLECTOR
+ * merely gathers up all BOARD_ITEMs of a given set of KICAD_T type(s).
+ * @see class COLLECTOR
+ */
+class PCB_TYPE_COLLECTOR : public COLLECTOR
+{
+
+public:
+
+ /**
+ * Function operator[int]
+ * overloads COLLECTOR::operator[](int) to return a BOARD_ITEM* instead of
+ * an EDA_ITEM* type.
+ * @param ndx The index into the list.
+ * @return BOARD_ITEM* - or something derived from it, or NULL.
+ */
+ BOARD_ITEM* operator[]( int ndx ) const
+ {
+ if( (unsigned)ndx < (unsigned)GetCount() )
+ return (BOARD_ITEM*) m_List[ ndx ];
+ return NULL;
+ }
+
+
+ /**
+ * Function Inspect
+ * is the examining function within the INSPECTOR which is passed to the
+ * Iterate function.
+ *
+ * @param testItem An EDA_ITEM to examine.
+ * @param testData is not used in this class.
+ * @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
+ * else SCAN_CONTINUE;
+ */
+ SEARCH_RESULT Inspect( EDA_ITEM* testItem, const void* testData );
+
+
+ /**
+ * Function Collect
+ * scans a BOARD_ITEM using this class's Inspector method, which does
+ * the collection.
+ * @param aBoard The BOARD_ITEM to scan.
+ * @param aScanList The KICAD_Ts to gather up.
+ */
+ void Collect( BOARD_ITEM* aBoard, const KICAD_T aScanList[] );
+};
+
+#endif // COLLECTORS_H
diff --git a/pcbnew/connect.cpp b/pcbnew/connect.cpp
new file mode 100644
index 0000000..848c30b
--- /dev/null
+++ b/pcbnew/connect.cpp
@@ -0,0 +1,1003 @@
+/**
+ * @file connect.cpp
+ * @brief Functions to handle existing tracks in ratsnest calculations.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <macros.h>
+#include <wxBasePcbFrame.h>
+
+#include <pcbnew.h>
+
+// Helper classes to handle connection points
+#include <connect.h>
+
+extern void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb );
+extern void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode );
+
+// Local functions
+static void RebuildTrackChain( BOARD* pcb );
+
+
+CONNECTIONS::CONNECTIONS( BOARD * aBrd )
+{
+ m_brd = aBrd;
+ m_firstTrack = NULL;
+ m_lastTrack = NULL;
+}
+
+
+/* Fills m_sortedPads with all pads that be connected to tracks
+ * pads are sorted by X coordinate ( and Y coordinates for same X value )
+ * aNetcode = net code to filter pads or < 0 to put all pads in list
+ */
+void CONNECTIONS::BuildPadsList( int aNetcode )
+{
+ // Creates sorted pad list if not exists
+ m_sortedPads.clear();
+ m_brd->GetSortedPadListByXthenYCoord( m_sortedPads, aNetcode < 0 ? -1 : aNetcode );
+}
+
+/* Explores the list of pads and adds to m_PadsConnected member
+ * of each pad pads connected to
+ * Here, connections are due to intersecting pads, not tracks
+ */
+void CONNECTIONS::SearchConnectionsPadsToIntersectingPads()
+{
+ std::vector<CONNECTED_POINT*> candidates;
+
+ BuildPadsCandidatesList();
+
+ for( unsigned ii = 0; ii < m_sortedPads.size(); ii++ )
+ {
+ D_PAD* pad = m_sortedPads[ii];
+
+ pad->m_PadsConnected.clear();
+ candidates.clear();
+
+ CollectItemsNearTo( candidates, pad->ShapePos(), pad->GetBoundingRadius() );
+
+ // add pads to pad.m_PadsConnected, if they are connected
+ for( unsigned jj = 0; jj < candidates.size(); jj++ )
+ {
+ CONNECTED_POINT* item = candidates[jj];
+
+ D_PAD* candidate_pad = item->GetPad();
+
+ if( pad == candidate_pad )
+ continue;
+
+ if( !( pad->GetLayerSet() & candidate_pad->GetLayerSet() ).any() )
+ continue;
+ if( pad->HitTest( item->GetPoint() ) )
+ {
+ pad->m_PadsConnected.push_back( candidate_pad );
+ }
+ }
+ }
+}
+
+/* Explores the list of pads
+ * Adds to m_PadsConnected member of each track the pad(s) connected to
+ * Adds to m_TracksConnected member of each pad the track(s) connected to
+ * D_PAD::m_TracksConnected is cleared before adding items
+ * TRACK::m_PadsConnected is not cleared
+ */
+void CONNECTIONS::SearchTracksConnectedToPads( bool add_to_padlist, bool add_to_tracklist)
+{
+ std::vector<CONNECTED_POINT*> candidates;
+
+ for( unsigned ii = 0; ii < m_sortedPads.size(); ii++ )
+ {
+ D_PAD * pad = m_sortedPads[ii];
+ pad->m_TracksConnected.clear();
+ candidates.clear();
+
+ CollectItemsNearTo( candidates, pad->GetPosition(), pad->GetBoundingRadius() );
+
+ // add this pad to track.m_PadsConnected, if it is connected
+ for( unsigned jj = 0; jj < candidates.size(); jj++ )
+ {
+ CONNECTED_POINT* cp_item = candidates[jj];
+
+ if( !( pad->GetLayerSet() & cp_item->GetTrack()->GetLayerSet() ).any() )
+ continue;
+
+ if( pad->HitTest( cp_item->GetPoint() ) )
+ {
+ if( add_to_padlist )
+ cp_item->GetTrack()->m_PadsConnected.push_back( pad );
+
+ if( add_to_tracklist )
+ pad->m_TracksConnected.push_back( cp_item->GetTrack() );
+ }
+ }
+ }
+}
+
+void CONNECTIONS::CollectItemsNearTo( std::vector<CONNECTED_POINT*>& aList,
+ const wxPoint& aPosition, int aDistMax )
+{
+ /* Search items in m_Candidates that position is <= aDistMax from aPosition
+ * (Rectilinear distance)
+ * m_Candidates is sorted by X then Y values, so a fast binary search is used
+ * to locate the "best" entry point in list
+ * The best entry is a pad having its m_Pos.x == (or near) aPosition.x
+ * All candidates are near this candidate in list
+ * So from this entry point, a linear search is made to find all candidates
+ */
+ int idxmax = m_candidates.size()-1;
+
+ int delta = m_candidates.size();
+
+ int idx = 0; // Starting index is the beginning of list
+ while( delta )
+ {
+ // Calculate half size of remaining interval to test.
+ // Ensure the computed value is not truncated (too small)
+ if( (delta & 1) && ( delta > 1 ) )
+ delta++;
+ delta /= 2;
+
+ CONNECTED_POINT& item = m_candidates[idx];
+
+ int dist = item.GetPoint().x - aPosition.x;
+ if( abs(dist) <= aDistMax )
+ {
+ break; // A good entry point is found. The list can be scanned from this point.
+ }
+
+ else if( item.GetPoint().x < aPosition.x ) // We should search after this item
+ {
+ idx += delta;
+ if( idx > idxmax )
+ idx = idxmax;
+ }
+ else // We should search before this item
+ {
+ idx -= delta;
+ if( idx < 0 )
+ idx = 0;
+ }
+ }
+
+ /* Now explore the candidate list from the "best" entry point found
+ * (candidate "near" aPosition.x)
+ * We explore the list until abs(candidate->m_Point.x - aPosition.x) > aDistMax
+ * because the list is sorted by X position (and for a given X pos, by Y pos)
+ * Currently a linear search is made because the number of candidates
+ * having the right X position is usually small
+ */
+ // search next candidates in list
+ wxPoint diff;
+ for( int ii = idx; ii <= idxmax; ii++ )
+ {
+ CONNECTED_POINT* item = &m_candidates[ii];
+ diff = item->GetPoint() - aPosition;
+ if( abs(diff.x) > aDistMax )
+ break; // Exit: the distance is to long, we cannot find other candidates
+ if( abs(diff.y) > aDistMax )
+ continue; // the y distance is to long, but we can find other candidates
+ // We have here a good candidate: add it
+ aList.push_back( item );
+ }
+ // search previous candidates in list
+ for( int ii = idx-1; ii >=0; ii-- )
+ {
+ CONNECTED_POINT * item = &m_candidates[ii];
+ diff = item->GetPoint() - aPosition;
+ if( abs(diff.x) > aDistMax )
+ break;
+ if( abs(diff.y) > aDistMax )
+ continue;
+ // We have here a good candidate:add it
+ aList.push_back( item );
+ }
+}
+
+
+void CONNECTIONS::BuildPadsCandidatesList()
+{
+ m_candidates.clear();
+ m_candidates.reserve( m_sortedPads.size() );
+ for( unsigned ii = 0; ii < m_sortedPads.size(); ii++ )
+ {
+ D_PAD * pad = m_sortedPads[ii];
+ CONNECTED_POINT candidate( pad, pad->GetPosition() );
+ m_candidates.push_back( candidate );
+ }
+}
+
+/* sort function used to sort .m_Connected by X the Y values
+ * items are sorted by X coordinate value,
+ * and for same X value, by Y coordinate value.
+ */
+static bool sortConnectedPointByXthenYCoordinates( const CONNECTED_POINT & aRef,
+ const CONNECTED_POINT & aTst )
+{
+ if( aRef.GetPoint().x == aTst.GetPoint().x )
+ return aRef.GetPoint().y < aTst.GetPoint().y;
+ return aRef.GetPoint().x < aTst.GetPoint().x;
+}
+
+void CONNECTIONS::BuildTracksCandidatesList( TRACK* aBegin, TRACK* aEnd)
+{
+ m_candidates.clear();
+ m_firstTrack = m_lastTrack = aBegin;
+
+ unsigned ii = 0;
+
+ // Count candidates ( i.e. end points )
+ for( const TRACK* track = aBegin; track; track = track->Next() )
+ {
+ if( track->Type() == PCB_VIA_T )
+ ii++;
+ else
+ ii += 2;
+
+ m_lastTrack = track;
+
+ if( track == aEnd )
+ break;
+ }
+
+ // Build candidate list
+ m_candidates.reserve( ii );
+ for( TRACK* track = aBegin; track; track = track->Next() )
+ {
+ CONNECTED_POINT candidate( track, track->GetStart() );
+
+ m_candidates.push_back( candidate );
+ if( track->Type() != PCB_VIA_T )
+ {
+ CONNECTED_POINT candidate2( track, track->GetEnd());
+ m_candidates.push_back( candidate2 );
+ }
+
+ if( track == aEnd )
+ break;
+ }
+
+ // Sort list by increasing X coordinate,
+ // and for increasing Y coordinate when items have the same X coordinate
+ // So candidates to the same location are consecutive in list.
+ sort( m_candidates.begin(), m_candidates.end(), sortConnectedPointByXthenYCoordinates );
+}
+
+
+/* Populates .m_connected with tracks/vias connected to aTrack
+ * param aTrack = track or via to use as reference
+ * For calculation time reason, an exhaustive search cannot be made
+ * and a proximity search is made:
+ * Only tracks with one end near one end of aTrack are collected.
+ * near means dist <= aTrack width / 2
+ * because with this constraint we can make a fast search in track list
+ * m_candidates is expected to be populated by the track candidates ends list
+ */
+int CONNECTIONS::SearchConnectedTracks( const TRACK* aTrack )
+{
+ int count = 0;
+ m_connected.clear();
+
+ LSET layerMask = aTrack->GetLayerSet();
+
+ // Search for connections to starting point:
+#define USE_EXTENDED_SEARCH
+
+#ifdef USE_EXTENDED_SEARCH
+ int dist_max = aTrack->GetWidth() / 2;
+ static std::vector<CONNECTED_POINT*> tracks_candidates;
+#endif
+
+ wxPoint position = aTrack->GetStart();
+
+ for( int kk = 0; kk < 2; kk++ )
+ {
+#ifndef USE_EXTENDED_SEARCH
+ int idx = searchEntryPointInCandidatesList( position );
+
+ if( idx >= 0 )
+ {
+ // search after:
+ for( unsigned ii = idx; ii < m_candidates.size(); ii ++ )
+ {
+ if( m_candidates[ii].GetTrack() == aTrack )
+ continue;
+
+ if( m_candidates[ii].GetPoint() != position )
+ break;
+
+ if( ( m_candidates[ii].GetTrack()->GetLayerSet() & layerMask ).any() )
+ m_connected.push_back( m_candidates[ii].GetTrack() );
+ }
+
+ // search before:
+ for( int ii = idx-1; ii >= 0; ii -- )
+ {
+ if( m_candidates[ii].GetTrack() == aTrack )
+ continue;
+
+ if( m_candidates[ii].GetPoint() != position )
+ break;
+
+ if( ( m_candidates[ii].GetTrack()->GetLayerSet() & layerMask ).any() )
+ m_connected.push_back( m_candidates[ii].GetTrack() );
+ }
+ }
+#else
+
+ tracks_candidates.clear();
+
+ CollectItemsNearTo( tracks_candidates, position, dist_max );
+
+ for( unsigned ii = 0; ii < tracks_candidates.size(); ii++ )
+ {
+ TRACK* ctrack = tracks_candidates[ii]->GetTrack();
+
+ if( !( ctrack->GetLayerSet() & layerMask ).any() )
+ continue;
+
+ if( ctrack == aTrack )
+ continue;
+
+ // We have a good candidate: calculate the actual distance
+ // between ends, which should be <= dist max.
+ wxPoint delta = tracks_candidates[ii]->GetPoint() - position;
+
+ int dist = KiROUND( EuclideanNorm( delta ) );
+
+ if( dist > dist_max )
+ continue;
+
+ m_connected.push_back( ctrack );
+ }
+#endif
+
+ // Search for connections to ending point:
+ if( aTrack->Type() == PCB_VIA_T )
+ break;
+
+ position = aTrack->GetEnd();
+ }
+
+ return count;
+}
+
+
+int CONNECTIONS::searchEntryPointInCandidatesList( const wxPoint& aPoint )
+{
+ // Search the aPoint coordinates in m_Candidates
+ // m_Candidates is sorted by X then Y values, and a fast binary search is used
+ int idxmax = m_candidates.size()-1;
+
+ int delta = m_candidates.size();
+
+ int idx = 0; // Starting index is the beginning of list
+
+ while( delta )
+ {
+ // Calculate half size of remaining interval to test.
+ // Ensure the computed value is not truncated (too small)
+ if( ( delta & 1 ) && ( delta > 1 ) )
+ delta++;
+
+ delta /= 2;
+
+ CONNECTED_POINT& candidate = m_candidates[idx];
+
+ if( candidate.GetPoint() == aPoint ) // candidate found
+ {
+ return idx;
+ }
+
+ // Not found: test the middle of the remaining sub list
+ if( candidate.GetPoint().x == aPoint.x ) // Must search considering Y coordinate
+ {
+ if(candidate.GetPoint().y < aPoint.y) // Must search after this item
+ {
+ idx += delta;
+ if( idx > idxmax )
+ idx = idxmax;
+ }
+ else // Must search before this item
+ {
+ idx -= delta;
+ if( idx < 0 )
+ idx = 0;
+ }
+ }
+ else if( candidate.GetPoint().x < aPoint.x ) // Must search after this item
+ {
+ idx += delta;
+ if( idx > idxmax )
+ idx = idxmax;
+ }
+ else // Must search before this item
+ {
+ idx -= delta;
+ if( idx < 0 )
+ idx = 0;
+ }
+ }
+
+ return -1;
+}
+
+/* Used after a track change (delete a track ou add a track)
+ * Connections to pads are recalculated
+ * Note also aFirstTrack (and aLastTrack ) can be NULL
+ */
+void CONNECTIONS::Build_CurrNet_SubNets_Connections( TRACK* aFirstTrack, TRACK* aLastTrack, int aNetcode )
+{
+ m_firstTrack = aFirstTrack; // The first track used to build m_Candidates
+ m_lastTrack = aLastTrack; // The last track used to build m_Candidates
+
+ // Pads subnets are expected already cleared, because this function
+ // does not know the full list of pads
+ BuildTracksCandidatesList( aFirstTrack, aLastTrack );
+ TRACK* curr_track;
+ for( curr_track = aFirstTrack; curr_track != NULL; curr_track = curr_track->Next() )
+ {
+ // Clear track subnet id (Pads subnets are cleared outside this function)
+ curr_track->SetSubNet( 0 );
+ curr_track->m_TracksConnected.clear();
+ curr_track->m_PadsConnected.clear();
+
+ // Update connections between tracks:
+ SearchConnectedTracks( curr_track );
+ curr_track->m_TracksConnected = m_connected;
+
+ if( curr_track == aLastTrack )
+ break;
+ }
+
+ // Update connections between tracks and pads
+ BuildPadsList( aNetcode );
+ SearchTracksConnectedToPads();
+
+ // Update connections between intersecting pads (no tracks)
+ SearchConnectionsPadsToIntersectingPads();
+
+ // Creates sub nets (clusters) for the current net:
+ Propagate_SubNets();
+}
+
+
+/**
+ * Change a subnet value to a new value, in m_sortedPads pad list
+ * After that, 2 cluster (or subnets) are merged into only one.
+ * Note: the resulting subnet value is the smallest between aOldSubNet et aNewSubNet
+ */
+int CONNECTIONS::Merge_PadsSubNets( int aOldSubNet, int aNewSubNet )
+{
+ int change_count = 0;
+
+ if( aOldSubNet == aNewSubNet )
+ return 0;
+
+ if( (aOldSubNet > 0) && (aOldSubNet < aNewSubNet) )
+ std::swap( aOldSubNet, aNewSubNet );
+
+ // Examine connections between intersecting pads
+ for( unsigned ii = 0; ii < m_sortedPads.size(); ii++ )
+ {
+ D_PAD * curr_pad = m_sortedPads[ii];
+ if( curr_pad->GetSubNet() != aOldSubNet )
+ continue;
+
+ change_count++;
+ curr_pad->SetSubNet( aNewSubNet );
+ }
+
+ return change_count;
+}
+
+/*
+ * Change a subnet value to a new value, for tracks and pads which are connected to.
+ * The result is merging 2 clusters (or subnets) into only one cluster.
+ * Note: the resulting sub net value is the smallest between aOldSubNet et aNewSubNet
+ */
+int CONNECTIONS::Merge_SubNets( int aOldSubNet, int aNewSubNet )
+{
+ TRACK* curr_track;
+ int change_count = 0;
+
+ if( aOldSubNet == aNewSubNet )
+ return 0;
+
+ if( (aOldSubNet > 0) && (aOldSubNet < aNewSubNet) )
+ std::swap( aOldSubNet, aNewSubNet );
+
+ curr_track = (TRACK*)m_firstTrack;
+
+ for( ; curr_track != NULL; curr_track = curr_track->Next() )
+ {
+ if( curr_track->GetSubNet() != aOldSubNet )
+ {
+ if( curr_track == m_lastTrack )
+ break;
+
+ continue;
+ }
+
+ change_count++;
+ curr_track->SetSubNet( aNewSubNet );
+
+ for( unsigned ii = 0; ii < curr_track->m_PadsConnected.size(); ii++ )
+ {
+ D_PAD * pad = curr_track->m_PadsConnected[ii];
+ if( pad->GetSubNet() == aOldSubNet )
+ {
+ pad->SetSubNet( curr_track->GetSubNet() );
+ }
+ }
+
+ if( curr_track == m_lastTrack )
+ break;
+ }
+
+ return change_count;
+}
+
+
+/* Test a list of track segments, to create or propagate a sub netcode to pads and
+ * segments connected together.
+ * The track list must be sorted by nets, and all segments
+ * from m_firstTrack to m_lastTrack have the same net
+ * When 2 items are connected (a track to a pad, or a track to an other track),
+ * they are grouped in a cluster.
+ * The .m_Subnet member is the cluster identifier (subnet id)
+ * For a given net, if all tracks are created, there is only one cluster.
+ * but if not all tracks are created, there are more than one cluster,
+ * and some ratsnests will be left active.
+ * A ratsnest is active when it "connect" 2 items having different subnet id
+ */
+void CONNECTIONS::Propagate_SubNets()
+{
+ int sub_netcode = 1;
+
+ TRACK* curr_track = (TRACK*)m_firstTrack;
+ if( curr_track )
+ curr_track->SetSubNet( sub_netcode );
+
+ // Examine connections between tracks and pads
+ for( ; curr_track != NULL; curr_track = curr_track->Next() )
+ {
+ // First: handling connections to pads
+ for( unsigned ii = 0; ii < curr_track->m_PadsConnected.size(); ii++ )
+ {
+ D_PAD * pad = curr_track->m_PadsConnected[ii];
+
+ if( curr_track->GetSubNet() ) // the track segment is already a cluster member
+ {
+ if( pad->GetSubNet() > 0 )
+ {
+ // The pad is already a cluster member, so we can merge the 2 clusters
+ Merge_SubNets( pad->GetSubNet(), curr_track->GetSubNet() );
+ }
+ else
+ {
+ /* The pad is not yet attached to a cluster , so we can add this pad to
+ * the cluster */
+ pad->SetSubNet( curr_track->GetSubNet() );
+ }
+ }
+ else // the track segment is not attached to a cluster
+ {
+ if( pad->GetSubNet() > 0 )
+ {
+ // it is connected to a pad in a cluster, merge this track
+ curr_track->SetSubNet( pad->GetSubNet() );
+ }
+ else
+ {
+ /* it is connected to a pad not in a cluster, so we must create a new
+ * cluster (only with the 2 items: the track and the pad) */
+ sub_netcode++;
+ curr_track->SetSubNet( sub_netcode );
+ pad->SetSubNet( curr_track->GetSubNet() );
+ }
+ }
+ }
+
+ // Test connections between segments
+ for( unsigned ii = 0; ii < curr_track->m_TracksConnected.size(); ii++ )
+ {
+ BOARD_CONNECTED_ITEM* track = curr_track->m_TracksConnected[ii];
+
+ if( curr_track->GetSubNet() ) // The current track is already a cluster member
+ {
+ // The other track is already a cluster member, so we can merge the 2 clusters
+ if( track->GetSubNet() )
+ {
+ Merge_SubNets( track->GetSubNet(), curr_track->GetSubNet() );
+ }
+ else
+ {
+ // The other track is not yet attached to a cluster , so we can add this
+ // other track to the cluster
+ track->SetSubNet( curr_track->GetSubNet() );
+ }
+ }
+ else // the current track segment is not yet attached to a cluster
+ {
+ if( track->GetSubNet() )
+ {
+ // The other track is already a cluster member, so we can add
+ // the current segment to the cluster
+ curr_track->SetSubNet( track->GetSubNet() );
+ }
+ else
+ {
+ // it is connected to an other segment not in a cluster, so we must
+ // create a new cluster (only with the 2 track segments)
+ sub_netcode++;
+ curr_track->SetSubNet( sub_netcode );
+ track->SetSubNet( curr_track->GetSubNet() );
+ }
+ }
+ }
+
+ if( curr_track == m_lastTrack )
+ break;
+ }
+
+ // Examine connections between intersecting pads, and propagate
+ // sub_netcodes to intersecting pads
+ for( unsigned ii = 0; ii < m_sortedPads.size(); ii++ )
+ {
+ D_PAD* curr_pad = m_sortedPads[ii];
+
+ for( unsigned jj = 0; jj < curr_pad->m_PadsConnected.size(); jj++ )
+ {
+ D_PAD* pad = curr_pad->m_PadsConnected[jj];
+
+ if( curr_pad->GetSubNet() ) // the current pad is already attached to a cluster
+ {
+ if( pad->GetSubNet() > 0 )
+ {
+ // The pad is already a cluster member, so we can merge the 2 clusters
+ // Store the initial subnets, which will be modified by Merge_PadsSubNets
+ int subnet1 = pad->GetSubNet();
+ int subnet2 = curr_pad->GetSubNet();
+
+ // merge subnets of pads only, even those not connected by tracks
+ Merge_PadsSubNets( subnet1, subnet2 );
+
+ // merge subnets of tracks (and pads, which are already merged)
+ Merge_SubNets( subnet1, subnet2 );
+ }
+ else
+ {
+ // The pad is not yet attached to a cluster,
+ // so we can add this pad to the cluster
+ pad->SetSubNet( curr_pad->GetSubNet() );
+ }
+ }
+ else // the current pad is not attached to a cluster
+ {
+ if( pad->GetSubNet() > 0 )
+ {
+ // the connected pad is in a cluster,
+ // so we can add the current pad to the cluster
+ curr_pad->SetSubNet( pad->GetSubNet() );
+ }
+ else
+ {
+ // the connected pad is not in a cluster,
+ // so we must create a new cluster, with the 2 pads.
+ sub_netcode++;
+ curr_pad->SetSubNet( sub_netcode );
+ pad->SetSubNet( curr_pad->GetSubNet() );
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Test all connections of the board,
+ * and update subnet variable of pads and tracks
+ * TestForActiveLinksInRatsnest must be called after this function
+ * to update active/inactive ratsnest items status
+ */
+void PCB_BASE_FRAME::TestConnections()
+{
+ // Clear the cluster identifier for all pads
+ for( unsigned i = 0; i< m_Pcb->GetPadCount(); ++i )
+ {
+ D_PAD* pad = m_Pcb->GetPad(i);
+
+ pad->SetZoneSubNet( 0 );
+ pad->SetSubNet( 0 );
+ }
+
+ m_Pcb->Test_Connections_To_Copper_Areas();
+
+ // Test existing connections net by net
+ // note some nets can have no tracks, and pads intersecting
+ // so Build_CurrNet_SubNets_Connections must be called for each net
+ CONNECTIONS connections( m_Pcb );
+
+ int last_net_tested = 0;
+ int current_net_code = 0;
+
+ for( TRACK* track = m_Pcb->m_Track; track; )
+ {
+ // At this point, track is the first track of a given net
+ current_net_code = track->GetNetCode();
+
+ // Get last track of the current net
+ TRACK* lastTrack = track->GetEndNetCode( current_net_code );
+
+ if( current_net_code > 0 ) // do not spend time if net code = 0 ( dummy net )
+ {
+ // Test all previous nets having no tracks
+ for( int net = last_net_tested+1; net < current_net_code; net++ )
+ connections.Build_CurrNet_SubNets_Connections( NULL, NULL, net );
+
+ connections.Build_CurrNet_SubNets_Connections( track, lastTrack, current_net_code );
+ last_net_tested = current_net_code;
+ }
+
+ track = lastTrack->Next(); // this is now the first track of the next net
+ }
+
+ // Test last nets without tracks, if any
+ int netsCount = m_Pcb->GetNetCount();
+ for( int net = last_net_tested+1; net < netsCount; net++ )
+ connections.Build_CurrNet_SubNets_Connections( NULL, NULL, net );
+
+ Merge_SubNets_Connected_By_CopperAreas( m_Pcb );
+
+ return;
+}
+
+
+void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode )
+{
+ // Skip dummy net -1, and "not connected" net 0 (grouping all not connected pads)
+ if( aNetCode <= 0 )
+ return;
+
+ if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
+ Compile_Ratsnest( aDC, true );
+
+ // Clear the cluster identifier (subnet) of pads for this net
+ // Pads are grouped by netcode (and in netname alphabetic order)
+ for( unsigned i = 0; i < m_Pcb->GetPadCount(); ++i )
+ {
+ D_PAD* pad = m_Pcb->GetPad(i);
+
+ if( m_Pcb->GetPad(i)->GetNetCode() == aNetCode )
+ pad->SetSubNet( 0 );
+ }
+
+ m_Pcb->Test_Connections_To_Copper_Areas( aNetCode );
+
+ // Search for the first and the last segment relative to the given net code
+ if( m_Pcb->m_Track )
+ {
+ CONNECTIONS connections( m_Pcb );
+
+ TRACK* lastTrack = NULL;
+ TRACK* firstTrack = m_Pcb->m_Track.GetFirst()->GetStartNetCode( aNetCode );
+
+ if( firstTrack )
+ lastTrack = firstTrack->GetEndNetCode( aNetCode );
+
+ if( firstTrack && lastTrack ) // i.e. if there are segments
+ {
+ connections.Build_CurrNet_SubNets_Connections( firstTrack, lastTrack, aNetCode );
+ }
+ }
+
+ Merge_SubNets_Connected_By_CopperAreas( m_Pcb, aNetCode );
+
+ // rebuild the active ratsnest for this net
+ DrawGeneralRatsnest( aDC, aNetCode );
+ TestForActiveLinksInRatsnest( aNetCode );
+ DrawGeneralRatsnest( aDC, aNetCode );
+
+ // Display results
+ wxString msg;
+ int net_notconnected_count = 0;
+ NETINFO_ITEM* net = m_Pcb->FindNet( aNetCode );
+
+ if( net ) // Should not occur, but ...
+ {
+ for( unsigned ii = net->m_RatsnestStartIdx; ii < net->m_RatsnestEndIdx; ii++ )
+ {
+ if( m_Pcb->m_FullRatsnest[ii].IsActive() )
+ net_notconnected_count++;
+ }
+
+ msg.Printf( wxT( "links %d nc %d net %d: not conn %d" ),
+ m_Pcb->GetRatsnestsCount(), m_Pcb->GetUnconnectedNetCount(), aNetCode,
+ net_notconnected_count );
+ }
+ else
+ msg.Printf( wxT( "net not found: netcode %d" ), aNetCode );
+
+ SetStatusText( msg );
+
+ return;
+}
+
+
+/* search connections between tracks and pads and propagate pad net codes to the track
+ * segments.
+ * Pads netcodes are assumed to be up to date.
+ */
+void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
+{
+ // Build the net info list
+ GetBoard()->BuildListOfNets();
+
+ // Reset variables and flags used in computation
+ for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() )
+ {
+ t->m_TracksConnected.clear();
+ t->m_PadsConnected.clear();
+ t->start = NULL;
+ t->end = NULL;
+ t->SetState( BUSY | IN_EDIT | BEGIN_ONPAD | END_ONPAD, false );
+ t->SetZoneSubNet( 0 );
+ t->SetNetCode( NETINFO_LIST::UNCONNECTED );
+ }
+
+ // If no pad, reset pointers and netcode, and do nothing else
+ if( m_Pcb->GetPadCount() == 0 )
+ return;
+
+ CONNECTIONS connections( m_Pcb );
+ connections.BuildPadsList();
+ connections.BuildTracksCandidatesList(m_Pcb->m_Track);
+
+ // First pass: build connections between track segments and pads.
+ connections.SearchTracksConnectedToPads();
+
+ // For tracks connected to at least one pad,
+ // set the track net code to the pad netcode
+ for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() )
+ {
+ if( t->m_PadsConnected.size() )
+ t->SetNetCode( t->m_PadsConnected[0]->GetNetCode() );
+ }
+
+ // Pass 2: build connections between track ends
+ for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() )
+ {
+ connections.SearchConnectedTracks( t );
+ connections.GetConnectedTracks( t );
+ }
+
+ // Propagate net codes from a segment to other connected segments
+ bool new_pass_request = true; // set to true if a track has its netcode changed from 0
+ // to a known netcode to re-evaluate netcodes
+ // of connected items
+ while( new_pass_request )
+ {
+ new_pass_request = false;
+
+ for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() )
+ {
+ int netcode = t->GetNetCode();
+
+ if( netcode == 0 )
+ {
+ // try to find a connected item having a netcode
+ for( unsigned kk = 0; kk < t->m_TracksConnected.size(); kk++ )
+ {
+ int altnetcode = t->m_TracksConnected[kk]->GetNetCode();
+ if( altnetcode )
+ {
+ new_pass_request = true;
+ netcode = altnetcode;
+ t->SetNetCode(netcode);
+ break;
+ }
+ }
+ }
+
+ if( netcode ) // this track has a netcode
+ {
+ // propagate this netcode to connected tracks having no netcode
+ for( unsigned kk = 0; kk < t->m_TracksConnected.size(); kk++ )
+ {
+ int altnetcode = t->m_TracksConnected[kk]->GetNetCode();
+ if( altnetcode == 0 )
+ {
+ t->m_TracksConnected[kk]->SetNetCode(netcode);
+ new_pass_request = true;
+ }
+ }
+ }
+ }
+ }
+
+ // Sort the track list by net codes:
+ RebuildTrackChain( m_Pcb );
+}
+
+
+
+/*
+ * Function SortTracksByNetCode used in RebuildTrackChain()
+ * to sort track segments by net code.
+ */
+static bool SortTracksByNetCode( const TRACK* const & ref, const TRACK* const & compare )
+{
+ // For items having the same Net, keep the order in list
+ if( ref->GetNetCode() == compare->GetNetCode())
+ return ref->m_Param < compare->m_Param;
+
+ return ref->GetNetCode() < compare->GetNetCode();
+}
+
+/**
+ * Helper function RebuildTrackChain
+ * rebuilds the track segment linked list in order to have a chain
+ * sorted by increasing netcodes.
+ * We try to keep order of track segments in list, when possible
+ * @param pcb = board to rebuild
+ */
+static void RebuildTrackChain( BOARD* pcb )
+{
+ if( pcb->m_Track == NULL )
+ return;
+
+ int item_count = pcb->m_Track.GetCount();
+
+ std::vector<TRACK*> trackList;
+ trackList.reserve( item_count );
+
+ // Put track list in a temporary list to sort tracks by netcode
+ // We try to keep the initial order of track segments in list, when possible
+ // so we use m_Param (a member variable used for temporary storage)
+ // to temporary keep trace of the order of segments
+ // The sort function uses this variable to sort items that
+ // have the same net code.
+ // Without this, during sorting, the initial order is sometimes lost
+ // by the sort algorithm
+ for( int ii = 0; ii < item_count; ++ii )
+ {
+ pcb->m_Track->m_Param = ii;
+ trackList.push_back( pcb->m_Track.PopFront() );
+ }
+
+ // the list is empty now
+ wxASSERT( pcb->m_Track == NULL && pcb->m_Track.GetCount()==0 );
+
+ sort( trackList.begin(), trackList.end(), SortTracksByNetCode );
+
+ // add them back to the list
+ for( int i = 0; i < item_count; ++i )
+ pcb->m_Track.PushBack( trackList[i] );
+}
diff --git a/pcbnew/connect.h b/pcbnew/connect.h
new file mode 100644
index 0000000..46868c8
--- /dev/null
+++ b/pcbnew/connect.h
@@ -0,0 +1,263 @@
+/**
+ * @file connect.h
+ * @brief helper classes to find track to track and track to pad connections.
+ */
+#ifndef CONNECT_H
+#define CONNECT_H
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <class_track.h>
+#include <class_board.h>
+
+
+// Helper classes to handle connection points (i.e. candidates) for tracks
+
+/* class CONNECTED_POINT describes a coordinate having a track or pad parent.
+ * when a pad is the parent, the coordinate is (obviously) the connection point
+ * when a track is the parent, the coordinate is the staring point
+ * or the ending point.
+ * therefore when building a list of CONNECTED_POINT, a pad or via generates one item,
+ * and a track generates 2 items.
+ */
+class CONNECTED_POINT
+{
+private:
+ BOARD_CONNECTED_ITEM * m_item; // a link to the parent item (track, via or pad)
+ wxPoint m_point; // coordinates of this connected point
+
+public:
+ // ctor to build a CONNECTED_POINT instance, when the parent is a track or via
+ CONNECTED_POINT( TRACK * aTrack, const wxPoint & aPoint)
+ {
+ m_item = aTrack;
+ m_point = aPoint;
+ }
+
+ // ctor to build a CONNECTED_POINT instance, when the parent is a pad
+ CONNECTED_POINT( D_PAD * aPad, const wxPoint & aPoint)
+ {
+ m_item = aPad;
+ m_point = aPoint;
+ }
+
+ /**
+ * Function GetTrack
+ * @return the parent track or via of this connected point,
+ * or null if the parent is a pad
+ */
+ TRACK * GetTrack() const
+ {
+ return m_item->Type() != PCB_PAD_T ? (TRACK*) m_item : NULL ;
+ }
+
+ /**
+ * Function GetPad
+ * @return the parent pad of this connected point,
+ * or null if the parent is a track or via
+ */
+ D_PAD * GetPad() const
+ {
+ return m_item->Type() == PCB_PAD_T ? (D_PAD*) m_item : NULL;
+ }
+
+ const wxPoint & GetPoint() const { return m_point; }
+};
+
+// A helper class to handle connections calculations:
+class CONNECTIONS
+{
+private:
+ std::vector <TRACK*> m_connected; // List of connected tracks/vias
+ // to a given track or via
+ std::vector <CONNECTED_POINT> m_candidates; // List of points to test
+ // (end points of tracks or vias location )
+ BOARD * m_brd; // the master board.
+ const TRACK * m_firstTrack; // The first track used to build m_Candidates
+ const TRACK * m_lastTrack; // The last track used to build m_Candidates
+ std::vector<D_PAD*> m_sortedPads; // list of sorted pads by X (then Y) coordinate
+
+public:
+ CONNECTIONS( BOARD * aBrd );
+ ~CONNECTIONS() {};
+
+ /**
+ * Function BuildPadsList
+ * Fills m_sortedPads with all pads that be connected to tracks
+ * pads are sorted by X then Y coordinates to allow fast binary search in list
+ * @param aNetcode = net code to use to filter pads
+ * if aNetcode < 0, all pads will be put in list (default)
+ */
+ void BuildPadsList( int aNetcode = -1 );
+
+ /**
+ * Function GetPadsList
+ * @return the pads list used in connections calculations
+ */
+ std::vector<D_PAD*>& GetPadsList() { return m_sortedPads; }
+
+ /**
+ * Function Build_CurrNet_SubNets_Connections
+ * should be called after a track change (delete or add a track):
+ * Connections to pads and to tracks are recalculated
+ * If a track is deleted, the other pointers to pads do not change.
+ * When a new track is added in track list, its pointers to pads are already initialized
+ * Builds the subnets inside a net (tracks from aFirstTrack to aFirstTrack).
+ * subnets are clusters of pads and tracks that are connected together.
+ * When all tracks are created relative to the net, there is only a cluster
+ * when not tracks there are a cluster per pad
+ * @param aFirstTrack = first track of the given net
+ * @param aLastTrack = last track of the given net
+ * @param aNetcode = the netcode of the given net
+ */
+ void Build_CurrNet_SubNets_Connections( TRACK* aFirstTrack, TRACK* aLastTrack, int aNetcode );
+
+ /**
+ * Function BuildTracksCandidatesList
+ * Fills m_Candidates with all connecting points (track ends or via location)
+ * with tracks from aBegin to aEnd.
+ * @param aBegin = first track to store in list (should not be NULL)
+ * @param aEnd = last track to store in list
+ * if aEnd == NULL, uses all tracks from aBegin
+ */
+ void BuildTracksCandidatesList( TRACK * aBegin, TRACK * aEnd = NULL);
+
+ /**
+ * Function BuildPadsCandidatesList
+ * Populates m_candidates with all pads connecting points (pads position)
+ * m_sortedPads is expected to be populated by the pad candidates list
+ */
+ void BuildPadsCandidatesList();
+
+ /**
+ * function SearchConnectedTracks
+ * Populates .m_connected with tracks/vias connected to aTrack
+ * m_candidates is expected to be populated by the track candidates ends list
+ * @param aTrack = track or via to use as reference
+ */
+ int SearchConnectedTracks( const TRACK * aTrack );
+
+ /**
+ * Function GetConnectedTracks
+ * Copy m_Connected that contains the list of tracks connected
+ * calculated by SearchConnectedTracks
+ * in aTrack->m_TracksConnected
+ * @param aTrack = track or via to fill with connected tracks
+ */
+ void GetConnectedTracks(TRACK * aTrack)
+ {
+ aTrack->m_TracksConnected = m_connected;
+ }
+
+ /**
+ * function SearchConnectionsPadsToIntersectingPads
+ * Explores the list of pads and adds to m_PadsConnected member
+ * of each pad pads connected to
+ * Here, connections are due to intersecting pads, not tracks
+ * m_sortedPads must be initialized
+ */
+ void SearchConnectionsPadsToIntersectingPads();
+
+ /**
+ * function SearchTracksConnectedToPads
+ * Explores the list of pads.
+ * if( add_to_padlist )
+ * adds to m_PadsConnected member of each track the pad(s) connected to
+ * if add_to_tracklist
+ * adds to m_TracksConnected member of each pad the track(s) connected to
+ * D_PAD::m_TracksConnected is cleared before adding items
+ * TRACK::m_PadsConnected is not cleared
+ * @param add_to_padlist = true to fill m_PadsConnected member of each track
+ * @param add_to_tracklist = true to fill m_TracksConnected member of each pad
+ */
+ void SearchTracksConnectedToPads( bool add_to_padlist = true, bool add_to_tracklist = true);
+
+ /**
+ * function CollectItemsNearTo
+ * Used by SearchTracksConnectedToPads
+ * Fills aList with pads near to aPosition
+ * near means aPosition to pad position <= aDistMax
+ * @param aList = list to fill
+ * @param aPosition = aPosition to use as reference
+ * @param aDistMax = dist max from aPosition to a candidate to select it
+ */
+ void CollectItemsNearTo( std::vector<CONNECTED_POINT*>& aList,
+ const wxPoint& aPosition, int aDistMax );
+
+ /**
+ * Function Propagate_SubNets
+ * Test a list of tracks, to create or propagate a sub netcode to pads and
+ * segments connected together.
+ * The track list must be sorted by nets, and all segments
+ * from m_firstTrack to m_lastTrack have the same net.
+ * When 2 items are connected (a track to a pad, or a track to an other track),
+ * they are grouped in a cluster.
+ * For pads, this is the .m_physical_connexion member which is a cluster identifier
+ * For tracks, this is the .m_Subnet member which is a cluster identifier
+ * For a given net, if all tracks are created, there is only one cluster.
+ * but if not all tracks are created, there are more than one cluster,
+ * and some ratsnests will be left active.
+ */
+ void Propagate_SubNets();
+
+private:
+ /**
+ * function searchEntryPointInCandidatesList
+ * Search an item in m_Connected connected to aPoint
+ * note m_Connected containts usually more than one candidate
+ * and searchEntryPointInCandidatesList returns an index to one of these candidates
+ * Others are neightbor of the indexed item.
+ * @param aPoint is the reference coordinates
+ * @return the index of item found or -1 if no candidate
+ */
+ int searchEntryPointInCandidatesList( const wxPoint & aPoint);
+
+ /**
+ * Function Merge_SubNets
+ * Change a subnet old value to a new value, for tracks and pads which are connected to
+ * tracks from m_firstTrack to m_lastTrack and their connected pads.
+ * and modify the subnet parameter (change the old value to the new value).
+ * After that, 2 cluster (or subnets) are merged into only one.
+ * Note: the resulting sub net value is the smallest between aOldSubNet and aNewSubNet
+ * @return modification count
+ * @param aOldSubNet = subnet value to modify
+ * @param aNewSubNet = new subnet value for each item which have old_val as subnet value
+ */
+ int Merge_SubNets( int aOldSubNet, int aNewSubNet );
+
+ /**
+ * Function Merge_PadsSubNets
+ * Change a subnet value to a new value, in m_sortedPads pad list
+ * After that, 2 cluster (or subnets) are merged into only one.
+ * Note: the resulting subnet value is the smallest between aOldSubNet et aNewSubNet
+ * @return modification count
+ * @param aOldSubNet = subnet value to modify
+ * @param aNewSubNet = new subnet value for each item which have old_val as subnet value
+ */
+ int Merge_PadsSubNets( int aOldSubNet, int aNewSubNet );
+};
+
+#endif // ifndef CONNECT_H
diff --git a/pcbnew/controle.cpp b/pcbnew/controle.cpp
new file mode 100644
index 0000000..d9475f2
--- /dev/null
+++ b/pcbnew/controle.cpp
@@ -0,0 +1,355 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/controle.cpp
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+#include <pcbnew_id.h>
+#include <class_board.h>
+#include <class_module.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <protos.h>
+#include <collectors.h>
+#include <menus_helpers.h>
+
+//external functions used here:
+extern bool Magnetize( PCB_EDIT_FRAME* frame, int aCurrentTool,
+ wxSize aGridSize, wxPoint on_grid, wxPoint* curpos );
+
+
+/**
+ * Function AllAreModulesAndReturnSmallestIfSo
+ * tests that all items in the collection are MODULEs and if so, returns the
+ * smallest MODULE.
+ * @return BOARD_ITEM* - The smallest or NULL.
+ */
+static BOARD_ITEM* AllAreModulesAndReturnSmallestIfSo( GENERAL_COLLECTOR* aCollector )
+{
+#if 0 // Dick: this is not consistent with name of this function, and does not
+ // work correctly using 'M' (move hotkey) when another module's (2nd module) reference
+ // is under a module (first module) and you want to move the reference.
+ // Another way to fix this would be to
+ // treat module text as copper layer content, and put the module text into
+ // the primary list. I like the coded behavior best. If it breaks something
+ // perhaps you need a different test before calling this function, which should
+ // do what its name says it does.
+ int count = aCollector->GetPrimaryCount(); // try to use preferred layer
+ if( 0 == count ) count = aCollector->GetCount();
+#else
+ int count = aCollector->GetCount();
+#endif
+
+ for( int i = 0; i<count; ++i )
+ {
+ if( (*aCollector)[i]->Type() != PCB_MODULE_T )
+ return NULL;
+ }
+
+ // all are modules, now find smallest MODULE
+
+ int minDim = 0x7FFFFFFF;
+ int minNdx = 0;
+
+ for( int i = 0; i<count; ++i )
+ {
+ MODULE* module = (MODULE*) (*aCollector)[i];
+
+ int lx = module->GetBoundingBox().GetWidth();
+ int ly = module->GetBoundingBox().GetHeight();
+
+ int lmin = std::min( lx, ly );
+
+ if( lmin < minDim )
+ {
+ minDim = lmin;
+ minNdx = i;
+ }
+ }
+
+ return (*aCollector)[minNdx];
+}
+
+
+BOARD_ITEM* PCB_BASE_FRAME::PcbGeneralLocateAndDisplay( int aHotKeyCode )
+{
+ BOARD_ITEM* item;
+
+ GENERAL_COLLECTORS_GUIDE guide = GetCollectorsGuide();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ // Assign to scanList the proper item types desired based on tool type
+ // or hotkey that is in play.
+
+ const KICAD_T* scanList = NULL;
+
+ if( aHotKeyCode )
+ {
+ // @todo: add switch here and add calls to PcbGeneralLocateAndDisplay( int aHotKeyCode )
+ // when searching is needed from a hotkey handler
+ }
+ else if( GetToolId() == ID_NO_TOOL_SELECTED )
+ {
+ if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_MODULE ) )
+ scanList = GENERAL_COLLECTOR::Modules;
+ else
+ scanList = (displ_opts->m_DisplayZonesMode == 0) ?
+ GENERAL_COLLECTOR::AllBoardItems :
+ GENERAL_COLLECTOR::AllButZones;
+ }
+ else
+ {
+ switch( GetToolId() )
+ {
+ case ID_PCB_SHOW_1_RATSNEST_BUTT:
+ scanList = GENERAL_COLLECTOR::PadsOrModules;
+ break;
+
+ case ID_TRACK_BUTT:
+ scanList = GENERAL_COLLECTOR::Tracks;
+ break;
+
+ case ID_PCB_MODULE_BUTT:
+ scanList = GENERAL_COLLECTOR::Modules;
+ break;
+
+ case ID_PCB_ZONES_BUTT:
+ case ID_PCB_KEEPOUT_AREA_BUTT:
+ scanList = GENERAL_COLLECTOR::Zones;
+ break;
+
+ default:
+ scanList = displ_opts->m_DisplayZonesMode == 0 ?
+ GENERAL_COLLECTOR::AllBoardItems :
+ GENERAL_COLLECTOR::AllButZones;
+ }
+ }
+
+ m_Collector->Collect( m_Pcb, scanList, RefPos( true ), guide );
+
+#if 0
+ // debugging: print out the collected items, showing their priority order too.
+ for( int i = 0; i<m_Collector->GetCount(); ++i )
+ (*m_Collector)[i]->Show( 0, std::cout );
+#endif
+
+ /* Remove redundancies: sometime, legacy zones are found twice,
+ * because zones can be filled by overlapping segments (this is a fill option)
+ * Trigger the selection of the current edge for new-style zones
+ */
+ time_t timestampzone = 0;
+
+ for( int ii = 0; ii < m_Collector->GetCount(); ii++ )
+ {
+ item = (*m_Collector)[ii];
+
+ switch( item->Type() )
+ {
+ case PCB_ZONE_T:
+ // Found a TYPE ZONE
+ if( item->GetTimeStamp() == timestampzone ) // Remove it, redundant, zone already found
+ {
+ m_Collector->Remove( ii );
+ ii--;
+ }
+ else
+ {
+ timestampzone = item->GetTimeStamp();
+ }
+ break;
+
+ case PCB_ZONE_AREA_T:
+ {
+ /* We need to do the selection now because the menu text
+ * depends on it */
+ ZONE_CONTAINER *zone = static_cast<ZONE_CONTAINER*>( item );
+ zone->SetSelectedCorner( RefPos( true ) );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( m_Collector->GetCount() <= 1 )
+ {
+ item = (*m_Collector)[0];
+ SetCurItem( item );
+ }
+
+ // If the count is 2, and first item is a pad or module text, and the 2nd item is its
+ // parent module:
+ else if( m_Collector->GetCount() == 2
+ && ( (*m_Collector)[0]->Type() == PCB_PAD_T || (*m_Collector)[0]->Type() ==
+ PCB_MODULE_TEXT_T )
+ && (*m_Collector)[1]->Type() == PCB_MODULE_T && (*m_Collector)[0]->GetParent()==
+ (*m_Collector)[1] )
+ {
+ item = (*m_Collector)[0];
+ SetCurItem( item );
+ }
+ // if all are modules, find the smallest one among the primary choices
+ else if( ( item = AllAreModulesAndReturnSmallestIfSo( m_Collector ) ) != NULL )
+ {
+ SetCurItem( item );
+ }
+
+ else // we can't figure out which item user wants, do popup menu so user can choose
+ {
+ wxMenu itemMenu;
+
+ // Give a title to the selection menu. This is also a cancel menu item
+ wxMenuItem * item_title = new wxMenuItem( &itemMenu, -1, _( "Selection Clarification" ) );
+
+#ifdef __WINDOWS__
+ wxFont bold_font( *wxNORMAL_FONT );
+ bold_font.SetWeight( wxFONTWEIGHT_BOLD );
+ bold_font.SetStyle( wxFONTSTYLE_ITALIC );
+ item_title->SetFont( bold_font );
+#endif
+
+ itemMenu.Append( item_title );
+ itemMenu.AppendSeparator();
+
+ int limit = std::min( MAX_ITEMS_IN_PICKER, m_Collector->GetCount() );
+
+ for( int i = 0; i<limit; ++i )
+ {
+ wxString text;
+ item = (*m_Collector)[i];
+
+ text = item->GetSelectMenuText();
+
+ BITMAP_DEF xpm = item->GetMenuImage();
+
+ AddMenuItem( &itemMenu, ID_POPUP_PCB_ITEM_SELECTION_START + i, text, KiBitmap( xpm ) );
+ }
+
+ /* @todo: rather than assignment to true, these should be increment and decrement
+ * operators throughout _everywhere_.
+ * That way we can handle nesting.
+ * But I tried that and found there cases where the assignment to true (converted to
+ * a m_IgnoreMouseEvents++ )
+ * was not balanced with the -- (now m_IgnoreMouseEvents=false), so I had to revert.
+ * Somebody should track down these and make them balanced.
+ * m_canvas->SetIgnoreMouseEvents( true );
+ */
+
+ // this menu's handler is void PCB_BASE_FRAME::ProcessItemSelection()
+ // and it calls SetCurItem() which in turn calls DisplayInfo() on the item.
+ m_canvas->SetAbortRequest( true ); // changed in false if an item is selected
+ PopupMenu( &itemMenu );
+
+ m_canvas->MoveCursorToCrossHair();
+
+ // The function ProcessItemSelection() has set the current item, return it.
+ if( m_canvas->GetAbortRequest() ) // Nothing selected
+ item = NULL;
+ else
+ item = GetCurItem();
+ }
+
+ return item;
+}
+
+
+bool PCB_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
+{
+ bool eventHandled = true;
+
+ // Filter out the 'fake' mouse motion after a keyboard movement
+ if( !aHotKey && m_movingCursorWithKeyboard )
+ {
+ m_movingCursorWithKeyboard = false;
+ return false;
+ }
+
+ // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
+ // for next cursor position
+ // ( shift or ctrl key down are PAN command with mouse wheel)
+ bool snapToGrid = true;
+
+ if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
+ snapToGrid = false;
+
+ wxPoint oldpos = GetCrossHairPosition();
+ wxPoint pos = aPosition;
+ GeneralControlKeyMovement( aHotKey, &pos, snapToGrid );
+
+ // Put cursor in new position, according to the zoom keys (if any).
+ SetCrossHairPosition( pos, snapToGrid );
+
+ /* Put cursor on grid or a pad centre if requested. If the tool DELETE is active the
+ * cursor is left off grid this is better to reach items to delete off grid,
+ */
+ if( GetToolId() == ID_PCB_DELETE_ITEM_BUTT )
+ snapToGrid = false;
+
+ // Cursor is left off grid if no block in progress
+ if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
+ snapToGrid = true;
+
+ wxPoint curs_pos = pos;
+
+ wxRealPoint gridSize = GetScreen()->GetGridSize();
+ wxSize igridsize;
+ igridsize.x = KiROUND( gridSize.x );
+ igridsize.y = KiROUND( gridSize.y );
+
+ if( Magnetize( this, GetToolId(), igridsize, curs_pos, &pos ) )
+ {
+ SetCrossHairPosition( pos, false );
+ }
+ else
+ {
+ // If there's no intrusion and DRC is active, we pass the cursor
+ // "as is", and let ShowNewTrackWhenMovingCursor figure out what to do.
+ if( !g_Drc_On || !g_CurrentTrackSegment ||
+ (BOARD_ITEM*)g_CurrentTrackSegment != this->GetCurItem() ||
+ !LocateIntrusion( m_Pcb->m_Track, g_CurrentTrackSegment,
+ GetScreen()->m_Active_Layer, RefPos( true ) ) )
+ {
+ SetCrossHairPosition( curs_pos, snapToGrid );
+ }
+ }
+
+ RefreshCrossHair( oldpos, aPosition, aDC );
+
+ if( aHotKey )
+ {
+ eventHandled = OnHotKey( aDC, aHotKey, aPosition );
+ }
+
+ UpdateStatusBar(); // Display new cursor coordinates
+
+ return eventHandled;
+}
diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp
new file mode 100644
index 0000000..9c95569
--- /dev/null
+++ b/pcbnew/cross-probing.cpp
@@ -0,0 +1,251 @@
+/**
+ * @file pcbnew/cross-probing.cpp
+ * @brief Cross probing functions to handle communication to andfrom Eeschema.
+ */
+
+/**
+ * Handle messages between Pcbnew and Eeschema via a socket, the port numbers are
+ * KICAD_PCB_PORT_SERVICE_NUMBER (currently 4242) (Eeschema to Pcbnew)
+ * KICAD_SCH_PORT_SERVICE_NUMBER (currently 4243) (Pcbnew to Eeschema)
+ * Note: these ports must be enabled for firewall protection
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <kiway_express.h>
+#include <wxPcbStruct.h>
+#include <eda_dde.h>
+#include <macros.h>
+
+#include <pcbnew_id.h>
+#include <class_board.h>
+#include <class_module.h>
+
+#include <collectors.h>
+#include <pcbnew.h>
+
+#include <tools/common_actions.h>
+#include <tool/tool_manager.h>
+#include <pcb_draw_panel_gal.h>
+
+/* Execute a remote command send by Eeschema via a socket,
+ * port KICAD_PCB_PORT_SERVICE_NUMBER
+ * cmdline = received command from Eeschema
+ * Commands are
+ * $PART: "reference" put cursor on component
+ * $PIN: "pin name" $PART: "reference" put cursor on the footprint pin
+ */
+void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
+{
+ char line[1024];
+ wxString msg;
+ wxString modName;
+ char* idcmd;
+ char* text;
+ MODULE* module = NULL;
+ D_PAD* pad = NULL;
+ BOARD* pcb = GetBoard();
+ wxPoint pos;
+
+ strncpy( line, cmdline, sizeof(line) - 1 );
+ line[sizeof(line) - 1] = 0;
+
+ idcmd = strtok( line, " \n\r" );
+ text = strtok( NULL, " \n\r" );
+
+ if( !idcmd || !text )
+ return;
+
+ if( strcmp( idcmd, "$PART:" ) == 0 )
+ {
+ modName = FROM_UTF8( text );
+
+ module = pcb->FindModuleByReference( modName );
+
+ if( module )
+ msg.Printf( _( "%s found" ), GetChars( modName ) );
+ else
+ msg.Printf( _( "%s not found" ), GetChars( modName ) );
+
+ SetStatusText( msg );
+
+ if( module )
+ pos = module->GetPosition();
+ }
+ else if( strcmp( idcmd, "$PIN:" ) == 0 )
+ {
+ wxString pinName;
+ int netcode = -1;
+
+ pinName = FROM_UTF8( text );
+
+ text = strtok( NULL, " \n\r" );
+ if( text && strcmp( text, "$PART:" ) == 0 )
+ text = strtok( NULL, "\n\r" );
+
+ modName = FROM_UTF8( text );
+
+ module = pcb->FindModuleByReference( modName );
+
+ if( module )
+ pad = module->FindPadByName( pinName );
+
+ if( pad )
+ {
+ netcode = pad->GetNetCode();
+
+ // put cursor on the pad:
+ pos = pad->GetPosition();
+ }
+
+ if( netcode > 0 ) // highlight the pad net
+ {
+ pcb->HighLightON();
+ pcb->SetHighLightNet( netcode );
+ }
+ else
+ {
+ pcb->HighLightOFF();
+ pcb->SetHighLightNet( -1 );
+ }
+
+ if( module == NULL )
+ {
+ msg.Printf( _( "%s not found" ), GetChars( modName ) );
+ }
+ else if( pad == NULL )
+ {
+ msg.Printf( _( "%s pin %s not found" ), GetChars( modName ), GetChars( pinName ) );
+ SetCurItem( module );
+ }
+ else
+ {
+ msg.Printf( _( "%s pin %s found" ), GetChars( modName ), GetChars( pinName ) );
+ SetCurItem( pad );
+ }
+
+ SetStatusText( msg );
+ }
+
+ if( module ) // if found, center the module on screen, and redraw the screen.
+ {
+ if( IsGalCanvasActive() )
+ {
+ GetToolManager()->RunAction( COMMON_ACTIONS::crossProbeSchToPcb,
+ true,
+ pad ?
+ static_cast<BOARD_ITEM*>( pad ) :
+ static_cast<BOARD_ITEM*>( module )
+ );
+ }
+ else
+ {
+ SetCrossHairPosition( pos );
+ RedrawScreen( pos, false );
+ }
+ }
+}
+
+
+std::string FormatProbeItem( BOARD_ITEM* aItem )
+{
+ MODULE* module;
+
+ switch( aItem->Type() )
+ {
+ case PCB_MODULE_T:
+ module = (MODULE*) aItem;
+ return StrPrintf( "$PART: \"%s\"", TO_UTF8( module->GetReference() ) );
+
+ case PCB_PAD_T:
+ {
+ module = (MODULE*) aItem->GetParent();
+ wxString pad = ((D_PAD*)aItem)->GetPadName();
+
+ return StrPrintf( "$PART: \"%s\" $PAD: \"%s\"",
+ TO_UTF8( module->GetReference() ),
+ TO_UTF8( pad ) );
+ }
+
+ case PCB_MODULE_TEXT_T:
+ {
+ module = static_cast<MODULE*>( aItem->GetParent() );
+
+ TEXTE_MODULE* text_mod = static_cast<TEXTE_MODULE*>( aItem );
+
+ const char* text_key;
+
+ /* This can't be a switch since the break need to pull out
+ * from the outer switch! */
+ if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE )
+ text_key = "$REF:";
+ else if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_VALUE )
+ text_key = "$VAL:";
+ else
+ break;
+
+ return StrPrintf( "$PART: \"%s\" %s \"%s\"",
+ TO_UTF8( module->GetReference() ),
+ text_key,
+ TO_UTF8( text_mod->GetText() ) );
+ }
+
+ default:
+ break;
+ }
+
+ return "";
+}
+
+
+/* Send a remote command to Eeschema via a socket,
+ * aSyncItem = item to be located on schematic (module, pin or text)
+ * Commands are
+ * $PART: "reference" put cursor on component anchor
+ * $PART: "reference" $PAD: "pad number" put cursor on the component pin
+ * $PART: "reference" $REF: "reference" put cursor on the component ref
+ * $PART: "reference" $VAL: "value" put cursor on the component value
+ */
+void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* aSyncItem )
+{
+#if 1
+ wxASSERT( aSyncItem ); // can't we fix the caller?
+#else
+ if( !aSyncItem )
+ return;
+#endif
+
+ std::string packet = FormatProbeItem( aSyncItem );
+
+ if( packet.size() )
+ {
+ if( Kiface().IsSingle() )
+ SendCommand( MSG_TO_SCH, packet.c_str() );
+ else
+ {
+ // Typically ExpressMail is going to be s-expression packets, but since
+ // we have existing interpreter of the cross probe packet on the other
+ // side in place, we use that here.
+ Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, packet, this );
+ }
+ }
+}
+
+
+void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
+{
+ const std::string& payload = mail.GetPayload();
+
+ switch( mail.Command() )
+ {
+ case MAIL_CROSS_PROBE:
+ ExecuteRemoteCommand( payload.c_str() );
+ break;
+
+ // many many others.
+ default:
+ ;
+ }
+}
+
diff --git a/pcbnew/deltrack.cpp b/pcbnew/deltrack.cpp
new file mode 100644
index 0000000..d766deb
--- /dev/null
+++ b/pcbnew/deltrack.cpp
@@ -0,0 +1,238 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file deltrack.cpp
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <macros.h>
+#include <ratsnest_data.h>
+
+#include <class_board.h>
+#include <class_track.h>
+
+#include <pcbnew.h>
+#include <protos.h>
+
+
+TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack )
+{
+ if( aTrack == NULL )
+ return NULL;
+
+ if( aTrack->IsNew() ) // Trace in progress, erase the last segment
+ {
+ if( g_CurrentTrackList.GetCount() > 0 )
+ {
+ LAYER_ID previous_layer = GetActiveLayer();
+
+ DBG( g_CurrentTrackList.VerifyListIntegrity(); )
+
+ // Delete the current trace
+ ShowNewTrackWhenMovingCursor( m_canvas, DC, wxDefaultPosition, false );
+
+ // delete the most recently entered
+ delete g_CurrentTrackList.PopBack();
+
+ if( g_TwoSegmentTrackBuild )
+ {
+ // if in 2 track mode, and the next most recent is a segment
+ // not a via, and the one previous to that is a via, then
+ // delete up to the via.
+ if( g_CurrentTrackList.GetCount() >= 2
+ && g_CurrentTrackSegment->Type() != PCB_VIA_T
+ && g_CurrentTrackSegment->Back()->Type() == PCB_VIA_T )
+ {
+ delete g_CurrentTrackList.PopBack();
+ }
+ }
+
+ while( g_CurrentTrackSegment && g_CurrentTrackSegment->Type() == PCB_VIA_T )
+ {
+ delete g_CurrentTrackList.PopBack();
+
+ if( g_CurrentTrackSegment && g_CurrentTrackSegment->Type() != PCB_VIA_T )
+ previous_layer = g_CurrentTrackSegment->GetLayer();
+ }
+
+ // Correct active layer which could change if a via
+ // has been erased
+ SetActiveLayer( previous_layer );
+
+ UpdateStatusBar();
+
+ if( g_TwoSegmentTrackBuild ) // We must have 2 segments or more, or 0
+ {
+ if( g_CurrentTrackList.GetCount() == 1
+ && g_CurrentTrackSegment->Type() != PCB_VIA_T )
+ {
+ delete g_CurrentTrackList.PopBack();
+ }
+ }
+
+ if( g_CurrentTrackList.GetCount() == 0 )
+ {
+ m_canvas->SetMouseCapture( NULL, NULL );
+
+ if( GetBoard()->IsHighLightNetON() )
+ HighLight( DC );
+
+ SetCurItem( NULL );
+ return NULL;
+ }
+ else
+ {
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ return g_CurrentTrackSegment;
+ }
+ }
+ return NULL;
+ }
+
+ int netcode = aTrack->GetNetCode();
+
+ // Remove the segment from list, but do not delete it (it will be stored i n undo list)
+ GetBoard()->Remove( aTrack );
+
+ GetBoard()->GetRatsnest()->Remove( aTrack );
+ aTrack->ViewRelease();
+
+ // redraw the area where the track was
+ m_canvas->RefreshDrawingRect( aTrack->GetBoundingBox() );
+
+ SaveCopyInUndoList( aTrack, UR_DELETED );
+ OnModify();
+ TestNetConnection( DC, netcode );
+ SetMsgPanel( GetBoard() );
+
+ return NULL;
+}
+
+
+void PCB_EDIT_FRAME::Delete_Track( wxDC* DC, TRACK* aTrack )
+{
+ if( aTrack != NULL )
+ {
+ int netcode = aTrack->GetNetCode();
+ Remove_One_Track( DC, aTrack );
+ OnModify();
+ TestNetConnection( DC, netcode );
+ }
+}
+
+
+void PCB_EDIT_FRAME::Delete_net( wxDC* DC, TRACK* aTrack )
+{
+ if( aTrack == NULL )
+ return;
+
+ if( !IsOK( this, _( "Delete NET?" ) ) )
+ return;
+
+ PICKED_ITEMS_LIST itemsList;
+ ITEM_PICKER picker( NULL, UR_DELETED );
+ int netcode = aTrack->GetNetCode();
+
+ /* Search the first item for the given net code */
+ TRACK* trackList = GetBoard()->m_Track->GetStartNetCode( netcode );
+
+ /* Remove all segments having the given net code */
+ int ii = 0;
+ TRACK* next_track;
+ for( TRACK* segm = trackList; segm; segm = next_track, ++ii )
+ {
+ next_track = segm->Next();
+ if( segm->GetNetCode() != netcode )
+ break;
+
+ GetBoard()->GetRatsnest()->Remove( segm );
+ segm->ViewRelease();
+ GetBoard()->m_Track.Remove( segm );
+
+ // redraw the area where the track was
+ m_canvas->RefreshDrawingRect( segm->GetBoundingBox() );
+ picker.SetItem( segm );
+ itemsList.PushItem( picker );
+ }
+
+ SaveCopyInUndoList( itemsList, UR_DELETED );
+ OnModify();
+ TestNetConnection( DC, netcode );
+ SetMsgPanel( GetBoard() );
+}
+
+
+void PCB_EDIT_FRAME::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
+{
+ int segments_to_delete_count;
+
+ if( pt_segm == NULL )
+ return;
+
+ TRACK* trackList = GetBoard()->MarkTrace( pt_segm, &segments_to_delete_count,
+ NULL, NULL, true );
+
+ if( segments_to_delete_count == 0 )
+ return;
+
+ int net_code = pt_segm->GetNetCode();
+ PICKED_ITEMS_LIST itemsList;
+ ITEM_PICKER picker( NULL, UR_DELETED );
+
+ int ii = 0;
+ TRACK* tracksegment = trackList;
+ TRACK* next_track;
+
+ for( ; ii < segments_to_delete_count; ii++, tracksegment = next_track )
+ {
+ next_track = tracksegment->Next();
+ tracksegment->SetState( BUSY, false );
+
+ DBG( std::cout << __func__ << ": track " << tracksegment << " status=" \
+ << TO_UTF8( TRACK::ShowState( tracksegment->GetStatus() ) ) \
+ << std::endl; )
+
+ GetBoard()->GetRatsnest()->Remove( tracksegment );
+ tracksegment->ViewRelease();
+ GetBoard()->m_Track.Remove( tracksegment );
+
+ // redraw the area where the track was
+ m_canvas->RefreshDrawingRect( tracksegment->GetBoundingBox() );
+ picker.SetItem( tracksegment );
+ itemsList.PushItem( picker );
+ }
+
+ SaveCopyInUndoList( itemsList, UR_DELETED );
+
+ if( net_code > 0 )
+ TestNetConnection( DC, net_code );
+}
diff --git a/pcbnew/dialogs/dialog_SVG_print.cpp b/pcbnew/dialogs/dialog_SVG_print.cpp
new file mode 100644
index 0000000..1fbe7d0
--- /dev/null
+++ b/pcbnew/dialogs/dialog_SVG_print.cpp
@@ -0,0 +1,447 @@
+/**
+ * @file pcbnew/dialogs/dialog_SVG_print.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <wxBasePcbFrame.h>
+#include <class_pcb_screen.h>
+#include <base_units.h>
+#include <convert_from_iu.h>
+#include <wildcards_and_files_ext.h>
+#include <macros.h>
+#include <reporter.h>
+#include <confirm.h>
+
+#include <pcbnew.h>
+#include <pcbplot.h>
+#include <printout_controler.h>
+#include <class_board.h>
+#include <dialog_SVG_print_base.h>
+#include <invoke_pcb_dialog.h>
+#include <wx_html_report_panel.h>
+
+
+class DIALOG_SVG_PRINT : public DIALOG_SVG_PRINT_base
+{
+public:
+ DIALOG_SVG_PRINT( wxTopLevelWindow* aParent, BOARD* aBoard, PCB_PLOT_PARAMS* aSettings );
+
+private:
+ bool m_did_print;
+ BOARD* m_board;
+ PCB_PLOT_PARAMS* m_callers_params;
+ wxConfigBase* m_config;
+ LSET m_printMaskLayer;
+ wxCheckBox* m_boxSelectLayer[LAYER_ID_COUNT];
+ bool m_printBW;
+ wxString m_outputDirectory;
+ bool m_printMirror;
+ bool m_oneFileOnly;
+
+ void initDialog();
+
+ void OnCloseWindow( wxCloseEvent& event );
+ void OnButtonPlot( wxCommandEvent& event );
+
+ void OnButtonCloseClick( wxCommandEvent& event );
+
+ void OnOutputDirectoryBrowseClicked( wxCommandEvent& event );
+ void SetPenWidth();
+ void ExportSVGFile( bool aOnlyOneFile );
+
+ bool PageIsBoardBoundarySize()
+ {
+ return m_rbSvgPageSizeOpt->GetSelection() == 2;
+ }
+
+ bool PrintPageRef()
+ {
+ return m_rbSvgPageSizeOpt->GetSelection() == 0;
+ }
+
+ bool CreateSVGFile( const wxString& FullFileName, bool aOnlyOneFile );
+
+ LSET getCheckBoxSelectedLayers() const;
+};
+
+
+
+// Keys for configuration
+#define PLOTSVGMODECOLOR_KEY wxT( "PlotSVGModeColor" )
+#define PLOTSVGMODEMIRROR_KEY wxT( "PlotSVGModeMirror" )
+#define PLOTSVGMODEONEFILE_KEY wxT( "PlotSVGModeOneFile" )
+#define PLOTSVGPAGESIZEOPT_KEY wxT( "PlotSVGPageOpt" )
+#define PLOTSVGPLOT_BRD_EDGE_KEY wxT( "PlotSVGBrdEdge" )
+
+// reasonable values for default pen width
+#define WIDTH_MAX_VALUE (2 * IU_PER_MM)
+#define WIDTH_MIN_VALUE (0.05 * IU_PER_MM)
+
+// Local variables:
+static LSET s_SelectedLayers( 4, B_Cu, F_Cu, F_SilkS, B_SilkS );
+
+/*
+ * DIALOG_SVG_PRINT functions
+ */
+DIALOG_SVG_PRINT::DIALOG_SVG_PRINT( wxTopLevelWindow* aParent, BOARD* aBoard, PCB_PLOT_PARAMS* aSettings ) :
+ DIALOG_SVG_PRINT_base( aParent ),
+ m_did_print( false ),
+ m_callers_params( aSettings )
+{
+ m_board = aBoard;
+ m_config = Kiface().KifaceSettings();
+
+ memset( m_boxSelectLayer, 0, sizeof( m_boxSelectLayer ) );
+
+ initDialog();
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+
+void DIALOG_SVG_PRINT::initDialog()
+{
+ if( m_config )
+ {
+ m_config->Read( PLOTSVGMODECOLOR_KEY, &m_printBW, false );
+ long ltmp;
+ m_config->Read( PLOTSVGPAGESIZEOPT_KEY, &ltmp, 0 );
+ m_config->Read( PLOTSVGMODEMIRROR_KEY, &m_printMirror, false );
+ m_config->Read( PLOTSVGMODEONEFILE_KEY, &m_oneFileOnly, false);
+ m_rbSvgPageSizeOpt->SetSelection( ltmp );
+ m_config->Read( PLOTSVGPLOT_BRD_EDGE_KEY, &ltmp, 1 );
+ m_PrintBoardEdgesCtrl->SetValue( ltmp );
+ }
+
+ m_outputDirectory = m_callers_params->GetOutputDirectory();
+ m_outputDirectoryName->SetValue( m_outputDirectory );
+
+ m_ModeColorOption->SetSelection( m_printBW ? 1 : 0 );
+ m_printMirrorOpt->SetValue( m_printMirror );
+ m_rbFileOpt->SetSelection( m_oneFileOnly ? 1 : 0 );
+
+ AddUnitSymbol( *m_TextPenWidth, g_UserUnit );
+
+ m_DialogDefaultPenSize->SetValue( StringFromValue( g_UserUnit, g_DrawDefaultLineThickness ) );
+
+ LSEQ seq = m_board->GetEnabledLayers().UIOrder();
+
+ for( ; seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ // The layers in m_boxSelectLayer[] are in LAYER_ID order. This may be
+ // different than the order on screen.
+ m_boxSelectLayer[layer] = new wxCheckBox( this, -1, m_board->GetLayerName( layer ) );
+
+ if( s_SelectedLayers[layer] )
+ m_boxSelectLayer[layer]->SetValue( true );
+
+ if( IsCopperLayer( layer ) )
+ m_CopperLayersBoxSizer->Add( m_boxSelectLayer[layer], 0, wxGROW | wxALL, 1 );
+ else
+ m_TechnicalBoxSizer->Add( m_boxSelectLayer[layer], 0, wxGROW | wxALL, 1 );
+ }
+
+ if( m_config )
+ {
+ wxString layerKey;
+
+ for( seq.Rewind(); seq; ++seq )
+ {
+ bool option;
+
+ LAYER_NUM layer = *seq;
+
+ layerKey.Printf( OPTKEY_LAYERBASE, layer );
+
+ if( m_config->Read( layerKey, &option ) )
+ m_boxSelectLayer[layer]->SetValue( option );
+ }
+ }
+}
+
+
+LSET DIALOG_SVG_PRINT::getCheckBoxSelectedLayers() const
+{
+ LSET ret;
+
+ // the layers in m_boxSelectLayer[] are in LAYER_ID order.
+ for( unsigned layer=0; layer<DIM(m_boxSelectLayer); ++layer )
+ {
+ if( m_boxSelectLayer[layer] && m_boxSelectLayer[layer]->GetValue() )
+ ret.set( layer );
+ }
+
+ return ret;
+}
+
+
+void DIALOG_SVG_PRINT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
+{
+ // Build the absolute path of current output plot directory
+ // to preselect it when opening the dialog.
+ wxFileName fn( m_outputDirectoryName->GetValue() );
+ wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() );
+
+ wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
+
+ if( dirDialog.ShowModal() == wxID_CANCEL )
+ return;
+
+ wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
+
+ wxMessageDialog dialog( this, _( "Use a relative path? " ),
+ _( "Plot Output Directory" ),
+ wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
+
+ if( dialog.ShowModal() == wxID_YES )
+ {
+ wxString boardFilePath = Prj().AbsolutePath( m_board->GetFileName() );
+
+ boardFilePath = wxPathOnly( boardFilePath );
+
+ if( !dirName.MakeRelativeTo( boardFilePath ) )
+ wxMessageBox( _( "Cannot make path relative (target volume different from board file volume)!" ),
+ _( "Plot Output Directory" ), wxOK | wxICON_ERROR );
+ }
+
+ m_outputDirectoryName->SetValue( dirName.GetFullPath() );
+ m_outputDirectory = m_outputDirectoryName->GetValue();
+}
+
+
+void DIALOG_SVG_PRINT::SetPenWidth()
+{
+ int pensize = ValueFromTextCtrl( *m_DialogDefaultPenSize );
+
+ if( pensize > WIDTH_MAX_VALUE )
+ {
+ pensize = WIDTH_MAX_VALUE;
+ }
+
+ if( pensize < WIDTH_MIN_VALUE )
+ {
+ pensize = WIDTH_MIN_VALUE;
+ }
+
+ g_DrawDefaultLineThickness = pensize;
+ m_DialogDefaultPenSize->SetValue( StringFromValue( g_UserUnit, pensize ) );
+}
+
+
+void DIALOG_SVG_PRINT::ExportSVGFile( bool aOnlyOneFile )
+{
+ m_outputDirectory = m_outputDirectoryName->GetValue();
+
+ // Create output directory if it does not exist (also transform it in
+ // absolute form). Bail if it fails
+ wxFileName outputDir = wxFileName::DirName( m_outputDirectory );
+ wxString boardFilename = m_board->GetFileName();
+
+ REPORTER& reporter = m_messagesPanel->Reporter();
+
+ if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) )
+ {
+ wxString msg = wxString::Format(
+ _( "Could not write plot files to folder '%s'." ),
+ GetChars( outputDir.GetPath() )
+ );
+ DisplayError( this, msg );
+ return;
+ }
+
+ m_printMirror = m_printMirrorOpt->GetValue();
+ m_printBW = m_ModeColorOption->GetSelection();
+ SetPenWidth();
+
+ LSET all_selected = getCheckBoxSelectedLayers();
+
+ for( LSEQ seq = all_selected.Seq(); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ wxFileName fn( boardFilename );
+
+ wxString suffix = aOnlyOneFile ? wxT( "brd" ) : m_board->GetStandardLayerName( layer );
+
+ BuildPlotFileName( &fn, outputDir.GetPath(), suffix, SVGFileExtension );
+
+ m_printMaskLayer = aOnlyOneFile ? all_selected : LSET( layer );
+
+ if( m_PrintBoardEdgesCtrl->IsChecked() )
+ m_printMaskLayer.set( Edge_Cuts );
+
+ if( CreateSVGFile( fn.GetFullPath(), aOnlyOneFile ) )
+ {
+ reporter.Report (
+ wxString::Format( _( "Plot: '%s' OK." ), GetChars( fn.GetFullPath() ) ),
+ REPORTER::RPT_ACTION );
+ }
+ else // Error
+ {
+ reporter.Report (
+ wxString::Format( _( "Unable to create file '%s'." ), GetChars( fn.GetFullPath() ) ),
+ REPORTER::RPT_ERROR );
+ }
+
+ if( aOnlyOneFile )
+ break;
+ }
+}
+
+
+// Actual SVG file export function.
+bool DIALOG_SVG_PRINT::CreateSVGFile( const wxString& aFullFileName, bool aOnlyOneFile )
+{
+ PCB_PLOT_PARAMS plot_opts;
+
+ plot_opts.SetPlotFrameRef( PrintPageRef() );
+
+ // Adding drill marks, for copper layers
+ if( ( m_printMaskLayer & LSET::AllCuMask() ).any() )
+ plot_opts.SetDrillMarksType( PCB_PLOT_PARAMS::FULL_DRILL_SHAPE );
+ else
+ plot_opts.SetDrillMarksType( PCB_PLOT_PARAMS::NO_DRILL_SHAPE );
+
+ plot_opts.SetSkipPlotNPTH_Pads( false );
+
+ plot_opts.SetMirror( m_printMirror );
+ plot_opts.SetFormat( PLOT_FORMAT_SVG );
+
+ PAGE_INFO pageInfo = m_board->GetPageSettings();
+ wxPoint axisorigin = m_board->GetAuxOrigin();
+
+ if( PageIsBoardBoundarySize() )
+ {
+ EDA_RECT bbox = m_board->ComputeBoundingBox();
+ PAGE_INFO currpageInfo = m_board->GetPageSettings();
+
+ currpageInfo.SetWidthMils( bbox.GetWidth() / IU_PER_MILS );
+ currpageInfo.SetHeightMils( bbox.GetHeight() / IU_PER_MILS );
+ m_board->SetPageSettings( currpageInfo );
+ plot_opts.SetUseAuxOrigin( true );
+ wxPoint origin = bbox.GetOrigin();
+ m_board->SetAuxOrigin( origin );
+ }
+
+ LOCALE_IO toggle;
+
+ SVG_PLOTTER* plotter = (SVG_PLOTTER*) StartPlotBoard( m_board,
+ &plot_opts, UNDEFINED_LAYER, aFullFileName, wxEmptyString );
+
+ if( plotter )
+ {
+ plotter->SetColorMode( !m_printBW );
+ if( aOnlyOneFile )
+ {
+ for( LSEQ seq = m_printMaskLayer.SeqStackupBottom2Top(); seq; ++seq )
+ PlotOneBoardLayer( m_board, plotter, *seq, plot_opts );
+ }
+ else
+ {
+ PlotStandardLayer( m_board, plotter, m_printMaskLayer, plot_opts );
+ }
+ plotter->EndPlot();
+ }
+
+ delete plotter;
+
+ m_board->SetAuxOrigin( axisorigin ); // reset to the values saved earlier
+ m_board->SetPageSettings( pageInfo );
+
+ return true;
+}
+
+
+void DIALOG_SVG_PRINT::OnButtonPlot( wxCommandEvent& event )
+{
+ m_oneFileOnly = m_rbFileOpt->GetSelection() == 1;
+ ExportSVGFile( m_oneFileOnly );
+
+ m_did_print = true;
+}
+
+
+void DIALOG_SVG_PRINT::OnButtonCloseClick( wxCommandEvent& event )
+{
+ Close();
+}
+
+
+void DIALOG_SVG_PRINT::OnCloseWindow( wxCloseEvent& event )
+{
+ if( m_did_print ) // unless output was created, this is tantamount to a cancel.
+ {
+ SetPenWidth();
+ m_printBW = m_ModeColorOption->GetSelection();
+ m_oneFileOnly = m_rbFileOpt->GetSelection() == 1;
+
+ // Why are SVG layer choices co-mingled with other plot layer choices in the config file?
+ // The string OPTKEY_LAYERBASE is used in multiple places.
+ // fix this.
+
+ wxString dirStr = m_outputDirectoryName->GetValue();
+ dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
+
+ m_callers_params->SetOutputDirectory( dirStr );
+
+ if( m_config )
+ {
+ m_config->Write( PLOTSVGMODECOLOR_KEY, m_printBW );
+ m_config->Write( PLOTSVGMODEMIRROR_KEY, m_printMirror );
+ m_config->Write( PLOTSVGMODEONEFILE_KEY, m_oneFileOnly );
+ m_config->Write( PLOTSVGPAGESIZEOPT_KEY, m_rbSvgPageSizeOpt->GetSelection() );
+ m_config->Write( PLOTSVGPLOT_BRD_EDGE_KEY, m_PrintBoardEdgesCtrl->GetValue() );
+
+ wxString layerKey;
+
+ for( unsigned layer = 0; layer < DIM(m_boxSelectLayer); ++layer )
+ {
+ if( !m_boxSelectLayer[layer] )
+ continue;
+
+ layerKey.Printf( OPTKEY_LAYERBASE, layer );
+ m_config->Write( layerKey, m_boxSelectLayer[layer]->IsChecked() );
+ }
+ }
+ }
+
+ EndModal( m_did_print ? wxID_OK : wxID_CANCEL );
+}
+
+
+bool InvokeSVGPrint( wxTopLevelWindow* aCaller, BOARD* aBoard, PCB_PLOT_PARAMS* aSettings )
+{
+ DIALOG_SVG_PRINT dlg( aCaller, aBoard, aSettings );
+
+ return dlg.ShowModal() == wxID_OK;
+}
diff --git a/pcbnew/dialogs/dialog_SVG_print_base.cpp b/pcbnew/dialogs/dialog_SVG_print_base.cpp
new file mode 100644
index 0000000..cdde663
--- /dev/null
+++ b/pcbnew/dialogs/dialog_SVG_print_base.cpp
@@ -0,0 +1,152 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 6 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "wx_html_report_panel.h"
+
+#include "dialog_SVG_print_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_SVG_PRINT_base::DIALOG_SVG_PRINT_base( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,350 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextDir = new wxStaticText( this, wxID_ANY, _("Output directory:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextDir->Wrap( -1 );
+ bMainSizer->Add( m_staticTextDir, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_outputDirectoryName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_outputDirectoryName->SetMaxLength( 0 );
+ m_outputDirectoryName->SetToolTip( _("Enter a filename if you do not want to use default file names\nCan be used only when printing the current sheet") );
+ m_outputDirectoryName->SetMinSize( wxSize( 450,-1 ) );
+
+ bSizer4->Add( m_outputDirectoryName, 1, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_browseButton = new wxButton( this, wxID_ANY, _("Browse..."), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer4->Add( m_browseButton, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bMainSizer->Add( bSizer4, 0, wxEXPAND|wxBOTTOM, 5 );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sbLayersSizer;
+ sbLayersSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Layers:") ), wxHORIZONTAL );
+
+ m_CopperLayersBoxSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Copper Layers:") ), wxVERTICAL );
+
+
+ sbLayersSizer->Add( m_CopperLayersBoxSizer, 1, wxEXPAND, 5 );
+
+ m_TechnicalBoxSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Technical Layers:") ), wxVERTICAL );
+
+
+ sbLayersSizer->Add( m_TechnicalBoxSizer, 1, wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( sbLayersSizer, 1, wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbOptionsSizer;
+ sbOptionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Print SVG options:") ), wxVERTICAL );
+
+ m_TextPenWidth = new wxStaticText( this, wxID_ANY, _("Default pen size"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextPenWidth->Wrap( -1 );
+ m_TextPenWidth->SetToolTip( _("Selection of the pen size used to draw items which have no pen size specified.") );
+
+ sbOptionsSizer->Add( m_TextPenWidth, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_DialogDefaultPenSize = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_DialogDefaultPenSize->SetMaxLength( 0 );
+ sbOptionsSizer->Add( m_DialogDefaultPenSize, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ wxString m_ModeColorOptionChoices[] = { _("Color"), _("Black and white") };
+ int m_ModeColorOptionNChoices = sizeof( m_ModeColorOptionChoices ) / sizeof( wxString );
+ m_ModeColorOption = new wxRadioBox( this, wxID_ANY, _("Print mode"), wxDefaultPosition, wxDefaultSize, m_ModeColorOptionNChoices, m_ModeColorOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_ModeColorOption->SetSelection( 1 );
+ m_ModeColorOption->SetToolTip( _("Choose if you want to draw the sheet like it appears on screen,\nor in black and white mode, better to print it when using black and white printers") );
+
+ sbOptionsSizer->Add( m_ModeColorOption, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_rbSvgPageSizeOptChoices[] = { _("Full page with frame ref"), _("Current page size"), _("Board area only") };
+ int m_rbSvgPageSizeOptNChoices = sizeof( m_rbSvgPageSizeOptChoices ) / sizeof( wxString );
+ m_rbSvgPageSizeOpt = new wxRadioBox( this, wxID_ANY, _("SVG Page Size"), wxDefaultPosition, wxDefaultSize, m_rbSvgPageSizeOptNChoices, m_rbSvgPageSizeOptChoices, 1, wxRA_SPECIFY_COLS );
+ m_rbSvgPageSizeOpt->SetSelection( 0 );
+ sbOptionsSizer->Add( m_rbSvgPageSizeOpt, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_PrintBoardEdgesCtrl = new wxCheckBox( this, wxID_ANY, _("Print board edges"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PrintBoardEdgesCtrl->SetValue(true);
+ m_PrintBoardEdgesCtrl->SetToolTip( _("Print (or not) the edges layer on others layers") );
+
+ sbOptionsSizer->Add( m_PrintBoardEdgesCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_printMirrorOpt = new wxCheckBox( this, wxID_ANY, _("Print mirrored"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_printMirrorOpt->SetToolTip( _("Print the layer(s) horizontally mirrored") );
+
+ sbOptionsSizer->Add( m_printMirrorOpt, 0, wxRIGHT|wxLEFT, 5 );
+
+
+ bUpperSizer->Add( sbOptionsSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bButtonsSizer;
+ bButtonsSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_rbFileOptChoices[] = { _("One file per layer"), _("All in one file") };
+ int m_rbFileOptNChoices = sizeof( m_rbFileOptChoices ) / sizeof( wxString );
+ m_rbFileOpt = new wxRadioBox( this, wxID_ANY, _("File option:"), wxDefaultPosition, wxDefaultSize, m_rbFileOptNChoices, m_rbFileOptChoices, 1, wxRA_SPECIFY_COLS );
+ m_rbFileOpt->SetSelection( 0 );
+ bButtonsSizer->Add( m_rbFileOpt, 0, wxALL, 5 );
+
+ m_buttonCreateFile = new wxButton( this, wxID_PRINT_BOARD, _("Plot"), wxDefaultPosition, wxDefaultSize, 0 );
+ bButtonsSizer->Add( m_buttonCreateFile, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonQuit = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ bButtonsSizer->Add( m_buttonQuit, 0, wxALL|wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( bButtonsSizer, 0, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bUpperSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer5;
+ bSizer5 = new wxBoxSizer( wxVERTICAL );
+
+ m_messagesPanel = new WX_HTML_REPORT_PANEL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_messagesPanel->SetMinSize( wxSize( 300,150 ) );
+
+ bSizer5->Add( m_messagesPanel, 1, wxEXPAND | wxALL, 5 );
+
+
+ bMainSizer->Add( bSizer5, 1, wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_SVG_PRINT_base::OnCloseWindow ) );
+ m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SVG_PRINT_base::OnOutputDirectoryBrowseClicked ), NULL, this );
+ m_buttonCreateFile->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SVG_PRINT_base::OnButtonPlot ), NULL, this );
+ m_buttonQuit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SVG_PRINT_base::OnButtonCloseClick ), NULL, this );
+}
+
+DIALOG_SVG_PRINT_base::~DIALOG_SVG_PRINT_base()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_SVG_PRINT_base::OnCloseWindow ) );
+ m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SVG_PRINT_base::OnOutputDirectoryBrowseClicked ), NULL, this );
+ m_buttonCreateFile->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SVG_PRINT_base::OnButtonPlot ), NULL, this );
+ m_buttonQuit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SVG_PRINT_base::OnButtonCloseClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_SVG_print_base.fbp b/pcbnew/dialogs/dialog_SVG_print_base.fbp
new file mode 100644
index 0000000..852ecb9
--- /dev/null
+++ b/pcbnew/dialogs/dialog_SVG_print_base.fbp
@@ -0,0 +1,1337 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_SVG_print_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DialogSVGPrint_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,350</property>
+ <property name="name">DIALOG_SVG_PRINT_base</property>
+ <property name="pos"></property>
+ <property name="size">507,451</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Export SVG file</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseWindow</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Output directory:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextDir</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer4</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">450,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_outputDirectoryName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enter a filename if you do not want to use default file names&#x0A;Can be used only when printing the current sheet</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Browse...</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_browseButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnOutputDirectoryBrowseClicked</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layers:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbLayersSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Copper Layers:</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_CopperLayersBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Technical Layers:</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_TechnicalBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Print SVG options:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbOptionsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default pen size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextPenWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Selection of the pen size used to draw items which have no pen size specified.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DialogDefaultPenSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Color&quot; &quot;Black and white&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Print mode</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ModeColorOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Choose if you want to draw the sheet like it appears on screen,&#x0A;or in black and white mode, better to print it when using black and white printers</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Full page with frame ref&quot; &quot;Current page size&quot; &quot;Board area only&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">SVG Page Size</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbSvgPageSizeOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Print board edges</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PrintBoardEdgesCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Print (or not) the edges layer on others layers</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Print mirrored</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_printMirrorOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Print the layer(s) horizontally mirrored</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bButtonsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;One file per layer&quot; &quot;All in one file&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">File option:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbFileOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PRINT_BOARD</property>
+ <property name="label">Plot</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonCreateFile</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonPlot</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonQuit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonCloseClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer5</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">300,150</property>
+ <property name="moveable">1</property>
+ <property name="name">m_messagesPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass">WX_HTML_REPORT_PANEL; wx_html_report_panel.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_SVG_print_base.h b/pcbnew/dialogs/dialog_SVG_print_base.h
new file mode 100644
index 0000000..a47a04d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_SVG_print_base.h
@@ -0,0 +1,78 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 6 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_SVG_PRINT_BASE_H__
+#define __DIALOG_SVG_PRINT_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class WX_HTML_REPORT_PANEL;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/radiobox.h>
+#include <wx/checkbox.h>
+#include <wx/panel.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_SVG_PRINT_base
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_SVG_PRINT_base : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ wxID_PRINT_BOARD = 1000
+ };
+
+ wxStaticText* m_staticTextDir;
+ wxTextCtrl* m_outputDirectoryName;
+ wxButton* m_browseButton;
+ wxStaticBoxSizer* m_CopperLayersBoxSizer;
+ wxStaticBoxSizer* m_TechnicalBoxSizer;
+ wxStaticText* m_TextPenWidth;
+ wxTextCtrl* m_DialogDefaultPenSize;
+ wxRadioBox* m_ModeColorOption;
+ wxRadioBox* m_rbSvgPageSizeOpt;
+ wxCheckBox* m_PrintBoardEdgesCtrl;
+ wxCheckBox* m_printMirrorOpt;
+ wxRadioBox* m_rbFileOpt;
+ wxButton* m_buttonCreateFile;
+ wxButton* m_buttonQuit;
+ WX_HTML_REPORT_PANEL* m_messagesPanel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonPlot( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonCloseClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_SVG_PRINT_base( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Export SVG file"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 507,451 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_SVG_PRINT_base();
+
+};
+
+#endif //__DIALOG_SVG_PRINT_BASE_H__
diff --git a/pcbnew/dialogs/dialog_block_options_base.cpp b/pcbnew/dialogs/dialog_block_options_base.cpp
new file mode 100644
index 0000000..9299bef
--- /dev/null
+++ b/pcbnew/dialogs/dialog_block_options_base.cpp
@@ -0,0 +1,106 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 13 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_block_options_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_BLOCK_OPTIONS_BASE::DIALOG_BLOCK_OPTIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbSizer1;
+ sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options") ), wxVERTICAL );
+
+ wxGridSizer* gSizer1;
+ gSizer1 = new wxGridSizer( 4, 2, 0, 0 );
+
+ m_Include_Modules = new wxCheckBox( this, wxID_ANY, _("Include &footprints"), wxDefaultPosition, wxDefaultSize, 0 );
+ gSizer1->Add( m_Include_Modules, 0, wxALL, 5 );
+
+ m_Include_PcbTextes = new wxCheckBox( this, wxID_ANY, _("Include t&ext items"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Include_PcbTextes->SetValue(true);
+ gSizer1->Add( m_Include_PcbTextes, 0, wxALL, 5 );
+
+ m_IncludeLockedModules = new wxCheckBox( this, wxID_ANY, _("Include &locked footprints"), wxDefaultPosition, wxDefaultSize, 0 );
+ gSizer1->Add( m_IncludeLockedModules, 0, wxALL, 5 );
+
+ m_Include_Draw_Items = new wxCheckBox( this, wxID_ANY, _("Include &drawings"), wxDefaultPosition, wxDefaultSize, 0 );
+ gSizer1->Add( m_Include_Draw_Items, 0, wxALL, 5 );
+
+ m_Include_Tracks = new wxCheckBox( this, wxID_ANY, _("Include &tracks"), wxDefaultPosition, wxDefaultSize, 0 );
+ gSizer1->Add( m_Include_Tracks, 0, wxALL, 5 );
+
+ m_Include_Edges_Items = new wxCheckBox( this, wxID_ANY, _("Include &board outline layer"), wxDefaultPosition, wxDefaultSize, 0 );
+ gSizer1->Add( m_Include_Edges_Items, 0, wxALL, 5 );
+
+ m_Include_Zones = new wxCheckBox( this, wxID_ANY, _("Include &zones"), wxDefaultPosition, wxDefaultSize, 0 );
+ gSizer1->Add( m_Include_Zones, 0, wxALL, 5 );
+
+ m_DrawBlockItems = new wxCheckBox( this, wxID_ANY, _("Draw &selected items while moving"), wxDefaultPosition, wxDefaultSize, 0 );
+ gSizer1->Add( m_DrawBlockItems, 0, wxALL, 5 );
+
+
+ sbSizer1->Add( gSizer1, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ sbSizer1->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_checkBoxIncludeInvisible = new wxCheckBox( this, wxID_ANY, _("Include &items on invisible layers"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizer1->Add( m_checkBoxIncludeInvisible, 0, wxALL, 5 );
+
+
+ bSizerMain->Add( sbSizer1, 1, wxALL|wxEXPAND, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bSizerMain->Add( m_sdbSizer1, 0, wxALIGN_RIGHT|wxALL, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_Include_Modules->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_Include_PcbTextes->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_IncludeLockedModules->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_Include_Draw_Items->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_Include_Tracks->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_Include_Edges_Items->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_Include_Zones->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_DrawBlockItems->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_checkBoxIncludeInvisible->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::OnCancel ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::ExecuteCommand ), NULL, this );
+}
+
+DIALOG_BLOCK_OPTIONS_BASE::~DIALOG_BLOCK_OPTIONS_BASE()
+{
+ // Disconnect Events
+ m_Include_Modules->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_Include_PcbTextes->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_IncludeLockedModules->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_Include_Draw_Items->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_Include_Tracks->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_Include_Edges_Items->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_Include_Zones->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_DrawBlockItems->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_checkBoxIncludeInvisible->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::checkBoxClicked ), NULL, this );
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::OnCancel ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_BLOCK_OPTIONS_BASE::ExecuteCommand ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_block_options_base.fbp b/pcbnew/dialogs/dialog_block_options_base.fbp
new file mode 100644
index 0000000..41c422d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_block_options_base.fbp
@@ -0,0 +1,1026 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_block_options_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_block_options_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_BLOCK_OPTIONS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">500,226</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Options</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizer1</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGridSizer" expanded="0">
+ <property name="cols">2</property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">gSizer1</property>
+ <property name="permission">none</property>
+ <property name="rows">4</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Include &amp;footprints</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Include_Modules</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">checkBoxClicked</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Include t&amp;ext items</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Include_PcbTextes</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">checkBoxClicked</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Include &amp;locked footprints</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_IncludeLockedModules</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">checkBoxClicked</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Include &amp;drawings</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Include_Draw_Items</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">checkBoxClicked</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Include &amp;tracks</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Include_Tracks</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">checkBoxClicked</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Include &amp;board outline layer</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Include_Edges_Items</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">checkBoxClicked</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Include &amp;zones</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Include_Zones</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">checkBoxClicked</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Draw &amp;selected items while moving</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DrawBlockItems</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">checkBoxClicked</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Include &amp;items on invisible layers</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkBoxIncludeInvisible</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">checkBoxClicked</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancel</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">ExecuteCommand</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_block_options_base.h b/pcbnew/dialogs/dialog_block_options_base.h
new file mode 100644
index 0000000..173dbda
--- /dev/null
+++ b/pcbnew/dialogs/dialog_block_options_base.h
@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 13 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_BLOCK_OPTIONS_BASE_H__
+#define __DIALOG_BLOCK_OPTIONS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/checkbox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/statbox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_BLOCK_OPTIONS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_BLOCK_OPTIONS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxCheckBox* m_Include_Modules;
+ wxCheckBox* m_Include_PcbTextes;
+ wxCheckBox* m_IncludeLockedModules;
+ wxCheckBox* m_Include_Draw_Items;
+ wxCheckBox* m_Include_Tracks;
+ wxCheckBox* m_Include_Edges_Items;
+ wxCheckBox* m_Include_Zones;
+ wxCheckBox* m_DrawBlockItems;
+ wxStaticLine* m_staticline1;
+ wxCheckBox* m_checkBoxIncludeInvisible;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void checkBoxClicked( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); }
+ virtual void ExecuteCommand( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_BLOCK_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,226 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_BLOCK_OPTIONS_BASE();
+
+};
+
+#endif //__DIALOG_BLOCK_OPTIONS_BASE_H__
diff --git a/pcbnew/dialogs/dialog_cleaning_options.cpp b/pcbnew/dialogs/dialog_cleaning_options.cpp
new file mode 100644
index 0000000..ea4ec22
--- /dev/null
+++ b/pcbnew/dialogs/dialog_cleaning_options.cpp
@@ -0,0 +1,48 @@
+/**
+ * @file dialog_cleaning_options.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include <wx/wx.h>
+
+#include <dialog_cleaning_options.h>
+
+
+DIALOG_CLEANING_OPTIONS::DIALOG_CLEANING_OPTIONS( wxWindow* parent ):
+ DIALOG_CLEANING_OPTIONS_BASE( parent )
+{
+ m_cleanViasOpt->SetValue( m_cleanVias );
+ m_mergeSegmOpt->SetValue( m_mergeSegments );
+ m_deleteUnconnectedOpt->SetValue( m_deleteUnconnectedSegm );
+
+ m_sdbSizerOK->SetDefault();
+ GetSizer()->SetSizeHints(this);
+ Centre();
+}
+
+// Static members of DIALOG_CLEANING_OPTIONS
+bool DIALOG_CLEANING_OPTIONS::m_cleanVias = true;
+bool DIALOG_CLEANING_OPTIONS::m_mergeSegments = true;
+bool DIALOG_CLEANING_OPTIONS::m_deleteUnconnectedSegm = true;
+
diff --git a/pcbnew/dialogs/dialog_cleaning_options.h b/pcbnew/dialogs/dialog_cleaning_options.h
new file mode 100644
index 0000000..0aaef4d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_cleaning_options.h
@@ -0,0 +1,65 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef DIALOG_CLEANING_OPTIONS_H_
+#define DIALOG_CLEANING_OPTIONS_H_
+
+#include <dialog_cleaning_options_base.h>
+
+class DIALOG_CLEANING_OPTIONS: public DIALOG_CLEANING_OPTIONS_BASE
+{
+public:
+ static bool m_cleanVias;
+ static bool m_mergeSegments;
+ static bool m_deleteUnconnectedSegm;
+
+public:
+ DIALOG_CLEANING_OPTIONS( wxWindow* parent );
+
+ ~DIALOG_CLEANING_OPTIONS()
+ {
+ GetOpts( );
+ }
+
+private:
+ void OnCancelClick( wxCommandEvent& event )
+ {
+ EndModal( wxID_CANCEL );
+ }
+ void OnOKClick( wxCommandEvent& event )
+ {
+ GetOpts( );
+ EndModal( wxID_OK );
+ }
+
+ void GetOpts( )
+ {
+ m_cleanVias = m_cleanViasOpt->GetValue( );
+ m_mergeSegments = m_mergeSegmOpt->GetValue( );
+ m_deleteUnconnectedSegm = m_deleteUnconnectedOpt->GetValue( );
+ }
+};
+
+#endif
+ // DIALOG_CLEANING_OPTIONS_H_
diff --git a/pcbnew/dialogs/dialog_cleaning_options_base.cpp b/pcbnew/dialogs/dialog_cleaning_options_base.cpp
new file mode 100644
index 0000000..527d6d9
--- /dev/null
+++ b/pcbnew/dialogs/dialog_cleaning_options_base.cpp
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 13 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_cleaning_options_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_CLEANING_OPTIONS_BASE::DIALOG_CLEANING_OPTIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxVERTICAL );
+
+ m_cleanViasOpt = new wxCheckBox( this, wxID_ANY, _("&Delete redundant vias"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_cleanViasOpt->SetToolTip( _("remove vias on pads with a through hole") );
+
+ bSizerUpper->Add( m_cleanViasOpt, 0, wxALL, 5 );
+
+ m_mergeSegmOpt = new wxCheckBox( this, wxID_ANY, _("&Merge overlapping segments"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_mergeSegmOpt->SetToolTip( _("merge aligned track segments, and remove null segments") );
+
+ bSizerUpper->Add( m_mergeSegmOpt, 0, wxALL, 5 );
+
+ m_deleteUnconnectedOpt = new wxCheckBox( this, wxID_ANY, _("D&elete unconnected tracks"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_deleteUnconnectedOpt->SetToolTip( _("delete track segment having a dangling end") );
+
+ bSizerUpper->Add( m_deleteUnconnectedOpt, 0, wxALL, 5 );
+
+
+ bSizerMain->Add( bSizerUpper, 1, wxEXPAND|wxALL, 5 );
+
+ m_staticline = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerMain->Add( m_staticline, 0, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bSizerMain->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CLEANING_OPTIONS_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CLEANING_OPTIONS_BASE::OnOKClick ), NULL, this );
+}
+
+DIALOG_CLEANING_OPTIONS_BASE::~DIALOG_CLEANING_OPTIONS_BASE()
+{
+ // Disconnect Events
+ m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CLEANING_OPTIONS_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CLEANING_OPTIONS_BASE::OnOKClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_cleaning_options_base.fbp b/pcbnew/dialogs/dialog_cleaning_options_base.fbp
new file mode 100644
index 0000000..b3eaacf
--- /dev/null
+++ b/pcbnew/dialogs/dialog_cleaning_options_base.fbp
@@ -0,0 +1,481 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_cleaning_options_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_cleaning_options</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_CLEANING_OPTIONS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">257,185</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Cleaning Options</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Delete redundant vias</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cleanViasOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">remove vias on pads with a through hole</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NUMERIC</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Merge overlapping segments</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_mergeSegmOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">merge aligned track segments, and remove null segments</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NUMERIC</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">D&amp;elete unconnected tracks</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_deleteUnconnectedOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">delete track segment having a dangling end</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NUMERIC</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_cleaning_options_base.h b/pcbnew/dialogs/dialog_cleaning_options_base.h
new file mode 100644
index 0000000..a67a177
--- /dev/null
+++ b/pcbnew/dialogs/dialog_cleaning_options_base.h
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 13 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_CLEANING_OPTIONS_BASE_H__
+#define __DIALOG_CLEANING_OPTIONS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/checkbox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_CLEANING_OPTIONS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_CLEANING_OPTIONS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxCheckBox* m_cleanViasOpt;
+ wxCheckBox* m_mergeSegmOpt;
+ wxCheckBox* m_deleteUnconnectedOpt;
+ wxStaticLine* m_staticline;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_CLEANING_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Cleaning Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 257,185 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_CLEANING_OPTIONS_BASE();
+
+};
+
+#endif //__DIALOG_CLEANING_OPTIONS_BASE_H__
diff --git a/pcbnew/dialogs/dialog_copper_zones.cpp b/pcbnew/dialogs/dialog_copper_zones.cpp
new file mode 100644
index 0000000..46c7728
--- /dev/null
+++ b/pcbnew/dialogs/dialog_copper_zones.cpp
@@ -0,0 +1,718 @@
+/**
+ * @file dialog_copper_zones.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wx/wx.h>
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <confirm.h>
+#include <PolyLine.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <zones.h>
+#include <base_units.h>
+
+#include <class_zone.h>
+#include <class_board.h>
+#include <dialog_copper_zones_base.h>
+
+#include <wx/imaglist.h> // needed for wx/listctrl.h, in wxGTK 2.8.12
+#include <wx/listctrl.h>
+#include <layers_id_colors_and_visibility.h>
+
+
+/**
+ * Class DIALOG_COPPER_ZONE
+ * is the derived class from dialog_copper_zone_frame created by wxFormBuilder
+ */
+class DIALOG_COPPER_ZONE : public DIALOG_COPPER_ZONE_BASE
+{
+public:
+ DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings );
+
+private:
+ PCB_BASE_FRAME* m_Parent;
+ wxConfigBase* m_Config; ///< Current config
+
+ ZONE_EDIT_T m_OnExitCode; ///< exit code: ZONE_ABORT if no change,
+ ///< ZONE_OK if new values accepted
+ ///< ZONE_EXPORT_VALUES if values are exported to others zones
+
+ ZONE_SETTINGS m_settings;
+ ZONE_SETTINGS* m_ptr;
+
+ bool m_NetSortingByPadCount; ///< false = alphabetic sort.
+ ///< true = pad count sort.
+
+ long m_NetFiltering;
+
+ std::vector<LAYER_ID> m_LayerId; ///< Handle the real layer number from layer
+ ///< name position in m_LayerSelectionCtrl
+
+ static wxString m_netNameShowFilter; ///< the filter to show nets (default * "*").
+ ///< static to keep this pattern for an entire Pcbnew session
+
+ /**
+ * Function initDialog
+ * fills in the dialog controls using the current settings.
+ */
+ void initDialog();
+
+ void OnButtonOkClick( wxCommandEvent& event );
+ void OnButtonCancelClick( wxCommandEvent& event );
+ void OnClose( wxCloseEvent& event );
+ void OnCornerSmoothingModeChoice( wxCommandEvent& event );
+
+ /**
+ * Function AcceptOptions
+ * @param aPromptForErrors is true to prompt user on incorrect params.
+ * @param aUseExportableSetupOnly is true to use exportable parameters only (used to export this setup to other zones).
+ * @return bool - false if incorrect options, true if ok.
+ */
+ bool AcceptOptions( bool aPromptForErrors, bool aUseExportableSetupOnly = false );
+
+ void OnNetSortingOptionSelected( wxCommandEvent& event );
+ void ExportSetupToOtherCopperZones( wxCommandEvent& event );
+ void OnPadsInZoneClick( wxCommandEvent& event );
+ void OnRunFiltersButtonClick( wxCommandEvent& event );
+
+ void buildAvailableListOfNets();
+
+ /**
+ * Function initListNetsParams
+ * initializes m_NetSortingByPadCount and m_NetFiltering values
+ * according to m_NetDisplayOption selection.
+ */
+ void initListNetsParams();
+
+ /**
+ * Function makeLayerBitmap
+ * creates the colored rectangle bitmaps used in the layer selection widget.
+ * @param aColor is the color to fill the rectangle with.
+ */
+ wxBitmap makeLayerBitmap( EDA_COLOR_T aColor );
+};
+
+
+#define LAYER_BITMAP_SIZE_X 20
+#define LAYER_BITMAP_SIZE_Y 10
+
+// Initialize static member variables
+wxString DIALOG_COPPER_ZONE::m_netNameShowFilter( wxT( "*" ) );
+
+
+ZONE_EDIT_T InvokeCopperZonesEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings )
+{
+ DIALOG_COPPER_ZONE dlg( aCaller, aSettings );
+
+ ZONE_EDIT_T result = ZONE_EDIT_T( dlg.ShowModal() );
+ return result;
+}
+
+
+DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings ) :
+ DIALOG_COPPER_ZONE_BASE( aParent )
+{
+ m_Parent = aParent;
+ m_Config = Kiface().KifaceSettings();
+
+ m_ptr = aSettings;
+ m_settings = *aSettings;
+
+ m_NetSortingByPadCount = true; // false = alphabetic sort, true = pad count sort
+ m_OnExitCode = ZONE_ABORT;
+
+ SetReturnCode( ZONE_ABORT ); // Will be changed on buttons click
+
+ // Fix static text widget minimum width to a suitable value so that
+ // resizing the dialog is not necessary when changing the corner smoothing type.
+ // Depends on the default text in the widget.
+ m_cornerSmoothingTitle->SetMinSize( m_cornerSmoothingTitle->GetSize() );
+
+ initDialog();
+
+ m_sdbSizerOK->SetDefault();
+ GetSizer()->SetSizeHints( this );
+ Center();
+}
+
+
+void DIALOG_COPPER_ZONE::initDialog()
+{
+ BOARD* board = m_Parent->GetBoard();
+
+ wxString msg;
+
+ if( m_settings.m_Zone_45_Only )
+ m_OrientEdgesOpt->SetSelection( 1 );
+
+ m_FillModeCtrl->SetSelection( m_settings.m_FillMode ? 1 : 0 );
+
+ AddUnitSymbol( *m_ClearanceValueTitle, g_UserUnit );
+ msg = StringFromValue( g_UserUnit, m_settings.m_ZoneClearance );
+ m_ZoneClearanceCtrl->SetValue( msg );
+
+ AddUnitSymbol( *m_MinThicknessValueTitle, g_UserUnit );
+ msg = StringFromValue( g_UserUnit, m_settings.m_ZoneMinThickness );
+ m_ZoneMinThicknessCtrl->SetValue( msg );
+
+ switch( m_settings.GetPadConnection() )
+ {
+ case PAD_ZONE_CONN_THT_THERMAL: // Thermals only for THT pads
+ m_PadInZoneOpt->SetSelection( 2 );
+ break;
+
+ case PAD_ZONE_CONN_NONE: // Pads are not covered
+ m_PadInZoneOpt->SetSelection( 3 );
+ break;
+
+ default:
+ case PAD_ZONE_CONN_THERMAL: // Use thermal relief for pads
+ m_PadInZoneOpt->SetSelection( 1 );
+ break;
+
+ case PAD_ZONE_CONN_FULL: // pads are covered by copper
+ m_PadInZoneOpt->SetSelection( 0 );
+ break;
+ }
+
+ // Antipad and spokes are significant only for thermals
+ if( m_settings.GetPadConnection() != PAD_ZONE_CONN_THERMAL &&
+ m_settings.GetPadConnection() != PAD_ZONE_CONN_THT_THERMAL )
+ {
+ m_AntipadSizeValue->Enable( false );
+ m_CopperWidthValue->Enable( false );
+ }
+ else
+ {
+ m_AntipadSizeValue->Enable( true );
+ m_CopperWidthValue->Enable( true );
+ }
+
+ m_PriorityLevelCtrl->SetValue( m_settings.m_ZonePriority );
+
+ AddUnitSymbol( *m_AntipadSizeText, g_UserUnit );
+ AddUnitSymbol( *m_CopperBridgeWidthText, g_UserUnit );
+ PutValueInLocalUnits( *m_AntipadSizeValue, m_settings.m_ThermalReliefGap );
+ PutValueInLocalUnits( *m_CopperWidthValue, m_settings.m_ThermalReliefCopperBridge );
+
+ m_cornerSmoothingChoice->SetSelection( m_settings.GetCornerSmoothingType() );
+
+ PutValueInLocalUnits( *m_cornerSmoothingCtrl, m_settings.GetCornerRadius() );
+
+ switch( m_settings.m_Zone_HatchingStyle )
+ {
+ case CPolyLine::NO_HATCH:
+ m_OutlineAppearanceCtrl->SetSelection( 0 );
+ break;
+
+ case CPolyLine::DIAGONAL_EDGE:
+ m_OutlineAppearanceCtrl->SetSelection( 1 );
+ break;
+
+ case CPolyLine::DIAGONAL_FULL:
+ m_OutlineAppearanceCtrl->SetSelection( 2 );
+ break;
+ }
+
+ m_ArcApproximationOpt->SetSelection(
+ m_settings.m_ArcToSegmentsCount == ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF ? 1 : 0 );
+
+ // Create one column in m_LayerSelectionCtrl
+ wxListItem column0;
+ column0.SetId( 0 );
+ m_LayerSelectionCtrl->InsertColumn( 0, column0 );
+
+ wxImageList* imageList = new wxImageList( LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
+ m_LayerSelectionCtrl->AssignImageList( imageList, wxIMAGE_LIST_SMALL );
+
+ int ctrlWidth = 0; // Min width for m_LayerSelectionCtrl to show the layers names
+ int imgIdx = 0;
+
+ LSET cu_set = LSET::AllCuMask( board->GetCopperLayerCount() );
+
+ for( LSEQ cu_stack = cu_set.UIOrder(); cu_stack; ++cu_stack, imgIdx++ )
+ {
+ LAYER_ID layer = *cu_stack;
+
+ m_LayerId.push_back( layer );
+
+ msg = board->GetLayerName( layer );
+
+ msg.Trim();
+
+ EDA_COLOR_T layerColor = board->GetLayerColor( layer );
+
+ imageList->Add( makeLayerBitmap( layerColor ) );
+
+ int itemIndex = m_LayerSelectionCtrl->InsertItem(
+ m_LayerSelectionCtrl->GetItemCount(), msg, imgIdx );
+
+ if( m_settings.m_CurrentZone_Layer == layer )
+ m_LayerSelectionCtrl->Select( itemIndex );
+
+ wxSize tsize( GetTextSize( msg, m_LayerSelectionCtrl ) );
+ ctrlWidth = std::max( ctrlWidth, tsize.x );
+ }
+
+ // The most easy way to ensure the right size is to use wxLIST_AUTOSIZE
+ // unfortunately this option does not work well both on
+ // wxWidgets 2.8 ( column width too small), and
+ // wxWidgets 2.9 ( column width too large)
+ ctrlWidth += LAYER_BITMAP_SIZE_X + 25; // Add bitmap width + margin between bitmap and text
+ m_LayerSelectionCtrl->SetColumnWidth( 0, ctrlWidth );
+
+ ctrlWidth += 25; // add small margin between text and window borders
+ // and room for vertical scroll bar
+ m_LayerSelectionCtrl->SetMinSize( wxSize( ctrlWidth, -1 ) );
+
+ wxString netNameDoNotShowFilter = wxT( "Net-*" );
+ if( m_Config )
+ {
+ int opt = m_Config->Read( ZONE_NET_SORT_OPTION_KEY, 1l );
+ m_NetDisplayOption->SetSelection( opt );
+ m_Config->Read( ZONE_NET_FILTER_STRING_KEY, netNameDoNotShowFilter );
+ }
+ else
+ m_NetDisplayOption->SetSelection( 1 );
+
+ m_ShowNetNameFilter->SetValue( m_netNameShowFilter );
+ initListNetsParams();
+
+ // Build list of nets:
+ m_DoNotShowNetNameFilter->SetValue( netNameDoNotShowFilter );
+ buildAvailableListOfNets();
+
+ wxCommandEvent event;
+ OnCornerSmoothingModeChoice( event );
+}
+
+
+void DIALOG_COPPER_ZONE::OnButtonCancelClick( wxCommandEvent& event )
+{
+ Close( true );
+}
+
+void DIALOG_COPPER_ZONE::OnButtonOkClick( wxCommandEvent& event )
+{
+ m_netNameShowFilter = m_ShowNetNameFilter->GetValue();
+
+ if( AcceptOptions( true ) )
+ {
+ *m_ptr = m_settings;
+ EndModal( ZONE_OK );
+ }
+}
+
+
+// called on system close button
+void DIALOG_COPPER_ZONE::OnClose( wxCloseEvent& event )
+{
+ if( m_OnExitCode != ZONE_ABORT )
+ *m_ptr = m_settings;
+
+ EndModal( m_OnExitCode );
+}
+
+
+bool DIALOG_COPPER_ZONE::AcceptOptions( bool aPromptForErrors, bool aUseExportableSetupOnly )
+{
+ switch( m_PadInZoneOpt->GetSelection() )
+ {
+ case 3:
+ // Pads are not covered
+ m_settings.SetPadConnection( PAD_ZONE_CONN_NONE );
+ break;
+
+ case 2:
+ // Use thermal relief for THT pads
+ m_settings.SetPadConnection( PAD_ZONE_CONN_THT_THERMAL );
+ break;
+
+ case 1:
+ // Use thermal relief for pads
+ m_settings.SetPadConnection( PAD_ZONE_CONN_THERMAL );
+ break;
+
+ case 0:
+ // pads are covered by copper
+ m_settings.SetPadConnection( PAD_ZONE_CONN_FULL );
+ break;
+ }
+
+ switch( m_OutlineAppearanceCtrl->GetSelection() )
+ {
+ case 0:
+ m_settings.m_Zone_HatchingStyle = CPolyLine::NO_HATCH;
+ break;
+
+ case 1:
+ m_settings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE;
+ break;
+
+ case 2:
+ m_settings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_FULL;
+ break;
+ }
+
+ m_settings.m_ArcToSegmentsCount = m_ArcApproximationOpt->GetSelection() == 1 ?
+ ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF :
+ ARC_APPROX_SEGMENTS_COUNT_LOW_DEF;
+
+ if( m_Config )
+ {
+ m_Config->Write( ZONE_NET_OUTLINES_HATCH_OPTION_KEY,
+ (long) m_settings.m_Zone_HatchingStyle );
+ wxString filter = m_DoNotShowNetNameFilter->GetValue();
+ m_Config->Write( ZONE_NET_FILTER_STRING_KEY, filter );
+ }
+
+ m_netNameShowFilter = m_ShowNetNameFilter->GetValue();
+ m_settings.m_FillMode = (m_FillModeCtrl->GetSelection() == 0) ? 0 : 1;
+
+ wxString txtvalue = m_ZoneClearanceCtrl->GetValue();
+ m_settings.m_ZoneClearance = ValueFromString( g_UserUnit, txtvalue );
+
+ // Test if this is a reasonable value for this parameter
+ // A too large value can hang Pcbnew
+ #define CLEARANCE_MAX_VALUE ZONE_CLEARANCE_MAX_VALUE_MIL*IU_PER_MILS
+
+ if( m_settings.m_ZoneClearance > CLEARANCE_MAX_VALUE )
+ {
+ wxString msg;
+ msg.Printf( _( "Clearance must be smaller than %f\" / %f mm." ),
+ ZONE_CLEARANCE_MAX_VALUE_MIL / 1000.0, ZONE_CLEARANCE_MAX_VALUE_MIL * 0.0254 );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ txtvalue = m_ZoneMinThicknessCtrl->GetValue();
+ m_settings.m_ZoneMinThickness = ValueFromString( g_UserUnit, txtvalue );
+
+ if( m_settings.m_ZoneMinThickness < (ZONE_THICKNESS_MIN_VALUE_MIL*IU_PER_MILS) )
+ {
+ wxString msg;
+ msg.Printf( _( "Minimum width must be larger than %f\" / %f mm." ),
+ ZONE_THICKNESS_MIN_VALUE_MIL / 1000.0, ZONE_THICKNESS_MIN_VALUE_MIL * 0.0254 );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ m_settings.SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() );
+ txtvalue = m_cornerSmoothingCtrl->GetValue();
+ m_settings.SetCornerRadius( ValueFromString( g_UserUnit, txtvalue ) );
+
+ m_settings.m_ZonePriority = m_PriorityLevelCtrl->GetValue();
+
+ if( m_OrientEdgesOpt->GetSelection() == 0 )
+ m_settings.m_Zone_45_Only = false;
+ else
+ m_settings.m_Zone_45_Only = true;
+
+ m_settings.m_ThermalReliefGap = ValueFromTextCtrl( *m_AntipadSizeValue );
+ m_settings.m_ThermalReliefCopperBridge = ValueFromTextCtrl( *m_CopperWidthValue );
+
+ if( m_Config )
+ {
+ ConfigBaseWriteDouble( m_Config, ZONE_CLEARANCE_WIDTH_STRING_KEY,
+ (double) m_settings.m_ZoneClearance / IU_PER_MILS );
+
+ ConfigBaseWriteDouble( m_Config, ZONE_MIN_THICKNESS_WIDTH_STRING_KEY,
+ (double) m_settings.m_ZoneMinThickness / IU_PER_MILS );
+
+ ConfigBaseWriteDouble( m_Config, ZONE_THERMAL_RELIEF_GAP_STRING_KEY,
+ (double) m_settings.m_ThermalReliefGap / IU_PER_MILS );
+
+ ConfigBaseWriteDouble( m_Config, ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY,
+ (double) m_settings.m_ThermalReliefCopperBridge / IU_PER_MILS );
+ }
+
+ if( ( m_settings.GetPadConnection() == PAD_ZONE_CONN_THT_THERMAL
+ || m_settings.GetPadConnection() == PAD_ZONE_CONN_THERMAL )
+ && m_settings.m_ThermalReliefCopperBridge <= m_settings.m_ZoneMinThickness )
+ {
+ DisplayError( this,
+ _( "Thermal relief spoke must be greater than the minimum width." ) );
+ return false;
+ }
+
+ // If we use only exportable to others zones parameters, exit here:
+ if( aUseExportableSetupOnly )
+ return true;
+
+ // Get the layer selection for this zone
+ int ii = m_LayerSelectionCtrl->GetFirstSelected();
+
+ if( ii < 0 && aPromptForErrors )
+ {
+ DisplayError( this, _( "No layer selected." ) );
+ return false;
+ }
+
+ m_settings.m_CurrentZone_Layer = ToLAYER_ID( m_LayerId[ii] );
+
+ // Get the net name selection for this zone
+ ii = m_ListNetNameSelection->GetSelection();
+
+ if( ii < 0 && aPromptForErrors )
+ {
+ DisplayError( this, _( "No net selected." ) );
+ return false;
+ }
+
+ if( ii == 0 ) // the not connected option was selected: this is not a good practice: warn:
+ {
+ if( !IsOK( this, _( "You have chosen the \"not connected\" option. This will create "
+ "insulated copper islands. Are you sure ?" ) ) )
+ return false;
+ }
+
+ wxString net_name = m_ListNetNameSelection->GetString( ii );
+
+ m_settings.m_NetcodeSelection = 0;
+
+ // Search net_code for this net, if a net was selected
+ if( m_ListNetNameSelection->GetSelection() > 0 )
+ {
+ NETINFO_ITEM* net = m_Parent->GetBoard()->FindNet( net_name );
+
+ if( net )
+ m_settings.m_NetcodeSelection = net->GetNet();
+ }
+
+ return true;
+}
+
+
+void DIALOG_COPPER_ZONE::OnCornerSmoothingModeChoice( wxCommandEvent& event )
+{
+ int selection = m_cornerSmoothingChoice->GetSelection();
+
+ switch( selection )
+ {
+ case ZONE_SETTINGS::SMOOTHING_NONE:
+ m_cornerSmoothingTitle->Enable( false );
+ m_cornerSmoothingCtrl->Enable( false );
+ break;
+ case ZONE_SETTINGS::SMOOTHING_CHAMFER:
+ m_cornerSmoothingTitle->Enable( true );
+ m_cornerSmoothingCtrl->Enable( true );
+ m_cornerSmoothingTitle->SetLabel( _( "Chamfer distance" ) );
+ AddUnitSymbol( *m_cornerSmoothingTitle, g_UserUnit );
+ break;
+ case ZONE_SETTINGS::SMOOTHING_FILLET:
+ m_cornerSmoothingTitle->Enable( true );
+ m_cornerSmoothingCtrl->Enable( true );
+ m_cornerSmoothingTitle->SetLabel( _( "Fillet radius" ) );
+ AddUnitSymbol( *m_cornerSmoothingTitle, g_UserUnit );
+ break;
+ }
+}
+
+
+void DIALOG_COPPER_ZONE::OnNetSortingOptionSelected( wxCommandEvent& event )
+{
+ initListNetsParams();
+ buildAvailableListOfNets();
+
+ m_netNameShowFilter = m_ShowNetNameFilter->GetValue();
+
+ if( m_Config )
+ {
+ m_Config->Write( ZONE_NET_SORT_OPTION_KEY, (long) m_NetDisplayOption->GetSelection() );
+ wxString Filter = m_DoNotShowNetNameFilter->GetValue();
+ m_Config->Write( ZONE_NET_FILTER_STRING_KEY, Filter );
+ }
+}
+
+
+void DIALOG_COPPER_ZONE::ExportSetupToOtherCopperZones( wxCommandEvent& event )
+{
+ if( !AcceptOptions( true, true ) )
+ return;
+
+ // Export settings ( but layer and netcode ) to others copper zones
+ BOARD* pcb = m_Parent->GetBoard();
+
+ for( int ii = 0; ii < pcb->GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* zone = pcb->GetArea( ii );
+
+ // Cannot export settings from a copper zone
+ // to a zone keepout:
+ if( zone->GetIsKeepout() )
+ continue;
+
+ m_settings.ExportSetting( *zone, false ); // false = partial export
+ m_Parent->OnModify();
+ }
+
+ m_OnExitCode = ZONE_EXPORT_VALUES; // values are exported to others zones
+}
+
+
+void DIALOG_COPPER_ZONE::OnPadsInZoneClick( wxCommandEvent& event )
+{
+ switch( m_PadInZoneOpt->GetSelection() )
+ {
+ default:
+ m_AntipadSizeValue->Enable( false );
+ m_CopperWidthValue->Enable( false );
+ break;
+
+ case 2:
+ case 1:
+ m_AntipadSizeValue->Enable( true );
+ m_CopperWidthValue->Enable( true );
+ break;
+ }
+}
+
+
+void DIALOG_COPPER_ZONE::initListNetsParams()
+{
+ switch( m_NetDisplayOption->GetSelection() )
+ {
+ case 0:
+ m_NetSortingByPadCount = false;
+ m_NetFiltering = false;
+ break;
+
+ case 1:
+ m_NetSortingByPadCount = true;
+ m_NetFiltering = false;
+ break;
+
+ case 2:
+ m_NetSortingByPadCount = false;
+ m_NetFiltering = true;
+ break;
+
+ case 3:
+ m_NetSortingByPadCount = true;
+ m_NetFiltering = true;
+ break;
+ }
+}
+
+
+void DIALOG_COPPER_ZONE::OnRunFiltersButtonClick( wxCommandEvent& event )
+{
+ m_netNameShowFilter = m_ShowNetNameFilter->GetValue();
+
+ // Ensure filtered option for nets
+ if( m_NetDisplayOption->GetSelection() == 0 )
+ m_NetDisplayOption->SetSelection( 2 );
+ else if( m_NetDisplayOption->GetSelection() == 1 )
+ m_NetDisplayOption->SetSelection( 3 );
+
+ initListNetsParams();
+ buildAvailableListOfNets();
+}
+
+
+void DIALOG_COPPER_ZONE::buildAvailableListOfNets()
+{
+ wxArrayString listNetName;
+
+ m_Parent->GetBoard()->SortedNetnamesList( listNetName, m_NetSortingByPadCount );
+
+ if( m_NetFiltering )
+ {
+ wxString doNotShowFilter = m_DoNotShowNetNameFilter->GetValue();
+ wxString ShowFilter = m_ShowNetNameFilter->GetValue();
+
+ for( unsigned ii = 0; ii < listNetName.GetCount(); ii++ )
+ {
+ if( listNetName[ii].Matches( doNotShowFilter ) )
+ {
+ listNetName.RemoveAt( ii );
+ ii--;
+ }
+ else if( !listNetName[ii].Matches( ShowFilter ) )
+ {
+ listNetName.RemoveAt( ii );
+ ii--;
+ }
+ }
+ }
+
+ listNetName.Insert( wxT( "<no net>" ), 0 );
+
+ // Ensure currently selected net for the zone is visible, regardless of filters
+ int selectedNetListNdx = -1;
+ int net_select = m_settings.m_NetcodeSelection;
+
+ if( net_select > 0 )
+ {
+ NETINFO_ITEM* equipot = m_Parent->GetBoard()->FindNet( net_select );
+ if( equipot )
+ {
+ selectedNetListNdx = listNetName.Index( equipot->GetNetname() );
+
+ if( wxNOT_FOUND == selectedNetListNdx )
+ {
+ // the currently selected net must *always* be visible.
+ listNetName.Insert( equipot->GetNetname(), 0 );
+ selectedNetListNdx = 0;
+ }
+ }
+ }
+ else if( net_select == 0 )
+ selectedNetListNdx = 0; // SetSelection() on "<no net>"
+ else
+ {
+ // selectedNetListNdx remains -1, no net selected.
+ }
+
+ m_ListNetNameSelection->Clear();
+ m_ListNetNameSelection->InsertItems( listNetName, 0 );
+ m_ListNetNameSelection->SetSelection( 0 );
+
+ if( selectedNetListNdx >= 0 )
+ {
+ m_ListNetNameSelection->SetSelection( selectedNetListNdx );
+ m_ListNetNameSelection->EnsureVisible( selectedNetListNdx );
+ }
+}
+
+
+wxBitmap DIALOG_COPPER_ZONE::makeLayerBitmap( EDA_COLOR_T aColor )
+{
+ wxBitmap bitmap( LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
+ wxBrush brush;
+ wxMemoryDC iconDC;
+
+ iconDC.SelectObject( bitmap );
+ brush.SetColour( MakeColour( aColor ) );
+ brush.SetStyle( wxBRUSHSTYLE_SOLID );
+ iconDC.SetBrush( brush );
+ iconDC.DrawRectangle( 0, 0, LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
+
+ return bitmap;
+}
diff --git a/pcbnew/dialogs/dialog_copper_zones_base.cpp b/pcbnew/dialogs/dialog_copper_zones_base.cpp
new file mode 100644
index 0000000..75cf1a2
--- /dev/null
+++ b/pcbnew/dialogs/dialog_copper_zones_base.cpp
@@ -0,0 +1,273 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_copper_zones_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+BEGIN_EVENT_TABLE( DIALOG_COPPER_ZONE_BASE, DIALOG_SHIM )
+ EVT_CLOSE( DIALOG_COPPER_ZONE_BASE::_wxFB_OnClose )
+ EVT_CHOICE( ID_M_NETDISPLAYOPTION, DIALOG_COPPER_ZONE_BASE::_wxFB_OnNetSortingOptionSelected )
+ EVT_TEXT_ENTER( ID_TEXTCTRL_NETNAMES_FILTER, DIALOG_COPPER_ZONE_BASE::_wxFB_OnRunFiltersButtonClick )
+ EVT_TEXT_ENTER( ID_TEXTCTRL_NETNAMES_FILTER, DIALOG_COPPER_ZONE_BASE::_wxFB_OnRunFiltersButtonClick )
+ EVT_BUTTON( wxID_APPLY_FILTERS, DIALOG_COPPER_ZONE_BASE::_wxFB_OnRunFiltersButtonClick )
+ EVT_CHOICE( ID_CORNER_SMOOTHING, DIALOG_COPPER_ZONE_BASE::_wxFB_OnCornerSmoothingModeChoice )
+ EVT_CHOICE( ID_M_PADINZONEOPT, DIALOG_COPPER_ZONE_BASE::_wxFB_OnPadsInZoneClick )
+ EVT_BUTTON( wxID_BUTTON_EXPORT, DIALOG_COPPER_ZONE_BASE::_wxFB_ExportSetupToOtherCopperZones )
+ EVT_BUTTON( wxID_CANCEL, DIALOG_COPPER_ZONE_BASE::_wxFB_OnButtonCancelClick )
+ EVT_BUTTON( wxID_OK, DIALOG_COPPER_ZONE_BASE::_wxFB_OnButtonOkClick )
+END_EVENT_TABLE()
+
+DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ m_MainBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* m_OptionsBoxSizer;
+ m_OptionsBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* m_layerSizer;
+ m_layerSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText17 = new wxStaticText( this, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText17->Wrap( -1 );
+ m_layerSizer->Add( m_staticText17, 0, wxTOP|wxRIGHT, 5 );
+
+ m_LayerSelectionCtrl = new wxListView( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ALIGN_LEFT|wxLC_NO_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL );
+ m_layerSizer->Add( m_LayerSelectionCtrl, 1, wxRIGHT, 5 );
+
+
+ m_OptionsBoxSizer->Add( m_layerSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerNets;
+ bSizerNets = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText2 = new wxStaticText( this, wxID_ANY, _("Net:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText2->Wrap( -1 );
+ bSizerNets->Add( m_staticText2, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_ListNetNameSelection = new wxListBox( this, ID_NETNAME_SELECTION, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ bSizerNets->Add( m_ListNetNameSelection, 1, wxEXPAND, 5 );
+
+
+ m_OptionsBoxSizer->Add( bSizerNets, 1, wxEXPAND, 5 );
+
+ wxStaticBoxSizer* m_NetSortOptSizer;
+ m_NetSortOptSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Net Filtering") ), wxVERTICAL );
+
+ m_staticText16 = new wxStaticText( m_NetSortOptSizer->GetStaticBox(), wxID_ANY, _("Display:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText16->Wrap( -1 );
+ m_NetSortOptSizer->Add( m_staticText16, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ wxString m_NetDisplayOptionChoices[] = { _("Show all (alphabetical)"), _("Show all (pad count)"), _("Filtered (alphabetical)"), _("Filtered (pad count)") };
+ int m_NetDisplayOptionNChoices = sizeof( m_NetDisplayOptionChoices ) / sizeof( wxString );
+ m_NetDisplayOption = new wxChoice( m_NetSortOptSizer->GetStaticBox(), ID_M_NETDISPLAYOPTION, wxDefaultPosition, wxDefaultSize, m_NetDisplayOptionNChoices, m_NetDisplayOptionChoices, 0 );
+ m_NetDisplayOption->SetSelection( 0 );
+ m_NetSortOptSizer->Add( m_NetDisplayOption, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_staticText5 = new wxStaticText( m_NetSortOptSizer->GetStaticBox(), wxID_ANY, _("Hidden net filter:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText5->Wrap( -1 );
+ m_NetSortOptSizer->Add( m_staticText5, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_DoNotShowNetNameFilter = new wxTextCtrl( m_NetSortOptSizer->GetStaticBox(), ID_TEXTCTRL_NETNAMES_FILTER, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
+ m_DoNotShowNetNameFilter->SetToolTip( _("Pattern to filter net names in filtered list.\nNet names matching this pattern are not displayed.") );
+
+ m_NetSortOptSizer->Add( m_DoNotShowNetNameFilter, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticText51 = new wxStaticText( m_NetSortOptSizer->GetStaticBox(), wxID_ANY, _("Visible net filter:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText51->Wrap( -1 );
+ m_NetSortOptSizer->Add( m_staticText51, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_ShowNetNameFilter = new wxTextCtrl( m_NetSortOptSizer->GetStaticBox(), ID_TEXTCTRL_NETNAMES_FILTER, _("*"), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
+ m_ShowNetNameFilter->SetToolTip( _("Pattern to filter net names in filtered list.\nOnly net names matching this pattern are displayed.") );
+
+ m_NetSortOptSizer->Add( m_ShowNetNameFilter, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_buttonRunFilter = new wxButton( m_NetSortOptSizer->GetStaticBox(), wxID_APPLY_FILTERS, _("Apply Filters"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_NetSortOptSizer->Add( m_buttonRunFilter, 0, wxALL|wxEXPAND, 5 );
+
+
+ m_OptionsBoxSizer->Add( m_NetSortOptSizer, 0, wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ m_MainBoxSizer->Add( m_OptionsBoxSizer, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxStaticBoxSizer* m_ExportableSetupSizer;
+ m_ExportableSetupSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Settings") ), wxHORIZONTAL );
+
+ wxBoxSizer* bSizerSettings;
+ bSizerSettings = new wxBoxSizer( wxVERTICAL );
+
+ m_ClearanceValueTitle = new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, _("Clearance"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ClearanceValueTitle->Wrap( -1 );
+ bSizerSettings->Add( m_ClearanceValueTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_ZoneClearanceCtrl = new wxTextCtrl( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerSettings->Add( m_ZoneClearanceCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_MinThicknessValueTitle = new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, _("Minimum width"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MinThicknessValueTitle->Wrap( -1 );
+ m_MinThicknessValueTitle->SetToolTip( _("Minimum thickness of filled areas.") );
+
+ bSizerSettings->Add( m_MinThicknessValueTitle, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_ZoneMinThicknessCtrl = new wxTextCtrl( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerSettings->Add( m_ZoneMinThicknessCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticText151 = new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, _("Corner smoothing:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText151->Wrap( -1 );
+ bSizerSettings->Add( m_staticText151, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ wxString m_cornerSmoothingChoiceChoices[] = { _("None"), _("Chamfer"), _("Fillet") };
+ int m_cornerSmoothingChoiceNChoices = sizeof( m_cornerSmoothingChoiceChoices ) / sizeof( wxString );
+ m_cornerSmoothingChoice = new wxChoice( m_ExportableSetupSizer->GetStaticBox(), ID_CORNER_SMOOTHING, wxDefaultPosition, wxDefaultSize, m_cornerSmoothingChoiceNChoices, m_cornerSmoothingChoiceChoices, 0 );
+ m_cornerSmoothingChoice->SetSelection( 0 );
+ bSizerSettings->Add( m_cornerSmoothingChoice, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_cornerSmoothingTitle = new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, _("Chamfer distance (mm):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_cornerSmoothingTitle->Wrap( -1 );
+ bSizerSettings->Add( m_cornerSmoothingTitle, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_cornerSmoothingCtrl = new wxTextCtrl( m_ExportableSetupSizer->GetStaticBox(), ID_M_CORNERSMOOTHINGCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerSettings->Add( m_cornerSmoothingCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ m_ExportableSetupSizer->Add( bSizerSettings, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerPadsConnection;
+ bSizerPadsConnection = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText13 = new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, _("Pad connection:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText13->Wrap( -1 );
+ bSizerPadsConnection->Add( m_staticText13, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ wxString m_PadInZoneOptChoices[] = { _("Solid"), _("Thermal relief"), _("THT thermal"), _("None") };
+ int m_PadInZoneOptNChoices = sizeof( m_PadInZoneOptChoices ) / sizeof( wxString );
+ m_PadInZoneOpt = new wxChoice( m_ExportableSetupSizer->GetStaticBox(), ID_M_PADINZONEOPT, wxDefaultPosition, wxDefaultSize, m_PadInZoneOptNChoices, m_PadInZoneOptChoices, 0 );
+ m_PadInZoneOpt->SetSelection( 0 );
+ bSizerPadsConnection->Add( m_PadInZoneOpt, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ wxStaticBoxSizer* m_ThermalShapesParamsSizer;
+ m_ThermalShapesParamsSizer = new wxStaticBoxSizer( new wxStaticBox( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, _("Thermal Reliefs") ), wxVERTICAL );
+
+ m_AntipadSizeText = new wxStaticText( m_ThermalShapesParamsSizer->GetStaticBox(), wxID_ANY, _("Antipad clearance"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_AntipadSizeText->Wrap( -1 );
+ m_ThermalShapesParamsSizer->Add( m_AntipadSizeText, 0, wxTOP|wxRIGHT, 5 );
+
+ m_AntipadSizeValue = new wxTextCtrl( m_ThermalShapesParamsSizer->GetStaticBox(), wxID_ANTIPAD_SIZE, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_AntipadSizeValue->SetToolTip( _("Clearance between pads in the same net and filled areas.") );
+
+ m_ThermalShapesParamsSizer->Add( m_AntipadSizeValue, 0, wxEXPAND|wxBOTTOM, 5 );
+
+ m_CopperBridgeWidthText = new wxStaticText( m_ThermalShapesParamsSizer->GetStaticBox(), wxID_ANY, _("Spoke width"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_CopperBridgeWidthText->Wrap( -1 );
+ m_ThermalShapesParamsSizer->Add( m_CopperBridgeWidthText, 0, wxTOP|wxRIGHT, 5 );
+
+ m_CopperWidthValue = new wxTextCtrl( m_ThermalShapesParamsSizer->GetStaticBox(), wxID_COPPER_BRIDGE_VALUE, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_CopperWidthValue->SetToolTip( _("Width of copper in thermal reliefs.") );
+
+ m_ThermalShapesParamsSizer->Add( m_CopperWidthValue, 0, wxEXPAND|wxBOTTOM, 5 );
+
+
+ bSizerPadsConnection->Add( m_ThermalShapesParamsSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ m_ExportableSetupSizer->Add( bSizerPadsConnection, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* m_MiddleBox;
+ m_MiddleBox = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText171 = new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, _("Priority level:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText171->Wrap( -1 );
+ m_staticText171->SetToolTip( _("Zones are filled by priority level, level 3 has higher priority than level 2.\nWhen a zone is inside an other zone:\n* If its priority is higher, its outlines are removed from the other zone.\n* If its priority is equal, a DRC error is set.") );
+
+ m_MiddleBox->Add( m_staticText171, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PriorityLevelCtrl = new wxSpinCtrl( m_ExportableSetupSizer->GetStaticBox(), ID_M_PRIORITYLEVELCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, 0 );
+ m_MiddleBox->Add( m_PriorityLevelCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticText11 = new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, _("Fill mode:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText11->Wrap( -1 );
+ m_MiddleBox->Add( m_staticText11, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ wxString m_FillModeCtrlChoices[] = { _("Polygon"), _("Segment") };
+ int m_FillModeCtrlNChoices = sizeof( m_FillModeCtrlChoices ) / sizeof( wxString );
+ m_FillModeCtrl = new wxChoice( m_ExportableSetupSizer->GetStaticBox(), ID_M_FILLMODECTRL, wxDefaultPosition, wxDefaultSize, m_FillModeCtrlNChoices, m_FillModeCtrlChoices, 0 );
+ m_FillModeCtrl->SetSelection( 0 );
+ m_MiddleBox->Add( m_FillModeCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_staticText12 = new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, _("Segments / 360 deg:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText12->Wrap( -1 );
+ m_MiddleBox->Add( m_staticText12, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ wxString m_ArcApproximationOptChoices[] = { _("16"), _("32") };
+ int m_ArcApproximationOptNChoices = sizeof( m_ArcApproximationOptChoices ) / sizeof( wxString );
+ m_ArcApproximationOpt = new wxChoice( m_ExportableSetupSizer->GetStaticBox(), ID_M_ARCAPPROXIMATIONOPT, wxDefaultPosition, wxDefaultSize, m_ArcApproximationOptNChoices, m_ArcApproximationOptChoices, 0 );
+ m_ArcApproximationOpt->SetSelection( 0 );
+ m_MiddleBox->Add( m_ArcApproximationOpt, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ m_ExportableSetupSizer->Add( m_MiddleBox, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerLowerRight;
+ bSizerLowerRight = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText14 = new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, _("Outline slope:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText14->Wrap( -1 );
+ bSizerLowerRight->Add( m_staticText14, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ wxString m_OrientEdgesOptChoices[] = { _("Arbitrary"), _("H, V, and 45 deg only") };
+ int m_OrientEdgesOptNChoices = sizeof( m_OrientEdgesOptChoices ) / sizeof( wxString );
+ m_OrientEdgesOpt = new wxChoice( m_ExportableSetupSizer->GetStaticBox(), ID_M_ORIENTEDGESOPT, wxDefaultPosition, wxDefaultSize, m_OrientEdgesOptNChoices, m_OrientEdgesOptChoices, 0 );
+ m_OrientEdgesOpt->SetSelection( 0 );
+ bSizerLowerRight->Add( m_OrientEdgesOpt, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_staticText15 = new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, _("Outline style:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText15->Wrap( -1 );
+ bSizerLowerRight->Add( m_staticText15, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ wxString m_OutlineAppearanceCtrlChoices[] = { _("Line"), _("Hatched"), _("Fully hatched") };
+ int m_OutlineAppearanceCtrlNChoices = sizeof( m_OutlineAppearanceCtrlChoices ) / sizeof( wxString );
+ m_OutlineAppearanceCtrl = new wxChoice( m_ExportableSetupSizer->GetStaticBox(), ID_M_OUTLINEAPPEARANCECTRL, wxDefaultPosition, wxDefaultSize, m_OutlineAppearanceCtrlNChoices, m_OutlineAppearanceCtrlChoices, 0 );
+ m_OutlineAppearanceCtrl->SetSelection( 0 );
+ bSizerLowerRight->Add( m_OutlineAppearanceCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ m_ExportableSetupSizer->Add( bSizerLowerRight, 0, wxEXPAND, 5 );
+
+
+ m_MainBoxSizer->Add( m_ExportableSetupSizer, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerbottom;
+ bSizerbottom = new wxBoxSizer( wxHORIZONTAL );
+
+ m_ExportSetupButton = new wxButton( this, wxID_BUTTON_EXPORT, _("Export Settings to Other Zones"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ExportSetupButton->SetToolTip( _("Export this zone setup (excluding layer and net selection) to all other copper zones.") );
+
+ bSizerbottom->Add( m_ExportSetupButton, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bSizerbottom->Add( m_sdbSizer, 1, wxEXPAND, 5 );
+
+
+ m_MainBoxSizer->Add( bSizerbottom, 0, wxALIGN_RIGHT|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ this->SetSizer( m_MainBoxSizer );
+ this->Layout();
+}
+
+DIALOG_COPPER_ZONE_BASE::~DIALOG_COPPER_ZONE_BASE()
+{
+}
diff --git a/pcbnew/dialogs/dialog_copper_zones_base.fbp b/pcbnew/dialogs/dialog_copper_zones_base.fbp
new file mode 100644
index 0000000..75d5026
--- /dev/null
+++ b/pcbnew/dialogs/dialog_copper_zones_base.fbp
@@ -0,0 +1,3379 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">table</property>
+ <property name="file">dialog_copper_zones_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_copper_zones_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">ID_DIALOG_COPPER_ZONE_BASE</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_COPPER_ZONE_BASE</property>
+ <property name="pos"></property>
+ <property name="size">567,507</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Copper Zone Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnClose</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_MainBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_OptionsBoxSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_layerSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layer:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText17</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxListCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LayerSelectionCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLC_ALIGN_LEFT|wxLC_NO_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL</property>
+ <property name="subclass">wxListView; </property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBeginDrag"></event>
+ <event name="OnListBeginLabelEdit"></event>
+ <event name="OnListBeginRDrag"></event>
+ <event name="OnListCacheHint"></event>
+ <event name="OnListColBeginDrag"></event>
+ <event name="OnListColClick"></event>
+ <event name="OnListColDragging"></event>
+ <event name="OnListColEndDrag"></event>
+ <event name="OnListColRightClick"></event>
+ <event name="OnListDeleteAllItems"></event>
+ <event name="OnListDeleteItem"></event>
+ <event name="OnListEndLabelEdit"></event>
+ <event name="OnListInsertItem"></event>
+ <event name="OnListItemActivated"></event>
+ <event name="OnListItemDeselected"></event>
+ <event name="OnListItemFocused"></event>
+ <event name="OnListItemMiddleClick"></event>
+ <event name="OnListItemRightClick"></event>
+ <event name="OnListItemSelected"></event>
+ <event name="OnListKeyDown"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerNets</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Net:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxListBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_NETNAME_SELECTION</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_ListNetNameSelection</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox"></event>
+ <event name="OnListBoxDClick"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Net Filtering</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_NetSortOptSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Display:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText16</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Show all (alphabetical)&quot; &quot;Show all (pad count)&quot; &quot;Filtered (alphabetical)&quot; &quot;Filtered (pad count)&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_NETDISPLAYOPTION</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NetDisplayOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">OnNetSortingOptionSelected</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Hidden net filter:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_TEXTCTRL_NETNAMES_FILTER</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DoNotShowNetNameFilter</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_PROCESS_ENTER</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Pattern to filter net names in filtered list.&#x0A;Net names matching this pattern are not displayed.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnRunFiltersButtonClick</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Visible net filter:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText51</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_TEXTCTRL_NETNAMES_FILTER</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShowNetNameFilter</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_PROCESS_ENTER</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Pattern to filter net names in filtered list.&#x0A;Only net names matching this pattern are displayed.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">*</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnRunFiltersButtonClick</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_APPLY_FILTERS</property>
+ <property name="label">Apply Filters</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonRunFilter</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnRunFiltersButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Settings</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_ExportableSetupSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerSettings</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Clearance</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ClearanceValueTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ZoneClearanceCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Minimum width</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MinThicknessValueTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Minimum thickness of filled areas.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ZoneMinThicknessCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Corner smoothing:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText151</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;None&quot; &quot;Chamfer&quot; &quot;Fillet&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CORNER_SMOOTHING</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cornerSmoothingChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">OnCornerSmoothingModeChoice</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Chamfer distance (mm):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cornerSmoothingTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_CORNERSMOOTHINGCTRL</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cornerSmoothingCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerPadsConnection</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad connection:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText13</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Solid&quot; &quot;Thermal relief&quot; &quot;THT thermal&quot; &quot;None&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_PADINZONEOPT</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadInZoneOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">OnPadsInZoneClick</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Thermal Reliefs</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_ThermalShapesParamsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Antipad clearance</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AntipadSizeText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANTIPAD_SIZE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AntipadSizeValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Clearance between pads in the same net and filled areas.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Spoke width</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CopperBridgeWidthText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_COPPER_BRIDGE_VALUE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CopperWidthValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Width of copper in thermal reliefs.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_MiddleBox</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Priority level:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText171</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Zones are filled by priority level, level 3 has higher priority than level 2.&#x0A;When a zone is inside an other zone:&#x0A;* If its priority is higher, its outlines are removed from the other zone.&#x0A;* If its priority is equal, a DRC error is set.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_PRIORITYLEVELCTRL</property>
+ <property name="initial">0</property>
+ <property name="max">100</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PriorityLevelCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Fill mode:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText11</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Polygon&quot; &quot;Segment&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_FILLMODECTRL</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FillModeCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Segments / 360 deg:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText12</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;16&quot; &quot;32&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_ARCAPPROXIMATIONOPT</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ArcApproximationOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerLowerRight</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Outline slope:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText14</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Arbitrary&quot; &quot;H, V, and 45 deg only&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_ORIENTEDGESOPT</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OrientEdgesOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Outline style:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText15</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Line&quot; &quot;Hatched&quot; &quot;Fully hatched&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_M_OUTLINEAPPEARANCECTRL</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OutlineAppearanceCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerbottom</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_BUTTON_EXPORT</property>
+ <property name="label">Export Settings to Other Zones</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ExportSetupButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Export this zone setup (excluding layer and net selection) to all other copper zones.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">ExportSetupToOtherCopperZones</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnButtonCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnButtonOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_copper_zones_base.h b/pcbnew/dialogs/dialog_copper_zones_base.h
new file mode 100644
index 0000000..d3c9c93
--- /dev/null
+++ b/pcbnew/dialogs/dialog_copper_zones_base.h
@@ -0,0 +1,135 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_COPPER_ZONES_BASE_H__
+#define __DIALOG_COPPER_ZONES_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class wxListView;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/listctrl.h>
+#include <wx/sizer.h>
+#include <wx/listbox.h>
+#include <wx/choice.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/statbox.h>
+#include <wx/spinctrl.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_COPPER_ZONE_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_COPPER_ZONE_BASE : public DIALOG_SHIM
+{
+ DECLARE_EVENT_TABLE()
+ private:
+
+ // Private event handlers
+ void _wxFB_OnClose( wxCloseEvent& event ){ OnClose( event ); }
+ void _wxFB_OnNetSortingOptionSelected( wxCommandEvent& event ){ OnNetSortingOptionSelected( event ); }
+ void _wxFB_OnRunFiltersButtonClick( wxCommandEvent& event ){ OnRunFiltersButtonClick( event ); }
+ void _wxFB_OnCornerSmoothingModeChoice( wxCommandEvent& event ){ OnCornerSmoothingModeChoice( event ); }
+ void _wxFB_OnPadsInZoneClick( wxCommandEvent& event ){ OnPadsInZoneClick( event ); }
+ void _wxFB_ExportSetupToOtherCopperZones( wxCommandEvent& event ){ ExportSetupToOtherCopperZones( event ); }
+ void _wxFB_OnButtonCancelClick( wxCommandEvent& event ){ OnButtonCancelClick( event ); }
+ void _wxFB_OnButtonOkClick( wxCommandEvent& event ){ OnButtonOkClick( event ); }
+
+
+ protected:
+ enum
+ {
+ ID_DIALOG_COPPER_ZONE_BASE = 1000,
+ ID_NETNAME_SELECTION,
+ ID_M_NETDISPLAYOPTION,
+ ID_TEXTCTRL_NETNAMES_FILTER,
+ wxID_APPLY_FILTERS,
+ ID_CORNER_SMOOTHING,
+ ID_M_CORNERSMOOTHINGCTRL,
+ ID_M_PADINZONEOPT,
+ wxID_ANTIPAD_SIZE,
+ wxID_COPPER_BRIDGE_VALUE,
+ ID_M_PRIORITYLEVELCTRL,
+ ID_M_FILLMODECTRL,
+ ID_M_ARCAPPROXIMATIONOPT,
+ ID_M_ORIENTEDGESOPT,
+ ID_M_OUTLINEAPPEARANCECTRL,
+ wxID_BUTTON_EXPORT
+ };
+
+ wxBoxSizer* m_MainBoxSizer;
+ wxStaticText* m_staticText17;
+ wxListView* m_LayerSelectionCtrl;
+ wxStaticText* m_staticText2;
+ wxListBox* m_ListNetNameSelection;
+ wxStaticText* m_staticText16;
+ wxChoice* m_NetDisplayOption;
+ wxStaticText* m_staticText5;
+ wxTextCtrl* m_DoNotShowNetNameFilter;
+ wxStaticText* m_staticText51;
+ wxTextCtrl* m_ShowNetNameFilter;
+ wxButton* m_buttonRunFilter;
+ wxStaticText* m_ClearanceValueTitle;
+ wxTextCtrl* m_ZoneClearanceCtrl;
+ wxStaticText* m_MinThicknessValueTitle;
+ wxTextCtrl* m_ZoneMinThicknessCtrl;
+ wxStaticText* m_staticText151;
+ wxChoice* m_cornerSmoothingChoice;
+ wxStaticText* m_cornerSmoothingTitle;
+ wxTextCtrl* m_cornerSmoothingCtrl;
+ wxStaticText* m_staticText13;
+ wxChoice* m_PadInZoneOpt;
+ wxStaticText* m_AntipadSizeText;
+ wxTextCtrl* m_AntipadSizeValue;
+ wxStaticText* m_CopperBridgeWidthText;
+ wxTextCtrl* m_CopperWidthValue;
+ wxStaticText* m_staticText171;
+ wxSpinCtrl* m_PriorityLevelCtrl;
+ wxStaticText* m_staticText11;
+ wxChoice* m_FillModeCtrl;
+ wxStaticText* m_staticText12;
+ wxChoice* m_ArcApproximationOpt;
+ wxStaticText* m_staticText14;
+ wxChoice* m_OrientEdgesOpt;
+ wxStaticText* m_staticText15;
+ wxChoice* m_OutlineAppearanceCtrl;
+ wxButton* m_ExportSetupButton;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnNetSortingOptionSelected( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRunFiltersButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCornerSmoothingModeChoice( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPadsInZoneClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void ExportSetupToOtherCopperZones( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID id = ID_DIALOG_COPPER_ZONE_BASE, const wxString& title = _("Copper Zone Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 567,507 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_COPPER_ZONE_BASE();
+
+};
+
+#endif //__DIALOG_COPPER_ZONES_BASE_H__
diff --git a/pcbnew/dialogs/dialog_create_array.cpp b/pcbnew/dialogs/dialog_create_array.cpp
new file mode 100644
index 0000000..ee63520
--- /dev/null
+++ b/pcbnew/dialogs/dialog_create_array.cpp
@@ -0,0 +1,488 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 John Beard, john.j.beard@gmail.com
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wxPcbStruct.h>
+#include <base_units.h>
+#include <macros.h>
+
+#include <class_drawpanel.h>
+#include <class_board.h>
+#include <class_module.h>
+
+#include "dialog_create_array.h"
+
+
+// initialise statics
+DIALOG_CREATE_ARRAY::CREATE_ARRAY_DIALOG_ENTRIES DIALOG_CREATE_ARRAY::m_options;
+
+
+DIALOG_CREATE_ARRAY::DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrigPos,
+ ARRAY_OPTIONS** aSettings ) :
+ DIALOG_CREATE_ARRAY_BASE( aParent ),
+ CONFIG_SAVE_RESTORE_WINDOW( m_options.m_optionsSet ),
+ m_settings( aSettings ),
+ m_originalItemPosition( aOrigPos )
+{
+ // Set up numbering scheme drop downs
+ //
+ // character set
+ // NOTE: do not change the order of this relative to the ARRAY_NUMBERING_TYPE_T enum
+ const wxString charSetDescriptions[] =
+ {
+ _( "Numerals (0,1,2,...,9,10)" ),
+ _( "Hexadecimal (0,1,...,F,10,...)" ),
+ _( "Alphabet, minus IOSQXZ" ),
+ _( "Alphabet, full 26 characters" )
+ };
+ m_choicePriAxisNumbering->Set( DIM( charSetDescriptions ), charSetDescriptions );
+ m_choiceSecAxisNumbering->Set( DIM( charSetDescriptions ), charSetDescriptions );
+
+ m_choicePriAxisNumbering->SetSelection( 0 );
+ m_choiceSecAxisNumbering->SetSelection( 0 );
+
+ Add( m_entryNx, m_options.m_gridNx );
+ Add( m_entryNy, m_options.m_gridNy );
+ Add( m_entryDx, m_options.m_gridDx );
+ Add( m_entryDy, m_options.m_gridDy );
+
+ Add( m_entryOffsetX, m_options.m_gridOffsetX );
+ Add( m_entryOffsetY, m_options.m_gridOffsetY );
+ Add( m_entryStagger, m_options.m_gridStagger );
+
+ Add( m_radioBoxGridStaggerType, m_options.m_gridStaggerType );
+
+ Add( m_radioBoxGridNumberingAxis, m_options.m_gridNumberingAxis );
+ Add( m_checkBoxGridReverseNumbering, m_options.m_gridNumberingReverseAlternate );
+
+ Add( m_entryCentreX, m_options.m_circCentreX );
+ Add( m_entryCentreY, m_options.m_circCentreY );
+ Add( m_entryCircAngle, m_options.m_circAngle );
+ Add( m_entryCircCount, m_options.m_circCount );
+ Add( m_entryRotateItemsCb, m_options.m_circRotate );
+ Add( m_entryCircNumberingStart, m_options.m_circNumberingOffset );
+
+ Add( m_gridTypeNotebook, m_options.m_arrayTypeTab );
+
+ Add( m_radioBoxGridNumberingScheme, m_options.m_grid2dArrayNumbering );
+ Add( m_choicePriAxisNumbering, m_options.m_gridPriAxisNumScheme );
+ Add( m_choiceSecAxisNumbering, m_options.m_gridSecAxisNumScheme );
+
+ Add( m_entryGridPriNumberingOffset, m_options.m_gridPriNumberingOffset );
+ Add( m_entryGridSecNumberingOffset, m_options.m_gridSecNumberingOffset );
+
+ Add( m_rbGridStartNumberingOpt, m_options.m_gridNumberingScheme );
+ Add( m_rbCircStartNumberingOpt, m_options.m_circNumberingScheme );
+
+ RestoreConfigToControls();
+
+ // Load units into labels
+ {
+ const wxString lengthUnit = GetAbbreviatedUnitsLabel( g_UserUnit );
+
+ m_unitLabelCentreX->SetLabelText( lengthUnit );
+ m_unitLabelCentreY->SetLabelText( lengthUnit );
+ m_unitLabelDx->SetLabelText( lengthUnit );
+ m_unitLabelDy->SetLabelText( lengthUnit );
+ m_unitLabelOffsetX->SetLabelText( lengthUnit );
+ m_unitLabelOffsetY->SetLabelText( lengthUnit );
+ }
+
+ // Run the callbacks once to process the dialog contents
+ setControlEnablement();
+ calculateCircularArrayProperties();
+
+ m_stdButtonsOK->SetDefault();
+ Fit();
+ SetMinSize( GetSize() );
+}
+
+
+void DIALOG_CREATE_ARRAY::OnParameterChanged( wxCommandEvent& event )
+{
+ setControlEnablement();
+ calculateCircularArrayProperties();
+}
+
+
+static const std::string& alphabetFromNumberingScheme(
+ DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T type )
+{
+ static const std::string alphaNumeric = "0123456789";
+ static const std::string alphaHex = "0123456789ABCDEF";
+ static const std::string alphaFull = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ static const std::string alphaNoIOSQXZ = "ABCDEFGHJKLMNPRTUVWY";
+
+ switch( type )
+ {
+ default:
+ case DIALOG_CREATE_ARRAY::NUMBERING_NUMERIC:
+ break;
+
+ case DIALOG_CREATE_ARRAY::NUMBERING_HEX:
+ return alphaHex;
+
+ case DIALOG_CREATE_ARRAY::NUMBERING_ALPHA_NO_IOSQXZ:
+ return alphaNoIOSQXZ;
+
+ case DIALOG_CREATE_ARRAY::NUMBERING_ALPHA_FULL:
+ return alphaFull;
+ }
+
+ return alphaNumeric;
+}
+
+
+/**
+ * @return False for schemes like 0,1...9,10
+ * True for schemes like A,B..Z,AA (where the tens column starts with char 0)
+ */
+static bool schemeNonUnitColsStartAt0( DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T type )
+{
+ return type == DIALOG_CREATE_ARRAY::NUMBERING_ALPHA_FULL
+ || type == DIALOG_CREATE_ARRAY::NUMBERING_ALPHA_NO_IOSQXZ;
+}
+
+
+static bool getNumberingOffset( const std::string& str,
+ DIALOG_CREATE_ARRAY::ARRAY_NUMBERING_TYPE_T type,
+ int& offsetToFill )
+{
+ const std::string alphabet = alphabetFromNumberingScheme( type );
+
+ int offset = 0;
+ const int radix = alphabet.length();
+
+ for( unsigned i = 0; i < str.length(); i++ )
+ {
+ int chIndex = alphabet.find( str[i], 0 );
+
+ if( chIndex == wxNOT_FOUND )
+ return false;
+
+ const bool start0 = schemeNonUnitColsStartAt0( type );
+
+ // eg "AA" is actually index 27, not 26
+ if( start0 && i < str.length() - 1 )
+ chIndex++;
+
+ offset *= radix;
+ offset += chIndex;
+ }
+
+ offsetToFill = offset;
+ return true;
+}
+
+
+void DIALOG_CREATE_ARRAY::OnOkClick( wxCommandEvent& event )
+{
+ ARRAY_OPTIONS* newSettings = NULL;
+
+ const wxWindow* page = m_gridTypeNotebook->GetCurrentPage();
+
+ if( page == m_gridPanel )
+ {
+ ARRAY_GRID_OPTIONS* newGrid = new ARRAY_GRID_OPTIONS();
+ bool ok = true;
+
+ // ints
+ ok = ok && m_entryNx->GetValue().ToLong( &newGrid->m_nx );
+ ok = ok && m_entryNy->GetValue().ToLong( &newGrid->m_ny );
+
+ newGrid->m_delta.x = DoubleValueFromString( g_UserUnit, m_entryDx->GetValue() );
+ newGrid->m_delta.y = DoubleValueFromString( g_UserUnit, m_entryDy->GetValue() );
+
+ newGrid->m_offset.x = DoubleValueFromString( g_UserUnit, m_entryOffsetX->GetValue() );
+ newGrid->m_offset.y = DoubleValueFromString( g_UserUnit, m_entryOffsetY->GetValue() );
+
+ ok = ok && m_entryStagger->GetValue().ToLong( &newGrid->m_stagger );
+
+ newGrid->m_stagger_rows = m_radioBoxGridStaggerType->GetSelection() == 0;
+
+ newGrid->m_horizontalThenVertical = m_radioBoxGridNumberingAxis->GetSelection() == 0;
+ newGrid->m_reverseNumberingAlternate = m_checkBoxGridReverseNumbering->GetValue();
+
+ newGrid->m_2dArrayNumbering = m_radioBoxGridNumberingScheme->GetSelection() != 0;
+
+ // this is only correct if you set the choice up according to the enum size and order
+ ok = ok && m_choicePriAxisNumbering->GetSelection() <= NUMBERING_TYPE_MAX
+ && m_choiceSecAxisNumbering->GetSelection() <= NUMBERING_TYPE_MAX;
+
+ // mind undefined casts to enums (should not be able to happen)
+ if( ok )
+ {
+ newGrid->m_priAxisNumType =
+ (ARRAY_NUMBERING_TYPE_T) m_choicePriAxisNumbering->GetSelection();
+ newGrid->m_secAxisNumType =
+ (ARRAY_NUMBERING_TYPE_T) m_choiceSecAxisNumbering->GetSelection();
+ }
+
+ // Work out the offsets for the numbering
+ ok = ok && getNumberingOffset(
+ m_entryGridPriNumberingOffset->GetValue().ToStdString(),
+ newGrid->m_priAxisNumType, newGrid->m_numberingOffsetX );
+
+ if( newGrid->m_2dArrayNumbering )
+ ok = ok && getNumberingOffset(
+ m_entryGridSecNumberingOffset->GetValue().ToStdString(),
+ newGrid->m_secAxisNumType, newGrid->m_numberingOffsetY );
+
+ newGrid->m_shouldRenumber = m_rbGridStartNumberingOpt->GetSelection() == 1;
+
+ // Only use settings if all values are good
+ if( ok )
+ newSettings = newGrid;
+ else
+ delete newGrid;
+ }
+ else if( page == m_circularPanel )
+ {
+ ARRAY_CIRCULAR_OPTIONS* newCirc = new ARRAY_CIRCULAR_OPTIONS();
+ bool ok = true;
+
+ newCirc->m_centre.x = DoubleValueFromString( g_UserUnit, m_entryCentreX->GetValue() );
+ newCirc->m_centre.y = DoubleValueFromString( g_UserUnit, m_entryCentreY->GetValue() );
+
+ newCirc->m_angle = DoubleValueFromString( DEGREES, m_entryCircAngle->GetValue() );
+ ok = ok && m_entryCircCount->GetValue().ToLong( &newCirc->m_nPts );
+
+ newCirc->m_rotateItems = m_entryRotateItemsCb->GetValue();
+ newCirc->m_shouldRenumber = m_rbCircStartNumberingOpt->GetSelection() == 1;
+ newCirc->m_numberingType = NUMBERING_NUMERIC;
+
+ ok = ok && m_entryCircNumberingStart->GetValue().ToLong( &newCirc->m_numberingOffset );
+
+ // Only use settings if all values are good
+ if( ok )
+ newSettings = newCirc;
+ else
+ delete newCirc;
+ }
+
+ // If we got good settings, send them out and finish
+ if( newSettings )
+ {
+ delete *m_settings;
+
+ // assign pointer and ownership here
+ *m_settings = newSettings;
+ ReadConfigFromControls();
+
+ EndModal( wxID_OK );
+ }
+
+ else
+ wxMessageBox( _("Bad parameters" ) );
+}
+
+
+void DIALOG_CREATE_ARRAY::setControlEnablement()
+{
+ const bool renumber = m_rbGridStartNumberingOpt->GetSelection() == 1;
+
+ // If we're not renumbering, we can't set the numbering scheme
+ // or axis numbering types
+ m_radioBoxGridNumberingScheme->Enable( renumber );
+ m_labelPriAxisNumbering->Enable( renumber );
+ m_choicePriAxisNumbering->Enable( renumber );
+
+ // Disable the secondary axis numbering option if the
+ // numbering scheme doesn't have two axes
+ const bool num2d = m_radioBoxGridNumberingScheme->GetSelection() != 0;
+
+ m_labelSecAxisNumbering->Enable( renumber && num2d );
+ m_choiceSecAxisNumbering->Enable( renumber && num2d );
+
+ // We can only set an offset if we renumber
+ m_labelGridNumberingOffset->Enable( renumber );
+ m_entryGridPriNumberingOffset->Enable( renumber );
+ m_entryGridSecNumberingOffset->Enable( renumber && num2d );
+
+ m_entryCircNumberingStart->Enable( m_rbCircStartNumberingOpt->GetSelection() == 1 );
+}
+
+
+void DIALOG_CREATE_ARRAY::calculateCircularArrayProperties()
+{
+ wxPoint centre;
+
+ centre.x = DoubleValueFromString( g_UserUnit, m_entryCentreX->GetValue() );
+ centre.y = DoubleValueFromString( g_UserUnit, m_entryCentreY->GetValue() );
+
+ // Find the radius, etc of the circle
+ centre -= m_originalItemPosition;
+
+ const double radius = VECTOR2I(centre.x, centre.y).EuclideanNorm();
+ m_labelCircRadiusValue->SetLabelText( StringFromValue( g_UserUnit, int(radius), true ) );
+}
+
+
+// ARRAY OPTION implementation functions --------------------------------------
+
+std::string DIALOG_CREATE_ARRAY::ARRAY_OPTIONS::getCoordinateNumber( int n,
+ ARRAY_NUMBERING_TYPE_T type )
+{
+ std::string itemNum;
+ const std::string& alphabet = alphabetFromNumberingScheme( type );
+
+ const bool nonUnitColsStartAt0 = schemeNonUnitColsStartAt0( type );
+
+ bool firstRound = true;
+ int radix = alphabet.length();
+
+ do {
+ int modN = n % radix;
+
+ if( nonUnitColsStartAt0 && !firstRound )
+ modN--; // Start the "tens/hundreds/etc column" at "Ax", not "Bx"
+
+ itemNum.insert( 0, 1, alphabet[modN] );
+
+ n /= radix;
+ firstRound = false;
+ } while( n );
+
+ return itemNum;
+}
+
+
+wxString DIALOG_CREATE_ARRAY::ARRAY_OPTIONS::InterpolateNumberIntoString(
+ int aN, const wxString& aPattern ) const
+{
+ wxString newStr( aPattern );
+ newStr.Replace( "%s", GetItemNumber( aN ), false );
+
+ return newStr;
+}
+
+
+int DIALOG_CREATE_ARRAY::ARRAY_GRID_OPTIONS::GetArraySize() const
+{
+ return m_nx * m_ny;
+}
+
+
+wxPoint DIALOG_CREATE_ARRAY::ARRAY_GRID_OPTIONS::getGridCoords( int n ) const
+{
+ const int axisSize = m_horizontalThenVertical ? m_nx : m_ny;
+
+ int x = n % axisSize;
+ int y = n / axisSize;
+
+ // reverse on this row/col?
+ if( m_reverseNumberingAlternate && ( y % 2 ) )
+ x = axisSize - x - 1;
+
+ wxPoint coords( x, y );
+
+ return coords;
+}
+
+
+void DIALOG_CREATE_ARRAY::ARRAY_GRID_OPTIONS::TransformItem( int n, BOARD_ITEM* item,
+ const wxPoint& rotPoint ) const
+{
+ wxPoint point;
+
+ wxPoint coords = getGridCoords( n );
+
+ // swap axes if needed
+ if( !m_horizontalThenVertical )
+ std::swap( coords.x, coords.y );
+
+ point.x = coords.x * m_delta.x + coords.y * m_offset.x;
+ point.y = coords.y * m_delta.y + coords.x * m_offset.y;
+
+ if( std::abs( m_stagger ) > 1 )
+ {
+ const int stagger = std::abs( m_stagger );
+ const bool sr = m_stagger_rows;
+ const int stagger_idx = ( ( sr ? coords.y : coords.x ) % stagger );
+
+ wxPoint stagger_delta( ( sr ? m_delta.x : m_offset.x ),
+ ( sr ? m_offset.y : m_delta.y ) );
+
+ // Stagger to the left/up if the sign of the stagger is negative
+ point += stagger_delta * copysign( stagger_idx, m_stagger ) / stagger;
+ }
+
+ // this is already relative to the first array entry
+ item->Move( point );
+}
+
+
+wxString DIALOG_CREATE_ARRAY::ARRAY_GRID_OPTIONS::GetItemNumber( int n ) const
+{
+ wxString itemNum;
+
+ if( m_2dArrayNumbering )
+ {
+ wxPoint coords = getGridCoords( n );
+
+ itemNum += getCoordinateNumber( coords.x + m_numberingOffsetX, m_priAxisNumType );
+ itemNum += getCoordinateNumber( coords.y + m_numberingOffsetY, m_secAxisNumType );
+ }
+ else
+ {
+ itemNum += getCoordinateNumber( n + m_numberingOffsetX, m_priAxisNumType );
+ }
+
+ return itemNum;
+}
+
+
+int DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::GetArraySize() const
+{
+ return m_nPts;
+}
+
+
+void DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::TransformItem( int n, BOARD_ITEM* item,
+ const wxPoint& rotPoint ) const
+{
+ double angle;
+
+ if( m_angle == 0 )
+ // angle is zero, divide evenly into m_nPts
+ angle = 3600.0 * n / double( m_nPts );
+ else
+ // n'th step
+ angle = m_angle * n;
+
+ item->Rotate( m_centre, angle );
+
+ // take off the rotation (but not the translation) if needed
+ if( !m_rotateItems )
+ item->Rotate( item->GetCenter(), -angle );
+}
+
+
+wxString DIALOG_CREATE_ARRAY::ARRAY_CIRCULAR_OPTIONS::GetItemNumber( int aN ) const
+{
+ // The first new pad has aN number == 1, not 0
+ if( m_shouldRenumber ) // numbering pad from initial user value
+ return getCoordinateNumber( aN - 1 + m_numberingOffset, m_numberingType );
+ else // numbering pad from inital pad number
+ return getCoordinateNumber( aN + m_numberingOffset, m_numberingType );
+}
diff --git a/pcbnew/dialogs/dialog_create_array.h b/pcbnew/dialogs/dialog_create_array.h
new file mode 100644
index 0000000..11aa83f
--- /dev/null
+++ b/pcbnew/dialogs/dialog_create_array.h
@@ -0,0 +1,355 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 John Beard, john.j.beard@gmail.com
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __DIALOG_CREATE_ARRAY__
+#define __DIALOG_CREATE_ARRAY__
+
+// Include the wxFormBuider header base:
+#include <dialog_create_array_base.h>
+
+#include <boost/bimap.hpp>
+
+class CONFIG_SAVE_RESTORE_WINDOW
+{
+private:
+
+ enum CONFIG_CTRL_TYPE_T
+ {
+ CFG_CTRL_TEXT,
+ CFG_CTRL_CHECKBOX,
+ CFG_CTRL_RADIOBOX,
+ CFG_CTRL_CHOICE,
+ CFG_CTRL_TAB
+ };
+
+ struct CONFIG_CTRL_T
+ {
+ wxControl* control;
+ CONFIG_CTRL_TYPE_T type;
+ void* dest;
+ };
+
+ std::vector<CONFIG_CTRL_T> ctrls;
+ bool& valid;
+
+protected:
+ CONFIG_SAVE_RESTORE_WINDOW( bool& validFlag ) :
+ valid( validFlag )
+ {}
+
+ void Add( wxRadioBox* ctrl, int& dest )
+ {
+ CONFIG_CTRL_T ctrlInfo = { ctrl, CFG_CTRL_RADIOBOX, (void*) &dest };
+
+ ctrls.push_back( ctrlInfo );
+ }
+
+ void Add( wxCheckBox* ctrl, bool& dest )
+ {
+ CONFIG_CTRL_T ctrlInfo = { ctrl, CFG_CTRL_CHECKBOX, (void*) &dest };
+
+ ctrls.push_back( ctrlInfo );
+ }
+
+ void Add( wxTextCtrl* ctrl, std::string& dest )
+ {
+ CONFIG_CTRL_T ctrlInfo = { ctrl, CFG_CTRL_TEXT, (void*) &dest };
+
+ ctrls.push_back( ctrlInfo );
+ }
+
+ void Add( wxChoice* ctrl, int& dest )
+ {
+ CONFIG_CTRL_T ctrlInfo = { ctrl, CFG_CTRL_CHOICE, (void*) &dest };
+
+ ctrls.push_back( ctrlInfo );
+ }
+
+ void Add( wxNotebook* ctrl, int& dest )
+ {
+ CONFIG_CTRL_T ctrlInfo = { ctrl, CFG_CTRL_TAB, (void*) &dest };
+
+ ctrls.push_back( ctrlInfo );
+ }
+
+ void ReadConfigFromControls()
+ {
+ for( std::vector<CONFIG_CTRL_T>::const_iterator iter = ctrls.begin(), iend = ctrls.end();
+ iter != iend; ++iter )
+ {
+ switch( iter->type )
+ {
+ case CFG_CTRL_CHECKBOX:
+ *(bool*) iter->dest = static_cast<wxCheckBox*>( iter->control )->GetValue();
+ break;
+
+ case CFG_CTRL_TEXT:
+ *(std::string*) iter->dest = static_cast<wxTextCtrl*>( iter->control )->GetValue();
+ break;
+
+ case CFG_CTRL_CHOICE:
+ *(int*) iter->dest = static_cast<wxChoice*>( iter->control )->GetSelection();
+ break;
+
+ case CFG_CTRL_RADIOBOX:
+ *(int*) iter->dest = static_cast<wxRadioBox*>( iter->control )->GetSelection();
+ break;
+
+ case CFG_CTRL_TAB:
+ *(int*) iter->dest = static_cast<wxNotebook*>( iter->control )->GetSelection();
+ break;
+
+ default:
+ wxASSERT_MSG( false, wxString(
+ "Unhandled control type for config store: " ) << iter->type );
+ }
+ }
+
+ valid = true;
+ }
+
+ void RestoreConfigToControls()
+ {
+ if( !valid )
+ return;
+
+ for( std::vector<CONFIG_CTRL_T>::const_iterator iter = ctrls.begin(), iend = ctrls.end();
+ iter != iend; ++iter )
+ {
+ switch( iter->type )
+ {
+ case CFG_CTRL_CHECKBOX:
+ static_cast<wxCheckBox*>( iter->control )->SetValue( *(bool*) iter->dest );
+ break;
+
+ case CFG_CTRL_TEXT:
+ static_cast<wxTextCtrl*>( iter->control )->SetValue( *(std::string*) iter->dest );
+ break;
+
+ case CFG_CTRL_CHOICE:
+ static_cast<wxChoice*>( iter->control )->SetSelection( *(int*) iter->dest );
+ break;
+
+ case CFG_CTRL_RADIOBOX:
+ static_cast<wxRadioBox*>( iter->control )->SetSelection( *(int*) iter->dest );
+ break;
+
+ case CFG_CTRL_TAB:
+ static_cast<wxNotebook*>( iter->control )->SetSelection( *(int*) iter->dest );
+ break;
+
+ default:
+ wxASSERT_MSG( false, wxString(
+ "Unhandled control type for config restore: " ) << iter->type );
+ }
+ }
+ }
+};
+
+class DIALOG_CREATE_ARRAY : public DIALOG_CREATE_ARRAY_BASE,
+ public CONFIG_SAVE_RESTORE_WINDOW
+{
+public:
+
+ enum ARRAY_TYPE_T
+ {
+ ARRAY_GRID, ///< A grid (x*y) array
+ ARRAY_CIRCULAR, ///< A circular array
+ };
+
+ // NOTE: do not change order relative to charSetDescriptions
+ enum ARRAY_NUMBERING_TYPE_T
+ {
+ NUMBERING_NUMERIC = 0, ///< Arabic numerals: 0,1,2,3,4,5,6,7,8,9,10,11...
+ NUMBERING_HEX,
+ NUMBERING_ALPHA_NO_IOSQXZ, /*!< Alphabet, excluding IOSQXZ
+ *
+ * Per ASME Y14.35M-1997 sec. 5.2 (previously MIL-STD-100 sec. 406.5)
+ * as these can be confused with numerals and are often not used
+ * for pin numbering on BGAs, etc
+ */
+ NUMBERING_ALPHA_FULL, ///< Full 26-character alphabet
+ };
+
+ #define NUMBERING_TYPE_MAX NUMBERING_ALPHA_FULL
+
+ /**
+ * Persistent dialog options
+ */
+ struct ARRAY_OPTIONS
+ {
+ ARRAY_OPTIONS( ARRAY_TYPE_T aType ) :
+ m_type( aType ),
+ m_shouldRenumber( false )
+ {}
+
+ virtual ~ARRAY_OPTIONS() {};
+
+ ARRAY_TYPE_T m_type;
+ bool m_shouldRenumber;
+
+ /*!
+ * Function GetArrayPositions
+ * Returns the set of points that represent the array
+ * in order, if that is important
+ *
+ * TODO: Can/should this be done with some sort of iterator?
+ */
+ virtual void TransformItem( int n, BOARD_ITEM* item,
+ const wxPoint& rotPoint ) const = 0;
+ virtual int GetArraySize() const = 0;
+ virtual wxString GetItemNumber( int n ) const = 0;
+ virtual wxString InterpolateNumberIntoString( int n, const wxString& pattern ) const;
+
+ bool ShouldRenumberItems() const
+ {
+ return m_shouldRenumber;
+ }
+
+protected:
+ static std::string getCoordinateNumber( int n, ARRAY_NUMBERING_TYPE_T type );
+ };
+
+ struct ARRAY_GRID_OPTIONS : public ARRAY_OPTIONS
+ {
+ ARRAY_GRID_OPTIONS() :
+ ARRAY_OPTIONS( ARRAY_GRID ),
+ m_nx( 0 ), m_ny( 0 ),
+ m_horizontalThenVertical( true ),
+ m_reverseNumberingAlternate( false ),
+ m_stagger( 0 ),
+ m_stagger_rows( true ),
+ m_2dArrayNumbering( false ),
+ m_numberingOffsetX( 0 ),
+ m_numberingOffsetY( 0 ),
+ m_priAxisNumType( NUMBERING_NUMERIC ),
+ m_secAxisNumType( NUMBERING_NUMERIC )
+ {}
+
+ long m_nx, m_ny;
+ bool m_horizontalThenVertical, m_reverseNumberingAlternate;
+ wxPoint m_delta;
+ wxPoint m_offset;
+ long m_stagger;
+ bool m_stagger_rows;
+ bool m_2dArrayNumbering;
+ int m_numberingOffsetX, m_numberingOffsetY;
+ ARRAY_NUMBERING_TYPE_T m_priAxisNumType, m_secAxisNumType;
+
+ void TransformItem( int n, BOARD_ITEM* item, const wxPoint& rotPoint ) const; // override virtual
+ int GetArraySize() const; // override virtual
+ wxString GetItemNumber( int n ) const; // override virtual
+
+private:
+ wxPoint getGridCoords( int n ) const;
+ };
+
+ struct ARRAY_CIRCULAR_OPTIONS : public ARRAY_OPTIONS
+ {
+ ARRAY_CIRCULAR_OPTIONS() :
+ ARRAY_OPTIONS( ARRAY_CIRCULAR ),
+ m_nPts( 0 ),
+ m_angle( 0.0f ),
+ m_rotateItems( false ),
+ m_numberingType( NUMBERING_NUMERIC ),
+ m_numberingOffset( 0 )
+ {}
+
+ long m_nPts;
+ double m_angle;
+ wxPoint m_centre;
+ bool m_rotateItems;
+ ARRAY_NUMBERING_TYPE_T m_numberingType;
+ long m_numberingOffset;
+
+ void TransformItem( int n, BOARD_ITEM* item, const wxPoint& rotPoint ) const; // override virtual
+ int GetArraySize() const; // override virtual
+ wxString GetItemNumber( int n ) const; // override virtual
+ };
+
+ // Constructor and destructor
+ DIALOG_CREATE_ARRAY( PCB_BASE_FRAME* aParent, wxPoint aOrigPos, ARRAY_OPTIONS** settings );
+ virtual ~DIALOG_CREATE_ARRAY() {};
+
+private:
+
+ /**
+ * The settings object returned to the caller.
+ * We update the caller's object and never have ownership
+ */
+ ARRAY_OPTIONS** m_settings;
+
+ /*
+ * The position of the original item(s), used for finding radius, etc
+ */
+ const wxPoint m_originalItemPosition;
+
+ // Event callbacks
+ void OnParameterChanged( wxCommandEvent& event );
+ void OnOkClick( wxCommandEvent& event );
+
+ // Internal callback handlers
+ void setControlEnablement();
+ void calculateCircularArrayProperties();
+
+ struct CREATE_ARRAY_DIALOG_ENTRIES
+ {
+ CREATE_ARRAY_DIALOG_ENTRIES() :
+ m_optionsSet( false ),
+ m_gridStaggerType( 0 ),
+ m_gridNumberingAxis( 0 ),
+ m_gridNumberingReverseAlternate( false ),
+ m_grid2dArrayNumbering( 0 ),
+ m_gridPriAxisNumScheme( 0 ),
+ m_gridSecAxisNumScheme( 0 ),
+ m_circRotate( false ),
+ m_arrayTypeTab( 0 )
+ {}
+
+ bool m_optionsSet;
+
+ std::string m_gridNx, m_gridNy,
+ m_gridDx, m_gridDy,
+ m_gridOffsetX, m_gridOffsetY,
+ m_gridStagger;
+
+ int m_gridStaggerType, m_gridNumberingAxis;
+ bool m_gridNumberingReverseAlternate;
+ int m_grid2dArrayNumbering;
+ int m_gridPriAxisNumScheme, m_gridSecAxisNumScheme;
+ std::string m_gridPriNumberingOffset, m_gridSecNumberingOffset;
+
+ std::string m_circCentreX, m_circCentreY,
+ m_circAngle, m_circCount, m_circNumberingOffset;
+ bool m_circRotate;
+ int m_arrayTypeTab;
+ int m_gridNumberingScheme;
+ int m_circNumberingScheme;
+ };
+
+ static CREATE_ARRAY_DIALOG_ENTRIES m_options;
+
+};
+
+#endif // __DIALOG_CREATE_ARRAY__
diff --git a/pcbnew/dialogs/dialog_create_array_base.cpp b/pcbnew/dialogs/dialog_create_array_base.cpp
new file mode 100644
index 0000000..f9e7b43
--- /dev/null
+++ b/pcbnew/dialogs/dialog_create_array_base.cpp
@@ -0,0 +1,332 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jan 1 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_create_array_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_gridTypeNotebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_gridPanel = new wxPanel( m_gridTypeNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* bSizer2;
+ bSizer2 = new wxBoxSizer( wxHORIZONTAL );
+
+ wxGridBagSizer* gbSizer1;
+ gbSizer1 = new wxGridBagSizer( 0, 0 );
+ gbSizer1->SetFlexibleDirection( wxBOTH );
+ gbSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_labelNx = new wxStaticText( m_gridPanel, wxID_ANY, _("Horizontal count:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelNx->Wrap( -1 );
+ gbSizer1->Add( m_labelNx, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_RIGHT|wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_entryNx = new wxTextCtrl( m_gridPanel, wxID_ANY, _("5"), wxDefaultPosition, wxDefaultSize, 0 );
+ gbSizer1->Add( m_entryNx, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_labelNy = new wxStaticText( m_gridPanel, wxID_ANY, _("Vertical count:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelNy->Wrap( -1 );
+ gbSizer1->Add( m_labelNy, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_RIGHT|wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_entryNy = new wxTextCtrl( m_gridPanel, wxID_ANY, _("5"), wxDefaultPosition, wxDefaultSize, 0 );
+ gbSizer1->Add( m_entryNy, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_labelDx = new wxStaticText( m_gridPanel, wxID_ANY, _("Horizontal spacing:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelDx->Wrap( -1 );
+ gbSizer1->Add( m_labelDx, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_entryDx = new wxTextCtrl( m_gridPanel, wxID_ANY, _("5"), wxDefaultPosition, wxDefaultSize, 0 );
+ gbSizer1->Add( m_entryDx, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_unitLabelDx = new wxStaticText( m_gridPanel, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_unitLabelDx->Wrap( -1 );
+ gbSizer1->Add( m_unitLabelDx, wxGBPosition( 2, 2 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_labelDy = new wxStaticText( m_gridPanel, wxID_ANY, _("Vertical spacing:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelDy->Wrap( -1 );
+ gbSizer1->Add( m_labelDy, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_entryDy = new wxTextCtrl( m_gridPanel, wxID_ANY, _("5"), wxDefaultPosition, wxDefaultSize, 0 );
+ gbSizer1->Add( m_entryDy, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_unitLabelDy = new wxStaticText( m_gridPanel, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_unitLabelDy->Wrap( -1 );
+ gbSizer1->Add( m_unitLabelDy, wxGBPosition( 3, 2 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_labelOffsetX = new wxStaticText( m_gridPanel, wxID_ANY, _("Horizontal offset:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelOffsetX->Wrap( -1 );
+ gbSizer1->Add( m_labelOffsetX, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_entryOffsetX = new wxTextCtrl( m_gridPanel, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ gbSizer1->Add( m_entryOffsetX, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_unitLabelOffsetX = new wxStaticText( m_gridPanel, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_unitLabelOffsetX->Wrap( -1 );
+ gbSizer1->Add( m_unitLabelOffsetX, wxGBPosition( 4, 2 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_labelOffsetY = new wxStaticText( m_gridPanel, wxID_ANY, _("Vertical offset:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelOffsetY->Wrap( -1 );
+ gbSizer1->Add( m_labelOffsetY, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_entryOffsetY = new wxTextCtrl( m_gridPanel, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ gbSizer1->Add( m_entryOffsetY, wxGBPosition( 5, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_unitLabelOffsetY = new wxStaticText( m_gridPanel, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_unitLabelOffsetY->Wrap( -1 );
+ gbSizer1->Add( m_unitLabelOffsetY, wxGBPosition( 5, 2 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_labelStagger = new wxStaticText( m_gridPanel, wxID_ANY, _("Stagger:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelStagger->Wrap( -1 );
+ gbSizer1->Add( m_labelStagger, wxGBPosition( 6, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_entryStagger = new wxTextCtrl( m_gridPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
+ gbSizer1->Add( m_entryStagger, wxGBPosition( 6, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ wxString m_radioBoxGridStaggerTypeChoices[] = { _("Rows"), _("Columns") };
+ int m_radioBoxGridStaggerTypeNChoices = sizeof( m_radioBoxGridStaggerTypeChoices ) / sizeof( wxString );
+ m_radioBoxGridStaggerType = new wxRadioBox( m_gridPanel, wxID_ANY, _("Stagger Type"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridStaggerTypeNChoices, m_radioBoxGridStaggerTypeChoices, 1, wxRA_SPECIFY_COLS );
+ m_radioBoxGridStaggerType->SetSelection( 1 );
+ gbSizer1->Add( m_radioBoxGridStaggerType, wxGBPosition( 7, 0 ), wxGBSpan( 2, 2 ), wxALL|wxEXPAND, 5 );
+
+
+ bSizer2->Add( gbSizer1, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer3;
+ bSizer3 = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_radioBoxGridNumberingAxisChoices[] = { _("Horizontal, then vertical"), _("Vertical, then horizontal") };
+ int m_radioBoxGridNumberingAxisNChoices = sizeof( m_radioBoxGridNumberingAxisChoices ) / sizeof( wxString );
+ m_radioBoxGridNumberingAxis = new wxRadioBox( m_gridPanel, wxID_ANY, _("Pad Numbering Direction"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingAxisNChoices, m_radioBoxGridNumberingAxisChoices, 1, wxRA_SPECIFY_COLS );
+ m_radioBoxGridNumberingAxis->SetSelection( 0 );
+ bSizer3->Add( m_radioBoxGridNumberingAxis, 0, wxALL|wxEXPAND, 5 );
+
+ m_checkBoxGridReverseNumbering = new wxCheckBox( m_gridPanel, wxID_ANY, _("Reverse pad numbering on alternate rows or columns"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer3->Add( m_checkBoxGridReverseNumbering, 0, wxALL, 5 );
+
+ wxString m_rbGridStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") };
+ int m_rbGridStartNumberingOptNChoices = sizeof( m_rbGridStartNumberingOptChoices ) / sizeof( wxString );
+ m_rbGridStartNumberingOpt = new wxRadioBox( m_gridPanel, wxID_ANY, _("Initial pad number"), wxDefaultPosition, wxDefaultSize, m_rbGridStartNumberingOptNChoices, m_rbGridStartNumberingOptChoices, 1, wxRA_SPECIFY_COLS );
+ m_rbGridStartNumberingOpt->SetSelection( 1 );
+ bSizer3->Add( m_rbGridStartNumberingOpt, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_radioBoxGridNumberingSchemeChoices[] = { _("Continuous (1, 2, 3...)"), _("Coordinate (A1, A2, ... B1, ...)") };
+ int m_radioBoxGridNumberingSchemeNChoices = sizeof( m_radioBoxGridNumberingSchemeChoices ) / sizeof( wxString );
+ m_radioBoxGridNumberingScheme = new wxRadioBox( m_gridPanel, wxID_ANY, _("Pad Numbering Scheme"), wxDefaultPosition, wxDefaultSize, m_radioBoxGridNumberingSchemeNChoices, m_radioBoxGridNumberingSchemeChoices, 1, wxRA_SPECIFY_COLS );
+ m_radioBoxGridNumberingScheme->SetSelection( 1 );
+ bSizer3->Add( m_radioBoxGridNumberingScheme, 0, wxALL|wxEXPAND, 5 );
+
+ m_labelPriAxisNumbering = new wxStaticText( m_gridPanel, wxID_ANY, _("Primary axis numbering:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelPriAxisNumbering->Wrap( -1 );
+ bSizer3->Add( m_labelPriAxisNumbering, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ wxArrayString m_choicePriAxisNumberingChoices;
+ m_choicePriAxisNumbering = new wxChoice( m_gridPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choicePriAxisNumberingChoices, 0 );
+ m_choicePriAxisNumbering->SetSelection( 0 );
+ bSizer3->Add( m_choicePriAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_labelSecAxisNumbering = new wxStaticText( m_gridPanel, wxID_ANY, _("Secondary axis numbering:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelSecAxisNumbering->Wrap( -1 );
+ m_labelSecAxisNumbering->Enable( false );
+
+ bSizer3->Add( m_labelSecAxisNumbering, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxArrayString m_choiceSecAxisNumberingChoices;
+ m_choiceSecAxisNumbering = new wxChoice( m_gridPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceSecAxisNumberingChoices, 0 );
+ m_choiceSecAxisNumbering->SetSelection( 0 );
+ m_choiceSecAxisNumbering->Enable( false );
+
+ bSizer3->Add( m_choiceSecAxisNumbering, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizer5;
+ bSizer5 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_labelGridNumberingOffset = new wxStaticText( m_gridPanel, wxID_ANY, _("Pad numbering start:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelGridNumberingOffset->Wrap( -1 );
+ bSizer5->Add( m_labelGridNumberingOffset, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_entryGridPriNumberingOffset = new wxTextCtrl( m_gridPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer5->Add( m_entryGridPriNumberingOffset, 0, wxALL, 5 );
+
+ m_entryGridSecNumberingOffset = new wxTextCtrl( m_gridPanel, wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer5->Add( m_entryGridSecNumberingOffset, 0, wxALL, 5 );
+
+
+ bSizer3->Add( bSizer5, 0, wxEXPAND, 5 );
+
+
+ bSizer2->Add( bSizer3, 0, wxALL|wxEXPAND, 5 );
+
+
+ m_gridPanel->SetSizer( bSizer2 );
+ m_gridPanel->Layout();
+ bSizer2->Fit( m_gridPanel );
+ m_gridTypeNotebook->AddPage( m_gridPanel, _("Grid Array"), true );
+ m_circularPanel = new wxPanel( m_gridTypeNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxHORIZONTAL );
+
+ wxGridBagSizer* gbSizer2;
+ gbSizer2 = new wxGridBagSizer( 0, 0 );
+ gbSizer2->SetFlexibleDirection( wxBOTH );
+ gbSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_labelCentreX = new wxStaticText( m_circularPanel, wxID_ANY, _("Horizontal center:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelCentreX->Wrap( -1 );
+ gbSizer2->Add( m_labelCentreX, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_entryCentreX = new wxTextCtrl( m_circularPanel, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ gbSizer2->Add( m_entryCentreX, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_unitLabelCentreX = new wxStaticText( m_circularPanel, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_unitLabelCentreX->Wrap( -1 );
+ gbSizer2->Add( m_unitLabelCentreX, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_labelCentreY = new wxStaticText( m_circularPanel, wxID_ANY, _("Vertical center:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelCentreY->Wrap( -1 );
+ gbSizer2->Add( m_labelCentreY, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_entryCentreY = new wxTextCtrl( m_circularPanel, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ gbSizer2->Add( m_entryCentreY, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_unitLabelCentreY = new wxStaticText( m_circularPanel, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_unitLabelCentreY->Wrap( -1 );
+ gbSizer2->Add( m_unitLabelCentreY, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_labelCircRadius = new wxStaticText( m_circularPanel, wxID_ANY, _("Radius:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelCircRadius->Wrap( -1 );
+ gbSizer2->Add( m_labelCircRadius, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_labelCircRadiusValue = new wxStaticText( m_circularPanel, wxID_ANY, _("0 mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelCircRadiusValue->Wrap( -1 );
+ gbSizer2->Add( m_labelCircRadiusValue, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_labelCircAngle = new wxStaticText( m_circularPanel, wxID_ANY, _("Angle:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelCircAngle->Wrap( -1 );
+ gbSizer2->Add( m_labelCircAngle, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_entryCircAngle = new wxTextCtrl( m_circularPanel, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_entryCircAngle->SetToolTip( _("Positive angles represent an anti-clockwise rotation. An angle of 0 will produce a full circle divided evenly into \"Count\" portions.") );
+
+ gbSizer2->Add( m_entryCircAngle, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_unitLabelCircAngle = new wxStaticText( m_circularPanel, wxID_ANY, _("deg"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_unitLabelCircAngle->Wrap( -1 );
+ gbSizer2->Add( m_unitLabelCircAngle, wxGBPosition( 3, 2 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_labelCircCount = new wxStaticText( m_circularPanel, wxID_ANY, _("Count:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelCircCount->Wrap( -1 );
+ gbSizer2->Add( m_labelCircCount, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_entryCircCount = new wxTextCtrl( m_circularPanel, wxID_ANY, _("4"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_entryCircCount->SetToolTip( _("How many items in the array.") );
+
+ gbSizer2->Add( m_entryCircCount, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+ m_labelCircRotate = new wxStaticText( m_circularPanel, wxID_ANY, _("Rotate:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelCircRotate->Wrap( -1 );
+ gbSizer2->Add( m_labelCircRotate, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_entryRotateItemsCb = new wxCheckBox( m_circularPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_entryRotateItemsCb->SetValue(true);
+ m_entryRotateItemsCb->SetToolTip( _("Rotate the item as well as move it - multi-selections will be rotated together") );
+
+ gbSizer2->Add( m_entryRotateItemsCb, wxGBPosition( 5, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
+
+
+ bSizer4->Add( gbSizer2, 0, wxALL|wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbcircPadNumberingSizer;
+ sbcircPadNumberingSizer = new wxStaticBoxSizer( new wxStaticBox( m_circularPanel, wxID_ANY, _("Pad Numbering Options") ), wxVERTICAL );
+
+ wxString m_rbCircStartNumberingOptChoices[] = { _("Use first free number"), _("From start value") };
+ int m_rbCircStartNumberingOptNChoices = sizeof( m_rbCircStartNumberingOptChoices ) / sizeof( wxString );
+ m_rbCircStartNumberingOpt = new wxRadioBox( sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Initial pad number"), wxDefaultPosition, wxDefaultSize, m_rbCircStartNumberingOptNChoices, m_rbCircStartNumberingOptChoices, 1, wxRA_SPECIFY_COLS );
+ m_rbCircStartNumberingOpt->SetSelection( 0 );
+ sbcircPadNumberingSizer->Add( m_rbCircStartNumberingOpt, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer7;
+ bSizer7 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_labelCircNumStart = new wxStaticText( sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("Pad numbering start value:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_labelCircNumStart->Wrap( -1 );
+ bSizer7->Add( m_labelCircNumStart, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_entryCircNumberingStart = new wxTextCtrl( sbcircPadNumberingSizer->GetStaticBox(), wxID_ANY, _("1"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer7->Add( m_entryCircNumberingStart, 1, wxALL, 5 );
+
+
+ sbcircPadNumberingSizer->Add( bSizer7, 0, wxEXPAND, 5 );
+
+
+ bSizer4->Add( sbcircPadNumberingSizer, 1, wxEXPAND|wxALL, 5 );
+
+
+ m_circularPanel->SetSizer( bSizer4 );
+ m_circularPanel->Layout();
+ bSizer4->Fit( m_circularPanel );
+ m_gridTypeNotebook->AddPage( m_circularPanel, _("Circular Array"), false );
+
+ bMainSizer->Add( m_gridTypeNotebook, 1, wxEXPAND | wxALL, 5 );
+
+ m_stdButtons = new wxStdDialogButtonSizer();
+ m_stdButtonsOK = new wxButton( this, wxID_OK );
+ m_stdButtons->AddButton( m_stdButtonsOK );
+ m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_stdButtons->AddButton( m_stdButtonsCancel );
+ m_stdButtons->Realize();
+
+ bMainSizer->Add( m_stdButtons, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_CREATE_ARRAY_BASE::OnClose ) );
+ m_entryNx->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryNy->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryDx->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryDy->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryOffsetX->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryOffsetY->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryStagger->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_rbGridStartNumberingOpt->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_radioBoxGridNumberingScheme->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryCentreX->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryCentreY->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryCircAngle->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryCircCount->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_rbCircStartNumberingOpt->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_CREATE_ARRAY_BASE::~DIALOG_CREATE_ARRAY_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_CREATE_ARRAY_BASE::OnClose ) );
+ m_entryNx->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryNy->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryDx->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryDy->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryOffsetX->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryOffsetY->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryStagger->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_rbGridStartNumberingOpt->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_radioBoxGridNumberingScheme->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryCentreX->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryCentreY->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryCircAngle->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_entryCircCount->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_rbCircStartNumberingOpt->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
+ m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_create_array_base.fbp b/pcbnew/dialogs/dialog_create_array_base.fbp
new file mode 100644
index 0000000..f6eb1cc
--- /dev/null
+++ b/pcbnew/dialogs/dialog_create_array_base.fbp
@@ -0,0 +1,4716 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_create_array_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_CREATE_ARRAY_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_DIALOG_CREATE_ARRAY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_CREATE_ARRAY_BASE</property>
+ <property name="pos"></property>
+ <property name="size">652,473</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Create Array</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnClose</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxNotebook" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmapsize"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_gridTypeNotebook</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnNotebookPageChanged"></event>
+ <event name="OnNotebookPageChanging"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap">Load From File; </property>
+ <property name="label">Grid Array</property>
+ <property name="select">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_gridPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer2</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGridBagSizer" expanded="1">
+ <property name="empty_cell_size"></property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">gbSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="vgap">0</property>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALIGN_RIGHT|wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">0</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Horizontal count:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelNx</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">0</property>
+ <property name="rowspan">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryNx</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">5</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnParameterChanged</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALIGN_RIGHT|wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">1</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Vertical count:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelNy</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">1</property>
+ <property name="rowspan">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryNy</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">5</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnParameterChanged</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">2</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Horizontal spacing:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelDx</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">2</property>
+ <property name="rowspan">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryDx</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">5</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnParameterChanged</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">2</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">2</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mm</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_unitLabelDx</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">3</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Vertical spacing:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelDy</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">3</property>
+ <property name="rowspan">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryDy</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">5</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnParameterChanged</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">2</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">3</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mm</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_unitLabelDy</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">4</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Horizontal offset:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelOffsetX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">4</property>
+ <property name="rowspan">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryOffsetX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnParameterChanged</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">2</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">4</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mm</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_unitLabelOffsetX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">5</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Vertical offset:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelOffsetY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">5</property>
+ <property name="rowspan">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryOffsetY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnParameterChanged</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">2</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">5</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mm</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_unitLabelOffsetY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">6</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Stagger:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelStagger</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">6</property>
+ <property name="rowspan">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryStagger</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">1</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnParameterChanged</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">2</property>
+ <property name="column">0</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="row">7</property>
+ <property name="rowspan">2</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Rows&quot; &quot;Columns&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Stagger Type</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioBoxGridStaggerType</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer3</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Horizontal, then vertical&quot; &quot;Vertical, then horizontal&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad Numbering Direction</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioBoxGridNumberingAxis</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Reverse pad numbering on alternate rows or columns</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkBoxGridReverseNumbering</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Use first free number&quot; &quot;From start value&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Initial pad number</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbGridStartNumberingOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox">OnParameterChanged</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Continuous (1, 2, 3...)&quot; &quot;Coordinate (A1, A2, ... B1, ...)&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad Numbering Scheme</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioBoxGridNumberingScheme</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox">OnParameterChanged</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Primary axis numbering:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelPriAxisNumbering</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choicePriAxisNumbering</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Secondary axis numbering:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelSecAxisNumbering</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceSecAxisNumbering</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer5</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad numbering start:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelGridNumberingOffset</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryGridPriNumberingOffset</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">1</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryGridSecNumberingOffset</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">1</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Circular Array</property>
+ <property name="select">0</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_circularPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer4</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxGridBagSizer" expanded="0">
+ <property name="empty_cell_size"></property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">gbSizer2</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="vgap">0</property>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="row">0</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Horizontal center:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelCentreX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">0</property>
+ <property name="rowspan">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryCentreX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnParameterChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">2</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">0</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mm</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_unitLabelCentreX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="row">1</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Vertical center:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelCentreY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">1</property>
+ <property name="rowspan">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryCentreY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnParameterChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">2</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">1</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mm</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_unitLabelCentreY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+ <property name="row">2</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Radius:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelCircRadius</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">2</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">0 mm</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelCircRadiusValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="row">3</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Angle:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelCircAngle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">3</property>
+ <property name="rowspan">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryCircAngle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Positive angles represent an anti-clockwise rotation. An angle of 0 will produce a full circle divided evenly into &quot;Count&quot; portions.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnParameterChanged</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">2</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="row">3</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">deg</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_unitLabelCircAngle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="row">4</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Count:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelCircCount</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">4</property>
+ <property name="rowspan">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryCircCount</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">How many items in the array.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">4</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter">OnParameterChanged</event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">0</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="row">5</property>
+ <property name="rowspan">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Rotate:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelCircRotate</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="gbsizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="colspan">1</property>
+ <property name="column">1</property>
+ <property name="flag">wxALL</property>
+ <property name="row">5</property>
+ <property name="rowspan">1</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryRotateItemsCb</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Rotate the item as well as move it - multi-selections will be rotated together</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad Numbering Options</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbcircPadNumberingSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Use first free number&quot; &quot;From start value&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Initial pad number</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbCircStartNumberingOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox">OnParameterChanged</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer7</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad numbering start value:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_labelCircNumStart</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_entryCircNumberingStart</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">1</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="0">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_stdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_create_array_base.h b/pcbnew/dialogs/dialog_create_array_base.h
new file mode 100644
index 0000000..df1f990
--- /dev/null
+++ b/pcbnew/dialogs/dialog_create_array_base.h
@@ -0,0 +1,118 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jan 1 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_CREATE_ARRAY_BASE_H__
+#define __DIALOG_CREATE_ARRAY_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/radiobox.h>
+#include <wx/gbsizer.h>
+#include <wx/checkbox.h>
+#include <wx/choice.h>
+#include <wx/sizer.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/statbox.h>
+#include <wx/notebook.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define wxID_DIALOG_CREATE_ARRAY 1000
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_CREATE_ARRAY_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_CREATE_ARRAY_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxNotebook* m_gridTypeNotebook;
+ wxPanel* m_gridPanel;
+ wxStaticText* m_labelNx;
+ wxTextCtrl* m_entryNx;
+ wxStaticText* m_labelNy;
+ wxTextCtrl* m_entryNy;
+ wxStaticText* m_labelDx;
+ wxTextCtrl* m_entryDx;
+ wxStaticText* m_unitLabelDx;
+ wxStaticText* m_labelDy;
+ wxTextCtrl* m_entryDy;
+ wxStaticText* m_unitLabelDy;
+ wxStaticText* m_labelOffsetX;
+ wxTextCtrl* m_entryOffsetX;
+ wxStaticText* m_unitLabelOffsetX;
+ wxStaticText* m_labelOffsetY;
+ wxTextCtrl* m_entryOffsetY;
+ wxStaticText* m_unitLabelOffsetY;
+ wxStaticText* m_labelStagger;
+ wxTextCtrl* m_entryStagger;
+ wxRadioBox* m_radioBoxGridStaggerType;
+ wxRadioBox* m_radioBoxGridNumberingAxis;
+ wxCheckBox* m_checkBoxGridReverseNumbering;
+ wxRadioBox* m_rbGridStartNumberingOpt;
+ wxRadioBox* m_radioBoxGridNumberingScheme;
+ wxStaticText* m_labelPriAxisNumbering;
+ wxChoice* m_choicePriAxisNumbering;
+ wxStaticText* m_labelSecAxisNumbering;
+ wxChoice* m_choiceSecAxisNumbering;
+ wxStaticText* m_labelGridNumberingOffset;
+ wxTextCtrl* m_entryGridPriNumberingOffset;
+ wxTextCtrl* m_entryGridSecNumberingOffset;
+ wxPanel* m_circularPanel;
+ wxStaticText* m_labelCentreX;
+ wxTextCtrl* m_entryCentreX;
+ wxStaticText* m_unitLabelCentreX;
+ wxStaticText* m_labelCentreY;
+ wxTextCtrl* m_entryCentreY;
+ wxStaticText* m_unitLabelCentreY;
+ wxStaticText* m_labelCircRadius;
+ wxStaticText* m_labelCircRadiusValue;
+ wxStaticText* m_labelCircAngle;
+ wxTextCtrl* m_entryCircAngle;
+ wxStaticText* m_unitLabelCircAngle;
+ wxStaticText* m_labelCircCount;
+ wxTextCtrl* m_entryCircCount;
+ wxStaticText* m_labelCircRotate;
+ wxCheckBox* m_entryRotateItemsCb;
+ wxRadioBox* m_rbCircStartNumberingOpt;
+ wxStaticText* m_labelCircNumStart;
+ wxTextCtrl* m_entryCircNumberingStart;
+ wxStdDialogButtonSizer* m_stdButtons;
+ wxButton* m_stdButtonsOK;
+ wxButton* m_stdButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnParameterChanged( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID id = wxID_DIALOG_CREATE_ARRAY, const wxString& title = _("Create Array"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 652,473 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_CREATE_ARRAY_BASE();
+
+};
+
+#endif //__DIALOG_CREATE_ARRAY_BASE_H__
diff --git a/pcbnew/dialogs/dialog_design_rules.cpp b/pcbnew/dialogs/dialog_design_rules.cpp
new file mode 100644
index 0000000..80fe0f8
--- /dev/null
+++ b/pcbnew/dialogs/dialog_design_rules.cpp
@@ -0,0 +1,1082 @@
+/**
+ * @file dialog_design_rules.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2009 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2009 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2009-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* functions relative to the design rules editor
+ */
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <base_units.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <class_board_design_settings.h>
+
+#include <pcbnew_id.h>
+#include <class_track.h>
+#include <macros.h>
+#include <html_messagebox.h>
+
+#include <dialog_design_rules.h>
+#include <wx/generic/gridctrl.h>
+#include <dialog_design_rules_aux_helper_class.h>
+
+#include <boost/make_shared.hpp>
+
+// Column labels for net lists
+#define NET_TITLE _( "Net" )
+#define CLASS_TITLE _( "Class" )
+
+// Field Positions on rules grid
+enum {
+ GRID_CLEARANCE,
+ GRID_TRACKSIZE,
+ GRID_VIASIZE,
+ GRID_VIADRILL,
+ GRID_uVIASIZE,
+ GRID_uVIADRILL
+};
+
+const wxString DIALOG_DESIGN_RULES::wildCard = _( "* (Any)" );
+
+// dialog should remember its previously selected tab
+int DIALOG_DESIGN_RULES::s_LastTabSelection = -1;
+
+// methods for the helper class NETS_LIST_CTRL
+
+wxString NETS_LIST_CTRL::OnGetItemText( long item, long column ) const
+{
+ if( column == 0 )
+ {
+ if( item < (long) m_Netnames.GetCount() )
+ return m_Netnames[item];
+ else
+ return wxEmptyString;
+ }
+ else if( item < (long) m_Classnames.GetCount() )
+ return m_Classnames[item];
+
+ return wxEmptyString;
+}
+
+
+void NETS_LIST_CTRL::SetRowItems( unsigned aRow,
+ const wxString& aNetname,
+ const wxString& aNetclassName )
+{
+ // insert blanks if aRow is larger than existing row count
+ unsigned cnt = m_Netnames.GetCount();
+
+ if( cnt <= aRow )
+ m_Netnames.Add( wxEmptyString, aRow - cnt + 1 );
+
+ cnt = m_Classnames.GetCount();
+
+ if( cnt <= aRow )
+ m_Classnames.Add( wxEmptyString, aRow - cnt + 1 );
+
+ if( (int)aRow <= GetItemCount() )
+ SetItemCount( aRow + 1 );
+
+ m_Netnames[aRow] = aNetname;
+ m_Classnames[aRow] = aNetclassName;
+}
+
+
+/**
+ * Function EnsureGridColumnWidths
+ * resizes all the columns in a wxGrid based only on the requirements of the
+ * column titles and not on the grid cell requirements, assuming that the grid
+ * cell width requirements are narrower than the column title requirements.
+ */
+
+// @todo: maybe move this to common.cpp if it works.
+void EnsureGridColumnWidths( wxGrid* aGrid )
+{
+ wxScreenDC sDC;
+
+ sDC.SetFont( aGrid->GetLabelFont() );
+
+ int colCount = aGrid->GetNumberCols();
+
+ for( int col = 0; col<colCount; ++col )
+ {
+ // add two spaces to the text and size it.
+ wxString colText = aGrid->GetColLabelValue( col ) + wxT( " " );
+
+ wxSize needed = sDC.GetTextExtent( colText );
+
+ // set the width of this column
+ aGrid->SetColSize( col, needed.x );
+ }
+}
+
+
+DIALOG_DESIGN_RULES::DIALOG_DESIGN_RULES( PCB_EDIT_FRAME* parent ) :
+ DIALOG_DESIGN_RULES_BASE( parent )
+{
+ m_Parent = parent;
+ SetAutoLayout( true );
+
+ EnsureGridColumnWidths( m_grid ); // override any column widths set by wxformbuilder.
+
+ wxListItem column0;
+ wxListItem column1;
+
+ column0.Clear();
+ column1.Clear();
+
+ column0.SetMask( wxLIST_MASK_TEXT );
+ column1.SetMask( wxLIST_MASK_TEXT );
+
+ column0.SetText( NET_TITLE );
+ column1.SetText( CLASS_TITLE );
+
+ m_leftListCtrl->InsertColumn( 0, column0 );
+ m_leftListCtrl->InsertColumn( 1, column1 );
+ m_leftListCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE );
+ m_leftListCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE );
+
+ m_rightListCtrl->InsertColumn( 0, column0 );
+ m_rightListCtrl->InsertColumn( 1, column1 );
+ m_rightListCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE );
+ m_rightListCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE );
+
+ // if user has been into the dialog before, go back to same tab
+ if( s_LastTabSelection != -1 )
+ {
+ m_DRnotebook->SetSelection( s_LastTabSelection );
+ }
+
+ InitDialogRules();
+ m_sdbSizer1OK->SetDefault();
+
+ // Allow tabbing out of grid controls.
+ m_grid->SetTabBehaviour( wxGrid::Tab_Leave );
+ m_gridViaSizeList->SetTabBehaviour( wxGrid::Tab_Leave );
+ m_gridTrackWidthList->SetTabBehaviour( wxGrid::Tab_Leave );
+
+ Layout();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void DIALOG_DESIGN_RULES::InitDialogRules()
+{
+ // @todo: Move the initialization code into TransferDataToWindow() to follow wxWidgets
+ // dialog data transfer convention.
+ SetFocus();
+ SetReturnCode( 0 );
+
+ m_Pcb = m_Parent->GetBoard();
+ m_BrdSettings = &m_Pcb->GetDesignSettings();
+
+ // Initialize the Rules List
+ InitRulesList();
+
+ // copy all NETs into m_AllNets by adding them as NETCUPs.
+
+ // @todo go fix m_Pcb->SynchronizeNetsAndNetClasses() so that the netcode==0 is not
+ // present in the BOARD::m_NetClasses
+ NETCLASSES& netclasses = m_BrdSettings->m_NetClasses;
+ NETCLASSPTR netclass = netclasses.GetDefault();
+
+ // Initialize list of nets for Default Net Class
+ for( NETCLASS::iterator name = netclass->begin(); name != netclass->end(); ++name )
+ {
+ m_AllNets.push_back( NETCUP( *name, netclass->GetName() ) );
+ }
+
+ // Initialize list of nets for others (custom) Net Classes
+ for( NETCLASSES::const_iterator nc = netclasses.begin(); nc != netclasses.end(); ++nc )
+ {
+ netclass = nc->second;
+
+ for( NETCLASS::const_iterator name = netclass->begin(); name != netclass->end(); ++name )
+ {
+ m_AllNets.push_back( NETCUP( *name, netclass->GetName() ) );
+ }
+ }
+
+ InitializeRulesSelectionBoxes();
+ InitGlobalRules();
+}
+
+
+void DIALOG_DESIGN_RULES::InitGlobalRules()
+{
+ AddUnitSymbol( *m_ViaMinTitle );
+ AddUnitSymbol( *m_ViaMinDrillTitle );
+ AddUnitSymbol( *m_MicroViaMinSizeTitle );
+ AddUnitSymbol( *m_MicroViaMinDrillTitle );
+ AddUnitSymbol( *m_TrackMinWidthTitle );
+
+ PutValueInLocalUnits( *m_SetViasMinSizeCtrl, m_BrdSettings->m_ViasMinSize );
+ PutValueInLocalUnits( *m_SetViasMinDrillCtrl, m_BrdSettings->m_ViasMinDrill );
+
+ if( m_BrdSettings->m_BlindBuriedViaAllowed )
+ m_OptViaType->SetSelection( 1 );
+
+ m_AllowMicroViaCtrl->SetSelection( m_BrdSettings->m_MicroViasAllowed ? 1 : 0 );
+ PutValueInLocalUnits( *m_SetMicroViasMinSizeCtrl, m_BrdSettings->m_MicroViasMinSize );
+ PutValueInLocalUnits( *m_SetMicroViasMinDrillCtrl, m_BrdSettings->m_MicroViasMinDrill );
+ PutValueInLocalUnits( *m_SetTrackMinWidthCtrl, m_BrdSettings->m_TrackMinWidth );
+
+ // Initialize Vias and Tracks sizes lists.
+ // note we display only extra values, never the current netclass value.
+ // (the first value in history list)
+ m_TracksWidthList = m_BrdSettings->m_TrackWidthList;
+ m_TracksWidthList.erase( m_TracksWidthList.begin() ); // remove the netclass value
+ m_ViasDimensionsList = m_BrdSettings->m_ViasDimensionsList;
+ m_ViasDimensionsList.erase( m_ViasDimensionsList.begin() ); // remove the netclass value
+ InitDimensionsLists();
+}
+
+
+void DIALOG_DESIGN_RULES::InitDimensionsLists()
+{
+ wxString msg;
+
+ // Compute the column widths here, after setting texts
+ msg = wxT("000000.000000"); // This is a very long text to display values.
+ // Actual values are shorter.
+ m_gridViaSizeList->SetCellValue( 0, 0, msg );
+ m_gridViaSizeList->SetCellValue( 0, 1, msg );
+ m_gridTrackWidthList->SetCellValue( 0, 0, msg );
+ m_gridViaSizeList->SetColMinimalWidth( 0, 150 );
+ m_gridViaSizeList->SetColMinimalWidth( 1, 150 );
+ m_gridViaSizeList->AutoSizeColumns( true );
+ m_gridTrackWidthList->SetColMinimalWidth( 0, 150 );
+ m_gridTrackWidthList->AutoSizeColumns( true );
+ m_gridViaSizeList->SetColMinimalWidth( 1, 150 );
+
+ // Fill cells with actual values:
+ m_gridViaSizeList->SetCellValue( 0, 0, wxEmptyString );
+ m_gridViaSizeList->SetCellValue( 0, 1, wxEmptyString );
+ m_gridTrackWidthList->SetCellValue( 0, 0, wxEmptyString );
+
+ // Give a correct size to row labels column
+ m_gridViaSizeList->SetRowLabelSize( wxGRID_AUTOSIZE );
+ m_gridTrackWidthList->SetRowLabelSize( wxGRID_AUTOSIZE );
+
+ for( unsigned ii = 0; ii < m_TracksWidthList.size(); ii++ )
+ {
+ msg = StringFromValue( g_UserUnit, m_TracksWidthList[ii], false );
+ m_gridTrackWidthList->SetCellValue( ii, 0, msg );
+ }
+
+ for( unsigned ii = 0; ii < m_ViasDimensionsList.size(); ii++ )
+ {
+ msg = StringFromValue( g_UserUnit, m_ViasDimensionsList[ii].m_Diameter, false );
+ m_gridViaSizeList->SetCellValue( ii, 0, msg );
+
+ if( m_ViasDimensionsList[ii].m_Drill > 0 )
+ {
+ msg = StringFromValue( g_UserUnit, m_ViasDimensionsList[ii].m_Drill, false );
+ m_gridViaSizeList->SetCellValue( ii, 1, msg );
+ }
+ }
+}
+
+
+// Sort comparison function (helper for makePointers() )
+static bool sortByClassThenName( NETCUP* a, NETCUP* b )
+{
+ // return a < b
+ if( a->clazz < b->clazz )
+ return true;
+
+ // inside the same class, sort by net name:
+ if( a->clazz == b->clazz )
+ {
+ if( a->net < b->net )
+ return true;
+ }
+
+ return false;
+}
+
+
+void DIALOG_DESIGN_RULES::makePointers( PNETCUPS* aList, const wxString& aNetClassName )
+{
+ aList->clear();
+
+ if( wildCard == aNetClassName )
+ {
+ for( NETCUPS::iterator n = m_AllNets.begin(); n != m_AllNets.end(); ++n )
+ {
+ aList->push_back( &*n );
+ }
+
+ sort( aList->begin(), aList->end(), sortByClassThenName );
+
+ // could use a different sort order for wildCard case.
+ }
+ else
+ {
+ for( NETCUPS::iterator n = m_AllNets.begin(); n != m_AllNets.end(); ++n )
+ {
+ if( n->clazz == aNetClassName )
+ aList->push_back( &*n );
+ }
+
+ sort( aList->begin(), aList->end(), sortByClassThenName );
+ }
+}
+
+
+void DIALOG_DESIGN_RULES::FillListBoxWithNetNames( NETS_LIST_CTRL* aListCtrl,
+ const wxString& aNetClass )
+{
+ aListCtrl->ClearList();
+
+ PNETCUPS ptrList;
+
+ // get a subset of m_AllNets in pointer form, sorted as desired.
+ makePointers( &ptrList, aNetClass );
+
+#if 0 && defined(DEBUG)
+ int r = 0;
+ for( PNETCUPS::iterator i = ptrList.begin(); i!=ptrList.end(); ++i, ++r )
+ {
+ printf( "[%d]: %s %s\n", r, TO_UTF8( (*i)->net ), TO_UTF8( (*i)->clazz ) );
+ }
+
+#endif
+
+ // Add netclass info to m_Netnames and m_Classnames wxArrayString buffers
+ // aListCtrl uses wxLC_VIRTUAL option, so this is fast
+ wxClientDC sDC( aListCtrl );
+ int row = 0;
+ // recompute the column widths here, after setting texts
+ int net_colsize = sDC.GetTextExtent( NET_TITLE ).x;
+ int class_colsize = sDC.GetTextExtent( CLASS_TITLE ).x;
+
+ for( PNETCUPS::iterator i = ptrList.begin(); i!=ptrList.end(); ++i, ++row )
+ {
+ wxSize net_needed = sDC.GetTextExtent( (*i)->net );
+ wxSize class_needed = sDC.GetTextExtent( (*i)->clazz );
+ net_colsize = std::max( net_colsize, net_needed.x );
+ class_colsize = std::max( class_colsize, class_needed.x );
+ aListCtrl->SetRowItems( row, (*i)->net, (*i)->clazz );
+ }
+
+ int margin = sDC.GetTextExtent( wxT( "XX" ) ).x;
+ aListCtrl->SetColumnWidth( 0, net_colsize + margin );
+ aListCtrl->SetColumnWidth( 1, class_colsize + margin );
+ aListCtrl->Refresh();
+}
+
+
+/* Populates combo boxes with the list of existing net classes
+ */
+void DIALOG_DESIGN_RULES::InitializeRulesSelectionBoxes()
+{
+ m_rightClassChoice->Clear();
+ m_leftClassChoice->Clear();
+
+ m_rightClassChoice->Append( wildCard );
+ m_leftClassChoice->Append( wildCard );
+
+ for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
+ {
+ m_rightClassChoice->Append( m_grid->GetRowLabelValue( ii ) );
+ m_leftClassChoice->Append( m_grid->GetRowLabelValue( ii ) );
+ }
+
+ m_rightClassChoice->Select( 0 );
+ m_leftClassChoice->Select( 0 );
+
+ m_buttonRightToLeft->Enable( false );
+ m_buttonLeftToRight->Enable( false );
+
+ FillListBoxWithNetNames( m_leftListCtrl, m_leftClassChoice->GetStringSelection() );
+ FillListBoxWithNetNames( m_rightListCtrl, m_rightClassChoice->GetStringSelection() );
+}
+
+
+/* Initialize the rules list from board
+ */
+
+static void class2gridRow( wxGrid* grid, int row, NETCLASSPTR nc )
+{
+ wxString msg;
+
+ // label is netclass name
+ grid->SetRowLabelValue( row, nc->GetName() );
+
+ msg = StringFromValue( g_UserUnit, nc->GetClearance() );
+ grid->SetCellValue( row, GRID_CLEARANCE, msg );
+
+ msg = StringFromValue( g_UserUnit, nc->GetTrackWidth() );
+ grid->SetCellValue( row, GRID_TRACKSIZE, msg );
+
+ msg = StringFromValue( g_UserUnit, nc->GetViaDiameter() );
+ grid->SetCellValue( row, GRID_VIASIZE, msg );
+
+ msg = StringFromValue( g_UserUnit, nc->GetViaDrill() );
+ grid->SetCellValue( row, GRID_VIADRILL, msg );
+
+ msg = StringFromValue( g_UserUnit, nc->GetuViaDiameter() );
+ grid->SetCellValue( row, GRID_uVIASIZE, msg );
+
+ msg = StringFromValue( g_UserUnit, nc->GetuViaDrill() );
+ grid->SetCellValue( row, GRID_uVIADRILL, msg );
+}
+
+
+void DIALOG_DESIGN_RULES::InitRulesList()
+{
+ NETCLASSES& netclasses = m_BrdSettings->m_NetClasses;
+
+ // the +1 is for the Default NETCLASS.
+ if( netclasses.GetCount() + 1 > (unsigned) m_grid->GetNumberRows() )
+ {
+ m_grid->AppendRows( netclasses.GetCount() + 1 - m_grid->GetNumberRows() );
+ }
+
+ // enter the Default NETCLASS.
+ class2gridRow( m_grid, 0, netclasses.GetDefault() );
+
+ // enter others netclasses
+ int row = 1;
+
+ for( NETCLASSES::iterator i = netclasses.begin(); i!=netclasses.end(); ++i, ++row )
+ {
+ NETCLASSPTR netclass = i->second;
+
+ class2gridRow( m_grid, row, netclass );
+ }
+}
+
+
+static void gridRow2class( wxGrid* grid, int row, NETCLASSPTR nc )
+{
+#define MYCELL( col ) \
+ ValueFromString( g_UserUnit, grid->GetCellValue( row, col ) )
+
+ nc->SetClearance( MYCELL( GRID_CLEARANCE ) );
+ nc->SetTrackWidth( MYCELL( GRID_TRACKSIZE ) );
+ nc->SetViaDiameter( MYCELL( GRID_VIASIZE ) );
+ nc->SetViaDrill( MYCELL( GRID_VIADRILL ) );
+ nc->SetuViaDiameter( MYCELL( GRID_uVIASIZE ) );
+ nc->SetuViaDrill( MYCELL( GRID_uVIADRILL ) );
+}
+
+
+void DIALOG_DESIGN_RULES::CopyRulesListToBoard()
+{
+ NETCLASSES& netclasses = m_BrdSettings->m_NetClasses;
+
+ // Remove all netclasses from board. We'll copy new list after
+ netclasses.Clear();
+
+ // Copy the default NetClass:
+ gridRow2class( m_grid, 0, netclasses.GetDefault() );
+
+ // Copy other NetClasses :
+ for( int row = 1; row < m_grid->GetNumberRows(); ++row )
+ {
+ NETCLASSPTR nc = boost::make_shared<NETCLASS>( m_grid->GetRowLabelValue( row ) );
+
+ if( !m_BrdSettings->m_NetClasses.Add( nc ) )
+ {
+ // this netclass cannot be added because an other netclass with the same name exists
+ // Should not occur because OnAddNetclassClick() tests for existing NetClass names
+ wxString msg;
+ msg.Printf( wxT( "CopyRulesListToBoard(): The NetClass \"%s\" already exists. Skip" ),
+ GetChars( m_grid->GetRowLabelValue( row ) ) );
+ wxMessageBox( msg );
+
+ continue;
+ }
+
+ gridRow2class( m_grid, row, nc );
+ }
+
+ // Now read all nets and push them in the corresponding netclass net buffer
+ for( NETCUPS::const_iterator netcup = m_AllNets.begin(); netcup != m_AllNets.end(); ++netcup )
+ {
+ NETCLASSPTR nc = netclasses.Find( netcup->clazz );
+ wxASSERT( nc );
+ nc->Add( netcup->net );
+ }
+
+ m_Pcb->SynchronizeNetsAndNetClasses();
+}
+
+
+void DIALOG_DESIGN_RULES::CopyGlobalRulesToBoard()
+{
+ m_BrdSettings->m_BlindBuriedViaAllowed = m_OptViaType->GetSelection() > 0;
+
+ // Update vias minimum values for DRC
+ m_BrdSettings->m_ViasMinSize = ValueFromTextCtrl( *m_SetViasMinSizeCtrl );
+ m_BrdSettings->m_ViasMinDrill = ValueFromTextCtrl( *m_SetViasMinDrillCtrl );
+
+ m_BrdSettings->m_MicroViasAllowed = m_AllowMicroViaCtrl->GetSelection() == 1;
+
+ // Update microvias minimum values for DRC
+ m_BrdSettings->m_MicroViasMinSize = ValueFromTextCtrl( *m_SetMicroViasMinSizeCtrl );
+ m_BrdSettings->m_MicroViasMinDrill = ValueFromTextCtrl( *m_SetMicroViasMinDrillCtrl );
+
+ // Update tracks minimum values for DRC
+ m_BrdSettings->m_TrackMinWidth = ValueFromTextCtrl( *m_SetTrackMinWidthCtrl );
+}
+
+
+void DIALOG_DESIGN_RULES::CopyDimensionsListsToBoard()
+{
+ wxString msg;
+
+ // Reinitialize m_TrackWidthList
+ m_TracksWidthList.clear();
+
+ for( int row = 0; row < m_gridTrackWidthList->GetNumberRows(); ++row )
+ {
+ msg = m_gridTrackWidthList->GetCellValue( row, 0 );
+
+ if( msg.IsEmpty() )
+ continue;
+
+ int value = ValueFromString( g_UserUnit, msg );
+ m_TracksWidthList.push_back( value );
+ }
+
+ // Sort new list by by increasing value
+ sort( m_TracksWidthList.begin(), m_TracksWidthList.end() );
+
+ // Reinitialize m_TrackWidthList
+ m_ViasDimensionsList.clear();
+
+ for( int row = 0; row < m_gridViaSizeList->GetNumberRows(); ++row )
+ {
+ msg = m_gridViaSizeList->GetCellValue( row, 0 );
+
+ if( msg.IsEmpty() )
+ continue;
+
+ int value = ValueFromString( g_UserUnit, msg );
+ VIA_DIMENSION via_dim;
+ via_dim.m_Diameter = value;
+ msg = m_gridViaSizeList->GetCellValue( row, 1 );
+
+ if( !msg.IsEmpty() )
+ {
+ value = ValueFromString( g_UserUnit, msg );
+ via_dim.m_Drill = value;
+ }
+
+ m_ViasDimensionsList.push_back( via_dim );
+ }
+
+ // Sort new list by by increasing value
+ sort( m_ViasDimensionsList.begin(), m_ViasDimensionsList.end() );
+
+ std::vector<int>* tlist = &m_BrdSettings->m_TrackWidthList;
+
+ // Remove old "custom" sizes
+ tlist->erase( tlist->begin() + 1, tlist->end() );
+
+ // Add new "custom" sizes
+ tlist->insert( tlist->end(), m_TracksWidthList.begin(), m_TracksWidthList.end() );
+
+ // Reinitialize m_ViaSizeList
+ std::vector<VIA_DIMENSION>* vialist = &m_BrdSettings->m_ViasDimensionsList;
+ vialist->erase( vialist->begin() + 1, vialist->end() );
+ vialist->insert( vialist->end(), m_ViasDimensionsList.begin(), m_ViasDimensionsList.end() );
+}
+
+
+void DIALOG_DESIGN_RULES::OnNotebookPageChanged( wxNotebookEvent& event )
+{
+ s_LastTabSelection = event.GetSelection();
+
+ // Skip() allows OSX to properly refresh controls.
+ event.Skip();
+}
+
+
+bool DIALOG_DESIGN_RULES::TransferDataFromWindow()
+{
+ if( !wxDialog::TransferDataFromWindow() )
+ return false;
+
+ wxString errorMsg;
+
+ if( !TestDataValidity( &errorMsg ) )
+ {
+ HTML_MESSAGE_BOX dlg( this, _( "Design Rule Setting Error" ) );
+ dlg.MessageSet( errorMsg );
+ dlg.ShowModal();
+ return false;
+ }
+
+ CopyRulesListToBoard();
+ CopyGlobalRulesToBoard();
+ CopyDimensionsListsToBoard();
+ m_BrdSettings->SetCurrentNetClass( NETCLASS::Default );
+ return true;
+}
+
+
+void DIALOG_DESIGN_RULES::OnAddNetclassClick( wxCommandEvent& event )
+{
+ wxString class_name;
+
+ // @todo set validator to ensure net class name is valid rather than all of the checks
+ // after the OK button has been selected.
+ wxTextEntryDialog dlg( this, _( "New Net Class Name:" ), wxEmptyString, class_name );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return; // canceled by user
+
+ class_name = dlg.GetValue();
+ class_name.Trim( true );
+ class_name.Trim( false );
+
+ if( class_name.IsEmpty() )
+ return; // empty name not allowed
+
+ // The name must dot exists:
+ for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
+ {
+ wxString value;
+ value = m_grid->GetRowLabelValue( ii );
+
+ if( class_name.CmpNoCase( value ) == 0 ) // Already exists!
+ {
+ DisplayError( this, _( "Duplicate net class names are not allowed." ) );
+ return;
+ }
+ }
+
+ m_grid->AppendRows();
+ m_grid->SetRowLabelValue( m_grid->GetNumberRows() - 1, class_name );
+
+ // Copy values of the default class:
+ int irow = m_grid->GetNumberRows() - 1;
+
+ for( int icol = 0; icol < m_grid->GetNumberCols(); icol++ )
+ {
+ wxString value;
+ value = m_grid->GetCellValue( 0, icol );
+ m_grid->SetCellValue( irow, icol, value );
+ }
+
+ InitializeRulesSelectionBoxes();
+}
+
+
+// Sort function for wxArrayInt. Items (ints) are sorted by decreasing value
+// used in DIALOG_DESIGN_RULES::OnRemoveNetclassClick
+int sort_int( int* first, int* second )
+{
+ return *second - *first;
+}
+
+
+void DIALOG_DESIGN_RULES::OnRemoveNetclassClick( wxCommandEvent& event )
+{
+ wxArrayInt select = m_grid->GetSelectedRows();
+
+ // Sort selection by decreasing index order:
+ select.Sort( sort_int );
+ bool reinit = false;
+
+ // rows labels are not removed when deleting rows: they are not deleted.
+ // So we must store them, remove corresponding labels and reinit them
+ wxArrayString labels;
+
+ for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
+ labels.Add( m_grid->GetRowLabelValue( ii ) );
+
+ // Delete rows from last to first (this is the order wxArrayInt select after sorting) )
+ // This order is Ok when removing rows
+ for( unsigned ii = 0; ii < select.GetCount(); ii++ )
+ {
+ int grid_row = select[ii];
+
+ if( grid_row != 0 ) // Do not remove the default class
+ {
+ wxString classname = m_grid->GetRowLabelValue( grid_row );
+ m_grid->DeleteRows( grid_row );
+ labels.RemoveAt( grid_row ); // Remove corresponding row label
+ reinit = true;
+
+ // reset the net class to default for members of the removed class
+ swapNetClass( classname, NETCLASS::Default );
+ }
+ else
+ wxMessageBox( _( "The default net class cannot be removed" ) );
+ }
+
+ if( reinit )
+ {
+ // Reinit labels :
+ for( unsigned ii = 1; ii < labels.GetCount(); ii++ )
+ m_grid->SetRowLabelValue( ii, labels[ii] );
+
+ InitializeRulesSelectionBoxes();
+ }
+}
+
+
+void DIALOG_DESIGN_RULES::OnMoveUpSelectedNetClass( wxCommandEvent& event )
+{
+ // Cannot move up rules if we have 1 or 2 rules only
+ if( m_grid->GetNumberRows() < 3 )
+ return;
+
+ wxArrayInt select = m_grid->GetSelectedRows();
+ bool reinit = false;
+
+ for( unsigned irow = 0; irow < select.GetCount(); irow++ )
+ {
+ int ii = select[irow];
+ if( ii < 2 ) // The default netclass *must* be the first netclass
+ continue; // so we cannot move up line 0 and 1
+
+ // Swap the rule and the previous rule
+ wxString curr_value, previous_value;
+
+ for( int icol = 0; icol < m_grid->GetNumberCols(); icol++ )
+ {
+ reinit = true;
+ curr_value = m_grid->GetCellValue( ii, icol );
+ previous_value = m_grid->GetCellValue( ii - 1, icol );
+ m_grid->SetCellValue( ii, icol, previous_value );
+ m_grid->SetCellValue( ii - 1, icol, curr_value );
+ }
+
+ curr_value = m_grid->GetRowLabelValue( ii );
+ previous_value = m_grid->GetRowLabelValue( ii - 1 );
+ m_grid->SetRowLabelValue( ii, previous_value );
+ m_grid->SetRowLabelValue( ii - 1, curr_value );
+ }
+
+ if( reinit )
+ InitializeRulesSelectionBoxes();
+}
+
+
+void DIALOG_DESIGN_RULES::OnLeftCBSelection( wxCommandEvent& event )
+{
+ FillListBoxWithNetNames( m_leftListCtrl, m_leftClassChoice->GetStringSelection() );
+
+ if( m_leftClassChoice->GetStringSelection() == m_rightClassChoice->GetStringSelection() )
+ {
+ m_buttonRightToLeft->Enable( false );
+ m_buttonLeftToRight->Enable( false );
+ }
+ else
+ {
+ m_buttonRightToLeft->Enable( true );
+ m_buttonLeftToRight->Enable( true );
+ }
+}
+
+
+void DIALOG_DESIGN_RULES::OnRightCBSelection( wxCommandEvent& event )
+{
+ FillListBoxWithNetNames( m_rightListCtrl, m_rightClassChoice->GetStringSelection() );
+
+ if( m_leftClassChoice->GetStringSelection() == m_rightClassChoice->GetStringSelection() )
+ {
+ m_buttonRightToLeft->Enable( false );
+ m_buttonLeftToRight->Enable( false );
+ }
+ else
+ {
+ m_buttonRightToLeft->Enable( true );
+ m_buttonLeftToRight->Enable( true );
+ }
+}
+
+
+void DIALOG_DESIGN_RULES::moveSelectedItems( NETS_LIST_CTRL* src, const wxString& newClassName )
+{
+ wxListItem item;
+ wxString netName;
+
+ item.m_mask |= wxLIST_MASK_TEXT; // Validate the member m_text of the wxListItem item
+
+ for( int row = 0; row < src->GetItemCount(); ++row )
+ {
+ if( !src->GetItemState( row, wxLIST_STATE_SELECTED ) )
+ continue;
+
+ item.SetColumn( 0 );
+ item.SetId( row );
+
+ src->GetItem( item );
+ netName = item.GetText();
+
+ setNetClass( netName, newClassName == wildCard ? NETCLASS::Default : newClassName );
+ }
+}
+
+
+void DIALOG_DESIGN_RULES::OnRightToLeftCopyButton( wxCommandEvent& event )
+{
+ wxString newClassName = m_leftClassChoice->GetStringSelection();
+
+ moveSelectedItems( m_rightListCtrl, newClassName );
+
+ FillListBoxWithNetNames( m_leftListCtrl, m_leftClassChoice->GetStringSelection() );
+ FillListBoxWithNetNames( m_rightListCtrl, m_rightClassChoice->GetStringSelection() );
+}
+
+
+void DIALOG_DESIGN_RULES::OnLeftToRightCopyButton( wxCommandEvent& event )
+{
+ wxString newClassName = m_rightClassChoice->GetStringSelection();
+
+ moveSelectedItems( m_leftListCtrl, newClassName );
+
+ FillListBoxWithNetNames( m_leftListCtrl, m_leftClassChoice->GetStringSelection() );
+ FillListBoxWithNetNames( m_rightListCtrl, m_rightClassChoice->GetStringSelection() );
+}
+
+
+void DIALOG_DESIGN_RULES::OnLeftSelectAllButton( wxCommandEvent& event )
+{
+ for( int ii = 0; ii < m_leftListCtrl->GetItemCount(); ii++ )
+ m_leftListCtrl->SetItemState( ii, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
+}
+
+
+void DIALOG_DESIGN_RULES::OnRightSelectAllButton( wxCommandEvent& event )
+{
+ for( int ii = 0; ii < m_rightListCtrl->GetItemCount(); ii++ )
+ m_rightListCtrl->SetItemState( ii, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
+}
+
+
+void DIALOG_DESIGN_RULES::setNetClass( const wxString& aNetName, const wxString& aClassName )
+{
+ for( NETCUPS::iterator i = m_AllNets.begin(); i != m_AllNets.end(); ++i )
+ {
+ if( i->net == aNetName )
+ {
+ i->clazz = aClassName;
+ break;
+ }
+ }
+}
+
+
+bool DIALOG_DESIGN_RULES::TestDataValidity( wxString* aErrorMsg )
+{
+ bool result = true;
+
+ wxString msg;
+ wxString errorMsg;
+
+ int minViaDia = ValueFromTextCtrl( *m_SetViasMinSizeCtrl );
+ int minViaDrill = ValueFromTextCtrl( *m_SetViasMinDrillCtrl );
+ int minUViaDia = ValueFromTextCtrl( *m_SetMicroViasMinSizeCtrl );
+ int minUViaDrill = ValueFromTextCtrl( *m_SetMicroViasMinDrillCtrl );
+ int minTrackWidth = ValueFromTextCtrl( *m_SetTrackMinWidthCtrl );
+ int maxval = 1000 * IU_PER_MILS; // a max value for tracks and vias sizes (1 inch)
+
+ // @todo Change this code to set the focus to the control where the first error occurs
+ // so the user doesn't have to figure out where the issue is.
+
+ // Test net class parameters.
+ for( int row = 0; row < m_grid->GetNumberRows(); row++ )
+ {
+ int tracksize = ValueFromString( g_UserUnit,
+ m_grid->GetCellValue( row, GRID_TRACKSIZE ) );
+ if( tracksize < minTrackWidth )
+ {
+ result = false;
+ msg.Printf( _( "%s: <b>Track Size</b> &lt; <b>Min Track Size</b><br>" ),
+ GetChars( m_grid->GetRowLabelValue( row ) ) );
+ errorMsg += msg;
+ }
+
+ // Test vias
+ int viadia = ValueFromString( g_UserUnit,
+ m_grid->GetCellValue( row, GRID_VIASIZE ) );
+
+ if( viadia < minViaDia )
+ {
+ result = false;
+ msg.Printf( _( "%s: <b>Via Diameter</b> &lt; <b>Minimum Via Diameter</b><br>" ),
+ GetChars( m_grid->GetRowLabelValue( row ) ) );
+ errorMsg += msg;
+ }
+
+ int viadrill = ValueFromString( g_UserUnit,
+ m_grid->GetCellValue( row, GRID_VIADRILL ) );
+
+ if( viadrill >= viadia )
+ {
+ result = false;
+ msg.Printf( _( "%s: <b>Via Drill</b> &ge; <b>Via Dia</b><br>" ),
+ GetChars( m_grid->GetRowLabelValue( row ) ) );
+ errorMsg += msg;
+ }
+
+ if( viadrill < minViaDrill )
+ {
+ result = false;
+ msg.Printf( _( "%s: <b>Via Drill</b> &lt; <b>Min Via Drill</b><br>" ),
+ GetChars( m_grid->GetRowLabelValue( row ) ) );
+ errorMsg += msg;
+ }
+
+ // Test Micro vias
+ int muviadia = ValueFromString( g_UserUnit,
+ m_grid->GetCellValue( row, GRID_uVIASIZE ) );
+
+ if( muviadia < minUViaDia )
+ {
+ result = false;
+ msg.Printf( _( "%s: <b>MicroVia Diameter</b> &lt; <b>MicroVia Min Diameter</b><br>" ),
+ GetChars( m_grid->GetRowLabelValue( row ) ) );
+ errorMsg += msg;
+ }
+
+ int muviadrill = ValueFromString( g_UserUnit,
+ m_grid->GetCellValue( row, GRID_uVIADRILL ) );
+
+ if( muviadrill >= muviadia )
+ {
+ result = false;
+ msg.Printf( _( "%s: <b>MicroVia Drill</b> &ge; <b>MicroVia Dia</b><br>" ),
+ GetChars( m_grid->GetRowLabelValue( row ) ) );
+ errorMsg += msg;
+ }
+
+ if( muviadrill < minUViaDrill )
+ {
+ result = false;
+ msg.Printf( _( "%s: <b>MicroVia Drill</b> &lt; <b>MicroVia Min Drill</b><br>" ),
+ GetChars( m_grid->GetRowLabelValue( row ) ) );
+ errorMsg += msg;
+ }
+ }
+
+ // Test custom tracks
+ for( int row = 0; row < m_gridTrackWidthList->GetNumberRows(); ++row )
+ {
+ wxString tvalue = m_gridTrackWidthList->GetCellValue( row, 0 );
+
+ if( tvalue.IsEmpty() )
+ continue;
+
+ int tracksize = ValueFromString( g_UserUnit, tvalue );
+
+ if( tracksize < minTrackWidth )
+ {
+ result = false;
+ msg.Printf( _( "<b>Extra Track %d Size</b> %s &lt; <b>Min Track Size</b><br>" ),
+ row + 1, GetChars( tvalue ) );
+
+ errorMsg += msg;
+ }
+
+ if( tracksize > maxval )
+ {
+ result = false;
+ msg.Printf( _( "<b>Extra Track %d Size</b> %s &gt; <b>1 inch!</b><br>" ),
+ row + 1, GetChars( tvalue ) );
+
+ errorMsg += msg;
+ }
+ }
+
+ // Test custom vias
+ for( int row = 0; row < m_gridViaSizeList->GetNumberRows(); ++row )
+ {
+ wxString tvalue = m_gridViaSizeList->GetCellValue( row, 0 );
+
+ if( tvalue.IsEmpty() )
+ continue;
+
+ int viadia = ValueFromString( g_UserUnit, tvalue );
+
+ if( viadia < minViaDia )
+ {
+ result = false;
+ msg.Printf( _( "<b>Extra Via %d Size</b> %s &lt; <b>Min Via Size</b><br>" ),
+ row + 1, GetChars( tvalue ) );
+ errorMsg += msg;
+ }
+
+ wxString drlvalue = m_gridViaSizeList->GetCellValue( row, 1 );
+
+ if( drlvalue.IsEmpty() )
+ {
+ result = false;
+ msg.Printf( _( "<b>No via drill size define in row %d</b><br>" ), row + 1 );
+ errorMsg += msg;
+ continue;
+ }
+
+ int viadrill = ValueFromString( g_UserUnit, drlvalue );
+
+ if( viadrill < minViaDrill )
+ {
+ result = false;
+ msg.Printf( _( "<b>Extra Via %d Drill</b> %s &lt; <b>Min Via Drill %s</b><br>" ),
+ row + 1, GetChars( drlvalue ),
+ GetChars( m_SetViasMinDrillCtrl->GetValue() ) );
+ errorMsg += msg;
+ }
+
+ if( viadia <= viadrill )
+ {
+ result = false;
+ msg.Printf( _( "<b>Extra Via %d Size</b> %s &le; <b> Drill Size</b> %s<br>" ),
+ row + 1, GetChars( tvalue ), GetChars( drlvalue ) );
+ errorMsg += msg;
+ }
+
+ // Test for a reasonable via size:
+ if( viadia > maxval ) // 1 inch!
+ {
+ result = false;
+ msg.Printf( _( "<b>Extra Via %d Size</b>%s &gt; <b>1 inch!</b><br>" ),
+ row + 1, GetChars( tvalue ) );
+ errorMsg += msg;
+ }
+ }
+
+ if( !result && aErrorMsg )
+ *aErrorMsg = errorMsg;
+
+ return result;
+}
diff --git a/pcbnew/dialogs/dialog_design_rules.h b/pcbnew/dialogs/dialog_design_rules.h
new file mode 100644
index 0000000..9544f92
--- /dev/null
+++ b/pcbnew/dialogs/dialog_design_rules.h
@@ -0,0 +1,190 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2009 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr
+ * Copyright (C) 2009 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2009-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/**
+ * @file dialog_design_rules.h
+ */
+
+#ifndef __dialog_design_rules_h_
+#define __dialog_design_rules_h_
+
+#include <../class_board.h>
+
+#include <dialog_design_rules_base.h>
+
+
+class PCB_EDIT_FRAME;
+class BOARD_DESIGN_SETTINGS;
+
+
+// helper struct to handle a net and its netclass in dialog design rule editor
+struct NETCUP
+{
+ NETCUP( const wxString& aNet, const wxString& aClass )
+ {
+ net = aNet;
+ clazz = aClass;
+ }
+
+ wxString net; ///< a net name
+ wxString clazz; ///< a class name
+};
+
+
+typedef std::vector<NETCUP> NETCUPS;
+typedef std::vector<NETCUP*> PNETCUPS;
+
+class DIALOG_DESIGN_RULES : public DIALOG_DESIGN_RULES_BASE
+{
+
+private:
+
+ static const wxString wildCard; ///< the name of a fictitious netclass which includes all NETs
+
+ PCB_EDIT_FRAME* m_Parent;
+ BOARD* m_Pcb;
+ BOARD_DESIGN_SETTINGS* m_BrdSettings;
+
+ static int s_LastTabSelection; ///< which tab user had open last
+
+ /**
+ * A two column table which gets filled once and never loses any elements, so it is
+ * basically constant, except that the NETCUP::clazz member can change for any
+ * given row a NET is moved in and out of a class. class reflects the respective
+ * NET's current net class.
+ */
+ NETCUPS m_AllNets;
+
+ // List of values to "customize" some tracks and vias
+ std::vector <VIA_DIMENSION> m_ViasDimensionsList;
+ std::vector <int> m_TracksWidthList;
+
+private:
+ void OnNetClassesNameLeftClick( wxGridEvent& event ){ event.Skip(); }
+ void OnNetClassesNameRightClick( wxGridEvent& event ){ event.Skip(); }
+ void OnAddNetclassClick( wxCommandEvent& event );
+ void OnRemoveNetclassClick( wxCommandEvent& event );
+
+ /*
+ * Called on "Move Up" button click
+ * the selected(s) rules are moved up
+ * The default netclass is always the first rule
+ */
+ void OnMoveUpSelectedNetClass( wxCommandEvent& event );
+
+ /*
+ * Called on the left Choice Box selection
+ */
+ void OnLeftCBSelection( wxCommandEvent& event );
+
+ /*
+ * Called on the Right Choice Box selection
+ */
+ void OnRightCBSelection( wxCommandEvent& event );
+
+ void OnRightToLeftCopyButton( wxCommandEvent& event );
+ void OnLeftToRightCopyButton( wxCommandEvent& event );
+
+ void OnNotebookPageChanged( wxNotebookEvent& event );
+
+ /*
+ * Called on clicking the left "select all" button:
+ * select all items of the left netname list list box
+ */
+ void OnLeftSelectAllButton( wxCommandEvent& event );
+
+ /*
+ * Called on clicking the right "select all" button:
+ * select all items of the right netname list list box
+ */
+ void OnRightSelectAllButton( wxCommandEvent& event );
+
+ /*
+ * Function TestDataValidity
+ *
+ * Performs a check of design rule data validity and displays an error message if errors
+ * are found.
+ * @param aErrorMsg is a pointer to a wxString to copy the error message into. Can be NULL.
+ * @return true if Ok, false if error
+ */
+ bool TestDataValidity( wxString* aErrorMsg = NULL );
+
+ void InitDialogRules();
+ void InitGlobalRules();
+
+ /**
+ * Function InitRulesList
+ * Fill the grid showing current rules with values
+ */
+ void InitRulesList();
+
+ /* Populates the lists of sizes (Tracks width list and Vias diameters & drill list) */
+ void InitDimensionsLists();
+
+ void InitializeRulesSelectionBoxes();
+
+ /* Copy the rules list from grid to board
+ */
+ void CopyRulesListToBoard();
+
+ void CopyGlobalRulesToBoard();
+ void CopyDimensionsListsToBoard( );
+ void SetRoutableLayerStatus();
+
+ /**
+ * Function FillListBoxWithNetNames
+ * populates aListCtrl with net names and class names from m_AllNets in a two column display.
+ */
+ void FillListBoxWithNetNames( NETS_LIST_CTRL* aListCtrl, const wxString& aNetClass );
+
+ /**
+ * Function swapNetClass
+ * replaces one net class name with another in the master list, m_AllNets.
+ */
+ void swapNetClass( const wxString& oldClass, const wxString& newClass )
+ {
+ for( NETCUPS::iterator i = m_AllNets.begin(); i!=m_AllNets.end(); ++i )
+ {
+ if( i->clazz == oldClass )
+ i->clazz = newClass;
+ }
+ }
+
+ void makePointers( PNETCUPS* aList, const wxString& aNetClassName );
+
+ void setNetClass( const wxString& aNetName, const wxString& aClassName );
+
+ void moveSelectedItems( NETS_LIST_CTRL* src, const wxString& newClassName );
+
+
+public:
+ DIALOG_DESIGN_RULES( PCB_EDIT_FRAME* parent );
+ ~DIALOG_DESIGN_RULES( ) { }
+
+ virtual bool TransferDataFromWindow();
+};
+
+#endif //__dialog_design_rules_h_
diff --git a/pcbnew/dialogs/dialog_design_rules_aux_helper_class.h b/pcbnew/dialogs/dialog_design_rules_aux_helper_class.h
new file mode 100644
index 0000000..bc8af25
--- /dev/null
+++ b/pcbnew/dialogs/dialog_design_rules_aux_helper_class.h
@@ -0,0 +1,78 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __dialog_design_rules_aux_helper_class_h_
+#define __dialog_design_rules_aux_helper_class_h_
+
+#include <wx/listctrl.h>
+
+/**
+ * Class NETS_LIST_CTRL
+ * is a helper to display lists of nets and associated netclasses
+ * used in dialog design rules.
+ * It's needed because the 2 "wxListCtl"s used to display lists of nets
+ * uses the wxLC_VIRTUAL option. The method:
+ *
+ * virtual wxString OnGetItemText( long item, long column ) const
+ *
+ * must be overloaded.
+ */
+class NETS_LIST_CTRL: public wxListCtrl
+{
+public:
+ NETS_LIST_CTRL( wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize, long style = wxLC_ICON ):
+ wxListCtrl( parent, id, pos, size, style )
+ {
+ };
+
+ void ClearList()
+ {
+ SetItemCount( 0 );
+ m_Netnames.Clear();
+ m_Classnames.Clear();
+ }
+
+ /**
+ * Function OnGetItemText
+ * is an overloaded method needed by wxListCtrl with wxLC_VIRTUAL options
+ */
+ virtual wxString OnGetItemText( long item, long column ) const;
+
+ /**
+ * Function SetRowItems
+ * sets the net name and the net class name at @a aRow.
+ * @param aRow = row index (if aRow > number of stored row, empty rows will be created)
+ * @param aNetname = the string to display in row aRow, column 0
+ * @param aNetclassName = the string to display in row aRow, column 1
+ */
+ void SetRowItems( unsigned aRow, const wxString& aNetname, const wxString& aNetclassName );
+
+private:
+ wxArrayString m_Netnames; ///< column 0: nets
+ wxArrayString m_Classnames; ///< column 1: netclasses
+};
+
+
+#endif //__dialog_design_rules_aux_helper_class_h_
diff --git a/pcbnew/dialogs/dialog_design_rules_base.cpp b/pcbnew/dialogs/dialog_design_rules_base.cpp
new file mode 100644
index 0000000..4fd6dc6
--- /dev/null
+++ b/pcbnew/dialogs/dialog_design_rules_base.cpp
@@ -0,0 +1,407 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_design_rules_aux_helper_class.h"
+
+#include "dialog_design_rules_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_DESIGN_RULES_BASE::DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_DRnotebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP );
+ m_panelNetClassesEditor = new wxPanel( m_DRnotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
+ wxBoxSizer* bpanelNetClassesSizer;
+ bpanelNetClassesSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbSizerUpper;
+ sbSizerUpper = new wxStaticBoxSizer( new wxStaticBox( m_panelNetClassesEditor, wxID_ANY, _("Net Classes:") ), wxVERTICAL );
+
+ m_grid = new wxGrid( m_panelNetClassesEditor, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxSIMPLE_BORDER|wxTAB_TRAVERSAL|wxVSCROLL );
+
+ // Grid
+ m_grid->CreateGrid( 1, 6 );
+ m_grid->EnableEditing( true );
+ m_grid->EnableGridLines( true );
+ m_grid->EnableDragGridSize( false );
+ m_grid->SetMargins( 0, 0 );
+
+ // Columns
+ m_grid->SetColSize( 0, 100 );
+ m_grid->SetColSize( 1, 120 );
+ m_grid->SetColSize( 2, 84 );
+ m_grid->SetColSize( 3, 85 );
+ m_grid->SetColSize( 4, 81 );
+ m_grid->SetColSize( 5, 90 );
+ m_grid->EnableDragColMove( false );
+ m_grid->EnableDragColSize( true );
+ m_grid->SetColLabelSize( 40 );
+ m_grid->SetColLabelValue( 0, _("Clearance") );
+ m_grid->SetColLabelValue( 1, _("Track Width") );
+ m_grid->SetColLabelValue( 2, _("Via Dia") );
+ m_grid->SetColLabelValue( 3, _("Via Drill") );
+ m_grid->SetColLabelValue( 4, _("uVia Dia") );
+ m_grid->SetColLabelValue( 5, _("uVia Drill") );
+ m_grid->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_grid->EnableDragRowSize( false );
+ m_grid->SetRowLabelSize( 120 );
+ m_grid->SetRowLabelValue( 0, _("Default") );
+ m_grid->SetRowLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ m_grid->SetToolTip( _("Net Class parameters") );
+
+ sbSizerUpper->Add( m_grid, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* buttonBoxSizer;
+ buttonBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ m_addButton = new wxButton( m_panelNetClassesEditor, wxID_ADD_NETCLASS, _("Add"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_addButton->SetToolTip( _("Add another Net Class") );
+
+ buttonBoxSizer->Add( m_addButton, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_removeButton = new wxButton( m_panelNetClassesEditor, wxID_REMOVE_NETCLASS, _("Remove"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_removeButton->SetToolTip( _("Remove the currently select Net Class\nThe default Net Class cannot be removed") );
+
+ buttonBoxSizer->Add( m_removeButton, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_moveUpButton = new wxButton( m_panelNetClassesEditor, wxID_ANY, _("Move Up"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_moveUpButton->SetToolTip( _("Move the currently selected Net Class up one row") );
+
+ buttonBoxSizer->Add( m_moveUpButton, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+
+ sbSizerUpper->Add( buttonBoxSizer, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+
+ bpanelNetClassesSizer->Add( sbSizerUpper, 2, wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ wxStaticBoxSizer* sbSizerNetSelectMain;
+ sbSizerNetSelectMain = new wxStaticBoxSizer( new wxStaticBox( m_panelNetClassesEditor, wxID_ANY, _("Membership:") ), wxHORIZONTAL );
+
+ wxBoxSizer* leftNetSelectBoxSizer;
+ leftNetSelectBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_leftClassChoice = new wxComboBox( m_panelNetClassesEditor, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
+ leftNetSelectBoxSizer->Add( m_leftClassChoice, 0, wxEXPAND, 5 );
+
+ m_leftListCtrl = new NETS_LIST_CTRL( m_panelNetClassesEditor, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VIRTUAL|wxLC_VRULES|wxSUNKEN_BORDER );
+ leftNetSelectBoxSizer->Add( m_leftListCtrl, 1, wxEXPAND|wxTOP, 5 );
+
+
+ sbSizerNetSelectMain->Add( leftNetSelectBoxSizer, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bmiddleSizerNetSelect;
+ bmiddleSizerNetSelect = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonRightToLeft = new wxButton( m_panelNetClassesEditor, ID_LEFT_TO_RIGHT_COPY, _("<<<"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonRightToLeft->SetToolTip( _("Move the selected nets in the right list to the left list") );
+
+ bmiddleSizerNetSelect->Add( m_buttonRightToLeft, 0, wxALL, 5 );
+
+ m_buttonLeftToRight = new wxButton( m_panelNetClassesEditor, ID_RIGHT_TO_LEFT_COPY, _(">>>"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonLeftToRight->SetToolTip( _("Move the selected nets in the left list to the right list") );
+
+ bmiddleSizerNetSelect->Add( m_buttonLeftToRight, 0, wxALL, 5 );
+
+ m_buttonLeftSelAll = new wxButton( m_panelNetClassesEditor, wxID_ANY, _("<< Select All"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonLeftSelAll->SetToolTip( _("Select all nets in the left list") );
+
+ bmiddleSizerNetSelect->Add( m_buttonLeftSelAll, 0, wxALL, 5 );
+
+ m_buttonRightSelAll = new wxButton( m_panelNetClassesEditor, wxID_ANY, _("Select All >>"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonRightSelAll->SetToolTip( _("Select all nets in the right list") );
+
+ bmiddleSizerNetSelect->Add( m_buttonRightSelAll, 0, wxALL, 5 );
+
+
+ sbSizerNetSelectMain->Add( bmiddleSizerNetSelect, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ wxBoxSizer* rghtNetSelectBoxSizer;
+ rghtNetSelectBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_rightClassChoice = new wxComboBox( m_panelNetClassesEditor, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
+ rghtNetSelectBoxSizer->Add( m_rightClassChoice, 0, wxEXPAND, 5 );
+
+ m_rightListCtrl = new NETS_LIST_CTRL( m_panelNetClassesEditor, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VIRTUAL|wxLC_VRULES|wxSUNKEN_BORDER );
+ rghtNetSelectBoxSizer->Add( m_rightListCtrl, 1, wxEXPAND|wxTOP, 5 );
+
+
+ sbSizerNetSelectMain->Add( rghtNetSelectBoxSizer, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+
+ bpanelNetClassesSizer->Add( sbSizerNetSelectMain, 3, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+
+ m_panelNetClassesEditor->SetSizer( bpanelNetClassesSizer );
+ m_panelNetClassesEditor->Layout();
+ bpanelNetClassesSizer->Fit( m_panelNetClassesEditor );
+ m_DRnotebook->AddPage( m_panelNetClassesEditor, _("Net Classes Editor"), true );
+ m_panelGolbalDesignRules = new wxPanel( m_DRnotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
+ wxBoxSizer* bpanelGlobRulesSizer;
+ bpanelGlobRulesSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bDesignRulesUpperSizer;
+ bDesignRulesUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sbViasOptionSizer;
+ sbViasOptionSizer = new wxStaticBoxSizer( new wxStaticBox( m_panelGolbalDesignRules, wxID_ANY, _("Via Options:") ), wxVERTICAL );
+
+ wxString m_OptViaTypeChoices[] = { _("Do not allow blind/buried vias"), _("Allow blind/buried vias") };
+ int m_OptViaTypeNChoices = sizeof( m_OptViaTypeChoices ) / sizeof( wxString );
+ m_OptViaType = new wxRadioBox( m_panelGolbalDesignRules, wxID_ANY, _("Blind/buried Vias:"), wxDefaultPosition, wxDefaultSize, m_OptViaTypeNChoices, m_OptViaTypeChoices, 1, wxRA_SPECIFY_COLS );
+ m_OptViaType->SetSelection( 0 );
+ m_OptViaType->SetToolTip( _("Allows or not blind/buried vias.\nDo not allow is the usual selection.\nNote: micro vias are a special type of blind vias and are not managed here") );
+
+ sbViasOptionSizer->Add( m_OptViaType, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_AllowMicroViaCtrlChoices[] = { _("Do not allow micro vias"), _("Allow micro vias") };
+ int m_AllowMicroViaCtrlNChoices = sizeof( m_AllowMicroViaCtrlChoices ) / sizeof( wxString );
+ m_AllowMicroViaCtrl = new wxRadioBox( m_panelGolbalDesignRules, wxID_ANY, _("Micro Vias:"), wxDefaultPosition, wxDefaultSize, m_AllowMicroViaCtrlNChoices, m_AllowMicroViaCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_AllowMicroViaCtrl->SetSelection( 0 );
+ m_AllowMicroViaCtrl->SetToolTip( _("Allows or do not allow use of micro vias\nThey are very small vias only from an external copper layer to its near neightbour") );
+
+ sbViasOptionSizer->Add( m_AllowMicroViaCtrl, 0, wxALL|wxEXPAND, 5 );
+
+
+ bDesignRulesUpperSizer->Add( sbViasOptionSizer, 1, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ wxStaticBoxSizer* sbMinSizesSizer;
+ sbMinSizesSizer = new wxStaticBoxSizer( new wxStaticBox( m_panelGolbalDesignRules, wxID_ANY, _("Minimum Allowed Values:") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgMinValuesSizer;
+ fgMinValuesSizer = new wxFlexGridSizer( 5, 2, 0, 0 );
+ fgMinValuesSizer->AddGrowableCol( 1 );
+ fgMinValuesSizer->SetFlexibleDirection( wxBOTH );
+ fgMinValuesSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_TrackMinWidthTitle = new wxStaticText( m_panelGolbalDesignRules, wxID_ANY, _("Min track width"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackMinWidthTitle->Wrap( -1 );
+ fgMinValuesSizer->Add( m_TrackMinWidthTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ m_SetTrackMinWidthCtrl = new wxTextCtrl( m_panelGolbalDesignRules, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SetTrackMinWidthCtrl->SetMaxLength( 0 );
+ fgMinValuesSizer->Add( m_SetTrackMinWidthCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_ViaMinTitle = new wxStaticText( m_panelGolbalDesignRules, wxID_ANY, _("Min via diameter"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaMinTitle->Wrap( -1 );
+ fgMinValuesSizer->Add( m_ViaMinTitle, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT, 5 );
+
+ m_SetViasMinSizeCtrl = new wxTextCtrl( m_panelGolbalDesignRules, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SetViasMinSizeCtrl->SetMaxLength( 0 );
+ fgMinValuesSizer->Add( m_SetViasMinSizeCtrl, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_ViaMinDrillTitle = new wxStaticText( m_panelGolbalDesignRules, wxID_ANY, _("Min via drill dia"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaMinDrillTitle->Wrap( -1 );
+ fgMinValuesSizer->Add( m_ViaMinDrillTitle, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT, 5 );
+
+ m_SetViasMinDrillCtrl = new wxTextCtrl( m_panelGolbalDesignRules, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SetViasMinDrillCtrl->SetMaxLength( 0 );
+ fgMinValuesSizer->Add( m_SetViasMinDrillCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_MicroViaMinSizeTitle = new wxStaticText( m_panelGolbalDesignRules, wxID_ANY, _("Min uvia diameter"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MicroViaMinSizeTitle->Wrap( -1 );
+ fgMinValuesSizer->Add( m_MicroViaMinSizeTitle, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT, 5 );
+
+ m_SetMicroViasMinSizeCtrl = new wxTextCtrl( m_panelGolbalDesignRules, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SetMicroViasMinSizeCtrl->SetMaxLength( 6 );
+ fgMinValuesSizer->Add( m_SetMicroViasMinSizeCtrl, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_MicroViaMinDrillTitle = new wxStaticText( m_panelGolbalDesignRules, wxID_ANY, _("Min uvia drill dia"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MicroViaMinDrillTitle->Wrap( -1 );
+ fgMinValuesSizer->Add( m_MicroViaMinDrillTitle, 0, wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ m_SetMicroViasMinDrillCtrl = new wxTextCtrl( m_panelGolbalDesignRules, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SetMicroViasMinDrillCtrl->SetMaxLength( 6 );
+ fgMinValuesSizer->Add( m_SetMicroViasMinDrillCtrl, 0, wxEXPAND|wxALL, 5 );
+
+
+ sbMinSizesSizer->Add( fgMinValuesSizer, 1, wxEXPAND, 5 );
+
+
+ bDesignRulesUpperSizer->Add( sbMinSizesSizer, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+
+ bpanelGlobRulesSizer->Add( bDesignRulesUpperSizer, 0, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( m_panelGolbalDesignRules, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bpanelGlobRulesSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_staticTextInfo = new wxStaticText( m_panelGolbalDesignRules, wxID_ANY, _("Specific via diameters and track widths, which \ncan be used to replace default Netclass values \non demand, for arbitrary vias or track segments."), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextInfo->Wrap( -1 );
+ bpanelGlobRulesSizer->Add( m_staticTextInfo, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
+
+ wxBoxSizer* bDesignRulesLowerSizer;
+ bDesignRulesLowerSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sViaSizeBox;
+ sViaSizeBox = new wxStaticBoxSizer( new wxStaticBox( m_panelGolbalDesignRules, wxID_ANY, _("Custom Via Sizes:") ), wxVERTICAL );
+
+ m_staticText7 = new wxStaticText( m_panelGolbalDesignRules, wxID_ANY, _("Drill value: a blank or 0 => default Netclass value"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText7->Wrap( -1 );
+ sViaSizeBox->Add( m_staticText7, 0, wxALL, 5 );
+
+ m_gridViaSizeList = new wxGrid( m_panelGolbalDesignRules, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_gridViaSizeList->CreateGrid( 8, 2 );
+ m_gridViaSizeList->EnableEditing( true );
+ m_gridViaSizeList->EnableGridLines( true );
+ m_gridViaSizeList->EnableDragGridSize( false );
+ m_gridViaSizeList->SetMargins( 0, 0 );
+
+ // Columns
+ m_gridViaSizeList->EnableDragColMove( false );
+ m_gridViaSizeList->EnableDragColSize( true );
+ m_gridViaSizeList->SetColLabelSize( 30 );
+ m_gridViaSizeList->SetColLabelValue( 0, _("Diameter") );
+ m_gridViaSizeList->SetColLabelValue( 1, _("Drill") );
+ m_gridViaSizeList->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_gridViaSizeList->EnableDragRowSize( true );
+ m_gridViaSizeList->SetRowLabelSize( 80 );
+ m_gridViaSizeList->SetRowLabelValue( 0, _("Via 1") );
+ m_gridViaSizeList->SetRowLabelValue( 1, _("Via 2") );
+ m_gridViaSizeList->SetRowLabelValue( 2, _("Via 3") );
+ m_gridViaSizeList->SetRowLabelValue( 3, _("Via 4") );
+ m_gridViaSizeList->SetRowLabelValue( 4, _("Via 5") );
+ m_gridViaSizeList->SetRowLabelValue( 5, _("Via 6") );
+ m_gridViaSizeList->SetRowLabelValue( 6, _("Via 7") );
+ m_gridViaSizeList->SetRowLabelValue( 7, _("Via 8") );
+ m_gridViaSizeList->SetRowLabelValue( 8, _("Via 9") );
+ m_gridViaSizeList->SetRowLabelValue( 9, _("Via 10") );
+ m_gridViaSizeList->SetRowLabelValue( 10, _("Via 11") );
+ m_gridViaSizeList->SetRowLabelValue( 11, _("Via 12") );
+ m_gridViaSizeList->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_gridViaSizeList->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ sViaSizeBox->Add( m_gridViaSizeList, 1, wxALL|wxEXPAND, 5 );
+
+
+ bDesignRulesLowerSizer->Add( sViaSizeBox, 1, wxALL|wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbTracksListSizer;
+ sbTracksListSizer = new wxStaticBoxSizer( new wxStaticBox( m_panelGolbalDesignRules, wxID_ANY, _("Custom Track Widths:") ), wxVERTICAL );
+
+ m_staticText8 = new wxStaticText( m_panelGolbalDesignRules, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText8->Wrap( -1 );
+ sbTracksListSizer->Add( m_staticText8, 0, wxALL, 5 );
+
+ m_gridTrackWidthList = new wxGrid( m_panelGolbalDesignRules, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_gridTrackWidthList->CreateGrid( 8, 1 );
+ m_gridTrackWidthList->EnableEditing( true );
+ m_gridTrackWidthList->EnableGridLines( true );
+ m_gridTrackWidthList->EnableDragGridSize( false );
+ m_gridTrackWidthList->SetMargins( 0, 0 );
+
+ // Columns
+ m_gridTrackWidthList->EnableDragColMove( false );
+ m_gridTrackWidthList->EnableDragColSize( true );
+ m_gridTrackWidthList->SetColLabelSize( 30 );
+ m_gridTrackWidthList->SetColLabelValue( 0, _("Width") );
+ m_gridTrackWidthList->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_gridTrackWidthList->EnableDragRowSize( true );
+ m_gridTrackWidthList->SetRowLabelSize( 80 );
+ m_gridTrackWidthList->SetRowLabelValue( 0, _("Track 1") );
+ m_gridTrackWidthList->SetRowLabelValue( 1, _("Track 2") );
+ m_gridTrackWidthList->SetRowLabelValue( 2, _("Track 3") );
+ m_gridTrackWidthList->SetRowLabelValue( 3, _("Track 4") );
+ m_gridTrackWidthList->SetRowLabelValue( 4, _("Track 5") );
+ m_gridTrackWidthList->SetRowLabelValue( 5, _("Track 6") );
+ m_gridTrackWidthList->SetRowLabelValue( 6, _("Track 7") );
+ m_gridTrackWidthList->SetRowLabelValue( 7, _("Track 8") );
+ m_gridTrackWidthList->SetRowLabelValue( 8, _("Track 9") );
+ m_gridTrackWidthList->SetRowLabelValue( 9, _("Track 10") );
+ m_gridTrackWidthList->SetRowLabelValue( 10, _("Track 11") );
+ m_gridTrackWidthList->SetRowLabelValue( 11, _("Track 12") );
+ m_gridTrackWidthList->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_gridTrackWidthList->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ sbTracksListSizer->Add( m_gridTrackWidthList, 1, wxALL|wxEXPAND, 5 );
+
+
+ bDesignRulesLowerSizer->Add( sbTracksListSizer, 1, wxALL|wxEXPAND, 5 );
+
+
+ bpanelGlobRulesSizer->Add( bDesignRulesLowerSizer, 0, wxEXPAND, 5 );
+
+
+ m_panelGolbalDesignRules->SetSizer( bpanelGlobRulesSizer );
+ m_panelGolbalDesignRules->Layout();
+ bpanelGlobRulesSizer->Fit( m_panelGolbalDesignRules );
+ m_DRnotebook->AddPage( m_panelGolbalDesignRules, _("Global Design Rules"), false );
+
+ bMainSizer->Add( m_DRnotebook, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bMainSizer->Add( m_sdbSizer1, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ m_DRnotebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_DESIGN_RULES_BASE::OnNotebookPageChanged ), NULL, this );
+ m_grid->Connect( wxEVT_GRID_LABEL_LEFT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesNameLeftClick ), NULL, this );
+ m_grid->Connect( wxEVT_GRID_LABEL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesNameRightClick ), NULL, this );
+ m_addButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnAddNetclassClick ), NULL, this );
+ m_removeButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRemoveNetclassClick ), NULL, this );
+ m_moveUpButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnMoveUpSelectedNetClass ), NULL, this );
+ m_leftClassChoice->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftCBSelection ), NULL, this );
+ m_buttonRightToLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightToLeftCopyButton ), NULL, this );
+ m_buttonLeftToRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftToRightCopyButton ), NULL, this );
+ m_buttonLeftSelAll->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftSelectAllButton ), NULL, this );
+ m_buttonRightSelAll->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightSelectAllButton ), NULL, this );
+ m_rightClassChoice->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightCBSelection ), NULL, this );
+}
+
+DIALOG_DESIGN_RULES_BASE::~DIALOG_DESIGN_RULES_BASE()
+{
+ // Disconnect Events
+ m_DRnotebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_DESIGN_RULES_BASE::OnNotebookPageChanged ), NULL, this );
+ m_grid->Disconnect( wxEVT_GRID_LABEL_LEFT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesNameLeftClick ), NULL, this );
+ m_grid->Disconnect( wxEVT_GRID_LABEL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesNameRightClick ), NULL, this );
+ m_addButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnAddNetclassClick ), NULL, this );
+ m_removeButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRemoveNetclassClick ), NULL, this );
+ m_moveUpButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnMoveUpSelectedNetClass ), NULL, this );
+ m_leftClassChoice->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftCBSelection ), NULL, this );
+ m_buttonRightToLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightToLeftCopyButton ), NULL, this );
+ m_buttonLeftToRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftToRightCopyButton ), NULL, this );
+ m_buttonLeftSelAll->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftSelectAllButton ), NULL, this );
+ m_buttonRightSelAll->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightSelectAllButton ), NULL, this );
+ m_rightClassChoice->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightCBSelection ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_design_rules_base.fbp b/pcbnew/dialogs/dialog_design_rules_base.fbp
new file mode 100644
index 0000000..4d2392d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_design_rules_base.fbp
@@ -0,0 +1,3366 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_design_rules_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_design_rules_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_DESIGN_RULES_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Design Rules Editor</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxNotebook" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmapsize"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DRnotebook</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxNB_TOP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnNotebookPageChanged">OnNotebookPageChanged</event>
+ <event name="OnNotebookPageChanging"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Net Classes Editor</property>
+ <property name="select">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_panelNetClassesEditor</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxSUNKEN_BORDER|wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bpanelNetClassesSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">2</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Net Classes:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerUpper</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">0</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg"></property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">40</property>
+ <property name="col_label_values">&quot;Clearance&quot; &quot;Track Width&quot; &quot;Via Dia&quot; &quot;Via Drill&quot; &quot;uVia Dia&quot; &quot;uVia Drill&quot;</property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">6</property>
+ <property name="column_sizes">100,120,84,85,81,90</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">0</property>
+ <property name="editing">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_grid</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="row_label_size">120</property>
+ <property name="row_label_values">&quot;Default&quot;</property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Net Class parameters</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxHSCROLL|wxSIMPLE_BORDER|wxTAB_TRAVERSAL|wxVSCROLL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick"></event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick">OnNetClassesNameLeftClick</event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick">OnNetClassesNameRightClick</event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">buttonBoxSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ADD_NETCLASS</property>
+ <property name="label">Add</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_addButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Add another Net Class</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnAddNetclassClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_REMOVE_NETCLASS</property>
+ <property name="label">Remove</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_removeButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Remove the currently select Net Class&#x0A;The default Net Class cannot be removed</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnRemoveNetclassClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Move Up</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_moveUpButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Move the currently selected Net Class up one row</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnMoveUpSelectedNetClass</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">3</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Membership:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerNetSelectMain</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">leftNetSelectBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_leftClassChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxCB_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox">OnLeftCBSelection</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxListCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_leftListCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLC_HRULES|wxLC_REPORT|wxLC_VIRTUAL|wxLC_VRULES</property>
+ <property name="subclass">NETS_LIST_CTRL; dialog_design_rules_aux_helper_class.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxSUNKEN_BORDER</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBeginDrag"></event>
+ <event name="OnListBeginLabelEdit"></event>
+ <event name="OnListBeginRDrag"></event>
+ <event name="OnListCacheHint"></event>
+ <event name="OnListColBeginDrag"></event>
+ <event name="OnListColClick"></event>
+ <event name="OnListColDragging"></event>
+ <event name="OnListColEndDrag"></event>
+ <event name="OnListColRightClick"></event>
+ <event name="OnListDeleteAllItems"></event>
+ <event name="OnListDeleteItem"></event>
+ <event name="OnListEndLabelEdit"></event>
+ <event name="OnListInsertItem"></event>
+ <event name="OnListItemActivated"></event>
+ <event name="OnListItemDeselected"></event>
+ <event name="OnListItemFocused"></event>
+ <event name="OnListItemMiddleClick"></event>
+ <event name="OnListItemRightClick"></event>
+ <event name="OnListItemSelected"></event>
+ <event name="OnListKeyDown"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmiddleSizerNetSelect</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_LEFT_TO_RIGHT_COPY</property>
+ <property name="label">&lt;&lt;&lt;</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonRightToLeft</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Move the selected nets in the right list to the left list</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnRightToLeftCopyButton</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_RIGHT_TO_LEFT_COPY</property>
+ <property name="label">&gt;&gt;&gt;</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonLeftToRight</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Move the selected nets in the left list to the right list</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnLeftToRightCopyButton</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&lt;&lt; Select All</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonLeftSelAll</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Select all nets in the left list</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnLeftSelectAllButton</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Select All &gt;&gt;</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonRightSelAll</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Select all nets in the right list</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnRightSelectAllButton</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">rghtNetSelectBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rightClassChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxCB_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox">OnRightCBSelection</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxListCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_rightListCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLC_HRULES|wxLC_REPORT|wxLC_VIRTUAL|wxLC_VRULES</property>
+ <property name="subclass">NETS_LIST_CTRL; dialog_design_rules_aux_helper_class.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxSUNKEN_BORDER</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBeginDrag"></event>
+ <event name="OnListBeginLabelEdit"></event>
+ <event name="OnListBeginRDrag"></event>
+ <event name="OnListCacheHint"></event>
+ <event name="OnListColBeginDrag"></event>
+ <event name="OnListColClick"></event>
+ <event name="OnListColDragging"></event>
+ <event name="OnListColEndDrag"></event>
+ <event name="OnListColRightClick"></event>
+ <event name="OnListDeleteAllItems"></event>
+ <event name="OnListDeleteItem"></event>
+ <event name="OnListEndLabelEdit"></event>
+ <event name="OnListInsertItem"></event>
+ <event name="OnListItemActivated"></event>
+ <event name="OnListItemDeselected"></event>
+ <event name="OnListItemFocused"></event>
+ <event name="OnListItemMiddleClick"></event>
+ <event name="OnListItemRightClick"></event>
+ <event name="OnListItemSelected"></event>
+ <event name="OnListKeyDown"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Global Design Rules</property>
+ <property name="select">0</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_panelGolbalDesignRules</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxSUNKEN_BORDER|wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bpanelGlobRulesSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bDesignRulesUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Via Options:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbViasOptionSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Do not allow blind/buried vias&quot; &quot;Allow blind/buried vias&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Blind/buried Vias:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptViaType</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Allows or not blind/buried vias.&#x0A;Do not allow is the usual selection.&#x0A;Note: micro vias are a special type of blind vias and are not managed here</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Do not allow micro vias&quot; &quot;Allow micro vias&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Micro Vias:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AllowMicroViaCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Allows or do not allow use of micro vias&#x0A;They are very small vias only from an external copper layer to its near neightbour</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Minimum Allowed Values:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbMinSizesSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgMinValuesSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">5</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Min track width</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackMinWidthTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SetTrackMinWidthCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Min via diameter</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaMinTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SetViasMinSizeCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Min via drill dia</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaMinDrillTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SetViasMinDrillCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Min uvia diameter</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MicroViaMinSizeTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">6</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SetMicroViasMinSizeCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Min uvia drill dia</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MicroViaMinDrillTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">6</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SetMicroViasMinDrillCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_HORIZONTAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Specific via diameters and track widths, which &#x0A;can be used to replace default Netclass values &#x0A;on demand, for arbitrary vias or track segments.</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextInfo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bDesignRulesLowerSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Custom Via Sizes:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sViaSizeBox</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Drill value: a blank or 0 =&gt; default Netclass value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText7</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">0</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg"></property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">30</property>
+ <property name="col_label_values">&quot;Diameter&quot; &quot;Drill&quot;</property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">2</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">1</property>
+ <property name="editing">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_gridViaSizeList</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">80</property>
+ <property name="row_label_values">&quot;Via 1&quot; &quot;Via 2&quot; &quot;Via 3&quot; &quot;Via 4&quot; &quot;Via 5&quot; &quot;Via 6&quot; &quot;Via 7&quot; &quot;Via 8&quot; &quot;Via 9&quot; &quot;Via 10&quot; &quot;Via 11&quot; &quot;Via 12&quot;</property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">8</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick"></event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Custom Track Widths:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbTracksListSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText8</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">0</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg"></property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">30</property>
+ <property name="col_label_values">&quot;Width&quot;</property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">1</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">1</property>
+ <property name="editing">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_gridTrackWidthList</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">80</property>
+ <property name="row_label_values">&quot;Track 1&quot; &quot;Track 2&quot; &quot;Track 3&quot; &quot;Track 4&quot; &quot;Track 5&quot; &quot;Track 6&quot; &quot;Track 7&quot; &quot;Track 8&quot; &quot;Track 9&quot; &quot;Track 10&quot; &quot;Track 11&quot; &quot;Track 12&quot;</property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">8</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick"></event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_design_rules_base.h b/pcbnew/dialogs/dialog_design_rules_base.h
new file mode 100644
index 0000000..0de97bf
--- /dev/null
+++ b/pcbnew/dialogs/dialog_design_rules_base.h
@@ -0,0 +1,117 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_DESIGN_RULES_BASE_H__
+#define __DIALOG_DESIGN_RULES_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class NETS_LIST_CTRL;
+
+#include "dialog_shim.h"
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/string.h>
+#include <wx/font.h>
+#include <wx/grid.h>
+#include <wx/gdicmn.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/combobox.h>
+#include <wx/listctrl.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/radiobox.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/statline.h>
+#include <wx/notebook.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_DESIGN_RULES_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_DESIGN_RULES_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ wxID_ADD_NETCLASS = 1000,
+ wxID_REMOVE_NETCLASS,
+ ID_LEFT_TO_RIGHT_COPY,
+ ID_RIGHT_TO_LEFT_COPY
+ };
+
+ wxNotebook* m_DRnotebook;
+ wxPanel* m_panelNetClassesEditor;
+ wxGrid* m_grid;
+ wxButton* m_addButton;
+ wxButton* m_removeButton;
+ wxButton* m_moveUpButton;
+ wxComboBox* m_leftClassChoice;
+ NETS_LIST_CTRL* m_leftListCtrl;
+ wxButton* m_buttonRightToLeft;
+ wxButton* m_buttonLeftToRight;
+ wxButton* m_buttonLeftSelAll;
+ wxButton* m_buttonRightSelAll;
+ wxComboBox* m_rightClassChoice;
+ NETS_LIST_CTRL* m_rightListCtrl;
+ wxPanel* m_panelGolbalDesignRules;
+ wxRadioBox* m_OptViaType;
+ wxRadioBox* m_AllowMicroViaCtrl;
+ wxStaticText* m_TrackMinWidthTitle;
+ wxTextCtrl* m_SetTrackMinWidthCtrl;
+ wxStaticText* m_ViaMinTitle;
+ wxTextCtrl* m_SetViasMinSizeCtrl;
+ wxStaticText* m_ViaMinDrillTitle;
+ wxTextCtrl* m_SetViasMinDrillCtrl;
+ wxStaticText* m_MicroViaMinSizeTitle;
+ wxTextCtrl* m_SetMicroViasMinSizeCtrl;
+ wxStaticText* m_MicroViaMinDrillTitle;
+ wxTextCtrl* m_SetMicroViasMinDrillCtrl;
+ wxStaticLine* m_staticline1;
+ wxStaticText* m_staticTextInfo;
+ wxStaticText* m_staticText7;
+ wxGrid* m_gridViaSizeList;
+ wxStaticText* m_staticText8;
+ wxGrid* m_gridTrackWidthList;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnNotebookPageChanged( wxNotebookEvent& event ) { event.Skip(); }
+ virtual void OnNetClassesNameLeftClick( wxGridEvent& event ) { event.Skip(); }
+ virtual void OnNetClassesNameRightClick( wxGridEvent& event ) { event.Skip(); }
+ virtual void OnAddNetclassClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRemoveNetclassClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnMoveUpSelectedNetClass( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnLeftCBSelection( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRightToLeftCopyButton( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnLeftToRightCopyButton( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnLeftSelectAllButton( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRightSelectAllButton( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRightCBSelection( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Design Rules Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_DESIGN_RULES_BASE();
+
+};
+
+#endif //__DIALOG_DESIGN_RULES_BASE_H__
diff --git a/pcbnew/dialogs/dialog_dimension_editor_base.cpp b/pcbnew/dialogs/dialog_dimension_editor_base.cpp
new file mode 100644
index 0000000..96205bb
--- /dev/null
+++ b/pcbnew/dialogs/dialog_dimension_editor_base.cpp
@@ -0,0 +1,132 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "class_pcb_layer_box_selector.h"
+
+#include "dialog_dimension_editor_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_DIMENSION_EDITOR_BASE::DIALOG_DIMENSION_EDITOR_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextDim = new wxStaticText( this, wxID_ANY, _("Text"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextDim->Wrap( -1 );
+ bSizerMain->Add( m_staticTextDim, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_Name = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_Name->SetMaxLength( 0 );
+ m_Name->SetMinSize( wxSize( 400,-1 ) );
+
+ bSizerMain->Add( m_Name, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizerLeft;
+ bSizerLeft = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextSizeX = new wxStaticText( this, wxID_ANY, _("Text Width"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSizeX->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextSizeX, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_TxtSizeXCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_TxtSizeXCtrl->SetMaxLength( 0 );
+ bSizerLeft->Add( m_TxtSizeXCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_staticTextSizeY = new wxStaticText( this, wxID_ANY, _("Text Height"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSizeY->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextSizeY, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_TxtSizeYCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_TxtSizeYCtrl->SetMaxLength( 0 );
+ bSizerLeft->Add( m_TxtSizeYCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_staticTextWidth = new wxStaticText( this, wxID_ANY, _("Text Thickness"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextWidth->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextWidth, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_TxtWidthCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_TxtWidthCtrl->SetMaxLength( 0 );
+ bSizerLeft->Add( m_TxtWidthCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_staticTextPosX = new wxStaticText( this, wxID_ANY, _("Text Position X"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextPosX->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextPosX, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_textCtrlPosX = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textCtrlPosX->SetMaxLength( 0 );
+ bSizerLeft->Add( m_textCtrlPosX, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_staticTextPosY = new wxStaticText( this, wxID_ANY, _("Text Position Y"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextPosY->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextPosY, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_textCtrlPosY = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textCtrlPosY->SetMaxLength( 0 );
+ bSizerLeft->Add( m_textCtrlPosY, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerUpper->Add( bSizerLeft, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerRight;
+ bSizerRight = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_rbMirrorChoices[] = { _("Normal"), _("Mirror") };
+ int m_rbMirrorNChoices = sizeof( m_rbMirrorChoices ) / sizeof( wxString );
+ m_rbMirror = new wxRadioBox( this, wxID_ANY, _("Display"), wxDefaultPosition, wxDefaultSize, m_rbMirrorNChoices, m_rbMirrorChoices, 1, wxRA_SPECIFY_COLS );
+ m_rbMirror->SetSelection( 0 );
+ bSizerRight->Add( m_rbMirror, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticTextLayer = new wxStaticText( this, wxID_ANY, _("Layer"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextLayer->Wrap( -1 );
+ bSizerRight->Add( m_staticTextLayer, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_SelLayerBox = new PCB_LAYER_BOX_SELECTOR( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ bSizerRight->Add( m_SelLayerBox, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerUpper->Add( bSizerRight, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bSizerMain->Add( bSizerUpper, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerMain->Add( m_staticline1, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_sdbSizerBts = new wxStdDialogButtonSizer();
+ m_sdbSizerBtsOK = new wxButton( this, wxID_OK );
+ m_sdbSizerBts->AddButton( m_sdbSizerBtsOK );
+ m_sdbSizerBtsCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizerBts->AddButton( m_sdbSizerBtsCancel );
+ m_sdbSizerBts->Realize();
+
+ bSizerMain->Add( m_sdbSizerBts, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+ bSizerMain->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_sdbSizerBtsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DIMENSION_EDITOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerBtsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DIMENSION_EDITOR_BASE::OnOKClick ), NULL, this );
+}
+
+DIALOG_DIMENSION_EDITOR_BASE::~DIALOG_DIMENSION_EDITOR_BASE()
+{
+ // Disconnect Events
+ m_sdbSizerBtsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DIMENSION_EDITOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerBtsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DIMENSION_EDITOR_BASE::OnOKClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_dimension_editor_base.fbp b/pcbnew/dialogs/dialog_dimension_editor_base.fbp
new file mode 100644
index 0000000..96e453c
--- /dev/null
+++ b/pcbnew/dialogs/dialog_dimension_editor_base.fbp
@@ -0,0 +1,1547 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_dimension_editor_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_dimension_editor_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_DIMENSION_EDITOR_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Dimension Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextDim</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">400,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerLeft</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text Width</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSizeX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TxtSizeXCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text Height</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSizeY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TxtSizeYCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text Thickness</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TxtWidthCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text Position X</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextPosX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlPosX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text Position Y</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextPosY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlPosY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRight</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Normal&quot; &quot;Mirror&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Display</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbMirror</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layer</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextLayer</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxBitmapComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SelLayerBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">PCB_LAYER_BOX_SELECTOR; class_pcb_layer_box_selector.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizerBts</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_dimension_editor_base.h b/pcbnew/dialogs/dialog_dimension_editor_base.h
new file mode 100644
index 0000000..6b03a0b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_dimension_editor_base.h
@@ -0,0 +1,75 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_DIMENSION_EDITOR_BASE_H__
+#define __DIALOG_DIMENSION_EDITOR_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class PCB_LAYER_BOX_SELECTOR;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/radiobox.h>
+#include <wx/bmpcbox.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_DIMENSION_EDITOR_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_DIMENSION_EDITOR_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticTextDim;
+ wxTextCtrl* m_Name;
+ wxStaticText* m_staticTextSizeX;
+ wxTextCtrl* m_TxtSizeXCtrl;
+ wxStaticText* m_staticTextSizeY;
+ wxTextCtrl* m_TxtSizeYCtrl;
+ wxStaticText* m_staticTextWidth;
+ wxTextCtrl* m_TxtWidthCtrl;
+ wxStaticText* m_staticTextPosX;
+ wxTextCtrl* m_textCtrlPosX;
+ wxStaticText* m_staticTextPosY;
+ wxTextCtrl* m_textCtrlPosY;
+ wxRadioBox* m_rbMirror;
+ wxStaticText* m_staticTextLayer;
+ PCB_LAYER_BOX_SELECTOR* m_SelLayerBox;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizerBts;
+ wxButton* m_sdbSizerBtsOK;
+ wxButton* m_sdbSizerBtsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_DIMENSION_EDITOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Dimension Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_DIMENSION_EDITOR_BASE();
+
+};
+
+#endif //__DIALOG_DIMENSION_EDITOR_BASE_H__
diff --git a/pcbnew/dialogs/dialog_display_options.cpp b/pcbnew/dialogs/dialog_display_options.cpp
new file mode 100644
index 0000000..5e4c7c3
--- /dev/null
+++ b/pcbnew/dialogs/dialog_display_options.cpp
@@ -0,0 +1,186 @@
+/**
+ * @file pcbnew/dialogs/dialog_general_options.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* functions relatives to the dialog opened from the main menu :
+ Preferences/display
+*/
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <pcbstruct.h>
+
+#include <pcbnew_id.h>
+
+#include <dialog_display_options.h>
+#include <dialog_display_options_base.h>
+
+#include <class_draw_panel_gal.h>
+#include <view/view.h>
+#include <pcb_painter.h>
+
+
+void PCB_EDIT_FRAME::InstallDisplayOptionsDialog( wxCommandEvent& aEvent )
+{
+ DIALOG_DISPLAY_OPTIONS dlg( this );
+ dlg.ShowModal();
+}
+
+
+DIALOG_DISPLAY_OPTIONS::DIALOG_DISPLAY_OPTIONS( PCB_EDIT_FRAME* parent ) :
+ DIALOG_DISPLAY_OPTIONS_BASE( parent )
+{
+ m_Parent = parent;
+
+ init();
+ m_sdbSizerOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+void DIALOG_DISPLAY_OPTIONS::init()
+{
+ SetFocus();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)m_Parent->GetDisplayOptions();
+
+ m_OptDisplayTracks->SetValue( displ_opts->m_DisplayPcbTrackFill == SKETCH );
+
+ switch ( displ_opts->m_ShowTrackClearanceMode )
+ {
+ case DO_NOT_SHOW_CLEARANCE:
+ m_OptDisplayTracksClearance->SetSelection( 0 );
+ break;
+
+ case SHOW_CLEARANCE_NEW_TRACKS:
+ m_OptDisplayTracksClearance->SetSelection( 1 );
+ break;
+
+ case SHOW_CLEARANCE_NEW_AND_EDITED_TRACKS_AND_VIA_AREAS:
+ m_OptDisplayTracksClearance->SetSelection( 3 );
+ break;
+
+ default:
+ case SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS:
+ m_OptDisplayTracksClearance->SetSelection( 2 );
+ break;
+
+ case SHOW_CLEARANCE_ALWAYS:
+ m_OptDisplayTracksClearance->SetSelection( 4 );
+ break;
+ }
+
+ m_OptDisplayPads->SetValue( displ_opts->m_DisplayPadFill == SKETCH );
+ m_OptDisplayVias->SetValue( displ_opts->m_DisplayViaFill == SKETCH );
+
+ m_Show_Page_Limits->SetValue( m_Parent->ShowPageLimits() );
+
+ m_OptDisplayViaHole->SetSelection( displ_opts->m_DisplayViaMode );
+ m_OptDisplayModTexts->SetValue( displ_opts->m_DisplayModTextFill == SKETCH );
+ m_OptDisplayModOutlines->SetValue( displ_opts->m_DisplayModEdgeFill == SKETCH );
+ m_OptDisplayPadClearence->SetValue( displ_opts->m_DisplayPadIsol );
+ m_OptDisplayPadNumber->SetValue( displ_opts->m_DisplayPadNum );
+ m_OptDisplayPadNoConn->SetValue( m_Parent->IsElementVisible( PCB_VISIBLE( NO_CONNECTS_VISIBLE ) ) );
+ m_OptDisplayDrawings->SetValue( displ_opts->m_DisplayDrawItemsFill == SKETCH );
+ m_ShowNetNamesOption->SetSelection( displ_opts->m_DisplayNetNamesMode );
+}
+
+
+void DIALOG_DISPLAY_OPTIONS::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( 0 );
+}
+
+
+/* Update variables with new options
+*/
+void DIALOG_DISPLAY_OPTIONS::OnOkClick(wxCommandEvent& event)
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)m_Parent->GetDisplayOptions();
+
+ m_Parent->SetShowPageLimits( m_Show_Page_Limits->GetValue() );
+
+ displ_opts->m_DisplayPcbTrackFill = not m_OptDisplayTracks->GetValue();
+
+ displ_opts->m_DisplayViaMode = (VIA_DISPLAY_MODE_T) m_OptDisplayViaHole->GetSelection();
+
+ switch ( m_OptDisplayTracksClearance->GetSelection() )
+ {
+ case 0:
+ displ_opts->m_ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE;
+ break;
+
+ case 1:
+ displ_opts->m_ShowTrackClearanceMode = SHOW_CLEARANCE_NEW_TRACKS;
+ break;
+
+ case 2:
+ displ_opts->m_ShowTrackClearanceMode = SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS;
+ break;
+
+ case 3:
+ displ_opts->m_ShowTrackClearanceMode = SHOW_CLEARANCE_NEW_AND_EDITED_TRACKS_AND_VIA_AREAS;
+ break;
+
+ case 4:
+ displ_opts->m_ShowTrackClearanceMode = SHOW_CLEARANCE_ALWAYS;
+ break;
+ }
+
+ displ_opts->m_DisplayModTextFill = not m_OptDisplayModTexts->GetValue();
+ displ_opts->m_DisplayModEdgeFill = not m_OptDisplayModOutlines->GetValue();
+
+ displ_opts->m_DisplayPadFill = not m_OptDisplayPads->GetValue();
+ displ_opts->m_DisplayViaFill = not m_OptDisplayVias->GetValue();
+
+ displ_opts->m_DisplayPadIsol = m_OptDisplayPadClearence->GetValue();
+
+ displ_opts->m_DisplayPadNum = m_OptDisplayPadNumber->GetValue();
+
+ m_Parent->SetElementVisibility( PCB_VISIBLE(NO_CONNECTS_VISIBLE),
+ m_OptDisplayPadNoConn->GetValue() );
+
+ displ_opts->m_DisplayDrawItemsFill = not m_OptDisplayDrawings->GetValue();
+ displ_opts->m_DisplayNetNamesMode = m_ShowNetNamesOption->GetSelection();
+
+ // Apply changes to the GAL
+ KIGFX::VIEW* view = m_Parent->GetGalCanvas()->GetView();
+ KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( view->GetPainter() );
+ KIGFX::PCB_RENDER_SETTINGS* settings =
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
+ settings->LoadDisplayOptions( displ_opts );
+ view->RecacheAllItems( true );
+
+ m_Parent->GetCanvas()->Refresh();
+
+ EndModal( 1 );
+}
diff --git a/pcbnew/dialogs/dialog_display_options.h b/pcbnew/dialogs/dialog_display_options.h
new file mode 100644
index 0000000..6590a67
--- /dev/null
+++ b/pcbnew/dialogs/dialog_display_options.h
@@ -0,0 +1,43 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/dialogs/dialog_display_options.h
+ */
+#include <dialog_display_options_base.h>
+
+class DIALOG_DISPLAY_OPTIONS : public DIALOG_DISPLAY_OPTIONS_BASE
+{
+private:
+ PCB_EDIT_FRAME* m_Parent;
+
+ void init();
+
+public:
+ DIALOG_DISPLAY_OPTIONS( PCB_EDIT_FRAME* parent );
+ ~DIALOG_DISPLAY_OPTIONS( ) { };
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+};
+
diff --git a/pcbnew/dialogs/dialog_display_options_base.cpp b/pcbnew/dialogs/dialog_display_options_base.cpp
new file mode 100644
index 0000000..2033a7b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_display_options_base.cpp
@@ -0,0 +1,143 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_display_options_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_DISPLAY_OPTIONS_BASE::DIALOG_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bupperSizer;
+ bupperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sLeftBoxSizer;
+ sLeftBoxSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Tracks and Vias:") ), wxVERTICAL );
+
+ m_OptDisplayTracks = new wxCheckBox( this, wxID_ANY, _("Show tracks in sketch mode"), wxDefaultPosition, wxDefaultSize, 0 );
+ sLeftBoxSizer->Add( m_OptDisplayTracks, 0, wxALL, 5 );
+
+ m_OptDisplayVias = new wxCheckBox( this, wxID_ANY, _("Show vias in sketch mode"), wxDefaultPosition, wxDefaultSize, 0 );
+ sLeftBoxSizer->Add( m_OptDisplayVias, 0, wxALL, 5 );
+
+ wxString m_OptDisplayViaHoleChoices[] = { _("Never"), _("Defined holes"), _("Always") };
+ int m_OptDisplayViaHoleNChoices = sizeof( m_OptDisplayViaHoleChoices ) / sizeof( wxString );
+ m_OptDisplayViaHole = new wxRadioBox( this, ID_VIAS_HOLES, _("Show Via Holes:"), wxDefaultPosition, wxDefaultSize, m_OptDisplayViaHoleNChoices, m_OptDisplayViaHoleChoices, 1, wxRA_SPECIFY_COLS );
+ m_OptDisplayViaHole->SetSelection( 0 );
+ m_OptDisplayViaHole->SetToolTip( _("Show or hide via holes.\nIf Defined Holes is selected, only the non default size holes are shown") );
+
+ sLeftBoxSizer->Add( m_OptDisplayViaHole, 1, wxALL|wxEXPAND, 5 );
+
+
+ bupperSizer->Add( sLeftBoxSizer, 0, wxEXPAND|wxALL, 5 );
+
+ wxStaticBoxSizer* sbMiddleLeftSizer;
+ sbMiddleLeftSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Routing Help:") ), wxVERTICAL );
+
+ wxString m_ShowNetNamesOptionChoices[] = { _("Do not show"), _("On pads"), _("On tracks"), _("On pads and tracks") };
+ int m_ShowNetNamesOptionNChoices = sizeof( m_ShowNetNamesOptionChoices ) / sizeof( wxString );
+ m_ShowNetNamesOption = new wxRadioBox( this, wxID_ANY, _("Show Net Names:"), wxDefaultPosition, wxDefaultSize, m_ShowNetNamesOptionNChoices, m_ShowNetNamesOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_ShowNetNamesOption->SetSelection( 0 );
+ m_ShowNetNamesOption->SetToolTip( _("Show or hide net names on pads and/or tracks") );
+
+ sbMiddleLeftSizer->Add( m_ShowNetNamesOption, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_OptDisplayTracksClearanceChoices[] = { _("Never"), _("New track"), _("New track with via area"), _("New and edited tracks with via area"), _("Always") };
+ int m_OptDisplayTracksClearanceNChoices = sizeof( m_OptDisplayTracksClearanceChoices ) / sizeof( wxString );
+ m_OptDisplayTracksClearance = new wxRadioBox( this, ID_SHOW_CLEARANCE, _("Show Track Clearance:"), wxDefaultPosition, wxDefaultSize, m_OptDisplayTracksClearanceNChoices, m_OptDisplayTracksClearanceChoices, 1, wxRA_SPECIFY_COLS );
+ m_OptDisplayTracksClearance->SetSelection( 0 );
+ m_OptDisplayTracksClearance->SetToolTip( _("Show or hide the track and via clearance area.\nIf New track is selected, track clearance area is shown only when creating the track.") );
+
+ sbMiddleLeftSizer->Add( m_OptDisplayTracksClearance, 1, wxALL|wxEXPAND, 5 );
+
+
+ bupperSizer->Add( sbMiddleLeftSizer, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* b_rightSizer;
+ b_rightSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sfootprintSizer;
+ sfootprintSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Footprints:") ), wxVERTICAL );
+
+ m_OptDisplayModOutlines = new wxCheckBox( this, wxID_ANY, _("Show outlines in sketch mode"), wxDefaultPosition, wxDefaultSize, 0 );
+ sfootprintSizer->Add( m_OptDisplayModOutlines, 0, wxALL, 5 );
+
+ m_OptDisplayModTexts
+ = new wxCheckBox( this, wxID_ANY, _("Show text in sketch mode"), wxDefaultPosition, wxDefaultSize, 0 );
+ sfootprintSizer->Add( m_OptDisplayModTexts
+ , 0, wxALL, 5 );
+
+ m_OptDisplayPads = new wxCheckBox( this, wxID_ANY, _("Show pads in sketch mode"), wxDefaultPosition, wxDefaultSize, 0 );
+ sfootprintSizer->Add( m_OptDisplayPads, 0, wxALL, 5 );
+
+ m_OptDisplayPadClearence = new wxCheckBox( this, wxID_ANY, _("Show pad clearance"), wxDefaultPosition, wxDefaultSize, 0 );
+ sfootprintSizer->Add( m_OptDisplayPadClearence, 0, wxALL, 5 );
+
+ m_OptDisplayPadNumber = new wxCheckBox( this, wxID_ANY, _("Show pad number"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptDisplayPadNumber->SetValue(true);
+ sfootprintSizer->Add( m_OptDisplayPadNumber, 0, wxALL, 5 );
+
+ m_OptDisplayPadNoConn = new wxCheckBox( this, wxID_ANY, _("Show pad no net connection indicator"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptDisplayPadNoConn->SetValue(true);
+ sfootprintSizer->Add( m_OptDisplayPadNoConn, 0, wxALL, 5 );
+
+
+ b_rightSizer->Add( sfootprintSizer, 0, wxEXPAND|wxALL, 5 );
+
+ wxStaticBoxSizer* s_otherSizer;
+ s_otherSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Other:") ), wxVERTICAL );
+
+ m_OptDisplayDrawings = new wxCheckBox( this, wxID_ANY, _("Show graphic items in sketch mode"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptDisplayDrawings->SetValue(true);
+ s_otherSizer->Add( m_OptDisplayDrawings, 0, wxALL, 5 );
+
+ m_Show_Page_Limits = new wxCheckBox( this, wxID_ANY, _("Show page limits"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Show_Page_Limits->SetValue(true);
+ s_otherSizer->Add( m_Show_Page_Limits, 0, wxALL, 5 );
+
+
+ b_rightSizer->Add( s_otherSizer, 1, wxEXPAND|wxALL, 5 );
+
+
+ bupperSizer->Add( b_rightSizer, 0, 0, 5 );
+
+
+ bMainSizer->Add( bupperSizer, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline1, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bMainSizer->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DISPLAY_OPTIONS_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DISPLAY_OPTIONS_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_DISPLAY_OPTIONS_BASE::~DIALOG_DISPLAY_OPTIONS_BASE()
+{
+ // Disconnect Events
+ m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DISPLAY_OPTIONS_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DISPLAY_OPTIONS_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_display_options_base.fbp b/pcbnew/dialogs/dialog_display_options_base.fbp
new file mode 100644
index 0000000..cc4821f
--- /dev/null
+++ b/pcbnew/dialogs/dialog_display_options_base.fbp
@@ -0,0 +1,1434 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_display_options_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DialogDisplayOptions_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_DISPLAY_OPTIONS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Display Options</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bupperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Tracks and Vias:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sLeftBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show tracks in sketch mode</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayTracks</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show vias in sketch mode</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayVias</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Never&quot; &quot;Defined holes&quot; &quot;Always&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_VIAS_HOLES</property>
+ <property name="label">Show Via Holes:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayViaHole</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Show or hide via holes.&#x0A;If Defined Holes is selected, only the non default size holes are shown</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Routing Help:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbMiddleLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Do not show&quot; &quot;On pads&quot; &quot;On tracks&quot; &quot;On pads and tracks&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show Net Names:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShowNetNamesOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Show or hide net names on pads and/or tracks</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Never&quot; &quot;New track&quot; &quot;New track with via area&quot; &quot;New and edited tracks with via area&quot; &quot;Always&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SHOW_CLEARANCE</property>
+ <property name="label">Show Track Clearance:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayTracksClearance</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Show or hide the track and via clearance area.&#x0A;If New track is selected, track clearance area is shown only when creating the track.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">b_rightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprints:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sfootprintSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show outlines in sketch mode</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayModOutlines</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show text in sketch mode</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayModTexts&#x0A;</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show pads in sketch mode</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayPads</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show pad clearance</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayPadClearence</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show pad number</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayPadNumber</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show pad no net connection indicator</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayPadNoConn</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Other:</property>
+ <property name="minimum_size"></property>
+ <property name="name">s_otherSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show graphic items in sketch mode</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptDisplayDrawings</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Show page limits</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Show_Page_Limits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_display_options_base.h b/pcbnew/dialogs/dialog_display_options_base.h
new file mode 100644
index 0000000..3f180e9
--- /dev/null
+++ b/pcbnew/dialogs/dialog_display_options_base.h
@@ -0,0 +1,77 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_DISPLAY_OPTIONS_BASE_H__
+#define __DIALOG_DISPLAY_OPTIONS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/checkbox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/radiobox.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_DISPLAY_OPTIONS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_DISPLAY_OPTIONS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ ID_VIAS_HOLES = 1000,
+ ID_SHOW_CLEARANCE
+ };
+
+ wxCheckBox* m_OptDisplayTracks;
+ wxCheckBox* m_OptDisplayVias;
+ wxRadioBox* m_OptDisplayViaHole;
+ wxRadioBox* m_ShowNetNamesOption;
+ wxRadioBox* m_OptDisplayTracksClearance;
+ wxCheckBox* m_OptDisplayModOutlines;
+ wxCheckBox* m_OptDisplayModTexts
+ ;
+ wxCheckBox* m_OptDisplayPads;
+ wxCheckBox* m_OptDisplayPadClearence;
+ wxCheckBox* m_OptDisplayPadNumber;
+ wxCheckBox* m_OptDisplayPadNoConn;
+ wxCheckBox* m_OptDisplayDrawings;
+ wxCheckBox* m_Show_Page_Limits;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Display Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_DISPLAY_OPTIONS_BASE();
+
+};
+
+#endif //__DIALOG_DISPLAY_OPTIONS_BASE_H__
diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp
new file mode 100644
index 0000000..2c3725d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_drc.cpp
@@ -0,0 +1,647 @@
+/**
+ * @file dialog_drc.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2009 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <wildcards_and_files_ext.h>
+#include <pgm_base.h>
+#include <dialog_drc.h>
+#include <wxPcbStruct.h>
+#include <base_units.h>
+#include <class_board_design_settings.h>
+#include <class_draw_panel_gal.h>
+
+/* class DIALOG_DRC_CONTROL: a dialog to set DRC parameters (clearance, min cooper size)
+ * and run DRC tests
+ */
+
+DIALOG_DRC_CONTROL::DIALOG_DRC_CONTROL( DRC* aTester, PCB_EDIT_FRAME* parent ) :
+ DIALOG_DRC_CONTROL_BASE( parent )
+{
+ m_tester = aTester;
+ m_Parent = parent;
+ m_currentBoard = m_Parent->GetBoard();
+ m_BrdSettings = m_Parent->GetBoard()->GetDesignSettings();
+
+ InitValues();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void DIALOG_DRC_CONTROL::OnActivateDlg( wxActivateEvent& event )
+{
+ if( m_currentBoard != m_Parent->GetBoard() )
+ {
+ // If m_currentBoard is not the current parent board,
+ // (for instance because a new board was loaded),
+ // close the dialog, because many pointers are now invalid
+ // in lists
+ SetReturnCode( wxID_CANCEL );
+ Close();
+ m_tester->DestroyDialog( wxID_CANCEL );
+ return;
+ }
+
+ // updating data which can be modified outside the dialog (DRC parameters, units ...)
+ // because the dialog is not modal
+ m_BrdSettings = m_Parent->GetBoard()->GetDesignSettings();
+ DisplayDRCValues();
+}
+
+
+void DIALOG_DRC_CONTROL::DisplayDRCValues()
+{
+ m_TrackMinWidthUnit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_ViaMinUnit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_MicroViaMinUnit->SetLabel(GetAbbreviatedUnitsLabel( g_UserUnit ) );
+
+ PutValueInLocalUnits( *m_SetTrackMinWidthCtrl, m_BrdSettings.m_TrackMinWidth );
+ PutValueInLocalUnits( *m_SetViaMinSizeCtrl, m_BrdSettings.m_ViasMinSize );
+ PutValueInLocalUnits( *m_SetMicroViakMinSizeCtrl, m_BrdSettings.m_MicroViasMinSize );
+}
+
+
+void DIALOG_DRC_CONTROL::InitValues()
+{
+ // Connect events and objects
+ m_ClearanceListBox->Connect( ID_CLEARANCE_LIST, wxEVT_LEFT_DCLICK,
+ wxMouseEventHandler(
+ DIALOG_DRC_CONTROL::OnLeftDClickClearance ), NULL, this );
+ m_ClearanceListBox->Connect( ID_CLEARANCE_LIST, wxEVT_RIGHT_UP,
+ wxMouseEventHandler(
+ DIALOG_DRC_CONTROL::OnRightUpClearance ), NULL, this );
+ m_UnconnectedListBox->Connect( ID_UNCONNECTED_LIST, wxEVT_LEFT_DCLICK,
+ wxMouseEventHandler( DIALOG_DRC_CONTROL::
+ OnLeftDClickUnconnected ), NULL, this );
+ m_UnconnectedListBox->Connect( ID_UNCONNECTED_LIST, wxEVT_RIGHT_UP,
+ wxMouseEventHandler(
+ DIALOG_DRC_CONTROL::OnRightUpUnconnected ), NULL, this );
+
+ m_DeleteCurrentMarkerButton->Enable( false );
+
+ DisplayDRCValues();
+
+ // Set the initial "enabled" status of the browse button and the text
+ // field for report name
+ wxCommandEvent junk;
+ OnReportCheckBoxClicked( junk );
+
+ Layout(); // adding the units above expanded Clearance text, now resize.
+
+ SetFocus();
+}
+
+/* accept DRC parameters (min clearance value and min sizes
+*/
+void DIALOG_DRC_CONTROL::SetDrcParmeters( )
+{
+ m_BrdSettings.m_TrackMinWidth = ValueFromTextCtrl( *m_SetTrackMinWidthCtrl );
+ m_BrdSettings.m_ViasMinSize = ValueFromTextCtrl( *m_SetViaMinSizeCtrl );
+ m_BrdSettings.m_MicroViasMinSize = ValueFromTextCtrl( *m_SetMicroViakMinSizeCtrl );
+
+ m_Parent->GetBoard()->SetDesignSettings( m_BrdSettings );
+}
+
+
+void DIALOG_DRC_CONTROL::SetRptSettings( bool aEnable, const wxString& aFileName )
+{
+ m_RptFilenameCtrl->Enable( aEnable );
+ m_BrowseButton->Enable( aEnable );
+ m_CreateRptCtrl->SetValue( aEnable );
+ m_RptFilenameCtrl->SetValue( aFileName );
+}
+
+void DIALOG_DRC_CONTROL::GetRptSettings( bool* aEnable, wxString& aFileName )
+{
+ *aEnable = m_CreateRptCtrl->GetValue();
+ aFileName = m_RptFilenameCtrl->GetValue();
+}
+
+void DIALOG_DRC_CONTROL::OnStartdrcClick( wxCommandEvent& event )
+{
+ wxString reportName;
+
+ bool make_report = m_CreateRptCtrl->IsChecked();
+
+ if( make_report ) // Create a rpt file
+ {
+ reportName = m_RptFilenameCtrl->GetValue();
+
+ if( reportName.IsEmpty() )
+ {
+ wxCommandEvent dummy;
+ OnButtonBrowseRptFileClick( dummy );
+ }
+
+ if( !reportName.IsEmpty() )
+ reportName = makeValidFileNameReport();
+ }
+
+ SetDrcParmeters();
+ m_tester->SetSettings( true, // Pad to pad DRC test enabled
+ true, // unconnected pads DRC test enabled
+ true, // DRC test for zones enabled
+ true, // DRC test for keepout areas enabled
+ reportName, make_report );
+
+ DelDRCMarkers();
+
+ wxBeginBusyCursor();
+
+ // run all the tests, with no UI at this time.
+ m_Messages->Clear();
+ wxSafeYield(); // Allows time slice to refresh the m_Messages window
+ m_Parent->GetBoard()->m_Status_Pcb = 0; // Force full connectivity and ratsnest recalculations
+ m_tester->RunTests(m_Messages);
+ m_Notebook->ChangeSelection( 0 ); // display the 1at tab "...Markers ..."
+
+
+ // Generate the report
+ if( !reportName.IsEmpty() )
+ {
+ if( writeReport( reportName ) )
+ {
+ wxString msg;
+ msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) );
+
+ wxString caption( _( "Disk File Report Completed" ) );
+ wxMessageDialog popupWindow( this, msg, caption );
+ popupWindow.ShowModal();
+ }
+ else
+ DisplayError( this, wxString::Format( _( "Unable to create report file '%s' "),
+ GetChars( reportName ) ) );
+ }
+
+ wxEndBusyCursor();
+
+ RedrawDrawPanel();
+}
+
+
+void DIALOG_DRC_CONTROL::OnDeleteAllClick( wxCommandEvent& event )
+{
+ DelDRCMarkers();
+ RedrawDrawPanel();
+}
+
+
+void DIALOG_DRC_CONTROL::OnListUnconnectedClick( wxCommandEvent& event )
+{
+ wxString reportName;
+
+ bool make_report = m_CreateRptCtrl->IsChecked();
+
+ if( make_report ) // Create a file rpt
+ {
+ reportName = m_RptFilenameCtrl->GetValue();
+
+ if( reportName.IsEmpty() )
+ {
+ wxCommandEvent junk;
+ OnButtonBrowseRptFileClick( junk );
+ }
+
+ if( !reportName.IsEmpty() )
+ reportName = makeValidFileNameReport();
+ }
+
+ SetDrcParmeters();
+
+ m_tester->SetSettings( true, // Pad to pad DRC test enabled
+ true, // unconnected pads DRC test enabled
+ true, // DRC test for zones enabled
+ true, // DRC test for keepout areas enabled
+ reportName, make_report );
+
+ DelDRCMarkers();
+
+ wxBeginBusyCursor();
+
+ m_Messages->Clear();
+ m_tester->ListUnconnectedPads();
+
+ m_Notebook->ChangeSelection( 1 ); // display the 2nd tab "Unconnected..."
+
+ // Generate the report
+ if( !reportName.IsEmpty() )
+ {
+ if( writeReport( reportName ) )
+ {
+ wxString msg;
+ msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) );
+ wxString caption( _( "Disk File Report Completed" ) );
+ wxMessageDialog popupWindow( this, msg, caption );
+ popupWindow.ShowModal();
+ }
+ else
+ DisplayError( this, wxString::Format( _( "Unable to create report file '%s' "),
+ GetChars( reportName ) ) );
+ }
+
+ wxEndBusyCursor();
+
+ /* there is currently nothing visible on the DrawPanel for unconnected pads
+ * RedrawDrawPanel();
+ */
+}
+
+
+void DIALOG_DRC_CONTROL::OnButtonBrowseRptFileClick( wxCommandEvent& event )
+{
+ wxFileName fn = m_Parent->GetBoard()->GetFileName();
+ fn.SetExt( ReportFileExtension );
+ wxString prj_path = Prj().GetProjectPath();
+
+ wxFileDialog dlg( this, _( "Save DRC Report File" ), prj_path,
+ fn.GetFullName(), ReportFileWildcard,
+ wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ m_RptFilenameCtrl->SetValue( dlg.GetPath() );
+}
+
+
+void DIALOG_DRC_CONTROL::OnOkClick( wxCommandEvent& event )
+{
+ SetReturnCode( wxID_OK );
+ SetDrcParmeters();
+
+ m_tester->DestroyDialog( wxID_OK );
+}
+
+
+void DIALOG_DRC_CONTROL::OnCancelClick( wxCommandEvent& event )
+{
+ SetReturnCode( wxID_CANCEL );
+
+ m_tester->DestroyDialog( wxID_CANCEL );
+}
+
+
+/*!
+ * wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_CHECKBOX1
+ */
+
+void DIALOG_DRC_CONTROL::OnReportCheckBoxClicked( wxCommandEvent& event )
+{
+ m_RptFilenameCtrl->Enable( m_CreateRptCtrl->IsChecked() );
+ m_BrowseButton->Enable( m_CreateRptCtrl->IsChecked() );
+}
+
+
+void DIALOG_DRC_CONTROL::OnLeftDClickClearance( wxMouseEvent& event )
+{
+ event.Skip();
+
+ // I am assuming that the double click actually changed the selected item.
+ // please verify this.
+ int selection = m_ClearanceListBox->GetSelection();
+
+ if( selection != wxNOT_FOUND )
+ {
+ // Find the selected MARKER in the PCB, position cursor there.
+ // Then close the dialog.
+ const DRC_ITEM* item = m_ClearanceListBox->GetItem( selection );
+
+ if( item )
+ {
+ m_Parent->CursorGoto( item->GetPointA() );
+ m_Parent->GetGalCanvas()->GetView()->SetCenter( VECTOR2D( item->GetPointA() ) );
+
+ // turn control over to m_Parent, hide this DIALOG_DRC_CONTROL window,
+ // no destruction so we can preserve listbox cursor
+ Show( false );
+
+ // We do not want the clarification popup window.
+ // when releasing the left button in the main window
+ m_Parent->SkipNextLeftButtonReleaseEvent();
+ }
+ }
+}
+
+
+void DIALOG_DRC_CONTROL::OnPopupMenu( wxCommandEvent& event )
+{
+ int source = event.GetId();
+
+ const DRC_ITEM* item = 0;
+ wxPoint pos;
+
+ int selection;
+
+ switch( source )
+ {
+ case ID_POPUP_UNCONNECTED_A:
+ selection = m_UnconnectedListBox->GetSelection();
+ item = m_UnconnectedListBox->GetItem( selection );
+ pos = item->GetPointA();
+ break;
+
+ case ID_POPUP_UNCONNECTED_B:
+ selection = m_UnconnectedListBox->GetSelection();
+ item = m_UnconnectedListBox->GetItem( selection );
+ pos = item->GetPointB();
+ break;
+
+ case ID_POPUP_MARKERS_A:
+ selection = m_ClearanceListBox->GetSelection();
+ item = m_ClearanceListBox->GetItem( selection );
+ pos = item->GetPointA();
+ break;
+
+ case ID_POPUP_MARKERS_B:
+ selection = m_ClearanceListBox->GetSelection();
+ item = m_ClearanceListBox->GetItem( selection );
+ pos = item->GetPointB();
+ break;
+ }
+
+ if( item )
+ {
+ m_Parent->CursorGoto( pos );
+ m_Parent->GetGalCanvas()->GetView()->SetCenter( VECTOR2D( item->GetPointA() ) );
+
+ Show( false );
+ }
+}
+
+
+void DIALOG_DRC_CONTROL::OnRightUpUnconnected( wxMouseEvent& event )
+{
+ event.Skip();
+
+ // popup menu to go to either of the items listed in the DRC_ITEM.
+
+ int selection = m_UnconnectedListBox->GetSelection();
+
+ if( selection != wxNOT_FOUND )
+ {
+ wxMenu menu;
+ wxMenuItem* mItem;
+ const DRC_ITEM* dItem = m_UnconnectedListBox->GetItem( selection );
+
+ mItem = new wxMenuItem( &menu, ID_POPUP_UNCONNECTED_A, dItem->GetTextA() );
+ menu.Append( mItem );
+
+ if( dItem->HasSecondItem() )
+ {
+ mItem = new wxMenuItem( &menu, ID_POPUP_UNCONNECTED_B, dItem->GetTextB() );
+ menu.Append( mItem );
+ }
+
+ PopupMenu( &menu );
+ }
+}
+
+
+void DIALOG_DRC_CONTROL::OnRightUpClearance( wxMouseEvent& event )
+{
+ event.Skip();
+
+ // popup menu to go to either of the items listed in the DRC_ITEM.
+
+ int selection = m_ClearanceListBox->GetSelection();
+
+ if( selection != wxNOT_FOUND )
+ {
+ wxMenu menu;
+ wxMenuItem* mItem;
+ const DRC_ITEM* dItem = m_ClearanceListBox->GetItem( selection );
+
+ mItem = new wxMenuItem( &menu, ID_POPUP_MARKERS_A, dItem->GetTextA() );
+ menu.Append( mItem );
+
+ if( dItem->HasSecondItem() )
+ {
+ mItem = new wxMenuItem( &menu, ID_POPUP_MARKERS_B, dItem->GetTextB() );
+ menu.Append( mItem );
+ }
+
+ PopupMenu( &menu );
+ }
+}
+
+
+void DIALOG_DRC_CONTROL::OnLeftDClickUnconnected( wxMouseEvent& event )
+{
+ event.Skip();
+
+ // I am assuming that the double click actually changed the selected item.
+ // please verify this.
+ int selection = m_UnconnectedListBox->GetSelection();
+
+ if( selection != wxNOT_FOUND )
+ {
+ // Find the selected DRC_ITEM in the listbox, position cursor there,
+ // at the first of the two pads.
+ // Then hide the dialog.
+ const DRC_ITEM* item = m_UnconnectedListBox->GetItem( selection );
+ if( item )
+ {
+ m_Parent->CursorGoto( item->GetPointA() );
+ m_Parent->GetGalCanvas()->GetView()->SetCenter( VECTOR2D( item->GetPointA() ) );
+
+ Show( false );
+
+ // We do not want the clarification popup window.
+ // when releasing the left button in the main window
+ m_Parent->SkipNextLeftButtonReleaseEvent();
+ }
+ }
+}
+
+/* called when switching from Error list to Unconnected list
+ * To avoid mistakes, the current marker is selection is cleared
+ */
+void DIALOG_DRC_CONTROL::OnChangingMarkerList( wxNotebookEvent& event )
+{
+ m_DeleteCurrentMarkerButton->Enable( false );
+ m_ClearanceListBox->SetSelection( -1 );
+ m_UnconnectedListBox->SetSelection( -1 );
+}
+
+void DIALOG_DRC_CONTROL::OnMarkerSelectionEvent( wxCommandEvent& event )
+{
+ int selection = event.GetSelection();
+
+ if( selection != wxNOT_FOUND )
+ {
+ // until a MARKER is selected, this button is not enabled.
+ m_DeleteCurrentMarkerButton->Enable( true );
+
+ // Find the selected DRC_ITEM in the listbox, position cursor there,
+ // at the first of the two pads.
+ const DRC_ITEM* item = m_ClearanceListBox->GetItem( selection );
+ if( item )
+ {
+ m_Parent->CursorGoto( item->GetPointA(), false );
+ m_Parent->GetGalCanvas()->GetView()->SetCenter( VECTOR2D( item->GetPointA() ) );
+ }
+ }
+
+ event.Skip();
+}
+
+
+void DIALOG_DRC_CONTROL::OnUnconnectedSelectionEvent( wxCommandEvent& event )
+{
+ int selection = event.GetSelection();
+
+ if( selection != wxNOT_FOUND )
+ {
+ // until a MARKER is selected, this button is not enabled.
+ m_DeleteCurrentMarkerButton->Enable( true );
+
+ // Find the selected DRC_ITEM in the listbox, position cursor there,
+ // at the first of the two pads.
+ const DRC_ITEM* item = m_UnconnectedListBox->GetItem( selection );
+ if( item )
+ {
+ m_Parent->CursorGoto( item->GetPointA(), false );
+ m_Parent->GetGalCanvas()->GetView()->SetCenter( VECTOR2D( item->GetPointA() ) );
+ }
+ }
+
+ event.Skip();
+}
+
+
+void DIALOG_DRC_CONTROL::RedrawDrawPanel()
+{
+ m_Parent->GetCanvas()->Refresh();
+}
+
+
+void DIALOG_DRC_CONTROL::DelDRCMarkers()
+{
+ m_Parent->SetCurItem( NULL ); // clear curr item, because it could be a DRC marker
+ m_ClearanceListBox->DeleteAllItems();
+ m_UnconnectedListBox->DeleteAllItems();
+ m_DeleteCurrentMarkerButton->Enable( false );
+}
+
+
+const wxString DIALOG_DRC_CONTROL::makeValidFileNameReport()
+{
+ wxFileName fn = m_RptFilenameCtrl->GetValue();
+
+ if( !fn.HasExt() )
+ {
+ fn.SetExt( ReportFileExtension );
+ m_RptFilenameCtrl->SetValue( fn.GetFullPath() );
+ }
+
+ // Ensure it is an absolute filename. if it is given relative
+ // it will be made relative to the project
+ if( !fn.IsAbsolute() )
+ {
+ wxString prj_path = Prj().GetProjectPath();
+ fn.MakeAbsolute( prj_path );
+ }
+
+ return fn.GetFullPath();
+}
+
+
+bool DIALOG_DRC_CONTROL::writeReport( const wxString& aFullFileName )
+{
+ FILE* fp = wxFopen( aFullFileName, wxT( "w" ) );
+
+ if( fp == NULL )
+ return false;
+
+ int count;
+
+ fprintf( fp, "** Drc report for %s **\n",
+ TO_UTF8( m_Parent->GetBoard()->GetFileName() ) );
+
+ wxDateTime now = wxDateTime::Now();
+
+ fprintf( fp, "** Created on %s **\n", TO_UTF8( now.Format( wxT( "%F %T" ) ) ) );
+
+ count = m_ClearanceListBox->GetItemCount();
+
+ fprintf( fp, "\n** Found %d DRC errors **\n", count );
+
+ for( int i = 0; i<count; ++i )
+ fprintf( fp, "%s", TO_UTF8( m_ClearanceListBox->GetItem( i )->ShowReport()) );
+
+ count = m_UnconnectedListBox->GetItemCount();
+
+ fprintf( fp, "\n** Found %d unconnected pads **\n", count );
+
+ for( int i = 0; i<count; ++i )
+ fprintf( fp, "%s", TO_UTF8( m_UnconnectedListBox->GetItem( i )->ShowReport() ) );
+
+ fprintf( fp, "\n** End of Report **\n" );
+
+ fclose( fp );
+
+ return true;
+}
+
+
+void DIALOG_DRC_CONTROL::OnDeleteOneClick( wxCommandEvent& event )
+{
+ int selectedIndex;
+ int curTab = m_Notebook->GetSelection();
+
+ if( curTab == 0 )
+ {
+ selectedIndex = m_ClearanceListBox->GetSelection();
+
+ if( selectedIndex != wxNOT_FOUND )
+ {
+ m_ClearanceListBox->DeleteItem( selectedIndex );
+
+ // redraw the pcb
+ RedrawDrawPanel();
+ }
+ }
+ else if( curTab == 1 )
+ {
+ selectedIndex = m_UnconnectedListBox->GetSelection();
+
+ if( selectedIndex != wxNOT_FOUND )
+ {
+ m_UnconnectedListBox->DeleteItem( selectedIndex );
+
+ /* these unconnected DRC_ITEMs are not currently visible on the pcb
+ * RedrawDrawPanel();
+ */
+ }
+ }
+}
diff --git a/pcbnew/dialogs/dialog_drc.h b/pcbnew/dialogs/dialog_drc.h
new file mode 100644
index 0000000..d370792
--- /dev/null
+++ b/pcbnew/dialogs/dialog_drc.h
@@ -0,0 +1,150 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2009 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef _DIALOG_DRC_H_
+#define _DIALOG_DRC_H_
+
+#include <wx/htmllbox.h>
+
+#include <fctsys.h>
+#include <pcbnew.h>
+#include <class_drawpanel.h>
+#include <wxstruct.h>
+#include <drc_stuff.h>
+#include <class_marker_pcb.h>
+#include <class_board.h>
+
+#include <dialog_drc_base.h>
+#include <dialog_drclistbox.h>
+
+
+// forward declarations
+class DRCLISTBOX;
+class BOARD_DESIGN_SETTINGS;
+
+//end forward declarations
+
+/*!
+ * DrcDialog class declaration
+ */
+
+class DIALOG_DRC_CONTROL: public DIALOG_DRC_CONTROL_BASE
+{
+public:
+ BOARD_DESIGN_SETTINGS m_BrdSettings;
+
+ /// Constructors
+ DIALOG_DRC_CONTROL( DRC* aTester, PCB_EDIT_FRAME* parent );
+ ~DIALOG_DRC_CONTROL(){};
+
+ /**
+ * Enable/disable the report file creation
+ * @param aEnbale = true to ask for creation
+ * @param aFileName = the filename or the report file
+ */
+ void SetRptSettings( bool aEnable, const wxString& aFileName );
+
+ void GetRptSettings( bool* aEnable, wxString& aFileName );
+
+private:
+ /**
+ * Function writeReport
+ * outputs the MARKER items and unconnecte DRC_ITEMs with commentary to an
+ * open text file.
+ * @param aFullFileName The text filename to write the report to.
+ * @return true if OK, false on error
+ */
+ bool writeReport( const wxString& aFullFileName );
+
+ /**
+ * filenames can be entered by name.
+ * @return a good report filename (with .rpt extension) (a full filename)
+ * from m_CreateRptCtrl
+ */
+ const wxString makeValidFileNameReport();
+
+ void InitValues( );
+
+ void DisplayDRCValues( );
+
+ void SetDrcParmeters( );
+
+ /// wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_CHECKBOX
+ void OnReportCheckBoxClicked( wxCommandEvent& event );
+
+ /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_BROWSE_RPT_FILE
+ void OnButtonBrowseRptFileClick( wxCommandEvent& event );
+
+ /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_STARTDRC
+ void OnStartdrcClick( wxCommandEvent& event );
+
+ /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_LIST_UNCONNECTED
+ void OnListUnconnectedClick( wxCommandEvent& event );
+
+ /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_DELETE_ALL
+ void OnDeleteAllClick( wxCommandEvent& event );
+
+ /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_DELETE_ONE
+ void OnDeleteOneClick( wxCommandEvent& event );
+
+ /// wxEVT_LEFT_DCLICK event handler for ID_CLEARANCE_LIST
+ void OnLeftDClickClearance( wxMouseEvent& event );
+
+ /// wxEVT_RIGHT_UP event handler for ID_CLEARANCE_LIST
+ void OnRightUpClearance( wxMouseEvent& event );
+
+ /// wxEVT_LEFT_DCLICK event handler for ID_UNCONNECTED_LIST
+ void OnLeftDClickUnconnected( wxMouseEvent& event );
+
+ /// wxEVT_RIGHT_UP event handler for ID_UNCONNECTED_LIST
+ void OnRightUpUnconnected( wxMouseEvent& event );
+
+ /// wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL
+ void OnCancelClick( wxCommandEvent& event );
+
+ /// wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_OK
+ void OnOkClick( wxCommandEvent& event );
+
+ /// handler for activate event, updating data which can be modified outside the dialog
+ /// (DRC parameters)
+ void OnActivateDlg( wxActivateEvent& event );
+
+ void OnMarkerSelectionEvent( wxCommandEvent& event );
+ void OnUnconnectedSelectionEvent( wxCommandEvent& event );
+ void OnChangingMarkerList( wxNotebookEvent& event );
+
+ void DelDRCMarkers();
+ void RedrawDrawPanel();
+
+ void OnPopupMenu( wxCommandEvent& event );
+
+ BOARD* m_currentBoard; // the board currently on test
+ DRC* m_tester;
+ PCB_EDIT_FRAME* m_Parent;
+};
+
+#endif // _DIALOG_DRC_H_
+
diff --git a/pcbnew/dialogs/dialog_drc_base.cpp b/pcbnew/dialogs/dialog_drc_base.cpp
new file mode 100644
index 0000000..03d63cf
--- /dev/null
+++ b/pcbnew/dialogs/dialog_drc_base.cpp
@@ -0,0 +1,256 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_drclistbox.h"
+
+#include "dialog_drc_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_DRC_CONTROL_BASE::DIALOG_DRC_CONTROL_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* m_MainSizer;
+ m_MainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* m_CommandSizer;
+ m_CommandSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sbSizerOptions;
+ sbSizerOptions = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options:") ), wxHORIZONTAL );
+
+ wxBoxSizer* bSizer7;
+ bSizer7 = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgMinValuesSizer;
+ fgMinValuesSizer = new wxFlexGridSizer( 4, 3, 0, 0 );
+ fgMinValuesSizer->AddGrowableCol( 1 );
+ fgMinValuesSizer->SetFlexibleDirection( wxHORIZONTAL );
+ fgMinValuesSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_ClearanceTitle = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Clearance"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ClearanceTitle->Wrap( -1 );
+ fgMinValuesSizer->Add( m_ClearanceTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_SetClearance = new wxTextCtrl( sbSizerOptions->GetStaticBox(), wxID_ANY, _("By Netclass"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SetClearance->Enable( false );
+
+ fgMinValuesSizer->Add( m_SetClearance, 0, wxALL|wxEXPAND, 5 );
+
+
+ fgMinValuesSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_TrackMinWidthTitle = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Min track width"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackMinWidthTitle->Wrap( -1 );
+ m_TrackMinWidthTitle->SetToolTip( _("Enter the minimum acceptable value for a track width") );
+
+ fgMinValuesSizer->Add( m_TrackMinWidthTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_SetTrackMinWidthCtrl = new wxTextCtrl( sbSizerOptions->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgMinValuesSizer->Add( m_SetTrackMinWidthCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_TrackMinWidthUnit = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackMinWidthUnit->Wrap( -1 );
+ m_TrackMinWidthUnit->SetToolTip( _("Enter the minimum acceptable value for a track width") );
+
+ fgMinValuesSizer->Add( m_TrackMinWidthUnit, 0, wxALL, 5 );
+
+ m_ViaMinTitle = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Min via size"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaMinTitle->Wrap( -1 );
+ m_ViaMinTitle->SetHelpText( _("Enter the minimum acceptable diameter for a standard via") );
+
+ fgMinValuesSizer->Add( m_ViaMinTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_SetViaMinSizeCtrl = new wxTextCtrl( sbSizerOptions->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgMinValuesSizer->Add( m_SetViaMinSizeCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_ViaMinUnit = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaMinUnit->Wrap( -1 );
+ m_ViaMinUnit->SetHelpText( _("Enter the minimum acceptable diameter for a standard via") );
+
+ fgMinValuesSizer->Add( m_ViaMinUnit, 0, wxALL, 5 );
+
+ m_MicroViaMinTitle = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Min uVia size"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MicroViaMinTitle->Wrap( -1 );
+ m_MicroViaMinTitle->SetToolTip( _("Enter the minimum acceptable diameter for a micro via") );
+
+ fgMinValuesSizer->Add( m_MicroViaMinTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_SetMicroViakMinSizeCtrl = new wxTextCtrl( sbSizerOptions->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgMinValuesSizer->Add( m_SetMicroViakMinSizeCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_MicroViaMinUnit = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MicroViaMinUnit->Wrap( -1 );
+ m_MicroViaMinUnit->SetToolTip( _("Enter the minimum acceptable diameter for a micro via") );
+
+ fgMinValuesSizer->Add( m_MicroViaMinUnit, 0, wxALL, 5 );
+
+
+ bSizer7->Add( fgMinValuesSizer, 1, wxEXPAND, 5 );
+
+ wxStaticBoxSizer* ReportFileSizer;
+ ReportFileSizer = new wxStaticBoxSizer( new wxStaticBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Create Report File") ), wxHORIZONTAL );
+
+ m_CreateRptCtrl = new wxCheckBox( ReportFileSizer->GetStaticBox(), ID_CHECKBOX_RPT_FILE, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_CreateRptCtrl->SetToolTip( _("Enable writing report to this file") );
+
+ ReportFileSizer->Add( m_CreateRptCtrl, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_RptFilenameCtrl = new wxTextCtrl( ReportFileSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_RptFilenameCtrl->SetToolTip( _("Enter the report filename") );
+ m_RptFilenameCtrl->SetMinSize( wxSize( 180,-1 ) );
+
+ ReportFileSizer->Add( m_RptFilenameCtrl, 1, wxALL|wxEXPAND, 5 );
+
+ m_BrowseButton = new wxButton( ReportFileSizer->GetStaticBox(), ID_BUTTON_BROWSE_RPT_FILE, _("..."), wxDefaultPosition, wxSize( 50,-1 ), 0 );
+ ReportFileSizer->Add( m_BrowseButton, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bSizer7->Add( ReportFileSizer, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 );
+
+
+ sbSizerOptions->Add( bSizer7, 1, wxEXPAND, 5 );
+
+
+ m_CommandSizer->Add( sbSizerOptions, 1, 0, 5 );
+
+ wxBoxSizer* bSizerMessages;
+ bSizerMessages = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText6 = new wxStaticText( this, wxID_ANY, _("Messages:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText6->Wrap( -1 );
+ bSizerMessages->Add( m_staticText6, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_Messages = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTE_MULTILINE|wxTE_READONLY );
+ m_Messages->SetMinSize( wxSize( 220,-1 ) );
+
+ bSizerMessages->Add( m_Messages, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+
+ m_CommandSizer->Add( bSizerMessages, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer11;
+ bSizer11 = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonRunDRC = new wxButton( this, ID_STARTDRC, _("Start DRC"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonRunDRC->SetDefault();
+ m_buttonRunDRC->SetToolTip( _("Start the Design Rule Checker") );
+
+ bSizer11->Add( m_buttonRunDRC, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonListUnconnected = new wxButton( this, ID_LIST_UNCONNECTED, _("List Unconnected"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonListUnconnected->SetToolTip( _("List unconnected pads or tracks") );
+
+ bSizer11->Add( m_buttonListUnconnected, 0, wxALL|wxEXPAND, 5 );
+
+ m_DeleteAllButton = new wxButton( this, ID_DELETE_ALL, _("Delete All Markers"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_DeleteAllButton->SetToolTip( _("Delete every marker") );
+
+ bSizer11->Add( m_DeleteAllButton, 0, wxALL|wxEXPAND, 5 );
+
+ m_DeleteCurrentMarkerButton = new wxButton( this, wxID_ANY, _("Delete Current Marker"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_DeleteCurrentMarkerButton->SetToolTip( _("Delete the marker selected in the list box below") );
+
+ bSizer11->Add( m_DeleteCurrentMarkerButton, 0, wxEXPAND|wxALL, 5 );
+
+
+ m_CommandSizer->Add( bSizer11, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ m_MainSizer->Add( m_CommandSizer, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticTextErrMsg = new wxStaticText( this, wxID_ANY, _("Error Messages:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextErrMsg->Wrap( -1 );
+ m_MainSizer->Add( m_staticTextErrMsg, 0, wxALL, 5 );
+
+ m_Notebook = new wxNotebook( this, ID_NOTEBOOK1, wxDefaultPosition, wxDefaultSize, 0 );
+ m_panelClearanceListBox = new wxPanel( m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* bSizeClearanceBox;
+ bSizeClearanceBox = new wxBoxSizer( wxVERTICAL );
+
+ m_ClearanceListBox = new DRCLISTBOX( m_panelClearanceListBox, ID_CLEARANCE_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ m_ClearanceListBox->SetToolTip( _("MARKERs, double click any to go there in PCB, right click for popup menu") );
+ m_ClearanceListBox->SetMinSize( wxSize( -1,80 ) );
+
+ bSizeClearanceBox->Add( m_ClearanceListBox, 1, wxALL|wxEXPAND, 5 );
+
+
+ m_panelClearanceListBox->SetSizer( bSizeClearanceBox );
+ m_panelClearanceListBox->Layout();
+ bSizeClearanceBox->Fit( m_panelClearanceListBox );
+ m_Notebook->AddPage( m_panelClearanceListBox, _("Problems / Markers"), true );
+ m_panelUnconnectedBox = new wxPanel( m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* bSizerUnconnectedBox;
+ bSizerUnconnectedBox = new wxBoxSizer( wxVERTICAL );
+
+ m_UnconnectedListBox = new DRCLISTBOX( m_panelUnconnectedBox, ID_UNCONNECTED_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ m_UnconnectedListBox->SetToolTip( _("A list of unconnected pads, right click for popup menu") );
+
+ bSizerUnconnectedBox->Add( m_UnconnectedListBox, 1, wxALL|wxEXPAND, 5 );
+
+
+ m_panelUnconnectedBox->SetSizer( bSizerUnconnectedBox );
+ m_panelUnconnectedBox->Layout();
+ bSizerUnconnectedBox->Fit( m_panelUnconnectedBox );
+ m_Notebook->AddPage( m_panelUnconnectedBox, _("Unconnected"), false );
+
+ m_MainSizer->Add( m_Notebook, 1, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ m_MainSizer->Add( m_sdbSizer1, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( m_MainSizer );
+ this->Layout();
+
+ // Connect Events
+ this->Connect( wxEVT_ACTIVATE, wxActivateEventHandler( DIALOG_DRC_CONTROL_BASE::OnActivateDlg ) );
+ m_CreateRptCtrl->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnReportCheckBoxClicked ), NULL, this );
+ m_BrowseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnButtonBrowseRptFileClick ), NULL, this );
+ m_buttonRunDRC->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnStartdrcClick ), NULL, this );
+ m_buttonListUnconnected->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnListUnconnectedClick ), NULL, this );
+ m_DeleteAllButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnDeleteAllClick ), NULL, this );
+ m_DeleteCurrentMarkerButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnDeleteOneClick ), NULL, this );
+ m_Notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_DRC_CONTROL_BASE::OnChangingMarkerList ), NULL, this );
+ m_ClearanceListBox->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_DRC_CONTROL_BASE::OnLeftDClickClearance ), NULL, this );
+ m_ClearanceListBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnMarkerSelectionEvent ), NULL, this );
+ m_ClearanceListBox->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( DIALOG_DRC_CONTROL_BASE::OnRightUpClearance ), NULL, this );
+ m_UnconnectedListBox->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_DRC_CONTROL_BASE::OnLeftDClickUnconnected ), NULL, this );
+ m_UnconnectedListBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnUnconnectedSelectionEvent ), NULL, this );
+ m_UnconnectedListBox->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( DIALOG_DRC_CONTROL_BASE::OnRightUpUnconnected ), NULL, this );
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_DRC_CONTROL_BASE::~DIALOG_DRC_CONTROL_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_ACTIVATE, wxActivateEventHandler( DIALOG_DRC_CONTROL_BASE::OnActivateDlg ) );
+ m_CreateRptCtrl->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnReportCheckBoxClicked ), NULL, this );
+ m_BrowseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnButtonBrowseRptFileClick ), NULL, this );
+ m_buttonRunDRC->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnStartdrcClick ), NULL, this );
+ m_buttonListUnconnected->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnListUnconnectedClick ), NULL, this );
+ m_DeleteAllButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnDeleteAllClick ), NULL, this );
+ m_DeleteCurrentMarkerButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnDeleteOneClick ), NULL, this );
+ m_Notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_DRC_CONTROL_BASE::OnChangingMarkerList ), NULL, this );
+ m_ClearanceListBox->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_DRC_CONTROL_BASE::OnLeftDClickClearance ), NULL, this );
+ m_ClearanceListBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnMarkerSelectionEvent ), NULL, this );
+ m_ClearanceListBox->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( DIALOG_DRC_CONTROL_BASE::OnRightUpClearance ), NULL, this );
+ m_UnconnectedListBox->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_DRC_CONTROL_BASE::OnLeftDClickUnconnected ), NULL, this );
+ m_UnconnectedListBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnUnconnectedSelectionEvent ), NULL, this );
+ m_UnconnectedListBox->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( DIALOG_DRC_CONTROL_BASE::OnRightUpUnconnected ), NULL, this );
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DRC_CONTROL_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_drc_base.fbp b/pcbnew/dialogs/dialog_drc_base.fbp
new file mode 100644
index 0000000..bf7590b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_drc_base.fbp
@@ -0,0 +1,2480 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_drc_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_drc_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_DRC_CONTROL_BASE</property>
+ <property name="pos"></property>
+ <property name="size">733,438</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">DRC Control</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate">OnActivateDlg</event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_MainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_CommandSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Options:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerOptions</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer7</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxHORIZONTAL</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgMinValuesSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">4</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Clearance</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ClearanceTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SetClearance</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">public</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">By Netclass</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Min track width</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackMinWidthTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enter the minimum acceptable value for a track width</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SetTrackMinWidthCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">public</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackMinWidthUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enter the minimum acceptable value for a track width</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help">Enter the minimum acceptable diameter for a standard via</property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Min via size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaMinTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SetViaMinSizeCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">public</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help">Enter the minimum acceptable diameter for a standard via</property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaMinUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Min uVia size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MicroViaMinTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enter the minimum acceptable diameter for a micro via</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SetMicroViakMinSizeCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">public</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MicroViaMinUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enter the minimum acceptable diameter for a micro via</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Create Report File</property>
+ <property name="minimum_size"></property>
+ <property name="name">ReportFileSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CHECKBOX_RPT_FILE</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CreateRptCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enable writing report to this file</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnReportCheckBoxClicked</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">180,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_RptFilenameCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enter the report filename</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_BUTTON_BROWSE_RPT_FILE</property>
+ <property name="label">...</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,-1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_BrowseButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">50,-1</property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonBrowseRptFileClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMessages</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Messages:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText6</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">220,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_Messages</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxHSCROLL|wxTE_MULTILINE|wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer11</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_STARTDRC</property>
+ <property name="label">Start DRC</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonRunDRC</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Start the Design Rule Checker</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnStartdrcClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_LIST_UNCONNECTED</property>
+ <property name="label">List Unconnected</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonListUnconnected</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">List unconnected pads or tracks</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnListUnconnectedClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_DELETE_ALL</property>
+ <property name="label">Delete All Markers</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DeleteAllButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Delete every marker</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnDeleteAllClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Delete Current Marker</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DeleteCurrentMarkerButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Delete the marker selected in the list box below</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnDeleteOneClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Error Messages:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextErrMsg</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxNotebook" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmapsize"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_NOTEBOOK1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Notebook</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnNotebookPageChanged">OnChangingMarkerList</event>
+ <event name="OnNotebookPageChanging"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Problems / Markers</property>
+ <property name="select">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_panelClearanceListBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass">; </property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizeClearanceBox</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxListBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CLEARANCE_LIST</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,80</property>
+ <property name="moveable">1</property>
+ <property name="name">m_ClearanceListBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">public</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">DRCLISTBOX; dialog_drclistbox.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">MARKERs, double click any to go there in PCB, right click for popup menu</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick">OnLeftDClickClearance</event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox">OnMarkerSelectionEvent</event>
+ <event name="OnListBoxDClick"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp">OnRightUpClearance</event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Unconnected</property>
+ <property name="select">0</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_panelUnconnectedBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">private</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUnconnectedBox</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxListBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_UNCONNECTED_LIST</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_UnconnectedListBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">public</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">DRCLISTBOX; </property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">A list of unconnected pads, right click for popup menu</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick">OnLeftDClickUnconnected</event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox">OnUnconnectedSelectionEvent</event>
+ <event name="OnListBoxDClick"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp">OnRightUpUnconnected</event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_drc_base.h b/pcbnew/dialogs/dialog_drc_base.h
new file mode 100644
index 0000000..8b24392
--- /dev/null
+++ b/pcbnew/dialogs/dialog_drc_base.h
@@ -0,0 +1,112 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_DRC_BASE_H__
+#define __DIALOG_DRC_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class DRCLISTBOX;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/checkbox.h>
+#include <wx/button.h>
+#include <wx/statbox.h>
+#include <wx/listbox.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/notebook.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_CHECKBOX_RPT_FILE 1000
+#define ID_BUTTON_BROWSE_RPT_FILE 1001
+#define ID_STARTDRC 1002
+#define ID_LIST_UNCONNECTED 1003
+#define ID_DELETE_ALL 1004
+#define ID_NOTEBOOK1 1005
+#define ID_CLEARANCE_LIST 1006
+#define ID_UNCONNECTED_LIST 1007
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_DRC_CONTROL_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_DRC_CONTROL_BASE : public DIALOG_SHIM
+{
+ private:
+ wxPanel* m_panelUnconnectedBox;
+
+ protected:
+ wxStaticText* m_ClearanceTitle;
+ wxStaticText* m_TrackMinWidthTitle;
+ wxStaticText* m_TrackMinWidthUnit;
+ wxStaticText* m_ViaMinTitle;
+ wxStaticText* m_ViaMinUnit;
+ wxStaticText* m_MicroViaMinTitle;
+ wxStaticText* m_MicroViaMinUnit;
+ wxCheckBox* m_CreateRptCtrl;
+ wxTextCtrl* m_RptFilenameCtrl;
+ wxButton* m_BrowseButton;
+ wxStaticText* m_staticText6;
+ wxTextCtrl* m_Messages;
+ wxButton* m_buttonRunDRC;
+ wxButton* m_buttonListUnconnected;
+ wxButton* m_DeleteAllButton;
+ wxButton* m_DeleteCurrentMarkerButton;
+ wxStaticText* m_staticTextErrMsg;
+ wxNotebook* m_Notebook;
+ wxPanel* m_panelClearanceListBox;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnActivateDlg( wxActivateEvent& event ) { event.Skip(); }
+ virtual void OnReportCheckBoxClicked( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonBrowseRptFileClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnStartdrcClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnListUnconnectedClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnDeleteAllClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnDeleteOneClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnChangingMarkerList( wxNotebookEvent& event ) { event.Skip(); }
+ virtual void OnLeftDClickClearance( wxMouseEvent& event ) { event.Skip(); }
+ virtual void OnMarkerSelectionEvent( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRightUpClearance( wxMouseEvent& event ) { event.Skip(); }
+ virtual void OnLeftDClickUnconnected( wxMouseEvent& event ) { event.Skip(); }
+ virtual void OnUnconnectedSelectionEvent( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnRightUpUnconnected( wxMouseEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+ wxTextCtrl* m_SetClearance;
+ wxTextCtrl* m_SetTrackMinWidthCtrl;
+ wxTextCtrl* m_SetViaMinSizeCtrl;
+ wxTextCtrl* m_SetMicroViakMinSizeCtrl;
+ DRCLISTBOX* m_ClearanceListBox;
+ DRCLISTBOX* m_UnconnectedListBox;
+
+ DIALOG_DRC_CONTROL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("DRC Control"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 733,438 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_DRC_CONTROL_BASE();
+
+};
+
+#endif //__DIALOG_DRC_BASE_H__
diff --git a/pcbnew/dialogs/dialog_drclistbox.h b/pcbnew/dialogs/dialog_drclistbox.h
new file mode 100644
index 0000000..4848504
--- /dev/null
+++ b/pcbnew/dialogs/dialog_drclistbox.h
@@ -0,0 +1,311 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef _DIALOG_DRCLISTBOX_H_
+#define _DIALOG_DRCLISTBOX_H_
+
+#include <wx/htmllbox.h>
+
+#include <fctsys.h>
+#include <pcbnew.h>
+#include <class_drawpanel.h>
+#include <wxstruct.h>
+#include <drc_stuff.h>
+#include <class_marker_pcb.h>
+#include <class_board.h>
+
+#include <dialog_drc_base.h>
+
+
+// outside @end control identifiers since wxFormBuilder knows not DRCLISTBOX
+#define ID_DRCLISTCTRL 14000
+#define ID_POPUP_UNCONNECTED_A 14001
+#define ID_POPUP_UNCONNECTED_B 14002
+#define ID_POPUP_MARKERS_A 14003
+#define ID_POPUP_MARKERS_B 14004
+
+
+/**
+ * Class DRC_LIST_MARKERS
+ * is an implementation of the interface named DRC_ITEM_LIST which uses
+ * a BOARD instance to fulfill the interface. No ownership is taken of the
+ * BOARD.
+ */
+class DRC_LIST_MARKERS : public DRC_ITEM_LIST
+{
+ BOARD* m_board;
+
+public:
+
+ DRC_LIST_MARKERS( BOARD* aBoard ) :
+ m_board(aBoard)
+ {
+ }
+
+ /* no destructor since we do not own anything to delete, not even the BOARD.
+ ~DRC_LIST_MARKERS() {}
+ */
+
+
+ //-----<Interface DRC_ITEM_LIST>---------------------------------------
+
+ void DeleteAllItems()
+ {
+ m_board->DeleteMARKERs();
+ }
+
+
+ const DRC_ITEM* GetItem( int aIndex )
+ {
+ const MARKER_PCB* marker = m_board->GetMARKER( aIndex );
+ if( marker )
+ return &marker->GetReporter();
+ return NULL;
+ }
+
+ void DeleteItem( int aIndex )
+ {
+ MARKER_PCB* marker = m_board->GetMARKER( aIndex );
+ if( marker )
+ m_board->Delete( marker );
+ }
+
+
+ /**
+ * Function GetCount
+ * returns the number of items in the list.
+ */
+ int GetCount()
+ {
+ return m_board->GetMARKERCount();
+ }
+
+ //-----</Interface DRC_ITEM_LIST>--------------------------------------
+
+};
+
+
+/**
+ * Class DRC_LIST_UNCONNECTED
+ * is an implementation of the interface named DRC_ITEM_LIST which uses
+ * a vector of pointers to DRC_ITEMs to fulfill the interface. No ownership is taken of the
+ * vector, which will reside in class DRC
+ */
+class DRC_LIST_UNCONNECTED : public DRC_ITEM_LIST
+{
+ DRC_LIST* m_vector;
+
+public:
+
+ DRC_LIST_UNCONNECTED( DRC_LIST* aList ) :
+ m_vector(aList)
+ {
+ }
+
+ /* no destructor since we do not own anything to delete, not even the BOARD.
+ ~DRC_LIST_UNCONNECTED() {}
+ */
+
+
+ //-----<Interface DRC_ITEM_LIST>---------------------------------------
+
+ void DeleteAllItems()
+ {
+ if( m_vector )
+ {
+ for( unsigned i=0; i<m_vector->size(); ++i )
+ delete (*m_vector)[i];
+
+ m_vector->clear();
+ }
+ }
+
+
+ const DRC_ITEM* GetItem( int aIndex )
+ {
+ if( m_vector && (unsigned)aIndex < m_vector->size() )
+ {
+ const DRC_ITEM* item = (*m_vector)[aIndex];
+ return item;
+ }
+ return NULL;
+ }
+
+ void DeleteItem( int aIndex )
+ {
+ if( m_vector && (unsigned)aIndex < m_vector->size() )
+ {
+ delete (*m_vector)[aIndex];
+ m_vector->erase( m_vector->begin()+aIndex );
+ }
+ }
+
+
+ /**
+ * Function GetCount
+ * returns the number of items in the list.
+ */
+ int GetCount()
+ {
+ if( m_vector )
+ {
+ return m_vector->size();
+ }
+ return 0;
+ }
+
+ //-----</Interface DRC_ITEM_LIST>--------------------------------------
+
+};
+
+
+
+/**
+ * Class DRCLISTBOX
+ * is used to display a DRC_ITEM_LIST.
+ */
+class DRCLISTBOX : public wxHtmlListBox
+{
+private:
+ DRC_ITEM_LIST* m_list; ///< wxHtmlListBox does not own the list, I do
+
+public:
+ DRCLISTBOX( wxWindow* parent, wxWindowID id = wxID_ANY,
+ const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+ long style = 0, const wxString choices[] = NULL, int unused = 0)
+ : wxHtmlListBox( parent, id, pos, size, style )
+ {
+ m_list = 0;
+ }
+
+
+ ~DRCLISTBOX()
+ {
+ delete m_list; // I own it, I destroy it.
+ }
+
+
+ /**
+ * Function SetList
+ * sets the DRC_ITEM_LIST for this listbox. Ownership of the DRC_ITEM_LIST is
+ * transfered to this DRCLISTBOX.
+ * @param aList The DRC_ITEM_LIST* containing the DRC_ITEMs which will be
+ * displayed in the wxHtmlListBox
+ */
+ void SetList( DRC_ITEM_LIST* aList )
+ {
+ delete m_list;
+
+ m_list = aList;
+ SetItemCount( aList->GetCount() );
+ Refresh();
+ }
+
+
+ /**
+ * Function GetItem
+ * returns a requested DRC_ITEM* or NULL.
+ */
+ const DRC_ITEM* GetItem( int aIndex )
+ {
+ if( m_list )
+ {
+ return m_list->GetItem( aIndex );
+ }
+ return NULL;
+ }
+
+
+ /**
+ * Function OnGetItem
+ * returns the html text associated with the DRC_ITEM given by index 'n'.
+ * @param n An index into the list.
+ * @return wxString - the simple html text to show in the listbox.
+ */
+ wxString OnGetItem( size_t n ) const
+ {
+ if( m_list )
+ {
+ const DRC_ITEM* item = m_list->GetItem( (int) n );
+ if( item )
+ return item->ShowHtml();
+ }
+ return wxString();
+ }
+
+
+ /**
+ * Function OnGetItem
+ * returns the html text associated with the given index 'n'.
+ * @param n An index into the list.
+ * @return wxString - the simple html text to show in the listbox.
+ */
+ wxString OnGetItemMarkup( size_t n ) const
+ {
+ return OnGetItem( n );
+ }
+
+
+ /**
+ * Function DeleteElement
+ * will delete one of the items in the list.
+ * @param aIndex The index into the list to delete.
+ */
+ void DeleteItem( int aIndex )
+ {
+ if( m_list )
+ {
+ int selection = GetSelection();
+
+ m_list->DeleteItem( aIndex );
+ int count = m_list->GetCount();
+ SetItemCount( count );
+
+ // if old selection >= new count
+ if( selection >= count )
+ SetSelection( count-1 ); // -1 is "no selection"
+ Refresh();
+ }
+ }
+
+
+ /**
+ * Function DeleteAllItems
+ * deletes all items in the list.
+ */
+ void DeleteAllItems()
+ {
+ if( m_list )
+ {
+ m_list->DeleteAllItems();
+ SetItemCount(0);
+ SetSelection( -1 ); // -1 is no selection
+ Refresh();
+ }
+ }
+};
+
+#endif // _DIALOG_DRCLISTBOX_H_
+
diff --git a/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.cpp b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.cpp
new file mode 100644
index 0000000..1fe2178
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.cpp
@@ -0,0 +1,728 @@
+/**
+ * Module editor: Dialog for editing module properties in the pcb editor.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <pgm_base.h>
+#include <gestfich.h>
+#include <3d_struct.h>
+#include <3d_viewer.h>
+#include <wxPcbStruct.h>
+#include <base_units.h>
+
+#include <class_module.h>
+#include <class_text_mod.h>
+#include <validators.h>
+
+#include <dialog_edit_module_for_BoardEditor.h>
+#include <wildcards_and_files_ext.h>
+
+size_t DIALOG_MODULE_BOARD_EDITOR::m_page = 0; // remember the last open page during session
+
+
+DIALOG_MODULE_BOARD_EDITOR::DIALOG_MODULE_BOARD_EDITOR( PCB_EDIT_FRAME* aParent,
+ MODULE* aModule,
+ wxDC* aDC ) :
+ DIALOG_MODULE_BOARD_EDITOR_BASE( aParent )
+{
+ m_Parent = aParent;
+ m_DC = aDC;
+ m_CurrentModule = aModule;
+
+ // Give an icon
+ wxIcon icon;
+ icon.CopyFromBitmap( KiBitmap( icon_modedit_xpm ) );
+ SetIcon( icon );
+
+ InitModeditProperties();
+ InitBoardProperties();
+
+ m_NoteBook->SetSelection( m_page );
+
+ m_sdbSizerStdButtonsOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+
+DIALOG_MODULE_BOARD_EDITOR::~DIALOG_MODULE_BOARD_EDITOR()
+{
+ m_page = m_NoteBook->GetSelection();
+
+ for( unsigned ii = 0; ii < m_Shapes3D_list.size(); ii++ )
+ delete m_Shapes3D_list[ii];
+
+ m_Shapes3D_list.clear();
+
+ delete m_ReferenceCopy;
+ delete m_ValueCopy;
+ delete m_3D_Scale;
+ delete m_3D_Offset;
+ delete m_3D_Rotation;
+}
+
+
+// Creation of the panel properties of the module editor.
+void DIALOG_MODULE_BOARD_EDITOR::InitBoardProperties()
+{
+ PutValueInLocalUnits( *m_ModPositionX, m_CurrentModule->GetPosition().x );
+ m_XPosUnit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+
+ PutValueInLocalUnits( *m_ModPositionY, m_CurrentModule->GetPosition().y );
+ m_YPosUnit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+
+ m_LayerCtrl->SetSelection(
+ (m_CurrentModule->GetLayer() == B_Cu) ? 1 : 0 );
+
+ bool select = false;
+ switch( int( m_CurrentModule->GetOrientation() ) )
+ {
+ case 0:
+ m_OrientCtrl->SetSelection( 0 );
+ break;
+
+ case 900:
+ case -2700:
+ m_OrientCtrl->SetSelection( 1 );
+ break;
+
+ case -900:
+ case 2700:
+ m_OrientCtrl->SetSelection( 2 );
+ break;
+
+ case -1800:
+ case 1800:
+ m_OrientCtrl->SetSelection( 3 );
+ break;
+
+ default:
+ m_OrientCtrl->SetSelection( 4 );
+ select = true;
+ break;
+ }
+
+ wxString msg;
+ msg << m_CurrentModule->GetOrientation();
+ m_OrientValue->SetValue( msg );
+ m_OrientValue->Enable( select );
+
+ // Initialize dialog relative to masks clearances
+ m_NetClearanceUnits->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_SolderMaskMarginUnits->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_SolderPasteMarginUnits->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+
+ PutValueInLocalUnits( *m_NetClearanceValueCtrl, m_CurrentModule->GetLocalClearance() );
+ PutValueInLocalUnits( *m_SolderMaskMarginCtrl, m_CurrentModule->GetLocalSolderMaskMargin() );
+
+ // These 2 parameters are usually < 0, so prepare entering a negative
+ // value, if current is 0
+ PutValueInLocalUnits( *m_SolderPasteMarginCtrl, m_CurrentModule->GetLocalSolderPasteMargin() );
+
+ if( m_CurrentModule->GetLocalSolderPasteMargin() == 0 )
+ m_SolderPasteMarginCtrl->SetValue( wxT( "-" ) +
+ m_SolderPasteMarginCtrl->GetValue() );
+
+ // Add solder paste margin ration in per cent
+ // for the usual default value 0.0, display -0.0 (or -0,0 in some countries)
+ msg.Printf( wxT( "%f" ),
+ m_CurrentModule->GetLocalSolderPasteMarginRatio() * 100.0 );
+
+ if( m_CurrentModule->GetLocalSolderPasteMarginRatio() == 0.0 &&
+ msg[0] == '0') // Sometimes Printf adds a sign if the value is very small (0.0)
+ m_SolderPasteMarginRatioCtrl->SetValue( wxT("-") + msg );
+ else
+ m_SolderPasteMarginRatioCtrl->SetValue( msg );
+
+ switch( m_CurrentModule->GetZoneConnection() )
+ {
+ default:
+ case PAD_ZONE_CONN_INHERITED:
+ m_ZoneConnectionChoice->SetSelection( 0 );
+ break;
+
+ case PAD_ZONE_CONN_FULL:
+ m_ZoneConnectionChoice->SetSelection( 1 );
+ break;
+
+ case PAD_ZONE_CONN_THERMAL:
+ m_ZoneConnectionChoice->SetSelection( 2 );
+ break;
+
+ case PAD_ZONE_CONN_NONE:
+ m_ZoneConnectionChoice->SetSelection( 3 );
+ break;
+ }
+}
+
+
+void DIALOG_MODULE_BOARD_EDITOR::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( PRM_EDITOR_ABORT );
+}
+
+
+void DIALOG_MODULE_BOARD_EDITOR::GotoModuleEditor( wxCommandEvent& event )
+{
+ if( m_CurrentModule->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
+ {
+ m_CurrentModule->SetTimeStamp( GetNewTimeStamp() );
+ m_Parent->OnModify();
+ }
+
+ EndModal( PRM_EDITOR_WANT_MODEDIT );
+}
+
+
+void DIALOG_MODULE_BOARD_EDITOR::ExchangeModule( wxCommandEvent& event )
+{
+ EndModal( PRM_EDITOR_WANT_EXCHANGE_FP );
+}
+
+
+void DIALOG_MODULE_BOARD_EDITOR::ModuleOrientEvent( wxCommandEvent& event )
+{
+ switch( m_OrientCtrl->GetSelection() )
+ {
+ case 0:
+ m_OrientValue->Enable( false );
+ m_OrientValue->SetValue( wxT( "0" ) );
+ break;
+
+ case 1:
+ m_OrientValue->Enable( false );
+ m_OrientValue->SetValue( wxT( "900" ) );
+ break;
+
+ case 2:
+ m_OrientValue->Enable( false );
+ m_OrientValue->SetValue( wxT( "2700" ) );
+ break;
+
+ case 3:
+ m_OrientValue->Enable( false );
+ m_OrientValue->SetValue( wxT( "1800" ) );
+ break;
+
+ default:
+ m_OrientValue->Enable( true );
+ break;
+ }
+}
+
+
+void DIALOG_MODULE_BOARD_EDITOR::InitModeditProperties()
+{
+ wxString default_path;
+ wxGetEnv( KISYS3DMOD, &default_path );
+#ifdef __WINDOWS__
+ default_path.Replace( wxT( "/" ), wxT( "\\" ) );
+#endif
+ m_textCtrl3DDefaultPath->SetValue( default_path );
+
+ m_LastSelected3DShapeIndex = -1;
+
+ // Init 3D shape list
+ S3D_MASTER* draw3D = m_CurrentModule->Models();
+
+ while( draw3D )
+ {
+ if( !draw3D->GetShape3DName().IsEmpty() )
+ {
+ S3D_MASTER* draw3DCopy = new S3D_MASTER( NULL );
+ draw3DCopy->Copy( draw3D );
+ m_Shapes3D_list.push_back( draw3DCopy );
+ m_3D_ShapeNameListBox->Append( draw3DCopy->GetShape3DName() );
+ }
+ draw3D = (S3D_MASTER*) draw3D->Next();
+ }
+
+ m_ReferenceCopy = new TEXTE_MODULE( NULL );
+ m_ValueCopy = new TEXTE_MODULE( NULL );
+ m_ReferenceCopy->Copy( &m_CurrentModule->Reference() );
+ m_ValueCopy->Copy( &m_CurrentModule->Value() );
+ m_ReferenceCtrl->SetValue( m_ReferenceCopy->GetText() );
+ m_ValueCtrl->SetValue( m_ValueCopy->GetText() );
+
+ // Shows the footprint's schematic path.
+ m_textCtrlSheetPath->SetValue( m_CurrentModule->GetPath() );
+
+ m_AttributsCtrl->SetItemToolTip( 0,
+ _( "Use this attribute for most non SMD components\n"
+ "Components with this option are not put in the footprint position list file" ) );
+ m_AttributsCtrl->SetItemToolTip( 1,
+ _( "Use this attribute for SMD components.\n"
+ "Only components with this option are put in the footprint position list file" ) );
+ m_AttributsCtrl->SetItemToolTip( 2,
+ _( "Use this attribute for \"virtual\" components drawn on board\n"
+ "(like a old ISA PC bus connector)" ) );
+
+ // Controls on right side of the dialog
+ switch( m_CurrentModule->GetAttributes() & 255 )
+ {
+ case 0:
+ m_AttributsCtrl->SetSelection( 0 );
+ break;
+
+ case MOD_CMS:
+ m_AttributsCtrl->SetSelection( 1 );
+ break;
+
+ case MOD_VIRTUAL:
+ m_AttributsCtrl->SetSelection( 2 );
+ break;
+
+ default:
+ m_AttributsCtrl->SetSelection( 0 );
+ break;
+ }
+
+ if( m_CurrentModule->IsLocked() )
+ m_AutoPlaceCtrl->SetSelection( 2 );
+ else if( m_CurrentModule->PadsLocked() )
+ m_AutoPlaceCtrl->SetSelection( 1 );
+ else
+ m_AutoPlaceCtrl->SetSelection( 0 );
+
+ m_AutoPlaceCtrl->SetItemToolTip( 0,
+ _( "Component can be freely moved and auto placed. User can arbitrarily select and edit component's pads." ) );
+ m_AutoPlaceCtrl->SetItemToolTip( 1,
+ _( "Component can be freely moved and auto placed, but its pads cannot be selected or edited." ) );
+ m_AutoPlaceCtrl->SetItemToolTip( 2,
+ _( "Component is locked: it cannot be freely moved or auto placed." ) );
+
+ m_CostRot90Ctrl->SetValue( m_CurrentModule->GetPlacementCost90() );
+
+ m_CostRot180Ctrl->SetValue( m_CurrentModule->GetPlacementCost180() );
+
+ // Initialize 3D parameters
+ m_3D_Scale = new S3DPOINT_VALUE_CTRL( m_Panel3D, m_bSizerShapeScale );
+ m_3D_Offset = new S3DPOINT_VALUE_CTRL( m_Panel3D, m_bSizerShapeOffset );
+ m_3D_Rotation = new S3DPOINT_VALUE_CTRL( m_Panel3D, m_bSizerShapeRotation );
+
+ // if m_3D_ShapeNameListBox is not empty, preselect first 3D shape
+ if( m_3D_ShapeNameListBox->GetCount() > 0 )
+ {
+ m_LastSelected3DShapeIndex = 0;
+ m_3D_ShapeNameListBox->SetSelection( m_LastSelected3DShapeIndex );
+ Transfert3DValuesToDisplay( m_Shapes3D_list[m_LastSelected3DShapeIndex] );
+ }
+
+ // We have modified the UI, so call Fit() for m_Panel3D
+ // to be sure the m_Panel3D sizers are initiliazed before opening the dialog
+ m_Panel3D->GetSizer()->Fit( m_Panel3D );
+}
+
+
+/* Initialize 3D info displayed in dialog box from values in aStruct3DSource
+ */
+void DIALOG_MODULE_BOARD_EDITOR::Transfert3DValuesToDisplay(
+ S3D_MASTER* aStruct3DSource )
+{
+ if( aStruct3DSource )
+ {
+ m_3D_Scale->SetValue( aStruct3DSource->m_MatScale );
+
+ m_3D_Offset->SetValue( aStruct3DSource->m_MatPosition );
+
+ m_3D_Rotation->SetValue( aStruct3DSource->m_MatRotation );
+ }
+ else
+ {
+ S3DPOINT dummy_vertex( 1.0, 1.0, 1.0 );
+ m_3D_Scale->SetValue( dummy_vertex );
+ }
+}
+
+
+/** Copy 3D info displayed in dialog box to values in a item in m_Shapes3D_list
+ * @param aIndexSelection = item index in m_Shapes3D_list
+ */
+void DIALOG_MODULE_BOARD_EDITOR::TransfertDisplayTo3DValues(
+ int aIndexSelection )
+{
+ if( aIndexSelection >= (int) m_Shapes3D_list.size() )
+ return;
+
+ S3D_MASTER* struct3DDest = m_Shapes3D_list[aIndexSelection];
+ struct3DDest->m_MatScale = m_3D_Scale->GetValue();
+ struct3DDest->m_MatRotation = m_3D_Rotation->GetValue();
+ struct3DDest->m_MatPosition = m_3D_Offset->GetValue();
+}
+
+
+void DIALOG_MODULE_BOARD_EDITOR::On3DShapeNameSelected( wxCommandEvent& event )
+{
+ if( m_LastSelected3DShapeIndex >= 0 )
+ TransfertDisplayTo3DValues( m_LastSelected3DShapeIndex );
+ m_LastSelected3DShapeIndex = m_3D_ShapeNameListBox->GetSelection();
+
+ if( m_LastSelected3DShapeIndex < 0 ) // happens under wxGTK when
+ // deleting an item in
+ // m_3D_ShapeNameListBox wxListBox
+ return;
+
+ if( m_LastSelected3DShapeIndex >= (int) m_Shapes3D_list.size() )
+ {
+ wxMessageBox( wxT( "On3DShapeNameSelected() error" ) );
+ m_LastSelected3DShapeIndex = -1;
+ return;
+ }
+ Transfert3DValuesToDisplay( m_Shapes3D_list[m_LastSelected3DShapeIndex] );
+}
+
+
+
+void DIALOG_MODULE_BOARD_EDITOR::Remove3DShape( wxCommandEvent& event )
+{
+ if( m_LastSelected3DShapeIndex >= 0 )
+ TransfertDisplayTo3DValues( m_LastSelected3DShapeIndex );
+
+ int ii = m_3D_ShapeNameListBox->GetSelection();
+ if( ii < 0 )
+ return;
+
+ m_Shapes3D_list.erase( m_Shapes3D_list.begin() + ii );
+ m_3D_ShapeNameListBox->Delete( ii );
+
+ if( m_3D_ShapeNameListBox->GetCount() == 0 )
+ Transfert3DValuesToDisplay( NULL );
+ else
+ {
+ m_LastSelected3DShapeIndex = 0;
+ m_3D_ShapeNameListBox->SetSelection( m_LastSelected3DShapeIndex );
+ Transfert3DValuesToDisplay(
+ m_Shapes3D_list[m_LastSelected3DShapeIndex] );
+ }
+}
+
+void DIALOG_MODULE_BOARD_EDITOR::Edit3DShapeFileName()
+{
+ int idx = m_3D_ShapeNameListBox->GetSelection();
+
+ if( idx < 0 )
+ return;
+
+ // Edit filename
+ wxString filename = m_3D_ShapeNameListBox->GetStringSelection();
+
+ wxTextEntryDialog dlg( this, wxEmptyString, wxEmptyString, filename );
+ dlg.SetTextValidator( FILE_NAME_WITH_PATH_CHAR_VALIDATOR( &filename ) );
+
+ if( dlg.ShowModal() != wxID_OK || filename.IsEmpty() )
+ return; //Aborted by user
+
+#ifdef __WINDOWS__
+ // In Kicad files, filenames and paths are stored using Unix notation
+ // So be sure the unix notation is still used
+ filename.Replace( wxT( "\\" ), wxT( "/" ) );
+#endif
+
+ m_3D_ShapeNameListBox->SetString( idx, filename );
+
+ S3D_MASTER* new3DShape = new S3D_MASTER( NULL );
+ new3DShape->SetShape3DName( filename );
+ delete m_Shapes3D_list[idx];
+ m_Shapes3D_list[idx] = new3DShape;
+}
+
+
+void DIALOG_MODULE_BOARD_EDITOR::BrowseAndAdd3DShapeFile()
+{
+ PROJECT& prj = Prj();
+
+ // here, the KISYS3DMOD default path for 3D shape files is expected
+ // to be already defined (when starting Pcbnew, it is defined
+ // from the user defined env variable, or set to a default value)
+ wxFileName fn( wxGetenv( KISYS3DMOD ), wxEmptyString );
+ wxString default3DPath = fn.GetPathWithSep();
+
+ wxString initialpath = prj.GetRString( PROJECT::VIEWER_3D_PATH );
+
+ if( !initialpath )
+ initialpath = default3DPath;
+
+ wxString fileFilters = wxGetTranslation( Shapes3DFileWildcard );
+
+ fileFilters += wxChar( '|' );
+ fileFilters += wxGetTranslation( IDF3DFileWildcard );
+
+ wxString filename = EDA_FILE_SELECTOR( _( "3D Shape:" ), initialpath,
+ wxEmptyString, wxEmptyString,
+ fileFilters, this, wxFD_OPEN, true );
+
+ if( filename.IsEmpty() )
+ return;
+
+ fn = filename;
+
+ prj.SetRString( PROJECT::VIEWER_3D_PATH, fn.GetPath() );
+
+ /* If the file path is already in the 3D shape file default path
+ * just add the file name relative to this path to the list.
+ * Otherwise, add the file name with a full or relative path.
+ * The relative path, when possible, is preferable
+ * because it preserve use of default path, when the path is a sub path of this path
+ */
+ wxString rootpath = filename.SubString( 0, default3DPath.Length()-1 );
+ bool useRelPath = rootpath.IsSameAs( default3DPath, wxFileName::IsCaseSensitive() );
+
+ if( useRelPath )
+ fn.MakeRelativeTo( default3DPath );
+ else // Absolute path given, not a subpath of the default path,
+ // therefore ask if the user wants a relative (to the default path) one
+ {
+ wxString msg;
+ msg.Printf( _( "Use a path relative to '%s'?" ), GetChars( default3DPath ) );
+ int diag = wxMessageBox( msg, _( "Path type" ),
+ wxYES_NO | wxICON_QUESTION, this );
+
+ if( diag == wxYES ) // Make it relative to the default 3D path
+ fn.MakeRelativeTo( default3DPath );
+ }
+
+ filename = fn.GetFullPath();
+
+ S3D_MASTER* new3DShape = new S3D_MASTER( NULL );
+
+#ifdef __WINDOWS__
+ // In Kicad files, filenames and paths are stored using Unix notation
+ filename.Replace( wxT( "\\" ), wxT( "/" ) );
+#endif
+
+ new3DShape->SetShape3DName( filename );
+ m_Shapes3D_list.push_back( new3DShape );
+ m_3D_ShapeNameListBox->Append( filename );
+
+ if( m_LastSelected3DShapeIndex >= 0 )
+ TransfertDisplayTo3DValues( m_LastSelected3DShapeIndex );
+
+ m_LastSelected3DShapeIndex = m_3D_ShapeNameListBox->GetCount() - 1;
+ m_3D_ShapeNameListBox->SetSelection( m_LastSelected3DShapeIndex );
+ Transfert3DValuesToDisplay( m_Shapes3D_list[m_LastSelected3DShapeIndex] );
+}
+
+
+void DIALOG_MODULE_BOARD_EDITOR::OnOkClick( wxCommandEvent& event )
+{
+ wxPoint modpos;
+ wxString msg;
+
+ if( m_CurrentModule->GetFlags() == 0 ) // this is a simple edition, we
+ // must create an undo entry
+ m_Parent->SaveCopyInUndoList( m_CurrentModule, UR_CHANGED );
+
+ if( m_DC )
+ {
+ m_Parent->GetCanvas()->CrossHairOff( m_DC );
+ m_CurrentModule->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR );
+ }
+
+ // Init Fields (should be first, because they can be moved or/and flipped later):
+ m_CurrentModule->Reference().Copy( m_ReferenceCopy );
+ m_CurrentModule->Value().Copy( m_ValueCopy );
+
+ // Initialize masks clearances
+ m_CurrentModule->SetLocalClearance( ValueFromTextCtrl( *m_NetClearanceValueCtrl ) );
+ m_CurrentModule->SetLocalSolderMaskMargin( ValueFromTextCtrl( *m_SolderMaskMarginCtrl ) );
+ m_CurrentModule->SetLocalSolderPasteMargin( ValueFromTextCtrl( *m_SolderPasteMarginCtrl ) );
+
+ double dtmp = 0.0;
+ msg = m_SolderPasteMarginRatioCtrl->GetValue();
+ msg.ToDouble( &dtmp );
+
+ // A -50% margin ratio means no paste on a pad, the ratio must be >= -50%
+ if( dtmp < -50.0 )
+ dtmp = -50.0;
+ // A margin ratio is always <= 0
+ // 0 means use full pad copper area
+ if( dtmp > 0.0 )
+ dtmp = 0.0;
+
+ m_CurrentModule->SetLocalSolderPasteMarginRatio( dtmp / 100 );
+
+ switch( m_ZoneConnectionChoice->GetSelection() )
+ {
+ default:
+ case 0:
+ m_CurrentModule->SetZoneConnection( PAD_ZONE_CONN_INHERITED );
+ break;
+
+ case 1:
+ m_CurrentModule->SetZoneConnection( PAD_ZONE_CONN_FULL );
+ break;
+
+ case 2:
+ m_CurrentModule->SetZoneConnection( PAD_ZONE_CONN_THERMAL );
+ break;
+
+ case 3:
+ m_CurrentModule->SetZoneConnection( PAD_ZONE_CONN_NONE );
+ break;
+ }
+
+ // Set Module Position
+ modpos.x = ValueFromTextCtrl( *m_ModPositionX );
+ modpos.y = ValueFromTextCtrl( *m_ModPositionY );
+ m_CurrentModule->SetPosition( modpos );
+ m_CurrentModule->SetLocked( m_AutoPlaceCtrl->GetSelection() == 2 );
+ m_CurrentModule->SetPadsLocked( m_AutoPlaceCtrl->GetSelection() == 1 );
+
+ switch( m_AttributsCtrl->GetSelection() )
+ {
+ case 0:
+ m_CurrentModule->SetAttributes( 0 );
+ break;
+
+ case 1:
+ m_CurrentModule->SetAttributes( MOD_CMS );
+ break;
+
+ case 2:
+ m_CurrentModule->SetAttributes( MOD_VIRTUAL );
+ break;
+ }
+
+ m_CurrentModule->SetPlacementCost90( m_CostRot90Ctrl->GetValue() );
+ m_CurrentModule->SetPlacementCost180( m_CostRot180Ctrl->GetValue() );
+
+ /* Now, set orientation. must be made after others changes,
+ * because rotation changes fields positions on board according to the new orientation
+ * (relative positions are not modified)
+ */
+ long orient = 0;
+ msg = m_OrientValue->GetValue();
+ msg.ToLong( &orient );
+
+ if( m_CurrentModule->GetOrientation() != orient )
+ m_CurrentModule->Rotate( m_CurrentModule->GetPosition(),
+ orient - m_CurrentModule->GetOrientation() );
+
+ // Set component side, that also have effect on the fields positions on board
+ bool change_layer = false;
+ if( m_LayerCtrl->GetSelection() == 0 ) // layer req = COMPONENT
+ {
+ if( m_CurrentModule->GetLayer() == B_Cu )
+ change_layer = true;
+ }
+ else if( m_CurrentModule->GetLayer() == F_Cu )
+ change_layer = true;
+
+ if( change_layer )
+ m_CurrentModule->Flip( m_CurrentModule->GetPosition() );
+
+ // Update 3D shape list
+ int ii = m_3D_ShapeNameListBox->GetSelection();
+
+ if( ii >= 0 )
+ TransfertDisplayTo3DValues( ii );
+
+ S3D_MASTER* draw3D = m_CurrentModule->Models();
+
+ for( unsigned ii = 0; ii < m_Shapes3D_list.size(); ii++ )
+ {
+ S3D_MASTER* draw3DCopy = m_Shapes3D_list[ii];
+
+ if( draw3DCopy->GetShape3DName().IsEmpty() )
+ continue;
+
+ if( draw3D == NULL )
+ {
+ draw3D = new S3D_MASTER( draw3D );
+ m_CurrentModule->Models().Append( draw3D );
+ }
+
+ draw3D->SetShape3DName( draw3DCopy->GetShape3DName() );
+ draw3D->m_MatScale = draw3DCopy->m_MatScale;
+ draw3D->m_MatRotation = draw3DCopy->m_MatRotation;
+ draw3D->m_MatPosition = draw3DCopy->m_MatPosition;
+
+ draw3D = draw3D->Next();
+ }
+
+ // Remove old extra 3D shapes
+ S3D_MASTER* nextdraw3D;
+
+ for( ; draw3D != NULL; draw3D = nextdraw3D )
+ {
+ nextdraw3D = (S3D_MASTER*) draw3D->Next();
+ delete m_CurrentModule->Models().Remove( draw3D );
+ }
+
+ // Fill shape list with one void entry, if no entry
+ if( m_CurrentModule->Models() == NULL )
+ m_CurrentModule->Models().PushBack( new S3D_MASTER( m_CurrentModule ) );
+
+
+ m_CurrentModule->CalculateBoundingBox();
+
+ m_Parent->OnModify();
+
+ EndModal( PRM_EDITOR_EDIT_OK );
+
+ if( m_DC )
+ {
+ m_CurrentModule->Draw( m_Parent->GetCanvas(), m_DC, GR_OR );
+ m_Parent->GetCanvas()->CrossHairOn( m_DC );
+ }
+}
+
+
+void DIALOG_MODULE_BOARD_EDITOR::OnEditReference( wxCommandEvent& event )
+{
+ wxPoint tmp = m_Parent->GetCrossHairPosition();
+
+ m_Parent->SetCrossHairPosition( m_ReferenceCopy->GetTextPosition() );
+ m_ReferenceCopy->SetParent( m_CurrentModule );
+ m_Parent->InstallTextModOptionsFrame( m_ReferenceCopy, NULL );
+ m_Parent->SetCrossHairPosition( tmp );
+ m_ReferenceCtrl->SetValue( m_ReferenceCopy->GetText() );
+}
+
+
+void DIALOG_MODULE_BOARD_EDITOR::OnEditValue( wxCommandEvent& event )
+{
+ wxPoint tmp = m_Parent->GetCrossHairPosition();
+
+ m_Parent->SetCrossHairPosition( m_ValueCopy->GetTextPosition() );
+ m_ValueCopy->SetParent( m_CurrentModule );
+ m_Parent->InstallTextModOptionsFrame( m_ValueCopy, NULL );
+ m_Parent->SetCrossHairPosition( tmp );
+ m_ValueCtrl->SetValue( m_ValueCopy->GetText() );
+}
+
diff --git a/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.h b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.h
new file mode 100644
index 0000000..ae299c9
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.h
@@ -0,0 +1,86 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2015 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <dialog_edit_module_for_BoardEditor_base.h>
+
+class DIALOG_MODULE_BOARD_EDITOR: public DIALOG_MODULE_BOARD_EDITOR_BASE
+{
+private:
+ PCB_EDIT_FRAME * m_Parent;
+ wxDC * m_DC;
+ MODULE* m_CurrentModule;
+ TEXTE_MODULE* m_ReferenceCopy;
+ TEXTE_MODULE* m_ValueCopy;
+ std::vector <S3D_MASTER*> m_Shapes3D_list;
+ int m_LastSelected3DShapeIndex;
+ S3DPOINT_VALUE_CTRL * m_3D_Scale;
+ S3DPOINT_VALUE_CTRL * m_3D_Offset;
+ S3DPOINT_VALUE_CTRL * m_3D_Rotation;
+ static size_t m_page; // remember the last open page during session
+
+public:
+ // The dialog can be closed for several reasons.
+ // they are listed here:
+ enum FP_PRM_EDITOR_RETVALUE
+ {
+ PRM_EDITOR_ABORT,
+ PRM_EDITOR_WANT_EXCHANGE_FP,
+ PRM_EDITOR_EDIT_OK,
+ PRM_EDITOR_WANT_MODEDIT
+ };
+
+public:
+ // Constructor and destructor
+ DIALOG_MODULE_BOARD_EDITOR( PCB_EDIT_FRAME* aParent, MODULE* aModule, wxDC* aDC );
+ ~DIALOG_MODULE_BOARD_EDITOR();
+
+private:
+ void BrowseAndAdd3DShapeFile();
+ void InitBoardProperties();
+ void InitModeditProperties();
+ void Transfert3DValuesToDisplay( S3D_MASTER * aStruct3DSource );
+ void TransfertDisplayTo3DValues( int aIndexSelection );
+ void Edit3DShapeFileName();
+
+ // virtual event functions
+ void OnEditValue( wxCommandEvent& event );
+ void OnEditReference( wxCommandEvent& event );
+ void On3DShapeSelection( wxCommandEvent& event );
+ void On3DShapeNameSelected( wxCommandEvent& event );
+ void Edit3DShapeFilename( wxCommandEvent& event )
+ {
+ Edit3DShapeFileName();
+ }
+ void Remove3DShape( wxCommandEvent& event );
+ void Add3DShape( wxCommandEvent& event )
+ {
+ BrowseAndAdd3DShapeFile();
+ }
+ void OnCancelClick( wxCommandEvent& event );
+ void OnOkClick( wxCommandEvent& event );
+ void GotoModuleEditor( wxCommandEvent& event );
+ void ExchangeModule( wxCommandEvent& event );
+ void ModuleOrientEvent( wxCommandEvent& event );
+};
+
diff --git a/pcbnew/dialogs/dialog_edit_module_for_BoardEditor_base.cpp b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor_base.cpp
new file mode 100644
index 0000000..6b917b9
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor_base.cpp
@@ -0,0 +1,425 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_edit_module_for_BoardEditor_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_MODULE_BOARD_EDITOR_BASE::DIALOG_MODULE_BOARD_EDITOR_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ m_GeneralBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_NoteBook = new wxNotebook( this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PanelProperties = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
+ wxBoxSizer* m_PanelPropertiesBoxSizer;
+ m_PanelPropertiesBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizerLeft;
+ bSizerLeft = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextRef = new wxStaticText( m_PanelProperties, wxID_ANY, _("Reference"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextRef->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextRef, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerRef;
+ bSizerRef = new wxBoxSizer( wxHORIZONTAL );
+
+ m_ReferenceCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ m_ReferenceCtrl->SetMaxLength( 0 );
+ bSizerRef->Add( m_ReferenceCtrl, 1, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
+
+ m_button4 = new wxButton( m_PanelProperties, wxID_ANY, _("Edit"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
+ bSizerRef->Add( m_button4, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+
+ bSizerLeft->Add( bSizerRef, 0, wxEXPAND, 5 );
+
+ m_staticTextVal = new wxStaticText( m_PanelProperties, wxID_ANY, _("Value"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextVal->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextVal, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerVal;
+ bSizerVal = new wxBoxSizer( wxHORIZONTAL );
+
+ m_ValueCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ m_ValueCtrl->SetMaxLength( 0 );
+ bSizerVal->Add( m_ValueCtrl, 1, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
+
+ m_button5 = new wxButton( m_PanelProperties, wxID_ANY, _("Edit"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
+ bSizerVal->Add( m_button5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+
+ bSizerLeft->Add( bSizerVal, 0, wxEXPAND, 5 );
+
+ wxString m_LayerCtrlChoices[] = { _("Front"), _("Back") };
+ int m_LayerCtrlNChoices = sizeof( m_LayerCtrlChoices ) / sizeof( wxString );
+ m_LayerCtrl = new wxRadioBox( m_PanelProperties, wxID_ANY, _("Board Side"), wxDefaultPosition, wxDefaultSize, m_LayerCtrlNChoices, m_LayerCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_LayerCtrl->SetSelection( 0 );
+ bSizerLeft->Add( m_LayerCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_OrientCtrlChoices[] = { _("0.0"), _("+90.0"), _("-90.0"), _("180.0"), _("Other") };
+ int m_OrientCtrlNChoices = sizeof( m_OrientCtrlChoices ) / sizeof( wxString );
+ m_OrientCtrl = new wxRadioBox( m_PanelProperties, ID_LISTBOX_ORIENT_SELECT, _("Rotation"), wxDefaultPosition, wxDefaultSize, m_OrientCtrlNChoices, m_OrientCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_OrientCtrl->SetSelection( 0 );
+ bSizerLeft->Add( m_OrientCtrl, 0, wxEXPAND|wxALL, 5 );
+
+ m_staticTextRotation = new wxStaticText( m_PanelProperties, wxID_ANY, _("Rotation (in 0.1 degrees):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextRotation->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextRotation, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OrientValue = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_OrientValue->SetMaxLength( 0 );
+ bSizerLeft->Add( m_OrientValue, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticTextPos = new wxStaticText( m_PanelProperties, wxID_ANY, _("Position"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextPos->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextPos, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxFlexGridSizer* fgSizerPos;
+ fgSizerPos = new wxFlexGridSizer( 2, 3, 0, 0 );
+ fgSizerPos->AddGrowableCol( 1 );
+ fgSizerPos->SetFlexibleDirection( wxHORIZONTAL );
+ fgSizerPos->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_XPosLabel = new wxStaticText( m_PanelProperties, wxID_ANY, _("X"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_XPosLabel->Wrap( -1 );
+ fgSizerPos->Add( m_XPosLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+ m_ModPositionX = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ModPositionX->SetMaxLength( 0 );
+ fgSizerPos->Add( m_ModPositionX, 1, wxEXPAND|wxRIGHT, 5 );
+
+ m_XPosUnit = new wxStaticText( m_PanelProperties, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_XPosUnit->Wrap( -1 );
+ fgSizerPos->Add( m_XPosUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+ m_YPosLabel = new wxStaticText( m_PanelProperties, wxID_ANY, _("Y"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_YPosLabel->Wrap( -1 );
+ fgSizerPos->Add( m_YPosLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+ m_ModPositionY = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ModPositionY->SetMaxLength( 0 );
+ fgSizerPos->Add( m_ModPositionY, 1, wxEXPAND|wxRIGHT, 5 );
+
+ m_YPosUnit = new wxStaticText( m_PanelProperties, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_YPosUnit->Wrap( -1 );
+ fgSizerPos->Add( m_YPosUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+
+ bSizerLeft->Add( fgSizerPos, 0, wxEXPAND|wxBOTTOM, 5 );
+
+ m_TextSheetPath = new wxStaticText( m_PanelProperties, wxID_ANY, _("Sheet path:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextSheetPath->Wrap( -1 );
+ bSizerLeft->Add( m_TextSheetPath, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_textCtrlSheetPath = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ m_textCtrlSheetPath->SetToolTip( _("An unique ID (a time stamp) to identify the component.\nThis is an alternate identifier to the reference.") );
+
+ bSizerLeft->Add( m_textCtrlSheetPath, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ m_PanelPropertiesBoxSizer->Add( bSizerLeft, 1, wxEXPAND, 5 );
+
+ m_PropRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonExchange = new wxButton( m_PanelProperties, ID_MODULE_PROPERTIES_EXCHANGE, _("Change Footprint(s)"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PropRightSizer->Add( m_buttonExchange, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonModuleEditor = new wxButton( m_PanelProperties, ID_GOTO_MODULE_EDITOR, _("Footprint Editor"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PropRightSizer->Add( m_buttonModuleEditor, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerAttrib;
+ bSizerAttrib = new wxBoxSizer( wxHORIZONTAL );
+
+ wxString m_AttributsCtrlChoices[] = { _("Normal"), _("Normal+Insert"), _("Virtual") };
+ int m_AttributsCtrlNChoices = sizeof( m_AttributsCtrlChoices ) / sizeof( wxString );
+ m_AttributsCtrl = new wxRadioBox( m_PanelProperties, wxID_ANY, _("Attributes"), wxDefaultPosition, wxDefaultSize, m_AttributsCtrlNChoices, m_AttributsCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_AttributsCtrl->SetSelection( 0 );
+ bSizerAttrib->Add( m_AttributsCtrl, 1, wxALL|wxEXPAND, 5 );
+
+ wxString m_AutoPlaceCtrlChoices[] = { _("Free"), _("Lock pads"), _("Lock footprint") };
+ int m_AutoPlaceCtrlNChoices = sizeof( m_AutoPlaceCtrlChoices ) / sizeof( wxString );
+ m_AutoPlaceCtrl = new wxRadioBox( m_PanelProperties, wxID_ANY, _("Move and Place"), wxDefaultPosition, wxDefaultSize, m_AutoPlaceCtrlNChoices, m_AutoPlaceCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_AutoPlaceCtrl->SetSelection( 0 );
+ bSizerAttrib->Add( m_AutoPlaceCtrl, 1, wxALL|wxEXPAND, 5 );
+
+
+ m_PropRightSizer->Add( bSizerAttrib, 0, wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbSizerAP;
+ sbSizerAP = new wxStaticBoxSizer( new wxStaticBox( m_PanelProperties, wxID_ANY, _("Auto Place") ), wxHORIZONTAL );
+
+ wxBoxSizer* bSizerRotOpt;
+ bSizerRotOpt = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText11 = new wxStaticText( m_PanelProperties, wxID_ANY, _("Rotate 90 degrees"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText11->Wrap( -1 );
+ bSizerRotOpt->Add( m_staticText11, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
+
+ m_CostRot90Ctrl = new wxSlider( m_PanelProperties, wxID_ANY, 0, 0, 10, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_LABELS );
+ bSizerRotOpt->Add( m_CostRot90Ctrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ sbSizerAP->Add( bSizerRotOpt, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerMoveOpt;
+ bSizerMoveOpt = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText12 = new wxStaticText( m_PanelProperties, wxID_ANY, _("Rotate 180 degrees"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText12->Wrap( -1 );
+ bSizerMoveOpt->Add( m_staticText12, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
+
+ m_CostRot180Ctrl = new wxSlider( m_PanelProperties, wxID_ANY, 0, 0, 10, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_LABELS );
+ bSizerMoveOpt->Add( m_CostRot180Ctrl, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ sbSizerAP->Add( bSizerMoveOpt, 1, wxEXPAND, 5 );
+
+
+ m_PropRightSizer->Add( sbSizerAP, 0, wxEXPAND|wxALL, 5 );
+
+ wxStaticBoxSizer* sbSizerLocalProperties;
+ sbSizerLocalProperties = new wxStaticBoxSizer( new wxStaticBox( m_PanelProperties, wxID_ANY, _("Local Settings") ), wxVERTICAL );
+
+ wxBoxSizer* bSizer11;
+ bSizer11 = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizer10;
+ bSizer10 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_staticText16 = new wxStaticText( m_PanelProperties, wxID_ANY, _("Pad connection to zones:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText16->Wrap( -1 );
+ bSizer10->Add( m_staticText16, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxString m_ZoneConnectionChoiceChoices[] = { _("Use zone setting"), _("Solid"), _("Thermal relief"), _("None") };
+ int m_ZoneConnectionChoiceNChoices = sizeof( m_ZoneConnectionChoiceChoices ) / sizeof( wxString );
+ m_ZoneConnectionChoice = new wxChoice( m_PanelProperties, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_ZoneConnectionChoiceNChoices, m_ZoneConnectionChoiceChoices, 0 );
+ m_ZoneConnectionChoice->SetSelection( 0 );
+ bSizer10->Add( m_ZoneConnectionChoice, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizer11->Add( bSizer10, 1, wxEXPAND, 5 );
+
+ m_staticTextInfo = new wxStaticText( m_PanelProperties, wxID_ANY, _("Set clearances to 0 to use global values"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextInfo->Wrap( -1 );
+ m_staticTextInfo->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizer11->Add( m_staticTextInfo, 0, wxALL, 5 );
+
+
+ sbSizerLocalProperties->Add( bSizer11, 0, wxEXPAND, 5 );
+
+ wxFlexGridSizer* fgSizerClearances;
+ fgSizerClearances = new wxFlexGridSizer( 5, 3, 0, 0 );
+ fgSizerClearances->AddGrowableCol( 1 );
+ fgSizerClearances->SetFlexibleDirection( wxBOTH );
+ fgSizerClearances->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticTextNetClearance = new wxStaticText( m_PanelProperties, wxID_ANY, _("Pad clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextNetClearance->Wrap( -1 );
+ m_staticTextNetClearance->SetToolTip( _("This is the local net clearance for all pad of this footprint\nIf 0, the Netclass values are used\nThis value can be superseded by a pad local value.") );
+
+ fgSizerClearances->Add( m_staticTextNetClearance, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
+
+ m_NetClearanceValueCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_NetClearanceValueCtrl->SetMaxLength( 0 );
+ fgSizerClearances->Add( m_NetClearanceValueCtrl, 1, wxALL|wxEXPAND, 5 );
+
+ m_NetClearanceUnits = new wxStaticText( m_PanelProperties, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_NetClearanceUnits->Wrap( -1 );
+ fgSizerClearances->Add( m_NetClearanceUnits, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
+
+ m_staticline1 = new wxStaticLine( m_PanelProperties, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ fgSizerClearances->Add( m_staticline1, 1, wxEXPAND, 5 );
+
+ m_staticline2 = new wxStaticLine( m_PanelProperties, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ fgSizerClearances->Add( m_staticline2, 1, wxEXPAND, 5 );
+
+ m_staticline3 = new wxStaticLine( m_PanelProperties, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ fgSizerClearances->Add( m_staticline3, 1, wxEXPAND, 5 );
+
+ m_MaskClearanceTitle = new wxStaticText( m_PanelProperties, wxID_ANY, _("Solder mask clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MaskClearanceTitle->Wrap( -1 );
+ m_MaskClearanceTitle->SetToolTip( _("This is the local clearance between pads and the solder mask\nfor this footprint\nThis value can be superseded by a pad local value.\nIf 0, the global value is used") );
+
+ fgSizerClearances->Add( m_MaskClearanceTitle, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_SolderMaskMarginCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMarginCtrl->SetMaxLength( 0 );
+ fgSizerClearances->Add( m_SolderMaskMarginCtrl, 1, wxALL|wxEXPAND, 5 );
+
+ m_SolderMaskMarginUnits = new wxStaticText( m_PanelProperties, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMarginUnits->Wrap( -1 );
+ fgSizerClearances->Add( m_SolderMaskMarginUnits, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
+
+ m_staticTextSolderPaste = new wxStaticText( m_PanelProperties, wxID_ANY, _("Solder paste clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSolderPaste->Wrap( -1 );
+ m_staticTextSolderPaste->SetToolTip( _("This is the local clearance between pads and the solder paste\nfor this footprint.\nThis value can be superseded by a pad local values.\nThe final clearance value is the sum of this value and the clearance value ratio\nA negative value means a smaller mask size than pad size") );
+
+ fgSizerClearances->Add( m_staticTextSolderPaste, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
+
+ m_SolderPasteMarginCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginCtrl->SetMaxLength( 0 );
+ fgSizerClearances->Add( m_SolderPasteMarginCtrl, 1, wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_SolderPasteMarginUnits = new wxStaticText( m_PanelProperties, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginUnits->Wrap( -1 );
+ fgSizerClearances->Add( m_SolderPasteMarginUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+ m_staticTextRatio = new wxStaticText( m_PanelProperties, wxID_ANY, _("Solder paste ratio clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextRatio->Wrap( -1 );
+ m_staticTextRatio->SetToolTip( _("This is the local clearance ratio in per cent between pads and the solder paste\nfor this footprint.\nA value of 10 means the clearance value is 10 per cent of the pad size\nThis value can be superseded by a pad local value.\nThe final clearance value is the sum of this value and the clearance value\nA negative value means a smaller mask size than pad size.") );
+
+ fgSizerClearances->Add( m_staticTextRatio, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_SolderPasteMarginRatioCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginRatioCtrl->SetMaxLength( 0 );
+ fgSizerClearances->Add( m_SolderPasteMarginRatioCtrl, 1, wxALL|wxEXPAND, 5 );
+
+ m_SolderPasteRatioMarginUnits = new wxStaticText( m_PanelProperties, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteRatioMarginUnits->Wrap( -1 );
+ fgSizerClearances->Add( m_SolderPasteRatioMarginUnits, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
+
+
+ sbSizerLocalProperties->Add( fgSizerClearances, 1, wxEXPAND, 5 );
+
+
+ m_PropRightSizer->Add( sbSizerLocalProperties, 0, wxALL|wxEXPAND, 5 );
+
+
+ m_PanelPropertiesBoxSizer->Add( m_PropRightSizer, 0, 0, 5 );
+
+
+ m_PanelProperties->SetSizer( m_PanelPropertiesBoxSizer );
+ m_PanelProperties->Layout();
+ m_PanelPropertiesBoxSizer->Fit( m_PanelProperties );
+ m_NoteBook->AddPage( m_PanelProperties, _("Properties"), true );
+ m_Panel3D = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
+ wxBoxSizer* bSizerMain3D;
+ bSizerMain3D = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText3Dname = new wxStaticText( m_Panel3D, wxID_ANY, _("3D Shape Name"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3Dname->Wrap( -1 );
+ bSizerMain3D->Add( m_staticText3Dname, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_3D_ShapeNameListBox = new wxListBox( m_Panel3D, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE );
+ bSizerMain3D->Add( m_3D_ShapeNameListBox, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticTextDefault3DPath = new wxStaticText( m_Panel3D, wxID_ANY, _("Default Path (from KISYS3DMOD environment variable)"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextDefault3DPath->Wrap( -1 );
+ bSizerMain3D->Add( m_staticTextDefault3DPath, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_textCtrl3DDefaultPath = new wxTextCtrl( m_Panel3D, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ bSizerMain3D->Add( m_textCtrl3DDefaultPath, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ wxBoxSizer* bLowerSizer3D;
+ bLowerSizer3D = new wxBoxSizer( wxHORIZONTAL );
+
+ m_Sizer3DValues = new wxStaticBoxSizer( new wxStaticBox( m_Panel3D, wxID_ANY, _("3D Scale and Position") ), wxVERTICAL );
+
+ m_bSizerShapeScale = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextShapeScale = new wxStaticText( m_Panel3D, wxID_ANY, _("Shape Scale:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextShapeScale->Wrap( -1 );
+ m_bSizerShapeScale->Add( m_staticTextShapeScale, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+
+ m_Sizer3DValues->Add( m_bSizerShapeScale, 0, wxEXPAND, 5 );
+
+ m_bSizerShapeOffset = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextShapeOffset = new wxStaticText( m_Panel3D, wxID_ANY, _("Shape Offset (inch):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextShapeOffset->Wrap( -1 );
+ m_bSizerShapeOffset->Add( m_staticTextShapeOffset, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+
+ m_Sizer3DValues->Add( m_bSizerShapeOffset, 0, wxEXPAND, 5 );
+
+ m_bSizerShapeRotation = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextShapeRotation = new wxStaticText( m_Panel3D, wxID_ANY, _("Shape Rotation (degrees):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextShapeRotation->Wrap( -1 );
+ m_bSizerShapeRotation->Add( m_staticTextShapeRotation, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+
+ m_Sizer3DValues->Add( m_bSizerShapeRotation, 0, wxEXPAND, 5 );
+
+
+ bLowerSizer3D->Add( m_Sizer3DValues, 1, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer3DButtons;
+ bSizer3DButtons = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonAdd = new wxButton( m_Panel3D, ID_ADD_3D_SHAPE, _("Add 3D Shape"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer3DButtons->Add( m_buttonAdd, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_buttonRemove = new wxButton( m_Panel3D, ID_REMOVE_3D_SHAPE, _("Remove 3D Shape"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer3DButtons->Add( m_buttonRemove, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_buttonEdit = new wxButton( m_Panel3D, wxID_ANY, _("Edit Filename"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer3DButtons->Add( m_buttonEdit, 0, wxALL|wxEXPAND, 5 );
+
+
+ bLowerSizer3D->Add( bSizer3DButtons, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bSizerMain3D->Add( bLowerSizer3D, 0, wxEXPAND, 5 );
+
+
+ m_Panel3D->SetSizer( bSizerMain3D );
+ m_Panel3D->Layout();
+ bSizerMain3D->Fit( m_Panel3D );
+ m_NoteBook->AddPage( m_Panel3D, _("3D settings"), false );
+
+ m_GeneralBoxSizer->Add( m_NoteBook, 1, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizerStdButtons = new wxStdDialogButtonSizer();
+ m_sdbSizerStdButtonsOK = new wxButton( this, wxID_OK );
+ m_sdbSizerStdButtons->AddButton( m_sdbSizerStdButtonsOK );
+ m_sdbSizerStdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizerStdButtons->AddButton( m_sdbSizerStdButtonsCancel );
+ m_sdbSizerStdButtons->Realize();
+
+ m_GeneralBoxSizer->Add( m_sdbSizerStdButtons, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( m_GeneralBoxSizer );
+ this->Layout();
+ m_GeneralBoxSizer->Fit( this );
+
+ // Connect Events
+ m_button4->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::OnEditReference ), NULL, this );
+ m_button5->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::OnEditValue ), NULL, this );
+ m_OrientCtrl->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::ModuleOrientEvent ), NULL, this );
+ m_buttonExchange->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::ExchangeModule ), NULL, this );
+ m_buttonModuleEditor->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::GotoModuleEditor ), NULL, this );
+ m_3D_ShapeNameListBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::On3DShapeNameSelected ), NULL, this );
+ m_buttonAdd->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::Add3DShape ), NULL, this );
+ m_buttonRemove->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::Remove3DShape ), NULL, this );
+ m_buttonEdit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::Edit3DShapeFilename ), NULL, this );
+ m_sdbSizerStdButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerStdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_MODULE_BOARD_EDITOR_BASE::~DIALOG_MODULE_BOARD_EDITOR_BASE()
+{
+ // Disconnect Events
+ m_button4->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::OnEditReference ), NULL, this );
+ m_button5->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::OnEditValue ), NULL, this );
+ m_OrientCtrl->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::ModuleOrientEvent ), NULL, this );
+ m_buttonExchange->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::ExchangeModule ), NULL, this );
+ m_buttonModuleEditor->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::GotoModuleEditor ), NULL, this );
+ m_3D_ShapeNameListBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::On3DShapeNameSelected ), NULL, this );
+ m_buttonAdd->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::Add3DShape ), NULL, this );
+ m_buttonRemove->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::Remove3DShape ), NULL, this );
+ m_buttonEdit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::Edit3DShapeFilename ), NULL, this );
+ m_sdbSizerStdButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerStdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_BOARD_EDITOR_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_edit_module_for_BoardEditor_base.fbp b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor_base.fbp
new file mode 100644
index 0000000..ffbfa87
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor_base.fbp
@@ -0,0 +1,5383 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_edit_module_for_BoardEditor_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_edit_module_for_BoardEditor_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_MODULE_BOARD_EDITOR_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Footprint Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_GeneralBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">private</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxNotebook" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmapsize"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_NOTEBOOK</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NoteBook</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnNotebookPageChanged"></event>
+ <event name="OnNotebookPageChanging"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Properties</property>
+ <property name="select">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PanelProperties</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxSUNKEN_BORDER|wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_PanelPropertiesBoxSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerLeft</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Reference</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextRef</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRef</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ReferenceCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Edit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_button4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_EXACTFIT</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnEditReference</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextVal</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerVal</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ValueCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Edit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_button5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_EXACTFIT</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnEditValue</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Front&quot; &quot;Back&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Board Side</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LayerCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;0.0&quot; &quot;+90.0&quot; &quot;-90.0&quot; &quot;180.0&quot; &quot;Other&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_LISTBOX_ORIENT_SELECT</property>
+ <property name="label">Rotation</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OrientCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox">ModuleOrientEvent</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Rotation (in 0.1 degrees):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextRotation</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OrientValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Position</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextPos</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxHORIZONTAL</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerPos</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">2</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">X</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_XPosLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ModPositionX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_XPosUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Y</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_YPosLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ModPositionY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_YPosUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Sheet path:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextSheetPath</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlSheetPath</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">An unique ID (a time stamp) to identify the component.&#x0A;This is an alternate identifier to the reference.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_PropRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">private</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_MODULE_PROPERTIES_EXCHANGE</property>
+ <property name="label">Change Footprint(s)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonExchange</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">ExchangeModule</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_GOTO_MODULE_EDITOR</property>
+ <property name="label">Footprint Editor</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonModuleEditor</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">GotoModuleEditor</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerAttrib</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Normal&quot; &quot;Normal+Insert&quot; &quot;Virtual&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Attributes</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AttributsCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Free&quot; &quot;Lock pads&quot; &quot;Lock footprint&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Move and Place</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AutoPlaceCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Auto Place</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerAP</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRotOpt</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Rotate 90 degrees</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText11</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxSlider" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maxValue">10</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="minValue">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CostRot90Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_LABELS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCommandScroll"></event>
+ <event name="OnCommandScrollBottom"></event>
+ <event name="OnCommandScrollChanged"></event>
+ <event name="OnCommandScrollLineDown"></event>
+ <event name="OnCommandScrollLineUp"></event>
+ <event name="OnCommandScrollPageDown"></event>
+ <event name="OnCommandScrollPageUp"></event>
+ <event name="OnCommandScrollThumbRelease"></event>
+ <event name="OnCommandScrollThumbTrack"></event>
+ <event name="OnCommandScrollTop"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnScroll"></event>
+ <event name="OnScrollBottom"></event>
+ <event name="OnScrollChanged"></event>
+ <event name="OnScrollLineDown"></event>
+ <event name="OnScrollLineUp"></event>
+ <event name="OnScrollPageDown"></event>
+ <event name="OnScrollPageUp"></event>
+ <event name="OnScrollThumbRelease"></event>
+ <event name="OnScrollThumbTrack"></event>
+ <event name="OnScrollTop"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMoveOpt</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Rotate 180 degrees</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText12</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSlider" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maxValue">10</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="minValue">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CostRot180Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_LABELS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCommandScroll"></event>
+ <event name="OnCommandScrollBottom"></event>
+ <event name="OnCommandScrollChanged"></event>
+ <event name="OnCommandScrollLineDown"></event>
+ <event name="OnCommandScrollLineUp"></event>
+ <event name="OnCommandScrollPageDown"></event>
+ <event name="OnCommandScrollPageUp"></event>
+ <event name="OnCommandScrollThumbRelease"></event>
+ <event name="OnCommandScrollThumbTrack"></event>
+ <event name="OnCommandScrollTop"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnScroll"></event>
+ <event name="OnScrollBottom"></event>
+ <event name="OnScrollChanged"></event>
+ <event name="OnScrollLineDown"></event>
+ <event name="OnScrollLineUp"></event>
+ <event name="OnScrollPageDown"></event>
+ <event name="OnScrollPageUp"></event>
+ <event name="OnScrollThumbRelease"></event>
+ <event name="OnScrollThumbTrack"></event>
+ <event name="OnScrollTop"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Local Settings</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerLocalProperties</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer11</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer10</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad connection to zones:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText16</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Use zone setting&quot; &quot;Solid&quot; &quot;Thermal relief&quot; &quot;None&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ZoneConnectionChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Set clearances to 0 to use global values</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextInfo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerClearances</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">5</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextNetClearance</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the local net clearance for all pad of this footprint&#x0A;If 0, the Netclass values are used&#x0A;This value can be superseded by a pad local value.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NetClearanceValueCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NetClearanceUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticLine" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticLine" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticLine" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder mask clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaskClearanceTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the local clearance between pads and the solder mask&#x0A;for this footprint&#x0A;This value can be superseded by a pad local value.&#x0A;If 0, the global value is used</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderMaskMarginCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderMaskMarginUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder paste clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSolderPaste</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the local clearance between pads and the solder paste&#x0A;for this footprint.&#x0A;This value can be superseded by a pad local values.&#x0A;The final clearance value is the sum of this value and the clearance value ratio&#x0A;A negative value means a smaller mask size than pad size</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteMarginCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteMarginUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder paste ratio clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextRatio</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the local clearance ratio in per cent between pads and the solder paste&#x0A;for this footprint.&#x0A;A value of 10 means the clearance value is 10 per cent of the pad size&#x0A;This value can be superseded by a pad local value.&#x0A;The final clearance value is the sum of this value and the clearance value&#x0A;A negative value means a smaller mask size than pad size.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteMarginRatioCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">%</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteRatioMarginUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">3D settings</property>
+ <property name="select">0</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Panel3D</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxSUNKEN_BORDER|wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain3D</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">3D Shape Name</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3Dname</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxListBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_3D_ShapeNameListBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLB_SINGLE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox">On3DShapeNameSelected</event>
+ <event name="OnListBoxDClick"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default Path (from KISYS3DMOD environment variable)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextDefault3DPath</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrl3DDefaultPath</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLowerSizer3D</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">3D Scale and Position</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_Sizer3DValues</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">public</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">m_bSizerShapeScale</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Shape Scale:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextShapeScale</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">m_bSizerShapeOffset</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Shape Offset (inch):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextShapeOffset</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">m_bSizerShapeRotation</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Shape Rotation (degrees):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextShapeRotation</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer3DButtons</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADD_3D_SHAPE</property>
+ <property name="label">Add 3D Shape</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonAdd</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">Add3DShape</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_REMOVE_3D_SHAPE</property>
+ <property name="label">Remove 3D Shape</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonRemove</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">Remove3DShape</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Edit Filename</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonEdit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">Edit3DShapeFilename</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizerStdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_edit_module_for_BoardEditor_base.h b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor_base.h
new file mode 100644
index 0000000..c0a6410
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor_base.h
@@ -0,0 +1,145 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_EDIT_MODULE_FOR_BOARDEDITOR_BASE_H__
+#define __DIALOG_EDIT_MODULE_FOR_BOARDEDITOR_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/radiobox.h>
+#include <wx/slider.h>
+#include <wx/statbox.h>
+#include <wx/choice.h>
+#include <wx/statline.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/listbox.h>
+#include <wx/notebook.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_NOTEBOOK 1000
+#define ID_LISTBOX_ORIENT_SELECT 1001
+#define ID_MODULE_PROPERTIES_EXCHANGE 1002
+#define ID_GOTO_MODULE_EDITOR 1003
+#define ID_ADD_3D_SHAPE 1004
+#define ID_REMOVE_3D_SHAPE 1005
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_MODULE_BOARD_EDITOR_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_MODULE_BOARD_EDITOR_BASE : public DIALOG_SHIM
+{
+ private:
+ wxBoxSizer* m_GeneralBoxSizer;
+ wxBoxSizer* m_PropRightSizer;
+
+ protected:
+ wxNotebook* m_NoteBook;
+ wxPanel* m_PanelProperties;
+ wxStaticText* m_staticTextRef;
+ wxTextCtrl* m_ReferenceCtrl;
+ wxButton* m_button4;
+ wxStaticText* m_staticTextVal;
+ wxTextCtrl* m_ValueCtrl;
+ wxButton* m_button5;
+ wxRadioBox* m_LayerCtrl;
+ wxRadioBox* m_OrientCtrl;
+ wxStaticText* m_staticTextRotation;
+ wxTextCtrl* m_OrientValue;
+ wxStaticText* m_staticTextPos;
+ wxStaticText* m_XPosLabel;
+ wxTextCtrl* m_ModPositionX;
+ wxStaticText* m_XPosUnit;
+ wxStaticText* m_YPosLabel;
+ wxTextCtrl* m_ModPositionY;
+ wxStaticText* m_YPosUnit;
+ wxStaticText* m_TextSheetPath;
+ wxTextCtrl* m_textCtrlSheetPath;
+ wxButton* m_buttonExchange;
+ wxButton* m_buttonModuleEditor;
+ wxRadioBox* m_AttributsCtrl;
+ wxRadioBox* m_AutoPlaceCtrl;
+ wxStaticText* m_staticText11;
+ wxSlider* m_CostRot90Ctrl;
+ wxStaticText* m_staticText12;
+ wxSlider* m_CostRot180Ctrl;
+ wxStaticText* m_staticText16;
+ wxChoice* m_ZoneConnectionChoice;
+ wxStaticText* m_staticTextInfo;
+ wxStaticText* m_staticTextNetClearance;
+ wxTextCtrl* m_NetClearanceValueCtrl;
+ wxStaticText* m_NetClearanceUnits;
+ wxStaticLine* m_staticline1;
+ wxStaticLine* m_staticline2;
+ wxStaticLine* m_staticline3;
+ wxStaticText* m_MaskClearanceTitle;
+ wxTextCtrl* m_SolderMaskMarginCtrl;
+ wxStaticText* m_SolderMaskMarginUnits;
+ wxStaticText* m_staticTextSolderPaste;
+ wxTextCtrl* m_SolderPasteMarginCtrl;
+ wxStaticText* m_SolderPasteMarginUnits;
+ wxStaticText* m_staticTextRatio;
+ wxTextCtrl* m_SolderPasteMarginRatioCtrl;
+ wxStaticText* m_SolderPasteRatioMarginUnits;
+ wxPanel* m_Panel3D;
+ wxStaticText* m_staticText3Dname;
+ wxListBox* m_3D_ShapeNameListBox;
+ wxStaticText* m_staticTextDefault3DPath;
+ wxTextCtrl* m_textCtrl3DDefaultPath;
+ wxBoxSizer* m_bSizerShapeScale;
+ wxStaticText* m_staticTextShapeScale;
+ wxBoxSizer* m_bSizerShapeOffset;
+ wxStaticText* m_staticTextShapeOffset;
+ wxBoxSizer* m_bSizerShapeRotation;
+ wxStaticText* m_staticTextShapeRotation;
+ wxButton* m_buttonAdd;
+ wxButton* m_buttonRemove;
+ wxButton* m_buttonEdit;
+ wxStdDialogButtonSizer* m_sdbSizerStdButtons;
+ wxButton* m_sdbSizerStdButtonsOK;
+ wxButton* m_sdbSizerStdButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnEditReference( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnEditValue( wxCommandEvent& event ) { event.Skip(); }
+ virtual void ModuleOrientEvent( wxCommandEvent& event ) { event.Skip(); }
+ virtual void ExchangeModule( wxCommandEvent& event ) { event.Skip(); }
+ virtual void GotoModuleEditor( wxCommandEvent& event ) { event.Skip(); }
+ virtual void On3DShapeNameSelected( wxCommandEvent& event ) { event.Skip(); }
+ virtual void Add3DShape( wxCommandEvent& event ) { event.Skip(); }
+ virtual void Remove3DShape( wxCommandEvent& event ) { event.Skip(); }
+ virtual void Edit3DShapeFilename( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+ wxStaticBoxSizer* m_Sizer3DValues;
+
+ DIALOG_MODULE_BOARD_EDITOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Footprint Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_MODULE_BOARD_EDITOR_BASE();
+
+};
+
+#endif //__DIALOG_EDIT_MODULE_FOR_BOARDEDITOR_BASE_H__
diff --git a/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp b/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp
new file mode 100644
index 0000000..88f11a3
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp
@@ -0,0 +1,554 @@
+/**
+ * @file dialog_edit_module_for_Modedit.cpp
+ *
+ * @brief Dialog for editing a module properties in module editor (modedit)
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <kiface_i.h>
+#include <gestfich.h>
+#include <3d_struct.h>
+#include <3d_viewer.h>
+#include <wxPcbStruct.h>
+#include <base_units.h>
+#include <macros.h>
+#include <validators.h>
+#include <kicad_string.h>
+
+#include <class_module.h>
+#include <class_text_mod.h>
+#include <module_editor_frame.h>
+#include <dialog_edit_module_for_Modedit.h>
+#include <wildcards_and_files_ext.h>
+
+size_t DIALOG_MODULE_MODULE_EDITOR::m_page = 0; // remember the last open page during session
+
+
+DIALOG_MODULE_MODULE_EDITOR::DIALOG_MODULE_MODULE_EDITOR( FOOTPRINT_EDIT_FRAME* aParent,
+ MODULE* aModule ) :
+ DIALOG_MODULE_MODULE_EDITOR_BASE( aParent )
+{
+ m_parent = aParent;
+ m_currentModule = aModule;
+
+ // Give an icon
+ wxIcon icon;
+ icon.CopyFromBitmap( KiBitmap( icon_modedit_xpm ) );
+ SetIcon( icon );
+
+ m_FootprintNameCtrl->SetValidator( FILE_NAME_CHAR_VALIDATOR() );
+ initModeditProperties();
+
+ m_NoteBook->SetSelection( m_page );
+
+ m_sdbSizerStdButtonsOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+DIALOG_MODULE_MODULE_EDITOR::~DIALOG_MODULE_MODULE_EDITOR()
+{
+ m_page = m_NoteBook->GetSelection();
+
+ for( unsigned ii = 0; ii < m_shapes3D_list.size(); ii++ )
+ delete m_shapes3D_list[ii];
+
+ m_shapes3D_list.clear();
+
+ delete m_referenceCopy;
+ delete m_valueCopy;
+ delete m_3D_Scale;
+ delete m_3D_Offset;
+ delete m_3D_Rotation;
+}
+
+
+void DIALOG_MODULE_MODULE_EDITOR::initModeditProperties()
+{
+ SetFocus();
+
+ // Display the default path, given by environment variable KISYS3DMOD
+ wxString default_path;
+ wxGetEnv( KISYS3DMOD, &default_path );
+#ifdef __WINDOWS__
+ default_path.Replace( wxT( "/" ), wxT( "\\" ) );
+#endif
+ m_textCtrl3DDefaultPath->SetValue( default_path );
+
+ m_lastSelected3DShapeIndex = -1;
+
+ // Init 3D shape list
+ S3D_MASTER* draw3D = m_currentModule->Models();
+
+ while( draw3D )
+ {
+ if( !draw3D->GetShape3DName().IsEmpty() )
+ {
+ S3D_MASTER* draw3DCopy = new S3D_MASTER(NULL);
+ draw3DCopy->Copy( draw3D );
+ m_shapes3D_list.push_back( draw3DCopy );
+ m_3D_ShapeNameListBox->Append( draw3DCopy->GetShape3DName() );
+ }
+ draw3D = (S3D_MASTER*) draw3D->Next();
+ }
+
+ m_DocCtrl->SetValue( m_currentModule->GetDescription() );
+ m_KeywordCtrl->SetValue( m_currentModule->GetKeywords() );
+ m_referenceCopy = new TEXTE_MODULE( NULL );
+ m_valueCopy = new TEXTE_MODULE( NULL );
+ m_referenceCopy->Copy( &m_currentModule->Reference() );
+ m_valueCopy->Copy( &m_currentModule->Value() );
+ m_ReferenceCtrl->SetValue( m_referenceCopy->GetText() );
+ m_ValueCtrl->SetValue( m_valueCopy->GetText() );
+ m_FootprintNameCtrl->SetValue( m_currentModule->GetFPID().Format() );
+
+ m_AttributsCtrl->SetItemToolTip( 0, _( "Use this attribute for most non SMD components" ) );
+ m_AttributsCtrl->SetItemToolTip( 1,
+ _( "Use this attribute for SMD components.\nOnly components with this option are put in the footprint position list file" ) );
+ m_AttributsCtrl->SetItemToolTip( 2,
+ _( "Use this attribute for \"virtual\" components drawn on board (like a old ISA PC bus connector)" ) );
+
+ // Controls on right side of the dialog
+ switch( m_currentModule->GetAttributes() & 255 )
+ {
+ case 0:
+ m_AttributsCtrl->SetSelection( 0 );
+ break;
+
+ case MOD_CMS:
+ m_AttributsCtrl->SetSelection( 1 );
+ break;
+
+ case MOD_VIRTUAL:
+ m_AttributsCtrl->SetSelection( 2 );
+ break;
+
+ default:
+ m_AttributsCtrl->SetSelection( 0 );
+ break;
+ }
+
+ m_AutoPlaceCtrl->SetSelection( (m_currentModule->IsLocked()) ? 1 : 0 );
+ m_AutoPlaceCtrl->SetItemToolTip( 0, _( "Enable hotkey move commands and Auto Placement" ) );
+ m_AutoPlaceCtrl->SetItemToolTip( 1, _( "Disable hotkey move commands and Auto Placement" ) );
+
+ m_CostRot90Ctrl->SetValue( m_currentModule->GetPlacementCost90() );
+ m_CostRot180Ctrl->SetValue( m_currentModule->GetPlacementCost180() );
+
+ // Initialize 3D parameters
+ m_3D_Scale = new S3DPOINT_VALUE_CTRL( m_Panel3D, m_bSizerShapeScale );
+ m_3D_Offset = new S3DPOINT_VALUE_CTRL( m_Panel3D, m_bSizerShapeOffset );
+ m_3D_Rotation = new S3DPOINT_VALUE_CTRL( m_Panel3D, m_bSizerShapeRotation );
+
+ // Initialize dialog relative to masks clearances
+ m_NetClearanceUnits->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_SolderMaskMarginUnits->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_SolderPasteMarginUnits->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+
+ wxString msg;
+ PutValueInLocalUnits( *m_NetClearanceValueCtrl, m_currentModule->GetLocalClearance() );
+ PutValueInLocalUnits( *m_SolderMaskMarginCtrl, m_currentModule->GetLocalSolderMaskMargin() );
+
+ // These 2 parameters are usually < 0, so prepare entering a negative value, if current is 0
+ PutValueInLocalUnits( *m_SolderPasteMarginCtrl, m_currentModule->GetLocalSolderPasteMargin() );
+
+ if( m_currentModule->GetLocalSolderPasteMargin() == 0 )
+ m_SolderPasteMarginCtrl->SetValue( wxT( "-" ) + m_SolderPasteMarginCtrl->GetValue() );
+
+ if( m_currentModule->GetLocalSolderPasteMarginRatio() == 0.0 )
+ msg.Printf( wxT( "-%f" ), m_currentModule->GetLocalSolderPasteMarginRatio() * 100.0 );
+ else
+ msg.Printf( wxT( "%f" ), m_currentModule->GetLocalSolderPasteMarginRatio() * 100.0 );
+
+ m_SolderPasteMarginRatioCtrl->SetValue( msg );
+
+ // Add solder paste margin ration in per cent
+ // for the usual default value 0.0, display -0.0 (or -0,0 in some countries)
+ msg.Printf( wxT( "%f" ), m_currentModule->GetLocalSolderPasteMarginRatio() * 100.0 );
+
+ if( m_currentModule->GetLocalSolderPasteMarginRatio() == 0.0 &&
+ msg[0] == '0') // Sometimes Printf adds a sign if the value is very small (0.0)
+ m_SolderPasteMarginRatioCtrl->SetValue( wxT( "-" ) + msg );
+ else
+ m_SolderPasteMarginRatioCtrl->SetValue( msg );
+
+ // if m_3D_ShapeNameListBox is not empty, preselect first 3D shape
+ if( m_3D_ShapeNameListBox->GetCount() > 0 )
+ {
+ m_lastSelected3DShapeIndex = 0;
+ m_3D_ShapeNameListBox->SetSelection( m_lastSelected3DShapeIndex );
+ Transfert3DValuesToDisplay( m_shapes3D_list[m_lastSelected3DShapeIndex] );
+ }
+
+ // We have modified the UI, so call Fit() for m_Panel3D
+ // to be sure the m_Panel3D sizers are initialized before opening the dialog
+ m_Panel3D->GetSizer()->Fit( m_Panel3D );
+}
+
+
+// Initialize 3D info displayed in dialog box from values in aStruct3DSource
+void DIALOG_MODULE_MODULE_EDITOR::Transfert3DValuesToDisplay( S3D_MASTER * aStruct3DSource )
+{
+ if( aStruct3DSource )
+ {
+ m_3D_Scale->SetValue( aStruct3DSource->m_MatScale );
+ m_3D_Offset->SetValue( aStruct3DSource->m_MatPosition );
+ m_3D_Rotation->SetValue( aStruct3DSource->m_MatRotation );
+ }
+ else
+ {
+ S3DPOINT dummy_vertex( 1.0, 1.0, 1.0 );
+ m_3D_Scale->SetValue( dummy_vertex );
+ }
+}
+
+
+/** Copy 3D info displayed in dialog box to values in a item in m_shapes3D_list
+ * @param aIndexSelection = item index in m_shapes3D_list
+ */
+void DIALOG_MODULE_MODULE_EDITOR::TransfertDisplayTo3DValues( int aIndexSelection )
+{
+ if( aIndexSelection >= (int)m_shapes3D_list.size() )
+ return;
+
+ S3D_MASTER * struct3DDest = m_shapes3D_list[aIndexSelection];
+ struct3DDest->m_MatScale = m_3D_Scale->GetValue();
+ struct3DDest->m_MatRotation = m_3D_Rotation->GetValue();
+ struct3DDest->m_MatPosition = m_3D_Offset->GetValue();
+}
+
+
+void DIALOG_MODULE_MODULE_EDITOR::On3DShapeNameSelected(wxCommandEvent& event)
+{
+ if( m_lastSelected3DShapeIndex >= 0 )
+ TransfertDisplayTo3DValues( m_lastSelected3DShapeIndex );
+
+ m_lastSelected3DShapeIndex = m_3D_ShapeNameListBox->GetSelection();
+
+ if( m_lastSelected3DShapeIndex < 0 ) // happens under wxGTK when deleting an item in m_3D_ShapeNameListBox wxListBox
+ return;
+
+ if( m_lastSelected3DShapeIndex >= (int)m_shapes3D_list.size() )
+ {
+ wxMessageBox( wxT( "On3DShapeNameSelected() error" ) );
+ m_lastSelected3DShapeIndex = -1;
+ return;
+ }
+
+ Transfert3DValuesToDisplay( m_shapes3D_list[m_lastSelected3DShapeIndex] );
+}
+
+
+void DIALOG_MODULE_MODULE_EDITOR::Remove3DShape(wxCommandEvent& event)
+{
+ if( m_lastSelected3DShapeIndex >= 0 )
+ TransfertDisplayTo3DValues( m_lastSelected3DShapeIndex );
+
+ int ii = m_3D_ShapeNameListBox->GetSelection();
+
+ if( ii < 0 )
+ return;
+
+ m_shapes3D_list.erase( m_shapes3D_list.begin() + ii );
+ m_3D_ShapeNameListBox->Delete( ii );
+
+ if( m_3D_ShapeNameListBox->GetCount() == 0)
+ Transfert3DValuesToDisplay( NULL );
+ else
+ {
+ m_lastSelected3DShapeIndex = 0;
+ m_3D_ShapeNameListBox->SetSelection( m_lastSelected3DShapeIndex );
+ Transfert3DValuesToDisplay( m_shapes3D_list[m_lastSelected3DShapeIndex] );
+ }
+}
+
+
+void DIALOG_MODULE_MODULE_EDITOR::Edit3DShapeFileName()
+{
+ int idx = m_3D_ShapeNameListBox->GetSelection();
+
+ if( idx < 0 )
+ return;
+
+ // Edit filename
+ wxString filename = m_3D_ShapeNameListBox->GetStringSelection();
+
+ wxTextEntryDialog dlg( this, wxEmptyString, wxEmptyString, filename );
+ dlg.SetTextValidator( FILE_NAME_WITH_PATH_CHAR_VALIDATOR( &filename ) );
+
+ if( dlg.ShowModal() != wxID_OK || filename.IsEmpty() )
+ return; //Aborted by user
+
+#ifdef __WINDOWS__
+ // In Kicad files, filenames and paths are stored using Unix notation
+ // So be sure the unix notation is still used
+ filename.Replace( wxT( "\\" ), wxT( "/" ) );
+#endif
+
+ m_3D_ShapeNameListBox->SetString( idx, filename );
+
+ S3D_MASTER* new3DShape = new S3D_MASTER( NULL );
+ new3DShape->SetShape3DName( filename );
+ delete m_shapes3D_list[idx];
+ m_shapes3D_list[idx] = new3DShape;
+}
+
+
+void DIALOG_MODULE_MODULE_EDITOR::BrowseAndAdd3DShapeFile()
+{
+ PROJECT& prj = Prj();
+
+ // here, the KISYS3DMOD default path for 3D shape files is expected
+ // to be already defined (when starting Pcbnew, it is defined
+ // from the user defined env variable, or set to a default value)
+ wxFileName fn( wxGetenv( KISYS3DMOD ), wxEmptyString );
+ wxString default3DPath = fn.GetPathWithSep();
+
+ wxString initialpath = prj.GetRString( PROJECT::VIEWER_3D_PATH );
+
+ if( !initialpath )
+ initialpath = default3DPath;
+
+#ifdef __WINDOWS__
+ initialpath.Replace( wxT( "/" ), wxT( "\\" ) );
+#endif
+
+ wxString fileFilters = wxGetTranslation( Shapes3DFileWildcard );
+
+ fileFilters += wxChar( '|' );
+ fileFilters += wxGetTranslation( IDF3DFileWildcard );
+
+ wxString filename = EDA_FILE_SELECTOR( _( "3D Shape:" ), initialpath,
+ wxEmptyString, wxEmptyString,
+ wxGetTranslation( fileFilters ),
+ this, wxFD_OPEN, true );
+
+ if( filename.IsEmpty() )
+ return;
+
+ fn = filename;
+
+ prj.SetRString( PROJECT::VIEWER_3D_PATH, fn.GetPath() );
+
+ /* If the file path is already in the 3D shape file default path
+ * just add the file name relative to this path to the list.
+ * Otherwise, add the file name with a full or relative path.
+ * The relative path, when possible, is preferable
+ * because it preserve use of default path, when the path is a sub path of this path
+ */
+ wxString rootpath = filename.SubString( 0, default3DPath.Length()-1 );
+ bool useRelPath = rootpath.IsSameAs( default3DPath, wxFileName::IsCaseSensitive() );
+
+ if( useRelPath )
+ fn.MakeRelativeTo( default3DPath );
+ else // Absolute path given, not a subpath of the default path,
+ // therefore ask if the user wants a relative (to the default path) one
+ {
+ wxString msg;
+ msg.Printf( _( "Use a path relative to '%s'?" ), GetChars( default3DPath ) );
+ int diag = wxMessageBox( msg, _( "Path type" ),
+ wxYES_NO | wxICON_QUESTION, this );
+
+ if( diag == wxYES ) // Make it relative to the default 3D path
+ fn.MakeRelativeTo( default3DPath );
+ }
+
+ filename = fn.GetFullPath();
+
+ S3D_MASTER* new3DShape = new S3D_MASTER(NULL);
+
+#ifdef __WINDOWS__
+ // Store filename in Unix notation
+ filename.Replace( wxT( "\\" ), wxT( "/" ) );
+#endif
+
+ new3DShape->SetShape3DName( filename );
+ m_shapes3D_list.push_back( new3DShape );
+ m_3D_ShapeNameListBox->Append( filename );
+
+ if( m_lastSelected3DShapeIndex >= 0 )
+ TransfertDisplayTo3DValues( m_lastSelected3DShapeIndex );
+
+ m_lastSelected3DShapeIndex = m_3D_ShapeNameListBox->GetCount() - 1;
+ m_3D_ShapeNameListBox->SetSelection( m_lastSelected3DShapeIndex );
+ Transfert3DValuesToDisplay( m_shapes3D_list[m_lastSelected3DShapeIndex] );
+}
+
+
+void DIALOG_MODULE_MODULE_EDITOR::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( -1 );
+}
+
+
+void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event )
+{
+ // First, test for invalid chars in module name
+ wxString footprintName = m_FootprintNameCtrl->GetValue();
+
+ if( ! footprintName.IsEmpty() )
+ {
+ if( ! MODULE::IsLibNameValid( footprintName ) )
+ {
+ wxString msg;
+ msg.Printf( _( "Error:\none of invalid chars <%s> found\nin <%s>" ),
+ MODULE::StringLibNameInvalidChars( true ),
+ GetChars( footprintName ) );
+
+ DisplayError( NULL, msg );
+ return;
+ }
+ }
+
+ m_parent->SaveCopyInUndoList( m_currentModule, UR_MODEDIT );
+ m_currentModule->SetLocked( m_AutoPlaceCtrl->GetSelection() == 1 );
+
+ switch( m_AttributsCtrl->GetSelection() )
+ {
+ case 0:
+ m_currentModule->SetAttributes( 0 );
+ break;
+
+ case 1:
+ m_currentModule->SetAttributes( MOD_CMS );
+ break;
+
+ case 2:
+ m_currentModule->SetAttributes( MOD_VIRTUAL );
+ break;
+ }
+
+ m_currentModule->SetPlacementCost90( m_CostRot90Ctrl->GetValue() );
+ m_currentModule->SetPlacementCost180( m_CostRot180Ctrl->GetValue() );
+ m_currentModule->SetDescription( m_DocCtrl->GetValue() );
+ m_currentModule->SetKeywords( m_KeywordCtrl->GetValue() );
+
+ // Init footprint name in library
+ if( ! footprintName.IsEmpty() )
+ m_currentModule->SetFPID( FPID( footprintName ) );
+
+ // Init Fields:
+ m_currentModule->Reference().Copy( m_referenceCopy );
+ m_currentModule->Value().Copy( m_valueCopy );
+
+ // Initialize masks clearances
+ m_currentModule->SetLocalClearance( ValueFromTextCtrl( *m_NetClearanceValueCtrl ) );
+ m_currentModule->SetLocalSolderMaskMargin( ValueFromTextCtrl( *m_SolderMaskMarginCtrl ) );
+ m_currentModule->SetLocalSolderPasteMargin( ValueFromTextCtrl( *m_SolderPasteMarginCtrl ) );
+ double dtmp;
+ wxString msg = m_SolderPasteMarginRatioCtrl->GetValue();
+ msg.ToDouble( &dtmp );
+
+ // A -50% margin ratio means no paste on a pad, the ratio must be >= -50 %
+ if( dtmp < -50.0 )
+ dtmp = -50.0;
+
+ // A margin ratio is always <= 0
+ if( dtmp > 0.0 )
+ dtmp = 0.0;
+
+ m_currentModule->SetLocalSolderPasteMarginRatio( dtmp / 100 );
+
+ // Update 3D shape list
+ int ii = m_3D_ShapeNameListBox->GetSelection();
+
+ if ( ii >= 0 )
+ TransfertDisplayTo3DValues( ii );
+
+ S3D_MASTER* draw3D = m_currentModule->Models();
+
+ for( unsigned ii = 0; ii < m_shapes3D_list.size(); ii++ )
+ {
+ S3D_MASTER* draw3DCopy = m_shapes3D_list[ii];
+
+ if( draw3DCopy->GetShape3DName().IsEmpty() )
+ continue;
+
+ if( draw3D == NULL )
+ {
+ draw3D = new S3D_MASTER( draw3D );
+ m_currentModule->Models().Append( draw3D );
+ }
+
+ draw3D->SetShape3DName( draw3DCopy->GetShape3DName() );
+ draw3D->m_MatScale = draw3DCopy->m_MatScale;
+ draw3D->m_MatRotation = draw3DCopy->m_MatRotation;
+ draw3D->m_MatPosition = draw3DCopy->m_MatPosition;
+
+ draw3D = draw3D->Next();
+ }
+
+ // Remove old extra 3D shapes
+ S3D_MASTER* nextdraw3D;
+
+ for( ; draw3D != NULL; draw3D = nextdraw3D )
+ {
+ nextdraw3D = (S3D_MASTER*) draw3D->Next();
+ delete m_currentModule->Models().Remove( draw3D );
+ }
+
+ // Fill shape list with one void entry, if no entry
+ if( m_currentModule->Models() == NULL )
+ m_currentModule->Models().PushBack( new S3D_MASTER( m_currentModule ) );
+
+
+ m_currentModule->CalculateBoundingBox();
+
+ m_parent->OnModify();
+
+ EndModal( 1 );
+}
+
+
+void DIALOG_MODULE_MODULE_EDITOR::OnEditReference(wxCommandEvent& event)
+{
+ wxPoint tmp = m_parent->GetCrossHairPosition();
+ m_parent->SetCrossHairPosition( m_referenceCopy->GetTextPosition() );
+ m_parent->InstallTextModOptionsFrame( m_referenceCopy, NULL );
+ m_parent->SetCrossHairPosition( tmp );
+ m_ReferenceCtrl->SetValue( m_referenceCopy->GetText() );
+}
+
+
+void DIALOG_MODULE_MODULE_EDITOR::OnEditValue(wxCommandEvent& event)
+{
+ wxPoint tmp = m_parent->GetCrossHairPosition();
+ m_parent->SetCrossHairPosition( m_valueCopy->GetTextPosition() );
+ m_parent->InstallTextModOptionsFrame( m_valueCopy, NULL );
+ m_parent->SetCrossHairPosition( tmp );
+ m_ValueCtrl->SetValue( m_valueCopy->GetText() );
+}
diff --git a/pcbnew/dialogs/dialog_edit_module_for_Modedit.h b/pcbnew/dialogs/dialog_edit_module_for_Modedit.h
new file mode 100644
index 0000000..06fac76
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_for_Modedit.h
@@ -0,0 +1,79 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2015 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __DIALOG_EDIT_MODULE_FOR_MODEDIT__
+#define __DIALOG_EDIT_MODULE_FOR_MODEDIT__
+
+// Include the wxFormBuider header base:
+#include <vector>
+#include <dialog_edit_module_for_Modedit_base.h>
+
+class DIALOG_MODULE_MODULE_EDITOR : public DIALOG_MODULE_MODULE_EDITOR_BASE
+{
+private:
+
+ FOOTPRINT_EDIT_FRAME* m_parent;
+ MODULE* m_currentModule;
+ TEXTE_MODULE* m_referenceCopy;
+ TEXTE_MODULE* m_valueCopy;
+ std::vector <S3D_MASTER*> m_shapes3D_list;
+ int m_lastSelected3DShapeIndex;
+ S3DPOINT_VALUE_CTRL * m_3D_Scale;
+ S3DPOINT_VALUE_CTRL * m_3D_Offset;
+ S3DPOINT_VALUE_CTRL * m_3D_Rotation;
+ static size_t m_page; // remember the last open page during session
+
+public:
+
+ // Constructor and destructor
+ DIALOG_MODULE_MODULE_EDITOR( FOOTPRINT_EDIT_FRAME* aParent, MODULE* aModule );
+ ~DIALOG_MODULE_MODULE_EDITOR();
+
+private:
+ void BrowseAndAdd3DShapeFile();
+ void initModeditProperties();
+ void Transfert3DValuesToDisplay( S3D_MASTER * aStruct3DSource );
+ void TransfertDisplayTo3DValues( int aIndexSelection );
+ void Edit3DShapeFileName();
+
+ // virtual event functions
+ void OnEditValue( wxCommandEvent& event );
+ void OnEditReference( wxCommandEvent& event );
+ void On3DShapeSelection( wxCommandEvent& event );
+ void On3DShapeNameSelected( wxCommandEvent& event );
+ void Add3DShape( wxCommandEvent& event )
+ {
+ BrowseAndAdd3DShapeFile();
+ }
+ void Remove3DShape( wxCommandEvent& event );
+ void Edit3DShapeFilename( wxCommandEvent& event )
+ {
+ Edit3DShapeFileName();
+ }
+ void OnCancelClick( wxCommandEvent& event );
+ void OnOkClick( wxCommandEvent& event );
+};
+
+
+#endif // __DIALOG_EDIT_MODULE_FOR_MODEDIT__
diff --git a/pcbnew/dialogs/dialog_edit_module_for_Modedit_base.cpp b/pcbnew/dialogs/dialog_edit_module_for_Modedit_base.cpp
new file mode 100644
index 0000000..535a687
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_for_Modedit_base.cpp
@@ -0,0 +1,352 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_edit_module_for_Modedit_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_MODULE_MODULE_EDITOR_BASE::DIALOG_MODULE_MODULE_EDITOR_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ m_GeneralBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_NoteBook = new wxNotebook( this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PanelProperties = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
+ wxBoxSizer* m_PanelPropertiesBoxSizer;
+ m_PanelPropertiesBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* PropLeftSizer;
+ PropLeftSizer = new wxStaticBoxSizer( new wxStaticBox( m_PanelProperties, wxID_ANY, _("Fields") ), wxVERTICAL );
+
+ m_staticTextDoc = new wxStaticText( m_PanelProperties, wxID_ANY, _("Doc"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextDoc->Wrap( -1 );
+ PropLeftSizer->Add( m_staticTextDoc, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_DocCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_DocCtrl->SetMaxLength( 0 );
+ PropLeftSizer->Add( m_DocCtrl, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_staticTextKeywords = new wxStaticText( m_PanelProperties, wxID_ANY, _("Keywords"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextKeywords->Wrap( -1 );
+ PropLeftSizer->Add( m_staticTextKeywords, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_KeywordCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_KeywordCtrl->SetMaxLength( 0 );
+ PropLeftSizer->Add( m_KeywordCtrl, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_staticTextRef = new wxStaticText( m_PanelProperties, wxID_ANY, _("Reference"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextRef->Wrap( -1 );
+ PropLeftSizer->Add( m_staticTextRef, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerRef;
+ bSizerRef = new wxBoxSizer( wxHORIZONTAL );
+
+ m_ReferenceCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ m_ReferenceCtrl->SetMaxLength( 0 );
+ bSizerRef->Add( m_ReferenceCtrl, 1, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_button4 = new wxButton( m_PanelProperties, wxID_ANY, _("Edit"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
+ bSizerRef->Add( m_button4, 0, wxBOTTOM|wxRIGHT, 5 );
+
+
+ PropLeftSizer->Add( bSizerRef, 0, wxEXPAND, 5 );
+
+ m_staticTextVal = new wxStaticText( m_PanelProperties, wxID_ANY, _("Value"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextVal->Wrap( -1 );
+ PropLeftSizer->Add( m_staticTextVal, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerVal;
+ bSizerVal = new wxBoxSizer( wxHORIZONTAL );
+
+ m_ValueCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ m_ValueCtrl->SetMaxLength( 0 );
+ bSizerVal->Add( m_ValueCtrl, 1, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_button5 = new wxButton( m_PanelProperties, wxID_ANY, _("Edit"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
+ bSizerVal->Add( m_button5, 0, wxBOTTOM|wxRIGHT, 5 );
+
+
+ PropLeftSizer->Add( bSizerVal, 0, wxEXPAND, 5 );
+
+
+ PropLeftSizer->Add( 0, 20, 0, 0, 5 );
+
+ m_staticTextFp = new wxStaticText( m_PanelProperties, wxID_ANY, _("Footprint Name in Library"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextFp->Wrap( -1 );
+ PropLeftSizer->Add( m_staticTextFp, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_FootprintNameCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_FootprintNameCtrl->SetMaxLength( 0 );
+ PropLeftSizer->Add( m_FootprintNameCtrl, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+
+ PropLeftSizer->Add( 0, 0, 0, wxEXPAND, 5 );
+
+
+ m_PanelPropertiesBoxSizer->Add( PropLeftSizer, 1, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_PropRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerAttrib;
+ bSizerAttrib = new wxBoxSizer( wxHORIZONTAL );
+
+ wxString m_AttributsCtrlChoices[] = { _("Normal"), _("Normal+Insert"), _("Virtual") };
+ int m_AttributsCtrlNChoices = sizeof( m_AttributsCtrlChoices ) / sizeof( wxString );
+ m_AttributsCtrl = new wxRadioBox( m_PanelProperties, wxID_ANY, _("Attributes"), wxDefaultPosition, wxDefaultSize, m_AttributsCtrlNChoices, m_AttributsCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_AttributsCtrl->SetSelection( 0 );
+ bSizerAttrib->Add( m_AttributsCtrl, 1, wxALL|wxEXPAND, 5 );
+
+ wxString m_AutoPlaceCtrlChoices[] = { _("Free"), _("Locked") };
+ int m_AutoPlaceCtrlNChoices = sizeof( m_AutoPlaceCtrlChoices ) / sizeof( wxString );
+ m_AutoPlaceCtrl = new wxRadioBox( m_PanelProperties, wxID_ANY, _("Move and Place"), wxDefaultPosition, wxDefaultSize, m_AutoPlaceCtrlNChoices, m_AutoPlaceCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_AutoPlaceCtrl->SetSelection( 0 );
+ bSizerAttrib->Add( m_AutoPlaceCtrl, 1, wxALL|wxEXPAND, 5 );
+
+
+ m_PropRightSizer->Add( bSizerAttrib, 0, wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbSizerAutoplace;
+ sbSizerAutoplace = new wxStaticBoxSizer( new wxStaticBox( m_PanelProperties, wxID_ANY, _("Auto Place") ), wxHORIZONTAL );
+
+ wxBoxSizer* bSizerRot90;
+ bSizerRot90 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText11 = new wxStaticText( m_PanelProperties, wxID_ANY, _("Rotation 90 degree"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText11->Wrap( -1 );
+ bSizerRot90->Add( m_staticText11, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
+
+ m_CostRot90Ctrl = new wxSlider( m_PanelProperties, wxID_ANY, 0, 0, 10, wxDefaultPosition, wxSize( -1,-1 ), wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_LABELS );
+ bSizerRot90->Add( m_CostRot90Ctrl, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+
+ sbSizerAutoplace->Add( bSizerRot90, 1, 0, 5 );
+
+ wxBoxSizer* bSizerRot180;
+ bSizerRot180 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText12 = new wxStaticText( m_PanelProperties, wxID_ANY, _("Rotation 180 degree"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText12->Wrap( -1 );
+ bSizerRot180->Add( m_staticText12, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
+
+ m_CostRot180Ctrl = new wxSlider( m_PanelProperties, wxID_ANY, 0, 0, 10, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_LABELS );
+ bSizerRot180->Add( m_CostRot180Ctrl, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+
+ sbSizerAutoplace->Add( bSizerRot180, 1, 0, 5 );
+
+
+ m_PropRightSizer->Add( sbSizerAutoplace, 0, wxEXPAND|wxALL, 5 );
+
+ wxStaticBoxSizer* sbSizer8;
+ sbSizer8 = new wxStaticBoxSizer( new wxStaticBox( m_PanelProperties, wxID_ANY, _("Local Clearance Values") ), wxVERTICAL );
+
+ m_staticTextInfo = new wxStaticText( m_PanelProperties, wxID_ANY, _("Set clearances to 0 to use global values"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextInfo->Wrap( -1 );
+ m_staticTextInfo->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ sbSizer8->Add( m_staticTextInfo, 0, wxALL, 5 );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 5, 3, 0, 0 );
+ fgSizer1->AddGrowableCol( 1 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticTextNetClearance = new wxStaticText( m_PanelProperties, wxID_ANY, _("Pad clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextNetClearance->Wrap( -1 );
+ fgSizer1->Add( m_staticTextNetClearance, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_NetClearanceValueCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_NetClearanceValueCtrl->SetMaxLength( 0 );
+ fgSizer1->Add( m_NetClearanceValueCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_NetClearanceUnits = new wxStaticText( m_PanelProperties, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_NetClearanceUnits->Wrap( -1 );
+ fgSizer1->Add( m_NetClearanceUnits, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_staticline1 = new wxStaticLine( m_PanelProperties, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ fgSizer1->Add( m_staticline1, 0, wxEXPAND, 5 );
+
+ m_staticline2 = new wxStaticLine( m_PanelProperties, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ fgSizer1->Add( m_staticline2, 0, wxEXPAND, 5 );
+
+ m_staticline3 = new wxStaticLine( m_PanelProperties, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ fgSizer1->Add( m_staticline3, 0, wxEXPAND, 5 );
+
+ m_MaskClearanceTitle = new wxStaticText( m_PanelProperties, wxID_ANY, _("Solder mask clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MaskClearanceTitle->Wrap( -1 );
+ m_MaskClearanceTitle->SetToolTip( _("This is the local clearance between pads and the solder mask\nfor this footprint\nThis value can be superseded by a pad local value.\nIf 0, the global value is used") );
+
+ fgSizer1->Add( m_MaskClearanceTitle, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
+
+ m_SolderMaskMarginCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMarginCtrl->SetMaxLength( 0 );
+ fgSizer1->Add( m_SolderMaskMarginCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_SolderMaskMarginUnits = new wxStaticText( m_PanelProperties, wxID_ANY, _("inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMarginUnits->Wrap( -1 );
+ fgSizer1->Add( m_SolderMaskMarginUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+ m_staticTextSolderPaste = new wxStaticText( m_PanelProperties, wxID_ANY, _("Solder paste clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSolderPaste->Wrap( -1 );
+ m_staticTextSolderPaste->SetToolTip( _("This is the local clearance between pads and the solder paste\nfor this footprint.\nThis value can be superseded by a pad local values.\nThe final clearance value is the sum of this value and the clearance value ratio\nA negative value means a smaller mask size than pad size") );
+
+ fgSizer1->Add( m_staticTextSolderPaste, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
+
+ m_SolderPasteMarginCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginCtrl->SetMaxLength( 0 );
+ fgSizer1->Add( m_SolderPasteMarginCtrl, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_SolderPasteMarginUnits = new wxStaticText( m_PanelProperties, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginUnits->Wrap( -1 );
+ fgSizer1->Add( m_SolderPasteMarginUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+ m_staticTextRatio = new wxStaticText( m_PanelProperties, wxID_ANY, _("Solder paste ratio clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextRatio->Wrap( -1 );
+ m_staticTextRatio->SetToolTip( _("This is the local clearance ratio in per cent between pads and the solder paste\nfor this footprint.\nA value of 10 means the clearance value is 10 per cent of the pad size\nThis value can be superseded by a pad local value.\nThe final clearance value is the sum of this value and the clearance value\nA negative value means a smaller mask size than pad size.") );
+
+ fgSizer1->Add( m_staticTextRatio, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
+
+ m_SolderPasteMarginRatioCtrl = new wxTextCtrl( m_PanelProperties, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginRatioCtrl->SetMaxLength( 0 );
+ fgSizer1->Add( m_SolderPasteMarginRatioCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_SolderPasteRatioMarginUnits = new wxStaticText( m_PanelProperties, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteRatioMarginUnits->Wrap( -1 );
+ fgSizer1->Add( m_SolderPasteRatioMarginUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+
+ sbSizer8->Add( fgSizer1, 1, wxEXPAND, 5 );
+
+
+ m_PropRightSizer->Add( sbSizer8, 0, wxEXPAND|wxALL, 5 );
+
+
+ m_PanelPropertiesBoxSizer->Add( m_PropRightSizer, 0, 0, 5 );
+
+
+ m_PanelProperties->SetSizer( m_PanelPropertiesBoxSizer );
+ m_PanelProperties->Layout();
+ m_PanelPropertiesBoxSizer->Fit( m_PanelProperties );
+ m_NoteBook->AddPage( m_PanelProperties, _("Properties"), true );
+ m_Panel3D = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
+ wxBoxSizer* bSizerMain3D;
+ bSizerMain3D = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText3Dname = new wxStaticText( m_Panel3D, wxID_ANY, _("3D Shape Names"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3Dname->Wrap( -1 );
+ bSizerMain3D->Add( m_staticText3Dname, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_3D_ShapeNameListBox = new wxListBox( m_Panel3D, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE );
+ bSizerMain3D->Add( m_3D_ShapeNameListBox, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticTextDefault3DPath = new wxStaticText( m_Panel3D, wxID_ANY, _("Default Path (from KISYS3DMOD environment variable)"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextDefault3DPath->Wrap( -1 );
+ bSizerMain3D->Add( m_staticTextDefault3DPath, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_textCtrl3DDefaultPath = new wxTextCtrl( m_Panel3D, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ bSizerMain3D->Add( m_textCtrl3DDefaultPath, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ wxBoxSizer* bLowerSizer3D;
+ bLowerSizer3D = new wxBoxSizer( wxHORIZONTAL );
+
+ m_Sizer3DValues = new wxStaticBoxSizer( new wxStaticBox( m_Panel3D, wxID_ANY, _("3D Scale and Position") ), wxVERTICAL );
+
+ m_bSizerShapeScale = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextShapeScale = new wxStaticText( m_Panel3D, wxID_ANY, _("Shape Scale:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextShapeScale->Wrap( -1 );
+ m_bSizerShapeScale->Add( m_staticTextShapeScale, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+
+ m_Sizer3DValues->Add( m_bSizerShapeScale, 0, wxEXPAND, 5 );
+
+ m_bSizerShapeOffset = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextShapeOffset = new wxStaticText( m_Panel3D, wxID_ANY, _("Shape Offset (inch):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextShapeOffset->Wrap( -1 );
+ m_bSizerShapeOffset->Add( m_staticTextShapeOffset, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+
+ m_Sizer3DValues->Add( m_bSizerShapeOffset, 0, wxEXPAND, 5 );
+
+ m_bSizerShapeRotation = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextShapeRotation = new wxStaticText( m_Panel3D, wxID_ANY, _("Shape Rotation (degrees):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextShapeRotation->Wrap( -1 );
+ m_bSizerShapeRotation->Add( m_staticTextShapeRotation, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+
+ m_Sizer3DValues->Add( m_bSizerShapeRotation, 0, wxEXPAND, 5 );
+
+
+ bLowerSizer3D->Add( m_Sizer3DValues, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer3DButtons;
+ bSizer3DButtons = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonBrowse = new wxButton( m_Panel3D, ID_BROWSE_3D_LIB, _("Add 3D Shape"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer3DButtons->Add( m_buttonBrowse, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonRemove = new wxButton( m_Panel3D, ID_REMOVE_3D_SHAPE, _("Remove 3D Shape"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer3DButtons->Add( m_buttonRemove, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonEdit = new wxButton( m_Panel3D, wxID_ANY, _("Edit Filename"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer3DButtons->Add( m_buttonEdit, 0, wxALL|wxEXPAND, 5 );
+
+
+ bLowerSizer3D->Add( bSizer3DButtons, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bSizerMain3D->Add( bLowerSizer3D, 0, wxALL|wxEXPAND, 5 );
+
+
+ m_Panel3D->SetSizer( bSizerMain3D );
+ m_Panel3D->Layout();
+ bSizerMain3D->Fit( m_Panel3D );
+ m_NoteBook->AddPage( m_Panel3D, _("3D settings"), false );
+
+ m_GeneralBoxSizer->Add( m_NoteBook, 1, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizerStdButtons = new wxStdDialogButtonSizer();
+ m_sdbSizerStdButtonsOK = new wxButton( this, wxID_OK );
+ m_sdbSizerStdButtons->AddButton( m_sdbSizerStdButtonsOK );
+ m_sdbSizerStdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizerStdButtons->AddButton( m_sdbSizerStdButtonsCancel );
+ m_sdbSizerStdButtons->Realize();
+
+ m_GeneralBoxSizer->Add( m_sdbSizerStdButtons, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( m_GeneralBoxSizer );
+ this->Layout();
+
+ // Connect Events
+ m_button4->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::OnEditReference ), NULL, this );
+ m_button5->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::OnEditValue ), NULL, this );
+ m_3D_ShapeNameListBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::On3DShapeNameSelected ), NULL, this );
+ m_buttonBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::Add3DShape ), NULL, this );
+ m_buttonRemove->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::Remove3DShape ), NULL, this );
+ m_buttonEdit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::Edit3DShapeFilename ), NULL, this );
+ m_sdbSizerStdButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerStdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_MODULE_MODULE_EDITOR_BASE::~DIALOG_MODULE_MODULE_EDITOR_BASE()
+{
+ // Disconnect Events
+ m_button4->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::OnEditReference ), NULL, this );
+ m_button5->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::OnEditValue ), NULL, this );
+ m_3D_ShapeNameListBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::On3DShapeNameSelected ), NULL, this );
+ m_buttonBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::Add3DShape ), NULL, this );
+ m_buttonRemove->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::Remove3DShape ), NULL, this );
+ m_buttonEdit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::Edit3DShapeFilename ), NULL, this );
+ m_sdbSizerStdButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerStdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODULE_MODULE_EDITOR_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_edit_module_for_Modedit_base.fbp b/pcbnew/dialogs/dialog_edit_module_for_Modedit_base.fbp
new file mode 100644
index 0000000..8757782
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_for_Modedit_base.fbp
@@ -0,0 +1,4416 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_edit_module_for_Modedit_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_edit_module_for_Modedit_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_MODULE_MODULE_EDITOR_BASE</property>
+ <property name="pos"></property>
+ <property name="size">486,510</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Footprint Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_GeneralBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">private</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxNotebook" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmapsize"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_NOTEBOOK</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NoteBook</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnNotebookPageChanged"></event>
+ <event name="OnNotebookPageChanging"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Properties</property>
+ <property name="select">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PanelProperties</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxSUNKEN_BORDER|wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">m_PanelPropertiesBoxSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Fields</property>
+ <property name="minimum_size"></property>
+ <property name="name">PropLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Doc</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextDoc</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DocCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Keywords</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextKeywords</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_KeywordCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Reference</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextRef</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRef</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ReferenceCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Edit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_button4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_EXACTFIT</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnEditReference</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextVal</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerVal</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ValueCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Edit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_button5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_EXACTFIT</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnEditValue</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="0">
+ <property name="height">20</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprint Name in Library</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextFp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FootprintNameCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="0">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">m_PropRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">private</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerAttrib</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Normal&quot; &quot;Normal+Insert&quot; &quot;Virtual&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Attributes</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AttributsCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Free&quot; &quot;Locked&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Move and Place</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AutoPlaceCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Auto Place</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerAutoplace</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRot90</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Rotation 90 degree</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText11</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxSlider" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maxValue">10</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="minValue">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_CostRot90Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_LABELS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCommandScroll"></event>
+ <event name="OnCommandScrollBottom"></event>
+ <event name="OnCommandScrollChanged"></event>
+ <event name="OnCommandScrollLineDown"></event>
+ <event name="OnCommandScrollLineUp"></event>
+ <event name="OnCommandScrollPageDown"></event>
+ <event name="OnCommandScrollPageUp"></event>
+ <event name="OnCommandScrollThumbRelease"></event>
+ <event name="OnCommandScrollThumbTrack"></event>
+ <event name="OnCommandScrollTop"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnScroll"></event>
+ <event name="OnScrollBottom"></event>
+ <event name="OnScrollChanged"></event>
+ <event name="OnScrollLineDown"></event>
+ <event name="OnScrollLineUp"></event>
+ <event name="OnScrollPageDown"></event>
+ <event name="OnScrollPageUp"></event>
+ <event name="OnScrollThumbRelease"></event>
+ <event name="OnScrollThumbTrack"></event>
+ <event name="OnScrollTop"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRot180</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Rotation 180 degree</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText12</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxSlider" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maxValue">10</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="minValue">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_CostRot180Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_LABELS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCommandScroll"></event>
+ <event name="OnCommandScrollBottom"></event>
+ <event name="OnCommandScrollChanged"></event>
+ <event name="OnCommandScrollLineDown"></event>
+ <event name="OnCommandScrollLineUp"></event>
+ <event name="OnCommandScrollPageDown"></event>
+ <event name="OnCommandScrollPageUp"></event>
+ <event name="OnCommandScrollThumbRelease"></event>
+ <event name="OnCommandScrollThumbTrack"></event>
+ <event name="OnCommandScrollTop"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnScroll"></event>
+ <event name="OnScrollBottom"></event>
+ <event name="OnScrollChanged"></event>
+ <event name="OnScrollLineDown"></event>
+ <event name="OnScrollLineUp"></event>
+ <event name="OnScrollPageDown"></event>
+ <event name="OnScrollPageUp"></event>
+ <event name="OnScrollThumbRelease"></event>
+ <event name="OnScrollThumbTrack"></event>
+ <event name="OnScrollTop"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Local Clearance Values</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizer8</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Set clearances to 0 to use global values</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextInfo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">5</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextNetClearance</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NetClearanceValueCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NetClearanceUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder mask clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaskClearanceTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the local clearance between pads and the solder mask&#x0A;for this footprint&#x0A;This value can be superseded by a pad local value.&#x0A;If 0, the global value is used</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderMaskMarginCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderMaskMarginUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder paste clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSolderPaste</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the local clearance between pads and the solder paste&#x0A;for this footprint.&#x0A;This value can be superseded by a pad local values.&#x0A;The final clearance value is the sum of this value and the clearance value ratio&#x0A;A negative value means a smaller mask size than pad size</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteMarginCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteMarginUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder paste ratio clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextRatio</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the local clearance ratio in per cent between pads and the solder paste&#x0A;for this footprint.&#x0A;A value of 10 means the clearance value is 10 per cent of the pad size&#x0A;This value can be superseded by a pad local value.&#x0A;The final clearance value is the sum of this value and the clearance value&#x0A;A negative value means a smaller mask size than pad size.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteMarginRatioCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">%</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteRatioMarginUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">3D settings</property>
+ <property name="select">0</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Panel3D</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxSUNKEN_BORDER|wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain3D</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">3D Shape Names</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3Dname</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxListBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_3D_ShapeNameListBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLB_SINGLE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox">On3DShapeNameSelected</event>
+ <event name="OnListBoxDClick"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default Path (from KISYS3DMOD environment variable)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextDefault3DPath</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrl3DDefaultPath</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLowerSizer3D</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">3D Scale and Position</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_Sizer3DValues</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">m_bSizerShapeScale</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Shape Scale:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextShapeScale</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">m_bSizerShapeOffset</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Shape Offset (inch):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextShapeOffset</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">m_bSizerShapeRotation</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Shape Rotation (degrees):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextShapeRotation</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer3DButtons</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_BROWSE_3D_LIB</property>
+ <property name="label">Add 3D Shape</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonBrowse</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">Add3DShape</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_REMOVE_3D_SHAPE</property>
+ <property name="label">Remove 3D Shape</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonRemove</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">Remove3DShape</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Edit Filename</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonEdit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">Edit3DShapeFilename</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizerStdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_edit_module_for_Modedit_base.h b/pcbnew/dialogs/dialog_edit_module_for_Modedit_base.h
new file mode 100644
index 0000000..180f059
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_for_Modedit_base.h
@@ -0,0 +1,127 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_EDIT_MODULE_FOR_MODEDIT_BASE_H__
+#define __DIALOG_EDIT_MODULE_FOR_MODEDIT_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/radiobox.h>
+#include <wx/slider.h>
+#include <wx/statline.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/listbox.h>
+#include <wx/notebook.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_NOTEBOOK 1000
+#define ID_BROWSE_3D_LIB 1001
+#define ID_REMOVE_3D_SHAPE 1002
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_MODULE_MODULE_EDITOR_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_MODULE_MODULE_EDITOR_BASE : public DIALOG_SHIM
+{
+ private:
+ wxBoxSizer* m_GeneralBoxSizer;
+ wxBoxSizer* m_PropRightSizer;
+
+ protected:
+ wxNotebook* m_NoteBook;
+ wxPanel* m_PanelProperties;
+ wxStaticText* m_staticTextDoc;
+ wxTextCtrl* m_DocCtrl;
+ wxStaticText* m_staticTextKeywords;
+ wxTextCtrl* m_KeywordCtrl;
+ wxStaticText* m_staticTextRef;
+ wxTextCtrl* m_ReferenceCtrl;
+ wxButton* m_button4;
+ wxStaticText* m_staticTextVal;
+ wxTextCtrl* m_ValueCtrl;
+ wxButton* m_button5;
+ wxStaticText* m_staticTextFp;
+ wxTextCtrl* m_FootprintNameCtrl;
+ wxRadioBox* m_AttributsCtrl;
+ wxRadioBox* m_AutoPlaceCtrl;
+ wxStaticText* m_staticText11;
+ wxSlider* m_CostRot90Ctrl;
+ wxStaticText* m_staticText12;
+ wxSlider* m_CostRot180Ctrl;
+ wxStaticText* m_staticTextInfo;
+ wxStaticText* m_staticTextNetClearance;
+ wxTextCtrl* m_NetClearanceValueCtrl;
+ wxStaticText* m_NetClearanceUnits;
+ wxStaticLine* m_staticline1;
+ wxStaticLine* m_staticline2;
+ wxStaticLine* m_staticline3;
+ wxStaticText* m_MaskClearanceTitle;
+ wxTextCtrl* m_SolderMaskMarginCtrl;
+ wxStaticText* m_SolderMaskMarginUnits;
+ wxStaticText* m_staticTextSolderPaste;
+ wxTextCtrl* m_SolderPasteMarginCtrl;
+ wxStaticText* m_SolderPasteMarginUnits;
+ wxStaticText* m_staticTextRatio;
+ wxTextCtrl* m_SolderPasteMarginRatioCtrl;
+ wxStaticText* m_SolderPasteRatioMarginUnits;
+ wxPanel* m_Panel3D;
+ wxStaticText* m_staticText3Dname;
+ wxListBox* m_3D_ShapeNameListBox;
+ wxStaticText* m_staticTextDefault3DPath;
+ wxTextCtrl* m_textCtrl3DDefaultPath;
+ wxStaticBoxSizer* m_Sizer3DValues;
+ wxBoxSizer* m_bSizerShapeScale;
+ wxStaticText* m_staticTextShapeScale;
+ wxBoxSizer* m_bSizerShapeOffset;
+ wxStaticText* m_staticTextShapeOffset;
+ wxBoxSizer* m_bSizerShapeRotation;
+ wxStaticText* m_staticTextShapeRotation;
+ wxButton* m_buttonBrowse;
+ wxButton* m_buttonRemove;
+ wxButton* m_buttonEdit;
+ wxStdDialogButtonSizer* m_sdbSizerStdButtons;
+ wxButton* m_sdbSizerStdButtonsOK;
+ wxButton* m_sdbSizerStdButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnEditReference( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnEditValue( wxCommandEvent& event ) { event.Skip(); }
+ virtual void On3DShapeNameSelected( wxCommandEvent& event ) { event.Skip(); }
+ virtual void Add3DShape( wxCommandEvent& event ) { event.Skip(); }
+ virtual void Remove3DShape( wxCommandEvent& event ) { event.Skip(); }
+ virtual void Edit3DShapeFilename( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_MODULE_MODULE_EDITOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Footprint Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 486,510 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_MODULE_MODULE_EDITOR_BASE();
+
+};
+
+#endif //__DIALOG_EDIT_MODULE_FOR_MODEDIT_BASE_H__
diff --git a/pcbnew/dialogs/dialog_edit_module_text.cpp b/pcbnew/dialogs/dialog_edit_module_text.cpp
new file mode 100644
index 0000000..2006fb3
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_text.cpp
@@ -0,0 +1,268 @@
+/**
+ * @file dialog_edit_module_text.cpp
+ * @brief dialog editor for texts (fields) in footprints.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras
+ * Copyright (C) 2013 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2008-2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <macros.h>
+#include <gr_basic.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <pcbnew.h>
+#include <drawtxt.h>
+#include <confirm.h>
+#include <wxBasePcbFrame.h>
+#include <base_units.h>
+
+#include <class_module.h>
+#include <class_text_mod.h>
+#include <class_board.h>
+
+#include <class_pcb_layer_box_selector.h>
+#include <dialog_edit_module_text.h>
+
+
+extern wxPoint MoveVector; // Move vector for move edge, imported from edtxtmod.cpp
+
+
+void PCB_BASE_FRAME::InstallTextModOptionsFrame( TEXTE_MODULE* TextMod, wxDC* DC )
+{
+ m_canvas->SetIgnoreMouseEvents( true );
+ DialogEditModuleText dialog( this, TextMod, DC );
+ dialog.ShowModal();
+ m_canvas->SetIgnoreMouseEvents( false );
+}
+
+
+DialogEditModuleText::DialogEditModuleText( PCB_BASE_FRAME* aParent,
+ TEXTE_MODULE* aTextMod, wxDC* aDC ) :
+ DialogEditModuleText_base( aParent )
+
+{
+ m_parent = aParent;
+ m_dc = aDC;
+ m_module = NULL;
+ m_currentText = aTextMod;
+
+ if( m_currentText )
+ m_module = (MODULE*) m_currentText->GetParent();
+
+ initDlg();
+
+ m_sdbSizerOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void DialogEditModuleText::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( 0 );
+}
+
+
+void DialogEditModuleText::initDlg( )
+{
+ SetFocus();
+
+ wxString msg;
+
+ if( m_module )
+ {
+ wxString format = m_ModuleInfoText->GetLabel();
+ msg.Printf( format,
+ GetChars( m_module->GetReference() ),
+ GetChars( m_module->GetValue() ),
+ m_module->GetOrientation() / 10.0 );
+ }
+ else
+ {
+ msg.Empty();
+ }
+
+ m_ModuleInfoText->SetLabel( msg );
+
+ // Create a list of not allowed layers.
+ // could be slightly dependent of the type of footprint text.
+ LSET forbiddenLayers( LSET::AllCuMask() );
+ forbiddenLayers.set( Edge_Cuts ).set( Margin ).set( F_Paste ).set( B_Paste ).set( F_Mask ).set( B_Mask );
+
+ switch( m_currentText->GetType() )
+ {
+ case TEXTE_MODULE::TEXT_is_VALUE:
+ m_TextDataTitle->SetLabel( _( "Value:" ) );
+ break;
+
+ case TEXTE_MODULE::TEXT_is_DIVERS:
+ m_TextDataTitle->SetLabel( _( "Text:" ) );
+ break;
+
+ case TEXTE_MODULE::TEXT_is_REFERENCE:
+ m_TextDataTitle->SetLabel( _( "Reference:" ) );
+ break;
+ }
+
+ m_Name->SetValue( m_currentText->GetText() );
+
+ m_Style->SetSelection( m_currentText->IsItalic() ? 1 : 0 );
+
+ AddUnitSymbol( *m_SizeXTitle );
+ PutValueInLocalUnits( *m_TxtSizeCtrlX, m_currentText->GetSize().x );
+
+ AddUnitSymbol( *m_SizeYTitle );
+ PutValueInLocalUnits( *m_TxtSizeCtrlY, m_currentText->GetSize().y );
+
+ AddUnitSymbol( *m_PosXTitle );
+ PutValueInLocalUnits( *m_TxtPosCtrlX, m_currentText->GetPos0().x );
+
+ AddUnitSymbol( *m_PosYTitle );
+ PutValueInLocalUnits( *m_TxtPosCtrlY, m_currentText->GetPos0().y );
+
+ AddUnitSymbol( *m_WidthTitle );
+ PutValueInLocalUnits( *m_TxtWidthCtlr, m_currentText->GetThickness() );
+
+ double text_orient = m_currentText->GetOrientation();
+ NORMALIZE_ANGLE_90( text_orient );
+
+ if( (text_orient != 0) )
+ m_Orient->SetSelection( 1 );
+
+ if( !m_currentText->IsVisible() )
+ m_Show->SetSelection( 1 );
+
+ // Configure the layers list selector
+ if( !m_parent->GetBoard()->IsLayerEnabled( m_currentText->GetLayer() ) )
+ // Footprints are built outside the current board, so items cann be
+ // on a not activated layer, therefore show it if happens.
+ m_LayerSelectionCtrl->ShowNonActivatedLayers( true );
+
+ m_LayerSelectionCtrl->SetLayersHotkeys( false );
+ m_LayerSelectionCtrl->SetLayerSet( forbiddenLayers );
+ m_LayerSelectionCtrl->SetBoardFrame( m_parent );
+ m_LayerSelectionCtrl->Resync();
+
+ if( m_LayerSelectionCtrl->SetLayerSelection( m_currentText->GetLayer() ) < 0 )
+ {
+ wxMessageBox( _( "This item has an illegal layer id.\n"
+ "Now, forced on the front silk screen layer. Please, fix it" ) );
+ m_LayerSelectionCtrl->SetLayerSelection( F_SilkS );
+ }
+}
+
+
+void DialogEditModuleText::OnOkClick( wxCommandEvent& event )
+{
+ wxString msg;
+
+ if( m_module )
+ m_parent->SaveCopyInUndoList( m_module, UR_CHANGED );
+
+#ifndef USE_WX_OVERLAY
+ if( m_dc ) //Erase old text on screen
+ {
+ m_currentText->Draw( m_parent->GetCanvas(), m_dc, GR_XOR,
+ (m_currentText->IsMoving()) ? MoveVector : wxPoint( 0, 0 ) );
+ }
+#endif
+
+ m_currentText->SetText( m_Name->GetValue() );
+ m_currentText->SetItalic( m_Style->GetSelection() == 1 );
+
+ wxPoint tmp;
+
+ msg = m_TxtPosCtrlX->GetValue();
+ tmp.x = ValueFromString( g_UserUnit, msg );
+
+ msg = m_TxtPosCtrlY->GetValue();
+ tmp.y = ValueFromString( g_UserUnit, msg );
+
+ m_currentText->SetPos0( tmp );
+
+ wxSize textSize( wxSize( ValueFromString( g_UserUnit, m_TxtSizeCtrlX->GetValue() ),
+ ValueFromString( g_UserUnit, m_TxtSizeCtrlY->GetValue() ) ) );
+
+ // Test for a reasonable size:
+ if( textSize.x < TEXTS_MIN_SIZE )
+ textSize.x = TEXTS_MIN_SIZE;
+
+ if( textSize.y < TEXTS_MIN_SIZE )
+ textSize.y = TEXTS_MIN_SIZE;
+
+ m_currentText->SetSize( textSize ),
+
+ msg = m_TxtWidthCtlr->GetValue();
+ int width = ValueFromString( g_UserUnit, msg );
+
+ // Test for a reasonable width:
+ if( width <= 1 )
+ width = 1;
+
+ int maxthickness = Clamp_Text_PenSize(width, m_currentText->GetSize() );
+
+ if( width > maxthickness )
+ {
+ DisplayError( NULL,
+ _( "The text thickness is too large for the text size. It will be clamped" ) );
+ width = maxthickness;
+ }
+
+ m_currentText->SetThickness( width );
+
+ m_currentText->SetVisible( m_Show->GetSelection() == 0 );
+
+ int text_orient = (m_Orient->GetSelection() == 0) ? 0 : 900;
+ m_currentText->SetOrientation( text_orient );
+
+ m_currentText->SetDrawCoord();
+
+ LAYER_NUM layer = m_LayerSelectionCtrl->GetLayerSelection();
+ m_currentText->SetLayer( ToLAYER_ID( layer ) );
+ m_currentText->SetMirrored( IsBackLayer( m_currentText->GetLayer() ) );
+
+#ifndef USE_WX_OVERLAY
+ if( m_dc ) // Display new text
+ {
+ m_currentText->Draw( m_parent->GetCanvas(), m_dc, GR_XOR,
+ (m_currentText->IsMoving()) ? MoveVector : wxPoint( 0, 0 ) );
+ }
+#else
+ m_parent->Refresh();
+#endif
+
+ m_parent->OnModify();
+
+ if( m_module )
+ m_module->SetLastEditTime();
+
+ EndModal( 1 );
+}
diff --git a/pcbnew/dialogs/dialog_edit_module_text.h b/pcbnew/dialogs/dialog_edit_module_text.h
new file mode 100644
index 0000000..674481b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_text.h
@@ -0,0 +1,53 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras
+ * Copyright (C) 2013 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2008-2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef DIALOG_EDIT_MODULE_TEXT_H
+#define DIALOG_EDIT_MODULE_TEXT_H
+
+#include <dialog_edit_module_text_base.h>
+
+/*************** **************/
+/* class DialogEditModuleText */
+/*************** **************/
+class DialogEditModuleText : public DialogEditModuleText_base
+{
+private:
+ PCB_BASE_FRAME* m_parent;
+ wxDC* m_dc;
+ MODULE* m_module;
+ TEXTE_MODULE* m_currentText;
+
+public:
+ DialogEditModuleText( PCB_BASE_FRAME* aParent, TEXTE_MODULE* aTextMod, wxDC* aDC );
+ ~DialogEditModuleText() {};
+
+private:
+ void initDlg( );
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+};
+
+#endif /* DIALOG_EDIT_MODULE_TEXT_H */
diff --git a/pcbnew/dialogs/dialog_edit_module_text_base.cpp b/pcbnew/dialogs/dialog_edit_module_text_base.cpp
new file mode 100644
index 0000000..4c8cbee
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_text_base.cpp
@@ -0,0 +1,152 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "class_pcb_layer_box_selector.h"
+
+#include "dialog_edit_module_text_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DialogEditModuleText_base::DialogEditModuleText_base( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_ModuleInfoText = new wxStaticText( this, wxID_ANY, _("Footprint %s (%s) orientation %.1f"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ModuleInfoText->Wrap( -1 );
+ m_ModuleInfoText->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
+
+ bMainSizer->Add( m_ModuleInfoText, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline1, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizer10;
+ bSizer10 = new wxBoxSizer( wxHORIZONTAL );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 7, 2, 0, 0 );
+ fgSizer1->AddGrowableCol( 1 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_TextDataTitle = new wxStaticText( this, wxID_ANY, _("Reference:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextDataTitle->Wrap( -1 );
+ fgSizer1->Add( m_TextDataTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_Name = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer1->Add( m_Name, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_SizeXTitle = new wxStaticText( this, wxID_ANY, _("Width"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SizeXTitle->Wrap( -1 );
+ fgSizer1->Add( m_SizeXTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_TxtSizeCtrlX = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer1->Add( m_TxtSizeCtrlX, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_SizeYTitle = new wxStaticText( this, wxID_ANY, _("Height"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SizeYTitle->Wrap( -1 );
+ fgSizer1->Add( m_SizeYTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_TxtSizeCtrlY = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer1->Add( m_TxtSizeCtrlY, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_WidthTitle = new wxStaticText( this, wxID_ANY, _("Thickness"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_WidthTitle->Wrap( -1 );
+ fgSizer1->Add( m_WidthTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_TxtWidthCtlr = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer1->Add( m_TxtWidthCtlr, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_PosXTitle = new wxStaticText( this, wxID_ANY, _("Offset X"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PosXTitle->Wrap( -1 );
+ fgSizer1->Add( m_PosXTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_TxtPosCtrlX = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer1->Add( m_TxtPosCtrlX, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_PosYTitle = new wxStaticText( this, wxID_ANY, _("Offset Y"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PosYTitle->Wrap( -1 );
+ fgSizer1->Add( m_PosYTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_TxtPosCtrlY = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer1->Add( m_TxtPosCtrlY, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_LayerLabel = new wxStaticText( this, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_LayerLabel->Wrap( -1 );
+ fgSizer1->Add( m_LayerLabel, 0, wxALL, 5 );
+
+ m_LayerSelectionCtrl = new PCB_LAYER_BOX_SELECTOR( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ fgSizer1->Add( m_LayerSelectionCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ bSizer10->Add( fgSizer1, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizerUpper->Add( bSizer10, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerOpts;
+ bSizerOpts = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_StyleChoices[] = { _("Normal"), _("Italic") };
+ int m_StyleNChoices = sizeof( m_StyleChoices ) / sizeof( wxString );
+ m_Style = new wxRadioBox( this, wxID_ANY, _("Style"), wxDefaultPosition, wxDefaultSize, m_StyleNChoices, m_StyleChoices, 1, wxRA_SPECIFY_COLS );
+ m_Style->SetSelection( 0 );
+ bSizerOpts->Add( m_Style, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ wxString m_OrientChoices[] = { _("Horizontal"), _("Vertical") };
+ int m_OrientNChoices = sizeof( m_OrientChoices ) / sizeof( wxString );
+ m_Orient = new wxRadioBox( this, wxID_ANY, _("Orientation"), wxDefaultPosition, wxDefaultSize, m_OrientNChoices, m_OrientChoices, 1, wxRA_SPECIFY_COLS );
+ m_Orient->SetSelection( 0 );
+ bSizerOpts->Add( m_Orient, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ wxString m_ShowChoices[] = { _("Visible"), _("Invisible") };
+ int m_ShowNChoices = sizeof( m_ShowChoices ) / sizeof( wxString );
+ m_Show = new wxRadioBox( this, wxID_ANY, _("Display"), wxDefaultPosition, wxDefaultSize, m_ShowNChoices, m_ShowChoices, 1, wxRA_SPECIFY_COLS );
+ m_Show->SetSelection( 0 );
+ bSizerOpts->Add( m_Show, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ bSizerUpper->Add( bSizerOpts, 0, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bSizerUpper, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 );
+
+
+ bMainSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bMainSizer->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ // Connect Events
+ m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogEditModuleText_base::OnOkClick ), NULL, this );
+}
+
+DialogEditModuleText_base::~DialogEditModuleText_base()
+{
+ // Disconnect Events
+ m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogEditModuleText_base::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_edit_module_text_base.fbp b/pcbnew/dialogs/dialog_edit_module_text_base.fbp
new file mode 100644
index 0000000..5a2866d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_text_base.fbp
@@ -0,0 +1,1919 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_edit_module_text_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DialogEditModuleText_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DialogEditModuleText_base</property>
+ <property name="pos"></property>
+ <property name="size">489,328</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Footprint Text Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_HORIZONTAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprint %s (%s) orientation %.1f</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ModuleInfoText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer10</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">7</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Reference:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextDataTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Width</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SizeXTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TxtSizeCtrlX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Height</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SizeYTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TxtSizeCtrlY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Thickness</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_WidthTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TxtWidthCtlr</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Offset X</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PosXTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TxtPosCtrlX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Offset Y</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PosYTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TxtPosCtrlY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layer:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LayerLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxBitmapComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LayerSelectionCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">PCB_LAYER_BOX_SELECTOR; class_pcb_layer_box_selector.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerOpts</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Normal&quot; &quot;Italic&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Style</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Style</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Horizontal&quot; &quot;Vertical&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Orientation</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Orient</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Visible&quot; &quot;Invisible&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Display</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Show</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_edit_module_text_base.h b/pcbnew/dialogs/dialog_edit_module_text_base.h
new file mode 100644
index 0000000..c072c55
--- /dev/null
+++ b/pcbnew/dialogs/dialog_edit_module_text_base.h
@@ -0,0 +1,77 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_EDIT_MODULE_TEXT_BASE_H__
+#define __DIALOG_EDIT_MODULE_TEXT_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class PCB_LAYER_BOX_SELECTOR;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/statline.h>
+#include <wx/textctrl.h>
+#include <wx/bmpcbox.h>
+#include <wx/sizer.h>
+#include <wx/radiobox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DialogEditModuleText_base
+///////////////////////////////////////////////////////////////////////////////
+class DialogEditModuleText_base : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_ModuleInfoText;
+ wxStaticLine* m_staticline1;
+ wxStaticText* m_TextDataTitle;
+ wxTextCtrl* m_Name;
+ wxStaticText* m_SizeXTitle;
+ wxTextCtrl* m_TxtSizeCtrlX;
+ wxStaticText* m_SizeYTitle;
+ wxTextCtrl* m_TxtSizeCtrlY;
+ wxStaticText* m_WidthTitle;
+ wxTextCtrl* m_TxtWidthCtlr;
+ wxStaticText* m_PosXTitle;
+ wxTextCtrl* m_TxtPosCtrlX;
+ wxStaticText* m_PosYTitle;
+ wxTextCtrl* m_TxtPosCtrlY;
+ wxStaticText* m_LayerLabel;
+ PCB_LAYER_BOX_SELECTOR* m_LayerSelectionCtrl;
+ wxRadioBox* m_Style;
+ wxRadioBox* m_Orient;
+ wxRadioBox* m_Show;
+ wxStaticLine* m_staticline2;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DialogEditModuleText_base( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Footprint Text Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 489,328 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DialogEditModuleText_base();
+
+};
+
+#endif //__DIALOG_EDIT_MODULE_TEXT_BASE_H__
diff --git a/pcbnew/dialogs/dialog_enum_pads.cpp b/pcbnew/dialogs/dialog_enum_pads.cpp
new file mode 100644
index 0000000..5238fda
--- /dev/null
+++ b/pcbnew/dialogs/dialog_enum_pads.cpp
@@ -0,0 +1,46 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "dialog_enum_pads.h"
+
+DIALOG_ENUM_PADS::DIALOG_ENUM_PADS( wxWindow* aParent ) :
+ DIALOG_ENUM_PADS_BASE( aParent )
+{
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+int DIALOG_ENUM_PADS::GetStartNumber() const
+{
+ return m_padStartNum->GetValue();
+}
+
+
+wxString DIALOG_ENUM_PADS::GetPrefix() const
+{
+ return m_padPrefix->GetValue();
+}
diff --git a/pcbnew/dialogs/dialog_enum_pads.h b/pcbnew/dialogs/dialog_enum_pads.h
new file mode 100644
index 0000000..188c732
--- /dev/null
+++ b/pcbnew/dialogs/dialog_enum_pads.h
@@ -0,0 +1,49 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __dialog_enum_pads__
+#define __dialog_enum_pads__
+
+/**
+@file
+Subclass of DIALOG_ENUM_PADS_BASE, which is generated by wxFormBuilder.
+*/
+
+#include "dialog_enum_pads_base.h"
+
+/** Implementing DIALOG_ENUM_PADS_BASE */
+class DIALOG_ENUM_PADS : public DIALOG_ENUM_PADS_BASE
+{
+public:
+ /** Constructor */
+ DIALOG_ENUM_PADS( wxWindow* parent );
+
+ ///> Returns the starting number that is going to be used for the first enumerated pad.
+ int GetStartNumber() const;
+
+ ///> Returns common prefix for all enumerated pads.
+ wxString GetPrefix() const;
+};
+
+#endif // __dialog_enum_pads__
diff --git a/pcbnew/dialogs/dialog_enum_pads_base.cpp b/pcbnew/dialogs/dialog_enum_pads_base.cpp
new file mode 100644
index 0000000..9d651e2
--- /dev/null
+++ b/pcbnew/dialogs/dialog_enum_pads_base.cpp
@@ -0,0 +1,71 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_enum_pads_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_ENUM_PADS_BASE::DIALOG_ENUM_PADS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_lblInfo = new wxStaticText( this, wxID_ANY, _("Pad names are restricted to 4 characters (including number)."), wxDefaultPosition, wxDefaultSize, 0 );
+ m_lblInfo->Wrap( -1 );
+ bMainSizer->Add( m_lblInfo, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
+
+
+ bMainSizer->Add( 0, 0, 0, wxTOP|wxBOTTOM, 5 );
+
+ wxFlexGridSizer* fgSizer;
+ fgSizer = new wxFlexGridSizer( 0, 2, 0, 0 );
+ fgSizer->AddGrowableCol( 1 );
+ fgSizer->SetFlexibleDirection( wxBOTH );
+ fgSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_lblPadPrefix = new wxStaticText( this, wxID_ANY, _("Pad name prefix:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_lblPadPrefix->Wrap( -1 );
+ fgSizer->Add( m_lblPadPrefix, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_padPrefix = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_padPrefix->SetMaxLength( 4 );
+ fgSizer->Add( m_padPrefix, 0, wxALL|wxEXPAND, 5 );
+
+ m_lblPadStartNum = new wxStaticText( this, wxID_ANY, _("First pad number:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_lblPadStartNum->Wrap( -1 );
+ fgSizer->Add( m_lblPadStartNum, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_padStartNum = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 999, 1 );
+ fgSizer->Add( m_padStartNum, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( fgSizer, 1, wxEXPAND|wxALL, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_stdButtons = new wxStdDialogButtonSizer();
+ m_stdButtonsOK = new wxButton( this, wxID_OK );
+ m_stdButtons->AddButton( m_stdButtonsOK );
+ m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_stdButtons->AddButton( m_stdButtonsCancel );
+ m_stdButtons->Realize();
+
+ bMainSizer->Add( m_stdButtons, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_ENUM_PADS_BASE::~DIALOG_ENUM_PADS_BASE()
+{
+}
diff --git a/pcbnew/dialogs/dialog_enum_pads_base.fbp b/pcbnew/dialogs/dialog_enum_pads_base.fbp
new file mode 100644
index 0000000..9816e70
--- /dev/null
+++ b/pcbnew/dialogs/dialog_enum_pads_base.fbp
@@ -0,0 +1,662 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_enum_pads_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_ENUM_PADS_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_ENUM_PADS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">340,187</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Pad enumeration settings</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_HORIZONTAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad names are restricted to 4 characters (including number).</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_lblInfo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad name prefix:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_lblPadPrefix</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">4</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_padPrefix</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">First pad number:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_lblPadStartNum</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">1</property>
+ <property name="max">999</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_padStartNum</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_stdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_enum_pads_base.h b/pcbnew/dialogs/dialog_enum_pads_base.h
new file mode 100644
index 0000000..5600a66
--- /dev/null
+++ b/pcbnew/dialogs/dialog_enum_pads_base.h
@@ -0,0 +1,58 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_ENUM_PADS_BASE_H__
+#define __DIALOG_ENUM_PADS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/spinctrl.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_ENUM_PADS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_ENUM_PADS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_lblInfo;
+ wxStaticText* m_lblPadPrefix;
+ wxTextCtrl* m_padPrefix;
+ wxStaticText* m_lblPadStartNum;
+ wxSpinCtrl* m_padStartNum;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_stdButtons;
+ wxButton* m_stdButtonsOK;
+ wxButton* m_stdButtonsCancel;
+
+ public:
+
+ DIALOG_ENUM_PADS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Pad enumeration settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 340,187 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_ENUM_PADS_BASE();
+
+};
+
+#endif //__DIALOG_ENUM_PADS_BASE_H__
diff --git a/pcbnew/dialogs/dialog_exchange_modules_base.cpp b/pcbnew/dialogs/dialog_exchange_modules_base.cpp
new file mode 100644
index 0000000..c20ff83
--- /dev/null
+++ b/pcbnew/dialogs/dialog_exchange_modules_base.cpp
@@ -0,0 +1,136 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_exchange_modules_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_EXCHANGE_MODULE_BASE::DIALOG_EXCHANGE_MODULE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bLeftSizer;
+ bLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextCmpVal = new wxStaticText( this, wxID_ANY, _("Component value"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextCmpVal->Wrap( -1 );
+ bLeftSizer->Add( m_staticTextCmpVal, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_CmpValue = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ m_CmpValue->SetMaxLength( 0 );
+ bLeftSizer->Add( m_CmpValue, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ m_staticTexCmpRef = new wxStaticText( this, wxID_ANY, _("Component reference"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTexCmpRef->Wrap( -1 );
+ bLeftSizer->Add( m_staticTexCmpRef, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_CmpReference = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ bLeftSizer->Add( m_CmpReference, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bUpperSizer->Add( bLeftSizer, 1, wxALIGN_CENTER_VERTICAL, 5 );
+
+ wxBoxSizer* bMiddleSizer;
+ bMiddleSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_SelectionChoices[] = { _("Change footprint"), _("Change footprints"), _("Change footprints having same value"), _("Update all footprints of the board") };
+ int m_SelectionNChoices = sizeof( m_SelectionChoices ) / sizeof( wxString );
+ m_Selection = new wxRadioBox( this, ID_SELECTION_CLICKED, _("Options"), wxDefaultPosition, wxDefaultSize, m_SelectionNChoices, m_SelectionChoices, 1, wxRA_SPECIFY_COLS );
+ m_Selection->SetSelection( 1 );
+ bMiddleSizer->Add( m_Selection, 0, wxALL, 5 );
+
+
+ bUpperSizer->Add( bMiddleSizer, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ wxBoxSizer* bRightSizer;
+ bRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonCmpList = new wxButton( this, wxID_ANY, _("Export Footprint Association File"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonCmpList, 0, wxALL|wxEXPAND, 5 );
+
+ m_Browsebutton = new wxButton( this, wxID_ANY, _("List Footprints"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_Browsebutton, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonFPViewer = new wxButton( this, wxID_ANY, _("View Footprints"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonFPViewer, 0, wxALL|wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( bRightSizer, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bMainSizer->Add( bUpperSizer, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticTextCurrFPID = new wxStaticText( this, wxID_ANY, _("Current footprint name (FPID)"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextCurrFPID->Wrap( -1 );
+ bMainSizer->Add( m_staticTextCurrFPID, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_CurrentFootprintFPID = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ m_CurrentFootprintFPID->SetMaxLength( 0 );
+ bMainSizer->Add( m_CurrentFootprintFPID, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticTextNewFPID = new wxStaticText( this, wxID_ANY, _("New footprint name (FPID)"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextNewFPID->Wrap( -1 );
+ bMainSizer->Add( m_staticTextNewFPID, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_NewFootprintFPID = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_NewFootprintFPID->SetMaxLength( 0 );
+ bMainSizer->Add( m_NewFootprintFPID, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_staticTextMsg = new wxStaticText( this, wxID_ANY, _("Messages:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextMsg->Wrap( -1 );
+ bMainSizer->Add( m_staticTextMsg, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_WinMessages = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY );
+ m_WinMessages->SetMinSize( wxSize( -1,150 ) );
+
+ bMainSizer->Add( m_WinMessages, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ wxBoxSizer* bSizerButts;
+ bSizerButts = new wxBoxSizer( wxHORIZONTAL );
+
+ m_Applybutton = new wxButton( this, wxID_OK, _("Apply"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButts->Add( m_Applybutton, 0, wxEXPAND|wxALL, 5 );
+
+ m_Quitbutton = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButts->Add( m_Quitbutton, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bSizerButts, 0, wxALIGN_RIGHT, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ // Connect Events
+ m_Selection->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_EXCHANGE_MODULE_BASE::OnSelectionClicked ), NULL, this );
+ m_buttonCmpList->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXCHANGE_MODULE_BASE::RebuildCmpList ), NULL, this );
+ m_Browsebutton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXCHANGE_MODULE_BASE::BrowseAndSelectFootprint ), NULL, this );
+ m_buttonFPViewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXCHANGE_MODULE_BASE::ViewAndSelectFootprint ), NULL, this );
+ m_Applybutton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXCHANGE_MODULE_BASE::OnOkClick ), NULL, this );
+ m_Quitbutton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXCHANGE_MODULE_BASE::OnQuit ), NULL, this );
+}
+
+DIALOG_EXCHANGE_MODULE_BASE::~DIALOG_EXCHANGE_MODULE_BASE()
+{
+ // Disconnect Events
+ m_Selection->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_EXCHANGE_MODULE_BASE::OnSelectionClicked ), NULL, this );
+ m_buttonCmpList->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXCHANGE_MODULE_BASE::RebuildCmpList ), NULL, this );
+ m_Browsebutton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXCHANGE_MODULE_BASE::BrowseAndSelectFootprint ), NULL, this );
+ m_buttonFPViewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXCHANGE_MODULE_BASE::ViewAndSelectFootprint ), NULL, this );
+ m_Applybutton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXCHANGE_MODULE_BASE::OnOkClick ), NULL, this );
+ m_Quitbutton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXCHANGE_MODULE_BASE::OnQuit ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_exchange_modules_base.fbp b/pcbnew/dialogs/dialog_exchange_modules_base.fbp
new file mode 100644
index 0000000..a624bd5
--- /dev/null
+++ b/pcbnew/dialogs/dialog_exchange_modules_base.fbp
@@ -0,0 +1,1635 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_exchange_modules_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_exchange_modules_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_EXCHANGE_MODULE_BASE</property>
+ <property name="pos"></property>
+ <property name="size">555,449</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Change Footprint</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Component value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextCmpVal</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CmpValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Component reference</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTexCmpRef</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CmpReference</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMiddleSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Change footprint&quot; &quot;Change footprints&quot; &quot;Change footprints having same value&quot; &quot;Update all footprints of the board&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SELECTION_CLICKED</property>
+ <property name="label">Options</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Selection</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox">OnSelectionClicked</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Export Footprint Association File</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonCmpList</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">RebuildCmpList</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">List Footprints</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Browsebutton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">BrowseAndSelectFootprint</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">View Footprints</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonFPViewer</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">ViewAndSelectFootprint</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Current footprint name (FPID)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextCurrFPID</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CurrentFootprintFPID</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">New footprint name (FPID)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextNewFPID</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NewFootprintFPID</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Messages:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextMsg</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,150</property>
+ <property name="moveable">1</property>
+ <property name="name">m_WinMessages</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_MULTILINE|wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerButts</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_OK</property>
+ <property name="label">Apply</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Applybutton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnOkClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Quitbutton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnQuit</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_exchange_modules_base.h b/pcbnew/dialogs/dialog_exchange_modules_base.h
new file mode 100644
index 0000000..ee1075e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_exchange_modules_base.h
@@ -0,0 +1,76 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_EXCHANGE_MODULES_BASE_H__
+#define __DIALOG_EXCHANGE_MODULES_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/radiobox.h>
+#include <wx/button.h>
+#include <wx/statline.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_SELECTION_CLICKED 1000
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_EXCHANGE_MODULE_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_EXCHANGE_MODULE_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticTextCmpVal;
+ wxTextCtrl* m_CmpValue;
+ wxStaticText* m_staticTexCmpRef;
+ wxTextCtrl* m_CmpReference;
+ wxRadioBox* m_Selection;
+ wxButton* m_buttonCmpList;
+ wxButton* m_Browsebutton;
+ wxButton* m_buttonFPViewer;
+ wxStaticText* m_staticTextCurrFPID;
+ wxTextCtrl* m_CurrentFootprintFPID;
+ wxStaticText* m_staticTextNewFPID;
+ wxTextCtrl* m_NewFootprintFPID;
+ wxStaticText* m_staticTextMsg;
+ wxTextCtrl* m_WinMessages;
+ wxStaticLine* m_staticline1;
+ wxButton* m_Applybutton;
+ wxButton* m_Quitbutton;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnSelectionClicked( wxCommandEvent& event ) { event.Skip(); }
+ virtual void RebuildCmpList( wxCommandEvent& event ) { event.Skip(); }
+ virtual void BrowseAndSelectFootprint( wxCommandEvent& event ) { event.Skip(); }
+ virtual void ViewAndSelectFootprint( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnQuit( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_EXCHANGE_MODULE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Change Footprint"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 555,449 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_EXCHANGE_MODULE_BASE();
+
+};
+
+#endif //__DIALOG_EXCHANGE_MODULES_BASE_H__
diff --git a/pcbnew/dialogs/dialog_export_idf.cpp b/pcbnew/dialogs/dialog_export_idf.cpp
new file mode 100644
index 0000000..ed405a6
--- /dev/null
+++ b/pcbnew/dialogs/dialog_export_idf.cpp
@@ -0,0 +1,231 @@
+/**
+ * @file dialog_export_idf.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013-2015 Cirilo Bernardo
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wxPcbStruct.h>
+#include <kiface_i.h>
+#include <pcbnew.h>
+#include <class_board.h>
+#include <convert_from_iu.h>
+
+// IDF export header generated by wxFormBuilder
+#include <dialog_export_idf_base.h>
+
+#define OPTKEY_IDF_THOU wxT( "IDFExportThou" )
+#define OPTKEY_IDF_REF_AUTOADJ wxT( "IDFRefAutoAdj" )
+#define OPTKEY_IDF_REF_UNITS wxT( "IDFRefUnits" )
+#define OPTKEY_IDF_REF_X wxT( "IDFRefX" )
+#define OPTKEY_IDF_REF_Y wxT( "IDFRefY" )
+
+
+/**
+ * Function Export_IDF3
+ * Creates an IDF3 compliant BOARD (*.emn) and LIBRARY (*.emp) file.
+ *
+ * @param aPcb = a pointer to the board to be exported to IDF
+ * @param aFullFileName = the full filename of the export file
+ * @param aUseThou = set to true if the desired IDF unit is thou (mil)
+ * @param aXRef = the board Reference Point in mm, X value
+ * @param aYRef = the board Reference Point in mm, Y value
+ * @return true if OK
+ */
+bool Export_IDF3( BOARD *aPcb, const wxString & aFullFileName, bool aUseThou,
+ double aXRef, double aYRef );
+
+
+class DIALOG_EXPORT_IDF3: public DIALOG_EXPORT_IDF3_BASE
+{
+private:
+ PCB_EDIT_FRAME* m_parent;
+ wxConfigBase* m_config;
+ bool m_idfThouOpt; // remember last preference for units in THOU
+ bool m_AutoAdjust; // remember last Reference Point AutoAdjust setting
+ int m_RefUnits; // remember last units for Reference Point
+ double m_XRef; // remember last X Reference Point
+ double m_YRef; // remember last Y Reference Point
+
+public:
+ DIALOG_EXPORT_IDF3( PCB_EDIT_FRAME* parent ) :
+ DIALOG_EXPORT_IDF3_BASE( parent )
+ {
+ m_parent = parent;
+ m_config = Kiface().KifaceSettings();
+ SetFocus();
+ m_idfThouOpt = false;
+ m_config->Read( OPTKEY_IDF_THOU, &m_idfThouOpt );
+ m_rbUnitSelection->SetSelection( m_idfThouOpt ? 1 : 0 );
+ m_config->Read( OPTKEY_IDF_REF_AUTOADJ, &m_AutoAdjust, false );
+ m_config->Read( OPTKEY_IDF_REF_UNITS, &m_RefUnits, 0 );
+ m_config->Read( OPTKEY_IDF_REF_X, &m_XRef, 0.0 );
+ m_config->Read( OPTKEY_IDF_REF_Y, &m_YRef, 0.0 );
+
+ m_cbAutoAdjustOffset->SetValue( m_AutoAdjust );
+ m_cbAutoAdjustOffset->Bind( wxEVT_CHECKBOX, &DIALOG_EXPORT_IDF3::OnAutoAdjustOffset, this );
+
+ m_IDF_RefUnitChoice->SetSelection( m_RefUnits );
+ wxString tmpStr;
+ tmpStr << m_XRef;
+ m_IDF_Xref->SetValue( tmpStr );
+ tmpStr = wxT( "" );
+ tmpStr << m_YRef;
+ m_IDF_Yref->SetValue( tmpStr );
+
+ if( m_AutoAdjust )
+ {
+ m_IDF_RefUnitChoice->Enable( false );
+ m_IDF_Xref->Enable( false );
+ m_IDF_Yref->Enable( false );
+ }
+ else
+ {
+ m_IDF_RefUnitChoice->Enable( true );
+ m_IDF_Xref->Enable( true );
+ m_IDF_Yref->Enable( true );
+ }
+
+ m_sdbSizerOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+ }
+
+ ~DIALOG_EXPORT_IDF3()
+ {
+ m_idfThouOpt = m_rbUnitSelection->GetSelection() == 1;
+ m_config->Write( OPTKEY_IDF_THOU, m_idfThouOpt );
+ m_config->Write( OPTKEY_IDF_REF_AUTOADJ, GetAutoAdjustOffset() );
+ m_config->Write( OPTKEY_IDF_REF_UNITS, m_IDF_RefUnitChoice->GetSelection() );
+ m_config->Write( OPTKEY_IDF_REF_X, m_IDF_Xref->GetValue() );
+ m_config->Write( OPTKEY_IDF_REF_Y, m_IDF_Yref->GetValue() );
+ }
+
+ bool GetThouOption()
+ {
+ return m_rbUnitSelection->GetSelection() == 1;
+ }
+
+ wxFilePickerCtrl* FilePicker()
+ {
+ return m_filePickerIDF;
+ }
+
+ int GetRefUnitsChoice()
+ {
+ return m_IDF_RefUnitChoice->GetSelection();
+ }
+
+ double GetXRef()
+ {
+ return DoubleValueFromString( UNSCALED_UNITS, m_IDF_Xref->GetValue() );
+ }
+
+ double GetYRef()
+ {
+ return DoubleValueFromString( UNSCALED_UNITS, m_IDF_Yref->GetValue() );
+ }
+
+ bool GetAutoAdjustOffset()
+ {
+ return m_cbAutoAdjustOffset->GetValue();
+ }
+
+ void OnAutoAdjustOffset( wxCommandEvent& event )
+ {
+ if( GetAutoAdjustOffset() )
+ {
+ m_IDF_RefUnitChoice->Enable( false );
+ m_IDF_Xref->Enable( false );
+ m_IDF_Yref->Enable( false );
+ }
+ else
+ {
+ m_IDF_RefUnitChoice->Enable( true );
+ m_IDF_Xref->Enable( true );
+ m_IDF_Yref->Enable( true );
+ }
+
+ event.Skip();
+ }
+
+};
+
+
+/**
+ * Function OnExportIDF3
+ * will export the current BOARD to IDF board and lib files.
+ */
+void PCB_EDIT_FRAME::ExportToIDF3( wxCommandEvent& event )
+{
+ wxFileName fn;
+
+ // Build default file name
+ fn = GetBoard()->GetFileName();
+ fn.SetExt( wxT( "emn" ) );
+
+ DIALOG_EXPORT_IDF3 dlg( this );
+ dlg.FilePicker()->SetPath( fn.GetFullPath() );
+
+ if ( dlg.ShowModal() != wxID_OK )
+ return;
+
+ bool thou = dlg.GetThouOption();
+ double aXRef;
+ double aYRef;
+
+ if( dlg.GetAutoAdjustOffset() )
+ {
+ EDA_RECT bbox = GetBoard()->ComputeBoundingBox( true );
+
+ aXRef = bbox.Centre().x * MM_PER_IU;
+ aYRef = bbox.Centre().y * MM_PER_IU;
+ }
+ else
+ {
+ aXRef = dlg.GetXRef();
+ aYRef = dlg.GetYRef();
+
+ if( dlg.GetRefUnitsChoice() == 1 )
+ {
+ // selected reference unit is in inches
+ aXRef *= 25.4;
+ aYRef *= 25.4;
+ }
+
+ }
+
+ wxBusyCursor dummy;
+
+ wxString fullFilename = dlg.FilePicker()->GetPath();
+
+ if( !Export_IDF3( GetBoard(), fullFilename, thou, aXRef, aYRef ) )
+ {
+ wxString msg = _( "Unable to create " ) + fullFilename;
+ wxMessageBox( msg );
+ return;
+ }
+}
diff --git a/pcbnew/dialogs/dialog_export_idf_base.cpp b/pcbnew/dialogs/dialog_export_idf_base.cpp
new file mode 100644
index 0000000..fbc8132
--- /dev/null
+++ b/pcbnew/dialogs/dialog_export_idf_base.cpp
@@ -0,0 +1,134 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_export_idf_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_EXPORT_IDF3_BASE::DIALOG_EXPORT_IDF3_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerIDFFile;
+ bSizerIDFFile = new wxBoxSizer( wxVERTICAL );
+
+ m_txtBrdFile = new wxStaticText( this, wxID_ANY, _("File name:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_txtBrdFile->Wrap( -1 );
+ bSizerIDFFile->Add( m_txtBrdFile, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_filePickerIDF = new wxFilePickerCtrl( this, wxID_ANY, wxEmptyString, _("Select an IDF export filename"), wxT("*.emn"), wxDefaultPosition, wxSize( 450,-1 ), wxFLP_OVERWRITE_PROMPT|wxFLP_SAVE|wxFLP_USE_TEXTCTRL );
+ bSizerIDFFile->Add( m_filePickerIDF, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizer2;
+ bSizer2 = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizer3;
+ bSizer3 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText2 = new wxStaticText( this, wxID_ANY, _("Grid Reference Point:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText2->Wrap( -1 );
+ bSizer3->Add( m_staticText2, 0, wxALL, 5 );
+
+ m_cbAutoAdjustOffset = new wxCheckBox( this, wxID_ANY, _("Adjust automatically"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE );
+ bSizer3->Add( m_cbAutoAdjustOffset, 0, wxALL, 5 );
+
+ wxBoxSizer* bSizer6;
+ bSizer6 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_staticText5 = new wxStaticText( this, wxID_ANY, _("Units:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText5->Wrap( -1 );
+ bSizer6->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxString m_IDF_RefUnitChoiceChoices[] = { _("mm"), _("inch") };
+ int m_IDF_RefUnitChoiceNChoices = sizeof( m_IDF_RefUnitChoiceChoices ) / sizeof( wxString );
+ m_IDF_RefUnitChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_IDF_RefUnitChoiceNChoices, m_IDF_RefUnitChoiceChoices, 0 );
+ m_IDF_RefUnitChoice->SetSelection( 0 );
+ bSizer6->Add( m_IDF_RefUnitChoice, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizer3->Add( bSizer6, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_staticText3 = new wxStaticText( this, wxID_ANY, _("X Position:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ bSizer4->Add( m_staticText3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_IDF_Xref = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ #ifdef __WXGTK__
+ if ( !m_IDF_Xref->HasFlag( wxTE_MULTILINE ) )
+ {
+ m_IDF_Xref->SetMaxLength( 8 );
+ }
+ #else
+ m_IDF_Xref->SetMaxLength( 8 );
+ #endif
+ bSizer4->Add( m_IDF_Xref, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizer3->Add( bSizer4, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer5;
+ bSizer5 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_staticText4 = new wxStaticText( this, wxID_ANY, _("Y Position:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText4->Wrap( -1 );
+ bSizer5->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_IDF_Yref = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ #ifdef __WXGTK__
+ if ( !m_IDF_Yref->HasFlag( wxTE_MULTILINE ) )
+ {
+ m_IDF_Yref->SetMaxLength( 8 );
+ }
+ #else
+ m_IDF_Yref->SetMaxLength( 8 );
+ #endif
+ bSizer5->Add( m_IDF_Yref, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizer3->Add( bSizer5, 1, wxEXPAND, 5 );
+
+
+ bSizer2->Add( bSizer3, 1, wxEXPAND|wxLEFT, 5 );
+
+ wxString m_rbUnitSelectionChoices[] = { _("Millimeters"), _("Mils") };
+ int m_rbUnitSelectionNChoices = sizeof( m_rbUnitSelectionChoices ) / sizeof( wxString );
+ m_rbUnitSelection = new wxRadioBox( this, wxID_ANY, _("Output Units:"), wxDefaultPosition, wxDefaultSize, m_rbUnitSelectionNChoices, m_rbUnitSelectionChoices, 1, wxRA_SPECIFY_COLS );
+ m_rbUnitSelection->SetSelection( 0 );
+ bSizer2->Add( m_rbUnitSelection, 0, wxALL, 5 );
+
+
+ bSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ bSizerIDFFile->Add( bSizer2, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerIDFFile->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bSizerIDFFile->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ this->SetSizer( bSizerIDFFile );
+ this->Layout();
+ bSizerIDFFile->Fit( this );
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_EXPORT_IDF3_BASE::~DIALOG_EXPORT_IDF3_BASE()
+{
+}
diff --git a/pcbnew/dialogs/dialog_export_idf_base.fbp b/pcbnew/dialogs/dialog_export_idf_base.fbp
new file mode 100644
index 0000000..1dee900
--- /dev/null
+++ b/pcbnew/dialogs/dialog_export_idf_base.fbp
@@ -0,0 +1,1223 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_export_idf_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_export_idf3_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_EXPORT_IDF3_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Export IDFv3</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">bSizerIDFFile</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">File name:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_txtBrdFile</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxFilePickerCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="message">Select an IDF export filename</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_filePickerIDF</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">450,-1</property>
+ <property name="style">wxFLP_OVERWRITE_PROMPT|wxFLP_SAVE|wxFLP_USE_TEXTCTRL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="wildcard">*.emn</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnFileChanged"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer2</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer3</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Grid Reference Point:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Adjust automatically</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbAutoAdjustOffset</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxCHK_2STATE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer6</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Units:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;mm&quot; &quot;inch&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_IDF_RefUnitChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer4</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">X Position:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">8</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_IDF_Xref</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NUMERIC</property>
+ <property name="validator_type">wxTextValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer5</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Y Position:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">8</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_IDF_Yref</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NUMERIC</property>
+ <property name="validator_type">wxTextValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Millimeters&quot; &quot;Mils&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Output Units:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbUnitSelection</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_export_idf_base.h b/pcbnew/dialogs/dialog_export_idf_base.h
new file mode 100644
index 0000000..d440143
--- /dev/null
+++ b/pcbnew/dialogs/dialog_export_idf_base.h
@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_EXPORT_IDF_BASE_H__
+#define __DIALOG_EXPORT_IDF_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/filepicker.h>
+#include <wx/checkbox.h>
+#include <wx/choice.h>
+#include <wx/sizer.h>
+#include <wx/textctrl.h>
+#include <wx/valtext.h>
+#include <wx/radiobox.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_EXPORT_IDF3_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_EXPORT_IDF3_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_txtBrdFile;
+ wxFilePickerCtrl* m_filePickerIDF;
+ wxStaticText* m_staticText2;
+ wxCheckBox* m_cbAutoAdjustOffset;
+ wxStaticText* m_staticText5;
+ wxChoice* m_IDF_RefUnitChoice;
+ wxStaticText* m_staticText3;
+ wxTextCtrl* m_IDF_Xref;
+ wxStaticText* m_staticText4;
+ wxTextCtrl* m_IDF_Yref;
+ wxRadioBox* m_rbUnitSelection;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ public:
+
+ DIALOG_EXPORT_IDF3_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Export IDFv3"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_EXPORT_IDF3_BASE();
+
+};
+
+#endif //__DIALOG_EXPORT_IDF_BASE_H__
diff --git a/pcbnew/dialogs/dialog_export_vrml.cpp b/pcbnew/dialogs/dialog_export_vrml.cpp
new file mode 100644
index 0000000..c2165b9
--- /dev/null
+++ b/pcbnew/dialogs/dialog_export_vrml.cpp
@@ -0,0 +1,250 @@
+/**
+ * @file dialog_export_vrml.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009-2013 Lorenzo Mercantonio
+ * Copyright (C) 2013 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include <fctsys.h>
+#include <wxPcbStruct.h>
+#include <kiface_i.h>
+#include <pcbnew.h>
+#include <class_board.h>
+
+
+/* the dialog to create VRML files, derived from DIALOG_EXPORT_3DFILE_BASE,
+ * created by wxFormBuilder
+ */
+#include <dialog_export_vrml_base.h> // the wxFormBuilder header file
+
+#define OPTKEY_OUTPUT_UNIT wxT( "VrmlExportUnit" )
+#define OPTKEY_3DFILES_OPT wxT( "VrmlExportCopyFiles" )
+#define OPTKEY_USE_RELATIVE_PATHS wxT( "VrmlUseRelativePaths" )
+#define OPTKEY_USE_PLAIN_PCB wxT( "VrmlUsePlainPCB" )
+#define OPTKEY_VRML_REF_UNITS wxT( "VrmlRefUnits" )
+#define OPTKEY_VRML_REF_X wxT( "VrmlRefX" )
+#define OPTKEY_VRML_REF_Y wxT( "VrmlRefY" )
+
+
+class DIALOG_EXPORT_3DFILE : public DIALOG_EXPORT_3DFILE_BASE
+{
+private:
+ PCB_EDIT_FRAME* m_parent;
+ wxConfigBase* m_config;
+ int m_unitsOpt; // Remember last units option
+ bool m_copy3DFilesOpt; // Remember last copy model files option
+ bool m_useRelativePathsOpt; // Remember last use absolute paths option
+ bool m_usePlainPCBOpt; // Remember last Plain Board option
+ int m_RefUnits; // Remember last units for Reference Point
+ double m_XRef; // Remember last X Reference Point
+ double m_YRef; // Remember last Y Reference Point
+
+public:
+ DIALOG_EXPORT_3DFILE( PCB_EDIT_FRAME* parent ) :
+ DIALOG_EXPORT_3DFILE_BASE( parent )
+ {
+ m_parent = parent;
+ m_config = Kiface().KifaceSettings();
+ m_filePicker->SetFocus();
+ m_config->Read( OPTKEY_OUTPUT_UNIT, &m_unitsOpt, 1 );
+ m_config->Read( OPTKEY_3DFILES_OPT, &m_copy3DFilesOpt, false );
+ m_config->Read( OPTKEY_USE_RELATIVE_PATHS, &m_useRelativePathsOpt, false );
+ m_config->Read( OPTKEY_USE_PLAIN_PCB, &m_usePlainPCBOpt, false );
+ m_config->Read( OPTKEY_VRML_REF_UNITS, &m_RefUnits, 0 );
+ m_config->Read( OPTKEY_VRML_REF_X, &m_XRef, 0.0 );
+ m_config->Read( OPTKEY_VRML_REF_Y, &m_YRef, 0.0 );
+ m_rbSelectUnits->SetSelection( m_unitsOpt );
+ m_cbCopyFiles->SetValue( m_copy3DFilesOpt );
+ m_cbUseRelativePaths->SetValue( m_useRelativePathsOpt );
+ m_cbPlainPCB->SetValue( m_usePlainPCBOpt );
+ m_VRML_RefUnitChoice->SetSelection( m_RefUnits );
+ wxString tmpStr;
+ tmpStr << m_XRef;
+ m_VRML_Xref->SetValue( tmpStr );
+ tmpStr = wxT( "" );
+ tmpStr << m_YRef;
+ m_VRML_Yref->SetValue( tmpStr );
+ m_sdbSizer1OK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+
+ Connect( ID_USE_ABS_PATH, wxEVT_UPDATE_UI,
+ wxUpdateUIEventHandler( DIALOG_EXPORT_3DFILE::OnUpdateUseRelativePath ) );
+ }
+
+ ~DIALOG_EXPORT_3DFILE()
+ {
+ m_unitsOpt = GetUnits();
+ m_copy3DFilesOpt = GetCopyFilesOption();
+ m_config->Write( OPTKEY_OUTPUT_UNIT, m_unitsOpt );
+ m_config->Write( OPTKEY_3DFILES_OPT, m_copy3DFilesOpt );
+ m_config->Write( OPTKEY_USE_RELATIVE_PATHS, m_useRelativePathsOpt );
+ m_config->Write( OPTKEY_USE_PLAIN_PCB, m_usePlainPCBOpt );
+ m_config->Write( OPTKEY_VRML_REF_UNITS, m_VRML_RefUnitChoice->GetSelection() );
+ m_config->Write( OPTKEY_VRML_REF_X, m_VRML_Xref->GetValue() );
+ m_config->Write( OPTKEY_VRML_REF_Y, m_VRML_Yref->GetValue() );
+ };
+
+ void SetSubdir( const wxString & aDir )
+ {
+ m_SubdirNameCtrl->SetValue( aDir );
+ }
+
+ wxString GetSubdir3Dshapes()
+ {
+ return m_SubdirNameCtrl->GetValue();
+ }
+
+ wxFilePickerCtrl* FilePicker()
+ {
+ return m_filePicker;
+ }
+
+ int GetRefUnitsChoice()
+ {
+ return m_VRML_RefUnitChoice->GetSelection();
+ }
+
+ double GetXRef()
+ {
+ return DoubleValueFromString( UNSCALED_UNITS, m_VRML_Xref->GetValue() );
+ }
+
+ double GetYRef()
+ {
+ return DoubleValueFromString( UNSCALED_UNITS, m_VRML_Yref->GetValue() );
+ }
+
+ int GetUnits()
+ {
+ return m_unitsOpt = m_rbSelectUnits->GetSelection();
+ }
+
+ bool GetCopyFilesOption()
+ {
+ return m_copy3DFilesOpt = m_cbCopyFiles->GetValue();
+ }
+
+ bool GetUseRelativePathsOption()
+ {
+ return m_useRelativePathsOpt = m_cbUseRelativePaths->GetValue();
+ }
+
+ bool GetUsePlainPCBOption()
+ {
+ return m_usePlainPCBOpt = m_cbPlainPCB->GetValue();
+ }
+
+ void OnUpdateUseRelativePath( wxUpdateUIEvent& event )
+ {
+ // Making path relative or absolute has no meaning when VRML files are not copied.
+ event.Enable( m_cbCopyFiles->GetValue() );
+ }
+
+ virtual void OnFileChanged( wxFileDirPickerEvent& event )
+ {
+ // Clicking on file picker button changes the focus to the file picker button which
+ // is not the behavior we want. Set the focus back to the OK button so the next enter
+ // key press dismisses this dialog with the OK action.
+ m_sdbSizer1OK->SetFocus();
+ }
+
+};
+
+
+void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event )
+{
+ // These variables are static to keep info during the session.
+ static wxString subDirFor3Dshapes;
+ static wxString last_brdName; // the last board name used to build the vrml filename
+ static wxString last_vrmlName; // the last wrml file name built
+
+ // If the board name has changed since the last export,
+ // do not use the old path, initialized by an other board
+ if( last_brdName.IsEmpty() || last_brdName != GetBoard()->GetFileName() )
+ {
+ last_brdName = GetBoard()->GetFileName();
+ last_vrmlName = last_brdName;
+ }
+
+ if( subDirFor3Dshapes.IsEmpty() )
+ {
+ subDirFor3Dshapes = wxT( "shapes3D" );
+ }
+
+ // The general VRML scale factor
+ // Assuming the VRML default unit is the mm
+ // this is the mm to VRML scaling factor for mm, 0.1 inch, and inch
+ double scaleList[4] = { 1.0, 0.001, 10.0/25.4, 1.0/25.4 };
+
+ // Build default file name, to display in the file picker
+ wxFileName fn = last_vrmlName;
+ fn.SetExt( wxT( "wrl" ) );
+
+ DIALOG_EXPORT_3DFILE dlg( this );
+ dlg.FilePicker()->SetPath( fn.GetFullPath() );
+ dlg.SetSubdir( subDirFor3Dshapes );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return;
+
+ double aXRef = dlg.GetXRef();
+ double aYRef = dlg.GetYRef();
+
+ if( dlg.GetRefUnitsChoice() == 1 )
+ {
+ // selected reference unit is in inches
+ aXRef *= 25.4;
+ aYRef *= 25.4;
+ }
+
+ double scale = scaleList[dlg.GetUnits()]; // final scale export
+ bool export3DFiles = dlg.GetCopyFilesOption();
+ bool useRelativePaths = dlg.GetUseRelativePathsOption();
+ bool usePlainPCB = dlg.GetUsePlainPCBOption();
+
+ last_vrmlName = dlg.FilePicker()->GetPath();
+ wxFileName modelPath = last_vrmlName;
+ wxBusyCursor dummy;
+
+ subDirFor3Dshapes = dlg.GetSubdir3Dshapes();
+ modelPath.AppendDir( subDirFor3Dshapes );
+
+ if( export3DFiles && !modelPath.DirExists() )
+ {
+ modelPath.Mkdir();
+ }
+
+ if( !ExportVRML_File( last_vrmlName, scale, export3DFiles, useRelativePaths,
+ usePlainPCB, modelPath.GetPath(), aXRef, aYRef ) )
+ {
+ wxString msg;
+ msg.Printf( _( "Unable to create file '%s'" ), GetChars( last_vrmlName ) );
+ wxMessageBox( msg );
+ return;
+ }
+}
diff --git a/pcbnew/dialogs/dialog_export_vrml_base.cpp b/pcbnew/dialogs/dialog_export_vrml_base.cpp
new file mode 100644
index 0000000..05ec56b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_export_vrml_base.cpp
@@ -0,0 +1,160 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_export_vrml_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_EXPORT_3DFILE_BASE::DIALOG_EXPORT_3DFILE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizer1;
+ bSizer1 = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText1 = new wxStaticText( this, wxID_ANY, _("File Name:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ bUpperSizer->Add( m_staticText1, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_filePicker = new wxFilePickerCtrl( this, wxID_ANY, wxEmptyString, _("Save VRML Board File"), wxT("*.wrl"), wxDefaultPosition, wxDefaultSize, wxFLP_SAVE|wxFLP_USE_TEXTCTRL );
+ bUpperSizer->Add( m_filePicker, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_staticText3 = new wxStaticText( this, wxID_ANY, _("Footprint 3D model path:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ bUpperSizer->Add( m_staticText3, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_SubdirNameCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SubdirNameCtrl->SetMaxLength( 0 );
+ bUpperSizer->Add( m_SubdirNameCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizer1->Add( bUpperSizer, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer12;
+ bSizer12 = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizer5;
+ bSizer5 = new wxBoxSizer( wxVERTICAL );
+
+ m_panel1 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* bSizer9;
+ bSizer9 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText6 = new wxStaticText( m_panel1, wxID_ANY, _("Grid Reference Point:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText6->Wrap( -1 );
+ bSizer9->Add( m_staticText6, 0, wxALL, 5 );
+
+ wxFlexGridSizer* fgSizerOptions;
+ fgSizerOptions = new wxFlexGridSizer( 0, 2, 0, 0 );
+ fgSizerOptions->AddGrowableCol( 1 );
+ fgSizerOptions->SetFlexibleDirection( wxBOTH );
+ fgSizerOptions->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText61 = new wxStaticText( m_panel1, wxID_ANY, _("Units:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText61->Wrap( -1 );
+ fgSizerOptions->Add( m_staticText61, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ wxString m_VRML_RefUnitChoiceChoices[] = { _("mm"), _("inch") };
+ int m_VRML_RefUnitChoiceNChoices = sizeof( m_VRML_RefUnitChoiceChoices ) / sizeof( wxString );
+ m_VRML_RefUnitChoice = new wxChoice( m_panel1, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_VRML_RefUnitChoiceNChoices, m_VRML_RefUnitChoiceChoices, 0 );
+ m_VRML_RefUnitChoice->SetSelection( 0 );
+ fgSizerOptions->Add( m_VRML_RefUnitChoice, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+ m_staticText4 = new wxStaticText( m_panel1, wxID_ANY, _("X Ref:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText4->Wrap( -1 );
+ fgSizerOptions->Add( m_staticText4, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_VRML_Xref = new wxTextCtrl( m_panel1, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_VRML_Xref->SetMaxLength( 8 );
+ fgSizerOptions->Add( m_VRML_Xref, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_staticText5 = new wxStaticText( m_panel1, wxID_ANY, _("Y Ref:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText5->Wrap( -1 );
+ fgSizerOptions->Add( m_staticText5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_VRML_Yref = new wxTextCtrl( m_panel1, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_VRML_Yref->SetMaxLength( 8 );
+ fgSizerOptions->Add( m_VRML_Yref, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bSizer9->Add( fgSizerOptions, 1, wxEXPAND, 5 );
+
+
+ m_panel1->SetSizer( bSizer9 );
+ m_panel1->Layout();
+ bSizer9->Fit( m_panel1 );
+ bSizer5->Add( m_panel1, 1, wxEXPAND | wxALL, 5 );
+
+
+ bSizer12->Add( bSizer5, 1, wxEXPAND, 5 );
+
+ wxString m_rbSelectUnitsChoices[] = { _("mm"), _("meter"), _("0.1 Inch"), _("Inch") };
+ int m_rbSelectUnitsNChoices = sizeof( m_rbSelectUnitsChoices ) / sizeof( wxString );
+ m_rbSelectUnits = new wxRadioBox( this, wxID_ANY, _("Output Units:"), wxDefaultPosition, wxDefaultSize, m_rbSelectUnitsNChoices, m_rbSelectUnitsChoices, 1, wxRA_SPECIFY_COLS );
+ m_rbSelectUnits->SetSelection( 0 );
+ bSizer12->Add( m_rbSelectUnits, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizer1->Add( bSizer12, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bLowerSizer;
+ bLowerSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxVERTICAL );
+
+ m_cbCopyFiles = new wxCheckBox( this, wxID_ANY, _("Copy 3D model files to 3D model path"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_cbCopyFiles->SetValue(true);
+ bSizer4->Add( m_cbCopyFiles, 0, wxALL, 5 );
+
+ m_cbUseRelativePaths = new wxCheckBox( this, ID_USE_ABS_PATH, _("Use relative paths to model files in board VRML file"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_cbUseRelativePaths->SetToolTip( _("Use paths for model files in board VRML file relative to the vrml file") );
+
+ bSizer4->Add( m_cbUseRelativePaths, 0, wxALL, 5 );
+
+ m_cbPlainPCB = new wxCheckBox( this, wxID_ANY, _("Plain PCB (no copper or silk)"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer4->Add( m_cbPlainPCB, 0, wxALL, 5 );
+
+
+ bLowerSizer->Add( bSizer4, 2, wxEXPAND, 5 );
+
+
+ bSizer1->Add( bLowerSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ bSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizer1->Add( m_staticline1, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bSizer1->Add( m_sdbSizer1, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( bSizer1 );
+ this->Layout();
+ bSizer1->Fit( this );
+
+ // Connect Events
+ m_filePicker->Connect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( DIALOG_EXPORT_3DFILE_BASE::OnFileChanged ), NULL, this );
+}
+
+DIALOG_EXPORT_3DFILE_BASE::~DIALOG_EXPORT_3DFILE_BASE()
+{
+ // Disconnect Events
+ m_filePicker->Disconnect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( DIALOG_EXPORT_3DFILE_BASE::OnFileChanged ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_export_vrml_base.fbp b/pcbnew/dialogs/dialog_export_vrml_base.fbp
new file mode 100644
index 0000000..b9a987e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_export_vrml_base.fbp
@@ -0,0 +1,1677 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_export_vrml_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_export_vrml</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_EXPORT_3DFILE_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">VRML Export Options</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">bSizer1</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">File Name:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFilePickerCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="message">Save VRML Board File</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_filePicker</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxFLP_SAVE|wxFLP_USE_TEXTCTRL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="wildcard">*.wrl</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnFileChanged">OnFileChanged</event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprint 3D model path:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SubdirNameCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer12</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer5</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_panel1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer9</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Grid Reference Point:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText6</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerOptions</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Units:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText61</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;mm&quot; &quot;inch&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_VRML_RefUnitChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">X Ref:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">8</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_VRML_Xref</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NUMERIC</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Y Ref:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">8</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_VRML_Yref</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NUMERIC</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;mm&quot; &quot;meter&quot; &quot;0.1 Inch&quot; &quot;Inch&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Output Units:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbSelectUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLowerSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">2</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer4</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Copy 3D model files to 3D model path</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbCopyFiles</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_USE_ABS_PATH</property>
+ <property name="label">Use relative paths to model files in board VRML file</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbUseRelativePaths</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Use paths for model files in board VRML file relative to the vrml file</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Plain PCB (no copper or silk)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbPlainPCB</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="0">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="0">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_export_vrml_base.h b/pcbnew/dialogs/dialog_export_vrml_base.h
new file mode 100644
index 0000000..674ebb3
--- /dev/null
+++ b/pcbnew/dialogs/dialog_export_vrml_base.h
@@ -0,0 +1,81 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_EXPORT_VRML_BASE_H__
+#define __DIALOG_EXPORT_VRML_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/filepicker.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/choice.h>
+#include <wx/panel.h>
+#include <wx/radiobox.h>
+#include <wx/checkbox.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_EXPORT_3DFILE_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_EXPORT_3DFILE_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ ID_USE_ABS_PATH = 1000
+ };
+
+ wxStaticText* m_staticText1;
+ wxFilePickerCtrl* m_filePicker;
+ wxStaticText* m_staticText3;
+ wxTextCtrl* m_SubdirNameCtrl;
+ wxPanel* m_panel1;
+ wxStaticText* m_staticText6;
+ wxStaticText* m_staticText61;
+ wxChoice* m_VRML_RefUnitChoice;
+ wxStaticText* m_staticText4;
+ wxTextCtrl* m_VRML_Xref;
+ wxStaticText* m_staticText5;
+ wxTextCtrl* m_VRML_Yref;
+ wxRadioBox* m_rbSelectUnits;
+ wxCheckBox* m_cbCopyFiles;
+ wxCheckBox* m_cbUseRelativePaths;
+ wxCheckBox* m_cbPlainPCB;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnFileChanged( wxFileDirPickerEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_EXPORT_3DFILE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("VRML Export Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_EXPORT_3DFILE_BASE();
+
+};
+
+#endif //__DIALOG_EXPORT_VRML_BASE_H__
diff --git a/pcbnew/dialogs/dialog_find.cpp b/pcbnew/dialogs/dialog_find.cpp
new file mode 100644
index 0000000..e3acac2
--- /dev/null
+++ b/pcbnew/dialogs/dialog_find.cpp
@@ -0,0 +1,196 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Marco Mattila <marcom99@gmail.com>
+ * Copyright (C) 2006 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
+ * Copyright (C) 1992-2012 Kicad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <wxPcbStruct.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_marker_pcb.h>
+
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <dialog_find.h>
+
+
+// Initialize static member variables
+wxString DIALOG_FIND::prevSearchString;
+bool DIALOG_FIND::warpMouse = true;
+
+
+DIALOG_FIND::DIALOG_FIND( PCB_BASE_FRAME* aParent ) : DIALOG_FIND_BASE( aParent )
+{
+ parent = aParent;
+ foundItem = NULL;
+ GetSizer()->SetSizeHints( this );
+
+ m_SearchTextCtrl->AppendText( prevSearchString );
+ m_SearchTextCtrl->SetFocus();
+ m_SearchTextCtrl->SetSelection( -1, -1 );
+ m_NoMouseWarpCheckBox->SetValue( !warpMouse );
+
+ itemCount = markerCount = 0;
+
+ Center();
+}
+
+void DIALOG_FIND::EnableWarp( bool aEnabled )
+{
+ m_NoMouseWarpCheckBox->SetValue( !aEnabled );
+ warpMouse = aEnabled;
+}
+
+void DIALOG_FIND::onButtonCloseClick( wxCommandEvent& aEvent )
+{
+ Close( true );
+}
+
+
+void DIALOG_FIND::onButtonFindItemClick( wxCommandEvent& aEvent )
+{
+ PCB_SCREEN* screen = parent->GetScreen();
+ wxPoint pos;
+
+ foundItem = NULL;
+ wxString searchString = m_SearchTextCtrl->GetValue();
+
+ if( !searchString.IsSameAs( prevSearchString, false ) )
+ {
+ itemCount = 0;
+ }
+ prevSearchString = searchString;
+
+ parent->GetCanvas()->GetViewStart( &screen->m_StartVisu.x, &screen->m_StartVisu.y );
+
+ int count = 0;
+
+ for( MODULE* module = parent->GetBoard()->m_Modules; module; module = module->Next() )
+ {
+ if( WildCompareString( searchString, module->GetReference().GetData(), false ) )
+ {
+ count++;
+
+ if( count > itemCount )
+ {
+ foundItem = module;
+ pos = module->GetPosition();
+ itemCount++;
+ break;
+ }
+ }
+
+ if( WildCompareString( searchString, module->GetValue().GetData(), false ) )
+ {
+ count++;
+
+ if( count > itemCount )
+ {
+ foundItem = module;
+ pos = module->GetPosition();
+ itemCount++;
+ break;
+ }
+ }
+ }
+
+ wxString msg;
+
+ if( foundItem )
+ {
+ parent->SetCurItem( foundItem );
+ msg.Printf( _( "<%s> found" ), GetChars( searchString ) );
+ parent->SetStatusText( msg );
+
+ parent->CursorGoto( pos, !m_NoMouseWarpCheckBox->IsChecked() );
+ }
+ else
+ {
+ parent->SetStatusText( wxEmptyString );
+ msg.Printf( _( "<%s> not found" ), GetChars( searchString ) );
+ DisplayError( this, msg, 10 );
+ itemCount = 0;
+ }
+
+ if( callback )
+ callback( foundItem );
+}
+
+
+void DIALOG_FIND::onButtonFindMarkerClick( wxCommandEvent& aEvent )
+{
+ PCB_SCREEN* screen = parent->GetScreen();
+ wxPoint pos;
+ foundItem = NULL;
+
+ parent->GetCanvas()->GetViewStart( &screen->m_StartVisu.x, &screen->m_StartVisu.y );
+
+ MARKER_PCB* marker = parent->GetBoard()->GetMARKER( markerCount++ );
+
+ if( marker )
+ {
+ foundItem = marker;
+ pos = marker->GetPosition();
+ }
+
+ wxString msg;
+ if( foundItem )
+ {
+ parent->SetCurItem( foundItem );
+ msg = _( "Marker found" );
+ parent->SetStatusText( msg );
+
+ parent->CursorGoto( pos, !m_NoMouseWarpCheckBox->IsChecked() );
+ }
+ else
+ {
+ parent->SetStatusText( wxEmptyString );
+ msg = _( "No marker found" );
+ DisplayError( this, msg, 10 );
+ markerCount = 0;
+ }
+
+ if( callback )
+ callback( foundItem );
+}
+
+
+void DIALOG_FIND::onClose( wxCloseEvent& aEvent )
+{
+ warpMouse = !m_NoMouseWarpCheckBox->IsChecked();
+
+ EndModal( 1 );
+}
+
+
+void PCB_EDIT_FRAME::InstallFindFrame()
+{
+ DIALOG_FIND dlg( this );
+ dlg.ShowModal();
+}
+
diff --git a/pcbnew/dialogs/dialog_find.h b/pcbnew/dialogs/dialog_find.h
new file mode 100644
index 0000000..d374c41
--- /dev/null
+++ b/pcbnew/dialogs/dialog_find.h
@@ -0,0 +1,57 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Marco Mattila <marcom99@gmail.com>
+ * Copyright (C) 2006 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
+ * Copyright (C) 1992-2012 Kicad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef DIALOG_FIND_BASE_H
+#define DIALOG_FIND_BASE_H
+
+#include <dialog_find_base.h>
+#include <boost/function.hpp>
+
+class DIALOG_FIND : public DIALOG_FIND_BASE
+{
+public:
+ DIALOG_FIND( PCB_BASE_FRAME* aParent );
+ inline BOARD_ITEM* GetItem() const { return foundItem; }
+ void EnableWarp( bool aEnabled );
+ void SetCallback( boost::function<void (BOARD_ITEM*)> aCallback ) { callback = aCallback; }
+
+private:
+ PCB_BASE_FRAME* parent;
+
+ int itemCount, markerCount;
+ static wxString prevSearchString;
+ static bool warpMouse;
+ BOARD_ITEM* foundItem;
+
+ // Function called when an item is found
+ boost::function<void (BOARD_ITEM*)> callback;
+
+ void onButtonFindItemClick( wxCommandEvent& event );
+ void onButtonFindMarkerClick( wxCommandEvent& event );
+ void onButtonCloseClick( wxCommandEvent& event );
+ void onClose( wxCloseEvent& event );
+};
+
+#endif /* DIALOG_FIND_BASE_H */
diff --git a/pcbnew/dialogs/dialog_find_base.cpp b/pcbnew/dialogs/dialog_find_base.cpp
new file mode 100644
index 0000000..3c40e61
--- /dev/null
+++ b/pcbnew/dialogs/dialog_find_base.cpp
@@ -0,0 +1,73 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Apr 10 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_find_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_FIND_BASE::DIALOG_FIND_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizer3;
+ bSizer3 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText1 = new wxStaticText( this, wxID_ANY, _("Search for:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ bSizer3->Add( m_staticText1, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_SearchTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 200,-1 ), 0 );
+ bSizer3->Add( m_SearchTextCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_NoMouseWarpCheckBox = new wxCheckBox( this, wxID_ANY, _("Do not warp mouse pointer"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer3->Add( m_NoMouseWarpCheckBox, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bSizer3, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxVERTICAL );
+
+ m_button1 = new wxButton( this, wxID_ANY, _("Find Item"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_button1->SetDefault();
+ bSizer4->Add( m_button1, 1, wxALL|wxEXPAND, 5 );
+
+ m_button2 = new wxButton( this, wxID_ANY, _("Find Marker"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer4->Add( m_button2, 1, wxALL|wxEXPAND, 5 );
+
+ m_button3 = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer4->Add( m_button3, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bSizer4, 0, wxALL, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+ bSizerMain->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_FIND_BASE::onClose ) );
+ m_button1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FIND_BASE::onButtonFindItemClick ), NULL, this );
+ m_button2->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FIND_BASE::onButtonFindMarkerClick ), NULL, this );
+ m_button3->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FIND_BASE::onButtonCloseClick ), NULL, this );
+}
+
+DIALOG_FIND_BASE::~DIALOG_FIND_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_FIND_BASE::onClose ) );
+ m_button1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FIND_BASE::onButtonFindItemClick ), NULL, this );
+ m_button2->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FIND_BASE::onButtonFindMarkerClick ), NULL, this );
+ m_button3->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FIND_BASE::onButtonCloseClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_find_base.fbp b/pcbnew/dialogs/dialog_find_base.fbp
new file mode 100644
index 0000000..3d82718
--- /dev/null
+++ b/pcbnew/dialogs/dialog_find_base.fbp
@@ -0,0 +1,645 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="11" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_find_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_find</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_FIND_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Find</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">onClose</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerLeft</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Search for:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SearchTextCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">200,-1</property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Do not warp mouse pointer</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NoMouseWarpCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRight</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Find Item</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_button1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">onButtonFindItemClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Find Marker</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_button2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">onButtonFindMarkerClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_button3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">onButtonCloseClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_find_base.h b/pcbnew/dialogs/dialog_find_base.h
new file mode 100644
index 0000000..dad8e7a
--- /dev/null
+++ b/pcbnew/dialogs/dialog_find_base.h
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Apr 10 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_FIND_BASE_H__
+#define __DIALOG_FIND_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/checkbox.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_FIND_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_FIND_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText1;
+ wxTextCtrl* m_SearchTextCtrl;
+ wxCheckBox* m_NoMouseWarpCheckBox;
+ wxButton* m_button1;
+ wxButton* m_button2;
+ wxButton* m_button3;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void onClose( wxCloseEvent& event ) { event.Skip(); }
+ virtual void onButtonFindItemClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void onButtonFindMarkerClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void onButtonCloseClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_FIND_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Find"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_FIND_BASE();
+
+};
+
+#endif //__DIALOG_FIND_BASE_H__
diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list.cpp b/pcbnew/dialogs/dialog_footprint_wizard_list.cpp
new file mode 100644
index 0000000..8c49d6b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_footprint_wizard_list.cpp
@@ -0,0 +1,110 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2014 Miguel Angel Ajo <miguelangel@nbee.es>
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_footprint_wizard_list.cpp
+ */
+
+#include <wx/grid.h>
+
+#include <fctsys.h>
+#include <pcbnew.h>
+#include <kiface_i.h>
+#include <dialog_footprint_wizard_list.h>
+#include <class_footprint_wizard.h>
+
+#define ROW_NAME 0
+#define ROW_DESCR 1
+#define FPWIZARTDLIST_HEIGHT_KEY wxT( "FpWizardListHeight" )
+#define FPWIZARTDLIST_WIDTH_KEY wxT( "FpWizardListWidth" )
+
+DIALOG_FOOTPRINT_WIZARD_LIST::DIALOG_FOOTPRINT_WIZARD_LIST( wxWindow* aParent )
+ : DIALOG_FOOTPRINT_WIZARD_LIST_BASE( aParent )
+{
+ int n_wizards = FOOTPRINT_WIZARDS::GetWizardsCount();
+ m_config = Kiface().KifaceSettings();
+
+ // Current wizard selection, empty or first
+ m_footprintWizard = NULL;
+
+ if( n_wizards )
+ m_footprintWizard = FOOTPRINT_WIZARDS::GetWizard( 0 );
+
+ // Choose selection mode and insert the needed rows
+
+ m_footprintGeneratorsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
+ m_footprintGeneratorsGrid->InsertRows( 0, n_wizards, true );
+
+ // Put all wizards in the list
+ for( int i=0; i<n_wizards; i++ )
+ {
+ FOOTPRINT_WIZARD *wizard = FOOTPRINT_WIZARDS::GetWizard( i );
+ wxString name = wizard->GetName();
+ wxString description = wizard->GetDescription();
+ wxString image = wizard->GetImage();
+
+ m_footprintGeneratorsGrid->SetCellValue( i, ROW_NAME, name );
+ m_footprintGeneratorsGrid->SetCellValue( i, ROW_DESCR, description );
+
+ }
+
+ // Select the first row
+ m_footprintGeneratorsGrid->ClearSelection();
+ m_footprintGeneratorsGrid->SelectRow( 0, false );
+
+ if( m_config )
+ {
+ wxSize size;
+ m_config->Read( FPWIZARTDLIST_WIDTH_KEY, &size.x, -1 );
+ m_config->Read( FPWIZARTDLIST_HEIGHT_KEY, &size.y, -1 );
+ SetSize( size );
+ }
+
+ Center();
+}
+
+
+DIALOG_FOOTPRINT_WIZARD_LIST::~DIALOG_FOOTPRINT_WIZARD_LIST()
+{
+ if( m_config && !IsIconized() )
+ {
+ m_config->Write( FPWIZARTDLIST_WIDTH_KEY, GetSize().x );
+ m_config->Write( FPWIZARTDLIST_HEIGHT_KEY, GetSize().y );
+ }
+}
+
+
+
+void DIALOG_FOOTPRINT_WIZARD_LIST::OnCellFpGeneratorClick( wxGridEvent& event )
+{
+ int click_row = event.GetRow();
+ m_footprintWizard = FOOTPRINT_WIZARDS::GetWizard( click_row );
+ m_footprintGeneratorsGrid->SelectRow( event.GetRow(), false );
+}
+
+
+FOOTPRINT_WIZARD* DIALOG_FOOTPRINT_WIZARD_LIST::GetWizard()
+{
+ return m_footprintWizard;
+}
diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list.h b/pcbnew/dialogs/dialog_footprint_wizard_list.h
new file mode 100644
index 0000000..ad11c4b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_footprint_wizard_list.h
@@ -0,0 +1,47 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2014 Miguel Angel Ajo <miguelangel@nbee.es>
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _DIALOG_FOOTPRINT_WIZARD_LIST_H_
+#define _DIALOG_FOOTPRINT_WIZARD_LIST_H_
+
+#include <dialog_footprint_wizard_list_base.h>
+#include <class_footprint_wizard.h>
+
+class DIALOG_FOOTPRINT_WIZARD_LIST: public DIALOG_FOOTPRINT_WIZARD_LIST_BASE
+{
+private:
+ FOOTPRINT_WIZARD* m_footprintWizard; ///< The selected python script wizard
+ wxConfigBase* m_config;
+
+public:
+ DIALOG_FOOTPRINT_WIZARD_LIST( wxWindow * aParent );
+ ~DIALOG_FOOTPRINT_WIZARD_LIST();
+
+ FOOTPRINT_WIZARD* GetWizard();
+
+private:
+ void OnCellFpGeneratorClick( wxGridEvent& event );
+};
+
+#endif // _DIALOG_FOOTPRINT_WIZARD_LIST_H_
diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp b/pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp
new file mode 100644
index 0000000..73641f7
--- /dev/null
+++ b/pcbnew/dialogs/dialog_footprint_wizard_list_base.cpp
@@ -0,0 +1,79 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_footprint_wizard_list_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_FOOTPRINT_WIZARD_LIST_BASE::DIALOG_FOOTPRINT_WIZARD_LIST_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( 400,200 ), wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ m_footprintGeneratorsGrid = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_footprintGeneratorsGrid->CreateGrid( 0, 2 );
+ m_footprintGeneratorsGrid->EnableEditing( false );
+ m_footprintGeneratorsGrid->EnableGridLines( true );
+ m_footprintGeneratorsGrid->EnableDragGridSize( false );
+ m_footprintGeneratorsGrid->SetMargins( 0, 0 );
+
+ // Columns
+ m_footprintGeneratorsGrid->SetColSize( 0, 160 );
+ m_footprintGeneratorsGrid->SetColSize( 1, 325 );
+ m_footprintGeneratorsGrid->EnableDragColMove( false );
+ m_footprintGeneratorsGrid->EnableDragColSize( true );
+ m_footprintGeneratorsGrid->SetColLabelSize( 20 );
+ m_footprintGeneratorsGrid->SetColLabelValue( 0, _("Name") );
+ m_footprintGeneratorsGrid->SetColLabelValue( 1, _("Description") );
+ m_footprintGeneratorsGrid->SetColLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTRE );
+
+ // Rows
+ m_footprintGeneratorsGrid->AutoSizeRows();
+ m_footprintGeneratorsGrid->EnableDragRowSize( true );
+ m_footprintGeneratorsGrid->SetRowLabelSize( 1 );
+ m_footprintGeneratorsGrid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_footprintGeneratorsGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ m_footprintGeneratorsGrid->SetMinSize( wxSize( 485,120 ) );
+
+ bSizerMain->Add( m_footprintGeneratorsGrid, 1, wxALL|wxEXPAND, 5 );
+
+ m_staticline = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerMain->Add( m_staticline, 0, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bSizerMain->Add( m_sdbSizer, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_footprintGeneratorsGrid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::OnCellFpGeneratorClick ), NULL, this );
+}
+
+DIALOG_FOOTPRINT_WIZARD_LIST_BASE::~DIALOG_FOOTPRINT_WIZARD_LIST_BASE()
+{
+ // Disconnect Events
+ m_footprintGeneratorsGrid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_FOOTPRINT_WIZARD_LIST_BASE::OnCellFpGeneratorClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list_base.fbp b/pcbnew/dialogs/dialog_footprint_wizard_list_base.fbp
new file mode 100644
index 0000000..02901a7
--- /dev/null
+++ b/pcbnew/dialogs/dialog_footprint_wizard_list_base.fbp
@@ -0,0 +1,349 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_footprint_wizard_list_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_FOOTPRINT_WIZARD_LIST_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">400,200</property>
+ <property name="name">DIALOG_FOOTPRINT_WIZARD_LIST_BASE</property>
+ <property name="pos"></property>
+ <property name="size">501,273</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Footprint Generators</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">0</property>
+ <property name="autosize_rows">1</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg"></property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="col_label_size">20</property>
+ <property name="col_label_values">&quot;Name&quot; &quot;Description&quot;</property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">2</property>
+ <property name="column_sizes">160,325</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">1</property>
+ <property name="editing">0</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">485,120</property>
+ <property name="moveable">1</property>
+ <property name="name">m_footprintGeneratorsGrid</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">1</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick">OnCellFpGeneratorClick</event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_footprint_wizard_list_base.h b/pcbnew/dialogs/dialog_footprint_wizard_list_base.h
new file mode 100644
index 0000000..0d8c48c
--- /dev/null
+++ b/pcbnew/dialogs/dialog_footprint_wizard_list_base.h
@@ -0,0 +1,56 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_FOOTPRINT_WIZARD_LIST_BASE_H__
+#define __DIALOG_FOOTPRINT_WIZARD_LIST_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/string.h>
+#include <wx/font.h>
+#include <wx/grid.h>
+#include <wx/gdicmn.h>
+#include <wx/statline.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_FOOTPRINT_WIZARD_LIST_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_FOOTPRINT_WIZARD_LIST_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxGrid* m_footprintGeneratorsGrid;
+ wxStaticLine* m_staticline;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCellFpGeneratorClick( wxGridEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_FOOTPRINT_WIZARD_LIST_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Footprint Generators"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 501,273 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_FOOTPRINT_WIZARD_LIST_BASE();
+
+};
+
+#endif //__DIALOG_FOOTPRINT_WIZARD_LIST_BASE_H__
diff --git a/pcbnew/dialogs/dialog_fp_lib_table.cpp b/pcbnew/dialogs/dialog_fp_lib_table.cpp
new file mode 100644
index 0000000..1f3b4d6
--- /dev/null
+++ b/pcbnew/dialogs/dialog_fp_lib_table.cpp
@@ -0,0 +1,887 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2013 CERN
+ * Copyright (C) 2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* TODO:
+
+*) After any change to uri, reparse the environment variables.
+
+*/
+
+
+#include <set>
+#include <wx/regex.h>
+
+#include <fctsys.h>
+#include <project.h>
+#include <3d_viewer.h> // for KISYS3DMOD
+#include <dialog_fp_lib_table_base.h>
+#include <fp_lib_table.h>
+#include <fp_lib_table_lexer.h>
+#include <invoke_pcb_dialog.h>
+#include <grid_tricks.h>
+#include <confirm.h>
+#include <wizard_add_fplib.h>
+
+
+/// grid column order is established by this sequence
+enum COL_ORDER
+{
+ COL_NICKNAME,
+ COL_URI,
+ COL_TYPE,
+ COL_OPTIONS,
+ COL_DESCR,
+ COL_COUNT // keep as last
+};
+
+
+/**
+ * Class FP_TBL_MODEL
+ * mixes in FP_LIB_TABLE into wxGridTableBase so the result can be used
+ * as a table within wxGrid.
+ */
+class FP_TBL_MODEL : public wxGridTableBase, public FP_LIB_TABLE
+{
+ friend class FP_GRID_TRICKS;
+
+public:
+
+ /**
+ * Constructor FP_TBL_MODEL
+ * is a copy constructor that builds a wxGridTableBase (table model) by wrapping
+ * an FP_LIB_TABLE.
+ */
+ FP_TBL_MODEL( const FP_LIB_TABLE& aTableToEdit ) :
+ FP_LIB_TABLE( aTableToEdit ) // copy constructor
+ {
+ }
+
+ //-----<wxGridTableBase overloads>-------------------------------------------
+
+ int GetNumberRows() { return rows.size(); }
+ int GetNumberCols() { return COL_COUNT; }
+
+ wxString GetValue( int aRow, int aCol )
+ {
+ if( unsigned( aRow ) < rows.size() )
+ {
+ const ROW& r = rows[aRow];
+
+ switch( aCol )
+ {
+ case COL_NICKNAME: return r.GetNickName();
+ case COL_URI: return r.GetFullURI();
+ case COL_TYPE: return r.GetType();
+ case COL_OPTIONS: return r.GetOptions();
+ case COL_DESCR: return r.GetDescr();
+ default:
+ ; // fall thru to wxEmptyString
+ }
+ }
+
+ return wxEmptyString;
+ }
+
+ void SetValue( int aRow, int aCol, const wxString &aValue )
+ {
+ if( unsigned( aRow ) < rows.size() )
+ {
+ ROW& r = rows[aRow];
+
+ switch( aCol )
+ {
+ case COL_NICKNAME: r.SetNickName( aValue ); break;
+ case COL_URI: r.SetFullURI( aValue ); break;
+ case COL_TYPE: r.SetType( aValue ); break;
+ case COL_OPTIONS: r.SetOptions( aValue ); break;
+ case COL_DESCR: r.SetDescr( aValue ); break;
+ }
+ }
+ }
+
+ bool IsEmptyCell( int aRow, int aCol )
+ {
+ return !GetValue( aRow, aCol );
+ }
+
+ bool InsertRows( size_t aPos = 0, size_t aNumRows = 1 )
+ {
+ if( aPos < rows.size() )
+ {
+ rows.insert( rows.begin() + aPos, aNumRows, ROW() );
+
+ // use the (wxGridStringTable) source Luke.
+ if( GetView() )
+ {
+ wxGridTableMessage msg( this,
+ wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
+ aPos,
+ aNumRows );
+
+ GetView()->ProcessTableMessage( msg );
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ bool AppendRows( size_t aNumRows = 1 )
+ {
+ // do not modify aNumRows, original value needed for wxGridTableMessage below
+ for( int i = aNumRows; i; --i )
+ rows.push_back( ROW() );
+
+ if( GetView() )
+ {
+ wxGridTableMessage msg( this,
+ wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
+ aNumRows );
+
+ GetView()->ProcessTableMessage( msg );
+ }
+
+ return true;
+ }
+
+ bool DeleteRows( size_t aPos, size_t aNumRows )
+ {
+ // aPos may be a large positive, e.g. size_t(-1), and the sum of
+ // aPos+aNumRows may wrap here, so both ends of the range are tested.
+ if( aPos < rows.size() && aPos + aNumRows <= rows.size() )
+ {
+ ROWS_ITER start = rows.begin() + aPos;
+ rows.erase( start, start + aNumRows );
+
+ if( GetView() )
+ {
+ wxGridTableMessage msg( this,
+ wxGRIDTABLE_NOTIFY_ROWS_DELETED,
+ aPos,
+ aNumRows );
+
+ GetView()->ProcessTableMessage( msg );
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ void Clear()
+ {
+ rows.clear();
+ nickIndex.clear();
+ }
+
+ wxString GetColLabelValue( int aCol )
+ {
+ switch( aCol )
+ {
+ case COL_NICKNAME: return _( "Nickname" );
+ case COL_URI: return _( "Library Path" );
+
+ // keep this "Plugin Type" text fairly long so column is sized wide enough
+ case COL_TYPE: return _( "Plugin Type" );
+ case COL_OPTIONS: return _( "Options" );
+ case COL_DESCR: return _( "Description" );
+ default: return wxEmptyString;
+ }
+ }
+
+ //-----</wxGridTableBase overloads>------------------------------------------
+};
+
+
+class FP_GRID_TRICKS : public GRID_TRICKS
+{
+public:
+ FP_GRID_TRICKS( wxGrid* aGrid ) :
+ GRID_TRICKS( aGrid )
+ {
+ }
+
+protected:
+
+ /// handle specialized clipboard text, with leading "(fp_lib_table", OR
+ /// spreadsheet formatted text.
+ virtual void paste_text( const wxString& cb_text )
+ {
+ FP_TBL_MODEL* tbl = (FP_TBL_MODEL*) m_grid->GetTable();
+
+ size_t ndx = cb_text.find( wxT( "(fp_lib_table" ) );
+
+ if( ndx != std::string::npos )
+ {
+ // paste the ROWs of s-expression (fp_lib_table), starting
+ // at column 0 regardless of current cursor column.
+
+ STRING_LINE_READER slr( TO_UTF8( cb_text ), wxT( "Clipboard" ) );
+ FP_LIB_TABLE_LEXER lexer( &slr );
+ FP_LIB_TABLE tmp_tbl;
+ bool parsed = true;
+
+ try
+ {
+ tmp_tbl.Parse( &lexer );
+ }
+ catch( PARSE_ERROR& pe )
+ {
+ DisplayError( NULL, pe.errorText );
+ parsed = false;
+ }
+
+ if( parsed )
+ {
+ const int cur_row = std::max( getCursorRow(), 0 );
+
+ // if clipboard rows would extend past end of current table size...
+ if( tmp_tbl.GetCount() > tbl->GetNumberRows() - cur_row )
+ {
+ int newRowsNeeded = tmp_tbl.GetCount() - ( tbl->GetNumberRows() - cur_row );
+ tbl->AppendRows( newRowsNeeded );
+ }
+
+ for( int i = 0; i < tmp_tbl.GetCount(); ++i )
+ {
+ tbl->At( cur_row+i ) = tmp_tbl.At( i );
+ }
+ }
+ m_grid->AutoSizeColumns( false );
+ }
+ else
+ {
+ // paste spreadsheet formatted text.
+ GRID_TRICKS::paste_text( cb_text );
+ }
+ }
+};
+
+
+/**
+ * Class DIALOG_FP_LIB_TABLE
+ * shows and edits the PCB library tables. Two tables are expected, one global
+ * and one project specific.
+ */
+class DIALOG_FP_LIB_TABLE : public DIALOG_FP_LIB_TABLE_BASE
+{
+
+public:
+ DIALOG_FP_LIB_TABLE( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject ) :
+ DIALOG_FP_LIB_TABLE_BASE( aParent ),
+ m_global( aGlobal ),
+ m_project( aProject )
+ {
+ // For user info, shows the table filenames:
+ m_PrjTableFilename->SetLabel( Prj().FootprintLibTblName() );
+ m_GblTableFilename->SetLabel( FP_LIB_TABLE::GetGlobalTableFileName() );
+
+ // wxGrid only supports user owned tables if they exist past end of ~wxGrid(),
+ // so make it a grid owned table.
+ m_global_grid->SetTable( new FP_TBL_MODEL( *aGlobal ), true );
+ m_project_grid->SetTable( new FP_TBL_MODEL( *aProject ), true );
+
+ // add Cut, Copy, and Paste to wxGrids
+ m_global_grid->PushEventHandler( new FP_GRID_TRICKS( m_global_grid ) );
+ m_project_grid->PushEventHandler( new FP_GRID_TRICKS( m_project_grid ) );
+
+ m_global_grid->AutoSizeColumns( false );
+ m_project_grid->AutoSizeColumns( false );
+
+ wxArrayString choices;
+
+ choices.Add( IO_MGR::ShowType( IO_MGR::KICAD ) );
+ choices.Add( IO_MGR::ShowType( IO_MGR::GITHUB ) );
+ choices.Add( IO_MGR::ShowType( IO_MGR::LEGACY ) );
+ choices.Add( IO_MGR::ShowType( IO_MGR::EAGLE ) );
+ choices.Add( IO_MGR::ShowType( IO_MGR::GEDA_PCB ) );
+
+ /* PCAD_PLUGIN does not support Footprint*() functions
+ choices.Add( IO_MGR::ShowType( IO_MGR::GITHUB ) );
+ */
+
+ wxGridCellAttr* attr;
+
+ attr = new wxGridCellAttr;
+ attr->SetEditor( new wxGridCellChoiceEditor( choices ) );
+ m_project_grid->SetColAttr( COL_TYPE, attr );
+
+ attr = new wxGridCellAttr;
+ attr->SetEditor( new wxGridCellChoiceEditor( choices ) );
+ m_global_grid->SetColAttr( COL_TYPE, attr );
+
+ populateEnvironReadOnlyTable();
+
+ for( int i=0; i<2; ++i )
+ {
+ wxGrid* g = i==0 ? m_global_grid : m_project_grid;
+
+ // all but COL_OPTIONS, which is edited with Option Editor anyways.
+ g->AutoSizeColumn( COL_NICKNAME, false );
+ g->AutoSizeColumn( COL_TYPE, false );
+ g->AutoSizeColumn( COL_URI, false );
+ g->AutoSizeColumn( COL_DESCR, false );
+
+ // would set this to width of title, if it was easily known.
+ g->SetColSize( COL_OPTIONS, 80 );
+ }
+
+ // This scrunches the dialog hideously, probably due to wxAUI container.
+ // Fit();
+ // We derive from DIALOG_SHIM so prior size will be used anyways.
+
+ // select the last selected page
+ m_auinotebook->SetSelection( m_pageNdx );
+
+ // fire pageChangedHandler() so m_cur_grid gets set
+ // m_auinotebook->SetSelection will generate a pageChangedHandler()
+ // event call later, but too late.
+ wxAuiNotebookEvent uneventful;
+ pageChangedHandler( uneventful );
+
+ // Gives a selection for each grid, mainly for delete lib button.
+ // Without that, we do not see what lib will be deleted
+ m_global_grid->SelectRow(0);
+ m_project_grid->SelectRow(0);
+
+ // for ALT+A handling, we want the initial focus to be on the first selected grid.
+ m_cur_grid->SetFocus();
+
+ // On some windows manager (Unity, XFCE), this dialog is
+ // not always raised, depending on this dialog is run.
+ // Force it to be raised
+ Raise();
+ }
+
+ ~DIALOG_FP_LIB_TABLE()
+ {
+ // Delete the GRID_TRICKS.
+ // Any additional event handlers should be popped before the window is deleted.
+ m_global_grid->PopEventHandler( true );
+ m_project_grid->PopEventHandler( true );
+ }
+
+
+private:
+ typedef FP_LIB_TABLE::ROW ROW;
+
+ /// If the cursor is not on a valid cell, because there are no rows at all, return -1,
+ /// else return a 0 based column index.
+ int getCursorCol() const
+ {
+ return m_cur_grid->GetGridCursorCol();
+ }
+
+ /// If the cursor is not on a valid cell, because there are no rows at all, return -1,
+ /// else return a 0 based row index.
+ int getCursorRow() const
+ {
+ return m_cur_grid->GetGridCursorRow();
+ }
+
+ /**
+ * Function verifyTables
+ * trims important fields, removes blank row entries, and checks for duplicates.
+ * @return bool - true if tables are OK, else false.
+ */
+ bool verifyTables()
+ {
+ for( int t=0; t<2; ++t )
+ {
+ FP_TBL_MODEL& model = t==0 ? *global_model() : *project_model();
+
+ for( int r = 0; r < model.GetNumberRows(); )
+ {
+ wxString nick = model.GetValue( r, COL_NICKNAME ).Trim( false ).Trim();
+ wxString uri = model.GetValue( r, COL_URI ).Trim( false ).Trim();
+
+ if( !nick || !uri )
+ {
+ // Delete the "empty" row, where empty means missing nick or uri.
+ // This also updates the UI which could be slow, but there should only be a few
+ // rows to delete, unless the user fell asleep on the Add Row
+ // button.
+ model.DeleteRows( r, 1 );
+ }
+ else if( nick.find(':') != size_t(-1) )
+ {
+ wxString msg = wxString::Format(
+ _( "Illegal character '%s' found in Nickname: '%s' in row %d" ),
+ wxT( ":" ), GetChars( nick ), r );
+
+ // show the tabbed panel holding the grid we have flunked:
+ if( &model != cur_model() )
+ {
+ m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 );
+ }
+
+ // go to the problematic row
+ m_cur_grid->SetGridCursor( r, 0 );
+ m_cur_grid->SelectBlock( r, 0, r, 0 );
+ m_cur_grid->MakeCellVisible( r, 0 );
+
+ wxMessageDialog errdlg( this, msg, _( "No Colon in Nicknames" ) );
+ errdlg.ShowModal();
+ return false;
+ }
+ else
+ {
+ // set the trimmed values back into the table so they get saved to disk.
+ model.SetValue( r, COL_NICKNAME, nick );
+ model.SetValue( r, COL_URI, uri );
+ ++r; // this row was OK.
+ }
+ }
+ }
+
+ // check for duplicate nickNames, separately in each table.
+ for( int t=0; t<2; ++t )
+ {
+ FP_TBL_MODEL& model = t==0 ? *global_model() : *project_model();
+
+ for( int r1 = 0; r1 < model.GetNumberRows() - 1; ++r1 )
+ {
+ wxString nick1 = model.GetValue( r1, COL_NICKNAME );
+
+ for( int r2=r1+1; r2 < model.GetNumberRows(); ++r2 )
+ {
+ wxString nick2 = model.GetValue( r2, COL_NICKNAME );
+
+ if( nick1 == nick2 )
+ {
+ wxString msg = wxString::Format(
+ _( "Duplicate Nickname: '%s' in rows %d and %d" ),
+ GetChars( nick1 ), r1+1, r2+1
+ );
+
+ // show the tabbed panel holding the grid we have flunked:
+ if( &model != cur_model() )
+ {
+ m_auinotebook->SetSelection( &model == global_model() ? 0 : 1 );
+ }
+
+ // go to the lower of the two rows, it is technically the duplicate:
+ m_cur_grid->SetGridCursor( r2, 0 );
+ m_cur_grid->SelectBlock( r2, 0, r2, 0 );
+ m_cur_grid->MakeCellVisible( r2, 0 );
+
+ wxMessageDialog errdlg( this, msg, _( "Please Delete or Modify One" ) );
+ errdlg.ShowModal();
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ //-----<event handlers>----------------------------------
+
+ void onKeyDown( wxKeyEvent& ev )
+ {
+#if 0
+ // send the key to the current grid
+ ((wxEvtHandler*)m_cur_grid)->ProcessEvent( ev );
+#else
+ // or no:
+ // m_cur_grid has the focus most of the time anyways, so above not needed.
+ ev.Skip();
+#endif
+ }
+
+ void pageChangedHandler( wxAuiNotebookEvent& event )
+ {
+ m_pageNdx = m_auinotebook->GetSelection();
+ m_cur_grid = ( m_pageNdx == 0 ) ? m_global_grid : m_project_grid;
+ }
+
+ void appendRowHandler( wxCommandEvent& event )
+ {
+ if( m_cur_grid->AppendRows( 1 ) )
+ {
+ int last_row = m_cur_grid->GetNumberRows() - 1;
+
+ // wx documentation is wrong, SetGridCursor does not make visible.
+ m_cur_grid->MakeCellVisible( last_row, 0 );
+ m_cur_grid->SetGridCursor( last_row, 0 );
+ m_cur_grid->SelectRow( m_cur_grid->GetGridCursorRow() );
+ }
+ }
+
+ void deleteRowHandler( wxCommandEvent& event )
+ {
+#if 1
+ int currRow = getCursorRow();
+ wxArrayInt selectedRows = m_cur_grid->GetSelectedRows();
+
+ if( selectedRows.size() == 0 && getCursorRow() >= 0 )
+ selectedRows.Add( getCursorRow() );
+
+ std::sort( selectedRows.begin(), selectedRows.end() );
+
+ for( int ii = selectedRows.GetCount()-1; ii >= 0; ii-- )
+ {
+ int row = selectedRows[ii];
+ m_cur_grid->DeleteRows( row, 1 );
+ }
+
+ if( currRow >= m_cur_grid->GetNumberRows() )
+ m_cur_grid->SetGridCursor(m_cur_grid->GetNumberRows()-1, getCursorCol() );
+
+ m_cur_grid->SelectRow( m_cur_grid->GetGridCursorRow() );
+#else
+ int rowCount = m_cur_grid->GetNumberRows();
+ int curRow = getCursorRow();
+
+ if( curRow >= 0 )
+ {
+ m_cur_grid->DeleteRows( curRow );
+
+ if( curRow && curRow == rowCount - 1 )
+ {
+ m_cur_grid->SetGridCursor( curRow-1, getCursorCol() );
+ }
+ }
+#endif
+ }
+
+ void moveUpHandler( wxCommandEvent& event )
+ {
+ int curRow = getCursorRow();
+ if( curRow >= 1 )
+ {
+ int curCol = getCursorCol();
+
+ FP_TBL_MODEL* tbl = cur_model();
+
+ ROW move_me = tbl->rows[curRow];
+
+ tbl->rows.erase( tbl->rows.begin() + curRow );
+ --curRow;
+ tbl->rows.insert( tbl->rows.begin() + curRow, move_me );
+
+ if( tbl->GetView() )
+ {
+ // fire a msg to cause redrawing
+ wxGridTableMessage msg( tbl,
+ wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
+ curRow,
+ 0 );
+
+ tbl->GetView()->ProcessTableMessage( msg );
+ }
+
+ m_cur_grid->MakeCellVisible( curRow, curCol );
+ m_cur_grid->SetGridCursor( curRow, curCol );
+ m_cur_grid->SelectRow( getCursorRow() );
+ }
+ }
+
+ void moveDownHandler( wxCommandEvent& event )
+ {
+ FP_TBL_MODEL* tbl = cur_model();
+
+ int curRow = getCursorRow();
+ if( unsigned( curRow + 1 ) < tbl->rows.size() )
+ {
+ int curCol = getCursorCol();
+
+ ROW move_me = tbl->rows[curRow];
+
+ tbl->rows.erase( tbl->rows.begin() + curRow );
+ ++curRow;
+ tbl->rows.insert( tbl->rows.begin() + curRow, move_me );
+
+ if( tbl->GetView() )
+ {
+ // fire a msg to cause redrawing
+ wxGridTableMessage msg( tbl,
+ wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
+ curRow - 1,
+ 0 );
+
+ tbl->GetView()->ProcessTableMessage( msg );
+ }
+
+ m_cur_grid->MakeCellVisible( curRow, curCol );
+ m_cur_grid->SetGridCursor( curRow, curCol );
+ m_cur_grid->SelectRow( getCursorRow() );
+ }
+ }
+
+ void optionsEditor( wxCommandEvent& event )
+ {
+ FP_TBL_MODEL* tbl = cur_model();
+
+ if( tbl->GetNumberRows() )
+ {
+ int curRow = getCursorRow();
+ ROW& row = tbl->rows[curRow];
+
+ wxString result;
+ const wxString& options = row.GetOptions();
+
+ InvokePluginOptionsEditor( this, row.GetNickName(), row.GetType(), options, &result );
+
+ if( options != result )
+ {
+ row.SetOptions( result );
+
+ // all but options:
+ m_cur_grid->AutoSizeColumn( COL_NICKNAME, false );
+ m_cur_grid->AutoSizeColumn( COL_URI, false );
+ m_cur_grid->AutoSizeColumn( COL_TYPE, false );
+
+ // On Windows, the grid is not refresh,
+ // so force resfresh after a change
+#ifdef __WINDOWS__
+ Refresh();
+#endif
+ }
+ }
+ }
+
+ void OnClickLibraryWizard( wxCommandEvent& event );
+
+ void onCancelButtonClick( wxCommandEvent& event )
+ {
+ EndModal( 0 );
+ }
+
+ void onCancelCaptionButtonClick( wxCloseEvent& event )
+ {
+ EndModal( 0 );
+ }
+
+ void onOKButtonClick( wxCommandEvent& event )
+ {
+ int dialogRet = 0;
+
+ // stuff any pending cell editor text into the table.
+ m_cur_grid->SaveEditControlValue();
+
+ if( verifyTables() )
+ {
+ if( *global_model() != *m_global )
+ {
+ dialogRet |= 1;
+
+ *m_global = *global_model();
+ m_global->reindex();
+ }
+
+ if( *project_model() != *m_project )
+ {
+ dialogRet |= 2;
+
+ *m_project = *project_model();
+ m_project->reindex();
+ }
+
+ EndModal( dialogRet );
+ }
+ }
+
+ /// Populate the readonly environment variable table with names and values
+ /// by examining all the full_uri columns.
+ void populateEnvironReadOnlyTable()
+ {
+ wxRegEx re( wxT( ".*?\\$\\{(.+?)\\}.*?" ), wxRE_ADVANCED );
+ wxASSERT( re.IsValid() ); // wxRE_ADVANCED is required.
+
+ std::set< wxString > unique;
+ typedef std::set<wxString>::const_iterator SET_CITER;
+
+ // clear the table
+ m_path_subs_grid->DeleteRows( 0, m_path_subs_grid->GetNumberRows() );
+
+ FP_TBL_MODEL* gbl = global_model();
+ FP_TBL_MODEL* prj = project_model();
+
+ int gblRowCount = gbl->GetNumberRows();
+ int prjRowCount = prj->GetNumberRows();
+ int row;
+
+ for( row = 0; row < gblRowCount; ++row )
+ {
+ wxString uri = gbl->GetValue( row, COL_URI );
+
+ while( re.Matches( uri ) )
+ {
+ wxString envvar = re.GetMatch( uri, 1 );
+
+ // ignore duplicates
+ unique.insert( envvar );
+
+ // delete the last match and search again
+ uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
+ }
+ }
+
+ for( row = 0; row < prjRowCount; ++row )
+ {
+ wxString uri = prj->GetValue( row, COL_URI );
+
+ while( re.Matches( uri ) )
+ {
+ wxString envvar = re.GetMatch( uri, 1 );
+
+ // ignore duplicates
+ unique.insert( envvar );
+
+ // delete the last match and search again
+ uri.Replace( re.GetMatch( uri, 0 ), wxEmptyString );
+ }
+ }
+
+ // Make sure this special environment variable shows up even if it was
+ // not used yet. It is automatically set by KiCad to the directory holding
+ // the current project.
+ unique.insert( PROJECT_VAR_NAME );
+ unique.insert( FP_LIB_TABLE::GlobalPathEnvVariableName() );
+ // This special environment variable is used to locate 3d shapes
+ unique.insert( KISYS3DMOD );
+
+ m_path_subs_grid->AppendRows( unique.size() );
+
+ row = 0;
+ for( SET_CITER it = unique.begin(); it != unique.end(); ++it, ++row )
+ {
+ wxString evName = *it;
+ wxString evValue;
+
+ m_path_subs_grid->SetCellValue( row, 0, evName );
+
+ if( wxGetEnv( evName, &evValue ) )
+ m_path_subs_grid->SetCellValue( row, 1, evValue );
+ }
+
+ m_path_subs_grid->AutoSizeColumns();
+ }
+
+ //-----</event handlers>---------------------------------
+
+ // caller's tables are modified only on OK button and successful verification.
+ FP_LIB_TABLE* m_global;
+ FP_LIB_TABLE* m_project;
+
+ FP_TBL_MODEL* global_model() const { return (FP_TBL_MODEL*) m_global_grid->GetTable(); }
+ FP_TBL_MODEL* project_model() const { return (FP_TBL_MODEL*) m_project_grid->GetTable(); }
+ FP_TBL_MODEL* cur_model() const { return (FP_TBL_MODEL*) m_cur_grid->GetTable(); }
+
+ wxGrid* m_cur_grid; ///< changed based on tab choice
+ static int m_pageNdx; ///< Remember the last notebook page selected during a session
+};
+
+int DIALOG_FP_LIB_TABLE::m_pageNdx = 0;
+
+
+void DIALOG_FP_LIB_TABLE::OnClickLibraryWizard( wxCommandEvent& event )
+{
+ WIZARD_FPLIB_TABLE dlg( this );
+
+ if( !dlg.RunWizard( dlg.GetFirstPage() ) )
+ return; // Aborted by user
+
+ const std::vector<WIZARD_FPLIB_TABLE::LIBRARY>& libs = dlg.GetLibraries();
+ bool global_scope = dlg.GetLibScope() == WIZARD_FPLIB_TABLE::GLOBAL;
+ wxGrid* libgrid = global_scope ? m_global_grid : m_project_grid;
+ FP_TBL_MODEL* tbl = (FP_TBL_MODEL*) libgrid->GetTable();
+
+ for( std::vector<WIZARD_FPLIB_TABLE::LIBRARY>::const_iterator it = libs.begin();
+ it != libs.end(); ++it )
+ {
+ if( it->GetStatus() == WIZARD_FPLIB_TABLE::LIBRARY::INVALID )
+ continue;
+
+ if( libgrid->AppendRows( 1 ) )
+ {
+ int last_row = libgrid->GetNumberRows() - 1;
+
+ // Add the nickname: currently make it from filename
+ tbl->SetValue( last_row, COL_NICKNAME, it->GetDescription() );
+
+ // Add the path:
+ tbl->SetValue( last_row, COL_URI, it->GetAutoPath( dlg.GetLibScope() ) );
+
+ // Add the plugin name:
+ tbl->SetValue( last_row, COL_TYPE, it->GetPluginName() );
+
+ libgrid->MakeCellVisible( last_row, 0 );
+ libgrid->SetGridCursor( last_row, 0 );
+ }
+ }
+
+ // Switch to the current scope tab
+ if( global_scope )
+ m_auinotebook->SetSelection( 0 );
+ else
+ m_auinotebook->SetSelection( 1 );
+
+ libgrid->SelectRow( libgrid->GetGridCursorRow() );
+}
+
+
+int InvokePcbLibTableEditor( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject )
+{
+ DIALOG_FP_LIB_TABLE dlg( aParent, aGlobal, aProject );
+
+ int dialogRet = dlg.ShowModal(); // returns value passed to EndModal() above
+
+ return dialogRet;
+}
+
+
+int InvokeFootprintWizard( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject )
+{
+ WIZARD_FPLIB_TABLE dlg( aParent );
+
+ if( !dlg.RunWizard( dlg.GetFirstPage() ) )
+ return 0; // Aborted by user
+
+ const std::vector<WIZARD_FPLIB_TABLE::LIBRARY>& libs = dlg.GetLibraries();
+ WIZARD_FPLIB_TABLE::LIB_SCOPE scope = dlg.GetLibScope();
+ FP_LIB_TABLE* fp_tbl = ( scope == WIZARD_FPLIB_TABLE::GLOBAL ? aGlobal : aProject );
+
+ if( fp_tbl )
+ {
+ for( std::vector<WIZARD_FPLIB_TABLE::LIBRARY>::const_iterator it = libs.begin();
+ it != libs.end(); ++it )
+ {
+ if( it->GetStatus() == WIZARD_FPLIB_TABLE::LIBRARY::INVALID )
+ continue;
+
+ FP_LIB_TABLE::ROW row( it->GetDescription(),
+ it->GetAutoPath( scope ),
+ it->GetPluginName(),
+ wxEmptyString ); // options
+ fp_tbl->InsertRow( row );
+ }
+ }
+
+ return scope;
+}
diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.cpp b/pcbnew/dialogs/dialog_fp_lib_table_base.cpp
new file mode 100644
index 0000000..9b1f611
--- /dev/null
+++ b/pcbnew/dialogs/dialog_fp_lib_table_base.cpp
@@ -0,0 +1,256 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_fp_lib_table_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizer1;
+ bSizer1 = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* m_top_sizer;
+ m_top_sizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Library Tables by Scope") ), wxVERTICAL );
+
+ m_auinotebook = new wxAuiNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_BOTTOM );
+ m_global_panel = new wxPanel( m_auinotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* m_global_sizer;
+ m_global_sizer = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 1, 2, 0, 0 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText3 = new wxStaticText( m_global_panel, wxID_ANY, _("Table:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ fgSizer1->Add( m_staticText3, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_GblTableFilename = new wxStaticText( m_global_panel, wxID_ANY, _("Table Name"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_GblTableFilename->Wrap( -1 );
+ fgSizer1->Add( m_GblTableFilename, 0, wxRIGHT|wxLEFT, 5 );
+
+
+ m_global_sizer->Add( fgSizer1, 0, wxEXPAND, 5 );
+
+ m_global_grid = new wxGrid( m_global_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_global_grid->CreateGrid( 1, 5 );
+ m_global_grid->EnableEditing( true );
+ m_global_grid->EnableGridLines( true );
+ m_global_grid->EnableDragGridSize( false );
+ m_global_grid->SetMargins( 0, 0 );
+
+ // Columns
+ m_global_grid->AutoSizeColumns();
+ m_global_grid->EnableDragColMove( false );
+ m_global_grid->EnableDragColSize( true );
+ m_global_grid->SetColLabelSize( 30 );
+ m_global_grid->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_global_grid->EnableDragRowSize( false );
+ m_global_grid->SetRowLabelSize( 40 );
+ m_global_grid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_global_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ m_global_sizer->Add( m_global_grid, 1, wxALL|wxEXPAND, 5 );
+
+
+ m_global_panel->SetSizer( m_global_sizer );
+ m_global_panel->Layout();
+ m_global_sizer->Fit( m_global_panel );
+ m_auinotebook->AddPage( m_global_panel, _("Global Libraries"), true, wxNullBitmap );
+ m_project_panel = new wxPanel( m_auinotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* m_project_sizer;
+ m_project_sizer = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer2;
+ fgSizer2 = new wxFlexGridSizer( 1, 2, 0, 0 );
+ fgSizer2->SetFlexibleDirection( wxBOTH );
+ fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText4 = new wxStaticText( m_project_panel, wxID_ANY, _("Table:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText4->Wrap( -1 );
+ fgSizer2->Add( m_staticText4, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_PrjTableFilename = new wxStaticText( m_project_panel, wxID_ANY, _("Table Name"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PrjTableFilename->Wrap( -1 );
+ fgSizer2->Add( m_PrjTableFilename, 0, wxRIGHT|wxLEFT, 5 );
+
+
+ m_project_sizer->Add( fgSizer2, 0, wxEXPAND, 5 );
+
+ m_project_grid = new wxGrid( m_project_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_project_grid->CreateGrid( 1, 5 );
+ m_project_grid->EnableEditing( true );
+ m_project_grid->EnableGridLines( true );
+ m_project_grid->EnableDragGridSize( false );
+ m_project_grid->SetMargins( 0, 0 );
+
+ // Columns
+ m_project_grid->AutoSizeColumns();
+ m_project_grid->EnableDragColMove( false );
+ m_project_grid->EnableDragColSize( true );
+ m_project_grid->SetColLabelSize( 30 );
+ m_project_grid->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_project_grid->EnableDragRowSize( false );
+ m_project_grid->SetRowLabelSize( 40 );
+ m_project_grid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_project_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ m_project_sizer->Add( m_project_grid, 1, wxALL|wxEXPAND, 5 );
+
+
+ m_project_panel->SetSizer( m_project_sizer );
+ m_project_panel->Layout();
+ m_project_sizer->Fit( m_project_panel );
+ m_auinotebook->AddPage( m_project_panel, _("Project Specific Libraries"), false, wxNullBitmap );
+
+ m_top_sizer->Add( m_auinotebook, 6, wxEXPAND | wxALL, 5 );
+
+ wxBoxSizer* bSizer51;
+ bSizer51 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_buttonWizard = new wxButton( this, wxID_ANY, _("Append with Wizard"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer51->Add( m_buttonWizard, 0, wxALL, 5 );
+
+ m_append_button = new wxButton( this, wxID_ANY, _("Append Library"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_append_button->SetToolTip( _("Add a PCB library row to this table") );
+
+ bSizer51->Add( m_append_button, 0, wxALL, 5 );
+
+ m_delete_button = new wxButton( this, wxID_ANY, _("Remove Library"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_delete_button->SetToolTip( _("Remove a PCB library from this library table") );
+
+ bSizer51->Add( m_delete_button, 0, wxALL, 5 );
+
+ m_move_up_button = new wxButton( this, wxID_ANY, _("Move Up"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_move_up_button->SetToolTip( _("Move the currently selected row up one position") );
+
+ bSizer51->Add( m_move_up_button, 0, wxALL, 5 );
+
+ m_move_down_button = new wxButton( this, wxID_ANY, _("Move Down"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_move_down_button->SetToolTip( _("Move the currently selected row down one position") );
+
+ bSizer51->Add( m_move_down_button, 0, wxALL, 5 );
+
+ m_edit_options = new wxButton( this, wxID_ANY, _("Options Editor"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_edit_options->SetToolTip( _("Zoom into the options table for current row") );
+
+ bSizer51->Add( m_edit_options, 0, wxALL, 5 );
+
+
+ m_top_sizer->Add( bSizer51, 0, wxALIGN_CENTER|wxBOTTOM, 8 );
+
+
+ bSizer1->Add( m_top_sizer, 1, wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbSizer1;
+ sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Path Substitutions") ), wxVERTICAL );
+
+ m_path_subs_grid = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_path_subs_grid->CreateGrid( 1, 2 );
+ m_path_subs_grid->EnableEditing( false );
+ m_path_subs_grid->EnableGridLines( true );
+ m_path_subs_grid->EnableDragGridSize( false );
+ m_path_subs_grid->SetMargins( 0, 0 );
+
+ // Columns
+ m_path_subs_grid->SetColSize( 0, 150 );
+ m_path_subs_grid->SetColSize( 1, 500 );
+ m_path_subs_grid->AutoSizeColumns();
+ m_path_subs_grid->EnableDragColMove( false );
+ m_path_subs_grid->EnableDragColSize( true );
+ m_path_subs_grid->SetColLabelSize( 30 );
+ m_path_subs_grid->SetColLabelValue( 0, _("Environment Variable") );
+ m_path_subs_grid->SetColLabelValue( 1, _("Path Segment") );
+ m_path_subs_grid->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_path_subs_grid->EnableDragRowSize( true );
+ m_path_subs_grid->SetRowLabelSize( 40 );
+ m_path_subs_grid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_path_subs_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ m_path_subs_grid->SetToolTip( _("This is a read-only table which shows pertinent environment variables.") );
+
+ sbSizer1->Add( m_path_subs_grid, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizer1->Add( sbSizer1, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* m_bottom_sizer;
+ m_bottom_sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ m_bottom_sizer->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizer1->Add( m_bottom_sizer, 0, wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizer1 );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_FP_LIB_TABLE_BASE::onCancelCaptionButtonClick ) );
+ this->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_FP_LIB_TABLE_BASE::onKeyDown ) );
+ m_auinotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( DIALOG_FP_LIB_TABLE_BASE::pageChangedHandler ), NULL, this );
+ m_buttonWizard->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::OnClickLibraryWizard ), NULL, this );
+ m_append_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::appendRowHandler ), NULL, this );
+ m_delete_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::deleteRowHandler ), NULL, this );
+ m_move_up_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveUpHandler ), NULL, this );
+ m_move_down_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveDownHandler ), NULL, this );
+ m_edit_options->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::optionsEditor ), NULL, this );
+ m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::onCancelButtonClick ), NULL, this );
+ m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::onOKButtonClick ), NULL, this );
+}
+
+DIALOG_FP_LIB_TABLE_BASE::~DIALOG_FP_LIB_TABLE_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_FP_LIB_TABLE_BASE::onCancelCaptionButtonClick ) );
+ this->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_FP_LIB_TABLE_BASE::onKeyDown ) );
+ m_auinotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( DIALOG_FP_LIB_TABLE_BASE::pageChangedHandler ), NULL, this );
+ m_buttonWizard->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::OnClickLibraryWizard ), NULL, this );
+ m_append_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::appendRowHandler ), NULL, this );
+ m_delete_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::deleteRowHandler ), NULL, this );
+ m_move_up_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveUpHandler ), NULL, this );
+ m_move_down_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveDownHandler ), NULL, this );
+ m_edit_options->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::optionsEditor ), NULL, this );
+ m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::onCancelButtonClick ), NULL, this );
+ m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::onOKButtonClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.fbp b/pcbnew/dialogs/dialog_fp_lib_table_base.fbp
new file mode 100644
index 0000000..94152fa
--- /dev/null
+++ b/pcbnew/dialogs/dialog_fp_lib_table_base.fbp
@@ -0,0 +1,1763 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_fp_lib_table_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">MyProject1</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">decl_pure_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_FP_LIB_TABLE_BASE</property>
+ <property name="pos"></property>
+ <property name="size">717,600</property>
+ <property name="style">wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">PCB Library Tables</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">onCancelCaptionButtonClick</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown">onKeyDown</event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer1</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Library Tables by Scope</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_top_sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">6</property>
+ <object class="wxAuiNotebook" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_auinotebook</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxAUI_NB_BOTTOM</property>
+ <property name="subclass"></property>
+ <property name="tab_ctrl_height">-1</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="uniform_bitmap_size"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnAuiNotebookAllowDND"></event>
+ <event name="OnAuiNotebookBeginDrag"></event>
+ <event name="OnAuiNotebookButton"></event>
+ <event name="OnAuiNotebookDragMotion"></event>
+ <event name="OnAuiNotebookEndDrag"></event>
+ <event name="OnAuiNotebookPageChanged">pageChangedHandler</event>
+ <event name="OnAuiNotebookPageChanging"></event>
+ <event name="OnAuiNotebookPageClose"></event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="auinotebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Global Libraries</property>
+ <property name="select">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">0</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_global_panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">0</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_global_sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">1</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Table:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Table Name</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_GblTableFilename</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">1</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg"></property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">30</property>
+ <property name="col_label_values"></property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">5</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">1</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">0</property>
+ <property name="editing">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">0</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">0</property>
+ <property name="name">m_global_grid</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Fixed</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">40</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick"></event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="auinotebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Project Specific Libraries</property>
+ <property name="select">0</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_project_panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_project_sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer2</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">1</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Table:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Table Name</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PrjTableFilename</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">1</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg"></property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">30</property>
+ <property name="col_label_values"></property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">5</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">1</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">0</property>
+ <property name="editing">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">0</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">0</property>
+ <property name="name">m_project_grid</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Fixed</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">40</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick"></event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">8</property>
+ <property name="flag">wxALIGN_CENTER|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer51</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Append with Wizard</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonWizard</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnClickLibraryWizard</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Append Library</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_append_button</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Add a PCB library row to this table</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">appendRowHandler</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Remove Library</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_delete_button</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Remove a PCB library from this library table</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">deleteRowHandler</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Move Up</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_move_up_button</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Move the currently selected row up one position</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">moveUpHandler</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Move Down</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_move_down_button</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Move the currently selected row down one position</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">moveDownHandler</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Options Editor</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_edit_options</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Zoom into the options table for current row</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">optionsEditor</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Path Substitutions</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizer1</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">1</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg"></property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">30</property>
+ <property name="col_label_values">&quot;Environment Variable&quot; &quot;Path Segment&quot;</property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">2</property>
+ <property name="column_sizes">150,500</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">1</property>
+ <property name="editing">0</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_path_subs_grid</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">40</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is a read-only table which shows pertinent environment variables.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick"></event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_bottom_sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="0">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">onCancelButtonClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">onOKButtonClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.h b/pcbnew/dialogs/dialog_fp_lib_table_base.h
new file mode 100644
index 0000000..b2e4932
--- /dev/null
+++ b/pcbnew/dialogs/dialog_fp_lib_table_base.h
@@ -0,0 +1,86 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_FP_LIB_TABLE_BASE_H__
+#define __DIALOG_FP_LIB_TABLE_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/grid.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/aui/auibook.h>
+#include <wx/button.h>
+#include <wx/statbox.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_FP_LIB_TABLE_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_FP_LIB_TABLE_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxAuiNotebook* m_auinotebook;
+ wxPanel* m_global_panel;
+ wxStaticText* m_staticText3;
+ wxStaticText* m_GblTableFilename;
+ wxGrid* m_global_grid;
+ wxPanel* m_project_panel;
+ wxStaticText* m_staticText4;
+ wxStaticText* m_PrjTableFilename;
+ wxGrid* m_project_grid;
+ wxButton* m_buttonWizard;
+ wxButton* m_append_button;
+ wxButton* m_delete_button;
+ wxButton* m_move_up_button;
+ wxButton* m_move_down_button;
+ wxButton* m_edit_options;
+ wxGrid* m_path_subs_grid;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void onCancelCaptionButtonClick( wxCloseEvent& event ) = 0;
+ virtual void onKeyDown( wxKeyEvent& event ) = 0;
+ virtual void pageChangedHandler( wxAuiNotebookEvent& event ) = 0;
+ virtual void OnClickLibraryWizard( wxCommandEvent& event ) = 0;
+ virtual void appendRowHandler( wxCommandEvent& event ) = 0;
+ virtual void deleteRowHandler( wxCommandEvent& event ) = 0;
+ virtual void moveUpHandler( wxCommandEvent& event ) = 0;
+ virtual void moveDownHandler( wxCommandEvent& event ) = 0;
+ virtual void optionsEditor( wxCommandEvent& event ) = 0;
+ virtual void onCancelButtonClick( wxCommandEvent& event ) = 0;
+ virtual void onOKButtonClick( wxCommandEvent& event ) = 0;
+
+
+ public:
+
+ DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("PCB Library Tables"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 717,600 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU );
+ ~DIALOG_FP_LIB_TABLE_BASE();
+
+};
+
+#endif //__DIALOG_FP_LIB_TABLE_BASE_H__
diff --git a/pcbnew/dialogs/dialog_fp_plugin_options.cpp b/pcbnew/dialogs/dialog_fp_plugin_options.cpp
new file mode 100644
index 0000000..316ce5a
--- /dev/null
+++ b/pcbnew/dialogs/dialog_fp_plugin_options.cpp
@@ -0,0 +1,399 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2013 CERN
+ * Copyright (C) 2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <invoke_pcb_dialog.h>
+#include <dialog_fp_plugin_options_base.h>
+#include <fp_lib_table.h>
+#include <grid_tricks.h>
+
+
+#define INITIAL_HELP \
+ _( "Select an <b>Option Choice</b> in the listbox above, and then click the <b>Append Selected Option</b> button." )
+
+
+using std::string;
+
+// re-enter the dialog with the column sizes preserved from last time.
+static int col_width_option;
+static int col_width_value;
+
+
+/**
+ * Class DIALOG_FP_PLUGIN_OPTIONS
+ * is an options editor in the form of a two column name/value
+ * spreadsheet like (table) UI. It takes hints from a pcbnew PLUGIN as to
+ * supported options.
+ */
+class DIALOG_FP_PLUGIN_OPTIONS : public DIALOG_FP_PLUGIN_OPTIONS_BASE
+{
+
+public:
+ DIALOG_FP_PLUGIN_OPTIONS( wxTopLevelWindow* aParent,
+ const wxString& aNickname, const wxString& aPluginType,
+ const wxString& aOptions, wxString* aResult ) :
+ DIALOG_FP_PLUGIN_OPTIONS_BASE( aParent ),
+ m_callers_options( aOptions ),
+ m_result( aResult ),
+ m_initial_help( INITIAL_HELP )
+ {
+ wxString title = wxString::Format(
+ _( "Options for Library '%s'" ), GetChars( aNickname ) );
+
+ SetTitle( title );
+
+ // add Cut, Copy, and Paste to wxGrid
+ m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
+
+ m_grid->SetColMinimalWidth( 1, 250 );
+
+ // Fill the grid with existing aOptions
+ string options = TO_UTF8( aOptions );
+
+ PROPERTIES* props = FP_LIB_TABLE::ParseOptions( options );
+
+ if( props )
+ {
+ if( (int) props->size() > m_grid->GetNumberRows() )
+ m_grid->AppendRows( props->size() - m_grid->GetNumberRows() );
+
+ int row = 0;
+ for( PROPERTIES::const_iterator it = props->begin(); it != props->end(); ++it, ++row )
+ {
+ m_grid->SetCellValue( row, 0, FROM_UTF8( it->first.c_str() ) );
+ m_grid->SetCellValue( row, 1, it->second );
+ }
+
+ delete props;
+ }
+
+ // Option Choices Panel:
+
+ IO_MGR::PCB_FILE_T pi_type = IO_MGR::EnumFromStr( aPluginType );
+ PLUGIN::RELEASER pi( IO_MGR::PluginFind( pi_type ) );
+
+ pi->FootprintLibOptions( &m_choices );
+
+ if( m_choices.size() )
+ {
+ int row = 0;
+ for( PROPERTIES::const_iterator it = m_choices.begin(); it != m_choices.end(); ++it, ++row )
+ {
+ wxString item = FROM_UTF8( it->first.c_str() );
+
+ m_listbox->InsertItems( 1, &item, row );
+ }
+ }
+
+ m_html->SetPage( m_initial_help );
+
+ if( !col_width_option )
+ {
+ m_grid->AutoSizeColumns( false );
+ }
+ else
+ {
+ m_grid->SetColSize( 0, col_width_option );
+ m_grid->SetColSize( 1, col_width_value );
+ }
+
+ Fit();
+
+ // initial focus on the grid please.
+ m_grid->SetFocus();
+ }
+
+ ~DIALOG_FP_PLUGIN_OPTIONS()
+ {
+ // destroy GRID_TRICKS before m_grid.
+ m_grid->PopEventHandler( true );
+ }
+
+
+private:
+ const wxString& m_callers_options;
+ wxString* m_result;
+ PROPERTIES m_choices;
+ wxString m_initial_help;
+
+
+ /// If the cursor is not on a valid cell, because there are no rows at all, return -1,
+ /// else return a 0 based column index.
+ int getCursorCol() const
+ {
+ return m_grid->GetGridCursorCol();
+ }
+
+ /// If the cursor is not on a valid cell, because there are no rows at all, return -1,
+ /// else return a 0 based row index.
+ int getCursorRow() const
+ {
+ return m_grid->GetGridCursorRow();
+ }
+
+ wxArrayString getRow( int aRow )
+ {
+ wxArrayString row;
+
+ const int col_count = m_grid->GetNumberCols();
+ for( int col = 0; col < col_count; ++col )
+ {
+ row.Add( m_grid->GetCellValue( aRow, col ) );
+ }
+
+ return row;
+ }
+
+ void setRow( int aRow, const wxArrayString& aPair )
+ {
+ const int col_count = m_grid->GetNumberCols();
+ for( int col = 0; col < col_count; ++col )
+ {
+ m_grid->SetCellValue( aRow, col, aPair[col] );
+ }
+ }
+
+ wxString makeResult()
+ {
+ PROPERTIES props;
+ const int rowCount = m_grid->GetNumberRows();
+
+ for( int row = 0; row<rowCount; ++row )
+ {
+ string name = TO_UTF8( m_grid->GetCellValue( row, 0 ).Trim( false ).Trim() );
+ UTF8 value = m_grid->GetCellValue( row, 1 ).Trim( false ).Trim();
+
+ if( name.size() )
+ {
+ props[name] = value;
+ }
+ }
+
+ return FP_LIB_TABLE::FormatOptions( &props );
+ }
+
+ void saveColSizes()
+ {
+ col_width_option = m_grid->GetColSize( 0 );
+ col_width_value = m_grid->GetColSize( 1 );
+ }
+
+ void abort()
+ {
+ saveColSizes();
+
+ *m_result = m_callers_options; // tell caller "no change"
+ EndModal( 0 );
+ }
+
+ int appendRow()
+ {
+ if( m_grid->AppendRows( 1 ) )
+ {
+ int last_row = m_grid->GetNumberRows() - 1;
+
+ // wx documentation is wrong, SetGridCursor does not make visible.
+ m_grid->MakeCellVisible( last_row, 0 );
+ m_grid->SetGridCursor( last_row, 0 );
+
+ return last_row;
+ }
+
+ return -1;
+ }
+
+ void appendOption()
+ {
+ int selected_row = m_listbox->GetSelection();
+ if( selected_row != wxNOT_FOUND )
+ {
+ wxString option = m_listbox->GetString( selected_row );
+
+ int row_count = m_grid->GetNumberRows();
+ int row;
+
+ for( row=0; row<row_count; ++row )
+ {
+ wxString col0 = m_grid->GetCellValue( row, 0 );
+
+ if( !col0 ) // empty col0
+ break;
+ }
+
+ if( row == row_count )
+ row = appendRow();
+
+ m_grid->SetCellValue( row, 0, option );
+ m_grid->AutoSizeColumns( false );
+ }
+ }
+
+ //-----<event handlers>------------------------------------------------------
+
+ void onListBoxItemSelected( wxCommandEvent& event )
+ {
+ // change the help text based on the m_listbox selection:
+ if( event.IsSelection() )
+ {
+ string option = TO_UTF8( event.GetString() );
+ UTF8 help_text;
+
+ if( m_choices.Value( option.c_str(), &help_text ) )
+ {
+ wxString page = help_text;
+
+ m_html->SetPage( page );
+ }
+ else
+ {
+ m_html->SetPage( m_initial_help );
+ }
+ }
+ }
+
+ void onListBoxItemDoubleClicked( wxCommandEvent& event )
+ {
+ appendOption();
+ }
+
+ void onAppendOption( wxCommandEvent& event )
+ {
+ appendOption();
+ }
+
+ void onAppendRow( wxMouseEvent& event )
+ {
+ appendRow();
+ }
+
+ void onDeleteRow( wxMouseEvent& event )
+ {
+ int rowCount = m_grid->GetNumberRows();
+ int curRow = getCursorRow();
+
+ m_grid->DeleteRows( curRow );
+
+ if( curRow && curRow == rowCount - 1 )
+ {
+ m_grid->MakeCellVisible( curRow-1, getCursorCol() );
+ m_grid->SetGridCursor( curRow-1, getCursorCol() );
+ }
+ }
+
+ void onMoveUp( wxMouseEvent& event )
+ {
+ int curRow = getCursorRow();
+ if( curRow >= 1 )
+ {
+ int curCol = getCursorCol();
+
+ wxArrayString move_me = getRow( curRow );
+
+ m_grid->DeleteRows( curRow );
+ --curRow;
+ m_grid->InsertRows( curRow );
+
+ setRow( curRow, move_me );
+
+ wxGridTableBase* tbl = m_grid->GetTable();
+
+ if( tbl->GetView() )
+ {
+ // fire a msg to cause redrawing
+ wxGridTableMessage msg( tbl,
+ wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
+ curRow,
+ 0 );
+
+ tbl->GetView()->ProcessTableMessage( msg );
+ }
+
+ m_grid->MakeCellVisible( curRow, curCol );
+ m_grid->SetGridCursor( curRow, curCol );
+ }
+ }
+
+ void onMoveDown( wxMouseEvent& event )
+ {
+ int curRow = getCursorRow();
+ if( curRow + 1 < m_grid->GetNumberRows() )
+ {
+ int curCol = getCursorCol();
+
+ wxArrayString move_me = getRow( curRow );
+
+ m_grid->DeleteRows( curRow );
+ ++curRow;
+ m_grid->InsertRows( curRow );
+ setRow( curRow, move_me );
+
+ wxGridTableBase* tbl = m_grid->GetTable();
+
+ if( tbl->GetView() )
+ {
+ // fire a msg to cause redrawing
+ wxGridTableMessage msg( tbl,
+ wxGRIDTABLE_NOTIFY_ROWS_INSERTED,
+ curRow - 1,
+ 0 );
+
+ tbl->GetView()->ProcessTableMessage( msg );
+ }
+
+ m_grid->MakeCellVisible( curRow, curCol );
+ m_grid->SetGridCursor( curRow, curCol );
+ }
+ }
+
+ void onCancelButtonClick( wxCommandEvent& event )
+ {
+ abort();
+ }
+
+ void onCancelCaptionButtonClick( wxCloseEvent& event )
+ {
+ abort();
+ }
+
+ void onOKButtonClick( wxCommandEvent& event )
+ {
+ saveColSizes();
+
+ *m_result = makeResult(); // change from edits
+ EndModal( 1 );
+ }
+ //-----</event handlers>-----------------------------------------------------
+};
+
+
+void InvokePluginOptionsEditor( wxTopLevelWindow* aCaller,
+ const wxString& aNickname, const wxString& aPluginType,
+ const wxString& aOptions, wxString* aResult )
+{
+ DIALOG_FP_PLUGIN_OPTIONS dlg( aCaller, aNickname, aPluginType, aOptions, aResult );
+
+ dlg.ShowModal();
+}
diff --git a/pcbnew/dialogs/dialog_fp_plugin_options_base.cpp b/pcbnew/dialogs/dialog_fp_plugin_options_base.cpp
new file mode 100644
index 0000000..825d971
--- /dev/null
+++ b/pcbnew/dialogs/dialog_fp_plugin_options_base.cpp
@@ -0,0 +1,158 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_fp_plugin_options_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_FP_PLUGIN_OPTIONS_BASE::DIALOG_FP_PLUGIN_OPTIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* m_horizontal_sizer;
+ m_horizontal_sizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* m_grid_sizer;
+ m_grid_sizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Plugin Options:") ), wxVERTICAL );
+
+ m_grid_sizer->SetMinSize( wxSize( -1,300 ) );
+ m_grid = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL );
+
+ // Grid
+ m_grid->CreateGrid( 1, 2 );
+ m_grid->EnableEditing( true );
+ m_grid->EnableGridLines( true );
+ m_grid->EnableDragGridSize( false );
+ m_grid->SetMargins( 0, 0 );
+
+ // Columns
+ m_grid->EnableDragColMove( false );
+ m_grid->EnableDragColSize( true );
+ m_grid->SetColLabelSize( 30 );
+ m_grid->SetColLabelValue( 0, _("Option") );
+ m_grid->SetColLabelValue( 1, _("Value") );
+ m_grid->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_grid->EnableDragRowSize( false );
+ m_grid->SetRowLabelSize( 40 );
+ m_grid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ m_grid_sizer->Add( m_grid, 1, wxEXPAND|wxTOP, 5 );
+
+ wxBoxSizer* m_button_sizer;
+ m_button_sizer = new wxBoxSizer( wxHORIZONTAL );
+
+ m_add_row = new wxButton( this, wxID_ANY, _("Append"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_add_row->SetToolTip( _("Append a blank row") );
+
+ m_button_sizer->Add( m_add_row, 0, wxALL, 5 );
+
+ m_delete_row = new wxButton( this, wxID_ANY, _("Delete"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_delete_row->SetToolTip( _("Delete the selected row") );
+
+ m_button_sizer->Add( m_delete_row, 0, wxALL, 5 );
+
+ m_move_up = new wxButton( this, wxID_ANY, _("Move Up"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_move_up->SetToolTip( _("Move the selected row up one position") );
+
+ m_button_sizer->Add( m_move_up, 0, wxALL, 5 );
+
+ m_move_down = new wxButton( this, wxID_ANY, _("Move Down"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_move_down->SetToolTip( _("Move the selected row down one position") );
+
+ m_button_sizer->Add( m_move_down, 0, wxALL, 5 );
+
+
+ m_grid_sizer->Add( m_button_sizer, 0, wxALIGN_CENTER, 5 );
+
+
+ m_horizontal_sizer->Add( m_grid_sizer, 3, wxEXPAND, 5 );
+
+ wxGridSizer* m_choose_size;
+ m_choose_size = new wxGridSizer( 1, 1, 0, 0 );
+
+
+ m_horizontal_sizer->Add( m_choose_size, 0, wxEXPAND, 5 );
+
+ wxStaticBoxSizer* m_options_sizer;
+ m_options_sizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Option Choices:") ), wxVERTICAL );
+
+ m_options_sizer->SetMinSize( wxSize( 200,-1 ) );
+ m_listbox = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_ALWAYS_SB|wxLB_SINGLE );
+ m_listbox->SetToolTip( _("Options supported by current plugin") );
+
+ m_options_sizer->Add( m_listbox, 2, wxALL|wxEXPAND, 5 );
+
+ m_append_choice_button = new wxButton( this, wxID_ANY, _("<< Append Selected Option"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_options_sizer->Add( m_append_choice_button, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_staticText1 = new wxStaticText( this, wxID_ANY, _("Option Specific Help:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ m_options_sizer->Add( m_staticText1, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_html = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO|wxVSCROLL );
+ m_html->SetMinSize( wxSize( 300,300 ) );
+
+ m_options_sizer->Add( m_html, 3, wxALL|wxEXPAND, 5 );
+
+
+ m_horizontal_sizer->Add( m_options_sizer, 2, wxEXPAND, 5 );
+
+
+ bSizer4->Add( m_horizontal_sizer, 1, wxALL|wxEXPAND, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bSizer4->Add( m_sdbSizer1, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizer4 );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onCancelCaptionButtonClick ) );
+ m_add_row->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onAppendRow ), NULL, this );
+ m_delete_row->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onDeleteRow ), NULL, this );
+ m_move_up->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onMoveUp ), NULL, this );
+ m_move_down->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onMoveDown ), NULL, this );
+ m_listbox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onListBoxItemSelected ), NULL, this );
+ m_listbox->Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onListBoxItemDoubleClicked ), NULL, this );
+ m_append_choice_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onAppendOption ), NULL, this );
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onCancelButtonClick ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onOKButtonClick ), NULL, this );
+}
+
+DIALOG_FP_PLUGIN_OPTIONS_BASE::~DIALOG_FP_PLUGIN_OPTIONS_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onCancelCaptionButtonClick ) );
+ m_add_row->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onAppendRow ), NULL, this );
+ m_delete_row->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onDeleteRow ), NULL, this );
+ m_move_up->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onMoveUp ), NULL, this );
+ m_move_down->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onMoveDown ), NULL, this );
+ m_listbox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onListBoxItemSelected ), NULL, this );
+ m_listbox->Disconnect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onListBoxItemDoubleClicked ), NULL, this );
+ m_append_choice_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onAppendOption ), NULL, this );
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onCancelButtonClick ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_PLUGIN_OPTIONS_BASE::onOKButtonClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_fp_plugin_options_base.fbp b/pcbnew/dialogs/dialog_fp_plugin_options_base.fbp
new file mode 100644
index 0000000..afa1934
--- /dev/null
+++ b/pcbnew/dialogs/dialog_fp_plugin_options_base.fbp
@@ -0,0 +1,1027 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_fp_plugin_options_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_fp_plugin_options</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">decl_pure_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_FP_PLUGIN_OPTIONS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">678,342</property>
+ <property name="style">wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">onCancelCaptionButtonClick</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer4</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_horizontal_sizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">3</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Plugin Options:</property>
+ <property name="minimum_size">-1,300</property>
+ <property name="name">m_grid_sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">0</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg"></property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">30</property>
+ <property name="col_label_values">&quot;Option&quot; &quot;Value&quot;</property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">2</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">0</property>
+ <property name="editing">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_grid</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">40</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxVSCROLL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick"></event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_button_sizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Append</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_add_row</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Append a blank row</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick"></event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown">onAppendRow</event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Delete</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_delete_row</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Delete the selected row</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick"></event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown">onDeleteRow</event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Move Up</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_move_up</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Move the selected row up one position</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick"></event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown">onMoveUp</event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Move Down</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_move_down</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Move the selected row down one position</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick"></event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown">onMoveDown</event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxGridSizer" expanded="1">
+ <property name="cols">1</property>
+ <property name="hgap">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">m_choose_size</property>
+ <property name="permission">none</property>
+ <property name="rows">1</property>
+ <property name="vgap">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">2</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Option Choices:</property>
+ <property name="minimum_size">200,-1</property>
+ <property name="name">m_options_sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">2</property>
+ <object class="wxListBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_listbox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLB_ALWAYS_SB|wxLB_SINGLE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Options supported by current plugin</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBox">onListBoxItemSelected</event>
+ <event name="OnListBoxDClick">onListBoxItemDoubleClicked</event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&lt;&lt; Append Selected Option</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,-1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_append_choice_button</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">onAppendOption</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Option Specific Help:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">3</property>
+ <object class="wxHtmlWindow" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,-1</property>
+ <property name="min_size">300,300</property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">300,300</property>
+ <property name="moveable">1</property>
+ <property name="name">m_html</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxHW_SCROLLBAR_AUTO</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxVSCROLL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHtmlCellClicked"></event>
+ <event name="OnHtmlCellHover"></event>
+ <event name="OnHtmlLinkClicked"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">onCancelButtonClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">onOKButtonClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_fp_plugin_options_base.h b/pcbnew/dialogs/dialog_fp_plugin_options_base.h
new file mode 100644
index 0000000..659cc75
--- /dev/null
+++ b/pcbnew/dialogs/dialog_fp_plugin_options_base.h
@@ -0,0 +1,75 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_FP_PLUGIN_OPTIONS_BASE_H__
+#define __DIALOG_FP_PLUGIN_OPTIONS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/string.h>
+#include <wx/font.h>
+#include <wx/grid.h>
+#include <wx/gdicmn.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/listbox.h>
+#include <wx/stattext.h>
+#include <wx/html/htmlwin.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_FP_PLUGIN_OPTIONS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_FP_PLUGIN_OPTIONS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxGrid* m_grid;
+ wxButton* m_add_row;
+ wxButton* m_delete_row;
+ wxButton* m_move_up;
+ wxButton* m_move_down;
+ wxListBox* m_listbox;
+ wxButton* m_append_choice_button;
+ wxStaticText* m_staticText1;
+ wxHtmlWindow* m_html;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void onCancelCaptionButtonClick( wxCloseEvent& event ) = 0;
+ virtual void onAppendRow( wxMouseEvent& event ) = 0;
+ virtual void onDeleteRow( wxMouseEvent& event ) = 0;
+ virtual void onMoveUp( wxMouseEvent& event ) = 0;
+ virtual void onMoveDown( wxMouseEvent& event ) = 0;
+ virtual void onListBoxItemSelected( wxCommandEvent& event ) = 0;
+ virtual void onListBoxItemDoubleClicked( wxCommandEvent& event ) = 0;
+ virtual void onAppendOption( wxCommandEvent& event ) = 0;
+ virtual void onCancelButtonClick( wxCommandEvent& event ) = 0;
+ virtual void onOKButtonClick( wxCommandEvent& event ) = 0;
+
+
+ public:
+
+ DIALOG_FP_PLUGIN_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 678,342 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER );
+ ~DIALOG_FP_PLUGIN_OPTIONS_BASE();
+
+};
+
+#endif //__DIALOG_FP_PLUGIN_OPTIONS_BASE_H__
diff --git a/pcbnew/dialogs/dialog_freeroute_exchange.cpp b/pcbnew/dialogs/dialog_freeroute_exchange.cpp
new file mode 100644
index 0000000..f84bd7e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_freeroute_exchange.cpp
@@ -0,0 +1,208 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+/**
+ * @file dialog_freeroute_exchange.cpp
+ * Dialog to access to FreeRoute, the web bases free router, export/import files
+ * to/from FreeRoute
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <macros.h>
+#include <class_board.h>
+
+#include <../common/dialogs/dialog_display_info_HTML_base.h>
+
+#include <dialog_freeroute_exchange.h>
+
+#ifdef __WINDOWS__
+#include <wx/msw/registry.h>
+#endif
+
+
+void PCB_EDIT_FRAME::Access_to_External_Tool( wxCommandEvent& event )
+{
+ DIALOG_FREEROUTE dialog( this );
+ dialog.ShowModal();
+}
+
+
+
+DIALOG_FREEROUTE::DIALOG_FREEROUTE( PCB_EDIT_FRAME* parent ):
+ DIALOG_FREEROUTE_BASE( parent )
+{
+ m_Parent = parent;
+ MyInit();
+
+ m_sdbSizerOK->SetDefault();
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+
+
+// Specific data initialization
+void DIALOG_FREEROUTE::MyInit()
+{
+ SetFocus();
+ m_freeRouterFound = false;
+
+ wxFileName fileName( FindKicadFile( wxT( "freeroute.jar" ) ), wxPATH_UNIX );
+
+ if( fileName.FileExists() )
+ m_freeRouterFound = true;
+
+ m_buttonLaunchFreeroute->Enable( m_freeRouterFound );
+
+}
+
+const char * s_FreeRouteHelpInfo =
+#include <dialog_freeroute_exchange_help_html.h>
+;
+
+void DIALOG_FREEROUTE::OnHelpButtonClick( wxCommandEvent& event )
+{
+ DIALOG_DISPLAY_HTML_TEXT_BASE help_Dlg( this, wxID_ANY,
+ _("Freeroute Help"),wxDefaultPosition, wxSize( 650,550 ) );
+
+ wxString msg = FROM_UTF8(s_FreeRouteHelpInfo);
+ help_Dlg.m_htmlWindow->AppendToPage( msg );
+ help_Dlg.ShowModal();
+}
+
+
+void DIALOG_FREEROUTE::OnExportButtonClick( wxCommandEvent& event )
+{
+ m_Parent->ExportToSpecctra( event );
+}
+
+
+void DIALOG_FREEROUTE::OnImportButtonClick( wxCommandEvent& event )
+{
+ m_Parent->ImportSpecctraSession( event );
+
+ /* Connectivity must be rebuild.
+ * because for large board it can take some time, this is made only on demand
+ */
+ if( IsOK( this, _("Do you want to rebuild connectivity data ?" ) ) )
+ m_Parent->Compile_Ratsnest( NULL, true );
+}
+
+
+// Run freeroute, if it is available (freeroute.jar found in kicad binaries)
+void DIALOG_FREEROUTE::OnLaunchButtonClick( wxCommandEvent& event )
+{
+ wxString dsnFile;
+
+ if( m_freeRouterFound )
+ {
+ dsnFile = createDSN_File();
+
+ if( dsnFile.IsEmpty() ) // Something is wrong or command cancelled
+ return;
+ }
+
+ wxFileName jarfileName( FindKicadFile( wxT( "freeroute.jar" ) ), wxPATH_UNIX );
+ wxString command;
+
+ // Find the Java application on Windows.
+ // Colud be no more needed since we now have to run only java, not java web start
+#ifdef __WINDOWS__
+
+ // If you thought the registry was brain dead before, now you have to deal with
+ // accessing it in either 64 or 32 bit mode depending on the build version of
+ // Windows and the build version of KiCad.
+
+ // This key works for 32 bit Java on 32 bit Windows and 64 bit Java on 64 bit Windows.
+ wxString keyName = wxT( "SOFTWARE\\JavaSoft\\Java Runtime Environment" );
+ wxRegKey key( wxRegKey::HKLM, keyName,
+ wxIsPlatform64Bit() ? wxRegKey::WOW64ViewMode_64 :
+ wxRegKey::WOW64ViewMode_Default );
+
+ // It's possible that 32 bit Java is installed on 64 bit Windows.
+ if( !key.Exists() && wxIsPlatform64Bit() )
+ {
+ keyName = wxT( "SOFTWARE\\Wow6432Node\\JavaSoft\\Java Runtime Environment" );
+ key.SetName( wxRegKey::HKLM, keyName );
+ }
+
+ if( !key.Exists() )
+ {
+ ::wxMessageBox( _( "It appears that the Java run time environment is not "
+ "installed on this computer. Java is required to use "
+ "FreeRoute." ),
+ _( "Pcbnew Error" ), wxOK | wxICON_ERROR );
+ return;
+ }
+
+ key.Open( wxRegKey::Read );
+
+ // Get the current version of java installed to determine the executable path.
+ wxString value;
+ key.QueryValue( wxT( "CurrentVersion" ), value );
+ key.SetName( key.GetName() + wxT( "\\" ) + value );
+
+ key.QueryValue( wxT( "JavaHome" ), value );
+ command = value + wxFileName::GetPathSeparator();
+ command << wxT("bin\\java");
+#else // __WINDOWS__
+ command = wxT( "java" );
+#endif
+
+ command << wxT(" -jar ");
+ // add "freeroute.jar" to command line:
+ command << wxChar( '"' ) << jarfileName.GetFullPath() << wxChar( '"' );
+ // add option to load the .dsn file
+ command << wxT( " -de " );
+ // add *.dsn full filename (quoted):
+ command << wxChar( '"' ) << dsnFile << wxChar( '"' );
+
+ ProcessExecute( command );
+}
+
+const wxString DIALOG_FREEROUTE::createDSN_File()
+{
+ wxFileName fn( m_Parent->GetBoard()->GetFileName() );
+ wxString dsn_ext = wxT( "dsn" );
+ fn.SetExt( dsn_ext );
+ wxString mask = wxT( "*." ) + dsn_ext;
+
+ wxString fullFileName = EDA_FILE_SELECTOR( _( "Specctra DSN file:" ),
+ fn.GetPath(), fn.GetFullName(),
+ dsn_ext, mask,
+ this, wxFD_SAVE, false );
+
+ if( !fullFileName.IsEmpty() )
+ {
+ if( ! m_Parent->ExportSpecctraFile( fullFileName ) ) // the file was not created
+ return wxEmptyString;
+ }
+
+ return fullFileName;
+}
+
+
diff --git a/pcbnew/dialogs/dialog_freeroute_exchange.h b/pcbnew/dialogs/dialog_freeroute_exchange.h
new file mode 100644
index 0000000..1484a6f
--- /dev/null
+++ b/pcbnew/dialogs/dialog_freeroute_exchange.h
@@ -0,0 +1,54 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _DIALOG_FREEROUTE_EXCHANGE_H_
+#define _DIALOG_FREEROUTE_EXCHANGE_H_
+
+#include <dialog_freeroute_exchange_base.h>
+
+class DIALOG_FREEROUTE : public DIALOG_FREEROUTE_BASE
+{
+private:
+ PCB_EDIT_FRAME* m_Parent;
+ bool m_freeRouterFound;
+
+private:
+ // Virtual event handlers
+ void OnExportButtonClick( wxCommandEvent& event );
+ void OnLaunchButtonClick( wxCommandEvent& event );
+ void OnImportButtonClick( wxCommandEvent& event );
+ void OnHelpButtonClick( wxCommandEvent& event );
+
+ void MyInit ( );
+ const wxString createDSN_File();
+
+public:
+ DIALOG_FREEROUTE( PCB_EDIT_FRAME* parent );
+ ~DIALOG_FREEROUTE() {};
+
+};
+
+#endif
+
+// _DIALOG_FREEROUTE_EXCHANGE_H_
diff --git a/pcbnew/dialogs/dialog_freeroute_exchange_base.cpp b/pcbnew/dialogs/dialog_freeroute_exchange_base.cpp
new file mode 100644
index 0000000..4110285
--- /dev/null
+++ b/pcbnew/dialogs/dialog_freeroute_exchange_base.cpp
@@ -0,0 +1,101 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_freeroute_exchange_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_FREEROUTE_BASE::DIALOG_FREEROUTE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bLeftSizer;
+ bLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextMsg = new wxStaticText( this, wxID_ANY, _("Export/Import to/from FreeRoute:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextMsg->Wrap( -1 );
+ m_staticTextMsg->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bLeftSizer->Add( m_staticTextMsg, 0, wxALL, 5 );
+
+ wxBoxSizer* bLeftSubSizerSizer;
+ bLeftSubSizerSizer = new wxBoxSizer( wxHORIZONTAL );
+
+
+ bLeftSubSizerSizer->Add( 20, 20, 0, 0, 5 );
+
+ wxBoxSizer* bLeftButtonsSizer;
+ bLeftButtonsSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_ExportDSN = new wxButton( this, wxID_ANY, _("Export a Specctra Design (*.dsn) File"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ExportDSN->SetToolTip( _("Export a Specctra DSN file (to FreeRouter)") );
+
+ bLeftButtonsSizer->Add( m_ExportDSN, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonLaunchFreeroute = new wxButton( this, wxID_ANY, _("Export a Specctra Design and Launch FreeRoute"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonLaunchFreeroute->SetToolTip( _("FreeRouter can be run only if freeroute.jar is found in Kicad binaries folder") );
+
+ bLeftButtonsSizer->Add( m_buttonLaunchFreeroute, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonImport = new wxButton( this, wxID_ANY, _("Back Import the Specctra Session (*.ses) File"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonImport->SetToolTip( _("Merge a session file created by FreeRouter with the current board.") );
+
+ bLeftButtonsSizer->Add( m_buttonImport, 0, wxALL|wxEXPAND, 5 );
+
+
+ bLeftSubSizerSizer->Add( bLeftButtonsSizer, 1, wxEXPAND, 5 );
+
+
+ bLeftSizer->Add( bLeftSubSizerSizer, 1, wxALL|wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( bLeftSizer, 1, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bUpperSizer, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline1, 0, wxEXPAND|wxALL, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizerHelp = new wxButton( this, wxID_HELP );
+ m_sdbSizer->AddButton( m_sdbSizerHelp );
+ m_sdbSizer->Realize();
+
+ bMainSizer->Add( m_sdbSizer, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ m_ExportDSN->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FREEROUTE_BASE::OnExportButtonClick ), NULL, this );
+ m_buttonLaunchFreeroute->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FREEROUTE_BASE::OnLaunchButtonClick ), NULL, this );
+ m_buttonImport->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FREEROUTE_BASE::OnImportButtonClick ), NULL, this );
+ m_sdbSizerHelp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FREEROUTE_BASE::OnHelpButtonClick ), NULL, this );
+}
+
+DIALOG_FREEROUTE_BASE::~DIALOG_FREEROUTE_BASE()
+{
+ // Disconnect Events
+ m_ExportDSN->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FREEROUTE_BASE::OnExportButtonClick ), NULL, this );
+ m_buttonLaunchFreeroute->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FREEROUTE_BASE::OnLaunchButtonClick ), NULL, this );
+ m_buttonImport->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FREEROUTE_BASE::OnImportButtonClick ), NULL, this );
+ m_sdbSizerHelp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FREEROUTE_BASE::OnHelpButtonClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_freeroute_exchange_base.fbp b/pcbnew/dialogs/dialog_freeroute_exchange_base.fbp
new file mode 100644
index 0000000..d1d7913
--- /dev/null
+++ b/pcbnew/dialogs/dialog_freeroute_exchange_base.fbp
@@ -0,0 +1,607 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_freeroute_exchange_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_freeroute_exchange_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_FREEROUTE_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Export/Import to/from FreeRoute:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextMsg</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLeftSubSizerSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">20</property>
+ <property name="permission">protected</property>
+ <property name="width">20</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLeftButtonsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Export a Specctra Design (*.dsn) File</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ExportDSN</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Export a Specctra DSN file (to FreeRouter)</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnExportButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Export a Specctra Design and Launch FreeRoute</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonLaunchFreeroute</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">FreeRouter can be run only if freeroute.jar is found in Kicad binaries folder</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnLaunchButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Back Import the Specctra Session (*.ses) File</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonImport</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Merge a session file created by FreeRouter with the current board.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnImportButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">1</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick">OnHelpButtonClick</event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_freeroute_exchange_base.h b/pcbnew/dialogs/dialog_freeroute_exchange_base.h
new file mode 100644
index 0000000..b6e14dc
--- /dev/null
+++ b/pcbnew/dialogs/dialog_freeroute_exchange_base.h
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_FREEROUTE_EXCHANGE_BASE_H__
+#define __DIALOG_FREEROUTE_EXCHANGE_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_FREEROUTE_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_FREEROUTE_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticTextMsg;
+ wxButton* m_ExportDSN;
+ wxButton* m_buttonLaunchFreeroute;
+ wxButton* m_buttonImport;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+ wxButton* m_sdbSizerHelp;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnExportButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnLaunchButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnImportButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnHelpButtonClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_FREEROUTE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_FREEROUTE_BASE();
+
+};
+
+#endif //__DIALOG_FREEROUTE_EXCHANGE_BASE_H__
diff --git a/pcbnew/dialogs/dialog_freeroute_exchange_help.html b/pcbnew/dialogs/dialog_freeroute_exchange_help.html
new file mode 100644
index 0000000..375df66
--- /dev/null
+++ b/pcbnew/dialogs/dialog_freeroute_exchange_help.html
@@ -0,0 +1,71 @@
+<html>
+<!-- This file is used to autogenerate a *.h file, but you can load it into a browser to preview -->
+<h1>Freerouter Guidelines:</h1>
+<ol>
+<li> in pcbnew, using the Layers Setup dialog:</li><br>
+ <li>choose the number of layers, and enter the name of each layer.</li><br><br>
+ These should look something like this (if a 6 layer board):
+<ul>
+ <li>Front - signal</li>
+ <li>Ground - power</li>
+ <li>H1_Signal - signal</li>
+ <li>V2_Signal - signal</li>
+ <li>Power - power</li>
+ <li>Back - signal</li>
+</ul><br>
+ Notice that after the layer name there is a layer type field, either 'signal' or 'power', typically.
+ Any layer identified as 'power' will be removed from the layer menu in Freerouter,
+ as this will be assumed to contain a power zone.
+</li><br><br>
+
+<li> in pcbnew: establish board perimeter.</li><br>
+
+<li> in pcbnew: load in the netlist so you have all the components defined and instantiated.</li><br>
+
+<li> in pcbnew: establish any zones, inclusive of net association.</li><br>
+
+<li> in pcbnew: do the degree of component placements you are comfortable with.
+ It is a little easier to accurately position components in pcbnew than in
+ freerouter, but either will work.</li><br>
+
+<li> in pcbnew: set up the netclasses. Power traces might be a little thicker
+ than signal traces. If so, add a netclass called 'power'.
+ Make its traces thicker than what you establish for netclass 'Default'.
+ Set trace width, spacing and vias for each netclass.</li><br>
+
+<li> in pcbnew: export to DSN.</li><br>
+
+<li> load up freerouter (keep it running for any subsequent iterations of 5) through 16) here).</li><br>
+
+<li> in freerouter: load the project's *.dsn file. Immediately after a load, all
+ components and traces (if any) will initially be 'fixed'. This is a 'lock
+ in place' toggle that you can undo by selecting a region with your mouse
+ and then selecting 'Unfix' from the menu. Occassionally you may want to
+ re-fix a trace or a part, if only temporarily. This keeps it locked in
+ place.
+</li><br>
+
+<li> useful, not mandatory: in freerouter: set your move snap modulus, which seems
+ to default to 1 internal unit.
+ 20 mils in x and in y is about reasonable.</li><br>
+
+<li> in freerouter: finish placing any components, you can change sides of a part
+ here also, rotate, whatever.</li><br>
+
+<li> in freerouter: route the board, and save frequently to a *.dsn file while
+ routing in case of power loss. Pick the menu option for saving a full *.dsn
+ file, not a session file (yet). The full freerouter *.dsn file is a superset
+ format, one that can be reloaded in the event of a power loss. Whereas the
+ *.ses file is not a complete design, but only with the *.brd file
+ constitutes a full design. So it is important to backup your work to a
+ *.dsn file while routing in case of power loss.</li><br>
+
+<li> in freerouter: when done, or when you want to back import, then save as a session file, *.ses.</li><br>
+
+<li> in pcbnew: backimport the session file</li><br>
+
+<li> in pcbnew: at this point the zones have to be refilled. One way to do that
+ is to simply run DRC.</li>
+
+</ol>
+</html>
diff --git a/pcbnew/dialogs/dialog_gen_module_position_file_base.cpp b/pcbnew/dialogs/dialog_gen_module_position_file_base.cpp
new file mode 100644
index 0000000..352459a
--- /dev/null
+++ b/pcbnew/dialogs/dialog_gen_module_position_file_base.cpp
@@ -0,0 +1,121 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "wx_html_report_panel.h"
+
+#include "dialog_gen_module_position_file_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_GEN_MODULE_POSITION_BASE::DIALOG_GEN_MODULE_POSITION_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ m_MainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bDirSizer;
+ bDirSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextDir = new wxStaticText( this, wxID_ANY, _("Output directory:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextDir->Wrap( -1 );
+ bDirSizer->Add( m_staticTextDir, 0, wxEXPAND|wxTOP|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerdirBrowse;
+ bSizerdirBrowse = new wxBoxSizer( wxHORIZONTAL );
+
+ m_outputDirectoryName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_outputDirectoryName->SetMaxLength( 0 );
+ m_outputDirectoryName->SetToolTip( _("Target directory for plot files. Can be absolute or relative to the board file location.") );
+ m_outputDirectoryName->SetMinSize( wxSize( 350,-1 ) );
+
+ bSizerdirBrowse->Add( m_outputDirectoryName, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ m_browseButton = new wxButton( this, wxID_ANY, _("Browse..."), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerdirBrowse->Add( m_browseButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
+
+
+ bDirSizer->Add( bSizerdirBrowse, 1, wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( bDirSizer, 1, 0, 5 );
+
+
+ m_MainSizer->Add( bUpperSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerOptions;
+ bSizerOptions = new wxBoxSizer( wxHORIZONTAL );
+
+ wxString m_radioBoxUnitsChoices[] = { _("Inches"), _("mm") };
+ int m_radioBoxUnitsNChoices = sizeof( m_radioBoxUnitsChoices ) / sizeof( wxString );
+ m_radioBoxUnits = new wxRadioBox( this, wxID_ANY, _("Units:"), wxDefaultPosition, wxDefaultSize, m_radioBoxUnitsNChoices, m_radioBoxUnitsChoices, 1, wxRA_SPECIFY_COLS );
+ m_radioBoxUnits->SetSelection( 0 );
+ bSizerOptions->Add( m_radioBoxUnits, 1, wxALL, 5 );
+
+ wxString m_radioBoxFilesCountChoices[] = { _("One file per side"), _("One file for board") };
+ int m_radioBoxFilesCountNChoices = sizeof( m_radioBoxFilesCountChoices ) / sizeof( wxString );
+ m_radioBoxFilesCount = new wxRadioBox( this, wxID_ANY, _("Files:"), wxDefaultPosition, wxDefaultSize, m_radioBoxFilesCountNChoices, m_radioBoxFilesCountChoices, 1, wxRA_SPECIFY_COLS );
+ m_radioBoxFilesCount->SetSelection( 0 );
+ m_radioBoxFilesCount->SetToolTip( _("Creates 2 files: one for each board side or\nCreates only one file containing all footprints to place\n") );
+
+ bSizerOptions->Add( m_radioBoxFilesCount, 1, wxALL, 5 );
+
+ wxString m_radioBoxForceSmdChoices[] = { _("With INSERT attribute set"), _("Force INSERT attribute for all SMD footprints") };
+ int m_radioBoxForceSmdNChoices = sizeof( m_radioBoxForceSmdChoices ) / sizeof( wxString );
+ m_radioBoxForceSmd = new wxRadioBox( this, wxID_ANY, _("Footprints Selection:"), wxDefaultPosition, wxDefaultSize, m_radioBoxForceSmdNChoices, m_radioBoxForceSmdChoices, 1, wxRA_SPECIFY_COLS );
+ m_radioBoxForceSmd->SetSelection( 0 );
+ m_radioBoxForceSmd->SetToolTip( _("Only footprints with option INSERT are listed in placement file.\nThis option can force this option for all footprints having only SMD pads.\nWarning: this options will modify the board.") );
+
+ bSizerOptions->Add( m_radioBoxForceSmd, 0, wxALL, 5 );
+
+
+ m_MainSizer->Add( bSizerOptions, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+ wxBoxSizer* bSizer7;
+ bSizer7 = new wxBoxSizer( wxVERTICAL );
+
+ m_messagesPanel = new WX_HTML_REPORT_PANEL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_messagesPanel->SetMinSize( wxSize( 300,150 ) );
+
+ bSizer7->Add( m_messagesPanel, 1, wxEXPAND | wxALL, 5 );
+
+
+ m_MainSizer->Add( bSizer7, 1, wxEXPAND, 5 );
+
+ m_sdbSizerButtons = new wxStdDialogButtonSizer();
+ m_sdbSizerButtonsOK = new wxButton( this, wxID_OK );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsOK );
+ m_sdbSizerButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsCancel );
+ m_sdbSizerButtons->Realize();
+
+ m_MainSizer->Add( m_sdbSizerButtons, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 );
+
+
+ this->SetSizer( m_MainSizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnClose ) );
+ this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnInitDialog ) );
+ m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnOutputDirectoryBrowseClicked ), NULL, this );
+ m_sdbSizerButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnOKButton ), NULL, this );
+}
+
+DIALOG_GEN_MODULE_POSITION_BASE::~DIALOG_GEN_MODULE_POSITION_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnClose ) );
+ this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnInitDialog ) );
+ m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnOutputDirectoryBrowseClicked ), NULL, this );
+ m_sdbSizerButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnOKButton ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_gen_module_position_file_base.fbp b/pcbnew/dialogs/dialog_gen_module_position_file_base.fbp
new file mode 100644
index 0000000..6b5131a
--- /dev/null
+++ b/pcbnew/dialogs/dialog_gen_module_position_file_base.fbp
@@ -0,0 +1,792 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_gen_module_position_file_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">Dialog_Gen_Modules_Positions_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_GEN_MODULE_POSITION_BASE</property>
+ <property name="pos"></property>
+ <property name="size">510,351</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Generate Component Position Files</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnClose</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog">OnInitDialog</event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_MainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bDirSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Output directory:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextDir</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerdirBrowse</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">350,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_outputDirectoryName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Target directory for plot files. Can be absolute or relative to the board file location.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Browse...</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_browseButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnOutputDirectoryBrowseClicked</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerOptions</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Inches&quot; &quot;mm&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Units:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioBoxUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;One file per side&quot; &quot;One file for board&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Files:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioBoxFilesCount</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Creates 2 files: one for each board side or&#x0A;Creates only one file containing all footprints to place&#x0A;</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;With INSERT attribute set&quot; &quot;Force INSERT attribute for all SMD footprints&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprints Selection:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioBoxForceSmd</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Only footprints with option INSERT are listed in placement file.&#x0A;This option can force this option for all footprints having only SMD pads.&#x0A;Warning: this options will modify the board.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer7</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">300,150</property>
+ <property name="moveable">1</property>
+ <property name="name">m_messagesPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass">WX_HTML_REPORT_PANEL; wx_html_report_panel.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizerButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKButton</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_gen_module_position_file_base.h b/pcbnew/dialogs/dialog_gen_module_position_file_base.h
new file mode 100644
index 0000000..72a4bd9
--- /dev/null
+++ b/pcbnew/dialogs/dialog_gen_module_position_file_base.h
@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_GEN_MODULE_POSITION_FILE_BASE_H__
+#define __DIALOG_GEN_MODULE_POSITION_FILE_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class WX_HTML_REPORT_PANEL;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/radiobox.h>
+#include <wx/panel.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_GEN_MODULE_POSITION_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_GEN_MODULE_POSITION_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxBoxSizer* m_MainSizer;
+ wxStaticText* m_staticTextDir;
+ wxTextCtrl* m_outputDirectoryName;
+ wxButton* m_browseButton;
+ wxRadioBox* m_radioBoxUnits;
+ wxRadioBox* m_radioBoxFilesCount;
+ wxRadioBox* m_radioBoxForceSmd;
+ WX_HTML_REPORT_PANEL* m_messagesPanel;
+ wxStdDialogButtonSizer* m_sdbSizerButtons;
+ wxButton* m_sdbSizerButtonsOK;
+ wxButton* m_sdbSizerButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
+ virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOKButton( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_GEN_MODULE_POSITION_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generate Component Position Files"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 510,351 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_GEN_MODULE_POSITION_BASE();
+
+};
+
+#endif //__DIALOG_GEN_MODULE_POSITION_FILE_BASE_H__
diff --git a/pcbnew/dialogs/dialog_gendrill.cpp b/pcbnew/dialogs/dialog_gendrill.cpp
new file mode 100644
index 0000000..9714444
--- /dev/null
+++ b/pcbnew/dialogs/dialog_gendrill.cpp
@@ -0,0 +1,427 @@
+/**
+ * @file dialog_gendrill.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 Jean_Pierre Charras <jp.charras at wanadoo.fr>
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <pcbplot.h>
+#include <gendrill_Excellon_writer.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_track.h>
+#include <class_module.h>
+
+#include <dialog_gendrill.h>
+#include <wildcards_and_files_ext.h>
+#include <reporter.h>
+
+#include <wx/stdpaths.h>
+
+
+// Keywords for read and write config
+#define ZerosFormatKey wxT( "DrillZerosFormat" )
+#define PrecisionKey wxT( "DrilltPrecisionOpt" )
+#define MirrorKey wxT( "DrillMirrorYOpt" )
+#define MinimalHeaderKey wxT( "DrillMinHeader" )
+#define MergePTHNPTHKey wxT( "DrillMergePTHNPTH" )
+#define UnitDrillInchKey wxT( "DrillUnit" )
+#define DrillOriginIsAuxAxisKey wxT( "DrillAuxAxis" )
+#define DrillMapFileTypeKey wxT( "DrillMapFileType" )
+
+// list of allowed precision for EXCELLON files, for integer format:
+// Due to difference between inches and mm,
+// there are 2 precision values, one for inches and one for metric
+static DRILL_PRECISION precisionListForInches( 2, 4 );
+static DRILL_PRECISION precisionListForMetric( 3, 3 );
+
+
+/* This function displays the dialog frame for drill tools
+ */
+void PCB_EDIT_FRAME::InstallDrillFrame( wxCommandEvent& event )
+{
+ DIALOG_GENDRILL dlg( this );
+
+ dlg.ShowModal();
+}
+
+
+DIALOG_GENDRILL::DIALOG_GENDRILL( PCB_EDIT_FRAME* parent ) :
+ DIALOG_GENDRILL_BASE( parent )
+{
+ m_parent = parent;
+ m_board = parent->GetBoard();
+ m_config = Kiface().KifaceSettings();
+ m_plotOpts = m_parent->GetPlotSettings();
+
+ SetReturnCode( 1 );
+ initDialog();
+ GetSizer()->SetSizeHints( this );
+}
+
+
+// Static members of DIALOG_GENDRILL
+int DIALOG_GENDRILL::m_UnitDrillIsInch = true;
+int DIALOG_GENDRILL::m_ZerosFormat = EXCELLON_WRITER::DECIMAL_FORMAT;
+bool DIALOG_GENDRILL::m_MinimalHeader = false;
+bool DIALOG_GENDRILL::m_Mirror = false;
+bool DIALOG_GENDRILL::m_Merge_PTH_NPTH = false;
+bool DIALOG_GENDRILL::m_DrillOriginIsAuxAxis = false;
+int DIALOG_GENDRILL::m_mapFileType = 1;
+
+
+DIALOG_GENDRILL::~DIALOG_GENDRILL()
+{
+ UpdateConfig();
+}
+
+
+void DIALOG_GENDRILL::initDialog()
+{
+ m_config->Read( ZerosFormatKey, &m_ZerosFormat );
+ m_config->Read( MirrorKey, &m_Mirror );
+ m_config->Read( MergePTHNPTHKey, &m_Merge_PTH_NPTH );
+ m_config->Read( MinimalHeaderKey, &m_MinimalHeader );
+ m_config->Read( UnitDrillInchKey, &m_UnitDrillIsInch );
+ m_config->Read( DrillOriginIsAuxAxisKey, &m_DrillOriginIsAuxAxis );
+ m_config->Read( DrillMapFileTypeKey, &m_mapFileType );
+
+ InitDisplayParams();
+}
+
+
+void DIALOG_GENDRILL::InitDisplayParams()
+{
+ wxString msg;
+
+ m_Choice_Unit->SetSelection( m_UnitDrillIsInch ? 1 : 0 );
+ m_Choice_Zeros_Format->SetSelection( m_ZerosFormat );
+ UpdatePrecisionOptions();
+ m_Check_Minimal->SetValue( m_MinimalHeader );
+
+ if( m_DrillOriginIsAuxAxis )
+ m_Choice_Drill_Offset->SetSelection( 1 );
+
+ m_Check_Mirror->SetValue( m_Mirror );
+ m_Check_Merge_PTH_NPTH->SetValue( m_Merge_PTH_NPTH );
+ m_Choice_Drill_Map->SetSelection( m_mapFileType );
+ m_ViaDrillValue->SetLabel( _( "Use Netclasses values" ) );
+ m_MicroViaDrillValue->SetLabel( _( "Use Netclasses values" ) );
+
+ // See if we have some buried vias or/and microvias, and display
+ // microvias drill value if so
+ m_throughViasCount = 0;
+ m_microViasCount = 0;
+ m_blindOrBuriedViasCount = 0;
+
+ for( TRACK* track = m_parent->GetBoard()->m_Track; track != NULL; track = track->Next() )
+ {
+ const VIA *via = dynamic_cast<const VIA*>( track );
+ if( via )
+ {
+ switch( via->GetViaType() )
+ {
+ case VIA_THROUGH:
+ m_throughViasCount++;
+ break;
+
+ case VIA_MICROVIA:
+ m_microViasCount++;
+ break;
+
+ case VIA_BLIND_BURIED:
+ m_blindOrBuriedViasCount++;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ m_MicroViaDrillValue->Enable( m_microViasCount );
+
+ // Count plated pad holes and not plated pad holes:
+ m_platedPadsHoleCount = 0;
+ m_notplatedPadsHoleCount = 0;
+
+ for( MODULE* module = m_parent->GetBoard()->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad != NULL; pad = pad->Next() )
+ {
+ if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
+ {
+ if( pad->GetDrillSize().x != 0 )
+ {
+ if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
+ m_notplatedPadsHoleCount++;
+ else
+ m_platedPadsHoleCount++;
+ }
+ }
+ else
+ {
+ if( pad->GetDrillSize().x != 0 && pad->GetDrillSize().y != 0 )
+ {
+ if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
+ m_notplatedPadsHoleCount++;
+ else
+ m_platedPadsHoleCount++;
+ }
+ }
+ }
+ }
+
+ // Display hole counts:
+ msg = m_PlatedPadsCountInfoMsg->GetLabel();
+ msg << wxT( " " ) << m_platedPadsHoleCount;
+ m_PlatedPadsCountInfoMsg->SetLabel( msg );
+
+ msg = m_NotPlatedPadsCountInfoMsg->GetLabel();
+ msg << wxT( " " ) << m_notplatedPadsHoleCount;
+ m_NotPlatedPadsCountInfoMsg->SetLabel( msg );
+
+ msg = m_ThroughViasInfoMsg->GetLabel();
+ msg << wxT( " " ) << m_throughViasCount;
+ m_ThroughViasInfoMsg->SetLabel( msg );
+
+ msg = m_MicroViasInfoMsg->GetLabel();
+ msg << wxT( " " ) << m_microViasCount;
+ m_MicroViasInfoMsg->SetLabel( msg );
+
+ msg = m_BuriedViasInfoMsg->GetLabel();
+ msg << wxT( " " ) << m_blindOrBuriedViasCount;
+ m_BuriedViasInfoMsg->SetLabel( msg );
+
+ // Output directory
+ m_outputDirectoryName->SetValue( m_plotOpts.GetOutputDirectory() );
+}
+
+
+void DIALOG_GENDRILL::UpdateConfig()
+{
+ SetParams();
+
+ m_config->Write( ZerosFormatKey, m_ZerosFormat );
+ m_config->Write( MirrorKey, m_Mirror );
+ m_config->Write( MergePTHNPTHKey, m_Merge_PTH_NPTH );
+ m_config->Write( MinimalHeaderKey, m_MinimalHeader );
+ m_config->Write( UnitDrillInchKey, m_UnitDrillIsInch );
+ m_config->Write( DrillOriginIsAuxAxisKey, m_DrillOriginIsAuxAxis );
+ m_config->Write( DrillMapFileTypeKey, m_mapFileType );
+}
+
+
+void DIALOG_GENDRILL::OnSelDrillUnitsSelected( wxCommandEvent& event )
+{
+ UpdatePrecisionOptions();
+}
+
+void DIALOG_GENDRILL::OnGenMapFile( wxCommandEvent& event )
+{
+ GenDrillAndMapFiles( false, true);
+}
+
+
+void DIALOG_GENDRILL::OnGenDrillFile( wxCommandEvent& event )
+{
+ GenDrillAndMapFiles(true, false);
+}
+
+
+void DIALOG_GENDRILL::OnCancelClick( wxCommandEvent& event )
+{
+ UpdateConfig(); // Save drill options:
+ EndModal( wxID_CANCEL ); // Process the default cancel event (close dialog)
+}
+
+
+void DIALOG_GENDRILL::OnSelZerosFmtSelected( wxCommandEvent& event )
+{
+ UpdatePrecisionOptions();
+}
+
+
+void DIALOG_GENDRILL::UpdatePrecisionOptions()
+{
+ if( m_Choice_Unit->GetSelection()== 1 ) // Units = inches
+ m_staticTextPrecision->SetLabel( precisionListForInches.GetPrecisionString() );
+ else
+ {
+ // metric options
+ m_staticTextPrecision->SetLabel( precisionListForMetric.GetPrecisionString() );
+ }
+
+ if( m_Choice_Zeros_Format->GetSelection() == EXCELLON_WRITER::DECIMAL_FORMAT )
+ m_staticTextPrecision->Enable( false );
+ else
+ m_staticTextPrecision->Enable( true );
+}
+
+
+void DIALOG_GENDRILL::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
+{
+ // Build the absolute path of current output plot directory
+ // to preselect it when opening the dialog.
+ wxFileName fn( m_outputDirectoryName->GetValue() );
+ wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() );
+
+ wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
+
+ if( dirDialog.ShowModal() == wxID_CANCEL )
+ return;
+
+ wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
+
+ wxMessageDialog dialog( this, _( "Use a relative path? " ),
+ _( "Plot Output Directory" ),
+ wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
+
+ if( dialog.ShowModal() == wxID_YES )
+ {
+ wxString boardFilePath = Prj().AbsolutePath( m_parent->GetBoard()->GetFileName() );
+
+ boardFilePath = wxPathOnly( boardFilePath );
+
+ if( !dirName.MakeRelativeTo( boardFilePath ) )
+ wxMessageBox( _( "Cannot make path relative. The target volume is different from board file volume!" ),
+ _( "Plot Output Directory" ), wxOK | wxICON_ERROR );
+ }
+
+ m_outputDirectoryName->SetValue( dirName.GetFullPath() );
+}
+
+
+void DIALOG_GENDRILL::SetParams()
+{
+ wxString msg;
+
+ // Set output directory and replace backslashes with forward ones
+ wxString dirStr;
+ dirStr = m_outputDirectoryName->GetValue();
+ dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
+ m_plotOpts.SetOutputDirectory( dirStr );
+
+ m_mapFileType = m_Choice_Drill_Map->GetSelection();
+
+ m_UnitDrillIsInch = (m_Choice_Unit->GetSelection() == 0) ? false : true;
+ m_MinimalHeader = m_Check_Minimal->IsChecked();
+ m_Mirror = m_Check_Mirror->IsChecked();
+ m_Merge_PTH_NPTH = m_Check_Merge_PTH_NPTH->IsChecked();
+ m_ZerosFormat = m_Choice_Zeros_Format->GetSelection();
+ m_DrillOriginIsAuxAxis = m_Choice_Drill_Offset->GetSelection();
+
+ if( m_Choice_Drill_Offset->GetSelection() == 0 )
+ m_FileDrillOffset = wxPoint( 0, 0 );
+ else
+ m_FileDrillOffset = m_parent->GetAuxOrigin();
+
+ if( m_UnitDrillIsInch )
+ m_Precision = precisionListForInches;
+ else
+ m_Precision = precisionListForMetric;
+
+ m_board->SetPlotOptions( m_plotOpts );
+}
+
+
+void DIALOG_GENDRILL::GenDrillAndMapFiles(bool aGenDrill, bool aGenMap)
+{
+ UpdateConfig(); // set params and Save drill options
+
+ m_parent->ClearMsgPanel();
+ wxString defaultPath = Prj().AbsolutePath( m_plotOpts.GetOutputDirectory() );
+ WX_TEXT_CTRL_REPORTER reporter( m_messagesBox );
+
+ const PlotFormat filefmt[6] =
+ { // Keep these format ids in the same order than m_Choice_Drill_Map choices
+ PLOT_FORMAT_HPGL, PLOT_FORMAT_POST, PLOT_FORMAT_GERBER,
+ PLOT_FORMAT_DXF, PLOT_FORMAT_SVG, PLOT_FORMAT_PDF
+ };
+ unsigned choice = (unsigned) m_Choice_Drill_Map->GetSelection();
+
+ if( choice >= DIM( filefmt ) )
+ choice = 1;
+
+ EXCELLON_WRITER excellonWriter( m_parent->GetBoard() );
+ excellonWriter.SetFormat( !m_UnitDrillIsInch,
+ (EXCELLON_WRITER::ZEROS_FMT) m_ZerosFormat,
+ m_Precision.m_lhs, m_Precision.m_rhs );
+ excellonWriter.SetOptions( m_Mirror, m_MinimalHeader,
+ m_FileDrillOffset, m_Merge_PTH_NPTH );
+ excellonWriter.SetMapFileFormat( filefmt[choice] );
+
+ excellonWriter.CreateDrillandMapFilesSet( defaultPath, aGenDrill, aGenMap,
+ &reporter);
+}
+
+
+void DIALOG_GENDRILL::OnGenReportFile( wxCommandEvent& event )
+{
+ UpdateConfig(); // set params and Save drill options
+
+ wxFileName fn = m_parent->GetBoard()->GetFileName();
+
+ fn.SetName( fn.GetName() + wxT( "-drl" ) );
+ fn.SetExt( ReportFileExtension );
+
+ wxString defaultPath = Prj().AbsolutePath( m_plotOpts.GetOutputDirectory() );
+
+ if( defaultPath.IsEmpty() )
+ defaultPath = wxStandardPaths::Get().GetDocumentsDir();
+
+ wxFileDialog dlg( this, _( "Save Drill Report File" ), defaultPath,
+ fn.GetFullName(), wxGetTranslation( ReportFileWildcard ),
+ wxFD_SAVE );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ EXCELLON_WRITER excellonWriter( m_parent->GetBoard() );
+ excellonWriter.SetFormat( !m_UnitDrillIsInch,
+ (EXCELLON_WRITER::ZEROS_FMT) m_ZerosFormat,
+ m_Precision.m_lhs, m_Precision.m_rhs );
+ excellonWriter.SetOptions( m_Mirror, m_MinimalHeader,
+ m_FileDrillOffset, m_Merge_PTH_NPTH );
+
+ bool success = excellonWriter.GenDrillReportFile( dlg.GetPath() );
+
+ wxString msg;
+
+ if( ! success )
+ {
+ msg.Printf( _( "** Unable to create %s **\n" ), GetChars( dlg.GetPath() ) );
+ m_messagesBox->AppendText( msg );
+ }
+ else
+ {
+ msg.Printf( _( "Report file %s created\n" ), GetChars( dlg.GetPath() ) );
+ m_messagesBox->AppendText( msg );
+ }
+}
diff --git a/pcbnew/dialogs/dialog_gendrill.h b/pcbnew/dialogs/dialog_gendrill.h
new file mode 100644
index 0000000..85a7087
--- /dev/null
+++ b/pcbnew/dialogs/dialog_gendrill.h
@@ -0,0 +1,113 @@
+/**
+ *@file dialog_gendrill.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 Jean_Pierre Charras <jp.charras@ujf-grenoble.fr>
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef DIALOG_GENDRILL_H_
+#define DIALOG_GENDRILL_H_
+
+#include <dialog_gendrill_base.h>
+
+class DIALOG_GENDRILL : public DIALOG_GENDRILL_BASE
+{
+public:
+ DIALOG_GENDRILL( PCB_EDIT_FRAME* parent );
+ ~DIALOG_GENDRILL();
+
+ static int m_UnitDrillIsInch;
+ static int m_ZerosFormat;
+ static bool m_MinimalHeader;
+ static bool m_Mirror;
+ static bool m_Merge_PTH_NPTH;
+ static bool m_DrillOriginIsAuxAxis; /* Axis selection (main / auxiliary)
+ * for drill origin coordinates */
+ DRILL_PRECISION m_Precision; // Selected precision for drill files
+ wxPoint m_FileDrillOffset; // Drill offset: 0,0 for absolute coordinates,
+ // or origin of the auxiliary axis
+
+
+private:
+ PCB_EDIT_FRAME* m_parent;
+ wxConfigBase* m_config;
+ BOARD* m_board;
+ PCB_PLOT_PARAMS m_plotOpts;
+
+ int m_platedPadsHoleCount;
+ int m_notplatedPadsHoleCount;
+ int m_throughViasCount;
+ int m_microViasCount;
+ int m_blindOrBuriedViasCount;
+
+ static int m_mapFileType; // HPGL, PS ...
+
+
+ void initDialog();
+ void InitDisplayParams( void );
+
+ // event functions
+ void OnSelDrillUnitsSelected( wxCommandEvent& event );
+ void OnSelZerosFmtSelected( wxCommandEvent& event );
+ void OnGenDrillFile( wxCommandEvent& event );
+ void OnGenMapFile( wxCommandEvent& event );
+
+ /*
+ * Create a plain text report file giving a list of drill values and drill count
+ * for through holes, oblong holes, and for buried vias,
+ * drill values and drill count per layer pair
+ */
+ void OnGenReportFile( wxCommandEvent& event );
+
+ void OnCancelClick( wxCommandEvent& event );
+ void OnOutputDirectoryBrowseClicked( wxCommandEvent& event );
+
+ // Specific functions:
+ void SetParams( void );
+
+ /**
+ * Function GenDrillAndMapFiles
+ * Calls the functions to create EXCELLON drill files and/or drill map files
+ * >When all holes are through holes, only one excellon file is created.
+ * >When there are some partial holes (some blind or buried vias),
+ * one excellon file is created, for all plated through holes,
+ * and one file per layer pair, which have one or more holes, excluding
+ * through holes, already in the first file.
+ * one file for all Not Plated through holes
+ */
+ void GenDrillAndMapFiles( bool aGenDrill, bool aGenMap );
+
+ void UpdatePrecisionOptions();
+ void UpdateConfig();
+ int Create_Drill_File_EXCELLON( FILE* aFile, wxPoint aOffset );
+ int Gen_Liste_Tools( std::vector<DRILL_TOOL>& buffer,
+ bool print_header );
+
+ /**
+ * Return the selected format for coordinates, if not decimal
+ */
+ DRILL_PRECISION GetPrecison();
+};
+
+#endif // DIALOG_GENDRILL_H_
diff --git a/pcbnew/dialogs/dialog_gendrill_base.cpp b/pcbnew/dialogs/dialog_gendrill_base.cpp
new file mode 100644
index 0000000..e868e1f
--- /dev/null
+++ b/pcbnew/dialogs/dialog_gendrill_base.cpp
@@ -0,0 +1,233 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_gendrill_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bupperSizer;
+ bupperSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* bdirnameSizer;
+ bdirnameSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Output directory:") ), wxHORIZONTAL );
+
+ m_outputDirectoryName = new wxTextCtrl( bdirnameSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_outputDirectoryName->SetMaxLength( 0 );
+ bdirnameSizer->Add( m_outputDirectoryName, 1, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonBrowse = new wxButton( bdirnameSizer->GetStaticBox(), wxID_ANY, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 );
+ bdirnameSizer->Add( m_buttonBrowse, 0, wxBOTTOM|wxLEFT, 5 );
+
+
+ bupperSizer->Add( bdirnameSizer, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+
+ bMainSizer->Add( bupperSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bmiddlerSizer;
+ bmiddlerSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* m_LeftBoxSizer;
+ m_LeftBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_Choice_UnitChoices[] = { _("Millimeters"), _("Inches") };
+ int m_Choice_UnitNChoices = sizeof( m_Choice_UnitChoices ) / sizeof( wxString );
+ m_Choice_Unit = new wxRadioBox( this, wxID_ANY, _("Drill Units:"), wxDefaultPosition, wxDefaultSize, m_Choice_UnitNChoices, m_Choice_UnitChoices, 1, wxRA_SPECIFY_COLS );
+ m_Choice_Unit->SetSelection( 1 );
+ m_LeftBoxSizer->Add( m_Choice_Unit, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_Choice_Zeros_FormatChoices[] = { _("Decimal format"), _("Suppress leading zeros"), _("Suppress trailing zeros"), _("Keep zeros") };
+ int m_Choice_Zeros_FormatNChoices = sizeof( m_Choice_Zeros_FormatChoices ) / sizeof( wxString );
+ m_Choice_Zeros_Format = new wxRadioBox( this, wxID_ANY, _("Zeros Format"), wxDefaultPosition, wxDefaultSize, m_Choice_Zeros_FormatNChoices, m_Choice_Zeros_FormatChoices, 1, wxRA_SPECIFY_COLS );
+ m_Choice_Zeros_Format->SetSelection( 0 );
+ m_Choice_Zeros_Format->SetToolTip( _("Choose EXCELLON numbers notation") );
+
+ m_LeftBoxSizer->Add( m_Choice_Zeros_Format, 0, wxALL|wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbSizerPrecision;
+ sbSizerPrecision = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Precision") ), wxVERTICAL );
+
+ m_staticTextPrecision = new wxStaticText( sbSizerPrecision->GetStaticBox(), wxID_ANY, _("Precision"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextPrecision->Wrap( -1 );
+ sbSizerPrecision->Add( m_staticTextPrecision, 0, wxALL, 5 );
+
+
+ m_LeftBoxSizer->Add( sbSizerPrecision, 0, wxEXPAND, 5 );
+
+
+ bmiddlerSizer->Add( m_LeftBoxSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bMiddleBoxSizer;
+ bMiddleBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_Choice_Drill_MapChoices[] = { _("HPGL"), _("PostScript"), _("Gerber"), _("DXF"), _("SVG"), _("PDF") };
+ int m_Choice_Drill_MapNChoices = sizeof( m_Choice_Drill_MapChoices ) / sizeof( wxString );
+ m_Choice_Drill_Map = new wxRadioBox( this, wxID_ANY, _("Drill Map File Format:"), wxDefaultPosition, wxDefaultSize, m_Choice_Drill_MapNChoices, m_Choice_Drill_MapChoices, 1, wxRA_SPECIFY_COLS );
+ m_Choice_Drill_Map->SetSelection( 1 );
+ m_Choice_Drill_Map->SetToolTip( _("Creates a drill map in PS, HPGL or other formats") );
+
+ bMiddleBoxSizer->Add( m_Choice_Drill_Map, 0, wxALL|wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbOptSizer;
+ sbOptSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Drill File Options:") ), wxVERTICAL );
+
+ m_Check_Mirror = new wxCheckBox( sbOptSizer->GetStaticBox(), wxID_ANY, _("Mirror y axis"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Check_Mirror->SetToolTip( _("Not recommanded.\nUsed mostly by users who make themselves the boards.") );
+
+ sbOptSizer->Add( m_Check_Mirror, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_Check_Minimal = new wxCheckBox( sbOptSizer->GetStaticBox(), wxID_ANY, _("Minimal header"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Check_Minimal->SetToolTip( _("Not recommanded.\nUse it only for board houses which do not accept fully featured headers.") );
+
+ sbOptSizer->Add( m_Check_Minimal, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_Check_Merge_PTH_NPTH = new wxCheckBox( sbOptSizer->GetStaticBox(), wxID_ANY, _("Merge PTH and NPTH holes into one file"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Check_Merge_PTH_NPTH->SetToolTip( _("Not recommanded.\nUse it only for board houses which ask for merged PTH and NPTH into onlu one file") );
+
+ sbOptSizer->Add( m_Check_Merge_PTH_NPTH, 0, wxALL, 5 );
+
+
+ bMiddleBoxSizer->Add( sbOptSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_Choice_Drill_OffsetChoices[] = { _("Absolute"), _("Auxiliary axis") };
+ int m_Choice_Drill_OffsetNChoices = sizeof( m_Choice_Drill_OffsetChoices ) / sizeof( wxString );
+ m_Choice_Drill_Offset = new wxRadioBox( this, wxID_ANY, _("Drill Origin:"), wxDefaultPosition, wxDefaultSize, m_Choice_Drill_OffsetNChoices, m_Choice_Drill_OffsetChoices, 1, wxRA_SPECIFY_COLS );
+ m_Choice_Drill_Offset->SetSelection( 0 );
+ m_Choice_Drill_Offset->SetToolTip( _("Choose the coordinate origin: absolute or relative to the auxiliray axis") );
+
+ bMiddleBoxSizer->Add( m_Choice_Drill_Offset, 0, wxALL|wxEXPAND, 5 );
+
+
+ bmiddlerSizer->Add( bMiddleBoxSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bRightBoxSizer;
+ bRightBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbSizerInfo;
+ sbSizerInfo = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Info:") ), wxVERTICAL );
+
+ m_DefaultViasDrillSizer = new wxStaticBoxSizer( new wxStaticBox( sbSizerInfo->GetStaticBox(), wxID_ANY, _("Default Vias Drill:") ), wxVERTICAL );
+
+ m_ViaDrillValue = new wxStaticText( m_DefaultViasDrillSizer->GetStaticBox(), wxID_ANY, _("Via Drill Value"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaDrillValue->Wrap( -1 );
+ m_DefaultViasDrillSizer->Add( m_ViaDrillValue, 0, wxALL, 5 );
+
+
+ sbSizerInfo->Add( m_DefaultViasDrillSizer, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+ m_MicroViasDrillSizer = new wxStaticBoxSizer( new wxStaticBox( sbSizerInfo->GetStaticBox(), wxID_ANY, _("Micro Vias Drill:") ), wxVERTICAL );
+
+ m_MicroViaDrillValue = new wxStaticText( m_MicroViasDrillSizer->GetStaticBox(), wxID_ANY, _("Micro Via Drill Value"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MicroViaDrillValue->Wrap( -1 );
+ m_MicroViasDrillSizer->Add( m_MicroViaDrillValue, 0, wxALL, 5 );
+
+
+ sbSizerInfo->Add( m_MicroViasDrillSizer, 0, wxEXPAND|wxBOTTOM, 5 );
+
+ wxStaticBoxSizer* sbSizerHoles;
+ sbSizerHoles = new wxStaticBoxSizer( new wxStaticBox( sbSizerInfo->GetStaticBox(), wxID_ANY, _("Holes Count:") ), wxVERTICAL );
+
+ m_PlatedPadsCountInfoMsg = new wxStaticText( sbSizerHoles->GetStaticBox(), wxID_ANY, _("Plated Pads:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PlatedPadsCountInfoMsg->Wrap( -1 );
+ sbSizerHoles->Add( m_PlatedPadsCountInfoMsg, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_NotPlatedPadsCountInfoMsg = new wxStaticText( sbSizerHoles->GetStaticBox(), wxID_ANY, _("Not Plated Pads:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_NotPlatedPadsCountInfoMsg->Wrap( -1 );
+ sbSizerHoles->Add( m_NotPlatedPadsCountInfoMsg, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_ThroughViasInfoMsg = new wxStaticText( sbSizerHoles->GetStaticBox(), wxID_ANY, _("Through Vias:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ThroughViasInfoMsg->Wrap( -1 );
+ sbSizerHoles->Add( m_ThroughViasInfoMsg, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_MicroViasInfoMsg = new wxStaticText( sbSizerHoles->GetStaticBox(), wxID_ANY, _("Micro Vias:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MicroViasInfoMsg->Wrap( -1 );
+ sbSizerHoles->Add( m_MicroViasInfoMsg, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_BuriedViasInfoMsg = new wxStaticText( sbSizerHoles->GetStaticBox(), wxID_ANY, _("Buried Vias:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_BuriedViasInfoMsg->Wrap( -1 );
+ sbSizerHoles->Add( m_BuriedViasInfoMsg, 0, wxALL, 5 );
+
+
+ sbSizerInfo->Add( sbSizerHoles, 1, wxEXPAND|wxBOTTOM, 5 );
+
+
+ bRightBoxSizer->Add( sbSizerInfo, 0, wxEXPAND|wxTOP, 5 );
+
+
+ bmiddlerSizer->Add( bRightBoxSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerButtons;
+ bSizerButtons = new wxBoxSizer( wxVERTICAL );
+
+
+ bSizerButtons->Add( 10, 20, 0, 0, 5 );
+
+ m_buttonDrill = new wxButton( this, ID_GEN_DRILL_FILE, _("Drill File"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonDrill->SetDefault();
+ bSizerButtons->Add( m_buttonDrill, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonMap = new wxButton( this, wxID_ANY, _("Map File"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( m_buttonMap, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonReport = new wxButton( this, wxID_ANY, _("Report File"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( m_buttonReport, 0, wxALL|wxEXPAND, 5 );
+
+ m_CancelButton = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( m_CancelButton, 0, wxALL|wxEXPAND, 5 );
+
+
+ bmiddlerSizer->Add( bSizerButtons, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bmiddlerSizer, 0, wxEXPAND, 5 );
+
+ wxStaticBoxSizer* bmsgSizer;
+ bmsgSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Messages:") ), wxVERTICAL );
+
+ m_messagesBox = new wxTextCtrl( bmsgSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY );
+ m_messagesBox->SetMinSize( wxSize( -1,90 ) );
+
+ bmsgSizer->Add( m_messagesBox, 1, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bmsgSizer, 1, wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_buttonBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnOutputDirectoryBrowseClicked ), NULL, this );
+ m_Choice_Unit->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnSelDrillUnitsSelected ), NULL, this );
+ m_Choice_Zeros_Format->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnSelZerosFmtSelected ), NULL, this );
+ m_buttonDrill->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnGenDrillFile ), NULL, this );
+ m_buttonMap->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnGenMapFile ), NULL, this );
+ m_buttonReport->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnGenReportFile ), NULL, this );
+ m_CancelButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnCancelClick ), NULL, this );
+}
+
+DIALOG_GENDRILL_BASE::~DIALOG_GENDRILL_BASE()
+{
+ // Disconnect Events
+ m_buttonBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnOutputDirectoryBrowseClicked ), NULL, this );
+ m_Choice_Unit->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnSelDrillUnitsSelected ), NULL, this );
+ m_Choice_Zeros_Format->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnSelZerosFmtSelected ), NULL, this );
+ m_buttonDrill->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnGenDrillFile ), NULL, this );
+ m_buttonMap->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnGenMapFile ), NULL, this );
+ m_buttonReport->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnGenReportFile ), NULL, this );
+ m_CancelButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENDRILL_BASE::OnCancelClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_gendrill_base.fbp b/pcbnew/dialogs/dialog_gendrill_base.fbp
new file mode 100644
index 0000000..73fef32
--- /dev/null
+++ b/pcbnew/dialogs/dialog_gendrill_base.fbp
@@ -0,0 +1,2197 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_gendrill_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_gendrill_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_GENDRILL_BASE</property>
+ <property name="pos"></property>
+ <property name="size">506,518</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Drill Files Generation</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bupperSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Output directory:</property>
+ <property name="minimum_size"></property>
+ <property name="name">bdirnameSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_outputDirectoryName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Browse</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonBrowse</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnOutputDirectoryBrowseClicked</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmiddlerSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_LeftBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Millimeters&quot; &quot;Inches&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Drill Units:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Choice_Unit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox">OnSelDrillUnitsSelected</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Decimal format&quot; &quot;Suppress leading zeros&quot; &quot;Suppress trailing zeros&quot; &quot;Keep zeros&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Zeros Format</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Choice_Zeros_Format</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Choose EXCELLON numbers notation</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox">OnSelZerosFmtSelected</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Precision</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerPrecision</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Precision</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextPrecision</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMiddleBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;HPGL&quot; &quot;PostScript&quot; &quot;Gerber&quot; &quot;DXF&quot; &quot;SVG&quot; &quot;PDF&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Drill Map File Format:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Choice_Drill_Map</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Creates a drill map in PS, HPGL or other formats</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Drill File Options:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbOptSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Mirror y axis</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Check_Mirror</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Not recommanded.&#x0A;Used mostly by users who make themselves the boards.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Minimal header</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Check_Minimal</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Not recommanded.&#x0A;Use it only for board houses which do not accept fully featured headers.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Merge PTH and NPTH holes into one file</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Check_Merge_PTH_NPTH</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Not recommanded.&#x0A;Use it only for board houses which ask for merged PTH and NPTH into onlu one file</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Absolute&quot; &quot;Auxiliary axis&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Drill Origin:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Choice_Drill_Offset</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Choose the coordinate origin: absolute or relative to the auxiliray axis</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Info:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerInfo</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default Vias Drill:</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_DefaultViasDrillSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Via Drill Value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaDrillValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Micro Vias Drill:</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_MicroViasDrillSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Micro Via Drill Value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MicroViaDrillValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Holes Count:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerHoles</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Plated Pads:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PlatedPadsCountInfoMsg</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Not Plated Pads:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NotPlatedPadsCountInfoMsg</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Through Vias:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ThroughViasInfoMsg</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Micro Vias:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MicroViasInfoMsg</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Buried Vias:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_BuriedViasInfoMsg</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerButtons</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">20</property>
+ <property name="permission">protected</property>
+ <property name="width">10</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_GEN_DRILL_FILE</property>
+ <property name="label">Drill File</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonDrill</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnGenDrillFile</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Map File</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonMap</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnGenMapFile</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Report File</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonReport</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnGenReportFile</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CancelButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Messages:</property>
+ <property name="minimum_size"></property>
+ <property name="name">bmsgSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,90</property>
+ <property name="moveable">1</property>
+ <property name="name">m_messagesBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_MULTILINE|wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_gendrill_base.h b/pcbnew/dialogs/dialog_gendrill_base.h
new file mode 100644
index 0000000..d0b5706
--- /dev/null
+++ b/pcbnew/dialogs/dialog_gendrill_base.h
@@ -0,0 +1,85 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_GENDRILL_BASE_H__
+#define __DIALOG_GENDRILL_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/textctrl.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/radiobox.h>
+#include <wx/stattext.h>
+#include <wx/checkbox.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_GEN_DRILL_FILE 1000
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_GENDRILL_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_GENDRILL_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxTextCtrl* m_outputDirectoryName;
+ wxButton* m_buttonBrowse;
+ wxRadioBox* m_Choice_Unit;
+ wxRadioBox* m_Choice_Zeros_Format;
+ wxStaticText* m_staticTextPrecision;
+ wxRadioBox* m_Choice_Drill_Map;
+ wxCheckBox* m_Check_Mirror;
+ wxCheckBox* m_Check_Minimal;
+ wxCheckBox* m_Check_Merge_PTH_NPTH;
+ wxRadioBox* m_Choice_Drill_Offset;
+ wxStaticBoxSizer* m_DefaultViasDrillSizer;
+ wxStaticText* m_ViaDrillValue;
+ wxStaticBoxSizer* m_MicroViasDrillSizer;
+ wxStaticText* m_MicroViaDrillValue;
+ wxStaticText* m_PlatedPadsCountInfoMsg;
+ wxStaticText* m_NotPlatedPadsCountInfoMsg;
+ wxStaticText* m_ThroughViasInfoMsg;
+ wxStaticText* m_MicroViasInfoMsg;
+ wxStaticText* m_BuriedViasInfoMsg;
+ wxButton* m_buttonDrill;
+ wxButton* m_buttonMap;
+ wxButton* m_buttonReport;
+ wxButton* m_CancelButton;
+ wxTextCtrl* m_messagesBox;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnSelDrillUnitsSelected( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnSelZerosFmtSelected( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnGenDrillFile( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnGenMapFile( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnGenReportFile( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Drill Files Generation"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 506,473 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_GENDRILL_BASE();
+
+};
+
+#endif //__DIALOG_GENDRILL_BASE_H__
diff --git a/pcbnew/dialogs/dialog_general_options.cpp b/pcbnew/dialogs/dialog_general_options.cpp
new file mode 100644
index 0000000..8dfd846
--- /dev/null
+++ b/pcbnew/dialogs/dialog_general_options.cpp
@@ -0,0 +1,152 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_general_options.cpp
+ */
+
+/* functions relatives to the dialogs opened from the main menu :
+ * Preferences/general
+ * Preferences/display
+ */
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <class_board_design_settings.h>
+#include <kicad_string.h>
+#include <pcbnew_id.h>
+#include <class_board.h>
+#include <collectors.h>
+#include <dialog_general_options.h>
+
+
+DIALOG_GENERALOPTIONS::DIALOG_GENERALOPTIONS( PCB_EDIT_FRAME* parent ) :
+ DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE( parent )
+{
+ init();
+
+ GetSizer()->SetSizeHints( this );
+ Center();
+}
+
+
+void DIALOG_GENERALOPTIONS::init()
+{
+ SetFocus();
+ m_sdbSizerOK->SetDefault();
+
+ m_Board = GetParent()->GetBoard();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetParent()->GetDisplayOptions();
+
+ /* Set display options */
+ m_PolarDisplay->SetSelection( displ_opts->m_DisplayPolarCood ? 1 : 0 );
+ m_UnitsSelection->SetSelection( g_UserUnit ? 1 : 0 );
+ m_CursorShape->SetSelection( GetParent()->GetCursorShape() ? 1 : 0 );
+
+
+ wxString rotationAngle;
+ rotationAngle = AngleToStringDegrees( (double)GetParent()->GetRotationAngle() );
+ m_RotationAngle->SetValue( rotationAngle );
+
+ m_spinMaxUndoItems->SetValue( GetParent()->GetScreen()->GetMaxUndoItems() );
+
+ wxString timevalue;
+ timevalue << GetParent()->GetAutoSaveInterval() / 60;
+ m_SaveTime->SetValue( timevalue );
+ m_MaxShowLinks->SetValue( displ_opts->m_MaxLinksShowed );
+
+ m_DrcOn->SetValue( g_Drc_On );
+ m_ShowModuleRatsnest->SetValue( displ_opts->m_Show_Module_Ratsnest );
+ m_ShowGlobalRatsnest->SetValue( m_Board->IsElementVisible( RATSNEST_VISIBLE ) );
+ m_TrackAutodel->SetValue( g_AutoDeleteOldTrack );
+ m_Track_45_Only_Ctrl->SetValue( g_Track_45_Only_Allowed );
+ m_Segments_45_Only_Ctrl->SetValue( g_Segments_45_Only );
+ m_ZoomCenterOpt->SetValue( ! GetParent()->GetCanvas()->GetEnableZoomNoCenter() );
+ m_MousewheelPANOpt->SetValue( GetParent()->GetCanvas()->GetEnableMousewheelPan() );
+ m_MiddleButtonPANOpt->SetValue( GetParent()->GetCanvas()->GetEnableMiddleButtonPan() );
+ m_OptMiddleButtonPanLimited->SetValue( GetParent()->GetCanvas()->GetMiddleButtonPanLimited() );
+ m_OptMiddleButtonPanLimited->Enable( m_MiddleButtonPANOpt->GetValue() );
+ m_AutoPANOpt->SetValue( GetParent()->GetCanvas()->GetEnableAutoPan() );
+ m_Track_DoubleSegm_Ctrl->SetValue( g_TwoSegmentTrackBuild );
+ m_MagneticPadOptCtrl->SetSelection( g_MagneticPadOption );
+ m_MagneticTrackOptCtrl->SetSelection( g_MagneticTrackOption );
+ m_DumpZonesWhenFilling->SetValue ( g_DumpZonesWhenFilling );
+}
+
+
+void DIALOG_GENERALOPTIONS::OnCancelClick( wxCommandEvent& event )
+{
+ event.Skip();
+}
+
+
+void DIALOG_GENERALOPTIONS::OnOkClick( wxCommandEvent& event )
+{
+ EDA_UNITS_T ii;
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetParent()->GetDisplayOptions();
+
+ displ_opts->m_DisplayPolarCood = ( m_PolarDisplay->GetSelection() == 0 ) ? false : true;
+ ii = g_UserUnit;
+ g_UserUnit = ( m_UnitsSelection->GetSelection() == 0 ) ? INCHES : MILLIMETRES;
+
+ if( ii != g_UserUnit )
+ GetParent()->ReCreateAuxiliaryToolbar();
+
+ GetParent()->SetCursorShape( m_CursorShape->GetSelection() );
+ GetParent()->SetAutoSaveInterval( m_SaveTime->GetValue() * 60 );
+ GetParent()->SetRotationAngle( wxRound( 10.0 * wxAtof( m_RotationAngle->GetValue() ) ) );
+
+ GetParent()->GetScreen()->SetMaxUndoItems( m_spinMaxUndoItems->GetValue() );
+
+ /* Updating the combobox to display the active layer. */
+ displ_opts->m_MaxLinksShowed = m_MaxShowLinks->GetValue();
+ g_Drc_On = m_DrcOn->GetValue();
+
+ if( m_Board->IsElementVisible(RATSNEST_VISIBLE) != m_ShowGlobalRatsnest->GetValue() )
+ {
+ GetParent()->SetElementVisibility( RATSNEST_VISIBLE, m_ShowGlobalRatsnest->GetValue() );
+ GetParent()->GetCanvas()->Refresh();
+ GetParent()->OnModify();
+ }
+
+ displ_opts->m_Show_Module_Ratsnest = m_ShowModuleRatsnest->GetValue();
+ g_AutoDeleteOldTrack = m_TrackAutodel->GetValue();
+ g_Segments_45_Only = m_Segments_45_Only_Ctrl->GetValue();
+ g_Track_45_Only_Allowed = m_Track_45_Only_Ctrl->GetValue();
+
+ GetParent()->GetCanvas()->SetEnableZoomNoCenter( ! m_ZoomCenterOpt->GetValue() );
+ GetParent()->GetCanvas()->SetEnableMousewheelPan( m_MousewheelPANOpt->GetValue() );
+ GetParent()->GetCanvas()->SetEnableMiddleButtonPan( m_MiddleButtonPANOpt->GetValue() );
+ GetParent()->GetCanvas()->SetMiddleButtonPanLimited( m_OptMiddleButtonPanLimited->GetValue() );
+ GetParent()->GetCanvas()->SetEnableAutoPan( m_AutoPANOpt->GetValue() );
+
+ g_TwoSegmentTrackBuild = m_Track_DoubleSegm_Ctrl->GetValue();
+ g_MagneticPadOption = m_MagneticPadOptCtrl->GetSelection();
+ g_MagneticTrackOption = m_MagneticTrackOptCtrl->GetSelection();
+ g_DumpZonesWhenFilling = m_DumpZonesWhenFilling->GetValue();
+
+ EndModal( wxID_OK );
+}
diff --git a/pcbnew/dialogs/dialog_general_options.h b/pcbnew/dialogs/dialog_general_options.h
new file mode 100644
index 0000000..4b4fbe2
--- /dev/null
+++ b/pcbnew/dialogs/dialog_general_options.h
@@ -0,0 +1,53 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __dialog_general_options_h
+#define __dialog_general_options_h
+
+#include <dialog_general_options_BoardEditor_base.h>
+
+class DIALOG_GENERALOPTIONS : public DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE
+{
+private:
+ BOARD* m_Board;
+
+ void init();
+
+public:
+ DIALOG_GENERALOPTIONS( PCB_EDIT_FRAME* parent );
+ ~DIALOG_GENERALOPTIONS() {};
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+
+ PCB_EDIT_FRAME* GetParent() const { return (PCB_EDIT_FRAME*) wxDialog::GetParent(); }
+
+private:
+ void OnMiddleBtnPanEnbl( wxCommandEvent& event )
+ {
+ m_OptMiddleButtonPanLimited->Enable( m_MiddleButtonPANOpt->GetValue() );
+ }
+};
+
+
+#endif // __dialog_general_options_h
diff --git a/pcbnew/dialogs/dialog_general_options_BoardEditor_base.cpp b/pcbnew/dialogs/dialog_general_options_BoardEditor_base.cpp
new file mode 100644
index 0000000..3412d6e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_general_options_BoardEditor_base.cpp
@@ -0,0 +1,240 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_general_options_BoardEditor_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE::DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bLeftSizer;
+ bLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_PolarDisplayChoices[] = { _("Cartesian coordinates"), _("Polar coordinates") };
+ int m_PolarDisplayNChoices = sizeof( m_PolarDisplayChoices ) / sizeof( wxString );
+ m_PolarDisplay = new wxRadioBox( this, wxID_POLAR_CTRL, _("Coordinates"), wxDefaultPosition, wxDefaultSize, m_PolarDisplayNChoices, m_PolarDisplayChoices, 1, wxRA_SPECIFY_COLS );
+ m_PolarDisplay->SetSelection( 1 );
+ m_PolarDisplay->SetToolTip( _("Activates the display of relative coordinates from relative origin (set by the space key)\nto the cursor, in polar coordinates (angle and distance)") );
+
+ bLeftSizer->Add( m_PolarDisplay, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_UnitsSelectionChoices[] = { _("Inches"), _("Millimeters") };
+ int m_UnitsSelectionNChoices = sizeof( m_UnitsSelectionChoices ) / sizeof( wxString );
+ m_UnitsSelection = new wxRadioBox( this, wxID_UNITS, _("Units"), wxDefaultPosition, wxDefaultSize, m_UnitsSelectionNChoices, m_UnitsSelectionChoices, 1, wxRA_SPECIFY_COLS );
+ m_UnitsSelection->SetSelection( 1 );
+ m_UnitsSelection->SetToolTip( _("Selection of units used to display dimensions and positions of items") );
+
+ bLeftSizer->Add( m_UnitsSelection, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_CursorShapeChoices[] = { _("Small cross"), _("Full screen cursor") };
+ int m_CursorShapeNChoices = sizeof( m_CursorShapeChoices ) / sizeof( wxString );
+ m_CursorShape = new wxRadioBox( this, wxID_CURSOR_SHAPE, _("Cursor"), wxDefaultPosition, wxDefaultSize, m_CursorShapeNChoices, m_CursorShapeChoices, 1, wxRA_SPECIFY_COLS );
+ m_CursorShape->SetSelection( 0 );
+ m_CursorShape->SetToolTip( _("Main cursor shape selection (small cross or large cursor)") );
+
+ bLeftSizer->Add( m_CursorShape, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizerUpper->Add( bLeftSizer, 2, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bMiddleLeftSizer;
+ bMiddleLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticTextmaxlinks = new wxStaticText( this, wxID_ANY, _("&Maximum links:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextmaxlinks->Wrap( -1 );
+ fgSizer1->Add( m_staticTextmaxlinks, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_MaxShowLinks = new wxSpinCtrl( this, wxID_ANY, wxT("1"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 5, 1 );
+ m_MaxShowLinks->SetToolTip( _("Adjust the number of ratsnets shown from cursor to closest pads") );
+
+ fgSizer1->Add( m_MaxShowLinks, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxTOP, 5 );
+
+ m_staticTextautosave = new wxStaticText( this, wxID_ANY, _("&Auto save (minutes):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextautosave->Wrap( -1 );
+ fgSizer1->Add( m_staticTextautosave, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_SaveTime = new wxSpinCtrl( this, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 60, 0 );
+ m_SaveTime->SetToolTip( _("Delay after the first change to create a backup file of the board on disk.") );
+
+ fgSizer1->Add( m_SaveTime, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_stMaxUndoItems = new wxStaticText( this, wxID_ANY, _("Ma&ximum undo items:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_stMaxUndoItems->Wrap( -1 );
+ fgSizer1->Add( m_stMaxUndoItems, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_spinMaxUndoItems = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 65536, 1 );
+ fgSizer1->Add( m_spinMaxUndoItems, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_staticTextRotationAngle = new wxStaticText( this, wxID_ANY, _("&Rotation angle:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextRotationAngle->Wrap( -1 );
+ fgSizer1->Add( m_staticTextRotationAngle, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_RotationAngle = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_RotationAngle->SetToolTip( _("Context menu and hot key footprint rotation increment.") );
+
+ fgSizer1->Add( m_RotationAngle, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
+
+
+ bMiddleLeftSizer->Add( fgSizer1, 0, wxEXPAND, 5 );
+
+ wxStaticBoxSizer* bMiddleRightBoxSizer;
+ bMiddleRightBoxSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options") ), wxVERTICAL );
+
+ m_DrcOn = new wxCheckBox( bMiddleRightBoxSizer->GetStaticBox(), wxID_DRC_ONOFF, _("&Enforce design rules when routing"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_DrcOn->SetValue(true);
+ m_DrcOn->SetToolTip( _("Enable/disable the DRC control.\nWhen the DRC control is disabled, all connections are allowed.") );
+
+ bMiddleRightBoxSizer->Add( m_DrcOn, 0, wxALL|wxEXPAND, 5 );
+
+ m_ShowGlobalRatsnest = new wxCheckBox( bMiddleRightBoxSizer->GetStaticBox(), wxID_GENERAL_RATSNEST, _("&Show ratsnest"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ShowGlobalRatsnest->SetValue(true);
+ m_ShowGlobalRatsnest->SetToolTip( _("Show (or not) the full rastnest.") );
+
+ bMiddleRightBoxSizer->Add( m_ShowGlobalRatsnest, 0, wxALL, 5 );
+
+ m_ShowModuleRatsnest = new wxCheckBox( bMiddleRightBoxSizer->GetStaticBox(), wxID_RATSNEST_MODULE, _("S&how footprint ratsnest"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ShowModuleRatsnest->SetToolTip( _("Shows (or not) the local ratsnest relative to a footprint, when moving it.\nThis ratsnest is useful to place a footprint.") );
+
+ bMiddleRightBoxSizer->Add( m_ShowModuleRatsnest, 0, wxALL, 5 );
+
+ m_TrackAutodel = new wxCheckBox( bMiddleRightBoxSizer->GetStaticBox(), wxID_TRACK_AUTODEL, _("&Delete unconnected tracks"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackAutodel->SetToolTip( _("Enable/disable the automatic track deletion when recreating a track.") );
+
+ bMiddleRightBoxSizer->Add( m_TrackAutodel, 0, wxALL, 5 );
+
+ m_Track_45_Only_Ctrl = new wxCheckBox( bMiddleRightBoxSizer->GetStaticBox(), wxID_TRACKS45, _("&Limit tracks to 45 degrees"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Track_45_Only_Ctrl->SetToolTip( _("If enabled, force tracks directions to H, V or 45 degrees, when creating a track.") );
+
+ bMiddleRightBoxSizer->Add( m_Track_45_Only_Ctrl, 0, wxALL, 5 );
+
+ m_Segments_45_Only_Ctrl = new wxCheckBox( bMiddleRightBoxSizer->GetStaticBox(), wxID_SEGMENTS45, _("L&imit graphic lines to 45 degrees"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Segments_45_Only_Ctrl->SetToolTip( _("If enabled, force segments directions to H, V or 45 degrees, when creating a segment on technical layers.") );
+
+ bMiddleRightBoxSizer->Add( m_Segments_45_Only_Ctrl, 0, wxALL, 5 );
+
+ m_Track_DoubleSegm_Ctrl = new wxCheckBox( bMiddleRightBoxSizer->GetStaticBox(), wxID_ANY, _("&Use double segmented tracks"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Track_DoubleSegm_Ctrl->SetToolTip( _("If enabled, uses two track segments, with 45 degrees angle between them when creating a new track ") );
+
+ bMiddleRightBoxSizer->Add( m_Track_DoubleSegm_Ctrl, 0, wxALL, 5 );
+
+
+ bMiddleLeftSizer->Add( bMiddleRightBoxSizer, 4, wxALL|wxEXPAND, 5 );
+
+
+ bSizerUpper->Add( bMiddleLeftSizer, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bRightSizer;
+ bRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_MagneticPadOptCtrlChoices[] = { _("Never"), _("When creating tracks"), _("Always") };
+ int m_MagneticPadOptCtrlNChoices = sizeof( m_MagneticPadOptCtrlChoices ) / sizeof( wxString );
+ m_MagneticPadOptCtrl = new wxRadioBox( this, wxID_ANY, _("Magnetic Pads"), wxDefaultPosition, wxDefaultSize, m_MagneticPadOptCtrlNChoices, m_MagneticPadOptCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_MagneticPadOptCtrl->SetSelection( 0 );
+ m_MagneticPadOptCtrl->SetToolTip( _("control the capture of the pcb cursor when the mouse cursor enters a pad area") );
+
+ bRightSizer->Add( m_MagneticPadOptCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_MagneticTrackOptCtrlChoices[] = { _("Never"), _("When creating tracks"), _("Always") };
+ int m_MagneticTrackOptCtrlNChoices = sizeof( m_MagneticTrackOptCtrlChoices ) / sizeof( wxString );
+ m_MagneticTrackOptCtrl = new wxRadioBox( this, wxID_MAGNETIC_TRACKS, _("Magnetic Tracks"), wxDefaultPosition, wxDefaultSize, m_MagneticTrackOptCtrlNChoices, m_MagneticTrackOptCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_MagneticTrackOptCtrl->SetSelection( 0 );
+ m_MagneticTrackOptCtrl->SetToolTip( _("Control the capture of the pcb cursor when the mouse cursor enters a track") );
+
+ bRightSizer->Add( m_MagneticTrackOptCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbSizer2PAN;
+ sbSizer2PAN = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Pan and Zoom") ), wxVERTICAL );
+
+ m_ZoomCenterOpt = new wxCheckBox( sbSizer2PAN->GetStaticBox(), wxID_ANY, _("Ce&nter and warp cursor on zoom"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ZoomCenterOpt->SetToolTip( _("Keep the cursor at its current location when zooming") );
+
+ sbSizer2PAN->Add( m_ZoomCenterOpt, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_MiddleButtonPANOpt = new wxCheckBox( sbSizer2PAN->GetStaticBox(), wxID_ANY, _("Use middle mouse &button to pan"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MiddleButtonPANOpt->SetToolTip( _("Use middle mouse button dragging to pan") );
+
+ sbSizer2PAN->Add( m_MiddleButtonPANOpt, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_OptMiddleButtonPanLimited = new wxCheckBox( sbSizer2PAN->GetStaticBox(), wxID_MIDDLEBUTTONPAN, _("Limi&t panning to scroll size"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptMiddleButtonPanLimited->SetToolTip( _("Middle mouse button panning limited by current scrollbar size") );
+
+ sbSizer2PAN->Add( m_OptMiddleButtonPanLimited, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_MousewheelPANOpt = new wxCheckBox( sbSizer2PAN->GetStaticBox(), wxID_ANY, _("Use touchpad to pan"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MousewheelPANOpt->SetToolTip( _("Use touchpad to pan canvas") );
+
+ sbSizer2PAN->Add( m_MousewheelPANOpt, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_AutoPANOpt = new wxCheckBox( sbSizer2PAN->GetStaticBox(), wxID_AUTOPAN, _("&Pan while moving object"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_AutoPANOpt->SetToolTip( _("Allows auto pan when creating a track, or moving an item.") );
+
+ sbSizer2PAN->Add( m_AutoPANOpt, 0, wxALL, 5 );
+
+
+ bRightSizer->Add( sbSizer2PAN, 1, wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbSizer2Adv;
+ sbSizer2Adv = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Advanced/Developer") ), wxVERTICAL );
+
+ m_DumpZonesWhenFilling = new wxCheckBox( sbSizer2Adv->GetStaticBox(), wxID_ANY, _("Dump zone geometry to files when filling"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizer2Adv->Add( m_DumpZonesWhenFilling, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
+
+
+ bRightSizer->Add( sbSizer2Adv, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizerUpper->Add( bRightSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bSizerUpper, 0, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline1, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bMainSizer->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ m_MiddleButtonPANOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE::OnMiddleBtnPanEnbl ), NULL, this );
+ m_DumpZonesWhenFilling->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE::OnMiddleBtnPanEnbl ), NULL, this );
+ m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE::~DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE()
+{
+ // Disconnect Events
+ m_MiddleButtonPANOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE::OnMiddleBtnPanEnbl ), NULL, this );
+ m_DumpZonesWhenFilling->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE::OnMiddleBtnPanEnbl ), NULL, this );
+ m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_general_options_BoardEditor_base.fbp b/pcbnew/dialogs/dialog_general_options_BoardEditor_base.fbp
new file mode 100644
index 0000000..4374147
--- /dev/null
+++ b/pcbnew/dialogs/dialog_general_options_BoardEditor_base.fbp
@@ -0,0 +1,2591 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_general_options_BoardEditor_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DialogGeneralOptionsBoardEditor_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">General Settings</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">2</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Cartesian coordinates&quot; &quot;Polar coordinates&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_POLAR_CTRL</property>
+ <property name="label">Coordinates</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PolarDisplay</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Activates the display of relative coordinates from relative origin (set by the space key)&#x0A;to the cursor, in polar coordinates (angle and distance)</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Inches&quot; &quot;Millimeters&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_UNITS</property>
+ <property name="label">Units</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_UnitsSelection</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Selection of units used to display dimensions and positions of items</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Small cross&quot; &quot;Full screen cursor&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CURSOR_SHAPE</property>
+ <property name="label">Cursor</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CursorShape</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Main cursor shape selection (small cross or large cursor)</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMiddleLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Maximum links:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextmaxlinks</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">1</property>
+ <property name="max">5</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaxShowLinks</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Adjust the number of ratsnets shown from cursor to closest pads</property>
+ <property name="value">1</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Auto save (minutes):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextautosave</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">0</property>
+ <property name="max">60</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SaveTime</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Delay after the first change to create a backup file of the board on disk.</property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Ma&amp;ximum undo items:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_stMaxUndoItems</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">1</property>
+ <property name="max">65536</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinMaxUndoItems</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Rotation angle:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextRotationAngle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_RotationAngle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Context menu and hot key footprint rotation increment.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">4</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Options</property>
+ <property name="minimum_size"></property>
+ <property name="name">bMiddleRightBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_DRC_ONOFF</property>
+ <property name="label">&amp;Enforce design rules when routing</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DrcOn</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enable/disable the DRC control.&#x0A;When the DRC control is disabled, all connections are allowed.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_GENERAL_RATSNEST</property>
+ <property name="label">&amp;Show ratsnest</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShowGlobalRatsnest</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Show (or not) the full rastnest.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_RATSNEST_MODULE</property>
+ <property name="label">S&amp;how footprint ratsnest</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShowModuleRatsnest</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Shows (or not) the local ratsnest relative to a footprint, when moving it.&#x0A;This ratsnest is useful to place a footprint.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_TRACK_AUTODEL</property>
+ <property name="label">&amp;Delete unconnected tracks</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackAutodel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enable/disable the automatic track deletion when recreating a track.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_TRACKS45</property>
+ <property name="label">&amp;Limit tracks to 45 degrees</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Track_45_Only_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If enabled, force tracks directions to H, V or 45 degrees, when creating a track.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_SEGMENTS45</property>
+ <property name="label">L&amp;imit graphic lines to 45 degrees</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Segments_45_Only_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If enabled, force segments directions to H, V or 45 degrees, when creating a segment on technical layers.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Use double segmented tracks</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Track_DoubleSegm_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If enabled, uses two track segments, with 45 degrees angle between them when creating a new track </property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Never&quot; &quot;When creating tracks&quot; &quot;Always&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Magnetic Pads</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MagneticPadOptCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">control the capture of the pcb cursor when the mouse cursor enters a pad area</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Never&quot; &quot;When creating tracks&quot; &quot;Always&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_MAGNETIC_TRACKS</property>
+ <property name="label">Magnetic Tracks</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MagneticTrackOptCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Control the capture of the pcb cursor when the mouse cursor enters a track</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pan and Zoom</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizer2PAN</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Ce&amp;nter and warp cursor on zoom</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ZoomCenterOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Keep the cursor at its current location when zooming</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Use middle mouse &amp;button to pan</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MiddleButtonPANOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Use middle mouse button dragging to pan</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnMiddleBtnPanEnbl</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_MIDDLEBUTTONPAN</property>
+ <property name="label">Limi&amp;t panning to scroll size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptMiddleButtonPanLimited</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Middle mouse button panning limited by current scrollbar size</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Use touchpad to pan</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MousewheelPANOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Use touchpad to pan canvas</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_AUTOPAN</property>
+ <property name="label">&amp;Pan while moving object</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AutoPANOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Allows auto pan when creating a track, or moving an item.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Advanced/Developer</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizer2Adv</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Dump zone geometry to files when filling</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DumpZonesWhenFilling</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnMiddleBtnPanEnbl</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_general_options_BoardEditor_base.h b/pcbnew/dialogs/dialog_general_options_BoardEditor_base.h
new file mode 100644
index 0000000..6bb5bb0
--- /dev/null
+++ b/pcbnew/dialogs/dialog_general_options_BoardEditor_base.h
@@ -0,0 +1,103 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_GENERAL_OPTIONS_BOARDEDITOR_BASE_H__
+#define __DIALOG_GENERAL_OPTIONS_BOARDEDITOR_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/radiobox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/stattext.h>
+#include <wx/spinctrl.h>
+#include <wx/textctrl.h>
+#include <wx/checkbox.h>
+#include <wx/statbox.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ wxID_POLAR_CTRL = 1000,
+ wxID_UNITS,
+ wxID_CURSOR_SHAPE,
+ wxID_DRC_ONOFF,
+ wxID_GENERAL_RATSNEST,
+ wxID_RATSNEST_MODULE,
+ wxID_TRACK_AUTODEL,
+ wxID_TRACKS45,
+ wxID_SEGMENTS45,
+ wxID_MAGNETIC_TRACKS,
+ wxID_MIDDLEBUTTONPAN,
+ wxID_AUTOPAN
+ };
+
+ wxRadioBox* m_PolarDisplay;
+ wxRadioBox* m_UnitsSelection;
+ wxRadioBox* m_CursorShape;
+ wxStaticText* m_staticTextmaxlinks;
+ wxSpinCtrl* m_MaxShowLinks;
+ wxStaticText* m_staticTextautosave;
+ wxSpinCtrl* m_SaveTime;
+ wxStaticText* m_stMaxUndoItems;
+ wxSpinCtrl* m_spinMaxUndoItems;
+ wxStaticText* m_staticTextRotationAngle;
+ wxTextCtrl* m_RotationAngle;
+ wxCheckBox* m_DrcOn;
+ wxCheckBox* m_ShowGlobalRatsnest;
+ wxCheckBox* m_ShowModuleRatsnest;
+ wxCheckBox* m_TrackAutodel;
+ wxCheckBox* m_Track_45_Only_Ctrl;
+ wxCheckBox* m_Segments_45_Only_Ctrl;
+ wxCheckBox* m_Track_DoubleSegm_Ctrl;
+ wxRadioBox* m_MagneticPadOptCtrl;
+ wxRadioBox* m_MagneticTrackOptCtrl;
+ wxCheckBox* m_ZoomCenterOpt;
+ wxCheckBox* m_MiddleButtonPANOpt;
+ wxCheckBox* m_OptMiddleButtonPanLimited;
+ wxCheckBox* m_MousewheelPANOpt;
+ wxCheckBox* m_AutoPANOpt;
+ wxCheckBox* m_DumpZonesWhenFilling;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnMiddleBtnPanEnbl( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("General Settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_GENERALOPTIONS_BOARDEDITOR_BASE();
+
+};
+
+#endif //__DIALOG_GENERAL_OPTIONS_BOARDEDITOR_BASE_H__
diff --git a/pcbnew/dialogs/dialog_global_deletion.cpp b/pcbnew/dialogs/dialog_global_deletion.cpp
new file mode 100644
index 0000000..8d1c2b4
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_deletion.cpp
@@ -0,0 +1,275 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <boost/bind.hpp>
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <ratsnest_data.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_zone.h>
+
+#include <dialog_global_deletion.h>
+
+
+DIALOG_GLOBAL_DELETION::DIALOG_GLOBAL_DELETION( PCB_EDIT_FRAME* parent ) :
+ DIALOG_GLOBAL_DELETION_BASE( parent )
+{
+ m_Parent = parent;
+ m_currentLayer = F_Cu;
+ m_TrackFilterAR->Enable( m_DelTracks->GetValue() );
+ m_TrackFilterLocked->Enable( m_DelTracks->GetValue() );
+ m_TrackFilterNormal->Enable( m_DelTracks->GetValue() );
+ m_TrackFilterVias->Enable( m_DelTracks->GetValue() );
+ m_ModuleFilterLocked->Enable( m_DelModules->GetValue() );
+ m_ModuleFilterNormal->Enable( m_DelModules->GetValue() );
+ m_sdbSizer1OK->SetDefault();
+ SetFocus();
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+
+void PCB_EDIT_FRAME::InstallPcbGlobalDeleteFrame( const wxPoint& pos )
+{
+ DIALOG_GLOBAL_DELETION dlg( this );
+ dlg.SetCurrentLayer( GetActiveLayer() );
+
+ dlg.ShowModal();
+}
+
+
+void DIALOG_GLOBAL_DELETION::SetCurrentLayer( LAYER_NUM aLayer )
+{
+ m_currentLayer = aLayer;
+ m_textCtrlCurrLayer->SetValue( m_Parent->GetBoard()->GetLayerName( ToLAYER_ID( aLayer ) ) );
+}
+
+
+void DIALOG_GLOBAL_DELETION::OnCheckDeleteTracks( wxCommandEvent& event )
+{
+ m_TrackFilterAR->Enable( m_DelTracks->GetValue() );
+ m_TrackFilterLocked->Enable( m_DelTracks->GetValue() );
+ m_TrackFilterNormal->Enable( m_DelTracks->GetValue() );
+ m_TrackFilterVias->Enable( m_DelTracks->GetValue() );
+}
+
+
+void DIALOG_GLOBAL_DELETION::OnCheckDeleteModules( wxCommandEvent& event )
+{
+ m_ModuleFilterLocked->Enable( m_DelModules->GetValue() );
+ m_ModuleFilterNormal->Enable( m_DelModules->GetValue() );
+}
+
+
+void DIALOG_GLOBAL_DELETION::AcceptPcbDelete()
+{
+ bool gen_rastnest = false;
+
+ m_Parent->SetCurItem( NULL );
+
+ bool delAll = false;
+
+ if( m_DelAlls->GetValue() )
+ {
+ if( !IsOK( this, _( "Are you sure you want to delete the entire board?" ) ) )
+ return;
+
+ delAll = true;
+ }
+ else if( !IsOK( this, _( "Are you sure you want to delete the selected items?" ) ) )
+ return;
+
+ BOARD* pcb = m_Parent->GetBoard();
+ PICKED_ITEMS_LIST pickersList;
+ ITEM_PICKER itemPicker( NULL, UR_DELETED );
+ BOARD_ITEM* item;
+ BOARD_ITEM* nextitem;
+ RN_DATA* ratsnest = pcb->GetRatsnest();
+
+ LSET layers_filter = LSET().set();
+
+ if( m_rbLayersOption->GetSelection() != 0 ) // Use current layer only
+ layers_filter = LSET( ToLAYER_ID( m_currentLayer ) );
+
+ if( delAll || m_DelZones->GetValue() )
+ {
+ int area_index = 0;
+ item = pcb->GetArea( area_index );
+
+ while( item )
+ {
+ if( delAll || layers_filter[item->GetLayer()] )
+ {
+ itemPicker.SetItem( item );
+ pickersList.PushItem( itemPicker );
+ pcb->Remove( item );
+ item->ViewRelease();
+ ratsnest->Remove( item );
+ gen_rastnest = true;
+ }
+ else
+ {
+ area_index++;
+ }
+
+ item = pcb->GetArea( area_index );
+ }
+ }
+
+ if( delAll || m_DelDrawings->GetValue() || m_DelBoardEdges->GetValue() )
+ {
+ LSET masque_layer;
+
+ if( m_DelDrawings->GetValue() )
+ masque_layer = LSET::AllNonCuMask().set( Edge_Cuts, false );
+
+ if( m_DelBoardEdges->GetValue() )
+ masque_layer.set( Edge_Cuts );
+
+ masque_layer &= layers_filter;
+
+ for( item = pcb->m_Drawings; item; item = nextitem )
+ {
+ nextitem = item->Next();
+
+ if( delAll ||
+ ( item->Type() == PCB_LINE_T && masque_layer[item->GetLayer()] ) )
+ {
+ itemPicker.SetItem( item );
+ pickersList.PushItem( itemPicker );
+ item->ViewRelease();
+ item->UnLink();
+ }
+ }
+ }
+
+ if( delAll || m_DelTexts->GetValue() )
+ {
+ LSET del_text_layers = layers_filter;
+
+ for( item = pcb->m_Drawings; item; item = nextitem )
+ {
+ nextitem = item->Next();
+
+ if( delAll ||
+ ( item->Type() == PCB_TEXT_T && del_text_layers[item->GetLayer()] ) )
+ {
+ itemPicker.SetItem( item );
+ pickersList.PushItem( itemPicker );
+ item->ViewRelease();
+ item->UnLink();
+ }
+ }
+ }
+
+ if( delAll || m_DelModules->GetValue() )
+ {
+ for( item = pcb->m_Modules; item; item = nextitem )
+ {
+ nextitem = item->Next();
+
+ bool del_fp = delAll;
+
+ if( layers_filter[item->GetLayer()] &&
+ ( ( m_ModuleFilterNormal->GetValue() && !item->IsLocked() ) ||
+ ( m_ModuleFilterLocked->GetValue() && item->IsLocked() ) ) )
+ del_fp = true;
+
+ if( del_fp )
+ {
+ itemPicker.SetItem( item );
+ pickersList.PushItem( itemPicker );
+ static_cast<MODULE*>( item )->RunOnChildren(
+ boost::bind( &KIGFX::VIEW_ITEM::ViewRelease, _1 ) );
+ ratsnest->Remove( item );
+ item->ViewRelease();
+ item->UnLink();
+ gen_rastnest = true;
+ }
+ }
+ }
+
+ if( delAll || m_DelTracks->GetValue() )
+ {
+ STATUS_FLAGS track_mask_filter = 0;
+
+ if( !m_TrackFilterLocked->GetValue() )
+ track_mask_filter |= TRACK_LOCKED;
+
+ if( !m_TrackFilterAR->GetValue() )
+ track_mask_filter |= TRACK_AR;
+
+ TRACK* nexttrack;
+
+ for( TRACK *track = pcb->m_Track; track; track = nexttrack )
+ {
+ nexttrack = track->Next();
+
+ if( !delAll )
+ {
+ if( ( track->GetState( TRACK_LOCKED | TRACK_AR ) & track_mask_filter ) != 0 )
+ continue;
+
+ if( ( track->GetState( TRACK_LOCKED | TRACK_AR ) == 0 ) &&
+ !m_TrackFilterNormal->GetValue() )
+ continue;
+
+ if( ( track->Type() == PCB_VIA_T ) && !m_TrackFilterVias->GetValue() )
+ continue;
+
+ if( ( track->GetLayerSet() & layers_filter ) == 0 )
+ continue;
+ }
+
+ itemPicker.SetItem( track );
+ pickersList.PushItem( itemPicker );
+ track->ViewRelease();
+ ratsnest->Remove( track );
+ track->UnLink();
+ gen_rastnest = true;
+ }
+ }
+
+ if( pickersList.GetCount() )
+ m_Parent->SaveCopyInUndoList( pickersList, UR_DELETED );
+
+ if( m_DelMarkers->GetValue() )
+ pcb->DeleteMARKERs();
+
+ if( gen_rastnest )
+ m_Parent->Compile_Ratsnest( NULL, true );
+
+ // There is a chance that some of tracks have changed their nets, so rebuild ratsnest from scratch
+ if( m_Parent->IsGalCanvasActive() )
+ pcb->GetRatsnest()->ProcessBoard();
+
+ m_Parent->GetCanvas()->Refresh();
+ m_Parent->OnModify();
+}
diff --git a/pcbnew/dialogs/dialog_global_deletion.h b/pcbnew/dialogs/dialog_global_deletion.h
new file mode 100644
index 0000000..e38b495
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_deletion.h
@@ -0,0 +1,55 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _DIALOG_GLOBAL_DELETION_H_
+#define _DIALOG_GLOBAL_DELETION_H_
+
+#include <dialog_global_deletion_base.h>
+
+class DIALOG_GLOBAL_DELETION: public DIALOG_GLOBAL_DELETION_BASE
+{
+public:
+ DIALOG_GLOBAL_DELETION( PCB_EDIT_FRAME* parent );
+ void SetCurrentLayer( LAYER_NUM aLayer );
+
+private:
+ PCB_EDIT_FRAME* m_Parent;
+ LAYER_NUM m_currentLayer;
+
+ void OnOkClick( wxCommandEvent& event )
+ {
+ AcceptPcbDelete();
+ EndModal(wxID_OK);
+ }
+
+ void OnCancelClick( wxCommandEvent& event )
+ {
+ EndModal(wxID_CANCEL);
+ }
+
+ void AcceptPcbDelete();
+ void OnCheckDeleteTracks( wxCommandEvent& event );
+ void OnCheckDeleteModules( wxCommandEvent& event );
+};
+
+#endif // _DIALOG_GLOBAL_DELETION_H_
diff --git a/pcbnew/dialogs/dialog_global_deletion_base.cpp b/pcbnew/dialogs/dialog_global_deletion_base.cpp
new file mode 100644
index 0000000..6d851bb
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_deletion_base.cpp
@@ -0,0 +1,145 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_global_deletion_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_GLOBAL_DELETION_BASE::DIALOG_GLOBAL_DELETION_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sbSizerLeft;
+ sbSizerLeft = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Items to Delete") ), wxVERTICAL );
+
+ m_DelZones = new wxCheckBox( this, wxID_ANY, _("Zones"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_DelZones, 0, wxALL, 5 );
+
+ m_DelTexts = new wxCheckBox( this, wxID_ANY, _("Text"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_DelTexts, 0, wxALL, 5 );
+
+ m_DelBoardEdges = new wxCheckBox( this, wxID_ANY, _("Board outlines"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_DelBoardEdges, 0, wxALL, 5 );
+
+ m_DelDrawings = new wxCheckBox( this, wxID_ANY, _("Drawings"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_DelDrawings, 0, wxALL, 5 );
+
+ m_DelModules = new wxCheckBox( this, wxID_ANY, _("Footprints"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_DelModules, 0, wxALL, 5 );
+
+ m_DelTracks = new wxCheckBox( this, wxID_ANY, _("Tracks"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_DelTracks, 0, wxALL, 5 );
+
+ m_DelMarkers = new wxCheckBox( this, wxID_ANY, _("Markers"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_DelMarkers, 0, wxALL, 5 );
+
+ m_DelAlls = new wxCheckBox( this, wxID_ANY, _("Clear board"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_DelAlls, 0, wxALL, 5 );
+
+
+ bSizerUpper->Add( sbSizerLeft, 2, wxEXPAND|wxALL, 5 );
+
+ wxBoxSizer* bSizerRight;
+ bSizerRight = new wxBoxSizer( wxVERTICAL );
+
+ sbFilter = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Filter Settings") ), wxVERTICAL );
+
+ m_TrackFilterAR = new wxCheckBox( this, wxID_ANY, _("Automatically routed tracks"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackFilterAR->SetValue(true);
+ sbFilter->Add( m_TrackFilterAR, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_TrackFilterLocked = new wxCheckBox( this, wxID_ANY, _("Locked tracks"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbFilter->Add( m_TrackFilterLocked, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_TrackFilterNormal = new wxCheckBox( this, wxID_ANY, _("Unlocked tracks"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackFilterNormal->SetValue(true);
+ sbFilter->Add( m_TrackFilterNormal, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_TrackFilterVias = new wxCheckBox( this, wxID_ANY, _("Vias"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackFilterVias->SetValue(true);
+ sbFilter->Add( m_TrackFilterVias, 0, wxALL, 5 );
+
+ m_ModuleFilterLocked = new wxCheckBox( this, wxID_ANY, _("Locked footprints"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbFilter->Add( m_ModuleFilterLocked, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_ModuleFilterNormal = new wxCheckBox( this, wxID_ANY, _("Unlocked footprints"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ModuleFilterNormal->SetValue(true);
+ sbFilter->Add( m_ModuleFilterNormal, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+
+ bSizerRight->Add( sbFilter, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_rbLayersOptionChoices[] = { _("All layers"), _("Current layer only") };
+ int m_rbLayersOptionNChoices = sizeof( m_rbLayersOptionChoices ) / sizeof( wxString );
+ m_rbLayersOption = new wxRadioBox( this, wxID_ANY, _("Layer Filter"), wxDefaultPosition, wxDefaultSize, m_rbLayersOptionNChoices, m_rbLayersOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_rbLayersOption->SetSelection( 0 );
+ bSizerRight->Add( m_rbLayersOption, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizerUpper->Add( bSizerRight, 3, wxALL|wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bSizerUpper, 1, wxALL|wxEXPAND, 5 );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 );
+ fgSizer1->AddGrowableCol( 1 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText1 = new wxStaticText( this, wxID_ANY, _("Current layer:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ fgSizer1->Add( m_staticText1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_textCtrlCurrLayer = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
+ m_textCtrlCurrLayer->SetMaxLength( 0 );
+ fgSizer1->Add( m_textCtrlCurrLayer, 0, wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bSizerMain->Add( fgSizer1, 0, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerMain->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bSizerMain->Add( m_sdbSizer1, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+ bSizerMain->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_DelModules->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_DELETION_BASE::OnCheckDeleteModules ), NULL, this );
+ m_DelTracks->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_DELETION_BASE::OnCheckDeleteTracks ), NULL, this );
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_DELETION_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_DELETION_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_GLOBAL_DELETION_BASE::~DIALOG_GLOBAL_DELETION_BASE()
+{
+ // Disconnect Events
+ m_DelModules->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_DELETION_BASE::OnCheckDeleteModules ), NULL, this );
+ m_DelTracks->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_DELETION_BASE::OnCheckDeleteTracks ), NULL, this );
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_DELETION_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_DELETION_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_global_deletion_base.fbp b/pcbnew/dialogs/dialog_global_deletion_base.fbp
new file mode 100644
index 0000000..98ee3b1
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_deletion_base.fbp
@@ -0,0 +1,1770 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_global_deletion_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_global_deletion</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_GLOBAL_DELETION_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Delete Items</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">2</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Items to Delete</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerLeft</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Zones</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DelZones</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DelTexts</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Board outlines</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DelBoardEdges</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Drawings</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DelDrawings</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprints</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DelModules</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckDeleteModules</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Tracks</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DelTracks</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckDeleteTracks</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Markers</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DelMarkers</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Clear board</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DelAlls</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">3</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRight</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Filter Settings</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbFilter</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Automatically routed tracks</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackFilterAR</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Locked tracks</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackFilterLocked</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unlocked tracks</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackFilterNormal</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Vias</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackFilterVias</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Locked footprints</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ModuleFilterLocked</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unlocked footprints</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ModuleFilterNormal</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;All layers&quot; &quot;Current layer only&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layer Filter</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbLayersOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Current layer:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlCurrLayer</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_global_deletion_base.h b/pcbnew/dialogs/dialog_global_deletion_base.h
new file mode 100644
index 0000000..12cc276
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_deletion_base.h
@@ -0,0 +1,80 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_GLOBAL_DELETION_BASE_H__
+#define __DIALOG_GLOBAL_DELETION_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/checkbox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/radiobox.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_GLOBAL_DELETION_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_GLOBAL_DELETION_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxCheckBox* m_DelZones;
+ wxCheckBox* m_DelTexts;
+ wxCheckBox* m_DelBoardEdges;
+ wxCheckBox* m_DelDrawings;
+ wxCheckBox* m_DelModules;
+ wxCheckBox* m_DelTracks;
+ wxCheckBox* m_DelMarkers;
+ wxCheckBox* m_DelAlls;
+ wxStaticBoxSizer* sbFilter;
+ wxCheckBox* m_TrackFilterAR;
+ wxCheckBox* m_TrackFilterLocked;
+ wxCheckBox* m_TrackFilterNormal;
+ wxCheckBox* m_TrackFilterVias;
+ wxCheckBox* m_ModuleFilterLocked;
+ wxCheckBox* m_ModuleFilterNormal;
+ wxRadioBox* m_rbLayersOption;
+ wxStaticText* m_staticText1;
+ wxTextCtrl* m_textCtrlCurrLayer;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCheckDeleteModules( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCheckDeleteTracks( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_GLOBAL_DELETION_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Delete Items"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_GLOBAL_DELETION_BASE();
+
+};
+
+#endif //__DIALOG_GLOBAL_DELETION_BASE_H__
diff --git a/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.cpp b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.cpp
new file mode 100644
index 0000000..91c749a
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.cpp
@@ -0,0 +1,229 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <class_drawpanel.h>
+#include <base_units.h>
+
+#include <class_board.h>
+
+#include <dialog_global_edit_tracks_and_vias.h>
+
+
+/**
+ * DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS, derived from DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE_BASE
+ * @see dialog_global_edit_tracks_and_vias_base.h and dialog_global_edit_tracks_and_vias_base.cpp,
+ * automatically created by wxFormBuilder
+ */
+
+DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS( PCB_EDIT_FRAME* aParent,
+ int aNetcode ) :
+ DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE( aParent )
+{
+ m_Parent = aParent;
+ m_Netcode = aNetcode;
+ m_OptionID = 0;
+ MyInit();
+ GetSizer()->SetSizeHints( this );
+ Layout();
+}
+
+
+void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::MyInit()
+{
+ SetFocus();
+
+ wxString msg;
+
+ // Display current setup for tracks and vias
+ BOARD* board = m_Parent->GetBoard();
+ BOARD_DESIGN_SETTINGS& dsnSettings = board->GetDesignSettings();
+ NETCLASSES& netclasses = dsnSettings.m_NetClasses;
+ NETCLASSPTR netclass = netclasses.GetDefault();
+ NETINFO_ITEM* net = board->FindNet( m_Netcode );
+
+ if( net )
+ {
+ m_CurrentNetName->SetLabel( net->GetNetname() );
+ m_CurrentNetclassName->SetLabel( dsnSettings.GetCurrentNetClassName() );
+ netclass = netclasses.Find( dsnSettings.GetCurrentNetClassName() );
+ }
+
+ /* Disable the option "copy current to net" if we have only default netclass values
+ * i.e. when m_TrackWidthSelector and m_ViaSizeSelector are set to 0
+ */
+ if( !dsnSettings.GetTrackWidthIndex() && !dsnSettings.GetViaSizeIndex() )
+ {
+ m_Net2CurrValueButton->Enable( false );
+ m_OptionID = ID_NETCLASS_VALUES_TO_CURRENT_NET;
+ m_NetUseNetclassValueButton->SetValue(true);
+ }
+ else
+ {
+ m_OptionID = ID_CURRENT_VALUES_TO_CURRENT_NET;
+ m_Net2CurrValueButton->SetValue(true);
+ }
+
+ // Display current values, and current netclass values:
+ int value = netclass->GetTrackWidth(); // Display track width
+ msg = StringFromValue( g_UserUnit, value, true );
+ m_gridDisplayCurrentSettings->SetCellValue( 0, 0, msg );
+
+ if( dsnSettings.GetTrackWidthIndex() )
+ {
+ value = dsnSettings.GetCurrentTrackWidth();
+ msg = StringFromValue( g_UserUnit, value, true );
+ }
+ else
+ msg = _( "Default" );
+
+ m_gridDisplayCurrentSettings->SetCellValue( 1, 0, msg );
+
+ value = netclass->GetViaDiameter(); // Display via diameter
+ msg = StringFromValue( g_UserUnit, value, true );
+ m_gridDisplayCurrentSettings->SetCellValue( 0, 1, msg );
+
+ if( dsnSettings.GetViaSizeIndex() )
+ {
+ value = dsnSettings.GetCurrentViaSize();
+ msg = StringFromValue( g_UserUnit, value, true );
+ }
+ else
+ msg = _( "Default" );
+ m_gridDisplayCurrentSettings->SetCellValue( 1, 1, msg );
+
+ value = netclass->GetViaDrill(); // Display via drill
+ msg = StringFromValue( g_UserUnit, value, true );
+ m_gridDisplayCurrentSettings->SetCellValue( 0, 2, msg );
+ value = dsnSettings.GetCurrentViaDrill();
+ if( value >= 0 )
+ msg = StringFromValue( g_UserUnit, value, true );
+ else
+ msg = _( "Default" );
+ m_gridDisplayCurrentSettings->SetCellValue( 1, 2, msg );
+
+ value = netclass->GetuViaDiameter(); // Display micro via diameter
+ msg = StringFromValue( g_UserUnit, value, true );
+ m_gridDisplayCurrentSettings->SetCellValue( 0, 3, msg );
+#if 0 // Currently we use always the default netclass value
+ value = board->GetCurrentMicroViaSize();
+ msg = StringFromValue( g_UserUnit, value, true );
+#endif
+ msg = _( "Default" );
+ m_gridDisplayCurrentSettings->SetCellValue( 1, 3, msg );
+
+ value = netclass->GetuViaDrill(); // Display micro via drill
+ msg = StringFromValue( g_UserUnit, value, true );
+ m_gridDisplayCurrentSettings->SetCellValue( 0, 4, msg );
+#if 0 // Currently we use always the default netclass value
+ value = board->GetCurrentMicroViaDrill();
+ if( value >= 0 )
+ msg = StringFromValue( g_UserUnit, value, true );
+ else
+#endif
+ msg = _( "Default" );
+ m_gridDisplayCurrentSettings->SetCellValue( 1, 4, msg );
+
+ // Set all cells Read Only
+ for( int ii = 0; ii < m_gridDisplayCurrentSettings->GetNumberRows(); ii++ )
+ {
+ for( int jj = 0; jj < m_gridDisplayCurrentSettings->GetNumberCols(); jj++ )
+ m_gridDisplayCurrentSettings->SetReadOnly( ii, jj, true );
+ }
+
+ // needs wxWidgets version >= 2.8.8:
+ m_gridDisplayCurrentSettings->SetRowLabelSize(wxGRID_AUTOSIZE);
+
+ m_gridDisplayCurrentSettings->Fit();
+}
+
+
+void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::OnOkClick( wxCommandEvent& event )
+{
+ bool change = false;
+
+ switch( m_OptionID )
+ {
+ case ID_CURRENT_VALUES_TO_CURRENT_NET:
+ if( !IsOK( this,
+ _( "Set current Net tracks and vias sizes and drill to the current values?" ) ) )
+ return;
+ {
+ wxBusyCursor dummy;
+ change = m_Parent->Change_Net_Tracks_And_Vias_Sizes( m_Netcode, false );
+ }
+ break;
+
+ case ID_NETCLASS_VALUES_TO_CURRENT_NET:
+ if( !IsOK( this,
+ _( "Set current Net tracks and vias sizes and drill to the Netclass default value?" ) ) )
+ return;
+ {
+ wxBusyCursor dummy;
+ change = m_Parent->Change_Net_Tracks_And_Vias_Sizes( m_Netcode, true );
+ }
+ break;
+
+ case ID_ALL_TRACKS_VIAS:
+ if( !IsOK( this, _( "Set All Tracks and Vias to Netclass value" ) ) )
+ return;
+ {
+ wxBusyCursor dummy;
+ change = m_Parent->Reset_All_Tracks_And_Vias_To_Netclass_Values( true, true );
+ }
+ break;
+
+ case ID_ALL_VIAS:
+ if( !IsOK( this, _( "Set All Via to Netclass value" ) ) )
+ return;
+ {
+ wxBusyCursor dummy;
+ change = m_Parent->Reset_All_Tracks_And_Vias_To_Netclass_Values( false, true );
+ }
+ break;
+
+ case ID_ALL_TRACKS:
+ if( !IsOK( this, _( "Set All Track to Netclass value" ) ) )
+ return;
+ {
+ wxBusyCursor dummy;
+ change = m_Parent->Reset_All_Tracks_And_Vias_To_Netclass_Values( true, false );
+ }
+ break;
+ }
+
+ EndModal( 1 );
+
+ if( change )
+ m_Parent->GetCanvas()->Refresh();
+}
+
+
+void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( 0 );
+}
diff --git a/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.h b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.h
new file mode 100644
index 0000000..6114239
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias.h
@@ -0,0 +1,52 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2009 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 1992-2009 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __dialog_global_edit_tracks_and_vias__
+#define __dialog_global_edit_tracks_and_vias__
+
+#include <dialog_global_edit_tracks_and_vias_base.h>
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS :
+ public DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE
+{
+private:
+ PCB_EDIT_FRAME* m_Parent;
+ int m_Netcode;
+ int m_OptionID;
+
+public:
+ DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS( PCB_EDIT_FRAME* aParent, int aNetcode );
+ ~DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS() {};
+
+ // Virtual event handlers, overided here
+ void OnSelectionClick( wxCommandEvent& event ){ m_OptionID = event.GetId(); }
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+ void MyInit();
+};
+
+#endif //__dialog_global_edit_tracks_and_vias__
diff --git a/pcbnew/dialogs/dialog_global_edit_tracks_and_vias_base.cpp b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias_base.cpp
new file mode 100644
index 0000000..e931e89
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias_base.cpp
@@ -0,0 +1,192 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Apr 10 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_global_edit_tracks_and_vias_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerCurrSettings;
+ bSizerCurrSettings = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText12 = new wxStaticText( this, wxID_ANY, _("Current Settings:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText12->Wrap( -1 );
+ m_staticText12->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizerCurrSettings->Add( m_staticText12, 0, wxALL, 5 );
+
+ wxBoxSizer* bSizerCurrSettingsLeft;
+ bSizerCurrSettingsLeft = new wxBoxSizer( wxHORIZONTAL );
+
+
+ bSizerCurrSettingsLeft->Add( 20, 0, 0, 0, 5 );
+
+ wxBoxSizer* bSizerGrids;
+ bSizerGrids = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizeNetInfo;
+ fgSizeNetInfo = new wxFlexGridSizer( 2, 2, 0, 0 );
+ fgSizeNetInfo->SetFlexibleDirection( wxBOTH );
+ fgSizeNetInfo->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_CurrentNetText = new wxStaticText( this, wxID_ANY, _("Current Net:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_CurrentNetText->Wrap( -1 );
+ fgSizeNetInfo->Add( m_CurrentNetText, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_CurrentNetName = new wxStaticText( this, wxID_ANY, _("NetName"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_CurrentNetName->Wrap( -1 );
+ m_CurrentNetName->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ fgSizeNetInfo->Add( m_CurrentNetName, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_CurrentNetclassText = new wxStaticText( this, wxID_ANY, _("Current NetClass:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_CurrentNetclassText->Wrap( -1 );
+ fgSizeNetInfo->Add( m_CurrentNetclassText, 0, wxALL, 5 );
+
+ m_CurrentNetclassName = new wxStaticText( this, wxID_ANY, _("NetClassName"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_CurrentNetclassName->Wrap( -1 );
+ m_CurrentNetclassName->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ fgSizeNetInfo->Add( m_CurrentNetclassName, 0, wxALL, 5 );
+
+
+ bSizerGrids->Add( fgSizeNetInfo, 0, wxEXPAND, 5 );
+
+
+ bSizerGrids->Add( 10, 10, 0, 0, 5 );
+
+ m_gridDisplayCurrentSettings = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_gridDisplayCurrentSettings->CreateGrid( 2, 5 );
+ m_gridDisplayCurrentSettings->EnableEditing( true );
+ m_gridDisplayCurrentSettings->EnableGridLines( true );
+ m_gridDisplayCurrentSettings->EnableDragGridSize( true );
+ m_gridDisplayCurrentSettings->SetMargins( 10, 0 );
+
+ // Columns
+ m_gridDisplayCurrentSettings->AutoSizeColumns();
+ m_gridDisplayCurrentSettings->EnableDragColMove( false );
+ m_gridDisplayCurrentSettings->EnableDragColSize( true );
+ m_gridDisplayCurrentSettings->SetColLabelSize( 30 );
+ m_gridDisplayCurrentSettings->SetColLabelValue( 0, _("Track size") );
+ m_gridDisplayCurrentSettings->SetColLabelValue( 1, _("Via diameter") );
+ m_gridDisplayCurrentSettings->SetColLabelValue( 2, _("Via drill") );
+ m_gridDisplayCurrentSettings->SetColLabelValue( 3, _("uVia size") );
+ m_gridDisplayCurrentSettings->SetColLabelValue( 4, _("uVia Drill") );
+ m_gridDisplayCurrentSettings->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_gridDisplayCurrentSettings->AutoSizeRows();
+ m_gridDisplayCurrentSettings->EnableDragRowSize( true );
+ m_gridDisplayCurrentSettings->SetRowLabelSize( 100 );
+ m_gridDisplayCurrentSettings->SetRowLabelValue( 0, _("Netclass value") );
+ m_gridDisplayCurrentSettings->SetRowLabelValue( 1, _("Current value") );
+ m_gridDisplayCurrentSettings->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_gridDisplayCurrentSettings->SetDefaultCellAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+ bSizerGrids->Add( m_gridDisplayCurrentSettings, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizerCurrSettingsLeft->Add( bSizerGrids, 1, wxEXPAND, 5 );
+
+
+ bSizerCurrSettings->Add( bSizerCurrSettingsLeft, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bSizerCurrSettings, 0, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline1, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bLowerSizer;
+ bLowerSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText11 = new wxStaticText( this, wxID_ANY, _("Global Edition Option:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText11->Wrap( -1 );
+ m_staticText11->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bLowerSizer->Add( m_staticText11, 0, wxALL, 5 );
+
+
+ bMainSizer->Add( bLowerSizer, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerOptions;
+ bSizerOptions = new wxBoxSizer( wxHORIZONTAL );
+
+
+ bSizerOptions->Add( 20, 0, 0, 0, 5 );
+
+ wxBoxSizer* bSizerRadioButtons;
+ bSizerRadioButtons = new wxBoxSizer( wxVERTICAL );
+
+ m_Net2CurrValueButton = new wxRadioButton( this, ID_CURRENT_VALUES_TO_CURRENT_NET, _("Set tracks and vias of the current Net to the current value"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
+ m_Net2CurrValueButton->SetValue( true );
+ bSizerRadioButtons->Add( m_Net2CurrValueButton, 0, wxALL, 5 );
+
+ m_NetUseNetclassValueButton = new wxRadioButton( this, ID_NETCLASS_VALUES_TO_CURRENT_NET, _("Set tracks and vias of the current Net to the Netclass value"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerRadioButtons->Add( m_NetUseNetclassValueButton, 0, wxALL, 5 );
+
+ m_radioBtn3 = new wxRadioButton( this, ID_ALL_TRACKS_VIAS, _("Set all tracks and vias to their Netclass value"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerRadioButtons->Add( m_radioBtn3, 0, wxALL, 5 );
+
+ m_radioBtn4 = new wxRadioButton( this, ID_ALL_VIAS, _("Set all vias (no track) to their Netclass value"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerRadioButtons->Add( m_radioBtn4, 0, wxALL, 5 );
+
+ m_radioBtn5 = new wxRadioButton( this, ID_ALL_TRACKS, _("Set all tracks (no via) to their Netclass value"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerRadioButtons->Add( m_radioBtn5, 0, wxALL, 5 );
+
+
+ bSizerOptions->Add( bSizerRadioButtons, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bSizerOptions, 0, wxEXPAND, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bMainSizer->Add( m_sdbSizer1, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ // Connect Events
+ m_Net2CurrValueButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnSelectionClick ), NULL, this );
+ m_NetUseNetclassValueButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnSelectionClick ), NULL, this );
+ m_radioBtn3->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnSelectionClick ), NULL, this );
+ m_radioBtn4->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnSelectionClick ), NULL, this );
+ m_radioBtn5->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnSelectionClick ), NULL, this );
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::~DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE()
+{
+ // Disconnect Events
+ m_Net2CurrValueButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnSelectionClick ), NULL, this );
+ m_NetUseNetclassValueButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnSelectionClick ), NULL, this );
+ m_radioBtn3->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnSelectionClick ), NULL, this );
+ m_radioBtn4->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnSelectionClick ), NULL, this );
+ m_radioBtn5->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnSelectionClick ), NULL, this );
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_global_edit_tracks_and_vias_base.fbp b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias_base.fbp
new file mode 100644
index 0000000..481a587
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias_base.fbp
@@ -0,0 +1,1399 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="11" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_global_edit_tracks_and_vias_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_global_edit_tracks_and_vias_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">711,376</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Global Edition of Tracks and Vias</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerCurrSettings</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Current Settings:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText12</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerCurrSettingsLeft</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">20</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerGrids</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizeNetInfo</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">2</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Current Net:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CurrentNetText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">NetName</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CurrentNetName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Current NetClass:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CurrentNetclassText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">NetClassName</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CurrentNetclassName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">10</property>
+ <property name="permission">protected</property>
+ <property name="width">10</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">1</property>
+ <property name="autosize_rows">1</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg"></property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">30</property>
+ <property name="col_label_values">&quot;Track size&quot; &quot;Via diameter&quot; &quot;Via drill&quot; &quot;uVia size&quot; &quot;uVia Drill&quot;</property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">5</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">1</property>
+ <property name="drag_row_size">1</property>
+ <property name="editing">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">10</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_gridDisplayCurrentSettings</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">100</property>
+ <property name="row_label_values">&quot;Netclass value&quot; &quot;Current value&quot;</property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">2</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick"></event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLowerSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Global Edition Option:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText11</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerOptions</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">20</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRadioButtons</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CURRENT_VALUES_TO_CURRENT_NET</property>
+ <property name="label">Set tracks and vias of the current Net to the current value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Net2CurrValueButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRB_GROUP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">1</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton">OnSelectionClick</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_NETCLASS_VALUES_TO_CURRENT_NET</property>
+ <property name="label">Set tracks and vias of the current Net to the Netclass value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NetUseNetclassValueButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton">OnSelectionClick</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ALL_TRACKS_VIAS</property>
+ <property name="label">Set all tracks and vias to their Netclass value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioBtn3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton">OnSelectionClick</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ALL_VIAS</property>
+ <property name="label">Set all vias (no track) to their Netclass value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioBtn4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton">OnSelectionClick</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ALL_TRACKS</property>
+ <property name="label">Set all tracks (no via) to their Netclass value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioBtn5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton">OnSelectionClick</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_global_edit_tracks_and_vias_base.h b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias_base.h
new file mode 100644
index 0000000..aff1208
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_edit_tracks_and_vias_base.h
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Apr 10 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE_H__
+#define __DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/grid.h>
+#include <wx/statline.h>
+#include <wx/radiobut.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_CURRENT_VALUES_TO_CURRENT_NET 1000
+#define ID_NETCLASS_VALUES_TO_CURRENT_NET 1001
+#define ID_ALL_TRACKS_VIAS 1002
+#define ID_ALL_VIAS 1003
+#define ID_ALL_TRACKS 1004
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText12;
+ wxStaticText* m_CurrentNetText;
+ wxStaticText* m_CurrentNetName;
+ wxStaticText* m_CurrentNetclassText;
+ wxStaticText* m_CurrentNetclassName;
+ wxGrid* m_gridDisplayCurrentSettings;
+ wxStaticLine* m_staticline1;
+ wxStaticText* m_staticText11;
+ wxRadioButton* m_Net2CurrValueButton;
+ wxRadioButton* m_NetUseNetclassValueButton;
+ wxRadioButton* m_radioBtn3;
+ wxRadioButton* m_radioBtn4;
+ wxRadioButton* m_radioBtn5;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnSelectionClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Global Edition of Tracks and Vias"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 711,376 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE();
+
+};
+
+#endif //__DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE_H__
diff --git a/pcbnew/dialogs/dialog_global_modules_fields_edition.cpp b/pcbnew/dialogs/dialog_global_modules_fields_edition.cpp
new file mode 100644
index 0000000..e342141
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_modules_fields_edition.cpp
@@ -0,0 +1,253 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_global_modules_fields_edition.cpp
+ * @brief global module fields edition.
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <wxBasePcbFrame.h>
+#include <base_units.h>
+#include <kicad_string.h>
+#include <macros.h>
+
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_text_mod.h>
+#include <dialog_global_modules_fields_edition_base.h>
+
+
+// The dialog to set options for global fields edition:
+// optionas are:
+// - edited fields (ref, value, others
+// - the footprint filter, for selective edition
+class DIALOG_GLOBAL_MODULES_FIELDS_EDITION : public DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE
+{
+ PCB_EDIT_FRAME* m_parent;
+ BOARD_DESIGN_SETTINGS* m_brdSettings;
+ // Static variable to remember options, withing a session:
+ static bool m_refSelection;
+ static bool m_valueSelection;
+ static bool m_othersSelection;
+ static wxString m_filterString;
+
+
+public:
+ DIALOG_GLOBAL_MODULES_FIELDS_EDITION( PCB_EDIT_FRAME* parent )
+ : DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE( parent )
+ {
+ m_parent = parent;
+ initDialog();
+ }
+
+private:
+ void initDialog();
+
+ // event handlers
+ void OnOKClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event )
+ {
+ EndModal( wxID_CANCEL );
+ }
+};
+
+bool DIALOG_GLOBAL_MODULES_FIELDS_EDITION::m_refSelection = false;
+bool DIALOG_GLOBAL_MODULES_FIELDS_EDITION::m_valueSelection = false;
+bool DIALOG_GLOBAL_MODULES_FIELDS_EDITION::m_othersSelection = false;
+wxString DIALOG_GLOBAL_MODULES_FIELDS_EDITION::m_filterString;
+
+void DIALOG_GLOBAL_MODULES_FIELDS_EDITION::initDialog()
+{
+ m_sdbSizerButtonsOK->SetDefault();
+
+ m_brdSettings = &m_parent->GetDesignSettings();
+
+ m_ReferenceOpt->SetValue(m_refSelection),
+ m_ValueOpt->SetValue(m_valueSelection),
+ m_OtherFields->SetValue(m_othersSelection);
+ m_ModuleFilter->SetValue(m_filterString);
+ m_SizeXunit->SetLabel( GetAbbreviatedUnitsLabel() );
+ m_SizeYunit->SetLabel( GetAbbreviatedUnitsLabel() );
+ m_Ticknessunit->SetLabel( GetAbbreviatedUnitsLabel() );
+ m_SizeX_Value->SetValue(
+ StringFromValue( g_UserUnit, m_brdSettings->m_ModuleTextSize.x ) );
+ m_SizeY_Value->SetValue(
+ StringFromValue( g_UserUnit, m_brdSettings->m_ModuleTextSize.y ) );
+ m_TicknessValue->SetValue(
+ StringFromValue( g_UserUnit, m_brdSettings->m_ModuleTextWidth) );
+
+ Layout();
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+
+void DIALOG_GLOBAL_MODULES_FIELDS_EDITION::OnOKClick( wxCommandEvent& event )
+{
+ m_refSelection = m_ReferenceOpt->GetValue();
+ m_valueSelection = m_ValueOpt->GetValue();
+ m_othersSelection = m_OtherFields->GetValue();
+ m_filterString = m_ModuleFilter->GetValue();
+
+ m_brdSettings->m_ModuleTextSize.x = ValueFromTextCtrl( *m_SizeX_Value );
+ m_brdSettings->m_ModuleTextSize.y = ValueFromTextCtrl( *m_SizeY_Value );
+ m_brdSettings->m_ModuleTextWidth = ValueFromTextCtrl( *m_TicknessValue );
+
+ // clip m_ModuleTextWidth to the 1/4 of min size, to keep it always readable
+ int minsize = std::min( m_brdSettings->m_ModuleTextSize.x,
+ m_brdSettings->m_ModuleTextSize.y ) / 4;
+ if( m_brdSettings->m_ModuleTextWidth > minsize )
+ m_brdSettings->m_ModuleTextWidth = minsize;
+
+ m_parent->ResetModuleTextSizes( m_filterString, m_refSelection,
+ m_valueSelection, m_othersSelection );
+ EndModal( wxID_OK );
+}
+
+
+void PCB_EDIT_FRAME::OnResetModuleTextSizes( wxCommandEvent& event )
+{
+ DIALOG_GLOBAL_MODULES_FIELDS_EDITION dlg(this);
+ dlg.ShowModal();
+
+ if( IsGalCanvasActive() )
+ {
+ for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
+ {
+ module->Value().ViewUpdate();
+ module->Reference().ViewUpdate();
+ }
+ }
+
+ m_canvas->Refresh();
+}
+
+void PCB_BASE_FRAME::ResetModuleTextSizes( const wxString & aFilter, bool aRef,
+ bool aValue, bool aOthers )
+{
+ MODULE* module;
+ BOARD_ITEM* boardItem;
+ ITEM_PICKER itemWrapper( NULL, UR_CHANGED );
+ PICKED_ITEMS_LIST undoItemList;
+ unsigned int ii;
+
+ // Prepare undo list
+ for( module = GetBoard()->m_Modules; module; module = module->Next() )
+ {
+ itemWrapper.SetItem( module );
+
+ if( ! aFilter.IsEmpty() )
+ {
+ if( ! WildCompareString( aFilter, FROM_UTF8( module->GetFPID().Format().c_str() ),
+ false ) )
+ continue;
+ }
+
+
+ if( aRef )
+ {
+ TEXTE_MODULE *item = &module->Reference();
+
+ if( item->GetSize() != GetDesignSettings().m_ModuleTextSize ||
+ item->GetThickness() != GetDesignSettings().m_ModuleTextWidth )
+ {
+ undoItemList.PushItem( itemWrapper );
+ }
+ }
+
+ if( aValue )
+ {
+ TEXTE_MODULE *item = &module->Value();
+
+ if( item->GetSize() != GetDesignSettings().m_ModuleTextSize ||
+ item->GetThickness() != GetDesignSettings().m_ModuleTextWidth )
+ {
+ undoItemList.PushItem( itemWrapper );
+ }
+ }
+
+ if( aOthers )
+ {
+ // Go through all other module text fields
+ for( boardItem = module->GraphicalItems(); boardItem; boardItem = boardItem->Next() )
+ {
+ if( boardItem->Type() == PCB_MODULE_TEXT_T )
+ {
+ TEXTE_MODULE *item = static_cast<TEXTE_MODULE*>( boardItem );
+
+ if( item->GetSize() != GetDesignSettings().m_ModuleTextSize
+ || item->GetThickness() != GetDesignSettings().m_ModuleTextWidth )
+ {
+ undoItemList.PushItem( itemWrapper );
+ }
+ }
+ }
+ }
+ }
+
+ // Exit if there's nothing to do
+ if( !undoItemList.GetCount() )
+ return;
+
+ SaveCopyInUndoList( undoItemList, UR_CHANGED );
+
+ // Apply changes to modules in the undo list
+ for( ii = 0; ii < undoItemList.GetCount(); ii++ )
+ {
+ module = (MODULE*) undoItemList.GetPickedItem( ii );
+
+ if( aRef )
+ {
+ module->Reference().SetThickness( GetDesignSettings().m_ModuleTextWidth );
+ module->Reference().SetSize( GetDesignSettings().m_ModuleTextSize );
+ }
+
+ if( aValue )
+ {
+ module->Value().SetThickness( GetDesignSettings().m_ModuleTextWidth );
+ module->Value().SetSize( GetDesignSettings().m_ModuleTextSize );
+ }
+
+ if( aOthers )
+ {
+ for( boardItem = module->GraphicalItems(); boardItem; boardItem = boardItem->Next() )
+ {
+ if( boardItem->Type() == PCB_MODULE_TEXT_T )
+ {
+ TEXTE_MODULE *item = static_cast<TEXTE_MODULE*>( boardItem );
+ item->SetThickness( GetDesignSettings().m_ModuleTextWidth );
+ item->SetSize( GetDesignSettings().m_ModuleTextSize );
+ }
+ }
+ }
+ }
+
+ OnModify();
+}
diff --git a/pcbnew/dialogs/dialog_global_modules_fields_edition_base.cpp b/pcbnew/dialogs/dialog_global_modules_fields_edition_base.cpp
new file mode 100644
index 0000000..33ce483
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_modules_fields_edition_base.cpp
@@ -0,0 +1,141 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_global_modules_fields_edition_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE::DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bLeftSizer;
+ bLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbSizer1;
+ sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Footprint Fields") ), wxVERTICAL );
+
+ m_ReferenceOpt = new wxCheckBox( this, wxID_ANY, _("Reference designator"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizer1->Add( m_ReferenceOpt, 0, wxALL|wxEXPAND, 5 );
+
+ m_ValueOpt = new wxCheckBox( this, wxID_ANY, _("Value"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizer1->Add( m_ValueOpt, 0, wxALL|wxEXPAND, 5 );
+
+ m_OtherFields = new wxCheckBox( this, wxID_ANY, _("User defined"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizer1->Add( m_OtherFields, 0, wxALL|wxEXPAND, 5 );
+
+
+ bLeftSizer->Add( sbSizer1, 1, wxBOTTOM|wxEXPAND|wxRIGHT, 5 );
+
+ m_staticTextFilter = new wxStaticText( this, wxID_ANY, _("Footprint Filter:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextFilter->Wrap( -1 );
+ m_staticTextFilter->SetToolTip( _("A string to filter footprints to edit.\nIf not void, footprint names should match this filter.\nA filter can be something like SM* (case insensitive)") );
+
+ bLeftSizer->Add( m_staticTextFilter, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_ModuleFilter = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ModuleFilter->SetMaxLength( 0 );
+ bLeftSizer->Add( m_ModuleFilter, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+
+ bSizerUpper->Add( bLeftSizer, 2, wxEXPAND, 5 );
+
+ wxBoxSizer* bRightSizer;
+ bRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbSizerSettings;
+ sbSizerSettings = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Current Text Dimensions") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgSizerCurrSettings;
+ fgSizerCurrSettings = new wxFlexGridSizer( 3, 3, 0, 0 );
+ fgSizerCurrSettings->AddGrowableCol( 1 );
+ fgSizerCurrSettings->SetFlexibleDirection( wxBOTH );
+ fgSizerCurrSettings->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText3 = new wxStaticText( this, wxID_ANY, _("Width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ fgSizerCurrSettings->Add( m_staticText3, 0, wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_SizeX_Value = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SizeX_Value->SetMaxLength( 0 );
+ fgSizerCurrSettings->Add( m_SizeX_Value, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_SizeXunit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SizeXunit->Wrap( -1 );
+ fgSizerCurrSettings->Add( m_SizeXunit, 0, wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_staticText6 = new wxStaticText( this, wxID_ANY, _("Height:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText6->Wrap( -1 );
+ fgSizerCurrSettings->Add( m_staticText6, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT|wxALIGN_RIGHT, 5 );
+
+ m_SizeY_Value = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SizeY_Value->SetMaxLength( 0 );
+ fgSizerCurrSettings->Add( m_SizeY_Value, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_SizeYunit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SizeYunit->Wrap( -1 );
+ fgSizerCurrSettings->Add( m_SizeYunit, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_staticText9 = new wxStaticText( this, wxID_ANY, _("Thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText9->Wrap( -1 );
+ fgSizerCurrSettings->Add( m_staticText9, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_TicknessValue = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_TicknessValue->SetMaxLength( 0 );
+ fgSizerCurrSettings->Add( m_TicknessValue, 0, wxALL|wxEXPAND, 5 );
+
+ m_Ticknessunit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Ticknessunit->Wrap( -1 );
+ fgSizerCurrSettings->Add( m_Ticknessunit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ sbSizerSettings->Add( fgSizerCurrSettings, 1, wxEXPAND, 5 );
+
+
+ bRightSizer->Add( sbSizerSettings, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ bSizerUpper->Add( bRightSizer, 3, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bSizerUpper, 1, wxALL|wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline1, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_sdbSizerButtons = new wxStdDialogButtonSizer();
+ m_sdbSizerButtonsOK = new wxButton( this, wxID_OK );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsOK );
+ m_sdbSizerButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsCancel );
+ m_sdbSizerButtons->Realize();
+
+ bMainSizer->Add( m_sdbSizerButtons, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ m_sdbSizerButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE::OnOKClick ), NULL, this );
+}
+
+DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE::~DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE()
+{
+ // Disconnect Events
+ m_sdbSizerButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE::OnOKClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_global_modules_fields_edition_base.fbp b/pcbnew/dialogs/dialog_global_modules_fields_edition_base.fbp
new file mode 100644
index 0000000..3276eb7
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_modules_fields_edition_base.fbp
@@ -0,0 +1,1494 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_global_modules_fields_edition_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_global_modules_fields_edition</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Set Text Size</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">2</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprint Fields</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizer1</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Reference designator</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ReferenceOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ValueOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">User defined</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OtherFields</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprint Filter:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextFilter</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">A string to filter footprints to edit.&#x0A;If not void, footprint names should match this filter.&#x0A;A filter can be something like SM* (case insensitive)</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_ModuleFilter</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">3</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Current Text Dimensions</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerSettings</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerCurrSettings</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">3</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SizeX_Value</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SizeXunit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Height:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText6</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SizeY_Value</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SizeYunit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Thickness:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText9</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TicknessValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Ticknessunit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizerButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_global_modules_fields_edition_base.h b/pcbnew/dialogs/dialog_global_modules_fields_edition_base.h
new file mode 100644
index 0000000..809771e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_modules_fields_edition_base.h
@@ -0,0 +1,73 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE_H__
+#define __DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/checkbox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxCheckBox* m_ReferenceOpt;
+ wxCheckBox* m_ValueOpt;
+ wxCheckBox* m_OtherFields;
+ wxStaticText* m_staticTextFilter;
+ wxTextCtrl* m_ModuleFilter;
+ wxStaticText* m_staticText3;
+ wxTextCtrl* m_SizeX_Value;
+ wxStaticText* m_SizeXunit;
+ wxStaticText* m_staticText6;
+ wxTextCtrl* m_SizeY_Value;
+ wxStaticText* m_SizeYunit;
+ wxStaticText* m_staticText9;
+ wxTextCtrl* m_TicknessValue;
+ wxStaticText* m_Ticknessunit;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizerButtons;
+ wxButton* m_sdbSizerButtonsOK;
+ wxButton* m_sdbSizerButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Set Text Size"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE();
+
+};
+
+#endif //__DIALOG_GLOBAL_MODULES_FIELDS_EDITION_BASE_H__
diff --git a/pcbnew/dialogs/dialog_global_pads_edition_base.cpp b/pcbnew/dialogs/dialog_global_pads_edition_base.cpp
new file mode 100644
index 0000000..cfea6b4
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_pads_edition_base.cpp
@@ -0,0 +1,81 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 6 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_global_pads_edition_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_GLOBAL_PADS_EDITION_BASE::DIALOG_GLOBAL_PADS_EDITION_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bLeftSizer;
+ bLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbSizer1;
+ sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Pad Filter :") ), wxVERTICAL );
+
+ m_Pad_Shape_Filter_CB = new wxCheckBox( this, wxID_ANY, _("Do not modify pads having a different shape"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizer1->Add( m_Pad_Shape_Filter_CB, 0, wxALL, 5 );
+
+ m_Pad_Layer_Filter_CB = new wxCheckBox( this, wxID_ANY, _("Do not modify pads having different layers"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizer1->Add( m_Pad_Layer_Filter_CB, 0, wxALL, 5 );
+
+ m_Pad_Orient_Filter_CB = new wxCheckBox( this, wxID_ANY, _("Do not modify pads having a different orientation"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizer1->Add( m_Pad_Orient_Filter_CB, 0, wxALL, 5 );
+
+
+ bLeftSizer->Add( sbSizer1, 1, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bLeftSizer, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bRightSizer;
+ bRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonPadEditor = new wxButton( this, ID_CHANGE_GET_PAD_SETTINGS, _("Pad Editor"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonPadEditor, 0, wxALL|wxEXPAND, 5 );
+
+
+ bRightSizer->Add( 10, 10, 0, 0, 5 );
+
+ m_buttonChangeModule = new wxButton( this, ID_CHANGE_CURRENT_MODULE, _("Change Pads on Footprint"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonChangeModule, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonIdModules = new wxButton( this, ID_CHANGE_ID_MODULES, _("Change Pads on Identical Footprints"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonIdModules, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizer->Add( m_buttonCancel, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bRightSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ m_buttonPadEditor->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_PADS_EDITION_BASE::InstallPadEditor ), NULL, this );
+ m_buttonChangeModule->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_PADS_EDITION_BASE::PadPropertiesAccept ), NULL, this );
+ m_buttonIdModules->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_PADS_EDITION_BASE::PadPropertiesAccept ), NULL, this );
+ m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_PADS_EDITION_BASE::OnCancelClick ), NULL, this );
+}
+
+DIALOG_GLOBAL_PADS_EDITION_BASE::~DIALOG_GLOBAL_PADS_EDITION_BASE()
+{
+ // Disconnect Events
+ m_buttonPadEditor->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_PADS_EDITION_BASE::InstallPadEditor ), NULL, this );
+ m_buttonChangeModule->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_PADS_EDITION_BASE::PadPropertiesAccept ), NULL, this );
+ m_buttonIdModules->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_PADS_EDITION_BASE::PadPropertiesAccept ), NULL, this );
+ m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_PADS_EDITION_BASE::OnCancelClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_global_pads_edition_base.fbp b/pcbnew/dialogs/dialog_global_pads_edition_base.fbp
new file mode 100644
index 0000000..3e6abef
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_pads_edition_base.fbp
@@ -0,0 +1,761 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_global_pads_edition_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_global_pads_edition</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_GLOBAL_PADS_EDITION_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Global Pads Edition</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad Filter :</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizer1</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Do not modify pads having a different shape</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Pad_Shape_Filter_CB</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Do not modify pads having different layers</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Pad_Layer_Filter_CB</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Do not modify pads having a different orientation</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Pad_Orient_Filter_CB</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CHANGE_GET_PAD_SETTINGS</property>
+ <property name="label">Pad Editor</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPadEditor</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">InstallPadEditor</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">10</property>
+ <property name="permission">protected</property>
+ <property name="width">10</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CHANGE_CURRENT_MODULE</property>
+ <property name="label">Change Pads on Footprint</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonChangeModule</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">PadPropertiesAccept</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CHANGE_ID_MODULES</property>
+ <property name="label">Change Pads on Identical Footprints</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonIdModules</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">public</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">PadPropertiesAccept</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Cancel</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonCancel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_global_pads_edition_base.h b/pcbnew/dialogs/dialog_global_pads_edition_base.h
new file mode 100644
index 0000000..8a444bd
--- /dev/null
+++ b/pcbnew/dialogs/dialog_global_pads_edition_base.h
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 6 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_GLOBAL_PADS_EDITION_BASE_H__
+#define __DIALOG_GLOBAL_PADS_EDITION_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/checkbox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_CHANGE_GET_PAD_SETTINGS 1000
+#define ID_CHANGE_CURRENT_MODULE 1001
+#define ID_CHANGE_ID_MODULES 1002
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_GLOBAL_PADS_EDITION_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_GLOBAL_PADS_EDITION_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxCheckBox* m_Pad_Shape_Filter_CB;
+ wxCheckBox* m_Pad_Layer_Filter_CB;
+ wxCheckBox* m_Pad_Orient_Filter_CB;
+ wxButton* m_buttonPadEditor;
+ wxButton* m_buttonChangeModule;
+ wxButton* m_buttonCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void InstallPadEditor( wxCommandEvent& event ) { event.Skip(); }
+ virtual void PadPropertiesAccept( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+ wxButton* m_buttonIdModules;
+
+ DIALOG_GLOBAL_PADS_EDITION_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Global Pads Edition"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_GLOBAL_PADS_EDITION_BASE();
+
+};
+
+#endif //__DIALOG_GLOBAL_PADS_EDITION_BASE_H__
diff --git a/pcbnew/dialogs/dialog_graphic_item_properties.cpp b/pcbnew/dialogs/dialog_graphic_item_properties.cpp
new file mode 100644
index 0000000..21f13d4
--- /dev/null
+++ b/pcbnew/dialogs/dialog_graphic_item_properties.cpp
@@ -0,0 +1,339 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Jean-Pierre Charras <jp.charras@wanadoo.fr>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_graphic_item_properties.cpp
+ */
+
+/* Edit parameters values of graphic items type DRAWSEGMENTS:
+ * Lines
+ * Circles
+ * Arcs
+ * used as graphic elements found on non copper layers in boards
+ * items on edge layers are considered as graphic items
+ * Pcb texts are not always graphic items and are not handled here
+ */
+#include <fctsys.h>
+#include <macros.h>
+#include <gr_basic.h>
+#include <confirm.h>
+#include <class_drawpanel.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <class_board_design_settings.h>
+#include <base_units.h>
+
+#include <class_board.h>
+#include <class_drawsegment.h>
+
+#include <dialog_graphic_item_properties_base.h>
+#include <class_pcb_layer_box_selector.h>
+#include <html_messagebox.h>
+
+
+class DIALOG_GRAPHIC_ITEM_PROPERTIES : public DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE
+{
+private:
+ PCB_EDIT_FRAME* m_parent;
+ wxDC* m_DC;
+ DRAWSEGMENT* m_item;
+ BOARD_DESIGN_SETTINGS m_brdSettings;
+
+public:
+ DIALOG_GRAPHIC_ITEM_PROPERTIES( PCB_EDIT_FRAME* aParent, DRAWSEGMENT* aItem, wxDC* aDC );
+ ~DIALOG_GRAPHIC_ITEM_PROPERTIES() {};
+
+private:
+ void initDlg();
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ void OnLayerChoice( wxCommandEvent& event );
+ bool itemValuesOK();
+};
+
+DIALOG_GRAPHIC_ITEM_PROPERTIES::DIALOG_GRAPHIC_ITEM_PROPERTIES( PCB_EDIT_FRAME* aParent,
+ DRAWSEGMENT* aItem, wxDC* aDC ):
+ DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE( aParent )
+{
+ m_parent = aParent;
+ m_DC = aDC;
+ m_item = aItem;
+ m_brdSettings = m_parent->GetDesignSettings();
+ initDlg();
+ Layout();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void PCB_EDIT_FRAME::InstallGraphicItemPropertiesDialog( DRAWSEGMENT* aItem, wxDC* aDC )
+{
+ wxCHECK_RET( aItem != NULL, wxT( "InstallGraphicItemPropertiesDialog() error: NULL item" ) );
+
+ m_canvas->SetIgnoreMouseEvents( true );
+ DIALOG_GRAPHIC_ITEM_PROPERTIES dlg( this, aItem, aDC );
+ dlg.ShowModal();
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+}
+
+
+void DIALOG_GRAPHIC_ITEM_PROPERTIES::initDlg()
+{
+ m_StandardButtonsSizerOK->SetDefault();
+
+ // Set unit symbol
+ wxStaticText* texts_unit[] =
+ {
+ m_StartPointXUnit,
+ m_StartPointYUnit,
+ m_EndPointXUnit,
+ m_EndPointYUnit,
+ m_ThicknessTextUnit,
+ m_DefaulThicknessTextUnit,
+ NULL
+ };
+
+ for( int ii = 0; ; ii++ )
+ {
+ if( texts_unit[ii] == NULL )
+ break;
+
+ texts_unit[ii]->SetLabel( GetAbbreviatedUnitsLabel() );
+ }
+
+ wxString msg;
+
+ // Change texts according to the segment shape:
+ switch( m_item->GetShape() )
+ {
+ case S_CIRCLE:
+ SetTitle( _( "Circle Properties" ) );
+ m_StartPointXLabel->SetLabel( _( "Center X:" ) );
+ m_StartPointYLabel->SetLabel( _( "Center Y:" ) );
+ m_EndPointXLabel->SetLabel( _( "Point X:" ) );
+ m_EndPointYLabel->SetLabel( _( "Point Y:" ) );
+ m_Angle_Text->Show( false );
+ m_Angle_Ctrl->Show( false );
+ m_AngleUnit->Show( false );
+ break;
+
+ case S_ARC:
+ SetTitle( _( "Arc Properties" ) );
+ m_StartPointXLabel->SetLabel( _( "Center X:" ) );
+ m_StartPointYLabel->SetLabel( _( "Center Y:" ) );
+ m_EndPointXLabel->SetLabel( _( "Start Point X:" ) );
+ m_EndPointYLabel->SetLabel( _( "Start Point Y:" ) );
+
+ // Here the angle is a double, but the UI is still working with integers.
+ msg << int( m_item->GetAngle() );
+ m_Angle_Ctrl->SetValue( msg );
+ break;
+
+ case S_SEGMENT:
+ SetTitle( _( "Line Segment Properties" ) );
+
+ // Fall through.
+ default:
+ m_Angle_Text->Show( false );
+ m_Angle_Ctrl->Show( false );
+ m_AngleUnit->Show( false );
+ break;
+ }
+
+ PutValueInLocalUnits( *m_Center_StartXCtrl, m_item->GetStart().x );
+
+ PutValueInLocalUnits( *m_Center_StartYCtrl, m_item->GetStart().y );
+
+ PutValueInLocalUnits( *m_EndX_Radius_Ctrl, m_item->GetEnd().x );
+
+ PutValueInLocalUnits( *m_EndY_Ctrl, m_item->GetEnd().y );
+
+ PutValueInLocalUnits( *m_ThicknessCtrl, m_item->GetWidth() );
+
+ int thickness;
+
+ if( m_item->GetLayer() == Edge_Cuts )
+ thickness = m_brdSettings.m_EdgeSegmentWidth;
+ else
+ thickness = m_brdSettings.m_DrawSegmentWidth;
+
+ PutValueInLocalUnits( *m_DefaultThicknessCtrl, thickness );
+
+ // Configure the layers list selector
+ m_LayerSelectionCtrl->SetLayersHotkeys( false );
+ m_LayerSelectionCtrl->SetLayerSet( LSET::AllCuMask() );
+ m_LayerSelectionCtrl->SetBoardFrame( m_parent );
+ m_LayerSelectionCtrl->Resync();
+
+ if( m_LayerSelectionCtrl->SetLayerSelection( m_item->GetLayer() ) < 0 )
+ {
+ wxMessageBox( _( "This item was on an unknown layer.\n"
+ "It has been moved to the drawings layer. Please fix it." ) );
+ m_LayerSelectionCtrl->SetLayerSelection( Dwgs_User );
+ }
+}
+
+
+void DIALOG_GRAPHIC_ITEM_PROPERTIES::OnLayerChoice( wxCommandEvent& event )
+{
+ int thickness;
+
+ if( m_LayerSelectionCtrl->GetLayerSelection() == Edge_Cuts )
+ thickness = m_brdSettings.m_EdgeSegmentWidth;
+ else
+ thickness = m_brdSettings.m_DrawSegmentWidth;
+
+ PutValueInLocalUnits( *m_DefaultThicknessCtrl, thickness );
+}
+
+
+void DIALOG_GRAPHIC_ITEM_PROPERTIES::OnOkClick( wxCommandEvent& event )
+{
+ if( !itemValuesOK() )
+ return;
+
+ m_parent->SaveCopyInUndoList( m_item, UR_CHANGED );
+
+ wxString msg;
+
+ if( m_DC )
+ m_item->Draw( m_parent->GetCanvas(), m_DC, GR_XOR );
+
+ msg = m_Center_StartXCtrl->GetValue();
+ m_item->SetStartX( ValueFromString( g_UserUnit, msg ) );
+
+ msg = m_Center_StartYCtrl->GetValue();
+ m_item->SetStartY( ValueFromString( g_UserUnit, msg ) );
+
+ msg = m_EndX_Radius_Ctrl->GetValue();
+ m_item->SetEndX( ValueFromString( g_UserUnit, msg ) );
+
+ msg = m_EndY_Ctrl->GetValue();
+ m_item->SetEndY( ValueFromString( g_UserUnit, msg ) );
+
+ msg = m_ThicknessCtrl->GetValue();
+ m_item->SetWidth( ValueFromString( g_UserUnit, msg ) );
+
+ msg = m_DefaultThicknessCtrl->GetValue();
+ int thickness = ValueFromString( g_UserUnit, msg );
+
+ m_item->SetLayer( ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) );
+
+ if( m_item->GetLayer() == Edge_Cuts )
+ m_brdSettings.m_EdgeSegmentWidth = thickness;
+ else
+ m_brdSettings.m_DrawSegmentWidth = thickness;
+
+ if( m_item->GetShape() == S_ARC )
+ {
+ double angle;
+ m_Angle_Ctrl->GetValue().ToDouble( &angle );
+ NORMALIZE_ANGLE_360( angle );
+ m_item->SetAngle( angle );
+ }
+
+ m_parent->OnModify();
+
+ if( m_DC )
+ m_item->Draw( m_parent->GetCanvas(), m_DC, GR_OR );
+
+ m_parent->SetMsgPanel( m_item );
+
+ m_parent->SetDesignSettings( m_brdSettings );
+
+ Close( true );
+}
+
+
+bool DIALOG_GRAPHIC_ITEM_PROPERTIES::itemValuesOK()
+{
+ wxArrayString error_msgs;
+
+ // Load the start and end points -- all types use these in the checks.
+ int startx = ValueFromString( g_UserUnit, m_Center_StartXCtrl->GetValue() );
+ int starty = ValueFromString( g_UserUnit, m_Center_StartYCtrl->GetValue() );
+ int endx = ValueFromString( g_UserUnit, m_EndX_Radius_Ctrl->GetValue() );
+ int endy = ValueFromString( g_UserUnit, m_EndY_Ctrl->GetValue() );
+
+ // Type specific checks.
+ switch( m_item->GetShape() )
+ {
+ case S_ARC:
+ // Check angle of arc.
+ double angle;
+ m_Angle_Ctrl->GetValue().ToDouble( &angle );
+ NORMALIZE_ANGLE_360( angle );
+
+ if( angle == 0 )
+ {
+ error_msgs.Add( _( "The arc angle must be greater than zero." ) );
+ }
+
+ // Fall through.
+ case S_CIRCLE:
+
+ // Check radius.
+ if( (startx == endx) && (starty == endy) )
+ {
+ error_msgs.Add( _( "The radius must be greater than zero." ) );
+ }
+
+ break;
+
+ default:
+
+ // Check start and end are not the same.
+ if( (startx == endx) && (starty == endy) )
+ {
+ error_msgs.Add( _( "The start and end points cannot be the same." ) );
+ }
+
+ break;
+ }
+
+ // Check the item thickness.
+ int thickness = ValueFromString( g_UserUnit, m_ThicknessCtrl->GetValue() );
+
+ if( thickness <= 0 )
+ error_msgs.Add( _( "The item thickness must be greater than zero." ) );
+
+ // And the default thickness.
+ thickness = ValueFromString( g_UserUnit, m_DefaultThicknessCtrl->GetValue() );
+
+ if( thickness <= 0 )
+ error_msgs.Add( _( "The default thickness must be greater than zero." ) );
+
+ if( error_msgs.GetCount() )
+ {
+ HTML_MESSAGE_BOX dlg( this, _( "Error List" ) );
+ dlg.ListSet( error_msgs );
+ dlg.ShowModal();
+ }
+
+ return error_msgs.GetCount() == 0;
+}
diff --git a/pcbnew/dialogs/dialog_graphic_item_properties_base.cpp b/pcbnew/dialogs/dialog_graphic_item_properties_base.cpp
new file mode 100644
index 0000000..4590d47
--- /dev/null
+++ b/pcbnew/dialogs/dialog_graphic_item_properties_base.cpp
@@ -0,0 +1,180 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "class_pcb_layer_box_selector.h"
+
+#include "dialog_graphic_item_properties_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxFlexGridSizer* fgUpperLeftGridSizer;
+ fgUpperLeftGridSizer = new wxFlexGridSizer( 4, 3, 0, 0 );
+ fgUpperLeftGridSizer->AddGrowableCol( 1 );
+ fgUpperLeftGridSizer->SetFlexibleDirection( wxBOTH );
+ fgUpperLeftGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_StartPointXLabel = new wxStaticText( this, wxID_ANY, _("Start point X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_StartPointXLabel->Wrap( -1 );
+ fgUpperLeftGridSizer->Add( m_StartPointXLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_Center_StartXCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_Center_StartXCtrl->SetMaxLength( 0 );
+ fgUpperLeftGridSizer->Add( m_Center_StartXCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_StartPointXUnit = new wxStaticText( this, wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_StartPointXUnit->Wrap( -1 );
+ fgUpperLeftGridSizer->Add( m_StartPointXUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_StartPointYLabel = new wxStaticText( this, wxID_ANY, _("Start point Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_StartPointYLabel->Wrap( -1 );
+ fgUpperLeftGridSizer->Add( m_StartPointYLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_Center_StartYCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_Center_StartYCtrl->SetMaxLength( 0 );
+ fgUpperLeftGridSizer->Add( m_Center_StartYCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_StartPointYUnit = new wxStaticText( this, wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_StartPointYUnit->Wrap( -1 );
+ fgUpperLeftGridSizer->Add( m_StartPointYUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_EndPointXLabel = new wxStaticText( this, wxID_ANY, _("End point X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_EndPointXLabel->Wrap( -1 );
+ fgUpperLeftGridSizer->Add( m_EndPointXLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_EndX_Radius_Ctrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_EndX_Radius_Ctrl->SetMaxLength( 0 );
+ fgUpperLeftGridSizer->Add( m_EndX_Radius_Ctrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_EndPointXUnit = new wxStaticText( this, wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_EndPointXUnit->Wrap( -1 );
+ fgUpperLeftGridSizer->Add( m_EndPointXUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_EndPointYLabel = new wxStaticText( this, wxID_ANY, _("End point Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_EndPointYLabel->Wrap( -1 );
+ fgUpperLeftGridSizer->Add( m_EndPointYLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_EndY_Ctrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_EndY_Ctrl->SetMaxLength( 0 );
+ fgUpperLeftGridSizer->Add( m_EndY_Ctrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_EndPointYUnit = new wxStaticText( this, wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_EndPointYUnit->Wrap( -1 );
+ fgUpperLeftGridSizer->Add( m_EndPointYUnit, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+
+ bUpperSizer->Add( fgUpperLeftGridSizer, 1, wxEXPAND, 5 );
+
+ m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
+ bUpperSizer->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 );
+
+ wxBoxSizer* bUpperRightSizer;
+ bUpperRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgUpperRightGridSizer;
+ fgUpperRightGridSizer = new wxFlexGridSizer( 0, 3, 0, 0 );
+ fgUpperRightGridSizer->AddGrowableCol( 1 );
+ fgUpperRightGridSizer->SetFlexibleDirection( wxBOTH );
+ fgUpperRightGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_Angle_Text = new wxStaticText( this, wxID_ANY, _("Arc angle:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Angle_Text->Wrap( -1 );
+ fgUpperRightGridSizer->Add( m_Angle_Text, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_Angle_Ctrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_Angle_Ctrl->SetMaxLength( 0 );
+ fgUpperRightGridSizer->Add( m_Angle_Ctrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_AngleUnit = new wxStaticText( this, wxID_ANY, _("0.1 degree"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_AngleUnit->Wrap( -1 );
+ fgUpperRightGridSizer->Add( m_AngleUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_ThicknessLabel = new wxStaticText( this, wxID_ANY, _("Item thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ThicknessLabel->Wrap( -1 );
+ fgUpperRightGridSizer->Add( m_ThicknessLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ m_ThicknessCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ThicknessCtrl->SetMaxLength( 0 );
+ fgUpperRightGridSizer->Add( m_ThicknessCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_ThicknessTextUnit = new wxStaticText( this, wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ThicknessTextUnit->Wrap( -1 );
+ fgUpperRightGridSizer->Add( m_ThicknessTextUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_DefaultThicknessLabel = new wxStaticText( this, wxID_ANY, _("Default thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_DefaultThicknessLabel->Wrap( -1 );
+ fgUpperRightGridSizer->Add( m_DefaultThicknessLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_DefaultThicknessCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_DefaultThicknessCtrl->SetMaxLength( 0 );
+ fgUpperRightGridSizer->Add( m_DefaultThicknessCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_DefaulThicknessTextUnit = new wxStaticText( this, wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_DefaulThicknessTextUnit->Wrap( -1 );
+ fgUpperRightGridSizer->Add( m_DefaulThicknessTextUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_LayerLabel = new wxStaticText( this, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_LayerLabel->Wrap( -1 );
+ fgUpperRightGridSizer->Add( m_LayerLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ m_LayerSelectionCtrl = new PCB_LAYER_BOX_SELECTOR( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ fgUpperRightGridSizer->Add( m_LayerSelectionCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+
+ fgUpperRightGridSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ bUpperRightSizer->Add( fgUpperRightGridSizer, 0, wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( bUpperRightSizer, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bUpperSizer, 1, wxALL|wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_StandardButtonsSizer = new wxStdDialogButtonSizer();
+ m_StandardButtonsSizerOK = new wxButton( this, wxID_OK );
+ m_StandardButtonsSizer->AddButton( m_StandardButtonsSizerOK );
+ m_StandardButtonsSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_StandardButtonsSizer->AddButton( m_StandardButtonsSizerCancel );
+ m_StandardButtonsSizer->Realize();
+
+ bMainSizer->Add( m_StandardButtonsSizer, 0, wxALIGN_RIGHT|wxALL, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::OnClose ) );
+ m_StandardButtonsSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::OnCancelClick ), NULL, this );
+ m_StandardButtonsSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::~DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::OnClose ) );
+ m_StandardButtonsSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::OnCancelClick ), NULL, this );
+ m_StandardButtonsSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_graphic_item_properties_base.fbp b/pcbnew/dialogs/dialog_graphic_item_properties_base.fbp
new file mode 100644
index 0000000..1fcb7cd
--- /dev/null
+++ b/pcbnew/dialogs/dialog_graphic_item_properties_base.fbp
@@ -0,0 +1,2328 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_graphic_item_properties_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Graphic Item Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnClose</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgUpperLeftGridSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">4</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Start point X:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_StartPointXLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Center_StartXCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_StartPointXUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Start point Y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_StartPointYLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Center_StartYCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_StartPointYUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">End point X:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_EndPointXLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_EndX_Radius_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_EndPointXUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">End point Y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_EndPointYLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_EndY_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_EndPointYUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_VERTICAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgUpperRightGridSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Arc angle:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Angle_Text</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Angle_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">0.1 degree</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AngleUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Item thickness:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ThicknessLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ThicknessCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ThicknessTextUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default thickness:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DefaultThicknessLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DefaultThicknessCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DefaulThicknessTextUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layer:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LayerLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxBitmapComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LayerSelectionCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">PCB_LAYER_BOX_SELECTOR; class_pcb_layer_box_selector.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_StandardButtonsSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_graphic_item_properties_base.h b/pcbnew/dialogs/dialog_graphic_item_properties_base.h
new file mode 100644
index 0000000..84a8bb8
--- /dev/null
+++ b/pcbnew/dialogs/dialog_graphic_item_properties_base.h
@@ -0,0 +1,84 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE_H__
+#define __DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class PCB_LAYER_BOX_SELECTOR;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/bmpcbox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_StartPointXLabel;
+ wxTextCtrl* m_Center_StartXCtrl;
+ wxStaticText* m_StartPointXUnit;
+ wxStaticText* m_StartPointYLabel;
+ wxTextCtrl* m_Center_StartYCtrl;
+ wxStaticText* m_StartPointYUnit;
+ wxStaticText* m_EndPointXLabel;
+ wxTextCtrl* m_EndX_Radius_Ctrl;
+ wxStaticText* m_EndPointXUnit;
+ wxStaticText* m_EndPointYLabel;
+ wxTextCtrl* m_EndY_Ctrl;
+ wxStaticText* m_EndPointYUnit;
+ wxStaticLine* m_staticline2;
+ wxStaticText* m_Angle_Text;
+ wxTextCtrl* m_Angle_Ctrl;
+ wxStaticText* m_AngleUnit;
+ wxStaticText* m_ThicknessLabel;
+ wxTextCtrl* m_ThicknessCtrl;
+ wxStaticText* m_ThicknessTextUnit;
+ wxStaticText* m_DefaultThicknessLabel;
+ wxTextCtrl* m_DefaultThicknessCtrl;
+ wxStaticText* m_DefaulThicknessTextUnit;
+ wxStaticText* m_LayerLabel;
+ PCB_LAYER_BOX_SELECTOR* m_LayerSelectionCtrl;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_StandardButtonsSizer;
+ wxButton* m_StandardButtonsSizerOK;
+ wxButton* m_StandardButtonsSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Graphic Item Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU );
+ ~DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE();
+
+};
+
+#endif //__DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE_H__
diff --git a/pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp b/pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp
new file mode 100644
index 0000000..92c8d7c
--- /dev/null
+++ b/pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp
@@ -0,0 +1,339 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_graphic_item_properties_for_Modedit.cpp
+ */
+
+/* Edit parameters values of graphic items in a footprint body:
+ * Lines
+ * Circles
+ * Arcs
+ * used as graphic elements found on non copper layers in boards
+ * Footprint texts are not graphic items and are not handled here
+ */
+#include <fctsys.h>
+#include <macros.h>
+#include <confirm.h>
+#include <class_drawpanel.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <class_board_design_settings.h>
+#include <module_editor_frame.h>
+#include <base_units.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+
+#include <dialog_graphic_item_properties_base.h>
+#include <class_pcb_layer_box_selector.h>
+#include <html_messagebox.h>
+
+class DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES : public DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE
+{
+private:
+ FOOTPRINT_EDIT_FRAME* m_parent;
+ EDGE_MODULE* m_item;
+ BOARD_DESIGN_SETTINGS m_brdSettings;
+ MODULE* m_module;
+
+public:
+ DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES( FOOTPRINT_EDIT_FRAME* aParent,
+ EDGE_MODULE* aItem );
+ ~DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES() {};
+
+private:
+ void initDlg();
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event ){ event.Skip(); }
+ void OnLayerChoice( wxCommandEvent& event );
+ bool itemValuesOK();
+};
+
+DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES(
+ FOOTPRINT_EDIT_FRAME* aParent,
+ EDGE_MODULE * aItem ):
+ DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE( aParent )
+{
+ m_parent = aParent;
+ m_item = aItem;
+ m_brdSettings = m_parent->GetDesignSettings();
+ m_module = m_parent->GetBoard()->m_Modules;
+ initDlg();
+ Layout();
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+
+/*
+ * Dialog to edit a graphic item of a footprint body.
+ */
+void FOOTPRINT_EDIT_FRAME::InstallFootprintBodyItemPropertiesDlg( EDGE_MODULE* aItem )
+{
+ if( aItem == NULL )
+ {
+ wxMessageBox( wxT( "InstallGraphicItemPropertiesDialog() error: NULL item" ) );
+ return;
+ }
+
+ m_canvas->SetIgnoreMouseEvents( true );
+ DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES* dialog =
+ new DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES( this, aItem );
+ dialog->ShowModal();
+ dialog->Destroy();
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+}
+
+
+void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::initDlg()
+{
+ SetFocus();
+ m_StandardButtonsSizerOK->SetDefault();
+
+ // Set unit symbol
+ wxStaticText* texts_unit[] =
+ {
+ m_StartPointXUnit,
+ m_StartPointYUnit,
+ m_EndPointXUnit,
+ m_EndPointYUnit,
+ m_ThicknessTextUnit,
+ m_DefaulThicknessTextUnit,
+ NULL
+ };
+
+ for( int ii = 0; ; ii++ )
+ {
+ if( texts_unit[ii] == NULL )
+ break;
+
+ texts_unit[ii]->SetLabel( GetAbbreviatedUnitsLabel() );
+ }
+
+ wxString msg;
+
+ // Change texts according to the segment shape:
+ switch( m_item->GetShape() )
+ {
+ case S_CIRCLE:
+ SetTitle( _( "Circle Properties" ) );
+ m_StartPointXLabel->SetLabel( _( "Center X" ) );
+ m_StartPointYLabel->SetLabel( _( "Center Y" ) );
+ m_EndPointXLabel->SetLabel( _( "Point X" ) );
+ m_EndPointYLabel->SetLabel( _( "Point Y" ) );
+ m_Angle_Text->Show( false );
+ m_Angle_Ctrl->Show( false );
+ m_AngleUnit->Show( false );
+ break;
+
+ case S_ARC:
+ SetTitle( _( "Arc Properties" ) );
+ m_StartPointXLabel->SetLabel( _( "Center X" ) );
+ m_StartPointYLabel->SetLabel( _( "Center Y" ) );
+ m_EndPointXLabel->SetLabel( _( "Start Point X" ) );
+ m_EndPointYLabel->SetLabel( _( "Start Point Y" ) );
+
+ // Here the angle is a double, but the UI is still working
+ // with integers
+ msg << int( m_item->GetAngle() );
+ m_Angle_Ctrl->SetValue( msg );
+ break;
+
+ case S_SEGMENT:
+ SetTitle( _( "Line Segment Properties" ) );
+
+ // Fall through.
+ default:
+ m_Angle_Text->Show( false );
+ m_Angle_Ctrl->Show( false );
+ m_AngleUnit->Show( false );
+ break;
+ }
+
+ PutValueInLocalUnits( *m_Center_StartXCtrl, m_item->GetStart().x );
+
+ PutValueInLocalUnits( *m_Center_StartYCtrl, m_item->GetStart().y );
+
+ PutValueInLocalUnits( *m_EndX_Radius_Ctrl, m_item->GetEnd().x );
+
+ PutValueInLocalUnits( *m_EndY_Ctrl, m_item->GetEnd().y );
+
+ PutValueInLocalUnits( *m_ThicknessCtrl, m_item->GetWidth() );
+
+ PutValueInLocalUnits( *m_DefaultThicknessCtrl, m_brdSettings.m_ModuleSegmentWidth );
+
+ // Configure the layers list selector
+ m_LayerSelectionCtrl->SetLayersHotkeys( false );
+ m_LayerSelectionCtrl->SetLayerSet( LSET::InternalCuMask().set( Edge_Cuts ) );
+ m_LayerSelectionCtrl->SetBoardFrame( m_parent );
+ m_LayerSelectionCtrl->Resync();
+
+ if( m_LayerSelectionCtrl->SetLayerSelection( m_item->GetLayer() ) < 0 )
+ {
+ wxMessageBox( _( "This item was on an unknown layer.\n"
+ "It has been moved to the front silk screen layer. Please fix it." ) );
+ m_LayerSelectionCtrl->SetLayerSelection( F_SilkS );
+ }
+}
+
+
+/*******************************************************************/
+void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::OnLayerChoice( wxCommandEvent& event )
+/*******************************************************************/
+{
+}
+
+
+/*******************************************************************/
+void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::OnOkClick( wxCommandEvent& event )
+/*******************************************************************/
+/* Copy values in text control to the item parameters
+ */
+{
+ if( !itemValuesOK() )
+ return;
+
+ LAYER_NUM layer = m_LayerSelectionCtrl->GetLayerSelection();
+
+ if( IsCopperLayer( layer ) )
+ {
+ /* an edge is put on a copper layer: this it is very dangerous. a
+ * confirmation is requested */
+ if( !IsOK( NULL,
+ _( "The graphic item will be on a copper layer. This is very dangerous. Are you sure?" ) ) )
+ return;
+ }
+
+ m_parent->SaveCopyInUndoList( m_module, UR_MODEDIT );
+ m_module->SetLastEditTime();
+
+ wxString msg;
+
+ wxPoint coord;
+
+ msg = m_Center_StartXCtrl->GetValue();
+ coord.x = ValueFromString( g_UserUnit, msg );
+ msg = m_Center_StartYCtrl->GetValue();
+ coord.y = ValueFromString( g_UserUnit, msg );
+ m_item->SetStart( coord );
+ m_item->SetStart0( coord );
+
+ msg = m_EndX_Radius_Ctrl->GetValue();
+ coord.x = ValueFromString( g_UserUnit, msg );
+ msg = m_EndY_Ctrl->GetValue();
+ coord.y = ValueFromString( g_UserUnit, msg );
+ m_item->SetEnd( coord );
+ m_item->SetEnd0( coord );
+
+ msg = m_ThicknessCtrl->GetValue();
+ m_item->SetWidth( ValueFromString( g_UserUnit, msg ) );
+
+ msg = m_DefaultThicknessCtrl->GetValue();
+ int thickness = ValueFromString( g_UserUnit, msg );
+ m_brdSettings.m_ModuleSegmentWidth = thickness;
+ m_parent->SetDesignSettings( m_brdSettings );
+
+ m_item->SetLayer( ToLAYER_ID( layer ) );
+
+ if( m_item->GetShape() == S_ARC )
+ {
+ double angle;
+ m_Angle_Ctrl->GetValue().ToDouble( &angle );
+ NORMALIZE_ANGLE_360( angle );
+ m_item->SetAngle( angle );
+ }
+
+ m_parent->OnModify();
+ m_parent->SetMsgPanel( m_item );
+
+ Close( true );
+}
+
+
+bool DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::itemValuesOK()
+{
+ wxArrayString error_msgs;
+
+ // Load the start and end points -- all types use these in the checks.
+ int startx = ValueFromString( g_UserUnit, m_Center_StartXCtrl->GetValue() );
+ int starty = ValueFromString( g_UserUnit, m_Center_StartYCtrl->GetValue() );
+ int endx = ValueFromString( g_UserUnit, m_EndX_Radius_Ctrl->GetValue() );
+ int endy = ValueFromString( g_UserUnit, m_EndY_Ctrl->GetValue() );
+
+ // Type specific checks.
+ switch( m_item->GetShape() )
+ {
+ case S_ARC:
+ // Check angle of arc.
+ double angle;
+ m_Angle_Ctrl->GetValue().ToDouble( &angle );
+ NORMALIZE_ANGLE_360( angle );
+
+ if( angle == 0 )
+ {
+ error_msgs.Add( _( "The arc angle must be greater than zero." ) );
+ }
+
+ // Fall through.
+ case S_CIRCLE:
+
+ // Check radius.
+ if( (startx == endx) && (starty == endy) )
+ error_msgs.Add( _( "The radius must be greater than zero." ) );
+
+ break;
+
+ default:
+
+ // Check start and end are not the same.
+ if( (startx == endx) && (starty == endy) )
+ error_msgs.Add( _( "The start and end points cannot be the same." ) );
+
+ break;
+ }
+
+ // Check the item thickness.
+ int thickness = ValueFromString( g_UserUnit, m_ThicknessCtrl->GetValue() );
+
+ if( thickness <= 0 )
+ error_msgs.Add( _( "The item thickness must be greater than zero." ) );
+
+ // And the default thickness.
+ thickness = ValueFromString( g_UserUnit, m_DefaultThicknessCtrl->GetValue() );
+
+ if( thickness <= 0 )
+ error_msgs.Add( _( "The default thickness must be greater than zero." ) );
+
+ if( error_msgs.GetCount() )
+ {
+ HTML_MESSAGE_BOX dlg( this, _( "Error list" ) );
+ dlg.ListSet( error_msgs );
+ dlg.ShowModal();
+ }
+
+ return error_msgs.GetCount() == 0;
+}
diff --git a/pcbnew/dialogs/dialog_graphic_items_options.cpp b/pcbnew/dialogs/dialog_graphic_items_options.cpp
new file mode 100644
index 0000000..c6a3b61
--- /dev/null
+++ b/pcbnew/dialogs/dialog_graphic_items_options.cpp
@@ -0,0 +1,149 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <base_units.h>
+
+#include <pcbnew_id.h>
+#include <module_editor_frame.h>
+#include <class_board.h>
+
+#include <dialog_graphic_items_options.h>
+
+
+void PCB_EDIT_FRAME::OnConfigurePcbOptions( wxCommandEvent& aEvent )
+{
+ DIALOG_GRAPHIC_ITEMS_OPTIONS dlg( this );
+
+ dlg.ShowModal();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::InstallOptionsFrame( const wxPoint& pos )
+{
+ DIALOG_GRAPHIC_ITEMS_OPTIONS dlg( this );
+ dlg.ShowModal();
+}
+
+
+/*
+ * DIALOG_GRAPHIC_ITEMS_OPTIONS constructor
+ */
+
+DIALOG_GRAPHIC_ITEMS_OPTIONS::DIALOG_GRAPHIC_ITEMS_OPTIONS( PCB_BASE_FRAME* parent )
+ : DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE( parent )
+{
+ m_parent = parent;
+ m_brdSettings = m_parent->GetDesignSettings();
+ initValues( );
+
+ m_sdbSizerOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+}
+
+DIALOG_GRAPHIC_ITEMS_OPTIONS::~DIALOG_GRAPHIC_ITEMS_OPTIONS()
+{
+}
+
+
+void DIALOG_GRAPHIC_ITEMS_OPTIONS::initValues()
+{
+ SetFocus();
+
+ /* Drawings width */
+ AddUnitSymbol( *m_GraphicSegmWidthTitle );
+ PutValueInLocalUnits( *m_OptPcbSegmWidth, m_brdSettings.m_DrawSegmentWidth );
+
+ /* Edges width */
+ AddUnitSymbol( *m_BoardEdgesWidthTitle );
+ PutValueInLocalUnits( *m_OptPcbEdgesWidth, m_brdSettings.m_EdgeSegmentWidth );
+
+ /* Pcb Textes (Size & Width) */
+ AddUnitSymbol( *m_CopperTextWidthTitle );
+ PutValueInLocalUnits( *m_OptPcbTextWidth, m_brdSettings.m_PcbTextWidth );
+
+ AddUnitSymbol( *m_TextSizeVTitle );
+ PutValueInLocalUnits( *m_OptPcbTextVSize, m_brdSettings.m_PcbTextSize.y );
+
+ AddUnitSymbol( *m_TextSizeHTitle );
+ PutValueInLocalUnits( *m_OptPcbTextHSize, m_brdSettings.m_PcbTextSize.x );
+
+
+ /* Modules: Edges width */
+ AddUnitSymbol( *m_EdgeModWidthTitle );
+ PutValueInLocalUnits( *m_OptModuleEdgesWidth, m_brdSettings.m_ModuleSegmentWidth );
+
+ /* Modules: Texts: Size & width */
+ AddUnitSymbol( *m_TextModWidthTitle );
+ PutValueInLocalUnits( *m_OptModuleTextWidth, m_brdSettings.m_ModuleTextWidth );
+
+ AddUnitSymbol( *m_TextModSizeVTitle );
+ PutValueInLocalUnits( *m_OptModuleTextVSize, m_brdSettings.m_ModuleTextSize.y );
+
+ AddUnitSymbol( *m_TextModSizeHTitle );
+ PutValueInLocalUnits( *m_OptModuleTextHSize, m_brdSettings.m_ModuleTextSize.x );
+
+ AddUnitSymbol( *m_DefaultPenSizeTitle );
+ PutValueInLocalUnits( *m_DefaultPenSizeCtrl, g_DrawDefaultLineThickness );
+}
+
+
+void DIALOG_GRAPHIC_ITEMS_OPTIONS::OnOkClick( wxCommandEvent& event )
+{
+ m_brdSettings.m_DrawSegmentWidth = ValueFromTextCtrl( *m_OptPcbSegmWidth );
+ m_brdSettings.m_EdgeSegmentWidth = ValueFromTextCtrl( *m_OptPcbEdgesWidth );
+ m_brdSettings.m_PcbTextWidth = ValueFromTextCtrl( *m_OptPcbTextWidth );
+ m_brdSettings.m_PcbTextSize.y = ValueFromTextCtrl( *m_OptPcbTextVSize );
+ m_brdSettings.m_PcbTextSize.x = ValueFromTextCtrl( *m_OptPcbTextHSize );
+
+ m_parent->GetBoard()->SetDesignSettings( m_brdSettings );
+
+ m_brdSettings.m_ModuleSegmentWidth = ValueFromTextCtrl( *m_OptModuleEdgesWidth );
+ m_brdSettings.m_ModuleTextWidth = ValueFromTextCtrl( *m_OptModuleTextWidth );
+ m_brdSettings.m_ModuleTextSize.y = ValueFromTextCtrl( *m_OptModuleTextVSize );
+ m_brdSettings.m_ModuleTextSize.x = ValueFromTextCtrl( *m_OptModuleTextHSize );
+
+ g_DrawDefaultLineThickness = ValueFromTextCtrl( *m_DefaultPenSizeCtrl );
+
+ if( g_DrawDefaultLineThickness < 0 )
+ g_DrawDefaultLineThickness = 0;
+
+ m_parent->SetDesignSettings( m_brdSettings );
+
+ EndModal( wxID_OK );
+}
+
+
+/*!
+ * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL
+ */
+
+void DIALOG_GRAPHIC_ITEMS_OPTIONS::OnCancelClick( wxCommandEvent& event )
+{
+ event.Skip();
+}
diff --git a/pcbnew/dialogs/dialog_graphic_items_options.h b/pcbnew/dialogs/dialog_graphic_items_options.h
new file mode 100644
index 0000000..d0e81b8
--- /dev/null
+++ b/pcbnew/dialogs/dialog_graphic_items_options.h
@@ -0,0 +1,64 @@
+/**
+ * @file dialog_graphic_items_options.h
+ */
+
+ /*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 <Jean-Pierre Charras> jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _DIALOG_GRAPHIC_ITEMS_OPTIONS_H_
+#define _DIALOG_GRAPHIC_ITEMS_OPTIONS_H_
+
+#include <dialog_graphic_items_options_base.h>
+
+/*!
+ * DIALOG_GRAPHIC_ITEMS_OPTIONS class declaration
+ */
+
+class DIALOG_GRAPHIC_ITEMS_OPTIONS: public DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE
+{
+private:
+ BOARD_DESIGN_SETTINGS m_brdSettings;
+ PCB_BASE_FRAME * m_parent;
+
+public:
+ DIALOG_GRAPHIC_ITEMS_OPTIONS( PCB_BASE_FRAME* parent );
+ ~DIALOG_GRAPHIC_ITEMS_OPTIONS();
+
+private:
+ void initValues( );
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+
+ void OnInitDlg( wxInitDialogEvent& event )
+ {
+ // Call the default wxDialog handler of a wxInitDialogEvent
+ TransferDataToWindow();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+ }
+};
+
+#endif
+ // _DIALOG_GRAPHIC_ITEMS_OPTIONS_H_
diff --git a/pcbnew/dialogs/dialog_graphic_items_options_base.cpp b/pcbnew/dialogs/dialog_graphic_items_options_base.cpp
new file mode 100644
index 0000000..be04ee4
--- /dev/null
+++ b/pcbnew/dialogs/dialog_graphic_items_options_base.cpp
@@ -0,0 +1,145 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_graphic_items_options_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE::DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sbSizerLeft;
+ sbSizerLeft = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Graphics:") ), wxVERTICAL );
+
+ m_GraphicSegmWidthTitle = new wxStaticText( sbSizerLeft->GetStaticBox(), wxID_ANY, _("Graphic segment width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_GraphicSegmWidthTitle->Wrap( -1 );
+ sbSizerLeft->Add( m_GraphicSegmWidthTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OptPcbSegmWidth = new wxTextCtrl( sbSizerLeft->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_OptPcbSegmWidth, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_BoardEdgesWidthTitle = new wxStaticText( sbSizerLeft->GetStaticBox(), wxID_ANY, _("Board edge width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_BoardEdgesWidthTitle->Wrap( -1 );
+ sbSizerLeft->Add( m_BoardEdgesWidthTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OptPcbEdgesWidth = new wxTextCtrl( sbSizerLeft->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_OptPcbEdgesWidth, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_CopperTextWidthTitle = new wxStaticText( sbSizerLeft->GetStaticBox(), wxID_ANY, _("Copper text thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_CopperTextWidthTitle->Wrap( -1 );
+ sbSizerLeft->Add( m_CopperTextWidthTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OptPcbTextWidth = new wxTextCtrl( sbSizerLeft->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_OptPcbTextWidth, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_TextSizeVTitle = new wxStaticText( sbSizerLeft->GetStaticBox(), wxID_ANY, _("Text height:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextSizeVTitle->Wrap( -1 );
+ sbSizerLeft->Add( m_TextSizeVTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OptPcbTextVSize = new wxTextCtrl( sbSizerLeft->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_OptPcbTextVSize, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_TextSizeHTitle = new wxStaticText( sbSizerLeft->GetStaticBox(), wxID_ANY, _("Text width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextSizeHTitle->Wrap( -1 );
+ sbSizerLeft->Add( m_TextSizeHTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OptPcbTextHSize = new wxTextCtrl( sbSizerLeft->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerLeft->Add( m_OptPcbTextHSize, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerUpper->Add( sbSizerLeft, 1, wxEXPAND|wxALL, 5 );
+
+ wxStaticBoxSizer* sbSizerMiddle;
+ sbSizerMiddle = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Footprints:") ), wxVERTICAL );
+
+ m_EdgeModWidthTitle = new wxStaticText( sbSizerMiddle->GetStaticBox(), wxID_ANY, _("Edge width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_EdgeModWidthTitle->Wrap( -1 );
+ sbSizerMiddle->Add( m_EdgeModWidthTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OptModuleEdgesWidth = new wxTextCtrl( sbSizerMiddle->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerMiddle->Add( m_OptModuleEdgesWidth, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_TextModWidthTitle = new wxStaticText( sbSizerMiddle->GetStaticBox(), wxID_ANY, _("Text thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextModWidthTitle->Wrap( -1 );
+ sbSizerMiddle->Add( m_TextModWidthTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OptModuleTextWidth = new wxTextCtrl( sbSizerMiddle->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerMiddle->Add( m_OptModuleTextWidth, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_TextModSizeVTitle = new wxStaticText( sbSizerMiddle->GetStaticBox(), wxID_ANY, _("Text height:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextModSizeVTitle->Wrap( -1 );
+ sbSizerMiddle->Add( m_TextModSizeVTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OptModuleTextVSize = new wxTextCtrl( sbSizerMiddle->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerMiddle->Add( m_OptModuleTextVSize, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_TextModSizeHTitle = new wxStaticText( sbSizerMiddle->GetStaticBox(), wxID_ANY, _("Text width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextModSizeHTitle->Wrap( -1 );
+ sbSizerMiddle->Add( m_TextModSizeHTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OptModuleTextHSize = new wxTextCtrl( sbSizerMiddle->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerMiddle->Add( m_OptModuleTextHSize, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ bSizerUpper->Add( sbSizerMiddle, 1, wxEXPAND|wxALL, 5 );
+
+ wxStaticBoxSizer* sbSizerRight;
+ sbSizerRight = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("General:") ), wxVERTICAL );
+
+ m_DefaultPenSizeTitle = new wxStaticText( sbSizerRight->GetStaticBox(), wxID_ANY, _("Default pen size:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_DefaultPenSizeTitle->Wrap( -1 );
+ m_DefaultPenSizeTitle->SetToolTip( _("Pen size used to draw items that have no pen size specified.\nUsed mainly to draw items in sketch mode.") );
+
+ sbSizerRight->Add( m_DefaultPenSizeTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_DefaultPenSizeCtrl = new wxTextCtrl( sbSizerRight->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerRight->Add( m_DefaultPenSizeCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerUpper->Add( sbSizerRight, 1, wxEXPAND|wxALL, 5 );
+
+
+ bSizerMain->Add( bSizerUpper, 1, wxEXPAND, 5 );
+
+
+ bSizerMain->Add( 0, 0, 0, wxEXPAND, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bSizerMain->Add( m_sdbSizer, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+ bSizerMain->Fit( this );
+
+ // Connect Events
+ this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE::OnInitDlg ) );
+ m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE::~DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE::OnInitDlg ) );
+ m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_graphic_items_options_base.fbp b/pcbnew/dialogs/dialog_graphic_items_options_base.fbp
new file mode 100644
index 0000000..2856df1
--- /dev/null
+++ b/pcbnew/dialogs/dialog_graphic_items_options_base.fbp
@@ -0,0 +1,1931 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_graphic_items_options_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_graphic_items_options</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Text and Drawings</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog">OnInitDlg</event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Graphics:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerLeft</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Graphic segment width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_GraphicSegmWidthTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptPcbSegmWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Board edge width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_BoardEdgesWidthTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptPcbEdgesWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Copper text thickness:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CopperTextWidthTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptPcbTextWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text height:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextSizeVTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptPcbTextVSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextSizeHTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptPcbTextHSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprints:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerMiddle</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Edge width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_EdgeModWidthTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptModuleEdgesWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text thickness:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextModWidthTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptModuleTextWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text height:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextModSizeVTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptModuleTextVSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextModSizeHTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptModuleTextHSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">General:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerRight</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default pen size:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DefaultPenSizeTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Pen size used to draw items that have no pen size specified.&#x0A;Used mainly to draw items in sketch mode.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DefaultPenSizeCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_graphic_items_options_base.h b/pcbnew/dialogs/dialog_graphic_items_options_base.h
new file mode 100644
index 0000000..7d2a8c1
--- /dev/null
+++ b/pcbnew/dialogs/dialog_graphic_items_options_base.h
@@ -0,0 +1,77 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE_H__
+#define __DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_GraphicSegmWidthTitle;
+ wxTextCtrl* m_OptPcbSegmWidth;
+ wxStaticText* m_BoardEdgesWidthTitle;
+ wxTextCtrl* m_OptPcbEdgesWidth;
+ wxStaticText* m_CopperTextWidthTitle;
+ wxTextCtrl* m_OptPcbTextWidth;
+ wxStaticText* m_TextSizeVTitle;
+ wxTextCtrl* m_OptPcbTextVSize;
+ wxStaticText* m_TextSizeHTitle;
+ wxTextCtrl* m_OptPcbTextHSize;
+ wxStaticText* m_EdgeModWidthTitle;
+ wxTextCtrl* m_OptModuleEdgesWidth;
+ wxStaticText* m_TextModWidthTitle;
+ wxTextCtrl* m_OptModuleTextWidth;
+ wxStaticText* m_TextModSizeVTitle;
+ wxTextCtrl* m_OptModuleTextVSize;
+ wxStaticText* m_TextModSizeHTitle;
+ wxTextCtrl* m_OptModuleTextHSize;
+ wxStaticText* m_DefaultPenSizeTitle;
+ wxTextCtrl* m_DefaultPenSizeCtrl;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnInitDlg( wxInitDialogEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Text and Drawings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE();
+
+};
+
+#endif //__DIALOG_GRAPHIC_ITEMS_OPTIONS_BASE_H__
diff --git a/pcbnew/dialogs/dialog_keepout_area_properties.cpp b/pcbnew/dialogs/dialog_keepout_area_properties.cpp
new file mode 100644
index 0000000..b0e08a2
--- /dev/null
+++ b/pcbnew/dialogs/dialog_keepout_area_properties.cpp
@@ -0,0 +1,279 @@
+/**
+ * @file dialog_keepout_area_properties.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wx/wx.h>
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <zones.h>
+#include <base_units.h>
+
+#include <class_zone_settings.h>
+#include <class_board.h>
+#include <dialog_keepout_area_properties_base.h>
+
+#include <wx/imaglist.h> // needed for wx/listctrl.h, in wxGTK 2.8.12
+#include <wx/listctrl.h>
+
+
+
+/**
+ * Class DIALOG_KEEPOUT_AREA_PROPERTIES
+ * is the derived class from dialog_copper_zone_frame created by wxFormBuilder
+ */
+class DIALOG_KEEPOUT_AREA_PROPERTIES : public DIALOG_KEEPOUT_AREA_PROPERTIES_BASE
+{
+public:
+ DIALOG_KEEPOUT_AREA_PROPERTIES( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings );
+
+private:
+ PCB_BASE_FRAME* m_parent;
+ wxConfigBase* m_config; ///< Current config
+ ZONE_SETTINGS m_zonesettings;
+ ZONE_SETTINGS* m_ptr;
+
+ std::vector<LAYER_NUM> m_layerId; ///< Handle the real layer number from layer
+ ///< name position in m_LayerSelectionCtrl
+
+ /**
+ * Function initDialog
+ * fills in the dialog controls using the current settings.
+ */
+ void initDialog();
+
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+
+ /**
+ * Function AcceptOptionsForKeepOut
+ * Test validity of options, and copy options in m_zonesettings, for keepout zones
+ * @return bool - false if incorrect options, true if ok.
+ */
+ bool AcceptOptionsForKeepOut();
+
+ /**
+ * Function makeLayerBitmap
+ * creates the colored rectangle bitmaps used in the layer selection widget.
+ * @param aColor is the color to fill the rectangle with.
+ */
+ wxBitmap makeLayerBitmap( EDA_COLOR_T aColor );
+};
+
+
+#define LAYER_BITMAP_SIZE_X 20
+#define LAYER_BITMAP_SIZE_Y 10
+
+ZONE_EDIT_T InvokeKeepoutAreaEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings )
+{
+ DIALOG_KEEPOUT_AREA_PROPERTIES dlg( aCaller, aSettings );
+
+ ZONE_EDIT_T result = ZONE_EDIT_T( dlg.ShowModal() );
+
+ return result;
+}
+
+
+DIALOG_KEEPOUT_AREA_PROPERTIES::DIALOG_KEEPOUT_AREA_PROPERTIES( PCB_BASE_FRAME* aParent,
+ ZONE_SETTINGS* aSettings ) :
+ DIALOG_KEEPOUT_AREA_PROPERTIES_BASE( aParent )
+{
+ m_parent = aParent;
+ m_config = Kiface().KifaceSettings();
+
+ m_ptr = aSettings;
+ m_zonesettings = *aSettings;
+
+ SetReturnCode( ZONE_ABORT ); // Will be changed on button OK click
+
+ initDialog();
+
+ m_sdbSizerButtonsOK->SetDefault();
+ GetSizer()->SetSizeHints( this );
+ Center();
+}
+
+
+void DIALOG_KEEPOUT_AREA_PROPERTIES::initDialog()
+{
+ BOARD* board = m_parent->GetBoard();
+
+ wxString msg;
+
+ if( m_zonesettings.m_Zone_45_Only )
+ m_OrientEdgesOpt->SetSelection( 1 );
+
+ switch( m_zonesettings.m_Zone_HatchingStyle )
+ {
+ case CPolyLine::NO_HATCH:
+ m_OutlineAppearanceCtrl->SetSelection( 0 );
+ break;
+
+ case CPolyLine::DIAGONAL_EDGE:
+ m_OutlineAppearanceCtrl->SetSelection( 1 );
+ break;
+
+ case CPolyLine::DIAGONAL_FULL:
+ m_OutlineAppearanceCtrl->SetSelection( 2 );
+ break;
+ }
+
+ // Create one column in m_LayerSelectionCtrl
+ wxListItem column0;
+ column0.SetId( 0 );
+ m_LayerSelectionCtrl->InsertColumn( 0, column0 );
+
+ wxImageList* imageList = new wxImageList( LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
+ m_LayerSelectionCtrl->AssignImageList( imageList, wxIMAGE_LIST_SMALL );
+
+ // Build copper layer list and append to layer widget
+ LSET show = LSET::AllCuMask( board->GetCopperLayerCount() );
+ int imgIdx = 0;
+
+ for( LSEQ cu_stack = show.UIOrder(); cu_stack; ++cu_stack, imgIdx++ )
+ {
+ LAYER_ID layer = *cu_stack;
+
+ m_layerId.push_back( layer );
+
+ msg = board->GetLayerName( layer );
+
+ EDA_COLOR_T layerColor = board->GetLayerColor( layer );
+
+ imageList->Add( makeLayerBitmap( layerColor ) );
+
+ int itemIndex = m_LayerSelectionCtrl->InsertItem(
+ m_LayerSelectionCtrl->GetItemCount(), msg, imgIdx );
+
+ if( m_zonesettings.m_CurrentZone_Layer == layer )
+ m_LayerSelectionCtrl->Select( itemIndex );
+ }
+
+ m_LayerSelectionCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE);
+
+ // Init keepout parameters:
+ m_cbTracksCtrl->SetValue( m_zonesettings.GetDoNotAllowTracks() );
+ m_cbViasCtrl->SetValue( m_zonesettings.GetDoNotAllowVias() );
+ m_cbCopperPourCtrl->SetValue( m_zonesettings.GetDoNotAllowCopperPour() );
+}
+
+
+void DIALOG_KEEPOUT_AREA_PROPERTIES::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( ZONE_ABORT );
+}
+
+
+void DIALOG_KEEPOUT_AREA_PROPERTIES::OnOkClick( wxCommandEvent& event )
+{
+ if( AcceptOptionsForKeepOut() )
+ {
+ *m_ptr = m_zonesettings;
+ EndModal( ZONE_OK );
+ }
+}
+
+
+bool DIALOG_KEEPOUT_AREA_PROPERTIES::AcceptOptionsForKeepOut()
+{
+ // Init keepout parameters:
+ m_zonesettings.SetIsKeepout( true );
+ m_zonesettings.SetDoNotAllowTracks( m_cbTracksCtrl->GetValue() );
+ m_zonesettings.SetDoNotAllowVias( m_cbViasCtrl->GetValue() );
+ m_zonesettings.SetDoNotAllowCopperPour( m_cbCopperPourCtrl->GetValue() );
+
+ // Test for not allowed items: should have at least one item not allowed:
+ if( ! m_zonesettings.GetDoNotAllowTracks() &&
+ ! m_zonesettings.GetDoNotAllowVias() &&
+ ! m_zonesettings.GetDoNotAllowCopperPour() )
+ {
+ DisplayError( NULL,
+ _("Tracks, vias, and pads are allowed. The keepout is useless" ) );
+ return false;
+ }
+
+ // Get the layer selection for this zone
+ int ii = m_LayerSelectionCtrl->GetFirstSelected();
+
+ if( ii < 0 )
+ {
+ DisplayError( NULL, _( "No layer selected." ) );
+ return false;
+ }
+
+ m_zonesettings.m_CurrentZone_Layer = ToLAYER_ID( m_layerId[ii] );
+
+ switch( m_OutlineAppearanceCtrl->GetSelection() )
+ {
+ case 0:
+ m_zonesettings.m_Zone_HatchingStyle = CPolyLine::NO_HATCH;
+ break;
+
+ case 1:
+ m_zonesettings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE;
+ break;
+
+ case 2:
+ m_zonesettings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_FULL;
+ break;
+ }
+
+ if( m_config )
+ {
+ m_config->Write( ZONE_NET_OUTLINES_HATCH_OPTION_KEY,
+ (long) m_zonesettings.m_Zone_HatchingStyle );
+ }
+
+ if( m_OrientEdgesOpt->GetSelection() == 0 )
+ m_zonesettings.m_Zone_45_Only = false;
+ else
+ m_zonesettings.m_Zone_45_Only = true;
+
+ m_zonesettings.m_ZonePriority = 0; //m_PriorityLevelCtrl->GetValue();
+
+ return true;
+}
+
+
+wxBitmap DIALOG_KEEPOUT_AREA_PROPERTIES::makeLayerBitmap( EDA_COLOR_T aColor )
+{
+ wxBitmap bitmap( LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
+ wxBrush brush;
+ wxMemoryDC iconDC;
+
+ iconDC.SelectObject( bitmap );
+ brush.SetColour( MakeColour( aColor ) );
+ brush.SetStyle( wxBRUSHSTYLE_SOLID );
+
+ iconDC.SetBrush( brush );
+ iconDC.DrawRectangle( 0, 0, LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
+
+ return bitmap;
+}
diff --git a/pcbnew/dialogs/dialog_keepout_area_properties_base.cpp b/pcbnew/dialogs/dialog_keepout_area_properties_base.cpp
new file mode 100644
index 0000000..0665261
--- /dev/null
+++ b/pcbnew/dialogs/dialog_keepout_area_properties_base.cpp
@@ -0,0 +1,102 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_keepout_area_properties_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+BEGIN_EVENT_TABLE( DIALOG_KEEPOUT_AREA_PROPERTIES_BASE, DIALOG_SHIM )
+ EVT_BUTTON( wxID_CANCEL, DIALOG_KEEPOUT_AREA_PROPERTIES_BASE::_wxFB_OnCancelClick )
+ EVT_BUTTON( wxID_OK, DIALOG_KEEPOUT_AREA_PROPERTIES_BASE::_wxFB_OnOkClick )
+END_EVENT_TABLE()
+
+DIALOG_KEEPOUT_AREA_PROPERTIES_BASE::DIALOG_KEEPOUT_AREA_PROPERTIES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* m_MainSizer;
+ m_MainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* m_UpperSizer;
+ m_UpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* m_layersListSizer;
+ m_layersListSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextLayerSelection = new wxStaticText( this, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextLayerSelection->Wrap( -1 );
+ m_layersListSizer->Add( m_staticTextLayerSelection, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_LayerSelectionCtrl = new wxListView( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ALIGN_LEFT|wxLC_NO_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL );
+ m_layersListSizer->Add( m_LayerSelectionCtrl, 1, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ m_UpperSizer->Add( m_layersListSizer, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerRight;
+ bSizerRight = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextprops = new wxStaticText( this, wxID_ANY, _("Properties:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextprops->Wrap( -1 );
+ bSizerRight->Add( m_staticTextprops, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_OrientEdgesOptChoices[] = { _("Any"), _("180, 90, and 45 degrees") };
+ int m_OrientEdgesOptNChoices = sizeof( m_OrientEdgesOptChoices ) / sizeof( wxString );
+ m_OrientEdgesOpt = new wxRadioBox( this, wxID_ANY, _("Zone Edge Orientation:"), wxDefaultPosition, wxDefaultSize, m_OrientEdgesOptNChoices, m_OrientEdgesOptChoices, 1, wxRA_SPECIFY_COLS );
+ m_OrientEdgesOpt->SetSelection( 1 );
+ bSizerRight->Add( m_OrientEdgesOpt, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_OutlineAppearanceCtrlChoices[] = { _("Line"), _("Hatched Outline"), _("Full Hatched") };
+ int m_OutlineAppearanceCtrlNChoices = sizeof( m_OutlineAppearanceCtrlChoices ) / sizeof( wxString );
+ m_OutlineAppearanceCtrl = new wxRadioBox( this, wxID_ANY, _("Outline Appearence:"), wxDefaultPosition, wxDefaultSize, m_OutlineAppearanceCtrlNChoices, m_OutlineAppearanceCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_OutlineAppearanceCtrl->SetSelection( 1 );
+ bSizerRight->Add( m_OutlineAppearanceCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbSizerCutoutOpts;
+ sbSizerCutoutOpts = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Keepout Options:") ), wxVERTICAL );
+
+ m_cbTracksCtrl = new wxCheckBox( this, wxID_ANY, _("No tracks"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerCutoutOpts->Add( m_cbTracksCtrl, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_cbViasCtrl = new wxCheckBox( this, wxID_ANY, _("No vias"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerCutoutOpts->Add( m_cbViasCtrl, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_cbCopperPourCtrl = new wxCheckBox( this, wxID_ANY, _("No copper pour"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerCutoutOpts->Add( m_cbCopperPourCtrl, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizerRight->Add( sbSizerCutoutOpts, 0, wxEXPAND|wxALL, 5 );
+
+
+ m_UpperSizer->Add( bSizerRight, 0, wxEXPAND, 5 );
+
+
+ m_MainSizer->Add( m_UpperSizer, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ m_MainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizerButtons = new wxStdDialogButtonSizer();
+ m_sdbSizerButtonsOK = new wxButton( this, wxID_OK );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsOK );
+ m_sdbSizerButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsCancel );
+ m_sdbSizerButtons->Realize();
+
+ m_MainSizer->Add( m_sdbSizerButtons, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( m_MainSizer );
+ this->Layout();
+ m_MainSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_KEEPOUT_AREA_PROPERTIES_BASE::~DIALOG_KEEPOUT_AREA_PROPERTIES_BASE()
+{
+}
diff --git a/pcbnew/dialogs/dialog_keepout_area_properties_base.fbp b/pcbnew/dialogs/dialog_keepout_area_properties_base.fbp
new file mode 100644
index 0000000..926ae8b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_keepout_area_properties_base.fbp
@@ -0,0 +1,968 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">table</property>
+ <property name="file">dialog_keepout_area_properties_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_keepout_areas_properties_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_KEEPOUT_AREA_PROPERTIES_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Keepout Area Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER</property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_MainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_UpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_layersListSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layer:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextLayerSelection</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxListCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LayerSelectionCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLC_ALIGN_LEFT|wxLC_NO_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL</property>
+ <property name="subclass">wxListView; </property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBeginDrag"></event>
+ <event name="OnListBeginLabelEdit"></event>
+ <event name="OnListBeginRDrag"></event>
+ <event name="OnListCacheHint"></event>
+ <event name="OnListColBeginDrag"></event>
+ <event name="OnListColClick"></event>
+ <event name="OnListColDragging"></event>
+ <event name="OnListColEndDrag"></event>
+ <event name="OnListColRightClick"></event>
+ <event name="OnListDeleteAllItems"></event>
+ <event name="OnListDeleteItem"></event>
+ <event name="OnListEndLabelEdit"></event>
+ <event name="OnListInsertItem"></event>
+ <event name="OnListItemActivated"></event>
+ <event name="OnListItemDeselected"></event>
+ <event name="OnListItemFocused"></event>
+ <event name="OnListItemMiddleClick"></event>
+ <event name="OnListItemRightClick"></event>
+ <event name="OnListItemSelected"></event>
+ <event name="OnListKeyDown"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRight</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Properties:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextprops</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Any&quot; &quot;180, 90, and 45 degrees&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Zone Edge Orientation:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OrientEdgesOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Line&quot; &quot;Hatched Outline&quot; &quot;Full Hatched&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Outline Appearence:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OutlineAppearanceCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Keepout Options:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerCutoutOpts</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">No tracks</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbTracksCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">No vias</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbViasCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">No copper pour</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_cbCopperPourCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizerButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_keepout_area_properties_base.h b/pcbnew/dialogs/dialog_keepout_area_properties_base.h
new file mode 100644
index 0000000..3f38de5
--- /dev/null
+++ b/pcbnew/dialogs/dialog_keepout_area_properties_base.h
@@ -0,0 +1,75 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_KEEPOUT_AREA_PROPERTIES_BASE_H__
+#define __DIALOG_KEEPOUT_AREA_PROPERTIES_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class wxListView;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/listctrl.h>
+#include <wx/sizer.h>
+#include <wx/radiobox.h>
+#include <wx/checkbox.h>
+#include <wx/statbox.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_KEEPOUT_AREA_PROPERTIES_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_KEEPOUT_AREA_PROPERTIES_BASE : public DIALOG_SHIM
+{
+ DECLARE_EVENT_TABLE()
+ private:
+
+ // Private event handlers
+ void _wxFB_OnCancelClick( wxCommandEvent& event ){ OnCancelClick( event ); }
+ void _wxFB_OnOkClick( wxCommandEvent& event ){ OnOkClick( event ); }
+
+
+ protected:
+ wxStaticText* m_staticTextLayerSelection;
+ wxListView* m_LayerSelectionCtrl;
+ wxStaticText* m_staticTextprops;
+ wxRadioBox* m_OrientEdgesOpt;
+ wxRadioBox* m_OutlineAppearanceCtrl;
+ wxCheckBox* m_cbTracksCtrl;
+ wxCheckBox* m_cbViasCtrl;
+ wxCheckBox* m_cbCopperPourCtrl;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizerButtons;
+ wxButton* m_sdbSizerButtonsOK;
+ wxButton* m_sdbSizerButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_KEEPOUT_AREA_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Keepout Area Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER );
+ ~DIALOG_KEEPOUT_AREA_PROPERTIES_BASE();
+
+};
+
+#endif //__DIALOG_KEEPOUT_AREA_PROPERTIES_BASE_H__
diff --git a/pcbnew/dialogs/dialog_layer_selection_base.cpp b/pcbnew/dialogs/dialog_layer_selection_base.cpp
new file mode 100644
index 0000000..bdd2b7d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_layer_selection_base.cpp
@@ -0,0 +1,224 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Oct 8 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_layer_selection_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_LAYER_SELECTION_BASE::DIALOG_LAYER_SELECTION_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxHORIZONTAL );
+
+ m_leftGridLayers = new wxGrid( this, ID_LEFT_LIST, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_leftGridLayers->CreateGrid( 1, 3 );
+ m_leftGridLayers->EnableEditing( false );
+ m_leftGridLayers->EnableGridLines( true );
+ m_leftGridLayers->EnableDragGridSize( false );
+ m_leftGridLayers->SetMargins( 0, 3 );
+
+ // Columns
+ m_leftGridLayers->EnableDragColMove( false );
+ m_leftGridLayers->EnableDragColSize( false );
+ m_leftGridLayers->SetColLabelSize( 0 );
+ m_leftGridLayers->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_leftGridLayers->EnableDragRowSize( false );
+ m_leftGridLayers->SetRowLabelSize( 0 );
+ m_leftGridLayers->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+ m_leftGridLayers->SetLabelBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
+
+ // Cell Defaults
+ m_leftGridLayers->SetDefaultCellBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) );
+ m_leftGridLayers->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ bSizerUpper->Add( m_leftGridLayers, 1, wxALL|wxEXPAND, 5 );
+
+ m_rightGridLayers = new wxGrid( this, ID_RIGHT_LIST, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_rightGridLayers->CreateGrid( 1, 3 );
+ m_rightGridLayers->EnableEditing( false );
+ m_rightGridLayers->EnableGridLines( true );
+ m_rightGridLayers->EnableDragGridSize( false );
+ m_rightGridLayers->SetMargins( 0, 3 );
+
+ // Columns
+ m_rightGridLayers->EnableDragColMove( false );
+ m_rightGridLayers->EnableDragColSize( false );
+ m_rightGridLayers->SetColLabelSize( 0 );
+ m_rightGridLayers->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_rightGridLayers->EnableDragRowSize( false );
+ m_rightGridLayers->SetRowLabelSize( 0 );
+ m_rightGridLayers->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_rightGridLayers->SetDefaultCellBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) );
+ m_rightGridLayers->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ bSizerUpper->Add( m_rightGridLayers, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bSizerUpper, 1, wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_leftGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftGridCellClick ), NULL, this );
+ m_leftGridLayers->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftButtonReleased ), NULL, this );
+ m_rightGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LAYER_SELECTION_BASE::OnRightGridCellClick ), NULL, this );
+ m_rightGridLayers->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftButtonReleased ), NULL, this );
+}
+
+DIALOG_LAYER_SELECTION_BASE::~DIALOG_LAYER_SELECTION_BASE()
+{
+ // Disconnect Events
+ m_leftGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftGridCellClick ), NULL, this );
+ m_leftGridLayers->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftButtonReleased ), NULL, this );
+ m_rightGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LAYER_SELECTION_BASE::OnRightGridCellClick ), NULL, this );
+ m_rightGridLayers->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( DIALOG_LAYER_SELECTION_BASE::OnLeftButtonReleased ), NULL, this );
+
+}
+
+DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizerLeft;
+ bSizerLeft = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextTopLayer = new wxStaticText( this, wxID_ANY, _("Top/Front Layer"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextTopLayer->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextTopLayer, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_leftGridLayers = new wxGrid( this, ID_LEFT_LIST, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_leftGridLayers->CreateGrid( 1, 3 );
+ m_leftGridLayers->EnableEditing( false );
+ m_leftGridLayers->EnableGridLines( true );
+ m_leftGridLayers->EnableDragGridSize( false );
+ m_leftGridLayers->SetMargins( 0, 3 );
+
+ // Columns
+ m_leftGridLayers->EnableDragColMove( false );
+ m_leftGridLayers->EnableDragColSize( false );
+ m_leftGridLayers->SetColLabelSize( 0 );
+ m_leftGridLayers->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_leftGridLayers->EnableDragRowSize( false );
+ m_leftGridLayers->SetRowLabelSize( 0 );
+ m_leftGridLayers->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+ m_leftGridLayers->SetLabelBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
+
+ // Cell Defaults
+ m_leftGridLayers->SetDefaultCellBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) );
+ m_leftGridLayers->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ bSizerLeft->Add( m_leftGridLayers, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizerUpper->Add( bSizerLeft, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerRight;
+ bSizerRight = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextBottomLayer = new wxStaticText( this, wxID_ANY, _("Bottom/Back Layer"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextBottomLayer->Wrap( -1 );
+ bSizerRight->Add( m_staticTextBottomLayer, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_rightGridLayers = new wxGrid( this, ID_RIGHT_LIST, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_rightGridLayers->CreateGrid( 1, 3 );
+ m_rightGridLayers->EnableEditing( false );
+ m_rightGridLayers->EnableGridLines( true );
+ m_rightGridLayers->EnableDragGridSize( false );
+ m_rightGridLayers->SetMargins( 0, 3 );
+
+ // Columns
+ m_rightGridLayers->EnableDragColMove( false );
+ m_rightGridLayers->EnableDragColSize( false );
+ m_rightGridLayers->SetColLabelSize( 0 );
+ m_rightGridLayers->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_rightGridLayers->EnableDragRowSize( false );
+ m_rightGridLayers->SetRowLabelSize( 0 );
+ m_rightGridLayers->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_rightGridLayers->SetDefaultCellBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) );
+ m_rightGridLayers->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ bSizerRight->Add( m_rightGridLayers, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizerUpper->Add( bSizerRight, 1, wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bSizerUpper, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerMain->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bSizerMain->Add( m_sdbSizer, 0, wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_leftGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnLeftGridCellClick ), NULL, this );
+ m_rightGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnRightGridCellClick ), NULL, this );
+ m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnOKClick ), NULL, this );
+}
+
+DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::~DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE()
+{
+ // Disconnect Events
+ m_leftGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnLeftGridCellClick ), NULL, this );
+ m_rightGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnRightGridCellClick ), NULL, this );
+ m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnOKClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_layer_selection_base.fbp b/pcbnew/dialogs/dialog_layer_selection_base.fbp
new file mode 100644
index 0000000..9bea630
--- /dev/null
+++ b/pcbnew/dialogs/dialog_layer_selection_base.fbp
@@ -0,0 +1,1055 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="11" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_layer_selection_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_layer_selection_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_LAYER_SELECTION_BASE</property>
+ <property name="pos"></property>
+ <property name="size">337,183</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE</property>
+ <property name="subclass"></property>
+ <property name="title">Select Layer:</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">0</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg">wxSYS_COLOUR_MENU</property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">0</property>
+ <property name="col_label_values"></property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">3</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">0</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">0</property>
+ <property name="editing">0</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_LEFT_LIST</property>
+ <property name="label_bg">wxSYS_COLOUR_WINDOW</property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">3</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_leftGridLayers</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">0</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick">OnLeftGridCellClick</event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp">OnLeftButtonReleased</event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">0</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg">wxSYS_COLOUR_MENU</property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">0</property>
+ <property name="col_label_values"></property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">3</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">0</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">0</property>
+ <property name="editing">0</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_RIGHT_LIST</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">3</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rightGridLayers</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">0</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick">OnRightGridCellClick</event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp">OnLeftButtonReleased</event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE</property>
+ <property name="pos"></property>
+ <property name="size">400,175</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE</property>
+ <property name="subclass"></property>
+ <property name="title">Select Copper Layer Pair:</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerLeft</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Top/Front Layer</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextTopLayer</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">0</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg">wxSYS_COLOUR_MENU</property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">0</property>
+ <property name="col_label_values"></property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">3</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">0</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">0</property>
+ <property name="editing">0</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_LEFT_LIST</property>
+ <property name="label_bg">wxSYS_COLOUR_WINDOW</property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">3</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_leftGridLayers</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">0</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick">OnLeftGridCellClick</event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRight</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Bottom/Back Layer</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextBottomLayer</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">0</property>
+ <property name="autosize_rows">0</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg">wxSYS_COLOUR_MENU</property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">0</property>
+ <property name="col_label_values"></property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">3</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">0</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">0</property>
+ <property name="editing">0</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_RIGHT_LIST</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">3</property>
+ <property name="margin_width">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rightGridLayers</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">0</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick">OnRightGridCellClick</event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_layer_selection_base.h b/pcbnew/dialogs/dialog_layer_selection_base.h
new file mode 100644
index 0000000..d61d4bf
--- /dev/null
+++ b/pcbnew/dialogs/dialog_layer_selection_base.h
@@ -0,0 +1,86 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Oct 8 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_LAYER_SELECTION_BASE_H__
+#define __DIALOG_LAYER_SELECTION_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/string.h>
+#include <wx/font.h>
+#include <wx/grid.h>
+#include <wx/gdicmn.h>
+#include <wx/sizer.h>
+#include <wx/dialog.h>
+#include <wx/stattext.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_LEFT_LIST 1000
+#define ID_RIGHT_LIST 1001
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_LAYER_SELECTION_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_LAYER_SELECTION_BASE : public wxDialog
+{
+ private:
+
+ protected:
+ wxGrid* m_leftGridLayers;
+ wxGrid* m_rightGridLayers;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnLeftGridCellClick( wxGridEvent& event ) { event.Skip(); }
+ virtual void OnLeftButtonReleased( wxMouseEvent& event ) { event.Skip(); }
+ virtual void OnRightGridCellClick( wxGridEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_LAYER_SELECTION_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select Layer:"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 337,183 ), long style = wxDEFAULT_DIALOG_STYLE );
+ ~DIALOG_LAYER_SELECTION_BASE();
+
+};
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE : public wxDialog
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticTextTopLayer;
+ wxGrid* m_leftGridLayers;
+ wxStaticText* m_staticTextBottomLayer;
+ wxGrid* m_rightGridLayers;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnLeftGridCellClick( wxGridEvent& event ) { event.Skip(); }
+ virtual void OnRightGridCellClick( wxGridEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select Copper Layer Pair:"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 400,175 ), long style = wxDEFAULT_DIALOG_STYLE );
+ ~DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE();
+
+};
+
+#endif //__DIALOG_LAYER_SELECTION_BASE_H__
diff --git a/pcbnew/dialogs/dialog_layers_setup.cpp b/pcbnew/dialogs/dialog_layers_setup.cpp
new file mode 100644
index 0000000..b3ae757
--- /dev/null
+++ b/pcbnew/dialogs/dialog_layers_setup.cpp
@@ -0,0 +1,743 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Isaac Marino Bavaresco, isaacbavaresco@yahoo.com.br
+ * Copyright (C) 2009 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2009 - 2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <macros.h>
+
+#include <confirm.h>
+#include <pcbnew.h>
+#include <invoke_pcb_dialog.h>
+
+#include <class_board.h>
+
+#include <dialog_layers_setup_base.h>
+
+
+// some define to choose how copper layers widgets are shown
+
+// if defined, display only active copper layers
+// if not displays always 1=the full set (32 copper layers)
+#define HIDE_INACTIVE_LAYERS
+
+// if defined, use the layer manager copper layers order (from FRONT to BACK)
+// to display inner layers.
+// if not, use the default order (from BACK to FRONT)
+#define USE_LAYER_MANAGER_COPPER_LAYERS_ORDER
+
+
+/**
+ * Struct CTLs
+ * holds the 3 ui control pointers for a single board layer.
+ */
+struct CTLs
+{
+ CTLs( wxControl* aName, wxCheckBox* aCheckBox, wxControl* aChoiceOrDesc, wxPanel * aPanel = NULL)
+ {
+ name = aName;
+ checkbox = aCheckBox;
+ choice = aChoiceOrDesc;
+ panel = aPanel;
+ }
+
+ wxControl* name;
+ wxCheckBox* checkbox;
+ wxControl* choice;
+ wxPanel * panel;
+};
+
+
+static LSEQ dlg_layers()
+{
+ // layers that are put out into the dialog UI, coordinate with wxformbuilder and
+ // getCTLs( LAYER_NUM aLayerNumber )
+ static const LAYER_ID layers[] = {
+ F_CrtYd,
+ F_Fab,
+ F_Adhes,
+ F_Paste,
+ F_SilkS,
+ F_Mask,
+ F_Cu,
+
+ In1_Cu,
+ In2_Cu,
+ In3_Cu,
+ In4_Cu,
+ In5_Cu,
+ In6_Cu,
+ In7_Cu,
+ In8_Cu,
+ In9_Cu,
+ In10_Cu,
+ In11_Cu,
+ In12_Cu,
+ In13_Cu,
+ In14_Cu,
+ In15_Cu,
+
+ In16_Cu,
+ In17_Cu,
+ In18_Cu,
+ In19_Cu,
+ In20_Cu,
+ In21_Cu,
+ In22_Cu,
+ In23_Cu,
+ In24_Cu,
+ In25_Cu,
+ In26_Cu,
+ In27_Cu,
+ In28_Cu,
+ In29_Cu,
+ In30_Cu,
+
+ B_Cu,
+ B_Mask,
+ B_SilkS,
+ B_Paste,
+ B_Adhes,
+ B_Fab,
+ B_CrtYd,
+
+ Edge_Cuts,
+ Margin,
+ Eco2_User,
+ Eco1_User,
+ Cmts_User,
+ Dwgs_User,
+ };
+
+ return LSEQ( layers, layers + DIM( layers ) );
+}
+
+
+class DIALOG_LAYERS_SETUP : public DIALOG_LAYERS_SETUP_BASE
+{
+public:
+ DIALOG_LAYERS_SETUP( wxTopLevelWindow* aCaller, BOARD* aBoard );
+
+private:
+ int m_copperLayerCount;
+ LSET m_enabledLayers;
+
+ BOARD* m_pcb;
+
+ wxStaticText* m_nameStaticText;
+ wxStaticText* m_enabledStaticText;
+ wxStaticText* m_typeStaticText;
+
+ void setLayerCheckBox( LAYER_NUM layer, bool isChecked );
+ void setCopperLayerCheckBoxes( int copperCount );
+
+ void showCopperChoice( int copperCount );
+ void showBoardLayerNames();
+ void showSelectedLayerCheckBoxes( LSET enableLayerMask );
+ void showLayerTypes();
+ void showPresets( LSET enabledLayerMask );
+
+ /** return the selected layer mask within the UI checkboxes */
+ LSET getUILayerMask();
+ wxString getLayerName( LAYER_NUM layer );
+ int getLayerTypeIndex( LAYER_NUM layer );
+
+
+ void OnCancelButtonClick( wxCommandEvent& event );
+ void OnOkButtonClick( wxCommandEvent& event );
+ void OnCheckBox( wxCommandEvent& event );
+ void DenyChangeCheckBox( wxCommandEvent& event );
+ void OnPresetsChoice( wxCommandEvent& event );
+ void OnCopperLayersChoice( wxCommandEvent& event );
+
+ bool testLayerNames();
+
+ /**
+ * Function getCTLs
+ * maps \a aLayerNumber to the wx IDs for that layer which are
+ * the layer name control ID, checkbox control ID, and choice control ID
+ */
+ CTLs getCTLs( LAYER_NUM aLayerNumber );
+
+ wxControl* getName( LAYER_NUM aLayer )
+ {
+ return getCTLs( aLayer ).name;
+ }
+
+ wxCheckBox* getCheckBox( LAYER_NUM aLayer )
+ {
+ return getCTLs( aLayer ).checkbox;
+ }
+
+ wxChoice* getChoice( LAYER_NUM aLayer )
+ {
+ return (wxChoice*) getCTLs( aLayer ).choice;
+ }
+
+ void moveTitles()
+ {
+ wxArrayInt widths = m_LayerListFlexGridSizer->GetColWidths();
+
+ int offset = 0;
+ wxSize txtz;
+
+ txtz = m_nameStaticText->GetSize();
+ m_nameStaticText->Move( offset + (widths[0] - txtz.x)/2, 5 );
+ offset += widths[0];
+
+ txtz = m_enabledStaticText->GetSize();
+ m_enabledStaticText->Move( offset + (widths[1] - txtz.x)/2, 5 );
+ offset += widths[1];
+
+ txtz = m_typeStaticText->GetSize();
+ m_typeStaticText->Move( offset + (widths[2] - txtz.x)/2, 5 );
+ }
+
+ void OnSize( wxSizeEvent& event );
+};
+
+
+// Layer bit masks for each defined "Preset Layer Grouping"
+static const LSET presets[] =
+{
+ LSET(), // shift the array index up by one, matches with "Custom".
+
+ // "Two layers, parts on Front only"
+ LSET( 2, F_Cu, B_Cu ) | LSET::FrontTechMask() | LSET::UserMask(),
+
+ // "Two layers, parts on Back only",
+ LSET( 2, F_Cu, B_Cu ) | LSET::BackTechMask() | LSET::UserMask(),
+
+ // "Two layers, parts on Front and Back",
+ LSET( 2, F_Cu, B_Cu ) | LSET::FrontTechMask() | LSET::BackTechMask() | LSET::UserMask(),
+
+ // "Four layers, parts on Front only"
+ LSET( 4, F_Cu, B_Cu, In1_Cu, In2_Cu ) | LSET::FrontTechMask() | LSET::UserMask(),
+
+ // "Four layers, parts on Front and Back"
+ LSET( 4, F_Cu, B_Cu, In1_Cu, In2_Cu ) | LSET::FrontTechMask() | LSET::BackTechMask() | LSET::UserMask(),
+
+ // "All layers on",
+ LSET().set(),
+};
+
+
+CTLs DIALOG_LAYERS_SETUP::getCTLs( LAYER_NUM aLayerNumber )
+{
+#define RETCOP(x) return CTLs( x##Name, x##CheckBox, x##Choice, x##Panel );
+#define RETAUX(x) return CTLs( x##Name, x##CheckBox, x##StaticText, x##Panel );
+
+ switch( aLayerNumber )
+ {
+ case F_CrtYd: RETAUX( m_CrtYdFront );
+ case F_Fab: RETAUX( m_FabFront );
+ case F_Adhes: RETAUX( m_AdhesFront );
+ case F_Paste: RETAUX( m_SoldPFront );
+ case F_SilkS: RETAUX( m_SilkSFront );
+ case F_Mask: RETAUX( m_MaskFront );
+ case F_Cu: RETCOP( m_Front );
+
+ case In1_Cu: RETCOP( m_In1 );
+ case In2_Cu: RETCOP( m_In2 );
+ case In3_Cu: RETCOP( m_In3 );
+ case In4_Cu: RETCOP( m_In4 );
+ case In5_Cu: RETCOP( m_In5 );
+ case In6_Cu: RETCOP( m_In6 );
+ case In7_Cu: RETCOP( m_In7 );
+ case In8_Cu: RETCOP( m_In8 );
+ case In9_Cu: RETCOP( m_In9 );
+ case In10_Cu: RETCOP( m_In10 );
+ case In11_Cu: RETCOP( m_In11 );
+ case In12_Cu: RETCOP( m_In12 );
+ case In13_Cu: RETCOP( m_In13 );
+ case In14_Cu: RETCOP( m_In14 );
+ case In15_Cu: RETCOP( m_In15 );
+
+ case In16_Cu: RETCOP( m_In16 );
+ case In17_Cu: RETCOP( m_In17 );
+ case In18_Cu: RETCOP( m_In18 );
+ case In19_Cu: RETCOP( m_In19 );
+ case In20_Cu: RETCOP( m_In20 );
+ case In21_Cu: RETCOP( m_In21 );
+ case In22_Cu: RETCOP( m_In22 );
+ case In23_Cu: RETCOP( m_In23 );
+ case In24_Cu: RETCOP( m_In24 );
+ case In25_Cu: RETCOP( m_In25 );
+ case In26_Cu: RETCOP( m_In26 );
+ case In27_Cu: RETCOP( m_In27 );
+ case In28_Cu: RETCOP( m_In28 );
+ case In29_Cu: RETCOP( m_In29 );
+ case In30_Cu: RETCOP( m_In30 );
+
+ case B_Cu: RETCOP( m_Back );
+ case B_Mask: RETAUX( m_MaskBack );
+ case B_SilkS: RETAUX( m_SilkSBack );
+ case B_Paste: RETAUX( m_SoldPBack );
+ case B_Adhes: RETAUX( m_AdhesBack );
+ case B_Fab: RETAUX( m_FabBack );
+ case B_CrtYd: RETAUX( m_CrtYdBack );
+
+ case Edge_Cuts: RETAUX( m_PCBEdges );
+ case Margin: RETAUX( m_Margin );
+ case Eco2_User: RETAUX( m_Eco2 );
+ case Eco1_User: RETAUX( m_Eco1 );
+ case Cmts_User: RETAUX( m_Comments );
+ case Dwgs_User: RETAUX( m_Drawings );
+ default:
+ wxASSERT_MSG( 0, wxT( "bad layer id" ) );
+ return CTLs( 0, 0, 0 );
+ }
+
+#undef RETCOP
+#undef RETAUX
+}
+
+
+DIALOG_LAYERS_SETUP::DIALOG_LAYERS_SETUP( wxTopLevelWindow* aParent, BOARD* aBoard ) :
+ DIALOG_LAYERS_SETUP_BASE( aParent )
+{
+ m_pcb = aBoard;
+
+ m_copperLayerCount = m_pcb->GetCopperLayerCount();
+ showCopperChoice( m_copperLayerCount );
+ setCopperLayerCheckBoxes( m_copperLayerCount );
+ m_staticTextBrdThicknessUnit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ PutValueInLocalUnits( *m_textCtrlBrdThickness,
+ m_pcb->GetDesignSettings().GetBoardThickness() );
+
+ showBoardLayerNames();
+
+ m_enabledLayers = m_pcb->GetEnabledLayers();
+ showSelectedLayerCheckBoxes( m_enabledLayers );
+ showPresets( m_enabledLayers );
+
+ showLayerTypes();
+
+ SetAutoLayout( true );
+
+ // these 3 controls are handled outside wxformbuilder so that we can add
+ // them without a sizer. Then we position them manually based on the column
+ // widths from m_LayerListFlexGridSizer->GetColWidths()
+ m_nameStaticText = new wxStaticText( m_TitlePanel, wxID_ANY, _("Name"), wxDefaultPosition, wxDefaultSize, 0 );
+
+ m_enabledStaticText = new wxStaticText( m_TitlePanel, wxID_ANY, _("Enabled"), wxDefaultPosition, wxDefaultSize, 0 );
+
+ m_typeStaticText = new wxStaticText( m_TitlePanel, wxID_ANY, _("Type"), wxDefaultPosition, wxDefaultSize, 0 );
+
+ // set the height of the title panel to be the size of any wxStaticText object
+ // plus 10 so we can have a border of 5 on both top and bottom.
+ m_TitlePanel->SetMinSize( wxSize( -1, m_AdhesFrontName->GetSize().y+10 ) );
+
+ m_LayersListPanel->ShowScrollbars( wxSHOW_SB_ALWAYS, wxSHOW_SB_ALWAYS );
+
+ Layout();
+ Fit();
+ moveTitles();
+
+ Center();
+
+ m_sdbSizerOK->SetFocus();
+ m_sdbSizerOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+}
+
+void DIALOG_LAYERS_SETUP::OnSize( wxSizeEvent& event )
+{
+ moveTitles();
+ event.Skip();
+}
+
+void DIALOG_LAYERS_SETUP::showCopperChoice( int copperCount )
+{
+ if( copperCount > MAX_CU_LAYERS )
+ copperCount = MAX_CU_LAYERS;
+
+ if( copperCount < 2 )
+ copperCount = 2;
+
+ for( int lyrCnt = 2; lyrCnt <= MAX_CU_LAYERS; lyrCnt += 2 )
+ {
+ // note this will change a one layer board to 2:
+ if( copperCount <= lyrCnt )
+ {
+ int idx = lyrCnt/2 - 1;
+ m_CopperLayersChoice->SetSelection(idx);
+ break;
+ }
+ }
+}
+
+
+void DIALOG_LAYERS_SETUP::showBoardLayerNames()
+{
+ // Establish all the board's layer names into the dialog presentation, by
+ // obtaining them from BOARD::GetLayerName() which calls
+ // BOARD::GetStandardLayerName() for non-coppers.
+
+ for( LSEQ seq = dlg_layers(); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ wxControl* ctl = getName( layer );
+
+ wxASSERT( ctl );
+
+ if( ctl )
+ {
+ wxString lname = m_pcb->GetLayerName( layer );
+ //D(printf("layerName[%d]=%s\n", layer, TO_UTF8( lname ) );)
+
+ if( ctl->IsKindOf( CLASSINFO(wxTextCtrl) ) )
+ ((wxTextCtrl*)ctl)->SetValue( lname ); // wxTextCtrl
+ else
+ ctl->SetLabel( lname ); // wxStaticText
+ }
+ }
+}
+
+
+void DIALOG_LAYERS_SETUP::showSelectedLayerCheckBoxes( LSET enabledLayers )
+{
+ // the check boxes
+ for( LSEQ seq = dlg_layers(); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+ setLayerCheckBox( layer, enabledLayers[layer] );
+ }
+}
+
+
+void DIALOG_LAYERS_SETUP::showPresets( LSET enabledLayers )
+{
+ int presetsNdx = 0; // the "Custom" setting, matches nothing
+
+ for( unsigned i=1; i<DIM(presets); ++i )
+ {
+ if( enabledLayers == presets[i] )
+ {
+ presetsNdx = i;
+ break;
+ }
+ }
+
+ m_PresetsChoice->SetSelection( presetsNdx );
+}
+
+
+void DIALOG_LAYERS_SETUP::showLayerTypes()
+{
+ for( LSEQ seq = LSET::AllCuMask().Seq(); seq; ++seq )
+ {
+ LAYER_ID cu_layer = *seq;
+
+ wxChoice* ctl = getChoice( cu_layer );
+ ctl->SetSelection( m_pcb->GetLayerType( cu_layer ) );
+ }
+}
+
+
+LSET DIALOG_LAYERS_SETUP::getUILayerMask()
+{
+ LSET layerMaskResult;
+
+ for( LSEQ seq = dlg_layers(); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+ wxCheckBox* ctl = getCheckBox( layer );
+
+ if( ctl->GetValue() )
+ {
+ layerMaskResult.set( layer );
+ }
+ }
+
+ return layerMaskResult;
+}
+
+
+void DIALOG_LAYERS_SETUP::setLayerCheckBox( LAYER_NUM aLayer, bool isChecked )
+{
+ wxCheckBox* ctl = getCheckBox( aLayer );
+ ctl->SetValue( isChecked );
+}
+
+
+void DIALOG_LAYERS_SETUP::setCopperLayerCheckBoxes( int copperCount )
+{
+ if( copperCount > 0 )
+ {
+ setLayerCheckBox( F_Cu, true );
+ --copperCount;
+ }
+
+ if( copperCount > 0 )
+ {
+ setLayerCheckBox( B_Cu, true );
+ --copperCount;
+ }
+
+ for( LSEQ seq = LSET::InternalCuMask().Seq(); seq; ++seq, --copperCount )
+ {
+ LAYER_ID layer = *seq;
+ bool state = copperCount > 0;
+
+#ifdef HIDE_INACTIVE_LAYERS
+ // This code hides non-active copper layers, or redisplays hidden
+ // layers which are now needed.
+ CTLs ctl = getCTLs( layer );
+
+ ctl.name->Show( state );
+ ctl.checkbox->Show( state );
+ ctl.choice->Show( state );
+
+ if( ctl.panel )
+ ctl.panel->Show( state );
+#endif
+
+ setLayerCheckBox( layer, state );
+ }
+
+#ifdef HIDE_INACTIVE_LAYERS
+ // Send an size event to force sizers to be updated,
+ // because the number of copper layers can have changed.
+ wxSizeEvent evt_size( m_LayersListPanel->GetSize() );
+ m_LayersListPanel->GetEventHandler()->ProcessEvent( evt_size );
+#endif
+}
+
+
+void DIALOG_LAYERS_SETUP::OnCheckBox( wxCommandEvent& event )
+{
+ m_enabledLayers = getUILayerMask();
+
+ showPresets( m_enabledLayers );
+}
+
+
+void DIALOG_LAYERS_SETUP::DenyChangeCheckBox( wxCommandEvent& event )
+{
+ // user may not change copper layer checkboxes from anything other than
+ // either presets choice or the copper layer choice controls.
+
+ // I tried to simply disable the copper CheckBoxes but they look like crap,
+ // so leave them enabled and reverse the user's attempt to toggle them.
+
+ setCopperLayerCheckBoxes( m_copperLayerCount );
+}
+
+
+void DIALOG_LAYERS_SETUP::OnPresetsChoice( wxCommandEvent& event )
+{
+ unsigned presetNdx = m_PresetsChoice->GetCurrentSelection();
+
+ if( presetNdx == 0 ) // the Custom setting controls nothing.
+ return;
+
+ if( presetNdx < DIM(presets) )
+ {
+ m_enabledLayers = presets[ presetNdx ];
+
+ LSET copperSet = m_enabledLayers & LSET::AllCuMask();
+
+ int copperCount = copperSet.count();
+
+ m_copperLayerCount = copperCount;
+
+ showCopperChoice( m_copperLayerCount );
+
+ showSelectedLayerCheckBoxes( m_enabledLayers );
+
+ setCopperLayerCheckBoxes( m_copperLayerCount );
+ }
+}
+
+
+void DIALOG_LAYERS_SETUP::OnCopperLayersChoice( wxCommandEvent& event )
+{
+ m_copperLayerCount = m_CopperLayersChoice->GetCurrentSelection() * 2 + 2;
+
+ setCopperLayerCheckBoxes( m_copperLayerCount );
+
+ m_enabledLayers = getUILayerMask();
+
+ showPresets( m_enabledLayers );
+}
+
+
+void DIALOG_LAYERS_SETUP::OnCancelButtonClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+void DIALOG_LAYERS_SETUP::OnOkButtonClick( wxCommandEvent& event )
+{
+ if( testLayerNames() )
+ {
+ wxString name;
+
+ m_enabledLayers = getUILayerMask();
+ m_pcb->SetEnabledLayers( m_enabledLayers );
+
+ /* Ensure enabled layers are also visible
+ * This is mainly to avoid mistakes if some enabled
+ * layers are not visible when exiting this dialog
+ */
+ m_pcb->SetVisibleLayers( m_enabledLayers );
+
+ for( LSEQ seq = LSET::AllCuMask().Seq(); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ if( m_enabledLayers[layer] )
+ {
+ name = getLayerName( layer );
+ m_pcb->SetLayerName( layer, name );
+ LAYER_T t = (LAYER_T) getLayerTypeIndex( layer );
+ m_pcb->SetLayerType( layer, t );
+ }
+ }
+
+ int thickness = ValueFromTextCtrl( *m_textCtrlBrdThickness );
+
+ // Clamp the value between reasonable values
+
+ thickness = Clamp( Millimeter2iu( 0.1 ), thickness, Millimeter2iu( 10.0 ) );
+ m_pcb->GetDesignSettings().SetBoardThickness( thickness );
+
+ EndModal( wxID_OK );
+ }
+}
+
+
+int DIALOG_LAYERS_SETUP::getLayerTypeIndex( LAYER_NUM aLayer )
+{
+ wxChoice* ctl = getChoice( aLayer );
+
+ int ret = ctl->GetCurrentSelection(); // indices must have same sequence as LAYER_T
+
+ return ret;
+}
+
+
+wxString DIALOG_LAYERS_SETUP::getLayerName( LAYER_NUM aLayer )
+{
+ wxString ret;
+
+ wxASSERT( IsCopperLayer( aLayer ) );
+
+ wxTextCtrl* ctl = (wxTextCtrl*) getName( aLayer );
+
+ ret = ctl->GetValue().Trim();
+
+ return ret;
+}
+
+
+static bool hasOneOf( const wxString& str, const wxString& chars )
+{
+ for( unsigned i=0; i<chars.Len(); ++i )
+ if( str.Find( chars[i] ) != wxNOT_FOUND )
+ return true;
+ return false;
+}
+
+
+bool DIALOG_LAYERS_SETUP::testLayerNames()
+{
+ std::vector<wxString> names;
+
+ wxTextCtrl* ctl;
+
+ for( LSEQ seq = LSET::AllCuMask().Seq(); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ // we _can_ rely on m_enabledLayers being current here:
+ if( !m_enabledLayers[layer] )
+ continue;
+
+ wxString name = getLayerName( layer );
+
+ //D(printf("name[%d]=%s\n", layer, TO_UTF8(name) );)
+
+ ctl = (wxTextCtrl*) getName( layer );
+
+ // check name for legality.
+ // 1) cannot be blank.
+ // 2) cannot have blanks.
+ // 3) cannot have " chars
+ // 4) cannot be 'signal'
+ // 5) must be unique.
+ // 6) cannot have illegal chars in filenames ( some filenames are built from layer names )
+ // like : % $ \ " / :
+
+ wxString badchars = wxFileName::GetForbiddenChars(wxPATH_DOS);
+ badchars.Append( '%' );
+
+ if( !name )
+ {
+ DisplayError( this, _("Layer name may not be empty" ) );
+ ctl->SetFocus(); // on the bad name
+ return false;
+ }
+
+ if( hasOneOf( name, badchars ) )
+ {
+ DisplayError( this, _("Layer name has an illegal character, one of: '") + badchars + wxT("'") );
+ ctl->SetFocus(); // on the bad name
+ return false;
+ }
+
+ if( name == wxT("signal") )
+ {
+ DisplayError( this, _("'signal' is a reserved layer name") );
+ ctl->SetFocus(); // on the bad name
+ return false;
+ }
+
+ for( std::vector<wxString>::iterator it = names.begin(); it != names.end(); ++it )
+ {
+ if( name == *it )
+ {
+ DisplayError( this, _("Layer name is a duplicate of another") );
+ ctl->SetFocus(); // on the bad name
+ return false;
+ }
+ }
+
+ names.push_back( name );
+ }
+
+ return true;
+}
+
+
+bool InvokeLayerSetup( wxTopLevelWindow* aCaller, BOARD* aBoard )
+{
+ DIALOG_LAYERS_SETUP dlg( aCaller, aBoard );
+
+ return dlg.ShowModal() == wxID_OK;
+}
diff --git a/pcbnew/dialogs/dialog_layers_setup_base.cpp b/pcbnew/dialogs/dialog_layers_setup_base.cpp
new file mode 100644
index 0000000..1baa0a6
--- /dev/null
+++ b/pcbnew/dialogs/dialog_layers_setup_base.cpp
@@ -0,0 +1,1633 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_layers_setup_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_LAYERS_SETUP_BASE::DIALOG_LAYERS_SETUP_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( 550,600 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bChoicesSizer;
+ bChoicesSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bPresetsSizer;
+ bPresetsSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextGrouping = new wxStaticText( this, wxID_ANY, _("Preset Layer Groupings"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextGrouping->Wrap( -1 );
+ bPresetsSizer->Add( m_staticTextGrouping, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_PresetsChoiceChoices[] = { _("Custom"), _("Two layers, parts on Front only"), _("Two layers, parts on Back only"), _("Two layers, parts on Front and Back"), _("Four layers, parts on Front only"), _("Four layers, parts on Front and Back"), _("All layers on") };
+ int m_PresetsChoiceNChoices = sizeof( m_PresetsChoiceChoices ) / sizeof( wxString );
+ m_PresetsChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_PresetsChoiceNChoices, m_PresetsChoiceChoices, 0 );
+ m_PresetsChoice->SetSelection( 0 );
+ bPresetsSizer->Add( m_PresetsChoice, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+
+ bChoicesSizer->Add( bPresetsSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bCopperLayersSizer;
+ bCopperLayersSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextCopperLayers = new wxStaticText( this, wxID_ANY, _("Copper Layers"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextCopperLayers->Wrap( -1 );
+ bCopperLayersSizer->Add( m_staticTextCopperLayers, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_CopperLayersChoiceChoices[] = { _("2"), _("4"), _("6"), _("8"), _("10"), _("12"), _("14"), _("16"), _("18"), _("20"), _("22"), _("24"), _("26"), _("28"), _("30"), _("32") };
+ int m_CopperLayersChoiceNChoices = sizeof( m_CopperLayersChoiceChoices ) / sizeof( wxString );
+ m_CopperLayersChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_CopperLayersChoiceNChoices, m_CopperLayersChoiceChoices, 0 );
+ m_CopperLayersChoice->SetSelection( 0 );
+ bCopperLayersSizer->Add( m_CopperLayersChoice, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+
+ bChoicesSizer->Add( bCopperLayersSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bBrdThicknessSizer;
+ bBrdThicknessSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextBrdThickness = new wxStaticText( this, wxID_ANY, _("Board Thickness"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextBrdThickness->Wrap( -1 );
+ bBrdThicknessSizer->Add( m_staticTextBrdThickness, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxFlexGridSizer* fgSizerBrdThickness;
+ fgSizerBrdThickness = new wxFlexGridSizer( 0, 2, 0, 0 );
+ fgSizerBrdThickness->AddGrowableCol( 0 );
+ fgSizerBrdThickness->SetFlexibleDirection( wxBOTH );
+ fgSizerBrdThickness->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_textCtrlBrdThickness = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizerBrdThickness->Add( m_textCtrlBrdThickness, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticTextBrdThicknessUnit = new wxStaticText( this, wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextBrdThicknessUnit->Wrap( -1 );
+ fgSizerBrdThickness->Add( m_staticTextBrdThicknessUnit, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
+
+
+ bBrdThicknessSizer->Add( fgSizerBrdThickness, 1, wxEXPAND, 5 );
+
+
+ bChoicesSizer->Add( bBrdThicknessSizer, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bChoicesSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* b_layersListSizer;
+ b_layersListSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextLayers = new wxStaticText( this, wxID_ANY, _("Layers"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextLayers->Wrap( -1 );
+ b_layersListSizer->Add( m_staticTextLayers, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bCaptionsSizer;
+ bCaptionsSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ m_TitlePanel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxRAISED_BORDER|wxTAB_TRAVERSAL );
+ m_TitlePanel->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_CAPTIONTEXT ) );
+ m_TitlePanel->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVECAPTION ) );
+ m_TitlePanel->SetMinSize( wxSize( -1,15 ) );
+
+ bCaptionsSizer->Add( m_TitlePanel, 1, wxEXPAND, 5 );
+
+
+ b_layersListSizer->Add( bCaptionsSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ m_LayersListPanel = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxRAISED_BORDER|wxTAB_TRAVERSAL|wxVSCROLL );
+ m_LayersListPanel->SetScrollRate( 0, 5 );
+ m_LayerListFlexGridSizer = new wxFlexGridSizer( 0, 3, 0, 0 );
+ m_LayerListFlexGridSizer->AddGrowableCol( 0 );
+ m_LayerListFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
+ m_LayerListFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_CrtYdFrontName = new wxStaticText( m_LayersListPanel, ID_CRTYDFRONTNAME, _("CrtYd_Front_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_CrtYdFrontName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_CrtYdFrontName, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_CrtYdFrontPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), 0 );
+ m_CrtYdFrontPanel->SetBackgroundColour( wxColour( 255, 233, 236 ) );
+
+ wxBoxSizer* bSizer611;
+ bSizer611 = new wxBoxSizer( wxHORIZONTAL );
+
+
+ bSizer611->Add( 0, 0, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 15 );
+
+ m_CrtYdFrontCheckBox = new wxCheckBox( m_CrtYdFrontPanel, ID_CRTYDFRONTCHECKBOX, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 );
+ m_CrtYdFrontCheckBox->SetToolTip( _("If you want a courtyard layer for the front side of the board") );
+
+ bSizer611->Add( m_CrtYdFrontCheckBox, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
+
+
+ bSizer611->Add( 0, 0, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 15 );
+
+
+ m_CrtYdFrontPanel->SetSizer( bSizer611 );
+ m_CrtYdFrontPanel->Layout();
+ bSizer611->Fit( m_CrtYdFrontPanel );
+ m_LayerListFlexGridSizer->Add( m_CrtYdFrontPanel, 1, wxEXPAND, 5 );
+
+ m_CrtYdFrontStaticText = new wxStaticText( m_LayersListPanel, ID_CRTYDFRONTCHOICE, _("Off-board, testing"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_CrtYdFrontStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_CrtYdFrontStaticText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_FabFrontName = new wxStaticText( m_LayersListPanel, ID_FABFRONTNAME, _("Fab_Front_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_FabFrontName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_FabFrontName, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_FabFrontPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_FabFrontPanel->SetBackgroundColour( wxColour( 236, 233, 236 ) );
+
+ wxBoxSizer* bSizer61;
+ bSizer61 = new wxBoxSizer( wxVERTICAL );
+
+ m_FabFrontCheckBox = new wxCheckBox( m_FabFrontPanel, ID_FABFRONTCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_FabFrontCheckBox->SetToolTip( _("If you want a fabrication layer for the front side of the board") );
+
+ bSizer61->Add( m_FabFrontCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_FabFrontPanel->SetSizer( bSizer61 );
+ m_FabFrontPanel->Layout();
+ bSizer61->Fit( m_FabFrontPanel );
+ m_LayerListFlexGridSizer->Add( m_FabFrontPanel, 1, wxEXPAND, 5 );
+
+ m_FabFrontStaticText = new wxStaticText( m_LayersListPanel, ID_FABFRONTCHOICE, _("Off-board, manufacturing"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_FabFrontStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_FabFrontStaticText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_AdhesFrontName = new wxStaticText( m_LayersListPanel, ID_ADHESFRONTNAME, _("Adhes_Front_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_AdhesFrontName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_AdhesFrontName, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_AdhesFrontPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_AdhesFrontPanel->SetBackgroundColour( wxColour( 236, 233, 236 ) );
+
+ wxBoxSizer* bSizer6;
+ bSizer6 = new wxBoxSizer( wxVERTICAL );
+
+ m_AdhesFrontCheckBox = new wxCheckBox( m_AdhesFrontPanel, ID_ADHESFRONTCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_AdhesFrontCheckBox->SetToolTip( _("If you want an adhesive template for the front side of the board") );
+
+ bSizer6->Add( m_AdhesFrontCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_AdhesFrontPanel->SetSizer( bSizer6 );
+ m_AdhesFrontPanel->Layout();
+ bSizer6->Fit( m_AdhesFrontPanel );
+ m_LayerListFlexGridSizer->Add( m_AdhesFrontPanel, 1, wxEXPAND, 5 );
+
+ m_AdhesFrontStaticText = new wxStaticText( m_LayersListPanel, ID_ADHESFRONTCHOICE, _("Off-board, manufacturing"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_AdhesFrontStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_AdhesFrontStaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_SoldPFrontName = new wxStaticText( m_LayersListPanel, ID_SOLDPFRONTNAME, _("SoldP_Front_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SoldPFrontName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_SoldPFrontName, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_SoldPFrontPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SoldPFrontPanel->SetBackgroundColour( wxColour( 255, 253, 235 ) );
+
+ wxBoxSizer* bSizer7;
+ bSizer7 = new wxBoxSizer( wxVERTICAL );
+
+ m_SoldPFrontCheckBox = new wxCheckBox( m_SoldPFrontPanel, ID_SOLDPFRONTCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SoldPFrontCheckBox->SetToolTip( _("If you want a solder paster layer for front side of the board") );
+
+ bSizer7->Add( m_SoldPFrontCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_SoldPFrontPanel->SetSizer( bSizer7 );
+ m_SoldPFrontPanel->Layout();
+ bSizer7->Fit( m_SoldPFrontPanel );
+ m_LayerListFlexGridSizer->Add( m_SoldPFrontPanel, 1, wxEXPAND, 5 );
+
+ m_SoldPFrontStaticText = new wxStaticText( m_LayersListPanel, ID_SOLDPFRONTCHOICE, _("On-board, non-copper"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SoldPFrontStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_SoldPFrontStaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_SilkSFrontName = new wxStaticText( m_LayersListPanel, ID_SILKSFRONTNAME, _("SilkS_Front_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SilkSFrontName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_SilkSFrontName, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_SilkSFrontPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_SilkSFrontPanel->SetBackgroundColour( wxColour( 255, 252, 235 ) );
+
+ wxBoxSizer* bSizer5;
+ bSizer5 = new wxBoxSizer( wxVERTICAL );
+
+ m_SilkSFrontCheckBox = new wxCheckBox( m_SilkSFrontPanel, ID_SILKSFRONTCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SilkSFrontCheckBox->SetToolTip( _("If you want a silk screen layer for the front side of the board") );
+
+ bSizer5->Add( m_SilkSFrontCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_SilkSFrontPanel->SetSizer( bSizer5 );
+ m_SilkSFrontPanel->Layout();
+ bSizer5->Fit( m_SilkSFrontPanel );
+ m_LayerListFlexGridSizer->Add( m_SilkSFrontPanel, 1, wxEXPAND, 5 );
+
+ m_SilkSFrontStaticText = new wxStaticText( m_LayersListPanel, ID_SILKSFRONTCHOICE, _("On-board, non-copper"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SilkSFrontStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_SilkSFrontStaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_MaskFrontName = new wxStaticText( m_LayersListPanel, ID_MASKFRONTNAME, _("Mask_Front_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MaskFrontName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_MaskFrontName, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_MaskFrontPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_MaskFrontPanel->SetBackgroundColour( wxColour( 255, 252, 235 ) );
+
+ wxBoxSizer* bSizer8;
+ bSizer8 = new wxBoxSizer( wxVERTICAL );
+
+ m_MaskFrontCheckBox = new wxCheckBox( m_MaskFrontPanel, ID_MASKFRONTCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_MaskFrontCheckBox->SetToolTip( _("If you want a solder mask layer for the front of the board") );
+
+ bSizer8->Add( m_MaskFrontCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_MaskFrontPanel->SetSizer( bSizer8 );
+ m_MaskFrontPanel->Layout();
+ bSizer8->Fit( m_MaskFrontPanel );
+ m_LayerListFlexGridSizer->Add( m_MaskFrontPanel, 1, wxEXPAND, 5 );
+
+ m_MaskFrontStaticText = new wxStaticText( m_LayersListPanel, ID_MASKFRONTCHOICE, _("On-board, non-copper"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MaskFrontStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_MaskFrontStaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_FrontName = new wxTextCtrl( m_LayersListPanel, ID_FRONTNAME, _("Front_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_FrontName->SetMaxLength( 20 );
+ m_FrontName->SetToolTip( _("Layer name of front (top) copper layer") );
+
+ m_LayerListFlexGridSizer->Add( m_FrontName, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_FrontPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_FrontPanel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bSizer9;
+ bSizer9 = new wxBoxSizer( wxVERTICAL );
+
+ m_FrontCheckBox = new wxCheckBox( m_FrontPanel, ID_FRONTCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_FrontCheckBox->Enable( false );
+ m_FrontCheckBox->SetToolTip( _("If you want a front copper layer") );
+
+ bSizer9->Add( m_FrontCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_FrontPanel->SetSizer( bSizer9 );
+ m_FrontPanel->Layout();
+ bSizer9->Fit( m_FrontPanel );
+ m_LayerListFlexGridSizer->Add( m_FrontPanel, 1, wxEXPAND, 5 );
+
+ wxString m_FrontChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_FrontChoiceNChoices = sizeof( m_FrontChoiceChoices ) / sizeof( wxString );
+ m_FrontChoice = new wxChoice( m_LayersListPanel, ID_FRONTCHOICE, wxDefaultPosition, wxDefaultSize, m_FrontChoiceNChoices, m_FrontChoiceChoices, 0 );
+ m_FrontChoice->SetSelection( 0 );
+ m_FrontChoice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_FrontChoice, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_In1Name = new wxTextCtrl( m_LayersListPanel, ID_IN1NAME, _("In1"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In1Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In1Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In1Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In1Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn1Sizer;
+ bIn1Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In1CheckBox = new wxCheckBox( m_In1Panel, ID_IN1CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In1CheckBox->Enable( false );
+
+ bIn1Sizer->Add( m_In1CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In1Panel->SetSizer( bIn1Sizer );
+ m_In1Panel->Layout();
+ bIn1Sizer->Fit( m_In1Panel );
+ m_LayerListFlexGridSizer->Add( m_In1Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In1ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In1ChoiceNChoices = sizeof( m_In1ChoiceChoices ) / sizeof( wxString );
+ m_In1Choice = new wxChoice( m_LayersListPanel, ID_IN1CHOICE, wxDefaultPosition, wxDefaultSize, m_In1ChoiceNChoices, m_In1ChoiceChoices, 0 );
+ m_In1Choice->SetSelection( 0 );
+ m_In1Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In1Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In2Name = new wxTextCtrl( m_LayersListPanel, ID_IN2NAME, _("In2"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In2Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In2Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In2Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In2Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn2Sizer;
+ bIn2Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In2CheckBox = new wxCheckBox( m_In2Panel, ID_IN2CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In2CheckBox->Enable( false );
+
+ bIn2Sizer->Add( m_In2CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In2Panel->SetSizer( bIn2Sizer );
+ m_In2Panel->Layout();
+ bIn2Sizer->Fit( m_In2Panel );
+ m_LayerListFlexGridSizer->Add( m_In2Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In2ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In2ChoiceNChoices = sizeof( m_In2ChoiceChoices ) / sizeof( wxString );
+ m_In2Choice = new wxChoice( m_LayersListPanel, ID_IN2CHOICE, wxDefaultPosition, wxDefaultSize, m_In2ChoiceNChoices, m_In2ChoiceChoices, 0 );
+ m_In2Choice->SetSelection( 0 );
+ m_In2Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In2Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In3Name = new wxTextCtrl( m_LayersListPanel, ID_IN3NAME, _("In3"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In3Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In3Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In3Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In3Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn3Sizer;
+ bIn3Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In3CheckBox = new wxCheckBox( m_In3Panel, ID_IN3CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In3CheckBox->Enable( false );
+
+ bIn3Sizer->Add( m_In3CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In3Panel->SetSizer( bIn3Sizer );
+ m_In3Panel->Layout();
+ bIn3Sizer->Fit( m_In3Panel );
+ m_LayerListFlexGridSizer->Add( m_In3Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In3ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In3ChoiceNChoices = sizeof( m_In3ChoiceChoices ) / sizeof( wxString );
+ m_In3Choice = new wxChoice( m_LayersListPanel, ID_IN3CHOICE, wxDefaultPosition, wxDefaultSize, m_In3ChoiceNChoices, m_In3ChoiceChoices, 0 );
+ m_In3Choice->SetSelection( 0 );
+ m_In3Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In3Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In4Name = new wxTextCtrl( m_LayersListPanel, ID_IN4NAME, _("In4"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In4Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In4Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In4Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In4Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn4Sizer;
+ bIn4Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In4CheckBox = new wxCheckBox( m_In4Panel, ID_IN4CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In4CheckBox->Enable( false );
+
+ bIn4Sizer->Add( m_In4CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In4Panel->SetSizer( bIn4Sizer );
+ m_In4Panel->Layout();
+ bIn4Sizer->Fit( m_In4Panel );
+ m_LayerListFlexGridSizer->Add( m_In4Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In4ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In4ChoiceNChoices = sizeof( m_In4ChoiceChoices ) / sizeof( wxString );
+ m_In4Choice = new wxChoice( m_LayersListPanel, ID_IN4CHOICE, wxDefaultPosition, wxDefaultSize, m_In4ChoiceNChoices, m_In4ChoiceChoices, 0 );
+ m_In4Choice->SetSelection( 0 );
+ m_In4Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In4Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In5Name = new wxTextCtrl( m_LayersListPanel, ID_IN5NAME, _("In5"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In5Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In5Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In5Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In5Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn5Sizer;
+ bIn5Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In5CheckBox = new wxCheckBox( m_In5Panel, ID_IN5CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In5CheckBox->Enable( false );
+
+ bIn5Sizer->Add( m_In5CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In5Panel->SetSizer( bIn5Sizer );
+ m_In5Panel->Layout();
+ bIn5Sizer->Fit( m_In5Panel );
+ m_LayerListFlexGridSizer->Add( m_In5Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In5ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In5ChoiceNChoices = sizeof( m_In5ChoiceChoices ) / sizeof( wxString );
+ m_In5Choice = new wxChoice( m_LayersListPanel, ID_IN5CHOICE, wxDefaultPosition, wxDefaultSize, m_In5ChoiceNChoices, m_In5ChoiceChoices, 0 );
+ m_In5Choice->SetSelection( 0 );
+ m_In5Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In5Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In6Name = new wxTextCtrl( m_LayersListPanel, ID_IN6NAME, _("In6"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In6Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In6Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In6Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In6Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn6Sizer;
+ bIn6Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In6CheckBox = new wxCheckBox( m_In6Panel, ID_IN6CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In6CheckBox->Enable( false );
+
+ bIn6Sizer->Add( m_In6CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In6Panel->SetSizer( bIn6Sizer );
+ m_In6Panel->Layout();
+ bIn6Sizer->Fit( m_In6Panel );
+ m_LayerListFlexGridSizer->Add( m_In6Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In6ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In6ChoiceNChoices = sizeof( m_In6ChoiceChoices ) / sizeof( wxString );
+ m_In6Choice = new wxChoice( m_LayersListPanel, ID_IN6CHOICE, wxDefaultPosition, wxDefaultSize, m_In6ChoiceNChoices, m_In6ChoiceChoices, 0 );
+ m_In6Choice->SetSelection( 0 );
+ m_In6Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In6Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In7Name = new wxTextCtrl( m_LayersListPanel, ID_IN7NAME, _("In7"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In7Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In7Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In7Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In7Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn7Sizer;
+ bIn7Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In7CheckBox = new wxCheckBox( m_In7Panel, ID_IN7CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In7CheckBox->Enable( false );
+
+ bIn7Sizer->Add( m_In7CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In7Panel->SetSizer( bIn7Sizer );
+ m_In7Panel->Layout();
+ bIn7Sizer->Fit( m_In7Panel );
+ m_LayerListFlexGridSizer->Add( m_In7Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In7ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In7ChoiceNChoices = sizeof( m_In7ChoiceChoices ) / sizeof( wxString );
+ m_In7Choice = new wxChoice( m_LayersListPanel, ID_IN7CHOICE, wxDefaultPosition, wxDefaultSize, m_In7ChoiceNChoices, m_In7ChoiceChoices, 0 );
+ m_In7Choice->SetSelection( 0 );
+ m_In7Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In7Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In8Name = new wxTextCtrl( m_LayersListPanel, ID_IN8NAME, _("In8"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In8Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In8Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In8Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In8Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn8Sizer;
+ bIn8Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In8CheckBox = new wxCheckBox( m_In8Panel, ID_IN8CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In8CheckBox->Enable( false );
+
+ bIn8Sizer->Add( m_In8CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In8Panel->SetSizer( bIn8Sizer );
+ m_In8Panel->Layout();
+ bIn8Sizer->Fit( m_In8Panel );
+ m_LayerListFlexGridSizer->Add( m_In8Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In8ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In8ChoiceNChoices = sizeof( m_In8ChoiceChoices ) / sizeof( wxString );
+ m_In8Choice = new wxChoice( m_LayersListPanel, ID_IN8CHOICE, wxDefaultPosition, wxDefaultSize, m_In8ChoiceNChoices, m_In8ChoiceChoices, 0 );
+ m_In8Choice->SetSelection( 0 );
+ m_In8Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In8Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In9Name = new wxTextCtrl( m_LayersListPanel, ID_IN9NAME, _("In9"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In9Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In9Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In9Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In9Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn9Sizer;
+ bIn9Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In9CheckBox = new wxCheckBox( m_In9Panel, ID_IN9CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In9CheckBox->Enable( false );
+
+ bIn9Sizer->Add( m_In9CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In9Panel->SetSizer( bIn9Sizer );
+ m_In9Panel->Layout();
+ bIn9Sizer->Fit( m_In9Panel );
+ m_LayerListFlexGridSizer->Add( m_In9Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In9ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In9ChoiceNChoices = sizeof( m_In9ChoiceChoices ) / sizeof( wxString );
+ m_In9Choice = new wxChoice( m_LayersListPanel, ID_IN9CHOICE, wxDefaultPosition, wxDefaultSize, m_In9ChoiceNChoices, m_In9ChoiceChoices, 0 );
+ m_In9Choice->SetSelection( 0 );
+ m_In9Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In9Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In10Name = new wxTextCtrl( m_LayersListPanel, ID_IN10NAME, _("In10"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In10Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In10Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In10Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In10Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn10Sizer;
+ bIn10Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In10CheckBox = new wxCheckBox( m_In10Panel, ID_IN10CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In10CheckBox->Enable( false );
+
+ bIn10Sizer->Add( m_In10CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In10Panel->SetSizer( bIn10Sizer );
+ m_In10Panel->Layout();
+ bIn10Sizer->Fit( m_In10Panel );
+ m_LayerListFlexGridSizer->Add( m_In10Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In10ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In10ChoiceNChoices = sizeof( m_In10ChoiceChoices ) / sizeof( wxString );
+ m_In10Choice = new wxChoice( m_LayersListPanel, ID_IN10CHOICE, wxDefaultPosition, wxDefaultSize, m_In10ChoiceNChoices, m_In10ChoiceChoices, 0 );
+ m_In10Choice->SetSelection( 0 );
+ m_In10Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In10Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In11Name = new wxTextCtrl( m_LayersListPanel, ID_IN11NAME, _("In11"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In11Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In11Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In11Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In11Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn11Sizer;
+ bIn11Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In11CheckBox = new wxCheckBox( m_In11Panel, ID_IN11CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In11CheckBox->Enable( false );
+
+ bIn11Sizer->Add( m_In11CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In11Panel->SetSizer( bIn11Sizer );
+ m_In11Panel->Layout();
+ bIn11Sizer->Fit( m_In11Panel );
+ m_LayerListFlexGridSizer->Add( m_In11Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In11ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In11ChoiceNChoices = sizeof( m_In11ChoiceChoices ) / sizeof( wxString );
+ m_In11Choice = new wxChoice( m_LayersListPanel, ID_IN11CHOICE, wxDefaultPosition, wxDefaultSize, m_In11ChoiceNChoices, m_In11ChoiceChoices, 0 );
+ m_In11Choice->SetSelection( 0 );
+ m_In11Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In11Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In12Name = new wxTextCtrl( m_LayersListPanel, ID_IN12NAME, _("In12"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In12Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In12Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In12Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In12Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn12Sizer;
+ bIn12Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In12CheckBox = new wxCheckBox( m_In12Panel, ID_IN12CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In12CheckBox->Enable( false );
+
+ bIn12Sizer->Add( m_In12CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In12Panel->SetSizer( bIn12Sizer );
+ m_In12Panel->Layout();
+ bIn12Sizer->Fit( m_In12Panel );
+ m_LayerListFlexGridSizer->Add( m_In12Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In12ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In12ChoiceNChoices = sizeof( m_In12ChoiceChoices ) / sizeof( wxString );
+ m_In12Choice = new wxChoice( m_LayersListPanel, ID_IN12CHOICE, wxDefaultPosition, wxDefaultSize, m_In12ChoiceNChoices, m_In12ChoiceChoices, 0 );
+ m_In12Choice->SetSelection( 0 );
+ m_In12Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In12Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In13Name = new wxTextCtrl( m_LayersListPanel, ID_IN13NAME, _("In13"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In13Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In13Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In13Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In13Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn13Sizer;
+ bIn13Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In13CheckBox = new wxCheckBox( m_In13Panel, ID_IN13CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In13CheckBox->Enable( false );
+
+ bIn13Sizer->Add( m_In13CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In13Panel->SetSizer( bIn13Sizer );
+ m_In13Panel->Layout();
+ bIn13Sizer->Fit( m_In13Panel );
+ m_LayerListFlexGridSizer->Add( m_In13Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In13ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In13ChoiceNChoices = sizeof( m_In13ChoiceChoices ) / sizeof( wxString );
+ m_In13Choice = new wxChoice( m_LayersListPanel, ID_IN13CHOICE, wxDefaultPosition, wxDefaultSize, m_In13ChoiceNChoices, m_In13ChoiceChoices, 0 );
+ m_In13Choice->SetSelection( 0 );
+ m_In13Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In13Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In14Name = new wxTextCtrl( m_LayersListPanel, ID_IN14NAME, _("In14"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In14Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In14Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In14Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In14Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn14Sizer;
+ bIn14Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In14CheckBox = new wxCheckBox( m_In14Panel, ID_IN14CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In14CheckBox->Enable( false );
+
+ bIn14Sizer->Add( m_In14CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In14Panel->SetSizer( bIn14Sizer );
+ m_In14Panel->Layout();
+ bIn14Sizer->Fit( m_In14Panel );
+ m_LayerListFlexGridSizer->Add( m_In14Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In14ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In14ChoiceNChoices = sizeof( m_In14ChoiceChoices ) / sizeof( wxString );
+ m_In14Choice = new wxChoice( m_LayersListPanel, ID_IN14CHOICE, wxDefaultPosition, wxDefaultSize, m_In14ChoiceNChoices, m_In14ChoiceChoices, 0 );
+ m_In14Choice->SetSelection( 0 );
+ m_In14Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In14Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In15Name = new wxTextCtrl( m_LayersListPanel, ID_IN15NAME, _("In15"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In15Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In15Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In15Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In15Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn15Sizer;
+ bIn15Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In15CheckBox = new wxCheckBox( m_In15Panel, ID_IN15CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In15CheckBox->Enable( false );
+
+ bIn15Sizer->Add( m_In15CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In15Panel->SetSizer( bIn15Sizer );
+ m_In15Panel->Layout();
+ bIn15Sizer->Fit( m_In15Panel );
+ m_LayerListFlexGridSizer->Add( m_In15Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In15ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In15ChoiceNChoices = sizeof( m_In15ChoiceChoices ) / sizeof( wxString );
+ m_In15Choice = new wxChoice( m_LayersListPanel, ID_IN15CHOICE, wxDefaultPosition, wxDefaultSize, m_In15ChoiceNChoices, m_In15ChoiceChoices, 0 );
+ m_In15Choice->SetSelection( 0 );
+ m_In15Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In15Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In16Name = new wxTextCtrl( m_LayersListPanel, ID_IN16NAME, _("In16"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In16Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In16Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In16Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In16Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn16Sizer;
+ bIn16Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In16CheckBox = new wxCheckBox( m_In16Panel, ID_IN16CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In16CheckBox->Enable( false );
+
+ bIn16Sizer->Add( m_In16CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In16Panel->SetSizer( bIn16Sizer );
+ m_In16Panel->Layout();
+ bIn16Sizer->Fit( m_In16Panel );
+ m_LayerListFlexGridSizer->Add( m_In16Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In16ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In16ChoiceNChoices = sizeof( m_In16ChoiceChoices ) / sizeof( wxString );
+ m_In16Choice = new wxChoice( m_LayersListPanel, ID_IN16CHOICE, wxDefaultPosition, wxDefaultSize, m_In16ChoiceNChoices, m_In16ChoiceChoices, 0 );
+ m_In16Choice->SetSelection( 0 );
+ m_In16Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In16Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In17Name = new wxTextCtrl( m_LayersListPanel, ID_IN17NAME, _("In17"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In17Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In17Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In17Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In17Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn17Sizer;
+ bIn17Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In17CheckBox = new wxCheckBox( m_In17Panel, ID_IN17CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In17CheckBox->Enable( false );
+
+ bIn17Sizer->Add( m_In17CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In17Panel->SetSizer( bIn17Sizer );
+ m_In17Panel->Layout();
+ bIn17Sizer->Fit( m_In17Panel );
+ m_LayerListFlexGridSizer->Add( m_In17Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In17ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In17ChoiceNChoices = sizeof( m_In17ChoiceChoices ) / sizeof( wxString );
+ m_In17Choice = new wxChoice( m_LayersListPanel, ID_IN17CHOICE, wxDefaultPosition, wxDefaultSize, m_In17ChoiceNChoices, m_In17ChoiceChoices, 0 );
+ m_In17Choice->SetSelection( 0 );
+ m_In17Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In17Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In18Name = new wxTextCtrl( m_LayersListPanel, ID_IN18NAME, _("In18"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In18Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In18Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In18Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In18Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn18Sizer;
+ bIn18Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In18CheckBox = new wxCheckBox( m_In18Panel, ID_IN18CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In18CheckBox->Enable( false );
+
+ bIn18Sizer->Add( m_In18CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In18Panel->SetSizer( bIn18Sizer );
+ m_In18Panel->Layout();
+ bIn18Sizer->Fit( m_In18Panel );
+ m_LayerListFlexGridSizer->Add( m_In18Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In18ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In18ChoiceNChoices = sizeof( m_In18ChoiceChoices ) / sizeof( wxString );
+ m_In18Choice = new wxChoice( m_LayersListPanel, ID_IN18CHOICE, wxDefaultPosition, wxDefaultSize, m_In18ChoiceNChoices, m_In18ChoiceChoices, 0 );
+ m_In18Choice->SetSelection( 0 );
+ m_In18Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In18Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In19Name = new wxTextCtrl( m_LayersListPanel, ID_IN19NAME, _("In19"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In19Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In19Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In19Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In19Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn19Sizer;
+ bIn19Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In19CheckBox = new wxCheckBox( m_In19Panel, ID_IN19CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In19CheckBox->Enable( false );
+
+ bIn19Sizer->Add( m_In19CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In19Panel->SetSizer( bIn19Sizer );
+ m_In19Panel->Layout();
+ bIn19Sizer->Fit( m_In19Panel );
+ m_LayerListFlexGridSizer->Add( m_In19Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In19ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In19ChoiceNChoices = sizeof( m_In19ChoiceChoices ) / sizeof( wxString );
+ m_In19Choice = new wxChoice( m_LayersListPanel, ID_IN19CHOICE, wxDefaultPosition, wxDefaultSize, m_In19ChoiceNChoices, m_In19ChoiceChoices, 0 );
+ m_In19Choice->SetSelection( 0 );
+ m_In19Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In19Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In20Name = new wxTextCtrl( m_LayersListPanel, ID_IN20NAME, _("In20"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In20Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In20Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In20Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In20Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn20Sizer;
+ bIn20Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In20CheckBox = new wxCheckBox( m_In20Panel, ID_IN20CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In20CheckBox->Enable( false );
+
+ bIn20Sizer->Add( m_In20CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In20Panel->SetSizer( bIn20Sizer );
+ m_In20Panel->Layout();
+ bIn20Sizer->Fit( m_In20Panel );
+ m_LayerListFlexGridSizer->Add( m_In20Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In20ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In20ChoiceNChoices = sizeof( m_In20ChoiceChoices ) / sizeof( wxString );
+ m_In20Choice = new wxChoice( m_LayersListPanel, ID_IN20CHOICE, wxDefaultPosition, wxDefaultSize, m_In20ChoiceNChoices, m_In20ChoiceChoices, 0 );
+ m_In20Choice->SetSelection( 0 );
+ m_In20Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In20Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In21Name = new wxTextCtrl( m_LayersListPanel, ID_IN21NAME, _("In21"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In21Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In21Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In21Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In21Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn21Sizer;
+ bIn21Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In21CheckBox = new wxCheckBox( m_In21Panel, ID_IN21CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In21CheckBox->Enable( false );
+
+ bIn21Sizer->Add( m_In21CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In21Panel->SetSizer( bIn21Sizer );
+ m_In21Panel->Layout();
+ bIn21Sizer->Fit( m_In21Panel );
+ m_LayerListFlexGridSizer->Add( m_In21Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In21ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In21ChoiceNChoices = sizeof( m_In21ChoiceChoices ) / sizeof( wxString );
+ m_In21Choice = new wxChoice( m_LayersListPanel, ID_IN21CHOICE, wxDefaultPosition, wxDefaultSize, m_In21ChoiceNChoices, m_In21ChoiceChoices, 0 );
+ m_In21Choice->SetSelection( 0 );
+ m_In21Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In21Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In22Name = new wxTextCtrl( m_LayersListPanel, ID_IN22NAME, _("In22"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In22Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In22Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In22Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In22Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn22Sizer;
+ bIn22Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In22CheckBox = new wxCheckBox( m_In22Panel, ID_IN22CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In22CheckBox->Enable( false );
+
+ bIn22Sizer->Add( m_In22CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In22Panel->SetSizer( bIn22Sizer );
+ m_In22Panel->Layout();
+ bIn22Sizer->Fit( m_In22Panel );
+ m_LayerListFlexGridSizer->Add( m_In22Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In22ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In22ChoiceNChoices = sizeof( m_In22ChoiceChoices ) / sizeof( wxString );
+ m_In22Choice = new wxChoice( m_LayersListPanel, ID_IN22CHOICE, wxDefaultPosition, wxDefaultSize, m_In22ChoiceNChoices, m_In22ChoiceChoices, 0 );
+ m_In22Choice->SetSelection( 0 );
+ m_In22Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In22Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In23Name = new wxTextCtrl( m_LayersListPanel, ID_IN23NAME, _("In23"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In23Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In23Name, 0, wxALL|wxEXPAND, 5 );
+
+ m_In23Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In23Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn23Sizer;
+ bIn23Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In23CheckBox = new wxCheckBox( m_In23Panel, ID_IN23CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In23CheckBox->Enable( false );
+
+ bIn23Sizer->Add( m_In23CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In23Panel->SetSizer( bIn23Sizer );
+ m_In23Panel->Layout();
+ bIn23Sizer->Fit( m_In23Panel );
+ m_LayerListFlexGridSizer->Add( m_In23Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In23ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In23ChoiceNChoices = sizeof( m_In23ChoiceChoices ) / sizeof( wxString );
+ m_In23Choice = new wxChoice( m_LayersListPanel, ID_IN22CHOICE, wxDefaultPosition, wxDefaultSize, m_In23ChoiceNChoices, m_In23ChoiceChoices, 0 );
+ m_In23Choice->SetSelection( 0 );
+ m_In23Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In23Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In24Name = new wxTextCtrl( m_LayersListPanel, ID_IN24NAME, _("In24"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In24Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In24Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In24Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In24Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn24Sizer;
+ bIn24Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In24CheckBox = new wxCheckBox( m_In24Panel, ID_IN24CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In24CheckBox->Enable( false );
+
+ bIn24Sizer->Add( m_In24CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In24Panel->SetSizer( bIn24Sizer );
+ m_In24Panel->Layout();
+ bIn24Sizer->Fit( m_In24Panel );
+ m_LayerListFlexGridSizer->Add( m_In24Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In24ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In24ChoiceNChoices = sizeof( m_In24ChoiceChoices ) / sizeof( wxString );
+ m_In24Choice = new wxChoice( m_LayersListPanel, ID_IN24CHOICE, wxDefaultPosition, wxDefaultSize, m_In24ChoiceNChoices, m_In24ChoiceChoices, 0 );
+ m_In24Choice->SetSelection( 0 );
+ m_In24Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In24Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In25Name = new wxTextCtrl( m_LayersListPanel, ID_IN25NAME, _("In25"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In25Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In25Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In25Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In25Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn25Sizer;
+ bIn25Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In25CheckBox = new wxCheckBox( m_In25Panel, ID_IN25CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In25CheckBox->Enable( false );
+
+ bIn25Sizer->Add( m_In25CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In25Panel->SetSizer( bIn25Sizer );
+ m_In25Panel->Layout();
+ bIn25Sizer->Fit( m_In25Panel );
+ m_LayerListFlexGridSizer->Add( m_In25Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In25ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In25ChoiceNChoices = sizeof( m_In25ChoiceChoices ) / sizeof( wxString );
+ m_In25Choice = new wxChoice( m_LayersListPanel, ID_IN25CHOICE, wxDefaultPosition, wxDefaultSize, m_In25ChoiceNChoices, m_In25ChoiceChoices, 0 );
+ m_In25Choice->SetSelection( 0 );
+ m_In25Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In25Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In26Name = new wxTextCtrl( m_LayersListPanel, ID_IN26NAME, _("In26"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In26Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In26Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In26Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In26Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn26Sizer;
+ bIn26Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In26CheckBox = new wxCheckBox( m_In26Panel, ID_IN26CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In26CheckBox->Enable( false );
+
+ bIn26Sizer->Add( m_In26CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In26Panel->SetSizer( bIn26Sizer );
+ m_In26Panel->Layout();
+ bIn26Sizer->Fit( m_In26Panel );
+ m_LayerListFlexGridSizer->Add( m_In26Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In26ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In26ChoiceNChoices = sizeof( m_In26ChoiceChoices ) / sizeof( wxString );
+ m_In26Choice = new wxChoice( m_LayersListPanel, ID_IN26CHOICE, wxDefaultPosition, wxDefaultSize, m_In26ChoiceNChoices, m_In26ChoiceChoices, 0 );
+ m_In26Choice->SetSelection( 0 );
+ m_In26Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In26Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In27Name = new wxTextCtrl( m_LayersListPanel, ID_IN27NAME, _("In27"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In27Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In27Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In27Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In27Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn27Sizer;
+ bIn27Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In27CheckBox = new wxCheckBox( m_In27Panel, ID_IN27CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In27CheckBox->Enable( false );
+
+ bIn27Sizer->Add( m_In27CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In27Panel->SetSizer( bIn27Sizer );
+ m_In27Panel->Layout();
+ bIn27Sizer->Fit( m_In27Panel );
+ m_LayerListFlexGridSizer->Add( m_In27Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In27ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In27ChoiceNChoices = sizeof( m_In27ChoiceChoices ) / sizeof( wxString );
+ m_In27Choice = new wxChoice( m_LayersListPanel, ID_IN27CHOICE, wxDefaultPosition, wxDefaultSize, m_In27ChoiceNChoices, m_In27ChoiceChoices, 0 );
+ m_In27Choice->SetSelection( 0 );
+ m_In27Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In27Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In28Name = new wxTextCtrl( m_LayersListPanel, ID_IN28NAME, _("In28"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In28Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In28Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In28Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In28Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn28Sizer;
+ bIn28Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In28CheckBox = new wxCheckBox( m_In28Panel, ID_IN28CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In28CheckBox->Enable( false );
+
+ bIn28Sizer->Add( m_In28CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In28Panel->SetSizer( bIn28Sizer );
+ m_In28Panel->Layout();
+ bIn28Sizer->Fit( m_In28Panel );
+ m_LayerListFlexGridSizer->Add( m_In28Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In28ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In28ChoiceNChoices = sizeof( m_In28ChoiceChoices ) / sizeof( wxString );
+ m_In28Choice = new wxChoice( m_LayersListPanel, ID_IN28CHOICE, wxDefaultPosition, wxDefaultSize, m_In28ChoiceNChoices, m_In28ChoiceChoices, 0 );
+ m_In28Choice->SetSelection( 0 );
+ m_In28Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In28Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In29Name = new wxTextCtrl( m_LayersListPanel, ID_IN29NAME, _("In29"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In29Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In29Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In29Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In29Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn29Sizer;
+ bIn29Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In29CheckBox = new wxCheckBox( m_In29Panel, ID_IN29CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In29CheckBox->Enable( false );
+
+ bIn29Sizer->Add( m_In29CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In29Panel->SetSizer( bIn29Sizer );
+ m_In29Panel->Layout();
+ bIn29Sizer->Fit( m_In29Panel );
+ m_LayerListFlexGridSizer->Add( m_In29Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In29ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In29ChoiceNChoices = sizeof( m_In29ChoiceChoices ) / sizeof( wxString );
+ m_In29Choice = new wxChoice( m_LayersListPanel, ID_IN29CHOICE, wxDefaultPosition, wxDefaultSize, m_In29ChoiceNChoices, m_In29ChoiceChoices, 0 );
+ m_In29Choice->SetSelection( 0 );
+ m_In29Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In29Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In30Name = new wxTextCtrl( m_LayersListPanel, ID_IN30NAME, _("In30"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_In30Name->SetMaxLength( 20 );
+ m_LayerListFlexGridSizer->Add( m_In30Name, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_In30Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_In30Panel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bIn30Sizer;
+ bIn30Sizer = new wxBoxSizer( wxVERTICAL );
+
+ m_In30CheckBox = new wxCheckBox( m_In30Panel, ID_IN30CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_In30CheckBox->Enable( false );
+
+ bIn30Sizer->Add( m_In30CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_In30Panel->SetSizer( bIn30Sizer );
+ m_In30Panel->Layout();
+ bIn30Sizer->Fit( m_In30Panel );
+ m_LayerListFlexGridSizer->Add( m_In30Panel, 1, wxEXPAND, 5 );
+
+ wxString m_In30ChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_In30ChoiceNChoices = sizeof( m_In30ChoiceChoices ) / sizeof( wxString );
+ m_In30Choice = new wxChoice( m_LayersListPanel, ID_IN30CHOICE, wxDefaultPosition, wxDefaultSize, m_In30ChoiceNChoices, m_In30ChoiceChoices, 0 );
+ m_In30Choice->SetSelection( 0 );
+ m_In30Choice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_In30Choice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_BackName = new wxTextCtrl( m_LayersListPanel, ID_BACKNAME, _("Back"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_BackName->SetMaxLength( 20 );
+ m_BackName->SetToolTip( _("Layer name of back (bottom) copper layer") );
+
+ m_LayerListFlexGridSizer->Add( m_BackName, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_BackPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_BackPanel->SetBackgroundColour( wxColour( 236, 253, 216 ) );
+
+ wxBoxSizer* bBackSizer;
+ bBackSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_BackCheckBox = new wxCheckBox( m_BackPanel, ID_BACKCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_BackCheckBox->Enable( false );
+ m_BackCheckBox->SetToolTip( _("If you want a back copper layer") );
+
+ bBackSizer->Add( m_BackCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_BackPanel->SetSizer( bBackSizer );
+ m_BackPanel->Layout();
+ bBackSizer->Fit( m_BackPanel );
+ m_LayerListFlexGridSizer->Add( m_BackPanel, 1, wxEXPAND, 5 );
+
+ wxString m_BackChoiceChoices[] = { _("signal"), _("power"), _("mixed"), _("jumper") };
+ int m_BackChoiceNChoices = sizeof( m_BackChoiceChoices ) / sizeof( wxString );
+ m_BackChoice = new wxChoice( m_LayersListPanel, ID_BACKCHOICE, wxDefaultPosition, wxDefaultSize, m_BackChoiceNChoices, m_BackChoiceChoices, 0 );
+ m_BackChoice->SetSelection( 0 );
+ m_BackChoice->SetToolTip( _("Copper layer type for Freerouter. Power layers are removed from Freerouter's layer menus.") );
+
+ m_LayerListFlexGridSizer->Add( m_BackChoice, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
+
+ m_MaskBackName = new wxStaticText( m_LayersListPanel, ID_MASKBACKNAME, _("Mask_Back_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MaskBackName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_MaskBackName, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_MaskBackPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_MaskBackPanel->SetBackgroundColour( wxColour( 255, 252, 235 ) );
+
+ wxBoxSizer* bSizer24;
+ bSizer24 = new wxBoxSizer( wxVERTICAL );
+
+ m_MaskBackCheckBox = new wxCheckBox( m_MaskBackPanel, ID_MASKBACKCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_MaskBackCheckBox->SetToolTip( _("If you want a solder mask layer for the back side of the board") );
+
+ bSizer24->Add( m_MaskBackCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_MaskBackPanel->SetSizer( bSizer24 );
+ m_MaskBackPanel->Layout();
+ bSizer24->Fit( m_MaskBackPanel );
+ m_LayerListFlexGridSizer->Add( m_MaskBackPanel, 1, wxEXPAND, 5 );
+
+ m_MaskBackStaticText = new wxStaticText( m_LayersListPanel, ID_MASKBACKCHOICE, _("On-board, non-copper"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MaskBackStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_MaskBackStaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_SilkSBackName = new wxStaticText( m_LayersListPanel, ID_SILKSBACKNAME, _("SilkS_Back_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SilkSBackName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_SilkSBackName, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_SilkSBackPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SilkSBackPanel->SetBackgroundColour( wxColour( 255, 252, 235 ) );
+
+ wxBoxSizer* bSizer25;
+ bSizer25 = new wxBoxSizer( wxVERTICAL );
+
+ m_SilkSBackCheckBox = new wxCheckBox( m_SilkSBackPanel, ID_SILKSBACKCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SilkSBackCheckBox->SetToolTip( _("If you want a silk screen layer for the back side of the board") );
+
+ bSizer25->Add( m_SilkSBackCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_SilkSBackPanel->SetSizer( bSizer25 );
+ m_SilkSBackPanel->Layout();
+ bSizer25->Fit( m_SilkSBackPanel );
+ m_LayerListFlexGridSizer->Add( m_SilkSBackPanel, 1, wxEXPAND, 5 );
+
+ m_SilkSBackStaticText = new wxStaticText( m_LayersListPanel, ID_SILKSBACKCHOICE, _("On-board, non-copper"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SilkSBackStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_SilkSBackStaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_SoldPBackName = new wxStaticText( m_LayersListPanel, ID_SOLDPBACKNAME, _("SoldP_Back_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SoldPBackName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_SoldPBackName, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_SoldPBackPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SoldPBackPanel->SetBackgroundColour( wxColour( 255, 253, 235 ) );
+
+ wxBoxSizer* bSizer26;
+ bSizer26 = new wxBoxSizer( wxVERTICAL );
+
+ m_SoldPBackCheckBox = new wxCheckBox( m_SoldPBackPanel, ID_SOLDPBACKCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SoldPBackCheckBox->SetToolTip( _("If you want a solder paste layer for the back side of the board") );
+
+ bSizer26->Add( m_SoldPBackCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_SoldPBackPanel->SetSizer( bSizer26 );
+ m_SoldPBackPanel->Layout();
+ bSizer26->Fit( m_SoldPBackPanel );
+ m_LayerListFlexGridSizer->Add( m_SoldPBackPanel, 1, wxEXPAND, 5 );
+
+ m_SoldPBackStaticText = new wxStaticText( m_LayersListPanel, ID_SOLDPBACKCHOICE, _("On-board, non-copper"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SoldPBackStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_SoldPBackStaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_AdhesBackName = new wxStaticText( m_LayersListPanel, ID_ADHESBACKNAME, _("Adhes_Back_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_AdhesBackName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_AdhesBackName, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_AdhesBackPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_AdhesBackPanel->SetBackgroundColour( wxColour( 236, 233, 236 ) );
+
+ wxBoxSizer* bSizer27;
+ bSizer27 = new wxBoxSizer( wxVERTICAL );
+
+ m_AdhesBackCheckBox = new wxCheckBox( m_AdhesBackPanel, ID_ADHESBACKCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_AdhesBackCheckBox->SetToolTip( _("If you want an adhesive layer for the back side of the board") );
+
+ bSizer27->Add( m_AdhesBackCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_AdhesBackPanel->SetSizer( bSizer27 );
+ m_AdhesBackPanel->Layout();
+ bSizer27->Fit( m_AdhesBackPanel );
+ m_LayerListFlexGridSizer->Add( m_AdhesBackPanel, 1, wxEXPAND, 5 );
+
+ m_AdhesBackStaticText = new wxStaticText( m_LayersListPanel, ID_ADHESBACKCHOICE, _("Off-board, manufacturing"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_AdhesBackStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_AdhesBackStaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_FabBackName = new wxStaticText( m_LayersListPanel, ID_FABBACKNAME, _("Fab_Back_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_FabBackName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_FabBackName, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_FabBackPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_FabBackPanel->SetBackgroundColour( wxColour( 236, 233, 236 ) );
+
+ wxBoxSizer* bSizer281;
+ bSizer281 = new wxBoxSizer( wxVERTICAL );
+
+ m_FabBackCheckBox = new wxCheckBox( m_FabBackPanel, ID_FABBACKCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_FabBackCheckBox->SetToolTip( _("If you want a fabrication layer for the back side of the board") );
+
+ bSizer281->Add( m_FabBackCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_FabBackPanel->SetSizer( bSizer281 );
+ m_FabBackPanel->Layout();
+ bSizer281->Fit( m_FabBackPanel );
+ m_LayerListFlexGridSizer->Add( m_FabBackPanel, 1, wxEXPAND, 5 );
+
+ m_FabBackStaticText = new wxStaticText( m_LayersListPanel, ID_FABBACKCHOICE, _("Off-board, manufacturing"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_FabBackStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_FabBackStaticText, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_CrtYdBackName = new wxStaticText( m_LayersListPanel, ID_CRTYDBACKNAME, _("CrtYd_Back_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_CrtYdBackName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_CrtYdBackName, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_CrtYdBackPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_CrtYdBackPanel->SetBackgroundColour( wxColour( 255, 233, 236 ) );
+
+ wxBoxSizer* bSizer6111;
+ bSizer6111 = new wxBoxSizer( wxVERTICAL );
+
+ m_CrtYdBackCheckBox = new wxCheckBox( m_CrtYdBackPanel, ID_CRTYDBACKCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_CrtYdBackCheckBox->SetToolTip( _("If you want a courtyard layer for the front side of the board") );
+
+ bSizer6111->Add( m_CrtYdBackCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_CrtYdBackPanel->SetSizer( bSizer6111 );
+ m_CrtYdBackPanel->Layout();
+ bSizer6111->Fit( m_CrtYdBackPanel );
+ m_LayerListFlexGridSizer->Add( m_CrtYdBackPanel, 1, wxEXPAND, 5 );
+
+ m_CrtYdBackStaticText = new wxStaticText( m_LayersListPanel, ID_CRTYDBACKCHOICE, _("Off-board, testing"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_CrtYdBackStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_CrtYdBackStaticText, 0, wxALL, 5 );
+
+ m_PCBEdgesName = new wxStaticText( m_LayersListPanel, ID_PCBEDGESNAME, _("PCB_Edges_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PCBEdgesName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_PCBEdgesName, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_PCBEdgesPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PCBEdgesPanel->SetBackgroundColour( wxColour( 255, 253, 216 ) );
+
+ wxBoxSizer* bSizer28;
+ bSizer28 = new wxBoxSizer( wxVERTICAL );
+
+ m_PCBEdgesCheckBox = new wxCheckBox( m_PCBEdgesPanel, ID_PCBEDGESCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PCBEdgesCheckBox->SetToolTip( _("If you want a board perimeter layer") );
+
+ bSizer28->Add( m_PCBEdgesCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_PCBEdgesPanel->SetSizer( bSizer28 );
+ m_PCBEdgesPanel->Layout();
+ bSizer28->Fit( m_PCBEdgesPanel );
+ m_LayerListFlexGridSizer->Add( m_PCBEdgesPanel, 1, wxEXPAND, 5 );
+
+ m_PCBEdgesStaticText = new wxStaticText( m_LayersListPanel, ID_PCBEDGESCHOICE, _("Board contour"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PCBEdgesStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_PCBEdgesStaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_MarginName = new wxStaticText( m_LayersListPanel, ID_MARGINNAME, _("Margin_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MarginName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_MarginName, 0, wxALL, 5 );
+
+ m_MarginPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_MarginPanel->SetBackgroundColour( wxColour( 236, 233, 255 ) );
+
+ wxBoxSizer* bSizer291;
+ bSizer291 = new wxBoxSizer( wxVERTICAL );
+
+ m_MarginCheckBox = new wxCheckBox( m_MarginPanel, ID_MARGINCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer291->Add( m_MarginCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_MarginPanel->SetSizer( bSizer291 );
+ m_MarginPanel->Layout();
+ bSizer291->Fit( m_MarginPanel );
+ m_LayerListFlexGridSizer->Add( m_MarginPanel, 1, wxEXPAND, 5 );
+
+ m_MarginStaticText = new wxStaticText( m_LayersListPanel, ID_ECO2CHOICE, _("Edge_Cuts setback"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MarginStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_MarginStaticText, 0, wxALL, 5 );
+
+ m_Eco1Name = new wxStaticText( m_LayersListPanel, ID_ECO2NAME, _("Eco1_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Eco1Name->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_Eco1Name, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_Eco1Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_Eco1Panel->SetBackgroundColour( wxColour( 236, 233, 255 ) );
+
+ wxBoxSizer* bSizer29;
+ bSizer29 = new wxBoxSizer( wxVERTICAL );
+
+ m_Eco1CheckBox = new wxCheckBox( m_Eco1Panel, ID_ECO2CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer29->Add( m_Eco1CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_Eco1Panel->SetSizer( bSizer29 );
+ m_Eco1Panel->Layout();
+ bSizer29->Fit( m_Eco1Panel );
+ m_LayerListFlexGridSizer->Add( m_Eco1Panel, 1, wxEXPAND, 5 );
+
+ m_Eco1StaticText = new wxStaticText( m_LayersListPanel, ID_ECO2CHOICE, _("Auxiliary"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Eco1StaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_Eco1StaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_Eco2Name = new wxStaticText( m_LayersListPanel, ID_ECO1NAME, _("Eco2_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Eco2Name->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_Eco2Name, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_Eco2Panel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_Eco2Panel->SetBackgroundColour( wxColour( 236, 233, 255 ) );
+
+ wxBoxSizer* bSizer30;
+ bSizer30 = new wxBoxSizer( wxVERTICAL );
+
+ m_Eco2CheckBox = new wxCheckBox( m_Eco2Panel, ID_ECO1CHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer30->Add( m_Eco2CheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_Eco2Panel->SetSizer( bSizer30 );
+ m_Eco2Panel->Layout();
+ bSizer30->Fit( m_Eco2Panel );
+ m_LayerListFlexGridSizer->Add( m_Eco2Panel, 1, wxEXPAND, 5 );
+
+ m_Eco2StaticText = new wxStaticText( m_LayersListPanel, ID_ECO1CHOICE, _("Auxiliary"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Eco2StaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_Eco2StaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_CommentsName = new wxStaticText( m_LayersListPanel, ID_COMMENTSNAME, _("Comments_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_CommentsName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_CommentsName, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_CommentsPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_CommentsPanel->SetBackgroundColour( wxColour( 236, 233, 255 ) );
+
+ wxBoxSizer* bSizer31;
+ bSizer31 = new wxBoxSizer( wxVERTICAL );
+
+ m_CommentsCheckBox = new wxCheckBox( m_CommentsPanel, ID_COMMENTSCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_CommentsCheckBox->SetToolTip( _("If you want a separate layer for comments or notes") );
+
+ bSizer31->Add( m_CommentsCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_CommentsPanel->SetSizer( bSizer31 );
+ m_CommentsPanel->Layout();
+ bSizer31->Fit( m_CommentsPanel );
+ m_LayerListFlexGridSizer->Add( m_CommentsPanel, 1, wxEXPAND, 5 );
+
+ m_CommentsStaticText = new wxStaticText( m_LayersListPanel, ID_COMMENTSCHOICE, _("Auxiliary"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_CommentsStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_CommentsStaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_DrawingsName = new wxStaticText( m_LayersListPanel, ID_DRAWINGSNAME, _("Drawings_later"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_DrawingsName->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_DrawingsName, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+ m_DrawingsPanel = new wxPanel( m_LayersListPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_DrawingsPanel->SetBackgroundColour( wxColour( 236, 233, 255 ) );
+
+ wxBoxSizer* bSizer32;
+ bSizer32 = new wxBoxSizer( wxVERTICAL );
+
+ m_DrawingsCheckBox = new wxCheckBox( m_DrawingsPanel, ID_DRAWINGSCHECKBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_DrawingsCheckBox->SetToolTip( _("If you want a layer for documentation drawings") );
+
+ bSizer32->Add( m_DrawingsCheckBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_DrawingsPanel->SetSizer( bSizer32 );
+ m_DrawingsPanel->Layout();
+ bSizer32->Fit( m_DrawingsPanel );
+ m_LayerListFlexGridSizer->Add( m_DrawingsPanel, 1, wxEXPAND, 5 );
+
+ m_DrawingsStaticText = new wxStaticText( m_LayersListPanel, ID_DRAWINGSCHOICE, _("Auxiliary"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_DrawingsStaticText->Wrap( -1 );
+ m_LayerListFlexGridSizer->Add( m_DrawingsStaticText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_LayersListPanel->SetSizer( m_LayerListFlexGridSizer );
+ m_LayersListPanel->Layout();
+ m_LayerListFlexGridSizer->Fit( m_LayersListPanel );
+ b_layersListSizer->Add( m_LayersListPanel, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bMainSizer->Add( b_layersListSizer, 1, wxEXPAND, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bMainSizer->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ // Connect Events
+ this->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_LAYERS_SETUP_BASE::OnSize ) );
+ m_PresetsChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnPresetsChoice ), NULL, this );
+ m_CopperLayersChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCopperLayersChoice ), NULL, this );
+ m_CrtYdFrontCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_FabFrontCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_AdhesFrontCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_SoldPFrontCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_SilkSFrontCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_MaskFrontCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_FrontCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In1CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In2CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In3CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In4CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In5CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In6CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In7CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In8CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In9CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In10CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In11CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In12CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In13CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In14CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In15CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In16CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In17CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In18CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In19CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In20CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In21CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In22CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In23CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In24CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In25CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In26CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In27CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In28CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In29CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In30CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_BackCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_MaskBackCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_SilkSBackCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_SoldPBackCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_AdhesBackCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_FabBackCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_CrtYdBackCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_PCBEdgesCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_MarginCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_Eco1CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_Eco2CheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_CommentsCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_DrawingsCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCancelButtonClick ), NULL, this );
+ m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnOkButtonClick ), NULL, this );
+}
+
+DIALOG_LAYERS_SETUP_BASE::~DIALOG_LAYERS_SETUP_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_LAYERS_SETUP_BASE::OnSize ) );
+ m_PresetsChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnPresetsChoice ), NULL, this );
+ m_CopperLayersChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCopperLayersChoice ), NULL, this );
+ m_CrtYdFrontCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_FabFrontCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_AdhesFrontCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_SoldPFrontCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_SilkSFrontCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_MaskFrontCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_FrontCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In1CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In2CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In3CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In4CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In5CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In6CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In7CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In8CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In9CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In10CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In11CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In12CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In13CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In14CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In15CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In16CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In17CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In18CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In19CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In20CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In21CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In22CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In23CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In24CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In25CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In26CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In27CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In28CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In29CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_In30CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_BackCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::DenyChangeCheckBox ), NULL, this );
+ m_MaskBackCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_SilkSBackCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_SoldPBackCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_AdhesBackCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_FabBackCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_CrtYdBackCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_PCBEdgesCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_MarginCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_Eco1CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_Eco2CheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_CommentsCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_DrawingsCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCheckBox ), NULL, this );
+ m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnCancelButtonClick ), NULL, this );
+ m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LAYERS_SETUP_BASE::OnOkButtonClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_layers_setup_base.fbp b/pcbnew/dialogs/dialog_layers_setup_base.fbp
new file mode 100644
index 0000000..3be3422
--- /dev/null
+++ b/pcbnew/dialogs/dialog_layers_setup_base.fbp
@@ -0,0 +1,18502 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_layers_setup_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_LAYERS_SETUP_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">550,600</property>
+ <property name="name">DIALOG_LAYERS_SETUP_BASE</property>
+ <property name="pos"></property>
+ <property name="size">550,1580</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Layer Setup</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize">OnSize</event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bChoicesSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bPresetsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Preset Layer Groupings</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextGrouping</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Custom&quot; &quot;Two layers, parts on Front only&quot; &quot;Two layers, parts on Back only&quot; &quot;Two layers, parts on Front and Back&quot; &quot;Four layers, parts on Front only&quot; &quot;Four layers, parts on Front and Back&quot; &quot;All layers on&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PresetsChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">OnPresetsChoice</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bCopperLayersSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Copper Layers</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextCopperLayers</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;2&quot; &quot;4&quot; &quot;6&quot; &quot;8&quot; &quot;10&quot; &quot;12&quot; &quot;14&quot; &quot;16&quot; &quot;18&quot; &quot;20&quot; &quot;22&quot; &quot;24&quot; &quot;26&quot; &quot;28&quot; &quot;30&quot; &quot;32&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CopperLayersChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">OnCopperLayersChoice</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bBrdThicknessSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Board Thickness</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextBrdThickness</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">0</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerBrdThickness</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlBrdThickness</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextBrdThicknessUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">b_layersListSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layers</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextLayers</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bCaptionsSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">wxSYS_COLOUR_ACTIVECAPTION</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg">wxSYS_COLOUR_CAPTIONTEXT</property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,15</property>
+ <property name="moveable">1</property>
+ <property name="name">m_TitlePanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxRAISED_BORDER|wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxScrolledWindow" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LayersListPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="scroll_rate_x">0</property>
+ <property name="scroll_rate_y">5</property>
+ <property name="show">1</property>
+ <property name="size">-1,-1</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxRAISED_BORDER|wxTAB_TRAVERSAL|wxVSCROLL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxHORIZONTAL</property>
+ <property name="growablecols">0</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_LayerListFlexGridSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">protected</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CRTYDFRONTNAME</property>
+ <property name="label">CrtYd_Front_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CrtYdFrontName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">; </property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">255,233,236</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,-1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_CrtYdFrontPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">-1,-1</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer611</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">15</property>
+ <property name="flag">wxRIGHT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="0">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CRTYDFRONTCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_CrtYdFrontCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">-1,-1</property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a courtyard layer for the front side of the board</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">15</property>
+ <property name="flag">wxRIGHT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="0">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CRTYDFRONTCHOICE</property>
+ <property name="label">Off-board, testing</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CrtYdFrontStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_FABFRONTNAME</property>
+ <property name="label">Fab_Front_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FabFrontName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">; </property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,233,236</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,-1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_FabFrontPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer61</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_FABFRONTCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FabFrontCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a fabrication layer for the front side of the board</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_FABFRONTCHOICE</property>
+ <property name="label">Off-board, manufacturing</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FabFrontStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADHESFRONTNAME</property>
+ <property name="label">Adhes_Front_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AdhesFrontName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">; </property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,233,236</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,-1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_AdhesFrontPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer6</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADHESFRONTCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AdhesFrontCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want an adhesive template for the front side of the board</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADHESFRONTCHOICE</property>
+ <property name="label">Off-board, manufacturing</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AdhesFrontStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SOLDPFRONTNAME</property>
+ <property name="label">SoldP_Front_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SoldPFrontName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">255,253,235</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SoldPFrontPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer7</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SOLDPFRONTCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SoldPFrontCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a solder paster layer for front side of the board</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SOLDPFRONTCHOICE</property>
+ <property name="label">On-board, non-copper</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SoldPFrontStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SILKSFRONTNAME</property>
+ <property name="label">SilkS_Front_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SilkSFrontName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">255,252,235</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SilkSFrontPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer5</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SILKSFRONTCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SilkSFrontCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a silk screen layer for the front side of the board</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SILKSFRONTCHOICE</property>
+ <property name="label">On-board, non-copper</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SilkSFrontStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_MASKFRONTNAME</property>
+ <property name="label">Mask_Front_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaskFrontName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">255,252,235</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaskFrontPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer8</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_MASKFRONTCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaskFrontCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a solder mask layer for the front of the board</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_MASKFRONTCHOICE</property>
+ <property name="label">On-board, non-copper</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaskFrontStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_FRONTNAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FrontName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Layer name of front (top) copper layer</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">Front_later</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FrontPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer9</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_FRONTCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FrontCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a front copper layer</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_FRONTCHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FrontChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN1NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In1Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In1</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In1Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn1Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN1CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In1CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN1CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In1Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN2NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In2Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In2</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In2Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn2Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN2CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In2CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN2CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In2Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN3NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In3Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In3</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In3Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn3Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN3CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In3CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN3CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In3Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN4NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In4Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In4</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In4Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn4Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN4CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In4CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN4CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In4Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN5NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In5Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In5</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In5Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn5Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN5CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In5CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN5CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In5Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN6NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In6Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In6</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In6Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn6Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN6CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In6CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN6CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In6Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN7NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In7Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In7</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In7Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn7Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN7CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In7CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN7CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In7Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN8NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In8Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In8</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In8Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn8Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN8CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In8CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN8CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In8Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN9NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In9Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In9</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In9Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn9Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN9CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In9CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN9CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In9Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN10NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In10Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In10</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In10Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn10Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN10CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In10CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN10CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In10Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN11NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In11Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In11</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In11Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn11Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN11CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In11CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN11CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In11Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN12NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In12Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In12</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In12Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn12Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN12CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In12CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN12CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In12Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN13NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In13Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In13</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In13Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn13Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN13CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In13CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN13CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In13Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN14NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In14Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In14</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In14Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn14Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN14CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In14CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN14CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In14Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN15NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In15Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In15</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In15Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn15Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN15CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In15CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN15CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In15Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN16NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In16Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In16</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In16Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn16Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN16CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In16CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN16CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In16Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN17NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In17Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In17</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In17Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn17Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN17CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In17CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN17CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In17Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN18NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In18Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In18</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In18Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn18Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN18CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In18CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN18CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In18Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN19NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In19Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In19</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In19Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn19Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN19CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In19CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN19CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In19Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN20NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In20Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In20</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In20Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn20Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN20CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In20CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN20CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In20Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN21NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In21Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In21</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In21Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn21Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN21CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In21CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN21CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In21Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN22NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In22Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In22</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In22Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn22Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN22CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In22CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN22CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In22Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN23NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In23Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In23</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In23Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn23Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN23CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In23CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN22CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In23Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN24NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In24Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In24</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In24Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn24Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN24CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In24CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN24CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In24Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN25NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In25Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In25</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In25Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn25Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN25CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In25CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN25CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In25Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN26NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In26Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In26</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In26Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn26Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN26CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In26CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN26CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In26Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN27NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In27Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In27</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In27Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn27Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN27CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In27CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN27CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In27Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN28NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In28Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In28</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In28Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn28Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN28CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In28CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN28CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In28Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN29NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In29Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In29</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In29Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn29Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN29CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In29CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN29CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In29Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN30NAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In30Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">In30</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In30Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bIn30Sizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN30CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In30CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_IN30CHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_In30Choice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_BACKNAME</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">20</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_BackName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Layer name of back (bottom) copper layer</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">Back</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_BackPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bBackSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_BACKCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_BackCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a back copper layer</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">DenyChangeCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;signal&quot; &quot;power&quot; &quot;mixed&quot; &quot;jumper&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_BACKCHOICE</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_BackChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Copper layer type for Freerouter. Power layers are removed from Freerouter&apos;s layer menus.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_MASKBACKNAME</property>
+ <property name="label">Mask_Back_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaskBackName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">255,252,235</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaskBackPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer24</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_MASKBACKCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaskBackCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a solder mask layer for the back side of the board</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_MASKBACKCHOICE</property>
+ <property name="label">On-board, non-copper</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaskBackStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SILKSBACKNAME</property>
+ <property name="label">SilkS_Back_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SilkSBackName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">255,252,235</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SilkSBackPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer25</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SILKSBACKCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SilkSBackCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a silk screen layer for the back side of the board</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SILKSBACKCHOICE</property>
+ <property name="label">On-board, non-copper</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SilkSBackStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SOLDPBACKNAME</property>
+ <property name="label">SoldP_Back_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SoldPBackName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">255,253,235</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SoldPBackPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer26</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SOLDPBACKCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SoldPBackCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a solder paste layer for the back side of the board</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_SOLDPBACKCHOICE</property>
+ <property name="label">On-board, non-copper</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SoldPBackStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADHESBACKNAME</property>
+ <property name="label">Adhes_Back_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AdhesBackName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,233,236</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AdhesBackPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer27</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADHESBACKCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AdhesBackCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want an adhesive layer for the back side of the board</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ADHESBACKCHOICE</property>
+ <property name="label">Off-board, manufacturing</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_AdhesBackStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_FABBACKNAME</property>
+ <property name="label">Fab_Back_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FabBackName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">; </property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,233,236</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FabBackPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer281</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_FABBACKCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FabBackCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a fabrication layer for the back side of the board</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_FABBACKCHOICE</property>
+ <property name="label">Off-board, manufacturing</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FabBackStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CRTYDBACKNAME</property>
+ <property name="label">CrtYd_Back_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CrtYdBackName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">; </property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">255,233,236</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,-1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_CrtYdBackPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer6111</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CRTYDBACKCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CrtYdBackCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a courtyard layer for the front side of the board</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CRTYDBACKCHOICE</property>
+ <property name="label">Off-board, testing</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CrtYdBackStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_PCBEDGESNAME</property>
+ <property name="label">PCB_Edges_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PCBEdgesName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">255,253,216</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PCBEdgesPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer28</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_PCBEDGESCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PCBEdgesCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a board perimeter layer</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_PCBEDGESCHOICE</property>
+ <property name="label">Board contour</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PCBEdgesStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_MARGINNAME</property>
+ <property name="label">Margin_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MarginName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,233,255</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MarginPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer291</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_MARGINCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MarginCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ECO2CHOICE</property>
+ <property name="label">Edge_Cuts setback</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MarginStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ECO2NAME</property>
+ <property name="label">Eco1_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Eco1Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,233,255</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Eco1Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer29</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ECO2CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Eco1CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ECO2CHOICE</property>
+ <property name="label">Auxiliary</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Eco1StaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ECO1NAME</property>
+ <property name="label">Eco2_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Eco2Name</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,233,255</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Eco2Panel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer30</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ECO1CHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Eco2CheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ECO1CHOICE</property>
+ <property name="label">Auxiliary</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Eco2StaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_COMMENTSNAME</property>
+ <property name="label">Comments_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CommentsName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,233,255</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CommentsPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer31</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_COMMENTSCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CommentsCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a separate layer for comments or notes</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_COMMENTSCHOICE</property>
+ <property name="label">Auxiliary</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_CommentsStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_DRAWINGSNAME</property>
+ <property name="label">Drawings_later</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DrawingsName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">236,233,255</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DrawingsPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer32</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_DRAWINGSCHECKBOX</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DrawingsCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">If you want a layer for documentation drawings</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckBox</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_DRAWINGSCHOICE</property>
+ <property name="label">Auxiliary</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DrawingsStaticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelButtonClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkButtonClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_layers_setup_base.h b/pcbnew/dialogs/dialog_layers_setup_base.h
new file mode 100644
index 0000000..a866567
--- /dev/null
+++ b/pcbnew/dialogs/dialog_layers_setup_base.h
@@ -0,0 +1,423 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_LAYERS_SETUP_BASE_H__
+#define __DIALOG_LAYERS_SETUP_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/choice.h>
+#include <wx/sizer.h>
+#include <wx/textctrl.h>
+#include <wx/panel.h>
+#include <wx/checkbox.h>
+#include <wx/scrolwin.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_CRTYDFRONTNAME 1000
+#define ID_CRTYDFRONTCHECKBOX 1001
+#define ID_CRTYDFRONTCHOICE 1002
+#define ID_FABFRONTNAME 1003
+#define ID_FABFRONTCHECKBOX 1004
+#define ID_FABFRONTCHOICE 1005
+#define ID_ADHESFRONTNAME 1006
+#define ID_ADHESFRONTCHECKBOX 1007
+#define ID_ADHESFRONTCHOICE 1008
+#define ID_SOLDPFRONTNAME 1009
+#define ID_SOLDPFRONTCHECKBOX 1010
+#define ID_SOLDPFRONTCHOICE 1011
+#define ID_SILKSFRONTNAME 1012
+#define ID_SILKSFRONTCHECKBOX 1013
+#define ID_SILKSFRONTCHOICE 1014
+#define ID_MASKFRONTNAME 1015
+#define ID_MASKFRONTCHECKBOX 1016
+#define ID_MASKFRONTCHOICE 1017
+#define ID_FRONTNAME 1018
+#define ID_FRONTCHECKBOX 1019
+#define ID_FRONTCHOICE 1020
+#define ID_IN1NAME 1021
+#define ID_IN1CHECKBOX 1022
+#define ID_IN1CHOICE 1023
+#define ID_IN2NAME 1024
+#define ID_IN2CHECKBOX 1025
+#define ID_IN2CHOICE 1026
+#define ID_IN3NAME 1027
+#define ID_IN3CHECKBOX 1028
+#define ID_IN3CHOICE 1029
+#define ID_IN4NAME 1030
+#define ID_IN4CHECKBOX 1031
+#define ID_IN4CHOICE 1032
+#define ID_IN5NAME 1033
+#define ID_IN5CHECKBOX 1034
+#define ID_IN5CHOICE 1035
+#define ID_IN6NAME 1036
+#define ID_IN6CHECKBOX 1037
+#define ID_IN6CHOICE 1038
+#define ID_IN7NAME 1039
+#define ID_IN7CHECKBOX 1040
+#define ID_IN7CHOICE 1041
+#define ID_IN8NAME 1042
+#define ID_IN8CHECKBOX 1043
+#define ID_IN8CHOICE 1044
+#define ID_IN9NAME 1045
+#define ID_IN9CHECKBOX 1046
+#define ID_IN9CHOICE 1047
+#define ID_IN10NAME 1048
+#define ID_IN10CHECKBOX 1049
+#define ID_IN10CHOICE 1050
+#define ID_IN11NAME 1051
+#define ID_IN11CHECKBOX 1052
+#define ID_IN11CHOICE 1053
+#define ID_IN12NAME 1054
+#define ID_IN12CHECKBOX 1055
+#define ID_IN12CHOICE 1056
+#define ID_IN13NAME 1057
+#define ID_IN13CHECKBOX 1058
+#define ID_IN13CHOICE 1059
+#define ID_IN14NAME 1060
+#define ID_IN14CHECKBOX 1061
+#define ID_IN14CHOICE 1062
+#define ID_IN15NAME 1063
+#define ID_IN15CHECKBOX 1064
+#define ID_IN15CHOICE 1065
+#define ID_IN16NAME 1066
+#define ID_IN16CHECKBOX 1067
+#define ID_IN16CHOICE 1068
+#define ID_IN17NAME 1069
+#define ID_IN17CHECKBOX 1070
+#define ID_IN17CHOICE 1071
+#define ID_IN18NAME 1072
+#define ID_IN18CHECKBOX 1073
+#define ID_IN18CHOICE 1074
+#define ID_IN19NAME 1075
+#define ID_IN19CHECKBOX 1076
+#define ID_IN19CHOICE 1077
+#define ID_IN20NAME 1078
+#define ID_IN20CHECKBOX 1079
+#define ID_IN20CHOICE 1080
+#define ID_IN21NAME 1081
+#define ID_IN21CHECKBOX 1082
+#define ID_IN21CHOICE 1083
+#define ID_IN22NAME 1084
+#define ID_IN22CHECKBOX 1085
+#define ID_IN22CHOICE 1086
+#define ID_IN23NAME 1087
+#define ID_IN23CHECKBOX 1088
+#define ID_IN24NAME 1089
+#define ID_IN24CHECKBOX 1090
+#define ID_IN24CHOICE 1091
+#define ID_IN25NAME 1092
+#define ID_IN25CHECKBOX 1093
+#define ID_IN25CHOICE 1094
+#define ID_IN26NAME 1095
+#define ID_IN26CHECKBOX 1096
+#define ID_IN26CHOICE 1097
+#define ID_IN27NAME 1098
+#define ID_IN27CHECKBOX 1099
+#define ID_IN27CHOICE 1100
+#define ID_IN28NAME 1101
+#define ID_IN28CHECKBOX 1102
+#define ID_IN28CHOICE 1103
+#define ID_IN29NAME 1104
+#define ID_IN29CHECKBOX 1105
+#define ID_IN29CHOICE 1106
+#define ID_IN30NAME 1107
+#define ID_IN30CHECKBOX 1108
+#define ID_IN30CHOICE 1109
+#define ID_BACKNAME 1110
+#define ID_BACKCHECKBOX 1111
+#define ID_BACKCHOICE 1112
+#define ID_MASKBACKNAME 1113
+#define ID_MASKBACKCHECKBOX 1114
+#define ID_MASKBACKCHOICE 1115
+#define ID_SILKSBACKNAME 1116
+#define ID_SILKSBACKCHECKBOX 1117
+#define ID_SILKSBACKCHOICE 1118
+#define ID_SOLDPBACKNAME 1119
+#define ID_SOLDPBACKCHECKBOX 1120
+#define ID_SOLDPBACKCHOICE 1121
+#define ID_ADHESBACKNAME 1122
+#define ID_ADHESBACKCHECKBOX 1123
+#define ID_ADHESBACKCHOICE 1124
+#define ID_FABBACKNAME 1125
+#define ID_FABBACKCHECKBOX 1126
+#define ID_FABBACKCHOICE 1127
+#define ID_CRTYDBACKNAME 1128
+#define ID_CRTYDBACKCHECKBOX 1129
+#define ID_CRTYDBACKCHOICE 1130
+#define ID_PCBEDGESNAME 1131
+#define ID_PCBEDGESCHECKBOX 1132
+#define ID_PCBEDGESCHOICE 1133
+#define ID_MARGINNAME 1134
+#define ID_MARGINCHECKBOX 1135
+#define ID_ECO2CHOICE 1136
+#define ID_ECO2NAME 1137
+#define ID_ECO2CHECKBOX 1138
+#define ID_ECO1NAME 1139
+#define ID_ECO1CHECKBOX 1140
+#define ID_ECO1CHOICE 1141
+#define ID_COMMENTSNAME 1142
+#define ID_COMMENTSCHECKBOX 1143
+#define ID_COMMENTSCHOICE 1144
+#define ID_DRAWINGSNAME 1145
+#define ID_DRAWINGSCHECKBOX 1146
+#define ID_DRAWINGSCHOICE 1147
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_LAYERS_SETUP_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_LAYERS_SETUP_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticTextGrouping;
+ wxChoice* m_PresetsChoice;
+ wxStaticText* m_staticTextCopperLayers;
+ wxChoice* m_CopperLayersChoice;
+ wxStaticText* m_staticTextBrdThickness;
+ wxTextCtrl* m_textCtrlBrdThickness;
+ wxStaticText* m_staticTextBrdThicknessUnit;
+ wxStaticText* m_staticTextLayers;
+ wxPanel* m_TitlePanel;
+ wxScrolledWindow* m_LayersListPanel;
+ wxFlexGridSizer* m_LayerListFlexGridSizer;
+ wxStaticText* m_CrtYdFrontName;
+ wxPanel* m_CrtYdFrontPanel;
+ wxCheckBox* m_CrtYdFrontCheckBox;
+ wxStaticText* m_CrtYdFrontStaticText;
+ wxStaticText* m_FabFrontName;
+ wxPanel* m_FabFrontPanel;
+ wxCheckBox* m_FabFrontCheckBox;
+ wxStaticText* m_FabFrontStaticText;
+ wxStaticText* m_AdhesFrontName;
+ wxPanel* m_AdhesFrontPanel;
+ wxCheckBox* m_AdhesFrontCheckBox;
+ wxStaticText* m_AdhesFrontStaticText;
+ wxStaticText* m_SoldPFrontName;
+ wxPanel* m_SoldPFrontPanel;
+ wxCheckBox* m_SoldPFrontCheckBox;
+ wxStaticText* m_SoldPFrontStaticText;
+ wxStaticText* m_SilkSFrontName;
+ wxPanel* m_SilkSFrontPanel;
+ wxCheckBox* m_SilkSFrontCheckBox;
+ wxStaticText* m_SilkSFrontStaticText;
+ wxStaticText* m_MaskFrontName;
+ wxPanel* m_MaskFrontPanel;
+ wxCheckBox* m_MaskFrontCheckBox;
+ wxStaticText* m_MaskFrontStaticText;
+ wxTextCtrl* m_FrontName;
+ wxPanel* m_FrontPanel;
+ wxCheckBox* m_FrontCheckBox;
+ wxChoice* m_FrontChoice;
+ wxTextCtrl* m_In1Name;
+ wxPanel* m_In1Panel;
+ wxCheckBox* m_In1CheckBox;
+ wxChoice* m_In1Choice;
+ wxTextCtrl* m_In2Name;
+ wxPanel* m_In2Panel;
+ wxCheckBox* m_In2CheckBox;
+ wxChoice* m_In2Choice;
+ wxTextCtrl* m_In3Name;
+ wxPanel* m_In3Panel;
+ wxCheckBox* m_In3CheckBox;
+ wxChoice* m_In3Choice;
+ wxTextCtrl* m_In4Name;
+ wxPanel* m_In4Panel;
+ wxCheckBox* m_In4CheckBox;
+ wxChoice* m_In4Choice;
+ wxTextCtrl* m_In5Name;
+ wxPanel* m_In5Panel;
+ wxCheckBox* m_In5CheckBox;
+ wxChoice* m_In5Choice;
+ wxTextCtrl* m_In6Name;
+ wxPanel* m_In6Panel;
+ wxCheckBox* m_In6CheckBox;
+ wxChoice* m_In6Choice;
+ wxTextCtrl* m_In7Name;
+ wxPanel* m_In7Panel;
+ wxCheckBox* m_In7CheckBox;
+ wxChoice* m_In7Choice;
+ wxTextCtrl* m_In8Name;
+ wxPanel* m_In8Panel;
+ wxCheckBox* m_In8CheckBox;
+ wxChoice* m_In8Choice;
+ wxTextCtrl* m_In9Name;
+ wxPanel* m_In9Panel;
+ wxCheckBox* m_In9CheckBox;
+ wxChoice* m_In9Choice;
+ wxTextCtrl* m_In10Name;
+ wxPanel* m_In10Panel;
+ wxCheckBox* m_In10CheckBox;
+ wxChoice* m_In10Choice;
+ wxTextCtrl* m_In11Name;
+ wxPanel* m_In11Panel;
+ wxCheckBox* m_In11CheckBox;
+ wxChoice* m_In11Choice;
+ wxTextCtrl* m_In12Name;
+ wxPanel* m_In12Panel;
+ wxCheckBox* m_In12CheckBox;
+ wxChoice* m_In12Choice;
+ wxTextCtrl* m_In13Name;
+ wxPanel* m_In13Panel;
+ wxCheckBox* m_In13CheckBox;
+ wxChoice* m_In13Choice;
+ wxTextCtrl* m_In14Name;
+ wxPanel* m_In14Panel;
+ wxCheckBox* m_In14CheckBox;
+ wxChoice* m_In14Choice;
+ wxTextCtrl* m_In15Name;
+ wxPanel* m_In15Panel;
+ wxCheckBox* m_In15CheckBox;
+ wxChoice* m_In15Choice;
+ wxTextCtrl* m_In16Name;
+ wxPanel* m_In16Panel;
+ wxCheckBox* m_In16CheckBox;
+ wxChoice* m_In16Choice;
+ wxTextCtrl* m_In17Name;
+ wxPanel* m_In17Panel;
+ wxCheckBox* m_In17CheckBox;
+ wxChoice* m_In17Choice;
+ wxTextCtrl* m_In18Name;
+ wxPanel* m_In18Panel;
+ wxCheckBox* m_In18CheckBox;
+ wxChoice* m_In18Choice;
+ wxTextCtrl* m_In19Name;
+ wxPanel* m_In19Panel;
+ wxCheckBox* m_In19CheckBox;
+ wxChoice* m_In19Choice;
+ wxTextCtrl* m_In20Name;
+ wxPanel* m_In20Panel;
+ wxCheckBox* m_In20CheckBox;
+ wxChoice* m_In20Choice;
+ wxTextCtrl* m_In21Name;
+ wxPanel* m_In21Panel;
+ wxCheckBox* m_In21CheckBox;
+ wxChoice* m_In21Choice;
+ wxTextCtrl* m_In22Name;
+ wxPanel* m_In22Panel;
+ wxCheckBox* m_In22CheckBox;
+ wxChoice* m_In22Choice;
+ wxTextCtrl* m_In23Name;
+ wxPanel* m_In23Panel;
+ wxCheckBox* m_In23CheckBox;
+ wxChoice* m_In23Choice;
+ wxTextCtrl* m_In24Name;
+ wxPanel* m_In24Panel;
+ wxCheckBox* m_In24CheckBox;
+ wxChoice* m_In24Choice;
+ wxTextCtrl* m_In25Name;
+ wxPanel* m_In25Panel;
+ wxCheckBox* m_In25CheckBox;
+ wxChoice* m_In25Choice;
+ wxTextCtrl* m_In26Name;
+ wxPanel* m_In26Panel;
+ wxCheckBox* m_In26CheckBox;
+ wxChoice* m_In26Choice;
+ wxTextCtrl* m_In27Name;
+ wxPanel* m_In27Panel;
+ wxCheckBox* m_In27CheckBox;
+ wxChoice* m_In27Choice;
+ wxTextCtrl* m_In28Name;
+ wxPanel* m_In28Panel;
+ wxCheckBox* m_In28CheckBox;
+ wxChoice* m_In28Choice;
+ wxTextCtrl* m_In29Name;
+ wxPanel* m_In29Panel;
+ wxCheckBox* m_In29CheckBox;
+ wxChoice* m_In29Choice;
+ wxTextCtrl* m_In30Name;
+ wxPanel* m_In30Panel;
+ wxCheckBox* m_In30CheckBox;
+ wxChoice* m_In30Choice;
+ wxTextCtrl* m_BackName;
+ wxPanel* m_BackPanel;
+ wxCheckBox* m_BackCheckBox;
+ wxChoice* m_BackChoice;
+ wxStaticText* m_MaskBackName;
+ wxPanel* m_MaskBackPanel;
+ wxCheckBox* m_MaskBackCheckBox;
+ wxStaticText* m_MaskBackStaticText;
+ wxStaticText* m_SilkSBackName;
+ wxPanel* m_SilkSBackPanel;
+ wxCheckBox* m_SilkSBackCheckBox;
+ wxStaticText* m_SilkSBackStaticText;
+ wxStaticText* m_SoldPBackName;
+ wxPanel* m_SoldPBackPanel;
+ wxCheckBox* m_SoldPBackCheckBox;
+ wxStaticText* m_SoldPBackStaticText;
+ wxStaticText* m_AdhesBackName;
+ wxPanel* m_AdhesBackPanel;
+ wxCheckBox* m_AdhesBackCheckBox;
+ wxStaticText* m_AdhesBackStaticText;
+ wxStaticText* m_FabBackName;
+ wxPanel* m_FabBackPanel;
+ wxCheckBox* m_FabBackCheckBox;
+ wxStaticText* m_FabBackStaticText;
+ wxStaticText* m_CrtYdBackName;
+ wxPanel* m_CrtYdBackPanel;
+ wxCheckBox* m_CrtYdBackCheckBox;
+ wxStaticText* m_CrtYdBackStaticText;
+ wxStaticText* m_PCBEdgesName;
+ wxPanel* m_PCBEdgesPanel;
+ wxCheckBox* m_PCBEdgesCheckBox;
+ wxStaticText* m_PCBEdgesStaticText;
+ wxStaticText* m_MarginName;
+ wxPanel* m_MarginPanel;
+ wxCheckBox* m_MarginCheckBox;
+ wxStaticText* m_MarginStaticText;
+ wxStaticText* m_Eco1Name;
+ wxPanel* m_Eco1Panel;
+ wxCheckBox* m_Eco1CheckBox;
+ wxStaticText* m_Eco1StaticText;
+ wxStaticText* m_Eco2Name;
+ wxPanel* m_Eco2Panel;
+ wxCheckBox* m_Eco2CheckBox;
+ wxStaticText* m_Eco2StaticText;
+ wxStaticText* m_CommentsName;
+ wxPanel* m_CommentsPanel;
+ wxCheckBox* m_CommentsCheckBox;
+ wxStaticText* m_CommentsStaticText;
+ wxStaticText* m_DrawingsName;
+ wxPanel* m_DrawingsPanel;
+ wxCheckBox* m_DrawingsCheckBox;
+ wxStaticText* m_DrawingsStaticText;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnSize( wxSizeEvent& event ) { event.Skip(); }
+ virtual void OnPresetsChoice( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCopperLayersChoice( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCheckBox( wxCommandEvent& event ) { event.Skip(); }
+ virtual void DenyChangeCheckBox( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkButtonClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_LAYERS_SETUP_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Layer Setup"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 550,1580 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_LAYERS_SETUP_BASE();
+
+};
+
+#endif //__DIALOG_LAYERS_SETUP_BASE_H__
diff --git a/pcbnew/dialogs/dialog_mask_clearance.cpp b/pcbnew/dialogs/dialog_mask_clearance.cpp
new file mode 100644
index 0000000..913ba2e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_mask_clearance.cpp
@@ -0,0 +1,118 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+/**
+ * @file dialog_mask_clearance.cpp
+ */
+
+#include <fctsys.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <class_board_design_settings.h>
+#include <base_units.h>
+
+#include <class_board.h>
+
+#include <dialog_mask_clearance.h>
+
+/**
+ * Class DIALOG_PADS_MASK_CLEARANCE
+ * is derived from DIALOG_PADS_MASK_CLEARANCE_BASE.
+ * @see dialog_dialog_mask_clearance_base.h and dialog_mask_clearance_base.cpp,
+ * which are maintained by wxFormBuilder
+ */
+DIALOG_PADS_MASK_CLEARANCE::DIALOG_PADS_MASK_CLEARANCE( PCB_EDIT_FRAME* aParent ) :
+ DIALOG_PADS_MASK_CLEARANCE_BASE( aParent )
+{
+ m_parent = aParent;
+ m_brdSettings = m_parent->GetBoard()->GetDesignSettings();
+
+ myInit();
+ m_sdbButtonsSizerOK->SetDefault();
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+
+void DIALOG_PADS_MASK_CLEARANCE::myInit()
+{
+ SetFocus();
+
+ m_SolderMaskMarginUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
+ m_solderMaskMinWidthUnit->SetLabel( GetUnitsLabel( g_UserUnit ) );
+ m_SolderPasteMarginUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
+
+ PutValueInLocalUnits( *m_SolderMaskMarginCtrl, m_brdSettings.m_SolderMaskMargin );
+ PutValueInLocalUnits( *m_SolderMaskMinWidthCtrl, m_brdSettings.m_SolderMaskMinWidth );
+
+ // These 2 parameters are usually < 0, so prepare entering a negative
+ // value, if current is 0
+ PutValueInLocalUnits( *m_SolderPasteMarginCtrl, m_brdSettings.m_SolderPasteMargin );
+
+ if( m_brdSettings.m_SolderPasteMargin == 0 )
+ m_SolderPasteMarginCtrl->SetValue( wxT( "-" ) +
+ m_SolderPasteMarginCtrl->GetValue() );
+
+ wxString msg;
+ msg.Printf( wxT( "%f" ), m_brdSettings.m_SolderPasteMarginRatio * 100.0 );
+
+ // Sometimes Printf adds a sign if the value is small
+ if( m_brdSettings.m_SolderPasteMarginRatio == 0.0 && msg[0] == '0' )
+ m_SolderPasteMarginRatioCtrl->SetValue( wxT( "-" ) + msg );
+ else
+ m_SolderPasteMarginRatioCtrl->SetValue( msg );
+}
+
+
+void DIALOG_PADS_MASK_CLEARANCE::OnButtonOkClick( wxCommandEvent& event )
+{
+ m_brdSettings.m_SolderMaskMargin = ValueFromTextCtrl( *m_SolderMaskMarginCtrl );
+ m_brdSettings.m_SolderMaskMinWidth = ValueFromTextCtrl( *m_SolderMaskMinWidthCtrl );
+
+ m_brdSettings.m_SolderPasteMargin = ValueFromTextCtrl( *m_SolderPasteMarginCtrl );
+
+ double dtmp = 0;
+ wxString msg = m_SolderPasteMarginRatioCtrl->GetValue();
+
+ msg.ToDouble( &dtmp );
+
+ // A margin ratio de -50% means no paste on a pad, the ratio must be >= 50 %
+ if( dtmp < -50 )
+ dtmp = -50;
+
+ if( dtmp > +100 )
+ dtmp = +100;
+
+ m_brdSettings.m_SolderPasteMarginRatio = dtmp / 100;
+
+ m_parent->OnModify();
+
+ m_parent->GetBoard()->SetDesignSettings( m_brdSettings );
+
+ EndModal( 1 );
+}
+
+
+void DIALOG_PADS_MASK_CLEARANCE::OnButtonCancelClick( wxCommandEvent& event )
+{
+ EndModal( 0 );
+}
diff --git a/pcbnew/dialogs/dialog_mask_clearance.h b/pcbnew/dialogs/dialog_mask_clearance.h
new file mode 100644
index 0000000..764ea1a
--- /dev/null
+++ b/pcbnew/dialogs/dialog_mask_clearance.h
@@ -0,0 +1,50 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _DIALOG_MASK_CLEARANCE_H_
+#define _DIALOG_MASK_CLEARANCE_H_
+
+#include <dialog_mask_clearance_base.h>
+
+/**
+ * DIALOG_PADS_MASK_CLEARANCE, derived from DIALOG_PADS_MASK_CLEARANCE_BASE
+ * @see dialog_mask_clearance.h and dialog_mask_clearance.cpp,
+ * automatically created by wxFormBuilder
+ */
+class DIALOG_PADS_MASK_CLEARANCE : public DIALOG_PADS_MASK_CLEARANCE_BASE
+{
+private:
+ PCB_EDIT_FRAME* m_parent;
+ BOARD_DESIGN_SETTINGS m_brdSettings;
+
+public:
+ DIALOG_PADS_MASK_CLEARANCE( PCB_EDIT_FRAME* parent );
+ ~DIALOG_PADS_MASK_CLEARANCE() {};
+private:
+ void myInit();
+ virtual void OnButtonOkClick( wxCommandEvent& event );
+ virtual void OnButtonCancelClick( wxCommandEvent& event );
+};
+
+#endif // _DIALOG_MASK_CLEARANCE_H_
diff --git a/pcbnew/dialogs/dialog_mask_clearance_base.cpp b/pcbnew/dialogs/dialog_mask_clearance_base.cpp
new file mode 100644
index 0000000..16699cb
--- /dev/null
+++ b/pcbnew/dialogs/dialog_mask_clearance_base.cpp
@@ -0,0 +1,130 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_mask_clearance_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+BEGIN_EVENT_TABLE( DIALOG_PADS_MASK_CLEARANCE_BASE, DIALOG_SHIM )
+ EVT_BUTTON( wxID_CANCEL, DIALOG_PADS_MASK_CLEARANCE_BASE::_wxFB_OnButtonCancelClick )
+ EVT_BUTTON( wxID_OK, DIALOG_PADS_MASK_CLEARANCE_BASE::_wxFB_OnButtonOkClick )
+END_EVENT_TABLE()
+
+DIALOG_PADS_MASK_CLEARANCE_BASE::DIALOG_PADS_MASK_CLEARANCE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bMainUpperSizer;
+ bMainUpperSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextInfo = new wxStaticText( this, wxID_ANY, _("Note: For clearance values:\n- a positive value means a mask bigger than a pad\n- a negative value means a mask smaller than a pad\n"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextInfo->Wrap( -1 );
+ bMainUpperSizer->Add( m_staticTextInfo, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainUpperSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ wxFlexGridSizer* fgGridSolderMaskSizer;
+ fgGridSolderMaskSizer = new wxFlexGridSizer( 0, 3, 0, 0 );
+ fgGridSolderMaskSizer->AddGrowableCol( 1 );
+ fgGridSolderMaskSizer->SetFlexibleDirection( wxBOTH );
+ fgGridSolderMaskSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_MaskClearanceTitle = new wxStaticText( this, wxID_ANY, _("Solder mask clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MaskClearanceTitle->Wrap( -1 );
+ m_MaskClearanceTitle->SetToolTip( _("This is the global clearance between pads and the solder mask\nThis value can be superseded by local values for a footprint or a pad.") );
+
+ fgGridSolderMaskSizer->Add( m_MaskClearanceTitle, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ m_SolderMaskMarginCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMarginCtrl->SetMaxLength( 0 );
+ fgGridSolderMaskSizer->Add( m_SolderMaskMarginCtrl, 0, wxEXPAND|wxALL, 5 );
+
+ m_SolderMaskMarginUnits = new wxStaticText( this, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMarginUnits->Wrap( -1 );
+ fgGridSolderMaskSizer->Add( m_SolderMaskMarginUnits, 0, wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_staticTextMinWidth = new wxStaticText( this, wxID_ANY, _("Solder mask min width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextMinWidth->Wrap( -1 );
+ m_staticTextMinWidth->SetToolTip( _("Min dist between 2 pad areas.\nTwo pad areas nearer than this value will be merged during plotting.\nThis parameter is used only to plot solder mask layers.") );
+
+ fgGridSolderMaskSizer->Add( m_staticTextMinWidth, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ m_SolderMaskMinWidthCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMinWidthCtrl->SetMaxLength( 0 );
+ fgGridSolderMaskSizer->Add( m_SolderMaskMinWidthCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_solderMaskMinWidthUnit = new wxStaticText( this, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_solderMaskMinWidthUnit->Wrap( -1 );
+ fgGridSolderMaskSizer->Add( m_solderMaskMinWidthUnit, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
+
+ m_staticline3 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ fgGridSolderMaskSizer->Add( m_staticline3, 0, wxEXPAND | wxALL, 5 );
+
+ m_staticline4 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ fgGridSolderMaskSizer->Add( m_staticline4, 0, wxEXPAND | wxALL, 5 );
+
+ m_staticline5 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ fgGridSolderMaskSizer->Add( m_staticline5, 0, wxEXPAND | wxALL, 5 );
+
+ m_staticTextSolderPaste = new wxStaticText( this, wxID_ANY, _("Solder paste clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSolderPaste->Wrap( -1 );
+ m_staticTextSolderPaste->SetToolTip( _("This is the global clearance between pads and the solder paste\nThis value can be superseded by local values for a footprint or a pad.\nThe final clearance value is the sum of this value and the clearance value ratio") );
+
+ fgGridSolderMaskSizer->Add( m_staticTextSolderPaste, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ m_SolderPasteMarginCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginCtrl->SetMaxLength( 0 );
+ fgGridSolderMaskSizer->Add( m_SolderPasteMarginCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_SolderPasteMarginUnits = new wxStaticText( this, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginUnits->Wrap( -1 );
+ fgGridSolderMaskSizer->Add( m_SolderPasteMarginUnits, 0, wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_staticTextRatio = new wxStaticText( this, wxID_ANY, _("Solder paste ratio clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextRatio->Wrap( -1 );
+ m_staticTextRatio->SetToolTip( _("This is the global clearance ratio in per cent between pads and the solder paste\nA value of 10 means the clearance value is 10 per cent of the pad size\nThis value can be superseded by local values for a footprint or a pad.\nThe final clearance value is the sum of this value and the clearance value") );
+
+ fgGridSolderMaskSizer->Add( m_staticTextRatio, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ m_SolderPasteMarginRatioCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginRatioCtrl->SetMaxLength( 0 );
+ fgGridSolderMaskSizer->Add( m_SolderPasteMarginRatioCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_SolderPasteRatioMarginUnits = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteRatioMarginUnits->Wrap( -1 );
+ fgGridSolderMaskSizer->Add( m_SolderPasteRatioMarginUnits, 0, wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bMainUpperSizer->Add( fgGridSolderMaskSizer, 1, wxEXPAND, 5 );
+
+ m_staticline11 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainUpperSizer->Add( m_staticline11, 0, wxEXPAND | wxALL, 5 );
+
+
+ bMainSizer->Add( bMainUpperSizer, 1, wxEXPAND, 5 );
+
+ m_sdbButtonsSizer = new wxStdDialogButtonSizer();
+ m_sdbButtonsSizerOK = new wxButton( this, wxID_OK );
+ m_sdbButtonsSizer->AddButton( m_sdbButtonsSizerOK );
+ m_sdbButtonsSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbButtonsSizer->AddButton( m_sdbButtonsSizerCancel );
+ m_sdbButtonsSizer->Realize();
+
+ bMainSizer->Add( m_sdbButtonsSizer, 0, wxALIGN_RIGHT|wxTOP|wxBOTTOM, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+}
+
+DIALOG_PADS_MASK_CLEARANCE_BASE::~DIALOG_PADS_MASK_CLEARANCE_BASE()
+{
+}
diff --git a/pcbnew/dialogs/dialog_mask_clearance_base.fbp b/pcbnew/dialogs/dialog_mask_clearance_base.fbp
new file mode 100644
index 0000000..bb99b7d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_mask_clearance_base.fbp
@@ -0,0 +1,1670 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">table</property>
+ <property name="file">dialog_mask_clearance_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DialogMaskClearanceOptions</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_PADS_MASK_CLEARANCE_BASE</property>
+ <property name="pos"></property>
+ <property name="size">361,304</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Pads Mask Clearance</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainUpperSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Note: For clearance values:&#x0A;- a positive value means a mask bigger than a pad&#x0A;- a negative value means a mask smaller than a pad&#x0A;</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextInfo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgGridSolderMaskSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder mask clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaskClearanceTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the global clearance between pads and the solder mask&#x0A;This value can be superseded by local values for a footprint or a pad.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderMaskMarginCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderMaskMarginUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder mask min width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextMinWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Min dist between 2 pad areas.&#x0A;Two pad areas nearer than this value will be merged during plotting.&#x0A;This parameter is used only to plot solder mask layers.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderMaskMinWidthCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_solderMaskMinWidthUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder paste clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSolderPaste</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the global clearance between pads and the solder paste&#x0A;This value can be superseded by local values for a footprint or a pad.&#x0A;The final clearance value is the sum of this value and the clearance value ratio</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteMarginCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteMarginUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder paste ratio clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextRatio</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the global clearance ratio in per cent between pads and the solder paste&#x0A;A value of 10 means the clearance value is 10 per cent of the pad size&#x0A;This value can be superseded by local values for a footprint or a pad.&#x0A;The final clearance value is the sum of this value and the clearance value</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteMarginRatioCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">%</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteRatioMarginUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline11</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbButtonsSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnButtonCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnButtonOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_mask_clearance_base.h b/pcbnew/dialogs/dialog_mask_clearance_base.h
new file mode 100644
index 0000000..d7ca21e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_mask_clearance_base.h
@@ -0,0 +1,79 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_MASK_CLEARANCE_BASE_H__
+#define __DIALOG_MASK_CLEARANCE_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/statline.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PADS_MASK_CLEARANCE_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PADS_MASK_CLEARANCE_BASE : public DIALOG_SHIM
+{
+ DECLARE_EVENT_TABLE()
+ private:
+
+ // Private event handlers
+ void _wxFB_OnButtonCancelClick( wxCommandEvent& event ){ OnButtonCancelClick( event ); }
+ void _wxFB_OnButtonOkClick( wxCommandEvent& event ){ OnButtonOkClick( event ); }
+
+
+ protected:
+ wxStaticText* m_staticTextInfo;
+ wxStaticLine* m_staticline1;
+ wxStaticText* m_MaskClearanceTitle;
+ wxTextCtrl* m_SolderMaskMarginCtrl;
+ wxStaticText* m_SolderMaskMarginUnits;
+ wxStaticText* m_staticTextMinWidth;
+ wxTextCtrl* m_SolderMaskMinWidthCtrl;
+ wxStaticText* m_solderMaskMinWidthUnit;
+ wxStaticLine* m_staticline3;
+ wxStaticLine* m_staticline4;
+ wxStaticLine* m_staticline5;
+ wxStaticText* m_staticTextSolderPaste;
+ wxTextCtrl* m_SolderPasteMarginCtrl;
+ wxStaticText* m_SolderPasteMarginUnits;
+ wxStaticText* m_staticTextRatio;
+ wxTextCtrl* m_SolderPasteMarginRatioCtrl;
+ wxStaticText* m_SolderPasteRatioMarginUnits;
+ wxStaticLine* m_staticline11;
+ wxStdDialogButtonSizer* m_sdbButtonsSizer;
+ wxButton* m_sdbButtonsSizerOK;
+ wxButton* m_sdbButtonsSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnButtonCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PADS_MASK_CLEARANCE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Pads Mask Clearance"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 361,304 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_PADS_MASK_CLEARANCE_BASE();
+
+};
+
+#endif //__DIALOG_MASK_CLEARANCE_BASE_H__
diff --git a/pcbnew/dialogs/dialog_modedit_options.cpp b/pcbnew/dialogs/dialog_modedit_options.cpp
new file mode 100644
index 0000000..aaeea3a
--- /dev/null
+++ b/pcbnew/dialogs/dialog_modedit_options.cpp
@@ -0,0 +1,140 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+/**
+ * @file dialog_modedit_options.cpp
+ */
+
+#include <fctsys.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <class_board_design_settings.h>
+#include <base_units.h>
+
+#include <module_editor_frame.h>
+
+#include <dialog_modedit_options_base.h>
+
+
+class DIALOG_MODEDIT_OPTIONS : public DIALOG_MODEDIT_OPTIONS_BASE
+{
+ BOARD_DESIGN_SETTINGS m_brdSettings;
+ FOOTPRINT_EDIT_FRAME * m_parent;
+
+public:
+ DIALOG_MODEDIT_OPTIONS( FOOTPRINT_EDIT_FRAME* aParent );
+
+private:
+ void OnCancelClick( wxCommandEvent& event ) { EndModal( wxID_CANCEL ); }
+ void OnOkClick( wxCommandEvent& event );
+
+ void initValues( );
+};
+
+
+DIALOG_MODEDIT_OPTIONS::DIALOG_MODEDIT_OPTIONS( FOOTPRINT_EDIT_FRAME* aParent ) :
+ DIALOG_MODEDIT_OPTIONS_BASE( aParent )
+{
+ m_parent = aParent;
+ m_brdSettings = m_parent->GetDesignSettings();
+ initValues();
+
+ m_sdbSizer1OK->SetDefault();
+ GetSizer()->SetSizeHints( this );
+
+ Centre();
+}
+
+
+bool InvokeFPEditorPrefsDlg( FOOTPRINT_EDIT_FRAME* aCaller )
+{
+ DIALOG_MODEDIT_OPTIONS dlg( aCaller );
+
+ int ret = dlg.ShowModal();
+
+ return ret == wxID_OK;
+}
+
+
+void DIALOG_MODEDIT_OPTIONS::initValues()
+{
+ EDA_UNITS_T units = g_UserUnit;
+
+ // Modules: graphic lines width:
+ m_staticTextGrLineUnit->SetLabel( GetAbbreviatedUnitsLabel( units ) );
+ PutValueInLocalUnits( *m_OptModuleGrLineWidth, m_brdSettings.m_ModuleSegmentWidth );
+
+ // Modules: Texts: Size & width:
+ m_staticTextTextWidthUnit->SetLabel( GetAbbreviatedUnitsLabel( units ) );
+ PutValueInLocalUnits( *m_OptModuleTextWidth, m_brdSettings.m_ModuleTextWidth );
+
+ m_staticTextTextVSizeUnit->SetLabel( GetAbbreviatedUnitsLabel( units ) );
+ PutValueInLocalUnits( *m_OptModuleTextVSize, m_brdSettings.m_ModuleTextSize.y );
+
+ m_staticTextTextHSizeUnit->SetLabel( GetAbbreviatedUnitsLabel( units ) );
+ PutValueInLocalUnits( *m_OptModuleTextHSize, m_brdSettings.m_ModuleTextSize.x );
+
+ // Ref: default values
+ m_textCtrlRefText->SetValue( m_brdSettings.m_RefDefaultText );
+ int sel = m_brdSettings.m_RefDefaultlayer == F_SilkS ? 0 : 1;
+ m_choiceLayerReference->SetSelection( sel );
+ sel = m_brdSettings.m_RefDefaultVisibility ? 0 : 1;
+ m_choiceVisibleReference->SetSelection( sel );
+
+ // Value: default values
+ m_textCtrlValueText->SetValue( m_brdSettings.m_ValueDefaultText );
+ sel = m_brdSettings.m_ValueDefaultlayer == F_SilkS ? 0 : 1;
+ m_choiceLayerValue->SetSelection( sel );
+ sel = m_brdSettings.m_ValueDefaultVisibility ? 0 : 1;
+ m_choiceVisibleValue->SetSelection( sel );
+
+ m_spinMaxUndoItems->SetValue( m_parent->GetScreen()->GetMaxUndoItems() );
+}
+
+
+void DIALOG_MODEDIT_OPTIONS::OnOkClick( wxCommandEvent& event )
+{
+ m_brdSettings.m_ModuleSegmentWidth = ValueFromTextCtrl( *m_OptModuleGrLineWidth );
+ m_brdSettings.m_ModuleTextWidth = ValueFromTextCtrl( *m_OptModuleTextWidth );
+ m_brdSettings.m_ModuleTextSize.y = ValueFromTextCtrl( *m_OptModuleTextVSize );
+ m_brdSettings.m_ModuleTextSize.x = ValueFromTextCtrl( *m_OptModuleTextHSize );
+
+ // Ref: default values
+ m_brdSettings.m_RefDefaultText = m_textCtrlRefText->GetValue();
+ int sel = m_choiceLayerReference->GetSelection();
+ m_brdSettings.m_RefDefaultlayer = sel == 1 ? F_Fab : F_SilkS;
+ sel = m_choiceVisibleReference->GetSelection();
+ m_brdSettings.m_RefDefaultVisibility = sel != 1;
+
+ // Value: default values
+ m_brdSettings.m_ValueDefaultText = m_textCtrlValueText->GetValue();
+ sel = m_choiceLayerValue->GetSelection();
+ m_brdSettings.m_ValueDefaultlayer = sel == 1 ? F_Fab : F_SilkS;
+ sel = m_choiceVisibleValue->GetSelection();
+ m_brdSettings.m_ValueDefaultVisibility = sel != 1;
+
+ m_parent->SetDesignSettings( m_brdSettings );
+
+ m_parent->GetScreen()->SetMaxUndoItems( m_spinMaxUndoItems->GetValue() );
+
+ EndModal( wxID_OK );
+}
diff --git a/pcbnew/dialogs/dialog_modedit_options_base.cpp b/pcbnew/dialogs/dialog_modedit_options_base.cpp
new file mode 100644
index 0000000..d83869a
--- /dev/null
+++ b/pcbnew/dialogs/dialog_modedit_options_base.cpp
@@ -0,0 +1,224 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_modedit_options_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_MODEDIT_OPTIONS_BASE::DIALOG_MODEDIT_OPTIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText281 = new wxStaticText( this, wxID_ANY, _("On new graphic item creation:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText281->Wrap( -1 );
+ m_staticText281->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizerUpper->Add( m_staticText281, 0, wxALL, 5 );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 0, 3, 0, 0 );
+ fgSizer1->AddGrowableCol( 1 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_EdgeModEWidthTitle = new wxStaticText( this, wxID_ANY, _("&Graphic line width"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_EdgeModEWidthTitle->Wrap( -1 );
+ fgSizer1->Add( m_EdgeModEWidthTitle, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_OptModuleGrLineWidth = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptModuleGrLineWidth->SetMaxLength( 0 );
+ fgSizer1->Add( m_OptModuleGrLineWidth, 0, wxEXPAND|wxALL, 5 );
+
+ m_staticTextGrLineUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextGrLineUnit->Wrap( -1 );
+ fgSizer1->Add( m_staticTextGrLineUnit, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_TextModWidthTitle = new wxStaticText( this, wxID_ANY, _("Text line width"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextModWidthTitle->Wrap( -1 );
+ fgSizer1->Add( m_TextModWidthTitle, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_OptModuleTextWidth = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptModuleTextWidth->SetMaxLength( 0 );
+ fgSizer1->Add( m_OptModuleTextWidth, 0, wxEXPAND|wxALL, 5 );
+
+ m_staticTextTextWidthUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextTextWidthUnit->Wrap( -1 );
+ fgSizer1->Add( m_staticTextTextWidthUnit, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_TextModSizeVTitle = new wxStaticText( this, wxID_ANY, _("Text &height"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextModSizeVTitle->Wrap( -1 );
+ fgSizer1->Add( m_TextModSizeVTitle, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_OptModuleTextVSize = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptModuleTextVSize->SetMaxLength( 0 );
+ fgSizer1->Add( m_OptModuleTextVSize, 0, wxEXPAND|wxALL, 5 );
+
+ m_staticTextTextVSizeUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextTextVSizeUnit->Wrap( -1 );
+ fgSizer1->Add( m_staticTextTextVSizeUnit, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_TextModSizeHTitle = new wxStaticText( this, wxID_ANY, _("Text &width"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextModSizeHTitle->Wrap( -1 );
+ fgSizer1->Add( m_TextModSizeHTitle, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_OptModuleTextHSize = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_OptModuleTextHSize->SetMaxLength( 0 );
+ fgSizer1->Add( m_OptModuleTextHSize, 0, wxEXPAND|wxALL, 5 );
+
+ m_staticTextTextHSizeUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextTextHSizeUnit->Wrap( -1 );
+ fgSizer1->Add( m_staticTextTextHSizeUnit, 0, wxALL, 5 );
+
+
+ bSizerUpper->Add( fgSizer1, 0, wxEXPAND|wxLEFT, 20 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerUpper->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_staticText28 = new wxStaticText( this, wxID_ANY, _("Default values on new footprint creation:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText28->Wrap( -1 );
+ m_staticText28->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizerUpper->Add( m_staticText28, 0, wxALL, 5 );
+
+ m_staticTextInfo = new wxStaticText( this, wxID_ANY, _("Leave reference or value blank to use the footprint name as default text"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextInfo->Wrap( -1 );
+ bSizerUpper->Add( m_staticTextInfo, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
+
+ wxFlexGridSizer* fgSizer2;
+ fgSizer2 = new wxFlexGridSizer( 0, 6, 0, 0 );
+ fgSizer2->AddGrowableCol( 1 );
+ fgSizer2->AddGrowableCol( 3 );
+ fgSizer2->AddGrowableCol( 5 );
+ fgSizer2->SetFlexibleDirection( wxBOTH );
+ fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticTextRef = new wxStaticText( this, wxID_ANY, _("&Reference"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextRef->Wrap( -1 );
+ fgSizer2->Add( m_staticTextRef, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ m_textCtrlRefText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textCtrlRefText->SetToolTip( _("Default text for reference\nLeave blank to use the footprint name") );
+
+ fgSizer2->Add( m_textCtrlRefText, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticTextRefLayer = new wxStaticText( this, wxID_ANY, _("Layer"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextRefLayer->Wrap( -1 );
+ fgSizer2->Add( m_staticTextRefLayer, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ wxString m_choiceLayerReferenceChoices[] = { _("SilkScreen"), _("Fab. Layer") };
+ int m_choiceLayerReferenceNChoices = sizeof( m_choiceLayerReferenceChoices ) / sizeof( wxString );
+ m_choiceLayerReference = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceLayerReferenceNChoices, m_choiceLayerReferenceChoices, 0 );
+ m_choiceLayerReference->SetSelection( 0 );
+ fgSizer2->Add( m_choiceLayerReference, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticText32 = new wxStaticText( this, wxID_ANY, _("Visibility"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText32->Wrap( -1 );
+ fgSizer2->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ wxString m_choiceVisibleReferenceChoices[] = { _("Visible"), _("Invisible") };
+ int m_choiceVisibleReferenceNChoices = sizeof( m_choiceVisibleReferenceChoices ) / sizeof( wxString );
+ m_choiceVisibleReference = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceVisibleReferenceNChoices, m_choiceVisibleReferenceChoices, 0 );
+ m_choiceVisibleReference->SetSelection( 0 );
+ fgSizer2->Add( m_choiceVisibleReference, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticTextValue = new wxStaticText( this, wxID_ANY, _("V&alue"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextValue->Wrap( -1 );
+ fgSizer2->Add( m_staticTextValue, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ m_textCtrlValueText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textCtrlValueText->SetToolTip( _("Default text for value\nLeave blank to use the footprint name") );
+
+ fgSizer2->Add( m_textCtrlValueText, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticTextValLayer = new wxStaticText( this, wxID_ANY, _("Layer"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextValLayer->Wrap( -1 );
+ fgSizer2->Add( m_staticTextValLayer, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ wxString m_choiceLayerValueChoices[] = { _("SilkScreen"), _("Fab. Layer") };
+ int m_choiceLayerValueNChoices = sizeof( m_choiceLayerValueChoices ) / sizeof( wxString );
+ m_choiceLayerValue = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceLayerValueNChoices, m_choiceLayerValueChoices, 0 );
+ m_choiceLayerValue->SetSelection( 1 );
+ fgSizer2->Add( m_choiceLayerValue, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticTextValVisibility = new wxStaticText( this, wxID_ANY, _("Visibility"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextValVisibility->Wrap( -1 );
+ fgSizer2->Add( m_staticTextValVisibility, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
+
+ wxString m_choiceVisibleValueChoices[] = { _("Visible"), _("Invisible") };
+ int m_choiceVisibleValueNChoices = sizeof( m_choiceVisibleValueChoices ) / sizeof( wxString );
+ m_choiceVisibleValue = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceVisibleValueNChoices, m_choiceVisibleValueChoices, 0 );
+ m_choiceVisibleValue->SetSelection( 0 );
+ fgSizer2->Add( m_choiceVisibleValue, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizerUpper->Add( fgSizer2, 0, wxEXPAND|wxLEFT, 20 );
+
+ m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerUpper->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 );
+
+ m_stGeneral = new wxStaticText( this, wxID_ANY, _("General options:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_stGeneral->Wrap( -1 );
+ m_stGeneral->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizerUpper->Add( m_stGeneral, 0, wxALL, 5 );
+
+ wxFlexGridSizer* fgGeneral;
+ fgGeneral = new wxFlexGridSizer( 0, 3, 0, 0 );
+ fgGeneral->AddGrowableCol( 1 );
+ fgGeneral->SetFlexibleDirection( wxBOTH );
+ fgGeneral->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_stMaxUndoItems = new wxStaticText( this, wxID_ANY, _("Ma&ximum undo items (0 = unlimited):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_stMaxUndoItems->Wrap( -1 );
+ fgGeneral->Add( m_stMaxUndoItems, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_spinMaxUndoItems = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 65536, 0 );
+ fgGeneral->Add( m_spinMaxUndoItems, 0, wxALL|wxEXPAND, 5 );
+
+ m_stMaxUndoItemsUnit = new wxStaticText( this, wxID_ANY, _("actions"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_stMaxUndoItemsUnit->Wrap( -1 );
+ fgGeneral->Add( m_stMaxUndoItemsUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizerUpper->Add( fgGeneral, 0, wxEXPAND|wxLEFT, 20 );
+
+
+ bSizerMain->Add( bSizerUpper, 1, wxALL|wxEXPAND, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bSizerMain->Add( m_sdbSizer1, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+ bSizerMain->Fit( this );
+
+ // Connect Events
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODEDIT_OPTIONS_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODEDIT_OPTIONS_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_MODEDIT_OPTIONS_BASE::~DIALOG_MODEDIT_OPTIONS_BASE()
+{
+ // Disconnect Events
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODEDIT_OPTIONS_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MODEDIT_OPTIONS_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_modedit_options_base.fbp b/pcbnew/dialogs/dialog_modedit_options_base.fbp
new file mode 100644
index 0000000..6ab0102
--- /dev/null
+++ b/pcbnew/dialogs/dialog_modedit_options_base.fbp
@@ -0,0 +1,2998 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_modedit_options_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_graphic_items_options</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_MODEDIT_OPTIONS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Footprint Editor Options</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">On new graphic item creation:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText281</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">20</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Graphic line width</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_EdgeModEWidthTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptModuleGrLineWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextGrLineUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Text line width</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextModWidthTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptModuleTextWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextTextWidthUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text &amp;height</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextModSizeVTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptModuleTextVSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextTextVSizeUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text &amp;width</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextModSizeHTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptModuleTextHSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextTextHSizeUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default values on new footprint creation:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText28</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_HORIZONTAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Leave reference or value blank to use the footprint name as default text</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextInfo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">20</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">6</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1,3,5</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer2</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Reference</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextRef</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlRefText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Default text for reference&#x0A;Leave blank to use the footprint name</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layer</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextRefLayer</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;SilkScreen&quot; &quot;Fab. Layer&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceLayerReference</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Visibility</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText32</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Visible&quot; &quot;Invisible&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceVisibleReference</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">V&amp;alue</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlValueText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Default text for value&#x0A;Leave blank to use the footprint name</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layer</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextValLayer</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;SilkScreen&quot; &quot;Fab. Layer&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceLayerValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Visibility</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextValVisibility</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Visible&quot; &quot;Invisible&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choiceVisibleValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">General options:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_stGeneral</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">20</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgGeneral</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Ma&amp;ximum undo items (0 = unlimited):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_stMaxUndoItems</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxSpinCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="initial">0</property>
+ <property name="max">65536</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spinMaxUndoItems</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSP_ARROW_KEYS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnSpinCtrl"></event>
+ <event name="OnSpinCtrlText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">actions</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_stMaxUndoItemsUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_modedit_options_base.h b/pcbnew/dialogs/dialog_modedit_options_base.h
new file mode 100644
index 0000000..9535da1
--- /dev/null
+++ b/pcbnew/dialogs/dialog_modedit_options_base.h
@@ -0,0 +1,91 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_MODEDIT_OPTIONS_BASE_H__
+#define __DIALOG_MODEDIT_OPTIONS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/choice.h>
+#include <wx/spinctrl.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_MODEDIT_OPTIONS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_MODEDIT_OPTIONS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText281;
+ wxStaticText* m_EdgeModEWidthTitle;
+ wxTextCtrl* m_OptModuleGrLineWidth;
+ wxStaticText* m_staticTextGrLineUnit;
+ wxStaticText* m_TextModWidthTitle;
+ wxTextCtrl* m_OptModuleTextWidth;
+ wxStaticText* m_staticTextTextWidthUnit;
+ wxStaticText* m_TextModSizeVTitle;
+ wxTextCtrl* m_OptModuleTextVSize;
+ wxStaticText* m_staticTextTextVSizeUnit;
+ wxStaticText* m_TextModSizeHTitle;
+ wxTextCtrl* m_OptModuleTextHSize;
+ wxStaticText* m_staticTextTextHSizeUnit;
+ wxStaticLine* m_staticline1;
+ wxStaticText* m_staticText28;
+ wxStaticText* m_staticTextInfo;
+ wxStaticText* m_staticTextRef;
+ wxTextCtrl* m_textCtrlRefText;
+ wxStaticText* m_staticTextRefLayer;
+ wxChoice* m_choiceLayerReference;
+ wxStaticText* m_staticText32;
+ wxChoice* m_choiceVisibleReference;
+ wxStaticText* m_staticTextValue;
+ wxTextCtrl* m_textCtrlValueText;
+ wxStaticText* m_staticTextValLayer;
+ wxChoice* m_choiceLayerValue;
+ wxStaticText* m_staticTextValVisibility;
+ wxChoice* m_choiceVisibleValue;
+ wxStaticLine* m_staticline2;
+ wxStaticText* m_stGeneral;
+ wxStaticText* m_stMaxUndoItems;
+ wxSpinCtrl* m_spinMaxUndoItems;
+ wxStaticText* m_stMaxUndoItemsUnit;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_MODEDIT_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Footprint Editor Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_MODEDIT_OPTIONS_BASE();
+
+};
+
+#endif //__DIALOG_MODEDIT_OPTIONS_BASE_H__
diff --git a/pcbnew/dialogs/dialog_move_exact.cpp b/pcbnew/dialogs/dialog_move_exact.cpp
new file mode 100644
index 0000000..e4c3ac4
--- /dev/null
+++ b/pcbnew/dialogs/dialog_move_exact.cpp
@@ -0,0 +1,201 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 John Beard, john.j.beard@gmail.com
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wxPcbStruct.h>
+#include <base_units.h>
+#include <macros.h>
+
+#include <module_editor_frame.h>
+
+#include "dialog_move_exact.h"
+
+// initialise statics
+DIALOG_MOVE_EXACT::MOVE_EXACT_OPTIONS DIALOG_MOVE_EXACT::m_options;
+
+
+DIALOG_MOVE_EXACT::DIALOG_MOVE_EXACT( PCB_BASE_FRAME* aParent,
+ wxPoint& translation, double& rotation ):
+ DIALOG_MOVE_EXACT_BASE( aParent ),
+ m_translation( translation ),
+ m_rotation( rotation )
+{
+ // set the unit labels
+ m_xUnit->SetLabelText( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_yUnit->SetLabelText( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+
+ // tabbing goes through the entries in sequence
+ m_yEntry->MoveAfterInTabOrder( m_xEntry );
+ m_rotEntry->MoveAfterInTabOrder( m_yEntry );
+
+ // and set up the entries according to the saved options
+ m_polarCoords->SetValue( m_options.polarCoords );
+ m_xEntry->SetValue( wxString::FromDouble( m_options.entry1 ) );
+ m_yEntry->SetValue( wxString::FromDouble( m_options.entry2 ) );
+ m_rotEntry->SetValue( wxString::FromDouble( m_options.entryRotation ) );
+ updateDlgTexts( m_polarCoords->IsChecked() );
+
+ m_stdButtonsOK->SetDefault();
+
+ GetSizer()->SetSizeHints( this );
+}
+
+
+DIALOG_MOVE_EXACT::~DIALOG_MOVE_EXACT()
+{
+}
+
+
+void DIALOG_MOVE_EXACT::ToPolarDeg( double x, double y, double& r, double& q )
+{
+ // convert to polar coordinates
+ r = hypot ( x, y );
+
+ q = ( r != 0) ? RAD2DEG( atan2( y, x ) ) : 0;
+}
+
+
+bool DIALOG_MOVE_EXACT::GetTranslationInIU ( wxPoint& val, bool polar )
+{
+ if( polar )
+ {
+ const int r = ValueFromTextCtrl( *m_xEntry );
+ const double q = DoubleValueFromString( DEGREES, m_yEntry->GetValue() );
+
+ val.x = r * cos( DEG2RAD( q / 10.0 ) );
+ val.y = r * sin( DEG2RAD( q / 10.0 ) );
+ }
+ else
+ {
+ // direct read
+ val.x = ValueFromTextCtrl( *m_xEntry );
+ val.y = ValueFromTextCtrl( *m_yEntry );
+ }
+
+ // no validation to do here, but in future, you could return false here
+ return true;
+}
+
+
+void DIALOG_MOVE_EXACT::OnPolarChanged( wxCommandEvent& event )
+{
+ bool newPolar = m_polarCoords->IsChecked();
+ updateDlgTexts( newPolar );
+ wxPoint val;
+
+ // get the value as previously stored
+ GetTranslationInIU( val, !newPolar );
+
+ if( newPolar )
+ {
+ // convert to polar coordinates
+ double r, q;
+ ToPolarDeg( val.x, val.y, r, q );
+
+ PutValueInLocalUnits( *m_xEntry, KiROUND( r / 10.0) * 10 );
+ m_yEntry->SetValue( wxString::FromDouble( q ) );
+ }
+ else
+ {
+ // vector is already in Cartesian, so just render out
+ // note - round off the last decimal place (10nm) to prevent
+ // (some) rounding causing errors when round-tripping
+ // you can never eliminate entirely, however
+ PutValueInLocalUnits( *m_xEntry, KiROUND( val.x / 10.0 ) * 10 );
+ PutValueInLocalUnits( *m_yEntry, KiROUND( val.y / 10.0 ) * 10 );
+ }
+ Layout();
+}
+
+
+void DIALOG_MOVE_EXACT::updateDlgTexts( bool aPolar )
+{
+ if( aPolar )
+ {
+ m_xLabel->SetLabelText( _( "Distance:" ) ); // Polar radius
+ m_yLabel->SetLabelText( _( "Angle:" ) ); // Polar theta or angle
+
+ m_yUnit->SetLabelText( GetAbbreviatedUnitsLabel( DEGREES ) );
+ }
+ else
+ {
+ m_xLabel->SetLabelText( _( "Move vector X:" ) );
+ m_yLabel->SetLabelText( _( "Move vector Y:" ) );
+
+ m_yUnit->SetLabelText( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ }
+}
+
+
+void DIALOG_MOVE_EXACT::OnClear( wxCommandEvent& event )
+{
+ wxObject* obj = event.GetEventObject();
+ wxTextCtrl* entry = NULL;
+
+ if( obj == m_clearX )
+ {
+ entry = m_xEntry;
+ }
+ else if( obj == m_clearY )
+ {
+ entry = m_yEntry;
+ }
+ else if( obj == m_clearRot )
+ {
+ entry = m_rotEntry;
+ }
+
+ if( entry )
+ entry->SetValue( "0" );
+}
+
+
+void DIALOG_MOVE_EXACT::OnOkClick( wxCommandEvent& event )
+{
+ m_rotation = DoubleValueFromString( DEGREES, m_rotEntry->GetValue() );
+
+ // for the output, we only deliver a Cartesian vector
+ bool ok = GetTranslationInIU( m_translation, m_polarCoords->IsChecked() );
+
+ if( ok )
+ {
+ // save the settings
+ m_options.polarCoords = m_polarCoords->GetValue();
+ m_xEntry->GetValue().ToDouble( &m_options.entry1 );
+ m_yEntry->GetValue().ToDouble( &m_options.entry2 );
+ m_rotEntry->GetValue().ToDouble( &m_options.entryRotation );
+
+ event.Skip();
+ }
+}
+
+
+void DIALOG_MOVE_EXACT::OnTextFocusLost( wxFocusEvent& event )
+{
+ wxTextCtrl* obj = static_cast<wxTextCtrl*>( event.GetEventObject() );
+
+ if( obj->GetValue().IsEmpty() )
+ obj->SetValue( "0" );
+
+ event.Skip();
+}
diff --git a/pcbnew/dialogs/dialog_move_exact.fbp b/pcbnew/dialogs/dialog_move_exact.fbp
new file mode 100644
index 0000000..f26f053
--- /dev/null
+++ b/pcbnew/dialogs/dialog_move_exact.fbp
@@ -0,0 +1,1347 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_move_exact_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_MOVE_EXACT_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_MOVE_EXACT_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Move Item</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnClose</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Use polar coordinates</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_polarCoords</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnPolarChanged</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">4</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer2</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">x:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_xLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">-1,-1</property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_xEntry</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus">OnTextFocusLost</event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mm</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_xUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Reset</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_clearX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_EXACTFIT</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnClear</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_yLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_yEntry</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus">OnTextFocusLost</event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">mm</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_yUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Reset</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_clearY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_EXACTFIT</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnClear</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Item rotation:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rotLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rotEntry</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus">OnTextFocusLost</event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">deg</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rotUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Reset</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_clearRot</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_EXACTFIT</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnClear</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="0">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_stdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_move_exact.h b/pcbnew/dialogs/dialog_move_exact.h
new file mode 100644
index 0000000..ffd5bc5
--- /dev/null
+++ b/pcbnew/dialogs/dialog_move_exact.h
@@ -0,0 +1,99 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 John Beard, john.j.beard@gmail.com
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __DIALOG_MOVE_EXACT__
+#define __DIALOG_MOVE_EXACT__
+
+// Include the wxFormBuider header base:
+#include <vector>
+#include <dialog_move_exact_base.h>
+
+class DIALOG_MOVE_EXACT : public DIALOG_MOVE_EXACT_BASE
+{
+private:
+
+ wxPoint& m_translation;
+ double& m_rotation;
+
+public:
+ // Constructor and destructor
+ DIALOG_MOVE_EXACT( PCB_BASE_FRAME* aParent, wxPoint& translation,
+ double& rotation );
+ ~DIALOG_MOVE_EXACT();
+
+private:
+
+ /*!
+ * Reset a text field to be 0 if it was exited while blank
+ */
+ void OnTextFocusLost( wxFocusEvent& event );
+
+ void OnPolarChanged( wxCommandEvent& event );
+ void OnClear( wxCommandEvent& event );
+
+ void OnOkClick( wxCommandEvent& event );
+
+ /**
+ * Convert a given Cartesian point into a polar representation.
+ *
+ * Linear units are not considered, the answer is in the same units as given
+ * Angle is returned in degrees
+ */
+ void ToPolarDeg( double x, double y, double& r, double& q );
+
+ /**
+ * Get the (Cartesian) translation described by the text entries
+ * @param val output translation vector
+ * @param polar interpret as polar coords
+ * @return false if error (though the text conversion functions don't report errors)
+ */
+ bool GetTranslationInIU ( wxPoint& val, bool polar );
+
+ // Update texts (comments) after changing the coordinates type (polar/cartesian)
+ void updateDlgTexts( bool aPolar );
+
+ /**
+ * Persistent dialog options
+ */
+ struct MOVE_EXACT_OPTIONS
+ {
+ bool polarCoords;
+ double entry1;
+ double entry2;
+ double entryRotation;
+
+ MOVE_EXACT_OPTIONS():
+ polarCoords(false),
+ entry1(0),
+ entry2(0),
+ entryRotation(0)
+ {
+ }
+ };
+
+ // persistent settings
+ static MOVE_EXACT_OPTIONS m_options;
+};
+
+#endif // __DIALOG_MOVE_EXACT__
diff --git a/pcbnew/dialogs/dialog_move_exact_base.cpp b/pcbnew/dialogs/dialog_move_exact_base.cpp
new file mode 100644
index 0000000..c7d237f
--- /dev/null
+++ b/pcbnew/dialogs/dialog_move_exact_base.cpp
@@ -0,0 +1,115 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_move_exact_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_MOVE_EXACT_BASE::DIALOG_MOVE_EXACT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_polarCoords = new wxCheckBox( this, wxID_ANY, _("Use polar coordinates"), wxDefaultPosition, wxDefaultSize, 0 );
+ bMainSizer->Add( m_polarCoords, 0, wxALL|wxEXPAND, 5 );
+
+ wxFlexGridSizer* fgSizer2;
+ fgSizer2 = new wxFlexGridSizer( 0, 4, 0, 0 );
+ fgSizer2->AddGrowableCol( 1 );
+ fgSizer2->SetFlexibleDirection( wxBOTH );
+ fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_xLabel = new wxStaticText( this, wxID_ANY, _("x:"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
+ m_xLabel->Wrap( -1 );
+ fgSizer2->Add( m_xLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_xEntry = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer2->Add( m_xEntry, 0, wxALL|wxEXPAND, 5 );
+
+ m_xUnit = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_xUnit->Wrap( -1 );
+ fgSizer2->Add( m_xUnit, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 5 );
+
+ m_clearX = new wxButton( this, wxID_ANY, _("Reset"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
+ fgSizer2->Add( m_clearX, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_yLabel = new wxStaticText( this, wxID_ANY, _("y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_yLabel->Wrap( -1 );
+ fgSizer2->Add( m_yLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_yEntry = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer2->Add( m_yEntry, 0, wxALL|wxEXPAND, 5 );
+
+ m_yUnit = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_yUnit->Wrap( -1 );
+ fgSizer2->Add( m_yUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_clearY = new wxButton( this, wxID_ANY, _("Reset"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
+ fgSizer2->Add( m_clearY, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_rotLabel = new wxStaticText( this, wxID_ANY, _("Item rotation:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_rotLabel->Wrap( -1 );
+ fgSizer2->Add( m_rotLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_rotEntry = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer2->Add( m_rotEntry, 0, wxALL|wxEXPAND, 5 );
+
+ m_rotUnit = new wxStaticText( this, wxID_ANY, _("deg"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_rotUnit->Wrap( -1 );
+ fgSizer2->Add( m_rotUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_clearRot = new wxButton( this, wxID_ANY, _("Reset"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
+ fgSizer2->Add( m_clearRot, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bMainSizer->Add( fgSizer2, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_stdButtons = new wxStdDialogButtonSizer();
+ m_stdButtonsOK = new wxButton( this, wxID_OK );
+ m_stdButtons->AddButton( m_stdButtonsOK );
+ m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_stdButtons->AddButton( m_stdButtonsCancel );
+ m_stdButtons->Realize();
+
+ bMainSizer->Add( m_stdButtons, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_MOVE_EXACT_BASE::OnClose ) );
+ m_polarCoords->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnPolarChanged ), NULL, this );
+ m_xEntry->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_MOVE_EXACT_BASE::OnTextFocusLost ), NULL, this );
+ m_clearX->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnClear ), NULL, this );
+ m_yEntry->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_MOVE_EXACT_BASE::OnTextFocusLost ), NULL, this );
+ m_clearY->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnClear ), NULL, this );
+ m_rotEntry->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_MOVE_EXACT_BASE::OnTextFocusLost ), NULL, this );
+ m_clearRot->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnClear ), NULL, this );
+ m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_MOVE_EXACT_BASE::~DIALOG_MOVE_EXACT_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_MOVE_EXACT_BASE::OnClose ) );
+ m_polarCoords->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnPolarChanged ), NULL, this );
+ m_xEntry->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_MOVE_EXACT_BASE::OnTextFocusLost ), NULL, this );
+ m_clearX->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnClear ), NULL, this );
+ m_yEntry->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_MOVE_EXACT_BASE::OnTextFocusLost ), NULL, this );
+ m_clearY->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnClear ), NULL, this );
+ m_rotEntry->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_MOVE_EXACT_BASE::OnTextFocusLost ), NULL, this );
+ m_clearRot->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnClear ), NULL, this );
+ m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_move_exact_base.h b/pcbnew/dialogs/dialog_move_exact_base.h
new file mode 100644
index 0000000..ecb3221
--- /dev/null
+++ b/pcbnew/dialogs/dialog_move_exact_base.h
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_MOVE_EXACT_BASE_H__
+#define __DIALOG_MOVE_EXACT_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/checkbox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_MOVE_EXACT_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_MOVE_EXACT_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxCheckBox* m_polarCoords;
+ wxStaticText* m_xLabel;
+ wxTextCtrl* m_xEntry;
+ wxStaticText* m_xUnit;
+ wxButton* m_clearX;
+ wxStaticText* m_yLabel;
+ wxTextCtrl* m_yEntry;
+ wxStaticText* m_yUnit;
+ wxButton* m_clearY;
+ wxStaticText* m_rotLabel;
+ wxTextCtrl* m_rotEntry;
+ wxStaticText* m_rotUnit;
+ wxButton* m_clearRot;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_stdButtons;
+ wxButton* m_stdButtonsOK;
+ wxButton* m_stdButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnPolarChanged( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnTextFocusLost( wxFocusEvent& event ) { event.Skip(); }
+ virtual void OnClear( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_MOVE_EXACT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Move Item"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_MOVE_EXACT_BASE();
+
+};
+
+#endif //__DIALOG_MOVE_EXACT_BASE_H__
diff --git a/pcbnew/dialogs/dialog_netlist.cpp b/pcbnew/dialogs/dialog_netlist.cpp
new file mode 100644
index 0000000..8733bdd
--- /dev/null
+++ b/pcbnew/dialogs/dialog_netlist.cpp
@@ -0,0 +1,487 @@
+
+/**
+ * @file pcbnew/dialogs/dialog_netlist.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <project.h>
+#include <kiface_i.h>
+#include <confirm.h>
+#include <macros.h>
+#include <dialog_helpers.h>
+#include <html_messagebox.h>
+#include <base_units.h>
+#include <wxPcbStruct.h>
+#include <pcb_netlist.h>
+#include <netlist_reader.h>
+#include <reporter.h>
+
+#include <pcbnew_config.h>
+#include <class_board_design_settings.h>
+#include <class_board.h>
+#include <class_module.h>
+#include <ratsnest_data.h>
+#include <wildcards_and_files_ext.h>
+
+#include <dialog_netlist.h>
+#include <wx_html_report_panel.h>
+
+#define NETLIST_SILENTMODE_KEY wxT("SilentMode")
+#define NETLIST_FILTER_MESSAGES_KEY wxT("NetlistReportFilterMsg")
+#define NETLIST_DELETESINGLEPADNETS_KEY wxT("NetlistDeleteSinglePadNets")
+
+void PCB_EDIT_FRAME::InstallNetlistFrame( wxDC* DC )
+{
+ /* Setup the netlist file name to the last netlist file read,
+ * or the board file name if the last filename is empty or last file not existing.
+ */
+ wxString netlistName = GetLastNetListRead();
+
+ wxFileName fn = netlistName;
+
+ if( !fn.IsOk() || !fn.FileExists() )
+ {
+ fn = GetBoard()->GetFileName();
+ fn.SetExt( NetlistFileExtension );
+
+ if( fn.GetName().IsEmpty() )
+ netlistName.Clear();
+ else
+ netlistName = fn.GetFullPath();
+ }
+
+ DIALOG_NETLIST dlg( this, DC, netlistName );
+
+ dlg.ShowModal();
+
+ // Save project settings if needed.
+ // Project settings are saved in the corresponding <board name>.pro file
+ bool configChanged = !GetLastNetListRead().IsEmpty() && ( netlistName != GetLastNetListRead() );
+
+ if( configChanged && !GetBoard()->GetFileName().IsEmpty()
+ && IsOK( NULL, _( "The project configuration has changed. Do you want to save it?" ) ) )
+ {
+ wxFileName fn = Prj().AbsolutePath( GetBoard()->GetFileName() );
+ fn.SetExt( ProjectFileExtension );
+
+ wxString pro_name = fn.GetFullPath();
+
+ Prj().ConfigSave( Kiface().KifaceSearch(), GROUP_PCB,
+ GetProjectFileParameters(), pro_name );
+ }
+}
+
+
+DIALOG_NETLIST::DIALOG_NETLIST( PCB_EDIT_FRAME* aParent, wxDC * aDC,
+ const wxString & aNetlistFullFilename )
+ : DIALOG_NETLIST_FBP( aParent )
+{
+ m_parent = aParent;
+ m_dc = aDC;
+ m_config = Kiface().KifaceSettings();
+
+ m_silentMode = m_config->Read( NETLIST_SILENTMODE_KEY, 0l );
+ bool tmp = m_config->Read( NETLIST_DELETESINGLEPADNETS_KEY, 0l );
+ m_rbSingleNets->SetSelection( tmp == 0 ? 0 : 1);
+ m_NetlistFilenameCtrl->SetValue( aNetlistFullFilename );
+ m_checkBoxSilentMode->SetValue( m_silentMode );
+
+ int severities = m_config->Read( NETLIST_FILTER_MESSAGES_KEY, -1l );
+ m_MessageWindow->SetVisibleSeverities( severities );
+
+ // Update sizes and sizers:
+ m_MessageWindow->MsgPanelSetMinSize( wxSize( -1, 150 ) );
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+DIALOG_NETLIST::~DIALOG_NETLIST()
+{
+ m_config->Write( NETLIST_SILENTMODE_KEY, (long) m_silentMode );
+ m_config->Write( NETLIST_DELETESINGLEPADNETS_KEY,
+ (long) m_rbSingleNets->GetSelection() );
+ m_config->Write( NETLIST_FILTER_MESSAGES_KEY,
+ (long) m_MessageWindow->GetVisibleSeverities() );
+}
+
+
+void DIALOG_NETLIST::OnOpenNetlistClick( wxCommandEvent& event )
+{
+ wxString lastPath = wxFileName( Prj().GetProjectFullName() ).GetPath();
+
+ wxString lastNetlistRead = m_parent->GetLastNetListRead();
+
+ if( !lastNetlistRead.IsEmpty() && !wxFileName::FileExists( lastNetlistRead ) )
+ {
+ lastNetlistRead = wxEmptyString;
+ }
+ else
+ {
+ wxFileName fn = lastNetlistRead;
+ lastPath = fn.GetPath();
+ lastNetlistRead = fn.GetFullName();
+ }
+
+ wxLogDebug( wxT( "Last net list read path '%s', file name '%s'." ),
+ GetChars( lastPath ), GetChars( lastNetlistRead ) );
+
+ wxFileDialog FilesDialog( this, _( "Select Netlist" ), lastPath, lastNetlistRead,
+ NetlistFileWildcard, wxFD_DEFAULT_STYLE | wxFD_FILE_MUST_EXIST );
+
+ if( FilesDialog.ShowModal() != wxID_OK )
+ return;
+
+ m_NetlistFilenameCtrl->SetValue( FilesDialog.GetPath() );
+}
+
+void DIALOG_NETLIST::OnReadNetlistFileClick( wxCommandEvent& event )
+{
+ wxString netlistFileName = m_NetlistFilenameCtrl->GetValue();
+ wxFileName fn = netlistFileName;
+
+ if( !fn.IsOk() )
+ {
+ wxMessageBox( _("Please, choose a valid netlist file") );
+ return;
+ }
+
+ if( !fn.FileExists() )
+ {
+ wxMessageBox( _("The netlist file does not exist") );
+ return;
+ }
+
+ // Give the user a chance to bail out when making changes from a netlist.
+ if( !m_checkDryRun->GetValue() && !m_silentMode
+ && !m_parent->GetBoard()->IsEmpty()
+ && !IsOK( NULL, _( "The changes made by reading the netlist cannot be undone. Are you "
+ "sure you want to read the netlist?" ) ) )
+ return;
+
+ m_MessageWindow->Clear();
+ REPORTER& reporter = m_MessageWindow->Reporter();
+
+ wxBusyCursor busy;
+
+ wxString msg;
+ msg.Printf( _( "Reading netlist file \"%s\".\n" ), GetChars( netlistFileName ) );
+ reporter.Report( msg, REPORTER::RPT_INFO );
+
+ if( m_Select_By_Timestamp->GetSelection() == 1 )
+ msg = _( "Using time stamps to match components and footprints.\n" );
+ else
+ msg = _( "Using references to match components and footprints.\n" );
+
+ reporter.Report( msg, REPORTER::RPT_INFO );
+ m_MessageWindow->SetLazyUpdate( true ); // use a "lazy" update to speed up the creation of the report
+ // (The window is not updated for each message)
+
+ m_parent->ReadPcbNetlist( netlistFileName, wxEmptyString, &reporter,
+ m_ChangeExistingFootprintCtrl->GetSelection() == 1,
+ m_DeleteBadTracks->GetSelection() == 1,
+ m_RemoveExtraFootprintsCtrl->GetSelection() == 1,
+ m_Select_By_Timestamp->GetSelection() == 1,
+ m_rbSingleNets->GetSelection() == 1,
+ m_checkDryRun->GetValue() );
+ // The creation of the report was made without window update:
+ // the full page must be displayed
+ m_MessageWindow->Flush();
+}
+
+
+void DIALOG_NETLIST::OnTestFootprintsClick( wxCommandEvent& event )
+{
+ if( m_parent->GetBoard()->m_Modules == NULL )
+ {
+ DisplayInfoMessage( this, _( "No footprints" ) );
+ return;
+ }
+
+ // Lists of duplicates, missing references and not in netlist footprints:
+ std::vector <MODULE*> duplicate;
+ wxArrayString missing;
+ std::vector <MODULE*> notInNetlist;
+ wxString netlistFilename = m_NetlistFilenameCtrl->GetValue();
+
+ if( !verifyFootprints( netlistFilename, wxEmptyString, duplicate, missing, notInNetlist ) )
+ return;
+
+ #define ERR_CNT_MAX 100 // Max number of errors to output in dialog
+ // to avoid a too long message list
+
+ wxString list; // The messages to display
+
+ m_parent->SetLastNetListRead( netlistFilename );
+
+ int err_cnt = 0;
+
+ // Search for duplicate footprints.
+ if( duplicate.size() == 0 )
+ list << wxT("<p><b>") << _( "No duplicate." ) << wxT("</b></p>");
+ else
+ {
+ list << wxT("<p><b>") << _( "Duplicates:" ) << wxT("</b></p>");
+
+ for( unsigned ii = 0; ii < duplicate.size(); ii++ )
+ {
+ MODULE* module = duplicate[ii];
+
+ if( module->GetReference().IsEmpty() )
+ list << wxT("<br>") << wxT("[noref)");
+ else
+ list << wxT("<br>") << module->GetReference();
+
+ list << wxT(" (<i>") << module->GetValue() << wxT("</i>)");
+ list << wxT(" @ ");
+ list << CoordinateToString( module->GetPosition().x ),
+ list << wxT(", ") << CoordinateToString( module->GetPosition().y ),
+ err_cnt++;
+
+ if( ERR_CNT_MAX < err_cnt )
+ break;
+ }
+ }
+
+ // Search for missing modules on board.
+ if( missing.size() == 0 )
+ list << wxT("<p><b>") << _( "No missing footprints." ) << wxT("</b></p>");
+ else
+ {
+ list << wxT("<p><b>") << _( "Missing:" ) << wxT("</b></p>");
+
+ for( unsigned ii = 0; ii < missing.size(); ii += 2 )
+ {
+ list << wxT("<br>") << missing[ii];
+ list << wxT(" (<i>") << missing[ii+1] << wxT("</i>)");
+ err_cnt++;
+
+ if( ERR_CNT_MAX < err_cnt )
+ break;
+ }
+ }
+
+
+ // Search for modules found on board but not in net list.
+ if( notInNetlist.size() == 0 )
+ list << wxT( "<p><b>" ) << _( "No extra footprints." ) << wxT( "</b></p>" );
+ else
+ {
+ list << wxT( "<p><b>" ) << _( "Not in Netlist:" ) << wxT( "</b></p>" );
+
+ for( unsigned ii = 0; ii < notInNetlist.size(); ii++ )
+ {
+ MODULE* module = notInNetlist[ii];
+
+ if( module->GetReference().IsEmpty() )
+ list << wxT( "<br>" ) << wxT( "[noref)" );
+ else
+ list << wxT( "<br>" ) << module->GetReference() ;
+
+ list << wxT( " (<i>" ) << module->GetValue() << wxT( "</i>)" );
+ list << wxT( " @ " );
+ list << CoordinateToString( module->GetPosition().x ),
+ list << wxT( ", " ) << CoordinateToString( module->GetPosition().y ),
+ err_cnt++;
+
+ if( ERR_CNT_MAX < err_cnt )
+ break;
+ }
+ }
+
+ if( ERR_CNT_MAX < err_cnt )
+ {
+ list << wxT( "<p><b>" )
+ << _( "Too many errors: some are skipped" )
+ << wxT( "</b></p>" );
+ }
+
+ HTML_MESSAGE_BOX dlg( this, _( "Check footprints" ) );
+ dlg.AddHTML_Text( list );
+ dlg.ShowModal();
+}
+
+
+/*!
+ * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_COMPILE_RATSNEST
+ */
+
+void DIALOG_NETLIST::OnCompileRatsnestClick( wxCommandEvent& event )
+{
+ // Rebuild the board connectivity:
+ if( m_parent->IsGalCanvasActive() )
+ m_parent->GetBoard()->GetRatsnest()->ProcessBoard();
+
+ m_parent->Compile_Ratsnest( m_dc, true );
+}
+
+
+/*!
+ * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL
+ */
+
+void DIALOG_NETLIST::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+void DIALOG_NETLIST::OnSaveMessagesToFile( wxCommandEvent& aEvent )
+{
+ wxFileName fn;
+
+ if( !m_parent->GetLastNetListRead().IsEmpty() )
+ {
+ fn = m_parent->GetLastNetListRead();
+ fn.SetExt( wxT( "txt" ) );
+ }
+ else
+ {
+ fn = wxPathOnly( Prj().GetProjectFullName() );
+ }
+
+ wxFileDialog dlg( this, _( "Save contents of message window" ), fn.GetPath(), fn.GetName(),
+ TextWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return;
+
+ fn = dlg.GetPath();
+
+ if( fn.GetExt().IsEmpty() )
+ fn.SetExt( wxT( "txt" ) );
+
+ wxFile f( fn.GetFullPath(), wxFile::write );
+
+ if( !f.IsOpened() )
+ {
+ wxString msg;
+
+ msg.Printf( _( "Cannot write message contents to file \"%s\"." ),
+ GetChars( fn.GetFullPath() ) );
+ wxMessageBox( msg, _( "File Write Error" ), wxOK | wxICON_ERROR, this );
+ return;
+ }
+}
+
+
+void DIALOG_NETLIST::OnUpdateUISaveMessagesToFile( wxUpdateUIEvent& aEvent )
+{
+ //aEvent.Enable( !m_MessageWindow->IsEmpty() );
+}
+
+
+void DIALOG_NETLIST::OnUpdateUIValidNetlistFile( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Enable( !m_NetlistFilenameCtrl->GetValue().IsEmpty() );
+}
+
+
+bool DIALOG_NETLIST::verifyFootprints( const wxString& aNetlistFilename,
+ const wxString & aCmpFilename,
+ std::vector< MODULE* >& aDuplicates,
+ wxArrayString& aMissing,
+ std::vector< MODULE* >& aNotInNetlist )
+{
+ wxString msg;
+ MODULE* module;
+ MODULE* nextModule;
+ NETLIST netlist;
+ wxBusyCursor dummy; // Shows an hourglass while calculating.
+ NETLIST_READER* netlistReader;
+ COMPONENT* component;
+
+ try
+ {
+ netlistReader = NETLIST_READER::GetNetlistReader( &netlist, aNetlistFilename,
+ aCmpFilename );
+
+ if( netlistReader == NULL )
+ {
+ msg.Printf( _( "Cannot open netlist file \"%s\"." ), GetChars( aNetlistFilename ) );
+ wxMessageBox( msg, _( "Netlist Load Error." ), wxOK | wxICON_ERROR );
+ return false;
+ }
+
+ std::auto_ptr< NETLIST_READER > nlr( netlistReader );
+ netlistReader->LoadNetlist();
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ msg.Printf( _( "Error loading netlist file:\n%s" ), ioe.errorText.GetData() );
+ wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR );
+ return false;
+ }
+
+ BOARD* pcb = m_parent->GetBoard();
+
+ // Search for duplicate footprints.
+ module = pcb->m_Modules;
+
+ for( ; module != NULL; module = module->Next() )
+ {
+ nextModule = module->Next();
+
+ for( ; nextModule != NULL; nextModule = nextModule->Next() )
+ {
+ if( module->GetReference().CmpNoCase( nextModule->GetReference() ) == 0 )
+ {
+ aDuplicates.push_back( module );
+ break;
+ }
+ }
+ }
+
+ // Search for component footprints in the netlist but not on the board.
+ for( unsigned ii = 0; ii < netlist.GetCount(); ii++ )
+ {
+ component = netlist.GetComponent( ii );
+
+ module = pcb->FindModuleByReference( component->GetReference() );
+
+ if( module == NULL )
+ {
+ aMissing.Add( component->GetReference() );
+ aMissing.Add( component->GetValue() );
+ }
+ }
+
+ // Search for component footprints found on board but not in netlist.
+ module = pcb->m_Modules;
+
+ for( ; module != NULL; module = module->Next() )
+ {
+
+ component = netlist.GetComponentByReference( module->GetReference() );
+
+ if( component == NULL )
+ aNotInNetlist.push_back( module );
+ }
+
+ return true;
+}
diff --git a/pcbnew/dialogs/dialog_netlist.h b/pcbnew/dialogs/dialog_netlist.h
new file mode 100644
index 0000000..958a7e0
--- /dev/null
+++ b/pcbnew/dialogs/dialog_netlist.h
@@ -0,0 +1,97 @@
+/**
+ * @file pcbnew/dialogs/dialog_netlist.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _DIALOG_NETLIST_H_
+#define _DIALOG_NETLIST_H_
+
+#include <dialog_netlist_fbp.h>
+
+
+class MODULE;
+class NETLIST;
+
+
+class DIALOG_NETLIST : public DIALOG_NETLIST_FBP
+{
+private:
+ PCB_EDIT_FRAME* m_parent;
+ wxDC* m_dc;
+ bool m_silentMode; // if true, do not display warning message about undo
+ wxConfigBase* m_config;
+
+public:
+ DIALOG_NETLIST( PCB_EDIT_FRAME* aParent, wxDC* aDC, const wxString & aNetlistFullFilename );
+ ~DIALOG_NETLIST();
+
+private:
+ /**
+ * Function verifyFootprints
+ * compares the netlist to the board and builds a list of duplicate, missing, and
+ * extra footprints.
+ *
+ * @param aNetlistFilename the netlist filename.
+ * @param aCmpFilename the component link filename.
+ * @param aDuplicate the list of duplicate modules to populate
+ * @param aMissing the list of missing module references and values to populate. For
+ * each missing item, the first string is the reference designator and
+ * the second is the value.
+ * @param aNotInNetlist is the list of component footprint found in the netlist but not on
+ * the board.
+ * @return true if no errors occurred while reading the netlist. Otherwise false.
+ */
+ bool verifyFootprints( const wxString& aNetlistFilename,
+ const wxString& aCmpFilename,
+ std::vector< MODULE* >& aDuplicate,
+ wxArrayString& aMissing,
+ std::vector< MODULE* >& aNotInNetlist );
+
+ /**
+ * Function loadFootprints
+ * loads the footprints for each #COMPONENT in \a aNetlist from the list of libraries.
+ *
+ * @param aNetlist is the netlist of components to load the footprints into.
+ */
+ void loadFootprints( NETLIST& aNetlist );
+
+ // Virtual event handlers:
+ void OnOpenNetlistClick( wxCommandEvent& event );
+ void OnReadNetlistFileClick( wxCommandEvent& event );
+ void OnTestFootprintsClick( wxCommandEvent& event );
+ void OnCompileRatsnestClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+ void OnSaveMessagesToFile( wxCommandEvent& aEvent );
+ void OnClickSilentMode( wxCommandEvent& event )
+ {
+ m_silentMode = m_checkBoxSilentMode->GetValue();
+ }
+
+ void OnUpdateUISaveMessagesToFile( wxUpdateUIEvent& aEvent );
+ void OnUpdateUIValidNetlistFile( wxUpdateUIEvent& aEvent );
+};
+
+
+#endif // _DIALOG_NETLIST_H_
diff --git a/pcbnew/dialogs/dialog_netlist_fbp.cpp b/pcbnew/dialogs/dialog_netlist_fbp.cpp
new file mode 100644
index 0000000..461a667
--- /dev/null
+++ b/pcbnew/dialogs/dialog_netlist_fbp.cpp
@@ -0,0 +1,200 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "wx_html_report_panel.h"
+
+#include "dialog_netlist_fbp.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_NETLIST_FBP::DIALOG_NETLIST_FBP( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bleftSizer;
+ bleftSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bnetlistOptSizer;
+ bnetlistOptSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bmodulesOptSizer;
+ bmodulesOptSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_Select_By_TimestampChoices[] = { _("Reference"), _("Timestamp") };
+ int m_Select_By_TimestampNChoices = sizeof( m_Select_By_TimestampChoices ) / sizeof( wxString );
+ m_Select_By_Timestamp = new wxRadioBox( this, wxID_ANY, _("Footprint Selection"), wxDefaultPosition, wxDefaultSize, m_Select_By_TimestampNChoices, m_Select_By_TimestampChoices, 1, wxRA_SPECIFY_COLS );
+ m_Select_By_Timestamp->SetSelection( 0 );
+ m_Select_By_Timestamp->SetToolTip( _("Select how footprints are recognized:\nby their reference (U1, R3...) (normal setting)\nor their time stamp (special setting after a full schematic reannotation)") );
+
+ bmodulesOptSizer->Add( m_Select_By_Timestamp, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_ChangeExistingFootprintCtrlChoices[] = { _("Keep"), _("Change") };
+ int m_ChangeExistingFootprintCtrlNChoices = sizeof( m_ChangeExistingFootprintCtrlChoices ) / sizeof( wxString );
+ m_ChangeExistingFootprintCtrl = new wxRadioBox( this, wxID_ANY, _("Exchange Footprint"), wxDefaultPosition, wxDefaultSize, m_ChangeExistingFootprintCtrlNChoices, m_ChangeExistingFootprintCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_ChangeExistingFootprintCtrl->SetSelection( 0 );
+ m_ChangeExistingFootprintCtrl->SetToolTip( _("Keep or change an existing footprint when the netlist gives a different footprint") );
+
+ bmodulesOptSizer->Add( m_ChangeExistingFootprintCtrl, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+
+ bnetlistOptSizer->Add( bmodulesOptSizer, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bTracksSizer;
+ bTracksSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_DeleteBadTracksChoices[] = { _("Keep"), _("Delete") };
+ int m_DeleteBadTracksNChoices = sizeof( m_DeleteBadTracksChoices ) / sizeof( wxString );
+ m_DeleteBadTracks = new wxRadioBox( this, wxID_ANY, _("Unconnected Tracks"), wxDefaultPosition, wxDefaultSize, m_DeleteBadTracksNChoices, m_DeleteBadTracksChoices, 1, wxRA_SPECIFY_COLS );
+ m_DeleteBadTracks->SetSelection( 0 );
+ m_DeleteBadTracks->SetToolTip( _("Keep or delete bad tracks after a netlist change") );
+
+ bTracksSizer->Add( m_DeleteBadTracks, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_RemoveExtraFootprintsCtrlChoices[] = { _("Keep"), _("Delete") };
+ int m_RemoveExtraFootprintsCtrlNChoices = sizeof( m_RemoveExtraFootprintsCtrlChoices ) / sizeof( wxString );
+ m_RemoveExtraFootprintsCtrl = new wxRadioBox( this, wxID_ANY, _("Extra Footprints"), wxDefaultPosition, wxDefaultSize, m_RemoveExtraFootprintsCtrlNChoices, m_RemoveExtraFootprintsCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_RemoveExtraFootprintsCtrl->SetSelection( 0 );
+ m_RemoveExtraFootprintsCtrl->SetToolTip( _("Remove footprints found on the Board but not in netlist\nNote: only not locked footprints will be removed") );
+
+ bTracksSizer->Add( m_RemoveExtraFootprintsCtrl, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_rbSingleNetsChoices[] = { _("Keep"), _("Delete") };
+ int m_rbSingleNetsNChoices = sizeof( m_rbSingleNetsChoices ) / sizeof( wxString );
+ m_rbSingleNets = new wxRadioBox( this, wxID_ANY, _("Single Pad Nets"), wxDefaultPosition, wxDefaultSize, m_rbSingleNetsNChoices, m_rbSingleNetsChoices, 1, wxRA_SPECIFY_COLS );
+ m_rbSingleNets->SetSelection( 0 );
+ bTracksSizer->Add( m_rbSingleNets, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+
+ bnetlistOptSizer->Add( bTracksSizer, 1, wxEXPAND, 5 );
+
+
+ bleftSizer->Add( bnetlistOptSizer, 1, wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( bleftSizer, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bRightSizerButtons;
+ bRightSizerButtons = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonRead = new wxButton( this, ID_READ_NETLIST_FILE, _("Read Current Netlist"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonRead->SetDefault();
+ m_buttonRead->SetToolTip( _("Read the current netlist and update connections and connectivity info") );
+
+ bRightSizerButtons->Add( m_buttonRead, 0, wxEXPAND|wxALL, 5 );
+
+ m_buttonClose = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizerButtons->Add( m_buttonClose, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonFPTest = new wxButton( this, ID_TEST_NETLIST, _("Test Footprints"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonFPTest->SetToolTip( _("Read the current netlist file and list missing and extra footprints") );
+
+ bRightSizerButtons->Add( m_buttonFPTest, 0, wxEXPAND|wxALL, 5 );
+
+ m_buttonRebild = new wxButton( this, ID_COMPILE_RATSNEST, _("Rebuild Board Connectivity"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonRebild->SetToolTip( _("Rebuild the full ratsnest (useful after a manual pad netname edition)") );
+
+ bRightSizerButtons->Add( m_buttonRebild, 0, wxEXPAND|wxALL, 5 );
+
+ m_buttonSaveMessages = new wxButton( this, wxID_ANY, _("Save Messages to File"), wxDefaultPosition, wxDefaultSize, 0 );
+ bRightSizerButtons->Add( m_buttonSaveMessages, 0, wxALL|wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( bRightSizerButtons, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bMainSizer->Add( bUpperSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ m_staticline11 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline11, 0, wxEXPAND | wxALL, 5 );
+
+ wxBoxSizer* bCenterSizer;
+ bCenterSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_checkDryRun = new wxCheckBox( this, wxID_ANY, _("Dry run. Only report changes in message panel"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkDryRun->SetToolTip( _("Dry Run:\nThe netlist is read, but no change is actually made on board.\nChanges are only reported in message panel, for info") );
+
+ bCenterSizer->Add( m_checkDryRun, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_checkBoxSilentMode = new wxCheckBox( this, wxID_ANY, _("Silent mode"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkBoxSilentMode->SetToolTip( _("Silent mode:\nDo not show the warning message before reading the netlist") );
+
+ bCenterSizer->Add( m_checkBoxSilentMode, 0, wxRIGHT|wxLEFT, 5 );
+
+
+ bMainSizer->Add( bCenterSizer, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bMainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ wxBoxSizer* bLowerSizer;
+ bLowerSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextNetfilename = new wxStaticText( this, wxID_ANY, _("Netlist File:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextNetfilename->Wrap( -1 );
+ bLowerSizer->Add( m_staticTextNetfilename, 0, wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerNetlistFilename;
+ bSizerNetlistFilename = new wxBoxSizer( wxHORIZONTAL );
+
+ m_NetlistFilenameCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerNetlistFilename->Add( m_NetlistFilenameCtrl, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ m_buttonBrowse = new wxButton( this, ID_OPEN_NELIST, _("Browse"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
+ bSizerNetlistFilename->Add( m_buttonBrowse, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+
+ bLowerSizer->Add( bSizerNetlistFilename, 0, wxEXPAND, 5 );
+
+ m_MessageWindow = new WX_HTML_REPORT_PANEL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_MessageWindow->SetMinSize( wxSize( -300,150 ) );
+
+ bLowerSizer->Add( m_MessageWindow, 1, wxEXPAND | wxALL, 5 );
+
+
+ bMainSizer->Add( bLowerSizer, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ m_buttonRead->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnReadNetlistFileClick ), NULL, this );
+ m_buttonRead->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUIValidNetlistFile ), NULL, this );
+ m_buttonClose->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnCancelClick ), NULL, this );
+ m_buttonFPTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnTestFootprintsClick ), NULL, this );
+ m_buttonFPTest->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUIValidNetlistFile ), NULL, this );
+ m_buttonRebild->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnCompileRatsnestClick ), NULL, this );
+ m_buttonRebild->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUIValidNetlistFile ), NULL, this );
+ m_buttonSaveMessages->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnSaveMessagesToFile ), NULL, this );
+ m_buttonSaveMessages->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUISaveMessagesToFile ), NULL, this );
+ m_checkBoxSilentMode->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnClickSilentMode ), NULL, this );
+ m_buttonBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnOpenNetlistClick ), NULL, this );
+}
+
+DIALOG_NETLIST_FBP::~DIALOG_NETLIST_FBP()
+{
+ // Disconnect Events
+ m_buttonRead->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnReadNetlistFileClick ), NULL, this );
+ m_buttonRead->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUIValidNetlistFile ), NULL, this );
+ m_buttonClose->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnCancelClick ), NULL, this );
+ m_buttonFPTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnTestFootprintsClick ), NULL, this );
+ m_buttonFPTest->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUIValidNetlistFile ), NULL, this );
+ m_buttonRebild->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnCompileRatsnestClick ), NULL, this );
+ m_buttonRebild->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUIValidNetlistFile ), NULL, this );
+ m_buttonSaveMessages->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnSaveMessagesToFile ), NULL, this );
+ m_buttonSaveMessages->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_NETLIST_FBP::OnUpdateUISaveMessagesToFile ), NULL, this );
+ m_checkBoxSilentMode->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnClickSilentMode ), NULL, this );
+ m_buttonBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_NETLIST_FBP::OnOpenNetlistClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_netlist_fbp.fbp b/pcbnew/dialogs/dialog_netlist_fbp.fbp
new file mode 100644
index 0000000..deb2c43
--- /dev/null
+++ b/pcbnew/dialogs/dialog_netlist_fbp.fbp
@@ -0,0 +1,1768 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_netlist_fbp</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_netlist_fbp</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_NETLIST_FBP</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Netlist</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bleftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bnetlistOptSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmodulesOptSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Reference&quot; &quot;Timestamp&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Footprint Selection</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Select_By_Timestamp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Select how footprints are recognized:&#x0A;by their reference (U1, R3...) (normal setting)&#x0A;or their time stamp (special setting after a full schematic reannotation)</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Keep&quot; &quot;Change&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Exchange Footprint</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ChangeExistingFootprintCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Keep or change an existing footprint when the netlist gives a different footprint</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bTracksSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Keep&quot; &quot;Delete&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unconnected Tracks</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DeleteBadTracks</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Keep or delete bad tracks after a netlist change</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Keep&quot; &quot;Delete&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Extra Footprints</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_RemoveExtraFootprintsCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Remove footprints found on the Board but not in netlist&#x0A;Note: only not locked footprints will be removed</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Keep&quot; &quot;Delete&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Single Pad Nets</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbSingleNets</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bRightSizerButtons</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_READ_NETLIST_FILE</property>
+ <property name="label">Read Current Netlist</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonRead</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Read the current netlist and update connections and connectivity info</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnReadNetlistFileClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI">OnUpdateUIValidNetlistFile</event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonClose</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_TEST_NETLIST</property>
+ <property name="label">Test Footprints</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonFPTest</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Read the current netlist file and list missing and extra footprints</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnTestFootprintsClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI">OnUpdateUIValidNetlistFile</event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_COMPILE_RATSNEST</property>
+ <property name="label">Rebuild Board Connectivity</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonRebild</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Rebuild the full ratsnest (useful after a manual pad netname edition)</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnCompileRatsnestClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI">OnUpdateUIValidNetlistFile</event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Save Messages to File</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonSaveMessages</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnSaveMessagesToFile</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI">OnUpdateUISaveMessagesToFile</event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline11</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bCenterSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Dry run. Only report changes in message panel</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkDryRun</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Dry Run:&#x0A;The netlist is read, but no change is actually made on board.&#x0A;Changes are only reported in message panel, for info</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Silent mode</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkBoxSilentMode</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Silent mode:&#x0A;Do not show the warning message before reading the netlist</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnClickSilentMode</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bLowerSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Netlist File:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextNetfilename</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerNetlistFilename</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NetlistFilenameCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_OPEN_NELIST</property>
+ <property name="label">Browse</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonBrowse</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_EXACTFIT</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnOpenNetlistClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-300,150</property>
+ <property name="moveable">1</property>
+ <property name="name">m_MessageWindow</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass">WX_HTML_REPORT_PANEL; wx_html_report_panel.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_netlist_fbp.h b/pcbnew/dialogs/dialog_netlist_fbp.h
new file mode 100644
index 0000000..db56cbf
--- /dev/null
+++ b/pcbnew/dialogs/dialog_netlist_fbp.h
@@ -0,0 +1,89 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_NETLIST_FBP_H__
+#define __DIALOG_NETLIST_FBP_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class WX_HTML_REPORT_PANEL;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/radiobox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/statline.h>
+#include <wx/checkbox.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/panel.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_NETLIST_FBP
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_NETLIST_FBP : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ ID_READ_NETLIST_FILE = 1000,
+ ID_TEST_NETLIST,
+ ID_COMPILE_RATSNEST,
+ ID_OPEN_NELIST
+ };
+
+ wxRadioBox* m_Select_By_Timestamp;
+ wxRadioBox* m_ChangeExistingFootprintCtrl;
+ wxRadioBox* m_DeleteBadTracks;
+ wxRadioBox* m_RemoveExtraFootprintsCtrl;
+ wxRadioBox* m_rbSingleNets;
+ wxButton* m_buttonRead;
+ wxButton* m_buttonClose;
+ wxButton* m_buttonFPTest;
+ wxButton* m_buttonRebild;
+ wxButton* m_buttonSaveMessages;
+ wxStaticLine* m_staticline11;
+ wxCheckBox* m_checkDryRun;
+ wxCheckBox* m_checkBoxSilentMode;
+ wxStaticLine* m_staticline1;
+ wxStaticText* m_staticTextNetfilename;
+ wxTextCtrl* m_NetlistFilenameCtrl;
+ wxButton* m_buttonBrowse;
+ WX_HTML_REPORT_PANEL* m_MessageWindow;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnReadNetlistFileClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnUpdateUIValidNetlistFile( wxUpdateUIEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnTestFootprintsClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCompileRatsnestClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnSaveMessagesToFile( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnUpdateUISaveMessagesToFile( wxUpdateUIEvent& event ) { event.Skip(); }
+ virtual void OnClickSilentMode( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOpenNetlistClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_NETLIST_FBP( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Netlist"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_NETLIST_FBP();
+
+};
+
+#endif //__DIALOG_NETLIST_FBP_H__
diff --git a/pcbnew/dialogs/dialog_non_copper_zones_properties.cpp b/pcbnew/dialogs/dialog_non_copper_zones_properties.cpp
new file mode 100644
index 0000000..6c54bce
--- /dev/null
+++ b/pcbnew/dialogs/dialog_non_copper_zones_properties.cpp
@@ -0,0 +1,268 @@
+/**
+ * @file dialog_non_copper_zones_properties.cpp
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <base_units.h>
+
+#include <class_board.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <zones.h>
+
+#include <wx/imaglist.h> // needed for wx/listctrl.h, in wxGTK 2.8.12
+
+#include <dialog_non_copper_zones_properties_base.h>
+
+#define LAYER_BITMAP_SIZE_X 20
+#define LAYER_BITMAP_SIZE_Y 10
+
+/**
+ * Class DIALOG_NON_COPPER_ZONES_EDITOR
+ * is a dialog editor for non copper zones properties,
+ * derived from DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE, which is maintained and
+ * created by wxFormBuilder
+ */
+class DIALOG_NON_COPPER_ZONES_EDITOR : public DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE
+{
+private:
+ PCB_BASE_FRAME* m_parent;
+ ZONE_CONTAINER* m_zone;
+ ZONE_SETTINGS* m_ptr;
+ ZONE_SETTINGS m_settings; // working copy of zone settings
+
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+ void Init();
+
+public:
+ DIALOG_NON_COPPER_ZONES_EDITOR( PCB_BASE_FRAME* aParent,
+ ZONE_CONTAINER* aZone, ZONE_SETTINGS* aSettings );
+
+private:
+ /**
+ * Function makeLayerBitmap
+ * creates the colored rectangle bitmaps used in the layer selection widget.
+ * @param aColor is the color to fill the rectangle with.
+ */
+ wxBitmap makeLayerBitmap( EDA_COLOR_T aColor );
+};
+
+
+ZONE_EDIT_T InvokeNonCopperZonesEditor( PCB_BASE_FRAME* aParent,
+ ZONE_CONTAINER* aZone, ZONE_SETTINGS* aSettings )
+{
+ DIALOG_NON_COPPER_ZONES_EDITOR dlg( aParent, aZone, aSettings );
+
+ ZONE_EDIT_T result = ZONE_EDIT_T( dlg.ShowModal() );
+
+ return result;
+}
+
+
+DIALOG_NON_COPPER_ZONES_EDITOR::DIALOG_NON_COPPER_ZONES_EDITOR( PCB_BASE_FRAME* aParent,
+ ZONE_CONTAINER* aZone,
+ ZONE_SETTINGS* aSettings ) :
+ DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE( aParent )
+{
+ m_parent = aParent;
+
+ m_zone = aZone;
+ m_ptr = aSettings;
+ m_settings = *aSettings;
+
+ Init();
+
+ // the size of some items has changed, so we must call SetSizeHints()
+ GetSizer()->SetSizeHints( this );
+}
+
+
+void DIALOG_NON_COPPER_ZONES_EDITOR::Init()
+{
+ BOARD* board = m_parent->GetBoard();
+
+ SetReturnCode( ZONE_ABORT ); // Will be changed on button click
+
+ AddUnitSymbol( *m_MinThicknessValueTitle, g_UserUnit );
+ wxString msg = StringFromValue( g_UserUnit, m_settings.m_ZoneMinThickness );
+ m_ZoneMinThicknessCtrl->SetValue( msg );
+
+ if( m_settings.m_Zone_45_Only )
+ m_OrientEdgesOpt->SetSelection( 1 );
+
+ switch( m_settings.m_Zone_HatchingStyle )
+ {
+ case CPolyLine::NO_HATCH:
+ m_OutlineAppearanceCtrl->SetSelection( 0 );
+ break;
+
+ case CPolyLine::DIAGONAL_EDGE:
+ m_OutlineAppearanceCtrl->SetSelection( 1 );
+ break;
+
+ case CPolyLine::DIAGONAL_FULL:
+ m_OutlineAppearanceCtrl->SetSelection( 2 );
+ break;
+ }
+
+ // Create one column in m_LayerSelectionCtrl
+ wxListItem column0;
+ column0.SetId( 0 );
+ m_LayerSelectionCtrl->InsertColumn( 0, column0 );
+
+ // Create an icon list:
+ wxImageList* imageList = new wxImageList( LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
+ m_LayerSelectionCtrl->AssignImageList( imageList, wxIMAGE_LIST_SMALL );
+
+ LAYER_ID lyrSelect = m_parent->GetActiveLayer();
+
+ if( m_zone )
+ lyrSelect = m_zone->GetLayer();
+
+ int ctrlWidth = 0; // Min width for m_LayerSelectionCtrl to show the layers names
+ int imgIdx = 0;
+
+ for( LSEQ seq = LSET::AllNonCuMask().Seq(); seq; ++seq, ++imgIdx )
+ {
+ LAYER_ID layer = *seq;
+
+ EDA_COLOR_T layerColor = board->GetLayerColor( layer );
+ imageList->Add( makeLayerBitmap( layerColor ) );
+
+ wxString msg = board->GetLayerName( layer );
+ msg.Trim();
+
+ int itemIndex = m_LayerSelectionCtrl->InsertItem(
+ m_LayerSelectionCtrl->GetItemCount(), msg, imgIdx );
+
+ if(lyrSelect == layer )
+ m_LayerSelectionCtrl->Select( itemIndex );
+
+ wxSize tsize( GetTextSize( msg, m_LayerSelectionCtrl ) );
+ ctrlWidth = std::max( ctrlWidth, tsize.x );
+ }
+
+ // The most easy way to ensure the right size is to use wxLIST_AUTOSIZE
+ // unfortunately this option does not work well both on
+ // wxWidgets 2.8 ( column witdth too small), and
+ // wxWidgets 2.9 ( column witdth too large)
+ ctrlWidth += LAYER_BITMAP_SIZE_X + 25; // Add bitmap width + margin between bitmap and text
+ m_LayerSelectionCtrl->SetColumnWidth( 0, ctrlWidth );
+
+ ctrlWidth += 25; // add small margin between text and window borders
+ // and room for vertical scroll bar
+ m_LayerSelectionCtrl->SetMinSize( wxSize( ctrlWidth, -1 ) );
+}
+
+
+void DIALOG_NON_COPPER_ZONES_EDITOR::OnOkClick( wxCommandEvent& event )
+{
+ wxString txtvalue = m_ZoneMinThicknessCtrl->GetValue();
+
+ m_settings.m_ZoneMinThickness = ValueFromString( g_UserUnit, txtvalue );
+
+ if( m_settings.m_ZoneMinThickness < 10 )
+ {
+ DisplayError( this,
+ _( "Error :\nyou must choose a min thickness value bigger than 0.001 inch (or 0.0254 mm)" ) );
+ return;
+ }
+
+ m_settings.m_FillMode = 0; // Use always polygon fill mode
+
+ switch( m_OutlineAppearanceCtrl->GetSelection() )
+ {
+ case 0:
+ m_settings.m_Zone_HatchingStyle = CPolyLine::NO_HATCH;
+ break;
+
+ case 1:
+ m_settings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE;
+ break;
+
+ case 2:
+ m_settings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_FULL;
+ break;
+ }
+
+ wxConfigBase* cfg = Kiface().KifaceSettings();
+ wxASSERT( cfg );
+
+ cfg->Write( ZONE_NET_OUTLINES_HATCH_OPTION_KEY, (long) m_settings.m_Zone_HatchingStyle );
+
+ if( m_OrientEdgesOpt->GetSelection() == 0 )
+ m_settings.m_Zone_45_Only = false;
+ else
+ m_settings.m_Zone_45_Only = true;
+
+ // Get the layer selection for this zone
+ int ii = m_LayerSelectionCtrl->GetFirstSelected();
+
+ if( ii < 0 )
+ {
+ DisplayError( this, _( "Error : you must choose a layer" ) );
+ return;
+ }
+
+ LSEQ seq = LSET::AllNonCuMask().Seq();
+
+ m_settings.m_CurrentZone_Layer = seq[ii];
+
+ *m_ptr = m_settings;
+
+ EndModal( ZONE_OK );
+}
+
+
+void DIALOG_NON_COPPER_ZONES_EDITOR::OnCancelClick( wxCommandEvent& event )
+{
+ // do not save the edits.
+
+ EndModal( ZONE_ABORT );
+}
+
+
+wxBitmap DIALOG_NON_COPPER_ZONES_EDITOR::makeLayerBitmap( EDA_COLOR_T aColor )
+{
+ wxBitmap bitmap( LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
+ wxBrush brush;
+ wxMemoryDC iconDC;
+
+ iconDC.SelectObject( bitmap );
+ brush.SetColour( MakeColour( aColor ) );
+ brush.SetStyle( wxBRUSHSTYLE_SOLID );
+
+ iconDC.SetBrush( brush );
+ iconDC.DrawRectangle( 0, 0, LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
+
+ return bitmap;
+}
diff --git a/pcbnew/dialogs/dialog_non_copper_zones_properties_base.cpp b/pcbnew/dialogs/dialog_non_copper_zones_properties_base.cpp
new file mode 100644
index 0000000..c41ffc2
--- /dev/null
+++ b/pcbnew/dialogs/dialog_non_copper_zones_properties_base.cpp
@@ -0,0 +1,96 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_non_copper_zones_properties_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+BEGIN_EVENT_TABLE( DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE, DIALOG_SHIM )
+ EVT_BUTTON( wxID_CANCEL, DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE::_wxFB_OnCancelClick )
+ EVT_BUTTON( wxID_OK, DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE::_wxFB_OnOkClick )
+END_EVENT_TABLE()
+
+DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE::DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* m_MainSizer;
+ m_MainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* m_UpperSizer;
+ m_UpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizerLeft;
+ bSizerLeft = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextLayerSelection = new wxStaticText( this, wxID_ANY, _("Layer selection:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextLayerSelection->Wrap( -1 );
+ bSizerLeft->Add( m_staticTextLayerSelection, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_LayerSelectionCtrl = new wxListView( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ALIGN_LEFT|wxLC_NO_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL );
+ bSizerLeft->Add( m_LayerSelectionCtrl, 1, wxALL|wxEXPAND, 5 );
+
+
+ m_UpperSizer->Add( bSizerLeft, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerRight;
+ bSizerRight = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* m_OutilinesBoxOpt;
+ m_OutilinesBoxOpt = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Outlines Options:") ), wxVERTICAL );
+
+ wxString m_OrientEdgesOptChoices[] = { _("Any"), _("H, V and 45 deg") };
+ int m_OrientEdgesOptNChoices = sizeof( m_OrientEdgesOptChoices ) / sizeof( wxString );
+ m_OrientEdgesOpt = new wxRadioBox( this, wxID_ANY, _("Zone Edges Orient"), wxDefaultPosition, wxDefaultSize, m_OrientEdgesOptNChoices, m_OrientEdgesOptChoices, 1, wxRA_SPECIFY_COLS );
+ m_OrientEdgesOpt->SetSelection( 0 );
+ m_OutilinesBoxOpt->Add( m_OrientEdgesOpt, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_OutlineAppearanceCtrlChoices[] = { _("Line"), _("Hatched Outline"), _("Full Hatched") };
+ int m_OutlineAppearanceCtrlNChoices = sizeof( m_OutlineAppearanceCtrlChoices ) / sizeof( wxString );
+ m_OutlineAppearanceCtrl = new wxRadioBox( this, wxID_ANY, _("Outlines Appearence"), wxDefaultPosition, wxDefaultSize, m_OutlineAppearanceCtrlNChoices, m_OutlineAppearanceCtrlChoices, 1, wxRA_SPECIFY_COLS );
+ m_OutlineAppearanceCtrl->SetSelection( 1 );
+ m_OutilinesBoxOpt->Add( m_OutlineAppearanceCtrl, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizerRight->Add( m_OutilinesBoxOpt, 0, wxEXPAND|wxALL, 5 );
+
+ m_MinThicknessValueTitle = new wxStaticText( this, wxID_ANY, _("Zone min thickness value"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MinThicknessValueTitle->Wrap( -1 );
+ bSizerRight->Add( m_MinThicknessValueTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_ZoneMinThicknessCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ZoneMinThicknessCtrl->SetMaxLength( 0 );
+ bSizerRight->Add( m_ZoneMinThicknessCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ m_UpperSizer->Add( bSizerRight, 0, wxEXPAND, 5 );
+
+
+ m_MainSizer->Add( m_UpperSizer, 1, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ m_MainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizerButtons = new wxStdDialogButtonSizer();
+ m_sdbSizerButtonsOK = new wxButton( this, wxID_OK );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsOK );
+ m_sdbSizerButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizerButtons->AddButton( m_sdbSizerButtonsCancel );
+ m_sdbSizerButtons->Realize();
+
+ m_MainSizer->Add( m_sdbSizerButtons, 0, wxEXPAND, 5 );
+
+
+ this->SetSizer( m_MainSizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+}
+
+DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE::~DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE()
+{
+}
diff --git a/pcbnew/dialogs/dialog_non_copper_zones_properties_base.fbp b/pcbnew/dialogs/dialog_non_copper_zones_properties_base.fbp
new file mode 100644
index 0000000..20f6296
--- /dev/null
+++ b/pcbnew/dialogs/dialog_non_copper_zones_properties_base.fbp
@@ -0,0 +1,795 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">table</property>
+ <property name="file">dialog_non_copper_zones_properties_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_non_copper_zones_properties_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE</property>
+ <property name="pos"></property>
+ <property name="size">369,317</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Non Copper Zones Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER</property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_MainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_UpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerLeft</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layer selection:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextLayerSelection</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxListCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LayerSelectionCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLC_ALIGN_LEFT|wxLC_NO_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL</property>
+ <property name="subclass">wxListView; </property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnListBeginDrag"></event>
+ <event name="OnListBeginLabelEdit"></event>
+ <event name="OnListBeginRDrag"></event>
+ <event name="OnListCacheHint"></event>
+ <event name="OnListColBeginDrag"></event>
+ <event name="OnListColClick"></event>
+ <event name="OnListColDragging"></event>
+ <event name="OnListColEndDrag"></event>
+ <event name="OnListColRightClick"></event>
+ <event name="OnListDeleteAllItems"></event>
+ <event name="OnListDeleteItem"></event>
+ <event name="OnListEndLabelEdit"></event>
+ <event name="OnListInsertItem"></event>
+ <event name="OnListItemActivated"></event>
+ <event name="OnListItemDeselected"></event>
+ <event name="OnListItemFocused"></event>
+ <event name="OnListItemMiddleClick"></event>
+ <event name="OnListItemRightClick"></event>
+ <event name="OnListItemSelected"></event>
+ <event name="OnListKeyDown"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRight</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Outlines Options:</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_OutilinesBoxOpt</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Any&quot; &quot;H, V and 45 deg&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Zone Edges Orient</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OrientEdgesOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Line&quot; &quot;Hatched Outline&quot; &quot;Full Hatched&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Outlines Appearence</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OutlineAppearanceCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Zone min thickness value</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MinThicknessValueTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ZoneMinThicknessCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizerButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_non_copper_zones_properties_base.h b/pcbnew/dialogs/dialog_non_copper_zones_properties_base.h
new file mode 100644
index 0000000..05cc56d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_non_copper_zones_properties_base.h
@@ -0,0 +1,72 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_NON_COPPER_ZONES_PROPERTIES_BASE_H__
+#define __DIALOG_NON_COPPER_ZONES_PROPERTIES_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class wxListView;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/listctrl.h>
+#include <wx/sizer.h>
+#include <wx/radiobox.h>
+#include <wx/statbox.h>
+#include <wx/textctrl.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE : public DIALOG_SHIM
+{
+ DECLARE_EVENT_TABLE()
+ private:
+
+ // Private event handlers
+ void _wxFB_OnCancelClick( wxCommandEvent& event ){ OnCancelClick( event ); }
+ void _wxFB_OnOkClick( wxCommandEvent& event ){ OnOkClick( event ); }
+
+
+ protected:
+ wxStaticText* m_staticTextLayerSelection;
+ wxListView* m_LayerSelectionCtrl;
+ wxRadioBox* m_OrientEdgesOpt;
+ wxRadioBox* m_OutlineAppearanceCtrl;
+ wxStaticText* m_MinThicknessValueTitle;
+ wxTextCtrl* m_ZoneMinThicknessCtrl;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizerButtons;
+ wxButton* m_sdbSizerButtonsOK;
+ wxButton* m_sdbSizerButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Non Copper Zones Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 369,317 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER );
+ ~DIALOG_NONCOPPER_ZONES_PROPERTIES_BASE();
+
+};
+
+#endif //__DIALOG_NON_COPPER_ZONES_PROPERTIES_BASE_H__
diff --git a/pcbnew/dialogs/dialog_orient_footprints.cpp b/pcbnew/dialogs/dialog_orient_footprints.cpp
new file mode 100644
index 0000000..4c6dd83
--- /dev/null
+++ b/pcbnew/dialogs/dialog_orient_footprints.cpp
@@ -0,0 +1,162 @@
+/**
+ * @file dialog_orient_footprints.cpp
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2010 Jean_Pierre Charras <jp.charras@ujf-grenoble.fr>
+ * Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <dialog_orient_footprints_base.h>
+
+
+
+/* DIALOG_ORIENT_FOOTPRINTS class declaration
+ */
+
+class DIALOG_ORIENT_FOOTPRINTS: public DIALOG_ORIENT_FOOTPRINTS_BASE
+{
+private:
+ PCB_EDIT_FRAME * m_Parent;
+ static int newOrientation;
+
+public:
+ DIALOG_ORIENT_FOOTPRINTS( PCB_EDIT_FRAME* parent );
+ ~DIALOG_ORIENT_FOOTPRINTS() {}
+
+ bool ApplyToLockedModules()
+ {
+ return m_ApplyToLocked->IsChecked();
+ }
+
+ int GetOrientation()
+ {
+ return newOrientation;
+ }
+
+ wxString GetFilter()
+ {
+ return m_FilterPattern->GetValue();
+ }
+
+private:
+ void init();
+
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+};
+
+
+int DIALOG_ORIENT_FOOTPRINTS::newOrientation = 0;
+
+
+DIALOG_ORIENT_FOOTPRINTS::DIALOG_ORIENT_FOOTPRINTS( PCB_EDIT_FRAME* parent )
+ : DIALOG_ORIENT_FOOTPRINTS_BASE( parent )
+{
+ m_Parent = parent;
+ wxString txt;
+ txt.Printf( wxT( "%g" ), (double) newOrientation/10 );
+ m_OrientationCtrl->SetValue( txt );
+ SetFocus();
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+
+void PCB_EDIT_FRAME::OnOrientFootprints( wxCommandEvent& event )
+{
+ DIALOG_ORIENT_FOOTPRINTS dlg( this );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return;
+
+ wxString text = dlg.GetFilter();
+
+ if( ReOrientModules( text, dlg.GetOrientation(), dlg.ApplyToLockedModules() ) )
+ {
+ m_canvas->Refresh();
+ Compile_Ratsnest( NULL, true );
+ }
+}
+
+
+bool PCB_EDIT_FRAME::ReOrientModules( const wxString& ModuleMask, double Orient,
+ bool include_fixe )
+{
+ wxString line;
+ bool modified = false;
+
+ line.Printf( _( "OK to set footprints orientation to %.1f degrees ?" ), Orient / 10.0 );
+
+ if( !IsOK( this, line ) )
+ return false;
+
+ for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
+ {
+ if( module->IsLocked() && !include_fixe )
+ continue;
+
+ if( WildCompareString( ModuleMask, module->GetReference(), false ) )
+ {
+ modified = true;
+ Rotate_Module( NULL, module, Orient, false );
+ }
+ }
+
+ if ( modified )
+ OnModify();
+
+ return modified;
+}
+
+
+void DIALOG_ORIENT_FOOTPRINTS::OnOkClick( wxCommandEvent& event )
+{
+ double d_orient;
+ wxString text = m_OrientationCtrl->GetValue();
+
+ if ( ! text.ToDouble( &d_orient ) )
+ {
+ DisplayError( this, _( "Bad value for footprints orientation" ) );
+ return;
+ }
+
+ newOrientation = KiROUND( d_orient * 10 );
+ NORMALIZE_ANGLE_180( newOrientation );
+ EndModal( wxID_OK );
+}
+
+void DIALOG_ORIENT_FOOTPRINTS::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
diff --git a/pcbnew/dialogs/dialog_orient_footprints_base.cpp b/pcbnew/dialogs/dialog_orient_footprints_base.cpp
new file mode 100644
index 0000000..9500469
--- /dev/null
+++ b/pcbnew/dialogs/dialog_orient_footprints_base.cpp
@@ -0,0 +1,81 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Apr 10 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_orient_footprints_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_ORIENT_FOOTPRINTS_BASE::DIALOG_ORIENT_FOOTPRINTS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizerLeft;
+ bSizerLeft = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText1 = new wxStaticText( this, wxID_ANY, _("Orientation:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ bSizerLeft->Add( m_staticText1, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OrientationCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_OrientationCtrl->SetToolTip( _("New orientation (0.1 degree resolution)") );
+
+ bSizerLeft->Add( m_OrientationCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_staticText2 = new wxStaticText( this, wxID_ANY, _("Filter:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText2->Wrap( -1 );
+ bSizerLeft->Add( m_staticText2, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_FilterPattern = new wxTextCtrl( this, wxID_ANY, _("*"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_FilterPattern->SetToolTip( _("Filter to select footprints by reference") );
+
+ bSizerLeft->Add( m_FilterPattern, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerLeft->Add( 0, 0, 0, wxTOP|wxBOTTOM, 5 );
+
+ m_ApplyToLocked = new wxCheckBox( this, wxID_ANY, _("Include Locked Footprints"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ApplyToLocked->SetToolTip( _("Force locked footprints to be modified") );
+
+ bSizerLeft->Add( m_ApplyToLocked, 0, wxALL, 5 );
+
+
+ bSizerMain->Add( bSizerLeft, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerRight;
+ bSizerRight = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonOK->SetDefault();
+ bSizerRight->Add( m_buttonOK, 0, wxALL, 5 );
+
+ m_buttonClose = new wxButton( this, wxID_ANY, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerRight->Add( m_buttonClose, 0, wxALL, 5 );
+
+
+ bSizerMain->Add( bSizerRight, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ORIENT_FOOTPRINTS_BASE::OnOkClick ), NULL, this );
+ m_buttonClose->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ORIENT_FOOTPRINTS_BASE::OnCancelClick ), NULL, this );
+}
+
+DIALOG_ORIENT_FOOTPRINTS_BASE::~DIALOG_ORIENT_FOOTPRINTS_BASE()
+{
+ // Disconnect Events
+ m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ORIENT_FOOTPRINTS_BASE::OnOkClick ), NULL, this );
+ m_buttonClose->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ORIENT_FOOTPRINTS_BASE::OnCancelClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_orient_footprints_base.fbp b/pcbnew/dialogs/dialog_orient_footprints_base.fbp
new file mode 100644
index 0000000..a0f53cd
--- /dev/null
+++ b/pcbnew/dialogs/dialog_orient_footprints_base.fbp
@@ -0,0 +1,741 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="11" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_orient_footprints_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_orient_footprints</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_ORIENT_FOOTPRINTS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">403,160</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Footprints Orientation</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerLeft</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Orientation:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OrientationCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">New orientation (0.1 degree resolution)</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Filter:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FilterPattern</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Filter to select footprints by reference</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">*</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Include Locked Footprints</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ApplyToLocked</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Force locked footprints to be modified</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerRight</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_OK</property>
+ <property name="label">OK</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonOK</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnOkClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonClose</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_orient_footprints_base.h b/pcbnew/dialogs/dialog_orient_footprints_base.h
new file mode 100644
index 0000000..37429c6
--- /dev/null
+++ b/pcbnew/dialogs/dialog_orient_footprints_base.h
@@ -0,0 +1,58 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Apr 10 2012)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_ORIENT_FOOTPRINTS_BASE_H__
+#define __DIALOG_ORIENT_FOOTPRINTS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/checkbox.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_ORIENT_FOOTPRINTS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_ORIENT_FOOTPRINTS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText1;
+ wxTextCtrl* m_OrientationCtrl;
+ wxStaticText* m_staticText2;
+ wxTextCtrl* m_FilterPattern;
+ wxCheckBox* m_ApplyToLocked;
+ wxButton* m_buttonOK;
+ wxButton* m_buttonClose;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_ORIENT_FOOTPRINTS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Footprints Orientation"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 403,160 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_ORIENT_FOOTPRINTS_BASE();
+
+};
+
+#endif //__DIALOG_ORIENT_FOOTPRINTS_BASE_H__
diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp
new file mode 100644
index 0000000..0495121
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pad_properties.cpp
@@ -0,0 +1,1247 @@
+/**
+ * @file dialog_pad_properties.cpp
+ * @brief Pad editing functions and dialog pad editor.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2008-2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <trigo.h>
+#include <macros.h>
+#include <wxBasePcbFrame.h>
+#include <pcbcommon.h>
+#include <base_units.h>
+
+#include <wx/dcbuffer.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <dialog_pad_properties_base.h>
+#include <html_messagebox.h>
+
+
+// list of pad shapes.
+static PAD_SHAPE_T code_shape[] = {
+ PAD_SHAPE_CIRCLE,
+ PAD_SHAPE_OVAL,
+ PAD_SHAPE_RECT,
+ PAD_SHAPE_TRAPEZOID
+};
+
+
+static PAD_ATTR_T code_type[] = {
+ PAD_ATTRIB_STANDARD,
+ PAD_ATTRIB_SMD,
+ PAD_ATTRIB_CONN,
+ PAD_ATTRIB_HOLE_NOT_PLATED
+};
+
+
+// Default mask layers setup for pads according to the pad type
+static const LSET std_pad_layers[] = {
+ // PAD_ATTRIB_STANDARD:
+ D_PAD::StandardMask(),
+
+ // PAD_ATTRIB_SMD:
+ D_PAD::SMDMask(),
+
+ // PAD_ATTRIB_CONN:
+ D_PAD::ConnSMDMask(),
+
+ // PAD_ATTRIB_HOLE_NOT_PLATED:
+ D_PAD::UnplatedHoleMask()
+};
+
+
+/**
+ * class DIALOG_PAD_PROPERTIES, derived from DIALOG_PAD_PROPERTIES_BASE,
+ * created by wxFormBuilder
+ */
+class DIALOG_PAD_PROPERTIES : public DIALOG_PAD_PROPERTIES_BASE
+{
+public:
+ DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, D_PAD* aPad );
+ ~DIALOG_PAD_PROPERTIES()
+ {
+ delete m_dummyPad;
+ }
+
+private:
+ PCB_BASE_FRAME* m_parent;
+ D_PAD* m_currentPad; // pad currently being edited
+ D_PAD* m_dummyPad; // a working copy used to show changes
+ D_PAD* m_padMaster; // The pad used to create new pads in board or
+ // footprint editor
+ BOARD* m_board; // the main board: this is the board handled by
+ // the PCB editor, if running or the dummy
+ // board used by the footprint editor
+ // (could happen when the Footprint editor will be run
+ // alone, outside the board editor
+ bool m_isFlipped; // true if the parent footprint (therefore pads) is flipped (mirrored)
+ // in this case, some Y coordinates values must be negated
+ bool m_canUpdate;
+ bool m_canEditNetName; // true only if the called is the board editor
+
+private:
+ void initValues();
+
+ bool padValuesOK(); ///< test if all values are acceptable for the pad
+
+ void redraw();
+
+ /**
+ * Function setPadLayersList
+ * updates the CheckBox states in pad layers list,
+ * @param layer_mask = pad layer mask (ORed layers bit mask)
+ */
+ void setPadLayersList( LSET layer_mask );
+
+ /// Copy values from dialog field to aPad's members
+ bool transferDataToPad( D_PAD* aPad );
+
+ // event handlers:
+ void OnResize( wxSizeEvent& event );
+
+ void OnPadShapeSelection( wxCommandEvent& event );
+ void OnDrillShapeSelected( wxCommandEvent& event );
+
+ void PadOrientEvent( wxCommandEvent& event );
+ void PadTypeSelected( wxCommandEvent& event );
+
+ void OnSetLayers( wxCommandEvent& event );
+ void OnCancelButtonClick( wxCommandEvent& event );
+ void OnPaintShowPanel( wxPaintEvent& event );
+
+ /// Called when a dimension has changed.
+ /// Update the graphical pad shown in the panel.
+ void OnValuesChanged( wxCommandEvent& event );
+
+ /// Updates the different parameters for the component being edited.
+ /// Fired from the OK button click.
+ void PadPropertiesAccept( wxCommandEvent& event );
+};
+
+
+void PCB_BASE_FRAME::InstallPadOptionsFrame( D_PAD* aPad )
+{
+ DIALOG_PAD_PROPERTIES dlg( this, aPad );
+
+ dlg.ShowModal();
+}
+
+
+DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, D_PAD* aPad ) :
+ DIALOG_PAD_PROPERTIES_BASE( aParent )
+{
+ m_canUpdate = false;
+ m_parent = aParent;
+ m_currentPad = aPad; // aPad can be NULL, if the dialog is called
+ // from the module editor to set default pad characteristics
+
+ m_board = m_parent->GetBoard();
+
+ m_padMaster = &m_parent->GetDesignSettings().m_Pad_Master;
+ m_dummyPad = new D_PAD( (MODULE*) NULL );
+
+ if( aPad )
+ m_dummyPad->Copy( aPad );
+ else // We are editing a "master" pad, i.e. a pad used to create new pads
+ m_dummyPad->Copy( m_padMaster );
+
+ if( m_parent->IsGalCanvasActive() )
+ {
+ m_panelShowPadGal->UseColorScheme( m_board->GetColorsSettings() );
+ m_panelShowPadGal->SwitchBackend( m_parent->GetGalCanvas()->GetBackend() );
+ m_panelShowPadGal->Show();
+ m_panelShowPad->Hide();
+ m_panelShowPadGal->GetView()->Add( m_dummyPad );
+ m_panelShowPadGal->StartDrawing();
+
+ Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_PAD_PROPERTIES::OnResize ) );
+ }
+ else
+ {
+ m_panelShowPad->Show();
+ m_panelShowPadGal->Hide();
+ }
+
+ initValues();
+
+ m_sdbSizer1OK->SetDefault();
+ m_PadNumCtrl->SetFocus();
+ m_canUpdate = true;
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
+{
+ wxPaintDC dc( m_panelShowPad );
+ PAD_DRAWINFO drawInfo;
+
+ EDA_COLOR_T color = BLACK;
+
+ if( m_dummyPad->GetLayerSet()[F_Cu] )
+ {
+ color = m_board->GetVisibleElementColor( PAD_FR_VISIBLE );
+ }
+
+ if( m_dummyPad->GetLayerSet()[B_Cu] )
+ {
+ color = ColorMix( color, m_board->GetVisibleElementColor( PAD_BK_VISIBLE ) );
+ }
+
+ // What could happen: the pad color is *actually* black, or no
+ // copper was selected
+ if( color == BLACK )
+ color = LIGHTGRAY;
+
+ drawInfo.m_Color = color;
+ drawInfo.m_HoleColor = DARKGRAY;
+ drawInfo.m_Offset = m_dummyPad->GetPosition();
+ drawInfo.m_Display_padnum = true;
+ drawInfo.m_Display_netname = true;
+
+ if( m_dummyPad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
+ drawInfo.m_ShowNotPlatedHole = true;
+
+ // Shows the local pad clearance
+ drawInfo.m_PadClearance = m_dummyPad->GetLocalClearance();
+
+ wxSize dc_size = dc.GetSize();
+ dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
+
+ // Calculate a suitable scale to fit the available draw area
+ int dim = m_dummyPad->GetSize().x + std::abs( m_dummyPad->GetDelta().y );
+
+ // Invalid x size. User could enter zero, or have deleted all text prior to
+ // entering a new value; this is also treated as zero. If dim is left at
+ // zero, the drawing scale is zero and we get a crash.
+ if( dim == 0 )
+ {
+ // If drill size has been set, use that. Otherwise default to 1mm.
+ dim = m_dummyPad->GetDrillSize().x;
+ if( dim == 0 )
+ dim = Millimeter2iu( 1.0 );
+ }
+
+ if( m_dummyPad->GetLocalClearance() > 0 )
+ dim += m_dummyPad->GetLocalClearance() * 2;
+
+ double scale = (double) dc_size.x / dim;
+
+ // If the pad is a circle, use the x size here instead.
+ int ysize;
+ if( m_dummyPad->GetShape() == PAD_SHAPE_CIRCLE )
+ ysize = m_dummyPad->GetSize().x;
+ else
+ ysize = m_dummyPad->GetSize().y;
+
+ dim = ysize + std::abs( m_dummyPad->GetDelta().x );
+
+ // Invalid y size. See note about x size above.
+ if( dim == 0 )
+ {
+ dim = m_dummyPad->GetDrillSize().y;
+ if( dim == 0 )
+ dim = Millimeter2iu( 0.1 );
+ }
+
+ if( m_dummyPad->GetLocalClearance() > 0 )
+ dim += m_dummyPad->GetLocalClearance() * 2;
+
+ double altscale = (double) dc_size.y / dim;
+ scale = std::min( scale, altscale );
+
+ // Give a margin
+ scale *= 0.7;
+ dc.SetUserScale( scale, scale );
+
+ GRResetPenAndBrush( &dc );
+ m_dummyPad->DrawShape( NULL, &dc, drawInfo );
+
+ // Draw X and Y axis.
+ // this is particularly useful to show the reference position of pads
+ // with offset and no hole
+ GRLine( NULL, &dc, -dim, 0, dim, 0, 0, BLUE ); // X axis
+ GRLine( NULL, &dc, 0, -dim, 0, dim, 0, BLUE ); // Y axis
+
+ event.Skip();
+}
+
+
+void DIALOG_PAD_PROPERTIES::initValues()
+{
+ wxString msg;
+ double angle;
+
+ // Disable pad net name wxTextCtrl if the caller is the footprint editor
+ // because nets are living only in the board managed by the board editor
+ m_canEditNetName = m_parent->IsType( FRAME_PCB );
+
+
+ // Setup layers names from board
+ // Should be made first, before calling m_rbCopperLayersSel->SetSelection()
+ m_rbCopperLayersSel->SetString( 0, m_board->GetLayerName( F_Cu ) );
+ m_rbCopperLayersSel->SetString( 1, m_board->GetLayerName( B_Cu ) );
+
+ m_PadLayerAdhCmp->SetLabel( m_board->GetLayerName( F_Adhes ) );
+ m_PadLayerAdhCu->SetLabel( m_board->GetLayerName( B_Adhes ) );
+ m_PadLayerPateCmp->SetLabel( m_board->GetLayerName( F_Paste ) );
+ m_PadLayerPateCu->SetLabel( m_board->GetLayerName( B_Paste ) );
+ m_PadLayerSilkCmp->SetLabel( m_board->GetLayerName( F_SilkS ) );
+ m_PadLayerSilkCu->SetLabel( m_board->GetLayerName( B_SilkS ) );
+ m_PadLayerMaskCmp->SetLabel( m_board->GetLayerName( F_Mask ) );
+ m_PadLayerMaskCu->SetLabel( m_board->GetLayerName( B_Mask ) );
+ m_PadLayerECO1->SetLabel( m_board->GetLayerName( Eco1_User ) );
+ m_PadLayerECO2->SetLabel( m_board->GetLayerName( Eco2_User ) );
+ m_PadLayerDraft->SetLabel( m_board->GetLayerName( Dwgs_User ) );
+
+ m_isFlipped = false;
+
+ if( m_currentPad )
+ {
+ MODULE* module = m_currentPad->GetParent();
+
+ if( module->GetLayer() == B_Cu )
+ {
+ m_isFlipped = true;
+ m_staticModuleSideValue->SetLabel( _( "Back side (footprint is mirrored)" ) );
+ }
+
+ //Internal angles are in 0.1 degree
+ msg.Printf( wxT( "%.1f" ), module->GetOrientation() / 10.0 );
+ m_staticModuleRotValue->SetLabel( msg );
+ }
+
+ if( m_isFlipped )
+ {
+ wxPoint pt = m_dummyPad->GetOffset();
+ pt.y = -pt.y;
+ m_dummyPad->SetOffset( pt );
+
+ wxSize sz = m_dummyPad->GetDelta();
+ sz.y = -sz.y;
+ m_dummyPad->SetDelta( sz );
+
+ // flip pad's layers
+ m_dummyPad->SetLayerSet( FlipLayerMask( m_dummyPad->GetLayerSet() ) );
+ }
+
+ m_staticTextWarningPadFlipped->Show(m_isFlipped);
+
+ m_PadNumCtrl->SetValue( m_dummyPad->GetPadName() );
+ m_PadNetNameCtrl->SetValue( m_dummyPad->GetNetname() );
+
+ // Display current unit name in dialog:
+ m_PadPosX_Unit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_PadPosY_Unit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_PadDrill_X_Unit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_PadDrill_Y_Unit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_PadShapeSizeX_Unit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_PadShapeSizeY_Unit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_PadShapeOffsetX_Unit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_PadShapeOffsetY_Unit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_PadShapeDelta_Unit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_PadLengthDie_Unit->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+
+ // Display current pad masks clearances units
+ m_NetClearanceUnits->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_SolderMaskMarginUnits->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_SolderPasteMarginUnits->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_ThermalWidthUnits->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_ThermalGapUnits->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+
+ // Display current pad parameters units:
+ PutValueInLocalUnits( *m_PadPosition_X_Ctrl, m_dummyPad->GetPosition().x );
+ PutValueInLocalUnits( *m_PadPosition_Y_Ctrl, m_dummyPad->GetPosition().y );
+
+ PutValueInLocalUnits( *m_PadDrill_X_Ctrl, m_dummyPad->GetDrillSize().x );
+ PutValueInLocalUnits( *m_PadDrill_Y_Ctrl, m_dummyPad->GetDrillSize().y );
+
+ PutValueInLocalUnits( *m_ShapeSize_X_Ctrl, m_dummyPad->GetSize().x );
+ PutValueInLocalUnits( *m_ShapeSize_Y_Ctrl, m_dummyPad->GetSize().y );
+
+ PutValueInLocalUnits( *m_ShapeOffset_X_Ctrl, m_dummyPad->GetOffset().x );
+ PutValueInLocalUnits( *m_ShapeOffset_Y_Ctrl, m_dummyPad->GetOffset().y );
+
+ if( m_dummyPad->GetDelta().x )
+ {
+ PutValueInLocalUnits( *m_ShapeDelta_Ctrl, m_dummyPad->GetDelta().x );
+ m_trapDeltaDirChoice->SetSelection( 0 );
+ }
+ else
+ {
+ PutValueInLocalUnits( *m_ShapeDelta_Ctrl, m_dummyPad->GetDelta().y );
+ m_trapDeltaDirChoice->SetSelection( 1 );
+ }
+
+ PutValueInLocalUnits( *m_LengthPadToDieCtrl, m_dummyPad->GetPadToDieLength() );
+
+ PutValueInLocalUnits( *m_NetClearanceValueCtrl, m_dummyPad->GetLocalClearance() );
+ PutValueInLocalUnits( *m_SolderMaskMarginCtrl, m_dummyPad->GetLocalSolderMaskMargin() );
+ PutValueInLocalUnits( *m_ThermalWidthCtrl, m_dummyPad->GetThermalWidth() );
+ PutValueInLocalUnits( *m_ThermalGapCtrl, m_dummyPad->GetThermalGap() );
+
+ // These 2 parameters are usually < 0, so prepare entering a negative value, if current is 0
+ PutValueInLocalUnits( *m_SolderPasteMarginCtrl, m_dummyPad->GetLocalSolderPasteMargin() );
+
+ if( m_dummyPad->GetLocalSolderPasteMargin() == 0 )
+ m_SolderPasteMarginCtrl->SetValue( wxT( "-" ) + m_SolderPasteMarginCtrl->GetValue() );
+
+ msg.Printf( wxT( "%f" ), m_dummyPad->GetLocalSolderPasteMarginRatio() * 100.0 );
+
+ if( m_dummyPad->GetLocalSolderPasteMarginRatio() == 0.0 && msg[0] == '0' )
+ // Sometimes Printf adds a sign if the value is small
+ m_SolderPasteMarginRatioCtrl->SetValue( wxT( "-" ) + msg );
+ else
+ m_SolderPasteMarginRatioCtrl->SetValue( msg );
+
+ switch( m_dummyPad->GetZoneConnection() )
+ {
+ default:
+ case PAD_ZONE_CONN_INHERITED:
+ m_ZoneConnectionChoice->SetSelection( 0 );
+ break;
+
+ case PAD_ZONE_CONN_FULL:
+ m_ZoneConnectionChoice->SetSelection( 1 );
+ break;
+
+ case PAD_ZONE_CONN_THERMAL:
+ m_ZoneConnectionChoice->SetSelection( 2 );
+ break;
+
+ case PAD_ZONE_CONN_NONE:
+ m_ZoneConnectionChoice->SetSelection( 3 );
+ break;
+ }
+
+ if( m_currentPad )
+ {
+ MODULE* module = m_currentPad->GetParent();
+
+ angle = m_currentPad->GetOrientation() - module->GetOrientation();
+
+ if( m_isFlipped )
+ angle = -angle;
+
+ m_dummyPad->SetOrientation( angle );
+ }
+
+ angle = m_dummyPad->GetOrientation();
+
+ NORMALIZE_ANGLE_180( angle ); // ? normalizing is in D_PAD::SetOrientation()
+
+ // Set layers used by this pad: :
+ setPadLayersList( m_dummyPad->GetLayerSet() );
+
+ // Pad Orient
+ switch( int( angle ) )
+ {
+ case 0:
+ m_PadOrient->SetSelection( 0 );
+ break;
+
+ case 900:
+ m_PadOrient->SetSelection( 1 );
+ break;
+
+ case -900:
+ m_PadOrient->SetSelection( 2 );
+ break;
+
+ case 1800:
+ case -1800:
+ m_PadOrient->SetSelection( 3 );
+ break;
+
+ default:
+ m_PadOrient->SetSelection( 4 );
+ break;
+ }
+
+ switch( m_dummyPad->GetShape() )
+ {
+ default:
+ case PAD_SHAPE_CIRCLE:
+ m_PadShape->SetSelection( 0 );
+ break;
+
+ case PAD_SHAPE_OVAL:
+ m_PadShape->SetSelection( 1 );
+ break;
+
+ case PAD_SHAPE_RECT:
+ m_PadShape->SetSelection( 2 );
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ m_PadShape->SetSelection( 3 );
+ break;
+ }
+
+ msg.Printf( wxT( "%g" ), angle );
+ m_PadOrientCtrl->SetValue( msg );
+
+ // Type of pad selection
+ m_PadType->SetSelection( 0 );
+
+ for( unsigned ii = 0; ii < DIM( code_type ); ii++ )
+ {
+ if( code_type[ii] == m_dummyPad->GetAttribute() )
+ {
+ m_PadType->SetSelection( ii );
+ break;
+ }
+ }
+
+ // Enable/disable Pad name,and pad length die
+ // (disable for NPTH pads (mechanical pads)
+ bool enable = m_dummyPad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED;
+
+ m_PadNumCtrl->Enable( enable );
+ m_PadNetNameCtrl->Enable( m_canEditNetName && enable && m_currentPad != NULL );
+ m_LengthPadToDieCtrl->Enable( enable );
+
+ if( m_dummyPad->GetDrillShape() != PAD_DRILL_SHAPE_OBLONG )
+ m_DrillShapeCtrl->SetSelection( 0 );
+ else
+ m_DrillShapeCtrl->SetSelection( 1 );
+
+ // Update some dialog widgets state (Enable/disable options):
+ wxCommandEvent cmd_event;
+ setPadLayersList( m_dummyPad->GetLayerSet() );
+ OnDrillShapeSelected( cmd_event );
+ OnPadShapeSelection( cmd_event );
+}
+
+
+void DIALOG_PAD_PROPERTIES::OnResize( wxSizeEvent& event )
+{
+ redraw();
+ event.Skip();
+}
+
+
+void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event )
+{
+ switch( m_PadShape->GetSelection() )
+ {
+ case 0: // PAD_SHAPE_CIRCLE:
+ m_ShapeDelta_Ctrl->Enable( false );
+ m_trapDeltaDirChoice->Enable( false );
+ m_ShapeSize_Y_Ctrl->Enable( false );
+ m_ShapeOffset_X_Ctrl->Enable( false );
+ m_ShapeOffset_Y_Ctrl->Enable( false );
+ break;
+
+ case 1: // PAD_SHAPE_OVAL:
+ m_ShapeDelta_Ctrl->Enable( false );
+ m_trapDeltaDirChoice->Enable( false );
+ m_ShapeSize_Y_Ctrl->Enable( true );
+ m_ShapeOffset_X_Ctrl->Enable( true );
+ m_ShapeOffset_Y_Ctrl->Enable( true );
+ break;
+
+ case 2: // PAD_SHAPE_RECT:
+ m_ShapeDelta_Ctrl->Enable( false );
+ m_trapDeltaDirChoice->Enable( false );
+ m_ShapeSize_Y_Ctrl->Enable( true );
+ m_ShapeOffset_X_Ctrl->Enable( true );
+ m_ShapeOffset_Y_Ctrl->Enable( true );
+ break;
+
+ case 3: // PAD_SHAPE_TRAPEZOID:
+ m_ShapeDelta_Ctrl->Enable( true );
+ m_trapDeltaDirChoice->Enable( true );
+ m_ShapeSize_Y_Ctrl->Enable( true );
+ m_ShapeOffset_X_Ctrl->Enable( true );
+ m_ShapeOffset_Y_Ctrl->Enable( true );
+ break;
+ }
+
+ transferDataToPad( m_dummyPad );
+ redraw();
+}
+
+
+void DIALOG_PAD_PROPERTIES::OnDrillShapeSelected( wxCommandEvent& event )
+{
+ if( m_PadType->GetSelection() == 1 || m_PadType->GetSelection() == 2 )
+ {
+ // pad type = SMD or CONN: no hole allowed
+ m_PadDrill_X_Ctrl->Enable( false );
+ m_PadDrill_Y_Ctrl->Enable( false );
+ }
+ else
+ {
+ switch( m_DrillShapeCtrl->GetSelection() )
+ {
+ case 0: //CIRCLE:
+ m_PadDrill_X_Ctrl->Enable( true );
+ m_PadDrill_Y_Ctrl->Enable( false );
+ break;
+
+ case 1: //OVALE:
+ m_PadDrill_X_Ctrl->Enable( true );
+ m_PadDrill_Y_Ctrl->Enable( true );
+ break;
+ }
+ }
+
+ transferDataToPad( m_dummyPad );
+ redraw();
+}
+
+
+void DIALOG_PAD_PROPERTIES::PadOrientEvent( wxCommandEvent& event )
+{
+ switch( m_PadOrient->GetSelection() )
+ {
+ case 0:
+ m_dummyPad->SetOrientation( 0 );
+ break;
+
+ case 1:
+ m_dummyPad->SetOrientation( 900 );
+ break;
+
+ case 2:
+ m_dummyPad->SetOrientation( -900 );
+ break;
+
+ case 3:
+ m_dummyPad->SetOrientation( 1800 );
+ break;
+
+ default:
+ break;
+ }
+
+ wxString msg;
+ msg.Printf( wxT( "%g" ), m_dummyPad->GetOrientation() );
+ m_PadOrientCtrl->SetValue( msg );
+
+ transferDataToPad( m_dummyPad );
+ redraw();
+}
+
+
+void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event )
+{
+ unsigned ii = m_PadType->GetSelection();
+
+ if( ii >= DIM( code_type ) ) // catches < 0 also
+ ii = 0;
+
+ LSET layer_mask = std_pad_layers[ii];
+ setPadLayersList( layer_mask );
+
+ // Enable/disable drill dialog items:
+ event.SetId( m_DrillShapeCtrl->GetSelection() );
+ OnDrillShapeSelected( event );
+
+ if( ii == 0 || ii == DIM( code_type )-1 )
+ m_DrillShapeCtrl->Enable( true );
+ else
+ m_DrillShapeCtrl->Enable( false );
+
+ // Enable/disable Pad name,and pad length die
+ // (disable for NPTH pads (mechanical pads)
+ bool enable = ii != 3;
+ m_PadNumCtrl->Enable( enable );
+ m_PadNetNameCtrl->Enable( m_canEditNetName && enable && m_currentPad != NULL );
+ m_LengthPadToDieCtrl->Enable( enable );
+}
+
+
+void DIALOG_PAD_PROPERTIES::setPadLayersList( LSET layer_mask )
+{
+ LSET cu_set = layer_mask & LSET::AllCuMask();
+
+ if( cu_set == LSET( F_Cu ) )
+ m_rbCopperLayersSel->SetSelection( 0 );
+ else if( cu_set == LSET( B_Cu ) )
+ m_rbCopperLayersSel->SetSelection( 1 );
+ else if( cu_set.any() )
+ m_rbCopperLayersSel->SetSelection( 2 );
+ else
+ m_rbCopperLayersSel->SetSelection( 3 );
+
+ m_PadLayerAdhCmp->SetValue( layer_mask[F_Adhes] );
+ m_PadLayerAdhCu->SetValue( layer_mask[B_Adhes] );
+
+ m_PadLayerPateCmp->SetValue( layer_mask[F_Paste] );
+ m_PadLayerPateCu->SetValue( layer_mask[B_Paste] );
+
+ m_PadLayerSilkCmp->SetValue( layer_mask[F_SilkS] );
+ m_PadLayerSilkCu->SetValue( layer_mask[B_SilkS] );
+
+ m_PadLayerMaskCmp->SetValue( layer_mask[F_Mask] );
+ m_PadLayerMaskCu->SetValue( layer_mask[B_Mask] );
+
+ m_PadLayerECO1->SetValue( layer_mask[Eco1_User] );
+ m_PadLayerECO2->SetValue( layer_mask[Eco2_User] );
+
+ m_PadLayerDraft->SetValue( layer_mask[Dwgs_User] );
+}
+
+
+// Called when select/deselect a layer.
+void DIALOG_PAD_PROPERTIES::OnSetLayers( wxCommandEvent& event )
+{
+ transferDataToPad( m_dummyPad );
+ redraw();
+}
+
+
+// test if all values are acceptable for the pad
+bool DIALOG_PAD_PROPERTIES::padValuesOK()
+{
+ bool error = transferDataToPad( m_dummyPad );
+ bool skip_tstoffset = false; // the offset prm is not always tested
+
+ wxArrayString error_msgs;
+ wxString msg;
+
+ // Test for incorrect values
+ if( (m_dummyPad->GetSize().x <= 0) ||
+ ((m_dummyPad->GetSize().y <= 0) && (m_dummyPad->GetShape() != PAD_SHAPE_CIRCLE)) )
+ {
+ error_msgs.Add( _( "Pad size must be greater than zero" ) );
+ }
+
+ if( (m_dummyPad->GetSize().x < m_dummyPad->GetDrillSize().x) ||
+ (m_dummyPad->GetSize().y < m_dummyPad->GetDrillSize().y) )
+ {
+ error_msgs.Add( _( "Incorrect value for pad drill: pad drill bigger than pad size" ) );
+ skip_tstoffset = true; // offset prm will be not tested because if the drill value
+ // is incorrect the offset prm is always seen as incorrect, even if it is 0
+ }
+
+ LSET padlayers_mask = m_dummyPad->GetLayerSet();
+
+ if( padlayers_mask == 0 )
+ error_msgs.Add( _( "Error: pad has no layer" ) );
+
+ if( !padlayers_mask[F_Cu] && !padlayers_mask[B_Cu] )
+ {
+ if( m_dummyPad->GetDrillSize().x || m_dummyPad->GetDrillSize().y )
+ {
+ // Note: he message is shown in an HTML window
+ msg = _( "Error: the pad is not on a copper layer and has a hole" );
+
+ if( m_dummyPad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
+ {
+ msg += wxT( "<br><br><i>" );
+ msg += _( "For NPTH pad, set pad size value to pad drill value,"
+ " if you do not want this pad plotted in gerber files"
+ );
+ }
+
+ error_msgs.Add( msg );
+ }
+ }
+
+ if( !skip_tstoffset )
+ {
+ wxPoint max_size;
+ max_size.x = std::abs( m_dummyPad->GetOffset().x );
+ max_size.y = std::abs( m_dummyPad->GetOffset().y );
+ max_size.x += m_dummyPad->GetDrillSize().x / 2;
+ max_size.y += m_dummyPad->GetDrillSize().y / 2;
+
+ if( ( m_dummyPad->GetSize().x / 2 < max_size.x ) ||
+ ( m_dummyPad->GetSize().y / 2 < max_size.y ) )
+ {
+ error_msgs.Add( _( "Incorrect value for pad offset" ) );
+ }
+ }
+
+ if( error )
+ {
+ error_msgs.Add( _( "Too large value for pad delta size" ) );
+ }
+
+ switch( m_dummyPad->GetAttribute() )
+ {
+ case PAD_ATTRIB_HOLE_NOT_PLATED: // Not plated, but through hole, a hole is expected
+ case PAD_ATTRIB_STANDARD : // Pad through hole, a hole is also expected
+ if( m_dummyPad->GetDrillSize().x <= 0 )
+ error_msgs.Add( _( "Error: Through hole pad: drill diameter set to 0" ) );
+ break;
+
+ case PAD_ATTRIB_CONN: // Connector pads are smd pads, just they do not have solder paste.
+ if( padlayers_mask[B_Paste] || padlayers_mask[F_Paste] )
+ error_msgs.Add( _( "Error: Connector pads are not on the solder paste layer\n"
+ "Use SMD pads instead" ) );
+ // Fall trough
+ case PAD_ATTRIB_SMD: // SMD and Connector pads (One external copper layer only)
+ {
+ LSET innerlayers_mask = padlayers_mask & LSET::InternalCuMask();
+
+ if( ( padlayers_mask[F_Cu] && padlayers_mask[B_Cu] ) ||
+ innerlayers_mask.count() != 0 )
+ error_msgs.Add( _( "Error: only one external copper layer allowed for SMD or Connector pads" ) );
+ }
+ break;
+ }
+
+ if( error_msgs.GetCount() )
+ {
+ HTML_MESSAGE_BOX dlg( this, _("Pad setup errors list" ) );
+ dlg.ListSet( error_msgs );
+ dlg.ShowModal();
+ }
+
+ return error_msgs.GetCount() == 0;
+}
+
+
+void DIALOG_PAD_PROPERTIES::redraw()
+{
+ if( m_parent->IsGalCanvasActive() )
+ {
+ m_dummyPad->ViewUpdate();
+
+ BOX2I bbox = m_dummyPad->ViewBBox();
+
+ if( bbox.GetSize().x > 0 && bbox.GetSize().y > 0 )
+ {
+ // Autozoom
+ m_panelShowPadGal->GetView()->SetViewport( BOX2D( bbox.GetOrigin(), bbox.GetSize() ) );
+
+ // Add a margin
+ m_panelShowPadGal->GetView()->SetScale( m_panelShowPadGal->GetView()->GetScale() * 0.7 );
+
+ m_panelShowPadGal->Refresh();
+ }
+ }
+ else
+ {
+ m_panelShowPad->Refresh();
+ }
+}
+
+
+void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event )
+{
+ if( !padValuesOK() )
+ return;
+
+ bool rastnestIsChanged = false;
+ int isign = m_isFlipped ? -1 : 1;
+
+ transferDataToPad( m_padMaster );
+ // m_padMaster is a pattern: ensure there is no net for this pad:
+ m_padMaster->SetNetCode( NETINFO_LIST::UNCONNECTED );
+
+ if( m_currentPad ) // Set current Pad parameters
+ {
+ wxSize size;
+ MODULE* module = m_currentPad->GetParent();
+
+ m_parent->SaveCopyInUndoList( module, UR_CHANGED );
+ module->SetLastEditTime();
+
+ // redraw the area where the pad was, without pad (delete pad on screen)
+ m_currentPad->SetFlags( DO_NOT_DRAW );
+ m_parent->GetCanvas()->RefreshDrawingRect( m_currentPad->GetBoundingBox() );
+ m_currentPad->ClearFlags( DO_NOT_DRAW );
+
+ // Update values
+ m_currentPad->SetShape( m_padMaster->GetShape() );
+ m_currentPad->SetAttribute( m_padMaster->GetAttribute() );
+
+ if( m_currentPad->GetPosition() != m_padMaster->GetPosition() )
+ {
+ m_currentPad->SetPosition( m_padMaster->GetPosition() );
+ rastnestIsChanged = true;
+ }
+
+ // compute the pos 0 value, i.e. pad position for module with orientation = 0
+ // i.e. relative to module origin (module position)
+ wxPoint pt = m_currentPad->GetPosition() - module->GetPosition();
+
+ RotatePoint( &pt, -module->GetOrientation() );
+
+ m_currentPad->SetPos0( pt );
+
+ m_currentPad->SetOrientation( m_padMaster->GetOrientation() * isign + module->GetOrientation() );
+
+ m_currentPad->SetSize( m_padMaster->GetSize() );
+
+ size = m_padMaster->GetDelta();
+ size.y *= isign;
+ m_currentPad->SetDelta( size );
+
+ m_currentPad->SetDrillSize( m_padMaster->GetDrillSize() );
+ m_currentPad->SetDrillShape( m_padMaster->GetDrillShape() );
+
+ wxPoint offset = m_padMaster->GetOffset();
+ offset.y *= isign;
+ m_currentPad->SetOffset( offset );
+
+ m_currentPad->SetPadToDieLength( m_padMaster->GetPadToDieLength() );
+
+ if( m_currentPad->GetLayerSet() != m_padMaster->GetLayerSet() )
+ {
+ rastnestIsChanged = true;
+ m_currentPad->SetLayerSet( m_padMaster->GetLayerSet() );
+ }
+
+ if( m_isFlipped )
+ m_currentPad->SetLayerSet( FlipLayerMask( m_currentPad->GetLayerSet() ) );
+
+ m_currentPad->SetPadName( m_padMaster->GetPadName() );
+
+ wxString padNetname;
+
+ // For PAD_ATTRIB_HOLE_NOT_PLATED, ensure there is no net name selected
+ if( m_padMaster->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
+ padNetname = m_PadNetNameCtrl->GetValue();
+
+ if( m_currentPad->GetNetname() != padNetname )
+ {
+ const NETINFO_ITEM* netinfo = m_board->FindNet( padNetname );
+
+ if( !padNetname.IsEmpty() && netinfo == NULL )
+ {
+ DisplayError( NULL, _( "Unknown netname, netname not changed" ) );
+ }
+ else if( netinfo )
+ {
+ rastnestIsChanged = true;
+ m_currentPad->SetNetCode( netinfo->GetNet() );
+ }
+ }
+
+ m_currentPad->SetLocalClearance( m_padMaster->GetLocalClearance() );
+ m_currentPad->SetLocalSolderMaskMargin( m_padMaster->GetLocalSolderMaskMargin() );
+ m_currentPad->SetLocalSolderPasteMargin( m_padMaster->GetLocalSolderPasteMargin() );
+ m_currentPad->SetLocalSolderPasteMarginRatio( m_padMaster->GetLocalSolderPasteMarginRatio() );
+ m_currentPad->SetZoneConnection( m_padMaster->GetZoneConnection() );
+ m_currentPad->SetThermalWidth( m_padMaster->GetThermalWidth() );
+ m_currentPad->SetThermalGap( m_padMaster->GetThermalGap() );
+
+ module->CalculateBoundingBox();
+ m_parent->SetMsgPanel( m_currentPad );
+
+ // redraw the area where the pad was
+ m_parent->GetCanvas()->RefreshDrawingRect( m_currentPad->GetBoundingBox() );
+ m_parent->OnModify();
+ }
+
+ EndModal( wxID_OK );
+
+ if( rastnestIsChanged ) // The net ratsnest must be recalculated
+ m_board->m_Status_Pcb = 0;
+}
+
+
+bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad )
+{
+ wxString msg;
+ int x, y;
+
+ aPad->SetAttribute( code_type[m_PadType->GetSelection()] );
+ aPad->SetShape( code_shape[m_PadShape->GetSelection()] );
+
+ // Read pad clearances values:
+ aPad->SetLocalClearance( ValueFromTextCtrl( *m_NetClearanceValueCtrl ) );
+ aPad->SetLocalSolderMaskMargin( ValueFromTextCtrl( *m_SolderMaskMarginCtrl ) );
+ aPad->SetLocalSolderPasteMargin( ValueFromTextCtrl( *m_SolderPasteMarginCtrl ) );
+ aPad->SetThermalWidth( ValueFromTextCtrl( *m_ThermalWidthCtrl ) );
+ aPad->SetThermalGap( ValueFromTextCtrl( *m_ThermalGapCtrl ) );
+ double dtmp = 0.0;
+ msg = m_SolderPasteMarginRatioCtrl->GetValue();
+ msg.ToDouble( &dtmp );
+
+ // A -50% margin ratio means no paste on a pad, the ratio must be >= -50%
+ if( dtmp < -50.0 )
+ dtmp = -50.0;
+ // A margin ratio is always <= 0
+ // 0 means use full pad copper area
+ if( dtmp > 0.0 )
+ dtmp = 0.0;
+
+ aPad->SetLocalSolderPasteMarginRatio( dtmp / 100 );
+
+ switch( m_ZoneConnectionChoice->GetSelection() )
+ {
+ default:
+ case 0:
+ aPad->SetZoneConnection( PAD_ZONE_CONN_INHERITED );
+ break;
+
+ case 1:
+ aPad->SetZoneConnection( PAD_ZONE_CONN_FULL );
+ break;
+
+ case 2:
+ aPad->SetZoneConnection( PAD_ZONE_CONN_THERMAL );
+ break;
+
+ case 3:
+ aPad->SetZoneConnection( PAD_ZONE_CONN_NONE );
+ break;
+ }
+
+ // Read pad position:
+ x = ValueFromTextCtrl( *m_PadPosition_X_Ctrl );
+ y = ValueFromTextCtrl( *m_PadPosition_Y_Ctrl );
+
+ aPad->SetPosition( wxPoint( x, y ) );
+ aPad->SetPos0( wxPoint( x, y ) );
+
+ // Read pad drill:
+ x = ValueFromTextCtrl( *m_PadDrill_X_Ctrl );
+ y = ValueFromTextCtrl( *m_PadDrill_Y_Ctrl );
+
+ if( m_DrillShapeCtrl->GetSelection() == 0 )
+ {
+ aPad->SetDrillShape( PAD_DRILL_SHAPE_CIRCLE );
+ y = x;
+ }
+ else
+ aPad->SetDrillShape( PAD_DRILL_SHAPE_OBLONG );
+
+ aPad->SetDrillSize( wxSize( x, y ) );
+
+ // Read pad shape size:
+ x = ValueFromTextCtrl( *m_ShapeSize_X_Ctrl );
+ y = ValueFromTextCtrl( *m_ShapeSize_Y_Ctrl );
+ if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
+ y = x;
+
+ aPad->SetSize( wxSize( x, y ) );
+
+ // Read pad length die
+ aPad->SetPadToDieLength( ValueFromTextCtrl( *m_LengthPadToDieCtrl ) );
+
+ // For a trapezoid, test delta value (be sure delta is not too large for pad size)
+ // remember DeltaSize.x is the Y size variation
+ bool error = false;
+
+ if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID )
+ {
+ wxSize delta;
+
+ // For a trapezoid, only one of delta.x or delta.y is not 0, depending on
+ // the direction.
+ if( m_trapDeltaDirChoice->GetSelection() == 0 )
+ delta.x = ValueFromTextCtrl( *m_ShapeDelta_Ctrl );
+ else
+ delta.y = ValueFromTextCtrl( *m_ShapeDelta_Ctrl );
+
+ if( delta.x < 0 && delta.x <= -aPad->GetSize().y )
+ {
+ delta.x = -aPad->GetSize().y + 2;
+ error = true;
+ }
+
+ if( delta.x > 0 && delta.x >= aPad->GetSize().y )
+ {
+ delta.x = aPad->GetSize().y - 2;
+ error = true;
+ }
+
+ if( delta.y < 0 && delta.y <= -aPad->GetSize().x )
+ {
+ delta.y = -aPad->GetSize().x + 2;
+ error = true;
+ }
+
+ if( delta.y > 0 && delta.y >= aPad->GetSize().x )
+ {
+ delta.y = aPad->GetSize().x - 2;
+ error = true;
+ }
+
+ aPad->SetDelta( delta );
+ }
+
+ // Read pad shape offset:
+ x = ValueFromTextCtrl( *m_ShapeOffset_X_Ctrl );
+ y = ValueFromTextCtrl( *m_ShapeOffset_Y_Ctrl );
+ aPad->SetOffset( wxPoint( x, y ) );
+
+ double orient_value = 0;
+ msg = m_PadOrientCtrl->GetValue();
+ msg.ToDouble( &orient_value );
+
+ aPad->SetOrientation( orient_value );
+
+ msg = m_PadNumCtrl->GetValue().Left( 4 );
+ aPad->SetPadName( msg );
+
+ // Check if user has set an existing net name
+ const NETINFO_ITEM* netinfo = m_board->FindNet( m_PadNetNameCtrl->GetValue() );
+
+ if( netinfo != NULL )
+ aPad->SetNetCode( netinfo->GetNet() );
+ else
+ aPad->SetNetCode( NETINFO_LIST::UNCONNECTED );
+
+ // Clear some values, according to the pad type and shape
+ switch( aPad->GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+ aPad->SetOffset( wxPoint( 0, 0 ) );
+ aPad->SetDelta( wxSize( 0, 0 ) );
+ x = aPad->GetSize().x;
+ aPad->SetSize( wxSize( x, x ) );
+ break;
+
+ case PAD_SHAPE_RECT:
+ aPad->SetDelta( wxSize( 0, 0 ) );
+ break;
+
+ case PAD_SHAPE_OVAL:
+ aPad->SetDelta( wxSize( 0, 0 ) );
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ break;
+
+ default:
+ ;
+ }
+
+ switch( aPad->GetAttribute() )
+ {
+ case PAD_ATTRIB_STANDARD:
+ break;
+
+ case PAD_ATTRIB_CONN:
+ case PAD_ATTRIB_SMD:
+ // SMD and PAD_ATTRIB_CONN has no hole.
+ // basically, SMD and PAD_ATTRIB_CONN are same type of pads
+ // PAD_ATTRIB_CONN has just a default non technical layers that differs from SMD
+ // and are intended to be used in virtual edge board connectors
+ // However we can accept a non null offset,
+ // mainly to allow complex pads build from a set of from basic pad shapes
+ aPad->SetDrillSize( wxSize( 0, 0 ) );
+ break;
+
+ case PAD_ATTRIB_HOLE_NOT_PLATED:
+ // Mechanical purpose only:
+ // no offset, no net name, no pad name allowed
+ aPad->SetOffset( wxPoint( 0, 0 ) );
+ aPad->SetPadName( wxEmptyString );
+ aPad->SetNetCode( NETINFO_LIST::UNCONNECTED );
+ break;
+
+ default:
+ DisplayError( NULL, wxT( "Error: unknown pad type" ) );
+ break;
+ }
+
+ LSET padLayerMask;
+
+ switch( m_rbCopperLayersSel->GetSelection() )
+ {
+ case 0:
+ padLayerMask.set( F_Cu );
+ break;
+
+ case 1:
+ padLayerMask.set( B_Cu );
+ break;
+
+ case 2:
+ padLayerMask |= LSET::AllCuMask();
+ break;
+
+ case 3: // No copper layers
+ break;
+ }
+
+ if( m_PadLayerAdhCmp->GetValue() )
+ padLayerMask.set( F_Adhes );
+
+ if( m_PadLayerAdhCu->GetValue() )
+ padLayerMask.set( B_Adhes );
+
+ if( m_PadLayerPateCmp->GetValue() )
+ padLayerMask.set( F_Paste );
+
+ if( m_PadLayerPateCu->GetValue() )
+ padLayerMask.set( B_Paste );
+
+ if( m_PadLayerSilkCmp->GetValue() )
+ padLayerMask.set( F_SilkS );
+
+ if( m_PadLayerSilkCu->GetValue() )
+ padLayerMask.set( B_SilkS );
+
+ if( m_PadLayerMaskCmp->GetValue() )
+ padLayerMask.set( F_Mask );
+
+ if( m_PadLayerMaskCu->GetValue() )
+ padLayerMask.set( B_Mask );
+
+ if( m_PadLayerECO1->GetValue() )
+ padLayerMask.set( Eco1_User );
+
+ if( m_PadLayerECO2->GetValue() )
+ padLayerMask.set( Eco2_User );
+
+ if( m_PadLayerDraft->GetValue() )
+ padLayerMask.set( Dwgs_User );
+
+ aPad->SetLayerSet( padLayerMask );
+
+ return error;
+}
+
+
+void DIALOG_PAD_PROPERTIES::OnValuesChanged( wxCommandEvent& event )
+{
+ if( m_canUpdate )
+ {
+ transferDataToPad( m_dummyPad );
+ redraw();
+ }
+}
+
+
+void DIALOG_PAD_PROPERTIES::OnCancelButtonClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
diff --git a/pcbnew/dialogs/dialog_pad_properties_base.cpp b/pcbnew/dialogs/dialog_pad_properties_base.cpp
new file mode 100644
index 0000000..1a03533
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pad_properties_base.cpp
@@ -0,0 +1,640 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_pad_properties_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* m_MainSizer;
+ m_MainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxHORIZONTAL );
+
+ m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+ m_notebook->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
+
+ m_panelGeneral = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* bGeneralSizer;
+ bGeneralSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* m_LeftBoxSizer;
+ m_LeftBoxSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizerPadType;
+ fgSizerPadType = new wxFlexGridSizer( 4, 2, 0, 0 );
+ fgSizerPadType->AddGrowableCol( 1 );
+ fgSizerPadType->SetFlexibleDirection( wxBOTH );
+ fgSizerPadType->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_PadNumText = new wxStaticText( m_panelGeneral, wxID_ANY, _("Pad number:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadNumText->Wrap( -1 );
+ fgSizerPadType->Add( m_PadNumText, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_PadNumCtrl = new wxTextCtrl( m_panelGeneral, wxID_PADNUMCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadNumCtrl->SetMaxLength( 0 );
+ fgSizerPadType->Add( m_PadNumCtrl, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_PadNameText = new wxStaticText( m_panelGeneral, wxID_ANY, _("Net name:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadNameText->Wrap( -1 );
+ fgSizerPadType->Add( m_PadNameText, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_PadNetNameCtrl = new wxTextCtrl( m_panelGeneral, wxID_PADNETNAMECTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadNetNameCtrl->SetMaxLength( 0 );
+ fgSizerPadType->Add( m_PadNetNameCtrl, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText44 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Pad type:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText44->Wrap( -1 );
+ fgSizerPadType->Add( m_staticText44, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ wxString m_PadTypeChoices[] = { _("Through-hole"), _("SMD"), _("Connector"), _("NPTH, Mechanical") };
+ int m_PadTypeNChoices = sizeof( m_PadTypeChoices ) / sizeof( wxString );
+ m_PadType = new wxChoice( m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_PadTypeNChoices, m_PadTypeChoices, 0 );
+ m_PadType->SetSelection( 0 );
+ fgSizerPadType->Add( m_PadType, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText45 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Shape:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText45->Wrap( -1 );
+ fgSizerPadType->Add( m_staticText45, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ wxString m_PadShapeChoices[] = { _("Circular"), _("Oval"), _("Rectangular"), _("Trapezoidal") };
+ int m_PadShapeNChoices = sizeof( m_PadShapeChoices ) / sizeof( wxString );
+ m_PadShape = new wxChoice( m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_PadShapeNChoices, m_PadShapeChoices, 0 );
+ m_PadShape->SetSelection( 0 );
+ fgSizerPadType->Add( m_PadShape, 0, wxALL|wxEXPAND, 5 );
+
+
+ m_LeftBoxSizer->Add( fgSizerPadType, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxFlexGridSizer* fgSizerShapeType;
+ fgSizerShapeType = new wxFlexGridSizer( 11, 3, 0, 0 );
+ fgSizerShapeType->AddGrowableCol( 1 );
+ fgSizerShapeType->SetFlexibleDirection( wxBOTH );
+ fgSizerShapeType->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText4 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Position X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText4->Wrap( -1 );
+ fgSizerShapeType->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_PadPosition_X_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadPosition_X_Ctrl->SetMaxLength( 0 );
+ fgSizerShapeType->Add( m_PadPosition_X_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_PadPosX_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadPosX_Unit->Wrap( -1 );
+ fgSizerShapeType->Add( m_PadPosX_Unit, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText41 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Position Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText41->Wrap( -1 );
+ fgSizerShapeType->Add( m_staticText41, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_PadPosition_Y_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadPosition_Y_Ctrl->SetMaxLength( 0 );
+ fgSizerShapeType->Add( m_PadPosition_Y_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_PadPosY_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadPosY_Unit->Wrap( -1 );
+ fgSizerShapeType->Add( m_PadPosY_Unit, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText12 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Size X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText12->Wrap( -1 );
+ fgSizerShapeType->Add( m_staticText12, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_ShapeSize_X_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ShapeSize_X_Ctrl->SetMaxLength( 0 );
+ fgSizerShapeType->Add( m_ShapeSize_X_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_PadShapeSizeX_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadShapeSizeX_Unit->Wrap( -1 );
+ fgSizerShapeType->Add( m_PadShapeSizeX_Unit, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText15 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Size Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText15->Wrap( -1 );
+ fgSizerShapeType->Add( m_staticText15, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_ShapeSize_Y_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ShapeSize_Y_Ctrl->SetMaxLength( 0 );
+ fgSizerShapeType->Add( m_ShapeSize_Y_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_PadShapeSizeY_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadShapeSizeY_Unit->Wrap( -1 );
+ fgSizerShapeType->Add( m_PadShapeSizeY_Unit, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText48 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Orientation:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText48->Wrap( -1 );
+ fgSizerShapeType->Add( m_staticText48, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ wxString m_PadOrientChoices[] = { _("0"), _("90"), _("-90"), _("180"), _("Custom") };
+ int m_PadOrientNChoices = sizeof( m_PadOrientChoices ) / sizeof( wxString );
+ m_PadOrient = new wxChoice( m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_PadOrientNChoices, m_PadOrientChoices, 0 );
+ m_PadOrient->SetSelection( 4 );
+ fgSizerShapeType->Add( m_PadOrient, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_staticText491 = new wxStaticText( m_panelGeneral, wxID_ANY, _("deg"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText491->Wrap( -1 );
+ fgSizerShapeType->Add( m_staticText491, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_PadOrientText = new wxStaticText( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadOrientText->Wrap( -1 );
+ fgSizerShapeType->Add( m_PadOrientText, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_PadOrientCtrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadOrientCtrl->SetMaxLength( 0 );
+ fgSizerShapeType->Add( m_PadOrientCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_customOrientUnits = new wxStaticText( m_panelGeneral, wxID_ANY, _("0.1 deg"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_customOrientUnits->Wrap( -1 );
+ fgSizerShapeType->Add( m_customOrientUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText17 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Shape offset X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText17->Wrap( -1 );
+ fgSizerShapeType->Add( m_staticText17, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_ShapeOffset_X_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ShapeOffset_X_Ctrl->SetMaxLength( 0 );
+ fgSizerShapeType->Add( m_ShapeOffset_X_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_PadShapeOffsetX_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadShapeOffsetX_Unit->Wrap( -1 );
+ fgSizerShapeType->Add( m_PadShapeOffsetX_Unit, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText19 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Shape offset Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText19->Wrap( -1 );
+ fgSizerShapeType->Add( m_staticText19, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_ShapeOffset_Y_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ShapeOffset_Y_Ctrl->SetMaxLength( 0 );
+ fgSizerShapeType->Add( m_ShapeOffset_Y_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_PadShapeOffsetY_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadShapeOffsetY_Unit->Wrap( -1 );
+ fgSizerShapeType->Add( m_PadShapeOffsetY_Unit, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText38 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Pad to die length:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText38->Wrap( -1 );
+ m_staticText38->SetToolTip( _("Wire length from pad to die on chip ( used to calculate actual track length)") );
+
+ fgSizerShapeType->Add( m_staticText38, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_LengthPadToDieCtrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_LengthPadToDieCtrl->SetMaxLength( 0 );
+ fgSizerShapeType->Add( m_LengthPadToDieCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_PadLengthDie_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadLengthDie_Unit->Wrap( -1 );
+ fgSizerShapeType->Add( m_PadLengthDie_Unit, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText21 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Trapezoid delta:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText21->Wrap( -1 );
+ fgSizerShapeType->Add( m_staticText21, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT, 5 );
+
+ m_ShapeDelta_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ShapeDelta_Ctrl->SetMaxLength( 0 );
+ fgSizerShapeType->Add( m_ShapeDelta_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_PadShapeDelta_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadShapeDelta_Unit->Wrap( -1 );
+ fgSizerShapeType->Add( m_PadShapeDelta_Unit, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText23 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Trapezoid direction:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText23->Wrap( -1 );
+ fgSizerShapeType->Add( m_staticText23, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ wxString m_trapDeltaDirChoiceChoices[] = { _("Horiz."), _("Vert.") };
+ int m_trapDeltaDirChoiceNChoices = sizeof( m_trapDeltaDirChoiceChoices ) / sizeof( wxString );
+ m_trapDeltaDirChoice = new wxChoice( m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_trapDeltaDirChoiceNChoices, m_trapDeltaDirChoiceChoices, 0 );
+ m_trapDeltaDirChoice->SetSelection( 0 );
+ fgSizerShapeType->Add( m_trapDeltaDirChoice, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_staticText521 = new wxStaticText( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText521->Wrap( -1 );
+ fgSizerShapeType->Add( m_staticText521, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_LeftBoxSizer->Add( fgSizerShapeType, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbSizeModuleInfo;
+ sbSizeModuleInfo = new wxStaticBoxSizer( new wxStaticBox( m_panelGeneral, wxID_ANY, _("Parent footprint orientation") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer4;
+ fgSizer4 = new wxFlexGridSizer( 2, 2, 0, 0 );
+ fgSizer4->AddGrowableCol( 1 );
+ fgSizer4->SetFlexibleDirection( wxBOTH );
+ fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticTitleModuleRot = new wxStaticText( m_panelGeneral, wxID_ANY, _("Rotation:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTitleModuleRot->Wrap( -1 );
+ fgSizer4->Add( m_staticTitleModuleRot, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_staticModuleRotValue = new wxStaticText( m_panelGeneral, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticModuleRotValue->Wrap( -1 );
+ fgSizer4->Add( m_staticModuleRotValue, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticTitleModuleSide = new wxStaticText( m_panelGeneral, wxID_ANY, _("Board side:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTitleModuleSide->Wrap( -1 );
+ fgSizer4->Add( m_staticTitleModuleSide, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_staticModuleSideValue = new wxStaticText( m_panelGeneral, wxID_ANY, _("Front side"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticModuleSideValue->Wrap( -1 );
+ fgSizer4->Add( m_staticModuleSideValue, 0, wxALL|wxEXPAND, 5 );
+
+
+ sbSizeModuleInfo->Add( fgSizer4, 0, 0, 5 );
+
+
+ m_LeftBoxSizer->Add( sbSizeModuleInfo, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ bGeneralSizer->Add( m_LeftBoxSizer, 3, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer10;
+ bSizer10 = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbSizer2;
+ sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( m_panelGeneral, wxID_ANY, _("Drill") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgSizerGeometry;
+ fgSizerGeometry = new wxFlexGridSizer( 14, 3, 0, 0 );
+ fgSizerGeometry->AddGrowableCol( 1 );
+ fgSizerGeometry->SetFlexibleDirection( wxBOTH );
+ fgSizerGeometry->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText47 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Shape:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText47->Wrap( -1 );
+ fgSizerGeometry->Add( m_staticText47, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ wxString m_DrillShapeCtrlChoices[] = { _("Circular hole"), _("Oval hole") };
+ int m_DrillShapeCtrlNChoices = sizeof( m_DrillShapeCtrlChoices ) / sizeof( wxString );
+ m_DrillShapeCtrl = new wxChoice( m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_DrillShapeCtrlNChoices, m_DrillShapeCtrlChoices, 0 );
+ m_DrillShapeCtrl->SetSelection( 0 );
+ fgSizerGeometry->Add( m_DrillShapeCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_staticText51 = new wxStaticText( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText51->Wrap( -1 );
+ fgSizerGeometry->Add( m_staticText51, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_textPadDrillX = new wxStaticText( m_panelGeneral, wxID_ANY, _("Size X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_textPadDrillX->Wrap( -1 );
+ fgSizerGeometry->Add( m_textPadDrillX, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_PadDrill_X_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadDrill_X_Ctrl->SetMaxLength( 0 );
+ fgSizerGeometry->Add( m_PadDrill_X_Ctrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_PadDrill_X_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadDrill_X_Unit->Wrap( -1 );
+ fgSizerGeometry->Add( m_PadDrill_X_Unit, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_textPadDrillY = new wxStaticText( m_panelGeneral, wxID_ANY, _("Size Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_textPadDrillY->Wrap( -1 );
+ fgSizerGeometry->Add( m_textPadDrillY, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_PadDrill_Y_Ctrl = new wxTextCtrl( m_panelGeneral, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadDrill_Y_Ctrl->SetMaxLength( 0 );
+ fgSizerGeometry->Add( m_PadDrill_Y_Ctrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_PadDrill_Y_Unit = new wxStaticText( m_panelGeneral, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PadDrill_Y_Unit->Wrap( -1 );
+ fgSizerGeometry->Add( m_PadDrill_Y_Unit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ sbSizer2->Add( fgSizerGeometry, 0, wxEXPAND, 5 );
+
+
+ bSizer10->Add( sbSizer2, 0, wxALL|wxEXPAND, 5 );
+
+ wxStaticBoxSizer* m_LayersSizer;
+ m_LayersSizer = new wxStaticBoxSizer( new wxStaticBox( m_panelGeneral, wxID_ANY, _("Layers") ), wxVERTICAL );
+
+ wxBoxSizer* bSizer11;
+ bSizer11 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_staticText511 = new wxStaticText( m_panelGeneral, wxID_ANY, _("Copper:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText511->Wrap( -1 );
+ bSizer11->Add( m_staticText511, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ wxString m_rbCopperLayersSelChoices[] = { _("Front layer"), _("Back layer"), _("All copper layers"), _("None") };
+ int m_rbCopperLayersSelNChoices = sizeof( m_rbCopperLayersSelChoices ) / sizeof( wxString );
+ m_rbCopperLayersSel = new wxChoice( m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_rbCopperLayersSelNChoices, m_rbCopperLayersSelChoices, 0 );
+ m_rbCopperLayersSel->SetSelection( 0 );
+ bSizer11->Add( m_rbCopperLayersSel, 1, wxALL|wxEXPAND, 5 );
+
+
+ m_LayersSizer->Add( bSizer11, 0, wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbSizerTechlayers;
+ sbSizerTechlayers = new wxStaticBoxSizer( new wxStaticBox( m_panelGeneral, wxID_ANY, _("Technical Layers") ), wxVERTICAL );
+
+ m_PadLayerAdhCmp = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Front adhesive"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerTechlayers->Add( m_PadLayerAdhCmp, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PadLayerAdhCu = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Back adhesive"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerTechlayers->Add( m_PadLayerAdhCu, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PadLayerPateCmp = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Front solder paste"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerTechlayers->Add( m_PadLayerPateCmp, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PadLayerPateCu = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Back solder paste"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerTechlayers->Add( m_PadLayerPateCu, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PadLayerSilkCmp = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Front silk screen"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerTechlayers->Add( m_PadLayerSilkCmp, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PadLayerSilkCu = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Back silk screen"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerTechlayers->Add( m_PadLayerSilkCu, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PadLayerMaskCmp = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Front solder mask"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerTechlayers->Add( m_PadLayerMaskCmp, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PadLayerMaskCu = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Back solder mask"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerTechlayers->Add( m_PadLayerMaskCu, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PadLayerDraft = new wxCheckBox( m_panelGeneral, wxID_ANY, _("Drafting notes"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerTechlayers->Add( m_PadLayerDraft, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PadLayerECO1 = new wxCheckBox( m_panelGeneral, wxID_ANY, _("E.C.O.1"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerTechlayers->Add( m_PadLayerECO1, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_PadLayerECO2 = new wxCheckBox( m_panelGeneral, wxID_ANY, _("E.C.O.2"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizerTechlayers->Add( m_PadLayerECO2, 0, wxALL, 5 );
+
+
+ m_LayersSizer->Add( sbSizerTechlayers, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizer10->Add( m_LayersSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ bGeneralSizer->Add( bSizer10, 2, wxALL|wxEXPAND, 5 );
+
+
+ m_panelGeneral->SetSizer( bGeneralSizer );
+ m_panelGeneral->Layout();
+ bGeneralSizer->Fit( m_panelGeneral );
+ m_notebook->AddPage( m_panelGeneral, _("General"), true );
+ m_localSettingsPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ wxBoxSizer* bSizerPanelClearance;
+ bSizerPanelClearance = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerClearance;
+ bSizerClearance = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbClearancesSizer;
+ sbClearancesSizer = new wxStaticBoxSizer( new wxStaticBox( m_localSettingsPanel, wxID_ANY, _("Clearances") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgClearancesGridSizer;
+ fgClearancesGridSizer = new wxFlexGridSizer( 4, 3, 0, 0 );
+ fgClearancesGridSizer->AddGrowableCol( 1 );
+ fgClearancesGridSizer->SetFlexibleDirection( wxBOTH );
+ fgClearancesGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticTextNetClearance = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Net pad clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextNetClearance->Wrap( -1 );
+ m_staticTextNetClearance->SetToolTip( _("This is the local net clearance for pad.\nIf 0, the footprint local value or the Netclass value is used") );
+
+ fgClearancesGridSizer->Add( m_staticTextNetClearance, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_NetClearanceValueCtrl = new wxTextCtrl( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_NetClearanceValueCtrl->SetMaxLength( 0 );
+ fgClearancesGridSizer->Add( m_NetClearanceValueCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_NetClearanceUnits = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_NetClearanceUnits->Wrap( -1 );
+ fgClearancesGridSizer->Add( m_NetClearanceUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_MaskClearanceTitle = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Solder mask clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_MaskClearanceTitle->Wrap( -1 );
+ m_MaskClearanceTitle->SetToolTip( _("This is the local clearance between this pad and the solder mask\nIf 0, the footprint local value or the global value is used") );
+
+ fgClearancesGridSizer->Add( m_MaskClearanceTitle, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_SolderMaskMarginCtrl = new wxTextCtrl( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMarginCtrl->SetMaxLength( 0 );
+ fgClearancesGridSizer->Add( m_SolderMaskMarginCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_SolderMaskMarginUnits = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMarginUnits->Wrap( -1 );
+ fgClearancesGridSizer->Add( m_SolderMaskMarginUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticTextSolderPaste = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Solder paste clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSolderPaste->Wrap( -1 );
+ m_staticTextSolderPaste->SetToolTip( _("This is the local clearance between this pad and the solder paste.\nIf 0 the footprint value or the global value is used..\nThe final clearance value is the sum of this value and the clearance value ratio\nA negative value means a smaller mask size than pad size") );
+
+ fgClearancesGridSizer->Add( m_staticTextSolderPaste, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_SolderPasteMarginCtrl = new wxTextCtrl( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginCtrl->SetMaxLength( 0 );
+ fgClearancesGridSizer->Add( m_SolderPasteMarginCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_SolderPasteMarginUnits = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginUnits->Wrap( -1 );
+ fgClearancesGridSizer->Add( m_SolderPasteMarginUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticTextRatio = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Solder paste ratio clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextRatio->Wrap( -1 );
+ m_staticTextRatio->SetToolTip( _("This is the local clearance ratio in per cent between this pad and the solder paste.\nA value of 10 means the clearance value is 10 per cent of the pad size\nIf 0 the footprint value or the global value is used..\nThe final clearance value is the sum of this value and the clearance value\nA negative value means a smaller mask size than pad size.") );
+
+ fgClearancesGridSizer->Add( m_staticTextRatio, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_SolderPasteMarginRatioCtrl = new wxTextCtrl( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteMarginRatioCtrl->SetMaxLength( 0 );
+ fgClearancesGridSizer->Add( m_SolderPasteMarginRatioCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_SolderPasteRatioMarginUnits = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderPasteRatioMarginUnits->Wrap( -1 );
+ fgClearancesGridSizer->Add( m_SolderPasteRatioMarginUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ sbClearancesSizer->Add( fgClearancesGridSizer, 0, wxEXPAND, 5 );
+
+
+ bSizerClearance->Add( sbClearancesSizer, 0, wxALL|wxEXPAND, 5 );
+
+ wxStaticBoxSizer* sbSizerZonesSettings;
+ sbSizerZonesSettings = new wxStaticBoxSizer( new wxStaticBox( m_localSettingsPanel, wxID_ANY, _("Copper Zones") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer41;
+ fgSizer41 = new wxFlexGridSizer( 3, 3, 0, 0 );
+ fgSizer41->AddGrowableCol( 1 );
+ fgSizer41->SetFlexibleDirection( wxBOTH );
+ fgSizer41->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText40 = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Pad connection:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText40->Wrap( -1 );
+ fgSizer41->Add( m_staticText40, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ wxString m_ZoneConnectionChoiceChoices[] = { _("From parent footprint"), _("Solid"), _("Thermal relief"), _("None") };
+ int m_ZoneConnectionChoiceNChoices = sizeof( m_ZoneConnectionChoiceChoices ) / sizeof( wxString );
+ m_ZoneConnectionChoice = new wxChoice( m_localSettingsPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_ZoneConnectionChoiceNChoices, m_ZoneConnectionChoiceChoices, 0 );
+ m_ZoneConnectionChoice->SetSelection( 0 );
+ fgSizer41->Add( m_ZoneConnectionChoice, 0, wxLEFT|wxTOP|wxEXPAND, 5 );
+
+ m_staticText53 = new wxStaticText( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText53->Wrap( -1 );
+ fgSizer41->Add( m_staticText53, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText49 = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Thermal relief width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText49->Wrap( -1 );
+ fgSizer41->Add( m_staticText49, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
+
+ m_ThermalWidthCtrl = new wxTextCtrl( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ThermalWidthCtrl->SetMaxLength( 0 );
+ fgSizer41->Add( m_ThermalWidthCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_ThermalWidthUnits = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ThermalWidthUnits->Wrap( -1 );
+ fgSizer41->Add( m_ThermalWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticText52 = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Thermal relief gap:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText52->Wrap( -1 );
+ fgSizer41->Add( m_staticText52, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_ThermalGapCtrl = new wxTextCtrl( m_localSettingsPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ThermalGapCtrl->SetMaxLength( 0 );
+ fgSizer41->Add( m_ThermalGapCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_ThermalGapUnits = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Inch"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ThermalGapUnits->Wrap( -1 );
+ fgSizer41->Add( m_ThermalGapUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ sbSizerZonesSettings->Add( fgSizer41, 0, wxEXPAND, 5 );
+
+
+ bSizerClearance->Add( sbSizerZonesSettings, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticTextWarning = new wxStaticText( m_localSettingsPanel, wxID_ANY, _("Set fields to 0 to use parent or global values"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextWarning->Wrap( -1 );
+ m_staticTextWarning->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizerClearance->Add( m_staticTextWarning, 0, wxALL, 5 );
+
+
+ bSizerPanelClearance->Add( bSizerClearance, 0, wxALL|wxEXPAND, 5 );
+
+
+ m_localSettingsPanel->SetSizer( bSizerPanelClearance );
+ m_localSettingsPanel->Layout();
+ bSizerPanelClearance->Fit( m_localSettingsPanel );
+ m_notebook->AddPage( m_localSettingsPanel, _("Local Clearance and Settings"), false );
+
+ bSizerUpper->Add( m_notebook, 0, wxALL, 5 );
+
+ wxBoxSizer* bSizerDisplayPad;
+ bSizerDisplayPad = new wxBoxSizer( wxVERTICAL );
+
+ bSizerDisplayPad->SetMinSize( wxSize( 200,-1 ) );
+ m_panelShowPad = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxSize( 200,-1 ), wxFULL_REPAINT_ON_RESIZE|wxSIMPLE_BORDER );
+ m_panelShowPad->SetBackgroundColour( wxColour( 0, 0, 0 ) );
+
+ bSizerDisplayPad->Add( m_panelShowPad, 4, wxRIGHT|wxTOP|wxEXPAND, 5 );
+
+ m_panelShowPadGal = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), wxDefaultSize, EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO );
+ bSizerDisplayPad->Add( m_panelShowPadGal, 4, wxEXPAND|wxRIGHT|wxTOP, 5 );
+
+
+ bSizerUpper->Add( bSizerDisplayPad, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+
+ m_MainSizer->Add( bSizerUpper, 1, wxEXPAND, 5 );
+
+ m_staticTextWarningPadFlipped = new wxStaticText( this, wxID_ANY, _("Warning:\nThis pad is flipped on board.\nBack and front layers will be swapped."), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextWarningPadFlipped->Wrap( -1 );
+ m_staticTextWarningPadFlipped->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ m_MainSizer->Add( m_staticTextWarningPadFlipped, 0, wxALL, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ m_MainSizer->Add( m_sdbSizer1, 0, wxALIGN_RIGHT|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ this->SetSizer( m_MainSizer );
+ this->Layout();
+ m_MainSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_PadNumCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_PadNetNameCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_PadType->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadTypeSelected ), NULL, this );
+ m_PadShape->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnPadShapeSelection ), NULL, this );
+ m_ShapeSize_X_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_ShapeSize_Y_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_PadOrient->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadOrientEvent ), NULL, this );
+ m_PadOrientCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_ShapeOffset_X_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_ShapeOffset_Y_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_ShapeDelta_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_trapDeltaDirChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_DrillShapeCtrl->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnDrillShapeSelected ), NULL, this );
+ m_PadDrill_X_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_PadDrill_Y_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_rbCopperLayersSel->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerAdhCmp->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerAdhCu->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerPateCmp->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerPateCu->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerSilkCmp->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerSilkCu->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerMaskCmp->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerMaskCu->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerDraft->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerECO1->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerECO2->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_NetClearanceValueCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_panelShowPad->Connect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnPaintShowPanel ), NULL, this );
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnCancelButtonClick ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadPropertiesAccept ), NULL, this );
+}
+
+DIALOG_PAD_PROPERTIES_BASE::~DIALOG_PAD_PROPERTIES_BASE()
+{
+ // Disconnect Events
+ m_PadNumCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_PadNetNameCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_PadType->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadTypeSelected ), NULL, this );
+ m_PadShape->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnPadShapeSelection ), NULL, this );
+ m_ShapeSize_X_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_ShapeSize_Y_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_PadOrient->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadOrientEvent ), NULL, this );
+ m_PadOrientCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_ShapeOffset_X_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_ShapeOffset_Y_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_ShapeDelta_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_trapDeltaDirChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_DrillShapeCtrl->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnDrillShapeSelected ), NULL, this );
+ m_PadDrill_X_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_PadDrill_Y_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_rbCopperLayersSel->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerAdhCmp->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerAdhCu->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerPateCmp->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerPateCu->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerSilkCmp->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerSilkCu->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerMaskCmp->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerMaskCu->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerDraft->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerECO1->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_PadLayerECO2->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
+ m_NetClearanceValueCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
+ m_panelShowPad->Disconnect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnPaintShowPanel ), NULL, this );
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnCancelButtonClick ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadPropertiesAccept ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_pad_properties_base.fbp b/pcbnew/dialogs/dialog_pad_properties_base.fbp
new file mode 100644
index 0000000..07c6e0c
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pad_properties_base.fbp
@@ -0,0 +1,8516 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_pad_properties_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_pad_properties_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_DIALOG_EDIT_PAD</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_PAD_PROPERTIES_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Pad Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxSUNKEN_BORDER</property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_MainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxNotebook" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">wxSYS_COLOUR_BTNFACE</property>
+ <property name="bitmapsize"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_notebook</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnNotebookPageChanged"></event>
+ <event name="OnNotebookPageChanging"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">General</property>
+ <property name="select">1</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_panelGeneral</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bGeneralSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">3</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">m_LeftBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerPadType</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">4</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad number:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadNumText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PADNUMCTRL</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadNumCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnValuesChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Net name:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadNameText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PADNETNAMECTRL</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadNetNameCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnValuesChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad type:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText44</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Through-hole&quot; &quot;SMD&quot; &quot;Connector&quot; &quot;NPTH, Mechanical&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadType</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">PadTypeSelected</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Shape:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText45</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Circular&quot; &quot;Oval&quot; &quot;Rectangular&quot; &quot;Trapezoidal&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadShape</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">OnPadShapeSelection</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerShapeType</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">11</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Position X:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadPosition_X_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadPosX_Unit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Position Y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText41</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadPosition_Y_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadPosY_Unit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Size X:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText12</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShapeSize_X_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnValuesChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadShapeSizeX_Unit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Size Y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText15</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShapeSize_Y_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnValuesChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadShapeSizeY_Unit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Orientation:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText48</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;0&quot; &quot;90&quot; &quot;-90&quot; &quot;180&quot; &quot;Custom&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadOrient</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">4</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">PadOrientEvent</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">deg</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText491</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadOrientText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadOrientCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnValuesChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">0.1 deg</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_customOrientUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Shape offset X:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText17</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShapeOffset_X_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnValuesChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadShapeOffsetX_Unit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Shape offset Y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText19</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShapeOffset_Y_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnValuesChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadShapeOffsetY_Unit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad to die length:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText38</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Wire length from pad to die on chip ( used to calculate actual track length)</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LengthPadToDieCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadLengthDie_Unit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Trapezoid delta:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText21</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ShapeDelta_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnValuesChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadShapeDelta_Unit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Trapezoid direction:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText23</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Horiz.&quot; &quot;Vert.&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_trapDeltaDirChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText521</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Parent footprint orientation</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizeModuleInfo</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer4</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">2</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Rotation:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTitleModuleRot</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">0</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticModuleRotValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Board side:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTitleModuleSide</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Front side</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticModuleSideValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">2</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer10</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Drill</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizer2</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerGeometry</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">14</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Shape:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText47</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Circular hole&quot; &quot;Oval hole&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DrillShapeCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">OnDrillShapeSelected</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText51</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Size X:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textPadDrillX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadDrill_X_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnValuesChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadDrill_X_Unit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Size Y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textPadDrillY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadDrill_Y_Ctrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnValuesChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadDrill_Y_Unit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layers</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_LayersSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer11</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Copper:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText511</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Front layer&quot; &quot;Back layer&quot; &quot;All copper layers&quot; &quot;None&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbCopperLayersSel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Technical Layers</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerTechlayers</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Front adhesive</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadLayerAdhCmp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Back adhesive</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadLayerAdhCu</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Front solder paste</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadLayerPateCmp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Back solder paste</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadLayerPateCu</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Front silk screen</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadLayerSilkCmp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Back silk screen</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadLayerSilkCu</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Front solder mask</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadLayerMaskCmp</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Back solder mask</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadLayerMaskCu</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Drafting notes</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadLayerDraft</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">E.C.O.1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadLayerECO1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">E.C.O.2</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PadLayerECO2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnSetLayers</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="notebookpage" expanded="1">
+ <property name="bitmap"></property>
+ <property name="label">Local Clearance and Settings</property>
+ <property name="select">0</property>
+ <object class="wxPanel" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_localSettingsPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerPanelClearance</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerClearance</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Clearances</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbClearancesSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgClearancesGridSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">4</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Net pad clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextNetClearance</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the local net clearance for pad.&#x0A;If 0, the footprint local value or the Netclass value is used</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NetClearanceValueCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnValuesChanged</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_NetClearanceUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder mask clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_MaskClearanceTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the local clearance between this pad and the solder mask&#x0A;If 0, the footprint local value or the global value is used</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderMaskMarginCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderMaskMarginUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder paste clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSolderPaste</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the local clearance between this pad and the solder paste.&#x0A;If 0 the footprint value or the global value is used..&#x0A;The final clearance value is the sum of this value and the clearance value ratio&#x0A;A negative value means a smaller mask size than pad size</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteMarginCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteMarginUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder paste ratio clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextRatio</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">This is the local clearance ratio in per cent between this pad and the solder paste.&#x0A;A value of 10 means the clearance value is 10 per cent of the pad size&#x0A;If 0 the footprint value or the global value is used..&#x0A;The final clearance value is the sum of this value and the clearance value&#x0A;A negative value means a smaller mask size than pad size.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteMarginRatioCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">%</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderPasteRatioMarginUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Copper Zones</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerZonesSettings</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer41</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">3</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pad connection:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText40</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxLEFT|wxTOP|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;From parent footprint&quot; &quot;Solid&quot; &quot;Thermal relief&quot; &quot;None&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ZoneConnectionChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText53</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Thermal relief width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText49</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ThermalWidthCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ThermalWidthUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Thermal relief gap:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText52</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ThermalGapCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inch</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ThermalGapUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Set fields to 0 to use parent or global values</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextWarning</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size">200,-1</property>
+ <property name="name">bSizerDisplayPad</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxTOP|wxEXPAND</property>
+ <property name="proportion">4</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg">0,0,0</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_panelShowPad</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">200,-1</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxFULL_REPAINT_ON_RESIZE|wxSIMPLE_BORDER</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint">OnPaintShowPanel</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxTOP</property>
+ <property name="proportion">4</property>
+ <object class="CustomControl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="class">PCB_DRAW_PANEL_GAL</property>
+ <property name="close_button">1</property>
+ <property name="construction">m_panelShowPadGal = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), wxDefaultSize, EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO );</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="declaration">PCB_DRAW_PANEL_GAL* m_panelShowPadGal;</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="include">#include &lt;pcb_draw_panel_gal.h&gt;</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_panelShowPadGal</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="settings"></property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Warning:&#x0A;This pad is flipped on board.&#x0A;Back and front layers will be swapped.</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextWarningPadFlipped</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelButtonClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">PadPropertiesAccept</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_pad_properties_base.h b/pcbnew/dialogs/dialog_pad_properties_base.h
new file mode 100644
index 0000000..7a2cca8
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pad_properties_base.h
@@ -0,0 +1,172 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_PAD_PROPERTIES_BASE_H__
+#define __DIALOG_PAD_PROPERTIES_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/choice.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/checkbox.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/notebook.h>
+#include <pcb_draw_panel_gal.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PAD_PROPERTIES_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ wxID_DIALOG_EDIT_PAD = 1000,
+ wxID_PADNUMCTRL,
+ wxID_PADNETNAMECTRL
+ };
+
+ wxNotebook* m_notebook;
+ wxPanel* m_panelGeneral;
+ wxStaticText* m_PadNumText;
+ wxTextCtrl* m_PadNumCtrl;
+ wxStaticText* m_PadNameText;
+ wxTextCtrl* m_PadNetNameCtrl;
+ wxStaticText* m_staticText44;
+ wxChoice* m_PadType;
+ wxStaticText* m_staticText45;
+ wxChoice* m_PadShape;
+ wxStaticText* m_staticText4;
+ wxTextCtrl* m_PadPosition_X_Ctrl;
+ wxStaticText* m_PadPosX_Unit;
+ wxStaticText* m_staticText41;
+ wxTextCtrl* m_PadPosition_Y_Ctrl;
+ wxStaticText* m_PadPosY_Unit;
+ wxStaticText* m_staticText12;
+ wxTextCtrl* m_ShapeSize_X_Ctrl;
+ wxStaticText* m_PadShapeSizeX_Unit;
+ wxStaticText* m_staticText15;
+ wxTextCtrl* m_ShapeSize_Y_Ctrl;
+ wxStaticText* m_PadShapeSizeY_Unit;
+ wxStaticText* m_staticText48;
+ wxChoice* m_PadOrient;
+ wxStaticText* m_staticText491;
+ wxStaticText* m_PadOrientText;
+ wxTextCtrl* m_PadOrientCtrl;
+ wxStaticText* m_customOrientUnits;
+ wxStaticText* m_staticText17;
+ wxTextCtrl* m_ShapeOffset_X_Ctrl;
+ wxStaticText* m_PadShapeOffsetX_Unit;
+ wxStaticText* m_staticText19;
+ wxTextCtrl* m_ShapeOffset_Y_Ctrl;
+ wxStaticText* m_PadShapeOffsetY_Unit;
+ wxStaticText* m_staticText38;
+ wxTextCtrl* m_LengthPadToDieCtrl;
+ wxStaticText* m_PadLengthDie_Unit;
+ wxStaticText* m_staticText21;
+ wxTextCtrl* m_ShapeDelta_Ctrl;
+ wxStaticText* m_PadShapeDelta_Unit;
+ wxStaticText* m_staticText23;
+ wxChoice* m_trapDeltaDirChoice;
+ wxStaticText* m_staticText521;
+ wxStaticText* m_staticTitleModuleRot;
+ wxStaticText* m_staticModuleRotValue;
+ wxStaticText* m_staticTitleModuleSide;
+ wxStaticText* m_staticModuleSideValue;
+ wxStaticText* m_staticText47;
+ wxChoice* m_DrillShapeCtrl;
+ wxStaticText* m_staticText51;
+ wxStaticText* m_textPadDrillX;
+ wxTextCtrl* m_PadDrill_X_Ctrl;
+ wxStaticText* m_PadDrill_X_Unit;
+ wxStaticText* m_textPadDrillY;
+ wxTextCtrl* m_PadDrill_Y_Ctrl;
+ wxStaticText* m_PadDrill_Y_Unit;
+ wxStaticText* m_staticText511;
+ wxChoice* m_rbCopperLayersSel;
+ wxCheckBox* m_PadLayerAdhCmp;
+ wxCheckBox* m_PadLayerAdhCu;
+ wxCheckBox* m_PadLayerPateCmp;
+ wxCheckBox* m_PadLayerPateCu;
+ wxCheckBox* m_PadLayerSilkCmp;
+ wxCheckBox* m_PadLayerSilkCu;
+ wxCheckBox* m_PadLayerMaskCmp;
+ wxCheckBox* m_PadLayerMaskCu;
+ wxCheckBox* m_PadLayerDraft;
+ wxCheckBox* m_PadLayerECO1;
+ wxCheckBox* m_PadLayerECO2;
+ wxPanel* m_localSettingsPanel;
+ wxStaticText* m_staticTextNetClearance;
+ wxTextCtrl* m_NetClearanceValueCtrl;
+ wxStaticText* m_NetClearanceUnits;
+ wxStaticText* m_MaskClearanceTitle;
+ wxTextCtrl* m_SolderMaskMarginCtrl;
+ wxStaticText* m_SolderMaskMarginUnits;
+ wxStaticText* m_staticTextSolderPaste;
+ wxTextCtrl* m_SolderPasteMarginCtrl;
+ wxStaticText* m_SolderPasteMarginUnits;
+ wxStaticText* m_staticTextRatio;
+ wxTextCtrl* m_SolderPasteMarginRatioCtrl;
+ wxStaticText* m_SolderPasteRatioMarginUnits;
+ wxStaticText* m_staticText40;
+ wxChoice* m_ZoneConnectionChoice;
+ wxStaticText* m_staticText53;
+ wxStaticText* m_staticText49;
+ wxTextCtrl* m_ThermalWidthCtrl;
+ wxStaticText* m_ThermalWidthUnits;
+ wxStaticText* m_staticText52;
+ wxTextCtrl* m_ThermalGapCtrl;
+ wxStaticText* m_ThermalGapUnits;
+ wxStaticText* m_staticTextWarning;
+ wxPanel* m_panelShowPad;
+ PCB_DRAW_PANEL_GAL* m_panelShowPadGal;
+ wxStaticText* m_staticTextWarningPadFlipped;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnValuesChanged( wxCommandEvent& event ) { event.Skip(); }
+ virtual void PadTypeSelected( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPadShapeSelection( wxCommandEvent& event ) { event.Skip(); }
+ virtual void PadOrientEvent( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnSetLayers( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnDrillShapeSelected( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPaintShowPanel( wxPaintEvent& event ) { event.Skip(); }
+ virtual void OnCancelButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void PadPropertiesAccept( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_DIALOG_EDIT_PAD, const wxString& title = _("Pad Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSUNKEN_BORDER );
+ ~DIALOG_PAD_PROPERTIES_BASE();
+
+};
+
+#endif //__DIALOG_PAD_PROPERTIES_BASE_H__
diff --git a/pcbnew/dialogs/dialog_pcb_text_properties.cpp b/pcbnew/dialogs/dialog_pcb_text_properties.cpp
new file mode 100644
index 0000000..c035bee
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pcb_text_properties.cpp
@@ -0,0 +1,309 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2010 Jean-Pierre Charras <jean-pierre.charras@gpisa-lab.inpg.fr>
+ * Copyright (C) 2010-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/***************************************************************************/
+/* Dialog editor for text on copper and technical layers (TEXTE_PCB class) */
+/***************************************************************************/
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <drawtxt.h>
+#include <confirm.h>
+#include <base_units.h>
+
+#include <class_board.h>
+#include <class_pcb_text.h>
+
+#include <vector>
+#include <wx/wx.h>
+#include <dialog_pcb_text_properties_base.h>
+#include <class_pcb_layer_box_selector.h>
+
+
+class PCB_EDIT_FRAME;
+class TEXTE_PCB;
+
+
+class DIALOG_PCB_TEXT_PROPERTIES : public DIALOG_PCB_TEXT_PROPERTIES_BASE
+{
+public:
+ DIALOG_PCB_TEXT_PROPERTIES( PCB_EDIT_FRAME* parent, TEXTE_PCB* passedTextPCB, wxDC* DC );
+
+private:
+ PCB_EDIT_FRAME* m_Parent;
+ wxDC* m_DC;
+ TEXTE_PCB* m_SelectedPCBText;
+
+ void MyInit();
+
+ // Handlers for DIALOG_PCB_TEXT_PROPERTIES_BASE events.
+ void OnClose( wxCloseEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+ void OnOkClick( wxCommandEvent& event );
+};
+
+
+/**
+ * DIALOG_PCB_TEXT_PROPERTIES, derived from DIALOG_PCB_TEXT_PROPERTIES_BASE
+ * @see dialog_dialog_pcb_text_properties_base.h and
+ * dialog_dialog_pcb_text_properties_base.cpp, automatically created by
+ * wxFormBuilder.
+ */
+
+DIALOG_PCB_TEXT_PROPERTIES::DIALOG_PCB_TEXT_PROPERTIES( PCB_EDIT_FRAME* parent,
+ TEXTE_PCB* passedTextPCB, wxDC* DC )
+ : DIALOG_PCB_TEXT_PROPERTIES_BASE( parent )
+{
+ m_Parent = parent;
+ m_DC = DC;
+ m_SelectedPCBText = passedTextPCB;
+
+ MyInit();
+ m_StandardSizerOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+/**
+ * Routine for main window class to launch text properties dialog.
+ */
+void PCB_EDIT_FRAME::InstallTextPCBOptionsFrame( TEXTE_PCB* TextPCB, wxDC* DC )
+{
+ m_canvas->SetIgnoreMouseEvents( true );
+#ifndef __WXMAC__
+ DIALOG_PCB_TEXT_PROPERTIES dlg( this, TextPCB, DC );
+#else
+ // Avoid "writes" in the dialog, creates errors with WxOverlay and NSView
+ // Raising an Exception - Fixes #891347
+ DIALOG_PCB_TEXT_PROPERTIES dlg( this, TextPCB, NULL );
+#endif
+ dlg.ShowModal();
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+}
+
+
+void DIALOG_PCB_TEXT_PROPERTIES::MyInit()
+{
+ // Put units symbols to text labels where appropriate
+ AddUnitSymbol( *m_SizeXLabel );
+ AddUnitSymbol( *m_SizeYLabel );
+ AddUnitSymbol( *m_ThicknessLabel );
+ AddUnitSymbol( *m_PositionXLabel );
+ AddUnitSymbol( *m_PositionYLabel );
+
+ // Fill fields with current values
+ *m_TextContentCtrl << m_SelectedPCBText->GetText();
+
+ PutValueInLocalUnits( *m_SizeXCtrl, m_SelectedPCBText->GetSize().x );
+ PutValueInLocalUnits( *m_SizeYCtrl, m_SelectedPCBText->GetSize().y );
+ PutValueInLocalUnits( *m_ThicknessCtrl, m_SelectedPCBText->GetThickness() );
+ PutValueInLocalUnits( *m_PositionXCtrl, m_SelectedPCBText->GetTextPosition().x );
+ PutValueInLocalUnits( *m_PositionYCtrl, m_SelectedPCBText->GetTextPosition().y );
+
+ // Configure the layers list selector
+ m_LayerSelectionCtrl->SetLayersHotkeys( false );
+
+ // A text has no sense on edge cut layer
+ m_LayerSelectionCtrl->SetLayerSet( Edge_Cuts );
+ m_LayerSelectionCtrl->SetBoardFrame( m_Parent );
+ m_LayerSelectionCtrl->Resync();
+ m_LayerSelectionCtrl->SetLayerSelection( m_SelectedPCBText->GetLayer() );
+
+ wxString orientationStr;
+ orientationStr << m_SelectedPCBText->GetOrientation();
+ m_OrientationCtrl->SetValue( orientationStr );
+
+ if( m_SelectedPCBText->IsMirrored() )
+ m_DisplayCtrl->SetSelection( 1 );
+ else
+ m_DisplayCtrl->SetSelection( 0 );
+
+ if( m_SelectedPCBText->IsItalic() )
+ m_StyleCtrl->SetSelection( 1 );
+ else
+ m_StyleCtrl->SetSelection( 0 );
+
+ // Set justification
+ EDA_TEXT_HJUSTIFY_T hJustify = m_SelectedPCBText->GetHorizJustify();
+ m_justifyChoice->SetSelection( (int) hJustify + 1 );
+
+ // Manually set tab order
+ m_SizeXCtrl->MoveAfterInTabOrder( m_TextContentCtrl );
+ m_SizeYCtrl->MoveAfterInTabOrder( m_SizeXCtrl );
+ m_ThicknessCtrl->MoveAfterInTabOrder( m_SizeYCtrl );
+ m_PositionXCtrl->MoveAfterInTabOrder( m_ThicknessCtrl );
+ m_PositionYCtrl->MoveAfterInTabOrder( m_PositionXCtrl );
+ m_OrientationCtrl->MoveAfterInTabOrder( m_PositionYCtrl );
+ m_LayerSelectionCtrl->MoveAfterInTabOrder( m_OrientationCtrl );
+ m_StyleCtrl->MoveAfterInTabOrder( m_LayerSelectionCtrl );
+ m_DisplayCtrl->MoveAfterInTabOrder( m_StyleCtrl );
+ m_justifyChoice->MoveAfterInTabOrder( m_DisplayCtrl );
+
+ // Set focus on most important control
+ m_TextContentCtrl->SetFocus();
+ m_TextContentCtrl->SetSelection( -1, -1 );
+}
+
+
+void DIALOG_PCB_TEXT_PROPERTIES::OnClose( wxCloseEvent& event )
+{
+ EndModal( 0 );
+}
+
+
+void DIALOG_PCB_TEXT_PROPERTIES::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+void DIALOG_PCB_TEXT_PROPERTIES::OnOkClick( wxCommandEvent& event )
+{
+ // Test for acceptable layer.
+ // Incorrect layer can happen for old boards,
+ // having texts on edge cut layer for instance
+ if( m_LayerSelectionCtrl->GetLayerSelection() < 0 )
+ {
+ wxMessageBox( _( "No layer selected, Please select the text layer" ) );
+ return;
+ }
+
+ wxPoint newPosition;
+ wxSize newSize;
+
+ // If no other command in progress, prepare undo command
+ // (for a command in progress, will be made later, at the completion of command)
+ if( m_SelectedPCBText->GetFlags() == 0 )
+ m_Parent->SaveCopyInUndoList( m_SelectedPCBText, UR_CHANGED );
+
+ /* set flag in edit to force undo/redo/abort proper operation,
+ * and avoid new calls to SaveCopyInUndoList for the same text
+ * this can occurs when a text is moved, and then rotated, edited ..
+ */
+ if( m_SelectedPCBText->GetFlags() != 0 )
+ m_SelectedPCBText->SetFlags( IN_EDIT );
+
+#ifndef USE_WX_OVERLAY
+ // Erase old text on screen if context is available
+ if( m_DC )
+ {
+ m_SelectedPCBText->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR );
+ }
+#endif
+
+ // Set the new text content
+ if( !m_TextContentCtrl->GetValue().IsEmpty() )
+ {
+ m_SelectedPCBText->SetText( m_TextContentCtrl->GetValue() );
+ }
+
+ // Set PCB Text position
+ newPosition.x = ValueFromString( g_UserUnit, m_PositionXCtrl->GetValue() );
+ newPosition.y = ValueFromString( g_UserUnit, m_PositionYCtrl->GetValue() );
+ m_SelectedPCBText->SetTextPosition( newPosition );
+
+ // Check constraints and set PCB Text size
+ newSize.x = ValueFromString( g_UserUnit, m_SizeXCtrl->GetValue() );
+ newSize.y = ValueFromString( g_UserUnit, m_SizeYCtrl->GetValue() );
+
+ if( newSize.x < TEXTS_MIN_SIZE )
+ newSize.x = TEXTS_MIN_SIZE;
+
+ if( newSize.y < TEXTS_MIN_SIZE )
+ newSize.y = TEXTS_MIN_SIZE;
+
+ if( newSize.x > TEXTS_MAX_WIDTH )
+ newSize.x = TEXTS_MAX_WIDTH;
+
+ if( newSize.y > TEXTS_MAX_WIDTH )
+ newSize.y = TEXTS_MAX_WIDTH;
+
+ m_SelectedPCBText->SetSize( newSize );
+
+ // Set the new thickness
+ m_SelectedPCBText->SetThickness( ValueFromString( g_UserUnit,
+ m_ThicknessCtrl->GetValue() ) );
+
+ // Test for acceptable values for thickness and size and clamp if fails
+ int maxthickness = Clamp_Text_PenSize( m_SelectedPCBText->GetThickness(),
+ m_SelectedPCBText->GetSize() );
+
+ if( m_SelectedPCBText->GetThickness() > maxthickness )
+ {
+ DisplayError( NULL,
+ _( "The text thickness is too large for the text size. It will be clamped" ) );
+ m_SelectedPCBText->SetThickness( maxthickness );
+ }
+
+ // Set the layer on which the PCB text is laying
+ m_SelectedPCBText->SetLayer( ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) );
+
+ // Set whether the PCB text is mirrored (faced down from layer face perspective)
+ m_SelectedPCBText->SetMirrored( m_DisplayCtrl->GetSelection() == 1 );
+
+ // Set the text orientation
+ long orientation;
+ m_OrientationCtrl->GetValue().ToLong( &orientation );
+ orientation = orientation % 3600;
+ m_SelectedPCBText->SetOrientation( orientation );
+
+ // Set whether the PCB text is slanted (it is not italics, as italics has additional curves in style)
+ m_SelectedPCBText->SetItalic( m_StyleCtrl->GetSelection() );
+
+ // Set justification
+ switch( m_justifyChoice->GetSelection() )
+ {
+ case 0:
+ m_SelectedPCBText->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ break;
+ case 1:
+ m_SelectedPCBText->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
+ break;
+ case 2:
+ m_SelectedPCBText->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ break;
+ default:
+ break;
+ }
+
+#ifndef USE_WX_OVERLAY
+ // Finally, display new text if there is a context to do so
+ if( m_DC )
+ {
+ m_SelectedPCBText->Draw( m_Parent->GetCanvas(), m_DC, GR_OR );
+ }
+#else
+ m_parent->Refresh();
+#endif
+ m_Parent->OnModify();
+ EndModal( 1 );
+}
diff --git a/pcbnew/dialogs/dialog_pcb_text_properties_base.cpp b/pcbnew/dialogs/dialog_pcb_text_properties_base.cpp
new file mode 100644
index 0000000..65c8b2a
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pcb_text_properties_base.cpp
@@ -0,0 +1,169 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "class_pcb_layer_box_selector.h"
+
+#include "dialog_pcb_text_properties_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_PCB_TEXT_PROPERTIES_BASE::DIALOG_PCB_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizer9;
+ bSizer9 = new wxBoxSizer( wxVERTICAL );
+
+ m_TextLabel = new wxStaticText( this, wxID_ANY, _("Text:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextLabel->Wrap( -1 );
+ bSizer9->Add( m_TextLabel, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_TextContentCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
+ m_TextContentCtrl->SetToolTip( _("Enter the text placed on selected layer.") );
+ m_TextContentCtrl->SetMinSize( wxSize( 400,60 ) );
+
+ bSizer9->Add( m_TextContentCtrl, 1, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 6, 4, 0, 0 );
+ fgSizer1->AddGrowableCol( 0 );
+ fgSizer1->AddGrowableCol( 1 );
+ fgSizer1->AddGrowableCol( 2 );
+ fgSizer1->AddGrowableCol( 3 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_SizeXLabel = new wxStaticText( this, wxID_ANY, _("Width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SizeXLabel->Wrap( -1 );
+ fgSizer1->Add( m_SizeXLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_PositionXLabel = new wxStaticText( this, wxID_ANY, _("Position X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PositionXLabel->Wrap( -1 );
+ fgSizer1->Add( m_PositionXLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_LayerLabel = new wxStaticText( this, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_LayerLabel->Wrap( -1 );
+ fgSizer1->Add( m_LayerLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_staticText10 = new wxStaticText( this, wxID_ANY, _("Display:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText10->Wrap( -1 );
+ fgSizer1->Add( m_staticText10, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_SizeXCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SizeXCtrl->SetMaxLength( 0 );
+ fgSizer1->Add( m_SizeXCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_PositionXCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PositionXCtrl->SetMaxLength( 0 );
+ fgSizer1->Add( m_PositionXCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_LayerSelectionCtrl = new PCB_LAYER_BOX_SELECTOR( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ fgSizer1->Add( m_LayerSelectionCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ wxString m_DisplayCtrlChoices[] = { _("Normal"), _("Mirrored") };
+ int m_DisplayCtrlNChoices = sizeof( m_DisplayCtrlChoices ) / sizeof( wxString );
+ m_DisplayCtrl = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_DisplayCtrlNChoices, m_DisplayCtrlChoices, 0 );
+ m_DisplayCtrl->SetSelection( 0 );
+ fgSizer1->Add( m_DisplayCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_SizeYLabel = new wxStaticText( this, wxID_ANY, _("Height:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SizeYLabel->Wrap( -1 );
+ fgSizer1->Add( m_SizeYLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_PositionYLabel = new wxStaticText( this, wxID_ANY, _("Position Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PositionYLabel->Wrap( -1 );
+ fgSizer1->Add( m_PositionYLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_staticText9 = new wxStaticText( this, wxID_ANY, _("Style:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText9->Wrap( -1 );
+ fgSizer1->Add( m_staticText9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_staticText11 = new wxStaticText( this, wxID_ANY, _("Justification:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText11->Wrap( -1 );
+ fgSizer1->Add( m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_SizeYCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SizeYCtrl->SetMaxLength( 0 );
+ fgSizer1->Add( m_SizeYCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_PositionYCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PositionYCtrl->SetMaxLength( 0 );
+ fgSizer1->Add( m_PositionYCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ wxString m_StyleCtrlChoices[] = { _("Normal"), _("Italic") };
+ int m_StyleCtrlNChoices = sizeof( m_StyleCtrlChoices ) / sizeof( wxString );
+ m_StyleCtrl = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_StyleCtrlNChoices, m_StyleCtrlChoices, 0 );
+ m_StyleCtrl->SetSelection( 0 );
+ fgSizer1->Add( m_StyleCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ wxString m_justifyChoiceChoices[] = { _("Left"), _("Center"), _("Right") };
+ int m_justifyChoiceNChoices = sizeof( m_justifyChoiceChoices ) / sizeof( wxString );
+ m_justifyChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_justifyChoiceNChoices, m_justifyChoiceChoices, 0 );
+ m_justifyChoice->SetSelection( 0 );
+ fgSizer1->Add( m_justifyChoice, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_ThicknessLabel = new wxStaticText( this, wxID_ANY, _("Thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ThicknessLabel->Wrap( -1 );
+ fgSizer1->Add( m_ThicknessLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_orientationLabel = new wxStaticText( this, wxID_ANY, _("Orientation (0.1 deg):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_orientationLabel->Wrap( -1 );
+ fgSizer1->Add( m_orientationLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_ThicknessCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_ThicknessCtrl->SetMaxLength( 0 );
+ fgSizer1->Add( m_ThicknessCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+ m_OrientationCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_OrientationCtrl->SetMaxLength( 0 );
+ fgSizer1->Add( m_OrientationCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 3 );
+
+
+ bSizer9->Add( fgSizer1, 1, wxALL|wxEXPAND, 5 );
+
+ m_StandardSizer = new wxStdDialogButtonSizer();
+ m_StandardSizerOK = new wxButton( this, wxID_OK );
+ m_StandardSizer->AddButton( m_StandardSizerOK );
+ m_StandardSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_StandardSizer->AddButton( m_StandardSizerCancel );
+ m_StandardSizer->Realize();
+
+ bSizer9->Add( m_StandardSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bSizer9, 1, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PCB_TEXT_PROPERTIES_BASE::OnClose ) );
+ m_StandardSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PCB_TEXT_PROPERTIES_BASE::OnCancelClick ), NULL, this );
+ m_StandardSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PCB_TEXT_PROPERTIES_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_PCB_TEXT_PROPERTIES_BASE::~DIALOG_PCB_TEXT_PROPERTIES_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PCB_TEXT_PROPERTIES_BASE::OnClose ) );
+ m_StandardSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PCB_TEXT_PROPERTIES_BASE::OnCancelClick ), NULL, this );
+ m_StandardSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PCB_TEXT_PROPERTIES_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_pcb_text_properties_base.fbp b/pcbnew/dialogs/dialog_pcb_text_properties_base.fbp
new file mode 100644
index 0000000..103fea2
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pcb_text_properties_base.fbp
@@ -0,0 +1,2079 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_pcb_text_properties_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_PCB_TEXT_PROPERTIES_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_PCB_TEXT_PROPERTIES_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Text Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnClose</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer9</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Text:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">400,60</property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextContentCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_MULTILINE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enter the text placed on selected layer.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">4</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">0,1,2,3</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">6</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SizeXLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Position X:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PositionXLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layer:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LayerLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Display:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText10</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SizeXCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PositionXCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxBitmapComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LayerSelectionCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">PCB_LAYER_BOX_SELECTOR; class_pcb_layer_box_selector.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Normal&quot; &quot;Mirrored&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DisplayCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Height:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SizeYLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Position Y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PositionYLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Style:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText9</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Justification:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText11</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SizeYCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PositionYCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Normal&quot; &quot;Italic&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_StyleCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Left&quot; &quot;Center&quot; &quot;Right&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_justifyChoice</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Thickness:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ThicknessLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Orientation (0.1 deg):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_orientationLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ThicknessCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OrientationCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_StandardSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_pcb_text_properties_base.h b/pcbnew/dialogs/dialog_pcb_text_properties_base.h
new file mode 100644
index 0000000..ddadfbe
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pcb_text_properties_base.h
@@ -0,0 +1,81 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_PCB_TEXT_PROPERTIES_BASE_H__
+#define __DIALOG_PCB_TEXT_PROPERTIES_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class PCB_LAYER_BOX_SELECTOR;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/bmpcbox.h>
+#include <wx/choice.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PCB_TEXT_PROPERTIES_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PCB_TEXT_PROPERTIES_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_TextLabel;
+ wxTextCtrl* m_TextContentCtrl;
+ wxStaticText* m_SizeXLabel;
+ wxStaticText* m_PositionXLabel;
+ wxStaticText* m_LayerLabel;
+ wxStaticText* m_staticText10;
+ wxTextCtrl* m_SizeXCtrl;
+ wxTextCtrl* m_PositionXCtrl;
+ PCB_LAYER_BOX_SELECTOR* m_LayerSelectionCtrl;
+ wxChoice* m_DisplayCtrl;
+ wxStaticText* m_SizeYLabel;
+ wxStaticText* m_PositionYLabel;
+ wxStaticText* m_staticText9;
+ wxStaticText* m_staticText11;
+ wxTextCtrl* m_SizeYCtrl;
+ wxTextCtrl* m_PositionYCtrl;
+ wxChoice* m_StyleCtrl;
+ wxChoice* m_justifyChoice;
+ wxStaticText* m_ThicknessLabel;
+ wxStaticText* m_orientationLabel;
+ wxTextCtrl* m_ThicknessCtrl;
+ wxTextCtrl* m_OrientationCtrl;
+ wxStdDialogButtonSizer* m_StandardSizer;
+ wxButton* m_StandardSizerOK;
+ wxButton* m_StandardSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PCB_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Text Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU );
+ ~DIALOG_PCB_TEXT_PROPERTIES_BASE();
+
+};
+
+#endif //__DIALOG_PCB_TEXT_PROPERTIES_BASE_H__
diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp
new file mode 100644
index 0000000..d0065eb
--- /dev/null
+++ b/pcbnew/dialogs/dialog_plot.cpp
@@ -0,0 +1,869 @@
+/**
+ * @file dialog_plot.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <kiface_i.h>
+#include <plot_common.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <pcbplot.h>
+#include <base_units.h>
+#include <macros.h>
+#include <reporter.h>
+
+#include <class_board.h>
+#include <wx/ffile.h>
+#include <dialog_plot.h>
+#include <wx_html_report_panel.h>
+
+DIALOG_PLOT::DIALOG_PLOT( PCB_EDIT_FRAME* aParent ) :
+ DIALOG_PLOT_BASE( aParent ), m_parent( aParent ),
+ m_board( aParent->GetBoard() ),
+ m_plotOpts( aParent->GetPlotSettings() )
+{
+ m_config = Kiface().KifaceSettings();
+ init_Dialog();
+
+ GetSizer()->Fit( this );
+ GetSizer()->SetSizeHints( this );
+}
+
+
+void DIALOG_PLOT::init_Dialog()
+{
+ wxString msg;
+ wxFileName fileName;
+
+ m_config->Read( OPTKEY_PLOT_X_FINESCALE_ADJ, &m_XScaleAdjust );
+ m_config->Read( OPTKEY_PLOT_Y_FINESCALE_ADJ, &m_YScaleAdjust );
+
+ // m_PSWidthAdjust is stored in mm in user config
+ double dtmp;
+ m_config->Read( CONFIG_PS_FINEWIDTH_ADJ, &dtmp, 0 );
+ m_PSWidthAdjust = KiROUND( dtmp * IU_PER_MM );
+
+ // The reasonable width correction value must be in a range of
+ // [-(MinTrackWidth-1), +(MinClearanceValue-1)] decimils.
+ m_widthAdjustMinValue = -( m_board->GetDesignSettings().m_TrackMinWidth - 1 );
+ m_widthAdjustMaxValue = m_board->GetDesignSettings().GetSmallestClearanceValue() - 1;
+
+ switch( m_plotOpts.GetFormat() )
+ {
+ default:
+ case PLOT_FORMAT_GERBER:
+ m_plotFormatOpt->SetSelection( 0 );
+ break;
+
+ case PLOT_FORMAT_POST:
+ m_plotFormatOpt->SetSelection( 1 );
+ break;
+
+ case PLOT_FORMAT_SVG:
+ m_plotFormatOpt->SetSelection( 2 );
+ break;
+
+ case PLOT_FORMAT_DXF:
+ m_plotFormatOpt->SetSelection( 3 );
+ break;
+
+ case PLOT_FORMAT_HPGL:
+ m_plotFormatOpt->SetSelection( 4 );
+ break;
+
+ case PLOT_FORMAT_PDF:
+ m_plotFormatOpt->SetSelection( 5 );
+ break;
+ }
+
+ msg = StringFromValue( g_UserUnit, m_board->GetDesignSettings().m_SolderMaskMargin, true );
+ m_SolderMaskMarginCurrValue->SetLabel( msg );
+ msg = StringFromValue( g_UserUnit, m_board->GetDesignSettings().m_SolderMaskMinWidth, true );
+ m_SolderMaskMinWidthCurrValue->SetLabel( msg );
+
+ // Set units and value for HPGL pen size (this param in in mils).
+ AddUnitSymbol( *m_textPenSize, g_UserUnit );
+ msg = StringFromValue( g_UserUnit,
+ m_plotOpts.GetHPGLPenDiameter() * IU_PER_MILS );
+ m_HPGLPenSizeOpt->AppendText( msg );
+
+ // Set units and value for HPGL pen overlay (this param in in mils).
+ AddUnitSymbol( *m_textPenOvr, g_UserUnit );
+ msg = StringFromValue( g_UserUnit,
+ m_plotOpts.GetHPGLPenOverlay() * IU_PER_MILS );
+ m_HPGLPenOverlayOpt->AppendText( msg );
+
+ AddUnitSymbol( *m_textDefaultPenSize, g_UserUnit );
+ msg = StringFromValue( g_UserUnit, m_plotOpts.GetLineWidth() );
+ m_linesWidth->AppendText( msg );
+
+ // Set units for PS global width correction.
+ AddUnitSymbol( *m_textPSFineAdjustWidth, g_UserUnit );
+
+ m_useAuxOriginCheckBox->SetValue( m_plotOpts.GetUseAuxOrigin() );
+
+ // Test for a reasonable scale value. Set to 1 if problem
+ if( m_XScaleAdjust < PLOT_MIN_SCALE || m_YScaleAdjust < PLOT_MIN_SCALE
+ || m_XScaleAdjust > PLOT_MAX_SCALE || m_YScaleAdjust > PLOT_MAX_SCALE )
+ m_XScaleAdjust = m_YScaleAdjust = 1.0;
+
+ msg.Printf( wxT( "%f" ), m_XScaleAdjust );
+ m_fineAdjustXscaleOpt->AppendText( msg );
+
+ msg.Printf( wxT( "%f" ), m_YScaleAdjust );
+ m_fineAdjustYscaleOpt->AppendText( msg );
+
+ // Test for a reasonable PS width correction value. Set to 0 if problem.
+ if( m_PSWidthAdjust < m_widthAdjustMinValue || m_PSWidthAdjust > m_widthAdjustMaxValue )
+ m_PSWidthAdjust = 0.;
+
+ msg.Printf( wxT( "%f" ), To_User_Unit( g_UserUnit, m_PSWidthAdjust ) );
+ m_PSFineAdjustWidthOpt->AppendText( msg );
+
+ m_plotPSNegativeOpt->SetValue( m_plotOpts.GetNegative() );
+ m_forcePSA4OutputOpt->SetValue( m_plotOpts.GetA4Output() );
+
+ // Could devote a PlotOrder() function in place of UIOrder().
+ m_layerList = m_board->GetEnabledLayers().UIOrder();
+
+ // Populate the check list box by all enabled layers names
+ for( LSEQ seq = m_layerList; seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ int checkIndex = m_layerCheckListBox->Append( m_board->GetLayerName( layer ) );
+
+ if( m_plotOpts.GetLayerSelection()[layer] )
+ m_layerCheckListBox->Check( checkIndex );
+ }
+
+ // Option for using proper Gerber extensions
+ m_useGerberExtensions->SetValue( m_plotOpts.GetUseGerberProtelExtensions() );
+
+ // Option for including Gerber attributes (from Gerber X2 format) in the output
+ m_useGerberAttributes->SetValue( m_plotOpts.GetUseGerberAttributes() );
+
+ // Gerber precision for coordinates
+ m_rbGerberFormat->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 );
+
+ // Option for excluding contents of "Edges Pcb" layer
+ m_excludeEdgeLayerOpt->SetValue( m_plotOpts.GetExcludeEdgeLayer() );
+
+ m_subtractMaskFromSilk->SetValue( m_plotOpts.GetSubtractMaskFromSilk() );
+
+ // Option to plot page references:
+ m_plotSheetRef->SetValue( m_plotOpts.GetPlotFrameRef() );
+
+ // Option to allow pads on silkscreen layers
+ m_plotPads_on_Silkscreen->SetValue( m_plotOpts.GetPlotPadsOnSilkLayer() );
+
+ // Options to plot texts on footprints
+ m_plotModuleValueOpt->SetValue( m_plotOpts.GetPlotValue() );
+ m_plotModuleRefOpt->SetValue( m_plotOpts.GetPlotReference() );
+ m_plotInvisibleText->SetValue( m_plotOpts.GetPlotInvisibleText() );
+
+ // Options to plot pads and vias holes
+ m_drillShapeOpt->SetSelection( m_plotOpts.GetDrillMarksType() );
+
+ // Scale option
+ m_scaleOpt->SetSelection( m_plotOpts.GetScaleSelection() );
+
+ // Plot mode
+ setPlotModeChoiceSelection( m_plotOpts.GetPlotMode() );
+
+ // Plot outline mode
+ m_DXF_plotModeOpt->SetValue( m_plotOpts.GetDXFPlotPolygonMode() );
+
+ // Plot text mode
+ m_DXF_plotTextStrokeFontOpt->SetValue( m_plotOpts.GetTextMode() == PLOTTEXTMODE_DEFAULT );
+
+ // Plot mirror option
+ m_plotMirrorOpt->SetValue( m_plotOpts.GetMirror() );
+
+ // Put vias on mask layer
+ m_plotNoViaOnMaskOpt->SetValue( m_plotOpts.GetPlotViaOnMaskLayer() );
+
+ // Output directory
+ m_outputDirectoryName->SetValue( m_plotOpts.GetOutputDirectory() );
+
+ // Update options values:
+ wxCommandEvent cmd_event;
+ SetPlotFormat( cmd_event );
+ OnSetScaleOpt( cmd_event );
+}
+
+
+void DIALOG_PLOT::OnQuit( wxCommandEvent& event )
+{
+ Close( true ); // true is to force the frame to close
+}
+
+
+void DIALOG_PLOT::OnClose( wxCloseEvent& event )
+{
+ applyPlotSettings();
+ EndModal( 0 );
+}
+
+
+// A helper function to show a popup menu, when the dialog is right clicked.
+void DIALOG_PLOT::OnRightClick( wxMouseEvent& event )
+{
+ PopupMenu( m_popMenu );
+}
+
+
+// Select or deselect groups of layers in the layers list:
+#include <layers_id_colors_and_visibility.h>
+void DIALOG_PLOT::OnPopUpLayers( wxCommandEvent& event )
+{
+ unsigned int i;
+
+ switch( event.GetId() )
+ {
+ case ID_LAYER_FAB: // Select layers usually needed to build a board
+ for( i = 0; i < m_layerList.size(); i++ )
+ {
+ LSET layermask( m_layerList[ i ] );
+
+ if( ( layermask & ( LSET::AllCuMask() | LSET::AllTechMask() ) ).any() )
+ m_layerCheckListBox->Check( i, true );
+ else
+ m_layerCheckListBox->Check( i, false );
+ }
+ break;
+
+ case ID_SELECT_COPPER_LAYERS:
+ for( i = 0; i < m_layerList.size(); i++ )
+ {
+ if( IsCopperLayer( m_layerList[i] ) )
+ m_layerCheckListBox->Check( i, true );
+ }
+ break;
+
+ case ID_DESELECT_COPPER_LAYERS:
+ for( i = 0; i < m_layerList.size(); i++ )
+ {
+ if( IsCopperLayer( m_layerList[i] ) )
+ m_layerCheckListBox->Check( i, false );
+ }
+ break;
+
+ case ID_SELECT_ALL_LAYERS:
+ for( i = 0; i < m_layerList.size(); i++ )
+ m_layerCheckListBox->Check( i, true );
+ break;
+
+ case ID_DESELECT_ALL_LAYERS:
+ for( i = 0; i < m_layerList.size(); i++ )
+ m_layerCheckListBox->Check( i, false );
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void DIALOG_PLOT::CreateDrillFile( wxCommandEvent& event )
+{
+ m_parent->InstallDrillFrame( event );
+}
+
+
+void DIALOG_PLOT::OnChangeDXFPlotMode( wxCommandEvent& event )
+{
+ // m_DXF_plotTextStrokeFontOpt is disabled if m_DXF_plotModeOpt
+ // is checked (plot in DXF polygon mode)
+ m_DXF_plotTextStrokeFontOpt->Enable( !m_DXF_plotModeOpt->GetValue() );
+
+ // if m_DXF_plotTextStrokeFontOpt option is disabled (plot DXF in polygon mode),
+ // force m_DXF_plotTextStrokeFontOpt to true to use Pcbnew stroke font
+ if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() )
+ m_DXF_plotTextStrokeFontOpt->SetValue( true );
+}
+
+
+void DIALOG_PLOT::OnSetScaleOpt( wxCommandEvent& event )
+{
+ /* Disable sheet reference for scale != 1:1 */
+ bool scale1 = ( m_scaleOpt->GetSelection() == 1 );
+
+ m_plotSheetRef->Enable( scale1 );
+
+ if( !scale1 )
+ m_plotSheetRef->SetValue( false );
+}
+
+
+void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
+{
+ // Build the absolute path of current output plot directory
+ // to preselect it when opening the dialog.
+ wxFileName fn( m_outputDirectoryName->GetValue() );
+ wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() );
+
+ wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
+
+ if( dirDialog.ShowModal() == wxID_CANCEL )
+ return;
+
+ wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
+
+ fn = Prj().AbsolutePath( m_parent->GetBoard()->GetFileName() );
+ wxString defaultPath = fn.GetPathWithSep();
+ wxString msg;
+ msg.Printf( _( "Do you want to use a path relative to\n'%s'" ),
+ GetChars( defaultPath ) );
+
+ wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
+ wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
+
+ if( dialog.ShowModal() == wxID_YES )
+ {
+ if( !dirName.MakeRelativeTo( defaultPath ) )
+ wxMessageBox( _( "Cannot make path relative (target volume different from file volume)!" ),
+ _( "Plot Output Directory" ), wxOK | wxICON_ERROR );
+ }
+
+ m_outputDirectoryName->SetValue( dirName.GetFullPath() );
+}
+
+
+PlotFormat DIALOG_PLOT::getPlotFormat()
+{
+ // plot format id's are ordered like displayed in m_plotFormatOpt
+ static const PlotFormat plotFmt[] =
+ {
+ PLOT_FORMAT_GERBER,
+ PLOT_FORMAT_POST,
+ PLOT_FORMAT_SVG,
+ PLOT_FORMAT_DXF,
+ PLOT_FORMAT_HPGL,
+ PLOT_FORMAT_PDF
+ };
+
+ return plotFmt[ m_plotFormatOpt->GetSelection() ];
+}
+
+
+// Enable or disable widgets according to the plot format selected
+// and clear also some optional values
+void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
+{
+ // this option exist only in DXF format:
+ m_DXF_plotModeOpt->Enable( getPlotFormat() == PLOT_FORMAT_DXF );
+
+ switch( getPlotFormat() )
+ {
+ case PLOT_FORMAT_PDF:
+ case PLOT_FORMAT_SVG:
+ m_drillShapeOpt->Enable( true );
+ m_plotModeOpt->Enable( false );
+ setPlotModeChoiceSelection( FILLED );
+ m_plotMirrorOpt->Enable( true );
+ m_useAuxOriginCheckBox->Enable( false );
+ m_useAuxOriginCheckBox->SetValue( false );
+ m_linesWidth->Enable( true );
+ m_HPGLPenSizeOpt->Enable( false );
+ m_HPGLPenOverlayOpt->Enable( false );
+ m_excludeEdgeLayerOpt->Enable( true );
+ m_subtractMaskFromSilk->Enable( false );
+ m_subtractMaskFromSilk->SetValue( false );
+ m_useGerberExtensions->Enable( false );
+ m_useGerberExtensions->SetValue( false );
+ m_useGerberAttributes->Enable( false );
+ m_useGerberAttributes->SetValue( false );
+ m_scaleOpt->Enable( false );
+ m_scaleOpt->SetSelection( 1 );
+ m_fineAdjustXscaleOpt->Enable( false );
+ m_fineAdjustYscaleOpt->Enable( false );
+ m_PSFineAdjustWidthOpt->Enable( false );
+ m_plotPSNegativeOpt->Enable( true );
+ m_forcePSA4OutputOpt->Enable( false );
+ m_forcePSA4OutputOpt->SetValue( false );
+
+ m_PlotOptionsSizer->Hide( m_GerberOptionsSizer );
+ m_PlotOptionsSizer->Hide( m_HPGLOptionsSizer );
+ m_PlotOptionsSizer->Hide( m_PSOptionsSizer );
+ m_PlotOptionsSizer->Hide( m_SizerDXF_options );
+ break;
+
+ case PLOT_FORMAT_POST:
+ m_drillShapeOpt->Enable( true );
+ m_plotModeOpt->Enable( true );
+ m_plotMirrorOpt->Enable( true );
+ m_useAuxOriginCheckBox->Enable( false );
+ m_useAuxOriginCheckBox->SetValue( false );
+ m_linesWidth->Enable( true );
+ m_HPGLPenSizeOpt->Enable( false );
+ m_HPGLPenOverlayOpt->Enable( false );
+ m_excludeEdgeLayerOpt->Enable( true );
+ m_subtractMaskFromSilk->Enable( false );
+ m_subtractMaskFromSilk->SetValue( false );
+ m_useGerberExtensions->Enable( false );
+ m_useGerberExtensions->SetValue( false );
+ m_useGerberAttributes->Enable( false );
+ m_useGerberAttributes->SetValue( false );
+ m_scaleOpt->Enable( true );
+ m_fineAdjustXscaleOpt->Enable( true );
+ m_fineAdjustYscaleOpt->Enable( true );
+ m_PSFineAdjustWidthOpt->Enable( true );
+ m_plotPSNegativeOpt->Enable( true );
+ m_forcePSA4OutputOpt->Enable( true );
+
+ m_PlotOptionsSizer->Hide( m_GerberOptionsSizer );
+ m_PlotOptionsSizer->Hide( m_HPGLOptionsSizer );
+ m_PlotOptionsSizer->Show( m_PSOptionsSizer );
+ m_PlotOptionsSizer->Hide( m_SizerDXF_options );
+ break;
+
+ case PLOT_FORMAT_GERBER:
+ m_drillShapeOpt->Enable( false );
+ m_drillShapeOpt->SetSelection( 0 );
+ m_plotModeOpt->Enable( false );
+ setPlotModeChoiceSelection( FILLED );
+ m_plotMirrorOpt->Enable( false );
+ m_plotMirrorOpt->SetValue( false );
+ m_useAuxOriginCheckBox->Enable( true );
+ m_linesWidth->Enable( true );
+ m_HPGLPenSizeOpt->Enable( false );
+ m_HPGLPenOverlayOpt->Enable( false );
+ m_excludeEdgeLayerOpt->Enable( true );
+ m_subtractMaskFromSilk->Enable( true );
+ m_useGerberExtensions->Enable( true );
+ m_useGerberAttributes->Enable( true );
+ m_scaleOpt->Enable( false );
+ m_scaleOpt->SetSelection( 1 );
+ m_fineAdjustXscaleOpt->Enable( false );
+ m_fineAdjustYscaleOpt->Enable( false );
+ m_PSFineAdjustWidthOpt->Enable( false );
+ m_plotPSNegativeOpt->Enable( false );
+ m_plotPSNegativeOpt->SetValue( false );
+ m_forcePSA4OutputOpt->Enable( false );
+ m_forcePSA4OutputOpt->SetValue( false );
+
+ m_PlotOptionsSizer->Show( m_GerberOptionsSizer );
+ m_PlotOptionsSizer->Hide( m_HPGLOptionsSizer );
+ m_PlotOptionsSizer->Hide( m_PSOptionsSizer );
+ m_PlotOptionsSizer->Hide( m_SizerDXF_options );
+ break;
+
+ case PLOT_FORMAT_HPGL:
+ m_drillShapeOpt->Enable( true );
+ m_plotModeOpt->Enable( true );
+ m_plotMirrorOpt->Enable( true );
+ m_useAuxOriginCheckBox->Enable( false );
+ m_useAuxOriginCheckBox->SetValue( false );
+ m_linesWidth->Enable( false );
+ m_HPGLPenSizeOpt->Enable( true );
+ m_HPGLPenOverlayOpt->Enable( true );
+ m_excludeEdgeLayerOpt->Enable( true );
+ m_subtractMaskFromSilk->Enable( false );
+ m_subtractMaskFromSilk->SetValue( false );
+ m_useGerberExtensions->Enable( false );
+ m_useGerberExtensions->SetValue( false );
+ m_useGerberAttributes->Enable( false );
+ m_useGerberAttributes->SetValue( false );
+ m_scaleOpt->Enable( true );
+ m_fineAdjustXscaleOpt->Enable( false );
+ m_fineAdjustYscaleOpt->Enable( false );
+ m_PSFineAdjustWidthOpt->Enable( false );
+ m_plotPSNegativeOpt->SetValue( false );
+ m_plotPSNegativeOpt->Enable( false );
+ m_forcePSA4OutputOpt->Enable( true );
+
+ m_PlotOptionsSizer->Hide( m_GerberOptionsSizer );
+ m_PlotOptionsSizer->Show( m_HPGLOptionsSizer );
+ m_PlotOptionsSizer->Hide( m_PSOptionsSizer );
+ m_PlotOptionsSizer->Hide( m_SizerDXF_options );
+ break;
+
+ case PLOT_FORMAT_DXF:
+ m_drillShapeOpt->Enable( true );
+ m_plotModeOpt->Enable( false );
+ setPlotModeChoiceSelection( FILLED );
+ m_plotMirrorOpt->Enable( false );
+ m_plotMirrorOpt->SetValue( false );
+ m_useAuxOriginCheckBox->Enable( true );
+ m_linesWidth->Enable( false );
+ m_HPGLPenSizeOpt->Enable( false );
+ m_HPGLPenOverlayOpt->Enable( false );
+ m_excludeEdgeLayerOpt->Enable( true );
+ m_subtractMaskFromSilk->Enable( false );
+ m_subtractMaskFromSilk->SetValue( false );
+ m_useGerberExtensions->Enable( false );
+ m_useGerberExtensions->SetValue( false );
+ m_useGerberAttributes->Enable( false );
+ m_useGerberAttributes->SetValue( false );
+ m_scaleOpt->Enable( false );
+ m_scaleOpt->SetSelection( 1 );
+ m_fineAdjustXscaleOpt->Enable( false );
+ m_fineAdjustYscaleOpt->Enable( false );
+ m_PSFineAdjustWidthOpt->Enable( false );
+ m_plotPSNegativeOpt->Enable( false );
+ m_plotPSNegativeOpt->SetValue( false );
+ m_forcePSA4OutputOpt->Enable( false );
+ m_forcePSA4OutputOpt->SetValue( false );
+
+ m_PlotOptionsSizer->Hide( m_GerberOptionsSizer );
+ m_PlotOptionsSizer->Hide( m_HPGLOptionsSizer );
+ m_PlotOptionsSizer->Hide( m_PSOptionsSizer );
+ m_PlotOptionsSizer->Show( m_SizerDXF_options );
+
+ OnChangeDXFPlotMode( event );
+ break;
+
+ default:
+ wxASSERT( false );
+ }
+
+ /* Update the interlock between scale and frame reference
+ * (scaling would mess up the frame border...) */
+ OnSetScaleOpt( event );
+
+ Layout();
+ m_MainSizer->SetSizeHints( this );
+}
+
+
+// A helper function to "clip" aValue between aMin and aMax
+// and write result in * aResult
+// return false if clipped, true if aValue is just copied into * aResult
+static bool setDouble( double* aResult, double aValue, double aMin, double aMax )
+{
+ if( aValue < aMin )
+ {
+ *aResult = aMin;
+ return false;
+ }
+ else if( aValue > aMax )
+ {
+ *aResult = aMax;
+ return false;
+ }
+
+ *aResult = aValue;
+ return true;
+}
+
+
+static bool setInt( int* aResult, int aValue, int aMin, int aMax )
+{
+ if( aValue < aMin )
+ {
+ *aResult = aMin;
+ return false;
+ }
+ else if( aValue > aMax )
+ {
+ *aResult = aMax;
+ return false;
+ }
+
+ *aResult = aValue;
+ return true;
+}
+
+
+void DIALOG_PLOT::applyPlotSettings()
+{
+ REPORTER& reporter = m_messagesPanel->Reporter();
+
+ PCB_PLOT_PARAMS tempOptions;
+
+ tempOptions.SetExcludeEdgeLayer( m_excludeEdgeLayerOpt->GetValue() );
+ tempOptions.SetSubtractMaskFromSilk( m_subtractMaskFromSilk->GetValue() );
+ tempOptions.SetPlotFrameRef( m_plotSheetRef->GetValue() );
+ tempOptions.SetPlotPadsOnSilkLayer( m_plotPads_on_Silkscreen->GetValue() );
+ tempOptions.SetUseAuxOrigin( m_useAuxOriginCheckBox->GetValue() );
+ tempOptions.SetPlotValue( m_plotModuleValueOpt->GetValue() );
+ tempOptions.SetPlotReference( m_plotModuleRefOpt->GetValue() );
+ tempOptions.SetPlotInvisibleText( m_plotInvisibleText->GetValue() );
+ tempOptions.SetScaleSelection( m_scaleOpt->GetSelection() );
+ tempOptions.SetDrillMarksType( static_cast<PCB_PLOT_PARAMS::DrillMarksType>
+ ( m_drillShapeOpt->GetSelection() ) );
+ tempOptions.SetMirror( m_plotMirrorOpt->GetValue() );
+ tempOptions.SetPlotMode( m_plotModeOpt->GetSelection() == 1 ? SKETCH : FILLED );
+ tempOptions.SetDXFPlotPolygonMode( m_DXF_plotModeOpt->GetValue() );
+ tempOptions.SetPlotViaOnMaskLayer( m_plotNoViaOnMaskOpt->GetValue() );
+
+ if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() ) // Currently, only DXF supports this option
+ tempOptions.SetTextMode( PLOTTEXTMODE_DEFAULT );
+ else
+ tempOptions.SetTextMode( m_DXF_plotTextStrokeFontOpt->GetValue() ?
+ PLOTTEXTMODE_DEFAULT : PLOTTEXTMODE_NATIVE );
+
+ // Update settings from text fields. Rewrite values back to the fields,
+ // since the values may have been constrained by the setters.
+
+ // read HPLG pen size (this param is stored in mils)
+ wxString msg = m_HPGLPenSizeOpt->GetValue();
+ int tmp = ValueFromString( g_UserUnit, msg ) / IU_PER_MILS;
+
+ if( !tempOptions.SetHPGLPenDiameter( tmp ) )
+ {
+ msg = StringFromValue( g_UserUnit, tempOptions.GetHPGLPenDiameter() * IU_PER_MILS );
+ m_HPGLPenSizeOpt->SetValue( msg );
+ msg.Printf( _( "HPGL pen size constrained." ) );
+ reporter.Report( msg, REPORTER::RPT_INFO );
+ }
+
+ // Read HPGL pen overlay (this param is stored in mils)
+ msg = m_HPGLPenOverlayOpt->GetValue();
+ tmp = ValueFromString( g_UserUnit, msg ) / IU_PER_MILS;
+
+ if( !tempOptions.SetHPGLPenOverlay( tmp ) )
+ {
+ msg = StringFromValue( g_UserUnit,
+ tempOptions.GetHPGLPenOverlay() * IU_PER_MILS );
+ m_HPGLPenOverlayOpt->SetValue( msg );
+ msg.Printf( _( "HPGL pen overlay constrained." ) );
+ reporter.Report( msg, REPORTER::RPT_INFO );
+ }
+
+ // Default linewidth
+ msg = m_linesWidth->GetValue();
+ tmp = ValueFromString( g_UserUnit, msg );
+
+ if( !tempOptions.SetLineWidth( tmp ) )
+ {
+ msg = StringFromValue( g_UserUnit, tempOptions.GetLineWidth() );
+ m_linesWidth->SetValue( msg );
+ msg.Printf( _( "Default line width constrained." ) );
+ reporter.Report( msg, REPORTER::RPT_INFO );
+ }
+
+ // X scale
+ double tmpDouble;
+ msg = m_fineAdjustXscaleOpt->GetValue();
+ msg.ToDouble( &tmpDouble );
+
+ if( !setDouble( &m_XScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
+ {
+ msg.Printf( wxT( "%f" ), m_XScaleAdjust );
+ m_fineAdjustXscaleOpt->SetValue( msg );
+ msg.Printf( _( "X scale constrained." ) );
+ reporter.Report( msg, REPORTER::RPT_INFO );
+ }
+
+ ConfigBaseWriteDouble( m_config, OPTKEY_PLOT_X_FINESCALE_ADJ, m_XScaleAdjust );
+
+ // Y scale
+ msg = m_fineAdjustYscaleOpt->GetValue();
+ msg.ToDouble( &tmpDouble );
+
+ if( !setDouble( &m_YScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
+ {
+ msg.Printf( wxT( "%f" ), m_YScaleAdjust );
+ m_fineAdjustYscaleOpt->SetValue( msg );
+ msg.Printf( _( "Y scale constrained." ) );
+ reporter.Report( msg, REPORTER::RPT_INFO );
+ }
+
+ ConfigBaseWriteDouble( m_config, OPTKEY_PLOT_Y_FINESCALE_ADJ, m_YScaleAdjust );
+
+ // PS Width correction
+ msg = m_PSFineAdjustWidthOpt->GetValue();
+ int itmp = ValueFromString( g_UserUnit, msg );
+
+ if( !setInt( &m_PSWidthAdjust, itmp, m_widthAdjustMinValue, m_widthAdjustMaxValue ) )
+ {
+ msg = StringFromValue( g_UserUnit, m_PSWidthAdjust );
+ m_PSFineAdjustWidthOpt->SetValue( msg );
+ msg.Printf( _( "Width correction constrained. "
+ "The reasonable width correction value must be in a range of "
+ " [%+f; %+f] (%s) for current design rules. " ),
+ To_User_Unit( g_UserUnit, m_widthAdjustMinValue ),
+ To_User_Unit( g_UserUnit, m_widthAdjustMaxValue ),
+ ( g_UserUnit == INCHES ) ? wxT( "\"" ) : wxT( "mm" ) );
+ reporter.Report( msg, REPORTER::RPT_WARNING );
+ }
+
+ // Store m_PSWidthAdjust in mm in user config
+ ConfigBaseWriteDouble( m_config, CONFIG_PS_FINEWIDTH_ADJ,
+ (double)m_PSWidthAdjust / IU_PER_MM );
+
+ tempOptions.SetFormat( getPlotFormat() );
+
+ tempOptions.SetUseGerberProtelExtensions( m_useGerberExtensions->GetValue() );
+ tempOptions.SetUseGerberAttributes( m_useGerberAttributes->GetValue() );
+ tempOptions.SetGerberPrecision( m_rbGerberFormat->GetSelection() == 0 ? 5 : 6 );
+
+ LSET selectedLayers;
+
+ for( unsigned i = 0; i < m_layerList.size(); i++ )
+ {
+ if( m_layerCheckListBox->IsChecked( i ) )
+ selectedLayers.set( m_layerList[i] );
+ }
+
+ tempOptions.SetLayerSelection( selectedLayers );
+ tempOptions.SetNegative( m_plotPSNegativeOpt->GetValue() );
+ tempOptions.SetA4Output( m_forcePSA4OutputOpt->GetValue() );
+
+ // Set output directory and replace backslashes with forward ones
+ wxString dirStr;
+ dirStr = m_outputDirectoryName->GetValue();
+ dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
+ tempOptions.SetOutputDirectory( dirStr );
+
+ if( !m_plotOpts.IsSameAs( tempOptions, false ) )
+ {
+ // First, mark board as modified only for parameters saved in file
+ if( !m_plotOpts.IsSameAs( tempOptions, true ) )
+ m_parent->OnModify();
+
+ // Now, save any change, for the session
+ m_parent->SetPlotSettings( tempOptions );
+ m_plotOpts = tempOptions;
+ }
+}
+
+
+void DIALOG_PLOT::Plot( wxCommandEvent& event )
+{
+ applyPlotSettings();
+
+ // Create output directory if it does not exist (also transform it in
+ // absolute form). Bail if it fails
+ wxFileName outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() );
+ wxString boardFilename = m_parent->GetBoard()->GetFileName();
+ REPORTER& reporter = m_messagesPanel->Reporter();
+
+ if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) )
+ {
+ wxString msg;
+ msg.Printf( _( "Could not write plot files to folder \"%s\"." ),
+ GetChars( outputDir.GetPath() ) );
+ DisplayError( this, msg );
+ return;
+ }
+
+ m_plotOpts.SetAutoScale( false );
+ m_plotOpts.SetScale( 1 );
+
+ switch( m_plotOpts.GetScaleSelection() )
+ {
+ default:
+ break;
+
+ case 0: // Autoscale option
+ m_plotOpts.SetAutoScale( true );
+ break;
+
+ case 2: // 3:2 option
+ m_plotOpts.SetScale( 1.5 );
+ break;
+
+ case 3: // 2:1 option
+ m_plotOpts.SetScale( 2 );
+ break;
+
+ case 4: // 3:1 option
+ m_plotOpts.SetScale( 3 );
+ break;
+ }
+
+ /* If the scale factor edit controls are disabled or the scale value
+ * is 0, don't adjust the base scale factor. This fixes a bug when
+ * the default scale adjust is initialized to 0 and saved in program
+ * settings resulting in a divide by zero fault.
+ */
+ if( m_fineAdjustXscaleOpt->IsEnabled() && m_XScaleAdjust != 0.0 )
+ m_plotOpts.SetFineScaleAdjustX( m_XScaleAdjust );
+
+ if( m_fineAdjustYscaleOpt->IsEnabled() && m_YScaleAdjust != 0.0 )
+ m_plotOpts.SetFineScaleAdjustY( m_YScaleAdjust );
+
+ if( m_PSFineAdjustWidthOpt->IsEnabled() )
+ m_plotOpts.SetWidthAdjust( m_PSWidthAdjust );
+
+ wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) );
+
+ // Test for a reasonable scale value
+ // XXX could this actually happen? isn't it constrained in the apply
+ // function?
+ if( m_plotOpts.GetScale() < PLOT_MIN_SCALE )
+ DisplayInfoMessage( this,
+ _( "Warning: Scale option set to a very small value" ) );
+
+ if( m_plotOpts.GetScale() > PLOT_MAX_SCALE )
+ DisplayInfoMessage( this,
+ _( "Warning: Scale option set to a very large value" ) );
+
+ // Save the current plot options in the board
+ m_parent->SetPlotSettings( m_plotOpts );
+
+ wxBusyCursor dummy;
+
+ for( LSEQ seq = m_plotOpts.GetLayerSelection().UIOrder(); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ // Pick the basename from the board file
+ wxFileName fn( boardFilename );
+
+ // Use Gerber Extensions based on layer number
+ // (See http://en.wikipedia.org/wiki/Gerber_File)
+ if( m_plotOpts.GetFormat() == PLOT_FORMAT_GERBER && m_useGerberExtensions->GetValue() )
+ file_ext = GetGerberProtelExtension( layer );
+
+ // Create file name (from the English default layer name for non copper layers).
+ BuildPlotFileName( &fn, outputDir.GetPath(),
+// m_board->GetStandardLayerName( layer ),
+ m_board->GetLayerName( layer ),
+ file_ext );
+
+ LOCALE_IO toggle;
+
+ BOARD* board = m_parent->GetBoard();
+ PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString );
+
+ // Print diags in messages box:
+ wxString msg;
+
+ if( plotter )
+ {
+ PlotOneBoardLayer( board, plotter, layer, m_plotOpts );
+ plotter->EndPlot();
+ delete plotter;
+
+ msg.Printf( _( "Plot file '%s' created." ), GetChars( fn.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ACTION );
+ }
+ else
+ {
+ msg.Printf( _( "Unable to create file '%s'." ), GetChars( fn.GetFullPath() ) );
+ reporter.Report( msg, REPORTER::RPT_ERROR );
+ }
+ }
+
+ // If no layer selected, we have nothing plotted.
+ // Prompt user if it happens because he could think there is a bug in Pcbnew.
+ if( !m_plotOpts.GetLayerSelection().any() )
+ DisplayError( this, _( "No layer selected" ) );
+}
diff --git a/pcbnew/dialogs/dialog_plot.h b/pcbnew/dialogs/dialog_plot.h
new file mode 100644
index 0000000..637b246
--- /dev/null
+++ b/pcbnew/dialogs/dialog_plot.h
@@ -0,0 +1,81 @@
+/**
+ * @file dialog_plot.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <class_board.h>
+#include <dialog_plot_base.h>
+#include <pcb_plot_params.h>
+
+/**
+ * Class DIALOG_PLOT is the dialog to set the plot options, and create plot files
+ * in various formats.
+ */
+class DIALOG_PLOT : public DIALOG_PLOT_BASE
+{
+public:
+ DIALOG_PLOT( PCB_EDIT_FRAME* parent );
+private:
+ PCB_EDIT_FRAME* m_parent;
+ BOARD* m_board;
+ wxConfigBase* m_config;
+ LSEQ m_layerList; // List to hold CheckListBox layer numbers
+ double m_XScaleAdjust; // X scale factor adjust to compensate
+ // plotter X scaling error
+ double m_YScaleAdjust; // X scale factor adjust to compensate
+ // plotter Y scaling error
+ int m_PSWidthAdjust; // Global width correction for exact line width
+ // in postscript output.
+ // this is a correction factor for tracks width
+ // when plotted
+ int m_widthAdjustMinValue; // Global track width limits
+ int m_widthAdjustMaxValue; // tracks width will be "clipped" whenever the
+ // m_PSWidthAdjust to these limits.
+
+ PCB_PLOT_PARAMS m_plotOpts;
+
+ // Event called functions
+ void Plot( wxCommandEvent& event ) override;
+ void OnQuit( wxCommandEvent& event ) override;
+ void OnClose( wxCloseEvent& event ) override;
+ void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) override;
+ void OnRightClick( wxMouseEvent& event ) override;
+ void OnPopUpLayers( wxCommandEvent& event ) override;
+ void SetPlotFormat( wxCommandEvent& event ) override;
+ void OnChangeDXFPlotMode( wxCommandEvent& event ) override;
+ void OnSetScaleOpt( wxCommandEvent& event ) override;
+ void CreateDrillFile( wxCommandEvent& event ) override;
+
+ // orther functions
+ void init_Dialog(); // main initialization
+ void applyPlotSettings();
+ PlotFormat getPlotFormat();
+
+ void setPlotModeChoiceSelection( EDA_DRAW_MODE_T aPlotMode )
+ {
+ m_plotModeOpt->SetSelection( aPlotMode == SKETCH ? 1 : 0 );
+ }
+};
diff --git a/pcbnew/dialogs/dialog_plot_base.cpp b/pcbnew/dialogs/dialog_plot_base.cpp
new file mode 100644
index 0000000..84e03d0
--- /dev/null
+++ b/pcbnew/dialogs/dialog_plot_base.cpp
@@ -0,0 +1,471 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jul 2 2017)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "wx_html_report_panel.h"
+
+#include "dialog_plot_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_PLOT_BASE::DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ m_MainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bupperSizer;
+ bupperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizerPlotFmt;
+ bSizerPlotFmt = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextPlotFmt = new wxStaticText( this, wxID_ANY, _("Plot format:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextPlotFmt->Wrap( -1 );
+ bSizerPlotFmt->Add( m_staticTextPlotFmt, 0, wxTOP, 5 );
+
+ wxString m_plotFormatOptChoices[] = { _("Gerber"), _("Postscript"), _("SVG"), _("DXF"), _("HPGL"), _("PDF") };
+ int m_plotFormatOptNChoices = sizeof( m_plotFormatOptChoices ) / sizeof( wxString );
+ m_plotFormatOpt = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_plotFormatOptNChoices, m_plotFormatOptChoices, 0 );
+ m_plotFormatOpt->SetSelection( 0 );
+ bSizerPlotFmt->Add( m_plotFormatOpt, 0, 0, 5 );
+
+
+ bupperSizer->Add( bSizerPlotFmt, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bSizerOutDir;
+ bSizerOutDir = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextDir = new wxStaticText( this, wxID_ANY, _("Output directory:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextDir->Wrap( -1 );
+ bSizerOutDir->Add( m_staticTextDir, 0, wxEXPAND|wxTOP|wxLEFT, 5 );
+
+ wxBoxSizer* bSizer29;
+ bSizer29 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_outputDirectoryName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_outputDirectoryName->SetToolTip( _("Target directory for plot files. Can be absolute or relative to the board file location.") );
+
+ bSizer29->Add( m_outputDirectoryName, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
+ m_browseButton = new wxButton( this, wxID_ANY, _("Browse..."), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer29->Add( m_browseButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
+
+
+ bSizerOutDir->Add( bSizer29, 1, wxEXPAND, 5 );
+
+
+ bupperSizer->Add( bSizerOutDir, 1, 0, 5 );
+
+
+ m_MainSizer->Add( bupperSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bmiddleSizer;
+ bmiddleSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ m_LayersSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Layers") ), wxHORIZONTAL );
+
+ wxArrayString m_layerCheckListBoxChoices;
+ m_layerCheckListBox = new wxCheckListBox( m_LayersSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_layerCheckListBoxChoices, 0 );
+ m_LayersSizer->Add( m_layerCheckListBox, 1, wxEXPAND, 5 );
+
+
+ bmiddleSizer->Add( m_LayersSizer, 1, wxALL|wxEXPAND, 3 );
+
+ m_PlotOptionsSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbOptionsSizer;
+ sbOptionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options") ), wxVERTICAL );
+
+ wxBoxSizer* bSizer192;
+ bSizer192 = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizerPlotItems;
+ bSizerPlotItems = new wxBoxSizer( wxVERTICAL );
+
+ m_plotSheetRef = new wxCheckBox( sbOptionsSizer->GetStaticBox(), wxID_ANY, _("Plot sheet reference on all layers"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerPlotItems->Add( m_plotSheetRef, 0, wxTOP|wxRIGHT|wxLEFT, 2 );
+
+ m_plotPads_on_Silkscreen = new wxCheckBox( sbOptionsSizer->GetStaticBox(), ID_ALLOW_PRINT_PAD_ON_SILKSCREEN, _("Plot pads on silkscreen"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_plotPads_on_Silkscreen->SetToolTip( _("Enable plotting of pads on silkscreen layers\nWhen disabled, pads are never plotted on silkscreen layers\nWhen enabled, pads are plotted only if they appear on silkscreen layers") );
+
+ bSizerPlotItems->Add( m_plotPads_on_Silkscreen, 0, wxALL, 2 );
+
+ m_plotModuleValueOpt = new wxCheckBox( sbOptionsSizer->GetStaticBox(), wxID_ANY, _("Plot footprint values"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_plotModuleValueOpt->SetValue(true);
+ bSizerPlotItems->Add( m_plotModuleValueOpt, 0, wxTOP|wxRIGHT|wxLEFT, 2 );
+
+ m_plotModuleRefOpt = new wxCheckBox( sbOptionsSizer->GetStaticBox(), ID_PRINT_REF, _("Plot footprint references"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerPlotItems->Add( m_plotModuleRefOpt, 0, wxTOP|wxRIGHT|wxLEFT, 2 );
+
+ m_plotInvisibleText = new wxCheckBox( sbOptionsSizer->GetStaticBox(), wxID_ANY, _("Force plotting of invisible values/references"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_plotInvisibleText->SetToolTip( _("Force plot invisible values and/or references") );
+
+ bSizerPlotItems->Add( m_plotInvisibleText, 0, wxALL, 2 );
+
+ m_plotNoViaOnMaskOpt = new wxCheckBox( sbOptionsSizer->GetStaticBox(), wxID_ANY, _("Do not tent vias"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_plotNoViaOnMaskOpt->SetToolTip( _("Remove soldermask on vias") );
+
+ bSizerPlotItems->Add( m_plotNoViaOnMaskOpt, 0, wxTOP|wxRIGHT|wxLEFT, 2 );
+
+ m_excludeEdgeLayerOpt = new wxCheckBox( sbOptionsSizer->GetStaticBox(), wxID_ANY, _("Exclude PCB edge layer from other layers"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_excludeEdgeLayerOpt->SetToolTip( _("Exclude contents of the pcb edge layer from all other layers") );
+
+ bSizerPlotItems->Add( m_excludeEdgeLayerOpt, 0, wxALL, 2 );
+
+ m_plotMirrorOpt = new wxCheckBox( sbOptionsSizer->GetStaticBox(), ID_MIROR_OPT, _("Mirrored plot"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerPlotItems->Add( m_plotMirrorOpt, 0, wxALL, 2 );
+
+ m_plotPSNegativeOpt = new wxCheckBox( sbOptionsSizer->GetStaticBox(), wxID_ANY, _("Negative plot"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerPlotItems->Add( m_plotPSNegativeOpt, 0, wxALL, 2 );
+
+ m_useAuxOriginCheckBox = new wxCheckBox( sbOptionsSizer->GetStaticBox(), wxID_ANY, _("Use auxiliary axis as origin"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_useAuxOriginCheckBox->SetToolTip( _("Use auxiliary axis as coordinates origin in plot files") );
+
+ bSizerPlotItems->Add( m_useAuxOriginCheckBox, 0, wxALL, 2 );
+
+
+ bSizer192->Add( bSizerPlotItems, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer14;
+ bSizer14 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText11 = new wxStaticText( sbOptionsSizer->GetStaticBox(), wxID_ANY, _("Drill marks:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText11->Wrap( -1 );
+ bSizer14->Add( m_staticText11, 0, wxRIGHT|wxLEFT, 5 );
+
+ wxString m_drillShapeOptChoices[] = { _("None"), _("Small"), _("Actual size") };
+ int m_drillShapeOptNChoices = sizeof( m_drillShapeOptChoices ) / sizeof( wxString );
+ m_drillShapeOpt = new wxChoice( sbOptionsSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_drillShapeOptNChoices, m_drillShapeOptChoices, 0 );
+ m_drillShapeOpt->SetSelection( 0 );
+ bSizer14->Add( m_drillShapeOpt, 0, wxEXPAND|wxLEFT, 5 );
+
+ m_staticText12 = new wxStaticText( sbOptionsSizer->GetStaticBox(), wxID_ANY, _("Scaling:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText12->Wrap( -1 );
+ bSizer14->Add( m_staticText12, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_scaleOptChoices[] = { _("Auto"), _("1:1"), _("3:2"), _("2:1"), _("3:1") };
+ int m_scaleOptNChoices = sizeof( m_scaleOptChoices ) / sizeof( wxString );
+ m_scaleOpt = new wxChoice( sbOptionsSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_scaleOptNChoices, m_scaleOptChoices, 0 );
+ m_scaleOpt->SetSelection( 1 );
+ bSizer14->Add( m_scaleOpt, 0, wxEXPAND|wxLEFT, 5 );
+
+ m_staticText13 = new wxStaticText( sbOptionsSizer->GetStaticBox(), wxID_ANY, _("Plot mode:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText13->Wrap( -1 );
+ bSizer14->Add( m_staticText13, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_plotModeOptChoices[] = { _("Filled"), _("Sketch") };
+ int m_plotModeOptNChoices = sizeof( m_plotModeOptChoices ) / sizeof( wxString );
+ m_plotModeOpt = new wxChoice( sbOptionsSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_plotModeOptNChoices, m_plotModeOptChoices, 0 );
+ m_plotModeOpt->SetSelection( 0 );
+ bSizer14->Add( m_plotModeOpt, 0, wxEXPAND|wxLEFT, 5 );
+
+ m_textDefaultPenSize = new wxStaticText( sbOptionsSizer->GetStaticBox(), wxID_ANY, _("Default line width"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_textDefaultPenSize->Wrap( -1 );
+ m_textDefaultPenSize->SetToolTip( _("Pen size used to draw items that have no pen size specified.\nUsed mainly to draw items in sketch mode.") );
+
+ bSizer14->Add( m_textDefaultPenSize, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_linesWidth = new wxTextCtrl( sbOptionsSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_linesWidth->SetToolTip( _("Line width for, e.g., sheet references.") );
+
+ bSizer14->Add( m_linesWidth, 0, wxBOTTOM|wxEXPAND|wxLEFT, 5 );
+
+
+ bSizer192->Add( bSizer14, 1, wxRIGHT|wxLEFT, 3 );
+
+
+ sbOptionsSizer->Add( bSizer192, 0, wxEXPAND, 5 );
+
+
+ m_PlotOptionsSizer->Add( sbOptionsSizer, 0, wxALL|wxEXPAND, 3 );
+
+ wxStaticBoxSizer* sbSizerSoldMaskLayerOpt;
+ sbSizerSoldMaskLayerOpt = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Current solder mask settings:") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgSizerSoldMaskOpts;
+ fgSizerSoldMaskOpts = new wxFlexGridSizer( 2, 2, 0, 0 );
+ fgSizerSoldMaskOpts->SetFlexibleDirection( wxBOTH );
+ fgSizerSoldMaskOpts->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_SolderMaskMarginLabel = new wxStaticText( sbSizerSoldMaskLayerOpt->GetStaticBox(), wxID_ANY, _("Solder mask clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMarginLabel->Wrap( -1 );
+ m_SolderMaskMarginLabel->SetToolTip( _("Margin between pads and solder mask") );
+
+ fgSizerSoldMaskOpts->Add( m_SolderMaskMarginLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_SolderMaskMarginCurrValue = new wxStaticText( sbSizerSoldMaskLayerOpt->GetStaticBox(), wxID_ANY, _("val"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMarginCurrValue->Wrap( -1 );
+ fgSizerSoldMaskOpts->Add( m_SolderMaskMarginCurrValue, 0, wxALL, 5 );
+
+ m_solderMaskMinWidthLabel = new wxStaticText( sbSizerSoldMaskLayerOpt->GetStaticBox(), wxID_ANY, _("Solder mask min width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_solderMaskMinWidthLabel->Wrap( -1 );
+ m_solderMaskMinWidthLabel->SetToolTip( _("Minimum distance between 2 pad areas.\nTwo pad areas nearer than this value will be merged during plotting") );
+
+ fgSizerSoldMaskOpts->Add( m_solderMaskMinWidthLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_SolderMaskMinWidthCurrValue = new wxStaticText( sbSizerSoldMaskLayerOpt->GetStaticBox(), wxID_ANY, _("val"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_SolderMaskMinWidthCurrValue->Wrap( -1 );
+ fgSizerSoldMaskOpts->Add( m_SolderMaskMinWidthCurrValue, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ sbSizerSoldMaskLayerOpt->Add( fgSizerSoldMaskOpts, 1, wxEXPAND, 5 );
+
+
+ m_PlotOptionsSizer->Add( sbSizerSoldMaskLayerOpt, 1, wxEXPAND, 5 );
+
+ m_GerberOptionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Gerber Options") ), wxHORIZONTAL );
+
+ wxBoxSizer* bSizerGbrOpt;
+ bSizerGbrOpt = new wxBoxSizer( wxVERTICAL );
+
+ m_useGerberExtensions = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Use Protel filename extensions"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_useGerberExtensions->SetToolTip( _("Use conventional Protel Gerber extensions - .GBL, .GTL, etc...") );
+
+ bSizerGbrOpt->Add( m_useGerberExtensions, 0, wxALL, 2 );
+
+ m_useGerberAttributes = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Include extended attributes"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_useGerberAttributes->SetToolTip( _("Include extended attributes (X2 Gerber files format) in the Gerber file") );
+
+ bSizerGbrOpt->Add( m_useGerberAttributes, 0, wxALL, 2 );
+
+ m_subtractMaskFromSilk = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Subtract soldermask from silkscreen"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_subtractMaskFromSilk->SetToolTip( _("Remove silkscreen from areas without soldermask") );
+
+ bSizerGbrOpt->Add( m_subtractMaskFromSilk, 0, wxALL, 2 );
+
+
+ m_GerberOptionsSizer->Add( bSizerGbrOpt, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ wxString m_rbGerberFormatChoices[] = { _("4.5 (unit mm)"), _("4.6 (unit mm)") };
+ int m_rbGerberFormatNChoices = sizeof( m_rbGerberFormatChoices ) / sizeof( wxString );
+ m_rbGerberFormat = new wxRadioBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Format"), wxDefaultPosition, wxDefaultSize, m_rbGerberFormatNChoices, m_rbGerberFormatChoices, 1, wxRA_SPECIFY_COLS );
+ m_rbGerberFormat->SetSelection( 0 );
+ m_rbGerberFormat->SetToolTip( _("Resolution of coordinates in Gerber files.\nUse the higher value if possible.") );
+
+ m_GerberOptionsSizer->Add( m_rbGerberFormat, 1, wxEXPAND|wxALL, 5 );
+
+
+ m_PlotOptionsSizer->Add( m_GerberOptionsSizer, 0, wxALL|wxEXPAND, 3 );
+
+ m_HPGLOptionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("HPGL Options") ), wxVERTICAL );
+
+ wxBoxSizer* bSizer22;
+ bSizer22 = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizer20;
+ bSizer20 = new wxBoxSizer( wxVERTICAL );
+
+ m_textPenSize = new wxStaticText( m_HPGLOptionsSizer->GetStaticBox(), wxID_ANY, _("Pen size"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_textPenSize->Wrap( -1 );
+ bSizer20->Add( m_textPenSize, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_HPGLPenSizeOpt = new wxTextCtrl( m_HPGLOptionsSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer20->Add( m_HPGLPenSizeOpt, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizer22->Add( bSizer20, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer21;
+ bSizer21 = new wxBoxSizer( wxVERTICAL );
+
+ m_textPenOvr = new wxStaticText( m_HPGLOptionsSizer->GetStaticBox(), wxID_ANY, _("Pen overlay"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_textPenOvr->Wrap( -1 );
+ bSizer21->Add( m_textPenOvr, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_HPGLPenOverlayOpt = new wxTextCtrl( m_HPGLOptionsSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_HPGLPenOverlayOpt->SetToolTip( _("Set plot overlay for filling") );
+
+ bSizer21->Add( m_HPGLPenOverlayOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ bSizer22->Add( bSizer21, 1, wxEXPAND, 5 );
+
+
+ m_HPGLOptionsSizer->Add( bSizer22, 1, wxEXPAND, 5 );
+
+
+ m_PlotOptionsSizer->Add( m_HPGLOptionsSizer, 0, wxALL|wxEXPAND, 3 );
+
+ m_PSOptionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Postscript Options") ), wxVERTICAL );
+
+ wxBoxSizer* bSizer17;
+ bSizer17 = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bSizer18;
+ bSizer18 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText7 = new wxStaticText( m_PSOptionsSizer->GetStaticBox(), wxID_ANY, _("X scale:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText7->Wrap( -1 );
+ bSizer18->Add( m_staticText7, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_fineAdjustXscaleOpt = new wxTextCtrl( m_PSOptionsSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_fineAdjustXscaleOpt->SetToolTip( _("Set global X scale adjust for exact scale postscript output.") );
+
+ bSizer18->Add( m_fineAdjustXscaleOpt, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizer17->Add( bSizer18, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer19;
+ bSizer19 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText8 = new wxStaticText( m_PSOptionsSizer->GetStaticBox(), wxID_ANY, _("Y scale:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText8->Wrap( -1 );
+ bSizer19->Add( m_staticText8, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_fineAdjustYscaleOpt = new wxTextCtrl( m_PSOptionsSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_fineAdjustYscaleOpt->SetToolTip( _("Set global Y scale adjust for exact scale postscript output.") );
+
+ bSizer19->Add( m_fineAdjustYscaleOpt, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizer17->Add( bSizer19, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer191;
+ bSizer191 = new wxBoxSizer( wxVERTICAL );
+
+ m_textPSFineAdjustWidth = new wxStaticText( m_PSOptionsSizer->GetStaticBox(), wxID_ANY, _("Width correction"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_textPSFineAdjustWidth->Wrap( -1 );
+ bSizer191->Add( m_textPSFineAdjustWidth, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_PSFineAdjustWidthOpt = new wxTextCtrl( m_PSOptionsSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_PSFineAdjustWidthOpt->SetToolTip( _("Set global width correction for exact width postscript output.\nThese width correction is intended to compensate tracks width and also pads and vias size errors.\nThe reasonable width correction value must be in a range of [-(MinTrackWidth-1), +(MinClearanceValue-1)] in decimils.") );
+
+ bSizer191->Add( m_PSFineAdjustWidthOpt, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ bSizer17->Add( bSizer191, 1, wxEXPAND, 5 );
+
+
+ m_PSOptionsSizer->Add( bSizer17, 1, wxEXPAND, 5 );
+
+ m_forcePSA4OutputOpt = new wxCheckBox( m_PSOptionsSizer->GetStaticBox(), wxID_ANY, _("Force A4 output"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_PSOptionsSizer->Add( m_forcePSA4OutputOpt, 0, wxALL, 2 );
+
+
+ m_PlotOptionsSizer->Add( m_PSOptionsSizer, 0, wxALL|wxEXPAND, 3 );
+
+ m_SizerDXF_options = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("DXF options") ), wxVERTICAL );
+
+ m_DXF_plotModeOpt = new wxCheckBox( m_SizerDXF_options->GetStaticBox(), wxID_ANY, _("Plot all layers in outline (polygon) mode"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_DXF_plotModeOpt->SetValue(true);
+ m_DXF_plotModeOpt->SetToolTip( _("DXF only:\nCheck to plot all layers in polygon mode.\nUncheck to plot in sketch mode layers that don't support polygons (*.SilkS, *_User, Edge.Cuts, Margin, *.CrtYd, *.Fab)\nand plot in polygon mode other layers (*.Cu, *.Adhes, *.Paste, *.Mask)") );
+
+ m_SizerDXF_options->Add( m_DXF_plotModeOpt, 0, wxALL, 2 );
+
+ m_DXF_plotTextStrokeFontOpt = new wxCheckBox( m_SizerDXF_options->GetStaticBox(), wxID_ANY, _("Use Pcbnew font to plot texts"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_DXF_plotTextStrokeFontOpt->SetValue(true);
+ m_DXF_plotTextStrokeFontOpt->SetToolTip( _("Check to use Pcbnew stroke font\nUncheck to plot oneline ASCII texts as editable text (using DXF font)") );
+
+ m_SizerDXF_options->Add( m_DXF_plotTextStrokeFontOpt, 0, wxALL, 2 );
+
+
+ m_PlotOptionsSizer->Add( m_SizerDXF_options, 0, wxEXPAND, 5 );
+
+
+ bmiddleSizer->Add( m_PlotOptionsSizer, 0, 0, 5 );
+
+
+ m_MainSizer->Add( bmiddleSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* sbSizerMsg;
+ sbSizerMsg = new wxBoxSizer( wxVERTICAL );
+
+ m_messagesPanel = new WX_HTML_REPORT_PANEL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ m_messagesPanel->SetMinSize( wxSize( -300,150 ) );
+
+ sbSizerMsg->Add( m_messagesPanel, 1, wxEXPAND | wxALL, 5 );
+
+
+ m_MainSizer->Add( sbSizerMsg, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerButtons;
+ bSizerButtons = new wxBoxSizer( wxHORIZONTAL );
+
+ m_plotButton = new wxButton( this, wxID_ANY, _("Plot"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_plotButton->SetDefault();
+ bSizerButtons->Add( m_plotButton, 0, wxALL, 5 );
+
+ m_buttonDrill = new wxButton( this, ID_CREATE_DRILL_FILE, _("Generate Drill File"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( m_buttonDrill, 0, wxALL, 5 );
+
+ m_buttonQuit = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButtons->Add( m_buttonQuit, 0, wxALL, 5 );
+
+
+ m_MainSizer->Add( bSizerButtons, 0, wxALIGN_RIGHT|wxRIGHT|wxLEFT, 5 );
+
+
+ this->SetSizer( m_MainSizer );
+ this->Layout();
+ m_popMenu = new wxMenu();
+ wxMenuItem* m_menuItem1;
+ m_menuItem1 = new wxMenuItem( m_popMenu, ID_LAYER_FAB, wxString( _("Select Fab Layers") ) , wxEmptyString, wxITEM_NORMAL );
+ m_popMenu->Append( m_menuItem1 );
+
+ wxMenuItem* m_menuItem2;
+ m_menuItem2 = new wxMenuItem( m_popMenu, ID_SELECT_COPPER_LAYERS, wxString( _("Select all Copper Layers") ) , wxEmptyString, wxITEM_NORMAL );
+ m_popMenu->Append( m_menuItem2 );
+
+ wxMenuItem* m_menuItem3;
+ m_menuItem3 = new wxMenuItem( m_popMenu, ID_DESELECT_COPPER_LAYERS, wxString( _("Deselect all Copper Layers") ) , wxEmptyString, wxITEM_NORMAL );
+ m_popMenu->Append( m_menuItem3 );
+
+ wxMenuItem* m_menuItem4;
+ m_menuItem4 = new wxMenuItem( m_popMenu, ID_SELECT_ALL_LAYERS, wxString( _("Select all Layers") ) , wxEmptyString, wxITEM_NORMAL );
+ m_popMenu->Append( m_menuItem4 );
+
+ wxMenuItem* m_menuItem5;
+ m_menuItem5 = new wxMenuItem( m_popMenu, ID_DESELECT_ALL_LAYERS, wxString( _("Deselect all Layers") ) , wxEmptyString, wxITEM_NORMAL );
+ m_popMenu->Append( m_menuItem5 );
+
+ this->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( DIALOG_PLOT_BASE::DIALOG_PLOT_BASEOnContextMenu ), NULL, this );
+
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PLOT_BASE::OnClose ) );
+ this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_PLOT_BASE::OnInitDialog ) );
+ this->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( DIALOG_PLOT_BASE::OnRightClick ) );
+ m_plotFormatOpt->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::SetPlotFormat ), NULL, this );
+ m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnOutputDirectoryBrowseClicked ), NULL, this );
+ m_layerCheckListBox->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( DIALOG_PLOT_BASE::OnRightClick ), NULL, this );
+ m_scaleOpt->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnSetScaleOpt ), NULL, this );
+ m_DXF_plotModeOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnChangeDXFPlotMode ), NULL, this );
+ m_plotButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_BASE::Plot ), NULL, this );
+ m_buttonDrill->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_BASE::CreateDrillFile ), NULL, this );
+ m_buttonQuit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnQuit ), NULL, this );
+ this->Connect( m_menuItem1->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnPopUpLayers ) );
+ this->Connect( m_menuItem2->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnPopUpLayers ) );
+ this->Connect( m_menuItem3->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnPopUpLayers ) );
+ this->Connect( m_menuItem4->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnPopUpLayers ) );
+ this->Connect( m_menuItem5->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnPopUpLayers ) );
+}
+
+DIALOG_PLOT_BASE::~DIALOG_PLOT_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PLOT_BASE::OnClose ) );
+ this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_PLOT_BASE::OnInitDialog ) );
+ this->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( DIALOG_PLOT_BASE::OnRightClick ) );
+ m_plotFormatOpt->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::SetPlotFormat ), NULL, this );
+ m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnOutputDirectoryBrowseClicked ), NULL, this );
+ m_layerCheckListBox->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( DIALOG_PLOT_BASE::OnRightClick ), NULL, this );
+ m_scaleOpt->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnSetScaleOpt ), NULL, this );
+ m_DXF_plotModeOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnChangeDXFPlotMode ), NULL, this );
+ m_plotButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_BASE::Plot ), NULL, this );
+ m_buttonDrill->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_BASE::CreateDrillFile ), NULL, this );
+ m_buttonQuit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnQuit ), NULL, this );
+ this->Disconnect( ID_LAYER_FAB, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnPopUpLayers ) );
+ this->Disconnect( ID_SELECT_COPPER_LAYERS, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnPopUpLayers ) );
+ this->Disconnect( ID_DESELECT_COPPER_LAYERS, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnPopUpLayers ) );
+ this->Disconnect( ID_SELECT_ALL_LAYERS, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnPopUpLayers ) );
+ this->Disconnect( ID_DESELECT_ALL_LAYERS, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( DIALOG_PLOT_BASE::OnPopUpLayers ) );
+
+ delete m_popMenu;
+}
diff --git a/pcbnew/dialogs/dialog_plot_base.fbp b/pcbnew/dialogs/dialog_plot_base.fbp
new file mode 100644
index 0000000..0249857
--- /dev/null
+++ b/pcbnew/dialogs/dialog_plot_base.fbp
@@ -0,0 +1,4764 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_plot_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">Dialog_Plot_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_PLOT_BASE</property>
+ <property name="pos"></property>
+ <property name="size">733,809</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Plot</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnClose</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog">OnInitDialog</event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown">OnRightClick</event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_MainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bupperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerPlotFmt</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Plot format:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextPlotFmt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Gerber&quot; &quot;Postscript&quot; &quot;SVG&quot; &quot;DXF&quot; &quot;HPGL&quot; &quot;PDF&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotFormatOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">SetPlotFormat</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerOutDir</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Output directory:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextDir</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer29</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_outputDirectoryName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Target directory for plot files. Can be absolute or relative to the board file location.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Browse...</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_browseButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnOutputDirectoryBrowseClicked</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmiddleSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layers</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_LayersSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="parent">1</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxCheckListBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_layerCheckListBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckListBox"></event>
+ <event name="OnCheckListBoxDClick"></event>
+ <event name="OnCheckListBoxToggled"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown">OnRightClick</event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_PlotOptionsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Options</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbOptionsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer192</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerPlotItems</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Plot sheet reference on all layers</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotSheetRef</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_ALLOW_PRINT_PAD_ON_SILKSCREEN</property>
+ <property name="label">Plot pads on silkscreen</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotPads_on_Silkscreen</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Enable plotting of pads on silkscreen layers&#x0A;When disabled, pads are never plotted on silkscreen layers&#x0A;When enabled, pads are plotted only if they appear on silkscreen layers</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Plot footprint values</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotModuleValueOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_PRINT_REF</property>
+ <property name="label">Plot footprint references</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotModuleRefOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Force plotting of invisible values/references</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotInvisibleText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Force plot invisible values and/or references</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Do not tent vias</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotNoViaOnMaskOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Remove soldermask on vias</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Exclude PCB edge layer from other layers</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_excludeEdgeLayerOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Exclude contents of the pcb edge layer from all other layers</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_MIROR_OPT</property>
+ <property name="label">Mirrored plot</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotMirrorOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Negative plot</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotPSNegativeOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Use auxiliary axis as origin</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_useAuxOriginCheckBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Use auxiliary axis as coordinates origin in plot files</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer14</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Drill marks:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText11</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;None&quot; &quot;Small&quot; &quot;Actual size&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_drillShapeOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Scaling:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText12</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Auto&quot; &quot;1:1&quot; &quot;3:2&quot; &quot;2:1&quot; &quot;3:1&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_scaleOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice">OnSetScaleOpt</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Plot mode:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText13</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Filled&quot; &quot;Sketch&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotModeOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default line width</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textDefaultPenSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Pen size used to draw items that have no pen size specified.&#x0A;Used mainly to draw items in sketch mode.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_linesWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Line width for, e.g., sheet references.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Current solder mask settings:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerSoldMaskLayerOpt</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerSoldMaskOpts</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">2</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder mask clearance:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderMaskMarginLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Margin between pads and solder mask</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">val</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderMaskMarginCurrValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Solder mask min width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_solderMaskMinWidthLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Minimum distance between 2 pad areas.&#x0A;Two pad areas nearer than this value will be merged during plotting</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">val</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SolderMaskMinWidthCurrValue</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Gerber Options</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_GerberOptionsSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="parent">1</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerGbrOpt</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Use Protel filename extensions</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_useGerberExtensions</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Use conventional Protel Gerber extensions - .GBL, .GTL, etc...</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Include extended attributes</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_useGerberAttributes</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Include extended attributes (X2 Gerber files format) in the Gerber file</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Subtract soldermask from silkscreen</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_subtractMaskFromSilk</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Remove silkscreen from areas without soldermask</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;4.5 (unit mm)&quot; &quot;4.6 (unit mm)&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Format</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbGerberFormat</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Resolution of coordinates in Gerber files.&#x0A;Use the higher value if possible.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">HPGL Options</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_HPGLOptionsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer22</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer20</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pen size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textPenSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_HPGLPenSizeOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer21</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pen overlay</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textPenOvr</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_HPGLPenOverlayOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Set plot overlay for filling</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="0">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Postscript Options</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_PSOptionsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer17</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer18</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">X scale:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText7</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_fineAdjustXscaleOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Set global X scale adjust for exact scale postscript output.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer19</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Y scale:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText8</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_fineAdjustYscaleOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Set global Y scale adjust for exact scale postscript output.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer191</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Width correction</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_textPSFineAdjustWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PSFineAdjustWidthOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Set global width correction for exact width postscript output.&#x0A;These width correction is intended to compensate tracks width and also pads and vias size errors.&#x0A;The reasonable width correction value must be in a range of [-(MinTrackWidth-1), +(MinClearanceValue-1)] in decimils.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Force A4 output</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_forcePSA4OutputOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">DXF options</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_SizerDXF_options</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Plot all layers in outline (polygon) mode</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DXF_plotModeOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">DXF only:&#x0A;Check to plot all layers in polygon mode.&#x0A;Uncheck to plot in sketch mode layers that don&apos;t support polygons (*.SilkS, *_User, Edge.Cuts, Margin, *.CrtYd, *.Fab)&#x0A;and plot in polygon mode other layers (*.Cu, *.Adhes, *.Paste, *.Mask)</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnChangeDXFPlotMode</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">2</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Use Pcbnew font to plot texts</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DXF_plotTextStrokeFontOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Check to use Pcbnew stroke font&#x0A;Uncheck to plot oneline ASCII texts as editable text (using DXF font)</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">sbSizerMsg</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxPanel" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-300,150</property>
+ <property name="moveable">1</property>
+ <property name="name">m_messagesPanel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass">WX_HTML_REPORT_PANEL; wx_html_report_panel.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerButtons</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Plot</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_plotButton</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">Plot</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">ID_CREATE_DRILL_FILE</property>
+ <property name="label">Generate Drill File</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonDrill</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">CreateDrillFile</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonQuit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnQuit</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="wxMenu" expanded="1">
+ <property name="label">MyMenu</property>
+ <property name="name">m_popMenu</property>
+ <property name="permission">protected</property>
+ <object class="wxMenuItem" expanded="0">
+ <property name="bitmap"></property>
+ <property name="checked">0</property>
+ <property name="enabled">1</property>
+ <property name="help"></property>
+ <property name="id">ID_LAYER_FAB</property>
+ <property name="kind">wxITEM_NORMAL</property>
+ <property name="label">Select Fab Layers</property>
+ <property name="name">m_menuItem1</property>
+ <property name="permission">none</property>
+ <property name="shortcut"></property>
+ <property name="unchecked_bitmap"></property>
+ <event name="OnMenuSelection">OnPopUpLayers</event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ <object class="wxMenuItem" expanded="0">
+ <property name="bitmap"></property>
+ <property name="checked">0</property>
+ <property name="enabled">1</property>
+ <property name="help"></property>
+ <property name="id">ID_SELECT_COPPER_LAYERS</property>
+ <property name="kind">wxITEM_NORMAL</property>
+ <property name="label">Select all Copper Layers</property>
+ <property name="name">m_menuItem2</property>
+ <property name="permission">none</property>
+ <property name="shortcut"></property>
+ <property name="unchecked_bitmap"></property>
+ <event name="OnMenuSelection">OnPopUpLayers</event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ <object class="wxMenuItem" expanded="0">
+ <property name="bitmap"></property>
+ <property name="checked">0</property>
+ <property name="enabled">1</property>
+ <property name="help"></property>
+ <property name="id">ID_DESELECT_COPPER_LAYERS</property>
+ <property name="kind">wxITEM_NORMAL</property>
+ <property name="label">Deselect all Copper Layers</property>
+ <property name="name">m_menuItem3</property>
+ <property name="permission">none</property>
+ <property name="shortcut"></property>
+ <property name="unchecked_bitmap"></property>
+ <event name="OnMenuSelection">OnPopUpLayers</event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ <object class="wxMenuItem" expanded="0">
+ <property name="bitmap"></property>
+ <property name="checked">0</property>
+ <property name="enabled">1</property>
+ <property name="help"></property>
+ <property name="id">ID_SELECT_ALL_LAYERS</property>
+ <property name="kind">wxITEM_NORMAL</property>
+ <property name="label">Select all Layers</property>
+ <property name="name">m_menuItem4</property>
+ <property name="permission">none</property>
+ <property name="shortcut"></property>
+ <property name="unchecked_bitmap"></property>
+ <event name="OnMenuSelection">OnPopUpLayers</event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ <object class="wxMenuItem" expanded="0">
+ <property name="bitmap"></property>
+ <property name="checked">0</property>
+ <property name="enabled">1</property>
+ <property name="help"></property>
+ <property name="id">ID_DESELECT_ALL_LAYERS</property>
+ <property name="kind">wxITEM_NORMAL</property>
+ <property name="label">Deselect all Layers</property>
+ <property name="name">m_menuItem5</property>
+ <property name="permission">none</property>
+ <property name="shortcut"></property>
+ <property name="unchecked_bitmap"></property>
+ <event name="OnMenuSelection">OnPopUpLayers</event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_plot_base.h b/pcbnew/dialogs/dialog_plot_base.h
new file mode 100644
index 0000000..13a0fd4
--- /dev/null
+++ b/pcbnew/dialogs/dialog_plot_base.h
@@ -0,0 +1,146 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jul 2 2017)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_PLOT_BASE_H__
+#define __DIALOG_PLOT_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class WX_HTML_REPORT_PANEL;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/choice.h>
+#include <wx/sizer.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/checklst.h>
+#include <wx/statbox.h>
+#include <wx/checkbox.h>
+#include <wx/radiobox.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/menu.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PLOT_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PLOT_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ ID_ALLOW_PRINT_PAD_ON_SILKSCREEN = 1000,
+ ID_PRINT_REF,
+ ID_MIROR_OPT,
+ ID_CREATE_DRILL_FILE,
+ ID_LAYER_FAB,
+ ID_SELECT_COPPER_LAYERS,
+ ID_DESELECT_COPPER_LAYERS,
+ ID_SELECT_ALL_LAYERS,
+ ID_DESELECT_ALL_LAYERS
+ };
+
+ wxBoxSizer* m_MainSizer;
+ wxStaticText* m_staticTextPlotFmt;
+ wxChoice* m_plotFormatOpt;
+ wxStaticText* m_staticTextDir;
+ wxTextCtrl* m_outputDirectoryName;
+ wxButton* m_browseButton;
+ wxStaticBoxSizer* m_LayersSizer;
+ wxCheckListBox* m_layerCheckListBox;
+ wxBoxSizer* m_PlotOptionsSizer;
+ wxCheckBox* m_plotSheetRef;
+ wxCheckBox* m_plotPads_on_Silkscreen;
+ wxCheckBox* m_plotModuleValueOpt;
+ wxCheckBox* m_plotModuleRefOpt;
+ wxCheckBox* m_plotInvisibleText;
+ wxCheckBox* m_plotNoViaOnMaskOpt;
+ wxCheckBox* m_excludeEdgeLayerOpt;
+ wxCheckBox* m_plotMirrorOpt;
+ wxCheckBox* m_plotPSNegativeOpt;
+ wxCheckBox* m_useAuxOriginCheckBox;
+ wxStaticText* m_staticText11;
+ wxChoice* m_drillShapeOpt;
+ wxStaticText* m_staticText12;
+ wxChoice* m_scaleOpt;
+ wxStaticText* m_staticText13;
+ wxChoice* m_plotModeOpt;
+ wxStaticText* m_textDefaultPenSize;
+ wxTextCtrl* m_linesWidth;
+ wxStaticText* m_SolderMaskMarginLabel;
+ wxStaticText* m_SolderMaskMarginCurrValue;
+ wxStaticText* m_solderMaskMinWidthLabel;
+ wxStaticText* m_SolderMaskMinWidthCurrValue;
+ wxStaticBoxSizer* m_GerberOptionsSizer;
+ wxCheckBox* m_useGerberExtensions;
+ wxCheckBox* m_useGerberAttributes;
+ wxCheckBox* m_subtractMaskFromSilk;
+ wxRadioBox* m_rbGerberFormat;
+ wxStaticBoxSizer* m_HPGLOptionsSizer;
+ wxStaticText* m_textPenSize;
+ wxTextCtrl* m_HPGLPenSizeOpt;
+ wxStaticText* m_textPenOvr;
+ wxTextCtrl* m_HPGLPenOverlayOpt;
+ wxStaticBoxSizer* m_PSOptionsSizer;
+ wxStaticText* m_staticText7;
+ wxTextCtrl* m_fineAdjustXscaleOpt;
+ wxStaticText* m_staticText8;
+ wxTextCtrl* m_fineAdjustYscaleOpt;
+ wxStaticText* m_textPSFineAdjustWidth;
+ wxTextCtrl* m_PSFineAdjustWidthOpt;
+ wxCheckBox* m_forcePSA4OutputOpt;
+ wxStaticBoxSizer* m_SizerDXF_options;
+ wxCheckBox* m_DXF_plotModeOpt;
+ wxCheckBox* m_DXF_plotTextStrokeFontOpt;
+ WX_HTML_REPORT_PANEL* m_messagesPanel;
+ wxButton* m_plotButton;
+ wxButton* m_buttonDrill;
+ wxButton* m_buttonQuit;
+ wxMenu* m_popMenu;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
+ virtual void OnRightClick( wxMouseEvent& event ) { event.Skip(); }
+ virtual void SetPlotFormat( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnSetScaleOpt( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnChangeDXFPlotMode( wxCommandEvent& event ) { event.Skip(); }
+ virtual void Plot( wxCommandEvent& event ) { event.Skip(); }
+ virtual void CreateDrillFile( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnQuit( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPopUpLayers( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Plot"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 733,809 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_PLOT_BASE();
+
+ void DIALOG_PLOT_BASEOnContextMenu( wxMouseEvent &event )
+ {
+ this->PopupMenu( m_popMenu, event.GetPosition() );
+ }
+
+};
+
+#endif //__DIALOG_PLOT_BASE_H__
diff --git a/pcbnew/dialogs/dialog_pns_diff_pair_dimensions.cpp b/pcbnew/dialogs/dialog_pns_diff_pair_dimensions.cpp
new file mode 100644
index 0000000..0ce3c63
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_diff_pair_dimensions.cpp
@@ -0,0 +1,83 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2014-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * Push and Shove diff pair dimensions (gap) settings dialog.
+ */
+
+#include "dialog_pns_diff_pair_dimensions.h"
+#include <router/pns_sizes_settings.h>
+
+DIALOG_PNS_DIFF_PAIR_DIMENSIONS::DIALOG_PNS_DIFF_PAIR_DIMENSIONS( wxWindow* aParent, PNS_SIZES_SETTINGS& aSizes ) :
+ DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE( aParent ),
+ m_traceWidth( this, m_traceWidthText, m_traceWidthUnit ),
+ m_traceGap( this, m_traceGapText, m_traceGapUnit ),
+ m_viaGap( this, m_viaGapText, m_viaGapUnit ),
+ m_sizes( aSizes )
+{
+ m_traceWidth.SetValue( aSizes.DiffPairWidth() );
+ m_traceGap.SetValue( aSizes.DiffPairGap() );
+ m_viaGap.SetValue( aSizes.DiffPairViaGap() );
+ m_viaTraceGapEqual->SetValue( m_sizes.DiffPairViaGapSameAsTraceGap() );
+
+ updateCheckbox();
+
+ GetSizer()->SetSizeHints(this);
+ Centre();
+}
+
+
+void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::updateCheckbox()
+{
+ if( m_viaTraceGapEqual->GetValue() )
+ {
+ m_sizes.SetDiffPairViaGapSameAsTraceGap( true );
+ m_viaGapText->Disable();
+ m_viaGapLabel->Disable();
+ m_viaGapUnit->Disable();
+ }
+ else
+ {
+ m_sizes.SetDiffPairViaGapSameAsTraceGap( false );
+ m_viaGapText->Enable();
+ m_viaGapLabel->Enable();
+ m_viaGapUnit->Enable();
+ }
+}
+
+
+void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnOkClick( wxCommandEvent& aEvent )
+{
+ // Save widgets' values to settings
+ m_sizes.SetDiffPairGap ( m_traceGap.GetValue() );
+ m_sizes.SetDiffPairViaGap ( m_viaGap.GetValue() );
+ m_sizes.SetDiffPairWidth ( m_traceWidth.GetValue() );
+
+ // todo: verify against design rules
+ EndModal( wxID_OK );
+}
+
+
+void DIALOG_PNS_DIFF_PAIR_DIMENSIONS::OnViaTraceGapEqualCheck( wxCommandEvent& event )
+{
+ event.Skip();
+ updateCheckbox();
+}
+
diff --git a/pcbnew/dialogs/dialog_pns_diff_pair_dimensions.h b/pcbnew/dialogs/dialog_pns_diff_pair_dimensions.h
new file mode 100644
index 0000000..70f0538
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_diff_pair_dimensions.h
@@ -0,0 +1,52 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2014-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.or/licenses/>.
+ */
+
+/**
+ * Push and Shove diff pair dimensions (gap) settings dialog.
+ */
+
+#ifndef __dialog_diff_pair_dimensions_settings__
+#define __dialog_diff_pair_dimensions_settings__
+
+#include <wx_unit_binder.h>
+
+#include "dialog_pns_diff_pair_dimensions_base.h"
+
+class PNS_SIZES_SETTINGS;
+
+class DIALOG_PNS_DIFF_PAIR_DIMENSIONS : public DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE
+{
+public:
+ DIALOG_PNS_DIFF_PAIR_DIMENSIONS( wxWindow* aParent, PNS_SIZES_SETTINGS& aSizes );
+
+private:
+ void updateCheckbox();
+
+ virtual void OnOkClick( wxCommandEvent& aEvent );
+ virtual void OnViaTraceGapEqualCheck( wxCommandEvent& event );
+
+ WX_UNIT_BINDER m_traceWidth;
+ WX_UNIT_BINDER m_traceGap;
+ WX_UNIT_BINDER m_viaGap;
+
+ PNS_SIZES_SETTINGS& m_sizes;
+};
+
+#endif // __dialog_pns_settings__
diff --git a/pcbnew/dialogs/dialog_pns_diff_pair_dimensions_base.cpp b/pcbnew/dialogs/dialog_pns_diff_pair_dimensions_base.cpp
new file mode 100644
index 0000000..01da090
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_diff_pair_dimensions_base.cpp
@@ -0,0 +1,103 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_pns_diff_pair_dimensions_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( 400,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bSizer7;
+ bSizer7 = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 0, 3, 0, 0 );
+ fgSizer1->AddGrowableCol( 1 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_traceWidthLabel = new wxStaticText( this, wxID_ANY, _("Width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_traceWidthLabel->Wrap( -1 );
+ fgSizer1->Add( m_traceWidthLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_traceWidthText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer1->Add( m_traceWidthText, 0, wxALL|wxEXPAND, 5 );
+
+ m_traceWidthUnit = new wxStaticText( this, wxID_ANY, _("u"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_traceWidthUnit->Wrap( -1 );
+ fgSizer1->Add( m_traceWidthUnit, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_traceGapLabel = new wxStaticText( this, wxID_ANY, _("Trace gap:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_traceGapLabel->Wrap( -1 );
+ fgSizer1->Add( m_traceGapLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_traceGapText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer1->Add( m_traceGapText, 0, wxALL|wxEXPAND, 5 );
+
+ m_traceGapUnit = new wxStaticText( this, wxID_ANY, _("u"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_traceGapUnit->Wrap( -1 );
+ m_traceGapUnit->SetMaxSize( wxSize( 40,-1 ) );
+
+ fgSizer1->Add( m_traceGapUnit, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_viaGapLabel = new wxStaticText( this, wxID_ANY, _("Via gap:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_viaGapLabel->Wrap( -1 );
+ m_viaGapLabel->Enable( false );
+
+ fgSizer1->Add( m_viaGapLabel, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_viaGapText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_viaGapText->Enable( false );
+
+ fgSizer1->Add( m_viaGapText, 0, wxALL|wxEXPAND, 5 );
+
+ m_viaGapUnit = new wxStaticText( this, wxID_ANY, _("u"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_viaGapUnit->Wrap( -1 );
+ m_viaGapUnit->Enable( false );
+ m_viaGapUnit->SetMaxSize( wxSize( 40,-1 ) );
+
+ fgSizer1->Add( m_viaGapUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizer7->Add( fgSizer1, 0, wxEXPAND|wxALL, 5 );
+
+ m_viaTraceGapEqual = new wxCheckBox( this, wxID_ANY, _("Via gap same as trace gap"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_viaTraceGapEqual->SetValue(true);
+ bSizer7->Add( m_viaTraceGapEqual, 0, wxALL|wxEXPAND, 10 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizer7->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_stdButtons = new wxStdDialogButtonSizer();
+ m_stdButtonsOK = new wxButton( this, wxID_OK );
+ m_stdButtons->AddButton( m_stdButtonsOK );
+ m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_stdButtons->AddButton( m_stdButtonsCancel );
+ m_stdButtons->Realize();
+
+ bSizer7->Add( m_stdButtons, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( bSizer7 );
+ this->Layout();
+
+ // Connect Events
+ m_viaTraceGapEqual->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::OnViaTraceGapEqualCheck ), NULL, this );
+ m_stdButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::OnCancelClick ), NULL, this );
+ m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::~DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE()
+{
+ // Disconnect Events
+ m_viaTraceGapEqual->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::OnViaTraceGapEqualCheck ), NULL, this );
+ m_stdButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::OnCancelClick ), NULL, this );
+ m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_pns_diff_pair_dimensions_base.fbp b/pcbnew/dialogs/dialog_pns_diff_pair_dimensions_base.fbp
new file mode 100644
index 0000000..192f6b3
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_diff_pair_dimensions_base.fbp
@@ -0,0 +1,1083 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_pns_diff_pair_dimensions_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_PNS_SETTINGS_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">400,-1</property>
+ <property name="name">DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">400,216</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Differential Pair Dimensions</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer7</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_traceWidthLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_traceWidthText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">u</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_traceWidthUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Trace gap:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_traceGapLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_traceGapText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">u</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">40,-1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_traceGapUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Via gap:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_viaGapLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_viaGapText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">u</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">40,-1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_viaGapUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">10</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Via gap same as trace gap</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_viaTraceGapEqual</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnViaTraceGapEqualCheck</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_stdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_pns_diff_pair_dimensions_base.h b/pcbnew/dialogs/dialog_pns_diff_pair_dimensions_base.h
new file mode 100644
index 0000000..30e5bd5
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_diff_pair_dimensions_base.h
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE_H__
+#define __DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/checkbox.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_traceWidthLabel;
+ wxTextCtrl* m_traceWidthText;
+ wxStaticText* m_traceWidthUnit;
+ wxStaticText* m_traceGapLabel;
+ wxTextCtrl* m_traceGapText;
+ wxStaticText* m_traceGapUnit;
+ wxStaticText* m_viaGapLabel;
+ wxTextCtrl* m_viaGapText;
+ wxStaticText* m_viaGapUnit;
+ wxCheckBox* m_viaTraceGapEqual;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_stdButtons;
+ wxButton* m_stdButtonsOK;
+ wxButton* m_stdButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnViaTraceGapEqualCheck( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Differential Pair Dimensions"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 400,216 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE();
+
+};
+
+#endif //__DIALOG_PNS_DIFF_PAIR_DIMENSIONS_BASE_H__
diff --git a/pcbnew/dialogs/dialog_pns_length_tuning_settings.cpp b/pcbnew/dialogs/dialog_pns_length_tuning_settings.cpp
new file mode 100644
index 0000000..0ba8f11
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_length_tuning_settings.cpp
@@ -0,0 +1,103 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2014-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * Length tuner settings dialog.
+ */
+
+#include "dialog_pns_length_tuning_settings.h"
+#include <router/pns_meander_placer.h>
+
+DIALOG_PNS_LENGTH_TUNING_SETTINGS::DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow* aParent, PNS_MEANDER_SETTINGS& aSettings, PNS_ROUTER_MODE aMode ) :
+ DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE( aParent ),
+ m_minAmpl( this, m_minAmplText, m_minAmplUnit ),
+ m_maxAmpl( this, m_maxAmplText, m_maxAmplUnit ),
+ m_spacing( this, m_spacingText, m_spacingUnit ),
+ m_targetLength( this, m_targetLengthText, m_targetLengthUnit ),
+ m_settings( aSettings ),
+ m_mode( aMode )
+{
+ m_miterStyle->Enable( false );
+ m_radiusText->Enable( aMode != PNS_MODE_TUNE_DIFF_PAIR );
+ //m_minAmpl.Enable ( aMode != PNS_MODE_TUNE_DIFF_PAIR_SKEW );
+
+ m_minAmpl.SetValue( m_settings.m_minAmplitude );
+ m_maxAmpl.SetValue( m_settings.m_maxAmplitude );
+
+ m_spacing.SetValue( m_settings.m_spacing );
+ m_radiusText->SetValue( wxString::Format( wxT( "%i" ), m_settings.m_cornerRadiusPercentage ) );
+
+ m_miterStyle->SetSelection( m_settings.m_cornerType == PNS_MEANDER_SETTINGS::ROUND ? 1 : 0 );
+
+ switch( aMode )
+ {
+ case PNS_MODE_TUNE_SINGLE:
+ SetTitle( _( "Single Track Length Tuning" ) );
+ m_legend->SetBitmap( KiBitmap( tune_single_track_length_legend_xpm ) );
+ m_targetLength.SetValue( m_settings.m_targetLength );
+ break;
+
+ case PNS_MODE_TUNE_DIFF_PAIR:
+ SetTitle( _( "Differential Pair Length Tuning" ) );
+ m_legend->SetBitmap( KiBitmap( tune_diff_pair_length_legend_xpm ) );
+ m_targetLength.SetValue( m_settings.m_targetLength );
+ break;
+
+ case PNS_MODE_TUNE_DIFF_PAIR_SKEW:
+ SetTitle( _( "Differential Pair Skew Tuning" ) );
+ m_legend->SetBitmap( KiBitmap( tune_diff_pair_skew_legend_xpm ) );
+ m_targetLengthLabel->SetLabel( _( "Target skew: " ) );
+ m_targetLength.SetValue ( m_settings.m_targetSkew );
+ break;
+
+ default:
+ break;
+ }
+
+ m_stdButtonsOK->SetDefault();
+ m_targetLengthText->SetSelection( -1, -1 );
+ m_targetLengthText->SetFocus();
+
+ GetSizer()->SetSizeHints(this);
+ Centre();
+}
+
+
+void DIALOG_PNS_LENGTH_TUNING_SETTINGS::OnOkClick( wxCommandEvent& aEvent )
+{
+ // fixme: use validators and TransferDataFromWindow
+ m_settings.m_minAmplitude = m_minAmpl.GetValue();
+ m_settings.m_maxAmplitude = m_maxAmpl.GetValue();
+ m_settings.m_spacing = m_spacing.GetValue();
+
+ m_settings.m_cornerRadiusPercentage = wxAtoi( m_radiusText->GetValue() );
+
+ if( m_mode == PNS_MODE_TUNE_DIFF_PAIR_SKEW )
+ m_settings.m_targetSkew = m_targetLength.GetValue();
+ else
+ m_settings.m_targetLength = m_targetLength.GetValue();
+
+ if( m_settings.m_maxAmplitude < m_settings.m_minAmplitude )
+ m_settings.m_maxAmplitude = m_settings.m_minAmplitude;
+
+ m_settings.m_cornerType = m_miterStyle->GetSelection() ? PNS_MEANDER_SETTINGS::CHAMFER : PNS_MEANDER_SETTINGS::ROUND;
+
+ EndModal( wxID_OK );
+}
diff --git a/pcbnew/dialogs/dialog_pns_length_tuning_settings.h b/pcbnew/dialogs/dialog_pns_length_tuning_settings.h
new file mode 100644
index 0000000..f6dcba3
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_length_tuning_settings.h
@@ -0,0 +1,53 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2014 CERN
+ * Author: Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.or/licenses/>.
+ */
+
+/**
+ * Push and Shove router settings dialog.
+ */
+
+#ifndef __dialog_pns_length_tuning_settings__
+#define __dialog_pns_length_tuning_settings__
+
+#include "dialog_pns_length_tuning_settings_base.h"
+
+#include <wx_unit_binder.h>
+
+#include <router/pns_router.h>
+
+class PNS_MEANDER_SETTINGS;
+
+class DIALOG_PNS_LENGTH_TUNING_SETTINGS : public DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE
+{
+public:
+ DIALOG_PNS_LENGTH_TUNING_SETTINGS( wxWindow* aParent, PNS_MEANDER_SETTINGS& aSettings, PNS_ROUTER_MODE aMode );
+
+ virtual void OnOkClick( wxCommandEvent& aEvent );
+
+private:
+ WX_UNIT_BINDER m_minAmpl;
+ WX_UNIT_BINDER m_maxAmpl;
+ WX_UNIT_BINDER m_spacing;
+ WX_UNIT_BINDER m_targetLength;
+
+ PNS_MEANDER_SETTINGS& m_settings;
+ PNS_ROUTER_MODE m_mode;
+};
+
+#endif // __dialog_pns_settings__
diff --git a/pcbnew/dialogs/dialog_pns_length_tuning_settings_base.cpp b/pcbnew/dialogs/dialog_pns_length_tuning_settings_base.cpp
new file mode 100644
index 0000000..d6a0104
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_length_tuning_settings_base.cpp
@@ -0,0 +1,182 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_pns_length_tuning_settings_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE::DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( 400,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbSizer1;
+ sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Length/skew") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgSizerLenSkew;
+ fgSizerLenSkew = new wxFlexGridSizer( 0, 3, 0, 0 );
+ fgSizerLenSkew->AddGrowableCol( 1 );
+ fgSizerLenSkew->SetFlexibleDirection( wxBOTH );
+ fgSizerLenSkew->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText4 = new wxStaticText( this, wxID_ANY, _("Tune from:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText4->Wrap( -1 );
+ fgSizerLenSkew->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+ wxArrayString m_choicePathFromChoices;
+ m_choicePathFrom = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choicePathFromChoices, 0 );
+ m_choicePathFrom->SetSelection( 0 );
+ fgSizerLenSkew->Add( m_choicePathFrom, 0, wxALL|wxEXPAND, 5 );
+
+
+ fgSizerLenSkew->Add( 0, 0, 0, 0, 5 );
+
+ m_staticText15 = new wxStaticText( this, wxID_ANY, _("Tune to:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText15->Wrap( -1 );
+ fgSizerLenSkew->Add( m_staticText15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+ wxArrayString m_choice4Choices;
+ m_choice4 = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choice4Choices, 0 );
+ m_choice4->SetSelection( 0 );
+ fgSizerLenSkew->Add( m_choice4, 0, wxALL|wxEXPAND, 5 );
+
+
+ fgSizerLenSkew->Add( 0, 0, 0, 0, 5 );
+
+ m_staticText3 = new wxStaticText( this, wxID_ANY, _("Constraint:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ fgSizerLenSkew->Add( m_staticText3, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+ wxString m_constraintSourceChoices[] = { _("From Design Rules"), _("Manual") };
+ int m_constraintSourceNChoices = sizeof( m_constraintSourceChoices ) / sizeof( wxString );
+ m_constraintSource = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_constraintSourceNChoices, m_constraintSourceChoices, 0 );
+ m_constraintSource->SetSelection( 1 );
+ m_constraintSource->Enable( false );
+
+ fgSizerLenSkew->Add( m_constraintSource, 1, wxALL|wxEXPAND, 5 );
+
+
+ fgSizerLenSkew->Add( 0, 0, 0, 0, 5 );
+
+ m_targetLengthLabel = new wxStaticText( this, wxID_ANY, _("Target length:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_targetLengthLabel->Wrap( -1 );
+ fgSizerLenSkew->Add( m_targetLengthLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_targetLengthText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizerLenSkew->Add( m_targetLengthText, 0, wxALL|wxEXPAND, 5 );
+
+ m_targetLengthUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_targetLengthUnit->Wrap( -1 );
+ fgSizerLenSkew->Add( m_targetLengthUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+
+ sbSizer1->Add( fgSizerLenSkew, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( sbSizer1, 0, wxEXPAND|wxALL, 5 );
+
+ wxStaticBoxSizer* sbSizer2;
+ sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Meandering") ), wxVERTICAL );
+
+ m_legend = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
+ sbSizer2->Add( m_legend, 1, wxALL|wxEXPAND, 5 );
+
+ wxFlexGridSizer* fgSizer3;
+ fgSizer3 = new wxFlexGridSizer( 0, 3, 0, 0 );
+ fgSizer3->AddGrowableCol( 1 );
+ fgSizer3->SetFlexibleDirection( wxBOTH );
+ fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText9 = new wxStaticText( this, wxID_ANY, _("Min amplitude (Amin):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText9->Wrap( -1 );
+ fgSizer3->Add( m_staticText9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+ m_minAmplText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer3->Add( m_minAmplText, 0, wxALL|wxEXPAND, 5 );
+
+ m_minAmplUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_minAmplUnit->Wrap( -1 );
+ fgSizer3->Add( m_minAmplUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+ m_staticText91 = new wxStaticText( this, wxID_ANY, _("Max amplitude (Amax):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText91->Wrap( -1 );
+ fgSizer3->Add( m_staticText91, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+ m_maxAmplText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer3->Add( m_maxAmplText, 0, wxALL|wxEXPAND, 5 );
+
+ m_maxAmplUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_maxAmplUnit->Wrap( -1 );
+ fgSizer3->Add( m_maxAmplUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+ m_staticText11 = new wxStaticText( this, wxID_ANY, _("Spacing (s):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText11->Wrap( -1 );
+ fgSizer3->Add( m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+ m_spacingText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer3->Add( m_spacingText, 0, wxALL|wxEXPAND, 5 );
+
+ m_spacingUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_spacingUnit->Wrap( -1 );
+ fgSizer3->Add( m_spacingUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+ m_staticText13 = new wxStaticText( this, wxID_ANY, _("Miter radius (r):"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText13->Wrap( -1 );
+ fgSizer3->Add( m_staticText13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+ m_radiusText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer3->Add( m_radiusText, 0, wxALL|wxEXPAND, 5 );
+
+ m_radiusUnit = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_radiusUnit->Wrap( -1 );
+ fgSizer3->Add( m_radiusUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
+
+ m_staticText14 = new wxStaticText( this, wxID_ANY, _("Miter style:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText14->Wrap( -1 );
+ m_staticText14->Enable( false );
+
+ fgSizer3->Add( m_staticText14, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ wxString m_miterStyleChoices[] = { _("45 degree"), _("arc") };
+ int m_miterStyleNChoices = sizeof( m_miterStyleChoices ) / sizeof( wxString );
+ m_miterStyle = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_miterStyleNChoices, m_miterStyleChoices, 0 );
+ m_miterStyle->SetSelection( 0 );
+ m_miterStyle->Enable( false );
+
+ fgSizer3->Add( m_miterStyle, 0, wxALL|wxEXPAND, 5 );
+
+
+ sbSizer2->Add( fgSizer3, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( sbSizer2, 1, wxALL|wxEXPAND, 5 );
+
+ m_stdButtons = new wxStdDialogButtonSizer();
+ m_stdButtonsOK = new wxButton( this, wxID_OK );
+ m_stdButtons->AddButton( m_stdButtonsOK );
+ m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_stdButtons->AddButton( m_stdButtonsCancel );
+ m_stdButtons->Realize();
+
+ bMainSizer->Add( m_stdButtons, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ // Connect Events
+ m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE::~DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE()
+{
+ // Disconnect Events
+ m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_pns_length_tuning_settings_base.fbp b/pcbnew/dialogs/dialog_pns_length_tuning_settings_base.fbp
new file mode 100644
index 0000000..367f0ed
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_length_tuning_settings_base.fbp
@@ -0,0 +1,2269 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">/home/twl/Kicad-dev/kicad-git/bitmaps_png/cpp_other</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_pns_length_tuning_settings_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">400,-1</property>
+ <property name="name">DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">404,565</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Trace length tuning</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Length/skew</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizer1</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerLenSkew</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Tune from:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choicePathFrom</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Tune to:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText15</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_choice4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Constraint:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;From Design Rules&quot; &quot;Manual&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_constraintSource</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Target length:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_targetLengthLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_targetLengthText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_targetLengthUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Meandering</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizer2</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBitmap" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmap">Load From Resource; </property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_legend</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer3</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Min amplitude (Amin):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText9</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_minAmplText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_minAmplUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Max amplitude (Amax):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText91</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_maxAmplText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_maxAmplUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Spacing (s):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText11</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spacingText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_spacingUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Miter radius (r):</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText13</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radiusText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">%</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radiusUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Miter style:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText14</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;45 degree&quot; &quot;arc&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_miterStyle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="0">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_stdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_pns_length_tuning_settings_base.h b/pcbnew/dialogs/dialog_pns_length_tuning_settings_base.h
new file mode 100644
index 0000000..a4c73f4
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_length_tuning_settings_base.h
@@ -0,0 +1,84 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE_H__
+#define __DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/choice.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/statbmp.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText4;
+ wxChoice* m_choicePathFrom;
+ wxStaticText* m_staticText15;
+ wxChoice* m_choice4;
+ wxStaticText* m_staticText3;
+ wxChoice* m_constraintSource;
+ wxStaticText* m_targetLengthLabel;
+ wxTextCtrl* m_targetLengthText;
+ wxStaticText* m_targetLengthUnit;
+ wxStaticBitmap* m_legend;
+ wxStaticText* m_staticText9;
+ wxTextCtrl* m_minAmplText;
+ wxStaticText* m_minAmplUnit;
+ wxStaticText* m_staticText91;
+ wxTextCtrl* m_maxAmplText;
+ wxStaticText* m_maxAmplUnit;
+ wxStaticText* m_staticText11;
+ wxTextCtrl* m_spacingText;
+ wxStaticText* m_spacingUnit;
+ wxStaticText* m_staticText13;
+ wxTextCtrl* m_radiusText;
+ wxStaticText* m_radiusUnit;
+ wxStaticText* m_staticText14;
+ wxChoice* m_miterStyle;
+ wxStdDialogButtonSizer* m_stdButtons;
+ wxButton* m_stdButtonsOK;
+ wxButton* m_stdButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Trace length tuning"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 404,565 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE();
+
+};
+
+#endif //__DIALOG_PNS_LENGTH_TUNING_SETTINGS_BASE_H__
diff --git a/pcbnew/dialogs/dialog_pns_settings.cpp b/pcbnew/dialogs/dialog_pns_settings.cpp
new file mode 100644
index 0000000..c310a52
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_settings.cpp
@@ -0,0 +1,75 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2014 CERN
+ * Author: Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.or/licenses/>.
+ */
+
+/**
+ * Push and Shove router settings dialog.
+ */
+
+#include "dialog_pns_settings.h"
+#include <router/pns_routing_settings.h>
+
+DIALOG_PNS_SETTINGS::DIALOG_PNS_SETTINGS( wxWindow* aParent, PNS_ROUTING_SETTINGS& aSettings ) :
+ DIALOG_PNS_SETTINGS_BASE( aParent ), m_settings( aSettings )
+{
+ // "Figure out what's best" is not available yet
+ m_mode->Enable( RM_Smart, false );
+
+ // Add tool tip to the mode radio box, one by option
+ // (cannot be made with wxFormBuilder for each item )
+ m_mode->SetItemToolTip( 0, _( "DRC violation: highlight obstacles" ) );
+ m_mode->SetItemToolTip( 1, _( "DRC violation: shove tracks and vias" ) );
+ m_mode->SetItemToolTip( 2, _( "DRC violation: walk around obstacles" ) );
+
+ // Load widgets' values from settings
+ m_mode->SetSelection( m_settings.Mode() );
+ m_shoveVias->SetValue( m_settings.ShoveVias() );
+ m_backPressure->SetValue( m_settings.JumpOverObstacles() );
+ m_removeLoops->SetValue( m_settings.RemoveLoops() );
+ m_suggestEnding->SetValue( m_settings.SuggestFinish() );
+ m_autoNeckdown->SetValue( m_settings.SmartPads() );
+ m_effort->SetValue( m_settings.OptimizerEffort() );
+ m_smoothDragged->SetValue( m_settings.SmoothDraggedSegments() );
+ m_violateDrc->SetValue( m_settings.CanViolateDRC() );
+ m_freeAngleMode->SetValue( m_settings.GetFreeAngleMode() );
+ m_dragToolMode->SetSelection ( m_settings.InlineDragEnabled() ? 1 : 0 );
+
+ SetDefaultItem( m_stdButtonsOK );
+ GetSizer()->Fit( this );
+ GetSizer()->SetSizeHints( this );
+}
+
+
+void DIALOG_PNS_SETTINGS::OnOkClick( wxCommandEvent& aEvent )
+{
+ // Save widgets' values to settings
+ m_settings.SetMode( (PNS_MODE) m_mode->GetSelection() );
+ m_settings.SetShoveVias( m_shoveVias->GetValue() );
+ m_settings.SetJumpOverObstacles( m_backPressure->GetValue() );
+ m_settings.SetRemoveLoops( m_removeLoops->GetValue() );
+ m_settings.SetSuggestFinish ( m_suggestEnding->GetValue() );
+ m_settings.SetSmartPads( m_autoNeckdown->GetValue() );
+ m_settings.SetOptimizerEffort( (PNS_OPTIMIZATION_EFFORT) m_effort->GetValue() );
+ m_settings.SetSmoothDraggedSegments( m_smoothDragged->GetValue() );
+ m_settings.SetCanViolateDRC( m_violateDrc->GetValue() );
+ m_settings.SetFreeAngleMode( m_freeAngleMode->GetValue() );
+ m_settings.SetInlineDragEnabled( m_dragToolMode->GetSelection () ? true : false );
+
+ aEvent.Skip(); // ends returning wxID_OK (default behavior)
+}
diff --git a/pcbnew/dialogs/dialog_pns_settings.h b/pcbnew/dialogs/dialog_pns_settings.h
new file mode 100644
index 0000000..d59cfa5
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_settings.h
@@ -0,0 +1,43 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2014 CERN
+ * Author: Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.or/licenses/>.
+ */
+
+/**
+ * Push and Shove router settings dialog.
+ */
+
+#ifndef __dialog_pns_settings__
+#define __dialog_pns_settings__
+
+#include "dialog_pns_settings_base.h"
+
+class PNS_ROUTING_SETTINGS;
+
+class DIALOG_PNS_SETTINGS : public DIALOG_PNS_SETTINGS_BASE
+{
+ public:
+ DIALOG_PNS_SETTINGS( wxWindow* aParent, PNS_ROUTING_SETTINGS& aSettings );
+
+ private:
+ virtual void OnOkClick( wxCommandEvent& aEvent );
+
+ PNS_ROUTING_SETTINGS& m_settings;
+};
+
+#endif // __dialog_pns_settings__
diff --git a/pcbnew/dialogs/dialog_pns_settings_base.cpp b/pcbnew/dialogs/dialog_pns_settings_base.cpp
new file mode 100644
index 0000000..c87a99c
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_settings_base.cpp
@@ -0,0 +1,161 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_pns_settings_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_PNS_SETTINGS_BASE::DIALOG_PNS_SETTINGS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( 350,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_modeChoices[] = { _("Highlight collisions"), _("Shove"), _("Walk around"), _("Figure out what's best") };
+ int m_modeNChoices = sizeof( m_modeChoices ) / sizeof( wxString );
+ m_mode = new wxRadioBox( this, wxID_ANY, _("Mode"), wxDefaultPosition, wxDefaultSize, m_modeNChoices, m_modeChoices, 1, wxRA_SPECIFY_COLS );
+ m_mode->SetSelection( 0 );
+ bMainSizer->Add( m_mode, 0, wxALL|wxEXPAND, 5 );
+
+ wxStaticBoxSizer* bOptions;
+ bOptions = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 );
+ fgSizer1->AddGrowableCol( 1 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText4 = new wxStaticText( bOptions->GetStaticBox(), wxID_ANY, _("Mouse drag behaviour:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText4->Wrap( -1 );
+ fgSizer1->Add( m_staticText4, 0, wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ wxString m_dragToolModeChoices[] = { _("move item"), _("interactive drag") };
+ int m_dragToolModeNChoices = sizeof( m_dragToolModeChoices ) / sizeof( wxString );
+ m_dragToolMode = new wxChoice( bOptions->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_dragToolModeNChoices, m_dragToolModeChoices, 0 );
+ m_dragToolMode->SetSelection( 0 );
+ fgSizer1->Add( m_dragToolMode, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ bOptions->Add( fgSizer1, 1, wxEXPAND, 5 );
+
+ m_freeAngleMode = new wxCheckBox( bOptions->GetStaticBox(), wxID_ANY, _("Free angle mode (no shove/walkaround)"), wxDefaultPosition, wxDefaultSize, 0 );
+ bOptions->Add( m_freeAngleMode, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_shoveVias = new wxCheckBox( bOptions->GetStaticBox(), wxID_ANY, _("Shove vias"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_shoveVias->Enable( false );
+ m_shoveVias->SetToolTip( _("When disabled, vias are treated as un-movable objects and hugged instead of shoved.") );
+
+ bOptions->Add( m_shoveVias, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_backPressure = new wxCheckBox( bOptions->GetStaticBox(), wxID_ANY, _("Jump over obstacles"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_backPressure->SetToolTip( _("When enabled, the router tries to move colliding traces behind solid obstacles (e.g. pads) instead of \"reflecting\" back the collision") );
+
+ bOptions->Add( m_backPressure, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_removeLoops = new wxCheckBox( bOptions->GetStaticBox(), wxID_ANY, _("Remove redundant tracks"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_removeLoops->SetToolTip( _("Removes loops while routing (e.g. if the new track ensures same connectivity as an already existing one, the old track is removed).\nLoop removal works locally (only between the start and end of the currently routed trace).") );
+
+ bOptions->Add( m_removeLoops, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_autoNeckdown = new wxCheckBox( bOptions->GetStaticBox(), wxID_ANY, _("Automatic neckdown"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_autoNeckdown->SetToolTip( _("When enabled, the router tries to break out pads/vias in a clean way, avoiding acute angles and jagged breakout traces.") );
+
+ bOptions->Add( m_autoNeckdown, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_smoothDragged = new wxCheckBox( bOptions->GetStaticBox(), wxID_ANY, _("Smooth dragged segments"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_smoothDragged->SetToolTip( _("When enabled, the router attempts to merge several jagged segments into a single straight one (dragging mode).") );
+
+ bOptions->Add( m_smoothDragged, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_violateDrc = new wxCheckBox( bOptions->GetStaticBox(), wxID_ANY, _("Allow DRC violations"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_violateDrc->SetToolTip( _("(Highlight collisions mode only) - allows to establish a track even if is violating the DRC rules.") );
+
+ bOptions->Add( m_violateDrc, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_suggestEnding = new wxCheckBox( bOptions->GetStaticBox(), wxID_ANY, _("Suggest track finish"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_suggestEnding->Enable( false );
+
+ bOptions->Add( m_suggestEnding, 0, wxALL, 5 );
+
+ m_staticline1 = new wxStaticLine( bOptions->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bOptions->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ wxBoxSizer* bEffort;
+ bEffort = new wxBoxSizer( wxHORIZONTAL );
+
+ m_effortLabel = new wxStaticText( bOptions->GetStaticBox(), wxID_ANY, _("Optimizer effort"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_effortLabel->Wrap( -1 );
+ m_effortLabel->SetToolTip( _("Defines how much time the router shall spend optimizing the routed/shoved traces.\nMore effort means cleaner routing (but slower), less effort means faster routing but somewhat jagged traces.") );
+
+ bEffort->Add( m_effortLabel, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bEffort->Add( 0, 0, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bSlider;
+ bSlider = new wxBoxSizer( wxVERTICAL );
+
+ m_effort = new wxSlider( bOptions->GetStaticBox(), wxID_ANY, 1, 0, 2, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_BOTTOM|wxSL_HORIZONTAL|wxSL_TOP );
+ bSlider->Add( m_effort, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSliderLabels;
+ bSliderLabels = new wxBoxSizer( wxHORIZONTAL );
+
+ m_lowLabel = new wxStaticText( bOptions->GetStaticBox(), wxID_ANY, _("low"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_lowLabel->Wrap( -1 );
+ m_lowLabel->SetFont( wxFont( 8, 70, 90, 90, false, wxEmptyString ) );
+
+ bSliderLabels->Add( m_lowLabel, 0, 0, 5 );
+
+
+ bSliderLabels->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_highLabel = new wxStaticText( bOptions->GetStaticBox(), wxID_ANY, _("high"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_highLabel->Wrap( -1 );
+ m_highLabel->SetFont( wxFont( 8, 70, 90, 90, false, wxEmptyString ) );
+
+ bSliderLabels->Add( m_highLabel, 0, 0, 5 );
+
+
+ bSlider->Add( bSliderLabels, 1, wxEXPAND, 5 );
+
+
+ bEffort->Add( bSlider, 1, wxEXPAND, 5 );
+
+
+ bOptions->Add( bEffort, 0, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bOptions, 1, wxEXPAND|wxALL, 5 );
+
+ m_stdButtons = new wxStdDialogButtonSizer();
+ m_stdButtonsOK = new wxButton( this, wxID_OK );
+ m_stdButtons->AddButton( m_stdButtonsOK );
+ m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_stdButtons->AddButton( m_stdButtonsCancel );
+ m_stdButtons->Realize();
+
+ bMainSizer->Add( m_stdButtons, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+
+ // Connect Events
+ m_freeAngleMode->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PNS_SETTINGS_BASE::onFreeAngleModeChange ), NULL, this );
+ m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_SETTINGS_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_PNS_SETTINGS_BASE::~DIALOG_PNS_SETTINGS_BASE()
+{
+ // Disconnect Events
+ m_freeAngleMode->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PNS_SETTINGS_BASE::onFreeAngleModeChange ), NULL, this );
+ m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PNS_SETTINGS_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_pns_settings_base.fbp b/pcbnew/dialogs/dialog_pns_settings_base.fbp
new file mode 100644
index 0000000..d79ef6e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_settings_base.fbp
@@ -0,0 +1,1613 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_pns_settings_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_PNS_SETTINGS_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">350,-1</property>
+ <property name="name">DIALOG_PNS_SETTINGS_BASE</property>
+ <property name="pos"></property>
+ <property name="size">377,460</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Interactive Router Settings</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Highlight collisions&quot; &quot;Shove&quot; &quot;Walk around&quot; &quot;Figure out what&apos;s best&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Mode</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_mode</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Options</property>
+ <property name="minimum_size"></property>
+ <property name="name">bOptions</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Mouse drag behaviour:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxChoice" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;move item&quot; &quot;interactive drag&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_dragToolMode</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Free angle mode (no shove/walkaround)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_freeAngleMode</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">onFreeAngleModeChange</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Shove vias</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_shoveVias</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">When disabled, vias are treated as un-movable objects and hugged instead of shoved.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Jump over obstacles</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_backPressure</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">When enabled, the router tries to move colliding traces behind solid obstacles (e.g. pads) instead of &quot;reflecting&quot; back the collision</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Remove redundant tracks</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_removeLoops</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Removes loops while routing (e.g. if the new track ensures same connectivity as an already existing one, the old track is removed).&#x0A;Loop removal works locally (only between the start and end of the currently routed trace).</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Automatic neckdown</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_autoNeckdown</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">When enabled, the router tries to break out pads/vias in a clean way, avoiding acute angles and jagged breakout traces.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Smooth dragged segments</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_smoothDragged</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">When enabled, the router attempts to merge several jagged segments into a single straight one (dragging mode).</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Allow DRC violations</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_violateDrc</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">(Highlight collisions mode only) - allows to establish a track even if is violating the DRC rules.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">0</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Suggest track finish</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_suggestEnding</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bEffort</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Optimizer effort</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_effortLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Defines how much time the router shall spend optimizing the routed/shoved traces.&#x0A;More effort means cleaner routing (but slower), less effort means faster routing but somewhat jagged traces.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="0">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSlider</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxSlider" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maxValue">2</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">1</property>
+ <property name="maximum_size"></property>
+ <property name="minValue">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_effort</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxSL_AUTOTICKS|wxSL_BOTTOM|wxSL_HORIZONTAL|wxSL_TOP</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">1</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCommandScroll"></event>
+ <event name="OnCommandScrollBottom"></event>
+ <event name="OnCommandScrollChanged"></event>
+ <event name="OnCommandScrollLineDown"></event>
+ <event name="OnCommandScrollLineUp"></event>
+ <event name="OnCommandScrollPageDown"></event>
+ <event name="OnCommandScrollPageUp"></event>
+ <event name="OnCommandScrollThumbRelease"></event>
+ <event name="OnCommandScrollThumbTrack"></event>
+ <event name="OnCommandScrollTop"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnScroll"></event>
+ <event name="OnScrollBottom"></event>
+ <event name="OnScrollChanged"></event>
+ <event name="OnScrollLineDown"></event>
+ <event name="OnScrollLineUp"></event>
+ <event name="OnScrollPageDown"></event>
+ <event name="OnScrollPageUp"></event>
+ <event name="OnScrollThumbRelease"></event>
+ <event name="OnScrollThumbTrack"></event>
+ <event name="OnScrollTop"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSliderLabels</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,90,8,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">low</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_lowLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="0">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,90,8,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">high</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_highLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="0">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_stdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_pns_settings_base.h b/pcbnew/dialogs/dialog_pns_settings_base.h
new file mode 100644
index 0000000..bdc531b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_pns_settings_base.h
@@ -0,0 +1,76 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_PNS_SETTINGS_BASE_H__
+#define __DIALOG_PNS_SETTINGS_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/radiobox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/stattext.h>
+#include <wx/choice.h>
+#include <wx/sizer.h>
+#include <wx/checkbox.h>
+#include <wx/statline.h>
+#include <wx/slider.h>
+#include <wx/statbox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PNS_SETTINGS_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PNS_SETTINGS_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxRadioBox* m_mode;
+ wxStaticText* m_staticText4;
+ wxChoice* m_dragToolMode;
+ wxCheckBox* m_freeAngleMode;
+ wxCheckBox* m_shoveVias;
+ wxCheckBox* m_backPressure;
+ wxCheckBox* m_removeLoops;
+ wxCheckBox* m_autoNeckdown;
+ wxCheckBox* m_smoothDragged;
+ wxCheckBox* m_violateDrc;
+ wxCheckBox* m_suggestEnding;
+ wxStaticLine* m_staticline1;
+ wxStaticText* m_effortLabel;
+ wxSlider* m_effort;
+ wxStaticText* m_lowLabel;
+ wxStaticText* m_highLabel;
+ wxStdDialogButtonSizer* m_stdButtons;
+ wxButton* m_stdButtonsOK;
+ wxButton* m_stdButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void onFreeAngleModeChange( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PNS_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Interactive Router Settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 377,460 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_PNS_SETTINGS_BASE();
+
+};
+
+#endif //__DIALOG_PNS_SETTINGS_BASE_H__
diff --git a/pcbnew/dialogs/dialog_print_for_modedit.cpp b/pcbnew/dialogs/dialog_print_for_modedit.cpp
new file mode 100644
index 0000000..296463d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_print_for_modedit.cpp
@@ -0,0 +1,238 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* File: dialog_print_for_modedit.cpp */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <module_editor_frame.h>
+#include <pcbplot.h>
+
+#include <dialog_print_for_modedit_base.h>
+#include <printout_controler.h>
+
+static double s_scaleList[] =
+{ 0, 0.5, 0.7, 1.0, 1.4, 2.0, 3.0, 4.0, 8.0, 16.0 };
+
+
+// static print data and page setup data, to remember settings during the session
+static PRINT_PARAMETERS s_Parameters;
+static wxPrintData* s_PrintData;
+static wxPageSetupDialogData* s_pageSetupData = (wxPageSetupDialogData*) NULL;
+
+
+/**
+ * Class DIALOG_PRINT_FOR_MODEDIT
+ * is derived from DIALOG_PRINT_FOR_MODEDIT_BASE which is created by wxFormBuilder.
+ */
+class DIALOG_PRINT_FOR_MODEDIT : public DIALOG_PRINT_FOR_MODEDIT_BASE
+{
+public:
+ DIALOG_PRINT_FOR_MODEDIT( PCB_BASE_FRAME* parent );
+
+private:
+ PCB_BASE_FRAME* m_parent;
+ wxConfigBase* m_config;
+
+ void OnCloseWindow( wxCloseEvent& event );
+
+ /// Open a dialog box for printer setup (printer options, page size ...)
+ void OnPageSetup( wxCommandEvent& event );
+
+ void OnPrintPreview( wxCommandEvent& event );
+
+ /// Called on activate Print button
+ void OnPrintButtonClick( wxCommandEvent& event );
+
+ void OnButtonCancelClick( wxCommandEvent& event ) { Close(); }
+ void InitValues( );
+};
+
+
+void FOOTPRINT_EDIT_FRAME::ToPrinter( wxCommandEvent& event )
+{
+ const PAGE_INFO& pageInfo = GetPageSettings();
+
+ if( s_PrintData == NULL ) // First print
+ {
+ s_PrintData = new wxPrintData();
+
+ if( !s_PrintData->Ok() )
+ {
+ DisplayError( this, _( "An error occurred initializing the printer information." ) );
+ }
+
+ s_PrintData->SetQuality( wxPRINT_QUALITY_HIGH ); // Default resolution = HIGH;
+ }
+
+ if( s_pageSetupData == NULL )
+ s_pageSetupData = new wxPageSetupDialogData( *s_PrintData );
+
+ s_pageSetupData->SetPaperId( pageInfo.GetPaperId() );
+ s_pageSetupData->GetPrintData().SetOrientation( pageInfo.GetWxOrientation() );
+ s_PrintData->SetOrientation( pageInfo.GetWxOrientation() );
+
+ *s_PrintData = s_pageSetupData->GetPrintData();
+ s_Parameters.m_PageSetupData = s_pageSetupData;
+
+ DIALOG_PRINT_FOR_MODEDIT dlg( this );
+
+ dlg.ShowModal();
+}
+
+
+DIALOG_PRINT_FOR_MODEDIT::DIALOG_PRINT_FOR_MODEDIT( PCB_BASE_FRAME* parent ) :
+ DIALOG_PRINT_FOR_MODEDIT_BASE( parent )
+{
+ m_parent = parent;
+ s_Parameters.m_ForceCentered = true;
+ m_config = Kiface().KifaceSettings();
+ InitValues();
+
+ m_buttonPrint->SetDefault();
+ GetSizer()->SetSizeHints( this );
+ GetSizer()->Fit( this ); // Needed on Ubuntu/Unity to display the dialog
+}
+
+
+void DIALOG_PRINT_FOR_MODEDIT::InitValues( )
+{
+ // Read the scale adjust option
+ int scale_Select = 3; // default selected scale = ScaleList[3] = 1
+
+ if( m_config )
+ {
+ m_config->Read( OPTKEY_PRINT_MODULE_SCALE, &scale_Select );
+ m_config->Read( OPTKEY_PRINT_MONOCHROME_MODE, &s_Parameters.m_Print_Black_and_White, 1);
+ }
+
+ s_Parameters.m_PenDefaultSize = g_DrawDefaultLineThickness;
+ m_ScaleOption->SetSelection( scale_Select );
+
+ if( s_Parameters.m_Print_Black_and_White )
+ m_ModeColorOption->SetSelection( 1 );
+}
+
+
+
+void DIALOG_PRINT_FOR_MODEDIT::OnCloseWindow( wxCloseEvent& event )
+{
+ if( m_config )
+ {
+ m_config->Write( OPTKEY_PRINT_MODULE_SCALE, m_ScaleOption->GetSelection() );
+ m_config->Write( OPTKEY_PRINT_MONOCHROME_MODE, s_Parameters.m_Print_Black_and_White );
+ }
+
+ EndModal( 0 );
+}
+
+
+void DIALOG_PRINT_FOR_MODEDIT::OnPageSetup( wxCommandEvent& event )
+{
+ wxPageSetupDialog pageSetupDialog( this, s_pageSetupData );
+ pageSetupDialog.ShowModal();
+
+ (*s_PrintData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
+ (*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
+}
+
+
+void DIALOG_PRINT_FOR_MODEDIT::OnPrintPreview( wxCommandEvent& event )
+{
+ s_Parameters.m_Print_Black_and_White = m_ModeColorOption->GetSelection();
+ s_Parameters.m_PrintScale = s_scaleList[m_ScaleOption->GetSelection()];
+
+ // Pass two printout objects: for preview, and possible printing.
+ wxString title = _( "Print Preview" );
+ wxPrintPreview* preview =
+ new wxPrintPreview( new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_parent, title ),
+ new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_parent, title ),
+ s_PrintData );
+
+ if( preview == NULL )
+ {
+ DisplayError( this, wxT( "OnPrintPreview() problem" ) );
+ return;
+ }
+
+ // Uses the parent position and size.
+ // @todo uses last position and size ans store them when exit in m_config
+ wxPoint WPos = m_parent->GetPosition();
+ wxSize WSize = m_parent->GetSize();
+
+ wxPreviewFrame* frame = new wxPreviewFrame( preview, this, title, WPos, WSize );
+ frame->SetMinSize( wxSize( 550, 350 ) );
+
+ // On wxGTK, set the flag wxTOPLEVEL_EX_DIALOG is mandatory, if we want
+ // close the frame using the X box in caption, when the preview frame is run
+ // from a dialog
+ frame->SetExtraStyle( frame->GetExtraStyle() | wxTOPLEVEL_EX_DIALOG );
+
+ // We use here wxPreviewFrame_WindowModal option to make the wxPrintPreview frame
+ // modal for its caller only.
+ // An other reason is the fact when closing the frame without this option,
+ // all top level frames are reenabled.
+ // With this option, only the parent is reenabled.
+ // Reenabling all top level frames should be made by the parent dialog.
+ frame->InitializeWithModality( wxPreviewFrame_WindowModal );
+
+ frame->Raise(); // Needed on Ubuntu/Unity to display the frame
+ frame->Show( true );
+}
+
+
+void DIALOG_PRINT_FOR_MODEDIT::OnPrintButtonClick( wxCommandEvent& event )
+{
+ PCB_PLOT_PARAMS plot_opts = m_parent->GetPlotSettings();
+
+ s_Parameters.m_Print_Black_and_White = m_ModeColorOption->GetSelection();
+ s_Parameters.m_PrintScale = s_scaleList[m_ScaleOption->GetSelection()];
+
+ plot_opts.SetFineScaleAdjustX( s_Parameters.m_XScaleAdjust );
+ plot_opts.SetFineScaleAdjustY( s_Parameters.m_YScaleAdjust );
+ plot_opts.SetScale( s_Parameters.m_PrintScale );
+
+ m_parent->SetPlotSettings( plot_opts );
+
+ wxPrintDialogData printDialogData( *s_PrintData );
+ wxPrinter printer( &printDialogData );
+
+ BOARD_PRINTOUT_CONTROLLER printout( s_Parameters, m_parent, _( "Print Footprint" ) );
+
+ if( !printer.Print( this, &printout, true ) )
+ {
+ if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
+ DisplayError( this, _( "There was a problem printing." ) );
+
+ return;
+ }
+ else
+ {
+ *s_PrintData = printer.GetPrintDialogData().GetPrintData();
+ }
+}
diff --git a/pcbnew/dialogs/dialog_print_for_modedit_base.cpp b/pcbnew/dialogs/dialog_print_for_modedit_base.cpp
new file mode 100644
index 0000000..84e4608
--- /dev/null
+++ b/pcbnew/dialogs/dialog_print_for_modedit_base.cpp
@@ -0,0 +1,87 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_print_for_modedit_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_PRINT_FOR_MODEDIT_BASE::DIALOG_PRINT_FOR_MODEDIT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxBoxSizer* bmiddleLeftSizer;
+ bmiddleLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_ScaleOptionChoices[] = { _("fit in page"), _("Scale 0.5"), _("Scale 0.7"), _("Scale 1"), _("Scale 1.4"), _("Scale 2"), _("Scale 3"), _("Scale 4"), _("Scale 8"), _("Scale 16") };
+ int m_ScaleOptionNChoices = sizeof( m_ScaleOptionChoices ) / sizeof( wxString );
+ m_ScaleOption = new wxRadioBox( this, wxID_ANY, _("Approx. Scale:"), wxDefaultPosition, wxDefaultSize, m_ScaleOptionNChoices, m_ScaleOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_ScaleOption->SetSelection( 3 );
+ bmiddleLeftSizer->Add( m_ScaleOption, 0, wxALL, 5 );
+
+
+ bMainSizer->Add( bmiddleLeftSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bmiddleRightSizer;
+ bmiddleRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_ModeColorOptionChoices[] = { _("Color"), _("Black and white") };
+ int m_ModeColorOptionNChoices = sizeof( m_ModeColorOptionChoices ) / sizeof( wxString );
+ m_ModeColorOption = new wxRadioBox( this, wxID_PRINT_MODE, _("Print Mode"), wxDefaultPosition, wxDefaultSize, m_ModeColorOptionNChoices, m_ModeColorOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_ModeColorOption->SetSelection( 1 );
+ m_ModeColorOption->SetToolTip( _("Choose if you want to draw the sheet like it appears on screen,\nor in black and white mode, better to print it when using black and white printers") );
+
+ bmiddleRightSizer->Add( m_ModeColorOption, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bmiddleRightSizer, 1, 0, 5 );
+
+ wxBoxSizer* bbuttonsSizer;
+ bbuttonsSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_buttonOption = new wxButton( this, wxID_PRINT_OPTIONS, _("Page Options"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttonOption, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonPreview = new wxButton( this, wxID_PREVIEW, _("Preview"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttonPreview, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonPrint = new wxButton( this, wxID_PRINT_ALL, _("Print"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttonPrint, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonQuit = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttonQuit, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bbuttonsSizer, 0, 0, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PRINT_FOR_MODEDIT_BASE::OnCloseWindow ) );
+ m_buttonOption->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_FOR_MODEDIT_BASE::OnPageSetup ), NULL, this );
+ m_buttonPreview->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_FOR_MODEDIT_BASE::OnPrintPreview ), NULL, this );
+ m_buttonPrint->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_FOR_MODEDIT_BASE::OnPrintButtonClick ), NULL, this );
+ m_buttonQuit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_FOR_MODEDIT_BASE::OnButtonCancelClick ), NULL, this );
+}
+
+DIALOG_PRINT_FOR_MODEDIT_BASE::~DIALOG_PRINT_FOR_MODEDIT_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PRINT_FOR_MODEDIT_BASE::OnCloseWindow ) );
+ m_buttonOption->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_FOR_MODEDIT_BASE::OnPageSetup ), NULL, this );
+ m_buttonPreview->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_FOR_MODEDIT_BASE::OnPrintPreview ), NULL, this );
+ m_buttonPrint->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_FOR_MODEDIT_BASE::OnPrintButtonClick ), NULL, this );
+ m_buttonQuit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_FOR_MODEDIT_BASE::OnButtonCancelClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_print_for_modedit_base.fbp b/pcbnew/dialogs/dialog_print_for_modedit_base.fbp
new file mode 100644
index 0000000..c0a65be
--- /dev/null
+++ b/pcbnew/dialogs/dialog_print_for_modedit_base.fbp
@@ -0,0 +1,664 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_print_for_modedit_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DialogPrintModedit_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_PRINT_FOR_MODEDIT_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Print</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseWindow</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmiddleLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;fit in page&quot; &quot;Scale 0.5&quot; &quot;Scale 0.7&quot; &quot;Scale 1&quot; &quot;Scale 1.4&quot; &quot;Scale 2&quot; &quot;Scale 3&quot; &quot;Scale 4&quot; &quot;Scale 8&quot; &quot;Scale 16&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Approx. Scale:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ScaleOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">3</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmiddleRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Color&quot; &quot;Black and white&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PRINT_MODE</property>
+ <property name="label">Print Mode</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ModeColorOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Choose if you want to draw the sheet like it appears on screen,&#x0A;or in black and white mode, better to print it when using black and white printers</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bbuttonsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PRINT_OPTIONS</property>
+ <property name="label">Page Options</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnPageSetup</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PREVIEW</property>
+ <property name="label">Preview</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPreview</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnPrintPreview</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PRINT_ALL</property>
+ <property name="label">Print</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPrint</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnPrintButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonQuit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_print_for_modedit_base.h b/pcbnew/dialogs/dialog_print_for_modedit_base.h
new file mode 100644
index 0000000..3b8387d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_print_for_modedit_base.h
@@ -0,0 +1,66 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_PRINT_FOR_MODEDIT_BASE_H__
+#define __DIALOG_PRINT_FOR_MODEDIT_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/radiobox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PRINT_FOR_MODEDIT_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PRINT_FOR_MODEDIT_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ wxID_PRINT_MODE = 1000,
+ wxID_PRINT_OPTIONS,
+ wxID_PRINT_ALL
+ };
+
+ wxRadioBox* m_ScaleOption;
+ wxRadioBox* m_ModeColorOption;
+ wxButton* m_buttonOption;
+ wxButton* m_buttonPreview;
+ wxButton* m_buttonPrint;
+ wxButton* m_buttonQuit;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnPageSetup( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPrintPreview( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPrintButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonCancelClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PRINT_FOR_MODEDIT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Print"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_PRINT_FOR_MODEDIT_BASE();
+
+};
+
+#endif //__DIALOG_PRINT_FOR_MODEDIT_BASE_H__
diff --git a/pcbnew/dialogs/dialog_print_using_printer.cpp b/pcbnew/dialogs/dialog_print_using_printer.cpp
new file mode 100644
index 0000000..05b7d62
--- /dev/null
+++ b/pcbnew/dialogs/dialog_print_using_printer.cpp
@@ -0,0 +1,518 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+// Set this to 1 if you want to test PostScript printing under MSW.
+//#define wxTEST_POSTSCRIPT_IN_MSW 1
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <base_units.h>
+
+#include <printout_controler.h>
+#include <pcbnew.h>
+#include <pcbplot.h>
+
+#include <class_board.h>
+
+#include <dialog_print_using_printer_base.h>
+
+
+#define PEN_WIDTH_MAX_VALUE ( KiROUND( 5 * IU_PER_MM ) )
+#define PEN_WIDTH_MIN_VALUE ( KiROUND( 0.005 * IU_PER_MM ) )
+
+
+extern int g_DrawDefaultLineThickness;
+
+// Local variables
+static LSET s_SelectedLayers;
+static double s_ScaleList[] =
+{ 0, 0.5, 0.7, 0.999, 1.0, 1.4, 2.0, 3.0, 4.0 };
+
+// Define min et max reasonable values for print scale
+#define MIN_SCALE 0.01
+#define MAX_SCALE 100.0
+
+// static print data and page setup data, to remember settings during the session
+static wxPrintData* s_PrintData;
+static wxPageSetupDialogData* s_pageSetupData = (wxPageSetupDialogData*) NULL;
+
+static PRINT_PARAMETERS s_Parameters;
+
+
+/**
+ * Dialog to print schematic. Class derived from DIALOG_PRINT_USING_PRINTER_base
+ * created by wxFormBuilder
+ */
+class DIALOG_PRINT_USING_PRINTER : public DIALOG_PRINT_USING_PRINTER_base
+{
+public:
+ DIALOG_PRINT_USING_PRINTER( PCB_EDIT_FRAME* parent );
+
+ bool IsMirrored() { return m_Print_Mirror->IsChecked(); }
+ bool ExcludeEdges() { return m_Exclude_Edges_Pcb->IsChecked(); }
+ bool PrintUsingSinglePage() { return m_PagesOption->GetSelection(); }
+ int SetLayerSetFromListSelection();
+
+
+private:
+
+ PCB_EDIT_FRAME* m_parent;
+ wxConfigBase* m_config;
+ wxCheckBox* m_BoxSelectLayer[LAYER_ID_COUNT];
+ static bool m_ExcludeEdgeLayer;
+
+ void OnCloseWindow( wxCloseEvent& event );
+ void OnPageSetup( wxCommandEvent& event );
+ void OnPrintPreview( wxCommandEvent& event );
+ void OnPrintButtonClick( wxCommandEvent& event );
+ void OnScaleSelectionClick( wxCommandEvent& event );
+
+ void OnButtonCancelClick( wxCommandEvent& event ) { Close(); }
+ void SetPrintParameters( );
+ void SetPenWidth();
+ void initValues( );
+};
+
+
+bool DIALOG_PRINT_USING_PRINTER::m_ExcludeEdgeLayer;
+
+
+void PCB_EDIT_FRAME::ToPrinter( wxCommandEvent& event )
+{
+ const PAGE_INFO& pageInfo = GetPageSettings();
+
+ if( s_PrintData == NULL ) // First print
+ {
+ s_PrintData = new wxPrintData();
+
+ if( !s_PrintData->Ok() )
+ {
+ DisplayError( this, _( "Error Init Printer info" ) );
+ }
+ s_PrintData->SetQuality( wxPRINT_QUALITY_HIGH ); // Default resolution = HIGH;
+ }
+
+ if( s_pageSetupData == NULL )
+ s_pageSetupData = new wxPageSetupDialogData( *s_PrintData );
+
+ s_pageSetupData->SetPaperId( pageInfo.GetPaperId() );
+ s_pageSetupData->GetPrintData().SetOrientation( pageInfo.GetWxOrientation() );
+
+ if( pageInfo.IsCustom() )
+ {
+ if( pageInfo.IsPortrait() )
+ s_pageSetupData->SetPaperSize( wxSize( Mils2mm( pageInfo.GetWidthMils() ),
+ Mils2mm( pageInfo.GetHeightMils() ) ) );
+ else
+ s_pageSetupData->SetPaperSize( wxSize( Mils2mm( pageInfo.GetHeightMils() ),
+ Mils2mm( pageInfo.GetWidthMils() ) ) );
+ }
+
+ *s_PrintData = s_pageSetupData->GetPrintData();
+
+ DIALOG_PRINT_USING_PRINTER dlg( this );
+
+ dlg.ShowModal();
+}
+
+
+DIALOG_PRINT_USING_PRINTER::DIALOG_PRINT_USING_PRINTER( PCB_EDIT_FRAME* parent ) :
+ DIALOG_PRINT_USING_PRINTER_base( parent )
+{
+ m_parent = parent;
+ m_config = Kiface().KifaceSettings();
+ memset( m_BoxSelectLayer, 0, sizeof( m_BoxSelectLayer ) );
+
+ initValues( );
+
+ GetSizer()->SetSizeHints( this );
+ Center();
+#ifdef __WXMAC__
+ /* Problems with modal on wx-2.9 - Anyway preview is standard for OSX */
+ m_buttonPreview->Hide();
+#endif
+
+ GetSizer()->Fit( this );
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::initValues( )
+{
+ wxString msg;
+ BOARD* board = m_parent->GetBoard();
+
+ s_Parameters.m_PageSetupData = s_pageSetupData;
+
+ // Create layer list.
+ wxString layerKey;
+
+ LSEQ seq = board->GetEnabledLayers().UIOrder();
+
+ for( ; seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ m_BoxSelectLayer[layer] = new wxCheckBox( this, -1, board->GetLayerName( layer ) );
+
+ if( IsCopperLayer( layer ) )
+ m_CopperLayersBoxSizer->Add( m_BoxSelectLayer[layer], 0, wxGROW | wxALL, 1 );
+ else
+ m_TechnicalLayersBoxSizer->Add( m_BoxSelectLayer[layer], 0, wxGROW | wxALL, 1 );
+
+ layerKey.Printf( OPTKEY_LAYERBASE, layer );
+
+ bool option;
+
+ if( m_config->Read( layerKey, &option ) )
+ m_BoxSelectLayer[layer]->SetValue( option );
+ else
+ {
+ if( s_SelectedLayers[layer] )
+ m_BoxSelectLayer[layer]->SetValue( true );
+ }
+ }
+
+ // Option for excluding contents of "Edges Pcb" layer
+ m_Exclude_Edges_Pcb->Show( true );
+
+ // Read the scale adjust option
+ int scale_idx = 4; // default selected scale = ScaleList[4] = 1.000
+
+ if( m_config )
+ {
+ m_config->Read( OPTKEY_PRINT_X_FINESCALE_ADJ, &s_Parameters.m_XScaleAdjust );
+ m_config->Read( OPTKEY_PRINT_Y_FINESCALE_ADJ, &s_Parameters.m_YScaleAdjust );
+ m_config->Read( OPTKEY_PRINT_SCALE, &scale_idx );
+ m_config->Read( OPTKEY_PRINT_PAGE_FRAME, &s_Parameters.m_Print_Sheet_Ref, 1);
+ m_config->Read( OPTKEY_PRINT_MONOCHROME_MODE, &s_Parameters.m_Print_Black_and_White, 1);
+ m_config->Read( OPTKEY_PRINT_PAGE_PER_LAYER, &s_Parameters.m_OptionPrintPage, 0);
+ int tmp;
+ m_config->Read( OPTKEY_PRINT_PADS_DRILL, &tmp, PRINT_PARAMETERS::SMALL_DRILL_SHAPE );
+ s_Parameters.m_DrillShapeOpt = (PRINT_PARAMETERS::DrillShapeOptT) tmp;
+
+ // Test for a reasonable scale value. Set to 1 if problem
+ if( s_Parameters.m_XScaleAdjust < MIN_SCALE ||
+ s_Parameters.m_YScaleAdjust < MIN_SCALE ||
+ s_Parameters.m_XScaleAdjust > MAX_SCALE ||
+ s_Parameters.m_YScaleAdjust > MAX_SCALE )
+ s_Parameters.m_XScaleAdjust = s_Parameters.m_YScaleAdjust = 1.0;
+
+ s_SelectedLayers = LSET();
+
+ for( seq.Rewind(); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ wxString layerKey;
+ bool option;
+
+ layerKey.Printf( OPTKEY_LAYERBASE, layer );
+
+ option = false;
+ if( m_config->Read( layerKey, &option ) )
+ {
+ m_BoxSelectLayer[layer]->SetValue( option );
+ if( option )
+ s_SelectedLayers.set( layer );
+ }
+ }
+ }
+
+ m_ScaleOption->SetSelection( scale_idx );
+ scale_idx = m_ScaleOption->GetSelection();
+ s_Parameters.m_PrintScale = s_ScaleList[scale_idx];
+ m_Print_Mirror->SetValue(s_Parameters.m_PrintMirror);
+ m_Exclude_Edges_Pcb->SetValue(m_ExcludeEdgeLayer);
+ m_Print_Sheet_Ref->SetValue( s_Parameters.m_Print_Sheet_Ref );
+
+ // Options to plot pads and vias holes
+ m_Drill_Shape_Opt->SetSelection( s_Parameters.m_DrillShapeOpt );
+
+ if( s_Parameters.m_Print_Black_and_White )
+ m_ModeColorOption->SetSelection( 1 );
+ else
+ m_ModeColorOption->SetSelection( 0 );
+
+ m_PagesOption->SetSelection(s_Parameters.m_OptionPrintPage);
+ s_Parameters.m_PenDefaultSize = g_DrawDefaultLineThickness;
+ AddUnitSymbol( *m_TextPenWidth, g_UserUnit );
+ m_DialogPenWidth->SetValue(
+ StringFromValue( g_UserUnit, s_Parameters.m_PenDefaultSize ) );
+
+ // Create scale adjust option
+ msg.Printf( wxT( "%f" ), s_Parameters.m_XScaleAdjust );
+ m_FineAdjustXscaleOpt->SetValue( msg );
+
+ msg.Printf( wxT( "%f" ), s_Parameters.m_YScaleAdjust );
+ m_FineAdjustYscaleOpt->SetValue( msg );
+
+ bool enable = (s_Parameters.m_PrintScale == 1.0);
+ m_FineAdjustXscaleOpt->Enable(enable);
+ m_FineAdjustYscaleOpt->Enable(enable);
+}
+
+
+int DIALOG_PRINT_USING_PRINTER::SetLayerSetFromListSelection()
+{
+ int page_count = 0;
+
+ s_Parameters.m_PrintMaskLayer = LSET();
+
+ for( unsigned ii = 0; ii < DIM(m_BoxSelectLayer); ++ii )
+ {
+ if( !m_BoxSelectLayer[ii] )
+ continue;
+
+ if( m_BoxSelectLayer[ii]->IsChecked() )
+ {
+ page_count++;
+ s_Parameters.m_PrintMaskLayer.set( ii );
+ }
+ }
+
+ // In Pcbnew force the EDGE layer to be printed or not with the other layers
+ m_ExcludeEdgeLayer = m_Exclude_Edges_Pcb->IsChecked();
+ if( m_ExcludeEdgeLayer )
+ s_Parameters.m_Flags = 0;
+ else
+ s_Parameters.m_Flags = 1;
+
+ s_Parameters.m_PageCount = page_count;
+
+ return page_count;
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::OnCloseWindow( wxCloseEvent& event )
+{
+ SetPrintParameters();
+
+ if( m_config )
+ {
+ ConfigBaseWriteDouble( m_config, OPTKEY_PRINT_X_FINESCALE_ADJ,
+ s_Parameters.m_XScaleAdjust );
+ ConfigBaseWriteDouble( m_config, OPTKEY_PRINT_Y_FINESCALE_ADJ,
+ s_Parameters.m_YScaleAdjust );
+ m_config->Write( OPTKEY_PRINT_SCALE, m_ScaleOption->GetSelection() );
+ m_config->Write( OPTKEY_PRINT_PAGE_FRAME, s_Parameters.m_Print_Sheet_Ref);
+ m_config->Write( OPTKEY_PRINT_MONOCHROME_MODE, s_Parameters.m_Print_Black_and_White);
+ m_config->Write( OPTKEY_PRINT_PAGE_PER_LAYER, s_Parameters.m_OptionPrintPage );
+ m_config->Write( OPTKEY_PRINT_PADS_DRILL, (long) s_Parameters.m_DrillShapeOpt );
+ wxString layerKey;
+
+ for( unsigned layer = 0; layer < DIM(m_BoxSelectLayer); ++layer )
+ {
+ if( !m_BoxSelectLayer[layer] )
+ continue;
+
+ layerKey.Printf( OPTKEY_LAYERBASE, layer );
+ m_config->Write( layerKey, m_BoxSelectLayer[layer]->IsChecked() );
+ }
+ }
+
+ EndModal( 0 );
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::SetPrintParameters( )
+{
+ PCB_PLOT_PARAMS plot_opts = m_parent->GetPlotSettings();
+
+ s_Parameters.m_PrintMirror = m_Print_Mirror->GetValue();
+ s_Parameters.m_Print_Sheet_Ref = m_Print_Sheet_Ref->GetValue();
+ s_Parameters.m_Print_Black_and_White =
+ m_ModeColorOption->GetSelection() != 0;
+
+ s_Parameters.m_DrillShapeOpt =
+ (PRINT_PARAMETERS::DrillShapeOptT) m_Drill_Shape_Opt->GetSelection();
+
+ if( m_PagesOption )
+ s_Parameters.m_OptionPrintPage = m_PagesOption->GetSelection() != 0;
+
+ SetLayerSetFromListSelection();
+
+ int idx = m_ScaleOption->GetSelection();
+ s_Parameters.m_PrintScale = s_ScaleList[idx];
+ plot_opts.SetScale( s_Parameters.m_PrintScale );
+
+ if( m_FineAdjustXscaleOpt )
+ {
+ if( s_Parameters.m_XScaleAdjust > MAX_SCALE ||
+ s_Parameters.m_YScaleAdjust > MAX_SCALE )
+ DisplayInfoMessage( NULL, _( "Warning: Scale option set to a very large value" ) );
+
+ m_FineAdjustXscaleOpt->GetValue().ToDouble( &s_Parameters.m_XScaleAdjust );
+ }
+
+ if( m_FineAdjustYscaleOpt )
+ {
+ // Test for a reasonable scale value
+ if( s_Parameters.m_XScaleAdjust < MIN_SCALE ||
+ s_Parameters.m_YScaleAdjust < MIN_SCALE )
+ DisplayInfoMessage( NULL, _( "Warning: Scale option set to a very small value" ) );
+
+ m_FineAdjustYscaleOpt->GetValue().ToDouble( &s_Parameters.m_YScaleAdjust );
+ }
+
+ plot_opts.SetFineScaleAdjustX( s_Parameters.m_XScaleAdjust );
+ plot_opts.SetFineScaleAdjustY( s_Parameters.m_YScaleAdjust );
+
+ m_parent->SetPlotSettings( plot_opts );
+
+ SetPenWidth();
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::SetPenWidth()
+{
+ // Get the new pen width value, and verify min et max value
+ // NOTE: s_Parameters.m_PenDefaultSize is in internal units
+
+ s_Parameters.m_PenDefaultSize = ValueFromTextCtrl( *m_DialogPenWidth );
+
+ if( s_Parameters.m_PenDefaultSize > PEN_WIDTH_MAX_VALUE )
+ {
+ s_Parameters.m_PenDefaultSize = PEN_WIDTH_MAX_VALUE;
+ }
+
+ if( s_Parameters.m_PenDefaultSize < PEN_WIDTH_MIN_VALUE )
+ {
+ s_Parameters.m_PenDefaultSize = PEN_WIDTH_MIN_VALUE;
+ }
+
+ g_DrawDefaultLineThickness = s_Parameters.m_PenDefaultSize;
+
+ m_DialogPenWidth->SetValue(
+ StringFromValue( g_UserUnit, s_Parameters.m_PenDefaultSize ) );
+}
+
+void DIALOG_PRINT_USING_PRINTER::OnScaleSelectionClick( wxCommandEvent& event )
+{
+ double scale = s_ScaleList[m_ScaleOption->GetSelection()];
+ bool enable = (scale == 1.0);
+
+ if( m_FineAdjustXscaleOpt )
+ m_FineAdjustXscaleOpt->Enable(enable);
+ if( m_FineAdjustYscaleOpt )
+ m_FineAdjustYscaleOpt->Enable(enable);
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::OnPageSetup( wxCommandEvent& event )
+{
+ wxPageSetupDialog pageSetupDialog( this, s_pageSetupData );
+ pageSetupDialog.ShowModal();
+
+ (*s_PrintData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
+ (*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event )
+{
+ SetPrintParameters( );
+
+ // If no layer selected, we have no plot. prompt user if it happens
+ // because he could think there is a bug in Pcbnew:
+ if( s_Parameters.m_PrintMaskLayer == 0 )
+ {
+ DisplayError( this, _( "No layer selected" ) );
+ return;
+ }
+
+ // Pass two printout objects: for preview, and possible printing.
+ wxString title = _( "Print Preview" );
+ wxPrintPreview* preview =
+ new wxPrintPreview( new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_parent, title ),
+ new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_parent, title ),
+ s_PrintData );
+
+ if( preview == NULL )
+ {
+ DisplayError( this, wxT( "An error occurred attempting to show the print preview window." ) );
+ return;
+ }
+
+ // Uses the parent position and size.
+ wxPoint WPos = m_parent->GetPosition();
+ wxSize WSize = m_parent->GetSize();
+
+ preview->SetZoom( 100 );
+
+ wxPreviewFrame* frame = new wxPreviewFrame( preview, this, title, WPos, WSize );
+ frame->SetMinSize( wxSize( 550, 350 ) );
+ frame->Center();
+
+ // On wxGTK, set the flag wxTOPLEVEL_EX_DIALOG is mandatory, if we want
+ // close the frame using the X box in caption, when the preview frame is run
+ // from a dialog
+ frame->SetExtraStyle( frame->GetExtraStyle() | wxTOPLEVEL_EX_DIALOG );
+
+ // We use here wxPreviewFrame_WindowModal option to make the wxPrintPreview frame
+ // modal for its caller only.
+ // An other reason is the fact when closing the frame without this option,
+ // all top level frames are reenabled.
+ // With this option, only the parent is reenabled.
+ // Reenabling all top level frames should be made by the parent dialog.
+ frame->InitializeWithModality( wxPreviewFrame_WindowModal );
+
+ frame->Raise(); // Needed on Ubuntu/Unity to display the frame
+ frame->Show( true );
+}
+
+
+void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event )
+{
+ SetPrintParameters( );
+
+ // If no layer selected, we have no plot. prompt user if it happens
+ // because he could think there is a bug in Pcbnew:
+ if( s_Parameters.m_PrintMaskLayer == 0 )
+ {
+ DisplayError( this, _( "No layer selected." ) );
+ return;
+ }
+
+ wxPrintDialogData printDialogData( *s_PrintData );
+
+ wxPrinter printer( &printDialogData );
+
+ wxString title = _( "Print" );
+ BOARD_PRINTOUT_CONTROLLER printout( s_Parameters, m_parent, title );
+
+ if( !printer.Print( this, &printout, true ) )
+ {
+ if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
+ DisplayError( this, _( "There was a problem printing." ) );
+
+ return;
+ }
+ else
+ {
+ *s_PrintData = printer.GetPrintDialogData().GetPrintData();
+ }
+}
diff --git a/pcbnew/dialogs/dialog_print_using_printer_base.cpp b/pcbnew/dialogs/dialog_print_using_printer_base.cpp
new file mode 100644
index 0000000..f5eceb0
--- /dev/null
+++ b/pcbnew/dialogs/dialog_print_using_printer_base.cpp
@@ -0,0 +1,180 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_print_using_printer_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_PRINT_USING_PRINTER_base::DIALOG_PRINT_USING_PRINTER_base( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sbLayersSizer;
+ sbLayersSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Layers:") ), wxVERTICAL );
+
+ wxBoxSizer* bleftSizer;
+ bleftSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ m_CopperLayersBoxSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Copper Layers:") ), wxVERTICAL );
+
+
+ bleftSizer->Add( m_CopperLayersBoxSizer, 1, wxALL, 5 );
+
+ m_TechnicalLayersBoxSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Technical Layers:") ), wxVERTICAL );
+
+
+ bleftSizer->Add( m_TechnicalLayersBoxSizer, 1, wxALL, 5 );
+
+
+ sbLayersSizer->Add( bleftSizer, 1, wxEXPAND, 5 );
+
+ m_Exclude_Edges_Pcb = new wxCheckBox( this, wxID_ANY, _("Exclude Edges_Pcb Layer"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Exclude_Edges_Pcb->SetToolTip( _("Exclude contents of Edges_Pcb layer from all other layers") );
+
+ sbLayersSizer->Add( m_Exclude_Edges_Pcb, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( sbLayersSizer, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bmiddleLeftSizer;
+ bmiddleLeftSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_ScaleOptionChoices[] = { _("fit in page"), _("Scale 0.5"), _("Scale 0.7"), _("Approx. Scale 1"), _("Accurate Scale 1"), _("Scale 1.4"), _("Scale 2"), _("Scale 3"), _("Scale 4") };
+ int m_ScaleOptionNChoices = sizeof( m_ScaleOptionChoices ) / sizeof( wxString );
+ m_ScaleOption = new wxRadioBox( this, wxID_ANY, _("Approx. Scale:"), wxDefaultPosition, wxDefaultSize, m_ScaleOptionNChoices, m_ScaleOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_ScaleOption->SetSelection( 4 );
+ bmiddleLeftSizer->Add( m_ScaleOption, 0, wxALL, 5 );
+
+ m_FineAdjustXscaleTitle = new wxStaticText( this, wxID_ANY, _("X Scale Adjust"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_FineAdjustXscaleTitle->Wrap( -1 );
+ bmiddleLeftSizer->Add( m_FineAdjustXscaleTitle, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_FineAdjustXscaleOpt = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_FineAdjustXscaleOpt->SetMaxLength( 0 );
+ m_FineAdjustXscaleOpt->SetToolTip( _("Set X scale adjust for exact scale plotting") );
+
+ bmiddleLeftSizer->Add( m_FineAdjustXscaleOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_FineAdjustYscaleTitle = new wxStaticText( this, wxID_ANY, _("Y Scale Adjust"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_FineAdjustYscaleTitle->Wrap( -1 );
+ bmiddleLeftSizer->Add( m_FineAdjustYscaleTitle, 0, wxRIGHT|wxLEFT, 5 );
+
+ m_FineAdjustYscaleOpt = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_FineAdjustYscaleOpt->SetMaxLength( 0 );
+ m_FineAdjustYscaleOpt->SetToolTip( _("Set Y scale adjust for exact scale plotting") );
+
+ bmiddleLeftSizer->Add( m_FineAdjustYscaleOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bmiddleLeftSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bmiddleRightSizer;
+ bmiddleRightSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbOptionsSizer;
+ sbOptionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options:") ), wxVERTICAL );
+
+ m_TextPenWidth = new wxStaticText( this, wxID_ANY, _("Default pen size"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextPenWidth->Wrap( -1 );
+ m_TextPenWidth->SetToolTip( _("Pen size used to draw items that have no pen size specified.\nUsed mainly to draw items in sketch mode.") );
+
+ sbOptionsSizer->Add( m_TextPenWidth, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_DialogPenWidth = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_DialogPenWidth->SetMaxLength( 0 );
+ sbOptionsSizer->Add( m_DialogPenWidth, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ m_Print_Sheet_Ref = new wxCheckBox( this, wxID_FRAME_SEL, _("Print frame ref"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_Print_Sheet_Ref->SetValue(true);
+ m_Print_Sheet_Ref->SetToolTip( _("Print (or not) the Frame references.") );
+
+ sbOptionsSizer->Add( m_Print_Sheet_Ref, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_Print_Mirror = new wxCheckBox( this, wxID_ANY, _("Mirror"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbOptionsSizer->Add( m_Print_Mirror, 0, wxALL, 5 );
+
+
+ bmiddleRightSizer->Add( sbOptionsSizer, 0, wxEXPAND|wxALL, 5 );
+
+ wxString m_Drill_Shape_OptChoices[] = { _("No drill mark"), _("Small mark"), _("Real drill") };
+ int m_Drill_Shape_OptNChoices = sizeof( m_Drill_Shape_OptChoices ) / sizeof( wxString );
+ m_Drill_Shape_Opt = new wxRadioBox( this, wxID_ANY, _("Pads Drill Opt"), wxDefaultPosition, wxDefaultSize, m_Drill_Shape_OptNChoices, m_Drill_Shape_OptChoices, 1, wxRA_SPECIFY_COLS );
+ m_Drill_Shape_Opt->SetSelection( 1 );
+ bmiddleRightSizer->Add( m_Drill_Shape_Opt, 0, wxALL|wxEXPAND, 5 );
+
+ wxString m_ModeColorOptionChoices[] = { _("Color"), _("Black and white") };
+ int m_ModeColorOptionNChoices = sizeof( m_ModeColorOptionChoices ) / sizeof( wxString );
+ m_ModeColorOption = new wxRadioBox( this, wxID_PRINT_MODE, _("Print Mode"), wxDefaultPosition, wxDefaultSize, m_ModeColorOptionNChoices, m_ModeColorOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_ModeColorOption->SetSelection( 1 );
+ m_ModeColorOption->SetToolTip( _("Choose if you want to draw the sheet like it appears on screen,\nor in black and white mode, better to print it when using black and white printers") );
+
+ bmiddleRightSizer->Add( m_ModeColorOption, 0, wxALL|wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bmiddleRightSizer, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bbuttonsSizer;
+ bbuttonsSizer = new wxBoxSizer( wxVERTICAL );
+
+ wxString m_PagesOptionChoices[] = { _("1 Page per Layer"), _("Single page") };
+ int m_PagesOptionNChoices = sizeof( m_PagesOptionChoices ) / sizeof( wxString );
+ m_PagesOption = new wxRadioBox( this, wxID_PAGE_MODE, _("Page Print"), wxDefaultPosition, wxDefaultSize, m_PagesOptionNChoices, m_PagesOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_PagesOption->SetSelection( 0 );
+ bbuttonsSizer->Add( m_PagesOption, 0, wxALL|wxEXPAND, 5 );
+
+
+ bbuttonsSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_buttonOption = new wxButton( this, wxID_PRINT_OPTIONS, _("Page Options"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttonOption, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonPreview = new wxButton( this, wxID_PREVIEW, _("Preview"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttonPreview, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonPrint = new wxButton( this, wxID_PRINT_ALL, _("Print"), wxDefaultPosition, wxDefaultSize, 0 );
+ bbuttonsSizer->Add( m_buttonPrint, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonQuit = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_buttonQuit->SetDefault();
+ bbuttonsSizer->Add( m_buttonQuit, 0, wxALL|wxEXPAND, 5 );
+
+
+ bbuttonsSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ bMainSizer->Add( bbuttonsSizer, 0, wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PRINT_USING_PRINTER_base::OnCloseWindow ) );
+ m_ScaleOption->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_base::OnScaleSelectionClick ), NULL, this );
+ m_buttonOption->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_base::OnPageSetup ), NULL, this );
+ m_buttonPreview->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_base::OnPrintPreview ), NULL, this );
+ m_buttonPrint->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_base::OnPrintButtonClick ), NULL, this );
+ m_buttonQuit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_base::OnButtonCancelClick ), NULL, this );
+}
+
+DIALOG_PRINT_USING_PRINTER_base::~DIALOG_PRINT_USING_PRINTER_base()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PRINT_USING_PRINTER_base::OnCloseWindow ) );
+ m_ScaleOption->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_base::OnScaleSelectionClick ), NULL, this );
+ m_buttonOption->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_base::OnPageSetup ), NULL, this );
+ m_buttonPreview->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_base::OnPrintPreview ), NULL, this );
+ m_buttonPrint->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_base::OnPrintButtonClick ), NULL, this );
+ m_buttonQuit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_base::OnButtonCancelClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_print_using_printer_base.fbp b/pcbnew/dialogs/dialog_print_using_printer_base.fbp
new file mode 100644
index 0000000..d817f7d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_print_using_printer_base.fbp
@@ -0,0 +1,1717 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_print_using_printer_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DialogPrint_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">1</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_PRINT_USING_PRINTER_base</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Print</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnCloseWindow</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layers:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbLayersSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bleftSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Copper Layers:</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_CopperLayersBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Technical Layers:</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_TechnicalLayersBoxSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Exclude Edges_Pcb Layer</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Exclude_Edges_Pcb</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Exclude contents of Edges_Pcb layer from all other layers</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmiddleLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;fit in page&quot; &quot;Scale 0.5&quot; &quot;Scale 0.7&quot; &quot;Approx. Scale 1&quot; &quot;Accurate Scale 1&quot; &quot;Scale 1.4&quot; &quot;Scale 2&quot; &quot;Scale 3&quot; &quot;Scale 4&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Approx. Scale:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ScaleOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">4</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox">OnScaleSelectionClick</event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">X Scale Adjust</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FineAdjustXscaleTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FineAdjustXscaleOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Set X scale adjust for exact scale plotting</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Y Scale Adjust</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FineAdjustYscaleTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_FineAdjustYscaleOpt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Set Y scale adjust for exact scale plotting</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmiddleRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Options:</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbOptionsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default pen size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextPenWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Pen size used to draw items that have no pen size specified.&#x0A;Used mainly to draw items in sketch mode.</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_DialogPenWidth</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_FRAME_SEL</property>
+ <property name="label">Print frame ref</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Print_Sheet_Ref</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Print (or not) the Frame references.</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Mirror</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Print_Mirror</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;No drill mark&quot; &quot;Small mark&quot; &quot;Real drill&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Pads Drill Opt</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_Drill_Shape_Opt</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Color&quot; &quot;Black and white&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PRINT_MODE</property>
+ <property name="label">Print Mode</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ModeColorOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Choose if you want to draw the sheet like it appears on screen,&#x0A;or in black and white mode, better to print it when using black and white printers</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bbuttonsSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;1 Page per Layer&quot; &quot;Single page&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PAGE_MODE</property>
+ <property name="label">Page Print</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_PagesOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PRINT_OPTIONS</property>
+ <property name="label">Page Options</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnPageSetup</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PREVIEW</property>
+ <property name="label">Preview</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPreview</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnPrintPreview</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_PRINT_ALL</property>
+ <property name="label">Print</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonPrint</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnPrintButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_CANCEL</property>
+ <property name="label">Close</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonQuit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnButtonCancelClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_print_using_printer_base.h b/pcbnew/dialogs/dialog_print_using_printer_base.h
new file mode 100644
index 0000000..2748dcb
--- /dev/null
+++ b/pcbnew/dialogs/dialog_print_using_printer_base.h
@@ -0,0 +1,86 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_PRINT_USING_PRINTER_BASE_H__
+#define __DIALOG_PRINT_USING_PRINTER_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/gdicmn.h>
+#include <wx/checkbox.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/radiobox.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_PRINT_USING_PRINTER_base
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_PRINT_USING_PRINTER_base : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ enum
+ {
+ wxID_FRAME_SEL = 1000,
+ wxID_PRINT_MODE,
+ wxID_PAGE_MODE,
+ wxID_PRINT_OPTIONS,
+ wxID_PRINT_ALL
+ };
+
+ wxStaticBoxSizer* m_CopperLayersBoxSizer;
+ wxStaticBoxSizer* m_TechnicalLayersBoxSizer;
+ wxCheckBox* m_Exclude_Edges_Pcb;
+ wxRadioBox* m_ScaleOption;
+ wxStaticText* m_FineAdjustXscaleTitle;
+ wxTextCtrl* m_FineAdjustXscaleOpt;
+ wxStaticText* m_FineAdjustYscaleTitle;
+ wxTextCtrl* m_FineAdjustYscaleOpt;
+ wxStaticText* m_TextPenWidth;
+ wxTextCtrl* m_DialogPenWidth;
+ wxCheckBox* m_Print_Sheet_Ref;
+ wxCheckBox* m_Print_Mirror;
+ wxRadioBox* m_Drill_Shape_Opt;
+ wxRadioBox* m_ModeColorOption;
+ wxRadioBox* m_PagesOption;
+ wxButton* m_buttonOption;
+ wxButton* m_buttonPreview;
+ wxButton* m_buttonPrint;
+ wxButton* m_buttonQuit;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnScaleSelectionClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPageSetup( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPrintPreview( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPrintButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonCancelClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_PRINT_USING_PRINTER_base( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Print"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_PRINT_USING_PRINTER_base();
+
+};
+
+#endif //__DIALOG_PRINT_USING_PRINTER_BASE_H__
diff --git a/pcbnew/dialogs/dialog_scripting.cpp b/pcbnew/dialogs/dialog_scripting.cpp
new file mode 100644
index 0000000..3ae282b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_scripting.cpp
@@ -0,0 +1,52 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2014 Miguel Angel Ajo <miguelangel@nbee.es>
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_scripting.cpp
+ */
+
+
+#include <Python.h>
+#include <fctsys.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <dialog_scripting.h>
+
+
+DIALOG_SCRIPTING::DIALOG_SCRIPTING( wxWindow* parent )
+ : DIALOG_SCRIPTING_BASE( parent )
+{
+ SetFocus();
+
+}
+
+
+
+void DIALOG_SCRIPTING::OnRunButtonClick( wxCommandEvent& event )
+{
+ wxCharBuffer buffer = m_txScript->GetValue().ToUTF8();
+ PyRun_SimpleString(buffer.data());
+}
+
+
diff --git a/pcbnew/dialogs/dialog_scripting.h b/pcbnew/dialogs/dialog_scripting.h
new file mode 100644
index 0000000..deb33b7
--- /dev/null
+++ b/pcbnew/dialogs/dialog_scripting.h
@@ -0,0 +1,39 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2014 Miguel Angel Ajo <miguelangel@nbee.es>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _DIALOG_SCRIPTING_H_
+#define _DIALOG_SCRIPTING_H_
+
+#include <dialog_scripting_base.h>
+
+class DIALOG_SCRIPTING: public DIALOG_SCRIPTING_BASE
+{
+public:
+ DIALOG_SCRIPTING( wxWindow * parent );
+
+private:
+ void OnRunButtonClick( wxCommandEvent& event );
+};
+
+#endif // _DIALOG_SCRIPTING_H_
diff --git a/pcbnew/dialogs/dialog_scripting_base.cpp b/pcbnew/dialogs/dialog_scripting_base.cpp
new file mode 100644
index 0000000..3b2cb4f
--- /dev/null
+++ b/pcbnew/dialogs/dialog_scripting_base.cpp
@@ -0,0 +1,43 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_scripting_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_SCRIPTING_BASE::DIALOG_SCRIPTING_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ m_txScript = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTE_MULTILINE );
+ m_txScript->SetMaxLength( 0 );
+ m_txScript->SetMinSize( wxSize( 480,500 ) );
+
+ bSizerMain->Add( m_txScript, 1, wxALL|wxEXPAND, 5 );
+
+ m_btRun = new wxButton( this, wxID_ANY, wxT("&Run"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerMain->Add( m_btRun, 0, wxALL, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_btRun->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCRIPTING_BASE::OnRunButtonClick ), NULL, this );
+}
+
+DIALOG_SCRIPTING_BASE::~DIALOG_SCRIPTING_BASE()
+{
+ // Disconnect Events
+ m_btRun->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCRIPTING_BASE::OnRunButtonClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_scripting_base.fbp b/pcbnew/dialogs/dialog_scripting_base.fbp
new file mode 100644
index 0000000..d9b5e98
--- /dev/null
+++ b/pcbnew/dialogs/dialog_scripting_base.fbp
@@ -0,0 +1,278 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_scripting_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">0</property>
+ <property name="name">DIALOG_SCRIPTING_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Frame" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_SCRIPTING_BASE</property>
+ <property name="pos"></property>
+ <property name="size">500,468</property>
+ <property name="style">wxDEFAULT_FRAME_STYLE</property>
+ <property name="subclass"></property>
+ <property name="title">Scripting Test Window</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <property name="xrc_skip_sizer">1</property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">480,500</property>
+ <property name="moveable">1</property>
+ <property name="name">m_txScript</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxHSCROLL|wxTE_MULTILINE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">&amp;Run</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_btRun</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnRunButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_scripting_base.h b/pcbnew/dialogs/dialog_scripting_base.h
new file mode 100644
index 0000000..eb42fb6
--- /dev/null
+++ b/pcbnew/dialogs/dialog_scripting_base.h
@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_SCRIPTING_BASE_H__
+#define __DIALOG_SCRIPTING_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/string.h>
+#include <wx/textctrl.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/frame.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_SCRIPTING_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_SCRIPTING_BASE : public wxFrame
+{
+ private:
+
+ protected:
+ wxTextCtrl* m_txScript;
+ wxButton* m_btRun;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnRunButtonClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_SCRIPTING_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Scripting Test Window"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,468 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
+
+ ~DIALOG_SCRIPTING_BASE();
+
+};
+
+#endif //__DIALOG_SCRIPTING_BASE_H__
diff --git a/pcbnew/dialogs/dialog_select_pretty_lib.cpp b/pcbnew/dialogs/dialog_select_pretty_lib.cpp
new file mode 100644
index 0000000..6cd1a4c
--- /dev/null
+++ b/pcbnew/dialogs/dialog_select_pretty_lib.cpp
@@ -0,0 +1,78 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_select_pretty_lib.cpp
+ * @brief A dialog to select/create a .pretty folder which is a
+ * footprint library.
+ * footprints are .kicad_mod files inside this folder
+ */
+
+#include <wildcards_and_files_ext.h>
+#include <dialog_select_pretty_lib.h>
+#include <project.h>
+
+
+DIALOG_SELECT_PRETTY_LIB::DIALOG_SELECT_PRETTY_LIB( wxWindow* parent,
+ const wxString& aDefaultPath ) :
+ DIALOG_SELECT_PRETTY_LIB_BASE( parent )
+{
+ if( !aDefaultPath.IsEmpty() )
+ m_dirCtrl->SetPath( aDefaultPath );
+
+ m_sdbSizerOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void DIALOG_SELECT_PRETTY_LIB::OnSelectFolder( wxFileDirPickerEvent& event )
+{
+ m_libName->SetValue( m_dirCtrl->GetPath() );
+
+ event.Skip();
+}
+
+
+const wxString DIALOG_SELECT_PRETTY_LIB::GetFullPrettyLibName()
+{
+ wxFileName fn = m_libName->GetValue();
+
+ if( !fn.IsAbsolute() )
+ fn.MakeAbsolute( m_dirCtrl->GetPath() );
+
+ // Enforce the extension:
+ fn.SetExt( KiCadFootprintLibPathExtension );
+
+ return fn.GetFullPath();
+}
+
+void DIALOG_SELECT_PRETTY_LIB::OnOKButton( wxCommandEvent& event )
+{
+ event.Skip();
+}
diff --git a/pcbnew/dialogs/dialog_select_pretty_lib.h b/pcbnew/dialogs/dialog_select_pretty_lib.h
new file mode 100644
index 0000000..0188c19
--- /dev/null
+++ b/pcbnew/dialogs/dialog_select_pretty_lib.h
@@ -0,0 +1,58 @@
+#ifndef __DIALOG_SELECT_PRETTY_LIB_H__
+#define __DIALOG_SELECT_PRETTY_LIB_H__
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file dialog_select_pretty_lib.h
+ * @brief A dialog to select/create a .pretty folder which is a
+ * footprint library.
+ * footprints are .kicad_mod files inside this folder
+ */
+
+#include <dialog_select_pretty_lib_base.h>
+
+
+class DIALOG_SELECT_PRETTY_LIB : public DIALOG_SELECT_PRETTY_LIB_BASE
+{
+public:
+ DIALOG_SELECT_PRETTY_LIB( wxWindow* parent,
+ const wxString& aDefaultPath );
+ ~DIALOG_SELECT_PRETTY_LIB() {};
+
+ /**
+ * @return the full .pretty lib name, which is an absolute path
+ *, ending wityh ".pretty"
+ */
+ const wxString GetFullPrettyLibName();
+
+private:
+ virtual void OnSelectFolder( wxFileDirPickerEvent& event );
+ virtual void OnOKButton( wxCommandEvent& event );
+};
+
+
+#endif //__DIALOG_SELECT_PRETTY_LIB_BASE_H__
diff --git a/pcbnew/dialogs/dialog_select_pretty_lib_base.cpp b/pcbnew/dialogs/dialog_select_pretty_lib_base.cpp
new file mode 100644
index 0000000..17b70a1
--- /dev/null
+++ b/pcbnew/dialogs/dialog_select_pretty_lib_base.cpp
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_select_pretty_lib_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_SELECT_PRETTY_LIB_BASE::DIALOG_SELECT_PRETTY_LIB_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText = new wxStaticText( this, wxID_ANY, _("The footprint library is a folder with a name ending with .pretty\nFootprints are .kicad_mod files inside this folder."), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText->Wrap( -1 );
+ m_staticText->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
+
+ bSizerMain->Add( m_staticText, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
+
+ m_staticText3 = new wxStaticText( this, wxID_ANY, _("Path base:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ bSizerMain->Add( m_staticText3, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_dirCtrl = new wxDirPickerCtrl( this, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, wxDIRP_DEFAULT_STYLE );
+ bSizerMain->Add( m_dirCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_SizerNewLibName = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextDirname = new wxStaticText( this, wxID_ANY, _("Library folder (.pretty will be added to name, if missing)"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextDirname->Wrap( -1 );
+ m_SizerNewLibName->Add( m_staticTextDirname, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_libName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_SizerNewLibName->Add( m_libName, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizerMain->Add( m_SizerNewLibName, 0, wxEXPAND, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerMain->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bSizerMain->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+ bSizerMain->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_dirCtrl->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( DIALOG_SELECT_PRETTY_LIB_BASE::OnSelectFolder ), NULL, this );
+ m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_PRETTY_LIB_BASE::OnOKButton ), NULL, this );
+}
+
+DIALOG_SELECT_PRETTY_LIB_BASE::~DIALOG_SELECT_PRETTY_LIB_BASE()
+{
+ // Disconnect Events
+ m_dirCtrl->Disconnect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( DIALOG_SELECT_PRETTY_LIB_BASE::OnSelectFolder ), NULL, this );
+ m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_PRETTY_LIB_BASE::OnOKButton ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_select_pretty_lib_base.fbp b/pcbnew/dialogs/dialog_select_pretty_lib_base.fbp
new file mode 100644
index 0000000..34d665b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_select_pretty_lib_base.fbp
@@ -0,0 +1,645 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_select_pretty_lib_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_select_pretty_lib_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_SELECT_PRETTY_LIB_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Select Footprint Library Folder</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_HORIZONTAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font">,90,92,-1,70,0</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">The footprint library is a folder with a name ending with .pretty&#x0A;Footprints are .kicad_mod files inside this folder.</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Path base:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxDirPickerCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="message">Select a folder</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_dirCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxDIRP_DEFAULT_STYLE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnDirChanged">OnSelectFolder</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_SizerNewLibName</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Library folder (.pretty will be added to name, if missing)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextDirname</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_libName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKButton</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_select_pretty_lib_base.h b/pcbnew/dialogs/dialog_select_pretty_lib_base.h
new file mode 100644
index 0000000..9c5893d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_select_pretty_lib_base.h
@@ -0,0 +1,64 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_SELECT_PRETTY_LIB_BASE_H__
+#define __DIALOG_SELECT_PRETTY_LIB_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/filepicker.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_SELECT_PRETTY_LIB_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_SELECT_PRETTY_LIB_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText;
+ wxStaticText* m_staticText3;
+ wxDirPickerCtrl* m_dirCtrl;
+ wxBoxSizer* m_SizerNewLibName;
+ wxStaticText* m_staticTextDirname;
+ wxTextCtrl* m_libName;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnSelectFolder( wxFileDirPickerEvent& event ) { event.Skip(); }
+ virtual void OnOKButton( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_SELECT_PRETTY_LIB_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select Footprint Library Folder"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_SELECT_PRETTY_LIB_BASE();
+
+};
+
+#endif //__DIALOG_SELECT_PRETTY_LIB_BASE_H__
diff --git a/pcbnew/dialogs/dialog_set_grid.cpp b/pcbnew/dialogs/dialog_set_grid.cpp
new file mode 100644
index 0000000..da8148e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_set_grid.cpp
@@ -0,0 +1,307 @@
+/**
+ * @file dialog_set_grid.cpp
+ * @brief Manage user grid.
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <macros.h>
+#include <common.h>
+#include <base_units.h>
+#include <macros.h>
+
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <dialog_set_grid_base.h>
+#include <invoke_pcb_dialog.h>
+
+#include <gal/graphics_abstraction_layer.h>
+#include <class_draw_panel_gal.h>
+#include <tool/tool_manager.h>
+#include <tools/common_actions.h>
+
+// Max values for grid size
+#define MAX_GRID_SIZE ( 50.0 * IU_PER_MM )
+#define MIN_GRID_SIZE ( 0.001 * IU_PER_MM )
+
+// Min/Max value for grid offset
+#define MAX_GRID_OFFSET ((double)INT_MAX/2)
+
+class DIALOG_SET_GRID : public DIALOG_SET_GRID_BASE
+{
+public:
+
+ /// This has no dependencies on calling wxFrame derivative, such as PCB_BASE_FRAME.
+ DIALOG_SET_GRID( wxFrame* aCaller, EDA_UNITS_T* aGridUnits, EDA_UNITS_T aBoardUnits,
+ wxRealPoint* aUserSize, wxPoint* aOrigin,
+ int* aFastGrid1, int* aFastGrid2, const wxArrayString& aGridChoices );
+
+private:
+ void OnResetGridOrgClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+ void OnOkClick( wxCommandEvent& event );
+ void OnInitDlg( wxInitDialogEvent& event )
+ {
+ // Call the default wxDialog handler of a wxInitDialogEvent
+ TransferDataToWindow();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+ }
+
+ EDA_UNITS_T& m_callers_grid_units;
+ EDA_UNITS_T m_callers_board_units;
+ wxRealPoint& m_callers_user_size;
+ wxPoint& m_callers_origin;
+ int& m_callers_fast_grid1;
+ int& m_callers_fast_grid2;
+
+ void setGridUnits( EDA_UNITS_T units );
+ EDA_UNITS_T getGridUnits();
+
+ void setGridSize( const wxRealPoint& grid );
+ bool getGridSize( wxRealPoint& aGrisSize );
+
+ void setGridOrigin( const wxPoint& grid );
+ bool getGridOrigin( wxPoint& aGridOrigin );
+
+ void setGridForFastSwitching( const wxArrayString& aGrids, int aGrid1, int aGrid2 );
+ void getGridForFastSwitching( int& aGrid1, int& aGrid2 );
+};
+
+
+DIALOG_SET_GRID::DIALOG_SET_GRID( wxFrame* aCaller, EDA_UNITS_T* aGridUnits, EDA_UNITS_T aBoardUnits,
+ wxRealPoint* aUserSize, wxPoint* aOrigin, int* aFastGrid1, int* aFastGrid2, const wxArrayString& aGridChoices ):
+ DIALOG_SET_GRID_BASE( aCaller ),
+ m_callers_grid_units( *aGridUnits ),
+ m_callers_board_units( aBoardUnits ),
+ m_callers_user_size( *aUserSize ),
+ m_callers_origin( *aOrigin ),
+ m_callers_fast_grid1( *aFastGrid1 ),
+ m_callers_fast_grid2( *aFastGrid2 )
+{
+ m_TextPosXUnits->SetLabel( GetUnitsLabel( m_callers_board_units ) );
+ m_TextPosYUnits->SetLabel( GetUnitsLabel( m_callers_board_units ) );
+
+ m_sdbSizerOK->SetDefault(); // set OK button as default response to 'Enter' key
+
+ setGridUnits( m_callers_grid_units );
+ setGridSize( m_callers_user_size );
+ setGridOrigin( m_callers_origin );
+ setGridForFastSwitching( aGridChoices, m_callers_fast_grid1, m_callers_fast_grid2 );
+
+ FixOSXCancelButtonIssue();
+}
+
+
+void DIALOG_SET_GRID::setGridUnits( EDA_UNITS_T aUnits )
+{
+ m_UnitGrid->SetSelection( aUnits != INCHES );
+}
+
+
+EDA_UNITS_T DIALOG_SET_GRID::getGridUnits()
+{
+ return m_UnitGrid->GetSelection() == 0 ? INCHES : MILLIMETRES;
+}
+
+
+void DIALOG_SET_GRID::setGridSize( const wxRealPoint& grid )
+{
+ wxString msg;
+
+ msg.Printf( wxT( "%.10g" ), grid.x );
+ m_OptGridSizeX->SetValue( msg );
+
+ msg.Printf( wxT( "%.10g" ), grid.y );
+ m_OptGridSizeY->SetValue( msg );
+}
+
+
+bool DIALOG_SET_GRID::getGridSize( wxRealPoint& aGrisSize )
+{
+ wxRealPoint grid;
+ m_callers_grid_units = getGridUnits();
+ double grid_unit_to_iu = m_callers_grid_units == INCHES ? IU_PER_MILS*1000 : IU_PER_MM;
+
+ wxString val = m_OptGridSizeX->GetValue();
+
+ double tmp;
+
+ if( !val.ToDouble( &tmp ) ||
+ tmp*grid_unit_to_iu < MIN_GRID_SIZE || tmp*grid_unit_to_iu > MAX_GRID_SIZE )
+ {
+ return false;
+ }
+ else
+ aGrisSize.x = tmp;
+
+ val = m_OptGridSizeY->GetValue();
+
+ if( !val.ToDouble( &tmp ) ||
+ tmp*grid_unit_to_iu < MIN_GRID_SIZE || tmp*grid_unit_to_iu > MAX_GRID_SIZE )
+ {
+ return false;
+ }
+ else
+ aGrisSize.y = tmp;
+
+ return true;
+}
+
+
+bool DIALOG_SET_GRID::getGridOrigin( wxPoint& aGridOrigin )
+{
+ double tmp;
+
+ tmp = DoubleValueFromString( g_UserUnit, m_GridOriginXCtrl->GetValue() );
+
+ // Some error checking here is a good thing.
+ if( tmp < -MAX_GRID_OFFSET || tmp > MAX_GRID_OFFSET )
+ return false;
+
+ aGridOrigin.x = KiROUND( tmp );
+
+ tmp = DoubleValueFromString( g_UserUnit, m_GridOriginYCtrl->GetValue() );
+
+ if( tmp < -MAX_GRID_OFFSET || tmp > MAX_GRID_OFFSET )
+ return false;
+
+ aGridOrigin.y = KiROUND( tmp );
+
+ return true;
+}
+
+
+void DIALOG_SET_GRID::setGridOrigin( const wxPoint& grid )
+{
+ PutValueInLocalUnits( *m_GridOriginXCtrl, grid.x );
+ PutValueInLocalUnits( *m_GridOriginYCtrl, grid.y );
+}
+
+
+void DIALOG_SET_GRID::setGridForFastSwitching( const wxArrayString& aGrids, int aGrid1, int aGrid2 )
+{
+ m_comboBoxGrid1->Append( aGrids );
+ m_comboBoxGrid2->Append( aGrids );
+
+ m_comboBoxGrid1->SetSelection( aGrid1 );
+ m_comboBoxGrid2->SetSelection( aGrid2 );
+}
+
+
+void DIALOG_SET_GRID::getGridForFastSwitching( int& aGrid1, int& aGrid2 )
+{
+ aGrid1 = m_comboBoxGrid1->GetSelection();
+ aGrid2 = m_comboBoxGrid2->GetSelection();
+}
+
+
+void DIALOG_SET_GRID::OnResetGridOrgClick( wxCommandEvent& event )
+{
+ setGridOrigin( wxPoint( 0, 0 ) );
+}
+
+
+void DIALOG_SET_GRID::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( wxID_CANCEL );
+}
+
+
+void DIALOG_SET_GRID::OnOkClick( wxCommandEvent& event )
+{
+ bool success = getGridSize( m_callers_user_size );
+
+ if( !success )
+ {
+ wxMessageBox( wxString::Format( _( "Incorrect grid size (size must be >= %.3f mm and <= %.3f mm)"),
+ MIN_GRID_SIZE/IU_PER_MM, MAX_GRID_SIZE/IU_PER_MM ) );
+ return;
+ }
+
+ success = getGridOrigin( m_callers_origin );
+
+ if( !success )
+ {
+ wxMessageBox( wxString::Format( _( "Incorrect grid origin (coordinates must be >= %.3f mm and <= %.3f mm)" ),
+ -MAX_GRID_OFFSET/IU_PER_MM, MAX_GRID_OFFSET/IU_PER_MM ) );
+ return;
+ }
+
+ getGridForFastSwitching( m_callers_fast_grid1, m_callers_fast_grid2 );
+
+ EndModal( wxID_OK );
+}
+
+
+#include <class_drawpanel.h>
+#include <wxBasePcbFrame.h>
+
+bool PCB_BASE_FRAME::InvokeDialogGrid()
+{
+ wxPoint grid_origin = GetGridOrigin();
+
+ DIALOG_SET_GRID dlg( this, &m_UserGridUnit, g_UserUnit, &m_UserGridSize,
+ &grid_origin, &m_FastGrid1, &m_FastGrid2,
+ m_gridSelectBox->GetStrings() );
+
+ int ret = dlg.ShowModal();
+
+ if( ret == wxID_OK )
+ {
+ if( GetGridOrigin() != grid_origin && IsType( FRAME_PCB ) )
+ OnModify(); // because grid origin is saved in board, show as modified
+
+ SetGridOrigin( grid_origin );
+
+ BASE_SCREEN* screen = GetScreen();
+
+ screen->AddGrid( m_UserGridSize, m_UserGridUnit, ID_POPUP_GRID_USER );
+
+ // If the user grid is the current option, recall SetGrid()
+ // to force new values put in list as current grid value
+ if( screen->GetGridCmdId() == ID_POPUP_GRID_USER )
+ screen->SetGrid( ID_POPUP_GRID_USER );
+
+ // Notify GAL
+ TOOL_MANAGER* mgr = GetToolManager();
+
+ if( mgr && IsGalCanvasActive() )
+ {
+ mgr->RunAction( "common.Control.gridPreset", true,
+ screen->GetGridCmdId() - ID_POPUP_GRID_LEVEL_1000 );
+
+ TOOL_EVENT gridOriginUpdate = COMMON_ACTIONS::gridSetOrigin.MakeEvent();
+ gridOriginUpdate.SetParameter( new VECTOR2D( grid_origin ) );
+ mgr->ProcessEvent( gridOriginUpdate );
+ }
+
+ m_canvas->Refresh();
+
+ return true;
+ }
+
+ return false;
+}
diff --git a/pcbnew/dialogs/dialog_set_grid_base.cpp b/pcbnew/dialogs/dialog_set_grid_base.cpp
new file mode 100644
index 0000000..1b4a19f
--- /dev/null
+++ b/pcbnew/dialogs/dialog_set_grid_base.cpp
@@ -0,0 +1,164 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_set_grid_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_SET_GRID_BASE::DIALOG_SET_GRID_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bUpperSizer;
+ bUpperSizer = new wxBoxSizer( wxHORIZONTAL );
+
+ wxStaticBoxSizer* sbLeftSizer;
+ sbLeftSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("User Defined Grid") ), wxVERTICAL );
+
+ wxString m_UnitGridChoices[] = { _("Inches"), _("Millimeters") };
+ int m_UnitGridNChoices = sizeof( m_UnitGridChoices ) / sizeof( wxString );
+ m_UnitGrid = new wxRadioBox( sbLeftSizer->GetStaticBox(), wxID_ANY, _("Units"), wxDefaultPosition, wxDefaultSize, m_UnitGridNChoices, m_UnitGridChoices, 1, wxRA_SPECIFY_COLS );
+ m_UnitGrid->SetSelection( 0 );
+ sbLeftSizer->Add( m_UnitGrid, 0, wxALL|wxEXPAND, 5 );
+
+ wxFlexGridSizer* fgSizer31;
+ fgSizer31 = new wxFlexGridSizer( 2, 2, 0, 0 );
+ fgSizer31->AddGrowableCol( 1 );
+ fgSizer31->SetFlexibleDirection( wxBOTH );
+ fgSizer31->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticTextSizeX = new wxStaticText( sbLeftSizer->GetStaticBox(), wxID_ANY, _("Size X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSizeX->Wrap( -1 );
+ fgSizer31->Add( m_staticTextSizeX, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OptGridSizeX = new wxTextCtrl( sbLeftSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer31->Add( m_OptGridSizeX, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+ m_staticTextSizeY = new wxStaticText( sbLeftSizer->GetStaticBox(), wxID_ANY, _("Size Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSizeY->Wrap( -1 );
+ fgSizer31->Add( m_staticTextSizeY, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_OptGridSizeY = new wxTextCtrl( sbLeftSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer31->Add( m_OptGridSizeY, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ sbLeftSizer->Add( fgSizer31, 0, wxALL|wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( sbLeftSizer, 1, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* sbRightSizer;
+ sbRightSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Origin") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgSizerGridOrigin;
+ fgSizerGridOrigin = new wxFlexGridSizer( 2, 3, 0, 0 );
+ fgSizerGridOrigin->AddGrowableCol( 1 );
+ fgSizerGridOrigin->SetFlexibleDirection( wxBOTH );
+ fgSizerGridOrigin->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticTextGridPosX = new wxStaticText( sbRightSizer->GetStaticBox(), wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextGridPosX->Wrap( -1 );
+ fgSizerGridOrigin->Add( m_staticTextGridPosX, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT|wxTOP, 5 );
+
+ m_GridOriginXCtrl = new wxTextCtrl( sbRightSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizerGridOrigin->Add( m_GridOriginXCtrl, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_TextPosXUnits = new wxStaticText( sbRightSizer->GetStaticBox(), wxID_ANY, _("Inches"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextPosXUnits->Wrap( -1 );
+ fgSizerGridOrigin->Add( m_TextPosXUnits, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxLEFT|wxTOP, 5 );
+
+ m_staticTextGridPosY = new wxStaticText( sbRightSizer->GetStaticBox(), wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextGridPosY->Wrap( -1 );
+ fgSizerGridOrigin->Add( m_staticTextGridPosY, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_GridOriginYCtrl = new wxTextCtrl( sbRightSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizerGridOrigin->Add( m_GridOriginYCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
+
+ m_TextPosYUnits = new wxStaticText( sbRightSizer->GetStaticBox(), wxID_ANY, _("Inches"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TextPosYUnits->Wrap( -1 );
+ fgSizerGridOrigin->Add( m_TextPosYUnits, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 5 );
+
+
+ sbRightSizer->Add( fgSizerGridOrigin, 0, wxALL|wxEXPAND, 5 );
+
+ m_buttonReset = new wxButton( sbRightSizer->GetStaticBox(), wxID_ANY, _("Reset Grid Origin"), wxDefaultPosition, wxDefaultSize, 0 );
+ sbRightSizer->Add( m_buttonReset, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizer4->Add( sbRightSizer, 0, wxEXPAND|wxALL, 5 );
+
+ wxStaticBoxSizer* sbSizer4;
+ sbSizer4 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Fast Switching") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer3;
+ fgSizer3 = new wxFlexGridSizer( 2, 2, 0, 0 );
+ fgSizer3->AddGrowableCol( 1 );
+ fgSizer3->SetFlexibleDirection( wxBOTH );
+ fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticTextGrid1 = new wxStaticText( sbSizer4->GetStaticBox(), wxID_ANY, _("Grid 1:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextGrid1->Wrap( -1 );
+ fgSizer3->Add( m_staticTextGrid1, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT|wxTOP, 5 );
+
+ m_comboBoxGrid1 = new wxComboBox( sbSizer4->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
+ fgSizer3->Add( m_comboBoxGrid1, 1, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+ m_staticTextGrid2 = new wxStaticText( sbSizer4->GetStaticBox(), wxID_ANY, _("Grid 2:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextGrid2->Wrap( -1 );
+ fgSizer3->Add( m_staticTextGrid2, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_comboBoxGrid2 = new wxComboBox( sbSizer4->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
+ fgSizer3->Add( m_comboBoxGrid2, 1, wxALL|wxEXPAND, 5 );
+
+
+ sbSizer4->Add( fgSizer3, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizer4->Add( sbSizer4, 1, wxALL|wxEXPAND, 5 );
+
+
+ bUpperSizer->Add( bSizer4, 1, wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bUpperSizer, 1, wxEXPAND, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bSizerMain->Add( m_sdbSizer, 0, wxALL|wxEXPAND|wxTOP, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+ bSizerMain->Fit( this );
+
+ // Connect Events
+ this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_SET_GRID_BASE::OnInitDlg ) );
+ m_buttonReset->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SET_GRID_BASE::OnResetGridOrgClick ), NULL, this );
+ m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SET_GRID_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SET_GRID_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_SET_GRID_BASE::~DIALOG_SET_GRID_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_SET_GRID_BASE::OnInitDlg ) );
+ m_buttonReset->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SET_GRID_BASE::OnResetGridOrgClick ), NULL, this );
+ m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SET_GRID_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SET_GRID_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_set_grid_base.fbp b/pcbnew/dialogs/dialog_set_grid_base.fbp
new file mode 100644
index 0000000..621682c
--- /dev/null
+++ b/pcbnew/dialogs/dialog_set_grid_base.fbp
@@ -0,0 +1,1634 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_set_grid_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_set_grid</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_SET_GRID_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Grid Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog">OnInitDlg</event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bUpperSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">User Defined Grid</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbLeftSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Inches&quot; &quot;Millimeters&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Units</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_UnitGrid</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer31</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">2</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Size X:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSizeX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptGridSizeX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Size Y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSizeY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_OptGridSizeY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer4</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Origin</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbRightSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerGridOrigin</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">2</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">X:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextGridPosX</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_GridOriginXCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inches</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextPosXUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextGridPosY</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_GridOriginYCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Inches</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TextPosYUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Reset Grid Origin</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonReset</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnResetGridOrgClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Fast Switching</property>
+ <property name="minimum_size"></property>
+ <property name="name">sbSizer4</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="parent">1</property>
+ <property name="permission">none</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer3</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">2</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Grid 1:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextGrid1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_comboBoxGrid1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxCB_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Grid 2:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextGrid2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_comboBoxGrid2</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxCB_READONLY</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_set_grid_base.h b/pcbnew/dialogs/dialog_set_grid_base.h
new file mode 100644
index 0000000..e0e1018
--- /dev/null
+++ b/pcbnew/dialogs/dialog_set_grid_base.h
@@ -0,0 +1,76 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_SET_GRID_BASE_H__
+#define __DIALOG_SET_GRID_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/radiobox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/button.h>
+#include <wx/combobox.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_SET_GRID_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_SET_GRID_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxRadioBox* m_UnitGrid;
+ wxStaticText* m_staticTextSizeX;
+ wxTextCtrl* m_OptGridSizeX;
+ wxStaticText* m_staticTextSizeY;
+ wxTextCtrl* m_OptGridSizeY;
+ wxStaticText* m_staticTextGridPosX;
+ wxTextCtrl* m_GridOriginXCtrl;
+ wxStaticText* m_TextPosXUnits;
+ wxStaticText* m_staticTextGridPosY;
+ wxTextCtrl* m_GridOriginYCtrl;
+ wxStaticText* m_TextPosYUnits;
+ wxButton* m_buttonReset;
+ wxStaticText* m_staticTextGrid1;
+ wxComboBox* m_comboBoxGrid1;
+ wxStaticText* m_staticTextGrid2;
+ wxComboBox* m_comboBoxGrid2;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnInitDlg( wxInitDialogEvent& event ) { event.Skip(); }
+ virtual void OnResetGridOrgClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_SET_GRID_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Grid Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_SET_GRID_BASE();
+
+};
+
+#endif //__DIALOG_SET_GRID_BASE_H__
diff --git a/pcbnew/dialogs/dialog_target_properties_base.cpp b/pcbnew/dialogs/dialog_target_properties_base.cpp
new file mode 100644
index 0000000..1f76596
--- /dev/null
+++ b/pcbnew/dialogs/dialog_target_properties_base.cpp
@@ -0,0 +1,99 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_target_properties_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+TARGET_PROPERTIES_DIALOG_EDITOR_BASE::TARGET_PROPERTIES_DIALOG_EDITOR_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerUpper;
+ bSizerUpper = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer;
+ fgSizer = new wxFlexGridSizer( 0, 3, 0, 0 );
+ fgSizer->AddGrowableCol( 1 );
+ fgSizer->SetFlexibleDirection( wxBOTH );
+ fgSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticTextSize = new wxStaticText( this, wxID_ANY, _("Size"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSize->Wrap( -1 );
+ fgSizer->Add( m_staticTextSize, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_TargetSizeCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer->Add( m_TargetSizeCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticTextSizeUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextSizeUnits->Wrap( -1 );
+ fgSizer->Add( m_staticTextSizeUnits, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
+
+ m_staticTextThickness = new wxStaticText( this, wxID_ANY, _("Thickness"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextThickness->Wrap( -1 );
+ fgSizer->Add( m_staticTextThickness, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_TargetThicknessCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer->Add( m_TargetThicknessCtrl, 0, wxEXPAND|wxALL, 5 );
+
+ m_staticTextThicknessUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextThicknessUnits->Wrap( -1 );
+ fgSizer->Add( m_staticTextThicknessUnits, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
+
+ m_staticTextShape = new wxStaticText( this, wxID_ANY, _("Shape"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextShape->Wrap( -1 );
+ fgSizer->Add( m_staticTextShape, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ wxString m_TargetShapeChoices[] = { _("+"), _("X") };
+ int m_TargetShapeNChoices = sizeof( m_TargetShapeChoices ) / sizeof( wxString );
+ m_TargetShape = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_TargetShapeNChoices, m_TargetShapeChoices, 0 );
+ m_TargetShape->SetSelection( 0 );
+ fgSizer->Add( m_TargetShape, 0, wxALL|wxEXPAND, 5 );
+
+
+ fgSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ bSizerUpper->Add( fgSizer, 1, wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bSizerUpper, 1, wxEXPAND, 5 );
+
+ m_staticline = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerMain->Add( m_staticline, 0, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizerButts = new wxStdDialogButtonSizer();
+ m_sdbSizerButtsOK = new wxButton( this, wxID_OK );
+ m_sdbSizerButts->AddButton( m_sdbSizerButtsOK );
+ m_sdbSizerButtsCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizerButts->AddButton( m_sdbSizerButtsCancel );
+ m_sdbSizerButts->Realize();
+
+ bSizerMain->Add( m_sdbSizerButts, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+ bSizerMain->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_sdbSizerButtsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( TARGET_PROPERTIES_DIALOG_EDITOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerButtsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( TARGET_PROPERTIES_DIALOG_EDITOR_BASE::OnOkClick ), NULL, this );
+}
+
+TARGET_PROPERTIES_DIALOG_EDITOR_BASE::~TARGET_PROPERTIES_DIALOG_EDITOR_BASE()
+{
+ // Disconnect Events
+ m_sdbSizerButtsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( TARGET_PROPERTIES_DIALOG_EDITOR_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizerButtsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( TARGET_PROPERTIES_DIALOG_EDITOR_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_target_properties_base.fbp b/pcbnew/dialogs/dialog_target_properties_base.fbp
new file mode 100644
index 0000000..ec4795c
--- /dev/null
+++ b/pcbnew/dialogs/dialog_target_properties_base.fbp
@@ -0,0 +1,930 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_target_properties_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_target_properties_base</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">TARGET_PROPERTIES_DIALOG_EDITOR_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Target Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerUpper</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSize</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TargetSizeCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextSizeUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Thickness</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextThickness</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TargetThicknessCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextThicknessUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Shape</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextShape</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;+&quot; &quot;X&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TargetShape</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizerButts</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_target_properties_base.h b/pcbnew/dialogs/dialog_target_properties_base.h
new file mode 100644
index 0000000..60cd64b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_target_properties_base.h
@@ -0,0 +1,66 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Mar 9 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_TARGET_PROPERTIES_BASE_H__
+#define __DIALOG_TARGET_PROPERTIES_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/choice.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class TARGET_PROPERTIES_DIALOG_EDITOR_BASE
+///////////////////////////////////////////////////////////////////////////////
+class TARGET_PROPERTIES_DIALOG_EDITOR_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticTextSize;
+ wxTextCtrl* m_TargetSizeCtrl;
+ wxStaticText* m_staticTextSizeUnits;
+ wxStaticText* m_staticTextThickness;
+ wxTextCtrl* m_TargetThicknessCtrl;
+ wxStaticText* m_staticTextThicknessUnits;
+ wxStaticText* m_staticTextShape;
+ wxChoice* m_TargetShape;
+ wxStaticLine* m_staticline;
+ wxStdDialogButtonSizer* m_sdbSizerButts;
+ wxButton* m_sdbSizerButtsOK;
+ wxButton* m_sdbSizerButtsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ TARGET_PROPERTIES_DIALOG_EDITOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Target Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~TARGET_PROPERTIES_DIALOG_EDITOR_BASE();
+
+};
+
+#endif //__DIALOG_TARGET_PROPERTIES_BASE_H__
diff --git a/pcbnew/dialogs/dialog_track_via_properties.cpp b/pcbnew/dialogs/dialog_track_via_properties.cpp
new file mode 100644
index 0000000..58b6e2d
--- /dev/null
+++ b/pcbnew/dialogs/dialog_track_via_properties.cpp
@@ -0,0 +1,364 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <dialogs/dialog_track_via_properties.h>
+#include <class_pcb_layer_box_selector.h>
+#include <tools/selection_tool.h>
+#include <class_track.h>
+#include <wxPcbStruct.h>
+#include <confirm.h>
+
+DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParent, const SELECTION& aItems ) :
+ DIALOG_TRACK_VIA_PROPERTIES_BASE( aParent ), m_items( aItems ),
+ m_trackStartX( aParent, m_TrackStartXCtrl, m_TrackStartXUnit ),
+ m_trackStartY( aParent, m_TrackStartYCtrl, m_TrackStartYUnit ),
+ m_trackEndX( aParent, m_TrackEndXCtrl, m_TrackEndXUnit ),
+ m_trackEndY( aParent, m_TrackEndYCtrl, m_TrackEndYUnit ),
+ m_trackWidth( aParent, m_TrackWidthCtrl, m_TrackWidthUnit ),
+ m_viaX( aParent, m_ViaXCtrl, m_ViaXUnit ), m_viaY( aParent, m_ViaYCtrl, m_ViaYUnit ),
+ m_viaDiameter( aParent, m_ViaDiameterCtrl, m_ViaDiameterUnit ),
+ m_viaDrill( aParent, m_ViaDrillCtrl, m_ViaDrillUnit ),
+ m_tracks( false ), m_vias( false )
+{
+ assert( !m_items.Empty() );
+
+ boost::optional<int> trackStartX, trackStartY, trackEndX, trackEndY, trackWidth;
+ boost::optional<LAYER_ID> trackLayer;
+ boost::optional<int> viaX, viaY, viaDiameter, viaDrill;
+
+ // Look for values that are common for every item that is selected
+ for( int i = 0; i < m_items.Size(); ++i )
+ {
+ const BOARD_ITEM* item = m_items.Item<BOARD_ITEM>( i );
+
+ switch( item->Type() )
+ {
+ case PCB_TRACE_T:
+ {
+ const TRACK* t = static_cast<const TRACK*>( item );
+
+ if( !m_tracks ) // first track in the list
+ {
+ trackStartX = t->GetStart().x;
+ trackStartY = t->GetStart().y;
+ trackEndX = t->GetEnd().x;
+ trackEndY = t->GetEnd().y;
+ trackWidth = t->GetWidth();
+ trackLayer = t->GetLayer();
+ m_tracks = true;
+ }
+ else // check if values are the same for every selected track
+ {
+ if( trackStartX && *trackStartX != t->GetStart().x )
+ trackStartX = boost::none;
+
+ if( trackStartY && *trackStartY != t->GetStart().y )
+ trackStartY = boost::none;
+
+ if( trackEndX && *trackEndX != t->GetEnd().x )
+ trackEndX = boost::none;
+
+ if( trackEndY && *trackEndY != t->GetEnd().y )
+ trackEndY = boost::none;
+
+ if( trackWidth && *trackWidth != t->GetWidth() )
+ trackWidth = boost::none;
+
+ if( trackLayer && *trackLayer != t->GetLayer() )
+ trackLayer = boost::none;
+ }
+ break;
+ }
+
+ case PCB_VIA_T:
+ {
+ const VIA* v = static_cast<const VIA*>( item );
+
+ if( !m_vias ) // first via in the list
+ {
+ viaX = v->GetPosition().x;
+ viaY = v->GetPosition().y;
+ viaDiameter = v->GetWidth();
+ viaDrill = v->GetDrillValue();
+ m_vias = true;
+ }
+ else // check if values are the same for every selected via
+ {
+ if( viaX && *viaX != v->GetPosition().x )
+ viaX = boost::none;
+
+ if( viaY && *viaY != v->GetPosition().y )
+ viaY = boost::none;
+
+ if( viaDiameter && *viaDiameter != v->GetWidth() )
+ viaDiameter = boost::none;
+
+ if( viaDrill && *viaDrill != v->GetDrillValue() )
+ viaDrill = boost::none;
+ }
+ break;
+ }
+
+ default:
+ assert( false );
+ break;
+ }
+ }
+
+ assert( m_tracks || m_vias );
+
+ if( m_vias )
+ {
+ setCommonVal( viaX, m_ViaXCtrl, m_viaX );
+ setCommonVal( viaY, m_ViaYCtrl, m_viaY );
+ setCommonVal( viaDiameter, m_ViaDiameterCtrl, m_viaDiameter );
+ setCommonVal( viaDrill, m_ViaDrillCtrl, m_viaDrill );
+ m_ViaDiameterCtrl->SetFocus();
+ }
+ else
+ {
+ m_MainSizer->Hide( m_sbViaSizer, true );
+ }
+
+ if( m_tracks )
+ {
+ setCommonVal( trackStartX, m_TrackStartXCtrl, m_trackStartX );
+ setCommonVal( trackStartY, m_TrackStartYCtrl, m_trackStartY );
+ setCommonVal( trackEndX, m_TrackEndXCtrl, m_trackEndX );
+ setCommonVal( trackEndY, m_TrackEndYCtrl, m_trackEndY );
+ setCommonVal( trackWidth, m_TrackWidthCtrl, m_trackWidth );
+
+ m_TrackLayerCtrl->SetLayersHotkeys( false );
+ m_TrackLayerCtrl->SetLayerSet( LSET::AllNonCuMask() );
+ m_TrackLayerCtrl->SetBoardFrame( aParent );
+ m_TrackLayerCtrl->Resync();
+
+ if( trackLayer )
+ m_TrackLayerCtrl->SetLayerSelection( *trackLayer );
+
+ m_TrackWidthCtrl->SetFocus();
+ }
+ else
+ {
+ m_MainSizer->Hide( m_sbTrackSizer, true );
+ }
+
+ m_StdButtonsOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+
+ // Pressing ENTER when any of the text input fields is active applies changes
+ Connect( wxEVT_TEXT_ENTER, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES::onOkClick ), NULL, this );
+}
+
+
+bool DIALOG_TRACK_VIA_PROPERTIES::Apply()
+{
+ if( !check() )
+ return false;
+
+ for( int i = 0; i < m_items.Size(); ++i )
+ {
+ BOARD_ITEM* item = m_items.Item<BOARD_ITEM>( i );
+
+ switch( item->Type() )
+ {
+ case PCB_TRACE_T:
+ {
+ assert( m_tracks );
+ TRACK* t = static_cast<TRACK*>( item );
+
+ if( m_trackStartX.Valid() || m_trackStartY.Valid() )
+ {
+ wxPoint start = t->GetStart();
+
+ if( m_trackStartX.Valid() )
+ start.x = m_trackStartX.GetValue();
+
+ if( m_trackStartY.Valid() )
+ start.y = m_trackStartY.GetValue();
+
+ t->SetStart( start );
+ }
+
+ if( m_trackEndX.Valid() || m_trackEndY.Valid() )
+ {
+ wxPoint end = t->GetEnd();
+
+ if( m_trackEndX.Valid() )
+ end.x = m_trackEndX.GetValue();
+
+ if( m_trackEndY.Valid() )
+ end.y = m_trackEndY.GetValue();
+
+ t->SetEnd( end );
+ }
+
+ if( m_trackNetclass->IsChecked() )
+ {
+ t->SetWidth( t->GetNetClass()->GetTrackWidth() );
+ }
+ else if( m_trackWidth.Valid() )
+ {
+ t->SetWidth( m_trackWidth.GetValue() );
+ }
+
+ LAYER_NUM layer = m_TrackLayerCtrl->GetLayerSelection();
+
+ if( layer != UNDEFINED_LAYER )
+ t->SetLayer( (LAYER_ID) layer );
+
+ break;
+ }
+
+ case PCB_VIA_T:
+ {
+ assert( m_vias );
+
+ VIA* v = static_cast<VIA*>( item );
+
+ if( m_viaX.Valid() || m_viaY.Valid() )
+ {
+ wxPoint pos = v->GetPosition();
+
+ if( m_viaX.Valid() )
+ pos.x = m_viaX.GetValue();
+
+ if( m_viaY.Valid() )
+ pos.y = m_viaY.GetValue();
+
+ v->SetPosition( pos );
+ }
+
+ if( m_viaNetclass->IsChecked() )
+ {
+ v->SetWidth( v->GetNetClass()->GetViaDiameter() );
+ v->SetDrill( v->GetNetClass()->GetViaDrill() );
+ }
+ else
+ {
+ if( m_viaDiameter.Valid() )
+ v->SetWidth( m_viaDiameter.GetValue() );
+
+ if( m_viaDrill.Valid() )
+ v->SetDrill( m_viaDrill.GetValue() );
+ }
+
+ break;
+ }
+
+ default:
+ assert( false );
+ break;
+ }
+ }
+
+ return true;
+}
+
+
+void DIALOG_TRACK_VIA_PROPERTIES::onClose( wxCloseEvent& aEvent )
+{
+ EndModal( 0 );
+}
+
+
+void DIALOG_TRACK_VIA_PROPERTIES::onTrackNetclassCheck( wxCommandEvent& aEvent )
+{
+ bool enableNC = aEvent.IsChecked();
+
+ m_TrackWidthLabel->Enable( !enableNC );
+ m_TrackWidthCtrl->Enable( !enableNC );
+ m_TrackWidthUnit->Enable( !enableNC );
+}
+
+
+void DIALOG_TRACK_VIA_PROPERTIES::onViaNetclassCheck( wxCommandEvent& aEvent )
+{
+ bool enableNC = aEvent.IsChecked();
+
+ m_ViaDiameterLabel->Enable( !enableNC );
+ m_ViaDiameterCtrl->Enable( !enableNC );
+ m_ViaDiameterUnit->Enable( !enableNC );
+
+ m_ViaDrillLabel->Enable( !enableNC );
+ m_ViaDrillCtrl->Enable( !enableNC );
+ m_ViaDrillUnit->Enable( !enableNC );
+}
+
+
+void DIALOG_TRACK_VIA_PROPERTIES::onCancelClick( wxCommandEvent& aEvent )
+{
+ EndModal( 0 );
+}
+
+
+void DIALOG_TRACK_VIA_PROPERTIES::onOkClick( wxCommandEvent& aEvent )
+{
+ if( check() )
+ EndModal( 1 );
+}
+
+
+bool DIALOG_TRACK_VIA_PROPERTIES::check() const
+{
+ bool trackNetclass = m_trackNetclass->IsChecked();
+ bool viaNetclass = m_trackNetclass->IsChecked();
+
+ if( m_tracks && !trackNetclass && m_trackWidth.Valid() && m_trackWidth.GetValue() <= 0 )
+ {
+ DisplayError( GetParent(), _( "Invalid track width" ) );
+ m_TrackWidthCtrl->SetFocus();
+ return false;
+ }
+
+ if( m_vias && !viaNetclass )
+ {
+ if( m_viaDiameter.Valid() && m_viaDiameter.GetValue() <= 0 )
+ {
+ DisplayError( GetParent(), _( "Invalid via diameter" ) );
+ m_ViaDiameterCtrl->SetFocus();
+ return false;
+ }
+
+ if( m_viaDrill.Valid() && m_viaDrill.GetValue() <= 0 )
+ {
+ DisplayError( GetParent(), _( "Invalid via drill size" ) );
+ m_ViaDrillCtrl->SetFocus();
+ return false;
+ }
+
+ if( m_viaDiameter.Valid() && m_viaDrill.Valid() && m_viaDiameter.GetValue() <= m_viaDrill.GetValue() )
+ {
+ DisplayError( GetParent(), _( "Via drill size has to be smaller than via diameter" ) );
+ m_ViaDrillCtrl->SetFocus();
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/pcbnew/dialogs/dialog_track_via_properties.h b/pcbnew/dialogs/dialog_track_via_properties.h
new file mode 100644
index 0000000..08fb945
--- /dev/null
+++ b/pcbnew/dialogs/dialog_track_via_properties.h
@@ -0,0 +1,76 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <dialogs/dialog_track_via_properties_base.h>
+#include <wx_unit_binder.h>
+#include <boost/optional.hpp>
+#include <layers_id_colors_and_visibility.h>
+
+struct SELECTION;
+class PCB_BASE_FRAME;
+
+class DIALOG_TRACK_VIA_PROPERTIES : public DIALOG_TRACK_VIA_PROPERTIES_BASE
+{
+public:
+ DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParent, const SELECTION& aItems );
+
+ ///> Applies values from the dialog to the selected items.
+ bool Apply();
+
+private:
+ void onClose( wxCloseEvent& aEvent );
+ void onTrackNetclassCheck( wxCommandEvent& aEvent );
+ void onViaNetclassCheck( wxCommandEvent& aEvent );
+ void onCancelClick( wxCommandEvent& aEvent );
+ void onOkClick( wxCommandEvent& aEvent );
+
+ ///> Checks if the dialog values are correct.
+ bool check() const;
+
+ ///> Sets wxTextCtrl to the value stored in boost::optional<T> or "<...>" if it is not available.
+ template<typename T>
+ void setCommonVal( const boost::optional<T>& aVal, wxTextCtrl* aTxtCtrl, WX_UNIT_BINDER& aBinder )
+ {
+ if( aVal )
+ aBinder.SetValue( *aVal );
+ else
+ aTxtCtrl->SetValue( "<...>" );
+ }
+
+ ///> Selected items to be modified.
+ const SELECTION& m_items;
+
+ WX_UNIT_BINDER m_trackStartX, m_trackStartY;
+ WX_UNIT_BINDER m_trackEndX, m_trackEndY;
+ WX_UNIT_BINDER m_trackWidth;
+
+ WX_UNIT_BINDER m_viaX, m_viaY;
+ WX_UNIT_BINDER m_viaDiameter, m_viaDrill;
+
+ ///> Flag that determines if the dialog displays track properties.
+ bool m_tracks;
+
+ ///> Flag that determines if the dialog displays via properties.
+ bool m_vias;
+};
diff --git a/pcbnew/dialogs/dialog_track_via_properties_base.cpp b/pcbnew/dialogs/dialog_track_via_properties_base.cpp
new file mode 100644
index 0000000..b5f7e91
--- /dev/null
+++ b/pcbnew/dialogs/dialog_track_via_properties_base.cpp
@@ -0,0 +1,231 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "class_pcb_layer_box_selector.h"
+
+#include "dialog_track_via_properties_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_TRACK_VIA_PROPERTIES_BASE::DIALOG_TRACK_VIA_PROPERTIES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ m_MainSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_sbTrackSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Tracks") ), wxHORIZONTAL );
+
+ wxFlexGridSizer* fgTrackLeftGridSizer;
+ fgTrackLeftGridSizer = new wxFlexGridSizer( 4, 3, 5, 5 );
+ fgTrackLeftGridSizer->SetFlexibleDirection( wxBOTH );
+ fgTrackLeftGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_TrackStartXLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Start point X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackStartXLabel->Wrap( -1 );
+ fgTrackLeftGridSizer->Add( m_TrackStartXLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_TrackStartXCtrl = new wxTextCtrl( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgTrackLeftGridSizer->Add( m_TrackStartXCtrl, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 );
+
+ m_TrackStartXUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackStartXUnit->Wrap( -1 );
+ fgTrackLeftGridSizer->Add( m_TrackStartXUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_TrackStartYLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Start point Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackStartYLabel->Wrap( -1 );
+ fgTrackLeftGridSizer->Add( m_TrackStartYLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_TrackStartYCtrl = new wxTextCtrl( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgTrackLeftGridSizer->Add( m_TrackStartYCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+ m_TrackStartYUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackStartYUnit->Wrap( -1 );
+ fgTrackLeftGridSizer->Add( m_TrackStartYUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_TrackEndXLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("End point X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackEndXLabel->Wrap( -1 );
+ fgTrackLeftGridSizer->Add( m_TrackEndXLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_TrackEndXCtrl = new wxTextCtrl( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgTrackLeftGridSizer->Add( m_TrackEndXCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+ m_TrackEndXUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackEndXUnit->Wrap( -1 );
+ fgTrackLeftGridSizer->Add( m_TrackEndXUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_TrackEndYLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("End point Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackEndYLabel->Wrap( -1 );
+ fgTrackLeftGridSizer->Add( m_TrackEndYLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_TrackEndYCtrl = new wxTextCtrl( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgTrackLeftGridSizer->Add( m_TrackEndYCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+ m_TrackEndYUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackEndYUnit->Wrap( -1 );
+ fgTrackLeftGridSizer->Add( m_TrackEndYUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ m_sbTrackSizer->Add( fgTrackLeftGridSizer, 1, wxEXPAND, 5 );
+
+ m_trackStaticLine = new wxStaticLine( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
+ m_sbTrackSizer->Add( m_trackStaticLine, 0, wxEXPAND | wxALL, 5 );
+
+ wxFlexGridSizer* fgTrackRightSizer;
+ fgTrackRightSizer = new wxFlexGridSizer( 0, 3, 5, 5 );
+ fgTrackRightSizer->SetFlexibleDirection( wxBOTH );
+ fgTrackRightSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_TrackWidthLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackWidthLabel->Wrap( -1 );
+ fgTrackRightSizer->Add( m_TrackWidthLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT, 5 );
+
+ m_TrackWidthCtrl = new wxTextCtrl( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgTrackRightSizer->Add( m_TrackWidthCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+ m_TrackWidthUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackWidthUnit->Wrap( -1 );
+ fgTrackRightSizer->Add( m_TrackWidthUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ fgTrackRightSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_trackNetclass = new wxCheckBox( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Use net class width"), wxDefaultPosition, wxDefaultSize, 0 );
+ fgTrackRightSizer->Add( m_trackNetclass, 0, wxBOTTOM|wxTOP, 5 );
+
+
+ fgTrackRightSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_TrackLayerLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_TrackLayerLabel->Wrap( -1 );
+ fgTrackRightSizer->Add( m_TrackLayerLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_TrackLayerCtrl = new PCB_LAYER_BOX_SELECTOR( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ fgTrackRightSizer->Add( m_TrackLayerCtrl, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ fgTrackRightSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ m_sbTrackSizer->Add( fgTrackRightSizer, 0, wxEXPAND, 5 );
+
+
+ m_MainSizer->Add( m_sbTrackSizer, 0, wxALL|wxEXPAND, 5 );
+
+ m_sbViaSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Vias") ), wxHORIZONTAL );
+
+ wxFlexGridSizer* fgViaLeftSizer;
+ fgViaLeftSizer = new wxFlexGridSizer( 2, 3, 5, 5 );
+ fgViaLeftSizer->SetFlexibleDirection( wxBOTH );
+ fgViaLeftSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_ViaXLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Position X:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaXLabel->Wrap( -1 );
+ fgViaLeftSizer->Add( m_ViaXLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_ViaXCtrl = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgViaLeftSizer->Add( m_ViaXCtrl, 0, wxEXPAND, 5 );
+
+ m_ViaXUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaXUnit->Wrap( -1 );
+ fgViaLeftSizer->Add( m_ViaXUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_ViaYLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Position Y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaYLabel->Wrap( -1 );
+ fgViaLeftSizer->Add( m_ViaYLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_ViaYCtrl = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgViaLeftSizer->Add( m_ViaYCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+ m_ViaYUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaYUnit->Wrap( -1 );
+ fgViaLeftSizer->Add( m_ViaYUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ m_sbViaSizer->Add( fgViaLeftSizer, 1, wxEXPAND, 5 );
+
+ m_viaStaticLine = new wxStaticLine( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
+ m_sbViaSizer->Add( m_viaStaticLine, 0, wxEXPAND | wxALL, 5 );
+
+ wxFlexGridSizer* fgViaRightSizer;
+ fgViaRightSizer = new wxFlexGridSizer( 0, 3, 5, 5 );
+ fgViaRightSizer->SetFlexibleDirection( wxBOTH );
+ fgViaRightSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_ViaDiameterLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Diameter:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaDiameterLabel->Wrap( -1 );
+ fgViaRightSizer->Add( m_ViaDiameterLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_ViaDiameterCtrl = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgViaRightSizer->Add( m_ViaDiameterCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+ m_ViaDiameterUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaDiameterUnit->Wrap( -1 );
+ fgViaRightSizer->Add( m_ViaDiameterUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_ViaDrillLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Drill:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaDrillLabel->Wrap( -1 );
+ fgViaRightSizer->Add( m_ViaDrillLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
+
+ m_ViaDrillCtrl = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgViaRightSizer->Add( m_ViaDrillCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+ m_ViaDrillUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ViaDrillUnit->Wrap( -1 );
+ fgViaRightSizer->Add( m_ViaDrillUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ fgViaRightSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_viaNetclass = new wxCheckBox( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Use net class size"), wxDefaultPosition, wxDefaultSize, 0 );
+ fgViaRightSizer->Add( m_viaNetclass, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxTOP, 5 );
+
+
+ fgViaRightSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+
+ m_sbViaSizer->Add( fgViaRightSizer, 1, wxEXPAND, 5 );
+
+
+ m_MainSizer->Add( m_sbViaSizer, 0, wxALL|wxEXPAND, 5 );
+
+
+ m_MainSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_StdButtons = new wxStdDialogButtonSizer();
+ m_StdButtonsOK = new wxButton( this, wxID_OK );
+ m_StdButtons->AddButton( m_StdButtonsOK );
+ m_StdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_StdButtons->AddButton( m_StdButtonsCancel );
+ m_StdButtons->Realize();
+
+ m_MainSizer->Add( m_StdButtons, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( m_MainSizer );
+ this->Layout();
+ m_MainSizer->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onClose ) );
+ m_trackNetclass->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTrackNetclassCheck ), NULL, this );
+ m_viaNetclass->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaNetclassCheck ), NULL, this );
+ m_StdButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onCancelClick ), NULL, this );
+ m_StdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onOkClick ), NULL, this );
+}
+
+DIALOG_TRACK_VIA_PROPERTIES_BASE::~DIALOG_TRACK_VIA_PROPERTIES_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onClose ) );
+ m_trackNetclass->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTrackNetclassCheck ), NULL, this );
+ m_viaNetclass->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaNetclassCheck ), NULL, this );
+ m_StdButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onCancelClick ), NULL, this );
+ m_StdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_track_via_properties_base.fbp b/pcbnew/dialogs/dialog_track_via_properties_base.fbp
new file mode 100644
index 0000000..dfae05a
--- /dev/null
+++ b/pcbnew/dialogs/dialog_track_via_properties_base.fbp
@@ -0,0 +1,3112 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_track_via_properties_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_TRACK_VIA_PROPERTIES_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_TRACK_VIA_PROPERTIES_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Track &amp; Via Properties</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">onClose</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_MainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">protected</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Tracks</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sbTrackSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="parent">1</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="0">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">5</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgTrackLeftGridSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">4</property>
+ <property name="vgap">5</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Start point X:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackStartXLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackStartXCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackStartXUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Start point Y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackStartYLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackStartYCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackStartYUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">End point X:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackEndXLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackEndXCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackEndXUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">End point Y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackEndYLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackEndYCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackEndYUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_trackStaticLine</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_VERTICAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">5</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgTrackRightSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">5</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackWidthLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackWidthCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackWidthUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Use net class width</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_trackNetclass</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">onTrackNetclassCheck</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layer:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackLayerLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxBitmapComboBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_TrackLayerCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">PCB_LAYER_BOX_SELECTOR; class_pcb_layer_box_selector.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="0">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBoxSizer" expanded="1">
+ <property name="id">wxID_ANY</property>
+ <property name="label">Vias</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sbViaSizer</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="parent">1</property>
+ <property name="permission">protected</property>
+ <event name="OnUpdateUI"></event>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">5</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgViaLeftSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">2</property>
+ <property name="vgap">5</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Position X:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaXLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaXCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaXUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Position Y:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaYLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaYCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaYUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_viaStaticLine</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_VERTICAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">5</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgViaRightSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">5</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Diameter:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaDiameterLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaDiameterCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaDiameterUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Drill:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaDrillLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaDrillCtrl</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_ViaDrillUnit</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Use net class size</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_viaNetclass</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">onViaNetclassCheck</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_StdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">onCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">onOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_track_via_properties_base.h b/pcbnew/dialogs/dialog_track_via_properties_base.h
new file mode 100644
index 0000000..fb23b8e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_track_via_properties_base.h
@@ -0,0 +1,99 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_TRACK_VIA_PROPERTIES_BASE_H__
+#define __DIALOG_TRACK_VIA_PROPERTIES_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class PCB_LAYER_BOX_SELECTOR;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/checkbox.h>
+#include <wx/bmpcbox.h>
+#include <wx/statbox.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_TRACK_VIA_PROPERTIES_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_TRACK_VIA_PROPERTIES_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxBoxSizer* m_MainSizer;
+ wxStaticBoxSizer* m_sbTrackSizer;
+ wxStaticText* m_TrackStartXLabel;
+ wxTextCtrl* m_TrackStartXCtrl;
+ wxStaticText* m_TrackStartXUnit;
+ wxStaticText* m_TrackStartYLabel;
+ wxTextCtrl* m_TrackStartYCtrl;
+ wxStaticText* m_TrackStartYUnit;
+ wxStaticText* m_TrackEndXLabel;
+ wxTextCtrl* m_TrackEndXCtrl;
+ wxStaticText* m_TrackEndXUnit;
+ wxStaticText* m_TrackEndYLabel;
+ wxTextCtrl* m_TrackEndYCtrl;
+ wxStaticText* m_TrackEndYUnit;
+ wxStaticLine* m_trackStaticLine;
+ wxStaticText* m_TrackWidthLabel;
+ wxTextCtrl* m_TrackWidthCtrl;
+ wxStaticText* m_TrackWidthUnit;
+ wxCheckBox* m_trackNetclass;
+ wxStaticText* m_TrackLayerLabel;
+ PCB_LAYER_BOX_SELECTOR* m_TrackLayerCtrl;
+ wxStaticBoxSizer* m_sbViaSizer;
+ wxStaticText* m_ViaXLabel;
+ wxTextCtrl* m_ViaXCtrl;
+ wxStaticText* m_ViaXUnit;
+ wxStaticText* m_ViaYLabel;
+ wxTextCtrl* m_ViaYCtrl;
+ wxStaticText* m_ViaYUnit;
+ wxStaticLine* m_viaStaticLine;
+ wxStaticText* m_ViaDiameterLabel;
+ wxTextCtrl* m_ViaDiameterCtrl;
+ wxStaticText* m_ViaDiameterUnit;
+ wxStaticText* m_ViaDrillLabel;
+ wxTextCtrl* m_ViaDrillCtrl;
+ wxStaticText* m_ViaDrillUnit;
+ wxCheckBox* m_viaNetclass;
+ wxStdDialogButtonSizer* m_StdButtons;
+ wxButton* m_StdButtonsOK;
+ wxButton* m_StdButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void onClose( wxCloseEvent& event ) { event.Skip(); }
+ virtual void onTrackNetclassCheck( wxCommandEvent& event ) { event.Skip(); }
+ virtual void onViaNetclassCheck( wxCommandEvent& event ) { event.Skip(); }
+ virtual void onCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void onOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_TRACK_VIA_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Track & Via Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU );
+ ~DIALOG_TRACK_VIA_PROPERTIES_BASE();
+
+};
+
+#endif //__DIALOG_TRACK_VIA_PROPERTIES_BASE_H__
diff --git a/pcbnew/dialogs/dialog_track_via_size.cpp b/pcbnew/dialogs/dialog_track_via_size.cpp
new file mode 100644
index 0000000..9264d32
--- /dev/null
+++ b/pcbnew/dialogs/dialog_track_via_size.cpp
@@ -0,0 +1,114 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2014 CERN
+ * Author: Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.or/licenses/>.
+ */
+
+/**
+ * Push and Shove router track width and via size dialog.
+ */
+
+#include "dialog_track_via_size.h"
+#include <base_units.h>
+#include <confirm.h>
+#include <boost/optional.hpp>
+
+#include "class_board_design_settings.h"
+
+DIALOG_TRACK_VIA_SIZE::DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SETTINGS& aSettings ) :
+ DIALOG_TRACK_VIA_SIZE_BASE( aParent ),
+ m_trackWidth( aParent, m_trackWidthText, m_trackWidthLabel ),
+ m_viaDiameter( aParent, m_viaDiameterText, m_viaDiameterLabel ),
+ m_viaDrill( aParent, m_viaDrillText, m_viaDrillLabel ),
+ m_settings( aSettings )
+{
+ // Load router settings to dialog fields
+ m_trackWidth.SetValue( m_settings.GetCustomTrackWidth() );
+ m_viaDiameter.SetValue( m_settings.GetCustomViaSize() );
+ m_viaDrill.SetValue( m_settings.GetCustomViaDrill() );
+
+ m_trackWidthText->SetFocus();
+ m_trackWidthText->SetSelection( -1, -1 );
+ m_stdButtonsOK->SetDefault();
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+
+ // Pressing ENTER when any of the text input fields is active applies changes
+ Connect( wxEVT_TEXT_ENTER, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE::onOkClick ), NULL, this );
+}
+
+
+bool DIALOG_TRACK_VIA_SIZE::check()
+{
+ if( m_trackWidth.GetValue() <= 0 )
+ {
+ DisplayError( GetParent(), _( "Invalid track width" ) );
+ m_trackWidthText->SetFocus();
+ return false;
+ }
+
+ if( m_viaDiameter.GetValue() <= 0 )
+ {
+ DisplayError( GetParent(), _( "Invalid via diameter" ) );
+ m_viaDiameterText->SetFocus();
+ return false;
+ }
+
+ if( m_viaDrill.GetValue() <= 0 )
+ {
+ DisplayError( GetParent(), _( "Invalid via drill size" ) );
+ m_viaDrillText->SetFocus();
+ return false;
+ }
+
+ if( m_viaDrill.GetValue() >= m_viaDiameter.GetValue() )
+ {
+ DisplayError( GetParent(), _( "Via drill size has to be smaller than via diameter" ) );
+ m_viaDrillText->SetFocus();
+ return false;
+ }
+
+ return true;
+}
+
+
+void DIALOG_TRACK_VIA_SIZE::onClose( wxCloseEvent& aEvent )
+{
+ EndModal( 0 );
+}
+
+
+void DIALOG_TRACK_VIA_SIZE::onOkClick( wxCommandEvent& aEvent )
+{
+ if( check() )
+ {
+ // Store dialog values to the router settings
+ m_settings.SetCustomTrackWidth( m_trackWidth.GetValue() );
+ m_settings.SetCustomViaSize( m_viaDiameter.GetValue() );
+ m_settings.SetCustomViaDrill( m_viaDrill.GetValue() );
+ EndModal( 1 );
+ }
+}
+
+
+void DIALOG_TRACK_VIA_SIZE::onCancelClick( wxCommandEvent& aEvent )
+{
+ EndModal( 0 );
+}
diff --git a/pcbnew/dialogs/dialog_track_via_size.h b/pcbnew/dialogs/dialog_track_via_size.h
new file mode 100644
index 0000000..b84d77f
--- /dev/null
+++ b/pcbnew/dialogs/dialog_track_via_size.h
@@ -0,0 +1,58 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2014 CERN
+ * Author: Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.or/licenses/>.
+ */
+
+/**
+ * Custom track width and via size dialog.
+ */
+
+#ifndef __dialog_track_via_size__
+#define __dialog_track_via_size__
+
+#include <wx_unit_binder.h>
+
+#include "dialog_track_via_size_base.h"
+
+class BOARD_DESIGN_SETTINGS;
+
+/** Implementing DIALOG_TRACK_VIA_SIZE_BASE */
+class DIALOG_TRACK_VIA_SIZE : public DIALOG_TRACK_VIA_SIZE_BASE
+{
+public:
+ /** Constructor */
+ DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, BOARD_DESIGN_SETTINGS& aSettings );
+
+protected:
+ WX_UNIT_BINDER m_trackWidth;
+ WX_UNIT_BINDER m_viaDiameter;
+ WX_UNIT_BINDER m_viaDrill;
+
+ // Routings settings that are modified by the dialog.
+ BOARD_DESIGN_SETTINGS& m_settings;
+
+ ///> Checks if values given in the dialog are sensible.
+ bool check();
+
+ // Handlers for DIALOG_TRACK_VIA_SIZE_BASE events.
+ void onClose( wxCloseEvent& aEvent );
+ void onOkClick( wxCommandEvent& aEvent );
+ void onCancelClick( wxCommandEvent& aEvent );
+};
+
+#endif // __dialog_track_via_size__
diff --git a/pcbnew/dialogs/dialog_track_via_size_base.cpp b/pcbnew/dialogs/dialog_track_via_size_base.cpp
new file mode 100644
index 0000000..4e8a8fa
--- /dev/null
+++ b/pcbnew/dialogs/dialog_track_via_size_base.cpp
@@ -0,0 +1,92 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_track_via_size_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_TRACK_VIA_SIZE_BASE::DIALOG_TRACK_VIA_SIZE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bSizes;
+ bSizes = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer1;
+ fgSizer1 = new wxFlexGridSizer( 0, 3, 0, 0 );
+ fgSizer1->AddGrowableCol( 1 );
+ fgSizer1->SetFlexibleDirection( wxBOTH );
+ fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText3 = new wxStaticText( this, wxID_ANY, _("Track width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ fgSizer1->Add( m_staticText3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_trackWidthText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer1->Add( m_trackWidthText, 1, wxALL|wxEXPAND, 5 );
+
+ m_trackWidthLabel = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_trackWidthLabel->Wrap( -1 );
+ fgSizer1->Add( m_trackWidthLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_staticText5 = new wxStaticText( this, wxID_ANY, _("Via diameter:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText5->Wrap( -1 );
+ fgSizer1->Add( m_staticText5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_viaDiameterText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer1->Add( m_viaDiameterText, 1, wxALL|wxEXPAND, 5 );
+
+ m_viaDiameterLabel = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_viaDiameterLabel->Wrap( -1 );
+ fgSizer1->Add( m_viaDiameterLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_staticText7 = new wxStaticText( this, wxID_ANY, _("Via drill:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText7->Wrap( -1 );
+ fgSizer1->Add( m_staticText7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_viaDrillText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer1->Add( m_viaDrillText, 1, wxALL|wxEXPAND, 5 );
+
+ m_viaDrillLabel = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_viaDrillLabel->Wrap( -1 );
+ fgSizer1->Add( m_viaDrillLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bSizes->Add( fgSizer1, 1, wxEXPAND|wxALL, 5 );
+
+ m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizes->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
+
+ m_stdButtons = new wxStdDialogButtonSizer();
+ m_stdButtonsOK = new wxButton( this, wxID_OK );
+ m_stdButtons->AddButton( m_stdButtonsOK );
+ m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_stdButtons->AddButton( m_stdButtonsCancel );
+ m_stdButtons->Realize();
+
+ bSizes->Add( m_stdButtons, 0, wxEXPAND|wxALL, 5 );
+
+
+ this->SetSizer( bSizes );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onClose ) );
+ m_stdButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onCancelClick ), NULL, this );
+ m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onOkClick ), NULL, this );
+}
+
+DIALOG_TRACK_VIA_SIZE_BASE::~DIALOG_TRACK_VIA_SIZE_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onClose ) );
+ m_stdButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onCancelClick ), NULL, this );
+ m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_SIZE_BASE::onOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_track_via_size_base.fbp b/pcbnew/dialogs/dialog_track_via_size_base.fbp
new file mode 100644
index 0000000..5bb2927
--- /dev/null
+++ b/pcbnew/dialogs/dialog_track_via_size_base.fbp
@@ -0,0 +1,995 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_track_via_size_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_TRACK_VIA_SIZE_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_TRACK_VIA_SIZE_BASE</property>
+ <property name="pos"></property>
+ <property name="size">303,187</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Track width and via size</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">onClose</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizes</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">3</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer1</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Track width:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_trackWidthText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_trackWidthLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Via diameter:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_viaDiameterText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_viaDiameterLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Via drill:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText7</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">0</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_viaDrillText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">unit</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_viaDrillLabel</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_stdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">onCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">onOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_track_via_size_base.h b/pcbnew/dialogs/dialog_track_via_size_base.h
new file mode 100644
index 0000000..133194b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_track_via_size_base.h
@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version May 6 2016)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_TRACK_VIA_SIZE_BASE_H__
+#define __DIALOG_TRACK_VIA_SIZE_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_TRACK_VIA_SIZE_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_TRACK_VIA_SIZE_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText3;
+ wxTextCtrl* m_trackWidthText;
+ wxStaticText* m_trackWidthLabel;
+ wxStaticText* m_staticText5;
+ wxTextCtrl* m_viaDiameterText;
+ wxStaticText* m_viaDiameterLabel;
+ wxStaticText* m_staticText7;
+ wxTextCtrl* m_viaDrillText;
+ wxStaticText* m_viaDrillLabel;
+ wxStaticLine* m_staticline1;
+ wxStdDialogButtonSizer* m_stdButtons;
+ wxButton* m_stdButtonsOK;
+ wxButton* m_stdButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void onClose( wxCloseEvent& event ) { event.Skip(); }
+ virtual void onCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void onOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_TRACK_VIA_SIZE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Track width and via size"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 303,187 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_TRACK_VIA_SIZE_BASE();
+
+};
+
+#endif //__DIALOG_TRACK_VIA_SIZE_BASE_H__
diff --git a/pcbnew/dialogs/wizard_3DShape_Libs_downloader.cpp b/pcbnew/dialogs/wizard_3DShape_Libs_downloader.cpp
new file mode 100644
index 0000000..08e61ff
--- /dev/null
+++ b/pcbnew/dialogs/wizard_3DShape_Libs_downloader.cpp
@@ -0,0 +1,543 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * Code derived from "wizard_add_fplib.cpp" ( author Maciej Suminski <maciej.suminski@cern.ch> )
+ * Copyright (C) 2014-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @brief Wizard for selecting and dowloading D shapes libraries of footprints
+ * consisting of 3 steps:
+ * - select source and destination (Github URL and local folder)
+ * - pick and select libraries
+ * - download files
+ */
+
+#include <wx/wx.h>
+#include <wx/uri.h>
+#include <wx/dir.h>
+#include <wx/progdlg.h>
+
+#include <pgm_base.h>
+#include <project.h>
+#include <wizard_3DShape_Libs_downloader.h>
+#include <confirm.h>
+#include <3d_viewer.h>
+
+#include <../github/github_getliblist.h>
+
+// a key to store the default Kicad Github 3D libs URL
+#define KICAD_3DLIBS_URL_KEY wxT( "kicad_3Dlib_url" )
+#define KICAD_3DLIBS_LAST_DOWNLOAD_DIR wxT( "kicad_3Dlib_last_download_dir" )
+
+#define DEFAULT_GITHUB_3DSHAPES_LIBS_URL \
+ wxT( "https://github.com/KiCad/kicad-library/tree/master/modules/packages3d" )
+
+void Invoke3DShapeLibsDownloaderWizard( wxTopLevelWindow* aParent )
+{
+ WIZARD_3DSHAPE_LIBS_DOWNLOADER wizard( aParent );
+ wizard.RunWizard( wizard.GetFirstPage() );
+}
+
+
+WIZARD_3DSHAPE_LIBS_DOWNLOADER::WIZARD_3DSHAPE_LIBS_DOWNLOADER( wxWindow* aParent ) :
+ WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE( aParent )
+{
+ m_welcomeDlg = m_pages[0];
+ m_githubListDlg = m_pages[1];
+ m_reviewDlg = m_pages[2];
+
+ // Initialize default download dir (local target folder of 3D shapes libs)
+ wxString default_path;
+ wxGetEnv( KISYS3DMOD, &default_path );
+
+ wxConfigBase* cfg = Pgm().CommonSettings();
+ wxString tmp;
+ cfg->Read( KICAD_3DLIBS_LAST_DOWNLOAD_DIR, &tmp, default_path );
+ setDownloadDir( tmp );
+
+ // Restore the Github 3D shapes libs url
+ wxString githubUrl;
+ cfg->Read( KICAD_3DLIBS_URL_KEY, &githubUrl );
+
+ if( githubUrl.IsEmpty() )
+ githubUrl = DEFAULT_GITHUB_3DSHAPES_LIBS_URL;
+
+ SetGithubURL( githubUrl );
+
+
+ // Give the minimal size to the dialog, which allows displaying any page
+ wxSize minsize;
+
+ for( unsigned ii = 0; ii < m_pages.size(); ii++ )
+ {
+ wxSize size = m_pages[ii]->GetSizer()->CalcMin();
+ minsize.x = std::max( minsize.x, size.x );
+ minsize.y = std::max( minsize.y, size.y );
+ }
+
+ SetMinSize( minsize );
+ SetPageSize( minsize );
+ GetSizer()->SetSizeHints( this );
+ Center();
+
+ setupDialogOrder();
+ updateGithubControls();
+
+ // When starting m_textCtrlGithubURL has the focus, and the text is selected,
+ // and not fully visible.
+ // Forcing deselection does not work, at least on W7 with wxWidgets 3.0.2
+ // So (and also because m_textCtrlGithubURL and m_downloadDir are rarely modified
+ // the focus is given to an other widget.
+ m_hyperlinkGithubKicad->SetFocus();
+
+ Connect( wxEVT_RADIOBUTTON, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnSourceCheck ), NULL, this );
+ Connect( wxEVT_CHECKLISTBOX, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnCheckGithubList ), NULL, this );
+}
+
+
+WIZARD_3DSHAPE_LIBS_DOWNLOADER::~WIZARD_3DSHAPE_LIBS_DOWNLOADER()
+{
+ // Use this if you want to store kicad lib URL in pcbnew/cvpcb section config:
+ // wxConfigBase* cfg = Kiface().KifaceSettings();
+
+ // Use this if you want to store kicad lib URL in common section config:
+ wxConfigBase* cfg = Pgm().CommonSettings();
+ cfg->Write( KICAD_3DLIBS_URL_KEY, GetGithubURL() );
+ cfg->Write( KICAD_3DLIBS_LAST_DOWNLOAD_DIR, getDownloadDir() );
+}
+
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnPageChanged( wxWizardEvent& aEvent )
+{
+ SetBitmap( KiBitmap( wizard_add_fplib_icon_xpm ) );
+ enableNext( true );
+
+ if( GetCurrentPage() == m_githubListDlg )
+ setupGithubList();
+ else if( GetCurrentPage() == m_reviewDlg )
+ setupReview();
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnCheckGithubList( wxCommandEvent& aEvent )
+{
+ wxArrayInt dummy;
+
+ enableNext( m_checkList3Dlibnames->GetCheckedItems( dummy ) > 0 );
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnSourceCheck( wxCommandEvent& aEvent )
+{
+ updateGithubControls();
+ setupDialogOrder();
+}
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnGridLibReviewSize( wxSizeEvent& event )
+{
+ // Adjust the width of the column 1 afo m_gridLibReview (library names) to the
+ // max available width.
+ int gridwidth = m_gridLibReview->GetClientSize().x;
+ gridwidth -= m_gridLibReview->GetColSize( 0 ) + m_gridLibReview->GetColLabelSize();
+
+ if( gridwidth < 200 )
+ gridwidth = 200;
+
+ m_gridLibReview->SetColSize( 1, gridwidth );
+
+ event.Skip();
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::setupReview()
+{
+ // Prepare the last page of the wizard.
+
+ m_LocalFolderInfo->SetLabel( getDownloadDir() );
+
+ wxArrayInt checkedIndices;
+ m_checkList3Dlibnames->GetCheckedItems( checkedIndices );
+
+ m_libraries.Clear();
+
+ // populate m_libraries with the name of libraries, without the github path:
+ for( unsigned int ii = 0; ii < checkedIndices.GetCount(); ++ii )
+ {
+ m_libraries.Add( m_checkList3Dlibnames->GetString( checkedIndices[ii] ).AfterLast( '/' ) );
+ }
+
+ // Adjust number of rows in m_gridLibReview:
+ int delta = m_libraries.GetCount() - m_gridLibReview->GetNumberRows();
+
+ if( delta < 0 )
+ m_gridLibReview->DeleteRows( -delta );
+ else if( delta > 0 )
+ m_gridLibReview->AppendRows( delta );
+
+ // For user info, verify the existence of these libs in local folder
+ wxArrayString liblist;
+ wxFileName fn;
+ fn.AssignDir( getDownloadDir() );
+
+ for( unsigned int ii = 0; ii < m_libraries.GetCount(); ++ii )
+ {
+ fn.SetName( m_libraries[ii] );
+
+ wxDir dirs;
+ bool isNew = ! dirs.Exists( fn.GetFullPath() );
+ wxString info = isNew ? _( "New" ) : _( "Update" );
+
+ liblist.Add( info + wxT(" ") + m_libraries[ii] );
+
+ m_gridLibReview->SetCellValue( ii, 0, info );
+ m_gridLibReview->SetCellValue( ii, 1, m_libraries[ii] );
+ }
+
+ m_gridLibReview->AutoSizeColumn( 0 );
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnSelectAll3Dlibs( wxCommandEvent& aEvent )
+{
+ for( unsigned int i = 0; i < m_checkList3Dlibnames->GetCount(); ++i )
+ m_checkList3Dlibnames->Check( i, true );
+
+ // The list might be empty, e.g. in case of download error
+ wxArrayInt dummy;
+ enableNext( m_checkList3Dlibnames->GetCheckedItems( dummy ) > 0 );
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnUnselectAll3Dlibs( wxCommandEvent& aEvent )
+{
+ for( unsigned int i = 0; i < m_checkList3Dlibnames->GetCount(); ++i )
+ m_checkList3Dlibnames->Check( i, false );
+
+ enableNext( false );
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnChangeSearch( wxCommandEvent& aEvent )
+{
+ wxString searchPhrase = m_searchCtrl3Dlibs->GetValue().Lower();
+
+ // Store the current selection
+ wxArrayInt checkedIndices;
+ m_checkList3Dlibnames->GetCheckedItems( checkedIndices );
+ wxArrayString checkedStrings;
+
+ for( unsigned int i = 0; i < checkedIndices.GetCount(); ++i )
+ checkedStrings.Add( m_checkList3Dlibnames->GetString( checkedIndices[i] ).AfterLast( '/' ) );
+
+ m_checkList3Dlibnames->Clear();
+
+ // Rebuild the list, putting the matching entries on the top
+ int matching = 0; // number of entries matching the search phrase
+ for( unsigned int i = 0; i < m_githubLibs.GetCount(); ++i )
+ {
+ const wxString& lib = m_githubLibs[i].AfterLast( '/' );
+ bool wasChecked = ( checkedStrings.Index( lib ) != wxNOT_FOUND );
+ int insertedIdx = -1;
+
+ if( !searchPhrase.IsEmpty() && lib.Lower().Contains( searchPhrase ) )
+ {
+ insertedIdx = m_checkList3Dlibnames->Insert( lib, matching++ );
+ m_checkList3Dlibnames->SetSelection( insertedIdx );
+ }
+ else
+ insertedIdx = m_checkList3Dlibnames->Append( lib );
+
+ if( wasChecked )
+ m_checkList3Dlibnames->Check( insertedIdx );
+ }
+
+ if( !m_checkList3Dlibnames->IsEmpty() )
+ m_checkList3Dlibnames->EnsureVisible( 0 );
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnWizardFinished( wxWizardEvent& aEvent )
+{
+ // we download a localy copy of the libraries
+ wxString error;
+
+ if( !downloadGithubLibsFromList( m_libraries, &error ) )
+ {
+ DisplayError( GetParent(), error );
+ }
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnBrowseButtonClick( wxCommandEvent& aEvent )
+{
+ wxString path = getDownloadDir();
+
+ path = wxDirSelector( _("Choose a folder to save the downloaded libraries" ),
+ path, 0, wxDefaultPosition, this );
+
+ if( !path.IsEmpty() && wxDirExists( path ) )
+ {
+ setDownloadDir( path );
+ updateGithubControls();
+ }
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnDefault3DPathButtonClick( wxCommandEvent& event )
+{
+ wxString default_path;
+ wxGetEnv( KISYS3DMOD, &default_path );
+
+ if( !default_path.IsEmpty() && wxDirExists( default_path ) )
+ {
+ setDownloadDir( default_path );
+ updateGithubControls();
+ }
+ else
+ wxMessageBox( _( "KISYS3DMOD path not defined , or not existing" ) );
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnCheckSaveCopy( wxCommandEvent& aEvent )
+{
+ updateGithubControls();
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::getLibsListGithub( wxArrayString& aList )
+{
+ wxBeginBusyCursor();
+
+ // Be sure there is no trailing '/' at the end of the repo name
+ wxString git_url = m_textCtrlGithubURL->GetValue();
+
+ if( git_url.EndsWith( wxT( "/" ) ) )
+ {
+ git_url.RemoveLast();
+ m_textCtrlGithubURL->SetValue( git_url );
+ }
+
+ GITHUB_GETLIBLIST getter( git_url );
+ getter.Get3DshapesLibsList( &aList, filter3dshapeslibraries );
+
+ wxEndBusyCursor();
+}
+
+
+// Download the .pretty libraries folders found in aUrlList and store them on disk
+// in a master folder
+bool WIZARD_3DSHAPE_LIBS_DOWNLOADER::downloadGithubLibsFromList( wxArrayString& aUrlList,
+ wxString* aErrorMessage )
+{
+ // Display a progress bar to show the download state
+ // The title is updated for each downloaded library.
+ // the state will be updated by downloadOneLib() for each file.
+ wxProgressDialog pdlg( _( "Downloading 3D libraries" ), wxEmptyString,
+ aUrlList.GetCount(), GetParent(),
+ wxPD_CAN_ABORT | wxPD_APP_MODAL | wxPD_AUTO_HIDE );
+
+ wxString url_base = GetGithubURL();
+
+ // Download libs:
+ for( unsigned ii = 0; ii < aUrlList.GetCount(); ii++ )
+ {
+ wxString& libsrc_name = aUrlList[ii];
+
+ // Extract the lib name from the full URL:
+ wxString url = GetGithubURL() + wxT( "/" ) + libsrc_name;
+ wxFileName fn( libsrc_name );
+ // Set our local path
+ fn.SetPath( getDownloadDir() );
+ wxString libdst_name = fn.GetFullPath();
+
+ // Display the name of the library to download in the wxProgressDialog
+ pdlg.SetTitle( wxString::Format( wxT("%s [%d/%d]" ),
+ libsrc_name.AfterLast( '/' ).GetData(),
+ ii + 1, aUrlList.GetCount() ) );
+
+ if( !wxDirExists( libdst_name ) )
+ wxMkdir( libdst_name );
+
+ if( !downloadOneLib( url, libdst_name, &pdlg, aErrorMessage ) )
+ return false;
+ }
+
+ return true;
+}
+
+
+bool WIZARD_3DSHAPE_LIBS_DOWNLOADER::downloadOneLib( const wxString& aLibURL,
+ const wxString& aLocalLibName, wxProgressDialog * aIndicator,
+ wxString* aErrorMessage )
+{
+ wxArrayString fileslist;
+
+ bool success;
+
+ // Get the list of candidate files: with ext .wrl or .wings
+ do
+ {
+ GITHUB_GETLIBLIST getter( aLibURL );
+ success = getter.Get3DshapesLibsList( &fileslist, filter3dshapesfiles );
+ } while( 0 );
+
+ if( !success )
+ return false;
+
+ // Load each file in list:
+ wxURI repo( aLibURL );
+
+ wxString server = repo.GetServer();
+
+ // Github gives the current url of files inside .3dshapes folders like:
+ // "https://github.com/KiCad/kicad-library/blob/master/modules/packages3d/Capacitors_SMD.3dshapes/C_0402.wrl"
+ // which displays a html page showing the file in html form.
+ //
+ // the URL of the corresponding raw file is
+ // "https://github.com/KiCad/kicad-library/raw/master/modules/packages3d/Capacitors_SMD.3dshapes/C_0402.wrl"
+ //
+ // However Github redirects this current url to raw.githubusercontent.com/fullfilename
+ // when trying to download raw files.
+ // "https://github.com/KiCad/kicad-library/raw/master/modules/packages3d/Capacitors_SMD.3dshapes/C_0402.wrl"
+ // would be redirected to:
+ // "https://raw.githubusercontent.com/KiCad/kicad-library/master/modules/packages3d/Capacitors_SMD.3dshapes/C_0402.wrl"
+ // So use raw.githubusercontent.com instead of github.com
+ // (and removes the "/raw" in path) speed up the downloads (x2 faster).
+ //
+ // wxURI has no way to change the server name, so we need to use tricks to make the URL.
+ //
+ // Comment this next line to use the github.com URL
+#define FORCE_GITHUB_RAW_URL
+
+#ifdef FORCE_GITHUB_RAW_URL
+ if( server.Cmp( wxT( "github.com" ) ) == 0 )
+ server = wxT( "raw.githubusercontent.com" );
+#endif
+
+ wxString full_url_base = repo.GetScheme() + wxT( "://" ) + server;
+ wxString target_full_url;
+
+ for( unsigned ii = 0; ii < fileslist.GetCount(); ii++ )
+ {
+ target_full_url = full_url_base + fileslist[ii];
+
+#ifdef FORCE_GITHUB_RAW_URL
+ // Remove "blob/" in URL string to build the URL on "raw.githubusercontent.com"
+ // server from "github.com" URL string:
+ target_full_url.Replace( wxT( "blob/" ), wxT( "" ) );
+#else
+ // Replace "blob" by "raw" in URL to access the raw file itself, not the html page
+ // on "github.com" server
+ target_full_url.Replace( wxT( "blob" ), wxT( "raw" ) );
+#endif
+ aIndicator->SetRange( fileslist.GetCount() );
+ bool abort = !aIndicator->Update( ii, target_full_url.AfterLast( '/' ) );
+
+ if( abort )
+ {
+ if( aErrorMessage )
+ *aErrorMessage << _( "Aborted by user" );
+ return false;
+ }
+
+ // Download the current file.
+ // Get3DshapesLibsList actually downloads and stores the target_full_url content.
+ GITHUB_GETLIBLIST getter( target_full_url );
+ success = getter.Get3DshapesLibsList( NULL, NULL );
+
+ if( !success )
+ break;
+
+ wxFileName fn;
+ fn.AssignDir( aLocalLibName );
+ fn.SetFullName( fileslist[ii].AfterLast( '/' ) );
+
+ // The entire downloaded file is stored in getter buffer
+ const std::string& buffer = getter.GetBuffer();
+
+ // Write is "as this". It can be a binary file.
+ wxFile file(fn.GetFullPath(), wxFile::write);
+ file.Write( &buffer[0], buffer.size() );
+ }
+
+ return success;
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::setupGithubList()
+{
+ // Enable 'Next' only if there is at least one library selected
+ wxArrayInt checkedIndices;
+ m_checkList3Dlibnames->GetCheckedItems( checkedIndices );
+ enableNext( checkedIndices.GetCount() > 0 );
+
+ // Update only if necessary
+ if( m_githubLibs.GetCount() == 0 )
+ getLibsListGithub( m_githubLibs );
+
+ m_searchCtrl3Dlibs->Clear();
+
+ // Clear the review list so it will be reloaded
+ m_libraries.clear();
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::updateGithubControls()
+{
+ bool valid = wxFileName::IsDirWritable( getDownloadDir() );
+
+ // Shows or not the warning text if the target 3d folder does not exist, or is not
+ // writable.
+ m_invalidDirWarningText->Show( !valid );
+ m_bitmapDirWarn->Show( !valid );
+
+ // If the dialog starts with m_invalidDirWarningText and m_bitmapDirWarn not shown
+ // the size and position of the sizer containing these widgets can be incorrect,
+ // until a wxSizeEvent is fired, and the widgets are not shown, or truncated,
+ // at least on Windows. So fire a dummy wxSizeEvent if the size looks bad
+ if( m_invalidDirWarningText->IsShown() && m_invalidDirWarningText->GetSize().x < 2 )
+ {
+ wxSizeEvent event( GetSize() );
+ wxPostEvent( this, event );
+ }
+
+ // Allow to go further only if there is a valid target directory selected
+ enableNext( valid );
+}
+
+// Called when the local folder name is edited.
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnLocalFolderChange( wxCommandEvent& event )
+{
+ updateGithubControls();
+}
+
+
+void WIZARD_3DSHAPE_LIBS_DOWNLOADER::setupDialogOrder()
+{
+ m_welcomeDlg->SetNext( m_githubListDlg );
+ m_githubListDlg->SetPrev( m_welcomeDlg );
+ m_githubListDlg->SetNext( m_reviewDlg );
+ m_reviewDlg->SetPrev( m_githubListDlg );
+}
+
diff --git a/pcbnew/dialogs/wizard_3DShape_Libs_downloader.h b/pcbnew/dialogs/wizard_3DShape_Libs_downloader.h
new file mode 100644
index 0000000..8ea13f1
--- /dev/null
+++ b/pcbnew/dialogs/wizard_3DShape_Libs_downloader.h
@@ -0,0 +1,144 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * Code derived from "wizard_add_fplib.h" (from Maciej Suminski <maciej.suminski@cern.ch>)
+ * Copyright (C) 2014-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wizard_3DShape_Libs_downloader_base.h>
+
+class KIWAY_PLAYER;
+
+class WIZARD_3DSHAPE_LIBS_DOWNLOADER : public WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE
+{
+public:
+ WIZARD_3DSHAPE_LIBS_DOWNLOADER( wxWindow* aParent );
+ ~WIZARD_3DSHAPE_LIBS_DOWNLOADER();
+
+ /**
+ * Function GetFirstPage
+ * Returns the welcoming page for the wizard.
+ */
+ inline wxWizardPage* GetFirstPage() const
+ {
+ return m_welcomeDlg;
+ }
+
+ /**
+ * Function GetGithubURL
+ * Returns the current Github repository URL set in the wizard.
+ */
+ inline wxString GetGithubURL() const
+ {
+ return m_textCtrlGithubURL->GetValue();
+ }
+
+ /**
+ * Function SetGithubURL
+ * Sets the current Github repository URL used by the wizard.
+ * @param aUrl is the new URL to be applied.
+ */
+ inline void SetGithubURL( const wxString& aUrl )
+ {
+ m_textCtrlGithubURL->SetValue( aUrl );
+ }
+
+ // Wizard event handlers
+ void OnSourceCheck( wxCommandEvent& aEvent );
+ void OnCheckGithubList( wxCommandEvent& aEvent );
+ void OnPageChanged( wxWizardEvent& aEvent );
+ void OnSelectAll3Dlibs( wxCommandEvent& aEvent );
+ void OnUnselectAll3Dlibs( wxCommandEvent& aEvent );
+ void OnChangeSearch( wxCommandEvent& aEvent );
+ void OnWizardFinished( wxWizardEvent& aEvent );
+ void OnBrowseButtonClick( wxCommandEvent& aEvent );
+ void OnCheckSaveCopy( wxCommandEvent& aEvent );
+ void OnDefault3DPathButtonClick( wxCommandEvent& event );
+ void OnGridLibReviewSize( wxSizeEvent& event );
+ void OnLocalFolderChange( wxCommandEvent& event );
+
+protected:
+ // Initialization of wizard pages
+ void setupDialogOrder();
+ void setupGithubList(); // Prepare the second page
+ // (list of available .3dshapes libraries on github)
+ void setupReview(); // Prepare the last page
+
+ ///> Sets the target directory for libraries downloaded from Github
+ void setDownloadDir( const wxString& aDir )
+ {
+ m_downloadDir->SetValue( aDir );
+ }
+
+ ///> Gets the current target for downloaded libraries
+ inline wxString getDownloadDir()
+ {
+ return m_downloadDir->GetValue();
+ }
+
+ ///> Downloads the list of Github libraries
+ void getLibsListGithub( wxArrayString& aList );
+
+ ///> Saves a list of Github libraries locally.
+ bool downloadGithubLibsFromList( wxArrayString& aUrlList, wxString* aErrorMessage );
+
+ ///> Saves a Github library aLibURL locally in aLocalLibName.
+ bool downloadOneLib( const wxString& aLibURL,
+ const wxString& aLocalLibName,
+ wxProgressDialog * aIndicator,
+ wxString* aErrorMessage );
+
+ ///> Enables Github widgets depending on the selected options.
+ void updateGithubControls();
+
+ ///> Enables/disable 'Next' button
+ inline void enableNext( bool aEnable )
+ {
+ wxWindow* nextBtn = FindWindowById( wxID_FORWARD );
+
+ if( nextBtn )
+ nextBtn->Enable( aEnable );
+ }
+
+ // A callback function to filter 3D filenames
+ static bool filter3dshapesfiles( const wxString& aData )
+ {
+ return aData.Contains( wxT( ".wrl" ) ) || aData.Contains( wxT( ".wings" ) );
+ }
+
+ // A callback function to filter 3D folders names
+ static bool filter3dshapeslibraries( const wxString& aData )
+ {
+ return aData.Contains( wxT( ".3dshapes" ) );
+ }
+
+ ///> Cache for the downloaded Github library list
+ wxArrayString m_githubLibs;
+
+ ///> Libraries names selected in the wizard
+ wxArrayString m_libraries;
+
+ // Aliases for wizard pages to make code more readable
+ wxWizardPageSimple* m_welcomeDlg;
+ wxWizardPageSimple* m_githubListDlg;
+ wxWizardPageSimple* m_reviewDlg;
+};
diff --git a/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.cpp b/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.cpp
new file mode 100644
index 0000000..8cde4a3
--- /dev/null
+++ b/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.cpp
@@ -0,0 +1,249 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "wizard_3DShape_Libs_downloader_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxBitmap& bitmap, const wxPoint& pos, long style )
+{
+ this->Create( parent, id, title, bitmap, pos, style );
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxWizardPageSimple* m_wizPage1 = new wxWizardPageSimple( this, NULL, NULL, wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ) );
+ m_pages.Add( m_wizPage1 );
+
+ m_wizPage1->SetMinSize( wxSize( 720,480 ) );
+
+ wxBoxSizer* bSizer1;
+ bSizer1 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextWelcome = new wxStaticText( m_wizPage1, wxID_ANY, _("Welcome to the 3D shape Libraries downloader Wizard!"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextWelcome->Wrap( -1 );
+ bSizer1->Add( m_staticTextWelcome, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizer1->Add( 0, 20, 0, 0, 5 );
+
+ wxBoxSizer* bSizer19;
+ bSizer19 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText8 = new wxStaticText( m_wizPage1, wxID_ANY, _("Please select the URL for the 3D libraries to download"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText8->Wrap( -1 );
+ bSizer19->Add( m_staticText8, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_textCtrlGithubURL = new wxTextCtrl( m_wizPage1, wxID_ANY, _("http://github.com/KiCad"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_textCtrlGithubURL->SetMinSize( wxSize( 300,-1 ) );
+
+ bSizer19->Add( m_textCtrlGithubURL, 0, wxALL|wxEXPAND, 5 );
+
+
+ bSizer19->Add( 0, 10, 0, 0, 5 );
+
+ wxFlexGridSizer* fgSizerLocalFolder;
+ fgSizerLocalFolder = new wxFlexGridSizer( 0, 2, 0, 0 );
+ fgSizerLocalFolder->AddGrowableCol( 0 );
+ fgSizerLocalFolder->SetFlexibleDirection( wxBOTH );
+ fgSizerLocalFolder->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ wxBoxSizer* bSizerDinname;
+ bSizerDinname = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText9 = new wxStaticText( m_wizPage1, wxID_ANY, _("3D shape local folder:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText9->Wrap( -1 );
+ bSizerDinname->Add( m_staticText9, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_downloadDir = new wxTextCtrl( m_wizPage1, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerDinname->Add( m_downloadDir, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+
+ fgSizerLocalFolder->Add( bSizerDinname, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
+
+ wxBoxSizer* bSizerButts;
+ bSizerButts = new wxBoxSizer( wxVERTICAL );
+
+ m_btnBrowse = new wxButton( m_wizPage1, wxID_ANY, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButts->Add( m_btnBrowse, 0, wxEXPAND|wxALL, 5 );
+
+ m_buttonDefault3DPath = new wxButton( m_wizPage1, wxID_ANY, _("Default 3D Path"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerButts->Add( m_buttonDefault3DPath, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+
+ fgSizerLocalFolder->Add( bSizerButts, 0, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerWarnMsg;
+ bSizerWarnMsg = new wxBoxSizer( wxHORIZONTAL );
+
+ m_bitmapDirWarn = new wxStaticBitmap( m_wizPage1, wxID_ANY, wxArtProvider::GetBitmap( wxART_ERROR, wxART_OTHER ), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerWarnMsg->Add( m_bitmapDirWarn, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 );
+
+ m_invalidDirWarningText = new wxStaticText( m_wizPage1, wxID_ANY, _("It is not possible to write in the selected directory.\nPlease choose another one."), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
+ m_invalidDirWarningText->Wrap( -1 );
+ m_invalidDirWarningText->SetForegroundColour( wxColour( 255, 0, 0 ) );
+
+ bSizerWarnMsg->Add( m_invalidDirWarningText, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
+
+
+ fgSizerLocalFolder->Add( bSizerWarnMsg, 1, wxEXPAND, 5 );
+
+
+ fgSizerLocalFolder->Add( 10, 40, 0, 0, 5 );
+
+
+ bSizer19->Add( fgSizerLocalFolder, 1, wxEXPAND, 5 );
+
+
+ bSizer1->Add( bSizer19, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerOfficialRepo;
+ bSizerOfficialRepo = new wxBoxSizer( wxHORIZONTAL );
+
+ m_bitmapRepo = new wxStaticBitmap( m_wizPage1, wxID_ANY, wxArtProvider::GetBitmap( wxART_INFORMATION, wxART_OTHER ), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerOfficialRepo->Add( m_bitmapRepo, 0, wxALL, 5 );
+
+
+ bSizerOfficialRepo->Add( 0, 0, 0, wxRIGHT|wxLEFT, 10 );
+
+ m_hyperlinkGithubKicad = new wxHyperlinkCtrl( m_wizPage1, wxID_ANY, _("Visit our official Kicad repository on Github and get more libraries"), wxT("https://github.com/KiCad"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE );
+ bSizerOfficialRepo->Add( m_hyperlinkGithubKicad, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizer1->Add( bSizerOfficialRepo, 0, wxEXPAND, 5 );
+
+
+ m_wizPage1->SetSizer( bSizer1 );
+ m_wizPage1->Layout();
+ wxWizardPageSimple* m_wizPage2_Github = new wxWizardPageSimple( this, NULL, NULL, wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ) );
+ m_pages.Add( m_wizPage2_Github );
+
+ wxBoxSizer* bSizer111;
+ bSizer111 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText112 = new wxStaticText( m_wizPage2_Github, wxID_ANY, _("Select Github libraries to add:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText112->Wrap( -1 );
+ bSizer111->Add( m_staticText112, 0, wxALL|wxEXPAND, 5 );
+
+ wxArrayString m_checkList3DlibnamesChoices;
+ m_checkList3Dlibnames = new wxCheckListBox( m_wizPage2_Github, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_checkList3DlibnamesChoices, wxLB_MULTIPLE|wxLB_NEEDED_SB );
+ bSizer111->Add( m_checkList3Dlibnames, 1, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer7;
+ bSizer7 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_btnSelectAll3Dlibs = new wxButton( m_wizPage2_Github, wxID_ANY, _("Select all"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer7->Add( m_btnSelectAll3Dlibs, 1, wxALL, 5 );
+
+ m_btnUnselectAll3Dlibs = new wxButton( m_wizPage2_Github, wxID_ANY, _("Unselect all"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer7->Add( m_btnUnselectAll3Dlibs, 1, wxALL, 5 );
+
+
+ bSizer7->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_searchCtrl3Dlibs = new wxSearchCtrl( m_wizPage2_Github, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ #ifndef __WXMAC__
+ m_searchCtrl3Dlibs->ShowSearchButton( true );
+ #endif
+ m_searchCtrl3Dlibs->ShowCancelButton( false );
+ bSizer7->Add( m_searchCtrl3Dlibs, 2, wxALL, 5 );
+
+
+ bSizer111->Add( bSizer7, 0, wxEXPAND, 5 );
+
+
+ m_wizPage2_Github->SetSizer( bSizer111 );
+ m_wizPage2_Github->Layout();
+ bSizer111->Fit( m_wizPage2_Github );
+ wxWizardPageSimple* m_wizPage3_SelectTarget = new wxWizardPageSimple( this, NULL, NULL, wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ) );
+ m_pages.Add( m_wizPage3_SelectTarget );
+
+ wxBoxSizer* bSizer12;
+ bSizer12 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticTextlocalfolder = new wxStaticText( m_wizPage3_SelectTarget, wxID_ANY, _("Local library folder:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextlocalfolder->Wrap( -1 );
+ bSizer12->Add( m_staticTextlocalfolder, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_LocalFolderInfo = new wxStaticText( m_wizPage3_SelectTarget, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_LocalFolderInfo->Wrap( -1 );
+ bSizer12->Add( m_LocalFolderInfo, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticText12 = new wxStaticText( m_wizPage3_SelectTarget, wxID_ANY, _("3D shape libraries to be downloaded:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText12->Wrap( -1 );
+ bSizer12->Add( m_staticText12, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ m_gridLibReview = new wxGrid( m_wizPage3_SelectTarget, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_gridLibReview->CreateGrid( 1, 2 );
+ m_gridLibReview->EnableEditing( false );
+ m_gridLibReview->EnableGridLines( true );
+ m_gridLibReview->EnableDragGridSize( false );
+ m_gridLibReview->SetMargins( 5, 0 );
+
+ // Columns
+ m_gridLibReview->EnableDragColMove( false );
+ m_gridLibReview->EnableDragColSize( true );
+ m_gridLibReview->SetColLabelSize( 30 );
+ m_gridLibReview->SetColLabelValue( 0, _("Status") );
+ m_gridLibReview->SetColLabelValue( 1, _("Libraries") );
+ m_gridLibReview->SetColLabelValue( 2, wxEmptyString );
+ m_gridLibReview->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_gridLibReview->AutoSizeRows();
+ m_gridLibReview->EnableDragRowSize( true );
+ m_gridLibReview->SetRowLabelSize( 30 );
+ m_gridLibReview->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_gridLibReview->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ bSizer12->Add( m_gridLibReview, 1, wxALL|wxEXPAND, 5 );
+
+
+ m_wizPage3_SelectTarget->SetSizer( bSizer12 );
+ m_wizPage3_SelectTarget->Layout();
+ bSizer12->Fit( m_wizPage3_SelectTarget );
+
+ this->Centre( wxBOTH );
+
+ for ( unsigned int i = 1; i < m_pages.GetCount(); i++ )
+ {
+ m_pages.Item( i )->SetPrev( m_pages.Item( i - 1 ) );
+ m_pages.Item( i - 1 )->SetNext( m_pages.Item( i ) );
+ }
+
+ // Connect Events
+ this->Connect( wxID_ANY, wxEVT_WIZARD_FINISHED, wxWizardEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnWizardFinished ) );
+ this->Connect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnPageChanged ) );
+ this->Connect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnPageChanging ) );
+ m_downloadDir->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnLocalFolderChange ), NULL, this );
+ m_btnBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnBrowseButtonClick ), NULL, this );
+ m_buttonDefault3DPath->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnDefault3DPathButtonClick ), NULL, this );
+ m_btnSelectAll3Dlibs->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnSelectAll3Dlibs ), NULL, this );
+ m_btnUnselectAll3Dlibs->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnUnselectAll3Dlibs ), NULL, this );
+ m_searchCtrl3Dlibs->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnChangeSearch ), NULL, this );
+ m_gridLibReview->Connect( wxEVT_SIZE, wxSizeEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnGridLibReviewSize ), NULL, this );
+}
+
+WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::~WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxID_ANY, wxEVT_WIZARD_FINISHED, wxWizardEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnWizardFinished ) );
+ this->Disconnect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnPageChanged ) );
+ this->Disconnect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnPageChanging ) );
+ m_downloadDir->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnLocalFolderChange ), NULL, this );
+ m_btnBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnBrowseButtonClick ), NULL, this );
+ m_buttonDefault3DPath->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnDefault3DPathButtonClick ), NULL, this );
+ m_btnSelectAll3Dlibs->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnSelectAll3Dlibs ), NULL, this );
+ m_btnUnselectAll3Dlibs->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnUnselectAll3Dlibs ), NULL, this );
+ m_searchCtrl3Dlibs->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnChangeSearch ), NULL, this );
+ m_gridLibReview->Disconnect( wxEVT_SIZE, wxSizeEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnGridLibReviewSize ), NULL, this );
+
+ m_pages.Clear();
+}
diff --git a/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.fbp b/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.fbp
new file mode 100644
index 0000000..83cedb8
--- /dev/null
+++ b/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.fbp
@@ -0,0 +1,2149 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">wizard_3DShape_Libs_downloader_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">Wizard_3DShapes_Libs_Downloader</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Wizard" expanded="1">
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON</property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE</property>
+ <property name="pos"></property>
+ <property name="size">591,386</property>
+ <property name="style">wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER</property>
+ <property name="subclass">; </property>
+ <property name="title">Add 3D Shape Libraries Wizard</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <event name="OnWizardCancel"></event>
+ <event name="OnWizardFinished">OnWizardFinished</event>
+ <event name="OnWizardHelp"></event>
+ <event name="OnWizardPageChanged">OnPageChanged</event>
+ <event name="OnWizardPageChanging">OnPageChanging</event>
+ <object class="WizardPageSimple" expanded="1">
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">720,480</property>
+ <property name="name">m_wizPage1</property>
+ <property name="permission">protected</property>
+ <property name="pos"></property>
+ <property name="size">720,480</property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer1</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Welcome to the 3D shape Libraries downloader Wizard!</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextWelcome</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">20</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer19</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Please select the URL for the 3D libraries to download</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText8</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">300,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlGithubURL</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">http://github.com/KiCad</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">10</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">0</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizerLocalFolder</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerDinname</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">3D shape local folder:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText9</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_downloadDir</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnLocalFolderChange</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerButts</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Browse</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_btnBrowse</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnBrowseButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Default 3D Path</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonDefault3DPath</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnDefault3DPathButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerWarnMsg</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBitmap" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_ERROR; wxART_OTHER</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_bitmapDirWarn</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg">255,0,0</property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">It is not possible to write in the selected directory.&#x0A;Please choose another one.</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_invalidDirWarningText</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxALIGN_CENTRE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">40</property>
+ <property name="permission">protected</property>
+ <property name="width">10</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerOfficialRepo</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBitmap" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_INFORMATION; wxART_OTHER</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_bitmapRepo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">10</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxHyperlinkCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="hover_color"></property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Visit our official Kicad repository on Github and get more libraries</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_hyperlinkGithubKicad</property>
+ <property name="normal_color"></property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxHL_DEFAULT_STYLE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="url">https://github.com/KiCad</property>
+ <property name="visited_color"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHyperlink"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="WizardPageSimple" expanded="1">
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">m_wizPage2_Github</property>
+ <property name="permission">protected</property>
+ <property name="pos"></property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer111</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Select Github libraries to add:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText112</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxCheckListBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkList3Dlibnames</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLB_MULTIPLE|wxLB_NEEDED_SB</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckListBox"></event>
+ <event name="OnCheckListBoxDClick"></event>
+ <event name="OnCheckListBoxToggled"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer7</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Select all</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_btnSelectAll3Dlibs</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnSelectAll3Dlibs</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unselect all</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_btnUnselectAll3Dlibs</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnUnselectAll3Dlibs</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">2</property>
+ <object class="wxSearchCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="cancel_button">0</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_searchCtrl3Dlibs</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="search_button">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnCancelButton"></event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSearchButton"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnChangeSearch</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="WizardPageSimple" expanded="1">
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">m_wizPage3_SelectTarget</property>
+ <property name="permission">protected</property>
+ <property name="pos"></property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer12</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Local library folder:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextlocalfolder</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">dummy</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_LocalFolderInfo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">3D shape libraries to be downloaded:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText12</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxGrid" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="autosize_cols">0</property>
+ <property name="autosize_rows">1</property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="cell_bg"></property>
+ <property name="cell_font"></property>
+ <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+ <property name="cell_text"></property>
+ <property name="cell_vert_alignment">wxALIGN_TOP</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="col_label_size">30</property>
+ <property name="col_label_values">&quot;Status&quot; &quot;Libraries&quot; &quot;&quot;</property>
+ <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="cols">2</property>
+ <property name="column_sizes"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="drag_col_move">0</property>
+ <property name="drag_col_size">1</property>
+ <property name="drag_grid_size">0</property>
+ <property name="drag_row_size">1</property>
+ <property name="editing">0</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="grid_line_color"></property>
+ <property name="grid_lines">1</property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label_bg"></property>
+ <property name="label_font"></property>
+ <property name="label_text"></property>
+ <property name="margin_height">0</property>
+ <property name="margin_width">5</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_gridLibReview</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+ <property name="row_label_size">30</property>
+ <property name="row_label_values"></property>
+ <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+ <property name="row_sizes"></property>
+ <property name="rows">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnGridCellChange"></event>
+ <event name="OnGridCellLeftClick"></event>
+ <event name="OnGridCellLeftDClick"></event>
+ <event name="OnGridCellRightClick"></event>
+ <event name="OnGridCellRightDClick"></event>
+ <event name="OnGridCmdCellChange"></event>
+ <event name="OnGridCmdCellLeftClick"></event>
+ <event name="OnGridCmdCellLeftDClick"></event>
+ <event name="OnGridCmdCellRightClick"></event>
+ <event name="OnGridCmdCellRightDClick"></event>
+ <event name="OnGridCmdColSize"></event>
+ <event name="OnGridCmdEditorCreated"></event>
+ <event name="OnGridCmdEditorHidden"></event>
+ <event name="OnGridCmdEditorShown"></event>
+ <event name="OnGridCmdLabelLeftClick"></event>
+ <event name="OnGridCmdLabelLeftDClick"></event>
+ <event name="OnGridCmdLabelRightClick"></event>
+ <event name="OnGridCmdLabelRightDClick"></event>
+ <event name="OnGridCmdRangeSelect"></event>
+ <event name="OnGridCmdRowSize"></event>
+ <event name="OnGridCmdSelectCell"></event>
+ <event name="OnGridColSize"></event>
+ <event name="OnGridEditorCreated"></event>
+ <event name="OnGridEditorHidden"></event>
+ <event name="OnGridEditorShown"></event>
+ <event name="OnGridLabelLeftClick"></event>
+ <event name="OnGridLabelLeftDClick"></event>
+ <event name="OnGridLabelRightClick"></event>
+ <event name="OnGridLabelRightDClick"></event>
+ <event name="OnGridRangeSelect"></event>
+ <event name="OnGridRowSize"></event>
+ <event name="OnGridSelectCell"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize">OnGridLibReviewSize</event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.h b/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.h
new file mode 100644
index 0000000..1e14d9d
--- /dev/null
+++ b/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.h
@@ -0,0 +1,88 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE_H__
+#define __WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/button.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/statbmp.h>
+#include <wx/hyperlink.h>
+#include <wx/checklst.h>
+#include <wx/srchctrl.h>
+#include <wx/grid.h>
+#include <wx/wizard.h>
+#include <wx/dynarray.h>
+WX_DEFINE_ARRAY_PTR( wxWizardPageSimple*, WizardPages );
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE
+///////////////////////////////////////////////////////////////////////////////
+class WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE : public wxWizard
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticTextWelcome;
+ wxStaticText* m_staticText8;
+ wxTextCtrl* m_textCtrlGithubURL;
+ wxStaticText* m_staticText9;
+ wxTextCtrl* m_downloadDir;
+ wxButton* m_btnBrowse;
+ wxButton* m_buttonDefault3DPath;
+ wxStaticBitmap* m_bitmapDirWarn;
+ wxStaticText* m_invalidDirWarningText;
+ wxStaticBitmap* m_bitmapRepo;
+ wxHyperlinkCtrl* m_hyperlinkGithubKicad;
+ wxStaticText* m_staticText112;
+ wxCheckListBox* m_checkList3Dlibnames;
+ wxButton* m_btnSelectAll3Dlibs;
+ wxButton* m_btnUnselectAll3Dlibs;
+ wxSearchCtrl* m_searchCtrl3Dlibs;
+ wxStaticText* m_staticTextlocalfolder;
+ wxStaticText* m_LocalFolderInfo;
+ wxStaticText* m_staticText12;
+ wxGrid* m_gridLibReview;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnWizardFinished( wxWizardEvent& event ) { event.Skip(); }
+ virtual void OnPageChanged( wxWizardEvent& event ) { event.Skip(); }
+ virtual void OnPageChanging( wxWizardEvent& event ) { event.Skip(); }
+ virtual void OnLocalFolderChange( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnBrowseButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnDefault3DPathButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnSelectAll3Dlibs( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnUnselectAll3Dlibs( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnChangeSearch( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnGridLibReviewSize( wxSizeEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Add 3D Shape Libraries Wizard"), const wxBitmap& bitmap = wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ), const wxPoint& pos = wxDefaultPosition, long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER );
+ WizardPages m_pages;
+ ~WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE();
+
+};
+
+#endif //__WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE_H__
diff --git a/pcbnew/dialogs/wizard_add_fplib.cpp b/pcbnew/dialogs/wizard_add_fplib.cpp
new file mode 100644
index 0000000..254cec3
--- /dev/null
+++ b/pcbnew/dialogs/wizard_add_fplib.cpp
@@ -0,0 +1,863 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ * Copyright (C) 2014-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @brief Wizard for selecting footprint libraries consisting of 4 steps:
+ * - select source (Github/local files)
+ * - pick libraries
+ * - present a review of libraries (including validation)
+ * - select scope (global/project)
+ */
+
+#include <wx/wx.h>
+#include <wx/uri.h>
+#include <wx/dir.h>
+#include <wx/progdlg.h>
+
+#include <pgm_base.h>
+#include <project.h>
+#include <wizard_add_fplib.h>
+#include <fp_lib_table.h>
+#include <confirm.h>
+
+#include <class_module.h>
+
+#ifdef BUILD_GITHUB_PLUGIN
+#include <../github/github_getliblist.h>
+#endif
+
+// a key to store the default Kicad Github libs URL
+#define KICAD_FPLIBS_URL_KEY wxT( "kicad_fplib_url" )
+#define KICAD_FPLIBS_LAST_DOWNLOAD_DIR wxT( "kicad_fplib_last_download_dir" )
+
+// Filters for the file picker
+static const int FILTER_COUNT = 4;
+static const struct
+{
+ wxString m_Description; ///< Description shown in the file picker dialog
+ wxString m_Extension; ///< In case of folders it stands for extensions of files stored inside
+ bool m_IsFile; ///< Whether it is a folder or a file
+ IO_MGR::PCB_FILE_T m_Plugin;
+} fileFilters[FILTER_COUNT] =
+{
+ { "KiCad (folder with .kicad_mod files)", "kicad_mod", false, IO_MGR::KICAD },
+ { "Eagle 6.x (*.lbr)", "lbr", true, IO_MGR::EAGLE },
+ { "KiCad legacy (*.mod)", "mod", true, IO_MGR::LEGACY },
+ { "Geda (folder with *.fp files)", "fp", false, IO_MGR::GEDA_PCB },
+};
+
+
+// Returns the filter string for the file picker
+static wxString getFilterString()
+{
+ wxString filterInit = _( "All supported library formats|" );
+ wxString filter;
+
+ for( int i = 0; i < FILTER_COUNT; ++i )
+ {
+ // Init part
+ if( i != 0 )
+ filterInit += ";";
+
+ filterInit += "*." + fileFilters[i].m_Extension;
+
+ // Rest of the filter string
+ filter += "|" + fileFilters[i].m_Description +
+ "|" + ( fileFilters[i].m_IsFile ? "*." + fileFilters[i].m_Extension : "" );
+ }
+
+ return filterInit + filter;
+}
+
+
+// Tries to guess the plugin type basing on the path
+static boost::optional<IO_MGR::PCB_FILE_T> getPluginType( const wxString& aPath )
+{
+ if( ( aPath.StartsWith( "http://" ) || aPath.StartsWith( "https://" ) ) )
+ return boost::optional<IO_MGR::PCB_FILE_T>( IO_MGR::GITHUB );
+
+ wxFileName path( aPath );
+
+ for( int i = 0; i < FILTER_COUNT; ++i )
+ {
+ bool ok = false;
+
+ if( fileFilters[i].m_IsFile )
+ {
+ ok = path.IsFileReadable() && path.GetExt() == fileFilters[i].m_Extension;
+ }
+ else if( path.IsDirReadable() )
+ {
+ // Plugin expects a directory containing files with a specific extension
+ wxDir dir( aPath );
+
+ if( dir.IsOpened() )
+ {
+ wxString filename;
+
+ dir.GetFirst( &filename, "*." + fileFilters[i].m_Extension, wxDIR_FILES );
+
+ ok = !filename.IsEmpty();
+ }
+ }
+
+ if( ok )
+ return boost::optional<IO_MGR::PCB_FILE_T>( fileFilters[i].m_Plugin );
+ }
+
+ return boost::none;
+}
+
+
+// Checks if a filename fits specific filter
+static bool passesFilter( const wxString& aFileName, int aFilterIndex )
+{
+ wxASSERT( aFilterIndex <= FILTER_COUNT );
+ wxFileName file( aFileName );
+ boost::optional<IO_MGR::PCB_FILE_T> result = getPluginType( aFileName );
+
+ if( !result ) // does not match any supported plugin
+ return false;
+
+ if( aFilterIndex == 0 ) // any plugin will do
+ return true;
+
+ return ( fileFilters[aFilterIndex - 1].m_Plugin == *result );
+}
+
+
+WIZARD_FPLIB_TABLE::LIBRARY::LIBRARY( const wxString& aPath, const wxString& aDescription ) :
+ m_path( aPath ), m_description( aDescription ), m_status( NOT_CHECKED )
+{
+ m_plugin = getPluginType( aPath );
+}
+
+
+bool WIZARD_FPLIB_TABLE::LIBRARY::Test()
+{
+ if( !m_plugin )
+ {
+ m_status = LIBRARY::INVALID;
+ return false;
+ }
+
+ PLUGIN* p = IO_MGR::PluginFind( *m_plugin );
+ wxArrayString footprints;
+
+ if( !p )
+ {
+ m_status = LIBRARY::INVALID;
+ return false;
+ }
+
+ try
+ {
+ footprints = p->FootprintEnumerate( m_path );
+ }
+ catch( IO_ERROR& e )
+ {
+ m_status = LIBRARY::INVALID;
+ return false;
+ }
+
+ if( footprints.GetCount() == 0 )
+ {
+ m_status = LIBRARY::INVALID;
+ return false;
+ }
+
+ m_status = LIBRARY::OK;
+ return true;
+}
+
+
+wxString WIZARD_FPLIB_TABLE::LIBRARY::GetPluginName() const
+{
+ if( !m_plugin )
+ return _( "UNKNOWN" );
+
+ switch( *m_plugin )
+ {
+ case IO_MGR::LEGACY:
+ return wxT( "Legacy" );
+
+ case IO_MGR::KICAD:
+ return wxT( "KiCad" );
+
+ case IO_MGR::EAGLE:
+ return wxT( "Eagle" );
+
+ case IO_MGR::GEDA_PCB:
+ return wxT( "Geda-PCB" );
+
+ case IO_MGR::GITHUB:
+ return wxT( "Github" );
+
+ default:
+ return _( "UNKNOWN" );
+ }
+
+ /*PLUGIN* p = IO_MGR::PluginFind( *m_plugin );
+
+ if( !p )
+ return _( "UNKNOWN" );
+
+ return p->PluginName();*/
+}
+
+
+wxString WIZARD_FPLIB_TABLE::LIBRARY::GetRelativePath( const wxString& aBase, const wxString& aSubstitution ) const
+{
+ wxFileName libPath( m_path );
+
+ // Check if the library path belongs to the project folder
+ if( libPath.MakeRelativeTo( aBase ) && !libPath.GetFullPath().StartsWith( ".." ) )
+ {
+ return wxString( aSubstitution + "/" + libPath.GetFullPath() );
+ }
+
+ // Probably on another drive, so the relative path will not work
+ return wxEmptyString;
+}
+
+
+wxString WIZARD_FPLIB_TABLE::LIBRARY::GetAutoPath( LIB_SCOPE aScope ) const
+{
+ const wxString& global_env = FP_LIB_TABLE::GlobalPathEnvVariableName();
+ const wxString& project_env = PROJECT_VAR_NAME;
+ const wxString& github_env( "KIGITHUB" );
+
+ wxString rel_path;
+
+ // KISYSMOD check
+ rel_path = replaceEnv( global_env );
+
+ if( !rel_path.IsEmpty() )
+ return rel_path;
+
+ // KIGITHUB check
+ rel_path = replaceEnv( github_env, false );
+
+ if( !rel_path.IsEmpty() )
+ return rel_path;
+
+ // KIPRJMOD check
+ if( aScope == PROJECT )
+ {
+ rel_path = replaceEnv( project_env );
+
+ if( !rel_path.IsEmpty() )
+ return rel_path;
+ }
+
+ // Return the full path
+ return m_path;
+}
+
+
+wxString WIZARD_FPLIB_TABLE::LIBRARY::GetDescription() const
+{
+ if( !m_description.IsEmpty() )
+ return m_description;
+
+ wxFileName filename( m_path );
+ return filename.GetName();
+}
+
+
+wxString WIZARD_FPLIB_TABLE::LIBRARY::replaceEnv( const wxString& aEnvVar, bool aFilePath ) const
+{
+ wxString env_path;
+
+ if( !wxGetEnv( aEnvVar, &env_path ) )
+ return wxEmptyString;
+
+ //return GetRelativePath( m_path, wxString( "$(" + aEnvVar + ")" ) );
+
+ wxString result( m_path );
+
+ if( result.Replace( env_path, wxString( "$(" + aEnvVar + ")" ) ) )
+ return result;
+
+ return wxEmptyString;
+}
+
+
+WIZARD_FPLIB_TABLE::WIZARD_FPLIB_TABLE( wxWindow* aParent ) :
+ WIZARD_FPLIB_TABLE_BASE( aParent ), m_welcomeDlg( m_pages[0] ),
+ m_fileSelectDlg( m_pages[1] ), m_githubListDlg( m_pages[2] ),
+ m_reviewDlg( m_pages[3] ), m_targetDlg( m_pages[4] ), m_selectedFilter( 0 )
+{
+ m_filePicker->SetFilter( getFilterString() );
+
+ // Initialize default download dir
+ wxString default_path;
+ wxGetEnv( FP_LIB_TABLE::GlobalPathEnvVariableName(), &default_path );
+ setDownloadDir( default_path );
+ m_filePicker->SetPath( default_path );
+
+ // Restore the Github url
+ wxString githubUrl;
+
+ wxConfigBase* cfg = Pgm().CommonSettings();
+ cfg->Read( KICAD_FPLIBS_URL_KEY, &githubUrl );
+ cfg->Read( KICAD_FPLIBS_LAST_DOWNLOAD_DIR, &m_lastGithubDownloadDirectory );
+
+
+ if( !m_lastGithubDownloadDirectory.IsEmpty() )
+ {
+ setDownloadDir( m_lastGithubDownloadDirectory );
+ m_filePicker->SetPath( m_lastGithubDownloadDirectory );
+ } else {
+ m_lastGithubDownloadDirectory = default_path;
+ }
+
+ if( githubUrl.IsEmpty() )
+ githubUrl = wxT( "https://github.com/KiCad" );
+
+ SetGithubURL( githubUrl );
+
+ // Give the minimal size to the dialog, which allows displaying any page
+ wxSize minsize;
+
+ for( unsigned ii = 0; ii < m_pages.size(); ii++ )
+ {
+ wxSize size = m_pages[ii]->GetSizer()->CalcMin();
+ minsize.x = std::max( minsize.x, size.x );
+ minsize.y = std::max( minsize.y, size.y );
+ }
+
+ SetMinSize( minsize );
+ SetPageSize( minsize );
+ GetSizer()->SetSizeHints( this );
+ Center();
+
+ if( !m_radioAddGithub->GetValue() && !m_radioAddLocal->GetValue() )
+ m_radioAddLocal->SetValue( true );
+
+ setupDialogOrder();
+ updateGithubControls();
+
+ Connect( wxEVT_RADIOBUTTON, wxCommandEventHandler( WIZARD_FPLIB_TABLE::OnSourceCheck ), NULL, this );
+ Connect( wxEVT_DIRCTRL_SELECTIONCHANGED, wxCommandEventHandler( WIZARD_FPLIB_TABLE::OnSelectFiles ), NULL, this );
+ Connect( wxEVT_CHECKLISTBOX, wxCommandEventHandler( WIZARD_FPLIB_TABLE::OnCheckGithubList ), NULL, this );
+}
+
+
+WIZARD_FPLIB_TABLE::~WIZARD_FPLIB_TABLE()
+{
+ // Use this if you want to store kicad lib URL in pcbnew/cvpcb section config:
+// wxConfigBase* cfg = Kiface().KifaceSettings();
+
+ // Use this if you want to store kicad lib URL in common section config:
+ wxConfigBase* cfg = Pgm().CommonSettings();
+ cfg->Write( KICAD_FPLIBS_URL_KEY, GetGithubURL() );
+}
+
+
+WIZARD_FPLIB_TABLE::LIB_SOURCE WIZARD_FPLIB_TABLE::GetLibSource() const
+{
+ if( m_radioAddGithub->GetValue() )
+ return GITHUB;
+
+ wxASSERT( m_radioAddLocal->GetValue() );
+
+ return LOCAL;
+}
+
+
+WIZARD_FPLIB_TABLE::LIB_SCOPE WIZARD_FPLIB_TABLE::GetLibScope() const
+{
+ if( m_radioGlobal->GetValue() )
+ return GLOBAL;
+
+ wxASSERT( m_radioProject->GetValue() );
+
+ return PROJECT;
+}
+
+
+void WIZARD_FPLIB_TABLE::OnPageChanged( wxWizardEvent& aEvent )
+{
+ SetBitmap( KiBitmap( wizard_add_fplib_icon_xpm ) );
+ enableNext( true );
+
+#ifdef BUILD_GITHUB_PLUGIN
+ if( GetCurrentPage() == m_githubListDlg )
+ setupGithubList();
+ else
+#endif
+ if( GetCurrentPage() == m_fileSelectDlg )
+ setupFileSelect();
+ else if( GetCurrentPage() == m_reviewDlg )
+ setupReview();
+}
+
+
+void WIZARD_FPLIB_TABLE::OnSelectFiles( wxCommandEvent& aEvent )
+{
+ int filterIdx = m_filePicker->GetFilterIndex();
+
+ if( m_selectedFilter != filterIdx )
+ {
+ m_selectedFilter = filterIdx;
+
+ // Process the event again, as in the first iteration we cannot get the list of selected items
+ wxCommandEvent ev( wxEVT_DIRCTRL_SELECTIONCHANGED );
+ AddPendingEvent( ev );
+ return;
+ }
+
+ enableNext( checkFiles() );
+}
+
+
+void WIZARD_FPLIB_TABLE::OnCheckGithubList( wxCommandEvent& aEvent )
+{
+ wxArrayInt dummy;
+
+ enableNext( m_checkListGH->GetCheckedItems( dummy ) > 0 );
+}
+
+
+void WIZARD_FPLIB_TABLE::OnSourceCheck( wxCommandEvent& aEvent )
+{
+ updateGithubControls();
+ setupDialogOrder();
+}
+
+
+void WIZARD_FPLIB_TABLE::OnSelectAllGH( wxCommandEvent& aEvent )
+{
+ for( unsigned int i = 0; i < m_checkListGH->GetCount(); ++i )
+ m_checkListGH->Check( i, true );
+
+ // The list might be empty, e.g. in case of download error
+ wxArrayInt dummy;
+ enableNext( m_checkListGH->GetCheckedItems( dummy ) > 0 );
+}
+
+
+void WIZARD_FPLIB_TABLE::OnUnselectAllGH( wxCommandEvent& aEvent )
+{
+ for( unsigned int i = 0; i < m_checkListGH->GetCount(); ++i )
+ m_checkListGH->Check( i, false );
+
+ enableNext( false );
+}
+
+
+void WIZARD_FPLIB_TABLE::OnChangeSearch( wxCommandEvent& aEvent )
+{
+ wxString searchPhrase = m_searchCtrlGH->GetValue().Lower();
+
+ // Store the current selection
+ wxArrayInt checkedIndices;
+ m_checkListGH->GetCheckedItems( checkedIndices );
+ wxArrayString checkedStrings;
+
+ for( unsigned int i = 0; i < checkedIndices.GetCount(); ++i )
+ checkedStrings.Add( m_checkListGH->GetString( checkedIndices[i] ).AfterLast( '/' ) );
+
+ m_checkListGH->Clear();
+
+ // Rebuild the list, putting the matching entries on the top
+ int matching = 0; // number of entries matching the search phrase
+ for( unsigned int i = 0; i < m_githubLibs.GetCount(); ++i )
+ {
+ const wxString& lib = m_githubLibs[i].AfterLast( '/' );
+ bool wasChecked = ( checkedStrings.Index( lib ) != wxNOT_FOUND );
+ int insertedIdx = -1;
+
+ if( !searchPhrase.IsEmpty() && lib.Lower().Contains( searchPhrase ) )
+ {
+ insertedIdx = m_checkListGH->Insert( lib, matching++ );
+ m_checkListGH->SetSelection( insertedIdx );
+ }
+ else
+ insertedIdx = m_checkListGH->Append( lib );
+
+ if( wasChecked )
+ m_checkListGH->Check( insertedIdx );
+ }
+
+ if( !m_checkListGH->IsEmpty() )
+ m_checkListGH->EnsureVisible( 0 );
+}
+
+
+void WIZARD_FPLIB_TABLE::OnWizardFinished( wxWizardEvent& aEvent )
+{
+#ifdef BUILD_GITHUB_PLUGIN
+ // Shall we download a localy copy of the libraries
+ if( GetLibSource() == GITHUB && m_downloadGithub->GetValue() )
+ {
+ wxString error;
+ wxArrayString libs;
+
+ // Prepare a list of libraries to download
+ for( std::vector<LIBRARY>::const_iterator it = m_libraries.begin();
+ it != m_libraries.end(); ++it )
+ {
+ wxASSERT( it->GetPluginType() == IO_MGR::GITHUB );
+
+ if( it->GetStatus() != LIBRARY::INVALID )
+ libs.Add( it->GetAbsolutePath() );
+ }
+
+ if( !downloadGithubLibsFromList( libs, &error ) )
+ {
+ DisplayError( this, error );
+ m_libraries.clear();
+ }
+ else
+ {
+ // Now libraries are stored locally, so update the paths to point to the download folder
+ for( std::vector<LIBRARY>::iterator it = m_libraries.begin();
+ it != m_libraries.end(); ++it )
+ {
+ wxString path = it->GetAbsolutePath();
+ path.Replace( GetGithubURL(), getDownloadDir() );
+ it->setPath( path );
+ it->setPluginType( IO_MGR::KICAD );
+ }
+ }
+ }
+#endif
+}
+
+
+void WIZARD_FPLIB_TABLE::OnBrowseButtonClick( wxCommandEvent& aEvent )
+{
+ wxString path = getDownloadDir();
+
+ path = wxDirSelector( _("Choose a folder to save the downloaded libraries" ),
+ path, 0, wxDefaultPosition, this );
+
+ if( !path.IsEmpty() && wxDirExists( path ) )
+ {
+ setDownloadDir( path );
+
+ wxConfigBase* cfg = Pgm().CommonSettings();
+ cfg->Write( KICAD_FPLIBS_LAST_DOWNLOAD_DIR, path );
+
+ updateGithubControls();
+ }
+}
+
+
+void WIZARD_FPLIB_TABLE::OnCheckSaveCopy( wxCommandEvent& aEvent )
+{
+ updateGithubControls();
+}
+
+
+bool WIZARD_FPLIB_TABLE::checkFiles() const
+{
+ // Get current selection (files & directories)
+ wxArrayString candidates;
+ m_filePicker->GetPaths( candidates );
+
+ // Workaround, when you change filters "/" is automatically selected
+ int slash_index = candidates.Index( "/", true, true );
+ if( slash_index != wxNOT_FOUND )
+ candidates.RemoveAt( slash_index, 1 );
+
+ if( candidates.IsEmpty() )
+ return false;
+
+ // Verify all the files/folders comply to the selected library type filter
+ for( unsigned int i = 0; i < candidates.GetCount(); ++i )
+ {
+ if( !passesFilter( candidates[i], m_filePicker->GetFilterIndex() ) )
+ return false;
+ }
+
+ return true;
+}
+
+
+#ifdef BUILD_GITHUB_PLUGIN
+void WIZARD_FPLIB_TABLE::getLibsListGithub( wxArrayString& aList )
+{
+ wxBeginBusyCursor();
+
+ // Be sure there is no trailing '/' at the end of the repo name
+ wxString git_url = m_textCtrlGithubURL->GetValue();
+
+ if( git_url.EndsWith( wxT( "/" ) ) )
+ {
+ git_url.RemoveLast();
+ m_textCtrlGithubURL->SetValue( git_url );
+ }
+
+ GITHUB_GETLIBLIST getter( git_url );
+ getter.GetFootprintLibraryList( aList );
+
+ wxEndBusyCursor();
+}
+
+
+// Download the .pretty libraries found in aUrlLis and store them on disk
+// in a master folder
+bool WIZARD_FPLIB_TABLE::downloadGithubLibsFromList( wxArrayString& aUrlList,
+ wxString* aErrorMessage )
+{
+ // Display a progress bar to show the downlaod state
+ wxProgressDialog pdlg( _( "Downloading libraries" ), wxEmptyString, aUrlList.GetCount() );
+
+ // Download libs:
+ for( unsigned ii = 0; ii < aUrlList.GetCount(); ii++ )
+ {
+ wxString& libsrc_name = aUrlList[ii];
+ wxString libdst_name;
+
+ // Extract the lib name from the full URL:
+ wxURI url( libsrc_name );
+ wxFileName fn( url.GetPath() );
+ // Set our local path
+ fn.SetPath( getDownloadDir() );
+ libdst_name = fn.GetFullPath();
+
+ if( !wxDirExists( libdst_name ) )
+ wxMkdir( libdst_name );
+
+ pdlg.Update( ii, libsrc_name );
+ pdlg.Refresh();
+ pdlg.Update();
+
+ try
+ {
+ PLUGIN::RELEASER src( IO_MGR::PluginFind( IO_MGR::GITHUB ) );
+ PLUGIN::RELEASER dst( IO_MGR::PluginFind( IO_MGR::KICAD ) );
+
+ wxArrayString footprints = src->FootprintEnumerate( libsrc_name );
+
+ for( unsigned i = 0; i < footprints.size(); ++i )
+ {
+ std::auto_ptr<MODULE> m( src->FootprintLoad( libsrc_name, footprints[i] ) );
+ dst->FootprintSave( libdst_name, m.get() );
+ // m is deleted here by auto_ptr.
+ }
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ if( aErrorMessage )
+ aErrorMessage->Printf( _( "Error:\n'%s'\nwhile downloading library:\n'%s'" ),
+ GetChars( ioe.errorText ), GetChars( libsrc_name ) );
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+void WIZARD_FPLIB_TABLE::setupGithubList()
+{
+ // Enable 'Next' only if there is at least one library selected
+ wxArrayInt checkedIndices;
+ m_checkListGH->GetCheckedItems( checkedIndices );
+ enableNext( checkedIndices.GetCount() > 0 );
+
+ // Update only if necessary
+ if( m_githubLibs.GetCount() == 0 )
+ getLibsListGithub( m_githubLibs );
+
+ m_searchCtrlGH->Clear();
+
+ // Clear the review list so it will be reloaded
+ m_libraries.clear();
+ m_listCtrlReview->DeleteAllItems();
+}
+#endif /* BUILD_GITHUB_PLUGIN */
+
+
+void WIZARD_FPLIB_TABLE::updateGithubControls()
+{
+#ifndef BUILD_GITHUB_PLUGIN
+ m_radioAddGithub->Enable( false );
+#endif
+
+ // Disable inputs that have no meaning for the selected source
+ bool githubEnabled = ( GetLibSource() == GITHUB );
+ m_textCtrlGithubURL->Enable( githubEnabled );
+ m_downloadGithub->Enable( githubEnabled );
+ m_downloadDir->Enable( githubEnabled && wantLocalCopy() );
+ m_btnBrowse->Enable( githubEnabled && wantLocalCopy() );
+
+ bool valid = !( githubEnabled && wantLocalCopy() ) || wxFileName::IsDirWritable( getDownloadDir() );
+
+ // Do not allow to go further unless there is a valid directory selected
+ m_invalidDir->Show( !valid );
+ enableNext( valid );
+}
+
+
+void WIZARD_FPLIB_TABLE::updateLibraries()
+{
+ // No need to update, the review list is ready
+ if( m_listCtrlReview->GetItemCount() != 0 )
+ return;
+
+ switch( GetLibSource() )
+ {
+ case LOCAL:
+ {
+ wxArrayString libs;
+ m_filePicker->GetPaths( libs );
+
+ // Workaround, when you change filters "/" is automatically selected
+ int slash_index = libs.Index( "/", true, true );
+ if( slash_index != wxNOT_FOUND )
+ libs.RemoveAt( slash_index, 1 );
+
+ m_libraries.reserve( libs.GetCount() );
+
+ for( unsigned int i = 0; i < libs.GetCount(); ++i )
+ m_libraries.push_back( libs[i] );
+ }
+ break;
+
+ case GITHUB:
+ {
+ wxArrayInt checkedLibs;
+ m_checkListGH->GetCheckedItems( checkedLibs );
+
+ m_libraries.reserve( checkedLibs.GetCount() );
+
+ for( unsigned int i = 0; i < checkedLibs.GetCount(); ++i )
+ m_libraries.push_back( GetGithubURL() + "/" + m_checkListGH->GetString( checkedLibs[i] ) );
+ }
+ break;
+
+ default:
+ wxASSERT( false );
+ break;
+ }
+}
+
+
+void WIZARD_FPLIB_TABLE::setupDialogOrder()
+{
+ // Alternate the wizard pages flow depending on the selected option
+ switch( GetLibSource() )
+ {
+ case LOCAL:
+ m_welcomeDlg->SetNext( m_fileSelectDlg );
+ m_fileSelectDlg->SetPrev( m_welcomeDlg );
+
+ m_fileSelectDlg->SetNext( m_reviewDlg );
+ m_reviewDlg->SetPrev( m_fileSelectDlg );
+ break;
+
+ case GITHUB:
+ m_welcomeDlg->SetNext( m_githubListDlg );
+ m_githubListDlg->SetPrev( m_welcomeDlg );
+
+ m_githubListDlg->SetNext( m_reviewDlg );
+ m_reviewDlg->SetPrev( m_githubListDlg );
+ break;
+
+ default:
+ wxASSERT( false );
+ break;
+ }
+}
+
+
+void WIZARD_FPLIB_TABLE::setupFileSelect()
+{
+ // Disable the button until something is selected
+ enableNext( checkFiles() );
+
+ // Clear the review list so it will be reloaded
+ m_libraries.clear();
+ m_listCtrlReview->DeleteAllItems();
+}
+
+
+void WIZARD_FPLIB_TABLE::setupReview()
+{
+ wxBeginBusyCursor();
+ updateLibraries();
+
+ int libTotalCount = m_libraries.size();
+ int libCount = 0;
+ bool validate = true;
+ wxProgressDialog progressDlg( _( "Please wait..." ), _( "Validating libraries" ),
+ libTotalCount, this,
+ wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_AUTO_HIDE );
+
+ m_dvLibName->SetWidth( 280 );
+
+ // Prepare the review list
+ m_listCtrlReview->DeleteAllItems();
+
+ for( std::vector<LIBRARY>::iterator it = m_libraries.begin(); it != m_libraries.end(); ++it )
+ {
+ wxVector<wxVariant> row;
+ LIBRARY::STATUS status = it->GetStatus();
+
+ // Check if the library contents is valid
+ if( status == LIBRARY::NOT_CHECKED && validate )
+ {
+ it->Test();
+ status = it->GetStatus();
+ }
+
+ row.push_back( wxVariant( it->GetDescription() ) );
+
+ switch( it->GetStatus() )
+ {
+ case LIBRARY::NOT_CHECKED:
+ row.push_back( wxVariant( _( "NOT CHECKED" ) ) );
+ break;
+
+ case LIBRARY::OK:
+ row.push_back( wxVariant( _( "OK" ) ) );
+ break;
+
+ case LIBRARY::INVALID:
+ row.push_back( wxVariant( _( "INVALID" ) ) );
+ break;
+ }
+
+ row.push_back( wxVariant( it->GetPluginName() ) );
+
+ m_listCtrlReview->AppendItem( row );
+
+ ++libCount;
+ if( !progressDlg.Update( libCount, wxString::Format( _( "Validating libraries %d/%d" ),
+ libCount, libTotalCount ) ) )
+ validate = false;
+ }
+
+ // The list should never be empty, but who knows?
+ enableNext( m_listCtrlReview->GetItemCount() > 0 );
+
+ wxEndBusyCursor();
+}
diff --git a/pcbnew/dialogs/wizard_add_fplib.h b/pcbnew/dialogs/wizard_add_fplib.h
new file mode 100644
index 0000000..94ba00b
--- /dev/null
+++ b/pcbnew/dialogs/wizard_add_fplib.h
@@ -0,0 +1,279 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ * Copyright (C) 2014-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wizard_add_fplib_base.h>
+#include <io_mgr.h>
+#include <boost/optional.hpp>
+
+class KIWAY_PLAYER;
+
+class WIZARD_FPLIB_TABLE : public WIZARD_FPLIB_TABLE_BASE
+{
+public:
+ WIZARD_FPLIB_TABLE( wxWindow* aParent );
+ ~WIZARD_FPLIB_TABLE();
+
+ ///> Source of the libraries (local files or Github)
+ enum LIB_SOURCE { LOCAL, GITHUB };
+
+ ///> Scope (global/project)
+ enum LIB_SCOPE { GLOBAL = 1, PROJECT = 2 };
+
+ /**
+ * Function GetFirstPage
+ * Returns the welcoming page for the wizard.
+ */
+ inline wxWizardPage* GetFirstPage() const
+ {
+ return m_welcomeDlg;
+ }
+
+ /**
+ * Function GetGithubURL
+ * Returns the current Github repository URL set in the wizard.
+ */
+ inline wxString GetGithubURL() const
+ {
+ return m_textCtrlGithubURL->GetValue();
+ }
+
+ /**
+ * Function SetGithubURL
+ * Sets the current Github repository URL used by the wizard.
+ * @param aUrl is the new URL to be applied.
+ */
+ inline void SetGithubURL( const wxString& aUrl )
+ {
+ m_textCtrlGithubURL->SetValue( aUrl );
+ }
+
+ /**
+ * Function GetLibSource
+ * Returns the source of libraries (local / Github).
+ */
+ LIB_SOURCE GetLibSource() const;
+
+ /**
+ * Function GetLibScope
+ * Returns the scope for the added libraries (global / project specific).
+ */
+ LIB_SCOPE GetLibScope() const;
+
+ // Wizard event handlers
+ void OnSourceCheck( wxCommandEvent& aEvent );
+ void OnSelectFiles( wxCommandEvent& aEvent );
+ void OnCheckGithubList( wxCommandEvent& aEvent );
+ void OnPageChanged( wxWizardEvent& aEvent );
+ void OnSelectAllGH( wxCommandEvent& aEvent );
+ void OnUnselectAllGH( wxCommandEvent& aEvent );
+ void OnChangeSearch( wxCommandEvent& aEvent );
+ void OnWizardFinished( wxWizardEvent& aEvent );
+ void OnBrowseButtonClick( wxCommandEvent& aEvent );
+ void OnCheckSaveCopy( wxCommandEvent& aEvent );
+
+ class LIBRARY
+ {
+ public:
+ LIBRARY( const wxString& aPath, const wxString& aDescription = wxEmptyString );
+ ~LIBRARY()
+ {
+ }
+
+ ///> Possible states of validation.
+ enum STATUS { OK, INVALID, NOT_CHECKED };
+
+ /**
+ * Function Test
+ * Uses the associated plugin to validate the library contents.
+ * @return True if the library and the matched plugin type are valid.
+ */
+ bool Test();
+
+ /**
+ * Function GetPluginType
+ * Returns the plugin type, autodetected basing on the path.
+ * @return Returns empty boost::optional if the type could not be autodetected.
+ */
+ inline boost::optional<IO_MGR::PCB_FILE_T> GetPluginType() const
+ {
+ return m_plugin;
+ }
+
+ /**
+ * Function GetPluginName
+ * Returns the plugin name, as used in the FPLIB table editor.
+ */
+ wxString GetPluginName() const;
+
+ /**
+ * Function GetAbsolutePath
+ * Returns the absolute path for the library.
+ */
+ inline const wxString& GetAbsolutePath() const
+ {
+ return m_path;
+ }
+
+ /**
+ * Function GetRelativePath
+ * Returns the relative path, based on the input path with the base part replaced.
+ * @param aBase is the base for the relative path.
+ * @param aSubstitution is the string to be replace the base path.
+ * @return Adjusted path if possible, or the absolute path when it is not possible.
+ */
+ wxString GetRelativePath( const wxString& aBase, const wxString& aSubstitution = wxEmptyString ) const;
+
+ /**
+ * Function GetAutoPath
+ * Returns path that is either absolute or related to KISYSMOD/KIPRJMOD if the files
+ * are stored within one of the mentioned paths.
+ * @param aScoep is the scope for the library. It determines the environmental variables
+ * that are used to check the path (GLOBAL scope checks only KISYSMOD, while PROJECT
+ * scope checks both KISYSMOD & KIPRJMOD).
+ */
+ wxString GetAutoPath( LIB_SCOPE aScope ) const;
+
+ /**
+ * Function GetDescription
+ * Returns the description for the library. If it is not specified in the constructor,
+ * it is just the filename.
+ */
+ wxString GetDescription() const;
+
+ /**
+ * Function GetStatus
+ * Returns the validity status for the library. It requires running Test() before, to get
+ * a result different than NOT_CHECKED.
+ */
+ STATUS GetStatus() const
+ {
+ return m_status;
+ }
+
+ protected:
+ inline void setPath( const wxString& aPath )
+ {
+ m_path = aPath;
+ }
+
+ inline void setPluginType( IO_MGR::PCB_FILE_T aType )
+ {
+ m_plugin = aType;
+ }
+
+ /**
+ * Function replaceEnv
+ * replaces path with environmental variable if applicable.
+ * @param aEnvVar is the environmental variable that should be substituted.
+ * @param aFilePath determines if the path is a file path (contrary to e.g. http address).
+ */
+ wxString replaceEnv( const wxString& aEnvVar, bool aFilePath = true ) const;
+
+ wxString m_path;
+ wxString m_description;
+ boost::optional<IO_MGR::PCB_FILE_T> m_plugin;
+ STATUS m_status;
+
+ friend class WIZARD_FPLIB_TABLE;
+ };
+
+ /**
+ * Function GetLibraries
+ * Returns libraries selected by the user.
+ */
+ const std::vector<LIBRARY>& GetLibraries() const
+ {
+ return m_libraries;
+ }
+
+
+protected:
+ // Initialization of wizard pages
+ void setupDialogOrder();
+ void setupGithubList();
+ void setupFileSelect();
+ void setupReview();
+
+ ///> Checks the selection in file picker
+ bool checkFiles() const;
+
+ ///> Sets the target directory for libraries downloaded from Github
+ void setDownloadDir( const wxString& aDir )
+ {
+ m_downloadDir->SetLabel( aDir );
+ }
+
+ ///> Gets the current target for downloaded libraries
+ inline wxString getDownloadDir()
+ {
+ return m_downloadDir->GetLabel();
+ }
+
+ ///> Downloads the list of Github libraries
+ void getLibsListGithub( wxArrayString& aList );
+
+ ///> Saves a list of Github libraries locally.
+ bool downloadGithubLibsFromList( wxArrayString& aUrlList, wxString* aErrorMessage );
+
+ ///> Does the user want a local copy of Github libraries?
+ inline bool wantLocalCopy() const { return m_downloadGithub->GetValue(); }
+
+ ///> Enables Github widgets depending on the selected options.
+ void updateGithubControls();
+
+ ///> Updates m_libraries basing on dialogs contents
+ void updateLibraries();
+
+ ///> Enables/disable 'Next' button
+ inline void enableNext( bool aEnable )
+ {
+ wxWindow* nextBtn = FindWindowById( wxID_FORWARD );
+
+ if( nextBtn )
+ nextBtn->Enable( aEnable );
+ }
+
+ ///> Cache for the downloaded Github library list
+ wxArrayString m_githubLibs;
+
+ ///> Libraries selected in the wizard
+ std::vector<LIBRARY> m_libraries;
+
+ // Aliases for wizard pages to make code more readable
+ wxWizardPageSimple* const m_welcomeDlg;
+ wxWizardPageSimple* const m_fileSelectDlg;
+ wxWizardPageSimple* const m_githubListDlg;
+ wxWizardPageSimple* const m_reviewDlg;
+ wxWizardPageSimple* const m_targetDlg;
+
+ // Since the same event is used for changing the selection/filter type, we need a way to
+ // determine what's the real cause of the event. Therefore here we store the number of the
+ // selected file type filter.
+ int m_selectedFilter;
+
+ // path to the most recently used download directory from Github.
+ wxString m_lastGithubDownloadDirectory;
+};
diff --git a/pcbnew/dialogs/wizard_add_fplib_base.cpp b/pcbnew/dialogs/wizard_add_fplib_base.cpp
new file mode 100644
index 0000000..343d898
--- /dev/null
+++ b/pcbnew/dialogs/wizard_add_fplib_base.cpp
@@ -0,0 +1,247 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "wizard_add_fplib_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+WIZARD_FPLIB_TABLE_BASE::WIZARD_FPLIB_TABLE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxBitmap& bitmap, const wxPoint& pos, long style )
+{
+ this->Create( parent, id, title, bitmap, pos, style );
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxWizardPageSimple* m_wizPage1 = new wxWizardPageSimple( this, NULL, NULL, wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ) );
+ m_pages.Add( m_wizPage1 );
+
+ m_wizPage1->SetMinSize( wxSize( 720,480 ) );
+
+ wxBoxSizer* bSizer1;
+ bSizer1 = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer112;
+ fgSizer112 = new wxFlexGridSizer( 3, 1, 0, 0 );
+ fgSizer112->AddGrowableRow( 1 );
+ fgSizer112->SetFlexibleDirection( wxBOTH );
+ fgSizer112->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText1 = new wxStaticText( m_wizPage1, wxID_ANY, _("Welcome to the Add Footprint Libraries Wizard!\n\nPlease select the source for the libraries to add:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1->Wrap( -1 );
+ fgSizer112->Add( m_staticText1, 1, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer19;
+ bSizer19 = new wxBoxSizer( wxVERTICAL );
+
+ m_radioAddLocal = new wxRadioButton( m_wizPage1, wxID_ANY, _("Files on my computer"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer19->Add( m_radioAddLocal, 0, wxALL|wxEXPAND, 5 );
+
+ wxFlexGridSizer* m_githubSizer;
+ m_githubSizer = new wxFlexGridSizer( 0, 2, 0, 0 );
+ m_githubSizer->SetFlexibleDirection( wxBOTH );
+ m_githubSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_radioAddGithub = new wxRadioButton( m_wizPage1, wxID_ANY, _("Github repository"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_githubSizer->Add( m_radioAddGithub, 0, wxALL|wxEXPAND, 5 );
+
+ m_textCtrlGithubURL = new wxTextCtrl( m_wizPage1, wxID_ANY, _("https://github.com/KiCad"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_textCtrlGithubURL->SetMinSize( wxSize( 300,-1 ) );
+
+ m_githubSizer->Add( m_textCtrlGithubURL, 1, wxALL|wxEXPAND, 5 );
+
+
+ m_githubSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_downloadGithub = new wxCheckBox( m_wizPage1, wxID_ANY, _("Save a local copy to:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_downloadGithub->SetValue(true);
+ m_githubSizer->Add( m_downloadGithub, 0, wxALL, 5 );
+
+
+ m_githubSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer9;
+ bSizer9 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_downloadDir = new wxStaticText( m_wizPage1, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_downloadDir->Wrap( -1 );
+ m_downloadDir->SetMinSize( wxSize( 300,-1 ) );
+
+ bSizer9->Add( m_downloadDir, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_btnBrowse = new wxButton( m_wizPage1, wxID_ANY, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer9->Add( m_btnBrowse, 0, wxALL, 5 );
+
+
+ m_githubSizer->Add( bSizer9, 1, wxEXPAND, 5 );
+
+
+ m_githubSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_invalidDir = new wxStaticText( m_wizPage1, wxID_ANY, _("It is not possible to write in the selected directory.\nPlease choose another one."), wxDefaultPosition, wxDefaultSize, 0 );
+ m_invalidDir->Wrap( -1 );
+ m_invalidDir->SetForegroundColour( wxColour( 255, 0, 0 ) );
+
+ m_githubSizer->Add( m_invalidDir, 0, wxALL, 5 );
+
+
+ bSizer19->Add( m_githubSizer, 1, wxEXPAND, 5 );
+
+
+ fgSizer112->Add( bSizer19, 1, wxEXPAND, 5 );
+
+
+ bSizer1->Add( fgSizer112, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizerOfficialRepo;
+ bSizerOfficialRepo = new wxBoxSizer( wxHORIZONTAL );
+
+ m_bitmapRepo = new wxStaticBitmap( m_wizPage1, wxID_ANY, wxArtProvider::GetBitmap( wxART_INFORMATION, wxART_OTHER ), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerOfficialRepo->Add( m_bitmapRepo, 0, wxALL, 5 );
+
+
+ bSizerOfficialRepo->Add( 0, 0, 0, wxRIGHT|wxLEFT, 10 );
+
+ m_hyperlinkGithubKicad = new wxHyperlinkCtrl( m_wizPage1, wxID_ANY, _("Visit our official Kicad repository on Github and get more libraries"), wxT("https://github.com/KiCad"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE );
+ bSizerOfficialRepo->Add( m_hyperlinkGithubKicad, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizer1->Add( bSizerOfficialRepo, 0, wxEXPAND, 5 );
+
+
+ m_wizPage1->SetSizer( bSizer1 );
+ m_wizPage1->Layout();
+ wxWizardPageSimple* m_wizPage2_Local = new wxWizardPageSimple( this, NULL, NULL, wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ) );
+ m_pages.Add( m_wizPage2_Local );
+
+ wxBoxSizer* bSizer8;
+ bSizer8 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText7 = new wxStaticText( m_wizPage2_Local, wxID_ANY, _("Select files or folders to add:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText7->Wrap( -1 );
+ bSizer8->Add( m_staticText7, 0, wxALL, 5 );
+
+ m_filePicker = new wxGenericDirCtrl( m_wizPage2_Local, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDIRCTRL_3D_INTERNAL|wxDIRCTRL_MULTIPLE|wxDIRCTRL_SHOW_FILTERS|wxSUNKEN_BORDER, wxEmptyString, 0 );
+
+ m_filePicker->ShowHidden( false );
+ bSizer8->Add( m_filePicker, 1, wxEXPAND | wxALL, 5 );
+
+
+ m_wizPage2_Local->SetSizer( bSizer8 );
+ m_wizPage2_Local->Layout();
+ bSizer8->Fit( m_wizPage2_Local );
+ wxWizardPageSimple* m_wizPage2_Github = new wxWizardPageSimple( this, NULL, NULL, wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ) );
+ m_pages.Add( m_wizPage2_Github );
+
+ wxBoxSizer* bSizer111;
+ bSizer111 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText112 = new wxStaticText( m_wizPage2_Github, wxID_ANY, _("Select Github libraries to add:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText112->Wrap( -1 );
+ bSizer111->Add( m_staticText112, 0, wxALL|wxEXPAND, 5 );
+
+ wxArrayString m_checkListGHChoices;
+ m_checkListGH = new wxCheckListBox( m_wizPage2_Github, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_checkListGHChoices, wxLB_MULTIPLE|wxLB_NEEDED_SB );
+ bSizer111->Add( m_checkListGH, 1, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer7;
+ bSizer7 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_btnSelectAllGH = new wxButton( m_wizPage2_Github, wxID_ANY, _("Select all"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer7->Add( m_btnSelectAllGH, 1, wxALL, 5 );
+
+ m_btnUnselectAllGH = new wxButton( m_wizPage2_Github, wxID_ANY, _("Unselect all"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer7->Add( m_btnUnselectAllGH, 1, wxALL, 5 );
+
+
+ bSizer7->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_searchCtrlGH = new wxSearchCtrl( m_wizPage2_Github, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ #ifndef __WXMAC__
+ m_searchCtrlGH->ShowSearchButton( true );
+ #endif
+ m_searchCtrlGH->ShowCancelButton( false );
+ bSizer7->Add( m_searchCtrlGH, 2, wxALL, 5 );
+
+
+ bSizer111->Add( bSizer7, 0, wxEXPAND, 5 );
+
+
+ m_wizPage2_Github->SetSizer( bSizer111 );
+ m_wizPage2_Github->Layout();
+ bSizer111->Fit( m_wizPage2_Github );
+ wxWizardPageSimple* m_wizPage3_Review = new wxWizardPageSimple( this, NULL, NULL, wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ) );
+ m_pages.Add( m_wizPage3_Review );
+
+ wxBoxSizer* bSizer1111;
+ bSizer1111 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText1121 = new wxStaticText( m_wizPage3_Review, wxID_ANY, _("Review and confirm the changes to the libraries:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1121->Wrap( -1 );
+ bSizer1111->Add( m_staticText1121, 0, wxALL|wxEXPAND, 5 );
+
+ m_listCtrlReview = new wxDataViewListCtrl( m_wizPage3_Review, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_HORIZ_RULES|wxDV_ROW_LINES|wxDV_VERT_RULES );
+ m_dvLibName = m_listCtrlReview->AppendTextColumn( _("Library") );
+ m_dvLibStatus = m_listCtrlReview->AppendTextColumn( _("Status") );
+ m_dvLibFormat = m_listCtrlReview->AppendTextColumn( _("Format") );
+ bSizer1111->Add( m_listCtrlReview, 1, wxALL|wxEXPAND, 5 );
+
+
+ m_wizPage3_Review->SetSizer( bSizer1111 );
+ m_wizPage3_Review->Layout();
+ bSizer1111->Fit( m_wizPage3_Review );
+ wxWizardPageSimple* m_wizPage4_SelectTarget = new wxWizardPageSimple( this, NULL, NULL, wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ) );
+ m_pages.Add( m_wizPage4_SelectTarget );
+
+ wxBoxSizer* bSizer12;
+ bSizer12 = new wxBoxSizer( wxVERTICAL );
+
+ m_staticText12 = new wxStaticText( m_wizPage4_SelectTarget, wxID_ANY, _("Where do you wish the new libraries to be added:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText12->Wrap( -1 );
+ bSizer12->Add( m_staticText12, 0, wxALL|wxEXPAND, 5 );
+
+ m_radioGlobal = new wxRadioButton( m_wizPage4_SelectTarget, wxID_ANY, _("To global library configuration (visible by all projects)"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer12->Add( m_radioGlobal, 0, wxALL|wxEXPAND, 5 );
+
+ m_radioProject = new wxRadioButton( m_wizPage4_SelectTarget, wxID_ANY, _("To the current project only"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer12->Add( m_radioProject, 0, wxALL|wxEXPAND, 5 );
+
+
+ m_wizPage4_SelectTarget->SetSizer( bSizer12 );
+ m_wizPage4_SelectTarget->Layout();
+ bSizer12->Fit( m_wizPage4_SelectTarget );
+
+ this->Centre( wxBOTH );
+
+ for ( unsigned int i = 1; i < m_pages.GetCount(); i++ )
+ {
+ m_pages.Item( i )->SetPrev( m_pages.Item( i - 1 ) );
+ m_pages.Item( i - 1 )->SetNext( m_pages.Item( i ) );
+ }
+
+ // Connect Events
+ this->Connect( wxID_ANY, wxEVT_WIZARD_FINISHED, wxWizardEventHandler( WIZARD_FPLIB_TABLE_BASE::OnWizardFinished ) );
+ this->Connect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( WIZARD_FPLIB_TABLE_BASE::OnPageChanged ) );
+ this->Connect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler( WIZARD_FPLIB_TABLE_BASE::OnPageChanging ) );
+ m_downloadGithub->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnCheckSaveCopy ), NULL, this );
+ m_btnBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnBrowseButtonClick ), NULL, this );
+ m_btnSelectAllGH->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnSelectAllGH ), NULL, this );
+ m_btnUnselectAllGH->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnUnselectAllGH ), NULL, this );
+ m_searchCtrlGH->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnChangeSearch ), NULL, this );
+}
+
+WIZARD_FPLIB_TABLE_BASE::~WIZARD_FPLIB_TABLE_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxID_ANY, wxEVT_WIZARD_FINISHED, wxWizardEventHandler( WIZARD_FPLIB_TABLE_BASE::OnWizardFinished ) );
+ this->Disconnect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( WIZARD_FPLIB_TABLE_BASE::OnPageChanged ) );
+ this->Disconnect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler( WIZARD_FPLIB_TABLE_BASE::OnPageChanging ) );
+ m_downloadGithub->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnCheckSaveCopy ), NULL, this );
+ m_btnBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnBrowseButtonClick ), NULL, this );
+ m_btnSelectAllGH->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnSelectAllGH ), NULL, this );
+ m_btnUnselectAllGH->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnUnselectAllGH ), NULL, this );
+ m_searchCtrlGH->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnChangeSearch ), NULL, this );
+
+ m_pages.Clear();
+}
diff --git a/pcbnew/dialogs/wizard_add_fplib_base.fbp b/pcbnew/dialogs/wizard_add_fplib_base.fbp
new file mode 100644
index 0000000..91e3d66
--- /dev/null
+++ b/pcbnew/dialogs/wizard_add_fplib_base.fbp
@@ -0,0 +1,2389 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">wizard_add_fplib_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">MyProject1</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Wizard" expanded="1">
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON</property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">WIZARD_FPLIB_TABLE_BASE</property>
+ <property name="pos"></property>
+ <property name="size">720,417</property>
+ <property name="style">wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER</property>
+ <property name="subclass">; </property>
+ <property name="title">Add Footprint Libraries Wizard</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <event name="OnWizardCancel"></event>
+ <event name="OnWizardFinished">OnWizardFinished</event>
+ <event name="OnWizardHelp"></event>
+ <event name="OnWizardPageChanged">OnPageChanged</event>
+ <event name="OnWizardPageChanging">OnPageChanging</event>
+ <object class="WizardPageSimple" expanded="1">
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">720,480</property>
+ <property name="name">m_wizPage1</property>
+ <property name="permission">protected</property>
+ <property name="pos"></property>
+ <property name="size">720,480</property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer1</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">1</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows">1</property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer112</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">3</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Welcome to the Add Footprint Libraries Wizard!&#x0A;&#x0A;Please select the source for the libraries to add:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer19</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Files on my computer</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioAddLocal</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">2</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols"></property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_githubSizer</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Github repository</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioAddGithub</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">300,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlGithubURL</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">https://github.com/KiCad</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">1</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Save a local copy to:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_downloadGithub</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox">OnCheckSaveCopy</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer9</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label"></property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">300,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_downloadDir</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Browse</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_btnBrowse</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnBrowseButtonClick</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg">255,0,0</property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">It is not possible to write in the selected directory.&#x0A;Please choose another one.</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_invalidDir</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerOfficialRepo</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBitmap" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_INFORMATION; wxART_OTHER</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_bitmapRepo</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">10</property>
+ <property name="flag">wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxHyperlinkCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="hover_color"></property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Visit our official Kicad repository on Github and get more libraries</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_hyperlinkGithubKicad</property>
+ <property name="normal_color"></property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxHL_DEFAULT_STYLE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="url">https://github.com/KiCad</property>
+ <property name="visited_color"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHyperlink"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="WizardPageSimple" expanded="0">
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">m_wizPage2_Local</property>
+ <property name="permission">protected</property>
+ <property name="pos"></property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer8</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Select files or folders to add:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText7</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxGenericDirCtrl" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="defaultfilter">0</property>
+ <property name="defaultfolder"></property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="filter"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_filePicker</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="show_hidden">0</property>
+ <property name="size"></property>
+ <property name="style">wxDIRCTRL_3D_INTERNAL|wxDIRCTRL_MULTIPLE|wxDIRCTRL_SHOW_FILTERS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxSUNKEN_BORDER</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnTreeBeginDrag"></event>
+ <event name="OnTreeBeginLabelEdit"></event>
+ <event name="OnTreeBeginRDrag"></event>
+ <event name="OnTreeDeleteItem"></event>
+ <event name="OnTreeEndDrag"></event>
+ <event name="OnTreeEndLabelEdit"></event>
+ <event name="OnTreeItemActivated"></event>
+ <event name="OnTreeItemCollapsed"></event>
+ <event name="OnTreeItemCollapsing"></event>
+ <event name="OnTreeItemExpanded"></event>
+ <event name="OnTreeItemExpanding"></event>
+ <event name="OnTreeItemMenu"></event>
+ <event name="OnTreeItemMiddleClick"></event>
+ <event name="OnTreeItemRightClick"></event>
+ <event name="OnTreeKeyDown"></event>
+ <event name="OnTreeSelChanged"></event>
+ <event name="OnTreeSelChanging"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="WizardPageSimple" expanded="1">
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">m_wizPage2_Github</property>
+ <property name="permission">protected</property>
+ <property name="pos"></property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer111</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Select Github libraries to add:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText112</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxCheckListBox" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkListGH</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLB_MULTIPLE|wxLB_NEEDED_SB</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckListBox"></event>
+ <event name="OnCheckListBoxDClick"></event>
+ <event name="OnCheckListBoxToggled"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer7</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Select all</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_btnSelectAllGH</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnSelectAllGH</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">1</property>
+ <object class="wxButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Unselect all</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_btnUnselectAllGH</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnUnselectAllGH</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">2</property>
+ <object class="wxSearchCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="cancel_button">0</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_searchCtrlGH</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="search_button">1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnCancelButton"></event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSearchButton"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText">OnChangeSearch</event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="WizardPageSimple" expanded="0">
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">m_wizPage3_Review</property>
+ <property name="permission">protected</property>
+ <property name="pos"></property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="0">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer1111</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Review and confirm the changes to the libraries:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText1121</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxDataViewListCtrl" expanded="0">
+ <property name="bg"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">m_listCtrlReview</property>
+ <property name="permission">protected</property>
+ <property name="pos"></property>
+ <property name="size"></property>
+ <property name="style">wxDV_HORIZ_RULES|wxDV_ROW_LINES|wxDV_VERT_RULES</property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnDataViewListCtrlColumnHeaderClick"></event>
+ <event name="OnDataViewListCtrlColumnHeaderRightClick"></event>
+ <event name="OnDataViewListCtrlColumnReordered"></event>
+ <event name="OnDataViewListCtrlColumnSorted"></event>
+ <event name="OnDataViewListCtrlItemActivated"></event>
+ <event name="OnDataViewListCtrlItemBeginDrag"></event>
+ <event name="OnDataViewListCtrlItemCollapsed"></event>
+ <event name="OnDataViewListCtrlItemCollapsing"></event>
+ <event name="OnDataViewListCtrlItemContextMenu"></event>
+ <event name="OnDataViewListCtrlItemDrop"></event>
+ <event name="OnDataViewListCtrlItemDropPossible"></event>
+ <event name="OnDataViewListCtrlItemEditingDone"></event>
+ <event name="OnDataViewListCtrlItemEditingStarted"></event>
+ <event name="OnDataViewListCtrlItemExpanded"></event>
+ <event name="OnDataViewListCtrlItemExpanding"></event>
+ <event name="OnDataViewListCtrlItemStartEditing"></event>
+ <event name="OnDataViewListCtrlItemValueChanged"></event>
+ <event name="OnDataViewListCtrlSelectionChanged"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="dataViewListColumn" expanded="0">
+ <property name="label">Library</property>
+ <property name="name">m_dvLibName</property>
+ <property name="permission">protected</property>
+ <property name="type">Text</property>
+ </object>
+ <object class="dataViewListColumn" expanded="0">
+ <property name="label">Status</property>
+ <property name="name">m_dvLibStatus</property>
+ <property name="permission">protected</property>
+ <property name="type">Text</property>
+ </object>
+ <object class="dataViewListColumn" expanded="0">
+ <property name="label">Format</property>
+ <property name="name">m_dvLibFormat</property>
+ <property name="permission">protected</property>
+ <property name="type">Text</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="WizardPageSimple" expanded="1">
+ <property name="bg"></property>
+ <property name="bitmap">Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">m_wizPage4_SelectTarget</property>
+ <property name="permission">protected</property>
+ <property name="pos"></property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer12</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Where do you wish the new libraries to be added:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText12</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">To global library configuration (visible by all projects)</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioGlobal</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioButton" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">To the current project only</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_radioProject</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioButton"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/wizard_add_fplib_base.h b/pcbnew/dialogs/wizard_add_fplib_base.h
new file mode 100644
index 0000000..4535aee
--- /dev/null
+++ b/pcbnew/dialogs/wizard_add_fplib_base.h
@@ -0,0 +1,94 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __WIZARD_ADD_FPLIB_BASE_H__
+#define __WIZARD_ADD_FPLIB_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/radiobut.h>
+#include <wx/textctrl.h>
+#include <wx/checkbox.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/statbmp.h>
+#include <wx/hyperlink.h>
+#include <wx/dirctrl.h>
+#include <wx/checklst.h>
+#include <wx/srchctrl.h>
+#include <wx/dataview.h>
+#include <wx/wizard.h>
+#include <wx/dynarray.h>
+WX_DEFINE_ARRAY_PTR( wxWizardPageSimple*, WizardPages );
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class WIZARD_FPLIB_TABLE_BASE
+///////////////////////////////////////////////////////////////////////////////
+class WIZARD_FPLIB_TABLE_BASE : public wxWizard
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText1;
+ wxRadioButton* m_radioAddLocal;
+ wxRadioButton* m_radioAddGithub;
+ wxTextCtrl* m_textCtrlGithubURL;
+ wxCheckBox* m_downloadGithub;
+ wxStaticText* m_downloadDir;
+ wxButton* m_btnBrowse;
+ wxStaticText* m_invalidDir;
+ wxStaticBitmap* m_bitmapRepo;
+ wxHyperlinkCtrl* m_hyperlinkGithubKicad;
+ wxStaticText* m_staticText7;
+ wxGenericDirCtrl* m_filePicker;
+ wxStaticText* m_staticText112;
+ wxCheckListBox* m_checkListGH;
+ wxButton* m_btnSelectAllGH;
+ wxButton* m_btnUnselectAllGH;
+ wxSearchCtrl* m_searchCtrlGH;
+ wxStaticText* m_staticText1121;
+ wxDataViewListCtrl* m_listCtrlReview;
+ wxDataViewColumn* m_dvLibName;
+ wxDataViewColumn* m_dvLibStatus;
+ wxDataViewColumn* m_dvLibFormat;
+ wxStaticText* m_staticText12;
+ wxRadioButton* m_radioGlobal;
+ wxRadioButton* m_radioProject;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnWizardFinished( wxWizardEvent& event ) { event.Skip(); }
+ virtual void OnPageChanged( wxWizardEvent& event ) { event.Skip(); }
+ virtual void OnPageChanging( wxWizardEvent& event ) { event.Skip(); }
+ virtual void OnCheckSaveCopy( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnBrowseButtonClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnSelectAllGH( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnUnselectAllGH( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnChangeSearch( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ WIZARD_FPLIB_TABLE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Add Footprint Libraries Wizard"), const wxBitmap& bitmap = wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ), const wxPoint& pos = wxDefaultPosition, long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER );
+ WizardPages m_pages;
+ ~WIZARD_FPLIB_TABLE_BASE();
+
+};
+
+#endif //__WIZARD_ADD_FPLIB_BASE_H__
diff --git a/pcbnew/dimension.cpp b/pcbnew/dimension.cpp
new file mode 100644
index 0000000..db08445
--- /dev/null
+++ b/pcbnew/dimension.cpp
@@ -0,0 +1,466 @@
+/**
+ * @file dimension.cpp
+ * @brief Dialog and code for editing a dimension object.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+#include <drawtxt.h>
+#include <dialog_helpers.h>
+#include <macros.h>
+#include <base_units.h>
+
+#include <class_board.h>
+#include <class_pcb_text.h>
+#include <class_dimension.h>
+
+#include <pcbnew.h>
+#include <dialog_dimension_editor_base.h>
+#include <class_pcb_layer_box_selector.h>
+
+/* Local functions */
+static void BuildDimension( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase );
+
+static void MoveDimensionText( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase );
+static void AbortMoveDimensionText( EDA_DRAW_PANEL* aPanel, wxDC* aDC );
+
+
+/* Local variables : */
+static int status_dimension; /* Used in dimension creation:
+ * = 0 : initial value: no dimension in progress
+ * = 1 : First point created
+ * = 2 : Second point created, the text must be placed */
+
+/*
+ * A dimension has this shape:
+ * It has 2 reference points, and a text
+ * | |
+ * | dist |
+ * |<---------->|
+ * | |
+ *
+ */
+
+
+/*********************************/
+/* class DIALOG_DIMENSION_EDITOR */
+/*********************************/
+
+class DIALOG_DIMENSION_EDITOR : public DIALOG_DIMENSION_EDITOR_BASE
+{
+private:
+
+ PCB_EDIT_FRAME* m_Parent;
+ wxDC* m_DC;
+ DIMENSION* CurrentDimension;
+
+public:
+
+ // Constructor and destructor
+ DIALOG_DIMENSION_EDITOR( PCB_EDIT_FRAME* aParent, DIMENSION* aDimension, wxDC* aDC );
+ ~DIALOG_DIMENSION_EDITOR()
+ {
+ }
+
+
+private:
+ void OnCancelClick( wxCommandEvent& event );
+ void OnOKClick( wxCommandEvent& event );
+};
+
+
+DIALOG_DIMENSION_EDITOR::DIALOG_DIMENSION_EDITOR( PCB_EDIT_FRAME* aParent,
+ DIMENSION* aDimension, wxDC* aDC ) :
+ DIALOG_DIMENSION_EDITOR_BASE( aParent )
+{
+ SetFocus();
+
+ m_Parent = aParent;
+ m_DC = aDC;
+
+ CurrentDimension = aDimension;
+
+ if( aDimension->Text().IsMirrored() )
+ m_rbMirror->SetSelection( 1 );
+ else
+ m_rbMirror->SetSelection( 0 );
+
+ m_Name->SetValue( aDimension->Text().GetText() );
+
+ // Enter size value in dialog
+ PutValueInLocalUnits( *m_TxtSizeXCtrl, aDimension->Text().GetSize().x );
+ AddUnitSymbol( *m_staticTextSizeX );
+ PutValueInLocalUnits( *m_TxtSizeYCtrl, aDimension->Text().GetSize().y );
+ AddUnitSymbol( *m_staticTextSizeY );
+
+ // Enter lines thickness value in dialog
+ PutValueInLocalUnits( *m_TxtWidthCtrl, aDimension->GetWidth() );
+ AddUnitSymbol( *m_staticTextWidth );
+
+ // Enter position value in dialog
+ PutValueInLocalUnits( *m_textCtrlPosX, aDimension->Text().GetTextPosition().x );
+ AddUnitSymbol( *m_staticTextPosX );
+ PutValueInLocalUnits( *m_textCtrlPosY, aDimension->Text().GetTextPosition().y );
+ AddUnitSymbol( *m_staticTextPosY );
+
+ // Configure the layers list selector
+ if( !m_Parent->GetBoard()->IsLayerEnabled( aDimension->GetLayer() ) )
+ // Should not happens, because one cannot select a board item on a
+ // not activated layer, but ...
+ m_SelLayerBox->ShowNonActivatedLayers( true );
+
+ m_SelLayerBox->SetLayersHotkeys( false );
+ m_SelLayerBox->SetLayerSet( LSET::AllCuMask().set( Edge_Cuts ) );
+ m_SelLayerBox->SetBoardFrame( m_Parent );
+ m_SelLayerBox->Resync();
+
+ if( m_SelLayerBox->SetLayerSelection( aDimension->GetLayer() ) < 0 )
+ {
+ wxMessageBox( _( "This item has an illegal layer id.\n"
+ "Now, forced on the drawings layer. Please, fix it" ) );
+ m_SelLayerBox->SetLayerSelection( Dwgs_User );
+ }
+
+ m_sdbSizerBtsOK->SetDefault();
+ GetSizer()->Fit( this );
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+
+void DIALOG_DIMENSION_EDITOR::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( -1 );
+}
+
+
+void DIALOG_DIMENSION_EDITOR::OnOKClick( wxCommandEvent& event )
+{
+ LAYER_ID newlayer = ToLAYER_ID( m_SelLayerBox->GetLayerSelection() );
+
+ if( !m_Parent->GetBoard()->IsLayerEnabled( newlayer ) )
+ {
+ wxMessageBox( _( "The layer currently selected is not enabled for this board\n"
+ "You cannot use it" ) );
+ return;
+ }
+
+#ifndef USE_WX_OVERLAY
+ if( m_DC ) // Delete old text.
+ {
+ CurrentDimension->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR );
+ }
+#endif
+
+ m_Parent->SaveCopyInUndoList(CurrentDimension, UR_CHANGED);
+
+ if( m_Name->GetValue() != wxEmptyString )
+ {
+ CurrentDimension->SetText( m_Name->GetValue() );
+ }
+
+ wxString msg;
+
+ // Get new size value:
+ msg = m_TxtSizeXCtrl->GetValue();
+ CurrentDimension->Text().SetWidth( ValueFromString( g_UserUnit, msg ) );
+ msg = m_TxtSizeYCtrl->GetValue();
+ CurrentDimension->Text().SetHeight( ValueFromString( g_UserUnit, msg ) );
+
+ // Get new position value:
+ // It will be copied later in dimension, because
+ msg = m_textCtrlPosX->GetValue();
+ wxPoint pos;
+ pos.x = ValueFromString( g_UserUnit, msg );
+ msg = m_textCtrlPosY->GetValue();
+ pos.y = ValueFromString( g_UserUnit, msg );
+ CurrentDimension->Text().SetTextPosition( pos );
+
+ // Get new line thickness value:
+ msg = m_TxtWidthCtrl->GetValue();
+ int width = ValueFromString( g_UserUnit, msg );
+ int maxthickness = Clamp_Text_PenSize( width, CurrentDimension->Text().GetSize() );
+
+ if( width > maxthickness )
+ {
+ DisplayError( NULL,
+ _( "The text thickness is too large for the text size. "
+ "It will be clamped" ) );
+ width = maxthickness;
+ }
+
+ CurrentDimension->SetWidth( width );
+ CurrentDimension->Text().SetThickness( width );
+ CurrentDimension->Text().SetMirrored( ( m_rbMirror->GetSelection() == 1 ) ? true : false );
+ CurrentDimension->SetLayer( newlayer );
+
+#ifndef USE_WX_OVERLAY
+ if( m_DC ) // Display new text
+ {
+ CurrentDimension->Draw( m_Parent->GetCanvas(), m_DC, GR_OR );
+ }
+#else
+ m_Parent->Refresh();
+#endif
+
+ m_Parent->OnModify();
+ EndModal( 1 );
+}
+
+
+static void AbortBuildDimension( EDA_DRAW_PANEL* Panel, wxDC* aDC )
+{
+ DIMENSION* Dimension = (DIMENSION*) Panel->GetScreen()->GetCurItem();
+
+ if( Dimension )
+ {
+ if( Dimension->IsNew() )
+ {
+ Dimension->Draw( Panel, aDC, GR_XOR );
+ Dimension->DeleteStructure();
+ }
+ else
+ {
+ Dimension->Draw( Panel, aDC, GR_OR );
+ }
+ }
+
+ status_dimension = 0;
+ ((PCB_EDIT_FRAME*)Panel->GetParent())->SetCurItem( NULL );
+}
+
+
+DIMENSION* PCB_EDIT_FRAME::EditDimension( DIMENSION* aDimension, wxDC* aDC )
+{
+ wxPoint pos;
+
+ if( aDimension == NULL )
+ {
+ status_dimension = 1;
+ pos = GetCrossHairPosition();
+
+ aDimension = new DIMENSION( GetBoard() );
+ aDimension->SetFlags( IS_NEW );
+ aDimension->SetLayer( GetActiveLayer() );
+ aDimension->SetOrigin( pos );
+ aDimension->SetEnd( pos );
+
+ aDimension->Text().SetSize( GetBoard()->GetDesignSettings().m_PcbTextSize );
+ int width = GetBoard()->GetDesignSettings().m_PcbTextWidth;
+ int maxthickness = Clamp_Text_PenSize(width, aDimension->Text().GetSize() );
+
+ if( width > maxthickness )
+ {
+ width = maxthickness;
+ }
+
+ aDimension->Text().SetThickness( width );
+ aDimension->SetWidth( width );
+ aDimension->AdjustDimensionDetails();
+ aDimension->Draw( m_canvas, aDC, GR_XOR );
+
+ m_canvas->SetMouseCapture( BuildDimension, AbortBuildDimension );
+ return aDimension;
+ }
+
+ // Dimension != NULL
+ if( status_dimension == 1 )
+ {
+ status_dimension = 2;
+ return aDimension;
+ }
+
+ aDimension->Draw( m_canvas, aDC, GR_OR );
+ aDimension->ClearFlags();
+
+ /* ADD this new item in list */
+ GetBoard()->Add( aDimension );
+
+ // Add store it in undo/redo list
+ SaveCopyInUndoList( aDimension, UR_NEW );
+
+ OnModify();
+ m_canvas->SetMouseCapture( NULL, NULL );
+
+ return NULL;
+}
+
+
+static void BuildDimension( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase )
+{
+ PCB_SCREEN* screen = (PCB_SCREEN*) aPanel->GetScreen();
+ DIMENSION* Dimension = (DIMENSION*) screen->GetCurItem();
+ wxPoint pos = aPanel->GetParent()->GetCrossHairPosition();
+
+ if( Dimension == NULL )
+ return;
+
+ // Erase previous dimension.
+ if( aErase )
+ {
+ Dimension->Draw( aPanel, aDC, GR_XOR );
+ }
+
+ Dimension->SetLayer( screen->m_Active_Layer );
+
+ if( status_dimension == 1 )
+ {
+ Dimension->m_featureLineDO = pos;
+ Dimension->m_crossBarF = Dimension->m_featureLineDO;
+ Dimension->AdjustDimensionDetails( );
+ }
+ else
+ {
+ /* Calculating the direction of travel perpendicular to the selected axis. */
+ double angle = Dimension->GetAngle() + (M_PI / 2);
+
+ wxPoint delta = pos - Dimension->m_featureLineDO;
+ double depl = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
+ Dimension->SetHeight( depl );
+ }
+
+ Dimension->Draw( aPanel, aDC, GR_XOR );
+}
+
+
+void PCB_EDIT_FRAME::ShowDimensionPropertyDialog( DIMENSION* aDimension, wxDC* aDC )
+{
+ if( aDimension == NULL )
+ return;
+
+ DIALOG_DIMENSION_EDITOR* frame = new DIALOG_DIMENSION_EDITOR( this, aDimension, aDC );
+ frame->ShowModal();
+ frame->Destroy();
+}
+
+
+void PCB_EDIT_FRAME::DeleteDimension( DIMENSION* aDimension, wxDC* aDC )
+{
+ if( aDimension == NULL )
+ return;
+
+ if( aDC )
+ aDimension->Draw( m_canvas, aDC, GR_XOR );
+
+ SaveCopyInUndoList( aDimension, UR_DELETED );
+ aDimension->UnLink();
+ OnModify();
+}
+
+
+/* Initialize parameters to move a pcb text
+ */
+static wxPoint initialTextPosition;
+
+void PCB_EDIT_FRAME::BeginMoveDimensionText( DIMENSION* aItem, wxDC* DC )
+{
+ if( aItem == NULL )
+ return;
+
+ // Store the initial position for undo/abort command
+ initialTextPosition = aItem->Text().GetTextPosition();
+
+ aItem->Draw( m_canvas, DC, GR_XOR );
+ aItem->SetFlags( IS_MOVED );
+ SetMsgPanel( aItem );
+
+ SetCrossHairPosition( aItem->Text().GetTextPosition() );
+ m_canvas->MoveCursorToCrossHair();
+
+ m_canvas->SetMouseCapture( MoveDimensionText, AbortMoveDimensionText );
+ SetCurItem( aItem );
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+}
+
+
+/* Move dimension text following the cursor. */
+static void MoveDimensionText( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ DIMENSION* dimension = (DIMENSION*) aPanel->GetScreen()->GetCurItem();
+
+ if( dimension == NULL )
+ return;
+
+ if( aErase )
+ dimension->Draw( aPanel, aDC, GR_XOR );
+
+ dimension->Text().SetTextPosition( aPanel->GetParent()->GetCrossHairPosition() );
+
+ dimension->Draw( aPanel, aDC, GR_XOR );
+}
+
+
+/*
+ * Abort current text edit progress.
+ *
+ * If a text is selected, its initial coord are regenerated
+ */
+void AbortMoveDimensionText( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
+{
+ DIMENSION* dimension = (DIMENSION*) aPanel->GetScreen()->GetCurItem();
+ ( (PCB_EDIT_FRAME*) aPanel->GetParent() )->SetCurItem( NULL );
+
+ aPanel->SetMouseCapture( NULL, NULL );
+
+ if( dimension == NULL ) // Should not occur
+ return;
+
+ dimension->Draw( aPanel, aDC, GR_XOR );
+ dimension->Text().SetTextPosition( initialTextPosition );
+ dimension->ClearFlags();
+ dimension->Draw( aPanel, aDC, GR_OR );
+}
+
+
+/*
+ * Place the current dimension text being moving
+ */
+void PCB_EDIT_FRAME::PlaceDimensionText( DIMENSION* aItem, wxDC* DC )
+{
+ m_canvas->SetMouseCapture( NULL, NULL );
+ SetCurItem( NULL );
+
+ if( aItem == NULL )
+ return;
+
+ aItem->Draw( m_canvas, DC, GR_OR );
+ OnModify();
+
+ wxPoint tmp = aItem->Text().GetTextPosition();
+ aItem->Text().SetTextPosition( initialTextPosition );
+ SaveCopyInUndoList( aItem, UR_CHANGED );
+ aItem->Text().SetTextPosition( tmp );
+ aItem->ClearFlags();
+}
diff --git a/pcbnew/drag.h b/pcbnew/drag.h
new file mode 100644
index 0000000..89e5900
--- /dev/null
+++ b/pcbnew/drag.h
@@ -0,0 +1,205 @@
+/**
+ * @file drag.h
+ * @brief Useful classes and functions used to collect tracks to drag
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _DRAG_H_
+#define _DRAG_H_
+
+
+#include <class_track.h>
+#include <vector>
+
+
+class wxDC;
+class wxPoint;
+class EDA_DRAW_PANEL;
+class MODULE;
+class D_PAD;
+class CONNECTIONS;
+
+
+/** Helper classes to handle a list of track segments to drag
+ * and has info to undo/abort the move command
+ */
+
+ /*
+ * a DRAG_LIST manages the list of track segments to modify
+ * when the pad or the module is moving in drag mode
+ */
+
+/**
+ * a DRAG_SEGM_PICKER manage one track segment or a via
+ */
+class DRAG_SEGM_PICKER
+{
+public:
+ TRACK* m_Track; // pointer to the parent track segment
+ D_PAD* m_Pad_Start; // pointer to the moving pad
+ // if the start point should follow this pad
+ // or NULL
+ D_PAD* m_Pad_End; // pointer to the moving pad
+ // if the end point should follow this pad
+ // or NULL
+ int m_TempFlags; // flag used in drag vias and drag track segment functions
+
+private:
+ double m_RotationOffset; // initial orientation of the parent module
+ // Used to recalculate m_PadStartOffset and m_PadEndOffset
+ // after a module rotation when dragging
+ bool m_Flipped; // initial side of the parent module
+ // Used to recalculate m_PadStartOffset and m_PadEndOffset
+ // if the module is flipped when dragging
+ wxPoint m_PadStartOffset; // offset between the pad and the starting point of the track
+ // usually 0,0, but not always
+ wxPoint m_PadEndOffset; // offset between the pad and the ending point of the track
+ // usually 0,0, but not always
+ wxPoint m_startInitialValue;
+ wxPoint m_endInitialValue; // For abort command:
+ // initial m_Start and m_End values for m_Track
+
+public:
+
+ DRAG_SEGM_PICKER( TRACK* aTrack );
+ ~DRAG_SEGM_PICKER() {};
+
+ /**
+ * Set auxiliary parameters relative to calculations needed
+ * to find track ends positions while dragging pads
+ * and when modules are rotated, flipped
+ */
+ void SetAuxParameters();
+
+ /**
+ * Calculate track ends position while dragging pads
+ * and when modules are rotated, flipped
+ * @param aOffset = offset of module or pad position (when moving)
+ */
+ void SetTrackEndsCoordinates( wxPoint aOffset );
+
+ void RestoreInitialValues()
+ {
+ m_Track->SetStart( m_startInitialValue );
+ m_Track->SetEnd( m_endInitialValue );
+ }
+};
+
+
+class DRAG_LIST
+{
+public:
+ BOARD* m_Brd; // the main board
+ MODULE* m_Module; // The link to the module to move, or NULL
+ D_PAD* m_Pad; // The link to the pad to move, or NULL
+
+ std::vector<DRAG_SEGM_PICKER> m_DragList; // The list of DRAG_SEGM_PICKER items
+
+public:
+ DRAG_LIST( BOARD* aPcb )
+ {
+ m_Brd = aPcb;
+ m_Module = NULL;
+ m_Pad = NULL;
+ }
+
+ /**
+ * Function ClearList
+ * clear the .m_Flags of all track segments in m_DragList
+ * and clear the list.
+ */
+ void ClearList();
+
+ /** Build the list of track segments connected to pads of aModule
+ * in m_DragList
+ * For each selected track segment the EDIT flag is set
+ */
+ void BuildDragListe( MODULE* aModule );
+
+ /** Build the list of track segments connected to aPad
+ * in m_DragList
+ * For each selected track segment the EDIT flag is set
+ */
+ void BuildDragListe( D_PAD* aPad );
+
+private:
+
+ /** Fills m_DragList with of track segments connected to pads in aConnections
+ * For each selected track segment the EDIT flag is set
+ */
+ void fillList( CONNECTIONS& aConnections );
+};
+
+
+// Global variables:
+
+// a list of DRAG_SEGM_PICKER items used to move or drag tracks.
+// Each DRAG_SEGM_PICKER item points a segment to move.
+extern std::vector<DRAG_SEGM_PICKER> g_DragSegmentList;
+
+// Functions:
+void DrawSegmentWhileMovingFootprint( EDA_DRAW_PANEL* panel, wxDC* DC );
+
+/**
+ * Function EraseDragList
+ * clear the .m_Flags of all track segments stored in g_DragSegmentList
+ * and clear the list.
+ * In order to avoid useless memory reallocation, the memory is not freed
+ * and will be reused when creating a new list
+ */
+void EraseDragList();
+
+/**
+ * Function Collect_TrackSegmentsToDrag.
+ * used to collect track segments in drag track segment
+ * Build the list of tracks connected to the ref point by calling
+ * AddSegmentToDragList for each selected track
+ * Net codes must be up to date, because only tracks having the right net code are tested.
+ *
+ * @param aPcb A point the the #BOARD object to collect track segment to drag.
+ * @param aRefPos = reference point of connection
+ * @param aLayerMask = layers mask to collect tracks
+ * @param aNetCode = the net code to consider
+ * @param aMaxDist = max distance from aRefPos to a track end candidate to collect the track
+ */
+void Collect_TrackSegmentsToDrag( BOARD* aPcb, const wxPoint& aRefPos, LSET aLayerMask,
+ int aNetCode, int aMaxDist );
+
+/* Add aTrack to the drag list
+ * flag = STARTPOINT (if the point to drag is the start point of Track)
+ * or ENDPOINT (if the point to drag is the end point of Track)
+ */
+void AddSegmentToDragList( int flag, TRACK* aTrack );
+
+/*
+ * Undraw the track segments in list, and set the EDIT flag
+ * Usually called after the track list is built, to prepare
+ * the redraw of the list when the mouse is moved
+ */
+void UndrawAndMarkSegmentsToDrag( EDA_DRAW_PANEL* aCanvas, wxDC* aDC );
+
+
+#endif // _DRAG_H_
diff --git a/pcbnew/dragsegm.cpp b/pcbnew/dragsegm.cpp
new file mode 100644
index 0000000..7e48f5c
--- /dev/null
+++ b/pcbnew/dragsegm.cpp
@@ -0,0 +1,422 @@
+/**
+ * @file dragsegm.cpp
+ * @brief Classes to find track segments connected to a pad or a module
+ * for drag commands
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <trigo.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <wxBasePcbFrame.h>
+#include <macros.h>
+
+#include <drag.h>
+#include <pcbnew.h>
+
+#include <class_module.h>
+#include <class_board.h>
+#include <connect.h>
+
+
+/* a list of DRAG_SEGM_PICKER items used to move or drag tracks */
+std::vector<DRAG_SEGM_PICKER> g_DragSegmentList;
+
+/* helper class to handle a list of track segments to drag or move
+ */
+DRAG_SEGM_PICKER::DRAG_SEGM_PICKER( TRACK* aTrack )
+{
+ m_Track = aTrack;
+ m_startInitialValue = m_Track->GetStart();
+ m_endInitialValue = m_Track->GetEnd();
+ m_Pad_Start = m_Track->GetState( START_ON_PAD ) ? (D_PAD*)m_Track->start : NULL;
+ m_Pad_End = m_Track->GetState( END_ON_PAD ) ? (D_PAD*)m_Track->end : NULL;
+ m_TempFlags = 0;
+ m_RotationOffset = 0.0;
+ m_Flipped = false;
+}
+
+
+void DRAG_SEGM_PICKER::SetAuxParameters()
+{
+ MODULE* module = NULL;
+
+ if( m_Pad_Start )
+ {
+ module = m_Pad_Start->GetParent();
+ m_PadStartOffset = m_Track->GetStart() - m_Pad_Start->GetPosition();
+ }
+
+ if( m_Pad_End )
+ {
+ if( module == NULL )
+ module = m_Pad_End->GetParent();
+
+ m_PadEndOffset = m_Track->GetEnd() - m_Pad_End->GetPosition();
+ }
+
+ if( module )
+ {
+ m_Flipped = module->IsFlipped();
+ m_RotationOffset = module->GetOrientation();
+ }
+}
+
+
+void DRAG_SEGM_PICKER::SetTrackEndsCoordinates( wxPoint aOffset )
+{
+ // the track start position is the pad position + m_PadStartOffset
+ // however m_PadStartOffset is known for the initial rotation/flip
+ // this is also true for track end position and m_PadEndOffset
+ // Therefore, because rotation/flipping is allowed during a drag
+ // and move module, we should recalculate the pad offset,
+ // depending on the current orientation/flip state of the module
+ // relative to its initial orientation.
+ // (although most of time, offset is 0,0)
+
+ double curr_rot_offset = m_RotationOffset;
+ MODULE* module = NULL;
+ bool flip = false;
+
+ if( m_Pad_Start )
+ module = m_Pad_Start->GetParent();
+
+ if( module == NULL && m_Pad_End )
+ module = m_Pad_End->GetParent();
+
+ if( module )
+ {
+ flip = m_Flipped != module->IsFlipped();
+ curr_rot_offset = module->GetOrientation() - m_RotationOffset;
+
+ if( flip ) // when flipping, module orientation is negated
+ curr_rot_offset = - module->GetOrientation() - m_RotationOffset;
+ }
+
+ if( m_Pad_Start )
+ {
+ wxPoint padoffset = m_PadStartOffset;
+
+ if( curr_rot_offset != 0.0 )
+ RotatePoint(&padoffset, curr_rot_offset);
+
+ if( flip )
+ padoffset.y = -padoffset.y;
+
+ m_Track->SetStart( m_Pad_Start->GetPosition() - aOffset + padoffset );
+ }
+
+ if( m_Pad_End )
+ {
+ wxPoint padoffset = m_PadEndOffset;
+
+ if( curr_rot_offset != 0.0 )
+ RotatePoint( &padoffset, curr_rot_offset );
+
+ if( flip )
+ padoffset.y = -padoffset.y;
+
+ m_Track->SetEnd( m_Pad_End->GetPosition() - aOffset + padoffset );
+ }
+}
+
+
+// A sort function needed to build ordered pads lists
+extern bool sortPadsByXthenYCoord( D_PAD* const & ref, D_PAD* const & comp );
+
+
+void DRAG_LIST::BuildDragListe( MODULE* aModule )
+{
+ m_Pad = NULL;
+ m_Module = aModule;
+
+ // Build connections info
+ CONNECTIONS connections( m_Brd );
+ std::vector<D_PAD*>&padList = connections.GetPadsList();
+
+ for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
+ padList.push_back( pad );
+
+ sort( padList.begin(), padList.end(), sortPadsByXthenYCoord );
+
+ fillList( connections );
+}
+
+
+void DRAG_LIST::BuildDragListe( D_PAD* aPad )
+{
+ m_Pad = aPad;
+ m_Module = NULL;
+
+ // Build connections info
+ CONNECTIONS connections( m_Brd );
+ std::vector<D_PAD*>&padList = connections.GetPadsList();
+ padList.push_back( aPad );
+
+ fillList( connections );
+}
+
+
+// A helper function to sort track list per tracks
+bool sort_tracklist( const DRAG_SEGM_PICKER& ref, const DRAG_SEGM_PICKER& tst )
+{
+ return ref.m_Track < tst.m_Track;
+}
+
+
+void DRAG_LIST::fillList( CONNECTIONS& aConnections )
+{
+ aConnections.BuildTracksCandidatesList( m_Brd->m_Track, NULL);
+
+ // Build connections info tracks to pads
+ // Rebuild pads to track info only)
+ aConnections.SearchTracksConnectedToPads( false, true );
+
+ std::vector<D_PAD*>padList = aConnections.GetPadsList();
+
+ // clear flags and variables of selected tracks
+ for( unsigned ii = 0; ii < padList.size(); ii++ )
+ {
+ D_PAD * pad = padList[ii];
+
+ // store track connected to the pad
+ for( unsigned jj = 0; jj < pad->m_TracksConnected.size(); jj++ )
+ {
+ TRACK * track = pad->m_TracksConnected[jj];
+ track->start = NULL;
+ track->end = NULL;
+ track->SetState( START_ON_PAD|END_ON_PAD|BUSY, false );
+ }
+ }
+
+ // store tracks connected to pads
+ for( unsigned ii = 0; ii < padList.size(); ii++ )
+ {
+ D_PAD * pad = padList[ii];
+
+ // store track connected to the pad
+ for( unsigned jj = 0; jj < pad->m_TracksConnected.size(); jj++ )
+ {
+ TRACK * track = pad->m_TracksConnected[jj];
+
+ if( pad->HitTest( track->GetStart() ) )
+ {
+ track->start = pad;
+ track->SetState( START_ON_PAD, true );
+ }
+
+ if( pad->HitTest( track->GetEnd() ) )
+ {
+ track->end = pad;
+ track->SetState( END_ON_PAD, true );
+ }
+
+ DRAG_SEGM_PICKER wrapper( track );
+ m_DragList.push_back( wrapper );
+ }
+ }
+
+ // remove duplicate in m_DragList:
+ // a track can be stored more than once if connected to 2 overlapping pads, or
+ // each track end connected to 2 moving pads
+ // to avoid artifact in draw function, items should be not duplicated
+ // However, there is not a lot of items to be removed, so there ir no optimization.
+
+ // sort the drag list by track pointers
+ sort( m_DragList.begin(), m_DragList.end(), sort_tracklist );
+
+ // Explore the list, merge duplicates
+ for( int ii = 0; ii < (int)m_DragList.size()-1; ii++ )
+ {
+ int jj = ii+1;
+
+ if( m_DragList[ii].m_Track != m_DragList[jj].m_Track )
+ continue;
+
+ // duplicate found: merge info and remove duplicate
+ if( m_DragList[ii].m_Pad_Start == NULL )
+ m_DragList[ii].m_Pad_Start = m_DragList[jj].m_Pad_Start;
+
+ if( m_DragList[ii].m_Pad_End == NULL )
+ m_DragList[ii].m_Pad_End = m_DragList[jj].m_Pad_End;
+
+ m_DragList.erase( m_DragList.begin() + jj );
+ ii--;
+ }
+
+ // Initialize pad offsets and other params
+ for( unsigned ii = 0; ii < m_DragList.size(); ii++ )
+ m_DragList[ii].SetAuxParameters();
+
+ // Copy the list in global list
+ g_DragSegmentList = m_DragList;
+}
+
+
+void DRAG_LIST::ClearList()
+{
+ for( unsigned ii = 0; ii < m_DragList.size(); ii++ )
+ m_DragList[ii].m_Track->ClearFlags();
+
+ m_DragList.clear();
+
+ m_Module = NULL;
+ m_Pad = NULL;
+}
+
+
+// Redraw the list of segments stored in g_DragSegmentList, while moving a footprint
+void DrawSegmentWhileMovingFootprint( EDA_DRAW_PANEL* panel, wxDC* DC )
+{
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ TRACK* track = g_DragSegmentList[ii].m_Track;
+
+#ifndef USE_WX_OVERLAY
+ track->Draw( panel, DC, GR_XOR ); // erase from screen at old position
+#endif
+ g_DragSegmentList[ii].SetTrackEndsCoordinates( g_Offset_Module );
+ track->Draw( panel, DC, GR_XOR );
+ }
+}
+
+
+void EraseDragList()
+{
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ g_DragSegmentList[ii].m_Track->ClearFlags();
+
+ g_DragSegmentList.clear();
+}
+
+
+void AddSegmentToDragList( int flag, TRACK* aTrack )
+{
+ DRAG_SEGM_PICKER wrapper( aTrack );
+
+ if( flag & STARTPOINT )
+ {
+ wrapper.m_TempFlags |= STARTPOINT;
+ aTrack->SetFlags( STARTPOINT );
+ }
+
+ if( flag & ENDPOINT )
+ {
+ wrapper.m_TempFlags |= ENDPOINT;
+ aTrack->SetFlags( ENDPOINT );
+ }
+
+ g_DragSegmentList.push_back( wrapper );
+}
+
+
+void Collect_TrackSegmentsToDrag( BOARD* aPcb, const wxPoint& aRefPos, LSET aLayerMask,
+ int aNetCode, int aMaxDist )
+{
+ TRACK* track = aPcb->m_Track->GetStartNetCode( aNetCode );
+
+ for( ; track; track = track->Next() )
+ {
+ if( track->GetNetCode() != aNetCode ) // not the same netcode: all candidates tested
+ break;
+
+ if( !( aLayerMask & track->GetLayerSet() ).any() )
+ continue; // Cannot be connected, not on the same layer
+
+ if( track->IsDragging() )
+ continue; // already put in list
+
+ STATUS_FLAGS flag = 0;
+ int maxdist = std::max( aMaxDist, track->GetWidth() / 2 );
+
+ if( (track->GetFlags() & STARTPOINT) == 0 )
+ {
+ wxPoint delta = track->GetStart() - aRefPos;
+
+ if( std::abs( delta.x ) <= maxdist && std::abs( delta.y ) <= maxdist )
+ {
+ int dist = KiROUND( EuclideanNorm( delta ) );
+
+ if( dist <= maxdist )
+ {
+ flag |= STARTPOINT;
+
+ if( track->Type() == PCB_VIA_T )
+ flag |= ENDPOINT;
+ }
+ }
+ }
+
+ if( (track->GetFlags() & ENDPOINT) == 0 )
+ {
+ wxPoint delta = track->GetEnd() - aRefPos;
+
+ if( std::abs( delta.x ) <= maxdist && std::abs( delta.y ) <= maxdist )
+ {
+ int dist = KiROUND( EuclideanNorm( delta ) );
+
+ if( dist <= maxdist )
+ flag |= ENDPOINT;
+ }
+ }
+
+ // Note: vias will be flagged with both STARTPOINT and ENDPOINT
+ // and must not be entered twice.
+ if( flag )
+ {
+ AddSegmentToDragList( flag, track );
+
+ // If a connected via is found at location aRefPos,
+ // collect also tracks connected by this via.
+ if( track->Type() == PCB_VIA_T )
+ Collect_TrackSegmentsToDrag( aPcb, aRefPos, track->GetLayerSet(),
+ aNetCode, track->GetWidth() / 2 );
+ }
+ }
+}
+
+
+void UndrawAndMarkSegmentsToDrag( EDA_DRAW_PANEL* aCanvas, wxDC* aDC )
+{
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ TRACK* track = g_DragSegmentList[ii].m_Track;
+
+ track->Draw( aCanvas, aDC, GR_XOR );
+ track->SetState( IN_EDIT, false );
+ track->SetFlags( IS_DRAGGED );
+
+ if( g_DragSegmentList[ii].m_TempFlags & STARTPOINT )
+ track->SetFlags( STARTPOINT );
+
+ if( g_DragSegmentList[ii].m_TempFlags & ENDPOINT )
+ track->SetFlags( ENDPOINT );
+
+ track->Draw( aCanvas, aDC, GR_XOR );
+ }
+}
diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp
new file mode 100644
index 0000000..31ebc50
--- /dev/null
+++ b/pcbnew/drc.cpp
@@ -0,0 +1,968 @@
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2016 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file drc.cpp
+ */
+
+#include <fctsys.h>
+#include <wxPcbStruct.h>
+#include <trigo.h>
+#include <base_units.h>
+#include <class_board_design_settings.h>
+
+#include <class_module.h>
+#include <class_track.h>
+#include <class_pad.h>
+#include <class_zone.h>
+#include <class_pcb_text.h>
+#include <class_draw_panel_gal.h>
+#include <view/view.h>
+#include <geometry/seg.h>
+
+#include <tool/tool_manager.h>
+#include <tools/common_actions.h>
+
+#include <pcbnew.h>
+#include <drc_stuff.h>
+
+#include <dialog_drc.h>
+#include <wx/progdlg.h>
+
+
+void DRC::ShowDialog()
+{
+ if( !m_drcDialog )
+ {
+ m_mainWindow->GetToolManager()->RunAction( COMMON_ACTIONS::selectionClear, true );
+ m_drcDialog = new DIALOG_DRC_CONTROL( this, m_mainWindow );
+ updatePointers();
+
+ m_drcDialog->SetRptSettings( m_doCreateRptFile, m_rptFilename);
+ }
+ else
+ updatePointers();
+
+ m_drcDialog->Show( true );
+}
+
+
+void DRC::DestroyDialog( int aReason )
+{
+ if( m_drcDialog )
+ {
+ if( aReason == wxID_OK )
+ {
+ // if user clicked OK, save his choices in this DRC object.
+ m_drcDialog->GetRptSettings( &m_doCreateRptFile, m_rptFilename);
+ }
+
+ m_drcDialog->Destroy();
+ m_drcDialog = NULL;
+ }
+}
+
+
+DRC::DRC( PCB_EDIT_FRAME* aPcbWindow )
+{
+ m_mainWindow = aPcbWindow;
+ m_pcb = aPcbWindow->GetBoard();
+ m_drcDialog = NULL;
+
+ // establish initial values for everything:
+ m_doPad2PadTest = true; // enable pad to pad clearance tests
+ m_doUnconnectedTest = true; // enable unconnected tests
+ m_doZonesTest = true; // enable zone to items clearance tests
+ m_doKeepoutTest = true; // enable keepout areas to items clearance tests
+ m_abortDRC = false;
+ m_drcInProgress = false;
+
+ m_doCreateRptFile = false;
+
+ // m_rptFilename set to empty by its constructor
+
+ m_currentMarker = NULL;
+
+ m_segmAngle = 0;
+ m_segmLength = 0;
+
+ m_xcliplo = 0;
+ m_ycliplo = 0;
+ m_xcliphi = 0;
+ m_ycliphi = 0;
+}
+
+
+DRC::~DRC()
+{
+ // maybe someday look at pointainer.h <- google for "pointainer.h"
+ for( unsigned i = 0; i<m_unconnected.size(); ++i )
+ delete m_unconnected[i];
+}
+
+
+int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
+{
+ updatePointers();
+
+ if( !doTrackDrc( aRefSegm, aList, true ) )
+ {
+ wxASSERT( m_currentMarker );
+
+ m_mainWindow->SetMsgPanel( m_currentMarker );
+ return BAD_DRC;
+ }
+
+ if( !doTrackKeepoutDrc( aRefSegm ) )
+ {
+ wxASSERT( m_currentMarker );
+
+ m_mainWindow->SetMsgPanel( m_currentMarker );
+ return BAD_DRC;
+ }
+
+ return OK_DRC;
+}
+
+
+int DRC::Drc( ZONE_CONTAINER* aArea, int aCornerIndex )
+{
+ updatePointers();
+
+ if( !doEdgeZoneDrc( aArea, aCornerIndex ) )
+ {
+ wxASSERT( m_currentMarker );
+ m_mainWindow->SetMsgPanel( m_currentMarker );
+ return BAD_DRC;
+ }
+
+ return OK_DRC;
+}
+
+
+void DRC::RunTests( wxTextCtrl* aMessages )
+{
+ // be sure m_pcb is the current board, not a old one
+ // ( the board can be reloaded )
+ m_pcb = m_mainWindow->GetBoard();
+
+ // Ensure ratsnest is up to date:
+ if( (m_pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
+ {
+ if( aMessages )
+ {
+ aMessages->AppendText( _( "Compile ratsnest...\n" ) );
+ wxSafeYield();
+ }
+
+ m_mainWindow->Compile_Ratsnest( NULL, true );
+ }
+
+ // someone should have cleared the two lists before calling this.
+
+ if( !testNetClasses() )
+ {
+ // testing the netclasses is a special case because if the netclasses
+ // do not pass the BOARD_DESIGN_SETTINGS checks, then every member of a net
+ // class (a NET) will cause its items such as tracks, vias, and pads
+ // to also fail. So quit after *all* netclass errors have been reported.
+ if( aMessages )
+ aMessages->AppendText( _( "Aborting\n" ) );
+
+ // update the m_drcDialog listboxes
+ updatePointers();
+
+ return;
+ }
+
+ // test pad to pad clearances, nothing to do with tracks, vias or zones.
+ if( m_doPad2PadTest )
+ {
+ if( aMessages )
+ {
+ aMessages->AppendText( _( "Pad clearances...\n" ) );
+ wxSafeYield();
+ }
+
+ testPad2Pad();
+ }
+
+ // test track and via clearances to other tracks, pads, and vias
+ if( aMessages )
+ {
+ aMessages->AppendText( _( "Track clearances...\n" ) );
+ wxSafeYield();
+ }
+
+ testTracks( aMessages ? aMessages->GetParent() : m_mainWindow, true );
+
+ // Before testing segments and unconnected, refill all zones:
+ // this is a good caution, because filled areas can be outdated.
+ if( aMessages )
+ {
+ aMessages->AppendText( _( "Fill zones...\n" ) );
+ wxSafeYield();
+ }
+
+ m_mainWindow->Fill_All_Zones( aMessages ? aMessages->GetParent() : m_mainWindow,
+ false );
+
+ // test zone clearances to other zones
+ if( aMessages )
+ {
+ aMessages->AppendText( _( "Test zones...\n" ) );
+ wxSafeYield();
+ }
+
+ testZones();
+
+ // find and gather unconnected pads.
+ if( m_doUnconnectedTest )
+ {
+ if( aMessages )
+ {
+ aMessages->AppendText( _( "Unconnected pads...\n" ) );
+ aMessages->Refresh();
+ }
+
+ testUnconnected();
+ }
+
+ // find and gather vias, tracks, pads inside keepout areas.
+ if( m_doKeepoutTest )
+ {
+ if( aMessages )
+ {
+ aMessages->AppendText( _( "Keepout areas ...\n" ) );
+ aMessages->Refresh();
+ }
+
+ testKeepoutAreas();
+ }
+
+ // find and gather vias, tracks, pads inside text boxes.
+ if( aMessages )
+ {
+ aMessages->AppendText( _( "Test texts...\n" ) );
+ wxSafeYield();
+ }
+
+ testTexts();
+
+ // update the m_drcDialog listboxes
+ updatePointers();
+
+ if( aMessages )
+ {
+ // no newline on this one because it is last, don't want the window
+ // to unnecessarily scroll.
+ aMessages->AppendText( _( "Finished" ) );
+ }
+}
+
+
+void DRC::ListUnconnectedPads()
+{
+ testUnconnected();
+
+ // update the m_drcDialog listboxes
+ updatePointers();
+}
+
+
+void DRC::updatePointers()
+{
+ // update my pointers, m_mainWindow is the only unchangeable one
+ m_pcb = m_mainWindow->GetBoard();
+
+ if( m_drcDialog ) // Use diag list boxes only in DRC dialog
+ {
+ m_drcDialog->m_ClearanceListBox->SetList( new DRC_LIST_MARKERS( m_pcb ) );
+ m_drcDialog->m_UnconnectedListBox->SetList( new DRC_LIST_UNCONNECTED( &m_unconnected ) );
+ }
+}
+
+
+bool DRC::doNetClass( NETCLASSPTR nc, wxString& msg )
+{
+ bool ret = true;
+
+ const BOARD_DESIGN_SETTINGS& g = m_pcb->GetDesignSettings();
+
+#define FmtVal( x ) GetChars( StringFromValue( g_UserUnit, x ) )
+
+#if 0 // set to 1 when (if...) BOARD_DESIGN_SETTINGS has a m_MinClearance value
+ if( nc->GetClearance() < g.m_MinClearance )
+ {
+ msg.Printf( _( "NETCLASS: '%s' has Clearance:%s which is less than global:%s" ),
+ GetChars( nc->GetName() ),
+ FmtVal( nc->GetClearance() ),
+ FmtVal( g.m_TrackClearance )
+ );
+
+ m_currentMarker = fillMarker( DRCE_NETCLASS_CLEARANCE, msg, m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = 0;
+ ret = false;
+ }
+#endif
+
+ if( nc->GetTrackWidth() < g.m_TrackMinWidth )
+ {
+ msg.Printf( _( "NETCLASS: '%s' has TrackWidth:%s which is less than global:%s" ),
+ GetChars( nc->GetName() ),
+ FmtVal( nc->GetTrackWidth() ),
+ FmtVal( g.m_TrackMinWidth )
+ );
+
+ m_currentMarker = fillMarker( DRCE_NETCLASS_TRACKWIDTH, msg, m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = 0;
+ ret = false;
+ }
+
+ if( nc->GetViaDiameter() < g.m_ViasMinSize )
+ {
+ msg.Printf( _( "NETCLASS: '%s' has Via Dia:%s which is less than global:%s" ),
+ GetChars( nc->GetName() ),
+ FmtVal( nc->GetViaDiameter() ),
+ FmtVal( g.m_ViasMinSize )
+ );
+
+ m_currentMarker = fillMarker( DRCE_NETCLASS_VIASIZE, msg, m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = 0;
+ ret = false;
+ }
+
+ if( nc->GetViaDrill() < g.m_ViasMinDrill )
+ {
+ msg.Printf( _( "NETCLASS: '%s' has Via Drill:%s which is less than global:%s" ),
+ GetChars( nc->GetName() ),
+ FmtVal( nc->GetViaDrill() ),
+ FmtVal( g.m_ViasMinDrill )
+ );
+
+ m_currentMarker = fillMarker( DRCE_NETCLASS_VIADRILLSIZE, msg, m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = 0;
+ ret = false;
+ }
+
+ if( nc->GetuViaDiameter() < g.m_MicroViasMinSize )
+ {
+ msg.Printf( _( "NETCLASS: '%s' has uVia Dia:%s which is less than global:%s" ),
+ GetChars( nc->GetName() ),
+ FmtVal( nc->GetuViaDiameter() ),
+ FmtVal( g.m_MicroViasMinSize )
+ );
+
+ m_currentMarker = fillMarker( DRCE_NETCLASS_uVIASIZE, msg, m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = 0;
+ ret = false;
+ }
+
+ if( nc->GetuViaDrill() < g.m_MicroViasMinDrill )
+ {
+ msg.Printf( _( "NETCLASS: '%s' has uVia Drill:%s which is less than global:%s" ),
+ GetChars( nc->GetName() ),
+ FmtVal( nc->GetuViaDrill() ),
+ FmtVal( g.m_MicroViasMinDrill )
+ );
+
+ m_currentMarker = fillMarker( DRCE_NETCLASS_uVIADRILLSIZE, msg, m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = 0;
+ ret = false;
+ }
+
+ return ret;
+}
+
+
+bool DRC::testNetClasses()
+{
+ bool ret = true;
+
+ NETCLASSES& netclasses = m_pcb->GetDesignSettings().m_NetClasses;
+
+ wxString msg; // construct this only once here, not in a loop, since somewhat expensive.
+
+ if( !doNetClass( netclasses.GetDefault(), msg ) )
+ ret = false;
+
+ for( NETCLASSES::const_iterator i = netclasses.begin(); i != netclasses.end(); ++i )
+ {
+ NETCLASSPTR nc = i->second;
+
+ if( !doNetClass( nc, msg ) )
+ ret = false;
+ }
+
+ return ret;
+}
+
+
+void DRC::testPad2Pad()
+{
+ std::vector<D_PAD*> sortedPads;
+
+ m_pcb->GetSortedPadListByXthenYCoord( sortedPads );
+
+ // find the max size of the pads (used to stop the test)
+ int max_size = 0;
+
+ for( unsigned i = 0; i < sortedPads.size(); ++i )
+ {
+ D_PAD* pad = sortedPads[i];
+
+ // GetBoundingRadius() is the radius of the minimum sized circle fully containing the pad
+ int radius = pad->GetBoundingRadius();
+ if( radius > max_size )
+ max_size = radius;
+ }
+
+ // Test the pads
+ D_PAD** listEnd = &sortedPads[ sortedPads.size() ];
+
+ for( unsigned i = 0; i< sortedPads.size(); ++i )
+ {
+ D_PAD* pad = sortedPads[i];
+
+ int x_limit = max_size + pad->GetClearance() +
+ pad->GetBoundingRadius() + pad->GetPosition().x;
+
+ if( !doPadToPadsDrc( pad, &sortedPads[i], listEnd, x_limit ) )
+ {
+ wxASSERT( m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = 0;
+ }
+ }
+}
+
+
+void DRC::testTracks( wxWindow *aActiveWindow, bool aShowProgressBar )
+{
+ wxProgressDialog * progressDialog = NULL;
+ const int delta = 500; // This is the number of tests between 2 calls to the
+ // progress bar
+ int count = 0;
+ for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() )
+ count++;
+
+ int deltamax = count/delta;
+
+ if( aShowProgressBar && deltamax > 3 )
+ {
+ progressDialog = new wxProgressDialog( _( "Track clearances" ), wxEmptyString,
+ deltamax, aActiveWindow,
+ wxPD_AUTO_HIDE | wxPD_CAN_ABORT |
+ wxPD_APP_MODAL | wxPD_ELAPSED_TIME );
+ progressDialog->Update( 0, wxEmptyString );
+ }
+
+ int ii = 0;
+ count = 0;
+
+ for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() )
+ {
+ if ( ii++ > delta )
+ {
+ ii = 0;
+ count++;
+
+ if( progressDialog )
+ {
+ if( !progressDialog->Update( count, wxEmptyString ) )
+ break; // Aborted by user
+#ifdef __WXMAC__
+ // Work around a dialog z-order issue on OS X
+ if( count == deltamax )
+ aActiveWindow->Raise();
+#endif
+ }
+ }
+
+ if( !doTrackDrc( segm, segm->Next(), true ) )
+ {
+ wxASSERT( m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = 0;
+ }
+ }
+
+ if( progressDialog )
+ progressDialog->Destroy();
+}
+
+
+void DRC::testUnconnected()
+{
+ if( (m_pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
+ {
+ wxClientDC dc( m_mainWindow->GetCanvas() );
+ m_mainWindow->Compile_Ratsnest( &dc, true );
+ }
+
+ if( m_pcb->GetRatsnestsCount() == 0 )
+ return;
+
+ wxString msg;
+
+ for( unsigned ii = 0; ii < m_pcb->GetRatsnestsCount(); ++ii )
+ {
+ RATSNEST_ITEM& rat = m_pcb->m_FullRatsnest[ii];
+
+ if( (rat.m_Status & CH_ACTIF) == 0 )
+ continue;
+
+ D_PAD* padStart = rat.m_PadStart;
+ D_PAD* padEnd = rat.m_PadEnd;
+
+ msg = padStart->GetSelectMenuText() + wxT( " net " ) + padStart->GetNetname();
+
+ DRC_ITEM* uncItem = new DRC_ITEM( DRCE_UNCONNECTED_PADS,
+ msg,
+ padEnd->GetSelectMenuText(),
+ padStart->GetPosition(), padEnd->GetPosition() );
+
+ m_unconnected.push_back( uncItem );
+ }
+}
+
+
+void DRC::testZones()
+{
+ // Test copper areas for valid netcodes
+ // if a netcode is < 0 the netname was not found when reading a netlist
+ // if a netcode is == 0 the netname is void, and the zone is not connected.
+ // This is allowed, but i am not sure this is a good idea
+ //
+ // In recent Pcbnew versions, the netcode is always >= 0, but an internal net name
+ // is stored, and initalized from the file or the zone properpies editor.
+ // if it differs from the net name from net code, there is a DRC issue
+ for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* test_area = m_pcb->GetArea( ii );
+
+ if( !test_area->IsOnCopperLayer() )
+ continue;
+
+ int netcode = test_area->GetNetCode();
+
+ // a netcode < 0 or > 0 and no pad in net is a error or strange
+ // perhaps a "dead" net, which happens when all pads in this net were removed
+ // Remark: a netcode < 0 should not happen (this is more a bug somewhere)
+ int pads_in_net = (test_area->GetNetCode() > 0) ?
+ test_area->GetNet()->GetNodesCount() : 1;
+
+ if( ( netcode < 0 ) || pads_in_net == 0 )
+ {
+ m_currentMarker = fillMarker( test_area,
+ DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE, m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = NULL;
+ }
+ }
+
+ // Test copper areas outlines, and create markers when needed
+ m_pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines( NULL, true );
+}
+
+
+void DRC::testKeepoutAreas()
+{
+ // Test keepout areas for vias, tracks and pads inside keepout areas
+ for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* area = m_pcb->GetArea( ii );
+
+ if( !area->GetIsKeepout() )
+ continue;
+
+ for( TRACK* segm = m_pcb->m_Track; segm != NULL; segm = segm->Next() )
+ {
+ if( segm->Type() == PCB_TRACE_T )
+ {
+ if( ! area->GetDoNotAllowTracks() )
+ continue;
+
+ if( segm->GetLayer() != area->GetLayer() )
+ continue;
+
+ if( area->Outline()->Distance( segm->GetStart(), segm->GetEnd(),
+ segm->GetWidth() ) == 0 )
+ {
+ m_currentMarker = fillMarker( segm, NULL,
+ DRCE_TRACK_INSIDE_KEEPOUT, m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = 0;
+ }
+ }
+ else if( segm->Type() == PCB_VIA_T )
+ {
+ if( ! area->GetDoNotAllowVias() )
+ continue;
+
+ if( ! ((VIA*)segm)->IsOnLayer( area->GetLayer() ) )
+ continue;
+
+ if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 )
+ {
+ m_currentMarker = fillMarker( segm, NULL,
+ DRCE_VIA_INSIDE_KEEPOUT, m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = 0;
+ }
+ }
+ }
+ // Test pads: TODO
+ }
+}
+
+
+void DRC::testTexts()
+{
+ std::vector<wxPoint> textShape; // a buffer to store the text shape (set of segments)
+ std::vector<D_PAD*> padList = m_pcb->GetPads();
+
+ // Test text areas for vias, tracks and pads inside text areas
+ for( BOARD_ITEM* item = m_pcb->m_Drawings; item; item = item->Next() )
+ {
+ // Drc test only items on copper layers
+ if( ! IsCopperLayer( item->GetLayer() ) )
+ continue;
+
+ // only texts on copper layers are tested
+ if( item->Type() != PCB_TEXT_T )
+ continue;
+
+ textShape.clear();
+
+ // So far the bounding box makes up the text-area
+ TEXTE_PCB* text = (TEXTE_PCB*) item;
+ text->TransformTextShapeToSegmentList( textShape );
+
+ if( textShape.size() == 0 ) // Should not happen (empty text?)
+ continue;
+
+ for( TRACK* track = m_pcb->m_Track; track != NULL; track = track->Next() )
+ {
+ if( ! track->IsOnLayer( item->GetLayer() ) )
+ continue;
+
+ // Test the distance between each segment and the current track/via
+ int min_dist = ( track->GetWidth() + text->GetThickness() ) /2 +
+ track->GetClearance(NULL);
+
+ if( track->Type() == PCB_TRACE_T )
+ {
+ SEG segref( track->GetStart(), track->GetEnd() );
+
+ // Error condition: Distance between text segment and track segment is
+ // smaller than the clearance of the segment
+ for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
+ {
+ SEG segtest( textShape[jj], textShape[jj+1] );
+ int dist = segref.Distance( segtest );
+
+ if( dist < min_dist )
+ {
+ m_currentMarker = fillMarker( track, text,
+ DRCE_TRACK_INSIDE_TEXT,
+ m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = NULL;
+ break;
+ }
+ }
+ }
+ else if( track->Type() == PCB_VIA_T )
+ {
+ // Error condition: Distance between text segment and via is
+ // smaller than the clearance of the via
+ for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
+ {
+ SEG segtest( textShape[jj], textShape[jj+1] );
+
+ if( segtest.PointCloserThan( track->GetPosition(), min_dist ) )
+ {
+ m_currentMarker = fillMarker( track, text,
+ DRCE_VIA_INSIDE_TEXT, m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = NULL;
+ break;
+ }
+ }
+ }
+ }
+
+ // Test pads
+ for( unsigned ii = 0; ii < padList.size(); ii++ )
+ {
+ D_PAD* pad = padList[ii];
+
+ if( ! pad->IsOnLayer( item->GetLayer() ) )
+ continue;
+
+ wxPoint shape_pos = pad->ShapePos();
+
+ for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
+ {
+ /* In order to make some calculations more easier or faster,
+ * pads and tracks coordinates will be made relative
+ * to the segment origin
+ */
+ wxPoint origin = textShape[jj]; // origin will be the origin of other coordinates
+ m_segmEnd = textShape[jj+1] - origin;
+ wxPoint delta = m_segmEnd;
+ m_segmAngle = 0;
+
+ // for a non horizontal or vertical segment Compute the segment angle
+ // in tenths of degrees and its length
+ if( delta.x || delta.y ) // delta.x == delta.y == 0 for vias
+ {
+ // Compute the segment angle in 0,1 degrees
+ m_segmAngle = ArcTangente( delta.y, delta.x );
+
+ // Compute the segment length: we build an equivalent rotated segment,
+ // this segment is horizontal, therefore dx = length
+ RotatePoint( &delta, m_segmAngle ); // delta.x = length, delta.y = 0
+ }
+
+ m_segmLength = delta.x;
+ m_padToTestPos = shape_pos - origin;
+
+ if( !checkClearanceSegmToPad( pad, text->GetThickness(),
+ pad->GetClearance(NULL) ) )
+ {
+ m_currentMarker = fillMarker( pad, text,
+ DRCE_PAD_INSIDE_TEXT, m_currentMarker );
+ m_pcb->Add( m_currentMarker );
+ m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+ m_currentMarker = NULL;
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg )
+{
+ // Test keepout areas for vias, tracks and pads inside keepout areas
+ for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* area = m_pcb->GetArea( ii );
+
+ if( !area->GetIsKeepout() )
+ continue;
+
+ if( aRefSeg->Type() == PCB_TRACE_T )
+ {
+ if( ! area->GetDoNotAllowTracks() )
+ continue;
+
+ if( aRefSeg->GetLayer() != area->GetLayer() )
+ continue;
+
+ if( area->Outline()->Distance( aRefSeg->GetStart(), aRefSeg->GetEnd(),
+ aRefSeg->GetWidth() ) == 0 )
+ {
+ m_currentMarker = fillMarker( aRefSeg, NULL,
+ DRCE_TRACK_INSIDE_KEEPOUT, m_currentMarker );
+ return false;
+ }
+ }
+ else if( aRefSeg->Type() == PCB_VIA_T )
+ {
+ if( ! area->GetDoNotAllowVias() )
+ continue;
+
+ if( ! ((VIA*)aRefSeg)->IsOnLayer( area->GetLayer() ) )
+ continue;
+
+ if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 )
+ {
+ m_currentMarker = fillMarker( aRefSeg, NULL,
+ DRCE_VIA_INSIDE_KEEPOUT, m_currentMarker );
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+
+bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_limit )
+{
+ const static LSET all_cu = LSET::AllCuMask();
+
+ LSET layerMask = aRefPad->GetLayerSet() & all_cu;
+
+ /* used to test DRC pad to holes: this dummy pad has the size and shape of the hole
+ * to test pad to pad hole DRC, using the pad to pad DRC test function.
+ * Therefore, this dummy pad is a circle or an oval.
+ * A pad must have a parent because some functions expect a non null parent
+ * to find the parent board, and some other data
+ */
+ MODULE dummymodule( m_pcb ); // Creates a dummy parent
+ D_PAD dummypad( &dummymodule );
+
+ // Ensure the hole is on all copper layers
+ dummypad.SetLayerSet( all_cu | dummypad.GetLayerSet() );
+
+ // Use the minimal local clearance value for the dummy pad.
+ // The clearance of the active pad will be used as minimum distance to a hole
+ // (a value = 0 means use netclass value)
+ dummypad.SetLocalClearance( 1 );
+
+ for( D_PAD** pad_list = aStart; pad_list<aEnd; ++pad_list )
+ {
+ D_PAD* pad = *pad_list;
+
+ if( pad == aRefPad )
+ continue;
+
+ // We can stop the test when pad->GetPosition().x > x_limit
+ // because the list is sorted by X values
+ if( pad->GetPosition().x > x_limit )
+ break;
+
+ // No problem if pads which are on copper layers are on different copper layers,
+ // (pads can be only on a technical layer, to build complex pads)
+ // but their hole (if any ) can create DRC error because they are on all
+ // copper layers, so we test them
+ if( ( pad->GetLayerSet() & layerMask ) == 0 &&
+ ( pad->GetLayerSet() & all_cu ) != 0 &&
+ ( aRefPad->GetLayerSet() & all_cu ) != 0 )
+ {
+ // if holes are in the same location and have the same size and shape,
+ // this can be accepted
+ if( pad->GetPosition() == aRefPad->GetPosition()
+ && pad->GetDrillSize() == aRefPad->GetDrillSize()
+ && pad->GetDrillShape() == aRefPad->GetDrillShape() )
+ {
+ if( aRefPad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
+ continue;
+
+ // for oval holes: must also have the same orientation
+ if( pad->GetOrientation() == aRefPad->GetOrientation() )
+ continue;
+ }
+
+ /* Here, we must test clearance between holes and pads
+ * dummy pad size and shape is adjusted to pad drill size and shape
+ */
+ if( pad->GetDrillSize().x )
+ {
+ // pad under testing has a hole, test this hole against pad reference
+ dummypad.SetPosition( pad->GetPosition() );
+ dummypad.SetSize( pad->GetDrillSize() );
+ dummypad.SetShape( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
+ PAD_SHAPE_OVAL : PAD_SHAPE_CIRCLE );
+ dummypad.SetOrientation( pad->GetOrientation() );
+
+ if( !checkClearancePadToPad( aRefPad, &dummypad ) )
+ {
+ // here we have a drc error on pad!
+ m_currentMarker = fillMarker( pad, aRefPad,
+ DRCE_HOLE_NEAR_PAD, m_currentMarker );
+ return false;
+ }
+ }
+
+ if( aRefPad->GetDrillSize().x ) // pad reference has a hole
+ {
+ dummypad.SetPosition( aRefPad->GetPosition() );
+ dummypad.SetSize( aRefPad->GetDrillSize() );
+ dummypad.SetShape( aRefPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
+ PAD_SHAPE_OVAL : PAD_SHAPE_CIRCLE );
+ dummypad.SetOrientation( aRefPad->GetOrientation() );
+
+ if( !checkClearancePadToPad( pad, &dummypad ) )
+ {
+ // here we have a drc error on aRefPad!
+ m_currentMarker = fillMarker( aRefPad, pad,
+ DRCE_HOLE_NEAR_PAD, m_currentMarker );
+ return false;
+ }
+ }
+
+ continue;
+ }
+
+ // The pad must be in a net (i.e pt_pad->GetNet() != 0 ),
+ // But no problem if pads have the same netcode (same net)
+ if( pad->GetNetCode() && ( aRefPad->GetNetCode() == pad->GetNetCode() ) )
+ continue;
+
+ // if pads are from the same footprint
+ if( pad->GetParent() == aRefPad->GetParent() )
+ {
+ // and have the same pad number ( equivalent pads )
+
+ // one can argue that this 2nd test is not necessary, that any
+ // two pads from a single module are acceptable. This 2nd test
+ // should eventually be a configuration option.
+ if( pad->PadNameEqual( aRefPad ) )
+ continue;
+ }
+
+ // if either pad has no drill and is only on technical layers, not a clearance violation
+ if( ( ( pad->GetLayerSet() & layerMask ) == 0 && !pad->GetDrillSize().x ) ||
+ ( ( aRefPad->GetLayerSet() & layerMask ) == 0 && !aRefPad->GetDrillSize().x ) )
+ {
+ continue;
+ }
+
+ if( !checkClearancePadToPad( aRefPad, pad ) )
+ {
+ // here we have a drc error!
+ m_currentMarker = fillMarker( aRefPad, pad, DRCE_PAD_NEAR_PAD1, m_currentMarker );
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp
new file mode 100644
index 0000000..39d1b9d
--- /dev/null
+++ b/pcbnew/drc_clearance_test_functions.cpp
@@ -0,0 +1,1191 @@
+/**
+ * @file drc_clearance_test_functions.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2015 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/****************************/
+/* DRC control */
+/****************************/
+
+#include <fctsys.h>
+#include <wxPcbStruct.h>
+#include <trigo.h>
+
+#include <pcbnew.h>
+#include <drc_stuff.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_zone.h>
+#include <class_marker_pcb.h>
+#include <math_for_graphics.h>
+#include <polygon_test_point_inside.h>
+
+
+/* compare 2 trapezoids (can be rectangle) and return true if distance > aDist
+ * i.e if for each edge of the first polygon distance from each edge of the other polygon
+ * is >= aDist
+ */
+bool trapezoid2trapezoidDRC( wxPoint aTref[4], wxPoint aTcompare[4], int aDist )
+{
+ /* Test if one polygon is contained in the other and thus the polygon overlap.
+ * This case is not covered by the following check if one polygond is
+ * completely contained in the other (because edges don't intersect)!
+ */
+ if( TestPointInsidePolygon( aTref, 4, aTcompare[0] ) )
+ return false;
+
+ if( TestPointInsidePolygon( aTcompare, 4, aTref[0] ) )
+ return false;
+
+ int ii, jj, kk, ll;
+
+ for( ii = 0, jj = 3; ii<4; jj = ii, ii++ ) // for all edges in aTref
+ {
+ for( kk = 0, ll = 3; kk < 4; ll = kk, kk++ ) // for all edges in aTcompare
+ {
+ double d;
+ int intersect = TestForIntersectionOfStraightLineSegments( aTref[ii].x,
+ aTref[ii].y,
+ aTref[jj].x,
+ aTref[jj].y,
+ aTcompare[kk].x,
+ aTcompare[kk].y,
+ aTcompare[ll].x,
+ aTcompare[ll].y,
+ NULL, NULL, &d );
+ if( intersect || (d< aDist) )
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+/* compare a trapezoids (can be rectangle) and a segment and return true if distance > aDist
+ */
+bool trapezoid2segmentDRC( wxPoint aTref[4], wxPoint aSegStart, wxPoint aSegEnd, int aDist )
+{
+ /* Test if the segment is contained in the polygon.
+ * This case is not covered by the following check if the segment is
+ * completely contained in the polygon (because edges don't intersect)!
+ */
+ if( TestPointInsidePolygon( aTref, 4, aSegStart ) )
+ return false;
+
+ int ii, jj;
+
+ for( ii = 0, jj = 3; ii < 4; jj = ii, ii++ ) // for all edges in aTref
+ {
+ double d;
+ int intersect = TestForIntersectionOfStraightLineSegments( aTref[ii].x,
+ aTref[ii].y,
+ aTref[jj].x,
+ aTref[jj].y,
+ aSegStart.x,
+ aSegStart.y,
+ aSegEnd.x,
+ aSegEnd.y,
+ NULL, NULL, &d );
+ if( intersect || (d< aDist) )
+ return false;
+ }
+
+ return true;
+}
+
+
+/* compare a trapezoid to a point and return true if distance > aDist
+ * do not use this function for horizontal or vertical rectangles
+ * because there is a faster an easier way to compare the distance
+ */
+bool trapezoid2pointDRC( wxPoint aTref[4], wxPoint aPcompare, int aDist )
+{
+ /* Test if aPcompare point is contained in the polygon.
+ * This case is not covered by the following check if this point is inside the polygon
+ */
+ if( TestPointInsidePolygon( aTref, 4, aPcompare ) )
+ {
+ return false;
+ }
+
+ // Test distance between aPcompare and each segment of the polygon:
+ for( int ii = 0, jj = 3; ii < 4; jj = ii, ii++ ) // for all edge in polygon
+ {
+ if( TestSegmentHit( aTref[ii], aTref[jj], aPcompare, aDist ) )
+ return false;
+ }
+
+ return true;
+}
+
+
+bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
+{
+ TRACK* track;
+ wxPoint delta; // lenght on X and Y axis of segments
+ LSET layerMask;
+ int net_code_ref;
+ wxPoint shape_pos;
+
+ NETCLASSPTR netclass = aRefSeg->GetNetClass();
+ BOARD_DESIGN_SETTINGS& dsnSettings = m_pcb->GetDesignSettings();
+
+ /* In order to make some calculations more easier or faster,
+ * pads and tracks coordinates will be made relative to the reference segment origin
+ */
+ wxPoint origin = aRefSeg->GetStart(); // origin will be the origin of other coordinates
+
+ m_segmEnd = delta = aRefSeg->GetEnd() - origin;
+ m_segmAngle = 0;
+
+ layerMask = aRefSeg->GetLayerSet();
+ net_code_ref = aRefSeg->GetNetCode();
+
+ // Phase 0 : Test vias
+ if( aRefSeg->Type() == PCB_VIA_T )
+ {
+ const VIA *refvia = static_cast<const VIA*>( aRefSeg );
+ // test if the via size is smaller than minimum
+ if( refvia->GetViaType() == VIA_MICROVIA )
+ {
+ if( refvia->GetWidth() < dsnSettings.m_MicroViasMinSize )
+ {
+ m_currentMarker = fillMarker( refvia, NULL,
+ DRCE_TOO_SMALL_MICROVIA, m_currentMarker );
+ return false;
+ }
+ }
+ else
+ {
+ if( refvia->GetWidth() < dsnSettings.m_ViasMinSize )
+ {
+ m_currentMarker = fillMarker( refvia, NULL,
+ DRCE_TOO_SMALL_VIA, m_currentMarker );
+ return false;
+ }
+ }
+
+ // test if via's hole is bigger than its diameter
+ // This test is necessary since the via hole size and width can be modified
+ // and a default via hole can be bigger than some vias sizes
+ if( refvia->GetDrillValue() > refvia->GetWidth() )
+ {
+ m_currentMarker = fillMarker( refvia, NULL,
+ DRCE_VIA_HOLE_BIGGER, m_currentMarker );
+ return false;
+ }
+
+ // For microvias: test if they are blind vias and only between 2 layers
+ // because they are used for very small drill size and are drill by laser
+ // and **only one layer** can be drilled
+ if( refvia->GetViaType() == VIA_MICROVIA )
+ {
+ LAYER_ID layer1, layer2;
+ bool err = true;
+
+ refvia->LayerPair( &layer1, &layer2 );
+
+ if( layer1 > layer2 )
+ std::swap( layer1, layer2 );
+
+ if( layer2 == B_Cu && layer1 == m_pcb->GetDesignSettings().GetCopperLayerCount() - 2 )
+ err = false;
+ else if( layer1 == F_Cu && layer2 == In1_Cu )
+ err = false;
+
+ if( err )
+ {
+ m_currentMarker = fillMarker( refvia, NULL,
+ DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR, m_currentMarker );
+ return false;
+ }
+ }
+ }
+ else // This is a track segment
+ {
+ if( aRefSeg->GetWidth() < dsnSettings.m_TrackMinWidth )
+ {
+ m_currentMarker = fillMarker( aRefSeg, NULL,
+ DRCE_TOO_SMALL_TRACK_WIDTH, m_currentMarker );
+ return false;
+ }
+ }
+
+ // for a non horizontal or vertical segment Compute the segment angle
+ // in tenths of degrees and its length
+ if( delta.x || delta.y )
+ {
+ // Compute the segment angle in 0,1 degrees
+ m_segmAngle = ArcTangente( delta.y, delta.x );
+
+ // Compute the segment length: we build an equivalent rotated segment,
+ // this segment is horizontal, therefore dx = length
+ RotatePoint( &delta, m_segmAngle ); // delta.x = length, delta.y = 0
+ }
+
+ m_segmLength = delta.x;
+
+ /******************************************/
+ /* Phase 1 : test DRC track to pads : */
+ /******************************************/
+
+ /* Use a dummy pad to test DRC tracks versus holes, for pads not on all copper layers
+ * but having a hole
+ * This dummy pad has the size and shape of the hole
+ * to test tracks to pad hole DRC, using checkClearanceSegmToPad test function.
+ * Therefore, this dummy pad is a circle or an oval.
+ * A pad must have a parent because some functions expect a non null parent
+ * to find the parent board, and some other data
+ */
+ MODULE dummymodule( m_pcb ); // Creates a dummy parent
+ D_PAD dummypad( &dummymodule );
+
+ dummypad.SetLayerSet( LSET::AllCuMask() ); // Ensure the hole is on all layers
+
+ // Compute the min distance to pads
+ if( testPads )
+ {
+ unsigned pad_count = m_pcb->GetPadCount();
+
+ for( unsigned ii = 0; ii<pad_count; ++ii )
+ {
+ D_PAD* pad = m_pcb->GetPad( ii );
+
+ /* No problem if pads are on an other layer,
+ * But if a drill hole exists (a pad on a single layer can have a hole!)
+ * we must test the hole
+ */
+ if( !( pad->GetLayerSet() & layerMask ).any() )
+ {
+ /* We must test the pad hole. In order to use the function
+ * checkClearanceSegmToPad(),a pseudo pad is used, with a shape and a
+ * size like the hole
+ */
+ if( pad->GetDrillSize().x == 0 )
+ continue;
+
+ dummypad.SetSize( pad->GetDrillSize() );
+ dummypad.SetPosition( pad->GetPosition() );
+ dummypad.SetShape( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
+ PAD_SHAPE_OVAL : PAD_SHAPE_CIRCLE );
+ dummypad.SetOrientation( pad->GetOrientation() );
+
+ m_padToTestPos = dummypad.GetPosition() - origin;
+
+ if( !checkClearanceSegmToPad( &dummypad, aRefSeg->GetWidth(),
+ netclass->GetClearance() ) )
+ {
+ m_currentMarker = fillMarker( aRefSeg, pad,
+ DRCE_TRACK_NEAR_THROUGH_HOLE, m_currentMarker );
+ return false;
+ }
+
+ continue;
+ }
+
+ // The pad must be in a net (i.e pt_pad->GetNet() != 0 )
+ // but no problem if the pad netcode is the current netcode (same net)
+ if( pad->GetNetCode() // the pad must be connected
+ && net_code_ref == pad->GetNetCode() ) // the pad net is the same as current net -> Ok
+ continue;
+
+ // DRC for the pad
+ shape_pos = pad->ShapePos();
+ m_padToTestPos = shape_pos - origin;
+
+ if( !checkClearanceSegmToPad( pad, aRefSeg->GetWidth(), aRefSeg->GetClearance( pad ) ) )
+ {
+ m_currentMarker = fillMarker( aRefSeg, pad,
+ DRCE_TRACK_NEAR_PAD, m_currentMarker );
+ return false;
+ }
+ }
+ }
+
+ /***********************************************/
+ /* Phase 2: test DRC with other track segments */
+ /***********************************************/
+
+ // At this point the reference segment is the X axis
+
+ // Test the reference segment with other track segments
+ wxPoint segStartPoint;
+ wxPoint segEndPoint;
+ for( track = aStart; track; track = track->Next() )
+ {
+ // No problem if segments have the same net code:
+ if( net_code_ref == track->GetNetCode() )
+ continue;
+
+ // No problem if segment are on different layers :
+ if( !( layerMask & track->GetLayerSet() ).any() )
+ continue;
+
+ // the minimum distance = clearance plus half the reference track
+ // width plus half the other track's width
+ int w_dist = aRefSeg->GetClearance( track );
+ w_dist += (aRefSeg->GetWidth() + track->GetWidth()) / 2;
+
+ // If the reference segment is a via, we test it here
+ if( aRefSeg->Type() == PCB_VIA_T )
+ {
+ delta = track->GetEnd() - track->GetStart();
+ segStartPoint = aRefSeg->GetStart() - track->GetStart();
+
+ if( track->Type() == PCB_VIA_T )
+ {
+ // Test distance between two vias, i.e. two circles, trivial case
+ if( EuclideanNorm( segStartPoint ) < w_dist )
+ {
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_VIA_NEAR_VIA, m_currentMarker );
+ return false;
+ }
+ }
+ else // test via to segment
+ {
+ // Compute l'angle du segment a tester;
+ double angle = ArcTangente( delta.y, delta.x );
+
+ // Compute new coordinates ( the segment become horizontal)
+ RotatePoint( &delta, angle );
+ RotatePoint( &segStartPoint, angle );
+
+ if( !checkMarginToCircle( segStartPoint, w_dist, delta.x ) )
+ {
+ m_currentMarker = fillMarker( track, aRefSeg,
+ DRCE_VIA_NEAR_TRACK, m_currentMarker );
+ return false;
+ }
+ }
+
+ continue;
+ }
+
+ /* We compute segStartPoint, segEndPoint = starting and ending point coordinates for
+ * the segment to test in the new axis : the new X axis is the
+ * reference segment. We must translate and rotate the segment to test
+ */
+ segStartPoint = track->GetStart() - origin;
+ segEndPoint = track->GetEnd() - origin;
+ RotatePoint( &segStartPoint, m_segmAngle );
+ RotatePoint( &segEndPoint, m_segmAngle );
+ if( track->Type() == PCB_VIA_T )
+ {
+ if( checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
+ continue;
+
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_TRACK_NEAR_VIA, m_currentMarker );
+ return false;
+ }
+
+ /* We have changed axis:
+ * the reference segment is Horizontal.
+ * 3 cases : the segment to test can be parallel, perpendicular or have an other direction
+ */
+ if( segStartPoint.y == segEndPoint.y ) // parallel segments
+ {
+ if( abs( segStartPoint.y ) >= w_dist )
+ continue;
+
+ // Ensure segStartPoint.x <= segEndPoint.x
+ if( segStartPoint.x > segEndPoint.x )
+ std::swap( segStartPoint.x, segEndPoint.x );
+
+ if( segStartPoint.x > (-w_dist) && segStartPoint.x < (m_segmLength + w_dist) ) /* possible error drc */
+ {
+ // the start point is inside the reference range
+ // X........
+ // O--REF--+
+
+ // Fine test : we consider the rounded shape of each end of the track segment:
+ if( segStartPoint.x >= 0 && segStartPoint.x <= m_segmLength )
+ {
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_TRACK_ENDS1, m_currentMarker );
+ return false;
+ }
+
+ if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
+ {
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_TRACK_ENDS2, m_currentMarker );
+ return false;
+ }
+ }
+
+ if( segEndPoint.x > (-w_dist) && segEndPoint.x < (m_segmLength + w_dist) )
+ {
+ // the end point is inside the reference range
+ // .....X
+ // O--REF--+
+ // Fine test : we consider the rounded shape of the ends
+ if( segEndPoint.x >= 0 && segEndPoint.x <= m_segmLength )
+ {
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_TRACK_ENDS3, m_currentMarker );
+ return false;
+ }
+
+ if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength ) )
+ {
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_TRACK_ENDS4, m_currentMarker );
+ return false;
+ }
+ }
+
+ if( segStartPoint.x <=0 && segEndPoint.x >= 0 )
+ {
+ // the segment straddles the reference range (this actually only
+ // checks if it straddles the origin, because the other cases where already
+ // handled)
+ // X.............X
+ // O--REF--+
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_TRACK_SEGMENTS_TOO_CLOSE, m_currentMarker );
+ return false;
+ }
+ }
+ else if( segStartPoint.x == segEndPoint.x ) // perpendicular segments
+ {
+ if( ( segStartPoint.x <= (-w_dist) ) || ( segStartPoint.x >= (m_segmLength + w_dist) ) )
+ continue;
+
+ // Test if segments are crossing
+ if( segStartPoint.y > segEndPoint.y )
+ std::swap( segStartPoint.y, segEndPoint.y );
+
+ if( (segStartPoint.y < 0) && (segEndPoint.y > 0) )
+ {
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_TRACKS_CROSSING, m_currentMarker );
+ return false;
+ }
+
+ // At this point the drc error is due to an end near a reference segm end
+ if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
+ {
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_ENDS_PROBLEM1, m_currentMarker );
+ return false;
+ }
+ if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength ) )
+ {
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_ENDS_PROBLEM2, m_currentMarker );
+ return false;
+ }
+ }
+ else // segments quelconques entre eux
+ {
+ // calcul de la "surface de securite du segment de reference
+ // First rought 'and fast) test : the track segment is like a rectangle
+
+ m_xcliplo = m_ycliplo = -w_dist;
+ m_xcliphi = m_segmLength + w_dist;
+ m_ycliphi = w_dist;
+
+ // A fine test is needed because a serment is not exactly a
+ // rectangle, it has rounded ends
+ if( !checkLine( segStartPoint, segEndPoint ) )
+ {
+ /* 2eme passe : the track has rounded ends.
+ * we must a fine test for each rounded end and the
+ * rectangular zone
+ */
+
+ m_xcliplo = 0;
+ m_xcliphi = m_segmLength;
+
+ if( !checkLine( segStartPoint, segEndPoint ) )
+ {
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_ENDS_PROBLEM3, m_currentMarker );
+ return false;
+ }
+ else // The drc error is due to the starting or the ending point of the reference segment
+ {
+ // Test the starting and the ending point
+ segStartPoint = track->GetStart();
+ segEndPoint = track->GetEnd();
+ delta = segEndPoint - segStartPoint;
+
+ // Compute the segment orientation (angle) en 0,1 degre
+ double angle = ArcTangente( delta.y, delta.x );
+
+ // Compute the segment lenght: delta.x = lenght after rotation
+ RotatePoint( &delta, angle );
+
+ /* Comute the reference segment coordinates relatives to a
+ * X axis = current tested segment
+ */
+ wxPoint relStartPos = aRefSeg->GetStart() - segStartPoint;
+ wxPoint relEndPos = aRefSeg->GetEnd() - segStartPoint;
+
+ RotatePoint( &relStartPos, angle );
+ RotatePoint( &relEndPos, angle );
+
+ if( !checkMarginToCircle( relStartPos, w_dist, delta.x ) )
+ {
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_ENDS_PROBLEM4, m_currentMarker );
+ return false;
+ }
+
+ if( !checkMarginToCircle( relEndPos, w_dist, delta.x ) )
+ {
+ m_currentMarker = fillMarker( aRefSeg, track,
+ DRCE_ENDS_PROBLEM5, m_currentMarker );
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+
+/* test DRC between 2 pads.
+ * this function can be also used to test DRC between a pas and a hole,
+ * because a hole is like a round pad.
+ */
+bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
+{
+ int dist;
+
+ double pad_angle;
+
+ // Get the clearance between the 2 pads. this is the min distance between aRefPad and aPad
+ int dist_min = aRefPad->GetClearance( aPad );
+
+ // relativePadPos is the aPad shape position relative to the aRefPad shape position
+ wxPoint relativePadPos = aPad->ShapePos() - aRefPad->ShapePos();
+
+ dist = KiROUND( EuclideanNorm( relativePadPos ) );
+
+ // Quick test: Clearance is OK if the bounding circles are further away than "dist_min"
+ if( (dist - aRefPad->GetBoundingRadius() - aPad->GetBoundingRadius()) >= dist_min )
+ return true;
+
+ /* Here, pads are near and DRC depend on the pad shapes
+ * We must compare distance using a fine shape analysis
+ * Because a circle or oval shape is the easier shape to test, try to have
+ * aRefPad shape type = PAD_SHAPE_CIRCLE or PAD_SHAPE_OVAL.
+ * if aRefPad = TRAP. and aPad = RECT, also swap pads
+ * Swap aRefPad and aPad if needed
+ */
+ bool swap_pads;
+ swap_pads = false;
+
+ // swap pads to make comparisons easier
+ // priority is aRefPad = ROUND then OVAL then RECT then other
+ if( aRefPad->GetShape() != aPad->GetShape() && aRefPad->GetShape() != PAD_SHAPE_CIRCLE )
+ {
+ // pad ref shape is here oval, rect or trapezoid
+ switch( aPad->GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+ swap_pads = true;
+ break;
+
+ case PAD_SHAPE_OVAL:
+ swap_pads = true;
+ break;
+
+ case PAD_SHAPE_RECT:
+ if( aRefPad->GetShape() != PAD_SHAPE_OVAL )
+ swap_pads = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( swap_pads )
+ {
+ std::swap( aRefPad, aPad );
+ relativePadPos = -relativePadPos;
+ }
+
+ /* Because pad exchange, aRefPad shape is PAD_SHAPE_CIRCLE or PAD_SHAPE_OVAL,
+ * if one of the 2 pads was a PAD_SHAPE_CIRCLE or PAD_SHAPE_OVAL.
+ * Therefore, if aRefPad is a PAD_SHAPE_SHAPE_RECT or a PAD_SHAPE_TRAPEZOID,
+ * aPad is also a PAD_SHAPE_RECT or a PAD_SHAPE_TRAPEZOID
+ */
+ bool diag = true;
+
+ switch( aRefPad->GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+
+ /* One can use checkClearanceSegmToPad to test clearance
+ * aRefPad is like a track segment with a null length and a witdth = GetSize().x
+ */
+ m_segmLength = 0;
+ m_segmAngle = 0;
+
+ m_segmEnd.x = m_segmEnd.y = 0;
+
+ m_padToTestPos = relativePadPos;
+ diag = checkClearanceSegmToPad( aPad, aRefPad->GetSize().x, dist_min );
+ break;
+
+ case PAD_SHAPE_RECT:
+ // pad_angle = pad orient relative to the aRefPad orient
+ pad_angle = aRefPad->GetOrientation() + aPad->GetOrientation();
+ NORMALIZE_ANGLE_POS( pad_angle );
+
+ if( aPad->GetShape() == PAD_SHAPE_RECT )
+ {
+ wxSize size = aPad->GetSize();
+
+ // The trivial case is if both rects are rotated by multiple of 90 deg
+ // Most of time this is the case, and the test is fast
+ if( ( (aRefPad->GetOrientation() == 0) || (aRefPad->GetOrientation() == 900)
+ || (aRefPad->GetOrientation() == 1800) || (aRefPad->GetOrientation() == 2700) )
+ && ( (aPad->GetOrientation() == 0) || (aPad->GetOrientation() == 900) || (aPad->GetOrientation() == 1800)
+ || (aPad->GetOrientation() == 2700) ) )
+ {
+ if( (pad_angle == 900) || (pad_angle == 2700) )
+ {
+ std::swap( size.x, size.y );
+ }
+
+ // Test DRC:
+ diag = false;
+ RotatePoint( &relativePadPos, aRefPad->GetOrientation() );
+ relativePadPos.x = std::abs( relativePadPos.x );
+ relativePadPos.y = std::abs( relativePadPos.y );
+
+ if( ( relativePadPos.x - ( (size.x + aRefPad->GetSize().x) / 2 ) ) >= dist_min )
+ diag = true;
+
+ if( ( relativePadPos.y - ( (size.y + aRefPad->GetSize().y) / 2 ) ) >= dist_min )
+ diag = true;
+ }
+ else // at least one pad has any other orient. Test is more tricky
+ { // Use the trapezoid2trapezoidDRC which also compare 2 rectangles with any orientation
+ wxPoint polyref[4]; // Shape of aRefPad
+ wxPoint polycompare[4]; // Shape of aPad
+ aRefPad->BuildPadPolygon( polyref, wxSize( 0, 0 ), aRefPad->GetOrientation() );
+ aPad->BuildPadPolygon( polycompare, wxSize( 0, 0 ), aPad->GetOrientation() );
+
+ // Move aPad shape to relativePadPos
+ for( int ii = 0; ii < 4; ii++ )
+ polycompare[ii] += relativePadPos;
+
+ // And now test polygons:
+ if( !trapezoid2trapezoidDRC( polyref, polycompare, dist_min ) )
+ diag = false;
+ }
+ }
+ else if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID )
+ {
+ wxPoint polyref[4]; // Shape of aRefPad
+ wxPoint polycompare[4]; // Shape of aPad
+ aRefPad->BuildPadPolygon( polyref, wxSize( 0, 0 ), aRefPad->GetOrientation() );
+ aPad->BuildPadPolygon( polycompare, wxSize( 0, 0 ), aPad->GetOrientation() );
+
+ // Move aPad shape to relativePadPos
+ for( int ii = 0; ii < 4; ii++ )
+ polycompare[ii] += relativePadPos;
+
+ // And now test polygons:
+ if( !trapezoid2trapezoidDRC( polyref, polycompare, dist_min ) )
+ diag = false;
+ }
+ else
+ {
+ // Should not occur, because aPad and aRefPad are swapped
+ // to have only aPad shape RECT or TRAP and aRefPad shape TRAP or RECT.
+ wxLogDebug( wxT( "DRC::checkClearancePadToPad: unexpected pad ref RECT @ %d, %d to pad shape %d @ %d, %d"),
+ aRefPad->GetPosition().x, aRefPad->GetPosition().y,
+ aPad->GetShape(), aPad->GetPosition().x, aPad->GetPosition().y );
+ }
+ break;
+
+ case PAD_SHAPE_OVAL: /* an oval pad is like a track segment */
+ {
+ /* Create a track segment with same dimensions as the oval aRefPad
+ * and use checkClearanceSegmToPad function to test aPad to aRefPad clearance
+ */
+ int segm_width;
+ m_segmAngle = aRefPad->GetOrientation(); // Segment orient.
+
+ if( aRefPad->GetSize().y < aRefPad->GetSize().x ) // Build an horizontal equiv segment
+ {
+ segm_width = aRefPad->GetSize().y;
+ m_segmLength = aRefPad->GetSize().x - aRefPad->GetSize().y;
+ }
+ else // Vertical oval: build an horizontal equiv segment and rotate 90.0 deg
+ {
+ segm_width = aRefPad->GetSize().x;
+ m_segmLength = aRefPad->GetSize().y - aRefPad->GetSize().x;
+ m_segmAngle += 900;
+ }
+
+ /* the start point must be 0,0 and currently relativePadPos
+ * is relative the center of pad coordinate */
+ wxPoint segstart;
+ segstart.x = -m_segmLength / 2; // Start point coordinate of the horizontal equivalent segment
+
+ RotatePoint( &segstart, m_segmAngle ); // actual start point coordinate of the equivalent segment
+ // Calculate segment end position relative to the segment origin
+ m_segmEnd.x = -2 * segstart.x;
+ m_segmEnd.y = -2 * segstart.y;
+
+ // Recalculate the equivalent segment angle in 0,1 degrees
+ // to prepare a call to checkClearanceSegmToPad()
+ m_segmAngle = ArcTangente( m_segmEnd.y, m_segmEnd.x );
+
+ // move pad position relative to the segment origin
+ m_padToTestPos = relativePadPos - segstart;
+
+ // Use segment to pad check to test the second pad:
+ diag = checkClearanceSegmToPad( aPad, segm_width, dist_min );
+ break;
+ }
+
+ case PAD_SHAPE_TRAPEZOID:
+
+ // at this point, aPad is also a trapezoid, because all other shapes
+ // have priority, and are already tested
+ wxASSERT( aPad->GetShape() == PAD_SHAPE_TRAPEZOID );
+ {
+ wxPoint polyref[4]; // Shape of aRefPad
+ wxPoint polycompare[4]; // Shape of aPad
+ aRefPad->BuildPadPolygon( polyref, wxSize( 0, 0 ), aRefPad->GetOrientation() );
+ aPad->BuildPadPolygon( polycompare, wxSize( 0, 0 ), aPad->GetOrientation() );
+
+ // Move aPad shape to relativePadPos
+ for( int ii = 0; ii < 4; ii++ )
+ polycompare[ii] += relativePadPos;
+
+ // And now test polygons:
+ if( !trapezoid2trapezoidDRC( polyref, polycompare, dist_min ) )
+ diag = false;
+ }
+ break;
+
+ default:
+ wxLogDebug( wxT( "DRC::checkClearancePadToPad: unexpected pad shape" ) );
+ break;
+ }
+
+ return diag;
+}
+
+
+/* test if distance between a segment is > aMinDist
+ * segment start point is assumed in (0,0) and segment start point in m_segmEnd
+ * and its orientation is m_segmAngle (m_segmAngle must be already initialized)
+ * and have aSegmentWidth.
+ */
+bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMinDist )
+{
+ wxSize padHalfsize; // half dimension of the pad
+ wxPoint startPoint, endPoint;
+
+ int segmHalfWidth = aSegmentWidth / 2;
+ int distToLine = segmHalfWidth + aMinDist;
+
+ padHalfsize.x = aPad->GetSize().x >> 1;
+ padHalfsize.y = aPad->GetSize().y >> 1;
+
+ if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID ) // The size is bigger, due to GetDelta() extra size
+ {
+ padHalfsize.x += std::abs(aPad->GetDelta().y) / 2; // Remember: GetDelta().y is the GetSize().x change
+ padHalfsize.y += std::abs(aPad->GetDelta().x) / 2; // Remember: GetDelta().x is the GetSize().y change
+ }
+
+ if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
+ {
+ /* Easy case: just test the distance between segment and pad centre
+ * calculate pad coordinates in the X,Y axis with X axis = segment to test
+ */
+ RotatePoint( &m_padToTestPos, m_segmAngle );
+ return checkMarginToCircle( m_padToTestPos, distToLine + padHalfsize.x, m_segmLength );
+ }
+
+ /* calculate the bounding box of the pad, including the clearance and the segment width
+ * if the line from 0 to m_segmEnd does not intersect this bounding box,
+ * the clearance is always OK
+ * But if intersect, a better analysis of the pad shape must be done.
+ */
+ m_xcliplo = m_padToTestPos.x - distToLine - padHalfsize.x;
+ m_ycliplo = m_padToTestPos.y - distToLine - padHalfsize.y;
+ m_xcliphi = m_padToTestPos.x + distToLine + padHalfsize.x;
+ m_ycliphi = m_padToTestPos.y + distToLine + padHalfsize.y;
+
+ startPoint.x = startPoint.y = 0;
+ endPoint = m_segmEnd;
+
+ double orient = aPad->GetOrientation();
+
+ RotatePoint( &startPoint, m_padToTestPos, -orient );
+ RotatePoint( &endPoint, m_padToTestPos, -orient );
+
+ if( checkLine( startPoint, endPoint ) )
+ return true;
+
+ /* segment intersects the bounding box. But there is not always a DRC error.
+ * A fine analysis of the pad shape must be done.
+ */
+ switch( aPad->GetShape() )
+ {
+ default:
+ return false;
+
+ case PAD_SHAPE_OVAL:
+ {
+ /* an oval is a complex shape, but is a rectangle and 2 circles
+ * these 3 basic shapes are more easy to test.
+ *
+ * In calculations we are using a vertical oval shape
+ * (i.e. a vertical rounded segment)
+ * for horizontal oval shapes, swap x and y size and rotate the shape
+ */
+ if( padHalfsize.x > padHalfsize.y )
+ {
+ std::swap( padHalfsize.x, padHalfsize.y );
+ orient = AddAngles( orient, 900 );
+ }
+
+ // here, padHalfsize.x is the radius of rounded ends.
+
+ int deltay = padHalfsize.y - padHalfsize.x;
+ // here: padHalfsize.x = radius,
+ // deltay = dist between the centre pad and the centre of a rounded end
+
+ // Test the rectangular area between the two circles (the rounded ends)
+ m_xcliplo = m_padToTestPos.x - distToLine - padHalfsize.x;
+ m_ycliplo = m_padToTestPos.y - deltay;
+ m_xcliphi = m_padToTestPos.x + distToLine + padHalfsize.x;
+ m_ycliphi = m_padToTestPos.y + deltay;
+
+ if( !checkLine( startPoint, endPoint ) )
+ {
+ return false;
+ }
+
+ // test the first circle
+ startPoint.x = m_padToTestPos.x; // startPoint = centre of the upper circle of the oval shape
+ startPoint.y = m_padToTestPos.y + deltay;
+
+ // Calculate the actual position of the circle, given the pad orientation:
+ RotatePoint( &startPoint, m_padToTestPos, orient );
+
+ // Calculate the actual position of the circle in the new X,Y axis:
+ RotatePoint( &startPoint, m_segmAngle );
+
+ if( !checkMarginToCircle( startPoint, padHalfsize.x + distToLine, m_segmLength ) )
+ {
+ return false;
+ }
+
+ // test the second circle
+ startPoint.x = m_padToTestPos.x; // startPoint = centre of the lower circle of the oval shape
+ startPoint.y = m_padToTestPos.y - deltay;
+ RotatePoint( &startPoint, m_padToTestPos, orient );
+ RotatePoint( &startPoint, m_segmAngle );
+
+ if( !checkMarginToCircle( startPoint, padHalfsize.x + distToLine, m_segmLength ) )
+ {
+ return false;
+ }
+ }
+ break;
+
+ case PAD_SHAPE_RECT:
+ // the area to test is a rounded rectangle.
+ // this can be done by testing 2 rectangles and 4 circles (the corners)
+
+ // Testing the first rectangle dimx + distToLine, dimy:
+ m_xcliplo = m_padToTestPos.x - padHalfsize.x - distToLine;
+ m_ycliplo = m_padToTestPos.y - padHalfsize.y;
+ m_xcliphi = m_padToTestPos.x + padHalfsize.x + distToLine;
+ m_ycliphi = m_padToTestPos.y + padHalfsize.y;
+
+ if( !checkLine( startPoint, endPoint ) )
+ return false;
+
+ // Testing the second rectangle dimx , dimy + distToLine
+ m_xcliplo = m_padToTestPos.x - padHalfsize.x;
+ m_ycliplo = m_padToTestPos.y - padHalfsize.y - distToLine;
+ m_xcliphi = m_padToTestPos.x + padHalfsize.x;
+ m_ycliphi = m_padToTestPos.y + padHalfsize.y + distToLine;
+
+ if( !checkLine( startPoint, endPoint ) )
+ return false;
+
+ // testing the 4 circles which are the clearance area of each corner:
+
+ // testing the left top corner of the rectangle
+ startPoint.x = m_padToTestPos.x - padHalfsize.x;
+ startPoint.y = m_padToTestPos.y - padHalfsize.y;
+ RotatePoint( &startPoint, m_padToTestPos, orient );
+ RotatePoint( &startPoint, m_segmAngle );
+
+ if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
+ return false;
+
+ // testing the right top corner of the rectangle
+ startPoint.x = m_padToTestPos.x + padHalfsize.x;
+ startPoint.y = m_padToTestPos.y - padHalfsize.y;
+ RotatePoint( &startPoint, m_padToTestPos, orient );
+ RotatePoint( &startPoint, m_segmAngle );
+
+ if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
+ return false;
+
+ // testing the left bottom corner of the rectangle
+ startPoint.x = m_padToTestPos.x - padHalfsize.x;
+ startPoint.y = m_padToTestPos.y + padHalfsize.y;
+ RotatePoint( &startPoint, m_padToTestPos, orient );
+ RotatePoint( &startPoint, m_segmAngle );
+
+ if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
+ return false;
+
+ // testing the right bottom corner of the rectangle
+ startPoint.x = m_padToTestPos.x + padHalfsize.x;
+ startPoint.y = m_padToTestPos.y + padHalfsize.y;
+ RotatePoint( &startPoint, m_padToTestPos, orient );
+ RotatePoint( &startPoint, m_segmAngle );
+
+ if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
+ return false;
+
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ {
+ wxPoint poly[4];
+ aPad->BuildPadPolygon( poly, wxSize( 0, 0 ), orient );
+
+ // Move shape to m_padToTestPos
+ for( int ii = 0; ii < 4; ii++ )
+ {
+ poly[ii] += m_padToTestPos;
+ RotatePoint( &poly[ii], m_segmAngle );
+ }
+
+ if( !trapezoid2segmentDRC( poly, wxPoint( 0, 0 ), wxPoint(m_segmLength,0), distToLine ) )
+ return false;
+ }
+ break;
+ }
+
+ return true;
+}
+
+
+/**
+ * Helper function checkMarginToCircle
+ * Check the distance between a circle (round pad, via or round end of track)
+ * and a segment. the segment is expected starting at 0,0, and on the X axis
+ * return true if distance >= aRadius
+ */
+bool DRC::checkMarginToCircle( wxPoint aCentre, int aRadius, int aLength )
+{
+ if( abs( aCentre.y ) > aRadius ) // trivial case
+ return true;
+
+ // Here, distance between aCentre and X axis is < aRadius
+ if( (aCentre.x >= -aRadius ) && ( aCentre.x <= (aLength + aRadius) ) )
+ {
+ if( (aCentre.x >= 0) && (aCentre.x <= aLength) )
+ return false; // aCentre is between the starting point and the ending point of the segm
+
+ if( aCentre.x > aLength ) // aCentre is after the ending point
+ aCentre.x -= aLength; // move aCentre to the starting point of the segment
+
+ if( EuclideanNorm( aCentre ) < aRadius )
+ // distance between aCentre and the starting point or the ending point is < aRadius
+ return false;
+ }
+
+ return true;
+}
+
+
+// Helper function used in checkLine::
+static inline int USCALE( unsigned arg, unsigned num, unsigned den )
+{
+ int ii;
+
+ ii = KiROUND( ( (double) arg * num ) / den );
+ return ii;
+}
+
+
+/** Helper function checkLine
+ * Test if a line intersects a bounding box (a rectangle)
+ * The rectangle is defined by m_xcliplo, m_ycliplo and m_xcliphi, m_ycliphi
+ * return true if the line from aSegStart to aSegEnd is outside the bounding box
+ */
+bool DRC::checkLine( wxPoint aSegStart, wxPoint aSegEnd )
+{
+#define WHEN_OUTSIDE return true
+#define WHEN_INSIDE
+ int temp;
+
+ if( aSegStart.x > aSegEnd.x )
+ std::swap( aSegStart, aSegEnd );
+
+ if( (aSegEnd.x < m_xcliplo) || (aSegStart.x > m_xcliphi) )
+ {
+ WHEN_OUTSIDE;
+ }
+
+ if( aSegStart.y < aSegEnd.y )
+ {
+ if( (aSegEnd.y < m_ycliplo) || (aSegStart.y > m_ycliphi) )
+ {
+ WHEN_OUTSIDE;
+ }
+
+ if( aSegStart.y < m_ycliplo )
+ {
+ temp = USCALE( (aSegEnd.x - aSegStart.x), (m_ycliplo - aSegStart.y),
+ (aSegEnd.y - aSegStart.y) );
+
+ if( (aSegStart.x += temp) > m_xcliphi )
+ {
+ WHEN_OUTSIDE;
+ }
+
+ aSegStart.y = m_ycliplo;
+ WHEN_INSIDE;
+ }
+
+ if( aSegEnd.y > m_ycliphi )
+ {
+ temp = USCALE( (aSegEnd.x - aSegStart.x), (aSegEnd.y - m_ycliphi),
+ (aSegEnd.y - aSegStart.y) );
+
+ if( (aSegEnd.x -= temp) < m_xcliplo )
+ {
+ WHEN_OUTSIDE;
+ }
+
+ aSegEnd.y = m_ycliphi;
+ WHEN_INSIDE;
+ }
+
+ if( aSegStart.x < m_xcliplo )
+ {
+ temp = USCALE( (aSegEnd.y - aSegStart.y), (m_xcliplo - aSegStart.x),
+ (aSegEnd.x - aSegStart.x) );
+ aSegStart.y += temp;
+ aSegStart.x = m_xcliplo;
+ WHEN_INSIDE;
+ }
+
+ if( aSegEnd.x > m_xcliphi )
+ {
+ temp = USCALE( (aSegEnd.y - aSegStart.y), (aSegEnd.x - m_xcliphi),
+ (aSegEnd.x - aSegStart.x) );
+ aSegEnd.y -= temp;
+ aSegEnd.x = m_xcliphi;
+ WHEN_INSIDE;
+ }
+ }
+ else
+ {
+ if( (aSegStart.y < m_ycliplo) || (aSegEnd.y > m_ycliphi) )
+ {
+ WHEN_OUTSIDE;
+ }
+
+ if( aSegStart.y > m_ycliphi )
+ {
+ temp = USCALE( (aSegEnd.x - aSegStart.x), (aSegStart.y - m_ycliphi),
+ (aSegStart.y - aSegEnd.y) );
+
+ if( (aSegStart.x += temp) > m_xcliphi )
+ {
+ WHEN_OUTSIDE;
+ }
+
+ aSegStart.y = m_ycliphi;
+ WHEN_INSIDE;
+ }
+
+ if( aSegEnd.y < m_ycliplo )
+ {
+ temp = USCALE( (aSegEnd.x - aSegStart.x), (m_ycliplo - aSegEnd.y),
+ (aSegStart.y - aSegEnd.y) );
+
+ if( (aSegEnd.x -= temp) < m_xcliplo )
+ {
+ WHEN_OUTSIDE;
+ }
+
+ aSegEnd.y = m_ycliplo;
+ WHEN_INSIDE;
+ }
+
+ if( aSegStart.x < m_xcliplo )
+ {
+ temp = USCALE( (aSegStart.y - aSegEnd.y), (m_xcliplo - aSegStart.x),
+ (aSegEnd.x - aSegStart.x) );
+ aSegStart.y -= temp;
+ aSegStart.x = m_xcliplo;
+ WHEN_INSIDE;
+ }
+
+ if( aSegEnd.x > m_xcliphi )
+ {
+ temp = USCALE( (aSegStart.y - aSegEnd.y), (aSegEnd.x - m_xcliphi),
+ (aSegEnd.x - aSegStart.x) );
+ aSegEnd.y += temp;
+ aSegEnd.x = m_xcliphi;
+ WHEN_INSIDE;
+ }
+ }
+
+ if( ( (aSegEnd.x + aSegStart.x) / 2 <= m_xcliphi )
+ && ( (aSegEnd.x + aSegStart.x) / 2 >= m_xcliplo ) \
+ && ( (aSegEnd.y + aSegStart.y) / 2 <= m_ycliphi )
+ && ( (aSegEnd.y + aSegStart.y) / 2 >= m_ycliplo ) )
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
diff --git a/pcbnew/drc_marker_functions.cpp b/pcbnew/drc_marker_functions.cpp
new file mode 100644
index 0000000..5642361
--- /dev/null
+++ b/pcbnew/drc_marker_functions.cpp
@@ -0,0 +1,226 @@
+/**
+ * @file drc_marker_functions.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* Methods of class DRC to initialize drc markers with messages
+ * according to items and error code
+*/
+
+#include <fctsys.h>
+#include <common.h>
+#include <pcbnew.h>
+#include <class_board_design_settings.h>
+
+#include <drc_stuff.h>
+#include <class_pad.h>
+#include <class_track.h>
+#include <class_zone.h>
+#include <class_zone.h>
+#include <class_marker_pcb.h>
+#include <class_pcb_text.h>
+
+
+MARKER_PCB* DRC::fillMarker( const TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode,
+ MARKER_PCB* fillMe )
+{
+ wxString textA = aTrack->GetSelectMenuText();
+ wxString textB;
+
+ wxPoint position;
+ wxPoint posB;
+
+ if( aItem ) // aItem might be NULL
+ {
+ textB = aItem->GetSelectMenuText();
+
+ if( aItem->Type() == PCB_PAD_T )
+ {
+ posB = position = ((D_PAD*)aItem)->GetPosition();
+ }
+ else if( aItem->Type() == PCB_VIA_T )
+ {
+ posB = position = ((VIA*)aItem)->GetPosition();
+ }
+ else if( aItem->Type() == PCB_TRACE_T )
+ {
+ TRACK* track = (TRACK*) aItem;
+
+ posB = track->GetPosition();
+
+ wxPoint endPos = track->GetEnd();
+
+ // either of aItem's start or end will be used for the marker position
+ // first assume start, then switch at end if needed. decision made on
+ // distance from end of aTrack.
+ position = track->GetStart();
+
+ double dToEnd = GetLineLength( endPos, aTrack->GetEnd() );
+ double dToStart = GetLineLength( position, aTrack->GetEnd() );
+
+ if( dToEnd < dToStart )
+ position = endPos;
+ }
+ else if( aItem->Type() == PCB_TEXT_T )
+ {
+ position = aTrack->GetPosition();
+ posB = ((TEXTE_PCB*) aItem)->GetPosition();
+ }
+ }
+ else
+ position = aTrack->GetPosition();
+
+ if( fillMe )
+ {
+ if( aItem )
+ fillMe->SetData( aErrorCode, position,
+ textA, aTrack->GetPosition(),
+ textB, posB );
+ else
+ fillMe->SetData( aErrorCode, position,
+ textA, aTrack->GetPosition() );
+ }
+ else
+ {
+ if( aItem )
+ {
+ fillMe = new MARKER_PCB( aErrorCode, position,
+ textA, aTrack->GetPosition(),
+ textB, posB );
+ fillMe->SetItem( aItem );
+ }
+ else
+ {
+ fillMe = new MARKER_PCB( aErrorCode, position,
+ textA, aTrack->GetPosition() );
+ }
+ }
+
+ return fillMe;
+}
+
+
+MARKER_PCB* DRC::fillMarker( D_PAD* aPad, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe )
+{
+ wxString textA = aPad->GetSelectMenuText();
+ wxString textB;
+
+ wxPoint posA = aPad->GetPosition();
+ wxPoint posB;
+
+ if( aItem )
+ {
+ textB = aItem->GetSelectMenuText();
+
+ switch( aItem->Type() )
+ {
+ case PCB_PAD_T:
+ posB = ((D_PAD*)aItem)->GetPosition();
+ break;
+
+ case PCB_TEXT_T:
+ posB = ((TEXTE_PCB*)aItem)->GetPosition();
+ break;
+
+ default:
+ wxLogDebug( wxT("fillMarker: unsupported item") );
+ break;
+ }
+ }
+
+ if( fillMe )
+ {
+ fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB );
+ }
+ else
+ {
+ fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA, textB, posB );
+ fillMe->SetItem( aPad ); // TODO it has to be checked
+ }
+
+ return fillMe;
+}
+
+
+MARKER_PCB* DRC::fillMarker( ZONE_CONTAINER* aArea, int aErrorCode, MARKER_PCB* fillMe )
+{
+ wxString textA = aArea->GetSelectMenuText();
+
+ wxPoint posA = aArea->GetPosition();
+
+ if( fillMe )
+ {
+ fillMe->SetData( aErrorCode, posA, textA, posA );
+ }
+ else
+ {
+ fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA );
+ fillMe->SetItem( aArea );
+ }
+
+ return fillMe;
+}
+
+
+MARKER_PCB* DRC::fillMarker( const ZONE_CONTAINER* aArea,
+ const wxPoint& aPos,
+ int aErrorCode,
+ MARKER_PCB* fillMe )
+{
+ wxString textA = aArea->GetSelectMenuText();
+
+ wxPoint posA = aPos;
+
+ if( fillMe )
+ {
+ fillMe->SetData( aErrorCode, posA, textA, posA );
+ }
+ else
+ {
+ fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA );
+ fillMe->SetItem( aArea );
+ }
+
+ return fillMe;
+}
+
+
+MARKER_PCB* DRC::fillMarker( int aErrorCode, const wxString& aMessage, MARKER_PCB* fillMe )
+{
+ wxPoint posA; // not displayed
+
+ if( fillMe )
+ fillMe->SetData( aErrorCode, posA, aMessage, posA );
+ else
+ fillMe = new MARKER_PCB( aErrorCode, posA, aMessage, posA );
+
+ fillMe->SetShowNoCoordinate();
+
+ return fillMe;
+}
+
diff --git a/pcbnew/drc_stuff.h b/pcbnew/drc_stuff.h
new file mode 100644
index 0000000..7441c96
--- /dev/null
+++ b/pcbnew/drc_stuff.h
@@ -0,0 +1,507 @@
+/**
+ * @file drc_stuff.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
+ * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _DRC_STUFF_H
+#define _DRC_STUFF_H
+
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+#define OK_DRC 0
+#define BAD_DRC 1
+
+
+/// DRC error codes:
+#define DRCE_ 1 // not used yet
+#define DRCE_UNCONNECTED_PADS 2 ///< pads are unconnected
+#define DRCE_TRACK_NEAR_THROUGH_HOLE 3 ///< thru hole is too close to track
+#define DRCE_TRACK_NEAR_PAD 4 ///< pad too close to track
+#define DRCE_TRACK_NEAR_VIA 5 ///< track too close to via
+#define DRCE_VIA_NEAR_VIA 6 ///< via too close to via
+#define DRCE_VIA_NEAR_TRACK 7 ///< via too close to track
+#define DRCE_TRACK_ENDS1 8 ///< 2 parallel track segments too close: fine start point test
+#define DRCE_TRACK_ENDS2 9 ///< 2 parallel track segments too close: fine start point test
+#define DRCE_TRACK_ENDS3 10 ///< 2 parallel track segments too close: fine end point test
+#define DRCE_TRACK_ENDS4 11 ///< 2 parallel track segments too close: fine end point test
+#define DRCE_TRACK_SEGMENTS_TOO_CLOSE 12 ///< 2 parallel track segments too close: segm ends between segref ends
+#define DRCE_TRACKS_CROSSING 13 ///< tracks are crossing
+#define DRCE_ENDS_PROBLEM1 14 ///< track ends are too close
+#define DRCE_ENDS_PROBLEM2 15 ///< track ends are too close
+#define DRCE_ENDS_PROBLEM3 16 ///< track ends are too close
+#define DRCE_ENDS_PROBLEM4 17 ///< track ends are too close
+#define DRCE_ENDS_PROBLEM5 18 ///< track ends are too close
+#define DRCE_PAD_NEAR_PAD1 19 ///< pad too close to pad
+#define DRCE_VIA_HOLE_BIGGER 20 ///< via's hole is bigger than its diameter
+#define DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR 21 ///< micro via's layer pair incorrect (layers must be adjacent)
+#define COPPERAREA_INSIDE_COPPERAREA 22 ///< copper area outlines intersect
+#define COPPERAREA_CLOSE_TO_COPPERAREA 23 ///< copper area outlines are too close
+#define DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE 24 ///< copper area has a net but no pads in nets, which is suspicious
+#define DRCE_HOLE_NEAR_PAD 25 ///< hole too close to pad
+#define DRCE_HOLE_NEAR_TRACK 26 ///< hole too close to track
+#define DRCE_TOO_SMALL_TRACK_WIDTH 27 ///< Too small track width
+#define DRCE_TOO_SMALL_VIA 28 ///< Too small via size
+#define DRCE_TOO_SMALL_MICROVIA 29 ///< Too small micro via size
+#define DRCE_NETCLASS_TRACKWIDTH 30 ///< netclass has TrackWidth < board.m_designSettings->m_TrackMinWidth
+#define DRCE_NETCLASS_CLEARANCE 31 ///< netclass has Clearance < board.m_designSettings->m_TrackClearance
+#define DRCE_NETCLASS_VIASIZE 32 ///< netclass has ViaSize < board.m_designSettings->m_ViasMinSize
+#define DRCE_NETCLASS_VIADRILLSIZE 33 ///< netclass has ViaDrillSize < board.m_designSettings->m_ViasMinDrill
+#define DRCE_NETCLASS_uVIASIZE 34 ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinSize
+#define DRCE_NETCLASS_uVIADRILLSIZE 35 ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinDrill
+#define DRCE_VIA_INSIDE_KEEPOUT 36 ///< Via in inside a keepout area
+#define DRCE_TRACK_INSIDE_KEEPOUT 37 ///< Track in inside a keepout area
+#define DRCE_PAD_INSIDE_KEEPOUT 38 ///< Pad in inside a keepout area
+#define DRCE_VIA_INSIDE_TEXT 39 ///< Via in inside a text area
+#define DRCE_TRACK_INSIDE_TEXT 40 ///< Track in inside a text area
+#define DRCE_PAD_INSIDE_TEXT 41 ///< Pad in inside a text area
+
+
+class EDA_DRAW_PANEL;
+class PCB_EDIT_FRAME;
+class DIALOG_DRC_CONTROL;
+class BOARD_ITEM;
+class BOARD;
+class D_PAD;
+class ZONE_CONTAINER;
+class TRACK;
+class MARKER_PCB;
+class DRC_ITEM;
+class NETCLASS;
+
+
+/**
+ * Class DRC_ITEM_LIST
+ * provides an abstract interface of a DRC_ITEM* list manager. The details
+ * of the actual list architecture are hidden from the caller. Any class
+ * that implements this interface can then be used by a DRCLISTBOX class without
+ * it knowing the actual architecture of the list.
+ */
+class DRC_ITEM_LIST
+{
+public:
+
+ /**
+ * Function DeleteAllItems
+ * removes and deletes all the items in the list.
+ */
+ virtual void DeleteAllItems() = 0;
+
+ /**
+ * Function GetItem
+ * retrieves a DRC_ITEM by pointer. The actual item remains owned by the
+ * list container.
+ * @param aIndex The 0 based index into the list of the desired item.
+ * @return const DRC_ITEM* - the desired item or NULL if aIndex is out of range.
+ */
+ virtual const DRC_ITEM* GetItem( int aIndex ) = 0;
+
+ /**
+ * Function DeleteAllItems
+ * removes and deletes desired item from the list.
+ * @param aIndex The 0 based index into the list of the desired item which
+ * is to be deleted.
+ */
+ virtual void DeleteItem( int aIndex ) = 0;
+
+ /**
+ * Function GetCount
+ * returns the number of items in the list.
+ */
+ virtual int GetCount() = 0;
+
+ virtual ~DRC_ITEM_LIST() { }
+};
+
+
+typedef std::vector<DRC_ITEM*> DRC_LIST;
+
+
+/**
+ * Class DRC
+ * is the Design Rule Checker, and performs all the DRC tests. The output of
+ * the checking goes to the BOARD file in the form of two MARKER lists. Those
+ * two lists are displayable in the drc dialog box. And they can optionally
+ * be sent to a text file on disk.
+ * This class is given access to the windows and the BOARD
+ * that it needs via its constructor or public access functions.
+ */
+class DRC
+{
+ friend class DIALOG_DRC_CONTROL;
+
+private:
+
+ // protected or private functions() are lowercase first character.
+
+ bool m_doPad2PadTest;
+ bool m_doUnconnectedTest;
+ bool m_doZonesTest;
+ bool m_doKeepoutTest;
+ bool m_doCreateRptFile;
+
+ wxString m_rptFilename;
+
+ MARKER_PCB* m_currentMarker;
+
+ bool m_abortDRC;
+ bool m_drcInProgress;
+
+ /* In DRC functions, many calculations are using coordinates relative
+ * to the position of the segment under test (segm to segm DRC, segm to pad DRC
+ * Next variables store coordinates relative to the start point of this segment
+ */
+ wxPoint m_padToTestPos; // Position of the pad to compare in drc test segm to pad or pad to pad
+ wxPoint m_segmEnd; // End point of the reference segment (start point = (0,0) )
+
+ /* Some functions are comparing the ref segm to pads or others segments using
+ * coordinates relative to the ref segment considered as the X axis
+ * so we store the ref segment length (the end point relative to these axis)
+ * and the segment orientation (used to rotate other coordinates)
+ */
+ double m_segmAngle; // Ref segm orientation in 0,1 degre
+ int m_segmLength; // length of the reference segment
+
+ /* variables used in checkLine to test DRC segm to segm:
+ * define the area relative to the ref segment that does not contains any other segment
+ */
+ int m_xcliplo;
+ int m_ycliplo;
+ int m_xcliphi;
+ int m_ycliphi;
+
+ PCB_EDIT_FRAME* m_mainWindow;
+ BOARD* m_pcb;
+ DIALOG_DRC_CONTROL* m_drcDialog;
+
+ DRC_LIST m_unconnected; ///< list of unconnected pads, as DRC_ITEMs
+
+
+ /**
+ * Function updatePointers
+ * is a private helper function used to update needed pointers from the
+ * one pointer which is known not to change, m_mainWindow.
+ */
+ void updatePointers();
+
+
+ /**
+ * Function fillMarker
+ * optionally creates a marker and fills it in with information,
+ * but does not add it to the BOARD. Use this to report any kind of
+ * DRC problem, or unconnected pad problem.
+ *
+ * @param aTrack The reference track.
+ * @param aItem Another item on the BOARD, such as a VIA, SEGZONE,
+ * or TRACK.
+ * @param aErrorCode A categorizing identifier for the particular type
+ * of error that is being reported.
+ * @param fillMe A MARKER_PCB* which is to be filled in, or NULL if one is to
+ * first be allocated, then filled.
+ */
+ MARKER_PCB* fillMarker( const TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe );
+
+ MARKER_PCB* fillMarker( D_PAD* aPad, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe );
+
+ MARKER_PCB* fillMarker( ZONE_CONTAINER* aArea, int aErrorCode, MARKER_PCB* fillMe );
+
+ /**
+ * Function fillMarker
+ * optionally creates a marker and fills it in with information,
+ * but does not add it to the BOARD. Use this to report any kind of
+ * DRC problem, or unconnected pad problem.
+ *
+ * @param aArea The zone to test
+ * @param aPos position of error
+ * @param aErrorCode Type of error
+ * @param fillMe A MARKER_PCB* which is to be filled in, or NULL if one is to
+ * first be allocated, then filled.
+ */
+ MARKER_PCB* fillMarker( const ZONE_CONTAINER* aArea,
+ const wxPoint& aPos,
+ int aErrorCode,
+ MARKER_PCB* fillMe );
+
+ /**
+ * Function fillMarker
+ * fills a MARKER which will report on a generic problem with the board which is
+ * not geographically locatable.
+ */
+ MARKER_PCB* fillMarker( int aErrorCode, const wxString& aMessage, MARKER_PCB* fillMe );
+
+
+ //-----<categorical group tests>-----------------------------------------
+
+ /**
+ * Function testNetClasses
+ * goes through each NETCLASS and verifies that its clearance, via size,
+ * track width, and track clearance are larger than those in board.m_designSettings.
+ * This is necessary because the actual DRC checks are run against the NETCLASS
+ * limits, so in order enforce global limits, we first check the NETCLASSes against
+ * the global limits.
+ * @return bool - true if succes, else false but only after
+ * reporting _all_ NETCLASS violations.
+ */
+ bool testNetClasses();
+
+ /**
+ * Function testTracks
+ * performs the DRC on all tracks.
+ * because this test can take a while, a progress bar can be displayed
+ * @param aActiveWindow = the active window ued as parent for the progress bar
+ * @param aShowProgressBar = true to show a progress bar
+ * (Note: it is shown only if there are many tracks)
+ */
+ void testTracks( wxWindow * aActiveWindow, bool aShowProgressBar );
+
+ void testPad2Pad();
+
+ void testUnconnected();
+
+ void testZones();
+
+ void testKeepoutAreas();
+
+ void testTexts();
+
+ //-----<single "item" tests>-----------------------------------------
+
+ bool doNetClass( boost::shared_ptr<NETCLASS> aNetClass, wxString& msg );
+
+ /**
+ * Function doPadToPadsDrc
+ * tests the clearance between aRefPad and other pads.
+ * The pad list must be sorted by x coordinate.
+ * @param aRefPad The pad to test
+ * @param aStart The start of the pad list to test against
+ * @param aEnd Marks the end of the list and is not included
+ * @param x_limit is used to stop the test (when the any pad's X coord exceeds this)
+ */
+ bool doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_limit );
+
+ /**
+ * Function DoTrackDrc
+ * tests the current segment.
+ * @param aRefSeg The segment to test
+ * @param aStart The head of a list of tracks to test against (usually BOARD::m_Track)
+ * @param doPads true if should do pads test
+ * @return bool - true if no poblems, else false and m_currentMarker is
+ * filled in with the problem information.
+ */
+ bool doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool doPads = true );
+
+ /**
+ * Function doTrackKeepoutDrc
+ * tests the current segment or via.
+ * @param aRefSeg The segment to test
+ * @return bool - true if no poblems, else false and m_currentMarker is
+ * filled in with the problem information.
+ */
+ bool doTrackKeepoutDrc( TRACK* aRefSeg );
+
+
+ /**
+ * Function doEdgeZoneDrc
+ * tests a segment in ZONE_CONTAINER * aArea:
+ * Test Edge inside other areas
+ * Test Edge too close other areas
+ * @param aArea The current area.
+ * @param aCornerIndex The first corner of the segment to test.
+ * @return bool - false if DRC error or true if OK
+ */
+ bool doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex );
+
+ //-----<single tests>----------------------------------------------
+
+ /**
+ * Function checkClearancePadToPad
+ * @param aRefPad The reference pad to check
+ * @param aPad Another pad to check against
+ * @return bool - true if clearance between aRefPad and aPad is >= dist_min, else false
+ */
+ bool checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad );
+
+
+ /**
+ * Function checkClearanceSegmToPad
+ * check the distance from a pad to segment. This function uses several
+ * instance variable not passed in:
+ * m_segmLength = length of the segment being tested
+ * m_segmAngle = angle of the segment with the X axis;
+ * m_segmEnd = end coordinate of the segment
+ * m_padToTestPos = position of pad relative to the origin of segment
+ * @param aPad Is the pad involved in the check
+ * @param aSegmentWidth width of the segment to test
+ * @param aMinDist Is the minimum clearance needed
+ *
+ * @return true distance >= dist_min,
+ * false if distance < dist_min
+ */
+ bool checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMinDist );
+
+
+ /**
+ * Helper function checkMarginToCircle
+ * Check the distance from a point to
+ * a segment. the segment is expected starting at 0,0, and on the X axis
+ * (used to test DRC between a segment and a round pad, via or round end of a track
+ * @param aCentre The coordinate of the circle's center
+ * @param aRadius A "keep out" radius centered over the circle
+ * @param aLength The length of the segment (i.e. coordinate of end, becuase it is on
+ * the X axis)
+ * @return bool - true if distance >= radius, else
+ * false when distance < aRadius
+ */
+ static bool checkMarginToCircle( wxPoint aCentre, int aRadius, int aLength );
+
+
+ /**
+ * Function checkLine
+ * (helper function used in drc calculations to see if one track is in contact with
+ * another track).
+ * Test if a line intersects a bounding box (a rectangle)
+ * The rectangle is defined by m_xcliplo, m_ycliplo and m_xcliphi, m_ycliphi
+ * return true if the line from aSegStart to aSegEnd is outside the bounding box
+ */
+ bool checkLine( wxPoint aSegStart, wxPoint aSegEnd );
+
+ //-----</single tests>---------------------------------------------
+
+public:
+ DRC( PCB_EDIT_FRAME* aPcbWindow );
+
+ ~DRC();
+
+ /**
+ * Function Drc
+ * tests the current segment and returns the result and displays the error
+ * in the status panel only if one exists.
+ * @param aRefSeg The current segment to test.
+ * @param aList The track list to test (usually m_Pcb->m_Track)
+ * @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
+ */
+ int Drc( TRACK* aRefSeg, TRACK* aList );
+
+ /**
+ * Function Drc
+ * tests the outline segment starting at CornerIndex and returns the result and displays
+ * the error in the status panel only if one exists.
+ * Test Edge inside other areas
+ * Test Edge too close other areas
+ * @param aArea The areaparent which contains the corner.
+ * @param aCornerIndex The starting point of the segment to test.
+ * @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
+ */
+ int Drc( ZONE_CONTAINER* aArea, int aCornerIndex );
+
+ /**
+ * Function DrcBlind
+ * tests the current segment and returns the result. Any error is not
+ * displayed in the status panel.
+ * @param aRefSeg The current segment to test.
+ * @param aList The track list to test (usually m_Pcb->m_Track)
+ * @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
+ */
+ int DrcBlind( TRACK* aRefSeg, TRACK* aList )
+ {
+ updatePointers();
+
+ if( ! doTrackDrc( aRefSeg, aList ) )
+ return BAD_DRC;
+
+ return doTrackKeepoutDrc( aRefSeg ) ? OK_DRC : BAD_DRC;
+ }
+
+
+ /**
+ * Function ShowDialog
+ * opens a dialog and prompts the user, then if a test run button is
+ * clicked, runs the test(s) and creates the MARKERS. The dialog is only
+ * created if it is not already in existence.
+ */
+ void ShowDialog();
+
+ /**
+ * Function DestroyDialog
+ * deletes this ui dialog box and zeros out its pointer to remember
+ * the state of the dialog's existence.
+ * @param aReason Indication of which button was clicked to cause the destruction.
+ */
+ void DestroyDialog( int aReason );
+
+
+ /**
+ * Function SetSettings
+ * saves all the UI or test settings and may be called before running the tests.
+ * @param aPad2PadTest Tells whether to test pad to pad distances.
+ * @param aUnconnectedTest Tells whether to list unconnected pads.
+ * @param aZonesTest Tells whether to test zones.
+ * @param aKeepoutTest Tells whether to test keepout areas.
+ * @param aReportName A string telling the disk file report name entered.
+ * @param aSaveReport A boolean telling whether to generate disk file report.
+ */
+ void SetSettings( bool aPad2PadTest, bool aUnconnectedTest,
+ bool aZonesTest, bool aKeepoutTest,
+ const wxString& aReportName, bool aSaveReport )
+ {
+ m_doPad2PadTest = aPad2PadTest;
+ m_doUnconnectedTest = aUnconnectedTest;
+ m_doZonesTest = aZonesTest;
+ m_doKeepoutTest = aKeepoutTest;
+ m_rptFilename = aReportName;
+ m_doCreateRptFile = aSaveReport;
+ }
+
+
+ /**
+ * Function RunTests
+ * will actually run all the tests specified with a previous call to
+ * SetSettings()
+ * @param aMessages = a wxTextControl where to display some activity messages. Can be NULL
+ */
+ void RunTests( wxTextCtrl* aMessages = NULL );
+
+ /**
+ * Function ListUnconnectedPad
+ * gathers a list of all the unconnected pads and shows them in the
+ * dialog, and optionally prints a report of such.
+ */
+ void ListUnconnectedPads();
+
+ /**
+ * @return a pointer to the current marker (last created marker
+ */
+ MARKER_PCB* GetCurrentMarker( )
+ {
+ return m_currentMarker;
+ }
+
+};
+
+
+#endif // _DRC_STUFF_H
+
+//EOF
diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp
new file mode 100644
index 0000000..cc3f198
--- /dev/null
+++ b/pcbnew/eagle_plugin.cpp
@@ -0,0 +1,2989 @@
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/*
+
+Pcbnew PLUGIN for Eagle 6.x XML *.brd and footprint format.
+
+XML parsing and converting:
+Getting line numbers and byte offsets from the source XML file is not
+possible using currently available XML libraries within KiCad project:
+wxXmlDocument and boost::property_tree.
+
+property_tree will give line numbers but no byte offsets, and only during
+document loading. This means that if we have a problem after the document is
+successfully loaded, there is no way to correlate back to line number and byte
+offset of the problem. So a different approach is taken, one which relies on the
+XML elements themselves using an XPATH type of reporting mechanism. The path to
+the problem is reported in the error messages. This means keeping track of that
+path as we traverse the XML document for the sole purpose of accurate error
+reporting.
+
+User can load the source XML file into firefox or other xml browser and follow
+our error message.
+
+Load() TODO's
+
+*) verify zone fill clearances are correct
+
+*/
+
+#include <errno.h>
+
+#include <wx/string.h>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/xml_parser.hpp>
+
+#include <eagle_plugin.h>
+
+#include <common.h>
+#include <macros.h>
+#include <fctsys.h>
+#include <trigo.h>
+#include <macros.h>
+#include <kicad_string.h>
+#include <wx/filename.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_edge_mod.h>
+#include <class_zone.h>
+#include <class_pcb_text.h>
+
+using namespace boost::property_tree;
+using namespace std;
+
+typedef EAGLE_PLUGIN::BIU BIU;
+typedef PTREE::const_assoc_iterator CA_ITER;
+typedef PTREE::const_iterator CITER;
+typedef std::pair<CA_ITER, CA_ITER> CA_ITER_RANGE;
+
+typedef MODULE_MAP::iterator MODULE_ITER;
+typedef MODULE_MAP::const_iterator MODULE_CITER;
+
+typedef boost::optional<string> opt_string;
+typedef boost::optional<int> opt_int;
+typedef boost::optional<double> opt_double;
+typedef boost::optional<bool> opt_bool;
+
+
+/// segment (element) of our XPATH into the Eagle XML document tree in PTREE form.
+struct TRIPLET
+{
+ const char* element;
+ const char* attribute;
+ const char* value;
+
+ TRIPLET( const char* aElement, const char* aAttribute = "", const char* aValue = "" ) :
+ element( aElement ),
+ attribute( aAttribute ),
+ value( aValue )
+ {}
+};
+
+
+/**
+ * Class XPATH
+ * keeps track of what we are working on within a PTREE.
+ * Then if an exception is thrown, the place within the tree that gave us
+ * grief can be reported almost accurately. To minimally impact
+ * speed, merely assign const char* pointers during the tree walking
+ * expedition. The const char* pointers must be to C strings residing either in
+ * the data or code segment (i.e. "compiled in") or within the XML document, but
+ * not on the stack, since the stack is unwound during the throwing of the
+ * exception. The XML document will not immediately vanish since we capture
+ * the xpath (using function Contents()) before the XML document tree (PTREE)
+ * is destroyed.
+ */
+class XPATH
+{
+ std::vector<TRIPLET> p;
+
+public:
+ void push( const char* aPathSegment, const char* aAttribute="" )
+ {
+ p.push_back( TRIPLET( aPathSegment, aAttribute ) );
+ }
+
+ void clear() { p.clear(); }
+
+ void pop() { p.pop_back(); }
+
+ /// modify the last path node's value
+ void Value( const char* aValue )
+ {
+ p.back().value = aValue;
+ }
+
+ /// modify the last path node's attribute
+ void Attribute( const char* aAttribute )
+ {
+ p.back().attribute = aAttribute;
+ }
+
+ /// return the contents of the XPATH as a single string
+ string Contents()
+ {
+ typedef std::vector<TRIPLET>::const_iterator CITER;
+
+ string ret;
+
+ for( CITER it = p.begin(); it != p.end(); ++it )
+ {
+ if( it != p.begin() )
+ ret += '.';
+
+ ret += it->element;
+
+ if( it->attribute[0] && it->value[0] )
+ {
+ ret += '[';
+ ret += it->attribute;
+ ret += '=';
+ ret += it->value;
+ ret += ']';
+ }
+ }
+
+ return ret;
+ }
+};
+
+
+/**
+ * Function parseOptionalBool
+ * returns an opt_bool and sets it true or false according to the presence
+ * and value of an attribute within the CPTREE element.
+ */
+static opt_bool parseOptionalBool( CPTREE& attribs, const char* aName )
+{
+ opt_bool ret;
+ opt_string stemp = attribs.get_optional<string>( aName );
+
+ if( stemp )
+ ret = !stemp->compare( "yes" );
+
+ return ret;
+}
+
+
+// All of the 'E'STRUCTS below merely hold Eagle XML information verbatim, in binary.
+// For maintenance and troubleshooting purposes, it was thought that we'd need to
+// separate the conversion process into distinct steps. There is no intent to have KiCad
+// forms of information in these 'E'STRUCTS. They are only binary forms
+// of the Eagle information in the corresponding Eagle XML nodes.
+
+
+/// Eagle rotation
+struct EROT
+{
+ bool mirror;
+ bool spin;
+ double degrees;
+
+ EROT() :
+ mirror( false ),
+ spin( false ),
+ degrees( 0 )
+ {}
+
+ EROT( double aDegrees ) :
+ mirror( false ),
+ spin( false ),
+ degrees( aDegrees )
+ {}
+};
+
+typedef boost::optional<EROT> opt_erot;
+
+/// parse an Eagle XML "rot" field. Unfortunately the DTD seems not to explain
+/// this format very well. [S][M]R<degrees>. Examples: "R90", "MR180", "SR180"
+static EROT erot( const string& aRot )
+{
+ EROT rot;
+
+ rot.spin = aRot.find( 'S' ) != aRot.npos;
+ rot.mirror = aRot.find( 'M' ) != aRot.npos;
+ rot.degrees = strtod( aRot.c_str()
+ + 1 // skip leading 'R'
+ + int( rot.spin ) // skip optional leading 'S'
+ + int( rot.mirror ), // skip optional leading 'M'
+ NULL );
+ return rot;
+}
+
+/// Eagle "rot" fields are optional, handle that by returning opt_erot.
+static opt_erot parseOptionalEROT( CPTREE& attribs )
+{
+ opt_erot ret;
+ opt_string stemp = attribs.get_optional<string>( "rot" );
+ if( stemp )
+ ret = erot( *stemp );
+ return ret;
+}
+
+/// Eagle wire
+struct EWIRE
+{
+ double x1;
+ double y1;
+ double x2;
+ double y2;
+ double width;
+ LAYER_NUM layer;
+
+ // for style: (continuous | longdash | shortdash | dashdot)
+ enum {
+ CONTINUOUS,
+ LONGDASH,
+ SHORTDASH,
+ DASHDOT,
+ };
+ opt_int style;
+ opt_double curve; ///< range is -359.9..359.9
+
+ // for cap: (flat | round)
+ enum {
+ FLAT,
+ ROUND,
+ };
+ opt_int cap;
+
+ EWIRE( CPTREE& aWire );
+};
+
+/**
+ * Constructor EWIRE
+ * converts a "wire"'s xml attributes ( &ltwire&gt )
+ * to binary without additional conversion.
+ * This result is an EWIRE with the &ltwire&gt textual data merely converted to binary.
+ */
+EWIRE::EWIRE( CPTREE& aWire )
+{
+ CPTREE& attribs = aWire.get_child( "<xmlattr>" );
+
+ /*
+ <!ELEMENT wire EMPTY>
+ <!ATTLIST wire
+ x1 %Coord; #REQUIRED
+ y1 %Coord; #REQUIRED
+ x2 %Coord; #REQUIRED
+ y2 %Coord; #REQUIRED
+ width %Dimension; #REQUIRED
+ layer %Layer; #REQUIRED
+ extent %Extent; #IMPLIED -- only applicable for airwires --
+ style %WireStyle; "continuous"
+ curve %WireCurve; "0"
+ cap %WireCap; "round" -- only applicable if 'curve' is not zero --
+ >
+ */
+
+ x1 = attribs.get<double>( "x1" );
+ y1 = attribs.get<double>( "y1" );
+ x2 = attribs.get<double>( "x2" );
+ y2 = attribs.get<double>( "y2" );
+ width = attribs.get<double>( "width" );
+ layer = attribs.get<int>( "layer" );
+
+ curve = attribs.get_optional<double>( "curve" );
+
+ opt_string s = attribs.get_optional<string>( "style" );
+ if( s )
+ {
+ if( !s->compare( "continuous" ) )
+ style = EWIRE::CONTINUOUS;
+ else if( !s->compare( "longdash" ) )
+ style = EWIRE::LONGDASH;
+ else if( !s->compare( "shortdash" ) )
+ style = EWIRE::SHORTDASH;
+ else if( !s->compare( "dashdot" ) )
+ style = EWIRE::DASHDOT;
+ }
+
+ s = attribs.get_optional<string>( "cap" );
+ if( s )
+ {
+ if( !s->compare( "round" ) )
+ cap = EWIRE::ROUND;
+ else if( !s->compare( "flat" ) )
+ cap = EWIRE::FLAT;
+ }
+ // ignoring extent
+}
+
+
+/// Eagle via
+struct EVIA
+{
+ double x;
+ double y;
+ int layer_front_most; /// < extent
+ int layer_back_most; /// < inclusive
+ double drill;
+ opt_double diam;
+ opt_string shape;
+ EVIA( CPTREE& aVia );
+};
+
+EVIA::EVIA( CPTREE& aVia )
+{
+ CPTREE& attribs = aVia.get_child( "<xmlattr>" );
+
+ /*
+ <!ELEMENT via EMPTY>
+ <!ATTLIST via
+ x %Coord; #REQUIRED
+ y %Coord; #REQUIRED
+ extent %Extent; #REQUIRED
+ drill %Dimension; #REQUIRED
+ diameter %Dimension; "0"
+ shape %ViaShape; "round"
+ alwaysstop %Bool; "no"
+ >
+ */
+
+ x = attribs.get<double>( "x" );
+ y = attribs.get<double>( "y" );
+
+ string ext = attribs.get<string>( "extent" );
+
+ sscanf( ext.c_str(), "%d-%d", &layer_front_most, &layer_back_most );
+
+ drill = attribs.get<double>( "drill" );
+ diam = attribs.get_optional<double>( "diameter" );
+ shape = attribs.get_optional<string>( "shape" );
+}
+
+
+/// Eagle circle
+struct ECIRCLE
+{
+ double x;
+ double y;
+ double radius;
+ double width;
+ LAYER_NUM layer;
+
+ ECIRCLE( CPTREE& aCircle );
+};
+
+ECIRCLE::ECIRCLE( CPTREE& aCircle )
+{
+ CPTREE& attribs = aCircle.get_child( "<xmlattr>" );
+
+ /*
+ <!ELEMENT circle EMPTY>
+ <!ATTLIST circle
+ x %Coord; #REQUIRED
+ y %Coord; #REQUIRED
+ radius %Coord; #REQUIRED
+ width %Dimension; #REQUIRED
+ layer %Layer; #REQUIRED
+ >
+ */
+
+ x = attribs.get<double>( "x" );
+ y = attribs.get<double>( "y" );
+ radius = attribs.get<double>( "radius" );
+ width = attribs.get<double>( "width" );
+ layer = attribs.get<int>( "layer" );
+}
+
+
+/// Eagle XML rectangle in binary
+struct ERECT
+{
+ double x1;
+ double y1;
+ double x2;
+ double y2;
+ int layer;
+ opt_erot rot;
+
+ ERECT( CPTREE& aRect );
+};
+
+ERECT::ERECT( CPTREE& aRect )
+{
+ CPTREE& attribs = aRect.get_child( "<xmlattr>" );
+
+ /*
+ <!ELEMENT rectangle EMPTY>
+ <!ATTLIST rectangle
+ x1 %Coord; #REQUIRED
+ y1 %Coord; #REQUIRED
+ x2 %Coord; #REQUIRED
+ y2 %Coord; #REQUIRED
+ layer %Layer; #REQUIRED
+ rot %Rotation; "R0"
+ >
+ */
+
+ x1 = attribs.get<double>( "x1" );
+ y1 = attribs.get<double>( "y1" );
+ x2 = attribs.get<double>( "x2" );
+ y2 = attribs.get<double>( "y2" );
+ layer = attribs.get<int>( "layer" );
+ rot = parseOptionalEROT( attribs );
+}
+
+
+/// Eagle "attribute" XML element, no foolin'.
+struct EATTR
+{
+ string name;
+ opt_string value;
+ opt_double x;
+ opt_double y;
+ opt_double size;
+ opt_int layer;
+ opt_double ratio;
+ opt_erot rot;
+
+ enum { // for 'display'
+ Off,
+ VALUE,
+ NAME,
+ BOTH,
+ };
+ opt_int display;
+
+ EATTR( CPTREE& aTree );
+ EATTR() {}
+};
+
+/**
+ * Constructor EATTR
+ * parses an Eagle "attribute" XML element. Note that an attribute element
+ * is different than an XML element attribute. The attribute element is a
+ * full XML node in and of itself, and has attributes of its own. Blame Eagle.
+ */
+EATTR::EATTR( CPTREE& aAttribute )
+{
+ CPTREE& attribs = aAttribute.get_child( "<xmlattr>" );
+
+ /*
+ <!ELEMENT attribute EMPTY>
+ <!ATTLIST attribute
+ name %String; #REQUIRED
+ value %String; #IMPLIED
+ x %Coord; #IMPLIED
+ y %Coord; #IMPLIED
+ size %Dimension; #IMPLIED
+ layer %Layer; #IMPLIED
+ font %TextFont; #IMPLIED
+ ratio %Int; #IMPLIED
+ rot %Rotation; "R0"
+ display %AttributeDisplay; "value" -- only in <element> or <instance> context --
+ constant %Bool; "no" -- only in <device> context --
+ >
+ */
+
+ name = attribs.get<string>( "name" ); // #REQUIRED
+ value = attribs.get_optional<string>( "value" );
+
+ x = attribs.get_optional<double>( "x" );
+ y = attribs.get_optional<double>( "y" );
+ size = attribs.get_optional<double>( "size" );
+
+ // KiCad cannot currently put a TEXTE_MODULE on a different layer than the MODULE
+ // Eagle can it seems.
+ layer = attribs.get_optional<int>( "layer" );
+
+ ratio = attribs.get_optional<double>( "ratio" );
+ rot = parseOptionalEROT( attribs );
+
+ opt_string stemp = attribs.get_optional<string>( "display" );
+ if( stemp )
+ {
+ // (off | value | name | both)
+ if( !stemp->compare( "off" ) )
+ display = EATTR::Off;
+ else if( !stemp->compare( "value" ) )
+ display = EATTR::VALUE;
+ else if( !stemp->compare( "name" ) )
+ display = EATTR::NAME;
+ else if( !stemp->compare( "both" ) )
+ display = EATTR::BOTH;
+ }
+}
+
+
+/// Eagle text element
+struct ETEXT
+{
+ string text;
+ double x;
+ double y;
+ double size;
+ int layer;
+ opt_string font;
+ opt_double ratio;
+ opt_erot rot;
+
+ enum { // for align
+ CENTER,
+ CENTER_LEFT,
+ TOP_CENTER,
+ TOP_LEFT,
+ TOP_RIGHT,
+
+ // opposites are -1 x above, used by code tricks in here
+ CENTER_RIGHT = -CENTER_LEFT,
+ BOTTOM_CENTER = -TOP_CENTER,
+ BOTTOM_LEFT = -TOP_RIGHT,
+ BOTTOM_RIGHT = -TOP_LEFT,
+ };
+
+ opt_int align;
+
+ ETEXT( CPTREE& aText );
+};
+
+ETEXT::ETEXT( CPTREE& aText )
+{
+ CPTREE& attribs = aText.get_child( "<xmlattr>" );
+
+ /*
+ <!ELEMENT text (#PCDATA)>
+ <!ATTLIST text
+ x %Coord; #REQUIRED
+ y %Coord; #REQUIRED
+ size %Dimension; #REQUIRED
+ layer %Layer; #REQUIRED
+ font %TextFont; "proportional"
+ ratio %Int; "8"
+ rot %Rotation; "R0"
+ align %Align; "bottom-left"
+ >
+ */
+
+ text = aText.data();
+ x = attribs.get<double>( "x" );
+ y = attribs.get<double>( "y" );
+ size = attribs.get<double>( "size" );
+ layer = attribs.get<int>( "layer" );
+
+ font = attribs.get_optional<string>( "font" );
+ ratio = attribs.get_optional<double>( "ratio" );
+ rot = parseOptionalEROT( attribs );
+
+ opt_string stemp = attribs.get_optional<string>( "align" );
+ if( stemp )
+ {
+ // (bottom-left | bottom-center | bottom-right | center-left |
+ // center | center-right | top-left | top-center | top-right)
+ if( !stemp->compare( "center" ) )
+ align = ETEXT::CENTER;
+ else if( !stemp->compare( "center-right" ) )
+ align = ETEXT::CENTER_RIGHT;
+ else if( !stemp->compare( "top-left" ) )
+ align = ETEXT::TOP_LEFT;
+ else if( !stemp->compare( "top-center" ) )
+ align = ETEXT::TOP_CENTER;
+ else if( !stemp->compare( "top-right" ) )
+ align = ETEXT::TOP_RIGHT;
+ else if( !stemp->compare( "bottom-left" ) )
+ align = ETEXT::BOTTOM_LEFT;
+ else if( !stemp->compare( "bottom-center" ) )
+ align = ETEXT::BOTTOM_CENTER;
+ else if( !stemp->compare( "bottom-right" ) )
+ align = ETEXT::BOTTOM_RIGHT;
+ else if( !stemp->compare( "center-left" ) )
+ align = ETEXT::CENTER_LEFT;
+ }
+}
+
+
+/// Eagle thru hol pad
+struct EPAD
+{
+ string name;
+ double x;
+ double y;
+ double drill;
+ opt_double diameter;
+
+ // for shape: (square | round | octagon | long | offset)
+ enum {
+ SQUARE,
+ ROUND,
+ OCTAGON,
+ LONG,
+ OFFSET,
+ };
+ opt_int shape;
+ opt_erot rot;
+ opt_bool stop;
+ opt_bool thermals;
+ opt_bool first;
+
+ EPAD( CPTREE& aPad );
+};
+
+EPAD::EPAD( CPTREE& aPad )
+{
+ CPTREE& attribs = aPad.get_child( "<xmlattr>" );
+
+ /*
+ <!ELEMENT pad EMPTY>
+ <!ATTLIST pad
+ name %String; #REQUIRED
+ x %Coord; #REQUIRED
+ y %Coord; #REQUIRED
+ drill %Dimension; #REQUIRED
+ diameter %Dimension; "0"
+ shape %PadShape; "round"
+ rot %Rotation; "R0"
+ stop %Bool; "yes"
+ thermals %Bool; "yes"
+ first %Bool; "no"
+ >
+ */
+
+ // #REQUIRED says DTD, throw exception if not found
+ name = attribs.get<string>( "name" );
+ x = attribs.get<double>( "x" );
+ y = attribs.get<double>( "y" );
+ drill = attribs.get<double>( "drill" );
+
+ diameter = attribs.get_optional<double>( "diameter" );
+
+ opt_string s = attribs.get_optional<string>( "shape" );
+ if( s )
+ {
+ // (square | round | octagon | long | offset)
+ if( !s->compare( "square" ) )
+ shape = EPAD::SQUARE;
+ else if( !s->compare( "round" ) )
+ shape = EPAD::ROUND;
+ else if( !s->compare( "octagon" ) )
+ shape = EPAD::OCTAGON;
+ else if( !s->compare( "long" ) )
+ shape = EPAD::LONG;
+ else if( !s->compare( "offset" ) )
+ shape = EPAD::OFFSET;
+ }
+
+ rot = parseOptionalEROT( attribs );
+ stop = parseOptionalBool( attribs, "stop" );
+ thermals = parseOptionalBool( attribs, "thermals" );
+ first = parseOptionalBool( attribs, "first" );
+}
+
+
+/// Eagle SMD pad
+struct ESMD
+{
+ string name;
+ double x;
+ double y;
+ double dx;
+ double dy;
+ int layer;
+ opt_int roundness;
+ opt_erot rot;
+ opt_bool stop;
+ opt_bool thermals;
+ opt_bool cream;
+
+ ESMD( CPTREE& aSMD );
+};
+
+ESMD::ESMD( CPTREE& aSMD )
+{
+ CPTREE& attribs = aSMD.get_child( "<xmlattr>" );
+
+ /*
+ <!ATTLIST smd
+ name %String; #REQUIRED
+ x %Coord; #REQUIRED
+ y %Coord; #REQUIRED
+ dx %Dimension; #REQUIRED
+ dy %Dimension; #REQUIRED
+ layer %Layer; #REQUIRED
+ roundness %Int; "0"
+ rot %Rotation; "R0"
+ stop %Bool; "yes"
+ thermals %Bool; "yes"
+ cream %Bool; "yes"
+ >
+ */
+
+ // DTD #REQUIRED, throw exception if not found
+ name = attribs.get<string>( "name" );
+ x = attribs.get<double>( "x" );
+ y = attribs.get<double>( "y" );
+ dx = attribs.get<double>( "dx" );
+ dy = attribs.get<double>( "dy" );
+ layer = attribs.get<int>( "layer" );
+ rot = parseOptionalEROT( attribs );
+
+ roundness = attribs.get_optional<int>( "roundness" );
+ thermals = parseOptionalBool( attribs, "thermals" );
+ stop = parseOptionalBool( attribs, "stop" );
+ thermals = parseOptionalBool( attribs, "thermals" );
+ cream = parseOptionalBool( attribs, "cream" );
+}
+
+
+struct EVERTEX
+{
+ double x;
+ double y;
+
+ EVERTEX( CPTREE& aVertex );
+};
+
+EVERTEX::EVERTEX( CPTREE& aVertex )
+{
+ CPTREE& attribs = aVertex.get_child( "<xmlattr>" );
+
+ /*
+ <!ELEMENT vertex EMPTY>
+ <!ATTLIST vertex
+ x %Coord; #REQUIRED
+ y %Coord; #REQUIRED
+ curve %WireCurve; "0" -- the curvature from this vertex to the next one --
+ >
+ */
+
+ x = attribs.get<double>( "x" );
+ y = attribs.get<double>( "y" );
+}
+
+
+/// Eagle polygon, without vertices which are parsed as needed
+struct EPOLYGON
+{
+ double width;
+ int layer;
+ opt_double spacing;
+
+ // KiCad priority is opposite of Eagle rank, that is:
+ // - Eagle Low rank drawn first
+ // - KiCad high priority drawn first
+ // So since Eagle has an upper limit we define this, used for the cases
+ // where no rank is specified.
+ static const int max_priority = 6;
+
+ enum { // for pour
+ SOLID,
+ HATCH,
+ CUTOUT,
+ };
+ int pour;
+ opt_double isolate;
+ opt_bool orphans;
+ opt_bool thermals;
+ opt_int rank;
+
+ EPOLYGON( CPTREE& aPolygon );
+};
+
+EPOLYGON::EPOLYGON( CPTREE& aPolygon )
+{
+ CPTREE& attribs = aPolygon.get_child( "<xmlattr>" );
+
+ /*
+ <!ATTLIST polygon
+ width %Dimension; #REQUIRED
+ layer %Layer; #REQUIRED
+ spacing %Dimension; #IMPLIED
+ pour %PolygonPour; "solid"
+ isolate %Dimension; #IMPLIED -- only in <signal> or <package> context --
+ orphans %Bool; "no" -- only in <signal> context --
+ thermals %Bool; "yes" -- only in <signal> context --
+ rank %Int; "0" -- 1..6 in <signal> context, 0 or 7 in <package> context --
+ >
+ */
+
+ width = attribs.get<double>( "width" );
+ layer = attribs.get<int>( "layer" );
+ spacing = attribs.get_optional<double>( "spacing" );
+ isolate = attribs.get_optional<double>( "isolate" );
+ // default pour to solid fill
+ pour = EPOLYGON::SOLID;
+ opt_string s = attribs.get_optional<string>( "pour" );
+
+ if( s )
+ {
+ // (solid | hatch | cutout)
+ if( !s->compare( "hatch" ) )
+ pour = EPOLYGON::HATCH;
+ else if( !s->compare( "cutout" ) )
+ pour = EPOLYGON::CUTOUT;
+ }
+
+ orphans = parseOptionalBool( attribs, "orphans" );
+ thermals = parseOptionalBool( attribs, "thermals" );
+ rank = attribs.get_optional<int>( "rank" );
+}
+
+/// Eagle hole element
+struct EHOLE
+{
+ double x;
+ double y;
+ double drill;
+
+ EHOLE( CPTREE& aHole );
+};
+
+EHOLE::EHOLE( CPTREE& aHole )
+{
+ CPTREE& attribs = aHole.get_child( "<xmlattr>" );
+
+ /*
+ <!ELEMENT hole EMPTY>
+ <!ATTLIST hole
+ x %Coord; #REQUIRED
+ y %Coord; #REQUIRED
+ drill %Dimension; #REQUIRED
+ >
+ */
+
+ // #REQUIRED:
+ x = attribs.get<double>( "x" );
+ y = attribs.get<double>( "y" );
+ drill = attribs.get<double>( "drill" );
+}
+
+
+/// Eagle element element
+struct EELEMENT
+{
+ string name;
+ string library;
+ string package;
+ string value;
+ double x;
+ double y;
+ opt_bool locked;
+ // opt_bool smashed;
+ opt_erot rot;
+
+ EELEMENT( CPTREE& aElement );
+};
+
+EELEMENT::EELEMENT( CPTREE& aElement )
+{
+ CPTREE& attribs = aElement.get_child( "<xmlattr>" );
+
+ /*
+ <!ELEMENT element (attribute*, variant*)>
+ <!ATTLIST element
+ name %String; #REQUIRED
+ library %String; #REQUIRED
+ package %String; #REQUIRED
+ value %String; #REQUIRED
+ x %Coord; #REQUIRED
+ y %Coord; #REQUIRED
+ locked %Bool; "no"
+ smashed %Bool; "no"
+ rot %Rotation; "R0"
+ >
+ */
+
+ // #REQUIRED
+ name = attribs.get<string>( "name" );
+ library = attribs.get<string>( "library" );
+ value = attribs.get<string>( "value" );
+
+ package = attribs.get<string>( "package" );
+ ReplaceIllegalFileNameChars( &package );
+
+ x = attribs.get<double>( "x" );
+ y = attribs.get<double>( "y" );
+
+ // optional
+ locked = parseOptionalBool( attribs, "locked" );
+ // smashed = pasreOptionalBool( attribs, "smashed" );
+ rot = parseOptionalEROT( attribs );
+}
+
+
+struct ELAYER
+{
+ int number;
+ string name;
+ int color;
+ int fill;
+ opt_bool visible;
+ opt_bool active;
+
+ ELAYER( CPTREE& aLayer );
+};
+
+ELAYER::ELAYER( CPTREE& aLayer )
+{
+ CPTREE& attribs = aLayer.get_child( "<xmlattr>" );
+
+ /*
+ <!ELEMENT layer EMPTY>
+ <!ATTLIST layer
+ number %Layer; #REQUIRED
+ name %String; #REQUIRED
+ color %Int; #REQUIRED
+ fill %Int; #REQUIRED
+ visible %Bool; "yes"
+ active %Bool; "yes"
+ >
+ */
+
+ number = attribs.get<int>( "number" );
+ name = attribs.get<string>( "name" );
+ color = attribs.get<int>( "color" );
+ fill = 1; // Temporary value.
+ visible = parseOptionalBool( attribs, "visible" );
+ active = parseOptionalBool( attribs, "active" );
+}
+
+
+/// Parse an eagle distance which is either mm, or mils if there is "mil" suffix.
+/// Return is in BIU.
+static double parseEagle( const string& aDistance )
+{
+ double ret = strtod( aDistance.c_str(), NULL );
+ if( aDistance.npos != aDistance.find( "mil" ) )
+ ret = IU_PER_MILS * ret;
+ else
+ ret = IU_PER_MM * ret;
+
+ return ret;
+}
+
+
+/// subset of eagle.drawing.board.designrules in the XML document
+struct ERULES
+{
+ int psElongationLong; ///< percent over 100%. 0-> not elongated, 100->twice as wide as is tall
+ ///< Goes into making a scaling factor for "long" pads.
+
+ int psElongationOffset; ///< the offset of the hole within the "long" pad.
+
+ double rvPadTop; ///< top pad size as percent of drill size
+ // double rvPadBottom; ///< bottom pad size as percent of drill size
+
+ double rlMinPadTop; ///< minimum copper annulus on through hole pads
+ double rlMaxPadTop; ///< maximum copper annulus on through hole pads
+
+ double rvViaOuter; ///< copper annulus is this percent of via hole
+ double rlMinViaOuter; ///< minimum copper annulus on via
+ double rlMaxViaOuter; ///< maximum copper annulus on via
+ double mdWireWire; ///< wire to wire spacing I presume.
+
+
+ ERULES() :
+ psElongationLong ( 100 ),
+ psElongationOffset ( 0 ),
+ rvPadTop ( 0.25 ),
+ // rvPadBottom ( 0.25 ),
+ rlMinPadTop ( Mils2iu( 10 ) ),
+ rlMaxPadTop ( Mils2iu( 20 ) ),
+
+ rvViaOuter ( 0.25 ),
+ rlMinViaOuter ( Mils2iu( 10 ) ),
+ rlMaxViaOuter ( Mils2iu( 20 ) ),
+ mdWireWire ( 0 )
+ {}
+
+ void parse( CPTREE& aRules );
+};
+
+void ERULES::parse( CPTREE& aRules )
+{
+ for( CITER it = aRules.begin(); it != aRules.end(); ++it )
+ {
+ if( it->first != "param" )
+ continue;
+
+ CPTREE& attribs = it->second.get_child( "<xmlattr>" );
+
+ const string& name = attribs.get<string>( "name" );
+
+ if( name == "psElongationLong" )
+ psElongationLong = attribs.get<int>( "value" );
+ else if( name == "psElongationOffset" )
+ psElongationOffset = attribs.get<int>( "value" );
+ else if( name == "rvPadTop" )
+ rvPadTop = attribs.get<double>( "value" );
+ else if( name == "rlMinPadTop" )
+ rlMinPadTop = parseEagle( attribs.get<string>( "value" ) );
+ else if( name == "rlMaxPadTop" )
+ rlMaxPadTop = parseEagle( attribs.get<string>( "value" ) );
+ else if( name == "rvViaOuter" )
+ rvViaOuter = attribs.get<double>( "value" );
+ else if( name == "rlMinViaOuter" )
+ rlMinViaOuter = parseEagle( attribs.get<string>( "value" ) );
+ else if( name == "rlMaxViaOuter" )
+ rlMaxViaOuter = parseEagle( attribs.get<string>( "value" ) );
+ else if( name == "mdWireWire" )
+ mdWireWire = parseEagle( attribs.get<string>( "value" ) );
+ }
+}
+
+
+/// Assemble a two part key as a simple concatonation of aFirst and aSecond parts,
+/// using a separator.
+static inline string makeKey( const string& aFirst, const string& aSecond )
+{
+ string key = aFirst + '\x02' + aSecond;
+ return key;
+}
+
+
+/// Make a unique time stamp
+static inline unsigned long timeStamp( CPTREE& aTree )
+{
+ // in this case from a unique tree memory location
+ return (unsigned long)(void*) &aTree;
+}
+
+
+/// Convert an Eagle curve end to a KiCad center for S_ARC
+wxPoint kicad_arc_center( wxPoint start, wxPoint end, double angle )
+{
+ // Eagle give us start and end.
+ // S_ARC wants start to give the center, and end to give the start.
+ double dx = end.x - start.x, dy = end.y - start.y;
+ wxPoint mid = (start + end) / 2;
+
+ double dlen = sqrt( dx*dx + dy*dy );
+ double dist = dlen / ( 2 * tan( DEG2RAD( angle ) / 2 ) );
+
+ wxPoint center(
+ mid.x + dist * ( dy / dlen ),
+ mid.y - dist * ( dx / dlen )
+ );
+
+ return center;
+}
+
+
+EAGLE_PLUGIN::EAGLE_PLUGIN() :
+ m_rules( new ERULES() ),
+ m_xpath( new XPATH() ),
+ m_mod_time( wxDateTime::Now() )
+{
+ init( NULL );
+
+ clear_cu_map();
+}
+
+
+EAGLE_PLUGIN::~EAGLE_PLUGIN()
+{
+ delete m_rules;
+ delete m_xpath;
+}
+
+
+const wxString EAGLE_PLUGIN::PluginName() const
+{
+ return wxT( "Eagle" );
+}
+
+
+const wxString EAGLE_PLUGIN::GetFileExtension() const
+{
+ return wxT( "brd" );
+}
+
+
+int inline EAGLE_PLUGIN::kicad( double d ) const
+{
+ return KiROUND( biu_per_mm * d );
+}
+
+
+wxSize inline EAGLE_PLUGIN::kicad_fontz( double d ) const
+{
+ // texts seem to better match eagle when scaled down by 0.95
+ int kz = kicad( d ) * 95 / 100;
+ return wxSize( kz, kz );
+}
+
+
+BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+ PTREE doc;
+
+ init( aProperties );
+
+ m_board = aAppendToMe ? aAppendToMe : new BOARD();
+
+ // Give the filename to the board if it's new
+ if( !aAppendToMe )
+ m_board->SetFileName( aFileName );
+
+ // delete on exception, iff I own m_board, according to aAppendToMe
+ auto_ptr<BOARD> deleter( aAppendToMe ? NULL : m_board );
+
+ try
+ {
+ // 8 bit "filename" should be encoded according to disk filename encoding,
+ // (maybe this is current locale, maybe not, its a filesystem issue),
+ // and is not necessarily utf8.
+ string filename = (const char*) aFileName.char_str( wxConvFile );
+
+ read_xml( filename, doc, xml_parser::no_comments );
+
+ m_min_trace = INT_MAX;
+ m_min_via = INT_MAX;
+ m_min_via_hole = INT_MAX;
+
+ loadAllSections( doc );
+
+ BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
+
+ if( m_min_trace < designSettings.m_TrackMinWidth )
+ designSettings.m_TrackMinWidth = m_min_trace;
+
+ if( m_min_via < designSettings.m_ViasMinSize )
+ designSettings.m_ViasMinSize = m_min_via;
+
+ if( m_min_via_hole < designSettings.m_ViasMinDrill )
+ designSettings.m_ViasMinDrill = m_min_via_hole;
+
+ if( m_rules->mdWireWire )
+ {
+ NETCLASSPTR defaultNetclass = designSettings.GetDefault();
+ int clearance = KiROUND( m_rules->mdWireWire );
+
+ if( clearance < defaultNetclass->GetClearance() )
+ defaultNetclass->SetClearance( clearance );
+ }
+
+ // should be empty, else missing m_xpath->pop()
+ wxASSERT( m_xpath->Contents().size() == 0 );
+ }
+
+ catch( file_parser_error fpe )
+ {
+ // for xml_parser_error, what() has the line number in it,
+ // but no byte offset. That should be an adequate error message.
+ THROW_IO_ERROR( fpe.what() );
+ }
+
+ // Class ptree_error is a base class for xml_parser_error & file_parser_error,
+ // so one catch should be OK for all errors.
+ catch( ptree_error pte )
+ {
+ string errmsg = pte.what();
+
+ errmsg += " @\n";
+ errmsg += m_xpath->Contents();
+
+ THROW_IO_ERROR( errmsg );
+ }
+
+ // IO_ERROR exceptions are left uncaught, they pass upwards from here.
+
+ // Ensure the copper layers count is a multiple of 2
+ // Pcbnew does not like boards with odd layers count
+ // (these boards cannot exist. they actually have a even layers count)
+ int lyrcnt = m_board->GetCopperLayerCount();
+
+ if( (lyrcnt % 2) != 0 )
+ {
+ lyrcnt++;
+ m_board->SetCopperLayerCount( lyrcnt );
+ }
+
+ centerBoard();
+
+ deleter.release();
+ return m_board;
+}
+
+
+void EAGLE_PLUGIN::init( const PROPERTIES* aProperties )
+{
+ m_hole_count = 0;
+ m_min_trace = 0;
+ m_min_via = 0;
+ m_min_via_hole = 0;
+ m_xpath->clear();
+ m_pads_to_nets.clear();
+
+ // m_templates.clear(); this is the FOOTPRINT cache too
+
+ m_board = NULL;
+ m_props = aProperties;
+
+ mm_per_biu = 1/IU_PER_MM;
+ biu_per_mm = IU_PER_MM;
+
+ delete m_rules;
+ m_rules = new ERULES();
+}
+
+
+void EAGLE_PLUGIN::clear_cu_map()
+{
+ // All cu layers are invalid until we see them in the <layers> section while
+ // loading either a board or library. See loadLayerDefs().
+ for( unsigned i = 0; i < DIM(m_cu_map); ++i )
+ m_cu_map[i] = -1;
+}
+
+
+void EAGLE_PLUGIN::loadAllSections( CPTREE& aDoc )
+{
+ CPTREE& drawing = aDoc.get_child( "eagle.drawing" );
+ CPTREE& board = drawing.get_child( "board" );
+
+ m_xpath->push( "eagle.drawing" );
+
+ {
+ m_xpath->push( "board" );
+
+ CPTREE& designrules = board.get_child( "designrules" );
+ loadDesignRules( designrules );
+
+ m_xpath->pop();
+ }
+
+ {
+ m_xpath->push( "layers" );
+
+ CPTREE& layers = drawing.get_child( "layers" );
+ loadLayerDefs( layers );
+
+ m_xpath->pop();
+ }
+
+ {
+ m_xpath->push( "board" );
+
+ CPTREE& plain = board.get_child( "plain" );
+ loadPlain( plain );
+
+ CPTREE& signals = board.get_child( "signals" );
+ loadSignals( signals );
+
+ CPTREE& libs = board.get_child( "libraries" );
+ loadLibraries( libs );
+
+ CPTREE& elems = board.get_child( "elements" );
+ loadElements( elems );
+
+ m_xpath->pop(); // "board"
+ }
+
+ m_xpath->pop(); // "eagle.drawing"
+}
+
+
+void EAGLE_PLUGIN::loadDesignRules( CPTREE& aDesignRules )
+{
+ m_xpath->push( "designrules" );
+ m_rules->parse( aDesignRules );
+ m_xpath->pop(); // "designrules"
+}
+
+
+void EAGLE_PLUGIN::loadLayerDefs( CPTREE& aLayers )
+{
+ typedef std::vector<ELAYER> ELAYERS;
+ typedef ELAYERS::const_iterator EITER;
+
+ ELAYERS cu; // copper layers
+
+ // find the subset of layers that are copper, and active
+ for( CITER layer = aLayers.begin(); layer != aLayers.end(); ++layer )
+ {
+ ELAYER elayer( layer->second );
+
+ if( elayer.number >= 1 && elayer.number <= 16 && ( !elayer.active || *elayer.active ) )
+ {
+ cu.push_back( elayer );
+ }
+ }
+
+ // establish cu layer map:
+ int ki_layer_count = 0;
+
+ for( EITER it = cu.begin(); it != cu.end(); ++it, ++ki_layer_count )
+ {
+ if( ki_layer_count == 0 )
+ m_cu_map[it->number] = F_Cu;
+ else if( ki_layer_count == int( cu.size()-1 ) )
+ m_cu_map[it->number] = B_Cu;
+ else
+ {
+ // some eagle boards do not have contiguous layer number sequences.
+
+#if 0 // pre LAYER_ID & LSET:
+ m_cu_map[it->number] = cu.size() - 1 - ki_layer_count;
+#else
+ m_cu_map[it->number] = ki_layer_count;
+#endif
+ }
+ }
+
+#if 0 && defined(DEBUG)
+ printf( "m_cu_map:\n" );
+ for( unsigned i=0; i<DIM(m_cu_map); ++i )
+ {
+ printf( "\t[%d]:%d\n", i, m_cu_map[i] );
+ }
+#endif
+
+ // Set the layer names and cu count iff we're loading a board.
+ if( m_board )
+ {
+ m_board->SetCopperLayerCount( cu.size() );
+
+ for( EITER it = cu.begin(); it != cu.end(); ++it )
+ {
+ LAYER_ID layer = kicad_layer( it->number );
+
+ // these function provide their own protection against UNDEFINED_LAYER:
+ m_board->SetLayerName( layer, FROM_UTF8( it->name.c_str() ) );
+ m_board->SetLayerType( layer, LT_SIGNAL );
+
+ // could map the colors here
+ }
+ }
+}
+
+
+void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics )
+{
+ m_xpath->push( "plain" );
+
+ // (polygon | wire | text | circle | rectangle | frame | hole)*
+ for( CITER gr = aGraphics.begin(); gr != aGraphics.end(); ++gr )
+ {
+ if( gr->first == "wire" )
+ {
+ m_xpath->push( "wire" );
+
+ EWIRE w( gr->second );
+ LAYER_ID layer = kicad_layer( w.layer );
+
+ wxPoint start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
+ wxPoint end( kicad_x( w.x2 ), kicad_y( w.y2 ) );
+
+ if( layer != UNDEFINED_LAYER )
+ {
+ DRAWSEGMENT* dseg = new DRAWSEGMENT( m_board );
+ m_board->Add( dseg, ADD_APPEND );
+
+ if( !w.curve )
+ {
+ dseg->SetStart( start );
+ dseg->SetEnd( end );
+ }
+ else
+ {
+ wxPoint center = kicad_arc_center( start, end, *w.curve);
+
+ dseg->SetShape( S_ARC );
+ dseg->SetStart( center );
+ dseg->SetEnd( start );
+ dseg->SetAngle( *w.curve * -10.0 ); // KiCad rotates the other way
+ }
+
+ dseg->SetTimeStamp( timeStamp( gr->second ) );
+ dseg->SetLayer( layer );
+ dseg->SetWidth( Millimeter2iu( DEFAULT_PCB_EDGE_THICKNESS ) );
+ }
+ m_xpath->pop();
+ }
+ else if( gr->first == "text" )
+ {
+#if defined(DEBUG)
+ if( gr->second.data() == "ATMEGA328" )
+ {
+ int breakhere = 1;
+ (void) breakhere;
+ }
+#endif
+ m_xpath->push( "text" );
+
+ ETEXT t( gr->second );
+ LAYER_ID layer = kicad_layer( t.layer );
+
+ if( layer != UNDEFINED_LAYER )
+ {
+ TEXTE_PCB* pcbtxt = new TEXTE_PCB( m_board );
+ m_board->Add( pcbtxt, ADD_APPEND );
+
+ pcbtxt->SetLayer( layer );
+ pcbtxt->SetTimeStamp( timeStamp( gr->second ) );
+ pcbtxt->SetText( FROM_UTF8( t.text.c_str() ) );
+ pcbtxt->SetTextPosition( wxPoint( kicad_x( t.x ), kicad_y( t.y ) ) );
+
+ pcbtxt->SetSize( kicad_fontz( t.size ) );
+
+ double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default
+
+ pcbtxt->SetThickness( kicad( t.size * ratio / 100 ) );
+
+ int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT;
+
+ if( t.rot )
+ {
+ int sign = t.rot->mirror ? -1 : 1;
+ pcbtxt->SetMirrored( t.rot->mirror );
+
+ double degrees = t.rot->degrees;
+
+ if( degrees == 90 || t.rot->spin )
+ pcbtxt->SetOrientation( sign * t.rot->degrees * 10 );
+ else if( degrees == 180 )
+ align = ETEXT::TOP_RIGHT;
+ else if( degrees == 270 )
+ {
+ pcbtxt->SetOrientation( sign * 90 * 10 );
+ align = ETEXT::TOP_RIGHT;
+ }
+ }
+
+ switch( align )
+ {
+ case ETEXT::CENTER:
+ // this was the default in pcbtxt's constructor
+ break;
+
+ case ETEXT::CENTER_LEFT:
+ pcbtxt->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ break;
+
+ case ETEXT::CENTER_RIGHT:
+ pcbtxt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ break;
+
+ case ETEXT::TOP_CENTER:
+ pcbtxt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
+ break;
+
+ case ETEXT::TOP_LEFT:
+ pcbtxt->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ pcbtxt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
+ break;
+
+ case ETEXT::TOP_RIGHT:
+ pcbtxt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ pcbtxt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
+ break;
+
+ case ETEXT::BOTTOM_CENTER:
+ pcbtxt->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+ break;
+
+ case ETEXT::BOTTOM_LEFT:
+ pcbtxt->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ pcbtxt->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+ break;
+
+ case ETEXT::BOTTOM_RIGHT:
+ pcbtxt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ pcbtxt->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+ break;
+ }
+ }
+ m_xpath->pop();
+ }
+ else if( gr->first == "circle" )
+ {
+ m_xpath->push( "circle" );
+
+ ECIRCLE c( gr->second );
+ LAYER_ID layer = kicad_layer( c.layer );
+
+ if( layer != UNDEFINED_LAYER ) // unsupported layer
+ {
+ DRAWSEGMENT* dseg = new DRAWSEGMENT( m_board );
+ m_board->Add( dseg, ADD_APPEND );
+
+ dseg->SetShape( S_CIRCLE );
+ dseg->SetTimeStamp( timeStamp( gr->second ) );
+ dseg->SetLayer( layer );
+ dseg->SetStart( wxPoint( kicad_x( c.x ), kicad_y( c.y ) ) );
+ dseg->SetEnd( wxPoint( kicad_x( c.x + c.radius ), kicad_y( c.y ) ) );
+ dseg->SetWidth( kicad( c.width ) );
+ }
+ m_xpath->pop();
+ }
+ else if( gr->first == "rectangle" )
+ {
+ // This seems to be a simplified rectangular [copper] zone, cannot find any
+ // net related info on it from the DTD.
+ m_xpath->push( "rectangle" );
+
+ ERECT r( gr->second );
+ LAYER_ID layer = kicad_layer( r.layer );
+
+ if( IsCopperLayer( layer ) )
+ {
+ // use a "netcode = 0" type ZONE:
+ ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board );
+ m_board->Add( zone, ADD_APPEND );
+
+ zone->SetTimeStamp( timeStamp( gr->second ) );
+ zone->SetLayer( layer );
+ zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
+
+ CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE;
+
+ zone->Outline()->Start( layer, kicad_x( r.x1 ), kicad_y( r.y1 ), outline_hatch );
+ zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ) );
+ zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ) );
+ zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ) );
+ zone->Outline()->CloseLastContour();
+
+ // this is not my fault:
+ zone->Outline()->SetHatch(
+ outline_hatch, Mils2iu( zone->Outline()->GetDefaultHatchPitchMils() ), true );
+ }
+
+ m_xpath->pop();
+ }
+ else if( gr->first == "hole" )
+ {
+ m_xpath->push( "hole" );
+ EHOLE e( gr->second );
+
+ // Fabricate a MODULE with a single PAD_ATTRIB_HOLE_NOT_PLATED pad.
+ // Use m_hole_count to gen up a unique name.
+
+ MODULE* module = new MODULE( m_board );
+ m_board->Add( module, ADD_APPEND );
+
+ char temp[40];
+ sprintf( temp, "@HOLE%d", m_hole_count++ );
+ module->SetReference( FROM_UTF8( temp ) );
+ module->Reference().SetVisible( false );
+
+ wxPoint pos( kicad_x( e.x ), kicad_y( e.y ) );
+
+ module->SetPosition( pos );
+
+ // Add a PAD_ATTRIB_HOLE_NOT_PLATED pad to this module.
+ D_PAD* pad = new D_PAD( module );
+ module->Pads().PushBack( pad );
+
+ pad->SetShape( PAD_SHAPE_CIRCLE );
+ pad->SetAttribute( PAD_ATTRIB_HOLE_NOT_PLATED );
+
+ /* pad's position is already centered on module at relative (0, 0)
+ wxPoint padpos( kicad_x( e.x ), kicad_y( e.y ) );
+
+ pad->SetPos0( padpos );
+ pad->SetPosition( padpos + module->GetPosition() );
+ */
+
+ wxSize sz( kicad( e.drill ), kicad( e.drill ) );
+
+ pad->SetDrillSize( sz );
+ pad->SetSize( sz );
+
+ pad->SetLayerSet( LSET::AllCuMask() );
+ m_xpath->pop();
+ }
+ else if( gr->first == "frame" )
+ {
+ // picture this
+ }
+ else if( gr->first == "polygon" )
+ {
+ // could be on a copper layer, could be on another layer.
+ // copper layer would be done using netCode=0 type of ZONE_CONTAINER.
+ }
+ }
+ m_xpath->pop();
+}
+
+
+void EAGLE_PLUGIN::loadLibrary( CPTREE& aLib, const string* aLibName )
+{
+ m_xpath->push( "packages" );
+
+ // library will have <xmlattr> node, skip that and get the single packages node
+ CPTREE& packages = aLib.get_child( "packages" );
+
+ // Create a MODULE for all the eagle packages, for use later via a copy constructor
+ // to instantiate needed MODULES in our BOARD. Save the MODULE templates in
+ // a MODULE_MAP using a single lookup key consisting of libname+pkgname.
+
+ for( CITER package = packages.begin(); package != packages.end(); ++package )
+ {
+ m_xpath->push( "package", "name" );
+
+ const string& pack_ref = package->second.get<string>( "<xmlattr>.name" );
+
+ string pack_name( pack_ref );
+
+ ReplaceIllegalFileNameChars( &pack_name );
+
+#if 0 && defined(DEBUG)
+ if( pack_name == "TO220H" )
+ {
+ int breakhere = 1;
+ (void) breakhere;
+ }
+#endif
+ m_xpath->Value( pack_name.c_str() );
+
+ string key = aLibName ? makeKey( *aLibName, pack_name ) : pack_name;
+
+ MODULE* m = makeModule( package->second, pack_name );
+
+ // add the templating MODULE to the MODULE template factory "m_templates"
+ std::pair<MODULE_ITER, bool> r = m_templates.insert( key, m );
+
+ if( !r.second
+ // && !( m_props && m_props->Value( "ignore_duplicates" ) )
+ )
+ {
+ wxString lib = aLibName ? FROM_UTF8( aLibName->c_str() ) : m_lib_path;
+ wxString pkg = FROM_UTF8( pack_name.c_str() );
+
+ wxString emsg = wxString::Format(
+ _( "<package> name: '%s' duplicated in eagle <library>: '%s'" ),
+ GetChars( pkg ),
+ GetChars( lib )
+ );
+ THROW_IO_ERROR( emsg );
+ }
+
+ m_xpath->pop();
+ }
+
+ m_xpath->pop(); // "packages"
+}
+
+
+void EAGLE_PLUGIN::loadLibraries( CPTREE& aLibs )
+{
+ m_xpath->push( "libraries.library", "name" );
+
+ for( CITER library = aLibs.begin(); library != aLibs.end(); ++library )
+ {
+ const string& lib_name = library->second.get<string>( "<xmlattr>.name" );
+
+ m_xpath->Value( lib_name.c_str() );
+
+ loadLibrary( library->second, &lib_name );
+ }
+
+ m_xpath->pop();
+}
+
+
+void EAGLE_PLUGIN::loadElements( CPTREE& aElements )
+{
+ m_xpath->push( "elements.element", "name" );
+
+ EATTR name;
+ EATTR value;
+
+ for( CITER it = aElements.begin(); it != aElements.end(); ++it )
+ {
+ if( it->first != "element" )
+ continue;
+
+ EELEMENT e( it->second );
+
+ // use "NULL-ness" as an indication of presence of the attribute:
+ EATTR* nameAttr = 0;
+ EATTR* valueAttr = 0;
+
+ m_xpath->Value( e.name.c_str() );
+
+ string key = makeKey( e.library, e.package );
+
+ MODULE_CITER mi = m_templates.find( key );
+
+ if( mi == m_templates.end() )
+ {
+ wxString emsg = wxString::Format( _( "No '%s' package in library '%s'" ),
+ GetChars( FROM_UTF8( e.package.c_str() ) ),
+ GetChars( FROM_UTF8( e.library.c_str() ) ) );
+ THROW_IO_ERROR( emsg );
+ }
+
+#if defined(DEBUG)
+ if( e.name == "ARM_C8" )
+ {
+ int breakhere = 1;
+ (void) breakhere;
+ }
+#endif
+ // copy constructor to clone the template
+ MODULE* m = new MODULE( *mi->second );
+ m_board->Add( m, ADD_APPEND );
+
+ // update the nets within the pads of the clone
+ for( D_PAD* pad = m->Pads(); pad; pad = pad->Next() )
+ {
+ string key = makeKey( e.name, TO_UTF8( pad->GetPadName() ) );
+
+ NET_MAP_CITER ni = m_pads_to_nets.find( key );
+ if( ni != m_pads_to_nets.end() )
+ {
+ const ENET* enet = &ni->second;
+ pad->SetNetCode( enet->netcode );
+ }
+ }
+
+ m->SetPosition( wxPoint( kicad_x( e.x ), kicad_y( e.y ) ) );
+ m->SetReference( FROM_UTF8( e.name.c_str() ) );
+ m->SetValue( FROM_UTF8( e.value.c_str() ) );
+ // m->Value().SetVisible( false );
+
+ // initalize these to default values incase the <attribute> elements are not present.
+ m_xpath->push( "attribute", "name" );
+
+ // VALUE and NAME can have something like our text "effects" overrides
+ // in SWEET and new schematic. Eagle calls these XML elements "attribute".
+ // There can be one for NAME and/or VALUE both. Features present in the
+ // EATTR override the ones established in the package only if they are
+ // present here (except for rot, which if not present means angle zero).
+ // So the logic is a bit different than in packageText() and in plain text.
+ for( CITER ait = it->second.begin(); ait != it->second.end(); ++ait )
+ {
+ if( ait->first != "attribute" )
+ continue;
+
+ EATTR a( ait->second );
+
+ if( a.name == "NAME" )
+ {
+ name = a;
+ nameAttr = &name;
+ }
+ else if( a.name == "VALUE" )
+ {
+ value = a;
+ valueAttr = &value;
+ }
+ }
+
+ m_xpath->pop(); // "attribute"
+
+ orientModuleAndText( m, e, nameAttr, valueAttr );
+ }
+
+ m_xpath->pop(); // "elements.element"
+}
+
+
+void EAGLE_PLUGIN::orientModuleAndText( MODULE* m, const EELEMENT& e,
+ const EATTR* nameAttr, const EATTR* valueAttr )
+{
+ if( e.rot )
+ {
+ if( e.rot->mirror )
+ {
+ double orientation = e.rot->degrees + 180.0;
+ m->SetOrientation( orientation * 10 );
+ m->Flip( m->GetPosition() );
+ }
+ else
+ m->SetOrientation( e.rot->degrees * 10 );
+ }
+
+ orientModuleText( m, e, &m->Reference(), nameAttr );
+ orientModuleText( m, e, &m->Value(), valueAttr );
+}
+
+
+void EAGLE_PLUGIN::orientModuleText( MODULE* m, const EELEMENT& e,
+ TEXTE_MODULE* txt, const EATTR* aAttr )
+{
+ if( aAttr )
+ {
+ const EATTR& a = *aAttr;
+
+ if( a.value )
+ {
+ txt->SetText( FROM_UTF8( a.value->c_str() ) );
+ }
+
+ if( a.x && a.y ) // boost::optional
+ {
+ wxPoint pos( kicad_x( *a.x ), kicad_y( *a.y ) );
+ txt->SetTextPosition( pos );
+ }
+
+ // Even though size and ratio are both optional, I am not seeing
+ // a case where ratio is present but size is not.
+ double ratio = 8;
+ wxSize fontz = txt->GetSize();
+
+ if( a.size )
+ {
+ fontz = kicad_fontz( *a.size );
+ txt->SetSize( fontz );
+
+ if( a.ratio )
+ ratio = *a.ratio;
+ }
+
+ int lw = int( fontz.y * ratio / 100.0 );
+ txt->SetThickness( lw );
+
+ int align = ETEXT::BOTTOM_LEFT; // bottom-left is eagle default
+
+ // The "rot" in a EATTR seems to be assumed to be zero if it is not
+ // present, and this zero rotation becomes an override to the
+ // package's text field. If they did not want zero, they specify
+ // what they want explicitly.
+ double degrees = a.rot ? a.rot->degrees : 0;
+ double orient; // relative to parent
+
+ int sign = 1;
+ bool spin = false;
+
+ if( a.rot )
+ {
+ spin = a.rot->spin;
+ sign = a.rot->mirror ? -1 : 1;
+ txt->SetMirrored( a.rot->mirror );
+ }
+
+ if( degrees == 90 || degrees == 0 || spin )
+ {
+ orient = degrees - m->GetOrientation() / 10;
+ txt->SetOrientation( sign * orient * 10 );
+ }
+ else if( degrees == 180 )
+ {
+ orient = 0 - m->GetOrientation() / 10;
+ txt->SetOrientation( sign * orient * 10 );
+ align = ETEXT::TOP_RIGHT;
+ }
+ else if( degrees == 270 )
+ {
+ orient = 90 - m->GetOrientation() / 10;
+ align = ETEXT::TOP_RIGHT;
+ txt->SetOrientation( sign * orient * 10 );
+ }
+ else
+ {
+ orient = 90 + degrees - m->GetOrientation() / 10;
+ txt->SetOrientation( sign * orient * 10 );
+ }
+
+ switch( align )
+ {
+ case ETEXT::TOP_RIGHT:
+ txt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ txt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
+ break;
+
+ case ETEXT::BOTTOM_LEFT:
+ txt->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ txt->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+ break;
+
+ default:
+ ;
+ }
+ }
+ else // the text is per the original package, sans <attribute>
+ {
+ double degrees = ( txt->GetOrientation() + m->GetOrientation() ) / 10;
+
+ // @todo there are a few more cases than these to contend with:
+ if( (!txt->IsMirrored() && ( abs( degrees ) == 180 || abs( degrees ) == 270 ))
+ || ( txt->IsMirrored() && ( degrees == 360 ) ) )
+ {
+ // ETEXT::TOP_RIGHT:
+ txt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ txt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
+ }
+ }
+}
+
+MODULE* EAGLE_PLUGIN::makeModule( CPTREE& aPackage, const string& aPkgName ) const
+{
+ std::auto_ptr<MODULE> m( new MODULE( m_board ) );
+
+ m->SetFPID( FPID( aPkgName ) );
+
+ opt_string description = aPackage.get_optional<string>( "description" );
+ if( description )
+ m->SetDescription( FROM_UTF8( description->c_str() ) );
+
+ for( CITER it = aPackage.begin(); it != aPackage.end(); ++it )
+ {
+ CPTREE& t = it->second;
+
+ if( it->first == "wire" )
+ packageWire( m.get(), t );
+
+ else if( it->first == "pad" )
+ packagePad( m.get(), t );
+
+ else if( it->first == "text" )
+ packageText( m.get(), t );
+
+ else if( it->first == "rectangle" )
+ packageRectangle( m.get(), t );
+
+ else if( it->first == "polygon" )
+ packagePolygon( m.get(), t );
+
+ else if( it->first == "circle" )
+ packageCircle( m.get(), t );
+
+ else if( it->first == "hole" )
+ packageHole( m.get(), t );
+
+ else if( it->first == "smd" )
+ packageSMD( m.get(), t );
+ }
+
+ return m.release();
+}
+
+
+void EAGLE_PLUGIN::packageWire( MODULE* aModule, CPTREE& aTree ) const
+{
+ EWIRE w( aTree );
+ LAYER_ID layer = kicad_layer( w.layer );
+
+ if( IsNonCopperLayer( layer ) ) // only valid non-copper wires, skip copper package wires
+ {
+ wxPoint start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
+ wxPoint end( kicad_x( w.x2 ), kicad_y( w.y2 ) );
+ int width = kicad( w.width );
+
+ // FIXME: the cap attribute is ignored because kicad can't create lines
+ // with flat ends.
+ EDGE_MODULE* dwg;
+ if( !w.curve )
+ {
+ dwg = new EDGE_MODULE( aModule, S_SEGMENT );
+
+ dwg->SetStart0( start );
+ dwg->SetEnd0( end );
+ }
+ else
+ {
+ dwg = new EDGE_MODULE( aModule, S_ARC );
+ wxPoint center = kicad_arc_center( start, end, *w.curve);
+
+ dwg->SetStart0( center );
+ dwg->SetEnd0( start );
+ dwg->SetAngle( *w.curve * -10.0 ); // KiCad rotates the other way
+ }
+
+ dwg->SetLayer( layer );
+ dwg->SetWidth( width );
+
+ aModule->GraphicalItems().PushBack( dwg );
+ }
+}
+
+
+void EAGLE_PLUGIN::packagePad( MODULE* aModule, CPTREE& aTree ) const
+{
+ // this is thru hole technology here, no SMDs
+ EPAD e( aTree );
+
+ D_PAD* pad = new D_PAD( aModule );
+ aModule->Pads().PushBack( pad );
+
+ pad->SetPadName( FROM_UTF8( e.name.c_str() ) );
+
+ // pad's "Position" is not relative to the module's,
+ // whereas Pos0 is relative to the module's but is the unrotated coordinate.
+
+ wxPoint padpos( kicad_x( e.x ), kicad_y( e.y ) );
+
+ pad->SetPos0( padpos );
+
+ RotatePoint( &padpos, aModule->GetOrientation() );
+
+ pad->SetPosition( padpos + aModule->GetPosition() );
+
+ pad->SetDrillSize( wxSize( kicad( e.drill ), kicad( e.drill ) ) );
+
+ pad->SetLayerSet( LSET::AllCuMask().set( B_Mask ).set( F_Mask ) );
+
+ if( e.shape )
+ {
+ switch( *e.shape )
+ {
+ case EPAD::ROUND:
+ wxASSERT( pad->GetShape()==PAD_SHAPE_CIRCLE ); // verify set in D_PAD constructor
+ break;
+ case EPAD::OCTAGON:
+ // no KiCad octagonal pad shape, use PAD_CIRCLE for now.
+ // pad->SetShape( PAD_OCTAGON );
+ wxASSERT( pad->GetShape()==PAD_SHAPE_CIRCLE ); // verify set in D_PAD constructor
+ break;
+ case EPAD::LONG:
+ pad->SetShape( PAD_SHAPE_OVAL );
+ break;
+ case EPAD::SQUARE:
+ pad->SetShape( PAD_SHAPE_RECT );
+ break;
+ case EPAD::OFFSET:
+ ; // don't know what to do here.
+ }
+ }
+ else
+ {
+ // if shape is not present, our default is circle and that matches their default "round"
+ }
+
+ if( e.diameter )
+ {
+ int diameter = kicad( *e.diameter );
+ pad->SetSize( wxSize( diameter, diameter ) );
+ }
+ else
+ {
+ double drillz = pad->GetDrillSize().x;
+ double annulus = drillz * m_rules->rvPadTop; // copper annulus, eagle "restring"
+ annulus = Clamp( m_rules->rlMinPadTop, annulus, m_rules->rlMaxPadTop );
+ int diameter = KiROUND( drillz + 2 * annulus );
+ pad->SetSize( wxSize( KiROUND( diameter ), KiROUND( diameter ) ) );
+ }
+
+ if( pad->GetShape() == PAD_SHAPE_OVAL )
+ {
+ // The Eagle "long" pad is wider than it is tall,
+ // m_elongation is percent elongation
+ wxSize sz = pad->GetSize();
+ sz.x = ( sz.x * ( 100 + m_rules->psElongationLong ) ) / 100;
+ pad->SetSize( sz );
+ }
+
+ if( e.rot )
+ {
+ pad->SetOrientation( e.rot->degrees * 10 );
+ }
+
+ // @todo: handle stop and thermal
+}
+
+
+void EAGLE_PLUGIN::packageText( MODULE* aModule, CPTREE& aTree ) const
+{
+ ETEXT t( aTree );
+ LAYER_ID layer = kicad_layer( t.layer );
+
+ if( layer == UNDEFINED_LAYER )
+ {
+ layer = Cmts_User;
+ }
+
+ TEXTE_MODULE* txt;
+
+ if( t.text == ">NAME" || t.text == ">name" )
+ txt = &aModule->Reference();
+ else if( t.text == ">VALUE" || t.text == ">value" )
+ txt = &aModule->Value();
+ else
+ {
+ // FIXME: graphical text items are rotated for some reason.
+ txt = new TEXTE_MODULE( aModule );
+ aModule->GraphicalItems().PushBack( txt );
+ }
+
+ txt->SetTimeStamp( timeStamp( aTree ) );
+ txt->SetText( FROM_UTF8( t.text.c_str() ) );
+
+ wxPoint pos( kicad_x( t.x ), kicad_y( t.y ) );
+
+ txt->SetTextPosition( pos );
+ txt->SetPos0( pos - aModule->GetPosition() );
+
+ txt->SetLayer( layer );
+
+ txt->SetSize( kicad_fontz( t.size ) );
+
+ double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default
+
+ txt->SetThickness( kicad( t.size * ratio / 100 ) );
+
+ int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT; // bottom-left is eagle default
+
+ // An eagle package is never rotated, the DTD does not allow it.
+ // angle -= aModule->GetOrienation();
+
+ if( t.rot )
+ {
+ int sign = t.rot->mirror ? -1 : 1;
+ txt->SetMirrored( t.rot->mirror );
+
+ double degrees = t.rot->degrees;
+
+ if( degrees == 90 || t.rot->spin )
+ txt->SetOrientation( sign * degrees * 10 );
+
+ else if( degrees == 180 )
+ align = ETEXT::TOP_RIGHT;
+
+ else if( degrees == 270 )
+ {
+ align = ETEXT::TOP_RIGHT;
+ txt->SetOrientation( sign * 90 * 10 );
+ }
+ }
+
+ switch( align )
+ {
+ case ETEXT::CENTER:
+ // this was the default in pcbtxt's constructor
+ break;
+
+ case ETEXT::CENTER_LEFT:
+ txt->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ break;
+
+ case ETEXT::CENTER_RIGHT:
+ txt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ break;
+
+ case ETEXT::TOP_CENTER:
+ txt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
+ break;
+
+ case ETEXT::TOP_LEFT:
+ txt->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ txt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
+ break;
+
+ case ETEXT::TOP_RIGHT:
+ txt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ txt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
+ break;
+
+ case ETEXT::BOTTOM_CENTER:
+ txt->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+ break;
+
+ case ETEXT::BOTTOM_LEFT:
+ txt->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ txt->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+ break;
+
+ case ETEXT::BOTTOM_RIGHT:
+ txt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ txt->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+ break;
+ }
+}
+
+
+void EAGLE_PLUGIN::packageRectangle( MODULE* aModule, CPTREE& aTree ) const
+{
+ ERECT r( aTree );
+ LAYER_ID layer = kicad_layer( r.layer );
+
+ if( IsNonCopperLayer( layer ) ) // skip copper "package.rectangle"s
+ {
+ EDGE_MODULE* dwg = new EDGE_MODULE( aModule, S_POLYGON );
+ aModule->GraphicalItems().PushBack( dwg );
+
+ dwg->SetLayer( layer );
+ dwg->SetWidth( 0 );
+
+ dwg->SetTimeStamp( timeStamp( aTree ) );
+
+ std::vector<wxPoint> pts;
+
+ wxPoint start( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ) );
+ wxPoint end( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ) );
+
+ pts.push_back( start );
+ pts.push_back( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ) );
+ pts.push_back( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ) );
+ pts.push_back( end );
+
+ dwg->SetPolyPoints( pts );
+
+ dwg->SetStart0( start );
+ dwg->SetEnd0( end );
+ }
+}
+
+
+void EAGLE_PLUGIN::packagePolygon( MODULE* aModule, CPTREE& aTree ) const
+{
+ EPOLYGON p( aTree );
+ LAYER_ID layer = kicad_layer( p.layer );
+
+ if( IsNonCopperLayer( layer ) ) // skip copper "package.rectangle"s
+ {
+ EDGE_MODULE* dwg = new EDGE_MODULE( aModule, S_POLYGON );
+ aModule->GraphicalItems().PushBack( dwg );
+
+ dwg->SetWidth( 0 ); // it's filled, no need for boundary width
+
+ /*
+ switch( layer )
+ {
+ case Eco1_User: layer = F_SilkS; break;
+ case Eco2_User: layer = B_SilkS; break;
+
+ // all MODULE templates (created from eagle packages) are on front layer
+ // until cloned.
+ case Cmts_User: layer = F_SilkS; break;
+ }
+ */
+
+ dwg->SetLayer( layer );
+
+ dwg->SetTimeStamp( timeStamp( aTree ) );
+
+ std::vector<wxPoint> pts;
+ pts.reserve( aTree.size() );
+
+ for( CITER vi = aTree.begin(); vi != aTree.end(); ++vi )
+ {
+ if( vi->first != "vertex" ) // skip <xmlattr> node
+ continue;
+
+ EVERTEX v( vi->second );
+
+ pts.push_back( wxPoint( kicad_x( v.x ), kicad_y( v.y ) ) );
+ }
+
+ dwg->SetPolyPoints( pts );
+
+ dwg->SetStart0( *pts.begin() );
+ dwg->SetEnd0( pts.back() );
+ }
+}
+
+
+void EAGLE_PLUGIN::packageCircle( MODULE* aModule, CPTREE& aTree ) const
+{
+ ECIRCLE e( aTree );
+ LAYER_ID layer = kicad_layer( e.layer );
+ EDGE_MODULE* gr = new EDGE_MODULE( aModule, S_CIRCLE );
+
+ aModule->GraphicalItems().PushBack( gr );
+
+ gr->SetWidth( kicad( e.width ) );
+
+ switch( (int) layer )
+ {
+ case UNDEFINED_LAYER: layer = Cmts_User; break;
+ /*
+ case Eco1_User: layer = F_SilkS; break;
+ case Eco2_User: layer = B_SilkS; break;
+ */
+ default:
+ break;
+ }
+
+ gr->SetLayer( layer );
+ gr->SetTimeStamp( timeStamp( aTree ) );
+
+ gr->SetStart0( wxPoint( kicad_x( e.x ), kicad_y( e.y ) ) );
+ gr->SetEnd0( wxPoint( kicad_x( e.x + e.radius ), kicad_y( e.y ) ) );
+}
+
+
+void EAGLE_PLUGIN::packageHole( MODULE* aModule, CPTREE& aTree ) const
+{
+ EHOLE e( aTree );
+
+ // we add a PAD_ATTRIB_HOLE_NOT_PLATED pad to this module.
+ D_PAD* pad = new D_PAD( aModule );
+ aModule->Pads().PushBack( pad );
+
+ pad->SetShape( PAD_SHAPE_CIRCLE );
+ pad->SetAttribute( PAD_ATTRIB_HOLE_NOT_PLATED );
+
+ // Mechanical purpose only:
+ // no offset, no net name, no pad name allowed
+ // pad->SetOffset( wxPoint( 0, 0 ) );
+ // pad->SetPadName( wxEmptyString );
+
+ wxPoint padpos( kicad_x( e.x ), kicad_y( e.y ) );
+
+ pad->SetPos0( padpos );
+ pad->SetPosition( padpos + aModule->GetPosition() );
+
+ wxSize sz( kicad( e.drill ), kicad( e.drill ) );
+
+ pad->SetDrillSize( sz );
+ pad->SetSize( sz );
+
+ pad->SetLayerSet( LSET::AllCuMask() /* | SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT */ );
+}
+
+
+void EAGLE_PLUGIN::packageSMD( MODULE* aModule, CPTREE& aTree ) const
+{
+ ESMD e( aTree );
+ LAYER_ID layer = kicad_layer( e.layer );
+
+ if( !IsCopperLayer( layer ) )
+ {
+ return;
+ }
+
+ D_PAD* pad = new D_PAD( aModule );
+ aModule->Pads().PushBack( pad );
+
+ pad->SetPadName( FROM_UTF8( e.name.c_str() ) );
+ pad->SetShape( PAD_SHAPE_RECT );
+ pad->SetAttribute( PAD_ATTRIB_SMD );
+
+ // pad's "Position" is not relative to the module's,
+ // whereas Pos0 is relative to the module's but is the unrotated coordinate.
+
+ wxPoint padpos( kicad_x( e.x ), kicad_y( e.y ) );
+
+ pad->SetPos0( padpos );
+
+ RotatePoint( &padpos, aModule->GetOrientation() );
+
+ pad->SetPosition( padpos + aModule->GetPosition() );
+
+ pad->SetSize( wxSize( kicad( e.dx ), kicad( e.dy ) ) );
+
+ pad->SetLayer( layer );
+
+ static const LSET front( 3, F_Cu, F_Paste, F_Mask );
+ static const LSET back( 3, B_Cu, B_Paste, B_Mask );
+
+ if( layer == F_Cu )
+ pad->SetLayerSet( front );
+ else if( layer == B_Cu )
+ pad->SetLayerSet( back );
+
+ // Optional according to DTD
+ if( e.roundness ) // set set shape to PAD_SHAPE_RECT above, in case roundness is not present
+ {
+ if( *e.roundness >= 75 ) // roundness goes from 0-100% as integer
+ {
+ if( e.dy == e.dx )
+ pad->SetShape( PAD_SHAPE_CIRCLE );
+ else
+ pad->SetShape( PAD_SHAPE_OVAL );
+ }
+ }
+
+ if( e.rot )
+ {
+ pad->SetOrientation( e.rot->degrees * 10 );
+ }
+
+ // don't know what stop, thermals, and cream should look like now.
+}
+
+/// non-owning container
+typedef std::vector<ZONE_CONTAINER*> ZONES;
+
+
+void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals )
+{
+ ZONES zones; // per net
+
+ m_xpath->push( "signals.signal", "name" );
+
+ int netCode = 1;
+
+ for( CITER net = aSignals.begin(); net != aSignals.end(); ++net )
+ {
+ bool sawPad = false;
+
+ zones.clear();
+
+ const string& nname = net->second.get<string>( "<xmlattr>.name" );
+ wxString netName = FROM_UTF8( nname.c_str() );
+ m_board->AppendNet( new NETINFO_ITEM( m_board, netName, netCode ) );
+
+ m_xpath->Value( nname.c_str() );
+
+#if defined(DEBUG)
+ if( netName == wxT( "N$8" ) )
+ {
+ int breakhere = 1;
+ (void) breakhere;
+ }
+#endif
+ // (contactref | polygon | wire | via)*
+ for( CITER it = net->second.begin(); it != net->second.end(); ++it )
+ {
+ if( it->first == "wire" )
+ {
+ m_xpath->push( "wire" );
+ EWIRE w( it->second );
+ LAYER_ID layer = kicad_layer( w.layer );
+
+ if( IsCopperLayer( layer ) )
+ {
+ TRACK* t = new TRACK( m_board );
+
+ t->SetTimeStamp( timeStamp( it->second ) );
+
+ t->SetPosition( wxPoint( kicad_x( w.x1 ), kicad_y( w.y1 ) ) );
+ t->SetEnd( wxPoint( kicad_x( w.x2 ), kicad_y( w.y2 ) ) );
+
+ int width = kicad( w.width );
+ if( width < m_min_trace )
+ m_min_trace = width;
+
+ t->SetWidth( width );
+ t->SetLayer( layer );
+ t->SetNetCode( netCode );
+
+ m_board->m_Track.Insert( t, NULL );
+ }
+ else
+ {
+ // put non copper wires where the sun don't shine.
+ }
+
+ m_xpath->pop();
+ }
+
+ else if( it->first == "via" )
+ {
+ m_xpath->push( "via" );
+ EVIA v( it->second );
+
+ LAYER_ID layer_front_most = kicad_layer( v.layer_front_most );
+ LAYER_ID layer_back_most = kicad_layer( v.layer_back_most );
+
+ if( IsCopperLayer( layer_front_most ) &&
+ IsCopperLayer( layer_back_most ) )
+ {
+ int kidiam;
+ int drillz = kicad( v.drill );
+ VIA* via = new VIA( m_board );
+ m_board->m_Track.Insert( via, NULL );
+
+ via->SetLayerPair( layer_front_most, layer_back_most );
+
+ if( v.diam )
+ {
+ kidiam = kicad( *v.diam );
+ via->SetWidth( kidiam );
+ }
+ else
+ {
+ double annulus = drillz * m_rules->rvViaOuter; // eagle "restring"
+ annulus = Clamp( m_rules->rlMinViaOuter, annulus, m_rules->rlMaxViaOuter );
+ kidiam = KiROUND( drillz + 2 * annulus );
+ via->SetWidth( kidiam );
+ }
+
+ via->SetDrill( drillz );
+
+ if( kidiam < m_min_via )
+ m_min_via = kidiam;
+
+ if( drillz < m_min_via_hole )
+ m_min_via_hole = drillz;
+
+ if( layer_front_most == F_Cu && layer_back_most == B_Cu )
+ via->SetViaType( VIA_THROUGH );
+ else if( layer_front_most == F_Cu || layer_back_most == B_Cu )
+ via->SetViaType( VIA_MICROVIA );
+ else
+ via->SetViaType( VIA_BLIND_BURIED );
+
+ via->SetTimeStamp( timeStamp( it->second ) );
+
+ wxPoint pos( kicad_x( v.x ), kicad_y( v.y ) );
+
+ via->SetPosition( pos );
+ via->SetEnd( pos );
+
+ via->SetNetCode( netCode );
+ }
+ m_xpath->pop();
+ }
+
+ else if( it->first == "contactref" )
+ {
+ m_xpath->push( "contactref" );
+ // <contactref element="RN1" pad="7"/>
+ CPTREE& attribs = it->second.get_child( "<xmlattr>" );
+
+ const string& reference = attribs.get<string>( "element" );
+ const string& pad = attribs.get<string>( "pad" );
+
+ string key = makeKey( reference, pad ) ;
+
+ // D(printf( "adding refname:'%s' pad:'%s' netcode:%d netname:'%s'\n", reference.c_str(), pad.c_str(), netCode, nname.c_str() );)
+
+ m_pads_to_nets[ key ] = ENET( netCode, nname );
+
+ m_xpath->pop();
+
+ sawPad = true;
+ }
+
+ else if( it->first == "polygon" )
+ {
+ m_xpath->push( "polygon" );
+
+ EPOLYGON p( it->second );
+ LAYER_ID layer = kicad_layer( p.layer );
+
+ if( IsCopperLayer( layer ) )
+ {
+ // use a "netcode = 0" type ZONE:
+ ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board );
+ m_board->Add( zone, ADD_APPEND );
+ zones.push_back( zone );
+
+ zone->SetTimeStamp( timeStamp( it->second ) );
+ zone->SetLayer( layer );
+ zone->SetNetCode( netCode );
+
+ bool first = true;
+ for( CITER vi = it->second.begin(); vi != it->second.end(); ++vi )
+ {
+ if( vi->first != "vertex" ) // skip <xmlattr> node
+ continue;
+
+ EVERTEX v( vi->second );
+
+ // the ZONE_CONTAINER API needs work, as you can see:
+ if( first )
+ {
+ zone->Outline()->Start( layer, kicad_x( v.x ), kicad_y( v.y ),
+ CPolyLine::NO_HATCH);
+ first = false;
+ }
+ else
+ zone->AppendCorner( wxPoint( kicad_x( v.x ), kicad_y( v.y ) ) );
+ }
+
+ zone->Outline()->CloseLastContour();
+
+ // If the pour is a cutout it needs to be set to a keepout
+ if( p.pour == EPOLYGON::CUTOUT )
+ {
+ zone->SetIsKeepout( true );
+ zone->SetDoNotAllowCopperPour( true );
+ zone->Outline()->SetHatchStyle( CPolyLine::NO_HATCH );
+ }
+
+ // if spacing is set the zone should be hatched
+ if( p.spacing )
+ zone->Outline()->SetHatch( CPolyLine::DIAGONAL_EDGE,
+ *p.spacing,
+ true );
+
+ // clearances, etc.
+ zone->SetArcSegmentCount( 32 ); // @todo: should be a constructor default?
+ zone->SetMinThickness( kicad( p.width ) );
+
+ // FIXME: KiCad zones have very rounded corners compared to eagle.
+ // This means that isolation amounts that work well in eagle
+ // tend to make copper intrude in soldermask free areas around pads.
+ if( p.isolate )
+ {
+ zone->SetZoneClearance( kicad( *p.isolate ) );
+ }
+
+ // missing == yes per DTD.
+ bool thermals = !p.thermals || *p.thermals;
+ zone->SetPadConnection( thermals ? PAD_ZONE_CONN_THERMAL : PAD_ZONE_CONN_FULL );
+ if( thermals )
+ {
+ // FIXME: eagle calculates dimensions for thermal spokes
+ // based on what the zone is connecting to.
+ // (i.e. width of spoke is half of the smaller side of an smd pad)
+ // This is a basic workaround
+ zone->SetThermalReliefGap( kicad( p.width + 0.05 ) );
+ zone->SetThermalReliefCopperBridge( kicad( p.width + 0.05 ) );
+ }
+
+ int rank = p.rank ? *p.rank : p.max_priority;
+ zone->SetPriority( rank );
+ }
+
+ m_xpath->pop(); // "polygon"
+ }
+ }
+
+ if( zones.size() && !sawPad )
+ {
+ // KiCad does not support an unconnected zone with its own non-zero netcode,
+ // but only when assigned netcode = 0 w/o a name...
+ for( ZONES::iterator it = zones.begin(); it != zones.end(); ++it )
+ (*it)->SetNetCode( NETINFO_LIST::UNCONNECTED );
+
+ // therefore omit this signal/net.
+ }
+ else
+ netCode++;
+ }
+
+ m_xpath->pop(); // "signals.signal"
+}
+
+
+LAYER_ID EAGLE_PLUGIN::kicad_layer( int aEagleLayer ) const
+{
+ /* will assume this is a valid mapping for all eagle boards until I get paid more:
+
+ <layers>
+ <layer number="1" name="Top" color="4" fill="1" visible="yes" active="yes"/>
+ <layer number="2" name="Route2" color="1" fill="3" visible="no" active="no"/>
+ <layer number="3" name="Route3" color="4" fill="3" visible="no" active="no"/>
+ <layer number="4" name="Route4" color="1" fill="4" visible="no" active="no"/>
+ <layer number="5" name="Route5" color="4" fill="4" visible="no" active="no"/>
+ <layer number="6" name="Route6" color="1" fill="8" visible="no" active="no"/>
+ <layer number="7" name="Route7" color="4" fill="8" visible="no" active="no"/>
+ <layer number="8" name="Route8" color="1" fill="2" visible="no" active="no"/>
+ <layer number="9" name="Route9" color="4" fill="2" visible="no" active="no"/>
+ <layer number="10" name="Route10" color="1" fill="7" visible="no" active="no"/>
+ <layer number="11" name="Route11" color="4" fill="7" visible="no" active="no"/>
+ <layer number="12" name="Route12" color="1" fill="5" visible="no" active="no"/>
+ <layer number="13" name="Route13" color="4" fill="5" visible="no" active="no"/>
+ <layer number="14" name="Route14" color="1" fill="6" visible="no" active="no"/>
+ <layer number="15" name="Route15" color="4" fill="6" visible="no" active="no"/>
+ <layer number="16" name="Bottom" color="1" fill="1" visible="yes" active="yes"/>
+ <layer number="17" name="Pads" color="2" fill="1" visible="yes" active="yes"/>
+ <layer number="18" name="Vias" color="14" fill="1" visible="yes" active="yes"/>
+ <layer number="19" name="Unrouted" color="6" fill="1" visible="yes" active="yes"/>
+ <layer number="20" name="Dimension" color="15" fill="1" visible="yes" active="yes"/>
+ <layer number="21" name="tPlace" color="7" fill="1" visible="yes" active="yes"/>
+ <layer number="22" name="bPlace" color="7" fill="1" visible="yes" active="yes"/>
+ <layer number="23" name="tOrigins" color="15" fill="1" visible="yes" active="yes"/>
+ <layer number="24" name="bOrigins" color="15" fill="1" visible="yes" active="yes"/>
+ <layer number="25" name="tNames" color="7" fill="1" visible="yes" active="yes"/>
+ <layer number="26" name="bNames" color="7" fill="1" visible="yes" active="yes"/>
+ <layer number="27" name="tValues" color="7" fill="1" visible="no" active="yes"/>
+ <layer number="28" name="bValues" color="7" fill="1" visible="no" active="yes"/>
+ <layer number="29" name="tStop" color="2" fill="3" visible="no" active="yes"/>
+ <layer number="30" name="bStop" color="5" fill="6" visible="no" active="yes"/>
+ <layer number="31" name="tCream" color="7" fill="4" visible="no" active="yes"/>
+ <layer number="32" name="bCream" color="7" fill="5" visible="no" active="yes"/>
+ <layer number="33" name="tFinish" color="6" fill="3" visible="no" active="yes"/>
+ <layer number="34" name="bFinish" color="6" fill="6" visible="no" active="yes"/>
+ <layer number="35" name="tGlue" color="7" fill="4" visible="no" active="yes"/>
+ <layer number="36" name="bGlue" color="7" fill="5" visible="no" active="yes"/>
+ <layer number="37" name="tTest" color="7" fill="1" visible="no" active="yes"/>
+ <layer number="38" name="bTest" color="7" fill="1" visible="no" active="yes"/>
+ <layer number="39" name="tKeepout" color="4" fill="11" visible="no" active="yes"/>
+ <layer number="40" name="bKeepout" color="1" fill="11" visible="no" active="yes"/>
+ <layer number="41" name="tRestrict" color="4" fill="10" visible="no" active="yes"/>
+ <layer number="42" name="bRestrict" color="1" fill="10" visible="no" active="yes"/>
+ <layer number="43" name="vRestrict" color="2" fill="10" visible="no" active="yes"/>
+ <layer number="44" name="Drills" color="7" fill="1" visible="no" active="yes"/>
+ <layer number="45" name="Holes" color="7" fill="1" visible="no" active="yes"/>
+ <layer number="46" name="Milling" color="3" fill="1" visible="no" active="yes"/>
+ <layer number="47" name="Measures" color="7" fill="1" visible="no" active="yes"/>
+ <layer number="48" name="Document" color="7" fill="1" visible="no" active="yes"/>
+ <layer number="49" name="ReferenceLC" color="13" fill="1" visible="yes" active="yes"/>
+ <layer number="50" name="ReferenceLS" color="12" fill="1" visible="yes" active="yes"/>
+ <layer number="51" name="tDocu" color="7" fill="1" visible="yes" active="yes"/>
+ <layer number="52" name="bDocu" color="7" fill="1" visible="yes" active="yes"/>
+
+ * These layers are used only in eagle schematic.
+ * They should not be found in board files.
+ * They are listed for info only.
+ <layer number="91" name="Nets" color="2" fill="1" visible="no" active="no"/>
+ <layer number="92" name="Busses" color="1" fill="1" visible="no" active="no"/>
+ <layer number="93" name="Pins" color="2" fill="1" visible="no" active="no"/>
+ <layer number="94" name="Symbols" color="4" fill="1" visible="no" active="no"/>
+ <layer number="95" name="Names" color="7" fill="1" visible="no" active="no"/>
+ <layer number="96" name="Values" color="7" fill="1" visible="no" active="no"/>
+ <layer number="97" name="Info" color="7" fill="1" visible="no" active="no"/>
+ <layer number="98" name="Guide" color="6" fill="1" visible="no" active="no"/>
+
+ * These layers are user layers
+ <layer number="160" name="???" color="7" fill="1" visible="yes" active="yes"/>
+ <layer number="161" name="???" color="7" fill="1" visible="yes" active="yes"/>
+
+ </layers>
+
+ */
+
+ int kiLayer;
+
+ // eagle copper layer:
+ if( aEagleLayer >= 1 && aEagleLayer < int( DIM( m_cu_map ) ) )
+ {
+ kiLayer = m_cu_map[aEagleLayer];
+ }
+
+ else
+ {
+ // translate non-copper eagle layer to pcbnew layer
+ switch( aEagleLayer )
+ {
+ case 20: kiLayer = Edge_Cuts; break; // eagle says "Dimension" layer, but it's for board perimeter
+ case 21: kiLayer = F_SilkS; break;
+ case 22: kiLayer = B_SilkS; break;
+ case 25: kiLayer = F_SilkS; break;
+ case 26: kiLayer = B_SilkS; break;
+ case 27: kiLayer = F_SilkS; break;
+ case 28: kiLayer = B_SilkS; break;
+ case 29: kiLayer = F_Mask; break;
+ case 30: kiLayer = B_Mask; break;
+ case 31: kiLayer = F_Paste; break;
+ case 32: kiLayer = B_Paste; break;
+ case 33: kiLayer = F_Mask; break;
+ case 34: kiLayer = B_Mask; break;
+ case 35: kiLayer = F_Adhes; break;
+ case 36: kiLayer = B_Adhes; break;
+ case 49: kiLayer = Cmts_User; break;
+ case 50: kiLayer = Cmts_User; break;
+
+ // Packages show the future chip pins on SMD parts using layer 51.
+ // This is an area slightly smaller than the PAD/SMD copper area.
+ // Carry those visual aids into the MODULE on the drawing layer, not silkscreen.
+ case 51: kiLayer = Dwgs_User; break;
+ case 52: kiLayer = Dwgs_User; break;
+
+ // thes layers are defined as user layers. put them on ECO layers
+ case 160: kiLayer = Eco1_User; break;
+ case 161: kiLayer = Eco2_User; break;
+ default:
+ // some layers do not map to KiCad
+ // DBG( printf( "unsupported eagle layer: %d\n", aEagleLayer );)
+ kiLayer = UNDEFINED_LAYER; break;
+ }
+ }
+
+ return LAYER_ID( kiLayer );
+}
+
+
+void EAGLE_PLUGIN::centerBoard()
+{
+ if( m_props )
+ {
+ UTF8 page_width;
+ UTF8 page_height;
+
+ if( m_props->Value( "page_width", &page_width ) &&
+ m_props->Value( "page_height", &page_height ) )
+ {
+ EDA_RECT bbbox = m_board->ComputeBoundingBox( true );
+
+ int w = atoi( page_width.c_str() );
+ int h = atoi( page_height.c_str() );
+
+ int desired_x = ( w - bbbox.GetWidth() ) / 2;
+ int desired_y = ( h - bbbox.GetHeight() ) / 2;
+
+ DBG(printf( "bbox.width:%d bbox.height:%d w:%d h:%d desired_x:%d desired_y:%d\n",
+ bbbox.GetWidth(), bbbox.GetHeight(), w, h, desired_x, desired_y );)
+
+ m_board->Move( wxPoint( desired_x - bbbox.GetX(), desired_y - bbbox.GetY() ) );
+ }
+ }
+}
+
+
+wxDateTime EAGLE_PLUGIN::getModificationTime( const wxString& aPath )
+{
+ wxFileName fn( aPath );
+
+ // Do not call wxFileName::GetModificationTime() on a non-existent file, because
+ // if it fails, wx's implementation calls the crap wxLogSysError() which
+ // eventually infects our UI with an unwanted popup window, so don't let it fail.
+ if( !fn.IsFileReadable() )
+ {
+ wxString msg = wxString::Format(
+ _( "File '%s' is not readable." ),
+ GetChars( aPath ) );
+
+ THROW_IO_ERROR( msg );
+ }
+
+ /*
+ // update the writable flag while we have a wxFileName, in a network this
+ // is possibly quite dynamic anyway.
+ m_writable = fn.IsFileWritable();
+ */
+
+ wxDateTime modTime = fn.GetModificationTime();
+
+ if( !modTime.IsValid() )
+ modTime.Now();
+
+ return modTime;
+}
+
+
+void EAGLE_PLUGIN::cacheLib( const wxString& aLibPath )
+{
+ try
+ {
+ wxDateTime modtime = getModificationTime( aLibPath );
+
+ // Fixes assertions in wxWidgets debug builds for the wxDateTime object. Refresh the
+ // cache if either of the wxDateTime objects are invalid or the last file modification
+ // time differs from the current file modification time.
+ bool load = !m_mod_time.IsValid() || !modtime.IsValid() ||
+ m_mod_time != modtime;
+
+ if( aLibPath != m_lib_path || load )
+ {
+ PTREE doc;
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ m_templates.clear();
+
+ // Set this before completion of loading, since we rely on it for
+ // text of an exception. Delay setting m_mod_time until after successful load
+ // however.
+ m_lib_path = aLibPath;
+
+ // 8 bit "filename" should be encoded according to disk filename encoding,
+ // (maybe this is current locale, maybe not, its a filesystem issue),
+ // and is not necessarily utf8.
+ string filename = (const char*) aLibPath.char_str( wxConvFile );
+
+ read_xml( filename, doc, xml_parser::no_comments );
+
+ // clear the cu map and then rebuild it.
+ clear_cu_map();
+
+ m_xpath->push( "eagle.drawing.layers" );
+ CPTREE& layers = doc.get_child( "eagle.drawing.layers" );
+ loadLayerDefs( layers );
+ m_xpath->pop();
+
+ m_xpath->push( "eagle.drawing.library" );
+ CPTREE& library = doc.get_child( "eagle.drawing.library" );
+ loadLibrary( library, NULL );
+ m_xpath->pop();
+
+ m_mod_time = modtime;
+ }
+ }
+ catch( file_parser_error fpe )
+ {
+ // for xml_parser_error, what() has the line number in it,
+ // but no byte offset. That should be an adequate error message.
+ THROW_IO_ERROR( fpe.what() );
+ }
+
+ // Class ptree_error is a base class for xml_parser_error & file_parser_error,
+ // so one catch should be OK for all errors.
+ catch( ptree_error pte )
+ {
+ string errmsg = pte.what();
+
+ errmsg += " @\n";
+ errmsg += m_xpath->Contents();
+
+ THROW_IO_ERROR( errmsg );
+ }
+}
+
+
+wxArrayString EAGLE_PLUGIN::FootprintEnumerate( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ init( aProperties );
+
+ cacheLib( aLibraryPath );
+
+ wxArrayString ret;
+
+ for( MODULE_CITER it = m_templates.begin(); it != m_templates.end(); ++it )
+ ret.Add( FROM_UTF8( it->first.c_str() ) );
+
+ return ret;
+}
+
+
+MODULE* EAGLE_PLUGIN::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties )
+{
+ init( aProperties );
+
+ cacheLib( aLibraryPath );
+
+ string key = TO_UTF8( aFootprintName );
+
+ MODULE_CITER mi = m_templates.find( key );
+
+ if( mi == m_templates.end() )
+ return NULL;
+
+ // copy constructor to clone the template
+ MODULE* ret = new MODULE( *mi->second );
+
+ return ret;
+}
+
+
+void EAGLE_PLUGIN::FootprintLibOptions( PROPERTIES* aListToAppendTo ) const
+{
+ PLUGIN::FootprintLibOptions( aListToAppendTo );
+
+ /*
+ (*aListToAppendTo)["ignore_duplicates"] = UTF8( _(
+ "Ignore duplicately named footprints within the same Eagle library. "
+ "Only the first similarly named footprint will be loaded."
+ ));
+ */
+}
+
+
+/*
+void EAGLE_PLUGIN::Save( const wxString& aFileName, BOARD* aBoard, const PROPERTIES* aProperties )
+{
+ // Eagle lovers apply here.
+}
+
+
+void EAGLE_PLUGIN::FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint, const PROPERTIES* aProperties )
+{
+}
+
+
+void EAGLE_PLUGIN::FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName )
+{
+}
+
+
+void EAGLE_PLUGIN::FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+}
+
+
+bool EAGLE_PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+}
+
+
+bool EAGLE_PLUGIN::IsFootprintLibWritable( const wxString& aLibraryPath )
+{
+ return true;
+}
+
+*/
diff --git a/pcbnew/eagle_plugin.h b/pcbnew/eagle_plugin.h
new file mode 100644
index 0000000..d12738f
--- /dev/null
+++ b/pcbnew/eagle_plugin.h
@@ -0,0 +1,231 @@
+#ifndef EAGLE_PLUGIN_H_
+#define EAGLE_PLUGIN_H_
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <io_mgr.h>
+#include <layers_id_colors_and_visibility.h>
+
+
+// forward declaration on ptree template so we can confine use of big boost
+// headers to only the implementation *.cpp file.
+
+#include <boost/property_tree/ptree_fwd.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+#include <map>
+
+
+class MODULE;
+typedef boost::ptr_map< std::string, MODULE > MODULE_MAP;
+
+
+struct ENET
+{
+ int netcode;
+ std::string netname;
+
+ ENET( int aNetCode, const std::string& aNetName ) :
+ netcode( aNetCode ),
+ netname( aNetName )
+ {}
+
+ ENET() :
+ netcode( 0 )
+ {}
+};
+
+typedef std::map< std::string, ENET > NET_MAP;
+typedef NET_MAP::const_iterator NET_MAP_CITER;
+
+typedef boost::property_tree::ptree PTREE;
+typedef const PTREE CPTREE;
+
+struct EELEMENT;
+class XPATH;
+struct ERULES;
+struct EATTR;
+class TEXTE_MODULE;
+
+
+/**
+ * Class EAGLE_PLUGIN
+ * works with Eagle 6.x XML board files and footprints to implement the
+ * Pcbnew PLUGIN API, or a portion of it.
+ */
+class EAGLE_PLUGIN : public PLUGIN
+{
+public:
+
+ //-----<PUBLIC PLUGIN API>--------------------------------------------------
+ const wxString PluginName() const;
+
+ BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties = NULL );
+
+ const wxString GetFileExtension() const;
+
+ wxArrayString FootprintEnumerate( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL);
+
+ MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties = NULL );
+
+ bool IsFootprintLibWritable( const wxString& aLibraryPath )
+ {
+ return false; // until someone writes others like FootprintSave(), etc.
+ }
+
+ void FootprintLibOptions( PROPERTIES* aProperties ) const;
+
+/*
+ void Save( const wxString& aFileName, BOARD* aBoard, const PROPERTIES* aProperties = NULL );
+
+ void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint, const PROPERTIES* aProperties = NULL );
+
+ void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName, const PROPERTIES* aProperties = NULL );
+
+ void FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL );
+
+ bool FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL );
+*/
+
+ //-----</PUBLIC PLUGIN API>-------------------------------------------------
+
+ typedef int BIU;
+
+ EAGLE_PLUGIN();
+ ~EAGLE_PLUGIN();
+
+private:
+
+ int m_cu_map[17]; ///< map eagle to kicad, cu layers only.
+
+ ERULES* m_rules; ///< Eagle design rules.
+ XPATH* m_xpath; ///< keeps track of what we are working on within
+ ///< XML document during a Load().
+
+ int m_hole_count; ///< generates unique module names from eagle "hole"s.
+
+ NET_MAP m_pads_to_nets; ///< net list
+
+ MODULE_MAP m_templates; ///< is part of a MODULE factory that operates
+ ///< using copy construction.
+ ///< lookup key is either libname.packagename or simply
+ ///< packagename if FootprintLoad() or FootprintEnumberate()
+
+ const PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL.
+ BOARD* m_board; ///< which BOARD is being worked on, no ownership here
+
+ int m_min_trace; ///< smallest trace we find on Load(), in BIU.
+ int m_min_via; ///< smallest via we find on Load(), in BIU.
+ int m_min_via_hole; ///< smallest via diameter hole we find on Load(), in BIU.
+
+ double mm_per_biu; ///< how many mm in each BIU
+ double biu_per_mm; ///< how many bius in a mm
+
+ wxString m_lib_path;
+ wxDateTime m_mod_time;
+
+ /// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
+ void init( const PROPERTIES* aProperties );
+
+ void clear_cu_map();
+
+ /// Convert an Eagle distance to a KiCad distance.
+ int kicad( double d ) const;
+ int kicad_y( double y ) const { return -kicad( y ); }
+ int kicad_x( double x ) const { return kicad( x ); }
+
+ /// create a font size (fontz) from an eagle font size scalar
+ wxSize kicad_fontz( double d ) const;
+
+ /// Convert an Eagle layer to a KiCad layer.
+ LAYER_ID kicad_layer( int aLayer ) const;
+
+ /// Convert a KiCad distance to an Eagle distance.
+ double eagle( BIU d ) const { return mm_per_biu * d; }
+ double eagle_x( BIU x ) const { return eagle( x ); }
+ double eagle_y( BIU y ) const { return eagle( y ); }
+
+ /// This PLUGIN only caches one footprint library, this determines which one.
+ void cacheLib( const wxString& aLibraryPath );
+
+ /// get a file's or dir's modification time.
+ static wxDateTime getModificationTime( const wxString& aPath );
+
+ // all these loadXXX() throw IO_ERROR or ptree_error exceptions:
+
+ void loadAllSections( CPTREE& aDocument );
+ void loadDesignRules( CPTREE& aDesignRules );
+ void loadLayerDefs( CPTREE& aLayers );
+ void loadPlain( CPTREE& aPlain );
+ void loadSignals( CPTREE& aSignals );
+
+ /**
+ * Function loadLibrary
+ * loads the Eagle "library" XML element, which can occur either under
+ * a "libraries" element (if a *.brd file) or under a "drawing" element if a
+ * *.lbr file.
+ * @param aLib is the portion of the loaded XML document tree that is the "library"
+ * element.
+ * @param aLibName is a pointer to the library name or NULL. If NULL this means
+ * we are loading a *.lbr not a *.brd file and the key used in m_templates is to exclude
+ * the library name.
+ */
+ void loadLibrary( CPTREE& aLib, const std::string* aLibName );
+
+ void loadLibraries( CPTREE& aLibs );
+ void loadElements( CPTREE& aElements );
+
+ void orientModuleAndText( MODULE* m, const EELEMENT& e, const EATTR* nameAttr, const EATTR* valueAttr );
+ void orientModuleText( MODULE* m, const EELEMENT& e, TEXTE_MODULE* txt, const EATTR* a );
+
+
+ /// move the BOARD into the center of the page
+ void centerBoard();
+
+ /**
+ * Function fmtDEG
+ * formats an angle in a way particular to a board file format. This function
+ * is the opposite or complement of degParse(). One has to know what the
+ * other is doing.
+ */
+ std::string fmtDEG( double aAngle ) const;
+
+ /**
+ * Function makeModule
+ * creates a MODULE from an Eagle package.
+ */
+ MODULE* makeModule( CPTREE& aPackage, const std::string& aPkgName ) const;
+
+ void packageWire( MODULE* aModule, CPTREE& aTree ) const;
+ void packagePad( MODULE* aModule, CPTREE& aTree ) const;
+ void packageText( MODULE* aModule, CPTREE& aTree ) const;
+ void packageRectangle( MODULE* aModule, CPTREE& aTree ) const;
+ void packagePolygon( MODULE* aModule, CPTREE& aTree ) const;
+ void packageCircle( MODULE* aModule, CPTREE& aTree ) const;
+ void packageHole( MODULE* aModule, CPTREE& aTree ) const;
+ void packageSMD( MODULE* aModule, CPTREE& aTree ) const;
+};
+
+#endif // EAGLE_PLUGIN_H_
diff --git a/pcbnew/edgemod.cpp b/pcbnew/edgemod.cpp
new file mode 100644
index 0000000..5dc01b5
--- /dev/null
+++ b/pcbnew/edgemod.cpp
@@ -0,0 +1,436 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file edgemod.cpp:
+ * @brief Functions to edit graphic items used to draw footprint edges.
+ *
+ * @todo - Arc functions not compete but menus are ready to use.
+ */
+
+#include <fctsys.h>
+#include <trigo.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <base_units.h>
+
+#include <module_editor_frame.h>
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+
+#include <pcbnew.h>
+
+
+static void ShowNewEdgeModule( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool erase );
+static void Abort_Move_ModuleOutline( EDA_DRAW_PANEL* Panel, wxDC* DC );
+static void ShowCurrentOutlineWhileMoving( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase );
+
+static double ArcValue = 900;
+static wxPoint MoveVector; // Move vector for move edge
+static wxPoint CursorInitialPosition; // Mouse cursor initial position for move command
+
+
+void FOOTPRINT_EDIT_FRAME::Start_Move_EdgeMod( EDGE_MODULE* aEdge, wxDC* DC )
+{
+ if( aEdge == NULL )
+ return;
+
+ aEdge->Draw( m_canvas, DC, GR_XOR );
+ aEdge->SetFlags( IS_MOVED );
+ MoveVector.x = MoveVector.y = 0;
+ CursorInitialPosition = GetCrossHairPosition();
+ m_canvas->SetMouseCapture( ShowCurrentOutlineWhileMoving, Abort_Move_ModuleOutline );
+ SetCurItem( aEdge );
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::Place_EdgeMod( EDGE_MODULE* aEdge )
+{
+ if( aEdge == NULL )
+ return;
+
+ aEdge->SetStart( aEdge->GetStart() - MoveVector );
+ aEdge->SetEnd( aEdge->GetEnd() - MoveVector );
+
+ aEdge->SetStart0( aEdge->GetStart0() - MoveVector );
+ aEdge->SetEnd0( aEdge->GetEnd0() - MoveVector );
+
+ aEdge->ClearFlags();
+ m_canvas->SetMouseCapture( NULL, NULL );
+ SetCurItem( NULL );
+ OnModify();
+
+ MODULE* module = (MODULE*) aEdge->GetParent();
+ module->CalculateBoundingBox();
+
+ m_canvas->Refresh( );
+}
+
+
+/* Redraw the current moved graphic item when mouse is moving
+ * Use this function to show an existing outline, in move command
+*/
+static void ShowCurrentOutlineWhileMoving( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase )
+{
+ BASE_SCREEN* screen = aPanel->GetScreen();
+ EDGE_MODULE* edge = (EDGE_MODULE*) screen->GetCurItem();
+
+ if( edge == NULL )
+ return;
+
+ MODULE* module = (MODULE*) edge->GetParent();
+
+ if( aErase )
+ {
+ edge->Draw( aPanel, aDC, GR_XOR, MoveVector );
+ }
+
+ MoveVector = -(aPanel->GetParent()->GetCrossHairPosition() - CursorInitialPosition);
+
+ edge->Draw( aPanel, aDC, GR_XOR, MoveVector );
+
+ module->CalculateBoundingBox();
+}
+
+
+/* Redraw the current graphic item during its creation
+ * Use this function to show a new outline, in begin command
+ */
+static void ShowNewEdgeModule( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ BASE_SCREEN* screen = aPanel->GetScreen();
+ EDGE_MODULE* edge = (EDGE_MODULE*) screen->GetCurItem();
+
+ if( edge == NULL )
+ return;
+
+ MODULE* module = (MODULE*) edge->GetParent();
+
+ // if( erase )
+ {
+ edge->Draw( aPanel, aDC, GR_XOR );
+ }
+
+ edge->SetEnd( aPanel->GetParent()->GetCrossHairPosition() );
+
+ // Update relative coordinate.
+ edge->SetEnd0( edge->GetEnd() - module->GetPosition() );
+
+ wxPoint pt( edge->GetEnd0() );
+
+ RotatePoint( &pt, -module->GetOrientation() );
+
+ edge->SetEnd0( pt );
+
+ edge->Draw( aPanel, aDC, GR_XOR );
+
+ module->CalculateBoundingBox();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::Edit_Edge_Width( EDGE_MODULE* aEdge )
+{
+ MODULE* module = GetBoard()->m_Modules;
+
+ SaveCopyInUndoList( module, UR_MODEDIT );
+
+ if( aEdge == NULL )
+ {
+ aEdge = (EDGE_MODULE*) (BOARD_ITEM*) module->GraphicalItems();
+
+ for( BOARD_ITEM *item = module->GraphicalItems(); item; item = item->Next() )
+ {
+ aEdge = dyn_cast<EDGE_MODULE*>( item );
+
+ if( aEdge )
+ aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth );
+ }
+ }
+ else
+ {
+ aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth );
+ }
+
+ OnModify();
+ module->CalculateBoundingBox();
+ module->SetLastEditTime();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::Edit_Edge_Layer( EDGE_MODULE* aEdge )
+{
+ // note: if aEdge == NULL, all outline segments will be modified
+
+ MODULE* module = GetBoard()->m_Modules;
+ LAYER_ID layer = F_SilkS;
+ bool modified = false;
+
+ if( aEdge )
+ layer = aEdge->GetLayer();
+
+ // Ask for the new layer
+ LAYER_ID new_layer = SelectLayer( layer, Edge_Cuts );
+
+ if( layer < 0 )
+ return;
+
+ if( IsCopperLayer( new_layer ) )
+ {
+ // an edge is put on a copper layer, and it is very dangerous.
+ // A confirmation is requested
+ if( !IsOK( this,
+ _( "The graphic item will be on a copper layer.\n"
+ "This is very dangerous. Are you sure?" ) ) )
+ return;
+ }
+
+ if( !aEdge )
+ {
+ for( BOARD_ITEM *item = module->GraphicalItems() ; item != NULL;
+ item = item->Next() )
+ {
+ aEdge = dyn_cast<EDGE_MODULE*>( item );
+
+ if( aEdge && (aEdge->GetLayer() != new_layer) )
+ {
+ if( ! modified ) // save only once
+ SaveCopyInUndoList( module, UR_MODEDIT );
+ aEdge->SetLayer( new_layer );
+ modified = true;
+ }
+ }
+ }
+ else if( aEdge->GetLayer() != new_layer )
+ {
+ SaveCopyInUndoList( module, UR_MODEDIT );
+ aEdge->SetLayer( new_layer );
+ modified = true;
+ }
+
+ if( modified )
+ {
+ module->CalculateBoundingBox();
+ module->SetLastEditTime();
+ }
+}
+
+
+void FOOTPRINT_EDIT_FRAME::Enter_Edge_Width( EDGE_MODULE* aEdge )
+{
+ wxString buffer;
+
+ buffer = StringFromValue( g_UserUnit, GetDesignSettings().m_ModuleSegmentWidth );
+ wxTextEntryDialog dlg( this, _( "New Width:" ), _( "Edge Width" ), buffer );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return; // canceled by user
+
+ buffer = dlg.GetValue( );
+ GetDesignSettings().m_ModuleSegmentWidth = ValueFromString( g_UserUnit, buffer );
+
+ if( aEdge )
+ {
+ MODULE* module = GetBoard()->m_Modules;
+ aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth );
+ module->CalculateBoundingBox();
+ OnModify();
+ }
+}
+
+
+void FOOTPRINT_EDIT_FRAME::Delete_Edge_Module( EDGE_MODULE* aEdge )
+{
+ if( aEdge == NULL )
+ return;
+
+ if( aEdge->Type() != PCB_MODULE_EDGE_T )
+ {
+ DisplayError( this, wxT( "StructType error: PCB_MODULE_EDGE_T expected" ) );
+ return;
+ }
+
+ MODULE* module = (MODULE*) aEdge->GetParent();
+
+ // Delete segment.
+ aEdge->DeleteStructure();
+ module->SetLastEditTime();
+ module->CalculateBoundingBox();
+ OnModify();
+}
+
+
+/* abort function in moving outline.
+ */
+static void Abort_Move_ModuleOutline( EDA_DRAW_PANEL* Panel, wxDC* DC )
+{
+ EDGE_MODULE* edge = (EDGE_MODULE*) Panel->GetScreen()->GetCurItem();
+
+ Panel->SetMouseCapture( NULL, NULL );
+
+ if( edge && ( edge->Type() == PCB_MODULE_EDGE_T ) )
+ {
+ if( edge->IsNew() ) // On aborting, delete new outline.
+ {
+ MODULE* module = (MODULE*) edge->GetParent();
+ edge->Draw( Panel, DC, GR_XOR, MoveVector );
+ edge->DeleteStructure();
+ module->CalculateBoundingBox();
+ }
+ else // On aborting, move existing outline to its initial position.
+ {
+ edge->Draw( Panel, DC, GR_XOR, MoveVector );
+ edge->ClearFlags();
+ edge->Draw( Panel, DC, GR_OR );
+ }
+ }
+
+ Panel->GetScreen()->SetCurItem( NULL );
+}
+
+
+EDGE_MODULE* FOOTPRINT_EDIT_FRAME::Begin_Edge_Module( EDGE_MODULE* aEdge,
+ wxDC* DC,
+ STROKE_T type_edge )
+{
+ MODULE* module = GetBoard()->m_Modules;
+
+ if( module == NULL )
+ return NULL;
+
+ if( aEdge == NULL ) // Start a new edge item
+ {
+ SaveCopyInUndoList( module, UR_MODEDIT );
+
+ aEdge = new EDGE_MODULE( module );
+ MoveVector.x = MoveVector.y = 0;
+
+ // Add the new item to the Drawings list head
+ module->GraphicalItems().PushFront( aEdge );
+
+ // Update characteristics of the segment or arc.
+ aEdge->SetFlags( IS_NEW );
+ aEdge->SetAngle( 0 );
+ aEdge->SetShape( type_edge );
+
+ if( aEdge->GetShape() == S_ARC )
+ aEdge->SetAngle( ArcValue );
+
+ aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth );
+ aEdge->SetLayer( GetActiveLayer() );
+
+ // Initialize the starting point of the new segment or arc
+ aEdge->SetStart( GetCrossHairPosition() );
+
+ // Initialize the ending point of the new segment or arc
+ aEdge->SetEnd( aEdge->GetStart() );
+
+ // Initialize the relative coordinates
+ aEdge->SetStart0( aEdge->GetStart() - module->GetPosition() );
+
+ RotatePoint( &aEdge->m_Start0, -module->GetOrientation() );
+
+ aEdge->m_End0 = aEdge->m_Start0;
+ module->CalculateBoundingBox();
+ m_canvas->SetMouseCapture( ShowNewEdgeModule, Abort_Move_ModuleOutline );
+ }
+ /* Segment creation in progress.
+ * The ending coordinate is updated by the function
+ * ShowNewEdgeModule() called on move mouse event
+ * during the segment creation
+ */
+ else
+ {
+ if( type_edge == S_SEGMENT )
+ {
+ if( aEdge->m_Start0 != aEdge->m_End0 )
+ {
+ aEdge->Draw( m_canvas, DC, GR_OR );
+
+ EDGE_MODULE* newedge = new EDGE_MODULE( *aEdge );
+
+ // insert _after_ aEdge, which is the same as inserting before aEdge->Next()
+ module->GraphicalItems().Insert( newedge, aEdge->Next() );
+ aEdge->ClearFlags();
+
+ aEdge = newedge; // point now new item
+
+ aEdge->SetFlags( IS_NEW );
+ aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth );
+ aEdge->SetStart( GetCrossHairPosition() );
+ aEdge->SetEnd( aEdge->GetStart() );
+
+ // Update relative coordinate.
+ aEdge->SetStart0( aEdge->GetStart() - module->GetPosition() );
+
+ wxPoint pt( aEdge->GetStart0() );
+
+ RotatePoint( &pt, -module->GetOrientation() );
+
+ aEdge->SetStart0( pt );
+
+ aEdge->SetEnd0( aEdge->GetStart0() );
+
+ module->CalculateBoundingBox();
+ module->SetLastEditTime();
+ OnModify();
+ }
+ }
+ else
+ {
+ wxMessageBox( wxT( "Begin_Edge() error" ) );
+ }
+ }
+
+ return aEdge;
+}
+
+
+void FOOTPRINT_EDIT_FRAME::End_Edge_Module( EDGE_MODULE* aEdge )
+{
+ MODULE* module = GetBoard()->m_Modules;
+
+ if( aEdge )
+ {
+ aEdge->ClearFlags();
+
+ // If last segment length is 0: remove it
+ if( aEdge->GetStart() == aEdge->GetEnd() )
+ aEdge->DeleteStructure();
+ }
+
+ module->CalculateBoundingBox();
+ module->SetLastEditTime();
+ OnModify();
+ m_canvas->SetMouseCapture( NULL, NULL );
+}
diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp
new file mode 100644
index 0000000..c764c17
--- /dev/null
+++ b/pcbnew/edit.cpp
@@ -0,0 +1,1685 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file edit.cpp
+ * @brief Edit PCB implementation.
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <eda_doc.h>
+#include <gestfich.h>
+#include <kicad_device_context.h>
+#include <wxPcbStruct.h>
+
+#include <pcbnew_id.h>
+#include <pcbnew.h>
+#include <module_editor_frame.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_zone.h>
+#include <class_pcb_text.h>
+#include <modview_frame.h>
+#include <class_pcb_layer_box_selector.h>
+#include <dialog_drc.h>
+#include <dialog_global_edit_tracks_and_vias.h>
+#include <invoke_pcb_dialog.h>
+
+#include <dialog_move_exact.h>
+#include <dialog_create_array.h>
+
+#include <tool/tool_manager.h>
+#include <tools/common_actions.h>
+
+// Handles the selection of command events.
+void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
+{
+ int id = event.GetId();
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+ MODULE* module;
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ m_canvas->CrossHairOff( &dc );
+
+ switch( id ) // Some (not all ) edit commands must be finished or aborted
+ {
+ case wxID_CUT:
+ case wxID_COPY:
+ case ID_PCB_USER_GRID_SETUP:
+ case ID_TOOLBARH_PCB_SELECT_LAYER:
+ case ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR:
+ case ID_POPUP_PCB_ROTATE_TEXTEPCB:
+ case ID_POPUP_PCB_FLIP_TEXTEPCB:
+ case ID_POPUP_PCB_COPY_TEXTEPCB:
+ case ID_POPUP_PCB_EDIT_TEXTEPCB:
+ case ID_POPUP_PCB_EDIT_MIRE:
+ case ID_POPUP_PCB_ROTATE_TEXTMODULE:
+ case ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE:
+ case ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE:
+ case ID_POPUP_PCB_CHANGE_SIDE_MODULE:
+ case ID_POPUP_PCB_EDIT_MODULE_PRMS:
+ case ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT:
+ case ID_POPUP_PCB_EDIT_TEXTMODULE:
+ case ID_POPUP_PCB_STOP_CURRENT_DRAWING:
+ case ID_POPUP_PCB_BEGIN_TRACK:
+ case ID_POPUP_PCB_END_TRACK:
+ case ID_POPUP_PCB_PLACE_THROUGH_VIA:
+ case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA:
+ case ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA:
+ case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA:
+ case ID_POPUP_PCB_PLACE_MICROVIA:
+ case ID_POPUP_PCB_SWITCH_TRACK_POSTURE:
+ case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
+ case ID_POPUP_PCB_EXPORT_PAD_SETTINGS:
+ case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS:
+ case ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE:
+ case ID_POPUP_PCB_DELETE_ZONE_LAST_CREATED_CORNER:
+ case ID_POPUP_PCB_FILL_ALL_ZONES:
+ case ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES:
+ case ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_CURRENT_ZONE:
+ case ID_POPUP_PCB_PLACE_ZONE_CORNER:
+ case ID_POPUP_PCB_PLACE_ZONE_OUTLINES:
+ case ID_POPUP_PCB_EDIT_ZONE_PARAMS:
+ case ID_POPUP_PCB_DELETE_ZONE:
+ case ID_POPUP_PCB_DELETE_ZONE_CORNER:
+ case ID_POPUP_PCB_MOVE_ZONE_CORNER:
+ case ID_POPUP_PCB_DRAG_ZONE_OUTLINE_SEGMENT:
+ case ID_POPUP_PCB_PLACE_DRAGGED_ZONE_OUTLINE_SEGMENT:
+ case ID_POPUP_PCB_MOVE_ZONE_OUTLINES:
+ case ID_POPUP_PCB_ADD_ZONE_CORNER:
+ case ID_POPUP_PCB_DELETE_TRACKSEG:
+ case ID_POPUP_PCB_DELETE_TRACK:
+ case ID_POPUP_PCB_DELETE_TRACKNET:
+ case ID_POPUP_PCB_FILL_ZONE:
+ case ID_POPUP_PCB_SELECT_LAYER:
+ case ID_POPUP_PCB_SELECT_CU_LAYER:
+ case ID_POPUP_PCB_SELECT_LAYER_PAIR:
+ case ID_POPUP_PCB_SELECT_NO_CU_LAYER:
+ case ID_POPUP_PCB_MOVE_TRACK_NODE:
+ case ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST:
+ case ID_POPUP_PCB_DRAG_TRACK_SEGMENT_KEEP_SLOPE:
+ case ID_POPUP_PCB_DRAG_TRACK_SEGMENT:
+ case ID_POPUP_PCB_MOVE_TRACK_SEGMENT:
+ case ID_POPUP_PCB_PLACE_MOVED_TRACK_NODE:
+ case ID_POPUP_PCB_BREAK_TRACK:
+ case ID_POPUP_PCB_EDIT_NET:
+ case ID_POPUP_PCB_EDIT_TRACK:
+ case ID_POPUP_PCB_EDIT_TRACKSEG:
+ case ID_POPUP_PCB_LOCK_ON_TRACKSEG:
+ case ID_POPUP_PCB_LOCK_OFF_TRACKSEG:
+ case ID_POPUP_PCB_LOCK_ON_TRACK:
+ case ID_POPUP_PCB_LOCK_OFF_TRACK:
+ case ID_POPUP_PCB_LOCK_ON_NET:
+ case ID_POPUP_PCB_LOCK_OFF_NET:
+ case ID_POPUP_DELETE_BLOCK:
+ case ID_POPUP_PLACE_BLOCK:
+ case ID_POPUP_ZOOM_BLOCK:
+ case ID_POPUP_FLIP_BLOCK:
+ case ID_POPUP_ROTATE_BLOCK:
+ case ID_POPUP_COPY_BLOCK:
+ case ID_POPUP_PCB_EDIT_DRAWING:
+ case ID_POPUP_PCB_GETINFO_MARKER:
+ case ID_POPUP_PCB_MOVE_TEXT_DIMENSION_REQUEST:
+ case ID_POPUP_PCB_DRAG_MODULE_REQUEST:
+ case ID_POPUP_PCB_MOVE_MODULE_REQUEST:
+ case ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST:
+ case ID_POPUP_PCB_MOVE_MIRE_REQUEST:
+ break;
+
+ case ID_POPUP_CANCEL_CURRENT_COMMAND:
+ if( m_canvas->IsMouseCaptured() )
+ {
+ m_canvas->EndMouseCapture();
+ }
+
+ // Should not be executed, just in case
+ if( GetScreen()->m_BlockLocate.GetCommand() != BLOCK_IDLE )
+ {
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_IDLE );
+ GetScreen()->m_BlockLocate.SetState( STATE_NO_BLOCK );
+ GetScreen()->m_BlockLocate.ClearItemsList();
+ }
+
+ if( GetToolId() == ID_NO_TOOL_SELECTED )
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ else
+ SetCursor( (wxStockCursor) m_canvas->GetDefaultCursor() );
+
+ break;
+
+ default: // Finish (abort) the command
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallEndMouseCapture( &dc );
+
+ if( GetToolId() != id )
+ {
+ if( m_lastDrawToolId != GetToolId() )
+ m_lastDrawToolId = GetToolId();
+
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ }
+
+ if( TOOL_MANAGER* toolMgr = GetToolManager() )
+ toolMgr->DeactivateTool();
+
+ break;
+ }
+
+ switch( id ) // Execute command
+ {
+ case 0:
+ break;
+
+ case ID_OPEN_MODULE_EDITOR:
+ {
+ FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, false );
+
+ if( !editor )
+ {
+ editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
+ editor->Zoom_Automatique( false );
+ }
+ else
+ {
+ // Needed on Windows, other platforms do not use it,
+ // but it creates no issue
+ if( editor->IsIconized() )
+ editor->Iconize( false );
+
+ editor->Raise();
+
+ // Raising the window does not set the focus on Linux. This should work on
+ // any platform.
+ if( wxWindow::FindFocus() != editor )
+ editor->SetFocus();
+ }
+
+ editor->PushPreferences( m_canvas );
+ }
+ break;
+
+ case ID_OPEN_MODULE_VIEWER:
+ {
+ FOOTPRINT_VIEWER_FRAME* viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, false );
+
+ if( !viewer )
+ {
+ viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, true );
+ viewer->Zoom_Automatique( false );
+ }
+ else
+ {
+ // Needed on Windows, other platforms do not use it,
+ // but it creates no issue
+ if( viewer->IsIconized() )
+ viewer->Iconize( false );
+
+ viewer->Raise();
+
+ // Raising the window does not set the focus on Linux. This should work on
+ // any platform.
+ if( wxWindow::FindFocus() != viewer )
+ viewer->SetFocus();
+ }
+
+ viewer->PushPreferences( m_canvas );
+ }
+ break;
+
+ case ID_PCB_GLOBAL_DELETE:
+ InstallPcbGlobalDeleteFrame( wxDefaultPosition );
+ break;
+
+ case ID_POPUP_PLACE_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE );
+ m_canvas->SetAutoPanRequest( false );
+ HandleBlockPlace( &dc );
+ break;
+
+ case ID_POPUP_COPY_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_COPY );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ m_canvas->SetAutoPanRequest( false );
+ HandleBlockPlace( &dc );
+ break;
+
+ case ID_POPUP_ZOOM_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_ZOOM );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_DELETE_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_DELETE );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_ROTATE_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_ROTATE );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_FLIP_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_FLIP );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_DRC_CONTROL:
+ m_drc->ShowDialog();
+ break;
+
+ case ID_GET_NETLIST:
+ InstallNetlistFrame( &dc );
+ break;
+
+ case ID_FIND_ITEMS:
+ InstallFindFrame();
+ break;
+
+ case ID_POPUP_CLOSE_CURRENT_TOOL:
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ break;
+
+ case ID_POPUP_CANCEL_CURRENT_COMMAND:
+ break;
+
+ case ID_POPUP_PCB_END_LINE:
+ m_canvas->MoveCursorToCrossHair();
+
+ // EndSegment(&dc);
+ break;
+
+ case ID_POPUP_PCB_EDIT_TRACK:
+ if( GetCurItem() == NULL )
+ break;
+ Edit_Track_Width( &dc, (TRACK*) GetCurItem() );
+ m_canvas->MoveCursorToCrossHair();
+ OnModify();
+ break;
+
+ case ID_POPUP_PCB_EDIT_TRACKSEG:
+ if( GetCurItem() == NULL )
+ break;
+ Edit_TrackSegm_Width( &dc, (TRACK*) GetCurItem() );
+ m_canvas->MoveCursorToCrossHair();
+ OnModify();
+ break;
+
+ case ID_POPUP_PCB_EDIT_ALL_VIAS_AND_TRACK_SIZE:
+ if( GetCurItem() == NULL )
+ break;
+ {
+ int type = GetCurItem()->Type();
+
+ if( type == PCB_TRACE_T || type == PCB_VIA_T )
+ {
+ BOARD_CONNECTED_ITEM*item = (BOARD_CONNECTED_ITEM*) GetCurItem();
+ DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS dlg( this, item->GetNetCode() );
+ dlg.ShowModal();
+ }
+
+ }
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_BEGIN_TRACK:
+ m_canvas->MoveCursorToCrossHair();
+ OnHotkeyBeginRoute( &dc );
+ break;
+
+ case ID_POPUP_PCB_END_TRACK:
+ m_canvas->MoveCursorToCrossHair();
+ End_Route( (TRACK*) GetCurItem(), &dc );
+ break;
+
+ case ID_POPUP_PCB_PLACE_MOVED_TRACK_NODE:
+ m_canvas->MoveCursorToCrossHair();
+
+ if( GetCurItem()->IsDragging() )
+ {
+ PlaceDraggedOrMovedTrackSegment( (TRACK*) GetCurItem(), &dc );
+ }
+
+ break;
+
+ case ID_POPUP_PCB_SWITCH_TRACK_POSTURE:
+ /* change the position of initial segment when creating new tracks
+ * switch from _/ to -\ .
+ * If a track is in progress, it will be redrawn
+ */
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( &dc, wxDefaultPosition, false );
+
+ g_Alternate_Track_Posture = !g_Alternate_Track_Posture;
+
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( &dc, wxDefaultPosition, false );
+
+ break;
+
+ case ID_POPUP_PCB_PLACE_MICROVIA:
+ if( !IsMicroViaAcceptable() )
+ break;
+ // fall through
+ case ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA:
+ case ID_POPUP_PCB_PLACE_THROUGH_VIA:
+ case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA:
+ case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA:
+ m_canvas->MoveCursorToCrossHair();
+
+ if( GetCurItem()->IsDragging() )
+ {
+ PlaceDraggedOrMovedTrackSegment( (TRACK*) GetCurItem(), &dc );
+ }
+ else
+ {
+ BOARD_DESIGN_SETTINGS &settings = GetDesignSettings();
+ VIATYPE_T v_type = settings.m_CurrentViaType;
+ switch( id )
+ {
+ case ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA:
+ case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA:
+ settings.m_CurrentViaType = VIA_BLIND_BURIED;
+ break;
+
+ case ID_POPUP_PCB_PLACE_MICROVIA:
+ settings.m_CurrentViaType = VIA_MICROVIA;
+ break;
+
+ default:
+ settings.m_CurrentViaType = VIA_THROUGH;
+ break;
+ }
+
+ // place via and switch layer.
+ if( id == ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA ||
+ id == ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA )
+ {
+ m_canvas->SetIgnoreMouseEvents( true );
+
+ wxPoint dlgPosition;
+
+ wxGetMousePosition( &dlgPosition.x, &dlgPosition.y );
+
+ LAYER_ID layer = SelectLayer( GetActiveLayer(), LSET::AllNonCuMask(), dlgPosition );
+
+ m_canvas->SetIgnoreMouseEvents( false );
+ m_canvas->MoveCursorToCrossHair();
+
+ if( GetActiveLayer() != layer )
+ {
+ GetScreen()->m_Route_Layer_TOP = GetActiveLayer();
+ GetScreen()->m_Route_Layer_BOTTOM = layer;
+ Other_Layer_Route( (TRACK*) GetCurItem(), &dc );
+ }
+ }
+
+ else
+ Other_Layer_Route( (TRACK*) GetCurItem(), &dc );
+
+ settings.m_CurrentViaType = v_type;
+
+ if( displ_opts->m_ContrastModeDisplay )
+ m_canvas->Refresh();
+ }
+ break;
+
+ case ID_POPUP_PCB_DELETE_TRACKSEG:
+ if( GetCurItem() == NULL )
+ break;
+
+ m_canvas->MoveCursorToCrossHair();
+ SetCurItem( Delete_Segment( &dc, (TRACK*) GetCurItem() ) );
+ OnModify();
+ break;
+
+ case ID_POPUP_PCB_DELETE_TRACK:
+ if( GetCurItem() == NULL )
+ break;
+ m_canvas->MoveCursorToCrossHair();
+ Delete_Track( &dc, (TRACK*) GetCurItem() );
+ SetCurItem( NULL );
+ OnModify();
+ break;
+
+ case ID_POPUP_PCB_DELETE_TRACKNET:
+ m_canvas->MoveCursorToCrossHair();
+ Delete_net( &dc, (TRACK*) GetCurItem() );
+ SetCurItem( NULL );
+ OnModify();
+ break;
+
+ case ID_POPUP_PCB_LOCK_ON_TRACKSEG:
+ Attribut_Segment( (TRACK*) GetCurItem(), &dc, true );
+ break;
+
+ case ID_POPUP_PCB_LOCK_OFF_TRACKSEG:
+ Attribut_Segment( (TRACK*) GetCurItem(), &dc, false );
+ break;
+
+ case ID_POPUP_PCB_LOCK_ON_TRACK:
+ Attribut_Track( (TRACK*) GetCurItem(), &dc, true );
+ break;
+
+ case ID_POPUP_PCB_LOCK_OFF_TRACK:
+ Attribut_Track( (TRACK*) GetCurItem(), &dc, false );
+ break;
+
+ case ID_POPUP_PCB_LOCK_ON_NET:
+ Attribut_net( &dc, ( (TRACK*) GetCurItem() )->GetNetCode(), true );
+ break;
+
+ case ID_POPUP_PCB_LOCK_OFF_NET:
+ Attribut_net( &dc, ( (TRACK*) GetCurItem() )->GetNetCode(), false );
+ break;
+
+ case ID_POPUP_PCB_SETFLAGS_TRACK_MNU:
+ break;
+
+ case ID_POPUP_PCB_DELETE_ZONE:
+ m_canvas->MoveCursorToCrossHair();
+
+ if( GetCurItem() == NULL )
+ break;
+
+ {
+ SEGZONE* zsegm = (SEGZONE*) GetCurItem();
+ int netcode = zsegm->GetNetCode();
+ Delete_OldZone_Fill( zsegm );
+ SetCurItem( NULL );
+ TestNetConnection( NULL, netcode );
+ OnModify();
+ SetMsgPanel( GetBoard() );
+ }
+ break;
+
+ case ID_POPUP_PCB_EDIT_ZONE_PARAMS:
+ Edit_Zone_Params( &dc, (ZONE_CONTAINER*) GetCurItem() );
+ SetCurItem( NULL ); // Outlines can have changed
+ break;
+
+ case ID_POPUP_PCB_ZONE_DUPLICATE:
+ {
+ ZONE_CONTAINER* zone = (ZONE_CONTAINER*) GetCurItem();
+ duplicateZone( &dc, zone );
+ }
+ break;
+
+ case ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE:
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetAutoPanRequest( true );
+ Add_Similar_Zone( &dc, (ZONE_CONTAINER*) GetCurItem() );
+ break;
+
+ case ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE:
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetAutoPanRequest( true );
+ Add_Zone_Cutout( &dc, (ZONE_CONTAINER*) GetCurItem() );
+ break;
+
+ case ID_POPUP_PCB_DELETE_ZONE_CONTAINER:
+ // Force the main contour selection, to remove the entire zone:
+ ((ZONE_CONTAINER*) GetCurItem())->SetSelectedCorner( 0 );
+ // Fall through
+ case ID_POPUP_PCB_DELETE_ZONE_CUTOUT:
+ m_canvas->MoveCursorToCrossHair();
+ {
+ int netcode = ( (ZONE_CONTAINER*) GetCurItem() )->GetNetCode();
+ Delete_Zone_Contour( &dc, (ZONE_CONTAINER*) GetCurItem() );
+ SetCurItem( NULL );
+ TestNetConnection( NULL, netcode );
+ SetMsgPanel( GetBoard() );
+ }
+ break;
+
+ case ID_POPUP_PCB_DELETE_ZONE_CORNER:
+ Remove_Zone_Corner( &dc, (ZONE_CONTAINER*) GetCurItem() );
+ SetCurItem( NULL );
+ break;
+
+ case ID_POPUP_PCB_MOVE_ZONE_CORNER:
+ {
+ m_canvas->MoveCursorToCrossHair();
+ ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem();
+ m_canvas->SetAutoPanRequest( true );
+ Start_Move_Zone_Corner( &dc, zone_cont, zone_cont->GetSelectedCorner(), false );
+ }
+ break;
+
+ case ID_POPUP_PCB_DRAG_ZONE_OUTLINE_SEGMENT:
+ {
+ m_canvas->MoveCursorToCrossHair();
+ ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem();
+ m_canvas->SetAutoPanRequest( true );
+ Start_Move_Zone_Drag_Outline_Edge( &dc, zone_cont, zone_cont->GetSelectedCorner() );
+ }
+ break;
+
+ case ID_POPUP_PCB_MOVE_ZONE_OUTLINES:
+ {
+ m_canvas->MoveCursorToCrossHair();
+ ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem();
+ m_canvas->SetAutoPanRequest( true );
+ Start_Move_Zone_Outlines( &dc, zone_cont );
+ }
+ break;
+
+ case ID_POPUP_PCB_ADD_ZONE_CORNER:
+ {
+ m_canvas->MoveCursorToCrossHair();
+ ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem();
+ wxPoint pos = GetCrossHairPosition();
+
+ /* add corner between zone_cont->m_CornerSelection
+ * and zone_cont->m_CornerSelection+1
+ * and start move the new corner
+ */
+ zone_cont->Draw( m_canvas, &dc, GR_XOR );
+ zone_cont->Outline()->InsertCorner( zone_cont->GetSelectedCorner(), pos.x, pos.y );
+ zone_cont->SetSelectedCorner( zone_cont->GetSelectedCorner() + 1 );
+ zone_cont->Draw( m_canvas, &dc, GR_XOR );
+ m_canvas->SetAutoPanRequest( true );
+ Start_Move_Zone_Corner( &dc, zone_cont, zone_cont->GetSelectedCorner(), true );
+ }
+ break;
+
+ case ID_POPUP_PCB_PLACE_ZONE_OUTLINES:
+ case ID_POPUP_PCB_PLACE_ZONE_CORNER:
+ case ID_POPUP_PCB_PLACE_DRAGGED_ZONE_OUTLINE_SEGMENT:
+ {
+ m_canvas->MoveCursorToCrossHair();
+ ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem();
+ End_Move_Zone_Corner_Or_Outlines( &dc, zone_cont );
+ m_canvas->SetAutoPanRequest( false );
+ }
+ break;
+
+ case ID_POPUP_PCB_FILL_ALL_ZONES:
+ m_canvas->MoveCursorToCrossHair();
+ Fill_All_Zones( this );
+ m_canvas->Refresh();
+ SetMsgPanel( GetBoard() );
+ break;
+
+ case ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_CURRENT_ZONE:
+ if( ( GetCurItem() )->Type() == PCB_ZONE_AREA_T )
+ {
+ ZONE_CONTAINER* zone_container = (ZONE_CONTAINER*) GetCurItem();
+ zone_container->UnFill();
+ TestNetConnection( NULL, zone_container->GetNetCode() );
+ OnModify();
+ SetMsgPanel( GetBoard() );
+ m_canvas->Refresh();
+ }
+ SetCurItem( NULL );
+ break;
+
+ case ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES: // Remove all zones :
+ GetBoard()->m_Zone.DeleteAll(); // remove zone segments used to fill zones.
+
+ for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
+ {
+ // Remove filled areas in zone
+ ZONE_CONTAINER* zone_container = GetBoard()->GetArea( ii );
+ zone_container->UnFill();
+ }
+
+ SetCurItem( NULL ); // CurItem might be deleted by this command, clear the pointer
+ TestConnections();
+ TestForActiveLinksInRatsnest( 0 ); // Recalculate the active ratsnest, i.e. the unconnected links
+ OnModify();
+ SetMsgPanel( GetBoard() );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_PCB_FILL_ZONE:
+ m_canvas->MoveCursorToCrossHair();
+ Fill_Zone( (ZONE_CONTAINER*) GetCurItem() );
+ TestNetConnection( NULL, ( (ZONE_CONTAINER*) GetCurItem() )->GetNetCode() );
+ SetMsgPanel( GetBoard() );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST:
+ StartMoveTextePcb( (TEXTE_PCB*) GetCurItem(), &dc );
+ m_canvas->SetAutoPanRequest( true );
+ break;
+
+ case ID_POPUP_PCB_DRAG_MODULE_REQUEST:
+ case ID_POPUP_PCB_MOVE_MODULE_REQUEST:
+ if( GetCurItem() == NULL )
+ break;
+
+ // If the current Item is a pad, text module ...: Get its parent
+ if( GetCurItem()->Type() != PCB_MODULE_T )
+ SetCurItem( GetCurItem()->GetParent() );
+
+ if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T )
+ break;
+
+ module = (MODULE*) GetCurItem();
+
+ if( module->IsLocked() )
+ {
+ wxString msg;
+ msg.Printf( _( "Footprint %s found, but it is locked" ),
+ module->GetReference().GetData() );
+ DisplayInfoMessage( this, msg );
+ break;
+ }
+
+ SendMessageToEESCHEMA( module );
+ SetCrossHairPosition( module->GetPosition() );
+ m_canvas->MoveCursorToCrossHair();
+ StartMoveModule( module, &dc, id == ID_POPUP_PCB_DRAG_MODULE_REQUEST );
+ break;
+
+ case ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST: // get module by name and move it
+ SetCurItem( GetModuleByName() );
+ module = (MODULE*) GetCurItem();
+
+ if( module == NULL )
+ break;
+
+ if( module->IsLocked() )
+ {
+ wxString msg = wxString::Format(
+ _( "Footprint %s found, but it is locked" ),
+ module->GetReference().GetData() );
+ DisplayInfoMessage( this, msg );
+ break;
+ }
+
+ SendMessageToEESCHEMA( module );
+ m_canvas->MoveCursorToCrossHair();
+ StartMoveModule( module, &dc, false );
+ break;
+
+ case ID_POPUP_PCB_DELETE_MODULE:
+ m_canvas->MoveCursorToCrossHair();
+
+ // If the current Item is a pad, text module ...: Get its parent
+ if( GetCurItem()->Type() != PCB_MODULE_T )
+ SetCurItem( GetCurItem()->GetParent() );
+
+ if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T )
+ break;
+
+ module = (MODULE*) GetCurItem();
+
+ if( module->IsLocked() )
+ {
+ wxString msg;
+ msg.Printf( _( "Footprint %s found, but it is locked" ),
+ module->GetReference().GetData() );
+ DisplayInfoMessage( this, msg );
+ break;
+ }
+
+ if( Delete_Module( (MODULE*) GetCurItem(), &dc ) )
+ {
+ SetCurItem( NULL );
+ }
+
+ break;
+
+ case ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE:
+ m_canvas->MoveCursorToCrossHair();
+
+ // If the current Item is a pad, text module ...: Get its parent
+ if( GetCurItem()->Type() != PCB_MODULE_T )
+ SetCurItem( GetCurItem()->GetParent() );
+
+ if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T )
+ break;
+
+ module = (MODULE*) GetCurItem();
+
+ if( module->IsLocked() )
+ {
+ wxString msg;
+ msg.Printf( _( "Footprint %s found, but it is locked" ),
+ module->GetReference().GetData() );
+ DisplayInfoMessage( this, msg );
+ break;
+ }
+
+ // This is a simple rotation, no other editing in progress
+ if( !GetCurItem()->IsMoving() )
+ SaveCopyInUndoList( GetCurItem(), UR_CHANGED, ((MODULE*)GetCurItem())->GetPosition() );
+
+ Rotate_Module( &dc, (MODULE*) GetCurItem(), m_rotationAngle, true );
+ break;
+
+ case ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE:
+ m_canvas->MoveCursorToCrossHair();
+
+ // If the current Item is a pad, text module ...: Get its parent
+ if( GetCurItem()->Type() != PCB_MODULE_T )
+ SetCurItem( GetCurItem()->GetParent() );
+
+ if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T )
+ break;
+
+ module = (MODULE*) GetCurItem();
+
+ if( module->IsLocked() )
+ {
+ wxString msg;
+ msg.Printf( _( "Footprint %s found, but it is locked" ),
+ module->GetReference().GetData() );
+ DisplayInfoMessage( this, msg );
+ break;
+ }
+
+ // This is a simple rotation, no other editing in progress
+ if( !GetCurItem()->IsMoving() )
+ SaveCopyInUndoList( GetCurItem(), UR_CHANGED, ((MODULE*)GetCurItem())->GetPosition() );
+
+ Rotate_Module( &dc, (MODULE*) GetCurItem(), -m_rotationAngle, true );
+ break;
+
+ case ID_POPUP_PCB_CHANGE_SIDE_MODULE:
+ m_canvas->MoveCursorToCrossHair();
+
+ // If the current Item is a pad, text module ...: Get its parent
+ if( GetCurItem()->Type() != PCB_MODULE_T )
+ SetCurItem( GetCurItem()->GetParent() );
+
+ if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T )
+ break;
+
+ module = (MODULE*) GetCurItem();
+
+ if( module->IsLocked() )
+ {
+ wxString msg;
+ msg.Printf( _( "Footprint %s found, but it is locked" ),
+ module->GetReference().GetData() );
+ DisplayInfoMessage( this, msg );
+ break;
+ }
+
+ // This is a simple flip, no other editing in progress
+ if( !GetCurItem()->IsMoving() )
+ SaveCopyInUndoList( GetCurItem(), UR_FLIPPED, ((MODULE*)GetCurItem())->GetPosition() );
+
+ Change_Side_Module( (MODULE*) GetCurItem(), &dc );
+ break;
+
+ case ID_POPUP_PCB_EXCHANGE_FOOTPRINTS:
+ if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T )
+ break;
+
+ InstallExchangeModuleFrame( (MODULE*) GetCurItem() );
+ // Warning: the current item can be deleted by exchange module
+ SetCurItem( NULL );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_EDIT_MODULE_PRMS:
+ // If the current Item is a pad, text module ...: Get its parent
+ if( GetCurItem()->Type() != PCB_MODULE_T )
+ SetCurItem( GetCurItem()->GetParent() );
+
+ if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T )
+ break;
+
+ InstallModuleOptionsFrame( (MODULE*) GetCurItem(), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT:
+
+ // If we don't have a current item, there's nothing we can do here
+ if( !GetCurItem() )
+ break;
+
+ // If the current Item is a pad, text module ...: Get its parent
+ if( GetCurItem()->Type() != PCB_MODULE_T )
+ SetCurItem( GetCurItem()->GetParent() );
+
+ if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T )
+ break;
+
+ if( GetCurItem()->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
+ {
+ GetCurItem()->SetTimeStamp( GetNewTimeStamp() );
+ OnModify();
+ }
+
+ {
+ FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
+
+ editor->Load_Module_From_BOARD( (MODULE*)GetCurItem() );
+ SetCurItem( NULL ); // the current module could be deleted by
+ }
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_DRAG_PAD_REQUEST:
+ module = (MODULE*) GetCurItem()->GetParent();
+
+ if( !module || module->Type() != PCB_MODULE_T )
+ break;
+
+ if( module->IsLocked() )
+ {
+ wxString msg;
+ msg.Printf( _( "The parent (%s) of the pad is locked" ),
+ module->GetReference().GetData() );
+ DisplayInfoMessage( this, msg );
+ break;
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+ StartMovePad( (D_PAD*) GetCurItem(), &dc, true );
+ break;
+
+ case ID_POPUP_PCB_MOVE_PAD_REQUEST:
+ module = (MODULE*) GetCurItem()->GetParent();
+
+ if( !module || module->Type() != PCB_MODULE_T )
+ break;
+
+ if( module->IsLocked() )
+ {
+ wxString msg;
+ msg.Printf( _( "The parent (%s) of the pad is locked" ),
+ module->GetReference().GetData() );
+ DisplayInfoMessage( this, msg );
+ break;
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+ StartMovePad( (D_PAD*) GetCurItem(), &dc, false );
+ break;
+
+ case ID_POPUP_PCB_EDIT_PAD:
+ InstallPadOptionsFrame( (D_PAD*) GetCurItem() );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
+ m_canvas->MoveCursorToCrossHair();
+ SaveCopyInUndoList( GetCurItem()->GetParent(), UR_CHANGED );
+ Import_Pad_Settings( (D_PAD*) GetCurItem(), true );
+ break;
+
+ case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS:
+ m_canvas->MoveCursorToCrossHair();
+ DlgGlobalChange_PadSettings( (D_PAD*) GetCurItem(), true );
+ break;
+
+ case ID_POPUP_PCB_EXPORT_PAD_SETTINGS:
+ m_canvas->MoveCursorToCrossHair();
+ Export_Pad_Settings( (D_PAD*) GetCurItem() );
+ break;
+
+ case ID_POPUP_PCB_DELETE_PAD:
+ SaveCopyInUndoList( GetCurItem()->GetParent(), UR_CHANGED );
+ DeletePad( (D_PAD*) GetCurItem() );
+ SetCurItem( NULL );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_EDIT_TEXTMODULE:
+ InstallTextModOptionsFrame( static_cast<TEXTE_MODULE*>( GetCurItem() ), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_RESET_TEXT_SIZE:
+ ResetTextSize( GetCurItem(), &dc );
+ break;
+
+ case ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST:
+ m_canvas->MoveCursorToCrossHair();
+ StartMoveTexteModule( static_cast<TEXTE_MODULE*>( GetCurItem() ), &dc );
+ break;
+
+ case ID_POPUP_PCB_ROTATE_TEXTMODULE:
+ RotateTextModule( static_cast<TEXTE_MODULE*>( GetCurItem() ), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_DELETE_TEXTMODULE:
+ DeleteTextModule( static_cast<TEXTE_MODULE*>( GetCurItem() ) );
+ SetCurItem( NULL );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_SELECT_LAYER:
+ {
+ LAYER_ID itmp = SelectLayer( GetActiveLayer() );
+
+ if( itmp >= 0 )
+ {
+ // if user changed colors and we are in high contrast mode, then redraw
+ // because the PAD_ATTRIB_SMD pads may change color.
+ if( displ_opts->m_ContrastModeDisplay && GetActiveLayer() != itmp )
+ {
+ m_canvas->Refresh();
+ }
+ SetActiveLayer( itmp );
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+ }
+ break;
+
+ case ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR:
+ SelectCopperLayerPair();
+ break;
+
+ case ID_POPUP_PCB_SELECT_NO_CU_LAYER:
+ {
+ LAYER_ID itmp = SelectLayer( GetActiveLayer(), LSET::AllCuMask() );
+
+ if( itmp >= 0 )
+ SetActiveLayer( itmp );
+
+ m_canvas->MoveCursorToCrossHair();
+ }
+ break;
+
+ case ID_POPUP_PCB_SELECT_CU_LAYER:
+ {
+ LAYER_ID itmp = SelectLayer( GetActiveLayer(), LSET::AllNonCuMask() );
+
+ if( itmp >= 0 )
+ SetActiveLayer( itmp );
+ }
+ break;
+
+ case ID_POPUP_PCB_SELECT_LAYER_PAIR:
+ SelectCopperLayerPair();
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_TOOLBARH_PCB_SELECT_LAYER:
+ SetActiveLayer( ToLAYER_ID( m_SelLayerBox->GetLayerSelection() ) );
+
+ if( displ_opts->m_ContrastModeDisplay )
+ m_canvas->Refresh( true );
+ break;
+
+ case ID_POPUP_PCB_EDIT_TEXTEPCB:
+ InstallTextPCBOptionsFrame( (TEXTE_PCB*) GetCurItem(), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_ROTATE_TEXTEPCB:
+ Rotate_Texte_Pcb( (TEXTE_PCB*) GetCurItem(), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_COPY_TEXTEPCB:
+ CreateTextePcb( &dc, (TEXTE_PCB*) GetCurItem() );
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetAutoPanRequest( true );
+ break;
+
+ case ID_POPUP_PCB_FLIP_TEXTEPCB:
+ FlipTextePcb( (TEXTE_PCB*) GetCurItem(), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_DELETE_TEXTEPCB:
+ Delete_Texte_Pcb( (TEXTE_PCB*) GetCurItem(), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_MOVE_MIRE_REQUEST:
+ BeginMoveTarget( (PCB_TARGET*) GetCurItem(), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_EDIT_MIRE:
+ ShowTargetOptionsDialog( (PCB_TARGET*) GetCurItem(), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_DELETE_MIRE:
+ m_canvas->MoveCursorToCrossHair();
+ DeleteTarget( (PCB_TARGET*) GetCurItem(), &dc );
+ SetCurItem( NULL );
+ break;
+
+ case ID_POPUP_PCB_DELETE_DIMENSION:
+ m_canvas->MoveCursorToCrossHair();
+ DeleteDimension( (DIMENSION*) GetCurItem(), &dc );
+ SetCurItem( NULL );
+ break;
+
+ case ID_POPUP_PCB_EDIT_DIMENSION:
+ ShowDimensionPropertyDialog( (DIMENSION*) GetCurItem(), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_MOVE_TEXT_DIMENSION_REQUEST:
+ BeginMoveDimensionText( (DIMENSION*) GetCurItem(), &dc );
+ break;
+
+ case ID_POPUP_PCB_DELETE_DRAWING:
+ Delete_Segment_Edge( (DRAWSEGMENT*) GetCurItem(), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_DELETE_MARKER:
+ RemoveStruct( GetCurItem(), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_GETINFO_MARKER:
+ if( GetCurItem() && GetCurItem()->Type() == PCB_MARKER_T )
+ ( (MARKER_PCB*) GetCurItem() )->DisplayMarkerInfo( this );
+
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_DELETE_DRAWING_LAYER:
+ if( GetCurItem()->GetFlags() != 0 )
+ break;
+
+ Delete_Drawings_All_Layer( GetCurItem()->GetLayer() );
+ SetCurItem( NULL );
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_PCB_EDIT_DRAWING:
+#ifndef USE_WX_OVERLAY
+ InstallGraphicItemPropertiesDialog( (DRAWSEGMENT*) GetCurItem(), &dc );
+#else
+ // #1277772 - Draw into dialog converted in refresh request
+ InstallGraphicItemPropertiesDialog( (DRAWSEGMENT*) GetCurItem(), NULL );
+ m_canvas->Refresh();
+#endif
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_MOVE_DRAWING_REQUEST:
+ m_canvas->MoveCursorToCrossHair();
+ Start_Move_DrawItem( (DRAWSEGMENT*) GetCurItem(), &dc );
+ break;
+
+ case ID_POPUP_PCB_STOP_CURRENT_DRAWING:
+ m_canvas->MoveCursorToCrossHair();
+
+ if( GetCurItem() && (GetCurItem()->IsNew()) )
+ {
+ End_Edge( (DRAWSEGMENT*) GetCurItem(), &dc );
+ SetCurItem( NULL );
+ }
+
+ break;
+
+ case ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE:
+ m_canvas->MoveCursorToCrossHair();
+
+ if( GetCurItem() && (GetCurItem()->IsNew()) )
+ {
+ if( End_Zone( &dc ) )
+ SetCurItem( NULL );
+ }
+
+ m_canvas->SetAutoPanRequest( false );
+ break;
+
+ case ID_POPUP_PCB_DELETE_ZONE_LAST_CREATED_CORNER:
+ m_canvas->MoveCursorToCrossHair();
+
+ if( GetCurItem() && (GetCurItem()->IsNew()) )
+ {
+ if( Delete_LastCreatedCorner( &dc ) == 0 ) // No more segment in outline,
+ SetCurItem( NULL );
+ }
+
+ break;
+
+
+ case ID_POPUP_PCB_MOVE_TRACK_SEGMENT:
+ m_canvas->MoveCursorToCrossHair();
+ StartMoveOneNodeOrSegment( (TRACK*) GetScreen()->GetCurItem(), &dc, id );
+ break;
+
+ case ID_POPUP_PCB_DRAG_TRACK_SEGMENT:
+ case ID_POPUP_PCB_MOVE_TRACK_NODE:
+ m_canvas->MoveCursorToCrossHair();
+ StartMoveOneNodeOrSegment( (TRACK*) GetScreen()->GetCurItem(), &dc, id );
+ break;
+
+ case ID_POPUP_PCB_DRAG_TRACK_SEGMENT_KEEP_SLOPE:
+ m_canvas->MoveCursorToCrossHair();
+ Start_DragTrackSegmentAndKeepSlope( (TRACK*) GetScreen()->GetCurItem(), &dc );
+ break;
+
+ case ID_POPUP_PCB_BREAK_TRACK:
+ m_canvas->MoveCursorToCrossHair();
+ {
+ TRACK* track = (TRACK*) GetScreen()->GetCurItem();
+ wxPoint pos = GetCrossHairPosition();
+
+ track->Draw( m_canvas, &dc, GR_XOR );
+ PICKED_ITEMS_LIST itemsListPicker;
+
+ TRACK* newtrack = GetBoard()->CreateLockPoint( pos, track, &itemsListPicker );
+
+ SaveCopyInUndoList( itemsListPicker, UR_UNSPECIFIED );
+ track->Draw( m_canvas, &dc, GR_XOR );
+ newtrack->Draw( m_canvas, &dc, GR_XOR );
+
+ // compute the new ratsnest, because connectivity could change
+ TestNetConnection( &dc, track->GetNetCode() );
+ }
+ break;
+
+ case ID_POPUP_PCB_MOVE_EXACT:
+ moveExact();
+ break;
+
+ case ID_POPUP_PCB_DUPLICATE_ITEM:
+ case ID_POPUP_PCB_DUPLICATE_ITEM_AND_INCREMENT:
+ duplicateItems( id == ID_POPUP_PCB_DUPLICATE_ITEM_AND_INCREMENT );
+ break;
+
+ case ID_POPUP_PCB_CREATE_ARRAY:
+ createArray();
+ break;
+
+ case ID_MENU_PCB_CLEAN:
+ Clean_Pcb();
+ break;
+
+ case ID_MENU_PCB_SWAP_LAYERS:
+ Swap_Layers( event );
+ break;
+
+ case ID_PCB_USER_GRID_SETUP:
+ InvokeDialogGrid();
+ break;
+
+ case ID_POPUP_PCB_DISPLAY_FOOTPRINT_DOC:
+ {
+ wxConfigBase* cfg = Pgm().CommonSettings();
+ cfg->Read( wxT( "module_doc_file" ), g_DocModulesFileName );
+ GetAssociatedDocument( this, g_DocModulesFileName, &Kiface().KifaceSearch() );
+ }
+ break;
+
+ case ID_MENU_ARCHIVE_MODULES_IN_LIBRARY:
+ ArchiveModulesOnBoard( false );
+ break;
+
+ case ID_MENU_CREATE_LIBRARY_AND_ARCHIVE_MODULES:
+ ArchiveModulesOnBoard( true );
+ break;
+
+ case ID_GEN_IMPORT_DXF_FILE:
+ InvokeDXFDialogBoardImport( this );
+ m_canvas->Refresh();
+ break;
+
+ default:
+ wxString msg;
+ msg.Printf( wxT( "PCB_EDIT_FRAME::Process_Special_Functions() unknown event id %d" ), id );
+ DisplayError( this, msg );
+ break;
+ }
+
+ m_canvas->CrossHairOn( &dc );
+ m_canvas->SetIgnoreMouseEvents( false );
+}
+
+
+void PCB_EDIT_FRAME::RemoveStruct( BOARD_ITEM* Item, wxDC* DC )
+{
+ if( Item == NULL )
+ return;
+
+ switch( Item->Type() )
+ {
+ case PCB_MODULE_T:
+ Delete_Module( (MODULE*) Item, DC );
+ break;
+
+ case PCB_DIMENSION_T:
+ DeleteDimension( (DIMENSION*) Item, DC );
+ break;
+
+ case PCB_TARGET_T:
+ DeleteTarget( (PCB_TARGET*) Item, DC );
+ break;
+
+ case PCB_LINE_T:
+ Delete_Segment_Edge( (DRAWSEGMENT*) Item, DC );
+ break;
+
+ case PCB_TEXT_T:
+ Delete_Texte_Pcb( (TEXTE_PCB*) Item, DC );
+ break;
+
+ case PCB_TRACE_T:
+ Delete_Track( DC, (TRACK*) Item );
+ break;
+
+ case PCB_VIA_T:
+ Delete_Segment( DC, (TRACK*) Item );
+ break;
+
+ case PCB_ZONE_T:
+ Delete_OldZone_Fill( (SEGZONE*) Item );
+ break;
+
+ case PCB_ZONE_AREA_T:
+ {
+ SetCurItem( NULL );
+ int netcode = ( (ZONE_CONTAINER*) Item )->GetNetCode();
+ Delete_Zone_Contour( DC, (ZONE_CONTAINER*) Item );
+ TestNetConnection( NULL, netcode );
+ SetMsgPanel( GetBoard() );
+ }
+ break;
+
+ case PCB_MARKER_T:
+ if( Item == GetCurItem() )
+ SetCurItem( NULL );
+
+ ( (MARKER_PCB*) Item )->Draw( m_canvas, DC, GR_XOR );
+
+ // delete the marker, and free memory. Don't use undo stack.
+ GetBoard()->Delete( Item );
+ break;
+
+ case PCB_PAD_T:
+ case PCB_MODULE_TEXT_T:
+ case PCB_MODULE_EDGE_T:
+ break;
+
+ case TYPE_NOT_INIT:
+ case PCB_T:
+ default:
+ {
+ wxString msg = wxString::Format(
+ wxT( "Remove: item type %d unknown." ), Item->Type() );
+ DisplayError( this, msg );
+ }
+ break;
+ }
+}
+
+
+void PCB_EDIT_FRAME::SwitchLayer( wxDC* DC, LAYER_ID layer )
+{
+ LAYER_ID curLayer = GetActiveLayer();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ // Check if the specified layer matches the present layer
+ if( layer == curLayer )
+ return;
+
+ // Copper layers cannot be selected unconditionally; how many
+ // of those layers are currently enabled needs to be checked.
+ if( IsCopperLayer( layer ) )
+ {
+ // If only one copper layer is enabled, the only such layer
+ // that can be selected to is the "Back" layer (so the
+ // selection of any other copper layer is disregarded).
+ if( GetBoard()->GetCopperLayerCount() < 2 )
+ {
+ if( layer != B_Cu )
+ return;
+ }
+ // If more than one copper layer is enabled, the "Copper"
+ // and "Component" layers can be selected, but the total
+ // number of copper layers determines which internal
+ // layers are also capable of being selected.
+ else
+ {
+ if( layer != B_Cu && layer != F_Cu && layer >= GetBoard()->GetCopperLayerCount() - 1 )
+ return;
+ }
+
+ EDA_ITEM* current = GetScreen()->GetCurItem();
+
+ // See if we are drawing a segment; if so, add a via?
+ if( GetToolId() == ID_TRACK_BUTT && current )
+ {
+ if( current->Type() == PCB_TRACE_T && current->IsNew() )
+ {
+ // Want to set the routing layers so that it switches properly -
+ // see the implementation of Other_Layer_Route - the working
+ // layer is used to 'start' the via and set the layer masks appropriately.
+ GetScreen()->m_Route_Layer_TOP = curLayer;
+ GetScreen()->m_Route_Layer_BOTTOM = layer;
+
+ SetActiveLayer( curLayer );
+
+ if( Other_Layer_Route( (TRACK*) GetScreen()->GetCurItem(), DC ) )
+ {
+ if( displ_opts->m_ContrastModeDisplay )
+ m_canvas->Refresh();
+ }
+
+ // if the via was allowed by DRC, then the layer swap has already
+ // been done by Other_Layer_Route(). if via not allowed, then
+ // return now so assignment to setActiveLayer() below doesn't happen.
+ return;
+ }
+ }
+ }
+
+ // Is yet more checking required? E.g. when the layer to be selected
+ // is a non-copper layer, or when switching between a copper layer
+ // and a non-copper layer, or vice-versa?
+ // ...
+
+ SetActiveLayer( layer );
+
+ if( displ_opts->m_ContrastModeDisplay )
+ m_canvas->Refresh();
+}
+
+
+void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent )
+{
+ int id = aEvent.GetId();
+
+ if( GetToolId() == id )
+ return;
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ // Stop the current command and deselect the current tool.
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+
+ switch( id )
+ {
+ case ID_NO_TOOL_SELECTED:
+ SetToolID( id, m_canvas->GetDefaultCursor(), wxEmptyString );
+ break;
+
+ case ID_TRACK_BUTT:
+ if( g_Drc_On )
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add tracks" ) );
+ else
+ SetToolID( id, wxCURSOR_QUESTION_ARROW, _( "Add tracks" ) );
+
+ if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
+ {
+ Compile_Ratsnest( &dc, true );
+ }
+
+ break;
+
+ case ID_PCB_MODULE_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add footprint" ) );
+ break;
+
+ case ID_PCB_ZONES_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add zones" ) );
+
+ if( displ_opts->m_DisplayZonesMode != 0 )
+ DisplayInfoMessage( this, _( "Warning: zone display is OFF!!!" ) );
+
+ if( !GetBoard()->IsHighLightNetON() && (GetBoard()->GetHighLightNetCode() > 0 ) )
+ HighLight( &dc );
+
+ break;
+
+ case ID_PCB_KEEPOUT_AREA_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add keepout" ) );
+ break;
+
+ case ID_PCB_MIRE_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add layer alignment target" ) );
+ break;
+
+ case ID_PCB_PLACE_OFFSET_COORD_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Adjust zero" ) );
+ break;
+
+ case ID_PCB_PLACE_GRID_COORD_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Adjust grid origin" ) );
+ break;
+
+ case ID_PCB_ADD_LINE_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic line" ) );
+ break;
+
+ case ID_PCB_ARC_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic arc" ) );
+ break;
+
+ case ID_PCB_CIRCLE_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic circle" ) );
+ break;
+
+ case ID_PCB_ADD_TEXT_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) );
+ break;
+
+ case ID_COMPONENT_BUTT:
+ SetToolID( id, wxCURSOR_HAND, _( "Add footprint" ) );
+ break;
+
+ case ID_PCB_DIMENSION_BUTT:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add dimension" ) );
+ break;
+
+ case ID_PCB_DELETE_ITEM_BUTT:
+ SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
+ break;
+
+ case ID_PCB_HIGHLIGHT_BUTT:
+ SetToolID( id, wxCURSOR_HAND, _( "Highlight net" ) );
+ break;
+
+ case ID_PCB_SHOW_1_RATSNEST_BUTT:
+ SetToolID( id, wxCURSOR_HAND, _( "Select rats nest" ) );
+
+ if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
+ Compile_Ratsnest( &dc, true );
+
+ break;
+ }
+}
+
+
+void PCB_EDIT_FRAME::moveExact()
+{
+ wxPoint translation;
+ double rotation = 0;
+
+ DIALOG_MOVE_EXACT dialog( this, translation, rotation );
+ int ret = dialog.ShowModal();
+
+ if( ret == wxID_OK )
+ {
+ if( BOARD_ITEM* item = GetScreen()->GetCurItem() )
+ {
+ // When a pad is modified, the full footprint is saved
+ BOARD_ITEM* itemToSave = item;
+
+ if( item->Type() == PCB_PAD_T )
+ itemToSave = item->GetParent();
+
+ // Could be moved or rotated
+ SaveCopyInUndoList( itemToSave, UR_CHANGED );
+
+ item->Move( translation );
+ item->Rotate( item->GetPosition(), rotation );
+ m_canvas->Refresh();
+ }
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+}
+
+void PCB_EDIT_FRAME::duplicateItems( bool aIncrement )
+{
+ BOARD_ITEM* item = GetScreen()->GetCurItem();
+
+ if( !item )
+ return;
+
+ // In the board editor, the pads or fp texts can be edited
+ // but cannot be duplicated (only the fp editor can do that).
+ // only the footprint can be duplicated
+ if( item->Type() == PCB_PAD_T || item->Type() == PCB_MODULE_TEXT_T )
+ item = static_cast<MODULE*>( item )->GetParent();
+
+ PCB_BASE_EDIT_FRAME::duplicateItem( item, aIncrement );
+}
+
+void PCB_BASE_EDIT_FRAME::duplicateItem( BOARD_ITEM* aItem, bool aIncrement )
+{
+ if( !aItem )
+ return;
+
+ // The easiest way to handle a duplicate item command
+ // is to simulate a block copy command, which gives us the undo management
+ // for free
+ if( GetScreen()->m_BlockLocate.GetState() == STATE_NO_BLOCK )
+ {
+ m_canvas->MoveCursorToCrossHair();
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ wxPoint crossHairPos = GetCrossHairPosition();
+
+ const BLOCK_COMMAND_T blockType = aIncrement ? BLOCK_COPY_AND_INCREMENT : BLOCK_COPY;
+
+ if( !HandleBlockBegin( &dc, blockType, crossHairPos ) )
+ return;
+
+ // Add the item to the block copy pick list:
+ PICKED_ITEMS_LIST& itemsList = GetScreen()->m_BlockLocate.GetItems();
+ ITEM_PICKER picker( NULL, UR_UNSPECIFIED );
+
+ picker.SetItem ( aItem );
+ itemsList.PushItem( picker );
+
+ // Set 2 coordinates updated by the mouse, because our simulation
+ // does not use the mouse to call HandleBlockEnd()
+ GetScreen()->m_BlockLocate.SetLastCursorPosition( crossHairPos );
+ GetScreen()->m_BlockLocate.SetEnd( crossHairPos );
+ HandleBlockEnd( &dc );
+ }
+}
+
+
+void PCB_BASE_EDIT_FRAME::createArray()
+{
+ BOARD_ITEM* item = GetScreen()->GetCurItem();
+
+ if( !item )
+ return;
+
+ // Note: original item is no more modified.
+
+ bool editingModule = NULL != dynamic_cast<FOOTPRINT_EDIT_FRAME*>( this );
+
+ BOARD* board = GetBoard();
+
+ // Remember this is valid and used only in the module editor.
+ // in board editor, the parent of items is usually the board.
+ MODULE* module = static_cast<MODULE*>( item->GetParent() );
+
+ DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* array_opts = NULL;
+
+ const wxPoint rotPoint = item->GetCenter();
+
+ DIALOG_CREATE_ARRAY dialog( this, rotPoint, &array_opts );
+ int ret = dialog.ShowModal();
+
+ if( ret == wxID_OK && array_opts != NULL )
+ {
+ PICKED_ITEMS_LIST newItemsList;
+
+ if( item->Type() == PCB_PAD_T && !editingModule )
+ {
+ // If it is not the module editor, then duplicate the parent module instead
+ item = static_cast<MODULE*>( item )->GetParent();
+ }
+
+ if( editingModule )
+ {
+ // modedit saves everything upfront
+ SaveCopyInUndoList( board->m_Modules, UR_MODEDIT );
+ }
+
+ #define INCREMENT_REF false
+ #define INCREMENT_PADNUMBER true
+
+ // The first item in list is the original item. We do not modify it
+ for( int ptN = 1; ptN < array_opts->GetArraySize(); ptN++ )
+ {
+ BOARD_ITEM* new_item;
+
+ if( editingModule )
+ new_item = module->DuplicateAndAddItem( item, INCREMENT_PADNUMBER );
+ else
+ new_item = board->DuplicateAndAddItem( item, INCREMENT_REF );
+
+ if( new_item )
+ {
+ array_opts->TransformItem( ptN, new_item, rotPoint );
+ newItemsList.PushItem( new_item ); // For undo list
+ }
+
+ if( !new_item || !array_opts->ShouldRenumberItems() )
+ continue;
+
+ // Renumber pads. Only new pad number renumbering has meaning,
+ // in the footprint editor.
+ if( new_item->Type() == PCB_PAD_T )
+ {
+ const wxString padName = array_opts->GetItemNumber( ptN );
+ static_cast<D_PAD*>( new_item )->SetPadName( padName );
+ }
+ }
+
+ if( !editingModule )
+ {
+ // pcbnew saves the new items like this
+ SaveCopyInUndoList( newItemsList, UR_NEW );
+ }
+
+ m_canvas->Refresh();
+ }
+}
diff --git a/pcbnew/edit_pcb_text.cpp b/pcbnew/edit_pcb_text.cpp
new file mode 100644
index 0000000..bae9b3a
--- /dev/null
+++ b/pcbnew/edit_pcb_text.cpp
@@ -0,0 +1,287 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file edit_pcb_text.cpp
+ * @brief Editing of text on copper and technical layers (TEXTE_PCB class)
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_pcb_text.h>
+#include <class_board_item.h>
+
+
+static void Move_Texte_Pcb( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase );
+static void Abort_Edit_Pcb_Text( EDA_DRAW_PANEL* Panel, wxDC* DC );
+
+
+static TEXTE_PCB s_TextCopy( (BOARD_ITEM*) NULL ); /* copy of the edited text
+ * (used to undo/redo/abort
+ * a complex edition command
+ */
+
+
+/*
+ * Abort current text edit progress.
+ * If a text is selected, its initial coord are regenerated
+ */
+void Abort_Edit_Pcb_Text( EDA_DRAW_PANEL* Panel, wxDC* DC )
+{
+ TEXTE_PCB* TextePcb = (TEXTE_PCB*) Panel->GetScreen()->GetCurItem();
+ ( (PCB_EDIT_FRAME*) Panel->GetParent() )->SetCurItem( NULL );
+
+ Panel->SetMouseCapture( NULL, NULL );
+
+ if( TextePcb == NULL ) // Should not occur
+ return;
+
+#ifndef USE_WX_OVERLAY
+ TextePcb->Draw( Panel, DC, GR_XOR );
+#endif
+
+ if( TextePcb->IsNew() ) // If new: remove it
+ {
+ TextePcb->DeleteStructure();
+ return;
+ }
+
+
+ TextePcb->SwapData( &s_TextCopy );
+ TextePcb->ClearFlags();
+#ifndef USE_WX_OVERLAY
+ TextePcb->Draw( Panel, DC, GR_OR );
+#else
+ Panel->Refresh();
+#endif
+}
+
+
+/*
+ * Place the current text being moving
+ */
+void PCB_EDIT_FRAME::Place_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC )
+{
+ m_canvas->SetMouseCapture( NULL, NULL );
+ SetCurItem( NULL );
+
+ if( TextePcb == NULL )
+ return;
+
+ TextePcb->Draw( m_canvas, DC, GR_OR );
+ OnModify();
+
+ if( TextePcb->IsNew() ) // If new: prepare undo command
+ {
+ SaveCopyInUndoList( TextePcb, UR_NEW );
+ TextePcb->ClearFlags();
+ return;
+ }
+
+ if( TextePcb->IsMoving() ) // If moved only
+ {
+ SaveCopyInUndoList( TextePcb, UR_MOVED,
+ TextePcb->GetTextPosition() - s_TextCopy.GetTextPosition() );
+ }
+ else
+ {
+ // Restore initial params
+ TextePcb->SwapData( &s_TextCopy );
+ // Prepare undo command
+ SaveCopyInUndoList( TextePcb, UR_CHANGED );
+ // Restore current params
+ TextePcb->SwapData( &s_TextCopy );
+ }
+
+ TextePcb->ClearFlags();
+#ifdef USE_WX_OVERLAY
+ m_canvas->Refresh();
+#endif
+}
+
+
+void PCB_EDIT_FRAME::StartMoveTextePcb( TEXTE_PCB* aTextePcb, wxDC* aDC, bool aErase )
+{
+ if( aTextePcb == NULL )
+ return;
+
+ // if it is an existing item: prepare a copy to undo/abort command
+ if( !aTextePcb->IsNew() )
+ s_TextCopy.Copy( aTextePcb );
+
+ aTextePcb->SetFlags( IS_MOVED );
+ SetMsgPanel( aTextePcb );
+
+#ifdef USE_WX_OVERLAY
+ m_canvas->Refresh();
+#endif
+
+ SetCrossHairPosition( aTextePcb->GetTextPosition() );
+ m_canvas->MoveCursorToCrossHair();
+
+ m_canvas->SetMouseCapture( Move_Texte_Pcb, Abort_Edit_Pcb_Text );
+ SetCurItem( aTextePcb );
+ m_canvas->CallMouseCapture( aDC, wxDefaultPosition, aErase );
+}
+
+
+// Move PCB text following the cursor.
+static void Move_Texte_Pcb( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ TEXTE_PCB* TextePcb = (TEXTE_PCB*) aPanel->GetScreen()->GetCurItem();
+
+ if( TextePcb == NULL )
+ return;
+
+ if( aErase )
+ TextePcb->Draw( aPanel, aDC, GR_XOR );
+
+ TextePcb->SetTextPosition( aPanel->GetParent()->GetCrossHairPosition() );
+
+ TextePcb->Draw( aPanel, aDC, GR_XOR );
+}
+
+
+void PCB_EDIT_FRAME::Delete_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC )
+{
+ if( TextePcb == NULL )
+ return;
+
+ TextePcb->Draw( m_canvas, DC, GR_XOR );
+
+ SaveCopyInUndoList( TextePcb, UR_DELETED );
+ TextePcb->UnLink();
+ m_canvas->SetMouseCapture( NULL, NULL );
+ SetCurItem( NULL );
+}
+
+
+TEXTE_PCB* PCB_EDIT_FRAME::CreateTextePcb( wxDC* aDC, TEXTE_PCB* aText )
+{
+ TEXTE_PCB* textePcb = new TEXTE_PCB( GetBoard() );
+
+ if( aText )
+ {
+ textePcb->Copy( aText );
+ GetBoard()->Add( textePcb );
+ textePcb->SetFlags( IS_NEW );
+ if( aDC )
+ StartMoveTextePcb( textePcb, aDC, false ); // Don't erase aText when copying
+ }
+ else
+ {
+ GetBoard()->Add( textePcb );
+ textePcb->SetFlags( IS_NEW );
+
+ LAYER_ID layer = GetActiveLayer();
+
+ textePcb->SetLayer( layer );
+
+ // Set the mirrored option for layers on the BACK side of the board
+ if( layer == B_Cu || layer == B_SilkS ||
+ layer == B_Paste || layer == B_Mask ||
+ layer == B_Adhes
+ )
+ textePcb->SetMirrored( true );
+
+ textePcb->SetSize( GetBoard()->GetDesignSettings().m_PcbTextSize );
+ textePcb->SetTextPosition( GetCrossHairPosition() );
+ textePcb->SetThickness( GetBoard()->GetDesignSettings().m_PcbTextWidth );
+
+ InstallTextPCBOptionsFrame( textePcb, aDC );
+
+ if( textePcb->GetText().IsEmpty() )
+ {
+ textePcb->DeleteStructure();
+ textePcb = NULL;
+ }
+ else if( aDC )
+ {
+ StartMoveTextePcb( textePcb, aDC );
+ }
+ }
+
+ return textePcb;
+}
+
+
+void PCB_EDIT_FRAME::Rotate_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC )
+{
+ int angle = 900;
+
+ if( TextePcb == NULL )
+ return;
+
+ // Erase previous text:
+ TextePcb->Draw( m_canvas, DC, GR_XOR );
+
+ TextePcb->SetOrientation( TextePcb->GetOrientation() + angle );
+
+ // Redraw text in new position:
+ TextePcb->Draw( m_canvas, DC, GR_XOR );
+ SetMsgPanel( TextePcb );
+
+ if( TextePcb->GetFlags() == 0 ) // i.e. not edited, or moved
+ SaveCopyInUndoList( TextePcb, UR_ROTATED, TextePcb->GetTextPosition() );
+ else // set flag edit, to show it was a complex command
+ TextePcb->SetFlags( IN_EDIT );
+
+ OnModify();
+#ifdef USE_WX_OVERLAY
+ m_canvas->Refresh();
+#endif
+}
+
+
+void PCB_EDIT_FRAME::FlipTextePcb( TEXTE_PCB* aTextePcb, wxDC* aDC )
+{
+ if( aTextePcb == NULL )
+ return;
+
+ aTextePcb->Draw( m_canvas, aDC, GR_XOR );
+
+ aTextePcb->Flip( aTextePcb->GetTextPosition() );
+
+ aTextePcb->Draw( m_canvas, aDC, GR_XOR );
+ SetMsgPanel( aTextePcb );
+
+ if( aTextePcb->GetFlags() == 0 ) // i.e. not edited, or moved
+ SaveCopyInUndoList( aTextePcb, UR_FLIPPED, aTextePcb->GetTextPosition() );
+ else // set edit flag, for the current command
+ aTextePcb->SetFlags( IN_EDIT );
+
+ OnModify();
+#ifdef USE_WX_OVERLAY
+ m_canvas->Refresh();
+#endif
+}
diff --git a/pcbnew/edit_track_width.cpp b/pcbnew/edit_track_width.cpp
new file mode 100644
index 0000000..d163bc9
--- /dev/null
+++ b/pcbnew/edit_track_width.cpp
@@ -0,0 +1,323 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file edit_track_width.cpp
+ * @brief Functions to modify sizes of segment, track, net, all vias and/or all tracks.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+
+#include <class_board.h>
+#include <class_track.h>
+
+#include <pcbnew.h>
+#include <drc_stuff.h>
+#include <protos.h>
+
+
+/**
+ * Function SetTrackSegmentWidth
+ * Modify one track segment width or one via diameter and drill (using DRC control).
+ * Basic routine used by other routines when editing tracks or vias
+ * @param aTrackItem = the track segment or via to modify
+ * @param aItemsListPicker = the list picker to use for an undo command (can be NULL)
+ * @param aUseNetclassValue = true to use NetClass value, false to use BOARD::m_designSettings value
+ * @return true if done, false if no not change (because DRC error)
+ */
+bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem,
+ PICKED_ITEMS_LIST* aItemsListPicker,
+ bool aUseNetclassValue )
+{
+ int initial_width, new_width;
+ int initial_drill = -1,new_drill = -1;
+ bool change_ok = false;
+ NETINFO_ITEM* net = NULL;
+
+ if( aUseNetclassValue )
+ net = aTrackItem->GetNet();
+
+ initial_width = aTrackItem->GetWidth();
+
+ if( net )
+ new_width = net->GetTrackWidth();
+ else
+ new_width = GetDesignSettings().GetCurrentTrackWidth();
+
+ if( aTrackItem->Type() == PCB_VIA_T )
+ {
+ const VIA *via = static_cast<const VIA *>( aTrackItem );
+
+ // Micro vias have a size only defined in their netclass
+ // (no specific values defined by a table of specific value)
+ // Ensure the netclass is accessible:
+ if( via->GetViaType() == VIA_MICROVIA && net == NULL )
+ net = aTrackItem->GetNet();
+
+ // Get the draill value, regardless it is default or specific
+ initial_drill = via->GetDrillValue();
+
+ if( net )
+ {
+ new_width = net->GetViaSize();
+ new_drill = net->GetViaDrillSize();
+ }
+ else
+ {
+ new_width = GetDesignSettings().GetCurrentViaSize();
+ new_drill = GetDesignSettings().GetCurrentViaDrill();
+ }
+
+ if( via->GetViaType() == VIA_MICROVIA )
+ {
+ if( net )
+ {
+ new_width = net->GetMicroViaSize();
+ new_drill = net->GetMicroViaDrillSize();
+ }
+ else
+ {
+ // Should not occur
+ }
+ }
+
+ // Old versions set a drill value <= 0, when the default netclass it used
+ // but it could be better to set the drill value to the actual value
+ // to avoid issues for existing vias, if the default drill value is modified
+ // in the netclass, and not in current vias.
+ if( via->GetDrill() <= 0 ) // means default netclass drill value used
+ {
+ initial_drill = -1; // Force drill vias re-initialization
+ }
+ }
+
+ aTrackItem->SetWidth( new_width );
+
+ // make a DRC test because the new size is bigger than the old size
+ if( initial_width < new_width )
+ {
+ int diagdrc = OK_DRC;
+
+ if( g_Drc_On )
+ diagdrc = m_drc->Drc( aTrackItem, GetBoard()->m_Track );
+
+ if( diagdrc == OK_DRC )
+ change_ok = true;
+ }
+ else if( initial_width > new_width )
+ {
+ change_ok = true;
+ }
+ else if( (aTrackItem->Type() == PCB_VIA_T) )
+ {
+ // if a via has its drill value changed, force change
+ if( initial_drill != new_drill )
+ change_ok = true;
+ }
+
+ if( change_ok )
+ {
+ OnModify();
+
+ if( aItemsListPicker )
+ {
+ aTrackItem->SetWidth( initial_width );
+ ITEM_PICKER picker( aTrackItem, UR_CHANGED );
+ picker.SetLink( aTrackItem->Clone() );
+ aItemsListPicker->PushItem( picker );
+ aTrackItem->SetWidth( new_width );
+
+ if( aTrackItem->Type() == PCB_VIA_T )
+ {
+ // Set new drill value. Note: currently microvias have only a default drill value
+ VIA *via = static_cast<VIA *>( aTrackItem );
+ if( new_drill > 0 )
+ via->SetDrill( new_drill );
+ else
+ via->SetDrillDefault();
+ }
+ }
+ }
+ else
+ {
+ aTrackItem->SetWidth( initial_width );
+ }
+
+ return change_ok;
+}
+
+
+/**
+ * Function Edit_TrackSegm_Width
+ * Modify one track segment width or one via diameter (using DRC control).
+ * @param aDC = the curred device context (can be NULL)
+ * @param aTrackItem = the track segment or via to modify
+ */
+void PCB_EDIT_FRAME::Edit_TrackSegm_Width( wxDC* aDC, TRACK* aTrackItem )
+{
+ PICKED_ITEMS_LIST itemsListPicker;
+ bool change = SetTrackSegmentWidth( aTrackItem, &itemsListPicker, false );
+
+ if( change == 0 || aTrackItem->GetFlags() )
+ return; // No change
+
+ // The segment has changed: redraw it and save it in undo list
+ if( aDC )
+ {
+ TRACK* oldsegm = (TRACK*) itemsListPicker.GetPickedItemLink( 0 );
+ wxASSERT( oldsegm );
+ m_canvas->CrossHairOff( aDC ); // Erase cursor shape
+ oldsegm->Draw( m_canvas, aDC, GR_XOR ); // Erase old track shape
+ aTrackItem->Draw( m_canvas, aDC, GR_OR ); // Display new track shape
+ m_canvas->CrossHairOn( aDC ); // Display cursor shape
+ }
+
+ SaveCopyInUndoList( itemsListPicker, UR_CHANGED );
+}
+
+
+/**
+ * Function Edit_Track_Width
+ * Modify a full track width (using DRC control).
+ * a full track is the set of track segments between 2 ends: pads or a point that has
+ * more than 2 segments ends connected
+ * @param aDC = the curred device context (can be NULL)
+ * @param aTrackSegment = a segment or via on the track to change
+ */
+void PCB_EDIT_FRAME::Edit_Track_Width( wxDC* aDC, TRACK* aTrackSegment )
+{
+ TRACK* pt_track;
+ int nb_segm;
+
+ if( aTrackSegment == NULL )
+ return;
+
+ pt_track = GetBoard()->MarkTrace( aTrackSegment, &nb_segm, NULL, NULL, true );
+
+ PICKED_ITEMS_LIST itemsListPicker;
+ bool change = false;
+
+ for( int ii = 0; ii < nb_segm; ii++, pt_track = pt_track->Next() )
+ {
+ pt_track->SetState( BUSY, false );
+
+ if( SetTrackSegmentWidth( pt_track, &itemsListPicker, false ) )
+ change = true;
+ }
+
+ if( !change )
+ return;
+
+ // Some segment have changed: redraw them and save in undo list
+ if( aDC )
+ {
+ m_canvas->CrossHairOff( aDC ); // Erase cursor shape
+
+ for( unsigned ii = 0; ii < itemsListPicker.GetCount(); ii++ )
+ {
+ TRACK* segm = (TRACK*) itemsListPicker.GetPickedItemLink( ii );
+ segm->Draw( m_canvas, aDC, GR_XOR ); // Erase old track shape
+ segm = (TRACK*) itemsListPicker.GetPickedItem( ii );
+ segm->Draw( m_canvas, aDC, GR_OR ); // Display new track shape
+ }
+
+ m_canvas->CrossHairOn( aDC ); // Display cursor shape
+ }
+
+ SaveCopyInUndoList( itemsListPicker, UR_CHANGED );
+}
+
+
+/**
+ * Function Change_Net_Tracks_And_Vias_Sizes
+ * Reset all tracks width and vias diameters and drill
+ * to their default Netclass value or current values
+ * @param aNetcode : the netcode of the net to edit
+ * @param aUseNetclassValue : bool. True to use netclass values, false to use current values
+ */
+bool PCB_EDIT_FRAME::Change_Net_Tracks_And_Vias_Sizes( int aNetcode, bool aUseNetclassValue )
+{
+ TRACK* pt_segm;
+
+ if( aNetcode <= 0 )
+ return false;
+
+ // Examine segments
+ PICKED_ITEMS_LIST itemsListPicker;
+ bool change = false;
+
+ for( pt_segm = GetBoard()->m_Track; pt_segm != NULL; pt_segm = pt_segm->Next() )
+ {
+ if( aNetcode != pt_segm->GetNetCode() ) // not in net
+ continue;
+
+ // we have found a item member of the net
+ if( SetTrackSegmentWidth( pt_segm, &itemsListPicker, aUseNetclassValue ) )
+ change = true;
+ }
+
+ if( !change )
+ return false;
+
+ // Some segment have changed: save them in undo list
+ SaveCopyInUndoList( itemsListPicker, UR_CHANGED );
+ return true;
+}
+
+
+bool PCB_EDIT_FRAME::Reset_All_Tracks_And_Vias_To_Netclass_Values( bool aTrack, bool aVia )
+{
+ TRACK* pt_segm;
+
+ // read and edit tracks and vias if required
+ PICKED_ITEMS_LIST itemsListPicker;
+ bool change = false;
+
+ for( pt_segm = GetBoard()->m_Track; pt_segm != NULL; pt_segm = pt_segm->Next() )
+ {
+ if( (pt_segm->Type() == PCB_VIA_T ) && aVia )
+ {
+ if( SetTrackSegmentWidth( pt_segm, &itemsListPicker, true ) )
+ change = true;
+ }
+
+ if( (pt_segm->Type() == PCB_TRACE_T ) && aTrack )
+ {
+ if( SetTrackSegmentWidth( pt_segm, &itemsListPicker, true ) )
+ change = true;
+ }
+ }
+
+ if( !change )
+ return false;
+
+ // Some segment have changed: save them in undo list
+ SaveCopyInUndoList( itemsListPicker, UR_CHANGED );
+
+ return true;
+}
diff --git a/pcbnew/editedge.cpp b/pcbnew/editedge.cpp
new file mode 100644
index 0000000..0dcd2f3
--- /dev/null
+++ b/pcbnew/editedge.cpp
@@ -0,0 +1,367 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file editedge.cpp
+ * @brief Edit segments and edges of PCB.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <gr_basic.h>
+
+#include <pcbnew.h>
+#include <protos.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_drawsegment.h>
+
+
+static void Abort_EditEdge( EDA_DRAW_PANEL* aPanel, wxDC* DC );
+static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, bool aErase );
+static void Move_Segment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase );
+
+
+static wxPoint s_InitialPosition; // Initial cursor position.
+static wxPoint s_LastPosition; // Current cursor position.
+
+
+// Start move of a graphic element type DRAWSEGMENT
+void PCB_EDIT_FRAME::Start_Move_DrawItem( DRAWSEGMENT* drawitem, wxDC* DC )
+{
+ if( drawitem == NULL )
+ return;
+
+ drawitem->Draw( m_canvas, DC, GR_XOR );
+ drawitem->SetFlags( IS_MOVED );
+ s_InitialPosition = s_LastPosition = GetCrossHairPosition();
+ SetMsgPanel( drawitem );
+ m_canvas->SetMouseCapture( Move_Segment, Abort_EditEdge );
+ SetCurItem( drawitem );
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+}
+
+
+/*
+ * Place graphic element of type DRAWSEGMENT.
+ */
+void PCB_EDIT_FRAME::Place_DrawItem( DRAWSEGMENT* drawitem, wxDC* DC )
+{
+ if( drawitem == NULL )
+ return;
+
+ drawitem->ClearFlags();
+ SaveCopyInUndoList(drawitem, UR_MOVED, s_LastPosition - s_InitialPosition);
+ drawitem->Draw( m_canvas, DC, GR_OR );
+ m_canvas->SetMouseCapture( NULL, NULL );
+ SetCurItem( NULL );
+ OnModify();
+}
+
+/*
+ * Redraw segment during cursor movement.
+ */
+static void Move_Segment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ DRAWSEGMENT* segment = (DRAWSEGMENT*) aPanel->GetScreen()->GetCurItem();
+
+ if( segment == NULL )
+ return;
+
+ if( aErase )
+ segment->Draw( aPanel, aDC, GR_XOR );
+
+ wxPoint delta;
+ delta = aPanel->GetParent()->GetCrossHairPosition() - s_LastPosition;
+
+ segment->SetStart( segment->GetStart() + delta );
+ segment->SetEnd( segment->GetEnd() + delta );
+
+ s_LastPosition = aPanel->GetParent()->GetCrossHairPosition();
+
+ segment->Draw( aPanel, aDC, GR_XOR );
+}
+
+
+void PCB_EDIT_FRAME::Delete_Segment_Edge( DRAWSEGMENT* Segment, wxDC* DC )
+{
+ EDA_ITEM* PtStruct;
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+ bool tmp = displ_opts->m_DisplayDrawItemsFill;
+
+ if( Segment == NULL )
+ return;
+
+ if( Segment->IsNew() ) // Trace in progress.
+ {
+ // Delete current segment.
+ displ_opts->m_DisplayDrawItemsFill = SKETCH;
+ Segment->Draw( m_canvas, DC, GR_XOR );
+ PtStruct = Segment->Back();
+ Segment ->DeleteStructure();
+
+ if( PtStruct && (PtStruct->Type() == PCB_LINE_T ) )
+ Segment = (DRAWSEGMENT*) PtStruct;
+
+ displ_opts->m_DisplayDrawItemsFill = tmp;
+ SetCurItem( NULL );
+ }
+ else if( Segment->GetFlags() == 0 )
+ {
+ Segment->Draw( m_canvas, DC, GR_XOR );
+ Segment->ClearFlags();
+ SaveCopyInUndoList(Segment, UR_DELETED);
+ Segment->UnLink();
+ SetCurItem( NULL );
+ OnModify();
+ }
+}
+
+
+void PCB_EDIT_FRAME::Delete_Drawings_All_Layer( LAYER_ID aLayer )
+{
+ if( IsCopperLayer( aLayer ) )
+ {
+ DisplayError( this, _( "Copper layer global delete not allowed!" ) );
+ return;
+ }
+
+ wxString msg = wxString::Format(
+ _( "Delete everything on layer %s?" ),
+ GetChars( GetBoard()->GetLayerName( aLayer ) ) );
+
+ if( !IsOK( this, msg ) )
+ return;
+
+ PICKED_ITEMS_LIST pickList;
+ ITEM_PICKER picker( NULL, UR_DELETED );
+ BOARD_ITEM* PtNext;
+
+ for( BOARD_ITEM* item = GetBoard()->m_Drawings; item; item = PtNext )
+ {
+ PtNext = item->Next();
+
+ switch( item->Type() )
+ {
+ case PCB_LINE_T:
+ case PCB_TEXT_T:
+ case PCB_DIMENSION_T:
+ case PCB_TARGET_T:
+ if( item->GetLayer() == aLayer )
+ {
+ item->UnLink();
+ picker.SetItem( item );
+ pickList.PushItem( picker );
+ }
+
+ break;
+
+ default:
+ {
+ wxString msg;
+ msg.Printf( wxT("Delete_Drawings_All_Layer() error: unknown type %d"),
+ item->Type() );
+ wxMessageBox( msg );
+ break;
+ }
+ }
+ }
+
+ if( pickList.GetCount() )
+ {
+ OnModify();
+ SaveCopyInUndoList(pickList, UR_DELETED);
+ }
+}
+
+
+static void Abort_EditEdge( EDA_DRAW_PANEL* aPanel, wxDC* DC )
+{
+ DRAWSEGMENT* Segment = (DRAWSEGMENT*) aPanel->GetScreen()->GetCurItem();
+
+ if( Segment == NULL )
+ {
+ aPanel->SetMouseCapture( NULL, NULL );
+ return;
+ }
+
+ if( Segment->IsNew() )
+ {
+ aPanel->CallMouseCapture( DC, wxDefaultPosition, false );
+ Segment ->DeleteStructure();
+ Segment = NULL;
+ }
+ else
+ {
+ wxPoint pos = aPanel->GetParent()->GetCrossHairPosition();
+ aPanel->GetParent()->SetCrossHairPosition( s_InitialPosition );
+ aPanel->CallMouseCapture( DC, wxDefaultPosition, true );
+ aPanel->GetParent()->SetCrossHairPosition( pos );
+ Segment->ClearFlags();
+ Segment->Draw( aPanel, DC, GR_OR );
+ }
+
+#ifdef USE_WX_OVERLAY
+ aPanel->Refresh();
+#endif
+
+ aPanel->SetMouseCapture( NULL, NULL );
+ ( (PCB_EDIT_FRAME*) aPanel->GetParent() )->SetCurItem( NULL );
+}
+
+
+/* Initialize the drawing of a segment of type other than trace.
+ */
+DRAWSEGMENT* PCB_EDIT_FRAME::Begin_DrawSegment( DRAWSEGMENT* Segment, STROKE_T shape, wxDC* DC )
+{
+ int s_large;
+ DRAWSEGMENT* DrawItem;
+
+ s_large = GetDesignSettings().m_DrawSegmentWidth;
+
+ if( GetActiveLayer() == Edge_Cuts )
+ {
+ s_large = GetDesignSettings().m_EdgeSegmentWidth;
+ }
+
+ if( Segment == NULL ) // Create new trace.
+ {
+ SetCurItem( Segment = new DRAWSEGMENT( GetBoard() ) );
+ Segment->SetFlags( IS_NEW );
+ Segment->SetLayer( GetActiveLayer() );
+ Segment->SetWidth( s_large );
+ Segment->SetShape( shape );
+ Segment->SetAngle( 900 );
+ Segment->SetStart( GetCrossHairPosition() );
+ Segment->SetEnd( GetCrossHairPosition() );
+ m_canvas->SetMouseCapture( DrawSegment, Abort_EditEdge );
+ }
+ else /* The ending point ccordinate Segment->m_End was updated by he function
+ * DrawSegment() called on a move mouse event
+ * during the segment creation
+ */
+ {
+ if( Segment->GetStart() != Segment->GetEnd() )
+ {
+ if( Segment->GetShape() == S_SEGMENT )
+ {
+ SaveCopyInUndoList( Segment, UR_NEW );
+ GetBoard()->Add( Segment );
+
+ OnModify();
+ Segment->ClearFlags();
+
+ Segment->Draw( m_canvas, DC, GR_OR );
+
+ DrawItem = Segment;
+
+ SetCurItem( Segment = new DRAWSEGMENT( GetBoard() ) );
+
+ Segment->SetFlags( IS_NEW );
+ Segment->SetLayer( DrawItem->GetLayer() );
+ Segment->SetWidth( s_large );
+ Segment->SetShape( DrawItem->GetShape() );
+ Segment->SetType( DrawItem->GetType() );
+ Segment->SetAngle( DrawItem->GetAngle() );
+ Segment->SetStart( DrawItem->GetEnd() );
+ Segment->SetEnd( DrawItem->GetEnd() );
+ DrawSegment( m_canvas, DC, wxDefaultPosition, false );
+ }
+ else
+ {
+ End_Edge( Segment, DC );
+ Segment = NULL;
+ }
+ }
+ }
+
+ return Segment;
+}
+
+
+void PCB_EDIT_FRAME::End_Edge( DRAWSEGMENT* Segment, wxDC* DC )
+{
+ if( Segment == NULL )
+ return;
+
+ Segment->Draw( m_canvas, DC, GR_OR );
+
+ // Delete if segment length is zero.
+ if( Segment->GetStart() == Segment->GetEnd() )
+ {
+ Segment->DeleteStructure();
+ }
+ else
+ {
+ Segment->ClearFlags();
+ GetBoard()->Add( Segment );
+ OnModify();
+ SaveCopyInUndoList( Segment, UR_NEW );
+ }
+
+ m_canvas->SetMouseCapture( NULL, NULL );
+ SetCurItem( NULL );
+}
+
+
+/* Redraw segment during cursor movement
+ */
+static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, bool aErase )
+{
+ DRAWSEGMENT* Segment = (DRAWSEGMENT*) aPanel->GetScreen()->GetCurItem();
+
+ if( Segment == NULL )
+ return;
+
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)aPanel->GetDisplayOptions();
+ bool tmp = displ_opts->m_DisplayDrawItemsFill;
+
+ displ_opts->m_DisplayDrawItemsFill = SKETCH;
+
+ if( aErase )
+ Segment->Draw( aPanel, aDC, GR_XOR );
+
+ if( g_Segments_45_Only && Segment->GetShape() == S_SEGMENT )
+ {
+ wxPoint pt;
+
+ CalculateSegmentEndPoint( aPanel->GetParent()->GetCrossHairPosition(),
+ Segment->GetStart().x, Segment->GetStart().y,
+ &pt.x, &pt.y );
+ Segment->SetEnd( pt );
+ }
+ else // here the angle is arbitrary
+ {
+ Segment->SetEnd( aPanel->GetParent()->GetCrossHairPosition() );
+ }
+
+ Segment->Draw( aPanel, aDC, GR_XOR );
+ displ_opts->m_DisplayDrawItemsFill = tmp;
+}
diff --git a/pcbnew/editmod.cpp b/pcbnew/editmod.cpp
new file mode 100644
index 0000000..b2c9dc0
--- /dev/null
+++ b/pcbnew/editmod.cpp
@@ -0,0 +1,144 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file edit.cpp
+ * @brief Module editor dialog box for editing module properties and characteristics.
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <kiway.h>
+#include <confirm.h>
+#include <class_drawpanel.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <module_editor_frame.h>
+#include <3d_viewer.h>
+
+#include <class_module.h>
+#include <class_pad.h>
+#include <class_edge_mod.h>
+
+#include <dialog_edit_module_for_BoardEditor.h>
+
+
+/*
+ * Show module property dialog.
+ */
+void PCB_EDIT_FRAME::InstallModuleOptionsFrame( MODULE* Module, wxDC* DC )
+{
+ if( Module == NULL )
+ return;
+
+#ifdef __WXMAC__
+ // avoid Avoid "writes" in the dialog, creates errors with WxOverlay and NSView & Modal
+ // Raising an Exception - Fixes #764678
+ DC = NULL;
+#endif
+
+ DIALOG_MODULE_BOARD_EDITOR* dlg = new DIALOG_MODULE_BOARD_EDITOR( this, Module, DC );
+
+ int retvalue = dlg->ShowModal();
+ /* retvalue =
+ * FP_PRM_EDITOR_RETVALUE::PRM_EDITOR_ABORT if abort,
+ * FP_PRM_EDITOR_RETVALUE::PRM_EDITOR_WANT_EXCHANGE_FP if exchange module,
+ * FP_PRM_EDITOR_RETVALUE::PRM_EDITOR_EDIT_OK for normal edition
+ * FP_PRM_EDITOR_RETVALUE::PRM_EDITOR_WANT_MODEDIT for a goto editor command
+ */
+ dlg->Destroy();
+
+#ifdef __WXMAC__
+ // If something edited, push a refresh request
+ if( retvalue == DIALOG_MODULE_BOARD_EDITOR::PRM_EDITOR_EDIT_OK )
+ m_canvas->Refresh();
+#endif
+
+ if( retvalue == DIALOG_MODULE_BOARD_EDITOR::PRM_EDITOR_WANT_MODEDIT )
+ {
+ FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
+
+ editor->Load_Module_From_BOARD( Module );
+ SetCurItem( NULL );
+
+ editor->Show( true );
+ editor->Raise(); // Iconize( false );
+ }
+
+ if( retvalue == DIALOG_MODULE_BOARD_EDITOR::PRM_EDITOR_WANT_EXCHANGE_FP )
+ {
+ InstallExchangeModuleFrame( Module );
+ // Warning: the current item can be deleted by exchange module
+ SetCurItem( NULL );
+ }
+}
+
+
+void FOOTPRINT_EDIT_FRAME::RemoveStruct( EDA_ITEM* Item )
+{
+ if( Item == NULL )
+ return;
+
+ switch( Item->Type() )
+ {
+ case PCB_PAD_T:
+ DeletePad( (D_PAD*) Item, false );
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ {
+ TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( Item );
+
+ switch( text->GetType() )
+ {
+ case TEXTE_MODULE::TEXT_is_REFERENCE:
+ DisplayError( this, _( "Cannot delete REFERENCE!" ) );
+ break;
+
+ case TEXTE_MODULE::TEXT_is_VALUE:
+ DisplayError( this, _( "Cannot delete VALUE!" ) );
+ break;
+
+ case TEXTE_MODULE::TEXT_is_DIVERS:
+ DeleteTextModule( text );
+ }
+ }
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ Delete_Edge_Module( (EDGE_MODULE*) Item );
+ m_canvas->Refresh();
+ break;
+
+ case PCB_MODULE_T:
+ break;
+
+ default:
+ {
+ wxString Line;
+ Line.Printf( wxT( " RemoveStruct: item type %d unknown." ), Item->Type() );
+ wxMessageBox( Line );
+ }
+ break;
+ }
+}
diff --git a/pcbnew/editrack-part2.cpp b/pcbnew/editrack-part2.cpp
new file mode 100644
index 0000000..0d114f1
--- /dev/null
+++ b/pcbnew/editrack-part2.cpp
@@ -0,0 +1,314 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file editrack-part2.cpp
+ */
+
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_marker_pcb.h>
+
+#include <pcbnew.h>
+#include <drc_stuff.h>
+
+
+bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
+{
+ unsigned itmp;
+
+ if( aTrack == NULL )
+ {
+ if( GetActiveLayer() != GetScreen()->m_Route_Layer_TOP )
+ SetActiveLayer( GetScreen()->m_Route_Layer_TOP );
+ else
+ SetActiveLayer( GetScreen()->m_Route_Layer_BOTTOM );
+
+ UpdateStatusBar();
+ return true;
+ }
+
+ // Avoid more than one via on the current location:
+ if( GetBoard()->GetViaByPosition( g_CurrentTrackSegment->GetEnd(),
+ g_CurrentTrackSegment->GetLayer() ) )
+ return false;
+
+ for( TRACK* segm = g_FirstTrackSegment; segm; segm = segm->Next() )
+ {
+ if( segm->Type() == PCB_VIA_T && g_CurrentTrackSegment->GetEnd() == segm->GetStart() )
+ return false;
+ }
+
+ // Is the current segment Ok (no DRC error) ?
+ if( g_Drc_On )
+ {
+ if( BAD_DRC==m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
+ // DRC error, the change layer is not made
+ return false;
+
+ // Handle 2 segments.
+ if( g_TwoSegmentTrackBuild && g_CurrentTrackSegment->Back() )
+ {
+ if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), GetBoard()->m_Track ) )
+ return false;
+ }
+ }
+
+ /* Save current state before placing a via.
+ * If the via cannot be placed this current state will be reused
+ */
+ itmp = g_CurrentTrackList.GetCount();
+ Begin_Route( g_CurrentTrackSegment, DC );
+
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ // create the via
+ VIA* via = new VIA( GetBoard() );
+ via->SetFlags( IS_NEW );
+ via->SetViaType( GetDesignSettings().m_CurrentViaType );
+ via->SetNetCode( GetBoard()->GetHighLightNetCode() );
+ via->SetPosition( g_CurrentTrackSegment->GetEnd() );
+
+ // for microvias, the size and hole will be changed later.
+ via->SetWidth( GetDesignSettings().GetCurrentViaSize());
+ via->SetDrill( GetDesignSettings().GetCurrentViaDrill() );
+
+ // Usual via is from copper to component.
+ // layer pair is B_Cu and F_Cu.
+ via->SetLayerPair( B_Cu, F_Cu );
+
+ LAYER_ID first_layer = GetActiveLayer();
+ LAYER_ID last_layer;
+
+ // prepare switch to new active layer:
+ if( first_layer != GetScreen()->m_Route_Layer_TOP )
+ last_layer = GetScreen()->m_Route_Layer_TOP;
+ else
+ last_layer = GetScreen()->m_Route_Layer_BOTTOM;
+
+ // Adjust the actual via layer pair
+ switch( via->GetViaType() )
+ {
+ case VIA_BLIND_BURIED:
+ via->SetLayerPair( first_layer, last_layer );
+ break;
+
+ case VIA_MICROVIA: // from external to the near neighbor inner layer
+ {
+ LAYER_ID last_inner_layer = ToLAYER_ID( ( GetBoard()->GetCopperLayerCount() - 2 ) );
+
+ if( first_layer == B_Cu )
+ last_layer = last_inner_layer;
+ else if( first_layer == F_Cu )
+ last_layer = In1_Cu;
+ else if( first_layer == last_inner_layer )
+ last_layer = B_Cu;
+ else if( first_layer == In1_Cu )
+ last_layer = F_Cu;
+ // else error: will be removed later
+ via->SetLayerPair( first_layer, last_layer );
+
+ // Update diameter and hole size, which where set previously
+ // for normal vias
+ NETINFO_ITEM* net = via->GetNet();
+ via->SetWidth( net->GetMicroViaSize() );
+ via->SetDrill( net->GetMicroViaDrillSize() );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if( g_Drc_On && BAD_DRC == m_drc->Drc( via, GetBoard()->m_Track ) )
+ {
+ // DRC fault: the Via cannot be placed here ...
+ delete via;
+
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ // delete the track(s) added in Begin_Route()
+ while( g_CurrentTrackList.GetCount() > itmp )
+ {
+ Delete_Segment( DC, g_CurrentTrackSegment );
+ }
+
+ SetCurItem( g_CurrentTrackSegment, false );
+
+ // Refresh DRC diag, erased by previous calls
+ if( m_drc->GetCurrentMarker() )
+ SetMsgPanel( m_drc->GetCurrentMarker() );
+
+ return false;
+ }
+
+ SetActiveLayer( last_layer );
+
+ TRACK* lastNonVia = g_CurrentTrackSegment;
+
+ /* A new via was created. It was Ok.
+ */
+ g_CurrentTrackList.PushBack( via );
+
+ /* The via is now in linked list and we need a new track segment
+ * after the via, starting at via location.
+ * it will become the new current segment (from via to the mouse cursor)
+ */
+
+ TRACK* track = (TRACK*)lastNonVia->Clone();
+
+ /* the above creates a new segment from the last entered segment, with the
+ * current width, flags, netcode, etc... values.
+ * layer, start and end point are not correct,
+ * and will be modified next
+ */
+
+ // set the layer to the new value
+ track->SetLayer( GetActiveLayer() );
+
+ /* the start point is the via position and the end point is the cursor
+ * which also is on the via (will change when moving mouse)
+ */
+ track->SetEnd( via->GetStart() );
+ track->SetStart( via->GetStart() );
+
+ g_CurrentTrackList.PushBack( track );
+
+ if( g_TwoSegmentTrackBuild )
+ {
+ // Create a second segment (we must have 2 track segments to adjust)
+ g_CurrentTrackList.PushBack( (TRACK*)g_CurrentTrackSegment->Clone() );
+ }
+
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ SetMsgPanel( via );
+ UpdateStatusBar();
+
+ return true;
+}
+
+
+void PCB_EDIT_FRAME::Show_1_Ratsnest( EDA_ITEM* item, wxDC* DC )
+{
+ D_PAD* pt_pad = NULL;
+ MODULE* Module = NULL;
+
+ if( GetBoard()->IsElementVisible(RATSNEST_VISIBLE) )
+ return;
+
+ if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
+ Compile_Ratsnest( DC, true );
+
+ if( item )
+ {
+ if( item->Type() == PCB_PAD_T )
+ {
+ pt_pad = (D_PAD*) item;
+ Module = pt_pad->GetParent();
+ }
+
+ if( pt_pad ) // Displaying the ratsnest of the corresponding net.
+ {
+ SetMsgPanel( pt_pad );
+
+ for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
+ {
+ RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii];
+
+ if( net->GetNet() == pt_pad->GetNetCode() )
+ {
+ if( ( net->m_Status & CH_VISIBLE ) != 0 )
+ continue;
+
+ net->m_Status |= CH_VISIBLE;
+
+ if( ( net->m_Status & CH_ACTIF ) == 0 )
+ continue;
+
+ net->Draw( m_canvas, DC, GR_XOR, wxPoint( 0, 0 ) );
+ }
+ }
+ }
+ else
+ {
+ if( item->Type() == PCB_MODULE_TEXT_T )
+ {
+ if( item->GetParent() && ( item->GetParent()->Type() == PCB_MODULE_T ) )
+ Module = static_cast<MODULE*>( item->GetParent() );
+ }
+ else if( item->Type() == PCB_MODULE_T )
+ {
+ Module = static_cast<MODULE*>( item );
+ }
+
+ if( Module )
+ {
+ SetMsgPanel( Module );
+ pt_pad = Module->Pads();
+
+ for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
+ {
+ for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
+ {
+ RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii];
+
+ if( ( net->m_PadStart == pt_pad ) || ( net->m_PadEnd == pt_pad ) )
+ {
+ if( net->m_Status & CH_VISIBLE )
+ continue;
+
+ net->m_Status |= CH_VISIBLE;
+
+ if( (net->m_Status & CH_ACTIF) == 0 )
+ continue;
+
+ net->Draw( m_canvas, DC, GR_XOR, wxPoint( 0, 0 ) );
+ }
+ }
+ }
+
+ pt_pad = NULL;
+ }
+ }
+ }
+
+ // Erase if no pad or module has been selected.
+ if( ( pt_pad == NULL ) && ( Module == NULL ) )
+ {
+ DrawGeneralRatsnest( DC );
+
+ for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
+ GetBoard()->m_FullRatsnest[ii].m_Status &= ~CH_VISIBLE;
+ }
+}
diff --git a/pcbnew/editrack.cpp b/pcbnew/editrack.cpp
new file mode 100644
index 0000000..d556096
--- /dev/null
+++ b/pcbnew/editrack.cpp
@@ -0,0 +1,1108 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file editrack.cpp
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <trigo.h>
+#include <wxPcbStruct.h>
+#include <colors_selection.h>
+
+#include <pcbnew.h>
+#include <drc_stuff.h>
+#include <protos.h>
+
+#include <class_board.h>
+#include <class_track.h>
+#include <class_zone.h>
+
+
+static void Abort_Create_Track( EDA_DRAW_PANEL* panel, wxDC* DC );
+void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase );
+static void ComputeBreakPoint( TRACK* track, int n, wxPoint end );
+static void DeleteNullTrackSegments( BOARD* pcb, DLIST<TRACK>& aTrackList );
+static void EnsureEndTrackOnPad( D_PAD* Pad );
+
+// A PICKED_ITEMS_LIST to store tracks which are modified/added/deleted
+// during a track edition:
+static PICKED_ITEMS_LIST s_ItemsListPicker;
+
+
+/* Function called to abort a track creation
+ */
+static void Abort_Create_Track( EDA_DRAW_PANEL* Panel, wxDC* DC )
+{
+ PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Panel->GetParent();
+ BOARD* pcb = frame->GetBoard();
+ TRACK* track = dyn_cast<TRACK*>( frame->GetCurItem() );
+
+ if( track )
+ {
+ // Erase the current drawing
+ ShowNewTrackWhenMovingCursor( Panel, DC, wxDefaultPosition, false );
+
+ if( pcb->IsHighLightNetON() )
+ frame->HighLight( DC );
+
+ pcb->PopHighLight();
+
+ if( pcb->IsHighLightNetON() )
+ pcb->DrawHighLight( Panel, DC, pcb->GetHighLightNetCode() );
+
+ frame->ClearMsgPanel();
+
+ // Undo pending changes (mainly a lock point creation) and clear the
+ // undo picker list:
+ frame->PutDataInPreviousState( &s_ItemsListPicker, false, false );
+ s_ItemsListPicker.ClearListAndDeleteItems();
+
+ // Delete current (new) track
+ g_CurrentTrackList.DeleteAll();
+ }
+
+ frame->SetCurItem( NULL );
+}
+
+/*
+ * This function starts a new track segment.
+ * If a new track segment is in progress, ends this current new segment,
+ * and created a new one.
+ */
+TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
+{
+ TRACK* trackOnStartPoint = NULL;
+ LSET layerMask( GetScreen()->m_Active_Layer );
+ wxPoint pos = GetCrossHairPosition();
+
+ BOARD_CONNECTED_ITEM* lockPoint;
+
+ if( aTrack == NULL ) // Starting a new track segment
+ {
+ m_canvas->SetMouseCapture( ShowNewTrackWhenMovingCursor, Abort_Create_Track );
+
+ // Prepare the undo command info
+ s_ItemsListPicker.ClearListAndDeleteItems(); // Should not be necessary, but...
+
+ GetBoard()->PushHighLight();
+
+ // erase old highlight
+ if( GetBoard()->IsHighLightNetON() )
+ HighLight( aDC );
+
+ g_CurrentTrackList.PushBack( new TRACK( GetBoard() ) );
+ g_CurrentTrackSegment->SetFlags( IS_NEW );
+
+ GetBoard()->SetHighLightNet( 0 );
+
+ // Search for a starting point of the new track, a track or pad
+ lockPoint = GetBoard()->GetLockPoint( pos, layerMask );
+
+ D_PAD* pad = NULL;
+ if( lockPoint ) // An item (pad or track) is found
+ {
+ if( lockPoint->Type() == PCB_PAD_T )
+ {
+ pad = (D_PAD*) lockPoint;
+
+ // A pad is found: put the starting point on pad center
+ pos = pad->GetPosition();
+ GetBoard()->SetHighLightNet( pad->GetNetCode() );
+ }
+ else // A track segment is found
+ {
+ trackOnStartPoint = (TRACK*) lockPoint;
+ GetBoard()->SetHighLightNet( trackOnStartPoint->GetNetCode() );
+ GetBoard()->CreateLockPoint( pos, trackOnStartPoint, &s_ItemsListPicker );
+ }
+ }
+ else
+ {
+ // Not a starting point, but a filled zone area can exist. This is also a
+ // good starting point.
+ ZONE_CONTAINER* zone;
+ zone = GetBoard()->HitTestForAnyFilledArea( pos,
+ GetScreen()-> m_Active_Layer,
+ GetScreen()-> m_Active_Layer,
+ -1 );
+
+ if( zone )
+ GetBoard()->SetHighLightNet( zone->GetNetCode() );
+ }
+
+ DBG( g_CurrentTrackList.VerifyListIntegrity() );
+
+ BuildAirWiresTargetsList( lockPoint, wxPoint( 0, 0 ), true );
+
+ DBG( g_CurrentTrackList.VerifyListIntegrity() );
+
+ GetBoard()->HighLightON();
+ GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() );
+
+ // Display info about track Net class, and init track and vias sizes:
+ g_CurrentTrackSegment->SetNetCode( GetBoard()->GetHighLightNetCode() );
+ SetCurrentNetClass( g_CurrentTrackSegment->GetNetClassName() );
+
+ g_CurrentTrackSegment->SetLayer( GetScreen()->m_Active_Layer );
+ g_CurrentTrackSegment->SetWidth( GetDesignSettings().GetCurrentTrackWidth() );
+
+ if( GetDesignSettings().m_UseConnectedTrackWidth )
+ {
+ if( trackOnStartPoint && trackOnStartPoint->Type() == PCB_TRACE_T )
+ g_CurrentTrackSegment->SetWidth( trackOnStartPoint->GetWidth());
+ }
+
+ g_CurrentTrackSegment->SetStart( pos );
+ g_CurrentTrackSegment->SetEnd( pos );
+
+ if( pad )
+ {
+ g_CurrentTrackSegment->m_PadsConnected.push_back( pad );
+ // Useful to display track length, if the pad has a die length:
+ g_CurrentTrackSegment->SetState( BEGIN_ONPAD, true );
+ g_CurrentTrackSegment->start = pad;
+ }
+
+ if( g_TwoSegmentTrackBuild )
+ {
+ // Create 2nd segment
+ g_CurrentTrackList.PushBack( (TRACK*)g_CurrentTrackSegment->Clone() );
+
+ DBG( g_CurrentTrackList.VerifyListIntegrity(); );
+
+ g_CurrentTrackSegment->start = g_FirstTrackSegment;
+ g_FirstTrackSegment->end = g_CurrentTrackSegment;
+
+ g_FirstTrackSegment->SetState( BEGIN_ONPAD | END_ONPAD, false );
+ }
+
+ DBG( g_CurrentTrackList.VerifyListIntegrity(); );
+
+ SetMsgPanel( g_CurrentTrackSegment );
+ SetCurItem( g_CurrentTrackSegment, false );
+ m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
+
+ if( g_Drc_On )
+ {
+ if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
+ {
+ return g_CurrentTrackSegment;
+ }
+ }
+ }
+ else // Track in progress : segment coordinates are updated by ShowNewTrackWhenMovingCursor.
+ {
+ // Test for a D.R.C. error:
+ if( g_Drc_On )
+ {
+ if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
+ return NULL;
+
+ // We must handle 2 segments
+ if( g_TwoSegmentTrackBuild && g_CurrentTrackSegment->Back() )
+ {
+ if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), GetBoard()->m_Track ) )
+ return NULL;
+ }
+ }
+
+ /* Current track is Ok: current segment is kept, and a new one is
+ * created unless the current segment is null, or 2 last are null
+ * if this is a 2 segments track build.
+ */
+ bool CanCreateNewSegment = true;
+
+ if( !g_TwoSegmentTrackBuild && g_CurrentTrackSegment->IsNull() )
+ CanCreateNewSegment = false;
+
+ if( g_TwoSegmentTrackBuild && g_CurrentTrackSegment->IsNull()
+ && g_CurrentTrackSegment->Back()
+ && g_CurrentTrackSegment->Back()->IsNull() )
+ CanCreateNewSegment = false;
+
+ if( CanCreateNewSegment )
+ {
+ // Erase old track on screen
+ DBG( g_CurrentTrackList.VerifyListIntegrity(); );
+
+ ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, false );
+
+ DBG( g_CurrentTrackList.VerifyListIntegrity(); );
+
+ if( g_Raccord_45_Auto )
+ Add45DegreeSegment( aDC );
+
+ TRACK* previousTrack = g_CurrentTrackSegment;
+
+ TRACK* newTrack = (TRACK*)g_CurrentTrackSegment->Clone();
+ g_CurrentTrackList.PushBack( newTrack );
+ newTrack->SetFlags( IS_NEW );
+
+ newTrack->SetState( BEGIN_ONPAD | END_ONPAD, false );
+
+ D_PAD* pad = GetBoard()->GetPad( previousTrack, ENDPOINT_END );
+
+ if( pad )
+ {
+ newTrack->m_PadsConnected.push_back( pad );
+ previousTrack->m_PadsConnected.push_back( pad );
+ }
+
+ newTrack->start = previousTrack->end;
+
+ DBG( g_CurrentTrackList.VerifyListIntegrity(); );
+
+ newTrack->SetStart( newTrack->GetEnd() );
+
+ newTrack->SetLayer( GetScreen()->m_Active_Layer );
+
+ if( !GetDesignSettings().m_UseConnectedTrackWidth )
+ newTrack->SetWidth( GetDesignSettings().GetCurrentTrackWidth() );
+
+ DBG( g_CurrentTrackList.VerifyListIntegrity(); );
+
+ // Show the new position
+ ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, false );
+ }
+ }
+
+ SetCurItem( g_CurrentTrackSegment, false );
+ return g_CurrentTrackSegment;
+}
+
+
+bool PCB_EDIT_FRAME::Add45DegreeSegment( wxDC* aDC )
+{
+ int dx0, dy0, dx1, dy1;
+
+ if( g_CurrentTrackList.GetCount() < 2 )
+ return false; // There must be 2 segments.
+
+ TRACK* curTrack = g_CurrentTrackSegment;
+ TRACK* prevTrack = curTrack->Back();
+
+ // Test if we have 2 consecutive track segments ( not via ) to connect.
+ if( curTrack->Type() != PCB_TRACE_T || prevTrack->Type() != PCB_TRACE_T )
+ {
+ return false;
+ }
+
+ int segm_step_45 = KiROUND( GetScreen()->GetGridSize().x / 2 );
+
+ if( segm_step_45 < ( curTrack->GetWidth() * 2 ) )
+ segm_step_45 = curTrack->GetWidth() * 2;
+
+ // Test if the segments are horizontal or vertical.
+ dx0 = prevTrack->GetEnd().x - prevTrack->GetStart().x;
+ dy0 = prevTrack->GetEnd().y - prevTrack->GetStart().y;
+
+ dx1 = curTrack->GetEnd().x - curTrack->GetStart().x;
+ dy1 = curTrack->GetEnd().y - curTrack->GetStart().y;
+
+ // Segments should have a min length.
+ if( std::max( abs( dx0 ), abs( dy0 ) ) < ( segm_step_45 * 2 ) )
+ return false;
+
+ if( std::max( abs( dx1 ), abs( dy1 ) ) < ( segm_step_45 * 2 ) )
+ return false;
+
+ // Create a new segment and connect it with the previous 2 segments.
+ TRACK* newTrack = (TRACK*)curTrack->Clone();
+
+ newTrack->SetStart( prevTrack->GetEnd() );
+ newTrack->SetEnd( curTrack->GetStart() );
+
+ if( dx0 == 0 ) // Previous segment is Vertical
+ {
+ if( dy1 != 0 ) // 2 segments are not 90 degrees.
+ {
+ delete newTrack;
+ return false;
+ }
+
+ /* Calculate coordinates the connection point.
+ * The new segment connects the 1st vertical segment and the 2nd
+ * horizontal segment.
+ */
+ if( dy0 > 0 )
+ newTrack->SetStart( wxPoint(newTrack->GetStart().x, newTrack->GetStart().y -segm_step_45) );
+ else
+ newTrack->SetStart( wxPoint(newTrack->GetStart().x, newTrack->GetStart().y + segm_step_45) );
+
+ if( dx1 > 0 )
+ newTrack->SetEnd( wxPoint(newTrack->GetEnd().x + segm_step_45, newTrack->GetEnd().y) );
+ else
+ newTrack->SetEnd( wxPoint(newTrack->GetEnd().x - segm_step_45, newTrack->GetEnd().y) );
+
+ if( g_Drc_On && BAD_DRC == m_drc->Drc( curTrack, GetBoard()->m_Track ) )
+ {
+ delete newTrack;
+ return false;
+ }
+
+ prevTrack->SetEnd( newTrack->GetStart());
+ curTrack->SetStart( newTrack->GetEnd());
+
+ g_CurrentTrackList.Insert( newTrack, curTrack );
+ return true;
+ }
+
+ if( dy0 == 0 ) // Previous segment is horizontal
+ {
+ if( dx1 != 0 ) // 2 segments are not 90 degrees
+ {
+ delete newTrack;
+ return false;
+ }
+
+ /* Calculate the coordinates of the point of connection:
+ * A new segment has been created, connecting segment 1
+ * (horizontal) and segment 2 (vertical)
+ */
+ if( dx0 > 0 )
+ newTrack->SetStart( wxPoint(newTrack->GetStart().x - segm_step_45 , newTrack->GetStart().y));
+ else
+ newTrack->SetStart( wxPoint(newTrack->GetStart().x + segm_step_45, newTrack->GetStart().y) );
+
+ if( dy1 > 0 )
+ newTrack->SetEnd( wxPoint(newTrack->GetEnd().x, newTrack->GetEnd().y + segm_step_45) );
+ else
+ newTrack->SetEnd( wxPoint(newTrack->GetEnd().x, newTrack->GetEnd().y - segm_step_45) );
+
+ if( g_Drc_On && BAD_DRC==m_drc->Drc( newTrack, GetBoard()->m_Track ) )
+ {
+ delete newTrack;
+ return false;
+ }
+
+ prevTrack->SetEnd( newTrack->GetStart());
+ curTrack->SetStart( newTrack->GetEnd());
+
+ g_CurrentTrackList.Insert( newTrack, curTrack );
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
+{
+ LSET layerMask( GetScreen()->m_Active_Layer );
+
+ if( aTrack == NULL )
+ return false;
+
+ if( g_Drc_On && BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
+ return false;
+
+ // Saving the coordinate of end point of the trace
+ wxPoint pos = g_CurrentTrackSegment->GetEnd();
+
+ DBG( g_CurrentTrackList.VerifyListIntegrity(); );
+
+ if( Begin_Route( aTrack, aDC ) == NULL )
+ return false;
+
+ ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, true );
+ ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, false );
+ TraceAirWiresToTargets( aDC );
+
+ /* cleanup
+ * if( g_CurrentTrackSegment->Next() != NULL )
+ * {
+ * delete g_CurrentTrackSegment->Next();
+ * g_CurrentTrackSegment->SetNext( NULL );
+ * }
+ */
+
+ DBG( g_CurrentTrackList.VerifyListIntegrity(); );
+
+
+ /* The track here is now chained to the list of track segments.
+ * It must be seen in the area of net
+ * As close as possible to the segment base (or end), because
+ * This helps to reduce the computing time */
+
+ // Attaching the end point of the new track to a pad or a track
+ BOARD_CONNECTED_ITEM* lockPoint = GetBoard()->GetLockPoint( pos, layerMask );
+
+ if( lockPoint )
+ {
+ if( lockPoint->Type() == PCB_PAD_T ) // End of track is on a pad.
+ {
+ EnsureEndTrackOnPad( (D_PAD*) lockPoint );
+ }
+ else // If end point of is on a different track,
+ // creates a lock point if not exists
+ {
+ // Creates a lock point, if not already exists:
+ wxPoint hp = g_CurrentTrackSegment->GetEnd();
+ lockPoint = GetBoard()->CreateLockPoint( hp, (TRACK*) lockPoint, &s_ItemsListPicker );
+ g_CurrentTrackSegment->SetEnd(hp);
+ }
+ }
+
+ // Delete null length segments:
+ DeleteNullTrackSegments( GetBoard(), g_CurrentTrackList );
+
+ // Insert new segments if they exist.
+ // g_FirstTrackSegment can be NULL on a double click on the starting point
+ if( g_FirstTrackSegment != NULL )
+ {
+ int netcode = g_FirstTrackSegment->GetNetCode();
+ TRACK* firstTrack = g_FirstTrackSegment;
+ int newCount = g_CurrentTrackList.GetCount();
+
+ // Put entire new current segment list in BOARD, and prepare undo command
+ TRACK* track;
+ TRACK* insertBeforeMe = g_CurrentTrackSegment->GetBestInsertPoint( GetBoard() );
+
+ while( ( track = g_CurrentTrackList.PopFront() ) != NULL )
+ {
+ ITEM_PICKER picker( track, UR_NEW );
+ s_ItemsListPicker.PushItem( picker );
+ GetBoard()->m_Track.Insert( track, insertBeforeMe );
+ }
+
+ TraceAirWiresToTargets( aDC );
+
+ int i = 0;
+
+ for( track = firstTrack; track && i < newCount; ++i, track = track->Next() )
+ {
+ track->ClearFlags();
+ track->SetState( BUSY, false );
+ }
+
+ // delete the old track, if it exists and is redundant
+ if( g_AutoDeleteOldTrack )
+ {
+ EraseRedundantTrack( aDC, firstTrack, newCount, &s_ItemsListPicker );
+ }
+
+ SaveCopyInUndoList( s_ItemsListPicker, UR_UNSPECIFIED );
+ s_ItemsListPicker.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
+
+ // compute the new ratsnest
+ TestNetConnection( aDC, netcode );
+ OnModify();
+ SetMsgPanel( GetBoard() );
+
+ // Redraw the entire new track.
+ DrawTraces( m_canvas, aDC, firstTrack, newCount, GR_OR );
+ }
+
+ wxASSERT( g_FirstTrackSegment == NULL );
+ wxASSERT( g_CurrentTrackSegment == NULL );
+ wxASSERT( g_CurrentTrackList.GetCount() == 0 );
+
+ if( GetBoard()->IsHighLightNetON() )
+ HighLight( aDC );
+
+ GetBoard()->PopHighLight();
+
+ if( GetBoard()->IsHighLightNetON() )
+ GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() );
+
+ m_canvas->SetMouseCapture( NULL, NULL );
+ SetCurItem( NULL );
+
+ return true;
+}
+
+
+TRACK* LocateIntrusion( TRACK* listStart, TRACK* aTrack, LAYER_NUM aLayer, const wxPoint& aRef )
+{
+ int net = aTrack->GetNetCode();
+ int width = aTrack->GetWidth();
+
+ TRACK* found = NULL;
+
+ for( TRACK* track = listStart; track; track = track->Next() )
+ {
+ if( track->Type() == PCB_TRACE_T ) // skip vias
+ {
+ if( track->GetState( BUSY | IS_DELETED ) )
+ continue;
+
+ if( aLayer != track->GetLayer() )
+ continue;
+
+ if( track->GetNetCode() == net )
+ continue;
+
+ // TRACK::HitTest
+ int dist = (width + track->GetWidth()) / 2 + aTrack->GetClearance( track );
+
+ if( !TestSegmentHit( aRef, track->GetStart(), track->GetEnd(), dist ) )
+ continue;
+
+ found = track;
+
+ // prefer intrusions from the side, not the end
+ wxPoint pos = aRef - track->GetStart();
+ wxPoint vec = track->GetEnd() - track->GetStart();
+ double tmp = (double) pos.x * vec.x + (double) pos.y * vec.y;
+
+ if( tmp >= 0 && tmp <= (double) vec.x * vec.x + (double) vec.y * vec.y )
+ break;
+ }
+ }
+
+ return found;
+}
+
+
+/**
+ * Function PushTrack
+ * detects if the mouse is pointing into a conflicting track.
+ * In this case, it tries to push the new track out of the conflicting track's
+ * clearance zone. This gives us a cheap mechanism for drawing tracks that
+ * tightly follow others, independent of grid settings.
+ *
+ * KNOWN BUGS:
+ * - we do the same sort of search and calculation up to three times:
+ * 1) we search for magnetic hits (in controle.cpp)
+ * 2) we check if there's a DRC violation in the making (also controle.cpp)
+ * 3) we try to fix the DRC violation (here)
+ * - if we have a magnetic hit and a DRC violation at the same time, we choose
+ * the magnetic hit instead of solving the violation
+ * - should locate conflicting tracks also when we're crossing over them
+ */
+static void PushTrack( EDA_DRAW_PANEL* panel )
+{
+ PCB_SCREEN* screen = (PCB_SCREEN*) panel->GetParent()->GetScreen();
+ BOARD* pcb = ( (PCB_BASE_FRAME*) (panel->GetParent()) )->GetBoard();
+ wxPoint cursor = panel->GetParent()->GetCrossHairPosition();
+ wxPoint cv, vec, n;
+ TRACK* track = g_CurrentTrackSegment;
+ TRACK* other;
+ double det;
+ int dist;
+ double f;
+
+ other = LocateIntrusion( pcb->m_Track, track, screen->m_Active_Layer, panel->GetParent()->RefPos( true ) );
+
+ // are we currently pointing into a conflicting trace ?
+ if( !other )
+ return;
+
+ if( other->GetNetCode() == track->GetNetCode() )
+ return;
+
+ cv = cursor - other->GetStart();
+ vec = other->GetEnd() - other->GetStart();
+
+ det = (double) cv.x * vec.y - (double) cv.y * vec.x;
+
+ // cursor is right at the center of the old track
+ if( !det )
+ return;
+
+ dist = (track->GetWidth() + 1) / 2 + (other->GetWidth() + 1) / 2 + track->GetClearance( other ) + 2;
+
+ /*
+ * DRC wants >, so +1.
+ * We may have a quantization error of 1/sqrt(2), so +1 again.
+ */
+
+ // Vector "n" is perpendicular to "other", pointing towards the cursor.
+ if( det > 0 )
+ {
+ n.x = vec.y;
+ n.y = -vec.x;
+ }
+ else
+ {
+ n.x = -vec.y;
+ n.y = vec.x;
+ }
+
+ f = dist / hypot( double(n.x), double(n.y) );
+ n.x = KiROUND( f * n.x );
+ n.y = KiROUND( f * n.y );
+
+ wxPoint hp = track->GetEnd();
+ Project( &hp, cursor, other );
+ track->SetEnd( hp + n );
+}
+
+
+//Helper function: Draws Via circle and Via Clearance circle.
+inline void DrawViaCirclesWhenEditingNewTrack( EDA_RECT* aPanelClipBox,
+ wxDC* aDC, const wxPoint& aPos,
+ int aViaRadius,
+ int aViaRadiusWithClearence,
+ EDA_COLOR_T aColor)
+{
+ //Current viasize clearence circle
+ GRCircle( aPanelClipBox, aDC, aPos.x, aPos.y, aViaRadiusWithClearence, aColor );
+ //Current viasize circle
+ GRCircle( aPanelClipBox, aDC, aPos.x, aPos.y, aViaRadius, aColor );
+}
+
+/* Redraw the current track being created when the mouse cursor is moved
+ */
+void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+// DBG( g_CurrentTrackList.VerifyListIntegrity(); );
+
+ PCB_SCREEN* screen = (PCB_SCREEN*) aPanel->GetScreen();
+ PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) aPanel->GetDisplayOptions();
+
+ bool tmp = displ_opts->m_DisplayPcbTrackFill;
+ displ_opts->m_DisplayPcbTrackFill = true;
+ TRACE_CLEARANCE_DISPLAY_MODE_T showTrackClearanceMode = displ_opts->m_ShowTrackClearanceMode;
+
+ if ( g_FirstTrackSegment == NULL )
+ return;
+
+ NETCLASSPTR netclass = g_FirstTrackSegment->GetNetClass();
+
+ if( showTrackClearanceMode != DO_NOT_SHOW_CLEARANCE )
+ displ_opts->m_ShowTrackClearanceMode = SHOW_CLEARANCE_ALWAYS;
+
+ // Values to Via circle
+ int boardViaRadius = frame->GetDesignSettings().GetCurrentViaSize()/2;
+ int viaRadiusWithClearence = boardViaRadius+netclass->GetClearance();
+ EDA_RECT* panelClipBox=aPanel->GetClipBox();
+
+#ifndef USE_WX_OVERLAY
+ // Erase old track
+ if( aErase )
+ {
+ DrawTraces( aPanel, aDC, g_FirstTrackSegment, g_CurrentTrackList.GetCount(), GR_XOR );
+
+ frame->TraceAirWiresToTargets( aDC );
+
+ if( showTrackClearanceMode >= SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS )
+ {
+ EDA_COLOR_T color = g_ColorsSettings.GetLayerColor( g_CurrentTrackSegment->GetLayer() );
+ DrawViaCirclesWhenEditingNewTrack( panelClipBox, aDC, g_CurrentTrackSegment->GetEnd(),
+ boardViaRadius, viaRadiusWithClearence, color);
+ }
+ }
+#endif
+ // MacOSX seems to need this.
+ if( g_CurrentTrackList.GetCount() == 0 )
+ return;
+
+ // Set track parameters, that can be modified while creating the track
+ g_CurrentTrackSegment->SetLayer( screen->m_Active_Layer );
+
+ if( !frame->GetDesignSettings().m_UseConnectedTrackWidth )
+ g_CurrentTrackSegment->SetWidth( frame->GetDesignSettings().GetCurrentTrackWidth() );
+
+ if( g_TwoSegmentTrackBuild )
+ {
+ TRACK* previous_track = g_CurrentTrackSegment->Back();
+
+ if( previous_track && previous_track->Type()==PCB_TRACE_T )
+ {
+ previous_track->SetLayer( screen->m_Active_Layer );
+
+ if( !frame->GetDesignSettings().m_UseConnectedTrackWidth )
+ previous_track->SetWidth( frame->GetDesignSettings().GetCurrentTrackWidth() );
+ }
+ }
+
+ if( g_Track_45_Only_Allowed )
+ {
+ if( g_TwoSegmentTrackBuild )
+ {
+ g_CurrentTrackSegment->SetEnd( frame->GetCrossHairPosition() );
+
+ if( g_Drc_On )
+ PushTrack( aPanel );
+
+ ComputeBreakPoint( g_CurrentTrackSegment,
+ g_CurrentTrackList.GetCount(),
+ g_CurrentTrackSegment->GetEnd() );
+ }
+ else
+ {
+ /* Calculate of the end of the path for the permitted directions:
+ * horizontal, vertical or 45 degrees.
+ */
+ wxPoint hp = g_CurrentTrackSegment->GetEnd();
+ CalculateSegmentEndPoint( frame->GetCrossHairPosition(),
+ g_CurrentTrackSegment->GetStart().x,
+ g_CurrentTrackSegment->GetStart().y,
+ &hp.x,
+ &hp.y );
+ g_CurrentTrackSegment->SetEnd(hp);
+ }
+ }
+ else // Here the angle is arbitrary
+ {
+ g_CurrentTrackSegment->SetEnd( frame->GetCrossHairPosition() );
+ }
+
+ // Redraw the new track
+ DBG( g_CurrentTrackList.VerifyListIntegrity(); );
+ DrawTraces( aPanel, aDC, g_FirstTrackSegment, g_CurrentTrackList.GetCount(), GR_XOR );
+
+ if( showTrackClearanceMode >= SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS )
+ {
+ EDA_COLOR_T color = g_ColorsSettings.GetLayerColor(g_CurrentTrackSegment->GetLayer());
+
+ //Via diameter must have taken what we are using, rather than netclass value.
+ DrawViaCirclesWhenEditingNewTrack( panelClipBox, aDC, g_CurrentTrackSegment->GetEnd(),
+ boardViaRadius, viaRadiusWithClearence, color);
+
+ }
+
+ /* Display info about current segment and the full new track:
+ * Choose the interesting segment: because we are using a 2 segments step,
+ * the last segment can be null, and the previous segment can be the
+ * interesting segment.
+ */
+ TRACK* isegm = g_CurrentTrackSegment;
+
+ if( isegm->GetLength() == 0 && g_CurrentTrackSegment->Back() )
+ isegm = g_CurrentTrackSegment->Back();
+
+ // display interesting segment info only:
+ frame->SetMsgPanel( isegm );
+
+ // Display current track length (on board) and the the actual track len
+ // if there is an extra len due to the len die on the starting pad (if any)
+ double trackLen = 0.0;
+ double lenPadToDie = 0.0;
+ wxString msg;
+
+ // If the starting point is on a pad, add current track length+ length die
+ if( g_FirstTrackSegment->GetState( BEGIN_ONPAD ) )
+ {
+ D_PAD * pad = (D_PAD *) g_FirstTrackSegment->start;
+ lenPadToDie = (double) pad->GetPadToDieLength();
+ }
+
+ // calculate track len on board:
+ for( TRACK* track = g_FirstTrackSegment; track; track = track->Next() )
+ trackLen += track->GetLength();
+
+ msg = frame->LengthDoubleToString( trackLen );
+ frame->AppendMsgPanel( _( "Track Len" ), msg, DARKCYAN );
+
+ if( lenPadToDie != 0 ) // display the track len on board and the actual track len
+ {
+ frame->AppendMsgPanel( _( "Full Len" ), msg, DARKCYAN );
+ msg = frame->LengthDoubleToString( trackLen+lenPadToDie );
+ frame->AppendMsgPanel( _( "Pad to die" ), msg, DARKCYAN );
+ }
+
+ // Add current segments count (number of segments in this new track):
+ msg.Printf( wxT( "%d" ), g_CurrentTrackList.GetCount() );
+ frame->AppendMsgPanel( _( "Segs Count" ), msg, DARKCYAN );
+
+ displ_opts->m_ShowTrackClearanceMode = showTrackClearanceMode;
+ displ_opts->m_DisplayPcbTrackFill = tmp;
+
+ frame->BuildAirWiresTargetsList( NULL, g_CurrentTrackSegment->GetEnd(), false );
+ frame->TraceAirWiresToTargets( aDC );
+}
+
+
+/* Determine the coordinate to advanced the the current segment
+ * in 0, 90, or 45 degrees, depending on position of origin and \a aPosition.
+ */
+void CalculateSegmentEndPoint( const wxPoint& aPosition, int ox, int oy, int* fx, int* fy )
+{
+ int deltax, deltay, angle;
+
+ deltax = aPosition.x - ox;
+ deltay = aPosition.y - oy;
+
+ deltax = abs( deltax );
+ deltay = abs( deltay );
+ angle = 45;
+
+ if( deltax >= deltay )
+ {
+ if( deltax == 0 )
+ angle = 0;
+ else if( ( (deltay << 6 ) / deltax ) < 26 )
+ angle = 0;
+ }
+ else
+ {
+ angle = 45;
+
+ if( deltay == 0 )
+ angle = 90;
+ else if( ( (deltax << 6 ) / deltay ) < 26 )
+ angle = 90;
+ }
+
+ switch( angle )
+ {
+ case 0:
+ *fx = aPosition.x;
+ *fy = oy;
+ break;
+
+ case 45:
+ deltax = std::min( deltax, deltay );
+ deltay = deltax;
+
+ // Recalculate the signs for deltax and deltaY.
+ if( ( aPosition.x - ox ) < 0 )
+ deltax = -deltax;
+
+ if( ( aPosition.y - oy ) < 0 )
+ deltay = -deltay;
+
+ *fx = ox + deltax;
+ *fy = oy + deltay;
+ break;
+
+ case 90:
+ *fx = ox;
+ *fy = aPosition.y;
+ break;
+ }
+}
+
+
+/**
+ * Compute new track angle based on previous track.
+ */
+void ComputeBreakPoint( TRACK* track, int SegmentCount, wxPoint end )
+{
+ int iDx = 0;
+ int iDy = 0;
+ int iAngle = 0;
+
+ if( SegmentCount <= 0 )
+ return;
+
+ if( track == NULL )
+ return;
+
+ TRACK* newTrack = track;
+ track = track->Back();
+ SegmentCount--;
+
+ if( track )
+ {
+ iDx = end.x - track->GetStart().x;
+ iDy = end.y - track->GetStart().y;
+
+ iDx = abs( iDx );
+ iDy = abs( iDy );
+ }
+
+ TRACK* lastTrack = track ? track->Back() : NULL;
+
+ if( lastTrack )
+ {
+ if(( (lastTrack->GetEnd().x == lastTrack->GetStart().x)
+ || (lastTrack->GetEnd().y == lastTrack->GetStart().y) )
+ && !g_Alternate_Track_Posture)
+ {
+ iAngle = 45;
+ }
+ }
+ else
+ {
+ if( g_Alternate_Track_Posture )
+ {
+ iAngle = 45;
+ }
+ }
+
+ if( iAngle == 0 )
+ {
+ if( iDx >= iDy )
+ iAngle = 0;
+ else
+ iAngle = 90;
+ }
+
+ if( track == NULL )
+ iAngle = -1;
+
+ switch( iAngle )
+ {
+ case -1:
+ break;
+
+ case 0:
+ if( ( end.x - track->GetStart().x ) < 0 )
+ track->SetEnd(wxPoint( end.x + iDy, track->GetStart().y));
+ else
+ track->SetEnd(wxPoint( end.x - iDy, track->GetStart().y));
+ break;
+
+ case 45:
+ iDx = std::min( iDx, iDy );
+ iDy = iDx;
+
+ // Recalculate the signs for deltax and deltaY.
+ if( ( end.x - track->GetStart().x ) < 0 )
+ iDx = -iDx;
+
+ if( ( end.y - track->GetStart().y ) < 0 )
+ iDy = -iDy;
+
+ track->SetEnd(wxPoint(track->GetStart().x + iDx, track->GetStart().y + iDy));
+ break;
+
+ case 90:
+ if( ( end.y - track->GetStart().y ) < 0 )
+ track->SetEnd(wxPoint(track->GetStart().x , end.y + iDx));
+ else
+ track->SetEnd(wxPoint(track->GetStart().x , end.y - iDx));
+ break;
+ }
+
+ if( track )
+ {
+ if( track->IsNull() )
+ track->SetEnd( end );
+
+ newTrack->SetStart( track->GetEnd() );
+ }
+
+ newTrack->SetEnd( end );
+}
+
+
+/* Delete track segments which have len = 0 after creating a new track
+ * return a pointer on the first segment (start of track list)
+ */
+void DeleteNullTrackSegments( BOARD* pcb, DLIST<TRACK>& aTrackList )
+{
+ if( aTrackList.GetCount() == 0 )
+ return;
+
+ TRACK* track = aTrackList.GetFirst();
+ TRACK* firsttrack = track;
+ TRACK* oldtrack;
+
+ BOARD_CONNECTED_ITEM* lockPoint = track->start;
+
+ while( track != NULL )
+ {
+ oldtrack = track;
+ track = track->Next();
+
+ if( !oldtrack->IsNull() )
+ {
+ continue;
+ }
+
+ // NULL segment, delete it
+ if( firsttrack == oldtrack )
+ firsttrack = track;
+
+ delete aTrackList.Remove( oldtrack );
+ }
+
+ if( aTrackList.GetCount() == 0 )
+ return; // all the new track segments have been deleted
+
+ // we must set the pointers on connected items and the connection status
+ oldtrack = track = firsttrack;
+ firsttrack->start = NULL;
+
+ while( track != NULL )
+ {
+ oldtrack = track;
+ track = track->Next();
+ oldtrack->end = track;
+
+ if( track )
+ track->start = oldtrack;
+
+ oldtrack->SetStatus( 0 );
+ }
+
+ firsttrack->start = lockPoint;
+
+ if( lockPoint && lockPoint->Type()==PCB_PAD_T )
+ firsttrack->SetState( BEGIN_ONPAD, true );
+
+ track = firsttrack;
+
+ while( track != NULL )
+ {
+ TRACK* next_track = track->Next();
+ lockPoint = pcb->GetPad( track, ENDPOINT_END );
+
+ if( lockPoint )
+ {
+ track->end = lockPoint;
+ track->SetState( END_ONPAD, true );
+
+ if( next_track )
+ {
+ next_track->start = lockPoint;
+ next_track->SetState( BEGIN_ONPAD, true );
+ }
+ }
+
+ track = next_track;
+ }
+}
+
+
+/* Ensure the end point of g_CurrentTrackSegment is on the pad "Pad"
+ * if no, create a new track segment if necessary
+ * and move current (or new) end segment on pad
+ */
+void EnsureEndTrackOnPad( D_PAD* aPad )
+{
+ if( g_CurrentTrackSegment->GetEnd() == aPad->GetPosition() ) // Ok !
+ {
+ g_CurrentTrackSegment->end = aPad;
+ g_CurrentTrackSegment->SetState( END_ONPAD, true );
+ return;
+ }
+
+ TRACK* lasttrack = g_CurrentTrackSegment;
+
+ if( !g_CurrentTrackSegment->IsNull() )
+ {
+ // Must create a new segment, from track end to pad center
+ g_CurrentTrackList.PushBack( (TRACK*)lasttrack->Clone() );
+
+ lasttrack->end = g_CurrentTrackSegment;
+ }
+
+ g_CurrentTrackSegment->SetEnd( aPad->GetPosition() );
+ g_CurrentTrackSegment->SetState( END_ONPAD, false );
+
+ g_CurrentTrackSegment->end = aPad;
+ g_CurrentTrackSegment->SetState( END_ONPAD, true );
+}
diff --git a/pcbnew/edtxtmod.cpp b/pcbnew/edtxtmod.cpp
new file mode 100644
index 0000000..733183f
--- /dev/null
+++ b/pcbnew/edtxtmod.cpp
@@ -0,0 +1,343 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file edtxtmod.cpp
+ * @brief Edit module text.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <drawtxt.h>
+#include <trigo.h>
+#include <wxBasePcbFrame.h>
+#include <macros.h>
+
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <module_editor_frame.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_text_mod.h>
+#include <class_pcb_text.h>
+
+
+static void Show_MoveTexte_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase );
+static void AbortMoveTextModule( EDA_DRAW_PANEL* Panel, wxDC* DC );
+
+
+wxPoint MoveVector; // Move vector for move edge, exported
+ // to dialog_edit mod_text.cpp
+static wxPoint TextInitialPosition; // Mouse cursor initial position for
+ // undo/abort move command
+static double TextInitialOrientation; // module text initial orientation for
+ // undo/abort move+rot command+rot
+
+
+/* Add a new graphical text to the active module (footprint)
+ * Note there always are 2 mandatory texts: reference and value.
+ * New texts have the member TEXTE_MODULE.GetType() set to TEXT_is_DIVERS
+ */
+TEXTE_MODULE* FOOTPRINT_EDIT_FRAME::CreateTextModule( MODULE* aModule, wxDC* aDC )
+{
+ TEXTE_MODULE* text = new TEXTE_MODULE( aModule );
+
+ text->SetFlags( IS_NEW );
+
+ GetDesignSettings().m_ModuleTextWidth = Clamp_Text_PenSize( GetDesignSettings().m_ModuleTextWidth,
+ std::min( GetDesignSettings().m_ModuleTextSize.x, GetDesignSettings().m_ModuleTextSize.y ), true );
+ text->SetSize( GetDesignSettings().m_ModuleTextSize );
+ text->SetThickness( GetDesignSettings().m_ModuleTextWidth );
+ text->SetPosition( GetCrossHairPosition() );
+
+ if( LSET::AllTechMask().test( GetActiveLayer() ) ) // i.e. a possible layer for a text
+ text->SetLayer( GetActiveLayer() );
+
+ InstallTextModOptionsFrame( text, NULL );
+
+ m_canvas->MoveCursorToCrossHair();
+
+ if( text->GetText().IsEmpty() )
+ {
+ delete text;
+ return NULL;
+ }
+
+ // Add the new text object to the beginning of the footprint draw list.
+ if( aModule )
+ aModule->GraphicalItems().PushFront( text );
+
+ text->ClearFlags();
+
+ if( aDC )
+ text->Draw( m_canvas, aDC, GR_OR );
+
+ SetMsgPanel( text );
+
+ return text;
+}
+
+
+/* Rotate text 90 degrees.
+ */
+void PCB_BASE_FRAME::RotateTextModule( TEXTE_MODULE* Text, wxDC* DC )
+{
+ if( Text == NULL )
+ return;
+
+ MODULE* module = (MODULE*) Text->GetParent();
+
+ if( module && module->GetFlags() == 0 && Text->GetFlags() == 0 ) // prepare undo command
+ {
+ if( IsType( FRAME_PCB ) )
+ SaveCopyInUndoList( module, UR_CHANGED );
+ }
+
+ // we expect MoveVector to be (0,0) if there is no move in progress
+ Text->Draw( m_canvas, DC, GR_XOR, MoveVector );
+
+ Text->SetOrientation( Text->GetOrientation() + 900 );
+
+ Text->Draw( m_canvas, DC, GR_XOR, MoveVector );
+ SetMsgPanel( Text );
+
+ if( module )
+ module->SetLastEditTime();
+
+ OnModify();
+}
+
+
+/*
+ * Deletes text in module (if not the reference or value)
+ */
+void PCB_BASE_FRAME::DeleteTextModule( TEXTE_MODULE* Text )
+{
+ MODULE* Module;
+
+ if( Text == NULL )
+ return;
+
+ Module = static_cast<MODULE*>( Text->GetParent() );
+
+ if( Text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
+ {
+ m_canvas->RefreshDrawingRect( Text->GetBoundingBox() );
+ Text->DeleteStructure();
+ OnModify();
+ Module->SetLastEditTime();
+ }
+}
+
+
+/*
+ * Abort text move in progress.
+ *
+ * If a text is selected, its initial coordinates are regenerated.
+ */
+static void AbortMoveTextModule( EDA_DRAW_PANEL* Panel, wxDC* DC )
+{
+ BASE_SCREEN* screen = Panel->GetScreen();
+ TEXTE_MODULE* Text = static_cast<TEXTE_MODULE*>( screen->GetCurItem() );
+ MODULE* Module;
+
+ Panel->SetMouseCapture( NULL, NULL );
+
+ if( Text == NULL )
+ return;
+
+ Module = static_cast<MODULE*>( Text->GetParent() );
+
+ Text->DrawUmbilical( Panel, DC, GR_XOR, -MoveVector );
+ Text->Draw( Panel, DC, GR_XOR, MoveVector );
+
+ // If the text was moved (the move does not change internal data)
+ // it could be rotated while moving. So set old value for orientation
+ if( Text->IsMoving() )
+ Text->SetOrientation( TextInitialOrientation );
+
+ // Redraw the text
+ Panel->RefreshDrawingRect( Text->GetBoundingBox() );
+
+ // leave it at (0,0) so we can use it Rotate when not moving.
+ MoveVector.x = MoveVector.y = 0;
+
+ Text->ClearFlags();
+ Module->ClearFlags();
+
+ screen->SetCurItem( NULL );
+}
+
+
+/* Start a text move.
+ */
+void PCB_BASE_FRAME::StartMoveTexteModule( TEXTE_MODULE* Text, wxDC* DC )
+{
+ if( Text == NULL )
+ return;
+
+ MODULE *Module = static_cast<MODULE*>( Text->GetParent() );
+
+ Text->SetFlags( IS_MOVED );
+ Module->SetFlags( IN_EDIT );
+
+ MoveVector.x = MoveVector.y = 0;
+
+ TextInitialPosition = Text->GetTextPosition();
+ TextInitialOrientation = Text->GetOrientation();
+
+ // Center cursor on initial position of text
+ SetCrossHairPosition( TextInitialPosition );
+ m_canvas->MoveCursorToCrossHair();
+
+ SetMsgPanel( Text );
+ SetCurItem( Text );
+ m_canvas->SetMouseCapture( Show_MoveTexte_Module, AbortMoveTextModule );
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, true );
+}
+
+
+/* Place the text a the cursor position when the left mouse button is clicked.
+ */
+void PCB_BASE_FRAME::PlaceTexteModule( TEXTE_MODULE* Text, wxDC* DC )
+{
+ if( Text != NULL )
+ {
+ m_canvas->RefreshDrawingRect( Text->GetBoundingBox() );
+ Text->DrawUmbilical( m_canvas, DC, GR_XOR, -MoveVector );
+
+ // Update the coordinates for anchor.
+ MODULE* Module = static_cast<MODULE*>( Text->GetParent() );
+
+ if( Module )
+ {
+ // Prepare undo command (a rotation can be made while moving)
+ double tmp = Text->GetOrientation();
+ Text->SetOrientation( TextInitialOrientation );
+
+ if( IsType( FRAME_PCB ) )
+ SaveCopyInUndoList( Module, UR_CHANGED );
+ else
+ SaveCopyInUndoList( Module, UR_MODEDIT );
+
+ Text->SetOrientation( tmp );
+
+ // Set the new position for text.
+ Text->SetTextPosition( GetCrossHairPosition() );
+ wxPoint textRelPos = Text->GetTextPosition() - Module->GetPosition();
+ RotatePoint( &textRelPos, -Module->GetOrientation() );
+ Text->SetPos0( textRelPos );
+ Text->ClearFlags();
+ Module->ClearFlags();
+ Module->SetLastEditTime();
+ OnModify();
+
+ // Redraw text.
+ m_canvas->RefreshDrawingRect( Text->GetBoundingBox() );
+ }
+ else
+ {
+ Text->SetTextPosition( GetCrossHairPosition() );
+ }
+ }
+
+ // leave it at (0,0) so we can use it Rotate when not moving.
+ MoveVector.x = MoveVector.y = 0;
+
+ m_canvas->SetMouseCapture( NULL, NULL );
+}
+
+
+static void Show_MoveTexte_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ BASE_SCREEN* screen = aPanel->GetScreen();
+ TEXTE_MODULE* Text = static_cast<TEXTE_MODULE*>( screen->GetCurItem() );
+
+ if( Text == NULL )
+ return;
+
+ // Erase umbilical and text if necessary
+ if( aErase )
+ {
+ Text->DrawUmbilical( aPanel, aDC, GR_XOR, -MoveVector );
+ Text->Draw( aPanel, aDC, GR_XOR, MoveVector );
+ }
+
+ MoveVector = TextInitialPosition - aPanel->GetParent()->GetCrossHairPosition();
+
+ // Draw umbilical if text moved
+ if( MoveVector.x || MoveVector.y )
+ Text->DrawUmbilical( aPanel, aDC, GR_XOR, -MoveVector );
+
+ // Redraw text
+ Text->Draw( aPanel, aDC, GR_XOR, MoveVector );
+}
+
+void PCB_BASE_FRAME::ResetTextSize( BOARD_ITEM* aItem, wxDC* aDC )
+{
+ wxSize newSize;
+ int newThickness;
+
+ if( aItem->Type() == PCB_TEXT_T )
+ {
+ newSize = GetDesignSettings().m_PcbTextSize;
+ newThickness = GetDesignSettings().m_PcbTextWidth;
+ TEXTE_PCB* text = static_cast<TEXTE_PCB*>( aItem );
+
+ // Exit if there's nothing to do
+ if( text->GetSize() == newSize && text->GetThickness() == newThickness )
+ return;
+
+ SaveCopyInUndoList( text, UR_CHANGED );
+ text->SetSize( newSize );
+ text->SetThickness( newThickness );
+ }
+
+ else if( aItem->Type() == PCB_MODULE_TEXT_T )
+ {
+ newSize = GetDesignSettings().m_ModuleTextSize;
+ newThickness = GetDesignSettings().m_ModuleTextWidth;
+ TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( aItem );
+
+ // Exit if there's nothing to do
+ if( text->GetSize() == newSize && text->GetThickness() == newThickness )
+ return;
+
+ SaveCopyInUndoList( text->GetParent(), UR_CHANGED );
+ text->SetSize( newSize );
+ text->SetThickness( newThickness );
+ }
+ else
+ return;
+
+ if( aDC )
+ m_canvas->Refresh();
+
+ OnModify();
+}
diff --git a/pcbnew/event_handlers_tracks_vias_sizes.cpp b/pcbnew/event_handlers_tracks_vias_sizes.cpp
new file mode 100644
index 0000000..3361f4b
--- /dev/null
+++ b/pcbnew/event_handlers_tracks_vias_sizes.cpp
@@ -0,0 +1,146 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file event_handlers_tracks_vias_sizes.cpp
+ * @brief Handlers for popup and toolbars events relative to the tracks and vias sizes.
+ */
+
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <dialog_helpers.h>
+
+#include <pcbnew_id.h>
+#include <pcbnew.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+
+/* Event handler for tracks and vias size selection (and some options)
+ * relative to toolbars and popup events
+ */
+void PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event( wxCommandEvent& event )
+{
+ int ii;
+ int id = event.GetId();
+
+ /* Note: none of these events require aborting the current command (if any)
+ * (like move, edit or block command)
+ * so we do not test for a current command in progress and call
+ * m_canvas->m_endMouseCaptureCallback( m_canvas, &dc );
+ */
+ switch( id )
+ {
+ case ID_AUX_TOOLBAR_PCB_SELECT_AUTO_WIDTH:
+ GetDesignSettings().m_UseConnectedTrackWidth =
+ not GetDesignSettings().m_UseConnectedTrackWidth;
+ break;
+
+ case ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES:
+ GetDesignSettings().m_UseConnectedTrackWidth = false;
+ GetDesignSettings().SetTrackWidthIndex( 0 );
+ GetDesignSettings().SetViaSizeIndex( 0 );
+ break;
+
+ case ID_POPUP_PCB_SELECT_AUTO_WIDTH:
+ m_canvas->MoveCursorToCrossHair();
+ GetDesignSettings().m_UseConnectedTrackWidth = true;
+ break;
+
+ case ID_POPUP_PCB_SELECT_WIDTH1: // this is the default Netclass selection
+ case ID_POPUP_PCB_SELECT_WIDTH2: // this is a custom value selection
+ case ID_POPUP_PCB_SELECT_WIDTH3:
+ case ID_POPUP_PCB_SELECT_WIDTH4:
+ case ID_POPUP_PCB_SELECT_WIDTH5:
+ case ID_POPUP_PCB_SELECT_WIDTH6:
+ case ID_POPUP_PCB_SELECT_WIDTH7:
+ case ID_POPUP_PCB_SELECT_WIDTH8:
+ case ID_POPUP_PCB_SELECT_WIDTH9:
+ case ID_POPUP_PCB_SELECT_WIDTH10:
+ case ID_POPUP_PCB_SELECT_WIDTH11:
+ case ID_POPUP_PCB_SELECT_WIDTH12:
+ case ID_POPUP_PCB_SELECT_WIDTH13:
+ case ID_POPUP_PCB_SELECT_WIDTH14:
+ case ID_POPUP_PCB_SELECT_WIDTH15:
+ case ID_POPUP_PCB_SELECT_WIDTH16:
+ m_canvas->MoveCursorToCrossHair();
+ GetDesignSettings().m_UseConnectedTrackWidth = false;
+ ii = id - ID_POPUP_PCB_SELECT_WIDTH1;
+ GetDesignSettings().SetTrackWidthIndex( ii );
+ break;
+
+ case ID_POPUP_PCB_SELECT_VIASIZE1: // this is the default Netclass selection
+ case ID_POPUP_PCB_SELECT_VIASIZE2: // this is a custom value selection
+ case ID_POPUP_PCB_SELECT_VIASIZE3:
+ case ID_POPUP_PCB_SELECT_VIASIZE4:
+ case ID_POPUP_PCB_SELECT_VIASIZE5:
+ case ID_POPUP_PCB_SELECT_VIASIZE6:
+ case ID_POPUP_PCB_SELECT_VIASIZE7:
+ case ID_POPUP_PCB_SELECT_VIASIZE8:
+ case ID_POPUP_PCB_SELECT_VIASIZE9:
+ case ID_POPUP_PCB_SELECT_VIASIZE10:
+ case ID_POPUP_PCB_SELECT_VIASIZE11:
+ case ID_POPUP_PCB_SELECT_VIASIZE12:
+ case ID_POPUP_PCB_SELECT_VIASIZE13:
+ case ID_POPUP_PCB_SELECT_VIASIZE14:
+ case ID_POPUP_PCB_SELECT_VIASIZE15:
+ case ID_POPUP_PCB_SELECT_VIASIZE16:
+ // select the new current value for via size (via diameter)
+ m_canvas->MoveCursorToCrossHair();
+ ii = id - ID_POPUP_PCB_SELECT_VIASIZE1;
+ GetDesignSettings().SetViaSizeIndex( ii );
+ break;
+
+ case ID_AUX_TOOLBAR_PCB_TRACK_WIDTH:
+ ii = m_SelTrackWidthBox->GetCurrentSelection();
+ GetDesignSettings().SetTrackWidthIndex( ii );
+ break;
+
+ case ID_AUX_TOOLBAR_PCB_VIA_SIZE:
+ ii = m_SelViaSizeBox->GetCurrentSelection();
+ GetDesignSettings().SetViaSizeIndex( ii );
+ break;
+
+ default:
+ wxMessageBox( wxT( "PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event() error") );
+ break;
+ }
+
+ // Refresh track in progress, if any, by forcing a mouse event,
+ // to call the current function attached to the mouse
+ /*if( m_canvas->IsMouseCaptured() )
+ {
+ wxMouseEvent event(wxEVT_MOTION);
+ wxPostEvent( m_canvas, event );
+ }*/
+ //+hp
+ //Refresh canvas, that we can see changes instantly. I use this because it dont,t throw mouse up-left corner.
+
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->Refresh();
+}
diff --git a/pcbnew/exporters/export_d356.cpp b/pcbnew/exporters/export_d356.cpp
new file mode 100644
index 0000000..ed9ed98
--- /dev/null
+++ b/pcbnew/exporters/export_d356.cpp
@@ -0,0 +1,397 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011-2013 Lorenzo Marcantonio <l.marcantonio@logossrl.com>
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file export_d356.cpp
+ * @brief Export IPC-D-356 test format
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <kiface_i.h>
+#include <wxPcbStruct.h>
+#include <trigo.h>
+#include <build_version.h>
+#include <macros.h>
+
+#include <pcbnew.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_edge_mod.h>
+#include <vector>
+#include <cctype>
+
+/* Structure for holding the D-356 record fields.
+ * Useful because 356A (when implemented) must be sorted before outputting it */
+struct D356_RECORD
+{
+ bool smd;
+ bool hole;
+ wxString netname;
+ wxString refdes;
+ wxString pin;
+ bool midpoint;
+ int drill;
+ bool mechanical;
+ int access; // Access 0 is 'both sides'
+ int soldermask;
+ // All these in PCB units, will be output in decimils
+ int x_location;
+ int y_location;
+ int x_size;
+ int y_size;
+ int rotation;
+};
+
+// Compute the access code for a pad. Returns -1 if there is no copper
+static int compute_pad_access_code( BOARD *aPcb, LSET aLayerMask )
+{
+ // Non-copper is not interesting here
+ aLayerMask &= LSET::AllCuMask();
+ if( !aLayerMask.any() )
+ return -1;
+
+ // Traditional TH pad
+ if( aLayerMask[F_Cu] && aLayerMask[B_Cu] )
+ return 0;
+
+ // Front SMD pad
+ if( aLayerMask[F_Cu] )
+ return 1;
+
+ // Back SMD pad
+ if( aLayerMask[B_Cu] )
+ return aPcb->GetCopperLayerCount();
+
+ // OK, we have an inner-layer only pad (and I have no idea about
+ // what could be used for); anyway, find the first copper layer
+ // it's on
+ for( LAYER_NUM layer = In1_Cu; layer < B_Cu; ++layer )
+ {
+ if( aLayerMask[layer] )
+ return layer + 1;
+ }
+
+ // This shouldn't happen
+ return -1;
+}
+
+/* Convert and clamp a size from IU to decimils */
+static int iu_to_d356(int iu, int clamp)
+{
+ int val = KiROUND( iu / IU_PER_DECIMILS );
+ if( val > clamp ) return clamp;
+ if( val < -clamp ) return -clamp;
+ return val;
+}
+
+/* Extract the D356 record from the modules (pads) */
+static void build_pad_testpoints( BOARD *aPcb,
+ std::vector <D356_RECORD>& aRecords )
+{
+ wxPoint origin = aPcb->GetAuxOrigin();
+
+ for( MODULE *module = aPcb->m_Modules;
+ module; module = module->Next() )
+ {
+ for( D_PAD *pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ D356_RECORD rk;
+ rk.access = compute_pad_access_code( aPcb, pad->GetLayerSet() );
+
+ // It could be a mask only pad, we only handle pads with copper here
+ if( rk.access != -1 )
+ {
+ rk.netname = pad->GetNetname();
+ rk.refdes = module->GetReference();
+ pad->StringPadName( rk.pin );
+ rk.midpoint = false; // XXX MAYBE need to be computed (how?)
+ const wxSize& drill = pad->GetDrillSize();
+ rk.drill = std::min( drill.x, drill.y );
+ rk.hole = (rk.drill != 0);
+ rk.smd = pad->GetAttribute() == PAD_ATTRIB_SMD;
+ rk.mechanical = (pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED);
+ rk.x_location = pad->GetPosition().x - origin.x;
+ rk.y_location = origin.y - pad->GetPosition().y;
+ rk.x_size = pad->GetSize().x;
+
+ // Rule: round pads have y = 0
+ if( pad->GetShape() == PAD_SHAPE_CIRCLE )
+ rk.y_size = 0;
+ else
+ rk.y_size = pad->GetSize().y;
+
+ rk.rotation = -KiROUND( pad->GetOrientation() ) / 10;
+ if( rk.rotation < 0 ) rk.rotation += 360;
+
+ // the value indicates which sides are *not* accessible
+ rk.soldermask = 3;
+ if( pad->GetLayerSet()[F_Mask] )
+ rk.soldermask &= ~1;
+ if( pad->GetLayerSet()[B_Mask] )
+ rk.soldermask &= ~2;
+
+ aRecords.push_back( rk );
+ }
+ }
+ }
+}
+
+/* Compute the access code for a via. In D-356 layers are numbered from 1 up,
+ where '1' is the 'primary side' (usually the component side);
+ '0' means 'both sides', and other layers follows in an unspecified order */
+static int via_access_code( BOARD *aPcb, int top_layer, int bottom_layer )
+{
+ // Easy case for through vias: top_layer is component, bottom_layer is
+ // solder, access code is 0
+ if( (top_layer == F_Cu) && (bottom_layer == B_Cu) )
+ return 0;
+
+ // Blind via, reachable from front
+ if( top_layer == F_Cu )
+ return 1;
+
+ // Blind via, reachable from bottom
+ if( bottom_layer == B_Cu )
+ return aPcb->GetCopperLayerCount();
+
+ // It's a buried via, accessible from some inner layer
+ // (maybe could be used for testing before laminating? no idea)
+ return bottom_layer + 1; // XXX is this correct?
+}
+
+/* Extract the D356 record from the vias */
+static void build_via_testpoints( BOARD *aPcb,
+ std::vector <D356_RECORD>& aRecords )
+{
+ wxPoint origin = aPcb->GetAuxOrigin();
+
+ // Enumerate all the track segments and keep the vias
+ for( TRACK *track = aPcb->m_Track; track; track = track->Next() )
+ {
+ if( track->Type() == PCB_VIA_T )
+ {
+ VIA *via = (VIA*) track;
+ NETINFO_ITEM *net = track->GetNet();
+
+ D356_RECORD rk;
+ rk.smd = false;
+ rk.hole = true;
+ if( net )
+ rk.netname = net->GetNetname();
+ else
+ rk.netname = wxEmptyString;
+ rk.refdes = wxT("VIA");
+ rk.pin = wxT("");
+ rk.midpoint = true; // Vias are always midpoints
+ rk.drill = via->GetDrillValue();
+ rk.mechanical = false;
+
+ LAYER_ID top_layer, bottom_layer;
+
+ via->LayerPair( &top_layer, &bottom_layer );
+
+ rk.access = via_access_code( aPcb, top_layer, bottom_layer );
+ rk.x_location = via->GetPosition().x - origin.x;
+ rk.y_location = origin.y - via->GetPosition().y;
+ rk.x_size = via->GetWidth();
+ rk.y_size = 0; // Round so height = 0
+ rk.rotation = 0;
+ rk.soldermask = 3; // XXX always tented?
+
+ aRecords.push_back( rk );
+ }
+ }
+}
+
+/* Add a new netname to the d356 canonicalized list */
+static const wxString intern_new_d356_netname( const wxString &aNetname,
+ std::map<wxString, wxString> &aMap, std::set<wxString> &aSet )
+{
+ wxString canon;
+ for (wxString::const_iterator i = aNetname.begin();
+ i != aNetname.end(); ++i)
+ {
+ // Rule: we can only use the standard ASCII, control excluded
+ char ch = *i;
+ if( ch > 126 || !std::isgraph( ch ) )
+ ch = '?';
+ canon += ch;
+ }
+
+ // Rule: only uppercase (unofficial, but known to give problems
+ // otherwise)
+ canon.MakeUpper();
+
+ // Rule: maximum length is 14 characters, otherwise we keep the tail
+ if( canon.size() > 14 )
+ {
+ canon = canon.Right( 14 );
+ }
+
+ // Check if it's still unique
+ if( aSet.count( canon ) )
+ {
+ // Nope, need to uniquify it, trim it more and add a number
+ wxString base( canon );
+ if( base.size() > 10 )
+ {
+ base = base.Right( 10 );
+ }
+
+ int ctr = 0;
+ do
+ {
+ ++ctr;
+ canon = base;
+ canon << '#' << ctr;
+ } while ( aSet.count( canon ) );
+ }
+
+ // Register it
+ aMap[aNetname] = canon;
+ aSet.insert( canon );
+ return canon;
+}
+
+/* Write all the accumuled data to the file in D356 format */
+static void write_D356_records( std::vector <D356_RECORD> &aRecords,
+ FILE *fout )
+{
+ // Sanified and shorted network names and set of short names
+ std::map<wxString, wxString> d356_net_map;
+ std::set<wxString> d356_net_set;
+
+ for (unsigned i = 0; i < aRecords.size(); i++)
+ {
+ D356_RECORD &rk = aRecords[i];
+
+ // Try to sanify the network name (there are limits on this), if
+ // not already done. Also 'empty' net are marked as N/C, as
+ // specified.
+ wxString d356_net( wxT("N/C") );
+ if( !rk.netname.empty() )
+ {
+ d356_net = d356_net_map[rk.netname];
+
+ if( d356_net.empty() )
+ d356_net = intern_new_d356_netname( rk.netname, d356_net_map,
+ d356_net_set );
+ }
+
+ // Choose the best record type
+ int rktype;
+ if( rk.smd )
+ rktype = 327;
+ else
+ {
+ if( rk.mechanical )
+ rktype = 367;
+ else
+ rktype = 317;
+ }
+
+ // Operation code, signal and component
+ fprintf( fout, "%03d%-14.14s %-6.6s%c%-4.4s%c",
+ rktype, TO_UTF8(d356_net),
+ TO_UTF8(rk.refdes),
+ rk.pin.empty()?' ':'-',
+ TO_UTF8(rk.pin),
+ rk.midpoint?'M':' ' );
+
+ // Hole definition
+ if( rk.hole )
+ {
+ fprintf( fout, "D%04d%c",
+ iu_to_d356( rk.drill, 9999 ),
+ rk.mechanical ? 'U':'P' );
+ }
+ else
+ fprintf( fout, " " );
+
+ // Test point access
+ fprintf( fout, "A%02dX%+07dY%+07dX%04dY%04dR%03d",
+ rk.access,
+ iu_to_d356( rk.x_location, 999999 ),
+ iu_to_d356( rk.y_location, 999999 ),
+ iu_to_d356( rk.x_size, 9999 ),
+ iu_to_d356( rk.y_size, 9999 ),
+ rk.rotation );
+
+ // Soldermask
+ fprintf( fout, "S%d\n", rk.soldermask );
+ }
+}
+
+
+void PCB_EDIT_FRAME::GenD356File( wxCommandEvent& aEvent )
+{
+ wxFileName fn = GetBoard()->GetFileName();
+ wxString msg, ext, wildcard;
+ FILE* file;
+
+ ext = wxT( "d356" );
+ wildcard = _( "IPC-D-356 Test Files (.d356)|*.d356" );
+ fn.SetExt( ext );
+
+ wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
+
+ wxFileDialog dlg( this, _( "Export D-356 Test File" ), pro_dir,
+ fn.GetFullName(), wildcard,
+ wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ if( ( file = wxFopen( dlg.GetPath(), wxT( "wt" ) ) ) == NULL )
+ {
+ msg = _( "Unable to create " ) + dlg.GetPath();
+ DisplayError( this, msg ); return;
+ }
+
+ LOCALE_IO toggle; // Switch the locale to standard C
+
+ // This will contain everything needed for the 356 file
+ std::vector <D356_RECORD> d356_records;
+ BOARD* pcb = GetBoard();
+
+ build_via_testpoints( pcb, d356_records );
+
+ build_pad_testpoints( pcb, d356_records );
+
+ // Code 00 AFAIK is ASCII, CUST 0 is decimils/degrees
+ // CUST 1 would be metric but gerbtool simply ignores it!
+ fprintf( file, "P CODE 00\n" );
+ fprintf( file, "P UNITS CUST 0\n" );
+ fprintf( file, "P DIM N\n" );
+ write_D356_records( d356_records, file );
+ fprintf( file, "999\n" );
+
+ fclose( file );
+}
+
diff --git a/pcbnew/exporters/export_gencad.cpp b/pcbnew/exporters/export_gencad.cpp
new file mode 100644
index 0000000..2166021
--- /dev/null
+++ b/pcbnew/exporters/export_gencad.cpp
@@ -0,0 +1,1257 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file export_gencad.cpp
+ * @brief Export GenCAD 1.4 format.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <pgm_base.h>
+#include <wxPcbStruct.h>
+#include <trigo.h>
+#include <build_version.h>
+#include <macros.h>
+
+#include <pcbnew.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_edge_mod.h>
+
+
+static bool CreateHeaderInfoData( FILE* aFile, PCB_EDIT_FRAME* frame );
+static void CreateArtworksSection( FILE* aFile );
+static void CreateTracksInfoData( FILE* aFile, BOARD* aPcb );
+static void CreateBoardSection( FILE* aFile, BOARD* aPcb );
+static void CreateComponentsSection( FILE* aFile, BOARD* aPcb );
+static void CreateDevicesSection( FILE* aFile, BOARD* aPcb );
+static void CreateRoutesSection( FILE* aFile, BOARD* aPcb );
+static void CreateSignalsSection( FILE* aFile, BOARD* aPcb );
+static void CreateShapesSection( FILE* aFile, BOARD* aPcb );
+static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb );
+static void FootprintWriteShape( FILE* File, MODULE* module );
+
+// layer names for Gencad export
+
+#if 0 // was:
+static const wxString GenCADLayerName[] =
+{
+ wxT( "BOTTOM" ), wxT( "INNER1" ), wxT( "INNER2" ),
+ wxT( "INNER3" ), wxT( "INNER4" ), wxT( "INNER5" ),
+ wxT( "INNER6" ), wxT( "INNER7" ), wxT( "INNER8" ),
+ wxT( "INNER9" ), wxT( "INNER10" ), wxT( "INNER11" ),
+ wxT( "INNER12" ), wxT( "INNER13" ), wxT( "INNER14" ),
+ wxT( "TOP" ), wxT( "LAYER17" ), wxT( "LAYER18" ),
+ wxT( "SOLDERPASTE_BOTTOM" ), wxT( "SOLDERPASTE_TOP" ),
+ wxT( "SILKSCREEN_BOTTOM" ), wxT( "SILKSCREEN_TOP" ),
+ wxT( "SOLDERMASK_BOTTOM" ), wxT( "SOLDERMASK_TOP" ), wxT( "LAYER25" ),
+ wxT( "LAYER26" ), wxT( "LAYER27" ), wxT( "LAYER28" ),
+ wxT( "LAYER29" ), wxT( "LAYER30" ), wxT( "LAYER31" ),
+ wxT( "LAYER32" )
+};
+
+// flipped layer name for Gencad export (to make CAM350 imports correct)
+static const wxString GenCADLayerNameFlipped[32] =
+{
+ wxT( "TOP" ), wxT( "INNER14" ), wxT( "INNER13" ),
+ wxT( "INNER12" ), wxT( "INNER11" ), wxT( "INNER10" ),
+ wxT( "INNER9" ), wxT( "INNER8" ), wxT( "INNER7" ),
+ wxT( "INNER6" ), wxT( "INNER5" ), wxT( "INNER4" ),
+ wxT( "INNER3" ), wxT( "INNER2" ), wxT( "INNER1" ),
+ wxT( "BOTTOM" ), wxT( "LAYER17" ), wxT( "LAYER18" ),
+ wxT( "SOLDERPASTE_TOP" ), wxT( "SOLDERPASTE_BOTTOM" ),
+ wxT( "SILKSCREEN_TOP" ), wxT( "SILKSCREEN_BOTTOM" ),
+ wxT( "SOLDERMASK_TOP" ), wxT( "SOLDERMASK_BOTTOM" ), wxT( "LAYER25" ),
+ wxT( "LAYER26" ), wxT( "LAYER27" ), wxT( "LAYER28" ),
+ wxT( "LAYER29" ), wxT( "LAYER30" ), wxT( "LAYER31" ),
+ wxT( "LAYER32" )
+};
+
+#else
+
+static std::string GenCADLayerName( int aCuCount, LAYER_ID aId )
+{
+ if( IsCopperLayer( aId ) )
+ {
+ if( aId == F_Cu )
+ return "TOP";
+ else if( aId == B_Cu )
+ return "BOTTOM";
+
+ else if( aId <= 14 )
+ {
+ return StrPrintf( "INNER%d", aCuCount - aId - 1 );
+ }
+ else
+ {
+ return StrPrintf( "LAYER%d", aId );
+ }
+ }
+
+ else
+ {
+ const char* txt;
+
+ // using a switch to clearly show mapping & catch out of bounds index.
+ switch( aId )
+ {
+ // Technicals
+ case B_Adhes: txt = "B.Adhes"; break;
+ case F_Adhes: txt = "F.Adhes"; break;
+ case B_Paste: txt = "SOLDERPASTE_BOTTOM"; break;
+ case F_Paste: txt = "SOLDERPASTE_TOP"; break;
+ case B_SilkS: txt = "SILKSCREEN_BOTTOM"; break;
+ case F_SilkS: txt = "SILKSCREEN_TOP"; break;
+ case B_Mask: txt = "SOLDERMASK_BOTTOM"; break;
+ case F_Mask: txt = "SOLDERMASK_TOP"; break;
+
+ // Users
+ case Dwgs_User: txt = "Dwgs.User"; break;
+ case Cmts_User: txt = "Cmts.User"; break;
+ case Eco1_User: txt = "Eco1.User"; break;
+ case Eco2_User: txt = "Eco2.User"; break;
+ case Edge_Cuts: txt = "Edge.Cuts"; break;
+ case Margin: txt = "Margin"; break;
+
+ // Footprint
+ case F_CrtYd: txt = "F_CrtYd"; break;
+ case B_CrtYd: txt = "B_CrtYd"; break;
+ case F_Fab: txt = "F_Fab"; break;
+ case B_Fab: txt = "B_Fab"; break;
+
+ default:
+ wxASSERT_MSG( 0, wxT( "aId UNEXPECTED" ) );
+ txt = "BAD-INDEX!"; break;
+ }
+
+ return txt;
+ }
+};
+
+
+static const LAYER_ID gc_seq[] = {
+ B_Cu,
+ In30_Cu,
+ In29_Cu,
+ In28_Cu,
+ In27_Cu,
+ In26_Cu,
+ In25_Cu,
+ In24_Cu,
+ In23_Cu,
+ In22_Cu,
+ In21_Cu,
+ In20_Cu,
+ In19_Cu,
+ In18_Cu,
+ In17_Cu,
+ In16_Cu,
+ In15_Cu,
+ In14_Cu,
+ In13_Cu,
+ In12_Cu,
+ In11_Cu,
+ In10_Cu,
+ In9_Cu,
+ In8_Cu,
+ In7_Cu,
+ In6_Cu,
+ In5_Cu,
+ In4_Cu,
+ In3_Cu,
+ In2_Cu,
+ In1_Cu,
+ F_Cu,
+};
+
+
+// flipped layer name for Gencad export (to make CAM350 imports correct)
+static std::string GenCADLayerNameFlipped( int aCuCount, LAYER_ID aId )
+{
+ if( 1<= aId && aId <= 14 )
+ {
+ return StrPrintf( "INNER%d", 14 - aId );
+ }
+
+ return GenCADLayerName( aCuCount, aId );
+};
+
+
+#endif
+
+static std::string fmt_mask( LSET aSet )
+{
+#if 0
+ return aSet.FmtHex();
+#else
+ return StrPrintf( "%08x", (unsigned) ( aSet & LSET::AllCuMask() ).to_ulong() );
+#endif
+}
+
+
+// These are the export origin (the auxiliary axis)
+static int GencadOffsetX, GencadOffsetY;
+
+/* GerbTool chokes on units different than INCH so this is the conversion
+ * factor */
+const static double SCALE_FACTOR = 10000.0 * IU_PER_DECIMILS;
+
+
+/* Two helper functions to calculate coordinates of modules in gencad values
+ * (GenCAD Y axis from bottom to top)
+ */
+static double MapXTo( int aX )
+{
+ return (aX - GencadOffsetX) / SCALE_FACTOR;
+}
+
+
+static double MapYTo( int aY )
+{
+ return (GencadOffsetY - aY) / SCALE_FACTOR;
+}
+
+
+/* Driver function: processing starts here */
+void PCB_EDIT_FRAME::ExportToGenCAD( wxCommandEvent& aEvent )
+{
+ wxFileName fn = GetBoard()->GetFileName();
+ FILE* file;
+
+ wxString ext = wxT( "cad" );
+ wxString wildcard = _( "GenCAD 1.4 board files (.cad)|*.cad" );
+
+ fn.SetExt( ext );
+
+ wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
+
+ wxFileDialog dlg( this, _( "Save GenCAD Board File" ), pro_dir,
+ fn.GetFullName(), wildcard,
+ wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ if( ( file = wxFopen( dlg.GetPath(), wxT( "wt" ) ) ) == NULL )
+ {
+ wxString msg;
+
+ msg.Printf( _( "Unable to create <%s>" ), GetChars( dlg.GetPath() ) );
+ DisplayError( this, msg ); return;
+ }
+
+ // Switch the locale to standard C (needed to print floating point numbers)
+ LOCALE_IO toggle;
+
+ // Update some board data, to ensure a reliable gencad export
+ GetBoard()->ComputeBoundingBox();
+
+ // Save the auxiliary origin for the rest of the module
+ GencadOffsetX = GetAuxOrigin().x;
+ GencadOffsetY = GetAuxOrigin().y;
+
+ // No idea on *why* this should be needed... maybe to fix net names?
+ Compile_Ratsnest( NULL, true );
+
+ /* Temporary modification of footprints that are flipped (i.e. on bottom
+ * layer) to convert them to non flipped footprints.
+ * This is necessary to easily export shapes to GenCAD,
+ * that are given as normal orientation (non flipped, rotation = 0))
+ * these changes will be undone later
+ */
+ BOARD* pcb = GetBoard();
+ MODULE* module;
+
+ for( module = pcb->m_Modules; module; module = module->Next() )
+ {
+ module->SetFlag( 0 );
+
+ if( module->GetLayer() == B_Cu )
+ {
+ module->Flip( module->GetPosition() );
+ module->SetFlag( 1 );
+ }
+ }
+
+ /* Gencad has some mandatory and some optional sections: some importer
+ * need the padstack section (which is optional) anyway. Also the
+ * order of the section *is* important */
+
+ CreateHeaderInfoData( file, this ); // Gencad header
+ CreateBoardSection( file, pcb ); // Board perimeter
+
+ CreatePadsShapesSection( file, pcb ); // Pads and padstacks
+ CreateArtworksSection( file ); // Empty but mandatory
+
+ /* Gencad splits a component info in shape, component and device.
+ * We don't do any sharing (it would be difficult since each module is
+ * customizable after placement) */
+ CreateShapesSection( file, pcb );
+ CreateComponentsSection( file, pcb );
+ CreateDevicesSection( file, pcb );
+
+ // In a similar way the netlist is split in net, track and route
+ CreateSignalsSection( file, pcb );
+ CreateTracksInfoData( file, pcb );
+ CreateRoutesSection( file, pcb );
+
+ fclose( file );
+
+ // Undo the footprints modifications (flipped footprints)
+ for( module = pcb->m_Modules; module; module = module->Next() )
+ {
+ if( module->GetFlag() )
+ {
+ module->Flip( module->GetPosition() );
+ module->SetFlag( 0 );
+ }
+ }
+}
+
+
+// Comparator for sorting pads with qsort
+static int PadListSortByShape( const void* aRefptr, const void* aObjptr )
+{
+ const D_PAD* padref = *(D_PAD**) aRefptr;
+ const D_PAD* padcmp = *(D_PAD**) aObjptr;
+
+ return D_PAD::Compare( padref, padcmp );
+}
+
+
+// Sort vias for uniqueness
+static int ViaSort( const void* aRefptr, const void* aObjptr )
+{
+ VIA* padref = *(VIA**) aRefptr;
+ VIA* padcmp = *(VIA**) aObjptr;
+
+ if( padref->GetWidth() != padcmp->GetWidth() )
+ return padref->GetWidth() - padcmp->GetWidth();
+
+ if( padref->GetDrillValue() != padcmp->GetDrillValue() )
+ return padref->GetDrillValue() - padcmp->GetDrillValue();
+
+ if( padref->GetLayerSet() != padcmp->GetLayerSet() )
+ return padref->GetLayerSet().FmtBin().compare( padcmp->GetLayerSet().FmtBin() );
+
+ return 0;
+}
+
+
+// The ARTWORKS section is empty but (officially) mandatory
+static void CreateArtworksSection( FILE* aFile )
+{
+ /* The artworks section is empty */
+ fputs( "$ARTWORKS\n", aFile );
+ fputs( "$ENDARTWORKS\n\n", aFile );
+}
+
+
+// Emit PADS and PADSTACKS. They are sorted and emitted uniquely.
+// Via name is synthesized from their attributes, pads are numbered
+static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb )
+{
+ std::vector<D_PAD*> pads;
+ std::vector<D_PAD*> padstacks;
+ std::vector<VIA*> vias;
+ std::vector<VIA*> viastacks;
+
+ padstacks.resize( 1 ); // We count pads from 1
+
+ // The master layermask (i.e. the enabled layers) for padstack generation
+ LSET master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
+ int cu_count = aPcb->GetCopperLayerCount();
+
+ fputs( "$PADS\n", aFile );
+
+ // Enumerate and sort the pads
+ if( aPcb->GetPadCount() > 0 )
+ {
+ pads = aPcb->GetPads();
+ qsort( &pads[0], aPcb->GetPadCount(), sizeof( D_PAD* ),
+ PadListSortByShape );
+ }
+
+ // The same for vias
+ for( VIA* via = GetFirstVia( aPcb->m_Track ); via;
+ via = GetFirstVia( via->Next() ) )
+ {
+ vias.push_back( via );
+ }
+
+ qsort( &vias[0], vias.size(), sizeof(VIA*), ViaSort );
+
+ // Emit vias pads
+ TRACK* old_via = 0;
+
+ for( unsigned i = 0; i < vias.size(); i++ )
+ {
+ VIA* via = vias[i];
+
+ if( old_via && 0 == ViaSort( &old_via, &via ) )
+ continue;
+
+ old_via = via;
+ viastacks.push_back( via );
+ fprintf( aFile, "PAD V%d.%d.%s ROUND %g\nCIRCLE 0 0 %g\n",
+ via->GetWidth(), via->GetDrillValue(),
+ fmt_mask( via->GetLayerSet() ).c_str(),
+ via->GetDrillValue() / SCALE_FACTOR,
+ via->GetWidth() / (SCALE_FACTOR * 2) );
+ }
+
+ // Emit component pads
+ D_PAD* old_pad = 0;
+ int pad_name_number = 0;
+
+ for( unsigned i = 0; i<pads.size(); ++i )
+ {
+ D_PAD* pad = pads[i];
+
+ pad->SetSubRatsnest( pad_name_number );
+
+ if( old_pad && 0==D_PAD::Compare( old_pad, pad ) )
+ continue; // already created
+
+ old_pad = pad;
+
+ pad_name_number++;
+ pad->SetSubRatsnest( pad_name_number );
+
+ fprintf( aFile, "PAD P%d", pad->GetSubRatsnest() );
+
+ padstacks.push_back( pad ); // Will have its own padstack later
+ int dx = pad->GetSize().x / 2;
+ int dy = pad->GetSize().y / 2;
+
+ switch( pad->GetShape() )
+ {
+ default:
+ case PAD_SHAPE_CIRCLE:
+ fprintf( aFile, " ROUND %g\n",
+ pad->GetDrillSize().x / SCALE_FACTOR );
+ /* Circle is center, radius */
+ fprintf( aFile, "CIRCLE %g %g %g\n",
+ pad->GetOffset().x / SCALE_FACTOR,
+ -pad->GetOffset().y / SCALE_FACTOR,
+ pad->GetSize().x / (SCALE_FACTOR * 2) );
+ break;
+
+ case PAD_SHAPE_RECT:
+ fprintf( aFile, " RECTANGULAR %g\n",
+ pad->GetDrillSize().x / SCALE_FACTOR );
+
+ // Rectangle is begin, size *not* begin, end!
+ fprintf( aFile, "RECTANGLE %g %g %g %g\n",
+ (-dx + pad->GetOffset().x ) / SCALE_FACTOR,
+ (-dy - pad->GetOffset().y ) / SCALE_FACTOR,
+ dx / (SCALE_FACTOR / 2), dy / (SCALE_FACTOR / 2) );
+ break;
+
+ case PAD_SHAPE_OVAL: // Create outline by 2 lines and 2 arcs
+ {
+ // OrCAD Layout call them OVAL or OBLONG - GenCAD call them FINGERs
+ fprintf( aFile, " FINGER %g\n",
+ pad->GetDrillSize().x / SCALE_FACTOR );
+ int dr = dx - dy;
+
+ if( dr >= 0 ) // Horizontal oval
+ {
+ int radius = dy;
+ fprintf( aFile, "LINE %g %g %g %g\n",
+ (-dr + pad->GetOffset().x) / SCALE_FACTOR,
+ (-pad->GetOffset().y - radius) / SCALE_FACTOR,
+ (dr + pad->GetOffset().x ) / SCALE_FACTOR,
+ (-pad->GetOffset().y - radius) / SCALE_FACTOR );
+
+ // GenCAD arcs are (start, end, center)
+ fprintf( aFile, "ARC %g %g %g %g %g %g\n",
+ (dr + pad->GetOffset().x) / SCALE_FACTOR,
+ (-pad->GetOffset().y - radius) / SCALE_FACTOR,
+ (dr + pad->GetOffset().x) / SCALE_FACTOR,
+ (-pad->GetOffset().y + radius) / SCALE_FACTOR,
+ (dr + pad->GetOffset().x) / SCALE_FACTOR,
+ -pad->GetOffset().y / SCALE_FACTOR );
+
+ fprintf( aFile, "LINE %g %g %g %g\n",
+ (dr + pad->GetOffset().x) / SCALE_FACTOR,
+ (-pad->GetOffset().y + radius) / SCALE_FACTOR,
+ (-dr + pad->GetOffset().x) / SCALE_FACTOR,
+ (-pad->GetOffset().y + radius) / SCALE_FACTOR );
+ fprintf( aFile, "ARC %g %g %g %g %g %g\n",
+ (-dr + pad->GetOffset().x) / SCALE_FACTOR,
+ (-pad->GetOffset().y + radius) / SCALE_FACTOR,
+ (-dr + pad->GetOffset().x) / SCALE_FACTOR,
+ (-pad->GetOffset().y - radius) / SCALE_FACTOR,
+ (-dr + pad->GetOffset().x) / SCALE_FACTOR,
+ -pad->GetOffset().y / SCALE_FACTOR );
+ }
+ else // Vertical oval
+ {
+ dr = -dr;
+ int radius = dx;
+ fprintf( aFile, "LINE %g %g %g %g\n",
+ (-radius + pad->GetOffset().x) / SCALE_FACTOR,
+ (-pad->GetOffset().y - dr) / SCALE_FACTOR,
+ (-radius + pad->GetOffset().x ) / SCALE_FACTOR,
+ (-pad->GetOffset().y + dr) / SCALE_FACTOR );
+ fprintf( aFile, "ARC %g %g %g %g %g %g\n",
+ (-radius + pad->GetOffset().x ) / SCALE_FACTOR,
+ (-pad->GetOffset().y + dr) / SCALE_FACTOR,
+ (radius + pad->GetOffset().x ) / SCALE_FACTOR,
+ (-pad->GetOffset().y + dr) / SCALE_FACTOR,
+ pad->GetOffset().x / SCALE_FACTOR,
+ (-pad->GetOffset().y + dr) / SCALE_FACTOR );
+
+ fprintf( aFile, "LINE %g %g %g %g\n",
+ (radius + pad->GetOffset().x) / SCALE_FACTOR,
+ (-pad->GetOffset().y + dr) / SCALE_FACTOR,
+ (radius + pad->GetOffset().x) / SCALE_FACTOR,
+ (-pad->GetOffset().y - dr) / SCALE_FACTOR );
+ fprintf( aFile, "ARC %g %g %g %g %g %g\n",
+ (radius + pad->GetOffset().x) / SCALE_FACTOR,
+ (-pad->GetOffset().y - dr) / SCALE_FACTOR,
+ (-radius + pad->GetOffset().x) / SCALE_FACTOR,
+ (-pad->GetOffset().y - dr) / SCALE_FACTOR,
+ pad->GetOffset().x / SCALE_FACTOR,
+ (-pad->GetOffset().y - dr) / SCALE_FACTOR );
+ }
+ }
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ fprintf( aFile, " POLYGON %g\n",
+ pad->GetDrillSize().x / SCALE_FACTOR );
+
+ // XXX TO BE IMPLEMENTED! and I don't know if it could be actually imported by something
+ break;
+ }
+ }
+
+ fputs( "\n$ENDPADS\n\n", aFile );
+
+ // Now emit the padstacks definitions, using the combined layer masks
+ fputs( "$PADSTACKS\n", aFile );
+
+ // Via padstacks
+ for( unsigned i = 0; i < viastacks.size(); i++ )
+ {
+ VIA* via = viastacks[i];
+
+ LSET mask = via->GetLayerSet() & master_layermask;
+
+ fprintf( aFile, "PADSTACK VIA%d.%d.%s %g\n",
+ via->GetWidth(), via->GetDrillValue(),
+ fmt_mask( mask ).c_str(),
+ via->GetDrillValue() / SCALE_FACTOR );
+
+ for( LSEQ seq = mask.Seq( gc_seq, DIM( gc_seq ) ); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ fprintf( aFile, "PAD V%d.%d.%s %s 0 0\n",
+ via->GetWidth(), via->GetDrillValue(),
+ fmt_mask( mask ).c_str(),
+ GenCADLayerName( cu_count, layer ).c_str()
+ );
+ }
+ }
+
+ /* Component padstacks
+ * CAM350 don't apply correctly the FLIP semantics for padstacks, i.e. doesn't
+ * swap the top and bottom layers... so I need to define the shape as MIRRORX
+ * and define a separate 'flipped' padstack... until it appears yet another
+ * noncompliant importer */
+ for( unsigned i = 1; i < padstacks.size(); i++ )
+ {
+ D_PAD* pad = padstacks[i];
+
+ // Straight padstack
+ fprintf( aFile, "PADSTACK PAD%u %g\n", i, pad->GetDrillSize().x / SCALE_FACTOR );
+
+ LSET pad_set = pad->GetLayerSet() & master_layermask;
+
+ // the special gc_seq
+ for( LSEQ seq = pad_set.Seq( gc_seq, DIM( gc_seq ) ); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ fprintf( aFile, "PAD P%u %s 0 0\n", i, GenCADLayerName( cu_count, layer ).c_str() );
+ }
+
+ // Flipped padstack
+ fprintf( aFile, "PADSTACK PAD%uF %g\n", i, pad->GetDrillSize().x / SCALE_FACTOR );
+
+ // the normal LAYER_ID sequence is inverted from gc_seq[]
+ for( LSEQ seq = pad_set.Seq(); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ fprintf( aFile, "PAD P%u %s 0 0\n", i, GenCADLayerNameFlipped( cu_count, layer ).c_str() );
+ }
+ }
+
+ fputs( "$ENDPADSTACKS\n\n", aFile );
+}
+
+
+/* Creates the footprint shape list.
+ * Since module shape is customizable after the placement we cannot share them;
+ * instead we opt for the one-module-one-shape-one-component-one-device approach
+ */
+static void CreateShapesSection( FILE* aFile, BOARD* aPcb )
+{
+ MODULE* module;
+ D_PAD* pad;
+ const char* layer;
+ wxString pinname;
+ const char* mirror = "0";
+
+ fputs( "$SHAPES\n", aFile );
+
+ const LSET all_cu = LSET::AllCuMask();
+
+ for( module = aPcb->m_Modules; module; module = module->Next() )
+ {
+ FootprintWriteShape( aFile, module );
+
+ for( pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ /* Funny thing: GenCAD requires the pad side even if you use
+ * padstacks (which are theorically optional but gerbtools
+ *requires* them). Now the trouble thing is that 'BOTTOM'
+ * is interpreted by someone as a padstack flip even
+ * if the spec explicitly says it's not... */
+ layer = "ALL";
+
+ if( ( pad->GetLayerSet() & all_cu ) == LSET( B_Cu ) )
+ {
+ layer = module->GetFlag() ? "TOP" : "BOTTOM";
+ }
+ else if( ( pad->GetLayerSet() & all_cu ) == LSET( F_Cu ) )
+ {
+ layer = module->GetFlag() ? "BOTTOM" : "TOP";
+ }
+
+ pad->StringPadName( pinname );
+
+ if( pinname.IsEmpty() )
+ pinname = wxT( "none" );
+
+ double orient = pad->GetOrientation() - module->GetOrientation();
+ NORMALIZE_ANGLE_POS( orient );
+
+ // Bottom side modules use the flipped padstack
+ fprintf( aFile, (module->GetFlag()) ?
+ "PIN %s PAD%dF %g %g %s %g %s\n" :
+ "PIN %s PAD%d %g %g %s %g %s\n",
+ TO_UTF8( pinname ), pad->GetSubRatsnest(),
+ pad->GetPos0().x / SCALE_FACTOR,
+ -pad->GetPos0().y / SCALE_FACTOR,
+ layer, orient / 10.0, mirror );
+ }
+ }
+
+ fputs( "$ENDSHAPES\n\n", aFile );
+}
+
+
+/* Creates the section $COMPONENTS (Footprints placement)
+ * Bottom side components are difficult to handle: shapes must be mirrored or
+ * flipped, silk layers need to be handled correctly and so on. Also it seems
+ * that *noone* follows the specs...
+ */
+static void CreateComponentsSection( FILE* aFile, BOARD* aPcb )
+{
+ fputs( "$COMPONENTS\n", aFile );
+
+ int cu_count = aPcb->GetCopperLayerCount();
+
+ for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
+ {
+ const char* mirror;
+ const char* flip;
+ double orient = module->GetOrientation();
+
+ if( module->GetFlag() )
+ {
+ mirror = "0";
+ flip = "FLIP";
+ NEGATE_AND_NORMALIZE_ANGLE_POS( orient );
+ }
+ else
+ {
+ mirror = "0";
+ flip = "0";
+ }
+
+ fprintf( aFile, "\nCOMPONENT %s\n",
+ TO_UTF8( module->GetReference() ) );
+ fprintf( aFile, "DEVICE %s_%s\n",
+ TO_UTF8( module->GetReference() ),
+ TO_UTF8( module->GetValue() ) );
+ fprintf( aFile, "PLACE %g %g\n",
+ MapXTo( module->GetPosition().x ),
+ MapYTo( module->GetPosition().y ) );
+ fprintf( aFile, "LAYER %s\n",
+ (module->GetFlag()) ? "BOTTOM" : "TOP" );
+ fprintf( aFile, "ROTATION %g\n",
+ orient / 10.0 );
+ fprintf( aFile, "SHAPE %s %s %s\n",
+ TO_UTF8( module->GetReference() ),
+ mirror, flip );
+
+ // Text on silk layer: RefDes and value (are they actually useful?)
+ TEXTE_MODULE *textmod = &module->Reference();
+
+ for( int ii = 0; ii < 2; ii++ )
+ {
+ double orient = textmod->GetOrientation();
+ std::string layer = GenCADLayerName( cu_count, module->GetFlag() ? B_SilkS : F_SilkS );
+
+ fprintf( aFile, "TEXT %g %g %g %g %s %s \"%s\"",
+ textmod->GetPos0().x / SCALE_FACTOR,
+ -textmod->GetPos0().y / SCALE_FACTOR,
+ textmod->GetSize().x / SCALE_FACTOR,
+ orient / 10.0,
+ mirror,
+ layer.c_str(),
+ TO_UTF8( textmod->GetText() ) );
+
+ // Please note, the width is approx
+ fprintf( aFile, " 0 0 %g %g\n",
+ ( textmod->GetSize().x * textmod->GetLength() ) / SCALE_FACTOR,
+ textmod->GetSize().y / SCALE_FACTOR );
+
+ textmod = &module->Value(); // Dirty trick for the second iteration
+ }
+
+ // The SHEET is a 'generic description' for referencing the component
+ fprintf( aFile, "SHEET \"RefDes: %s, Value: %s\"\n",
+ TO_UTF8( module->GetReference() ),
+ TO_UTF8( module->GetValue() ) );
+ }
+
+ fputs( "$ENDCOMPONENTS\n\n", aFile );
+}
+
+
+/* Emit the netlist (which is actually the thing for which GenCAD is used these
+ * days!); tracks are handled later */
+static void CreateSignalsSection( FILE* aFile, BOARD* aPcb )
+{
+ wxString msg;
+ NETINFO_ITEM* net;
+ D_PAD* pad;
+ MODULE* module;
+ int NbNoConn = 1;
+
+ fputs( "$SIGNALS\n", aFile );
+
+ for( unsigned ii = 0; ii < aPcb->GetNetCount(); ii++ )
+ {
+ net = aPcb->FindNet( ii );
+
+ if( net->GetNetname() == wxEmptyString ) // dummy netlist (no connection)
+ {
+ wxString msg; msg << wxT( "NoConnection" ) << NbNoConn++;
+ }
+
+ if( net->GetNet() <= 0 ) // dummy netlist (no connection)
+ continue;
+
+ msg = wxT( "SIGNAL " ) + net->GetNetname();
+
+ fputs( TO_UTF8( msg ), aFile );
+ fputs( "\n", aFile );
+
+ for( module = aPcb->m_Modules; module; module = module->Next() )
+ {
+ for( pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ wxString padname;
+
+ if( pad->GetNetCode() != net->GetNet() )
+ continue;
+
+ pad->StringPadName( padname );
+ msg.Printf( wxT( "NODE %s %s" ),
+ GetChars( module->GetReference() ),
+ GetChars( padname ) );
+
+ fputs( TO_UTF8( msg ), aFile );
+ fputs( "\n", aFile );
+ }
+ }
+ }
+
+ fputs( "$ENDSIGNALS\n\n", aFile );
+}
+
+
+// Creates the header section
+static bool CreateHeaderInfoData( FILE* aFile, PCB_EDIT_FRAME* aFrame )
+{
+ wxString msg;
+ BOARD *board = aFrame->GetBoard();
+
+ fputs( "$HEADER\n", aFile );
+ fputs( "GENCAD 1.4\n", aFile );
+
+ // Please note: GenCAD syntax requires quoted strings if they can contain spaces
+ msg.Printf( wxT( "USER \"%s %s\"\n" ),
+ GetChars( Pgm().App().GetAppName() ),
+ GetChars( GetBuildVersion() ) );
+ fputs( TO_UTF8( msg ), aFile );
+
+ msg = wxT( "DRAWING \"" ) + board->GetFileName() + wxT( "\"\n" );
+ fputs( TO_UTF8( msg ), aFile );
+
+ const TITLE_BLOCK& tb = aFrame->GetTitleBlock();
+
+ msg = wxT( "REVISION \"" ) + tb.GetRevision() + wxT( " " ) + tb.GetDate() + wxT( "\"\n" );
+
+ fputs( TO_UTF8( msg ), aFile );
+ fputs( "UNITS INCH\n", aFile );
+
+ msg.Printf( wxT( "ORIGIN %g %g\n" ),
+ MapXTo( aFrame->GetAuxOrigin().x ),
+ MapYTo( aFrame->GetAuxOrigin().y ) );
+ fputs( TO_UTF8( msg ), aFile );
+
+ fputs( "INTERTRACK 0\n", aFile );
+ fputs( "$ENDHEADER\n\n", aFile );
+
+ return true;
+}
+
+
+/*
+ * Sort function used to sort tracks segments:
+ * items are sorted by netcode, then by width then by layer
+ */
+static int TrackListSortByNetcode( const void* refptr, const void* objptr )
+{
+ const TRACK* ref, * cmp;
+ int diff;
+
+ ref = *( (TRACK**) refptr );
+ cmp = *( (TRACK**) objptr );
+
+ if( ( diff = ref->GetNetCode() - cmp->GetNetCode() ) )
+ return diff;
+
+ if( ( diff = ref->GetWidth() - cmp->GetWidth() ) )
+ return diff;
+
+ if( ( diff = ref->GetLayer() - cmp->GetLayer() ) )
+ return diff;
+
+ return 0;
+}
+
+
+/* Creates the section ROUTES
+ * that handles tracks, vias
+ * TODO: add zones
+ * section:
+ * $ROUTE
+ * ...
+ * $ENROUTE
+ * Track segments must be sorted by nets
+ */
+static void CreateRoutesSection( FILE* aFile, BOARD* aPcb )
+{
+ TRACK* track, ** tracklist;
+ int vianum = 1;
+ int old_netcode, old_width, old_layer;
+ int nbitems, ii;
+ LSET master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
+
+ int cu_count = aPcb->GetCopperLayerCount();
+
+ // Count items
+ nbitems = 0;
+
+ for( track = aPcb->m_Track; track; track = track->Next() )
+ nbitems++;
+
+ for( track = aPcb->m_Zone; track; track = track->Next() )
+ {
+ if( track->Type() == PCB_ZONE_T )
+ nbitems++;
+ }
+
+ tracklist = (TRACK**) operator new( (nbitems + 1)* sizeof( TRACK* ) );
+
+ nbitems = 0;
+
+ for( track = aPcb->m_Track; track; track = track->Next() )
+ tracklist[nbitems++] = track;
+
+ for( track = aPcb->m_Zone; track; track = track->Next() )
+ {
+ if( track->Type() == PCB_ZONE_T )
+ tracklist[nbitems++] = track;
+ }
+
+ tracklist[nbitems] = NULL;
+
+ qsort( tracklist, nbitems, sizeof(TRACK*), TrackListSortByNetcode );
+
+ fputs( "$ROUTES\n", aFile );
+
+ old_netcode = -1; old_width = -1; old_layer = -1;
+
+ for( ii = 0; ii < nbitems; ii++ )
+ {
+ track = tracklist[ii];
+
+ if( old_netcode != track->GetNetCode() )
+ {
+ old_netcode = track->GetNetCode();
+ NETINFO_ITEM* net = track->GetNet();
+ wxString netname;
+
+ if( net && (net->GetNetname() != wxEmptyString) )
+ netname = net->GetNetname();
+ else
+ netname = wxT( "_noname_" );
+
+ fprintf( aFile, "ROUTE %s\n", TO_UTF8( netname ) );
+ }
+
+ if( old_width != track->GetWidth() )
+ {
+ old_width = track->GetWidth();
+ fprintf( aFile, "TRACK TRACK%d\n", track->GetWidth() );
+ }
+
+ if( (track->Type() == PCB_TRACE_T) || (track->Type() == PCB_ZONE_T) )
+ {
+ if( old_layer != track->GetLayer() )
+ {
+ old_layer = track->GetLayer();
+ fprintf( aFile, "LAYER %s\n",
+ GenCADLayerName( cu_count, track->GetLayer() ).c_str()
+ );
+ }
+
+ fprintf( aFile, "LINE %g %g %g %g\n",
+ MapXTo( track->GetStart().x ), MapYTo( track->GetStart().y ),
+ MapXTo( track->GetEnd().x ), MapYTo( track->GetEnd().y ) );
+ }
+
+ if( track->Type() == PCB_VIA_T )
+ {
+ const VIA* via = static_cast<const VIA*>(track);
+
+ LSET vset = via->GetLayerSet() & master_layermask;
+
+ fprintf( aFile, "VIA VIA%d.%d.%s %g %g ALL %g via%d\n",
+ via->GetWidth(), via->GetDrillValue(),
+ fmt_mask( vset ).c_str(),
+ MapXTo( via->GetStart().x ), MapYTo( via->GetStart().y ),
+ via->GetDrillValue() / SCALE_FACTOR, vianum++ );
+ }
+ }
+
+ fputs( "$ENDROUTES\n\n", aFile );
+
+ delete tracklist;
+}
+
+
+/* Creates the section $DEVICES
+ * This is a list of footprints properties
+ * ( Shapes are in section $SHAPE )
+ */
+static void CreateDevicesSection( FILE* aFile, BOARD* aPcb )
+{
+ MODULE* module;
+
+ fputs( "$DEVICES\n", aFile );
+
+ for( module = aPcb->m_Modules; module; module = module->Next() )
+ {
+ fprintf( aFile, "DEVICE \"%s\"\n", TO_UTF8( module->GetReference() ) );
+ fprintf( aFile, "PART \"%s\"\n", TO_UTF8( module->GetValue() ) );
+ fprintf( aFile, "PACKAGE \"%s\"\n", module->GetFPID().Format().c_str() );
+
+ // The TYPE attribute is almost freeform
+ const char* ty = "TH";
+
+ if( module->GetAttributes() & MOD_CMS )
+ ty = "SMD";
+
+ if( module->GetAttributes() & MOD_VIRTUAL )
+ ty = "VIRTUAL";
+
+ fprintf( aFile, "TYPE %s\n", ty );
+ }
+
+ fputs( "$ENDDEVICES\n\n", aFile );
+}
+
+
+/* Creates the section $BOARD.
+ * We output here only the board perimeter
+ */
+static void CreateBoardSection( FILE* aFile, BOARD* aPcb )
+{
+ fputs( "$BOARD\n", aFile );
+
+ // Extract the board edges
+ for( EDA_ITEM* drawing = aPcb->m_Drawings; drawing != 0;
+ drawing = drawing->Next() )
+ {
+ if( drawing->Type() == PCB_LINE_T )
+ {
+ DRAWSEGMENT* drawseg = static_cast<DRAWSEGMENT*>( drawing );
+ if( drawseg->GetLayer() == Edge_Cuts )
+ {
+ // XXX GenCAD supports arc boundaries but I've seen nothing that reads them
+ fprintf( aFile, "LINE %g %g %g %g\n",
+ MapXTo( drawseg->GetStart().x ), MapYTo( drawseg->GetStart().y ),
+ MapXTo( drawseg->GetEnd().x ), MapYTo( drawseg->GetEnd().y ) );
+ }
+ }
+ }
+
+ fputs( "$ENDBOARD\n\n", aFile );
+}
+
+
+/* Creates the section "$TRACKS"
+ * This sections give the list of widths (tools) used in tracks and vias
+ * format:
+ * $TRACK
+ * TRACK <name> <width>
+ * $ENDTRACK
+ *
+ * Each tool name is build like this: "TRACK" + track width.
+ * For instance for a width = 120 : name = "TRACK120".
+ */
+static void CreateTracksInfoData( FILE* aFile, BOARD* aPcb )
+{
+ TRACK* track;
+ int last_width = -1;
+
+ // Find thickness used for traces
+ // XXX could use the same sorting approach used for pads
+
+ std::vector <int> trackinfo;
+
+ unsigned ii;
+
+ for( track = aPcb->m_Track; track; track = track->Next() )
+ {
+ if( last_width != track->GetWidth() ) // Find a thickness already used.
+ {
+ for( ii = 0; ii < trackinfo.size(); ii++ )
+ {
+ if( trackinfo[ii] == track->GetWidth() )
+ break;
+ }
+
+ if( ii == trackinfo.size() ) // not found
+ trackinfo.push_back( track->GetWidth() );
+
+ last_width = track->GetWidth();
+ }
+ }
+
+ for( track = aPcb->m_Zone; track; track = track->Next() )
+ {
+ if( last_width != track->GetWidth() ) // Find a thickness already used.
+ {
+ for( ii = 0; ii < trackinfo.size(); ii++ )
+ {
+ if( trackinfo[ii] == track->GetWidth() )
+ break;
+ }
+
+ if( ii == trackinfo.size() ) // not found
+ trackinfo.push_back( track->GetWidth() );
+
+ last_width = track->GetWidth();
+ }
+ }
+
+ // Write data
+ fputs( "$TRACKS\n", aFile );
+
+ for( ii = 0; ii < trackinfo.size(); ii++ )
+ {
+ fprintf( aFile, "TRACK TRACK%d %g\n", trackinfo[ii],
+ trackinfo[ii] / SCALE_FACTOR );
+ }
+
+ fputs( "$ENDTRACKS\n\n", aFile );
+}
+
+
+/* Creates the shape of a footprint (section SHAPE)
+ * The shape is always given "normal" (Orient 0, not mirrored)
+ * It's almost guaranteed that the silk layer will be imported wrong but
+ * the shape also contains the pads!
+ */
+static void FootprintWriteShape( FILE* aFile, MODULE* module )
+{
+ EDGE_MODULE* PtEdge;
+ EDA_ITEM* PtStruct;
+
+ // Control Y axis change sign for flipped modules
+ int Yaxis_sign = -1;
+
+ // Flip for bottom side components
+ if( module->GetFlag() )
+ Yaxis_sign = 1;
+
+ /* creates header: */
+ fprintf( aFile, "\nSHAPE %s\n", TO_UTF8( module->GetReference() ) );
+
+ if( module->GetAttributes() & MOD_VIRTUAL )
+ {
+ fprintf( aFile, "INSERT SMD\n" );
+ }
+ else
+ {
+ if( module->GetAttributes() & MOD_CMS )
+ {
+ fprintf( aFile, "INSERT SMD\n" );
+ }
+ else
+ {
+ fprintf( aFile, "INSERT TH\n" );
+ }
+ }
+
+#if 0 /* ATTRIBUTE name and value is unspecified and the original exporter
+ * got the syntax wrong, so CAM350 rejected the whole shape! */
+
+ if( module->m_Attributs != MOD_DEFAULT )
+ {
+ fprintf( aFile, "ATTRIBUTE" );
+
+ if( module->m_Attributs & MOD_CMS )
+ fprintf( aFile, " PAD_SMD" );
+
+ if( module->m_Attributs & MOD_VIRTUAL )
+ fprintf( aFile, " VIRTUAL" );
+
+ fprintf( aFile, "\n" );
+ }
+#endif
+
+ // Silk outline; wildly interpreted by various importers:
+ // CAM350 read it right but only closed shapes
+ // ProntoPlace double-flip it (at least the pads are correct)
+ // GerberTool usually get it right...
+ for( PtStruct = module->GraphicalItems(); PtStruct; PtStruct = PtStruct->Next() )
+ {
+ switch( PtStruct->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+
+ // If we wanted to export text, this is not the correct section
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ PtEdge = (EDGE_MODULE*) PtStruct;
+ if( PtEdge->GetLayer() == F_SilkS
+ || PtEdge->GetLayer() == B_SilkS )
+ {
+ switch( PtEdge->GetShape() )
+ {
+ case S_SEGMENT:
+ fprintf( aFile, "LINE %g %g %g %g\n",
+ (PtEdge->m_Start0.x) / SCALE_FACTOR,
+ (Yaxis_sign * PtEdge->m_Start0.y) / SCALE_FACTOR,
+ (PtEdge->m_End0.x) / SCALE_FACTOR,
+ (Yaxis_sign * PtEdge->m_End0.y ) / SCALE_FACTOR );
+ break;
+
+ case S_CIRCLE:
+ {
+ int radius = KiROUND( GetLineLength( PtEdge->m_End0,
+ PtEdge->m_Start0 ) );
+ fprintf( aFile, "CIRCLE %g %g %g\n",
+ PtEdge->m_Start0.x / SCALE_FACTOR,
+ Yaxis_sign * PtEdge->m_Start0.y / SCALE_FACTOR,
+ radius / SCALE_FACTOR );
+ break;
+ }
+
+ case S_ARC:
+ {
+ int arcendx, arcendy;
+ arcendx = PtEdge->m_End0.x - PtEdge->m_Start0.x;
+ arcendy = PtEdge->m_End0.y - PtEdge->m_Start0.y;
+ RotatePoint( &arcendx, &arcendy, -PtEdge->GetAngle() );
+ arcendx += PtEdge->GetStart0().x;
+ arcendy += PtEdge->GetStart0().y;
+ if( Yaxis_sign == -1 )
+ {
+ // Flipping Y flips the arc direction too
+ fprintf( aFile, "ARC %g %g %g %g %g %g\n",
+ (arcendx) / SCALE_FACTOR,
+ (Yaxis_sign * arcendy) / SCALE_FACTOR,
+ (PtEdge->m_End0.x) / SCALE_FACTOR,
+ (Yaxis_sign * PtEdge->GetEnd0().y) / SCALE_FACTOR,
+ (PtEdge->GetStart0().x) / SCALE_FACTOR,
+ (Yaxis_sign * PtEdge->GetStart0().y) / SCALE_FACTOR );
+ }
+ else
+ {
+ fprintf( aFile, "ARC %g %g %g %g %g %g\n",
+ (PtEdge->GetEnd0().x) / SCALE_FACTOR,
+ (Yaxis_sign * PtEdge->GetEnd0().y) / SCALE_FACTOR,
+ (arcendx) / SCALE_FACTOR,
+ (Yaxis_sign * arcendy) / SCALE_FACTOR,
+ (PtEdge->GetStart0().x) / SCALE_FACTOR,
+ (Yaxis_sign * PtEdge->GetStart0().y) / SCALE_FACTOR );
+ }
+ break;
+ }
+
+ default:
+ DisplayError( NULL, wxT( "Type Edge Module invalid." ) );
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
diff --git a/pcbnew/exporters/export_idf.cpp b/pcbnew/exporters/export_idf.cpp
new file mode 100644
index 0000000..51a61cc
--- /dev/null
+++ b/pcbnew/exporters/export_idf.cpp
@@ -0,0 +1,609 @@
+/**
+ * @file export_idf.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Cirilo Bernardo
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <list>
+#include <wxPcbStruct.h>
+#include <macros.h>
+#include <pcbnew.h>
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+#include <idf_parser.h>
+#include <3d_struct.h>
+#include <build_version.h>
+#include <convert_from_iu.h>
+
+#ifndef PCBNEW
+#define PCBNEW // needed to define the right value of Millimeter2iu(x)
+#endif
+#include <convert_to_biu.h> // to define Millimeter2iu(x)
+
+// assumed default graphical line thickness: == 0.1mm
+#define LINE_WIDTH (Millimeter2iu( 0.1 ))
+
+/**
+ * Function idf_export_outline
+ * retrieves line segment information from the edge layer and compiles
+ * the data into a form which can be output as an IDFv3 compliant
+ * BOARD_OUTLINE section.
+ */
+static void idf_export_outline( BOARD* aPcb, IDF3_BOARD& aIDFBoard )
+{
+ double scale = aIDFBoard.GetUserScale();
+
+ DRAWSEGMENT* graphic; // KiCad graphical item
+ IDF_POINT sp, ep; // start and end points from KiCad item
+
+ std::list< IDF_SEGMENT* > lines; // IDF intermediate form of KiCad graphical item
+ IDF_OUTLINE* outline = NULL; // graphical items forming an outline or cutout
+
+ // NOTE: IMPLEMENTATION
+ // If/when component cutouts are allowed, we must implement them separately. Cutouts
+ // must be added to the board outline section and not to the Other Outline section.
+ // The module cutouts should be handled via the idf_export_module() routine.
+
+ double offX, offY;
+ aIDFBoard.GetUserOffset( offX, offY );
+
+ // Retrieve segments and arcs from the board
+ for( BOARD_ITEM* item = aPcb->m_Drawings; item; item = item->Next() )
+ {
+ if( item->Type() != PCB_LINE_T || item->GetLayer() != Edge_Cuts )
+ continue;
+
+ graphic = (DRAWSEGMENT*) item;
+
+ switch( graphic->GetShape() )
+ {
+ case S_SEGMENT:
+ {
+ if( ( graphic->GetStart().x == graphic->GetEnd().x )
+ && ( graphic->GetStart().y == graphic->GetEnd().y ) )
+ break;
+
+ sp.x = graphic->GetStart().x * scale + offX;
+ sp.y = -graphic->GetStart().y * scale + offY;
+ ep.x = graphic->GetEnd().x * scale + offX;
+ ep.y = -graphic->GetEnd().y * scale + offY;
+ IDF_SEGMENT* seg = new IDF_SEGMENT( sp, ep );
+
+ if( seg )
+ lines.push_back( seg );
+ }
+ break;
+
+ case S_ARC:
+ {
+ if( ( graphic->GetCenter().x == graphic->GetArcStart().x )
+ && ( graphic->GetCenter().y == graphic->GetArcStart().y ) )
+ break;
+
+ sp.x = graphic->GetCenter().x * scale + offX;
+ sp.y = -graphic->GetCenter().y * scale + offY;
+ ep.x = graphic->GetArcStart().x * scale + offX;
+ ep.y = -graphic->GetArcStart().y * scale + offY;
+ IDF_SEGMENT* seg = new IDF_SEGMENT( sp, ep, -graphic->GetAngle() / 10.0, true );
+
+ if( seg )
+ lines.push_back( seg );
+ }
+ break;
+
+ case S_CIRCLE:
+ {
+ if( graphic->GetRadius() == 0 )
+ break;
+
+ sp.x = graphic->GetCenter().x * scale + offX;
+ sp.y = -graphic->GetCenter().y * scale + offY;
+ ep.x = sp.x - graphic->GetRadius() * scale;
+ ep.y = sp.y;
+ // Circles must always have an angle of +360 deg. to appease
+ // quirky MCAD implementations of IDF.
+ IDF_SEGMENT* seg = new IDF_SEGMENT( sp, ep, 360.0, true );
+
+ if( seg )
+ lines.push_back( seg );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // if there is no outline then use the bounding box
+ if( lines.empty() )
+ {
+ goto UseBoundingBox;
+ }
+
+ // get the board outline and write it out
+ // note: we do not use a try/catch block here since we intend
+ // to simply ignore unclosed loops and continue processing
+ // until we're out of segments to process
+ outline = new IDF_OUTLINE;
+ IDF3::GetOutline( lines, *outline );
+
+ if( outline->empty() )
+ goto UseBoundingBox;
+
+ aIDFBoard.AddBoardOutline( outline );
+ outline = NULL;
+
+ // get all cutouts and write them out
+ while( !lines.empty() )
+ {
+ if( !outline )
+ outline = new IDF_OUTLINE;
+
+ IDF3::GetOutline( lines, *outline );
+
+ if( outline->empty() )
+ {
+ outline->Clear();
+ continue;
+ }
+
+ aIDFBoard.AddBoardOutline( outline );
+ outline = NULL;
+ }
+
+ return;
+
+UseBoundingBox:
+
+ // clean up if necessary
+ while( !lines.empty() )
+ {
+ delete lines.front();
+ lines.pop_front();
+ }
+
+ if( outline )
+ outline->Clear();
+ else
+ outline = new IDF_OUTLINE;
+
+ // fetch a rectangular bounding box for the board;
+ // there is always some uncertainty in the board dimensions
+ // computed via ComputeBoundingBox() since this depends on the
+ // individual module entities.
+ EDA_RECT bbbox = aPcb->ComputeBoundingBox( true );
+
+ // convert to mm and compensate for an assumed LINE_WIDTH line thickness
+ double x = ( bbbox.GetOrigin().x + LINE_WIDTH / 2 ) * scale + offX;
+ double y = ( bbbox.GetOrigin().y + LINE_WIDTH / 2 ) * scale + offY;
+ double dx = ( bbbox.GetSize().x - LINE_WIDTH ) * scale;
+ double dy = ( bbbox.GetSize().y - LINE_WIDTH ) * scale;
+
+ double px[4], py[4];
+ px[0] = x;
+ py[0] = y;
+
+ px[1] = x;
+ py[1] = y + dy;
+
+ px[2] = x + dx;
+ py[2] = y + dy;
+
+ px[3] = x + dx;
+ py[3] = y;
+
+ IDF_POINT p1, p2;
+
+ p1.x = px[3];
+ p1.y = py[3];
+ p2.x = px[0];
+ p2.y = py[0];
+
+ outline->push( new IDF_SEGMENT( p1, p2 ) );
+
+ for( int i = 1; i < 4; ++i )
+ {
+ p1.x = px[i - 1];
+ p1.y = py[i - 1];
+ p2.x = px[i];
+ p2.y = py[i];
+
+ outline->push( new IDF_SEGMENT( p1, p2 ) );
+ }
+
+ aIDFBoard.AddBoardOutline( outline );
+}
+
+
+/**
+ * Function idf_export_module
+ * retrieves information from all board modules, adds drill holes to
+ * the DRILLED_HOLES or BOARD_OUTLINE section as appropriate,
+ * compiles data for the PLACEMENT section and compiles data for
+ * the library ELECTRICAL section.
+ */
+static void idf_export_module( BOARD* aPcb, MODULE* aModule,
+ IDF3_BOARD& aIDFBoard )
+{
+ // Reference Designator
+ std::string crefdes = TO_UTF8( aModule->GetReference() );
+
+ if( crefdes.empty() || !crefdes.compare( "~" ) )
+ {
+ std::string cvalue = TO_UTF8( aModule->GetValue() );
+
+ // if both the RefDes and Value are empty or set to '~' the board owns the part,
+ // otherwise associated parts of the module must be marked NOREFDES.
+ if( cvalue.empty() || !cvalue.compare( "~" ) )
+ crefdes = "BOARD";
+ else
+ crefdes = "NOREFDES";
+ }
+
+ // TODO: If module cutouts are supported we must add code here
+ // for( EDA_ITEM* item = aModule->GraphicalItems(); item != NULL; item = item->Next() )
+ // {
+ // if( ( item->Type() != PCB_MODULE_EDGE_T )
+ // || (item->GetLayer() != Edge_Cuts ) ) continue;
+ // code to export cutouts
+ // }
+
+ // Export pads
+ double drill, x, y;
+ double scale = aIDFBoard.GetUserScale();
+ IDF3::KEY_PLATING kplate;
+ std::string pintype;
+ std::string tstr;
+
+ double dx, dy;
+
+ aIDFBoard.GetUserOffset( dx, dy );
+
+ for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
+ {
+ drill = (double) pad->GetDrillSize().x * scale;
+ x = pad->GetPosition().x * scale + dx;
+ y = -pad->GetPosition().y * scale + dy;
+
+ // Export the hole on the edge layer
+ if( drill > 0.0 )
+ {
+ // plating
+ if( pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
+ kplate = IDF3::NPTH;
+ else
+ kplate = IDF3::PTH;
+
+ // hole type
+ tstr = TO_UTF8( pad->GetPadName() );
+
+ if( tstr.empty() || !tstr.compare( "0" ) || !tstr.compare( "~" )
+ || ( kplate == IDF3::NPTH )
+ ||( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ) )
+ pintype = "MTG";
+ else
+ pintype = "PIN";
+
+ // fields:
+ // 1. hole dia. : float
+ // 2. X coord : float
+ // 3. Y coord : float
+ // 4. plating : PTH | NPTH
+ // 5. Assoc. part : BOARD | NOREFDES | PANEL | {"refdes"}
+ // 6. type : PIN | VIA | MTG | TOOL | { "other" }
+ // 7. owner : MCAD | ECAD | UNOWNED
+ if( ( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG )
+ && ( pad->GetDrillSize().x != pad->GetDrillSize().y ) )
+ {
+ // NOTE: IDF does not have direct support for slots;
+ // slots are implemented as a board cutout and we
+ // cannot represent plating or reference designators
+
+ double dlength = pad->GetDrillSize().y * scale;
+
+ // NOTE: The orientation of modules and pads have
+ // the opposite sense due to KiCad drawing on a
+ // screen with a LH coordinate system
+ double angle = pad->GetOrientation() / 10.0;
+
+ // NOTE: Since this code assumes the scenario where
+ // GetDrillSize().y is the length but idf_parser.cpp
+ // assumes a length along the X axis, the orientation
+ // must be shifted +90 deg when GetDrillSize().y is
+ // the major axis.
+
+ if( dlength < drill )
+ {
+ std::swap( drill, dlength );
+ }
+ else
+ {
+ angle += 90.0;
+ }
+
+ // NOTE: KiCad measures a slot's length from end to end
+ // rather than between the centers of the arcs
+ dlength -= drill;
+
+ aIDFBoard.AddSlot( drill, dlength, angle, x, y );
+ }
+ else
+ {
+ IDF_DRILL_DATA *dp = new IDF_DRILL_DATA( drill, x, y, kplate, crefdes,
+ pintype, IDF3::ECAD );
+
+ if( !aIDFBoard.AddDrill( dp ) )
+ {
+ delete dp;
+
+ std::ostringstream ostr;
+ ostr << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__;
+ ostr << "(): could not add drill";
+
+ throw std::runtime_error( ostr.str() );
+ }
+ }
+ }
+ }
+
+ // add any valid models to the library item list
+ std::string refdes;
+
+ IDF3_COMPONENT* comp = NULL;
+
+ for( S3D_MASTER* modfile = aModule->Models(); modfile != 0; modfile = modfile->Next() )
+ {
+ if( !modfile->Is3DType( S3D_MASTER::FILE3D_IDF ) )
+ continue;
+
+ if( refdes.empty() )
+ {
+ refdes = TO_UTF8( aModule->GetReference() );
+
+ // NOREFDES cannot be used or else the software gets confused
+ // when writing out the placement data due to conflicting
+ // placement and layer specifications; to work around this we
+ // create a (hopefully) unique refdes for our exported part.
+ if( refdes.empty() || !refdes.compare( "~" ) )
+ refdes = aIDFBoard.GetNewRefDes();
+ }
+
+ IDF3_COMP_OUTLINE* outline;
+
+ outline = aIDFBoard.GetComponentOutline( modfile->GetShape3DFullFilename() );
+
+ if( !outline )
+ throw( std::runtime_error( aIDFBoard.GetError() ) );
+
+ double rotz = aModule->GetOrientation()/10.0;
+ double locx = modfile->m_MatPosition.x * 25.4; // part offsets are in inches
+ double locy = modfile->m_MatPosition.y * 25.4;
+ double locz = modfile->m_MatPosition.z * 25.4;
+ double lrot = modfile->m_MatRotation.z;
+
+ bool top = ( aModule->GetLayer() == B_Cu ) ? false : true;
+
+ if( top )
+ {
+ rotz += modfile->m_MatRotation.z;
+ locy = -locy;
+ RotatePoint( &locx, &locy, aModule->GetOrientation() );
+ locy = -locy;
+ }
+
+ if( !top )
+ {
+ RotatePoint( &locx, &locy, aModule->GetOrientation() );
+ locy = -locy;
+
+ rotz = 180.0 - rotz;
+
+ if( rotz >= 360.0 )
+ while( rotz >= 360.0 ) rotz -= 360.0;
+
+ if( rotz <= -360.0 )
+ while( rotz <= -360.0 ) rotz += 360.0;
+ }
+
+ if( comp == NULL )
+ comp = aIDFBoard.FindComponent( refdes );
+
+ if( comp == NULL )
+ {
+ comp = new IDF3_COMPONENT( &aIDFBoard );
+
+ if( comp == NULL )
+ throw( std::runtime_error( aIDFBoard.GetError() ) );
+
+ comp->SetRefDes( refdes );
+
+ if( top )
+ comp->SetPosition( aModule->GetPosition().x * scale + dx,
+ -aModule->GetPosition().y * scale + dy,
+ rotz, IDF3::LYR_TOP );
+ else
+ comp->SetPosition( aModule->GetPosition().x * scale + dx,
+ -aModule->GetPosition().y * scale + dy,
+ rotz, IDF3::LYR_BOTTOM );
+
+ comp->SetPlacement( IDF3::PS_ECAD );
+
+ aIDFBoard.AddComponent( comp );
+ }
+ else
+ {
+ double refX, refY, refA;
+ IDF3::IDF_LAYER side;
+
+ if( ! comp->GetPosition( refX, refY, refA, side ) )
+ {
+ // place the item
+ if( top )
+ comp->SetPosition( aModule->GetPosition().x * scale + dx,
+ -aModule->GetPosition().y * scale + dy,
+ rotz, IDF3::LYR_TOP );
+ else
+ comp->SetPosition( aModule->GetPosition().x * scale + dx,
+ -aModule->GetPosition().y * scale + dy,
+ rotz, IDF3::LYR_BOTTOM );
+
+ comp->SetPlacement( IDF3::PS_ECAD );
+
+ }
+ else
+ {
+ // check that the retrieved component matches this one
+ refX = refX - ( aModule->GetPosition().x * scale + dx );
+ refY = refY - ( -aModule->GetPosition().y * scale + dy );
+ refA = refA - rotz;
+ refA *= refA;
+ refX *= refX;
+ refY *= refY;
+ refX += refY;
+
+ // conditions: same side, X,Y coordinates within 10 microns,
+ // angle within 0.01 degree
+ if( ( top && side == IDF3::LYR_BOTTOM ) || ( !top && side == IDF3::LYR_TOP )
+ || ( refA > 0.0001 ) || ( refX > 0.0001 ) )
+ {
+ comp->GetPosition( refX, refY, refA, side );
+
+ std::ostringstream ostr;
+ ostr << "* " << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "():\n";
+ ostr << "* conflicting Reference Designator '" << refdes << "'\n";
+ ostr << "* X loc: " << (aModule->GetPosition().x * scale + dx);
+ ostr << " vs. " << refX << "\n";
+ ostr << "* Y loc: " << (-aModule->GetPosition().y * scale + dy);
+ ostr << " vs. " << refY << "\n";
+ ostr << "* angle: " << rotz;
+ ostr << " vs. " << refA << "\n";
+
+ if( top )
+ ostr << "* TOP vs. ";
+ else
+ ostr << "* BOTTOM vs. ";
+
+ if( side == IDF3::LYR_TOP )
+ ostr << "TOP";
+ else
+ ostr << "BOTTOM";
+
+ throw( std::runtime_error( ostr.str() ) );
+ }
+ }
+ }
+
+
+ // create the local data ...
+ IDF3_COMP_OUTLINE_DATA* data = new IDF3_COMP_OUTLINE_DATA( comp, outline );
+
+ data->SetOffsets( locx, locy, locz, lrot );
+ comp->AddOutlineData( data );
+ }
+
+ return;
+}
+
+
+/**
+ * Function Export_IDF3
+ * generates IDFv3 compliant board (*.emn) and library (*.emp)
+ * files representing the user's PCB design.
+ */
+bool Export_IDF3( BOARD* aPcb, const wxString& aFullFileName, bool aUseThou,
+ double aXRef, double aYRef )
+{
+ IDF3_BOARD idfBoard( IDF3::CAD_ELEC );
+
+ // Switch the locale to standard C (needed to print floating point numbers)
+ LOCALE_IO toggle;
+
+ bool ok = true;
+ double scale = MM_PER_IU; // we must scale internal units to mm for IDF
+ IDF3::IDF_UNIT idfUnit;
+
+ if( aUseThou )
+ {
+ idfUnit = IDF3::UNIT_THOU;
+ idfBoard.SetUserPrecision( 1 );
+ }
+ else
+ {
+ idfUnit = IDF3::UNIT_MM;
+ idfBoard.SetUserPrecision( 5 );
+ }
+
+ wxFileName brdName = aPcb->GetFileName();
+
+ idfBoard.SetUserScale( scale );
+ idfBoard.SetBoardThickness( aPcb->GetDesignSettings().GetBoardThickness() * scale );
+ idfBoard.SetBoardName( TO_UTF8( brdName.GetFullName() ) );
+ idfBoard.SetBoardVersion( 0 );
+ idfBoard.SetLibraryVersion( 0 );
+
+ std::ostringstream ostr;
+ ostr << "KiCad " << TO_UTF8( GetBuildVersion() );
+ idfBoard.SetIDFSource( ostr.str() );
+
+ try
+ {
+ // set up the board reference point
+ idfBoard.SetUserOffset( -aXRef, aYRef );
+
+ // Export the board outline
+ idf_export_outline( aPcb, idfBoard );
+
+ // Output the drill holes and module (library) data.
+ for( MODULE* module = aPcb->m_Modules; module != 0; module = module->Next() )
+ idf_export_module( aPcb, module, idfBoard );
+
+ if( !idfBoard.WriteFile( aFullFileName, idfUnit, false ) )
+ {
+ wxString msg;
+ msg << _( "IDF Export Failed:\n" ) << FROM_UTF8( idfBoard.GetError().c_str() );
+ wxMessageBox( msg );
+
+ ok = false;
+ }
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg;
+ msg << _( "IDF Export Failed:\n" ) << ioe.errorText;
+ wxMessageBox( msg );
+
+ ok = false;
+ }
+ catch( const std::exception& e )
+ {
+ wxString msg;
+ msg << _( "IDF Export Failed:\n" ) << FROM_UTF8( e.what() );
+ wxMessageBox( msg );
+ ok = false;
+ }
+
+ return ok;
+}
diff --git a/pcbnew/exporters/export_vrml.cpp b/pcbnew/exporters/export_vrml.cpp
new file mode 100644
index 0000000..178e7c8
--- /dev/null
+++ b/pcbnew/exporters/export_vrml.cpp
@@ -0,0 +1,1408 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009-2013 Lorenzo Mercantonio
+ * Copyright (C) 2014 Cirilo Bernado
+ * Copyright (C) 2013 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <kicad_string.h>
+#include <wxPcbStruct.h>
+#include <drawtxt.h>
+#include <trigo.h>
+#include <pgm_base.h>
+#include <3d_struct.h>
+#include <macros.h>
+#include <exception>
+#include <fstream>
+#include <iomanip>
+
+#include <pcbnew.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_zone.h>
+#include <class_edge_mod.h>
+#include <class_pcb_text.h>
+#include <convert_from_iu.h>
+
+#include "../3d-viewer/modelparsers.h"
+
+#include <vector>
+#include <cmath>
+#include <vrml_layer.h>
+
+// minimum width (mm) of a VRML line
+#define MIN_VRML_LINEWIDTH 0.12
+
+// offset for art layers, mm (silk, paste, etc)
+#define ART_OFFSET 0.025
+
+
+struct VRML_COLOR
+{
+ float diffuse_red;
+ float diffuse_grn;
+ float diffuse_blu;
+
+ float spec_red;
+ float spec_grn;
+ float spec_blu;
+
+ float emit_red;
+ float emit_grn;
+ float emit_blu;
+
+ float ambient;
+ float transp;
+ float shiny;
+
+ VRML_COLOR()
+ {
+ // default green
+ diffuse_red = 0.13;
+ diffuse_grn = 0.81;
+ diffuse_blu = 0.22;
+ spec_red = 0.13;
+ spec_grn = 0.81;
+ spec_blu = 0.22;
+ emit_red = 0.0;
+ emit_grn = 0.0;
+ emit_blu = 0.0;
+
+ ambient = 1.0;
+ transp = 0;
+ shiny = 0.2;
+ }
+
+ VRML_COLOR( float dr, float dg, float db,
+ float sr, float sg, float sb,
+ float er, float eg, float eb,
+ float am, float tr, float sh )
+ {
+ diffuse_red = dr;
+ diffuse_grn = dg;
+ diffuse_blu = db;
+ spec_red = sr;
+ spec_grn = sg;
+ spec_blu = sb;
+ emit_red = er;
+ emit_grn = eg;
+ emit_blu = eb;
+
+ ambient = am;
+ transp = tr;
+ shiny = sh;
+ }
+};
+
+
+enum VRML_COLOR_INDEX
+{
+ VRML_COLOR_PCB = 0,
+ VRML_COLOR_TRACK,
+ VRML_COLOR_SILK,
+ VRML_COLOR_TIN,
+ VRML_COLOR_LAST
+};
+
+
+class MODEL_VRML
+{
+private:
+ double layer_z[LAYER_ID_COUNT];
+ VRML_COLOR colors[VRML_COLOR_LAST];
+
+ int iMaxSeg; // max. sides to a small circle
+ double arcMinLen, arcMaxLen; // min and max lengths of an arc chord
+
+public:
+ VRML_LAYER holes;
+ VRML_LAYER board;
+ VRML_LAYER top_copper;
+ VRML_LAYER bot_copper;
+ VRML_LAYER top_silk;
+ VRML_LAYER bot_silk;
+ VRML_LAYER top_tin;
+ VRML_LAYER bot_tin;
+ VRML_LAYER plated_holes;
+
+ bool plainPCB;
+
+ double scale; // board internal units to output scaling
+ double minLineWidth; // minimum width of a VRML line segment
+ int precision; // precision of output units
+
+ double tx; // global translation along X
+ double ty; // global translation along Y
+
+ double board_thickness; // depth of the PCB
+
+ LAYER_NUM s_text_layer;
+ int s_text_width;
+
+ MODEL_VRML()
+ {
+ for( unsigned i = 0; i < DIM( layer_z ); ++i )
+ layer_z[i] = 0;
+
+ holes.GetArcParams( iMaxSeg, arcMinLen, arcMaxLen );
+
+ // this default only makes sense if the output is in mm
+ board_thickness = 1.6;
+
+ // pcb green
+ colors[ VRML_COLOR_PCB ] = VRML_COLOR( .07, .3, .12, .07, .3, .12,
+ 0, 0, 0, 1, 0, 0.2 );
+ // track green
+ colors[ VRML_COLOR_TRACK ] = VRML_COLOR( .08, .5, .1, .08, .5, .1,
+ 0, 0, 0, 1, 0, 0.2 );
+ // silkscreen white
+ colors[ VRML_COLOR_SILK ] = VRML_COLOR( .9, .9, .9, .9, .9, .9,
+ 0, 0, 0, 1, 0, 0.2 );
+ // pad silver
+ colors[ VRML_COLOR_TIN ] = VRML_COLOR( .749, .756, .761, .749, .756, .761,
+ 0, 0, 0, 0.8, 0, 0.8 );
+
+ plainPCB = false;
+ SetScale( 1.0 );
+ SetOffset( 0.0, 0.0 );
+ s_text_layer = F_Cu;
+ s_text_width = 1;
+ }
+
+ VRML_COLOR& GetColor( VRML_COLOR_INDEX aIndex )
+ {
+ return colors[aIndex];
+ }
+
+ void SetOffset( double aXoff, double aYoff )
+ {
+ tx = aXoff;
+ ty = -aYoff;
+
+ holes.SetVertexOffsets( aXoff, aYoff );
+ board.SetVertexOffsets( aXoff, aYoff );
+ top_copper.SetVertexOffsets( aXoff, aYoff );
+ bot_copper.SetVertexOffsets( aXoff, aYoff );
+ top_silk.SetVertexOffsets( aXoff, aYoff );
+ bot_silk.SetVertexOffsets( aXoff, aYoff );
+ top_tin.SetVertexOffsets( aXoff, aYoff );
+ bot_tin.SetVertexOffsets( aXoff, aYoff );
+ plated_holes.SetVertexOffsets( aXoff, aYoff );
+ }
+
+ double GetLayerZ( LAYER_NUM aLayer )
+ {
+ if( unsigned( aLayer ) >= DIM( layer_z ) )
+ return 0;
+
+ return layer_z[ aLayer ];
+ }
+
+ void SetLayerZ( LAYER_NUM aLayer, double aValue )
+ {
+ layer_z[aLayer] = aValue;
+ }
+
+ // set the scaling of the VRML world
+ bool SetScale( double aWorldScale )
+ {
+ if( aWorldScale < 0.001 || aWorldScale > 10.0 )
+ throw( std::runtime_error( "WorldScale out of range (valid range is 0.001 to 10.0)" ) );
+
+ scale = aWorldScale * MM_PER_IU;
+ minLineWidth = aWorldScale * MIN_VRML_LINEWIDTH;
+
+ // set the precision of the VRML coordinates
+ if( aWorldScale < 0.01 )
+ precision = 8;
+ else if( aWorldScale < 0.1 )
+ precision = 7;
+ else if( aWorldScale< 1.0 )
+ precision = 6;
+ else if( aWorldScale < 10.0 )
+ precision = 5;
+ else
+ precision = 4;
+
+ double smin = arcMinLen * aWorldScale;
+ double smax = arcMaxLen * aWorldScale;
+
+ holes.SetArcParams( iMaxSeg, smin, smax );
+ board.SetArcParams( iMaxSeg, smin, smax );
+ top_copper.SetArcParams( iMaxSeg, smin, smax);
+ bot_copper.SetArcParams( iMaxSeg, smin, smax);
+ top_silk.SetArcParams( iMaxSeg, smin, smax );
+ bot_silk.SetArcParams( iMaxSeg, smin, smax );
+ top_tin.SetArcParams( iMaxSeg, smin, smax );
+ bot_tin.SetArcParams( iMaxSeg, smin, smax );
+ plated_holes.SetArcParams( iMaxSeg, smin, smax );
+
+ return true;
+ }
+
+};
+
+
+// static var. for dealing with text
+static MODEL_VRML* model_vrml;
+
+
+// select the VRML layer object to draw on; return true if
+// a layer has been selected.
+static bool GetLayer( MODEL_VRML& aModel, LAYER_NUM layer, VRML_LAYER** vlayer )
+{
+ switch( layer )
+ {
+ case B_Cu:
+ *vlayer = &aModel.bot_copper;
+ break;
+
+ case F_Cu:
+ *vlayer = &aModel.top_copper;
+ break;
+
+ case B_SilkS:
+ *vlayer = &aModel.bot_silk;
+ break;
+
+ case F_SilkS:
+ *vlayer = &aModel.top_silk;
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+
+static void write_triangle_bag( std::ofstream& output_file, VRML_COLOR& color,
+ VRML_LAYER* layer, bool plane, bool top,
+ double top_z, double bottom_z, int aPrecision )
+{
+ /* A lot of nodes are not required, but blender sometimes chokes
+ * without them */
+ static const char* shape_boiler[] =
+ {
+ "Transform {\n",
+ " children [\n",
+ " Group {\n",
+ " children [\n",
+ " Shape {\n",
+ " appearance Appearance {\n",
+ " material Material {\n",
+ 0, // Material marker
+ " }\n",
+ " }\n",
+ " geometry IndexedFaceSet {\n",
+ " solid TRUE\n",
+ " coord Coordinate {\n",
+ " point [\n",
+ 0, // Coordinates marker
+ " ]\n",
+ " }\n",
+ " coordIndex [\n",
+ 0, // Index marker
+ " ]\n",
+ " }\n",
+ " }\n",
+ " ]\n",
+ " }\n",
+ " ]\n",
+ "}\n",
+ 0 // End marker
+ };
+
+ int marker_found = 0, lineno = 0;
+
+ while( marker_found < 4 )
+ {
+ if( shape_boiler[lineno] )
+ output_file << shape_boiler[lineno];
+ else
+ {
+ marker_found++;
+
+ switch( marker_found )
+ {
+ case 1: // Material marker
+ output_file << " diffuseColor " << std::setprecision(3);
+ output_file << color.diffuse_red << " ";
+ output_file << color.diffuse_grn << " ";
+ output_file << color.diffuse_blu << "\n";
+
+ output_file << " specularColor ";
+ output_file << color.spec_red << " ";
+ output_file << color.spec_grn << " ";
+ output_file << color.spec_blu << "\n";
+
+ output_file << " emissiveColor ";
+ output_file << color.emit_red << " ";
+ output_file << color.emit_grn << " ";
+ output_file << color.emit_blu << "\n";
+
+ output_file << " ambientIntensity " << color.ambient << "\n";
+ output_file << " transparency " << color.transp << "\n";
+ output_file << " shininess " << color.shiny << "\n";
+ break;
+
+ case 2:
+
+ if( plane )
+ layer->WriteVertices( top_z, output_file, aPrecision );
+ else
+ layer->Write3DVertices( top_z, bottom_z, output_file, aPrecision );
+
+ output_file << "\n";
+ break;
+
+ case 3:
+
+ if( plane )
+ layer->WriteIndices( top, output_file );
+ else
+ layer->Write3DIndices( output_file );
+
+ output_file << "\n";
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ lineno++;
+ }
+}
+
+
+static void write_layers( MODEL_VRML& aModel, std::ofstream& output_file, BOARD* aPcb )
+{
+ // VRML_LAYER board;
+ aModel.board.Tesselate( &aModel.holes );
+ double brdz = aModel.board_thickness / 2.0
+ - ( Millimeter2iu( ART_OFFSET / 2.0 ) ) * aModel.scale;
+ write_triangle_bag( output_file, aModel.GetColor( VRML_COLOR_PCB ),
+ &aModel.board, false, false, brdz, -brdz, aModel.precision );
+
+ if( aModel.plainPCB )
+ return;
+
+ // VRML_LAYER top_copper;
+ aModel.top_copper.Tesselate( &aModel.holes );
+ write_triangle_bag( output_file, aModel.GetColor( VRML_COLOR_TRACK ),
+ &aModel.top_copper, true, true,
+ aModel.GetLayerZ( F_Cu ), 0, aModel.precision );
+
+ // VRML_LAYER top_tin;
+ aModel.top_tin.Tesselate( &aModel.holes );
+ write_triangle_bag( output_file, aModel.GetColor( VRML_COLOR_TIN ),
+ &aModel.top_tin, true, true,
+ aModel.GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * aModel.scale,
+ 0, aModel.precision );
+
+ // VRML_LAYER bot_copper;
+ aModel.bot_copper.Tesselate( &aModel.holes );
+ write_triangle_bag( output_file, aModel.GetColor( VRML_COLOR_TRACK ),
+ &aModel.bot_copper, true, false,
+ aModel.GetLayerZ( B_Cu ), 0, aModel.precision );
+
+ // VRML_LAYER bot_tin;
+ aModel.bot_tin.Tesselate( &aModel.holes );
+ write_triangle_bag( output_file, aModel.GetColor( VRML_COLOR_TIN ),
+ &aModel.bot_tin, true, false,
+ aModel.GetLayerZ( B_Cu )
+ - Millimeter2iu( ART_OFFSET / 2.0 ) * aModel.scale,
+ 0, aModel.precision );
+
+ // VRML_LAYER PTH;
+ aModel.plated_holes.Tesselate( NULL, true );
+ write_triangle_bag( output_file, aModel.GetColor( VRML_COLOR_TIN ),
+ &aModel.plated_holes, false, false,
+ aModel.GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * aModel.scale,
+ aModel.GetLayerZ( B_Cu ) - Millimeter2iu( ART_OFFSET / 2.0 ) * aModel.scale,
+ aModel.precision );
+
+ // VRML_LAYER top_silk;
+ aModel.top_silk.Tesselate( &aModel.holes );
+ write_triangle_bag( output_file, aModel.GetColor( VRML_COLOR_SILK ), &aModel.top_silk,
+ true, true, aModel.GetLayerZ( F_SilkS ), 0, aModel.precision );
+
+ // VRML_LAYER bot_silk;
+ aModel.bot_silk.Tesselate( &aModel.holes );
+ write_triangle_bag( output_file, aModel.GetColor( VRML_COLOR_SILK ), &aModel.bot_silk,
+ true, false, aModel.GetLayerZ( B_SilkS ), 0, aModel.precision );
+}
+
+
+static void compute_layer_Zs( MODEL_VRML& aModel, BOARD* pcb )
+{
+ int copper_layers = pcb->GetCopperLayerCount();
+
+ // We call it 'layer' thickness, but it's the whole board thickness!
+ aModel.board_thickness = pcb->GetDesignSettings().GetBoardThickness() * aModel.scale;
+ double half_thickness = aModel.board_thickness / 2;
+
+ // Compute each layer's Z value, more or less like the 3d view
+ for( LSEQ seq = LSET::AllCuMask().Seq(); seq; ++seq )
+ {
+ LAYER_ID i = *seq;
+
+ if( i < copper_layers )
+ aModel.SetLayerZ( i, half_thickness - aModel.board_thickness * i / (copper_layers - 1) );
+ else
+ aModel.SetLayerZ( i, - half_thickness ); // bottom layer
+ }
+
+ /* To avoid rounding interference, we apply an epsilon to each
+ * successive layer */
+ double epsilon_z = Millimeter2iu( ART_OFFSET ) * aModel.scale;
+ aModel.SetLayerZ( B_Paste, -half_thickness - epsilon_z * 4 );
+ aModel.SetLayerZ( B_Adhes, -half_thickness - epsilon_z * 3 );
+ aModel.SetLayerZ( B_SilkS, -half_thickness - epsilon_z * 2 );
+ aModel.SetLayerZ( B_Mask, -half_thickness - epsilon_z );
+ aModel.SetLayerZ( F_Mask, half_thickness + epsilon_z );
+ aModel.SetLayerZ( F_SilkS, half_thickness + epsilon_z * 2 );
+ aModel.SetLayerZ( F_Adhes, half_thickness + epsilon_z * 3 );
+ aModel.SetLayerZ( F_Paste, half_thickness + epsilon_z * 4 );
+ aModel.SetLayerZ( Dwgs_User, half_thickness + epsilon_z * 5 );
+ aModel.SetLayerZ( Cmts_User, half_thickness + epsilon_z * 6 );
+ aModel.SetLayerZ( Eco1_User, half_thickness + epsilon_z * 7 );
+ aModel.SetLayerZ( Eco2_User, half_thickness + epsilon_z * 8 );
+ aModel.SetLayerZ( Edge_Cuts, 0 );
+}
+
+
+static void export_vrml_line( MODEL_VRML& aModel, LAYER_NUM layer,
+ double startx, double starty,
+ double endx, double endy, double width )
+{
+ VRML_LAYER* vlayer;
+
+ if( !GetLayer( aModel, layer, &vlayer ) )
+ return;
+
+ if( width < aModel.minLineWidth)
+ width = aModel.minLineWidth;
+
+ starty = -starty;
+ endy = -endy;
+
+ double angle = atan2( endy - starty, endx - startx ) * 180.0 / M_PI;
+ double length = Distance( startx, starty, endx, endy ) + width;
+ double cx = ( startx + endx ) / 2.0;
+ double cy = ( starty + endy ) / 2.0;
+
+ if( !vlayer->AddSlot( cx, cy, length, width, angle, false ) )
+ throw( std::runtime_error( vlayer->GetError() ) );
+}
+
+
+static void export_vrml_circle( MODEL_VRML& aModel, LAYER_NUM layer,
+ double startx, double starty,
+ double endx, double endy, double width )
+{
+ VRML_LAYER* vlayer;
+
+ if( !GetLayer( aModel, layer, &vlayer ) )
+ return;
+
+ if( width < aModel.minLineWidth )
+ width = aModel.minLineWidth;
+
+ starty = -starty;
+ endy = -endy;
+
+ double hole, radius;
+
+ radius = Distance( startx, starty, endx, endy ) + ( width / 2);
+ hole = radius - width;
+
+ if( !vlayer->AddCircle( startx, starty, radius, false ) )
+ throw( std::runtime_error( vlayer->GetError() ) );
+
+ if( hole > 0.0001 )
+ {
+ if( !vlayer->AddCircle( startx, starty, hole, true ) )
+ throw( std::runtime_error( vlayer->GetError() ) );
+ }
+}
+
+
+static void export_vrml_arc( MODEL_VRML& aModel, LAYER_NUM layer,
+ double centerx, double centery,
+ double arc_startx, double arc_starty,
+ double width, double arc_angle )
+{
+ VRML_LAYER* vlayer;
+
+ if( !GetLayer( aModel, layer, &vlayer ) )
+ return;
+
+ if( width < aModel.minLineWidth )
+ width = aModel.minLineWidth;
+
+ centery = -centery;
+ arc_starty = -arc_starty;
+
+ if( !vlayer->AddArc( centerx, centery, arc_startx, arc_starty, width, -arc_angle, false ) )
+ throw( std::runtime_error( vlayer->GetError() ) );
+
+}
+
+
+static void export_vrml_drawsegment( MODEL_VRML& aModel, DRAWSEGMENT* drawseg )
+{
+ LAYER_NUM layer = drawseg->GetLayer();
+ double w = drawseg->GetWidth() * aModel.scale;
+ double x = drawseg->GetStart().x * aModel.scale;
+ double y = drawseg->GetStart().y * aModel.scale;
+ double xf = drawseg->GetEnd().x * aModel.scale;
+ double yf = drawseg->GetEnd().y * aModel.scale;
+ double r = sqrt( pow( x - xf, 2 ) + pow( y - yf, 2 ) );
+
+ // Items on the edge layer are handled elsewhere; just return
+ if( layer == Edge_Cuts )
+ return;
+
+ switch( drawseg->GetShape() )
+ {
+ case S_ARC:
+ export_vrml_arc( aModel, layer,
+ (double) drawseg->GetCenter().x * aModel.scale,
+ (double) drawseg->GetCenter().y * aModel.scale,
+ (double) drawseg->GetArcStart().x * aModel.scale,
+ (double) drawseg->GetArcStart().y * aModel.scale,
+ w, drawseg->GetAngle() / 10 );
+ break;
+
+ case S_CIRCLE:
+ // Break circles into two 180 arcs to prevent the vrml hole from obscuring objects
+ // within the hole area of the circle.
+ export_vrml_arc( aModel, layer, x, y, x, y-r, w, 180.0 );
+ export_vrml_arc( aModel, layer, x, y, x, y+r, w, 180.0 );
+ break;
+
+ default:
+ export_vrml_line( aModel, layer, x, y, xf, yf, w );
+ break;
+ }
+}
+
+
+/* C++ doesn't have closures and neither continuation forms... this is
+ * for coupling the vrml_text_callback with the common parameters */
+static void vrml_text_callback( int x0, int y0, int xf, int yf )
+{
+ LAYER_NUM s_text_layer = model_vrml->s_text_layer;
+ int s_text_width = model_vrml->s_text_width;
+ double scale = model_vrml->scale;
+
+ export_vrml_line( *model_vrml, s_text_layer,
+ x0 * scale, y0 * scale,
+ xf * scale, yf * scale,
+ s_text_width * scale );
+}
+
+
+static void export_vrml_pcbtext( MODEL_VRML& aModel, TEXTE_PCB* text )
+{
+ model_vrml->s_text_layer = text->GetLayer();
+ model_vrml->s_text_width = text->GetThickness();
+
+ wxSize size = text->GetSize();
+
+ if( text->IsMirrored() )
+ size.x = -size.x;
+
+ EDA_COLOR_T color = BLACK; // not actually used, but needed by DrawGraphicText
+
+ if( text->IsMultilineAllowed() )
+ {
+ wxArrayString strings_list;
+ wxStringSplit( text->GetShownText(), strings_list, '\n' );
+ std::vector<wxPoint> positions;
+ positions.reserve( strings_list.Count() );
+ text->GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() );
+
+ for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
+ {
+ wxString& txt = strings_list.Item( ii );
+ DrawGraphicText( NULL, NULL, positions[ii], color,
+ txt, text->GetOrientation(), size,
+ text->GetHorizJustify(), text->GetVertJustify(),
+ text->GetThickness(), text->IsItalic(),
+ true,
+ vrml_text_callback );
+ }
+ }
+ else
+ {
+ DrawGraphicText( NULL, NULL, text->GetTextPosition(), color,
+ text->GetShownText(), text->GetOrientation(), size,
+ text->GetHorizJustify(), text->GetVertJustify(),
+ text->GetThickness(), text->IsItalic(),
+ true,
+ vrml_text_callback );
+ }
+}
+
+
+static void export_vrml_drawings( MODEL_VRML& aModel, BOARD* pcb )
+{
+ // draw graphic items
+ for( BOARD_ITEM* drawing = pcb->m_Drawings; drawing != 0; drawing = drawing->Next() )
+ {
+ LAYER_ID layer = drawing->GetLayer();
+
+ if( layer != F_Cu && layer != B_Cu && layer != B_SilkS && layer != F_SilkS )
+ continue;
+
+ switch( drawing->Type() )
+ {
+ case PCB_LINE_T:
+ export_vrml_drawsegment( aModel, (DRAWSEGMENT*) drawing );
+ break;
+
+ case PCB_TEXT_T:
+ export_vrml_pcbtext( aModel, (TEXTE_PCB*) drawing );
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+// board edges and cutouts
+static void export_vrml_board( MODEL_VRML& aModel, BOARD* pcb )
+{
+ SHAPE_POLY_SET bufferPcbOutlines; // stores the board main outlines
+ SHAPE_POLY_SET allLayerHoles; // Contains through holes, calculated only once
+ // Build a polygon from edge cut items
+ wxString msg;
+
+ if( !pcb->GetBoardPolygonOutlines( bufferPcbOutlines, allLayerHoles, &msg ) )
+ {
+ msg << wxT( "\n\n" ) <<
+ _( "Unable to calculate the board outlines;\n"
+ "fall back to using the board boundary box." );
+ wxMessageBox( msg );
+ }
+
+ double scale = aModel.scale;
+ int seg;
+
+ for( int i = 0; i < bufferPcbOutlines.OutlineCount(); i++ )
+ {
+ const SHAPE_LINE_CHAIN& outline = bufferPcbOutlines.COutline( i );
+
+ seg = aModel.board.NewContour();
+
+ for( int j = 0; j < outline.PointCount(); j++ )
+ {
+ aModel.board.AddVertex( seg, (double)outline.CPoint(j).x * scale,
+ -((double)outline.CPoint(j).y * scale ) );
+
+ }
+
+ aModel.board.EnsureWinding( seg, false );
+ }
+
+ for( int i = 0; i < allLayerHoles.OutlineCount(); i++ )
+ {
+ const SHAPE_LINE_CHAIN& outline = allLayerHoles.COutline( i );
+
+ seg = aModel.holes.NewContour();
+
+ if( seg < 0 )
+ {
+ msg << wxT( "\n\n" ) <<
+ _( "VRML Export Failed:\nCould not add holes to contours." );
+ wxMessageBox( msg );
+
+ return;
+ }
+
+ for( int j = 0; j < outline.PointCount(); j++ )
+ {
+ aModel.holes.AddVertex( seg, (double)outline.CPoint(j).x * scale,
+ -((double)outline.CPoint(j).y * scale ) );
+
+ }
+
+ aModel.holes.EnsureWinding( seg, true );
+ }
+}
+
+
+static void export_round_padstack( MODEL_VRML& aModel, BOARD* pcb,
+ double x, double y, double r,
+ LAYER_NUM bottom_layer, LAYER_NUM top_layer,
+ double hole )
+{
+ LAYER_NUM layer = top_layer;
+ bool thru = true;
+
+ // if not a thru hole do not put a hole in the board
+ if( top_layer != F_Cu || bottom_layer != B_Cu )
+ thru = false;
+
+ if( thru && hole > 0 )
+ aModel.holes.AddCircle( x, -y, hole, true );
+
+ if( aModel.plainPCB )
+ return;
+
+ while( 1 )
+ {
+ if( layer == B_Cu )
+ {
+ aModel.bot_copper.AddCircle( x, -y, r );
+
+ if( hole > 0 && !thru )
+ aModel.bot_copper.AddCircle( x, -y, hole, true );
+
+ }
+ else if( layer == F_Cu )
+ {
+ aModel.top_copper.AddCircle( x, -y, r );
+
+ if( hole > 0 && !thru )
+ aModel.top_copper.AddCircle( x, -y, hole, true );
+
+ }
+
+ if( layer == bottom_layer )
+ break;
+
+ layer = bottom_layer;
+ }
+}
+
+
+static void export_vrml_via( MODEL_VRML& aModel, BOARD* pcb, const VIA* via )
+{
+ double x, y, r, hole;
+ LAYER_ID top_layer, bottom_layer;
+
+ hole = via->GetDrillValue() * aModel.scale / 2.0;
+ r = via->GetWidth() * aModel.scale / 2.0;
+ x = via->GetStart().x * aModel.scale;
+ y = via->GetStart().y * aModel.scale;
+ via->LayerPair( &top_layer, &bottom_layer );
+
+ // do not render a buried via
+ if( top_layer != F_Cu && bottom_layer != B_Cu )
+ return;
+
+ // Export the via padstack
+ export_round_padstack( aModel, pcb, x, y, r, bottom_layer, top_layer, hole );
+}
+
+
+static void export_vrml_tracks( MODEL_VRML& aModel, BOARD* pcb )
+{
+ for( TRACK* track = pcb->m_Track; track; track = track->Next() )
+ {
+ if( track->Type() == PCB_VIA_T )
+ {
+ export_vrml_via( aModel, pcb, (const VIA*) track );
+ }
+ else if( ( track->GetLayer() == B_Cu || track->GetLayer() == F_Cu )
+ && !aModel.plainPCB )
+ export_vrml_line( aModel, track->GetLayer(),
+ track->GetStart().x * aModel.scale,
+ track->GetStart().y * aModel.scale,
+ track->GetEnd().x * aModel.scale,
+ track->GetEnd().y * aModel.scale,
+ track->GetWidth() * aModel.scale );
+ }
+}
+
+
+static void export_vrml_zones( MODEL_VRML& aModel, BOARD* aPcb )
+{
+ double scale = aModel.scale;
+
+ for( int ii = 0; ii < aPcb->GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* zone = aPcb->GetArea( ii );
+
+ VRML_LAYER* vl;
+
+ if( !GetLayer( aModel, zone->GetLayer(), &vl ) )
+ continue;
+
+ if( !zone->IsFilled() )
+ {
+ zone->SetFillMode( 0 ); // use filled polygons
+ zone->BuildFilledSolidAreasPolygons( aPcb );
+ }
+
+ const SHAPE_POLY_SET& poly = zone->GetFilledPolysList();
+
+ for( int i = 0; i < poly.OutlineCount(); i++ )
+ {
+ const SHAPE_LINE_CHAIN& outline = poly.COutline( i );
+
+ int seg = vl->NewContour();
+
+ for( int j = 0; j < outline.PointCount(); j++ )
+ {
+ if( !vl->AddVertex( seg, (double)outline.CPoint( j ).x * scale,
+ -((double)outline.CPoint( j ).y * scale ) ) )
+ throw( std::runtime_error( vl->GetError() ) );
+
+ }
+
+ vl->EnsureWinding( seg, false );
+ }
+ }
+}
+
+
+static void export_vrml_text_module( TEXTE_MODULE* module )
+{
+ if( module->IsVisible() )
+ {
+ wxSize size = module->GetSize();
+
+ if( module->IsMirrored() )
+ size.x = -size.x; // Text is mirrored
+
+ model_vrml->s_text_layer = module->GetLayer();
+ model_vrml->s_text_width = module->GetThickness();
+
+ DrawGraphicText( NULL, NULL, module->GetTextPosition(), BLACK,
+ module->GetShownText(), module->GetDrawRotation(), size,
+ module->GetHorizJustify(), module->GetVertJustify(),
+ module->GetThickness(), module->IsItalic(),
+ true,
+ vrml_text_callback );
+ }
+}
+
+
+static void export_vrml_edge_module( MODEL_VRML& aModel, EDGE_MODULE* aOutline,
+ double aOrientation )
+{
+ LAYER_NUM layer = aOutline->GetLayer();
+ double x = aOutline->GetStart().x * aModel.scale;
+ double y = aOutline->GetStart().y * aModel.scale;
+ double xf = aOutline->GetEnd().x * aModel.scale;
+ double yf = aOutline->GetEnd().y * aModel.scale;
+ double w = aOutline->GetWidth() * aModel.scale;
+
+ switch( aOutline->GetShape() )
+ {
+ case S_SEGMENT:
+ export_vrml_line( aModel, layer, x, y, xf, yf, w );
+ break;
+
+ case S_ARC:
+ export_vrml_arc( aModel, layer, x, y, xf, yf, w, aOutline->GetAngle() / 10 );
+ break;
+
+ case S_CIRCLE:
+ export_vrml_circle( aModel, layer, x, y, xf, yf, w );
+ break;
+
+ case S_POLYGON:
+ {
+ VRML_LAYER* vl;
+
+ if( !GetLayer( aModel, layer, &vl ) )
+ break;
+
+ int nvert = aOutline->GetPolyPoints().size() - 1;
+ int i = 0;
+
+ if( nvert < 3 ) break;
+
+ int seg = vl->NewContour();
+
+ if( seg < 0 )
+ break;
+
+ while( i < nvert )
+ {
+ CPolyPt corner( aOutline->GetPolyPoints()[i] );
+ RotatePoint( &corner.x, &corner.y, aOrientation );
+ corner.x += aOutline->GetPosition().x;
+ corner.y += aOutline->GetPosition().y;
+
+ x = corner.x * aModel.scale;
+ y = - ( corner.y * aModel.scale );
+
+ if( !vl->AddVertex( seg, x, y ) )
+ throw( std::runtime_error( vl->GetError() ) );
+
+ ++i;
+ }
+ vl->EnsureWinding( seg, false );
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+static void export_vrml_padshape( MODEL_VRML& aModel, VRML_LAYER* aTinLayer, D_PAD* aPad )
+{
+ // The (maybe offset) pad position
+ wxPoint pad_pos = aPad->ShapePos();
+ double pad_x = pad_pos.x * aModel.scale;
+ double pad_y = pad_pos.y * aModel.scale;
+ wxSize pad_delta = aPad->GetDelta();
+
+ double pad_dx = pad_delta.x * aModel.scale / 2.0;
+ double pad_dy = pad_delta.y * aModel.scale / 2.0;
+
+ double pad_w = aPad->GetSize().x * aModel.scale / 2.0;
+ double pad_h = aPad->GetSize().y * aModel.scale / 2.0;
+
+ switch( aPad->GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+
+ if( !aTinLayer->AddCircle( pad_x, -pad_y, pad_w, false ) )
+ throw( std::runtime_error( aTinLayer->GetError() ) );
+
+ break;
+
+ case PAD_SHAPE_OVAL:
+
+ if( !aTinLayer->AddSlot( pad_x, -pad_y, pad_w * 2.0, pad_h * 2.0,
+ aPad->GetOrientation()/10.0, false ) )
+ throw( std::runtime_error( aTinLayer->GetError() ) );
+
+ break;
+
+ case PAD_SHAPE_RECT:
+ // Just to be sure :D
+ pad_dx = 0;
+ pad_dy = 0;
+
+ case PAD_SHAPE_TRAPEZOID:
+ {
+ double coord[8] =
+ {
+ -pad_w + pad_dy, -pad_h - pad_dx,
+ -pad_w - pad_dy, pad_h + pad_dx,
+ +pad_w - pad_dy, -pad_h + pad_dx,
+ +pad_w + pad_dy, pad_h - pad_dx
+ };
+
+ for( int i = 0; i < 4; i++ )
+ {
+ RotatePoint( &coord[i * 2], &coord[i * 2 + 1], aPad->GetOrientation() );
+ coord[i * 2] += pad_x;
+ coord[i * 2 + 1] += pad_y;
+ }
+
+ int lines;
+
+ lines = aTinLayer->NewContour();
+
+ if( lines < 0 )
+ throw( std::runtime_error( aTinLayer->GetError() ) );
+
+ if( !aTinLayer->AddVertex( lines, coord[0], -coord[1] ) )
+ throw( std::runtime_error( aTinLayer->GetError() ) );
+
+ if( !aTinLayer->AddVertex( lines, coord[4], -coord[5] ) )
+ throw( std::runtime_error( aTinLayer->GetError() ) );
+
+ if( !aTinLayer->AddVertex( lines, coord[6], -coord[7] ) )
+ throw( std::runtime_error( aTinLayer->GetError() ) );
+
+ if( !aTinLayer->AddVertex( lines, coord[2], -coord[3] ) )
+ throw( std::runtime_error( aTinLayer->GetError() ) );
+
+ if( !aTinLayer->EnsureWinding( lines, false ) )
+ throw( std::runtime_error( aTinLayer->GetError() ) );
+
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+static void export_vrml_pad( MODEL_VRML& aModel, BOARD* pcb, D_PAD* aPad )
+{
+ double hole_drill_w = (double) aPad->GetDrillSize().x * aModel.scale / 2.0;
+ double hole_drill_h = (double) aPad->GetDrillSize().y * aModel.scale / 2.0;
+ double hole_drill = std::min( hole_drill_w, hole_drill_h );
+ double hole_x = aPad->GetPosition().x * aModel.scale;
+ double hole_y = aPad->GetPosition().y * aModel.scale;
+
+ // Export the hole on the edge layer
+ if( hole_drill > 0 )
+ {
+ bool pth = false;
+
+ if( ( aPad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
+ && !aModel.plainPCB )
+ pth = true;
+
+ if( aPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG )
+ {
+ // Oblong hole (slot)
+ aModel.holes.AddSlot( hole_x, -hole_y, hole_drill_w * 2.0, hole_drill_h * 2.0,
+ aPad->GetOrientation()/10.0, true, pth );
+
+ if( pth )
+ aModel.plated_holes.AddSlot( hole_x, -hole_y,
+ hole_drill_w * 2.0, hole_drill_h * 2.0,
+ aPad->GetOrientation()/10.0, true, false );
+ }
+ else
+ {
+ // Drill a round hole
+ aModel.holes.AddCircle( hole_x, -hole_y, hole_drill, true, pth );
+
+ if( pth )
+ aModel.plated_holes.AddCircle( hole_x, -hole_y, hole_drill, true, false );
+
+ }
+ }
+
+ if( aModel.plainPCB )
+ return;
+
+ // The pad proper, on the selected layers
+ LSET layer_mask = aPad->GetLayerSet();
+
+ if( layer_mask[B_Cu] )
+ {
+ export_vrml_padshape( aModel, &aModel.bot_tin, aPad );
+ }
+
+ if( layer_mask[F_Cu] )
+ {
+ export_vrml_padshape( aModel, &aModel.top_tin, aPad );
+ }
+}
+
+
+// From axis/rot to quaternion
+static void build_quat( double x, double y, double z, double a, double q[4] )
+{
+ double sina = sin( a / 2 );
+
+ q[0] = x * sina;
+ q[1] = y * sina;
+ q[2] = z * sina;
+ q[3] = cos( a / 2 );
+}
+
+
+// From quaternion to axis/rot
+static void from_quat( double q[4], double rot[4] )
+{
+ rot[3] = acos( q[3] ) * 2;
+
+ for( int i = 0; i < 3; i++ )
+ {
+ rot[i] = q[i] / sin( rot[3] / 2 );
+ }
+}
+
+
+// Quaternion composition
+static void compose_quat( double q1[4], double q2[4], double qr[4] )
+{
+ double tmp[4];
+
+ tmp[0] = q2[3] * q1[0] + q2[0] * q1[3] + q2[1] * q1[2] - q2[2] * q1[1];
+ tmp[1] = q2[3] * q1[1] + q2[1] * q1[3] + q2[2] * q1[0] - q2[0] * q1[2];
+ tmp[2] = q2[3] * q1[2] + q2[2] * q1[3] + q2[0] * q1[1] - q2[1] * q1[0];
+ tmp[3] = q2[3] * q1[3] - q2[0] * q1[0] - q2[1] * q1[1] - q2[2] * q1[2];
+
+ qr[0] = tmp[0];
+ qr[1] = tmp[1];
+ qr[2] = tmp[2];
+ qr[3] = tmp[3];
+}
+
+
+static void export_vrml_module( MODEL_VRML& aModel, BOARD* aPcb, MODULE* aModule,
+ std::ofstream& aOutputFile, double aVRMLModelsToBiu,
+ bool aExport3DFiles, bool aUseRelativePaths,
+ const wxString& a3D_Subdir )
+{
+ if( !aModel.plainPCB )
+ {
+ // Reference and value
+ if( aModule->Reference().IsVisible() )
+ export_vrml_text_module( &aModule->Reference() );
+
+ if( aModule->Value().IsVisible() )
+ export_vrml_text_module( &aModule->Value() );
+
+ // Export module edges
+ for( EDA_ITEM* item = aModule->GraphicalItems(); item; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ export_vrml_text_module( static_cast<TEXTE_MODULE*>( item ) );
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ export_vrml_edge_module( aModel, static_cast<EDGE_MODULE*>( item ),
+ aModule->GetOrientation() );
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ // Export pads
+ for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
+ export_vrml_pad( aModel, aPcb, pad );
+
+ bool isFlipped = aModule->GetLayer() == B_Cu;
+
+ // Export the object VRML model(s)
+ for( S3D_MASTER* vrmlm = aModule->Models(); vrmlm; vrmlm = vrmlm->Next() )
+ {
+ if( !vrmlm->Is3DType( S3D_MASTER::FILE3D_VRML ) )
+ continue;
+
+ wxFileName modelFileName = vrmlm->GetShape3DFullFilename();
+ wxFileName destFileName( a3D_Subdir, modelFileName.GetName(), modelFileName.GetExt() );
+
+ // Only copy VRML files.
+ if( modelFileName.FileExists() && modelFileName.GetExt() == wxT( "wrl" ) )
+ {
+ if( aExport3DFiles )
+ {
+ wxDateTime srcModTime = modelFileName.GetModificationTime();
+ wxDateTime destModTime = srcModTime;
+
+ destModTime.SetToCurrent();
+
+ if( destFileName.FileExists() )
+ destModTime = destFileName.GetModificationTime();
+
+ // Only copy the file if it doesn't exist or has been modified. This eliminates
+ // the redundant file copies.
+ if( srcModTime != destModTime )
+ {
+ wxLogDebug( wxT( "Copying 3D model %s to %s." ),
+ GetChars( modelFileName.GetFullPath() ),
+ GetChars( destFileName.GetFullPath() ) );
+
+ if( !wxCopyFile( modelFileName.GetFullPath(), destFileName.GetFullPath() ) )
+ continue;
+ }
+ }
+
+ /* Calculate 3D shape rotation:
+ * this is the rotation parameters, with an additional 180 deg rotation
+ * for footprints that are flipped
+ * When flipped, axis rotation is the horizontal axis (X axis)
+ */
+ double rotx = -vrmlm->m_MatRotation.x;
+ double roty = -vrmlm->m_MatRotation.y;
+ double rotz = -vrmlm->m_MatRotation.z;
+
+ if( isFlipped )
+ {
+ rotx += 180.0;
+ roty = -roty;
+ rotz = -rotz;
+ }
+
+ // Do some quaternion munching
+ double q1[4], q2[4], rot[4];
+ build_quat( 1, 0, 0, DEG2RAD( rotx ), q1 );
+ build_quat( 0, 1, 0, DEG2RAD( roty ), q2 );
+ compose_quat( q1, q2, q1 );
+ build_quat( 0, 0, 1, DEG2RAD( rotz ), q2 );
+ compose_quat( q1, q2, q1 );
+
+ // Note here aModule->GetOrientation() is in 0.1 degrees,
+ // so module rotation has to be converted to radians
+ build_quat( 0, 0, 1, DECIDEG2RAD( aModule->GetOrientation() ), q2 );
+ compose_quat( q1, q2, q1 );
+ from_quat( q1, rot );
+
+ aOutputFile << "Transform {\n";
+
+ // A null rotation would fail the acos!
+ if( rot[3] != 0.0 )
+ {
+ aOutputFile << " rotation " << std::setprecision( 3 );
+ aOutputFile << rot[0] << " " << rot[1] << " " << rot[2] << " " << rot[3] << "\n";
+ }
+
+ // adjust 3D shape local offset position
+ // they are given in inch, so they are converted in board IU.
+ double offsetx = vrmlm->m_MatPosition.x * IU_PER_MILS * 1000.0;
+ double offsety = vrmlm->m_MatPosition.y * IU_PER_MILS * 1000.0;
+ double offsetz = vrmlm->m_MatPosition.z * IU_PER_MILS * 1000.0;
+
+ if( isFlipped )
+ offsetz = -offsetz;
+ else // In normal mode, Y axis is reversed in Pcbnew.
+ offsety = -offsety;
+
+ RotatePoint( &offsetx, &offsety, aModule->GetOrientation() );
+
+ aOutputFile << " translation " << std::setprecision( aModel.precision );
+ aOutputFile << ( ( offsetx + aModule->GetPosition().x ) *
+ aModel.scale + aModel.tx ) << " ";
+ aOutputFile << ( -(offsety + aModule->GetPosition().y) *
+ aModel.scale - aModel.ty ) << " ";
+ aOutputFile << ( (offsetz * aModel.scale ) +
+ aModel.GetLayerZ( aModule->GetLayer() ) ) << "\n";
+ aOutputFile << " scale ";
+ aOutputFile << ( vrmlm->m_MatScale.x * aVRMLModelsToBiu ) << " ";
+ aOutputFile << ( vrmlm->m_MatScale.y * aVRMLModelsToBiu ) << " ";
+ aOutputFile << ( vrmlm->m_MatScale.z * aVRMLModelsToBiu ) << "\n";
+ aOutputFile << " children [\n Inline {\n url \"";
+
+ if( aUseRelativePaths )
+ {
+ wxFileName tmp = destFileName;
+ tmp.SetExt( wxT( "" ) );
+ tmp.SetName( wxT( "" ) );
+ tmp.RemoveLastDir();
+ destFileName.MakeRelativeTo( tmp.GetPath() );
+ }
+
+ wxString fn = destFileName.GetFullPath();
+ fn.Replace( wxT( "\\" ), wxT( "/" ) );
+ aOutputFile << TO_UTF8( fn ) << "\"\n } ]\n";
+ aOutputFile << " }\n";
+ }
+ }
+}
+
+
+bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName, double aMMtoWRMLunit,
+ bool aExport3DFiles, bool aUseRelativePaths,
+ bool aUsePlainPCB, const wxString& a3D_Subdir,
+ double aXRef, double aYRef )
+{
+ BOARD* pcb = GetBoard();
+ bool ok = true;
+
+ MODEL_VRML model3d;
+ model3d.plainPCB = aUsePlainPCB;
+
+ model_vrml = &model3d;
+ std::ofstream output_file;
+
+ try
+ {
+ output_file.exceptions( std::ofstream::failbit );
+ output_file.open( TO_UTF8( aFullFileName ), std::ios_base::out );
+
+ // Switch the locale to standard C (needed to print floating point numbers)
+ LOCALE_IO toggle;
+
+ // Begin with the usual VRML boilerplate
+ wxString fn = aFullFileName;
+ fn.Replace( wxT( "\\" ), wxT( "/" ) );
+ output_file << "#VRML V2.0 utf8\n";
+ output_file << "WorldInfo {\n";
+ output_file << " title \"" << TO_UTF8( fn ) << " - Generated by Pcbnew\"\n";
+ output_file << "}\n";
+
+ // Set the VRML world scale factor
+ model3d.SetScale( aMMtoWRMLunit );
+
+ output_file << "Transform {\n";
+
+ // board reference point
+ model3d.SetOffset( -aXRef, aYRef );
+
+ output_file << " children [\n";
+
+ // Preliminary computation: the z value for each layer
+ compute_layer_Zs( model3d, pcb );
+
+ // board edges and cutouts
+ export_vrml_board( model3d, pcb );
+
+ // Drawing and text on the board
+ if( !aUsePlainPCB )
+ export_vrml_drawings( model3d, pcb );
+
+ // Export vias and trackage
+ export_vrml_tracks( model3d, pcb );
+
+ // Export zone fills
+ if( !aUsePlainPCB )
+ export_vrml_zones( model3d, pcb);
+
+ /* scaling factor to convert 3D models to board units (decimils)
+ * Usually we use Wings3D to create thems.
+ * One can consider the 3D units is 0.1 inch (2.54 mm)
+ * So the scaling factor from 0.1 inch to board units
+ * is 2.54 * aMMtoWRMLunit
+ */
+ double wrml_3D_models_scaling_factor = 2.54 * aMMtoWRMLunit;
+
+ // Export footprints
+ for( MODULE* module = pcb->m_Modules; module != 0; module = module->Next() )
+ export_vrml_module( model3d, pcb, module, output_file, wrml_3D_models_scaling_factor,
+ aExport3DFiles, aUseRelativePaths, a3D_Subdir );
+
+ // write out the board and all layers
+ write_layers( model3d, output_file, pcb );
+
+ // Close the outer 'transform' node
+ output_file << "]\n}\n";
+ }
+ catch( const std::exception& e )
+ {
+ wxString msg;
+ msg << _( "IDF Export Failed:\n" ) << FROM_UTF8( e.what() );
+ wxMessageBox( msg );
+
+ ok = false;
+ }
+
+ // End of work
+ output_file.exceptions( std::ios_base::goodbit );
+ output_file.close();
+
+ return ok;
+}
diff --git a/pcbnew/exporters/gen_drill_report_files.cpp b/pcbnew/exporters/gen_drill_report_files.cpp
new file mode 100644
index 0000000..94a6c75
--- /dev/null
+++ b/pcbnew/exporters/gen_drill_report_files.cpp
@@ -0,0 +1,455 @@
+/**
+ * @file gen_drill_report_files.cpp
+ * @brief Functions to create report and map files for EXCELLON drill files.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 Jean_Pierre Charras <jp.charras at wanadoo.fr>
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <plot_common.h>
+#include <base_struct.h>
+#include <drawtxt.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <macros.h>
+
+#include <class_board.h>
+
+#include <pcbnew.h>
+#include <pcbplot.h>
+#include <gendrill_Excellon_writer.h>
+
+/* Conversion utilities - these will be used often in there... */
+inline double diameter_in_inches( double ius )
+{
+ return ius * 0.001 / IU_PER_MILS;
+}
+
+
+inline double diameter_in_mm( double ius )
+{
+ return ius / IU_PER_MM;
+}
+
+
+bool EXCELLON_WRITER::GenDrillMapFile( const wxString& aFullFileName,
+ PlotFormat aFormat )
+{
+ double scale = 1.0;
+ wxPoint offset;
+ PLOTTER* plotter = NULL;
+ PAGE_INFO dummy( PAGE_INFO::A4, false );
+
+ PCB_PLOT_PARAMS plot_opts; // starts plotting with default options
+
+ LOCALE_IO toggle; // use standard C notation for float numbers
+
+ const PAGE_INFO& page_info = m_pageInfo ? *m_pageInfo : dummy;
+
+ // Calculate dimensions and center of PCB
+ EDA_RECT bbbox = m_pcb->ComputeBoundingBox( true );
+
+ // Calculate the scale for the format type, scale 1 in HPGL, drawing on
+ // an A4 sheet in PS, + text description of symbols
+ switch( aFormat )
+ {
+ case PLOT_FORMAT_GERBER:
+ offset = GetOffset();
+ plotter = new GERBER_PLOTTER();
+ plotter->SetViewport( offset, IU_PER_DECIMILS, scale, false );
+ plotter->SetGerberCoordinatesFormat( 5 ); // format x.5 unit = mm
+ break;
+
+ case PLOT_FORMAT_HPGL: // Scale for HPGL format.
+ {
+ HPGL_PLOTTER* hpgl_plotter = new HPGL_PLOTTER;
+ plotter = hpgl_plotter;
+ hpgl_plotter->SetPenNumber( plot_opts.GetHPGLPenNum() );
+ hpgl_plotter->SetPenSpeed( plot_opts.GetHPGLPenSpeed() );
+ hpgl_plotter->SetPenOverlap( 0 );
+ plotter->SetPageSettings( page_info );
+ plotter->SetViewport( offset, IU_PER_DECIMILS, scale, false );
+ }
+ break;
+
+
+ default:
+ wxASSERT( false );
+ // fall through
+ case PLOT_FORMAT_PDF:
+ case PLOT_FORMAT_POST:
+ {
+ PAGE_INFO pageA4( wxT( "A4" ) );
+ wxSize pageSizeIU = pageA4.GetSizeIU();
+
+ // Reserve a margin around the page.
+ int margin = KiROUND( 20 * IU_PER_MM );
+
+ // Calculate a scaling factor to print the board on the sheet
+ double Xscale = double( pageSizeIU.x - ( 2 * margin ) ) / bbbox.GetWidth();
+
+ // We should print the list of drill sizes, so reserve room for it
+ // 60% height for board 40% height for list
+ int ypagesize_for_board = KiROUND( pageSizeIU.y * 0.6 );
+ double Yscale = double( ypagesize_for_board - margin ) / bbbox.GetHeight();
+
+ scale = std::min( Xscale, Yscale );
+
+ // Experience shows the scale should not to large, because texts
+ // create problem (can be to big or too small).
+ // So the scale is clipped at 3.0;
+ scale = std::min( scale, 3.0 );
+
+ offset.x = KiROUND( double( bbbox.Centre().x ) -
+ ( pageSizeIU.x / 2.0 ) / scale );
+ offset.y = KiROUND( double( bbbox.Centre().y ) -
+ ( ypagesize_for_board / 2.0 ) / scale );
+
+ if( aFormat == PLOT_FORMAT_PDF )
+ plotter = new PDF_PLOTTER;
+ else
+ plotter = new PS_PLOTTER;
+
+ plotter->SetPageSettings( pageA4 );
+ plotter->SetViewport( offset, IU_PER_DECIMILS, scale, false );
+ }
+ break;
+
+ case PLOT_FORMAT_DXF:
+ {
+ DXF_PLOTTER* dxf_plotter = new DXF_PLOTTER;
+ plotter = dxf_plotter;
+ plotter->SetPageSettings( page_info );
+ plotter->SetViewport( offset, IU_PER_DECIMILS, scale, false );
+ }
+ break;
+
+ case PLOT_FORMAT_SVG:
+ {
+ SVG_PLOTTER* svg_plotter = new SVG_PLOTTER;
+ plotter = svg_plotter;
+ plotter->SetPageSettings( page_info );
+ plotter->SetViewport( offset, IU_PER_DECIMILS, scale, false );
+ }
+ break;
+ }
+
+ plotter->SetCreator( wxT( "PCBNEW" ) );
+ plotter->SetDefaultLineWidth( 5 * IU_PER_MILS );
+ plotter->SetColorMode( false );
+
+ if( ! plotter->OpenFile( aFullFileName ) )
+ {
+ delete plotter;
+ return false;
+ }
+
+ plotter->StartPlot();
+
+ // Draw items on edge layer (not all, only items useful for drill map
+ BRDITEMS_PLOTTER itemplotter( plotter, m_pcb, plot_opts );
+ itemplotter.SetLayerSet( Edge_Cuts );
+
+ for( EDA_ITEM* PtStruct = m_pcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() )
+ {
+ switch( PtStruct->Type() )
+ {
+ case PCB_LINE_T:
+ itemplotter.PlotDrawSegment( (DRAWSEGMENT*) PtStruct );
+ break;
+
+ case PCB_TEXT_T:
+ itemplotter.PlotTextePcb( (TEXTE_PCB*) PtStruct );
+ break;
+
+ case PCB_DIMENSION_T:
+ case PCB_TARGET_T:
+ case PCB_MARKER_T: // do not draw
+ default:
+ break;
+ }
+ }
+
+ int x, y;
+ int plotX, plotY, TextWidth;
+ int intervalle = 0;
+ char line[1024];
+ wxString msg;
+ int textmarginaftersymbol = KiROUND( 2 * IU_PER_MM );
+
+ // Set Drill Symbols width
+ plotter->SetDefaultLineWidth( 0.2 * IU_PER_MM / scale );
+ plotter->SetCurrentLineWidth( -1 );
+
+ // Plot board outlines and drill map
+ PlotDrillMarks( plotter );
+
+ // Print a list of symbols used.
+ int charSize = 3 * IU_PER_MM; // text size in IUs
+ double charScale = 1.0 / scale; // real scale will be 1/scale,
+ // because the global plot scale is scale
+ TextWidth = KiROUND( (charSize * charScale) / 10.0 ); // Set text width (thickness)
+ intervalle = KiROUND( charSize * charScale ) + TextWidth;
+
+ // Trace information.
+ plotX = KiROUND( bbbox.GetX() + textmarginaftersymbol * charScale );
+ plotY = bbbox.GetBottom() + intervalle;
+
+ // Plot title "Info"
+ wxString Text = wxT( "Drill Map:" );
+ plotter->Text( wxPoint( plotX, plotY ), UNSPECIFIED_COLOR, Text, 0,
+ wxSize( KiROUND( charSize * charScale ),
+ KiROUND( charSize * charScale ) ),
+ GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER,
+ TextWidth, false, false );
+
+ for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ )
+ {
+ DRILL_TOOL& tool = m_toolListBuffer[ii];
+
+ if( tool.m_TotalCount == 0 )
+ continue;
+
+ plotY += intervalle;
+
+ int plot_diam = KiROUND( tool.m_Diameter );
+ x = KiROUND( plotX - textmarginaftersymbol * charScale - plot_diam / 2.0 );
+ y = KiROUND( plotY + charSize * charScale );
+ plotter->Marker( wxPoint( x, y ), plot_diam, ii );
+
+ // List the diameter of each drill in mm and inches.
+ sprintf( line, "%2.2fmm / %2.3f\" ",
+ diameter_in_mm( tool.m_Diameter ),
+ diameter_in_inches( tool.m_Diameter ) );
+
+ msg = FROM_UTF8( line );
+
+ // Now list how many holes and ovals are associated with each drill.
+ if( ( tool.m_TotalCount == 1 )
+ && ( tool.m_OvalCount == 0 ) )
+ sprintf( line, "(1 hole)" );
+ else if( tool.m_TotalCount == 1 ) // && ( toolm_OvalCount == 1 )
+ sprintf( line, "(1 slot)" );
+ else if( tool.m_OvalCount == 0 )
+ sprintf( line, "(%d holes)", tool.m_TotalCount );
+ else if( tool.m_OvalCount == 1 )
+ sprintf( line, "(%d holes + 1 slot)", tool.m_TotalCount - 1 );
+ else // if ( toolm_OvalCount > 1 )
+ sprintf( line, "(%d holes + %d slots)",
+ tool.m_TotalCount - tool.m_OvalCount,
+ tool.m_OvalCount );
+
+ msg += FROM_UTF8( line );
+
+ if( tool.m_Hole_NotPlated )
+ msg += wxT( " (not plated)" );
+
+ plotter->Text( wxPoint( plotX, y ), UNSPECIFIED_COLOR, msg, 0,
+ wxSize( KiROUND( charSize * charScale ),
+ KiROUND( charSize * charScale ) ),
+ GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER,
+ TextWidth, false, false );
+
+ intervalle = KiROUND( ( ( charSize * charScale ) + TextWidth ) * 1.2 );
+
+ if( intervalle < ( plot_diam + ( 1 * IU_PER_MM / scale ) + TextWidth ) )
+ intervalle = plot_diam + ( 1 * IU_PER_MM / scale ) + TextWidth;
+ }
+
+ plotter->EndPlot();
+ delete plotter;
+
+ return true;
+}
+
+
+bool EXCELLON_WRITER::GenDrillReportFile( const wxString& aFullFileName )
+{
+ FILE_OUTPUTFORMATTER out( aFullFileName );
+
+ static const char separator[] =
+ " =============================================================\n";
+
+ wxASSERT( m_pcb );
+
+ unsigned totalHoleCount;
+ wxString brdFilename = m_pcb->GetFileName();
+
+ std::vector<LAYER_PAIR> hole_sets = getUniqueLayerPairs();
+
+ out.Print( 0, "Drill report for %s\n", TO_UTF8( brdFilename ) );
+ out.Print( 0, "Created on %s\n\n", TO_UTF8( DateAndTime() ) );
+
+ // Output the cu layer stackup, so layer name references make sense.
+ out.Print( 0, "Copper Layer Stackup:\n" );
+ out.Print( 0, separator );
+
+ LSET cu = m_pcb->GetEnabledLayers() & LSET::AllCuMask();
+
+ int conventional_layer_num = 1;
+ for( LSEQ seq = cu.Seq(); seq; ++seq, ++conventional_layer_num )
+ {
+ out.Print( 0, " L%-2d: %-25s %s\n",
+ conventional_layer_num,
+ TO_UTF8( m_pcb->GetLayerName( *seq ) ),
+ layerName( *seq ).c_str() // generic layer name
+ );
+ }
+
+ out.Print( 0, "\n\n" );
+
+ /* output hole lists:
+ * 1 - through holes
+ * 2 - for partial holes only: by layer starting and ending pair
+ * 3 - Non Plated through holes
+ */
+
+ bool buildNPTHlist = false;
+
+ // in this loop are plated only:
+ for( unsigned pair_ndx = 0; pair_ndx < hole_sets.size(); ++pair_ndx )
+ {
+ LAYER_PAIR pair = hole_sets[pair_ndx];
+
+ BuildHolesList( pair, buildNPTHlist );
+
+ if( pair == LAYER_PAIR( F_Cu, B_Cu ) )
+ {
+ out.Print( 0, "Drill file '%s' contains\n",
+ TO_UTF8( drillFileName( pair, false ) ) );
+
+ out.Print( 0, " plated through holes:\n" );
+ out.Print( 0, separator );
+ totalHoleCount = printToolSummary( out, false );
+ out.Print( 0, " Total plated holes count %u\n", totalHoleCount );
+ }
+ else // blind/buried
+ {
+ out.Print( 0, "Drill file '%s' contains\n",
+ TO_UTF8( drillFileName( pair, false ) ) );
+
+ out.Print( 0, " holes connecting layer pair: '%s and %s' (%s vias):\n",
+ TO_UTF8( m_pcb->GetLayerName( ToLAYER_ID( pair.first ) ) ),
+ TO_UTF8( m_pcb->GetLayerName( ToLAYER_ID( pair.second ) ) ),
+ pair.first == F_Cu || pair.second == B_Cu ? "blind" : "buried"
+ );
+
+ out.Print( 0, separator );
+ totalHoleCount = printToolSummary( out, false );
+ out.Print( 0, " Total plated holes count %u\n", totalHoleCount );
+ }
+
+ out.Print( 0, "\n\n" );
+ }
+
+ // NPTHoles. Generate the full list (pads+vias) if PTH and NPTH are merged,
+ // or only the NPTH list (which never has vias)
+ if( !m_merge_PTH_NPTH )
+ buildNPTHlist = true;
+
+ BuildHolesList( LAYER_PAIR( F_Cu, B_Cu ), buildNPTHlist );
+
+ // nothing wrong with an empty NPTH file in report.
+ if( m_merge_PTH_NPTH )
+ out.Print( 0, "Not plated through holes are merged with plated holes\n" );
+ else
+ out.Print( 0, "Drill file '%s' contains\n",
+ TO_UTF8( drillFileName( LAYER_PAIR( F_Cu, B_Cu ), true ) ) );
+
+ out.Print( 0, " unplated through holes:\n" );
+ out.Print( 0, separator );
+ totalHoleCount = printToolSummary( out, true );
+ out.Print( 0, " Total unplated holes count %u\n", totalHoleCount );
+
+ return true;
+}
+
+
+bool EXCELLON_WRITER::PlotDrillMarks( PLOTTER* aPlotter )
+{
+ // Plot the drill map:
+ wxPoint pos;
+
+ for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
+ {
+ const HOLE_INFO& hole = m_holeListBuffer[ii];
+ pos = hole.m_Hole_Pos;
+
+ // Always plot the drill symbol (for slots identifies the needed cutter!
+ aPlotter->Marker( pos, hole.m_Hole_Diameter, hole.m_Tool_Reference - 1 );
+
+ if( hole.m_Hole_Shape != 0 )
+ {
+ wxSize oblong_size = hole.m_Hole_Size;
+ aPlotter->FlashPadOval( pos, oblong_size, hole.m_Hole_Orient, SKETCH );
+ }
+ }
+
+ return true;
+}
+
+
+unsigned EXCELLON_WRITER::printToolSummary( OUTPUTFORMATTER& out, bool aSummaryNPTH ) const
+{
+ unsigned totalHoleCount = 0;
+
+ for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ )
+ {
+ const DRILL_TOOL& tool = m_toolListBuffer[ii];
+
+ if( aSummaryNPTH && !tool.m_Hole_NotPlated )
+ continue;
+
+ if( !aSummaryNPTH && tool.m_Hole_NotPlated )
+ continue;
+
+ // List the tool number assigned to each drill,
+ // in mm then in inches.
+ int tool_number = ii+1;
+ out.Print( 0, " T%d %2.2fmm %2.3f\" ", tool_number,
+ diameter_in_mm( tool.m_Diameter ),
+ diameter_in_inches( tool.m_Diameter ) );
+
+ // Now list how many holes and ovals are associated with each drill.
+ if( ( tool.m_TotalCount == 1 ) && ( tool.m_OvalCount == 0 ) )
+ out.Print( 0, "(1 hole)\n" );
+ else if( tool.m_TotalCount == 1 )
+ out.Print( 0, "(1 hole) (with 1 slot)\n" );
+ else if( tool.m_OvalCount == 0 )
+ out.Print( 0, "(%d holes)\n", tool.m_TotalCount );
+ else if( tool.m_OvalCount == 1 )
+ out.Print( 0, "(%d holes) (with 1 slot)\n", tool.m_TotalCount );
+ else // tool.m_OvalCount > 1
+ out.Print( 0, "(%d holes) (with %d slots)\n",
+ tool.m_TotalCount, tool.m_OvalCount );
+
+ totalHoleCount += tool.m_TotalCount;
+ }
+
+ out.Print( 0, "\n" );
+
+ return totalHoleCount;
+}
diff --git a/pcbnew/exporters/gen_modules_placefile.cpp b/pcbnew/exporters/gen_modules_placefile.cpp
new file mode 100644
index 0000000..202ddb1
--- /dev/null
+++ b/pcbnew/exporters/gen_modules_placefile.cpp
@@ -0,0 +1,690 @@
+/**
+ * @file gen_modules_placefile.cpp
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * 1 - create ascii files for automatic placement of smd components
+ * 2 - create a module report (pos and module descr) (ascii file)
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <wxPcbStruct.h>
+#include <pgm_base.h>
+#include <build_version.h>
+#include <macros.h>
+#include <reporter.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <pcbnew.h>
+#include <wildcards_and_files_ext.h>
+#include <kiface_i.h>
+#include <wx_html_report_panel.h>
+
+
+#include <dialog_gen_module_position_file_base.h>
+/*
+ * The format of the kicad place file is:
+ * ### Module positions - created on 04/12/2012 15:24:24 ###
+ * ### Printed by Pcbnew version pcbnew (2012-11-30 BZR 3828)-testing
+ * ## Unit = inches, Angle = deg.
+ * or
+ * ## Unit = mm, Angle = deg.
+ * ## Side : top
+ * or
+ * ## Side : bottom
+ * or
+ * ## Side : all
+ * # Ref Val Package PosX PosY Rot Side
+ * C123 0,1uF/50V SM0603 1.6024 -2.6280 180.0 Front
+ * C124 0,1uF/50V SM0603 1.6063 -2.7579 180.0 Front
+ * C125 0,1uF/50V SM0603 1.6010 -2.8310 180.0 Front
+ * ## End
+ */
+
+#define PLACEFILE_UNITS_KEY wxT( "PlaceFileUnits" )
+#define PLACEFILE_OPT_KEY wxT( "PlaceFileOpts" )
+
+
+#define PCB_BACK_SIDE 0
+#define PCB_FRONT_SIDE 1
+#define PCB_BOTH_SIDES 2
+
+class LIST_MOD // An helper class used to build a list of useful footprints.
+{
+public:
+ MODULE* m_Module; // Link to the actual footprint
+ wxString m_Reference; // Its schematic reference
+ wxString m_Value; // Its schematic value
+ LAYER_NUM m_Layer; // its side (B_Cu, or F_Cu)
+};
+
+
+/**
+ * The dialog to create footprint position files,
+ * and choose options (one or 2 files, units and force all SMD footprints in list)
+ */
+class DIALOG_GEN_MODULE_POSITION : public DIALOG_GEN_MODULE_POSITION_BASE
+{
+public:
+ DIALOG_GEN_MODULE_POSITION( PCB_EDIT_FRAME * aParent ):
+ DIALOG_GEN_MODULE_POSITION_BASE( aParent ),
+ m_parent( aParent ),
+ m_plotOpts( aParent->GetPlotSettings() )
+ {
+ m_reporter = &m_messagesPanel->Reporter();
+ initDialog();
+
+ GetSizer()->SetSizeHints(this);
+ Centre();
+ }
+
+private:
+ PCB_EDIT_FRAME* m_parent;
+ PCB_PLOT_PARAMS m_plotOpts;
+ wxConfigBase* m_config;
+ REPORTER* m_reporter;
+
+ static int m_unitsOpt;
+ static int m_fileOpt;
+
+ void initDialog();
+ void OnOutputDirectoryBrowseClicked( wxCommandEvent& event );
+ void OnOKButton( wxCommandEvent& event );
+
+ bool CreateFiles();
+
+ // accessors to options:
+ wxString GetOutputDirectory()
+ {
+ return m_outputDirectoryName->GetValue();
+ }
+
+ bool UnitsMM()
+ {
+ return m_radioBoxUnits->GetSelection() == 1;
+ }
+
+ bool OneFileOnly()
+ {
+ return m_radioBoxFilesCount->GetSelection() == 1;
+ }
+
+ bool ForceAllSmd()
+ {
+ return m_radioBoxForceSmd->GetSelection() == 1;
+ }
+};
+
+
+// Static members to remember choices
+int DIALOG_GEN_MODULE_POSITION::m_unitsOpt = 0;
+int DIALOG_GEN_MODULE_POSITION::m_fileOpt = 0;
+
+// Use standard board side name. do not translate them,
+// they are keywords in place file
+const wxString frontSideName = wxT( "top" );
+const wxString backSideName = wxT( "bottom" );
+
+void DIALOG_GEN_MODULE_POSITION::initDialog()
+{
+ m_config = Kiface().KifaceSettings();
+ m_config->Read( PLACEFILE_UNITS_KEY, &m_unitsOpt, 1 );
+ m_config->Read( PLACEFILE_OPT_KEY, &m_fileOpt, 0 );
+
+ // Output directory
+ m_outputDirectoryName->SetValue( m_plotOpts.GetOutputDirectory() );
+ m_radioBoxUnits->SetSelection( m_unitsOpt );
+ m_radioBoxFilesCount->SetSelection( m_fileOpt );
+
+ m_sdbSizerButtonsOK->SetDefault();
+}
+
+void DIALOG_GEN_MODULE_POSITION::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
+{
+ // Build the absolute path of current output plot directory
+ // to preselect it when opening the dialog.
+ wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() );
+
+ wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
+
+ if( dirDialog.ShowModal() == wxID_CANCEL )
+ return;
+
+ wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
+
+ wxMessageDialog dialog( this, _( "Use a relative path? "),
+ _( "Plot Output Directory" ),
+ wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
+
+ if( dialog.ShowModal() == wxID_YES )
+ {
+ wxString boardFilePath = ( (wxFileName) m_parent->GetBoard()->GetFileName()).GetPath();
+
+ if( !dirName.MakeRelativeTo( boardFilePath ) )
+ wxMessageBox( _( "Cannot make path relative (target volume different from board file volume)!" ),
+ _( "Plot Output Directory" ), wxOK | wxICON_ERROR );
+ }
+
+ m_outputDirectoryName->SetValue( dirName.GetFullPath() );
+}
+
+void DIALOG_GEN_MODULE_POSITION::OnOKButton( wxCommandEvent& event )
+{
+ m_unitsOpt = m_radioBoxUnits->GetSelection();
+ m_fileOpt = m_radioBoxFilesCount->GetSelection();
+
+ m_config->Write( PLACEFILE_UNITS_KEY, m_unitsOpt );
+ m_config->Write( PLACEFILE_OPT_KEY, m_fileOpt );
+
+ // Set output directory and replace backslashes with forward ones
+ // (Keep unix convention in cfg files)
+ wxString dirStr;
+ dirStr = m_outputDirectoryName->GetValue();
+ dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
+
+ m_plotOpts.SetOutputDirectory( dirStr );
+
+ m_parent->SetPlotSettings( m_plotOpts );
+
+ CreateFiles();
+}
+
+
+bool DIALOG_GEN_MODULE_POSITION::CreateFiles()
+{
+ BOARD * brd = m_parent->GetBoard();
+ wxFileName fn;
+ wxString msg;
+ bool singleFile = OneFileOnly();
+ int fullcount = 0;
+
+ // Count the footprints to place, do not yet create a file
+ int fpcount = m_parent->DoGenFootprintsPositionFile( wxEmptyString, UnitsMM(),
+ ForceAllSmd(), PCB_BOTH_SIDES );
+ if( fpcount == 0)
+ {
+ wxMessageBox( _( "No footprint for automated placement." ) );
+ return false;
+ }
+
+ // Create output directory if it does not exist (also transform it in
+ // absolute form). Bail if it fails
+ wxFileName outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() );
+ wxString boardFilename = m_parent->GetBoard()->GetFileName();
+
+ m_reporter = &m_messagesPanel->Reporter();
+
+ if( !EnsureFileDirectoryExists( &outputDir, boardFilename, m_reporter ) )
+ {
+ msg.Printf( _( "Could not write plot files to folder \"%s\"." ),
+ GetChars( outputDir.GetPath() ) );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ fn = m_parent->GetBoard()->GetFileName();
+ fn.SetPath( outputDir.GetPath() );
+
+ // Create the the Front or Top side placement file,
+ // or the single file
+ int side = PCB_FRONT_SIDE;
+
+ if( singleFile )
+ {
+ side = PCB_BOTH_SIDES;
+ fn.SetName( fn.GetName() + wxT( "-" ) + wxT("all") );
+ }
+ else
+ fn.SetName( fn.GetName() + wxT( "-" ) + frontSideName );
+
+ fn.SetExt( FootprintPlaceFileExtension );
+
+ fpcount = m_parent->DoGenFootprintsPositionFile( fn.GetFullPath(), UnitsMM(),
+ ForceAllSmd(), side );
+ if( fpcount < 0 )
+ {
+ msg.Printf( _( "Unable to create '%s'." ), GetChars( fn.GetFullPath() ) );
+ wxMessageBox( msg );
+ m_reporter->Report( msg, REPORTER::RPT_ERROR );
+ return false;
+ }
+
+ if( singleFile )
+ msg.Printf( _( "Place file: '%s'." ), GetChars( fn.GetFullPath() ) );
+ else
+ msg.Printf( _( "Front side (top side) place file: '%s'." ),
+ GetChars( fn.GetFullPath() ) );
+ m_reporter->Report( msg, REPORTER::RPT_INFO );
+
+ msg.Printf( _( "Component count: %d." ), fpcount );
+ m_reporter->Report( msg, REPORTER::RPT_INFO );
+
+ if( singleFile )
+ {
+ m_reporter->Report( _( "Component Placement File generation OK." ), REPORTER::RPT_ACTION );
+ return true;
+ }
+
+ // Create the Back or Bottom side placement file
+ fullcount = fpcount;
+ side = PCB_BACK_SIDE;
+ fn = brd->GetFileName();
+ fn.SetPath( outputDir.GetPath() );
+ fn.SetName( fn.GetName() + wxT( "-" ) + backSideName );
+ fn.SetExt( wxT( "pos" ) );
+
+ fpcount = m_parent->DoGenFootprintsPositionFile( fn.GetFullPath(), UnitsMM(),
+ ForceAllSmd(), side );
+
+ if( fpcount < 0 )
+ {
+ msg.Printf( _( "Unable to create file '%s'." ), GetChars( fn.GetFullPath() ) );
+ m_reporter->Report( msg, REPORTER::RPT_ERROR );
+ wxMessageBox( msg );
+ return false;
+ }
+
+ // Display results
+ if( !singleFile )
+ {
+ msg.Printf( _( "Back side (bottom side) place file: '%s'." ), GetChars( fn.GetFullPath() ) );
+ m_reporter->Report( msg, REPORTER::RPT_INFO );
+
+ msg.Printf( _( "Component count: %d." ), fpcount );
+
+ m_reporter->Report( msg, REPORTER::RPT_INFO );
+ }
+
+ if( !singleFile )
+ {
+ fullcount += fpcount;
+ msg.Printf( _( "Full component count: %d\n" ), fullcount );
+ m_reporter->Report( msg, REPORTER::RPT_INFO );
+ }
+
+ m_reporter->Report( _( "Component Placement File generation OK." ), REPORTER::RPT_ACTION );
+
+ return true;
+}
+
+// Defined values to write coordinates using inches or mm:
+static const double conv_unit_inch = 0.001 / IU_PER_MILS ; // units = INCHES
+static const char unit_text_inch[] = "## Unit = inches, Angle = deg.\n";
+
+static const double conv_unit_mm = 1.0 / IU_PER_MM; // units = mm
+static const char unit_text_mm[] = "## Unit = mm, Angle = deg.\n";
+
+static wxPoint File_Place_Offset; // Offset coordinates for generated file.
+
+
+// Sort function use by GenereModulesPosition()
+// sort is made by side (layer) top layer first
+// then by reference increasing order
+static bool sortFPlist( const LIST_MOD& ref, const LIST_MOD& tst )
+{
+ if( ref.m_Layer == tst.m_Layer )
+ return StrNumCmp( ref.m_Reference, tst.m_Reference, 16 ) < 0;
+
+ return ref.m_Layer > tst.m_Layer;
+}
+
+
+/**
+ * Helper function HasNonSMDPins
+ * returns true if the given module has any non smd pins, such as through hole
+ * and therefore cannot be placed automatically.
+ */
+static bool HasNonSMDPins( MODULE* aModule )
+{
+ D_PAD* pad;
+
+ for( pad = aModule->Pads(); pad; pad = pad->Next() )
+ {
+ if( pad->GetAttribute() != PAD_ATTRIB_SMD )
+ return true;
+ }
+
+ return false;
+}
+
+void PCB_EDIT_FRAME::GenFootprintsPositionFile( wxCommandEvent& event )
+{
+ DIALOG_GEN_MODULE_POSITION dlg( this );
+ dlg.ShowModal();
+}
+
+/*
+ * Creates a footprint position file
+ * aSide = 0 -> Back (bottom) side)
+ * aSide = 1 -> Front (top) side)
+ * aSide = 2 -> both sides
+ * if aFullFileName is empty, the file is not created, only the
+ * count of footprints to place is returned
+ */
+int PCB_EDIT_FRAME::DoGenFootprintsPositionFile( const wxString& aFullFileName,
+ bool aUnitsMM,
+ bool aForceSmdItems, int aSide )
+{
+ MODULE* footprint;
+
+ // Minimal text lenghts:
+ int lenRefText = 8;
+ int lenValText = 8;
+ int lenPkgText = 16;
+
+ File_Place_Offset = GetAuxOrigin();
+
+ // Calculating the number of useful footprints (CMS attribute, not VIRTUAL)
+ int footprintCount = 0;
+
+ // Select units:
+ double conv_unit = aUnitsMM ? conv_unit_mm : conv_unit_inch;
+ const char *unit_text = aUnitsMM ? unit_text_mm : unit_text_inch;
+
+ // Build and sort the list of footprints alphabetically
+ std::vector<LIST_MOD> list;
+ list.reserve( footprintCount );
+
+ for( footprint = GetBoard()->m_Modules; footprint; footprint = footprint->Next() )
+ {
+ if( aSide != PCB_BOTH_SIDES )
+ {
+ if( footprint->GetLayer() == B_Cu && aSide == PCB_FRONT_SIDE)
+ continue;
+ if( footprint->GetLayer() == F_Cu && aSide == PCB_BACK_SIDE)
+ continue;
+ }
+
+ if( footprint->GetAttributes() & MOD_VIRTUAL )
+ {
+ DBG( printf( "skipping footprint %s because it's virtual\n",
+ TO_UTF8( footprint->GetReference() ) );)
+ continue;
+ }
+
+ if( ( footprint->GetAttributes() & MOD_CMS ) == 0 )
+ {
+ if( aForceSmdItems ) // true to fix a bunch of mis-labeled footprints:
+ {
+ if( !HasNonSMDPins( footprint ) )
+ {
+ // all footprint's pins are SMD, mark the part for pick and place
+ footprint->SetAttributes( footprint->GetAttributes() | MOD_CMS );
+ OnModify();
+ }
+ else
+ {
+ DBG(printf( "skipping %s because its attribute is not CMS and it has non SMD pins\n",
+ TO_UTF8(footprint->GetReference()) ) );
+ continue;
+ }
+ }
+ else
+ continue;
+ }
+
+ footprintCount++;
+
+ LIST_MOD item;
+ item.m_Module = footprint;
+ item.m_Reference = footprint->GetReference();
+ item.m_Value = footprint->GetValue();
+ item.m_Layer = footprint->GetLayer();
+ list.push_back( item );
+
+ lenRefText = std::max( lenRefText, int(item.m_Reference.length()) );
+ lenValText = std::max( lenValText, int(item.m_Value.length()) );
+ lenPkgText = std::max( lenPkgText, int(item.m_Module->GetFPID().GetFootprintName().length()) );
+ }
+
+ if( aFullFileName.IsEmpty() )
+ return footprintCount;
+
+ FILE * file = wxFopen( aFullFileName, wxT( "wt" ) );
+ if( file == NULL )
+ return -1;
+
+ if( list.size() > 1 )
+ sort( list.begin(), list.end(), sortFPlist );
+
+ // Switch the locale to standard C (needed to print floating point numbers)
+ LOCALE_IO toggle;
+
+ // Write file header
+ fprintf( file, "### Module positions - created on %s ###\n", TO_UTF8( DateAndTime() ) );
+
+ wxString Title = Pgm().App().GetAppName() + wxT( " " ) + GetBuildVersion();
+ fprintf( file, "### Printed by Pcbnew version %s\n", TO_UTF8( Title ) );
+
+ fputs( unit_text, file );
+
+ fputs( "## Side : ", file );
+
+ if( aSide == PCB_BACK_SIDE )
+ fputs( TO_UTF8( backSideName ), file );
+ else if( aSide == PCB_FRONT_SIDE )
+ fputs( TO_UTF8( frontSideName ), file );
+ else
+ fputs( "All", file );
+
+ fputs( "\n", file );
+
+ fprintf(file, "%-*s %-*s %-*s %9.9s %9.9s %8.8s %s\n",
+ int(lenRefText), "# Ref",
+ int(lenValText), "Val",
+ int(lenPkgText), "Package",
+ "PosX", "PosY", "Rot", "Side" );
+
+ for( int ii = 0; ii < footprintCount; ii++ )
+ {
+ wxPoint footprint_pos;
+ footprint_pos = list[ii].m_Module->GetPosition();
+ footprint_pos -= File_Place_Offset;
+
+ LAYER_NUM layer = list[ii].m_Module->GetLayer();
+ wxASSERT( layer==F_Cu || layer==B_Cu );
+
+ const wxString& ref = list[ii].m_Reference;
+ const wxString& val = list[ii].m_Value;
+ const wxString& pkg = list[ii].m_Module->GetFPID().GetFootprintName();
+
+ fprintf(file, "%-*s %-*s %-*s %9.4f %9.4f %8.4f %s\n",
+ lenRefText, TO_UTF8( ref ),
+ lenValText, TO_UTF8( val ),
+ lenPkgText, TO_UTF8( pkg ),
+ footprint_pos.x * conv_unit,
+ // Keep the coordinates in the first quadrant,
+ // (i.e. change y sign
+ -footprint_pos.y * conv_unit,
+ list[ii].m_Module->GetOrientation() / 10.0,
+ (layer == F_Cu ) ? TO_UTF8( frontSideName ) : TO_UTF8( backSideName ));
+ }
+
+ // Write EOF
+ fputs( "## End\n", file );
+
+ fclose( file );
+ return footprintCount;
+}
+
+
+void PCB_EDIT_FRAME::GenFootprintsReport( wxCommandEvent& event )
+{
+ wxFileName fn;
+
+ wxString boardFilePath = ( (wxFileName) GetBoard()->GetFileName()).GetPath();
+ wxDirDialog dirDialog( this, _( "Select Output Directory" ), boardFilePath );
+
+ if( dirDialog.ShowModal() == wxID_CANCEL )
+ return;
+
+ fn = GetBoard()->GetFileName();
+ fn.SetPath( dirDialog.GetPath() );
+ fn.SetExt( wxT( "rpt" ) );
+
+ bool unitMM = g_UserUnit != INCHES;
+ bool success = DoGenFootprintsReport( fn.GetFullPath(), unitMM );
+
+ wxString msg;
+ if( success )
+ {
+ msg.Printf( _( "Footprint report file created:\n'%s'" ),
+ GetChars( fn.GetFullPath() ) );
+ wxMessageBox( msg, _( "Footprint Report" ), wxICON_INFORMATION );
+ }
+
+ else
+ {
+ msg.Printf( _( "Unable to create '%s'" ), GetChars( fn.GetFullPath() ) );
+ DisplayError( this, msg );
+ }
+}
+
+/* Print a module report.
+ */
+bool PCB_EDIT_FRAME::DoGenFootprintsReport( const wxString& aFullFilename, bool aUnitsMM )
+{
+ wxString msg;
+ FILE* rptfile;
+ wxPoint module_pos;
+
+ File_Place_Offset = wxPoint( 0, 0 );
+
+ rptfile = wxFopen( aFullFilename, wxT( "wt" ) );
+
+ if( rptfile == NULL )
+ return false;
+
+ // Select units:
+ double conv_unit = aUnitsMM ? conv_unit_mm : conv_unit_inch;
+ const char *unit_text = aUnitsMM ? unit_text_mm : unit_text_inch;
+
+ LOCALE_IO toggle;
+
+ // Generate header file comments.)
+ fprintf( rptfile, "## Footprint report - date %s\n", TO_UTF8( DateAndTime() ) );
+
+ wxString Title = Pgm().App().GetAppName() + wxT( " " ) + GetBuildVersion();
+ fprintf( rptfile, "## Created by Pcbnew version %s\n", TO_UTF8( Title ) );
+ fputs( unit_text, rptfile );
+
+ fputs( "\n$BeginDESCRIPTION\n", rptfile );
+
+ EDA_RECT bbbox = GetBoard()->ComputeBoundingBox();
+
+ fputs( "\n$BOARD\n", rptfile );
+
+ fprintf( rptfile, "upper_left_corner %9.6f %9.6f\n",
+ bbbox.GetX() * conv_unit,
+ bbbox.GetY() * conv_unit );
+
+ fprintf( rptfile, "lower_right_corner %9.6f %9.6f\n",
+ bbbox.GetRight() * conv_unit,
+ bbbox.GetBottom() * conv_unit );
+
+ fputs( "$EndBOARD\n\n", rptfile );
+
+ for( MODULE* Module = GetBoard()->m_Modules; Module; Module = Module->Next() )
+ {
+ fprintf( rptfile, "$MODULE %s\n", EscapedUTF8( Module->GetReference() ).c_str() );
+
+ fprintf( rptfile, "reference %s\n", EscapedUTF8( Module->GetReference() ).c_str() );
+ fprintf( rptfile, "value %s\n", EscapedUTF8( Module->GetValue() ).c_str() );
+ fprintf( rptfile, "footprint %s\n",
+ EscapedUTF8( FROM_UTF8( Module->GetFPID().Format().c_str() ) ).c_str() );
+
+ msg = wxT( "attribut" );
+
+ if( Module->GetAttributes() & MOD_VIRTUAL )
+ msg += wxT( " virtual" );
+
+ if( Module->GetAttributes() & MOD_CMS )
+ msg += wxT( " smd" );
+
+ if( ( Module->GetAttributes() & (MOD_VIRTUAL | MOD_CMS) ) == 0 )
+ msg += wxT( " none" );
+
+ msg += wxT( "\n" );
+ fputs( TO_UTF8( msg ), rptfile );
+
+ module_pos = Module->GetPosition();
+ module_pos.x -= File_Place_Offset.x;
+ module_pos.y -= File_Place_Offset.y;
+
+ fprintf( rptfile, "position %9.6f %9.6f orientation %.2f\n",
+ module_pos.x * conv_unit,
+ module_pos.y * conv_unit,
+ Module->GetOrientation() / 10.0 );
+
+ if( Module->GetLayer() == F_Cu )
+ fputs( "layer front\n", rptfile );
+ else if( Module->GetLayer() == B_Cu )
+ fputs( "layer back\n", rptfile );
+ else
+ fputs( "layer other\n", rptfile );
+
+ for( D_PAD* pad = Module->Pads(); pad != NULL; pad = pad->Next() )
+ {
+ fprintf( rptfile, "$PAD \"%s\"\n", TO_UTF8( pad->GetPadName() ) );
+ int layer = 0;
+
+ if( pad->GetLayerSet()[B_Cu] )
+ layer = 1;
+
+ if( pad->GetLayerSet()[F_Cu] )
+ layer |= 2;
+
+ static const char* layer_name[4] = { "nocopper", "back", "front", "both" };
+ fprintf( rptfile, "Shape %s Layer %s\n", TO_UTF8( pad->ShowPadShape() ), layer_name[layer] );
+
+ fprintf( rptfile, "position %9.6f %9.6f size %9.6f %9.6f orientation %.2f\n",
+ pad->GetPos0().x * conv_unit, pad->GetPos0().y * conv_unit,
+ pad->GetSize().x * conv_unit, pad->GetSize().y * conv_unit,
+ (pad->GetOrientation() - Module->GetOrientation()) / 10.0 );
+
+ fprintf( rptfile, "drill %9.6f\n", pad->GetDrillSize().x * conv_unit );
+
+ fprintf( rptfile, "shape_offset %9.6f %9.6f\n",
+ pad->GetOffset().x * conv_unit,
+ pad->GetOffset().y * conv_unit );
+
+ fprintf( rptfile, "$EndPAD\n" );
+ }
+
+ fprintf( rptfile, "$EndMODULE %s\n\n", TO_UTF8 (Module->GetReference() ) );
+ }
+
+ // Generate EOF.
+ fputs( "$EndDESCRIPTION\n", rptfile );
+ fclose( rptfile );
+
+ return true;
+}
+
diff --git a/pcbnew/exporters/gendrill_Excellon_writer.cpp b/pcbnew/exporters/gendrill_Excellon_writer.cpp
new file mode 100644
index 0000000..2a607f7
--- /dev/null
+++ b/pcbnew/exporters/gendrill_Excellon_writer.cpp
@@ -0,0 +1,780 @@
+/**
+ * @file gendrill_Excellon_writer.cpp
+ * @brief Functions to create EXCELLON drill files and report files.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 Jean_Pierre Charras <jp.charras at wanadoo.fr>
+ * Copyright (C) 1992-2016 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @see for EXCELLON format, see:
+ * http://www.excellon.com/manuals/program.htm
+ * and the CNC-7 manual.
+ */
+
+#include <fctsys.h>
+
+#include <vector>
+
+#include <plot_common.h>
+#include <trigo.h>
+#include <macros.h>
+#include <kicad_string.h>
+#include <wxPcbStruct.h>
+#include <pgm_base.h>
+#include <build_version.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+
+#include <pcbplot.h>
+#include <pcbnew.h>
+#include <gendrill_Excellon_writer.h>
+#include <wildcards_and_files_ext.h>
+#include <reporter.h>
+#include <collectors.h>
+
+// Comment/uncomment this to write or not a comment
+// in drill file when PTH and NPTH are merged to flag
+// tools used for PTH and tools used for NPTH
+// #define WRITE_PTH_NPTH_COMMENT
+
+
+EXCELLON_WRITER::EXCELLON_WRITER( BOARD* aPcb )
+{
+ m_file = NULL;
+ m_pcb = aPcb;
+ m_zeroFormat = DECIMAL_FORMAT;
+ m_conversionUnits = 0.0001;
+ m_unitsDecimal = true;
+ m_mirror = false;
+ m_merge_PTH_NPTH = false;
+ m_minimalHeader = false;
+ m_ShortHeader = false;
+ m_mapFileFmt = PLOT_FORMAT_PDF;
+ m_pageInfo = NULL;
+}
+
+
+void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory,
+ bool aGenDrill, bool aGenMap,
+ REPORTER * aReporter )
+{
+ wxFileName fn;
+ wxString msg;
+
+ std::vector<LAYER_PAIR> hole_sets = getUniqueLayerPairs();
+
+ // append a pair representing the NPTH set of holes, for separate drill files.
+ if( !m_merge_PTH_NPTH )
+ hole_sets.push_back( LAYER_PAIR( F_Cu, B_Cu ) );
+
+ for( std::vector<LAYER_PAIR>::const_iterator it = hole_sets.begin();
+ it != hole_sets.end(); ++it )
+ {
+ LAYER_PAIR pair = *it;
+ // For separate drill files, the last layer pair is the NPTH dril file.
+ bool doing_npth = m_merge_PTH_NPTH ? false : ( it == hole_sets.end() - 1 );
+
+ BuildHolesList( pair, doing_npth );
+
+ if( GetHolesCount() > 0 ) // has holes?
+ {
+ fn = drillFileName( pair, doing_npth );
+ fn.SetPath( aPlotDirectory );
+
+ if( aGenDrill )
+ {
+ wxString fullFilename = fn.GetFullPath();
+
+ FILE* file = wxFopen( fullFilename, wxT( "w" ) );
+
+ if( file == NULL )
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "** Unable to create %s **\n" ),
+ GetChars( fullFilename ) );
+ aReporter->Report( msg );
+ }
+ break;
+ }
+ else
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "Create file %s\n" ), GetChars( fullFilename ) );
+ aReporter->Report( msg );
+ }
+ }
+
+ CreateDrillFile( file );
+ }
+
+ if( aGenMap )
+ {
+ fn.SetExt( wxEmptyString ); // Will be added by GenDrillMap
+ wxString fullfilename = fn.GetFullPath() + wxT( "-drl_map" );
+ fullfilename << wxT(".") << GetDefaultPlotExtension( m_mapFileFmt );
+
+ bool success = GenDrillMapFile( fullfilename, m_mapFileFmt );
+
+ if( ! success )
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullfilename ) );
+ aReporter->Report( msg );
+ }
+
+ return;
+ }
+ else
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "Create file %s\n" ), GetChars( fullfilename ) );
+ aReporter->Report( msg );
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+/*
+ * Creates the drill files in EXCELLON format
+ * Number format:
+ * - Floating point format
+ * - integer format
+ * - integer format: "Trailing Zero" ( TZ ) or "Leading Zero"
+ * Units
+ * - Decimal
+ * - Metric
+ */
+int EXCELLON_WRITER::CreateDrillFile( FILE* aFile )
+{
+ m_file = aFile;
+
+ int diam, holes_count;
+ int x0, y0, xf, yf, xc, yc;
+ double xt, yt;
+ char line[1024];
+
+ LOCALE_IO dummy; // Use the standard notation for double numbers
+
+ WriteEXCELLONHeader();
+
+ holes_count = 0;
+
+#ifdef WRITE_PTH_NPTH_COMMENT
+ // if PTH_ and NPTH are merged write a comment in drill file at the
+ // beginning of NPTH section
+ bool writePTHcomment = m_merge_PTH_NPTH;
+ bool writeNPTHcomment = m_merge_PTH_NPTH;
+#endif
+
+ /* Write the tool list */
+ for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ )
+ {
+ DRILL_TOOL& tool_descr = m_toolListBuffer[ii];
+
+#ifdef WRITE_PTH_NPTH_COMMENT
+ if( writePTHcomment && !tool_descr.m_Hole_NotPlated )
+ {
+ writePTHcomment = false;
+ fprintf( m_file, ";TYPE=PLATED\n" );
+ }
+
+ if( writeNPTHcomment && tool_descr.m_Hole_NotPlated )
+ {
+ writeNPTHcomment = false;
+ fprintf( m_file, ";TYPE=NON_PLATED\n" );
+ }
+#endif
+
+ fprintf( m_file, "T%dC%.3f\n", ii + 1,
+ tool_descr.m_Diameter * m_conversionUnits );
+ }
+
+ fputs( "%\n", m_file ); // End of header info
+
+ fputs( "G90\n", m_file ); // Absolute mode
+ fputs( "G05\n", m_file ); // Drill mode
+
+ // Units :
+ if( !m_minimalHeader )
+ {
+ if( m_unitsDecimal )
+ fputs( "M71\n", m_file ); /* M71 = metric mode */
+ else
+ fputs( "M72\n", m_file ); /* M72 = inch mode */
+ }
+
+ /* Read the hole file and generate lines for normal holes (oblong
+ * holes will be created later) */
+ int tool_reference = -2;
+
+ for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
+ {
+ HOLE_INFO& hole_descr = m_holeListBuffer[ii];
+
+ if( hole_descr.m_Hole_Shape )
+ continue; // oblong holes will be created later
+
+ if( tool_reference != hole_descr.m_Tool_Reference )
+ {
+ tool_reference = hole_descr.m_Tool_Reference;
+ fprintf( m_file, "T%d\n", tool_reference );
+ }
+
+ x0 = hole_descr.m_Hole_Pos.x - m_offset.x;
+ y0 = hole_descr.m_Hole_Pos.y - m_offset.y;
+
+ if( !m_mirror )
+ y0 *= -1;
+
+ xt = x0 * m_conversionUnits;
+ yt = y0 * m_conversionUnits;
+ WriteCoordinates( line, xt, yt );
+
+ fputs( line, m_file );
+ holes_count++;
+ }
+
+ /* Read the hole file and generate lines for normal holes (oblong holes
+ * will be created later) */
+ tool_reference = -2; // set to a value not used for
+ // m_holeListBuffer[ii].m_Tool_Reference
+ for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
+ {
+ HOLE_INFO& hole_descr = m_holeListBuffer[ii];
+
+ if( hole_descr.m_Hole_Shape == 0 )
+ continue; // wait for oblong holes
+
+ if( tool_reference != hole_descr.m_Tool_Reference )
+ {
+ tool_reference = hole_descr.m_Tool_Reference;
+ fprintf( m_file, "T%d\n", tool_reference );
+ }
+
+ diam = std::min( hole_descr.m_Hole_Size.x, hole_descr.m_Hole_Size.y );
+
+ if( diam == 0 )
+ continue;
+
+ /* Compute the hole coordinates: */
+ xc = x0 = xf = hole_descr.m_Hole_Pos.x - m_offset.x;
+ yc = y0 = yf = hole_descr.m_Hole_Pos.y - m_offset.y;
+
+ /* Compute the start and end coordinates for the shape */
+ if( hole_descr.m_Hole_Size.x < hole_descr.m_Hole_Size.y )
+ {
+ int delta = ( hole_descr.m_Hole_Size.y - hole_descr.m_Hole_Size.x ) / 2;
+ y0 -= delta;
+ yf += delta;
+ }
+ else
+ {
+ int delta = ( hole_descr.m_Hole_Size.x - hole_descr.m_Hole_Size.y ) / 2;
+ x0 -= delta;
+ xf += delta;
+ }
+
+ RotatePoint( &x0, &y0, xc, yc, hole_descr.m_Hole_Orient );
+ RotatePoint( &xf, &yf, xc, yc, hole_descr.m_Hole_Orient );
+
+ if( !m_mirror )
+ {
+ y0 *= -1;
+ yf *= -1;
+ }
+
+ xt = x0 * m_conversionUnits;
+ yt = y0 * m_conversionUnits;
+ WriteCoordinates( line, xt, yt );
+
+ /* remove the '\n' from end of line, because we must add the "G85"
+ * command to the line: */
+ for( int kk = 0; line[kk] != 0; kk++ )
+ {
+ if( line[kk] == '\n' || line[kk] =='\r' )
+ line[kk] = 0;
+ }
+
+ fputs( line, m_file );
+ fputs( "G85", m_file ); // add the "G85" command
+
+ xt = xf * m_conversionUnits;
+ yt = yf * m_conversionUnits;
+ WriteCoordinates( line, xt, yt );
+
+ fputs( line, m_file );
+ fputs( "G05\n", m_file );
+ holes_count++;
+ }
+
+ WriteEXCELLONEndOfFile();
+
+ return holes_count;
+}
+
+
+void EXCELLON_WRITER::SetFormat( bool aMetric,
+ ZEROS_FMT aZerosFmt,
+ int aLeftDigits,
+ int aRightDigits )
+{
+ m_unitsDecimal = aMetric;
+ m_zeroFormat = aZerosFmt;
+
+ /* Set conversion scale depending on drill file units */
+ if( m_unitsDecimal )
+ m_conversionUnits = 1.0 / IU_PER_MM; // EXCELLON units = mm
+ else
+ m_conversionUnits = 0.001 / IU_PER_MILS; // EXCELLON units = INCHES
+
+ // Set the zero counts. if aZerosFmt == DECIMAL_FORMAT, these values
+ // will be set, but not used.
+ if( aLeftDigits <= 0 )
+ aLeftDigits = m_unitsDecimal ? 3 : 2;
+
+ if( aRightDigits <= 0 )
+ aRightDigits = m_unitsDecimal ? 3 : 4;
+
+ m_precision.m_lhs = aLeftDigits;
+ m_precision.m_rhs = aRightDigits;
+}
+
+
+void EXCELLON_WRITER::WriteCoordinates( char* aLine, double aCoordX, double aCoordY )
+{
+ wxString xs, ys;
+ int xpad = m_precision.m_lhs + m_precision.m_rhs;
+ int ypad = xpad;
+
+ switch( m_zeroFormat )
+ {
+ default:
+ case DECIMAL_FORMAT:
+ /* In Excellon files, resolution is 1/1000 mm or 1/10000 inch (0.1 mil)
+ * Although in decimal format, Excellon specifications do not specify
+ * clearly the resolution. However it seems to be 1/1000mm or 0.1 mil
+ * like in non decimal formats, so we trunk coordinates to 3 or 4 digits in mantissa
+ * Decimal format just prohibit useless leading 0:
+ * 0.45 or .45 is right, but 00.54 is incorrect.
+ */
+ if( m_unitsDecimal )
+ {
+ // resolution is 1/1000 mm
+ xs.Printf( wxT( "%.3f" ), aCoordX );
+ ys.Printf( wxT( "%.3f" ), aCoordY );
+ }
+ else
+ {
+ // resolution is 1/10000 inch
+ xs.Printf( wxT( "%.4f" ), aCoordX );
+ ys.Printf( wxT( "%.4f" ), aCoordY );
+ }
+
+ //Remove useless trailing 0
+ while( xs.Last() == '0' )
+ xs.RemoveLast();
+
+ while( ys.Last() == '0' )
+ ys.RemoveLast();
+
+ sprintf( aLine, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
+ break;
+
+ case SUPPRESS_LEADING:
+ for( int i = 0; i< m_precision.m_rhs; i++ )
+ {
+ aCoordX *= 10; aCoordY *= 10;
+ }
+
+ sprintf( aLine, "X%dY%d\n", KiROUND( aCoordX ), KiROUND( aCoordY ) );
+ break;
+
+ case SUPPRESS_TRAILING:
+ {
+ for( int i = 0; i < m_precision.m_rhs; i++ )
+ {
+ aCoordX *= 10;
+ aCoordY *= 10;
+ }
+
+ if( aCoordX < 0 )
+ xpad++;
+
+ if( aCoordY < 0 )
+ ypad++;
+
+ xs.Printf( wxT( "%0*d" ), xpad, KiROUND( aCoordX ) );
+ ys.Printf( wxT( "%0*d" ), ypad, KiROUND( aCoordY ) );
+
+ size_t j = xs.Len() - 1;
+
+ while( xs[j] == '0' && j )
+ xs.Truncate( j-- );
+
+ j = ys.Len() - 1;
+
+ while( ys[j] == '0' && j )
+ ys.Truncate( j-- );
+
+ sprintf( aLine, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
+ break;
+ }
+
+ case KEEP_ZEROS:
+ for( int i = 0; i< m_precision.m_rhs; i++ )
+ {
+ aCoordX *= 10; aCoordY *= 10;
+ }
+
+ if( aCoordX < 0 )
+ xpad++;
+
+ if( aCoordY < 0 )
+ ypad++;
+
+ xs.Printf( wxT( "%0*d" ), xpad, KiROUND( aCoordX ) );
+ ys.Printf( wxT( "%0*d" ), ypad, KiROUND( aCoordY ) );
+ sprintf( aLine, "X%sY%s\n", TO_UTF8( xs ), TO_UTF8( ys ) );
+ break;
+ }
+}
+
+
+void EXCELLON_WRITER::WriteEXCELLONHeader()
+{
+ fputs( "M48\n", m_file ); // The beginning of a header
+
+ if( !m_minimalHeader )
+ {
+ // The next 2 lines in EXCELLON files are comments:
+ wxString msg;
+ msg << wxT("KiCad") << wxT( " " ) << GetBuildVersion();
+
+ fprintf( m_file, ";DRILL file {%s} date %s\n", TO_UTF8( msg ),
+ TO_UTF8( DateAndTime() ) );
+ msg = wxT( ";FORMAT={" );
+
+ // Print precision:
+ if( m_zeroFormat != DECIMAL_FORMAT )
+ msg << m_precision.GetPrecisionString();
+ else
+ msg << wxT( "-:-" ); // in decimal format the precision is irrelevant
+
+ msg << wxT( "/ absolute / " );
+ msg << ( m_unitsDecimal ? wxT( "metric" ) : wxT( "inch" ) );
+
+ /* Adding numbers notation format.
+ * this is same as m_Choice_Zeros_Format strings, but NOT translated
+ * because some EXCELLON parsers do not like non ASCII values
+ * so we use ONLY English (ASCII) strings.
+ * if new options are added in m_Choice_Zeros_Format, they must also
+ * be added here
+ */
+ msg << wxT( " / " );
+
+ const wxString zero_fmt[4] =
+ {
+ wxT( "decimal" ),
+ wxT( "suppress leading zeros" ),
+ wxT( "suppress trailing zeros" ),
+ wxT( "keep zeros" )
+ };
+
+ msg << zero_fmt[m_zeroFormat];
+ msg << wxT( "}\n" );
+ fputs( TO_UTF8( msg ), m_file );
+ fputs( "FMAT,2\n", m_file ); // Use Format 2 commands (version used since 1979)
+ }
+
+ fputs( m_unitsDecimal ? "METRIC" : "INCH", m_file );
+
+ switch( m_zeroFormat )
+ {
+ case SUPPRESS_LEADING:
+ case DECIMAL_FORMAT:
+ fputs( ",TZ\n", m_file );
+ break;
+
+ case SUPPRESS_TRAILING:
+ fputs( ",LZ\n", m_file );
+ break;
+
+ case KEEP_ZEROS:
+ fputs( ",TZ\n", m_file ); // TZ is acceptable when all zeros are kept
+ break;
+ }
+}
+
+
+void EXCELLON_WRITER::WriteEXCELLONEndOfFile()
+{
+ //add if minimal here
+ fputs( "T0\nM30\n", m_file );
+ fclose( m_file );
+}
+
+
+
+/* Helper function for sorting hole list.
+ * Compare function used for sorting holes type type (plated then not plated)
+ * then by increasing diameter value and X value
+ */
+static bool CmpHoleSettings( const HOLE_INFO& a, const HOLE_INFO& b )
+{
+ if( a.m_Hole_NotPlated != b.m_Hole_NotPlated )
+ return b.m_Hole_NotPlated;
+
+ if( a.m_Hole_Diameter != b.m_Hole_Diameter )
+ return a.m_Hole_Diameter < b.m_Hole_Diameter;
+
+ if( a.m_Hole_Pos.x != b.m_Hole_Pos.x )
+ return a.m_Hole_Pos.x < b.m_Hole_Pos.x;
+
+ return a.m_Hole_Pos.y < b.m_Hole_Pos.y;
+}
+
+
+void EXCELLON_WRITER::BuildHolesList( LAYER_PAIR aLayerPair,
+ bool aGenerateNPTH_list )
+{
+ HOLE_INFO new_hole;
+
+ m_holeListBuffer.clear();
+ m_toolListBuffer.clear();
+
+ wxASSERT( aLayerPair.first < aLayerPair.second ); // fix the caller
+
+ // build hole list for vias
+ if( ! aGenerateNPTH_list ) // vias are always plated !
+ {
+ for( VIA* via = GetFirstVia( m_pcb->m_Track ); via; via = GetFirstVia( via->Next() ) )
+ {
+ int hole_sz = via->GetDrillValue();
+
+ if( hole_sz == 0 ) // Should not occur.
+ continue;
+
+ new_hole.m_Tool_Reference = -1; // Flag value for Not initialized
+ new_hole.m_Hole_Orient = 0;
+ new_hole.m_Hole_Diameter = hole_sz;
+ new_hole.m_Hole_NotPlated = false;
+ new_hole.m_Hole_Size.x = new_hole.m_Hole_Size.y = new_hole.m_Hole_Diameter;
+
+ new_hole.m_Hole_Shape = 0; // hole shape: round
+ new_hole.m_Hole_Pos = via->GetStart();
+
+ via->LayerPair( &new_hole.m_Hole_Top_Layer, &new_hole.m_Hole_Bottom_Layer );
+
+ // LayerPair() returns params with m_Hole_Bottom_Layer > m_Hole_Top_Layer
+ // Remember: top layer = 0 and bottom layer = 31 for through hole vias
+ // Any captured via should be from aLayerPair.first to aLayerPair.second exactly.
+ if( new_hole.m_Hole_Top_Layer != aLayerPair.first ||
+ new_hole.m_Hole_Bottom_Layer != aLayerPair.second )
+ continue;
+
+ m_holeListBuffer.push_back( new_hole );
+ }
+ }
+
+ if( aLayerPair == LAYER_PAIR( F_Cu, B_Cu ) )
+ {
+ // add holes for thru hole pads
+ for( MODULE* module = m_pcb->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ if( !m_merge_PTH_NPTH )
+ {
+ if( !aGenerateNPTH_list && pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
+ continue;
+
+ if( aGenerateNPTH_list && pad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
+ continue;
+ }
+
+ if( pad->GetDrillSize().x == 0 )
+ continue;
+
+ new_hole.m_Hole_NotPlated = (pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED);
+ new_hole.m_Tool_Reference = -1; // Flag is: Not initialized
+ new_hole.m_Hole_Orient = pad->GetOrientation();
+ new_hole.m_Hole_Shape = 0; // hole shape: round
+ new_hole.m_Hole_Diameter = std::min( pad->GetDrillSize().x, pad->GetDrillSize().y );
+ new_hole.m_Hole_Size.x = new_hole.m_Hole_Size.y = new_hole.m_Hole_Diameter;
+
+ if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
+ new_hole.m_Hole_Shape = 1; // oval flag set
+
+ new_hole.m_Hole_Size = pad->GetDrillSize();
+ new_hole.m_Hole_Pos = pad->GetPosition(); // hole position
+ new_hole.m_Hole_Bottom_Layer = B_Cu;
+ new_hole.m_Hole_Top_Layer = F_Cu; // pad holes are through holes
+ m_holeListBuffer.push_back( new_hole );
+ }
+ }
+ }
+
+ // Sort holes per increasing diameter value
+ sort( m_holeListBuffer.begin(), m_holeListBuffer.end(), CmpHoleSettings );
+
+ // build the tool list
+ int last_hole = -1; // Set to not initialized (this is a value not used
+ // for m_holeListBuffer[ii].m_Hole_Diameter)
+ bool last_notplated_opt = false;
+
+ DRILL_TOOL new_tool( 0, false );
+ unsigned jj;
+
+ for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
+ {
+ if( m_holeListBuffer[ii].m_Hole_Diameter != last_hole ||
+ m_holeListBuffer[ii].m_Hole_NotPlated != last_notplated_opt )
+ {
+ new_tool.m_Diameter = m_holeListBuffer[ii].m_Hole_Diameter;
+ new_tool.m_Hole_NotPlated = m_holeListBuffer[ii].m_Hole_NotPlated;
+ m_toolListBuffer.push_back( new_tool );
+ last_hole = new_tool.m_Diameter;
+ last_notplated_opt = new_tool.m_Hole_NotPlated;
+ }
+
+ jj = m_toolListBuffer.size();
+
+ if( jj == 0 )
+ continue; // Should not occurs
+
+ m_holeListBuffer[ii].m_Tool_Reference = jj; // Tool value Initialized (value >= 1)
+
+ m_toolListBuffer.back().m_TotalCount++;
+
+ if( m_holeListBuffer[ii].m_Hole_Shape )
+ m_toolListBuffer.back().m_OvalCount++;
+ }
+}
+
+
+std::vector<LAYER_PAIR> EXCELLON_WRITER::getUniqueLayerPairs() const
+{
+ wxASSERT( m_pcb );
+
+ static const KICAD_T interesting_stuff_to_collect[] = {
+ PCB_VIA_T,
+ EOT
+ };
+
+ PCB_TYPE_COLLECTOR vias;
+
+ vias.Collect( m_pcb, interesting_stuff_to_collect );
+
+ std::set< LAYER_PAIR > unique;
+
+ LAYER_PAIR layer_pair;
+
+ for( int i = 0; i < vias.GetCount(); ++i )
+ {
+ VIA* v = (VIA*) vias[i];
+
+ v->LayerPair( &layer_pair.first, &layer_pair.second );
+
+ // only make note of blind buried.
+ // thru hole is placed unconditionally as first in fetched list.
+ if( layer_pair != LAYER_PAIR( F_Cu, B_Cu ) )
+ {
+ unique.insert( layer_pair );
+ }
+ }
+
+ std::vector<LAYER_PAIR> ret;
+
+ ret.push_back( LAYER_PAIR( F_Cu, B_Cu ) ); // always first in returned list
+
+ for( std::set< LAYER_PAIR >::const_iterator it = unique.begin(); it != unique.end(); ++it )
+ ret.push_back( *it );
+
+ return ret;
+}
+
+
+const std::string EXCELLON_WRITER::layerName( LAYER_ID aLayer ) const
+{
+ // Generic names here.
+ switch( aLayer )
+ {
+ case F_Cu:
+ return "front";
+ case B_Cu:
+ return "back";
+ default:
+ return StrPrintf( "inner%d", aLayer );
+ }
+}
+
+
+const std::string EXCELLON_WRITER::layerPairName( LAYER_PAIR aPair ) const
+{
+ std::string ret = layerName( aPair.first );
+ ret += '-';
+ ret += layerName( aPair.second );
+
+ return ret;
+}
+
+
+const wxString EXCELLON_WRITER::drillFileName( LAYER_PAIR aPair, bool aNPTH ) const
+{
+ wxASSERT( m_pcb );
+
+ wxString extend;
+
+ if( aNPTH )
+ extend = "-NPTH";
+ else if( aPair == LAYER_PAIR( F_Cu, B_Cu ) )
+ {
+ // extend with nothing
+ }
+ else
+ {
+ extend += '-';
+ extend += layerPairName( aPair );
+ }
+
+ wxFileName fn = m_pcb->GetFileName();
+
+ fn.SetName( fn.GetName() + extend );
+ fn.SetExt( DrillFileExtension );
+
+ wxString ret = fn.GetFullName(); // show me in debugger
+
+ return ret;
+}
diff --git a/pcbnew/exporters/gendrill_Excellon_writer.h b/pcbnew/exporters/gendrill_Excellon_writer.h
new file mode 100644
index 0000000..9a4d9c1
--- /dev/null
+++ b/pcbnew/exporters/gendrill_Excellon_writer.h
@@ -0,0 +1,368 @@
+/**
+ * @file gendrill_Excellon_writer.h
+ * @brief Classes used in drill files, map files and report files generation.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 Jean_Pierre Charras <jp.charras at wanadoo.fr>
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _GENDRILL_EXCELLON_WRITER_
+#define _GENDRILL_EXCELLON_WRITER_
+
+#include <vector>
+
+
+class BOARD;
+class PLOTTER;
+
+
+// the DRILL_TOOL class handles tools used in the excellon drill file:
+class DRILL_TOOL
+{
+public:
+ int m_Diameter; // the diameter of the used tool (for oblong, the smaller size)
+ int m_TotalCount; // how many times it is used (round and oblong)
+ int m_OvalCount; // oblong count
+ bool m_Hole_NotPlated; // Is the hole plated or not plated
+
+public:
+ DRILL_TOOL( int aDiameter, bool a_NotPlated )
+ {
+ m_TotalCount = 0;
+ m_OvalCount = 0;
+ m_Diameter = aDiameter;
+ m_Hole_NotPlated = a_NotPlated;
+ }
+};
+
+
+/* the HOLE_INFO class handle hole which must be drilled (diameter, position and layers)
+ * For buried or micro vias, the hole is not on all layers.
+ * So we must generate a drill file for each layer pair (adjacent layers)
+ * Not plated holes are always through holes, and must be output on a specific drill file
+ * because they are drilled after the Pcb process is finished.
+ */
+class HOLE_INFO
+{
+public:
+ int m_Hole_Diameter; // hole value, and for oblong: min(hole size x, hole size y)
+ int m_Tool_Reference; // Tool reference for this hole = 1 ... n (values <=0 must not be used)
+ wxSize m_Hole_Size; // hole size for oblong holes
+ double m_Hole_Orient; // Hole rotation (= pad rotation) for oblong holes
+ int m_Hole_Shape; // hole shape: round (0) or oval (1)
+ wxPoint m_Hole_Pos; // hole position
+ LAYER_ID m_Hole_Bottom_Layer; // hole ending layer (usually back layer)
+ LAYER_ID m_Hole_Top_Layer; // hole starting layer (usually front layer):
+ // m_Hole_Top_Layer < m_Hole_Bottom_Layer
+ bool m_Hole_NotPlated; // hole not plated. Must be in a specific drill file or section
+
+public:
+ HOLE_INFO()
+ {
+ m_Hole_NotPlated = false;
+ m_Hole_Diameter = 0;
+ m_Tool_Reference = 0;
+ m_Hole_Orient = 0.0;
+ m_Hole_Shape = 0;
+ m_Hole_Bottom_Layer = B_Cu;
+ m_Hole_Top_Layer = F_Cu;
+ }
+};
+
+
+/* the DRILL_PRECISION helper class to handle drill precision format in excellon files
+ */
+class DRILL_PRECISION
+{
+public:
+ int m_lhs; // Left digit number (integer value of coordinates)
+ int m_rhs; // Right digit number (decimal value of coordinates)
+
+public: DRILL_PRECISION( int l = 2, int r = 4 )
+ {
+ m_lhs = l; m_rhs = r;
+ }
+
+
+ wxString GetPrecisionString()
+ {
+ wxString text;
+
+ text << m_lhs << wxT( ":" ) << m_rhs;
+ return text;
+ }
+};
+
+
+typedef std::pair<LAYER_ID, LAYER_ID> LAYER_PAIR;
+class OUTPUTFORMATTER;
+
+/**
+ * EXCELLON_WRITER is a class mainly used to create Excellon drill files
+ * However, this class is also used to create drill maps and drill report
+ */
+class EXCELLON_WRITER
+{
+public:
+ enum ZEROS_FMT { // Zero format in coordinates
+ DECIMAL_FORMAT, // Floating point coordinates
+ SUPPRESS_LEADING, // Suppress leading zeros
+ SUPPRESS_TRAILING, // Suppress trainling zeros
+ KEEP_ZEROS // keep zeros
+ };
+
+ wxPoint m_Offset; // offset coordinates
+ bool m_ShortHeader; // true to generate the smallest header (strip comments)
+
+private:
+ FILE* m_file; // The output file
+ BOARD* m_pcb;
+ bool m_minimalHeader; // True to use minimal header
+ // in excellon file (strip comments)
+ bool m_unitsDecimal; // true = decimal, false = inches
+ ZEROS_FMT m_zeroFormat; // the zero format option for output file
+ DRILL_PRECISION m_precision; // The current coordinate precision (not used in decimal format)
+ double m_conversionUnits; // scaling factor to convert the board unites to Excellon units
+ // (i.e inches or mm)
+ bool m_mirror;
+ wxPoint m_offset; // Drill offset coordinates
+ bool m_merge_PTH_NPTH; // True to generate only one drill file
+ std::vector<HOLE_INFO> m_holeListBuffer; // Buffer containing holes
+ std::vector<DRILL_TOOL> m_toolListBuffer; // Buffer containing tools
+
+ PlotFormat m_mapFileFmt; // the format of the map drill file,
+ // if this map is needed
+ const PAGE_INFO* m_pageInfo; // the page info used to plot drill maps
+ // If NULL, use a A4 page format
+
+public:
+ EXCELLON_WRITER( BOARD* aPcb );
+
+ ~EXCELLON_WRITER()
+ {
+ }
+
+ /**
+ * Return the plot offset (usually the position
+ * of the auxiliary axis
+ */
+ const wxPoint GetOffset() { return m_offset; }
+
+ /**
+ * Function SetFormat
+ * Initialize internal parameters to match the given format
+ * @param aMetric = true for metric coordinates, false for imperial units
+ * @param aZerosFmt = DECIMAL_FORMAT, SUPPRESS_LEADING, SUPPRESS_TRAILING, KEEP_ZEROS
+ * @param aLeftDigits = number of digits for integer part of coordinates
+ * if <= 0 (default), a suitable value will be used, depending on units
+ * @param aRightDigits = number of digits for mantissa part of coordinates
+ * if <= 0 (default), a suitable value will be used, depending on units
+ */
+ void SetFormat( bool aMetric, ZEROS_FMT aZerosFmt = DECIMAL_FORMAT,
+ int aLeftDigits = 0, int aRightDigits = 0 );
+
+ /**
+ * Sets the page info used to plot drill maps
+ * If NULL, a A4 page format will be used
+ * @param aPageInfo = a reference to the page info, usually used to plot/display the board
+ */
+ void SetPageInfo( const PAGE_INFO* aPageInfo ) { m_pageInfo = aPageInfo; }
+
+ /**
+ * Function SetMapFileFormat
+ * Initialize the format for the drill map file
+ * @param SetMapFileFormat = a PlotFormat value (one of
+ * PLOT_FORMAT_HPGL, PLOT_FORMAT_POST, PLOT_FORMAT_GERBER,
+ * PLOT_FORMAT_DXF, PLOT_FORMAT_SVG, PLOT_FORMAT_PDF
+ * the most useful are PLOT_FORMAT_PDF and PLOT_FORMAT_POST
+ */
+ void SetMapFileFormat( PlotFormat aMapFmt ) { m_mapFileFmt = aMapFmt; }
+
+
+ /**
+ * Function SetOptions
+ * Initialize internal parameters to match drill options
+ * @param aMirror = true to create mirrored coordinates (Y coordinates negated)
+ * @param aMinimalHeader = true to use a minimal header (no comments, no info)
+ * @param aOffset = drill coordinates offset
+ */
+ void SetOptions( bool aMirror, bool aMinimalHeader, wxPoint aOffset, bool aMerge_PTH_NPTH )
+ {
+ m_mirror = aMirror;
+ m_offset = aOffset;
+ m_minimalHeader = aMinimalHeader;
+ m_merge_PTH_NPTH = aMerge_PTH_NPTH;
+ }
+
+ /**
+ * Function BuildHolesList
+ * Create the list of holes and tools for a given board
+ * The list is sorted by increasing drill size.
+ * Only holes included within aLayerPair are listed.
+ * If aLayerPair identifies with [F_Cu, B_Cu], then
+ * pad holes are always included also.
+ *
+ * @param aLayerPair is an inclusive range of layers.
+ * @param aGenerateNPTH_list :
+ * true to create NPTH only list (with no plated holes)
+ * false to created plated holes list (with no NPTH )
+ */
+ void BuildHolesList( LAYER_PAIR aLayerPair,
+ bool aGenerateNPTH_list );
+
+ int GetHolesCount() const { return m_holeListBuffer.size(); }
+
+ /**
+ * Function CreateDrillandMapFilesSet
+ * Creates the full set of Excellon drill file for the board
+ * filenames are computed from the board name, and layers id
+ * @param aPlotDirectory = the output folder
+ * @param aGenDrill = true to generate the EXCELLON drill file
+ * @param aGenMap = true to generate a drill map file
+ * @param aReporter = a REPORTER to return activity or any message (can be NULL)
+ */
+ void CreateDrillandMapFilesSet( const wxString& aPlotDirectory,
+ bool aGenDrill, bool aGenMap,
+ REPORTER * aReporter = NULL );
+
+ /**
+ * Function CreateDrillFile
+ * Creates an Excellon drill file
+ * @param aFile = an opened file to write to will be closed by CreateDrillFile
+ * @return hole count
+ */
+ int CreateDrillFile( FILE * aFile );
+
+ /**
+ * Function GenDrillReportFile
+ * Create a plain text report file giving a list of drill values and drill count
+ * for through holes, oblong holes, and for buried vias,
+ * drill values and drill count per layer pair
+ * there is only one report for all drill files even when buried or blinds vias exist
+ *
+ * Here is a sample created by this function:
+ * Drill report for F:/tmp/interf_u/interf_u.brd
+ * Created on 04/10/2012 20:48:38
+ * Selected Drill Unit: Imperial (inches)
+ *
+ * Drill report for plated through holes :
+ * T1 0,025" 0,64mm (88 holes)
+ * T2 0,031" 0,79mm (120 holes)
+ * T3 0,032" 0,81mm (151 holes) (with 1 slot)
+ * T4 0,040" 1,02mm (43 holes)
+ * T5 0,079" 2,00mm (1 hole) (with 1 slot)
+ * T6 0,120" 3,05mm (1 hole) (with 1 slot)
+ *
+ * Total plated holes count 404
+ *
+ *
+ * Drill report for buried and blind vias :
+ *
+ * Drill report for holes from layer Soudure to layer Interne1 :
+ *
+ * Total plated holes count 0
+ *
+ *
+ * Drill report for holes from layer Interne1 to layer Interne2 :
+ * T1 0,025" 0,64mm (3 holes)
+ *
+ * Total plated holes count 3
+ *
+ *
+ * Drill report for holes from layer Interne2 to layer Composant :
+ * T1 0,025" 0,64mm (1 hole)
+ *
+ * Total plated holes count 1
+ *
+ *
+ * Drill report for unplated through holes :
+ * T1 0,120" 3,05mm (1 hole) (with 1 slot)
+ *
+ * Total unplated holes count 1
+ *
+ * @param aFullFileName : the name of the file to create
+ * m_unitsDecimal = false to use inches, true to use mm in report file
+ *
+ * @return success if the file is created
+ */
+ bool GenDrillReportFile( const wxString& aFullFileName );
+
+ /**
+ * Function GenDrillMapFile
+ * Plot a map of drill marks for holes.
+ * the paper sheet to use to plot the map is set in m_pageInfo
+ * ( calls SetPageInfo() to set it )
+ * if NULL, A4 format will be used
+ * @param aFullFileName : the full filename of the map file to create,
+ * @param aFormat : one of the supported plot formats (see enum PlotFormat )
+ */
+ bool GenDrillMapFile( const wxString& aFullFileName, PlotFormat aFormat );
+
+private:
+ /* Print the DRILL file header. The full header is:
+ * M48
+ * ;DRILL file {PCBNEW (2007-11-29-b)} date 17/1/2008-21:02:35
+ * ;FORMAT={ <precision> / absolute / <units> / <numbers format>}
+ * FMAT,2
+ * INCH,TZ
+ */
+ void WriteEXCELLONHeader();
+
+ void WriteEXCELLONEndOfFile();
+
+ /* Created a line like:
+ * X48000Y19500
+ * According to the selected format
+ */
+ void WriteCoordinates( char* aLine, double aCoordX, double aCoordY );
+
+ /** Helper function.
+ * Writes the drill marks in HPGL, POSTSCRIPT or other supported formats
+ * Each hole size has a symbol (circle, cross X, cross + ...) up to
+ * PLOTTER::MARKER_COUNT different values.
+ * If more than PLOTTER::MARKER_COUNT different values,
+ * these other values share the same mark shape
+ * @param aPlotter = a PLOTTER instance (HPGL, POSTSCRIPT ... plotter).
+ */
+ bool PlotDrillMarks( PLOTTER* aPlotter );
+
+ /// Get unique layer pairs by examining the micro and blind_buried vias.
+ std::vector<LAYER_PAIR> getUniqueLayerPairs() const;
+
+ /**
+ * Function printToolSummary
+ * prints m_toolListBuffer[] tools to aOut and returns total hole count.
+ * @param aOut = the current OUTPUTFORMATTER to print summary
+ * @param aSummaryNPTH = true to print summary for NPTH, false for PTH
+ */
+ unsigned printToolSummary( OUTPUTFORMATTER& aOut, bool aSummaryNPTH ) const;
+
+ const std::string layerPairName( LAYER_PAIR aPair ) const;
+
+ const std::string layerName( LAYER_ID aLayer ) const;
+
+ const wxString drillFileName( LAYER_PAIR aPair, bool aNPTH ) const;
+};
+
+#endif // #ifndef _GENDRILL_EXCELLON_WRITER_
diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp
new file mode 100644
index 0000000..e8465ba
--- /dev/null
+++ b/pcbnew/files.cpp
@@ -0,0 +1,869 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2011-2016 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/files.cpp
+ * @brief Read and write board files.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <wxPcbStruct.h>
+#include <macros.h>
+#include <3d_viewer.h>
+#include <richio.h>
+#include <filter_reader.h>
+#include <pgm_base.h>
+#include <msgpanel.h>
+#include <fp_lib_table.h>
+#include <ratsnest_data.h>
+
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <io_mgr.h>
+#include <wildcards_and_files_ext.h>
+
+#include <class_board.h>
+#include <build_version.h> // LEGACY_BOARD_FILE_VERSION
+#include <module_editor_frame.h>
+#include <modview_frame.h>
+
+#include <wx/stdpaths.h>
+
+
+//#define USE_INSTRUMENTATION true
+#define USE_INSTRUMENTATION false
+
+
+static const wxChar backupSuffix[] = wxT( "-bak" );
+static const wxChar autosavePrefix[] = wxT( "_autosave-" );
+
+
+wxString PCB_EDIT_FRAME::GetAutoSaveFilePrefix()
+{
+ return wxString( autosavePrefix );
+}
+
+
+/**
+ * Function AskLoadBoardFileName
+ * puts up a wxFileDialog asking for a BOARD filename to open.
+ *
+ * @param aParent is a wxFrame passed to wxFileDialog.
+ * @param aCtl is where to put the OpenProjectFiles() control bits.
+ *
+ * @param aFileName on entry is a probable choice, on return is the chosen filename.
+ * @param aKicadFilesOnly true to list kiacad pcb files plugins only, false to list all plugins.
+ *
+ * @return bool - true if chosen, else false if user aborted.
+ */
+bool AskLoadBoardFileName( wxWindow* aParent, int* aCtl, wxString* aFileName, bool aKicadFilesOnly = false )
+{
+ // This is a subset of all PLUGINs which are trusted to be able to
+ // load a BOARD. User may occasionally use the wrong plugin to load a
+ // *.brd file (since both legacy and eagle use *.brd extension),
+ // but eventually *.kicad_pcb will be more common than legacy *.brd files.
+ static const struct
+ {
+ const wxString& filter;
+ IO_MGR::PCB_FILE_T pluginType;
+ } loaders[] =
+ {
+ { PcbFileWildcard, IO_MGR::KICAD },
+ { LegacyPcbFileWildcard, IO_MGR::LEGACY },
+ { EaglePcbFileWildcard, IO_MGR::EAGLE },
+ { PCadPcbFileWildcard, IO_MGR::PCAD },
+ };
+
+ wxFileName fileName( *aFileName );
+ wxString fileFilters;
+
+ unsigned pluginsCount = aKicadFilesOnly ? 2 : DIM( loaders );
+
+ for( unsigned i=0; i < pluginsCount; ++i )
+ {
+ if( i > 0 )
+ fileFilters += wxChar( '|' );
+
+ fileFilters += wxGetTranslation( loaders[i].filter );
+ }
+
+ wxString path;
+ wxString name;
+
+ if( fileName.FileExists() )
+ {
+ path = fileName.GetPath();
+ name = fileName.GetFullName();
+ }
+ else
+ {
+ path = wxStandardPaths::Get().GetDocumentsDir();
+ // leave name empty
+ }
+
+ wxFileDialog dlg( aParent, _( "Open Board File" ), path, name, fileFilters,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST );
+
+ if( dlg.ShowModal() != wxID_CANCEL )
+ {
+ int chosenFilter = dlg.GetFilterIndex();
+
+ // if Eagle, tell OpenProjectFiles() to use Eagle plugin. It's the only special
+ // case because of the duplicate use of the *.brd file extension. Other cases
+ // are clear because of unique file extensions.
+ *aCtl = chosenFilter == 2 ? KICTL_EAGLE_BRD : 0;
+ *aFileName = dlg.GetPath();
+
+ return true;
+ }
+ else
+ return false;
+}
+
+
+/**
+ * Function AskSaveBoardFileName
+ * puts up a wxFileDialog asking for a BOARD filename to save.
+ *
+ * @param aParent is a wxFrame passed to wxFileDialog.
+ * @param aFileName on entry is a probable choice, on return is the
+ * chosen full filename (includes path).
+ *
+ * @return bool - true if chosen, else false if user aborted.
+ */
+bool AskSaveBoardFileName( wxWindow* aParent, wxString* aFileName )
+{
+ wxString wildcard = wxGetTranslation( PcbFileWildcard );
+ wxFileName fn = *aFileName;
+
+ fn.SetExt( KiCadPcbFileExtension );
+
+ wxFileDialog dlg( aParent,
+ _( "Save Board File As" ),
+ fn.GetPath(),
+ fn.GetFullName(),
+ wildcard,
+ wxFD_SAVE
+ /* wxFileDialog is not equipped to handle multiple wildcards and
+ wxFD_OVERWRITE_PROMPT both together.
+ | wxFD_OVERWRITE_PROMPT
+ */
+ );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return false;
+
+ fn = dlg.GetPath();
+
+ // always enforce filename extension, user may not have entered it.
+ fn.SetExt( KiCadPcbFileExtension );
+
+ // Since the file overwrite test was removed from wxFileDialog because it doesn't work
+ // when multiple wildcards are defined, we have to check it ourselves to prevent an
+ // existing board file from silently being over written.
+ if( fn.FileExists() )
+ {
+ wxString ask = wxString::Format( _(
+ "The file '%s' already exists.\n\n"
+ "Do you want to overwrite it?" ),
+ GetChars( fn.GetFullPath() )
+ );
+
+ if( !IsOK( aParent, ask ) )
+ {
+ return false;
+ }
+ }
+
+ *aFileName = fn.GetFullPath();
+
+ return true;
+}
+
+
+void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event )
+{
+ wxString fn = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) );
+
+ if( !!fn )
+ {
+ int open_ctl = 0;
+
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+
+ if( !wxFileName::IsFileReadable( fn ) )
+ {
+ if( !AskLoadBoardFileName( this, &open_ctl, &fn ) )
+ return;
+ }
+
+ OpenProjectFiles( std::vector<wxString>( 1, fn ), open_ctl );
+ }
+}
+
+
+void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ Files_io_from_id( id );
+}
+
+void PCB_EDIT_FRAME::Files_io_from_id( int id )
+{
+ wxString msg;
+
+ // If an edition is in progress, stop it.
+ // For something else than save, get rid of current tool.
+ if( id == ID_SAVE_BOARD )
+ m_canvas->EndMouseCapture( -1, m_canvas->GetDefaultCursor() );
+ else
+ m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
+
+ switch( id )
+ {
+ case ID_LOAD_FILE:
+ {
+ // LoadOnePcbFile( GetBoard()->GetFileName(), append=false, aForceFileDialog=true );
+
+ int open_ctl;
+ wxString fileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
+
+ if( !AskLoadBoardFileName( this, &open_ctl, &fileName ) )
+ return;
+
+ OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
+ }
+ break;
+
+ case ID_MENU_READ_BOARD_BACKUP_FILE:
+ case ID_MENU_RECOVER_BOARD_AUTOSAVE:
+ {
+ wxFileName currfn = Prj().AbsolutePath( GetBoard()->GetFileName() );
+ wxFileName fn = currfn;
+
+ if( id == ID_MENU_RECOVER_BOARD_AUTOSAVE )
+ {
+ wxString rec_name = wxString( autosavePrefix ) + fn.GetName();
+ fn.SetName( rec_name );
+ }
+ else
+ {
+ wxString backup_ext = fn.GetExt()+ backupSuffix;
+ fn.SetExt( backup_ext );
+ }
+
+ if( !fn.FileExists() )
+ {
+ msg.Printf( _( "Recovery file '%s' not found." ),
+ GetChars( fn.GetFullPath() ) );
+ DisplayInfoMessage( this, msg );
+ break;
+ }
+
+ msg.Printf( _( "OK to load recovery or backup file '%s'" ),
+ GetChars(fn.GetFullPath() ) );
+
+ if( !IsOK( this, msg ) )
+ break;
+
+ GetScreen()->ClrModify(); // do not prompt the user for changes
+
+ // LoadOnePcbFile( fn.GetFullPath(), aAppend=false, aForceFileDialog=false );
+ OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
+
+ // Re-set the name since name or extension was changed
+ GetBoard()->SetFileName( currfn.GetFullPath() );
+ UpdateTitle();
+ }
+ break;
+
+ case ID_APPEND_FILE:
+ {
+ int open_ctl;
+ wxString fileName;
+
+ if( !AskLoadBoardFileName( this, &open_ctl, &fileName, true ) )
+ break;
+
+ AppendBoardFile( fileName, open_ctl );
+
+ m_canvas->Refresh();
+ }
+ break;
+
+ case ID_NEW_BOARD:
+ {
+ if( !Clear_Pcb( true ) )
+ break;
+
+ wxFileName fn( wxStandardPaths::Get().GetDocumentsDir(), wxT( "noname" ),
+ ProjectFileExtension );
+
+ Prj().SetProjectFullName( fn.GetFullPath() );
+
+ fn.SetExt( PcbFileExtension );
+
+ GetBoard()->SetFileName( fn.GetFullPath() );
+ UpdateTitle();
+ ReCreateLayerBox();
+ break;
+ }
+
+ case ID_SAVE_BOARD:
+ if( ! GetBoard()->GetFileName().IsEmpty() )
+ {
+ SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) );
+ break;
+ }
+ // Fall through
+ case ID_COPY_BOARD_AS:
+ case ID_SAVE_BOARD_AS:
+ {
+ wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
+ wxFileName fn( pro_dir, _( "noname" ), KiCadPcbFileExtension );
+ wxString filename = fn.GetFullPath();
+
+ if( AskSaveBoardFileName( this, &filename ) )
+ {
+ if( id == ID_COPY_BOARD_AS )
+ SavePcbCopy( filename );
+ else
+ SavePcbFile( filename, NO_BACKUP_FILE );
+ }
+ }
+ break;
+
+ default:
+ DisplayError( this, wxT( "File_io Internal Error" ) );
+ break;
+ }
+}
+
+
+// The KIWAY_PLAYER::OpenProjectFiles() API knows nothing about plugins, so
+// determine how to load the BOARD here, with minor assistance from KICTL_EAGLE_BRD
+// bit flag.
+IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl )
+{
+ IO_MGR::PCB_FILE_T pluginType;
+
+ wxFileName fn = aFileName;
+
+ // Note: file extensions are expected to be in ower case.
+ // This is not always true, especially when importing files, so the string
+ // comparisons are case insensitive to try to find the suitable plugin.
+
+ if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::LEGACY ) ) == 0 )
+ {
+ // both legacy and eagle share a common file extension.
+ pluginType = ( aCtl & KICTL_EAGLE_BRD ) ? IO_MGR::EAGLE : IO_MGR::LEGACY;
+ }
+ else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::LEGACY ) + backupSuffix ) == 0 )
+ {
+ pluginType = IO_MGR::LEGACY;
+ }
+ else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::PCAD ) ) == 0 )
+ {
+ pluginType = IO_MGR::PCAD;
+ }
+ else
+ {
+ pluginType = IO_MGR::KICAD;
+ }
+
+ return pluginType;
+}
+
+
+bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
+{
+ // This is for python:
+ if( aFileSet.size() != 1 )
+ {
+ UTF8 msg = StrPrintf( "Pcbnew:%s() takes only a single filename", __func__ );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ wxString fullFileName( aFileSet[0] );
+
+ // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
+ wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(),
+ wxT( "bug in single_top.cpp or project manager." ) );
+
+ if( !LockFile( fullFileName ) )
+ {
+ wxString msg = wxString::Format( _(
+ "PCB file '%s' is already open." ),
+ GetChars( fullFileName )
+ );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ if( GetScreen()->IsModify() )
+ {
+ int response = YesNoCancelDialog( this, _(
+ "The current board has been modified. Do you wish to save the changes?" ),
+ wxEmptyString,
+ _( "Save and Load" ),
+ _( "Load Without Saving" )
+ );
+
+ if( response == wxID_CANCEL )
+ return false;
+ else if( response == wxID_YES )
+ SavePcbFile( GetBoard()->GetFileName(), CREATE_BACKUP_FILE );
+ else
+ {
+ // response == wxID_NO, fall thru
+ }
+ }
+
+ wxFileName pro = fullFileName;
+ pro.SetExt( ProjectFileExtension );
+
+ bool is_new = !wxFileName::IsFileReadable( fullFileName );
+
+ // If its a non-existent schematic and caller thinks it exists
+ if( is_new && !( aCtl & KICTL_CREATE ) )
+ {
+ // notify user that fullFileName does not exist, ask if user wants to create it.
+ wxString ask = wxString::Format( _(
+ "Board '%s' does not exist. Do you wish to create it?" ),
+ GetChars( fullFileName )
+ );
+ if( !IsOK( this, ask ) )
+ return false;
+ }
+
+ Clear_Pcb( false ); // pass false since we prompted above for a modified board
+
+ IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl );
+
+ bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD;
+
+ if( !converted )
+ {
+ // PROJECT::SetProjectFullName() is an impactful function. It should only be
+ // called under carefully considered circumstances.
+
+ // The calling code should know not to ask me here to change projects unless
+ // it knows what consequences that will have on other KIFACEs running and using
+ // this same PROJECT. It can be very harmful if that calling code is stupid.
+ Prj().SetProjectFullName( pro.GetFullPath() );
+
+ // load project settings before BOARD
+ LoadProjectSettings();
+ }
+
+ if( is_new )
+ {
+ OnModify();
+ }
+ else
+ {
+ BOARD* loadedBoard = 0; // it will be set to non-NULL if loaded OK
+
+ PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
+
+ try
+ {
+ PROPERTIES props;
+ char xbuf[30];
+ char ybuf[30];
+
+ // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
+ sprintf( xbuf, "%d", GetPageSizeIU().x );
+ sprintf( ybuf, "%d", GetPageSizeIU().y );
+
+ props["page_width"] = xbuf;
+ props["page_height"] = ybuf;
+
+#if USE_INSTRUMENTATION
+ // measure the time to load a BOARD.
+ unsigned startTime = GetRunningMicroSecs();
+#endif
+
+ loadedBoard = pi->Load( fullFileName, NULL, &props );
+
+#if USE_INSTRUMENTATION
+ unsigned stopTime = GetRunningMicroSecs();
+ printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime );
+#endif
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _(
+ "Error loading board.\n%s" ),
+ GetChars( ioe.errorText )
+ );
+ DisplayError( this, msg );
+ return false;
+ }
+
+ SetBoard( loadedBoard );
+
+ // we should not ask PLUGINs to do these items:
+ loadedBoard->BuildListOfNets();
+ loadedBoard->SynchronizeNetsAndNetClasses();
+
+ SetStatusText( wxEmptyString );
+ BestZoom();
+
+ // update the layer names in the listbox
+ ReCreateLayerBox( false );
+
+ GetScreen()->ClrModify();
+
+ {
+ wxFileName fn = fullFileName;
+ CheckForAutoSaveFile( fullFileName, fn.GetExt() );
+ }
+
+ if( pluginType == IO_MGR::LEGACY &&
+ loadedBoard->GetFileFormatVersionAtLoad() < LEGACY_BOARD_FILE_VERSION )
+ {
+ DisplayInfoMessage( this,
+ _( "This file was created by an older version of Pcbnew.\n"
+ "It will be stored in the new file format when you save this file again." ) );
+ }
+ }
+
+ {
+ wxFileName fn = fullFileName;
+
+ if( converted )
+ fn.SetExt( PcbFileExtension );
+
+ wxString fname = fn.GetFullPath();
+
+ fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
+
+ GetBoard()->SetFileName( fname );
+ }
+
+ UpdateTitle();
+
+ if( !converted )
+ UpdateFileHistory( GetBoard()->GetFileName() );
+
+ // Rebuild the new pad list (for drc and ratsnet control ...)
+ GetBoard()->m_Status_Pcb = 0;
+
+ // Update current netclass:NETCLASS::Default alwaysxists
+ SetCurrentNetClass( NETCLASS::Default );
+
+ // Rebuild list of nets (full ratsnest rebuild)
+ {
+ wxBusyCursor dummy; // Displays an Hourglass while building connectivity
+ Compile_Ratsnest( NULL, true );
+ GetBoard()->GetRatsnest()->ProcessBoard();
+ }
+
+ // Update info shown by the horizontal toolbars
+ ReFillLayerWidget();
+ ReCreateLayerBox();
+
+ // upate the layer widget to match board visibility states, both layers and render columns.
+ syncLayerVisibilities();
+ syncLayerWidgetLayer();
+ syncRenderStates();
+
+ // Update the tracks / vias available sizes list:
+ ReCreateAuxiliaryToolbar();
+
+ // Update the RATSNEST items, which were not loaded at the time
+ // BOARD::SetVisibleElements() was called from within any PLUGIN.
+ // See case RATSNEST_VISIBLE: in BOARD::SetElementVisibility()
+ GetBoard()->SetVisibleElements( GetBoard()->GetVisibleElements() );
+
+ // Display the loaded board:
+ Zoom_Automatique( false );
+
+ SetMsgPanel( GetBoard() );
+
+ // Refresh the 3D view, if any
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->NewDisplay();
+
+#if 0 && defined(DEBUG)
+ // Output the board object tree to stdout, but please run from command prompt:
+ GetBoard()->Show( 0, std::cout );
+#endif
+
+ // from EDA_APPL which was first loaded BOARD only:
+ {
+ /* For an obscure reason the focus is lost after loading a board file
+ * when starting up the process.
+ * (seems due to the recreation of the layer manager after loading the file)
+ * Give focus to main window and Drawpanel
+ * must be done for these 2 windows (for an obscure reason ...)
+ * Linux specific
+ * This is more a workaround than a fix.
+ */
+ SetFocus();
+ GetCanvas()->SetFocus();
+ }
+
+ return true;
+}
+
+
+static wxString create_backup_file( const wxString& aFileName )
+{
+ wxFileName fn = aFileName;
+ wxFileName backupFileName = aFileName;
+
+ backupFileName.SetExt( fn.GetExt() + backupSuffix );
+
+ // If an old backup file exists, delete it. If an old board file exists,
+ // rename it to the backup file name.
+ if( fn.FileExists() )
+ {
+ // Remove the old file xxx.000 if it exists.
+ if( backupFileName.FileExists() )
+ wxRemoveFile( backupFileName.GetFullPath() );
+
+ // Rename the current file from <xxx>.kicad_pcb to <xxx>.kicad_pcb-bak
+ if( !wxRenameFile( fn.GetFullPath(), backupFileName.GetFullPath() ) )
+ {
+ wxString msg = wxString::Format( _(
+ "Warning: unable to create backup file '%s'" ),
+ GetChars( backupFileName.GetFullPath() )
+ );
+ DisplayError( NULL, msg );
+ }
+ }
+ else
+ {
+ backupFileName.Clear();
+ }
+
+ return backupFileName.GetFullPath();
+}
+
+
+bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupFile )
+{
+ // please, keep it simple. prompting goes elsewhere.
+
+ wxFileName pcbFileName = aFileName;
+
+ if( pcbFileName.GetExt() == LegacyPcbFileExtension )
+ pcbFileName.SetExt( KiCadPcbFileExtension );
+
+ if( !IsWritable( pcbFileName ) )
+ {
+ wxString msg = wxString::Format( _(
+ "No access rights to write to file '%s'" ),
+ GetChars( pcbFileName.GetFullPath() )
+ );
+
+ DisplayError( this, msg );
+ return false;
+ }
+
+ wxString backupFileName;
+
+ // aCreateBackupFile == false is mainly used to write autosave files
+ // or new files in save as... command
+ if( aCreateBackupFile )
+ {
+ backupFileName = create_backup_file( aFileName );
+ }
+
+ GetBoard()->m_Status_Pcb &= ~CONNEXION_OK;
+
+ GetBoard()->SynchronizeNetsAndNetClasses();
+
+ // Select default Netclass before writing file.
+ // Useful to save default values in headers
+ SetCurrentNetClass( NETCLASS::Default );
+
+ ClearMsgPanel();
+
+ wxString upperTxt;
+ wxString lowerTxt;
+
+ try
+ {
+ PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::KICAD ) );
+
+ wxASSERT( pcbFileName.IsAbsolute() );
+
+ pi->Save( pcbFileName.GetFullPath(), GetBoard(), NULL );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _(
+ "Error saving board file '%s'.\n%s" ),
+ GetChars( pcbFileName.GetFullPath() ),
+ GetChars( ioe.errorText )
+ );
+ DisplayError( this, msg );
+
+ lowerTxt.Printf( _( "Failed to create '%s'" ), GetChars( pcbFileName.GetFullPath() ) );
+
+ AppendMsgPanel( upperTxt, lowerTxt, CYAN );
+
+ return false;
+ }
+
+ GetBoard()->SetFileName( pcbFileName.GetFullPath() );
+ UpdateTitle();
+
+ // Put the saved file in File History, unless aCreateBackupFile
+ // is false.
+ // aCreateBackupFile == false is mainly used to write autosave files
+ // and not need to have an autosave file in file history
+ if( aCreateBackupFile )
+ UpdateFileHistory( GetBoard()->GetFileName() );
+
+ // Delete auto save file on successful save.
+ wxFileName autoSaveFileName = pcbFileName;
+
+ autoSaveFileName.SetName( wxString( autosavePrefix ) + pcbFileName.GetName() );
+
+ if( autoSaveFileName.FileExists() )
+ wxRemoveFile( autoSaveFileName.GetFullPath() );
+
+ if( !!backupFileName )
+ upperTxt.Printf( _( "Backup file: '%s'" ), GetChars( backupFileName ) );
+
+ lowerTxt.Printf( _( "Wrote board file: '%s'" ), GetChars( pcbFileName.GetFullPath() ) );
+
+ AppendMsgPanel( upperTxt, lowerTxt, CYAN );
+
+ GetScreen()->ClrModify();
+ GetScreen()->ClrSave();
+ return true;
+}
+
+
+bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName )
+{
+ wxFileName pcbFileName = aFileName;
+
+ // Ensure the file ext is the right ext:
+ pcbFileName.SetExt( KiCadPcbFileExtension );
+
+ if( !IsWritable( pcbFileName ) )
+ {
+ wxString msg = wxString::Format( _(
+ "No access rights to write to file '%s'" ),
+ GetChars( pcbFileName.GetFullPath() )
+ );
+
+ DisplayError( this, msg );
+ return false;
+ }
+
+ GetBoard()->m_Status_Pcb &= ~CONNEXION_OK;
+ GetBoard()->SynchronizeNetsAndNetClasses();
+
+ // Select default Netclass before writing file.
+ // Useful to save default values in headers
+ SetCurrentNetClass( NETCLASS::Default );
+
+ try
+ {
+ PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::KICAD ) );
+
+ wxASSERT( pcbFileName.IsAbsolute() );
+
+ pi->Save( pcbFileName.GetFullPath(), GetBoard(), NULL );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _(
+ "Error saving board file '%s'.\n%s" ),
+ GetChars( pcbFileName.GetFullPath() ),
+ GetChars( ioe.errorText )
+ );
+ DisplayError( this, msg );
+
+ return false;
+ }
+
+ DisplayInfoMessage( this, wxString::Format( _( "Board copied to:\n'%s'" ),
+ GetChars( pcbFileName.GetFullPath() ) ) );
+
+ return true;
+}
+
+
+bool PCB_EDIT_FRAME::doAutoSave()
+{
+ wxFileName tmpFileName;
+
+ if( GetBoard()->GetFileName().IsEmpty() )
+ {
+ tmpFileName = wxFileName( wxStandardPaths::Get().GetDocumentsDir(), wxT( "noname" ),
+ KiCadPcbFileExtension );
+ GetBoard()->SetFileName( tmpFileName.GetFullPath() );
+ }
+ else
+ {
+ tmpFileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
+ }
+
+ wxFileName autoSaveFileName = tmpFileName;
+
+ // Auto save file name is the board file name prepended with autosaveFilePrefix string.
+ autoSaveFileName.SetName( wxString( autosavePrefix ) + autoSaveFileName.GetName() );
+
+ if( !autoSaveFileName.IsOk() )
+ return false;
+
+ // If the board file path is not writable, try writing to a platform specific temp file
+ // path. If that path isn't writabe, give up.
+ if( !autoSaveFileName.IsDirWritable() )
+ {
+ autoSaveFileName.SetPath( wxFileName::GetTempDir() );
+
+ if( !autoSaveFileName.IsOk() || !autoSaveFileName.IsDirWritable() )
+ return false;
+ }
+
+ wxLogTrace( traceAutoSave, "Creating auto save file <" + autoSaveFileName.GetFullPath() + ">" );
+
+ if( SavePcbFile( autoSaveFileName.GetFullPath(), NO_BACKUP_FILE ) )
+ {
+ GetScreen()->SetModify();
+ GetBoard()->SetFileName( tmpFileName.GetFullPath() );
+ UpdateTitle();
+ m_autoSaveState = false;
+ return true;
+ }
+
+ GetBoard()->SetFileName( tmpFileName.GetFullPath() );
+
+ return false;
+}
diff --git a/pcbnew/footprint_wizard.cpp b/pcbnew/footprint_wizard.cpp
new file mode 100644
index 0000000..f63f8e5
--- /dev/null
+++ b/pcbnew/footprint_wizard.cpp
@@ -0,0 +1,305 @@
+/**
+ * @file footprint_wizard.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+#include <dialog_helpers.h>
+#include <3d_viewer.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include "footprint_wizard_frame.h"
+#include <wildcards_and_files_ext.h>
+#include <dialogs/dialog_footprint_wizard_list.h>
+#include <base_units.h>
+
+
+void FOOTPRINT_WIZARD_FRAME::Process_Special_Functions( wxCommandEvent& event )
+{
+ wxString msg;
+ int page;
+
+ switch( event.GetId() )
+ {
+ case ID_FOOTPRINT_WIZARD_NEXT:
+ m_pageList->SetSelection( m_pageList->GetSelection() + 1, true );
+ ClickOnPageList( event );
+ break;
+
+ case ID_FOOTPRINT_WIZARD_PREVIOUS:
+ page = m_pageList->GetSelection() - 1;
+
+ if( page < 0 )
+ page = 0;
+
+ m_pageList->SetSelection( page, true );
+ ClickOnPageList( event );
+ break;
+
+ default:
+ msg << wxT( "FOOTPRINT_WIZARD_FRAME::Process_Special_Functions error: id = " )
+ << event.GetId();
+ wxMessageBox( msg );
+ break;
+ }
+}
+
+
+/* Function OnLeftClick
+ * Captures a left click event in the dialog
+ *
+ */
+void FOOTPRINT_WIZARD_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
+{
+}
+
+
+/* Function OnRightClick
+ * Captures a right click event in the dialog
+ *
+ */
+bool FOOTPRINT_WIZARD_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu )
+{
+ return true;
+}
+
+
+/* Displays the name of the current opened library in the caption */
+void FOOTPRINT_WIZARD_FRAME::DisplayWizardInfos()
+{
+ wxString msg;
+
+ msg = _( "Footprint Wizard" );
+ msg << wxT( " [" );
+
+ if( !m_wizardName.IsEmpty() )
+ msg << m_wizardName;
+ else
+ msg += _( "no wizard selected" );
+
+ msg << wxT( "]" );
+
+ SetTitle( msg );
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::ReloadFootprint()
+{
+ FOOTPRINT_WIZARD* footprintWizard = GetMyWizard();
+
+ if( !footprintWizard )
+ return;
+
+ SetCurItem( NULL );
+ // Delete the current footprint
+ GetBoard()->m_Modules.DeleteAll();
+
+ // Creates the module
+ wxString msg;
+ MODULE* module = footprintWizard->GetFootprint( &msg );
+ DisplayBuildMessage( msg );
+
+ if( module )
+ {
+ // Add the object to board
+ GetBoard()->Add( module, ADD_APPEND );
+ module->SetPosition( wxPoint( 0, 0 ) );
+ }
+ else
+ {
+ DBG(printf( "footprintWizard->GetFootprint() returns NULL\n" );)
+ }
+
+ m_canvas->Refresh();
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::DisplayBuildMessage( wxString& aMessage )
+{
+ if( m_messagesFrame == NULL )
+ {
+ // Prepare the window to display the message generated by the footprint script builder
+ m_messagesFrame = new FOOTPRINT_WIZARD_MESSAGES( this, config() );
+ m_messagesFrame->Show( true );
+ }
+
+ m_messagesFrame->ClearScreen();
+
+ if( !aMessage.IsEmpty() )
+ m_messagesFrame->PrintMessage( aMessage );
+}
+
+
+FOOTPRINT_WIZARD* FOOTPRINT_WIZARD_FRAME::GetMyWizard()
+{
+ if( m_wizardName.Length() == 0 )
+ return NULL;
+
+ FOOTPRINT_WIZARD* footprintWizard = FOOTPRINT_WIZARDS::GetWizard( m_wizardName );
+
+ if( !footprintWizard )
+ {
+ wxMessageBox( _( "Couldn't reload footprint wizard" ) );
+ return NULL;
+ }
+
+ return footprintWizard;
+}
+
+
+MODULE* FOOTPRINT_WIZARD_FRAME::GetBuiltFootprint()
+{
+ FOOTPRINT_WIZARD* footprintWizard = FOOTPRINT_WIZARDS::GetWizard( m_wizardName );
+
+ if( footprintWizard && m_modal_ret_val )
+ {
+ wxString msg;
+ MODULE * footprint = footprintWizard->GetFootprint( &msg );
+ DisplayBuildMessage( msg );
+
+ return footprint;
+ }
+
+ return NULL;
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::SelectFootprintWizard()
+{
+ DIALOG_FOOTPRINT_WIZARD_LIST wizardSelector( this );
+
+ if( wizardSelector.ShowModal() != wxID_OK )
+ return;
+
+ FOOTPRINT_WIZARD* footprintWizard = wizardSelector.GetWizard();
+
+ if( footprintWizard )
+ {
+ m_wizardName = footprintWizard->GetName();
+ m_wizardDescription = footprintWizard->GetDescription();
+ }
+ else
+ {
+ m_wizardName.Empty();
+ m_wizardDescription.Empty();
+ }
+
+ ReloadFootprint();
+ Zoom_Automatique( false );
+ DisplayWizardInfos();
+ ReCreatePageList();
+ ReCreateParameterList();
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::SelectCurrentWizard( wxCommandEvent& event )
+{
+ SelectFootprintWizard();
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxGridEvent& event )
+{
+ int page = m_pageList->GetSelection();
+
+ FOOTPRINT_WIZARD* footprintWizard = GetMyWizard();
+
+ if( !footprintWizard )
+ return;
+
+ if( page < 0 )
+ return;
+
+ wxArrayString prmValues = footprintWizard->GetParameterValues( page );
+ wxArrayString ptList = footprintWizard->GetParameterTypes( page );
+
+ bool has_changed = false;
+ int count = m_parameterGrid->GetNumberRows();
+
+ // Skip extra event, useless
+ if( event.GetString() == m_parameterGrid->GetCellValue( event.GetRow(), m_columnPrmValue ) )
+ return;
+
+ for( int prm_id = 0; prm_id < count; ++prm_id )
+ {
+ wxString value = m_parameterGrid->GetCellValue( prm_id, m_columnPrmValue );
+
+ // if this parameter is expected to be an internal
+ // unit convert it back from the user format
+ if( ptList[prm_id]==wxT( "IU" ) )
+ {
+ // If our locale is set to use, for decimal point, just change it
+ // to be scripting compatible
+ LOCALE_IO toggle;
+ double dValue;
+
+ value.ToDouble( &dValue );
+
+ // convert from mils to inches where it's needed
+ if( g_UserUnit==INCHES )
+ dValue = dValue / 1000.0;
+
+ dValue = From_User_Unit( g_UserUnit, dValue );
+
+ // Internal units are int. Print them as int.
+ value.Printf( "%d", KiROUND( dValue ) );
+
+ if( prmValues[prm_id].EndsWith(".0") )
+ {
+ prmValues[prm_id].RemoveLast();
+ prmValues[prm_id].RemoveLast();
+ }
+ }
+
+ if( prmValues[prm_id] != value )
+ {
+ has_changed = true;
+ prmValues[prm_id] = value;
+ }
+ }
+
+ if( has_changed )
+ {
+ wxString res = footprintWizard->SetParameterValues( page, prmValues );
+
+ if( !res.IsEmpty() )
+ wxMessageBox( res );
+
+ ReloadFootprint();
+ DisplayWizardInfos();
+ }
+}
+
+
+/**
+ * Function RedrawActiveWindow
+ * Display the current selected component.
+ * If the component is an alias, the ROOT component is displayed
+ *
+ */
+void FOOTPRINT_WIZARD_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
+{
+ if( !GetBoard() )
+ return;
+
+ m_canvas->DrawBackGround( DC );
+ GetBoard()->Draw( m_canvas, DC, GR_COPY );
+
+ MODULE* module = GetBoard()->m_Modules;
+
+ if( module )
+ SetMsgPanel( module );
+
+ m_canvas->DrawCrossHair( DC );
+
+ ClearMsgPanel();
+
+ if( module )
+ SetMsgPanel( module );
+}
diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp
new file mode 100644
index 0000000..81f2640
--- /dev/null
+++ b/pcbnew/footprint_wizard_frame.cpp
@@ -0,0 +1,721 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2015 Miguel Angel Ajo Pelayo <miguelangel@nbee.es>
+ * Copyright (C) 2012-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file footprint_wizard_frame.cpp
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+#include <3d_viewer.h>
+#include <msgpanel.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <module_editor_frame.h>
+
+#include <pcbnew_id.h>
+#include "footprint_wizard_frame.h"
+#include <footprint_info.h>
+#include <wx/grid.h>
+
+#include <hotkeys.h>
+#include <wildcards_and_files_ext.h>
+#include <base_units.h>
+
+
+BEGIN_EVENT_TABLE( FOOTPRINT_WIZARD_FRAME, EDA_DRAW_FRAME )
+
+ // Window events
+ EVT_CLOSE( FOOTPRINT_WIZARD_FRAME::OnCloseWindow )
+ EVT_SIZE( FOOTPRINT_WIZARD_FRAME::OnSize )
+ EVT_ACTIVATE( FOOTPRINT_WIZARD_FRAME::OnActivate )
+
+ // Toolbar events
+ EVT_TOOL( ID_FOOTPRINT_WIZARD_SELECT_WIZARD,
+ FOOTPRINT_WIZARD_FRAME::SelectCurrentWizard )
+
+ EVT_TOOL( ID_FOOTPRINT_WIZARD_NEXT,
+ FOOTPRINT_WIZARD_FRAME::Process_Special_Functions )
+
+ EVT_TOOL( ID_FOOTPRINT_WIZARD_PREVIOUS,
+ FOOTPRINT_WIZARD_FRAME::Process_Special_Functions )
+
+ EVT_TOOL( ID_FOOTPRINT_WIZARD_DONE,
+ FOOTPRINT_WIZARD_FRAME::ExportSelectedFootprint )
+
+ EVT_TOOL( ID_FOOTPRINT_WIZARD_SHOW_3D_VIEW,
+ FOOTPRINT_WIZARD_FRAME::Show3D_Frame )
+
+ // listbox events
+ EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PAGE_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnPageList )
+ EVT_GRID_CMD_CELL_CHANGED( ID_FOOTPRINT_WIZARD_PARAMETER_LIST,
+ FOOTPRINT_WIZARD_FRAME::ParametersUpdated )
+
+ EVT_MENU( ID_SET_RELATIVE_OFFSET, FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset )
+END_EVENT_TABLE()
+
+// Column index to display parameters in m_parameterGrid
+int FOOTPRINT_WIZARD_FRAME::m_columnPrmName = 0;
+int FOOTPRINT_WIZARD_FRAME::m_columnPrmValue = 1;
+int FOOTPRINT_WIZARD_FRAME::m_columnPrmUnit = 2;
+
+#define FOOTPRINT_WIZARD_FRAME_NAME wxT( "FootprintWizard" )
+
+FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway,
+ wxWindow* aParent, FRAME_T aFrameType ) :
+ PCB_BASE_FRAME( aKiway, aParent, aFrameType, _( "Footprint Wizard" ),
+ wxDefaultPosition, wxDefaultSize,
+#ifdef __WINDOWS__
+ KICAD_DEFAULT_DRAWFRAME_STYLE | wxSTAY_ON_TOP,
+#else
+ KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT,
+#endif
+ FOOTPRINT_WIZARD_FRAME_NAME )
+{
+ wxASSERT( aFrameType==FRAME_PCB_FOOTPRINT_WIZARD_MODAL );
+
+ // This frame is always show modal:
+ SetModal( true );
+
+ m_messagesFrame = NULL; // This windows will be created the first time a wizard is loaded
+ m_showAxis = true; // true to draw axis.
+
+ // Give an icon
+ wxIcon icon;
+ icon.CopyFromBitmap( KiBitmap( module_wizard_xpm) );
+ SetIcon( icon );
+
+ m_hotkeysDescrList = g_Module_Viewer_Hokeys_Descr;
+ m_wizardName.Empty();
+
+ SetBoard( new BOARD() );
+
+ // Ensure all layers and items are visible:
+ GetBoard()->SetVisibleAlls();
+ SetScreen( new PCB_SCREEN( GetPageSizeIU() ) );
+ GetScreen()->m_Center = true; // Center coordinate origins on screen.
+
+ LoadSettings( config() );
+
+ SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
+
+ // Set some display options here, because the FOOTPRINT_WIZARD_FRAME
+ // does not have a config menu to do that:
+ DISPLAY_OPTIONS* disp_opts = (DISPLAY_OPTIONS*) GetDisplayOptions();
+ disp_opts->m_DisplayPadIsol = false;
+ disp_opts->m_DisplayPadNum = true;
+ GetBoard()->SetElementVisibility( PCB_VISIBLE(NO_CONNECTS_VISIBLE), false );
+
+ GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
+
+ ReCreateHToolbar();
+ ReCreateVToolbar();
+
+ // Creates the parameter pages list
+ m_pageList = new wxListBox( this, ID_FOOTPRINT_WIZARD_PAGE_LIST,
+ wxDefaultPosition, wxDefaultSize,
+ 0, NULL, wxLB_HSCROLL );
+
+ // Creates the The list of parameters for the current parameter page
+ initParameterGrid();
+
+ ReCreatePageList();
+
+ DisplayWizardInfos();
+
+ m_auimgr.SetManagedWindow( this );
+
+ EDA_PANEINFO horiztb;
+ horiztb.HorizontalToolbarPane();
+
+ EDA_PANEINFO info;
+ info.InfoToolbarPane();
+
+ EDA_PANEINFO mesg;
+ mesg.MessageToolbarPane();
+
+ // Manage main toolbal
+ m_auimgr.AddPane( m_mainToolBar, wxAuiPaneInfo( horiztb ).
+ Name( wxT ("m_mainToolBar" ) ).Top().Row( 0 ) );
+
+ // Manage the left window (list of parameter pages)
+ EDA_PANEINFO paneList;
+ paneList.InfoToolbarPane().Name( wxT( "m_pageList" ) ).Left().Row( 0 );
+ m_auimgr.AddPane( m_pageList, wxAuiPaneInfo( paneList ) );
+
+ // Manage the parameters grid editor for the current parameter page
+ EDA_PANEINFO panePrms;
+ panePrms.InfoToolbarPane().Name( wxT( "m_parameterGrid" ) ).Left().Row( 1 );
+ m_auimgr.AddPane( m_parameterGrid, wxAuiPaneInfo( panePrms ) );
+
+ // Manage the draw panel
+ m_auimgr.AddPane( m_canvas,
+ wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
+
+ // Manage the message panel
+ m_auimgr.AddPane( m_messagePanel,
+ wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(1) );
+
+ // Gives a min size and the last saved size to left windows
+ m_auimgr.GetPane( m_pageList ).MinSize( wxSize(60, -1 ) );
+ m_auimgr.GetPane( m_pageList ).BestSize( wxSize(m_pageListWidth, -1) );
+
+ m_auimgr.GetPane( m_parameterGrid ).MinSize( wxSize( 120, -1 ) );
+ m_auimgr.GetPane( m_parameterGrid ).BestSize( wxSize(m_parameterGridWidth, -1) );
+
+ m_auimgr.Update();
+
+ // Now Drawpanel is sized, we can use BestZoom to show the component (if any)
+#ifdef USE_WX_GRAPHICS_CONTEXT
+ GetScreen()->SetZoom( BestZoom() );
+#else
+ Zoom_Automatique( false );
+#endif
+
+ // Do not Run a dialog here: on some Window Managers, it creates issues.
+ // Reason: the FOOTPRINT_WIZARD_FRAME is run as modal;
+ // It means the call to FOOTPRINT_WIZARD_FRAME::ShowModal will change the
+ // Event Loop Manager, and stop the one created by the dialog.
+ // It does not happen on all W.M., perhaps due to the way the order events are called
+// SelectFootprintWizard();
+}
+
+
+FOOTPRINT_WIZARD_FRAME::~FOOTPRINT_WIZARD_FRAME()
+{
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->Destroy();
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::OnCloseWindow( wxCloseEvent& Event )
+{
+ if( m_messagesFrame )
+ m_messagesFrame->SaveSettings();
+
+ SaveSettings( config() );
+
+ if( IsModal() )
+ {
+ // Only dismiss a modal frame once, so that the return values set by
+ // the prior DismissModal() are not bashed for ShowModal().
+ if( !IsDismissed() )
+ DismissModal( false );
+ }
+ else
+ {
+ Destroy();
+ }
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::ExportSelectedFootprint( wxCommandEvent& aEvent )
+{
+ DismissModal( true );
+ Close();
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::OnSize( wxSizeEvent& SizeEv )
+{
+ if( m_auimgr.GetManagedWindow() )
+ m_auimgr.Update();
+
+ SizeEv.Skip();
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset( wxCommandEvent& event )
+{
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ UpdateStatusBar();
+}
+
+void FOOTPRINT_WIZARD_FRAME::initParameterGrid()
+{
+ // Prepare the grid where parameters are displayed
+ m_parameterGrid = new wxGrid( this, ID_FOOTPRINT_WIZARD_PARAMETER_LIST );
+ m_parameterGrid->CreateGrid( 0, 3 );
+
+ // Columns
+ m_parameterGrid->SetColLabelValue( m_columnPrmName, _( "Parameter" ) );
+ m_parameterGrid->SetColLabelValue( m_columnPrmValue, _( "Value" ) );
+ m_parameterGrid->SetColLabelValue( m_columnPrmUnit, _( "Units" ) );
+ m_parameterGrid->SetColLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTRE );
+ m_parameterGrid->AutoSizeColumns();
+
+ // Rows
+ m_parameterGrid->AutoSizeRows();
+ m_parameterGrid->SetRowLabelSize( 25 );
+ m_parameterGrid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::ReCreatePageList()
+{
+ if( m_pageList == NULL )
+ return;
+
+ FOOTPRINT_WIZARD* footprintWizard = GetMyWizard();
+
+ if( !footprintWizard )
+ return;
+
+ m_pageList->Clear();
+ int max_page = footprintWizard->GetNumParameterPages();
+
+ for( int i = 0; i<max_page; i++ )
+ {
+ wxString name = footprintWizard->GetParameterPageName( i );
+ m_pageList->Append( name );
+ }
+
+ m_pageList->SetSelection( 0, true );
+
+ ReCreateParameterList();
+ ReCreateHToolbar();
+ DisplayWizardInfos();
+ m_canvas->Refresh();
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList()
+{
+ if( m_parameterGrid == NULL )
+ return;
+
+ FOOTPRINT_WIZARD* footprintWizard = GetMyWizard();
+
+ if( footprintWizard == NULL )
+ return;
+
+ int page = m_pageList->GetSelection();
+
+ if( page<0 )
+ return;
+
+ m_parameterGrid->ClearGrid();
+
+ // Get the list of names, values, and types
+ wxArrayString fpList = footprintWizard->GetParameterNames( page );
+ wxArrayString fvList = footprintWizard->GetParameterValues( page );
+ wxArrayString ptList = footprintWizard->GetParameterTypes( page );
+
+ // Dimension the wxGrid
+ if( m_parameterGrid->GetNumberRows() > 0 )
+ m_parameterGrid->DeleteRows( 0, m_parameterGrid->GetNumberRows() );
+
+ m_parameterGrid->AppendRows( fpList.size() );
+
+ wxString value, units;
+ for( unsigned int i = 0; i< fpList.size(); i++ )
+ {
+ value = fvList[i];
+
+ m_parameterGrid->SetCellValue( i, m_columnPrmName, fpList[i] );
+ m_parameterGrid->SetReadOnly( i, m_columnPrmName );
+
+ if( ptList[i]==wxT( "IU" ) )
+ {
+ LOCALE_IO toggle;
+
+ // We are handling internal units, so convert them to the current
+ // system selected units and store into value.
+ double dValue;
+
+ value.ToDouble( &dValue );
+
+ dValue = To_User_Unit( g_UserUnit, dValue );
+
+ if( g_UserUnit==INCHES ) // we convert inches into mils for more detail
+ {
+ dValue = dValue * 1000.0;
+ units = wxT( "mils" );
+ }
+ else if( g_UserUnit==MILLIMETRES )
+ {
+ units = wxT( "mm" );
+ }
+
+ // Use Double2Str to build the string, because useless trailing 0
+ // are removed. The %f format does not remove them
+ std::string s = Double2Str( dValue );
+ value = FROM_UTF8( s.c_str() );
+ }
+ else if( ptList[i]==wxT( "UNITS" ) ) // 1,2,3,4,5 ... N
+ {
+ units = wxT( "" );
+ }
+
+ m_parameterGrid->SetCellValue( i, m_columnPrmValue, value );
+ m_parameterGrid->SetCellValue( i, m_columnPrmUnit, units );
+ m_parameterGrid->SetReadOnly( i, m_columnPrmUnit );
+ }
+
+ m_parameterGrid->AutoSizeColumns();
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::ClickOnPageList( wxCommandEvent& event )
+{
+ int ii = m_pageList->GetSelection();
+
+ if( ii < 0 )
+ return;
+
+ ReCreateParameterList();
+ m_canvas->Refresh();
+ DisplayWizardInfos();
+}
+
+
+#define PAGE_LIST_WIDTH_KEY wxT( "Fpwizard_Pagelist_width" )
+#define PARAMLIST_WIDTH_KEY wxT( "Fpwizard_Paramlist_width" )
+
+
+void FOOTPRINT_WIZARD_FRAME::LoadSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::LoadSettings( aCfg );
+
+ aCfg->Read( PAGE_LIST_WIDTH_KEY, &m_pageListWidth, 100 );
+ aCfg->Read( PARAMLIST_WIDTH_KEY, &m_parameterGridWidth, 200 );
+
+ // Set parameters to a reasonable value.
+ if( m_pageListWidth > m_FrameSize.x / 3 )
+ m_pageListWidth = m_FrameSize.x / 3;
+
+ if( m_parameterGridWidth > m_FrameSize.x / 2 )
+ m_parameterGridWidth = m_FrameSize.x / 2;
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::SaveSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::SaveSettings( aCfg );
+
+ aCfg->Write( PAGE_LIST_WIDTH_KEY, m_pageList->GetSize().x );
+ aCfg->Write( PARAMLIST_WIDTH_KEY, m_parameterGrid->GetSize().x );
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::OnActivate( wxActivateEvent& event )
+{
+ EDA_DRAW_FRAME::OnActivate( event );
+
+ // Ensure we do not have old selection:
+ if( !event.GetActive() )
+ return;
+
+#if 0
+ // Currently, we do not have a way to see if a Python wizard has changed,
+ // therefore the lists of parameters and option has to be rebuilt
+ // This code could be enabled when this way exists
+ bool footprintWizardsChanged = false;
+
+ if( footprintWizardsChanged )
+ {
+ // If we are here, the library list has changed, rebuild it
+ ReCreatePageList();
+ DisplayWizardInfos();
+ }
+#endif
+}
+
+
+bool FOOTPRINT_WIZARD_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
+{
+ bool eventHandled = true;
+
+ // Filter out the 'fake' mouse motion after a keyboard movement
+ if( !aHotKey && m_movingCursorWithKeyboard )
+ {
+ m_movingCursorWithKeyboard = false;
+ return false;
+ }
+
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+ cmd.SetEventObject( this );
+
+ wxPoint pos = aPosition;
+ wxPoint oldpos = GetCrossHairPosition();
+ GeneralControlKeyMovement( aHotKey, &pos, true );
+
+ switch( aHotKey )
+ {
+ case WXK_F1:
+ cmd.SetId( ID_POPUP_ZOOM_IN );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case WXK_F2:
+ cmd.SetId( ID_POPUP_ZOOM_OUT );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case WXK_F3:
+ cmd.SetId( ID_ZOOM_REDRAW );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case WXK_F4:
+ cmd.SetId( ID_POPUP_ZOOM_CENTER );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case WXK_HOME:
+ cmd.SetId( ID_ZOOM_PAGE );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case ' ':
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ break;
+
+ default:
+ eventHandled = false;
+ }
+
+ SetCrossHairPosition( pos );
+ RefreshCrossHair( oldpos, aPosition, aDC );
+
+ UpdateStatusBar(); // Display new cursor coordinates
+
+ return eventHandled;
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::Show3D_Frame( wxCommandEvent& event )
+{
+ if( m_Draw3DFrame )
+ {
+ // Raising the window does not show the window on Windows if iconized.
+ // This should work on any platform.
+ if( m_Draw3DFrame->IsIconized() )
+ m_Draw3DFrame->Iconize( false );
+
+ m_Draw3DFrame->Raise();
+
+ // Raising the window does not set the focus on Linux. This should work on any platform.
+ if( wxWindow::FindFocus() != m_Draw3DFrame )
+ m_Draw3DFrame->SetFocus();
+
+ return;
+ }
+
+ m_Draw3DFrame = new EDA_3D_FRAME( &Kiway(), this, wxEmptyString );
+ Update3D_Frame( false );
+ m_Draw3DFrame->Raise(); // Needed with some Window Managers
+ m_Draw3DFrame->Show( true );
+}
+
+
+/**
+ * Function Update3D_Frame
+ * must be called after a footprint selection
+ * Updates the 3D view and 3D frame title.
+ */
+void FOOTPRINT_WIZARD_FRAME::Update3D_Frame( bool aForceReloadFootprint )
+{
+ if( m_Draw3DFrame == NULL )
+ return;
+
+ wxString frm3Dtitle;
+ frm3Dtitle.Printf( _( "ModView: 3D Viewer [%s]" ), GetChars( m_wizardName ) );
+ m_Draw3DFrame->SetTitle( frm3Dtitle );
+
+ if( aForceReloadFootprint )
+ {
+ m_Draw3DFrame->ReloadRequest();
+
+ // Force 3D screen refresh immediately
+ if( GetBoard()->m_Modules )
+ m_Draw3DFrame->NewDisplay();
+ }
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::ReCreateHToolbar()
+{
+ wxString msg;
+
+ if( !m_mainToolBar )
+ {
+ m_mainToolBar = new wxAuiToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
+
+ // Set up toolbar
+ m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_SELECT_WIZARD, wxEmptyString,
+ KiBitmap( module_wizard_xpm ),
+ _( "Select the wizard script to load and run" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_PREVIOUS, wxEmptyString,
+ KiBitmap( lib_previous_xpm ),
+ _( "Select previous parameters page" ) );
+
+ m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_NEXT, wxEmptyString,
+ KiBitmap( lib_next_xpm ),
+ _( "Select next parameters page" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_SHOW_3D_VIEW, wxEmptyString,
+ KiBitmap( three_d_xpm ),
+ _( "Show footprint in 3D viewer" ) );
+
+ m_mainToolBar->AddSeparator();
+ msg = AddHotkeyName( _( "Zoom in" ), g_Module_Editor_Hokeys_Descr,
+ HK_ZOOM_IN, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_IN, wxEmptyString,
+ KiBitmap( zoom_in_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Zoom out" ), g_Module_Editor_Hokeys_Descr,
+ HK_ZOOM_OUT, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_OUT, wxEmptyString,
+ KiBitmap( zoom_out_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Redraw view" ), g_Module_Editor_Hokeys_Descr,
+ HK_ZOOM_REDRAW, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_REDRAW, wxEmptyString,
+ KiBitmap( zoom_redraw_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Zoom auto" ), g_Module_Editor_Hokeys_Descr,
+ HK_ZOOM_AUTO, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString,
+ KiBitmap( zoom_fit_in_page_xpm ), msg );
+
+ // The footprint wizard always can export the current footprint
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_FOOTPRINT_WIZARD_DONE,
+ wxEmptyString, KiBitmap( export_footprint_names_xpm ),
+ _( "Export the footprint to the editor" ) );
+
+ // after adding the buttons to the toolbar, must call Realize() to
+ // reflect the changes
+ m_mainToolBar->Realize();
+ }
+
+ m_mainToolBar->Refresh();
+}
+
+
+void FOOTPRINT_WIZARD_FRAME::ReCreateVToolbar()
+{
+ // Currently, there is no vertical toolbar
+}
+
+
+// frame to display messages from footprint builder scripts
+FOOTPRINT_WIZARD_MESSAGES::FOOTPRINT_WIZARD_MESSAGES( FOOTPRINT_WIZARD_FRAME* aParent, wxConfigBase* aCfg ) :
+ wxMiniFrame( aParent, wxID_ANY, _( "Footprint Builder Messages" ),
+ wxDefaultPosition, wxDefaultSize,
+ wxCAPTION | wxRESIZE_BORDER | wxFRAME_FLOAT_ON_PARENT )
+{
+ m_canClose = false;
+ wxBoxSizer* bSizer = new wxBoxSizer( wxVERTICAL );
+ SetSizer( bSizer );
+
+ m_messageWindow = new wxTextCtrl( this, wxID_ANY, wxEmptyString,
+ wxDefaultPosition, wxDefaultSize,
+ wxTE_MULTILINE|wxTE_READONLY );
+ bSizer->Add( m_messageWindow, 1, wxEXPAND, 0 );
+
+ m_config = aCfg;
+
+ LoadSettings();
+
+ SetSize( m_position.x, m_position.y, m_size.x, m_size.y );
+
+ m_messageWindow->SetMinSize( wxSize( 350, 250 ) );
+ Layout();
+
+ bSizer->SetSizeHints( this );
+}
+
+
+FOOTPRINT_WIZARD_MESSAGES::~FOOTPRINT_WIZARD_MESSAGES()
+{
+}
+
+
+BEGIN_EVENT_TABLE( FOOTPRINT_WIZARD_MESSAGES, wxMiniFrame )
+ EVT_CLOSE( FOOTPRINT_WIZARD_MESSAGES::OnCloseMsgWindow )
+END_EVENT_TABLE()
+
+
+void FOOTPRINT_WIZARD_MESSAGES::OnCloseMsgWindow( wxCloseEvent& aEvent )
+{
+ if( !m_canClose )
+ aEvent.Veto();
+ else
+ aEvent.Skip();
+}
+
+
+void FOOTPRINT_WIZARD_MESSAGES::PrintMessage( const wxString& aMessage )
+{
+ m_messageWindow->SetValue( aMessage );
+}
+
+
+void FOOTPRINT_WIZARD_MESSAGES::ClearScreen()
+{
+ m_messageWindow->Clear();
+}
+
+
+#define MESSAGE_BOX_POSX_KEY wxT( "Fpwizard_Msg_PosX" )
+#define MESSAGE_BOX_POSY_KEY wxT( "Fpwizard_Msg_PosY" )
+#define MESSAGE_BOX_SIZEX_KEY wxT( "Fpwizard_Msg_SIZEX" )
+#define MESSAGE_BOX_SIZEY_KEY wxT( "Fpwizard_Msg_SIZEY" )
+
+void FOOTPRINT_WIZARD_MESSAGES::SaveSettings()
+{
+ if( !IsIconized() )
+ {
+ m_position = GetPosition();
+ m_size = GetSize();
+ }
+
+ m_config->Write( MESSAGE_BOX_POSX_KEY, m_position.x );
+ m_config->Write( MESSAGE_BOX_POSY_KEY, m_position.y );
+ m_config->Write( MESSAGE_BOX_SIZEX_KEY, m_size.x );
+ m_config->Write( MESSAGE_BOX_SIZEY_KEY, m_size.y );
+
+ m_canClose = false; // close event now allowed
+}
+
+
+void FOOTPRINT_WIZARD_MESSAGES::LoadSettings()
+{
+ m_config->Read( MESSAGE_BOX_POSX_KEY, &m_position.x, -1 );
+ m_config->Read( MESSAGE_BOX_POSY_KEY, &m_position.y, -1 );
+ m_config->Read( MESSAGE_BOX_SIZEX_KEY, &m_size.x, 350 );
+ m_config->Read( MESSAGE_BOX_SIZEY_KEY, &m_size.y, 250 );
+}
diff --git a/pcbnew/footprint_wizard_frame.h b/pcbnew/footprint_wizard_frame.h
new file mode 100644
index 0000000..a8ca4cb
--- /dev/null
+++ b/pcbnew/footprint_wizard_frame.h
@@ -0,0 +1,230 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Miguel Angel Ajo Pelayo, miguelangel@nbee.es
+ * Copyright (C) 2012 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file footprint_wizard_frame.h
+ */
+
+#ifndef FOOTPRINT_WIZARD_FRAME_H_
+#define FOOTPRINT_WIZARD_FRAME_H_
+
+
+#include <wx/gdicmn.h>
+#include <class_footprint_wizard.h>
+class wxSashLayoutWindow;
+class wxListBox;
+class wxGrid;
+class wxGridEvent;
+class FOOTPRINT_EDIT_FRAME;
+
+// A helper class to display messages when building a footprin
+class FOOTPRINT_WIZARD_MESSAGES;
+
+/**
+ * Class FOOTPRINT_WIZARD_FRAME
+ */
+class FOOTPRINT_WIZARD_FRAME : public PCB_BASE_FRAME
+{
+private:
+ wxListBox* m_pageList; ///< The list of pages
+ int m_pageListWidth; ///< width of the window
+ wxGrid* m_parameterGrid; ///< The list of parameters
+ int m_parameterGridWidth; ///< size of the grid
+ FOOTPRINT_WIZARD_MESSAGES* m_messagesFrame;
+
+ // Column index to display parameters in m_parameterGrid
+ static int m_columnPrmName;
+ static int m_columnPrmValue;
+ static int m_columnPrmUnit;
+
+protected:
+ wxString m_wizardName; ///< name of the current wizard
+ wxString m_wizardDescription; ///< description of the wizard
+ wxString m_wizardStatus; ///< current wizard status
+
+public:
+
+ FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, wxWindow* parent, FRAME_T aFrameType );
+
+ ~FOOTPRINT_WIZARD_FRAME();
+
+ MODULE* GetBuiltFootprint();
+
+private:
+
+ void OnSize( wxSizeEvent& event );
+
+ /**
+ * Function ExportSelectedFootprint();
+ * will let the caller exit from the wait loop, and get the built footprint
+ *
+ */
+ void ExportSelectedFootprint( wxCommandEvent& aEvent );
+
+ /**
+ * Function OnSashDrag
+ * resizes the child windows when dragging a sash window border.
+ */
+
+ void OnSashDrag( wxSashEvent& event );
+
+ /**
+ * Function ReCreatePageList
+ * Creates or recreates the list of parameter pages for the current wizard.
+ * This list is sorted
+ */
+ void ReCreatePageList();
+
+ /**
+ * Function ReCreateParameterList
+ * Creates the list of parameters for the current page
+ */
+ void ReCreateParameterList();
+
+ /**
+ * Function initParameterGrid
+ * Prepare the grid where parameters are displayed
+ */
+ void initParameterGrid();
+
+ /**
+ * Function SelectFootprintWizard
+ * Shows the list of footprint wizards available into the system
+ */
+ void SelectFootprintWizard();
+
+ /**
+ * Function ReloadFootprint
+ * Reloads the current footprint
+ */
+ void ReloadFootprint();
+
+ /**
+ * Function DisplayBuildMessages
+ * Display the message generated by the python build footprint script
+ */
+ void DisplayBuildMessage( wxString& aMessage );
+
+ /**
+ * Function GetMyWizard
+ * Reloads the wizard by name
+ */
+ FOOTPRINT_WIZARD* GetMyWizard();
+
+
+ void Process_Special_Functions( wxCommandEvent& event );
+
+ /**
+ * Function DisplayWizardInfos
+ * Shows all the details about the current wizard
+ */
+ void DisplayWizardInfos();
+
+
+ void RedrawActiveWindow( wxDC* DC, bool EraseBg );
+ void OnCloseWindow( wxCloseEvent& Event );
+ void ReCreateHToolbar();
+ void ReCreateVToolbar();
+ void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
+ void ClickOnPageList( wxCommandEvent& event );
+ void OnSetRelativeOffset( wxCommandEvent& event );
+
+ bool GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey = 0 );
+
+ void LoadSettings( wxConfigBase* aCfg ); // override virtual
+ void SaveSettings( wxConfigBase* aCfg ); // override virtual
+
+ ///> @copydoc EDA_DRAW_FRAME::GetHotKeyDescription()
+ EDA_HOTKEY* GetHotKeyDescription( int ) const { return NULL; }
+
+ /**
+ * Function OnActivate
+ * is called when the frame frame is activate to reload the libraries and component lists
+ * that can be changed by the schematic editor or the library editor.
+ */
+ virtual void OnActivate( wxActivateEvent& event );
+
+ void SelectCurrentWizard( wxCommandEvent& event );
+
+ /**
+ * Function ParametersUpdated
+ * Update the footprint python parameters values from the values in grid
+ */
+ void ParametersUpdated( wxGridEvent& event );
+
+ bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
+
+ /**
+ * Function Show3D_Frame (virtual)
+ * displays 3D view of the footprint (module) being edited.
+ */
+ void Show3D_Frame( wxCommandEvent& event );
+
+ /**
+ * Function Update3D_Frame
+ * must be called after a footprint selection
+ * Updates the 3D view and 3D frame title.
+ * @param aForceReloadFootprint = true to reload data (default)
+ * = false to update title only -(aftre creating the 3D viewer)
+ */
+ void Update3D_Frame( bool aForceReloadFootprint = true );
+
+ /*
+ * Virtual functions, not used here, but needed by PCB_BASE_FRAME
+ * (virtual pure functions )
+ */
+ void OnLeftDClick( wxDC*, const wxPoint& ) {}
+ void SaveCopyInUndoList( BOARD_ITEM*, UNDO_REDO_T, const wxPoint& ) {}
+ void SaveCopyInUndoList( const PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint& ) {}
+
+
+ DECLARE_EVENT_TABLE()
+};
+
+
+// A miniframe to display messages from the builder
+class FOOTPRINT_WIZARD_MESSAGES: public wxMiniFrame
+{
+public:
+ FOOTPRINT_WIZARD_MESSAGES( FOOTPRINT_WIZARD_FRAME* aParent, wxConfigBase* aCfg );
+ ~FOOTPRINT_WIZARD_MESSAGES();
+ void PrintMessage( const wxString& aMessage );
+ void ClearScreen();
+ void SaveSettings();
+ void LoadSettings();
+
+private:
+ wxTextCtrl* m_messageWindow;
+ wxPoint m_position;
+ wxSize m_size;
+ wxConfigBase* m_config;
+ bool m_canClose; // false to veto a close event, true to allow it
+
+ void OnCloseMsgWindow( wxCloseEvent& aEvent );
+
+ DECLARE_EVENT_TABLE()
+};
+
+#endif // FOOTPRINT_WIZARD_FRM_H_
diff --git a/pcbnew/github/CMakeLists.txt b/pcbnew/github/CMakeLists.txt
new file mode 100644
index 0000000..e9c8b9c
--- /dev/null
+++ b/pcbnew/github/CMakeLists.txt
@@ -0,0 +1,50 @@
+# This program source code file is part of KICAD, a free EDA CAD application.
+#
+# Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+# Copyright (C) 2013 Kicad Developers, see AUTHORS.txt for contributors.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, you may find one here:
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# or you may search the http://www.gnu.org website for the version 2 license,
+# or you may write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+
+
+# These are additions to any inherited from pcbnew dir:
+include_directories( . )
+
+include_directories( ${CURL_INCLUDE_DIRS} )
+
+set( GITHUB_PLUGIN_SRCS
+ github_plugin.cpp
+ github_getliblist.cpp
+ html_link_parser.cpp
+ )
+
+add_library( github_plugin STATIC ${GITHUB_PLUGIN_SRCS} )
+
+target_link_libraries( github_plugin
+ common
+ )
+
+if( MINGW )
+ target_link_libraries( github_plugin
+ ${wxWidgets_LIBRARIES}
+ ws2_32
+ )
+endif()
+
+add_dependencies( github_plugin boost )
+
diff --git a/pcbnew/github/avhttp-master.zip b/pcbnew/github/avhttp-master.zip
new file mode 100644
index 0000000..2fa261a
--- /dev/null
+++ b/pcbnew/github/avhttp-master.zip
Binary files differ
diff --git a/pcbnew/github/github_getliblist.cpp b/pcbnew/github/github_getliblist.cpp
new file mode 100644
index 0000000..15c321a
--- /dev/null
+++ b/pcbnew/github/github_getliblist.cpp
@@ -0,0 +1,242 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/*
+ * While creating a wizard to edit the fp lib tables, and mainly the web viewer
+ * which can read the list of pretty library on a github repos, I was told there is
+ * this URL to retrieve info from any particular repo:
+ *
+ * https://api.github.com/orgs/KiCad/repos
+ * or
+ * https://api.github.com/users/KiCad/repos
+ *
+ * This gets just information on the repo in JSON format.
+ *
+ * JP Charras.
+ */
+
+#include <kicad_curl/kicad_curl_easy.h> // Include before any wx file
+#include <wx/uri.h>
+
+#include <github_getliblist.h>
+#include <macros.h>
+#include <common.h>
+#include <html_link_parser.h>
+
+
+GITHUB_GETLIBLIST::GITHUB_GETLIBLIST( const wxString& aRepoURL )
+{
+ m_repoURL = aRepoURL;
+ m_libs_ext = wxT( ".pretty" );
+ strcpy( m_option_string, "application/json" );
+}
+
+
+bool GITHUB_GETLIBLIST::Get3DshapesLibsList( wxArrayString* aList,
+ bool (*aFilter)( const wxString& aData ) )
+{
+ std::string fullURLCommand;
+
+ strcpy( m_option_string, "text/html" );
+
+ wxString repoURL = m_repoURL;
+
+ wxString errorMsg;
+
+ fullURLCommand = repoURL.utf8_str();
+ bool success = remoteGetJSON( fullURLCommand, &errorMsg );
+
+ if( !success )
+ {
+ wxMessageBox( errorMsg );
+ return false;
+ }
+
+ if( aFilter && aList )
+ {
+ //Convert m_image (std::string) to a wxString for HTML_LINK_PARSER
+ wxString buffer( GetBuffer() );
+
+ HTML_LINK_PARSER html_parser( buffer, *aList );
+ html_parser.ParseLinks( aFilter );
+ }
+
+ return true;
+}
+
+
+bool GITHUB_GETLIBLIST::GetFootprintLibraryList( wxArrayString& aList )
+{
+ std::string fullURLCommand;
+ int page = 1;
+ int itemCountMax = 99; // Do not use a valu > 100, it does not work
+
+ strcpy( m_option_string, "application/json" );
+
+ // Github max items returned is 100 per page
+
+ if( !repoURL2listURL( m_repoURL, &fullURLCommand, itemCountMax, page ) )
+ {
+ wxString msg = wxString::Format( _( "malformed URL:\n'%s'" ), GetChars( m_repoURL ) );
+ wxMessageBox( msg );
+ return false;
+ }
+
+ // The URL lib names are relative to the server name.
+ // so add the server name to them.
+ wxURI repo( m_repoURL );
+ wxString urlPrefix = repo.GetScheme() + wxT( "://" ) + repo.GetServer() + wxT( "/" );
+
+ wxString errorMsg;
+ const char sep = ','; // Separator fields, in json returned file
+ wxString tmp;
+ int items_count_per_page = 0;
+ std::string& json_image = GetBuffer();
+
+ while( 1 )
+ {
+ bool success = remoteGetJSON( fullURLCommand, &errorMsg );
+
+ if( !success )
+ {
+ wxMessageBox( errorMsg );
+ return false;
+ }
+
+
+ for( unsigned ii = 0; ii < json_image.size(); ii++ )
+ {
+ if( json_image[ii] == sep || ii == json_image.size() - 1 )
+ {
+ if( tmp.StartsWith( wxT( "\"full_name\"" ) ) )
+ {
+ #define QUOTE '\"'
+ // Remove useless quotes:
+ if( tmp[tmp.Length() - 1] == QUOTE )
+ tmp.RemoveLast();
+
+ if( tmp.EndsWith( m_libs_ext ) )
+ {
+ aList.Add( tmp.AfterLast( ':' ) );
+ int idx = aList.GetCount() - 1;
+
+ if( aList[idx][0] == QUOTE )
+ aList[idx].Remove( 0, 1 );
+
+ aList[idx].Prepend( urlPrefix );
+ }
+
+ items_count_per_page++;
+ }
+
+ tmp.Clear();
+ }
+ else
+ tmp << json_image[ii];
+ }
+
+ if( items_count_per_page >= itemCountMax )
+ {
+ page++;
+ repoURL2listURL( m_repoURL, &fullURLCommand, itemCountMax, page );
+ items_count_per_page = 0;
+ ClearBuffer();
+ }
+ else
+ break;
+ }
+
+ aList.Sort();
+ return true;
+}
+
+
+bool GITHUB_GETLIBLIST::repoURL2listURL( const wxString& aRepoURL,
+ std::string* aFullURLCommand,
+ int aItemCountMax, int aPage )
+{
+ // aListURL is e.g. "https://api.github.com/orgs/KiCad/repos"
+ // or "https://api.github.com/users/KiCad/repos"
+ // aRepoURL is e.g. "https://github.com/KiCad"
+ // Github has a default pagination set to 30 items.
+ // but allows up to 100 items max if we add the "?per_page=100" option
+
+ wxURI repo( aRepoURL );
+
+ if( repo.HasServer() && repo.HasPath() )
+ {
+ // goal: "https://api.github.com/users/KiCad"
+ // or "https://api.github.com/orgs/KiCad"
+ // "https://api.github.com/users/..." works both for orgs and users
+ // if we just retrieve the .pretty list
+ wxString target_url( wxT( "https://api.github.com/users" ) );
+ target_url += repo.GetPath();
+ target_url += wxT( "/repos" );
+
+ // Github has a default pagination set to 30 items.
+ // but allows up to 100 items max. Use this limit
+ target_url += wxString::Format( "?per_page=%d&page=%d", aItemCountMax, aPage );
+
+ *aFullURLCommand = target_url.utf8_str();
+ return true;
+ }
+
+ return false;
+}
+
+
+bool GITHUB_GETLIBLIST::remoteGetJSON( const std::string& aFullURLCommand, wxString* aMsgError )
+{
+ KICAD_CURL_EASY kcurl;
+
+ wxLogDebug( wxT( "Attempting to download: " ) + aFullURLCommand );
+
+ kcurl.SetURL( aFullURLCommand );
+ kcurl.SetUserAgent( "http://kicad-pcb.org" );
+ kcurl.SetHeader( "Accept", m_option_string );
+ kcurl.SetFollowRedirects( true );
+
+ try
+ {
+ kcurl.Perform();
+ m_image = kcurl.GetBuffer();
+ return true;
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ if( aMsgError )
+ {
+ UTF8 fmt( _( "Error fetching JSON data from URL '%s'.\nReason: '%s'" ) );
+
+ std::string msg = StrPrintf( fmt.c_str(),
+ aFullURLCommand.c_str(),
+ TO_UTF8( ioe.errorText ) );
+
+ *aMsgError = FROM_UTF8( msg.c_str() );
+ }
+ return false;
+ }
+}
diff --git a/pcbnew/github/github_getliblist.h b/pcbnew/github/github_getliblist.h
new file mode 100644
index 0000000..0d38b8a
--- /dev/null
+++ b/pcbnew/github/github_getliblist.h
@@ -0,0 +1,124 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras jp.charras at wanadoo.fr
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef GITHUB_GETLIBLIST_H_
+#define GITHUB_GETLIBLIST_H_
+
+
+/**
+ * Class GITHUB_GETLIBLIST
+ * implements a portion of pcbnew's PLUGIN interface to provide read only access
+ * to a github repo to extract pretty footprints library list, in json format,
+ * or extract 3D shapes libraries list (.3dshapes folders) and download the 3d shapes files
+ *
+ * To extract pretty footprints library list, this plugin simply reads in
+ * a zip file of the repo and unzips it from RAM as needed.
+ * Therefore this "Github" plugin is <b>read only for accessing remote
+ * at https://api.github.com/orgs/KiCad/repos</b>
+ *
+ * To extract 3D shapes libraries list (.3dshapes folders) we cannot use api.github.com
+ * to read this list, becuse it is in a subdirectory of https://github.com/KiCad.
+ * The corresponding html page of the server is read, and URLs of all .3dshapes folders
+ * are extracted.
+ * files are then read from https://raw.githubusercontent.com/<lib path>, but not zipped
+ * because they are not accessible in zipped form.
+ */
+class GITHUB_GETLIBLIST
+{
+public:
+ // -----<API>----------------------------------------------------------
+
+ /**
+ * Fills aList by the name of footprint libraries found on the github repo
+ */
+ bool GetFootprintLibraryList( wxArrayString& aList );
+
+ /**
+ * Fills aList by the URL of libraries found on the github repo
+ * @param aList = a reference to a wxArrayString to fill with names
+ * @param aFilter( const wxString& aData ) = a callback funtion to
+ * to filter URLs to put in aList.
+ * If NULL, no URL will be stored in aList
+ */
+ bool Get3DshapesLibsList( wxArrayString* aList,
+ bool (*aFilter)( const wxString& aData ) );
+
+ /**
+ * @return the buffer which stores all the downloaded raw data
+ */
+ std::string& GetBuffer() { return m_image; }
+
+ /**
+ * Clear the buffer which stores all the downloaded raw data
+ */
+ void ClearBuffer() { m_image.clear(); }
+
+ /**
+ * The library names are expecting ending by .pretty
+ * SetLibraryExt set the extension to aExt
+ */
+ void SetLibraryExt( const wxString& aExt ) { m_libs_ext = aExt; }
+
+ // -----</API>---------------------------------------------------------
+
+ GITHUB_GETLIBLIST( const wxString& aRepoURL );
+ ~GITHUB_GETLIBLIST() {}
+
+protected:
+
+ /**
+ * Function repoURL2listURL
+ * translates a repo URL to the URL name which gives the state of repos URL
+ * as commonly seen on github.com
+ *
+ * @param aRepoURL points to the base of the repo.
+ * @param aFullURLCommand is URL the full URL command (URL+options).
+ * @param aItemCountMax is the max item count in a page,
+ * and is 100 for github repo.
+ * @param aPage is the page number, if there are more than one page in repo.
+ * @return bool - true if @a aRepoULR was parseable, else false
+ */
+ bool repoURL2listURL( const wxString& aRepoURL, std::string* aFullURLCommand,
+ int aItemCountMax, int aPage = 1 );
+
+ /**
+ * Function remoteGetJSON
+ * Download a json text from a github repo. The text image
+ * is received into the m_input_stream.
+ * @param aFullURLCommand the full command, i.e. the url with options like
+ * "https://api.github.com/users/KiCad/repos?per_page=100?page=1"
+ * @param aMsgError a pointer to a wxString which can store an error message
+ * @return true if OK, false if error (which an error message in *aMsgError
+ */
+ bool remoteGetJSON( const std::string& aFullURLCommand, wxString* aMsgError );
+
+ wxString m_github_path; ///< Something like https://api.github.com/orgs/KiCad
+ std::string m_image; ///< image of the downloaded data in its entirety.
+ wxString m_repoURL; ///< the URL of the Github repo
+ wxString m_libs_ext; ///< the extension of the name of libraries (default = .pretty)
+ char m_option_string[64]; ///< option for transfert type, like "application/json"
+};
+
+
+#endif // GITHUB_GETLIBLIST_H_
diff --git a/pcbnew/github/github_plugin.cpp b/pcbnew/github/github_plugin.cpp
new file mode 100644
index 0000000..0981083
--- /dev/null
+++ b/pcbnew/github/github_plugin.cpp
@@ -0,0 +1,599 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/*
+
+While exploring the possibility of local caching of the zip file, I discovered
+this command to retrieve the time stamp of the last commit into any particular
+repo:
+
+ $time curl -I -i https://api.github.com/repos/KiCad/Mounting_Holes.pretty/commits
+
+This gets just the header to what would otherwise return information on the repo
+in JSON format, and is reasonably faster than actually getting the repo
+in zip form. However it still takes 5 seconds or more when github is busy, so
+I have lost my enthusiasm for local caching until a faster time stamp retrieval
+mechanism can be found, or github gets more servers. But note that the occasionally
+slow response is the exception rather than the norm. Normally the response is
+down around a 1/3 of a second. The information we would use is in the header
+named "Last-Modified" as seen below.
+
+
+HTTP/1.1 200 OK
+Server: GitHub.com
+Date: Mon, 27 Jan 2014 15:46:46 GMT
+Content-Type: application/json; charset=utf-8
+Status: 200 OK
+X-RateLimit-Limit: 60
+X-RateLimit-Remaining: 49
+X-RateLimit-Reset: 1390839612
+Cache-Control: public, max-age=60, s-maxage=60
+Last-Modified: Mon, 02 Dec 2013 10:08:51 GMT
+ETag: "3d04d760f469f2516a51a56eac63bbd5"
+Vary: Accept
+X-GitHub-Media-Type: github.beta
+X-Content-Type-Options: nosniff
+Content-Length: 6310
+Access-Control-Allow-Credentials: true
+Access-Control-Expose-Headers: ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
+Access-Control-Allow-Origin: *
+X-GitHub-Request-Id: 411087C2:659E:50FD6E6:52E67F66
+Vary: Accept-Encoding
+*/
+
+#include <kicad_curl/kicad_curl_easy.h> // Include before any wx file
+#include <sstream>
+#include <boost/ptr_container/ptr_map.hpp>
+#include <set>
+
+#include <wx/zipstrm.h>
+#include <wx/mstream.h>
+#include <wx/uri.h>
+
+#include <fctsys.h>
+
+#include <io_mgr.h>
+#include <richio.h>
+#include <pcb_parser.h>
+#include <class_board.h>
+#include <github_plugin.h>
+#include <class_module.h>
+#include <macros.h>
+#include <fp_lib_table.h> // ExpandSubstitutions()
+#include <github_getliblist.h>
+
+
+using namespace std;
+
+
+static const char* PRETTY_DIR = "allow_pretty_writing_to_this_dir";
+
+
+typedef boost::ptr_map<string, wxZipEntry> MODULE_MAP;
+typedef MODULE_MAP::iterator MODULE_ITER;
+typedef MODULE_MAP::const_iterator MODULE_CITER;
+
+
+/**
+ * Class GH_CACHE
+ * assists only within GITHUB_PLUGIN and holds a map of footprint name to wxZipEntry
+ */
+struct GH_CACHE : public MODULE_MAP
+{
+ // MODULE_MAP is a boost::ptr_map template, made into a class hereby.
+};
+
+
+GITHUB_PLUGIN::GITHUB_PLUGIN() :
+ PCB_IO(),
+ m_gh_cache( 0 )
+{
+}
+
+
+GITHUB_PLUGIN::~GITHUB_PLUGIN()
+{
+ delete m_gh_cache;
+}
+
+
+const wxString GITHUB_PLUGIN::PluginName() const
+{
+ return "Github";
+}
+
+
+const wxString GITHUB_PLUGIN::GetFileExtension() const
+{
+ return wxEmptyString;
+}
+
+
+wxArrayString GITHUB_PLUGIN::FootprintEnumerate(
+ const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ //D(printf("%s: this:%p aLibraryPath:'%s'\n", __func__, this, TO_UTF8(aLibraryPath) );)
+ cacheLib( aLibraryPath, aProperties );
+
+ typedef std::set<wxString> MYSET;
+
+ MYSET unique;
+
+ if( m_pretty_dir.size() )
+ {
+ wxArrayString locals = PCB_IO::FootprintEnumerate( m_pretty_dir );
+
+ for( unsigned i=0; i<locals.GetCount(); ++i )
+ unique.insert( locals[i] );
+ }
+
+ for( MODULE_ITER it = m_gh_cache->begin(); it!=m_gh_cache->end(); ++it )
+ {
+ unique.insert( FROM_UTF8( it->first.c_str() ) );
+ }
+
+ wxArrayString ret;
+
+ for( MYSET::const_iterator it = unique.begin(); it != unique.end(); ++it )
+ {
+ ret.Add( *it );
+ }
+
+ return ret;
+}
+
+
+MODULE* GITHUB_PLUGIN::FootprintLoad( const wxString& aLibraryPath,
+ const wxString& aFootprintName, const PROPERTIES* aProperties )
+{
+ // D(printf("%s: this:%p aLibraryPath:'%s'\n", __func__, this, TO_UTF8(aLibraryPath) );)
+
+ // clear or set to valid the variable m_pretty_dir
+ cacheLib( aLibraryPath, aProperties );
+
+ if( m_pretty_dir.size() )
+ {
+ // API has FootprintLoad() *not* throwing an exception if footprint not found.
+ MODULE* local = PCB_IO::FootprintLoad( m_pretty_dir, aFootprintName, aProperties );
+
+ if( local )
+ {
+ // It has worked, see <src>/scripts/test_kicad_plugin.py. So this was not firing:
+ // wxASSERT( aFootprintName == FROM_UTF8( local->GetFPID().GetFootprintName().c_str() ) );
+ // Moving it to higher API layer FP_LIB_TABLE::FootprintLoad().
+
+ return local;
+ }
+ }
+
+ UTF8 fp_name = aFootprintName;
+
+ MODULE_CITER it = m_gh_cache->find( fp_name );
+
+ if( it != m_gh_cache->end() ) // fp_name is present
+ {
+ //std::string::data() ensures that the referenced data block is contiguous.
+ wxMemoryInputStream mis( m_zip_image.data(), m_zip_image.size() );
+
+ // This decoder should always be UTF8, since it was saved that way by git.
+ // That is, since pretty footprints are UTF8, and they were pushed to the
+ // github repo, they are still UTF8.
+ wxZipInputStream zis( mis, wxConvUTF8 );
+ wxZipEntry* entry = (wxZipEntry*) it->second; // remove "const"-ness
+
+ if( zis.OpenEntry( *entry ) )
+ {
+ INPUTSTREAM_LINE_READER reader( &zis, aLibraryPath );
+
+ // I am a PCB_IO derivative with my own PCB_PARSER
+ m_parser->SetLineReader( &reader ); // ownership not passed
+
+ MODULE* ret = (MODULE*) m_parser->Parse();
+
+ // In a github library, (as well as in a "KiCad" library) the name of
+ // the pretty file defines the footprint name. That filename trumps
+ // any name found in the pretty file; any name in the pretty file
+ // must be ignored here. Also, the library nickname is unknown in
+ // this context so clear it just in case.
+ ret->SetFPID( fp_name );
+
+ return ret;
+ }
+ }
+
+ return NULL; // this API function returns NULL for "not found", per spec.
+}
+
+
+bool GITHUB_PLUGIN::IsFootprintLibWritable( const wxString& aLibraryPath )
+{
+ if( m_pretty_dir.size() )
+ return PCB_IO::IsFootprintLibWritable( m_pretty_dir );
+ else
+ return false;
+}
+
+
+void GITHUB_PLUGIN::FootprintSave( const wxString& aLibraryPath,
+ const MODULE* aFootprint, const PROPERTIES* aProperties )
+{
+ // set m_pretty_dir to either empty or something in aProperties
+ cacheLib( aLibraryPath, aProperties );
+
+ if( GITHUB_PLUGIN::IsFootprintLibWritable( aLibraryPath ) )
+ {
+ PCB_IO::FootprintSave( m_pretty_dir, aFootprint, aProperties );
+ }
+ else
+ {
+ // This typically will not happen if the caller first properly calls
+ // IsFootprintLibWritable() to determine if calling FootprintSave() is
+ // even legal, so I spend no time on internationalization here:
+
+ string msg = StrPrintf( "Github library\n'%s'\nis only writable if you set option '%s' in Library Tables dialog.",
+ TO_UTF8( aLibraryPath ), PRETTY_DIR );
+
+ THROW_IO_ERROR( msg );
+ }
+}
+
+
+void GITHUB_PLUGIN::FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties )
+{
+ // set m_pretty_dir to either empty or something in aProperties
+ cacheLib( aLibraryPath, aProperties );
+
+ if( GITHUB_PLUGIN::IsFootprintLibWritable( aLibraryPath ) )
+ {
+ // Does the PCB_IO base class have this footprint?
+ // We cannot write to github.
+
+ wxArrayString pretties = PCB_IO::FootprintEnumerate( m_pretty_dir, aProperties );
+
+ if( pretties.Index( aFootprintName ) != wxNOT_FOUND )
+ {
+ PCB_IO::FootprintDelete( m_pretty_dir, aFootprintName, aProperties );
+ }
+ else
+ {
+ wxString msg = wxString::Format(
+ _( "Footprint\n'%s'\nis not in the writable portion of this Github library\n'%s'" ),
+ GetChars( aFootprintName ),
+ GetChars( aLibraryPath )
+ );
+
+ THROW_IO_ERROR( msg );
+ }
+ }
+ else
+ {
+ // This typically will not happen if the caller first properly calls
+ // IsFootprintLibWritable() to determine if calling FootprintSave() is
+ // even legal, so I spend no time on internationalization here:
+
+ string msg = StrPrintf( "Github library\n'%s'\nis only writable if you set option '%s' in Library Tables dialog.",
+ TO_UTF8( aLibraryPath ), PRETTY_DIR );
+
+ THROW_IO_ERROR( msg );
+ }
+}
+
+
+void GITHUB_PLUGIN::FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ // set m_pretty_dir to either empty or something in aProperties
+ cacheLib( aLibraryPath, aProperties );
+
+ if( m_pretty_dir.size() )
+ {
+ PCB_IO::FootprintLibCreate( m_pretty_dir, aProperties );
+ }
+ else
+ {
+ // THROW_IO_ERROR() @todo
+ }
+}
+
+
+bool GITHUB_PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ // set m_pretty_dir to either empty or something in aProperties
+ cacheLib( aLibraryPath, aProperties );
+
+ if( m_pretty_dir.size() )
+ {
+ return PCB_IO::FootprintLibDelete( m_pretty_dir, aProperties );
+ }
+ else
+ {
+ // THROW_IO_ERROR() @todo
+ return false;
+ }
+}
+
+
+void GITHUB_PLUGIN::FootprintLibOptions( PROPERTIES* aListToAppendTo ) const
+{
+ // inherit options supported by all PLUGINs.
+ PLUGIN::FootprintLibOptions( aListToAppendTo );
+
+ (*aListToAppendTo)[ PRETTY_DIR ] = UTF8( _(
+ "Set this property to a directory where footprints are to be written as pretty "
+ "footprints when saving to this library. Anything saved will take precedence over "
+ "footprints by the same name in the github repo. These saved footprints can then "
+ "be sent to the library maintainer as updates. "
+ "<p>The directory <b>must</b> have a <b>.pretty</b> file extension because the "
+ "format of the save is pretty.</p>"
+ ));
+
+ /*
+ (*aListToAppendTo)["cache_github_zip_in_this_dir"] = UTF8( _(
+ "Set this property to a directory where the github *.zip file will be cached. "
+ "This should speed up subsequent visits to this library."
+ ));
+ */
+}
+
+
+void GITHUB_PLUGIN::cacheLib( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ // This is edge triggered based on a change in 'aLibraryPath',
+ // usually it does nothing. When the edge fires, m_pretty_dir is set
+ // to either:
+ // 1) empty or
+ // 2) a verified and validated, writable, *.pretty directory.
+
+ if( !m_gh_cache || m_lib_path != aLibraryPath )
+ {
+ delete m_gh_cache;
+ m_gh_cache = 0;
+
+ m_pretty_dir.clear();
+
+ if( aProperties )
+ {
+ UTF8 pretty_dir;
+
+ if( aProperties->Value( PRETTY_DIR, &pretty_dir ) )
+ {
+ wxString wx_pretty_dir = pretty_dir;
+
+ wx_pretty_dir = FP_LIB_TABLE::ExpandSubstitutions( wx_pretty_dir );
+
+ wxFileName wx_pretty_fn = wx_pretty_dir;
+
+ if( !wx_pretty_fn.IsOk() ||
+ !wx_pretty_fn.IsDirWritable() ||
+ wx_pretty_fn.GetExt() != "pretty"
+ )
+ {
+ wxString msg = wxString::Format(
+ _( "option '%s' for Github library '%s' must point to a writable directory ending with '.pretty'." ),
+ GetChars( FROM_UTF8( PRETTY_DIR ) ),
+ GetChars( aLibraryPath )
+ );
+
+ THROW_IO_ERROR( msg );
+ }
+
+ m_pretty_dir = wx_pretty_dir;
+ }
+ }
+
+ // operator==( wxString, wxChar* ) does not exist, construct wxString once here.
+ const wxString kicad_mod( "kicad_mod" );
+
+ //D(printf("%s: this:%p m_lib_path:'%s' aLibraryPath:'%s'\n", __func__, this, TO_UTF8( m_lib_path), TO_UTF8(aLibraryPath) );)
+ m_gh_cache = new GH_CACHE();
+
+ // INIT_LOGGER( "/tmp", "test.log" );
+ remoteGetZip( aLibraryPath );
+ // UNINIT_LOGGER();
+
+ m_lib_path = aLibraryPath;
+
+ wxMemoryInputStream mis( &m_zip_image[0], m_zip_image.size() );
+
+ // @todo: generalize this name encoding from a PROPERTY (option) later
+ wxZipInputStream zis( mis, wxConvUTF8 );
+
+ wxZipEntry* entry;
+
+ while( ( entry = zis.GetNextEntry() ) != NULL )
+ {
+ wxFileName fn( entry->GetName() ); // chop long name into parts
+
+ if( fn.GetExt() == kicad_mod )
+ {
+ UTF8 fp_name = fn.GetName(); // omit extension & path
+
+ m_gh_cache->insert( fp_name, entry );
+ }
+ else
+ delete entry;
+ }
+ }
+}
+
+
+bool GITHUB_PLUGIN::repoURL_zipURL( const wxString& aRepoURL, std::string* aZipURL )
+{
+ // e.g. "https://github.com/liftoff-sr/pretty_footprints"
+ //D(printf("aRepoURL:%s\n", TO_UTF8( aRepoURL ) );)
+
+ wxURI repo( aRepoURL );
+
+ if( repo.HasServer() && repo.HasPath() )
+ {
+ // scheme might be "http" or if truly github.com then "https".
+ wxString zip_url;
+
+ if( repo.GetServer() == "github.com" )
+ {
+ //codeload.github.com only supports https
+ zip_url = "https://";
+#if 0 // A proper code path would be this one, but it is not the fastest.
+ zip_url += repo.GetServer();
+ zip_url += repo.GetPath(); // path comes with a leading '/'
+ zip_url += "/archive/master.zip";
+#else
+ // Github issues a redirect for the "master.zip". i.e.
+ // "https://github.com/liftoff-sr/pretty_footprints/archive/master.zip"
+ // would be redirected to:
+ // "https://codeload.github.com/liftoff-sr/pretty_footprints/zip/master"
+
+ // In order to bypass this redirect, saving time, we use the
+ // redirected URL on first attempt to save one HTTP GET hit.
+ zip_url += "codeload.github.com";
+ zip_url += repo.GetPath(); // path comes with a leading '/'
+ zip_url += "/zip/master";
+#endif
+ }
+
+ else
+ {
+ zip_url = repo.GetScheme();
+ zip_url += "://";
+
+ // This is the generic code path for any server which can serve
+ // up zip files. The schemes tested include: http and https.
+
+ // zip_url goal: "<scheme>://<server>[:<port>]/<path>"
+
+ // Remember that <scheme>, <server>, <port> if present, and <path> all came
+ // from the lib_path in the fp-lib-table row.
+
+ // This code path is used with the nginx proxy setup, but is useful
+ // beyond that.
+
+ zip_url += repo.GetServer();
+
+ if( repo.HasPort() )
+ {
+ zip_url += ':';
+ zip_url += repo.GetPort();
+ }
+
+ zip_url += repo.GetPath(); // path comes with a leading '/'
+
+ // Do not modify the path, we cannot anticipate the needs of all
+ // servers which are serving up zip files directly. URL modifications
+ // are more generally done in the server, rather than contaminating
+ // this code path with the needs of one particular inflexible server.
+ }
+
+ *aZipURL = zip_url.utf8_str();
+ return true;
+ }
+ return false;
+}
+
+
+void GITHUB_PLUGIN::remoteGetZip( const wxString& aRepoURL ) throw( IO_ERROR )
+{
+ std::string zip_url;
+
+ if( !repoURL_zipURL( aRepoURL, &zip_url ) )
+ {
+ wxString msg = wxString::Format( _( "Unable to parse URL:\n'%s'" ), GetChars( aRepoURL ) );
+ THROW_IO_ERROR( msg );
+ }
+
+ wxLogDebug( wxT( "Attempting to download: " ) + zip_url );
+
+ KICAD_CURL_EASY kcurl; // this can THROW_IO_ERROR
+
+ kcurl.SetURL( zip_url.c_str() );
+ kcurl.SetUserAgent( "http://kicad-pcb.org" );
+ kcurl.SetHeader( "Accept", "application/zip" );
+ kcurl.SetFollowRedirects( true );
+
+ try
+ {
+ kcurl.Perform();
+ m_zip_image = kcurl.GetBuffer();
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ // https "GET" has failed, report this to API caller.
+ // Note: kcurl.Perform() does not return an error if the file to download is not found
+ static const char errorcmd[] = "http GET command failed"; // Do not translate this message
+
+ UTF8 fmt( _( "%s\nCannot get/download Zip archive: '%s'\nfor library path: '%s'.\nReason: '%s'" ) );
+
+ std::string msg = StrPrintf( fmt.c_str(),
+ errorcmd,
+ zip_url.c_str(),
+ TO_UTF8( aRepoURL ),
+ TO_UTF8( ioe.errorText )
+ );
+
+ THROW_IO_ERROR( msg );
+ }
+
+ // If the zip archive is not existing, the received data is "Not Found" or "404: Not Found",
+ // and no error is returned by kcurl.Perform().
+ if( ( m_zip_image.compare( 0, 9, "Not Found", 9 ) == 0 ) ||
+ ( m_zip_image.compare( 0, 14, "404: Not Found", 14 ) == 0 ) )
+ {
+ UTF8 fmt( _( "Cannot download library '%s'.\nThe library does not exist on the server" ) );
+ std::string msg = StrPrintf( fmt.c_str(), TO_UTF8( aRepoURL ) );
+
+ THROW_IO_ERROR( msg );
+ }
+}
+
+#if 0 && defined(STANDALONE)
+
+int main( int argc, char** argv )
+{
+ INIT_LOGGER( ".", "test.log" );
+
+ GITHUB_PLUGIN gh;
+
+ try
+ {
+ wxArrayString fps = gh.FootprintEnumerate(
+ "https://github.com/liftoff-sr/pretty_footprints",
+ NULL
+ );
+
+ for( int i=0; i<(int)fps.Count(); ++i )
+ {
+ printf("[%d]:%s\n", i, TO_UTF8( fps[i] ) );
+ }
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ printf( "%s\n", TO_UTF8(ioe.errorText) );
+ }
+
+ UNINIT_LOGGER();
+
+ return 0;
+}
+
+#endif
diff --git a/pcbnew/github/github_plugin.h b/pcbnew/github/github_plugin.h
new file mode 100644
index 0000000..92f2c13
--- /dev/null
+++ b/pcbnew/github/github_plugin.h
@@ -0,0 +1,229 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef GITHUB_PLUGIN_H_
+#define GITHUB_PLUGIN_H_
+
+#include <kicad_plugin.h>
+
+struct GH_CACHE;
+
+
+/**
+ Class GITHUB_PLUGIN
+ implements a portion of pcbnew's PLUGIN interface to provide read only access
+ to a github repo consisting of pretty footprints, and optionally provides "Copy On Write"
+ support of edited footprints.
+
+ <p>It could have used version 3 of the github.com API documented here:
+
+ <pre>
+ http://developer.github.com/v3/
+ https://help.github.com/articles/creating-an-access-token-for-command-line-use
+ </pre>
+
+ but it does not, since a better technique was discovered. Cleverly this
+ plugin simply reads in a zip file of the repo and unzips it from RAM as
+ needed. Therefore this "Github" plugin is <b>read only for accessing remote
+ pretty libraries at https://github.com.</b>
+
+ <p>The fp-lib-table dialog is entered via menu choice "Preferences | Library
+ Tables". For easy options editing in the current row, click on the "Edit
+ Options" button. The "Library Path" in the fp-lib-table row for a Github
+ library should be set to the full https:// URL.
+
+ <p>For example:
+
+ <pre>
+ https://github.com/liftoff-sr/pretty_footprints
+ </pre>
+
+ This is typically
+
+ <pre>
+ https://github.com/user_name/repo_name
+ </pre>
+ <p>
+
+ The "Plugin Type" should be set to "Github".
+
+ <p>This plugin also supports "Copy On Write", a.k.a. "COW". Thus a Github
+ library may take an optional option called
+ <b>allow_pretty_writing_to_this_dir</b>. This option is essentially the
+ "Library Path" for a local "KiCad" (pretty) type library which is combined to
+ make up the Github library found in the same fp-lib-table row. If the option
+ is missing, then the Github library is read only as always. If the option is
+ present for a Github library, then any writes to this hybrid library will go
+ to the local *.pretty directory. Note that the github.com resident portion of
+ this hybrid COW library is always read only, meaning you cannot delete
+ anything or modify any footprint at github directly. The aggregate library
+ type remains "Github" in your discussions, but it consists of a local R/W
+ portion and a remote R/O portion.
+
+ <p>Below is an fp-lib-table entry for the case without option
+ <b>allow_pretty_writing_to_this_dir</b>:
+
+ <table>
+ <tr>
+ <th>Nickname</th><th>Library Path</th><th>Plugin Type</th><th>Options</th><th>Description</th>
+ </tr>
+
+ <tr>
+ <td>github</td><td>https://github.com/liftoff-sr/pretty_footprints</td><td>Github</td>
+ <td></td><td>Liftoff's GH footprints</td>
+ </tr>
+ </table>
+
+ Below is an fp-lib-table entry with the COW option given. Note the use of the environment variable
+ ${HOME}, as an example only. The github.pretty directory is based in ${HOME}/pretty/. Anytime you
+ use option allow_pretty_writing_to_this_dir, you will create that directory manually and it must
+ end in extension <b>.pretty</b>.
+
+ <table>
+ <tr>
+ <th>Nickname</th><th>Library Path</th><th>Plugin Type</th><th>Options</th><th>Description</th>
+ </tr>
+
+ <tr>
+
+ <td>github</td><td>https://github.com/liftoff-sr/pretty_footprints</td><td>Github</td>
+ <td>allow_pretty_writing_to_this_dir=${HOME}/pretty/github.pretty</td>
+ <td>Liftoff's GH footprints</td>
+ </tr>
+ </table>
+
+ <p>Any footprint loads will always give precedence to the local footprints
+ found in the pretty dir given by option
+ <b>allow_pretty_writing_to_this_dir</b>. So once you have written to the COW
+ library's local directory by doing a footprint save, no github updates will
+ be seen when loading a footprint by the same name as one for which you've
+ written locally.
+
+ <p>Always keep a separate local *.pretty directory for each Github library,
+ never combine them by referring to the same directory more than once. Also,
+ do not also use the same COW (*.pretty) directory in a "KiCad" fp-lib-table
+ entry. This would likely create a mess. The COW directory should be manually
+ created in advance, and the directory name must end with ".pretty". The value
+ of the option <b>allow_pretty_writing_to_this_dir</b> will be path
+ substituted with any environment variable strings embedded, just like the
+ "Library Path" is.
+
+ <p>What's the point of COW? It is to turbo-charge the sharing of footprints.
+ If you periodically email your COW pretty footprint modifications to the
+ Github repo maintainer, you can help update the Github copy. Simply email the
+ individual *.kicad_mod files you find in your COW directories. After you've
+ received confirmation that your changes have been committed up at github.com,
+ you can safely delete your COW file(s) and those from github.com will flow
+ down. Your goal should be to keep the COW file set as small as possible by
+ contributing frequently to the shared master copies at https://github.com.
+
+ <p>Note that if you use the module editor to delete a footprint and it is
+ present in the COW local dir, it will get deleted from there. However, it may
+ not be deleted from the library as a whole if the footprint of the same name
+ also exists in the github repo. In this case deleting the local copy will
+ simply unmask the one at the github repo. Remember, it is masked out if there
+ is a local COW copy, since the local copy always takes precedence. And
+ remember you cannot modify the github copy except by emailing a COW
+ modification to the repo maintainer.
+
+ <p>If you happen to be the repo maintainer, then the obvious solution for you
+ is to make your COW directory <b>be</b> your working copy directory. From
+ there you can push to github. And you can receive *.kicad_mod files by email
+ and put them into your local working copy directory also and do diffs,
+ reverting or denying when appropriate, editing when appropriate before
+ pushing or denying the change. Ultimately you would owe the sender either a
+ note of acceptance or denial by email.
+
+ @author Dick Hollenbeck
+ @date Original date: 10-Sep-2013
+
+ */
+class GITHUB_PLUGIN : public PCB_IO
+{
+public:
+ //-----<PLUGIN API>----------------------------------------------------------
+ const wxString PluginName() const;
+
+ const wxString GetFileExtension() const;
+
+ wxArrayString FootprintEnumerate( const wxString& aLibraryPath,
+ const PROPERTIES* aProperties = NULL );
+
+ MODULE* FootprintLoad( const wxString& aLibraryPath,
+ const wxString& aFootprintName, const PROPERTIES* aProperties );
+
+ void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint,
+ const PROPERTIES* aProperties = NULL );
+
+ void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties = NULL );
+
+ bool IsFootprintLibWritable( const wxString& aLibraryPath );
+
+ void FootprintLibOptions( PROPERTIES* aListToAppendTo ) const;
+
+ // Since I derive from PCB_IO, I have to implement this, else I'd inherit his, which is bad since
+ // my lib_path is not his. Note: it is impossible to create a Github library, but can the C.O.W. portion.
+ void FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties );
+
+ // Since I derive from PCB_IO, I have to implement this, else I'd inherit his, which is bad since
+ // my lib_path is not his. Note: it is impossible to delete a Github library, but can the C.O.W portion.
+ bool FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties );
+
+ //-----</PLUGIN API>---------------------------------------------------------
+
+ GITHUB_PLUGIN(); // constructor, if any, must be zero arg
+ ~GITHUB_PLUGIN();
+
+protected:
+
+ void init( const PROPERTIES* aProperties );
+
+ void cacheLib( const wxString& aLibraryPath, const PROPERTIES* aProperties );
+
+ /**
+ * Function repoURL_zipURL
+ * translates a repo URL to a zipfile URL name as commonly seen on github.com
+ *
+ * @param aRepoURL points to the base of the repo.
+ * @param aZipURL is where to put the zip file URL.
+ * @return bool - true if @a aRepoULR was parseable, else false
+ */
+ static bool repoURL_zipURL( const wxString& aRepoURL, std::string* aZipURL );
+
+ /**
+ * Function remoteGetZip
+ * fetches a zip file image from a github repo synchronously. The byte image
+ * is received into the m_input_stream.
+ */
+ void remoteGetZip( const wxString& aRepoURL ) throw( IO_ERROR );
+
+ wxString m_lib_path; ///< from aLibraryPath, something like https://github.com/liftoff-sr/pretty_footprints
+ std::string m_zip_image; ///< byte image of the zip file in its entirety.
+ GH_CACHE* m_gh_cache;
+ wxString m_pretty_dir;
+};
+
+
+#endif // GITHUB_PLUGIN_H_
diff --git a/pcbnew/github/html_link_parser.cpp b/pcbnew/github/html_link_parser.cpp
new file mode 100644
index 0000000..b548b67
--- /dev/null
+++ b/pcbnew/github/html_link_parser.cpp
@@ -0,0 +1,69 @@
+/**
+ * @file html_link_parse.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * wxWidgets gives very few info about wxwebkit. For more info and more comments:
+ * see https://forums.wxwidgets.org/viewtopic.php?f=1&t=1119#
+ */
+
+#include <html_link_parser.h>
+
+bool LINK_TAGHANDLER::HandleTag(const wxHtmlTag& tag)
+{
+ if( tag.HasParam( wxT("HREF") ) )
+ {
+ wxString href( tag.GetParam( wxT("HREF") ) );
+ // Add the first parameter (the link)
+ m_Parser->AddString( href );
+ // Parse other params, but do nothing, because the AddText() callback
+ // do nothing
+ ParseInner(tag);
+ return true;
+ }
+ else
+ return false;
+}
+
+HTML_LINK_PARSER::HTML_LINK_PARSER( const wxString& aSrc, wxArrayString& aUrls )
+ : m_src( aSrc ), stringUrls( aUrls )
+{
+ m_filter = NULL;
+ AddTagHandler( new LINK_TAGHANDLER(this) );
+}
+
+
+void HTML_LINK_PARSER::AddString( const wxString& aText )
+{
+ wxString text = aText;
+ text.Trim( true );
+ text.Trim( false );
+
+ if( ! m_filter || m_filter( text ) )
+ {
+ stringUrls.Add( text );
+ }
+}
diff --git a/pcbnew/github/html_link_parser.h b/pcbnew/github/html_link_parser.h
new file mode 100644
index 0000000..c18c27e
--- /dev/null
+++ b/pcbnew/github/html_link_parser.h
@@ -0,0 +1,109 @@
+/**
+ * @file html_link_parse.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * wxWidgets gives very few info about wxwebkit. For more info and more comments:
+ * see https://forums.wxwidgets.org/viewtopic.php?f=1&t=1119#
+ */
+
+#ifndef HTML_LINK_PARSE_H
+#define HTML_LINK_PARSE_H
+
+
+#include <wx/wx.h>
+#include <wx/html/htmlpars.h>
+
+class HTML_LINK_PARSER ;
+
+/**
+ * a Tag parser, to extract tagged data in html text.
+ * this tag handler extract a url link, givent by tag "A"
+ * like:
+ * "<a href="/KiCad/Valves.pretty" itemprop="name codeRepository"> Valves.pretty</a>"
+ * the tag is "a"
+ * and the link is the parameter given by "href"
+ */
+class LINK_TAGHANDLER : public wxHtmlTagHandler
+{
+ HTML_LINK_PARSER* m_Parser;
+
+public:
+ LINK_TAGHANDLER() : m_Parser( NULL )
+ {
+ }
+
+ LINK_TAGHANDLER( HTML_LINK_PARSER* aParser ) : m_Parser( aParser )
+ {
+ }
+
+ wxString GetSupportedTags()
+ {
+ return "A";
+ }
+
+ bool HandleTag(const wxHtmlTag& tag);
+};
+
+/**
+ * The engine to parse a html text and extract useful data
+ * Here, the useful data are url links
+ */
+class HTML_LINK_PARSER : public wxHtmlParser
+{
+ const wxString& m_src; // the html text to parse
+ wxArrayString& stringUrls; // the strings extracted from html text
+ bool (*m_filter)( const wxString& aData ); // a callback function to filter strings
+
+public:
+
+ HTML_LINK_PARSER( const wxString& aSrc, wxArrayString& aUrls );
+
+ /**
+ * Parse the html text and store links in stringUrls
+ * Stored links can be filtered if aFilter is non NULL
+ * @param aFilter a filtering function ( bool aFilter( const wxString& aData ) )
+ * which return true if the text aData must be stored.
+ */
+ void ParseLinks( bool (*aFilter)( const wxString& aData ) )
+ {
+ m_filter = aFilter;
+ Parse(m_src);
+ }
+
+ // virtual pure from wxHtmlParser, do nothing here, but needed.
+ void AddText( const wxString& aText ){}
+
+ // Our "AddText" used to store selected text (the url link)
+ void AddString( const wxString& aText );
+
+ wxObject* GetProduct()
+ {
+ return NULL;
+ }
+};
+
+#endif // ifndef HTML_LINK_PARSE_H
diff --git a/pcbnew/github/nginx.conf b/pcbnew/github/nginx.conf
new file mode 100644
index 0000000..24f3320
--- /dev/null
+++ b/pcbnew/github/nginx.conf
@@ -0,0 +1,64 @@
+# Author: <Dick Hollenbeck> dick@softplc.com
+# Configuration file for nginx. Nginx works as a nice cache-ing proxy for
+# the github footprint repos in a local nginx instance.
+
+
+# In my case I also added a small RAM disk on a linux server to hold the cache.
+# This line in /etc/fstab adds my RAM disk, this is 10 mbytes but 5mb would
+# probably suffice:
+none /var/cache/nginx tmpfs size=10m
+
+# I then set my KIGITHUB environment variable to
+# export KIGITHUB=http://my_server:54321/KiCad
+
+# Note that http is used between kicad and nginx, not https. However nginx uses
+# https when refreshing from github. http is faster than https.
+
+# You can run nginx either on your local machine, or on a server on your network,
+# or a server on the Internet. In my case I run it on my network. I imagine
+# that even a Raspery Pi would act as a decent caching server so long as you
+# install nginx and give the machine Internet access.
+
+
+worker_processes 2;
+
+events {
+ worker_connections 1024;
+}
+
+
+http {
+ proxy_cache_path /var/cache/nginx keys_zone=cache_zone:10m;
+
+ server {
+ # nginx will listen on this port:
+ listen 54321;
+
+ proxy_cache cache_zone;
+
+ # hold the stuff for one week, then mark it as out of date which will
+ # cause it to be reloaded from github.
+ proxy_cache_valid 1w;
+
+ location /KiCad/ {
+ rewrite /KiCad/(.+) /KiCad/$1/zip/master break;
+
+ # Skip past the redirect issued by https://github.com
+ proxy_pass https://codeload.github.com;
+
+ proxy_set_header Proxy-Connection "Keep-Alive";
+
+ proxy_ignore_headers "Set-Cookie";
+ proxy_ignore_headers "Cache-Control";
+ proxy_ignore_headers "Expires";
+
+ proxy_cache_bypass $http_secret_header;
+
+ add_header X-Cache-Status $upstream_cache_status;
+
+ # This line causes github.com to return a "502 Bad Gateway Error"
+ # so do not include it:
+ # proxy_set_header Host $http_host;
+ }
+ }
+}
diff --git a/pcbnew/globaleditpad.cpp b/pcbnew/globaleditpad.cpp
new file mode 100644
index 0000000..3f5cfb5
--- /dev/null
+++ b/pcbnew/globaleditpad.cpp
@@ -0,0 +1,387 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009-2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file globaleditpad.cpp
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <module_editor_frame.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <pcbnew.h>
+#include <dialog_global_pads_edition_base.h>
+
+
+/************************************/
+/* class DIALOG_GLOBAL_PADS_EDITION */
+/************************************/
+
+class DIALOG_GLOBAL_PADS_EDITION : public DIALOG_GLOBAL_PADS_EDITION_BASE
+{
+private:
+ PCB_BASE_FRAME* m_parent;
+ D_PAD* m_currentPad;
+
+public:
+ static bool m_Pad_Shape_Filter;
+ static bool m_Pad_Layer_Filter;
+ static bool m_Pad_Orient_Filter;
+
+public:
+ DIALOG_GLOBAL_PADS_EDITION( PCB_BASE_FRAME* aParent, D_PAD* aPad );
+
+private:
+ void InstallPadEditor( wxCommandEvent& event );
+ void PadPropertiesAccept( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+};
+
+
+DIALOG_GLOBAL_PADS_EDITION::DIALOG_GLOBAL_PADS_EDITION( PCB_BASE_FRAME* aParent, D_PAD* aPad ) :
+ DIALOG_GLOBAL_PADS_EDITION_BASE( aParent )
+{
+ m_parent = aParent;
+ m_currentPad = aPad;
+
+ // Pad filter selection.
+ m_Pad_Shape_Filter_CB->SetValue( m_Pad_Shape_Filter );
+ m_Pad_Layer_Filter_CB->SetValue( m_Pad_Layer_Filter );
+ m_Pad_Orient_Filter_CB->SetValue( m_Pad_Orient_Filter );
+
+ SetFocus();
+
+ GetSizer()->Fit( this );
+ Centre();
+}
+
+
+// Class DIALOG_GLOBAL_PADS_EDITION static variables
+bool DIALOG_GLOBAL_PADS_EDITION::m_Pad_Shape_Filter = true;
+bool DIALOG_GLOBAL_PADS_EDITION::m_Pad_Layer_Filter = true;
+bool DIALOG_GLOBAL_PADS_EDITION::m_Pad_Orient_Filter = true;
+
+
+void DIALOG_GLOBAL_PADS_EDITION::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( -1 );
+}
+
+
+/* Calls the Pad editor.
+ */
+void DIALOG_GLOBAL_PADS_EDITION::InstallPadEditor( wxCommandEvent& event )
+{
+ m_parent->InstallPadOptionsFrame( m_currentPad );
+}
+
+
+/* Update the parameters for the component being edited.
+ */
+void DIALOG_GLOBAL_PADS_EDITION::PadPropertiesAccept( wxCommandEvent& event )
+{
+ int returncode = 0;
+
+ switch( event.GetId() )
+ {
+ case ID_CHANGE_ID_MODULES:
+ returncode = 1;
+
+ // Fall through
+
+ case ID_CHANGE_CURRENT_MODULE:
+ m_Pad_Shape_Filter = m_Pad_Shape_Filter_CB->GetValue();
+ m_Pad_Layer_Filter = m_Pad_Layer_Filter_CB->GetValue();
+ m_Pad_Orient_Filter = m_Pad_Orient_Filter_CB->GetValue();
+ EndModal( returncode );
+ break;
+ }
+
+ m_parent->OnModify();
+}
+
+
+/*
+ * PCB_EDIT_FRAME::Function DlgGlobalChange_PadSettings
+ * Function to change pad caracteristics for the given footprint
+ * or alls footprints which look like the given footprint
+ * Options are set by the opened dialog.
+ * aPad is the pattern. The given footprint is the parent of this pad
+ * aRedraw: if true: redraws the footprint
+ */
+void PCB_EDIT_FRAME::DlgGlobalChange_PadSettings( D_PAD* aPad, bool aRedraw )
+{
+ int diag;
+
+ if( aPad == NULL )
+ aPad = &GetDesignSettings().m_Pad_Master;
+
+ MODULE* module = aPad->GetParent();
+
+ if( module == NULL )
+ {
+ DisplayError( this, wxT( "Global_Import_Pad_Settings() Error: NULL module" ) );
+ return;
+ }
+
+ SetMsgPanel( module );
+
+ {
+ DIALOG_GLOBAL_PADS_EDITION dlg( this, aPad );
+
+ diag = dlg.ShowModal();
+ }
+
+ if( diag == -1 )
+ return;
+
+ bool edit_Same_Modules = false;
+ if( diag == 1 )
+ edit_Same_Modules = true;
+
+ GlobalChange_PadSettings( aPad,edit_Same_Modules,
+ DIALOG_GLOBAL_PADS_EDITION::m_Pad_Shape_Filter,
+ DIALOG_GLOBAL_PADS_EDITION::m_Pad_Orient_Filter,
+ DIALOG_GLOBAL_PADS_EDITION::m_Pad_Layer_Filter,
+ aRedraw, true );
+}
+
+/*
+ * FOOTPRINT_EDIT_FRAME::Function DlgGlobalChange_PadSettings
+ * Function to change pad caracteristics for the given footprint
+ * or alls footprints which look like the given footprint
+ * Options are set by the opened dialog.
+ * aPad is the pattern. The given footprint is the parent of this pad
+ */
+void FOOTPRINT_EDIT_FRAME::DlgGlobalChange_PadSettings( D_PAD* aPad )
+{
+ int diag;
+
+ if( aPad == NULL )
+ aPad = &GetDesignSettings().m_Pad_Master;
+
+ MODULE* module = aPad->GetParent();
+
+ if( module == NULL )
+ {
+ DisplayError( this, wxT( "Global_Import_Pad_Settings() Error: NULL module" ) );
+ return;
+ }
+
+ SetMsgPanel( module );
+
+ {
+ DIALOG_GLOBAL_PADS_EDITION dlg( this, aPad );
+
+ dlg.m_buttonIdModules->Enable( false );
+
+ diag = dlg.ShowModal();
+ }
+
+ if( diag == -1 )
+ return;
+
+ bool edit_Same_Modules = false;
+ if( diag == 1 )
+ edit_Same_Modules = true;
+
+ GlobalChange_PadSettings( aPad, edit_Same_Modules,
+ DIALOG_GLOBAL_PADS_EDITION::m_Pad_Shape_Filter,
+ DIALOG_GLOBAL_PADS_EDITION::m_Pad_Orient_Filter,
+ DIALOG_GLOBAL_PADS_EDITION::m_Pad_Layer_Filter,
+ true, false );
+}
+
+/*
+ * Function GlobalChange_PadSettings
+ * Function to change pad caracteristics for the given footprint
+ * or alls footprints which look like the given footprint
+ * aPad is the pattern. The given footprint is the parent of this pad
+ * aSameFootprints: if true, make changes on all identical footprints
+ * aPadShapeFilter: if true, make changes only on pads having the same shape as aPad
+ * aPadOrientFilter: if true, make changes only on pads having the same orientation as aPad
+ * aPadLayerFilter: if true, make changes only on pads having the same layers as aPad
+ * aRedraw: if true: redraws the footprint
+ * aSaveForUndo: if true: create an entry in the Undo/Redo list
+ * (usually: true in Schematic editor, false in Module editor)
+ */
+void PCB_BASE_FRAME::GlobalChange_PadSettings( D_PAD* aPad,
+ bool aSameFootprints,
+ bool aPadShapeFilter,
+ bool aPadOrientFilter,
+ bool aPadLayerFilter,
+ bool aRedraw, bool aSaveForUndo )
+{
+ if( aPad == NULL )
+ aPad = &GetDesignSettings().m_Pad_Master;
+
+ MODULE* module = aPad->GetParent();
+
+ if( module == NULL )
+ {
+ DisplayError( this, wxT( "Global_Import_Pad_Settings() Error: NULL module" ) );
+ return;
+ }
+
+ // Search and copy the name of library reference.
+ MODULE* Module_Ref = module;
+ double pad_orient = aPad->GetOrientation() - Module_Ref->GetOrientation();
+
+ // Prepare an undo list:
+ if( aSaveForUndo )
+ {
+ PICKED_ITEMS_LIST itemsList;
+
+ for( module = m_Pcb->m_Modules; module; module = module->Next() )
+ {
+ if( !aSameFootprints && (module != Module_Ref) )
+ continue;
+
+ if( module->GetFPID() != Module_Ref->GetFPID() )
+ continue;
+
+ bool saveMe = false;
+
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ // Filters changes prohibited.
+ if( aPadShapeFilter && ( pad->GetShape() != aPad->GetShape() ) )
+ continue;
+
+ double currpad_orient = pad->GetOrientation() - module->GetOrientation();
+
+ if( aPadOrientFilter && ( currpad_orient != pad_orient ) )
+ continue;
+
+ if( aPadLayerFilter && pad->GetLayerSet() != aPad->GetLayerSet() )
+ continue;
+
+ saveMe = true;
+ }
+
+ if( saveMe )
+ {
+ ITEM_PICKER itemWrapper( module, UR_CHANGED );
+
+ itemsList.PushItem( itemWrapper );
+ }
+ }
+
+ SaveCopyInUndoList( itemsList, UR_CHANGED );
+ }
+
+ // Update the current module and same others modules if requested.
+ for( module = m_Pcb->m_Modules; module; module = module->Next() )
+ {
+ if( !aSameFootprints && (module != Module_Ref) )
+ continue;
+
+ if( module->GetFPID() != Module_Ref->GetFPID() )
+ continue;
+
+ // Erase module on screen
+ if( aRedraw )
+ {
+ module->SetFlags( DO_NOT_DRAW );
+ m_canvas->RefreshDrawingRect( module->GetBoundingBox() );
+ module->ClearFlags( DO_NOT_DRAW );
+ }
+
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ // Filters changes prohibited.
+ if( aPadShapeFilter && ( pad->GetShape() != aPad->GetShape() ) )
+ continue;
+
+ if( aPadOrientFilter && (pad->GetOrientation() - module->GetOrientation()) != pad_orient )
+ continue;
+
+ if( aPadLayerFilter )
+ {
+ if( pad->GetLayerSet() != aPad->GetLayerSet() )
+ continue;
+ else
+ m_Pcb->m_Status_Pcb &= ~( LISTE_RATSNEST_ITEM_OK | CONNEXION_OK);
+ }
+
+ // Change characteristics:
+ pad->SetAttribute( aPad->GetAttribute() );
+ pad->SetShape( aPad->GetShape() );
+
+ pad->SetLayerSet( aPad->GetLayerSet() );
+
+ pad->SetSize( aPad->GetSize() );
+ pad->SetDelta( aPad->GetDelta() );
+ pad->SetOffset( aPad->GetOffset() );
+
+ pad->SetDrillSize( aPad->GetDrillSize() );
+ pad->SetDrillShape( aPad->GetDrillShape() );
+
+ pad->SetOrientation( pad_orient + module->GetOrientation() );
+
+ // copy also local mask margins, because these parameters usually depend on
+ // pad sizes and layers
+ pad->SetLocalSolderMaskMargin( aPad->GetLocalSolderMaskMargin() );
+ pad->SetLocalSolderPasteMargin( aPad->GetLocalSolderPasteMargin() );
+ pad->SetLocalSolderPasteMarginRatio( aPad->GetLocalSolderPasteMarginRatio() );
+
+ if( pad->GetShape() != PAD_SHAPE_TRAPEZOID )
+ {
+ pad->SetDelta( wxSize( 0, 0 ) );
+ }
+
+ if( pad->GetShape() == PAD_SHAPE_CIRCLE )
+ {
+ // Ensure pad size.y = pad size.x
+ int size = pad->GetSize().x;
+ pad->SetSize( wxSize( size, size ) );
+ }
+
+ switch( pad->GetAttribute() )
+ {
+ case PAD_ATTRIB_SMD:
+ case PAD_ATTRIB_CONN:
+ pad->SetDrillSize( wxSize( 0, 0 ) );
+ pad->SetOffset( wxPoint( 0, 0 ) );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ module->CalculateBoundingBox();
+
+ if( aRedraw )
+ m_canvas->RefreshDrawingRect( module->GetBoundingBox() );
+ }
+
+ OnModify();
+}
diff --git a/pcbnew/gpcb_plugin.cpp b/pcbnew/gpcb_plugin.cpp
new file mode 100644
index 0000000..0e7df9b
--- /dev/null
+++ b/pcbnew/gpcb_plugin.cpp
@@ -0,0 +1,1127 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file gpcb_plugin.cpp
+ * @brief Geda PCB file plugin implementation file.
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <macros.h>
+#include <trigo.h>
+#include <wildcards_and_files_ext.h>
+#include <filter_reader.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_pcb_text.h>
+#include <class_drawsegment.h>
+#include <class_edge_mod.h>
+#include <gpcb_plugin.h>
+
+#include <wx/dir.h>
+#include <wx/filename.h>
+#include <wx/wfstream.h>
+#include <boost/ptr_container/ptr_map.hpp>
+#include <memory.h>
+
+/**
+ * Definition for enabling and disabling footprint library trace output. See the
+ * wxWidgets documentation on using the WXTRACE environment variable.
+ */
+static const wxString traceFootprintLibrary( wxT( "GedaPcbFootprintLib" ) );
+
+
+static const char delims[] = " \t\r\n";
+
+static bool inline isSpace( int c ) { return strchr( delims, c ) != 0; }
+
+static void inline traceParams( wxArrayString& aParams )
+{
+ wxString tmp;
+
+ for( unsigned i = 0; i < aParams.GetCount(); i++ )
+ {
+ if( aParams[i].IsEmpty() )
+ tmp << wxT( "\"\" " );
+ else
+ tmp << aParams[i] << wxT( " " );
+ }
+
+ wxLogTrace( traceFootprintLibrary, tmp );
+}
+
+
+static inline long parseInt( const wxString& aValue, double aScalar )
+{
+ double value = LONG_MAX;
+
+ /*
+ * In 2011 gEDA/pcb introduced values with units, like "10mm" or "200mil".
+ * Unit-less values are still centimils (100000 units per inch), like with
+ * the previous format.
+ *
+ * Distinction between the even older format (mils, 1000 units per inch)
+ * and the pre-2011 format is done in ::parseMODULE already; the
+ * distinction is by wether an object definition opens with '(' or '['.
+ * All values with explicite unit open with a '[' so there's no need to
+ * consider this distinction when parsing them.
+ *
+ * The solution here is to watch for a unit and, if present, convert the
+ * value to centimils. All unit-less values are read unaltered. This way
+ * the code below can contine to consider all read values to be in mils or
+ * centimils. It also matches the strategy gEDA/pcb uses for backwards
+ * compatibility with its own layouts.
+ *
+ * Fortunately gEDA/pcb allows only units 'mil' and 'mm' in files, see
+ * definition of ALLOW_READABLE in gEDA/pcb's pcb_printf.h. So we don't
+ * have to test for all 11 units gEDA/pcb allows in user dialogs.
+ */
+ if( aValue.EndsWith( wxT( "mm" ) ) )
+ {
+ aScalar *= 100000.0 / 25.4;
+ }
+ else if( aValue.EndsWith( wxT( "mil" ) ) )
+ {
+ aScalar *= 100.;
+ }
+
+ // This conversion reports failure on strings as simple as "1000", still
+ // it returns the right result in &value. Thus, ignore the return value.
+ aValue.ToCDouble(&value);
+ if( value == LONG_MAX ) // conversion really failed
+ {
+ THROW_IO_ERROR( wxString::Format( _( "Cannot convert \"%s\" to an integer" ),
+ aValue.GetData() ) );
+ return 0;
+ }
+
+ return KiROUND( value * aScalar );
+}
+
+
+// Tracing for token parameter arrays.
+#ifdef DEBUG
+#define TRACE_PARAMS( arr ) traceParams( arr );
+#else
+#define TRACE_PARAMS( arr ) // Expands to nothing on non-debug builds.
+#endif
+
+
+/**
+ * Class GPCB_FPL_CACHE_ITEM
+ * is helper class for creating a footprint library cache.
+ *
+ * The new footprint library design is a file path of individual module files
+ * that contain a single module per file. This class is a helper only for the
+ * footprint portion of the PLUGIN API, and only for the #PCB_IO plugin. It is
+ * private to this implementation file so it is not placed into a header.
+ */
+class GPCB_FPL_CACHE_ITEM
+{
+ wxFileName m_file_name; ///< The the full file name and path of the footprint to cache.
+ bool m_writable; ///< Writability status of the footprint file.
+ wxDateTime m_mod_time; ///< The last file modified time stamp.
+ std::auto_ptr<MODULE> m_module;
+
+public:
+ GPCB_FPL_CACHE_ITEM( MODULE* aModule, const wxFileName& aFileName );
+
+ wxString GetName() const { return m_file_name.GetDirs().Last(); }
+ wxFileName GetFileName() const { return m_file_name; }
+ bool IsModified() const;
+ MODULE* GetModule() const { return m_module.get(); }
+ void UpdateModificationTime() { m_mod_time = m_file_name.GetModificationTime(); }
+};
+
+
+GPCB_FPL_CACHE_ITEM::GPCB_FPL_CACHE_ITEM( MODULE* aModule, const wxFileName& aFileName ) :
+ m_module( aModule )
+{
+ m_file_name = aFileName;
+ m_writable = true; // temporary init
+
+ if( m_file_name.FileExists() )
+ m_mod_time = m_file_name.GetModificationTime();
+ else
+ m_mod_time.Now();
+}
+
+
+bool GPCB_FPL_CACHE_ITEM::IsModified() const
+{
+ if( !m_file_name.FileExists() )
+ return false;
+
+ return m_file_name.GetModificationTime() != m_mod_time;
+}
+
+
+typedef boost::ptr_map< std::string, GPCB_FPL_CACHE_ITEM > MODULE_MAP;
+typedef MODULE_MAP::iterator MODULE_ITER;
+typedef MODULE_MAP::const_iterator MODULE_CITER;
+
+
+class GPCB_FPL_CACHE
+{
+ GPCB_PLUGIN* m_owner; /// Plugin object that owns the cache.
+ wxFileName m_lib_path; /// The path of the library.
+ wxDateTime m_mod_time; /// Footprint library path modified time stamp.
+ MODULE_MAP m_modules; /// Map of footprint file name per MODULE*.
+
+ MODULE* parseMODULE( LINE_READER* aLineReader ) throw( IO_ERROR, PARSE_ERROR );
+
+ /**
+ * Function testFlags
+ * tests \a aFlag for \a aMask or \a aName.
+ * @param aFlag = List of flags to test against: can be a bit field flag or a list name flag
+ * a bit field flag is an hexadecimal value: Ox00020000
+ * a list name flag is a string list of flags, comma separated like square,option1
+ * @param aMask = flag list to test
+ * @param aName = flag name to find in list
+ * @return true if found
+ */
+ bool testFlags( const wxString& aFlag, long aMask, const wxChar* aName );
+
+ /**
+ * Function parseParameters
+ * extracts parameters and tokens from \a aLineReader and adds them to \a aParameterList.
+ *
+ * Delimiter characters are:
+ * [ ] ( ) Begin and end of parameter list and units indicator
+ * " is a string delimiter
+ * space is the param separator
+ * The first word is the keyword
+ * the second item is one of ( or [
+ * other are parameters (number or delimited string)
+ * last parameter is ) or ]
+ *
+ * @param aParameterList This list of parameters parsed.
+ * @param aLineReader The line reader object to parse.
+ */
+ void parseParameters( wxArrayString& aParameterList, LINE_READER* aLineReader );
+
+public:
+ GPCB_FPL_CACHE( GPCB_PLUGIN* aOwner, const wxString& aLibraryPath );
+
+ wxString GetPath() const { return m_lib_path.GetPath(); }
+ wxDateTime GetLastModificationTime() const { return m_mod_time; }
+ bool IsWritable() const { return m_lib_path.IsOk() && m_lib_path.IsDirWritable(); }
+ MODULE_MAP& GetModules() { return m_modules; }
+
+ // Most all functions in this class throw IO_ERROR exceptions. There are no
+ // error codes nor user interface calls from here, nor in any PLUGIN.
+ // Catch these exceptions higher up please.
+
+ /// Save not implemented for the Geda PCB footprint library format.
+
+ void Load();
+
+ void Remove( const wxString& aFootprintName );
+
+ wxDateTime GetLibModificationTime() const;
+
+ /**
+ * Function IsModified
+ * check if the footprint cache has been modified relative to \a aLibPath
+ * and \a aFootprintName.
+ *
+ * @param aLibPath is a path to test the current cache library path against.
+ * @param aFootprintName is the footprint name in the cache to test. If the footprint
+ * name is empty, the all the footprint files in the library are
+ * checked to see if they have been modified.
+ * @return true if the cache has been modified.
+ */
+ bool IsModified( const wxString& aLibPath,
+ const wxString& aFootprintName = wxEmptyString ) const;
+
+ /**
+ * Function IsPath
+ * checks if \a aPath is the same as the current cache path.
+ *
+ * This tests paths by converting \a aPath using the native separators. Internally
+ * #FP_CACHE stores the current path using native separators. This prevents path
+ * miscompares on Windows due to the fact that paths can be stored with / instead of \\
+ * in the footprint library table.
+ *
+ * @param aPath is the library path to test against.
+ * @return true if \a aPath is the same as the cache path.
+ */
+ bool IsPath( const wxString& aPath ) const;
+};
+
+
+GPCB_FPL_CACHE::GPCB_FPL_CACHE( GPCB_PLUGIN* aOwner, const wxString& aLibraryPath )
+{
+ m_owner = aOwner;
+ m_lib_path.SetPath( aLibraryPath );
+}
+
+
+wxDateTime GPCB_FPL_CACHE::GetLibModificationTime() const
+{
+ if( !m_lib_path.DirExists() )
+ return wxDateTime::Now();
+
+ return m_lib_path.GetModificationTime();
+}
+
+
+void GPCB_FPL_CACHE::Load()
+{
+ wxDir dir( m_lib_path.GetPath() );
+
+ if( !dir.IsOpened() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "footprint library path '%s' does not exist" ),
+ m_lib_path.GetPath().GetData() ) );
+ }
+
+ wxString fpFileName;
+ wxString wildcard = wxT( "*." ) + GedaPcbFootprintLibFileExtension;
+
+ if( !dir.GetFirst( &fpFileName, wildcard, wxDIR_FILES ) )
+ return;
+
+ do
+ {
+ wxFileName fn( m_lib_path.GetPath(), fpFileName );
+
+ // reader now owns fp, will close on exception or return
+ FILE_LINE_READER reader( fn.GetFullPath() );
+ std::string name = TO_UTF8( fn.GetName() );
+ MODULE* footprint = parseMODULE( &reader );
+
+ // The footprint name is the file name without the extension.
+ footprint->SetFPID( FPID( fn.GetName() ) );
+ m_modules.insert( name, new GPCB_FPL_CACHE_ITEM( footprint, fn.GetName() ) );
+
+ } while( dir.GetNext( &fpFileName ) );
+
+ // Remember the file modification time of library file when the
+ // cache snapshot was made, so that in a networked environment we will
+ // reload the cache as needed.
+ m_mod_time = GetLibModificationTime();
+}
+
+
+void GPCB_FPL_CACHE::Remove( const wxString& aFootprintName )
+{
+ std::string footprintName = TO_UTF8( aFootprintName );
+
+ MODULE_CITER it = m_modules.find( footprintName );
+
+ if( it == m_modules.end() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "library <%s> has no footprint '%s' to delete" ),
+ m_lib_path.GetPath().GetData(),
+ aFootprintName.GetData() ) );
+ }
+
+ // Remove the module from the cache and delete the module file from the library.
+ wxString fullPath = it->second->GetFileName().GetFullPath();
+ m_modules.erase( footprintName );
+ wxRemoveFile( fullPath );
+}
+
+
+bool GPCB_FPL_CACHE::IsPath( const wxString& aPath ) const
+{
+ // Converts path separators to native path separators
+ wxFileName newPath;
+ newPath.AssignDir( aPath );
+
+ return m_lib_path == newPath;
+}
+
+
+bool GPCB_FPL_CACHE::IsModified( const wxString& aLibPath, const wxString& aFootprintName ) const
+{
+ // The library is modified if the library path got deleted or changed.
+ if( !m_lib_path.DirExists() || !IsPath( aLibPath ) )
+ return true;
+
+ // If no footprint was specified, check every file modification time against the time
+ // it was loaded.
+ if( aFootprintName.IsEmpty() )
+ {
+ for( MODULE_CITER it = m_modules.begin(); it != m_modules.end(); ++it )
+ {
+ wxFileName fn = m_lib_path;
+
+ fn.SetName( it->second->GetFileName().GetName() );
+ fn.SetExt( KiCadFootprintFileExtension );
+
+ if( !fn.FileExists() )
+ {
+ wxLogTrace( traceFootprintLibrary,
+ wxT( "Footprint cache file '%s' does not exist." ),
+ fn.GetFullPath().GetData() );
+ return true;
+ }
+
+ if( it->second->IsModified() )
+ {
+ wxLogTrace( traceFootprintLibrary,
+ wxT( "Footprint cache file '%s' has been modified." ),
+ fn.GetFullPath().GetData() );
+ return true;
+ }
+ }
+ }
+ else
+ {
+ MODULE_CITER it = m_modules.find( TO_UTF8( aFootprintName ) );
+
+ if( it == m_modules.end() || it->second->IsModified() )
+ return true;
+ }
+
+ return false;
+}
+
+
+MODULE* GPCB_FPL_CACHE::parseMODULE( LINE_READER* aLineReader ) throw( IO_ERROR, PARSE_ERROR )
+{
+ #define TEXT_DEFAULT_SIZE ( 40*IU_PER_MILS )
+ #define OLD_GPCB_UNIT_CONV IU_PER_MILS
+
+ // Old version unit = 1 mil, so conv_unit is 10 or 0.1
+ #define NEW_GPCB_UNIT_CONV ( 0.01*IU_PER_MILS )
+
+ int paramCnt;
+ double conv_unit = NEW_GPCB_UNIT_CONV; // GPCB unit = 0.01 mils and Pcbnew 0.1
+ wxPoint textPos;
+ wxString msg;
+ wxArrayString parameters;
+ std::auto_ptr<MODULE> module( new MODULE( NULL ) );
+
+
+ if( aLineReader->ReadLine() == NULL )
+ THROW_IO_ERROR( "unexpected end of file" );
+
+ parameters.Clear();
+ parseParameters( parameters, aLineReader );
+ paramCnt = parameters.GetCount();
+
+ /* From the Geda PCB documentation, valid Element definitions:
+ * Element [SFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TSFlags]
+ * Element (NFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TNFlags)
+ * Element (NFlags "Desc" "Name" "Value" TX TY TDir TScale TNFlags)
+ * Element (NFlags "Desc" "Name" TX TY TDir TScale TNFlags)
+ * Element ("Desc" "Name" TX TY TDir TScale TNFlags)
+ */
+
+ if( parameters[0].CmpNoCase( wxT( "Element" ) ) != 0 )
+ {
+ msg.Printf( _( "unknown token \"%s\"" ), GetChars( parameters[0] ) );
+ THROW_PARSE_ERROR( msg, aLineReader->GetSource(), (const char *)aLineReader,
+ aLineReader->LineNumber(), 0 );
+ }
+
+ if( paramCnt < 10 || paramCnt > 14 )
+ {
+ msg.Printf( _( "Element token contains %d parameters." ), paramCnt );
+ THROW_PARSE_ERROR( msg, aLineReader->GetSource(), (const char *)aLineReader,
+ aLineReader->LineNumber(), 0 );
+ }
+
+ // Test symbol after "Element": if [ units = 0.01 mils, and if ( units = 1 mil
+ if( parameters[1] == wxT( "(" ) )
+ conv_unit = OLD_GPCB_UNIT_CONV;
+
+ if( paramCnt > 10 )
+ {
+ module->SetDescription( parameters[3] );
+ module->SetReference( parameters[4] );
+ }
+ else
+ {
+ module->SetDescription( parameters[2] );
+ module->SetReference( parameters[3] );
+ }
+
+ // Read value
+ if( paramCnt > 10 )
+ module->SetValue( parameters[5] );
+ // With gEDA/pcb, value is meaningful after instantiation, only, so it's
+ // often empty in bare footprints.
+ if( module->Value().GetText().IsEmpty() )
+ module->Value().SetText( wxT( "Val**" ) );
+
+
+ if( paramCnt == 14 )
+ {
+ textPos = wxPoint( parseInt( parameters[8], conv_unit ),
+ parseInt( parameters[9], conv_unit ) );
+ }
+ else
+ {
+ textPos = wxPoint( parseInt( parameters[6], conv_unit ),
+ parseInt( parameters[7], conv_unit ) );
+ }
+
+ int orientation = parseInt( parameters[paramCnt-4], 1.0 );
+ module->Reference().SetOrientation( (orientation % 2) ? 900 : 0 );
+
+ // Calculate size: default height is 40 mils, width 30 mil.
+ // real size is: default * ibuf[idx+3] / 100 (size in gpcb is given in percent of default size
+ int thsize = parseInt( parameters[paramCnt-3], TEXT_DEFAULT_SIZE ) / 100;
+ thsize = std::max( (int)( 5 * IU_PER_MILS ), thsize ); // Ensure a minimal size = 5 mils
+ int twsize = thsize * 30 / 40;
+ int thickness = thsize / 8;
+
+ // gEDA/pcb aligns top/left, not pcbnew's default, center/center.
+ // Compensate for this by shifting the insertion point instead of the
+ // aligment, because alignment isn't changeable in the GUI.
+ textPos.x = textPos.x + twsize * module->GetReference().Len() / 2;
+ textPos.y += thsize / 2;
+
+ // gEDA/pcb draws a bit too low/left, while pcbnew draws a bit too
+ // high/right. Compensate for similar appearance.
+ textPos.x -= thsize / 10;
+ textPos.y += thsize / 2;
+
+ module->Reference().SetTextPosition( textPos );
+ module->Reference().SetPos0( textPos );
+ module->Reference().SetSize( wxSize( twsize, thsize ) );
+ module->Reference().SetThickness( thickness );
+
+ // gEDA/pcb shows only one of value/reference/description at a time. Which
+ // one is selectable by a global menu setting. pcbnew needs reference as
+ // well as value visible, so place the value right below the reference.
+ module->Value().SetOrientation( module->Reference().GetOrientation() );
+ module->Value().SetSize( module->Reference().GetSize() );
+ module->Value().SetThickness( module->Reference().GetThickness() );
+ textPos.y += thsize * 13 / 10; // 130% line height
+ module->Value().SetTextPosition( textPos );
+ module->Value().SetPos0( textPos );
+
+ while( aLineReader->ReadLine() )
+ {
+ parameters.Clear();
+ parseParameters( parameters, aLineReader );
+
+ if( parameters.IsEmpty() || parameters[0] == wxT( "(" ) )
+ continue;
+
+ if( parameters[0] == wxT( ")" ) )
+ break;
+
+ paramCnt = parameters.GetCount();
+
+ // Test units value for a string line param (more than 3 parameters : ident [ xx ] )
+ if( paramCnt > 3 )
+ {
+ if( parameters[1] == wxT( "(" ) )
+ conv_unit = OLD_GPCB_UNIT_CONV;
+ else
+ conv_unit = NEW_GPCB_UNIT_CONV;
+ }
+
+ wxLogTrace( traceFootprintLibrary, wxT( "%s parameter count = %d." ),
+ GetChars( parameters[0] ), paramCnt );
+
+ // Parse a line with format: ElementLine [X1 Y1 X2 Y2 Thickness]
+ if( parameters[0].CmpNoCase( wxT( "ElementLine" ) ) == 0 )
+ {
+ if( paramCnt != 8 )
+ {
+ msg.Printf( wxT( "ElementLine token contains %d parameters." ), paramCnt );
+ THROW_PARSE_ERROR( msg, aLineReader->GetSource(), (const char *)aLineReader,
+ aLineReader->LineNumber(), 0 );
+ }
+
+ EDGE_MODULE* drawSeg = new EDGE_MODULE( module.get() );
+ drawSeg->SetLayer( F_SilkS );
+ drawSeg->SetShape( S_SEGMENT );
+ drawSeg->SetStart0( wxPoint( parseInt( parameters[2], conv_unit ),
+ parseInt( parameters[3], conv_unit ) ) );
+ drawSeg->SetEnd0( wxPoint( parseInt( parameters[4], conv_unit ),
+ parseInt( parameters[5], conv_unit ) ) );
+ drawSeg->SetWidth( parseInt( parameters[6], conv_unit ) );
+ drawSeg->SetDrawCoord();
+ module->GraphicalItems().PushBack( drawSeg );
+ continue;
+ }
+
+ // Parse an arc with format: ElementArc [X Y Width Height StartAngle DeltaAngle Thickness]
+ if( parameters[0].CmpNoCase( wxT( "ElementArc" ) ) == 0 )
+ {
+ if( paramCnt != 10 )
+ {
+ msg.Printf( wxT( "ElementArc token contains %d parameters." ), paramCnt );
+ THROW_PARSE_ERROR( msg, aLineReader->GetSource(), (const char *)aLineReader,
+ aLineReader->LineNumber(), 0 );
+ }
+
+ // Pcbnew does know ellipse so we must have Width = Height
+ EDGE_MODULE* drawSeg = new EDGE_MODULE( module.get() );
+ drawSeg->SetLayer( F_SilkS );
+ drawSeg->SetShape( S_ARC );
+ module->GraphicalItems().PushBack( drawSeg );
+
+ // for and arc: ibuf[3] = ibuf[4]. Pcbnew does not know ellipses
+ int radius = ( parseInt( parameters[4], conv_unit ) +
+ parseInt( parameters[5], conv_unit ) ) / 2;
+
+ wxPoint centre( parseInt( parameters[2], conv_unit ),
+ parseInt( parameters[3], conv_unit ) );
+
+ drawSeg->SetStart0( centre );
+
+ // Pcbnew start angles are inverted and 180 degrees from Geda PCB angles.
+ double start_angle = parseInt( parameters[6], -10.0 ) + 1800.0;
+
+ // Pcbnew delta angle direction is the opposite of Geda PCB delta angles.
+ double sweep_angle = parseInt( parameters[7], -10.0 );
+
+ // Geda PCB does not support circles.
+ if( sweep_angle == -3600.0 )
+ drawSeg->SetShape( S_CIRCLE );
+
+ // Angle value is clockwise in gpcb and Pcbnew.
+ drawSeg->SetAngle( sweep_angle );
+ drawSeg->SetEnd0( wxPoint( radius, 0 ) );
+
+ // Calculate start point coordinate of arc
+ wxPoint arcStart( drawSeg->GetEnd0() );
+ RotatePoint( &arcStart, -start_angle );
+ drawSeg->SetEnd0( centre + arcStart );
+ drawSeg->SetWidth( parseInt( parameters[8], conv_unit ) );
+ drawSeg->SetDrawCoord();
+ continue;
+ }
+
+ // Parse a Pad with no hole with format:
+ // Pad [rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" SFlags]
+ // Pad (rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" NFlags)
+ // Pad (aX1 aY1 aX2 aY2 Thickness "Name" "Number" NFlags)
+ // Pad (aX1 aY1 aX2 aY2 Thickness "Name" NFlags)
+ if( parameters[0].CmpNoCase( wxT( "Pad" ) ) == 0 )
+ {
+ if( paramCnt < 10 || paramCnt > 13 )
+ {
+ msg.Printf( wxT( "Pad token contains %d parameters." ), paramCnt );
+ THROW_PARSE_ERROR( msg, aLineReader->GetSource(), (const char *)aLineReader,
+ aLineReader->LineNumber(), 0 );
+ }
+
+ D_PAD* pad = new D_PAD( module.get() );
+
+ static const LSET pad_front( 3, F_Cu, F_Mask, F_Paste );
+ static const LSET pad_back( 3, B_Cu, B_Mask, B_Paste );
+
+ pad->SetShape( PAD_SHAPE_RECT );
+ pad->SetAttribute( PAD_ATTRIB_SMD );
+ pad->SetLayerSet( pad_front );
+
+ if( testFlags( parameters[paramCnt-2], 0x0080, wxT( "onsolder" ) ) )
+ pad->SetLayerSet( pad_back );
+
+ // Set the pad name:
+ // Pcbnew pad name is used for electrical connection calculations.
+ // Accordingly it should be mapped to gEDA's pin/pad number,
+ // which is used for the same purpose.
+ // gEDA also features a pin/pad "name", which is an arbitrary string
+ // and set to the pin name of the netlist on instantiation. Many gEDA
+ // bare footprints use identical strings for name and number, so this
+ // can be a bit confusing.
+ pad->SetPadName( parameters[paramCnt-3] );
+
+ int x1 = parseInt( parameters[2], conv_unit );
+ int x2 = parseInt( parameters[4], conv_unit );
+ int y1 = parseInt( parameters[3], conv_unit );
+ int y2 = parseInt( parameters[5], conv_unit );
+ int width = parseInt( parameters[6], conv_unit );
+ wxPoint delta( x2 - x1, y2 - y1 );
+ double angle = atan2( (double)delta.y, (double)delta.x );
+
+ // Get the pad clearance and the solder mask clearance.
+ if( paramCnt == 13 )
+ {
+ int clearance = parseInt( parameters[7], conv_unit );
+ // One of gEDA's oddities is that clearance between pad and polygon
+ // is given as the gap on both sides of the pad together, so for
+ // KiCad it has to halfed.
+ pad->SetLocalClearance( clearance / 2 );
+
+ // In GEDA, the mask value is the size of the hole in this
+ // solder mask. In Pcbnew, it is a margin, therefore the distance
+ // between the copper and the mask
+ int maskMargin = parseInt( parameters[8], conv_unit );
+ maskMargin = ( maskMargin - width ) / 2;
+ pad->SetLocalSolderMaskMargin( maskMargin );
+ }
+
+ // Negate angle (due to Y reversed axis) and convert it to internal units
+ angle = - RAD2DECIDEG( angle );
+ pad->SetOrientation( KiROUND( angle ) );
+
+ wxPoint padPos( (x1 + x2) / 2, (y1 + y2) / 2 );
+
+ pad->SetSize( wxSize( KiROUND( EuclideanNorm( delta ) ) + width,
+ width ) );
+
+ padPos += module->GetPosition();
+ pad->SetPos0( padPos );
+ pad->SetPosition( padPos );
+
+ if( !testFlags( parameters[paramCnt-2], 0x0100, wxT( "square" ) ) )
+ {
+ if( pad->GetSize().x == pad->GetSize().y )
+ pad->SetShape( PAD_SHAPE_CIRCLE );
+ else
+ pad->SetShape( PAD_SHAPE_OVAL );
+ }
+
+ module->Add( pad );
+ continue;
+ }
+
+ // Parse a Pin with through hole with format:
+ // Pin [rX rY Thickness Clearance Mask Drill "Name" "Number" SFlags]
+ // Pin (rX rY Thickness Clearance Mask Drill "Name" "Number" NFlags)
+ // Pin (aX aY Thickness Drill "Name" "Number" NFlags)
+ // Pin (aX aY Thickness Drill "Name" NFlags)
+ // Pin (aX aY Thickness "Name" NFlags)
+ if( parameters[0].CmpNoCase( wxT( "Pin" ) ) == 0 )
+ {
+ if( paramCnt < 8 || paramCnt > 12 )
+ {
+ msg.Printf( wxT( "Pin token contains %d parameters." ), paramCnt );
+ THROW_PARSE_ERROR( msg, aLineReader->GetSource(), (const char *)aLineReader,
+ aLineReader->LineNumber(), 0 );
+ }
+
+ D_PAD* pad = new D_PAD( module.get() );
+
+ pad->SetShape( PAD_SHAPE_CIRCLE );
+
+ static const LSET pad_set = LSET::AllCuMask() | LSET( 3, F_SilkS, F_Mask, B_Mask );
+
+ pad->SetLayerSet( pad_set );
+
+ if( testFlags( parameters[paramCnt-2], 0x0100, wxT( "square" ) ) )
+ pad->SetShape( PAD_SHAPE_RECT );
+
+ // Set the pad name:
+ // Pcbnew pad name is used for electrical connection calculations.
+ // Accordingly it should be mapped to gEDA's pin/pad number,
+ // which is used for the same purpose.
+ pad->SetPadName( parameters[paramCnt-3] );
+
+ wxPoint padPos( parseInt( parameters[2], conv_unit ),
+ parseInt( parameters[3], conv_unit ) );
+
+ int padSize = parseInt( parameters[4], conv_unit );
+
+ pad->SetSize( wxSize( padSize, padSize ) );
+
+ int drillSize = 0;
+
+ // Get the pad clearance, solder mask clearance, and drill size.
+ if( paramCnt == 12 )
+ {
+ int clearance = parseInt( parameters[5], conv_unit );
+ // One of gEDA's oddities is that clearance between pad and polygon
+ // is given as the gap on both sides of the pad together, so for
+ // KiCad it has to halfed.
+ pad->SetLocalClearance( clearance / 2 );
+
+ // In GEDA, the mask value is the size of the hole in this
+ // solder mask. In Pcbnew, it is a margin, therefore the distance
+ // between the copper and the mask
+ int maskMargin = parseInt( parameters[6], conv_unit );
+ maskMargin = ( maskMargin - padSize ) / 2;
+ pad->SetLocalSolderMaskMargin( maskMargin );
+
+ drillSize = parseInt( parameters[7], conv_unit );
+ }
+ else
+ {
+ drillSize = parseInt( parameters[5], conv_unit );
+ }
+
+ pad->SetDrillSize( wxSize( drillSize, drillSize ) );
+ padPos += module->GetPosition();
+ pad->SetPos0( padPos );
+ pad->SetPosition( padPos );
+
+ if( pad->GetShape() == PAD_SHAPE_CIRCLE && pad->GetSize().x != pad->GetSize().y )
+ pad->SetShape( PAD_SHAPE_OVAL );
+
+ module->Add( pad );
+ continue;
+ }
+ }
+
+ // Recalculate the bounding box
+ module->CalculateBoundingBox();
+ return module.release();
+}
+
+
+void GPCB_FPL_CACHE::parseParameters( wxArrayString& aParameterList, LINE_READER* aLineReader )
+{
+ char key;
+ wxString tmp;
+ char* line = aLineReader->Line();
+
+ // Last line already ready in main parser loop.
+ while( *line != 0 )
+ {
+ key = *line;
+ line++;
+
+ switch( key )
+ {
+ case '[':
+ case '(':
+ if( !tmp.IsEmpty() )
+ {
+ aParameterList.Add( tmp );
+ tmp.Clear();
+ }
+
+ tmp.Append( key );
+ aParameterList.Add( tmp );
+ tmp.Clear();
+
+ // Opening delimiter "(" after Element statement. Any other occurrence is part
+ // of a keyword definition.
+ if( aParameterList.GetCount() == 1 )
+ {
+ TRACE_PARAMS( aParameterList );
+ return;
+ }
+
+ break;
+
+ case ']':
+ case ')':
+ if( !tmp.IsEmpty() )
+ {
+ aParameterList.Add( tmp );
+ tmp.Clear();
+ }
+
+ tmp.Append( key );
+ aParameterList.Add( tmp );
+ TRACE_PARAMS( aParameterList );
+ return;
+
+ case '\n':
+ case '\r':
+ // Element descriptions can span multiple lines.
+ line = aLineReader->ReadLine();
+
+ // Fall through is intentional.
+
+ case '\t':
+ case ' ':
+ if( !tmp.IsEmpty() )
+ {
+ aParameterList.Add( tmp );
+ tmp.Clear();
+ }
+
+ break;
+
+ case '"':
+ // Handle empty quotes.
+ if( *line == '"' )
+ {
+ line++;
+ tmp.Clear();
+ aParameterList.Add( wxEmptyString );
+ break;
+ }
+
+ while( *line != 0 )
+ {
+ key = *line;
+ line++;
+
+ if( key == '"' )
+ {
+ aParameterList.Add( tmp );
+ tmp.Clear();
+ break;
+ }
+ else
+ {
+ tmp.Append( key );
+ }
+ }
+
+ break;
+
+ case '#':
+ line = aLineReader->ReadLine();
+ break;
+
+ default:
+ tmp.Append( key );
+ break;
+ }
+ }
+}
+
+
+bool GPCB_FPL_CACHE::testFlags( const wxString& aFlag, long aMask, const wxChar* aName )
+{
+ wxString number;
+
+ if( aFlag.StartsWith( wxT( "0x" ), &number ) || aFlag.StartsWith( wxT( "0X" ), &number ) )
+ {
+ long lflags;
+
+ if( number.ToLong( &lflags, 16 ) && ( lflags & aMask ) )
+ return true;
+ }
+ else if( aFlag.Contains( aName ) )
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+GPCB_PLUGIN::GPCB_PLUGIN() :
+ m_cache( 0 ),
+ m_ctl( 0 )
+{
+ m_reader = NULL;
+ init( 0 );
+}
+
+
+GPCB_PLUGIN::GPCB_PLUGIN( int aControlFlags ) :
+ m_cache( 0 ),
+ m_ctl( aControlFlags )
+{
+ m_reader = NULL;
+ init( 0 );
+}
+
+
+GPCB_PLUGIN::~GPCB_PLUGIN()
+{
+ delete m_cache;
+}
+
+
+void GPCB_PLUGIN::init( const PROPERTIES* aProperties )
+{
+ m_props = aProperties;
+}
+
+
+void GPCB_PLUGIN::cacheLib( const wxString& aLibraryPath, const wxString& aFootprintName )
+{
+ if( !m_cache || m_cache->IsModified( aLibraryPath, aFootprintName ) )
+ {
+ // a spectacular episode in memory management:
+ delete m_cache;
+ m_cache = new GPCB_FPL_CACHE( this, aLibraryPath );
+ m_cache->Load();
+ }
+}
+
+
+wxArrayString GPCB_PLUGIN::FootprintEnumerate( const wxString& aLibraryPath,
+ const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+ wxArrayString ret;
+ wxDir dir( aLibraryPath );
+
+ if( !dir.IsOpened() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "footprint library path '%s' does not exist" ),
+ GetChars( aLibraryPath ) ) );
+ }
+
+ init( aProperties );
+
+#if 1 // Set to 0 to only read directory contents, not load cache.
+ cacheLib( aLibraryPath );
+
+ const MODULE_MAP& mods = m_cache->GetModules();
+
+
+ for( MODULE_CITER it = mods.begin(); it != mods.end(); ++it )
+ {
+ ret.Add( FROM_UTF8( it->first.c_str() ) );
+ }
+#else
+ wxString fpFileName;
+ wxString wildcard = wxT( "*." ) + GedaPcbFootprintLibFileExtension;
+
+ if( dir.GetFirst( &fpFileName, wildcard, wxDIR_FILES ) )
+ {
+ do
+ {
+ wxFileName fn( aLibraryPath, fpFileName );
+ ret.Add( fn.GetName() );
+ } while( dir.GetNext( &fpFileName ) );
+ }
+#endif
+
+ return ret;
+}
+
+
+MODULE* GPCB_PLUGIN::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ init( aProperties );
+
+ cacheLib( aLibraryPath, aFootprintName );
+
+ const MODULE_MAP& mods = m_cache->GetModules();
+
+ MODULE_CITER it = mods.find( TO_UTF8( aFootprintName ) );
+
+ if( it == mods.end() )
+ {
+ return NULL;
+ }
+
+ // copy constructor to clone the already loaded MODULE
+ return new MODULE( *it->second->GetModule() );
+}
+
+
+void GPCB_PLUGIN::FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ init( aProperties );
+
+ cacheLib( aLibraryPath );
+
+ if( !m_cache->IsWritable() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "Library '%s' is read only" ),
+ aLibraryPath.GetData() ) );
+ }
+
+ m_cache->Remove( aFootprintName );
+}
+
+
+bool GPCB_PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ wxFileName fn;
+ fn.SetPath( aLibraryPath );
+
+ // Return if there is no library path to delete.
+ if( !fn.DirExists() )
+ return false;
+
+ if( !fn.IsDirWritable() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "user does not have permission to delete directory '%s'" ),
+ aLibraryPath.GetData() ) );
+ }
+
+ wxDir dir( aLibraryPath );
+
+ if( dir.HasSubDirs() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "library directory '%s' has unexpected sub-directories" ),
+ aLibraryPath.GetData() ) );
+ }
+
+ // All the footprint files must be deleted before the directory can be deleted.
+ if( dir.HasFiles() )
+ {
+ unsigned i;
+ wxFileName tmp;
+ wxArrayString files;
+
+ wxDir::GetAllFiles( aLibraryPath, &files );
+
+ for( i = 0; i < files.GetCount(); i++ )
+ {
+ tmp = files[i];
+
+ if( tmp.GetExt() != KiCadFootprintFileExtension )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "unexpected file '%s' was found in library path '%s'" ),
+ files[i].GetData(), aLibraryPath.GetData() ) );
+ }
+ }
+
+ for( i = 0; i < files.GetCount(); i++ )
+ {
+ wxRemoveFile( files[i] );
+ }
+ }
+
+ wxLogTrace( traceFootprintLibrary, wxT( "Removing footprint library '%s'" ),
+ aLibraryPath.GetData() );
+
+ // Some of the more elaborate wxRemoveFile() crap puts up its own wxLog dialog
+ // we don't want that. we want bare metal portability with no UI here.
+ if( !wxRmdir( aLibraryPath ) )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "footprint library '%s' cannot be deleted" ),
+ aLibraryPath.GetData() ) );
+ }
+
+ // For some reason removing a directory in Windows is not immediately updated. This delay
+ // prevents an error when attempting to immediately recreate the same directory when over
+ // writing an existing library.
+#ifdef __WINDOWS__
+ wxMilliSleep( 250L );
+#endif
+
+ if( m_cache && m_cache->GetPath() == aLibraryPath )
+ {
+ delete m_cache;
+ m_cache = NULL;
+ }
+
+ return true;
+}
+
+
+bool GPCB_PLUGIN::IsFootprintLibWritable( const wxString& aLibraryPath )
+{
+ LOCALE_IO toggle;
+
+ init( NULL );
+
+ cacheLib( aLibraryPath );
+
+ return m_cache->IsWritable();
+}
diff --git a/pcbnew/gpcb_plugin.h b/pcbnew/gpcb_plugin.h
new file mode 100644
index 0000000..20951cd
--- /dev/null
+++ b/pcbnew/gpcb_plugin.h
@@ -0,0 +1,102 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file gpcb_plugin.cpp
+ * @brief Geda PCB file plugin definition file.
+ */
+
+#ifndef _GPCB_PLUGIN_H_
+#define _GPCB_PLUGIN_H_
+
+#include <io_mgr.h>
+#include <string>
+
+
+class GPCB_FPL_CACHE;
+
+
+/**
+ * Class GPCB_PLUGIN
+ * is a PLUGIN derivation for saving and loading Geda PCB files.
+ *
+ * @note This class is not thread safe, but it is re-entrant multiple times in sequence.
+ * @note Currently only reading GPCB footprint files is implemented.
+ */
+class GPCB_PLUGIN : public PLUGIN
+{
+ friend class GPCB_FPL_CACHE;
+
+public:
+
+ //-----<PLUGIN API>---------------------------------------------------------
+
+ const wxString PluginName() const
+ {
+ return wxT( "Geda PCB" );
+ }
+
+ const wxString GetFileExtension() const
+ {
+ return wxT( "fp" );
+ }
+
+ wxArrayString FootprintEnumerate( const wxString& aLibraryPath,
+ const PROPERTIES* aProperties = NULL);
+
+ MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties = NULL );
+
+ void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties = NULL );
+
+ bool FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL );
+
+ bool IsFootprintLibWritable( const wxString& aLibraryPath );
+
+ //-----</PLUGIN API>--------------------------------------------------------
+
+ GPCB_PLUGIN();
+
+ GPCB_PLUGIN( int aControlFlags );
+
+ ~GPCB_PLUGIN();
+
+protected:
+
+ wxString m_error; ///< for throwing exceptions
+ const PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL.
+ GPCB_FPL_CACHE* m_cache; ///< Footprint library cache.
+ int m_ctl;
+ LINE_READER* m_reader; ///< no ownership here.
+ wxString m_filename; ///< for saves only, name is in m_reader for loads
+
+private:
+ /// we only cache one footprint library for now, this determines which one.
+ void cacheLib( const wxString& aLibraryPath, const wxString& aFootprintName = wxEmptyString );
+
+ void init( const PROPERTIES* aProperties );
+};
+
+#endif // _GPCB_PLUGIN_H_
diff --git a/pcbnew/help_common_strings.h b/pcbnew/help_common_strings.h
new file mode 100644
index 0000000..05486c9
--- /dev/null
+++ b/pcbnew/help_common_strings.h
@@ -0,0 +1,26 @@
+/**
+ * @file pcbnew/help_common_strings.h
+ * strings common to toolbars and menubar
+ */
+
+/**
+ * These strings are used in menus and tools, that do the same command
+ * But they are internationalized, and therefore must be created
+ * at run time, on the fly.
+ * So they cannot be static.
+ *
+ * Therefore they are defined by \#define, used inside menu constructors
+ */
+
+#define HELP_UNDO _( "Undo last edition" )
+#define HELP_REDO _( "Redo the last undo command" )
+#define HELP_FIND _( "Find components and text in current loaded board" )
+
+#define HELP_ZOOM_IN _( "Zoom in" )
+#define HELP_ZOOM_OUT _( "Zoom out" )
+#define HELP_ZOOM_FIT _( "Zoom to fit the board on the screen" )
+#define HELP_ZOOM_REDRAW _( "Redraw the current screen" )
+
+#define HELP_SHOW_HIDE_LAYERMANAGER _( "Show/hide the layers manager toolbar" )
+
+#define HELP_SHOW_HIDE_MICROWAVE_TOOLS _( "Show/hide the microwave toolbar\nThis is a experimental feature (under development)" )
diff --git a/pcbnew/highlight.cpp b/pcbnew/highlight.cpp
new file mode 100644
index 0000000..a7ae4e9
--- /dev/null
+++ b/pcbnew/highlight.cpp
@@ -0,0 +1,192 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file highlight.cpp
+ * @brief Highlight nets.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <kicad_string.h>
+#include <wxPcbStruct.h>
+#include <kicad_device_context.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_track.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <collectors.h>
+
+
+void PCB_EDIT_FRAME::ListNetsAndSelect( wxCommandEvent& event )
+{
+ NETINFO_ITEM* net;
+ wxString netFilter;
+ wxArrayString list;
+
+ netFilter = wxT( "*" );
+ wxTextEntryDialog dlg( this, _( "Filter Net Names" ), _( "Net Filter" ), netFilter );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return; // cancelled by user
+
+ netFilter = dlg.GetValue( );
+
+ if( netFilter.IsEmpty() )
+ return;
+
+ wxString Line;
+ for( unsigned ii = 0; ii < GetBoard()->GetNetCount(); ii++ )
+ {
+ net = GetBoard()->m_NetInfo.GetNetItem( ii );
+
+ if( !WildCompareString( netFilter, net->GetNetname(), false ) )
+ continue;
+
+ Line.Printf( wxT( "net %3.3d: %s" ), net->GetNet(),
+ GetChars( net->GetNetname() ) );
+ list.Add( Line );
+ }
+
+ wxSingleChoiceDialog choiceDlg( this, wxEmptyString, _( "Select Net" ), list );
+
+ if( (choiceDlg.ShowModal() == wxID_CANCEL) || (choiceDlg.GetSelection() == wxNOT_FOUND) )
+ return;
+
+ bool found = false;
+ unsigned netcode = (unsigned) choiceDlg.GetSelection();
+
+ // Search for the net selected.
+ for( unsigned ii = 0; ii < GetBoard()->GetNetCount(); ii++ )
+ {
+ net = GetBoard()->FindNet( ii );
+
+ if( !WildCompareString( netFilter, net->GetNetname(), false ) )
+ continue;
+
+ if( ii == netcode )
+ {
+ netcode = net->GetNet();
+ found = true;
+ break;
+ }
+ }
+
+ if( found )
+ {
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ if( GetBoard()->IsHighLightNetON() )
+ HighLight( &dc );
+
+ GetBoard()->SetHighLightNet( netcode );
+ HighLight( &dc );
+ }
+}
+
+
+int PCB_EDIT_FRAME::SelectHighLight( wxDC* DC )
+{
+ int netcode = -1;
+
+ if( GetBoard()->IsHighLightNetON() )
+ HighLight( DC );
+
+ // use this scheme because a pad is a higher priority than a track in the
+ // search, and finding a pad, instead of a track on a pad,
+ // allows us to fire a message to Eeschema.
+
+ GENERAL_COLLECTORS_GUIDE guide = GetCollectorsGuide();
+
+ // optionally, modify the "guide" here as needed using its member functions
+
+ m_Collector->Collect( GetBoard(), GENERAL_COLLECTOR::PadsTracksOrZones,
+ RefPos( true ), guide );
+
+ BOARD_ITEM* item = (*m_Collector)[0];
+
+ if( item )
+ {
+ switch( item->Type() )
+ {
+ case PCB_PAD_T:
+ netcode = ( (D_PAD*) item )->GetNetCode();
+ SendMessageToEESCHEMA( item );
+ break;
+
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ case PCB_ZONE_T:
+ // since these classes are all derived from TRACK, use a common
+ // GetNet() function:
+ netcode = ( (TRACK*) item )->GetNetCode();
+ break;
+
+ case PCB_ZONE_AREA_T:
+ netcode = ( (ZONE_CONTAINER*) item )->GetNetCode();
+ break;
+
+ default:
+ ; // until somebody changes GENERAL_COLLECTOR::PadsOrTracks,
+ // this should not happen.
+ }
+ }
+
+ if( netcode >= 0 )
+ {
+ GetBoard()->SetHighLightNet( netcode );
+ HighLight( DC );
+ }
+
+ return netcode; // HitTest() failed.
+}
+
+
+void PCB_EDIT_FRAME::HighLight( wxDC* DC )
+{
+ if( GetBoard()->IsHighLightNetON() )
+ GetBoard()->HighLightOFF();
+ else
+ GetBoard()->HighLightON();
+
+ GetBoard()->DrawHighLight( m_canvas, DC, GetBoard()->GetHighLightNetCode() );
+}
+
+void PCB_EDIT_FRAME::HighlightUnconnectedPads( wxDC* DC )
+{
+ for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
+ {
+ RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii];
+
+ if( (net->m_Status & CH_ACTIF) == 0 )
+ continue;
+
+ net->m_PadStart->Draw( m_canvas, DC, GR_OR | GR_HIGHLIGHT );
+ net->m_PadEnd->Draw( m_canvas, DC, GR_OR | GR_HIGHLIGHT );
+ }
+}
diff --git a/pcbnew/hotkeys.cpp b/pcbnew/hotkeys.cpp
new file mode 100644
index 0000000..48d0168
--- /dev/null
+++ b/pcbnew/hotkeys.cpp
@@ -0,0 +1,476 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/hotkeys.cpp
+ */
+
+#include <fctsys.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <modview_frame.h>
+#include <pcbnew_id.h>
+
+#include <hotkeys.h>
+
+// Remark: the hotkey message info is used as keyword in hotkey config files and
+// as comments in help windows, therefore translated only when displayed
+// they are marked _HKI to be extracted by translation tools
+// See hotkeys_basic.h for more info
+
+
+/* How to add a new hotkey:
+ * add a new id in the enum hotkey_id_commnand like MY_NEW_ID_FUNCTION.
+ * add a new EDA_HOTKEY entry like:
+ * static EDA_HOTKEY HkMyNewEntry(_HKI("Command Label"), MY_NEW_ID_FUNCTION, default key value);
+ * "Command Label" is the name used in hotkey list display, and the identifier in the
+ * hotkey list file MY_NEW_ID_FUNCTION is an equivalent id function used in the switch
+ * in OnHotKey() function.
+ * default key value is the default hotkey for this command. Can be overridden by the user
+ * hotkey list file
+ * add the HkMyNewEntry pointer in the s_board_edit_Hotkey_List list ( or/and the
+ * s_module_edit_Hotkey_List list)
+ * Add the new code in the switch in OnHotKey() function.
+ * Note: when the variable itemCurrentlyEdited is true, an item is currently edited.
+ * This can be useful if the new function cannot be executed while an item is currently
+ * being edited ( For example, one cannot start a new wire when a component is moving.)
+ *
+ * Note: If a hotkey is a special key, be sure the corresponding wxWidget keycode (WXK_XXXX)
+ * is handled in the hotkey_name_descr s_Hotkey_Name_List list (see hotkeys_basic.cpp)
+ * and see this list for some ascii keys (space ...)
+ */
+
+// Hotkey list:
+
+// mouse click command:
+static EDA_HOTKEY HkMouseLeftClick( _HKI( "Mouse Left Click" ),
+ HK_LEFT_CLICK, WXK_RETURN, 0 );
+static EDA_HOTKEY HkMouseLeftDClick( _HKI( "Mouse Left Double Click" ),
+ HK_LEFT_DCLICK, WXK_END, 0 );
+
+static EDA_HOTKEY HkSwitch2CopperLayer( _HKI( "Switch to Copper (B.Cu) layer" ),
+ HK_SWITCH_LAYER_TO_COPPER, WXK_PAGEDOWN );
+
+static EDA_HOTKEY HkSwitch2ComponentLayer( _HKI( "Switch to Component (F.Cu) layer" ),
+ HK_SWITCH_LAYER_TO_COMPONENT, WXK_PAGEUP );
+
+static EDA_HOTKEY HkSwitch2InnerLayer1( _HKI( "Switch to Inner layer 1" ),
+ HK_SWITCH_LAYER_TO_INNER1, WXK_F5 );
+static EDA_HOTKEY HkSwitch2InnerLayer2( _HKI( "Switch to Inner layer 2" ),
+ HK_SWITCH_LAYER_TO_INNER2, WXK_F6 );
+static EDA_HOTKEY HkSwitch2InnerLayer3( _HKI( "Switch to Inner layer 3" ),
+ HK_SWITCH_LAYER_TO_INNER3, WXK_F7 );
+static EDA_HOTKEY HkSwitch2InnerLayer4( _HKI( "Switch to Inner layer 4" ),
+ HK_SWITCH_LAYER_TO_INNER4, WXK_F8 );
+static EDA_HOTKEY HkSwitch2InnerLayer5( _HKI( "Switch to Inner layer 5" ),
+ HK_SWITCH_LAYER_TO_INNER5, GR_KB_SHIFT+WXK_F5 );
+static EDA_HOTKEY HkSwitch2InnerLayer6( _HKI( "Switch to Inner layer 6" ),
+ HK_SWITCH_LAYER_TO_INNER6, GR_KB_SHIFT+WXK_F6 );
+
+static EDA_HOTKEY HkSwitch2NextCopperLayer( _HKI( "Switch to Next Layer" ),
+ HK_SWITCH_LAYER_TO_NEXT, '+' );
+static EDA_HOTKEY HkSwitch2PreviousCopperLayer( _HKI( "Switch to Previous Layer" ),
+ HK_SWITCH_LAYER_TO_PREVIOUS, '-' );
+
+static EDA_HOTKEY HkSaveModule( _HKI( "Save Footprint" ), HK_SAVE_MODULE, 'S' + GR_KB_CTRL );
+static EDA_HOTKEY HkSavefile( _HKI( "Save Board" ), HK_SAVE_BOARD, 'S' + GR_KB_CTRL );
+static EDA_HOTKEY HkSavefileAs( _HKI( "Save Board As" ), HK_SAVE_BOARD_AS, 'S' + GR_KB_CTRL + GR_KB_SHIFT );
+static EDA_HOTKEY HkLoadfile( _HKI( "Load Board" ), HK_LOAD_BOARD, 'L' + GR_KB_CTRL );
+static EDA_HOTKEY HkFindItem( _HKI( "Find Item" ), HK_FIND_ITEM, 'F' + GR_KB_CTRL );
+static EDA_HOTKEY HkBackspace( _HKI( "Delete Track Segment" ), HK_BACK_SPACE, WXK_BACK );
+static EDA_HOTKEY HkAddNewTrack( _HKI( "Add New Track" ), HK_ADD_NEW_TRACK, 'X' );
+static EDA_HOTKEY HkAddThroughVia( _HKI( "Add Through Via" ), HK_ADD_THROUGH_VIA, 'V' );
+static EDA_HOTKEY HkSelLayerAndAddThroughVia( _HKI( "Select Layer and Add Through Via" ),
+ HK_SEL_LAYER_AND_ADD_THROUGH_VIA, '<' );
+static EDA_HOTKEY HkAddMicroVia( _HKI( "Add MicroVia" ), HK_ADD_MICROVIA, 'V' + GR_KB_CTRL );
+static EDA_HOTKEY HkAddBlindBuriedVia( _HKI( "Add Blind/Buried Via" ), HK_ADD_BLIND_BURIED_VIA, 'V' + GR_KB_ALT + GR_KB_SHIFT );
+static EDA_HOTKEY HkSelLayerAndAddBlindBuriedVia( _HKI( "Select Layer and Add Blind/Buried Via" ),
+ HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA, '<' + GR_KB_ALT );
+static EDA_HOTKEY HkSwitchTrackPosture( _HKI( "Switch Track Posture" ), HK_SWITCH_TRACK_POSTURE, '/' );
+static EDA_HOTKEY HkDragTrackKeepSlope( _HKI( "Drag Track Keep Slope" ), HK_DRAG_TRACK_KEEP_SLOPE, 'D' );
+static EDA_HOTKEY HkPlaceItem( _HKI( "Place Item" ), HK_PLACE_ITEM, 'P' );
+static EDA_HOTKEY HkEditBoardItem( _HKI( "Edit Item" ), HK_EDIT_ITEM, 'E' );
+static EDA_HOTKEY HkEditWithModedit( _HKI( "Edit with Footprint Editor" ), HK_EDIT_MODULE_WITH_MODEDIT, 'E' + GR_KB_CTRL );
+static EDA_HOTKEY HkFlipItem( _HKI( "Flip Item" ), HK_FLIP_ITEM, 'F' );
+static EDA_HOTKEY HkRotateItem( _HKI( "Rotate Item" ), HK_ROTATE_ITEM, 'R' );
+static EDA_HOTKEY HkMoveItem( _HKI( "Move Item" ), HK_MOVE_ITEM, 'M' );
+static EDA_HOTKEY HkMoveItemExact( _HKI( "Move Item Exactly" ), HK_MOVE_ITEM_EXACT, 'M' + GR_KB_CTRL );
+static EDA_HOTKEY HkDuplicateItem( _HKI( "Duplicate Item" ), HK_DUPLICATE_ITEM, 'D' + GR_KB_CTRL );
+static EDA_HOTKEY HkDuplicateItemAndIncrement( _HKI( "Duplicate Item and Increment" ),
+ HK_DUPLICATE_ITEM_AND_INCREMENT, 'D' + GR_KB_SHIFTCTRL );
+static EDA_HOTKEY HkCreateArray( _HKI( "Create Array" ), HK_CREATE_ARRAY, 'N' + GR_KB_CTRL );
+static EDA_HOTKEY HkCopyItem( _HKI( "Copy Item" ), HK_COPY_ITEM, 'C' );
+static EDA_HOTKEY HkDragFootprint( _HKI( "Drag Item" ), HK_DRAG_ITEM, 'G' );
+static EDA_HOTKEY HkGetAndMoveFootprint( _HKI( "Get and Move Footprint" ), HK_GET_AND_MOVE_FOOTPRINT, 'T' );
+static EDA_HOTKEY HkLock_Unlock_Footprint( _HKI( "Lock/Unlock Footprint" ), HK_LOCK_UNLOCK_FOOTPRINT, 'L' );
+static EDA_HOTKEY HkDelete( _HKI( "Delete Track or Footprint" ), HK_DELETE, WXK_DELETE );
+static EDA_HOTKEY HkResetLocalCoord( _HKI( "Reset Local Coordinates" ), HK_RESET_LOCAL_COORD, ' ' );
+static EDA_HOTKEY HkSwitchHighContrastMode( _HKI( "Toggle High Contrast Mode" ), HK_SWITCH_HIGHCONTRAST_MODE,'H');
+
+static EDA_HOTKEY HkSetGridOrigin( _HKI( "Set Grid Origin" ), HK_SET_GRID_ORIGIN, 'S' );
+static EDA_HOTKEY HkResetGridOrigin( _HKI( "Reset Grid Origin" ), HK_RESET_GRID_ORIGIN, 'Z' );
+
+static EDA_HOTKEY HkCanvasDefault( _HKI( "Switch to Default Canvas" ),
+ HK_CANVAS_DEFAULT,
+#ifdef __WXMAC__
+ GR_KB_ALT +
+#endif
+ WXK_F9 );
+static EDA_HOTKEY HkCanvasOpenGL( _HKI( "Switch to OpenGL Canvas" ),
+ HK_CANVAS_OPENGL,
+#ifdef __WXMAC__
+ GR_KB_ALT +
+#endif
+ WXK_F11 );
+static EDA_HOTKEY HkCanvasCairo( _HKI( "Switch to Cairo Canvas" ),
+ HK_CANVAS_CAIRO,
+#ifdef __WXMAC__
+ GR_KB_ALT +
+#endif
+ WXK_F12 );
+
+static EDA_HOTKEY HkZoneFillOrRefill( _HKI( "Fill or Refill All Zones" ),
+ HK_ZONE_FILL_OR_REFILL, 'B' );
+static EDA_HOTKEY HkZoneRemoveFilled( _HKI( "Remove Filled Areas in All Zones" ),
+ HK_ZONE_REMOVE_FILLED, 'B' + GR_KB_CTRL );
+/* Fit on Screen */
+#if !defined( __WXMAC__ )
+static EDA_HOTKEY HkZoomAuto( _HKI( "Zoom Auto" ), HK_ZOOM_AUTO, WXK_HOME );
+#else
+static EDA_HOTKEY HkZoomAuto( _HKI( "Zoom Auto" ), HK_ZOOM_AUTO, GR_KB_CTRL + '0' );
+#endif
+
+static EDA_HOTKEY HkZoomCenter( _HKI( "Zoom Center" ), HK_ZOOM_CENTER, WXK_F4 );
+
+/* Refresh Screen */
+#if !defined( __WXMAC__ )
+static EDA_HOTKEY HkZoomRedraw( _HKI( "Zoom Redraw" ), HK_ZOOM_REDRAW, WXK_F3 );
+#else
+static EDA_HOTKEY HkZoomRedraw( _HKI( "Zoom Redraw" ), HK_ZOOM_REDRAW, GR_KB_CTRL + 'R' );
+#endif
+
+/* Zoom In */
+#if !defined( __WXMAC__ )
+static EDA_HOTKEY HkZoomIn( _HKI( "Zoom In" ), HK_ZOOM_IN, WXK_F1 );
+#else
+static EDA_HOTKEY HkZoomIn( _HKI( "Zoom In" ), HK_ZOOM_IN, GR_KB_CTRL + '+' );
+#endif
+
+/* Zoom Out */
+#if !defined( __WXMAC__ )
+static EDA_HOTKEY HkZoomOut( _HKI( "Zoom Out" ), HK_ZOOM_OUT, WXK_F2 );
+#else
+static EDA_HOTKEY HkZoomOut( _HKI( "Zoom Out" ), HK_ZOOM_OUT, GR_KB_CTRL + '-' );
+#endif
+
+static EDA_HOTKEY Hk3DViewer( _HKI( "3D Viewer" ), HK_3D_VIEWER, GR_KB_ALT + '3' );
+
+static EDA_HOTKEY HkHelp( _HKI( "Help (this window)" ), HK_HELP, '?' );
+
+
+/* Undo */
+static EDA_HOTKEY HkUndo( _HKI( "Undo" ), HK_UNDO, GR_KB_CTRL + 'Z', (int) wxID_UNDO );
+
+/* Redo */
+#if !defined( __WXMAC__ )
+static EDA_HOTKEY HkRedo( _HKI( "Redo" ), HK_REDO, GR_KB_CTRL + 'Y', (int) wxID_REDO );
+#else
+static EDA_HOTKEY HkRedo( _HKI( "Redo" ), HK_REDO,
+ GR_KB_SHIFT + GR_KB_CTRL + 'Z',
+ (int) wxID_REDO );
+#endif
+
+static EDA_HOTKEY HkSwitchTrackWidthToNext( _HKI( "Switch Track Width To Next" ),
+ HK_SWITCH_TRACK_WIDTH_TO_NEXT, 'W' );
+
+static EDA_HOTKEY HkSwitchTrackWidthToPrevious( _HKI( "Switch Track Width To Previous" ),
+ HK_SWITCH_TRACK_WIDTH_TO_PREVIOUS, 'W'
+ + GR_KB_CTRL );
+
+static EDA_HOTKEY HkSwitchGridToFastGrid1( _HKI( "Switch Grid To Fast Grid1" ),
+ HK_SWITCH_GRID_TO_FASTGRID1, GR_KB_ALT + '1' );
+
+static EDA_HOTKEY HkSwitchGridToFastGrid2( _HKI( "Switch Grid To Fast Grid2" ),
+ HK_SWITCH_GRID_TO_FASTGRID2, GR_KB_ALT + '2' );
+
+static EDA_HOTKEY HkSwitchGridToNext( _HKI( "Switch Grid To Next" ),
+ HK_SWITCH_GRID_TO_NEXT, 'N' );
+
+static EDA_HOTKEY HkSwitchGridToPrevious( _HKI( "Switch Grid To Previous" ),
+ HK_SWITCH_GRID_TO_PREVIOUS, 'N' + GR_KB_SHIFT );
+
+static EDA_HOTKEY HkSwitchUnits( _HKI( "Switch Units" ), HK_SWITCH_UNITS, 'U' + GR_KB_CTRL );
+static EDA_HOTKEY HkTrackDisplayMode( _HKI( "Track Display Mode" ),
+ HK_SWITCH_TRACK_DISPLAY_MODE, 'K' );
+static EDA_HOTKEY HkAddModule( _HKI( "Add Footprint" ), HK_ADD_MODULE, 'O' );
+
+/* Record and play macros */
+static EDA_HOTKEY HkRecordMacros0( _HKI( "Record Macro 0" ), HK_RECORD_MACROS_0, GR_KB_CTRL+'0' );
+
+static EDA_HOTKEY HkCallMacros0( _HKI( "Call Macro 0" ), HK_CALL_MACROS_0, '0' );
+
+static EDA_HOTKEY HkRecordMacros1( _HKI( "Record Macro 1" ), HK_RECORD_MACROS_1, GR_KB_CTRL+'1' );
+
+static EDA_HOTKEY HkCallMacros1( _HKI( "Call Macro 1" ), HK_CALL_MACROS_1, '1' );
+
+static EDA_HOTKEY HkRecordMacros2( _HKI( "Record Macro 2" ), HK_RECORD_MACROS_2, GR_KB_CTRL+'2' );
+
+static EDA_HOTKEY HkCallMacros2( _HKI( "Call Macro 2" ), HK_CALL_MACROS_2, '2' );
+
+static EDA_HOTKEY HkRecordMacros3( _HKI( "Record Macro 3" ), HK_RECORD_MACROS_3, GR_KB_CTRL+'3' );
+
+static EDA_HOTKEY HkCallMacros3( _HKI( "Call Macro 3" ), HK_CALL_MACROS_3, '3' );
+
+static EDA_HOTKEY HkRecordMacros4( _HKI( "Record Macro 4" ), HK_RECORD_MACROS_4, GR_KB_CTRL+'4' );
+
+static EDA_HOTKEY HkCallMacros4( _HKI( "Call Macro 4" ), HK_CALL_MACROS_4, '4' );
+
+static EDA_HOTKEY HkRecordMacros5( _HKI( "Record Macro 5" ), HK_RECORD_MACROS_5, GR_KB_CTRL+'5' );
+
+static EDA_HOTKEY HkCallMacros5( _HKI( "Call Macro 5" ), HK_CALL_MACROS_5, '5' );
+
+static EDA_HOTKEY HkRecordMacros6( _HKI( "Record Macro 6" ), HK_RECORD_MACROS_6, GR_KB_CTRL+'6' );
+
+static EDA_HOTKEY HkCallMacros6( _HKI( "Call Macro 6" ), HK_CALL_MACROS_6, '6' );
+
+static EDA_HOTKEY HkRecordMacros7( _HKI( "Record Macro 7" ), HK_RECORD_MACROS_7, GR_KB_CTRL+'7' );
+
+static EDA_HOTKEY HkCallMacros7( _HKI( "Call Macro 7" ), HK_CALL_MACROS_7, '7' );
+
+static EDA_HOTKEY HkRecordMacros8( _HKI( "Record Macro 8" ), HK_RECORD_MACROS_8, GR_KB_CTRL+'8' );
+
+static EDA_HOTKEY HkCallMacros8( _HKI( "Call Macro 8" ), HK_CALL_MACROS_8, '8' );
+
+static EDA_HOTKEY HkRecordMacros9( _HKI( "Record Macro 9" ), HK_RECORD_MACROS_9, GR_KB_CTRL+'9' );
+
+static EDA_HOTKEY HkCallMacros9( _HKI( "Call Macro 9" ), HK_CALL_MACROS_9, '9' );
+
+
+// List of common hotkey descriptors
+EDA_HOTKEY* common_Hotkey_List[] =
+{
+ &HkHelp, &HkZoomIn, &HkZoomOut,
+ &HkZoomRedraw, &HkZoomCenter, &HkZoomAuto, &Hk3DViewer,
+ &HkSwitchUnits, &HkResetLocalCoord, &HkSetGridOrigin, &HkResetGridOrigin,
+ &HkUndo, &HkRedo,
+ &HkMouseLeftClick,
+ &HkMouseLeftDClick,
+ NULL
+};
+
+// common hotkey descriptors only useful in footprint viewer
+EDA_HOTKEY* common_basic_Hotkey_List[] =
+{
+ &HkHelp, &HkZoomIn, &HkZoomOut,
+ &HkZoomRedraw, &HkZoomCenter, &HkZoomAuto, &Hk3DViewer,
+ &HkSwitchUnits, &HkResetLocalCoord,
+ &HkMouseLeftClick,
+ &HkMouseLeftDClick,
+ NULL
+};
+
+// List of hotkey descriptors for Pcbnew
+EDA_HOTKEY* board_edit_Hotkey_List[] =
+{
+ &HkTrackDisplayMode, &HkDelete,
+ &HkBackspace,
+ &HkAddNewTrack, &HkAddThroughVia, &HkAddBlindBuriedVia,
+ &HkAddMicroVia,
+ &HkSelLayerAndAddThroughVia, &HkSelLayerAndAddBlindBuriedVia,
+ &HkSwitchTrackPosture,
+ &HkDragTrackKeepSlope,
+ &HkPlaceItem, &HkCopyItem,
+ &HkMoveItem,
+ &HkFlipItem,
+ &HkRotateItem, &HkMoveItemExact,
+ &HkDuplicateItem, &HkDuplicateItemAndIncrement, &HkCreateArray,
+ &HkDragFootprint,
+ &HkGetAndMoveFootprint, &HkLock_Unlock_Footprint, &HkSavefile, &HkSavefileAs,
+ &HkLoadfile, &HkFindItem, &HkEditBoardItem,
+ &HkEditWithModedit,
+ &HkSwitch2CopperLayer, &HkSwitch2InnerLayer1,
+ &HkSwitch2InnerLayer2, &HkSwitch2InnerLayer3, &HkSwitch2InnerLayer4,
+ &HkSwitch2InnerLayer5, &HkSwitch2InnerLayer6, &HkSwitch2ComponentLayer,
+ &HkSwitch2NextCopperLayer, &HkSwitch2PreviousCopperLayer,&HkAddModule,
+ &HkSwitchTrackWidthToNext, &HkSwitchTrackWidthToPrevious,&HkSwitchGridToFastGrid1,
+ &HkSwitchGridToFastGrid2, &HkSwitchGridToNext, &HkSwitchGridToPrevious,
+ &HkRecordMacros0, &HkCallMacros0, &HkRecordMacros1, &HkCallMacros1,
+ &HkRecordMacros2, &HkCallMacros2, &HkRecordMacros3, &HkCallMacros3,
+ &HkRecordMacros4, &HkCallMacros4, &HkRecordMacros5, &HkCallMacros5,
+ &HkRecordMacros6, &HkCallMacros6, &HkRecordMacros7, &HkCallMacros7,
+ &HkRecordMacros8, &HkCallMacros8, &HkRecordMacros9, &HkCallMacros9,
+ &HkSwitchHighContrastMode,
+ &HkCanvasDefault, &HkCanvasCairo, &HkCanvasOpenGL,
+ &HkZoneFillOrRefill, &HkZoneRemoveFilled,
+ NULL
+};
+
+// List of hotkey descriptors for the module editor
+EDA_HOTKEY* module_edit_Hotkey_List[] = {
+ &HkMoveItem, &HkRotateItem, &HkEditBoardItem,
+ &HkMoveItemExact, &HkDuplicateItem, &HkDuplicateItemAndIncrement,
+ &HkCreateArray, &HkDelete, &HkSaveModule,
+ &HkCanvasDefault, &HkCanvasCairo, &HkCanvasOpenGL,
+ NULL
+ };
+
+// List of hotkey descriptors for the module viewer
+// Currently empty
+EDA_HOTKEY* module_viewer_Hotkey_List[] = {
+ NULL
+ };
+
+// Keyword Identifiers (tags) in key code configuration file (section names)
+// (.m_SectionTag member of a EDA_HOTKEY_CONFIG)
+static wxString boardEditorSectionTag( wxT( "[pcbnew]" ) );
+static wxString moduleEditSectionTag( wxT( "[footprinteditor]" ) );
+
+// Titles for hotkey editor and hotkey display
+static wxString commonSectionTitle( _HKI( "Common" ) );
+static wxString boardEditorSectionTitle( _HKI( "Board Editor" ) );
+static wxString moduleEditSectionTitle( _HKI( "Footprint Editor" ) );
+
+// list of sections and corresponding hotkey list for Pcbnew
+// (used to create an hotkey config file, and edit hotkeys )
+struct EDA_HOTKEY_CONFIG g_Pcbnew_Editor_Hokeys_Descr[] = {
+ { &g_CommonSectionTag, common_Hotkey_List, &commonSectionTitle },
+ { &boardEditorSectionTag, board_edit_Hotkey_List, &boardEditorSectionTitle },
+ { &moduleEditSectionTag, module_edit_Hotkey_List, &moduleEditSectionTitle },
+ { NULL, NULL, NULL }
+};
+
+// list of sections and corresponding hotkey list for the board editor
+// (used to list current hotkeys in the board editor)
+struct EDA_HOTKEY_CONFIG g_Board_Editor_Hokeys_Descr[] = {
+ { &g_CommonSectionTag, common_Hotkey_List, &commonSectionTitle },
+ { &boardEditorSectionTag, board_edit_Hotkey_List, &boardEditorSectionTitle },
+ { NULL, NULL, NULL }
+};
+
+// list of sections and corresponding hotkey list for the footprint editor
+// (used to list current hotkeys in the module editor)
+struct EDA_HOTKEY_CONFIG g_Module_Editor_Hokeys_Descr[] = {
+ { &g_CommonSectionTag, common_Hotkey_List, &commonSectionTitle },
+ { &moduleEditSectionTag, module_edit_Hotkey_List, &moduleEditSectionTitle },
+ { NULL, NULL, NULL }
+};
+
+// list of sections and corresponding hotkey list for the footprint viewer
+// (used to list current hotkeys in the module viewer)
+struct EDA_HOTKEY_CONFIG g_Module_Viewer_Hokeys_Descr[] = {
+ { &g_CommonSectionTag, common_basic_Hotkey_List, &commonSectionTitle },
+ { NULL, NULL, NULL }
+};
+
+
+EDA_HOTKEY* FOOTPRINT_VIEWER_FRAME::GetHotKeyDescription( int aCommand ) const
+{
+ EDA_HOTKEY* HK_Descr = GetDescriptorFromCommand( aCommand, common_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ HK_Descr = GetDescriptorFromCommand( aCommand, module_viewer_Hotkey_List );
+
+ return HK_Descr;
+}
+
+
+bool FOOTPRINT_VIEWER_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
+ EDA_ITEM* aItem )
+{
+ if( aHotKey == 0 )
+ return false;
+
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+ cmd.SetEventObject( this );
+
+ /* Convert lower to upper case (the usual toupper function has problem with non ascii
+ * codes like function keys */
+ if( (aHotKey >= 'a') && (aHotKey <= 'z') )
+ aHotKey += 'A' - 'a';
+
+ EDA_HOTKEY* HK_Descr = GetDescriptorFromHotkey( aHotKey, common_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ HK_Descr = GetDescriptorFromHotkey( aHotKey, module_viewer_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ return false;
+
+ switch( HK_Descr->m_Idcommand )
+ {
+ default:
+ case HK_NOT_FOUND:
+ return false;
+
+ case HK_HELP: // Display Current hotkey list
+ DisplayHotkeyList( this, g_Module_Viewer_Hokeys_Descr );
+ break;
+
+ case HK_RESET_LOCAL_COORD: // set local (relative) coordinate origin
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ break;
+
+ case HK_LEFT_CLICK:
+ OnLeftClick( aDC, aPosition );
+ break;
+
+ case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events
+ OnLeftClick( aDC, aPosition );
+ OnLeftDClick( aDC, aPosition );
+ break;
+
+ case HK_SWITCH_UNITS:
+ cmd.SetId( (g_UserUnit == INCHES) ?
+ ID_TB_OPTIONS_SELECT_UNIT_MM : ID_TB_OPTIONS_SELECT_UNIT_INCH );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_IN:
+ cmd.SetId( ID_POPUP_ZOOM_IN );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_OUT:
+ cmd.SetId( ID_POPUP_ZOOM_OUT );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_REDRAW:
+ cmd.SetId( ID_ZOOM_REDRAW );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_CENTER:
+ cmd.SetId( ID_POPUP_ZOOM_CENTER );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_AUTO:
+ cmd.SetId( ID_ZOOM_PAGE );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+ }
+
+ return true;
+}
diff --git a/pcbnew/hotkeys.h b/pcbnew/hotkeys.h
new file mode 100644
index 0000000..98e93ff
--- /dev/null
+++ b/pcbnew/hotkeys.h
@@ -0,0 +1,153 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/hotkeys.h
+ * Pcbnew hotkeys
+ */
+#ifndef _PCBNEW_HOTKEYS_H
+#define _PCBNEW_HOTKEYS_H
+
+#include <hotkeys_basic.h>
+
+// List of hot keys id.
+// see also enum common_hotkey_id_commnand in hotkeys_basic.h
+// for shared hotkeys id
+enum hotkey_id_commnand {
+ HK_DELETE = HK_COMMON_END,
+ HK_BACK_SPACE,
+ HK_ROTATE_ITEM,
+ HK_FLIP_ITEM,
+ HK_COPY_ITEM,
+ HK_MOVE_ITEM,
+ HK_MOVE_ITEM_EXACT,
+ HK_DRAG_ITEM,
+ HK_GET_AND_MOVE_FOOTPRINT,
+ HK_LOCK_UNLOCK_FOOTPRINT,
+ HK_ADD_NEW_TRACK,
+ HK_ADD_THROUGH_VIA,
+ HK_SEL_LAYER_AND_ADD_THROUGH_VIA,
+ HK_ADD_BLIND_BURIED_VIA,
+ HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA,
+ HK_ADD_MICROVIA,
+ HK_SWITCH_TRACK_POSTURE,
+ HK_DRAG_TRACK_KEEP_SLOPE,
+ HK_SAVE_BOARD,
+ HK_SAVE_BOARD_AS,
+ HK_LOAD_BOARD,
+ HK_SAVE_MODULE,
+ HK_SWITCH_UNITS,
+ HK_SWITCH_TRACK_DISPLAY_MODE,
+ HK_3D_VIEWER,
+ HK_FIND_ITEM,
+ HK_EDIT_ITEM,
+ HK_EDIT_MODULE_WITH_MODEDIT,
+ HK_DUPLICATE_ITEM,
+ HK_DUPLICATE_ITEM_AND_INCREMENT,
+ HK_CREATE_ARRAY,
+ HK_PLACE_ITEM,
+ HK_SWITCH_TRACK_WIDTH_TO_NEXT,
+ HK_SWITCH_TRACK_WIDTH_TO_PREVIOUS,
+ HK_SWITCH_GRID_TO_FASTGRID1,
+ HK_SWITCH_GRID_TO_FASTGRID2,
+ HK_SWITCH_GRID_TO_NEXT,
+ HK_SWITCH_GRID_TO_PREVIOUS,
+ HK_SWITCH_LAYER_TO_COPPER,
+ HK_SWITCH_LAYER_TO_COMPONENT,
+ HK_SWITCH_LAYER_TO_NEXT,
+ HK_SWITCH_LAYER_TO_PREVIOUS,
+ HK_SWITCH_LAYER_TO_INNER1,
+ HK_SWITCH_LAYER_TO_INNER2,
+ HK_SWITCH_LAYER_TO_INNER3,
+ HK_SWITCH_LAYER_TO_INNER4,
+ HK_SWITCH_LAYER_TO_INNER5,
+ HK_SWITCH_LAYER_TO_INNER6,
+ HK_SWITCH_LAYER_TO_INNER7,
+ HK_SWITCH_LAYER_TO_INNER8,
+ HK_SWITCH_LAYER_TO_INNER9,
+ HK_SWITCH_LAYER_TO_INNER10,
+ HK_SWITCH_LAYER_TO_INNER11,
+ HK_SWITCH_LAYER_TO_INNER12,
+ HK_SWITCH_LAYER_TO_INNER13,
+ HK_SWITCH_LAYER_TO_INNER14,
+ HK_ADD_MODULE,
+ HK_SLIDE_TRACK,
+ HK_MACRO_ID_BEGIN,
+ HK_RECORD_MACROS_0, // keep these id ordered from 0 to 9
+ HK_RECORD_MACROS_1, // because this order is used in code
+ HK_RECORD_MACROS_2,
+ HK_RECORD_MACROS_3,
+ HK_RECORD_MACROS_4,
+ HK_RECORD_MACROS_5,
+ HK_RECORD_MACROS_6,
+ HK_RECORD_MACROS_7,
+ HK_RECORD_MACROS_8,
+ HK_RECORD_MACROS_9,
+ HK_CALL_MACROS_0,
+ HK_CALL_MACROS_1,
+ HK_CALL_MACROS_2,
+ HK_CALL_MACROS_3,
+ HK_CALL_MACROS_4,
+ HK_CALL_MACROS_5,
+ HK_CALL_MACROS_6,
+ HK_CALL_MACROS_7,
+ HK_CALL_MACROS_8,
+ HK_CALL_MACROS_9,
+ HK_MACRO_ID_END,
+ HK_SWITCH_HIGHCONTRAST_MODE,
+ HK_CANVAS_DEFAULT,
+ HK_CANVAS_OPENGL,
+ HK_CANVAS_CAIRO,
+ HK_LEFT_CLICK,
+ HK_LEFT_DCLICK,
+ HK_ZONE_FILL_OR_REFILL,
+ HK_ZONE_REMOVE_FILLED
+};
+
+// Full list of hotkey descriptors for board editor and footprint editor
+extern struct EDA_HOTKEY_CONFIG g_Pcbnew_Editor_Hokeys_Descr[];
+
+// List of hotkey descriptors for the board editor only
+extern struct EDA_HOTKEY_CONFIG g_Board_Editor_Hokeys_Descr[];
+
+// List of hotkey descriptors for the footprint editor only
+extern struct EDA_HOTKEY_CONFIG g_Module_Editor_Hokeys_Descr[];
+
+// List of hotkey descriptors for the footprint editor only
+extern struct EDA_HOTKEY_CONFIG g_Module_Viewer_Hokeys_Descr[];
+
+// List of common hotkey descriptors
+// used in hotkeys_board_editor.cpp and hotkeys_module_editor.cpp
+extern EDA_HOTKEY* common_Hotkey_List[];
+
+// List of hotkey descriptors for pcbnew
+// used in hotkeys_board_editor.cpp
+extern EDA_HOTKEY* board_edit_Hotkey_List[];
+
+// List of hotkey descriptors for the module editor
+// used in hotkeys_module_editor.cpp
+extern EDA_HOTKEY* module_edit_Hotkey_List[];
+
+
+#endif /* _PCBNEW_HOTKEYS_H_ */
diff --git a/pcbnew/hotkeys_board_editor.cpp b/pcbnew/hotkeys_board_editor.cpp
new file mode 100644
index 0000000..3dd119d
--- /dev/null
+++ b/pcbnew/hotkeys_board_editor.cpp
@@ -0,0 +1,1205 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jp.charras@wanadoo.fr
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file hotkeys_board_editor.cpp
+ */
+
+#include <fctsys.h>
+#include <wxPcbStruct.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_pcb_text.h>
+#include <class_mire.h>
+#include <class_drawsegment.h>
+
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <hotkeys.h>
+#include <class_zone.h>
+#include <tool/tool_manager.h>
+
+/* How to add a new hotkey:
+ * see hotkeys.cpp
+ */
+
+
+void PCB_EDIT_FRAME::RecordMacros(wxDC* aDC, int aNumber)
+{
+ wxASSERT( aNumber >= 0 && aNumber < 10 );
+ wxString msg;
+
+ if( m_RecordingMacros < 0 )
+ {
+ m_RecordingMacros = aNumber;
+ m_Macros[aNumber].m_StartPosition = GetCrossHairPosition( false );
+ m_Macros[aNumber].m_Record.clear();
+
+ msg.Printf( _( "Recording macro %d" ), aNumber );
+ SetStatusText( msg );
+ }
+ else
+ {
+ m_RecordingMacros = -1;
+
+ msg.Printf( _( "Macro %d recorded" ), aNumber );
+ SetStatusText( msg );
+ }
+}
+
+
+void PCB_EDIT_FRAME::CallMacros( wxDC* aDC, const wxPoint& aPosition, int aNumber )
+{
+ wxPoint tPosition;
+
+ wxString msg;
+
+ msg.Printf( _( "Call macro %d" ), aNumber );
+ SetStatusText( msg );
+
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+ cmd.SetEventObject( this );
+
+ tPosition = GetNearestGridPosition( aPosition );
+
+ m_canvas->CrossHairOff( aDC );
+ SetMousePosition( tPosition );
+ GeneralControl( aDC, tPosition );
+
+ for( std::list<MACROS_RECORD>::iterator i = m_Macros[aNumber].m_Record.begin();
+ i != m_Macros[aNumber].m_Record.end(); ++i )
+ {
+ wxPoint tmpPos = GetNearestGridPosition( tPosition + i->m_Position );
+
+ SetMousePosition( tmpPos );
+
+ GeneralControl( aDC, tmpPos, i->m_HotkeyCode );
+ }
+
+ cmd.SetId( ID_ZOOM_REDRAW );
+ GetEventHandler()->ProcessEvent( cmd );
+
+ m_canvas->CrossHairOn( aDC );
+}
+
+
+EDA_HOTKEY* PCB_EDIT_FRAME::GetHotKeyDescription( int aCommand ) const
+{
+ EDA_HOTKEY* HK_Descr = GetDescriptorFromCommand( aCommand, common_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ HK_Descr = GetDescriptorFromCommand( aCommand, board_edit_Hotkey_List );
+
+ return HK_Descr;
+}
+
+
+bool PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosition,
+ EDA_ITEM* aItem )
+{
+ if( aHotkeyCode == 0 )
+ return false;
+
+ bool itemCurrentlyEdited = GetCurItem() && GetCurItem()->GetFlags();
+ MODULE* module = NULL;
+ int evt_type = 0; //Used to post a wxCommandEvent on demand
+ PCB_SCREEN* screen = GetScreen();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ /* Convert lower to upper case
+ * (the usual toupper function has problem with non ascii codes like function keys
+ */
+ if( (aHotkeyCode >= 'a') && (aHotkeyCode <= 'z') )
+ aHotkeyCode += 'A' - 'a';
+
+ EDA_HOTKEY* HK_Descr = GetDescriptorFromHotkey( aHotkeyCode, common_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ HK_Descr = GetDescriptorFromHotkey( aHotkeyCode, board_edit_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ return false;
+
+ int hk_id = HK_Descr->m_Idcommand;
+
+ if( (m_RecordingMacros != -1) &&
+ !( hk_id > HK_MACRO_ID_BEGIN && hk_id < HK_MACRO_ID_END) )
+ {
+ MACROS_RECORD macros_record;
+ macros_record.m_HotkeyCode = aHotkeyCode;
+ macros_record.m_Idcommand = HK_Descr->m_Idcommand;
+ macros_record.m_Position = GetNearestGridPosition( aPosition ) -
+ m_Macros[m_RecordingMacros].m_StartPosition;
+ m_Macros[m_RecordingMacros].m_Record.push_back( macros_record );
+ wxString msg;
+ msg.Printf( _( "Add key [%c] in macro %d" ), aHotkeyCode, m_RecordingMacros );
+ SetStatusText( msg );
+ }
+
+ // Create a wxCommandEvent that will be posted in some hot keys functions
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+ cmd.SetEventObject( this );
+
+ LAYER_NUM ll;
+
+ switch( hk_id )
+ {
+ default:
+ case HK_NOT_FOUND:
+ return false;
+
+ case HK_LEFT_CLICK:
+ OnLeftClick( aDC, aPosition );
+ break;
+
+ case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events
+ OnLeftClick( aDC, aPosition );
+ OnLeftDClick( aDC, aPosition );
+ break;
+
+ case HK_RECORD_MACROS_0:
+ case HK_RECORD_MACROS_1:
+ case HK_RECORD_MACROS_2:
+ case HK_RECORD_MACROS_3:
+ case HK_RECORD_MACROS_4:
+ case HK_RECORD_MACROS_5:
+ case HK_RECORD_MACROS_6:
+ case HK_RECORD_MACROS_7:
+ case HK_RECORD_MACROS_8:
+ case HK_RECORD_MACROS_9:
+ RecordMacros( aDC, hk_id - HK_RECORD_MACROS_0 );
+ break;
+
+ case HK_CALL_MACROS_0:
+ case HK_CALL_MACROS_1:
+ case HK_CALL_MACROS_2:
+ case HK_CALL_MACROS_3:
+ case HK_CALL_MACROS_4:
+ case HK_CALL_MACROS_5:
+ case HK_CALL_MACROS_6:
+ case HK_CALL_MACROS_7:
+ case HK_CALL_MACROS_8:
+ case HK_CALL_MACROS_9:
+ CallMacros( aDC, GetCrossHairPosition( false ), hk_id - HK_CALL_MACROS_0 );
+ break;
+
+ case HK_SWITCH_TRACK_WIDTH_TO_NEXT:
+ if( GetCanvas()->IsMouseCaptured() )
+ GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );
+
+ if( GetDesignSettings().GetTrackWidthIndex() < GetDesignSettings().m_TrackWidthList.size() - 1 )
+ GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().GetTrackWidthIndex() + 1 );
+ else
+ GetDesignSettings().SetTrackWidthIndex( 0 );
+
+ if( GetCanvas()->IsMouseCaptured() )
+ GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );
+
+ break;
+
+ case HK_SWITCH_TRACK_WIDTH_TO_PREVIOUS:
+ if( GetCanvas()->IsMouseCaptured() )
+ GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );
+
+ if( GetDesignSettings().GetTrackWidthIndex() <= 0 )
+ GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().m_TrackWidthList.size() -1 );
+ else
+ GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().GetTrackWidthIndex() - 1 );
+
+ if( GetCanvas()->IsMouseCaptured() )
+ GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false );
+
+ break;
+
+ case HK_SWITCH_GRID_TO_FASTGRID1:
+ SetFastGrid1();
+ break;
+
+ case HK_SWITCH_GRID_TO_FASTGRID2:
+ SetFastGrid2();
+ break;
+
+ case HK_SWITCH_GRID_TO_NEXT:
+ SetNextGrid();
+ break;
+
+ case HK_SWITCH_GRID_TO_PREVIOUS:
+ SetPrevGrid();
+ break;
+
+ case HK_SWITCH_LAYER_TO_PREVIOUS:
+ ll = GetActiveLayer();
+
+ if( !IsCopperLayer( ll ) )
+ break;
+
+ if( ll == F_Cu )
+ ll = B_Cu;
+ else if( ll == B_Cu )
+ ll = ToLAYER_ID( GetBoard()->GetCopperLayerCount() - 2 );
+ else
+ ll = ll - 1;
+
+ SwitchLayer( aDC, ToLAYER_ID( ll ) );
+ break;
+
+ case HK_SWITCH_LAYER_TO_NEXT:
+ ll = GetActiveLayer();
+
+ if( !IsCopperLayer( ll ) )
+ break;
+
+ if( ll == B_Cu )
+ ll = F_Cu;
+ else if( ++ll >= GetBoard()->GetCopperLayerCount() - 1 )
+ ll = B_Cu;
+
+ SwitchLayer( aDC, ToLAYER_ID( ll ) );
+ break;
+
+ case HK_SWITCH_LAYER_TO_COMPONENT:
+ SwitchLayer( aDC, F_Cu );
+ break;
+
+ case HK_SWITCH_LAYER_TO_COPPER:
+ SwitchLayer( aDC, B_Cu );
+ break;
+
+ case HK_SWITCH_LAYER_TO_INNER1:
+ SwitchLayer( aDC, In1_Cu );
+ break;
+
+ case HK_SWITCH_LAYER_TO_INNER2:
+ SwitchLayer( aDC, In2_Cu );
+ break;
+
+ case HK_SWITCH_LAYER_TO_INNER3:
+ SwitchLayer( aDC, In3_Cu );
+ break;
+
+ case HK_SWITCH_LAYER_TO_INNER4:
+ SwitchLayer( aDC, In4_Cu );
+ break;
+
+ case HK_SWITCH_LAYER_TO_INNER5:
+ SwitchLayer( aDC, In5_Cu );
+ break;
+
+ case HK_SWITCH_LAYER_TO_INNER6:
+ SwitchLayer( aDC, In6_Cu );
+ break;
+
+ case HK_HELP: // Display Current hotkey list
+ DisplayHotkeyList( this, g_Board_Editor_Hokeys_Descr );
+ break;
+
+ case HK_ZOOM_IN:
+ evt_type = ID_POPUP_ZOOM_IN;
+ break;
+
+ case HK_ZOOM_OUT:
+ evt_type = ID_POPUP_ZOOM_OUT;
+ break;
+
+ case HK_ZOOM_REDRAW:
+ evt_type = ID_ZOOM_REDRAW;
+ break;
+
+ case HK_ZOOM_AUTO:
+ evt_type = ID_ZOOM_PAGE;
+ break;
+
+ case HK_ZOOM_CENTER:
+ evt_type = ID_POPUP_ZOOM_CENTER;
+ break;
+
+ case HK_ADD_MODULE:
+ evt_type = ID_PCB_MODULE_BUTT;
+ break;
+
+ case HK_UNDO:
+ case HK_REDO:
+ if( !itemCurrentlyEdited )
+ {
+ wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent );
+ wxPostEvent( this, event );
+ }
+
+ break;
+
+ case HK_RESET_LOCAL_COORD: // Set the relative coord
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ break;
+
+ case HK_SET_GRID_ORIGIN:
+ SetGridOrigin( GetCrossHairPosition() );
+ OnModify(); // because grid origin is saved in board, show as modified
+ m_canvas->Refresh();
+ break;
+
+ case HK_RESET_GRID_ORIGIN:
+ SetGridOrigin( wxPoint( 0,0 ) );
+ OnModify(); // because grid origin is saved in board, show as modified
+ m_canvas->Refresh();
+ break;
+
+ case HK_SWITCH_UNITS:
+ evt_type = (g_UserUnit == INCHES) ?
+ ID_TB_OPTIONS_SELECT_UNIT_MM : ID_TB_OPTIONS_SELECT_UNIT_INCH;
+ break;
+
+ case HK_SWITCH_TRACK_DISPLAY_MODE:
+ displ_opts->m_DisplayPcbTrackFill = !displ_opts->m_DisplayPcbTrackFill;
+ m_canvas->Refresh();
+ break;
+
+ case HK_DELETE:
+ OnHotkeyDeleteItem( aDC );
+ break;
+
+ case HK_BACK_SPACE:
+ if( IsCopperLayer( GetActiveLayer() ) )
+ {
+ if( !itemCurrentlyEdited )
+ {
+ // no track is currently being edited - select a segment and remove it.
+ // @todo: possibly? pass the HK command code to PcbGeneralLocateAndDisplay()
+ // so it can restrict its search to specific item types.
+ BOARD_ITEM * item = PcbGeneralLocateAndDisplay();
+
+ // don't let backspace delete modules!!
+ if( item && item->IsTrack() )
+ {
+ Delete_Segment( aDC, (TRACK*) item );
+ SetCurItem( NULL );
+ }
+
+ OnModify();
+ }
+ else if( GetCurItem()->IsTrack() )
+ {
+ // then an element is being edited - remove the last segment.
+ // simple lines for debugger:
+ TRACK* track = (TRACK*) GetCurItem();
+ track = Delete_Segment( aDC, track );
+ SetCurItem( track );
+ OnModify();
+ }
+ }
+
+ break;
+
+ case HK_GET_AND_MOVE_FOOTPRINT:
+ if( !itemCurrentlyEdited )
+ evt_type = ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST;
+
+ break;
+
+ case HK_FIND_ITEM:
+ if( !itemCurrentlyEdited )
+ evt_type = ID_FIND_ITEMS;
+
+ break;
+
+ case HK_LOAD_BOARD:
+ if( !itemCurrentlyEdited )
+ evt_type = ID_LOAD_FILE ;
+
+ break;
+
+ case HK_SAVE_BOARD:
+ if( !itemCurrentlyEdited )
+ evt_type = ID_SAVE_BOARD;
+
+ break;
+
+ case HK_ADD_MICROVIA: // Place a micro via if a track is in progress
+ if( GetToolId() != ID_TRACK_BUTT )
+ return true;
+
+ if( !itemCurrentlyEdited ) // no track in progress: nothing to do
+ break;
+
+ if( GetCurItem()->Type() != PCB_TRACE_T ) // Should not occur
+ return true;
+
+ if( !GetCurItem()->IsNew() )
+ return true;
+
+ // place micro via and switch layer
+ if( IsMicroViaAcceptable() )
+ evt_type = ID_POPUP_PCB_PLACE_MICROVIA;
+
+ break;
+
+ case HK_ADD_BLIND_BURIED_VIA:
+ case HK_ADD_THROUGH_VIA: // Switch to alternate layer and Place a via if a track is in progress
+ if( GetBoard()->GetDesignSettings().m_BlindBuriedViaAllowed &&
+ hk_id == HK_ADD_BLIND_BURIED_VIA )
+ GetBoard()->GetDesignSettings().m_CurrentViaType = VIA_BLIND_BURIED;
+ else
+ GetBoard()->GetDesignSettings().m_CurrentViaType = VIA_THROUGH;
+
+ if( !itemCurrentlyEdited ) // no track in progress: switch layer only
+ {
+ Other_Layer_Route( NULL, aDC );
+ if( displ_opts->m_ContrastModeDisplay )
+ m_canvas->Refresh();
+ break;
+ }
+
+ if( GetToolId() != ID_TRACK_BUTT )
+ return true;
+
+ if( GetCurItem()->Type() != PCB_TRACE_T )
+ return true;
+
+ if( !GetCurItem()->IsNew() )
+ return true;
+
+ evt_type = hk_id == HK_ADD_BLIND_BURIED_VIA ?
+ ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA : ID_POPUP_PCB_PLACE_THROUGH_VIA;
+ break;
+
+ case HK_SEL_LAYER_AND_ADD_THROUGH_VIA:
+ case HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA:
+ if( GetCurItem() == NULL || !GetCurItem()->IsNew() ||
+ GetCurItem()->Type() != PCB_TRACE_T )
+ break;
+
+ evt_type = hk_id == HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA ?
+ ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA :
+ ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA;
+ break;
+
+ case HK_SWITCH_TRACK_POSTURE:
+ /* change the position of initial segment when creating new tracks
+ * switch from _/ to -\ .
+ */
+ evt_type = ID_POPUP_PCB_SWITCH_TRACK_POSTURE ;
+ break;
+
+ case HK_DRAG_TRACK_KEEP_SLOPE:
+ OnHotkeyMoveItem( HK_DRAG_TRACK_KEEP_SLOPE );
+ break;
+
+ case HK_PLACE_ITEM:
+ OnHotkeyPlaceItem( aDC );
+ break;
+
+ case HK_ADD_NEW_TRACK: // Start new track, if possible
+ OnHotkeyBeginRoute( aDC );
+ break;
+
+ case HK_EDIT_ITEM: // Edit board item
+ OnHotkeyEditItem( HK_EDIT_ITEM );
+ break;
+
+ case HK_EDIT_MODULE_WITH_MODEDIT: // Edit module with module editor
+ OnHotkeyEditItem( HK_EDIT_MODULE_WITH_MODEDIT );
+ break;
+
+ // Footprint edition:
+ case HK_LOCK_UNLOCK_FOOTPRINT: // toggle module "MODULE_is_LOCKED" status:
+ // get any module, locked or not locked and toggle its locked status
+ if( !itemCurrentlyEdited )
+ {
+ wxPoint pos = RefPos( true );
+ module = GetBoard()->GetFootprint( pos, screen->m_Active_Layer, true );
+ }
+ else if( GetCurItem()->Type() == PCB_MODULE_T )
+ {
+ module = (MODULE*) GetCurItem();
+ }
+
+ if( module )
+ {
+ SetCurItem( module );
+ module->SetLocked( !module->IsLocked() );
+ OnModify();
+ SetMsgPanel( module );
+ }
+ break;
+
+ case HK_DRAG_ITEM: // Start drag module or track segment
+ OnHotkeyMoveItem( HK_DRAG_ITEM );
+ break;
+
+ case HK_MOVE_ITEM: // Start move item
+ OnHotkeyMoveItem( HK_MOVE_ITEM );
+ break;
+
+ case HK_COPY_ITEM:
+ evt_type = OnHotkeyCopyItem();
+ break;
+
+ case HK_ROTATE_ITEM: // Rotation
+ OnHotkeyRotateItem( HK_ROTATE_ITEM );
+ break;
+
+ case HK_FLIP_ITEM:
+ OnHotkeyFlipItem( HK_FLIP_ITEM );
+ break;
+
+ case HK_MOVE_ITEM_EXACT:
+ case HK_DUPLICATE_ITEM:
+ case HK_DUPLICATE_ITEM_AND_INCREMENT:
+ case HK_CREATE_ARRAY:
+ OnHotkeyDuplicateOrArrayItem( HK_Descr->m_Idcommand );
+ break;
+
+ case HK_SWITCH_HIGHCONTRAST_MODE: // switch to high contrast mode and refresh the canvas
+ displ_opts->m_ContrastModeDisplay = !displ_opts->m_ContrastModeDisplay;
+ m_canvas->Refresh();
+ break;
+
+ case HK_CANVAS_CAIRO:
+ evt_type = ID_MENU_CANVAS_CAIRO;
+ break;
+
+ case HK_CANVAS_OPENGL:
+ evt_type = ID_MENU_CANVAS_OPENGL;
+ break;
+
+ case HK_CANVAS_DEFAULT:
+ evt_type = ID_MENU_CANVAS_DEFAULT;
+ break;
+ case HK_ZONE_FILL_OR_REFILL:
+ evt_type = ID_POPUP_PCB_FILL_ALL_ZONES;
+ break;
+ case HK_ZONE_REMOVE_FILLED:
+ evt_type = ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES;
+ break;
+
+ }
+
+ if( evt_type != 0 )
+ {
+ wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
+ evt.SetEventObject( this );
+ evt.SetId( evt_type );
+ GetEventHandler()->ProcessEvent( evt );
+ }
+
+ return true;
+}
+
+
+bool PCB_EDIT_FRAME::OnHotkeyDeleteItem( wxDC* aDC )
+{
+ BOARD_ITEM* item = GetCurItem();
+ bool ItemFree = (item == NULL) || (item->GetFlags() == 0);
+
+ switch( GetToolId() )
+ {
+ case ID_TRACK_BUTT:
+ if( !IsCopperLayer ( GetActiveLayer() ) )
+ return false;
+
+ if( ItemFree )
+ {
+ item = PcbGeneralLocateAndDisplay();
+
+ if( item && !item->IsTrack() )
+ return false;
+
+ Delete_Track( aDC, (TRACK*) item );
+ }
+ else if( item->IsTrack( ) )
+ {
+ // simple lines for debugger:
+ TRACK* track = (TRACK*) item;
+ track = Delete_Segment( aDC, track );
+ SetCurItem( track );
+ OnModify();
+ return true;
+ }
+ break;
+
+ case ID_PCB_MODULE_BUTT:
+ if( ItemFree )
+ {
+ wxPoint pos = RefPos( false );
+ MODULE* module = GetBoard()->GetFootprint( pos, UNDEFINED_LAYER, false );
+
+ if( module == NULL || module->IsLocked() )
+ return false;
+
+ RemoveStruct( module, aDC );
+ }
+ else
+ return false;
+ break;
+
+ default:
+ if( ItemFree )
+ {
+ item = PcbGeneralLocateAndDisplay();
+
+ // Shouldn't there be a check for locked tracks and vias here?
+ if( item == NULL || (item->Type() == PCB_MODULE_T && (MODULE*)item->IsLocked()) )
+ return false;
+
+ RemoveStruct( item, aDC );
+ }
+ else
+ return false;
+ }
+
+ OnModify();
+ SetCurItem( NULL );
+ return true;
+}
+
+
+bool PCB_EDIT_FRAME::OnHotkeyEditItem( int aIdCommand )
+{
+ BOARD_ITEM* item = GetCurItem();
+ bool itemCurrentlyEdited = item && item->GetFlags();
+
+ if( itemCurrentlyEdited )
+ return false;
+
+ item = PcbGeneralLocateAndDisplay();
+
+ if( item == NULL )
+ return false;
+
+ SetCurItem( item );
+
+ int evt_type = 0; //Used to post a wxCommandEvent on demand
+
+ switch( item->Type() )
+ {
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ if( aIdCommand == HK_EDIT_ITEM )
+ {
+ // Be sure the corresponding netclass is selected before edit:
+ SetCurrentNetClass( ( (BOARD_CONNECTED_ITEM*)item )->GetNetClassName() );
+ evt_type = ID_POPUP_PCB_EDIT_TRACKSEG;
+ }
+
+ break;
+
+ case PCB_TEXT_T:
+ if( aIdCommand == HK_EDIT_ITEM )
+ evt_type = ID_POPUP_PCB_EDIT_TEXTEPCB;
+
+ break;
+
+ case PCB_MODULE_T:
+ if( aIdCommand == HK_EDIT_ITEM )
+ evt_type = ID_POPUP_PCB_EDIT_MODULE_PRMS;
+ else if( aIdCommand == HK_EDIT_MODULE_WITH_MODEDIT )
+ evt_type = ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT;
+
+ break;
+
+ case PCB_PAD_T:
+ // Until dec 2012 a EDIT_MODULE event is posted here to prevent pads
+ // from being edited by hotkeys.
+ // Process_Special_Functions takes care of finding the parent.
+ // After dec 2012 a EDIT_PAD event is posted, because there is no
+ // reason to not allow pad edit by hotkey
+ // (pad coordinates are no more modified by rounding, in nanometer version
+ // when using inches or mm in dialog)
+ if( aIdCommand == HK_EDIT_ITEM )
+ evt_type = ID_POPUP_PCB_EDIT_PAD;
+
+ break;
+
+ case PCB_TARGET_T:
+ if( aIdCommand == HK_EDIT_ITEM )
+ evt_type = ID_POPUP_PCB_EDIT_MIRE;
+
+ break;
+
+ case PCB_DIMENSION_T:
+ if( aIdCommand == HK_EDIT_ITEM )
+ evt_type = ID_POPUP_PCB_EDIT_DIMENSION;
+
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ if( aIdCommand == HK_EDIT_ITEM )
+ evt_type = ID_POPUP_PCB_EDIT_TEXTMODULE;
+
+ break;
+
+ case PCB_LINE_T:
+ if( aIdCommand == HK_EDIT_ITEM )
+ evt_type = ID_POPUP_PCB_EDIT_DRAWING;
+
+ break;
+
+ case PCB_ZONE_AREA_T:
+ if( aIdCommand == HK_EDIT_ITEM )
+ evt_type = ID_POPUP_PCB_EDIT_ZONE_PARAMS;
+
+ break;
+
+ default:
+ break;
+ }
+
+ if( evt_type != 0 )
+ {
+ wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
+ evt.SetEventObject( this );
+ evt.SetId( evt_type );
+ GetEventHandler()->ProcessEvent( evt );
+ return true;
+ }
+
+ return false;
+}
+
+
+int PCB_EDIT_FRAME::OnHotkeyCopyItem()
+{
+ BOARD_ITEM* item = GetCurItem();
+ bool itemCurrentlyEdited = item && item->GetFlags();
+
+ if( itemCurrentlyEdited )
+ return 0;
+
+ item = PcbGeneralLocateAndDisplay();
+
+ if( item == NULL )
+ return 0;
+
+ SetCurItem( item );
+
+ int eventId = 0;
+
+ switch( item->Type() )
+ {
+ case PCB_TEXT_T:
+ eventId = ID_POPUP_PCB_COPY_TEXTEPCB;
+ break;
+ default:
+ eventId = 0;
+ break;
+ }
+
+ return eventId;
+}
+
+
+bool PCB_EDIT_FRAME::OnHotkeyMoveItem( int aIdCommand )
+{
+ BOARD_ITEM* item = GetCurItem();
+ bool itemCurrentlyEdited = item && item->GetFlags();
+
+ if( itemCurrentlyEdited )
+ return false;
+
+ item = PcbGeneralLocateAndDisplay();
+
+ if( item == NULL )
+ return false;
+
+ SetCurItem( item );
+
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
+
+ switch( item->Type() )
+ {
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ if( aIdCommand == HK_MOVE_ITEM )
+ evt_type = ID_POPUP_PCB_MOVE_TRACK_NODE;
+
+ if( aIdCommand == HK_DRAG_ITEM )
+ evt_type = ID_POPUP_PCB_DRAG_TRACK_SEGMENT;
+
+ if( aIdCommand == HK_DRAG_TRACK_KEEP_SLOPE )
+ evt_type = ID_POPUP_PCB_DRAG_TRACK_SEGMENT_KEEP_SLOPE;
+
+ break;
+
+ case PCB_MODULE_T:
+ {
+ if( aIdCommand == HK_MOVE_ITEM )
+ evt_type = ID_POPUP_PCB_MOVE_MODULE_REQUEST;
+
+ if( aIdCommand == HK_DRAG_ITEM )
+ evt_type = ID_POPUP_PCB_DRAG_MODULE_REQUEST;
+ }
+ break;
+
+ case PCB_PAD_T:
+ // Post MODULE_REQUEST events here to prevent pads
+ // from being moved or dragged by hotkeys.
+ // Process_Special_Functions takes care of finding
+ // the parent.
+ if( aIdCommand == HK_MOVE_ITEM )
+ evt_type = ID_POPUP_PCB_MOVE_MODULE_REQUEST;
+
+ if( aIdCommand == HK_DRAG_ITEM )
+ evt_type = ID_POPUP_PCB_DRAG_MODULE_REQUEST;
+
+ break;
+
+ case PCB_TEXT_T:
+ if( aIdCommand == HK_MOVE_ITEM )
+ evt_type = ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST;
+
+ break;
+
+ case PCB_TARGET_T:
+ if( aIdCommand == HK_MOVE_ITEM )
+ evt_type = ID_POPUP_PCB_MOVE_MIRE_REQUEST;
+
+ break;
+
+ case PCB_ZONE_AREA_T:
+ if( aIdCommand == HK_MOVE_ITEM )
+ evt_type = ID_POPUP_PCB_MOVE_ZONE_OUTLINES;
+
+ if( aIdCommand == HK_DRAG_ITEM )
+ evt_type = ID_POPUP_PCB_DRAG_ZONE_OUTLINE_SEGMENT;
+
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ if( aIdCommand == HK_MOVE_ITEM )
+ evt_type = ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST;
+
+ break;
+
+ case PCB_LINE_T:
+ if( aIdCommand == HK_MOVE_ITEM )
+ evt_type = ID_POPUP_PCB_MOVE_DRAWING_REQUEST;
+
+ break;
+
+ case PCB_DIMENSION_T:
+ if( aIdCommand == HK_MOVE_ITEM )
+ evt_type = ID_POPUP_PCB_MOVE_TEXT_DIMENSION_REQUEST;
+ break;
+
+ default:
+ break;
+ }
+
+ if( evt_type != 0 )
+ {
+ wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
+ evt.SetEventObject( this );
+ evt.SetId( evt_type );
+ GetEventHandler()->ProcessEvent( evt );
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PCB_EDIT_FRAME::OnHotkeyPlaceItem( wxDC* aDC )
+{
+ BOARD_ITEM* item = GetCurItem();
+ bool no_tool = GetToolId() == ID_NO_TOOL_SELECTED;
+ bool itemCurrentlyEdited = item && item->GetFlags();
+
+ m_canvas->SetAutoPanRequest( false );
+
+ if( itemCurrentlyEdited )
+ {
+ m_canvas->SetIgnoreMouseEvents( true );
+ m_canvas->CrossHairOff( aDC );
+
+ switch( item->Type() )
+ {
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ if( item->IsDragging() )
+ PlaceDraggedOrMovedTrackSegment( static_cast<TRACK*>( item ), aDC );
+
+ break;
+
+ case PCB_TEXT_T:
+ Place_Texte_Pcb( static_cast<TEXTE_PCB*>( item ), aDC );
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ PlaceTexteModule( static_cast<TEXTE_MODULE*>( item ), aDC );
+ break;
+
+ case PCB_PAD_T:
+ PlacePad( static_cast<D_PAD*>( item ), aDC );
+ break;
+
+ case PCB_MODULE_T:
+ PlaceModule( static_cast<MODULE*>( item ), aDC );
+ break;
+
+ case PCB_TARGET_T:
+ PlaceTarget( static_cast<PCB_TARGET*>( item ), aDC );
+ break;
+
+ case PCB_LINE_T:
+ if( no_tool ) // when no tools: existing item moving.
+ Place_DrawItem( static_cast<DRAWSEGMENT*>( item ), aDC );
+
+ break;
+
+ default:
+ break;
+ }
+
+ m_canvas->SetIgnoreMouseEvents( false );
+ m_canvas->CrossHairOn( aDC );
+
+ return true;
+ }
+
+ return false;
+}
+
+
+TRACK * PCB_EDIT_FRAME::OnHotkeyBeginRoute( wxDC* aDC )
+{
+ if( !IsCopperLayer( GetActiveLayer() ) )
+ return NULL;
+
+ bool itemCurrentlyEdited = GetCurItem() && GetCurItem()->GetFlags();
+
+ // Ensure the track tool is active
+ if( GetToolId() != ID_TRACK_BUTT && !itemCurrentlyEdited )
+ {
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+ cmd.SetEventObject( this );
+ cmd.SetId( ID_TRACK_BUTT );
+ GetEventHandler()->ProcessEvent( cmd );
+ }
+
+ if( GetToolId() != ID_TRACK_BUTT )
+ return NULL;
+
+ TRACK* track = NULL;
+
+ if( !itemCurrentlyEdited ) // no track in progress:
+ {
+ track = Begin_Route( NULL, aDC );
+ SetCurItem( track );
+
+ if( track )
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else if( GetCurItem()->IsNew() )
+ {
+ track = Begin_Route( (TRACK*) GetCurItem(), aDC );
+
+ // SetCurItem() must not write to the msg panel
+ // because a track info is displayed while moving the mouse cursor
+ if( track ) // A new segment was created
+ SetCurItem( track, false );
+
+ m_canvas->SetAutoPanRequest( true );
+ }
+
+ return track;
+}
+
+
+bool PCB_EDIT_FRAME::OnHotkeyFlipItem( int aIdCommand )
+{
+ BOARD_ITEM* item = GetCurItem();
+ bool itemCurrentlyEdited = item && item->GetFlags();
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
+
+ wxASSERT( aIdCommand == HK_FLIP_ITEM );
+
+ if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
+ {
+ evt_type = ID_POPUP_FLIP_BLOCK;
+ }
+ else
+ {
+ if( !itemCurrentlyEdited )
+ item = PcbGeneralLocateAndDisplay();
+
+ if( item == NULL )
+ return false;
+
+ SetCurItem( item );
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_T:
+ evt_type = ID_POPUP_PCB_CHANGE_SIDE_MODULE;
+ break;
+
+ case PCB_TEXT_T:
+ evt_type = ID_POPUP_PCB_FLIP_TEXTEPCB;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( evt_type != 0 )
+ {
+ wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
+ evt.SetEventObject( this );
+ evt.SetId( evt_type );
+ GetEventHandler()->ProcessEvent( evt );
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+bool PCB_EDIT_FRAME::OnHotkeyRotateItem( int aIdCommand )
+{
+ BOARD_ITEM* item = GetCurItem();
+ bool itemCurrentlyEdited = item && item->GetFlags();
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
+
+ wxASSERT( aIdCommand == HK_ROTATE_ITEM );
+
+ // Allows block rotate operation on hot key.
+ if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
+ {
+ evt_type = ID_POPUP_ROTATE_BLOCK;
+ }
+ else
+ {
+ if( !itemCurrentlyEdited )
+ item = PcbGeneralLocateAndDisplay();
+
+ if( item == NULL )
+ return false;
+
+ SetCurItem( item );
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_T:
+ evt_type = ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE;
+ break;
+
+ case PCB_TEXT_T:
+ evt_type = ID_POPUP_PCB_ROTATE_TEXTEPCB;
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ evt_type = ID_POPUP_PCB_ROTATE_TEXTMODULE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if( evt_type != 0 )
+ {
+ wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
+ evt.SetEventObject( this );
+ evt.SetId( evt_type );
+ GetEventHandler()->ProcessEvent( evt );
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PCB_EDIT_FRAME::OnHotkeyDuplicateOrArrayItem( int aIdCommand )
+{
+ BOARD_ITEM* item = GetCurItem();
+ bool itemCurrentlyEdited = item && item->GetFlags();
+
+ if( itemCurrentlyEdited )
+ return false;
+
+ item = PcbGeneralLocateAndDisplay();
+
+ if( item == NULL )
+ return false;
+
+ SetCurItem( item );
+
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
+
+ bool canDuplicate = true;
+
+ switch( item->Type() )
+ {
+ // Only handle items we know we can handle
+ case PCB_PAD_T:
+ canDuplicate = false;
+ // no break
+ case PCB_MODULE_T:
+ case PCB_LINE_T:
+ case PCB_TEXT_T:
+ case PCB_TRACE_T:
+ case PCB_ZONE_AREA_T:
+ case PCB_TARGET_T:
+ case PCB_DIMENSION_T:
+ switch( aIdCommand )
+ {
+ case HK_CREATE_ARRAY:
+ if( canDuplicate )
+ evt_type = ID_POPUP_PCB_CREATE_ARRAY;
+ break;
+
+ case HK_DUPLICATE_ITEM_AND_INCREMENT:
+ if( canDuplicate )
+ evt_type = ID_POPUP_PCB_DUPLICATE_ITEM_AND_INCREMENT;
+ break;
+
+ case HK_DUPLICATE_ITEM:
+ if( canDuplicate )
+ evt_type = ID_POPUP_PCB_DUPLICATE_ITEM;
+ break;
+
+ case HK_MOVE_ITEM_EXACT:
+ evt_type = ID_POPUP_PCB_MOVE_EXACT;
+ break;
+
+ default:
+ // We don't handle other commands here
+ break;
+ }
+ break;
+
+ default:
+ wxASSERT_MSG( false, "Unhandled move, duplicate or array for "
+ "object type " + item->Type() );
+ break;
+ }
+
+ return PostCommandMenuEvent( evt_type );
+}
diff --git a/pcbnew/hotkeys_module_editor.cpp b/pcbnew/hotkeys_module_editor.cpp
new file mode 100644
index 0000000..48b0901
--- /dev/null
+++ b/pcbnew/hotkeys_module_editor.cpp
@@ -0,0 +1,416 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file hotkeys_module_editor.cpp
+ */
+
+#include <fctsys.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <module_editor_frame.h>
+#include <pcbnew_id.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <class_board_design_settings.h>
+
+#include <hotkeys.h>
+
+/* How to add a new hotkey:
+ * See hotkeys.cpp
+ */
+
+EDA_HOTKEY* FOOTPRINT_EDIT_FRAME::GetHotKeyDescription( int aCommand ) const
+{
+ EDA_HOTKEY* HK_Descr = GetDescriptorFromCommand( aCommand, common_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ HK_Descr = GetDescriptorFromCommand( aCommand, module_edit_Hotkey_List );
+
+ return HK_Descr;
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
+ EDA_ITEM* aItem )
+{
+ if( aHotKey == 0 )
+ return false;
+
+ bool blockActive = GetScreen()->m_BlockLocate.GetCommand() != BLOCK_IDLE;
+ BOARD_ITEM* item = GetCurItem();
+ bool ItemFree = (item == 0) || (item->GetFlags() == 0);
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+ cmd.SetEventObject( this );
+
+ /* Convert lower to upper case (the usual toupper function has problem with non ascii
+ * codes like function keys */
+ if( (aHotKey >= 'a') && (aHotKey <= 'z') )
+ aHotKey += 'A' - 'a';
+
+ EDA_HOTKEY* HK_Descr = GetDescriptorFromHotkey( aHotKey, common_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ HK_Descr = GetDescriptorFromHotkey( aHotKey, module_edit_Hotkey_List );
+
+ if( HK_Descr == NULL )
+ return false;
+
+ switch( HK_Descr->m_Idcommand )
+ {
+ default:
+ case HK_NOT_FOUND:
+ return false;
+
+ case HK_HELP: // Display Current hotkey list
+ DisplayHotkeyList( this, g_Module_Editor_Hokeys_Descr );
+ break;
+
+ case HK_RESET_LOCAL_COORD: // set local (relative) coordinate origin
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ break;
+
+ case HK_LEFT_CLICK:
+ OnLeftClick( aDC, aPosition );
+ break;
+
+ case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events
+ OnLeftClick( aDC, aPosition );
+ OnLeftDClick( aDC, aPosition );
+ break;
+
+ case HK_SET_GRID_ORIGIN:
+ SetGridOrigin( GetCrossHairPosition() );
+ m_canvas->Refresh();
+ break;
+
+ case HK_RESET_GRID_ORIGIN:
+ SetGridOrigin( wxPoint(0,0) );
+ m_canvas->Refresh();
+ break;
+
+ case HK_SWITCH_UNITS:
+ cmd.SetId( (g_UserUnit == INCHES) ?
+ ID_TB_OPTIONS_SELECT_UNIT_MM : ID_TB_OPTIONS_SELECT_UNIT_INCH );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_IN:
+ cmd.SetId( ID_POPUP_ZOOM_IN );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_OUT:
+ cmd.SetId( ID_POPUP_ZOOM_OUT );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_REDRAW:
+ cmd.SetId( ID_ZOOM_REDRAW );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_ZOOM_CENTER:
+ cmd.SetId( ID_POPUP_ZOOM_CENTER );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_UNDO:
+ case HK_REDO:
+ if( ItemFree && !blockActive )
+ {
+ wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent );
+ wxPostEvent( this, event );
+ }
+ break;
+
+ case HK_ZOOM_AUTO:
+ cmd.SetId( ID_ZOOM_PAGE );
+ GetEventHandler()->ProcessEvent( cmd );
+ break;
+
+ case HK_EDIT_ITEM:
+ OnHotkeyEditItem( HK_EDIT_ITEM );
+ break;
+
+ case HK_DELETE:
+ OnHotkeyDeleteItem( HK_DELETE );
+ break;
+
+ case HK_MOVE_ITEM:
+ OnHotkeyMoveItem( HK_MOVE_ITEM );
+ break;
+
+ case HK_MOVE_ITEM_EXACT:
+ if( blockActive )
+ {
+ cmd.SetId( ID_POPUP_MOVE_BLOCK_EXACT );
+ GetEventHandler()->ProcessEvent( cmd );
+ }
+ else
+ {
+ OnHotkeyMoveItemExact();
+ }
+ break;
+
+ case HK_ROTATE_ITEM:
+ OnHotkeyRotateItem( HK_ROTATE_ITEM );
+ break;
+
+ case HK_DUPLICATE_ITEM:
+ case HK_DUPLICATE_ITEM_AND_INCREMENT:
+ OnHotkeyDuplicateItem( HK_Descr->m_Idcommand );
+ break;
+
+ case HK_CREATE_ARRAY:
+ PostCommandMenuEvent( ID_POPUP_PCB_CREATE_ARRAY );
+ }
+
+ return true;
+}
+
+
+BOARD_ITEM* FOOTPRINT_EDIT_FRAME::PrepareItemForHotkey( bool aFailIfCurrentlyEdited )
+{
+ BOARD_ITEM* item = GetCurItem();
+ bool itemCurrentlyEdited = item && item->GetFlags();
+ bool blockActive = GetScreen()->m_BlockLocate.GetCommand() != BLOCK_IDLE;
+
+ if( aFailIfCurrentlyEdited )
+ {
+ if( itemCurrentlyEdited || blockActive )
+ return NULL;
+
+ item = ModeditLocateAndDisplay();
+ }
+ else
+ {
+ if( blockActive )
+ return NULL;
+
+ if( !itemCurrentlyEdited )
+ item = ModeditLocateAndDisplay();
+ }
+
+ // set item if we can, but don't clear if not
+ if( item )
+ SetCurItem( item );
+
+ return item;
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::OnHotkeyEditItem( int aIdCommand )
+{
+ BOARD_ITEM* item = PrepareItemForHotkey( true );
+
+ if( item == NULL )
+ return false;
+
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_T:
+ if( aIdCommand == HK_EDIT_ITEM )
+ evt_type = ID_POPUP_PCB_EDIT_MODULE_PRMS;
+
+ break;
+
+ case PCB_PAD_T:
+ if( aIdCommand == HK_EDIT_ITEM )
+ evt_type = ID_POPUP_PCB_EDIT_PAD;
+
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ if( aIdCommand == HK_EDIT_ITEM )
+ evt_type = ID_POPUP_PCB_EDIT_TEXTMODULE;
+
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ if( aIdCommand == HK_EDIT_ITEM )
+ evt_type = ID_POPUP_MODEDIT_EDIT_BODY_ITEM;
+
+ break;
+
+ default:
+ break;
+ }
+
+ return PostCommandMenuEvent( evt_type );
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::OnHotkeyDeleteItem( int aIdCommand )
+{
+ BOARD_ITEM* item = PrepareItemForHotkey( true );
+
+ if( item == NULL )
+ return false;
+
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
+
+ switch( item->Type() )
+ {
+ case PCB_PAD_T:
+ if( aIdCommand == HK_DELETE )
+ evt_type = ID_POPUP_PCB_DELETE_PAD;
+
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ if( aIdCommand == HK_DELETE )
+ evt_type = ID_POPUP_PCB_DELETE_TEXTMODULE;
+
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ if( aIdCommand == HK_DELETE )
+ evt_type = ID_POPUP_PCB_DELETE_EDGE;
+
+ break;
+
+ default:
+ break;
+ }
+
+ return PostCommandMenuEvent( evt_type );
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::OnHotkeyMoveItem( int aIdCommand )
+{
+ BOARD_ITEM* item = PrepareItemForHotkey( true );
+
+ if( item == NULL )
+ return false;
+
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
+
+ switch( item->Type() )
+ {
+ case PCB_PAD_T:
+ if( aIdCommand == HK_MOVE_ITEM )
+ evt_type = ID_POPUP_PCB_MOVE_PAD_REQUEST;
+
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ if( aIdCommand == HK_MOVE_ITEM )
+ evt_type = ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST;
+
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ if( aIdCommand == HK_MOVE_ITEM )
+ evt_type = ID_POPUP_PCB_MOVE_EDGE;
+
+ break;
+
+ default:
+ break;
+ }
+
+ return PostCommandMenuEvent( evt_type );
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::OnHotkeyMoveItemExact()
+{
+ BOARD_ITEM* item = PrepareItemForHotkey( false );
+
+ if( item == NULL )
+ return false;
+
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
+
+ switch( item->Type() )
+ {
+ case PCB_PAD_T:
+ case PCB_MODULE_EDGE_T:
+ case PCB_MODULE_TEXT_T:
+ evt_type = ID_POPUP_PCB_MOVE_EXACT;
+ break;
+ default:
+ break;
+ }
+
+ return PostCommandMenuEvent( evt_type );
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::OnHotkeyDuplicateItem( int aIdCommand )
+{
+ BOARD_ITEM* item = PrepareItemForHotkey( true );
+
+ if( item == NULL )
+ return false;
+
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
+
+ switch( item->Type() )
+ {
+ case PCB_PAD_T:
+ case PCB_MODULE_EDGE_T:
+ case PCB_MODULE_TEXT_T:
+ if( aIdCommand == HK_DUPLICATE_ITEM )
+ evt_type = ID_POPUP_PCB_DUPLICATE_ITEM;
+ else
+ evt_type = ID_POPUP_PCB_DUPLICATE_ITEM_AND_INCREMENT;
+
+ break;
+
+ default:
+ break;
+ }
+
+ return PostCommandMenuEvent( evt_type );
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::OnHotkeyRotateItem( int aIdCommand )
+{
+ BOARD_ITEM* item = PrepareItemForHotkey( false );
+
+ if( item == NULL )
+ return false;
+
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ if( aIdCommand == HK_ROTATE_ITEM ) // Rotation
+ evt_type = ID_POPUP_PCB_ROTATE_TEXTMODULE;
+
+ break;
+
+ default:
+ break;
+ }
+
+ return PostCommandMenuEvent( evt_type );
+}
diff --git a/pcbnew/import_dxf/dialog_dxf_import.cpp b/pcbnew/import_dxf/dialog_dxf_import.cpp
new file mode 100644
index 0000000..caf0c77
--- /dev/null
+++ b/pcbnew/import_dxf/dialog_dxf_import.cpp
@@ -0,0 +1,285 @@
+/**
+ * @file dialog_dxf_import.cpp
+ * @brief Dialog to import a dxf file on a given board layer.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <dialog_dxf_import.h>
+#include <kiface_i.h>
+#include <convert_from_iu.h>
+#include <class_pcb_layer_box_selector.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+#include <class_text_mod.h>
+#include <class_pcb_text.h>
+
+// Keys to store setup in config
+#define DXF_IMPORT_LAYER_OPTION_KEY "DxfImportBrdLayer"
+#define DXF_IMPORT_COORD_ORIGIN_KEY "DxfImportCoordOrigin"
+#define DXF_IMPORT_LAST_FILE_KEY "DxfImportLastFile"
+#define DXF_IMPORT_GRID_UNITS_KEY "DxfImportGridUnits"
+#define DXF_IMPORT_GRID_OFFSET_X_KEY "DxfImportGridOffsetX"
+#define DXF_IMPORT_GRID_OFFSET_Y_KEY "DxfImportGridOffsetY"
+
+
+// Static members of DIALOG_DXF_IMPORT, to remember
+// the user's choices during the session
+wxString DIALOG_DXF_IMPORT::m_dxfFilename;
+int DIALOG_DXF_IMPORT::m_offsetSelection = 0;
+LAYER_NUM DIALOG_DXF_IMPORT::m_layer = Dwgs_User;
+
+
+DIALOG_DXF_IMPORT::DIALOG_DXF_IMPORT( PCB_BASE_FRAME* aParent, bool aUseModuleItems )
+ : DIALOG_DXF_IMPORT_BASE( aParent )
+{
+ m_parent = aParent;
+ m_dxfImporter.UseModuleItems( aUseModuleItems );
+ m_config = Kiface().KifaceSettings();
+ m_PCBGridUnits = 0;
+ m_PCBGridOffsetX = 0.0;
+ m_PCBGridOffsetY = 0.0;
+
+ if( m_config )
+ {
+ m_layer = m_config->Read( DXF_IMPORT_LAYER_OPTION_KEY, (long)Dwgs_User );
+ m_offsetSelection = m_config->Read( DXF_IMPORT_COORD_ORIGIN_KEY, (long)0 );
+ m_dxfFilename = m_config->Read( DXF_IMPORT_LAST_FILE_KEY, wxEmptyString );
+ m_config->Read( DXF_IMPORT_GRID_UNITS_KEY, &m_PCBGridUnits, 0 );
+ m_config->Read( DXF_IMPORT_GRID_OFFSET_X_KEY, &m_PCBGridOffsetX, 0.0 );
+ m_config->Read( DXF_IMPORT_GRID_OFFSET_Y_KEY, &m_PCBGridOffsetY, 0.0 );
+ }
+
+ m_DXFPCBGridUnits->SetSelection( m_PCBGridUnits );
+ wxString tmpStr;
+ tmpStr << m_PCBGridOffsetX;
+ m_DXFPCBXCoord->SetValue( tmpStr );
+ tmpStr = "";
+ tmpStr << m_PCBGridOffsetY;
+ m_DXFPCBYCoord->SetValue( tmpStr );
+
+ m_textCtrlFileName->SetValue( m_dxfFilename );
+ m_rbOffsetOption->SetSelection( m_offsetSelection );
+
+ // Configure the layers list selector
+ m_SelLayerBox->SetLayersHotkeys( false ); // Do not display hotkeys
+ m_SelLayerBox->SetLayerSet( LSET::AllCuMask() ); // Do not use copper layers
+ m_SelLayerBox->SetBoardFrame( m_parent );
+ m_SelLayerBox->Resync();
+
+ if( m_SelLayerBox->SetLayerSelection( m_layer ) < 0 )
+ {
+ m_layer = Dwgs_User;
+ m_SelLayerBox->SetLayerSelection( m_layer );
+ }
+
+ m_sdbSizer1OK->SetDefault();
+ GetSizer()->Fit( this );
+ GetSizer()->SetSizeHints( this );
+ Centre();
+}
+
+
+DIALOG_DXF_IMPORT::~DIALOG_DXF_IMPORT()
+{
+ m_offsetSelection = m_rbOffsetOption->GetSelection();
+ m_layer = m_SelLayerBox->GetLayerSelection();
+
+ if( m_config )
+ {
+ m_config->Write( DXF_IMPORT_LAYER_OPTION_KEY, (long)m_layer );
+ m_config->Write( DXF_IMPORT_COORD_ORIGIN_KEY, m_offsetSelection );
+ m_config->Write( DXF_IMPORT_LAST_FILE_KEY, m_dxfFilename );
+
+ m_config->Write( DXF_IMPORT_GRID_UNITS_KEY, GetPCBGridUnits() );
+ m_config->Write( DXF_IMPORT_GRID_OFFSET_X_KEY, m_DXFPCBXCoord->GetValue() );
+ m_config->Write( DXF_IMPORT_GRID_OFFSET_Y_KEY, m_DXFPCBYCoord->GetValue() );
+ }
+}
+
+
+void DIALOG_DXF_IMPORT::OnBrowseDxfFiles( wxCommandEvent& event )
+{
+ wxString path;
+ wxString filename;
+
+ if( !m_dxfFilename.IsEmpty() )
+ {
+ wxFileName fn( m_dxfFilename );
+ path = fn.GetPath();
+ filename = fn.GetFullName();
+ }
+
+ wxFileDialog dlg( m_parent,
+ _( "Open File" ),
+ path, filename,
+ "DXF Files (*.dxf)|*.dxf",
+ wxFD_OPEN|wxFD_FILE_MUST_EXIST );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return;
+
+ wxString fileName = dlg.GetPath();
+
+ if( fileName.IsEmpty() )
+ return;
+
+ m_dxfFilename = fileName;
+ m_textCtrlFileName->SetValue( fileName );
+}
+
+
+void DIALOG_DXF_IMPORT::OnOKClick( wxCommandEvent& event )
+{
+ m_dxfFilename = m_textCtrlFileName->GetValue();
+
+ if( m_dxfFilename.IsEmpty() )
+ return;
+
+ double offsetX = 0;
+ double offsetY = 0;
+
+ m_offsetSelection = m_rbOffsetOption->GetSelection();
+
+ switch( m_offsetSelection )
+ {
+ case 0:
+ offsetX = m_parent->GetPageSizeIU().x * MM_PER_IU / 2;
+ offsetY = m_parent->GetPageSizeIU().y * MM_PER_IU / 2;
+ break;
+
+ case 1:
+ break;
+
+ case 2:
+ offsetY = m_parent->GetPageSizeIU().y * MM_PER_IU / 2;
+ break;
+
+ case 3:
+ offsetY = m_parent->GetPageSizeIU().y * MM_PER_IU;
+ break;
+
+ case 4:
+ GetPCBGridOffsets( offsetX, offsetY );
+
+ if( GetPCBGridUnits() )
+ {
+ offsetX *= 25.4;
+ offsetY *= 25.4;
+ }
+ break;
+ }
+
+ // Set coordinates offset for import (offset is given in mm)
+ m_dxfImporter.SetOffset( offsetX, offsetY );
+ m_layer = m_SelLayerBox->GetLayerSelection();
+ m_dxfImporter.SetBrdLayer( m_layer );
+
+ // Read dxf file:
+ m_dxfImporter.ImportDxfFile( m_dxfFilename );
+
+ EndModal( wxID_OK );
+}
+
+
+bool InvokeDXFDialogBoardImport( PCB_BASE_FRAME* aCaller )
+{
+ DIALOG_DXF_IMPORT dlg( aCaller );
+ bool success = ( dlg.ShowModal() == wxID_OK );
+
+ if( success )
+ {
+ const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems();
+ PICKED_ITEMS_LIST picklist;
+ BOARD* board = aCaller->GetBoard();
+
+ std::list<BOARD_ITEM*>::const_iterator it, itEnd;
+ for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it )
+ {
+ BOARD_ITEM* item = *it;
+ board->Add( item );
+
+ ITEM_PICKER itemWrapper( item, UR_NEW );
+ picklist.PushItem( itemWrapper );
+ }
+
+ aCaller->SaveCopyInUndoList( picklist, UR_NEW, wxPoint( 0, 0 ) );
+ aCaller->OnModify();
+ }
+
+ return success;
+}
+
+
+bool InvokeDXFDialogModuleImport( PCB_BASE_FRAME* aCaller, MODULE* aModule )
+{
+ wxASSERT( aModule );
+
+ DIALOG_DXF_IMPORT dlg( aCaller, true );
+ bool success = ( dlg.ShowModal() == wxID_OK );
+
+ if( success )
+ {
+ const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems();
+
+ aCaller->SaveCopyInUndoList( aModule, UR_MODEDIT );
+ aCaller->OnModify();
+
+ std::list<BOARD_ITEM*>::const_iterator it, itEnd;
+
+ for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it )
+ {
+ aModule->Add( *it );
+ }
+ }
+
+ return success;
+}
+
+
+void DIALOG_DXF_IMPORT::OriginOptionOnUpdateUI( wxUpdateUIEvent& event )
+{
+ bool enable = m_rbOffsetOption->GetSelection() == 4;
+
+ m_DXFPCBGridUnits->Enable( enable );
+ m_DXFPCBXCoord->Enable( enable );
+ m_DXFPCBYCoord->Enable( enable );
+}
+
+
+int DIALOG_DXF_IMPORT::GetPCBGridUnits( void )
+{
+ return m_DXFPCBGridUnits->GetSelection();
+}
+
+
+void DIALOG_DXF_IMPORT::GetPCBGridOffsets( double &aXOffset, double &aYOffset )
+{
+ aXOffset = DoubleValueFromString( UNSCALED_UNITS, m_DXFPCBXCoord->GetValue() );
+ aYOffset = DoubleValueFromString( UNSCALED_UNITS, m_DXFPCBYCoord->GetValue() );
+ return;
+}
diff --git a/pcbnew/import_dxf/dialog_dxf_import.fbp b/pcbnew/import_dxf/dialog_dxf_import.fbp
new file mode 100644
index 0000000..f2f699d
--- /dev/null
+++ b/pcbnew/import_dxf/dialog_dxf_import.fbp
@@ -0,0 +1,1328 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_dxf_import_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">dialog_dxf_import</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size"></property>
+ <property name="name">DIALOG_DXF_IMPORT_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Import DXF File</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerMain</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizerFile</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">File:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText37</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">300,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_textCtrlFileName</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Browse</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonBrowse</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">OnBrowseDxfFiles</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer3</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxRadioBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;Center of page&quot; &quot;Upper left corner of page&quot; &quot;Center left side of page&quot; &quot;Lower left corner of page&quot; &quot;User defined position&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ORIGIN_SELECT</property>
+ <property name="label">Place DXF origin (0,0) point:</property>
+ <property name="majorDimension">1</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_rbOffsetOption</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxRA_SPECIFY_COLS</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRadioBox"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI">OriginOptionOnUpdateUI</event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag"></property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer4</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer6</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">X Position:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText4</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">10</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DXFPCBXCoord</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">DXF origin on PCB Grid, X Coordinate</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NUMERIC</property>
+ <property name="validator_type">wxTextValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0.0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer7</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Y Position:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText5</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength">10</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DXFPCBYCoord</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">DXF origin on PCB Grid, Y Coordinate</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NUMERIC</property>
+ <property name="validator_type">wxTextValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value">0.0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer5</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Units:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticText3</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxChoice" expanded="0">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices">&quot;mm&quot; &quot;inch&quot;</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_DXFPCBGridUnits</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">0</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip">Select PCB grid units</property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnChoice"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer8</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Layer:</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextBrdlayer</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxBitmapComboBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="choices"></property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_SelLayerBox</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="selection">-1</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass">PCB_LAYER_BOX_SELECTOR; class_pcb_layer_box_selector.h</property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCombobox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline8</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer1</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOKClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/import_dxf/dialog_dxf_import.h b/pcbnew/import_dxf/dialog_dxf_import.h
new file mode 100644
index 0000000..91f87de
--- /dev/null
+++ b/pcbnew/import_dxf/dialog_dxf_import.h
@@ -0,0 +1,64 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <dialog_dxf_import_base.h>
+#include <wxPcbStruct.h>
+#include <dxf2brd_items.h>
+
+class DIALOG_DXF_IMPORT : public DIALOG_DXF_IMPORT_BASE
+{
+public:
+ DIALOG_DXF_IMPORT( PCB_BASE_FRAME* aParent, bool aUseModuleItems = false );
+ ~DIALOG_DXF_IMPORT();
+
+ /**
+ * Function GetImportedItems()
+ *
+ * Returns a list of items imported from a DXF file.
+ */
+ const std::list<BOARD_ITEM*>& GetImportedItems() const
+ {
+ return m_dxfImporter.GetItemsList();
+ }
+
+private:
+ PCB_BASE_FRAME* m_parent;
+ wxConfigBase* m_config; // Current config
+ DXF2BRD_CONVERTER m_dxfImporter;
+ int m_PCBGridUnits;
+ double m_PCBGridOffsetX;
+ double m_PCBGridOffsetY;
+
+ static wxString m_dxfFilename;
+ static int m_offsetSelection;
+ static LAYER_NUM m_layer;
+
+ // Virtual event handlers
+ void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ void OnOKClick( wxCommandEvent& event );
+ void OnBrowseDxfFiles( wxCommandEvent& event );
+ void OriginOptionOnUpdateUI( wxUpdateUIEvent& event );
+ int GetPCBGridUnits( void );
+ void GetPCBGridOffsets( double &aXOffset, double &aYOffset );
+};
diff --git a/pcbnew/import_dxf/dialog_dxf_import_base.cpp b/pcbnew/import_dxf/dialog_dxf_import_base.cpp
new file mode 100644
index 0000000..f3ba8e3
--- /dev/null
+++ b/pcbnew/import_dxf/dialog_dxf_import_base.cpp
@@ -0,0 +1,154 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "class_pcb_layer_box_selector.h"
+
+#include "dialog_dxf_import_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_DXF_IMPORT_BASE::DIALOG_DXF_IMPORT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxDefaultSize, wxDefaultSize );
+
+ wxBoxSizer* bSizerMain;
+ bSizerMain = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizerFile;
+ bSizerFile = new wxBoxSizer( wxHORIZONTAL );
+
+ m_staticText37 = new wxStaticText( this, wxID_ANY, _("File:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText37->Wrap( -1 );
+ bSizerFile->Add( m_staticText37, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_textCtrlFileName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_textCtrlFileName->SetMinSize( wxSize( 300,-1 ) );
+
+ bSizerFile->Add( m_textCtrlFileName, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP, 5 );
+
+ m_buttonBrowse = new wxButton( this, wxID_ANY, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizerFile->Add( m_buttonBrowse, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP, 5 );
+
+
+ bSizerMain->Add( bSizerFile, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer3;
+ bSizer3 = new wxBoxSizer( wxHORIZONTAL );
+
+ wxString m_rbOffsetOptionChoices[] = { _("Center of page"), _("Upper left corner of page"), _("Center left side of page"), _("Lower left corner of page"), _("User defined position") };
+ int m_rbOffsetOptionNChoices = sizeof( m_rbOffsetOptionChoices ) / sizeof( wxString );
+ m_rbOffsetOption = new wxRadioBox( this, wxID_ORIGIN_SELECT, _("Place DXF origin (0,0) point:"), wxDefaultPosition, wxDefaultSize, m_rbOffsetOptionNChoices, m_rbOffsetOptionChoices, 1, wxRA_SPECIFY_COLS );
+ m_rbOffsetOption->SetSelection( 0 );
+ bSizer3->Add( m_rbOffsetOption, 0, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizer6;
+ bSizer6 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_staticText4 = new wxStaticText( this, wxID_ANY, _("X Position:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText4->Wrap( -1 );
+ bSizer6->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_DXFPCBXCoord = new wxTextCtrl( this, wxID_ANY, _("0.0"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_DXFPCBXCoord->SetMaxLength( 10 );
+ m_DXFPCBXCoord->SetToolTip( _("DXF origin on PCB Grid, X Coordinate") );
+
+ bSizer6->Add( m_DXFPCBXCoord, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizer4->Add( bSizer6, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer7;
+ bSizer7 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_staticText5 = new wxStaticText( this, wxID_ANY, _("Y Position:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText5->Wrap( -1 );
+ bSizer7->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_DXFPCBYCoord = new wxTextCtrl( this, wxID_ANY, _("0.0"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_DXFPCBYCoord->SetMaxLength( 10 );
+ m_DXFPCBYCoord->SetToolTip( _("DXF origin on PCB Grid, Y Coordinate") );
+
+ bSizer7->Add( m_DXFPCBYCoord, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizer4->Add( bSizer7, 1, wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer5;
+ bSizer5 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_staticText3 = new wxStaticText( this, wxID_ANY, _("Units:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ bSizer5->Add( m_staticText3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxString m_DXFPCBGridUnitsChoices[] = { _("mm"), _("inch") };
+ int m_DXFPCBGridUnitsNChoices = sizeof( m_DXFPCBGridUnitsChoices ) / sizeof( wxString );
+ m_DXFPCBGridUnits = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_DXFPCBGridUnitsNChoices, m_DXFPCBGridUnitsChoices, 0 );
+ m_DXFPCBGridUnits->SetSelection( 0 );
+ m_DXFPCBGridUnits->SetToolTip( _("Select PCB grid units") );
+
+ bSizer5->Add( m_DXFPCBGridUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ bSizer4->Add( bSizer5, 1, wxEXPAND, 5 );
+
+
+ bSizer3->Add( bSizer4, 1, 0, 5 );
+
+
+ bSizerMain->Add( bSizer3, 1, wxALL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer8;
+ bSizer8 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_staticTextBrdlayer = new wxStaticText( this, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextBrdlayer->Wrap( -1 );
+ bSizer8->Add( m_staticTextBrdlayer, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
+
+ m_SelLayerBox = new PCB_LAYER_BOX_SELECTOR( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
+ bSizer8->Add( m_SelLayerBox, 1, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
+
+
+ bSizerMain->Add( bSizer8, 0, wxALL|wxEXPAND, 5 );
+
+ m_staticline8 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bSizerMain->Add( m_staticline8, 0, wxALL|wxEXPAND, 5 );
+
+ m_sdbSizer1 = new wxStdDialogButtonSizer();
+ m_sdbSizer1OK = new wxButton( this, wxID_OK );
+ m_sdbSizer1->AddButton( m_sdbSizer1OK );
+ m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
+ m_sdbSizer1->Realize();
+
+ bSizerMain->Add( m_sdbSizer1, 0, wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
+
+ this->SetSizer( bSizerMain );
+ this->Layout();
+ bSizerMain->Fit( this );
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_buttonBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DXF_IMPORT_BASE::OnBrowseDxfFiles ), NULL, this );
+ m_rbOffsetOption->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_DXF_IMPORT_BASE::OriginOptionOnUpdateUI ), NULL, this );
+ m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DXF_IMPORT_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DXF_IMPORT_BASE::OnOKClick ), NULL, this );
+}
+
+DIALOG_DXF_IMPORT_BASE::~DIALOG_DXF_IMPORT_BASE()
+{
+ // Disconnect Events
+ m_buttonBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DXF_IMPORT_BASE::OnBrowseDxfFiles ), NULL, this );
+ m_rbOffsetOption->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_DXF_IMPORT_BASE::OriginOptionOnUpdateUI ), NULL, this );
+ m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DXF_IMPORT_BASE::OnCancelClick ), NULL, this );
+ m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DXF_IMPORT_BASE::OnOKClick ), NULL, this );
+
+}
diff --git a/pcbnew/import_dxf/dialog_dxf_import_base.h b/pcbnew/import_dxf/dialog_dxf_import_base.h
new file mode 100644
index 0000000..7592d9b
--- /dev/null
+++ b/pcbnew/import_dxf/dialog_dxf_import_base.h
@@ -0,0 +1,77 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 5 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_DXF_IMPORT_BASE_H__
+#define __DIALOG_DXF_IMPORT_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+class PCB_LAYER_BOX_SELECTOR;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/stattext.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/radiobox.h>
+#include <wx/valtext.h>
+#include <wx/choice.h>
+#include <wx/bmpcbox.h>
+#include <wx/statline.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+#define wxID_ORIGIN_SELECT 1000
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_DXF_IMPORT_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_DXF_IMPORT_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText37;
+ wxTextCtrl* m_textCtrlFileName;
+ wxButton* m_buttonBrowse;
+ wxRadioBox* m_rbOffsetOption;
+ wxStaticText* m_staticText4;
+ wxTextCtrl* m_DXFPCBXCoord;
+ wxStaticText* m_staticText5;
+ wxTextCtrl* m_DXFPCBYCoord;
+ wxStaticText* m_staticText3;
+ wxChoice* m_DXFPCBGridUnits;
+ wxStaticText* m_staticTextBrdlayer;
+ PCB_LAYER_BOX_SELECTOR* m_SelLayerBox;
+ wxStaticLine* m_staticline8;
+ wxStdDialogButtonSizer* m_sdbSizer1;
+ wxButton* m_sdbSizer1OK;
+ wxButton* m_sdbSizer1Cancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnBrowseDxfFiles( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OriginOptionOnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_DXF_IMPORT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Import DXF File"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_DXF_IMPORT_BASE();
+
+};
+
+#endif //__DIALOG_DXF_IMPORT_BASE_H__
diff --git a/pcbnew/import_dxf/dxf2brd_items.cpp b/pcbnew/import_dxf/dxf2brd_items.cpp
new file mode 100644
index 0000000..a48f591
--- /dev/null
+++ b/pcbnew/import_dxf/dxf2brd_items.cpp
@@ -0,0 +1,824 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+// The DXF reader lib (libdxfrw) comes from LibreCAD project, a 2D CAD program
+// libdxfrw can be found on http://sourceforge.net/projects/libdxfrw/
+// or (latest sources) on
+// https://github.com/LibreCAD/LibreCAD/tree/master/libraries/libdxfrw/src
+//
+// There is no doc to use it, but have a look to
+// https://github.com/LibreCAD/LibreCAD/blob/master/librecad/src/lib/filters/rs_filterdxf.cpp
+// and https://github.com/LibreCAD/LibreCAD/blob/master/librecad/src/lib/filters/rs_filterdxf.h
+// Each time a dxf entity is read, a "call back" fuction is called
+// like void DXF2BRD_CONVERTER::addLine( const DRW_Line& data ) when a line is read.
+// this function just add the BOARD entity from dxf parameters (start and end point ...)
+
+
+#include "libdxfrw.h"
+#include "dxf2brd_items.h"
+#include <wx/arrstr.h>
+#include <wx/regex.h>
+
+#include <trigo.h>
+#include <macros.h>
+#include <class_board.h>
+#include <class_drawsegment.h>
+#include <class_edge_mod.h>
+#include <class_pcb_text.h>
+#include <convert_from_iu.h>
+#include <class_text_mod.h>
+#include <drw_base.h>
+
+// minimum bulge value before resorting to a line segment;
+// the value 0.0218 is equivalent to about 5 degrees arc,
+#define MIN_BULGE 0.0218
+
+DXF2BRD_CONVERTER::DXF2BRD_CONVERTER() : DRW_Interface()
+{
+ m_xOffset = 0.0; // X coord offset for conversion (in mm)
+ m_yOffset = 0.0; // Y coord offset for conversion (in mm)
+ m_DXF2mm = 1.0; // The scale factor to convert DXF units to mm
+ m_version = 0;
+ m_defaultThickness = 0.1;
+ m_brdLayer = Dwgs_User;
+}
+
+
+DXF2BRD_CONVERTER::~DXF2BRD_CONVERTER()
+{
+}
+
+
+// coordinate conversions from dxf to internal units
+int DXF2BRD_CONVERTER::mapX( double aDxfCoordX )
+{
+ return Millimeter2iu( m_xOffset + ( aDxfCoordX * m_DXF2mm ) );
+}
+
+
+int DXF2BRD_CONVERTER::mapY( double aDxfCoordY )
+{
+ return Millimeter2iu( m_yOffset - ( aDxfCoordY * m_DXF2mm ) );
+}
+
+
+int DXF2BRD_CONVERTER::mapDim( double aDxfValue )
+{
+ return Millimeter2iu( aDxfValue * m_DXF2mm );
+}
+
+
+bool DXF2BRD_CONVERTER::ImportDxfFile( const wxString& aFile )
+{
+ dxfRW* dxf = new dxfRW( aFile.ToUTF8() );
+ bool success = dxf->read( this, true );
+
+ delete dxf;
+
+ return success;
+}
+
+
+void DXF2BRD_CONVERTER::addLayer( const DRW_Layer& aData )
+{
+ // Not yet useful in Pcbnew.
+#if 0
+ wxString name = wxString::FromUTF8( aData.name.c_str() );
+ wxLogMessage( name );
+#endif
+}
+
+
+void DXF2BRD_CONVERTER::addLine( const DRW_Line& aData )
+{
+ DRAWSEGMENT* segm = ( m_useModuleItems ) ?
+ static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT;
+
+ segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
+ wxPoint start( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) );
+ segm->SetStart( start );
+ wxPoint end( mapX( aData.secPoint.x ), mapY( aData.secPoint.y ) );
+ segm->SetEnd( end );
+ segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
+ : aData.thickness ) );
+ m_newItemsList.push_back( segm );
+}
+
+void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& aData )
+{
+ // Currently, Pcbnew does not know polylines, for boards.
+ // So we have to convert a polyline to a set of segments.
+ // Obviously, the z coordinate is ignored
+
+ wxPoint polyline_startpoint;
+ wxPoint segment_startpoint;
+
+ for( unsigned ii = 0; ii < aData.vertlist.size(); ii++ )
+ {
+ DRW_Vertex* vertex = aData.vertlist[ii];
+
+ if( ii == 0 )
+ {
+ segment_startpoint.x = mapX( vertex->basePoint.x );
+ segment_startpoint.y = mapY( vertex->basePoint.y );
+ polyline_startpoint = segment_startpoint;
+ continue;
+ }
+
+ DRAWSEGMENT* segm = ( m_useModuleItems ) ?
+ static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) :
+ new DRAWSEGMENT;
+
+ segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
+ segm->SetStart( segment_startpoint );
+ wxPoint segment_endpoint( mapX( vertex->basePoint.x ), mapY( vertex->basePoint.y ) );
+ segm->SetEnd( segment_endpoint );
+ segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
+ : aData.thickness ) );
+ m_newItemsList.push_back( segm );
+ segment_startpoint = segment_endpoint;
+ }
+
+ // Polyline flags bit 0 indicates closed (1) or open (0) polyline
+ if( aData.flags & 1 )
+ {
+ DRAWSEGMENT* closing_segm = ( m_useModuleItems ) ?
+ static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) :
+ new DRAWSEGMENT;
+
+ closing_segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
+ closing_segm->SetStart( segment_startpoint );
+ closing_segm->SetEnd( polyline_startpoint );
+ closing_segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
+ : aData.thickness ) );
+ m_newItemsList.push_back( closing_segm );
+ }
+}
+
+
+void DXF2BRD_CONVERTER::addLWPolyline(const DRW_LWPolyline& aData )
+{
+ // Currently, Pcbnew does not know polylines, for boards.
+ // So we have to convert a polyline to a set of segments.
+ // The import is a simplified import: the width of segment is
+ // (obviously constant and is the width of the DRW_LWPolyline.
+ // the variable width of each vertex (when exists) is not used.
+ wxRealPoint seg_start;
+ wxRealPoint poly_start;
+ double bulge = 0.0;
+ int lineWidth = mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
+ : aData.thickness );
+
+ for( unsigned ii = 0; ii < aData.vertlist.size(); ii++ )
+ {
+ DRW_Vertex2D* vertex = aData.vertlist[ii];
+
+ if( ii == 0 )
+ {
+ seg_start.x = m_xOffset + vertex->x * m_DXF2mm;
+ seg_start.y = m_yOffset - vertex->y * m_DXF2mm;
+ bulge = vertex->bulge;
+ poly_start = seg_start;
+ continue;
+ }
+
+ wxRealPoint seg_end( m_xOffset + vertex->x * m_DXF2mm, m_yOffset - vertex->y * m_DXF2mm );
+
+ if( std::abs( bulge ) < MIN_BULGE )
+ insertLine( seg_start, seg_end, lineWidth );
+ else
+ insertArc( seg_start, seg_end, bulge, lineWidth );
+
+ bulge = vertex->bulge;
+ seg_start = seg_end;
+ }
+
+ // LWPolyline flags bit 0 indicates closed (1) or open (0) polyline
+ if( aData.flags & 1 )
+ {
+ if( std::abs( bulge ) < MIN_BULGE )
+ insertLine( seg_start, poly_start, lineWidth );
+ else
+ insertArc( seg_start, poly_start, bulge, lineWidth );
+ }
+}
+
+
+void DXF2BRD_CONVERTER::addCircle( const DRW_Circle& aData )
+{
+ DRAWSEGMENT* segm = ( m_useModuleItems ) ?
+ static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT;
+
+ segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
+ segm->SetShape( S_CIRCLE );
+ wxPoint center( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) );
+ segm->SetCenter( center );
+ wxPoint circle_start( mapX( aData.basePoint.x + aData.radious ), mapY( aData.basePoint.y ) );
+ segm->SetArcStart( circle_start );
+ segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
+ : aData.thickness ) );
+ m_newItemsList.push_back( segm );
+}
+
+
+/*
+ * Import Arc entities.
+ */
+void DXF2BRD_CONVERTER::addArc( const DRW_Arc& data )
+{
+ DRAWSEGMENT* segm = ( m_useModuleItems ) ?
+ static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT;
+
+ segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
+ segm->SetShape( S_ARC );
+
+ // Init arc centre:
+ wxPoint center( mapX( data.basePoint.x ), mapY( data.basePoint.y ) );
+ segm->SetCenter( center );
+
+ // Init arc start point
+ double arcStartx = data.radious;
+ double arcStarty = 0;
+ double startangle = data.staangle;
+ double endangle = data.endangle;
+
+ RotatePoint( &arcStartx, &arcStarty, -RAD2DECIDEG( startangle ) );
+ wxPoint arcStart( mapX( arcStartx + data.basePoint.x ),
+ mapY( arcStarty + data.basePoint.y ) );
+ segm->SetArcStart( arcStart );
+
+ // calculate arc angle (arcs are CCW, and should be < 0 in Pcbnew)
+ double angle = -RAD2DECIDEG( endangle - startangle );
+
+ if( angle > 0.0 )
+ angle -= 3600.0;
+
+ segm->SetAngle( angle );
+
+ segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness / m_DXF2mm
+ : data.thickness ) );
+ m_newItemsList.push_back( segm );
+}
+
+
+void DXF2BRD_CONVERTER::addText( const DRW_Text& aData )
+{
+ BOARD_ITEM* brdItem;
+ EDA_TEXT* textItem;
+
+ if( m_useModuleItems )
+ {
+ TEXTE_MODULE* modText = new TEXTE_MODULE( NULL );
+ brdItem = static_cast< BOARD_ITEM* >( modText );
+ textItem = static_cast< EDA_TEXT* >( modText );
+ }
+ else
+ {
+ TEXTE_PCB* pcbText = new TEXTE_PCB( NULL );
+ brdItem = static_cast< BOARD_ITEM* >( pcbText );
+ textItem = static_cast< EDA_TEXT* >( pcbText );
+ }
+
+ brdItem->SetLayer( ToLAYER_ID( m_brdLayer ) );
+
+ wxPoint refPoint( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) );
+ wxPoint secPoint( mapX( aData.secPoint.x ), mapY( aData.secPoint.y ) );
+
+ if( aData.alignV != 0 || aData.alignH != 0 || aData.alignH == DRW_Text::HMiddle )
+ {
+ if( aData.alignH != DRW_Text::HAligned && aData.alignH != DRW_Text::HFit )
+ {
+ wxPoint tmp = secPoint;
+ secPoint = refPoint;
+ refPoint = tmp;
+ }
+ }
+
+ switch( aData.alignV )
+ {
+ case DRW_Text::VBaseLine:
+ textItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+ break;
+
+ case DRW_Text::VBottom:
+ textItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+ break;
+
+ case DRW_Text::VMiddle:
+ textItem->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
+ break;
+
+ case DRW_Text::VTop:
+ textItem->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
+ break;
+ }
+
+ switch( aData.alignH )
+ {
+ case DRW_Text::HLeft:
+ textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ break;
+
+ case DRW_Text::HCenter:
+ textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
+ break;
+
+ case DRW_Text::HRight:
+ textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ break;
+
+ case DRW_Text::HAligned:
+ // no equivalent options in text pcb.
+ textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ break;
+
+ case DRW_Text::HMiddle:
+ // no equivalent options in text pcb.
+ textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
+ break;
+
+ case DRW_Text::HFit:
+ // no equivalent options in text pcb.
+ textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ break;
+ }
+
+#if 0
+ wxString sty = wxString::FromUTF8( aData.style.c_str() );
+ sty = sty.ToLower();
+
+ if( aData.textgen == 2 )
+ {
+ // Text dir = left to right;
+ } else if( aData.textgen == 4 )
+ {
+ // Text dir = top to bottom;
+ } else
+ {
+ }
+#endif
+
+ wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) );
+
+ textItem->SetTextPosition( refPoint );
+ textItem->SetOrientation( aData.angle * 10 );
+
+ // The 0.8 factor gives a better height/width ratio with our font
+ textItem->SetWidth( mapDim( aData.height * 0.8 ) );
+ textItem->SetHeight( mapDim( aData.height ) );
+ textItem->SetThickness( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
+ : aData.thickness ) );
+ textItem->SetText( text );
+
+ m_newItemsList.push_back( static_cast< BOARD_ITEM* >( brdItem ) );
+}
+
+
+void DXF2BRD_CONVERTER::addMText( const DRW_MText& aData )
+{
+ wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) );
+ wxString attrib, tmp;
+
+ /* Some texts start by '\' and have formating chars (font name, font option...)
+ * ending with ';'
+ * Here are some mtext formatting codes:
+ * Format code Purpose
+ * \0...\o Turns overline on and off
+ * \L...\l Turns underline on and off
+ * \~ Inserts a nonbreaking space
+ \\ Inserts a backslash
+ \\\{...\} Inserts an opening and closing brace
+ \\ \File name; Changes to the specified font file
+ \\ \Hvalue; Changes to the text height specified in drawing units
+ \\ \Hvaluex; Changes the text height to a multiple of the current text height
+ \\ \S...^...; Stacks the subsequent text at the \, #, or ^ symbol
+ \\ \Tvalue; Adjusts the space between characters, from.75 to 4 times
+ \\ \Qangle; Changes obliquing angle
+ \\ \Wvalue; Changes width factor to produce wide text
+ \\ \A Sets the alignment value; valid values: 0, 1, 2 (bottom, center, top) while( text.StartsWith( wxT("\\") ) )
+ */
+ while( text.StartsWith( wxT( "\\" ) ) )
+ {
+ attrib << text.BeforeFirst( ';' );
+ tmp = text.AfterFirst( ';' );
+ text = tmp;
+ }
+
+ BOARD_ITEM* brdItem;
+ EDA_TEXT* textItem;
+
+ if( m_useModuleItems )
+ {
+ TEXTE_MODULE* modText = new TEXTE_MODULE( NULL );
+ brdItem = static_cast< BOARD_ITEM* >( modText );
+ textItem = static_cast< EDA_TEXT* >( modText );
+ }
+ else
+ {
+ TEXTE_PCB* pcbText = new TEXTE_PCB( NULL );
+ brdItem = static_cast< BOARD_ITEM* >( pcbText );
+ textItem = static_cast< EDA_TEXT* >( pcbText );
+ }
+
+ brdItem->SetLayer( ToLAYER_ID( m_brdLayer ) );
+ wxPoint textpos( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) );
+
+ textItem->SetTextPosition( textpos );
+ textItem->SetOrientation( aData.angle * 10 );
+
+ // The 0.8 factor gives a better height/width ratio with our font
+ textItem->SetWidth( mapDim( aData.height * 0.8 ) );
+ textItem->SetHeight( mapDim( aData.height ) );
+ textItem->SetThickness( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
+ : aData.thickness ) );
+ textItem->SetText( text );
+
+ // Initialize text justifications:
+ if( aData.textgen <= 3 )
+ {
+ textItem->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
+ }
+ else if( aData.textgen <= 6 )
+ {
+ textItem->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
+ }
+ else
+ {
+ textItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+ }
+
+ if( aData.textgen % 3 == 1 )
+ {
+ textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ }
+ else if( aData.textgen % 3 == 2 )
+ {
+ textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
+ }
+ else
+ {
+ textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ }
+
+#if 0 // These setting have no mening in Pcbnew
+ if( data.alignH == 1 )
+ {
+ // Text is left to right;
+ }
+ else if( data.alignH == 3 )
+ {
+ // Text is top to bottom;
+ }
+ else
+ {
+ // use ByStyle;
+ }
+
+ if( aData.alignV == 1 )
+ {
+ // use AtLeast;
+ }
+ else
+ {
+ // useExact;
+ }
+#endif
+
+ m_newItemsList.push_back( static_cast< BOARD_ITEM* >( brdItem ) );
+}
+
+
+void DXF2BRD_CONVERTER::addHeader( const DRW_Header* data )
+{
+ std::map<std::string, DRW_Variant*>::const_iterator it;
+ m_DXF2mm = 1.0; // assume no scale factor
+
+ for( it = data->vars.begin(); it != data->vars.end(); ++it )
+ {
+ std::string key = ( (*it).first ).c_str();
+
+ if( key == "$DWGCODEPAGE" )
+ {
+ DRW_Variant* var = (*it).second;
+ m_codePage = ( *var->content.s );
+ }
+ else if( key == "$INSUNITS" )
+ {
+ DRW_Variant* var = (*it).second;
+
+ switch( var->content.i )
+ {
+ case 1: // inches
+ m_DXF2mm = 25.4;
+ break;
+
+ case 2: // feet
+ m_DXF2mm = 304.8;
+ break;
+
+ case 5: // centimeters
+ m_DXF2mm = 10.0;
+ break;
+
+ case 6: // meters
+ m_DXF2mm = 1000.0;
+ break;
+
+ case 8: // microinches
+ m_DXF2mm = 2.54e-5;
+ break;
+
+ case 9: // mils
+ m_DXF2mm = 0.0254;
+ break;
+
+ case 10: // yards
+ m_DXF2mm = 914.4;
+ break;
+
+ case 11: // Angstroms
+ m_DXF2mm = 1.0e-7;
+ break;
+
+ case 12: // nanometers
+ m_DXF2mm = 1.0e-6;
+ break;
+
+ case 13: // micrometers
+ m_DXF2mm = 1.0e-3;
+ break;
+
+ case 14: // decimeters
+ m_DXF2mm = 100.0;
+ break;
+
+ default:
+ // use the default of 1.0 for:
+ // 0: Unspecified Units
+ // 4: mm
+ // 3: miles
+ // 7: kilometers
+ // 15: decameters
+ // 16: hectometers
+ // 17: gigameters
+ // 18: AU
+ // 19: lightyears
+ // 20: parsecs
+ break;
+ }
+ }
+ }
+}
+
+
+wxString DXF2BRD_CONVERTER::toDxfString( const wxString& aStr )
+{
+ wxString res;
+ int j = 0;
+
+ for( unsigned i = 0; i<aStr.length(); ++i )
+ {
+ int c = aStr[i];
+
+ if( c > 175 || c < 11 )
+ {
+ res.append( aStr.Mid( j, i - j ) );
+ j = i;
+
+ switch( c )
+ {
+ case 0x0A:
+ res += wxT( "\\P" );
+ break;
+
+ // diameter:
+#ifdef __WINDOWS_
+ // windows, as always, is special.
+ case 0x00D8:
+#else
+ case 0x2205:
+#endif
+ res += wxT( "%%C" );
+ break;
+
+ // degree:
+ case 0x00B0:
+ res += wxT( "%%D" );
+ break;
+
+ // plus/minus
+ case 0x00B1:
+ res += wxT( "%%P" );
+ break;
+
+ default:
+ j--;
+ break;
+ }
+
+ j++;
+ }
+ }
+
+ res.append( aStr.Mid( j ) );
+ return res;
+}
+
+
+wxString DXF2BRD_CONVERTER::toNativeString( const wxString& aData )
+{
+ wxString res;
+
+ // Ignore font tags:
+ int j = 0;
+
+ for( unsigned i = 0; i < aData.length(); ++i )
+ {
+ if( aData[ i ] == 0x7B ) // is '{' ?
+ {
+ if( aData[ i + 1 ] == 0x5c && aData[ i + 2 ] == 0x66 ) // is "\f" ?
+ {
+ // found font tag, append parsed part
+ res.append( aData.Mid( j, i - j ) );
+
+ // skip to ';'
+ for( unsigned k = i + 3; k < aData.length(); ++k )
+ {
+ if( aData[ k ] == 0x3B )
+ {
+ i = j = ++k;
+ break;
+ }
+ }
+
+ // add to '}'
+ for( unsigned k = i; k < aData.length(); ++k )
+ {
+ if( aData[ k ] == 0x7D )
+ {
+ res.append( aData.Mid( i, k - i ) );
+ i = j = ++k;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ res.append( aData.Mid( j ) );
+
+#if 1
+ wxRegEx regexp;
+ // Line feed:
+ regexp.Compile( wxT( "\\\\P" ) );
+ regexp.Replace( &res, wxT( "\n" ) );
+
+ // Space:
+ regexp.Compile( wxT( "\\\\~" ) );
+ regexp.Replace( &res, wxT( " " ) );
+
+ // diameter:
+ regexp.Compile( wxT( "%%[cC]" ) );
+#ifdef __WINDOWS__
+ // windows, as always, is special.
+ regexp.Replace( &res, wxChar( 0xD8 ) );
+#else
+ // Empty_set, diameter is 0x2300
+ regexp.Replace( &res, wxChar( 0x2205 ) );
+#endif
+
+ // degree:
+ regexp.Compile( wxT( "%%[dD]" ) );
+ regexp.Replace( &res, wxChar( 0x00B0 ) );
+ // plus/minus
+ regexp.Compile( wxT( "%%[pP]" ) );
+ regexp.Replace( &res, wxChar( 0x00B1 ) );
+#endif
+
+ return res;
+}
+
+
+void DXF2BRD_CONVERTER::addTextStyle( const DRW_Textstyle& aData )
+{
+ // TODO
+}
+
+
+void DXF2BRD_CONVERTER::insertLine( const wxRealPoint& aSegStart,
+ const wxRealPoint& aSegEnd, int aWidth )
+{
+ DRAWSEGMENT* segm = ( m_useModuleItems ) ?
+ static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT;
+ wxPoint segment_startpoint( Millimeter2iu( aSegStart.x ), Millimeter2iu( aSegStart.y ) );
+ wxPoint segment_endpoint( Millimeter2iu( aSegEnd.x ), Millimeter2iu( aSegEnd.y ) );
+
+ segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
+ segm->SetStart( segment_startpoint );
+ segm->SetEnd( segment_endpoint );
+ segm->SetWidth( aWidth );
+
+ m_newItemsList.push_back( segm );
+ return;
+}
+
+
+void DXF2BRD_CONVERTER::insertArc( const wxRealPoint& aSegStart, const wxRealPoint& aSegEnd,
+ double aBulge, int aWidth )
+{
+ DRAWSEGMENT* segm = ( m_useModuleItems ) ?
+ static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) : new DRAWSEGMENT;
+
+ wxPoint segment_startpoint( Millimeter2iu( aSegStart.x ), Millimeter2iu( aSegStart.y ) );
+ wxPoint segment_endpoint( Millimeter2iu( aSegEnd.x ), Millimeter2iu( aSegEnd.y ) );
+
+ // ensure aBulge represents an angle from +/- ( 0 .. approx 359.8 deg )
+ if( aBulge < -2000.0 )
+ aBulge = -2000.0;
+ else if( aBulge > 2000.0 )
+ aBulge = 2000.0;
+
+ double ang = 4.0 * atan( aBulge );
+
+ // reflect the Y values to put everything in a RHCS
+ wxRealPoint sp( aSegStart.x, -aSegStart.y );
+ wxRealPoint ep( aSegEnd.x, -aSegEnd.y );
+ // angle from end->start
+ double offAng = atan2( ep.y - sp.y, ep.x - sp.x );
+ // length of subtended segment = 1/2 distance between the 2 points
+ double d = 0.5 * sqrt( (sp.x - ep.x) * (sp.x - ep.x) + (sp.y - ep.y) * (sp.y - ep.y) );
+ // midpoint of the subtended segment
+ double xm = ( sp.x + ep.x ) * 0.5;
+ double ym = ( sp.y + ep.y ) * 0.5;
+ double radius = d / sin( ang * 0.5 );
+
+ if( radius < 0.0 )
+ radius = -radius;
+
+ // calculate the height of the triangle with base d and hypotenuse r
+ double dh2 = radius * radius - d * d;
+
+ // this should only ever happen due to rounding errors when r == d
+ if( dh2 < 0.0 )
+ dh2 = 0.0;
+
+ double h = sqrt( dh2 );
+
+ if( ang < 0.0 )
+ offAng -= M_PI_2;
+ else
+ offAng += M_PI_2;
+
+ // for angles greater than 180 deg we need to flip the
+ // direction in which the arc center is found relative
+ // to the midpoint of the subtended segment.
+ if( ang < -M_PI )
+ offAng += M_PI;
+ else if( ang > M_PI )
+ offAng -= M_PI;
+
+ // center point
+ double cx = h * cos( offAng ) + xm;
+ double cy = h * sin( offAng ) + ym;
+
+ segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
+ segm->SetShape( S_ARC );
+ segm->SetCenter( wxPoint( Millimeter2iu( cx ), Millimeter2iu( -cy ) ) );
+
+ if( ang < 0.0 )
+ {
+ segm->SetArcStart( wxPoint( Millimeter2iu( ep.x ), Millimeter2iu( -ep.y ) ) );
+ segm->SetAngle( RAD2DECIDEG( ang ) );
+ }
+ else
+ {
+ segm->SetArcStart( wxPoint( Millimeter2iu( sp.x ), Millimeter2iu( -sp.y ) ) );
+ segm->SetAngle( RAD2DECIDEG( -ang ) );
+ }
+
+ segm->SetWidth( aWidth );
+
+ m_newItemsList.push_back( segm );
+ return;
+}
diff --git a/pcbnew/import_dxf/dxf2brd_items.h b/pcbnew/import_dxf/dxf2brd_items.h
new file mode 100644
index 0000000..7e4f7e9
--- /dev/null
+++ b/pcbnew/import_dxf/dxf2brd_items.h
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** This file comes from the LibreCAD project, a 2D CAD program
+**
+** Copyright (C) 2011 Rallaz, rallazz@gmail.com
+** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
+**
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License as published by the Free Software
+** Foundation either version 2 of the License, or (at your option)
+** any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+**
+**********************************************************************/
+
+
+#ifndef FILTERDXFRW_H
+#define FILTERDXFRW_H
+
+#include "drw_interface.h"
+#include "wx/wx.h"
+#include <list>
+
+class BOARD;
+class BOARD_ITEM;
+
+/**
+ * This format filter class can import and export DXF files.
+ * It depends on the dxflib library.
+ *
+ * @author Rallaz
+ */
+class DXF2BRD_CONVERTER : public DRW_Interface
+{
+private:
+ std::list<BOARD_ITEM*> m_newItemsList; // The list of new items added to the board
+ double m_xOffset; // X coord offset for conversion (in mm)
+ double m_yOffset; // Y coord offset for conversion (in mm)
+ double m_defaultThickness; // default line thickness for conversion (in mm)
+ double m_DXF2mm; // The scale factor to convert DXF units to mm
+ int m_brdLayer; // The board layer to place imported DXF items
+ int m_version; // the dxf version, not used here
+ std::string m_codePage; // The code page, not used here
+ bool m_useModuleItems; // Use module items instead of board items when true.
+
+public:
+ DXF2BRD_CONVERTER();
+ ~DXF2BRD_CONVERTER();
+
+ bool IsUsingModuleItems() const { return m_useModuleItems; }
+ void UseModuleItems( bool aUseModuleItems = true ) { m_useModuleItems = aUseModuleItems; }
+
+ /**
+ * Set the coordinate offset between the importede dxf items
+ * and Pcbnew.
+ * because dxf files have the Y axis from bottom to top;
+ * aOffsetX = 0, and aOffsetY = - vertical page size to import a full page
+ * @param aOffsetX = the X offset in mm
+ * @param aOffsetY = the Y offset in mm
+ */
+ void SetOffset( double aOffsetX, double aOffsetY )
+ {
+ m_xOffset = aOffsetX;
+ m_yOffset = aOffsetY;
+ }
+
+ /**
+ * Set the layer number to import dxf items.
+ * the layer should be a techicanl layer, not a copper layer
+ */
+ void SetBrdLayer( int aBrdLayer ) { m_brdLayer = aBrdLayer; }
+
+ /**
+ * Implementation of the method used for communicate
+ * with this filter.
+ *
+ * @param aFile = the full filename.
+ */
+ bool ImportDxfFile( const wxString& aFile );
+
+ /**
+ * @return the list of new BOARD_ITEM
+ */
+ const std::list<BOARD_ITEM*>& GetItemsList() const
+ {
+ return m_newItemsList;
+ }
+
+private:
+ // coordinate conversions from dxf to internal units
+ int mapX( double aDxfCoordX );
+ int mapY( double aDxfCoordY );
+ int mapDim( double aDxfValue );
+
+ // Functions to aid in the creation of a LWPolyline
+ void insertLine( const wxRealPoint& aSegStart, const wxRealPoint& aSegEnd, int aWidth );
+ void insertArc( const wxRealPoint& aSegStart, const wxRealPoint& aSegEnd,
+ double aBulge, int aWidth );
+
+ // Methods from DRW_CreationInterface:
+ // They are "call back" fonctions, called when the corresponding object
+ // is read in dxf file
+ // Depending of the application, they can do something or not
+ virtual void addHeader( const DRW_Header* aData );
+ virtual void addLType( const DRW_LType& aData ) {}
+ virtual void addLayer( const DRW_Layer& aData );
+ virtual void addDimStyle( const DRW_Dimstyle& aData ) {}
+ virtual void addBlock( const DRW_Block& aData ) {}
+ virtual void endBlock() {}
+ virtual void addPoint( const DRW_Point& aData ) {}
+ virtual void addLine( const DRW_Line& aData);
+ virtual void addRay( const DRW_Ray& aData ) {}
+ virtual void addXline( const DRW_Xline& aData ) {}
+ virtual void addCircle( const DRW_Circle& aData );
+ virtual void addArc( const DRW_Arc& aData );
+ virtual void addEllipse( const DRW_Ellipse& aData ) {}
+ virtual void addLWPolyline( const DRW_LWPolyline& aData );
+ virtual void addText( const DRW_Text& aData );
+ virtual void addPolyline( const DRW_Polyline& aData );
+ virtual void addSpline( const DRW_Spline* aData ) {}
+ virtual void addKnot( const DRW_Entity&) {}
+ virtual void addInsert( const DRW_Insert& aData ){}
+ virtual void addTrace( const DRW_Trace& aData ){}
+ virtual void addSolid( const DRW_Solid& aData ){}
+ virtual void addMText( const DRW_MText& aData);
+ virtual void addDimAlign( const DRW_DimAligned* aData ) {}
+ virtual void addDimLinear( const DRW_DimLinear* aData ) {}
+ virtual void addDimRadial( const DRW_DimRadial* aData ) {}
+ virtual void addDimDiametric( const DRW_DimDiametric* aData ) {}
+ virtual void addDimAngular( const DRW_DimAngular* aData ) {}
+ virtual void addDimAngular3P( const DRW_DimAngular3p* aData ) {}
+ virtual void addDimOrdinate( const DRW_DimOrdinate* aData ) {}
+ virtual void addLeader( const DRW_Leader* aData ) {}
+ virtual void addHatch( const DRW_Hatch* aData ) {}
+ virtual void addImage( const DRW_Image* aData ) {}
+ virtual void linkImage( const DRW_ImageDef* aData ) {}
+
+ virtual void add3dFace( const DRW_3Dface& aData ) {}
+ virtual void addComment( const char*) {}
+
+ virtual void addVport( const DRW_Vport& aData ) {}
+
+ virtual void addTextStyle( const DRW_Textstyle& aData );
+
+ virtual void addViewport( const DRW_Viewport& aData ) {}
+
+ virtual void setBlock( const int aHandle ) {}
+
+ /**
+ * Converts a native unicode string into a DXF encoded string.
+ *
+ * DXF endoding includes the following special sequences:
+ * - %%%c for a diameter sign
+ * - %%%d for a degree sign
+ * - %%%p for a plus/minus sign
+ */
+ static wxString toDxfString( const wxString& aStr );
+
+ /**
+ * Converts a DXF encoded string into a native Unicode string.
+ */
+ static wxString toNativeString( const wxString& aData );
+
+ // These functions are not used in Kicad.
+ // But because they are virtual pure in DRW_Interface, they should be defined
+ virtual void writeTextstyles() {}
+ virtual void writeVports() {}
+ virtual void writeHeader( DRW_Header& aData ) {}
+ virtual void writeEntities() {}
+ virtual void writeLTypes() {}
+ virtual void writeLayers() {}
+ virtual void writeBlockRecords() {}
+ virtual void writeBlocks() {}
+ virtual void writeDimstyles() {}
+
+ void writeLine();
+ void writeMtext();
+
+ virtual void addAppId( const DRW_AppId& data ) {}
+ virtual void writeAppId() {}
+};
+
+#endif // FILTERDXFRW_H
diff --git a/pcbnew/import_dxf/examples/basic_ellipses.dxf b/pcbnew/import_dxf/examples/basic_ellipses.dxf
new file mode 100644
index 0000000..8b0bb14
--- /dev/null
+++ b/pcbnew/import_dxf/examples/basic_ellipses.dxf
@@ -0,0 +1,2992 @@
+999
+dxfrw 0.5.13
+0
+SECTION
+2
+HEADER
+9
+$ACADVER
+1
+AC1009
+9
+$DWGCODEPAGE
+3
+ANSI_1252
+9
+$INSBASE
+10
+0
+20
+0
+30
+0
+9
+$EXTMIN
+10
+0
+20
+0
+30
+0
+9
+$EXTMAX
+10
+286.021046008
+20
+141.572897408
+30
+0
+9
+$LIMMIN
+10
+0
+20
+0
+9
+$LIMMAX
+10
+420
+20
+297
+9
+$ORTHOMODE
+70
+0
+9
+$LTSCALE
+40
+1
+9
+$TEXTSTYLE
+7
+STANDARD
+9
+$CLAYER
+8
+0
+9
+$DIMASZ
+40
+2.5
+9
+$DIMLFAC
+40
+1
+9
+$DIMSCALE
+40
+1
+9
+$DIMEXO
+40
+0.625
+9
+$DIMEXE
+40
+1.25
+9
+$DIMTXT
+40
+2.5
+9
+$DIMTSZ
+40
+0
+9
+$DIMUNIT
+70
+2
+9
+$DIMSTYLE
+2
+STANDARD
+9
+$DIMGAP
+40
+0.625
+9
+$DIMTIH
+70
+0
+9
+$LUNITS
+70
+2
+9
+$LUPREC
+70
+4
+9
+$AUNITS
+70
+0
+9
+$AUPREC
+70
+2
+9
+$SNAPSTYLE
+70
+0
+9
+$PLIMMIN
+10
+0
+20
+0
+9
+$PLIMMAX
+10
+841
+20
+594
+0
+ENDSEC
+0
+SECTION
+2
+CLASSES
+0
+ENDSEC
+0
+SECTION
+2
+TABLES
+0
+TABLE
+2
+VPORT
+70
+1
+0
+VPORT
+2
+*ACTIVE
+70
+0
+10
+0
+20
+0
+11
+1
+21
+1
+12
+190.125
+22
+76.75
+13
+0
+23
+0
+14
+10
+24
+10
+15
+10
+25
+10
+16
+0
+26
+0
+36
+1
+17
+0
+27
+0
+37
+0
+40
+166
+41
+2.36596385542
+42
+50
+43
+0
+44
+0
+50
+0
+51
+0
+71
+0
+72
+100
+73
+1
+74
+3
+75
+0
+76
+1
+77
+0
+78
+0
+0
+ENDTAB
+0
+TABLE
+2
+LTYPE
+70
+4
+0
+LTYPE
+2
+BYBLOCK
+70
+0
+3
+
+72
+65
+73
+0
+40
+0
+0
+LTYPE
+2
+BYLAYER
+70
+0
+3
+
+72
+65
+73
+0
+40
+0
+0
+LTYPE
+2
+CONTINUOUS
+70
+0
+3
+Solid line
+72
+65
+73
+0
+40
+0
+0
+LTYPE
+2
+DOT
+70
+0
+3
+Dot . . . . . . . . . . . . . . . . . . . . . .
+72
+65
+73
+2
+40
+6.35
+49
+0
+49
+-6.35
+0
+LTYPE
+2
+DOT2
+70
+0
+3
+Dot (.5x) .....................................
+72
+65
+73
+2
+40
+3.175
+49
+0
+49
+-3.175
+0
+LTYPE
+2
+DOTX2
+70
+0
+3
+Dot (2x) . . . . . . . . . . . . .
+72
+65
+73
+2
+40
+12.7
+49
+0
+49
+-12.7
+0
+LTYPE
+2
+DASHED
+70
+0
+3
+Dot . . . . . . . . . . . . . . . . . . . . . .
+72
+65
+73
+2
+40
+19.05
+49
+12.7
+49
+-6.35
+0
+LTYPE
+2
+DASHED2
+70
+0
+3
+Dashed (.5x) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+72
+65
+73
+2
+40
+9.525
+49
+6.35
+49
+-3.175
+0
+LTYPE
+2
+DASHEDX2
+70
+0
+3
+Dashed (2x) ____ ____ ____ ____ ____ ___
+72
+65
+73
+2
+40
+38.1
+49
+25.4
+49
+-12.7
+0
+LTYPE
+2
+DASHDOT
+70
+0
+3
+Dash dot __ . __ . __ . __ . __ . __ . __ . __
+72
+65
+73
+4
+40
+25.4
+49
+12.7
+49
+-6.35
+49
+0
+49
+-6.35
+0
+LTYPE
+2
+DASHDOT2
+70
+0
+3
+Dash dot (.5x) _._._._._._._._._._._._._._._.
+72
+65
+73
+4
+40
+12.7
+49
+6.35
+49
+-3.175
+49
+0
+49
+-3.175
+0
+LTYPE
+2
+DASHDOTX2
+70
+0
+3
+Dash dot (2x) ____ . ____ . ____ . ___
+72
+65
+73
+4
+40
+50.8
+49
+25.4
+49
+-12.7
+49
+0
+49
+-12.7
+0
+LTYPE
+2
+DIVIDE
+70
+0
+3
+Divide ____ . . ____ . . ____ . . ____ . . ____
+72
+65
+73
+6
+40
+31.75
+49
+12.7
+49
+-6.35
+49
+0
+49
+-6.35
+49
+0
+49
+-6.35
+0
+LTYPE
+2
+DIVIDE2
+70
+0
+3
+Divide (.5x) __..__..__..__..__..__..__..__.._
+72
+65
+73
+6
+40
+15.875
+49
+6.35
+49
+-3.175
+49
+0
+49
+-3.175
+49
+0
+49
+-3.175
+0
+LTYPE
+2
+DIVIDEX2
+70
+0
+3
+Divide (2x) ________ . . ________ . . _
+72
+65
+73
+6
+40
+63.5
+49
+25.4
+49
+-12.7
+49
+0
+49
+-12.7
+49
+0
+49
+-12.7
+0
+LTYPE
+2
+BORDER
+70
+0
+3
+Border __ __ . __ __ . __ __ . __ __ . __ __ .
+72
+65
+73
+6
+40
+44.45
+49
+12.7
+49
+-6.35
+49
+12.7
+49
+-6.35
+49
+0
+49
+-6.35
+0
+LTYPE
+2
+BORDER2
+70
+0
+3
+Border (.5x) __.__.__.__.__.__.__.__.__.__.__.
+72
+65
+73
+6
+40
+22.225
+49
+6.35
+49
+-3.175
+49
+6.35
+49
+-3.175
+49
+0
+49
+-3.175
+0
+LTYPE
+2
+BORDERX2
+70
+0
+3
+Border (2x) ____ ____ . ____ ____ . ___
+72
+65
+73
+6
+40
+88.9
+49
+25.4
+49
+-12.7
+49
+25.4
+49
+-12.7
+49
+0
+49
+-12.7
+0
+LTYPE
+2
+CENTER
+70
+0
+3
+Center ____ _ ____ _ ____ _ ____ _ ____ _ ____
+72
+65
+73
+4
+40
+50.8
+49
+31.75
+49
+-6.35
+49
+6.35
+49
+-6.35
+0
+LTYPE
+2
+CENTER2
+70
+0
+3
+Center (.5x) ___ _ ___ _ ___ _ ___ _ ___ _ ___
+72
+65
+73
+4
+40
+28.575
+49
+19.05
+49
+-3.175
+49
+3.175
+49
+-3.175
+0
+LTYPE
+2
+CENTERX2
+70
+0
+3
+Center (2x) ________ __ ________ __ _____
+72
+65
+73
+4
+40
+101.6
+49
+63.5
+49
+-12.7
+49
+12.7
+49
+-12.7
+0
+ENDTAB
+0
+TABLE
+2
+LAYER
+70
+1
+0
+LAYER
+2
+0
+70
+0
+62
+7
+6
+CONTINUOUS
+0
+ENDTAB
+0
+TABLE
+2
+STYLE
+70
+3
+0
+STYLE
+2
+STANDARD
+70
+0
+40
+0
+41
+1
+50
+0
+71
+0
+42
+1
+3
+TXT
+4
+
+0
+ENDTAB
+0
+TABLE
+2
+VIEW
+70
+0
+0
+ENDTAB
+0
+TABLE
+2
+UCS
+70
+0
+0
+ENDTAB
+0
+TABLE
+2
+APPID
+70
+1
+0
+APPID
+2
+ACAD
+70
+0
+0
+APPID
+2
+LIBRECAD
+70
+0
+0
+ENDTAB
+0
+TABLE
+2
+DIMSTYLE
+70
+1
+0
+DIMSTYLE
+2
+STANDARD
+70
+0
+3
+
+4
+
+5
+
+6
+
+7
+
+40
+1
+41
+2.5
+42
+0.625
+43
+0.38
+44
+1.25
+45
+0
+46
+0
+47
+0
+48
+0
+140
+2.5
+141
+0.09
+142
+0
+143
+25.4
+144
+1
+145
+0
+146
+1
+147
+0.625
+71
+0
+72
+0
+73
+0
+74
+1
+75
+0
+76
+0
+77
+0
+78
+0
+170
+0
+171
+2
+172
+0
+173
+0
+174
+0
+175
+0
+176
+0
+177
+0
+178
+0
+0
+ENDTAB
+0
+ENDSEC
+0
+SECTION
+2
+BLOCKS
+0
+BLOCK
+8
+0
+2
+$MODEL_SPACE
+70
+0
+10
+0
+20
+0
+30
+0
+3
+$MODEL_SPACE
+1
+
+0
+ENDBLK
+8
+0
+0
+BLOCK
+8
+0
+2
+$PAPER_SPACE
+70
+0
+10
+0
+20
+0
+30
+0
+3
+$PAPER_SPACE
+1
+
+0
+ENDBLK
+8
+0
+0
+ENDSEC
+0
+SECTION
+2
+ENTITIES
+0
+POLYLINE
+5
+31
+8
+0
+6
+BYLAYER
+62
+256
+66
+1
+10
+0
+20
+0
+30
+0
+70
+1
+0
+VERTEX
+5
+32
+8
+0
+6
+BYLAYER
+62
+256
+10
+114.5
+20
+76.5
+30
+0
+0
+VERTEX
+5
+33
+8
+0
+6
+BYLAYER
+62
+256
+10
+115.06685415
+20
+74.8221771035
+30
+0
+0
+VERTEX
+5
+34
+8
+0
+6
+BYLAYER
+62
+256
+10
+115.838319688
+20
+73.2044075157
+30
+0
+0
+VERTEX
+5
+35
+8
+0
+6
+BYLAYER
+62
+256
+10
+116.812538085
+20
+71.6505885853
+30
+0
+0
+VERTEX
+5
+36
+8
+0
+6
+BYLAYER
+62
+256
+10
+117.987162364
+20
+70.1644635983
+30
+0
+0
+VERTEX
+5
+37
+8
+0
+6
+BYLAYER
+62
+256
+10
+119.359362753
+20
+68.7496127599
+30
+0
+0
+VERTEX
+5
+38
+8
+0
+6
+BYLAYER
+62
+256
+10
+120.9258335
+20
+67.4094445696
+30
+0
+0
+VERTEX
+5
+39
+8
+0
+6
+BYLAYER
+62
+256
+10
+122.68280084
+20
+66.14718761
+30
+0
+0
+VERTEX
+5
+3A
+8
+0
+6
+BYLAYER
+62
+256
+10
+124.626032085
+20
+64.9658827688
+30
+0
+0
+VERTEX
+5
+3B
+8
+0
+6
+BYLAYER
+62
+256
+10
+126.750845821
+20
+63.8683759127
+30
+0
+0
+VERTEX
+5
+3C
+8
+0
+6
+BYLAYER
+62
+256
+10
+129.052123185
+20
+62.8573110318
+30
+0
+0
+VERTEX
+5
+3D
+8
+0
+6
+BYLAYER
+62
+256
+10
+131.524320199
+20
+61.9351238702
+30
+0
+0
+VERTEX
+5
+3E
+8
+0
+6
+BYLAYER
+62
+256
+10
+134.161481123
+20
+61.1040360573
+30
+0
+0
+VERTEX
+5
+3F
+8
+0
+6
+BYLAYER
+62
+256
+10
+136.957252806
+20
+60.3660497565
+30
+0
+0
+VERTEX
+5
+40
+8
+0
+6
+BYLAYER
+62
+256
+10
+139.904899989
+20
+59.7229428415
+30
+0
+0
+VERTEX
+5
+41
+8
+0
+6
+BYLAYER
+62
+256
+10
+142.997321531
+20
+59.1762646132
+30
+0
+0
+VERTEX
+5
+42
+8
+0
+6
+BYLAYER
+62
+256
+10
+146.227067519
+20
+58.7273320672
+30
+0
+0
+VERTEX
+5
+43
+8
+0
+6
+BYLAYER
+62
+256
+10
+149.586357211
+20
+58.3772267214
+30
+0
+0
+VERTEX
+5
+44
+8
+0
+6
+BYLAYER
+62
+256
+10
+153.067097784
+20
+58.1267920103
+30
+0
+0
+VERTEX
+5
+45
+8
+0
+6
+BYLAYER
+62
+256
+10
+156.660903829
+20
+57.9766312531
+30
+0
+0
+VERTEX
+5
+46
+8
+0
+6
+BYLAYER
+62
+256
+10
+160.359117554
+20
+57.9271062
+30
+0
+0
+VERTEX
+5
+47
+8
+0
+6
+BYLAYER
+62
+256
+10
+164.152829636
+20
+57.9783361613
+30
+0
+0
+VERTEX
+5
+48
+8
+0
+6
+BYLAYER
+62
+256
+10
+168.032900691
+20
+58.1301977196
+30
+0
+0
+VERTEX
+5
+49
+8
+0
+6
+BYLAYER
+62
+256
+10
+171.989983289
+20
+58.3823250271
+30
+0
+0
+VERTEX
+5
+4A
+8
+0
+6
+BYLAYER
+62
+256
+10
+176.01454447
+20
+58.734110687
+30
+0
+0
+VERTEX
+5
+4B
+8
+0
+6
+BYLAYER
+62
+256
+10
+180.096888714
+20
+59.1847072167
+30
+0
+0
+VERTEX
+5
+4C
+8
+0
+6
+BYLAYER
+62
+256
+10
+184.227181297
+20
+59.7330290899
+30
+0
+0
+VERTEX
+5
+4D
+8
+0
+6
+BYLAYER
+62
+256
+10
+188.395471982
+20
+60.3777553511
+30
+0
+0
+VERTEX
+5
+4E
+8
+0
+6
+BYLAYER
+62
+256
+10
+192.591718991
+20
+61.1173327983
+30
+0
+0
+VERTEX
+5
+4F
+8
+0
+6
+BYLAYER
+62
+256
+10
+196.805813198
+20
+61.9499797245
+30
+0
+0
+VERTEX
+5
+50
+8
+0
+6
+BYLAYER
+62
+256
+10
+201.027602481
+20
+62.8736902105
+30
+0
+0
+VERTEX
+5
+51
+8
+0
+6
+BYLAYER
+62
+256
+10
+205.246916179
+20
+63.8862389568
+30
+0
+0
+VERTEX
+5
+52
+8
+0
+6
+BYLAYER
+62
+256
+10
+209.453589597
+20
+64.9851866447
+30
+0
+0
+VERTEX
+5
+53
+8
+0
+6
+BYLAYER
+62
+256
+10
+213.637488489
+20
+66.167885813
+30
+0
+0
+VERTEX
+5
+54
+8
+0
+6
+BYLAYER
+62
+256
+10
+217.788533477
+20
+67.4314872359
+30
+0
+0
+VERTEX
+5
+55
+8
+0
+6
+BYLAYER
+62
+256
+10
+221.89672433
+20
+68.7729467867
+30
+0
+0
+VERTEX
+5
+56
+8
+0
+6
+BYLAYER
+62
+256
+10
+225.952164056
+20
+70.189032772
+30
+0
+0
+VERTEX
+5
+57
+8
+0
+6
+BYLAYER
+62
+256
+10
+229.945082745
+20
+71.6763337166
+30
+0
+0
+VERTEX
+5
+58
+8
+0
+6
+BYLAYER
+62
+256
+10
+233.865861108
+20
+73.2312665823
+30
+0
+0
+VERTEX
+5
+59
+8
+0
+6
+BYLAYER
+62
+256
+10
+237.705053644
+20
+74.8500853995
+30
+0
+0
+VERTEX
+5
+5A
+8
+0
+6
+BYLAYER
+62
+256
+10
+241.453411404
+20
+76.5288902919
+30
+0
+0
+VERTEX
+5
+5B
+8
+0
+6
+BYLAYER
+62
+256
+10
+245.101904265
+20
+78.2636368716
+30
+0
+0
+VERTEX
+5
+5C
+8
+0
+6
+BYLAYER
+62
+256
+10
+248.641742688
+20
+80.0501459821
+30
+0
+0
+VERTEX
+5
+5D
+8
+0
+6
+BYLAYER
+62
+256
+10
+252.064398893
+20
+81.8841137663
+30
+0
+0
+VERTEX
+5
+5E
+8
+0
+6
+BYLAYER
+62
+256
+10
+255.3616274
+20
+83.7611220354
+30
+0
+0
+VERTEX
+5
+5F
+8
+0
+6
+BYLAYER
+62
+256
+10
+258.525484898
+20
+85.6766489119
+30
+0
+0
+VERTEX
+5
+60
+8
+0
+6
+BYLAYER
+62
+256
+10
+261.548349376
+20
+87.6260797239
+30
+0
+0
+VERTEX
+5
+61
+8
+0
+6
+BYLAYER
+62
+256
+10
+264.42293849
+20
+89.6047181218
+30
+0
+0
+VERTEX
+5
+62
+8
+0
+6
+BYLAYER
+62
+256
+10
+267.142327102
+20
+91.6077973924
+30
+0
+0
+VERTEX
+5
+63
+8
+0
+6
+BYLAYER
+62
+256
+10
+269.699963967
+20
+93.6304919422
+30
+0
+0
+VERTEX
+5
+64
+8
+0
+6
+BYLAYER
+62
+256
+10
+272.089687514
+20
+95.6679289229
+30
+0
+0
+VERTEX
+5
+65
+8
+0
+6
+BYLAYER
+62
+256
+10
+274.305740689
+20
+97.7151999704
+30
+0
+0
+VERTEX
+5
+66
+8
+0
+6
+BYLAYER
+62
+256
+10
+276.342784827
+20
+99.7673730293
+30
+0
+0
+VERTEX
+5
+67
+8
+0
+6
+BYLAYER
+62
+256
+10
+278.195912509
+20
+101.819504235
+30
+0
+0
+VERTEX
+5
+68
+8
+0
+6
+BYLAYER
+62
+256
+10
+279.860659389
+20
+103.866649824
+30
+0
+0
+VERTEX
+5
+69
+8
+0
+6
+BYLAYER
+62
+256
+10
+281.333014945
+20
+105.903878043
+30
+0
+0
+VERTEX
+5
+6A
+8
+0
+6
+BYLAYER
+62
+256
+10
+282.609432145
+20
+107.926281031
+30
+0
+0
+VERTEX
+5
+6B
+8
+0
+6
+BYLAYER
+62
+256
+10
+283.686835986
+20
+109.928986641
+30
+0
+0
+VERTEX
+5
+6C
+8
+0
+6
+BYLAYER
+62
+256
+10
+284.56263091
+20
+111.907170181
+30
+0
+0
+VERTEX
+5
+6D
+8
+0
+6
+BYLAYER
+62
+256
+10
+285.234707049
+20
+113.856066033
+30
+0
+0
+VERTEX
+5
+6E
+8
+0
+6
+BYLAYER
+62
+256
+10
+285.701445313
+20
+115.770979137
+30
+0
+0
+VERTEX
+5
+6F
+8
+0
+6
+BYLAYER
+62
+256
+10
+285.961721289
+20
+117.647296299
+30
+0
+0
+VERTEX
+5
+70
+8
+0
+6
+BYLAYER
+62
+256
+10
+286.014907949
+20
+119.480497306
+30
+0
+0
+VERTEX
+5
+71
+8
+0
+6
+BYLAYER
+62
+256
+10
+285.860877161
+20
+121.266165817
+30
+0
+0
+VERTEX
+5
+72
+8
+0
+6
+BYLAYER
+62
+256
+10
+285.5
+20
+123
+30
+0
+0
+VERTEX
+5
+73
+8
+0
+6
+BYLAYER
+62
+256
+10
+284.93314585
+20
+124.677822897
+30
+0
+0
+VERTEX
+5
+74
+8
+0
+6
+BYLAYER
+62
+256
+10
+284.161680312
+20
+126.295592484
+30
+0
+0
+VERTEX
+5
+75
+8
+0
+6
+BYLAYER
+62
+256
+10
+283.187461915
+20
+127.849411415
+30
+0
+0
+VERTEX
+5
+76
+8
+0
+6
+BYLAYER
+62
+256
+10
+282.012837636
+20
+129.335536402
+30
+0
+0
+VERTEX
+5
+77
+8
+0
+6
+BYLAYER
+62
+256
+10
+280.640637247
+20
+130.75038724
+30
+0
+0
+VERTEX
+5
+78
+8
+0
+6
+BYLAYER
+62
+256
+10
+279.0741665
+20
+132.09055543
+30
+0
+0
+VERTEX
+5
+79
+8
+0
+6
+BYLAYER
+62
+256
+10
+277.31719916
+20
+133.35281239
+30
+0
+0
+VERTEX
+5
+7A
+8
+0
+6
+BYLAYER
+62
+256
+10
+275.373967915
+20
+134.534117231
+30
+0
+0
+VERTEX
+5
+7B
+8
+0
+6
+BYLAYER
+62
+256
+10
+273.249154179
+20
+135.631624087
+30
+0
+0
+VERTEX
+5
+7C
+8
+0
+6
+BYLAYER
+62
+256
+10
+270.947876815
+20
+136.642688968
+30
+0
+0
+VERTEX
+5
+7D
+8
+0
+6
+BYLAYER
+62
+256
+10
+268.475679801
+20
+137.56487613
+30
+0
+0
+VERTEX
+5
+7E
+8
+0
+6
+BYLAYER
+62
+256
+10
+265.838518877
+20
+138.395963943
+30
+0
+0
+VERTEX
+5
+7F
+8
+0
+6
+BYLAYER
+62
+256
+10
+263.042747194
+20
+139.133950243
+30
+0
+0
+VERTEX
+5
+80
+8
+0
+6
+BYLAYER
+62
+256
+10
+260.095100011
+20
+139.777057158
+30
+0
+0
+VERTEX
+5
+81
+8
+0
+6
+BYLAYER
+62
+256
+10
+257.002678469
+20
+140.323735387
+30
+0
+0
+VERTEX
+5
+82
+8
+0
+6
+BYLAYER
+62
+256
+10
+253.772932481
+20
+140.772667933
+30
+0
+0
+VERTEX
+5
+83
+8
+0
+6
+BYLAYER
+62
+256
+10
+250.413642789
+20
+141.122773279
+30
+0
+0
+VERTEX
+5
+84
+8
+0
+6
+BYLAYER
+62
+256
+10
+246.932902216
+20
+141.37320799
+30
+0
+0
+VERTEX
+5
+85
+8
+0
+6
+BYLAYER
+62
+256
+10
+243.339096171
+20
+141.523368747
+30
+0
+0
+VERTEX
+5
+86
+8
+0
+6
+BYLAYER
+62
+256
+10
+239.640882446
+20
+141.5728938
+30
+0
+0
+VERTEX
+5
+87
+8
+0
+6
+BYLAYER
+62
+256
+10
+235.847170364
+20
+141.521663839
+30
+0
+0
+VERTEX
+5
+88
+8
+0
+6
+BYLAYER
+62
+256
+10
+231.967099309
+20
+141.36980228
+30
+0
+0
+VERTEX
+5
+89
+8
+0
+6
+BYLAYER
+62
+256
+10
+228.010016711
+20
+141.117674973
+30
+0
+0
+VERTEX
+5
+8A
+8
+0
+6
+BYLAYER
+62
+256
+10
+223.98545553
+20
+140.765889313
+30
+0
+0
+VERTEX
+5
+8B
+8
+0
+6
+BYLAYER
+62
+256
+10
+219.903111286
+20
+140.315292783
+30
+0
+0
+VERTEX
+5
+8C
+8
+0
+6
+BYLAYER
+62
+256
+10
+215.772818703
+20
+139.76697091
+30
+0
+0
+VERTEX
+5
+8D
+8
+0
+6
+BYLAYER
+62
+256
+10
+211.604528018
+20
+139.122244649
+30
+0
+0
+VERTEX
+5
+8E
+8
+0
+6
+BYLAYER
+62
+256
+10
+207.408281009
+20
+138.382667202
+30
+0
+0
+VERTEX
+5
+8F
+8
+0
+6
+BYLAYER
+62
+256
+10
+203.194186802
+20
+137.550020275
+30
+0
+0
+VERTEX
+5
+90
+8
+0
+6
+BYLAYER
+62
+256
+10
+198.972397519
+20
+136.626309789
+30
+0
+0
+VERTEX
+5
+91
+8
+0
+6
+BYLAYER
+62
+256
+10
+194.753083821
+20
+135.613761043
+30
+0
+0
+VERTEX
+5
+92
+8
+0
+6
+BYLAYER
+62
+256
+10
+190.546410403
+20
+134.514813355
+30
+0
+0
+VERTEX
+5
+93
+8
+0
+6
+BYLAYER
+62
+256
+10
+186.362511511
+20
+133.332114187
+30
+0
+0
+VERTEX
+5
+94
+8
+0
+6
+BYLAYER
+62
+256
+10
+182.211466523
+20
+132.068512764
+30
+0
+0
+VERTEX
+5
+95
+8
+0
+6
+BYLAYER
+62
+256
+10
+178.10327567
+20
+130.727053213
+30
+0
+0
+VERTEX
+5
+96
+8
+0
+6
+BYLAYER
+62
+256
+10
+174.047835944
+20
+129.310967228
+30
+0
+0
+VERTEX
+5
+97
+8
+0
+6
+BYLAYER
+62
+256
+10
+170.054917255
+20
+127.823666283
+30
+0
+0
+VERTEX
+5
+98
+8
+0
+6
+BYLAYER
+62
+256
+10
+166.134138892
+20
+126.268733418
+30
+0
+0
+VERTEX
+5
+99
+8
+0
+6
+BYLAYER
+62
+256
+10
+162.294946356
+20
+124.649914601
+30
+0
+0
+VERTEX
+5
+9A
+8
+0
+6
+BYLAYER
+62
+256
+10
+158.546588596
+20
+122.971109708
+30
+0
+0
+VERTEX
+5
+9B
+8
+0
+6
+BYLAYER
+62
+256
+10
+154.898095735
+20
+121.236363128
+30
+0
+0
+VERTEX
+5
+9C
+8
+0
+6
+BYLAYER
+62
+256
+10
+151.358257312
+20
+119.449854018
+30
+0
+0
+VERTEX
+5
+9D
+8
+0
+6
+BYLAYER
+62
+256
+10
+147.935601107
+20
+117.615886234
+30
+0
+0
+VERTEX
+5
+9E
+8
+0
+6
+BYLAYER
+62
+256
+10
+144.6383726
+20
+115.738877965
+30
+0
+0
+VERTEX
+5
+9F
+8
+0
+6
+BYLAYER
+62
+256
+10
+141.474515102
+20
+113.823351088
+30
+0
+0
+VERTEX
+5
+A0
+8
+0
+6
+BYLAYER
+62
+256
+10
+138.451650624
+20
+111.873920276
+30
+0
+0
+VERTEX
+5
+A1
+8
+0
+6
+BYLAYER
+62
+256
+10
+135.57706151
+20
+109.895281878
+30
+0
+0
+VERTEX
+5
+A2
+8
+0
+6
+BYLAYER
+62
+256
+10
+132.857672898
+20
+107.892202608
+30
+0
+0
+VERTEX
+5
+A3
+8
+0
+6
+BYLAYER
+62
+256
+10
+130.300036033
+20
+105.869508058
+30
+0
+0
+VERTEX
+5
+A4
+8
+0
+6
+BYLAYER
+62
+256
+10
+127.910312486
+20
+103.832071077
+30
+0
+0
+VERTEX
+5
+A5
+8
+0
+6
+BYLAYER
+62
+256
+10
+125.694259311
+20
+101.78480003
+30
+0
+0
+VERTEX
+5
+A6
+8
+0
+6
+BYLAYER
+62
+256
+10
+123.657215173
+20
+99.7326269707
+30
+0
+0
+VERTEX
+5
+A7
+8
+0
+6
+BYLAYER
+62
+256
+10
+121.804087491
+20
+97.6804957648
+30
+0
+0
+VERTEX
+5
+A8
+8
+0
+6
+BYLAYER
+62
+256
+10
+120.139340611
+20
+95.633350176
+30
+0
+0
+VERTEX
+5
+A9
+8
+0
+6
+BYLAYER
+62
+256
+10
+118.666985055
+20
+93.5961219571
+30
+0
+0
+VERTEX
+5
+AA
+8
+0
+6
+BYLAYER
+62
+256
+10
+117.390567855
+20
+91.5737189695
+30
+0
+0
+VERTEX
+5
+AB
+8
+0
+6
+BYLAYER
+62
+256
+10
+116.313164014
+20
+89.571013359
+30
+0
+0
+VERTEX
+5
+AC
+8
+0
+6
+BYLAYER
+62
+256
+10
+115.43736909
+20
+87.5928298189
+30
+0
+0
+VERTEX
+5
+AD
+8
+0
+6
+BYLAYER
+62
+256
+10
+114.765292951
+20
+85.6439339666
+30
+0
+0
+VERTEX
+5
+AE
+8
+0
+6
+BYLAYER
+62
+256
+10
+114.298554687
+20
+83.7290208629
+30
+0
+0
+VERTEX
+5
+AF
+8
+0
+6
+BYLAYER
+62
+256
+10
+114.038278711
+20
+81.8527037013
+30
+0
+0
+VERTEX
+5
+B0
+8
+0
+6
+BYLAYER
+62
+256
+10
+113.985092051
+20
+80.019502694
+30
+0
+0
+VERTEX
+5
+B1
+8
+0
+6
+BYLAYER
+62
+256
+10
+114.139122839
+20
+78.233834183
+30
+0
+0
+SEQEND
+5
+B2
+8
+0
+6
+BYLAYER
+62
+256
+0
+ENDSEC
+0
+EOF
diff --git a/pcbnew/import_dxf/examples/test_outlines.dxf b/pcbnew/import_dxf/examples/test_outlines.dxf
new file mode 100644
index 0000000..c5448b1
--- /dev/null
+++ b/pcbnew/import_dxf/examples/test_outlines.dxf
@@ -0,0 +1,7264 @@
+999
+dxfrw 0.5.10
+0
+SECTION
+2
+HEADER
+9
+$ACADVER
+1
+AC1021
+9
+$HANDSEED
+5
+20000
+9
+$DWGCODEPAGE
+3
+ANSI_1252
+9
+$INSBASE
+10
+0
+20
+0
+30
+0
+9
+$EXTMIN
+10
+8.01510349296
+20
+22.3703927791
+30
+0
+9
+$EXTMAX
+10
+160.415103493
+20
+173.677807569
+30
+0
+9
+$LIMMIN
+10
+0
+20
+0
+9
+$LIMMAX
+10
+210
+20
+297
+9
+$ORTHOMODE
+70
+0
+9
+$LTSCALE
+40
+1
+9
+$TEXTSTYLE
+7
+Standard
+9
+$DIMASZ
+40
+1.8
+9
+$DIMSCALE
+40
+1
+9
+$DIMEXO
+40
+0.0625
+9
+$DIMEXE
+40
+0.18
+9
+$DIMTXT
+40
+0.25
+9
+$DIMTSZ
+40
+0
+9
+$DIMAUNIT
+70
+0
+9
+$DIMADEC
+70
+0
+9
+$DIMLUNIT
+70
+2
+9
+$DIMSTYLE
+2
+Standard
+9
+$DIMGAP
+40
+0.09
+9
+$DIMTIH
+70
+1
+9
+$LUNITS
+70
+2
+9
+$LUPREC
+70
+4
+9
+$AUNITS
+70
+0
+9
+$AUPREC
+70
+0
+9
+$SPLINESEGS
+70
+8
+9
+$GRIDMODE
+70
+0
+9
+$SNAPSTYLE
+70
+0
+9
+$PINSBASE
+10
+0
+20
+0
+30
+0
+9
+$PLIMMIN
+10
+0
+20
+0
+9
+$PLIMMAX
+10
+210
+20
+297
+9
+$INSUNITS
+70
+4
+9
+$PSVPSCALE
+40
+0
+0
+ENDSEC
+0
+SECTION
+2
+CLASSES
+0
+ENDSEC
+0
+SECTION
+2
+TABLES
+0
+TABLE
+2
+VPORT
+5
+8
+330
+0
+100
+AcDbSymbolTable
+70
+1
+0
+VPORT
+5
+31
+330
+2
+100
+AcDbSymbolTableRecord
+100
+AcDbViewportTableRecord
+2
+*ACTIVE
+70
+0
+10
+0
+20
+0
+11
+1
+21
+1
+12
+103.477837818
+22
+82.10741479
+13
+0
+23
+0
+14
+10
+24
+10
+15
+10
+25
+10
+16
+0
+26
+0
+36
+1
+17
+0
+27
+0
+37
+0
+40
+368.920987002
+41
+0.976829268293
+42
+50
+43
+0
+44
+0
+50
+0
+51
+0
+71
+0
+72
+100
+73
+1
+74
+3
+75
+0
+76
+0
+77
+0
+78
+0
+281
+0
+65
+1
+110
+0
+120
+0
+130
+0
+111
+1
+121
+0
+131
+0
+112
+0
+122
+1
+132
+0
+79
+0
+146
+0
+348
+10020
+60
+7
+61
+5
+292
+1
+282
+1
+141
+0
+142
+0
+63
+250
+421
+3358443
+0
+ENDTAB
+0
+TABLE
+2
+LTYPE
+5
+5
+330
+0
+100
+AcDbSymbolTable
+70
+4
+0
+LTYPE
+5
+14
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+ByBlock
+70
+0
+3
+
+72
+65
+73
+0
+40
+0
+0
+LTYPE
+5
+15
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+ByLayer
+70
+0
+3
+
+72
+65
+73
+0
+40
+0
+0
+LTYPE
+5
+16
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+Continuous
+70
+0
+3
+Solid line
+72
+65
+73
+0
+40
+0
+0
+LTYPE
+5
+32
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+DOT
+70
+0
+3
+Dot . . . . . . . . . . . . . . . . . . . . . .
+72
+65
+73
+2
+40
+6.35
+49
+0
+74
+0
+49
+-6.35
+74
+0
+0
+LTYPE
+5
+33
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+DOT2
+70
+0
+3
+Dot (.5x) .....................................
+72
+65
+73
+2
+40
+3.175
+49
+0
+74
+0
+49
+-3.175
+74
+0
+0
+LTYPE
+5
+34
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+DOTX2
+70
+0
+3
+Dot (2x) . . . . . . . . . . . . .
+72
+65
+73
+2
+40
+12.7
+49
+0
+74
+0
+49
+-12.7
+74
+0
+0
+LTYPE
+5
+35
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+DASHED
+70
+0
+3
+Dot . . . . . . . . . . . . . . . . . . . . . .
+72
+65
+73
+2
+40
+19.05
+49
+12.7
+74
+0
+49
+-6.35
+74
+0
+0
+LTYPE
+5
+36
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+DASHED2
+70
+0
+3
+Dashed (.5x) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+72
+65
+73
+2
+40
+9.525
+49
+6.35
+74
+0
+49
+-3.175
+74
+0
+0
+LTYPE
+5
+37
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+DASHEDX2
+70
+0
+3
+Dashed (2x) ____ ____ ____ ____ ____ ___
+72
+65
+73
+2
+40
+38.1
+49
+25.4
+74
+0
+49
+-12.7
+74
+0
+0
+LTYPE
+5
+38
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+DASHDOT
+70
+0
+3
+Dash dot __ . __ . __ . __ . __ . __ . __ . __
+72
+65
+73
+4
+40
+25.4
+49
+12.7
+74
+0
+49
+-6.35
+74
+0
+49
+0
+74
+0
+49
+-6.35
+74
+0
+0
+LTYPE
+5
+39
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+DASHDOT2
+70
+0
+3
+Dash dot (.5x) _._._._._._._._._._._._._._._.
+72
+65
+73
+4
+40
+12.7
+49
+6.35
+74
+0
+49
+-3.175
+74
+0
+49
+0
+74
+0
+49
+-3.175
+74
+0
+0
+LTYPE
+5
+3A
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+DASHDOTX2
+70
+0
+3
+Dash dot (2x) ____ . ____ . ____ . ___
+72
+65
+73
+4
+40
+50.8
+49
+25.4
+74
+0
+49
+-12.7
+74
+0
+49
+0
+74
+0
+49
+-12.7
+74
+0
+0
+LTYPE
+5
+3B
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+DIVIDE
+70
+0
+3
+Divide ____ . . ____ . . ____ . . ____ . . ____
+72
+65
+73
+6
+40
+31.75
+49
+12.7
+74
+0
+49
+-6.35
+74
+0
+49
+0
+74
+0
+49
+-6.35
+74
+0
+49
+0
+74
+0
+49
+-6.35
+74
+0
+0
+LTYPE
+5
+3C
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+DIVIDE2
+70
+0
+3
+Divide (.5x) __..__..__..__..__..__..__..__.._
+72
+65
+73
+6
+40
+15.875
+49
+6.35
+74
+0
+49
+-3.175
+74
+0
+49
+0
+74
+0
+49
+-3.175
+74
+0
+49
+0
+74
+0
+49
+-3.175
+74
+0
+0
+LTYPE
+5
+3D
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+DIVIDEX2
+70
+0
+3
+Divide (2x) ________ . . ________ . . _
+72
+65
+73
+6
+40
+63.5
+49
+25.4
+74
+0
+49
+-12.7
+74
+0
+49
+0
+74
+0
+49
+-12.7
+74
+0
+49
+0
+74
+0
+49
+-12.7
+74
+0
+0
+LTYPE
+5
+3E
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+BORDER
+70
+0
+3
+Border __ __ . __ __ . __ __ . __ __ . __ __ .
+72
+65
+73
+6
+40
+44.45
+49
+12.7
+74
+0
+49
+-6.35
+74
+0
+49
+12.7
+74
+0
+49
+-6.35
+74
+0
+49
+0
+74
+0
+49
+-6.35
+74
+0
+0
+LTYPE
+5
+3F
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+BORDER2
+70
+0
+3
+Border (.5x) __.__.__.__.__.__.__.__.__.__.__.
+72
+65
+73
+6
+40
+22.225
+49
+6.35
+74
+0
+49
+-3.175
+74
+0
+49
+6.35
+74
+0
+49
+-3.175
+74
+0
+49
+0
+74
+0
+49
+-3.175
+74
+0
+0
+LTYPE
+5
+40
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+BORDERX2
+70
+0
+3
+Border (2x) ____ ____ . ____ ____ . ___
+72
+65
+73
+6
+40
+88.9
+49
+25.4
+74
+0
+49
+-12.7
+74
+0
+49
+25.4
+74
+0
+49
+-12.7
+74
+0
+49
+0
+74
+0
+49
+-12.7
+74
+0
+0
+LTYPE
+5
+41
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+CENTER
+70
+0
+3
+Center ____ _ ____ _ ____ _ ____ _ ____ _ ____
+72
+65
+73
+4
+40
+50.8
+49
+31.75
+74
+0
+49
+-6.35
+74
+0
+49
+6.35
+74
+0
+49
+-6.35
+74
+0
+0
+LTYPE
+5
+42
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+CENTER2
+70
+0
+3
+Center (.5x) ___ _ ___ _ ___ _ ___ _ ___ _ ___
+72
+65
+73
+4
+40
+28.575
+49
+19.05
+74
+0
+49
+-3.175
+74
+0
+49
+3.175
+74
+0
+49
+-3.175
+74
+0
+0
+LTYPE
+5
+43
+330
+5
+100
+AcDbSymbolTableRecord
+100
+AcDbLinetypeTableRecord
+2
+CENTERX2
+70
+0
+3
+Center (2x) ________ __ ________ __ _____
+72
+65
+73
+4
+40
+101.6
+49
+63.5
+74
+0
+49
+-12.7
+74
+0
+49
+12.7
+74
+0
+49
+-12.7
+74
+0
+0
+ENDTAB
+0
+TABLE
+2
+LAYER
+5
+2
+330
+0
+100
+AcDbSymbolTable
+70
+1
+0
+LAYER
+5
+10
+330
+2
+100
+AcDbSymbolTableRecord
+100
+AcDbLayerTableRecord
+2
+0
+70
+0
+62
+7
+6
+CONTINUOUS
+370
+-3
+390
+F
+0
+LAYER
+5
+44
+330
+2
+100
+AcDbSymbolTableRecord
+100
+AcDbLayerTableRecord
+2
+Visible Edges(PEC)
+70
+0
+62
+7
+6
+CONTINUOUS
+370
+50
+390
+F
+0
+ENDTAB
+0
+TABLE
+2
+STYLE
+5
+3
+330
+0
+100
+AcDbSymbolTable
+70
+3
+0
+STYLE
+5
+45
+330
+2
+100
+AcDbSymbolTableRecord
+100
+AcDbTextStyleTableRecord
+2
+Standard
+70
+0
+40
+0
+41
+1
+50
+0
+71
+0
+42
+1
+3
+txt
+4
+
+0
+ENDTAB
+0
+TABLE
+2
+VIEW
+5
+6
+330
+0
+100
+AcDbSymbolTable
+70
+0
+0
+ENDTAB
+0
+TABLE
+2
+UCS
+5
+7
+330
+0
+100
+AcDbSymbolTable
+70
+0
+0
+ENDTAB
+0
+TABLE
+2
+APPID
+5
+9
+330
+0
+100
+AcDbSymbolTable
+70
+1
+0
+APPID
+5
+12
+330
+9
+100
+AcDbSymbolTableRecord
+100
+AcDbRegAppTableRecord
+2
+ACAD
+70
+0
+0
+ENDTAB
+0
+TABLE
+2
+DIMSTYLE
+5
+A
+330
+0
+100
+AcDbSymbolTable
+70
+1
+100
+AcDbDimStyleTable
+71
+1
+0
+DIMSTYLE
+105
+46
+330
+A
+100
+AcDbSymbolTableRecord
+100
+AcDbDimStyleTableRecord
+2
+Standard
+70
+0
+40
+1
+41
+1.8
+42
+0.0625
+43
+0.38
+44
+0.18
+45
+0
+46
+0
+47
+0
+48
+0
+140
+0.25
+141
+0.09
+142
+0
+143
+25.4
+144
+1
+145
+0
+146
+1
+147
+0.09
+148
+0
+71
+0
+72
+0
+73
+0
+74
+1
+75
+0
+76
+0
+77
+0
+78
+0
+79
+0
+170
+0
+171
+2
+172
+0
+173
+0
+174
+0
+175
+0
+176
+0
+177
+0
+178
+0
+179
+0
+271
+4
+272
+4
+273
+2
+274
+2
+275
+0
+276
+0
+277
+2
+278
+46
+279
+0
+280
+0
+281
+0
+282
+0
+283
+1
+284
+0
+285
+0
+286
+0
+288
+0
+289
+3
+340
+Standard
+341
+
+371
+-2
+372
+-2
+0
+ENDTAB
+0
+TABLE
+2
+BLOCK_RECORD
+5
+1
+330
+0
+100
+AcDbSymbolTable
+70
+2
+0
+BLOCK_RECORD
+5
+1F
+330
+1
+100
+AcDbSymbolTableRecord
+100
+AcDbBlockTableRecord
+2
+*Model_Space
+70
+0
+280
+1
+281
+0
+0
+BLOCK_RECORD
+5
+1E
+330
+1
+100
+AcDbSymbolTableRecord
+100
+AcDbBlockTableRecord
+2
+*Paper_Space
+70
+0
+280
+1
+281
+0
+0
+ENDTAB
+0
+ENDSEC
+0
+SECTION
+2
+BLOCKS
+0
+BLOCK
+5
+20
+330
+1F
+100
+AcDbEntity
+8
+0
+100
+AcDbBlockBegin
+2
+*Model_Space
+70
+0
+10
+0
+20
+0
+30
+0
+3
+*Model_Space
+1
+
+0
+ENDBLK
+5
+21
+330
+1F
+100
+AcDbEntity
+8
+0
+100
+AcDbBlockEnd
+0
+BLOCK
+5
+1C
+330
+1B
+100
+AcDbEntity
+8
+0
+100
+AcDbBlockBegin
+2
+*Paper_Space
+70
+0
+10
+0
+20
+0
+30
+0
+3
+*Paper_Space
+1
+
+0
+ENDBLK
+5
+1D
+330
+1F
+100
+AcDbEntity
+8
+0
+100
+AcDbBlockEnd
+0
+ENDSEC
+0
+SECTION
+2
+ENTITIES
+0
+LINE
+5
+47
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+54.0015095768
+20
+145.07427149
+11
+57.9407405889
+21
+144.379678779
+0
+LINE
+5
+48
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+57.9407405889
+20
+144.379678779
+11
+55.9264217279
+21
+132.955908844
+0
+LINE
+5
+49
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+55.9264217279
+20
+132.955908844
+11
+51.9871907159
+21
+133.650501555
+0
+CIRCLE
+5
+4A
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+76.6151034931
+20
+128.870392779
+40
+2
+0
+CIRCLE
+5
+4B
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+62.3755750957
+20
+142.867767753
+40
+1.6
+0
+CIRCLE
+5
+4C
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+60.6112785469
+20
+132.861944812
+40
+1.6
+0
+CIRCLE
+5
+4D
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+76.9279747741
+20
+141.354399538
+40
+1.1
+0
+CIRCLE
+5
+4E
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+28.165103493
+20
+25.4703927791
+40
+0.7
+0
+CIRCLE
+5
+4F
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+44.265103493
+20
+25.4703927791
+40
+0.7
+0
+CIRCLE
+5
+50
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+36.965103493
+20
+25.4703927791
+40
+0.7
+0
+ARC
+5
+51
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+78.5610437151
+20
+131.847953136
+40
+0.4
+100
+AcDbArc
+50
+85.34
+51
+265.34
+0
+LINE
+5
+52
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+78.5935407971
+20
+132.246630875
+11
+79.4905657101
+21
+132.173512441
+0
+ARC
+5
+53
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+79.4580686281
+20
+131.774834702
+40
+0.4
+100
+AcDbArc
+50
+265.34
+51
+85.34
+0
+LINE
+5
+54
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+79.4255715461
+20
+131.376156963
+11
+78.5285466331
+21
+131.449275397
+0
+LINE
+5
+55
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+79.1866125401
+20
+139.522499614
+11
+80.0836374531
+21
+139.44938118
+0
+ARC
+5
+56
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+80.0511403711
+20
+139.050703441
+40
+0.4
+100
+AcDbArc
+50
+265.34
+51
+85.34
+0
+LINE
+5
+57
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+80.0186432901
+20
+138.652025702
+11
+79.1216183771
+21
+138.725144136
+0
+ARC
+5
+58
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+79.1541154581
+20
+139.123821875
+40
+0.4
+100
+AcDbArc
+50
+85.34
+51
+265.34
+0
+ARC
+5
+59
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+73.8716354151
+20
+139.554408209
+40
+0.4
+100
+AcDbArc
+50
+85.34
+51
+265.34
+0
+LINE
+5
+5A
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+73.9041324969
+20
+139.953085949
+11
+74.8011574099
+21
+139.879967514
+0
+ARC
+5
+5B
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+74.7686603281
+20
+139.481289775
+40
+0.4
+100
+AcDbArc
+50
+265.34
+51
+85.34
+0
+LINE
+5
+5C
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+74.7361632463
+20
+139.082612036
+11
+73.8391383333
+21
+139.15573047
+0
+ARC
+5
+5D
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+73.2785636718
+20
+132.27853947
+40
+0.4
+100
+AcDbArc
+50
+85.34
+51
+265.34
+0
+LINE
+5
+5E
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+73.3110607536
+20
+132.67721721
+11
+74.2080856666
+21
+132.604098775
+0
+ARC
+5
+5F
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+74.1755885848
+20
+132.205421036
+40
+0.4
+100
+AcDbArc
+50
+265.34
+51
+85.34
+0
+LINE
+5
+60
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+74.143091503
+20
+131.806743297
+11
+73.2460665899
+21
+131.879861731
+0
+LINE
+5
+61
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+56.8197279711
+20
+132.003859741
+11
+57.9030164994
+21
+131.812846746
+0
+ARC
+5
+62
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+57.8509220461
+20
+131.51740442
+40
+0.3
+100
+AcDbArc
+50
+260
+51
+80
+0
+LINE
+5
+63
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+57.7988275928
+20
+131.221962094
+11
+56.7155390645
+21
+131.412975089
+0
+ARC
+5
+64
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+56.7676335178
+20
+131.708417415
+40
+0.3
+100
+AcDbArc
+50
+80
+51
+260
+0
+LINE
+5
+65
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+59.2022229169
+20
+145.515660013
+11
+60.2855114452
+21
+145.324647017
+0
+ARC
+5
+66
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+60.2334169919
+20
+145.029204691
+40
+0.3
+100
+AcDbArc
+50
+260
+51
+80
+0
+LINE
+5
+67
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+60.1813225386
+20
+144.733762365
+11
+59.0980340103
+21
+144.924775361
+0
+ARC
+5
+68
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+59.1501284636
+20
+145.220217687
+40
+0.3
+100
+AcDbArc
+50
+80
+51
+260
+0
+CIRCLE
+5
+69
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+17.415103493
+20
+33.7103927791
+40
+0.5
+0
+CIRCLE
+5
+6A
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+17.415103493
+20
+36.2503927791
+40
+0.5
+0
+CIRCLE
+5
+6B
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+17.415103493
+20
+38.7903927791
+40
+0.5
+0
+CIRCLE
+5
+6C
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+17.415103493
+20
+41.3303927791
+40
+0.5
+0
+CIRCLE
+5
+6D
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+76.1591754285
+20
+137.461644322
+40
+0.45
+0
+CIRCLE
+5
+6E
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+75.8748259626
+20
+133.973214105
+40
+0.45
+0
+CIRCLE
+5
+6F
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+68.0851733401
+20
+138.680315907
+40
+0.45
+0
+CIRCLE
+5
+70
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+67.6440992029
+20
+136.178860171
+40
+0.45
+0
+CIRCLE
+5
+71
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+70.3686653354
+20
+137.003365518
+40
+0.45
+0
+CIRCLE
+5
+72
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+69.9275911982
+20
+134.501909782
+40
+0.45
+0
+LINE
+5
+73
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+54.388745013
+20
+147.270392779
+11
+54.0015095768
+21
+145.07427149
+0
+LINE
+5
+74
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+51.9871907159
+20
+133.650501555
+11
+50.7387765123
+21
+126.570392779
+0
+LINE
+5
+75
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+26.115103493
+20
+28.5703927791
+11
+26.115103493
+21
+22.3703927791
+0
+LINE
+5
+76
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+26.115103493
+20
+22.3703927791
+11
+46.315103493
+21
+22.3703927791
+0
+LINE
+5
+77
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+46.315103493
+20
+22.3703927791
+11
+46.315103493
+21
+28.5703927791
+0
+LINE
+5
+78
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+80.1469013801
+20
+126.070392779
+11
+81.4988185711
+21
+142.655860116
+0
+LINE
+5
+79
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+54.388745013
+20
+147.270392779
+11
+81.4988185711
+21
+142.655860116
+0
+CIRCLE
+5
+7A
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+38.615103493
+20
+36.0703927791
+40
+0.75
+0
+CIRCLE
+5
+7B
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+31.115103493
+20
+33.8203927791
+40
+0.75
+0
+CIRCLE
+5
+7C
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+141.915103493
+20
+109.820392779
+40
+0.75
+0
+CIRCLE
+5
+7D
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+149.415103493
+20
+112.070392779
+40
+0.75
+0
+CIRCLE
+5
+7E
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+139.665103493
+20
+71.8203927791
+40
+0.75
+0
+CIRCLE
+5
+7F
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+147.165103493
+20
+74.0703927791
+40
+0.75
+0
+CIRCLE
+5
+80
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+135.165103493
+20
+52.8203927791
+40
+0.75
+0
+CIRCLE
+5
+81
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+142.665103493
+20
+55.0703927791
+40
+0.75
+0
+CIRCLE
+5
+82
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+137.415103493
+20
+33.8203927791
+40
+0.75
+0
+CIRCLE
+5
+83
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+144.915103493
+20
+36.0703927791
+40
+0.75
+0
+CIRCLE
+5
+84
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+114.765103493
+20
+36.0703927791
+40
+0.75
+0
+CIRCLE
+5
+85
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+107.265103493
+20
+33.8203927791
+40
+0.75
+0
+CIRCLE
+5
+86
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+91.3651034931
+20
+36.0703927791
+40
+0.75
+0
+CIRCLE
+5
+87
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+83.8651034931
+20
+33.8203927791
+40
+0.75
+0
+CIRCLE
+5
+88
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+67.965103493
+20
+36.0703927791
+40
+0.75
+0
+CIRCLE
+5
+89
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+60.465103493
+20
+33.8203927791
+40
+0.75
+0
+CIRCLE
+5
+8A
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+104.715103493
+20
+52.8203927791
+40
+0.75
+0
+CIRCLE
+5
+8B
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+112.215103493
+20
+55.0703927791
+40
+0.75
+0
+CIRCLE
+5
+8C
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+85.5151034931
+20
+52.8203927791
+40
+0.75
+0
+CIRCLE
+5
+8D
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+93.0151034931
+20
+55.0703927791
+40
+0.75
+0
+CIRCLE
+5
+8E
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+66.315103493
+20
+52.8203927791
+40
+0.75
+0
+CIRCLE
+5
+8F
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+73.815103493
+20
+55.0703927791
+40
+0.75
+0
+CIRCLE
+5
+90
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+47.115103493
+20
+52.8203927791
+40
+0.75
+0
+CIRCLE
+5
+91
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+54.615103493
+20
+55.0703927791
+40
+0.75
+0
+CIRCLE
+5
+92
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+35.415103493
+20
+55.0703927791
+40
+0.75
+0
+CIRCLE
+5
+93
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+27.915103493
+20
+52.8203927791
+40
+0.75
+0
+CIRCLE
+5
+94
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+121.325103493
+20
+74.0703927791
+40
+0.75
+0
+CIRCLE
+5
+95
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+113.825103493
+20
+71.8203927791
+40
+0.75
+0
+CIRCLE
+5
+96
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+102.235103493
+20
+74.0703927791
+40
+0.75
+0
+CIRCLE
+5
+97
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+94.7351034931
+20
+71.8203927791
+40
+0.75
+0
+CIRCLE
+5
+98
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+83.1451034931
+20
+74.0703927791
+40
+0.75
+0
+CIRCLE
+5
+99
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+75.645103493
+20
+71.8203927791
+40
+0.75
+0
+CIRCLE
+5
+9A
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+64.055103493
+20
+74.0703927791
+40
+0.75
+0
+CIRCLE
+5
+9B
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+56.555103493
+20
+71.8203927791
+40
+0.75
+0
+CIRCLE
+5
+9C
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+44.965103493
+20
+74.0703927791
+40
+0.75
+0
+CIRCLE
+5
+9D
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+37.465103493
+20
+71.8203927791
+40
+0.75
+0
+CIRCLE
+5
+9E
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+18.375103493
+20
+71.8203927791
+40
+0.75
+0
+CIRCLE
+5
+9F
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+25.875103493
+20
+74.0703927791
+40
+0.75
+0
+CIRCLE
+5
+A0
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+146.415103493
+20
+90.8203927791
+40
+0.75
+0
+CIRCLE
+5
+A1
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+153.915103493
+20
+93.0703927791
+40
+0.75
+0
+CIRCLE
+5
+A2
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+127.415103493
+20
+90.8203927791
+40
+0.75
+0
+CIRCLE
+5
+A3
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+134.915103493
+20
+93.0703927791
+40
+0.75
+0
+CIRCLE
+5
+A4
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+108.415103493
+20
+90.8203927791
+40
+0.75
+0
+CIRCLE
+5
+A5
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+115.915103493
+20
+93.0703927791
+40
+0.75
+0
+CIRCLE
+5
+A6
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+89.4151034931
+20
+90.8203927791
+40
+0.75
+0
+CIRCLE
+5
+A7
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+96.9151034931
+20
+93.0703927791
+40
+0.75
+0
+CIRCLE
+5
+A8
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+70.415103493
+20
+90.8203927791
+40
+0.75
+0
+CIRCLE
+5
+A9
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+77.9151034931
+20
+93.0703927791
+40
+0.75
+0
+CIRCLE
+5
+AA
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+58.915103493
+20
+93.0703927791
+40
+0.75
+0
+CIRCLE
+5
+AB
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+32.415103493
+20
+90.8203927791
+40
+0.75
+0
+CIRCLE
+5
+AC
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+39.915103493
+20
+93.0703927791
+40
+0.75
+0
+CIRCLE
+5
+AD
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+13.415103493
+20
+90.8203927791
+40
+0.75
+0
+CIRCLE
+5
+AE
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+20.915103493
+20
+93.0703927791
+40
+0.75
+0
+CIRCLE
+5
+AF
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+118.415103493
+20
+109.820392779
+40
+0.75
+0
+CIRCLE
+5
+B0
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+125.915103493
+20
+112.070392779
+40
+0.75
+0
+CIRCLE
+5
+B1
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+99.4151034931
+20
+109.820392779
+40
+0.75
+0
+CIRCLE
+5
+B2
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+106.915103493
+20
+112.070392779
+40
+0.75
+0
+CIRCLE
+5
+B3
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+80.4151034931
+20
+109.820392779
+40
+0.75
+0
+CIRCLE
+5
+B4
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+87.9151034931
+20
+112.070392779
+40
+0.75
+0
+CIRCLE
+5
+B5
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+61.415103493
+20
+109.820392779
+40
+0.75
+0
+CIRCLE
+5
+B6
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+68.915103493
+20
+112.070392779
+40
+0.75
+0
+CIRCLE
+5
+B7
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+42.415103493
+20
+109.820392779
+40
+0.75
+0
+CIRCLE
+5
+B8
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+49.915103493
+20
+112.070392779
+40
+0.75
+0
+CIRCLE
+5
+B9
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+23.415103493
+20
+109.820392779
+40
+0.75
+0
+CIRCLE
+5
+BA
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+30.915103493
+20
+112.070392779
+40
+0.75
+0
+LINE
+5
+BB
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+19.215103493
+20
+114.070392779
+11
+19.215103493
+21
+110.070392779
+0
+LINE
+5
+BC
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+19.215103493
+20
+110.070392779
+11
+17.915103493
+21
+110.070392779
+0
+LINE
+5
+BD
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+17.915103493
+20
+114.070392779
+11
+19.215103493
+21
+114.070392779
+0
+LINE
+5
+BE
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+19.215103493
+20
+122.070392779
+11
+19.215103493
+21
+118.070392779
+0
+LINE
+5
+BF
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+19.215103493
+20
+118.070392779
+11
+17.915103493
+21
+118.070392779
+0
+LINE
+5
+C0
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+17.915103493
+20
+122.070392779
+11
+19.215103493
+21
+122.070392779
+0
+LINE
+5
+C1
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+23.815103493
+20
+64.0703927791
+11
+23.815103493
+21
+60.0703927791
+0
+LINE
+5
+C2
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+23.815103493
+20
+60.0703927791
+11
+22.515103493
+21
+60.0703927791
+0
+LINE
+5
+C3
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+22.515103493
+20
+64.0703927791
+11
+23.815103493
+21
+64.0703927791
+0
+LINE
+5
+C4
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+23.815103493
+20
+57.0703927791
+11
+23.815103493
+21
+53.0703927791
+0
+LINE
+5
+C5
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+23.815103493
+20
+53.0703927791
+11
+22.515103493
+21
+53.0703927791
+0
+LINE
+5
+C6
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+22.515103493
+20
+57.0703927791
+11
+23.815103493
+21
+57.0703927791
+0
+LINE
+5
+C7
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+14.315103493
+20
+76.0703927791
+11
+14.315103493
+21
+72.0703927791
+0
+LINE
+5
+C8
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+14.315103493
+20
+72.0703927791
+11
+13.015103493
+21
+72.0703927791
+0
+LINE
+5
+C9
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+13.015103493
+20
+76.0703927791
+11
+14.315103493
+21
+76.0703927791
+0
+LINE
+5
+CA
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+14.315103493
+20
+83.5703927791
+11
+14.315103493
+21
+79.5703927791
+0
+LINE
+5
+CB
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+14.315103493
+20
+79.5703927791
+11
+13.015103493
+21
+79.5703927791
+0
+LINE
+5
+CC
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+13.015103493
+20
+83.5703927791
+11
+14.315103493
+21
+83.5703927791
+0
+LINE
+5
+CD
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+9.31510349296
+20
+95.0703927791
+11
+9.31510349296
+21
+91.0703927791
+0
+LINE
+5
+CE
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+9.31510349296
+20
+91.0703927791
+11
+8.01510349296
+21
+91.0703927791
+0
+LINE
+5
+CF
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+8.01510349296
+20
+95.0703927791
+11
+9.31510349296
+21
+95.0703927791
+0
+LINE
+5
+D0
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+9.31510349296
+20
+102.070392779
+11
+9.31510349296
+21
+98.0703927791
+0
+LINE
+5
+D1
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+9.31510349296
+20
+98.0703927791
+11
+8.01510349296
+21
+98.0703927791
+0
+LINE
+5
+D2
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+8.01510349296
+20
+102.070392779
+11
+9.31510349296
+21
+102.070392779
+0
+LINE
+5
+D3
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+15.615103493
+20
+28.5703927791
+11
+26.115103493
+21
+28.5703927791
+0
+LINE
+5
+D4
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+46.315103493
+20
+28.5703927791
+11
+160.415103493
+21
+28.5703927791
+0
+LINE
+5
+D5
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+21.115103493
+20
+126.570392779
+11
+21.115103493
+21
+123.270392779
+0
+LINE
+5
+D6
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+21.115103493
+20
+123.270392779
+11
+17.915103493
+21
+123.270392779
+0
+LINE
+5
+D7
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+50.7387765123
+20
+126.570392779
+11
+21.115103493
+21
+126.570392779
+0
+LINE
+5
+D8
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+31.215103493
+20
+103.570392779
+11
+8.01510349296
+21
+103.570392779
+0
+LINE
+5
+D9
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+17.915103493
+20
+108.570392779
+11
+31.215103493
+21
+108.570392779
+0
+LINE
+5
+DA
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+31.215103493
+20
+108.570392779
+11
+31.215103493
+21
+103.570392779
+0
+LINE
+5
+DB
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+160.415103493
+20
+126.070392779
+11
+80.1469013801
+21
+126.070392779
+0
+LINE
+5
+DC
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+31.215103493
+20
+84.5703927791
+11
+13.015103493
+21
+84.5703927791
+0
+LINE
+5
+DD
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+31.215103493
+20
+89.5703927791
+11
+31.215103493
+21
+84.5703927791
+0
+LINE
+5
+DE
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+8.01510349296
+20
+89.5703927791
+11
+31.215103493
+21
+89.5703927791
+0
+LINE
+5
+DF
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+41.715103493
+20
+46.5703927791
+11
+15.615103493
+21
+46.5703927791
+0
+LINE
+5
+E0
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+41.715103493
+20
+51.5703927791
+11
+41.715103493
+21
+46.5703927791
+0
+LINE
+5
+E1
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+22.515103493
+20
+51.5703927791
+11
+41.715103493
+21
+51.5703927791
+0
+LINE
+5
+E2
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+41.715103493
+20
+65.5703927791
+11
+22.515103493
+21
+65.5703927791
+0
+LINE
+5
+E3
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+41.715103493
+20
+70.5703927791
+11
+41.715103493
+21
+65.5703927791
+0
+LINE
+5
+E4
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+13.015103493
+20
+70.5703927791
+11
+41.715103493
+21
+70.5703927791
+0
+LINE
+5
+E5
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+17.915103493
+20
+122.070392779
+11
+17.915103493
+21
+123.270392779
+0
+LINE
+5
+E6
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+17.915103493
+20
+108.570392779
+11
+17.915103493
+21
+110.070392779
+0
+LINE
+5
+E7
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+8.01510349296
+20
+102.070392779
+11
+8.01510349296
+21
+103.570392779
+0
+LINE
+5
+E8
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+8.01510349296
+20
+89.5703927791
+11
+8.01510349296
+21
+91.0703927791
+0
+LINE
+5
+E9
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+15.615103493
+20
+28.5703927791
+11
+15.615103493
+21
+46.5703927791
+0
+LINE
+5
+EA
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+17.915103493
+20
+114.070392779
+11
+17.915103493
+21
+118.070392779
+0
+LINE
+5
+EB
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+8.01510349296
+20
+95.0703927791
+11
+8.01510349296
+21
+98.0703927791
+0
+LINE
+5
+EC
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+13.015103493
+20
+83.5703927791
+11
+13.015103493
+21
+84.5703927791
+0
+LINE
+5
+ED
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+13.015103493
+20
+76.0703927791
+11
+13.015103493
+21
+79.5703927791
+0
+LINE
+5
+EE
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+13.015103493
+20
+70.5703927791
+11
+13.015103493
+21
+72.0703927791
+0
+LINE
+5
+EF
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+22.515103493
+20
+64.0703927791
+11
+22.515103493
+21
+65.5703927791
+0
+LINE
+5
+F0
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+22.515103493
+20
+57.0703927791
+11
+22.515103493
+21
+60.0703927791
+0
+LINE
+5
+F1
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+22.515103493
+20
+51.5703927791
+11
+22.515103493
+21
+53.0703927791
+0
+LINE
+5
+F2
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+160.415103493
+20
+126.070392779
+11
+160.415103493
+21
+28.5703927791
+0
+CIRCLE
+5
+F3
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+44.915103493
+20
+105.570392779
+40
+2.1
+0
+CIRCLE
+5
+F4
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+59.715103493
+20
+67.5703927791
+40
+2.1
+0
+CIRCLE
+5
+F5
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+98.1151034931
+20
+67.5703927791
+40
+2.1
+0
+CIRCLE
+5
+F6
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+155.415103493
+20
+77.5703927791
+40
+2.1
+0
+CIRCLE
+5
+F7
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+111.915103493
+20
+106.570392779
+40
+2.1
+0
+CIRCLE
+5
+F8
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+140.415103493
+20
+39.5703927791
+40
+2
+0
+CIRCLE
+5
+F9
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+110.265103493
+20
+39.5703927791
+40
+2
+0
+CIRCLE
+5
+FA
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+107.715103493
+20
+58.5703927791
+40
+2
+0
+CIRCLE
+5
+FB
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+138.165103493
+20
+58.5703927791
+40
+2
+0
+CIRCLE
+5
+FC
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+142.665103493
+20
+77.5703927791
+40
+2
+0
+CIRCLE
+5
+FD
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+116.825103493
+20
+77.5703927791
+40
+2
+0
+CIRCLE
+5
+FE
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+149.415103493
+20
+96.5703927791
+40
+2
+0
+CIRCLE
+5
+FF
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+144.915103493
+20
+115.570392779
+40
+2
+0
+CIRCLE
+5
+100
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+121.415103493
+20
+115.570392779
+40
+2
+0
+CIRCLE
+5
+101
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+102.415103493
+20
+115.570392779
+40
+2
+0
+CIRCLE
+5
+102
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+83.4151034931
+20
+115.570392779
+40
+2
+0
+CIRCLE
+5
+103
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+64.415103493
+20
+115.570392779
+40
+2
+0
+CIRCLE
+5
+104
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+45.415103493
+20
+115.570392779
+40
+2
+0
+CIRCLE
+5
+105
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+26.415103493
+20
+115.570392779
+40
+2
+0
+CIRCLE
+5
+106
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+130.415103493
+20
+96.5703927791
+40
+2
+0
+CIRCLE
+5
+107
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+111.415103493
+20
+96.5703927791
+40
+2
+0
+CIRCLE
+5
+108
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+92.4151034931
+20
+96.5703927791
+40
+2
+0
+CIRCLE
+5
+109
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+73.415103493
+20
+96.5703927791
+40
+2
+0
+CIRCLE
+5
+10A
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+54.415103493
+20
+96.5703927791
+40
+2
+0
+CIRCLE
+5
+10B
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+35.415103493
+20
+96.5703927791
+40
+2
+0
+CIRCLE
+5
+10C
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+16.415103493
+20
+96.5703927791
+40
+2
+0
+CIRCLE
+5
+10D
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+97.7351034931
+20
+77.5703927791
+40
+2
+0
+CIRCLE
+5
+10E
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+78.6451034931
+20
+77.5703927791
+40
+2
+0
+CIRCLE
+5
+10F
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+59.555103493
+20
+77.5703927791
+40
+2
+0
+CIRCLE
+5
+110
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+40.465103493
+20
+77.5703927791
+40
+2
+0
+CIRCLE
+5
+111
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+21.375103493
+20
+77.5703927791
+40
+2
+0
+CIRCLE
+5
+112
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+88.5151034931
+20
+58.5703927791
+40
+2
+0
+CIRCLE
+5
+113
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+69.315103493
+20
+58.5703927791
+40
+2
+0
+CIRCLE
+5
+114
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+50.115103493
+20
+58.5703927791
+40
+2
+0
+CIRCLE
+5
+115
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+30.915103493
+20
+58.5703927791
+40
+2
+0
+CIRCLE
+5
+116
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+34.115103493
+20
+39.5703927791
+40
+2
+0
+CIRCLE
+5
+117
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+86.8651034931
+20
+39.5703927791
+40
+2
+0
+CIRCLE
+5
+118
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+63.465103493
+20
+39.5703927791
+40
+2
+0
+ARC
+5
+119
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+124.426298668
+20
+54.6043548311
+40
+2.37170824513
+100
+AcDbArc
+50
+341.565051177
+51
+198.434948823
+0
+LINE
+5
+11A
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+122.176298668
+20
+53.8543548311
+11
+123.676298668
+21
+50.8543548311
+0
+LINE
+5
+11B
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+126.676298668
+20
+53.8543548311
+11
+125.176298668
+21
+50.8543548311
+0
+ARC
+5
+11C
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+124.426298668
+20
+51.2543548311
+40
+0.85
+100
+AcDbArc
+50
+208.072486936
+51
+331.927513064
+0
+ARC
+5
+11D
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+124.380058759
+20
+41.2642934551
+40
+2.37170824513
+100
+AcDbArc
+50
+161.565051177
+51
+18.4349488229
+0
+LINE
+5
+11E
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+126.630058759
+20
+42.0142934551
+11
+125.130058759
+21
+45.0142934551
+0
+LINE
+5
+11F
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+122.130058759
+20
+42.0142934551
+11
+123.630058759
+21
+45.0142934551
+0
+ARC
+5
+120
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+124.380058759
+20
+44.6142934551
+40
+0.85
+100
+AcDbArc
+50
+28.0724869359
+51
+151.927513064
+0
+ARC
+5
+121
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+117.630058759
+20
+48.1425852101
+40
+2.37170824513
+100
+AcDbArc
+50
+71.5650511771
+51
+288.434948823
+0
+LINE
+5
+122
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+118.380058759
+20
+45.8925852101
+11
+121.380058759
+21
+47.3925852101
+0
+LINE
+5
+123
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+118.380058759
+20
+50.3925852101
+11
+121.380058759
+21
+48.8925852101
+0
+ARC
+5
+124
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+120.980058759
+20
+48.1425852101
+40
+0.85
+100
+AcDbArc
+50
+298.072486936
+51
+61.9275130641
+0
+ARC
+5
+125
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+131.130058759
+20
+48.1425852101
+40
+2.37170824513
+100
+AcDbArc
+50
+251.565051177
+51
+108.434948823
+0
+LINE
+5
+126
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+130.380058759
+20
+50.3925852101
+11
+127.380058759
+21
+48.8925852101
+0
+LINE
+5
+127
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+130.380058759
+20
+45.8925852101
+11
+127.380058759
+21
+47.3925852101
+0
+ARC
+5
+128
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+127.780058759
+20
+48.1425852101
+40
+0.85
+100
+AcDbArc
+50
+118.072486936
+51
+241.927513064
+0
+ARC
+5
+129
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+53.1318556378
+20
+37.0101551811
+40
+0.85
+100
+AcDbArc
+50
+73.0724869359
+51
+196.927513064
+0
+ARC
+5
+12A
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+45.8640058389
+20
+34.7320634341
+40
+2.37170824513
+100
+AcDbArc
+50
+116.565051177
+51
+333.434948823
+0
+LINE
+5
+12B
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+47.9853261825
+20
+33.6714032621
+11
+49.0459863543
+21
+36.8533837771
+0
+LINE
+5
+12C
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+44.8033456672
+20
+36.8533837771
+11
+47.9853261825
+21
+37.9140439491
+0
+ARC
+5
+12D
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+48.2328135559
+20
+37.1008711511
+40
+0.85
+100
+AcDbArc
+50
+343.072486936
+51
+106.927513064
+0
+ARC
+5
+12E
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+55.4099473849
+20
+44.2780049801
+40
+2.37170824513
+100
+AcDbArc
+50
+296.565051177
+51
+153.434948823
+0
+LINE
+5
+12F
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+53.2886270414
+20
+45.3386651511
+11
+52.2279668696
+21
+42.1566846361
+0
+LINE
+5
+130
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+56.4706075567
+20
+42.1566846361
+11
+53.2886270414
+21
+41.0960244641
+0
+ARC
+5
+131
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+53.041139668
+20
+41.9091972631
+40
+0.85
+100
+AcDbArc
+50
+163.072486936
+51
+286.927513064
+0
+ARC
+5
+132
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+46.1005120477
+20
+44.1068918771
+40
+2.37170824513
+100
+AcDbArc
+50
+26.5650511771
+51
+243.434948823
+0
+LINE
+5
+133
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+45.0398518759
+20
+41.9855715331
+11
+48.2218323913
+21
+40.9249113611
+0
+LINE
+5
+134
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+48.2218323913
+20
+45.1675520491
+11
+49.282492563
+21
+41.9855715331
+0
+ARC
+5
+135
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+48.4693197647
+20
+41.7380841601
+40
+0.85
+100
+AcDbArc
+50
+253.072486936
+51
+16.9275130641
+0
+ARC
+5
+136
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+55.5006633548
+20
+34.6413474641
+40
+2.37170824513
+100
+AcDbArc
+50
+206.565051177
+51
+63.4349488229
+0
+LINE
+5
+137
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+56.5613235266
+20
+36.7626678071
+11
+53.3793430112
+21
+37.8233279791
+0
+LINE
+5
+138
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbLine
+10
+53.3793430112
+20
+33.5806872921
+11
+52.3186828395
+21
+36.7626678071
+0
+CIRCLE
+5
+139
+100
+AcDbEntity
+8
+Visible Edges(PEC)
+6
+ByLayer
+62
+256
+370
+-1
+100
+AcDbCircle
+10
+156.82650113
+20
+63.0606544828
+40
+0.75
+0
+ENDSEC
+0
+SECTION
+2
+OBJECTS
+0
+DICTIONARY
+5
+C
+330
+0
+100
+AcDbDictionary
+281
+1
+3
+ACAD_GROUP
+350
+D
+0
+DICTIONARY
+5
+D
+330
+C
+100
+AcDbDictionary
+281
+1
+0
+ENDSEC
+0
+EOF
diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp
new file mode 100644
index 0000000..a614e84
--- /dev/null
+++ b/pcbnew/initpcb.cpp
@@ -0,0 +1,128 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/initpcb.cpp
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+
+#include <class_board.h>
+
+#include <pcbnew.h>
+#include <module_editor_frame.h>
+
+
+bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery )
+{
+ if( GetBoard() == NULL )
+ return false;
+
+ if( aQuery && !GetBoard()->IsEmpty() )
+ {
+ if( !IsOK( this,
+ _( "Current Board will be lost and this operation cannot be undone. Continue ?" ) ) )
+ return false;
+ }
+
+ // Clear undo and redo lists because we want a full deletion
+ GetScreen()->ClearUndoRedoList();
+ GetScreen()->ClrModify();
+
+ // Items visibility flags will be set because a new board will be created.
+ // Grid and ratsnest can be left to their previous state
+ bool showGrid = IsElementVisible( GRID_VISIBLE );
+ bool showRats = IsElementVisible( RATSNEST_VISIBLE );
+
+ // delete the old BOARD and create a new BOARD so that the default
+ // layer names are put into the BOARD.
+ SetBoard( new BOARD() );
+ SetElementVisibility( GRID_VISIBLE, showGrid );
+ SetElementVisibility( RATSNEST_VISIBLE, showRats );
+
+ SetCurItem( NULL );
+
+ // clear filename, to avoid overwriting an old file
+ GetBoard()->SetFileName( wxEmptyString );
+
+ GetScreen()->InitDataPoints( GetPageSizeIU() );
+
+ GetBoard()->ResetHighLight();
+
+ // Enable all layers (SetCopperLayerCount() will adjust the copper layers enabled)
+ GetBoard()->SetEnabledLayers( LSET().set() );
+
+ // Default copper layers count set to 2: double layer board
+ GetBoard()->SetCopperLayerCount( 2 );
+
+ // Update display (some options depend on the board setup)
+ GetBoard()->SetVisibleLayers( LSET().set() );
+ ReCreateLayerBox();
+ ReCreateAuxiliaryToolbar();
+ ReFillLayerWidget();
+ UpdateTitle();
+
+ Zoom_Automatique( false );
+
+ return true;
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::Clear_Pcb( bool aQuery )
+{
+ if( GetBoard() == NULL )
+ return false;
+
+ if( aQuery && GetScreen()->IsModify() && !GetBoard()->IsEmpty() )
+ {
+ if( !IsOK( this,
+ _( "Current Footprint will be lost and this operation cannot be undone. Continue ?" ) ) )
+ return false;
+ }
+
+ // Clear undo and redo lists because we want a full deletion
+ GetScreen()->ClearUndoRedoList();
+ GetScreen()->ClrModify();
+
+ BOARD* board = new BOARD;
+
+ // Transfer current design settings
+ if( GetBoard() )
+ board->SetDesignSettings( GetBoard()->GetDesignSettings() );
+
+ SetBoard( board );
+
+ SetCurItem( NULL );
+
+ // clear filename, to avoid overwriting an old file
+ GetBoard()->SetFileName( wxEmptyString );
+
+ GetScreen()->InitDataPoints( GetPageSizeIU() );
+
+ Zoom_Automatique( false );
+
+ return true;
+}
diff --git a/pcbnew/invoke_pcb_dialog.h b/pcbnew/invoke_pcb_dialog.h
new file mode 100644
index 0000000..aa5ad14
--- /dev/null
+++ b/pcbnew/invoke_pcb_dialog.h
@@ -0,0 +1,162 @@
+/**
+ * @file invoke_pcb_dialog.h
+ */
+
+/* This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+// This header is an insolation layer between top most frames and any number of
+// DIALOG classes which can be called from a frame window.
+// It is a place to put invocation functions for [modal] dialogs, with benefits:
+//
+// 1) The information about each dialog class is not exposed to the frame.
+// So therefore the DIALOG class can often be kept out of a header file entirely.
+//
+// 2) The information about the calling frame is not necessarily exposed to
+// to the called dialog class, at least not in here.
+
+// The actual InvokeDialog<class>() function is usually coded at the bottom of the
+// DIALOG_<class>.cpp file.
+
+
+#ifndef INVOKE_A_DIALOG_H_
+#define INVOKE_A_DIALOG_H_
+
+
+class wxTopLevelWindow;
+class wxPoint;
+class wxSize;
+class wxString;
+
+class BOARD;
+class MODULE;
+
+// Often this is not used in the prototypes, since wxFrame is good enough and would
+// represent maximum information hiding.
+class PCB_BASE_FRAME;
+class FOOTPRINT_EDIT_FRAME;
+class FP_LIB_TABLE;
+class BOARD;
+class PCB_PLOT_PARAMS;
+
+
+/**
+ * Function InvokePcbLibTableEditor
+ * shows the modal DIALOG_FP_LIB_TABLE for purposes of editing two lib tables.
+ *
+ * @param aCaller is the wxTopLevelWindow which is invoking the dialog.
+ * @param aGlobal is the common footprint library table file being edited.
+ * @param aProject is the project specific footprint library table file being edited.
+ *
+ * @return int - bits 0 and 1 tell whether a change was made to the @a aGlobal
+ * and/or the @a aProject table, respectively. If set, table was modified.
+ */
+int InvokePcbLibTableEditor( wxTopLevelWindow* aCaller, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject );
+
+/**
+ * Function InvokeFootprintWizard
+ * Runs the footprint library wizard for easy library addition.
+ *
+ * @param aCaller is the wxTopLevelWindow which is invoking the dialog.
+ * @param aGlobal is the common footprint library table file being edited. If aGlobal is NULL, then
+ * it will not be updated.
+ * @param aProject is the project specific footprint library table file being edited. if aProject
+ * is NULL, then it will not be updated.
+ *
+ * @return int 0 - no changes
+ * 1 - changes in the global table
+ * 2 - changes in the project table
+ * 3 - changes in both tables
+ */
+int InvokeFootprintWizard( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject );
+
+/**
+ * Function Invoke3DShapeLibsDownloaderWizard
+ * Runs the downloader wizard for easy 3D shape libraries download from
+ * the official Kicad Github repository of *.3Dshape libraries.
+ *
+ * @param aCaller is the wxTopLevelWindow which is invoking the dialog.
+ */
+void Invoke3DShapeLibsDownloaderWizard( wxTopLevelWindow* aParent );
+
+
+/**
+ * Function InvokePluginOptionsEditor
+ * calls DIALOG_FP_PLUGIN_OPTIONS dialog so that plugin options set can be edited.
+ *
+ * @param aCaller is the wxTopLevelWindow which is invoking the dialog.
+ * @param aNickname is the footprint library whose options are being edited.
+ * @param aPluginType is something that will pass through IO_MGR::EnumFromStr().
+ * @param aOptions is the options string on calling into this function.
+ * @param aResult is where to put the result of the editing.
+ */
+void InvokePluginOptionsEditor( wxTopLevelWindow* aCaller, const wxString& aNickname,
+ const wxString& aPluginType, const wxString& aOptions, wxString* aResult );
+
+/**
+ * Function InvokeDXFDialogBoardImport
+ * shows the modal DIALOG_DXF_IMPORT for importing a DXF file to a board.
+
+ * @param aCaller is the wxTopLevelWindow which is invoking the dialog.
+ * @return true if the import was made.
+ */
+bool InvokeDXFDialogBoardImport( PCB_BASE_FRAME* aCaller );
+
+/**
+ * Function InvokeDXFDialogModuleImport
+ * shows the modal DIALOG_DXF_IMPORT for importing a DXF file as footprint outlines.
+ *
+ * @param aCaller is the wxTopLevelWindow which is invoking the dialog.
+ * @param aModule is the footprint currently edited.
+ * @return true if the import was made.
+ */
+bool InvokeDXFDialogModuleImport( PCB_BASE_FRAME* aCaller, MODULE* aModule );
+
+/**
+ * Function InvokeLayerSetup
+ * shows the layer setup dialog
+ * @param aCaller is the wxTopLevelWindow which is invoking the dialog.
+ * @param aBoard is the currently edited board.
+ * @return bool - true if user pressed OK (did not abort), else false.
+ */
+bool InvokeLayerSetup( wxTopLevelWindow* aCaller, BOARD* aBoard );
+
+/**
+ * Function InvokeSVGPrint
+ * shows the SVG print dialog
+ * @param aCaller is the wxTopLevelWindow which is invoking the dialog.
+ * @param aBoard is the currently edited board.
+ * @param aSettings is the current pcb plot parameters.
+ * @return bool - true if user pressed OK (did not abort), else false.
+ */
+bool InvokeSVGPrint( wxTopLevelWindow* aCaller, BOARD* aBoard, PCB_PLOT_PARAMS* aSettings );
+
+/**
+ * Function InvokeSVGPrint
+ * shows the SVG print dialog
+ * @param aCaller is the FOOTPRINT_EDIT_FRAME which is invoking the dialog.
+ * @return bool - true if user pressed OK (did not abort), else false.
+ */
+bool InvokeFPEditorPrefsDlg( FOOTPRINT_EDIT_FRAME* aCaller );
+
+#endif // INVOKE_A_DIALOG_H_
diff --git a/pcbnew/io_mgr.cpp b/pcbnew/io_mgr.cpp
new file mode 100644
index 0000000..8d3981b
--- /dev/null
+++ b/pcbnew/io_mgr.cpp
@@ -0,0 +1,272 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wx/filename.h>
+#include <wx/uri.h>
+
+#include <io_mgr.h>
+#include <legacy_plugin.h>
+#include <kicad_plugin.h>
+#include <eagle_plugin.h>
+#include <pcad2kicadpcb_plugin/pcad_plugin.h>
+#include <gpcb_plugin.h>
+#include <config.h>
+
+#if defined(BUILD_GITHUB_PLUGIN)
+ #include <github/github_plugin.h>
+#endif
+
+#include <wildcards_and_files_ext.h>
+
+#define FMT_UNIMPLEMENTED _( "Plugin '%s' does not implement the '%s' function." )
+#define FMT_NOTFOUND _( "Plugin type '%s' is not found." )
+
+
+// is there a better place for this function?
+bool PROPERTIES::Value( const char* aName, UTF8* aFetchedValue ) const
+{
+ PROPERTIES::const_iterator it = find( aName );
+
+ if( it != end() )
+ {
+ if( aFetchedValue )
+ *aFetchedValue = it->second;
+ return true;
+ }
+ return false;
+}
+
+
+// Some day plugins might be in separate DLL/DSOs, simply because of numbers of them
+// and code size. Until then, use the simplest method:
+
+// This implementation is one of two which could be done.
+// The other one would cater to DLL/DSO's. But since it would be nearly
+// impossible to link a KICAD type DLL/DSO right now without pulling in all
+// ::Draw() functions, I forgo that option temporarily.
+
+// Some day it may be possible to have some built in AND some DLL/DSO
+// plugins coexisting.
+
+
+PLUGIN* IO_MGR::PluginFind( PCB_FILE_T aFileType )
+{
+ // This implementation is subject to change, any magic is allowed here.
+ // The public IO_MGR API is the only pertinent public information.
+
+ switch( aFileType )
+ {
+ case LEGACY:
+ return new LEGACY_PLUGIN();
+
+ case KICAD:
+ return new PCB_IO();
+
+ case EAGLE:
+ return new EAGLE_PLUGIN();
+
+ case PCAD:
+ return new PCAD_PLUGIN();
+
+ case GEDA_PCB:
+ return new GPCB_PLUGIN();
+
+ case GITHUB:
+#if defined(BUILD_GITHUB_PLUGIN)
+ return new GITHUB_PLUGIN();
+#else
+ THROW_IO_ERROR( "BUILD_GITHUB_PLUGIN not enabled in cmake build environment" );
+#endif
+
+ case FILE_TYPE_NONE:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+
+void IO_MGR::PluginRelease( PLUGIN* aPlugin )
+{
+ // This function is a place holder for a future point in time where
+ // the plugin is a DLL/DSO. It could do reference counting, and then
+ // unload the DLL/DSO when count goes to zero.
+
+ delete aPlugin;
+}
+
+
+const wxString IO_MGR::ShowType( PCB_FILE_T aType )
+{
+ // keep this function in sync with EnumFromStr() relative to the
+ // text spellings. If you change the spellings, you will obsolete
+ // library tables, so don't do change, only additions are ok.
+
+ switch( aType )
+ {
+ default:
+ return wxString::Format( _( "Unknown PCB_FILE_T value: %d" ), aType );
+
+ case LEGACY:
+ return wxString( wxT( "Legacy" ) );
+
+ case KICAD:
+ return wxString( wxT( "KiCad" ) );
+
+ case EAGLE:
+ return wxString( wxT( "Eagle" ) );
+
+ case PCAD:
+ return wxString( wxT( "P-Cad" ) );
+
+ case GEDA_PCB:
+ return wxString( wxT( "Geda-PCB" ) );
+
+ case GITHUB:
+ return wxString( wxT( "Github" ) );
+ }
+}
+
+
+IO_MGR::PCB_FILE_T IO_MGR::EnumFromStr( const wxString& aType )
+{
+ // keep this function in sync with ShowType() relative to the
+ // text spellings. If you change the spellings, you will obsolete
+ // library tables, so don't do change, only additions are ok.
+
+ if( aType == wxT( "KiCad" ) )
+ return KICAD;
+
+ if( aType == wxT( "Legacy" ) )
+ return LEGACY;
+
+ if( aType == wxT( "Eagle" ) )
+ return EAGLE;
+
+ if( aType == wxT( "P-Cad" ) )
+ return PCAD;
+
+ if( aType == wxT( "Geda-PCB" ) )
+ return GEDA_PCB;
+
+ if( aType == wxT( "Github" ) )
+ return GITHUB;
+
+ // wxASSERT( blow up here )
+
+ return PCB_FILE_T( -1 );
+}
+
+
+const wxString IO_MGR::GetFileExtension( PCB_FILE_T aFileType )
+{
+ wxString ext = wxEmptyString;
+ PLUGIN* plugin = PluginFind( aFileType );
+
+ if( plugin != NULL )
+ {
+ ext = plugin->GetFileExtension();
+ PluginRelease( plugin );
+ }
+
+ return ext;
+}
+
+
+IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath )
+{
+ PCB_FILE_T ret = KICAD; // default guess, unless detected otherwise.
+ wxFileName fn( aLibPath );
+
+ if( fn.GetExt() == LegacyFootprintLibPathExtension )
+ {
+ ret = LEGACY;
+ }
+ else if( fn.GetExt() == GedaPcbFootprintLibFileExtension )
+ {
+ ret = GEDA_PCB;
+ }
+ else if( fn.GetExt() == EagleFootprintLibPathExtension )
+ {
+ ret = EAGLE;
+ }
+
+ // Test this one anyways, even though it's the default guess, to avoid
+ // the wxURI instantiation below.
+ // We default ret to KICAD above, because somebody might have
+ // mistakenly put a pretty library into a directory other than
+ // *.pretty/ with *.kicad_mod in there., and I don't want to return -1,
+ // since we only claimed to be guessing.
+ //
+ // However libraries on GitHub have names ending by .pretty
+ // so test also this is not a name starting by http (including https).
+ else if( fn.GetExt() == KiCadFootprintLibPathExtension &&
+ !aLibPath.StartsWith( wxT( "http" ) ) )
+ {
+ ret = KICAD;
+ }
+ else
+ {
+ // There is no extension for a remote repo, so test the server name.
+ wxURI uri( aLibPath );
+
+ if( uri.HasServer() && uri.GetServer() == wxT( "github.com" ) )
+ {
+ ret = GITHUB;
+ }
+ }
+
+ return ret;
+}
+
+
+BOARD* IO_MGR::Load( PCB_FILE_T aFileType, const wxString& aFileName,
+ BOARD* aAppendToMe, const PROPERTIES* aProperties )
+{
+ // release the PLUGIN even if an exception is thrown.
+ PLUGIN::RELEASER pi( PluginFind( aFileType ) );
+
+ if( (PLUGIN*) pi ) // test pi->plugin
+ {
+ return pi->Load( aFileName, aAppendToMe, aProperties ); // virtual
+ }
+
+ THROW_IO_ERROR( wxString::Format( FMT_NOTFOUND, ShowType( aFileType ).GetData() ) );
+}
+
+
+void IO_MGR::Save( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* aBoard, const PROPERTIES* aProperties )
+{
+ // release the PLUGIN even if an exception is thrown.
+ PLUGIN::RELEASER pi( PluginFind( aFileType ) );
+
+ if( (PLUGIN*) pi ) // test pi->plugin
+ {
+ pi->Save( aFileName, aBoard, aProperties ); // virtual
+ return;
+ }
+
+ THROW_IO_ERROR( wxString::Format( FMT_NOTFOUND, ShowType( aFileType ).GetData() ) );
+}
+
diff --git a/pcbnew/io_mgr.h b/pcbnew/io_mgr.h
new file mode 100644
index 0000000..80b4821
--- /dev/null
+++ b/pcbnew/io_mgr.h
@@ -0,0 +1,522 @@
+#ifndef IO_MGR_H_
+#define IO_MGR_H_
+
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2011-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2016 Kicad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <richio.h>
+#include <map>
+
+
+class BOARD;
+class PLUGIN;
+class MODULE;
+
+/**
+ * Class PROPERTIES
+ * is a name/value tuple with unique names and optional values. The names
+ * may be iterated alphabetically.
+ */
+class PROPERTIES : public std::map< std::string, UTF8 >
+{
+ // alphabetical tuple of name and value hereby defined.
+
+public:
+
+ /**
+ * Function Value
+ * fetches a property by aName and returns true if that property was found, else false.
+ * If not found, aFetchedValue is not touched.
+ * @param aName is the property or option to look for.
+ * @param aFetchedValue is where to put the value of the property if it
+ * exists and aFetchedValue is not NULL.
+ * @return bool - true if property is found, else false.
+ */
+ bool Value( const char* aName, UTF8* aFetchedValue = NULL ) const;
+};
+
+
+/**
+ * Class IO_MGR
+ * is a factory which returns an instance of a PLUGIN.
+ */
+class IO_MGR
+{
+public:
+
+ /**
+ * Enum PCB_FILE_T
+ * is a set of file types that the IO_MGR knows about, and for which there
+ * has been a plugin written.
+ */
+ enum PCB_FILE_T
+ {
+ LEGACY, ///< Legacy Pcbnew file formats prior to s-expression.
+ KICAD, ///< S-expression Pcbnew file format.
+ EAGLE,
+ PCAD,
+ GEDA_PCB, ///< Geda PCB file formats.
+ GITHUB, ///< Read only http://github.com repo holding pretty footprints
+
+ // add your type here.
+
+ // ALTIUM,
+ // etc.
+
+ FILE_TYPE_NONE
+ };
+
+ /**
+ * Function PluginFind
+ * returns a PLUGIN which the caller can use to import, export, save, or load
+ * design documents. The returned PLUGIN, may be reference counted, so please
+ * call PluginRelease() when you are done using the returned PLUGIN. It may or
+ * may not be code running from a DLL/DSO.
+ *
+ * @param aFileType is from PCB_FILE_T and tells which plugin to find.
+ *
+ * @return PLUGIN* - the plugin corresponding to aFileType or NULL if not found.
+ * Caller owns the returned object, and must call PluginRelease when done using it.
+ */
+ static PLUGIN* PluginFind( PCB_FILE_T aFileType );
+
+ /**
+ * Function PluginRelease
+ * releases a PLUGIN back to the system, and may cause it to be unloaded from memory.
+ *
+ * @param aPlugin is the one to be released, and which is no longer usable
+ * after calling this.
+ */
+ static void PluginRelease( PLUGIN* aPlugin );
+
+ /**
+ * Function ShowType
+ * returns a brief name for a plugin, given aFileType enum.
+ */
+ static const wxString ShowType( PCB_FILE_T aFileType );
+
+ /**
+ * Function EnumFromStr
+ * returns the PCB_FILE_T from the corresponding plugin type name: "kicad", "legacy", etc.
+ */
+ static PCB_FILE_T EnumFromStr( const wxString& aFileType );
+
+ /**
+ * Function GetFileExtension
+ * returns the file extension for \a aFileType.
+ *
+ * @param aFileType The #PCB_FILE_T type.
+ * @return A wxString object containing the file extension for \a aFileType or an empty
+ * string if \a aFileType is invalid.
+ */
+ static const wxString GetFileExtension( PCB_FILE_T aFileType );
+
+ /**
+ * Function GuessPluginTypeFromLibPath
+ * returns a plugin type given a footprint library's libPath.
+ */
+ static PCB_FILE_T GuessPluginTypeFromLibPath( const wxString& aLibPath );
+
+ /**
+ * Function Load
+ * finds the requested PLUGIN and if found, calls the PLUGIN->Load(..) funtion
+ * on it using the arguments passed to this function. After the PLUGIN->Load()
+ * function returns, the PLUGIN is Released() as part of this call.
+ *
+ * @param aFileType is the PCB_FILE_T of file to load.
+ *
+ * @param aFileName is the name of the file to load.
+ *
+ * @param aAppendToMe is an existing BOARD to append to, use NULL if fresh
+ * board load is wanted.
+ *
+ * @param aProperties is an associative array that allows the caller to
+ * pass additional tuning parameters to the PLUGIN.
+ *
+ * @return BOARD* - caller owns it, never NULL because exception thrown if error.
+ *
+ * @throw IO_ERROR if the PLUGIN cannot be found, file cannot be found,
+ * or file cannot be loaded.
+ */
+ static BOARD* Load( PCB_FILE_T aFileType, const wxString& aFileName,
+ BOARD* aAppendToMe = NULL, const PROPERTIES* aProperties = NULL );
+
+ /**
+ * Function Save
+ * will write either a full aBoard to a storage file in a format that this
+ * implementation knows about, or it can be used to write a portion of
+ * aBoard to a special kind of export file.
+ *
+ * @param aFileType is the PCB_FILE_T of file to save.
+ *
+ * @param aFileName is the name of a file to save to on disk.
+ * @param aBoard is the BOARD document (data tree) to save or export to disk.
+ *
+ * @param aBoard is the in memory document tree from which to extract information
+ * when writing to \a aFileName. The caller continues to own the BOARD, and
+ * the plugin should refrain from modifying the BOARD if possible.
+ *
+ * @param aProperties is an associative array that can be used to tell the
+ * saver how to save the file, because it can take any number of
+ * additional named tuning arguments that the plugin is known to support.
+ * The caller continues to own this object (plugin may not delete it), and
+ * plugins should expect it to be optionally NULL.
+ *
+ * @throw IO_ERROR if there is a problem saving or exporting.
+ */
+ static void Save( PCB_FILE_T aFileType, const wxString& aFileName,
+ BOARD* aBoard, const PROPERTIES* aProperties = NULL );
+};
+
+
+/**
+ * Class PLUGIN
+ * is a base class that BOARD loading and saving plugins should derive from.
+ * Implementations can provide either Load() or Save() functions, or both.
+ * PLUGINs throw exceptions, so it is best that you wrap your calls to these
+ * functions in a try catch block. Plugins throw exceptions because it is illegal
+ * for them to have any user interface calls in them whatsoever, i.e. no windowing
+ * or screen printing at all.
+ *
+ * <pre>
+ * try
+ * {
+ * IO_MGR::Load(...);
+ * or
+ * IO_MGR::Save(...);
+ * }
+ * catch( const IO_ERROR& ioe )
+ * {
+ * // grab text from ioe, show in error window.
+ * }
+ * </pre>
+ */
+class PLUGIN
+{
+public:
+
+ //-----<PUBLIC PLUGIN API>-------------------------------------------------
+
+ /**
+ * Function PluginName
+ * returns a brief hard coded name for this PLUGIN.
+ */
+ virtual const wxString PluginName() const = 0;
+
+ /**
+ * Function GetFileExtension
+ * returns the file extension for the PLUGIN.
+ */
+ virtual const wxString GetFileExtension() const = 0;
+
+ /**
+ * Function Load
+ * loads information from some input file format that this PLUGIN implementation
+ * knows about, into either a new BOARD or an existing one. This may be used to load an
+ * entire new BOARD, or to augment an existing one if @a aAppendToMe is not NULL.
+ *
+ * @param aFileName is the name of the file to use as input and may be foreign in
+ * nature or native in nature.
+ *
+ * @param aAppendToMe is an existing BOARD to append to, but if NULL then
+ * this means "do not append, rather load anew".
+ *
+ * @param aProperties is an associative array that can be used to tell the
+ * loader how to load the file, because it can take any number of
+ * additional named arguments that the plugin is known to support. These are
+ * tuning parameters for the import or load. The caller continues to own
+ * this object (plugin may not delete it), and plugins should expect it to
+ * be optionally NULL.
+ *
+ * @return BOARD* - the successfully loaded board, or the same one as aAppendToMe
+ * if aAppendToMe was not NULL, and caller owns it.
+ *
+ * @throw IO_ERROR if there is a problem loading, and its contents should
+ * say what went wrong, using line number and character offsets of the
+ * input file if possible.
+ */
+ virtual BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe,
+ const PROPERTIES* aProperties = NULL );
+
+ /**
+ * Function Save
+ * will write @a aBoard to a storage file in a format that this
+ * PLUGIN implementation knows about, or it can be used to write a portion of
+ * aBoard to a special kind of export file.
+ *
+ * @param aFileName is the name of a file to save to on disk.
+ *
+ * @param aBoard is the class BOARD in memory document tree from which to
+ * extract information when writing to \a aFileName. The caller continues to
+ * own the BOARD, and the plugin should refrain from modifying the BOARD if possible.
+ *
+ * @param aProperties is an associative array that can be used to tell the
+ * saver how to save the file, because it can take any number of
+ * additional named tuning arguments that the plugin is known to support.
+ * The caller continues to own this object (plugin may not delete it),
+ * and plugins should expect it to be optionally NULL.
+ *
+ * @throw IO_ERROR if there is a problem saving or exporting.
+ */
+ virtual void Save( const wxString& aFileName, BOARD* aBoard,
+ const PROPERTIES* aProperties = NULL );
+
+ //-----<Footprint Stuff>-----------------------------
+
+ /**
+ * Function FootprintEnumerate
+ * returns a list of footprint names contained within the library at @a aLibraryPath.
+ *
+ * @param aLibraryPath is a locator for the "library", usually a directory, file,
+ * or URL containing several footprints.
+ *
+ * @param aProperties is an associative array that can be used to tell the
+ * plugin anything needed about how to perform with respect to @a aLibraryPath.
+ * The caller continues to own this object (plugin may not delete it), and
+ * plugins should expect it to be optionally NULL.
+ *
+ * @return wxArrayString - is the array of available footprint names inside
+ * a library
+ *
+ * @throw IO_ERROR if the library cannot be found, or footprint cannot be loaded.
+ */
+ virtual wxArrayString FootprintEnumerate( const wxString& aLibraryPath,
+ const PROPERTIES* aProperties = NULL );
+
+ /**
+ * Function FootprintLoad
+ * loads a footprint having @a aFootprintName from the @a aLibraryPath containing
+ * a library format that this PLUGIN knows about.
+ *
+ * @param aLibraryPath is a locator for the "library", usually a directory, file,
+ * or URL containing several footprints.
+ *
+ * @param aFootprintName is the name of the footprint to load.
+ *
+ * @param aProperties is an associative array that can be used to tell the
+ * loader implementation to do something special, because it can take any number of
+ * additional named tuning arguments that the plugin is known to support.
+ * The caller continues to own this object (plugin may not delete it), and
+ * plugins should expect it to be optionally NULL.
+ *
+ * @return MODULE* - if found caller owns it, else NULL if not found.
+ *
+ * @throw IO_ERROR if the library cannot be found or read. No exception
+ * is thrown in the case where aFootprintName cannot be found.
+ */
+ virtual MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties = NULL );
+
+ /**
+ * Function FootprintSave
+ * will write @a aModule to an existing library located at @a aLibraryPath.
+ * If a footprint by the same name already exists, it is replaced.
+ *
+ * @param aLibraryPath is a locator for the "library", usually a directory, file,
+ * or URL containing several footprints.
+ *
+ * @param aFootprint is what to store in the library. The caller continues
+ * to own the footprint after this call.
+ *
+ * @param aProperties is an associative array that can be used to tell the
+ * saver how to save the footprint, because it can take any number of
+ * additional named tuning arguments that the plugin is known to support.
+ * The caller continues to own this object (plugin may not delete it), and
+ * plugins should expect it to be optionally NULL.
+ *
+ * @throw IO_ERROR if there is a problem saving.
+ */
+ virtual void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint,
+ const PROPERTIES* aProperties = NULL );
+
+ /**
+ * Function FootprintDelete
+ * deletes @a aFootprintName from the library at @a aLibraryPath.
+ *
+ * @param aLibraryPath is a locator for the "library", usually a directory, file,
+ * or URL containing several footprints.
+ *
+ * @param aFootprintName is the name of a footprint to delete from the specified library.
+ *
+ * @param aProperties is an associative array that can be used to tell the
+ * library delete function anything special, because it can take any number of
+ * additional named tuning arguments that the plugin is known to support.
+ * The caller continues to own this object (plugin may not delete it), and
+ * plugins should expect it to be optionally NULL.
+ *
+ * @throw IO_ERROR if there is a problem finding the footprint or the library, or deleting it.
+ */
+ virtual void FootprintDelete( const wxString& aLibraryPath,
+ const wxString& aFootprintName, const PROPERTIES* aProperties = NULL );
+
+ /**
+ * Function FootprintLibCreate
+ * creates a new empty footprint library at @a aLibraryPath empty. It is an
+ * error to attempt to create an existing library or to attempt to create
+ * on a "read only" location.
+ *
+ * @param aLibraryPath is a locator for the "library", usually a directory, file,
+ * or URL containing several footprints.
+ *
+ * @param aProperties is an associative array that can be used to tell the
+ * library create function anything special, because it can take any number of
+ * additional named tuning arguments that the plugin is known to support.
+ * The caller continues to own this object (plugin may not delete it), and
+ * plugins should expect it to be optionally NULL.
+ *
+ * @throw IO_ERROR if there is a problem finding the library, or creating it.
+ */
+ virtual void FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL );
+
+ /**
+ * Function FootprintLibDelete
+ * deletes an existing footprint library and returns true, or if library does not
+ * exist returns false, or throws an exception if library exists but is read only or
+ * cannot be deleted for some other reason.
+ *
+ * @param aLibraryPath is a locator for the "library", usually a directory
+ * or file which will contain footprints.
+ *
+ * @param aProperties is an associative array that can be used to tell the
+ * library delete implementation function anything special, because it can
+ * take any number of additional named tuning arguments that the plugin is
+ * known to support. The caller continues to own this object (plugin may
+ * not delete it), and plugins should expect it to be optionally NULL.
+ *
+ * @return bool - true if library deleted, false if library did not exist.
+ *
+ * @throw IO_ERROR if there is a problem deleting an existing library.
+ */
+ virtual bool FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL );
+
+ /**
+ * Function IsFootprintLibWritable
+ * returns true iff the library at @a aLibraryPath is writable. (Often
+ * system libraries are read only because of where they are installed.)
+ *
+ * @param aLibraryPath is a locator for the "library", usually a directory, file,
+ * or URL containing several footprints.
+ *
+ * @throw IO_ERROR if no library at aLibraryPath exists.
+ */
+ virtual bool IsFootprintLibWritable( const wxString& aLibraryPath );
+
+ /**
+ * Function FootprintLibOptions
+ * appends supported PLUGIN options to @a aListToAppenTo along with
+ * internationalized descriptions. Options are typically appended so
+ * that a derived PLUGIN can call its base class
+ * function by the same name first, thus inheriting options declared there.
+ * (Some base class options could pertain to all Footprint*() functions
+ * in all derived PLUGINs.) Note that since aListToAppendTo is a PROPERTIES
+ * object, all options will be unique and last guy wins.
+ *
+ * @param aListToAppendTo holds a tuple of
+ * <dl>
+ <dt>option</dt>
+ <dd>This eventually is what shows up into the fp-lib-table "options"
+ field, possibly combined with others.</dd>
+ <dt>internationalized description</dt>
+ <dd>The internationalized description is displayed in DIALOG_FP_PLUGIN_OPTIONS.
+ * It may be multi-line and be quite explanatory of the option.</dd>
+ </dl>
+ * <br>
+ * In the future perhaps @a aListToAppendTo evolves to something capable of also
+ * holding a wxValidator for the cells in said dialog:
+ * http://forums.wxwidgets.org/viewtopic.php?t=23277&p=104180.
+ This would require a 3 column list, and introducing wx GUI knowledge to
+ PLUGIN, which has been avoided to date.
+ */
+ virtual void FootprintLibOptions( PROPERTIES* aListToAppendTo ) const;
+
+ //-----</PUBLIC PLUGIN API>------------------------------------------------
+
+
+ /* The compiler writes the "zero argument" constructor for a PLUGIN
+ automatically if you do not provide one. If you decide you need to
+ provide a zero argument constructor of your own design, that is allowed.
+ It must be public, and it is what the IO_MGR uses. Parameters may be
+ passed into a PLUGIN via the PROPERTIES variable for any of the public
+ API functions which take one.
+ */
+
+ virtual ~PLUGIN()
+ {
+ //printf( "~%s", __func__ );
+ };
+
+
+ /**
+ * Class RELEASER
+ * releases a PLUGIN in the context of a potential thrown exception, through
+ * its destructor.
+ */
+ class RELEASER
+ {
+ PLUGIN* plugin;
+
+ // private assignment operator so it's illegal
+ RELEASER& operator=( RELEASER& aOther ) { return *this; }
+
+ // private copy constructor so it's illegal
+ RELEASER( const RELEASER& aOther ) {}
+
+ public:
+ RELEASER( PLUGIN* aPlugin = NULL ) :
+ plugin( aPlugin )
+ {
+ }
+
+ ~RELEASER()
+ {
+ if( plugin )
+ release();
+ }
+
+ void release()
+ {
+ IO_MGR::PluginRelease( plugin );
+ plugin = NULL;
+ }
+
+ void set( PLUGIN* aPlugin )
+ {
+ if( plugin )
+ release();
+ plugin = aPlugin;
+ }
+
+ operator PLUGIN* () const
+ {
+ return plugin;
+ }
+
+ PLUGIN* operator -> () const
+ {
+ return plugin;
+ }
+ };
+};
+
+#endif // IO_MGR_H_
diff --git a/pcbnew/kicad_netlist_reader.cpp b/pcbnew/kicad_netlist_reader.cpp
new file mode 100644
index 0000000..18e75cf
--- /dev/null
+++ b/pcbnew/kicad_netlist_reader.cpp
@@ -0,0 +1,484 @@
+/**
+ * @file kicad_netlist_reader.cpp
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2011 Jean-Pierre Charras.
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wx/wx.h>
+#include <netlist_lexer.h> // netlist_lexer is common to Eeschema and Pcbnew
+#include <macros.h>
+
+#include <pcb_netlist.h>
+#include <netlist_reader.h>
+
+using namespace NL_T;
+
+
+void KICAD_NETLIST_READER::LoadNetlist() throw ( IO_ERROR, PARSE_ERROR, boost::bad_pointer )
+{
+ m_parser->Parse();
+
+ if( m_footprintReader )
+ {
+ m_footprintReader->Load( m_netlist );
+
+ // Sort the component pins so they are in the same order as the legacy format. This
+ // is useful for comparing legacy and s-expression netlist dumps.
+ for( unsigned i = 0; i < m_netlist->GetCount(); i++ )
+ m_netlist->GetComponent( i )->SortPins();
+ }
+}
+
+
+// KICAD_NETLIST_PARSER
+KICAD_NETLIST_PARSER::KICAD_NETLIST_PARSER( LINE_READER* aReader, NETLIST* aNetlist ) :
+ NETLIST_LEXER( aReader )
+{
+ m_lineReader = aReader;
+ m_netlist = aNetlist;
+ token = T_NONE;
+}
+
+
+void KICAD_NETLIST_PARSER::skipCurrent() throw( IO_ERROR, PARSE_ERROR )
+{
+ int curr_level = 0;
+
+ while( ( token = NextTok() ) != T_EOF )
+ {
+ if( token == T_LEFT )
+ curr_level--;
+
+ if( token == T_RIGHT )
+ {
+ curr_level++;
+
+ if( curr_level > 0 )
+ return;
+ }
+ }
+}
+
+
+void KICAD_NETLIST_PARSER::Parse() throw( IO_ERROR, PARSE_ERROR, boost::bad_pointer )
+{
+ int plevel = 0; // the count of ')' to read and end of file,
+ // after parsing all sections
+
+ while( ( token = NextTok() ) != T_EOF )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_export: // The netlist starts here.
+ // nothing to do here,
+ // just increment the count of ')' to read and end of file
+ plevel++;
+ break;
+
+ case T_version: // The netlist starts here.
+ // version id not yet used: read it but does not use it
+ NextTok();
+ NeedRIGHT();
+ break;
+
+ case T_components: // The section comp starts here.
+ while( ( token = NextTok() ) != T_RIGHT )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ if( token == T_comp ) // A component section found. Read it
+ parseComponent();
+ }
+
+ break;
+
+ case T_nets: // The section nets starts here.
+ while( ( token = NextTok() ) != T_RIGHT )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ if( token == T_net )
+ {
+ // A net section if found. Read it
+ parseNet();
+ }
+ }
+
+ break;
+
+ case T_libparts: // The section libparts starts here.
+ while( ( token = NextTok() ) != T_RIGHT )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ if( token == T_libpart )
+ {
+ // A libpart section if found. Read it
+ parseLibPartList();
+ }
+ }
+
+ break;
+
+ case T_libraries: // The section libraries starts here.
+ // List of libraries in use.
+ // Not used here, just skip it
+ skipCurrent();
+ break;
+
+ case T_design: // The section design starts here.
+ // Not used (mainly they are comments), just skip it
+ skipCurrent();
+ break;
+
+ case T_RIGHT: // The closing parenthesis of the file.
+ // Not used (mainly they are comments), just skip it
+ plevel--;
+ break;
+
+ default:
+ skipCurrent();
+ break;
+ }
+ }
+
+ if( plevel != 0 )
+ {
+ wxLogDebug( wxT( "KICAD_NETLIST_PARSER::Parse(): bad parenthesis count (count = %d"),
+ plevel );
+ }
+}
+
+
+void KICAD_NETLIST_PARSER::parseNet() throw( IO_ERROR, PARSE_ERROR )
+{
+ /* Parses a section like
+ * (net (code 20) (name /PC-A0)
+ * (node (ref BUS1) (pin 62))
+ * (node (ref U3) (pin 3))
+ * (node (ref U9) (pin M6)))
+ */
+
+ COMPONENT* component = NULL;
+ wxString code;
+ wxString name;
+ wxString reference;
+ wxString pin;
+ int nodecount = 0;
+
+ // The token net was read, so the next data is (code <number>)
+ while( (token = NextTok()) != T_RIGHT )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_code:
+ NeedSYMBOLorNUMBER();
+ code = FROM_UTF8( CurText() );
+ NeedRIGHT();
+ break;
+
+ case T_name:
+ NeedSYMBOLorNUMBER();
+ name = FROM_UTF8( CurText() );
+ NeedRIGHT();
+
+ if( name.IsEmpty() ) // Give a dummy net name like N-000109
+ name = wxT("N-00000") + code;
+
+ break;
+
+ case T_node:
+ while( (token = NextTok()) != T_RIGHT )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_ref:
+ NeedSYMBOLorNUMBER();
+ reference = FROM_UTF8( CurText() );
+ NeedRIGHT();
+ break;
+
+ case T_pin:
+ NeedSYMBOLorNUMBER();
+ pin = FROM_UTF8( CurText() );
+ NeedRIGHT();
+ break;
+
+ default:
+ skipCurrent();
+ break;
+ }
+ }
+
+
+ component = m_netlist->GetComponentByReference( reference );
+
+ // Cannot happen if the netlist is valid.
+ if( component == NULL )
+ {
+ wxString msg;
+ msg.Printf( _( "Cannot find component with reference \"%s\" in netlist." ),
+ GetChars( reference ) );
+ THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), m_lineReader->Line(),
+ m_lineReader->LineNumber(), m_lineReader->Length() );
+ }
+
+ component->AddNet( pin, name );
+ nodecount++;
+ break;
+
+ default:
+ skipCurrent();
+ break;
+ }
+ }
+}
+
+
+void KICAD_NETLIST_PARSER::parseComponent() throw( IO_ERROR, PARSE_ERROR, boost::bad_pointer )
+{
+ /* Parses a section like
+ * (comp (ref P1)
+ * (value DB25FEMELLE)
+ * (footprint DB25FC)
+ * (libsource (lib conn) (part DB25))
+ * (sheetpath (names /) (tstamps /))
+ * (tstamp 3256759C))
+ *
+ * other fields (unused) are skipped
+ * A component need a reference, value, footprint name and a full time stamp
+ * The full time stamp is the sheetpath time stamp + the component time stamp
+ */
+ FPID fpid;
+ wxString footprint;
+ wxString ref;
+ wxString value;
+ wxString library;
+ wxString name;
+ wxString pathtimestamp, timestamp;
+
+ // The token comp was read, so the next data is (ref P1)
+ while( (token = NextTok()) != T_RIGHT )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_ref:
+ NeedSYMBOLorNUMBER();
+ ref = FROM_UTF8( CurText() );
+ NeedRIGHT();
+ break;
+
+ case T_value:
+ NeedSYMBOLorNUMBER();
+ value = FROM_UTF8( CurText() );
+ NeedRIGHT();
+ break;
+
+ case T_footprint:
+ NeedSYMBOLorNUMBER();
+ footprint = FromUTF8();
+ NeedRIGHT();
+ break;
+
+ case T_libsource:
+ // Read libsource
+ while( (token = NextTok()) != T_RIGHT )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ if( token == T_lib )
+ {
+ NeedSYMBOLorNUMBER();
+ library = FROM_UTF8( CurText() );
+ NeedRIGHT();
+ }
+ else if( token == T_part )
+ {
+ NeedSYMBOLorNUMBER();
+ name = FROM_UTF8( CurText() );
+ NeedRIGHT();
+ }
+ else
+ {
+ Expecting( "part or lib" );
+ }
+ }
+ break;
+
+ case T_sheetpath:
+ while( ( token = NextTok() ) != T_tstamps );
+ NeedSYMBOLorNUMBER();
+ pathtimestamp = FROM_UTF8( CurText() );
+ NeedRIGHT();
+ NeedRIGHT();
+ break;
+
+ case T_tstamp:
+ NeedSYMBOLorNUMBER();
+ timestamp = FROM_UTF8( CurText() );
+ NeedRIGHT();
+ break;
+
+ default:
+ // Skip not used data (i.e all other tokens)
+ skipCurrent();
+ break;
+ }
+ }
+
+ if( !footprint.IsEmpty() && fpid.Parse( footprint ) >= 0 )
+ {
+ wxString error;
+ error.Printf( _( "invalid footprint ID in\nfile: <%s>\nline: %d\noffset: %d" ),
+ GetChars( CurSource() ), CurLineNumber(), CurOffset() );
+
+ THROW_IO_ERROR( error );
+ }
+
+ pathtimestamp += timestamp;
+ COMPONENT* component = new COMPONENT( fpid, ref, value, pathtimestamp );
+ component->SetName( name );
+ component->SetLibrary( library );
+ m_netlist->AddComponent( component );
+}
+
+
+void KICAD_NETLIST_PARSER::parseLibPartList() throw( IO_ERROR, PARSE_ERROR )
+{
+ /* Parses a section like
+ * (libpart (lib device) (part C)
+ * (aliases
+ * (alias Cxx)
+ * (alias Cyy))
+ * (description "Condensateur non polarise")
+ * (footprints
+ * (fp SM*)
+ * (fp C?)
+ * (fp C1-1))
+ * (fields
+ * (field (name Reference) C)
+ * (field (name Value) C))
+ * (pins
+ * (pin (num 1) (name ~) (type passive))
+ * (pin (num 2) (name ~) (type passive))))
+ *
+ * Currently footprints section/fp are read and data stored
+ * other fields (unused) are skipped
+ */
+ COMPONENT* component = NULL;
+ wxString libName;
+ wxString libPartName;
+ wxArrayString footprintFilters;
+ wxArrayString aliases;
+
+ // The last token read was libpart, so read the next token
+ while( (token = NextTok()) != T_RIGHT )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_lib:
+ NeedSYMBOLorNUMBER();
+ libName = FROM_UTF8( CurText() );
+ NeedRIGHT();
+ break;
+
+ case T_part:
+ NeedSYMBOLorNUMBER();
+ libPartName = FROM_UTF8( CurText() );
+ NeedRIGHT();
+ break;
+
+ case T_footprints:
+ // Read all fp elements (footprint filter item)
+ while( (token = NextTok()) != T_RIGHT )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ if( token != T_fp )
+ Expecting( T_fp );
+
+ NeedSYMBOLorNUMBER();
+ footprintFilters.Add( FROM_UTF8( CurText() ) );
+ NeedRIGHT();
+ }
+
+ break;
+
+ case T_aliases:
+ while( (token = NextTok()) != T_RIGHT )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ if( token != T_alias )
+ Expecting( T_alias );
+
+ NeedSYMBOLorNUMBER();
+ aliases.Add( FROM_UTF8( CurText() ) );
+ NeedRIGHT();
+ }
+ break;
+ default:
+ // Skip not used data (i.e all other tokens)
+ skipCurrent();
+ break;
+ }
+ }
+
+ // Find all of the components that reference this component library part definition.
+ for( unsigned i = 0; i < m_netlist->GetCount(); i++ )
+ {
+ component = m_netlist->GetComponent( i );
+
+ if( component->IsLibSource( libName, libPartName ) )
+ component->SetFootprintFilters( footprintFilters );
+
+ for( unsigned jj = 0; jj < aliases.GetCount(); jj++ )
+ {
+ if( component->IsLibSource( libName, aliases[jj] ) )
+ component->SetFootprintFilters( footprintFilters );
+ }
+
+ }
+}
diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp
new file mode 100644
index 0000000..528be48
--- /dev/null
+++ b/pcbnew/kicad_plugin.cpp
@@ -0,0 +1,2050 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 CERN
+ * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <kicad_string.h>
+#include <common.h>
+#include <build_version.h> // LEGACY_BOARD_FILE_VERSION
+#include <macros.h>
+#include <3d_struct.h>
+#include <wildcards_and_files_ext.h>
+#include <base_units.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_pcb_text.h>
+#include <class_dimension.h>
+#include <class_track.h>
+#include <class_zone.h>
+#include <class_drawsegment.h>
+#include <class_mire.h>
+#include <class_edge_mod.h>
+#include <pcb_plot_params.h>
+#include <zones.h>
+#include <kicad_plugin.h>
+#include <pcb_parser.h>
+
+#include <wx/dir.h>
+#include <wx/filename.h>
+#include <wx/wfstream.h>
+#include <boost/ptr_container/ptr_map.hpp>
+#include <memory.h>
+
+using namespace PCB_KEYS_T;
+
+#define FMTIU BOARD_ITEM::FormatInternalUnits
+
+/**
+ * Definition for enabling and disabling footprint library trace output. See the
+ * wxWidgets documentation on using the WXTRACE environment variable.
+ */
+static const wxString traceFootprintLibrary( wxT( "KicadFootprintLib" ) );
+
+///> Removes empty nets (i.e. with node count equal zero) from net classes
+void filterNetClass( const BOARD& aBoard, NETCLASS& aNetClass )
+{
+ for( NETCLASS::const_iterator it = aNetClass.begin(); it != aNetClass.end(); )
+ {
+ NETINFO_ITEM* netinfo = aBoard.FindNet( *it );
+
+ if( netinfo && netinfo->GetNodesCount() <= 0 ) // hopefully there are no nets with negative
+ aNetClass.Remove( it++ ); // node count, but you never know..
+ else
+ ++it;
+ }
+}
+
+/**
+ * Class FP_CACHE_ITEM
+ * is helper class for creating a footprint library cache.
+ *
+ * The new footprint library design is a file path of individual module files
+ * that contain a single module per file. This class is a helper only for the
+ * footprint portion of the PLUGIN API, and only for the #PCB_IO plugin. It is
+ * private to this implementation file so it is not placed into a header.
+ */
+class FP_CACHE_ITEM
+{
+ wxFileName m_file_name; ///< The the full file name and path of the footprint to cache.
+ wxDateTime m_mod_time; ///< The last file modified time stamp.
+ std::auto_ptr<MODULE> m_module;
+
+public:
+ FP_CACHE_ITEM( MODULE* aModule, const wxFileName& aFileName );
+
+ wxString GetName() const { return m_file_name.GetDirs().Last(); }
+ wxFileName GetFileName() const { return m_file_name; }
+
+ /// Tell if the disk content or the lib_path has changed.
+ bool IsModified() const;
+
+ MODULE* GetModule() const { return m_module.get(); }
+ void UpdateModificationTime() { m_mod_time = m_file_name.GetModificationTime(); }
+};
+
+
+FP_CACHE_ITEM::FP_CACHE_ITEM( MODULE* aModule, const wxFileName& aFileName ) :
+ m_module( aModule )
+{
+ m_file_name = aFileName;
+
+ if( m_file_name.FileExists() )
+ m_mod_time = m_file_name.GetModificationTime();
+ else
+ m_mod_time.Now();
+}
+
+
+bool FP_CACHE_ITEM::IsModified() const
+{
+ if( !m_file_name.FileExists() )
+ return false;
+
+ wxLogTrace( traceFootprintLibrary, wxT( "File '%s', m_mod_time %s-%s, file mod time: %s-%s." ),
+ GetChars( m_file_name.GetFullPath() ),
+ GetChars( m_mod_time.FormatDate() ), GetChars( m_mod_time.FormatTime() ),
+ GetChars( m_file_name.GetModificationTime().FormatDate() ),
+ GetChars( m_file_name.GetModificationTime().FormatTime() ) );
+
+ return m_file_name.GetModificationTime() != m_mod_time;
+}
+
+
+typedef boost::ptr_map< std::string, FP_CACHE_ITEM > MODULE_MAP;
+typedef MODULE_MAP::iterator MODULE_ITER;
+typedef MODULE_MAP::const_iterator MODULE_CITER;
+
+
+class FP_CACHE
+{
+ PCB_IO* m_owner; /// Plugin object that owns the cache.
+ wxFileName m_lib_path; /// The path of the library.
+ wxDateTime m_mod_time; /// Footprint library path modified time stamp.
+ MODULE_MAP m_modules; /// Map of footprint file name per MODULE*.
+
+public:
+ FP_CACHE( PCB_IO* aOwner, const wxString& aLibraryPath );
+
+ wxString GetPath() const { return m_lib_path.GetPath(); }
+ wxDateTime GetLastModificationTime() const { return m_mod_time; }
+ bool IsWritable() const { return m_lib_path.IsOk() && m_lib_path.IsDirWritable(); }
+ MODULE_MAP& GetModules() { return m_modules; }
+
+ // Most all functions in this class throw IO_ERROR exceptions. There are no
+ // error codes nor user interface calls from here, nor in any PLUGIN.
+ // Catch these exceptions higher up please.
+
+ /// save the entire legacy library to m_lib_name;
+ void Save();
+
+ void Load();
+
+ void Remove( const wxString& aFootprintName );
+
+ wxDateTime GetLibModificationTime() const;
+
+ /**
+ * Function IsModified
+ * check if the footprint cache has been modified relative to \a aLibPath
+ * and \a aFootprintName.
+ *
+ * @param aLibPath is a path to test the current cache library path against.
+ * @param aFootprintName is the footprint name in the cache to test. If the footprint
+ * name is empty, the all the footprint files in the library are
+ * checked to see if they have been modified.
+ * @return true if the cache has been modified.
+ */
+ bool IsModified( const wxString& aLibPath,
+ const wxString& aFootprintName = wxEmptyString ) const;
+
+ /**
+ * Function IsPath
+ * checks if \a aPath is the same as the current cache path.
+ *
+ * This tests paths by converting \a aPath using the native separators. Internally
+ * #FP_CACHE stores the current path using native separators. This prevents path
+ * miscompares on Windows due to the fact that paths can be stored with / instead of \\
+ * in the footprint library table.
+ *
+ * @param aPath is the library path to test against.
+ * @return true if \a aPath is the same as the cache path.
+ */
+ bool IsPath( const wxString& aPath ) const;
+};
+
+
+FP_CACHE::FP_CACHE( PCB_IO* aOwner, const wxString& aLibraryPath )
+{
+ m_owner = aOwner;
+ m_lib_path.SetPath( aLibraryPath );
+}
+
+
+wxDateTime FP_CACHE::GetLibModificationTime() const
+{
+ return m_lib_path.GetModificationTime();
+}
+
+
+void FP_CACHE::Save()
+{
+ if( !m_lib_path.DirExists() && !m_lib_path.Mkdir() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "Cannot create footprint library path '%s'" ),
+ m_lib_path.GetPath().GetData() ) );
+ }
+
+ if( !m_lib_path.IsDirWritable() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "Footprint library path '%s' is read only" ),
+ GetChars( m_lib_path.GetPath() ) ) );
+ }
+
+ for( MODULE_ITER it = m_modules.begin(); it != m_modules.end(); ++it )
+ {
+ wxFileName fn = it->second->GetFileName();
+
+ if( fn.FileExists() && !it->second->IsModified() )
+ continue;
+
+ wxString tempFileName =
+#ifdef USE_TMP_FILE
+ fn.CreateTempFileName( fn.GetPath() );
+#else
+ fn.GetFullPath();
+#endif
+ // Allow file output stream to go out of scope to close the file stream before
+ // renaming the file.
+ {
+ wxLogTrace( traceFootprintLibrary, wxT( "Creating temporary library file %s" ),
+ GetChars( tempFileName ) );
+
+ FILE_OUTPUTFORMATTER formatter( tempFileName );
+
+ m_owner->SetOutputFormatter( &formatter );
+ m_owner->Format( (BOARD_ITEM*) it->second->GetModule() );
+ }
+
+#ifdef USE_TMP_FILE
+ wxRemove( fn.GetFullPath() ); // it is not an error if this does not exist
+
+ // Even on linux you can see an _intermittent_ error when calling wxRename(),
+ // and it is fully inexplicable. See if this dodges the error.
+ wxMilliSleep( 250L );
+
+ if( !wxRenameFile( tempFileName, fn.GetFullPath() ) )
+ {
+ wxString msg = wxString::Format(
+ _( "Cannot rename temporary file '%s' to footprint library file '%s'" ),
+ GetChars( tempFileName ),
+ GetChars( fn.GetFullPath() )
+ );
+ THROW_IO_ERROR( msg );
+ }
+#endif
+ it->second->UpdateModificationTime();
+ m_mod_time = GetLibModificationTime();
+ }
+}
+
+
+void FP_CACHE::Load()
+{
+ wxDir dir( m_lib_path.GetPath() );
+
+ if( !dir.IsOpened() )
+ {
+ wxString msg = wxString::Format(
+ _( "Footprint library path '%s' does not exist" ),
+ GetChars( m_lib_path.GetPath() )
+ );
+
+ THROW_IO_ERROR( msg );
+ }
+
+ wxString fpFileName;
+ wxString wildcard = wxT( "*." ) + KiCadFootprintFileExtension;
+
+ if( dir.GetFirst( &fpFileName, wildcard, wxDIR_FILES ) )
+ {
+ wxString cacheError;
+
+ do
+ {
+ // prepend the libpath into fullPath
+ wxFileName fullPath( m_lib_path.GetPath(), fpFileName );
+
+ // Queue I/O errors so only files that fail to parse don't get loaded.
+ try
+ {
+ FILE_LINE_READER reader( fullPath.GetFullPath() );
+
+ m_owner->m_parser->SetLineReader( &reader );
+
+ std::string name = TO_UTF8( fullPath.GetName() );
+ MODULE* footprint = (MODULE*) m_owner->m_parser->Parse();
+
+ // The footprint name is the file name without the extension.
+ footprint->SetFPID( FPID( fullPath.GetName() ) );
+ m_modules.insert( name, new FP_CACHE_ITEM( footprint, fullPath ) );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ if( !cacheError.IsEmpty() )
+ cacheError += "\n\n";
+
+ cacheError += ioe.errorText;
+ }
+ } while( dir.GetNext( &fpFileName ) );
+
+ // Remember the file modification time of library file when the
+ // cache snapshot was made, so that in a networked environment we will
+ // reload the cache as needed.
+ m_mod_time = GetLibModificationTime();
+
+ if( !cacheError.IsEmpty() )
+ THROW_IO_ERROR( cacheError );
+ }
+}
+
+
+void FP_CACHE::Remove( const wxString& aFootprintName )
+{
+ std::string footprintName = TO_UTF8( aFootprintName );
+
+ MODULE_CITER it = m_modules.find( footprintName );
+
+ if( it == m_modules.end() )
+ {
+ wxString msg = wxString::Format(
+ _( "library '%s' has no footprint '%s' to delete" ),
+ GetChars( m_lib_path.GetPath() ),
+ GetChars( aFootprintName )
+ );
+ THROW_IO_ERROR( msg );
+ }
+
+ // Remove the module from the cache and delete the module file from the library.
+ wxString fullPath = it->second->GetFileName().GetFullPath();
+ m_modules.erase( footprintName );
+ wxRemoveFile( fullPath );
+}
+
+
+bool FP_CACHE::IsPath( const wxString& aPath ) const
+{
+ // Converts path separators to native path separators
+ wxFileName newPath;
+ newPath.AssignDir( aPath );
+
+ return m_lib_path == newPath;
+}
+
+
+bool FP_CACHE::IsModified( const wxString& aLibPath, const wxString& aFootprintName ) const
+{
+ // The library is modified if the library path got deleted or changed.
+ if( !m_lib_path.DirExists() || !IsPath( aLibPath ) )
+ return true;
+
+ // If no footprint was specified, check every file modification time against the time
+ // it was loaded.
+ if( aFootprintName.IsEmpty() )
+ {
+ for( MODULE_CITER it = m_modules.begin(); it != m_modules.end(); ++it )
+ {
+ wxFileName fn = m_lib_path;
+
+ fn.SetName( it->second->GetFileName().GetName() );
+ fn.SetExt( KiCadFootprintFileExtension );
+
+ if( !fn.FileExists() )
+ {
+ wxLogTrace( traceFootprintLibrary,
+ wxT( "Footprint cache file '%s' does not exist." ),
+ fn.GetFullPath().GetData() );
+ return true;
+ }
+
+ if( it->second->IsModified() )
+ {
+ wxLogTrace( traceFootprintLibrary,
+ wxT( "Footprint cache file '%s' has been modified." ),
+ fn.GetFullPath().GetData() );
+ return true;
+ }
+ }
+ }
+ else
+ {
+ MODULE_CITER it = m_modules.find( TO_UTF8( aFootprintName ) );
+
+ if( it == m_modules.end() || it->second->IsModified() )
+ return true;
+ }
+
+ return false;
+}
+
+
+void PCB_IO::Save( const wxString& aFileName, BOARD* aBoard, const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ init( aProperties );
+
+ m_board = aBoard; // after init()
+
+ // Prepare net mapping that assures that net codes saved in a file are consecutive integers
+ m_mapping->SetBoard( aBoard );
+
+ FILE_OUTPUTFORMATTER formatter( aFileName );
+
+ m_out = &formatter; // no ownership
+
+ m_out->Print( 0, "(kicad_pcb (version %d) (host pcbnew %s)\n", SEXPR_BOARD_FILE_VERSION,
+ formatter.Quotew( GetBuildVersion() ).c_str() );
+
+ Format( aBoard, 1 );
+
+ m_out->Print( 0, ")\n" );
+}
+
+
+BOARD_ITEM* PCB_IO::Parse( const wxString& aClipboardSourceInput )
+ throw( FUTURE_FORMAT_ERROR, PARSE_ERROR, IO_ERROR )
+{
+ std::string input = TO_UTF8( aClipboardSourceInput );
+
+ STRING_LINE_READER reader( input, wxT( "clipboard" ) );
+
+ m_parser->SetLineReader( &reader );
+
+ try
+ {
+ return m_parser->Parse();
+ }
+ catch( const PARSE_ERROR& parse_error )
+ {
+ if( m_parser->IsTooRecent() )
+ throw FUTURE_FORMAT_ERROR( parse_error, m_parser->GetRequiredVersion() );
+ else
+ throw;
+ }
+}
+
+
+void PCB_IO::Format( BOARD_ITEM* aItem, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ LOCALE_IO toggle; // public API function, perform anything convenient for caller
+
+ switch( aItem->Type() )
+ {
+ case PCB_T:
+ format( static_cast<BOARD*>( aItem ), aNestLevel );
+ break;
+
+ case PCB_DIMENSION_T:
+ format( static_cast<DIMENSION*>( aItem ), aNestLevel );
+ break;
+
+ case PCB_LINE_T:
+ format( static_cast<DRAWSEGMENT*>( aItem ), aNestLevel );
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ format( static_cast<EDGE_MODULE*>( aItem ), aNestLevel );
+ break;
+
+ case PCB_TARGET_T:
+ format( static_cast<PCB_TARGET*>( aItem ), aNestLevel );
+ break;
+
+ case PCB_MODULE_T:
+ format( static_cast<MODULE*>( aItem ), aNestLevel );
+ break;
+
+ case PCB_PAD_T:
+ format( static_cast<D_PAD*>( aItem ), aNestLevel );
+ break;
+
+ case PCB_TEXT_T:
+ format( static_cast<TEXTE_PCB*>( aItem ), aNestLevel );
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ format( static_cast<TEXTE_MODULE*>( aItem ), aNestLevel );
+ break;
+
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ format( static_cast<TRACK*>( aItem ), aNestLevel );
+ break;
+
+ case PCB_ZONE_AREA_T:
+ format( static_cast<ZONE_CONTAINER*>( aItem ), aNestLevel );
+ break;
+
+ default:
+ wxFAIL_MSG( wxT( "Cannot format item " ) + aItem->GetClass() );
+ }
+}
+
+
+void PCB_IO::formatLayer( const BOARD_ITEM* aItem ) const
+{
+ if( m_ctl & CTL_STD_LAYER_NAMES )
+ {
+ LAYER_ID layer = aItem->GetLayer();
+
+ // English layer names should never need quoting.
+ m_out->Print( 0, " (layer %s)", TO_UTF8( BOARD::GetStandardLayerName( layer ) ) );
+ }
+ else
+ m_out->Print( 0, " (layer %s)", m_out->Quotew( aItem->GetLayerName() ).c_str() );
+}
+
+
+void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ const BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings();
+
+ m_out->Print( 0, "\n" );
+
+ m_out->Print( aNestLevel, "(general\n" );
+ m_out->Print( aNestLevel+1, "(links %d)\n", aBoard->GetRatsnestsCount() );
+ m_out->Print( aNestLevel+1, "(no_connects %d)\n", aBoard->GetUnconnectedNetCount() );
+
+ // Write Bounding box info
+ m_out->Print( aNestLevel+1, "(area %s %s %s %s)\n",
+ FMTIU( aBoard->GetBoundingBox().GetX() ).c_str(),
+ FMTIU( aBoard->GetBoundingBox().GetY() ).c_str(),
+ FMTIU( aBoard->GetBoundingBox().GetRight() ).c_str(),
+ FMTIU( aBoard->GetBoundingBox().GetBottom() ).c_str() );
+ m_out->Print( aNestLevel+1, "(thickness %s)\n",
+ FMTIU( dsnSettings.GetBoardThickness() ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(drawings %d)\n", aBoard->m_Drawings.GetCount() );
+ m_out->Print( aNestLevel+1, "(tracks %d)\n", aBoard->GetNumSegmTrack() );
+ m_out->Print( aNestLevel+1, "(zones %d)\n", aBoard->GetNumSegmZone() );
+ m_out->Print( aNestLevel+1, "(modules %d)\n", aBoard->m_Modules.GetCount() );
+ m_out->Print( aNestLevel+1, "(nets %d)\n", m_mapping->GetSize() );
+ m_out->Print( aNestLevel, ")\n\n" );
+
+ aBoard->GetPageSettings().Format( m_out, aNestLevel, m_ctl );
+ aBoard->GetTitleBlock().Format( m_out, aNestLevel, m_ctl );
+
+ // Layers.
+ m_out->Print( aNestLevel, "(layers\n" );
+
+ // Save only the used copper layers from front to back.
+ LSET visible_layers = aBoard->GetVisibleLayers();
+
+ for( LSEQ cu = aBoard->GetEnabledLayers().CuStack(); cu; ++cu )
+ {
+ LAYER_ID layer = *cu;
+
+ m_out->Print( aNestLevel+1, "(%d %s %s", layer,
+ m_out->Quotew( aBoard->GetLayerName( layer ) ).c_str(),
+ LAYER::ShowType( aBoard->GetLayerType( layer ) ) );
+
+ if( !visible_layers[layer] )
+ m_out->Print( 0, " hide" );
+
+ m_out->Print( 0, ")\n" );
+ }
+
+ // Save used non-copper layers in the order they are defined.
+ // desired sequence for non Cu BOARD layers.
+ static const LAYER_ID non_cu[] = {
+ B_Adhes, // 32
+ F_Adhes,
+ B_Paste,
+ F_Paste,
+ B_SilkS,
+ F_SilkS,
+ B_Mask,
+ F_Mask,
+ Dwgs_User,
+ Cmts_User,
+ Eco1_User,
+ Eco2_User,
+ Edge_Cuts,
+ Margin,
+ B_CrtYd,
+ F_CrtYd,
+ B_Fab,
+ F_Fab
+ };
+
+ for( LSEQ seq = aBoard->GetEnabledLayers().Seq( non_cu, DIM( non_cu ) ); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ m_out->Print( aNestLevel+1, "(%d %s user", layer,
+ m_out->Quotew( aBoard->GetLayerName( layer ) ).c_str() );
+
+ if( !visible_layers[layer] )
+ m_out->Print( 0, " hide" );
+
+ m_out->Print( 0, ")\n" );
+ }
+
+ m_out->Print( aNestLevel, ")\n\n" );
+
+ // Setup
+ m_out->Print( aNestLevel, "(setup\n" );
+
+ // Save current default track width, for compatibility with older Pcbnew version;
+ m_out->Print( aNestLevel+1, "(last_trace_width %s)\n",
+ FMTIU( dsnSettings.GetCurrentTrackWidth() ).c_str() );
+
+ // Save custom tracks width list (the first is not saved here: this is the netclass value
+ for( unsigned ii = 1; ii < dsnSettings.m_TrackWidthList.size(); ii++ )
+ m_out->Print( aNestLevel+1, "(user_trace_width %s)\n",
+ FMTIU( dsnSettings.m_TrackWidthList[ii] ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(trace_clearance %s)\n",
+ FMTIU( dsnSettings.GetDefault()->GetClearance() ).c_str() );
+
+ // ZONE_SETTINGS
+ m_out->Print( aNestLevel+1, "(zone_clearance %s)\n",
+ FMTIU( aBoard->GetZoneSettings().m_ZoneClearance ).c_str() );
+ m_out->Print( aNestLevel+1, "(zone_45_only %s)\n",
+ aBoard->GetZoneSettings().m_Zone_45_Only ? "yes" : "no" );
+
+ m_out->Print( aNestLevel+1, "(trace_min %s)\n",
+ FMTIU( dsnSettings.m_TrackMinWidth ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(segment_width %s)\n",
+ FMTIU( dsnSettings.m_DrawSegmentWidth ).c_str() );
+ m_out->Print( aNestLevel+1, "(edge_width %s)\n",
+ FMTIU( dsnSettings.m_EdgeSegmentWidth ).c_str() );
+
+ // Save current default via size, for compatibility with older Pcbnew version;
+ m_out->Print( aNestLevel+1, "(via_size %s)\n",
+ FMTIU( dsnSettings.GetDefault()->GetViaDiameter() ).c_str() );
+ m_out->Print( aNestLevel+1, "(via_drill %s)\n",
+ FMTIU( dsnSettings.GetDefault()->GetViaDrill() ).c_str() );
+ m_out->Print( aNestLevel+1, "(via_min_size %s)\n",
+ FMTIU( dsnSettings.m_ViasMinSize ).c_str() );
+ m_out->Print( aNestLevel+1, "(via_min_drill %s)\n",
+ FMTIU( dsnSettings.m_ViasMinDrill ).c_str() );
+
+ // Save custom vias diameters list (the first is not saved here: this is
+ // the netclass value
+ for( unsigned ii = 1; ii < dsnSettings.m_ViasDimensionsList.size(); ii++ )
+ m_out->Print( aNestLevel+1, "(user_via %s %s)\n",
+ FMTIU( dsnSettings.m_ViasDimensionsList[ii].m_Diameter ).c_str(),
+ FMTIU( dsnSettings.m_ViasDimensionsList[ii].m_Drill ).c_str() );
+
+ // for old versions compatibility:
+ if( dsnSettings.m_BlindBuriedViaAllowed )
+ m_out->Print( aNestLevel+1, "(blind_buried_vias_allowed yes)\n" );
+
+ m_out->Print( aNestLevel+1, "(uvia_size %s)\n",
+ FMTIU( dsnSettings.GetDefault()->GetuViaDiameter() ).c_str() );
+ m_out->Print( aNestLevel+1, "(uvia_drill %s)\n",
+ FMTIU( dsnSettings.GetDefault()->GetuViaDrill() ).c_str() );
+ m_out->Print( aNestLevel+1, "(uvias_allowed %s)\n",
+ ( dsnSettings.m_MicroViasAllowed ) ? "yes" : "no" );
+ m_out->Print( aNestLevel+1, "(uvia_min_size %s)\n",
+ FMTIU( dsnSettings.m_MicroViasMinSize ).c_str() );
+ m_out->Print( aNestLevel+1, "(uvia_min_drill %s)\n",
+ FMTIU( dsnSettings.m_MicroViasMinDrill ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(pcb_text_width %s)\n",
+ FMTIU( dsnSettings.m_PcbTextWidth ).c_str() );
+ m_out->Print( aNestLevel+1, "(pcb_text_size %s %s)\n",
+ FMTIU( dsnSettings.m_PcbTextSize.x ).c_str(),
+ FMTIU( dsnSettings.m_PcbTextSize.y ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(mod_edge_width %s)\n",
+ FMTIU( dsnSettings.m_ModuleSegmentWidth ).c_str() );
+ m_out->Print( aNestLevel+1, "(mod_text_size %s %s)\n",
+ FMTIU( dsnSettings.m_ModuleTextSize.x ).c_str(),
+ FMTIU( dsnSettings.m_ModuleTextSize.y ).c_str() );
+ m_out->Print( aNestLevel+1, "(mod_text_width %s)\n",
+ FMTIU( dsnSettings.m_ModuleTextWidth ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(pad_size %s %s)\n",
+ FMTIU( dsnSettings.m_Pad_Master.GetSize().x ).c_str(),
+ FMTIU( dsnSettings.m_Pad_Master.GetSize().y ).c_str() );
+ m_out->Print( aNestLevel+1, "(pad_drill %s)\n",
+ FMTIU( dsnSettings.m_Pad_Master.GetDrillSize().x ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(pad_to_mask_clearance %s)\n",
+ FMTIU( dsnSettings.m_SolderMaskMargin ).c_str() );
+
+ if( dsnSettings.m_SolderMaskMinWidth )
+ m_out->Print( aNestLevel+1, "(solder_mask_min_width %s)\n",
+ FMTIU( dsnSettings.m_SolderMaskMinWidth ).c_str() );
+
+ if( dsnSettings.m_SolderPasteMargin != 0 )
+ m_out->Print( aNestLevel+1, "(pad_to_paste_clearance %s)\n",
+ FMTIU( dsnSettings.m_SolderPasteMargin ).c_str() );
+
+ if( dsnSettings.m_SolderPasteMarginRatio != 0 )
+ m_out->Print( aNestLevel+1, "(pad_to_paste_clearance_ratio %s)\n",
+ Double2Str( dsnSettings.m_SolderPasteMarginRatio ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(aux_axis_origin %s %s)\n",
+ FMTIU( aBoard->GetAuxOrigin().x ).c_str(),
+ FMTIU( aBoard->GetAuxOrigin().y ).c_str() );
+
+ if( aBoard->GetGridOrigin().x || aBoard->GetGridOrigin().y )
+ m_out->Print( aNestLevel+1, "(grid_origin %s %s)\n",
+ FMTIU( aBoard->GetGridOrigin().x ).c_str(),
+ FMTIU( aBoard->GetGridOrigin().y ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(visible_elements %X)\n",
+ dsnSettings.GetVisibleElements() );
+
+ aBoard->GetPlotOptions().Format( m_out, aNestLevel+1 );
+
+ m_out->Print( aNestLevel, ")\n\n" );
+
+ // Save net codes and names
+ for( NETINFO_MAPPING::iterator net = m_mapping->begin(), netEnd = m_mapping->end();
+ net != netEnd; ++net )
+ {
+ m_out->Print( aNestLevel, "(net %d %s)\n",
+ m_mapping->Translate( net->GetNet() ),
+ m_out->Quotew( net->GetNetname() ).c_str() );
+ }
+
+ m_out->Print( 0, "\n" );
+
+ // Save the default net class first.
+ NETCLASS defaultNC = *dsnSettings.GetDefault();
+ filterNetClass( *aBoard, defaultNC ); // Remove empty nets (from a copy of a netclass)
+ defaultNC.Format( m_out, aNestLevel, m_ctl );
+
+ // Save the rest of the net classes alphabetically.
+ for( NETCLASSES::const_iterator it = dsnSettings.m_NetClasses.begin();
+ it != dsnSettings.m_NetClasses.end();
+ ++it )
+ {
+ NETCLASS netclass = *it->second;
+ filterNetClass( *aBoard, netclass ); // Remove empty nets (from a copy of a netclass)
+ netclass.Format( m_out, aNestLevel, m_ctl );
+ }
+
+ // Save the modules.
+ for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
+ {
+ Format( module, aNestLevel );
+ m_out->Print( 0, "\n" );
+ }
+
+ // Save the graphical items on the board (not owned by a module)
+ for( BOARD_ITEM* item = aBoard->m_Drawings; item; item = item->Next() )
+ Format( item, aNestLevel );
+
+ if( aBoard->m_Drawings.GetCount() )
+ m_out->Print( 0, "\n" );
+
+ // Do not save MARKER_PCBs, they can be regenerated easily.
+
+ // Save the tracks and vias.
+ for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
+ Format( track, aNestLevel );
+
+ if( aBoard->m_Track.GetCount() )
+ m_out->Print( 0, "\n" );
+
+ /// @todo Add warning here that the old segment filed zones are no longer supported and
+ /// will not be saved.
+
+ // Save the polygon (which are the newer technology) zones.
+ for( int i = 0; i < aBoard->GetAreaCount(); ++i )
+ Format( aBoard->GetArea( i ), aNestLevel );
+}
+
+
+void PCB_IO::format( DIMENSION* aDimension, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ m_out->Print( aNestLevel, "(dimension %s (width %s)",
+ FMT_IU( aDimension->GetValue() ).c_str(),
+ FMT_IU( aDimension->GetWidth() ).c_str() );
+
+ formatLayer( aDimension );
+
+ if( aDimension->GetTimeStamp() )
+ m_out->Print( 0, " (tstamp %lX)", aDimension->GetTimeStamp() );
+
+ m_out->Print( 0, "\n" );
+
+ Format( &aDimension->Text(), aNestLevel+1 );
+
+ m_out->Print( aNestLevel+1, "(feature1 (pts (xy %s %s) (xy %s %s)))\n",
+ FMT_IU( aDimension->m_featureLineDO.x ).c_str(),
+ FMT_IU( aDimension->m_featureLineDO.y ).c_str(),
+ FMT_IU( aDimension->m_featureLineDF.x ).c_str(),
+ FMT_IU( aDimension->m_featureLineDF.y ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(feature2 (pts (xy %s %s) (xy %s %s)))\n",
+ FMT_IU( aDimension->m_featureLineGO.x ).c_str(),
+ FMT_IU( aDimension->m_featureLineGO.y ).c_str(),
+ FMT_IU( aDimension->m_featureLineGF.x ).c_str(),
+ FMT_IU( aDimension->m_featureLineGF.y ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(crossbar (pts (xy %s %s) (xy %s %s)))\n",
+ FMT_IU( aDimension->m_crossBarO.x ).c_str(),
+ FMT_IU( aDimension->m_crossBarO.y ).c_str(),
+ FMT_IU( aDimension->m_crossBarF.x ).c_str(),
+ FMT_IU( aDimension->m_crossBarF.y ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(arrow1a (pts (xy %s %s) (xy %s %s)))\n",
+ FMT_IU( aDimension->m_crossBarF.x ).c_str(),
+ FMT_IU( aDimension->m_crossBarF.y ).c_str(),
+ FMT_IU( aDimension->m_arrowD1F.x ).c_str(),
+ FMT_IU( aDimension->m_arrowD1F.y ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(arrow1b (pts (xy %s %s) (xy %s %s)))\n",
+ FMT_IU( aDimension->m_crossBarF.x ).c_str(),
+ FMT_IU( aDimension->m_crossBarF.y ).c_str(),
+ FMT_IU( aDimension->m_arrowD2F.x ).c_str(),
+ FMT_IU( aDimension->m_arrowD2F.y ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(arrow2a (pts (xy %s %s) (xy %s %s)))\n",
+ FMT_IU( aDimension->m_crossBarO.x ).c_str(),
+ FMT_IU( aDimension->m_crossBarO.y ).c_str(),
+ FMT_IU( aDimension->m_arrowG1F.x ).c_str(),
+ FMT_IU( aDimension->m_arrowG1F.y ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(arrow2b (pts (xy %s %s) (xy %s %s)))\n",
+ FMT_IU( aDimension->m_crossBarO.x ).c_str(),
+ FMT_IU( aDimension->m_crossBarO.y ).c_str(),
+ FMT_IU( aDimension->m_arrowG2F.x ).c_str(),
+ FMT_IU( aDimension->m_arrowG2F.y ).c_str() );
+
+ m_out->Print( aNestLevel, ")\n" );
+}
+
+
+void PCB_IO::format( DRAWSEGMENT* aSegment, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ unsigned i;
+
+ switch( aSegment->GetShape() )
+ {
+ case S_SEGMENT: // Line
+ m_out->Print( aNestLevel, "(gr_line (start %s) (end %s)",
+ FMT_IU( aSegment->GetStart() ).c_str(),
+ FMT_IU( aSegment->GetEnd() ).c_str() );
+
+ if( aSegment->GetAngle() != 0.0 )
+ m_out->Print( 0, " (angle %s)", FMT_ANGLE( aSegment->GetAngle() ).c_str() );
+
+ break;
+
+ case S_CIRCLE: // Circle
+ m_out->Print( aNestLevel, "(gr_circle (center %s) (end %s)",
+ FMT_IU( aSegment->GetStart() ).c_str(),
+ FMT_IU( aSegment->GetEnd() ).c_str() );
+ break;
+
+ case S_ARC: // Arc
+ m_out->Print( aNestLevel, "(gr_arc (start %s) (end %s) (angle %s)",
+ FMT_IU( aSegment->GetStart() ).c_str(),
+ FMT_IU( aSegment->GetEnd() ).c_str(),
+ FMT_ANGLE( aSegment->GetAngle() ).c_str() );
+ break;
+
+ case S_POLYGON: // Polygon
+ m_out->Print( aNestLevel, "(gr_poly (pts" );
+
+ for( i = 0; i < aSegment->GetPolyPoints().size(); ++i )
+ m_out->Print( 0, " (xy %s)", FMT_IU( aSegment->GetPolyPoints()[i] ).c_str() );
+
+ m_out->Print( 0, ")" );
+ break;
+
+ case S_CURVE: // Bezier curve
+ m_out->Print( aNestLevel, "(gr_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))",
+ FMT_IU( aSegment->GetStart() ).c_str(),
+ FMT_IU( aSegment->GetBezControl1() ).c_str(),
+ FMT_IU( aSegment->GetBezControl2() ).c_str(),
+ FMT_IU( aSegment->GetEnd() ).c_str() );
+ break;
+
+ default:
+ wxFAIL_MSG( wxT( "Cannot format invalid DRAWSEGMENT type." ) );
+ };
+
+ formatLayer( aSegment );
+
+ if( aSegment->GetWidth() != 0 )
+ m_out->Print( 0, " (width %s)", FMT_IU( aSegment->GetWidth() ).c_str() );
+
+ if( aSegment->GetTimeStamp() )
+ m_out->Print( 0, " (tstamp %lX)", aSegment->GetTimeStamp() );
+
+ if( aSegment->GetStatus() )
+ m_out->Print( 0, " (status %X)", aSegment->GetStatus() );
+
+ m_out->Print( 0, ")\n" );
+}
+
+
+void PCB_IO::format( EDGE_MODULE* aModuleDrawing, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ switch( aModuleDrawing->GetShape() )
+ {
+ case S_SEGMENT: // Line
+ m_out->Print( aNestLevel, "(fp_line (start %s) (end %s)",
+ FMT_IU( aModuleDrawing->GetStart0() ).c_str(),
+ FMT_IU( aModuleDrawing->GetEnd0() ).c_str() );
+ break;
+
+ case S_CIRCLE: // Circle
+ m_out->Print( aNestLevel, "(fp_circle (center %s) (end %s)",
+ FMT_IU( aModuleDrawing->GetStart0() ).c_str(),
+ FMT_IU( aModuleDrawing->GetEnd0() ).c_str() );
+ break;
+
+ case S_ARC: // Arc
+ m_out->Print( aNestLevel, "(fp_arc (start %s) (end %s) (angle %s)",
+ FMT_IU( aModuleDrawing->GetStart0() ).c_str(),
+ FMT_IU( aModuleDrawing->GetEnd0() ).c_str(),
+ FMT_ANGLE( aModuleDrawing->GetAngle() ).c_str() );
+ break;
+
+ case S_POLYGON: // Polygon
+ m_out->Print( aNestLevel, "(fp_poly (pts" );
+
+ for( unsigned i = 0; i < aModuleDrawing->GetPolyPoints().size(); ++i )
+ {
+ int nestLevel = 0;
+
+ if( i && !(i%4) ) // newline every 4(pts)
+ {
+ nestLevel = aNestLevel + 1;
+ m_out->Print( 0, "\n" );
+ }
+
+ m_out->Print( nestLevel, "%s(xy %s)",
+ nestLevel ? "" : " ",
+ FMT_IU( aModuleDrawing->GetPolyPoints()[i] ).c_str() );
+ }
+ m_out->Print( 0, ")" );
+ break;
+
+ case S_CURVE: // Bezier curve
+ m_out->Print( aNestLevel, "(fp_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))",
+ FMT_IU( aModuleDrawing->GetStart0() ).c_str(),
+ FMT_IU( aModuleDrawing->GetBezControl1() ).c_str(),
+ FMT_IU( aModuleDrawing->GetBezControl2() ).c_str(),
+ FMT_IU( aModuleDrawing->GetEnd0() ).c_str() );
+ break;
+
+ default:
+ wxFAIL_MSG( wxT( "Cannot format invalid DRAWSEGMENT type." ) );
+ };
+
+ formatLayer( aModuleDrawing );
+
+ m_out->Print( 0, " (width %s)", FMT_IU( aModuleDrawing->GetWidth() ).c_str() );
+
+ m_out->Print( 0, ")\n" );
+}
+
+
+void PCB_IO::format( PCB_TARGET* aTarget, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ m_out->Print( aNestLevel, "(target %s (at %s) (size %s)",
+ ( aTarget->GetShape() ) ? "x" : "plus",
+ FMT_IU( aTarget->GetPosition() ).c_str(),
+ FMT_IU( aTarget->GetSize() ).c_str() );
+
+ if( aTarget->GetWidth() != 0 )
+ m_out->Print( 0, " (width %s)", FMT_IU( aTarget->GetWidth() ).c_str() );
+
+ formatLayer( aTarget );
+
+ if( aTarget->GetTimeStamp() )
+ m_out->Print( 0, " (tstamp %lX)", aTarget->GetTimeStamp() );
+
+ m_out->Print( 0, ")\n" );
+}
+
+
+void PCB_IO::format( MODULE* aModule, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ if( !( m_ctl & CTL_OMIT_INITIAL_COMMENTS ) )
+ {
+ const wxArrayString* initial_comments = aModule->GetInitialComments();
+
+ if( initial_comments )
+ {
+ for( unsigned i=0; i<initial_comments->GetCount(); ++i )
+ m_out->Print( aNestLevel, "%s\n", TO_UTF8( (*initial_comments)[i] ) );
+
+ m_out->Print( 0, "\n" ); // improve readability?
+ }
+ }
+
+ m_out->Print( aNestLevel, "(module %s",
+ m_out->Quotes( aModule->GetFPID().Format() ).c_str() );
+
+ if( aModule->IsLocked() )
+ m_out->Print( 0, " locked" );
+
+ if( aModule->IsPlaced() )
+ m_out->Print( 0, " placed" );
+
+ formatLayer( aModule );
+
+ m_out->Print( 0, " (tedit %lX)", aModule->GetLastEditTime() );
+
+ if( !( m_ctl & CTL_OMIT_TSTAMPS ) )
+ {
+ m_out->Print( 0, " (tstamp %lX)\n", aModule->GetTimeStamp() );
+ }
+ else
+ m_out->Print( 0, "\n" );
+
+ if( !( m_ctl & CTL_OMIT_AT ) )
+ {
+ m_out->Print( aNestLevel+1, "(at %s", FMT_IU( aModule->GetPosition() ).c_str() );
+
+ if( aModule->GetOrientation() != 0.0 )
+ m_out->Print( 0, " %s", FMT_ANGLE( aModule->GetOrientation() ).c_str() );
+
+ m_out->Print( 0, ")\n" );
+ }
+
+ if( !aModule->GetDescription().IsEmpty() )
+ m_out->Print( aNestLevel+1, "(descr %s)\n",
+ m_out->Quotew( aModule->GetDescription() ).c_str() );
+
+ if( !aModule->GetKeywords().IsEmpty() )
+ m_out->Print( aNestLevel+1, "(tags %s)\n",
+ m_out->Quotew( aModule->GetKeywords() ).c_str() );
+
+ if( !( m_ctl & CTL_OMIT_PATH ) && !!aModule->GetPath() )
+ m_out->Print( aNestLevel+1, "(path %s)\n",
+ m_out->Quotew( aModule->GetPath() ).c_str() );
+
+ if( aModule->GetPlacementCost90() != 0 )
+ m_out->Print( aNestLevel+1, "(autoplace_cost90 %d)\n", aModule->GetPlacementCost90() );
+
+ if( aModule->GetPlacementCost180() != 0 )
+ m_out->Print( aNestLevel+1, "(autoplace_cost180 %d)\n", aModule->GetPlacementCost180() );
+
+ if( aModule->GetLocalSolderMaskMargin() != 0 )
+ m_out->Print( aNestLevel+1, "(solder_mask_margin %s)\n",
+ FMT_IU( aModule->GetLocalSolderMaskMargin() ).c_str() );
+
+ if( aModule->GetLocalSolderPasteMargin() != 0 )
+ m_out->Print( aNestLevel+1, "(solder_paste_margin %s)\n",
+ FMT_IU( aModule->GetLocalSolderPasteMargin() ).c_str() );
+
+ if( aModule->GetLocalSolderPasteMarginRatio() != 0 )
+ m_out->Print( aNestLevel+1, "(solder_paste_ratio %s)\n",
+ Double2Str( aModule->GetLocalSolderPasteMarginRatio() ).c_str() );
+
+ if( aModule->GetLocalClearance() != 0 )
+ m_out->Print( aNestLevel+1, "(clearance %s)\n",
+ FMT_IU( aModule->GetLocalClearance() ).c_str() );
+
+ if( aModule->GetZoneConnection() != PAD_ZONE_CONN_INHERITED )
+ m_out->Print( aNestLevel+1, "(zone_connect %d)\n", aModule->GetZoneConnection() );
+
+ if( aModule->GetThermalWidth() != 0 )
+ m_out->Print( aNestLevel+1, "(thermal_width %s)\n",
+ FMT_IU( aModule->GetThermalWidth() ).c_str() );
+
+ if( aModule->GetThermalGap() != 0 )
+ m_out->Print( aNestLevel+1, "(thermal_gap %s)\n",
+ FMT_IU( aModule->GetThermalGap() ).c_str() );
+
+ // Attributes
+ if( aModule->GetAttributes() != MOD_DEFAULT )
+ {
+ m_out->Print( aNestLevel+1, "(attr" );
+
+ if( aModule->GetAttributes() & MOD_CMS )
+ m_out->Print( 0, " smd" );
+
+ if( aModule->GetAttributes() & MOD_VIRTUAL )
+ m_out->Print( 0, " virtual" );
+
+ m_out->Print( 0, ")\n" );
+ }
+
+ Format( (BOARD_ITEM*) &aModule->Reference(), aNestLevel+1 );
+ Format( (BOARD_ITEM*) &aModule->Value(), aNestLevel+1 );
+
+ // Save drawing elements.
+ for( BOARD_ITEM* gr = aModule->GraphicalItems(); gr; gr = gr->Next() )
+ Format( gr, aNestLevel+1 );
+
+ // Save pads.
+ for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
+ format( pad, aNestLevel+1 );
+
+ // Save 3D info.
+ for( S3D_MASTER* t3D = aModule->Models(); t3D; t3D = t3D->Next() )
+ {
+ if( !t3D->GetShape3DName().IsEmpty() )
+ {
+ m_out->Print( aNestLevel+1, "(model %s\n",
+ m_out->Quotew( t3D->GetShape3DName() ).c_str() );
+
+ m_out->Print( aNestLevel+2, "(at (xyz %s %s %s))\n",
+ Double2Str( t3D->m_MatPosition.x ).c_str(),
+ Double2Str( t3D->m_MatPosition.y ).c_str(),
+ Double2Str( t3D->m_MatPosition.z ).c_str() );
+
+ m_out->Print( aNestLevel+2, "(scale (xyz %s %s %s))\n",
+ Double2Str( t3D->m_MatScale.x ).c_str(),
+ Double2Str( t3D->m_MatScale.y ).c_str(),
+ Double2Str( t3D->m_MatScale.z ).c_str() );
+
+ m_out->Print( aNestLevel+2, "(rotate (xyz %s %s %s))\n",
+ Double2Str( t3D->m_MatRotation.x ).c_str(),
+ Double2Str( t3D->m_MatRotation.y ).c_str(),
+ Double2Str( t3D->m_MatRotation.z ).c_str() );
+
+ m_out->Print( aNestLevel+1, ")\n" );
+ }
+ }
+
+ m_out->Print( aNestLevel, ")\n" );
+}
+
+
+void PCB_IO::formatLayers( LSET aLayerMask, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ std::string output;
+
+ if( aNestLevel == 0 )
+ output += ' ';
+
+ output += "(layers";
+
+ static const LSET cu_all( LSET::AllCuMask() );
+ static const LSET fr_bk( 2, B_Cu, F_Cu );
+ static const LSET adhes( 2, B_Adhes, F_Adhes );
+ static const LSET paste( 2, B_Paste, F_Paste );
+ static const LSET silks( 2, B_SilkS, F_SilkS );
+ static const LSET mask( 2, B_Mask, F_Mask );
+ static const LSET crt_yd(2, B_CrtYd, F_CrtYd );
+ static const LSET fab( 2, B_Fab, F_Fab );
+
+ LSET cu_mask = cu_all;
+
+ if( m_board )
+ cu_mask &= m_board->GetEnabledLayers();
+
+ // output copper layers first, then non copper
+
+ if( ( aLayerMask & cu_mask ) == cu_mask )
+ {
+ output += " *.Cu";
+ aLayerMask &= ~cu_all; // clear bits, so they are not output again below
+ }
+ else if( ( aLayerMask & cu_mask ) == fr_bk )
+ {
+ output += " F&B.Cu";
+ aLayerMask &= ~fr_bk;
+ }
+
+ if( ( aLayerMask & adhes ) == adhes )
+ {
+ output += " *.Adhes";
+ aLayerMask &= ~adhes;
+ }
+
+ if( ( aLayerMask & paste ) == paste )
+ {
+ output += " *.Paste";
+ aLayerMask &= ~paste;
+ }
+
+ if( ( aLayerMask & silks ) == silks )
+ {
+ output += " *.SilkS";
+ aLayerMask &= ~silks;
+ }
+
+ if( ( aLayerMask & mask ) == mask )
+ {
+ output += " *.Mask";
+ aLayerMask &= ~mask;
+ }
+
+ if( ( aLayerMask & crt_yd ) == crt_yd )
+ {
+ output += " *.CrtYd";
+ aLayerMask &= ~crt_yd;
+ }
+
+ if( ( aLayerMask & fab ) == fab )
+ {
+ output += " *.Fab";
+ aLayerMask &= ~fab;
+ }
+
+ // output any individual layers not handled in wildcard combos above
+
+ if( m_board )
+ aLayerMask &= m_board->GetEnabledLayers();
+
+ wxString layerName;
+
+ for( LAYER_NUM layer = 0; layer < LAYER_ID_COUNT; ++layer )
+ {
+ if( aLayerMask[layer] )
+ {
+ if( m_board && !( m_ctl & CTL_STD_LAYER_NAMES ) )
+ layerName = m_board->GetLayerName( LAYER_ID( layer ) );
+
+ else // I am being called from FootprintSave()
+ layerName = BOARD::GetStandardLayerName( LAYER_ID( layer ) );
+
+ output += ' ';
+ output += m_out->Quotew( layerName );
+ }
+ }
+
+ m_out->Print( aNestLevel, "%s)", output.c_str() );
+}
+
+
+void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ const char* shape;
+
+ switch( aPad->GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE: shape = "circle"; break;
+ case PAD_SHAPE_RECT: shape = "rect"; break;
+ case PAD_SHAPE_OVAL: shape = "oval"; break;
+ case PAD_SHAPE_TRAPEZOID: shape = "trapezoid"; break;
+
+ default:
+ THROW_IO_ERROR( wxString::Format( _( "unknown pad type: %d"), aPad->GetShape() ) );
+ }
+
+ const char* type;
+
+ switch( aPad->GetAttribute() )
+ {
+ case PAD_ATTRIB_STANDARD: type = "thru_hole"; break;
+ case PAD_ATTRIB_SMD: type = "smd"; break;
+ case PAD_ATTRIB_CONN: type = "connect"; break;
+ case PAD_ATTRIB_HOLE_NOT_PLATED: type = "np_thru_hole"; break;
+
+ default:
+ THROW_IO_ERROR( wxString::Format( _( "unknown pad attribute: %d" ),
+ aPad->GetAttribute() ) );
+ }
+
+ m_out->Print( aNestLevel, "(pad %s %s %s",
+ m_out->Quotew( aPad->GetPadName() ).c_str(),
+ type, shape );
+ m_out->Print( 0, " (at %s", FMT_IU( aPad->GetPos0() ).c_str() );
+
+ if( aPad->GetOrientation() != 0.0 )
+ m_out->Print( 0, " %s", FMT_ANGLE( aPad->GetOrientation() ).c_str() );
+
+ m_out->Print( 0, ")" );
+ m_out->Print( 0, " (size %s)", FMT_IU( aPad->GetSize() ).c_str() );
+
+ if( (aPad->GetDelta().GetWidth()) != 0 || (aPad->GetDelta().GetHeight() != 0 ) )
+ m_out->Print( 0, " (rect_delta %s )", FMT_IU( aPad->GetDelta() ).c_str() );
+
+ wxSize sz = aPad->GetDrillSize();
+ wxPoint shapeoffset = aPad->GetOffset();
+
+ if( (sz.GetWidth() > 0) || (sz.GetHeight() > 0) ||
+ (shapeoffset.x != 0) || (shapeoffset.y != 0) )
+ {
+ m_out->Print( 0, " (drill" );
+
+ if( aPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG )
+ m_out->Print( 0, " oval" );
+
+ if( sz.GetWidth() > 0 )
+ m_out->Print( 0, " %s", FMT_IU( sz.GetWidth() ).c_str() );
+
+ if( sz.GetHeight() > 0 && sz.GetWidth() != sz.GetHeight() )
+ m_out->Print( 0, " %s", FMT_IU( sz.GetHeight() ).c_str() );
+
+ if( (shapeoffset.x != 0) || (shapeoffset.y != 0) )
+ m_out->Print( 0, " (offset %s)", FMT_IU( aPad->GetOffset() ).c_str() );
+
+ m_out->Print( 0, ")" );
+ }
+
+ formatLayers( aPad->GetLayerSet(), 0 );
+
+ std::string output;
+
+ // Unconnected pad is default net so don't save it.
+ if( !( m_ctl & CTL_OMIT_NETS ) && aPad->GetNetCode() != NETINFO_LIST::UNCONNECTED )
+ StrPrintf( &output, " (net %d %s)", m_mapping->Translate( aPad->GetNetCode() ),
+ m_out->Quotew( aPad->GetNetname() ).c_str() );
+
+ if( aPad->GetPadToDieLength() != 0 )
+ StrPrintf( &output, " (die_length %s)", FMT_IU( aPad->GetPadToDieLength() ).c_str() );
+
+ if( aPad->GetLocalSolderMaskMargin() != 0 )
+ StrPrintf( &output, " (solder_mask_margin %s)", FMT_IU( aPad->GetLocalSolderMaskMargin() ).c_str() );
+
+ if( aPad->GetLocalSolderPasteMargin() != 0 )
+ StrPrintf( &output, " (solder_paste_margin %s)", FMT_IU( aPad->GetLocalSolderPasteMargin() ).c_str() );
+
+ if( aPad->GetLocalSolderPasteMarginRatio() != 0 )
+ StrPrintf( &output, " (solder_paste_margin_ratio %s)",
+ Double2Str( aPad->GetLocalSolderPasteMarginRatio() ).c_str() );
+
+ if( aPad->GetLocalClearance() != 0 )
+ StrPrintf( &output, " (clearance %s)", FMT_IU( aPad->GetLocalClearance() ).c_str() );
+
+ if( aPad->GetZoneConnection() != PAD_ZONE_CONN_INHERITED )
+ StrPrintf( &output, " (zone_connect %d)", aPad->GetZoneConnection() );
+
+ if( aPad->GetThermalWidth() != 0 )
+ StrPrintf( &output, " (thermal_width %s)", FMT_IU( aPad->GetThermalWidth() ).c_str() );
+
+ if( aPad->GetThermalGap() != 0 )
+ StrPrintf( &output, " (thermal_gap %s)", FMT_IU( aPad->GetThermalGap() ).c_str() );
+
+ if( output.size() )
+ {
+ m_out->Print( 0, "\n" );
+ m_out->Print( aNestLevel+1, "%s", output.c_str()+1 ); // +1 skips 1st space on 1st element
+ }
+
+ m_out->Print( 0, ")\n" );
+}
+
+
+void PCB_IO::format( TEXTE_PCB* aText, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ m_out->Print( aNestLevel, "(gr_text %s (at %s",
+ m_out->Quotew( aText->GetText() ).c_str(),
+ FMT_IU( aText->GetTextPosition() ).c_str() );
+
+ if( aText->GetOrientation() != 0.0 )
+ m_out->Print( 0, " %s", FMT_ANGLE( aText->GetOrientation() ).c_str() );
+
+ m_out->Print( 0, ")" );
+
+ formatLayer( aText );
+
+ if( aText->GetTimeStamp() )
+ m_out->Print( 0, " (tstamp %lX)", aText->GetTimeStamp() );
+
+ m_out->Print( 0, "\n" );
+
+ aText->EDA_TEXT::Format( m_out, aNestLevel, m_ctl );
+
+ m_out->Print( aNestLevel, ")\n" );
+}
+
+
+void PCB_IO::format( TEXTE_MODULE* aText, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ MODULE* parent = (MODULE*) aText->GetParent();
+ double orient = aText->GetOrientation();
+ wxString type;
+
+ switch( aText->GetType() )
+ {
+ case TEXTE_MODULE::TEXT_is_REFERENCE: type = wxT( "reference" ); break;
+ case TEXTE_MODULE::TEXT_is_VALUE: type = wxT( "value" ); break;
+ case TEXTE_MODULE::TEXT_is_DIVERS: type = wxT( "user" );
+ }
+
+ // Due to the Pcbnew history, m_Orient is saved in screen value
+ // but it is handled as relative to its parent footprint
+ if( parent )
+ orient += parent->GetOrientation();
+
+ m_out->Print( aNestLevel, "(fp_text %s %s (at %s",
+ m_out->Quotew( type ).c_str(),
+ m_out->Quotew( aText->GetText() ).c_str(),
+ FMT_IU( aText->GetPos0() ).c_str() );
+
+ if( orient != 0.0 )
+ m_out->Print( 0, " %s", FMT_ANGLE( orient ).c_str() );
+
+ m_out->Print( 0, ")" );
+ formatLayer( aText );
+
+ if( !aText->IsVisible() )
+ m_out->Print( 0, " hide" );
+
+ m_out->Print( 0, "\n" );
+
+ aText->EDA_TEXT::Format( m_out, aNestLevel, m_ctl );
+
+ m_out->Print( aNestLevel, ")\n" );
+}
+
+
+void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ if( aTrack->Type() == PCB_VIA_T )
+ {
+ LAYER_ID layer1, layer2;
+
+ const VIA* via = static_cast<const VIA*>(aTrack);
+ BOARD* board = (BOARD*) via->GetParent();
+
+ wxCHECK_RET( board != 0, wxT( "Via " ) + via->GetSelectMenuText() +
+ wxT( " has no parent." ) );
+
+ m_out->Print( aNestLevel, "(via" );
+
+ via->LayerPair( &layer1, &layer2 );
+
+ switch( via->GetViaType() )
+ {
+ case VIA_THROUGH: // Default shape not saved.
+ break;
+
+ case VIA_BLIND_BURIED:
+ m_out->Print( 0, " blind" );
+ break;
+
+ case VIA_MICROVIA:
+ m_out->Print( 0, " micro" );
+ break;
+
+ default:
+ THROW_IO_ERROR( wxString::Format( _( "unknown via type %d" ), via->GetViaType() ) );
+ }
+
+ m_out->Print( 0, " (at %s) (size %s)",
+ FMT_IU( aTrack->GetStart() ).c_str(),
+ FMT_IU( aTrack->GetWidth() ).c_str() );
+
+ if( via->GetDrill() != UNDEFINED_DRILL_DIAMETER )
+ m_out->Print( 0, " (drill %s)", FMT_IU( via->GetDrill() ).c_str() );
+
+ m_out->Print( 0, " (layers %s %s)",
+ m_out->Quotew( m_board->GetLayerName( layer1 ) ).c_str(),
+ m_out->Quotew( m_board->GetLayerName( layer2 ) ).c_str() );
+ }
+ else
+ {
+ m_out->Print( aNestLevel, "(segment (start %s) (end %s) (width %s)",
+ FMT_IU( aTrack->GetStart() ).c_str(), FMT_IU( aTrack->GetEnd() ).c_str(),
+ FMT_IU( aTrack->GetWidth() ).c_str() );
+
+ m_out->Print( 0, " (layer %s)", m_out->Quotew( aTrack->GetLayerName() ).c_str() );
+ }
+
+ m_out->Print( 0, " (net %d)", m_mapping->Translate( aTrack->GetNetCode() ) );
+
+ if( aTrack->GetTimeStamp() != 0 )
+ m_out->Print( 0, " (tstamp %lX)", aTrack->GetTimeStamp() );
+
+ if( aTrack->GetStatus() != 0 )
+ m_out->Print( 0, " (status %X)", aTrack->GetStatus() );
+
+ m_out->Print( 0, ")\n" );
+}
+
+
+void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
+ throw( IO_ERROR )
+{
+ // Save the NET info; For keepout zones, net code and net name are irrelevant
+ // so be sure a dummy value is stored, just for ZONE_CONTAINER compatibility
+ // (perhaps netcode and netname should be not stored)
+ m_out->Print( aNestLevel, "(zone (net %d) (net_name %s)",
+ aZone->GetIsKeepout() ? 0 : m_mapping->Translate( aZone->GetNetCode() ),
+ m_out->Quotew( aZone->GetIsKeepout() ? wxT("") : aZone->GetNetname() ).c_str() );
+
+ formatLayer( aZone );
+
+ m_out->Print( 0, " (tstamp %lX)", aZone->GetTimeStamp() );
+
+ // Save the outline aux info
+ std::string hatch;
+
+ switch( aZone->GetHatchStyle() )
+ {
+ default:
+ case CPolyLine::NO_HATCH: hatch = "none"; break;
+ case CPolyLine::DIAGONAL_EDGE: hatch = "edge"; break;
+ case CPolyLine::DIAGONAL_FULL: hatch = "full"; break;
+ }
+
+ m_out->Print( 0, " (hatch %s %s)\n", hatch.c_str(),
+ FMT_IU( aZone->Outline()->GetHatchPitch() ).c_str() );
+
+ if( aZone->GetPriority() > 0 )
+ m_out->Print( aNestLevel+1, "(priority %d)\n", aZone->GetPriority() );
+
+ m_out->Print( aNestLevel+1, "(connect_pads" );
+
+ switch( aZone->GetPadConnection() )
+ {
+ default:
+ case PAD_ZONE_CONN_THERMAL: // Default option not saved or loaded.
+ break;
+
+ case PAD_ZONE_CONN_THT_THERMAL:
+ m_out->Print( 0, " thru_hole_only" );
+ break;
+
+ case PAD_ZONE_CONN_FULL:
+ m_out->Print( 0, " yes" );
+ break;
+
+ case PAD_ZONE_CONN_NONE:
+ m_out->Print( 0, " no" );
+ break;
+ }
+
+ m_out->Print( 0, " (clearance %s))\n",
+ FMT_IU( aZone->GetZoneClearance() ).c_str() );
+
+ m_out->Print( aNestLevel+1, "(min_thickness %s)\n",
+ FMT_IU( aZone->GetMinThickness() ).c_str() );
+
+ if( aZone->GetIsKeepout() )
+ {
+ m_out->Print( aNestLevel+1, "(keepout (tracks %s) (vias %s) (copperpour %s))\n",
+ aZone->GetDoNotAllowTracks() ? "not_allowed" : "allowed",
+ aZone->GetDoNotAllowVias() ? "not_allowed" : "allowed",
+ aZone->GetDoNotAllowCopperPour() ? "not_allowed" : "allowed" );
+ }
+
+ m_out->Print( aNestLevel+1, "(fill" );
+
+ // Default is not filled.
+ if( aZone->IsFilled() )
+ m_out->Print( 0, " yes" );
+
+ // Default is polygon filled.
+ if( aZone->GetFillMode() )
+ m_out->Print( 0, " (mode segment)" );
+
+ m_out->Print( 0, " (arc_segments %d) (thermal_gap %s) (thermal_bridge_width %s)",
+ aZone->GetArcSegmentCount(),
+ FMT_IU( aZone->GetThermalReliefGap() ).c_str(),
+ FMT_IU( aZone->GetThermalReliefCopperBridge() ).c_str() );
+
+ if( aZone->GetCornerSmoothingType() != ZONE_SETTINGS::SMOOTHING_NONE )
+ {
+ m_out->Print( 0, " (smoothing" );
+
+ switch( aZone->GetCornerSmoothingType() )
+ {
+ case ZONE_SETTINGS::SMOOTHING_CHAMFER:
+ m_out->Print( 0, " chamfer" );
+ break;
+
+ case ZONE_SETTINGS::SMOOTHING_FILLET:
+ m_out->Print( 0, " fillet" );
+ break;
+
+ default:
+ THROW_IO_ERROR( wxString::Format( _( "unknown zone corner smoothing type %d" ),
+ aZone->GetCornerSmoothingType() ) );
+ }
+ m_out->Print( 0, ")" );
+
+ if( aZone->GetCornerRadius() != 0 )
+ m_out->Print( 0, " (radius %s)",
+ FMT_IU( aZone->GetCornerRadius() ).c_str() );
+ }
+
+ m_out->Print( 0, ")\n" );
+
+ const CPOLYGONS_LIST& cv = aZone->Outline()->m_CornersList;
+ int newLine = 0;
+
+ if( cv.GetCornersCount() )
+ {
+ m_out->Print( aNestLevel+1, "(polygon\n");
+ m_out->Print( aNestLevel+2, "(pts\n" );
+
+ for( unsigned it = 0; it < cv.GetCornersCount(); ++it )
+ {
+ if( newLine == 0 )
+ m_out->Print( aNestLevel+3, "(xy %s %s)",
+ FMT_IU( cv.GetX( it ) ).c_str(), FMT_IU( cv.GetY( it ) ).c_str() );
+ else
+ m_out->Print( 0, " (xy %s %s)",
+ FMT_IU( cv.GetX( it ) ).c_str(), FMT_IU( cv.GetY( it ) ).c_str() );
+
+ if( newLine < 4 )
+ {
+ newLine += 1;
+ }
+ else
+ {
+ newLine = 0;
+ m_out->Print( 0, "\n" );
+ }
+
+ if( cv.IsEndContour( it ) )
+ {
+ if( newLine != 0 )
+ m_out->Print( 0, "\n" );
+
+ m_out->Print( aNestLevel+2, ")\n" );
+
+ if( it+1 != cv.GetCornersCount() )
+ {
+ newLine = 0;
+ m_out->Print( aNestLevel+1, ")\n" );
+ m_out->Print( aNestLevel+1, "(polygon\n" );
+ m_out->Print( aNestLevel+2, "(pts" );
+ }
+ }
+ }
+
+ m_out->Print( aNestLevel+1, ")\n" );
+ }
+
+ // Save the PolysList
+ const SHAPE_POLY_SET& fv = aZone->GetFilledPolysList();
+ newLine = 0;
+
+ if( !fv.IsEmpty() )
+ {
+ m_out->Print( aNestLevel+1, "(filled_polygon\n" );
+ m_out->Print( aNestLevel+2, "(pts\n" );
+
+ for( SHAPE_POLY_SET::CONST_ITERATOR it = fv.CIterate(); it; ++it )
+ {
+ if( newLine == 0 )
+ m_out->Print( aNestLevel+3, "(xy %s %s)",
+ FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() );
+ else
+ m_out->Print( 0, " (xy %s %s)",
+ FMT_IU( it->x ) .c_str(), FMT_IU( it->y ).c_str() );
+
+ if( newLine < 4 )
+ {
+ newLine += 1;
+ }
+ else
+ {
+ newLine = 0;
+ m_out->Print( 0, "\n" );
+ }
+
+ if( it.IsEndContour() )
+ {
+ if( newLine != 0 )
+ m_out->Print( 0, "\n" );
+
+ m_out->Print( aNestLevel+2, ")\n" );
+
+ if( !it.IsLastContour() )
+ {
+ newLine = 0;
+ m_out->Print( aNestLevel+1, ")\n" );
+ m_out->Print( aNestLevel+1, "(filled_polygon\n" );
+ m_out->Print( aNestLevel+2, "(pts\n" );
+ }
+ }
+ }
+
+ m_out->Print( aNestLevel+1, ")\n" );
+ }
+
+ // Save the filling segments list
+ const std::vector< SEGMENT >& segs = aZone->FillSegments();
+
+ if( segs.size() )
+ {
+ m_out->Print( aNestLevel+1, "(fill_segments\n" );
+
+ for( std::vector< SEGMENT >::const_iterator it = segs.begin(); it != segs.end(); ++it )
+ {
+ m_out->Print( aNestLevel+2, "(pts (xy %s) (xy %s))\n",
+ FMT_IU( it->m_Start ).c_str(),
+ FMT_IU( it->m_End ).c_str() );
+ }
+
+ m_out->Print( aNestLevel+1, ")\n" );
+ }
+
+ m_out->Print( aNestLevel, ")\n" );
+}
+
+
+PCB_IO::PCB_IO( int aControlFlags ) :
+ m_cache( 0 ),
+ m_ctl( aControlFlags ),
+ m_parser( new PCB_PARSER() ),
+ m_mapping( new NETINFO_MAPPING() )
+{
+ init( 0 );
+ m_out = &m_sf;
+}
+
+
+PCB_IO::~PCB_IO()
+{
+ delete m_cache;
+ delete m_parser;
+ delete m_mapping;
+}
+
+
+BOARD* PCB_IO::Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties )
+{
+ FILE_LINE_READER reader( aFileName );
+
+ init( aProperties );
+
+ m_parser->SetLineReader( &reader );
+ m_parser->SetBoard( aAppendToMe );
+
+ BOARD* board;
+
+ try
+ {
+ board = dynamic_cast<BOARD*>( m_parser->Parse() );
+ }
+ catch( const FUTURE_FORMAT_ERROR& parse_error )
+ {
+ // Don't wrap a FUTURE_FORMAT_ERROR in another
+ throw;
+ }
+ catch( const PARSE_ERROR& parse_error )
+ {
+ if( m_parser->IsTooRecent() )
+ throw FUTURE_FORMAT_ERROR( parse_error, m_parser->GetRequiredVersion() );
+ else
+ throw;
+ }
+
+ wxASSERT( board );
+
+ // Give the filename to the board if it's new
+ if( !aAppendToMe )
+ board->SetFileName( aFileName );
+
+ return board;
+}
+
+
+void PCB_IO::init( const PROPERTIES* aProperties )
+{
+ m_board = NULL;
+ m_reader = NULL;
+ m_loading_format_version = SEXPR_BOARD_FILE_VERSION;
+ m_props = aProperties;
+}
+
+
+void PCB_IO::cacheLib( const wxString& aLibraryPath, const wxString& aFootprintName )
+{
+ if( !m_cache || m_cache->IsModified( aLibraryPath, aFootprintName ) )
+ {
+ // a spectacular episode in memory management:
+ delete m_cache;
+ m_cache = new FP_CACHE( this, aLibraryPath );
+ m_cache->Load();
+ }
+}
+
+
+wxArrayString PCB_IO::FootprintEnumerate( const wxString& aLibraryPath,
+ const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+ wxArrayString ret;
+ wxDir dir( aLibraryPath );
+
+ if( !dir.IsOpened() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "footprint library path '%s' does not exist" ),
+ GetChars( aLibraryPath ) ) );
+ }
+
+ init( aProperties );
+
+#if 1 // Set to 0 to only read directory contents, not load cache.
+ cacheLib( aLibraryPath );
+
+ const MODULE_MAP& mods = m_cache->GetModules();
+
+
+ for( MODULE_CITER it = mods.begin(); it != mods.end(); ++it )
+ {
+ ret.Add( FROM_UTF8( it->first.c_str() ) );
+ }
+#else
+ wxString fpFileName;
+ wxString wildcard = wxT( "*." ) + KiCadFootprintFileExtension;
+
+ if( dir.GetFirst( &fpFileName, wildcard, wxDIR_FILES ) )
+ {
+ do
+ {
+ wxFileName fn( aLibraryPath, fpFileName );
+ ret.Add( fn.GetName() );
+ } while( dir.GetNext( &fpFileName ) );
+ }
+#endif
+
+ return ret;
+}
+
+
+MODULE* PCB_IO::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ init( aProperties );
+
+ cacheLib( aLibraryPath, aFootprintName );
+
+ const MODULE_MAP& mods = m_cache->GetModules();
+
+ MODULE_CITER it = mods.find( TO_UTF8( aFootprintName ) );
+
+ if( it == mods.end() )
+ {
+ return NULL;
+ }
+
+ // copy constructor to clone the already loaded MODULE
+ return new MODULE( *it->second->GetModule() );
+}
+
+
+void PCB_IO::FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint,
+ const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ init( aProperties );
+
+ // In this public PLUGIN API function, we can safely assume it was
+ // called for saving into a library path.
+ m_ctl = CTL_FOR_LIBRARY;
+
+ cacheLib( aLibraryPath );
+
+ if( !m_cache->IsWritable() )
+ {
+ wxString msg = wxString::Format(
+ _( "Library '%s' is read only" ),
+ GetChars( aLibraryPath )
+ );
+
+ THROW_IO_ERROR( msg );
+ }
+
+ std::string footprintName = aFootprint->GetFPID().GetFootprintName();
+
+ MODULE_MAP& mods = m_cache->GetModules();
+
+ // Quietly overwrite module and delete module file from path for any by same name.
+ wxFileName fn( aLibraryPath, aFootprint->GetFPID().GetFootprintName(), KiCadFootprintFileExtension );
+
+ if( !fn.IsOk() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "Footprint file name '%s' is not valid." ),
+ GetChars( fn.GetFullPath() ) ) );
+ }
+
+ if( fn.FileExists() && !fn.IsFileWritable() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "user does not have write permission to delete file '%s' " ),
+ GetChars( fn.GetFullPath() ) ) );
+ }
+
+ MODULE_CITER it = mods.find( footprintName );
+
+ if( it != mods.end() )
+ {
+ wxLogTrace( traceFootprintLibrary, wxT( "Removing footprint library file '%s'." ),
+ fn.GetFullPath().GetData() );
+ mods.erase( footprintName );
+ wxRemoveFile( fn.GetFullPath() );
+ }
+
+ // I need my own copy for the cache
+ MODULE* module = new MODULE( *aFootprint );
+
+ // and it's time stamp must be 0, it should have no parent, orientation should
+ // be zero, and it should be on the front layer.
+ module->SetTimeStamp( 0 );
+ module->SetParent( 0 );
+ module->SetOrientation( 0 );
+
+ if( module->GetLayer() != F_Cu )
+ module->Flip( module->GetPosition() );
+
+ wxLogTrace( traceFootprintLibrary, wxT( "Creating s-expression footprint file: %s." ),
+ fn.GetFullPath().GetData() );
+ mods.insert( footprintName, new FP_CACHE_ITEM( module, fn ) );
+ m_cache->Save();
+}
+
+
+void PCB_IO::FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName, const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ init( aProperties );
+
+ cacheLib( aLibraryPath );
+
+ if( !m_cache->IsWritable() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "Library '%s' is read only" ),
+ aLibraryPath.GetData() ) );
+ }
+
+ m_cache->Remove( aFootprintName );
+}
+
+
+void PCB_IO::FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ if( wxDir::Exists( aLibraryPath ) )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "cannot overwrite library path '%s'" ),
+ aLibraryPath.GetData() ) );
+ }
+
+ LOCALE_IO toggle;
+
+ init( aProperties );
+
+ delete m_cache;
+ m_cache = new FP_CACHE( this, aLibraryPath );
+ m_cache->Save();
+}
+
+
+bool PCB_IO::FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ wxFileName fn;
+ fn.SetPath( aLibraryPath );
+
+ // Return if there is no library path to delete.
+ if( !fn.DirExists() )
+ return false;
+
+ if( !fn.IsDirWritable() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "user does not have permission to delete directory '%s'" ),
+ aLibraryPath.GetData() ) );
+ }
+
+ wxDir dir( aLibraryPath );
+
+ if( dir.HasSubDirs() )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "library directory '%s' has unexpected sub-directories" ),
+ aLibraryPath.GetData() ) );
+ }
+
+ // All the footprint files must be deleted before the directory can be deleted.
+ if( dir.HasFiles() )
+ {
+ unsigned i;
+ wxFileName tmp;
+ wxArrayString files;
+
+ wxDir::GetAllFiles( aLibraryPath, &files );
+
+ for( i = 0; i < files.GetCount(); i++ )
+ {
+ tmp = files[i];
+
+ if( tmp.GetExt() != KiCadFootprintFileExtension )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "unexpected file '%s' was found in library path '%s'" ),
+ files[i].GetData(), aLibraryPath.GetData() ) );
+ }
+ }
+
+ for( i = 0; i < files.GetCount(); i++ )
+ {
+ wxRemoveFile( files[i] );
+ }
+ }
+
+ wxLogTrace( traceFootprintLibrary, wxT( "Removing footprint library '%s'" ),
+ aLibraryPath.GetData() );
+
+ // Some of the more elaborate wxRemoveFile() crap puts up its own wxLog dialog
+ // we don't want that. we want bare metal portability with no UI here.
+ if( !wxRmdir( aLibraryPath ) )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "footprint library '%s' cannot be deleted" ),
+ aLibraryPath.GetData() ) );
+ }
+
+ // For some reason removing a directory in Windows is not immediately updated. This delay
+ // prevents an error when attempting to immediately recreate the same directory when over
+ // writing an existing library.
+#ifdef __WINDOWS__
+ wxMilliSleep( 250L );
+#endif
+
+ if( m_cache && !m_cache->IsPath( aLibraryPath ) )
+ {
+ delete m_cache;
+ m_cache = NULL;
+ }
+
+ return true;
+}
+
+
+bool PCB_IO::IsFootprintLibWritable( const wxString& aLibraryPath )
+{
+ LOCALE_IO toggle;
+
+ init( NULL );
+
+ cacheLib( aLibraryPath );
+
+ return m_cache->IsWritable();
+}
diff --git a/pcbnew/kicad_plugin.h b/pcbnew/kicad_plugin.h
new file mode 100644
index 0000000..f81555f
--- /dev/null
+++ b/pcbnew/kicad_plugin.h
@@ -0,0 +1,226 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 CERN.
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef KICAD_PLUGIN_H_
+#define KICAD_PLUGIN_H_
+
+#include <io_mgr.h>
+#include <string>
+#include <layers_id_colors_and_visibility.h>
+
+class BOARD;
+class BOARD_ITEM;
+class FP_CACHE;
+class PCB_PARSER;
+class NETINFO_MAPPING;
+
+
+/// Current s-expression file format version. 2 was the last legacy format version.
+
+//#define SEXPR_BOARD_FILE_VERSION 3 // first s-expression format, used legacy cu stack
+#define SEXPR_BOARD_FILE_VERSION 4 // reversed cu stack, changed Inner* to In* in reverse order
+ // went to 32 Cu layers from 16.
+
+#define CTL_STD_LAYER_NAMES (1 << 0) ///< Use English Standard layer names
+#define CTL_OMIT_NETS (1 << 1) ///< Omit pads net names (useless in library)
+#define CTL_OMIT_TSTAMPS (1 << 2) ///< Omit component time stamp (useless in library)
+#define CTL_OMIT_INITIAL_COMMENTS (1 << 3) ///< omit MODULE initial comments
+#define CTL_OMIT_PATH (1 << 4) ///< Omit component sheet time stamp (useless in library)
+#define CTL_OMIT_AT (1 << 5) ///< Omit position and rotation
+ // (always saved with potion 0,0 and rotation = 0 in library)
+
+
+// common combinations of the above:
+
+/// Format output for the clipboard instead of footprint library or BOARD
+#define CTL_FOR_CLIPBOARD (CTL_STD_LAYER_NAMES|CTL_OMIT_NETS)
+
+/// Format output for a footprint library instead of clipboard or BOARD
+#define CTL_FOR_LIBRARY (CTL_STD_LAYER_NAMES|CTL_OMIT_NETS|CTL_OMIT_TSTAMPS|CTL_OMIT_PATH|CTL_OMIT_AT)
+
+/// The zero arg constructor when PCB_IO is used for PLUGIN::Load() and PLUGIN::Save()ing
+/// a BOARD file underneath IO_MGR.
+#define CTL_FOR_BOARD (CTL_OMIT_INITIAL_COMMENTS)
+
+
+class DIMENSION;
+class EDGE_MODULE;
+class DRAWSEGMENT;
+class PCB_TARGET;
+class D_PAD;
+class TEXTE_MODULE;
+class TRACK;
+class ZONE_CONTAINER;
+class TEXTE_PCB;
+
+
+
+/**
+ * Class PCB_IO
+ * is a PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
+ *
+ * @note This class is not thread safe, but it is re-entrant multiple times in sequence.
+ */
+class PCB_IO : public PLUGIN
+{
+ friend class FP_CACHE;
+
+public:
+
+ //-----<PLUGIN API>---------------------------------------------------------
+
+ const wxString PluginName() const
+ {
+ return wxT( "KiCad" );
+ }
+
+ const wxString GetFileExtension() const
+ {
+ // Would have used wildcards_and_files_ext.cpp's KiCadPcbFileExtension,
+ // but to be pure, a plugin should not assume that it will always be linked
+ // with the core of the pcbnew code. (Might someday be a DLL/DSO.) Besides,
+ // file extension policy should be controlled by the plugin.
+ return wxT( "kicad_pcb" );
+ }
+
+ void Save( const wxString& aFileName, BOARD* aBoard,
+ const PROPERTIES* aProperties = NULL ); // overload
+
+ BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties = NULL );
+
+ wxArrayString FootprintEnumerate( const wxString& aLibraryPath,
+ const PROPERTIES* aProperties = NULL );
+
+ MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties = NULL );
+
+ void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint,
+ const PROPERTIES* aProperties = NULL );
+
+ void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName, const PROPERTIES* aProperties = NULL );
+
+ void FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL);
+
+ bool FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL );
+
+ bool IsFootprintLibWritable( const wxString& aLibraryPath );
+
+ //-----</PLUGIN API>--------------------------------------------------------
+
+ PCB_IO( int aControlFlags = CTL_FOR_BOARD );
+
+ ~PCB_IO();
+
+ /**
+ * Function Format
+ * outputs \a aItem to \a aFormatter in s-expression format.
+ *
+ * @param aItem A pointer the an #BOARD_ITEM object to format.
+ * @param aNestLevel The indentation nest level.
+ * @throw IO_ERROR on write error.
+ */
+ void Format( BOARD_ITEM* aItem, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+
+ std::string GetStringOutput( bool doClear )
+ {
+ std::string ret = m_sf.GetString();
+ if( doClear )
+ m_sf.Clear();
+
+ return ret;
+ }
+
+ void SetOutputFormatter( OUTPUTFORMATTER* aFormatter ) { m_out = aFormatter; }
+
+ BOARD_ITEM* Parse( const wxString& aClipboardSourceInput )
+ throw( FUTURE_FORMAT_ERROR, PARSE_ERROR, IO_ERROR );
+
+protected:
+
+ wxString m_error; ///< for throwing exceptions
+ BOARD* m_board; ///< which BOARD, no ownership here
+
+ const
+ PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL.
+ FP_CACHE* m_cache; ///< Footprint library cache.
+
+ LINE_READER* m_reader; ///< no ownership here.
+ wxString m_filename; ///< for saves only, name is in m_reader for loads
+
+ int m_loading_format_version; ///< which #SEXPR_BOARD_FILE_VERSION should be Load()ed?
+
+ STRING_FORMATTER m_sf;
+ OUTPUTFORMATTER* m_out; ///< output any Format()s to this, no ownership
+ int m_ctl;
+ PCB_PARSER* m_parser;
+ NETINFO_MAPPING* m_mapping; ///< mapping for net codes, so only not empty net codes
+ ///< are stored with consecutive integers as net codes
+
+ /// we only cache one footprint library, this determines which one.
+ void cacheLib( const wxString& aLibraryPath, const wxString& aFootprintName = wxEmptyString );
+
+ void init( const PROPERTIES* aProperties );
+
+private:
+ void format( BOARD* aBoard, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+
+ void format( DIMENSION* aDimension, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+
+ void format( EDGE_MODULE* aModuleDrawing, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+
+ void format( DRAWSEGMENT* aSegment, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+
+ void format( PCB_TARGET* aTarget, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+
+ void format( MODULE* aModule, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+
+ void format( D_PAD* aPad, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+
+ void format( TEXTE_PCB* aText, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+
+ void format( TEXTE_MODULE* aText, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+
+ void format( TRACK* aTrack, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+
+ void format( ZONE_CONTAINER* aZone, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+
+ void formatLayer( const BOARD_ITEM* aItem ) const;
+
+ void formatLayers( LSET aLayerMask, int aNestLevel = 0 ) const
+ throw( IO_ERROR );
+};
+
+#endif // KICAD_PLUGIN_H_
diff --git a/pcbnew/layer_widget.cpp b/pcbnew/layer_widget.cpp
new file mode 100644
index 0000000..607d531
--- /dev/null
+++ b/pcbnew/layer_widget.cpp
@@ -0,0 +1,976 @@
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+
+/* This source module implements the layer visibility and selection widget
+ @todo make the bitmapbutton a staticbitmap, and make dependent on the point size.
+*/
+
+
+//#define STAND_ALONE 1 // define to enable test program for LAYER_WIDGET
+
+
+#include <layer_widget.h>
+
+#include <macros.h>
+#include <common.h>
+#include <colors.h>
+#include <wx/colour.h>
+
+#define BUTT_SIZE_X 20
+#define BUTT_SIZE_Y 18
+#define BUTT_VOID 4
+
+const wxEventType LAYER_WIDGET::EVT_LAYER_COLOR_CHANGE = wxNewEventType();
+
+/* XPM
+ * This bitmap is used for not selected layers
+ */
+static const char * clear_xpm[] = {
+"10 14 1 1",
+" c None",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
+
+/* XPM
+ * This bitmap can be used to show a not selected layer
+ * with special property (mainly not selected layers not in use in GerbView)
+ */
+static const char * clear_alternate_xpm[] = {
+"10 14 4 1",
+" c None",
+"X c #008080",
+"o c GREEN",
+"O c #00B080",
+" ",
+" ",
+" ",
+" ",
+" X ",
+" XXX ",
+" XXXXX ",
+" OOOOOOO ",
+" ooooo ",
+" ooo ",
+" o ",
+" ",
+" ",
+" "};
+
+
+/* XPM
+ * This bitmap is used for a normale selected layer
+ */
+static const char * rightarrow_xpm[] = {
+"10 14 4 1",
+" c None",
+"X c #8080ff",
+"o c BLUE",
+"O c gray56",
+" X ",
+" XX ",
+" XXX ",
+" XXXX ",
+" XXXXX ",
+" XXXXXX ",
+" XXXXXXX ",
+" oooooooO",
+" ooooooO ",
+" oooooO ",
+" ooooO ",
+" oooO ",
+" ooO ",
+" oO "};
+
+/* XPM
+ * This bitmap can be used to show the selected layer
+ * with special property (mainly a layer in use in GerbView)
+ */
+static const char * rightarrow_alternate_xpm[] = {
+"10 14 5 1",
+" c None",
+". c #00B000",
+"X c #8080ff",
+"o c BLUE",
+"O c gray56",
+"..X ",
+"..XX ",
+"..XXX ",
+"..XXXX ",
+"..XXXXX ",
+"..XXXXXX ",
+"..XXXXXXX ",
+"..oooooooO",
+"..ooooooO ",
+"..oooooO ",
+"..ooooO ",
+"..oooO ",
+"..ooO ",
+"..oO "};
+
+
+/**
+ * Function makeColorTxt
+ * returns a string containing the numeric value of the color.
+ * in a form like 0x00000000. (Color is currently an index, not RGB).
+ */
+static wxString makeColorTxt( EDA_COLOR_T aColor )
+{
+ wxString txt;
+ txt.Printf( wxT("0x%08x"), aColor );
+ return txt;
+}
+
+
+/**
+ * Function shrinkFont
+ * reduces the size of the wxFont associated with \a aControl
+ */
+static void shrinkFont( wxWindow* aControl, int aPointSize )
+{
+ wxFont font = aControl->GetFont();
+ font.SetPointSize( aPointSize );
+ aControl->SetFont( font ); // need this?
+}
+
+
+int LAYER_WIDGET::encodeId( int aColumn, int aId )
+{
+ int id = aId * LYR_COLUMN_COUNT + aColumn;
+ return id;
+}
+
+
+LAYER_NUM LAYER_WIDGET::getDecodedId( int aControlId )
+{
+ int id = aControlId / LYR_COLUMN_COUNT; // rounding is OK.
+ return id;
+}
+
+
+wxBitmap LAYER_WIDGET::makeBitmap( EDA_COLOR_T aColor )
+{
+ // the bitmap will be BUTT_VOID*2 pixels smaller than the button, leaving a
+ // border of BUTT_VOID pixels on each side.
+ wxBitmap bitmap( BUTT_SIZE_X - 2 * BUTT_VOID, BUTT_SIZE_Y - 2 * BUTT_VOID );
+ wxBrush brush;
+ wxMemoryDC iconDC;
+
+ iconDC.SelectObject( bitmap );
+
+ brush.SetColour( MakeColour( aColor ) );
+ brush.SetStyle( wxBRUSHSTYLE_SOLID );
+
+ iconDC.SetBrush( brush );
+
+ iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X - 2 * BUTT_VOID, BUTT_SIZE_Y - 2 * BUTT_VOID );
+
+ return bitmap;
+}
+
+
+wxBitmapButton* LAYER_WIDGET::makeColorButton( wxWindow* aParent, EDA_COLOR_T aColor, int aID )
+{
+ // dynamically make a wxBitMap and brush it with the appropriate color,
+ // then create a wxBitmapButton from it.
+ wxBitmap bitmap = makeBitmap( aColor );
+
+#ifndef __WXMAC__
+ wxBitmapButton* ret = new wxBitmapButton( aParent, aID, bitmap,
+ wxDefaultPosition, wxSize(BUTT_SIZE_X, BUTT_SIZE_Y), wxBORDER_RAISED );
+#else
+ wxBitmapButton* ret = new wxBitmapButton( aParent, aID, bitmap,
+ wxDefaultPosition, wxSize(BUTT_SIZE_X, BUTT_SIZE_Y));
+#endif
+ // save the color value in the name, no where else to put it.
+ ret->SetName( makeColorTxt( aColor ) );
+ return ret;
+}
+
+
+void LAYER_WIDGET::OnLeftDownLayers( wxMouseEvent& event )
+{
+ int row;
+ LAYER_NUM layer;
+
+ wxWindow* eventSource = (wxWindow*) event.GetEventObject();
+
+ // if mouse event is coming from the m_LayerScrolledWindow and not one
+ // of its children, we have to find the row manually based on y coord.
+ if( eventSource == m_LayerScrolledWindow )
+ {
+ int y = event.GetY();
+
+ wxArrayInt heights = m_LayersFlexGridSizer->GetRowHeights();
+
+ int height = 0;
+
+ int rowCount = GetLayerRowCount();
+ for( row = 0; row<rowCount; ++row )
+ {
+ if( y < height + heights[row] )
+ break;
+
+ height += heights[row];
+ }
+
+ if( row >= rowCount )
+ row = rowCount - 1;
+
+ layer = getDecodedId( getLayerComp( row, 0 )->GetId() );
+ }
+
+ else
+ {
+ // all nested controls on a given row will have their ID encoded with
+ // encodeId(), and the corresponding decoding is getDecodedId()
+ int id = eventSource->GetId();
+ layer = getDecodedId( id );
+ row = findLayerRow( layer );
+ }
+
+ if( OnLayerSelect( layer ) ) // if client allows this change.
+ SelectLayerRow( row );
+
+ passOnFocus();
+}
+
+
+void LAYER_WIDGET::OnMiddleDownLayerColor( wxMouseEvent& event )
+{
+ wxBitmapButton* eventSource = (wxBitmapButton*) event.GetEventObject();
+
+ wxString colorTxt = eventSource->GetName();
+
+ EDA_COLOR_T oldColor = ColorFromInt( strtoul( TO_UTF8(colorTxt), NULL, 0 ) );
+ EDA_COLOR_T newColor = DisplayColorFrame( this, oldColor );
+
+ if( newColor >= 0 )
+ {
+ eventSource->SetName( makeColorTxt( newColor ) );
+
+ wxBitmap bm = makeBitmap( newColor );
+ eventSource->SetBitmapLabel( bm );
+
+ LAYER_NUM layer = getDecodedId( eventSource->GetId() );
+
+ // tell the client code.
+ OnLayerColorChange( layer, newColor );
+
+ // notify others
+ wxCommandEvent event( EVT_LAYER_COLOR_CHANGE );
+ wxPostEvent( this, event );
+ }
+
+ passOnFocus();
+}
+
+
+void LAYER_WIDGET::OnLayerCheckBox( wxCommandEvent& event )
+{
+ wxCheckBox* eventSource = (wxCheckBox*) event.GetEventObject();
+ LAYER_NUM layer = getDecodedId( eventSource->GetId() );
+ OnLayerVisible( layer, eventSource->IsChecked() );
+ passOnFocus();
+}
+
+
+void LAYER_WIDGET::OnMiddleDownRenderColor( wxMouseEvent& event )
+{
+ wxBitmapButton* eventSource = (wxBitmapButton*) event.GetEventObject();
+
+ wxString colorTxt = eventSource->GetName();
+
+ EDA_COLOR_T oldColor = ColorFromInt( strtoul( TO_UTF8(colorTxt), NULL, 0 ) );
+ EDA_COLOR_T newColor = DisplayColorFrame( this, oldColor );
+
+ if( newColor >= 0 )
+ {
+ eventSource->SetName( makeColorTxt( newColor ) );
+
+ wxBitmap bm = makeBitmap( newColor );
+ eventSource->SetBitmapLabel( bm );
+
+ LAYER_NUM id = getDecodedId( eventSource->GetId() );
+
+ // tell the client code.
+ OnRenderColorChange( id, newColor );
+ }
+ passOnFocus();
+}
+
+
+void LAYER_WIDGET::OnRenderCheckBox( wxCommandEvent& event )
+{
+ wxCheckBox* eventSource = (wxCheckBox*) event.GetEventObject();
+ LAYER_NUM id = getDecodedId( eventSource->GetId() );
+ OnRenderEnable( id, eventSource->IsChecked() );
+ passOnFocus();
+}
+
+
+void LAYER_WIDGET::OnTabChange( wxNotebookEvent& event )
+{
+// wxFocusEvent event( wxEVT_SET_FOCUS );
+// m_FocusOwner->AddPendingEvent( event );
+
+ passOnFocus(); // does not work in this context, probably because we have receive control here too early.
+}
+
+
+wxWindow* LAYER_WIDGET::getLayerComp( int aRow, int aColumn ) const
+{
+ unsigned ndx = aRow * LYR_COLUMN_COUNT + aColumn;
+ if( ndx < m_LayersFlexGridSizer->GetChildren().GetCount() )
+ return m_LayersFlexGridSizer->GetChildren()[ndx]->GetWindow();
+ return NULL;
+}
+
+
+int LAYER_WIDGET::findLayerRow( LAYER_NUM aLayer ) const
+{
+ int count = GetLayerRowCount();
+ for( int row=0; row<count; ++row )
+ {
+ // column 0 in the layer scroll window has a wxStaticBitmap, get its ID.
+ wxWindow* w = getLayerComp( row, 0 );
+ wxASSERT( w );
+
+ if( aLayer == getDecodedId( w->GetId() ))
+ return row;
+ }
+ return -1;
+}
+
+
+wxWindow* LAYER_WIDGET::getRenderComp( int aRow, int aColumn ) const
+{
+ int ndx = aRow * RND_COLUMN_COUNT + aColumn;
+ if( (unsigned) ndx < m_RenderFlexGridSizer->GetChildren().GetCount() )
+ return m_RenderFlexGridSizer->GetChildren()[ndx]->GetWindow();
+ return NULL;
+}
+
+
+int LAYER_WIDGET::findRenderRow( int aId ) const
+{
+ int count = GetRenderRowCount();
+ for( int row=0; row<count; ++row )
+ {
+ // column 0 in the layer scroll window has a wxStaticBitmap, get its ID.
+ wxWindow* w = getRenderComp( row, 0 );
+ wxASSERT( w );
+
+ if( aId == getDecodedId( w->GetId() ))
+ return row;
+ }
+ return -1;
+}
+
+
+void LAYER_WIDGET::insertLayerRow( int aRow, const ROW& aSpec )
+{
+ wxASSERT( aRow >= 0 );
+
+ int col;
+ int index = aRow * LYR_COLUMN_COUNT;
+ const int flags = wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT;
+
+ // column 0
+ col = 0;
+ wxStaticBitmap* sbm = new wxStaticBitmap( m_LayerScrolledWindow, encodeId( col, aSpec.id ),
+ useAlternateBitmap(aRow) ? *m_BlankAlternateBitmap : *m_BlankBitmap,
+ wxDefaultPosition, m_BitmapSize );
+ sbm->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this );
+ m_LayersFlexGridSizer->wxSizer::Insert( index+col, sbm, 0, flags );
+
+ // column 1 (COLUMN_COLORBM)
+ col = COLUMN_COLORBM;
+ wxBitmapButton* bmb = makeColorButton( m_LayerScrolledWindow, aSpec.color, encodeId( col, aSpec.id ) );
+ bmb->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this );
+ bmb->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnMiddleDownLayerColor ), NULL, this );
+ bmb->SetToolTip( _("Left click to select, middle click for color change, right click for menu" ) );
+ m_LayersFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags );
+
+ // column 2 (COLUMN_COLOR_LYR_CB)
+ col = COLUMN_COLOR_LYR_CB;
+ wxCheckBox* cb = new wxCheckBox( m_LayerScrolledWindow, encodeId( col, aSpec.id ), wxEmptyString );
+ cb->SetValue( aSpec.state );
+ cb->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( LAYER_WIDGET::OnLayerCheckBox ), NULL, this );
+ cb->SetToolTip( _( "Enable this for visibility" ) );
+ m_LayersFlexGridSizer->wxSizer::Insert( index+col, cb, 0, flags );
+
+ // column 3 (COLUMN_COLOR_LYRNAME)
+ col = COLUMN_COLOR_LYRNAME;
+ wxStaticText* st = new wxStaticText( m_LayerScrolledWindow, encodeId( col, aSpec.id ), aSpec.rowName );
+ shrinkFont( st, m_PointSize );
+ st->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnLeftDownLayers ), NULL, this );
+ st->SetToolTip( aSpec.tooltip );
+ m_LayersFlexGridSizer->wxSizer::Insert( index+col, st, 0, flags );
+}
+
+
+void LAYER_WIDGET::insertRenderRow( int aRow, const ROW& aSpec )
+{
+ wxASSERT( aRow >= 0 );
+
+ int col;
+ int index = aRow * RND_COLUMN_COUNT;
+ const int flags = wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT;
+
+ // column 0
+ col = 0;
+ if( aSpec.color != -1 )
+ {
+ wxBitmapButton* bmb = makeColorButton( m_RenderScrolledWindow, aSpec.color, encodeId( col, aSpec.id ) );
+ bmb->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( LAYER_WIDGET::OnMiddleDownRenderColor ), NULL, this );
+ bmb->SetToolTip( _( "Middle click for color change" ) );
+ m_RenderFlexGridSizer->wxSizer::Insert( index+col, bmb, 0, flags );
+
+ // could add a left click handler on the color button that toggles checkbox.
+ }
+ else // == -1, no color selection wanted
+ {
+ // need a place holder within the sizer to keep grid full.
+ wxPanel* invisible = new wxPanel( m_RenderScrolledWindow, encodeId( col, aSpec.id ) );
+ m_RenderFlexGridSizer->wxSizer::Insert( index+col, invisible, 0, flags );
+ }
+
+ // column 1
+ col = 1;
+ wxCheckBox* cb = new wxCheckBox( m_RenderScrolledWindow, encodeId( col, aSpec.id ),
+ aSpec.rowName, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
+ shrinkFont( cb, m_PointSize );
+ cb->SetValue( aSpec.state );
+ cb->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED,
+ wxCommandEventHandler( LAYER_WIDGET::OnRenderCheckBox ), NULL, this );
+ cb->SetToolTip( aSpec.tooltip );
+ m_RenderFlexGridSizer->wxSizer::Insert( index+col, cb, 0, flags );
+}
+
+
+void LAYER_WIDGET::passOnFocus()
+{
+ m_FocusOwner->SetFocus();
+}
+
+
+//-----<public>-------------------------------------------------------
+
+LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPointSize,
+ wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) :
+ wxPanel( aParent, id, pos, size, style )
+{
+ wxBoxSizer* boxSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_notebook = new wxAuiNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP );
+
+ wxFont font = m_notebook->GetFont();
+
+ if( aPointSize == -1 )
+ {
+ m_PointSize = font.GetPointSize();
+ }
+ else
+ {
+ m_PointSize = aPointSize;
+
+ // change the font size on the notebook's tabs to match aPointSize
+ font.SetPointSize( aPointSize );
+ m_notebook->SetFont( font );
+ m_notebook->SetNormalFont( font );
+ m_notebook->SetSelectedFont( font );
+ m_notebook->SetMeasuringFont( font );
+ }
+
+ m_LayerPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+
+ wxBoxSizer* bSizer3;
+ bSizer3 = new wxBoxSizer( wxVERTICAL );
+
+ m_LayerScrolledWindow = new wxScrolledWindow( m_LayerPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER );
+ m_LayerScrolledWindow->SetScrollRate( 5, 5 );
+ m_LayersFlexGridSizer = new wxFlexGridSizer( 0, 4, 0, 1 );
+ m_LayersFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
+ m_LayersFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE );
+
+ m_LayerScrolledWindow->SetSizer( m_LayersFlexGridSizer );
+ m_LayerScrolledWindow->Layout();
+ m_LayersFlexGridSizer->Fit( m_LayerScrolledWindow );
+ bSizer3->Add( m_LayerScrolledWindow, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 2 );
+
+ m_LayerPanel->SetSizer( bSizer3 );
+ m_LayerPanel->Layout();
+ bSizer3->Fit( m_LayerPanel );
+ m_notebook->AddPage( m_LayerPanel, _( "Layer" ), true );
+ m_RenderingPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxVERTICAL );
+
+ m_RenderScrolledWindow = new wxScrolledWindow( m_RenderingPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER );
+ m_RenderScrolledWindow->SetScrollRate( 5, 5 );
+ m_RenderFlexGridSizer = new wxFlexGridSizer( 0, 2, 0, 1 );
+ m_RenderFlexGridSizer->SetFlexibleDirection( wxHORIZONTAL );
+ m_RenderFlexGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_NONE );
+
+ m_RenderScrolledWindow->SetSizer( m_RenderFlexGridSizer );
+ m_RenderScrolledWindow->Layout();
+ m_RenderFlexGridSizer->Fit( m_RenderScrolledWindow );
+ bSizer4->Add( m_RenderScrolledWindow, 1, wxALL|wxEXPAND, 5 );
+
+ m_RenderingPanel->SetSizer( bSizer4 );
+ m_RenderingPanel->Layout();
+ bSizer4->Fit( m_RenderingPanel );
+ m_notebook->AddPage( m_RenderingPanel, _( "Render" ), false );
+
+ boxSizer->Add( m_notebook, 1, wxEXPAND | wxALL, 5 );
+
+ SetSizer( boxSizer );
+
+ m_FocusOwner = aFocusOwner;
+
+ m_CurrentRow = -1; // hide the arrow initially
+
+ m_RightArrowBitmap = new wxBitmap( rightarrow_xpm );
+ m_RightArrowAlternateBitmap = new wxBitmap( rightarrow_alternate_xpm );
+
+ m_BlankBitmap = new wxBitmap( clear_xpm ); // translucent
+ m_BlankAlternateBitmap = new wxBitmap( clear_alternate_xpm );
+ m_BitmapSize = wxSize(m_BlankBitmap->GetWidth(), m_BlankBitmap->GetHeight());
+
+ // trap the tab changes so that we can call passOnFocus().
+ m_notebook->Connect( -1, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
+ wxNotebookEventHandler( LAYER_WIDGET::OnTabChange ), NULL, this );
+
+ Layout();
+}
+
+
+LAYER_WIDGET::~LAYER_WIDGET()
+{
+ delete m_BlankBitmap;
+ delete m_BlankAlternateBitmap;
+ delete m_RightArrowBitmap;
+ delete m_RightArrowAlternateBitmap;
+}
+
+
+wxSize LAYER_WIDGET::GetBestSize() const
+{
+ // size of m_LayerScrolledWindow --------------
+ wxArrayInt widths = m_LayersFlexGridSizer->GetColWidths();
+ int totWidth = 0;
+ if( widths.GetCount() )
+ {
+ for( int i=0; i<LYR_COLUMN_COUNT; ++i )
+ {
+ totWidth += widths[i] + m_LayersFlexGridSizer->GetHGap();
+ // printf("widths[%d]:%d\n", i, widths[i] );
+ }
+ }
+ // Account for the parent's frame:
+ totWidth += 10;
+
+
+ /* The minimum height is a small size to properly force computation
+ * of the panel's scrollbars (otherwise it will assume it *has* all
+ * this space) */
+ unsigned totHeight = 32;
+
+ wxSize layerz( totWidth, totHeight );
+
+ layerz += m_LayerPanel->GetWindowBorderSize();
+
+
+ // size of m_RenderScrolledWindow --------------
+ widths = m_RenderFlexGridSizer->GetColWidths();
+ totWidth = 0;
+ if( widths.GetCount() )
+ {
+ for( int i=0; i<RND_COLUMN_COUNT; ++i )
+ {
+ totWidth += widths[i] + m_RenderFlexGridSizer->GetHGap();
+ // printf("widths[%d]:%d\n", i, widths[i] );
+ }
+ }
+ // account for the parent's frame, this one has void space of 10 PLUS a border:
+ totWidth += 20;
+
+ // For totHeight re-use the previous small one
+ wxSize renderz( totWidth, totHeight );
+
+ renderz += m_RenderingPanel->GetWindowBorderSize();
+
+ wxSize clientz( std::max(renderz.x,layerz.x), std::max(renderz.y,layerz.y) );
+
+ return clientz;
+}
+
+
+int LAYER_WIDGET::GetLayerRowCount() const
+{
+ int controlCount = m_LayersFlexGridSizer->GetChildren().GetCount();
+ return controlCount / LYR_COLUMN_COUNT;
+}
+
+
+int LAYER_WIDGET::GetRenderRowCount() const
+{
+ int controlCount = m_RenderFlexGridSizer->GetChildren().GetCount();
+ return controlCount / RND_COLUMN_COUNT;
+}
+
+
+void LAYER_WIDGET::AppendLayerRow( const ROW& aRow )
+{
+ int nextRow = GetLayerRowCount();
+ insertLayerRow( nextRow, aRow );
+ UpdateLayouts();
+}
+
+
+void LAYER_WIDGET::ClearLayerRows()
+{
+ m_LayersFlexGridSizer->Clear( true );
+}
+
+
+void LAYER_WIDGET::AppendRenderRow( const ROW& aRow )
+{
+ int nextRow = GetRenderRowCount();
+ insertRenderRow( nextRow, aRow );
+ UpdateLayouts();
+}
+
+
+void LAYER_WIDGET::ClearRenderRows()
+{
+ m_RenderFlexGridSizer->Clear( true );
+}
+
+
+void LAYER_WIDGET::SelectLayerRow( int aRow )
+{
+ // enable the layer tab at index 0
+ m_notebook->SetSelection( 0 );
+
+ wxStaticBitmap* oldbm = (wxStaticBitmap*) getLayerComp( m_CurrentRow, 0 );
+ if( oldbm )
+ oldbm->SetBitmap( useAlternateBitmap(m_CurrentRow) ? *m_BlankAlternateBitmap : *m_BlankBitmap );
+
+ wxStaticBitmap* newbm = (wxStaticBitmap*) getLayerComp( aRow, 0 );
+ if( newbm )
+ {
+ newbm->SetBitmap( useAlternateBitmap(aRow) ? *m_RightArrowAlternateBitmap : *m_RightArrowBitmap );
+
+ // Make sure the desired layer row is visible.
+ // It seems that as of 2.8.2, setting the focus does this.
+ // I don't expect the scrolling to be needed at all because
+ // the minimum window size may end up being established so that the
+ // scroll bars will not be visible.
+ getLayerComp( aRow, 1 )->SetFocus();
+ }
+
+ m_CurrentRow = aRow;
+
+ // give the focus back to the app.
+ passOnFocus();
+}
+
+
+void LAYER_WIDGET::SelectLayer( LAYER_NUM aLayer )
+{
+ int row = findLayerRow( aLayer );
+ SelectLayerRow( row );
+}
+
+
+LAYER_NUM LAYER_WIDGET::GetSelectedLayer()
+{
+ wxWindow* w = getLayerComp( m_CurrentRow, 0 );
+ if( w )
+ return getDecodedId( w->GetId() );
+
+ return UNDEFINED_LAYER;
+}
+
+
+void LAYER_WIDGET::SetLayerVisible( LAYER_NUM aLayer, bool isVisible )
+{
+ int row = findLayerRow( aLayer );
+ if( row >= 0 )
+ {
+ wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
+ wxASSERT( cb );
+ cb->SetValue( isVisible ); // does not fire an event
+ }
+}
+
+
+bool LAYER_WIDGET::IsLayerVisible( LAYER_NUM aLayer )
+{
+ int row = findLayerRow( aLayer );
+ if( row >= 0 )
+ {
+ wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
+ wxASSERT( cb );
+ return cb->GetValue();
+ }
+ return false;
+}
+
+
+void LAYER_WIDGET::SetLayerColor( LAYER_NUM aLayer, EDA_COLOR_T aColor )
+{
+ int row = findLayerRow( aLayer );
+ if( row >= 0 )
+ {
+ int col = 1; // bitmap button is column 1
+ wxBitmapButton* bmb = (wxBitmapButton*) getLayerComp( row, col );
+ wxASSERT( bmb );
+
+ wxBitmap bm = makeBitmap( aColor );
+
+ bmb->SetBitmapLabel( bm );
+ bmb->SetName( makeColorTxt( aColor ) ); // save color value in name as string
+ }
+}
+
+
+EDA_COLOR_T LAYER_WIDGET::GetLayerColor( LAYER_NUM aLayer ) const
+{
+ int row = findLayerRow( aLayer );
+ if( row >= 0 )
+ {
+ int col = 1; // bitmap button is column 1
+ wxBitmapButton* bmb = (wxBitmapButton*) getLayerComp( row, col );
+ wxASSERT( bmb );
+
+ wxString colorTxt = bmb->GetName();
+ return ColorFromInt( strtoul( TO_UTF8(colorTxt), NULL, 0 ) );
+ }
+
+ return UNSPECIFIED_COLOR; // it's caller fault, gave me a bad layer
+}
+
+
+void LAYER_WIDGET::SetRenderState( int aId, bool isSet )
+{
+ int row = findRenderRow( aId );
+ if( row >= 0 )
+ {
+ int col = 1; // checkbox is column 1
+ wxCheckBox* cb = (wxCheckBox*) getRenderComp( row, col );
+ wxASSERT( cb );
+ cb->SetValue( isSet ); // does not fire an event
+ }
+}
+
+
+bool LAYER_WIDGET::GetRenderState( int aId )
+{
+ int row = findRenderRow( aId );
+ if( row >= 0 )
+ {
+ int col = 1; // checkbox is column 1
+ wxCheckBox* cb = (wxCheckBox*) getRenderComp( row, col );
+ wxASSERT( cb );
+ return cb->GetValue();
+ }
+ return false; // the value of a non-existent row
+}
+
+
+void LAYER_WIDGET::UpdateLayouts()
+{
+ m_LayersFlexGridSizer->Layout();
+ m_RenderFlexGridSizer->Layout();
+ m_LayerPanel->Layout();
+ m_RenderingPanel->Layout();
+ FitInside();
+}
+
+#if defined(STAND_ALONE)
+
+#include <wx/aui/aui.h>
+
+
+/**
+ * Class MYFRAME
+ * is a test class here to exercise the LAYER_WIDGET and explore use cases.
+ * @see http://www.kirix.com/labs/wxaui/screenshots.html
+ * for ideas.
+ */
+class MYFRAME : public wxFrame
+{
+ // example of how to derive from LAYER_WIDGET in order to provide the
+ // abstract methods.
+ class MYLAYERS : public LAYER_WIDGET
+ {
+ public:
+ // your constructor could take a BOARD argument. here I leave it
+ // out because this source module wants to know nothing of BOARDs
+ // to maximize re-use.
+ MYLAYERS( wxWindow* aParent ) :
+ LAYER_WIDGET( aParent, aParent )
+ {
+ }
+
+ void OnLayerColorChange( int aLayer, EDA_COLOR_T aColor )
+ {
+ printf( "OnLayerColorChange( aLayer:%d, aColor:%d )\n", aLayer, aColor );
+
+ /* a test trigger only
+ if( aLayer == 2 )
+ {
+ ClearLayerRows();
+ printf(" GetLayerRowCount(): %d\n", GetLayerRowCount() );
+ }
+ */
+ }
+
+ bool OnLayerSelect( LAYER aLayer )
+ {
+ printf( "OnLayerSelect( aLayer:%d )\n", aLayer );
+ return true;
+ }
+
+ void OnLayerVisible( LAYER aLayer, bool isVisible, bool isFinal )
+ {
+ printf( "OnLayerVisible( aLayer:%d, isVisible:%d isFinal:%d)\n", aLayer, isVisible, isFinal );
+ }
+
+ void OnRenderColorChange( int aId, EDA_COLOR_T aColor )
+ {
+ printf( "OnRenderColorChange( aId:%d, aColor:%d )\n", aId, aColor );
+ }
+
+ void OnRenderEnable( int aId, bool isEnabled )
+ {
+ printf( "OnRenderEnable( aId:%d, isEnabled:%d )\n", aId, isEnabled );
+ }
+ };
+
+
+public:
+ MYFRAME( wxWindow * parent ) :
+ wxFrame( parent, -1, wxT( "wxAUI Test" ), wxDefaultPosition,
+ wxSize( 800, 600 ), wxDEFAULT_FRAME_STYLE )
+ {
+ // notify wxAUI which frame to use
+ m_mgr.SetManagedWindow( this );
+
+ MYLAYERS* lw = new MYLAYERS( this );
+
+ // add some layer rows
+ static const LAYER_WIDGET::ROW layerRows[] = {
+ LAYER_WIDGET::ROW( wxT("layer 1"), 0, RED, wxT("RED"), false ),
+ LAYER_WIDGET::ROW( wxT("layer 2"), 1, GREEN, wxT("GREEN"), true ),
+ LAYER_WIDGET::ROW( wxT("brown_layer"), 2, BROWN, wxT("BROWN"), true ),
+ LAYER_WIDGET::ROW( wxT("layer_4_you"), 3, BLUE, wxT("BLUE"), false ),
+ };
+
+ lw->AppendLayerRows( layerRows, DIM(layerRows) );
+
+ // add some render rows
+ static const LAYER_WIDGET::ROW renderRows[] = {
+ LAYER_WIDGET::ROW( wxT("With Very Large Ears"), 0, -1, wxT("Spock here") ),
+ LAYER_WIDGET::ROW( wxT("With Legs"), 1, YELLOW ),
+ LAYER_WIDGET::ROW( wxT("With Oval Eyes"), 1, BROWN, wxT("My eyes are upon you") ),
+ };
+
+ lw->AppendRenderRows( renderRows, DIM(renderRows) );
+
+ lw->SelectLayerRow( 1 );
+
+ wxAuiPaneInfo li;
+ li.MinSize( lw->GetBestSize() );
+ li.BestSize( lw->GetBestSize() );
+ li.Left();
+// li.MaximizeButton( true );
+// li.MinimizeButton( true );
+ li.CloseButton( false );
+ li.Caption( wxT( "Layers" ) );
+ m_mgr.AddPane( lw, li );
+
+
+ wxTextCtrl* text2 = new wxTextCtrl( this, -1, wxT( "Pane 2 - sample text" ),
+ wxDefaultPosition, wxSize( 200, 150 ),
+ wxNO_BORDER | wxTE_MULTILINE );
+ m_mgr.AddPane( text2, wxBOTTOM, wxT( "Pane Number Two" ) );
+
+ wxTextCtrl* text3 = new wxTextCtrl( this, -1, wxT( "Main content window" ),
+ wxDefaultPosition, wxSize( 200, 150 ),
+ wxNO_BORDER | wxTE_MULTILINE );
+ m_mgr.AddPane( text3, wxCENTER );
+
+ // tell the manager to "commit" all the changes just made
+ m_mgr.Update();
+ }
+
+ ~MYFRAME()
+ {
+ // deinitialize the frame manager
+ m_mgr.UnInit();
+ }
+
+private:
+ wxAuiManager m_mgr;
+};
+
+
+// our normal wxApp-derived class, as usual
+class MyApp : public wxApp
+{
+public:
+
+ bool OnInit()
+ {
+ wxFrame* frame = new MYFRAME( NULL );
+
+ SetTopWindow( frame );
+ frame->Show();
+ return true;
+ }
+};
+
+DECLARE_APP( MyApp );
+IMPLEMENT_APP( MyApp );
+
+#endif // STAND_ALONE
diff --git a/pcbnew/layer_widget.h b/pcbnew/layer_widget.h
new file mode 100644
index 0000000..e35be8e
--- /dev/null
+++ b/pcbnew/layer_widget.h
@@ -0,0 +1,434 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef LAYERWIDGET_H_
+#define LAYERWIDGET_H_
+
+#include <wx/intl.h>
+#include <wx/wx.h>
+#include <wx/statbmp.h>
+#include <wx/string.h>
+#include <wx/aui/auibook.h>
+#include <wx/notebook.h>
+#include <wx/sizer.h>
+#include <wx/gdicmn.h>
+#include <wx/scrolwin.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <layers_id_colors_and_visibility.h>
+#include <colors.h>
+
+#define LYR_COLUMN_COUNT 4 ///< Layer tab column count
+#define RND_COLUMN_COUNT 2 ///< Rendering tab column count
+
+#define COLUMN_ICON_ACTIVE 0
+#define COLUMN_COLORBM 1
+#define COLUMN_COLOR_LYR_CB 2
+#define COLUMN_COLOR_LYRNAME 3
+
+
+/**
+ * Class LAYER_WIDGET
+ * is abstract and is used to manage a list of layers, with the notion of
+ * a "current" layer, and layer specific visibility control. You must derive from
+ * it to use it so you can implement the abstract functions which recieve the
+ * events. Each layer is given its own color, and that color can be changed
+ * within the UI provided here. This widget knows nothing of the client code, meaning
+ * it has no knowledge of a BOARD or anything. To use it you must derive from
+ * this class and implement the abstract functions:
+ * <p> void OnLayerColorChange( int aLayer, int aColor );
+ * <p> bool OnLayerSelect( int aLayer );
+ * <p> void OnLayerVisible( int aLayer, bool isVisible );
+ * <p> void OnRenderColorChange( int id, int aColor );
+ * <p> void OnRenderEnable( int id, bool isEnabled );
+ *
+ * Please note that even if designed toward layers, it is used to
+ * contain other stuff, too (the second page in pcbnew contains render
+ * items, for example)
+ */
+class LAYER_WIDGET : public wxPanel
+{
+public:
+ /**
+ * Struct ROW
+ * provides all the data needed to add a row to a LAYER_WIDGET. This is
+ * part of the public API for a LAYER_WIDGET.
+ */
+ struct ROW
+ {
+ wxString rowName; ///< the prompt or layername
+ int id; ///< either a layer or "visible element" id
+ EDA_COLOR_T color; ///< -1 if none.
+ bool state; ///< initial wxCheckBox state
+ wxString tooltip; ///< if not empty, use this tooltip on row
+
+ ROW( const wxString& aRowName, int aId, EDA_COLOR_T aColor = UNSPECIFIED_COLOR,
+ const wxString& aTooltip = wxEmptyString, bool aState = true )
+ {
+ rowName = aRowName;
+ id = aId;
+ color = aColor;
+ state = aState;
+ tooltip = aTooltip;
+ }
+ };
+
+ static const wxEventType EVT_LAYER_COLOR_CHANGE;
+
+protected:
+
+ wxAuiNotebook* m_notebook;
+ wxPanel* m_LayerPanel;
+ wxScrolledWindow* m_LayerScrolledWindow;
+ wxFlexGridSizer* m_LayersFlexGridSizer;
+ wxPanel* m_RenderingPanel;
+ wxScrolledWindow* m_RenderScrolledWindow;
+ wxFlexGridSizer* m_RenderFlexGridSizer;
+
+ wxWindow* m_FocusOwner;
+ wxBitmap* m_BlankBitmap;
+ wxBitmap* m_BlankAlternateBitmap;
+ wxBitmap* m_RightArrowBitmap;
+ wxBitmap* m_RightArrowAlternateBitmap;
+ wxSize m_BitmapSize;
+ int m_CurrentRow; ///< selected row of layer list
+ int m_PointSize;
+
+ static wxBitmap makeBitmap( EDA_COLOR_T aColor );
+
+ /**
+ * Virtual Function useAlternateBitmap
+ * @return true if bitmaps shown in Render layer list
+ * are alternate bitmaps, or false if they are "normal" bitmaps
+ * This is a virtual function because Pcbnew uses normal bitmaps
+ * but GerbView uses both bitmaps
+ * (alternate bitmaps to show layers in use, normal fo others)
+ */
+ virtual bool useAlternateBitmap(int aRow) { return false; }
+
+ /**
+ * Function encodeId
+ * is here to allow saving a layer index within a control as its wxControl id,
+ * but to do so in a way that all child wxControl ids within a wxWindow are unique,
+ * since this is required by Windows.
+ * @see getDecodedId()
+ */
+ static int encodeId( int aColumn, int aId );
+
+ /**
+ * Function getDecodedId
+ * decodes \a aControlId to original un-encoded value. This of
+ * course holds iff encodedId was called with a LAYER_NUM (this box
+ * is used for other things than layers, too)
+ */
+ static LAYER_NUM getDecodedId( int aControlId );
+
+ /**
+ * Function makeColorButton
+ * creates a wxBitmapButton and assigns it a solid color and a control ID
+ */
+ wxBitmapButton* makeColorButton( wxWindow* aParent, EDA_COLOR_T aColor, int aID );
+
+ void OnLeftDownLayers( wxMouseEvent& event );
+
+ /**
+ * Function OnMiddleDownLayerColor
+ * is called only from a color button when user right clicks.
+ */
+ void OnMiddleDownLayerColor( wxMouseEvent& event );
+
+ /**
+ * Function OnLayerCheckBox
+ * handles the "is layer visible" checkbox and propogates the
+ * event to the client's notification function.
+ */
+ void OnLayerCheckBox( wxCommandEvent& event );
+
+ void OnMiddleDownRenderColor( wxMouseEvent& event );
+
+ void OnRenderCheckBox( wxCommandEvent& event );
+
+ void OnTabChange( wxNotebookEvent& event );
+
+
+ /**
+ * Function getLayerComp
+ * returns the component within the m_LayersFlexGridSizer at @a aRow and @a aCol
+ * or NULL if these parameters are out of range.
+ *
+ * @param aRow is the row index
+ * @param aColumn is the column
+ * @return wxWindow - the component installed within the sizer at given grid coordinate.
+ */
+ wxWindow* getLayerComp( int aRow, int aColumn ) const;
+ wxWindow* getRenderComp( int aRow, int aColumn ) const;
+
+ /**
+ * Function findLayerRow
+ * returns the row index that \a aLayer resides in, or -1 if not found.
+ */
+ int findLayerRow( LAYER_NUM aLayer ) const;
+ int findRenderRow( int aId ) const;
+
+ /**
+ * Function insertLayerRow
+ * appends or inserts a new row in the layer portion of the widget.
+ */
+ void insertLayerRow( int aRow, const ROW& aSpec );
+
+ void insertRenderRow( int aRow, const ROW& aSpec );
+
+ /**
+ * Function passOnFocus
+ * gives away the keyboard focus up to the main parent window.
+ */
+ void passOnFocus();
+
+public:
+
+ /** Constructor
+ * @param aParent is the parent window
+ * @param aFocusOwner is the window that should be sent the focus after
+ * @param aPointSize is the font point size to use within the widget. This
+ * effectively sets the overal size of the widget via the row height and bitmap
+ * button sizes.
+ * @param id is the wxWindow id ( default = wxID_ANY)
+ * @param pos is the window position
+ * @param size is the window size
+ * @param style is the window style
+ * every operation.
+ */
+ LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPointSize = -1,
+ wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL );
+
+ virtual ~LAYER_WIDGET();
+
+ /**
+ * Function GetBestSize
+ * returns the preferred minimum size, taking into consideration the
+ * dynamic content. Nothing in wxWidgets was reliable enough so this
+ * overrides one of their functions.
+ */
+ wxSize GetBestSize() const;
+
+ /**
+ * Function GetLayerRowCount
+ * returns the number of rows in the layer tab.
+ */
+ int GetLayerRowCount() const;
+
+ /**
+ * Function GetRenderRowCount
+ * returns the number of rows in the render tab.
+ */
+ int GetRenderRowCount() const;
+
+ /**
+ * Function AppendLayerRow
+ * appends a new row in the layer portion of the widget. The user must
+ * ensure that ROW::id is unique for all existing rows on Windows.
+ */
+ void AppendLayerRow( const ROW& aRow );
+
+ /**
+ * Function AppendLayerRows
+ * appends new rows in the layer portion of the widget. The user must
+ * ensure that ROW::id is unique for all existing rows on Windows.
+ */
+ void AppendLayerRows( const ROW* aRowsArray, int aRowCount )
+ {
+ for( int row=0; row<aRowCount; ++row )
+ AppendLayerRow( aRowsArray[row] );
+ }
+
+ /**
+ * Function ClearLayerRows
+ * empties out the layer rows.
+ */
+ void ClearLayerRows();
+
+ /**
+ * Function AppendRenderRow
+ * appends a new row in the render portion of the widget. The user must
+ * ensure that ROW::id is unique for all existing rows on Windows.
+ */
+ void AppendRenderRow( const ROW& aRow );
+
+ /**
+ * Function AppendRenderRows
+ * appends new rows in the render portion of the widget. The user must
+ * ensure that ROW::id is unique for all existing rows on Windows.
+ */
+ void AppendRenderRows( const ROW* aRowsArray, int aRowCount )
+ {
+ for( int row=0; row<aRowCount; ++row )
+ AppendRenderRow( aRowsArray[row] );
+ }
+
+ /**
+ * Function ClearRenderRows
+ * empties out the render rows.
+ */
+ void ClearRenderRows();
+
+ /**
+ * Function SelectLayerRow
+ * changes the row selection in the layer list to the given row.
+ */
+ void SelectLayerRow( int aRow );
+
+ /**
+ * Function SelectLayer
+ * changes the row selection in the layer list to \a aLayer provided.
+ */
+ void SelectLayer( LAYER_NUM aLayer );
+
+ /**
+ * Function GetSelectedLayer
+ * returns the selected layer or -1 if none.
+ */
+ LAYER_NUM GetSelectedLayer();
+
+ /**
+ * Function SetLayerVisible
+ * sets \a aLayer visible or not. This does not invoke OnLayerVisible().
+ */
+ void SetLayerVisible( LAYER_NUM aLayer, bool isVisible );
+
+ /**
+ * Function IsLayerVisible
+ * returns the visible state of the layer ROW associated with \a aLayer id.
+ */
+ bool IsLayerVisible( LAYER_NUM aLayer );
+
+ /**
+ * Function SetLayerColor
+ * changes the color of \a aLayer
+ */
+ void SetLayerColor( LAYER_NUM aLayer, EDA_COLOR_T aColor );
+
+ /**
+ * Function GetLayerColor
+ * returns the color of the layer ROW associated with \a aLayer id.
+ */
+ EDA_COLOR_T GetLayerColor( LAYER_NUM aLayer ) const;
+
+ /**
+ * Function SetRenderState
+ * sets the state of the checkbox associated with \a aId within the
+ * Render tab group of the widget. Does not fire an event, i.e. does
+ * not invoke OnRenderEnable().
+ * @param aId is the same unique id used when adding a ROW to the
+ * Render tab.
+ * @param isSet = the new checkbox state
+ */
+ void SetRenderState( int aId, bool isSet );
+
+ /**
+ * Function GetRenderState
+ * returns the state of the checkbox associated with \a aId.
+ * @return bool - true if checked, else false.
+ */
+ bool GetRenderState( int aId );
+
+ void UpdateLayouts();
+
+/* did not help:
+ void Freeze()
+ {
+ LAYER_PANEL_BASE::Freeze();
+ m_LayerScrolledWindow->Freeze();
+ m_RenderScrolledWindow->Freeze();
+ }
+
+ void Thaw()
+ {
+ m_RenderScrolledWindow->Thaw();
+ m_LayerScrolledWindow->Thaw();
+ LAYER_PANEL_BASE::Thaw();
+ }
+*/
+
+ //-----<abstract functions>-------------------------------------------
+
+ /**
+ * Function OnLayerColorChange
+ * is called to notify client code about a layer color change. Derived
+ * classes will handle this accordingly.
+ * @param aLayer is the board layer to change
+ * @param aColor is the new color
+ */
+ virtual void OnLayerColorChange( int aLayer, EDA_COLOR_T aColor ) = 0;
+
+ /**
+ * Function OnLayerSelect
+ * is called to notify client code whenever the user selects a different
+ * layer. Derived classes will handle this accordingly, and can deny
+ * the change by returning false.
+ * @param aLayer is the board layer to select
+ */
+ virtual bool OnLayerSelect( int aLayer ) = 0;
+
+ /**
+ * Function OnLayerVisible
+ * is called to notify client code about a layer visibility change.
+ *
+ * @param aLayer is the board layer to select
+ * @param isVisible is the new visible state
+ * @param isFinal is true when this is the last of potentially several
+ * such calls, and can be used to decide when to update the screen only
+ * one time instead of several times in the midst of a multiple layer change.
+ */
+ virtual void OnLayerVisible( LAYER_NUM aLayer, bool isVisible, bool isFinal = true ) = 0;
+
+ /**
+ * Function OnRenderColorChange
+ * is called to notify client code whenever the user changes a rendering
+ * color.
+ * @param aId is the same id that was established in a Rendering row
+ * via the AddRenderRow() function.
+ * @param aColor is the new color
+ */
+ virtual void OnRenderColorChange( int aId, EDA_COLOR_T aColor ) = 0;
+
+ /**
+ * Function OnRenderEnable
+ * is called to notify client code whenever the user changes an rendering
+ * enable in one of the rendering checkboxes.
+ * @param aId is the same id that was established in a Rendering row
+ * via the AddRenderRow() function.
+ * @param isEnabled is the state of the checkbox, true if checked.
+ */
+ virtual void OnRenderEnable( int aId, bool isEnabled ) = 0;
+
+ //-----</abstract functions>------------------------------------------
+};
+
+#endif // LAYERWIDGET_H_
diff --git a/pcbnew/legacy_netlist_reader.cpp b/pcbnew/legacy_netlist_reader.cpp
new file mode 100644
index 0000000..a559c7b
--- /dev/null
+++ b/pcbnew/legacy_netlist_reader.cpp
@@ -0,0 +1,264 @@
+/**
+ * @file pcbnew/legacy_netlist_reader.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2011 Jean-Pierre Charras.
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>.
+ * Copyright (C) 1992-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <richio.h>
+#include <kicad_string.h>
+
+#include <pcb_netlist.h>
+#include <netlist_reader.h>
+
+void LEGACY_NETLIST_READER::LoadNetlist() throw ( IO_ERROR, PARSE_ERROR, boost::bad_pointer )
+{
+ int state = 0;
+ bool is_comment = false;
+ COMPONENT* component = NULL;
+
+ while( m_lineReader->ReadLine() )
+ {
+ char* line = StrPurge( m_lineReader->Line() );
+
+ if( is_comment ) // Comments in progress
+ {
+ // Test for end of the current comment
+ if( ( line = strchr( line, '}' ) ) == NULL )
+ continue;
+
+ is_comment = false;
+ }
+
+ if( *line == '{' ) // Start Comment or Pcbnew info section
+ {
+ is_comment = true;
+
+ if( m_loadFootprintFilters && state == 0
+ && (strnicmp( line, "{ Allowed footprints", 20 ) == 0) )
+ {
+ loadFootprintFilters();
+ continue;
+ }
+
+ if( ( line = strchr( line, '}' ) ) == NULL )
+ continue;
+ }
+
+ if( *line == '(' )
+ state++;
+
+ if( *line == ')' )
+ state--;
+
+ if( state == 2 )
+ {
+ component = loadComponent( line );
+ continue;
+ }
+
+ if( state >= 3 ) // Pad descriptions are read here.
+ {
+ wxASSERT( component != NULL );
+
+ loadNet( line, component );
+ state--;
+ }
+ }
+
+ if( m_footprintReader )
+ {
+ m_footprintReader->Load( m_netlist );
+ }
+}
+
+
+COMPONENT* LEGACY_NETLIST_READER::loadComponent( char* aText )
+ throw( PARSE_ERROR, boost::bad_pointer )
+{
+ char* text;
+ wxString msg;
+ wxString timeStamp; // the full time stamp read from netlist
+ wxString footprintName; // the footprint name read from netlist
+ wxString value; // the component value read from netlist
+ wxString reference; // the component schematic reference designator read from netlist
+ wxString name; // the name of component that was placed in the schematic
+ char line[1024];
+
+ strncpy( line, aText, sizeof(line)-1 );
+ line[sizeof(line)-1] = '\0';
+
+ value = wxT( "~" );
+
+ // Sample component line: /40C08647 $noname R20 4.7K {Lib=R}
+
+ // Read time stamp (first word)
+ if( ( text = strtok( line, " ()\t\n" ) ) == NULL )
+ {
+ msg = _( "Cannot parse time stamp in component section of netlist." );
+ THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
+ m_lineReader->Length() );
+ }
+
+ timeStamp = FROM_UTF8( text );
+
+ // Read footprint name (second word)
+ if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
+ {
+ msg = _( "Cannot parse footprint name in component section of netlist." );
+ THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
+ m_lineReader->Length() );
+ }
+
+ footprintName = FROM_UTF8( text );
+
+ // The footprint name will have to be looked up in the *.cmp file.
+ if( footprintName == wxT( "$noname" ) )
+ footprintName = wxEmptyString;
+
+ // Read schematic reference designator (third word)
+ if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
+ {
+ msg = _( "Cannot parse reference designator in component section of netlist." );
+ THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
+ m_lineReader->Length() );
+ }
+
+ reference = FROM_UTF8( text );
+
+ // Read schematic value (forth word)
+ if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
+ {
+ msg = _( "Cannot parse value in component section of netlist." );
+ THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), aText, m_lineReader->LineNumber(),
+ m_lineReader->Length() );
+ }
+
+ value = FROM_UTF8( text );
+
+ // Read component name (fifth word) {Lib=C}
+ // This is an optional field (a comment), which does not always exists
+ if( ( text = strtok( NULL, " ()\t\n" ) ) != NULL )
+ {
+ name = FROM_UTF8( text ).AfterFirst( wxChar( '=' ) ).BeforeLast( wxChar( '}' ) );
+ }
+
+ FPID fpid;
+
+ if( !footprintName.IsEmpty() )
+ fpid.SetFootprintName( footprintName );
+
+ COMPONENT* component = new COMPONENT( fpid, reference, value, timeStamp );
+ component->SetName( name );
+ m_netlist->AddComponent( component );
+ return component;
+}
+
+
+void LEGACY_NETLIST_READER::loadNet( char* aText, COMPONENT* aComponent ) throw( PARSE_ERROR )
+{
+ wxString msg;
+ char* p;
+ char line[256];
+
+ strncpy( line, aText, sizeof( line ) );
+ line[ sizeof(line) - 1 ] = '\0';
+
+ if( ( p = strtok( line, " ()\t\n" ) ) == NULL )
+ {
+ msg = _( "Cannot parse pin name in component net section of netlist." );
+ THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
+ m_lineReader->Length() );
+ }
+
+ wxString pinName = FROM_UTF8( p );
+
+ if( ( p = strtok( NULL, " ()\t\n" ) ) == NULL )
+ {
+ msg = _( "Cannot parse net name in component net section of netlist." );
+ THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
+ m_lineReader->Length() );
+ }
+
+ wxString netName = FROM_UTF8( p );
+
+ if( (char) netName[0] == '?' ) // ? indicates no net connected to pin.
+ netName = wxEmptyString;
+
+ aComponent->AddNet( pinName, netName );
+}
+
+
+void LEGACY_NETLIST_READER::loadFootprintFilters() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxArrayString filters;
+ wxString cmpRef;
+ char* line;
+ COMPONENT* component = NULL; // Suppress compil warning
+
+ while( ( line = m_lineReader->ReadLine() ) != NULL )
+ {
+ if( strnicmp( line, "$endlist", 8 ) == 0 ) // end of list for the current component
+ {
+ wxASSERT( component != NULL );
+ component->SetFootprintFilters( filters );
+ component = NULL;
+ filters.Clear();
+ continue;
+ }
+
+ if( strnicmp( line, "$endfootprintlist", 4 ) == 0 )
+ // End of this section
+ return;
+
+ if( strnicmp( line, "$component", 10 ) == 0 ) // New component reference found
+ {
+ cmpRef = FROM_UTF8( line + 11 );
+ cmpRef.Trim( true );
+ cmpRef.Trim( false );
+
+ component = m_netlist->GetComponentByReference( cmpRef );
+
+ // Cannot happen if the netlist is valid.
+ if( component == NULL )
+ {
+ wxString msg;
+ msg.Printf( _( "Cannot find component \'%s\' in footprint filter section "
+ "of netlist." ), GetChars( cmpRef ) );
+ THROW_PARSE_ERROR( msg, m_lineReader->GetSource(), line, m_lineReader->LineNumber(),
+ m_lineReader->Length() );
+ }
+ }
+ else
+ {
+ // Add new filter to list
+ wxString fp = FROM_UTF8( line + 1 );
+ fp.Trim( false );
+ fp.Trim( true );
+ filters.Add( fp );
+ }
+ }
+}
diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp
new file mode 100644
index 0000000..713a18f
--- /dev/null
+++ b/pcbnew/legacy_plugin.cpp
@@ -0,0 +1,4793 @@
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2004 Jean-Pierre Charras, jp.charras@wanadoo.fr
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ This implements loading and saving a BOARD, behind the PLUGIN interface.
+
+ The definitions:
+
+ *) a Board Internal Unit (BIU) is a unit of length that is used only internally
+ to PCBNEW, and is nanometers when this work is done, but deci-mils until done.
+
+ The philosophies:
+
+ *) BIUs should be typed as such to distinguish them from ints. This is mostly
+ for human readability, and having the type nearby in the source supports this readability.
+ *) Do not assume that BIUs will always be int, doing a sscanf() into a BIU
+ does not make sense in case the size of the BIU changes.
+ *) variables are put onto the stack in an automatic, even when it might look
+ more efficient to do otherwise. This is so we can seem them with a debugger.
+ *) Global variables should not be touched from within a PLUGIN, since it will eventually
+ be in a DLL/DSO. This includes window information too. The PLUGIN API knows
+ nothing of wxFrame or globals and all error reporting must be done by throwing
+ an exception.
+ *) No wxWindowing calls are made in here, since the UI resides higher up than in here,
+ and is going to process a bucket of detailed information thrown from down here
+ in the form of an exception if an error happens.
+ *) Much of what we do in this source file is for human readability, not performance.
+ Simply avoiding strtok() more often than the old code washes out performance losses.
+ Remember strncmp() will bail as soon as a mismatch happens, not going all the way
+ to end of string unless a full match.
+ *) angles are in the process of migrating to doubles, and 'int' if used, is
+ only shortterm, and along with this a change, and transition from from
+ "tenths of degrees" to simply "degrees" in the double (which has no problem
+ representing any portion of a degree).
+*/
+
+
+#include <cmath>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <wx/ffile.h>
+
+#include <legacy_plugin.h> // implement this here
+
+#include <kicad_string.h>
+#include <macros.h>
+#include <zones.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_pcb_text.h>
+#include <class_zone.h>
+#include <class_dimension.h>
+#include <class_drawsegment.h>
+#include <class_mire.h>
+#include <class_edge_mod.h>
+#include <3d_struct.h>
+#include <pcb_plot_params.h>
+#include <pcb_plot_params_parser.h>
+#include <drawtxt.h>
+#include <convert_to_biu.h>
+#include <trigo.h>
+#include <build_version.h>
+
+#include <boost/make_shared.hpp>
+
+
+typedef LEGACY_PLUGIN::BIU BIU;
+
+
+#define VERSION_ERROR_FORMAT _( "File '%s' is format version: %d.\nI only support format version <= %d.\nPlease upgrade Pcbnew to load this file." )
+#define UNKNOWN_GRAPHIC_FORMAT _( "unknown graphic type: %d")
+#define UNKNOWN_PAD_FORMAT _( "unknown pad type: %d")
+#define UNKNOWN_PAD_ATTRIBUTE _( "unknown pad attribute: %d" )
+
+
+typedef unsigned LEG_MASK;
+
+#define FIRST_LAYER 0
+#define FIRST_COPPER_LAYER 0
+#define LAYER_N_BACK 0
+#define LAYER_N_2 1
+#define LAYER_N_3 2
+#define LAYER_N_4 3
+#define LAYER_N_5 4
+#define LAYER_N_6 5
+#define LAYER_N_7 6
+#define LAYER_N_8 7
+#define LAYER_N_9 8
+#define LAYER_N_10 9
+#define LAYER_N_11 10
+#define LAYER_N_12 11
+#define LAYER_N_13 12
+#define LAYER_N_14 13
+#define LAYER_N_15 14
+#define LAYER_N_FRONT 15
+#define LAST_COPPER_LAYER LAYER_N_FRONT
+
+#define FIRST_NON_COPPER_LAYER 16
+#define ADHESIVE_N_BACK 16
+#define ADHESIVE_N_FRONT 17
+#define SOLDERPASTE_N_BACK 18
+#define SOLDERPASTE_N_FRONT 19
+#define SILKSCREEN_N_BACK 20
+#define SILKSCREEN_N_FRONT 21
+#define SOLDERMASK_N_BACK 22
+#define SOLDERMASK_N_FRONT 23
+#define DRAW_N 24
+#define COMMENT_N 25
+#define ECO1_N 26
+#define ECO2_N 27
+#define EDGE_N 28
+#define LAST_NON_COPPER_LAYER 28
+
+// Masks to identify a layer by a bit map
+typedef unsigned LAYER_MSK;
+#define LAYER_BACK (1 << LAYER_N_BACK) ///< bit mask for copper layer
+#define LAYER_2 (1 << LAYER_N_2) ///< bit mask for layer 2
+#define LAYER_3 (1 << LAYER_N_3) ///< bit mask for layer 3
+#define LAYER_4 (1 << LAYER_N_4) ///< bit mask for layer 4
+#define LAYER_5 (1 << LAYER_N_5) ///< bit mask for layer 5
+#define LAYER_6 (1 << LAYER_N_6) ///< bit mask for layer 6
+#define LAYER_7 (1 << LAYER_N_7) ///< bit mask for layer 7
+#define LAYER_8 (1 << LAYER_N_8) ///< bit mask for layer 8
+#define LAYER_9 (1 << LAYER_N_9) ///< bit mask for layer 9
+#define LAYER_10 (1 << LAYER_N_10) ///< bit mask for layer 10
+#define LAYER_11 (1 << LAYER_N_11) ///< bit mask for layer 11
+#define LAYER_12 (1 << LAYER_N_12) ///< bit mask for layer 12
+#define LAYER_13 (1 << LAYER_N_13) ///< bit mask for layer 13
+#define LAYER_14 (1 << LAYER_N_14) ///< bit mask for layer 14
+#define LAYER_15 (1 << LAYER_N_15) ///< bit mask for layer 15
+#define LAYER_FRONT (1 << LAYER_N_FRONT) ///< bit mask for component layer
+#define ADHESIVE_LAYER_BACK (1 << ADHESIVE_N_BACK)
+#define ADHESIVE_LAYER_FRONT (1 << ADHESIVE_N_FRONT)
+#define SOLDERPASTE_LAYER_BACK (1 << SOLDERPASTE_N_BACK)
+#define SOLDERPASTE_LAYER_FRONT (1 << SOLDERPASTE_N_FRONT)
+#define SILKSCREEN_LAYER_BACK (1 << SILKSCREEN_N_BACK)
+#define SILKSCREEN_LAYER_FRONT (1 << SILKSCREEN_N_FRONT)
+#define SOLDERMASK_LAYER_BACK (1 << SOLDERMASK_N_BACK)
+#define SOLDERMASK_LAYER_FRONT (1 << SOLDERMASK_N_FRONT)
+#define DRAW_LAYER (1 << DRAW_N)
+#define COMMENT_LAYER (1 << COMMENT_N)
+#define ECO1_LAYER (1 << ECO1_N)
+#define ECO2_LAYER (1 << ECO2_N)
+#define EDGE_LAYER (1 << EDGE_N)
+
+// Helpful global layer masks:
+// ALL_AUX_LAYERS layers are technical layers, ALL_NO_CU_LAYERS has user
+// and edge layers too!
+#define ALL_NO_CU_LAYERS 0x1FFF0000
+#define ALL_CU_LAYERS 0x0000FFFF
+#define FRONT_TECH_LAYERS (SILKSCREEN_LAYER_FRONT | SOLDERMASK_LAYER_FRONT \
+ | ADHESIVE_LAYER_FRONT | SOLDERPASTE_LAYER_FRONT)
+#define BACK_TECH_LAYERS (SILKSCREEN_LAYER_BACK | SOLDERMASK_LAYER_BACK \
+ | ADHESIVE_LAYER_BACK | SOLDERPASTE_LAYER_BACK)
+#define ALL_TECH_LAYERS (FRONT_TECH_LAYERS | BACK_TECH_LAYERS)
+#define BACK_LAYERS (LAYER_BACK | BACK_TECH_LAYERS)
+#define FRONT_LAYERS (LAYER_FRONT | FRONT_TECH_LAYERS)
+
+#define ALL_USER_LAYERS (DRAW_LAYER | COMMENT_LAYER | ECO1_LAYER | ECO2_LAYER )
+
+#define NO_LAYERS 0x00000000
+
+
+// Old internal units definition (UI = decimil)
+#define PCB_LEGACY_INTERNAL_UNIT 10000
+
+/// Get the length of a string constant, at compile time
+#define SZ( x ) (sizeof(x)-1)
+
+
+static const char delims[] = " \t\r\n";
+
+
+static bool inline isSpace( int c ) { return strchr( delims, c ) != 0; }
+
+#define MASK(x) (1<<(x))
+
+//-----<BOARD Load Functions>---------------------------------------------------
+
+/// C string compare test for a specific length of characters.
+#define TESTLINE( x ) ( !strnicmp( line, x, SZ( x ) ) && isSpace( line[SZ( x )] ) )
+
+/// C sub-string compare test for a specific length of characters.
+#define TESTSUBSTR( x ) ( !strnicmp( line, x, SZ( x ) ) )
+
+
+#if 1
+#define READLINE( rdr ) rdr->ReadLine()
+
+#else
+/// The function and macro which follow comprise a shim which can be a
+/// monitor on lines of text read in from the input file.
+/// And it can be used as a trap.
+static inline char* ReadLine( LINE_READER* rdr, const char* caller )
+{
+ char* ret = rdr->ReadLine();
+
+ const char* line = rdr->Line();
+ printf( "%-6u %s: %s", rdr->LineNumber(), caller, line );
+
+#if 0 // trap
+ if( !strcmp( "loadSETUP", caller ) && !strcmp( "$EndSETUP\n", line ) )
+ {
+ int breakhere = 1;
+ }
+#endif
+
+ return ret;
+}
+#define READLINE( rdr ) ReadLine( rdr, __FUNCTION__ )
+#endif
+
+
+
+using namespace std; // auto_ptr
+
+
+static inline const char* ShowVertJustify( EDA_TEXT_VJUSTIFY_T vertical )
+{
+ const char* rs;
+ switch( vertical )
+ {
+ case GR_TEXT_VJUSTIFY_TOP: rs = "T"; break;
+ case GR_TEXT_VJUSTIFY_CENTER: rs = "C"; break;
+ case GR_TEXT_VJUSTIFY_BOTTOM: rs = "B"; break;
+ default: rs = "?"; break;
+ }
+ return rs;
+}
+
+static inline const char* ShowHorizJustify( EDA_TEXT_HJUSTIFY_T horizontal )
+{
+ const char* rs;
+ switch( horizontal )
+ {
+ case GR_TEXT_HJUSTIFY_LEFT: rs = "L"; break;
+ case GR_TEXT_HJUSTIFY_CENTER: rs = "C"; break;
+ case GR_TEXT_HJUSTIFY_RIGHT: rs = "R"; break;
+ default: rs = "?"; break;
+ }
+ return rs;
+}
+
+static EDA_TEXT_HJUSTIFY_T horizJustify( const char* horizontal )
+{
+ if( !strcmp( "L", horizontal ) )
+ return GR_TEXT_HJUSTIFY_LEFT;
+ if( !strcmp( "R", horizontal ) )
+ return GR_TEXT_HJUSTIFY_RIGHT;
+ return GR_TEXT_HJUSTIFY_CENTER;
+}
+
+static EDA_TEXT_VJUSTIFY_T vertJustify( const char* vertical )
+{
+ if( !strcmp( "T", vertical ) )
+ return GR_TEXT_VJUSTIFY_TOP;
+ if( !strcmp( "B", vertical ) )
+ return GR_TEXT_VJUSTIFY_BOTTOM;
+ return GR_TEXT_VJUSTIFY_CENTER;
+}
+
+
+/// Count the number of set layers in the mask
+inline int layerMaskCountSet( LEG_MASK aMask )
+{
+ int count = 0;
+
+ for( int i = 0; aMask; ++i, aMask >>= 1 )
+ {
+ if( aMask & 1 )
+ ++count;
+ }
+
+ return count;
+}
+
+
+// return true if aLegacyLayerNum is a valid copper layer legacy id, therefore
+// top, bottom or inner activated layer
+inline bool is_leg_copperlayer_valid( int aCu_Count, LAYER_NUM aLegacyLayerNum )
+{
+ return ( aLegacyLayerNum == LAYER_N_FRONT ) || ( aLegacyLayerNum < aCu_Count );
+}
+
+
+LAYER_ID LEGACY_PLUGIN::leg_layer2new( int cu_count, LAYER_NUM aLayerNum )
+{
+ int newid;
+ unsigned old = aLayerNum;
+
+ // this is a speed critical function, be careful.
+
+ if( unsigned( old ) <= unsigned( LAYER_N_FRONT ) )
+ {
+ if( old == LAYER_N_FRONT )
+ newid = F_Cu;
+ else if( old == LAYER_N_BACK )
+ newid = B_Cu;
+ else
+ {
+ newid = cu_count - 1 - old;
+ wxASSERT( newid >= 0 );
+ }
+ }
+ else
+ {
+ switch( old )
+ {
+ case ADHESIVE_N_BACK: newid = B_Adhes; break;
+ case ADHESIVE_N_FRONT: newid = F_Adhes; break;
+ case SOLDERPASTE_N_BACK: newid = B_Paste; break;
+ case SOLDERPASTE_N_FRONT: newid = F_Paste; break;
+ case SILKSCREEN_N_BACK: newid = B_SilkS; break;
+ case SILKSCREEN_N_FRONT: newid = F_SilkS; break;
+ case SOLDERMASK_N_BACK: newid = B_Mask; break;
+ case SOLDERMASK_N_FRONT: newid = F_Mask; break;
+ case DRAW_N: newid = Dwgs_User; break;
+ case COMMENT_N: newid = Cmts_User; break;
+ case ECO1_N: newid = Eco1_User; break;
+ case ECO2_N: newid = Eco2_User; break;
+ case EDGE_N: newid = Edge_Cuts; break;
+ default:
+// wxASSERT( 0 );
+ // Remap all illegal non copper layers to comment layer
+ newid = Cmts_User;
+ }
+ }
+
+ return LAYER_ID( newid );
+}
+
+
+LSET LEGACY_PLUGIN::leg_mask2new( int cu_count, unsigned aMask )
+{
+ LSET ret;
+
+ if( ( aMask & ALL_CU_LAYERS ) == ALL_CU_LAYERS )
+ {
+ ret = LSET::AllCuMask();
+
+ aMask &= ~ALL_CU_LAYERS;
+ }
+
+ for( int i=0; aMask; ++i, aMask >>= 1 )
+ {
+ if( aMask & 1 )
+ ret.set( leg_layer2new( cu_count, i ) );
+ }
+
+ return ret;
+}
+
+
+/**
+ * Function intParse
+ * parses an ASCII integer string with possible leading whitespace into
+ * an integer and updates the pointer at \a out if it is not NULL, just
+ * like "man strtol()". I can use this without casting, and its name says
+ * what I am doing.
+ */
+static inline int intParse( const char* next, const char** out = NULL )
+{
+ // please just compile this and be quiet, hide casting ugliness:
+ return (int) strtol( next, (char**) out, 10 );
+}
+
+/**
+ * Function layerParse
+ * Like intParse but returns a LAYER_NUM
+ */
+static inline LAYER_NUM layerParse( const char* next, const char** out = NULL )
+{
+ return intParse( next, out );
+}
+
+/**
+ * Function hexParse
+ * parses an ASCII hex integer string with possible leading whitespace into
+ * a long integer and updates the pointer at \a out if it is not NULL, just
+ * like "man strtol". I can use this without casting, and its name says
+ * what I am doing.
+ */
+static inline long hexParse( const char* next, const char** out = NULL )
+{
+ // please just compile this and be quiet, hide casting ugliness:
+ return strtol( next, (char**) out, 16 );
+}
+
+
+BOARD* LEGACY_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe,
+ const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ init( aProperties );
+
+ m_board = aAppendToMe ? aAppendToMe : new BOARD();
+
+ // Give the filename to the board if it's new
+ if( !aAppendToMe )
+ m_board->SetFileName( aFileName );
+
+ // delete on exception, iff I own m_board, according to aAppendToMe
+ auto_ptr<BOARD> deleter( aAppendToMe ? NULL : m_board );
+
+ FILE_LINE_READER reader( aFileName );
+
+ m_reader = &reader; // member function accessibility
+
+ checkVersion();
+
+ loadAllSections( bool( aAppendToMe ) );
+
+ deleter.release();
+ return m_board;
+}
+
+
+void LEGACY_PLUGIN::loadAllSections( bool doAppend )
+{
+ // $GENERAL section is first
+
+ // $SHEETDESCR section is next
+
+ // $SETUP section is next
+
+ // Then follows $EQUIPOT and all the rest
+ char* line;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ // put the more frequent ones at the top, but realize TRACKs are loaded as a group
+
+ if( TESTLINE( "$MODULE" ) )
+ {
+ auto_ptr<MODULE> module( new MODULE( m_board ) );
+
+ FPID fpid;
+ std::string fpName = StrPurge( line + SZ( "$MODULE" ) );
+
+ // The footprint names in legacy libraries can contain the '/' and ':'
+ // characters which will cause the FPID parser to choke.
+ ReplaceIllegalFileNameChars( &fpName );
+
+ if( !fpName.empty() )
+ fpid = FPID( fpName );
+
+ module->SetFPID( fpid );
+
+ loadMODULE( module.get() );
+ m_board->Add( module.release(), ADD_APPEND );
+ }
+
+ else if( TESTLINE( "$DRAWSEGMENT" ) )
+ {
+ loadPCB_LINE();
+ }
+
+ else if( TESTLINE( "$EQUIPOT" ) )
+ {
+ loadNETINFO_ITEM();
+ }
+
+ else if( TESTLINE( "$TEXTPCB" ) )
+ {
+ loadPCB_TEXT();
+ }
+
+ else if( TESTLINE( "$TRACK" ) )
+ {
+ loadTrackList( PCB_TRACE_T );
+ }
+
+ else if( TESTLINE( "$NCLASS" ) )
+ {
+ loadNETCLASS();
+ }
+
+ else if( TESTLINE( "$CZONE_OUTLINE" ) )
+ {
+ loadZONE_CONTAINER();
+ }
+
+ else if( TESTLINE( "$COTATION" ) )
+ {
+ loadDIMENSION();
+ }
+
+ else if( TESTLINE( "$PCB_TARGET" ) || TESTLINE( "$MIREPCB" ) )
+ {
+ loadPCB_TARGET();
+ }
+
+ else if( TESTLINE( "$ZONE" ) )
+ {
+ loadTrackList( PCB_ZONE_T );
+ }
+
+ else if( TESTLINE( "$GENERAL" ) )
+ {
+ loadGENERAL();
+ }
+
+ else if( TESTLINE( "$SHEETDESCR" ) )
+ {
+ loadSHEET();
+ }
+
+ else if( TESTLINE( "$SETUP" ) )
+ {
+ if( !doAppend )
+ {
+ loadSETUP();
+ }
+ else
+ {
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ // gobble until $EndSetup
+ if( TESTLINE( "$EndSETUP" ) )
+ break;
+ }
+ }
+ }
+
+ else if( TESTLINE( "$EndBOARD" ) )
+ return; // preferred exit
+ }
+
+ THROW_IO_ERROR( "Missing '$EndBOARD'" );
+}
+
+
+void LEGACY_PLUGIN::checkVersion()
+{
+ // Read first line and TEST if it is a PCB file format header like this:
+ // "PCBNEW-BOARD Version 1 ...."
+
+ m_reader->ReadLine();
+
+ char* line = m_reader->Line();
+
+ if( !TESTLINE( "PCBNEW-BOARD" ) )
+ {
+ THROW_IO_ERROR( "Unknown file type" );
+ }
+
+ int ver = 1; // if sccanf fails
+ sscanf( line, "PCBNEW-BOARD Version %d", &ver );
+
+#if !defined(DEBUG)
+ if( ver > LEGACY_BOARD_FILE_VERSION )
+ {
+ // "File '%s' is format version: %d.\nI only support format version <= %d.\nPlease upgrade Pcbnew to load this file."
+ m_error.Printf( VERSION_ERROR_FORMAT,
+ m_reader->GetSource().GetData(), ver, LEGACY_BOARD_FILE_VERSION );
+ THROW_IO_ERROR( m_error );
+ }
+#endif
+
+ m_loading_format_version = ver;
+ m_board->SetFileFormatVersionAtLoad( m_loading_format_version );
+}
+
+
+void LEGACY_PLUGIN::loadGENERAL()
+{
+ char* line;
+ char* saveptr;
+ bool saw_LayerCount = false;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ const char* data;
+
+ if( TESTLINE( "Units" ) )
+ {
+ // what are the engineering units of the lengths in the BOARD?
+ data = strtok_r( line + SZ("Units"), delims, &saveptr );
+
+ if( !strcmp( data, "mm" ) )
+ {
+ diskToBiu = IU_PER_MM;
+ }
+ }
+
+ else if( TESTLINE( "LayerCount" ) )
+ {
+ int tmp = intParse( line + SZ( "LayerCount" ) );
+ m_board->SetCopperLayerCount( tmp );
+
+ // This has to be set early so that leg_layer2new() works OK, and
+ // that means before parsing "EnabledLayers" and "VisibleLayers".
+ m_cu_count = tmp;
+
+ saw_LayerCount = true;
+ }
+
+ else if( TESTLINE( "EnabledLayers" ) )
+ {
+ if( !saw_LayerCount )
+ THROW_IO_ERROR( "Missing '$GENERAL's LayerCount" );
+
+ LEG_MASK enabledLayers = hexParse( line + SZ( "EnabledLayers" ) );
+
+ LSET new_mask = leg_mask2new( m_cu_count, enabledLayers );
+
+ //DBG( printf( "EnabledLayers: %s\n", new_mask.FmtHex().c_str() );)
+
+ m_board->SetEnabledLayers( new_mask );
+
+ // layer visibility equals layer usage, unless overridden later via "VisibleLayers"
+ // Must call SetEnabledLayers() before calling SetVisibleLayers().
+ m_board->SetVisibleLayers( new_mask );
+ }
+
+ else if( TESTLINE( "VisibleLayers" ) )
+ {
+ if( !saw_LayerCount )
+ THROW_IO_ERROR( "Missing '$GENERAL's LayerCount" );
+
+ LEG_MASK visibleLayers = hexParse( line + SZ( "VisibleLayers" ) );
+
+ LSET new_mask = leg_mask2new( m_cu_count, visibleLayers );
+
+ m_board->SetVisibleLayers( new_mask );
+ }
+
+ else if( TESTLINE( "Ly" ) ) // Old format for Layer count
+ {
+ if( !saw_LayerCount )
+ {
+ LEG_MASK layer_mask = hexParse( line + SZ( "Ly" ) );
+
+ m_cu_count = layerMaskCountSet( layer_mask & ALL_CU_LAYERS );
+
+ m_board->SetCopperLayerCount( m_cu_count );
+
+ saw_LayerCount = true;
+ }
+ }
+
+ else if( TESTLINE( "BoardThickness" ) )
+ {
+ BIU thickn = biuParse( line + SZ( "BoardThickness" ) );
+ m_board->GetDesignSettings().SetBoardThickness( thickn );
+ }
+
+ /*
+ else if( TESTLINE( "Links" ) )
+ {
+ // Info only, do nothing, but only for a short while.
+ }
+ */
+
+ else if( TESTLINE( "NoConn" ) )
+ {
+ int tmp = intParse( line + SZ( "NoConn" ) );
+ m_board->SetUnconnectedNetCount( tmp );
+ }
+
+ else if( TESTLINE( "Di" ) )
+ {
+ BIU x1 = biuParse( line + SZ( "Di" ), &data );
+ BIU y1 = biuParse( data, &data );
+ BIU x2 = biuParse( data, &data );
+ BIU y2 = biuParse( data );
+
+ EDA_RECT bbbox( wxPoint( x1, y1 ), wxSize( x2-x1, y2-y1 ) );
+
+ m_board->SetBoundingBox( bbbox );
+ }
+
+ /* This is no more usefull, so this info is no more parsed
+ // Read the number of segments of type DRAW, TRACK, ZONE
+ else if( TESTLINE( "Ndraw" ) )
+ {
+ NbDraw = intParse( line + SZ( "Ndraw" ) );
+ }
+
+ else if( TESTLINE( "Ntrack" ) )
+ {
+ NbTrack = intParse( line + SZ( "Ntrack" ) );
+ }
+
+ else if( TESTLINE( "Nzone" ) )
+ {
+ NbZone = intParse( line + SZ( "Nzone" ) );
+ }
+
+ else if( TESTLINE( "Nmodule" ) )
+ {
+ NbMod = intParse( line + SZ( "Nmodule" ) );
+ }*/
+
+ else if( TESTLINE( "Nnets" ) )
+ {
+ m_netCodes.resize( intParse( line + SZ( "Nnets" ) ) );
+ }
+
+ else if( TESTLINE( "Nn" ) ) // id "Nnets" for old .brd files
+ {
+ m_netCodes.resize( intParse( line + SZ( "Nn" ) ) );
+ }
+
+ else if( TESTLINE( "$EndGENERAL" ) )
+ return; // preferred exit
+ }
+
+ THROW_IO_ERROR( "Missing '$EndGENERAL'" );
+}
+
+
+void LEGACY_PLUGIN::loadSHEET()
+{
+ char buf[260];
+ TITLE_BLOCK tb;
+ char* line;
+ char* saveptr;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ if( TESTLINE( "Sheet" ) )
+ {
+ // e.g. "Sheet A3 16535 11700"
+ // width and height are in 1/1000th of an inch, always
+
+ PAGE_INFO page;
+ char* sname = strtok_r( line + SZ( "Sheet" ), delims, &saveptr );
+
+ if( sname )
+ {
+ wxString wname = FROM_UTF8( sname );
+ if( !page.SetType( wname ) )
+ {
+ m_error.Printf( _( "Unknown sheet type '%s' on line:%d" ),
+ wname.GetData(), m_reader->LineNumber() );
+ THROW_IO_ERROR( m_error );
+ }
+
+ char* width = strtok_r( NULL, delims, &saveptr );
+ char* height = strtok_r( NULL, delims, &saveptr );
+ char* orient = strtok_r( NULL, delims, &saveptr );
+
+ // only parse the width and height if page size is custom ("User")
+ if( wname == PAGE_INFO::Custom )
+ {
+ if( width && height )
+ {
+ // legacy disk file describes paper in mils
+ // (1/1000th of an inch)
+ int w = intParse( width );
+ int h = intParse( height );
+
+ page.SetWidthMils( w );
+ page.SetHeightMils( h );
+ }
+ }
+
+ if( orient && !strcmp( orient, "portrait" ) )
+ {
+ page.SetPortrait( true );
+ }
+
+ m_board->SetPageSettings( page );
+ }
+ }
+
+ else if( TESTLINE( "Title" ) )
+ {
+ ReadDelimitedText( buf, line, sizeof(buf) );
+ tb.SetTitle( FROM_UTF8( buf ) );
+ }
+
+ else if( TESTLINE( "Date" ) )
+ {
+ ReadDelimitedText( buf, line, sizeof(buf) );
+ tb.SetDate( FROM_UTF8( buf ) );
+ }
+
+ else if( TESTLINE( "Rev" ) )
+ {
+ ReadDelimitedText( buf, line, sizeof(buf) );
+ tb.SetRevision( FROM_UTF8( buf ) );
+ }
+
+ else if( TESTLINE( "Comp" ) )
+ {
+ ReadDelimitedText( buf, line, sizeof(buf) );
+ tb.SetCompany( FROM_UTF8( buf ) );
+ }
+
+ else if( TESTLINE( "Comment1" ) )
+ {
+ ReadDelimitedText( buf, line, sizeof(buf) );
+ tb.SetComment1( FROM_UTF8( buf ) );
+ }
+
+ else if( TESTLINE( "Comment2" ) )
+ {
+ ReadDelimitedText( buf, line, sizeof(buf) );
+ tb.SetComment2( FROM_UTF8( buf ) );
+ }
+
+ else if( TESTLINE( "Comment3" ) )
+ {
+ ReadDelimitedText( buf, line, sizeof(buf) );
+ tb.SetComment3( FROM_UTF8( buf ) );
+ }
+
+ else if( TESTLINE( "Comment4" ) )
+ {
+ ReadDelimitedText( buf, line, sizeof(buf) );
+ tb.SetComment4( FROM_UTF8( buf ) );
+ }
+
+ else if( TESTLINE( "$EndSHEETDESCR" ) )
+ {
+ m_board->SetTitleBlock( tb );
+ return; // preferred exit
+ }
+ }
+
+ THROW_IO_ERROR( "Missing '$EndSHEETDESCR'" );
+}
+
+
+void LEGACY_PLUGIN::loadSETUP()
+{
+ NETCLASSPTR netclass_default = m_board->GetDesignSettings().GetDefault();
+ // TODO Orson: is it really necessary to first operate on a copy and then apply it?
+ // would not it be better to use reference here and apply all the changes instantly?
+ BOARD_DESIGN_SETTINGS bds = m_board->GetDesignSettings();
+ ZONE_SETTINGS zs = m_board->GetZoneSettings();
+ char* line;
+ char* saveptr;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ const char* data;
+
+ if( TESTLINE( "PcbPlotParams" ) )
+ {
+ PCB_PLOT_PARAMS plot_opts;
+
+ PCB_PLOT_PARAMS_PARSER parser( line + SZ( "PcbPlotParams" ), m_reader->GetSource() );
+
+ plot_opts.Parse( &parser );
+
+ m_board->SetPlotOptions( plot_opts );
+ }
+
+ else if( TESTLINE( "AuxiliaryAxisOrg" ) )
+ {
+ BIU gx = biuParse( line + SZ( "AuxiliaryAxisOrg" ), &data );
+ BIU gy = biuParse( data );
+
+ // m_board->SetAuxOrigin( wxPoint( gx, gy ) ); gets overwritten by SetDesignSettings() below
+ bds.m_AuxOrigin = wxPoint( gx, gy );
+ }
+
+ /* Done from $General above's "LayerCount"
+ else if( TESTLINE( "Layers" ) )
+ {
+ int tmp = intParse( line + SZ( "Layers" ) );
+ m_board->SetCopperLayerCount( tmp );
+
+ m_cu_count = tmp;
+ }
+ */
+
+ else if( TESTSUBSTR( "Layer[" ) )
+ {
+ // eg: "Layer[n] <a_Layer_name_with_no_spaces> <LAYER_T>"
+
+ LAYER_NUM layer_num = layerParse( line + SZ( "Layer[" ), &data );
+ LAYER_ID layer_id = leg_layer2new( m_cu_count, layer_num );
+
+ /*
+ switch( layer_num )
+ {
+ case LAYER_N_BACK:
+ layer_id = B_Cu;
+ break;
+
+ case LAYER_N_FRONT:
+ layer_id = F_Cu;
+ break;
+
+ default:
+ layer_id = LAYER_ID( layer_num );
+ }
+ */
+
+ data = strtok_r( (char*) data+1, delims, &saveptr ); // +1 for ']'
+ if( data )
+ {
+ wxString layerName = FROM_UTF8( data );
+ m_board->SetLayerName( layer_id, layerName );
+
+ data = strtok_r( NULL, delims, &saveptr );
+ if( data ) // optional in old board files
+ {
+ LAYER_T type = LAYER::ParseType( data );
+ m_board->SetLayerType( layer_id, type );
+ }
+ }
+ }
+
+ else if( TESTLINE( "TrackWidth" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "TrackWidth" ) );
+ netclass_default->SetTrackWidth( tmp );
+ }
+
+ else if( TESTLINE( "TrackWidthList" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "TrackWidthList" ) );
+ bds.m_TrackWidthList.push_back( tmp );
+ }
+
+ else if( TESTLINE( "TrackClearence" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "TrackClearence" ) );
+ netclass_default->SetClearance( tmp );
+ }
+
+ else if( TESTLINE( "TrackMinWidth" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "TrackMinWidth" ) );
+ bds.m_TrackMinWidth = tmp;
+ }
+
+ else if( TESTLINE( "ZoneClearence" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "ZoneClearence" ) );
+ zs.m_ZoneClearance = tmp;
+ }
+
+ else if( TESTLINE( "Zone_45_Only" ) )
+ {
+ bool tmp = (bool) intParse( line + SZ( "Zone_45_Only" ) );
+ zs.m_Zone_45_Only = tmp;
+ }
+
+ else if( TESTLINE( "DrawSegmWidth" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "DrawSegmWidth" ) );
+ bds.m_DrawSegmentWidth = tmp;
+ }
+
+ else if( TESTLINE( "EdgeSegmWidth" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "EdgeSegmWidth" ) );
+ bds.m_EdgeSegmentWidth = tmp;
+ }
+
+ else if( TESTLINE( "ViaMinSize" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "ViaMinSize" ) );
+ bds.m_ViasMinSize = tmp;
+ }
+
+ else if( TESTLINE( "MicroViaMinSize" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "MicroViaMinSize" ) );
+ bds.m_MicroViasMinSize = tmp;
+ }
+
+ else if( TESTLINE( "ViaSizeList" ) )
+ {
+ // e.g. "ViaSizeList DIAMETER [DRILL]"
+
+ BIU drill = 0;
+ BIU diameter = biuParse( line + SZ( "ViaSizeList" ), &data );
+
+ data = strtok_r( (char*) data, delims, &saveptr );
+ if( data ) // DRILL may not be present ?
+ drill = biuParse( data );
+
+ bds.m_ViasDimensionsList.push_back( VIA_DIMENSION( diameter,
+ drill ) );
+ }
+
+ else if( TESTLINE( "ViaSize" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "ViaSize" ) );
+ netclass_default->SetViaDiameter( tmp );
+ }
+
+ else if( TESTLINE( "ViaDrill" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "ViaDrill" ) );
+ netclass_default->SetViaDrill( tmp );
+ }
+
+ else if( TESTLINE( "ViaMinDrill" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "ViaMinDrill" ) );
+ bds.m_ViasMinDrill = tmp;
+ }
+
+ else if( TESTLINE( "MicroViaSize" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "MicroViaSize" ) );
+ netclass_default->SetuViaDiameter( tmp );
+ }
+
+ else if( TESTLINE( "MicroViaDrill" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "MicroViaDrill" ) );
+ netclass_default->SetuViaDrill( tmp );
+ }
+
+ else if( TESTLINE( "MicroViaMinDrill" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "MicroViaMinDrill" ) );
+ bds.m_MicroViasMinDrill = tmp;
+ }
+
+ else if( TESTLINE( "MicroViasAllowed" ) )
+ {
+ int tmp = intParse( line + SZ( "MicroViasAllowed" ) );
+ bds.m_MicroViasAllowed = tmp;
+ }
+
+ else if( TESTLINE( "TextPcbWidth" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "TextPcbWidth" ) );
+ bds.m_PcbTextWidth = tmp;
+ }
+
+ else if( TESTLINE( "TextPcbSize" ) )
+ {
+ BIU x = biuParse( line + SZ( "TextPcbSize" ), &data );
+ BIU y = biuParse( data );
+
+ bds.m_PcbTextSize = wxSize( x, y );
+ }
+
+ else if( TESTLINE( "EdgeModWidth" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "EdgeModWidth" ) );
+ bds.m_ModuleSegmentWidth = tmp;
+ }
+
+ else if( TESTLINE( "TextModWidth" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "TextModWidth" ) );
+ bds.m_ModuleTextWidth = tmp;
+ }
+
+ else if( TESTLINE( "TextModSize" ) )
+ {
+ BIU x = biuParse( line + SZ( "TextModSize" ), &data );
+ BIU y = biuParse( data );
+
+ bds.m_ModuleTextSize = wxSize( x, y );
+ }
+
+ else if( TESTLINE( "PadSize" ) )
+ {
+ BIU x = biuParse( line + SZ( "PadSize" ), &data );
+ BIU y = biuParse( data );
+
+ bds.m_Pad_Master.SetSize( wxSize( x, y ) );
+ }
+
+ else if( TESTLINE( "PadDrill" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "PadDrill" ) );
+ bds.m_Pad_Master.SetDrillSize( wxSize( tmp, tmp ) );
+ }
+
+ else if( TESTLINE( "Pad2MaskClearance" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "Pad2MaskClearance" ) );
+ bds.m_SolderMaskMargin = tmp;
+ }
+
+ else if( TESTLINE( "SolderMaskMinWidth" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "SolderMaskMinWidth" ) );
+ bds.m_SolderMaskMinWidth = tmp;
+ }
+
+ else if( TESTLINE( "Pad2PasteClearance" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "Pad2PasteClearance" ) );
+ bds.m_SolderPasteMargin = tmp;
+ }
+
+ else if( TESTLINE( "Pad2PasteClearanceRatio" ) )
+ {
+ double ratio = atof( line + SZ( "Pad2PasteClearanceRatio" ) );
+ bds.m_SolderPasteMarginRatio = ratio;
+ }
+
+ else if( TESTLINE( "GridOrigin" ) )
+ {
+ BIU x = biuParse( line + SZ( "GridOrigin" ), &data );
+ BIU y = biuParse( data );
+
+ // m_board->SetGridOrigin( wxPoint( x, y ) ); gets overwritten by SetDesignSettings() below
+ bds.m_GridOrigin = wxPoint( x, y );
+ }
+
+ else if( TESTLINE( "VisibleElements" ) )
+ {
+ int visibleElements = hexParse( line + SZ( "VisibleElements" ) );
+ bds.SetVisibleElements( visibleElements );
+ }
+
+ else if( TESTLINE( "$EndSETUP" ) )
+ {
+ m_board->SetDesignSettings( bds );
+ m_board->SetZoneSettings( zs );
+
+ // Very old *.brd file does not have NETCLASSes
+ // "TrackWidth", "ViaSize", "ViaDrill", "ViaMinSize",
+ // and "TrackClearence", were defined in SETUP
+ // these values are put into the default NETCLASS until later board load
+ // code should override them. *.brd files which have been
+ // saved with knowledge of NETCLASSes will override these
+ // defaults, very old boards (before 2009) will not and use the setup values.
+ // However these values should be the same as default NETCLASS.
+
+ return; // preferred exit
+ }
+ }
+
+ // @todo: this code is currently unreachable, would need a goto, to get here.
+ // that may be better handled with an #ifdef
+
+ /* Ensure tracks and vias sizes lists are ok:
+ * Sort lists by by increasing value and remove duplicates
+ * (the first value is not tested, because it is the netclass value
+ */
+ BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
+ sort( designSettings.m_ViasDimensionsList.begin() + 1, designSettings.m_ViasDimensionsList.end() );
+ sort( designSettings.m_TrackWidthList.begin() + 1, designSettings.m_TrackWidthList.end() );
+
+ for( unsigned ii = 1; ii < designSettings.m_ViasDimensionsList.size() - 1; ii++ )
+ {
+ if( designSettings.m_ViasDimensionsList[ii] == designSettings.m_ViasDimensionsList[ii + 1] )
+ {
+ designSettings.m_ViasDimensionsList.erase( designSettings.m_ViasDimensionsList.begin() + ii );
+ ii--;
+ }
+ }
+
+ for( unsigned ii = 1; ii < designSettings.m_TrackWidthList.size() - 1; ii++ )
+ {
+ if( designSettings.m_TrackWidthList[ii] == designSettings.m_TrackWidthList[ii + 1] )
+ {
+ designSettings.m_TrackWidthList.erase( designSettings.m_TrackWidthList.begin() + ii );
+ ii--;
+ }
+ }
+}
+
+
+void LEGACY_PLUGIN::loadMODULE( MODULE* aModule )
+{
+ char* line;
+ char* saveptr;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ const char* data;
+
+ // most frequently encountered ones at the top
+
+ if( TESTSUBSTR( "D" ) && strchr( "SCAP", line[1] ) ) // read a drawing item, e.g. "DS"
+ {
+ loadMODULE_EDGE( aModule );
+ }
+
+ else if( TESTLINE( "$PAD" ) )
+ {
+ loadPAD( aModule );
+ }
+
+ // Read a footprint text description (ref, value, or drawing)
+ else if( TESTSUBSTR( "T" ) )
+ {
+ // e.g. "T1 6940 -16220 350 300 900 60 M I 20 N "CFCARD"\r\n"
+
+ int tnum = intParse( line + SZ( "T" ) );
+
+ TEXTE_MODULE* textm = 0;
+
+ switch( tnum )
+ {
+ case TEXTE_MODULE::TEXT_is_REFERENCE:
+ textm = &aModule->Reference();
+ break;
+
+ case TEXTE_MODULE::TEXT_is_VALUE:
+ textm = &aModule->Value();
+ break;
+
+ // All other fields greater than 1.
+ default:
+ textm = new TEXTE_MODULE( aModule );
+ aModule->GraphicalItems().PushBack( textm );
+ }
+
+ loadMODULE_TEXT( textm );
+ }
+
+ else if( TESTLINE( "Po" ) )
+ {
+ // e.g. "Po 19120 39260 900 0 4E823D06 46EAAFA5 ~~\r\n"
+
+ // sscanf( PtLine, "%d %d %d %d %lX %lX %s", &m_Pos.x, &m_Pos.y, &m_Orient, &m_Layer, &m_LastEdit_Time, &m_TimeStamp, BufCar1 );
+
+ BIU pos_x = biuParse( line + SZ( "Po" ), &data );
+ BIU pos_y = biuParse( data, &data );
+ int orient = intParse( data, &data );
+
+ LAYER_NUM layer_num = layerParse( data, &data );
+ LAYER_ID layer_id = leg_layer2new( m_cu_count, layer_num );
+
+ long edittime = hexParse( data, &data );
+ time_t timestamp = hexParse( data, &data );
+
+ data = strtok_r( (char*) data+1, delims, &saveptr );
+
+ // data is now a two character long string
+ // Note: some old files do not have this field
+ if( data && data[0] == 'F' )
+ aModule->SetLocked( true );
+
+ if( data && data[1] == 'P' )
+ aModule->SetIsPlaced( true );
+
+ aModule->SetPosition( wxPoint( pos_x, pos_y ) );
+ aModule->SetLayer( layer_id );
+ aModule->SetOrientation( orient );
+ aModule->SetTimeStamp( timestamp );
+ aModule->SetLastEditTime( edittime );
+ }
+
+ /* footprint name set earlier, immediately after MODULE construction
+ else if( TESTLINE( "Li" ) ) // Library name of footprint
+ {
+ // There can be whitespace in the footprint name on some old libraries.
+ // Grab everything after "Li" up to end of line:
+ //aModule->SetFPID( FROM_UTF8( StrPurge( line + SZ( "Li" ) ) ) );
+ }
+ */
+
+ else if( TESTLINE( "Sc" ) ) // timestamp
+ {
+ time_t timestamp = hexParse( line + SZ( "Sc" ) );
+ aModule->SetTimeStamp( timestamp );
+ }
+
+ else if( TESTLINE( "Op" ) ) // (Op)tions for auto placement
+ {
+ int itmp1 = hexParse( line + SZ( "Op" ), &data );
+ int itmp2 = hexParse( data );
+
+ int cntRot180 = itmp2 & 0x0F;
+ if( cntRot180 > 10 )
+ cntRot180 = 10;
+
+ aModule->SetPlacementCost180( cntRot180 );
+
+ int cntRot90 = itmp1 & 0x0F;
+ if( cntRot90 > 10 )
+ cntRot90 = 0;
+
+ itmp1 = (itmp1 >> 4) & 0x0F;
+ if( itmp1 > 10 )
+ itmp1 = 0;
+
+ aModule->SetPlacementCost90( (itmp1 << 4) | cntRot90 );
+ }
+
+ else if( TESTLINE( "At" ) ) // (At)tributes of module
+ {
+ int attrs = MOD_DEFAULT;
+
+ data = line + SZ( "At" );
+
+ if( strstr( data, "SMD" ) )
+ attrs |= MOD_CMS;
+
+ if( strstr( data, "VIRTUAL" ) )
+ attrs |= MOD_VIRTUAL;
+
+ aModule->SetAttributes( attrs );
+ }
+
+ else if( TESTLINE( "AR" ) ) // Alternate Reference
+ {
+ // e.g. "AR /47BA2624/45525076"
+ data = strtok_r( line + SZ( "AR" ), delims, &saveptr );
+ if( data )
+ aModule->SetPath( FROM_UTF8( data ) );
+ }
+
+ else if( TESTLINE( "$SHAPE3D" ) )
+ {
+ load3D( aModule );
+ }
+
+ else if( TESTLINE( "Cd" ) )
+ {
+ // e.g. "Cd Double rangee de contacts 2 x 4 pins\r\n"
+ aModule->SetDescription( FROM_UTF8( StrPurge( line + SZ( "Cd" ) ) ) );
+ }
+
+ else if( TESTLINE( "Kw" ) ) // Key words
+ {
+ aModule->SetKeywords( FROM_UTF8( StrPurge( line + SZ( "Kw" ) ) ) );
+ }
+
+ else if( TESTLINE( ".SolderPasteRatio" ) )
+ {
+ double tmp = atof( line + SZ( ".SolderPasteRatio" ) );
+ // Due to a bug in dialog editor in Modedit, fixed in BZR version 3565
+ // this parameter can be broken.
+ // It should be >= -50% (no solder paste) and <= 0% (full area of the pad)
+
+ if( tmp < -0.50 )
+ tmp = -0.50;
+ if( tmp > 0.0 )
+ tmp = 0.0;
+ aModule->SetLocalSolderPasteMarginRatio( tmp );
+ }
+
+ else if( TESTLINE( ".SolderPaste" ) )
+ {
+ BIU tmp = biuParse( line + SZ( ".SolderPaste" ) );
+ aModule->SetLocalSolderPasteMargin( tmp );
+ }
+
+ else if( TESTLINE( ".SolderMask" ) )
+ {
+ BIU tmp = biuParse( line + SZ( ".SolderMask" ) );
+ aModule->SetLocalSolderMaskMargin( tmp );
+ }
+
+ else if( TESTLINE( ".LocalClearance" ) )
+ {
+ BIU tmp = biuParse( line + SZ( ".LocalClearance" ) );
+ aModule->SetLocalClearance( tmp );
+ }
+
+ else if( TESTLINE( ".ZoneConnection" ) )
+ {
+ int tmp = intParse( line + SZ( ".ZoneConnection" ) );
+ aModule->SetZoneConnection( (ZoneConnection)tmp );
+ }
+
+ else if( TESTLINE( ".ThermalWidth" ) )
+ {
+ BIU tmp = biuParse( line + SZ( ".ThermalWidth" ) );
+ aModule->SetThermalWidth( tmp );
+ }
+
+ else if( TESTLINE( ".ThermalGap" ) )
+ {
+ BIU tmp = biuParse( line + SZ( ".ThermalGap" ) );
+ aModule->SetThermalGap( tmp );
+ }
+
+ else if( TESTLINE( "$EndMODULE" ) )
+ {
+ aModule->CalculateBoundingBox();
+
+ return; // preferred exit
+ }
+ }
+
+ wxString msg = wxString::Format(
+ wxT( "Missing '$EndMODULE' for MODULE '%s'" ),
+ GetChars( aModule->GetFPID().GetFootprintName() ) );
+
+ THROW_IO_ERROR( msg );
+}
+
+
+void LEGACY_PLUGIN::loadPAD( MODULE* aModule )
+{
+ auto_ptr<D_PAD> pad( new D_PAD( aModule ) );
+ char* line;
+ char* saveptr;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ const char* data;
+
+ if( TESTLINE( "Sh" ) ) // (Sh)ape and padname
+ {
+ // e.g. "Sh "A2" C 520 520 0 0 900"
+ // or "Sh "1" R 157 1378 0 0 900"
+
+ // mypadname is LATIN1/CRYLIC for BOARD_FORMAT_VERSION 1,
+ // but for BOARD_FORMAT_VERSION 2, it is UTF8 from disk.
+ // So we have to go through two code paths. Moving forward
+ // padnames will be in UTF8 on disk, as are all KiCad strings on disk.
+ char mypadname[50];
+
+ data = line + SZ( "Sh" ) + 1; // +1 skips trailing whitespace
+
+ data = data + ReadDelimitedText( mypadname, data, sizeof(mypadname) ) + 1; // +1 trailing whitespace
+
+ // sscanf( PtLine, " %s %d %d %d %d %d", BufCar, &m_Size.x, &m_Size.y, &m_DeltaSize.x, &m_DeltaSize.y, &m_Orient );
+ while( isSpace( *data ) )
+ ++data;
+
+ unsigned char padchar = (unsigned char) *data++;
+ int padshape;
+
+ BIU size_x = biuParse( data, &data );
+ BIU size_y = biuParse( data, &data );
+ BIU delta_x = biuParse( data, &data );
+ BIU delta_y = biuParse( data, &data );
+ double orient = degParse( data );
+
+ switch( padchar )
+ {
+ case 'C': padshape = PAD_SHAPE_CIRCLE; break;
+ case 'R': padshape = PAD_SHAPE_RECT; break;
+ case 'O': padshape = PAD_SHAPE_OVAL; break;
+ case 'T': padshape = PAD_SHAPE_TRAPEZOID; break;
+ default:
+ m_error.Printf( _( "Unknown padshape '%c=0x%02x' on line: %d of footprint: '%s'" ),
+ padchar,
+ padchar,
+ m_reader->LineNumber(),
+ GetChars( aModule->GetFPID().GetFootprintName() )
+ );
+ THROW_IO_ERROR( m_error );
+ }
+
+ // go through a wxString to establish a universal character set properly
+ wxString padname;
+
+ if( m_loading_format_version == 1 )
+ {
+ // add 8 bit bytes, file format 1 was KiCad font type byte,
+ // simply promote those 8 bit bytes up into UNICODE. (subset of LATIN1)
+ const unsigned char* cp = (unsigned char*) mypadname;
+ while( *cp )
+ {
+ padname += *cp++; // unsigned, ls 8 bits only
+ }
+ }
+ else
+ {
+ // version 2, which is UTF8.
+ padname = FROM_UTF8( mypadname );
+ }
+ // chances are both were ASCII, but why take chances?
+
+ pad->SetPadName( padname );
+ pad->SetShape( PAD_SHAPE_T( padshape ) );
+ pad->SetSize( wxSize( size_x, size_y ) );
+ pad->SetDelta( wxSize( delta_x, delta_y ) );
+ pad->SetOrientation( orient );
+ }
+
+ else if( TESTLINE( "Dr" ) ) // (Dr)ill
+ {
+ // e.g. "Dr 350 0 0" or "Dr 0 0 0 O 0 0"
+ // sscanf( PtLine, "%d %d %d %s %d %d", &m_Drill.x, &m_Offset.x, &m_Offset.y, BufCar, &dx, &dy );
+
+ BIU drill_x = biuParse( line + SZ( "Dr" ), &data );
+ BIU drill_y = drill_x;
+ BIU offs_x = biuParse( data, &data );
+ BIU offs_y = biuParse( data, &data );
+
+ PAD_DRILL_SHAPE_T drShape = PAD_DRILL_SHAPE_CIRCLE;
+
+ data = strtok_r( (char*) data, delims, &saveptr );
+ if( data ) // optional shape
+ {
+ if( data[0] == 'O' )
+ {
+ drShape = PAD_DRILL_SHAPE_OBLONG;
+
+ data = strtok_r( NULL, delims, &saveptr );
+ drill_x = biuParse( data );
+
+ data = strtok_r( NULL, delims, &saveptr );
+ drill_y = biuParse( data );
+ }
+ }
+
+ pad->SetDrillShape( drShape );
+ pad->SetOffset( wxPoint( offs_x, offs_y ) );
+ pad->SetDrillSize( wxSize( drill_x, drill_y ) );
+ }
+
+ else if( TESTLINE( "At" ) ) // (At)tribute
+ {
+ // e.g. "At SMD N 00888000"
+ // sscanf( PtLine, "%s %s %X", BufLine, BufCar, &m_layerMask );
+
+ PAD_ATTR_T attribute;
+
+ data = strtok_r( line + SZ( "At" ), delims, &saveptr );
+
+ if( !strcmp( data, "SMD" ) )
+ attribute = PAD_ATTRIB_SMD;
+ else if( !strcmp( data, "CONN" ) )
+ attribute = PAD_ATTRIB_CONN;
+ else if( !strcmp( data, "HOLE" ) )
+ attribute = PAD_ATTRIB_HOLE_NOT_PLATED;
+ else
+ attribute = PAD_ATTRIB_STANDARD;
+
+ strtok_r( NULL, delims, &saveptr ); // skip BufCar
+ data = strtok_r( NULL, delims, &saveptr );
+
+ LEG_MASK layer_mask = hexParse( data );
+
+ pad->SetLayerSet( leg_mask2new( m_cu_count, layer_mask ) );
+ pad->SetAttribute( attribute );
+ }
+
+ else if( TESTLINE( "Ne" ) ) // (Ne)tname
+ {
+ // e.g. "Ne 461 "V5.0"
+
+ char buf[1024]; // can be fairly long
+ int netcode = intParse( line + SZ( "Ne" ), &data );
+
+ // Store the new code mapping
+ pad->SetNetCode( getNetCode( netcode ) );
+
+ // read Netname
+ ReadDelimitedText( buf, data, sizeof(buf) );
+#ifndef NDEBUG
+ if( m_board )
+ assert( m_board->FindNet( getNetCode( netcode ) )->GetNetname() ==
+ FROM_UTF8( StrPurge( buf ) ) );
+#endif /* NDEBUG */
+ }
+
+ else if( TESTLINE( "Po" ) ) // (Po)sition
+ {
+ // e.g. "Po 500 -500"
+ wxPoint pos;
+
+ pos.x = biuParse( line + SZ( "Po" ), &data );
+ pos.y = biuParse( data );
+
+ pad->SetPos0( pos );
+ // pad->SetPosition( pos ); set at function return
+ }
+
+ else if( TESTLINE( "Le" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "Le" ) );
+ pad->SetPadToDieLength( tmp );
+ }
+
+ else if( TESTLINE( ".SolderMask" ) )
+ {
+ BIU tmp = biuParse( line + SZ( ".SolderMask" ) );
+ pad->SetLocalSolderMaskMargin( tmp );
+ }
+
+ else if( TESTLINE( ".SolderPasteRatio" ) )
+ {
+ double tmp = atof( line + SZ( ".SolderPasteRatio" ) );
+ pad->SetLocalSolderPasteMarginRatio( tmp );
+ }
+
+ else if( TESTLINE( ".SolderPaste" ) )
+ {
+ BIU tmp = biuParse( line + SZ( ".SolderPaste" ) );
+ pad->SetLocalSolderPasteMargin( tmp );
+ }
+
+ else if( TESTLINE( ".LocalClearance" ) )
+ {
+ BIU tmp = biuParse( line + SZ( ".LocalClearance" ) );
+ pad->SetLocalClearance( tmp );
+ }
+
+ else if( TESTLINE( ".ZoneConnection" ) )
+ {
+ int tmp = intParse( line + SZ( ".ZoneConnection" ) );
+ pad->SetZoneConnection( (ZoneConnection)tmp );
+ }
+
+ else if( TESTLINE( ".ThermalWidth" ) )
+ {
+ BIU tmp = biuParse( line + SZ( ".ThermalWidth" ) );
+ pad->SetThermalWidth( tmp );
+ }
+
+ else if( TESTLINE( ".ThermalGap" ) )
+ {
+ BIU tmp = biuParse( line + SZ( ".ThermalGap" ) );
+ pad->SetThermalGap( tmp );
+ }
+
+ else if( TESTLINE( "$EndPAD" ) )
+ {
+ // pad's "Position" is not relative to the module's,
+ // whereas Pos0 is relative to the module's but is the unrotated coordinate.
+
+ wxPoint padpos = pad->GetPos0();
+
+ RotatePoint( &padpos, aModule->GetOrientation() );
+
+ pad->SetPosition( padpos + aModule->GetPosition() );
+
+ aModule->Pads().PushBack( pad.release() );
+ return; // preferred exit
+ }
+ }
+
+ THROW_IO_ERROR( "Missing '$EndPAD'" );
+}
+
+
+void LEGACY_PLUGIN::loadMODULE_EDGE( MODULE* aModule )
+{
+ STROKE_T shape;
+ char* line = m_reader->Line(); // obtain current (old) line
+
+ switch( line[1] )
+ {
+ case 'S': shape = S_SEGMENT; break;
+ case 'C': shape = S_CIRCLE; break;
+ case 'A': shape = S_ARC; break;
+ case 'P': shape = S_POLYGON; break;
+ default:
+ m_error.Printf( wxT( "Unknown EDGE_MODULE type:'%c=0x%02x' on line:%d of module:'%s'" ),
+ (unsigned char) line[1],
+ (unsigned char) line[1],
+ m_reader->LineNumber(),
+ GetChars( aModule->GetFPID().GetFootprintName() )
+ );
+ THROW_IO_ERROR( m_error );
+ }
+
+ auto_ptr<EDGE_MODULE> dwg( new EDGE_MODULE( aModule, shape ) ); // a drawing
+
+ const char* data;
+
+ // common to all cases, and we have to check their values uniformly at end
+ BIU width = 1;
+ LAYER_NUM layer = FIRST_NON_COPPER_LAYER;
+
+ switch( shape )
+ {
+ case S_ARC:
+ {
+ // sscanf( Line + 3, "%d %d %d %d %d %d %d", &m_Start0.x, &m_Start0.y, &m_End0.x, &m_End0.y, &m_Angle, &m_Width, &m_Layer );
+ BIU start0_x = biuParse( line + SZ( "DA" ), &data );
+ BIU start0_y = biuParse( data, &data );
+ BIU end0_x = biuParse( data, &data );
+ BIU end0_y = biuParse( data, &data );
+ double angle = degParse( data, &data );
+
+ width = biuParse( data, &data );
+ layer = layerParse( data );
+
+ dwg->SetAngle( angle );
+ dwg->m_Start0 = wxPoint( start0_x, start0_y );
+ dwg->m_End0 = wxPoint( end0_x, end0_y );
+ }
+ break;
+
+ case S_SEGMENT:
+ case S_CIRCLE:
+ {
+ // e.g. "DS -7874 -10630 7874 -10630 50 20\r\n"
+ // sscanf( Line + 3, "%d %d %d %d %d %d", &m_Start0.x, &m_Start0.y, &m_End0.x, &m_End0.y, &m_Width, &m_Layer );
+
+ BIU start0_x = biuParse( line + SZ( "DS" ), &data );
+ BIU start0_y = biuParse( data, &data );
+ BIU end0_x = biuParse( data, &data );
+ BIU end0_y = biuParse( data, &data );
+
+ width = biuParse( data, &data );
+ layer = layerParse( data );
+
+ dwg->m_Start0 = wxPoint( start0_x, start0_y );
+ dwg->m_End0 = wxPoint( end0_x, end0_y );
+ }
+ break;
+
+ case S_POLYGON:
+ {
+ // e.g. "DP %d %d %d %d %d %d %d\n"
+ // sscanf( Line + 3, "%d %d %d %d %d %d %d", &m_Start0.x, &m_Start0.y, &m_End0.x, &m_End0.y, &pointCount, &m_Width, &m_Layer );
+
+ BIU start0_x = biuParse( line + SZ( "DP" ), &data );
+ BIU start0_y = biuParse( data, &data );
+ BIU end0_x = biuParse( data, &data );
+ BIU end0_y = biuParse( data, &data );
+ int ptCount = intParse( data, &data );
+
+ width = biuParse( data, &data );
+ layer = layerParse( data );
+
+ dwg->m_Start0 = wxPoint( start0_x, start0_y );
+ dwg->m_End0 = wxPoint( end0_x, end0_y );
+
+ std::vector<wxPoint> pts;
+ pts.reserve( ptCount );
+
+ for( int ii = 0; ii<ptCount; ++ii )
+ {
+ if( ( line = READLINE( m_reader ) ) == NULL )
+ {
+ THROW_IO_ERROR( "S_POLGON point count mismatch." );
+ }
+
+ // e.g. "Dl 23 44\n"
+
+ if( !TESTLINE( "Dl" ) )
+ {
+ THROW_IO_ERROR( "Missing Dl point def" );
+ }
+
+ BIU x = biuParse( line + SZ( "Dl" ), &data );
+ BIU y = biuParse( data );
+
+ pts.push_back( wxPoint( x, y ) );
+ }
+
+ dwg->SetPolyPoints( pts );
+ }
+ break;
+
+ default:
+ // first switch code above prevents us from getting here.
+ break;
+ }
+
+ // Check for a reasonable width:
+
+ /* @todo no MAX_WIDTH in out of reach header.
+ if( width <= 1 )
+ width = 1;
+ else if( width > MAX_WIDTH )
+ width = MAX_WIDTH;
+ */
+
+ // Check for a reasonable layer:
+ // m_Layer must be >= FIRST_NON_COPPER_LAYER, but because microwave footprints
+ // can use the copper layers m_Layer < FIRST_NON_COPPER_LAYER is allowed.
+ // @todo: changes use of EDGE_MODULE these footprints and allows only
+ // m_Layer >= FIRST_NON_COPPER_LAYER
+ if( layer < FIRST_LAYER || layer > LAST_NON_COPPER_LAYER )
+ layer = SILKSCREEN_N_FRONT;
+
+ dwg->SetWidth( width );
+ dwg->SetLayer( leg_layer2new( m_cu_count, layer ) );
+
+ EDGE_MODULE* em = dwg.release();
+
+ aModule->GraphicalItems().PushBack( em );
+
+ // this had been done at the MODULE level before, presumably because the
+ // EDGE_MODULE needs to be already added to a module before this function will work.
+ em->SetDrawCoord();
+}
+
+
+void LEGACY_PLUGIN::loadMODULE_TEXT( TEXTE_MODULE* aText )
+{
+ const char* data;
+ const char* txt_end;
+ const char* line = m_reader->Line(); // current (old) line
+ char* saveptr;
+
+ // sscanf( line + 1, "%d %d %d %d %d %d %d %s %s %d %s",
+ // &type, &m_Pos0.x, &m_Pos0.y, &m_Size.y, &m_Size.x,
+ // &m_Orient, &m_Thickness, BufCar1, BufCar2, &layer, BufCar3 ) >= 10 )
+
+ // e.g. "T1 6940 -16220 350 300 900 60 M I 20 N "CFCARD"\r\n"
+ // or T1 0 500 600 400 900 80 M V 20 N"74LS245"
+ // ouch, the last example has no space between N and "74LS245" !
+ // that is an older version.
+
+ int type = intParse( line+1, &data );
+ BIU pos0_x = biuParse( data, &data );
+ BIU pos0_y = biuParse( data, &data );
+ BIU size0_y = biuParse( data, &data );
+ BIU size0_x = biuParse( data, &data );
+ double orient = degParse( data, &data );
+ BIU thickn = biuParse( data, &data );
+
+ // read the quoted text before the first call to strtok() which introduces
+ // NULs into the string and chops it into mutliple C strings, something
+ // ReadDelimitedText() cannot traverse.
+
+ // convert the "quoted, escaped, UTF8, text" to a wxString, find it by skipping
+ // as far forward as needed until the first double quote.
+ txt_end = data + ReadDelimitedText( &m_field, data );
+
+#if 1 && defined(DEBUG)
+ if( m_field == wxT( "ARM_C8" ) )
+ {
+ int breakhere = 1;
+ (void) breakhere;
+ }
+#endif
+
+ aText->SetText( m_field );
+
+ // after switching to strtok, there's no easy coming back because of the
+ // embedded nul(s?) placed to the right of the current field.
+ // (that's the reason why strtok was deprecated...)
+ char* mirror = strtok_r( (char*) data, delims, &saveptr );
+ char* hide = strtok_r( NULL, delims, &saveptr );
+ char* tmp = strtok_r( NULL, delims, &saveptr );
+
+ LAYER_NUM layer_num = tmp ? layerParse( tmp ) : SILKSCREEN_N_FRONT;
+
+ char* italic = strtok_r( NULL, delims, &saveptr );
+
+ char* hjust = strtok_r( (char*) txt_end, delims, &saveptr );
+ char* vjust = strtok_r( NULL, delims, &saveptr );
+
+ if( type != TEXTE_MODULE::TEXT_is_REFERENCE
+ && type != TEXTE_MODULE::TEXT_is_VALUE )
+ type = TEXTE_MODULE::TEXT_is_DIVERS;
+
+ aText->SetType( static_cast<TEXTE_MODULE::TEXT_TYPE>( type ) );
+
+ aText->SetPos0( wxPoint( pos0_x, pos0_y ) );
+ aText->SetSize( wxSize( size0_x, size0_y ) );
+
+ orient -= ( static_cast<MODULE*>( aText->GetParent() ) )->GetOrientation();
+
+ aText->SetOrientation( orient );
+
+ // @todo put in accessors?
+ // Set a reasonable width:
+ if( thickn < 1 )
+ thickn = 1;
+
+ /* this is better left to the dialogs UIs
+ aText->SetThickness( Clamp_Text_PenSize( thickn, aText->GetSize() ) );
+ */
+
+ aText->SetThickness( thickn );
+
+ aText->SetMirrored( mirror && *mirror == 'M' );
+
+ aText->SetVisible( !(hide && *hide == 'I') );
+
+ aText->SetItalic( italic && *italic == 'I' );
+
+ if( hjust )
+ aText->SetHorizJustify( horizJustify( hjust ) );
+
+ if( vjust )
+ aText->SetVertJustify( vertJustify( vjust ) );
+
+ if( layer_num < FIRST_LAYER )
+ layer_num = FIRST_LAYER;
+ else if( layer_num > LAST_NON_COPPER_LAYER )
+ layer_num = LAST_NON_COPPER_LAYER;
+ else if( layer_num == LAYER_N_BACK )
+ layer_num = SILKSCREEN_N_BACK;
+ else if( layer_num == LAYER_N_FRONT )
+ layer_num = SILKSCREEN_N_FRONT;
+
+ aText->SetLayer( leg_layer2new( m_cu_count, layer_num ) );
+
+ // Calculate the actual position.
+ aText->SetDrawCoord();
+}
+
+
+void LEGACY_PLUGIN::load3D( MODULE* aModule )
+{
+ S3D_MASTER* t3D = aModule->Models();
+
+ if( !t3D->GetShape3DName().IsEmpty() )
+ {
+ S3D_MASTER* n3D = new S3D_MASTER( aModule );
+
+ aModule->Models().PushBack( n3D );
+
+ t3D = n3D;
+ }
+
+ char* line;
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ if( TESTLINE( "Na" ) ) // Shape File Name
+ {
+ char buf[512];
+ ReadDelimitedText( buf, line + SZ( "Na" ), sizeof(buf) );
+ t3D->SetShape3DName( FROM_UTF8( buf ) );
+ }
+
+ else if( TESTLINE( "Sc" ) ) // Scale
+ {
+ sscanf( line + SZ( "Sc" ), "%lf %lf %lf\n",
+ &t3D->m_MatScale.x,
+ &t3D->m_MatScale.y,
+ &t3D->m_MatScale.z );
+ }
+
+ else if( TESTLINE( "Of" ) ) // Offset
+ {
+ sscanf( line + SZ( "Of" ), "%lf %lf %lf\n",
+ &t3D->m_MatPosition.x,
+ &t3D->m_MatPosition.y,
+ &t3D->m_MatPosition.z );
+ }
+
+ else if( TESTLINE( "Ro" ) ) // Rotation
+ {
+ sscanf( line + SZ( "Ro" ), "%lf %lf %lf\n",
+ &t3D->m_MatRotation.x,
+ &t3D->m_MatRotation.y,
+ &t3D->m_MatRotation.z );
+ }
+
+ else if( TESTLINE( "$EndSHAPE3D" ) )
+ return; // preferred exit
+ }
+
+ THROW_IO_ERROR( "Missing '$EndSHAPE3D'" );
+}
+
+
+void LEGACY_PLUGIN::loadPCB_LINE()
+{
+ /* example:
+ $DRAWSEGMENT
+ Po 0 57500 -1000 57500 0 150
+ De 24 0 900 0 0
+ $EndDRAWSEGMENT
+ */
+
+ auto_ptr<DRAWSEGMENT> dseg( new DRAWSEGMENT( m_board ) );
+
+ char* line;
+ char* saveptr;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ const char* data;
+
+ if( TESTLINE( "Po" ) )
+ {
+ // sscanf( line + 2, " %d %d %d %d %d %d", &m_Shape, &m_Start.x, &m_Start.y, &m_End.x, &m_End.y, &m_Width );
+ int shape = intParse( line + SZ( "Po" ), &data );
+ BIU start_x = biuParse( data, &data );
+ BIU start_y = biuParse( data, &data );
+ BIU end_x = biuParse( data, &data );
+ BIU end_y = biuParse( data, &data );
+ BIU width = biuParse( data );
+
+ if( width < 0 )
+ width = 0;
+
+ dseg->SetShape( STROKE_T( shape ) );
+ dseg->SetWidth( width );
+ dseg->SetStart( wxPoint( start_x, start_y ) );
+ dseg->SetEnd( wxPoint( end_x, end_y ) );
+ }
+
+ else if( TESTLINE( "De" ) )
+ {
+ BIU x = 0;
+ BIU y;
+
+ data = strtok_r( line + SZ( "De" ), delims, &saveptr );
+ for( int i = 0; data; ++i, data = strtok_r( NULL, delims, &saveptr ) )
+ {
+ switch( i )
+ {
+ case 0:
+ LAYER_NUM layer;
+ layer = layerParse( data );
+
+ if( layer < FIRST_NON_COPPER_LAYER )
+ layer = FIRST_NON_COPPER_LAYER;
+
+ else if( layer > LAST_NON_COPPER_LAYER )
+ layer = LAST_NON_COPPER_LAYER;
+
+ dseg->SetLayer( leg_layer2new( m_cu_count, layer ) );
+ break;
+ case 1:
+ int mtype;
+ mtype = intParse( data );
+ dseg->SetType( mtype ); // m_Type
+ break;
+ case 2:
+ double angle;
+ angle = degParse( data );
+ dseg->SetAngle( angle ); // m_Angle
+ break;
+ case 3:
+ time_t timestamp;
+ timestamp = hexParse( data );
+ dseg->SetTimeStamp( timestamp );
+ break;
+ case 4:
+ STATUS_FLAGS state;
+ state = static_cast<STATUS_FLAGS>( hexParse( data ) );
+ dseg->SetState( state, true );
+ break;
+
+ // Bezier Control Points
+ case 5:
+ x = biuParse( data );
+ break;
+ case 6:
+ y = biuParse( data );
+ dseg->SetBezControl1( wxPoint( x, y ) );
+ break;
+
+ case 7:
+ x = biuParse( data );
+ break;
+ case 8:
+ y = biuParse( data );
+ dseg->SetBezControl2( wxPoint( x, y ) );
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ else if( TESTLINE( "$EndDRAWSEGMENT" ) )
+ {
+ m_board->Add( dseg.release(), ADD_APPEND );
+ return; // preferred exit
+ }
+ }
+
+ THROW_IO_ERROR( "Missing '$EndDRAWSEGMENT'" );
+}
+
+void LEGACY_PLUGIN::loadNETINFO_ITEM()
+{
+ /* a net description is something like
+ * $EQUIPOT
+ * Na 5 "/BIT1"
+ * St ~
+ * $EndEQUIPOT
+ */
+
+ char buf[1024];
+
+ NETINFO_ITEM* net = NULL;
+ char* line;
+ int netCode = 0;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ const char* data;
+
+ if( TESTLINE( "Na" ) )
+ {
+ // e.g. "Na 58 "/cpu.sch/PAD7"\r\n"
+
+ netCode = intParse( line + SZ( "Na" ), &data );
+
+ ReadDelimitedText( buf, data, sizeof(buf) );
+
+ if( net == NULL )
+ net = new NETINFO_ITEM( m_board, FROM_UTF8( buf ), netCode );
+ else
+ {
+ THROW_IO_ERROR( "Two net definitions in '$EQUIPOT' block" );
+ }
+ }
+
+ else if( TESTLINE( "$EndEQUIPOT" ) )
+ {
+ // net 0 should be already in list, so store this net
+ // if it is not the net 0, or if the net 0 does not exists.
+ if( net && ( net->GetNet() > 0 || m_board->FindNet( 0 ) == NULL ) )
+ {
+ m_board->AppendNet( net );
+
+ // Be sure we have room to store the net in m_netCodes
+ if( (int)m_netCodes.size() <= netCode )
+ m_netCodes.resize( netCode+1 );
+
+ m_netCodes[netCode] = net->GetNet();
+ net = NULL;
+ }
+ else
+ {
+ delete net;
+ net = NULL; // Avoid double deletion.
+ }
+
+ return; // preferred exit
+ }
+ }
+
+ // If we are here, there is an error.
+ delete net;
+ THROW_IO_ERROR( "Missing '$EndEQUIPOT'" );
+}
+
+
+void LEGACY_PLUGIN::loadPCB_TEXT()
+{
+ /* examples:
+ For a single line text:
+ ----------------------
+ $TEXTPCB
+ Te "Text example"
+ Po 66750 53450 600 800 150 0
+ De 24 1 0 Italic
+ $EndTEXTPCB
+
+ For a multi line text:
+ ---------------------
+ $TEXTPCB
+ Te "Text example"
+ Nl "Line 2"
+ Po 66750 53450 600 800 150 0
+ De 24 1 0 Italic
+ $EndTEXTPCB
+ Nl "line nn" is a line added to the current text
+ */
+
+ char text[1024];
+
+ // maybe someday a constructor that takes all this data in one call?
+ TEXTE_PCB* pcbtxt = new TEXTE_PCB( m_board );
+ m_board->Add( pcbtxt, ADD_APPEND );
+
+ char* line;
+ char* saveptr;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ const char* data;
+
+ if( TESTLINE( "Te" ) ) // Text line (or first line for multi line texts)
+ {
+ ReadDelimitedText( text, line + SZ( "Te" ), sizeof(text) );
+ pcbtxt->SetText( FROM_UTF8( text ) );
+ }
+
+ else if( TESTLINE( "nl" ) ) // next line of the current text
+ {
+ ReadDelimitedText( text, line + SZ( "nl" ), sizeof(text) );
+ pcbtxt->SetText( pcbtxt->GetText() + wxChar( '\n' ) + FROM_UTF8( text ) );
+ }
+
+ else if( TESTLINE( "Po" ) )
+ {
+ // sscanf( line + 2, " %d %d %d %d %d %d", &m_Pos.x, &m_Pos.y, &m_Size.x, &m_Size.y, &m_Thickness, &m_Orient );
+ wxSize size;
+
+ BIU pos_x = biuParse( line + SZ( "Po" ), &data );
+ BIU pos_y = biuParse( data, &data );
+ size.x = biuParse( data, &data );
+ size.y = biuParse( data, &data );
+ BIU thickn = biuParse( data, &data );
+ double angle = degParse( data );
+
+ // Ensure the text has minimal size to see this text on screen:
+
+ /* @todo wait until we are firmly in the nanometer world
+ if( sz.x < 5 )
+ sz.x = 5;
+
+ if( sz.y < 5 )
+ sz.y = 5;
+ */
+
+ pcbtxt->SetSize( size );
+
+ /* @todo move into an accessor
+ // Set a reasonable width:
+ if( thickn < 1 )
+ thickn = 1;
+
+ thickn = Clamp_Text_PenSize( thickn, size );
+ */
+
+ pcbtxt->SetThickness( thickn );
+ pcbtxt->SetOrientation( angle );
+
+ pcbtxt->SetTextPosition( wxPoint( pos_x, pos_y ) );
+ }
+
+ else if( TESTLINE( "De" ) )
+ {
+ // e.g. "De 21 1 0 Normal C\r\n"
+ // sscanf( line + 2, " %d %d %lX %s %c\n", &m_Layer, &normal_display, &m_TimeStamp, style, &hJustify );
+
+ LAYER_NUM layer_num = layerParse( line + SZ( "De" ), &data );
+ int notMirrored = intParse( data, &data );
+ time_t timestamp = hexParse( data, &data );
+ char* style = strtok_r( (char*) data, delims, &saveptr );
+ char* hJustify = strtok_r( NULL, delims, &saveptr );
+ char* vJustify = strtok_r( NULL, delims, &saveptr );
+
+ pcbtxt->SetMirrored( !notMirrored );
+ pcbtxt->SetTimeStamp( timestamp );
+ pcbtxt->SetItalic( !strcmp( style, "Italic" ) );
+
+ if( hJustify )
+ pcbtxt->SetHorizJustify( horizJustify( hJustify ) );
+ else
+ {
+ // boom, somebody changed a constructor, I was relying on this:
+ wxASSERT( pcbtxt->GetHorizJustify() == GR_TEXT_HJUSTIFY_CENTER );
+ }
+
+ if( vJustify )
+ pcbtxt->SetVertJustify( vertJustify( vJustify ) );
+
+ if( layer_num < FIRST_COPPER_LAYER )
+ layer_num = FIRST_COPPER_LAYER;
+ else if( layer_num > LAST_NON_COPPER_LAYER )
+ layer_num = LAST_NON_COPPER_LAYER;
+
+ if( layer_num >= FIRST_NON_COPPER_LAYER ||
+ is_leg_copperlayer_valid( m_cu_count, layer_num ) )
+ pcbtxt->SetLayer( leg_layer2new( m_cu_count, layer_num ) );
+ else // not perfect, but putting this text on front layer is a workaround
+ pcbtxt->SetLayer( F_Cu );
+ }
+
+ else if( TESTLINE( "$EndTEXTPCB" ) )
+ {
+ return; // preferred exit
+ }
+ }
+
+ THROW_IO_ERROR( "Missing '$EndTEXTPCB'" );
+}
+
+
+void LEGACY_PLUGIN::loadTrackList( int aStructType )
+{
+ char* line;
+ char* saveptr;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ // read two lines per loop iteration, each loop is one TRACK or VIA
+ // example first line:
+ // e.g. "Po 0 23994 28800 24400 28800 150 -1" for a track
+ // e.g. "Po 3 21086 17586 21086 17586 180 -1" for a via (uses sames start and end)
+
+ const char* data;
+
+ if( line[0] == '$' ) // $EndTRACK
+ return; // preferred exit
+
+ // int arg_count = sscanf( line + 2, " %d %d %d %d %d %d %d", &shape, &tempStartX, &tempStartY, &tempEndX, &tempEndY, &width, &drill );
+
+ assert( TESTLINE( "Po" ) );
+
+ VIATYPE_T viatype = static_cast<VIATYPE_T>( intParse( line + SZ( "Po" ), &data ));
+ BIU start_x = biuParse( data, &data );
+ BIU start_y = biuParse( data, &data );
+ BIU end_x = biuParse( data, &data );
+ BIU end_y = biuParse( data, &data );
+ BIU width = biuParse( data, &data );
+
+ // optional 7th drill parameter (must be optional in an old format?)
+ data = strtok_r( (char*) data, delims, &saveptr );
+
+ BIU drill = data ? biuParse( data ) : -1; // SetDefault() if < 0
+
+ // Read the 2nd line to determine the exact type, one of:
+ // PCB_TRACE_T, PCB_VIA_T, or PCB_ZONE_T. The type field in 2nd line
+ // differentiates between PCB_TRACE_T and PCB_VIA_T. With virtual
+ // functions in use, it is critical to instantiate the PCB_VIA_T
+ // exactly.
+ READLINE( m_reader );
+
+ line = m_reader->Line();
+
+ // example second line:
+ // "De 0 0 463 0 800000\r\n"
+
+#if 1
+ assert( TESTLINE( "De" ) );
+#else
+ if( !TESTLINE( "De" ) )
+ {
+ // mandatory 2nd line is missing
+ THROW_IO_ERROR( "Missing 2nd line of a TRACK def" );
+ }
+#endif
+
+ int makeType;
+ time_t timeStamp;
+ LAYER_NUM layer_num;
+ int type, net_code, flags_int;
+
+ // parse the 2nd line to determine the type of object
+ // e.g. "De 15 1 7 0 0" for a via
+ sscanf( line + SZ( "De" ), " %d %d %d %lX %X", &layer_num, &type, &net_code,
+ &timeStamp, &flags_int );
+
+ STATUS_FLAGS flags;
+
+ flags = static_cast<STATUS_FLAGS>( flags_int );
+
+ if( aStructType==PCB_TRACE_T && type==1 )
+ makeType = PCB_VIA_T;
+ else
+ makeType = aStructType;
+
+ TRACK* newTrack;
+
+ switch( makeType )
+ {
+ default:
+ case PCB_TRACE_T:
+ newTrack = new TRACK( m_board );
+ break;
+
+ case PCB_VIA_T:
+ newTrack = new VIA( m_board );
+ break;
+
+ case PCB_ZONE_T: // this is now deprecated, but exist in old boards
+ newTrack = new SEGZONE( m_board );
+ break;
+ }
+
+ newTrack->SetTimeStamp( timeStamp );
+
+ newTrack->SetPosition( wxPoint( start_x, start_y ) );
+ newTrack->SetEnd( wxPoint( end_x, end_y ) );
+
+ newTrack->SetWidth( width );
+
+ if( makeType == PCB_VIA_T ) // Ensure layers are OK when possible:
+ {
+ VIA *via = static_cast<VIA*>( newTrack );
+ via->SetViaType( viatype );
+
+ if( drill < 0 )
+ via->SetDrillDefault();
+ else
+ via->SetDrill( drill );
+
+ if( via->GetViaType() == VIA_THROUGH )
+ via->SetLayerPair( F_Cu, B_Cu );
+ else
+ {
+ LAYER_ID back = leg_layer2new( m_cu_count, (layer_num >> 4) & 0xf );
+ LAYER_ID front = leg_layer2new( m_cu_count, layer_num & 0xf );
+
+ if( is_leg_copperlayer_valid( m_cu_count, back ) &&
+ is_leg_copperlayer_valid( m_cu_count, front ) )
+ via->SetLayerPair( front, back );
+ else
+ {
+ delete via;
+ newTrack = NULL;
+ }
+ }
+ }
+ else
+ {
+ // A few legacy boards can have tracks on non existent layers, because
+ // reducing the number of layers does not remove tracks on removed layers
+ // If happens, skip them
+ if( is_leg_copperlayer_valid( m_cu_count, layer_num ) )
+ newTrack->SetLayer( leg_layer2new( m_cu_count, layer_num ) );
+ else
+ {
+ delete newTrack;
+ newTrack = NULL;
+ }
+ }
+
+ if( newTrack )
+ {
+ newTrack->SetNetCode( getNetCode( net_code ) );
+ newTrack->SetState( flags, true );
+
+ m_board->Add( newTrack );
+ }
+ }
+
+ THROW_IO_ERROR( "Missing '$EndTRACK'" );
+}
+
+
+void LEGACY_PLUGIN::loadNETCLASS()
+{
+ char buf[1024];
+ wxString netname;
+ char* line;
+
+ // create an empty NETCLASS without a name, but do not add it to the BOARD
+ // yet since that would bypass duplicate netclass name checking within the BOARD.
+ // store it temporarily in an auto_ptr until successfully inserted into the BOARD
+ // just before returning.
+ NETCLASSPTR nc = boost::make_shared<NETCLASS>( wxEmptyString );
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ if( TESTLINE( "AddNet" ) ) // most frequent type of line
+ {
+ // e.g. "AddNet "V3.3D"\n"
+ ReadDelimitedText( buf, line + SZ( "AddNet" ), sizeof(buf) );
+ netname = FROM_UTF8( buf );
+ nc->Add( netname );
+ }
+
+ else if( TESTLINE( "Clearance" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "Clearance" ) );
+ nc->SetClearance( tmp );
+ }
+
+ else if( TESTLINE( "TrackWidth" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "TrackWidth" ) );
+ nc->SetTrackWidth( tmp );
+ }
+
+ else if( TESTLINE( "ViaDia" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "ViaDia" ) );
+ nc->SetViaDiameter( tmp );
+ }
+
+ else if( TESTLINE( "ViaDrill" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "ViaDrill" ) );
+ nc->SetViaDrill( tmp );
+ }
+
+ else if( TESTLINE( "uViaDia" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "uViaDia" ) );
+ nc->SetuViaDiameter( tmp );
+ }
+
+ else if( TESTLINE( "uViaDrill" ) )
+ {
+ BIU tmp = biuParse( line + SZ( "uViaDrill" ) );
+ nc->SetuViaDrill( tmp );
+ }
+
+ else if( TESTLINE( "Name" ) )
+ {
+ ReadDelimitedText( buf, line + SZ( "Name" ), sizeof(buf) );
+ nc->SetName( FROM_UTF8( buf ) );
+ }
+
+ else if( TESTLINE( "Desc" ) )
+ {
+ ReadDelimitedText( buf, line + SZ( "Desc" ), sizeof(buf) );
+ nc->SetDescription( FROM_UTF8( buf ) );
+ }
+
+ else if( TESTLINE( "$EndNCLASS" ) )
+ {
+ if( !m_board->GetDesignSettings().m_NetClasses.Add( nc ) )
+ {
+ // Must have been a name conflict, this is a bad board file.
+ // User may have done a hand edit to the file.
+
+ // auto_ptr will delete nc on this code path
+
+ m_error.Printf( _( "duplicate NETCLASS name '%s'" ), nc->GetName().GetData() );
+ THROW_IO_ERROR( m_error );
+ }
+
+ return; // preferred exit
+ }
+ }
+
+ THROW_IO_ERROR( "Missing '$EndNCLASS'" );
+}
+
+
+void LEGACY_PLUGIN::loadZONE_CONTAINER()
+{
+ auto_ptr<ZONE_CONTAINER> zc( new ZONE_CONTAINER( m_board ) );
+
+ CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::NO_HATCH;
+ bool sawCorner = false;
+ char buf[1024];
+ char* line;
+ char* saveptr;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ const char* data;
+
+ if( TESTLINE( "ZCorner" ) ) // new corner found
+ {
+ // e.g. "ZCorner 25650 49500 0"
+ BIU x = biuParse( line + SZ( "ZCorner" ), &data );
+ BIU y = biuParse( data, &data );
+ int flag = intParse( data );
+
+ if( !sawCorner )
+ zc->Outline()->Start( zc->GetLayer(), x, y, outline_hatch );
+ else
+ zc->AppendCorner( wxPoint( x, y ) );
+
+ sawCorner = true;
+
+ if( flag )
+ zc->Outline()->CloseLastContour();
+ }
+
+ else if( TESTLINE( "ZInfo" ) ) // general info found
+ {
+ // e.g. 'ZInfo 479194B1 310 "COMMON"'
+ time_t timestamp = hexParse( line + SZ( "ZInfo" ), &data );
+ int netcode = intParse( data, &data );
+
+ if( ReadDelimitedText( buf, data, sizeof(buf) ) > (int) sizeof(buf) )
+ {
+ THROW_IO_ERROR( "ZInfo netname too long" );
+ }
+
+ zc->SetTimeStamp( timestamp );
+ // Init the net code only, not the netname, to be sure
+ // the zone net name is the name read in file.
+ // (When mismatch, the user will be prompted in DRC, to fix the actual name)
+ zc->BOARD_CONNECTED_ITEM::SetNetCode( getNetCode( netcode ) );
+ }
+
+ else if( TESTLINE( "ZLayer" ) ) // layer found
+ {
+ LAYER_NUM layer_num = layerParse( line + SZ( "ZLayer" ) );
+ zc->SetLayer( leg_layer2new( m_cu_count, layer_num ) );
+ }
+
+ else if( TESTLINE( "ZAux" ) ) // aux info found
+ {
+ // e.g. "ZAux 7 E"
+ int ignore = intParse( line + SZ( "ZAux" ), &data );
+ char* hopt = strtok_r( (char*) data, delims, &saveptr );
+
+ if( !hopt )
+ {
+ m_error.Printf( wxT( "Bad ZAux for CZONE_CONTAINER '%s'" ), zc->GetNetname().GetData() );
+ THROW_IO_ERROR( m_error );
+ }
+
+ switch( *hopt ) // upper case required
+ {
+ case 'N': outline_hatch = CPolyLine::NO_HATCH; break;
+ case 'E': outline_hatch = CPolyLine::DIAGONAL_EDGE; break;
+ case 'F': outline_hatch = CPolyLine::DIAGONAL_FULL; break;
+
+ default:
+ m_error.Printf( wxT( "Bad ZAux for CZONE_CONTAINER '%s'" ), zc->GetNetname().GetData() );
+ THROW_IO_ERROR( m_error );
+ }
+
+ (void) ignore;
+
+ // Set hatch mode later, after reading corner outline data
+ }
+
+ else if( TESTLINE( "ZSmoothing" ) )
+ {
+ // e.g. "ZSmoothing 0 0"
+ int smoothing = intParse( line + SZ( "ZSmoothing" ), &data );
+ BIU cornerRadius = biuParse( data );
+
+ if( smoothing >= ZONE_SETTINGS::SMOOTHING_LAST || smoothing < 0 )
+ {
+ m_error.Printf( wxT( "Bad ZSmoothing for CZONE_CONTAINER '%s'" ), zc->GetNetname().GetData() );
+ THROW_IO_ERROR( m_error );
+ }
+
+ zc->SetCornerSmoothingType( smoothing );
+ zc->SetCornerRadius( cornerRadius );
+ }
+
+ else if( TESTLINE( "ZKeepout" ) )
+ {
+ zc->SetIsKeepout( true );
+ // e.g. "ZKeepout tracks N vias N pads Y"
+ data = strtok_r( line + SZ( "ZKeepout" ), delims, &saveptr );
+
+ while( data )
+ {
+ if( !strcmp( data, "tracks" ) )
+ {
+ data = strtok_r( NULL, delims, &saveptr );
+ zc->SetDoNotAllowTracks( data && *data == 'N' );
+ }
+ else if( !strcmp( data, "vias" ) )
+ {
+ data = strtok_r( NULL, delims, &saveptr );
+ zc->SetDoNotAllowVias( data && *data == 'N' );
+ }
+ else if( !strcmp( data, "copperpour" ) )
+ {
+ data = strtok_r( NULL, delims, &saveptr );
+ zc->SetDoNotAllowCopperPour( data && *data == 'N' );
+ }
+
+ data = strtok_r( NULL, delims, &saveptr );
+ }
+ }
+
+ else if( TESTLINE( "ZOptions" ) )
+ {
+ // e.g. "ZOptions 0 32 F 200 200"
+ int fillmode = intParse( line + SZ( "ZOptions" ), &data );
+ int arcsegcount = intParse( data, &data );
+ char fillstate = data[1]; // here e.g. " F"
+ BIU thermalReliefGap = biuParse( data += 2 , &data ); // +=2 for " F"
+ BIU thermalReliefCopperBridge = biuParse( data );
+
+ zc->SetFillMode( fillmode ? 1 : 0 );
+
+ // @todo ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF: don't really want pcbnew.h
+ // in here, after all, its a PLUGIN and global data is evil.
+ // put in accessor
+ if( arcsegcount >= 32 )
+ arcsegcount = 32;
+
+ zc->SetArcSegmentCount( arcsegcount );
+ zc->SetIsFilled( fillstate == 'S' );
+ zc->SetThermalReliefGap( thermalReliefGap );
+ zc->SetThermalReliefCopperBridge( thermalReliefCopperBridge );
+ }
+
+ else if( TESTLINE( "ZClearance" ) ) // Clearance and pad options info found
+ {
+ // e.g. "ZClearance 40 I"
+ BIU clearance = biuParse( line + SZ( "ZClearance" ), &data );
+ char* padoption = strtok_r( (char*) data, delims, &saveptr ); // data: " I"
+
+ ZoneConnection popt;
+ switch( *padoption )
+ {
+ case 'I': popt = PAD_ZONE_CONN_FULL; break;
+ case 'T': popt = PAD_ZONE_CONN_THERMAL; break;
+ case 'H': popt = PAD_ZONE_CONN_THT_THERMAL; break;
+ case 'X': popt = PAD_ZONE_CONN_NONE; break;
+
+ default:
+ m_error.Printf( wxT( "Bad ZClearance padoption for CZONE_CONTAINER '%s'" ),
+ zc->GetNetname().GetData() );
+ THROW_IO_ERROR( m_error );
+ }
+
+ zc->SetZoneClearance( clearance );
+ zc->SetPadConnection( popt );
+ }
+
+ else if( TESTLINE( "ZMinThickness" ) )
+ {
+ BIU thickness = biuParse( line + SZ( "ZMinThickness" ) );
+ zc->SetMinThickness( thickness );
+ }
+
+ else if( TESTLINE( "ZPriority" ) )
+ {
+ int priority = intParse( line + SZ( "ZPriority" ) );
+ zc->SetPriority( priority );
+ }
+
+ else if( TESTLINE( "$POLYSCORNERS" ) )
+ {
+ // Read the PolysList (polygons used for fill areas in the zone)
+ SHAPE_POLY_SET polysList;
+
+ bool makeNewOutline = true;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ if( TESTLINE( "$endPOLYSCORNERS" ) )
+ break;
+
+ // e.g. "39610 43440 0 0"
+ BIU x = biuParse( line, &data );
+ BIU y = biuParse( data, &data );
+
+ if( makeNewOutline )
+ polysList.NewOutline();
+
+ polysList.Append( x, y );
+
+ bool end_contour = intParse( data, &data ); // end_countour was a bool when file saved, so '0' or '1' here
+ intParse( data ); // skip corner utility flag
+
+ makeNewOutline = end_contour;
+ }
+
+ zc->AddFilledPolysList( polysList );
+ }
+
+ else if( TESTLINE( "$FILLSEGMENTS" ) )
+ {
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ if( TESTLINE( "$endFILLSEGMENTS" ) )
+ break;
+
+ // e.g. ""%d %d %d %d\n"
+ BIU sx = biuParse( line, &data );
+ BIU sy = biuParse( data, &data );
+ BIU ex = biuParse( data, &data );
+ BIU ey = biuParse( data );
+
+ zc->FillSegments().push_back( SEGMENT( wxPoint( sx, sy ), wxPoint( ex, ey ) ) );
+ }
+ }
+
+ else if( TESTLINE( "$endCZONE_OUTLINE" ) )
+ {
+ // Ensure keepout does not have a net
+ // (which have no sense for a keepout zone)
+ if( zc->GetIsKeepout() )
+ zc->SetNetCode( NETINFO_LIST::UNCONNECTED );
+
+ // should always occur, but who knows, a zone without two corners
+ // is no zone at all, it's a spot?
+
+ if( zc->GetNumCorners() > 2 )
+ {
+ if( !zc->IsOnCopperLayer() )
+ {
+ zc->SetFillMode( 0 );
+ zc->SetNetCode( NETINFO_LIST::UNCONNECTED );
+ }
+
+ // Hatch here, after outlines corners are read
+ // Set hatch here, after outlines corners are read
+ zc->Outline()->SetHatch( outline_hatch,
+ Mils2iu( CPolyLine::GetDefaultHatchPitchMils() ),
+ true );
+
+ m_board->Add( zc.release() );
+ }
+
+ return; // preferred exit
+ }
+ }
+
+ THROW_IO_ERROR( "Missing '$endCZONE_OUTLINE'" );
+}
+
+
+void LEGACY_PLUGIN::loadDIMENSION()
+{
+ auto_ptr<DIMENSION> dim( new DIMENSION( m_board ) );
+
+ char* line;
+ char* saveptr;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ const char* data;
+
+ if( TESTLINE( "$endCOTATION" ) )
+ {
+ m_board->Add( dim.release(), ADD_APPEND );
+ return; // preferred exit
+ }
+
+ else if( TESTLINE( "Va" ) )
+ {
+ BIU value = biuParse( line + SZ( "Va" ) );
+ dim->SetValue( value );
+ }
+
+ else if( TESTLINE( "Ge" ) )
+ {
+ LAYER_NUM layer_num;
+ time_t timestamp;
+ int shape;
+ int ilayer;
+
+ sscanf( line + SZ( "Ge" ), " %d %d %lX", &shape, &ilayer, &timestamp );
+
+ if( ilayer < FIRST_NON_COPPER_LAYER )
+ layer_num = FIRST_NON_COPPER_LAYER;
+ else if( ilayer > LAST_NON_COPPER_LAYER )
+ layer_num = LAST_NON_COPPER_LAYER;
+ else
+ layer_num = ilayer;
+
+ dim->SetLayer( leg_layer2new( m_cu_count, layer_num ) );
+ dim->SetTimeStamp( timestamp );
+ dim->SetShape( shape );
+ }
+
+ else if( TESTLINE( "Te" ) )
+ {
+ char buf[2048];
+
+ ReadDelimitedText( buf, line + SZ( "Te" ), sizeof(buf) );
+ dim->SetText( FROM_UTF8( buf ) );
+ }
+
+ else if( TESTLINE( "Po" ) )
+ {
+ // sscanf( Line + 2, " %d %d %d %d %d %d %d", &m_Text->m_Pos.x, &m_Text->m_Pos.y,
+ // &m_Text->m_Size.x, &m_Text->m_Size.y, &thickness, &orientation, &normal_display );
+
+ BIU pos_x = biuParse( line + SZ( "Po" ), &data );
+ BIU pos_y = biuParse( data, &data );
+ BIU width = biuParse( data, &data );
+ BIU height = biuParse( data, &data );
+ BIU thickn = biuParse( data, &data );
+ double orient = degParse( data, &data );
+ char* mirror = strtok_r( (char*) data, delims, &saveptr );
+
+ // This sets both DIMENSION's position and internal m_Text's.
+ // @todo: But why do we even know about internal m_Text?
+ dim->SetPosition( wxPoint( pos_x, pos_y ) );
+ dim->SetTextSize( wxSize( width, height ) );
+
+ dim->Text().SetMirrored( mirror && *mirror == '0' );
+ dim->Text().SetThickness( thickn );
+ dim->Text().SetOrientation( orient );
+ }
+
+ else if( TESTLINE( "Sb" ) )
+ {
+ // sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_crossBarOx, &m_crossBarOy, &m_crossBarFx, &m_crossBarFy, &m_Width );
+
+ int ignore = biuParse( line + SZ( "Sb" ), &data );
+ BIU crossBarOx = biuParse( data, &data );
+ BIU crossBarOy = biuParse( data, &data );
+ BIU crossBarFx = biuParse( data, &data );
+ BIU crossBarFy = biuParse( data, &data );
+ BIU width = biuParse( data );
+
+ dim->m_crossBarO.x = crossBarOx;
+ dim->m_crossBarO.y = crossBarOy;
+ dim->m_crossBarF.x = crossBarFx;
+ dim->m_crossBarF.y = crossBarFy;
+ dim->SetWidth( width );
+ (void) ignore;
+ }
+
+ else if( TESTLINE( "Sd" ) )
+ {
+ // sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_featureLineDOx, &m_featureLineDOy, &m_featureLineDFx, &m_featureLineDFy, &Dummy );
+
+ int ignore = intParse( line + SZ( "Sd" ), &data );
+ BIU featureLineDOx = biuParse( data, &data );
+ BIU featureLineDOy = biuParse( data, &data );
+ BIU featureLineDFx = biuParse( data, &data );
+ BIU featureLineDFy = biuParse( data );
+
+ dim->m_featureLineDO.x = featureLineDOx;
+ dim->m_featureLineDO.y = featureLineDOy;
+ dim->m_featureLineDF.x = featureLineDFx;
+ dim->m_featureLineDF.y = featureLineDFy;
+ (void) ignore;
+ }
+
+ else if( TESTLINE( "Sg" ) )
+ {
+ // sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_featureLineGOx, &m_featureLineGOy, &m_featureLineGFx, &m_featureLineGFy, &Dummy );
+
+ int ignore = intParse( line + SZ( "Sg" ), &data );
+ BIU featureLineGOx = biuParse( data, &data );
+ BIU featureLineGOy = biuParse( data, &data );
+ BIU featureLineGFx = biuParse( data, &data );
+ BIU featureLineGFy = biuParse( data );
+
+ dim->m_featureLineGO.x = featureLineGOx;
+ dim->m_featureLineGO.y = featureLineGOy;
+ dim->m_featureLineGF.x = featureLineGFx;
+ dim->m_featureLineGF.y = featureLineGFy;
+ (void) ignore;
+ }
+
+ else if( TESTLINE( "S1" ) )
+ {
+ // sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_arrowD1Ox, &m_arrowD1Oy, &m_arrowD1Fx, &m_arrowD1Fy, &Dummy );
+
+ int ignore = intParse( line + SZ( "S1" ), &data );
+ biuParse( data, &data ); // skipping excessive data
+ biuParse( data, &data ); // skipping excessive data
+ BIU arrowD1Fx = biuParse( data, &data );
+ BIU arrowD1Fy = biuParse( data );
+
+ dim->m_arrowD1F.x = arrowD1Fx;
+ dim->m_arrowD1F.y = arrowD1Fy;
+ (void) ignore;
+ }
+
+ else if( TESTLINE( "S2" ) )
+ {
+ // sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_arrowD2Ox, &m_arrowD2Oy, &m_arrowD2Fx, &m_arrowD2Fy, &Dummy );
+
+ int ignore = intParse( line + SZ( "S2" ), &data );
+ biuParse( data, &data ); // skipping excessive data
+ biuParse( data, &data ); // skipping excessive data
+ BIU arrowD2Fx = biuParse( data, &data );
+ BIU arrowD2Fy = biuParse( data, &data );
+
+ dim->m_arrowD2F.x = arrowD2Fx;
+ dim->m_arrowD2F.y = arrowD2Fy;
+ (void) ignore;
+ }
+
+ else if( TESTLINE( "S3" ) )
+ {
+ // sscanf( Line + 2, " %d %d %d %d %d %d\n", &Dummy, &m_arrowG1Ox, &m_arrowG1Oy, &m_arrowG1Fx, &m_arrowG1Fy, &Dummy );
+ int ignore = intParse( line + SZ( "S3" ), &data );
+ biuParse( data, &data ); // skipping excessive data
+ biuParse( data, &data ); // skipping excessive data
+ BIU arrowG1Fx = biuParse( data, &data );
+ BIU arrowG1Fy = biuParse( data, &data );
+
+ dim->m_arrowG1F.x = arrowG1Fx;
+ dim->m_arrowG1F.y = arrowG1Fy;
+ (void) ignore;
+ }
+
+ else if( TESTLINE( "S4" ) )
+ {
+ // sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_arrowG2Ox, &m_arrowG2Oy, &m_arrowG2Fx, &m_arrowG2Fy, &Dummy );
+ int ignore = intParse( line + SZ( "S4" ), &data );
+ biuParse( data, &data ); // skipping excessive data
+ biuParse( data, &data ); // skipping excessive data
+ BIU arrowG2Fx = biuParse( data, &data );
+ BIU arrowG2Fy = biuParse( data, &data );
+
+ dim->m_arrowG2F.x = arrowG2Fx;
+ dim->m_arrowG2F.y = arrowG2Fy;
+ (void) ignore;
+ }
+ }
+
+ THROW_IO_ERROR( "Missing '$endCOTATION'" );
+}
+
+
+void LEGACY_PLUGIN::loadPCB_TARGET()
+{
+ char* line;
+
+ while( ( line = READLINE( m_reader ) ) != NULL )
+ {
+ const char* data;
+
+ if( TESTLINE( "$EndPCB_TARGET" ) || TESTLINE( "$EndMIREPCB" ) )
+ {
+ return; // preferred exit
+ }
+
+ else if( TESTLINE( "Po" ) )
+ {
+ // sscanf( Line + 2, " %X %d %d %d %d %d %lX", &m_Shape, &m_Layer, &m_Pos.x, &m_Pos.y, &m_Size, &m_Width, &m_TimeStamp );
+
+ int shape = intParse( line + SZ( "Po" ), &data );
+
+ LAYER_NUM layer_num = layerParse( data, &data );
+
+ BIU pos_x = biuParse( data, &data );
+ BIU pos_y = biuParse( data, &data );
+ BIU size = biuParse( data, &data );
+ BIU width = biuParse( data, &data );
+ time_t timestamp = hexParse( data );
+
+ if( layer_num < FIRST_NON_COPPER_LAYER )
+ layer_num = FIRST_NON_COPPER_LAYER;
+
+ else if( layer_num > LAST_NON_COPPER_LAYER )
+ layer_num = LAST_NON_COPPER_LAYER;
+
+ PCB_TARGET* t = new PCB_TARGET( m_board, shape, leg_layer2new( m_cu_count, layer_num ),
+ wxPoint( pos_x, pos_y ), size, width );
+ m_board->Add( t, ADD_APPEND );
+
+ t->SetTimeStamp( timestamp );
+ }
+ }
+
+ THROW_IO_ERROR( "Missing '$EndDIMENSION'" );
+}
+
+
+BIU LEGACY_PLUGIN::biuParse( const char* aValue, const char** nptrptr )
+{
+ char* nptr;
+
+ errno = 0;
+
+ double fval = strtod( aValue, &nptr );
+
+ if( errno )
+ {
+ m_error.Printf( _( "invalid float number in file: '%s'\nline: %d, offset: %d" ),
+ m_reader->GetSource().GetData(),
+ m_reader->LineNumber(), aValue - m_reader->Line() + 1 );
+
+ THROW_IO_ERROR( m_error );
+ }
+
+ if( aValue == nptr )
+ {
+ m_error.Printf( _( "missing float number in file: '%s'\nline: %d, offset: %d" ),
+ m_reader->GetSource().GetData(),
+ m_reader->LineNumber(), aValue - m_reader->Line() + 1 );
+
+ THROW_IO_ERROR( m_error );
+ }
+
+ if( nptrptr )
+ *nptrptr = nptr;
+
+ fval *= diskToBiu;
+
+ // fval is up into the whole number realm here, and should be bounded
+ // within INT_MIN to INT_MAX since BIU's are nanometers.
+ return KiROUND( fval );
+}
+
+
+double LEGACY_PLUGIN::degParse( const char* aValue, const char** nptrptr )
+{
+ char* nptr;
+
+ errno = 0;
+
+ double fval = strtod( aValue, &nptr );
+
+ if( errno )
+ {
+ m_error.Printf( _( "invalid float number in file: '%s'\nline: %d, offset: %d" ),
+ m_reader->GetSource().GetData(), m_reader->LineNumber(), aValue - m_reader->Line() + 1 );
+
+ THROW_IO_ERROR( m_error );
+ }
+
+ if( aValue == nptr )
+ {
+ m_error.Printf( _( "missing float number in file: '%s'\nline: %d, offset: %d" ),
+ m_reader->GetSource().GetData(), m_reader->LineNumber(), aValue - m_reader->Line() + 1 );
+
+ THROW_IO_ERROR( m_error );
+ }
+
+ if( nptrptr )
+ *nptrptr = nptr;
+
+ return fval;
+}
+
+
+void LEGACY_PLUGIN::init( const PROPERTIES* aProperties )
+{
+ m_loading_format_version = 0;
+ m_cu_count = 16;
+ m_board = NULL;
+ m_props = aProperties;
+
+ // conversion factor for saving RAM BIUs to KICAD legacy file format.
+ biuToDisk = 1.0/IU_PER_MM; // BIUs are nanometers & file is mm
+
+ // Conversion factor for loading KICAD legacy file format into BIUs in RAM
+ // Start by assuming the *.brd file is in deci-mils.
+ // If we see "Units mm" in the $GENERAL section, set diskToBiu to 1000000.0
+ // then, during the file loading process, to start a conversion from
+ // mm to nanometers. The deci-mil legacy files have no such "Units" marker
+ // so we must assume the file is in deci-mils until told otherwise.
+
+ diskToBiu = IU_PER_DECIMILS; // BIUs are nanometers
+}
+
+
+void LEGACY_PLUGIN::SaveModule3D( const MODULE* me ) const
+{
+ for( S3D_MASTER* t3D = me->Models(); t3D; t3D = t3D->Next() )
+ {
+ if( !t3D->GetShape3DName().IsEmpty() )
+ {
+ fprintf( m_fp, "$SHAPE3D\n" );
+
+ fprintf( m_fp, "Na %s\n", EscapedUTF8( t3D->GetShape3DName() ).c_str() );
+
+ fprintf(m_fp,
+#if defined(DEBUG)
+ // use old formats for testing, just to verify compatibility
+ // using "diff", then switch to more concise form for release builds.
+ "Sc %lf %lf %lf\n",
+#else
+ "Sc %.10g %.10g %.10g\n",
+#endif
+ t3D->m_MatScale.x,
+ t3D->m_MatScale.y,
+ t3D->m_MatScale.z );
+
+ fprintf(m_fp,
+#if defined(DEBUG)
+ "Of %lf %lf %lf\n",
+#else
+ "Of %.10g %.10g %.10g\n",
+#endif
+ t3D->m_MatPosition.x,
+ t3D->m_MatPosition.y,
+ t3D->m_MatPosition.z );
+
+ fprintf(m_fp,
+#if defined(DEBUG)
+ "Ro %lf %lf %lf\n",
+#else
+ "Ro %.10g %.10g %.10g\n",
+#endif
+ t3D->m_MatRotation.x,
+ t3D->m_MatRotation.y,
+ t3D->m_MatRotation.z );
+
+ fprintf( m_fp, "$EndSHAPE3D\n" );
+ }
+ }
+}
+
+
+#if 0
+
+//-----<BOARD Save Functions>---------------------------------------------------
+
+#define SPBUFZ 50 // wire all usages of this together.
+
+int LEGACY_PLUGIN::biuSprintf( char* buf, BIU aValue ) const
+{
+ double engUnits = biuToDisk * aValue;
+ int len;
+
+ if( engUnits != 0.0 && fabsl( engUnits ) <= 0.0001 )
+ {
+ len = snprintf( buf, SPBUFZ, "%.10f", engUnits );
+
+ while( --len > 0 && buf[len] == '0' )
+ buf[len] = '\0';
+
+ ++len;
+ }
+ else
+ {
+ // The %.10g is about optimal since we are dealing with a bounded
+ // range on aValue, and we can be sure that there will never
+ // be a reason to have more than 6 digits to the right of the
+ // decimal point because we are converting from integer
+ // (signed whole numbers) nanometers to mm. A value of
+ // 0.000001 is one nanometer, the smallest positive nonzero value
+ // that we can ever have here. If you ever see a board file with
+ // more digits to the right of the decimal point than 6, this is a
+ // possibly a bug in a formatting string nearby.
+ len = snprintf( buf, SPBUFZ, "%.10g", engUnits );
+ }
+ return len;
+}
+
+
+std::string LEGACY_PLUGIN::fmtBIU( BIU aValue ) const
+{
+ char temp[SPBUFZ];
+
+ int len = biuSprintf( temp, aValue );
+
+ return std::string( temp, len );
+}
+
+
+std::string LEGACY_PLUGIN::fmtDEG( double aAngle ) const
+{
+ char temp[50];
+
+ // @todo a hook site to convert from tenths degrees to degrees for BOARD_FORMAT_VERSION 2.
+
+ // MINGW: snprintf() comes from gcc folks, sprintf() comes from Microsoft.
+ int len = snprintf( temp, sizeof( temp ), "%.10g", aAngle );
+
+ return std::string( temp, len );
+}
+
+
+std::string LEGACY_PLUGIN::fmtBIUPair( BIU first, BIU second ) const
+{
+ char temp[2*SPBUFZ+2];
+ char* cp = temp;
+
+ cp += biuSprintf( cp, first );
+
+ *cp++ = ' ';
+
+ cp += biuSprintf( cp, second );
+
+ return std::string( temp, cp - temp );
+}
+
+void LEGACY_PLUGIN::Save( const wxString& aFileName, BOARD* aBoard, const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ init( aProperties );
+
+ FILE* fp = wxFopen( aFileName, wxT( "w" ) );
+ if( !fp )
+ {
+ m_error.Printf( _( "Unable to open file '%s'" ), aFileName.GetData() );
+ THROW_IO_ERROR( m_error );
+ }
+
+ m_filename = aFileName;
+
+ // wxf now owns fp, will close on exception or return
+ wxFFile wxf( fp );
+
+ m_fp = fp; // member function accessibility
+
+ wxString header = wxString::Format(
+ wxT( "PCBNEW-BOARD Version %d date %s\n\n# Created by Pcbnew%s\n\n" ),
+ LEGACY_BOARD_FILE_VERSION, DateAndTime().GetData(),
+ GetBuildVersion().GetData() );
+
+ // save a file header, if caller provided one (with trailing \n hopefully).
+ fprintf( m_fp, "%s", TO_UTF8( header ) );
+
+ SaveBOARD( aBoard );
+}
+
+
+wxString LEGACY_PLUGIN::writeError() const
+{
+ return wxString::Format( _( "error writing to file '%s'" ), m_filename.GetData() );
+}
+
+#define CHECK_WRITE_ERROR() \
+do { \
+ if( ferror( m_fp ) ) \
+ { \
+ THROW_IO_ERROR( writeError() ); \
+ } \
+} while(0)
+
+
+// With the advent of the LSET expansion it was agreed to abort the legacy save since
+// we'd have to expand the old format in order to suppor the new LAYER_IDs.
+
+void LEGACY_PLUGIN::SaveBOARD( const BOARD* aBoard ) const
+{
+ m_mapping->SetBoard( aBoard );
+
+ saveGENERAL( aBoard );
+
+ saveSHEET( aBoard );
+
+ saveSETUP( aBoard );
+
+ saveBOARD_ITEMS( aBoard );
+}
+
+
+void LEGACY_PLUGIN::saveGENERAL( const BOARD* aBoard ) const
+{
+ fprintf( m_fp, "$GENERAL\n" );
+ fprintf( m_fp, "encoding utf-8\n" );
+
+ // tell folks the units used within the file, as early as possible here.
+ fprintf( m_fp, "Units mm\n" );
+
+ // Write copper layer count
+ fprintf( m_fp, "LayerCount %d\n", aBoard->GetCopperLayerCount() );
+
+ /* No, EnabledLayers has this information, plus g_TabAllCopperLayerMask is
+ global and globals are not allowed in a plugin.
+ fprintf( m_fp,
+ "Ly %8X\n",
+ g_TabAllCopperLayerMask[NbLayers - 1] | ALL_NO_CU_LAYERS );
+ */
+
+ fprintf( m_fp, "EnabledLayers %08X\n", aBoard->GetEnabledLayers() );
+
+ if( aBoard->GetEnabledLayers() != aBoard->GetVisibleLayers() )
+ fprintf( m_fp, "VisibleLayers %08X\n", aBoard->GetVisibleLayers() );
+
+ fprintf( m_fp, "Links %d\n", aBoard->GetRatsnestsCount() );
+ fprintf( m_fp, "NoConn %d\n", aBoard->GetUnconnectedNetCount() );
+
+ // Write Bounding box info
+ EDA_RECT bbbox = ((BOARD*)aBoard)->ComputeBoundingBox();
+
+ fprintf( m_fp, "Di %s %s\n",
+ fmtBIUPair( bbbox.GetX(), bbbox.GetY() ).c_str(),
+ fmtBIUPair( bbbox.GetRight(), bbbox.GetBottom() ).c_str() );
+
+ fprintf( m_fp, "Ndraw %d\n", aBoard->m_Drawings.GetCount() );
+ fprintf( m_fp, "Ntrack %d\n", aBoard->GetNumSegmTrack() );
+ fprintf( m_fp, "Nzone %d\n", aBoard->GetNumSegmZone() );
+ fprintf( m_fp, "BoardThickness %s\n", fmtBIU( aBoard->GetDesignSettings().GetBoardThickness() ).c_str() );
+ fprintf( m_fp, "Nmodule %d\n", aBoard->m_Modules.GetCount() );
+ fprintf( m_fp, "Nnets %d\n", m_mapping->GetSize() );
+ fprintf( m_fp, "$EndGENERAL\n\n" );
+}
+
+
+void LEGACY_PLUGIN::saveSHEET( const BOARD* aBoard ) const
+{
+ const PAGE_INFO& pageInfo = aBoard->GetPageSettings();
+ const TITLE_BLOCK& tb = ((BOARD*)aBoard)->GetTitleBlock();
+
+ fprintf( m_fp, "$SHEETDESCR\n" );
+
+ // paper is described in mils
+ fprintf( m_fp, "Sheet %s %d %d%s\n",
+ TO_UTF8( pageInfo.GetType() ),
+ pageInfo.GetWidthMils(),
+ pageInfo.GetHeightMils(),
+ !pageInfo.IsCustom() && pageInfo.IsPortrait() ?
+ " portrait" : ""
+ );
+
+ fprintf( m_fp, "Title %s\n", EscapedUTF8( tb.GetTitle() ).c_str() );
+ fprintf( m_fp, "Date %s\n", EscapedUTF8( tb.GetDate() ).c_str() );
+ fprintf( m_fp, "Rev %s\n", EscapedUTF8( tb.GetRevision() ).c_str() );
+ fprintf( m_fp, "Comp %s\n", EscapedUTF8( tb.GetCompany() ).c_str() );
+ fprintf( m_fp, "Comment1 %s\n", EscapedUTF8( tb.GetComment1() ).c_str() );
+ fprintf( m_fp, "Comment2 %s\n", EscapedUTF8( tb.GetComment2() ).c_str() );
+ fprintf( m_fp, "Comment3 %s\n", EscapedUTF8( tb.GetComment3() ).c_str() );
+ fprintf( m_fp, "Comment4 %s\n", EscapedUTF8( tb.GetComment4() ).c_str() );
+ fprintf( m_fp, "$EndSHEETDESCR\n\n" );
+}
+
+
+void LEGACY_PLUGIN::saveSETUP( const BOARD* aBoard ) const
+{
+ const BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings();
+ NETCLASSPTR netclass_default = bds.GetDefault();
+
+ fprintf( m_fp, "$SETUP\n" );
+
+ /* Internal units are nobody's business, they are internal.
+ Units used in the file are now in the "Units" attribute of $GENERAL.
+ fprintf( m_fp,, "InternalUnit %f INCH\n", 1.0 / PCB_LEGACY_INTERNAL_UNIT );
+ */
+
+ fprintf( m_fp, "Layers %d\n", aBoard->GetCopperLayerCount() );
+
+ unsigned layerMask = ALL_CU_LAYERS & aBoard->GetEnabledLayers();
+
+ for( LAYER_NUM layer = FIRST_LAYER; layer <= LAST_COPPER_LAYER; ++layer )
+ {
+ if( layerMask & MASK( layer ) )
+ {
+ fprintf( m_fp, "Layer[%d] %s %s\n", layer,
+ TO_UTF8( aBoard->GetLayerName( layer ) ),
+ LAYER::ShowType( aBoard->GetLayerType( layer ) ) );
+ }
+ }
+
+ // Save current default track width, for compatibility with older Pcbnew version;
+ fprintf( m_fp, "TrackWidth %s\n",
+ fmtBIU( aBoard->GetDesignSettings().GetCurrentTrackWidth() ).c_str() );
+
+ // Save custom tracks width list (the first is not saved here: this is the netclass value
+ for( unsigned ii = 1; ii < aBoard->GetDesignSettings().m_TrackWidthList.size(); ii++ )
+ fprintf( m_fp, "TrackWidthList %s\n", fmtBIU( aBoard->GetDesignSettings().m_TrackWidthList[ii] ).c_str() );
+
+ fprintf( m_fp, "TrackClearence %s\n", fmtBIU( netclass_default->GetClearance() ).c_str() );
+
+ // ZONE_SETTINGS
+ fprintf( m_fp, "ZoneClearence %s\n", fmtBIU( aBoard->GetZoneSettings().m_ZoneClearance ).c_str() );
+ fprintf( m_fp, "Zone_45_Only %d\n", aBoard->GetZoneSettings().m_Zone_45_Only );
+
+ fprintf( m_fp, "TrackMinWidth %s\n", fmtBIU( bds.m_TrackMinWidth ).c_str() );
+
+ fprintf( m_fp, "DrawSegmWidth %s\n", fmtBIU( bds.m_DrawSegmentWidth ).c_str() );
+ fprintf( m_fp, "EdgeSegmWidth %s\n", fmtBIU( bds.m_EdgeSegmentWidth ).c_str() );
+
+ // Save current default via size, for compatibility with older Pcbnew version;
+ fprintf( m_fp, "ViaSize %s\n", fmtBIU( netclass_default->GetViaDiameter() ).c_str() );
+ fprintf( m_fp, "ViaDrill %s\n", fmtBIU( netclass_default->GetViaDrill() ).c_str() );
+ fprintf( m_fp, "ViaMinSize %s\n", fmtBIU( bds.m_ViasMinSize ).c_str() );
+ fprintf( m_fp, "ViaMinDrill %s\n", fmtBIU( bds.m_ViasMinDrill ).c_str() );
+
+ // Save custom vias diameters list (the first is not saved here: this is
+ // the netclass value
+ for( unsigned ii = 1; ii < aBoard->GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
+ fprintf( m_fp, "ViaSizeList %s %s\n",
+ fmtBIU( aBoard->GetDesignSettings().m_ViasDimensionsList[ii].m_Diameter ).c_str(),
+ fmtBIU( aBoard->GetDesignSettings().m_ViasDimensionsList[ii].m_Drill ).c_str() );
+
+ // for old versions compatibility:
+ fprintf( m_fp, "MicroViaSize %s\n", fmtBIU( netclass_default->GetuViaDiameter() ).c_str() );
+ fprintf( m_fp, "MicroViaDrill %s\n", fmtBIU( netclass_default->GetuViaDrill() ).c_str() );
+ fprintf( m_fp, "MicroViasAllowed %s\n", fmtBIU( bds.m_MicroViasAllowed ).c_str() );
+ fprintf( m_fp, "MicroViaMinSize %s\n", fmtBIU( bds.m_MicroViasMinSize ).c_str() );
+ fprintf( m_fp, "MicroViaMinDrill %s\n", fmtBIU( bds.m_MicroViasMinDrill ).c_str() );
+
+ fprintf( m_fp, "TextPcbWidth %s\n", fmtBIU( bds.m_PcbTextWidth ).c_str() );
+ fprintf( m_fp, "TextPcbSize %s\n", fmtBIUSize( bds.m_PcbTextSize ).c_str() );
+
+ fprintf( m_fp, "EdgeModWidth %s\n", fmtBIU( bds.m_ModuleSegmentWidth ).c_str() );
+ fprintf( m_fp, "TextModSize %s\n", fmtBIUSize( bds.m_ModuleTextSize ).c_str() );
+ fprintf( m_fp, "TextModWidth %s\n", fmtBIU( bds.m_ModuleTextWidth ).c_str() );
+
+ fprintf( m_fp, "PadSize %s\n", fmtBIUSize( bds.m_Pad_Master.GetSize() ).c_str() );
+ fprintf( m_fp, "PadDrill %s\n", fmtBIU( bds.m_Pad_Master.GetDrillSize().x ).c_str() );
+
+ fprintf( m_fp, "Pad2MaskClearance %s\n", fmtBIU( bds.m_SolderMaskMargin ).c_str() );
+ fprintf( m_fp, "SolderMaskMinWidth %s\n", fmtBIU( bds.m_SolderMaskMinWidth ).c_str() );
+
+ if( bds.m_SolderPasteMargin != 0 )
+ fprintf( m_fp, "Pad2PasteClearance %s\n", fmtBIU( bds.m_SolderPasteMargin ).c_str() );
+
+ if( bds.m_SolderPasteMarginRatio != 0 )
+ fprintf( m_fp, "Pad2PasteClearanceRatio %g\n", bds.m_SolderPasteMarginRatio );
+
+ fprintf( m_fp, "GridOrigin %s\n", fmtBIUPoint( aBoard->GetGridOrigin() ).c_str() );
+ fprintf( m_fp, "AuxiliaryAxisOrg %s\n", fmtBIUPoint( aBoard->GetAuxOrigin() ).c_str() );
+
+ fprintf( m_fp, "VisibleElements %X\n", bds.GetVisibleElements() );
+
+ {
+ STRING_FORMATTER sf;
+
+ aBoard->GetPlotOptions().Format( &sf, 0 );
+
+ wxString record = FROM_UTF8( sf.GetString().c_str() );
+
+ record.Replace( wxT("\n"), wxT(""), true );
+ record.Replace( wxT(" "), wxT(" "), true);
+
+ fprintf( m_fp, "PcbPlotParams %s\n", TO_UTF8( record ) );
+ }
+
+ fprintf( m_fp, "$EndSETUP\n\n" );
+}
+
+
+void LEGACY_PLUGIN::saveBOARD_ITEMS( const BOARD* aBoard ) const
+{
+ // save the nets
+ for( NETINFO_MAPPING::iterator net = m_mapping->begin(), netEnd = m_mapping->end();
+ net != netEnd; ++net )
+ {
+ saveNETINFO_ITEM( *net );
+ }
+
+ // Saved nets do not include netclass names, so save netclasses after nets.
+ saveNETCLASSES( &aBoard->GetDesignSettings().m_NetClasses );
+
+ // save the modules
+ for( MODULE* m = aBoard->m_Modules; m; m = (MODULE*) m->Next() )
+ saveMODULE( m );
+
+ // save the graphics owned by the board (not owned by a module)
+ for( BOARD_ITEM* gr = aBoard->m_Drawings; gr; gr = gr->Next() )
+ {
+ switch( gr->Type() )
+ {
+ case PCB_TEXT_T:
+ savePCB_TEXT( (TEXTE_PCB*) gr );
+ break;
+ case PCB_LINE_T:
+ savePCB_LINE( (DRAWSEGMENT*) gr );
+ break;
+ case PCB_TARGET_T:
+ savePCB_TARGET( (PCB_TARGET*) gr );
+ break;
+ case PCB_DIMENSION_T:
+ saveDIMENSION( (DIMENSION*) gr );
+ break;
+ default:
+ THROW_IO_ERROR( wxString::Format( UNKNOWN_GRAPHIC_FORMAT, gr->Type() ) );
+ }
+ }
+
+ // do not save MARKER_PCBs, they can be regenerated easily
+
+ // save the tracks & vias
+ fprintf( m_fp, "$TRACK\n" );
+ for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
+ saveTRACK( track );
+ fprintf( m_fp, "$EndTRACK\n" );
+
+ // save the old obsolete zones which were done by segments (tracks)
+ fprintf( m_fp, "$ZONE\n" );
+ for( SEGZONE* zone = aBoard->m_Zone; zone; zone = zone->Next() )
+ saveTRACK( zone );
+ fprintf( m_fp, "$EndZONE\n" );
+
+ // save the polygon (which are the newer technology) zones
+ for( int i=0; i < aBoard->GetAreaCount(); ++i )
+ saveZONE_CONTAINER( aBoard->GetArea( i ) );
+
+ fprintf( m_fp, "$EndBOARD\n" );
+
+ CHECK_WRITE_ERROR();
+}
+
+
+void LEGACY_PLUGIN::saveNETINFO_ITEM( const NETINFO_ITEM* aNet ) const
+{
+ fprintf( m_fp, "$EQUIPOT\n" );
+ fprintf( m_fp, "Na %d %s\n", m_mapping->Translate( aNet->GetNet() ),
+ EscapedUTF8( aNet->GetNetname() ).c_str() );
+ fprintf( m_fp, "St %s\n", "~" );
+ fprintf( m_fp, "$EndEQUIPOT\n" );
+
+ CHECK_WRITE_ERROR();
+}
+
+
+void LEGACY_PLUGIN::saveNETCLASSES( const NETCLASSES* aNetClasses ) const
+{
+ // save the default first.
+ saveNETCLASS( aNetClasses->GetDefault() );
+
+ // the rest will be alphabetical in the *.brd file.
+ for( NETCLASSES::const_iterator it = aNetClasses->begin(); it != aNetClasses->end(); ++it )
+ {
+ NETCLASSPTR netclass = it->second;
+ saveNETCLASS( netclass );
+ }
+
+ CHECK_WRITE_ERROR();
+}
+
+
+void LEGACY_PLUGIN::saveNETCLASS( const NETCLASSPTR nc ) const
+{
+ fprintf( m_fp, "$NCLASS\n" );
+ fprintf( m_fp, "Name %s\n", EscapedUTF8( nc->GetName() ).c_str() );
+ fprintf( m_fp, "Desc %s\n", EscapedUTF8( nc->GetDescription() ).c_str() );
+
+ fprintf( m_fp, "Clearance %s\n", fmtBIU( nc->GetClearance() ).c_str() );
+ fprintf( m_fp, "TrackWidth %s\n", fmtBIU( nc->GetTrackWidth() ).c_str() );
+
+ fprintf( m_fp, "ViaDia %s\n", fmtBIU( nc->GetViaDiameter() ).c_str() );
+ fprintf( m_fp, "ViaDrill %s\n", fmtBIU( nc->GetViaDrill() ).c_str() );
+
+ fprintf( m_fp, "uViaDia %s\n", fmtBIU( nc->GetuViaDiameter() ).c_str() );
+ fprintf( m_fp, "uViaDrill %s\n", fmtBIU( nc->GetuViaDrill() ).c_str() );
+
+ for( NETCLASS::const_iterator it = nc->begin(); it!=nc->end(); ++it )
+ fprintf( m_fp, "AddNet %s\n", EscapedUTF8( *it ).c_str() );
+
+ fprintf( m_fp, "$EndNCLASS\n" );
+
+ CHECK_WRITE_ERROR();
+}
+
+
+void LEGACY_PLUGIN::saveMODULE_TEXT( const TEXTE_MODULE* me ) const
+{
+ MODULE* parent = (MODULE*) me->GetParent();
+ double orient = me->GetOrientation();
+
+ // Due to the Pcbnew history, m_Orient is saved in screen value
+ // but it is handled as relative to its parent footprint
+ if( parent )
+ orient += parent->GetOrientation();
+
+ wxString txt = me->GetText();
+
+ fprintf( m_fp, "T%d %s %s %s %s %c %c %d %c %s",
+ me->GetType(),
+ fmtBIUPoint( me->GetPos0() ).c_str(), // m_Pos0.x, m_Pos0.y,
+
+ // legacy has goofed reversed order: ( y, x )
+ fmtBIUPair( me->GetSize().y, me->GetSize().x ).c_str(),
+
+ fmtDEG( orient ).c_str(),
+ fmtBIU( me->GetThickness() ).c_str(), // m_Thickness,
+ me->IsMirrored() ? 'M' : 'N',
+ me->IsVisible() ? 'V' : 'I',
+ me->GetLayer(),
+ me->IsItalic() ? 'I' : 'N',
+ EscapedUTF8( txt ).c_str()
+ );
+
+ if( me->GetHorizJustify() != GR_TEXT_HJUSTIFY_CENTER ||
+ me->GetVertJustify() != GR_TEXT_VJUSTIFY_CENTER )
+ {
+ fprintf( m_fp, " %s %s\n",
+ ShowHorizJustify( me->GetHorizJustify() ),
+ ShowVertJustify( me->GetVertJustify() )
+ );
+ }
+ else
+ fprintf( m_fp, "\n" );
+
+ CHECK_WRITE_ERROR();
+}
+
+
+void LEGACY_PLUGIN::saveMODULE_EDGE( const EDGE_MODULE* me ) const
+{
+ switch( me->GetShape() )
+ {
+ case S_SEGMENT:
+ fprintf( m_fp, "DS %s %s %s %d\n",
+ fmtBIUPoint( me->m_Start0 ).c_str(),
+ fmtBIUPoint( me->m_End0 ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str(),
+ me->GetLayer() );
+ break;
+
+ case S_CIRCLE:
+ fprintf( m_fp, "DC %s %s %s %d\n",
+ fmtBIUPoint( me->m_Start0 ).c_str(),
+ fmtBIUPoint( me->m_End0 ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str(),
+ me->GetLayer() );
+ break;
+
+ case S_ARC:
+ fprintf( m_fp, "DA %s %s %s %s %d\n",
+ fmtBIUPoint( me->m_Start0 ).c_str(),
+ fmtBIUPoint( me->m_End0 ).c_str(),
+ fmtDEG( me->GetAngle() ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str(),
+ me->GetLayer() );
+ break;
+
+ case S_POLYGON:
+ {
+ const std::vector<wxPoint>& polyPoints = me->GetPolyPoints();
+
+ fprintf( m_fp, "DP %s %s %d %s %d\n",
+ fmtBIUPoint( me->m_Start0 ).c_str(),
+ fmtBIUPoint( me->m_End0 ).c_str(),
+ (int) polyPoints.size(),
+ fmtBIU( me->GetWidth() ).c_str(),
+ me->GetLayer() );
+
+ for( unsigned i = 0; i<polyPoints.size(); ++i )
+ fprintf( m_fp, "Dl %s\n", fmtBIUPoint( polyPoints[i] ).c_str() );
+ }
+ break;
+
+ default:
+ THROW_IO_ERROR( wxString::Format( UNKNOWN_GRAPHIC_FORMAT, me->GetShape() ) );
+ }
+
+ CHECK_WRITE_ERROR();
+}
+
+
+void LEGACY_PLUGIN::savePAD( const D_PAD* me ) const
+{
+ fprintf( m_fp, "$PAD\n" );
+
+ int cshape;
+
+ switch( me->GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE: cshape = 'C'; break;
+ case PAD_SHAPE_RECT: cshape = 'R'; break;
+ case PAD_SHAPE_OVAL: cshape = 'O'; break;
+ case PAD_SHAPE_TRAPEZOID: cshape = 'T'; break;
+
+ default:
+ THROW_IO_ERROR( wxString::Format( UNKNOWN_PAD_FORMAT, me->GetShape() ) );
+ }
+
+#if BOARD_FORMAT_VERSION == 1 // saving mode is a compile time option
+
+ wxString wpadname = me->GetPadName(); // universal character set padname
+ std::string spadname;
+
+ for( unsigned i = 0; wpadname.size(); ++i )
+ {
+ // truncate from universal character down to 8 bit foreign jibber
+ // jabber byte. This basically duplicates what was done in the old
+ // BOARD_FORMAT_VERSION 1 code. Any characters that were in the 8 bit
+ // character space were OK.
+ spadname += (char) wpadname[i];
+ }
+
+ fprintf( m_fp, "Sh \"%s\" %c %s %s %s\n",
+ spadname.c_str(), // probably ASCII, but possibly jibber jabber
+#else
+
+ fprintf( m_fp, "Sh %s %c %s %s %s\n",
+ // legacy VERSION 2 simply uses UTF8, wrapped in quotes,
+ // and 99.99 % of the time there is no difference between 1 & 2,
+ // since ASCII is a subset of UTF8. But if they were not using
+ // ASCII pad names, then there is a difference in the file.
+ EscapedUTF8( me->GetPadName() ).c_str(),
+#endif
+ cshape,
+ fmtBIUSize( me->GetSize() ).c_str(),
+ fmtBIUSize( me->GetDelta() ).c_str(),
+ fmtDEG( me->GetOrientation() ).c_str() );
+
+ fprintf( m_fp, "Dr %s %s",
+ fmtBIU( me->GetDrillSize().x ).c_str(),
+ fmtBIUPoint( me->GetOffset() ).c_str() );
+
+ if( me->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG )
+ {
+ fprintf( m_fp, " %c %s", 'O', fmtBIUSize( me->GetDrillSize() ).c_str() );
+ }
+
+ fprintf( m_fp, "\n" );
+
+ const char* texttype;
+
+ switch( me->GetAttribute() )
+ {
+ case PAD_ATTRIB_STANDARD: texttype = "STD"; break;
+ case PAD_ATTRIB_SMD: texttype = "SMD"; break;
+ case PAD_ATTRIB_CONN: texttype = "CONN"; break;
+ case PAD_ATTRIB_HOLE_NOT_PLATED: texttype = "HOLE"; break;
+
+ default:
+ THROW_IO_ERROR( wxString::Format( UNKNOWN_PAD_ATTRIBUTE, me->GetAttribute() ) );
+ }
+
+ fprintf( m_fp, "At %s N %08X\n", texttype, me->GetLayerSet() );
+
+ fprintf( m_fp, "Ne %d %s\n", m_mapping->Translate( me->GetNetCode() ),
+ EscapedUTF8( me->GetNetname() ).c_str() );
+
+ fprintf( m_fp, "Po %s\n", fmtBIUPoint( me->GetPos0() ).c_str() );
+
+ if( me->GetPadToDieLength() != 0 )
+ fprintf( m_fp, "Le %s\n", fmtBIU( me->GetPadToDieLength() ).c_str() );
+
+ if( me->GetLocalSolderMaskMargin() != 0 )
+ fprintf( m_fp, ".SolderMask %s\n", fmtBIU( me->GetLocalSolderMaskMargin() ).c_str() );
+
+ if( me->GetLocalSolderPasteMargin() != 0 )
+ fprintf( m_fp, ".SolderPaste %s\n", fmtBIU( me->GetLocalSolderPasteMargin() ).c_str() );
+
+ double ratio = me->GetLocalSolderPasteMarginRatio();
+ if( ratio != 0.0 )
+ fprintf( m_fp, ".SolderPasteRatio %g\n", ratio );
+
+ if( me->GetLocalClearance() != 0 )
+ fprintf( m_fp, ".LocalClearance %s\n", fmtBIU( me->GetLocalClearance( ) ).c_str() );
+
+ if( me->GetZoneConnection() != PAD_ZONE_CONN_INHERITED )
+ fprintf( m_fp, ".ZoneConnection %d\n", me->GetZoneConnection() );
+
+ if( me->GetThermalWidth() != 0 )
+ fprintf( m_fp, ".ThermalWidth %s\n", fmtBIU( me->GetThermalWidth() ).c_str() );
+
+ if( me->GetThermalGap() != 0 )
+ fprintf( m_fp, ".ThermalGap %s\n", fmtBIU( me->GetThermalGap() ).c_str() );
+
+ fprintf( m_fp, "$EndPAD\n" );
+
+ CHECK_WRITE_ERROR();
+}
+
+
+void LEGACY_PLUGIN::saveMODULE( const MODULE* me ) const
+{
+ char statusTxt[3];
+ double orient = me->GetOrientation();
+
+ // Do not save full FPID. Only the footprint name. The legacy file format should
+ // never support FPIDs.
+ fprintf( m_fp, "$MODULE %s\n", me->GetFPID().GetFootprintName().c_str() );
+
+ statusTxt[0] = me->IsLocked() ? 'F' : '~';
+ statusTxt[1] = me->IsPlaced() ? 'P' : '~';
+ statusTxt[2] = '\0';
+
+ fprintf( m_fp, "Po %s %s %d %08lX %08lX %s\n",
+ fmtBIUPoint( me->GetPosition() ).c_str(), // m_Pos.x, m_Pos.y,
+ fmtDEG( orient ).c_str(),
+ me->GetLayer(),
+ me->GetLastEditTime(),
+ me->GetTimeStamp(),
+ statusTxt );
+
+ fprintf( m_fp, "Li %s\n", me->GetFPID().GetFootprintName().c_str() );
+
+ if( !me->GetDescription().IsEmpty() )
+ {
+ fprintf( m_fp, "Cd %s\n", TO_UTF8( me->GetDescription() ) );
+ }
+
+ if( !me->GetKeywords().IsEmpty() )
+ {
+ fprintf( m_fp, "Kw %s\n", TO_UTF8( me->GetKeywords() ) );
+ }
+
+ fprintf( m_fp, "Sc %lX\n", me->GetTimeStamp() );
+ fprintf( m_fp, "AR %s\n", TO_UTF8( me->GetPath() ) );
+ fprintf( m_fp, "Op %X %X 0\n", me->GetPlacementCost90(), me->GetPlacementCost180() );
+
+ if( me->GetLocalSolderMaskMargin() != 0 )
+ fprintf( m_fp, ".SolderMask %s\n", fmtBIU( me->GetLocalSolderMaskMargin() ).c_str() );
+
+ if( me->GetLocalSolderPasteMargin() != 0 )
+ fprintf( m_fp, ".SolderPaste %s\n", fmtBIU( me->GetLocalSolderPasteMargin() ).c_str() );
+
+ double ratio = me->GetLocalSolderPasteMarginRatio();
+ if( ratio != 0.0 )
+ fprintf( m_fp, ".SolderPasteRatio %g\n", ratio );
+
+ if( me->GetLocalClearance() != 0 )
+ fprintf( m_fp, ".LocalClearance %s\n", fmtBIU( me->GetLocalClearance( ) ).c_str() );
+
+ if( me->GetZoneConnection() != PAD_ZONE_CONN_INHERITED )
+ fprintf( m_fp, ".ZoneConnection %d\n", me->GetZoneConnection() );
+
+ if( me->GetThermalWidth() != 0 )
+ fprintf( m_fp, ".ThermalWidth %s\n", fmtBIU( me->GetThermalWidth() ).c_str() );
+
+ if( me->GetThermalGap() != 0 )
+ fprintf( m_fp, ".ThermalGap %s\n", fmtBIU( me->GetThermalGap() ).c_str() );
+
+ // attributes
+ if( me->GetAttributes() != MOD_DEFAULT )
+ {
+ fprintf( m_fp, "At" );
+
+ if( me->GetAttributes() & MOD_CMS )
+ fprintf( m_fp, " SMD" );
+
+ if( me->GetAttributes() & MOD_VIRTUAL )
+ fprintf( m_fp, " VIRTUAL" );
+
+ fprintf( m_fp, "\n" );
+ }
+
+ saveMODULE_TEXT( &me->Reference() );
+
+ saveMODULE_TEXT( &me->Value() );
+
+ // save drawing elements
+ for( BOARD_ITEM* gr = me->GraphicalItems(); gr; gr = gr->Next() )
+ {
+ switch( gr->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ saveMODULE_TEXT( static_cast<TEXTE_MODULE*>( gr ));
+ break;
+ case PCB_MODULE_EDGE_T:
+ saveMODULE_EDGE( static_cast<EDGE_MODULE*>( gr ));
+ break;
+ default:
+ THROW_IO_ERROR( wxString::Format( UNKNOWN_GRAPHIC_FORMAT, gr->Type() ) );
+ }
+ }
+
+ for( D_PAD* pad = me->Pads(); pad; pad = pad->Next() )
+ savePAD( pad );
+
+ SaveModule3D( me );
+
+ fprintf( m_fp, "$EndMODULE %s\n", me->GetFPID().GetFootprintName().c_str() );
+
+ CHECK_WRITE_ERROR();
+}
+
+
+void LEGACY_PLUGIN::savePCB_TARGET( const PCB_TARGET* me ) const
+{
+ fprintf( m_fp, "$PCB_TARGET\n" );
+
+ fprintf( m_fp, "Po %X %d %s %s %s %lX\n",
+ me->GetShape(),
+ me->GetLayer(),
+ fmtBIUPoint( me->GetPosition() ).c_str(),
+ fmtBIU( me->GetSize() ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str(),
+ me->GetTimeStamp()
+ );
+
+ fprintf( m_fp, "$EndPCB_TARGET\n" );
+
+ CHECK_WRITE_ERROR();
+}
+
+
+void LEGACY_PLUGIN::savePCB_LINE( const DRAWSEGMENT* me ) const
+{
+ fprintf( m_fp, "$DRAWSEGMENT\n" );
+
+ fprintf( m_fp, "Po %d %s %s %s\n",
+ me->GetShape(),
+ fmtBIUPoint( me->GetStart() ).c_str(),
+ fmtBIUPoint( me->GetEnd() ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str()
+ );
+
+ if( me->GetType() != S_CURVE )
+ {
+ fprintf( m_fp, "De %d %d %s %lX %X\n",
+ me->GetLayer(),
+ me->GetType(),
+ fmtDEG( me->GetAngle() ).c_str(),
+ me->GetTimeStamp(),
+ me->GetStatus()
+ );
+ }
+ else
+ {
+ fprintf( m_fp, "De %d %d %s %lX %X %s %s\n",
+ me->GetLayer(),
+ me->GetType(),
+ fmtDEG( me->GetAngle() ).c_str(),
+ me->GetTimeStamp(),
+ me->GetStatus(),
+ fmtBIUPoint( me->GetBezControl1() ).c_str(),
+ fmtBIUPoint( me->GetBezControl2() ).c_str()
+ );
+ }
+
+ fprintf( m_fp, "$EndDRAWSEGMENT\n" );
+}
+
+
+void LEGACY_PLUGIN::saveTRACK( const TRACK* me ) const
+{
+ int type = 0;
+ VIATYPE_T viatype = VIA_NOT_DEFINED;
+ int drill = UNDEFINED_DRILL_DIAMETER;
+
+ if( me->Type() == PCB_VIA_T )
+ {
+ const VIA *via = static_cast<const VIA *>(me);
+ type = 1;
+ viatype = via->GetViaType();
+ drill = via->GetDrill();
+ }
+
+ fprintf(m_fp, "Po %d %s %s %s %s\n",
+ viatype,
+ fmtBIUPoint( me->GetStart() ).c_str(),
+ fmtBIUPoint( me->GetEnd() ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str(),
+ drill == UNDEFINED_DRILL_DIAMETER ?
+ "-1" : fmtBIU( drill ).c_str() );
+
+ fprintf(m_fp, "De %d %d %d %lX %X\n",
+ me->GetLayer(), type, m_mapping->Translate( me->GetNetCode() ),
+ me->GetTimeStamp(), me->GetStatus() );
+}
+
+
+void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const
+{
+ fprintf( m_fp, "$CZONE_OUTLINE\n" );
+
+ // Save the outline main info
+ // For keepout zones, net code and net name are irrelevant, so we store a dummy value
+ // just for ZONE_CONTAINER compatibility
+ fprintf( m_fp, "ZInfo %lX %d %s\n",
+ me->GetTimeStamp(),
+ me->GetIsKeepout() ? 0 : m_mapping->Translate( me->GetNetCode() ),
+ EscapedUTF8( me->GetIsKeepout() ? wxT("") : me->GetNetname() ).c_str() );
+
+ // Save the outline layer info
+ fprintf( m_fp, "ZLayer %d\n", me->GetLayer() );
+
+ // Save the outline aux info
+ int outline_hatch;
+
+ switch( me->GetHatchStyle() )
+ {
+ default:
+ case CPolyLine::NO_HATCH: outline_hatch = 'N'; break;
+ case CPolyLine::DIAGONAL_EDGE: outline_hatch = 'E'; break;
+ case CPolyLine::DIAGONAL_FULL: outline_hatch = 'F'; break;
+ }
+
+ fprintf( m_fp, "ZAux %d %c\n", me->GetNumCorners(), outline_hatch );
+
+ if( me->GetPriority() > 0 )
+ fprintf( m_fp, "ZPriority %d\n", me->GetPriority() );
+
+ // Save pad option and clearance
+ char padoption;
+
+ switch( me->GetPadConnection() )
+ {
+ default:
+ case PAD_ZONE_CONN_FULL: padoption = 'I'; break;
+ case PAD_ZONE_CONN_THERMAL: padoption = 'T'; break;
+ case PAD_ZONE_CONN_THT_THERMAL: padoption = 'H'; break; // H is for 'hole' since it reliefs holes only
+ case PAD_ZONE_CONN_NONE: padoption = 'X'; break;
+ }
+
+ fprintf( m_fp, "ZClearance %s %c\n",
+ fmtBIU( me->GetZoneClearance() ).c_str(),
+ padoption );
+
+ fprintf( m_fp, "ZMinThickness %s\n", fmtBIU( me->GetMinThickness() ).c_str() );
+
+ fprintf( m_fp, "ZOptions %d %d %c %s %s\n",
+ me->GetFillMode(),
+ me->GetArcSegmentCount(),
+ me->IsFilled() ? 'S' : 'F',
+ fmtBIU( me->GetThermalReliefGap() ).c_str(),
+ fmtBIU( me->GetThermalReliefCopperBridge() ).c_str() );
+
+ if( me->GetIsKeepout() )
+ {
+ fprintf( m_fp, "ZKeepout tracks %c vias %c copperpour %c\n",
+ me->GetDoNotAllowTracks() ? 'N' : 'Y',
+ me->GetDoNotAllowVias() ? 'N' : 'Y',
+ me->GetDoNotAllowCopperPour() ? 'N' : 'Y' );
+ }
+
+ fprintf( m_fp, "ZSmoothing %d %s\n",
+ me->GetCornerSmoothingType(),
+ fmtBIU( me->GetCornerRadius() ).c_str() );
+
+ // Save the corner list
+ const CPOLYGONS_LIST& cv = me->Outline()->m_CornersList;
+
+ for( unsigned it = 0; it < cv.GetCornersCount(); ++it )
+ {
+ fprintf( m_fp, "ZCorner %s %d\n",
+ fmtBIUPair( cv.GetX( it ), cv.GetY( it ) ).c_str(),
+ cv.IsEndContour( it ) );
+ }
+
+ // Save the PolysList
+ const CPOLYGONS_LIST& fv = me->GetFilledPolysList();
+ if( fv.GetCornersCount() )
+ {
+ fprintf( m_fp, "$POLYSCORNERS\n" );
+
+ for( unsigned it = 0; it < fv.GetCornersCount(); ++it )
+ {
+ fprintf( m_fp, "%s %d %d\n",
+ fmtBIUPair( fv.GetX( it ), fv.GetY( it ) ).c_str(),
+ fv.IsEndContour( it ),
+ fv.GetUtility( it ) );
+ }
+
+ fprintf( m_fp, "$endPOLYSCORNERS\n" );
+ }
+
+ typedef std::vector< SEGMENT > SEGMENTS;
+
+ // Save the filling segments list
+ const SEGMENTS& segs = me->FillSegments();
+
+ if( segs.size() )
+ {
+ fprintf( m_fp, "$FILLSEGMENTS\n" );
+
+ for( SEGMENTS::const_iterator it = segs.begin(); it != segs.end(); ++it )
+ {
+ fprintf( m_fp, "%s %s\n",
+ fmtBIUPoint( it->m_Start ).c_str(),
+ fmtBIUPoint( it->m_End ).c_str() );
+ }
+
+ fprintf( m_fp, "$endFILLSEGMENTS\n" );
+ }
+
+ fprintf( m_fp, "$endCZONE_OUTLINE\n" );
+
+ CHECK_WRITE_ERROR();
+}
+
+
+void LEGACY_PLUGIN::saveDIMENSION( const DIMENSION* me ) const
+{
+ // note: COTATION was the previous name of DIMENSION
+ // this old keyword is used here for compatibility
+ fprintf( m_fp, "$COTATION\n" );
+
+ fprintf( m_fp, "Ge %d %d %lX\n", me->GetShape(), me->GetLayer(), me->GetTimeStamp() );
+
+ fprintf( m_fp, "Va %s\n", fmtBIU( me->GetValue() ).c_str() );
+
+ if( !me->GetText().IsEmpty() )
+ fprintf( m_fp, "Te %s\n", EscapedUTF8( me->GetText() ).c_str() );
+ else
+ fprintf( m_fp, "Te \"?\"\n" );
+
+ fprintf( m_fp, "Po %s %s %s %s %d\n",
+ fmtBIUPoint( me->Text().GetTextPosition() ).c_str(),
+ fmtBIUSize( me->Text().GetSize() ).c_str(),
+ fmtBIU( me->Text().GetThickness() ).c_str(),
+ fmtDEG( me->Text().GetOrientation() ).c_str(),
+ me->Text().IsMirrored() ? 0 : 1 // strange but true
+ );
+
+ fprintf( m_fp, "Sb %d %s %s %s\n", S_SEGMENT,
+ fmtBIUPair( me->m_crossBarO.x, me->m_crossBarO.y ).c_str(),
+ fmtBIUPair( me->m_crossBarF.x, me->m_crossBarF.y ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str() );
+
+ fprintf( m_fp, "Sd %d %s %s %s\n", S_SEGMENT,
+ fmtBIUPair( me->m_featureLineDO.x, me->m_featureLineDO.y ).c_str(),
+ fmtBIUPair( me->m_featureLineDF.x, me->m_featureLineDF.y ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str() );
+
+ fprintf( m_fp, "Sg %d %s %s %s\n", S_SEGMENT,
+ fmtBIUPair( me->m_featureLineGO.x, me->m_featureLineGO.y ).c_str(),
+ fmtBIUPair( me->m_featureLineGF.x, me->m_featureLineGF.y ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str() );
+
+ fprintf( m_fp, "S1 %d %s %s %s\n", S_SEGMENT,
+ fmtBIUPair( me->m_crossBarF.x, me->m_crossBarF.y ).c_str(),
+ fmtBIUPair( me->m_arrowD1F.x, me->m_arrowD1F.y ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str() );
+
+ fprintf( m_fp, "S2 %d %s %s %s\n", S_SEGMENT,
+ fmtBIUPair( me->m_crossBarF.x, me->m_crossBarF.y ).c_str(),
+ fmtBIUPair( me->m_arrowD2F.x, me->m_arrowD2F.y ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str() );
+
+ fprintf( m_fp, "S3 %d %s %s %s\n", S_SEGMENT,
+ fmtBIUPair( me->m_crossBarO.x, me->m_crossBarO.y ).c_str(),
+ fmtBIUPair( me->m_arrowG1F.x, me->m_arrowG1F.y ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str() );
+
+ fprintf( m_fp, "S4 %d %s %s %s\n", S_SEGMENT,
+ fmtBIUPair( me->m_crossBarO.x, me->m_crossBarO.y ).c_str(),
+ fmtBIUPair( me->m_arrowG2F.x, me->m_arrowG2F.y ).c_str(),
+ fmtBIU( me->GetWidth() ).c_str() );
+
+ fprintf( m_fp, "$endCOTATION\n" );
+
+ CHECK_WRITE_ERROR();
+}
+
+
+void LEGACY_PLUGIN::savePCB_TEXT( const TEXTE_PCB* me ) const
+{
+ if( me->GetText().IsEmpty() )
+ return;
+
+ fprintf( m_fp, "$TEXTPCB\n" );
+
+ wxArrayString* list = wxStringSplit( me->GetText(), '\n' );
+
+ for( unsigned ii = 0; ii < list->Count(); ii++ )
+ {
+ wxString txt = list->Item( ii );
+
+ if ( ii == 0 )
+ fprintf( m_fp, "Te %s\n", EscapedUTF8( txt ).c_str() );
+ else
+ fprintf( m_fp, "nl %s\n", EscapedUTF8( txt ).c_str() );
+ }
+
+ delete list;
+
+ fprintf( m_fp, "Po %s %s %s %s\n",
+ fmtBIUPoint( me->GetTextPosition() ).c_str(),
+ fmtBIUSize( me->GetSize() ).c_str(),
+ fmtBIU( me->GetThickness() ).c_str(),
+ fmtDEG( me->GetOrientation() ).c_str() );
+
+ fprintf( m_fp, "De %d %d %lX %s",
+ me->GetLayer(),
+ !me->IsMirrored(),
+ me->GetTimeStamp(),
+ me->IsItalic() ? "Italic" : "Normal" );
+
+ if( me->GetHorizJustify() != GR_TEXT_HJUSTIFY_CENTER ||
+ me->GetVertJustify() != GR_TEXT_VJUSTIFY_CENTER )
+ {
+ fprintf( m_fp, " %s %s\n",
+ ShowHorizJustify( me->GetHorizJustify() ),
+ ShowVertJustify( me->GetVertJustify() )
+ );
+ }
+ else
+ fprintf( m_fp, "\n" );
+
+ fprintf( m_fp, "$EndTEXTPCB\n" );
+}
+
+#endif // NO LEGACY_PLUGIN::Save()
+
+
+//-----<FOOTPRINT LIBRARY FUNCTIONS>--------------------------------------------
+
+/*
+
+ The legacy file format is being obsoleted and this code will have a short
+ lifetime, so it only needs to be good enough for a short duration of time.
+ Caching all the MODULEs is a bit memory intensive, but it is a considerably
+ faster way of fulfilling the API contract. Otherwise, without the cache, you
+ would have to re-read the file when searching for any MODULE, and this would
+ be very problematic filling a FOOTPRINT_LIST via this PLUGIN API. If memory
+ becomes a concern, consider the cache lifetime policy, which determines the
+ time that a LP_CACHE is in RAM. Note PLUGIN lifetime also plays a role in
+ cache lifetime.
+
+*/
+
+
+#include <boost/ptr_container/ptr_map.hpp>
+#include <wx/filename.h>
+
+typedef boost::ptr_map< std::string, MODULE > MODULE_MAP;
+typedef MODULE_MAP::iterator MODULE_ITER;
+typedef MODULE_MAP::const_iterator MODULE_CITER;
+
+
+/**
+ * Class LP_CACHE
+ * assists only for the footprint portion of the PLUGIN API, and only for the
+ * LEGACY_PLUGIN, so therefore is private to this implementation file, i.e. not placed
+ * into a header.
+ */
+struct LP_CACHE
+{
+ LEGACY_PLUGIN* m_owner; // my owner, I need its LEGACY_PLUGIN::loadMODULE()
+ wxString m_lib_path;
+ wxDateTime m_mod_time;
+ MODULE_MAP m_modules; // map or tuple of footprint_name vs. MODULE*
+ bool m_writable;
+
+ LP_CACHE( LEGACY_PLUGIN* aOwner, const wxString& aLibraryPath );
+
+ // Most all functions in this class throw IO_ERROR exceptions. There are no
+ // error codes nor user interface calls from here, nor in any PLUGIN.
+ // Catch these exceptions higher up please.
+
+ /// save the entire legacy library to m_lib_path;
+ void Save();
+
+ void SaveHeader( FILE* aFile );
+
+ void SaveIndex( FILE* aFile );
+
+ void SaveModules( FILE* aFile );
+
+ void SaveEndOfFile( FILE* aFile )
+ {
+ fprintf( aFile, "$EndLIBRARY\n" );
+ }
+
+ void Load();
+
+ void ReadAndVerifyHeader( LINE_READER* aReader );
+
+ void SkipIndex( LINE_READER* aReader );
+
+ void LoadModules( LINE_READER* aReader );
+
+ wxDateTime GetLibModificationTime();
+};
+
+
+LP_CACHE::LP_CACHE( LEGACY_PLUGIN* aOwner, const wxString& aLibraryPath ) :
+ m_owner( aOwner ),
+ m_lib_path( aLibraryPath ),
+ m_writable( true )
+{
+}
+
+
+wxDateTime LP_CACHE::GetLibModificationTime()
+{
+ wxFileName fn( m_lib_path );
+
+ // update the writable flag while we have a wxFileName, in a network this
+ // is possibly quite dynamic anyway.
+ m_writable = fn.IsFileWritable();
+
+ return fn.GetModificationTime();
+}
+
+
+void LP_CACHE::Load()
+{
+ FILE_LINE_READER reader( m_lib_path );
+
+ ReadAndVerifyHeader( &reader );
+ SkipIndex( &reader );
+ LoadModules( &reader );
+
+ // Remember the file modification time of library file when the
+ // cache snapshot was made, so that in a networked environment we will
+ // reload the cache as needed.
+ m_mod_time = GetLibModificationTime();
+}
+
+
+void LP_CACHE::ReadAndVerifyHeader( LINE_READER* aReader )
+{
+ char* line = aReader->ReadLine();
+ char* saveptr;
+
+ if( !line )
+ goto L_bad_library;
+
+ if( !TESTLINE( "PCBNEW-LibModule-V1" ) )
+ goto L_bad_library;
+
+ while( ( line = aReader->ReadLine() ) != NULL )
+ {
+ if( TESTLINE( "Units" ) )
+ {
+ const char* units = strtok_r( line + SZ( "Units" ), delims, &saveptr );
+
+ if( !strcmp( units, "mm" ) )
+ {
+ m_owner->diskToBiu = IU_PER_MM;
+ }
+
+ }
+ else if( TESTLINE( "$INDEX" ) )
+ return;
+ }
+
+L_bad_library:
+ THROW_IO_ERROR( wxString::Format( _( "File '%s' is empty or is not a legacy library" ),
+ m_lib_path.GetData() ) );
+}
+
+
+void LP_CACHE::SkipIndex( LINE_READER* aReader )
+{
+ // Some broken INDEX sections have more than one section, due to prior bugs.
+ // So we must read the next line after $EndINDEX tag,
+ // to see if this is not a new $INDEX tag.
+ bool exit = false;
+ char* line = aReader->Line();
+
+ do
+ {
+ if( TESTLINE( "$INDEX" ) )
+ {
+ exit = false;
+
+ while( ( line = aReader->ReadLine() ) != NULL )
+ {
+ if( TESTLINE( "$EndINDEX" ) )
+ {
+ exit = true;
+ break;
+ }
+ }
+ }
+ else if( exit )
+ break;
+ } while( ( line = aReader->ReadLine() ) != NULL );
+}
+
+
+void LP_CACHE::LoadModules( LINE_READER* aReader )
+{
+ m_owner->SetReader( aReader );
+
+ char* line = aReader->Line();
+
+ do
+ {
+ // test first for the $MODULE, even before reading because of INDEX bug.
+ if( TESTLINE( "$MODULE" ) )
+ {
+ auto_ptr<MODULE> module( new MODULE( m_owner->m_board ) );
+
+ std::string footprintName = StrPurge( line + SZ( "$MODULE" ) );
+
+ // The footprint names in legacy libraries can contain the '/' and ':'
+ // characters which will cause the FPID parser to choke.
+ ReplaceIllegalFileNameChars( &footprintName );
+
+ // set the footprint name first thing, so exceptions can use name.
+ module->SetFPID( FPID( footprintName ) );
+
+#if 0 && defined( DEBUG )
+ printf( "%s\n", footprintName.c_str() );
+ if( footprintName == "QFN40" )
+ {
+ int breakhere = 1;
+ (void) breakhere;
+ }
+#endif
+
+ m_owner->loadMODULE( module.get() );
+
+ MODULE* m = module.release(); // exceptions after this are not expected.
+
+ // Not sure why this is asserting on debug builds. The debugger shows the
+ // strings are the same. If it's not really needed maybe it can be removed.
+// wxASSERT( footprintName == m->GetFPID().GetFootprintName() );
+
+ /*
+
+ There was a bug in old legacy library management code
+ (pre-LEGACY_PLUGIN) which was introducing duplicate footprint names
+ in legacy libraries without notification. To best recover from such
+ bad libraries, and use them to their fullest, there are a few
+ strategies that could be used. (Note: footprints must have unique
+ names to be accepted into this cache.) The strategy used here is to
+ append a differentiating version counter to the end of the name as:
+ _v2, _v3, etc.
+
+ */
+
+ MODULE_CITER it = m_modules.find( footprintName );
+
+ if( it == m_modules.end() ) // footprintName is not present in cache yet.
+ {
+ std::pair<MODULE_ITER, bool> r = m_modules.insert( footprintName, m );
+
+ wxASSERT_MSG( r.second, wxT( "error doing cache insert using guaranteed unique name" ) );
+ (void) r;
+ }
+
+ // Bad library has a duplicate of this footprintName, generate a
+ // unique footprint name and load it anyway.
+ else
+ {
+ bool nameOK = false;
+ int version = 2;
+ char buf[48];
+
+ while( !nameOK )
+ {
+ std::string newName = footprintName;
+
+ newName += "_v";
+ sprintf( buf, "%d", version++ );
+ newName += buf;
+
+ it = m_modules.find( newName );
+
+ if( it == m_modules.end() )
+ {
+ nameOK = true;
+
+ m->SetFPID( FPID( newName ) );
+ std::pair<MODULE_ITER, bool> r = m_modules.insert( newName, m );
+
+ wxASSERT_MSG( r.second, wxT( "error doing cache insert using guaranteed unique name" ) );
+ (void) r;
+ }
+ }
+ }
+ }
+
+ } while( ( line = aReader->ReadLine() ) != NULL );
+}
+
+
+#if 0
+void LP_CACHE::Save()
+{
+ if( !m_writable )
+ {
+ THROW_IO_ERROR( wxString::Format(
+ _( "Legacy library file '%s' is read only" ), m_lib_path.GetData() ) );
+ }
+
+ wxString tempFileName;
+
+ // a block {} scope to fire wxFFile wxf()'s destructor
+ {
+ // CreateTempFileName works better with an absolute path
+ wxFileName abs_lib_name( m_lib_path );
+
+ abs_lib_name.MakeAbsolute();
+ tempFileName = wxFileName::CreateTempFileName( abs_lib_name.GetFullPath() );
+
+ //wxLogDebug( wxT( "tempFileName:'%s' m_lib_path:'%s'\n" ), TO_UTF8( tempFileName ), TO_UTF8( m_lib_path ) );
+
+ FILE* fp = wxFopen( tempFileName, wxT( "w" ) );
+ if( !fp )
+ {
+ THROW_IO_ERROR( wxString::Format(
+ _( "Unable to open or create legacy library file '%s'" ),
+ m_lib_path.GetData() ) );
+ }
+
+ // wxf now owns fp, will close on exception or exit from
+ // this block {} scope
+ wxFFile wxf( fp );
+
+ SaveHeader( fp );
+ SaveIndex( fp );
+ SaveModules( fp );
+ SaveEndOfFile( fp );
+ }
+
+ // fp is now closed here, and that seems proper before trying to rename
+ // the temporary file to m_lib_path.
+
+ wxRemove( m_lib_path ); // it is not an error if this does not exist
+
+ // Even on linux you can see an _intermittent_ error when calling wxRename(),
+ // and it is fully inexplicable. See if this dodges the error.
+ wxMilliSleep( 250L );
+
+ if( !wxRenameFile( tempFileName, m_lib_path ) )
+ {
+ THROW_IO_ERROR( wxString::Format(
+ _( "Unable to rename tempfile '%s' to library file '%s'" ),
+ tempFileName.GetData(),
+ m_lib_path.GetData() ) );
+ }
+}
+
+
+void LP_CACHE::SaveHeader( FILE* aFile )
+{
+ fprintf( aFile, "%s %s\n", FOOTPRINT_LIBRARY_HEADER, TO_UTF8( DateAndTime() ) );
+ fprintf( aFile, "# encoding utf-8\n" );
+ fprintf( aFile, "Units mm\n" );
+}
+
+
+void LP_CACHE::SaveIndex( FILE* aFile )
+{
+ fprintf( aFile, "$INDEX\n" );
+
+ for( MODULE_CITER it = m_modules.begin(); it != m_modules.end(); ++it )
+ {
+ fprintf( aFile, "%s\n", it->first.c_str() );
+ }
+
+ fprintf( aFile, "$EndINDEX\n" );
+}
+
+
+void LP_CACHE::SaveModules( FILE* aFile )
+{
+ m_owner->SetFilePtr( aFile );
+
+ for( MODULE_CITER it = m_modules.begin(); it != m_modules.end(); ++it )
+ {
+ m_owner->saveMODULE( it->second );
+ }
+}
+#endif
+
+void LEGACY_PLUGIN::cacheLib( const wxString& aLibraryPath )
+{
+ if( !m_cache || m_cache->m_lib_path != aLibraryPath ||
+ // somebody else on a network touched the library:
+ m_cache->m_mod_time != m_cache->GetLibModificationTime() )
+ {
+ // a spectacular episode in memory management:
+ delete m_cache;
+ m_cache = new LP_CACHE( this, aLibraryPath );
+ m_cache->Load();
+ }
+}
+
+
+wxArrayString LEGACY_PLUGIN::FootprintEnumerate( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ init( aProperties );
+
+ cacheLib( aLibraryPath );
+
+ const MODULE_MAP& mods = m_cache->m_modules;
+
+ wxArrayString ret;
+
+ for( MODULE_CITER it = mods.begin(); it != mods.end(); ++it )
+ {
+ ret.Add( FROM_UTF8( it->first.c_str() ) );
+ }
+
+ return ret;
+}
+
+
+MODULE* LEGACY_PLUGIN::FootprintLoad( const wxString& aLibraryPath,
+ const wxString& aFootprintName, const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ init( aProperties );
+
+ cacheLib( aLibraryPath );
+
+ const MODULE_MAP& mods = m_cache->m_modules;
+
+ MODULE_CITER it = mods.find( TO_UTF8( aFootprintName ) );
+
+ if( it == mods.end() )
+ {
+ /*
+ THROW_IO_ERROR( wxString::Format( _( "No '%s' footprint in library '%s'" ),
+ aFootprintName.GetData(), aLibraryPath.GetData() ) );
+ */
+
+ return NULL;
+ }
+
+ // copy constructor to clone the already loaded MODULE
+ return new MODULE( *it->second );
+}
+
+
+#if 0 // omit FootprintSave()
+
+void LEGACY_PLUGIN::FootprintSave( const wxString& aLibraryPath,
+ const MODULE* aFootprint, const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ init( aProperties );
+
+ cacheLib( aLibraryPath );
+
+ if( !m_cache->m_writable )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "Library '%s' is read only" ), aLibraryPath.GetData() ) );
+ }
+
+ std::string footprintName = aFootprint->GetFPID().GetFootprintName();
+
+ MODULE_MAP& mods = m_cache->m_modules;
+
+ // quietly overwrite any by same name.
+ MODULE_CITER it = mods.find( footprintName );
+ if( it != mods.end() )
+ {
+ mods.erase( footprintName );
+ }
+
+ // I need my own copy for the cache
+ MODULE* my_module = new MODULE( *aFootprint );
+
+ // and it's time stamp must be 0, it should have no parent, orientation should
+ // be zero, and it should be on the front layer.
+
+ my_module->SetTimeStamp( 0 );
+ my_module->SetParent( 0 );
+
+ my_module->SetOrientation( 0 );
+
+ if( my_module->GetLayer() != F_Cu )
+ my_module->Flip( my_module->GetPosition() );
+
+ mods.insert( footprintName, my_module );
+
+ m_cache->Save();
+}
+
+
+void LEGACY_PLUGIN::FootprintDelete( const wxString& aLibraryPath,
+ const wxString& aFootprintName, const PROPERTIES* aProperties )
+{
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ init( NULL );
+
+ cacheLib( aLibraryPath );
+
+ if( !m_cache->m_writable )
+ {
+ THROW_IO_ERROR( wxString::Format( _( "Library '%s' is read only" ), aLibraryPath.GetData() ) );
+ }
+
+ std::string footprintName = TO_UTF8( aFootprintName );
+
+ size_t erasedCount = m_cache->m_modules.erase( footprintName );
+
+ if( erasedCount != 1 )
+ {
+ THROW_IO_ERROR( wxString::Format(
+ _( "library '%s' has no footprint '%s' to delete" ),
+ aLibraryPath.GetData(), aFootprintName.GetData() ) );
+ }
+
+ m_cache->Save();
+}
+
+
+void LEGACY_PLUGIN::FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ if( wxFileExists( aLibraryPath ) )
+ {
+ THROW_IO_ERROR( wxString::Format(
+ _( "library '%s' already exists, will not create a new" ),
+ aLibraryPath.GetData() ) );
+ }
+
+ LOCALE_IO toggle;
+
+ init( NULL );
+
+ delete m_cache;
+ m_cache = new LP_CACHE( this, aLibraryPath );
+ m_cache->Save();
+ m_cache->Load(); // update m_writable and m_mod_time
+}
+
+#endif // omit FootprintSave()
+
+
+bool LEGACY_PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ wxFileName fn = aLibraryPath;
+
+ if( !fn.FileExists() )
+ return false;
+
+ // Some of the more elaborate wxRemoveFile() crap puts up its own wxLog dialog
+ // we don't want that. we want bare metal portability with no UI here.
+ if( wxRemove( aLibraryPath ) )
+ {
+ THROW_IO_ERROR( wxString::Format(
+ _( "library '%s' cannot be deleted" ),
+ aLibraryPath.GetData() ) );
+ }
+
+ if( m_cache && m_cache->m_lib_path == aLibraryPath )
+ {
+ delete m_cache;
+ m_cache = 0;
+ }
+
+ return true;
+}
+
+
+bool LEGACY_PLUGIN::IsFootprintLibWritable( const wxString& aLibraryPath )
+{
+#if 0 // no support for 32 Cu layers in legacy format
+ return false;
+#else
+ LOCALE_IO toggle;
+
+ init( NULL );
+
+ cacheLib( aLibraryPath );
+
+ return m_cache->m_writable;
+#endif
+}
+
+
+LEGACY_PLUGIN::LEGACY_PLUGIN() :
+ m_cu_count( 16 ), // for FootprintLoad()
+ m_board( 0 ),
+ m_props( 0 ),
+ m_reader( 0 ),
+ m_fp( 0 ),
+ m_cache( 0 ),
+ m_mapping( new NETINFO_MAPPING() )
+{
+ init( NULL );
+}
+
+
+LEGACY_PLUGIN::~LEGACY_PLUGIN()
+{
+ delete m_cache;
+ delete m_mapping;
+}
diff --git a/pcbnew/legacy_plugin.h b/pcbnew/legacy_plugin.h
new file mode 100644
index 0000000..d99935d
--- /dev/null
+++ b/pcbnew/legacy_plugin.h
@@ -0,0 +1,302 @@
+#ifndef LEGACY_PLUGIN_H_
+#define LEGACY_PLUGIN_H_
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <io_mgr.h>
+#include <boost/shared_ptr.hpp>
+#include <string>
+#include <layers_id_colors_and_visibility.h>
+
+// FOOTPRINT_LIBRARY_HEADER_CNT gives the number of characters to compare to detect
+// a footprint library. A few variants may have been used, and so we can only be
+// sure that the header contains "PCBNEW-LibModule-V", not "PCBNEW-LibModule-V1".
+#define FOOTPRINT_LIBRARY_HEADER "PCBNEW-LibModule-V1"
+#define FOOTPRINT_LIBRARY_HEADER_CNT 18
+
+class PCB_TARGET;
+class MODULE;
+class DRAWSEGMENT;
+class NETINFO;
+class TEXTE_PCB;
+class TRACK;
+class NETCLASS;
+class NETCLASSES;
+class ZONE_CONTAINER;
+class DIMENSION;
+class NETINFO_ITEM;
+class NETINFO_MAPPING;
+class TEXTE_MODULE;
+class EDGE_MODULE;
+class TRACK;
+class SEGZONE;
+class D_PAD;
+struct LP_CACHE;
+
+
+/**
+ * Class LEGACY_PLUGIN
+ * is a PLUGIN derivation which could possibly be put into a DLL/DSO.
+ * As with any PLUGIN, there is no UI, i.e. windowing calls allowed.
+ */
+class LEGACY_PLUGIN : public PLUGIN
+{
+ friend struct LP_CACHE;
+
+public:
+
+ //-----<PLUGIN IMPLEMENTATION>----------------------------------------------
+
+ const wxString PluginName() const
+ {
+ return wxT( "KiCad-Legacy" );
+ }
+
+ const wxString GetFileExtension() const
+ {
+ return wxT( "brd" );
+ }
+
+ BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe,
+ const PROPERTIES* aProperties = NULL );
+
+ /* we let go of "save" support when the number of CU layers were expanded from 16 to 32.
+ void Save( const wxString& aFileName, BOARD* aBoard, const PROPERTIES* aProperties = NULL );
+
+ void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint,
+ const PROPERTIES* aProperties = NULL );
+ void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName, const PROPERTIES* aProperties = NULL );
+
+ void FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL );
+ */
+
+ wxArrayString FootprintEnumerate( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL);
+
+ MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties = NULL );
+
+ bool FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL );
+
+ bool IsFootprintLibWritable( const wxString& aLibraryPath );
+
+ //-----</PLUGIN IMPLEMENTATION>---------------------------------------------
+
+ typedef int BIU;
+
+ LEGACY_PLUGIN();
+ ~LEGACY_PLUGIN();
+
+ void SetReader( LINE_READER* aReader ) { m_reader = aReader; }
+ void SetFilePtr( FILE* aFile ) { m_fp = aFile; }
+
+ void SaveModule3D( const MODULE* aModule ) const;
+
+ // return the new .kicad_pcb layer id from the old (legacy) layer id
+ static LAYER_ID leg_layer2new( int cu_count, LAYER_NUM aLayerNum );
+
+ static LSET leg_mask2new( int cu_count, unsigned aMask );
+
+protected:
+
+ int m_cu_count;
+
+ wxString m_error; ///< for throwing exceptions
+ BOARD* m_board; ///< which BOARD, no ownership here
+ const PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL.
+
+ LINE_READER* m_reader; ///< no ownership here.
+ FILE* m_fp; ///< no ownership here.
+ wxString m_filename; ///< for saves only, name is in m_reader for loads
+
+ wxString m_field; ///< reused to stuff MODULE fields.
+ int m_loading_format_version; ///< which BOARD_FORMAT_VERSION am I Load()ing?
+ LP_CACHE* m_cache;
+
+ NETINFO_MAPPING* m_mapping; ///< mapping for net codes, so only not empty nets
+ ///< are stored with consecutive integers as net codes
+ std::vector<int> m_netCodes; ///< net codes mapping for boards being loaded
+
+ /// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
+ void init( const PROPERTIES* aProperties );
+
+ double biuToDisk; ///< convert from BIUs to disk engineering units
+ ///< with this scale factor
+
+ double diskToBiu; ///< convert from disk engineering units to BIUs
+ ///< with this scale factor
+
+ ///> Converts net code using the mapping table if available,
+ ///> otherwise returns unchanged net code
+ inline int getNetCode( int aNetCode )
+ {
+ if( (unsigned int) aNetCode < m_netCodes.size() )
+ return m_netCodes[aNetCode];
+
+ return aNetCode;
+ }
+
+ /**
+ * Function biuParse
+ * parses an ASCII decimal floating point value and scales it into a BIU
+ * according to the current value of diskToBui. This fuction is the complement of
+ * fmtBIU(). One has to know what the other is doing.
+ *
+ * @param aValue is the ASCII value in C locale form with possible leading whitespace
+ *
+ * @param nptrptr may be NULL, but if not, then it tells where to put a
+ * pointer to the next unconsumed input text. See "man strtod" for more information.
+ *
+ * @return BIU - the converted Board Internal Unit.
+ */
+ BIU biuParse( const char* aValue, const char** nptrptr = NULL );
+
+ /**
+ * Function degParse
+ * parses an ASCII decimal floating point value which is certainly an angle. This
+ * is a dedicated function for encapsulating support for the migration from
+ * tenths of degrees to degrees in floating point. This function is the complement of
+ * fmtDEG(). One has to know what the other is doing.
+ *
+ * @param aValue is the ASCII value in C locale form with possible leading whitespace
+ *
+ * @param nptrptr may be NULL, but if not, then it tells where to put a
+ * pointer to the next unconsumed input text. See "man strtod" for more information.
+ *
+ * @return double - the string converted to a primitive double type
+ */
+ double degParse( const char* aValue, const char** nptrptr = NULL );
+
+ //-----<load/parse functions>-----------------------------------------------
+
+ void checkVersion();
+
+ void loadAllSections( bool doAppend );
+
+
+ void loadGENERAL();
+ void loadSETUP();
+ void loadSHEET();
+
+ void load3D( MODULE* aModule );
+ void loadPAD( MODULE* aModule );
+ void loadMODULE_TEXT( TEXTE_MODULE* aText );
+ void loadMODULE_EDGE( MODULE* aModule );
+
+ void loadPCB_LINE();
+ void loadNETINFO_ITEM();
+ void loadPCB_TEXT();
+ void loadNETCLASS();
+ void loadMODULE( MODULE* aModule );
+
+ /**
+ * Function loadTrackList
+ * reads a list of segments (Tracks and Vias, or Segzones)
+ *
+ * @param aStructType is either PCB_TRACE_T to indicate tracks and vias, or
+ * PCB_ZONE_T to indicate oldschool zone segments (before polygons came to be).
+ */
+ void loadTrackList( int aStructType );
+
+ void loadZONE_CONTAINER(); // "$CZONE_OUTLINE"
+ void loadDIMENSION(); // "$COTATION"
+ void loadPCB_TARGET(); // "$PCB_TARGET"
+
+ //-----</ load/parse functions>---------------------------------------------
+
+
+ //-----<save functions>-----------------------------------------------------
+#if 0
+ /**
+ * Function writeError
+ * returns an error message wxString containing the filename being
+ * currently written.
+ */
+ wxString writeError() const;
+
+ /// encapsulate the BIU formatting tricks in one place.
+ int biuSprintf( char* buf, BIU aValue ) const;
+
+ /**
+ * Function fmtBIU
+ * converts a BIU to engineering units by scaling and formatting to ASCII.
+ * This function is the complement of biuParse(). One has to know what the
+ * other is doing.
+ */
+ std::string fmtBIU( BIU aValue ) const;
+
+ std::string fmtBIUPair( BIU first, BIU second ) const;
+
+ std::string fmtBIUPoint( const wxPoint& aPoint ) const
+ {
+ return fmtBIUPair( aPoint.x, aPoint.y );
+ }
+
+ std::string fmtBIUSize( const wxSize& aSize ) const
+ {
+ return fmtBIUPair( aSize.x, aSize.y );
+ }
+
+ /**
+ * Function fmtDEG
+ * formats an angle in a way particular to a board file format. This function
+ * is the opposite or complement of degParse(). One has to know what the
+ * other is doing.
+ */
+ std::string fmtDEG( double aAngle ) const;
+
+ void saveGENERAL( const BOARD* aBoard ) const;
+ void saveSHEET( const BOARD* aBoard ) const;
+ void saveSETUP( const BOARD* aBoard ) const;
+ void saveBOARD_ITEMS( const BOARD* aBoard ) const;
+
+ void saveMODULE_TEXT( const TEXTE_MODULE* aText ) const;
+ void saveMODULE_EDGE( const EDGE_MODULE* aGraphic ) const;
+ void savePAD( const D_PAD* aPad ) const;
+
+ void saveNETINFO_ITEM( const NETINFO_ITEM* aNet ) const;
+ void saveNETCLASSES( const NETCLASSES* aNetClasses ) const;
+ void saveNETCLASS( const boost::shared_ptr<NETCLASS> aNetclass ) const;
+
+ void savePCB_TEXT( const TEXTE_PCB* aText ) const;
+ void savePCB_TARGET( const PCB_TARGET* aTarget ) const;
+ void savePCB_LINE( const DRAWSEGMENT* aStroke ) const;
+ void saveDIMENSION( const DIMENSION* aDimension ) const;
+ void saveTRACK( const TRACK* aTrack ) const;
+ void saveBOARD( const BOARD* aBoard ) const;
+
+ /**
+ * Function saveZONE_CONTAINER
+ * saves the new polygon zones.
+ */
+ void saveZONE_CONTAINER( const ZONE_CONTAINER* aZone ) const;
+
+ //-----</save functions>----------------------------------------------------
+#endif
+
+ /// we only cache one footprint library for now, this determines which one.
+ void cacheLib( const wxString& aLibraryPath );
+};
+
+#endif // LEGACY_PLUGIN_H_
diff --git a/pcbnew/librairi.cpp b/pcbnew/librairi.cpp
new file mode 100644
index 0000000..744a3d4
--- /dev/null
+++ b/pcbnew/librairi.cpp
@@ -0,0 +1,850 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file librairi.cpp
+ * @brief Manage module (footprint) libraries.
+ */
+
+#include <wx/ffile.h>
+#include <wx/stdpaths.h>
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <wxPcbStruct.h>
+#include <dialog_helpers.h>
+#include <filter_reader.h>
+#include <macros.h>
+#include <fp_lib_table.h>
+#include <validators.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <pcbnew.h>
+#include <module_editor_frame.h>
+#include <wildcards_and_files_ext.h>
+#include <kicad_plugin.h>
+#include <legacy_plugin.h>
+
+#include <dialog_select_pretty_lib.h>
+
+
+// unique, "file local" translations:
+
+#define FMT_OK_OVERWRITE _( "Library '%s' exists, OK to replace ?" )
+#define FMT_CREATE_LIB _( "Create New Library Folder (the .pretty folder is the library)" )
+#define FMT_OK_DELETE _( "OK to delete footprint %s in library '%s'" )
+#define FMT_IMPORT_MODULE _( "Import Footprint" )
+#define FMT_FILE_NOT_FOUND _( "File '%s' not found" )
+#define FMT_NOT_MODULE _( "Not a footprint file" )
+#define FMT_MOD_NOT_FOUND _( "Unable to find or load footprint %s from lib path '%s'" )
+#define FMT_BAD_PATH _( "Unable to find or load footprint from path '%s'" )
+#define FMT_BAD_PATHS _( "The footprint library '%s' could not be found in any of the search paths." )
+#define FMT_LIB_READ_ONLY _( "Library '%s' is read only, not writable" )
+
+#define FMT_EXPORT_MODULE _( "Export Footprint" )
+#define FMT_SAVE_MODULE _( "Save Footprint" )
+#define FMT_MOD_REF _( "Enter footprint name:" )
+#define FMT_EXPORTED _( "Footprint exported to file '%s'" )
+#define FMT_MOD_DELETED _( "Footprint %s deleted from library '%s'" )
+#define FMT_MOD_CREATE _( "New Footprint" )
+
+#define FMT_MOD_EXISTS _( "Footprint %s already exists in library '%s'" )
+#define FMT_NO_REF_ABORTED _( "No footprint name defined." )
+#define FMT_SELECT_LIB _( "Select Library" )
+
+static const wxString INFO_LEGACY_LIB_WARN_EDIT(
+ _( "Writing/modifying legacy libraries (.mod files) is not allowed\n"\
+ "Please save the current library to the new .pretty format\n"\
+ "and update your footprint lib table\n"\
+ "to save your footprint (a .kicad_mod file) in the .pretty library folder" ) );
+
+static const wxString INFO_LEGACY_LIB_WARN_DELETE(
+ _( "Modifying legacy libraries (.mod files) is not allowed\n"\
+ "Please save the current library under the new .pretty format\n"\
+ "and update your footprint lib table\n"\
+ "before deleting a footprint" ) );
+
+static const wxString ModLegacyExportFileWildcard( _( "Legacy foot print export files (*.emp)|*.emp" ) );
+static const wxString ModImportFileWildcard( _( "GPcb foot print files (*)|*" ) );
+
+
+#define EXPORT_IMPORT_LASTPATH_KEY wxT( "import_last_path" )
+
+
+/**
+ * Prompt the user for a module file to open.
+ * @param aParent - parent window for the dialog
+ * @param aLastPath - last opened path
+ */
+static wxFileName prompt_for_module( wxWindow* aParent, const wxString& aLastPath )
+{
+ static int lastFilterIndex = 0;
+ wxString wildCard;
+
+ wildCard << wxGetTranslation( KiCadFootprintLibFileWildcard ) << wxChar( '|' )
+ << wxGetTranslation( ModLegacyExportFileWildcard ) << wxChar( '|' )
+ << wxGetTranslation( ModImportFileWildcard ) << wxChar( '|' )
+ << wxGetTranslation( GedaPcbFootprintLibFileWildcard );
+
+ wxFileDialog dlg( aParent, FMT_IMPORT_MODULE, aLastPath, wxEmptyString, wildCard,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST );
+
+ dlg.SetFilterIndex( lastFilterIndex );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return wxFileName();
+
+ lastFilterIndex = dlg.GetFilterIndex();
+
+ return wxFileName( dlg.GetPath() );
+}
+
+
+/**
+ * Read a file to detect the type.
+ * @param aFile - open file to be read. File pointer will be closed.
+ * @param aFileName - file name to be read
+ * @param aName - wxString to receive the module name iff type is LEGACY
+ */
+static IO_MGR::PCB_FILE_T detect_file_type( FILE* aFile, const wxFileName& aFileName, wxString* aName )
+{
+ FILE_LINE_READER freader( aFile, aFileName.GetFullPath() );
+ WHITESPACE_FILTER_READER reader( freader );
+ IO_MGR::PCB_FILE_T file_type;
+
+ wxASSERT( aName );
+
+ reader.ReadLine();
+ char* line = reader.Line();
+
+ if( !strnicmp( line, "(module", strlen( "(module" ) ) )
+ {
+ file_type = IO_MGR::KICAD;
+ *aName = aFileName.GetName();
+ }
+ else if( !strnicmp( line, FOOTPRINT_LIBRARY_HEADER, FOOTPRINT_LIBRARY_HEADER_CNT ) )
+ {
+ file_type = IO_MGR::LEGACY;
+ while( reader.ReadLine() )
+ {
+ if( !strnicmp( line, "$MODULE", strlen( "$MODULE" ) ) )
+ {
+ *aName = FROM_UTF8( StrPurge( line + strlen( "$MODULE" ) ) );
+ break;
+ }
+ }
+ }
+ else if( !strnicmp( line, "Element", strlen( "Element" ) ) )
+ {
+ file_type = IO_MGR::GEDA_PCB;
+ *aName = aFileName.GetName();
+ }
+ else
+ {
+ file_type = IO_MGR::FILE_TYPE_NONE;
+ }
+
+ return file_type;
+}
+
+
+/**
+ * Parse a footprint using a PLUGIN.
+ * @param aFileName - file name to parse
+ * @param aFileType - type of the file
+ * @param aName - name of the footprint
+ */
+static MODULE* parse_module_with_plugin(
+ const wxFileName& aFileName, IO_MGR::PCB_FILE_T aFileType,
+ const wxString& aName )
+{
+ wxString path;
+
+ switch( aFileType )
+ {
+ case IO_MGR::GEDA_PCB:
+ path = aFileName.GetPath();
+ break;
+ case IO_MGR::LEGACY:
+ path = aFileName.GetFullPath();
+ break;
+ default:
+ wxFAIL_MSG( wxT( "unexpected IO_MGR::PCB_FILE_T" ) );
+ }
+
+ PLUGIN::RELEASER pi( IO_MGR::PluginFind( aFileType ) );
+
+ return pi->FootprintLoad( path, aName );
+}
+
+
+/**
+ * Parse a KICAD footprint.
+ * @param aFileName - file name to parse
+ */
+static MODULE* parse_module_kicad( const wxFileName& aFileName )
+{
+ wxString fcontents;
+ PCB_IO pcb_io;
+ wxFFile f( aFileName.GetFullPath() );
+
+ if( !f.IsOpened() )
+ return NULL;
+
+ f.ReadAll( &fcontents );
+
+ return dynamic_cast<MODULE*>( pcb_io.Parse( fcontents ) );
+}
+
+
+/**
+ * Try to load a footprint, returning NULL if the file couldn't be accessed.
+ * @param aFileName - file name to load
+ * @param aFileType - type of the file to load
+ * @param aName - footprint name
+ */
+MODULE* try_load_footprint( const wxFileName& aFileName, IO_MGR::PCB_FILE_T aFileType,
+ const wxString& aName )
+{
+ MODULE* module;
+
+ switch( aFileType )
+ {
+ case IO_MGR::GEDA_PCB:
+ case IO_MGR::LEGACY:
+ module = parse_module_with_plugin( aFileName, aFileType, aName );
+ break;
+
+ case IO_MGR::KICAD:
+ module = parse_module_kicad( aFileName );
+ break;
+
+ default:
+ wxFAIL_MSG( wxT( "unexpected IO_MGR::PCB_FILE_T" ) );
+ module = NULL;
+ }
+
+ return module;
+}
+
+
+MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
+{
+ wxString lastOpenedPathForLoading = m_mruPath;
+ wxConfigBase* config = Kiface().KifaceSettings();
+
+ if( config )
+ config->Read( EXPORT_IMPORT_LASTPATH_KEY, &lastOpenedPathForLoading );
+
+ wxFileName fn = prompt_for_module( this, lastOpenedPathForLoading );
+
+ if( !fn.IsOk() )
+ return NULL;
+
+ FILE* fp = wxFopen( fn.GetFullPath(), wxT( "rt" ) );
+
+ if( !fp )
+ {
+ wxString msg = wxString::Format( FMT_FILE_NOT_FOUND, GetChars( fn.GetFullPath() ) );
+ DisplayError( this, msg );
+ return NULL;
+ }
+
+ if( config ) // Save file path
+ {
+ lastOpenedPathForLoading = fn.GetPath();
+ config->Write( EXPORT_IMPORT_LASTPATH_KEY, lastOpenedPathForLoading );
+ }
+
+ wxString moduleName;
+ IO_MGR::PCB_FILE_T fileType = detect_file_type( fp, fn.GetFullPath(), &moduleName );
+
+ if( fileType == IO_MGR::FILE_TYPE_NONE )
+ {
+ DisplayError( this, FMT_NOT_MODULE );
+ return NULL;
+ }
+
+ MODULE* module;
+ wxString errMessage;
+
+ try
+ {
+ module = try_load_footprint( fn, fileType, moduleName );
+
+ if( !module )
+ {
+ wxString msg = wxString::Format(
+ FMT_MOD_NOT_FOUND, GetChars( moduleName ), GetChars( fn.GetFullPath() ) );
+ DisplayError( this, msg );
+ return NULL;
+ }
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( this, ioe.errorText );
+ return NULL;
+ }
+
+ // Insert footprint in list
+ GetBoard()->Add( module );
+
+ // Display info :
+ SetMsgPanel( module );
+ PlaceModule( module, NULL );
+
+ if( IsGalCanvasActive() )
+ module->SetPosition( wxPoint( 0, 0 ) );
+
+ GetBoard()->m_Status_Pcb = 0;
+ GetBoard()->BuildListOfNets();
+ updateView();
+
+ return module;
+}
+
+
+void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule )
+{
+ wxFileName fn;
+ wxConfigBase* config = Kiface().KifaceSettings();
+
+ if( !aModule )
+ return;
+
+ fn.SetName( aModule->GetFPID().GetFootprintName() );
+
+ wxString wildcard = wxGetTranslation( KiCadFootprintLibFileWildcard );
+
+ fn.SetExt( KiCadFootprintFileExtension );
+
+ if( config )
+ {
+ wxString path;
+ config->Read( EXPORT_IMPORT_LASTPATH_KEY, &path, m_mruPath );
+ fn.SetPath( path );
+ }
+
+ wxFileDialog dlg( this, FMT_EXPORT_MODULE, fn.GetPath(), fn.GetFullName(),
+ wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ fn = dlg.GetPath();
+
+ if( config ) // Save file path
+ {
+ config->Write( EXPORT_IMPORT_LASTPATH_KEY, fn.GetPath() );
+ }
+
+ try
+ {
+ // Export as *.kicad_pcb format, using a strategy which is specifically chosen
+ // as an example on how it could also be used to send it to the system clipboard.
+
+ PCB_IO pcb_io( CTL_FOR_LIBRARY );
+
+ /* This module should *already* be "normalized" in a way such that
+ orientation is zero, etc., since it came from module editor.
+
+ module->SetTimeStamp( 0 );
+ module->SetParent( 0 );
+ module->SetOrientation( 0 );
+ */
+
+ pcb_io.Format( aModule );
+
+ FILE* fp = wxFopen( dlg.GetPath(), wxT( "wt" ) );
+
+ if( fp == NULL )
+ {
+ wxMessageBox( wxString::Format(
+ _( "Unable to create or write file '%s'" ),
+ GetChars( dlg.GetPath() ) ) );
+ return;
+ }
+
+ fprintf( fp, "%s", pcb_io.GetStringOutput( false ).c_str() );
+ fclose( fp );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( this, ioe.errorText );
+ return;
+ }
+
+ wxString msg = wxString::Format( FMT_EXPORTED, GetChars( dlg.GetPath() ) );
+ DisplayInfoMessage( this, msg );
+}
+
+bool FOOTPRINT_EDIT_FRAME::SaveCurrentModule( const wxString* aLibPath )
+{
+ wxString libPath = aLibPath ? *aLibPath : getLibPath();
+
+ IO_MGR::PCB_FILE_T piType = IO_MGR::GuessPluginTypeFromLibPath( libPath );
+
+ // Legacy libraries are readable, but writing legacy format is not allowed
+ if( piType == IO_MGR::LEGACY )
+ {
+ DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT );
+ return false;
+ }
+
+ try
+ {
+ PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) );
+
+ pi->FootprintSave( libPath, GetBoard()->m_Modules );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( this, ioe.errorText );
+ return false;
+ }
+ return true;
+}
+
+wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary()
+{
+ // Kicad cannot write legacy format libraries, only .pretty new format
+ // because the legacy format cannot handle current features.
+ // The footprint library is actually a directory
+
+ // prompt user for footprint library name, ending by ".pretty"
+ // Because there are constraints for the directory name to create,
+ // (the name should have the extension ".pretty", and the folder cannot be inside
+ // a footprint library), we do not use the standard wxDirDialog.
+
+ wxString initialPath = wxPathOnly( Prj().GetProjectFullName() );
+ DIALOG_SELECT_PRETTY_LIB dlg( this, initialPath );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return wxEmptyString;
+
+ wxString libPath = dlg.GetFullPrettyLibName();
+
+ // We can save fp libs only using IO_MGR::KICAD format (.pretty libraries)
+ IO_MGR::PCB_FILE_T piType = IO_MGR::KICAD;
+
+ try
+ {
+ PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) );
+
+ bool writable = false;
+ bool exists = false;
+
+ try
+ {
+ writable = pi->IsFootprintLibWritable( libPath );
+ exists = true; // no exception was thrown, lib must exist.
+ }
+ catch( const IO_ERROR& )
+ {
+ // ignore, original values of 'writable' and 'exists' are accurate.
+ }
+
+ if( exists )
+ {
+ if( !writable )
+ {
+ wxString msg = wxString::Format( FMT_LIB_READ_ONLY, GetChars( libPath ) );
+ DisplayError( this, msg );
+ return wxEmptyString;
+ }
+ else
+ {
+ wxString msg = wxString::Format( FMT_OK_OVERWRITE, GetChars( libPath ) );
+
+ if( !IsOK( this, msg ) )
+ return wxEmptyString;
+
+ pi->FootprintLibDelete( libPath );
+ }
+ }
+
+ pi->FootprintLibCreate( libPath );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( this, ioe.errorText );
+ return wxEmptyString;
+ }
+
+ return libPath;
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary()
+{
+ wxString nickname = GetCurrentLib();
+
+ // Legacy libraries are readable, but modifying legacy format is not allowed
+ // So prompt the user if he try to delete a footprint from a legacy lib
+ wxString libfullname = Prj().PcbFootprintLibs()->FindRow(nickname)->GetFullURI();
+ IO_MGR::PCB_FILE_T piType = IO_MGR::GuessPluginTypeFromLibPath( libfullname );
+
+ if( piType == IO_MGR::LEGACY )
+ {
+ DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_DELETE );
+ return false;
+ }
+
+ if( !Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname ) )
+ {
+ wxString msg = wxString::Format(
+ _( "Library '%s' is read only" ),
+ GetChars( nickname )
+ );
+
+ DisplayError( this, msg );
+ return false;
+ }
+
+ wxString fpid_txt = PCB_BASE_FRAME::SelectFootprint( this, nickname,
+ wxEmptyString, wxEmptyString, Prj().PcbFootprintLibs() );
+
+ if( !fpid_txt )
+ return false;
+
+ FPID fpid( fpid_txt );
+ wxString fpname = fpid.GetFootprintName();
+
+ // Confirmation
+ wxString msg = wxString::Format( FMT_OK_DELETE, fpname.GetData(), nickname.GetData() );
+
+ if( !IsOK( this, msg ) )
+ return false;
+
+ try
+ {
+ Prj().PcbFootprintLibs()->FootprintDelete( nickname, fpname );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( this, ioe.errorText );
+ return false;
+ }
+
+ msg.Printf( FMT_MOD_DELETED, fpname.GetData(), nickname.GetData() );
+
+ SetStatusText( msg );
+
+ return true;
+}
+
+
+void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aStoreInNewLib )
+{
+ if( GetBoard()->m_Modules == NULL )
+ {
+ DisplayInfoMessage( this, _( "No footprints to archive!" ) );
+ return;
+ }
+
+ wxString footprintName;
+
+ if( !aStoreInNewLib )
+ {
+ // The footprints are saved in an existing .pretty library in the fp lib table
+ PROJECT& prj = Prj();
+ wxString last_nickname = prj.GetRString( PROJECT::PCB_LIB_NICKNAME );
+ wxString nickname = SelectLibrary( last_nickname );
+
+ if( !nickname ) // Aborted
+ return;
+
+ prj.SetRString( PROJECT::PCB_LIB_NICKNAME, nickname );
+
+ try
+ {
+ FP_LIB_TABLE* tbl = prj.PcbFootprintLibs();
+
+ for( MODULE* curr_fp = GetBoard()->m_Modules; curr_fp; curr_fp = curr_fp->Next() )
+ {
+ if( !curr_fp->GetFPID().GetFootprintName().empty() ) // Can happen with old boards.
+ tbl->FootprintSave( nickname, curr_fp, false );
+ }
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( this, ioe.errorText );
+ }
+ }
+ else
+ {
+ // The footprints are saved in a new .pretty library.
+ // If this library already exists, all previous footprints will be deleted
+ wxString libPath = CreateNewLibrary();
+
+ if( libPath.IsEmpty() ) // Aborted
+ return;
+
+ IO_MGR::PCB_FILE_T piType = IO_MGR::KICAD;
+ PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) );
+
+ for( MODULE* curr_fp = GetBoard()->m_Modules; curr_fp; curr_fp = curr_fp->Next() )
+ {
+ try
+ {
+ if( !curr_fp->GetFPID().GetFootprintName().empty() ) // Can happen with old boards.
+ pi->FootprintSave( libPath, curr_fp );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( this, ioe.errorText );
+ }
+ }
+ }
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::SaveFootprintInLibrary( const wxString& aLibrary,
+ MODULE* aModule,
+ bool aOverwrite,
+ bool aDisplayDialog )
+{
+ if( aModule == NULL )
+ return false;
+
+ SetMsgPanel( aModule );
+
+
+ // Legacy libraries are readable, but modifying legacy format is not allowed
+ // So prompt the user if he try to add/replace a footprint in a legacy lib
+ wxString libfullname = Prj().PcbFootprintLibs()->FindRow( aLibrary )->GetFullURI();
+ IO_MGR::PCB_FILE_T piType = IO_MGR::GuessPluginTypeFromLibPath( libfullname );
+
+ if( piType == IO_MGR::LEGACY )
+ {
+ DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT );
+ return false;
+ }
+
+ // Ask what to use as the footprint name in the library
+ wxString footprintName = aModule->GetFPID().GetFootprintName();
+
+ if( aDisplayDialog )
+ {
+ wxTextEntryDialog dlg( this, _( "Name:" ), FMT_SAVE_MODULE, footprintName );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return false; // canceled by user
+
+ footprintName = dlg.GetValue();
+ footprintName.Trim( true );
+ footprintName.Trim( false );
+
+ if( footprintName.IsEmpty() )
+ return false;
+
+ if( ! MODULE::IsLibNameValid( footprintName ) )
+ {
+ wxString msg = wxString::Format(
+ _("Error:\none of invalid chars '%s' found\nin '%s'" ),
+ MODULE::StringLibNameInvalidChars( true ),
+ GetChars( footprintName ) );
+
+ DisplayError( NULL, msg );
+ return false;
+ }
+
+ aModule->SetFPID( FPID( footprintName ) );
+ }
+
+ // Ensure this footprint has a libname
+ if( footprintName.IsEmpty() )
+ {
+ footprintName = wxT("noname");
+ aModule->SetFPID( FPID( footprintName ) );
+ }
+
+ bool module_exists = false;
+
+ try
+ {
+ FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
+
+ MODULE* m = tbl->FootprintLoad( aLibrary, footprintName );
+
+ if( m )
+ {
+ delete m;
+
+ module_exists = true;
+
+ // an existing footprint is found in current lib
+ if( aDisplayDialog )
+ {
+ wxString msg = wxString::Format( FMT_MOD_EXISTS,
+ footprintName.GetData(), aLibrary.GetData() );
+
+ SetStatusText( msg );
+ }
+
+ if( !aOverwrite )
+ {
+ // Do not save the given footprint: an old one exists
+ return true;
+ }
+ }
+
+ // this always overwrites any existing footprint, but should yell on its
+ // own if the library or footprint is not writable.
+ tbl->FootprintSave( aLibrary, aModule );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( this, ioe.errorText );
+ return false;
+ }
+
+ if( aDisplayDialog )
+ {
+ wxString fmt = module_exists ?
+ _( "Component [%s] replaced in '%s'" ) :
+ _( "Component [%s] added in '%s'" );
+
+ wxString msg = wxString::Format( fmt, footprintName.GetData(), aLibrary.GetData() );
+ SetStatusText( msg );
+ }
+
+ return true;
+}
+
+
+MODULE* PCB_BASE_FRAME::CreateNewModule( const wxString& aModuleName )
+{
+ // Creates a new footprint at position 0,0 which contains the minimal items:
+ // the reference and the value.
+ // Value : initialized to the footprint name.
+ // put on fab layer (front side)
+ // Reference : initialized to a default value (REF**).
+ // put on silkscreen layer (front side)
+
+ wxString moduleName = aModuleName;
+
+ // Ask for the new module name
+ if( moduleName.IsEmpty() )
+ {
+ wxTextEntryDialog dlg( this, FMT_MOD_REF, FMT_MOD_CREATE, moduleName );
+ dlg.SetTextValidator( FILE_NAME_CHAR_VALIDATOR( &moduleName ) );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return NULL; //Aborted by user
+ }
+
+ moduleName.Trim( true );
+ moduleName.Trim( false );
+
+ if( moduleName.IsEmpty() )
+ {
+ DisplayInfoMessage( this, FMT_NO_REF_ABORTED );
+ return NULL;
+ }
+
+ // Creates the new module and add it to the head of the linked list of modules
+ MODULE* module = new MODULE( GetBoard() );
+
+ GetBoard()->Add( module );
+
+ // Update parameters: timestamp ...
+ module->SetLastEditTime();
+
+ // Update its name in lib
+ module->SetFPID( FPID( moduleName ) );
+
+ wxPoint default_pos;
+ BOARD_DESIGN_SETTINGS& settings = GetDesignSettings();
+
+ // Update reference:
+ if( settings.m_RefDefaultText.IsEmpty() )
+ module->SetReference( moduleName );
+ else
+ module->SetReference( settings.m_RefDefaultText );
+
+ module->Reference().SetThickness( settings.m_ModuleTextWidth );
+ module->Reference().SetSize( settings.m_ModuleTextSize );
+ default_pos.y = GetDesignSettings().m_ModuleTextSize.y / 2;
+ module->Reference().SetPosition( default_pos );
+ module->Reference().SetLayer( ToLAYER_ID( settings.m_RefDefaultlayer ) );
+ module->Reference().SetVisible( settings.m_RefDefaultVisibility );
+
+ // Set the value field to a default value
+ if( settings.m_ValueDefaultText.IsEmpty() )
+ module->SetValue( moduleName );
+ else
+ module->SetValue( settings.m_ValueDefaultText );
+
+ module->Value().SetThickness( GetDesignSettings().m_ModuleTextWidth );
+ module->Value().SetSize( GetDesignSettings().m_ModuleTextSize );
+ default_pos.y = -default_pos.y;
+ module->Value().SetPosition( default_pos );
+ module->Value().SetLayer( ToLAYER_ID( settings.m_ValueDefaultlayer ) );
+ module->Value().SetVisible( settings.m_ValueDefaultVisibility );
+
+ SetMsgPanel( module );
+ return module;
+}
+
+
+wxString PCB_BASE_FRAME::SelectLibrary( const wxString& aNicknameExisting )
+{
+ wxArrayString headers;
+
+ headers.Add( _( "Nickname" ) );
+ headers.Add( _( "Description" ) );
+
+ FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();
+
+ std::vector< wxArrayString > itemsToDisplay;
+ std::vector< wxString > nicknames = fptbl->GetLogicalLibs();
+
+ for( unsigned i = 0; i < nicknames.size(); i++ )
+ {
+ wxArrayString item;
+
+ item.Add( nicknames[i] );
+ item.Add( fptbl->GetDescription( nicknames[i] ) );
+
+ itemsToDisplay.push_back( item );
+ }
+
+ EDA_LIST_DIALOG dlg( this, FMT_SELECT_LIB, headers, itemsToDisplay, aNicknameExisting );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return wxEmptyString;
+
+ wxString nickname = dlg.GetTextSelection();
+
+ wxLogDebug( wxT( "Chose footprint library '%s'." ), GetChars( nickname ) );
+
+ return nickname;
+}
diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp
new file mode 100644
index 0000000..3bf9710
--- /dev/null
+++ b/pcbnew/loadcmp.cpp
@@ -0,0 +1,580 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/loadcmp.cpp
+ * @brief Footprints selection and loading functions.
+ */
+
+#include <boost/bind.hpp>
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <pcb_draw_panel_gal.h>
+#include <confirm.h>
+#include <eda_doc.h>
+#include <kicad_string.h>
+#include <pgm_base.h>
+#include <kiway.h>
+#include <wxPcbStruct.h>
+#include <dialog_helpers.h>
+#include <filter_reader.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <fp_lib_table.h>
+#include <fpid.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <io_mgr.h>
+
+#include <pcbnew.h>
+#include <module_editor_frame.h>
+#include <footprint_info.h>
+#include <dialog_get_component.h>
+#include <modview_frame.h>
+#include <wildcards_and_files_ext.h>
+#include <class_pcb_layer_widget.h>
+
+
+static void DisplayCmpDoc( wxString& aName, void* aData );
+
+static FOOTPRINT_LIST MList;
+
+static void clearModuleItemFlags( BOARD_ITEM* aItem )
+{
+ aItem->ClearFlags();
+}
+
+bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
+{
+ MODULE* newModule;
+ PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false );
+
+ if( frame == NULL ) // happens if no board editor opened
+ return false;
+
+ if( aModule == NULL )
+ {
+ if( ! frame->GetBoard() || ! frame->GetBoard()->m_Modules )
+ return false;
+
+ aModule = SelectFootprint( frame->GetBoard() );
+ }
+
+ if( aModule == NULL )
+ return false;
+
+ SetCurItem( NULL );
+
+ Clear_Pcb( false );
+
+ GetBoard()->m_Status_Pcb = 0;
+ newModule = new MODULE( *aModule );
+ newModule->SetParent( GetBoard() );
+ newModule->SetLink( aModule->GetTimeStamp() );
+
+ aModule = newModule;
+
+ newModule->ClearFlags();
+ newModule->RunOnChildren( boost::bind( &clearModuleItemFlags, _1 ) );
+
+ GetBoard()->Add( newModule );
+
+ // Clear references to any net info, because the footprint editor
+ // does know any thing about nets handled by the current edited board.
+ // Morever we do not want to save any reference to an unknown net when
+ // saving the footprint in lib cache
+ // so we force the ORPHANED dummy net info for all pads
+ newModule->ClearAllNets();
+
+ SetCrossHairPosition( wxPoint( 0, 0 ) );
+ PlaceModule( newModule, NULL );
+ newModule->SetPosition( wxPoint( 0, 0 ) ); // cursor in GAL may not be initialized at the moment
+
+ // Put it on FRONT layer,
+ // because this is the default in ModEdit, and in libs
+ if( newModule->GetLayer() != F_Cu )
+ newModule->Flip( newModule->GetPosition() );
+
+ // Put it in orientation 0,
+ // because this is the default orientation in ModEdit, and in libs
+ Rotate_Module( NULL, newModule, 0, false );
+ GetScreen()->ClrModify();
+ Zoom_Automatique( false );
+
+ if( IsGalCanvasActive() )
+ updateView();
+
+ return true;
+}
+
+
+wxString PCB_BASE_FRAME::SelectFootprintFromLibBrowser()
+{
+ // Close the current non-modal Lib browser if opened, and open a new one, in "modal" mode:
+ FOOTPRINT_VIEWER_FRAME* viewer;
+
+ viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, false );
+
+ if( viewer )
+ viewer->Destroy();
+
+ viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true );
+
+ wxString fpid;
+
+ int ret = viewer->ShowModal( &fpid, this );
+ (void) ret; // make static analyser quiet
+
+ //DBG(printf("%s: fpid:'%s'\n", __func__, TO_UTF8( fpid ) );)
+
+ viewer->Destroy();
+
+ return fpid;
+}
+
+
+MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary,
+ FP_LIB_TABLE* aTable,
+ bool aUseFootprintViewer,
+ wxDC* aDC )
+{
+ MODULE* module = NULL;
+ wxPoint curspos = GetCrossHairPosition();
+ wxString moduleName, keys;
+ wxString libName = aLibrary;
+ bool allowWildSeach = true;
+
+ static wxArrayString HistoryList;
+ static wxString lastComponentName;
+
+ // Ask for a component name or key words
+ DIALOG_GET_COMPONENT dlg( this, HistoryList, _( "Load Footprint" ), aUseFootprintViewer );
+
+ dlg.SetComponentName( lastComponentName );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return NULL;
+
+ if( dlg.m_GetExtraFunction )
+ {
+ // SelectFootprintFromLibBrowser() returns the "full" footprint name, i.e.
+ // <lib_name>/<footprint name> or FPID format "lib_name:fp_name:rev#"
+ moduleName = SelectFootprintFromLibBrowser();
+ }
+ else
+ {
+ moduleName = dlg.GetComponentName();
+ }
+
+ if( moduleName.IsEmpty() ) // Cancel command
+ {
+ m_canvas->MoveCursorToCrossHair();
+ return NULL;
+ }
+
+ if( dlg.IsKeyword() ) // Selection by keywords
+ {
+ allowWildSeach = false;
+ keys = moduleName;
+ moduleName = SelectFootprint( this, libName, wxEmptyString, keys, aTable );
+
+ if( moduleName.IsEmpty() ) // Cancel command
+ {
+ m_canvas->MoveCursorToCrossHair();
+ return NULL;
+ }
+ }
+ else if( moduleName.Contains( wxT( "?" ) )
+ || moduleName.Contains( wxT( "*" ) ) ) // Selection wild card
+ {
+ allowWildSeach = false;
+ moduleName = SelectFootprint( this, libName, moduleName, wxEmptyString, aTable );
+
+ if( moduleName.IsEmpty() )
+ {
+ m_canvas->MoveCursorToCrossHair();
+ return NULL; // Cancel command.
+ }
+ }
+
+ FPID fpid;
+
+ wxCHECK_MSG( fpid.Parse( moduleName ) < 0, NULL,
+ wxString::Format( wxT( "Could not parse FPID string '%s'." ),
+ GetChars( moduleName ) ) );
+
+ try
+ {
+ module = loadFootprint( fpid );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxLogDebug( wxT( "An error occurred attemping to load footprint '%s'.\n\nError: %s" ),
+ fpid.Format().c_str(), GetChars( ioe.errorText ) );
+ }
+
+ if( !module && allowWildSeach ) // Search with wild card
+ {
+ allowWildSeach = false;
+
+ wxString wildname = wxChar( '*' ) + moduleName + wxChar( '*' );
+ moduleName = wildname;
+
+ moduleName = SelectFootprint( this, libName, moduleName, wxEmptyString, aTable );
+
+ if( moduleName.IsEmpty() )
+ {
+ m_canvas->MoveCursorToCrossHair();
+ return NULL; // Cancel command.
+ }
+ else
+ {
+ FPID fpid;
+
+ wxCHECK_MSG( fpid.Parse( moduleName ) < 0, NULL,
+ wxString::Format( wxT( "Could not parse FPID string '%s'." ),
+ GetChars( moduleName ) ) );
+
+ try
+ {
+ module = loadFootprint( fpid );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxLogDebug( wxT( "An error occurred attemping to load footprint '%s'.\n\nError: %s" ),
+ fpid.Format().c_str(), GetChars( ioe.errorText ) );
+ }
+ }
+ }
+
+ SetCrossHairPosition( curspos );
+ m_canvas->MoveCursorToCrossHair();
+
+ if( module )
+ {
+ GetBoard()->Add( module, ADD_APPEND );
+
+ lastComponentName = moduleName;
+ AddHistoryComponentName( HistoryList, moduleName );
+
+ module->SetFlags( IS_NEW );
+ module->SetLink( 0 );
+
+ if( IsGalCanvasActive() )
+ module->SetPosition( wxPoint( 0, 0 ) ); // cursor in GAL may not be initialized at the moment
+ else
+ module->SetPosition( curspos );
+
+ module->SetTimeStamp( GetNewTimeStamp() );
+ GetBoard()->m_Status_Pcb = 0;
+
+ // Put it on FRONT layer,
+ // (Can be stored flipped if the lib is an archive built from a board)
+ if( module->IsFlipped() )
+ module->Flip( module->GetPosition() );
+
+ // Place it in orientation 0,
+ // even if it is not saved with orientation 0 in lib
+ // (Can happen if the lib is an archive built from a board)
+ Rotate_Module( NULL, module, 0, false );
+
+ RecalculateAllTracksNetcode();
+
+ if( aDC )
+ module->Draw( m_canvas, aDC, GR_OR );
+ }
+
+ return module;
+}
+
+
+MODULE* PCB_BASE_FRAME::LoadFootprint( const FPID& aFootprintId )
+{
+ MODULE* module = NULL;
+
+ try
+ {
+ module = loadFootprint( aFootprintId );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxLogDebug( wxT( "An error occurred attemping to load footprint '%s'.\n\nError: %s" ),
+ aFootprintId.Format().c_str(), GetChars( ioe.errorText ) );
+ }
+
+ return module;
+}
+
+
+MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId )
+ throw( IO_ERROR, PARSE_ERROR, boost::interprocess::lock_exception )
+{
+ FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();
+
+ wxCHECK_MSG( fptbl, NULL, wxT( "Cannot look up FPID in NULL FP_LIB_TABLE." ) );
+
+ MODULE* module = fptbl->FootprintLoadWithOptionalNickname( aFootprintId );
+
+ // If the module is found, clear all net info,
+ // to be sure there is no broken links
+ // to any netinfo list (should be not needed, but it can be edited from
+ // the footprint editor )
+ if( module )
+ module->ClearAllNets();
+
+ return module;
+}
+
+
+wxString PCB_BASE_FRAME::SelectFootprint( EDA_DRAW_FRAME* aWindow,
+ const wxString& aLibraryName,
+ const wxString& aMask,
+ const wxString& aKeyWord,
+ FP_LIB_TABLE* aTable )
+{
+ static wxString oldName; // Save the name of the last module loaded.
+
+ wxString fpname;
+ wxString msg;
+ wxArrayString libraries;
+
+ std::vector< wxArrayString > rows;
+
+ wxASSERT( aTable != NULL );
+
+ MList.ReadFootprintFiles( aTable, !aLibraryName ? NULL : &aLibraryName );
+
+ if( MList.GetErrorCount() )
+ {
+ MList.DisplayErrors( this );
+ return wxEmptyString;
+ }
+
+ if( MList.GetCount() == 0 )
+ {
+ wxString tmp;
+
+ for( unsigned i = 0; i < libraries.GetCount(); i++ )
+ {
+ tmp += libraries[i] + wxT( "\n" );
+ }
+
+ msg.Printf( _( "No footprints could be read from library file(s):\n\n%s\nin any of "
+ "the library search paths. Verify your system is configured properly "
+ "so the footprint libraries can be found." ), GetChars( tmp ) );
+ DisplayError( aWindow, msg );
+ return wxEmptyString;
+ }
+
+ if( !aKeyWord.IsEmpty() ) // Create a list of modules found by keyword.
+ {
+ for( unsigned ii = 0; ii < MList.GetCount(); ii++ )
+ {
+ if( KeyWordOk( aKeyWord, MList.GetItem( ii ).GetKeywords() ) )
+ {
+ wxArrayString cols;
+ cols.Add( MList.GetItem( ii ).GetFootprintName() );
+ cols.Add( MList.GetItem( ii ).GetNickname() );
+ rows.push_back( cols );
+ }
+ }
+ }
+ else if( !aMask.IsEmpty() ) // Create a list of modules found by pattern
+ {
+ for( unsigned ii = 0; ii < MList.GetCount(); ii++ )
+ {
+ const wxString& candidate = MList.GetItem( ii ).GetFootprintName();
+
+ if( WildCompareString( aMask, candidate, false ) )
+ {
+ wxArrayString cols;
+ cols.Add( MList.GetItem( ii ).GetFootprintName() );
+ cols.Add( MList.GetItem( ii ).GetNickname() );
+ rows.push_back( cols );
+ }
+ }
+ }
+ else // Create the full list of modules
+ {
+ for( unsigned ii = 0; ii < MList.GetCount(); ii++ )
+ {
+ wxArrayString cols;
+ cols.Add( MList.GetItem( ii ).GetFootprintName() );
+ cols.Add( MList.GetItem( ii ).GetNickname() );
+ rows.push_back( cols );
+ }
+ }
+
+ if( !rows.empty() )
+ {
+ wxArrayString headers;
+
+ headers.Add( _( "Footprint" ) );
+ headers.Add( _( "Library" ) );
+
+ msg.Printf( _( "Footprints [%d items]" ), (int) rows.size() );
+
+ EDA_LIST_DIALOG dlg( aWindow, msg, headers, rows, oldName, DisplayCmpDoc );
+
+ if( dlg.ShowModal() == wxID_OK )
+ {
+ fpname = dlg.GetTextSelection();
+
+ fpname = dlg.GetTextSelection( 1 ) + wxT( ":" ) + fpname;
+
+ SkipNextLeftButtonReleaseEvent();
+ }
+ else
+ fpname.Empty();
+ }
+ else
+ {
+ DisplayError( aWindow, _( "No footprint found." ) );
+ fpname.Empty();
+ }
+
+ if( fpname != wxEmptyString )
+ oldName = fpname;
+
+ wxLogDebug( wxT( "Footprint '%s' was selected." ), GetChars( fpname ) );
+
+ return fpname;
+}
+
+
+static void DisplayCmpDoc( wxString& aName, void* aData )
+{
+ FOOTPRINT_INFO* module_info = MList.GetModuleInfo( aName );
+
+ if( !module_info )
+ {
+ aName.Empty();
+ return;
+ }
+
+ aName = _( "Description: " ) + module_info->GetDoc();
+ aName += _( "\nKey words: " ) + module_info->GetKeywords();
+}
+
+
+MODULE* FOOTPRINT_EDIT_FRAME::SelectFootprint( BOARD* aPcb )
+{
+ static wxString oldName; // Save name of last module selected.
+
+ wxString fpname;
+ wxString msg;
+ wxArrayString listnames;
+ MODULE* module = aPcb->m_Modules;
+
+ for( ; module; module = module->Next() )
+ listnames.Add( module->GetReference() );
+
+ msg.Printf( _( "Footprints [%u items]" ), (unsigned) listnames.GetCount() );
+
+ wxArrayString headers;
+
+ headers.Add( _( "Footprint" ) );
+
+ std::vector<wxArrayString> itemsToDisplay;
+
+ // Conversion from wxArrayString to vector of ArrayString
+ for( unsigned i = 0; i < listnames.GetCount(); i++ )
+ {
+ wxArrayString item;
+
+ item.Add( listnames[i] );
+ itemsToDisplay.push_back( item );
+ }
+
+ EDA_LIST_DIALOG dlg( this, msg, headers, itemsToDisplay, wxEmptyString, NULL, NULL, SORT_LIST );
+
+ if( dlg.ShowModal() == wxID_OK )
+ fpname = dlg.GetTextSelection();
+ else
+ return NULL;
+
+ oldName = fpname;
+
+ module = aPcb->m_Modules;
+
+ for( ; module; module = module->Next() )
+ {
+ if( fpname == module->GetReference() )
+ break;
+ }
+
+ return module;
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs( wxCommandEvent& aEvent )
+{
+ wxString curLibPath = getLibPath();
+ wxString dstLibPath = CreateNewLibrary();
+
+ if( !dstLibPath )
+ return; // user aborted in CreateNewLibrary()
+
+ wxBusyCursor dummy;
+ wxString msg;
+
+ IO_MGR::PCB_FILE_T dstType = IO_MGR::GuessPluginTypeFromLibPath( dstLibPath );
+ IO_MGR::PCB_FILE_T curType = IO_MGR::GuessPluginTypeFromLibPath( curLibPath );
+
+ try
+ {
+ PLUGIN::RELEASER cur( IO_MGR::PluginFind( curType ) );
+ PLUGIN::RELEASER dst( IO_MGR::PluginFind( dstType ) );
+
+ wxArrayString mods = cur->FootprintEnumerate( curLibPath );
+
+ for( unsigned i = 0; i < mods.size(); ++i )
+ {
+ std::auto_ptr<MODULE> m( cur->FootprintLoad( curLibPath, mods[i] ) );
+ dst->FootprintSave( dstLibPath, m.get() );
+
+ msg = wxString::Format( _( "Footprint '%s' saved" ),
+ GetChars( mods[i] ) );
+ SetStatusText( msg );
+
+ // m is deleted here by auto_ptr.
+ }
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ DisplayError( this, ioe.errorText );
+ return;
+ }
+
+ msg = wxString::Format(
+ _( "Footprint library '%s' saved as '%s'." ),
+ GetChars( curLibPath ), GetChars( dstLibPath ) );
+
+ DisplayInfoMessage( this, msg );
+
+ SetStatusText( wxEmptyString );
+}
diff --git a/pcbnew/magnetic_tracks_functions.cpp b/pcbnew/magnetic_tracks_functions.cpp
new file mode 100644
index 0000000..f124e9b
--- /dev/null
+++ b/pcbnew/magnetic_tracks_functions.cpp
@@ -0,0 +1,306 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file magnetic_tracks_functions.cpp
+ */
+
+/* functions used to control the cursor position, when creating a track
+ * and when the "magnetic tracks" option is on
+ * (the current created track is kept near existing tracks
+ * the distance is the clearance between tracks)
+ */
+
+#include <fctsys.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_track.h>
+
+#include <protos.h>
+#include <pcbnew_id.h>
+
+
+/**
+ * Function Join
+ * finds the point where line segment (b1,b0) intersects with segment (a1,a0).
+ * If that point would be outside of (a0,a1), the respective endpoint is used.
+ * Join returns the point in "res" and "true" if a suitable point was found,
+ * "false" if both lines are parallel or if the length of either segment is zero.
+ */
+static bool Join( wxPoint* aIntersectPoint, wxPoint a0, wxPoint a1, wxPoint b0, wxPoint b1 )
+{
+ /* References:
+ http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/
+ http://www.gekkou.co.uk/blogs/monologues/2007/12/13/1197586800000.html
+ */
+
+ double denom;
+ double t;
+
+ // if either segment is zero length
+ if( a1.x==a0.x && a1.y==a0.y )
+ return false;
+
+ if( b1.x==b0.x && b1.y==b0.y )
+ return false;
+
+ a1 -= a0;
+ b1 -= b0;
+
+ b0 -= a0;
+
+ denom = (double) b1.y * a1.x - (double) b1.x * a1.y;
+
+ if( !denom )
+ {
+ return false; // parallel
+ }
+
+ t = ((double) b1.y * b0.x - (double) b1.x * b0.y ) / denom;
+
+ t = std::min( std::max( t, 0.0 ), 1.0 );
+
+ aIntersectPoint->x = KiROUND( a0.x + t * a1.x );
+ aIntersectPoint->y = KiROUND( a0.y + t * a1.y );
+
+ return true;
+}
+
+
+/*
+ * "Project" finds the projection of a grid point on a track. This is the point
+ * from where we want to draw new orthogonal tracks when starting on a track.
+ */
+bool Project( wxPoint* aNearPos, wxPoint on_grid, const TRACK* track )
+{
+ if( track->GetStart ()== track->GetEnd() )
+ return false;
+
+ wxPoint vec = track->GetEnd() - track->GetStart();
+
+ double t = double( on_grid.x - track->GetStart().x ) * vec.x +
+ double( on_grid.y - track->GetStart().y ) * vec.y;
+
+ t /= (double) vec.x * vec.x + (double) vec.y * vec.y;
+ t = std::min( std::max( t, 0.0 ), 1.0 );
+
+ aNearPos->x = KiROUND( track->GetStart().x + t * vec.x );
+ aNearPos->y = KiROUND( track->GetStart().y + t * vec.y );
+
+ return true;
+}
+
+
+/**
+ * Function Magnetize
+ * tests to see if there are any magnetic items within near reach of the given
+ * "curpos". If yes, then curpos is adjusted appropriately according to that
+ * near magnetic item and true is returned.
+ * @param frame = the current frame
+ * @param aCurrentTool = the current tool id (from vertical right toolbar)
+ * @param aGridSize = the current grid size
+ * @param on_grid = the on grid position near initial position ( often on_grid = curpos)
+ * @param curpos The initial position, and what to adjust if a change is needed.
+ * @return bool - true if the position was adjusted magnetically, else false.
+ */
+bool Magnetize( PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize aGridSize,
+ wxPoint on_grid, wxPoint* curpos )
+{
+ bool doCheckNet = g_MagneticPadOption != capture_always && g_Drc_On;
+ bool doTrack = false;
+ bool doPad = false;
+ bool amMovingVia = false;
+
+ BOARD* m_Pcb = frame->GetBoard();
+ TRACK* currTrack = g_CurrentTrackSegment;
+ BOARD_ITEM* currItem = frame->GetCurItem();
+ PCB_SCREEN* screen = frame->GetScreen();
+ wxPoint pos = frame->RefPos( true );
+
+ // D( printf( "currTrack=%p currItem=%p currTrack->Type()=%d currItem->Type()=%d\n", currTrack, currItem, currTrack ? currTrack->Type() : 0, currItem ? currItem->Type() : 0 ); )
+
+ if( !currTrack && currItem && currItem->Type()==PCB_VIA_T && currItem->GetFlags() )
+ {
+ // moving a VIA
+ currTrack = (TRACK*) currItem;
+ amMovingVia = true;
+
+ return false; // comment this return out and play with it.
+ }
+ else if( currItem != currTrack )
+ {
+ currTrack = NULL;
+ }
+
+ if( g_MagneticPadOption == capture_always )
+ doPad = true;
+
+ if( g_MagneticTrackOption == capture_always )
+ doTrack = true;
+
+ if( aCurrentTool == ID_TRACK_BUTT || amMovingVia )
+ {
+ int q = capture_cursor_in_track_tool;
+
+ if( g_MagneticPadOption == q )
+ doPad = true;
+
+ if( g_MagneticTrackOption == q )
+ doTrack = true;
+ }
+
+ // D(printf("doPad=%d doTrack=%d aCurrentTool=%d amMovingVia=%d\n", doPad, doTrack, aCurrentTool, amMovingVia );)
+
+ // The search precedence order is pads, then tracks/vias
+
+ if( doPad )
+ {
+ LSET layer_mask( screen->m_Active_Layer );
+ D_PAD* pad = m_Pcb->GetPad( pos, layer_mask );
+
+ if( pad )
+ {
+ if( doCheckNet && currTrack && currTrack->GetNetCode() != pad->GetNetCode() )
+ return false;
+
+ *curpos = pad->GetPosition();
+ return true;
+ }
+ }
+
+ // after pads, only track & via tests remain, skip them if not desired
+ if( doTrack )
+ {
+ LAYER_ID layer = screen->m_Active_Layer;
+
+ for( TRACK* via = m_Pcb->m_Track;
+ via && (via = via->GetVia( *curpos, layer )) != NULL;
+ via = via->Next() )
+ {
+ if( via != currTrack ) // a via cannot influence itself
+ {
+ if( !doCheckNet || !currTrack || currTrack->GetNetCode() == via->GetNetCode() )
+ {
+ *curpos = via->GetStart();
+ // D(printf("via hit\n");)
+ return true;
+ }
+ }
+ }
+
+ if( !currTrack )
+ {
+ LSET layer_mask( layer );
+
+ TRACK* track = m_Pcb->GetTrack( m_Pcb->m_Track, pos, layer_mask );
+
+ if( !track || track->Type() != PCB_TRACE_T )
+ {
+ // D(printf("!currTrack and track=%p not found, layer_mask=0x%X\n", track, layer_mask );)
+ return false;
+ }
+
+ // D( printf( "Project\n" ); )
+ return Project( curpos, on_grid, track );
+ }
+
+ /*
+ * In two segment mode, ignore the final segment if it's inside a grid square.
+ */
+ if( !amMovingVia && currTrack && g_TwoSegmentTrackBuild && currTrack->Back()
+ && currTrack->GetStart().x - aGridSize.x < currTrack->GetEnd().x
+ && currTrack->GetStart().x + aGridSize.x > currTrack->GetEnd().x
+ && currTrack->GetStart().y - aGridSize.y < currTrack->GetEnd().y
+ && currTrack->GetStart().y + aGridSize.y > currTrack->GetEnd().y )
+ {
+ currTrack = currTrack->Back();
+ }
+
+
+ for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() )
+ {
+ if( track->Type() != PCB_TRACE_T )
+ continue;
+
+ if( doCheckNet && currTrack && currTrack->GetNetCode() != track->GetNetCode() )
+ continue;
+
+ if( m_Pcb->IsLayerVisible( track->GetLayer() ) == false )
+ continue;
+
+ // omit the layer check if moving a via
+ if( !amMovingVia && !track->IsOnLayer( layer ) )
+ continue;
+
+ if( !track->HitTest( *curpos ) )
+ continue;
+
+ // D(printf( "have track prospect\n");)
+
+ if( Join( curpos, track->GetStart(), track->GetEnd(), currTrack->GetStart(), currTrack->GetEnd() ) )
+ {
+ // D(printf( "join currTrack->Type()=%d\n", currTrack->Type() );)
+ return true;
+ }
+
+ if( aCurrentTool == ID_TRACK_BUTT || amMovingVia )
+ {
+ // At this point we have a drawing mouse on a track, we are drawing
+ // a new track and that new track is parallel to the track the
+ // mouse is on. Find the nearest end point of the track under mouse
+ // to the mouse and return that.
+ double distStart = GetLineLength( *curpos, track->GetStart() );
+ double distEnd = GetLineLength( *curpos, track->GetEnd() );
+
+ // if track not via, or if its a via dragging but not with its adjacent track
+ if( currTrack->Type() != PCB_VIA_T ||
+ ( currTrack->GetStart() != track->GetStart() && currTrack->GetStart() != track->GetEnd() ))
+ {
+ double max_dist = currTrack->GetWidth() / 2.0f;
+
+ if( distStart <= max_dist )
+ {
+ // D(printf("nearest end is start\n");)
+ *curpos = track->GetStart();
+ return true;
+ }
+
+ if( distEnd <= max_dist )
+ {
+ // D(printf("nearest end is end\n");)
+ *curpos = track->GetEnd();
+ return true;
+ }
+
+ // @todo otherwise confine curpos such that it stays centered within "track"
+ }
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/pcbnew/menubar_modedit.cpp b/pcbnew/menubar_modedit.cpp
new file mode 100644
index 0000000..b7e1e83
--- /dev/null
+++ b/pcbnew/menubar_modedit.cpp
@@ -0,0 +1,373 @@
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/menubar_modedit.cpp
+ * @brief (Re)Create the main menubar for the module editor
+ */
+#include <fctsys.h>
+#include <pgm_base.h>
+
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <module_editor_frame.h>
+#include <menus_helpers.h>
+
+#include <pcbnew_id.h>
+#include <hotkeys.h>
+#include <help_common_strings.h>
+
+
+void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
+{
+ // Create and try to get the current menubar
+ wxMenuBar* menuBar = GetMenuBar();
+
+ if( !menuBar )
+ menuBar = new wxMenuBar();
+
+ // Delete all existing menus so they can be rebuilt.
+ // This allows language changes of the menu text on the fly.
+ menuBar->Freeze();
+
+ while( menuBar->GetMenuCount() )
+ delete menuBar->Remove( 0 );
+
+ // Recreate all menus:
+ wxString text;
+
+ // Menu File:
+ wxMenu* fileMenu = new wxMenu;
+
+ // Active library selection
+ AddMenuItem( fileMenu, ID_MODEDIT_SELECT_CURRENT_LIB, _("Set Acti&ve Library"),
+ _( "Select active library" ),
+ KiBitmap( open_library_xpm ) );
+ fileMenu->AppendSeparator();
+
+ // New module
+ AddMenuItem( fileMenu, ID_MODEDIT_NEW_MODULE,
+ _( "&New Footprint" ), _( "Create new footprint" ),
+ KiBitmap( new_footprint_xpm ) );
+
+ // Open submenu
+ wxMenu* openSubmenu = new wxMenu;
+
+ // from File
+ AddMenuItem( openSubmenu, ID_MODEDIT_IMPORT_PART,
+ _( "&Import Footprint From File" ),
+ _( "Import footprint from an existing file" ),
+ KiBitmap( import_module_xpm ) );
+
+ // from Library
+ AddMenuItem( openSubmenu, ID_MODEDIT_LOAD_MODULE,
+ _( "Load Footprint From Current Li&brary" ),
+ _( "Open a footprint from library" ),
+ KiBitmap( module_xpm ) );
+
+ // from current Board
+ AddMenuItem( openSubmenu, ID_MODEDIT_LOAD_MODULE_FROM_BOARD,
+ _( "Load Footprint From &Current Board" ),
+ _( "Load a footprint from the current board" ),
+ KiBitmap( load_module_board_xpm ) );
+
+ /* Append openSubmenu to fileMenu */
+ AddMenuItem( fileMenu, openSubmenu, -1,
+ _( "&Load Footprint" ),
+ _( "Load footprint" ),
+ KiBitmap( open_document_xpm ) );
+ fileMenu->AppendSeparator();
+
+ // Save the currently loaded legacy library as an s-expression library.
+ AddMenuItem( fileMenu, ID_MODEDIT_SAVE_LIBRARY_AS,
+ _( "Save &Current Library As..." ),
+ _( "Save entire current library under a new name." ),
+ KiBitmap( copy_library_xpm ) );
+
+ // Save module
+ text = AddHotkeyName( _( "&Save Footprint in Active Library" ),
+ m_hotkeysDescrList, HK_SAVE_MODULE );
+
+ AddMenuItem( fileMenu, ID_MODEDIT_SAVE_LIBMODULE, text,
+ _( "Save footprint in active library" ),
+ KiBitmap( save_library_xpm ) );
+
+ // Save module in new lib
+ AddMenuItem( fileMenu, ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
+ _( "S&ave Footprint in New Library" ),
+ _( "Create a new library and save current footprint into it" ),
+ KiBitmap( new_library_xpm ) );
+
+ // Export module
+ AddMenuItem( fileMenu, ID_MODEDIT_EXPORT_PART,
+ _( "&Export Footprint" ),
+ _( "Save currently loaded footprint into file" ),
+ KiBitmap( export_module_xpm ) );
+
+ // Import DXF File
+ AddMenuItem( fileMenu, ID_GEN_IMPORT_DXF_FILE,
+ _( "&Import DXF File" ),
+ _( "Import a 2D Drawing DXF file to Pcbnew on the Drawings layer" ),
+ KiBitmap( import_xpm ) );
+
+ fileMenu->AppendSeparator();
+
+ // Print
+ AddMenuItem( fileMenu, wxID_PRINT,
+ _( "&Print" ),
+ _( "Print current footprint" ),
+ KiBitmap( plot_xpm ) );
+
+ // Separator
+ fileMenu->AppendSeparator();
+
+ // Close editor
+ AddMenuItem( fileMenu, wxID_EXIT,
+ _( "Cl&ose" ),
+ _( "Close footprint editor" ),
+ KiBitmap( exit_xpm ) );
+
+ //----- Edit menu ------------------
+ wxMenu* editMenu = new wxMenu;
+
+ // Undo
+ text = AddHotkeyName( _( "&Undo" ), m_hotkeysDescrList, HK_UNDO );
+ AddMenuItem( editMenu, wxID_UNDO,
+ text, _( "Undo last action" ),
+ KiBitmap( undo_xpm ) );
+
+ // Redo
+ text = AddHotkeyName( _( "&Redo" ), m_hotkeysDescrList, HK_REDO );
+ AddMenuItem( editMenu, wxID_REDO,
+ text, _( "Redo last action" ),
+ KiBitmap( redo_xpm ) );
+
+ // Delete items
+ AddMenuItem( editMenu, ID_MODEDIT_DELETE_TOOL,
+ _( "&Delete" ), _( "Delete objects with eraser" ),
+ KiBitmap( delete_xpm ) );
+
+ // Separator
+ editMenu->AppendSeparator();
+
+ // Properties
+ AddMenuItem( editMenu, ID_MODEDIT_EDIT_MODULE_PROPERTIES,
+ _( "Edit &Properties" ),
+ _( "Edit footprint properties" ),
+ KiBitmap( module_options_xpm ) );
+
+ // Dimensions submenu
+ wxMenu* dimensions_Submenu = new wxMenu;
+
+ // User grid size
+ AddMenuItem( dimensions_Submenu, ID_PCB_USER_GRID_SETUP,
+ _( "&User Grid Size" ), _( "Adjust user grid" ),
+ KiBitmap( grid_xpm ) );
+
+ // Sizes and Widths
+ AddMenuItem( dimensions_Submenu, ID_PCB_DRAWINGS_WIDTHS_SETUP,
+ _( "&Size and Width" ),
+ _( "Adjust width for texts and drawings" ),
+ KiBitmap( options_text_xpm ) );
+
+ // Pad settings
+ AddMenuItem( dimensions_Submenu, ID_MODEDIT_PAD_SETTINGS,
+ _( "&Pad Setting" ), _( "Edit settings for new pads" ),
+ KiBitmap( pad_dimensions_xpm ) );
+
+ //--------- View menu ----------------
+ wxMenu* viewMenu = new wxMenu;
+
+ /* Important Note for ZOOM IN and ZOOM OUT commands from menubar:
+ * we cannot add hotkey info here, because the hotkey HK_ZOOM_IN and HK_ZOOM_OUT
+ * events(default = WXK_F1 and WXK_F2) are *NOT* equivalent to this menu command:
+ * zoom in and out from hotkeys are equivalent to the pop up menu zoom
+ * From here, zooming is made around the screen center
+ * From hotkeys, zooming is made around the mouse cursor position
+ * (obviously not possible from the toolbar or menubar command)
+ *
+ * in other words HK_ZOOM_IN and HK_ZOOM_OUT *are NOT* accelerators
+ * for Zoom in and Zoom out sub menus
+ */
+ text = AddHotkeyName( _( "Zoom &In" ), m_hotkeysDescrList,
+ HK_ZOOM_IN, IS_ACCELERATOR );
+ AddMenuItem( viewMenu, ID_ZOOM_IN, text, HELP_ZOOM_IN, KiBitmap( zoom_in_xpm ) );
+
+ text = AddHotkeyName( _( "Zoom &Out" ), m_hotkeysDescrList,
+ HK_ZOOM_OUT, IS_ACCELERATOR );
+ AddMenuItem( viewMenu, ID_ZOOM_OUT, text, HELP_ZOOM_OUT, KiBitmap( zoom_out_xpm ) );
+
+ text = AddHotkeyName( _( "&Fit on Screen" ), m_hotkeysDescrList,
+ HK_ZOOM_AUTO );
+ AddMenuItem( viewMenu, ID_ZOOM_PAGE, text, HELP_ZOOM_FIT,
+ KiBitmap( zoom_fit_in_page_xpm ) );
+
+ text = AddHotkeyName( _( "&Redraw" ), m_hotkeysDescrList, HK_ZOOM_REDRAW );
+ AddMenuItem( viewMenu, ID_ZOOM_REDRAW, text,
+ HELP_ZOOM_REDRAW, KiBitmap( zoom_redraw_xpm ) );
+
+ viewMenu->AppendSeparator();
+
+ // 3D view
+ text = AddHotkeyName( _( "&3D Viewer" ), m_hotkeysDescrList, HK_3D_VIEWER );
+ AddMenuItem( viewMenu, ID_MENU_PCB_SHOW_3D_FRAME, text, _( "Show footprint in 3D viewer" ),
+ KiBitmap( three_d_xpm ) );
+
+ // Add canvas selection
+ viewMenu->AppendSeparator();
+
+ text = AddHotkeyName( _( "&Switch Canvas to Default" ), m_hotkeysDescrList,
+ HK_CANVAS_DEFAULT );
+
+ AddMenuItem( viewMenu, ID_MENU_CANVAS_DEFAULT,
+ text, _( "Switch the canvas implementation to default" ),
+ KiBitmap( tools_xpm ) );
+
+ text = AddHotkeyName( _( "Switch Canvas to Open&GL" ), m_hotkeysDescrList,
+ HK_CANVAS_OPENGL );
+
+ AddMenuItem( viewMenu, ID_MENU_CANVAS_OPENGL,
+ text, _( "Switch the canvas implementation to OpenGL" ),
+ KiBitmap( tools_xpm ) );
+
+ text = AddHotkeyName( _( "Switch Canvas to &Cairo" ), m_hotkeysDescrList,
+ HK_CANVAS_CAIRO );
+
+ AddMenuItem( viewMenu, ID_MENU_CANVAS_CAIRO,
+ text, _( "Switch the canvas implementation to Cairo" ),
+ KiBitmap( tools_xpm ) );
+
+ //-------- Place menu --------------------
+ wxMenu* placeMenu = new wxMenu;
+
+ // Pad
+ AddMenuItem( placeMenu, ID_MODEDIT_PAD_TOOL,
+ _( "&Pad" ), _( "Add pad" ),
+ KiBitmap( pad_xpm ) );
+
+ placeMenu->AppendSeparator();
+
+ // Circle
+ AddMenuItem( placeMenu, ID_MODEDIT_CIRCLE_TOOL,
+ _( "&Circle" ), _( "Add graphic circle" ),
+ KiBitmap( add_circle_xpm ) );
+
+ // Line or Polygon
+ AddMenuItem( placeMenu, ID_MODEDIT_LINE_TOOL,
+ _( "&Line or Polygon" ),
+ _( "Add graphic line or polygon" ),
+ KiBitmap( add_polygon_xpm ) );
+
+ // Arc
+ AddMenuItem( placeMenu, ID_MODEDIT_ARC_TOOL,
+ _( "&Arc" ), _( "Add graphic arc" ),
+ KiBitmap( add_arc_xpm ) );
+
+ // Text
+ AddMenuItem( placeMenu, ID_MODEDIT_TEXT_TOOL,
+ _( "&Text" ), _( "Add graphic text" ),
+ KiBitmap( add_text_xpm ) );
+
+ placeMenu->AppendSeparator();
+
+ // Anchor
+ AddMenuItem( placeMenu, ID_MODEDIT_ANCHOR_TOOL,
+ _( "A&nchor" ),
+ _( "Place footprint reference anchor" ),
+ KiBitmap( anchor_xpm ) );
+
+
+ //----- Preferences menu -----------------
+ wxMenu* prefs_menu = new wxMenu;
+
+ AddMenuItem( prefs_menu, ID_PCB_LIB_WIZARD,
+ _( "&Footprint Libraries Wizard" ), _( "Add footprint libraries with wizard" ),
+ KiBitmap( wizard_add_fplib_small_xpm ) );
+
+ AddMenuItem( prefs_menu, ID_PCB_LIB_TABLE_EDIT,
+ _( "Footprint Li&braries Manager" ), _( "Configure footprint libraries" ),
+ KiBitmap( library_table_xpm ) );
+
+ // Path configuration edit dialog.
+ AddMenuItem( prefs_menu,
+ ID_PREFERENCES_CONFIGURE_PATHS,
+ _( "Configure Pa&ths" ),
+ _( "Edit path configuration environment variables" ),
+ KiBitmap( editor_xpm ) );
+
+ // Settings
+ AddMenuItem( prefs_menu, wxID_PREFERENCES,
+ _( "&Settings" ), _( "Change the footprint editor settings." ),
+ KiBitmap( preference_xpm ) );
+
+ // Language submenu
+ Pgm().AddMenuLanguageList( prefs_menu );
+
+ // Hotkey submenu
+ AddHotkeyConfigMenu( prefs_menu );
+
+ //----- Help menu --------------------
+ wxMenu* helpMenu = new wxMenu;
+
+ // Version info
+ AddHelpVersionInfoMenuEntry( helpMenu );
+
+ // Contents
+ AddMenuItem( helpMenu, wxID_HELP,
+ _( "Pcbnew &Manual" ),
+ _( "Open the Pcbnew Manual" ),
+ KiBitmap( online_help_xpm ) );
+
+ AddMenuItem( helpMenu, wxID_INDEX,
+ _( "&Getting Started in KiCad" ),
+ _( "Open the \"Getting Started in KiCad\" guide for beginners" ),
+ KiBitmap( help_xpm ) );
+
+ // About Pcbnew
+ helpMenu->AppendSeparator();
+ AddMenuItem( helpMenu, wxID_ABOUT,
+ _( "&About KiCad" ),
+ _( "About KiCad" ),
+ KiBitmap( info_xpm ) );
+
+ // Append menus to the menubar
+ menuBar->Append( fileMenu, _( "&File" ) );
+ menuBar->Append( editMenu, _( "&Edit" ) );
+ menuBar->Append( viewMenu, _( "&View" ) );
+ menuBar->Append( placeMenu, _( "&Place" ) );
+ menuBar->Append( prefs_menu, _( "P&references" ) );
+ menuBar->Append( dimensions_Submenu, _( "Di&mensions" ) );
+ menuBar->Append( helpMenu, _( "&Help" ) );
+
+ menuBar->Thaw();
+
+ // Associate the menu bar with the frame, if no previous menubar
+ if( GetMenuBar() == NULL )
+ SetMenuBar( menuBar );
+ else
+ menuBar->Refresh();
+}
diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp
new file mode 100644
index 0000000..84ba357
--- /dev/null
+++ b/pcbnew/menubar_pcbframe.cpp
@@ -0,0 +1,682 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file menubar_pcbframe.cpp
+ * Pcbnew editor menu bar
+ */
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <hotkeys.h>
+#include <pcbnew_id.h>
+
+#include <help_common_strings.h>
+#include <menus_helpers.h>
+
+void PCB_EDIT_FRAME::ReCreateMenuBar()
+{
+ wxString text;
+ wxMenuBar* menuBar = GetMenuBar();
+ wxMenuItem * menutitem;
+
+ wxFileHistory& fhist = Kiface().GetFileHistory();
+
+ if( !menuBar )
+ menuBar = new wxMenuBar();
+
+ // Delete all existing menus so they can be rebuilt.
+ // This allows language changes of the menu text on the fly.
+ menuBar->Freeze();
+
+ while( menuBar->GetMenuCount() )
+ delete menuBar->Remove( 0 );
+
+ // Recreate all menus:
+
+ // Create File Menu
+ wxMenu* filesMenu = new wxMenu;
+
+ if( Kiface().IsSingle() ) // not when under a project mgr
+ {
+ AddMenuItem( filesMenu, ID_NEW_BOARD,
+ _( "&New" ),
+ _( "Clear current board and initialize a new one" ),
+ KiBitmap( new_pcb_xpm ) );
+
+ text = AddHotkeyName( _( "&Open" ), m_hotkeysDescrList, HK_LOAD_BOARD );
+ AddMenuItem( filesMenu, ID_LOAD_FILE, text,
+ _( "Delete current board and load new board" ),
+ KiBitmap( open_brd_file_xpm ) );
+ }
+
+ // Load Recent submenu
+ static wxMenu* openRecentMenu;
+
+ // Add this menu to list menu managed by m_fileHistory
+ // (the file history will be updated when adding/removing files in history
+ if( openRecentMenu )
+ fhist.RemoveMenu( openRecentMenu );
+
+ openRecentMenu = new wxMenu();
+
+ fhist.UseMenu( openRecentMenu );
+ fhist.AddFilesToMenu();
+
+ if( Kiface().IsSingle() ) // not when under a project mgr
+ {
+ AddMenuItem( filesMenu, openRecentMenu,
+ -1, _( "Open &Recent" ),
+ _( "Open a recent opened board" ),
+ KiBitmap( open_project_xpm ) );
+ }
+
+ menutitem = AddMenuItem( filesMenu, ID_APPEND_FILE,
+ _( "&Append Board" ),
+ _( "Append another Pcbnew board to the current loaded board. Available only when Pcbnew runs in stand alone mode" ),
+ KiBitmap( import_xpm ) );
+ if( ! Kiface().IsSingle() ) // disable when under a project mgr
+ menutitem->Enable( false );
+
+
+ filesMenu->AppendSeparator();
+
+ text = AddHotkeyName( _( "&Save" ), m_hotkeysDescrList, HK_SAVE_BOARD );
+ AddMenuItem( filesMenu, ID_SAVE_BOARD, text,
+ _( "Save current board" ),
+ KiBitmap( save_xpm ) );
+
+ // Save as menu:
+ // under a project mgr we do not want to modify the board filename
+ // to keep consistency with the project mgr which expects files names same as prj name
+ // for main files
+ // when not under a project mgr, we are free to change filenames, cwd ...
+ if( Kiface().IsSingle() ) // not when under a project mgr (pcbnew is run as stand alone)
+ {
+ text = AddHotkeyName( _( "Sa&ve As..." ), m_hotkeysDescrList, HK_SAVE_BOARD_AS );
+ AddMenuItem( filesMenu, ID_SAVE_BOARD_AS, text,
+ _( "Save the current board as..." ),
+ KiBitmap( save_as_xpm ) );
+ }
+ // under a project mgr, we can save a copy of the board,
+ // but do not change the current board file name
+ else
+ {
+ text = AddHotkeyName( _( "Sa&ve Copy As..." ), m_hotkeysDescrList, HK_SAVE_BOARD_AS );
+ AddMenuItem( filesMenu, ID_COPY_BOARD_AS, text,
+ _( "Save a copy of the current board as..." ),
+ KiBitmap( save_as_xpm ) );
+ }
+
+ filesMenu->AppendSeparator();
+
+ AddMenuItem( filesMenu, ID_MENU_READ_BOARD_BACKUP_FILE,
+ _( "Revert to Las&t" ),
+ _( "Clear board and get previous backup version of board" ),
+ KiBitmap( revert_pcbnew_xpm ) );
+
+ AddMenuItem( filesMenu, ID_MENU_RECOVER_BOARD_AUTOSAVE,
+ _( "Resc&ue" ),
+ _( "Clear board and get last rescue file automatically saved by Pcbnew" ),
+ KiBitmap( rescue_pcbnew_xpm ) );
+ filesMenu->AppendSeparator();
+
+ //----- Fabrication Outputs submenu -----------------------------------------
+ wxMenu* fabricationOutputsMenu = new wxMenu;
+ AddMenuItem( fabricationOutputsMenu, ID_PCB_GEN_POS_MODULES_FILE,
+ _( "Footprint &Position (.pos) File" ),
+ _( "Generate footprint position file for pick and place" ),
+ KiBitmap( post_compo_xpm ) );
+
+ AddMenuItem( fabricationOutputsMenu, ID_PCB_GEN_DRILL_FILE,
+ _( "&Drill (.drl) File" ),
+ _( "Generate excellon2 drill file" ),
+ KiBitmap( post_drill_xpm ) );
+
+ AddMenuItem( fabricationOutputsMenu, ID_GEN_EXPORT_FILE_MODULE_REPORT,
+ _( "&Footprint (.rpt) Report" ),
+ _( "Create a report of all footprints on the current board" ),
+ KiBitmap( tools_xpm ) );
+
+ AddMenuItem( fabricationOutputsMenu, ID_PCB_GEN_D356_FILE,
+ _( "IPC-D-356 Netlist File" ),
+ _( "Generate IPC-D-356 netlist file" ),
+ KiBitmap( netlist_xpm ) );
+
+ AddMenuItem( fabricationOutputsMenu, ID_PCB_GEN_BOM_FILE_FROM_BOARD,
+ _( "&BOM File" ),
+ _( "Create a bill of materials from schematic" ),
+ KiBitmap( bom_xpm ) );
+
+ AddMenuItem( filesMenu, fabricationOutputsMenu,
+ -1, _( "&Fabrication Outputs" ),
+ _( "Generate files for fabrication" ),
+ KiBitmap( fabrication_xpm ) );
+
+ //----- Import submenu ------------------------------------------------------
+ wxMenu* submenuImport = new wxMenu();
+
+ AddMenuItem( submenuImport, ID_GEN_IMPORT_SPECCTRA_SESSION,
+ _( "&Specctra Session" ),
+ _( "Import a routed \"Specctra Session\" (*.ses) file" ),
+ KiBitmap( import_xpm ) );
+
+ AddMenuItem( submenuImport, ID_GEN_IMPORT_DXF_FILE,
+ _( "&DXF File" ),
+ _( "Import a 2D Drawing DXF file to Pcbnew on the Drawings layer" ),
+ KiBitmap( import_xpm ) );
+
+ AddMenuItem( filesMenu, submenuImport,
+ ID_GEN_IMPORT_FILE, _( "&Import" ),
+ _( "Import files" ), KiBitmap( import_xpm ) );
+
+
+ //----- Export submenu ------------------------------------------------------
+ wxMenu* submenuexport = new wxMenu();
+
+ AddMenuItem( submenuexport, ID_GEN_EXPORT_SPECCTRA,
+ _( "&Specctra DSN" ),
+ _( "Export the current board to a \"Specctra DSN\" file" ),
+ KiBitmap( export_dsn_xpm ) );
+
+ AddMenuItem( submenuexport, ID_GEN_EXPORT_FILE_GENCADFORMAT,
+ _( "&GenCAD" ), _( "Export GenCAD format" ),
+ KiBitmap( export_xpm ) );
+
+ AddMenuItem( submenuexport, ID_GEN_EXPORT_FILE_VRML,
+ _( "&VRML" ),
+ _( "Export a VRML board representation" ),
+ KiBitmap( three_d_xpm ) );
+
+ AddMenuItem( submenuexport, ID_GEN_EXPORT_FILE_IDF3,
+ _( "I&DFv3" ), _( "IDFv3 board and component export" ),
+ KiBitmap( export_idf_xpm ) );
+
+ AddMenuItem( submenuexport, ID_PCB_GEN_CMP_FILE,
+ _( "&Component (.cmp) File" ),
+ _( "Export component file (*.cmp) for Eeschema footprint field back-annotation" ),
+ KiBitmap( create_cmp_file_xpm ) );
+
+ AddMenuItem( filesMenu, submenuexport,
+ ID_GEN_EXPORT_FILE, _( "E&xport" ),
+ _( "Export board" ), KiBitmap( export_xpm ) );
+
+ filesMenu->AppendSeparator();
+
+ AddMenuItem( filesMenu, ID_SHEET_SET,
+ _( "Page s&ettings" ),
+ _( "Page settings for paper size and texts" ),
+ KiBitmap( sheetset_xpm ) );
+
+ AddMenuItem( filesMenu, wxID_PRINT,
+ _( "&Print" ), _( "Print board" ),
+ KiBitmap( print_button_xpm ) );
+
+ AddMenuItem( filesMenu, ID_GEN_PLOT_SVG,
+ _( "Export SV&G" ),
+ _( "Export a board file in Scalable Vector Graphics format" ),
+ KiBitmap( plot_svg_xpm ) );
+
+ AddMenuItem( filesMenu, ID_GEN_PLOT,
+ _( "P&lot" ),
+ _( "Plot board in HPGL, PostScript or Gerber RS-274X format)" ),
+ KiBitmap( plot_xpm ) );
+
+ filesMenu->AppendSeparator();
+
+ //----- archive submenu -----------------------------------------------------
+ wxMenu* submenuarchive = new wxMenu();
+
+ AddMenuItem( submenuarchive, ID_MENU_ARCHIVE_MODULES_IN_LIBRARY,
+ _( "&Archive Footprints in a Project Library" ),
+ _( "Archive footprints in an existing library in footprint Lib table"
+ "(do not remove other footprints in this lib)" ),
+ KiBitmap( library_update_xpm ) );
+
+ AddMenuItem( submenuarchive, ID_MENU_CREATE_LIBRARY_AND_ARCHIVE_MODULES,
+ _( "&Create Library and Archive Footprints" ),
+ _( "Archive all footprints in a new library\n"
+ "(if this library already exists, it will be deleted)" ),
+ KiBitmap( library_xpm ) );
+
+ AddMenuItem( filesMenu, submenuarchive,
+ ID_MENU_ARCHIVE_MODULES,
+ _( "Arc&hive Footprints" ),
+ _( "Archive or add footprints in a library file" ),
+ KiBitmap( library_xpm ) );
+
+ filesMenu->AppendSeparator();
+ AddMenuItem( filesMenu, wxID_EXIT, _( "&Close" ), _( "Close Pcbnew" ), KiBitmap( exit_xpm ) );
+
+ //----- Edit menu -----------------------------------------------------------
+ wxMenu* editMenu = new wxMenu;
+
+ text = AddHotkeyName( _( "&Undo" ), g_Pcbnew_Editor_Hokeys_Descr, HK_UNDO );
+ AddMenuItem( editMenu, wxID_UNDO, text, HELP_UNDO, KiBitmap( undo_xpm ) );
+
+ text = AddHotkeyName( _( "&Redo" ), g_Pcbnew_Editor_Hokeys_Descr, HK_REDO );
+ AddMenuItem( editMenu, wxID_REDO, text, HELP_REDO, KiBitmap( redo_xpm ) );
+
+ AddMenuItem( editMenu, ID_PCB_DELETE_ITEM_BUTT,
+ _( "&Delete" ), _( "Delete items" ),
+ KiBitmap( delete_xpm ) );
+
+ editMenu->AppendSeparator();
+
+ text = AddHotkeyName( _( "&Find" ), g_Pcbnew_Editor_Hokeys_Descr, HK_FIND_ITEM );
+ AddMenuItem( editMenu, ID_FIND_ITEMS, text, HELP_FIND , KiBitmap( find_xpm ) );
+
+ editMenu->AppendSeparator();
+
+ AddMenuItem( editMenu, ID_PCB_GLOBAL_DELETE,
+ _( "&Global Deletions" ),
+ _( "Delete tracks, footprints, texts... on board" ),
+ KiBitmap( general_deletions_xpm ) );
+
+ AddMenuItem( editMenu, ID_MENU_PCB_CLEAN,
+ _( "&Cleanup Tracks and Vias" ),
+ _( "Clean stubs, vias, delete break points, or unconnected tracks to pads and vias" ),
+ KiBitmap( delete_xpm ) );
+
+ AddMenuItem( editMenu, ID_MENU_PCB_SWAP_LAYERS,
+ _( "&Swap Layers" ),
+ _( "Swap tracks on copper layers or drawings on other layers" ),
+ KiBitmap( swap_layer_xpm ) );
+
+ AddMenuItem( editMenu, ID_MENU_PCB_RESET_TEXTMODULE_FIELDS_SIZES,
+ _( "Set Footp&rint Field Sizes" ),
+ _( "Set text size and width of footprint fields." ),
+ KiBitmap( reset_text_xpm ) );
+
+ //----- View menu -----------------------------------------------------------
+ wxMenu* viewMenu = new wxMenu;
+
+ /* Important Note for ZOOM IN and ZOOM OUT commands from menubar:
+ * we cannot add hotkey info here, because the hotkey HK_ZOOM_IN and HK_ZOOM_OUT
+ * events(default = WXK_F1 and WXK_F2) are *NOT* equivalent to this menu command:
+ * zoom in and out from hotkeys are equivalent to the pop up menu zoom
+ * From here, zooming is made around the screen center
+ * From hotkeys, zooming is made around the mouse cursor position
+ * (obviously not possible from the toolbar or menubar command)
+ *
+ * in other words HK_ZOOM_IN and HK_ZOOM_OUT *are NOT* accelerators
+ * for Zoom in and Zoom out sub menus
+ */
+ text = AddHotkeyName( _( "Zoom &In" ), g_Pcbnew_Editor_Hokeys_Descr,
+ HK_ZOOM_IN, IS_ACCELERATOR );
+ AddMenuItem( viewMenu, ID_ZOOM_IN, text, HELP_ZOOM_IN, KiBitmap( zoom_in_xpm ) );
+
+ text = AddHotkeyName( _( "Zoom &Out" ), g_Pcbnew_Editor_Hokeys_Descr,
+ HK_ZOOM_OUT, IS_ACCELERATOR );
+ AddMenuItem( viewMenu, ID_ZOOM_OUT, text, HELP_ZOOM_OUT, KiBitmap( zoom_out_xpm ) );
+
+ text = AddHotkeyName( _( "&Fit on Screen" ), g_Pcbnew_Editor_Hokeys_Descr,
+ HK_ZOOM_AUTO );
+ AddMenuItem( viewMenu, ID_ZOOM_PAGE, text, HELP_ZOOM_FIT,
+ KiBitmap( zoom_fit_in_page_xpm ) );
+
+ text = AddHotkeyName( _( "&Redraw" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ZOOM_REDRAW );
+ AddMenuItem( viewMenu, ID_ZOOM_REDRAW, text,
+ HELP_ZOOM_REDRAW, KiBitmap( zoom_redraw_xpm ) );
+
+ viewMenu->AppendSeparator();
+
+ text = AddHotkeyName( _( "&3D Viewer" ), g_Pcbnew_Editor_Hokeys_Descr, HK_3D_VIEWER );
+
+ AddMenuItem( viewMenu, ID_MENU_PCB_SHOW_3D_FRAME, text, _( "Show board in 3D viewer" ),
+ KiBitmap( three_d_xpm ) );
+
+ AddMenuItem( viewMenu, ID_MENU_LIST_NETS,
+ _( "&List Nets" ), _( "View a list of nets with names and id's" ),
+ KiBitmap( list_nets_xpm ) );
+
+ viewMenu->AppendSeparator();
+
+ text = AddHotkeyName( _( "&Switch Canvas to Default" ), g_Pcbnew_Editor_Hokeys_Descr,
+ HK_CANVAS_DEFAULT );
+
+ AddMenuItem( viewMenu, ID_MENU_CANVAS_DEFAULT,
+ text, _( "Switch the canvas implementation to default" ),
+ KiBitmap( tools_xpm ) );
+
+ text = AddHotkeyName( _( "Switch Canvas to Open&GL" ), g_Pcbnew_Editor_Hokeys_Descr,
+ HK_CANVAS_OPENGL );
+
+ AddMenuItem( viewMenu, ID_MENU_CANVAS_OPENGL,
+ text, _( "Switch the canvas implementation to OpenGL" ),
+ KiBitmap( tools_xpm ) );
+
+ text = AddHotkeyName( _( "Switch Canvas to &Cairo" ), g_Pcbnew_Editor_Hokeys_Descr,
+ HK_CANVAS_CAIRO );
+
+ AddMenuItem( viewMenu, ID_MENU_CANVAS_CAIRO,
+ text, _( "Switch the canvas implementation to Cairo" ),
+ KiBitmap( tools_xpm ) );
+
+ //----- Place Menu ----------------------------------------------------------
+ wxMenu* placeMenu = new wxMenu;
+
+ text = AddHotkeyName( _( "&Footprint" ), g_Pcbnew_Editor_Hokeys_Descr,
+ HK_ADD_MODULE );
+ AddMenuItem( placeMenu, ID_PCB_MODULE_BUTT, text,
+ _( "Add footprints" ), KiBitmap( module_xpm ) );
+
+ text = AddHotkeyName( _( "&Track" ), g_Pcbnew_Editor_Hokeys_Descr,
+ HK_ADD_NEW_TRACK );
+ AddMenuItem( placeMenu, ID_TRACK_BUTT, text,
+ _( "Add tracks and vias" ), KiBitmap( add_tracks_xpm ) );
+
+ AddMenuItem( placeMenu, ID_PCB_ZONES_BUTT,
+ _( "&Zone" ), _( "Add filled zones" ), KiBitmap( add_zone_xpm ) );
+
+ AddMenuItem( placeMenu, ID_PCB_KEEPOUT_AREA_BUTT,
+ _( "&Keepout Area" ), _( "Add keepout areas" ), KiBitmap( add_keepout_area_xpm ) );
+
+ AddMenuItem( placeMenu, ID_PCB_ADD_TEXT_BUTT,
+ _( "Te&xt" ), _( "Add text on copper layers or graphic text" ),
+ KiBitmap( add_text_xpm ) );
+
+ AddMenuItem( placeMenu, ID_PCB_ARC_BUTT,
+ _( "&Arc" ), _( "Add graphic arc" ),KiBitmap( add_arc_xpm ) );
+
+ AddMenuItem( placeMenu, ID_PCB_CIRCLE_BUTT,
+ _( "&Circle" ), _( "Add graphic circle" ),
+ KiBitmap( add_circle_xpm ) );
+
+ AddMenuItem( placeMenu, ID_PCB_ADD_LINE_BUTT,
+ _( "&Line or Polygon" ),
+ _( "Add graphic line or polygon" ),
+ KiBitmap( add_dashed_line_xpm ) );
+
+ placeMenu->AppendSeparator();
+
+ AddMenuItem( placeMenu, ID_PCB_DIMENSION_BUTT,
+ _( "&Dimension" ), _( "Add dimension" ),
+ KiBitmap( add_dimension_xpm ) );
+
+ AddMenuItem( placeMenu, ID_PCB_MIRE_BUTT,
+ _( "La&yer alignment target" ), _( "Add layer alignment target" ),
+ KiBitmap( add_mires_xpm ) );
+
+ placeMenu->AppendSeparator();
+
+ AddMenuItem( placeMenu, ID_PCB_PLACE_OFFSET_COORD_BUTT,
+ _( "Drill and &Place Offset" ),
+ _( "Place the origin point for drill and place files" ),
+ KiBitmap( pcb_offset_xpm ) );
+
+ AddMenuItem( placeMenu, ID_PCB_PLACE_GRID_COORD_BUTT,
+ _( "&Grid Origin" ),
+ _( "Set the origin point for the grid" ),
+ KiBitmap( grid_select_axis_xpm ) );
+
+ wxMenu* routeMenu = new wxMenu;
+
+ AddMenuItem( routeMenu, ID_TRACK_BUTT,
+ _( "&Single Track" ),
+ _( "Interactively route a single track" ),
+ KiBitmap( add_tracks_xpm ) );
+
+ AddMenuItem( routeMenu, ID_DIFF_PAIR_BUTT,
+ _( "&Differential Pair" ),
+ _( "Interactively route a differential pair" ),
+ KiBitmap( ps_diff_pair_xpm ) );
+
+ routeMenu->AppendSeparator();
+
+ AddMenuItem( routeMenu, ID_TUNE_SINGLE_TRACK_LEN_BUTT,
+ _( "&Tune Track Length" ),
+ _( "Tune length of a single track" ),
+ KiBitmap( ps_tune_length_xpm ) );
+
+ AddMenuItem( routeMenu, ID_TUNE_DIFF_PAIR_LEN_BUTT,
+ _( "Tune Differential Pair &Length" ),
+ _( "Tune length of a differential pair" ),
+ KiBitmap( ps_diff_pair_tune_length_xpm ) );
+
+ AddMenuItem( routeMenu, ID_TUNE_DIFF_PAIR_SKEW_BUTT,
+ _( "Tune Differential Pair &Skew/Phase" ),
+ _( "Tune skew/phase of a differential pair" ),
+ KiBitmap( ps_diff_pair_tune_phase_xpm ) );
+
+/* Fixme: add icons & missing menu entries!
+ routeMenu->AppendSeparator();
+
+ AddMenuItem( routeMenu, ID_MENU_MITER_TRACES,
+ _( "Miter traces..." ),
+ _( "Miter trace corners with arcs" ),
+ KiBitmap( grid_select_axis_xpm ) );
+
+ AddMenuItem( routeMenu, ID_MENU_ADD_TEARDROPS,
+ _( "Teardrops..." ),
+ _( "Add teardrops to pads/vias" ),
+ KiBitmap( grid_select_axis_xpm ) );
+*/
+
+ //----- Preferences and configuration menu------------------------------------
+ wxMenu* configmenu = new wxMenu;
+
+ AddMenuItem( configmenu, ID_PCB_LIB_WIZARD,
+ _( "&Footprint Libraries Wizard" ), _( "Add footprint libraries with wizard" ),
+ KiBitmap( wizard_add_fplib_small_xpm ) );
+
+ AddMenuItem( configmenu, ID_PCB_LIB_TABLE_EDIT,
+ _( "Footprint Li&braries Manager" ), _( "Configure footprint libraries" ),
+ KiBitmap( library_table_xpm ) );
+
+ // Path configuration edit dialog.
+ AddMenuItem( configmenu,
+ ID_PREFERENCES_CONFIGURE_PATHS,
+ _( "Configure Pa&ths" ),
+ _( "Edit path configuration environment variables" ),
+ KiBitmap( editor_xpm ) );
+
+#ifdef BUILD_GITHUB_PLUGIN
+ AddMenuItem( configmenu, ID_PCB_3DSHAPELIB_WIZARD,
+ _( "&3D Shapes Libraries Downloader" ),
+ _( "Download from Github the 3D shape libraries with wizard" ),
+ KiBitmap( wizard_add_fplib_small_xpm ) );
+#endif
+
+ // Colors and Visibility are also handled by the layers manager toolbar
+ AddMenuItem( configmenu, ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
+ m_show_layer_manager_tools ?
+ _( "Hide La&yers Manager" ) : _("Show La&yers Manager" ),
+ HELP_SHOW_HIDE_LAYERMANAGER,
+ KiBitmap( layers_manager_xpm ) );
+
+ AddMenuItem( configmenu, ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR,
+ m_show_microwave_tools ?
+ _( "Hide Microwa&ve Toolbar" ): _( "Show Microwave Toolbar" ),
+ HELP_SHOW_HIDE_MICROWAVE_TOOLS,
+ KiBitmap( mw_toolbar_xpm ) );
+
+ // General
+#ifdef __WXMAC__
+ configmenu->Append( wxID_PREFERENCES );
+#else
+ AddMenuItem( configmenu, wxID_PREFERENCES,
+ _( "&General" ), _( "Select general options for Pcbnew" ),
+ KiBitmap( preference_xpm ) );
+#endif
+
+ AddMenuItem( configmenu, ID_PCB_DISPLAY_OPTIONS_SETUP,
+ _( "&Display" ),
+ _( "Select how items (pads, tracks texts ... ) are displayed" ),
+ KiBitmap( display_options_xpm ) );
+
+ AddMenuItem( configmenu, ID_MENU_INTERACTIVE_ROUTER_SETTINGS,
+ _( "&Interactive Routing" ),
+ _( "Configure the interactive router." ),
+ KiBitmap( add_tracks_xpm ) ); // fixme: icon
+
+ //--- dimensions submenu ------------------------------------------------------
+ wxMenu* dimensionsMenu = new wxMenu;
+
+ AddMenuItem( dimensionsMenu, ID_PCB_USER_GRID_SETUP,
+ _( "G&rid" ),_( "Adjust user grid dimensions" ),
+ KiBitmap( grid_xpm ) );
+
+ AddMenuItem( dimensionsMenu, ID_PCB_DRAWINGS_WIDTHS_SETUP,
+ _( "Te&xts and Drawings" ),
+ _( "Adjust dimensions for texts and drawings" ),
+ KiBitmap( options_text_xpm ) );
+
+ AddMenuItem( dimensionsMenu, ID_PCB_PAD_SETUP,
+ _( "&Pads" ), _( "Adjust default pad characteristics" ),
+ KiBitmap( pad_dimensions_xpm ) );
+
+ AddMenuItem( dimensionsMenu, ID_PCB_MASK_CLEARANCE,
+ _( "Pads &Mask Clearance" ),
+ _( "Adjust the global clearance between pads and the solder resist mask" ),
+ KiBitmap( pads_mask_layers_xpm ) );
+
+ AddMenuItem( dimensionsMenu, ID_MENU_DIFF_PAIR_DIMENSIONS,
+ _( "&Differential Pairs" ),
+ _( "Define the global gap/width for differential pairs." ),
+ KiBitmap( ps_diff_pair_xpm ) );
+
+ dimensionsMenu->AppendSeparator();
+ AddMenuItem( dimensionsMenu, ID_CONFIG_SAVE,
+ _( "&Save" ), _( "Save dimension preferences" ),
+ KiBitmap( save_xpm ) );
+
+ // Language submenu
+ Pgm().AddMenuLanguageList( configmenu );
+
+ // Hotkey submenu
+ AddHotkeyConfigMenu( configmenu );
+
+ //--- Macros submenu --------------------------------------------------------
+ wxMenu* macrosMenu = new wxMenu;
+
+ AddMenuItem( macrosMenu, ID_PREFRENCES_MACROS_SAVE,
+ _( "&Save macros" ),
+ _( "Save macros to file" ),
+ KiBitmap( save_setup_xpm ) );
+
+ AddMenuItem( macrosMenu, ID_PREFRENCES_MACROS_READ,
+ _( "&Read macros" ),
+ _( "Read macros from file" ),
+ KiBitmap( read_setup_xpm ) );
+
+ AddMenuItem( configmenu, macrosMenu,
+ -1, _( "Ma&cros" ),
+ _( "Macros save/read operations" ),
+ KiBitmap( macros_record_xpm ) );
+
+ configmenu->AppendSeparator();
+
+ AddMenuItem( configmenu, ID_CONFIG_SAVE,
+ _( "&Save Preferences" ),
+ _( "Save application preferences" ),
+ KiBitmap( save_setup_xpm ) );
+
+ AddMenuItem( configmenu, ID_CONFIG_READ,
+ _( "Load Prefe&rences" ),
+ _( "Load application preferences" ),
+ KiBitmap( read_setup_xpm ) );
+
+ //----- Tools menu ----------------------------------------------------------
+ wxMenu* toolsMenu = new wxMenu;
+
+ AddMenuItem( toolsMenu, ID_GET_NETLIST,
+ _( "&Netlist" ),
+ _( "Read the netlist and update board connectivity" ),
+ KiBitmap( netlist_xpm ) );
+
+ AddMenuItem( toolsMenu, ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR,
+ _( "&Layer Pair" ), _( "Change the active layer pair" ),
+ KiBitmap( select_layer_pair_xpm ) );
+
+ AddMenuItem( toolsMenu, ID_DRC_CONTROL,
+ _( "&DRC" ),
+ _( "Perform design rules check" ), KiBitmap( erc_xpm ) );
+
+ AddMenuItem( toolsMenu, ID_TOOLBARH_PCB_FREEROUTE_ACCESS,
+ _( "&FreeRoute" ),
+ _( "Fast access to the web based FreeROUTE advanced router" ),
+ KiBitmap( web_support_xpm ) );
+
+#if defined(KICAD_SCRIPTING_WXPYTHON)
+ AddMenuItem( toolsMenu, ID_TOOLBARH_PCB_SCRIPTING_CONSOLE,
+ _( "&Scripting Console" ),
+ _( "Show/Hide the Python scripting console" ),
+ KiBitmap( py_script_xpm ) );
+#endif
+
+ wxMenu* designRulesMenu = new wxMenu;
+
+ AddMenuItem( designRulesMenu, ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG,
+ _( "&Design Rules" ),
+ _( "Open the design rules editor" ), KiBitmap( hammer_xpm ) );
+
+ AddMenuItem( designRulesMenu, ID_PCB_LAYERS_SETUP,
+ _( "&Layers Setup" ), _( "Enable and set layer properties" ),
+ KiBitmap( copper_layers_setup_xpm ) );
+
+ wxMenu* helpMenu = new wxMenu;
+
+ AddHelpVersionInfoMenuEntry( helpMenu );
+
+ AddMenuItem( helpMenu, wxID_HELP,
+ _( "Pcbnew &Manual" ),
+ _( "Open the Pcbnew Manual" ),
+ KiBitmap( online_help_xpm ) );
+
+ AddMenuItem( helpMenu, wxID_INDEX,
+ _( "&Getting Started in KiCad" ),
+ _( "Open the \"Getting Started in KiCad\" guide for beginners" ),
+ KiBitmap( help_xpm ) );
+
+ helpMenu->AppendSeparator();
+ AddMenuItem( helpMenu, wxID_ABOUT,
+ _( "&About KiCad" ),
+ _( "Display the KiCad About dialog" ),
+ KiBitmap( info_xpm ) );
+
+ // Append all menus to the menuBar
+ menuBar->Append( filesMenu, _( "&File" ) );
+ menuBar->Append( editMenu, _( "&Edit" ) );
+ menuBar->Append( viewMenu, _( "&View" ) );
+ menuBar->Append( placeMenu, _( "&Place" ) );
+ menuBar->Append( routeMenu, _( "Ro&ute" ) );
+ menuBar->Append( configmenu, _( "P&references" ) );
+ menuBar->Append( dimensionsMenu, _( "D&imensions" ) );
+ menuBar->Append( toolsMenu, _( "&Tools" ) );
+ menuBar->Append( designRulesMenu, _( "&Design Rules" ) );
+ menuBar->Append( helpMenu, _( "&Help" ) );
+
+ menuBar->Thaw();
+
+ // Associate the menu bar with the frame, if no previous menubar
+ if( GetMenuBar() == NULL )
+ SetMenuBar( menuBar );
+ else
+ menuBar->Refresh();
+}
diff --git a/pcbnew/minimun_spanning_tree.cpp b/pcbnew/minimun_spanning_tree.cpp
new file mode 100644
index 0000000..5e608d3
--- /dev/null
+++ b/pcbnew/minimun_spanning_tree.cpp
@@ -0,0 +1,145 @@
+/**
+ * @file minimun_spanning_tree.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011 Jean-Pierre Charras
+ * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * derived from this article:
+ * http://compprog.wordpress.com/2007/11/09/minimal-spanning-trees-prims-algorithm
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <limits.h>
+
+#include <minimun_spanning_tree.h>
+#include <class_pad.h>
+
+/*
+ * The class MIN_SPAN_TREE calculates the rectilinear minimum spanning tree
+ * of a set of points (pads usually having the same net)
+ * using the Prim's algorithm.
+ */
+
+/*
+ * Prim's Algorithm
+ * Step 0
+ * Pick any vertex as a starting vertex. (Call it S).
+ * Mark it with any given flag, say 1.
+ *
+ * Step 1
+ * Find the nearest neighbour of S (call it P1).
+ * Mark both P1 and the edge SP1.
+ * cheapest unmarked edge in the graph that doesn't close a marked circuit.
+ * Mark this edge.
+ *
+ * Step 2
+ * Find the nearest unmarked neighbour to the marked subgraph
+ * (i.e., the closest vertex to any marked vertex).
+ * Mark it and the edge connecting the vertex.
+ *
+ * Step 3
+ * Repeat Step 2 until all vertices are marked.
+ * The marked subgraph is a minimum spanning tree.
+ */
+MIN_SPAN_TREE::MIN_SPAN_TREE()
+{
+ MSP_Init( 0 );
+}
+
+
+void MIN_SPAN_TREE::MSP_Init( int aNodesCount )
+{
+ m_Size = std::max( aNodesCount, 1 );
+ inTree.clear();
+ linkedTo.clear();
+ distTo.clear();
+
+ if( m_Size == 0 )
+ return;
+
+ // Reserve space in memory
+ inTree.reserve( m_Size );
+ linkedTo.reserve( m_Size );
+ distTo.reserve( m_Size );
+
+ // Initialize values:
+ for( int ii = 0; ii < m_Size; ii++ )
+ {
+ // Initialise dist with infinity:
+ distTo.push_back( INT_MAX );
+
+ // Mark all nodes as NOT beeing in the minimum spanning tree:
+ inTree.push_back( 0 );
+
+ linkedTo.push_back( 0 );
+ }
+}
+
+
+/* updateDistances(int target)
+ * should be called immediately after target is added to the tree;
+ * updates dist so that the values are correct (goes through target's
+ * neighbours making sure that the distances between them and the tree
+ * are indeed minimum)
+ */
+void MIN_SPAN_TREE::updateDistances( int target )
+{
+ for( int ii = 0; ii < m_Size; ++ii )
+ {
+ if( !inTree[ii] ) // no need to evaluate weight for already in tree items
+ {
+ int weight = GetWeight( target, ii );
+ if( (weight > 0) && (distTo[ii] > weight ) )
+ {
+ distTo[ii] = weight;
+ linkedTo[ii] = target;
+ }
+ }
+ }
+}
+
+
+void MIN_SPAN_TREE::BuildTree()
+{
+ // Add the first node to the tree
+ inTree[0] = 1;
+ updateDistances( 0 );
+
+ for( int treeSize = 1; treeSize < m_Size; ++treeSize )
+ {
+ // Find the node with the smallest distance to the tree
+ int min = -1;
+
+ for( int ii = 0; ii < m_Size; ++ii )
+ {
+ if( !inTree[ii] )
+ {
+ if( (min == -1) || (distTo[min] > distTo[ii]) )
+ min = ii;
+ }
+ }
+
+ inTree[min] = 1;
+ updateDistances( min );
+ }
+}
diff --git a/pcbnew/minimun_spanning_tree.h b/pcbnew/minimun_spanning_tree.h
new file mode 100644
index 0000000..97f4495
--- /dev/null
+++ b/pcbnew/minimun_spanning_tree.h
@@ -0,0 +1,101 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file minimun_spanning_tree.h
+ */
+
+#include <vector>
+
+/**
+ * @brief The class MIN_SPAN_TREE calculates the rectilinear minimum spanning tree
+ * of a set of points (pads usually having the same net)
+ * this class is an abstract class because you must provide the function
+ * int GetWeight( int aItem1, int aItem2 )
+ * that calculate the distance between 2 items
+ * MIN_SPAN_TREE does not know anything about the actual items to link
+ * by the tree
+ */
+class MIN_SPAN_TREE
+{
+protected:
+ int m_Size; /* The number of nodes in the graph
+ */
+private:
+ std::vector<char> inTree; /* inTree[ii] is a flag set to 1 if the node ii
+ * is already in the minimum spanning tree; 0 otherwise
+ */
+ std::vector<int> linkedTo; /* linkedTo[ii] holds the index of the node ii would have to be
+ * linked to in order to get a distance of d[ii]
+ * NOTE: linkedTo[0] is the starting point of the tree
+ * linkedTo[1] is the first linked point to use
+ * ii and linkedTo[ii] are the 2 ends of an edge in the graph
+ */
+ std::vector<int> distTo; /* distTo[ii] is the distance between node ii and the minimum spanning
+ * tree;
+ * this is initially infinity (INT_MAX);
+ * if ii is already in the tree, then d[ii] is undefined;
+ * this is just a temporary variable. It's not necessary but speeds
+ * up execution considerably (by a factor of n)
+ */
+public:
+ MIN_SPAN_TREE();
+ void MSP_Init( int aNodesCount );
+ void BuildTree();
+
+ int GetWhoTo( int aIdx )
+ {
+ return linkedTo[aIdx];
+ }
+
+
+ int GetDist( int aIdx )
+ {
+ return distTo[aIdx];
+ }
+
+ /**
+ * Function GetWeight
+ * calculates the weight between 2 items
+ * NOTE: The weight between a node and itself should be 0
+ * It is virtual pure, you must provide your GetWeight function
+ * @param aItem1 = first item
+ * @param aItem2 = other item
+ * @return the weight between items ( usually the distance )
+ */
+ virtual int GetWeight( int aItem1, int aItem2 ) = 0;
+
+private:
+
+ /**
+ * Function updateDistances
+ * should be called immediately after target is added to the tree;
+ * updates d so that the values are correct (goes through target's
+ * neighbours making sure that the distances between them and the tree
+ * are indeed minimum)
+ * @param aTarget = index of curr item
+ */
+ void updateDistances( int aTarget );
+
+};
diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp
new file mode 100644
index 0000000..8b06e6d
--- /dev/null
+++ b/pcbnew/modedit.cpp
@@ -0,0 +1,1005 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file modedit.cpp
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <kiway.h>
+#include <class_drawpanel.h>
+#include <pcb_draw_panel_gal.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <pgm_base.h>
+#include <trigo.h>
+#include <3d_viewer.h>
+#include <wxPcbStruct.h>
+#include <kicad_device_context.h>
+#include <macros.h>
+#include <invoke_pcb_dialog.h>
+#include <class_pcb_layer_widget.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+
+#include <ratsnest_data.h>
+#include <pcbnew.h>
+#include <protos.h>
+#include <pcbnew_id.h>
+#include <module_editor_frame.h>
+#include <modview_frame.h>
+#include <collectors.h>
+#include <tool/tool_manager.h>
+#include <tools/common_actions.h>
+
+#include <dialog_edit_module_for_Modedit.h>
+#include <dialog_move_exact.h>
+#include <dialog_create_array.h>
+#include <wildcards_and_files_ext.h>
+#include <menus_helpers.h>
+#include <footprint_wizard_frame.h>
+#include <pcbnew_config.h>
+
+#include <boost/bind.hpp>
+
+
+// Functions defined in block_module_editor, but used here
+// These 3 functions are used in modedit to rotate, mirror or move the
+// whole footprint so they are called with force_all = true
+void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
+void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
+void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre,
+ const wxPoint& translation, double rotation,
+ bool force_all = false );
+
+
+BOARD_ITEM* FOOTPRINT_EDIT_FRAME::ModeditLocateAndDisplay( int aHotKeyCode )
+{
+ BOARD_ITEM* item = GetCurItem();
+
+ if( GetBoard()->m_Modules == NULL )
+ return NULL;
+
+ GENERAL_COLLECTORS_GUIDE guide = GetCollectorsGuide();
+
+ // Assign to scanList the proper item types desired based on tool type
+ // or hotkey that is in play.
+
+ const KICAD_T* scanList = NULL;
+
+ if( aHotKeyCode )
+ {
+ // @todo: add switch here and add calls to PcbGeneralLocateAndDisplay(
+ // int aHotKeyCode ) when searching is needed from a hotkey handler
+ }
+ else
+ {
+ scanList = GENERAL_COLLECTOR::ModulesAndTheirItems;
+ }
+
+ m_Collector->Collect( GetBoard(), scanList, RefPos( true ), guide );
+
+ // Remove redundancies: when an item is found, we can remove the module from list
+ if( m_Collector->GetCount() > 1 )
+ {
+ for( int ii = 0; ii < m_Collector->GetCount(); ii++ )
+ {
+ item = (*m_Collector)[ii];
+
+ if( item->Type() != PCB_MODULE_T )
+ continue;
+
+ m_Collector->Remove( ii );
+ ii--;
+ }
+ }
+
+ if( m_Collector->GetCount() <= 1 )
+ {
+ item = (*m_Collector)[0];
+ SetCurItem( item );
+ }
+ else // we can't figure out which item user wants, do popup menu so user can choose
+ {
+ wxMenu itemMenu;
+
+ // Give a title to the selection menu. It also allow to close the popup menu without any action
+ wxMenuItem* item_title = new wxMenuItem( &itemMenu, wxID_NONE, _( "Selection Clarification" ) );
+
+#ifdef __WINDOWS__
+ wxFont bold_font( *wxNORMAL_FONT );
+ bold_font.SetWeight( wxFONTWEIGHT_BOLD );
+ bold_font.SetStyle( wxFONTSTYLE_ITALIC );
+ item_title->SetFont( bold_font );
+#endif
+
+ itemMenu.Append( item_title );
+ itemMenu.AppendSeparator();
+
+ int limit = std::min( MAX_ITEMS_IN_PICKER, m_Collector->GetCount() );
+
+ for( int ii = 0; ii<limit; ++ii )
+ {
+ item = (*m_Collector)[ii];
+
+ wxString text = item->GetSelectMenuText();
+ BITMAP_DEF xpm = item->GetMenuImage();
+
+ AddMenuItem( &itemMenu,
+ ID_POPUP_PCB_ITEM_SELECTION_START + ii,
+ text,
+ KiBitmap( xpm ) );
+ }
+
+ // this menu's handler is void
+ // PCB_BASE_FRAME::ProcessItemSelection()
+ // and it calls SetCurItem() which in turn calls DisplayInfo() on the
+ // item.
+ m_canvas->SetAbortRequest( true ); // changed in false if an item
+ PopupMenu( &itemMenu ); // m_AbortRequest = false if an item is selected
+
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+
+ // The function ProcessItemSelection() has set the current item, return it.
+ item = GetCurItem();
+ }
+
+ if( item )
+ {
+ SetMsgPanel( item );
+ }
+
+ return item;
+}
+
+
+void FOOTPRINT_EDIT_FRAME::LoadModuleFromBoard( wxCommandEvent& event )
+{
+ if( GetScreen()->IsModify() )
+ {
+ if( !IsOK( this,
+ _( "Current footprint changes will be lost and this operation cannot be undone. Continue?" ) ) )
+ return;
+ }
+
+ if( ! Load_Module_From_BOARD( NULL ) )
+ return;
+
+ GetScreen()->ClearUndoRedoList();
+ GetScreen()->ClrModify();
+
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->NewDisplay();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ wxPoint pos;
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ wxGetMousePosition( &pos.x, &pos.y );
+
+ pos.y += 20;
+
+ switch( id )
+ {
+ case wxID_CUT:
+ case wxID_COPY:
+ case ID_TOOLBARH_PCB_SELECT_LAYER:
+ case ID_MODEDIT_PAD_SETTINGS:
+ case ID_PCB_USER_GRID_SETUP:
+ case ID_POPUP_PCB_ROTATE_TEXTEPCB:
+ case ID_POPUP_PCB_EDIT_TEXTEPCB:
+ case ID_POPUP_PCB_ROTATE_TEXTMODULE:
+ case ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE:
+ case ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE:
+ case ID_POPUP_PCB_EDIT_TEXTMODULE:
+ case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
+ case ID_POPUP_PCB_EXPORT_PAD_SETTINGS:
+ case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS:
+ case ID_POPUP_PCB_STOP_CURRENT_DRAWING:
+ case ID_POPUP_MODEDIT_EDIT_BODY_ITEM:
+ case ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE:
+ case ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE:
+ case ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH:
+ case ID_POPUP_PCB_DELETE_EDGE:
+ case ID_POPUP_PCB_DELETE_TEXTMODULE:
+ case ID_POPUP_PCB_DELETE_PAD:
+ case ID_POPUP_DELETE_BLOCK:
+ case ID_POPUP_PLACE_BLOCK:
+ case ID_POPUP_ZOOM_BLOCK:
+ case ID_POPUP_MIRROR_X_BLOCK:
+ case ID_POPUP_ROTATE_BLOCK:
+ case ID_POPUP_COPY_BLOCK:
+ break;
+
+ case ID_POPUP_CANCEL_CURRENT_COMMAND:
+ default:
+ if( m_canvas->IsMouseCaptured() )
+ {
+ // for all other commands: stop the move in progress
+ m_canvas->CallEndMouseCapture( &dc );
+ }
+
+ if( id != ID_POPUP_CANCEL_CURRENT_COMMAND )
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+
+ break;
+ }
+
+ switch( id )
+ {
+ case ID_EXIT:
+ Close( true );
+ break;
+
+ case ID_MODEDIT_SELECT_CURRENT_LIB:
+ {
+ wxString library = SelectLibrary( GetCurrentLib() );
+
+ if( library.size() )
+ {
+ Prj().SetRString( PROJECT::PCB_LIB_NICKNAME, library );
+ updateTitle();
+ }
+ }
+ break;
+
+ case ID_OPEN_MODULE_VIEWER:
+ {
+ FOOTPRINT_VIEWER_FRAME* viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, false );
+
+ if( !viewer )
+ {
+ viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, true );
+ viewer->Show( true );
+ viewer->Zoom_Automatique( false );
+ }
+ else
+ {
+ // On Windows, Raise() does not bring the window on screen, when iconized
+ if( viewer->IsIconized() )
+ viewer->Iconize( false );
+
+ viewer->Raise();
+
+ // Raising the window does not set the focus on Linux. This should work on
+ // any platform.
+ if( wxWindow::FindFocus() != viewer )
+ viewer->SetFocus();
+ }
+ }
+ break;
+
+ case ID_MODEDIT_DELETE_PART:
+ DeleteModuleFromCurrentLibrary();
+ break;
+
+ case ID_MODEDIT_NEW_MODULE:
+ {
+ if( !Clear_Pcb( true ) )
+ break;
+
+ SetCrossHairPosition( wxPoint( 0, 0 ) );
+
+ MODULE* module = CreateNewModule( wxEmptyString );
+
+ if( module ) // i.e. if create module command not aborted
+ {
+ // Initialize data relative to nets and netclasses (for a new
+ // module the defaults are used)
+ // This is mandatory to handle and draw pads
+ GetBoard()->BuildListOfNets();
+ module->SetPosition( wxPoint( 0, 0 ) );
+
+ if( GetBoard()->m_Modules )
+ GetBoard()->m_Modules->ClearFlags();
+
+ Zoom_Automatique( false );
+ }
+
+ updateView();
+ m_canvas->Refresh();
+
+ GetScreen()->ClrModify();
+ }
+ break;
+
+ case ID_MODEDIT_NEW_MODULE_FROM_WIZARD:
+ {
+ if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() )
+ {
+ if( !IsOK( this,
+ _( "Current Footprint will be lost and this operation cannot be undone. Continue ?" ) ) )
+ break;
+ }
+
+ FOOTPRINT_WIZARD_FRAME* wizard = (FOOTPRINT_WIZARD_FRAME*) Kiway().Player(
+ FRAME_PCB_FOOTPRINT_WIZARD_MODAL, true );
+
+ if( wizard->ShowModal( NULL, this ) )
+ {
+ // Creates the new footprint from python script wizard
+ MODULE* module = wizard->GetBuiltFootprint();
+
+ if( module == NULL ) // i.e. if create module command aborted
+ break;
+
+ Clear_Pcb( false );
+
+ SetCrossHairPosition( wxPoint( 0, 0 ) );
+
+ // Add the new object to board
+ GetBoard()->Add( module, ADD_APPEND );
+
+ // Initialize data relative to nets and netclasses (for a new
+ // module the defaults are used)
+ // This is mandatory to handle and draw pads
+ GetBoard()->BuildListOfNets();
+ module->SetPosition( wxPoint( 0, 0 ) );
+ module->ClearFlags();
+
+ Zoom_Automatique( false );
+ updateView();
+ m_canvas->Refresh();
+
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->NewDisplay();
+
+ GetScreen()->ClrModify();
+ }
+
+ wizard->Destroy();
+ }
+ break;
+
+ case ID_MODEDIT_SAVE_LIBMODULE:
+ if( GetBoard()->m_Modules && GetCurrentLib().size() )
+ {
+ SaveFootprintInLibrary( GetCurrentLib(), GetBoard()->m_Modules, true, true );
+ GetScreen()->ClrModify();
+ }
+ break;
+
+ case ID_MODEDIT_INSERT_MODULE_IN_BOARD:
+ case ID_MODEDIT_UPDATE_MODULE_IN_BOARD:
+ {
+ // update module in the current board,
+ // not just add it to the board with total disregard for the netlist...
+ PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false );
+
+ if( pcbframe == NULL ) // happens when the board editor is not active (or closed)
+ {
+ wxMessageBox( _("No board currently edited" ) );
+ break;
+ }
+
+ BOARD* mainpcb = pcbframe->GetBoard();
+ MODULE* source_module = NULL;
+ MODULE* module_in_edit = GetBoard()->m_Modules;
+
+ // Search the old module (source) if exists
+ // Because this source could be deleted when editing the main board...
+ if( module_in_edit->GetLink() ) // this is not a new module ...
+ {
+ source_module = mainpcb->m_Modules;
+
+ for( ; source_module != NULL; source_module = source_module->Next() )
+ {
+ if( module_in_edit->GetLink() == source_module->GetTimeStamp() )
+ break;
+ }
+ }
+
+ if( ( source_module == NULL )
+ && ( id == ID_MODEDIT_UPDATE_MODULE_IN_BOARD ) ) // source not found
+ {
+ wxString msg;
+ msg.Printf( _( "Unable to find the footprint source on the main board" ) );
+ msg << _( "\nCannot update the footprint" );
+ DisplayError( this, msg );
+ break;
+ }
+
+ if( ( source_module != NULL )
+ && ( id == ID_MODEDIT_INSERT_MODULE_IN_BOARD ) ) // source not found
+ {
+ wxString msg;
+ msg.Printf( _( "A footprint source was found on the main board" ) );
+ msg << _( "\nCannot insert this footprint" );
+ DisplayError( this, msg );
+ break;
+ }
+
+ m_toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ // Create the "new" module
+ MODULE* newmodule = new MODULE( *module_in_edit );
+ newmodule->SetParent( mainpcb );
+ newmodule->SetLink( 0 );
+
+ // Put the footprint in the main pcb linked list.
+ mainpcb->Add( newmodule );
+
+ if( source_module ) // this is an update command
+ {
+ // In the main board,
+ // the new module replace the old module (pos, orient, ref, value
+ // and connexions are kept)
+ // and the source_module (old module) is deleted
+ PICKED_ITEMS_LIST pickList;
+
+ if( pcbframe->IsGalCanvasActive() )
+ {
+ KIGFX::VIEW* view = pcbframe->GetGalCanvas()->GetView();
+ source_module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
+ view->Remove( source_module );
+ }
+
+ pcbframe->Exchange_Module( source_module, newmodule, &pickList );
+ newmodule->SetTimeStamp( module_in_edit->GetLink() );
+
+ if( pickList.GetCount() )
+ pcbframe->SaveCopyInUndoList( pickList, UR_UNSPECIFIED );
+ }
+ else // This is an insert command
+ {
+ wxPoint cursor_pos = pcbframe->GetCrossHairPosition();
+
+ pcbframe->SetCrossHairPosition( wxPoint( 0, 0 ) );
+ pcbframe->PlaceModule( newmodule, NULL );
+ newmodule->SetPosition( wxPoint( 0, 0 ) );
+ pcbframe->SetCrossHairPosition( cursor_pos );
+ newmodule->SetTimeStamp( GetNewTimeStamp() );
+ pcbframe->SaveCopyInUndoList( newmodule, UR_NEW );
+ }
+
+ newmodule->ClearFlags();
+ GetScreen()->ClrModify();
+ pcbframe->SetCurItem( NULL );
+ mainpcb->m_Status_Pcb = 0;
+
+ if( pcbframe->IsGalCanvasActive() )
+ {
+ RN_DATA* ratsnest = pcbframe->GetBoard()->GetRatsnest();
+ ratsnest->Update( newmodule );
+ ratsnest->Recalculate();
+
+ KIGFX::VIEW* view = pcbframe->GetGalCanvas()->GetView();
+ newmodule->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
+ view->Add( newmodule );
+ pcbframe->GetGalCanvas()->ForceRefresh();
+ }
+ }
+ break;
+
+ case ID_MODEDIT_IMPORT_PART:
+ if( ! Clear_Pcb( true ) )
+ break; // //this command is aborted
+
+ SetCrossHairPosition( wxPoint( 0, 0 ) );
+ Import_Module();
+
+ if( GetBoard()->m_Modules )
+ GetBoard()->m_Modules->ClearFlags();
+
+ GetScreen()->ClrModify();
+ Zoom_Automatique( false );
+ m_canvas->Refresh();
+
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->NewDisplay();
+
+ break;
+
+ case ID_MODEDIT_EXPORT_PART:
+ if( GetBoard()->m_Modules )
+ Export_Module( GetBoard()->m_Modules );
+ break;
+
+ case ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART:
+ if( GetBoard()->m_Modules )
+ {
+ // CreateModuleLibrary() only creates a new library, does not save footprint
+ wxString libPath = CreateNewLibrary();
+ if( libPath.size() )
+ SaveCurrentModule( &libPath );
+ }
+ break;
+
+ case ID_MODEDIT_SHEET_SET:
+ break;
+
+ case ID_MODEDIT_LOAD_MODULE:
+ wxLogDebug( wxT( "Loading module from library " ) + getLibPath() );
+
+ if( ! Clear_Pcb( true ) )
+ break;
+
+ SetCrossHairPosition( wxPoint( 0, 0 ) );
+
+ LoadModuleFromLibrary( GetCurrentLib(), Prj().PcbFootprintLibs(), true );
+
+ if( GetBoard() && GetBoard()->m_Modules )
+ {
+ GetBoard()->m_Modules->ClearFlags();
+
+ // if either m_Reference or m_Value are gone, reinstall them -
+ // otherwise you cannot see what you are doing on board
+ TEXTE_MODULE* ref = &GetBoard()->m_Modules->Reference();
+ TEXTE_MODULE* val = &GetBoard()->m_Modules->Value();
+
+ if( val && ref )
+ {
+ ref->SetType( TEXTE_MODULE::TEXT_is_REFERENCE ); // just in case ...
+
+ if( ref->GetLength() == 0 )
+ ref->SetText( wxT( "Ref**" ) );
+
+ val->SetType( TEXTE_MODULE::TEXT_is_VALUE ); // just in case ...
+
+ if( val->GetLength() == 0 )
+ val->SetText( wxT( "Val**" ) );
+ }
+ }
+
+ Zoom_Automatique( false );
+
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->NewDisplay();
+
+ GetScreen()->ClrModify();
+
+ updateView();
+ m_canvas->Refresh();
+
+ break;
+
+ case ID_MODEDIT_PAD_SETTINGS:
+ InstallPadOptionsFrame( NULL );
+ break;
+
+ case ID_MODEDIT_CHECK:
+ // Currently: not implemented
+ break;
+
+ case ID_MODEDIT_EDIT_MODULE_PROPERTIES:
+ if( GetBoard()->m_Modules )
+ {
+ SetCurItem( GetBoard()->m_Modules );
+
+ DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) GetScreen()->GetCurItem() );
+
+ int ret = dialog.ShowModal();
+ GetScreen()->GetCurItem()->ClearFlags();
+ GetBoard()->m_Modules.GetFirst()->ViewUpdate();
+
+ if( ret > 0 )
+ m_canvas->Refresh();
+ }
+ break;
+
+ case ID_POPUP_CLOSE_CURRENT_TOOL:
+ break;
+
+ case ID_POPUP_CANCEL_CURRENT_COMMAND:
+ break;
+
+ case ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE:
+ m_canvas->MoveCursorToCrossHair();
+ Rotate_Module( NULL, (MODULE*) GetScreen()->GetCurItem(), 900, true );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE:
+ m_canvas->MoveCursorToCrossHair();
+ Rotate_Module( NULL, (MODULE*) GetScreen()->GetCurItem(), -900, true );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_PCB_EDIT_MODULE_PRMS:
+ {
+ DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) GetScreen()->GetCurItem() );
+ dialog.ShowModal();
+ GetScreen()->GetCurItem()->ClearFlags();
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->Refresh();
+ }
+ break;
+
+ case ID_POPUP_PCB_MOVE_PAD_REQUEST:
+ m_canvas->MoveCursorToCrossHair();
+ StartMovePad( (D_PAD*) GetScreen()->GetCurItem(), &dc, false );
+ break;
+
+ case ID_POPUP_PCB_EDIT_PAD:
+ InstallPadOptionsFrame( (D_PAD*) GetScreen()->GetCurItem() );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_DELETE_PAD:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ DeletePad( (D_PAD*) GetScreen()->GetCurItem(), false );
+ SetCurItem( NULL );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_DUPLICATE_ITEM:
+ duplicateItems( false );
+ break;
+
+ case ID_POPUP_PCB_DUPLICATE_ITEM_AND_INCREMENT:
+ duplicateItems( true );
+ break;
+
+ case ID_POPUP_PCB_MOVE_EXACT:
+ moveExact();
+ break;
+
+ case ID_POPUP_PCB_CREATE_ARRAY:
+ createArray();
+ break;
+
+ case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ m_canvas->MoveCursorToCrossHair();
+ Import_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem(), true );
+ break;
+
+ case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ // Calls the global change dialog:
+ DlgGlobalChange_PadSettings( (D_PAD*) GetScreen()->GetCurItem() );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_EXPORT_PAD_SETTINGS:
+ m_canvas->MoveCursorToCrossHair();
+ Export_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem() );
+ break;
+
+ case ID_POPUP_PCB_EDIT_TEXTMODULE:
+ InstallTextModOptionsFrame( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST:
+ m_canvas->MoveCursorToCrossHair();
+ StartMoveTexteModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
+ break;
+
+ case ID_POPUP_PCB_ROTATE_TEXTMODULE:
+ RotateTextModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_DELETE_TEXTMODULE:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ DeleteTextModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ) );
+ SetCurItem( NULL );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_MOVE_EDGE:
+ Start_Move_EdgeMod( static_cast<EDGE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_STOP_CURRENT_DRAWING:
+ m_canvas->MoveCursorToCrossHair();
+
+ if( GetScreen()->GetCurItem()->IsNew() )
+ {
+ End_Edge_Module( (EDGE_MODULE*) GetScreen()->GetCurItem() );
+ SetCurItem( NULL );
+ }
+ break;
+
+ case ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH:
+ {
+ EDGE_MODULE* edge = NULL;
+
+ if( GetScreen()->GetCurItem()
+ && ( GetScreen()->GetCurItem()->Type() == PCB_MODULE_EDGE_T ) )
+ {
+ edge = (EDGE_MODULE*) GetScreen()->GetCurItem();
+ }
+
+ Enter_Edge_Width( edge );
+ m_canvas->MoveCursorToCrossHair();
+
+ if( edge )
+ m_canvas->Refresh();
+ }
+ break;
+
+ case ID_POPUP_MODEDIT_EDIT_BODY_ITEM :
+ m_canvas->MoveCursorToCrossHair();
+ InstallFootprintBodyItemPropertiesDlg( (EDGE_MODULE*) GetScreen()->GetCurItem() );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE:
+ m_canvas->MoveCursorToCrossHair();
+ Edit_Edge_Width( NULL );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE:
+ m_canvas->MoveCursorToCrossHair();
+ Edit_Edge_Layer( NULL );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_PCB_DELETE_EDGE:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ m_canvas->MoveCursorToCrossHair();
+ RemoveStruct( GetScreen()->GetCurItem() );
+ SetCurItem( NULL );
+ break;
+
+ case ID_MODEDIT_MODULE_ROTATE:
+ case ID_MODEDIT_MODULE_MIRROR:
+ case ID_MODEDIT_MODULE_MOVE_EXACT:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ Transform( (MODULE*) GetScreen()->GetCurItem(), id );
+ m_canvas->Refresh();
+ break;
+
+ case ID_PCB_DRAWINGS_WIDTHS_SETUP:
+ InstallOptionsFrame( pos );
+ break;
+
+ case ID_PCB_PAD_SETUP:
+ {
+ BOARD_ITEM* item = GetCurItem();
+
+ if( item )
+ {
+ if( item->Type() != PCB_PAD_T )
+ item = NULL;
+ }
+
+ InstallPadOptionsFrame( (D_PAD*) item );
+ }
+ break;
+
+ case ID_PCB_USER_GRID_SETUP:
+ InvokeDialogGrid();
+ break;
+
+ case ID_POPUP_PLACE_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE );
+ m_canvas->SetAutoPanRequest( false );
+ HandleBlockPlace( &dc );
+ break;
+
+ case ID_POPUP_COPY_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_COPY );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ m_canvas->SetAutoPanRequest( false );
+ HandleBlockPlace( &dc );
+ break;
+
+ case ID_POPUP_ZOOM_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_ZOOM );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_DELETE_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_DELETE );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_ROTATE_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_ROTATE );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_MIRROR_X_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_MIRROR_X );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_MOVE_BLOCK_EXACT:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE_EXACT );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_GEN_IMPORT_DXF_FILE:
+ if( GetBoard()->m_Modules )
+ {
+ InvokeDXFDialogModuleImport( this, GetBoard()->m_Modules );
+ m_canvas->Refresh();
+ }
+ break;
+
+ default:
+ DisplayError( this,
+ wxT( "FOOTPRINT_EDIT_FRAME::Process_Special_Functions error" ) );
+ break;
+ }
+}
+
+
+void FOOTPRINT_EDIT_FRAME::moveExact()
+{
+ wxPoint translation;
+ double rotation = 0;
+
+ DIALOG_MOVE_EXACT dialog( this, translation, rotation );
+ int ret = dialog.ShowModal();
+
+ if( ret == wxID_OK )
+ {
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+
+ BOARD_ITEM* item = GetScreen()->GetCurItem();
+
+ item->Move( translation );
+ item->Rotate( item->GetPosition(), rotation );
+ m_canvas->Refresh();
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::duplicateItems( bool aIncrement )
+{
+ BOARD_ITEM* item = GetScreen()->GetCurItem();
+
+ PCB_BASE_EDIT_FRAME::duplicateItem( item, aIncrement );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::Transform( MODULE* module, int transform )
+{
+ switch( transform )
+ {
+ case ID_MODEDIT_MODULE_ROTATE:
+ RotateMarkedItems( module, wxPoint(0,0), true );
+ break;
+
+ case ID_MODEDIT_MODULE_MIRROR:
+ MirrorMarkedItems( module, wxPoint(0,0), true );
+ break;
+
+ case ID_MODEDIT_MODULE_MOVE_EXACT:
+ {
+ wxPoint translation;
+ double rotation = 0;
+
+ DIALOG_MOVE_EXACT dialog( this, translation, rotation );
+ int ret = dialog.ShowModal();
+
+ if( ret == wxID_OK )
+ {
+ MoveMarkedItemsExactly( module, wxPoint(0, 0),
+ translation, rotation, true );
+ }
+
+ break;
+ }
+
+ default:
+ DisplayInfoMessage( this, wxT( "Not available" ) );
+ break;
+ }
+
+ module->CalculateBoundingBox();
+ OnModify();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnVerticalToolbar( wxCommandEvent& aEvent )
+{
+ int id = aEvent.GetId();
+
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+
+ switch( id )
+ {
+ case ID_NO_TOOL_SELECTED:
+ break;
+
+ case ID_MODEDIT_LINE_TOOL:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add line" ) );
+ break;
+
+ case ID_MODEDIT_ARC_TOOL:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add arc" ) );
+ break;
+
+ case ID_MODEDIT_CIRCLE_TOOL:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add circle" ) );
+ break;
+
+ case ID_MODEDIT_TEXT_TOOL:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) );
+ break;
+
+ case ID_MODEDIT_ANCHOR_TOOL:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Place anchor" ) );
+ break;
+
+ case ID_MODEDIT_PLACE_GRID_COORD:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Set grid origin" ) );
+ break;
+
+ case ID_MODEDIT_PAD_TOOL:
+ if( GetBoard()->m_Modules )
+ {
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add pad" ) );
+ }
+ else
+ {
+ SetToolID( id, wxCURSOR_ARROW, _( "Pad settings" ) );
+ InstallPadOptionsFrame( NULL );
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ }
+ break;
+
+ case ID_MODEDIT_DELETE_TOOL:
+ SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
+ break;
+
+ default:
+ wxFAIL_MSG( wxT( "Unknown command id." ) );
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ }
+}
+
+
+EDA_COLOR_T FOOTPRINT_EDIT_FRAME::GetGridColor() const
+{
+ return g_ColorsSettings.GetItemColor( GRID_VISIBLE );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::SetActiveLayer( LAYER_ID aLayer )
+{
+ PCB_BASE_FRAME::SetActiveLayer( aLayer );
+
+ m_Layers->SelectLayer( GetActiveLayer() );
+ m_Layers->OnLayerSelected();
+
+ if( IsGalCanvasActive() )
+ {
+ GetGalCanvas()->SetHighContrastLayer( aLayer );
+ GetGalCanvas()->Refresh();
+ }
+}
+
diff --git a/pcbnew/modedit_onclick.cpp b/pcbnew/modedit_onclick.cpp
new file mode 100644
index 0000000..8c2af77
--- /dev/null
+++ b/pcbnew/modedit_onclick.cpp
@@ -0,0 +1,553 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file modedit_onclick.cpp
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <3d_viewer.h>
+#include <wxPcbStruct.h>
+#include <gr_basic.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <hotkeys.h>
+#include <module_editor_frame.h>
+#include <dialog_edit_module_for_Modedit.h>
+#include <menus_helpers.h>
+
+
+void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
+{
+ BOARD_ITEM* item = GetCurItem();
+
+ m_canvas->CrossHairOff( DC );
+
+ if( GetToolId() == ID_NO_TOOL_SELECTED )
+ {
+ if( item && item->GetFlags() ) // Move item command in progress
+ {
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ PlaceTexteModule( static_cast<TEXTE_MODULE*>( item ), DC );
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ Place_EdgeMod( static_cast<EDGE_MODULE*>( item ) );
+ break;
+
+ case PCB_PAD_T:
+ PlacePad( static_cast<D_PAD*>( item ), DC );
+ break;
+
+ default:
+ {
+ wxString msg;
+ msg.Printf( wxT( "WinEDA_ModEditFrame::OnLeftClick err:Struct %d, m_Flag %X" ),
+ item->Type(), item->GetFlags() );
+ DisplayError( this, msg );
+ item->ClearFlags();
+ break;
+ }
+ }
+ }
+
+ else
+ {
+ if( !wxGetKeyState( WXK_SHIFT ) && !wxGetKeyState( WXK_ALT )
+ && !wxGetKeyState( WXK_CONTROL ) )
+ item = ModeditLocateAndDisplay();
+
+ SetCurItem( item );
+ }
+ }
+
+ item = GetCurItem();
+ bool no_item_edited = item == NULL || item->GetFlags() == 0;
+
+ switch( GetToolId() )
+ {
+ case ID_NO_TOOL_SELECTED:
+ break;
+
+ case ID_MODEDIT_CIRCLE_TOOL:
+ case ID_MODEDIT_ARC_TOOL:
+ case ID_MODEDIT_LINE_TOOL:
+ if( no_item_edited )
+ {
+ STROKE_T shape = S_SEGMENT;
+
+ if( GetToolId() == ID_MODEDIT_CIRCLE_TOOL )
+ shape = S_CIRCLE;
+
+ if( GetToolId() == ID_MODEDIT_ARC_TOOL )
+ shape = S_ARC;
+
+ SetCurItem( Begin_Edge_Module( (EDGE_MODULE*) NULL, DC, shape ) );
+ }
+ else if( item->IsNew() )
+ {
+ if( ( (EDGE_MODULE*) item )->GetShape() == S_CIRCLE )
+ {
+ End_Edge_Module( (EDGE_MODULE*) item );
+ SetCurItem( NULL );
+ m_canvas->Refresh();
+ }
+ else if( ( (EDGE_MODULE*) item )->GetShape() == S_ARC )
+ {
+ End_Edge_Module( (EDGE_MODULE*) item );
+ SetCurItem( NULL );
+ m_canvas->Refresh();
+ }
+ else if( ( (EDGE_MODULE*) item )->GetShape() == S_SEGMENT )
+ {
+ SetCurItem( Begin_Edge_Module( (EDGE_MODULE*) item, DC, S_SEGMENT ) );
+ }
+ else
+ {
+ wxMessageBox( wxT( "ProcessCommand error: unknown shape" ) );
+ }
+ }
+ break;
+
+ case ID_MODEDIT_DELETE_TOOL:
+ if( ! no_item_edited ) // Item in edit, cannot delete it
+ break;
+
+ item = ModeditLocateAndDisplay();
+
+ if( item && item->Type() != PCB_MODULE_T ) // Cannot delete the module itself
+ {
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ RemoveStruct( item );
+ SetCurItem( NULL );
+ }
+
+ break;
+
+ case ID_MODEDIT_ANCHOR_TOOL:
+ {
+ MODULE* module = GetBoard()->m_Modules;
+
+ if( module == NULL // No module loaded
+ || (module->GetFlags() != 0) )
+ break;
+
+ SaveCopyInUndoList( module, UR_MODEDIT );
+
+ // set the new relative internal local coordinates of footprint items
+ wxPoint moveVector = module->GetPosition() - GetCrossHairPosition();
+ module->MoveAnchorPosition( moveVector );
+
+ // Usually, we do not need to change twice the anchor position,
+ // so deselect the active tool
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ SetCurItem( NULL );
+ m_canvas->Refresh();
+ }
+ break;
+
+ case ID_MODEDIT_PLACE_GRID_COORD:
+ m_canvas->DrawGridAxis( DC, GR_XOR, GetBoard()->GetGridOrigin() );
+ SetGridOrigin( GetCrossHairPosition() );
+ m_canvas->DrawGridAxis( DC, GR_COPY, GetBoard()->GetGridOrigin() );
+ GetScreen()->SetModify();
+ break;
+
+ case ID_MODEDIT_TEXT_TOOL:
+ if( GetBoard()->m_Modules == NULL )
+ break;
+
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ CreateTextModule( GetBoard()->m_Modules, DC );
+ break;
+
+ case ID_MODEDIT_PAD_TOOL:
+ if( GetBoard()->m_Modules )
+ {
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ AddPad( GetBoard()->m_Modules, true );
+ }
+
+ break;
+
+ default:
+ DisplayError( this, wxT( "FOOTPRINT_EDIT_FRAME::ProcessCommand error" ) );
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ }
+
+ m_canvas->CrossHairOn( DC );
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu )
+{
+ BOARD_ITEM* item = GetCurItem();
+ wxString msg;
+ bool blockActive = !GetScreen()->m_BlockLocate.IsIdle();
+
+ // Simple location of elements where possible.
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ {
+ SetCurItem( item = ModeditLocateAndDisplay() );
+ }
+
+ // End command in progress.
+ if( GetToolId() != ID_NO_TOOL_SELECTED )
+ {
+ if( item && item->GetFlags() )
+ AddMenuItem( PopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ),
+ KiBitmap( cancel_xpm ) );
+ else
+ AddMenuItem( PopMenu, ID_POPUP_CLOSE_CURRENT_TOOL, _( "End Tool" ),
+ KiBitmap( cursor_xpm ) );
+
+ PopMenu->AppendSeparator();
+ }
+ else
+ {
+ if( (item && item->GetFlags()) || blockActive )
+ {
+ if( blockActive ) // Put block commands in list
+ {
+ AddMenuItem( PopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND,
+ _( "Cancel Block" ), KiBitmap( cancel_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_ZOOM_BLOCK,
+ _( "Zoom Block (drag middle mouse)" ),
+ KiBitmap( zoom_area_xpm ) );
+ PopMenu->AppendSeparator();
+ AddMenuItem( PopMenu, ID_POPUP_PLACE_BLOCK,
+ _( "Place Block" ), KiBitmap( checked_ok_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_COPY_BLOCK,
+ _( "Copy Block (shift + drag mouse)" ),
+ KiBitmap( copyblock_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_MIRROR_X_BLOCK,
+ _( "Mirror Block (alt + drag mouse)" ),
+ KiBitmap( mirror_h_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_ROTATE_BLOCK,
+ _( "Rotate Block (ctrl + drag mouse)" ),
+ KiBitmap( rotate_ccw_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_DELETE_BLOCK,
+ _( "Delete Block (shift+ctrl + drag mouse)" ),
+ KiBitmap( delete_xpm ) );
+
+ msg = AddHotkeyName( _("Move Block Exactly" ),
+ g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM_EXACT );
+ AddMenuItem( PopMenu, ID_POPUP_MOVE_BLOCK_EXACT,
+ msg, KiBitmap( move_xpm ) );
+ }
+ else
+ {
+ AddMenuItem( PopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND,
+ _( "Cancel" ), KiBitmap( cancel_xpm ) );
+ }
+
+ PopMenu->AppendSeparator();
+ }
+ }
+
+ if( blockActive )
+ return true;
+
+ if( item )
+ {
+ STATUS_FLAGS flags = item->GetFlags();
+ switch( item->Type() )
+ {
+ case PCB_MODULE_T:
+ {
+ wxMenu* transform_choice = new wxMenu;
+ AddMenuItem( transform_choice, ID_MODEDIT_MODULE_ROTATE, _( "Rotate" ),
+ KiBitmap( rotate_module_ccw_xpm ) );
+ AddMenuItem( transform_choice, ID_MODEDIT_MODULE_MIRROR, _( "Mirror" ),
+ KiBitmap( mirror_footprint_axisY_xpm ) );
+ AddMenuItem( transform_choice, ID_MODEDIT_MODULE_MOVE_EXACT, _( "Move Exactly" ),
+ KiBitmap( move_module_xpm ) );
+
+ msg = AddHotkeyName( _( "Edit Footprint" ), g_Module_Editor_Hokeys_Descr, HK_EDIT_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_MODULE_PRMS, msg, KiBitmap( edit_module_xpm ) );
+ AddMenuItem( PopMenu, transform_choice, ID_MODEDIT_TRANSFORM_MODULE,
+ _( "Transform Footprint" ), KiBitmap( edit_xpm ) );
+
+ break;
+ }
+
+ case PCB_PAD_T:
+ if( !flags )
+ {
+ msg = AddHotkeyName( _("Move Pad" ), g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_PAD_REQUEST, msg, KiBitmap( move_pad_xpm ) );
+ }
+
+ msg = AddHotkeyName( _("Edit Pad" ), g_Module_Editor_Hokeys_Descr, HK_EDIT_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_PAD, msg, KiBitmap( options_pad_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_IMPORT_PAD_SETTINGS,
+ _( "New Pad Settings" ), KiBitmap( options_new_pad_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_EXPORT_PAD_SETTINGS,
+ _( "Export Pad Settings" ), KiBitmap( export_options_pad_xpm ) );
+ msg = AddHotkeyName( _("Delete Pad" ), g_Module_Editor_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_DELETE_PAD, msg, KiBitmap( delete_pad_xpm ) );
+
+ msg = AddHotkeyName( _( "Duplicate Pad" ), g_Module_Editor_Hokeys_Descr, HK_DUPLICATE_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_DUPLICATE_ITEM, msg, KiBitmap( duplicate_pad_xpm ) );
+
+ msg = AddHotkeyName( _("Move Pad Exactly" ), g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM_EXACT );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_EXACT, msg, KiBitmap( move_pad_xpm ) );
+
+ msg = AddHotkeyName( _("Create Pad Array" ), g_Module_Editor_Hokeys_Descr, HK_CREATE_ARRAY );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_CREATE_ARRAY, msg, KiBitmap( array_pad_xpm ) );
+
+
+ if( !flags )
+ {
+ PopMenu->AppendSeparator();
+ AddMenuItem( PopMenu, ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS,
+ _( "Global Pad Settings" ), KiBitmap( global_options_pad_xpm ) );
+ }
+
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ if( !flags )
+ {
+ msg = AddHotkeyName( _("Move Text" ), g_Module_Editor_Hokeys_Descr,
+ HK_MOVE_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST, msg,
+ KiBitmap( move_field_xpm ) );
+ }
+
+ msg = AddHotkeyName( _("Rotate Text" ), g_Module_Editor_Hokeys_Descr,
+ HK_ROTATE_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_ROTATE_TEXTMODULE, msg, KiBitmap( rotate_field_xpm ) );
+
+ {
+ // Do not show option to replicate value or reference fields
+ // (there can only be one of each)
+
+ const MODULE* module = static_cast<MODULE*>( item->GetParent() );
+ const TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
+
+ if( &module->Reference() != text && &module->Value() != text )
+ {
+ msg = AddHotkeyName( _( "Duplicate Text" ),
+ g_Module_Editor_Hokeys_Descr, HK_DUPLICATE_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_DUPLICATE_ITEM,
+ msg, KiBitmap( duplicate_text_xpm ) );
+
+ msg = AddHotkeyName( _("Create Text Array" ),
+ g_Module_Editor_Hokeys_Descr, HK_CREATE_ARRAY );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_CREATE_ARRAY,
+ msg, KiBitmap( array_text_xpm ) );
+ }
+ }
+
+ msg = AddHotkeyName( _("Move Text Exactly" ), g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM_EXACT );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_EXACT, msg, KiBitmap( move_field_xpm ) );
+
+ if( !flags )
+ {
+ msg = AddHotkeyName( _("Edit Text" ), g_Module_Editor_Hokeys_Descr,
+ HK_EDIT_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_TEXTMODULE, msg, KiBitmap( edit_text_xpm ) );
+
+ if( ( static_cast<TEXTE_MODULE*>( item ) )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
+ {
+ msg = AddHotkeyName( _("Delete Text" ), g_Module_Editor_Hokeys_Descr,
+ HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_DELETE_TEXTMODULE, msg,
+ KiBitmap( delete_text_xpm ) );
+ }
+ }
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ {
+ if( (flags & IS_NEW) )
+ AddMenuItem( PopMenu, ID_POPUP_PCB_STOP_CURRENT_DRAWING, _( "End edge" ),
+ KiBitmap( checked_ok_xpm ) );
+
+ if( !flags )
+ {
+ msg = AddHotkeyName( _("Move Edge" ), g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_EDGE, msg, KiBitmap( move_line_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Duplicate Edge" ), g_Module_Editor_Hokeys_Descr, HK_DUPLICATE_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_DUPLICATE_ITEM, msg, KiBitmap( duplicate_line_xpm ) );
+
+ msg = AddHotkeyName( _("Move Edge Exactly" ), g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM_EXACT );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_EXACT, msg, KiBitmap( move_line_xpm ) );
+
+ msg = AddHotkeyName( _("Create Edge Array" ), g_Module_Editor_Hokeys_Descr, HK_CREATE_ARRAY );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_CREATE_ARRAY, msg, KiBitmap( array_line_xpm ) );
+
+ if( ( flags & (IS_NEW | IS_MOVED) ) == IS_MOVED )
+ AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_EDGE, _( "Place edge" ),
+ KiBitmap( checked_ok_xpm ) );
+
+ msg = AddHotkeyName( _("Edit" ), g_Module_Editor_Hokeys_Descr, HK_EDIT_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_MODEDIT_EDIT_BODY_ITEM,
+ msg, KiBitmap( options_segment_xpm ) );
+
+ msg = AddHotkeyName( _("Delete Edge" ), g_Module_Editor_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_DELETE_EDGE, msg, KiBitmap( delete_xpm ) );
+
+ wxMenu* edit_global_mnu = new wxMenu;
+ AddMenuItem( PopMenu, edit_global_mnu, ID_POPUP_MODEDIT_GLOBAL_EDIT_EDGE,
+ _( "Global Changes" ), KiBitmap( edit_xpm ) );
+ AddMenuItem( edit_global_mnu, ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE,
+ _( "Change Body Items Width" ), KiBitmap( width_segment_xpm ) );
+ AddMenuItem( edit_global_mnu, ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE,
+ _( "Change Body Items Layer" ), KiBitmap( select_layer_pair_xpm ) );
+ }
+ break;
+
+ case PCB_LINE_T:
+ case PCB_TEXT_T:
+ case PCB_VIA_T:
+ case PCB_TRACE_T:
+ case PCB_ZONE_T:
+ case PCB_MARKER_T:
+ case PCB_DIMENSION_T:
+ case PCB_TARGET_T:
+ msg.Printf( wxT( "FOOTPRINT_EDIT_FRAME::OnRightClick Error: Unexpected DrawType %d" ),
+ item->Type() );
+ DisplayError( this, msg );
+ break;
+
+ case SCREEN_T:
+ case TYPE_NOT_INIT:
+ case PCB_T:
+ msg.Printf( wxT( "FOOTPRINT_EDIT_FRAME::OnRightClick Error: illegal DrawType %d" ),
+ item->Type() );
+ DisplayError( this, msg );
+ break;
+
+ default:
+ msg.Printf( wxT( "FOOTPRINT_EDIT_FRAME::OnRightClick Error: unknown DrawType %d" ),
+ item->Type() );
+ DisplayError( this, msg );
+ break;
+ }
+ PopMenu->AppendSeparator();
+ }
+
+ if( ( GetToolId() == ID_MODEDIT_LINE_TOOL ) ||
+ ( GetToolId() == ID_MODEDIT_CIRCLE_TOOL ) ||
+ ( GetToolId() == ID_MODEDIT_ARC_TOOL ) )
+ {
+ AddMenuItem( PopMenu, ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH, _("Set Line Width" ),
+ KiBitmap( width_segment_xpm ) );
+ PopMenu->AppendSeparator();
+ }
+
+ return true;
+}
+
+/*
+ * Called on a mouse left button double click
+ */
+void FOOTPRINT_EDIT_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& MousePos )
+{
+ BOARD_ITEM* item = GetCurItem();
+
+ switch( GetToolId() )
+ {
+ case ID_NO_TOOL_SELECTED:
+ if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
+ {
+ item = ModeditLocateAndDisplay();
+ }
+
+ if( ( item == NULL ) || ( item->GetFlags() != 0 ) )
+ break;
+
+ // Item found
+ SetCurItem( item );
+ OnEditItemRequest( DC, item );
+ break; // end case 0
+
+ case ID_PCB_ADD_LINE_BUTT:
+ {
+ if( item && item->IsNew() )
+ {
+ End_Edge_Module( (EDGE_MODULE*) item );
+ SetCurItem( NULL );
+ m_canvas->Refresh();
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem )
+{
+ switch( aItem->Type() )
+ {
+ case PCB_PAD_T:
+ InstallPadOptionsFrame( static_cast<D_PAD*>( aItem ) );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case PCB_MODULE_T:
+ {
+ DIALOG_MODULE_MODULE_EDITOR dialog( this, static_cast<MODULE*>( aItem ) );
+ int ret = dialog.ShowModal();
+ GetScreen()->GetCurItem()->ClearFlags();
+ m_canvas->MoveCursorToCrossHair();
+
+ if( ret > 0 )
+ m_canvas->Refresh();
+ }
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ InstallTextModOptionsFrame( static_cast<TEXTE_MODULE*>( aItem ), aDC );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case PCB_MODULE_EDGE_T :
+ m_canvas->MoveCursorToCrossHair();
+ InstallFootprintBodyItemPropertiesDlg( static_cast<EDGE_MODULE*>( aItem ) );
+ m_canvas->Refresh();
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/pcbnew/modedit_undo_redo.cpp b/pcbnew/modedit_undo_redo.cpp
new file mode 100644
index 0000000..ac72fd6
--- /dev/null
+++ b/pcbnew/modedit_undo_redo.cpp
@@ -0,0 +1,174 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <boost/bind.hpp>
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <class_draw_panel_gal.h>
+#include <tool/tool_manager.h>
+#include <wxPcbStruct.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <pcbnew.h>
+#include <protos.h>
+#include <module_editor_frame.h>
+
+
+void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem,
+ UNDO_REDO_T aTypeCommand,
+ const wxPoint& aTransformPoint )
+{
+ EDA_ITEM* item;
+ MODULE* CopyItem;
+ PICKED_ITEMS_LIST* lastcmd;
+
+ CopyItem = new MODULE( *( (MODULE*) aItem ) );
+ CopyItem->SetParent( GetBoard() );
+
+ lastcmd = new PICKED_ITEMS_LIST();
+ ITEM_PICKER wrapper( CopyItem, UR_MODEDIT );
+ lastcmd->PushItem( wrapper );
+
+ GetScreen()->PushCommandToUndoList( lastcmd );
+
+ /* Clear current flags (which can be temporary set by a current edit command) */
+ for( item = CopyItem->GraphicalItems(); item != NULL; item = item->Next() )
+ item->ClearFlags();
+
+ for( D_PAD* pad = CopyItem->Pads(); pad; pad = pad->Next() )
+ pad->ClearFlags();
+
+ CopyItem->Reference().ClearFlags();
+ CopyItem->Value().ClearFlags();
+
+ /* Clear redo list, because after new save there is no redo to do */
+ GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
+ UNDO_REDO_T aTypeCommand,
+ const wxPoint& aTransformPoint )
+{
+ assert( aItemsList.GetPickedItem( 0 )->GetParent()->Type() == PCB_MODULE_T );
+ MODULE* owner = static_cast<MODULE*>( aItemsList.GetPickedItem( 0 )->GetParent() );
+
+#ifndef NDEBUG
+ // All items should have the same parent (MODULE) to make undo/redo entry valid
+ for( unsigned int i = 0; i < aItemsList.GetCount(); ++i )
+ assert( aItemsList.GetPickedItem( i )->GetParent() == owner );
+#endif /* not NDEBUG */
+
+ SaveCopyInUndoList( owner, aTypeCommand, aTransformPoint );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent )
+{
+ if( GetScreen()->GetRedoCommandCount() <= 0 )
+ return;
+
+ // Inform tools that undo command was issued
+ TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
+ m_toolManager->ProcessEvent( event );
+
+ // Save current module state in undo list
+ PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
+ MODULE* module = GetBoard()->m_Modules.PopFront();
+ ITEM_PICKER wrapper( module, UR_MODEDIT );
+ KIGFX::VIEW* view = GetGalCanvas()->GetView();
+ lastcmd->PushItem( wrapper );
+ GetScreen()->PushCommandToUndoList( lastcmd );
+
+ view->Remove( module );
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
+
+ // Retrieve last module state from undo list
+ lastcmd = GetScreen()->PopCommandFromRedoList();
+ wrapper = lastcmd->PopItem();
+ module = (MODULE*) wrapper.GetItem();
+ delete lastcmd;
+
+ if( module )
+ {
+ GetBoard()->Add( module );
+ GetGalCanvas()->GetView()->Add( module );
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
+ module->ViewUpdate();
+ }
+
+ SetCurItem( NULL );
+
+ OnModify();
+ m_canvas->Refresh();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent )
+{
+ if( UndoRedoBlocked() )
+ return;
+
+ if( GetScreen()->GetUndoCommandCount() <= 0 )
+ return;
+
+ // Inform tools that undo command was issued
+ TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
+ m_toolManager->ProcessEvent( event );
+
+ if( UndoRedoBlocked() )
+ return;
+
+ // Save current module state in redo list
+ PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
+ MODULE* module = GetBoard()->m_Modules.PopFront();
+ ITEM_PICKER wrapper( module, UR_MODEDIT );
+ KIGFX::VIEW* view = GetGalCanvas()->GetView();
+ lastcmd->PushItem( wrapper );
+ GetScreen()->PushCommandToRedoList( lastcmd );
+
+ view->Remove( module );
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
+
+ // Retrieve last module state from undo list
+ lastcmd = GetScreen()->PopCommandFromUndoList();
+ wrapper = lastcmd->PopItem();
+ module = (MODULE*) wrapper.GetItem();
+ delete lastcmd;
+
+ if( module )
+ {
+ GetBoard()->Add( module, ADD_APPEND );
+ view->Add( module );
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
+ module->ViewUpdate();
+ }
+
+ SetCurItem( NULL );
+
+ OnModify();
+ m_canvas->Refresh();
+}
diff --git a/pcbnew/modeditoptions.cpp b/pcbnew/modeditoptions.cpp
new file mode 100644
index 0000000..ac06b7f
--- /dev/null
+++ b/pcbnew/modeditoptions.cpp
@@ -0,0 +1,151 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file modeditoptions.cpp
+ * @brief Pcbnew footprint (module) editor options.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <module_editor_frame.h>
+#include <class_board_design_settings.h>
+#include <layers_id_colors_and_visibility.h>
+
+#include <pcbnew_id.h>
+
+
+void FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+ bool state = m_optionsToolBar->GetToolToggled( id );
+
+ switch( id )
+ {
+ case ID_TB_OPTIONS_SHOW_PADS_SKETCH:
+ displ_opts->m_DisplayPadFill = !state;
+ m_canvas->Refresh( );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_VIAS_SKETCH:
+ displ_opts->m_DisplayViaFill = !state;
+ m_canvas->Refresh( );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH:
+ displ_opts->m_DisplayModTextFill = state ? SKETCH : FILLED;
+ m_canvas->Refresh( );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH:
+ displ_opts->m_DisplayModEdgeFill = state ? SKETCH : FILLED;
+ m_canvas->Refresh( );
+ break;
+
+ case ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE:
+ displ_opts->m_ContrastModeDisplay = state;
+ m_canvas->Refresh( );
+ break;
+
+ default:
+ wxMessageBox( wxT( "FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar error" ) );
+ break;
+ }
+}
+
+
+PARAM_CFG_ARRAY& FOOTPRINT_EDIT_FRAME::GetConfigurationSettings()
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) GetDisplayOptions();
+ BOARD_DESIGN_SETTINGS& settings = GetDesignSettings();
+
+ // Update everything
+ m_configSettings.clear(); // boost::ptr_vector destroys the pointers inside
+
+ // Display options:
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "FpEditorUnits" ),
+ (int*)&g_UserUnit, MILLIMETRES ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "FpEditorDisplayPolarCoords" ),
+ &displ_opts->m_DisplayPolarCood, false ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "FpEditorPadDisplayMode" ),
+ &displ_opts->m_DisplayPadFill, true ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "FpEditorGraphicLinesDisplayMode" ),
+ &displ_opts->m_DisplayModEdgeFill, FILLED ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "FpEditorTextsDisplayMode" ),
+ &displ_opts->m_DisplayModTextFill, FILLED ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "FpEditorTextsDisplayMode" ),
+ &displ_opts->m_DisplayModTextFill, FILLED ) );
+ m_configSettings.push_back( new PARAM_CFG_WXSTRING( true, wxT( "FpEditorTextsRefDefaultText" ),
+ &settings.m_RefDefaultText, wxT( "REF**" ) ) );
+
+ // design settings
+ m_configSettings.push_back( new PARAM_CFG_INT_WITH_SCALE( true, wxT( "FpEditorGrlineWidth" ),
+ &settings.m_ModuleSegmentWidth,
+ Millimeter2iu( DEFAULT_GR_MODULE_THICKNESS ),
+ Millimeter2iu( 0.01 ), Millimeter2iu( 100.0 ),
+ NULL, 1/IU_PER_MM ) );
+ m_configSettings.push_back( new PARAM_CFG_INT_WITH_SCALE( true, wxT( "FpEditorTextsDefaultSizeH" ),
+ &settings.m_ModuleTextSize.x,
+ Millimeter2iu( DEFAULT_TEXT_MODULE_SIZE ),
+ Millimeter2iu( 0.01 ), Millimeter2iu( 100.0 ),
+ NULL, 1/IU_PER_MM ) );
+ m_configSettings.push_back( new PARAM_CFG_INT_WITH_SCALE( true, wxT( "FpEditorTextsDefaultSizeV" ),
+ &settings.m_ModuleTextSize.y,
+ Millimeter2iu( DEFAULT_TEXT_MODULE_SIZE ),
+ Millimeter2iu(0.01), Millimeter2iu( 100.0 ),
+ NULL, 1/IU_PER_MM ) );
+ m_configSettings.push_back( new PARAM_CFG_INT_WITH_SCALE( true, wxT( "FpEditorTextsDefaultThickness" ),
+ &settings.m_ModuleTextWidth,
+ Millimeter2iu( DEFAULT_GR_MODULE_THICKNESS ),
+ Millimeter2iu( 0.01 ), Millimeter2iu( 20.0 ),
+ NULL, 1/IU_PER_MM ) );
+
+ m_configSettings.push_back( new PARAM_CFG_WXSTRING( true,
+ wxT( "FpEditorRefDefaultText" ),
+ &settings.m_RefDefaultText, wxT( "REF**" ) ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true,
+ wxT( "FpEditorRefDefaultVisibility" ),
+ &settings.m_RefDefaultVisibility, true ) );
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "FpEditorRefDefaultLayer" ),
+ &settings.m_RefDefaultlayer,
+ int( F_SilkS ), int( F_SilkS ), int( F_Fab ) ) );
+
+ m_configSettings.push_back( new PARAM_CFG_WXSTRING( true, wxT( "FpEditorValueDefaultText" ),
+ &settings.m_ValueDefaultText, wxT( "" ) ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true,
+ wxT( "FpEditorValueDefaultVisibility" ),
+ &settings.m_ValueDefaultVisibility, true ) );
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "FpEditorValueDefaultLayer" ),
+ &settings.m_ValueDefaultlayer,
+ int( F_Fab ), int( F_SilkS ), int( F_Fab ) ) );
+
+ return m_configSettings;
+}
+
diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h
new file mode 100644
index 0000000..ce32a2e
--- /dev/null
+++ b/pcbnew/module_editor_frame.h
@@ -0,0 +1,551 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file module_editor_frame.h
+ * @brief Definition of class FOOTPRINT_EDIT_FRAME.
+ */
+
+#ifndef MODULE_EDITOR_FRAME_H_
+#define MODULE_EDITOR_FRAME_H_
+
+#include <wxBasePcbFrame.h>
+#include <pcb_base_edit_frame.h>
+#include <io_mgr.h>
+
+class PCB_LAYER_WIDGET;
+class FP_LIB_TABLE;
+
+namespace PCB { struct IFACE; } // A KIFACE_I coded in pcbnew.c
+
+
+class FOOTPRINT_EDIT_FRAME : public PCB_BASE_EDIT_FRAME
+{
+ friend struct PCB::IFACE;
+
+public:
+
+ ~FOOTPRINT_EDIT_FRAME();
+
+ /**
+ * Function GetFootprintEditorFrameName (static)
+ * @return the frame name used when creating the frame
+ * used to get a reference to this frame, if exists
+ */
+ static const wxChar* GetFootprintEditorFrameName();
+
+ BOARD_DESIGN_SETTINGS& GetDesignSettings() const; // overload PCB_BASE_FRAME, get parent's
+ void SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings ); // overload
+
+ const PCB_PLOT_PARAMS& GetPlotSettings() const; // overload PCB_BASE_FRAME, get parent's
+ void SetPlotSettings( const PCB_PLOT_PARAMS& aSettings ); // overload
+
+ void LoadSettings( wxConfigBase* aCfg ); // Virtual
+ void SaveSettings( wxConfigBase* aCfg ); // Virtual
+
+ /**
+ * Function GetConfigurationSettings
+ * returns the footpr�int editor settings list.
+ *
+ * Currently, only the settings that are needed at start
+ * up by the main window are defined here. There are other locally used
+ * settings that are scattered throughout the Pcbnew source code. If you need
+ * to define a configuration setting that needs to be loaded at run time,
+ * this is the place to define it.
+ *
+ * @return - Reference to the list of applications settings.
+ */
+ PARAM_CFG_ARRAY& GetConfigurationSettings();
+
+ void InstallOptionsFrame( const wxPoint& pos );
+
+ void OnCloseWindow( wxCloseEvent& Event );
+ void CloseModuleEditor( wxCommandEvent& Event );
+
+ void Process_Special_Functions( wxCommandEvent& event );
+
+ void ProcessPreferences( wxCommandEvent& event );
+
+ /**
+ * Function RedrawActiveWindoow
+ * draws the footprint editor BOARD, and others elements such as axis and grid.
+ */
+ void RedrawActiveWindow( wxDC* DC, bool EraseBg );
+
+ /**
+ * Function ReCreateHToolbar
+ * create the main horizontal toolbar for the footprint editor
+ */
+ void ReCreateHToolbar();
+
+ void ReCreateVToolbar();
+ void ReCreateOptToolbar();
+ void ReCreateAuxiliaryToolbar();
+ void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
+
+ /**
+ * Function OnLeftDClick
+ * handles the double click in the footprint editor:
+ * If the double clicked item is editable: call the corresponding editor.
+ */
+ void OnLeftDClick( wxDC* DC, const wxPoint& MousePos );
+
+ /**
+ * Function OnRightClick
+ * handles the right mouse click in the footprint editor:
+ * Create the pop up menu
+ * After this menu is built, the standard ZOOM menu is added
+ */
+ bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
+
+ /**
+ * @brief (Re)Create the menubar for the module editor frame
+ */
+ void ReCreateMenuBar();
+
+ // The Tool Framework initalization, for GAL mode
+ void setupTools();
+
+ void ToolOnRightClick( wxCommandEvent& event );
+ void OnSelectOptionToolbar( wxCommandEvent& event );
+ void OnConfigurePaths( wxCommandEvent& aEvent );
+
+ /**
+ * Function OnSaveLibraryAs
+ * saves the current library to a new name and/or library type.
+ *
+ * @note Saving as a new library type requires the plug-in to support saving libraries
+ * @see PLUGIN::FootprintSave and PLUGIN::FootprintLibCreate
+ */
+ void OnSaveLibraryAs( wxCommandEvent& aEvent );
+
+ ///> @copydoc EDA_DRAW_FRAME::GetHotKeyDescription()
+ EDA_HOTKEY* GetHotKeyDescription( int aCommand ) const;
+
+ /**
+ * Function OnHotKey
+ * handle hot key events.
+ * <p>
+ * Some commands are relative to the item under the mouse cursor. Commands are
+ * case insensitive
+ * </p>
+ */
+ bool OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem = NULL );
+
+ BOARD_ITEM* PrepareItemForHotkey( bool failIfCurrentlyEdited );
+
+ bool OnHotkeyEditItem( int aIdCommand );
+ bool OnHotkeyDeleteItem( int aIdCommand );
+ bool OnHotkeyMoveItem( int aIdCommand );
+ bool OnHotkeyMoveItemExact();
+ bool OnHotkeyRotateItem( int aIdCommand );
+ bool OnHotkeyDuplicateItem( int aIdCommand );
+
+ /**
+ * Function Show3D_Frame
+ * displays 3D view of the footprint (module) being edited.
+ */
+ void Show3D_Frame( wxCommandEvent& event );
+
+ bool GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey = 0 );
+ void OnVerticalToolbar( wxCommandEvent& aEvent );
+
+ void OnUpdateVerticalToolbar( wxUpdateUIEvent& aEvent );
+ void OnUpdateOptionsToolbar( wxUpdateUIEvent& aEvent );
+ void OnUpdateLibSelected( wxUpdateUIEvent& aEvent );
+ void OnUpdateModuleSelected( wxUpdateUIEvent& aEvent );
+ void OnUpdateLibAndModuleSelected( wxUpdateUIEvent& aEvent );
+ void OnUpdateLoadModuleFromBoard( wxUpdateUIEvent& aEvent );
+ void OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent );
+ void OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent );
+ void OnUpdateSelectCurrentLib( wxUpdateUIEvent& aEvent );
+
+ ///> @copydoc PCB_BASE_EDIT_FRAME::OnEditItemRequest()
+ void OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem );
+
+ /**
+ * Function LoadModuleFromBoard
+ * called from the main toolbar to load a footprint from board mainly to edit it.
+ */
+ void LoadModuleFromBoard( wxCommandEvent& event );
+
+ /**
+ * Function SaveFootprintInLibrary
+ * Save in an existing library a given footprint
+ * @param aLibName = name of the library to use
+ * @param aModule = the given footprint
+ * @param aOverwrite = true to overwrite an existing footprint, false to
+ * abort if an existing footprint with same name is found
+ * @param aDisplayDialog = true to display a dialog to enter or confirm the
+ * footprint name
+ * @return : true if OK, false if abort
+ */
+ bool SaveFootprintInLibrary( const wxString& aLibName,
+ MODULE* aModule,
+ bool aOverwrite,
+ bool aDisplayDialog );
+
+ /**
+ * Virtual Function OnModify()
+ * Must be called after a footprint change
+ * in order to set the "modify" flag of the current screen
+ * and prepare, if needed the refresh of the 3D frame showing the footprint
+ * do not forget to call the basic OnModify function to update auxiliary info
+ */
+ virtual void OnModify();
+
+ /**
+ * Function ToPrinter
+ * Install the print dialog
+ */
+ void ToPrinter( wxCommandEvent& event );
+
+ /**
+ * Function PrintPage
+ * is used to print a page. Prints the page pointed by ActiveScreen,
+ * set by the calling print function.
+ * @param aDC = wxDC given by the calling print function
+ * @param aPrintMaskLayer = not used here
+ * @param aPrintMirrorMode = not used here (Set when printing in mirror mode)
+ * @param aData = a pointer on an auxiliary data (NULL if not used)
+ */
+ virtual void PrintPage( wxDC* aDC, LSET aPrintMaskLayer, bool aPrintMirrorMode,
+ void * aData = NULL);
+
+ // BOARD handling
+
+ /**
+ * Function Clear_Pcb
+ * delete all and reinitialize the current board
+ * @param aQuery = true to prompt user for confirmation, false to initialize silently
+ */
+ bool Clear_Pcb( bool aQuery );
+
+ /* handlers for block commands */
+ virtual int BlockCommand( int key );
+
+ /**
+ * Function HandleBlockPlace
+ * handles the BLOCK PLACE command
+ * Last routine for block operation for:
+ * - block move & drag
+ * - block copy & paste
+ */
+ virtual void HandleBlockPlace( wxDC* DC );
+
+ /**
+ * Function HandleBlockEnd( )
+ * Handle the "end" of a block command,
+ * i.e. is called at the end of the definition of the area of a block.
+ * depending on the current block command, this command is executed
+ * or parameters are initialized to prepare a call to HandleBlockPlace
+ * in GetScreen()->m_BlockLocate
+ * @return false if no item selected, or command finished,
+ * true if some items found and HandleBlockPlace must be called later
+ */
+ virtual bool HandleBlockEnd( wxDC* DC );
+
+ BOARD_ITEM* ModeditLocateAndDisplay( int aHotKeyCode = 0 );
+
+ /* Undo and redo functions */
+
+ /**
+ * Function SaveCopyInUndoList.
+ * Creates a new entry in undo list of commands.
+ * add a picker to handle aItemToCopy
+ * @param aItem = the board item modified by the command to undo
+ * @param aTypeCommand = command type (see enum UNDO_REDO_T)
+ * @param aTransformPoint = the reference point of the transformation, for
+ * commands like move
+ */
+ virtual void SaveCopyInUndoList( BOARD_ITEM* aItem,
+ UNDO_REDO_T aTypeCommand,
+ const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
+
+ /**
+ * Function SaveCopyInUndoList (overloaded).
+ * Creates a new entry in undo list of commands.
+ * add a list of pickers to handle a list of items
+ * @param aItemsList = the list of items modified by the command to undo
+ * @param aTypeCommand = command type (see enum UNDO_REDO_T)
+ * @param aTransformPoint = the reference point of the transformation, for
+ * commands like move
+ */
+ virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
+ UNDO_REDO_T aTypeCommand,
+ const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
+
+ /**
+ * Function RestoreCopyFromUndoList
+ * performs an undo operation on the last edition:
+ * - Place the current edited library component in Redo list
+ * - Get old version of the current edited library component
+ */
+ void RestoreCopyFromUndoList( wxCommandEvent& aEvent );
+
+ /**
+ * Function RestoreCopyFromRedoList
+ * performs a redo operation on the the last edition:
+ * - Place the current edited library component in undo list
+ * - Get old version of the current edited library component
+ */
+ void RestoreCopyFromRedoList( wxCommandEvent& aEvent );
+
+ /// Return the current library nickname.
+ const wxString GetCurrentLib() const;
+
+ // Footprint edition
+ void RemoveStruct( EDA_ITEM* Item );
+
+ /**
+ * Function Transform
+ * performs a geometric transform on the current footprint.
+ */
+ void Transform( MODULE* module, int transform );
+
+ // importing / exporting Footprint
+ /**
+ * Function Export_Module
+ * Create a file containing only one footprint.
+ * Used to export a footprint
+ * Exported files have the standard ext .emp
+ * This is the same format as .mod files but restricted to only one footprint
+ * So Create a new lib (which will contains one module) and export a footprint
+ * is basically the same thing
+ * @param aModule = the module to export
+ */
+ void Export_Module( MODULE* aModule );
+
+ /**
+ * Function Import_Module
+ * Read a file containing only one footprint.
+ * Used to import (after exporting) a footprint
+ * Exported files have the standard ext .emp
+ * This is the same format as .mod files but restricted to only one footprint
+ * The import function can also read gpcb footprint file, in Newlib format
+ * (One footprint per file, Newlib files have no special ext.)
+ */
+ MODULE* Import_Module();
+
+ /**
+ * Function SaveCurrentModule
+ * saves the module which is currently being edited into aLibPath or into the
+ * currently selected library if aLibPath is NULL.
+ * @return bool - true if successfully saved, else false because abort or error.
+ */
+ bool SaveCurrentModule( const wxString* aLibPath = NULL );
+
+ /**
+ * Function Load_Module_From_BOARD
+ * load in Modedit a footprint from the main board
+ * @param Module = the module to load. If NULL, a module reference will we asked to user
+ * @return true if a module isloaded, false otherwise.
+ */
+ bool Load_Module_From_BOARD( MODULE* Module );
+
+ /**
+ * Function SelectFootprint
+ * Display the list of modules currently existing on the BOARD
+ * @return a pointer to a module if this module is selected or NULL otherwise
+ * @param aPcb = the board from modules can be loaded
+ */
+ MODULE* SelectFootprint( BOARD* aPcb );
+
+ // functions to edit footprint edges
+
+ /**
+ * Function Edit_Edge_Width
+ * changes the width of module perimeter lines, EDGE_MODULEs.
+ * param ModuleSegmentWidth (global) = new width
+ * @param aEdge = edge to edit, or NULL. If aEdge == NULL change
+ * the width of all footprint's edges
+ */
+ void Edit_Edge_Width( EDGE_MODULE* aEdge );
+
+ /**
+ * Function Edit_Edge_Layer
+ * changes the EDGE_MODULE Edge layer, (The new layer will be asked)
+ * if Edge == NULL change the layer of the entire footprint edges
+ * @param Edge = edge to edit, or NULL
+ */
+ void Edit_Edge_Layer( EDGE_MODULE* Edge );
+
+ /**
+ * Function Delete_Edge_Module
+ * deletes EDGE_MODULE Edge
+ * @param Edge = edge to delete
+ */
+ void Delete_Edge_Module( EDGE_MODULE* Edge );
+
+ /**
+ * Function Begin_Edge_Module
+ * creates a new edge item (line, arc ..).
+ * @param Edge = if NULL: create new edge else terminate edge and create a
+ * new edge
+ * @param DC = current Device Context
+ * @param type_edge = S_SEGMENT,S_ARC ..
+ * @return the new created edge.
+ */
+ EDGE_MODULE* Begin_Edge_Module( EDGE_MODULE* Edge, wxDC* DC, STROKE_T type_edge );
+
+ /**
+ * Function End_Edge_Module
+ * terminates a move or create edge function
+ */
+ void End_Edge_Module( EDGE_MODULE* Edge );
+
+ /**
+ * Function Enter_Edge_Width
+ * Edition of width of module outlines
+ * Ask for a new width.
+ * Change the width of EDGE_MODULE Edge if aEdge != NULL
+ * @param aEdge = edge to edit, or NULL
+ * changes ModuleSegmentWidth (global) = new width
+ */
+ void Enter_Edge_Width( EDGE_MODULE* aEdge );
+
+ /// Function to initialize the move function params of a graphic item type DRAWSEGMENT
+ void Start_Move_EdgeMod( EDGE_MODULE* drawitem, wxDC* DC );
+
+ /// Function to place a graphic item type EDGE_MODULE currently moved
+ void Place_EdgeMod( EDGE_MODULE* drawitem );
+
+ /**
+ * Function InstallFootprintBodyItemPropertiesDlg
+ * Install a dialog to edit a graphic item of a footprint body.
+ * @param aItem = a pointer to the graphic item to edit
+ */
+ void InstallFootprintBodyItemPropertiesDlg( EDGE_MODULE* aItem );
+
+ /**
+ * Function DlgGlobalChange_PadSettings
+ * changes pad characteristics for the given footprint
+ * or all footprints which look like the given footprint.
+ * Options are set by the opened dialog.
+ * @param aPad is the pattern. The given footprint is the parent of this pad
+ */
+ void DlgGlobalChange_PadSettings( D_PAD* aPad );
+
+ /**
+ * Function DeleteModuleFromCurrentLibrary
+ * prompts user for footprint name, then deletes it from current library.
+ */
+ bool DeleteModuleFromCurrentLibrary();
+
+ /**
+ * Function IsElementVisible
+ * tests whether a given element category is visible. Keep this as an
+ * inline function.
+ * @param aElement is from the enum by the same name
+ * @return bool - true if the element is visible.
+ * @see enum PCB_VISIBLE
+ */
+ bool IsElementVisible( int aElement ) const;
+
+ /**
+ * Function SetElementVisibility
+ * changes the visibility of an element category
+ * @param aElement is from the enum by the same name
+ * @param aNewState = The new visibility state of the element category
+ * @see enum PCB_VISIBLE
+ */
+ void SetElementVisibility( int aElement, bool aNewState );
+
+ /**
+ * Function IsGridVisible() , virtual
+ * @return true if the grid must be shown
+ */
+ virtual bool IsGridVisible() const;
+
+ /**
+ * Function SetGridVisibility() , virtual
+ * It may be overloaded by derived classes
+ * if you want to store/retrieve the grid visibility in configuration.
+ * @param aVisible = true if the grid must be shown
+ */
+ virtual void SetGridVisibility( bool aVisible );
+
+ /**
+ * Function GetGridColor() , virtual
+ * @return the color of the grid
+ */
+ virtual EDA_COLOR_T GetGridColor() const;
+
+ ///> @copydoc PCB_BASE_FRAME::SetActiveLayer()
+ void SetActiveLayer( LAYER_ID aLayer );
+
+ ///> @copydoc EDA_DRAW_FRAME::UseGalCanvas()
+ virtual void UseGalCanvas( bool aEnable );
+
+ DECLARE_EVENT_TABLE()
+
+protected:
+
+ /// protected so only friend PCB::IFACE::CreateWindow() can act as sole factory.
+ FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );
+
+ PCB_LAYER_WIDGET* m_Layers;
+
+ PARAM_CFG_ARRAY m_configSettings; ///< List of footprint editor configuration settings.
+
+ /**
+ * Function UpdateTitle
+ * updates window title according to getLibNickName().
+ */
+ void updateTitle();
+
+ /// Reloads displayed items and sets view.
+ void updateView();
+
+ /// The libPath is not publicly visible, grab it from the FP_LIB_TABLE if we must.
+ const wxString getLibPath();
+
+ void restoreLastFootprint();
+ void retainLastFootprint();
+
+ /**
+ * Creates a new text for the footprint
+ * @param aModule is the owner of the text
+ * @param aDC is the current DC (can be NULL )
+ * @return a pointer to the new text, or NULL if aborted
+ */
+ TEXTE_MODULE* CreateTextModule( MODULE* aModule, wxDC* aDC );
+
+private:
+
+ /**
+ * Function moveExact
+ * Move the selected item exactly, popping up a dialog to allow the
+ * user the enter the move delta
+ */
+ void moveExact();
+
+ /**
+ * Function duplicateItems
+ * Duplicate the item under the cursor
+ * @param aIncrement increment the number of pad (if that is what is selected)
+ */
+ void duplicateItems( bool aIncrement ); //override
+};
+
+#endif // MODULE_EDITOR_FRAME_H_
diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp
new file mode 100644
index 0000000..b1ff42d
--- /dev/null
+++ b/pcbnew/moduleframe.cpp
@@ -0,0 +1,954 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file moduleframe.cpp
+ * @brief Footprint (module) editor main window.
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiway.h>
+#include <project.h>
+#include <kicad_plugin.h>
+#include <class_drawpanel.h>
+#include <pcb_draw_panel_gal.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <dialog_helpers.h>
+#include <3d_viewer.h>
+#include <msgpanel.h>
+#include <fp_lib_table.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <hotkeys.h>
+#include <dialog_hotkeys_editor.h>
+#include <module_editor_frame.h>
+#include <modview_frame.h>
+#include <wildcards_and_files_ext.h>
+#include <class_pcb_layer_widget.h>
+#include <invoke_pcb_dialog.h>
+
+#include <tool/tool_manager.h>
+#include <tool/tool_dispatcher.h>
+#include "tools/selection_tool.h"
+#include "tools/edit_tool.h"
+#include "tools/drawing_tool.h"
+#include "tools/point_editor.h"
+#include "tools/pcbnew_control.h"
+#include "tools/module_tools.h"
+#include "tools/placement_tool.h"
+#include "tools/picker_tool.h"
+#include "tools/common_actions.h"
+
+
+BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
+ EVT_MENU_RANGE( ID_POPUP_PCB_ITEM_SELECTION_START, ID_POPUP_PCB_ITEM_SELECTION_END,
+ PCB_BASE_FRAME::ProcessItemSelection )
+ EVT_CLOSE( FOOTPRINT_EDIT_FRAME::OnCloseWindow )
+ EVT_MENU( wxID_EXIT, FOOTPRINT_EDIT_FRAME::CloseModuleEditor )
+
+ EVT_SIZE( FOOTPRINT_EDIT_FRAME::OnSize )
+
+ EVT_CHOICE( ID_ON_ZOOM_SELECT, FOOTPRINT_EDIT_FRAME::OnSelectZoom )
+ EVT_CHOICE( ID_ON_GRID_SELECT, FOOTPRINT_EDIT_FRAME::OnSelectGrid )
+
+ EVT_TOOL( ID_MODEDIT_SELECT_CURRENT_LIB, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+
+ EVT_TOOL( ID_MODEDIT_SAVE_LIBRARY_AS, FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs )
+
+ EVT_TOOL( ID_MODEDIT_SAVE_LIBMODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_OPEN_MODULE_VIEWER, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+
+ EVT_TOOL( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_MODEDIT_NEW_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_MODEDIT_NEW_MODULE_FROM_WIZARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_MODEDIT_IMPORT_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_MODEDIT_EXPORT_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
+ FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_MODEDIT_SHEET_SET, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_GEN_IMPORT_DXF_FILE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( wxID_PRINT, FOOTPRINT_EDIT_FRAME::ToPrinter )
+ EVT_TOOL( ID_MODEDIT_LOAD_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_MODEDIT_CHECK, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_MODEDIT_PAD_SETTINGS, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_MODEDIT_LOAD_MODULE_FROM_BOARD, FOOTPRINT_EDIT_FRAME::LoadModuleFromBoard )
+ EVT_TOOL( ID_MODEDIT_INSERT_MODULE_IN_BOARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_MODEDIT_UPDATE_MODULE_IN_BOARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_MODEDIT_EDIT_MODULE_PROPERTIES, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( wxID_UNDO, FOOTPRINT_EDIT_FRAME::RestoreCopyFromUndoList )
+ EVT_TOOL( wxID_REDO, FOOTPRINT_EDIT_FRAME::RestoreCopyFromRedoList )
+
+ // Vertical tool bar button click event handler.
+ EVT_TOOL( ID_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnVerticalToolbar )
+ EVT_TOOL_RANGE( ID_MODEDIT_PAD_TOOL, ID_MODEDIT_PLACE_GRID_COORD,
+ FOOTPRINT_EDIT_FRAME::OnVerticalToolbar )
+
+ // Options Toolbar (ID_TB_OPTIONS_SHOW_PADS_SKETCH id is managed in PCB_BASE_FRAME)
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH, FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH, FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE, FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar )
+
+ // Preferences and option menus
+ EVT_MENU( ID_PREFERENCES_HOTKEY_EXPORT_CONFIG,
+ FOOTPRINT_EDIT_FRAME::ProcessPreferences )
+ EVT_MENU( ID_PREFERENCES_HOTKEY_IMPORT_CONFIG,
+ FOOTPRINT_EDIT_FRAME::ProcessPreferences )
+ EVT_MENU( ID_PREFERENCES_HOTKEY_SHOW_EDITOR,
+ FOOTPRINT_EDIT_FRAME::ProcessPreferences )
+ EVT_MENU( ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST,
+ FOOTPRINT_EDIT_FRAME::ProcessPreferences )
+ EVT_MENU( ID_PCB_LIB_WIZARD,
+ FOOTPRINT_EDIT_FRAME::ProcessPreferences )
+ EVT_MENU( ID_PCB_LIB_TABLE_EDIT,
+ FOOTPRINT_EDIT_FRAME::ProcessPreferences )
+ EVT_MENU( wxID_PREFERENCES,
+ FOOTPRINT_EDIT_FRAME::ProcessPreferences )
+ EVT_MENU( ID_PREFERENCES_CONFIGURE_PATHS, FOOTPRINT_EDIT_FRAME::OnConfigurePaths )
+
+ // popup commands
+ EVT_MENU_RANGE( ID_POPUP_PCB_START_RANGE, ID_POPUP_PCB_END_RANGE,
+ FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+
+ EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE,
+ FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+
+ EVT_MENU( ID_POPUP_MODEDIT_EDIT_BODY_ITEM,
+ FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE,
+ FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE,
+ FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+
+ // Module transformations
+ EVT_MENU( ID_MODEDIT_MODULE_ROTATE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_MODEDIT_MODULE_MIRROR, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_MODEDIT_MODULE_MOVE_EXACT, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+
+ EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_PCB_PAD_SETUP, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_PCB_USER_GRID_SETUP, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+
+ // Menu Help
+ EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_INDEX, EDA_DRAW_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::GetKicadAbout )
+
+ // Menu 3D Frame
+ EVT_MENU( ID_MENU_PCB_SHOW_3D_FRAME, FOOTPRINT_EDIT_FRAME::Show3D_Frame )
+
+ // Switching canvases
+ EVT_MENU( ID_MENU_CANVAS_DEFAULT, PCB_BASE_FRAME::SwitchCanvas )
+ EVT_MENU( ID_MENU_CANVAS_CAIRO, PCB_BASE_FRAME::SwitchCanvas )
+ EVT_MENU( ID_MENU_CANVAS_OPENGL, PCB_BASE_FRAME::SwitchCanvas )
+
+ // UI update events.
+ EVT_UPDATE_UI( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::OnUpdateLibSelected )
+ EVT_UPDATE_UI( ID_MODEDIT_SELECT_CURRENT_LIB, FOOTPRINT_EDIT_FRAME::OnUpdateSelectCurrentLib )
+ EVT_UPDATE_UI( ID_MODEDIT_EXPORT_PART, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
+ EVT_UPDATE_UI( ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
+ FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
+ EVT_UPDATE_UI( ID_MODEDIT_SAVE_LIBMODULE, FOOTPRINT_EDIT_FRAME::OnUpdateLibAndModuleSelected )
+ EVT_UPDATE_UI( ID_MODEDIT_LOAD_MODULE_FROM_BOARD,
+ FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard )
+ EVT_UPDATE_UI( ID_MODEDIT_INSERT_MODULE_IN_BOARD,
+ FOOTPRINT_EDIT_FRAME::OnUpdateInsertModuleInBoard )
+ EVT_UPDATE_UI( ID_MODEDIT_UPDATE_MODULE_IN_BOARD,
+ FOOTPRINT_EDIT_FRAME::OnUpdateReplaceModuleInBoard )
+ EVT_UPDATE_UI( ID_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar )
+
+ EVT_UPDATE_UI_RANGE( ID_MODEDIT_PAD_TOOL, ID_MODEDIT_PLACE_GRID_COORD,
+ FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar )
+
+ // Option toolbar:
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH,
+ FOOTPRINT_EDIT_FRAME::OnUpdateOptionsToolbar )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH,
+ FOOTPRINT_EDIT_FRAME::OnUpdateOptionsToolbar )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE,
+ FOOTPRINT_EDIT_FRAME::OnUpdateOptionsToolbar )
+
+ EVT_UPDATE_UI( ID_GEN_IMPORT_DXF_FILE,
+ FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
+
+END_EVENT_TABLE()
+
+#define FOOTPRINT_EDIT_FRAME_NAME wxT( "ModEditFrame" )
+
+FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
+ PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB_MODULE_EDITOR, wxEmptyString,
+ wxDefaultPosition, wxDefaultSize,
+ KICAD_DEFAULT_DRAWFRAME_STYLE, GetFootprintEditorFrameName() )
+{
+ m_showBorderAndTitleBlock = false; // true to show the frame references
+ m_showAxis = true; // true to show X and Y axis on screen
+ m_showGridAxis = true; // show the grid origin axis
+ m_hotkeysDescrList = g_Module_Editor_Hokeys_Descr;
+
+ // Give an icon
+ wxIcon icon;
+ icon.CopyFromBitmap( KiBitmap( icon_modedit_xpm ) );
+ SetIcon( icon );
+
+ // Show a title (frame title + footprint name):
+ updateTitle();
+
+ // Create GAL canvas
+ PCB_BASE_FRAME* parentFrame = static_cast<PCB_BASE_FRAME*>( Kiway().Player( FRAME_PCB, true ) );
+ PCB_DRAW_PANEL_GAL* drawPanel = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize,
+ parentFrame->GetGalCanvas()->GetBackend() );
+ SetGalCanvas( drawPanel );
+
+ SetBoard( new BOARD() );
+ // In modedit, the default net clearance is not known.
+ // (it depends on the actual board)
+ // So we do not show the default clearance, by setting it to 0
+ // The footprint or pad specific clearance will be shown
+ GetBoard()->GetDesignSettings().GetDefault()->SetClearance( 0 );
+
+ // Don't show the default board solder mask clearance in the footprint editor. Only the
+ // footprint or pad clearance setting should be shown if it is not 0.
+ GetBoard()->GetDesignSettings().m_SolderMaskMargin = 0;
+
+ // restore the last footprint from the project, if any
+ restoreLastFootprint();
+
+ // Ensure all layers and items are visible:
+ // In footprint editor, some layers have no meaning or
+ // cannot be used, but we show all of them, at least to be able
+ // to edit a bad layer
+ GetBoard()->SetVisibleAlls();
+
+ wxFont font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
+ m_Layers = new PCB_LAYER_WIDGET( this, GetCanvas(), font.GetPointSize(), true );
+
+ LoadSettings( config() );
+ SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) );
+ GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
+ GetScreen()->SetCurItem( NULL );
+
+ GetScreen()->AddGrid( m_UserGridSize, m_UserGridUnit, ID_POPUP_GRID_USER );
+ GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
+
+ // In modedit, set the default paper size to A4:
+ // this should be OK for all footprint to plot/print
+ SetPageSettings( PAGE_INFO( PAGE_INFO::A4 ) );
+
+ SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
+ ReCreateMenuBar();
+ ReCreateHToolbar();
+ ReCreateAuxiliaryToolbar();
+ ReCreateVToolbar();
+ ReCreateOptToolbar();
+
+ if( m_canvas )
+ m_canvas->SetEnableBlockCommands( true );
+
+ m_auimgr.SetManagedWindow( this );
+
+ EDA_PANEINFO horiz;
+ horiz.HorizontalToolbarPane();
+
+ EDA_PANEINFO vert;
+ vert.VerticalToolbarPane();
+
+ EDA_PANEINFO mesg_pane;
+ mesg_pane.MessageToolbarPane();
+
+ // Create a wxAuiPaneInfo for the Layers Manager, not derived from the template.
+ // LAYER_WIDGET is floatable, but initially docked at far right
+ EDA_PANEINFO lyrs;
+ lyrs.LayersToolbarPane();
+ lyrs.MinSize( m_Layers->GetBestSize() ); // updated in ReFillLayerWidget
+ lyrs.BestSize( m_Layers->GetBestSize() );
+ lyrs.Caption( _( "Visibles" ) );
+
+ m_auimgr.AddPane( m_mainToolBar,
+ wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top(). Row( 0 ) );
+
+ m_auimgr.AddPane( m_auxiliaryToolBar,
+ wxAuiPaneInfo( horiz ).Name( wxT( "m_auxiliaryToolBar" ) ).Top().Row( 1 ) );
+
+ // The main right vertical toolbar
+ m_auimgr.AddPane( m_drawToolBar,
+ wxAuiPaneInfo( vert ).Name( wxT( "m_VToolBar" ) ).Right().Layer(1) );
+
+ // Add the layer manager ( most right side of pcbframe )
+ m_auimgr.AddPane( m_Layers, lyrs.Name( wxT( "m_LayersManagerToolBar" ) ).Right().Layer( 2 ) );
+ // Layers manager is visible
+ m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( true );
+
+ // The left vertical toolbar (fast acces to display options)
+ m_auimgr.AddPane( m_optionsToolBar,
+ wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ). Left().Layer(1) );
+
+ m_auimgr.AddPane( m_canvas,
+ wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
+ m_auimgr.AddPane( (wxWindow*) GetGalCanvas(),
+ wxAuiPaneInfo().Name( wxT( "DrawFrameGal" ) ).CentrePane().Hide() );
+
+ m_auimgr.AddPane( m_messagePanel,
+ wxAuiPaneInfo( mesg_pane ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );
+
+ // Create the manager and dispatcher & route draw panel events to the dispatcher
+ setupTools();
+ UseGalCanvas( parentFrame->IsGalCanvasActive() );
+
+ if( m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).IsShown() )
+ {
+ m_Layers->ReFill();
+ m_Layers->ReFillRender();
+
+ GetScreen()->m_Active_Layer = F_SilkS;
+ m_Layers->SelectLayer( F_SilkS );
+ m_Layers->OnLayerSelected();
+ }
+
+ m_auimgr.Update();
+
+ Raise(); // On some window managers, this is needed
+ Show( true );
+
+ Zoom_Automatique( false );
+}
+
+
+FOOTPRINT_EDIT_FRAME::~FOOTPRINT_EDIT_FRAME()
+{
+ // save the footprint in the PROJECT
+ retainLastFootprint();
+
+ delete m_Layers;
+}
+
+
+const wxString FOOTPRINT_EDIT_FRAME::getLibPath()
+{
+ try
+ {
+ const wxString& nickname = GetCurrentLib();
+
+ const FP_LIB_TABLE::ROW* row = Prj().PcbFootprintLibs()->FindRow( nickname );
+
+ return row->GetFullURI( true );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ return wxEmptyString;
+ }
+}
+
+
+const wxString FOOTPRINT_EDIT_FRAME::GetCurrentLib() const
+{
+ return Prj().GetRString( PROJECT::PCB_LIB_NICKNAME );
+};
+
+
+void FOOTPRINT_EDIT_FRAME::retainLastFootprint()
+{
+ PCB_IO pcb_io;
+ MODULE* module = GetBoard()->m_Modules;
+
+ if( module )
+ {
+ pcb_io.Format( module );
+
+ wxString pretty = FROM_UTF8( pcb_io.GetStringOutput( true ).c_str() );
+
+ // save the footprint in the RSTRING facility.
+ Prj().SetRString( PROJECT::PCB_FOOTPRINT, pretty );
+ }
+}
+
+
+void FOOTPRINT_EDIT_FRAME::restoreLastFootprint()
+{
+ wxString pretty = Prj().GetRString( PROJECT::PCB_FOOTPRINT );
+
+ if( !!pretty )
+ {
+ PCB_IO pcb_io;
+ MODULE* module = NULL;
+
+ try
+ {
+ module = (MODULE*) pcb_io.Parse( pretty );
+ }
+ catch( const PARSE_ERROR& pe )
+ {
+ // unlikely to be a problem, since we produced the pretty string.
+ wxLogError( wxT( "PARSE_ERROR" ) );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ // unlikely to be a problem, since we produced the pretty string.
+ wxLogError( wxT( "IO_ERROR" ) );
+ }
+
+ if( module )
+ {
+ // assumes BOARD is empty.
+ wxASSERT( GetBoard()->m_Modules == NULL );
+
+ // no idea, its monkey see monkey do. I would encapsulate this into
+ // a member function if its actually necessary.
+ module->SetParent( GetBoard() );
+ module->SetLink( 0 );
+
+ GetBoard()->Add( module );
+ }
+ }
+}
+
+
+const wxChar* FOOTPRINT_EDIT_FRAME::GetFootprintEditorFrameName()
+{
+ return FOOTPRINT_EDIT_FRAME_NAME;
+}
+
+
+BOARD_DESIGN_SETTINGS& FOOTPRINT_EDIT_FRAME::GetDesignSettings() const
+{
+ return GetBoard()->GetDesignSettings();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings )
+{
+ GetBoard()->SetDesignSettings( aSettings );
+}
+
+
+const PCB_PLOT_PARAMS& FOOTPRINT_EDIT_FRAME::GetPlotSettings() const
+{
+ // get the settings from the parent editor, not our BOARD.
+
+ // @todo(DICK) change the routing to some default or the board directly, parent may not exist
+ PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) Kiway().Player( FRAME_PCB, true );
+ wxASSERT( parentFrame );
+
+ return parentFrame->GetPlotSettings();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::SetPlotSettings( const PCB_PLOT_PARAMS& aSettings )
+{
+ // set the settings into parent editor, not our BOARD.
+
+ // @todo(DICK) change the routing to some default or the board directly, parent may not exist
+ PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) Kiway().Player( FRAME_PCB, true );
+ wxASSERT( parentFrame );
+
+ parentFrame->SetPlotSettings( aSettings );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg )
+{
+ PCB_BASE_FRAME::LoadSettings( aCfg );
+ wxConfigLoadSetups( aCfg, GetConfigurationSettings() );
+
+ // Ensure some params are valid
+ BOARD_DESIGN_SETTINGS& settings = GetDesignSettings();
+
+ // Usually, graphic items are drawn on F_SilkS or F_Fab layer
+ // Force these layers if not default
+ if( ( settings.m_RefDefaultlayer != F_SilkS ) && ( settings.m_RefDefaultlayer != F_Fab ) )
+ settings.m_RefDefaultlayer = F_SilkS;
+
+ if( ( settings.m_ValueDefaultlayer != F_SilkS ) && ( settings.m_ValueDefaultlayer != F_Fab ) )
+ settings.m_ValueDefaultlayer = F_Fab;
+}
+
+
+void FOOTPRINT_EDIT_FRAME::SaveSettings( wxConfigBase* aCfg )
+{
+ PCB_BASE_FRAME::SaveSettings( aCfg );
+ wxConfigSaveSetups( aCfg, GetConfigurationSettings() );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
+{
+ if( GetScreen()->IsModify() )
+ {
+ int ii = DisplayExitDialog( this, _( "Save the changes to the footprint before closing?" ) );
+
+ switch( ii )
+ {
+ case wxID_NO:
+ break;
+
+ case wxID_YES:
+ // code from FOOTPRINT_EDIT_FRAME::Process_Special_Functions,
+ // at case ID_MODEDIT_SAVE_LIBMODULE
+ if( GetBoard()->m_Modules && GetCurrentLib().size() )
+ {
+ if( SaveFootprintInLibrary( GetCurrentLib(), GetBoard()->m_Modules, true, true ) )
+ {
+ // save was correct
+ GetScreen()->ClrModify();
+ break;
+ }
+ }
+ else
+ {
+ DisplayError( this, _( "Library is not set, the footprint could not be saved." ) );
+ }
+ // fall through: cancel the close because of an error
+
+ case wxID_CANCEL:
+ Event.Veto();
+ return;
+ }
+ }
+
+ if( IsGalCanvasActive() )
+ GetGalCanvas()->StopDrawing();
+
+ //close the editor
+ Destroy();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::CloseModuleEditor( wxCommandEvent& Event )
+{
+ Close();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Enable( GetBoard()->m_Modules != NULL );
+
+ if( aEvent.GetEventObject() == m_drawToolBar )
+ aEvent.Check( GetToolId() == aEvent.GetId() );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnUpdateOptionsToolbar( wxUpdateUIEvent& aEvent )
+{
+ int id = aEvent.GetId();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ bool state = false;
+
+ switch( id )
+ {
+ case ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH:
+ state = displ_opts->m_DisplayModTextFill == SKETCH;
+ break;
+
+ case ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH:
+ state = displ_opts->m_DisplayModEdgeFill == SKETCH;
+ break;
+
+ case ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE:
+ state = displ_opts->m_ContrastModeDisplay;
+ break;
+
+ default:
+ wxMessageBox( wxT( "FOOTPRINT_EDIT_FRAME::OnUpdateOptionsToolbar error" ) );
+ break;
+ }
+
+ aEvent.Check( state );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnUpdateLibSelected( wxUpdateUIEvent& aEvent )
+{
+ bool enable = getLibPath() != wxEmptyString;
+ aEvent.Enable( enable );
+ GetMenuBar()->Enable( ID_MODEDIT_SAVE_LIBRARY_AS, enable );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Enable( GetBoard()->m_Modules != NULL );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnUpdateLibAndModuleSelected( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Enable( getLibPath() != wxEmptyString && GetBoard()->m_Modules != NULL );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard( wxUpdateUIEvent& aEvent )
+{
+ PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false );
+
+ aEvent.Enable( frame && frame->GetBoard()->m_Modules != NULL );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent )
+{
+ PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false );
+
+ MODULE* module_in_edit = GetBoard()->m_Modules;
+ bool canInsert = frame && module_in_edit && !module_in_edit->GetLink();
+
+ // If the source was deleted, the module can inserted but not updated in the board.
+ if( frame && module_in_edit && module_in_edit->GetLink() ) // this is not a new module
+ {
+ BOARD* mainpcb = frame->GetBoard();
+ MODULE* source_module = mainpcb->m_Modules;
+
+ // search if the source module was not deleted:
+ for( ; source_module != NULL; source_module = source_module->Next() )
+ {
+ if( module_in_edit->GetLink() == source_module->GetTimeStamp() )
+ break;
+ }
+
+ canInsert = ( source_module == NULL );
+ }
+
+ aEvent.Enable( canInsert );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent )
+{
+ PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false );
+
+ MODULE* module_in_edit = GetBoard()->m_Modules;
+ bool canReplace = frame && module_in_edit && module_in_edit->GetLink();
+
+ if( canReplace ) // this is not a new module, but verify if the source is still on board
+ {
+ BOARD* mainpcb = frame->GetBoard();
+ MODULE* source_module = mainpcb->m_Modules;
+
+ // search if the source module was not deleted:
+ for( ; source_module != NULL; source_module = source_module->Next() )
+ {
+ if( module_in_edit->GetLink() == source_module->GetTimeStamp() )
+ break;
+ }
+
+ canReplace = ( source_module != NULL );
+ }
+
+ aEvent.Enable( canReplace );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnUpdateSelectCurrentLib( wxUpdateUIEvent& aEvent )
+{
+ FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();
+
+ aEvent.Enable( fptbl && !fptbl->IsEmpty() );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::Show3D_Frame( wxCommandEvent& event )
+{
+ if( m_Draw3DFrame )
+ {
+ // Raising the window does not show the window on Windows if iconized.
+ // This should work on any platform.
+ if( m_Draw3DFrame->IsIconized() )
+ m_Draw3DFrame->Iconize( false );
+
+ m_Draw3DFrame->Raise();
+
+ // Raising the window does not set the focus on Linux. This should work on any platform.
+ if( wxWindow::FindFocus() != m_Draw3DFrame )
+ m_Draw3DFrame->SetFocus();
+
+ return;
+ }
+
+ m_Draw3DFrame = new EDA_3D_FRAME( &Kiway(), this, _( "3D Viewer" ) );
+ m_Draw3DFrame->Raise(); // Needed with some Window Managers
+ m_Draw3DFrame->Show( true );
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
+{
+ bool eventHandled = true;
+
+ // Filter out the 'fake' mouse motion after a keyboard movement
+ if( !aHotKey && m_movingCursorWithKeyboard )
+ {
+ m_movingCursorWithKeyboard = false;
+ return false;
+ }
+
+ // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
+ // for next cursor position
+ // ( shift or ctrl key down are PAN command with mouse wheel)
+ bool snapToGrid = true;
+
+ if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
+ snapToGrid = false;
+
+ wxPoint oldpos = GetCrossHairPosition();
+ wxPoint pos = aPosition;
+ GeneralControlKeyMovement( aHotKey, &pos, snapToGrid );
+
+ SetCrossHairPosition( pos, snapToGrid );
+ RefreshCrossHair( oldpos, aPosition, aDC );
+
+ if( aHotKey )
+ {
+ eventHandled = OnHotKey( aDC, aHotKey, aPosition );
+ }
+
+ UpdateStatusBar();
+
+ return eventHandled;
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnModify()
+{
+ PCB_BASE_FRAME::OnModify();
+
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->ReloadRequest();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::updateTitle()
+{
+ wxString title = _( "Footprint Editor " );
+
+ wxString nickname = GetCurrentLib();
+
+ if( !nickname )
+ {
+ L_none:
+ title += _( "(no active library)" );
+ }
+ else
+ {
+ try
+ {
+ bool writable = Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname );
+
+ // no exception was thrown, this means libPath is valid, but it may be read only.
+ title = _( "Footprint Editor (active library: " ) + nickname + wxT( ")" );
+
+ if( !writable )
+ title += _( " [Read Only]" );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ // user may be bewildered as to why after selecting a library it is not showing up
+ // in the title, we could show an error message, but that should have been done at time
+ // of libary selection UI.
+ goto L_none;
+ }
+ }
+
+ SetTitle( title );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::updateView()
+{
+ static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() )->DisplayBoard( GetBoard() );
+ m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
+ m_toolManager->RunAction( COMMON_ACTIONS::zoomFitScreen, true );
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::IsGridVisible() const
+{
+ return IsElementVisible( GRID_VISIBLE );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::SetGridVisibility(bool aVisible)
+{
+ SetElementVisibility( GRID_VISIBLE, aVisible );
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::IsElementVisible( int aElement ) const
+{
+ return GetBoard()->IsElementVisible( aElement );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::SetElementVisibility( int aElement, bool aNewState )
+{
+ GetGalCanvas()->GetView()->SetLayerVisible( ITEM_GAL_LAYER( aElement ), aNewState );
+ GetBoard()->SetElementVisibility( aElement, aNewState );
+ m_Layers->SetRenderState( aElement, aNewState );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::ProcessPreferences( wxCommandEvent& event )
+{
+ int id = event.GetId();
+
+ switch( id )
+ {
+ // Hotkey IDs
+ case ID_PREFERENCES_HOTKEY_EXPORT_CONFIG:
+ ExportHotkeyConfigToFile( g_Module_Editor_Hokeys_Descr, wxT( "pcbnew" ) );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_IMPORT_CONFIG:
+ ImportHotkeyConfigFromFile( g_Module_Editor_Hokeys_Descr, wxT( "pcbnew" ) );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_SHOW_EDITOR:
+ InstallHotkeyFrame( this, g_Module_Editor_Hokeys_Descr );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST:
+ // Display current hotkey list for the footprint editor.
+ DisplayHotkeyList( this, g_Module_Editor_Hokeys_Descr );
+ break;
+
+ case ID_PCB_LIB_WIZARD:
+ case ID_PCB_LIB_TABLE_EDIT:
+ {
+ bool tableChanged = false;
+ int r = 0;
+
+ if( id == ID_PCB_LIB_TABLE_EDIT )
+ r = InvokePcbLibTableEditor( this, &GFootprintTable, Prj().PcbFootprintLibs() );
+ else
+ r = InvokeFootprintWizard( this, &GFootprintTable, Prj().PcbFootprintLibs() );
+
+ if( r & 1 )
+ {
+ try
+ {
+ FILE_OUTPUTFORMATTER sf( FP_LIB_TABLE::GetGlobalTableFileName() );
+
+ GFootprintTable.Format( &sf, 0 );
+ tableChanged = true;
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _(
+ "Error occurred saving the global footprint library "
+ "table:\n\n%s" ),
+ GetChars( ioe.errorText.GetData() )
+ );
+ wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
+ }
+ }
+
+ if( r & 2 )
+ {
+ wxString tblName = Prj().FootprintLibTblName();
+
+ try
+ {
+ Prj().PcbFootprintLibs()->Save( tblName );
+ tableChanged = true;
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _(
+ "Error occurred saving project specific footprint library "
+ "table:\n\n%s" ),
+ GetChars( ioe.errorText )
+ );
+ wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
+ }
+ }
+
+ FOOTPRINT_VIEWER_FRAME* viewer;
+ viewer = (FOOTPRINT_VIEWER_FRAME*)Kiway().Player( FRAME_PCB_MODULE_VIEWER, false );
+
+ if( tableChanged && viewer != NULL )
+ viewer->ReCreateLibraryList();
+ }
+ break;
+
+ case wxID_PREFERENCES:
+ InvokeFPEditorPrefsDlg( this );
+ break;
+
+ default:
+ DisplayError( this, wxT( "FOOTPRINT_EDIT_FRAME::ProcessPreferences error" ) );
+ }
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnConfigurePaths( wxCommandEvent& aEvent )
+{
+ Pgm().ConfigurePaths( this );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::setupTools()
+{
+ PCB_DRAW_PANEL_GAL* drawPanel = static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() );
+
+ // Create the manager and dispatcher & route draw panel events to the dispatcher
+ m_toolManager = new TOOL_MANAGER;
+ m_toolManager->SetEnvironment( GetBoard(), drawPanel->GetView(),
+ drawPanel->GetViewControls(), this );
+ m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
+
+ drawPanel->SetEventDispatcher( m_toolDispatcher );
+
+ m_toolManager->RegisterTool( new SELECTION_TOOL );
+ m_toolManager->RegisterTool( new EDIT_TOOL );
+ m_toolManager->RegisterTool( new DRAWING_TOOL );
+ m_toolManager->RegisterTool( new POINT_EDITOR );
+ m_toolManager->RegisterTool( new PCBNEW_CONTROL );
+ m_toolManager->RegisterTool( new MODULE_TOOLS );
+ m_toolManager->RegisterTool( new PLACEMENT_TOOL );
+ m_toolManager->RegisterTool( new PICKER_TOOL );
+
+ m_toolManager->GetTool<SELECTION_TOOL>()->EditModules( true );
+ m_toolManager->GetTool<EDIT_TOOL>()->EditModules( true );
+ m_toolManager->GetTool<DRAWING_TOOL>()->EditModules( true );
+
+ m_toolManager->ResetTools( TOOL_BASE::RUN );
+ m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" );
+
+}
+
+
+void FOOTPRINT_EDIT_FRAME::UseGalCanvas( bool aEnable )
+{
+ PCB_BASE_EDIT_FRAME::UseGalCanvas( aEnable );
+
+ if( aEnable )
+ updateView();
+}
diff --git a/pcbnew/modules.cpp b/pcbnew/modules.cpp
new file mode 100644
index 0000000..cb83e39
--- /dev/null
+++ b/pcbnew/modules.cpp
@@ -0,0 +1,512 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file modules.cpp
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <trigo.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <pcbnew.h>
+#include <drag.h>
+
+
+static void MoveFootprint( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase );
+static void Abort_MoveOrCopyModule( EDA_DRAW_PANEL* Panel, wxDC* DC );
+
+
+static MODULE* s_ModuleInitialCopy = NULL; /* Copy of module for
+ * abort/undo command
+ */
+static PICKED_ITEMS_LIST s_PickedList; /* a picked list to
+ * save initial module
+ * and dragged tracks
+ */
+
+/* Get a module name from user and return a pointer to the corresponding module
+ */
+MODULE* PCB_BASE_FRAME::GetModuleByName()
+{
+ wxString moduleName;
+ MODULE* module = NULL;
+
+ wxTextEntryDialog dlg( this, _( "Reference:" ), _( "Search for footprint" ), moduleName );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return NULL; //Aborted by user
+
+ moduleName = dlg.GetValue();
+ moduleName.Trim( true );
+ moduleName.Trim( false );
+
+ if( !moduleName.IsEmpty() )
+ {
+ module = GetBoard()->m_Modules;
+
+ while( module )
+ {
+ if( module->GetReference().CmpNoCase( moduleName ) == 0 )
+ break;
+
+ module = module->Next();
+ }
+ }
+
+ return module;
+}
+
+
+void PCB_EDIT_FRAME::StartMoveModule( MODULE* aModule, wxDC* aDC,
+ bool aDragConnectedTracks )
+{
+ if( aModule == NULL )
+ return;
+
+ if( s_ModuleInitialCopy )
+ delete s_ModuleInitialCopy;
+
+ s_PickedList.ClearItemsList(); // Should be empty, but...
+
+ // Creates a copy of the current module, for abort and undo commands
+ s_ModuleInitialCopy = (MODULE*)aModule->Clone();
+ s_ModuleInitialCopy->SetParent( GetBoard() );
+ s_ModuleInitialCopy->ClearFlags();
+
+ SetCurItem( aModule );
+ GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK;
+ aModule->SetFlags( IS_MOVED );
+
+ /* Show ratsnest. */
+ if( GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) )
+ DrawGeneralRatsnest( aDC );
+
+ EraseDragList();
+
+ if( aDragConnectedTracks )
+ {
+ DRAG_LIST drglist( GetBoard() );
+ drglist.BuildDragListe( aModule );
+
+ ITEM_PICKER itemWrapper( NULL, UR_CHANGED );
+
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ TRACK* segm = g_DragSegmentList[ii].m_Track;
+ itemWrapper.SetItem( segm );
+ itemWrapper.SetLink( segm->Clone() );
+ itemWrapper.GetLink()->SetState( IN_EDIT, false );
+ s_PickedList.PushItem( itemWrapper );
+ }
+
+ UndrawAndMarkSegmentsToDrag( m_canvas, aDC );
+ }
+
+ GetBoard()->m_Status_Pcb |= DO_NOT_SHOW_GENERAL_RASTNEST;
+ m_canvas->SetMouseCapture( MoveFootprint, Abort_MoveOrCopyModule );
+ m_canvas->SetAutoPanRequest( true );
+
+ // Erase the module.
+ if( aDC )
+ {
+ aModule->SetFlags( DO_NOT_DRAW );
+ m_canvas->RefreshDrawingRect( aModule->GetBoundingBox() );
+ aModule->ClearFlags( DO_NOT_DRAW );
+ }
+
+ m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
+}
+
+
+/* Called on a move or copy module command abort
+ */
+void Abort_MoveOrCopyModule( EDA_DRAW_PANEL* Panel, wxDC* DC )
+{
+ TRACK* pt_segm;
+ MODULE* module;
+ PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Panel->GetParent();
+
+ module = (MODULE*) pcbframe->GetScreen()->GetCurItem();
+ pcbframe->GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK;
+ Panel->SetMouseCapture( NULL, NULL );
+
+ if( module )
+ {
+ // Erase the current footprint on screen
+ module->DrawOutlinesWhenMoving( Panel, DC, g_Offset_Module );
+
+ /* If a move command: return to old position
+ * If a copy command, delete the new footprint
+ */
+ if( module->IsMoving() )
+ {
+ /* Restore old position for dragged tracks */
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ pt_segm = g_DragSegmentList[ii].m_Track;
+ pt_segm->Draw( Panel, DC, GR_XOR );
+ pt_segm->SetState( IN_EDIT, false );
+ pt_segm->ClearFlags();
+ g_DragSegmentList[ii].RestoreInitialValues();
+ pt_segm->Draw( Panel, DC, GR_OR );
+ }
+
+ EraseDragList();
+ module->ClearFlags( IS_MOVED );
+ }
+
+ if( module->IsNew() ) // Copy command: delete new footprint
+ {
+ module->DeleteStructure();
+ module = NULL;
+ pcbframe->GetBoard()->m_Status_Pcb = 0;
+ pcbframe->GetBoard()->BuildListOfNets();
+ }
+ }
+
+ /* Redraw the module. */
+ if( module && s_ModuleInitialCopy )
+ {
+ if( s_ModuleInitialCopy->GetOrientation() != module->GetOrientation() )
+ pcbframe->Rotate_Module( NULL, module, s_ModuleInitialCopy->GetOrientation(), false );
+
+ if( s_ModuleInitialCopy->GetLayer() != module->GetLayer() )
+ pcbframe->Change_Side_Module( module, NULL );
+
+ module->Draw( Panel, DC, GR_OR );
+ }
+
+ pcbframe->SetCurItem( NULL );
+
+ delete s_ModuleInitialCopy;
+ s_ModuleInitialCopy = NULL;
+ s_PickedList.ClearListAndDeleteItems();
+
+ // Display ratsnest is allowed
+ pcbframe->GetBoard()->m_Status_Pcb &= ~DO_NOT_SHOW_GENERAL_RASTNEST;
+
+ if( pcbframe->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) )
+ pcbframe->DrawGeneralRatsnest( DC );
+
+#ifdef __WXMAC__
+ Panel->Refresh();
+#endif
+}
+
+
+/* Redraw the footprint when moving the mouse.
+ */
+void MoveFootprint( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, bool aErase )
+{
+ MODULE* module = (MODULE*) aPanel->GetScreen()->GetCurItem();
+
+ if( module == NULL )
+ return;
+
+ /* Erase current footprint. */
+ if( aErase )
+ {
+ module->DrawOutlinesWhenMoving( aPanel, aDC, g_Offset_Module );
+ }
+
+ /* Redraw the module at the new position. */
+ g_Offset_Module = module->GetPosition() - aPanel->GetParent()->GetCrossHairPosition();
+ module->DrawOutlinesWhenMoving( aPanel, aDC, g_Offset_Module );
+
+ DrawSegmentWhileMovingFootprint( aPanel, aDC );
+}
+
+
+bool PCB_EDIT_FRAME::Delete_Module( MODULE* aModule, wxDC* aDC )
+{
+ wxString msg;
+
+ if( aModule == NULL )
+ return false;
+
+ SetMsgPanel( aModule );
+
+ /* Remove module from list, and put it in undo command list */
+ m_Pcb->m_Modules.Remove( aModule );
+ aModule->SetState( IS_DELETED, true );
+ SaveCopyInUndoList( aModule, UR_DELETED );
+
+ if( aDC && GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) )
+ Compile_Ratsnest( aDC, true );
+
+ // Redraw the full screen to ensure perfect display of board and ratsnest.
+ if( aDC )
+ m_canvas->Refresh();
+
+ OnModify();
+
+ return true;
+}
+
+
+void PCB_EDIT_FRAME::Change_Side_Module( MODULE* Module, wxDC* DC )
+{
+ if( Module == NULL )
+ return;
+
+ if( ( Module->GetLayer() != F_Cu ) && ( Module->GetLayer() != B_Cu ) )
+ return;
+
+ OnModify();
+
+ if( !Module->IsMoving() ) /* This is a simple flip, no other edition in progress */
+ {
+ GetBoard()->m_Status_Pcb &= ~( LISTE_RATSNEST_ITEM_OK | CONNEXION_OK );
+
+ if( DC )
+ {
+ Module->SetFlags( DO_NOT_DRAW );
+ m_canvas->RefreshDrawingRect( Module->GetBoundingBox() );
+ Module->ClearFlags( DO_NOT_DRAW );
+ }
+
+ /* Show ratsnest if necessary. */
+ if( DC && GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) )
+ DrawGeneralRatsnest( DC );
+
+ g_Offset_Module.x = 0;
+ g_Offset_Module.y = 0;
+ }
+ else // Module is being moved.
+ {
+ /* Erase footprint and draw outline if it has been already drawn. */
+ if( DC )
+ {
+ Module->DrawOutlinesWhenMoving( m_canvas, DC, g_Offset_Module );
+ DrawSegmentWhileMovingFootprint( m_canvas, DC );
+ }
+ }
+
+ /* Flip the module */
+ Module->Flip( Module->GetPosition() );
+
+ SetMsgPanel( Module );
+
+ if( !Module->IsMoving() ) /* Inversion simple */
+ {
+ if( DC )
+ {
+ Module->Draw( m_canvas, DC, GR_OR );
+
+ if( GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) )
+ Compile_Ratsnest( DC, true );
+ }
+ }
+ else
+ {
+ if( DC )
+ {
+ Module->DrawOutlinesWhenMoving( m_canvas, DC, g_Offset_Module );
+ DrawSegmentWhileMovingFootprint( m_canvas, DC );
+ }
+
+ GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK;
+ }
+}
+
+
+void PCB_BASE_FRAME::PlaceModule( MODULE* aModule, wxDC* aDC, bool aDoNotRecreateRatsnest )
+{
+ wxPoint newpos;
+
+ if( aModule == 0 )
+ return;
+
+ OnModify();
+ GetBoard()->m_Status_Pcb &= ~( LISTE_RATSNEST_ITEM_OK | CONNEXION_OK);
+
+ if( aModule->IsNew() )
+ {
+ SaveCopyInUndoList( aModule, UR_NEW );
+ }
+ else if( aModule->IsMoving() )
+ {
+ ITEM_PICKER picker( aModule, UR_CHANGED );
+ picker.SetLink( s_ModuleInitialCopy );
+ s_PickedList.PushItem( picker );
+ s_ModuleInitialCopy = NULL; // the picker is now owner of s_ModuleInitialCopy.
+ }
+
+ if( s_PickedList.GetCount() )
+ {
+ SaveCopyInUndoList( s_PickedList, UR_UNSPECIFIED );
+
+ // Clear list, but DO NOT delete items, because they are owned by the saved undo
+ // list and they therefore in use
+ s_PickedList.ClearItemsList();
+ }
+
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ if( displ_opts->m_Show_Module_Ratsnest && ( GetBoard()->m_Status_Pcb & LISTE_PAD_OK ) && aDC )
+ TraceModuleRatsNest( aDC );
+
+ newpos = GetCrossHairPosition();
+ aModule->SetPosition( newpos );
+ aModule->ClearFlags();
+
+ delete s_ModuleInitialCopy;
+ s_ModuleInitialCopy = NULL;
+
+ if( aDC )
+ aModule->Draw( m_canvas, aDC, GR_OR );
+
+ // Redraw dragged track segments, if any
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ TRACK * track = g_DragSegmentList[ii].m_Track;
+ track->SetState( IN_EDIT, false );
+ track->ClearFlags();
+
+ if( aDC )
+ track->Draw( m_canvas, aDC, GR_OR );
+ }
+
+ // Delete drag list
+ EraseDragList();
+
+ m_canvas->SetMouseCapture( NULL, NULL );
+
+ if( GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) && !aDoNotRecreateRatsnest )
+ Compile_Ratsnest( aDC, true );
+
+ if( aDC )
+ m_canvas->Refresh();
+
+ SetMsgPanel( aModule );
+}
+
+
+/*
+ * Rotate the footprint angle degrees in the direction < 0.
+ * If incremental == true, the rotation is made from the last orientation,
+ * If the module is placed in the absolute orientation angle.
+ * If DC == NULL, the component does not redraw.
+ * Otherwise, it erases and redraws turns
+ */
+void PCB_BASE_FRAME::Rotate_Module( wxDC* DC, MODULE* module, double angle, bool incremental )
+{
+ if( module == NULL )
+ return;
+
+ OnModify();
+
+ if( !module->IsMoving() ) /* This is a simple rotation, no other
+ * edition in progress */
+ {
+ if( DC ) // Erase footprint to screen
+ {
+ module->SetFlags( DO_NOT_DRAW );
+ m_canvas->RefreshDrawingRect( module->GetBoundingBox() );
+ module->ClearFlags( DO_NOT_DRAW );
+
+ if( GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) )
+ DrawGeneralRatsnest( DC );
+ }
+ }
+ else
+ {
+ if( DC )
+ {
+ module->DrawOutlinesWhenMoving( m_canvas, DC, g_Offset_Module );
+ DrawSegmentWhileMovingFootprint( m_canvas, DC );
+ }
+ }
+
+ GetBoard()->m_Status_Pcb &= ~( LISTE_RATSNEST_ITEM_OK | CONNEXION_OK );
+
+ if( incremental )
+ module->SetOrientation( module->GetOrientation() + angle );
+ else
+ module->SetOrientation( angle );
+
+ SetMsgPanel( module );
+
+ if( DC )
+ {
+ if( !module->IsMoving() )
+ {
+ // not beiing moved: redraw the module and update ratsnest
+ module->Draw( m_canvas, DC, GR_OR );
+
+ if( GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) )
+ Compile_Ratsnest( DC, true );
+ }
+ else
+ {
+ // Beiing moved: just redraw it
+ module->DrawOutlinesWhenMoving( m_canvas, DC, g_Offset_Module );
+ DrawSegmentWhileMovingFootprint( m_canvas, DC );
+ }
+
+ if( module->GetFlags() == 0 ) // module not in edit: redraw full screen
+ m_canvas->Refresh();
+ }
+}
+
+
+// Redraw in XOR mode the outlines of the module.
+void MODULE::DrawOutlinesWhenMoving( EDA_DRAW_PANEL* panel, wxDC* DC,
+ const wxPoint& aMoveVector )
+{
+ int pad_fill_tmp;
+ D_PAD* pt_pad;
+
+ DrawEdgesOnly( panel, DC, aMoveVector, GR_XOR );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
+
+ // Show pads in sketch mode to speedu up drawings
+ pad_fill_tmp = displ_opts->m_DisplayPadFill;
+ displ_opts->m_DisplayPadFill = true;
+
+ pt_pad = Pads();
+
+ for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
+ pt_pad->Draw( panel, DC, GR_XOR, aMoveVector );
+
+ displ_opts->m_DisplayPadFill = pad_fill_tmp;
+
+ if( displ_opts->m_Show_Module_Ratsnest )
+ {
+ PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) panel->GetParent();
+ frame->build_ratsnest_module( this );
+ frame->TraceModuleRatsNest( DC );
+ }
+}
diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp
new file mode 100644
index 0000000..ee88cc6
--- /dev/null
+++ b/pcbnew/modview_frame.cpp
@@ -0,0 +1,863 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file modview_frame.cpp
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiway.h>
+#include <class_drawpanel.h>
+#include <pcb_draw_panel_gal.h>
+#include <wxPcbStruct.h>
+#include <3d_viewer.h>
+#include <dialog_helpers.h>
+#include <msgpanel.h>
+#include <fp_lib_table.h>
+#include <fpid.h>
+#include <confirm.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <modview_frame.h>
+#include <footprint_info.h>
+
+#include <hotkeys.h>
+#include <wildcards_and_files_ext.h>
+#include <pcbnew_config.h>
+
+#include <tool/tool_manager.h>
+#include <tool/tool_dispatcher.h>
+#include "tools/pcbnew_control.h"
+#include "tools/common_actions.h"
+
+#include <boost/bind.hpp>
+
+
+#define NEXT_PART 1
+#define NEW_PART 0
+#define PREVIOUS_PART -1
+
+
+BEGIN_EVENT_TABLE( FOOTPRINT_VIEWER_FRAME, EDA_DRAW_FRAME )
+ // Window events
+ EVT_CLOSE( FOOTPRINT_VIEWER_FRAME::OnCloseWindow )
+ EVT_SIZE( FOOTPRINT_VIEWER_FRAME::OnSize )
+ EVT_ACTIVATE( FOOTPRINT_VIEWER_FRAME::OnActivate )
+
+ // Menu (and/or hotkey) events
+ EVT_MENU( wxID_EXIT, FOOTPRINT_VIEWER_FRAME::CloseFootprintViewer )
+ EVT_MENU( ID_SET_RELATIVE_OFFSET, FOOTPRINT_VIEWER_FRAME::OnSetRelativeOffset )
+
+ // Toolbar events
+ EVT_TOOL( ID_MODVIEW_SELECT_LIB,
+ FOOTPRINT_VIEWER_FRAME::SelectCurrentLibrary )
+ EVT_TOOL( ID_MODVIEW_SELECT_PART,
+ FOOTPRINT_VIEWER_FRAME::SelectCurrentFootprint )
+ EVT_TOOL( ID_MODVIEW_NEXT,
+ FOOTPRINT_VIEWER_FRAME::OnIterateFootprintList )
+ EVT_TOOL( ID_MODVIEW_PREVIOUS,
+ FOOTPRINT_VIEWER_FRAME::OnIterateFootprintList )
+ EVT_TOOL( ID_MODVIEW_FOOTPRINT_EXPORT_TO_BOARD,
+ FOOTPRINT_VIEWER_FRAME::ExportSelectedFootprint )
+ EVT_TOOL( ID_MODVIEW_SHOW_3D_VIEW, FOOTPRINT_VIEWER_FRAME::Show3D_Frame )
+
+ // listbox events
+ EVT_LISTBOX( ID_MODVIEW_LIB_LIST, FOOTPRINT_VIEWER_FRAME::ClickOnLibList )
+ EVT_LISTBOX( ID_MODVIEW_FOOTPRINT_LIST, FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList )
+ EVT_LISTBOX_DCLICK( ID_MODVIEW_FOOTPRINT_LIST, FOOTPRINT_VIEWER_FRAME::DClickOnFootprintList )
+
+END_EVENT_TABLE()
+
+
+/* Note:
+ * FOOTPRINT_VIEWER_FRAME can be build in "modal mode", or as a usual frame.
+ * In modal mode:
+ * a tool to export the selected footprint is shown in the toolbar
+ * the style is wxSTAY_ON_TOP on Windows and wxFRAME_FLOAT_ON_PARENT on unix
+ * reason:
+ * the parent is usually the kicad window manager (not easy to change)
+ * On windows, when the frame with stype wxFRAME_FLOAT_ON_PARENT is displayed
+ * its parent frame is brought to the foreground, on the top of the calling frame.
+ * and stays displayed when closing the FOOTPRINT_VIEWER_FRAME frame.
+ * this issue does not happen on unix
+ *
+ * So we use wxSTAY_ON_TOP on Windows, and wxFRAME_FLOAT_ON_PARENT on unix
+ * to simulate a dialog called by ShowModal.
+ */
+
+
+#define FOOTPRINT_VIEWER_FRAME_NAME wxT( "ModViewFrame" )
+
+
+FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType ) :
+ PCB_BASE_FRAME( aKiway, aParent, aFrameType, _( "Footprint Library Browser" ),
+ wxDefaultPosition, wxDefaultSize,
+ aFrameType == FRAME_PCB_MODULE_VIEWER_MODAL ?
+#ifdef __WINDOWS__
+ KICAD_DEFAULT_DRAWFRAME_STYLE | wxSTAY_ON_TOP :
+#else
+ KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT :
+#endif
+ KICAD_DEFAULT_DRAWFRAME_STYLE,
+ FOOTPRINT_VIEWER_FRAME_NAME )
+{
+ wxASSERT( aFrameType==FRAME_PCB_MODULE_VIEWER || aFrameType==FRAME_PCB_MODULE_VIEWER_MODAL );
+
+ if( aFrameType == FRAME_PCB_MODULE_VIEWER_MODAL )
+ SetModal( true );
+
+ m_configFrameName = FOOTPRINT_VIEWER_FRAME_NAME;
+ m_showAxis = true; // true to draw axis.
+
+ // Give an icon
+ wxIcon icon;
+ icon.CopyFromBitmap( KiBitmap( modview_icon_xpm ) );
+ SetIcon( icon );
+
+ m_hotkeysDescrList = g_Module_Viewer_Hokeys_Descr;
+
+ m_libList = new wxListBox( this, ID_MODVIEW_LIB_LIST,
+ wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL );
+
+ m_footprintList = new wxListBox( this, ID_MODVIEW_FOOTPRINT_LIST,
+ wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL );
+
+ SetBoard( new BOARD() );
+ // In viewer, the default net clearance is not known (it depends on the actual board).
+ // So we do not show the default clearance, by setting it to 0
+ // The footprint or pad specific clearance will be shown
+ GetBoard()->GetDesignSettings().GetDefault()->SetClearance(0);
+
+ // Ensure all layers and items are visible:
+ GetBoard()->SetVisibleAlls();
+ SetScreen( new PCB_SCREEN( GetPageSizeIU() ) );
+
+ GetScreen()->m_Center = true; // Center coordinate origins on screen.
+ LoadSettings( config() );
+
+ SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
+
+ GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
+
+ // Menu bar is not mandatory: uncomment/comment the next line
+ // to add/remove the menubar
+ ReCreateMenuBar();
+ ReCreateHToolbar();
+ ReCreateVToolbar();
+
+ ReCreateLibraryList();
+ UpdateTitle();
+
+ PCB_BASE_FRAME* parentFrame = static_cast<PCB_BASE_FRAME*>( Kiway().Player( FRAME_PCB, true ) );
+
+ // Create GAL canvas
+ PCB_DRAW_PANEL_GAL* drawPanel = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize,
+ parentFrame->GetGalCanvas()->GetBackend() );
+ SetGalCanvas( drawPanel );
+
+ // Create the manager and dispatcher & route draw panel events to the dispatcher
+ m_toolManager = new TOOL_MANAGER;
+ m_toolManager->SetEnvironment( GetBoard(), drawPanel->GetView(),
+ drawPanel->GetViewControls(), this );
+ m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
+ drawPanel->SetEventDispatcher( m_toolDispatcher );
+
+ m_toolManager->RegisterTool( new PCBNEW_CONTROL );
+ m_toolManager->ResetTools( TOOL_BASE::RUN );
+
+ // If a footprint was previously loaded, reload it
+ if( getCurNickname().size() && getCurFootprintName().size() )
+ {
+ FPID id;
+
+ id.SetLibNickname( getCurNickname() );
+ id.SetFootprintName( getCurFootprintName() );
+ GetBoard()->Add( loadFootprint( id ) );
+ }
+
+ drawPanel->DisplayBoard( m_Pcb );
+ updateView();
+
+ m_auimgr.SetManagedWindow( this );
+
+ wxSize minsize(100,-1); // Min size of list boxes
+
+ // Main toolbar is initially docked at the top of the main window and dockable on any side.
+ // The close button is disable because the footprint viewer has no main menu to re-enable it.
+ // The tool bar will only be dockable on the top or bottom of the main frame window. This is
+ // most likely due to the fact that the other windows are not dockable and are preventing the
+ // tool bar from docking on the right and left.
+ wxAuiPaneInfo toolbarPaneInfo;
+ toolbarPaneInfo.Name( wxT( "m_mainToolBar" ) ).ToolbarPane().Top().CloseButton( false );
+
+ EDA_PANEINFO info;
+ info.InfoToolbarPane();
+
+ EDA_PANEINFO mesg;
+ mesg.MessageToolbarPane();
+
+ // Manage main toolbar, top pane
+ m_auimgr.AddPane( m_mainToolBar, toolbarPaneInfo );
+
+ // Manage the list of libraries, left pane.
+ m_auimgr.AddPane( m_libList,
+ wxAuiPaneInfo( info ).Name( wxT( "m_libList" ) )
+ .Left().Row( 1 ).MinSize( minsize ) );
+
+ // Manage the list of footprints, center pane.
+ m_auimgr.AddPane( m_footprintList,
+ wxAuiPaneInfo( info ).Name( wxT( "m_footprintList" ) )
+ .Left().Row( 2 ).MinSize( minsize ) );
+
+ // Manage the draw panel, right pane.
+ m_auimgr.AddPane( m_canvas,
+ wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
+ m_auimgr.AddPane( (wxWindow*) GetGalCanvas(),
+ wxAuiPaneInfo().Name( wxT( "DrawFrameGal" ) ).CentrePane().Hide() );
+
+ // Manage the message panel, bottom pane.
+ m_auimgr.AddPane( m_messagePanel,
+ wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom() );
+
+ if( !m_perspective.IsEmpty() )
+ {
+ // Restore last saved sizes, pos and other params
+ // However m_mainToolBar size cannot be set to its last saved size
+ // because the actual size change depending on the way modview was called:
+ // the tool to export the current footprint exist or not.
+ // and the saved size is not always OK
+ // the trick is to get the default toolbar size, and set the size after
+ // calling LoadPerspective
+ wxSize tbsize = m_mainToolBar->GetSize();
+ m_auimgr.LoadPerspective( m_perspective, false );
+ m_auimgr.GetPane( m_mainToolBar ).BestSize( tbsize );
+ }
+
+ // after changing something to the aui manager,
+ // call Update()() to reflect the changes
+ m_auimgr.Update();
+
+ // Now Drawpanel is sized, we can use BestZoom to show the component (if any)
+#ifdef USE_WX_GRAPHICS_CONTEXT
+ GetScreen()->SetZoom( BestZoom() );
+#else
+ Zoom_Automatique( false );
+#endif
+
+ UseGalCanvas( parentFrame->IsGalCanvasActive() );
+
+ if( !IsModal() ) // For modal mode, calling ShowModal() will show this frame
+ {
+ Raise(); // On some window managers, this is needed
+ Show( true );
+ }
+}
+
+
+FOOTPRINT_VIEWER_FRAME::~FOOTPRINT_VIEWER_FRAME()
+{
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->Destroy();
+}
+
+
+
+void FOOTPRINT_VIEWER_FRAME::OnCloseWindow( wxCloseEvent& Event )
+{
+ DBG(printf( "%s:\n", __func__ );)
+
+ if( IsGalCanvasActive() )
+ GetGalCanvas()->StopDrawing();
+
+ if( IsModal() )
+ {
+ // Only dismiss a modal frame once, so that the return values set by
+ // the prior DismissModal() are not bashed for ShowModal().
+ if( !IsDismissed() )
+ DismissModal( false );
+
+ // window to be destroyed by the caller of KIWAY_PLAYER::ShowModal()
+ }
+ else
+ Destroy();
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::OnSize( wxSizeEvent& SizeEv )
+{
+ if( m_auimgr.GetManagedWindow() )
+ m_auimgr.Update();
+
+ SizeEv.Skip();
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::OnSetRelativeOffset( wxCommandEvent& event )
+{
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ UpdateStatusBar();
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
+{
+ m_libList->Clear();
+
+ std::vector< wxString > nicknames = Prj().PcbFootprintLibs()->GetLogicalLibs();
+
+ for( unsigned ii = 0; ii < nicknames.size(); ii++ )
+ m_libList->Append( nicknames[ii] );
+
+ // Search for a previous selection:
+ int index = m_libList->FindString( getCurNickname() );
+
+ if( index != wxNOT_FOUND )
+ {
+ m_libList->SetSelection( index, true );
+ }
+ else
+ {
+ // If not found, clear current library selection because it can be
+ // deleted after a configuration change.
+ setCurNickname( wxEmptyString );
+ setCurFootprintName( wxEmptyString );
+ }
+
+ ReCreateFootprintList();
+ ReCreateHToolbar();
+
+ m_canvas->Refresh();
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList()
+{
+ m_footprintList->Clear();
+
+ if( !getCurNickname() )
+ {
+ setCurFootprintName( wxEmptyString );
+ return;
+ }
+
+ FOOTPRINT_LIST fp_info_list;
+
+ wxString nickname = getCurNickname();
+
+ fp_info_list.ReadFootprintFiles( Prj().PcbFootprintLibs(), !nickname ? NULL : &nickname );
+
+ if( fp_info_list.GetErrorCount() )
+ {
+ fp_info_list.DisplayErrors( this );
+ return;
+ }
+
+ BOOST_FOREACH( const FOOTPRINT_INFO& footprint, fp_info_list.GetList() )
+ {
+ m_footprintList->Append( footprint.GetFootprintName() );
+ }
+
+ int index = m_footprintList->FindString( getCurFootprintName() );
+
+ if( index == wxNOT_FOUND )
+ setCurFootprintName( wxEmptyString );
+ else
+ m_footprintList->SetSelection( index, true );
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::ClickOnLibList( wxCommandEvent& event )
+{
+ int ii = m_libList->GetSelection();
+
+ if( ii < 0 )
+ return;
+
+ wxString name = m_libList->GetString( ii );
+
+ if( getCurNickname() == name )
+ return;
+
+ setCurNickname( name );
+
+ ReCreateFootprintList();
+ UpdateTitle();
+ ReCreateHToolbar();
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList( wxCommandEvent& event )
+{
+ if( m_footprintList->GetCount() == 0 )
+ return;
+
+ int ii = m_footprintList->GetSelection();
+
+ if( ii < 0 )
+ return;
+
+ wxString name = m_footprintList->GetString( ii );
+
+ if( getCurFootprintName().CmpNoCase( name ) != 0 )
+ {
+ setCurFootprintName( name );
+
+ SetCurItem( NULL );
+
+ // Delete the current footprint
+ GetBoard()->m_Modules.DeleteAll();
+
+ FPID id;
+ id.SetLibNickname( getCurNickname() );
+ id.SetFootprintName( getCurFootprintName() );
+
+ try
+ {
+ GetBoard()->Add( loadFootprint( id ) );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format(
+ _( "Could not load footprint \"%s\" from library \"%s\".\n\nError %s." ),
+ GetChars( getCurFootprintName() ),
+ GetChars( getCurNickname() ),
+ GetChars( ioe.errorText ) );
+
+ DisplayError( this, msg );
+ }
+
+ UpdateTitle();
+
+ if( IsGalCanvasActive() )
+ updateView();
+
+ Zoom_Automatique( false );
+ m_canvas->Refresh();
+ Update3D_Frame();
+ }
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::DClickOnFootprintList( wxCommandEvent& event )
+{
+ if( IsModal() )
+ {
+ // @todo(DICK)
+ ExportSelectedFootprint( event );
+
+ // Prevent the double click from being as a single mouse button release
+ // event in the parent window which would cause the part to be parked
+ // rather than staying in move mode.
+ // Remember the mouse button will be released in the parent window
+ // thus creating a mouse button release event which should be ignored
+ PCB_EDIT_FRAME* pcbframe = dynamic_cast<PCB_EDIT_FRAME*>( GetParent() );
+
+ // The parent may not be the board editor:
+ if( pcbframe )
+ {
+ pcbframe->SkipNextLeftButtonReleaseEvent();
+ }
+ }
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::ExportSelectedFootprint( wxCommandEvent& event )
+{
+ int ii = m_footprintList->GetSelection();
+
+ if( ii >= 0 )
+ {
+ wxString fp_name = m_footprintList->GetString( ii );
+
+ FPID fpid;
+
+ fpid.SetLibNickname( getCurNickname() );
+ fpid.SetFootprintName( fp_name );
+
+ DismissModal( true, fpid.Format() );
+ }
+ else
+ {
+ DismissModal( false );
+ }
+
+ Close( true );
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::LoadSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::LoadSettings( aCfg );
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::SaveSettings( wxConfigBase* aCfg )
+{
+ EDA_DRAW_FRAME::SaveSettings( aCfg );
+}
+
+
+const wxString FOOTPRINT_VIEWER_FRAME::getCurNickname()
+{
+ return Prj().GetRString( PROJECT::PCB_FOOTPRINT_VIEWER_NICKNAME );
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::setCurNickname( const wxString& aNickname )
+{
+ Prj().SetRString( PROJECT::PCB_FOOTPRINT_VIEWER_NICKNAME, aNickname );
+}
+
+
+const wxString FOOTPRINT_VIEWER_FRAME::getCurFootprintName()
+{
+ return Prj().GetRString( PROJECT::PCB_FOOTPRINT_VIEWER_FPNAME );
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::setCurFootprintName( const wxString& aName )
+{
+ Prj().SetRString( PROJECT::PCB_FOOTPRINT_VIEWER_FPNAME, aName );
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::OnActivate( wxActivateEvent& event )
+{
+ EDA_DRAW_FRAME::OnActivate( event );
+
+ // Ensure we do not have old selection:
+ if( !event.GetActive() )
+ return;
+
+ // Ensure we have the right library list:
+ std::vector< wxString > libNicknames = Prj().PcbFootprintLibs()->GetLogicalLibs();
+
+ if( libNicknames.size() == m_libList->GetCount() )
+ {
+ unsigned ii;
+
+ for( ii = 0; ii < libNicknames.size(); ii++ )
+ {
+ if( libNicknames[ii] != m_libList->GetString( ii ) )
+ break;
+ }
+
+ if( ii == libNicknames.size() )
+ return;
+ }
+
+ // If we are here, the library list has changed, rebuild it
+ ReCreateLibraryList();
+ UpdateTitle();
+}
+
+
+bool FOOTPRINT_VIEWER_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
+{
+ bool eventHandled = true;
+
+ // Filter out the 'fake' mouse motion after a keyboard movement
+ if( !aHotKey && m_movingCursorWithKeyboard )
+ {
+ m_movingCursorWithKeyboard = false;
+ return false;
+ }
+
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
+ cmd.SetEventObject( this );
+
+ wxPoint oldpos = GetCrossHairPosition();
+ wxPoint pos = aPosition;
+ GeneralControlKeyMovement( aHotKey, &pos, true );
+
+ if( aHotKey )
+ {
+ eventHandled = OnHotKey( aDC, aHotKey, aPosition );
+ }
+
+ SetCrossHairPosition( pos );
+ RefreshCrossHair( oldpos, aPosition, aDC );
+
+ UpdateStatusBar(); // Display new cursor coordinates
+
+ return eventHandled;
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::Show3D_Frame( wxCommandEvent& event )
+{
+ if( m_Draw3DFrame )
+ {
+ // Raising the window does not show the window on Windows if iconized.
+ // This should work on any platform.
+ if( m_Draw3DFrame->IsIconized() )
+ m_Draw3DFrame->Iconize( false );
+
+ m_Draw3DFrame->Raise();
+
+ // Raising the window does not set the focus on Linux. This should work on any platform.
+ if( wxWindow::FindFocus() != m_Draw3DFrame )
+ m_Draw3DFrame->SetFocus();
+
+ return;
+ }
+
+ m_Draw3DFrame = new EDA_3D_FRAME( &Kiway(), this, wxEmptyString );
+ Update3D_Frame( false );
+ m_Draw3DFrame->Raise(); // Needed with some Window Managers
+ m_Draw3DFrame->Show( true );
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::Update3D_Frame( bool aForceReloadFootprint )
+{
+ if( m_Draw3DFrame == NULL )
+ return;
+
+ wxString frm3Dtitle = wxString::Format(
+ _( "ModView: 3D Viewer [%s]" ),
+ GetChars( getCurFootprintName() ) );
+
+ m_Draw3DFrame->SetTitle( frm3Dtitle );
+
+ if( aForceReloadFootprint )
+ {
+ m_Draw3DFrame->ReloadRequest();
+
+ // Force 3D screen refresh immediately
+ if( GetBoard()->m_Modules )
+ m_Draw3DFrame->NewDisplay();
+ }
+}
+
+
+EDA_COLOR_T FOOTPRINT_VIEWER_FRAME::GetGridColor() const
+{
+ return g_ColorsSettings.GetItemColor( GRID_VISIBLE );
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::OnIterateFootprintList( wxCommandEvent& event )
+{
+ switch( event.GetId() )
+ {
+ case ID_MODVIEW_NEXT:
+ SelectAndViewFootprint( NEXT_PART );
+ break;
+
+ case ID_MODVIEW_PREVIOUS:
+ SelectAndViewFootprint( PREVIOUS_PART );
+ break;
+
+ default:
+ wxString id = wxString::Format(wxT("%i"),event.GetId());
+ wxFAIL_MSG( wxT( "FOOTPRINT_VIEWER_FRAME::OnIterateFootprintList error: id = " ) + id );
+ }
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
+{
+}
+
+
+bool FOOTPRINT_VIEWER_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu )
+{
+ return true;
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::UpdateTitle()
+{
+ wxString msg;
+
+ msg = _( "Library Browser" );
+ msg << wxT( " [" );
+
+ if( getCurNickname().size() )
+ msg << getCurNickname();
+ else
+ msg += _( "no library selected" );
+
+ msg << wxT( "]" );
+
+ SetTitle( msg );
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::SelectCurrentLibrary( wxCommandEvent& event )
+{
+ wxString selection = SelectLibrary( getCurNickname() );
+
+ if( !!selection && selection != getCurNickname() )
+ {
+ setCurNickname( selection );
+
+ UpdateTitle();
+ ReCreateFootprintList();
+
+ int id = m_libList->FindString( getCurNickname() );
+
+ if( id >= 0 )
+ m_libList->SetSelection( id );
+ }
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::SelectCurrentFootprint( wxCommandEvent& event )
+{
+#if 0 // cannot remember why this is here
+ // The PCB_EDIT_FRAME may not be the FOOTPRINT_VIEW_FRAME's parent,
+ // so use Kiway().Player() to fetch.
+ PCB_EDIT_FRAME* parent = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, true );
+ (void*) parent;
+#endif
+
+ wxString nickname = getCurNickname();
+ MODULE* oldmodule = GetBoard()->m_Modules;
+ MODULE* module = LoadModuleFromLibrary( nickname, Prj().PcbFootprintLibs(), false );
+
+ if( module )
+ {
+ module->SetPosition( wxPoint( 0, 0 ) );
+
+ // Only one footprint allowed: remove the previous footprint (if exists)
+ if( oldmodule )
+ {
+ GetBoard()->Remove( oldmodule );
+ delete oldmodule;
+ }
+
+ setCurFootprintName( module->GetFPID().GetFootprintName() );
+
+ wxString nickname = module->GetFPID().GetLibNickname();
+
+ if( !getCurNickname() && nickname.size() )
+ {
+ // Set the listbox
+ int index = m_libList->FindString( nickname );
+ if( index != wxNOT_FOUND )
+ m_libList->SetSelection( index, true );
+
+ setCurNickname( nickname );
+ }
+
+ module->ClearFlags();
+ SetCurItem( NULL );
+
+ Zoom_Automatique( false );
+ m_canvas->Refresh();
+ Update3D_Frame();
+ m_footprintList->SetStringSelection( getCurFootprintName() );
+ }
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::SelectAndViewFootprint( int aMode )
+{
+ if( !getCurNickname() )
+ return;
+
+ int selection = m_footprintList->FindString( getCurFootprintName() );
+
+ if( aMode == NEXT_PART )
+ {
+ if( selection != wxNOT_FOUND && selection < (int)m_footprintList->GetCount()-1 )
+ selection++;
+ }
+
+ if( aMode == PREVIOUS_PART )
+ {
+ if( selection != wxNOT_FOUND && selection > 0 )
+ selection--;
+ }
+
+ if( selection != wxNOT_FOUND )
+ {
+ m_footprintList->SetSelection( selection );
+ setCurFootprintName( m_footprintList->GetString( selection ) );
+ SetCurItem( NULL );
+
+ // Delete the current footprint
+ GetBoard()->m_Modules.DeleteAll();
+
+ MODULE* footprint = Prj().PcbFootprintLibs()->FootprintLoad(
+ getCurNickname(), getCurFootprintName() );
+
+ if( footprint )
+ GetBoard()->Add( footprint, ADD_APPEND );
+
+ Update3D_Frame();
+
+ if( IsGalCanvasActive() )
+ updateView();
+ }
+
+
+ UpdateTitle();
+ Zoom_Automatique( false );
+ m_canvas->Refresh();
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
+{
+ if( !GetBoard() )
+ return;
+
+ m_canvas->DrawBackGround( DC );
+ GetBoard()->Draw( m_canvas, DC, GR_COPY );
+
+ MODULE* module = GetBoard()->m_Modules;
+
+ m_canvas->DrawCrossHair( DC );
+
+ ClearMsgPanel();
+
+ if( module )
+ SetMsgPanel( module );
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::updateView()
+{
+ if( IsGalCanvasActive() )
+ {
+ static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() )->DisplayBoard( GetBoard() );
+ m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
+ m_toolManager->RunAction( COMMON_ACTIONS::zoomFitScreen, true );
+ }
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::CloseFootprintViewer( wxCommandEvent& event )
+{
+ Close();
+}
diff --git a/pcbnew/modview_frame.h b/pcbnew/modview_frame.h
new file mode 100644
index 0000000..cd472d6
--- /dev/null
+++ b/pcbnew/modview_frame.h
@@ -0,0 +1,187 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
+ * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file modview_frame.h
+ */
+
+#ifndef MODVIEWFRM_H_
+#define MODVIEWFRM_H_
+
+
+#include <wx/gdicmn.h>
+
+class wxSashLayoutWindow;
+class wxListBox;
+class FP_LIB_TABLE;
+
+namespace PCB { struct IFACE; }
+
+/**
+ * Component library viewer main window.
+ */
+class FOOTPRINT_VIEWER_FRAME : public PCB_BASE_FRAME
+{
+ friend struct PCB::IFACE; // constructor called from here only
+
+protected:
+ FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType );
+
+
+public:
+ ~FOOTPRINT_VIEWER_FRAME();
+
+ virtual EDA_COLOR_T GetGridColor() const;
+
+ /**
+ * Function ReCreateLibraryList
+ *
+ * Creates or recreates the list of current loaded libraries.
+ * This list is sorted, with the library cache always at end of the list
+ */
+ void ReCreateLibraryList();
+
+private:
+
+ wxListBox* m_libList; // The list of libs names
+ wxListBox* m_footprintList; // The list of footprint names
+
+ wxString m_configPath; // subpath for configuration
+
+ const wxString getCurNickname();
+ void setCurNickname( const wxString& aNickname );
+
+ const wxString getCurFootprintName();
+ void setCurFootprintName( const wxString& aName );
+
+ void OnSize( wxSizeEvent& event );
+
+ void ReCreateFootprintList();
+ void OnIterateFootprintList( wxCommandEvent& event );
+
+ /**
+ * Function UpdateTitle
+ * updates the window title with current library information.
+ */
+ void UpdateTitle();
+
+ /**
+ * Function RedrawActiveWindow
+ * Display the current selected component.
+ * If the component is an alias, the ROOT component is displayed
+ */
+ void RedrawActiveWindow( wxDC* DC, bool EraseBg );
+
+ void OnCloseWindow( wxCloseEvent& Event );
+ void CloseFootprintViewer( wxCommandEvent& event );
+
+ void ReCreateHToolbar();
+ void ReCreateVToolbar();
+ void ReCreateMenuBar();
+
+ void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
+ void ClickOnLibList( wxCommandEvent& event );
+ void ClickOnFootprintList( wxCommandEvent& event );
+ void DClickOnFootprintList( wxCommandEvent& event );
+ void OnSetRelativeOffset( wxCommandEvent& event );
+
+ bool GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey = 0 );
+
+ ///> @copydoc EDA_DRAW_FRAME::GetHotKeyDescription()
+ EDA_HOTKEY* GetHotKeyDescription( int aCommand ) const;
+
+ /**
+ * Function OnHotKey
+ * handle hot key events.
+ * <p?
+ * Some commands are relative to the item under the mouse cursor. Commands are
+ * case insensitive
+ * </p>
+ */
+ bool OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem = NULL );
+
+ void LoadSettings( wxConfigBase* aCfg ); // override virtual
+ void SaveSettings( wxConfigBase* aCfg ); // override virtual
+
+ /**
+ * Function OnActivate
+ * is called when the frame frame is activate to reload the libraries and component lists
+ * that can be changed by the schematic editor or the library editor.
+ */
+ virtual void OnActivate( wxActivateEvent& event );
+
+ void SelectCurrentLibrary( wxCommandEvent& event );
+
+ /**
+ * Function SelectCurrentFootprint
+ * Selects the current footprint name and display it
+ */
+ void SelectCurrentFootprint( wxCommandEvent& event );
+
+ /**
+ * Function ExportSelectedFootprint
+ * exports the current footprint name and close the library browser.
+ */
+ void ExportSelectedFootprint( wxCommandEvent& event );
+
+ /**
+ * Function SelectAndViewFootprint
+ * Select and load the next or the previous footprint
+ * if no current footprint, Rebuild the list of footprints available in a given footprint
+ * library
+ * @param aMode = NEXT_PART or PREVIOUS_PART
+ */
+ void SelectAndViewFootprint( int aMode );
+
+ bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
+
+ /**
+ * Function Show3D_Frame (virtual)
+ * displays 3D view of the footprint (module) being edited.
+ */
+ void Show3D_Frame( wxCommandEvent& event );
+
+ /**
+ * Function Update3D_Frame
+ * must be called after a footprint selection
+ * Updates the 3D view and 3D frame title.
+ * @param aForceReloadFootprint = true to reload data (default)
+ * = false to update title only -(after creating the 3D viewer)
+ */
+ void Update3D_Frame( bool aForceReloadFootprint = true );
+
+ /*
+ * Virtual functions, not used here, but needed by PCB_BASE_FRAME
+ * (virtual pure functions )
+ */
+ void OnLeftDClick( wxDC*, const wxPoint& ) {}
+ void SaveCopyInUndoList( BOARD_ITEM*, UNDO_REDO_T, const wxPoint& ) {}
+ void SaveCopyInUndoList( const PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint &) {}
+
+ void updateView();
+
+ DECLARE_EVENT_TABLE()
+};
+
+#endif // MODVIEWFRM_H_
diff --git a/pcbnew/move-drag_pads.cpp b/pcbnew/move-drag_pads.cpp
new file mode 100644
index 0000000..e52ad9f
--- /dev/null
+++ b/pcbnew/move-drag_pads.cpp
@@ -0,0 +1,210 @@
+
+
+/**
+ * @file move-drag_pads.cpp
+ * @brief Edit footprint pads.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <trigo.h>
+#include <block_commande.h>
+#include <wxBasePcbFrame.h>
+
+#include <class_board.h>
+#include <class_module.h>
+
+#include <pcbnew.h>
+#include <drag.h>
+
+
+static D_PAD* s_CurrentSelectedPad;
+static wxPoint Pad_OldPos;
+
+
+/* Cancel move pad command.
+ */
+static void Abort_Move_Pad( EDA_DRAW_PANEL* Panel, wxDC* DC )
+{
+ D_PAD* pad = s_CurrentSelectedPad;
+
+ Panel->SetMouseCapture( NULL, NULL );
+
+ if( pad == NULL )
+ return;
+
+ pad->Draw( Panel, DC, GR_XOR );
+ pad->ClearFlags();
+ pad->SetPosition( Pad_OldPos );
+ pad->Draw( Panel, DC, GR_XOR );
+
+ // Pad move in progress: restore origin of dragged tracks, if any.
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ TRACK* track = g_DragSegmentList[ii].m_Track;
+ track->Draw( Panel, DC, GR_XOR );
+ track->SetState( IN_EDIT, false );
+ track->ClearFlags();
+ g_DragSegmentList[ii].RestoreInitialValues();
+ track->Draw( Panel, DC, GR_OR );
+ }
+
+ EraseDragList();
+ s_CurrentSelectedPad = NULL;
+}
+
+
+/* Draw in drag mode when moving a pad.
+ */
+static void Show_Pad_Move( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ TRACK* Track;
+ D_PAD* pad = s_CurrentSelectedPad;
+
+ if( pad == NULL ) // Should not occur
+ return;
+
+ if( aErase )
+ pad->Draw( aPanel, aDC, GR_XOR );
+
+ pad->SetPosition( aPanel->GetParent()->GetCrossHairPosition() );
+ pad->Draw( aPanel, aDC, GR_XOR );
+
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ Track = g_DragSegmentList[ii].m_Track;
+
+ if( aErase )
+ Track->Draw( aPanel, aDC, GR_XOR );
+
+ g_DragSegmentList[ii].SetTrackEndsCoordinates( wxPoint(0, 0) );
+
+ Track->Draw( aPanel, aDC, GR_XOR );
+ }
+}
+
+
+// Function to initialize the "move pad" command
+void PCB_BASE_FRAME::StartMovePad( D_PAD* aPad, wxDC* aDC, bool aDragConnectedTracks )
+{
+ if( aPad == NULL )
+ return;
+
+ s_CurrentSelectedPad = aPad;
+
+ Pad_OldPos = aPad->GetPosition();
+
+ SetMsgPanel( aPad );
+ m_canvas->SetMouseCapture( Show_Pad_Move, Abort_Move_Pad );
+
+ // Draw the pad, in SKETCH mode
+ aPad->Draw( m_canvas, aDC, GR_XOR );
+ aPad->SetFlags( IS_MOVED );
+ aPad->Draw( m_canvas, aDC, GR_XOR );
+
+ EraseDragList();
+
+ // Build the list of track segments to drag if the command is a drag pad
+ if( aDragConnectedTracks )
+ {
+ DRAG_LIST drglist( GetBoard() );
+ drglist.BuildDragListe( aPad );
+ UndrawAndMarkSegmentsToDrag( m_canvas, aDC );
+ }
+}
+
+
+// Routine to place a moved pad.
+void PCB_BASE_FRAME::PlacePad( D_PAD* aPad, wxDC* DC )
+{
+ int dX, dY;
+ TRACK* track;
+
+ if( aPad == NULL )
+ return;
+
+ MODULE* module = aPad->GetParent();
+
+ ITEM_PICKER picker( NULL, UR_CHANGED );
+ PICKED_ITEMS_LIST pickList;
+
+ // Save dragged track segments in undo list
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ track = g_DragSegmentList[ii].m_Track;
+
+ // Set the old state
+ if( g_DragSegmentList[ii].m_Pad_Start )
+ track->SetStart( Pad_OldPos );
+
+ if( g_DragSegmentList[ii].m_Pad_End )
+ track->SetEnd( Pad_OldPos );
+
+ picker.SetItem( track );
+ pickList.PushItem( picker );
+ }
+
+ // Save old module and old items values
+ aPad->ClearFlags();
+ wxPoint pad_curr_position = aPad->GetPosition();
+
+ aPad->SetPosition( Pad_OldPos );
+
+ if( g_DragSegmentList.size() == 0 )
+ SaveCopyInUndoList( module, UR_CHANGED );
+ else
+ {
+ picker.SetItem( module );
+ pickList.PushItem( picker );
+ SaveCopyInUndoList( pickList, UR_CHANGED );
+ }
+
+ aPad->SetPosition( pad_curr_position );
+ aPad->Draw( m_canvas, DC, GR_XOR );
+
+ // Redraw dragged track segments
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ track = g_DragSegmentList[ii].m_Track;
+
+ // Set the new state
+ if( g_DragSegmentList[ii].m_Pad_Start )
+ track->SetStart( aPad->GetPosition() );
+
+ if( g_DragSegmentList[ii].m_Pad_End )
+ track->SetEnd( aPad->GetPosition() );
+
+ if( DC )
+ track->Draw( m_canvas, DC, GR_XOR );
+
+ track->SetState( IN_EDIT, false );
+ track->ClearFlags();
+
+ if( DC )
+ track->Draw( m_canvas, DC, GR_OR );
+ }
+
+ // Compute local coordinates (i.e refer to module position and for module orient = 0)
+ dX = aPad->GetPosition().x - Pad_OldPos.x;
+ dY = aPad->GetPosition().y - Pad_OldPos.y;
+
+ RotatePoint( &dX, &dY, -module->GetOrientation() );
+
+ aPad->SetX0( dX + aPad->GetPos0().x );
+ aPad->SetY0( dY + aPad->GetPos0().y );
+
+ if( DC )
+ aPad->Draw( m_canvas, DC, GR_OR );
+
+ module->CalculateBoundingBox();
+ module->SetLastEditTime();
+
+ EraseDragList();
+
+ OnModify();
+ m_canvas->SetMouseCapture( NULL, NULL );
+ m_Pcb->m_Status_Pcb &= ~( LISTE_RATSNEST_ITEM_OK | CONNEXION_OK );
+}
diff --git a/pcbnew/move_or_drag_track.cpp b/pcbnew/move_or_drag_track.cpp
new file mode 100644
index 0000000..b381e3c
--- /dev/null
+++ b/pcbnew/move_or_drag_track.cpp
@@ -0,0 +1,868 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file move_or_drag_track.cpp
+ * @brief Track editing routines to move and drag track segments or node.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <trigo.h>
+#include <macros.h>
+#include <gr_basic.h>
+
+#include <class_board.h>
+
+#include <pcbnew.h>
+#include <drc_stuff.h>
+#include <drag.h>
+#include <pcbnew_id.h>
+
+
+static void Show_MoveNode( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase );
+static void Show_Drag_Track_Segment_With_Cte_Slope( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC,
+ const wxPoint& aPosition,
+ bool aErase );
+static void Abort_MoveTrack( EDA_DRAW_PANEL* Panel, wxDC* DC );
+static bool InitialiseDragParameters();
+
+
+static wxPoint PosInit, s_LastPos;
+static double s_StartSegmentSlope, s_EndSegmentSlope,
+ s_MovingSegmentSlope,
+ s_StartSegment_Yorg, s_EndSegment_Yorg,
+ s_MovingSegment_Yorg; //slope and intercept parameters of lines
+bool s_StartPointVertical, s_EndPointVertical,
+ s_MovingSegmentVertical, s_MovingSegmentHorizontal,
+ s_StartPointHorizontal, s_EndPointHorizontal; // vertical or
+ // horizontal line
+ // indicators
+bool s_StartSegmentPresent, s_EndSegmentPresent;
+
+static PICKED_ITEMS_LIST s_ItemsListPicker;
+
+
+/** Abort function for drag or move track
+ */
+static void Abort_MoveTrack( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
+{
+ PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) aPanel->GetParent();
+ BOARD * pcb = frame->GetBoard();
+
+ pcb->HighLightOFF();
+ pcb->PopHighLight();
+
+ frame->SetCurItem( NULL );
+ aPanel->SetMouseCapture( NULL, NULL );
+
+ // Undo move and redraw trace segments.
+ for( unsigned jj=0 ; jj < g_DragSegmentList.size(); jj++ )
+ {
+ TRACK* track = g_DragSegmentList[jj].m_Track;
+ g_DragSegmentList[jj].RestoreInitialValues();
+ track->SetState( IN_EDIT, false );
+ track->ClearFlags();
+ }
+
+ // Clear the undo picker list:
+ s_ItemsListPicker.ClearListAndDeleteItems();
+ EraseDragList();
+ aPanel->Refresh();
+}
+
+
+// Redraw the moved node according to the mouse cursor position
+static void Show_MoveNode( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) aPanel->GetDisplayOptions();
+ wxPoint moveVector;
+ int tmp = displ_opts->m_DisplayPcbTrackFill;
+ GR_DRAWMODE draw_mode = GR_XOR | GR_HIGHLIGHT;
+
+ displ_opts->m_DisplayPcbTrackFill = false;
+
+#ifndef USE_WX_OVERLAY
+ aErase = true;
+#else
+ aErase = false;
+#endif
+
+ // set the new track coordinates
+ wxPoint Pos = aPanel->GetParent()->GetCrossHairPosition();
+
+ moveVector = Pos - s_LastPos;
+ s_LastPos = Pos;
+
+ TRACK *track = NULL;
+
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ track = g_DragSegmentList[ii].m_Track;
+
+ if( aErase )
+ track->Draw( aPanel, aDC, draw_mode );
+
+ if( track->GetFlags() & STARTPOINT )
+ track->SetStart( track->GetStart() + moveVector );
+
+ if( track->GetFlags() & ENDPOINT )
+ track->SetEnd( track->GetEnd() + moveVector );
+
+ if( track->Type() == PCB_VIA_T )
+ track->SetEnd( track->GetStart() );
+
+ track->Draw( aPanel, aDC, draw_mode );
+ }
+
+ displ_opts->m_DisplayPcbTrackFill = tmp;
+
+ // Display track length
+ if( track )
+ {
+ PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent();
+ frame->SetMsgPanel( track );
+ }
+}
+
+
+/* drawing the track segment movement
+ * > s_MovingSegmentSlope slope = moving track segment slope
+ * > s_StartSegmentSlope slope = slope of the segment connected to the start
+ * point of the moving segment
+ * > s_EndSegmentSlope slope = slope of the segment connected to the end point
+ * of the moving segment
+ *
+ * moved segment function :
+ * yt=s_MovingSegmentSlope * x + s_MovingSegment_Yorg
+ *
+ * segment connected to moved segment's start:
+ * y1 = s_StartSegmentSlope * x + s_StartSegment_Yorg
+ *
+ * segment connected to moved segment's end:
+ * y2=s_EndSegmentSlope * x + s_EndSegment_Yorg
+ *
+ * first intersection point will be located at
+ * y1=yt ->
+ *
+ * xi1=(s_MovingSegment_Yorg-s_StartSegment_Yorg)/(s_StartSegmentSlope-s_MovingSegmentSlope)
+ * yi1=s_MovingSegmentSlope*xi1+s_MovingSegment_Yorg
+ * or yi1=s_StartSegmentSlope*xi1+s_MovingSegment_Yorg
+ *
+ * second intersection point
+ * y2=yt ->
+ *
+ * xi2=(s_MovingSegment_Yorg-s_StartSegment_Yorg)/(s_MovingSegmentSlope-s_MovingSegmentSlope)
+ * yi2=s_MovingSegmentSlope*xi2+s_MovingSegment_Yorg
+ * or yi1=s_EndSegmentSlope*xi2+s_MovingSegment_Yorg
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * !!!!! special attention to vertical segments because
+ * !!!!! their slope=infinite
+ * !!!!! intersection point will be calculated using the
+ * !!!!! segment intersecting it
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ *
+ * Slope parameters are computed once, because they can become undetermined
+ * when moving segments
+ * (i.e. when a segment length is 0) and we want keep them constant
+ */
+static void Show_Drag_Track_Segment_With_Cte_Slope( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase )
+{
+ double xi1 = 0, yi1 = 0, xi2 = 0, yi2 = 0; // calculated intersection points
+ double tx1, tx2, ty1, ty2; // temporary storage of points
+ int dx, dy;
+ bool update = true;
+ TRACK* Track;
+ TRACK* tSegmentToStart = NULL, * tSegmentToEnd = NULL;
+
+ if( g_DragSegmentList.size() == 0 )
+ return;
+
+ /* get the segments :
+ * from last to first in list are:
+ * the segment to move
+ * the segment connected to its end point (if exists)
+ * the segment connected to its start point (if exists)
+ */
+ int ii = g_DragSegmentList.size() - 1;
+ Track = g_DragSegmentList[ii].m_Track;
+
+ if( Track == NULL )
+ return;
+
+ ii--;
+
+ if( ii >= 0)
+ {
+ if( s_EndSegmentPresent )
+ {
+ // Get the segment connected to the end point
+ tSegmentToEnd = g_DragSegmentList[ii].m_Track;
+ ii--;
+ }
+
+ if( s_StartSegmentPresent )
+ {
+ // Get the segment connected to the start point
+ if( ii >= 0 )
+ tSegmentToStart = g_DragSegmentList[ii].m_Track;
+ }
+ }
+
+ GR_DRAWMODE draw_mode = GR_XOR | GR_HIGHLIGHT;
+
+ // Undraw the current moved track segments before modification
+
+#ifndef USE_WX_OVERLAY
+// if( erase )
+ {
+ Track->Draw( aPanel, aDC, draw_mode );
+
+ if( tSegmentToStart )
+ tSegmentToStart->Draw( aPanel, aDC, draw_mode );
+
+ if( tSegmentToEnd )
+ tSegmentToEnd->Draw( aPanel, aDC, draw_mode );
+ }
+#endif
+
+ // Compute the new track segment position
+ wxPoint Pos = aPanel->GetParent()->GetCrossHairPosition();
+
+ dx = Pos.x - s_LastPos.x;
+ dy = Pos.y - s_LastPos.y;
+
+ // move the line by dx and dy
+ tx1 = (double) ( Track->GetStart().x + dx );
+ ty1 = (double) ( Track->GetStart().y + dy );
+ tx2 = (double) ( Track->GetEnd().x + dx );
+ ty2 = (double) ( Track->GetEnd().y + dy );
+
+ // recalculate the segments new parameters and intersection points
+ // only the intercept will change, segment slopes does not change
+ // because we are moving parallel with is initial state
+ if( !s_MovingSegmentVertical )
+ s_MovingSegment_Yorg = ty1 - ( s_MovingSegmentSlope * tx1 );
+
+ if( ( !s_EndPointVertical ) && ( !s_MovingSegmentVertical ) )
+ {
+ xi2 = ( s_MovingSegment_Yorg - s_EndSegment_Yorg )
+ / ( s_EndSegmentSlope - s_MovingSegmentSlope );
+ }
+ else
+ {
+ if( !s_EndPointVertical )
+ xi2 = tx2;
+ else
+ {
+ //P1=P2
+ if( !s_EndPointHorizontal )
+ xi2 = tx2 - dx;
+ else
+ update = false;
+ }
+ }
+
+ if( !s_MovingSegmentVertical )
+ yi2 = ( s_MovingSegmentSlope * xi2 ) + s_MovingSegment_Yorg;
+ else
+ {
+ if( !s_EndPointVertical )
+ yi2 = ( s_EndSegmentSlope * xi2 ) + s_EndSegment_Yorg;
+ else
+ {
+ if( !s_EndPointHorizontal )
+ update = false;
+ else
+ yi2 = ( s_MovingSegmentSlope * xi2 ) + s_MovingSegment_Yorg;
+ }
+ }
+
+ if( ( !s_StartPointVertical ) && ( !s_MovingSegmentVertical ) )
+ {
+ xi1 = ( s_MovingSegment_Yorg - s_StartSegment_Yorg )
+ / ( s_StartSegmentSlope - s_MovingSegmentSlope );
+ }
+ else
+ {
+ if( !s_StartPointVertical )
+ xi1 = tx1;
+ else
+ {
+ //P1=P2
+ if( !s_StartPointHorizontal )
+ xi1 = tx1 - dx;
+ else
+ {
+ if( !s_StartPointHorizontal )
+ update = false;
+ }
+ }
+ }
+
+ if( !s_MovingSegmentVertical )
+ yi1 = ( s_MovingSegmentSlope * xi1 ) + s_MovingSegment_Yorg;
+ else
+ {
+ if( !s_StartPointVertical )
+ yi1 = ( s_StartSegmentSlope * xi1 ) + s_StartSegment_Yorg;
+ else
+ {
+ if( !s_StartPointHorizontal )
+ update = false;
+ else
+ yi2 = ( s_MovingSegmentSlope * xi1 ) + s_MovingSegment_Yorg;
+ }
+ }
+
+ // update the segment coordinates (if possible)
+ if( tSegmentToStart == NULL )
+ {
+ xi1 = tx1;
+ yi1 = ty1;
+ }
+
+ if( tSegmentToEnd == NULL )
+ {
+ xi2 = tx2;
+ yi2 = ty2;
+ }
+
+ if( update )
+ {
+ s_LastPos = Pos;
+ Track->SetStart( wxPoint( KiROUND( xi1 ), KiROUND( yi1 ) ) );
+ Track->SetEnd( wxPoint( KiROUND( xi2 ), KiROUND( yi2 ) ) );
+
+ if( tSegmentToEnd )
+ {
+ if( tSegmentToEnd->GetFlags() & STARTPOINT )
+ tSegmentToEnd->SetStart( Track->GetEnd() );
+ else
+ tSegmentToEnd->SetEnd( Track->GetEnd() );
+ }
+
+ if( tSegmentToStart )
+ {
+ if( tSegmentToStart->GetFlags() & STARTPOINT )
+ tSegmentToStart->SetStart( Track->GetStart() );
+ else
+ tSegmentToStart->SetEnd( Track->GetStart() );
+ }
+ }
+
+ Track->Draw( aPanel, aDC, draw_mode );
+
+ if( tSegmentToStart )
+ tSegmentToStart->Draw( aPanel, aDC, draw_mode );
+
+ if( tSegmentToEnd )
+ tSegmentToEnd->Draw( aPanel, aDC, draw_mode );
+
+ // Display track length
+ PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent();
+ frame->SetMsgPanel( Track );
+}
+
+
+/* Init variables (slope, Y intersect point, flags) for
+ * Show_Drag_Track_Segment_With_Cte_Slope()
+ * return true if Ok, false if dragging is not possible
+ * (2 colinear segments)
+ */
+bool InitialiseDragParameters()
+{
+ double tx1, tx2, ty1, ty2; // temporary storage of points
+ TRACK* Track;
+ TRACK* tSegmentToStart = NULL, * tSegmentToEnd = NULL;
+
+ if( g_DragSegmentList.size() == 0 )
+ return false;
+
+ /* get the segments :
+ * from last to first in list are:
+ * the segment to move
+ * the segment connected to its end point (if exists)
+ * the segment connected to its start point (if exists)
+ */
+ int ii = g_DragSegmentList.size() - 1;
+ Track = g_DragSegmentList[ii].m_Track;
+ if( Track == NULL )
+ return false;
+
+ ii--;
+
+ if( ii >= 0)
+ {
+ if( s_EndSegmentPresent )
+ {
+ tSegmentToEnd = g_DragSegmentList[ii].m_Track; // Get the segment connected to
+ // the end point
+ ii--;
+ }
+
+ if( s_StartSegmentPresent )
+ {
+ if( ii >= 0 )
+ tSegmentToStart = g_DragSegmentList[ii].m_Track; // Get the segment connected to
+ // the start point
+ }
+ }
+
+ // would be nice to eliminate collinear segments here, so we don't
+ // have to deal with that annoying "Unable to drag this segment: two
+ // collinear segments"
+
+ s_StartPointVertical = false;
+ s_EndPointVertical = false;
+ s_MovingSegmentVertical = false;
+ s_StartPointHorizontal = false;
+ s_EndPointHorizontal = false;
+ s_MovingSegmentHorizontal = false;
+
+ // Init parameters for the starting point of the moved segment
+ if( tSegmentToStart )
+ {
+ if( tSegmentToStart->GetFlags() & ENDPOINT )
+ {
+ tx1 = (double) tSegmentToStart->GetStart().x;
+ ty1 = (double) tSegmentToStart->GetStart().y;
+ tx2 = (double) tSegmentToStart->GetEnd().x;
+ ty2 = (double) tSegmentToStart->GetEnd().y;
+ }
+ else
+ {
+ tx1 = (double) tSegmentToStart->GetEnd().x;
+ ty1 = (double) tSegmentToStart->GetEnd().y;
+ tx2 = (double) tSegmentToStart->GetStart().x;
+ ty2 = (double) tSegmentToStart->GetStart().y;
+ }
+ }
+ else // move the start point on a line starting at Track->GetStart(), and perpendicular to Track
+ {
+ tx1 = (double) Track->GetStart().x;
+ ty1 = (double) Track->GetStart().y;
+ tx2 = (double) Track->GetEnd().x;
+ ty2 = (double) Track->GetEnd().y;
+ RotatePoint( &tx2, &ty2, tx1, ty1, 900 );
+ }
+
+ if( tx1 != tx2 )
+ {
+ s_StartSegmentSlope = ( ty2 - ty1 ) / ( tx2 - tx1 );
+ s_StartSegment_Yorg = ty1 - ( ty2 - ty1 ) * tx1 / ( tx2 - tx1 );
+ }
+ else
+ {
+ s_StartPointVertical = true; //signal first segment vertical
+ }
+
+ if( ty1 == ty2 )
+ {
+ s_StartPointHorizontal = true;
+ }
+
+ // Init parameters for the ending point of the moved segment
+ if( tSegmentToEnd )
+ {
+ //check if second line is vertical
+ if( tSegmentToEnd->GetFlags() & STARTPOINT )
+ {
+ tx1 = (double) tSegmentToEnd->GetStart().x;
+ ty1 = (double) tSegmentToEnd->GetStart().y;
+ tx2 = (double) tSegmentToEnd->GetEnd().x;
+ ty2 = (double) tSegmentToEnd->GetEnd().y;
+ }
+ else
+ {
+ tx1 = (double) tSegmentToEnd->GetEnd().x;
+ ty1 = (double) tSegmentToEnd->GetEnd().y;
+ tx2 = (double) tSegmentToEnd->GetStart().x;
+ ty2 = (double) tSegmentToEnd->GetStart().y;
+ }
+ }
+ else // move the start point on a line starting at Track->GetEnd(), and perpendicular to Track
+ {
+ tx1 = (double) Track->GetEnd().x;
+ ty1 = (double) Track->GetEnd().y;
+ tx2 = (double) Track->GetStart().x;
+ ty2 = (double) Track->GetStart().y;
+ RotatePoint( &tx2, &ty2, tx1, ty1, -900 );
+ }
+
+ if( tx2 != tx1 )
+ {
+ s_EndSegmentSlope = ( ty2 - ty1 ) / ( tx2 - tx1 );
+ s_EndSegment_Yorg = ty1 - ( ty2 - ty1 ) * tx1 / ( tx2 - tx1 );
+ }
+ else
+ {
+ s_EndPointVertical = true; //signal second segment vertical
+ }
+
+ if( ty1 == ty2 )
+ {
+ s_EndPointHorizontal = true;
+ }
+
+ // Init parameters for the moved segment
+ tx1 = (double) Track->GetStart().x;
+ ty1 = (double) Track->GetStart().y;
+ tx2 = (double) Track->GetEnd().x;
+ ty2 = (double) Track->GetEnd().y;
+
+ if( tx2 != tx1 )
+ {
+ s_MovingSegmentSlope = ( ty2 - ty1 ) / ( tx2 - tx1 );
+ }
+ else
+ {
+ s_MovingSegmentVertical = true; // signal vertical line
+ }
+
+ if( ty1 == ty2 )
+ {
+ s_MovingSegmentHorizontal = true;
+ }
+
+ // Test if drag is possible:
+ if( s_MovingSegmentVertical )
+ {
+ if( s_EndPointVertical || s_StartPointVertical )
+ return false;
+ }
+ else
+ {
+ if( !s_EndPointVertical && ( s_MovingSegmentSlope == s_EndSegmentSlope ) )
+ return false;
+
+ if( !s_StartPointVertical && ( s_MovingSegmentSlope == s_StartSegmentSlope ) )
+ return false;
+ }
+
+ return true;
+}
+
+
+void PCB_EDIT_FRAME::StartMoveOneNodeOrSegment( TRACK* aTrack, wxDC* aDC, int aCommand )
+{
+ if( !aTrack )
+ return;
+
+ EraseDragList();
+
+ // Change highlighted net: the new one will be highlighted
+ GetBoard()->PushHighLight();
+
+ if( GetBoard()->IsHighLightNetON() )
+ HighLight( aDC );
+
+ PosInit = GetCrossHairPosition();
+
+ if( aTrack->Type() == PCB_VIA_T )
+ {
+ aTrack->SetFlags( IS_DRAGGED | STARTPOINT | ENDPOINT );
+ AddSegmentToDragList( aTrack->GetFlags(), aTrack );
+
+ if( aCommand != ID_POPUP_PCB_MOVE_TRACK_SEGMENT )
+ {
+ Collect_TrackSegmentsToDrag( GetBoard(), aTrack->GetStart(),
+ aTrack->GetLayerSet(),
+ aTrack->GetNetCode(), aTrack->GetWidth() / 2 );
+ }
+
+ PosInit = aTrack->GetStart();
+ }
+ else
+ {
+ STATUS_FLAGS diag = aTrack->IsPointOnEnds( GetCrossHairPosition(), -1 );
+ wxPoint pos;
+
+ switch( aCommand )
+ {
+ case ID_POPUP_PCB_MOVE_TRACK_SEGMENT: // Move segment
+ aTrack->SetFlags( IS_DRAGGED | ENDPOINT | STARTPOINT );
+ AddSegmentToDragList( aTrack->GetFlags(), aTrack );
+ break;
+
+ case ID_POPUP_PCB_DRAG_TRACK_SEGMENT: // drag a segment
+ pos = aTrack->GetStart();
+ Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerSet(),
+ aTrack->GetNetCode(), aTrack->GetWidth() / 2 );
+ pos = aTrack->GetEnd();
+ aTrack->SetFlags( IS_DRAGGED | ENDPOINT | STARTPOINT );
+ Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerSet(),
+ aTrack->GetNetCode(), aTrack->GetWidth() / 2 );
+ break;
+
+ case ID_POPUP_PCB_MOVE_TRACK_NODE: // Drag via or move node
+ pos = (diag & STARTPOINT) ? aTrack->GetStart() : aTrack->GetEnd();
+ Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerSet(),
+ aTrack->GetNetCode(), aTrack->GetWidth() / 2 );
+ PosInit = pos;
+ break;
+ }
+
+ aTrack->SetFlags( IS_DRAGGED );
+ }
+
+ // Prepare the Undo command
+ ITEM_PICKER picker( aTrack, UR_CHANGED );
+ picker.SetLink( aTrack->Clone() );
+ s_ItemsListPicker.PushItem( picker );
+
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ TRACK* draggedtrack = g_DragSegmentList[ii].m_Track;
+ picker.SetItem( draggedtrack );
+ picker.SetLink( draggedtrack->Clone() );
+ s_ItemsListPicker.PushItem( picker );
+ draggedtrack = (TRACK*) picker.GetLink();
+ draggedtrack->SetStatus( 0 );
+ draggedtrack->ClearFlags();
+ }
+
+ s_LastPos = PosInit;
+ m_canvas->SetMouseCapture( Show_MoveNode, Abort_MoveTrack );
+
+ GetBoard()->SetHighLightNet( aTrack->GetNetCode() );
+ GetBoard()->HighLightON();
+
+ GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() );
+ m_canvas->CallMouseCapture( aDC, wxDefaultPosition, true );
+
+ UndrawAndMarkSegmentsToDrag( m_canvas, aDC );
+}
+
+
+void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC )
+{
+ TRACK* TrackToStartPoint = NULL;
+ TRACK* TrackToEndPoint = NULL;
+ bool error = false;
+
+ if( !track )
+ return;
+
+ // TODO: Use cleanup functions to merge collinear segments if track
+ // is connected to a collinear segment.
+
+ s_StartSegmentPresent = s_EndSegmentPresent = true;
+
+ if( ( track->start == NULL ) || ( track->start->Type() == PCB_TRACE_T ) )
+ TrackToStartPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START, true, false );
+
+ // Test if more than one segment is connected to this point
+ if( TrackToStartPoint )
+ {
+ TrackToStartPoint->SetState( BUSY, true );
+
+ if( ( TrackToStartPoint->Type() == PCB_VIA_T )
+ || track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START, true, false ) )
+ error = true;
+
+ TrackToStartPoint->SetState( BUSY, false );
+ }
+
+ if( ( track->end == NULL ) || ( track->end->Type() == PCB_TRACE_T ) )
+ TrackToEndPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END, true, false );
+
+ // Test if more than one segment is connected to this point
+ if( TrackToEndPoint )
+ {
+ TrackToEndPoint->SetState( BUSY, true );
+
+ if( (TrackToEndPoint->Type() == PCB_VIA_T)
+ || track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END, true, false ) )
+ error = true;
+
+ TrackToEndPoint->SetState( BUSY, false );
+ }
+
+ if( error )
+ {
+ DisplayError( this,
+ _( "Unable to drag this segment: too many segments connected" ) );
+ return;
+ }
+
+ if( !TrackToStartPoint || ( TrackToStartPoint->Type() != PCB_TRACE_T ) )
+ s_StartSegmentPresent = false;
+
+ if( !TrackToEndPoint || ( TrackToEndPoint->Type() != PCB_TRACE_T ) )
+ s_EndSegmentPresent = false;
+
+ // Change high light net: the new one will be highlighted
+ GetBoard()->PushHighLight();
+
+ if( GetBoard()->IsHighLightNetON() )
+ HighLight( DC );
+
+ EraseDragList();
+
+ track->SetFlags( IS_DRAGGED );
+
+ if( TrackToStartPoint )
+ {
+ STATUS_FLAGS flag = STARTPOINT;
+
+ if( track->GetStart() != TrackToStartPoint->GetStart() )
+ flag = ENDPOINT;
+
+ AddSegmentToDragList( flag, TrackToStartPoint );
+ track->SetFlags( STARTPOINT );
+ }
+
+ if( TrackToEndPoint )
+ {
+ STATUS_FLAGS flag = STARTPOINT;
+
+ if( track->GetEnd() != TrackToEndPoint->GetStart() )
+ flag = ENDPOINT;
+
+ AddSegmentToDragList( flag, TrackToEndPoint );
+ track->SetFlags( ENDPOINT );
+ }
+
+ AddSegmentToDragList( track->GetFlags(), track );
+
+ UndrawAndMarkSegmentsToDrag( m_canvas, DC );
+
+
+ PosInit = GetCrossHairPosition();
+ s_LastPos = GetCrossHairPosition();
+ m_canvas->SetMouseCapture( Show_Drag_Track_Segment_With_Cte_Slope, Abort_MoveTrack );
+
+ GetBoard()->SetHighLightNet( track->GetNetCode() );
+ GetBoard()->HighLightON();
+ GetBoard()->DrawHighLight( m_canvas, DC, GetBoard()->GetHighLightNetCode() );
+
+ // Prepare the Undo command
+ ITEM_PICKER picker( NULL, UR_CHANGED );
+
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ TRACK* draggedtrack = g_DragSegmentList[ii].m_Track;
+ picker.SetItem( draggedtrack);
+ picker.SetLink ( draggedtrack->Clone() );
+ s_ItemsListPicker.PushItem( picker );
+ draggedtrack = (TRACK*) picker.GetLink();
+ draggedtrack->SetStatus( 0 );
+ draggedtrack->ClearFlags();
+ }
+
+ if( !InitialiseDragParameters() )
+ {
+ DisplayError( this, _( "Unable to drag this segment: two collinear segments" ) );
+ m_canvas->SetMouseCaptureCallback( NULL );
+ Abort_MoveTrack( m_canvas, DC );
+ return;
+ }
+}
+
+
+// Place a dragged (or moved) track segment or via
+bool PCB_EDIT_FRAME::PlaceDraggedOrMovedTrackSegment( TRACK* Track, wxDC* DC )
+{
+ int errdrc;
+
+ if( Track == NULL )
+ return false;
+
+ int current_net_code = Track->GetNetCode();
+
+ // DRC control:
+ if( g_Drc_On )
+ {
+ errdrc = m_drc->Drc( Track, GetBoard()->m_Track );
+
+ if( errdrc == BAD_DRC )
+ return false;
+
+ // Redraw the dragged segments
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ errdrc = m_drc->Drc( g_DragSegmentList[ii].m_Track, GetBoard()->m_Track );
+
+ if( errdrc == BAD_DRC )
+ return false;
+ }
+ }
+
+ // DRC Ok: place track segments
+ Track->ClearFlags();
+ Track->SetState( IN_EDIT, false );
+
+ // Draw dragged tracks
+ for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+ {
+ Track = g_DragSegmentList[ii].m_Track;
+ Track->SetState( IN_EDIT, false );
+ Track->ClearFlags();
+
+ /* Test the connections modified by the move
+ * (only pad connection must be tested, track connection will be
+ * tested by TestNetConnection() ) */
+ LSET layerMask( Track->GetLayer() );
+
+ Track->start = GetBoard()->GetPadFast( Track->GetStart(), layerMask );
+
+ if( Track->start )
+ Track->SetState( BEGIN_ONPAD, true );
+ else
+ Track->SetState( BEGIN_ONPAD, false );
+
+ Track->end = GetBoard()->GetPadFast( Track->GetEnd(), layerMask );
+
+ if( Track->end )
+ Track->SetState( END_ONPAD, true );
+ else
+ Track->SetState( END_ONPAD, false );
+ }
+
+ EraseDragList();
+
+ SaveCopyInUndoList( s_ItemsListPicker, UR_UNSPECIFIED );
+ s_ItemsListPicker.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
+
+ GetBoard()->PopHighLight();
+
+ OnModify();
+ m_canvas->SetMouseCapture( NULL, NULL );
+
+ if( current_net_code > 0 )
+ TestNetConnection( DC, current_net_code );
+
+ m_canvas->Refresh();
+
+ return true;
+}
diff --git a/pcbnew/muonde.cpp b/pcbnew/muonde.cpp
new file mode 100644
index 0000000..4e551b3
--- /dev/null
+++ b/pcbnew/muonde.cpp
@@ -0,0 +1,1105 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file muonde.cpp
+ * @brief Microwave pcb layout code.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <trigo.h>
+#include <kicad_string.h>
+#include <gestfich.h>
+#include <wxPcbStruct.h>
+#include <dialog_helpers.h>
+#include <richio.h>
+#include <filter_reader.h>
+#include <gr_basic.h>
+#include <macros.h>
+#include <base_units.h>
+#include <validators.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+
+#include <pcbnew.h>
+
+static std::vector< wxRealPoint > PolyEdges;
+static double ShapeScaleX, ShapeScaleY;
+static wxSize ShapeSize;
+static int PolyShapeType;
+
+
+static void Exit_Self( EDA_DRAW_PANEL* aPanel, wxDC* aDC );
+static void gen_arc( std::vector <wxPoint>& aBuffer,
+ wxPoint aStartPoint,
+ wxPoint aCenter,
+ int a_ArcAngle );
+
+static void ShowBoundingBoxMicroWaveInductor( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC,
+ const wxPoint& aPosition,
+ bool aErase );
+
+
+int BuildCornersList_S_Shape( std::vector <wxPoint>& aBuffer,
+ wxPoint aStartPoint, wxPoint aEndPoint,
+ int aLength, int aWidth );
+
+class MUWAVE_INDUCTOR
+{
+public:
+ wxPoint m_Start;
+ wxPoint m_End;
+ wxSize m_Size;
+ int m_lenght; // full length trace.
+ int m_Width; // Trace width.
+ // A flag set to true when mu-wave inductor is being created
+ bool m_Flag;
+};
+
+// An instance of MUWAVE_INDUCTOR temporary used during mu-wave inductor creation
+static MUWAVE_INDUCTOR s_inductor_pattern;
+
+
+/* This function shows on screen the bounding box of the inductor that will be
+ * created at the end of the build inductor process
+ */
+static void ShowBoundingBoxMicroWaveInductor( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase )
+{
+ /* Calculate the orientation and size of the box containing the inductor:
+ * the box is a rectangle with height = lenght/2
+ * the shape is defined by a rectangle, nor necessary horizontal or vertical
+ */
+ GRSetDrawMode( aDC, GR_XOR );
+
+ wxPoint poly[5];
+ wxPoint pt = s_inductor_pattern.m_End - s_inductor_pattern.m_Start;
+ double angle = -ArcTangente( pt.y, pt.x );
+ int len = KiROUND( EuclideanNorm( pt ) );
+
+ // calculate corners
+ pt.x = 0; pt.y = len / 4;
+ RotatePoint( &pt, angle );
+ poly[0] = s_inductor_pattern.m_Start + pt;
+ poly[1] = s_inductor_pattern.m_End + pt;
+ pt.x = 0; pt.y = -len / 4;
+ RotatePoint( &pt, angle );
+ poly[2] = s_inductor_pattern.m_End + pt;
+ poly[3] = s_inductor_pattern.m_Start + pt;
+ poly[4] = poly[0];
+
+ if( aErase )
+ {
+ GRPoly( aPanel->GetClipBox(), aDC, 5, poly, false, 0, YELLOW, YELLOW );
+ }
+
+ s_inductor_pattern.m_End = aPanel->GetParent()->GetCrossHairPosition();
+ pt = s_inductor_pattern.m_End - s_inductor_pattern.m_Start;
+ angle = -ArcTangente( pt.y, pt.x );
+ len = KiROUND( EuclideanNorm( pt ) );
+
+ // calculate new corners
+ pt.x = 0; pt.y = len / 4;
+ RotatePoint( &pt, angle );
+ poly[0] = s_inductor_pattern.m_Start + pt;
+ poly[1] = s_inductor_pattern.m_End + pt;
+ pt.x = 0; pt.y = -len / 4;
+ RotatePoint( &pt, angle );
+ poly[2] = s_inductor_pattern.m_End + pt;
+ poly[3] = s_inductor_pattern.m_Start + pt;
+ poly[4] = poly[0];
+
+ GRPoly( aPanel->GetClipBox(), aDC, 5, poly, false, 0, YELLOW, YELLOW );
+}
+
+
+void Exit_Self( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
+{
+ if( aPanel->IsMouseCaptured() )
+ aPanel->CallMouseCapture( aDC, wxDefaultPosition, false );
+
+ s_inductor_pattern.m_Flag = false;
+ aPanel->SetMouseCapture( NULL, NULL );
+}
+
+
+void PCB_EDIT_FRAME::Begin_Self( wxDC* DC )
+{
+ if( s_inductor_pattern.m_Flag )
+ {
+ Genere_Self( DC );
+ return;
+ }
+
+ s_inductor_pattern.m_Start = GetCrossHairPosition();
+ s_inductor_pattern.m_End = s_inductor_pattern.m_Start;
+
+ s_inductor_pattern.m_Flag = true;
+
+ // Update the initial coordinates.
+ GetScreen()->m_O_Curseur = GetCrossHairPosition();
+ UpdateStatusBar();
+
+ m_canvas->SetMouseCapture( ShowBoundingBoxMicroWaveInductor, Exit_Self );
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+}
+
+
+MODULE* PCB_EDIT_FRAME::Genere_Self( wxDC* DC )
+{
+ D_PAD* pad;
+ int ll;
+ wxString msg;
+
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ m_canvas->SetMouseCapture( NULL, NULL );
+
+ if( s_inductor_pattern.m_Flag == false )
+ {
+ DisplayError( this, wxT( "Starting point not init.." ) );
+ return NULL;
+ }
+
+ s_inductor_pattern.m_Flag = false;
+
+ s_inductor_pattern.m_End = GetCrossHairPosition();
+
+ wxPoint pt = s_inductor_pattern.m_End - s_inductor_pattern.m_Start;
+ int min_len = KiROUND( EuclideanNorm( pt ) );
+ s_inductor_pattern.m_lenght = min_len;
+
+ // Enter the desired length.
+ msg = StringFromValue( g_UserUnit, s_inductor_pattern.m_lenght );
+ wxTextEntryDialog dlg( this, wxEmptyString, _( "Length of Trace:" ), msg );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return NULL; // canceled by user
+
+ msg = dlg.GetValue();
+ s_inductor_pattern.m_lenght = ValueFromString( g_UserUnit, msg );
+
+ // Control values (ii = minimum length)
+ if( s_inductor_pattern.m_lenght < min_len )
+ {
+ DisplayError( this, _( "Requested length < minimum length" ) );
+ return NULL;
+ }
+
+ // Calculate the elements.
+ s_inductor_pattern.m_Width = GetDesignSettings().GetCurrentTrackWidth();
+
+ std::vector <wxPoint> buffer;
+ ll = BuildCornersList_S_Shape( buffer, s_inductor_pattern.m_Start,
+ s_inductor_pattern.m_End, s_inductor_pattern.m_lenght,
+ s_inductor_pattern.m_Width );
+
+ if( !ll )
+ {
+ DisplayError( this, _( "Requested length too large" ) );
+ return NULL;
+ }
+
+ // Generate footprint. the value is also used as footprint name.
+ msg.Empty();
+ wxTextEntryDialog cmpdlg( this, wxEmptyString, _( "Component Value:" ), msg );
+ cmpdlg.SetTextValidator( FILE_NAME_CHAR_VALIDATOR( &msg ) );
+
+ if( ( cmpdlg.ShowModal() != wxID_OK ) || msg.IsEmpty() )
+ return NULL; // Aborted by user
+
+ MODULE* module = CreateNewModule( msg );
+
+ // here the module is already in the BOARD, CreateNewModule() does that.
+ module->SetFPID( FPID( std::string( "mw_inductor" ) ) );
+ module->SetAttributes( MOD_VIRTUAL | MOD_CMS );
+ module->ClearFlags();
+ module->SetPosition( s_inductor_pattern.m_End );
+
+ // Generate segments
+ for( unsigned jj = 1; jj < buffer.size(); jj++ )
+ {
+ EDGE_MODULE* PtSegm;
+ PtSegm = new EDGE_MODULE( module );
+ PtSegm->SetStart( buffer[jj - 1] );
+ PtSegm->SetEnd( buffer[jj] );
+ PtSegm->SetWidth( s_inductor_pattern.m_Width );
+ PtSegm->SetLayer( module->GetLayer() );
+ PtSegm->SetShape( S_SEGMENT );
+ PtSegm->SetStart0( PtSegm->GetStart() - module->GetPosition() );
+ PtSegm->SetEnd0( PtSegm->GetEnd() - module->GetPosition() );
+ module->GraphicalItems().PushBack( PtSegm );
+ }
+
+ // Place a pad on each end of coil.
+ pad = new D_PAD( module );
+
+ module->Pads().PushFront( pad );
+
+ pad->SetPadName( wxT( "1" ) );
+ pad->SetPosition( s_inductor_pattern.m_End );
+ pad->SetPos0( pad->GetPosition() - module->GetPosition() );
+
+ pad->SetSize( wxSize( s_inductor_pattern.m_Width, s_inductor_pattern.m_Width ) );
+
+ pad->SetLayerSet( LSET( module->GetLayer() ) );
+ pad->SetAttribute( PAD_ATTRIB_SMD );
+ pad->SetShape( PAD_SHAPE_CIRCLE );
+
+ D_PAD* newpad = new D_PAD( *pad );
+
+ module->Pads().Insert( newpad, pad->Next() );
+
+ pad = newpad;
+ pad->SetPadName( wxT( "2" ) );
+ pad->SetPosition( s_inductor_pattern.m_Start );
+ pad->SetPos0( pad->GetPosition() - module->GetPosition() );
+
+ // Modify text positions.
+ SetMsgPanel( module );
+
+ wxPoint refPos( ( s_inductor_pattern.m_Start.x + s_inductor_pattern.m_End.x ) / 2,
+ ( s_inductor_pattern.m_Start.y + s_inductor_pattern.m_End.y ) / 2 );
+
+ wxPoint valPos = refPos;
+
+ refPos.y -= module->Reference().GetSize().y;
+ module->Reference().SetPosition( refPos );
+ valPos.y += module->Value().GetSize().y;
+ module->Value().SetPosition( valPos );
+
+ module->CalculateBoundingBox();
+ module->Draw( m_canvas, DC, GR_OR );
+
+ return module;
+}
+
+
+/**
+ * Function gen_arc
+ * generates an arc using arc approximation by lines:
+ * Center aCenter
+ * Angle "angle" (in 0.1 deg)
+ * @param aBuffer = a buffer to store points.
+ * @param aStartPoint = starting point of arc.
+ * @param aCenter = arc centre.
+ * @param a_ArcAngle = arc length in 0.1 degrees.
+ */
+static void gen_arc( std::vector <wxPoint>& aBuffer,
+ wxPoint aStartPoint,
+ wxPoint aCenter,
+ int a_ArcAngle )
+{
+ #define SEGM_COUNT_PER_360DEG 16
+ wxPoint first_point = aStartPoint - aCenter;
+ int seg_count = ( ( abs( a_ArcAngle ) ) * SEGM_COUNT_PER_360DEG ) / 3600;
+
+ if( seg_count == 0 )
+ seg_count = 1;
+
+ double increment_angle = (double) a_ArcAngle * M_PI / 1800 / seg_count;
+
+ // Creates nb_seg point to approximate arc by segments:
+ for( int ii = 1; ii <= seg_count; ii++ )
+ {
+ double rot_angle = increment_angle * ii;
+ double fcos = cos( rot_angle );
+ double fsin = sin( rot_angle );
+ wxPoint currpt;
+
+ // Rotate current point:
+ currpt.x = KiROUND( ( first_point.x * fcos + first_point.y * fsin ) );
+ currpt.y = KiROUND( ( first_point.y * fcos - first_point.x * fsin ) );
+
+ wxPoint corner = aCenter + currpt;
+ aBuffer.push_back( corner );
+ }
+}
+
+
+/**
+ * Function BuildCornersList_S_Shape
+ * Create a path like a S-shaped coil
+ * @param aBuffer = a buffer where to store points (ends of segments)
+ * @param aStartPoint = starting point of the path
+ * @param aEndPoint = ending point of the path
+ * @param aLength = full lenght of the path
+ * @param aWidth = segment width
+ */
+int BuildCornersList_S_Shape( std::vector <wxPoint>& aBuffer,
+ wxPoint aStartPoint, wxPoint aEndPoint,
+ int aLength, int aWidth )
+{
+/* We must determine:
+ * segm_count = number of segments perpendicular to the direction
+ * segm_len = length of a strand
+ * radius = radius of rounded parts of the coil
+ * stubs_len = length of the 2 stubs( segments parallel to the direction)
+ * connecting the start point to the start point of the S shape
+ * and the ending point to the end point of the S shape
+ * The equations are (assuming the area size of the entire shape is Size:
+ * Size.x = 2 * radius + segm_len
+ * Size.y = (segm_count + 2 ) * 2 * radius + 2 * stubs_len
+ * s_inductor_pattern.m_lenght = 2 * delta // connections to the coil
+ * + (segm_count-2) * segm_len // length of the strands except 1st and last
+ * + (segm_count) * (PI * radius) // length of rounded
+ * segm_len + / 2 - radius * 2) // length of 1st and last bit
+ *
+ * The constraints are:
+ * segm_count >= 2
+ * radius < m_Size.x
+ * Size.y = (radius * 4) + (2 * stubs_len)
+ * segm_len > radius * 2
+ *
+ * The calculation is conducted in the following way:
+ * first:
+ * segm_count = 2
+ * radius = 4 * Size.x (arbitrarily fixed value)
+ * Then:
+ * Increasing the number of segments to the desired length
+ * (radius decreases if necessary)
+ */
+ wxSize size;
+
+ // This scale factor adjusts the arc length to handle
+ // the arc to segment approximation.
+ // because we use SEGM_COUNT_PER_360DEG segment to approximate a circle,
+ // the trace len must be corrected when calculated using arcs
+ // this factor adjust calculations and must be changed if SEGM_COUNT_PER_360DEG is modified
+ // because trace using segment is shorter the corresponding arc
+ // ADJUST_SIZE is the ratio between tline len and the arc len for an arc
+ // of 360/ADJUST_SIZE angle
+ #define ADJUST_SIZE 0.988
+
+ wxPoint pt = aEndPoint - aStartPoint;
+ double angle = -ArcTangente( pt.y, pt.x );
+ int min_len = KiROUND( EuclideanNorm( pt ) );
+ int segm_len = 0; // length of segments
+ int full_len; // full len of shape (sum of lenght of all segments + arcs)
+
+
+ /* Note: calculations are made for a vertical coil (more easy calculations)
+ * and after points are rotated to their actual position
+ * So the main direction is the Y axis.
+ * the 2 stubs are on the Y axis
+ * the others segments are parallel to the X axis.
+ */
+
+ // Calculate the size of area (for a vertical shape)
+ size.x = min_len / 2;
+ size.y = min_len;
+
+ // Choose a reasonable starting value for the radius of the arcs.
+ int radius = std::min( aWidth * 5, size.x / 4 );
+
+ int segm_count; // number of full len segments
+ // the half size segments (first and last segment) are not counted here
+ int stubs_len = 0; // lenght of first or last segment (half size of others segments)
+
+ for( segm_count = 0; ; segm_count++ )
+ {
+ stubs_len = ( size.y - ( radius * 2 * (segm_count + 2 ) ) ) / 2;
+
+ if( stubs_len < size.y / 10 ) // Reduce radius.
+ {
+ stubs_len = size.y / 10;
+ radius = ( size.y - (2 * stubs_len) ) / ( 2 * (segm_count + 2) );
+
+ if( radius < aWidth ) // Radius too small.
+ {
+ // Unable to create line: Requested length value is too large for room
+ return 0;
+ }
+ }
+
+ segm_len = size.x - ( radius * 2 );
+ full_len = 2 * stubs_len; // Length of coil connections.
+ full_len += segm_len * segm_count; // Length of full length segments.
+ full_len += KiROUND( ( segm_count + 2 ) * M_PI * ADJUST_SIZE * radius ); // Ard arcs len
+ full_len += segm_len - (2 * radius); // Length of first and last segments
+ // (half size segments len = segm_len/2 - radius).
+
+ if( full_len >= aLength )
+ break;
+ }
+
+ // Adjust len by adjusting segm_len:
+ int delta_size = full_len - aLength;
+
+ // reduce len of the segm_count segments + 2 half size segments (= 1 full size segment)
+ segm_len -= delta_size / (segm_count + 1);
+
+ // Generate first line (the first stub) and first arc (90 deg arc)
+ pt = aStartPoint;
+ aBuffer.push_back( pt );
+ pt.y += stubs_len;
+ aBuffer.push_back( pt );
+
+ wxPoint centre = pt;
+ centre.x -= radius;
+ gen_arc( aBuffer, pt, centre, -900 );
+ pt = aBuffer.back();
+
+ int half_size_seg_len = segm_len / 2 - radius;
+
+ if( half_size_seg_len )
+ {
+ pt.x -= half_size_seg_len;
+ aBuffer.push_back( pt );
+ }
+
+ // Create shape.
+ int ii;
+ int sign = 1;
+ segm_count += 1; // increase segm_count to create the last half_size segment
+
+ for( ii = 0; ii < segm_count; ii++ )
+ {
+ int arc_angle;
+
+ if( ii & 1 ) // odd order arcs are greater than 0
+ sign = -1;
+ else
+ sign = 1;
+
+ arc_angle = 1800 * sign;
+ centre = pt;
+ centre.y += radius;
+ gen_arc( aBuffer, pt, centre, arc_angle );
+ pt = aBuffer.back();
+ pt.x += segm_len * sign;
+ aBuffer.push_back( pt );
+ }
+
+ // The last point is false:
+ // it is the end of a full size segment, but must be
+ // the end of the second half_size segment. Change it.
+ sign *= -1;
+ aBuffer.back().x = aStartPoint.x + radius * sign;
+
+ // create last arc
+ pt = aBuffer.back();
+ centre = pt;
+ centre.y += radius;
+ gen_arc( aBuffer, pt, centre, 900 * sign );
+ aBuffer.back();
+
+ // Rotate point
+ angle += 900;
+
+ for( unsigned jj = 0; jj < aBuffer.size(); jj++ )
+ {
+ RotatePoint( &aBuffer[jj].x, &aBuffer[jj].y, aStartPoint.x, aStartPoint.y, angle );
+ }
+
+ // push last point (end point)
+ aBuffer.push_back( aEndPoint );
+
+ return 1;
+}
+
+
+MODULE* PCB_EDIT_FRAME::CreateMuWaveBaseFootprint( const wxString& aValue,
+ int aTextSize, int aPadCount )
+{
+ MODULE* module = CreateNewModule( aValue );
+
+ if( aTextSize > 0 )
+ {
+ module->Reference().SetSize( wxSize( aTextSize, aTextSize ) );
+ module->Reference().SetThickness( aTextSize/5 );
+ module->Value().SetSize( wxSize( aTextSize, aTextSize ) );
+ module->Value().SetThickness( aTextSize/5 );
+ }
+
+ // Create 2 pads used in gaps and stubs. The gap is between these 2 pads
+ // the stub is the pad 2
+ wxString Line;
+ int pad_num = 1;
+
+ while( aPadCount-- )
+ {
+ D_PAD* pad = new D_PAD( module );
+
+ module->Pads().PushFront( pad );
+
+ int tw = GetDesignSettings().GetCurrentTrackWidth();
+ pad->SetSize( wxSize( tw, tw ) );
+
+ pad->SetPosition( module->GetPosition() );
+ pad->SetShape( PAD_SHAPE_RECT );
+ pad->SetAttribute( PAD_ATTRIB_SMD );
+ pad->SetLayerSet( F_Cu );
+
+ Line.Printf( wxT( "%d" ), pad_num );
+ pad->SetPadName( Line );
+ pad_num++;
+ }
+
+ return module;
+}
+
+
+MODULE* PCB_EDIT_FRAME::Create_MuWaveComponent( int shape_type )
+{
+ int oX;
+ D_PAD* pad;
+ MODULE* module;
+ wxString msg, cmp_name;
+ int pad_count = 2;
+ int angle = 0;
+ // Ref and value text size (O = use board default value.
+ // will be set to a value depending on the footprint size, if possible
+ int text_size = 0;
+
+ // Enter the size of the gap or stub
+ int gap_size = GetDesignSettings().GetCurrentTrackWidth();
+
+ switch( shape_type )
+ {
+ case 0:
+ msg = _( "Gap" );
+ cmp_name = wxT( "muwave_gap" );
+ text_size = gap_size;
+ break;
+
+ case 1:
+ msg = _( "Stub" );
+ cmp_name = wxT( "muwave_stub" );
+ text_size = gap_size;
+ pad_count = 2;
+ break;
+
+ case 2:
+ msg = _( "Arc Stub" );
+ cmp_name = wxT( "muwave_arcstub" );
+ pad_count = 1;
+ break;
+
+ default:
+ msg = wxT( "???" );
+ break;
+ }
+
+ wxString value = StringFromValue( g_UserUnit, gap_size );
+ wxTextEntryDialog dlg( this, msg, _( "Create microwave module" ), value );
+
+ if( dlg.ShowModal() != wxID_OK )
+ {
+ m_canvas->MoveCursorToCrossHair();
+ return NULL; // cancelled by user
+ }
+
+ value = dlg.GetValue();
+ gap_size = ValueFromString( g_UserUnit, value );
+
+ bool abort = false;
+
+ if( shape_type == 2 )
+ {
+ double fcoeff = 10.0, fval;
+ msg.Printf( wxT( "%3.1f" ), angle / fcoeff );
+ wxTextEntryDialog angledlg( this, _( "Angle in degrees:" ),
+ _( "Create microwave module" ), msg );
+
+ if( angledlg.ShowModal() != wxID_OK )
+ {
+ m_canvas->MoveCursorToCrossHair();
+ return NULL; // cancelled by user
+ }
+
+ msg = angledlg.GetValue();
+
+ if( !msg.ToDouble( &fval ) )
+ {
+ DisplayError( this, _( "Incorrect number, abort" ) );
+ abort = true;
+ }
+
+ angle = std::abs( KiROUND( fval * fcoeff ) );
+
+ if( angle > 1800 )
+ angle = 1800;
+ }
+
+ if( abort )
+ {
+ m_canvas->MoveCursorToCrossHair();
+ return NULL;
+ }
+
+ module = CreateMuWaveBaseFootprint( cmp_name, text_size, pad_count );
+ pad = module->Pads();
+
+ switch( shape_type )
+ {
+ case 0: //Gap :
+ oX = -( gap_size + pad->GetSize().x ) / 2;
+ pad->SetX0( oX );
+
+ pad->SetX( pad->GetPos0().x + pad->GetPosition().x );
+
+ pad = pad->Next();
+
+ pad->SetX0( oX + gap_size + pad->GetSize().x );
+ pad->SetX( pad->GetPos0().x + pad->GetPosition().x );
+ break;
+
+ case 1: //Stub :
+ pad->SetPadName( wxT( "1" ) );
+ pad = pad->Next();
+ pad->SetY0( -( gap_size + pad->GetSize().y ) / 2 );
+ pad->SetSize( wxSize( pad->GetSize().x, gap_size ) );
+ pad->SetY( pad->GetPos0().y + pad->GetPosition().y );
+ break;
+
+ case 2: // Arc Stub created by a polygonal approach:
+ {
+ EDGE_MODULE* edge = new EDGE_MODULE( module );
+ module->GraphicalItems().PushFront( edge );
+
+ edge->SetShape( S_POLYGON );
+ edge->SetLayer( F_Cu );
+
+ int numPoints = (angle / 50) + 3; // Note: angles are in 0.1 degrees
+ std::vector<wxPoint>& polyPoints = edge->GetPolyPoints();
+ polyPoints.reserve( numPoints );
+
+ edge->m_Start0.y = -pad->GetSize().y / 2;
+
+ polyPoints.push_back( wxPoint( 0, 0 ) );
+
+ int theta = -angle / 2;
+
+ for( int ii = 1; ii<numPoints - 1; ii++ )
+ {
+ wxPoint pt( 0, -gap_size );
+
+ RotatePoint( &pt.x, &pt.y, theta );
+
+ polyPoints.push_back( pt );
+
+ theta += 50;
+
+ if( theta > angle / 2 )
+ theta = angle / 2;
+ }
+
+ // Close the polygon:
+ polyPoints.push_back( polyPoints[0] );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ module->CalculateBoundingBox();
+ GetBoard()->m_Status_Pcb = 0;
+ OnModify();
+ return module;
+}
+
+
+/**************** Polygon Shapes ***********************/
+
+enum id_mw_cmd {
+ ID_READ_SHAPE_FILE = 1000
+};
+
+
+/* Setting polynomial form parameters
+ */
+class MWAVE_POLYGONAL_SHAPE_DLG : public wxDialog
+{
+private:
+ PCB_EDIT_FRAME* m_Parent;
+ wxRadioBox* m_ShapeOptionCtrl;
+ EDA_SIZE_CTRL* m_SizeCtrl;
+
+public:
+ MWAVE_POLYGONAL_SHAPE_DLG( PCB_EDIT_FRAME* parent, const wxPoint& pos );
+ ~MWAVE_POLYGONAL_SHAPE_DLG() { };
+
+private:
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+
+ /**
+ * Function ReadDataShapeDescr
+ * read a description shape file
+ * File format is
+ * Unit=MM
+ * XScale=271.501
+ * YScale=1.00133
+ *
+ * $COORD
+ * 0 0.6112600148417837
+ * 0.001851851851851852 0.6104800531118608
+ * ....
+ * $ENDCOORD
+ *
+ * Each line is the X Y coord (normalized units from 0 to 1)
+ */
+ void ReadDataShapeDescr( wxCommandEvent& event );
+ void AcceptOptions( wxCommandEvent& event );
+
+ DECLARE_EVENT_TABLE()
+};
+
+
+BEGIN_EVENT_TABLE( MWAVE_POLYGONAL_SHAPE_DLG, wxDialog )
+ EVT_BUTTON( wxID_OK, MWAVE_POLYGONAL_SHAPE_DLG::OnOkClick )
+ EVT_BUTTON( wxID_CANCEL, MWAVE_POLYGONAL_SHAPE_DLG::OnCancelClick )
+ EVT_BUTTON( ID_READ_SHAPE_FILE, MWAVE_POLYGONAL_SHAPE_DLG::ReadDataShapeDescr )
+END_EVENT_TABLE()
+
+
+MWAVE_POLYGONAL_SHAPE_DLG::MWAVE_POLYGONAL_SHAPE_DLG( PCB_EDIT_FRAME* parent,
+ const wxPoint& framepos ) :
+ wxDialog( parent, -1, _( "Complex shape" ), framepos, wxSize( 350, 280 ),
+ wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )
+{
+ m_Parent = parent;
+
+ PolyEdges.clear();
+
+ wxBoxSizer* MainBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+ SetSizer( MainBoxSizer );
+ wxBoxSizer* LeftBoxSizer = new wxBoxSizer( wxVERTICAL );
+ wxBoxSizer* RightBoxSizer = new wxBoxSizer( wxVERTICAL );
+ MainBoxSizer->Add( LeftBoxSizer, 0, wxGROW | wxALL, 5 );
+ MainBoxSizer->Add( RightBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
+
+ wxButton* Button = new wxButton( this, wxID_OK, _( "OK" ) );
+ RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
+
+ Button = new wxButton( this, wxID_CANCEL, _( "Cancel" ) );
+ RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
+
+ Button = new wxButton( this, ID_READ_SHAPE_FILE,
+ _( "Read Shape Description File..." ) );
+ RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
+
+ wxString shapelist[3] =
+ {
+ _( "Normal" ), _( "Symmetrical" ), _( "Mirrored" )
+ };
+
+ m_ShapeOptionCtrl = new wxRadioBox( this, -1, _( "Shape Option" ),
+ wxDefaultPosition, wxDefaultSize, 3,
+ shapelist, 1,
+ wxRA_SPECIFY_COLS );
+ LeftBoxSizer->Add( m_ShapeOptionCtrl, 0, wxGROW | wxALL, 5 );
+
+ m_SizeCtrl = new EDA_SIZE_CTRL( this, _( "Size" ), ShapeSize, g_UserUnit, LeftBoxSizer );
+
+ GetSizer()->SetSizeHints( this );
+}
+
+
+void MWAVE_POLYGONAL_SHAPE_DLG::OnCancelClick( wxCommandEvent& event )
+{
+ PolyEdges.clear();
+ EndModal( wxID_CANCEL );
+}
+
+
+void MWAVE_POLYGONAL_SHAPE_DLG::OnOkClick( wxCommandEvent& event )
+{
+ ShapeSize = m_SizeCtrl->GetValue();
+ PolyShapeType = m_ShapeOptionCtrl->GetSelection();
+ EndModal( wxID_OK );
+}
+
+
+void MWAVE_POLYGONAL_SHAPE_DLG::ReadDataShapeDescr( wxCommandEvent& event )
+{
+ static wxString lastpath; // To remember the last open path during a session
+ wxString mask = wxT( "*.*" );
+
+ wxString FullFileName = EDA_FILE_SELECTOR( _( "Read descr shape file" ),
+ lastpath, FullFileName,
+ wxEmptyString, mask,
+ this, wxFD_OPEN, true );
+ if( FullFileName.IsEmpty() )
+ return;
+
+ wxFileName fn( FullFileName );
+ lastpath = fn.GetPath();
+ PolyEdges.clear();
+
+ FILE* File = wxFopen( FullFileName, wxT( "rt" ) );
+
+ if( File == NULL )
+ {
+ DisplayError( this, _( "File not found" ) );
+ return;
+ }
+
+ double unitconv = IU_PER_MM;
+ ShapeScaleX = ShapeScaleY = 1.0;
+
+ FILE_LINE_READER fileReader( File, FullFileName );
+ FILTER_READER reader( fileReader );
+
+ LOCALE_IO toggle;
+
+ while( reader.ReadLine() )
+ {
+ char* Line = reader.Line();
+ char* param1 = strtok( Line, " =\n\r" );
+ char* param2 = strtok( NULL, " \t\n\r" );
+
+ if( strnicmp( param1, "Unit", 4 ) == 0 )
+ {
+ if( strnicmp( param2, "inch", 4 ) == 0 )
+ unitconv = IU_PER_MILS*1000;
+
+ if( strnicmp( param2, "mm", 2 ) == 0 )
+ unitconv = IU_PER_MM;
+ }
+
+ if( strnicmp( param1, "$ENDCOORD", 8 ) == 0 )
+ break;
+
+ if( strnicmp( param1, "$COORD", 6 ) == 0 )
+ {
+ while( reader.ReadLine() )
+ {
+ Line = reader.Line();
+ param1 = strtok( Line, " \t\n\r" );
+ param2 = strtok( NULL, " \t\n\r" );
+
+ if( strnicmp( param1, "$ENDCOORD", 8 ) == 0 )
+ break;
+
+ wxRealPoint coord( atof( param1 ), atof( param2 ) );
+ PolyEdges.push_back( coord );
+ }
+ }
+
+ if( strnicmp( Line, "XScale", 6 ) == 0 )
+ ShapeScaleX = atof( param2 );
+
+ if( strnicmp( Line, "YScale", 6 ) == 0 )
+ ShapeScaleY = atof( param2 );
+ }
+
+ ShapeScaleX *= unitconv;
+ ShapeScaleY *= unitconv;
+
+ m_SizeCtrl->SetValue( (int) ShapeScaleX, (int) ShapeScaleY );
+}
+
+
+MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape()
+{
+ D_PAD* pad1, * pad2;
+ MODULE* module;
+ wxString cmp_name;
+ int pad_count = 2;
+ EDGE_MODULE* edge;
+
+ MWAVE_POLYGONAL_SHAPE_DLG dlg( this, wxPoint( -1, -1 ) );
+
+ int ret = dlg.ShowModal();
+
+ m_canvas->MoveCursorToCrossHair();
+
+ if( ret != wxID_OK )
+ {
+ PolyEdges.clear();
+ return NULL;
+ }
+
+ if( PolyShapeType == 2 ) // mirrored
+ ShapeScaleY = -ShapeScaleY;
+
+ ShapeSize.x = KiROUND( ShapeScaleX );
+ ShapeSize.y = KiROUND( ShapeScaleY );
+
+ if( ( ShapeSize.x ) == 0 || ( ShapeSize.y == 0 ) )
+ {
+ DisplayError( this, _( "Shape has a null size!" ) );
+ return NULL;
+ }
+
+ if( PolyEdges.size() == 0 )
+ {
+ DisplayError( this, _( "Shape has no points!" ) );
+ return NULL;
+ }
+
+ cmp_name = wxT( "muwave_polygon" );
+
+ // Create a footprint with 2 pads, orientation = 0, pos 0
+ module = CreateMuWaveBaseFootprint( cmp_name, 0, pad_count );
+
+ // We try to place the footprint anchor to the middle of the shape len
+ wxPoint offset;
+ offset.x = -ShapeSize.x / 2;
+
+ pad1 = module->Pads();
+ pad1->SetX0( offset.x );
+ pad1->SetX( pad1->GetPos0().x );
+
+ pad2 = pad1->Next();
+ pad2->SetX0( offset.x + ShapeSize.x );
+ pad2->SetX( pad2->GetPos0().x );
+
+ // Add a polygonal edge (corners will be added later) on copper layer
+ edge = new EDGE_MODULE( module );
+ edge->SetShape( S_POLYGON );
+ edge->SetLayer( F_Cu );
+
+ module->GraphicalItems().PushFront( edge );
+
+ // Get the corner buffer of the polygonal edge
+ std::vector<wxPoint>& polyPoints = edge->GetPolyPoints();
+ polyPoints.reserve( PolyEdges.size() + 2 );
+
+ // Init start point coord:
+ polyPoints.push_back( wxPoint( offset.x, 0 ) );
+
+ wxPoint last_coordinate;
+
+ for( unsigned ii = 0; ii < PolyEdges.size(); ii++ ) // Copy points
+ {
+ last_coordinate.x = KiROUND( PolyEdges[ii].x * ShapeScaleX );
+ last_coordinate.y = -KiROUND( PolyEdges[ii].y * ShapeScaleY );
+ last_coordinate += offset;
+ polyPoints.push_back( last_coordinate );
+ }
+
+ // finish the polygonal shape
+ if( last_coordinate.y != 0 )
+ polyPoints.push_back( wxPoint( last_coordinate.x, 0 ) );
+
+ switch( PolyShapeType )
+ {
+ case 0: // shape from file
+ case 2: // shape from file, mirrored (the mirror is already done)
+ break;
+
+ case 1: // Symmetric shape: add the symmetric (mirrored) shape
+ for( int ndx = polyPoints.size() - 1; ndx >= 0; --ndx )
+ {
+ wxPoint pt = polyPoints[ndx];
+ pt.y = -pt.y; // mirror about X axis
+ polyPoints.push_back( pt );
+ }
+ break;
+ }
+
+ PolyEdges.clear();
+ module->CalculateBoundingBox();
+ GetBoard()->m_Status_Pcb = 0;
+ OnModify();
+ return module;
+}
+
+
+void PCB_EDIT_FRAME::Edit_Gap( wxDC* DC, MODULE* aModule )
+{
+ int gap_size, oX;
+ D_PAD* pad, * next_pad;
+ wxString msg;
+
+ if( aModule == NULL )
+ return;
+
+ // Test if module is a gap type (name begins with GAP, and has 2 pads).
+ msg = aModule->GetReference().Left( 3 );
+
+ if( msg != wxT( "GAP" ) )
+ return;
+
+ pad = aModule->Pads();
+
+ if( pad == NULL )
+ {
+ DisplayError( this, _( "No pad for this footprint" ) );
+ return;
+ }
+
+ next_pad = pad->Next();
+
+ if( next_pad == NULL )
+ {
+ DisplayError( this, _( "Only one pad for this footprint" ) );
+ return;
+ }
+
+ aModule->Draw( m_canvas, DC, GR_XOR );
+
+ // Calculate the current dimension.
+ gap_size = next_pad->GetPos0().x - pad->GetPos0().x - pad->GetSize().x;
+
+ // Entrer the desired length of the gap.
+ msg = StringFromValue( g_UserUnit, gap_size );
+ wxTextEntryDialog dlg( this, _( "Gap:" ), _( "Create Microwave Gap" ), msg );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return; // cancelled by user
+
+ msg = dlg.GetValue();
+ gap_size = ValueFromString( g_UserUnit, msg );
+
+ // Updating sizes of pads forming the gap.
+ int tw = GetDesignSettings().GetCurrentTrackWidth();
+ pad->SetSize( wxSize( tw, tw ) );
+
+ pad->SetY0( 0 );
+ oX = -( gap_size + pad->GetSize().x ) / 2;
+ pad->SetX0( oX );
+
+ wxPoint padpos = pad->GetPos0() + aModule->GetPosition();
+
+ RotatePoint( &padpos.x, &padpos.y,
+ aModule->GetPosition().x, aModule->GetPosition().y, aModule->GetOrientation() );
+
+ pad->SetPosition( padpos );
+
+ tw = GetDesignSettings().GetCurrentTrackWidth();
+ next_pad->SetSize( wxSize( tw, tw ) );
+
+ next_pad->SetY0( 0 );
+ next_pad->SetX0( oX + gap_size + next_pad->GetSize().x );
+
+ padpos = next_pad->GetPos0() + aModule->GetPosition();
+
+ RotatePoint( &padpos.x, &padpos.y,
+ aModule->GetPosition().x, aModule->GetPosition().y, aModule->GetOrientation() );
+
+ next_pad->SetPosition( padpos );
+
+ aModule->Draw( m_canvas, DC, GR_OR );
+}
diff --git a/pcbnew/muwave_command.cpp b/pcbnew/muwave_command.cpp
new file mode 100644
index 0000000..083567c
--- /dev/null
+++ b/pcbnew/muwave_command.cpp
@@ -0,0 +1,126 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+
+#include <pcbnew_id.h>
+#include <kicad_device_context.h>
+
+
+/* Handle microwave commands.
+ */
+void PCB_EDIT_FRAME::ProcessMuWaveFunctions( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ wxPoint pos;
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ wxGetMousePosition( &pos.x, &pos.y );
+
+ pos.y += 20;
+
+ switch( id ) // End any command in progress.
+ {
+ case ID_POPUP_COPY_BLOCK:
+ break;
+
+ default: // End block command in progress.
+ m_canvas->EndMouseCapture( );
+ break;
+ }
+
+ switch( id )
+ {
+ case ID_PCB_MUWAVE_TOOL_SELF_CMD:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add Line" ) );
+ break;
+
+ case ID_PCB_MUWAVE_TOOL_GAP_CMD:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add Gap" ) );
+ break;
+
+ case ID_PCB_MUWAVE_TOOL_STUB_CMD:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add Stub" ) );
+ break;
+
+ case ID_PCB_MUWAVE_TOOL_STUB_ARC_CMD:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add Arc Stub" ) );
+ break;
+
+ case ID_PCB_MUWAVE_TOOL_FUNCTION_SHAPE_CMD:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add Polynomial Shape" ) );
+ break;
+
+ default:
+ DisplayError( this,
+ wxT( "PCB_EDIT_FRAME::ProcessMuWaveFunctions() id error" ) );
+ break;
+ }
+}
+
+
+void PCB_EDIT_FRAME::MuWaveCommand( wxDC* DC, const wxPoint& MousePos )
+{
+ MODULE* module = NULL;
+
+ switch( GetToolId() )
+ {
+ case ID_PCB_MUWAVE_TOOL_SELF_CMD:
+ Begin_Self( DC );
+ break;
+
+ case ID_PCB_MUWAVE_TOOL_GAP_CMD:
+ module = Create_MuWaveComponent( 0 );
+ break;
+
+ case ID_PCB_MUWAVE_TOOL_STUB_CMD:
+ module = Create_MuWaveComponent( 1 );
+ break;
+
+ case ID_PCB_MUWAVE_TOOL_STUB_ARC_CMD:
+ module = Create_MuWaveComponent( 2 );
+ break;
+
+ case ID_PCB_MUWAVE_TOOL_FUNCTION_SHAPE_CMD:
+ module = Create_MuWavePolygonShape();
+ break;
+
+ default:
+ m_canvas->SetCursor( wxCURSOR_ARROW );
+ DisplayError( this, wxT( "PCB_EDIT_FRAME::MuWaveCommand() id error" ) );
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ break;
+ }
+
+ if( module )
+ {
+ StartMoveModule( module, DC, false );
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+}
diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp
new file mode 100644
index 0000000..9a9eba7
--- /dev/null
+++ b/pcbnew/netlist.cpp
@@ -0,0 +1,319 @@
+/**
+ * @file pcbnew/netlist.cpp
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <boost/bind.hpp>
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <class_draw_panel_gal.h>
+#include <confirm.h>
+#include <dialog_helpers.h>
+#include <wxPcbStruct.h>
+#include <pcb_netlist.h>
+#include <netlist_reader.h>
+#include <reporter.h>
+#include <wildcards_and_files_ext.h>
+#include <fpid.h>
+#include <fp_lib_table.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <ratsnest_data.h>
+#include <pcbnew.h>
+#include <io_mgr.h>
+
+#include <tool/tool_manager.h>
+#include <tools/common_actions.h>
+
+
+void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
+ const wxString& aCmpFileName,
+ REPORTER* aReporter,
+ bool aChangeFootprints,
+ bool aDeleteUnconnectedTracks,
+ bool aDeleteExtraFootprints,
+ bool aSelectByTimeStamp,
+ bool aDeleteSinglePadNets,
+ bool aIsDryRun )
+{
+ wxString msg;
+ NETLIST netlist;
+ KIGFX::VIEW* view = GetGalCanvas()->GetView();
+ BOARD* board = GetBoard();
+
+ netlist.SetIsDryRun( aIsDryRun );
+ netlist.SetFindByTimeStamp( aSelectByTimeStamp );
+ netlist.SetDeleteExtraFootprints( aDeleteExtraFootprints );
+ netlist.SetReplaceFootprints( aChangeFootprints );
+
+ try
+ {
+ std::auto_ptr<NETLIST_READER> netlistReader( NETLIST_READER::GetNetlistReader(
+ &netlist, aNetlistFileName, aCmpFileName ) );
+
+ if( !netlistReader.get() )
+ {
+ msg.Printf( _( "Cannot open netlist file \"%s\"." ), GetChars( aNetlistFileName ) );
+ wxMessageBox( msg, _( "Netlist Load Error." ), wxOK | wxICON_ERROR, this );
+ return;
+ }
+
+ SetLastNetListRead( aNetlistFileName );
+ netlistReader->LoadNetlist();
+ loadFootprints( netlist, aReporter );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ msg.Printf( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() );
+ wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR );
+ return;
+ }
+
+ // Clear undo and redo lists to avoid inconsistencies between lists
+ if( !netlist.IsDryRun() )
+ GetScreen()->ClearUndoRedoList();
+
+ if( !netlist.IsDryRun() )
+ {
+ // Remove old modules
+ for( MODULE* module = board->m_Modules; module; module = module->Next() )
+ {
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
+ view->Remove( module );
+ }
+ }
+
+ // Clear selection, just in case a selected item has to be removed
+ m_toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ netlist.SortByReference();
+ board->ReplaceNetlist( netlist, aDeleteSinglePadNets, aReporter );
+
+ // If it was a dry run, nothing has changed so we're done.
+ if( netlist.IsDryRun() )
+ return;
+
+ OnModify();
+
+ SetCurItem( NULL );
+
+ // Reload modules
+ for( MODULE* module = board->m_Modules; module; module = module->Next() )
+ {
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
+ view->Add( module );
+ module->ViewUpdate();
+ }
+
+ if( aDeleteUnconnectedTracks && board->m_Track )
+ {
+ // Remove erroneous tracks. This should probably pushed down to the #BOARD object.
+ RemoveMisConnectedTracks();
+ }
+
+ // Rebuild the board connectivity:
+ Compile_Ratsnest( NULL, true );
+ board->GetRatsnest()->ProcessBoard();
+
+ SetMsgPanel( board );
+ m_canvas->Refresh();
+}
+
+
+MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName()
+{
+ if( GetBoard()->m_Modules == NULL )
+ {
+ DisplayError( this, _( "No footprints" ) );
+ return 0;
+ }
+
+ wxArrayString listnames;
+
+ MODULE* module;
+
+ for( module = GetBoard()->m_Modules; module; module = module->Next() )
+ listnames.Add( module->GetReference() );
+
+ wxArrayString headers;
+ headers.Add( wxT( "Module" ) );
+ std::vector<wxArrayString> itemsToDisplay;
+
+ // Conversion from wxArrayString to vector of ArrayString
+ for( unsigned i = 0; i < listnames.GetCount(); i++ )
+ {
+ wxArrayString item;
+ item.Add( listnames[i] );
+ itemsToDisplay.push_back( item );
+ }
+
+ EDA_LIST_DIALOG dlg( this, _( "Components" ), headers, itemsToDisplay, wxEmptyString );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return NULL;
+
+ wxString ref = dlg.GetTextSelection();
+
+ for( module = GetBoard()->m_Modules; module; module = module->Next() )
+ {
+ if( module->GetReference() == ref )
+ break;
+ }
+
+ return module;
+}
+
+
+#define ALLOW_PARTIAL_FPID 1
+
+void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
+ throw( IO_ERROR, PARSE_ERROR )
+{
+ wxString msg;
+ FPID lastFPID;
+ COMPONENT* component;
+ MODULE* module = 0;
+ MODULE* fpOnBoard;
+
+ if( aNetlist.IsEmpty() || Prj().PcbFootprintLibs()->IsEmpty() )
+ return;
+
+ aNetlist.SortByFPID();
+
+ for( unsigned ii = 0; ii < aNetlist.GetCount(); ii++ )
+ {
+ component = aNetlist.GetComponent( ii );
+
+#if ALLOW_PARTIAL_FPID
+ // The FPID is ok as long as there is a footprint portion coming
+ // from eeschema.
+ if( !component->GetFPID().GetFootprintName().size() )
+#else
+ if( component->GetFPID().empty() )
+#endif
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "No footprint defined for component '%s'.\n" ),
+ GetChars( component->GetReference() ) );
+ aReporter->Report( msg, REPORTER::RPT_ERROR );
+ }
+
+ continue;
+ }
+
+ // Check if component footprint is already on BOARD and only load the footprint from
+ // the library if it's needed. Nickname can be blank.
+ if( aNetlist.IsFindByTimeStamp() )
+ fpOnBoard = m_Pcb->FindModule( aNetlist.GetComponent( ii )->GetTimeStamp(), true );
+ else
+ fpOnBoard = m_Pcb->FindModule( aNetlist.GetComponent( ii )->GetReference() );
+
+ bool footprintMisMatch = fpOnBoard &&
+ fpOnBoard->GetFPID() != component->GetFPID();
+
+ if( footprintMisMatch && !aNetlist.GetReplaceFootprints() )
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "* Warning: component '%s': board footprint '%s', netlist footprint '%s'\n" ),
+ GetChars( component->GetReference() ),
+ GetChars( fpOnBoard->GetFPID().Format() ),
+ GetChars( component->GetFPID().Format() ) );
+ aReporter->Report( msg );
+ }
+
+ continue;
+ }
+
+ if( !aNetlist.GetReplaceFootprints() )
+ footprintMisMatch = false;
+
+ bool loadFootprint = (fpOnBoard == NULL) || footprintMisMatch;
+
+ if( loadFootprint && (component->GetFPID() != lastFPID) )
+ {
+ module = NULL;
+
+#if ALLOW_PARTIAL_FPID
+ // The FPID is ok as long as there is a footprint portion coming
+ // the library if it's needed. Nickname can be blank.
+ if( !component->GetFPID().GetFootprintName().size() )
+#else
+ if( !component->GetFPID().IsValid() )
+#endif
+ {
+ if( aReporter )
+ {
+ msg.Printf( _( "Component '%s' footprint ID '%s' is not "
+ "valid.\n" ),
+ GetChars( component->GetReference() ),
+ GetChars( component->GetFPID().Format() ) );
+ aReporter->Report( msg, REPORTER::RPT_ERROR );
+ }
+
+ continue;
+ }
+
+ // loadFootprint() can find a footprint with an empty nickname in fpid.
+ module = PCB_BASE_FRAME::loadFootprint( component->GetFPID() );
+
+ if( module )
+ {
+ lastFPID = component->GetFPID();
+ }
+ else
+ {
+ if( aReporter )
+ {
+ wxString msg;
+ msg.Printf( _( "Component '%s' footprint '%s' was not found in "
+ "any libraries in the footprint library table.\n" ),
+ GetChars( component->GetReference() ),
+ GetChars( component->GetFPID().GetFootprintName() ) );
+ aReporter->Report( msg, REPORTER::RPT_ERROR );
+ }
+
+ continue;
+ }
+ }
+ else
+ {
+ // Footprint already loaded from a library, duplicate it (faster)
+ if( module == NULL )
+ continue; // Module does not exist in any library.
+
+ module = new MODULE( *module );
+ }
+
+ if( loadFootprint && module != NULL )
+ component->SetModule( module );
+ }
+}
+
diff --git a/pcbnew/netlist_reader.cpp b/pcbnew/netlist_reader.cpp
new file mode 100644
index 0000000..5e67c94
--- /dev/null
+++ b/pcbnew/netlist_reader.cpp
@@ -0,0 +1,205 @@
+/**
+ * @file netlist_reader.cpp
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2011 Jean-Pierre Charras.
+ * Copyright (C) 2013-2015 Wayne Stambaugh <stambaughw@verizon.net>.
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+
+#include <kicad_string.h>
+#include <reporter.h>
+
+#include <pcb_netlist.h>
+#include <netlist_reader.h>
+#include <class_module.h>
+
+#include <wx/regex.h>
+
+
+NETLIST_READER::~NETLIST_READER()
+{
+ delete m_lineReader;
+ delete m_footprintReader;
+}
+
+
+NETLIST_READER::NETLIST_FILE_T NETLIST_READER::GuessNetlistFileType( LINE_READER* aLineReader )
+{
+ // Orcad Pcb2 netlist format starts by "( {", followed by an unknown comment,
+ // depending on the tool which created the file
+ wxRegEx reOrcad( wxT( "(?i)[ ]*\\([ \t]+{+" ), wxRE_ADVANCED );
+ wxASSERT( reOrcad.IsValid() );
+ // Our legacy netlist format starts by "# EESchema Netlist "
+ wxRegEx reLegacy( wxT( "(?i)#[ \t]+EESchema[ \t]+Netlist[ \t]+" ), wxRE_ADVANCED );
+ wxASSERT( reLegacy.IsValid() );
+ // Our new netlist format starts by "(export (version "
+ wxRegEx reKicad( wxT( "[ ]*\\(export[ ]+" ), wxRE_ADVANCED );
+ wxASSERT( reKicad.IsValid() );
+
+ wxString line;
+
+ while( aLineReader->ReadLine() )
+ {
+ line = FROM_UTF8( aLineReader->Line() );
+
+ if( reLegacy.Matches( line ) )
+ return LEGACY;
+ else if( reKicad.Matches( line ) )
+ return KICAD;
+ else if( reOrcad.Matches( line ) )
+ return ORCAD;
+ }
+
+ return UNKNOWN;
+}
+
+
+NETLIST_READER* NETLIST_READER::GetNetlistReader( NETLIST* aNetlist,
+ const wxString& aNetlistFileName,
+ const wxString& aCompFootprintFileName )
+ throw( IO_ERROR )
+{
+ wxASSERT( aNetlist != NULL );
+
+ std::auto_ptr< FILE_LINE_READER > file_rdr(new FILE_LINE_READER( aNetlistFileName ) );
+
+ NETLIST_FILE_T type = GuessNetlistFileType( file_rdr.get() );
+ file_rdr->Rewind();
+
+ // The component footprint link reader is NULL if no file name was specified.
+ std::auto_ptr<CMP_READER> cmp_rdr( aCompFootprintFileName.IsEmpty() ?
+ NULL :
+ new CMP_READER( new FILE_LINE_READER( aCompFootprintFileName ) ) );
+
+ switch( type )
+ {
+ case LEGACY:
+ case ORCAD:
+ return new LEGACY_NETLIST_READER( file_rdr.release(), aNetlist, cmp_rdr.release() );
+
+ case KICAD:
+ return new KICAD_NETLIST_READER( file_rdr.release(), aNetlist, cmp_rdr.release() );
+
+ default: // Unrecognized format:
+ break;
+ }
+
+ return NULL;
+}
+
+
+bool CMP_READER::Load( NETLIST* aNetlist ) throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_MSG( aNetlist != NULL,true, wxT( "No netlist passed to CMP_READER::Load()" ) );
+
+ wxString reference; // Stores value read from line like Reference = BUS1;
+ wxString timestamp; // Stores value read from line like TimeStamp = /32307DE2/AA450F67;
+ wxString footprint; // Stores value read from line like IdModule = CP6;
+ wxString buffer;
+ wxString value;
+
+ bool ok = true;
+
+ while( m_lineReader->ReadLine() )
+ {
+ buffer = FROM_UTF8( m_lineReader->Line() );
+
+ if( !buffer.StartsWith( wxT( "BeginCmp" ) ) )
+ continue;
+
+ // Begin component description.
+ reference.Empty();
+ footprint.Empty();
+ timestamp.Empty();
+
+ while( m_lineReader->ReadLine() )
+ {
+ buffer = FROM_UTF8( m_lineReader->Line() );
+
+ if( buffer.StartsWith( wxT( "EndCmp" ) ) )
+ break;
+
+ // store string value, stored between '=' and ';' delimiters.
+ value = buffer.AfterFirst( '=' );
+ value = value.BeforeLast( ';' );
+ value.Trim( true );
+ value.Trim( false );
+
+ if( buffer.StartsWith( wxT( "Reference" ) ) )
+ {
+ reference = value;
+ continue;
+ }
+
+ if( buffer.StartsWith( wxT( "IdModule =" ) ) )
+ {
+ footprint = value;
+ continue;
+ }
+
+ if( buffer.StartsWith( wxT( "TimeStamp =" ) ) )
+ {
+ timestamp = value;
+ continue;
+ }
+ }
+
+ // Find the corresponding item in component list:
+ COMPONENT* component = aNetlist->GetComponentByReference( reference );
+
+ // The corresponding component could no longer existing in the netlist. This
+ // can happen when it is removed from schematic and still exists in footprint
+ // assignment list. This is an usual case during the life of a design.
+ if( component )
+ {
+ FPID fpid;
+
+ if( !footprint.IsEmpty() && fpid.Parse( footprint ) >= 0 )
+ {
+ wxString error;
+ error.Printf( _( "invalid footprint ID in\nfile: <%s>\nline: %d" ),
+ GetChars( m_lineReader->GetSource() ),
+ m_lineReader->LineNumber() );
+
+ THROW_IO_ERROR( error );
+ }
+
+ // For checking purpose, store the existing FPID (if any) in the alternate fpid copy
+ // if this existing FPID differs from the FPID read from the .cmp file.
+ // CvPcb can ask for user to chose the right FPID.
+ // It happens if the FPID was modified outside CvPcb.
+ if( fpid != component->GetFPID() && !component->GetFPID().empty() )
+ component->SetAltFPID( component->GetFPID() );
+
+ component->SetFPID( fpid );
+ }
+ else
+ {
+ ok = false; // can be used to display a warning in Pcbnew.
+ }
+ }
+
+ return ok;
+}
diff --git a/pcbnew/netlist_reader.h b/pcbnew/netlist_reader.h
new file mode 100644
index 0000000..0bdd643
--- /dev/null
+++ b/pcbnew/netlist_reader.h
@@ -0,0 +1,404 @@
+#ifndef NETLIST_READER_H
+#define NETLIST_READER_H
+
+/**
+ * @file netlist_reader.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras.
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>.
+ * Copyright (C) 2012-2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <boost/ptr_container/ptr_vector.hpp>
+
+#include <fctsys.h>
+#include <macros.h>
+#include <fpid.h>
+
+#include <netlist_lexer.h> // netlist_lexer is common to Eeschema and Pcbnew
+
+
+class NETLIST;
+class COMPONENT;
+
+
+/**
+ * Class CMP_READER
+ * reads a component footprint link file (*.cmp) format.
+ */
+class CMP_READER
+{
+ LINE_READER* m_lineReader; ///< The line reader to read.
+
+public:
+ /**
+ * CMP_READER constructor.
+ * @param aLineReader is a LINE_READER (in fact a FILE_LINE_READER)
+ * which is owned by me ( and deleted by me) to read
+ * the component footprint link file.
+ */
+ CMP_READER( LINE_READER* aLineReader )
+ {
+ m_lineReader = aLineReader;
+ }
+
+ ~CMP_READER()
+ {
+ if( m_lineReader )
+ {
+ delete m_lineReader;
+ m_lineReader = NULL;
+ }
+ }
+
+ /**
+ * Function Load
+ * read the *.cmp file format contains the component footprint assignments created by CvPcb
+ * into \a aNetlist.
+ *
+ * @param aNetlist is the #NETLIST to read into.
+ *
+ * @todo At some point in the future, use the footprint field in the new s-expression
+ * netlist file to assign a footprint to a component instead of using a secondary
+ * (*.cmp) file.
+ *
+ * Sample file footprint assignment entry:
+ *
+ * Cmp-Mod V01 Genere by CvPcb 29/10/2003-13: 11:6 *
+ * BeginCmp
+ * TimeStamp = /32307DE2/AA450F67;
+ * Reference = C1;
+ * ValeurCmp = 47uF;
+ * IdModule = CP6;
+ * EndCmp
+ *
+ * @throw IO_ERROR if a the #LINE_READER IO error occurs.
+ * @throw PARSE_ERROR if an error occurs while parsing the file.
+ * @return true if OK, false if a component reference found in the
+ * .cmp file is not found in netlist, which means the .cmp file
+ * is not updated. This is an usual case, in CvPcb, but can be used to
+ * print a warning in Pcbnew.
+ */
+ bool Load( NETLIST* aNetlist ) throw( IO_ERROR, PARSE_ERROR );
+};
+
+
+/**
+ * Class NETLIST_READER
+ * is a pure virtual class to derive a specific type of netlist reader from.
+ */
+class NETLIST_READER
+{
+public:
+
+ enum NETLIST_FILE_T
+ {
+ UNKNOWN = -1,
+ ORCAD,
+ LEGACY,
+ KICAD,
+
+ // Add new types here. Don't forget to create the appropriate class derived from
+ // NETCLASS_READER and add the entry to the NETLIST_READER::GetNetlistReader()
+ // function.
+ };
+
+
+ /**
+ * Constructor
+ * @param aLineReader ownership is taken of this LINE_READER.
+ * @param aFootprintLinkReader ownership is taken of this CMP_READER.
+ */
+ NETLIST_READER( LINE_READER* aLineReader,
+ NETLIST* aNetlist,
+ CMP_READER* aFootprintLinkReader = NULL )
+ {
+ wxASSERT( aLineReader != NULL );
+
+ m_lineReader = aLineReader;
+ m_footprintReader = aFootprintLinkReader;
+ m_netlist = aNetlist;
+ m_loadFootprintFilters = true;
+ m_loadNets = true;
+ }
+
+ virtual ~NETLIST_READER();
+
+ /**
+ * Function GuessNetlistFileType
+ * looks at \a aFileHeaderLine to see if it matches any of the netlist file types it
+ * knows about.
+ *
+ * @param aLineReader is the #LINE_READER object containing lines from the netlist to test.
+ * @return the #NETLIST_FILE_T of \a aLineReader.
+ */
+ static NETLIST_FILE_T GuessNetlistFileType( LINE_READER* aLineReader );
+
+ /**
+ * Function GetNetlistReader
+ * attempts to determine the net list file type of \a aNetlistFileName and return the
+ * appropriate NETLIST_READER type.
+ *
+ * @param aNetlist is the netlist to load \a aNetlistFileName into.
+ * @param aNetlistFileName is the full path and file name of the net list to read.
+ * @param aCompFootprintFileName is the full path and file name of the component footprint
+ * associations to read. Set to wxEmptyString if loading the
+ * footprint association file is not required.
+ * @return the appropriate NETLIST_READER if \a aNetlistFileName is a valid netlist or
+ * NULL if \a aNetlistFileName is not a valid netlist files.
+ */
+ static NETLIST_READER* GetNetlistReader( NETLIST* aNetlist,
+ const wxString& aNetlistFileName,
+ const wxString& aCompFootprintFileName = wxEmptyString )
+ throw( IO_ERROR );
+
+ /**
+ * Function LoadNetlist
+ * loads the contents of the netlist file into \a aNetlist.
+ *
+ * @throw IO_ERROR if a file IO error occurs.
+ * @throw PARSE_ERROR if an error occurs while parsing the file.
+ */
+ virtual void LoadNetlist() throw( IO_ERROR, PARSE_ERROR, boost::bad_pointer ) = 0;
+
+ /**
+ * Function GetLineReader()
+ * @return the #LINE_READER associated with the #NETLIST_READER.
+ */
+ LINE_READER* GetLineReader();
+
+protected:
+ NETLIST* m_netlist; ///< The net list to read the file(s) into.
+ bool m_loadFootprintFilters; ///< Load the component footprint filters section if true.
+ bool m_loadNets; ///< Load the nets section of the netlist file if true.
+ LINE_READER* m_lineReader; ///< The line reader of the netlist.
+
+ /// The reader used to load the footprint links. If NULL, footprint links are not read.
+ CMP_READER* m_footprintReader;
+};
+
+
+/**
+ * Class LEGACY_NETLIST_READER
+ * reads the KiCad legacy and the old Orcad netlist formats.
+ *
+ * The KiCad legacy netlist format was derived directly from an old Orcad netlist format. The
+ * primary difference is the header was changed so this reader can read both formats.
+ */
+class LEGACY_NETLIST_READER : public NETLIST_READER
+{
+ /**
+ * Function loadComponent
+ * read the \a aLine containing the description of a component from a legacy format
+ * netlist and add it to the netlist.
+ *
+ * Analyze the first line of a component description in netlist:
+ * ( /40C08647 $noname R20 4.7K {Lib=R}
+ *
+ * @param aText contains the first line of description
+ * @return the new component created by parsing \a aLine
+ * @throw PARSE_ERROR when \a aLine is not a valid component description.
+ */
+ COMPONENT* loadComponent( char* aText ) throw( PARSE_ERROR, boost::bad_pointer );
+
+ /**
+ * Function loadFootprintFilters
+ * loads the footprint filter section of netlist file.
+ *
+ * Sample legacy footprint filter section:
+ * { Allowed footprints by component:
+ * $component R11
+ * R?
+ * SM0603
+ * SM0805
+ * R?-*
+ * SM1206
+ * $endlist
+ * $endfootprintlist
+ * }
+ *
+ * @throw IO_ERROR if a file IO error occurs.
+ * @throw PARSE_ERROR if an error occurs while parsing the file.
+ */
+ void loadFootprintFilters() throw( IO_ERROR, PARSE_ERROR );
+
+ /**
+ * Function loadNet
+ * read a component net description from \a aText.
+ *
+ * @param aText is current line read from the netlist.
+ * @param aComponent is the component to add the net to.
+ * @throw PARSE_ERROR if a error occurs reading \a aText.
+ */
+ void loadNet( char* aText, COMPONENT* aComponent ) throw( PARSE_ERROR );
+
+public:
+
+ LEGACY_NETLIST_READER( LINE_READER* aLineReader,
+ NETLIST* aNetlist,
+ CMP_READER* aFootprintLinkReader = NULL ) :
+ NETLIST_READER( aLineReader, aNetlist, aFootprintLinkReader )
+ {
+ }
+
+ /**
+ * Function LoadNetlist
+ * read the netlist file in the legacy format into \a aNetlist.
+ *
+ * The legacy netlist format is:
+ * \# EESchema Netlist Version 1.0 generee le 18/5/2005-12:30:22
+ * (
+ * ( 40C08647 $noname R20 4,7K {Lib=R}
+ * ( 1 VCC )
+ * ( 2 MODB_1 )
+ * )
+ * ( 40C0863F $noname R18 4,7_k {Lib=R}
+ * ( 1 VCC )
+ * ( 2 MODA_1 )
+ * )
+ * }
+ * \#End
+ *
+ * @throw IO_ERROR if a file IO error occurs.
+ * @throw PARSE_ERROR if an error occurs while parsing the file.
+ */
+ virtual void LoadNetlist() throw ( IO_ERROR, PARSE_ERROR, boost::bad_pointer );
+};
+
+
+/**
+ * Class KICAD_NETLIST_PARSER
+ * is the parser for reading the KiCad s-expression netlist format.
+ */
+class KICAD_NETLIST_PARSER : public NETLIST_LEXER
+{
+private:
+ NL_T::T token;
+ LINE_READER* m_lineReader; ///< The line reader used to parse the netlist. Not owned.
+ NETLIST* m_netlist; ///< The netlist to parse into. Not owned.
+
+ /**
+ * Function skipCurrent
+ * Skip the current token level, i.e
+ * search for the RIGHT parenthesis which closes the current description
+ */
+ void skipCurrent() throw( IO_ERROR, PARSE_ERROR );
+
+ /**
+ * Function parseComponent
+ * parse a component description:
+ * (comp (ref P1)
+ * (value DB25FEMELLE)
+ * (footprint DB25FC)
+ * (libsource (lib conn) (part DB25))
+ * (sheetpath (names /) (tstamps /))
+ * (tstamp 3256759C))
+ */
+ void parseComponent() throw( IO_ERROR, PARSE_ERROR, boost::bad_pointer );
+
+ /**
+ * Function parseNet
+ * Parses a section like
+ * (net (code 20) (name /PC-A0)
+ * (node (ref BUS1) (pin 62))
+ * (node (ref U3) (pin 3))
+ * (node (ref U9) (pin M6)))
+ *
+ * and set the corresponding pads netnames
+ */
+ void parseNet() throw( IO_ERROR, PARSE_ERROR );
+
+ /**
+ * Function parseLibPartList
+ * reads the section "libparts" in the netlist:
+ * (libparts
+ * (libpart (lib device) (part C)
+ * (description "Condensateur non polarise")
+ * (footprints
+ * (fp SM*)
+ * (fp C?)
+ * (fp C1-1))
+ * (fields
+ * (field (name Reference) C)
+ * (field (name Value) C))
+ * (pins
+ * (pin (num 1) (name ~) (type passive))
+ * (pin (num 2) (name ~) (type passive))))
+ *
+ * And add the strings giving the footprint filter (subsection footprints)
+ * of the corresponding module info
+ * <p>This section is used by CvPcb, and is not useful in Pcbnew,
+ * therefore it it not always read </p>
+ */
+ void parseLibPartList() throw( IO_ERROR, PARSE_ERROR );
+
+
+public:
+ KICAD_NETLIST_PARSER( LINE_READER* aReader, NETLIST* aNetlist );
+
+ void SetLineReader( LINE_READER* aLineReader );
+
+ void SetNetlist( NETLIST* aNetlist ) { m_netlist = aNetlist; }
+
+ /**
+ * Function Parse
+ * parse the full netlist
+ */
+ void Parse() throw( IO_ERROR, PARSE_ERROR, boost::bad_pointer );
+
+ // Useful for debug only:
+ const char* getTokenName( NL_T::T aTok )
+ {
+ return NETLIST_LEXER::TokenName( aTok );
+ }
+};
+
+
+/**
+ * Class KICAD_NETLIST_READER
+ * read the new s-expression based KiCad netlist format.
+ */
+class KICAD_NETLIST_READER : public NETLIST_READER
+{
+ KICAD_NETLIST_PARSER* m_parser; ///< The s-expression format parser.
+
+public:
+ KICAD_NETLIST_READER( LINE_READER* aLineReader,
+ NETLIST* aNetlist,
+ CMP_READER* aFootprintLinkReader = NULL ) :
+ NETLIST_READER( aLineReader, aNetlist, aFootprintLinkReader ),
+ m_parser( new KICAD_NETLIST_PARSER( aLineReader, aNetlist ) )
+ {
+ }
+
+ virtual ~KICAD_NETLIST_READER()
+ {
+ delete m_parser;
+ }
+
+ virtual void LoadNetlist() throw ( IO_ERROR, PARSE_ERROR, boost::bad_pointer );
+};
+
+
+#endif // NETLIST_READER_H
diff --git a/pcbnew/onleftclick.cpp b/pcbnew/onleftclick.cpp
new file mode 100644
index 0000000..ebbb288
--- /dev/null
+++ b/pcbnew/onleftclick.cpp
@@ -0,0 +1,602 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/onleftclick.cpp
+ * @brief Functions called when the left button is clicked or double clicked.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <msgpanel.h>
+
+#include <class_board.h>
+#include <class_drawsegment.h>
+#include <class_dimension.h>
+#include <class_zone.h>
+#include <class_pcb_text.h>
+#include <class_text_mod.h>
+#include <class_module.h>
+#include <class_mire.h>
+#include <project.h>
+
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <menus_helpers.h>
+
+
+/* Handle the left button mouse click, when a tool is active
+ */
+void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
+{
+ BOARD_ITEM* curr_item = GetCurItem();
+ bool exit = false;
+ bool no_tool = GetToolId() == ID_NO_TOOL_SELECTED;
+
+ if( no_tool || ( curr_item && curr_item->GetFlags() ) )
+ {
+ m_canvas->SetAutoPanRequest( false );
+
+ if( curr_item && curr_item->GetFlags() ) // Command in progress
+ {
+ m_canvas->SetIgnoreMouseEvents( true );
+ m_canvas->CrossHairOff( aDC );
+
+ switch( curr_item->Type() )
+ {
+ case PCB_ZONE_AREA_T:
+ if( curr_item->IsNew() )
+ {
+ m_canvas->SetAutoPanRequest( true );
+ Begin_Zone( aDC );
+ }
+ else
+ {
+ End_Move_Zone_Corner_Or_Outlines( aDC, static_cast<ZONE_CONTAINER*>( curr_item ) );
+ }
+
+ exit = true;
+ break;
+
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ if( curr_item->IsDragging() )
+ {
+ PlaceDraggedOrMovedTrackSegment( static_cast<TRACK*>( curr_item ), aDC );
+ exit = true;
+ }
+
+ break;
+
+ case PCB_TEXT_T:
+ Place_Texte_Pcb( static_cast<TEXTE_PCB*>( curr_item ), aDC );
+ exit = true;
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ PlaceTexteModule( static_cast<TEXTE_MODULE*>( curr_item ), aDC );
+ exit = true;
+ break;
+
+ case PCB_PAD_T:
+ PlacePad( static_cast<D_PAD*>( curr_item ), aDC );
+ exit = true;
+ break;
+
+ case PCB_MODULE_T:
+ PlaceModule( static_cast<MODULE*>( curr_item ), aDC );
+ exit = true;
+ break;
+
+ case PCB_TARGET_T:
+ PlaceTarget( static_cast<PCB_TARGET*>( curr_item ), aDC );
+ exit = true;
+ break;
+
+ case PCB_LINE_T:
+ if( no_tool ) // when no tools: existing item moving.
+ {
+ Place_DrawItem( static_cast<DRAWSEGMENT*>( curr_item ), aDC );
+ exit = true;
+ }
+
+ break;
+
+ case PCB_DIMENSION_T:
+ if( ! curr_item->IsNew() )
+ { // We are moving the text of an existing dimension. Place it
+ PlaceDimensionText( static_cast<DIMENSION*>( curr_item ), aDC );
+ exit = true;
+ }
+ break;
+
+ case PCB_MARKER_T: // MARKER_PCB, a marker used to show something
+ curr_item->ClearFlags(); // Not reason to have flags set
+ exit = true;
+ break;
+
+ default:
+ DisplayError( this,
+ wxString::Format(
+ "PCB_EDIT_FRAME::OnLeftClick() err: curr_item type %d m_Flags != 0 (%X)",
+ curr_item->Type(), curr_item->GetFlags() ) );
+ exit = true;
+ break;
+ }
+
+ m_canvas->SetIgnoreMouseEvents( false );
+ m_canvas->CrossHairOn( aDC );
+
+ if( exit )
+ return;
+ }
+ else if( !wxGetKeyState( WXK_SHIFT ) && !wxGetKeyState( WXK_ALT )
+ && !wxGetKeyState( WXK_CONTROL ) )
+ {
+ curr_item = PcbGeneralLocateAndDisplay();
+
+ if( curr_item )
+ SendMessageToEESCHEMA( curr_item );
+ }
+ }
+
+ if( curr_item ) // display netclass info for zones, tracks and pads
+ {
+ switch( curr_item->Type() )
+ {
+ case PCB_ZONE_AREA_T:
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ case PCB_PAD_T:
+ SetCurrentNetClass(
+ ((BOARD_CONNECTED_ITEM*)curr_item)->GetNetClassName() );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch( GetToolId() )
+ {
+ case ID_MAIN_MENUBAR:
+ case ID_NO_TOOL_SELECTED:
+ break;
+
+ case ID_PCB_MUWAVE_TOOL_SELF_CMD:
+ case ID_PCB_MUWAVE_TOOL_GAP_CMD:
+ case ID_PCB_MUWAVE_TOOL_STUB_CMD:
+ case ID_PCB_MUWAVE_TOOL_STUB_ARC_CMD:
+ case ID_PCB_MUWAVE_TOOL_FUNCTION_SHAPE_CMD:
+ MuWaveCommand( aDC, aPosition );
+ break;
+
+ case ID_PCB_HIGHLIGHT_BUTT:
+ {
+ int netcode = SelectHighLight( aDC );
+
+ if( netcode < 0 )
+ SetMsgPanel( GetBoard() );
+ else
+ {
+ NETINFO_ITEM* net = GetBoard()->FindNet( netcode );
+
+ if( net )
+ {
+ MSG_PANEL_ITEMS items;
+ net->GetMsgPanelInfo( items );
+ SetMsgPanel( items );
+ }
+ }
+ }
+ break;
+
+ case ID_PCB_SHOW_1_RATSNEST_BUTT:
+ curr_item = PcbGeneralLocateAndDisplay();
+ Show_1_Ratsnest( curr_item, aDC );
+
+ if( curr_item )
+ SendMessageToEESCHEMA( curr_item );
+
+ break;
+
+ case ID_PCB_MIRE_BUTT:
+ if( (curr_item == NULL) || (curr_item->GetFlags() == 0) )
+ {
+ SetCurItem( (BOARD_ITEM*) CreateTarget( aDC ) );
+ m_canvas->MoveCursorToCrossHair();
+ }
+ else if( curr_item->Type() == PCB_TARGET_T )
+ {
+ PlaceTarget( (PCB_TARGET*) curr_item, aDC );
+ }
+ else
+ {
+ DisplayError( this, wxT( "OnLeftClick err: not a PCB_TARGET_T" ) );
+ }
+
+ break;
+
+ case ID_PCB_CIRCLE_BUTT:
+ case ID_PCB_ARC_BUTT:
+ case ID_PCB_ADD_LINE_BUTT:
+ {
+ STROKE_T shape = S_SEGMENT;
+
+ if( GetToolId() == ID_PCB_CIRCLE_BUTT )
+ shape = S_CIRCLE;
+
+ if( GetToolId() == ID_PCB_ARC_BUTT )
+ shape = S_ARC;
+
+ if( IsCopperLayer( GetActiveLayer() ) )
+ {
+ DisplayError( this, _( "Graphic not allowed on Copper layers" ) );
+ break;
+ }
+
+ if( (curr_item == NULL) || (curr_item->GetFlags() == 0) )
+ {
+ curr_item = (BOARD_ITEM*) Begin_DrawSegment( NULL, shape, aDC );
+ SetCurItem( curr_item );
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else if( curr_item
+ && (curr_item->Type() == PCB_LINE_T)
+ && curr_item->IsNew() )
+ {
+ curr_item = (BOARD_ITEM*) Begin_DrawSegment( (DRAWSEGMENT*) curr_item, shape, aDC );
+ SetCurItem( curr_item );
+ m_canvas->SetAutoPanRequest( true );
+ }
+ }
+ break;
+
+ case ID_TRACK_BUTT:
+ if( !IsCopperLayer( GetActiveLayer() ) )
+ {
+ DisplayError( this, _( "Tracks on Copper layers only " ) );
+ break;
+ }
+
+ if( (curr_item == NULL) || (curr_item->GetFlags() == 0) )
+ {
+ curr_item = (BOARD_ITEM*) Begin_Route( NULL, aDC );
+ SetCurItem( curr_item );
+
+ if( curr_item )
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else if( curr_item && curr_item->IsNew() )
+ {
+ TRACK* track = Begin_Route( (TRACK*) curr_item, aDC );
+
+ // SetCurItem() must not write to the msg panel
+ // because a track info is displayed while moving the mouse cursor
+ if( track ) // A new segment was created
+ SetCurItem( curr_item = (BOARD_ITEM*) track, false );
+
+ m_canvas->SetAutoPanRequest( true );
+ }
+
+ break;
+
+ case ID_PCB_ZONES_BUTT:
+ case ID_PCB_KEEPOUT_AREA_BUTT:
+ /* ZONE or KEEPOUT Tool is selected. Determine action for a left click:
+ * this can be start a new zone or select and move an existing zone outline corner
+ * if found near the mouse cursor
+ */
+ if( (curr_item == NULL) || (curr_item->GetFlags() == 0) )
+ {
+ if( Begin_Zone( aDC ) )
+ {
+ m_canvas->SetAutoPanRequest( true );
+ curr_item = GetBoard()->m_CurrentZoneContour;
+ GetScreen()->SetCurItem( curr_item );
+ }
+ }
+ else if( curr_item && (curr_item->Type() == PCB_ZONE_AREA_T) && curr_item->IsNew() )
+ { // Add a new corner to the current outline being created:
+ m_canvas->SetAutoPanRequest( true );
+ Begin_Zone( aDC );
+ curr_item = GetBoard()->m_CurrentZoneContour;
+ GetScreen()->SetCurItem( curr_item );
+ }
+ else
+ {
+ DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() zone internal error" ) );
+ }
+
+ break;
+
+ case ID_PCB_ADD_TEXT_BUTT:
+ if( Edge_Cuts == GetActiveLayer() )
+ {
+ DisplayError( this,
+ _( "Texts not allowed on Edge Cut layer" ) );
+ break;
+ }
+
+ if( (curr_item == NULL) || (curr_item->GetFlags() == 0) )
+ {
+ SetCurItem( CreateTextePcb( aDC ) );
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else if( curr_item->Type() == PCB_TEXT_T )
+ {
+ Place_Texte_Pcb( (TEXTE_PCB*) curr_item, aDC );
+ m_canvas->SetAutoPanRequest( false );
+ }
+ else
+ {
+ DisplayError( this, wxT( "OnLeftClick err: not a PCB_TEXT_T" ) );
+ }
+
+ break;
+
+ case ID_PCB_MODULE_BUTT:
+ if( (curr_item == NULL) || (curr_item->GetFlags() == 0) )
+ {
+ m_canvas->MoveCursorToCrossHair();
+ curr_item = (BOARD_ITEM*) LoadModuleFromLibrary(
+ wxEmptyString, Prj().PcbFootprintLibs(), true, aDC );
+
+ SetCurItem( curr_item );
+
+ if( curr_item )
+ StartMoveModule( (MODULE*) curr_item, aDC, false );
+ }
+ else if( curr_item->Type() == PCB_MODULE_T )
+ {
+ PlaceModule( (MODULE*) curr_item, aDC );
+ m_canvas->SetAutoPanRequest( false );
+ }
+ else
+ {
+ DisplayError( this, wxT( "Internal err: Struct not PCB_MODULE_T" ) );
+ }
+
+ break;
+
+ case ID_PCB_DIMENSION_BUTT:
+ if( IsCopperLayer( GetActiveLayer() ) || GetActiveLayer() == Edge_Cuts )
+ {
+ DisplayError( this, _( "Dimension not allowed on Copper or Edge Cut layers" ) );
+ break;
+ }
+
+ if( !curr_item || !curr_item->GetFlags() )
+ {
+ curr_item = (BOARD_ITEM*) EditDimension( NULL, aDC );
+ SetCurItem( curr_item );
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else if( curr_item && (curr_item->Type() == PCB_DIMENSION_T) && curr_item->IsNew() )
+ {
+ curr_item = (BOARD_ITEM*) EditDimension( (DIMENSION*) curr_item, aDC );
+ SetCurItem( curr_item );
+ m_canvas->SetAutoPanRequest( true );
+ }
+ else
+ {
+ DisplayError( this,
+ wxT( "PCB_EDIT_FRAME::OnLeftClick() error item is not a DIMENSION" ) );
+ }
+
+ break;
+
+ case ID_PCB_DELETE_ITEM_BUTT:
+ if( !curr_item || !curr_item->GetFlags() )
+ {
+ curr_item = PcbGeneralLocateAndDisplay();
+
+ if( curr_item && (curr_item->GetFlags() == 0) )
+ {
+ RemoveStruct( curr_item, aDC );
+ SetCurItem( curr_item = NULL );
+ }
+ }
+
+ break;
+
+ case ID_PCB_PLACE_OFFSET_COORD_BUTT:
+ m_canvas->DrawAuxiliaryAxis( aDC, GR_XOR );
+ SetAuxOrigin( GetCrossHairPosition() );
+ m_canvas->DrawAuxiliaryAxis( aDC, GR_COPY );
+ OnModify();
+ break;
+
+ case ID_PCB_PLACE_GRID_COORD_BUTT:
+ m_canvas->DrawGridAxis( aDC, GR_XOR, GetBoard()->GetGridOrigin() );
+ SetGridOrigin( GetCrossHairPosition() );
+ m_canvas->DrawGridAxis( aDC, GR_COPY, GetBoard()->GetGridOrigin() );
+ break;
+
+ default:
+ DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() id error" ) );
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ break;
+ }
+}
+
+
+/* handle the double click on the mouse left button
+ */
+void PCB_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition )
+{
+ BOARD_ITEM* curr_item = GetCurItem();
+
+ switch( GetToolId() )
+ {
+ case ID_NO_TOOL_SELECTED:
+ if( (curr_item == NULL) || (curr_item->GetFlags() == 0) )
+ {
+ curr_item = PcbGeneralLocateAndDisplay();
+ }
+
+ if( (curr_item == NULL) || (curr_item->GetFlags() != 0) )
+ break;
+
+ SendMessageToEESCHEMA( curr_item );
+
+ // An item is found
+ SetCurItem( curr_item );
+
+ switch( curr_item->Type() )
+ {
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ if( curr_item->IsNew() )
+ {
+ if( End_Route( (TRACK*) curr_item, aDC ) )
+ m_canvas->SetAutoPanRequest( false );
+ }
+ else if( curr_item->GetFlags() == 0 )
+ {
+ Edit_TrackSegm_Width( aDC, (TRACK*) curr_item );
+ }
+
+ break;
+
+ case PCB_TEXT_T:
+ case PCB_PAD_T:
+ case PCB_MODULE_T:
+ case PCB_TARGET_T:
+ case PCB_DIMENSION_T:
+ case PCB_MODULE_TEXT_T:
+ OnEditItemRequest( aDC, curr_item );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case PCB_LINE_T:
+ OnEditItemRequest( aDC, curr_item );
+ break;
+
+ case PCB_ZONE_AREA_T:
+ if( curr_item->GetFlags() )
+ break;
+
+ OnEditItemRequest( aDC, curr_item );
+ break;
+
+ default:
+ break;
+ }
+
+ break; // end case 0
+
+ case ID_TRACK_BUTT:
+ if( curr_item && curr_item->IsNew() )
+ {
+ if( End_Route( (TRACK*) curr_item, aDC ) )
+ m_canvas->SetAutoPanRequest( false );
+ }
+
+ break;
+
+ case ID_PCB_ZONES_BUTT:
+ case ID_PCB_KEEPOUT_AREA_BUTT:
+ if( End_Zone( aDC ) )
+ {
+ m_canvas->SetAutoPanRequest( false );
+ SetCurItem( NULL );
+ }
+
+ break;
+
+ case ID_PCB_ADD_LINE_BUTT:
+ case ID_PCB_ARC_BUTT:
+ case ID_PCB_CIRCLE_BUTT:
+ if( curr_item == NULL )
+ break;
+
+ if( curr_item->Type() != PCB_LINE_T )
+ {
+ DisplayError( this, wxT( "curr_item Type error" ) );
+ m_canvas->SetAutoPanRequest( false );
+ break;
+ }
+
+ if( curr_item->IsNew() )
+ {
+ End_Edge( (DRAWSEGMENT*) curr_item, aDC );
+ m_canvas->SetAutoPanRequest( false );
+ SetCurItem( NULL );
+ }
+
+ break;
+ }
+}
+
+
+void PCB_EDIT_FRAME::OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem )
+{
+ switch( aItem->Type() )
+ {
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ Edit_TrackSegm_Width( aDC, static_cast<TRACK*>( aItem ) );
+ break;
+
+ case PCB_TEXT_T:
+ InstallTextPCBOptionsFrame( static_cast<TEXTE_PCB*>( aItem ), aDC );
+ break;
+
+ case PCB_PAD_T:
+ InstallPadOptionsFrame( static_cast<D_PAD*>( aItem ) );
+ break;
+
+ case PCB_MODULE_T:
+ InstallModuleOptionsFrame( static_cast<MODULE*>( aItem ), aDC );
+ break;
+
+ case PCB_TARGET_T:
+ ShowTargetOptionsDialog( static_cast<PCB_TARGET*>( aItem ), aDC );
+ break;
+
+ case PCB_DIMENSION_T:
+ ShowDimensionPropertyDialog( static_cast<DIMENSION*>( aItem ), aDC );
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ InstallTextModOptionsFrame( static_cast<TEXTE_MODULE*>( aItem ), aDC );
+ break;
+
+ case PCB_LINE_T:
+ InstallGraphicItemPropertiesDialog( static_cast<DRAWSEGMENT*>( aItem ), aDC );
+ break;
+
+ case PCB_ZONE_AREA_T:
+ Edit_Zone_Params( aDC, static_cast<ZONE_CONTAINER*>( aItem ) );
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/pcbnew/onrightclick.cpp b/pcbnew/onrightclick.cpp
new file mode 100644
index 0000000..68c83a3
--- /dev/null
+++ b/pcbnew/onrightclick.cpp
@@ -0,0 +1,1095 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2007-2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/onrightclick.cpp
+ * @brief Right mouse button functions.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <macros.h>
+#include <base_units.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_pcb_text.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <pcbnew_id.h>
+#include <hotkeys.h>
+#include <collectors.h>
+#include <menus_helpers.h>
+
+
+static wxMenu* Append_Track_Width_List( BOARD* aBoard );
+
+
+bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
+{
+ wxString msg;
+ STATUS_FLAGS flags = 0;
+ bool trackFound = false; // Flag set to true,
+ // if a track is being the cursor, to avoid
+ // to display menus relative to tracks twice
+ bool blockActive = !GetScreen()->m_BlockLocate.IsIdle();
+
+ BOARD_ITEM* item = GetCurItem();
+
+ m_canvas->SetCanStartBlock( -1 ); // Avoid to start a block command when clicking on menu
+
+ // If a command or a block is in progress:
+ // Put the Cancel command (if needed) and the End command
+
+ if( blockActive )
+ {
+ createPopUpBlockMenu( aPopMenu );
+ aPopMenu->AppendSeparator();
+ return true;
+ }
+
+ if( GetToolId() != ID_NO_TOOL_SELECTED )
+ {
+ if( item && item->GetFlags() )
+ {
+ AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ),
+ KiBitmap( cancel_xpm ) );
+ }
+ else
+ {
+ AddMenuItem( aPopMenu, ID_POPUP_CLOSE_CURRENT_TOOL,
+ _( "End Tool" ), KiBitmap( cursor_xpm ) );
+ }
+
+ aPopMenu->AppendSeparator();
+ }
+ else
+ {
+ if( item && item->GetFlags() )
+ {
+ AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND,
+ _( "Cancel" ), KiBitmap( cancel_xpm ) );
+ aPopMenu->AppendSeparator();
+ }
+ }
+
+ // Select a proper item
+
+ wxPoint cursorPos = GetCrossHairPosition();
+ wxPoint selectPos = m_Collector->GetRefPos();
+
+ selectPos = GetNearestGridPosition( selectPos );
+
+ /* We can reselect another item only if there are no item being edited
+ * because ALL moving functions use GetCurItem(), therefore GetCurItem()
+ * must return the same item during moving. We know an item is moving
+ * if( item && (item->m_Flags != 0)) is true and after calling
+ * PcbGeneralLocateAndDisplay(), GetCurItem() is any arbitrary BOARD_ITEM,
+ * not the current item being edited. In such case we cannot call
+ * PcbGeneralLocateAndDisplay().
+ */
+ if( !item || (item->GetFlags() == 0) )
+ {
+ // show the "item selector" menu if no item selected or
+ // if there is a selected item but the mouse has moved
+ // (therefore a new item is perhaps under the cursor)
+ if( !item || cursorPos != selectPos )
+ {
+ m_canvas->SetAbortRequest( false );
+ PcbGeneralLocateAndDisplay();
+
+ if( m_canvas->GetAbortRequest() )
+ {
+ return false;
+ }
+ }
+ }
+
+ item = GetCurItem();
+ flags = item ? item->GetFlags() : 0;
+
+ // Add the context menu, which depends on the picked item:
+ if( item )
+ {
+ switch( item->Type() )
+ {
+ case PCB_MODULE_T:
+ createPopUpMenuForFootprints( (MODULE*) item, aPopMenu );
+
+ if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_MODULE ) )
+ {
+ aPopMenu->AppendSeparator();
+
+ if( !( (MODULE*) item )->IsLocked() )
+ {
+ msg = AddHotkeyName( _("Lock Footprint" ), g_Board_Editor_Hokeys_Descr,
+ HK_LOCK_UNLOCK_FOOTPRINT );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_AUTOPLACE_FIXE_MODULE, msg,
+ KiBitmap( locked_xpm ) );
+ }
+ else
+ {
+ msg = AddHotkeyName( _( "Unlock Footprint" ), g_Board_Editor_Hokeys_Descr,
+ HK_LOCK_UNLOCK_FOOTPRINT );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_AUTOPLACE_FREE_MODULE, msg,
+ KiBitmap( unlocked_xpm ) );
+ }
+
+ if( !flags )
+ aPopMenu->Append( ID_POPUP_PCB_AUTOPLACE_CURRENT_MODULE,
+ _( "Automatically Place Footprint" ) );
+ }
+
+ if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) )
+ {
+ if( !flags )
+ aPopMenu->Append( ID_POPUP_PCB_AUTOROUTE_MODULE,
+ _( "Automatically Route Footprint" ) );
+ }
+ break;
+
+ case PCB_PAD_T:
+ createPopUpMenuForFpPads( static_cast<D_PAD*>( item ), aPopMenu );
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ createPopUpMenuForFpTexts( static_cast<TEXTE_MODULE*>( item ), aPopMenu );
+ break;
+
+ case PCB_LINE_T: // Some graphic items on technical layers
+ if( (flags & IS_NEW) )
+ {
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_STOP_CURRENT_DRAWING,
+ _( "End Drawing" ), KiBitmap( checked_ok_xpm ) );
+ }
+
+ if( !flags )
+ {
+ msg = AddHotkeyName( _( "Move Drawing" ), g_Board_Editor_Hokeys_Descr,
+ HK_MOVE_ITEM );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_DRAWING_REQUEST,
+ msg, KiBitmap( move_xpm ) );
+
+ msg = AddHotkeyName( _( "Duplicate Drawing" ), g_Board_Editor_Hokeys_Descr,
+ HK_DUPLICATE_ITEM );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_DUPLICATE_ITEM,
+ msg, KiBitmap( duplicate_line_xpm ) );
+
+ msg = AddHotkeyName( _("Move Drawing Exactly" ), g_Board_Editor_Hokeys_Descr,
+ HK_MOVE_ITEM_EXACT );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_EXACT,
+ msg, KiBitmap( move_line_xpm ) );
+
+ msg = AddHotkeyName( _("Create Drawing Array" ), g_Board_Editor_Hokeys_Descr,
+ HK_CREATE_ARRAY );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_CREATE_ARRAY,
+ msg, KiBitmap( array_line_xpm ) );
+
+ msg = AddHotkeyName( _( "Edit Drawing" ), g_Board_Editor_Hokeys_Descr,
+ HK_EDIT_ITEM );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_DRAWING,
+ msg, KiBitmap( edit_xpm ) );
+
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING,
+ _( "Delete Drawing" ), KiBitmap( delete_xpm ) );
+
+ if( !IsCopperLayer( item->GetLayer() ) )
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING_LAYER,
+ _( "Delete All Drawings on Layer" ), KiBitmap( delete_xpm ) );
+ }
+
+ break;
+
+ case PCB_ZONE_T: // Item used to fill a zone
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_ZONE,
+ _( "Delete Zone Filling" ), KiBitmap( delete_xpm ) );
+ break;
+
+ case PCB_ZONE_AREA_T: // Item used to handle a zone area (outlines, holes ...)
+ if( flags & IS_NEW )
+ {
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE,
+ _( "Close Zone Outline" ), KiBitmap( checked_ok_xpm ) );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_ZONE_LAST_CREATED_CORNER,
+ _( "Delete Last Corner" ), KiBitmap( delete_xpm ) );
+ }
+ else
+ {
+ createPopUpMenuForZones( (ZONE_CONTAINER*) item, aPopMenu );
+ }
+
+ break;
+
+ case PCB_TEXT_T:
+ createPopUpMenuForTexts( (TEXTE_PCB*) item, aPopMenu );
+ break;
+
+ case PCB_TRACE_T:
+ case PCB_VIA_T:
+ trackFound = true;
+ createPopupMenuForTracks( (TRACK*) item, aPopMenu );
+ break;
+
+ case PCB_MARKER_T:
+ createPopUpMenuForMarkers( (MARKER_PCB*) item, aPopMenu );
+ break;
+
+ case PCB_DIMENSION_T:
+ if( !flags )
+ {
+ msg = AddHotkeyName( _( "Edit Dimension" ), g_Board_Editor_Hokeys_Descr,
+ HK_EDIT_ITEM );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_DIMENSION, msg, KiBitmap( edit_xpm ) );
+
+ msg = AddHotkeyName( _( "Move Dimension Text" ), g_Board_Editor_Hokeys_Descr,
+ HK_MOVE_ITEM );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_TEXT_DIMENSION_REQUEST,
+ msg, KiBitmap( move_text_xpm ) );
+
+ msg = AddHotkeyName( _( "Duplicate Dimension" ), g_Board_Editor_Hokeys_Descr,
+ HK_DUPLICATE_ITEM );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_DUPLICATE_ITEM,
+ msg, KiBitmap( duplicate_text_xpm ) );
+
+ msg = AddHotkeyName( _("Move Dimension Exactly" ), g_Board_Editor_Hokeys_Descr,
+ HK_MOVE_ITEM_EXACT );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_EXACT,
+ msg, KiBitmap( move_text_xpm ) );
+
+ msg = AddHotkeyName( _( "Delete Dimension" ), g_Board_Editor_Hokeys_Descr,
+ HK_DELETE );
+
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DIMENSION,
+ msg, KiBitmap( delete_xpm ) );
+ }
+ break;
+
+ case PCB_TARGET_T:
+ if( !flags )
+ {
+ msg = AddHotkeyName( _( "Move Target" ), g_Board_Editor_Hokeys_Descr,
+ HK_MOVE_ITEM );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_MIRE_REQUEST,
+ msg, KiBitmap( move_target_xpm ) );
+
+ msg = AddHotkeyName( _("Move Target Exactly" ), g_Board_Editor_Hokeys_Descr,
+ HK_MOVE_ITEM_EXACT );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_MOVE_EXACT,
+ msg, KiBitmap( move_target_xpm ) );
+
+ msg = AddHotkeyName( _( "Duplicate Target" ), g_Board_Editor_Hokeys_Descr,
+ HK_DUPLICATE_ITEM );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_DUPLICATE_ITEM,
+ msg, KiBitmap( duplicate_target_xpm ) );
+
+ msg = AddHotkeyName( _( "Edit Target" ), g_Board_Editor_Hokeys_Descr,
+ HK_EDIT_ITEM );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_EDIT_MIRE, msg, KiBitmap( edit_xpm ) );
+
+ msg = AddHotkeyName( _( "Delete Target" ), g_Board_Editor_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_MIRE,
+ msg, KiBitmap( delete_xpm ) );
+ }
+
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ case SCREEN_T:
+ case TYPE_NOT_INIT:
+ case PCB_T:
+ msg.Printf( wxT( "PCB_EDIT_FRAME::OnRightClick() Error: unexpected DrawType %d" ),
+ item->Type() );
+ wxMessageBox( msg );
+ SetCurItem( NULL );
+ break;
+
+ default:
+ msg.Printf( wxT( "PCB_EDIT_FRAME::OnRightClick() Error: unknown DrawType %d" ),
+ item->Type() );
+ wxMessageBox( msg );
+
+ // Attempt to clear error (but should no occurs )
+ if( item->Type() >= MAX_STRUCT_TYPE_ID )
+ SetCurItem( NULL );
+
+ break;
+ }
+
+ aPopMenu->AppendSeparator();
+ }
+
+ if( !flags )
+ {
+ msg = AddHotkeyName( _( "Get and Move Footprint" ),
+ g_Board_Editor_Hokeys_Descr, HK_GET_AND_MOVE_FOOTPRINT );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST,
+ msg, KiBitmap( move_module_xpm ) );
+ }
+
+ // Display context sensitive commands:
+ switch( GetToolId() )
+ {
+ case ID_PCB_ZONES_BUTT:
+ if( GetBoard()->m_ZoneDescriptorList.size() > 0 )
+ {
+ aPopMenu->AppendSeparator();
+ msg = AddHotkeyName( _( "Fill or Refill All Zones" ),
+ g_Board_Editor_Hokeys_Descr, HK_ZONE_FILL_OR_REFILL );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_FILL_ALL_ZONES,
+ msg, KiBitmap( fill_zone_xpm ) );
+ msg = AddHotkeyName( _( "Remove Filled Areas in All Zones" ),
+ g_Board_Editor_Hokeys_Descr, HK_ZONE_REMOVE_FILLED );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES,
+ msg, KiBitmap( zone_unfill_xpm ) );
+ aPopMenu->AppendSeparator();
+ }
+
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER,
+ _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) );
+ aPopMenu->AppendSeparator();
+ break;
+
+ case ID_PCB_KEEPOUT_AREA_BUTT:
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER,
+ _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) );
+ aPopMenu->AppendSeparator();
+ break;
+
+ case ID_TRACK_BUTT:
+ if ( ! trackFound ) // This menu is already added when a track is located
+ {
+ aPopMenu->AppendSeparator();
+ msg = AddHotkeyName( _( "Begin Track" ),
+ g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK,
+ msg, KiBitmap( add_tracks_xpm ) );
+
+ AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard() ),
+ ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ),
+ KiBitmap( width_track_xpm ) );
+
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_CU_LAYER,
+ _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER_PAIR,
+ _( "Select Layer Pair for Vias" ), KiBitmap( select_layer_pair_xpm ) );
+ aPopMenu->AppendSeparator();
+ }
+ break;
+
+ case ID_PCB_CIRCLE_BUTT:
+ case ID_PCB_ARC_BUTT:
+ case ID_PCB_ADD_TEXT_BUTT:
+ case ID_PCB_ADD_LINE_BUTT:
+ case ID_PCB_DIMENSION_BUTT:
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_NO_CU_LAYER,
+ _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) );
+ aPopMenu->AppendSeparator();
+ break;
+
+ case ID_PCB_MODULE_BUTT:
+ if( !flags )
+ {
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_DISPLAY_FOOTPRINT_DOC,
+ _( "Footprint Documentation" ), KiBitmap( book_xpm ) );
+ aPopMenu->AppendSeparator();
+ }
+ break;
+
+ case ID_NO_TOOL_SELECTED:
+ if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_MODULE ) )
+ {
+ wxMenu* commands = new wxMenu;
+ AddMenuItem( aPopMenu, commands, ID_POPUP_PCB_AUTOPLACE_COMMANDS,
+ _( "Global Spread and Place" ), KiBitmap( move_xpm ) );
+ AddMenuItem( commands, ID_POPUP_PCB_AUTOPLACE_FREE_ALL_MODULES,
+ _( "Unlock All Footprints" ), KiBitmap( unlocked_xpm ) );
+ AddMenuItem( commands, ID_POPUP_PCB_AUTOPLACE_FIXE_ALL_MODULES,
+ _( "Lock All Footprints" ), KiBitmap( locked_xpm ) );
+ commands->AppendSeparator();
+ AddMenuItem( commands, ID_POPUP_PCB_SPREAD_ALL_MODULES,
+ _( "Spread out All Footprints" ), KiBitmap( move_xpm ) );
+ commands->Append( ID_POPUP_PCB_SPREAD_NEW_MODULES,
+ _( "Spread out Footprints not Already on Board" ) );
+ commands->AppendSeparator();
+ commands->Append( ID_POPUP_PCB_AUTOPLACE_ALL_MODULES,
+ _( "Automatically Place All Footprints" ) );
+ commands->Append( ID_POPUP_PCB_AUTOPLACE_NEW_MODULES,
+ _( "Automatically Place New Footprints" ) );
+ commands->Append( ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE,
+ _( "Automatically Place Next Footprints" ) );
+ commands->AppendSeparator();
+ AddMenuItem( commands, ID_POPUP_PCB_REORIENT_ALL_MODULES,
+ _( "Orient All Footprints" ), KiBitmap( rotate_module_cw_xpm ) );
+ aPopMenu->AppendSeparator();
+ }
+
+ if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) )
+ {
+ wxMenu* commands = new wxMenu;
+ aPopMenu->Append( ID_POPUP_PCB_AUTOROUTE_COMMANDS, _( "Autoroute" ), commands );
+ AddMenuItem( commands, ID_POPUP_PCB_SELECT_LAYER_PAIR,
+ _( "Select Layer Pair" ), KiBitmap( select_layer_pair_xpm ) );
+ commands->AppendSeparator();
+ commands->Append( ID_POPUP_PCB_AUTOROUTE_ALL_MODULES,
+ _( "Automatically Route All Footprints" ) );
+ commands->AppendSeparator();
+ commands->Append( ID_POPUP_PCB_AUTOROUTE_RESET_UNROUTED, _( "Reset Unrouted" ) );
+ aPopMenu->AppendSeparator();
+ }
+
+ if( !trackFound )
+ {
+ msg = AddHotkeyName( _( "Begin Track" ), g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK, msg, KiBitmap( add_tracks_xpm ) );
+
+ AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard() ),
+ ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ),
+ KiBitmap( width_track_xpm ) );
+
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER,
+ _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) );
+ aPopMenu->AppendSeparator();
+ }
+ break;
+ }
+
+ return true;
+}
+
+
+/* Create Pop sub menu for block commands
+ */
+void PCB_EDIT_FRAME::createPopUpBlockMenu( wxMenu* menu )
+{
+ AddMenuItem( menu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel Block" ),
+ KiBitmap( cancel_xpm ) );
+ AddMenuItem( menu, ID_POPUP_ZOOM_BLOCK, _( "Zoom Block" ), KiBitmap( zoom_area_xpm ) );
+ menu->AppendSeparator();
+ AddMenuItem( menu, ID_POPUP_PLACE_BLOCK, _( "Place Block" ), KiBitmap( checked_ok_xpm ) );
+ AddMenuItem( menu, ID_POPUP_COPY_BLOCK, _( "Copy Block" ), KiBitmap( copyblock_xpm ) );
+ AddMenuItem( menu, ID_POPUP_FLIP_BLOCK, _( "Flip Block" ), KiBitmap( mirror_footprint_axisX_xpm ) );
+ AddMenuItem( menu, ID_POPUP_ROTATE_BLOCK, _( "Rotate Block" ), KiBitmap( rotate_ccw_xpm ) );
+ AddMenuItem( menu, ID_POPUP_DELETE_BLOCK, _( "Delete Block" ), KiBitmap( delete_xpm ) );
+}
+
+
+/* Create command lines for a popup menu, for track and via editing
+ * also update Netclass selection
+ */
+void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
+{
+ wxPoint cursorPosition = GetCrossHairPosition();
+ wxString msg;
+
+ SetCurrentNetClass( Track->GetNetClassName() );
+
+ int flags = Track->GetFlags();
+
+ if( flags == 0 )
+ {
+ msg = AddHotkeyName( _( "Begin Track" ),
+ g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_BEGIN_TRACK,
+ msg, KiBitmap( add_tracks_xpm ) );
+
+ if( Track->Type() == PCB_VIA_T )
+ {
+ msg = AddHotkeyName( _( "Drag Via" ), g_Board_Editor_Hokeys_Descr,
+ HK_DRAG_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_TRACK_NODE, msg,
+ KiBitmap( move_xpm ) );
+ }
+ else
+ {
+ if( Track->IsPointOnEnds( cursorPosition, -1 ) != 0 )
+ {
+ msg = AddHotkeyName( _( "Move Node" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_TRACK_NODE,
+ msg, KiBitmap( move_xpm ) );
+ }
+ else
+ {
+ msg = AddHotkeyName( _( "Drag Segments, Keep Slope" ), g_Board_Editor_Hokeys_Descr,
+ HK_DRAG_TRACK_KEEP_SLOPE );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_DRAG_TRACK_SEGMENT_KEEP_SLOPE,
+ msg, KiBitmap( drag_segment_withslope_xpm ) );
+
+ msg = AddHotkeyName( _( "Drag Segment" ), g_Board_Editor_Hokeys_Descr,
+ HK_DRAG_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_DRAG_TRACK_SEGMENT,
+ msg, KiBitmap( drag_track_segment_xpm ) );
+
+ msg = AddHotkeyName( _( "Duplicate Track" ), g_Board_Editor_Hokeys_Descr,
+ HK_DUPLICATE_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_DUPLICATE_ITEM,
+ msg, KiBitmap( duplicate_line_xpm ) );
+
+ msg = AddHotkeyName( _("Move Track Exactly" ), g_Board_Editor_Hokeys_Descr,
+ HK_MOVE_ITEM_EXACT );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_EXACT,
+ msg, KiBitmap( move_line_xpm ) );
+
+ msg = AddHotkeyName( _("Create Track Array" ), g_Board_Editor_Hokeys_Descr,
+ HK_CREATE_ARRAY );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_CREATE_ARRAY,
+ msg, KiBitmap( array_line_xpm ) );
+
+ AddMenuItem( PopMenu, ID_POPUP_PCB_BREAK_TRACK,
+ _( "Break Track" ), KiBitmap( break_line_xpm ) );
+ }
+ }
+
+ AddMenuItem( PopMenu, ID_POPUP_PCB_SELECT_CU_LAYER,
+ _( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) );
+ }
+ else if( flags & IS_DRAGGED ) // Drag via or node in progress
+ {
+ AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_MOVED_TRACK_NODE,
+ _( "Place Node" ), KiBitmap( checked_ok_xpm ) );
+ return;
+ }
+ else // Edition in progress
+ {
+ if( flags & IS_NEW )
+ {
+ msg = AddHotkeyName( _( "End Track" ), g_Board_Editor_Hokeys_Descr, HK_LEFT_DCLICK );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_END_TRACK, msg, KiBitmap( checked_ok_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Place Through Via" ), g_Board_Editor_Hokeys_Descr, HK_ADD_THROUGH_VIA );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_THROUGH_VIA, msg, KiBitmap( via_xpm ) );
+
+ msg = AddHotkeyName( _( "Select Layer and Place Through Via" ),
+ g_Board_Editor_Hokeys_Descr, HK_SEL_LAYER_AND_ADD_THROUGH_VIA );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA,
+ msg, KiBitmap( select_w_layer_xpm ) );
+
+ if( GetDesignSettings().m_BlindBuriedViaAllowed )
+ {
+ msg = AddHotkeyName( _( "Place Blind/Buried Via" ),
+ g_Board_Editor_Hokeys_Descr, HK_ADD_BLIND_BURIED_VIA );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA, msg, KiBitmap( via_buried_xpm ) );
+
+ msg = AddHotkeyName( _( "Select Layer and Place Blind/Buried Via" ),
+ g_Board_Editor_Hokeys_Descr, HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA,
+ msg, KiBitmap( select_w_layer_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Switch Track Posture" ), g_Board_Editor_Hokeys_Descr,
+ HK_SWITCH_TRACK_POSTURE );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_SWITCH_TRACK_POSTURE, msg,
+ KiBitmap( change_entry_orient_xpm ) );
+
+ // See if we can place a Micro Via (4 or more layers, and start from an external layer):
+ if( IsMicroViaAcceptable() )
+ {
+ msg = AddHotkeyName( _( "Place Micro Via" ), g_Board_Editor_Hokeys_Descr,
+ HK_ADD_MICROVIA );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_MICROVIA, msg, KiBitmap( via_microvia_xpm ) );
+ }
+ }
+
+ // track Width control :
+ if( !flags )
+ {
+ if( Track->Type() == PCB_VIA_T )
+ {
+ msg = AddHotkeyName( _( "Change Via Size and Drill" ), g_Board_Editor_Hokeys_Descr,
+ HK_EDIT_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_TRACKSEG, msg, KiBitmap( width_segment_xpm ) );
+ }
+ else
+ {
+ msg = AddHotkeyName( _( "Change Segment Width" ), g_Board_Editor_Hokeys_Descr,
+ HK_EDIT_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_TRACKSEG, msg, KiBitmap( width_segment_xpm ) );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_TRACK,
+ _( "Change Track Width" ), KiBitmap( width_track_xpm ) );
+ }
+ }
+
+ // Allows switching to an other track/via size when routing
+ AddMenuItem( PopMenu, Append_Track_Width_List( GetBoard() ), ID_POPUP_PCB_SELECT_WIDTH,
+ _( "Select Track Width" ), KiBitmap( width_track_xpm ) );
+
+ // Delete control:
+ PopMenu->AppendSeparator();
+ wxMenu* trackdel_mnu = new wxMenu;
+ AddMenuItem( PopMenu, trackdel_mnu, ID_POPUP_PCB_DELETE_TRACK_MNU, _( "Delete" ),
+ KiBitmap( delete_xpm ) );
+
+ msg = AddHotkeyName( Track->Type()==PCB_VIA_T ?
+ _( "Delete Via" ) : _( "Delete Segment" ),
+ g_Board_Editor_Hokeys_Descr, HK_BACK_SPACE );
+
+ AddMenuItem( trackdel_mnu, ID_POPUP_PCB_DELETE_TRACKSEG, msg, KiBitmap( delete_line_xpm ) );
+
+ if( !flags )
+ {
+ msg = AddHotkeyName( _( "Delete Track" ), g_Board_Editor_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( trackdel_mnu, ID_POPUP_PCB_DELETE_TRACK, msg, KiBitmap( delete_track_xpm ) );
+ AddMenuItem( trackdel_mnu, ID_POPUP_PCB_DELETE_TRACKNET, _( "Delete Net" ),
+ KiBitmap( delete_net_xpm ) );
+ }
+
+ // Add global edition command
+ if( !flags )
+ {
+ PopMenu->AppendSeparator();
+ AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_ALL_VIAS_AND_TRACK_SIZE,
+ _( "Edit All Tracks and Vias" ), KiBitmap( width_track_via_xpm ) );
+ }
+
+ // Add lock/unlock flags menu:
+ wxMenu* trackflg_mnu = new wxMenu;
+
+ AddMenuItem( PopMenu, trackflg_mnu, ID_POPUP_PCB_SETFLAGS_TRACK_MNU, _( "Set Flags" ),
+ KiBitmap( flag_xpm ) );
+ trackflg_mnu->Append( ID_POPUP_PCB_LOCK_ON_TRACKSEG, _( "Locked: Yes" ), wxEmptyString, true );
+ trackflg_mnu->Append( ID_POPUP_PCB_LOCK_OFF_TRACKSEG, _( "Locked: No" ), wxEmptyString, true );
+
+ if( Track->GetState( TRACK_LOCKED ) )
+ trackflg_mnu->Check( ID_POPUP_PCB_LOCK_ON_TRACKSEG, true );
+ else
+ trackflg_mnu->Check( ID_POPUP_PCB_LOCK_OFF_TRACKSEG, true );
+
+ if( !flags )
+ {
+ trackflg_mnu->Append( ID_POPUP_PCB_LOCK_ON_TRACK, _( "Track Locked: Yes" ) );
+ trackflg_mnu->Append( ID_POPUP_PCB_LOCK_OFF_TRACK, _( "Track Locked: No" ) );
+ trackflg_mnu->AppendSeparator();
+ trackflg_mnu->Append( ID_POPUP_PCB_LOCK_ON_NET, _( "Net Locked: Yes" ) );
+ trackflg_mnu->Append( ID_POPUP_PCB_LOCK_OFF_NET, _( "Net Locked: No" ) );
+ }
+}
+
+
+/* Create the wxMenuitem list for zone outlines editing and zone filling
+ */
+void PCB_EDIT_FRAME::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* aPopMenu )
+{
+ wxString msg;
+
+ if( edge_zone->GetFlags() == IS_DRAGGED )
+ {
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_PLACE_DRAGGED_ZONE_OUTLINE_SEGMENT,
+ _( "Place Edge Outline" ), KiBitmap( checked_ok_xpm ) );
+ }
+ else if( edge_zone->GetFlags() )
+ {
+ if( (edge_zone->GetFlags() & IN_EDIT ) )
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_PLACE_ZONE_CORNER,
+ _( "Place Corner" ), KiBitmap( checked_ok_xpm ) );
+ else
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_PLACE_ZONE_OUTLINES,
+ _( "Place Zone" ), KiBitmap( checked_ok_xpm ) );
+ }
+ else
+ {
+ wxMenu* zones_menu = new wxMenu();
+
+ AddMenuItem( aPopMenu, zones_menu, -1,
+ edge_zone->GetIsKeepout() ? _("Keepout Area") : _( "Zones" ),
+ KiBitmap( add_zone_xpm ) );
+
+ if( edge_zone->HitTestForCorner( RefPos( true ) ) >= 0 )
+ {
+ AddMenuItem( zones_menu, ID_POPUP_PCB_MOVE_ZONE_CORNER,
+ _( "Move Corner" ), KiBitmap( move_xpm ) );
+ AddMenuItem( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CORNER,
+ _( "Delete Corner" ), KiBitmap( delete_xpm ) );
+ }
+ else if( edge_zone->HitTestForEdge( RefPos( true ) ) >= 0 )
+ {
+ AddMenuItem( zones_menu, ID_POPUP_PCB_ADD_ZONE_CORNER,
+ _( "Create Corner" ), KiBitmap( add_corner_xpm ) );
+ msg = AddHotkeyName( _( "Drag Outline Segment" ), g_Board_Editor_Hokeys_Descr,
+ HK_DRAG_ITEM );
+ AddMenuItem( zones_menu, ID_POPUP_PCB_DRAG_ZONE_OUTLINE_SEGMENT,
+ msg, KiBitmap( drag_outline_segment_xpm ) );
+ }
+
+ zones_menu->AppendSeparator();
+ AddMenuItem( zones_menu, ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE,
+ _( "Add Similar Zone" ), KiBitmap( add_zone_xpm ) );
+
+ AddMenuItem( zones_menu, ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE,
+ _( "Add Cutout Area" ), KiBitmap( add_zone_cutout_xpm ) );
+
+ AddMenuItem( zones_menu, ID_POPUP_PCB_ZONE_DUPLICATE,
+ _( "Duplicate Zone Onto Layer" ), KiBitmap( zone_duplicate_xpm ) );
+
+ zones_menu->AppendSeparator();
+
+ if( ! edge_zone->GetIsKeepout() )
+ AddMenuItem( zones_menu, ID_POPUP_PCB_FILL_ZONE, _( "Fill Zone" ),
+ KiBitmap( fill_zone_xpm ) );
+
+ if( !edge_zone->GetFilledPolysList().IsEmpty() )
+ {
+ AddMenuItem( zones_menu, ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_CURRENT_ZONE,
+ _( "Remove Filled Areas in Zone" ), KiBitmap( zone_unfill_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Move Zone" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
+ AddMenuItem( zones_menu, ID_POPUP_PCB_MOVE_ZONE_OUTLINES, msg, KiBitmap( move_xpm ) );
+
+ msg = AddHotkeyName( _("Move Zone Exactly" ), g_Board_Editor_Hokeys_Descr,
+ HK_MOVE_ITEM_EXACT );
+ AddMenuItem( zones_menu, ID_POPUP_PCB_MOVE_EXACT,
+ msg, KiBitmap( move_zone_xpm ) );
+
+ msg = AddHotkeyName( _( "Edit Zone Properties" ), g_Board_Editor_Hokeys_Descr,
+ HK_EDIT_ITEM );
+ AddMenuItem( zones_menu, ID_POPUP_PCB_EDIT_ZONE_PARAMS,
+ msg, KiBitmap( edit_xpm ) );
+
+ zones_menu->AppendSeparator();
+
+ if( edge_zone->GetSelectedCorner() >= 0 &&
+ edge_zone->Outline()->IsCutoutContour( edge_zone->GetSelectedCorner() ) )
+ AddMenuItem( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CUTOUT,
+ _( "Delete Cutout" ), KiBitmap( delete_xpm ) );
+
+ AddMenuItem( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CONTAINER,
+ _( "Delete Zone Outline" ), KiBitmap( delete_xpm ) );
+ }
+}
+
+
+/* Create the wxMenuitem list for footprint editing
+ */
+void PCB_EDIT_FRAME::createPopUpMenuForFootprints( MODULE* aModule, wxMenu* menu )
+{
+ wxMenu* sub_menu_footprint;
+ int flags = aModule->GetFlags();
+ wxString msg;
+
+ sub_menu_footprint = new wxMenu;
+
+ msg = aModule->GetSelectMenuText();
+ AddMenuItem( menu, sub_menu_footprint, -1, msg, KiBitmap( module_xpm ) );
+
+ if( !flags )
+ {
+ msg = AddHotkeyName( _( "Move" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
+ AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_MOVE_MODULE_REQUEST,
+ msg, KiBitmap( move_module_xpm ) );
+
+ msg = AddHotkeyName( _( "Drag" ), g_Board_Editor_Hokeys_Descr, HK_DRAG_ITEM );
+ AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_DRAG_MODULE_REQUEST,
+ msg, KiBitmap( drag_module_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Rotate +" ), g_Board_Editor_Hokeys_Descr, HK_ROTATE_ITEM );
+ AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE,
+ msg, KiBitmap( rotate_module_ccw_xpm ) );
+ AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE,
+ _( "Rotate -" ), KiBitmap( rotate_module_cw_xpm ) );
+ msg = AddHotkeyName( _( "Flip" ), g_Board_Editor_Hokeys_Descr, HK_FLIP_ITEM );
+ AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_CHANGE_SIDE_MODULE,
+ msg, KiBitmap( mirror_footprint_axisX_xpm ) );
+
+ if( !flags )
+ {
+ msg = AddHotkeyName( _( "Edit Parameters" ),
+ g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM );
+ AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE_PRMS, msg,
+ KiBitmap( edit_module_xpm ) );
+
+ msg = AddHotkeyName( _( "Edit with Footprint Editor" ),
+ g_Board_Editor_Hokeys_Descr, HK_EDIT_MODULE_WITH_MODEDIT );
+ AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT,
+ msg, KiBitmap( module_editor_xpm ) );
+
+ sub_menu_footprint->AppendSeparator();
+
+ msg = AddHotkeyName( _( "Delete Footprint" ),
+ g_Board_Editor_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_DELETE_MODULE,
+ msg, KiBitmap( delete_module_xpm ) );
+
+ sub_menu_footprint->AppendSeparator();
+
+ msg = AddHotkeyName( _("Move Footprint Exactly" ), g_Board_Editor_Hokeys_Descr,
+ HK_MOVE_ITEM_EXACT );
+ AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_MOVE_EXACT,
+ msg, KiBitmap( move_module_xpm ) );
+
+ msg = AddHotkeyName( _( "Duplicate Footprint" ), g_Board_Editor_Hokeys_Descr,
+ HK_DUPLICATE_ITEM );
+ AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_DUPLICATE_ITEM,
+ msg, KiBitmap( duplicate_module_xpm ) );
+
+ msg = AddHotkeyName( _("Create Footprint Array" ), g_Board_Editor_Hokeys_Descr,
+ HK_CREATE_ARRAY );
+ AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_CREATE_ARRAY,
+ msg, KiBitmap( array_module_xpm ) );
+
+ AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EXCHANGE_FOOTPRINTS,
+ _( "Exchange Footprint(s)" ), KiBitmap( import_module_xpm ) );
+ }
+}
+
+
+/* Create the wxMenuitem list for editing texts on footprints
+ */
+void PCB_EDIT_FRAME::createPopUpMenuForFpTexts( TEXTE_MODULE* FpText, wxMenu* menu )
+{
+ wxMenu* sub_menu_Fp_text;
+ int flags = FpText->GetFlags();
+
+ wxString msg = FpText->GetSelectMenuText();
+
+ sub_menu_Fp_text = new wxMenu;
+
+ AddMenuItem( menu, sub_menu_Fp_text, -1, msg, KiBitmap( footprint_text_xpm ) );
+
+ if( !flags )
+ {
+ msg = AddHotkeyName( _( "Move Text" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
+ AddMenuItem( sub_menu_Fp_text, ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST,
+ msg, KiBitmap( move_field_xpm ) );
+
+ msg = AddHotkeyName( _("Move Text Exactly" ), g_Board_Editor_Hokeys_Descr,
+ HK_MOVE_ITEM_EXACT );
+ AddMenuItem( sub_menu_Fp_text, ID_POPUP_PCB_MOVE_EXACT,
+ msg, KiBitmap( move_text_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Rotate Text" ), g_Board_Editor_Hokeys_Descr, HK_ROTATE_ITEM );
+ AddMenuItem( sub_menu_Fp_text, ID_POPUP_PCB_ROTATE_TEXTMODULE,
+ msg, KiBitmap( rotate_field_xpm ) );
+
+ if( !flags )
+ {
+ msg = AddHotkeyName( _( "Edit Text" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM );
+ AddMenuItem( sub_menu_Fp_text, ID_POPUP_PCB_EDIT_TEXTMODULE,
+ msg, KiBitmap( edit_text_xpm ) );
+ AddMenuItem( sub_menu_Fp_text, ID_POPUP_PCB_RESET_TEXT_SIZE,
+ _( "Reset Size" ), KiBitmap( reset_text_xpm ) );
+ }
+
+ // Graphic texts can be deleted only if are not currently edited.
+ if( !flags && FpText->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
+ {
+ AddMenuItem( sub_menu_Fp_text, ID_POPUP_PCB_DELETE_TEXTMODULE,
+ _( "Delete Text" ), KiBitmap( delete_xpm ) );
+ }
+
+ if( !flags )
+ {
+ MODULE* module = (MODULE*) FpText->GetParent();
+
+ if( module )
+ {
+ menu->AppendSeparator();
+ createPopUpMenuForFootprints( module, menu );
+ }
+ }
+}
+
+
+/* Create pop menu for pads
+ * also update Netclass selection
+ */
+void PCB_EDIT_FRAME::createPopUpMenuForFpPads( D_PAD* Pad, wxMenu* menu )
+{
+ wxMenu* sub_menu_Pad;
+ int flags = Pad->GetFlags();
+
+ if( flags ) // Currently in edit, no others commands possible
+ return;
+
+ SetCurrentNetClass( Pad->GetNetClassName() );
+
+ wxString msg = Pad->GetSelectMenuText();
+
+ sub_menu_Pad = new wxMenu;
+ AddMenuItem( menu, sub_menu_Pad, -1, msg, KiBitmap( pad_xpm ) );
+
+ AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_MOVE_PAD_REQUEST, _( "Move Pad" ),
+ KiBitmap( move_pad_xpm ) );
+ AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_DRAG_PAD_REQUEST, _( "Drag Pad" ),
+ KiBitmap( drag_pad_xpm ) );
+
+ msg = AddHotkeyName( _( "Edit Pad" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM );
+ AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_EDIT_PAD, msg, KiBitmap( options_pad_xpm ) );
+ sub_menu_Pad->AppendSeparator();
+
+ AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_IMPORT_PAD_SETTINGS,
+ _( "Copy Current Settings to this Pad" ),
+ wxEmptyString,
+ KiBitmap( options_new_pad_xpm ) );
+ AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_EXPORT_PAD_SETTINGS,
+ _( "Copy this Pad Settings to Current Settings" ),
+ wxEmptyString,
+ KiBitmap( export_options_pad_xpm ) );
+
+ AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS,
+ _( "Edit All Pads" ),
+ _( "Copy this pad's settings to all pads in this footprint (or similar footprints)" ),
+ KiBitmap( global_options_pad_xpm ) );
+ sub_menu_Pad->AppendSeparator();
+
+ AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_DELETE_PAD, _( "Delete" ), KiBitmap( delete_pad_xpm ) );
+
+ if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) )
+ {
+ menu->Append( ID_POPUP_PCB_AUTOROUTE_PAD, _( "Automatically Route Pad" ) );
+ menu->Append( ID_POPUP_PCB_AUTOROUTE_NET, _( "Automatically Route Net" ) );
+ }
+
+ MODULE* module = Pad->GetParent();
+
+ if( module )
+ {
+ menu->AppendSeparator();
+ createPopUpMenuForFootprints( module, menu );
+ }
+}
+
+
+// Create pop menu for pcb texts
+void PCB_EDIT_FRAME::createPopUpMenuForTexts( TEXTE_PCB* Text, wxMenu* menu )
+{
+ wxMenu* sub_menu_Text;
+ int flags = Text->GetFlags();
+
+ wxString msg = Text->GetSelectMenuText();
+
+ sub_menu_Text = new wxMenu;
+
+ AddMenuItem( menu, sub_menu_Text, -1, msg, KiBitmap( add_text_xpm ) );
+
+ if( !flags )
+ {
+ msg = AddHotkeyName( _( "Move" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
+ AddMenuItem( sub_menu_Text, ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST,
+ msg, KiBitmap( move_text_xpm ) );
+ msg = AddHotkeyName( _( "Copy" ), g_Board_Editor_Hokeys_Descr, HK_COPY_ITEM );
+ AddMenuItem( sub_menu_Text, ID_POPUP_PCB_COPY_TEXTEPCB,
+ msg, KiBitmap( copyblock_xpm ) );
+ }
+
+ msg = AddHotkeyName( _( "Rotate" ), g_Board_Editor_Hokeys_Descr, HK_ROTATE_ITEM );
+ AddMenuItem( sub_menu_Text, ID_POPUP_PCB_ROTATE_TEXTEPCB, msg, KiBitmap( rotate_ccw_xpm ) );
+ msg = AddHotkeyName( _( "Flip" ), g_Board_Editor_Hokeys_Descr, HK_FLIP_ITEM );
+ AddMenuItem( sub_menu_Text, ID_POPUP_PCB_FLIP_TEXTEPCB, msg, KiBitmap( mirror_h_xpm ) );
+ msg = AddHotkeyName( _( "Edit" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM );
+ AddMenuItem( sub_menu_Text, ID_POPUP_PCB_EDIT_TEXTEPCB, msg, KiBitmap( edit_text_xpm ) );
+ if( !flags )
+ {
+ AddMenuItem( sub_menu_Text, ID_POPUP_PCB_RESET_TEXT_SIZE,
+ _( "Reset Size" ), KiBitmap( reset_text_xpm ) );
+
+ sub_menu_Text->AppendSeparator();
+ msg = AddHotkeyName( _( "Delete" ), g_Board_Editor_Hokeys_Descr, HK_DELETE );
+ AddMenuItem( sub_menu_Text, ID_POPUP_PCB_DELETE_TEXTEPCB, msg, KiBitmap( delete_text_xpm ) );
+ }
+}
+
+
+void PCB_EDIT_FRAME::createPopUpMenuForMarkers( MARKER_PCB* aMarker, wxMenu* aPopMenu )
+{
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_MARKER, _( "Delete Marker" ),
+ KiBitmap( delete_xpm ) );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_GETINFO_MARKER, _( "Marker Error Info" ),
+ KiBitmap( info_xpm ) );
+}
+
+
+/**
+ * Function Append_Track_Width_List
+ * creates a wxMenu * which shows the last used track widths and via diameters
+ * @return a pointer to the menu
+ */
+static wxMenu* Append_Track_Width_List( BOARD* aBoard )
+{
+ wxString msg;
+ wxMenu* trackwidth_menu;
+ wxString value;
+
+ trackwidth_menu = new wxMenu;
+
+ trackwidth_menu->Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH, _( "Auto Width" ),
+ _( "Use the track width when starting on a track, otherwise the current track width" ),
+ true );
+
+ if( aBoard->GetDesignSettings().m_UseConnectedTrackWidth )
+ trackwidth_menu->Check( ID_POPUP_PCB_SELECT_AUTO_WIDTH, true );
+
+ if( aBoard->GetDesignSettings().GetViaSizeIndex() != 0
+ || aBoard->GetDesignSettings().GetTrackWidthIndex() != 0
+ || aBoard->GetDesignSettings().m_UseConnectedTrackWidth )
+ trackwidth_menu->Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES,
+ _( "Use Netclass Values" ),
+ _( "Use track and via sizes from their Netclass values" ),
+ true );
+
+ for( unsigned ii = 0; ii < aBoard->GetDesignSettings().m_TrackWidthList.size(); ii++ )
+ {
+ value = StringFromValue( g_UserUnit, aBoard->GetDesignSettings().m_TrackWidthList[ii], true );
+ msg.Printf( _( "Track %s" ), GetChars( value ) );
+
+ if( ii == 0 )
+ msg << _( " uses NetClass" );
+
+ trackwidth_menu->Append( ID_POPUP_PCB_SELECT_WIDTH1 + ii, msg, wxEmptyString, true );
+ }
+
+ trackwidth_menu->AppendSeparator();
+
+ for( unsigned ii = 0; ii < aBoard->GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
+ {
+ value = StringFromValue( g_UserUnit,
+ aBoard->GetDesignSettings().m_ViasDimensionsList[ii].m_Diameter,
+ true );
+ wxString drill = StringFromValue( g_UserUnit,
+ aBoard->GetDesignSettings().m_ViasDimensionsList[ii].m_Drill,
+ true );
+
+ if( aBoard->GetDesignSettings().m_ViasDimensionsList[ii].m_Drill <= 0 )
+ {
+ msg.Printf( _( "Via %s" ), GetChars( value ) );
+ }
+ else
+ {
+ msg.Printf( _( "Via %s, drill %s" ), GetChars( value ), GetChars( drill ) );
+ }
+
+ if( ii == 0 )
+ msg << _( " uses NetClass" );
+
+ trackwidth_menu->Append( ID_POPUP_PCB_SELECT_VIASIZE1 + ii, msg, wxEmptyString, true );
+ }
+
+ return trackwidth_menu;
+}
diff --git a/pcbnew/pad_edition_functions.cpp b/pcbnew/pad_edition_functions.cpp
new file mode 100644
index 0000000..eaa2400
--- /dev/null
+++ b/pcbnew/pad_edition_functions.cpp
@@ -0,0 +1,276 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pad_edition_functions.cpp
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <trigo.h>
+#include <macros.h>
+#include <wxBasePcbFrame.h>
+
+#include <pcbnew.h>
+#include <class_board.h>
+#include <class_module.h>
+#include <class_pad.h>
+#include <class_board_design_settings.h>
+
+/* Exports the current pad settings to board design settings.
+ */
+void PCB_BASE_FRAME::Export_Pad_Settings( D_PAD* aPad )
+{
+ if( aPad == NULL )
+ return;
+
+ SetMsgPanel( aPad );
+
+ D_PAD& mp = GetDesignSettings().m_Pad_Master;
+
+ mp.SetShape( aPad->GetShape() );
+ mp.SetAttribute( aPad->GetAttribute() );
+ mp.SetLayerSet( aPad->GetLayerSet() );
+
+ mp.SetOrientation( aPad->GetOrientation() - aPad->GetParent()->GetOrientation() );
+
+ mp.SetSize( aPad->GetSize() );
+ mp.SetDelta( aPad->GetDelta() );
+
+ mp.SetOffset( aPad->GetOffset() );
+ mp.SetDrillSize( aPad->GetDrillSize() );
+ mp.SetDrillShape( aPad->GetDrillShape() );
+}
+
+
+/* Imports the board design settings to aPad
+ * - The position, names, and keys are not modifed.
+ */
+void PCB_BASE_FRAME::Import_Pad_Settings( D_PAD* aPad, bool aDraw )
+{
+ if( aDraw )
+ {
+ aPad->SetFlags( DO_NOT_DRAW );
+ m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() );
+ aPad->ClearFlags( DO_NOT_DRAW );
+ }
+
+ D_PAD& mp = GetDesignSettings().m_Pad_Master;
+
+ aPad->SetShape( mp.GetShape() );
+ aPad->SetLayerSet( mp.GetLayerSet() );
+ aPad->SetAttribute( mp.GetAttribute() );
+ aPad->SetOrientation( mp.GetOrientation() + aPad->GetParent()->GetOrientation() );
+ aPad->SetSize( mp.GetSize() );
+ aPad->SetDelta( wxSize( 0, 0 ) );
+ aPad->SetOffset( mp.GetOffset() );
+ aPad->SetDrillSize( mp.GetDrillSize() );
+ aPad->SetDrillShape( mp.GetDrillShape() );
+
+ switch( mp.GetShape() )
+ {
+ case PAD_SHAPE_TRAPEZOID:
+ aPad->SetDelta( mp.GetDelta() );
+ break;
+
+ case PAD_SHAPE_CIRCLE:
+ // ensure size.y == size.x
+ aPad->SetSize( wxSize( aPad->GetSize().x, aPad->GetSize().x ) );
+ break;
+
+ default:
+ ;
+ }
+
+ switch( mp.GetAttribute() )
+ {
+ case PAD_ATTRIB_SMD:
+ case PAD_ATTRIB_CONN:
+ aPad->SetDrillSize( wxSize( 0, 0 ) );
+ aPad->SetOffset( wxPoint( 0, 0 ) );
+ break;
+ default:
+ ;
+ }
+
+ if( aDraw )
+ m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() );
+
+ aPad->GetParent()->SetLastEditTime();
+
+ OnModify();
+}
+
+/** Compute the 'next' pad number for autoincrement
+ * aPadName is the last pad name used */
+static wxString GetNextPadName( wxString aPadName )
+{
+ // Automatically increment the current pad number.
+ int num = 0;
+ int ponder = 1;
+
+ // Trim and extract the trailing numeric part
+ while( aPadName.Len()
+ && aPadName.Last() >= '0'
+ && aPadName.Last() <= '9' )
+ {
+ num += ( aPadName.Last() - '0' ) * ponder;
+ aPadName.RemoveLast();
+ ponder *= 10;
+ }
+
+ num++; // Use next number for the new pad
+ aPadName << num;
+
+ return aPadName;
+}
+
+/* Add a new pad to aModule.
+ */
+void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw )
+{
+ m_Pcb->m_Status_Pcb = 0;
+ aModule->SetLastEditTime();
+
+ D_PAD* pad = new D_PAD( aModule );
+
+ // Add the new pad to end of the module pad list.
+ aModule->Pads().PushBack( pad );
+
+ // Update the pad properties,
+ // and keep NETINFO_LIST::ORPHANED as net info
+ // which is the default when nets cannot be handled.
+ Import_Pad_Settings( pad, false );
+
+ pad->SetPosition( GetCrossHairPosition() );
+
+ // Set the relative pad position
+ // ( pad position for module orient, 0, and relative to the module position)
+
+ wxPoint pos0 = pad->GetPosition() - aModule->GetPosition();
+ RotatePoint( &pos0, -aModule->GetOrientation() );
+ pad->SetPos0( pos0 );
+
+ /* NPTH pads take empty pad number (since they can't be connected),
+ * other pads get incremented from the last one edited */
+ wxString padName;
+
+ if( pad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
+ {
+ padName = GetNextPadName( GetDesignSettings()
+ .m_Pad_Master.GetPadName() );
+ }
+
+ pad->SetPadName( padName );
+ GetDesignSettings().m_Pad_Master.SetPadName( padName );
+
+ aModule->CalculateBoundingBox();
+ SetMsgPanel( pad );
+
+ if( draw )
+ m_canvas->RefreshDrawingRect( aModule->GetBoundingBox() );
+}
+
+
+void PCB_BASE_FRAME::DeletePad( D_PAD* aPad, bool aQuery )
+{
+ if( aPad == NULL )
+ return;
+
+ MODULE* module = aPad->GetParent();
+ module->SetLastEditTime();
+
+ // aQuery = true to prompt for confirmation, false to delete silently
+ if( aQuery )
+ {
+ wxString msg;
+ msg.Printf( _( "Delete Pad (footprint %s %s) ?" ),
+ GetChars( module->GetReference() ),
+ GetChars( module->GetValue() ) );
+
+ if( !IsOK( this, msg ) )
+ return;
+ }
+
+ // Stores the initial bounding box to refresh the old area
+ EDA_RECT bbox = module->GetBoundingBox();
+
+ m_Pcb->m_Status_Pcb = 0;
+
+ GetBoard()->PadDelete( aPad );
+
+ // Update the bounding box
+ module->CalculateBoundingBox();
+
+ // Refresh the modified screen area, using the initial bounding box
+ // which is perhaps larger than the new bounding box
+ m_canvas->RefreshDrawingRect( bbox );
+
+ OnModify();
+}
+
+
+// Rotate selected pad 90 degrees.
+void PCB_BASE_FRAME::RotatePad( D_PAD* aPad, wxDC* DC )
+{
+ if( aPad == NULL )
+ return;
+
+ MODULE* module = aPad->GetParent();
+
+ module->SetLastEditTime();
+
+ OnModify();
+
+ if( DC )
+ module->Draw( m_canvas, DC, GR_XOR );
+
+ wxSize sz = aPad->GetSize();
+ std::swap( sz.x, sz.y );
+ aPad->SetSize( sz );
+
+ sz = aPad->GetDrillSize();
+ std::swap( sz.x, sz.y );
+ aPad->SetDrillSize( sz );
+
+ wxPoint pt = aPad->GetOffset();
+ std::swap( pt.x, pt.y );
+ aPad->SetOffset( pt );
+
+ aPad->SetOffset( wxPoint( aPad->GetOffset().x, -aPad->GetOffset().y ) );
+
+ sz = aPad->GetDelta();
+ std::swap( sz.x, sz.y );
+ sz.x = -sz.x;
+ aPad->SetDelta( sz );
+
+ module->CalculateBoundingBox();
+ SetMsgPanel( aPad );
+
+ if( DC )
+ module->Draw( m_canvas, DC, GR_OR );
+}
diff --git a/pcbnew/pcad2kicadpcb_plugin/CMakeLists.txt b/pcbnew/pcad2kicadpcb_plugin/CMakeLists.txt
new file mode 100644
index 0000000..11e60de
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/CMakeLists.txt
@@ -0,0 +1,32 @@
+
+# Sources for the pcbnew PLUGIN called PCAD_PLUGIN
+
+# This CMakeLists.txt is included from pcbnew, so we are inheriting its include_directories(),
+# simply add the current source dir to inherited include_directories() for sources in here only.
+include_directories( . )
+
+
+set( PCAD2PCBNEW_SRCS
+ pcad2kicad_common.cpp
+ pcad_plugin.cpp
+ pcb.cpp
+ pcb_arc.cpp
+ pcb_component.cpp
+ pcb_copper_pour.cpp
+ pcb_cutout.cpp
+ pcb_keepout.cpp
+ pcb_line.cpp
+ pcb_module.cpp
+ pcb_net.cpp
+ pcb_pad.cpp
+ pcb_pad_shape.cpp
+ pcb_plane.cpp
+ pcb_polygon.cpp
+ pcb_text.cpp
+ pcb_via.cpp
+ pcb_via_shape.cpp
+ s_expr_loader.cpp
+ )
+
+add_library( pcad2kicadpcb STATIC ${PCAD2PCBNEW_SRCS} )
+add_dependencies( pcad2kicadpcb pcbcommon )
diff --git a/pcbnew/pcad2kicadpcb_plugin/examples/files.txt b/pcbnew/pcad2kicadpcb_plugin/examples/files.txt
new file mode 100644
index 0000000..ca06173
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/examples/files.txt
@@ -0,0 +1,7 @@
+
+Examples description
+====================
+A PCAD ASCII sample file can be downloaded from http://www.pcadbegin.webtm.ru
+(Provided by its author Andrey Manin <pcadbegin[at]rambler.ru>)
+
+http://www.pcadbegin.webtm.ru/schetchik.php?scach=1 (CK1202_V1.pcb)
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.cpp b/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.cpp
new file mode 100644
index 0000000..7ff4a60
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.cpp
@@ -0,0 +1,553 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcad2kicad_common.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+#include <convert_to_biu.h>
+
+#include <pcad2kicad_common.h>
+
+namespace PCAD2KICAD {
+
+// PCAD stroke font average ratio of width to height
+const double TEXT_WIDTH_TO_HEIGHT = 0.79;
+
+wxString GetWord( wxString* aStr )
+{
+ wxString result = wxEmptyString;
+
+ *aStr = aStr->Trim( false );
+
+ if( aStr->Len() == 0 )
+ return result;
+
+ if( (*aStr)[0] == wxT( '"' ) )
+ {
+ result += (*aStr)[0];
+ *aStr = aStr->Mid( 1 ); // remove Frot apostrofe
+
+ while( aStr->Len() > 0 && (*aStr)[0] != wxT( '"' ) )
+ {
+ result += (*aStr)[0];
+ *aStr = aStr->Mid( 1 );
+ }
+
+ if( aStr->Len() > 0 && (*aStr)[0] == wxT( '"' ) )
+ {
+ result += (*aStr)[0];
+ *aStr = aStr->Mid( 1 ); // remove ending apostrophe
+ }
+ }
+ else
+ {
+ while( aStr->Len() > 0
+ && !( (*aStr)[0] == wxT( ' ' )
+ || (*aStr)[0] == wxT( '(' )
+ || (*aStr)[0] == wxT( ')' ) ) )
+ {
+ result += (*aStr)[0];
+ *aStr = aStr->Mid( 1 );
+ }
+ }
+
+ result.Trim( true );
+ result.Trim( false );
+
+ return result;
+}
+
+
+XNODE* FindPinMap( XNODE* aNode )
+{
+ XNODE* result, * lNode;
+
+ result = NULL;
+ lNode = FindNode( aNode, wxT( "attachedPattern" ) );
+
+ if( lNode )
+ result = FindNode( lNode, wxT( "padPinMap" ) );
+
+ return result;
+}
+
+
+double StrToDoublePrecisionUnits( wxString aStr, char aAxe, wxString aActualConversion )
+{
+ wxString ls;
+ double i;
+ char u;
+
+ ls = aStr;
+ ls.Trim( true );
+ ls.Trim( false );
+
+ if( ls.Len() > 0 )
+ {
+ u = ls[ls.Len() - 1];
+
+ while( ls.Len() > 0
+ && !( ls[ls.Len() - 1] == wxT( '.' )
+ || ls[ls.Len() - 1] == wxT( ',' )
+ || (ls[ls.Len() - 1] >= wxT( '0' ) && ls[ls.Len() - 1] <= wxT( '9' ) ) ) )
+ {
+ ls = ls.Left( ls.Len() - 1 );
+ }
+
+ while( ls.Len() > 0
+ && !( ls[0] == wxT( '-' )
+ || ls[0] == wxT( '+' )
+ || ls[0] == wxT( '.' )
+ || ls[0] == wxT( ',' )
+ || (ls[0] >= wxT( '0' ) && ls[0] <= wxT( '9' ) ) ) )
+ {
+ ls = ls.Mid( 1 );
+ }
+
+ if( u == wxT( 'm' ) )
+ {
+ ls.ToDouble( &i );
+#ifdef PCAD2KICAD_SCALE_SCH_TO_INCH_GRID
+ if( aActualConversion == wxT( "SCH" )
+ || aActualConversion == wxT( "SCHLIB" ) )
+ i = i * (0.0254 / 0.025);
+#endif
+ i = Millimeter2iu( i );
+ }
+ else
+ {
+ ls.ToDouble( &i );
+ i = Mils2iu( i );
+ }
+ }
+ else
+ i = 0.0;
+
+ if( ( aActualConversion == wxT( "PCB" ) || aActualConversion == wxT( "SCH" ) )
+ && aAxe == wxT( 'Y' ) )
+ return -i;
+ else
+ return i; // Y axe is mirrored compared to P-Cad
+}
+
+
+int StrToIntUnits( wxString aStr, char aAxe, wxString aActualConversion )
+{
+ return KiROUND( StrToDoublePrecisionUnits( aStr, aAxe, aActualConversion ) );
+}
+
+
+wxString GetAndCutWordWithMeasureUnits( wxString* aStr, wxString aDefaultMeasurementUnit )
+{
+ wxString result;
+
+ aStr->Trim( false );
+ result = wxEmptyString;
+
+ // value
+ while( aStr->Len() > 0 && (*aStr)[0] != wxT( ' ' ) )
+ {
+ result += (*aStr)[0];
+ *aStr = aStr->Mid( 1 );
+ }
+
+ aStr->Trim( false );
+
+ // if there is also measurement unit
+ while( aStr->Len() > 0
+ && ( ( (*aStr)[0] >= wxT( 'a' ) && (*aStr)[0] <= wxT( 'z' ) )
+ || ( (*aStr)[0] >= wxT( 'A' ) && (*aStr)[0] <= wxT( 'Z' ) ) ) )
+ {
+ result += (*aStr)[0];
+ *aStr = aStr->Mid( 1 );
+ }
+
+ // and if not, add default....
+ if( result.Len() > 0
+ && ( result[result.Len() - 1] == wxT( '.' )
+ || result[result.Len() - 1] == wxT( ',' )
+ || (result[result.Len() - 1] >= wxT( '0' )
+ && result[result.Len() - 1] <= wxT( '9' ) ) ) )
+ {
+ result += aDefaultMeasurementUnit;
+ }
+
+ return result;
+}
+
+
+int StrToInt1Units( wxString aStr )
+{
+ double num, precision = 10;
+
+ // TODO: Is the following commented string necessary?
+ // if (pos(',',s)>0) then DecimalSeparator:=',' else DecimalSeparator:='.';
+ aStr.ToDouble( &num );
+ return KiROUND( num * precision );
+}
+
+
+wxString ValidateName( wxString aName )
+{
+ aName.Replace( wxT( " " ), wxT( "_" ) );
+
+ return aName;
+}
+
+
+void SetWidth( wxString aStr,
+ wxString aDefaultMeasurementUnit,
+ int* aWidth,
+ wxString aActualConversion )
+{
+ *aWidth = StrToIntUnits( GetAndCutWordWithMeasureUnits( &aStr,
+ aDefaultMeasurementUnit ), wxT( ' ' ),
+ aActualConversion );
+}
+
+
+void SetHeight( wxString aStr,
+ wxString aDefaultMeasurementUnit,
+ int* aHeight,
+ wxString aActualConversion )
+{
+ *aHeight = StrToIntUnits( GetAndCutWordWithMeasureUnits( &aStr,
+ aDefaultMeasurementUnit ), wxT( ' ' ),
+ aActualConversion );
+}
+
+
+void SetPosition( wxString aStr,
+ wxString aDefaultMeasurementUnit,
+ int* aX,
+ int* aY,
+ wxString aActualConversion )
+{
+ *aX = StrToIntUnits( GetAndCutWordWithMeasureUnits( &aStr,
+ aDefaultMeasurementUnit ), wxT( 'X' ),
+ aActualConversion );
+ *aY = StrToIntUnits( GetAndCutWordWithMeasureUnits( &aStr,
+ aDefaultMeasurementUnit ), wxT( 'Y' ),
+ aActualConversion );
+}
+
+
+void SetDoublePrecisionPosition( wxString aStr,
+ wxString aDefaultMeasurementUnit,
+ double* aX,
+ double* aY,
+ wxString aActualConversion )
+{
+ *aX = StrToDoublePrecisionUnits( GetAndCutWordWithMeasureUnits( &aStr,
+ aDefaultMeasurementUnit ), wxT( 'X' ),
+ aActualConversion );
+ *aY = StrToDoublePrecisionUnits( GetAndCutWordWithMeasureUnits( &aStr,
+ aDefaultMeasurementUnit ), wxT( 'Y' ),
+ aActualConversion );
+}
+
+TTEXT_JUSTIFY GetJustifyIdentificator( wxString aJustify )
+{
+ TTEXT_JUSTIFY id;
+
+ if( aJustify == wxT( "LowerCenter" ) )
+ id = LowerCenter;
+ else if( aJustify == wxT( "LowerRight" ) )
+ id = LowerRight;
+ else if( aJustify == wxT( "UpperLeft" ) )
+ id = UpperLeft;
+ else if( aJustify == wxT( "UpperCenter" ) )
+ id = UpperCenter;
+ else if( aJustify == wxT( "UpperRight" ) )
+ id = UpperRight;
+ else if( aJustify == wxT( "Left" ) )
+ id = Left;
+ else if( aJustify == wxT( "Center" ) )
+ id = Center;
+ else if( aJustify == wxT( "Right" ) )
+ id = Right;
+ else
+ id = LowerLeft;
+
+ return id;
+}
+
+void SetTextParameters( XNODE* aNode,
+ TTEXTVALUE* aTextValue,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ XNODE* tNode;
+ wxString str;
+
+ tNode = FindNode( aNode, wxT( "pt" ) );
+
+ if( tNode )
+ SetPosition( tNode->GetNodeContent(),
+ aDefaultMeasurementUnit,
+ &aTextValue->textPositionX,
+ &aTextValue->textPositionY,
+ aActualConversion );
+
+ tNode = FindNode( aNode, wxT( "rotation" ) );
+
+ if( tNode )
+ {
+ str = tNode->GetNodeContent();
+ str.Trim( false );
+ aTextValue->textRotation = StrToInt1Units( str );
+ }
+
+ str = FindNodeGetContent( aNode, wxT( "isVisible" ) );
+
+ if( str == wxT( "True" ) )
+ aTextValue->textIsVisible = 1;
+ else if( str == wxT( "False" ) )
+ aTextValue->textIsVisible = 0;
+
+ str = FindNodeGetContent( aNode, wxT( "justify" ) );
+ aTextValue->justify = GetJustifyIdentificator( str );
+
+ str = FindNodeGetContent( aNode, wxT( "isFlipped" ) );
+
+ if( str == wxT( "True" ) )
+ aTextValue->mirror = 1;
+
+ tNode = FindNode( aNode, wxT( "textStyleRef" ) );
+
+ if( tNode )
+ SetFontProperty( tNode, aTextValue, aDefaultMeasurementUnit, aActualConversion );
+}
+
+
+void SetFontProperty( XNODE* aNode,
+ TTEXTVALUE* aTextValue,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ wxString n, propValue;
+
+ aNode->GetAttribute( wxT( "Name" ), &n );
+
+ while( aNode->GetName() != wxT( "www.lura.sk" ) )
+ aNode = aNode->GetParent();
+
+ aNode = FindNode( aNode, wxT( "library" ) );
+
+ if( aNode )
+ aNode = FindNode( aNode, wxT( "textStyleDef" ) );
+
+ if( aNode )
+ {
+ while( true )
+ {
+ aNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+
+ if( propValue == n )
+ break;
+
+ aNode = aNode->GetNext();
+ }
+
+ if( aNode )
+ {
+ aNode = FindNode( aNode, wxT( "font" ) );
+
+ if( aNode )
+ {
+ if( FindNode( aNode, wxT( "fontHeight" ) ) )
+ // // SetWidth(iNode.ChildNodes.FindNode('fontHeight').Text,
+ // // DefaultMeasurementUnit,tv.TextHeight);
+ // Fixed By Lubo, 02/2008
+ SetHeight( FindNode( aNode, wxT(
+ "fontHeight" ) )->GetNodeContent(),
+ aDefaultMeasurementUnit, &aTextValue->textHeight,
+ aActualConversion );
+
+ if( FindNode( aNode, wxT( "strokeWidth" ) ) )
+ SetWidth( FindNode( aNode, wxT(
+ "strokeWidth" ) )->GetNodeContent(),
+ aDefaultMeasurementUnit, &aTextValue->textstrokeWidth,
+ aActualConversion );
+ }
+ }
+ }
+}
+
+int CalculateTextLengthSize( TTEXTVALUE* aText )
+{
+ return KiROUND( (double) aText->text.Len() *
+ (double) aText->textHeight * TEXT_WIDTH_TO_HEIGHT );
+}
+
+void CorrectTextPosition( TTEXTVALUE* aValue )
+{
+ int cm = aValue->mirror ? -1 : 1;
+ // sizes of justify correction
+ int cl = KiROUND( (double) CalculateTextLengthSize( aValue ) / 2.0 );
+ int ch = KiROUND( (double) aValue->textHeight / 2.0 );
+
+ aValue->correctedPositionX = aValue->textPositionX;
+ aValue->correctedPositionY = aValue->textPositionY;
+
+ switch( aValue->textRotation )
+ {
+ case 0:
+ if( aValue->justify == LowerLeft ||
+ aValue->justify == Left ||
+ aValue->justify == UpperLeft )
+ aValue->correctedPositionX += cl * cm;
+ else if( aValue->justify == LowerRight ||
+ aValue->justify == Right ||
+ aValue->justify == UpperRight )
+ aValue->correctedPositionX -= cl * cm;
+
+ if( aValue->justify == LowerLeft ||
+ aValue->justify == LowerCenter ||
+ aValue->justify == LowerRight )
+ aValue->correctedPositionY -= ch;
+ else if( aValue->justify == UpperLeft ||
+ aValue->justify == UpperCenter ||
+ aValue->justify == UpperRight )
+ aValue->correctedPositionY += ch;
+ break;
+ case 900:
+ if( aValue->justify == LowerLeft ||
+ aValue->justify == LowerCenter ||
+ aValue->justify == LowerRight )
+ aValue->correctedPositionX -= ch * cm;
+ else if( aValue->justify == UpperLeft ||
+ aValue->justify == UpperCenter ||
+ aValue->justify == UpperRight )
+ aValue->correctedPositionX += ch * cm;
+
+ if( aValue->justify == LowerLeft ||
+ aValue->justify == Left ||
+ aValue->justify == UpperLeft )
+ aValue->correctedPositionY -= cl;
+ else if( aValue->justify == LowerRight ||
+ aValue->justify == Right ||
+ aValue->justify == UpperRight )
+ aValue->correctedPositionY += cl;
+ break;
+ case 1800:
+ if( aValue->justify == LowerLeft ||
+ aValue->justify == Left ||
+ aValue->justify == UpperLeft )
+ aValue->correctedPositionX -= cl * cm;
+ else if( aValue->justify == LowerRight ||
+ aValue->justify == Right ||
+ aValue->justify == UpperRight )
+ aValue->correctedPositionX += cl * cm;
+
+ if( aValue->justify == LowerLeft ||
+ aValue->justify == LowerCenter ||
+ aValue->justify == LowerRight )
+ aValue->correctedPositionY += ch;
+ else if( aValue->justify == UpperLeft ||
+ aValue->justify == UpperCenter ||
+ aValue->justify == UpperRight )
+ aValue->correctedPositionY -= ch;
+ break;
+ case 2700:
+ if( aValue->justify == LowerLeft ||
+ aValue->justify == LowerCenter ||
+ aValue->justify == LowerRight )
+ aValue->correctedPositionX += ch * cm;
+ else if( aValue->justify == UpperLeft ||
+ aValue->justify == UpperCenter ||
+ aValue->justify == UpperRight )
+ aValue->correctedPositionX -= ch * cm;
+
+ if( aValue->justify == LowerLeft ||
+ aValue->justify == Left ||
+ aValue->justify == UpperLeft )
+ aValue->correctedPositionY += cl;
+ else if( aValue->justify == LowerRight ||
+ aValue->justify == Right ||
+ aValue->justify == UpperRight )
+ aValue->correctedPositionY -= cl;
+ break;
+ default:
+ break;
+ }
+}
+
+
+XNODE* FindNode( XNODE* aChild, wxString aTag )
+{
+ aChild = aChild->GetChildren();
+
+ while( aChild )
+ {
+ if( aChild->GetName() == aTag )
+ return aChild;
+
+ aChild = aChild->GetNext();
+ }
+
+ return NULL;
+}
+
+wxString FindNodeGetContent( XNODE* aChild, wxString aTag )
+{
+ wxString str = wxEmptyString;
+
+ aChild = FindNode( aChild, aTag );
+
+ if( aChild )
+ {
+ str = aChild->GetNodeContent();
+ str.Trim( false );
+ str.Trim( true );
+ }
+
+ return str;
+}
+
+void InitTTextValue( TTEXTVALUE* aTextValue )
+{
+ aTextValue->text = wxEmptyString;
+ aTextValue->textPositionX = 0;
+ aTextValue->textPositionY = 0;
+ aTextValue->textRotation = 0;
+ aTextValue->textHeight = 0;
+ aTextValue->textstrokeWidth = 0;
+ aTextValue->textIsVisible = 0;
+ aTextValue->mirror = 0;
+ aTextValue->textUnit = 0;
+ aTextValue->correctedPositionX = 0;
+ aTextValue->correctedPositionY = 0;
+ aTextValue->justify = LowerLeft;
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.h b/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.h
new file mode 100644
index 0000000..ce61cc2
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.h
@@ -0,0 +1,104 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcad2kicad_common.h
+ */
+
+#ifndef PCAD2KICAD_COMMON_H_
+#define PCAD2KICAD_COMMON_H_
+
+#include <wx/wx.h>
+#include <wx/xml/xml.h>
+#include <xnode.h>
+
+namespace PCAD2KICAD
+{
+
+#define PCAD2KICAD_SCALE_SCH_TO_INCH_GRID
+
+enum TTEXT_JUSTIFY
+{
+ LowerLeft,
+ LowerCenter,
+ LowerRight,
+ UpperLeft,
+ UpperCenter,
+ UpperRight,
+ Left,
+ Center,
+ Right
+};
+
+typedef struct _TTEXTVALUE
+{
+ wxString text;
+ int textPositionX, textPositionY,
+ textRotation, textHeight, textstrokeWidth;
+ int textIsVisible, mirror, textUnit;
+ int correctedPositionX, correctedPositionY;
+ TTEXT_JUSTIFY justify;
+} TTEXTVALUE;
+
+extern wxString GetWord( wxString* aStr );
+extern XNODE* FindPinMap( XNODE* aNode );
+extern int StrToIntUnits( wxString aStr, char aAxe, wxString aActualConversion );
+extern wxString GetAndCutWordWithMeasureUnits( wxString* aStr,
+ wxString aDefaultMeasurementUnit );
+extern int StrToInt1Units( wxString aStr );
+extern wxString ValidateName( wxString aName );
+extern void SetWidth( wxString aStr,
+ wxString aDefaultMeasurementUnit,
+ int* aWidth,
+ wxString aActualConversion );
+extern void SetPosition( wxString aStr,
+ wxString aDefaultMeasurementUnit,
+ int* aX,
+ int* aY,
+ wxString aActualConversion );
+extern void SetDoublePrecisionPosition( wxString aStr,
+ wxString aDefaultMeasurementUnit,
+ double* aX,
+ double* aY,
+ wxString aActualConversion );
+extern TTEXT_JUSTIFY GetJustifyIdentificator( wxString aJustify );
+extern void SetTextParameters( XNODE* aNode,
+ TTEXTVALUE* aTextValue,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion );
+extern void SetFontProperty( XNODE* aNode,
+ TTEXTVALUE* aTextValue,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion );
+extern int CalculateTextLengthSize( TTEXTVALUE* aText );
+extern void CorrectTextPosition( TTEXTVALUE* aValue );
+
+extern XNODE* FindNode( XNODE* aChild, wxString aTag );
+extern wxString FindNodeGetContent( XNODE* aChild, wxString aTag );
+extern void InitTTextValue( TTEXTVALUE* aTextValue );
+
+} // namespace PCAD2KICAD
+
+#endif // PCAD2KICAD_COMMON_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcad_plugin.cpp b/pcbnew/pcad2kicadpcb_plugin/pcad_plugin.cpp
new file mode 100644
index 0000000..0c7c75c
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcad_plugin.cpp
@@ -0,0 +1,91 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcad_plugin.cpp
+ * @brief Pcbnew PLUGIN for P-Cad 200x ASCII *.pcb format.
+ */
+
+#include <errno.h>
+
+#include <wx/string.h>
+#include <wx/filename.h>
+#include <wx/xml/xml.h>
+
+#include <pcad_plugin.h>
+#include <s_expr_loader.h>
+#include <pcb.h>
+
+#include <common.h>
+#include <macros.h>
+#include <fctsys.h>
+
+using namespace PCAD2KICAD;
+
+PCAD_PLUGIN::PCAD_PLUGIN()
+{
+ m_board = NULL;
+ m_props = NULL;
+}
+
+
+PCAD_PLUGIN::~PCAD_PLUGIN()
+{
+}
+
+
+const wxString PCAD_PLUGIN::PluginName() const
+{
+ return wxT( "P-Cad" );
+}
+
+
+const wxString PCAD_PLUGIN::GetFileExtension() const
+{
+ return wxT( "pcb" );
+}
+
+
+BOARD* PCAD_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties )
+{
+ wxXmlDocument xmlDoc;
+
+ m_props = aProperties;
+
+ m_board = aAppendToMe ? aAppendToMe : new BOARD();
+
+ // Give the filename to the board if it's new
+ if( !aAppendToMe )
+ m_board->SetFileName( aFileName );
+
+ PCB pcb( m_board );
+
+ LOCALE_IO toggle; // toggles on, then off, the C locale.
+
+ LoadInputFile( aFileName, &xmlDoc );
+ pcb.Parse( NULL, &xmlDoc, wxT( "PCB" ) );
+ pcb.AddToBoard();
+
+ return m_board;
+}
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcad_plugin.h b/pcbnew/pcad2kicadpcb_plugin/pcad_plugin.h
new file mode 100644
index 0000000..45ecbd9
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcad_plugin.h
@@ -0,0 +1,60 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcad_plugin.h
+ * @brief Pcbnew PLUGIN for P-Cad 200x ASCII *.pcb format.
+ */
+
+#ifndef PCAD_PLUGIN_H_
+#define PCAD_PLUGIN_H_
+
+
+#include <io_mgr.h>
+
+class PCAD_PLUGIN : public PLUGIN
+{
+public:
+
+ // -----<PUBLIC PLUGIN API>--------------------------------------------------
+
+ const wxString PluginName() const;
+
+ BOARD* Load( const wxString& aFileName,
+ BOARD* aAppendToMe,
+ const PROPERTIES* aProperties = NULL );
+
+ const wxString GetFileExtension() const;
+
+ // -----</PUBLIC PLUGIN API>-------------------------------------------------
+
+ PCAD_PLUGIN();
+ ~PCAD_PLUGIN();
+
+private:
+ const PROPERTIES* m_props;
+ BOARD* m_board;
+};
+
+#endif // PCAD_PLUGIN_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb.cpp
new file mode 100644
index 0000000..feedb83
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb.cpp
@@ -0,0 +1,937 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+
+#include <pcb.h>
+#include <pcb_arc.h>
+#include <pcb_copper_pour.h>
+#include <pcb_cutout.h>
+#include <pcb_keepout.h>
+#include <pcb_line.h>
+#include <pcb_module.h>
+#include <pcb_pad_shape.h>
+#include <pcb_via_shape.h>
+#include <pcb_pad.h>
+#include <pcb_text.h>
+#include <pcb_via.h>
+#include <s_expr_loader.h>
+
+namespace PCAD2KICAD {
+
+LAYER_ID PCB::GetKiCadLayer( int aPCadLayer )
+{
+ wxASSERT( aPCadLayer >= 0 && aPCadLayer < MAX_PCAD_LAYER_QTY );
+ return m_layersMap[aPCadLayer].KiCadLayer;
+}
+
+LAYER_TYPE_T PCB::GetLayerType( int aPCadLayer )
+{
+ wxASSERT( aPCadLayer >= 0 && aPCadLayer < MAX_PCAD_LAYER_QTY );
+ return m_layersMap[aPCadLayer].layerType;
+}
+
+wxString PCB::GetLayerNetNameRef( int aPCadLayer )
+{
+ wxASSERT( aPCadLayer >= 0 && aPCadLayer < MAX_PCAD_LAYER_QTY );
+ return m_layersMap[aPCadLayer].netNameRef;
+}
+
+PCB::PCB( BOARD* aBoard ) : PCB_MODULE( this, aBoard )
+{
+ int i;
+
+ m_defaultMeasurementUnit = wxT( "mil" );
+
+ for( i = 0; i < MAX_PCAD_LAYER_QTY; i++ )
+ {
+ m_layersMap[i].KiCadLayer = F_Mask; // default
+ m_layersMap[i].layerType = LAYER_TYPE_NONSIGNAL; // default
+ m_layersMap[i].netNameRef = wxT( "" ); // default
+ }
+
+ m_sizeX = 0;
+ m_sizeY = 0;
+
+ m_layersMap[1].KiCadLayer = F_Cu;
+ m_layersMap[1].layerType = LAYER_TYPE_SIGNAL;
+
+ m_layersMap[2].KiCadLayer = B_Cu;
+ m_layersMap[2].layerType = LAYER_TYPE_SIGNAL;
+
+ m_layersMap[3].KiCadLayer = Eco2_User;
+ m_layersMap[6].KiCadLayer = F_SilkS;
+ m_layersMap[7].KiCadLayer = B_SilkS;
+ m_timestamp_cnt = 0x10000000;
+}
+
+
+PCB::~PCB()
+{
+ int i;
+
+ for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ )
+ {
+ delete m_pcbComponents[i];
+ }
+
+ for( i = 0; i < (int) m_pcbNetlist.GetCount(); i++ )
+ {
+ delete m_pcbNetlist[i];
+ }
+}
+
+
+int PCB::GetNewTimestamp()
+{
+ return m_timestamp_cnt++;
+}
+
+int PCB::GetNetCode( wxString aNetName )
+{
+ PCB_NET* net;
+
+ for( int i = 0; i < (int) m_pcbNetlist.GetCount(); i++ )
+ {
+ net = m_pcbNetlist[i];
+
+ if( net->m_name == aNetName )
+ {
+ return net->m_netCode;
+ }
+ }
+
+ return 0;
+}
+
+XNODE* PCB::FindCompDefName( XNODE* aNode, wxString aName )
+{
+ XNODE* result = NULL, * lNode;
+ wxString propValue;
+
+ lNode = FindNode( aNode, wxT( "compDef" ) );
+
+ while( lNode )
+ {
+ if( lNode->GetName() == wxT( "compDef" ) )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+
+ if( propValue == aName )
+ {
+ result = lNode;
+ lNode = NULL;
+ }
+ }
+
+ if( lNode )
+ lNode = lNode->GetNext();
+ }
+
+ return result;
+}
+
+
+void PCB::SetTextProperty( XNODE* aNode, TTEXTVALUE* aTextValue,
+ wxString aPatGraphRefName, wxString aXmlName,
+ wxString aActualConversion )
+{
+ XNODE* tNode, * t1Node;
+ wxString n, nnew, pn, propValue, str;
+
+ // aNode is pattern now
+ tNode = aNode;
+ t1Node = aNode;
+ n = aXmlName;
+
+ // new file format version
+ if( FindNode( tNode, wxT( "patternGraphicsNameRef" ) ) )
+ {
+ FindNode( tNode,
+ wxT( "patternGraphicsNameRef" ) )->GetAttribute( wxT( "Name" ),
+ &pn );
+ pn.Trim( false );
+ pn.Trim( true );
+ tNode = FindNode( tNode, wxT( "patternGraphicsRef" ) );
+
+ while( tNode )
+ {
+ if( tNode->GetName() == wxT( "patternGraphicsRef" ) )
+ {
+ if( FindNode( tNode, wxT( "patternGraphicsNameRef" ) ) )
+ {
+ FindNode( tNode,
+ wxT( "patternGraphicsNameRef" ) )->GetAttribute( wxT( "Name" ),
+ &propValue );
+
+ if( propValue == pn )
+ {
+ t1Node = tNode; // find correct section with same name.
+ str = aTextValue->text;
+ str.Trim( false );
+ str.Trim( true );
+ nnew = n; // new file version
+ n = n + wxT( ' ' ) + str; // old file version
+ tNode = NULL;
+ }
+ }
+ }
+
+ if( tNode )
+ tNode = tNode->GetNext();
+ }
+ }
+
+ // old version and compatibile fr both from this point
+ tNode = FindNode( t1Node, wxT( "attr" ) );
+
+ while( tNode )
+ {
+ tNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+
+ if( propValue == n || propValue == nnew )
+ break;
+
+ tNode = tNode->GetNext();
+ }
+
+ if( tNode )
+ SetTextParameters( tNode, aTextValue, m_defaultMeasurementUnit, aActualConversion );
+}
+
+
+void PCB::DoPCBComponents( XNODE* aNode,
+ wxXmlDocument* aXmlDoc,
+ wxString aActualConversion,
+ wxStatusBar* aStatusBar )
+{
+ XNODE* lNode, * tNode, * mNode;
+ PCB_MODULE* mc;
+ PCB_PAD* pad;
+ PCB_VIA* via;
+ PCB_KEEPOUT* keepOut;
+ wxString cn, str, propValue;
+
+ lNode = aNode->GetChildren();
+
+ while( lNode )
+ {
+ mc = NULL;
+
+ if( lNode->GetName() == wxT( "pattern" ) )
+ {
+ FindNode( lNode, wxT( "patternRef" ) )->GetAttribute( wxT( "Name" ),
+ &cn );
+ cn = ValidateName( cn );
+ tNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "library" ) );
+
+ if( tNode && cn.Len() > 0 )
+ {
+ tNode = FindModulePatternDefName( tNode, cn );
+
+ if( tNode )
+ {
+ mc = new PCB_MODULE( this, m_board );
+
+ mNode = FindNode( lNode, wxT( "patternGraphicsNameRef" ) );
+ if( mNode )
+ mNode->GetAttribute( wxT( "Name" ), &mc->m_patGraphRefName );
+
+ mc->Parse( tNode, aStatusBar, m_defaultMeasurementUnit, aActualConversion );
+ }
+ }
+
+ if( mc )
+ {
+ mc->m_compRef = cn; // default - in new version of file it is updated later....
+ tNode = FindNode( lNode, wxT( "refDesRef" ) );
+
+ if( tNode )
+ {
+ tNode->GetAttribute( wxT( "Name" ), &mc->m_name.text );
+ SetTextProperty( lNode, &mc->m_name, mc->m_patGraphRefName, wxT(
+ "RefDes" ), aActualConversion );
+ SetTextProperty( lNode, &mc->m_value, mc->m_patGraphRefName, wxT(
+ "Value" ), aActualConversion );
+ }
+
+ tNode = FindNode( lNode, wxT( "pt" ) );
+
+ if( tNode )
+ SetPosition( tNode->GetNodeContent(),
+ m_defaultMeasurementUnit,
+ &mc->m_positionX,
+ &mc->m_positionY,
+ aActualConversion );
+
+ tNode = FindNode( lNode, wxT( "rotation" ) );
+
+ if( tNode )
+ {
+ str = tNode->GetNodeContent();
+ str.Trim( false );
+ mc->m_rotation = StrToInt1Units( str );
+ }
+
+ str = FindNodeGetContent( lNode, wxT( "isFlipped" ) );
+
+ if( str == wxT( "True" ) )
+ mc->m_mirror = 1;
+
+ tNode = aNode;
+
+ while( tNode->GetName() != wxT( "www.lura.sk" ) )
+ tNode = tNode->GetParent();
+
+ tNode = FindNode( tNode, wxT( "netlist" ) );
+
+ if( tNode )
+ {
+ tNode = FindNode( tNode, wxT( "compInst" ) );
+
+ while( tNode )
+ {
+ tNode->GetAttribute( wxT( "Name" ), &propValue );
+
+ if( propValue == mc->m_name.text )
+ {
+ if( FindNode( tNode, wxT( "compValue" ) ) )
+ {
+ FindNode( tNode,
+ wxT( "compValue" ) )->GetAttribute( wxT( "Name" ),
+ &mc->m_value.text );
+ mc->m_value.text.Trim( false );
+ mc->m_value.text.Trim( true );
+ }
+
+ if( FindNode( tNode, wxT( "compRef" ) ) )
+ {
+ FindNode( tNode,
+ wxT( "compRef" ) )->GetAttribute( wxT( "Name" ),
+ &mc->m_compRef );
+ mc->m_compRef.Trim( false );
+ mc->m_compRef.Trim( true );
+ }
+
+ tNode = NULL;
+ }
+ else
+ tNode = tNode->GetNext();
+ }
+ }
+
+ // map pins
+ tNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "library" ) );
+ tNode = FindCompDefName( tNode, mc->m_compRef );
+
+ if( tNode )
+ {
+ tNode = FindPinMap( tNode );
+
+ if( tNode )
+ {
+ mNode = tNode->GetChildren();
+
+ while( mNode )
+ {
+ if( mNode->GetName() == wxT( "padNum" ) )
+ {
+ str = mNode->GetNodeContent();
+ mNode = mNode->GetNext();
+
+ if( !mNode )
+ break;
+
+ mNode->GetAttribute( wxT( "Name" ), &propValue );
+ mc->SetPadName( str, propValue );
+ mNode = mNode->GetNext();
+ }
+ else
+ {
+ mNode = mNode->GetNext();
+
+ if( !mNode )
+ break;
+
+ mNode = mNode->GetNext();
+ }
+ }
+ }
+ }
+
+ m_pcbComponents.Add( mc );
+ }
+ }
+ else if( lNode->GetName() == wxT( "pad" ) )
+ {
+ pad = new PCB_PAD( this, m_board );
+ pad->Parse( lNode, m_defaultMeasurementUnit, aActualConversion );
+ m_pcbComponents.Add( pad );
+ }
+ else if( lNode->GetName() == wxT( "via" ) )
+ {
+ via = new PCB_VIA( this, m_board );
+ via->Parse( lNode, m_defaultMeasurementUnit, aActualConversion );
+ m_pcbComponents.Add( via );
+ }
+ else if( lNode->GetName() == wxT( "polyKeepOut" ) )
+ {
+ keepOut = new PCB_KEEPOUT( m_callbacks, m_board, 0 );
+
+ if( keepOut->Parse( lNode, m_defaultMeasurementUnit, aActualConversion ) )
+ m_pcbComponents.Add( keepOut );
+ else
+ delete keepOut;
+ }
+
+ lNode = lNode->GetNext();
+ }
+}
+
+
+void PCB::ConnectPinToNet( wxString aCompRef, wxString aPinRef, wxString aNetName )
+{
+ PCB_MODULE* module;
+ PCB_PAD* cp;
+ int i, j;
+
+ for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ )
+ {
+ module = (PCB_MODULE*) m_pcbComponents[i];
+
+ if( module->m_objType == wxT( 'M' ) && module->m_name.text == aCompRef )
+ {
+ for( j = 0; j < (int) module->m_moduleObjects.GetCount(); j++ )
+ {
+ if( module->m_moduleObjects[j]->m_objType == wxT( 'P' ) )
+ {
+ cp = (PCB_PAD*) module->m_moduleObjects[j];
+
+ if( cp->m_name.text == aPinRef )
+ cp->m_net = aNetName;
+ }
+ }
+ }
+ }
+}
+
+
+int PCB::FindLayer( wxString aLayerName )
+{
+ for( LAYER_NUM i = 0; i < (int)m_layersStackup.GetCount(); ++i )
+ {
+ if( m_layersStackup[i] == aLayerName )
+ return i;
+ }
+
+ return -1;
+}
+
+
+/* KiCad layers
+ * 0 Copper layer
+ * 1 to 14 Inner layers
+ * 15 Component layer
+ * 16 Copper side adhesive layer Technical layers
+ * 17 Component side adhesive layer
+ * 18 Copper side Solder paste layer
+ * 19 Component Solder paste layer
+ * 20 Copper side Silk screen layer
+ * 21 Component Silk screen layer
+ * 22 Copper side Solder mask layer
+ * 23 Component Solder mask layer
+ * 24 Draw layer (Used for general drawings)
+ * 25 Comment layer (Other layer used for general drawings)
+ * 26 ECO1 layer (Other layer used for general drawings) // BUG
+ * 26 ECO2 layer (Other layer used for general drawings) // BUG 27
+ * 27 Edge layer. Items on Edge layer are seen on all layers // BUG 28
+ */
+void PCB::MapLayer( XNODE* aNode )
+{
+ wxString lName, layerType;
+ LAYER_ID KiCadLayer;
+ long num = 0;
+
+ aNode->GetAttribute( wxT( "Name" ), &lName );
+ lName = lName.MakeUpper();
+
+ if( lName == wxT( "TOP ASSY" ) )
+ KiCadLayer = Cmts_User;
+ else if( lName == wxT( "TOP SILK" ) )
+ KiCadLayer = F_SilkS;
+ else if( lName == wxT( "TOP PASTE" ) )
+ KiCadLayer = F_Paste;
+ else if( lName == wxT( "TOP MASK" ) )
+ KiCadLayer = F_Mask;
+ else if( lName == wxT( "TOP" ) )
+ KiCadLayer = F_Cu;
+ else if( lName == wxT( "BOTTOM" ) )
+ KiCadLayer = B_Cu;
+ else if( lName == wxT( "BOT MASK" ) )
+ KiCadLayer = B_Mask;
+ else if( lName == wxT( "BOT PASTE" ) )
+ KiCadLayer = B_Paste;
+ else if( lName == wxT( "BOT SILK" ) )
+ KiCadLayer = B_SilkS;
+ else if( lName == wxT( "BOT ASSY" ) )
+ KiCadLayer = Dwgs_User;
+ else if( lName == wxT( "BOARD" ) )
+ KiCadLayer = Edge_Cuts;
+ else
+ {
+ int layernum = FindLayer( lName );
+
+ if( layernum == -1 )
+ KiCadLayer = Dwgs_User; // default
+ else
+#if 0 // was:
+ KiCadLayer = FIRST_COPPER_LAYER + m_layersStackup.GetCount() - 1 - layernum;
+#else
+ KiCadLayer = ToLAYER_ID( layernum );
+#endif
+ }
+
+ if( FindNode( aNode, wxT( "layerNum" ) ) )
+ FindNode( aNode, wxT( "layerNum" ) )->GetNodeContent().ToLong( &num );
+
+ if( num < 0 || num >= MAX_PCAD_LAYER_QTY )
+ THROW_IO_ERROR( wxString::Format( wxT( "layerNum = %ld is out of range" ), num ) );
+
+ m_layersMap[(int) num].KiCadLayer = KiCadLayer;
+
+ if( FindNode( aNode, wxT( "layerType" ) ) )
+ {
+ layerType = FindNode( aNode, wxT( "layerType" ) )->GetNodeContent().Trim( false );
+
+ if( layerType == wxT( "NonSignal" ) )
+ m_layersMap[(int) num].layerType = LAYER_TYPE_NONSIGNAL;
+ if( layerType == wxT( "Signal" ) )
+ m_layersMap[(int) num].layerType = LAYER_TYPE_SIGNAL;
+ if( layerType == wxT( "Plane" ) )
+ m_layersMap[(int) num].layerType = LAYER_TYPE_PLANE;
+ }
+
+ if( FindNode( aNode, wxT( "netNameRef" ) ) )
+ {
+ FindNode( aNode, wxT( "netNameRef" ) )->GetAttribute( wxT( "Name" ),
+ &m_layersMap[(int) num].netNameRef );
+ }
+}
+
+int PCB::FindOutlinePoint( VERTICES_ARRAY* aOutline, wxRealPoint aPoint )
+{
+ int i;
+
+ for( i = 0; i < (int) aOutline->GetCount(); i++ )
+ if( *((*aOutline)[i]) == aPoint )
+ return i;
+
+ return -1;
+}
+
+/*int cmpFunc( wxRealPoint **first, wxRealPoint **second )
+{
+ return sqrt( pow( (double) aPointA.x - (double) aPointB.x, 2 ) +
+ pow( (double) aPointA.y - (double) aPointB.y, 2 ) );
+
+ return 0;
+}*/
+double PCB::GetDistance( wxRealPoint* aPoint1, wxRealPoint* aPoint2 )
+{
+ return sqrt( ( aPoint1->x - aPoint2->x ) *
+ ( aPoint1->x - aPoint2->x ) +
+ ( aPoint1->y - aPoint2->y ) *
+ ( aPoint1->y - aPoint2->y ) );
+}
+
+void PCB::GetBoardOutline( wxXmlDocument* aXmlDoc, wxString aActualConversion )
+{
+ XNODE* iNode, *lNode, *pNode;
+ long PCadLayer = 0;
+ int x, y, i, j, targetInd;
+ wxRealPoint* xchgPoint;
+ double minDistance, distance;
+
+ iNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) );
+
+ if( iNode )
+ {
+ // COMPONENTS AND OBJECTS
+ iNode = iNode->GetChildren();
+
+ while( iNode )
+ {
+ // objects
+ if( iNode->GetName() == wxT( "layerContents" ) )
+ {
+ if( FindNode( iNode, wxT( "layerNumRef" ) ) )
+ FindNode( iNode, wxT( "layerNumRef" ) )->GetNodeContent().ToLong( &PCadLayer );
+
+ if( GetKiCadLayer( PCadLayer ) == Edge_Cuts )
+ {
+ lNode = iNode->GetChildren();
+ while( lNode )
+ {
+ if( lNode->GetName() == wxT( "line" ) )
+ {
+ pNode = FindNode( lNode, wxT( "pt" ) );
+
+ if( pNode )
+ {
+ SetPosition( pNode->GetNodeContent(), m_defaultMeasurementUnit,
+ &x, &y, aActualConversion );
+
+ if( FindOutlinePoint( &m_boardOutline, wxRealPoint( x, y) ) == -1 )
+ m_boardOutline.Add( new wxRealPoint( x, y ) );
+ }
+
+ if( pNode )
+ pNode = pNode->GetNext();
+
+ if( pNode )
+ {
+ SetPosition( pNode->GetNodeContent(), m_defaultMeasurementUnit,
+ &x, &y, aActualConversion );
+
+ if( FindOutlinePoint( &m_boardOutline, wxRealPoint( x, y) ) == -1 )
+ m_boardOutline.Add( new wxRealPoint( x, y ) );
+ }
+ }
+
+ lNode = lNode->GetNext();
+ }
+
+ //m_boardOutline.Sort( cmpFunc );
+ // sort vertices according to the distances between them
+ if( m_boardOutline.GetCount() > 3 )
+ {
+ for( i = 0; i < (int) m_boardOutline.GetCount() - 1; i++ )
+ {
+ minDistance = GetDistance( m_boardOutline[i], m_boardOutline[i + 1] );
+ targetInd = i + 1;
+
+ for( j = i + 2; j < (int) m_boardOutline.GetCount(); j++ )
+ {
+ distance = GetDistance( m_boardOutline[i], m_boardOutline[j] );
+ if( distance < minDistance )
+ {
+ minDistance = distance;
+ targetInd = j;
+ }
+ }
+
+ xchgPoint = m_boardOutline[i + 1];
+ m_boardOutline[i + 1] = m_boardOutline[targetInd];
+ m_boardOutline[targetInd] = xchgPoint;
+ }
+ }
+
+ break;
+ }
+ }
+
+ iNode = iNode->GetNext();
+ }
+ }
+}
+
+void PCB::Parse( wxStatusBar* aStatusBar, wxXmlDocument* aXmlDoc, wxString aActualConversion )
+{
+ XNODE* aNode;//, *aaNode;
+ PCB_NET* net;
+ PCB_COMPONENT* comp;
+ PCB_MODULE* module;
+ wxString compRef, pinRef, layerName, layerType;
+ int i, j, netCode;
+
+ // Defaut measurement units
+ aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "asciiHeader" ) );
+
+ if( aNode )
+ {
+ aNode = FindNode( aNode, wxT( "fileUnits" ) );
+
+ if( aNode )
+ {
+ m_defaultMeasurementUnit = aNode->GetNodeContent().Lower();
+ m_defaultMeasurementUnit.Trim( true );
+ m_defaultMeasurementUnit.Trim( false );
+ }
+ }
+
+ // Determine layers stackup
+ aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) );
+
+ /*if( aNode )
+ {
+ aNode = FindNode( aNode, wxT( "layersStackup" ) );
+
+ if( aNode )
+ {
+ aNode = FindNode( aNode, wxT( "layerStackupData" ) );
+
+ while( aNode )
+ {
+ if( aNode->GetName() == wxT( "layerStackupData" ) )
+ {
+ aaNode = FindNode( aNode, wxT( "layerStackupName" ) );
+
+ if( aaNode ) {
+ aaNode->GetAttribute( wxT( "Name" ), &layerName );
+ layerName = layerName.MakeUpper();
+ m_layersStackup.Add( layerName );
+ }
+ }
+
+ aNode = aNode->GetNext();
+ }
+ }
+ }*/
+
+ if( aNode )
+ {
+ aNode = FindNode( aNode, wxT( "layerDef" ) );
+
+ while( aNode )
+ {
+ if( aNode->GetName() == wxT( "layerDef" ) )
+ {
+ if( FindNode( aNode, wxT( "layerType" ) ) )
+ {
+ layerType = FindNode( aNode,
+ wxT( "layerType" ) )->GetNodeContent().Trim( false );
+
+ if( layerType == wxT( "Signal" ) || layerType == wxT( "Plane" ) )
+ {
+ aNode->GetAttribute( wxT( "Name" ), &layerName );
+ layerName = layerName.MakeUpper();
+ m_layersStackup.Add( layerName );
+ }
+ }
+ }
+
+ aNode = aNode->GetNext();
+ }
+ }
+
+ // Layers mapping
+ aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) );
+
+ if( aNode )
+ {
+ aNode = FindNode( aNode, wxT( "layerDef" ) );
+
+ while( aNode )
+ {
+ if( aNode->GetName() == wxT( "layerDef" ) )
+ MapLayer( aNode );
+
+ aNode = aNode->GetNext();
+ }
+ }
+
+ GetBoardOutline( aXmlDoc, aActualConversion );
+
+ // NETLIST
+ // aStatusBar->SetStatusText( wxT( "Loading NETLIST " ) );
+
+ aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "netlist" ) );
+
+ if( aNode )
+ {
+ aNode = FindNode( aNode, wxT( "net" ) );
+
+ netCode = 1;
+
+ while( aNode )
+ {
+ net = new PCB_NET( netCode++ );
+ net->Parse( aNode );
+ m_pcbNetlist.Add( net );
+
+ aNode = aNode->GetNext();
+ }
+ }
+
+ // BOARD FILE
+ // aStatusBar->SetStatusText( wxT( "Loading BOARD DEFINITION " ) );
+
+ aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "pcbDesign" ) );
+
+ if( aNode )
+ {
+ // COMPONENTS AND OBJECTS
+ aNode = aNode->GetChildren();
+
+ while( aNode )
+ {
+ // Components/modules
+ if( aNode->GetName() == wxT( "multiLayer" ) )
+ DoPCBComponents( aNode, aXmlDoc, aActualConversion, aStatusBar );
+
+ // objects
+ if( aNode->GetName() == wxT( "layerContents" ) )
+ DoLayerContentsObjects( aNode, NULL, &m_pcbComponents, aStatusBar,
+ m_defaultMeasurementUnit, aActualConversion );
+
+ aNode = aNode->GetNext();
+ }
+
+ // POSTPROCESS -- SET NETLIST REFERENCES
+ // aStatusBar->SetStatusText( wxT( "Processing NETLIST " ) );
+
+ for( i = 0; i < (int) m_pcbNetlist.GetCount(); i++ )
+ {
+ net = m_pcbNetlist[i];
+
+ for( j = 0; j < (int) net->m_netNodes.GetCount(); j++ )
+ {
+ compRef = net->m_netNodes[j]->m_compRef;
+ compRef.Trim( false );
+ compRef.Trim( true );
+ pinRef = net->m_netNodes[j]->m_pinRef;
+ pinRef.Trim( false );
+ pinRef.Trim( true );
+ ConnectPinToNet( compRef, pinRef, net->m_name );
+ }
+ }
+
+ // POSTPROCESS -- FLIP COMPONENTS
+ for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ )
+ {
+ if( m_pcbComponents[i]->m_objType == wxT( 'M' ) )
+ ( (PCB_MODULE*) m_pcbComponents[i] )->Flip();
+ }
+
+ // POSTPROCESS -- SET/OPTIMIZE NEW PCB POSITION
+ // aStatusBar->SetStatusText( wxT( "Optimizing BOARD POSITION " ) );
+
+ m_sizeX = 10000000;
+ m_sizeY = 0;
+
+ for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ )
+ {
+ comp = m_pcbComponents[i];
+
+ if( comp->m_positionY < m_sizeY )
+ m_sizeY = comp->m_positionY; // max Y
+
+ if( comp->m_positionX < m_sizeX && comp->m_positionX > 0 )
+ m_sizeX = comp->m_positionX; // Min X
+ }
+
+ m_sizeY -= 10000;
+ m_sizeX -= 10000;
+ // aStatusBar->SetStatusText( wxT( " POSITIONING POSTPROCESS " ) );
+
+ for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ )
+ m_pcbComponents[i]->SetPosOffset( -m_sizeX, -m_sizeY );
+
+ m_sizeX = 0;
+ m_sizeY = 0;
+
+ for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ )
+ {
+ comp = m_pcbComponents[i];
+
+ if( comp->m_positionY < m_sizeY )
+ m_sizeY = comp->m_positionY; // max Y
+
+ if( comp->m_positionX > m_sizeX )
+ m_sizeX = comp->m_positionX; // Min X
+ }
+
+ // SHEET SIZE CALCULATION
+ m_sizeY = -m_sizeY; // it is in absolute units
+ m_sizeX += 10000;
+ m_sizeY += 10000;
+
+ // A4 is minimum $Descr A4 11700 8267
+ if( m_sizeX < 11700 )
+ m_sizeX = 11700;
+
+ if( m_sizeY < 8267 )
+ m_sizeY = 8267;
+ }
+ else
+ {
+ // LIBRARY FILE
+ // aStatusBar->SetStatusText( wxT( "Processing LIBRARY FILE " ) );
+
+ aNode = FindNode( (XNODE *)aXmlDoc->GetRoot(), wxT( "library" ) );
+
+ if( aNode )
+ {
+ aNode = FindNode( aNode, wxT( "compDef" ) );
+
+ while( aNode )
+ {
+ // aStatusBar->SetStatusText( wxT( "Processing COMPONENTS " ) );
+
+ if( aNode->GetName() == wxT( "compDef" ) )
+ {
+ module = new PCB_MODULE( this, m_board );
+ module->Parse( aNode, aStatusBar, m_defaultMeasurementUnit,
+ aActualConversion );
+ m_pcbComponents.Add( module );
+ }
+
+ aNode = aNode->GetNext();
+ }
+ }
+ }
+}
+
+
+void PCB::AddToBoard()
+{
+ int i;
+ PCB_NET* net;
+
+ m_board->SetCopperLayerCount( m_layersStackup.GetCount() );
+
+ for( i = 0; i < (int) m_pcbNetlist.GetCount(); i++ )
+ {
+ net = m_pcbNetlist[i];
+
+ m_board->AppendNet( new NETINFO_ITEM( m_board, net->m_name, net->m_netCode ) );
+ }
+
+ for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ )
+ {
+ m_pcbComponents[i]->AddToBoard();
+ }
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb.h b/pcbnew/pcad2kicadpcb_plugin/pcb.h
new file mode 100644
index 0000000..5d566ff
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb.h
@@ -0,0 +1,92 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb.h
+ */
+
+#ifndef pcb_H_
+#define pcb_H_
+
+#include <wx/wx.h>
+#include <xnode.h>
+
+#include <pcb_module.h>
+#include <pcb_net.h>
+
+namespace PCAD2KICAD {
+
+#define MAX_PCAD_LAYER_QTY 32
+
+class PCB : public PCB_MODULE, public PCB_CALLBACKS
+{
+public:
+ PCB_COMPONENTS_ARRAY m_pcbComponents; // PCB Modules,Lines,Routes,Texts, .... and so on
+ PCB_NETS_ARRAY m_pcbNetlist; // net objects collection
+ wxString m_defaultMeasurementUnit;
+ TLAYER m_layersMap[MAX_PCAD_LAYER_QTY]; // flexible layers mapping
+ int m_sizeX;
+ int m_sizeY;
+
+ PCB( BOARD* aBoard );
+ ~PCB();
+
+ LAYER_ID GetKiCadLayer( int aPCadLayer );
+ LAYER_TYPE_T GetLayerType( int aPCadLayer );
+ wxString GetLayerNetNameRef( int aPCadLayer );
+ int GetNewTimestamp();
+ int GetNetCode( wxString aNetName );
+
+ void Parse( wxStatusBar* aStatusBar,
+ wxXmlDocument* aXmlDoc,
+ wxString aActualConversion );
+
+ void AddToBoard();
+
+private:
+ int m_timestamp_cnt;
+ wxArrayString m_layersStackup;
+
+ XNODE* FindCompDefName( XNODE* aNode, wxString aName );
+ void SetTextProperty( XNODE* aNode,
+ TTEXTVALUE* aTextValue,
+ wxString aPatGraphRefName,
+ wxString aXmlName,
+ wxString aActualConversion );
+ void DoPCBComponents( XNODE* aNode,
+ wxXmlDocument* aXmlDoc,
+ wxString aActualConversion,
+ wxStatusBar* aStatusBar );
+ void ConnectPinToNet( wxString aCr, wxString aPr, wxString aNetName );
+ int FindLayer( wxString aLayerName );
+ void MapLayer( XNODE* aNode );
+ int FindOutlinePoint( VERTICES_ARRAY* aOutline, wxRealPoint aPoint );
+ double GetDistance( wxRealPoint* aPoint1, wxRealPoint* aPoint2 );
+ void GetBoardOutline( wxXmlDocument* aXmlDoc, wxString aActualConversion );
+};
+
+} // namespace PCAD2KICAD
+
+#endif // pcb_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_arc.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_arc.cpp
new file mode 100644
index 0000000..d4395ad
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_arc.cpp
@@ -0,0 +1,193 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_arc.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+#include <trigo.h>
+
+#include <pcb_arc.h>
+
+namespace PCAD2KICAD {
+
+PCB_ARC::PCB_ARC( PCB_CALLBACKS* aCallbacks, BOARD* aBoard ) : PCB_COMPONENT( aCallbacks, aBoard )
+{
+ m_objType = wxT( 'A' );
+ m_startX = 0;
+ m_startY = 0;
+ m_angle = 0;
+ m_width = 0;
+}
+
+
+PCB_ARC::~PCB_ARC()
+{
+}
+
+
+void PCB_ARC::Parse( XNODE* aNode,
+ int aLayer,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ XNODE* lNode;
+ double a = 0.0;
+ int r = 0;
+ int endX = 0;
+ int endY = 0;
+
+ m_PCadLayer = aLayer;
+ m_KiCadLayer = GetKiCadLayer();
+
+ if( FindNode( aNode, wxT( "width" ) ) )
+ SetWidth( FindNode( aNode, wxT( "width" ) )->GetNodeContent(),
+ aDefaultMeasurementUnit, &m_width, aActualConversion );
+
+ if( aNode->GetName() == wxT( "triplePointArc" ) )
+ {
+ // center point
+ lNode = FindNode( aNode, wxT( "pt" ) );
+
+ if( lNode )
+ SetPosition( lNode->GetNodeContent(), aDefaultMeasurementUnit,
+ &m_positionX, &m_positionY, aActualConversion );
+
+ // start point
+ if( lNode )
+ lNode = lNode->GetNext();
+
+ if( lNode )
+ SetPosition( lNode->GetNodeContent(), aDefaultMeasurementUnit,
+ &m_startX, &m_startY, aActualConversion );
+
+ // end point
+ if( lNode )
+ lNode = lNode->GetNext();
+
+ if( lNode )
+ SetPosition( lNode->GetNodeContent(), aDefaultMeasurementUnit,
+ &endX, &endY, aActualConversion );
+
+ if( m_startX == endX && m_startY == endY )
+ {
+ m_angle = 3600;
+ }
+ else
+ {
+ double alpha1 = ArcTangente( m_startY - m_positionY, m_startX - m_positionX );
+ double alpha2 = ArcTangente( endY - m_positionY, endX - m_positionX );
+ m_angle = alpha1 - alpha2;
+
+ NORMALIZE_ANGLE_POS( m_angle );
+ }
+ }
+ else if( aNode->GetName() == wxT( "arc" ) )
+ {
+ lNode = FindNode( aNode, wxT( "pt" ) );
+
+ if( lNode )
+ SetPosition( lNode->GetNodeContent(), aDefaultMeasurementUnit,
+ &m_positionX, &m_positionY, aActualConversion );
+
+ lNode = FindNode( aNode, wxT( "radius" ) );
+ if( lNode)
+ SetWidth( FindNode( aNode, wxT( "radius" ) )->GetNodeContent(),
+ aDefaultMeasurementUnit, &r, aActualConversion );
+
+
+ lNode = FindNode( aNode, wxT( "startAngle" ) );
+ if( lNode )
+ a = StrToInt1Units( lNode->GetNodeContent() );
+
+ lNode = FindNode( aNode, wxT( "sweepAngle" ) );
+ if( lNode )
+ m_angle = StrToInt1Units( lNode->GetNodeContent() );
+
+ m_startX = m_positionX + KiROUND( cosdecideg( r, a ) );
+ m_startY = m_positionY - KiROUND( sindecideg( r, a ) );
+ }
+}
+
+
+void PCB_ARC::SetPosOffset( int aX_offs, int aY_offs )
+{
+ PCB_COMPONENT::SetPosOffset( aX_offs, aY_offs );
+
+ m_startX += aX_offs;
+ m_startY += aY_offs;
+}
+
+
+void PCB_ARC::Flip()
+{
+ PCB_COMPONENT::Flip();
+
+ m_startX = -m_startX;
+ m_angle = -m_angle;
+
+ m_KiCadLayer = FlipLayer( m_KiCadLayer );
+}
+
+
+void PCB_ARC::AddToModule( MODULE* aModule )
+{
+ if( IsNonCopperLayer( m_KiCadLayer ) )
+ {
+ EDGE_MODULE* arc = new EDGE_MODULE( aModule, S_ARC );
+ aModule->GraphicalItems().PushBack( arc );
+
+ arc->SetAngle( -m_angle );
+ arc->m_Start0 = wxPoint( m_positionX, m_positionY );
+ arc->m_End0 = wxPoint( m_startX, m_startY );
+
+ arc->SetWidth( m_width );
+ arc->SetLayer( m_KiCadLayer );
+
+ arc->SetDrawCoord();
+ }
+}
+
+
+void PCB_ARC::AddToBoard()
+{
+ DRAWSEGMENT* dseg = new DRAWSEGMENT( m_board );
+
+ m_board->Add( dseg, ADD_APPEND );
+
+ dseg->SetShape( S_ARC );
+ dseg->SetTimeStamp( m_timestamp );
+ dseg->SetLayer( m_KiCadLayer );
+ dseg->SetStart( wxPoint( m_positionX, m_positionY ) );
+ dseg->SetEnd( wxPoint( m_startX, m_startY ) );
+ dseg->SetAngle( -m_angle );
+ dseg->SetWidth( m_width );
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_arc.h b/pcbnew/pcad2kicadpcb_plugin/pcb_arc.h
new file mode 100644
index 0000000..8b1c83e
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_arc.h
@@ -0,0 +1,61 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_arc.h
+ */
+
+#ifndef PCB_ARC_H_
+#define PCB_ARC_H_
+
+#include <wx/wx.h>
+
+#include <pcb_component.h>
+
+namespace PCAD2KICAD {
+
+class PCB_ARC : public PCB_COMPONENT
+{
+public:
+ int m_startX;
+ int m_startY;
+ double m_angle;
+ int m_width;
+
+ PCB_ARC( PCB_CALLBACKS* aCallbacks, BOARD* aBoard );
+ ~PCB_ARC();
+
+ virtual void Parse( XNODE* aNode, int aLayer,
+ wxString aDefaultMeasurementUnit, wxString aActualConversion );
+
+ virtual void SetPosOffset( int aX_offs, int aY_offs );
+ virtual void Flip();
+ void AddToModule( MODULE* aModule );
+ void AddToBoard();
+};
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_ARC_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_callbacks.h b/pcbnew/pcad2kicadpcb_plugin/pcb_callbacks.h
new file mode 100644
index 0000000..2c2b5f8
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_callbacks.h
@@ -0,0 +1,64 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_callbacks.h
+ */
+
+#ifndef PCB_CALLBACKS_H_
+#define PCB_CALLBACKS_H_
+
+#include <wx/wx.h>
+#include <layers_id_colors_and_visibility.h>
+
+enum LAYER_TYPE_T
+{
+ LAYER_TYPE_SIGNAL,
+ LAYER_TYPE_NONSIGNAL,
+ LAYER_TYPE_PLANE
+};
+
+typedef struct _TLAYER
+{
+ LAYER_ID KiCadLayer;
+ LAYER_TYPE_T layerType;
+ wxString netNameRef;
+} TLAYER;
+
+namespace PCAD2KICAD
+{
+
+ class PCB_CALLBACKS
+ {
+ public:
+ virtual LAYER_ID GetKiCadLayer( int aPCadLayer ) = 0;
+ virtual LAYER_TYPE_T GetLayerType( int aPCadLayer ) = 0;
+ virtual wxString GetLayerNetNameRef( int aPCadLayer ) = 0;
+ virtual int GetNewTimestamp() = 0;
+ virtual int GetNetCode( wxString netName ) = 0;
+ };
+}
+
+#endif // PCB_CALLBACKS_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_component.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_component.cpp
new file mode 100644
index 0000000..44f5cd9
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_component.cpp
@@ -0,0 +1,80 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_component.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+
+#include <pcb_component.h>
+
+namespace PCAD2KICAD {
+
+PCB_COMPONENT::PCB_COMPONENT( PCB_CALLBACKS* aCallbacks,
+ BOARD* aBoard ) : m_callbacks( aCallbacks ),
+ m_board( aBoard )
+{
+ m_tag = 0;
+ m_objType = wxT( '?' );
+ m_PCadLayer = 0;
+ m_KiCadLayer = F_Cu; // It *has* to be somewhere...
+ m_timestamp = 0;
+ m_positionX = 0;
+ m_positionY = 0;
+ m_rotation = 0;
+ InitTTextValue( &m_name );
+ m_net = wxEmptyString;
+ m_netCode = 0;
+ m_compRef = wxEmptyString;
+ m_patGraphRefName = wxEmptyString;
+}
+
+
+PCB_COMPONENT::~PCB_COMPONENT()
+{
+}
+
+
+void PCB_COMPONENT::AddToModule( MODULE* aModule )
+{
+}
+
+
+void PCB_COMPONENT::SetPosOffset( int aX_offs, int aY_offs )
+{
+ m_positionX += aX_offs;
+ m_positionY += aY_offs;
+}
+
+void PCB_COMPONENT::Flip()
+{
+ m_positionX = -m_positionX;
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_component.h b/pcbnew/pcad2kicadpcb_plugin/pcb_component.h
new file mode 100644
index 0000000..6088fad
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_component.h
@@ -0,0 +1,87 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_component.h
+ */
+
+#ifndef PCB_COMPONENT_H_
+#define PCB_COMPONENT_H_
+
+#include <wx/wx.h>
+#include <wx/file.h>
+
+#include <pcad2kicad_common.h>
+#include <pcb_callbacks.h>
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_edge_mod.h>
+#include <class_zone.h>
+#include <class_pcb_text.h>
+
+namespace PCAD2KICAD {
+
+// basic parent class for PCB objects
+class PCB_COMPONENT : public wxObject
+{
+public:
+ int m_tag;
+ char m_objType;
+ int m_PCadLayer;
+ LAYER_ID m_KiCadLayer;
+ int m_timestamp;
+ int m_positionX;
+ int m_positionY;
+ int m_rotation;
+ TTEXTVALUE m_name; // name has also private positions, rotations and so on....
+ wxString m_net;
+ int m_netCode;
+ wxString m_compRef; // internal usage for XL parsing
+ wxString m_patGraphRefName; // internal usage for XL parsing
+
+ PCB_COMPONENT( PCB_CALLBACKS* aCallbacks, BOARD* aBoard );
+ ~PCB_COMPONENT();
+
+ virtual void SetPosOffset( int aX_offs, int aY_offs );
+ virtual void Flip();
+ virtual void AddToModule( MODULE* aModule );
+ virtual void AddToBoard() = 0;
+
+ LAYER_ID GetKiCadLayer() { return m_callbacks->GetKiCadLayer( m_PCadLayer ); }
+ int GetNewTimestamp() { return m_callbacks->GetNewTimestamp(); }
+ int GetNetCode( wxString aNetName ) { return m_callbacks->GetNetCode( aNetName ); }
+
+protected:
+ PCB_CALLBACKS* m_callbacks;
+ BOARD* m_board;
+};
+
+WX_DEFINE_ARRAY( PCB_COMPONENT*, PCB_COMPONENTS_ARRAY );
+WX_DEFINE_ARRAY( wxRealPoint*, VERTICES_ARRAY );
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_COMPONENT_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_copper_pour.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_copper_pour.cpp
new file mode 100644
index 0000000..16c7c22
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_copper_pour.cpp
@@ -0,0 +1,112 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_copper_pour.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+
+#include <pcb_copper_pour.h>
+
+namespace PCAD2KICAD {
+
+PCB_COPPER_POUR::PCB_COPPER_POUR( PCB_CALLBACKS* aCallbacks,
+ BOARD* aBoard,
+ int aPCadLayer ) :
+ PCB_POLYGON( aCallbacks, aBoard, aPCadLayer )
+{
+ m_filled = false;
+}
+
+
+PCB_COPPER_POUR::~PCB_COPPER_POUR()
+{
+}
+
+
+bool PCB_COPPER_POUR::Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion,
+ wxStatusBar* aStatusBar )
+{
+ XNODE* lNode;
+ wxString pourType, str, propValue;
+ int pourSpacing, thermalWidth;
+
+ // aStatusBar->SetStatusText( aStatusBar->GetStatusText() + wxT( " CooperPour..." ) );
+
+ //str = FindNode( aNode, wxT( "pourType" ) )->GetNodeContent();
+ //str.Trim( false );
+ //pourType = str.MakeUpper();
+
+ lNode = FindNode( aNode, wxT( "netNameRef" ) );
+
+ if( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+ m_net = propValue;
+ m_netCode = GetNetCode( m_net );
+ }
+
+ if( FindNode( aNode, wxT( "width" ) ) )
+ SetWidth( FindNode( aNode, wxT( "width" ) )->GetNodeContent(),
+ aDefaultMeasurementUnit, &m_width, aActualConversion );
+
+ if( FindNode( aNode, wxT( "pourSpacing" ) ) )
+ SetWidth( FindNode( aNode, wxT( "pourSpacing" ) )->GetNodeContent(),
+ aDefaultMeasurementUnit, &pourSpacing, aActualConversion );
+
+ if( FindNode( aNode, wxT( "thermalWidth" ) ) )
+ SetWidth( FindNode( aNode, wxT( "thermalWidth" ) )->GetNodeContent(),
+ aDefaultMeasurementUnit, &thermalWidth, aActualConversion );
+
+ if( FindNode( aNode, wxT( "island" ) ) )
+ m_filled = true;
+
+ lNode = FindNode( aNode, wxT( "pcbPoly" ) );
+
+ if( lNode )
+ {
+ // retrieve copper pour outline
+ FormPolygon( lNode, &m_outline, aDefaultMeasurementUnit, aActualConversion );
+
+ m_positionX = m_outline[0]->x;
+ m_positionY = m_outline[0]->y;
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_copper_pour.h b/pcbnew/pcad2kicadpcb_plugin/pcb_copper_pour.h
new file mode 100644
index 0000000..209b75f
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_copper_pour.h
@@ -0,0 +1,54 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_copper_pour.h
+ */
+
+#ifndef PCB_COPPER_POUR_H_
+#define PCB_COPPER_POUR_H_
+
+#include <wx/wx.h>
+
+#include <pcb_polygon.h>
+
+namespace PCAD2KICAD {
+
+class PCB_COPPER_POUR : public PCB_POLYGON
+{
+public:
+
+ PCB_COPPER_POUR( PCB_CALLBACKS* aCallbacks, BOARD* aBoard, int aPCadLayer );
+ ~PCB_COPPER_POUR();
+
+ virtual bool Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion,
+ wxStatusBar* aStatusBar );
+};
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_COPPER_POUR_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_cutout.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_cutout.cpp
new file mode 100644
index 0000000..4499783
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_cutout.cpp
@@ -0,0 +1,74 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_cutout.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <pcb_cutout.h>
+
+namespace PCAD2KICAD {
+
+PCB_CUTOUT::PCB_CUTOUT( PCB_CALLBACKS* aCallbacks, BOARD* aBoard, int aPCadLayer ) :
+ PCB_POLYGON( aCallbacks, aBoard, aPCadLayer )
+{
+ m_objType = wxT( 'C' );
+}
+
+
+PCB_CUTOUT::~PCB_CUTOUT()
+{
+}
+
+
+bool PCB_CUTOUT::Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ XNODE* lNode;
+
+ lNode = FindNode( aNode, wxT( "pcbPoly" ) );
+
+ if( lNode )
+ {
+ // retrieve cutout outline
+ FormPolygon( lNode, &m_outline, aDefaultMeasurementUnit, aActualConversion );
+
+ m_positionX = m_outline[0]->x;
+ m_positionY = m_outline[0]->y;
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_cutout.h b/pcbnew/pcad2kicadpcb_plugin/pcb_cutout.h
new file mode 100644
index 0000000..9f8fa6b
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_cutout.h
@@ -0,0 +1,53 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_cutout.h
+ */
+
+#ifndef PCB_CUTOUT_H_
+#define PCB_CUTOUT_H_
+
+#include <wx/wx.h>
+
+#include <pcb_polygon.h>
+
+namespace PCAD2KICAD {
+
+class PCB_CUTOUT : public PCB_POLYGON
+{
+public:
+
+ PCB_CUTOUT( PCB_CALLBACKS* aCallbacks, BOARD* aBoard, int aPCadLayer );
+ ~PCB_CUTOUT();
+
+ virtual bool Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString actualConversion );
+};
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_CUTOUT_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_keepout.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_keepout.cpp
new file mode 100644
index 0000000..d6305b3
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_keepout.cpp
@@ -0,0 +1,76 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_keepout.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+
+#include <pcb_keepout.h>
+
+namespace PCAD2KICAD {
+
+PCB_KEEPOUT::PCB_KEEPOUT( PCB_CALLBACKS* aCallbacks,
+ BOARD* aBoard,
+ int aPCadLayer ) :
+ PCB_POLYGON( aCallbacks, aBoard, aPCadLayer )
+{
+ m_objType = wxT( 'K' );
+}
+
+
+PCB_KEEPOUT::~PCB_KEEPOUT()
+{
+}
+
+
+bool PCB_KEEPOUT::Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ XNODE* lNode;
+
+ lNode = FindNode( aNode, wxT( "pcbPoly" ) );
+
+ if( lNode )
+ {
+ // retrieve keepOut outline
+ FormPolygon( lNode, &m_outline, aDefaultMeasurementUnit, aActualConversion );
+
+ m_positionX = m_outline[0]->x;
+ m_positionY = m_outline[0]->y;
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_keepout.h b/pcbnew/pcad2kicadpcb_plugin/pcb_keepout.h
new file mode 100644
index 0000000..d6b9513
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_keepout.h
@@ -0,0 +1,52 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_keepout.h
+ */
+
+#ifndef PCB_KEEPOUT_H_
+#define PCB_KEEPOUT_H_
+
+#include <wx/wx.h>
+
+#include <pcb_polygon.h>
+
+namespace PCAD2KICAD {
+
+class PCB_KEEPOUT : public PCB_POLYGON
+{
+public:
+
+ PCB_KEEPOUT( PCB_CALLBACKS* aCallbacks, BOARD* aBoard, int aPCadLayer );
+ ~PCB_KEEPOUT();
+
+ virtual bool Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion );
+};
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_KEEPOUT_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_line.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_line.cpp
new file mode 100644
index 0000000..019029d
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_line.cpp
@@ -0,0 +1,166 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_line.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+
+#include <pcb_line.h>
+
+namespace PCAD2KICAD {
+
+PCB_LINE::PCB_LINE( PCB_CALLBACKS* aCallbacks, BOARD* aBoard ) : PCB_COMPONENT( aCallbacks,
+ aBoard )
+{
+ m_width = 0;
+ m_toX = 0;
+ m_toY = 0;
+ m_objType = wxT( 'L' );
+}
+
+
+PCB_LINE::~PCB_LINE()
+{
+}
+
+
+void PCB_LINE::Parse( XNODE* aNode,
+ int aLayer,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ XNODE* lNode;
+ wxString propValue;
+
+ m_PCadLayer = aLayer;
+ m_KiCadLayer = GetKiCadLayer();
+ m_positionX = 0;
+ m_positionY = 0;
+ m_toX = 0;
+ m_toY = 0;
+ m_width = 0;
+ lNode = FindNode( aNode, wxT( "pt" ) );
+
+ if( lNode )
+ SetPosition( lNode->GetNodeContent(), aDefaultMeasurementUnit,
+ &m_positionX, &m_positionY, aActualConversion );
+
+ if( lNode )
+ lNode = lNode->GetNext();
+
+ if( lNode )
+ SetPosition( lNode->GetNodeContent(), aDefaultMeasurementUnit,
+ &m_toX, &m_toY, aActualConversion );
+
+ lNode = FindNode( aNode, wxT( "width" ) );
+
+ if( lNode )
+ SetWidth( lNode->GetNodeContent(), aDefaultMeasurementUnit, &m_width, aActualConversion );
+
+ lNode = FindNode( aNode, wxT( "netNameRef" ) );
+
+ if( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+ m_net = propValue;
+ m_netCode = GetNetCode( m_net );
+ }
+}
+
+
+void PCB_LINE::SetPosOffset( int aX_offs, int aY_offs )
+{
+ PCB_COMPONENT::SetPosOffset( aX_offs, aY_offs );
+
+ m_toX += aX_offs;
+ m_toY += aY_offs;
+}
+
+
+void PCB_LINE::Flip()
+{
+ PCB_COMPONENT::Flip();
+
+ m_toX = -m_toX;
+ m_KiCadLayer = FlipLayer( m_KiCadLayer );
+}
+
+
+void PCB_LINE::AddToModule( MODULE* aModule )
+{
+ if( IsNonCopperLayer( m_KiCadLayer ) )
+ {
+ EDGE_MODULE* segment = new EDGE_MODULE( aModule, S_SEGMENT );
+ aModule->GraphicalItems().PushBack( segment );
+
+ segment->m_Start0 = wxPoint( m_positionX, m_positionY );
+ segment->m_End0 = wxPoint( m_toX, m_toY );
+
+ segment->SetWidth( m_width );
+ segment->SetLayer( m_KiCadLayer );
+
+ segment->SetDrawCoord();
+ }
+}
+
+
+void PCB_LINE::AddToBoard()
+{
+ if( IsCopperLayer( m_KiCadLayer ) )
+ {
+ TRACK* track = new TRACK( m_board );
+ m_board->m_Track.Append( track );
+
+ track->SetTimeStamp( m_timestamp );
+
+ track->SetPosition( wxPoint( m_positionX, m_positionY ) );
+ track->SetEnd( wxPoint( m_toX, m_toY ) );
+
+ track->SetWidth( m_width );
+
+ track->SetLayer( m_KiCadLayer );
+ track->SetNetCode( m_netCode );
+ }
+ else
+ {
+ DRAWSEGMENT* dseg = new DRAWSEGMENT( m_board );
+ m_board->Add( dseg, ADD_APPEND );
+
+ dseg->SetTimeStamp( m_timestamp );
+ dseg->SetLayer( m_KiCadLayer );
+ dseg->SetStart( wxPoint( m_positionX, m_positionY ) );
+ dseg->SetEnd( wxPoint( m_toX, m_toY ) );
+ dseg->SetWidth( m_width );
+ }
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_line.h b/pcbnew/pcad2kicadpcb_plugin/pcb_line.h
new file mode 100644
index 0000000..e24aa38
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_line.h
@@ -0,0 +1,62 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_line.h
+ */
+
+#ifndef PCB_LINE_H_
+#define PCB_LINE_H_
+
+#include <wx/wx.h>
+
+#include <pcb_component.h>
+
+namespace PCAD2KICAD {
+
+// Line , routes and drawings
+class PCB_LINE : public PCB_COMPONENT
+{
+public:
+ int m_width;
+ int m_toX;
+ int m_toY;
+
+ PCB_LINE( PCB_CALLBACKS* aCallbacks, BOARD* aBoard );
+ ~PCB_LINE();
+
+ virtual void Parse( XNODE* aNode,
+ int aLayer,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion );
+ virtual void SetPosOffset( int aX_offs, int aY_offs );
+ virtual void Flip();
+ void AddToModule( MODULE* aModule );
+ void AddToBoard();
+};
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_LINE_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp
new file mode 100644
index 0000000..5bcf7d9
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp
@@ -0,0 +1,640 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_module.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+
+#include <pcb_arc.h>
+#include <pcb_copper_pour.h>
+#include <pcb_cutout.h>
+#include <pcb_plane.h>
+#include <pcb_line.h>
+#include <pcb_module.h>
+#include <pcb_pad.h>
+#include <pcb_polygon.h>
+#include <pcb_text.h>
+#include <pcb_via.h>
+
+#include <trigo.h>
+
+namespace PCAD2KICAD {
+
+PCB_MODULE::PCB_MODULE( PCB_CALLBACKS* aCallbacks, BOARD* aBoard ) : PCB_COMPONENT( aCallbacks,
+ aBoard )
+{
+ InitTTextValue( &m_value );
+ m_mirror = 0;
+ m_objType = wxT( 'M' ); // MODULE
+ m_KiCadLayer = F_SilkS; // default
+}
+
+
+PCB_MODULE::~PCB_MODULE()
+{
+ int i;
+
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ delete m_moduleObjects[i];
+ }
+}
+
+
+XNODE* PCB_MODULE::FindModulePatternDefName( XNODE* aNode, wxString aName )
+{
+ XNODE* result, * lNode;
+ wxString propValue1, propValue2;
+
+ result = NULL;
+ lNode = FindNode( aNode, wxT( "patternDef" ) );
+
+ while( lNode )
+ {
+ if( lNode->GetName() == wxT( "patternDef" ) )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue1 );
+ FindNode( lNode,
+ wxT( "originalName" ) )->GetAttribute( wxT( "Name" ), &propValue2 );
+
+ if( ValidateName( propValue1 ) == aName
+ || ValidateName( propValue2 ) == aName )
+ {
+ result = lNode;
+ lNode = NULL;
+ }
+ }
+
+ if( lNode )
+ lNode = lNode->GetNext();
+ }
+
+ if( result == NULL )
+ {
+ lNode = FindNode( aNode, wxT( "patternDefExtended" ) ); // New file format
+
+ while( lNode )
+ {
+ if( lNode->GetName() == wxT( "patternDefExtended" ) )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue1 );
+
+ if( ValidateName( propValue1 ) == aName )
+ {
+ result = lNode;
+ lNode = NULL;
+ }
+ }
+
+ if( lNode )
+ lNode = lNode->GetNext();
+ }
+ }
+
+ return result;
+}
+
+
+XNODE* PCB_MODULE::FindPatternMultilayerSection( XNODE* aNode, wxString* aPatGraphRefName )
+{
+ XNODE* result, * pNode, * lNode;
+ wxString propValue, patName;
+
+ result = NULL;
+ pNode = aNode; // pattern;
+ lNode = aNode;
+
+ // calling from library conversion we need to find pattern
+ if( lNode->GetName() == wxT( "compDef" ) )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ patName = ValidateName( propValue );
+
+ if( FindNode( lNode, wxT( "attachedPattern" ) ) )
+ {
+ FindNode( FindNode( lNode, wxT( "attachedPattern" ) ),
+ wxT( "patternName" ) )->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+ patName = ValidateName( propValue );
+ }
+
+ lNode = FindModulePatternDefName( lNode->GetParent(), patName );
+ pNode = lNode; // pattern;
+ }
+
+ lNode = NULL;
+
+ if( pNode )
+ lNode = FindNode( pNode, wxT( "multiLayer" ) ); // Old file format
+
+ if( lNode )
+ {
+ *aPatGraphRefName = wxEmptyString; // default
+ result = lNode;
+ }
+ else
+ {
+ // New file format
+
+ if( *aPatGraphRefName == wxEmptyString ) // default
+ {
+ if( FindNode( aNode, wxT( "patternGraphicsNameRef" ) ) )
+ {
+ FindNode( aNode,
+ wxT( "patternGraphicsNameRef" ) )->GetAttribute( wxT( "Name" ),
+ aPatGraphRefName );
+ }
+ }
+
+ if( FindNode( aNode, wxT( "patternGraphicsDef" ) ) )
+ lNode = FindNode( aNode, wxT( "patternGraphicsDef" ) );
+ else
+ lNode = FindNode( pNode, wxT( "patternGraphicsDef" ) );
+
+ if( *aPatGraphRefName == wxEmptyString ) // no patern delection, the first is actual...
+ {
+ if( lNode )
+ {
+ result = FindNode( lNode, wxT( "multiLayer" ) );
+ lNode = NULL;
+ }
+ }
+
+ while( lNode ) // selected by name
+ {
+ if( lNode->GetName() == wxT( "patternGraphicsDef" ) )
+ {
+ FindNode( lNode,
+ wxT( "patternGraphicsNameDef" ) )->GetAttribute( wxT( "Name" ),
+ &propValue );
+
+ if( propValue == *aPatGraphRefName )
+ {
+ result = FindNode( lNode, wxT( "multiLayer" ) );
+ lNode = NULL;
+ }
+ else
+ lNode = lNode->GetNext();
+ }
+ else
+ lNode = lNode->GetNext();
+ }
+ }
+
+ return result;
+}
+
+
+void PCB_MODULE::DoLayerContentsObjects( XNODE* aNode,
+ PCB_MODULE* aPCBModule,
+ PCB_COMPONENTS_ARRAY* aList,
+ wxStatusBar* aStatusBar,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ PCB_ARC* arc;
+ PCB_POLYGON* polygon;
+ PCB_POLYGON *plane_layer = NULL;
+ PCB_COPPER_POUR* copperPour;
+ PCB_CUTOUT* cutout;
+ PCB_PLANE* plane;
+ VERTICES_ARRAY* plane_layer_polygon;
+ PCB_LINE* line;
+ PCB_TEXT* text;
+ XNODE* lNode, * tNode;
+ wxString propValue;
+ long long i;
+ int PCadLayer;
+ long num = 0;
+
+ i = 0;
+ // aStatusBar->SetStatusText( wxT( "Processing LAYER CONTENT OBJECTS " ) );
+ if( FindNode( aNode, wxT( "layerNumRef" ) ) )
+ FindNode( aNode, wxT( "layerNumRef" ) )->GetNodeContent().ToLong( &num );
+
+ PCadLayer = (int) num;
+
+ if( m_callbacks->GetLayerType( PCadLayer ) == LAYER_TYPE_PLANE )
+ {
+ plane_layer = new PCB_POLYGON( m_callbacks, m_board, PCadLayer );
+ plane_layer->AssignNet( m_callbacks->GetLayerNetNameRef( PCadLayer ) );
+ plane_layer->SetOutline( &m_boardOutline );
+ aList->Add( plane_layer );
+
+ // fill the polygon with the same contour as its outline is
+ //plane_layer->AddIsland( &m_boardOutline );
+ }
+
+ lNode = aNode->GetChildren();
+
+ while( lNode )
+ {
+ i++;
+ // aStatusBar->SetStatusText( wxString::Format( "Processing LAYER CONTENT OBJECTS :%lld",
+ // i ) );
+
+ if( lNode->GetName() == wxT( "line" ) )
+ {
+ line = new PCB_LINE( m_callbacks, m_board );
+ line->Parse( lNode, PCadLayer, aDefaultMeasurementUnit, aActualConversion );
+ aList->Add( line );
+ }
+
+ if( lNode->GetName() == wxT( "text" ) )
+ {
+ text = new PCB_TEXT( m_callbacks, m_board );
+ text->Parse( lNode, PCadLayer, aDefaultMeasurementUnit, aActualConversion );
+ aList->Add( text );
+ }
+
+ // added as Sergeys request 02/2008
+ if( lNode->GetName() == wxT( "attr" ) )
+ {
+ // assign fonts to Module Name,Value,Type,....s
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+
+ if( propValue == wxT( "RefDes" ) )
+ {
+ tNode = FindNode( lNode, wxT( "textStyleRef" ) );
+
+ if( tNode && aPCBModule )
+ {
+ // TODO: to understand and may be repair
+ // Alexander Lunev: originally in Delphi version of the project there was
+ // a strange access to pcbModule->m_name (it was global variable). This access
+ // is necessary when the function DoLayerContentsObjects() is called from
+ // function CreatePCBModule(). However it is not clear whether the access is
+ // required when the function DoLayerContentsObjects() is called from
+ // function ProcessXMLtoPCBLib().
+ SetFontProperty( tNode,
+ &aPCBModule->m_name,
+ aDefaultMeasurementUnit,
+ aActualConversion );
+ }
+ }
+ }
+
+ // added as Sergeys request 02/2008
+ if( lNode->GetName() == wxT( "arc" ) || lNode->GetName() == wxT( "triplePointArc" ) )
+ {
+ arc = new PCB_ARC( m_callbacks, m_board );
+ arc->Parse( lNode, PCadLayer, aDefaultMeasurementUnit, aActualConversion );
+ aList->Add( arc );
+ }
+
+ if( lNode->GetName() == wxT( "pcbPoly" ) )
+ {
+ if( m_callbacks->GetLayerType( PCadLayer ) == LAYER_TYPE_PLANE )
+ {
+ plane_layer_polygon = new VERTICES_ARRAY;
+ wxASSERT( plane_layer );
+ plane_layer->FormPolygon( lNode, plane_layer_polygon, aDefaultMeasurementUnit, aActualConversion );
+ plane_layer->m_cutouts.Add( plane_layer_polygon );
+ }
+ else
+ {
+ polygon = new PCB_POLYGON( m_callbacks, m_board, PCadLayer );
+ if( polygon->Parse( lNode,
+ aDefaultMeasurementUnit,
+ aActualConversion,
+ aStatusBar ) )
+ aList->Add( polygon );
+ else
+ delete polygon;
+ }
+ }
+
+ if( lNode->GetName() == wxT( "copperPour95" ) )
+ {
+ copperPour = new PCB_COPPER_POUR( m_callbacks, m_board, PCadLayer );
+
+ if( copperPour->Parse( lNode, aDefaultMeasurementUnit, aActualConversion,
+ aStatusBar ) )
+ aList->Add( copperPour );
+ else
+ delete copperPour;
+ }
+
+ if( lNode->GetName() == wxT( "polyCutOut" ) )
+ {
+ cutout = new PCB_CUTOUT( m_callbacks, m_board, PCadLayer );
+
+ if( cutout->Parse( lNode, aDefaultMeasurementUnit, aActualConversion ) )
+ aList->Add( cutout );
+ else
+ delete cutout;
+ }
+
+ if( lNode->GetName() == wxT( "planeObj" ) )
+ {
+ plane = new PCB_PLANE( m_callbacks, m_board, PCadLayer );
+
+ if( plane->Parse( lNode, aDefaultMeasurementUnit, aActualConversion,
+ aStatusBar ) )
+ aList->Add( plane );
+ else
+ delete plane;
+ }
+
+ lNode = lNode->GetNext();
+ }
+}
+
+
+void PCB_MODULE::SetPadName( wxString aPin, wxString aName )
+{
+ int i;
+ long num;
+
+ aPin.ToLong( &num );
+
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'P' ) )
+ if( ( (PCB_PAD*) m_moduleObjects[i] )->m_number == num )
+ ( (PCB_PAD*) m_moduleObjects[i] )->m_name.text = aName;
+
+
+ }
+}
+
+
+void PCB_MODULE::Parse( XNODE* aNode, wxStatusBar* aStatusBar,
+ wxString aDefaultMeasurementUnit, wxString aActualConversion )
+{
+ XNODE* lNode, * tNode, * mNode;
+ PCB_PAD* pad;
+ PCB_VIA* via;
+ wxString propValue, str;
+
+ FindNode( aNode, wxT( "originalName" ) )->GetAttribute( wxT( "Name" ),
+ &propValue );
+ propValue.Trim( false );
+ m_name.text = propValue;
+
+ // aStatusBar->SetStatusText( wxT( "Creating Component : " ) + m_name.text );
+ lNode = aNode;
+ lNode = FindPatternMultilayerSection( lNode, &m_patGraphRefName );
+
+ if( lNode )
+ {
+ tNode = lNode;
+ tNode = tNode->GetChildren();
+
+ while( tNode )
+ {
+ if( tNode->GetName() == wxT( "pad" ) )
+ {
+ pad = new PCB_PAD( m_callbacks, m_board );
+ pad->Parse( tNode, aDefaultMeasurementUnit, aActualConversion );
+ m_moduleObjects.Add( pad );
+ }
+
+ if( tNode->GetName() == wxT( "via" ) )
+ {
+ via = new PCB_VIA( m_callbacks, m_board );
+ via->Parse( tNode, aDefaultMeasurementUnit, aActualConversion );
+ m_moduleObjects.Add( via );
+ }
+
+ tNode = tNode->GetNext();
+ }
+ }
+
+ if( lNode )
+ lNode = lNode->GetParent();
+
+ if( lNode )
+ lNode = FindNode( lNode, wxT( "layerContents" ) );
+
+ while( lNode )
+ {
+ if( lNode->GetName() == wxT( "layerContents" ) )
+ DoLayerContentsObjects( lNode, this, &m_moduleObjects, aStatusBar,
+ aDefaultMeasurementUnit, aActualConversion );
+
+ lNode = lNode->GetNext();
+ }
+
+ // map pins
+ lNode = FindPinMap( aNode );
+
+ if( lNode )
+ {
+ mNode = lNode->GetChildren();
+
+ while( mNode )
+ {
+ if( mNode->GetName() == wxT( "padNum" ) )
+ {
+ str = mNode->GetNodeContent();
+ mNode = mNode->GetNext();
+
+ if( !mNode )
+ break;
+
+ mNode->GetAttribute( wxT( "Name" ), &propValue );
+ SetPadName( str, propValue );
+ mNode = mNode->GetNext();
+ }
+ else
+ {
+ mNode = mNode->GetNext();
+
+ if( !mNode )
+ break;
+
+ mNode = mNode->GetNext();
+ }
+ }
+ }
+}
+
+
+wxString PCB_MODULE::ModuleLayer( int aMirror )
+{
+ wxString result;
+
+ // ///NOT ! {IntToStr(KiCadLayer)} NOT !
+ // / MODULES ARE HARD PLACED ON COMPONENT OR COPPER LAYER.
+ // / IsFLIPPED--> MIRROR attribute is decision Point!!!
+
+ if( aMirror == 0 )
+ result = wxT( "15" ); // Components side
+ else
+ result = wxT( "0" ); // Copper side
+
+ return result;
+}
+
+
+void PCB_MODULE::AddToBoard()
+{
+ int i;
+ int r;
+
+ // transform text positions
+ CorrectTextPosition( &m_name );
+ RotatePoint( &m_name.correctedPositionX, &m_name.correctedPositionY,
+ (double) -m_rotation );
+
+ CorrectTextPosition( &m_value );
+ RotatePoint( &m_value.correctedPositionX, &m_value.correctedPositionY,
+ (double) -m_rotation );
+
+ MODULE* module = new MODULE( m_board );
+ m_board->Add( module, ADD_APPEND );
+
+ module->SetPosition( wxPoint( m_positionX, m_positionY ) );
+ module->SetLayer( m_mirror ? B_Cu : F_Cu );
+ module->SetOrientation( m_rotation );
+ module->SetTimeStamp( 0 );
+ module->SetLastEditTime( 0 );
+
+ module->SetFPID( FPID( m_compRef ) );
+
+ module->SetAttributes( MOD_DEFAULT | MOD_CMS );
+
+ // reference text
+ TEXTE_MODULE* ref_text = &module->Reference();
+
+ ref_text->SetText( m_name.text );
+ ref_text->SetType( TEXTE_MODULE::TEXT_is_REFERENCE );
+
+ ref_text->SetPos0( wxPoint( m_name.correctedPositionX, m_name.correctedPositionY ) );
+ ref_text->SetSize( wxSize( KiROUND( m_name.textHeight / 2 ),
+ KiROUND( m_name.textHeight / 1.5 ) ) );
+
+ r = m_name.textRotation - m_rotation;
+ ref_text->SetOrientation( r );
+
+ ref_text->SetThickness( m_name.textstrokeWidth );
+
+ ref_text->SetMirrored( m_name.mirror );
+ ref_text->SetVisible( m_name.textIsVisible );
+
+ ref_text->SetLayer( m_KiCadLayer );
+
+ // Calculate the actual position.
+ ref_text->SetDrawCoord();
+
+ // value text
+ TEXTE_MODULE* val_text = &module->Value();
+
+ val_text->SetText( m_value.text );
+ val_text->SetType( TEXTE_MODULE::TEXT_is_VALUE );
+
+ val_text->SetPos0( wxPoint( m_value.correctedPositionX, m_value.correctedPositionY ) );
+ val_text->SetSize( wxSize( KiROUND( m_value.textHeight / 2 ),
+ KiROUND( m_value.textHeight / 1.5 ) ) );
+
+ r = m_value.textRotation - m_rotation;
+ val_text->SetOrientation( r );
+
+ val_text->SetThickness( m_value.textstrokeWidth );
+
+ val_text->SetMirrored( m_value.mirror );
+ val_text->SetVisible( m_value.textIsVisible );
+
+ val_text->SetLayer( m_KiCadLayer );
+
+ // Calculate the actual position.
+ val_text->SetDrawCoord();
+
+ // TEXTS
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'T' ) )
+ {
+ ( (PCB_TEXT*) m_moduleObjects[i] )->m_tag = i + 2;
+ m_moduleObjects[i]->AddToModule( module );
+ }
+ }
+
+ // MODULE LINES
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'L' ) )
+ m_moduleObjects[i]->AddToModule( module );
+ }
+
+ // MODULE Arcs
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'A' ) )
+ m_moduleObjects[i]->AddToModule( module );
+ }
+
+ // PADS
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'P' ) )
+ ( (PCB_PAD*) m_moduleObjects[i] )->AddToModule( module, m_rotation, false );
+ }
+
+ // VIAS
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'V' ) )
+ ( (PCB_VIA*) m_moduleObjects[i] )->AddToModule( module, m_rotation, false );
+ }
+
+ module->CalculateBoundingBox();
+}
+
+
+void PCB_MODULE::Flip()
+{
+ int i;
+
+ if( m_mirror == 1 )
+ {
+ // Flipped
+ m_KiCadLayer = FlipLayer( m_KiCadLayer );
+ m_rotation = -m_rotation;
+
+ for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ )
+ {
+ if( m_moduleObjects[i]->m_objType == wxT( 'L' ) || // lines
+ m_moduleObjects[i]->m_objType == wxT( 'A' ) || // arcs
+ m_moduleObjects[i]->m_objType == wxT( 'P' ) || // pads
+ m_moduleObjects[i]->m_objType == wxT( 'V' ) ) // vias
+ {
+ m_moduleObjects[i]->Flip();
+ }
+ }
+ }
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_module.h b/pcbnew/pcad2kicadpcb_plugin/pcb_module.h
new file mode 100644
index 0000000..27d8d3d
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_module.h
@@ -0,0 +1,75 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_module.h
+ */
+
+#ifndef PCB_MODULE_H_
+#define PCB_MODULE_H_
+
+#include <wx/wx.h>
+
+#include <pcad2kicad_common.h>
+#include <pcb_component.h>
+
+namespace PCAD2KICAD {
+
+class PCB_MODULE : public PCB_COMPONENT
+{
+public:
+ TTEXTVALUE m_value; // has reference (Name from parent) and value
+ PCB_COMPONENTS_ARRAY m_moduleObjects; // set of objects like PCB_LINE, PCB_PAD, PCB_VIA,....
+ int m_mirror;
+ VERTICES_ARRAY m_boardOutline;
+
+ PCB_MODULE( PCB_CALLBACKS* aCallbacks, BOARD* aBoard );
+ ~PCB_MODULE();
+
+ XNODE* FindModulePatternDefName( XNODE* aNode, wxString aName );
+
+ void DoLayerContentsObjects( XNODE* aNode,
+ PCB_MODULE* aPCBModule,
+ PCB_COMPONENTS_ARRAY* aList,
+ wxStatusBar* aStatusBar,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion );
+
+ void SetPadName( wxString aPin, wxString aName );
+
+ virtual void Parse( XNODE* aNode, wxStatusBar* aStatusBar,
+ wxString aDefaultMeasurementUnit, wxString aActualConversion );
+
+ virtual void Flip();
+ void AddToBoard();
+
+private:
+ XNODE* FindPatternMultilayerSection( XNODE* aNode, wxString* aPatGraphRefName );
+ wxString ModuleLayer( int aMirror );
+};
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_MODULE_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_net.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_net.cpp
new file mode 100644
index 0000000..c1dc5ee
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_net.cpp
@@ -0,0 +1,104 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_net.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <pcb_net.h>
+
+namespace PCAD2KICAD {
+
+PCB_NET_NODE::PCB_NET_NODE()
+{
+ m_compRef = wxEmptyString;
+ m_pinRef = wxEmptyString;
+}
+
+
+PCB_NET_NODE::~PCB_NET_NODE()
+{
+}
+
+
+PCB_NET::PCB_NET( int aNetCode ) : m_netCode( aNetCode )
+{
+ m_name = wxEmptyString;
+}
+
+
+PCB_NET::~PCB_NET()
+{
+ int i;
+
+ for( i = 0; i < (int) m_netNodes.GetCount(); i++ )
+ {
+ delete m_netNodes[i];
+ }
+}
+
+
+void PCB_NET::Parse( XNODE* aNode )
+{
+ wxString propValue, s1, s2;
+ PCB_NET_NODE* netNode;
+ XNODE* lNode;
+
+ aNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+ m_name = propValue;
+
+ lNode = FindNode( aNode, wxT( "node" ) );
+
+ while( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &s2 );
+ s2.Trim( false );
+ s1 = wxEmptyString;
+
+ while( s2.Len() > 0 && s2[0] != wxT( ' ' ) )
+ {
+ s1 = s1 + s2[0];
+ s2 = s2.Mid( 1 );
+ }
+
+ netNode = new PCB_NET_NODE;
+ s1.Trim( false );
+ s1.Trim( true );
+ netNode->m_compRef = s1;
+
+ s2.Trim( false );
+ s2.Trim( true );
+ netNode->m_pinRef = s2;
+ m_netNodes.Add( netNode );
+ lNode = lNode->GetNext();
+ }
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_net.h b/pcbnew/pcad2kicadpcb_plugin/pcb_net.h
new file mode 100644
index 0000000..867271d
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_net.h
@@ -0,0 +1,68 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_net.h
+ */
+
+#ifndef PCB_NET_H_
+#define PCB_NET_H_
+
+#include <wx/wx.h>
+
+#include <pcad2kicad_common.h>
+
+namespace PCAD2KICAD {
+
+class PCB_NET_NODE : public wxObject
+{
+public:
+ wxString m_compRef;
+ wxString m_pinRef;
+
+ PCB_NET_NODE();
+ ~PCB_NET_NODE();
+};
+
+WX_DEFINE_ARRAY( PCB_NET_NODE*, PCB_NET_NODES_ARRAY );
+
+class PCB_NET : public wxObject
+{
+public:
+ wxString m_name;
+ int m_netCode;
+ PCB_NET_NODES_ARRAY m_netNodes;
+
+ PCB_NET( int aNetCode );
+ ~PCB_NET();
+
+ void Parse( XNODE* aNode );
+};
+
+WX_DEFINE_ARRAY( PCB_NET*, PCB_NETS_ARRAY );
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_NET_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp
new file mode 100644
index 0000000..f1e9b91
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp
@@ -0,0 +1,363 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_pad.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+#include <trigo.h>
+
+#include <pcb_pad.h>
+
+namespace PCAD2KICAD {
+
+PCB_PAD::PCB_PAD( PCB_CALLBACKS* aCallbacks, BOARD* aBoard ) : PCB_COMPONENT( aCallbacks, aBoard )
+{
+ m_objType = wxT( 'P' );
+ m_number = 0;
+ m_hole = 0;
+ m_isHolePlated = true;
+ m_defaultPinDes = wxEmptyString;
+}
+
+
+PCB_PAD::~PCB_PAD()
+{
+ int i;
+
+ for( i = 0; i < (int) m_shapes.GetCount(); i++ )
+ {
+ delete m_shapes[i];
+ }
+}
+
+
+void PCB_PAD::Parse( XNODE* aNode, wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ XNODE* lNode, *cNode;
+ long num;
+ wxString propValue, str, emsg;
+ PCB_PAD_SHAPE* padShape;
+
+ m_rotation = 0;
+ lNode = FindNode( aNode, wxT( "padNum" ) );
+
+ if( lNode )
+ {
+ lNode->GetNodeContent().ToLong( &num );
+ m_number = (int) num;
+ }
+
+ lNode = FindNode( aNode, wxT( "padStyleRef" ) );
+
+ if( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ m_name.text = propValue;
+ }
+
+ lNode = FindNode( aNode, wxT( "pt" ) );
+
+ if( lNode )
+ SetPosition( lNode->GetNodeContent(), aDefaultMeasurementUnit,
+ &m_positionX, &m_positionY, aActualConversion );
+
+ lNode = FindNode( aNode, wxT( "rotation" ) );
+
+ if( lNode )
+ {
+ str = lNode->GetNodeContent();
+ str.Trim( false );
+ m_rotation = StrToInt1Units( str );
+ }
+
+ lNode = FindNode( aNode, wxT( "netNameRef" ) );
+
+ if( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+ m_net = propValue;
+ m_netCode = GetNetCode( m_net );
+ }
+
+ lNode = FindNode( aNode, wxT( "defaultPinDes" ) );
+
+ if( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ //propValue.Trim( false );
+ m_defaultPinDes = propValue;
+ }
+
+ lNode = aNode;
+
+ while( lNode && lNode->GetName() != wxT( "www.lura.sk" ) )
+ lNode = lNode->GetParent();
+
+ lNode = FindNode( lNode, wxT( "library" ) );
+ if ( !lNode )
+ THROW_IO_ERROR( wxT( "Unable to find library section" ) );
+
+ lNode = FindNode( lNode, wxT( "padStyleDef" ) );
+
+ while( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+
+ if( propValue.IsSameAs( m_name.text, false) )
+ break;
+
+ lNode = lNode->GetNext();
+ }
+
+ if ( !lNode )
+ THROW_IO_ERROR( wxString::Format( wxT( "Unable to find padStyleDef " ) + m_name.text ) );
+
+ cNode = FindNode( lNode, wxT( "holeDiam" ) );
+
+ if( cNode )
+ SetWidth( cNode->GetNodeContent(), aDefaultMeasurementUnit, &m_hole, aActualConversion );
+
+ if( FindNodeGetContent( lNode, wxT( "isHolePlated" ) ) == wxT( "False" ) )
+ m_isHolePlated = false;
+
+ cNode = FindNode( lNode, wxT( "padShape" ) );
+
+ while( cNode )
+ {
+ if( cNode->GetName() == wxT( "padShape" ) )
+ {
+ // we support only Pads on specific layers......
+ // we do not support pads on "Plane", "NonSignal" , "Signal" ... layerr
+ if( FindNode( cNode, wxT( "layerNumRef" ) ) )
+ {
+ padShape = new PCB_PAD_SHAPE( m_callbacks, m_board );
+ padShape->Parse( cNode, aDefaultMeasurementUnit, aActualConversion );
+ m_shapes.Add( padShape );
+ }
+ }
+
+ cNode = cNode->GetNext();
+ }
+}
+
+
+void PCB_PAD::Flip()
+{
+ int i;
+
+ PCB_COMPONENT::Flip();
+
+ if( m_objType == wxT( 'P' ) )
+ m_rotation = -m_rotation;
+
+ for( i = 0; i < (int)m_shapes.GetCount(); i++ )
+ m_shapes[i]->m_KiCadLayer = FlipLayer( m_shapes[i]->m_KiCadLayer );
+}
+
+
+void PCB_PAD::AddToModule( MODULE* aModule, int aRotation, bool aEncapsulatedPad )
+{
+ PCB_PAD_SHAPE* padShape;
+ wxString padShapeName = wxT( "Ellipse" );
+ PAD_ATTR_T padType;
+ int i;
+ int width = 0;
+ int height = 0;
+
+ D_PAD* pad = new D_PAD( aModule );
+
+ if( !m_isHolePlated && m_hole )
+ {
+ // mechanical hole
+ pad->SetShape( PAD_SHAPE_CIRCLE );
+ pad->SetAttribute( PAD_ATTRIB_HOLE_NOT_PLATED );
+
+ pad->SetDrillShape( PAD_DRILL_SHAPE_CIRCLE );
+ pad->SetDrillSize( wxSize( m_hole, m_hole ) );
+ pad->SetSize( wxSize( m_hole, m_hole ) );
+
+ pad->SetLayerSet( LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask ) );
+ }
+ else
+ {
+ ( m_hole ) ? padType = PAD_ATTRIB_STANDARD : padType = PAD_ATTRIB_SMD;
+
+ // form layer mask
+ for( i = 0; i < (int) m_shapes.GetCount(); i++ )
+ {
+ padShape = m_shapes[i];
+
+ if( padShape->m_width > 0 && padShape->m_height > 0 )
+ {
+ if( padShape->m_KiCadLayer == F_Cu ||
+ padShape->m_KiCadLayer == B_Cu )
+ {
+ padShapeName = padShape->m_shape;
+ width = padShape->m_width;
+ height = padShape->m_height;
+
+ // assume this is SMD pad
+ if( padShape->m_KiCadLayer == F_Cu )
+ pad->SetLayerSet( LSET( 3, F_Cu, F_Paste, F_Mask ) );
+ else
+ pad->SetLayerSet( LSET( 3, B_Cu, B_Paste, B_Mask ) );
+ break;
+ }
+ }
+ }
+
+ if( width == 0 || height == 0 )
+ {
+ delete pad;
+ return;
+ }
+
+ if( padType == PAD_ATTRIB_STANDARD )
+ // actually this is a thru-hole pad
+ pad->SetLayerSet( LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask ) );
+
+ pad->SetPadName( m_name.text );
+
+ if( padShapeName == wxT( "Oval" )
+ || padShapeName == wxT( "Ellipse" )
+ || padShapeName == wxT( "MtHole" ) )
+ {
+ if( width != height )
+ pad->SetShape( PAD_SHAPE_OVAL );
+ else
+ pad->SetShape( PAD_SHAPE_CIRCLE );
+ }
+ else if( padShapeName == wxT( "Rect" )
+ || padShapeName == wxT( "RndRect" ) )
+ pad->SetShape( PAD_SHAPE_RECT );
+ else if( padShapeName == wxT( "Polygon" ) )
+ pad->SetShape( PAD_SHAPE_RECT ); // approximation
+
+ pad->SetSize( wxSize( width, height ) );
+ pad->SetDelta( wxSize( 0, 0 ) );
+ pad->SetOrientation( m_rotation + aRotation );
+
+ pad->SetDrillShape( PAD_DRILL_SHAPE_CIRCLE );
+ pad->SetOffset( wxPoint( 0, 0 ) );
+ pad->SetDrillSize( wxSize( m_hole, m_hole ) );
+
+ pad->SetAttribute( padType );
+
+ // Set the proper net code
+ NETINFO_ITEM* netinfo = m_board->FindNet( m_net );
+ if( netinfo == NULL ) // I believe this should not happen, but just in case
+ {
+ // It is a new net
+ netinfo = new NETINFO_ITEM( m_board, m_net );
+ m_board->AppendNet( netinfo );
+ }
+
+ pad->SetNetCode( netinfo->GetNet() );
+ }
+
+ if( !aEncapsulatedPad )
+ {
+ // pad's "Position" is not relative to the module's,
+ // whereas Pos0 is relative to the module's but is the unrotated coordinate.
+ wxPoint padpos( m_positionX, m_positionY );
+ pad->SetPos0( padpos );
+ RotatePoint( &padpos, aModule->GetOrientation() );
+ pad->SetPosition( padpos + aModule->GetPosition() );
+ }
+
+ aModule->Pads().PushBack( pad );
+}
+
+
+void PCB_PAD::AddToBoard()
+{
+ PCB_PAD_SHAPE* padShape;
+ int i;
+ int width = 0;
+ int height = 0;
+
+ if( m_objType == wxT( 'V' ) ) // via
+ {
+ // choose one of the shapes
+ for( i = 0; i < (int) m_shapes.GetCount(); i++ )
+ {
+ padShape = m_shapes[i];
+
+ if( padShape->m_width > 0 && padShape->m_height > 0 )
+ {
+ if( padShape->m_KiCadLayer == F_Cu
+ || padShape->m_KiCadLayer == B_Cu )
+ {
+ width = padShape->m_width;
+ height = padShape->m_height;
+
+ break;
+ }
+ }
+ }
+
+ if( width == 0 || height == 0 )
+ return;
+
+ if( IsCopperLayer( m_KiCadLayer ) )
+ {
+ VIA* via = new VIA( m_board );
+ m_board->m_Track.Append( via );
+
+ via->SetTimeStamp( 0 );
+
+ via->SetPosition( wxPoint( m_positionX, m_positionY ) );
+ via->SetEnd( wxPoint( m_positionX, m_positionY ) );
+
+ via->SetWidth( height );
+ via->SetViaType( VIA_THROUGH );
+ via->SetLayerPair( F_Cu, B_Cu );
+ via->SetDrill( m_hole );
+
+ via->SetLayer( m_KiCadLayer );
+ via->SetNetCode( m_netCode );
+ }
+ }
+ else // pad
+ {
+ MODULE* module = new MODULE( m_board );
+ m_board->Add( module, ADD_APPEND );
+
+ m_name.text = m_defaultPinDes;
+
+ module->SetPosition( wxPoint( m_positionX, m_positionY ) );
+ AddToModule( module, 0, true );
+
+ }
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.h b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.h
new file mode 100644
index 0000000..fa18bd5
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.h
@@ -0,0 +1,64 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_pad.h
+ */
+
+#ifndef PCB_PAD_H_
+#define PCB_PAD_H_
+
+#include <wx/wx.h>
+
+#include <pcb_component.h>
+#include <pcb_pad_shape.h>
+
+namespace PCAD2KICAD {
+
+class PCB_PAD : public PCB_COMPONENT
+{
+public:
+ int m_number;
+ int m_hole;
+ bool m_isHolePlated;
+ PCB_PAD_SHAPES_ARRAY m_shapes;
+
+ PCB_PAD( PCB_CALLBACKS* aCallbacks, BOARD* aBoard );
+ ~PCB_PAD();
+
+ virtual void Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion );
+ virtual void Flip();
+ void AddToModule( MODULE* aModule, int aRotation, bool aEncapsulatedPad );
+ void AddToBoard();
+
+private:
+ wxString m_defaultPinDes;
+};
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_PAD_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_pad_shape.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_pad_shape.cpp
new file mode 100644
index 0000000..699f51f
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_pad_shape.cpp
@@ -0,0 +1,142 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_pad_shape.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+
+#include <pcb_pad_shape.h>
+
+namespace PCAD2KICAD {
+
+PCB_PAD_SHAPE::PCB_PAD_SHAPE( PCB_CALLBACKS* aCallbacks,
+ BOARD* aBoard ) : PCB_COMPONENT( aCallbacks, aBoard )
+{
+ m_shape = wxEmptyString;
+ m_width = 0;
+ m_height = 0;
+}
+
+
+PCB_PAD_SHAPE::~PCB_PAD_SHAPE()
+{
+}
+
+
+void PCB_PAD_SHAPE::Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ wxString str, s;
+ long num;
+ int minX, maxX, minY, maxY, x, y;
+ XNODE* lNode;
+
+ lNode = FindNode( aNode, wxT( "padShapeType" ) );
+
+ if( lNode )
+ {
+ str = lNode->GetNodeContent();
+ str.Trim( false );
+ m_shape = str;
+ }
+
+ lNode = FindNode( aNode, wxT( "layerNumRef" ) );
+
+ if( lNode )
+ {
+ lNode->GetNodeContent().ToLong( &num );
+ m_PCadLayer = (int) num;
+ }
+
+ m_KiCadLayer = GetKiCadLayer();
+
+ if( m_shape == wxT( "Oval" )
+ || m_shape == wxT( "Rect" )
+ || m_shape == wxT( "Ellipse" )
+ || m_shape == wxT( "MtHole" )
+ || m_shape == wxT( "RndRect" ) )
+ {
+ lNode = FindNode( aNode, wxT( "shapeWidth" ) );
+
+ if( lNode )
+ SetWidth( lNode->GetNodeContent(), aDefaultMeasurementUnit, &m_width,
+ aActualConversion );
+
+ lNode = FindNode( aNode, wxT( "shapeHeight" ) );
+
+ if( lNode )
+ SetWidth(
+ lNode->GetNodeContent(), aDefaultMeasurementUnit, &m_height, aActualConversion );
+ }
+ else if( m_shape == wxT( "Polygon" ) )
+ {
+ // aproximation to simplier pad shape .....
+ lNode = FindNode( aNode, wxT( "shapeOutline" ) );
+
+ if( lNode )
+ lNode = FindNode( lNode, wxT( "pt" ) );
+
+ minX = 0;
+ maxX = 0;
+ minY = 0;
+ maxY = 0;
+
+ while( lNode )
+ {
+ s = lNode->GetNodeContent();
+ SetPosition( s, aDefaultMeasurementUnit, &x, &y, aActualConversion );
+
+ if( minX > x )
+ minX = x;
+
+ if( maxX < x )
+ maxX = x;
+
+ if( minY > y )
+ minY = y;
+
+ if( maxY < y )
+ maxY = y;
+
+ lNode = lNode->GetNext();
+ }
+
+ m_width = maxX - minX;
+ m_height = maxY - minY;
+ }
+}
+
+
+void PCB_PAD_SHAPE::AddToBoard()
+{
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_pad_shape.h b/pcbnew/pcad2kicadpcb_plugin/pcb_pad_shape.h
new file mode 100644
index 0000000..662fb03
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_pad_shape.h
@@ -0,0 +1,61 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_pad_shape.h
+ */
+
+#ifndef PCB_PAD_SHAPE_H_
+#define PCB_PAD_SHAPE_H_
+
+#include <wx/wx.h>
+#include <wx/dynarray.h>
+
+#include <pcb_component.h>
+
+namespace PCAD2KICAD {
+
+class PCB_PAD_SHAPE : public PCB_COMPONENT
+{
+public:
+ wxString m_shape;
+ int m_width;
+ int m_height;
+
+ PCB_PAD_SHAPE( PCB_CALLBACKS* aCallbacks, BOARD* aBoard );
+ ~PCB_PAD_SHAPE();
+
+ virtual void Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion );
+
+ void AddToBoard();
+};
+
+WX_DEFINE_ARRAY( PCB_PAD_SHAPE*, PCB_PAD_SHAPES_ARRAY );
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_PAD_SHAPE_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_plane.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_plane.cpp
new file mode 100644
index 0000000..be89e50
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_plane.cpp
@@ -0,0 +1,95 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_plane.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+
+#include <pcb_plane.h>
+
+namespace PCAD2KICAD {
+
+PCB_PLANE::PCB_PLANE( PCB_CALLBACKS* aCallbacks,
+ BOARD* aBoard,
+ int aPCadLayer ) :
+ PCB_POLYGON( aCallbacks, aBoard, aPCadLayer )
+{
+ m_priority = 1;
+}
+
+
+PCB_PLANE::~PCB_PLANE()
+{
+}
+
+
+bool PCB_PLANE::Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion,
+ wxStatusBar* aStatusBar )
+{
+ XNODE* lNode;
+ wxString pourType, str, propValue;
+
+ // aStatusBar->SetStatusText( aStatusBar->GetStatusText() + wxT( " Plane..." ) );
+
+ lNode = FindNode( aNode, wxT( "netNameRef" ) );
+
+ if( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+ m_net = propValue;
+ m_netCode = GetNetCode( m_net );
+ }
+
+ if( FindNode( aNode, wxT( "width" ) ) )
+ SetWidth( FindNode( aNode, wxT( "width" ) )->GetNodeContent(),
+ aDefaultMeasurementUnit, &m_width, aActualConversion );
+
+ lNode = FindNode( aNode, wxT( "pcbPoly" ) );
+
+ if( lNode )
+ {
+ // retrieve plane outline
+ FormPolygon( lNode, &m_outline, aDefaultMeasurementUnit, aActualConversion );
+
+ m_positionX = m_outline[0]->x;
+ m_positionY = m_outline[0]->y;
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_plane.h b/pcbnew/pcad2kicadpcb_plugin/pcb_plane.h
new file mode 100644
index 0000000..6ace28b
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_plane.h
@@ -0,0 +1,53 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_plane.h
+ */
+
+#ifndef PCB_PLANE_H_
+#define PCB_PLANE_H_
+
+#include <wx/wx.h>
+
+#include <pcb_polygon.h>
+
+namespace PCAD2KICAD {
+
+class PCB_PLANE : public PCB_POLYGON
+{
+public:
+
+ PCB_PLANE( PCB_CALLBACKS* aCallbacks, BOARD* aBoard, int aPCadLayer );
+ ~PCB_PLANE();
+
+ virtual bool Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion,
+ wxStatusBar* aStatusBar );
+};
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_PLANE_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp
new file mode 100644
index 0000000..b3b4ec5
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp
@@ -0,0 +1,253 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_polygon.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+
+#include <pcb_polygon.h>
+
+namespace PCAD2KICAD {
+
+PCB_POLYGON::PCB_POLYGON( PCB_CALLBACKS* aCallbacks, BOARD* aBoard, int aPCadLayer ) :
+ PCB_COMPONENT( aCallbacks, aBoard )
+{
+ m_width = 0;
+ m_priority = 0;
+ m_objType = wxT( 'Z' );
+ m_PCadLayer = aPCadLayer;
+ m_KiCadLayer = GetKiCadLayer();
+ m_timestamp = GetNewTimestamp();
+ m_filled = true;
+}
+
+
+PCB_POLYGON::~PCB_POLYGON()
+{
+ int i, island;
+
+ for( i = 0; i < (int) m_outline.GetCount(); i++ )
+ {
+ delete m_outline[i];
+ }
+
+ for( island = 0; island < (int) m_cutouts.GetCount(); island++ )
+ {
+ for( i = 0; i < (int) m_cutouts[island]->GetCount(); i++ )
+ {
+ delete (*m_cutouts[island])[i];
+ }
+
+ delete m_cutouts[island];
+ }
+
+ for( island = 0; island < (int) m_islands.GetCount(); island++ )
+ {
+ for( i = 0; i < (int) m_islands[island]->GetCount(); i++ )
+ {
+ delete (*m_islands[island])[i];
+ }
+
+ delete m_islands[island];
+ }
+}
+
+void PCB_POLYGON::AssignNet( wxString aNetName )
+{
+ m_net = aNetName;
+ m_netCode = GetNetCode( m_net );
+}
+
+void PCB_POLYGON::SetOutline( VERTICES_ARRAY* aOutline )
+{
+ int i;
+
+ m_outline.Empty();
+
+ for( i = 0; i < (int) aOutline->GetCount(); i++ )
+ m_outline.Add( new wxRealPoint( (*aOutline)[i]->x, (*aOutline)[i]->y ) );
+
+ if( m_outline.Count() > 0 )
+ {
+ m_positionX = m_outline[0]->x;
+ m_positionY = m_outline[0]->y;
+ }
+}
+
+void PCB_POLYGON::FormPolygon( XNODE* aNode, VERTICES_ARRAY* aPolygon,
+ wxString aDefaultMeasurementUnit, wxString aActualConversion )
+{
+ XNODE* lNode;
+ double x, y;
+
+ lNode = FindNode( aNode, wxT( "pt" ) );
+
+ while( lNode )
+ {
+ if( lNode->GetName() == wxT( "pt" ) )
+ {
+ SetDoublePrecisionPosition(
+ lNode->GetNodeContent(), aDefaultMeasurementUnit, &x, &y, aActualConversion );
+ aPolygon->Add( new wxRealPoint( x, y ) );
+ }
+
+ lNode = lNode->GetNext();
+ }
+}
+
+
+bool PCB_POLYGON::Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion,
+ wxStatusBar* aStatusBar )
+{
+ XNODE* lNode;
+ wxString propValue;
+
+ // aStatusBar->SetStatusText( aStatusBar->GetStatusText() + wxT( " Polygon..." ) );
+
+ lNode = FindNode( aNode, wxT( "netNameRef" ) );
+
+ if( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+ m_net = propValue;
+ m_netCode = GetNetCode( m_net );
+ }
+
+ // retrieve polygon outline
+ FormPolygon( aNode, &m_outline, aDefaultMeasurementUnit, aActualConversion );
+
+ m_positionX = m_outline[0]->x;
+ m_positionY = m_outline[0]->y;
+
+ // fill the polygon with the same contour as its outline is
+ m_islands.Add( new VERTICES_ARRAY );
+ FormPolygon( aNode, m_islands[0], aDefaultMeasurementUnit, aActualConversion );
+
+ return true;
+}
+
+
+void PCB_POLYGON::AddToModule( MODULE* aModule )
+{
+}
+
+
+void PCB_POLYGON::AddToBoard()
+{
+ int i = 0;
+
+ if( m_outline.GetCount() > 0 )
+ {
+ ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board );
+ m_board->Add( zone, ADD_APPEND );
+
+ zone->SetTimeStamp( m_timestamp );
+ zone->SetLayer( m_KiCadLayer );
+ zone->SetNetCode( m_netCode );
+
+ // add outline
+ int outline_hatch = CPolyLine::DIAGONAL_EDGE;
+
+ zone->Outline()->Start( m_KiCadLayer, KiROUND( m_outline[i]->x ),
+ KiROUND( m_outline[i]->y ), outline_hatch );
+
+ for( i = 1; i < (int) m_outline.GetCount(); i++ )
+ {
+ zone->AppendCorner( wxPoint( KiROUND( m_outline[i]->x ),
+ KiROUND( m_outline[i]->y ) ) );
+ }
+
+ zone->Outline()->CloseLastContour();
+
+ zone->SetZoneClearance( m_width );
+
+ zone->SetPriority( m_priority );
+
+ zone->Outline()->SetHatch( outline_hatch,
+ Mils2iu( zone->Outline()->GetDefaultHatchPitchMils() ),
+ true );
+
+ if ( m_objType == wxT( 'K' ) )
+ {
+ zone->SetIsKeepout( true );
+ zone->SetDoNotAllowTracks( true );
+ zone->SetDoNotAllowVias( true );
+ zone->SetDoNotAllowCopperPour( true );
+ }
+ else if( m_objType == wxT( 'C' ) )
+ {
+ // convert cutouts to keepouts because standalone cutouts are not supported in KiCad
+ zone->SetIsKeepout( true );
+ zone->SetDoNotAllowCopperPour( true );
+ }
+
+ //if( m_filled )
+ // cvpcb is not linked
+ // zone->BuildFilledPolysListData( m_board );
+ }
+}
+
+
+void PCB_POLYGON::SetPosOffset( int aX_offs, int aY_offs )
+{
+ int i, island;
+
+ PCB_COMPONENT::SetPosOffset( aX_offs, aY_offs );
+
+ for( i = 0; i < (int) m_outline.GetCount(); i++ )
+ {
+ m_outline[i]->x += aX_offs;
+ m_outline[i]->y += aY_offs;
+ }
+
+ for( island = 0; island < (int) m_islands.GetCount(); island++ )
+ {
+ for( i = 0; i < (int) m_islands[island]->GetCount(); i++ )
+ {
+ (*m_islands[island])[i]->x += aX_offs;
+ (*m_islands[island])[i]->y += aY_offs;
+ }
+ }
+
+ for( island = 0; island < (int) m_cutouts.GetCount(); island++ )
+ {
+ for( i = 0; i < (int) m_cutouts[island]->GetCount(); i++ )
+ {
+ (*m_cutouts[island])[i]->x += aX_offs;
+ (*m_cutouts[island])[i]->y += aY_offs;
+ }
+ }
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.h b/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.h
new file mode 100644
index 0000000..90ffdbd
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.h
@@ -0,0 +1,75 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_polygon.h
+ */
+
+#ifndef PCB_POLYGON_H_
+#define PCB_POLYGON_H_
+
+#include <wx/wx.h>
+
+#include <pcb_component.h>
+
+namespace PCAD2KICAD {
+
+//WX_DEFINE_ARRAY( wxRealPoint*, VERTICES_ARRAY );
+WX_DEFINE_ARRAY( VERTICES_ARRAY*, ISLANDS_ARRAY );
+
+class PCB_POLYGON : public PCB_COMPONENT
+{
+public:
+ int m_width;
+ int m_priority;
+ VERTICES_ARRAY m_outline; // collection of boundary/outline lines - objects
+ ISLANDS_ARRAY m_islands;
+ ISLANDS_ARRAY m_cutouts;
+
+ PCB_POLYGON( PCB_CALLBACKS* aCallbacks, BOARD* aBoard, int aPCadLayer );
+ ~PCB_POLYGON();
+
+ virtual bool Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion,
+ wxStatusBar* aStatusBar );
+
+ virtual void SetPosOffset( int aX_offs, int aY_offs );
+ void AddToModule( MODULE* aModule );
+ void AddToBoard();
+
+// protected:
+ void AssignNet( wxString aNetName );
+ void SetOutline( VERTICES_ARRAY* aOutline );
+
+ void FormPolygon( XNODE* aNode, VERTICES_ARRAY* aPolygon,
+ wxString aDefaultMeasurementUnit, wxString actualConversion );
+protected:
+ bool m_filled;
+};
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_POLYGON_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_text.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_text.cpp
new file mode 100644
index 0000000..db8b57f
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_text.cpp
@@ -0,0 +1,138 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_text.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+
+#include <pcb_text.h>
+
+namespace PCAD2KICAD {
+
+PCB_TEXT::PCB_TEXT( PCB_CALLBACKS* aCallbacks, BOARD* aBoard ) : PCB_COMPONENT( aCallbacks,
+ aBoard )
+{
+ m_objType = wxT( 'T' );
+}
+
+
+PCB_TEXT::~PCB_TEXT()
+{
+}
+
+
+void PCB_TEXT::Parse( XNODE* aNode,
+ int aLayer,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ XNODE* lNode;
+ wxString str;
+
+ m_PCadLayer = aLayer;
+ m_KiCadLayer = GetKiCadLayer();
+ m_positionX = 0;
+ m_positionY = 0;
+ m_name.mirror = 0; // Normal, not mirrored
+ lNode = FindNode( aNode, wxT( "pt" ) );
+
+ if( lNode )
+ SetPosition( lNode->GetNodeContent(), aDefaultMeasurementUnit,
+ &m_positionX, &m_positionY, aActualConversion );
+
+ lNode = FindNode( aNode, wxT( "rotation" ) );
+
+ if( lNode )
+ {
+ str = lNode->GetNodeContent();
+ str.Trim( false );
+ m_rotation = StrToInt1Units( str );
+ }
+
+ aNode->GetAttribute( wxT( "Name" ), &m_name.text );
+
+ str = FindNodeGetContent( aNode, wxT( "justify" ) );
+ m_name.justify = GetJustifyIdentificator( str );
+
+ str = FindNodeGetContent( aNode, wxT( "isFlipped" ) );
+
+ if( str == wxT( "True" ) )
+ m_name.mirror = 1;
+
+ lNode = FindNode( aNode, wxT( "textStyleRef" ) );
+
+ if( lNode )
+ SetFontProperty( lNode, &m_name, aDefaultMeasurementUnit, aActualConversion );
+}
+
+
+void PCB_TEXT::AddToModule( MODULE* aModule )
+{
+}
+
+
+void PCB_TEXT::AddToBoard()
+{
+ // Simple, not the best, but acceptable text positioning.
+ m_name.textPositionX = m_positionX;
+ m_name.textPositionY = m_positionY;
+ m_name.textRotation = m_rotation;
+ CorrectTextPosition( &m_name );
+
+ TEXTE_PCB* pcbtxt = new TEXTE_PCB( m_board );
+ m_board->Add( pcbtxt, ADD_APPEND );
+
+ pcbtxt->SetText( m_name.text );
+
+ pcbtxt->SetSize( wxSize( KiROUND( m_name.textHeight / 2 ),
+ KiROUND( m_name.textHeight / 1.1 ) ) );
+
+ pcbtxt->SetThickness( m_name.textstrokeWidth );
+ pcbtxt->SetOrientation( m_name.textRotation );
+
+ pcbtxt->SetTextPosition( wxPoint( m_name.correctedPositionX,
+ m_name.correctedPositionY ) );
+
+ pcbtxt->SetMirrored( m_name.mirror );
+ pcbtxt->SetTimeStamp( 0 );
+
+ pcbtxt->SetLayer( m_KiCadLayer );
+}
+
+
+// void PCB_TEXT::SetPosOffset( int aX_offs, int aY_offs )
+// {
+// PCB_COMPONENT::SetPosOffset( aX_offs, aY_offs );
+
+// m_name.textPositionX += aX_offs;
+// m_name.textPositionY += aY_offs;
+// }
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_text.h b/pcbnew/pcad2kicadpcb_plugin/pcb_text.h
new file mode 100644
index 0000000..b85ec29
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_text.h
@@ -0,0 +1,59 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_text.h
+ */
+
+#ifndef PCB_TEXT_H_
+#define PCB_TEXT_H_
+
+#include <wx/wx.h>
+
+#include <pcb_component.h>
+
+namespace PCAD2KICAD {
+
+// Name property of parent is used for text value
+class PCB_TEXT : public PCB_COMPONENT
+{
+public:
+
+ PCB_TEXT( PCB_CALLBACKS* aCallbacks, BOARD* aBoard );
+ ~PCB_TEXT();
+
+ virtual void Parse( XNODE* aNode,
+ int aLayer,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion );
+ void AddToModule( MODULE* aModule );
+ void AddToBoard();
+
+// virtual void SetPosOffset( int aX_offs, int aY_offs );
+};
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_TEXT_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_via.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_via.cpp
new file mode 100644
index 0000000..49789d1
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_via.cpp
@@ -0,0 +1,139 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_via.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <pcb_via.h>
+#include <pcb_via_shape.h>
+
+namespace PCAD2KICAD {
+
+PCB_VIA::PCB_VIA( PCB_CALLBACKS* aCallbacks, BOARD* aBoard ) : PCB_PAD( aCallbacks, aBoard )
+{
+ m_objType = wxT( 'V' );
+}
+
+
+PCB_VIA::~PCB_VIA()
+{
+}
+
+
+void PCB_VIA::Parse( XNODE* aNode, wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ XNODE* lNode, * tNode;
+ wxString propValue;
+ PCB_VIA_SHAPE* viaShape;
+
+ m_rotation = 0;
+ lNode = FindNode( aNode, wxT( "viaStyleRef" ) );
+
+ if( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+ m_name.text = propValue;
+ }
+
+ lNode = FindNode( aNode, wxT( "pt" ) );
+
+ if( lNode )
+ SetPosition( lNode->GetNodeContent(), aDefaultMeasurementUnit,
+ &m_positionX, &m_positionY, aActualConversion );
+
+ lNode = FindNode( aNode, wxT( "netNameRef" ) );
+
+ if( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+ propValue.Trim( false );
+ propValue.Trim( true );
+ m_net = propValue;
+ m_netCode = GetNetCode( m_net );
+ }
+
+ lNode = aNode;
+
+ while( lNode && lNode->GetName() != wxT( "www.lura.sk" ) )
+ lNode = lNode->GetParent();
+
+ lNode = FindNode( lNode, wxT( "library" ) );
+
+ if ( !lNode )
+ THROW_IO_ERROR( wxT( "Unable to find library section" ) );
+
+ lNode = FindNode( lNode, wxT( "viaStyleDef" ) );
+
+ while( lNode )
+ {
+ lNode->GetAttribute( wxT( "Name" ), &propValue );
+
+ if( propValue.IsSameAs( m_name.text, false ) )
+ break;
+
+ lNode = lNode->GetNext();
+ }
+
+ if ( !lNode )
+ THROW_IO_ERROR( wxString::Format( wxT( "Unable to find viaStyleDef " ) + m_name.text ) );
+
+ if( lNode )
+ {
+ tNode = lNode;
+ lNode = FindNode( tNode, wxT( "holeDiam" ) );
+
+ if( lNode )
+ SetWidth( lNode->GetNodeContent(), aDefaultMeasurementUnit, &m_hole,
+ aActualConversion );
+
+ lNode = FindNode( tNode, wxT( "viaShape" ) );
+
+ while( lNode )
+ {
+ if( lNode->GetName() == wxT( "viaShape" ) )
+ {
+ // we support only Vias on specific layers......
+ // we do not support vias on "Plane", "NonSignal" , "Signal" ... layerr
+ if( FindNode( lNode, wxT( "layerNumRef" ) ) )
+ {
+ viaShape = new PCB_VIA_SHAPE( m_callbacks, m_board );
+ viaShape->Parse( lNode, aDefaultMeasurementUnit, aActualConversion );
+ m_shapes.Add( viaShape );
+ }
+ }
+
+ lNode = lNode->GetNext();
+ }
+ }
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_via.h b/pcbnew/pcad2kicadpcb_plugin/pcb_via.h
new file mode 100644
index 0000000..05b5c3a
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_via.h
@@ -0,0 +1,54 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_via.h
+ */
+
+#ifndef PCB_VIA_H_
+#define PCB_VIA_H_
+
+#include <wx/wx.h>
+
+#include <pcb_pad.h>
+
+namespace PCAD2KICAD {
+
+// will be replaced by pad in next version ????
+class PCB_VIA : public PCB_PAD
+{
+public:
+
+ PCB_VIA( PCB_CALLBACKS* aCallbacks, BOARD* aBoard );
+ ~PCB_VIA();
+
+ virtual void Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion );
+};
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_VIA_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_via_shape.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_via_shape.cpp
new file mode 100644
index 0000000..70e6d60
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_via_shape.cpp
@@ -0,0 +1,88 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_via_shape.cpp
+ */
+
+#include <wx/wx.h>
+#include <wx/config.h>
+
+#include <common.h>
+
+#include <pcb_via_shape.h>
+
+namespace PCAD2KICAD {
+
+PCB_VIA_SHAPE::PCB_VIA_SHAPE( PCB_CALLBACKS* aCallbacks,
+ BOARD* aBoard ) : PCB_PAD_SHAPE( aCallbacks, aBoard )
+{
+}
+
+
+PCB_VIA_SHAPE::~PCB_VIA_SHAPE()
+{
+}
+
+
+void PCB_VIA_SHAPE::Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion )
+{
+ XNODE* lNode;
+ wxString str;
+ long num;
+
+ lNode = FindNode( aNode, wxT( "viaShapeType" ) );
+
+ if( lNode )
+ {
+ str = lNode->GetNodeContent();
+ str.Trim( false );
+ m_shape = str;
+ }
+
+ lNode = FindNode( aNode, wxT( "layerNumRef" ) );
+
+ if( lNode )
+ {
+ lNode->GetNodeContent().ToLong( &num );
+ m_PCadLayer = (int) num;
+ }
+
+ m_KiCadLayer = GetKiCadLayer();
+ lNode = FindNode( aNode, wxT( "shapeWidth" ) );
+
+ if( lNode )
+ SetWidth( lNode->GetNodeContent(), aDefaultMeasurementUnit, &m_width, aActualConversion );
+
+ lNode = FindNode( aNode, wxT( "shapeHeight" ) );
+
+ if( lNode )
+ SetWidth( lNode->GetNodeContent(), aDefaultMeasurementUnit, &m_height, aActualConversion );
+
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_via_shape.h b/pcbnew/pcad2kicadpcb_plugin/pcb_via_shape.h
new file mode 100644
index 0000000..d12fa62
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/pcb_via_shape.h
@@ -0,0 +1,52 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
+ * Copyright (C) 2007, 2008, 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_via_shape.h
+ */
+
+#ifndef PCB_VIA_SHAPE_H_
+#define PCB_VIA_SHAPE_H_
+
+#include <wx/wx.h>
+
+#include <pcb_pad_shape.h>
+
+namespace PCAD2KICAD {
+
+class PCB_VIA_SHAPE : public PCB_PAD_SHAPE
+{
+public:
+ PCB_VIA_SHAPE( PCB_CALLBACKS* aCallbacks, BOARD* aBoard );
+ ~PCB_VIA_SHAPE();
+
+ virtual void Parse( XNODE* aNode,
+ wxString aDefaultMeasurementUnit,
+ wxString aActualConversion );
+};
+
+} // namespace PCAD2KICAD
+
+#endif // PCB_VIA_SHAPE_H_
diff --git a/pcbnew/pcad2kicadpcb_plugin/s_expr_loader.cpp b/pcbnew/pcad2kicadpcb_plugin/s_expr_loader.cpp
new file mode 100644
index 0000000..19ec21d
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/s_expr_loader.cpp
@@ -0,0 +1,116 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file s_expr_loader.cpp
+ */
+
+#include <dsnlexer.h>
+#include <macros.h>
+#include <wx/xml/xml.h>
+#include <xnode.h>
+
+namespace PCAD2KICAD {
+
+static KEYWORD empty_keywords[1] = {};
+static const char ACCEL_ASCII_KEYWORD[] = "ACCEL_ASCII";
+
+void LoadInputFile( wxString aFileName, wxXmlDocument* aXmlDoc )
+{
+ char line[sizeof( ACCEL_ASCII_KEYWORD )];
+ int tok;
+ XNODE* iNode = NULL, *cNode = NULL;
+ wxString str, propValue, content;
+ wxCSConv conv( wxT( "windows-1251" ) );
+
+ FILE* fp = wxFopen( aFileName, wxT( "rt" ) );
+
+ if( !fp )
+ THROW_IO_ERROR( wxT( "Unable to open file: " ) + aFileName );
+
+ // check file format
+ if( !fgets( line, sizeof( line ), fp )
+ // first line starts with "ACCEL_ASCII" with optional stuff on same line after that.
+ || memcmp( line, ACCEL_ASCII_KEYWORD, sizeof(ACCEL_ASCII_KEYWORD)-1 ) )
+ THROW_IO_ERROR( "Unknown file type" );
+
+ // rewind the file
+ fseek( fp, 0, SEEK_SET );
+
+ // lexer now owns fp, will close on exception or return
+ DSNLEXER lexer( empty_keywords, 0, fp, aFileName );
+
+ iNode = new XNODE( wxXML_ELEMENT_NODE, wxT( "www.lura.sk" ) );
+
+ while( ( tok = lexer.NextTok() ) != DSN_EOF )
+ {
+ if( tok == DSN_RIGHT )
+ {
+ iNode = iNode->GetParent();
+ }
+ else if( tok == DSN_LEFT )
+ {
+ tok = lexer.NextTok();
+ str = wxEmptyString;
+ cNode = new XNODE( wxXML_ELEMENT_NODE, wxString( lexer.CurText(), conv ) );
+ iNode->AddChild( cNode );
+ iNode = cNode;
+ }
+ else if( cNode )
+ {
+ str = wxString( lexer.CurText(), conv );
+ if( tok == DSN_STRING )
+ {
+ // update attribute
+ if( iNode->GetAttribute( wxT( "Name" ), &propValue ) )
+ {
+ iNode->DeleteAttribute( wxT( "Name" ) );
+ iNode->AddAttribute( wxT( "Name" ), propValue + wxT( ' ' ) + str );
+ }
+ else
+ iNode->AddAttribute( wxT( "Name" ), str );
+ }
+ else if( str != wxEmptyString )
+ {
+ // update node content
+ content = cNode->GetNodeContent() + wxT( ' ' ) + str;
+
+ if( cNode->GetChildren() )
+ cNode->GetChildren()->SetContent( content );
+ else
+ cNode->AddChild( new wxXmlNode( wxXML_TEXT_NODE,
+ wxEmptyString,
+ content ) );
+ }
+ }
+ }
+
+ if( iNode )
+ {
+ aXmlDoc->SetRoot( iNode );
+ //aXmlDoc->Save( wxT( "test.xml" ) );
+ }
+}
+
+} // namespace PCAD2KICAD
diff --git a/pcbnew/pcad2kicadpcb_plugin/s_expr_loader.h b/pcbnew/pcad2kicadpcb_plugin/s_expr_loader.h
new file mode 100644
index 0000000..02c1857
--- /dev/null
+++ b/pcbnew/pcad2kicadpcb_plugin/s_expr_loader.h
@@ -0,0 +1,37 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Alexander Lunev <al.lunev@yahoo.com>
+ * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file s_expr_loader.h
+ */
+
+#ifndef S_EXPR_LOADER_H_
+#define S_EXPR_LOADER_H_
+
+namespace PCAD2KICAD
+{
+ void LoadInputFile( wxString aFileName, wxXmlDocument* aXmlDoc );
+}
+
+#endif // S_EXPR_LOADER_H_
diff --git a/pcbnew/pcb_base_edit_frame.cpp b/pcbnew/pcb_base_edit_frame.cpp
new file mode 100644
index 0000000..81b28c6
--- /dev/null
+++ b/pcbnew/pcb_base_edit_frame.cpp
@@ -0,0 +1,95 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <pcb_base_edit_frame.h>
+#include <tool/tool_manager.h>
+#include <pcb_draw_panel_gal.h>
+#include <gal/graphics_abstraction_layer.h>
+#include <class_board.h>
+
+void PCB_BASE_EDIT_FRAME::SetRotationAngle( int aRotationAngle )
+{
+ wxCHECK2_MSG( aRotationAngle > 0 && aRotationAngle <= 900, aRotationAngle = 900,
+ wxT( "Invalid rotation angle, defaulting to 90." ) );
+
+ m_rotationAngle = aRotationAngle;
+}
+
+
+bool PCB_BASE_EDIT_FRAME::PostCommandMenuEvent( int evt_type )
+{
+ if( evt_type != 0 )
+ {
+ wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
+ evt.SetEventObject( this );
+ evt.SetId( evt_type );
+ wxPostEvent( this, evt );
+ return true;
+ }
+
+ return false;
+}
+
+
+void PCB_BASE_EDIT_FRAME::UseGalCanvas( bool aEnable )
+{
+ PCB_BASE_FRAME::UseGalCanvas( aEnable );
+
+ // No matter what, reenable undo/redo on switching to the legacy canvas
+ if( !aEnable )
+ UndoRedoBlock( false );
+ else
+ static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() )->SyncLayersVisibility( m_Pcb );
+}
+
+
+void PCB_BASE_EDIT_FRAME::SetBoard( BOARD* aBoard )
+{
+ bool new_board = ( aBoard != m_Pcb );
+
+ // The active tool might store a reference to the BOARD that is about to be deleted.
+ if( m_toolManager )
+ m_toolManager->DeactivateTool();
+
+ // It has to be done before the previous board is destroyed by SetBoard()
+ if( new_board )
+ GetGalCanvas()->GetView()->Clear();
+
+ PCB_BASE_FRAME::SetBoard( aBoard );
+
+ GetGalCanvas()->GetGAL()->SetGridOrigin( VECTOR2D( aBoard->GetGridOrigin() ) );
+
+ // update the tool manager with the new board and its view.
+ if( m_toolManager )
+ {
+ PCB_DRAW_PANEL_GAL* drawPanel = static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() );
+
+ drawPanel->DisplayBoard( aBoard );
+ m_toolManager->SetEnvironment( aBoard, drawPanel->GetView(),
+ drawPanel->GetViewControls(), this );
+
+ if( new_board )
+ m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
+ }
+}
diff --git a/pcbnew/pcb_base_edit_frame.h b/pcbnew/pcb_base_edit_frame.h
new file mode 100644
index 0000000..15332ac
--- /dev/null
+++ b/pcbnew/pcb_base_edit_frame.h
@@ -0,0 +1,148 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef BASE_EDIT_FRAME_H
+#define BASE_EDIT_FRAME_H
+
+#include <wxBasePcbFrame.h>
+
+/**
+ * Common, abstract interface for edit frames.
+ */
+class PCB_BASE_EDIT_FRAME : public PCB_BASE_FRAME
+{
+public:
+ PCB_BASE_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
+ const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
+ long aStyle, const wxString& aFrameName ) :
+ PCB_BASE_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ),
+ m_rotationAngle( 900 ), m_undoRedoBlocked( false )
+ {}
+
+ virtual ~PCB_BASE_EDIT_FRAME() {};
+
+ /**
+ * Function CreateNewLibrary
+ * prompts user for a library path, then creates a new footprint library at that
+ * location. If library exists, user is warned about that, and is given a chance
+ * to abort the new creation, and in that case existing library is first deleted.
+ *
+ * @return wxString - the newly created library path if library was successfully
+ * created, else wxEmptyString because user aborted or error.
+ */
+ wxString CreateNewLibrary();
+
+ /**
+ * Function OnEditItemRequest
+ * Install the corresponding dialog editor for the given item
+ * @param aDC = the current device context
+ * @param aItem = a pointer to the BOARD_ITEM to edit
+ */
+ virtual void OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem ) = 0;
+
+ /**
+ * Function RestoreCopyFromRedoList
+ * Redo the last edition:
+ * - Save the current data in Undo list
+ * - Get an old version of the data from Redo list
+ */
+ virtual void RestoreCopyFromRedoList( wxCommandEvent& aEvent ) = 0;
+
+ /**
+ * Function RestoreCopyFromUndoList
+ * Undo the last edition:
+ * - Save the current board in Redo list
+ * - Get an old version of the data from Undo list
+ */
+ virtual void RestoreCopyFromUndoList( wxCommandEvent& aEvent ) = 0;
+
+ int GetRotationAngle() const { return m_rotationAngle; }
+ void SetRotationAngle( int aRotationAngle );
+
+ bool PostCommandMenuEvent( int evt_type );
+
+ /**
+ * Function UndoRedoBlocked
+ * Checks if the undo and redo operations are currently blocked.
+ */
+ bool UndoRedoBlocked() const
+ {
+ return m_undoRedoBlocked;
+ }
+
+ /**
+ * Function UndoRedoBlock
+ * Enables/disable undo and redo operations.
+ */
+ void UndoRedoBlock( bool aBlock = true )
+ {
+ m_undoRedoBlocked = aBlock;
+ }
+
+ ///> @copydoc EDA_DRAW_FRAME::UseGalCanvas()
+ void UseGalCanvas( bool aEnable );
+
+ ///> @copydoc PCB_BASE_FRAME::SetBoard()
+ virtual void SetBoard( BOARD* aBoard );
+
+protected:
+ /// User defined rotation angle (in tenths of a degree).
+ int m_rotationAngle;
+
+ /// Is undo/redo operation currently blocked?
+ bool m_undoRedoBlocked;
+
+ /**
+ * Function createArray
+ * Create an array of the selected item (invokes the dialogue)
+ * This function is shared between pcbnew and modedit, as it is virtually
+ * the same
+ */
+ void createArray();
+
+ /**
+ * Function duplicateItem
+ * Duplicate the specified item
+ * This function is shared between pcbnew and modedit, as it is virtually
+ * the same
+ * @param aItem the item to duplicate
+ * @aIncrement increment item reference (module ref, pad number, etc,
+ * if appropriate)
+ */
+ void duplicateItem( BOARD_ITEM* aItem, bool aIncrement );
+
+ /**
+ * Function duplicateItems
+ * Find and duplicate the currently selected items
+ * @param aIncrement increment item reference (module ref, pad number, etc,
+ * if appropriate)
+ *
+ * @note The implementer should find the selected item (and do processing
+ * like finding parents when relevant, and then call
+ * duplicateItem(BOARD_ITEM*, bool) above
+ */
+ virtual void duplicateItems( bool aIncrement ) = 0;
+};
+
+#endif
diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp
new file mode 100644
index 0000000..c4313ab
--- /dev/null
+++ b/pcbnew/pcb_draw_panel_gal.cpp
@@ -0,0 +1,436 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "pcb_draw_panel_gal.h"
+#include <view/view.h>
+#include <view/wx_view_controls.h>
+#include <pcb_painter.h>
+#include <worksheet_viewitem.h>
+#include <ratsnest_viewitem.h>
+#include <ratsnest_data.h>
+
+#include <class_colors_design_settings.h>
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <wxBasePcbFrame.h>
+
+#include <boost/bind.hpp>
+
+const LAYER_NUM GAL_LAYER_ORDER[] =
+{
+ ITEM_GAL_LAYER( GP_OVERLAY ),
+ ITEM_GAL_LAYER( DRC_VISIBLE ),
+ NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ),
+ Dwgs_User, Cmts_User, Eco1_User, Eco2_User, Edge_Cuts,
+
+ ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ),
+ ITEM_GAL_LAYER( MOD_REFERENCES_VISIBLE), ITEM_GAL_LAYER( MOD_VALUES_VISIBLE ),
+
+ ITEM_GAL_LAYER( RATSNEST_VISIBLE ), ITEM_GAL_LAYER( ANCHOR_VISIBLE ),
+ ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ),
+ ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE ),
+ ITEM_GAL_LAYER( VIA_MICROVIA_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
+
+ NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_FR_VISIBLE ),
+ NETNAMES_GAL_LAYER( F_Cu ), F_Cu, F_Mask, F_SilkS, F_Paste, F_Adhes,
+
+ NETNAMES_GAL_LAYER( In1_Cu ), In1_Cu,
+ NETNAMES_GAL_LAYER( In2_Cu ), In2_Cu,
+ NETNAMES_GAL_LAYER( In3_Cu ), In3_Cu,
+ NETNAMES_GAL_LAYER( In4_Cu ), In4_Cu,
+ NETNAMES_GAL_LAYER( In5_Cu ), In5_Cu,
+ NETNAMES_GAL_LAYER( In6_Cu ), In6_Cu,
+ NETNAMES_GAL_LAYER( In7_Cu ), In7_Cu,
+ NETNAMES_GAL_LAYER( In8_Cu ), In8_Cu,
+ NETNAMES_GAL_LAYER( In9_Cu ), In9_Cu,
+ NETNAMES_GAL_LAYER( In10_Cu ), In10_Cu,
+ NETNAMES_GAL_LAYER( In11_Cu ), In11_Cu,
+ NETNAMES_GAL_LAYER( In12_Cu ), In12_Cu,
+ NETNAMES_GAL_LAYER( In13_Cu ), In13_Cu,
+ NETNAMES_GAL_LAYER( In14_Cu ), In14_Cu,
+ NETNAMES_GAL_LAYER( In15_Cu ), In15_Cu,
+ NETNAMES_GAL_LAYER( In16_Cu ), In16_Cu,
+ NETNAMES_GAL_LAYER( In17_Cu ), In17_Cu,
+ NETNAMES_GAL_LAYER( In18_Cu ), In18_Cu,
+ NETNAMES_GAL_LAYER( In19_Cu ), In19_Cu,
+ NETNAMES_GAL_LAYER( In20_Cu ), In20_Cu,
+ NETNAMES_GAL_LAYER( In21_Cu ), In21_Cu,
+ NETNAMES_GAL_LAYER( In22_Cu ), In22_Cu,
+ NETNAMES_GAL_LAYER( In23_Cu ), In23_Cu,
+ NETNAMES_GAL_LAYER( In24_Cu ), In24_Cu,
+ NETNAMES_GAL_LAYER( In25_Cu ), In25_Cu,
+ NETNAMES_GAL_LAYER( In26_Cu ), In26_Cu,
+ NETNAMES_GAL_LAYER( In27_Cu ), In27_Cu,
+ NETNAMES_GAL_LAYER( In28_Cu ), In28_Cu,
+ NETNAMES_GAL_LAYER( In29_Cu ), In29_Cu,
+ NETNAMES_GAL_LAYER( In30_Cu ), In30_Cu,
+
+ NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_BK_VISIBLE ),
+ NETNAMES_GAL_LAYER( B_Cu ), B_Cu, B_Mask, B_Adhes, B_Paste, B_SilkS,
+
+ ITEM_GAL_LAYER( MOD_TEXT_BK_VISIBLE ),
+ ITEM_GAL_LAYER( WORKSHEET )
+};
+
+
+PCB_DRAW_PANEL_GAL::PCB_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId,
+ const wxPoint& aPosition, const wxSize& aSize,
+ GAL_TYPE aGalType ) :
+EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aGalType )
+{
+ m_worksheet = NULL;
+ m_ratsnest = NULL;
+
+ setDefaultLayerOrder();
+ setDefaultLayerDeps();
+
+ // Load display options (such as filled/outline display of items).
+ // Can be made only if the parent window is an EDA_DRAW_FRAME (or a derived class)
+ // which is not always the case (namely when it is used from a wxDialog like the pad editor)
+ EDA_DRAW_FRAME* frame = dynamic_cast<EDA_DRAW_FRAME*>( aParentWindow );
+
+ if( frame )
+ {
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) frame->GetDisplayOptions();
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*>( m_view->GetPainter()->GetSettings() )->LoadDisplayOptions( displ_opts );
+ }
+}
+
+
+PCB_DRAW_PANEL_GAL::~PCB_DRAW_PANEL_GAL()
+{
+ delete m_worksheet;
+ delete m_ratsnest;
+}
+
+
+void PCB_DRAW_PANEL_GAL::DisplayBoard( const BOARD* aBoard )
+{
+ m_view->Clear();
+
+ // Load zones
+ for( int i = 0; i < aBoard->GetAreaCount(); ++i )
+ m_view->Add( (KIGFX::VIEW_ITEM*) ( aBoard->GetArea( i ) ) );
+
+ // Load drawings
+ for( BOARD_ITEM* drawing = aBoard->m_Drawings; drawing; drawing = drawing->Next() )
+ m_view->Add( drawing );
+
+ // Load tracks
+ for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
+ m_view->Add( track );
+
+ // Load modules and its additional elements
+ for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
+ {
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, m_view, _1 ) );
+ m_view->Add( module );
+ }
+
+ // Segzones (equivalent of ZONE_CONTAINER for legacy boards)
+ for( SEGZONE* zone = aBoard->m_Zone; zone; zone = zone->Next() )
+ m_view->Add( zone );
+
+ // Ratsnest
+ if( m_ratsnest )
+ {
+ m_view->Remove( m_ratsnest );
+ delete m_ratsnest;
+ }
+
+ m_ratsnest = new KIGFX::RATSNEST_VIEWITEM( aBoard->GetRatsnest() );
+ m_view->Add( m_ratsnest );
+
+ // Display settings
+ UseColorScheme( aBoard->GetColorsSettings() );
+
+ PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( GetParent() );
+
+ if( frame )
+ {
+ SetTopLayer( frame->GetActiveLayer() );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) frame->GetDisplayOptions();
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*>(
+ m_view->GetPainter()->GetSettings() )->LoadDisplayOptions( displ_opts );
+ }
+
+ m_view->RecacheAllItems( true );
+}
+
+
+void PCB_DRAW_PANEL_GAL::SetWorksheet( KIGFX::WORKSHEET_VIEWITEM* aWorksheet )
+{
+ if( m_worksheet )
+ {
+ m_view->Remove( m_worksheet );
+ delete m_worksheet;
+ }
+
+ m_worksheet = aWorksheet;
+ m_view->Add( m_worksheet );
+}
+
+
+void PCB_DRAW_PANEL_GAL::UseColorScheme( const COLORS_DESIGN_SETTINGS* aSettings )
+{
+ KIGFX::PCB_RENDER_SETTINGS* rs;
+ rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( m_view->GetPainter()->GetSettings() );
+ rs->ImportLegacyColors( aSettings );
+}
+
+
+void PCB_DRAW_PANEL_GAL::SetHighContrastLayer( LAYER_ID aLayer )
+{
+ // Set display settings for high contrast mode
+ KIGFX::RENDER_SETTINGS* rSettings = m_view->GetPainter()->GetSettings();
+
+ SetTopLayer( aLayer );
+
+ rSettings->ClearActiveLayers();
+ rSettings->SetActiveLayer( aLayer );
+
+ if( IsCopperLayer( aLayer ) )
+ {
+ // Bring some other layers to the front in case of copper layers and make them colored
+ // fixme do not like the idea of storing the list of layers here,
+ // should be done in some other way I guess..
+ LAYER_NUM layers[] = {
+ GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ),
+ ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
+ ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ),
+ ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE )
+ };
+
+ for( unsigned int i = 0; i < sizeof( layers ) / sizeof( LAYER_NUM ); ++i )
+ rSettings->SetActiveLayer( layers[i] );
+
+ // Pads should be shown too
+ if( aLayer == B_Cu )
+ {
+ rSettings->SetActiveLayer( ITEM_GAL_LAYER( PAD_BK_VISIBLE ) );
+ rSettings->SetActiveLayer( ITEM_GAL_LAYER( MOD_BK_VISIBLE ) );
+ rSettings->SetActiveLayer( NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE ) );
+ }
+ else if( aLayer == F_Cu )
+ {
+ rSettings->SetActiveLayer( ITEM_GAL_LAYER( PAD_FR_VISIBLE ) );
+ rSettings->SetActiveLayer( ITEM_GAL_LAYER( MOD_FR_VISIBLE ) );
+ rSettings->SetActiveLayer( NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ) );
+ }
+ }
+
+ m_view->UpdateAllLayersColor();
+}
+
+
+void PCB_DRAW_PANEL_GAL::SetTopLayer( LAYER_ID aLayer )
+{
+ m_view->ClearTopLayers();
+ setDefaultLayerOrder();
+ m_view->SetTopLayer( aLayer );
+
+ // Layers that should always have on-top attribute enabled
+ const LAYER_NUM layers[] = {
+ ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ),
+ ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
+ ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ),
+ ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ), Dwgs_User,
+ ITEM_GAL_LAYER( DRC_VISIBLE )
+ };
+
+ for( unsigned int i = 0; i < sizeof( layers ) / sizeof( LAYER_NUM ); ++i )
+ m_view->SetTopLayer( layers[i] );
+
+ // Extra layers that are brought to the top if a F.* or B.* is selected
+ const LAYER_NUM frontLayers[] = {
+ F_Cu, F_Adhes, F_Paste, F_SilkS, F_Mask, F_CrtYd, F_Fab, ITEM_GAL_LAYER( PAD_FR_VISIBLE ),
+ NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ), NETNAMES_GAL_LAYER( F_Cu ), -1
+ };
+
+ const LAYER_NUM backLayers[] = {
+ B_Cu, B_Adhes, B_Paste, B_SilkS, B_Mask, B_CrtYd, B_Fab, ITEM_GAL_LAYER( PAD_BK_VISIBLE ),
+ NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE ), NETNAMES_GAL_LAYER( B_Cu ), -1
+ };
+
+ const LAYER_NUM* extraLayers = NULL;
+
+ // Bring a few more extra layers to the top depending on the selected board side
+ if( IsFrontLayer( aLayer ) )
+ extraLayers = frontLayers;
+ else if( IsBackLayer( aLayer ) )
+ extraLayers = backLayers;
+
+ if( extraLayers )
+ {
+ const LAYER_NUM* l = extraLayers;
+
+ while( *l >= 0 )
+ m_view->SetTopLayer( *l++ );
+
+ // Move the active layer to the top
+ if( !IsCopperLayer( aLayer ) )
+ m_view->SetLayerOrder( aLayer, m_view->GetLayerOrder( GAL_LAYER_ORDER[0] ) );
+ }
+ else if( IsCopperLayer( aLayer ) )
+ {
+ // Display labels for copper layers on the top
+ m_view->SetTopLayer( GetNetnameLayer( aLayer ) );
+ }
+
+ m_view->UpdateAllLayersOrder();
+}
+
+
+void PCB_DRAW_PANEL_GAL::SyncLayersVisibility( const BOARD* aBoard )
+{
+ // Load layer & elements visibility settings
+ for( LAYER_NUM i = 0; i < LAYER_ID_COUNT; ++i )
+ {
+ m_view->SetLayerVisible( i, aBoard->IsLayerVisible( LAYER_ID( i ) ) );
+
+ // Synchronize netname layers as well
+ if( IsCopperLayer( i ) )
+ m_view->SetLayerVisible( GetNetnameLayer( i ), aBoard->IsLayerVisible( LAYER_ID( i ) ) );
+ }
+
+ for( LAYER_NUM i = 0; i < END_PCB_VISIBLE_LIST; ++i )
+ {
+ m_view->SetLayerVisible( ITEM_GAL_LAYER( i ), aBoard->IsElementVisible( i ) );
+ }
+
+ // Enable some layers that are GAL specific
+ m_view->SetLayerVisible( ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), true );
+ m_view->SetLayerVisible( ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), true );
+ m_view->SetLayerVisible( ITEM_GAL_LAYER( WORKSHEET ), true );
+ m_view->SetLayerVisible( ITEM_GAL_LAYER( GP_OVERLAY ), true );
+}
+
+
+void PCB_DRAW_PANEL_GAL::GetMsgPanelInfo( std::vector<MSG_PANEL_ITEM>& aList )
+{
+ BOARD* board = static_cast<PCB_BASE_FRAME*>( m_parent )->GetBoard();
+ wxString txt;
+ int viasCount = 0;
+ int trackSegmentsCount = 0;
+
+ for( const BOARD_ITEM* item = board->m_Track; item; item = item->Next() )
+ {
+ if( item->Type() == PCB_VIA_T )
+ viasCount++;
+ else
+ trackSegmentsCount++;
+ }
+
+ txt.Printf( wxT( "%d" ), board->GetPadCount() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Pads" ), txt, DARKGREEN ) );
+
+ txt.Printf( wxT( "%d" ), viasCount );
+ aList.push_back( MSG_PANEL_ITEM( _( "Vias" ), txt, DARKGREEN ) );
+
+ txt.Printf( wxT( "%d" ), trackSegmentsCount );
+ aList.push_back( MSG_PANEL_ITEM( _( "Track Segments" ), txt, DARKGREEN ) );
+
+ txt.Printf( wxT( "%d" ), board->GetNodesCount() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Nodes" ), txt, DARKCYAN ) );
+
+ txt.Printf( wxT( "%d" ), board->GetNetCount() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Nets" ), txt, RED ) );
+
+ txt.Printf( wxT( "%d" ), board->GetRatsnest()->GetUnconnectedCount() );
+ aList.push_back( MSG_PANEL_ITEM( _( "Unconnected" ), txt, BLUE ) );
+}
+
+
+void PCB_DRAW_PANEL_GAL::setDefaultLayerOrder()
+{
+ for( LAYER_NUM i = 0; (unsigned) i < sizeof( GAL_LAYER_ORDER ) / sizeof( LAYER_NUM ); ++i )
+ {
+ LAYER_NUM layer = GAL_LAYER_ORDER[i];
+ wxASSERT( layer < KIGFX::VIEW::VIEW_MAX_LAYERS );
+
+ m_view->SetLayerOrder( layer, i );
+ }
+}
+
+
+void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
+{
+ for( LAYER_NUM i = 0; (unsigned) i < sizeof( GAL_LAYER_ORDER ) / sizeof( LAYER_NUM ); ++i )
+ {
+ LAYER_NUM layer = GAL_LAYER_ORDER[i];
+ wxASSERT( layer < KIGFX::VIEW::VIEW_MAX_LAYERS );
+
+ if( IsCopperLayer( layer ) )
+ {
+ // Copper layers are required for netname layers
+ m_view->SetRequired( GetNetnameLayer( layer ), layer );
+ m_view->SetLayerTarget( layer, KIGFX::TARGET_CACHED );
+ }
+ else if( IsNetnameLayer( layer ) )
+ {
+ // Netnames are drawn only when scale is sufficient (level of details)
+ // so there is no point in caching them
+ m_view->SetLayerTarget( layer, KIGFX::TARGET_NONCACHED );
+ m_view->SetLayerDisplayOnly( layer );
+ }
+ }
+
+ m_view->SetLayerTarget( ITEM_GAL_LAYER( ANCHOR_VISIBLE ), KIGFX::TARGET_NONCACHED );
+ m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( ANCHOR_VISIBLE ) );
+
+ // Some more required layers settings
+ m_view->SetRequired( ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ) );
+ m_view->SetRequired( ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ) );
+ m_view->SetRequired( NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ) );
+
+ // Front modules
+ m_view->SetRequired( ITEM_GAL_LAYER( PAD_FR_VISIBLE ), ITEM_GAL_LAYER( MOD_FR_VISIBLE ) );
+ m_view->SetRequired( ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ), ITEM_GAL_LAYER( MOD_FR_VISIBLE ) );
+ m_view->SetRequired( NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_FR_VISIBLE ) );
+ m_view->SetRequired( F_Adhes, ITEM_GAL_LAYER( PAD_FR_VISIBLE ) );
+ m_view->SetRequired( F_Paste, ITEM_GAL_LAYER( PAD_FR_VISIBLE ) );
+ m_view->SetRequired( F_Mask, ITEM_GAL_LAYER( PAD_FR_VISIBLE ) );
+ m_view->SetRequired( F_CrtYd, ITEM_GAL_LAYER( MOD_FR_VISIBLE ) );
+ m_view->SetRequired( F_Fab, ITEM_GAL_LAYER( MOD_FR_VISIBLE ) );
+
+ // Back modules
+ m_view->SetRequired( ITEM_GAL_LAYER( PAD_BK_VISIBLE ), ITEM_GAL_LAYER( MOD_BK_VISIBLE ) );
+ m_view->SetRequired( ITEM_GAL_LAYER( MOD_TEXT_BK_VISIBLE ), ITEM_GAL_LAYER( MOD_BK_VISIBLE ) );
+ m_view->SetRequired( NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_BK_VISIBLE ) );
+ m_view->SetRequired( B_Adhes, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) );
+ m_view->SetRequired( B_Paste, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) );
+ m_view->SetRequired( B_Mask, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) );
+ m_view->SetRequired( B_CrtYd, ITEM_GAL_LAYER( MOD_BK_VISIBLE ) );
+ m_view->SetRequired( B_Fab, ITEM_GAL_LAYER( MOD_BK_VISIBLE ) );
+
+ m_view->SetLayerTarget( ITEM_GAL_LAYER( GP_OVERLAY ), KIGFX::TARGET_OVERLAY );
+ m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( GP_OVERLAY ) );
+ m_view->SetLayerTarget( ITEM_GAL_LAYER( RATSNEST_VISIBLE ), KIGFX::TARGET_OVERLAY );
+ m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( RATSNEST_VISIBLE ) );
+
+ m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( WORKSHEET ) );
+ m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( GRID_VISIBLE ) );
+ m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( DRC_VISIBLE ) );
+}
diff --git a/pcbnew/pcb_draw_panel_gal.h b/pcbnew/pcb_draw_panel_gal.h
new file mode 100644
index 0000000..8483424
--- /dev/null
+++ b/pcbnew/pcb_draw_panel_gal.h
@@ -0,0 +1,97 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef PCB_DRAW_PANEL_GAL_H_
+#define PCB_DRAW_PANEL_GAL_H_
+
+#include <class_draw_panel_gal.h>
+
+namespace KIGFX
+{
+ class WORKSHEET_VIEWITEM;
+ class RATSNEST_VIEWITEM;
+}
+class COLORS_DESIGN_SETTINGS;
+
+class PCB_DRAW_PANEL_GAL : public EDA_DRAW_PANEL_GAL
+{
+public:
+ PCB_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId, const wxPoint& aPosition,
+ const wxSize& aSize, GAL_TYPE aGalType = GAL_TYPE_OPENGL );
+
+ virtual ~PCB_DRAW_PANEL_GAL();
+
+ /**
+ * Function DisplayBoard
+ * adds all items from the current board to the VIEW, so they can be displayed by GAL.
+ * @param aBoard is the PCB to be loaded.
+ */
+ void DisplayBoard( const BOARD* aBoard );
+
+ /**
+ * Function SetWorksheet
+ * Sets (or updates) worksheet used by the draw panel.
+ * @param aWorksheet is the worksheet to be used.
+ * The object is then owned by PCB_DRAW_PANEL_GAL.
+ */
+ void SetWorksheet( KIGFX::WORKSHEET_VIEWITEM* aWorksheet );
+
+ /**
+ * Function UseColorScheme
+ * Applies layer color settings.
+ * @param aSettings are the new settings.
+ */
+ void UseColorScheme( const COLORS_DESIGN_SETTINGS* aSettings );
+
+ ///> @copydoc EDA_DRAW_PANEL_GAL::SetHighContrastLayer()
+ virtual void SetHighContrastLayer( LAYER_ID aLayer );
+
+ ///> @copydoc EDA_DRAW_PANEL_GAL::SetTopLayer()
+ virtual void SetTopLayer( LAYER_ID aLayer );
+
+ /**
+ * Function SyncLayersVisibility
+ * Updates "visibility" property of each layer of a given BOARD.
+ * @param aBoard contains layers visibility settings to be applied.
+ */
+ void SyncLayersVisibility( const BOARD* aBoard );
+
+ ///> @copydoc EDA_DRAW_PANEL_GAL::GetMsgPanelInfo()
+ void GetMsgPanelInfo( std::vector<MSG_PANEL_ITEM>& aList );
+
+protected:
+ ///> Reassigns layer order to the initial settings.
+ void setDefaultLayerOrder();
+
+ ///> Sets rendering targets & dependencies for layers.
+ void setDefaultLayerDeps();
+
+ ///> Currently used worksheet
+ KIGFX::WORKSHEET_VIEWITEM* m_worksheet;
+
+ ///> Ratsnest view item
+ KIGFX::RATSNEST_VIEWITEM* m_ratsnest;
+};
+
+#endif /* PCB_DRAW_PANEL_GAL_H_ */
diff --git a/pcbnew/pcb_netlist.cpp b/pcbnew/pcb_netlist.cpp
new file mode 100644
index 0000000..90a45a2
--- /dev/null
+++ b/pcbnew/pcb_netlist.cpp
@@ -0,0 +1,249 @@
+/**
+ * @file pcb_netlist.cpp
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2011 Jean-Pierre Charras.
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>.
+ * Copyright (C) 1992-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <macros.h>
+#include <kicad_string.h>
+#include <reporter.h>
+
+#include <pcb_netlist.h>
+#include <class_module.h>
+
+
+int COMPONENT_NET::Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl )
+{
+ return aOut->Print( aNestLevel, "(pin_net %s %s)",
+ aOut->Quotew( m_pinName ).c_str(),
+ aOut->Quotew( m_netName ).c_str() );
+}
+
+
+void COMPONENT::SetModule( MODULE* aModule )
+{
+ m_footprint.reset( aModule );
+
+ if( aModule == NULL )
+ return;
+
+ aModule->SetReference( m_reference );
+ aModule->SetValue( m_value );
+ aModule->SetFPID( m_fpid );
+ aModule->SetPath( m_timeStamp );
+}
+
+
+COMPONENT_NET COMPONENT::m_emptyNet;
+
+
+const COMPONENT_NET& COMPONENT::GetNet( const wxString& aPinName )
+{
+ for( unsigned i = 0; i < m_nets.size(); i++ )
+ {
+ if( m_nets[i].GetPinName() == aPinName )
+ return m_nets[i];
+ }
+
+ return m_emptyNet;
+}
+
+
+bool COMPONENT::MatchesFootprintFilters( const wxString& aFootprintName ) const
+{
+ if( m_footprintFilters.GetCount() == 0 )
+ return true;
+
+ // The matching is case insensitive
+ wxString name = aFootprintName.Upper();
+
+ for( unsigned ii = 0; ii < m_footprintFilters.GetCount(); ii++ )
+ {
+ if( name.Matches( m_footprintFilters[ii].Upper() ) )
+ return true;
+ }
+
+ return false;
+}
+
+
+void COMPONENT::Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl )
+{
+ int nl = aNestLevel;
+
+ aOut->Print( nl, "(ref %s ", aOut->Quotew( m_reference ).c_str() );
+ aOut->Print( 0, "(fpid %s)\n", aOut->Quotew( m_fpid.Format() ).c_str() );
+
+ if( ! ( aCtl & CTL_OMIT_EXTRA ) )
+ {
+ aOut->Print( nl+1, "(value %s)\n", aOut->Quotew( m_value ).c_str() );
+ aOut->Print( nl+1, "(name %s)\n", aOut->Quotew( m_name ).c_str() );
+ aOut->Print( nl+1, "(library %s)\n", aOut->Quotew( m_library ).c_str() );
+ aOut->Print( nl+1, "(timestamp %s)\n", aOut->Quotew( m_timeStamp ).c_str() );
+ }
+
+ if( !( aCtl & CTL_OMIT_FILTERS ) && m_footprintFilters.GetCount() )
+ {
+ aOut->Print( nl+1, "(fp_filters" );
+
+ for( unsigned i = 0; i < m_footprintFilters.GetCount(); ++i )
+ aOut->Print( 0, " %s", aOut->Quotew( m_footprintFilters[i] ).c_str() );
+
+ aOut->Print( 0, ")\n" );
+ }
+
+ if( !( aCtl & CTL_OMIT_NETS ) && m_nets.size() )
+ {
+ int llen = aOut->Print( nl+1, "(nets " );
+
+ for( unsigned i = 0; i < m_nets.size(); ++i )
+ {
+ if( llen > 80 )
+ {
+ aOut->Print( 0, "\n" );
+ llen = aOut->Print( nl+1, " " );
+ }
+
+ llen += m_nets[i].Format( aOut, 0, aCtl );
+ }
+
+ aOut->Print( 0, ")\n" );
+ }
+
+ aOut->Print( nl, ")\n" ); // </ref>
+}
+
+
+void NETLIST::Format( const char* aDocName, OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl )
+{
+ int nl = aNestLevel;
+
+ aOut->Print( nl, "(%s\n", aDocName );
+
+ for( unsigned i = 0; i < m_components.size(); i++ )
+ {
+ m_components[i].Format( aOut, nl+1, aCtl );
+ }
+
+ aOut->Print( nl, ")\n" );
+}
+
+
+void NETLIST::AddComponent( COMPONENT* aComponent )
+{
+ m_components.push_back( aComponent );
+}
+
+
+COMPONENT* NETLIST::GetComponentByReference( const wxString& aReference )
+{
+ COMPONENT* component = NULL;
+
+ for( unsigned i = 0; i < m_components.size(); i++ )
+ {
+ if( m_components[i].GetReference() == aReference )
+ {
+ component = &m_components[i];
+ break;
+ }
+ }
+
+ return component;
+}
+
+
+COMPONENT* NETLIST::GetComponentByTimeStamp( const wxString& aTimeStamp )
+{
+ COMPONENT* component = NULL;
+
+ for( unsigned i = 0; i < m_components.size(); i++ )
+ {
+ if( m_components[i].GetTimeStamp() == aTimeStamp )
+ {
+ component = &m_components[i];
+ break;
+ }
+ }
+
+ return component;
+}
+
+
+/**
+ * Function ByFPID
+ * is a helper function used to sort the component list used by loadNewModules.
+ */
+static bool ByFPID( const COMPONENT& ref, const COMPONENT& cmp )
+{
+ return ref.GetFPID() > cmp.GetFPID();
+}
+
+
+void NETLIST::SortByFPID()
+{
+ m_components.sort( ByFPID );
+}
+
+
+/**
+ * Operator <
+ * compares two #COMPONENT objects by reference designator.
+ */
+bool operator < ( const COMPONENT& item1, const COMPONENT& item2 )
+{
+ return StrNumCmp( item1.GetReference(), item2.GetReference(), INT_MAX, true ) < 0;
+}
+
+
+void NETLIST::SortByReference()
+{
+ m_components.sort();
+}
+
+
+bool NETLIST::AnyFootprintsLinked() const
+{
+ for( unsigned i = 0; i < m_components.size(); i++ )
+ {
+ if( !m_components[i].GetFPID().empty() )
+ return true;
+ }
+
+ return false;
+}
+
+
+bool NETLIST::AllFootprintsLinked() const
+{
+ for( unsigned i = 0; i < m_components.size(); i++ )
+ {
+ if( m_components[i].GetFPID().empty() )
+ return false;
+ }
+
+ return true;
+}
+
diff --git a/pcbnew/pcb_netlist.h b/pcbnew/pcb_netlist.h
new file mode 100644
index 0000000..0cecfb5
--- /dev/null
+++ b/pcbnew/pcb_netlist.h
@@ -0,0 +1,360 @@
+#ifndef PCB_NETLIST_H
+#define PCB_NETLIST_H
+
+/**
+ * @file pcb_netlist.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras.
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>.
+ * Copyright (C) 2012-2015 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <wx/arrstr.h>
+
+#include <fpid.h>
+#include <class_module.h>
+
+
+class REPORTER;
+
+
+/**
+ * Class COMPONENT_NET
+ * is used to store the component pin name to net name associations stored in a netlist.
+ */
+class COMPONENT_NET
+{
+ wxString m_pinName;
+ wxString m_netName;
+
+public:
+ COMPONENT_NET() {}
+
+ COMPONENT_NET( const wxString& aPinName, const wxString& aNetName ) :
+ m_pinName( aPinName ), m_netName( aNetName )
+ {
+ }
+
+ const wxString& GetPinName() const { return m_pinName; }
+
+ const wxString& GetNetName() const { return m_netName; }
+
+ bool IsValid() const { return !m_pinName.IsEmpty(); }
+
+ bool operator <( const COMPONENT_NET& aNet ) const
+ {
+ return m_pinName < aNet.m_pinName;
+ }
+
+ int Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl );
+};
+
+
+typedef std::vector< COMPONENT_NET > COMPONENT_NETS;
+
+
+/**
+ * Class COMPONENT
+ * is used to store components and all of their related information found in a netlist.
+ */
+class COMPONENT
+{
+ COMPONENT_NETS m_nets;
+ wxArrayString m_footprintFilters; ///< Footprint filters found in netlist.
+ wxString m_reference; ///< The component reference designator found in netlist.
+ wxString m_value; ///< The component value found in netlist.
+
+ // ZZZ This timestamp is string, not time_t
+ wxString m_timeStamp; ///< The component full time stamp found in netlist.
+
+ /// The name of the component in #m_library used when it was placed on the schematic..
+ wxString m_name;
+
+ /// The name of the component library where #m_name was found.
+ wxString m_library;
+
+ /// The #FPID of the footprint assigned to the component.
+ FPID m_fpid;
+
+ /// The alt FPID of the footprint, when there are 2 different assigned footprints,
+ /// One from the netlist, the other from the .cmp file.
+ /// this one is a copy of the netlist footprint assignment
+ FPID m_altFpid;
+
+ /// The #MODULE loaded for #m_fpid.
+ std::auto_ptr< MODULE > m_footprint;
+
+ /// Set to true if #m_fpid was changed when the footprint link file was read.
+ bool m_footprintChanged;
+
+ static COMPONENT_NET m_emptyNet;
+
+public:
+ COMPONENT( const FPID& aFPID,
+ const wxString& aReference,
+ const wxString& aValue,
+ const wxString& aTimeStamp )
+ {
+ m_fpid = aFPID;
+ m_reference = aReference;
+ m_value = aValue;
+ m_timeStamp = aTimeStamp;
+ m_footprintChanged = false;
+ }
+
+ virtual ~COMPONENT() { };
+
+ void AddNet( const wxString& aPinName, const wxString& aNetName )
+ {
+ m_nets.push_back( COMPONENT_NET( aPinName, aNetName ) );
+ }
+
+ unsigned GetNetCount() const { return m_nets.size(); }
+
+ const COMPONENT_NET& GetNet( unsigned aIndex ) const { return m_nets[aIndex]; }
+
+ const COMPONENT_NET& GetNet( const wxString& aPinName );
+
+ void SortPins() { sort( m_nets.begin(), m_nets.end() ); }
+
+ void SetName( const wxString& aName ) { m_name = aName;}
+ const wxString& GetName() const { return m_name; }
+
+ void SetLibrary( const wxString& aLibrary ) { m_library = aLibrary; }
+ const wxString& GetLibrary() const { return m_library; }
+
+ const wxString& GetReference() const { return m_reference; }
+
+ const wxString& GetValue() const { return m_value; }
+
+ void SetFPID( const FPID& aFPID )
+ {
+ m_footprintChanged = !m_fpid.empty() && (m_fpid != aFPID);
+ m_fpid = aFPID;
+ }
+
+ void SetAltFPID( const FPID& aFPID )
+ {
+ m_altFpid = aFPID;
+ }
+
+ const FPID& GetFPID() const { return m_fpid; }
+
+ const FPID& GetAltFPID() const { return m_altFpid; }
+
+ const wxString& GetTimeStamp() const { return m_timeStamp; }
+
+ void SetFootprintFilters( const wxArrayString& aFilterList )
+ {
+ m_footprintFilters = aFilterList;
+ }
+
+ const wxArrayString& GetFootprintFilters() const { return m_footprintFilters; }
+
+ /**
+ * Function MatchesFootprintFilters
+ *
+ * @return true if \a aFootprintName matches any of the footprint filters or no footprint
+ * filters are defined.
+ */
+ bool MatchesFootprintFilters( const wxString& aFootprintName ) const;
+
+ MODULE* GetModule( bool aRelease = false )
+ {
+ return ( aRelease ) ? m_footprint.release() : m_footprint.get();
+ }
+
+ void SetModule( MODULE* aModule );
+
+ bool IsLibSource( const wxString& aLibrary, const wxString& aName ) const
+ {
+ return aLibrary == m_library && aName == m_name;
+ }
+
+ bool FootprintChanged() const { return m_footprintChanged; }
+
+ void Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl );
+};
+
+
+typedef boost::ptr_vector< COMPONENT > COMPONENTS;
+typedef COMPONENTS::iterator COMPONENTS_ITER;
+typedef COMPONENTS::const_iterator COMPONENTS_CITER;
+
+
+/**
+ * Class NETLIST
+ * stores all of information read from a netlist along with the flags used to update
+ * the NETLIST in the #BOARD.
+ */
+class NETLIST
+{
+ COMPONENTS m_components; ///< Components found in the netlist.
+
+ /// Remove footprints from #BOARD not found in netlist when true.
+ bool m_deleteExtraFootprints;
+
+ /// Do not actually make any changes. Only report changes to #BOARD from netlist
+ /// when true.
+ bool m_isDryRun;
+
+ /// Find component by time stamp if true or reference designator if false.
+ bool m_findByTimeStamp;
+
+ /// Replace component footprints when they differ from the netlist if true.
+ bool m_replaceFootprints;
+
+public:
+ NETLIST() :
+ m_deleteExtraFootprints( false ),
+ m_isDryRun( false ),
+ m_findByTimeStamp( false ),
+ m_replaceFootprints( false )
+ {
+ }
+
+ /**
+ * Function IsEmpty()
+ * @return true if there are no components in the netlist.
+ */
+ bool IsEmpty() const { return m_components.empty(); }
+
+ /**
+ * Function Clear
+ * removes all components from the netlist.
+ */
+ void Clear() { m_components.clear(); }
+
+ /**
+ * Function GetCount
+ * @return the number of components in the netlist.
+ */
+ unsigned GetCount() const { return m_components.size(); }
+
+ /**
+ * Function GetComponent
+ * returns the #COMPONENT at \a aIndex.
+ *
+ * @param aIndex the index in #m_components to fetch.
+ * @return a pointer to the #COMPONENT at \a Index.
+ */
+ COMPONENT* GetComponent( unsigned aIndex ) { return &m_components[ aIndex ]; }
+
+ /**
+ * Function AddComponent
+ * adds \a aComponent to the NETLIST.
+ *
+ * @note If \a aComponent already exists in the NETLIST, \a aComponent is deleted
+ * to prevent memory leaks. An assertion is raised in debug builds.
+ *
+ * @param aComponent is the COMPONENT to save to the NETLIST.
+ */
+ void AddComponent( COMPONENT* aComponent );
+
+ /**
+ * Function GetComponentByReference
+ * returns a #COMPONENT by \a aReference.
+ *
+ * @param aReference is the reference designator the #COMPONENT.
+ * @return a pointer to the #COMPONENT that matches \a aReference if found. Otherwise NULL.
+ */
+ COMPONENT* GetComponentByReference( const wxString& aReference );
+
+ /**
+ * Function GetComponentByTimeStamp
+ * returns a #COMPONENT by \a aTimeStamp.
+ *
+ * @param aTimeStamp is the time stamp the #COMPONENT.
+ * @return a pointer to the #COMPONENT that matches \a aTimeStamp if found. Otherwise NULL.
+ */
+ COMPONENT* GetComponentByTimeStamp( const wxString& aTimeStamp );
+
+ void SortByFPID();
+
+ void SortByReference();
+
+ void SetDeleteExtraFootprints( bool aDeleteExtraFootprints )
+ {
+ m_deleteExtraFootprints = aDeleteExtraFootprints;
+ }
+
+ bool GetDeleteExtraFootprints() const { return m_deleteExtraFootprints; }
+
+ void SetIsDryRun( bool aIsDryRun ) { m_isDryRun = aIsDryRun; }
+
+ bool IsDryRun() const { return m_isDryRun; }
+
+ void SetFindByTimeStamp( bool aFindByTimeStamp ) { m_findByTimeStamp = aFindByTimeStamp; }
+
+ bool IsFindByTimeStamp() const { return m_findByTimeStamp; }
+
+ void SetReplaceFootprints( bool aReplaceFootprints )
+ {
+ m_replaceFootprints = aReplaceFootprints;
+ }
+
+ bool GetReplaceFootprints() const { return m_replaceFootprints; }
+
+ /**
+ * Function AnyFootprintsLinked
+ * @return true if any component with a footprint link is found.
+ */
+ bool AnyFootprintsLinked() const;
+
+ /**
+ * Function AllFootprintsLinked
+ * @return true if all components have a footprint link.
+ */
+ bool AllFootprintsLinked() const;
+
+ /**
+ * Function NoFootprintsLinked
+ * @return true if none of the components have a footprint link.
+ */
+ bool NoFootprintsLinked() const { return !AnyFootprintsLinked(); }
+
+ /**
+ * Function AnyFootprintsChanged
+ * @return true if any components footprints were changed when the footprint link file
+ * (*.cmp) was loaded.
+ */
+ bool AnyFootprintsChanged() const;
+
+ void Format( const char* aDocName, OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl = 0 );
+
+#define CTL_OMIT_EXTRA (1<<0)
+#define CTL_OMIT_NETS (1<<1)
+#define CTL_OMIT_FILTERS (1<<2)
+
+#define CTL_FOR_BACKANNO (CTL_OMIT_NETS | CTL_OMIT_FILTERS | CTL_OMIT_EXTRA)
+
+ void FormatBackAnnotation( OUTPUTFORMATTER* aOut )
+ {
+ Format( "back_annotation", aOut, 0, CTL_FOR_BACKANNO );
+ }
+};
+
+
+#endif // PCB_NETLIST_H
diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp
new file mode 100644
index 0000000..07dcd11
--- /dev/null
+++ b/pcbnew/pcb_painter.cpp
@@ -0,0 +1,1026 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013-2016 CERN
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <class_board.h>
+#include <class_track.h>
+#include <class_module.h>
+#include <class_pad.h>
+#include <class_drawsegment.h>
+#include <class_zone.h>
+#include <class_pcb_text.h>
+#include <class_colors_design_settings.h>
+#include <class_marker_pcb.h>
+#include <class_dimension.h>
+#include <class_mire.h>
+#include <class_marker_pcb.h>
+
+#include <pcb_painter.h>
+#include <gal/graphics_abstraction_layer.h>
+
+using namespace KIGFX;
+
+PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS()
+{
+ m_backgroundColor = COLOR4D( 0.0, 0.0, 0.0, 1.0 );
+ m_padNumbers = true;
+ m_netNamesOnPads = true;
+ m_netNamesOnTracks = true;
+ m_displayZoneMode = DZ_SHOW_FILLED;
+
+ // By default everything should be displayed as filled
+ for( unsigned int i = 0; i < TOTAL_LAYER_COUNT; ++i )
+ {
+ m_sketchMode[i] = false;
+ }
+
+ update();
+}
+
+
+void PCB_RENDER_SETTINGS::ImportLegacyColors( const COLORS_DESIGN_SETTINGS* aSettings )
+{
+ for( int i = 0; i < LAYER_ID_COUNT; i++ )
+ {
+ m_layerColors[i] = m_legacyColorMap[aSettings->GetLayerColor( i )];
+ }
+
+ for( int i = 0; i < END_PCB_VISIBLE_LIST; i++ )
+ {
+ m_layerColors[ITEM_GAL_LAYER( i )] = m_legacyColorMap[aSettings->GetItemColor( i )];
+ }
+
+ m_layerColors[ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE )] = m_layerColors[F_SilkS];
+ m_layerColors[ITEM_GAL_LAYER( MOD_TEXT_BK_VISIBLE )] = m_layerColors[B_SilkS];
+
+ // Default colors for specific layers
+ m_layerColors[ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE )] = COLOR4D( 0.5, 0.4, 0.0, 0.8 );
+ m_layerColors[ITEM_GAL_LAYER( PADS_HOLES_VISIBLE )] = COLOR4D( 0.0, 0.5, 0.5, 0.8 );
+ m_layerColors[ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE )] = COLOR4D( 0.6, 0.6, 0.6, 0.8 );
+ m_layerColors[ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE )] = COLOR4D( 0.6, 0.6, 0.6, 0.8 );
+ m_layerColors[ITEM_GAL_LAYER( VIA_MICROVIA_VISIBLE )] = COLOR4D( 0.4, 0.4, 0.8, 0.8 );
+ m_layerColors[ITEM_GAL_LAYER( PADS_VISIBLE )] = COLOR4D( 0.6, 0.6, 0.6, 0.8 );
+ m_layerColors[NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE )] = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
+ m_layerColors[NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE )] = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
+ m_layerColors[NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE )] = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
+ m_layerColors[ITEM_GAL_LAYER( ANCHOR_VISIBLE )] = COLOR4D( 0.3, 0.3, 1.0, 0.9 );
+ m_layerColors[ITEM_GAL_LAYER( RATSNEST_VISIBLE )] = COLOR4D( 0.4, 0.4, 0.4, 0.8 );
+ m_layerColors[ITEM_GAL_LAYER( WORKSHEET )] = COLOR4D( 0.5, 0.0, 0.0, 0.8 );
+ m_layerColors[ITEM_GAL_LAYER( DRC_VISIBLE )] = COLOR4D( 1.0, 0.0, 0.0, 0.8 );
+
+ // Netnames for copper layers
+ for( LSEQ cu = LSET::AllCuMask().CuStack(); cu; ++cu )
+ {
+ LAYER_ID layer = *cu;
+
+ m_layerColors[GetNetnameLayer( layer )] = COLOR4D( 0.8, 0.8, 0.8, 0.7 );
+ }
+
+ update();
+}
+
+
+void PCB_RENDER_SETTINGS::LoadDisplayOptions( const DISPLAY_OPTIONS* aOptions )
+{
+ if( aOptions == NULL )
+ return;
+
+ m_hiContrastEnabled = aOptions->m_ContrastModeDisplay;
+ m_padNumbers = aOptions->m_DisplayPadNum;
+
+ // Whether to draw tracks, vias & pads filled or as outlines
+ m_sketchMode[ITEM_GAL_LAYER( PADS_VISIBLE )] = !aOptions->m_DisplayPadFill;
+ m_sketchMode[ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE )] = !aOptions->m_DisplayViaFill;
+ m_sketchMode[ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE )] = !aOptions->m_DisplayViaFill;
+ m_sketchMode[ITEM_GAL_LAYER( VIA_MICROVIA_VISIBLE )] = !aOptions->m_DisplayViaFill;
+ m_sketchMode[ITEM_GAL_LAYER( TRACKS_VISIBLE )] = !aOptions->m_DisplayPcbTrackFill;
+
+ switch( aOptions->m_DisplayNetNamesMode )
+ {
+ case 0:
+ m_netNamesOnPads = false;
+ m_netNamesOnTracks = false;
+ break;
+
+ case 1:
+ m_netNamesOnPads = true;
+ m_netNamesOnTracks = false;
+ break;
+
+ case 2:
+ m_netNamesOnPads = false;
+ m_netNamesOnTracks = true;
+ break;
+
+ case 3:
+ m_netNamesOnPads = true;
+ m_netNamesOnTracks = true;
+ break;
+ }
+
+ switch( aOptions->m_DisplayZonesMode )
+ {
+ case 0:
+ m_displayZoneMode = DZ_SHOW_FILLED;
+ break;
+
+ case 1:
+ m_displayZoneMode = DZ_HIDE_FILLED;
+ break;
+
+ case 2:
+ m_displayZoneMode = DZ_SHOW_OUTLINED;
+ break;
+ }
+}
+
+
+const COLOR4D& PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const
+{
+ int netCode = -1;
+ const EDA_ITEM* item = static_cast<const EDA_ITEM*>( aItem );
+
+ if( item )
+ {
+ if( item->IsSelected() )
+ {
+ return m_layerColorsSel[aLayer];
+ }
+
+ // Try to obtain the netcode for the item
+ if( const BOARD_CONNECTED_ITEM* conItem = dyn_cast<const BOARD_CONNECTED_ITEM*> ( item ) )
+ netCode = conItem->GetNetCode();
+ }
+
+ // Single net highlight mode
+ if( m_highlightEnabled && netCode == m_highlightNetcode )
+ return m_layerColorsHi[aLayer];
+
+ // Return grayish color for non-highlighted layers in the high contrast mode
+ if( m_hiContrastEnabled && m_activeLayers.count( aLayer ) == 0 )
+ return m_hiContrastColor;
+
+ // Catch the case when highlight and high-contraste modes are enabled
+ // and we are drawing a not highlighted track
+ if( m_highlightEnabled )
+ return m_layerColorsDark[aLayer];
+
+ // No special modificators enabled
+ return m_layerColors[aLayer];
+}
+
+
+void PCB_RENDER_SETTINGS::update()
+{
+ RENDER_SETTINGS::update();
+
+ // Calculate darkened/highlighted variants of layer colors
+ for( int i = 0; i < TOTAL_LAYER_COUNT; i++ )
+ {
+ m_layerColorsHi[i] = m_layerColors[i].Brightened( m_highlightFactor );
+ m_layerColorsDark[i] = m_layerColors[i].Darkened( 1.0 - m_highlightFactor );
+ m_layerColorsSel[i] = m_layerColors[i].Brightened( m_selectFactor );
+ }
+}
+
+
+PCB_PAINTER::PCB_PAINTER( GAL* aGal ) :
+ PAINTER( aGal )
+{
+}
+
+
+bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
+{
+ const EDA_ITEM* item = static_cast<const EDA_ITEM*>( aItem );
+
+ // the "cast" applied in here clarifies which overloaded draw() is called
+ switch( item->Type() )
+ {
+ case PCB_ZONE_T:
+ case PCB_TRACE_T:
+ draw( static_cast<const TRACK*>( item ), aLayer );
+ break;
+
+ case PCB_VIA_T:
+ draw( static_cast<const VIA*>( item ), aLayer );
+ break;
+
+ case PCB_PAD_T:
+ draw( static_cast<const D_PAD*>( item ), aLayer );
+ break;
+
+ case PCB_LINE_T:
+ case PCB_MODULE_EDGE_T:
+ draw( static_cast<const DRAWSEGMENT*>( item ), aLayer );
+ break;
+
+ case PCB_TEXT_T:
+ draw( static_cast<const TEXTE_PCB*>( item ), aLayer );
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ draw( static_cast<const TEXTE_MODULE*>( item ), aLayer );
+ break;
+
+ case PCB_MODULE_T:
+ draw( static_cast<const MODULE*>( item ), aLayer );
+ break;
+
+ case PCB_ZONE_AREA_T:
+ draw( static_cast<const ZONE_CONTAINER*>( item ) );
+ break;
+
+ case PCB_DIMENSION_T:
+ draw( static_cast<const DIMENSION*>( item ), aLayer );
+ break;
+
+ case PCB_TARGET_T:
+ draw( static_cast<const PCB_TARGET*>( item ) );
+ break;
+
+ case PCB_MARKER_T:
+ draw( static_cast<const MARKER_PCB*>( item ) );
+ break;
+
+ default:
+ // Painter does not know how to draw the object
+ return false;
+ }
+
+ return true;
+}
+
+
+void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
+{
+ VECTOR2D start( aTrack->GetStart() );
+ VECTOR2D end( aTrack->GetEnd() );
+ int width = aTrack->GetWidth();
+
+ if( m_pcbSettings.m_netNamesOnTracks && IsNetnameLayer( aLayer ) )
+ {
+ // If there is a net name - display it on the track
+ if( aTrack->GetNetCode() > NETINFO_LIST::UNCONNECTED )
+ {
+ VECTOR2D line = ( end - start );
+ double length = line.EuclideanNorm();
+
+ // Check if the track is long enough to have a netname displayed
+ if( length < 10 * width )
+ return;
+
+ const wxString& netName = aTrack->GetShortNetname();
+ VECTOR2D textPosition = start + line / 2.0; // center of the track
+ double textOrientation = -atan( line.y / line.x );
+ double textSize = std::min( static_cast<double>( width ), length / netName.length() );
+
+ // Set a proper color for the label
+ const COLOR4D& color = m_pcbSettings.GetColor( aTrack, aTrack->GetLayer() );
+ const COLOR4D labelColor = m_pcbSettings.GetColor( NULL, aLayer );
+
+ if( color.GetBrightness() > 0.5 )
+ m_gal->SetStrokeColor( labelColor.Inverted() );
+ else
+ m_gal->SetStrokeColor( labelColor );
+
+ m_gal->SetLineWidth( width / 10.0 );
+ m_gal->SetBold( false );
+ m_gal->SetItalic( false );
+ m_gal->SetMirrored( false );
+ m_gal->SetGlyphSize( VECTOR2D( textSize * 0.7, textSize * 0.7 ) );
+ m_gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_CENTER );
+ m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_CENTER );
+ m_gal->StrokeText( netName, textPosition, textOrientation );
+ }
+ }
+ else if( IsCopperLayer( aLayer ) )
+ {
+ // Draw a regular track
+ const COLOR4D& color = m_pcbSettings.GetColor( aTrack, aLayer );
+ m_gal->SetStrokeColor( color );
+ m_gal->SetIsStroke( true );
+
+ if( m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( TRACKS_VISIBLE )] )
+ {
+ // Outline mode
+ m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
+ m_gal->SetIsFill( false );
+ }
+ else
+ {
+ // Filled mode
+ m_gal->SetFillColor( color );
+ m_gal->SetIsFill( true );
+ }
+
+ m_gal->DrawSegment( start, end, width );
+ }
+}
+
+
+void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
+{
+ VECTOR2D center( aVia->GetStart() );
+ double radius = 0.0;
+
+ // Only draw the via if at least one of the layers it crosses is being displayed
+ BOARD* brd = aVia->GetBoard( );
+ if( !( brd->GetVisibleLayers() & aVia->GetLayerSet() ).any() )
+ return;
+
+ // Choose drawing settings depending on if we are drawing via's pad or hole
+ if( aLayer == ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ) )
+ radius = aVia->GetDrillValue() / 2.0;
+ else
+ radius = aVia->GetWidth() / 2.0;
+
+ bool sketchMode = false;
+ const COLOR4D& color = m_pcbSettings.GetColor( aVia, aLayer );
+
+ switch( aVia->GetViaType() )
+ {
+ case VIA_THROUGH:
+ sketchMode = m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE )];
+ break;
+
+ case VIA_BLIND_BURIED:
+ sketchMode = m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE )];
+ break;
+
+ case VIA_MICROVIA:
+ sketchMode = m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( VIA_MICROVIA_VISIBLE )];
+ break;
+
+ default:
+ assert( false );
+ break;
+ }
+
+ if( aVia->GetViaType() == VIA_BLIND_BURIED )
+ {
+ LAYER_ID layerTop, layerBottom;
+ aVia->LayerPair( &layerTop, &layerBottom );
+
+ if( aLayer == ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ) )
+ { // TODO outline mode
+ m_gal->SetIsFill( true );
+ m_gal->SetIsStroke( false );
+ m_gal->SetFillColor( color );
+ m_gal->DrawCircle( center, radius );
+ }
+ else
+ {
+ double width = ( aVia->GetWidth() - aVia->GetDrillValue() ) / 2.0;
+
+ m_gal->SetLineWidth( width );
+ m_gal->SetIsFill( true );
+ m_gal->SetIsStroke( false );
+ m_gal->SetFillColor( color );
+
+ if( aLayer == layerTop )
+ {
+ m_gal->DrawArc( center, radius, 0.0, M_PI / 2.0 );
+ }
+ else if( aLayer == layerBottom )
+ {
+ m_gal->DrawArc( center, radius, M_PI, 3.0 * M_PI / 2.0 );
+ }
+ else if( aLayer == ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE ) )
+ {
+ m_gal->DrawArc( center, radius, M_PI / 2.0, M_PI );
+ m_gal->DrawArc( center, radius, 3.0 * M_PI / 2.0, 2.0 * M_PI );
+ }
+ }
+ }
+ else
+ {
+ m_gal->SetIsFill( !sketchMode );
+ m_gal->SetIsStroke( sketchMode );
+
+ if( sketchMode )
+ {
+ // Outline mode
+ m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
+ m_gal->SetStrokeColor( color );
+ }
+ else
+ {
+ // Filled mode
+ m_gal->SetFillColor( color );
+ }
+
+ m_gal->DrawCircle( center, radius );
+ }
+}
+
+
+void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
+{
+ VECTOR2D size;
+ VECTOR2D position( aPad->GetPosition() );
+ PAD_SHAPE_T shape;
+ double m, n;
+ double orientation = aPad->GetOrientation();
+ wxString buffer;
+
+ // Draw description layer
+ if( IsNetnameLayer( aLayer ) )
+ {
+ // Is anything that we can display enabled?
+ if( m_pcbSettings.m_netNamesOnPads || m_pcbSettings.m_padNumbers )
+ {
+ // Min char count to calculate string size
+ const int MIN_CHAR_COUNT = 3;
+
+ bool displayNetname = ( m_pcbSettings.m_netNamesOnPads &&
+ !aPad->GetNetname().empty() );
+ VECTOR2D padsize = VECTOR2D( aPad->GetSize() );
+ double maxSize = PCB_RENDER_SETTINGS::MAX_FONT_SIZE;
+ double size = padsize.y;
+
+ // Keep the size ratio for the font, but make it smaller
+ if( padsize.x < padsize.y )
+ {
+ orientation += 900.0;
+ size = padsize.x;
+ std::swap( padsize.x, padsize.y );
+ }
+ else if( padsize.x == padsize.y )
+ {
+ // If the text is displayed on a symmetrical pad, do not rotate it
+ orientation = 0.0;
+ }
+
+ // Font size limits
+ if( size > maxSize )
+ size = maxSize;
+
+ m_gal->Save();
+ m_gal->Translate( position );
+
+ // do not display descriptions upside down
+ NORMALIZE_ANGLE_90( orientation );
+ m_gal->Rotate( -orientation * M_PI / 1800.0 );
+
+ // Default font settings
+ m_gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_CENTER );
+ m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_CENTER );
+ m_gal->SetBold( false );
+ m_gal->SetItalic( false );
+ m_gal->SetMirrored( false );
+
+ // Set a proper color for the label
+ const COLOR4D& color = m_pcbSettings.GetColor( aPad, aPad->GetLayer() );
+ const COLOR4D labelColor = m_pcbSettings.GetColor( NULL, aLayer );
+
+ if( color.GetBrightness() > 0.5 )
+ m_gal->SetStrokeColor( labelColor.Inverted() );
+ else
+ m_gal->SetStrokeColor( labelColor );
+
+ VECTOR2D textpos( 0.0, 0.0);
+
+ // Divide the space, to display both pad numbers and netnames
+ // and set the Y text position to display 2 lines
+ if( displayNetname && m_pcbSettings.m_padNumbers )
+ {
+ size = size / 2.0;
+ textpos.y = size / 2.0;
+ }
+
+ if( displayNetname )
+ {
+ // calculate the size of net name text:
+ double tsize = padsize.x / aPad->GetShortNetname().Length();
+ tsize = std::min( tsize, size );
+ // Use a smaller text size to handle interline, pen size..
+ tsize *= 0.7;
+ VECTOR2D namesize( tsize, tsize );
+ m_gal->SetGlyphSize( namesize );
+ m_gal->SetLineWidth( namesize.x / 12.0 );
+ m_gal->StrokeText( aPad->GetShortNetname(), textpos, 0.0 );
+ }
+
+ if( m_pcbSettings.m_padNumbers )
+ {
+ textpos.y = -textpos.y;
+ aPad->StringPadName( buffer );
+ int len = buffer.Length();
+ double tsize = padsize.x / std::max( len, MIN_CHAR_COUNT );
+ tsize = std::min( tsize, size );
+ // Use a smaller text size to handle interline, pen size..
+ tsize *= 0.7;
+ tsize = std::min( tsize, size );
+ VECTOR2D numsize( tsize, tsize );
+
+ m_gal->SetGlyphSize( numsize );
+ m_gal->SetLineWidth( numsize.x / 12.0 );
+ m_gal->StrokeText( aPad->GetPadName(), textpos, 0.0 );
+ }
+
+ m_gal->Restore();
+ }
+ return;
+ }
+
+ // Pad drawing
+ const COLOR4D& color = m_pcbSettings.GetColor( aPad, aLayer );
+ if( m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( PADS_VISIBLE )] )
+ {
+ // Outline mode
+ m_gal->SetIsFill( false );
+ m_gal->SetIsStroke( true );
+ m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
+ m_gal->SetStrokeColor( color );
+ }
+ else
+ {
+ // Filled mode
+ m_gal->SetIsFill( true );
+ m_gal->SetIsStroke( false );
+ m_gal->SetFillColor( color );
+ }
+
+ m_gal->Save();
+ m_gal->Translate( VECTOR2D( aPad->GetPosition() ) );
+ m_gal->Rotate( -aPad->GetOrientation() * M_PI / 1800.0 );
+
+ // Choose drawing settings depending on if we are drawing a pad itself or a hole
+ if( aLayer == ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ) )
+ {
+ // Drawing hole: has same shape as PAD_CIRCLE or PAD_OVAL
+ size = VECTOR2D( aPad->GetDrillSize() ) / 2.0;
+ shape = aPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ? PAD_SHAPE_OVAL : PAD_SHAPE_CIRCLE;
+ }
+ else if( aLayer == F_Mask || aLayer == B_Mask )
+ {
+ // Drawing soldermask
+ int soldermaskMargin = aPad->GetSolderMaskMargin();
+
+ m_gal->Translate( VECTOR2D( aPad->GetOffset() ) );
+ size = VECTOR2D( aPad->GetSize().x / 2.0 + soldermaskMargin,
+ aPad->GetSize().y / 2.0 + soldermaskMargin );
+ shape = aPad->GetShape();
+ }
+ else if( aLayer == F_Paste || aLayer == B_Paste )
+ {
+ // Drawing solderpaste
+ wxSize solderpasteMargin = aPad->GetSolderPasteMargin();
+
+ m_gal->Translate( VECTOR2D( aPad->GetOffset() ) );
+ size = VECTOR2D( aPad->GetSize().x / 2.0 + solderpasteMargin.x,
+ aPad->GetSize().y / 2.0 + solderpasteMargin.y );
+ shape = aPad->GetShape();
+ }
+ else
+ {
+ // Drawing every kind of pad
+ m_gal->Translate( VECTOR2D( aPad->GetOffset() ) );
+ size = VECTOR2D( aPad->GetSize() ) / 2.0;
+ shape = aPad->GetShape();
+ }
+
+ switch( shape )
+ {
+ case PAD_SHAPE_OVAL:
+ if( size.y >= size.x )
+ {
+ m = ( size.y - size.x );
+ n = size.x;
+
+ if( m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( PADS_VISIBLE )] )
+ {
+ // Outline mode
+ m_gal->DrawArc( VECTOR2D( 0, -m ), n, -M_PI, 0 );
+ m_gal->DrawArc( VECTOR2D( 0, m ), n, M_PI, 0 );
+ m_gal->DrawLine( VECTOR2D( -n, -m ), VECTOR2D( -n, m ) );
+ m_gal->DrawLine( VECTOR2D( n, -m ), VECTOR2D( n, m ) );
+ }
+ else
+ {
+ // Filled mode
+ m_gal->DrawCircle( VECTOR2D( 0, -m ), n );
+ m_gal->DrawCircle( VECTOR2D( 0, m ), n );
+ m_gal->DrawRectangle( VECTOR2D( -n, -m ), VECTOR2D( n, m ) );
+ }
+ }
+ else
+ {
+ m = ( size.x - size.y );
+ n = size.y;
+
+ if( m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( PADS_VISIBLE )] )
+ {
+ // Outline mode
+ m_gal->DrawArc( VECTOR2D( -m, 0 ), n, M_PI / 2, 3 * M_PI / 2 );
+ m_gal->DrawArc( VECTOR2D( m, 0 ), n, M_PI / 2, -M_PI / 2 );
+ m_gal->DrawLine( VECTOR2D( -m, -n ), VECTOR2D( m, -n ) );
+ m_gal->DrawLine( VECTOR2D( -m, n ), VECTOR2D( m, n ) );
+ }
+ else
+ {
+ // Filled mode
+ m_gal->DrawCircle( VECTOR2D( -m, 0 ), n );
+ m_gal->DrawCircle( VECTOR2D( m, 0 ), n );
+ m_gal->DrawRectangle( VECTOR2D( -m, -n ), VECTOR2D( m, n ) );
+ }
+ }
+ break;
+
+ case PAD_SHAPE_RECT:
+ m_gal->DrawRectangle( VECTOR2D( -size.x, -size.y ), VECTOR2D( size.x, size.y ) );
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ {
+ std::deque<VECTOR2D> pointList;
+ wxPoint corners[4];
+
+ VECTOR2D padSize = VECTOR2D( aPad->GetSize().x, aPad->GetSize().y ) / 2;
+ VECTOR2D deltaPadSize = size - padSize; // = solder[Paste/Mask]Margin or 0
+
+ aPad->BuildPadPolygon( corners, wxSize( deltaPadSize.x, deltaPadSize.y ), 0.0 );
+ pointList.push_back( VECTOR2D( corners[0] ) );
+ pointList.push_back( VECTOR2D( corners[1] ) );
+ pointList.push_back( VECTOR2D( corners[2] ) );
+ pointList.push_back( VECTOR2D( corners[3] ) );
+
+ if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] )
+ {
+ // Add the beginning point to close the outline
+ pointList.push_back( pointList.front() );
+ m_gal->DrawPolyline( pointList );
+ }
+ else
+ {
+ m_gal->DrawPolygon( pointList );
+ }
+ }
+ break;
+
+ case PAD_SHAPE_CIRCLE:
+ m_gal->DrawCircle( VECTOR2D( 0.0, 0.0 ), size.x );
+ break;
+ }
+
+ m_gal->Restore();
+}
+
+
+void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
+{
+ const COLOR4D& color = m_pcbSettings.GetColor( aSegment, aSegment->GetLayer() );
+
+ m_gal->SetIsFill( false );
+ m_gal->SetIsStroke( true );
+ m_gal->SetStrokeColor( color );
+
+ if( m_pcbSettings.m_sketchMode[aLayer] )
+ m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); // Outline mode
+ else
+ m_gal->SetLineWidth( aSegment->GetWidth() ); // Filled mode
+
+ switch( aSegment->GetShape() )
+ {
+ case S_SEGMENT:
+ m_gal->DrawLine( VECTOR2D( aSegment->GetStart() ), VECTOR2D( aSegment->GetEnd() ) );
+ break;
+
+ case S_RECT:
+ wxASSERT_MSG( false, wxT( "Not tested yet" ) );
+ m_gal->DrawRectangle( VECTOR2D( aSegment->GetStart() ), VECTOR2D( aSegment->GetEnd() ) );
+ break;
+
+ case S_ARC:
+ m_gal->DrawArc( VECTOR2D( aSegment->GetCenter() ), aSegment->GetRadius(),
+ aSegment->GetArcAngleStart() * M_PI / 1800.0,
+ ( aSegment->GetArcAngleStart() + aSegment->GetAngle() ) * M_PI / 1800.0 );
+ break;
+
+ case S_CIRCLE:
+ m_gal->DrawCircle( VECTOR2D( aSegment->GetCenter() ), aSegment->GetRadius() );
+ break;
+
+ case S_POLYGON:
+ {
+ std::deque<VECTOR2D> pointsList;
+
+ m_gal->SetIsFill( true );
+ m_gal->SetIsStroke( false );
+ m_gal->SetFillColor( color );
+
+ m_gal->Save();
+
+ MODULE* module = aSegment->GetParentModule();
+ if( module )
+ {
+ m_gal->Translate( module->GetPosition() );
+ m_gal->Rotate( -module->GetOrientation() * M_PI / 1800.0 );
+ }
+ else
+ {
+ // not tested
+ m_gal->Translate( aSegment->GetPosition() );
+ m_gal->Rotate( -aSegment->GetAngle() * M_PI / 1800.0 );
+ }
+
+ std::copy( aSegment->GetPolyPoints().begin(), aSegment->GetPolyPoints().end(),
+ std::back_inserter( pointsList ) );
+
+ m_gal->SetLineWidth( aSegment->GetWidth() );
+ m_gal->DrawPolyline( pointsList );
+ m_gal->DrawPolygon( pointsList );
+
+ m_gal->Restore();
+ break;
+ }
+
+ case S_CURVE:
+ m_gal->DrawCurve( VECTOR2D( aSegment->GetStart() ),
+ VECTOR2D( aSegment->GetBezControl1() ),
+ VECTOR2D( aSegment->GetBezControl2() ),
+ VECTOR2D( aSegment->GetEnd() ) );
+ break;
+
+ case S_LAST:
+ break;
+ }
+}
+
+
+void PCB_PAINTER::draw( const TEXTE_PCB* aText, int aLayer )
+{
+ wxString shownText( aText->GetShownText() );
+ if( shownText.Length() == 0 )
+ return;
+
+ const COLOR4D& color = m_pcbSettings.GetColor( aText, aText->GetLayer() );
+ VECTOR2D position( aText->GetTextPosition().x, aText->GetTextPosition().y );
+ double orientation = aText->GetOrientation() * M_PI / 1800.0;
+
+ if( m_pcbSettings.m_sketchMode[aLayer] )
+ {
+ // Outline mode
+ m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
+ }
+ else
+ {
+ // Filled mode
+ m_gal->SetLineWidth( aText->GetThickness() );
+ }
+
+ m_gal->SetIsFill( false );
+ m_gal->SetIsStroke( true );
+ m_gal->SetStrokeColor( color );
+ m_gal->SetTextAttributes( aText );
+ m_gal->StrokeText( shownText, position, orientation );
+}
+
+
+void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer )
+{
+ wxString shownText( aText->GetShownText() );
+ if( shownText.Length() == 0 )
+ return;
+
+ const COLOR4D& color = m_pcbSettings.GetColor( aText, aLayer );
+ VECTOR2D position( aText->GetTextPosition().x, aText->GetTextPosition().y );
+ double orientation = aText->GetDrawRotation() * M_PI / 1800.0;
+
+ if( m_pcbSettings.m_sketchMode[aLayer] )
+ {
+ // Outline mode
+ m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
+ }
+ else
+ {
+ // Filled mode
+ m_gal->SetLineWidth( aText->GetThickness() );
+ }
+
+ m_gal->SetIsFill( false );
+ m_gal->SetIsStroke( true );
+ m_gal->SetStrokeColor( color );
+ m_gal->SetTextAttributes( aText );
+ m_gal->StrokeText( shownText, position, orientation );
+
+ // Draw the umbilical line
+ if( aText->IsSelected() && aText->GetType() != TEXTE_MODULE::TEXT_is_DIVERS )
+ {
+ m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
+ m_gal->SetStrokeColor( COLOR4D( 0.0, 0.0, 1.0, 1.0 ) );
+ m_gal->DrawLine( position, aText->GetParent()->GetPosition() );
+ }
+}
+
+
+void PCB_PAINTER::draw( const MODULE* aModule, int aLayer )
+{
+ if( aLayer == ITEM_GAL_LAYER( ANCHOR_VISIBLE ) )
+ {
+ const COLOR4D color = m_pcbSettings.GetColor( aModule, ITEM_GAL_LAYER( ANCHOR_VISIBLE ) );
+
+ // Draw anchor
+ m_gal->SetStrokeColor( color );
+ m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
+
+ // Keep the size constant, not related to the scale
+ double anchorSize = 5.0 / m_gal->GetWorldScale();
+
+ VECTOR2D center = aModule->GetPosition();
+ m_gal->DrawLine( center - VECTOR2D( anchorSize, 0 ), center + VECTOR2D( anchorSize, 0 ) );
+ m_gal->DrawLine( center - VECTOR2D( 0, anchorSize ), center + VECTOR2D( 0, anchorSize ) );
+ }
+}
+
+
+void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone )
+{
+ const COLOR4D& color = m_pcbSettings.GetColor( aZone, aZone->GetLayer() );
+ std::deque<VECTOR2D> corners;
+ PCB_RENDER_SETTINGS::DisplayZonesMode displayMode = m_pcbSettings.m_displayZoneMode;
+
+ // Draw the outline
+ m_gal->SetStrokeColor( color );
+ m_gal->SetIsFill( false );
+ m_gal->SetIsStroke( true );
+ m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
+
+ const CPolyLine* outline = aZone->Outline();
+ for( int i = 0; i < outline->GetCornersCount(); ++i )
+ {
+ corners.push_back( VECTOR2D( outline->GetPos( i ) ) );
+
+ if( outline->IsEndContour( i ) )
+ {
+ // The last point for closing the polyline
+ corners.push_back( corners[0] );
+ m_gal->DrawPolyline( corners );
+ corners.clear();
+ }
+ }
+
+ // Draw the filling
+ if( displayMode != PCB_RENDER_SETTINGS::DZ_HIDE_FILLED )
+ {
+ const SHAPE_POLY_SET& polySet = aZone->GetFilledPolysList();
+
+ if( polySet.OutlineCount() == 0 ) // Nothing to draw
+ return;
+
+ // Set up drawing options
+ m_gal->SetFillColor( color );
+ m_gal->SetLineWidth( aZone->GetMinThickness() );
+
+ if( displayMode == PCB_RENDER_SETTINGS::DZ_SHOW_FILLED )
+ {
+ m_gal->SetIsFill( true );
+ m_gal->SetIsStroke( true );
+ }
+ else if( displayMode == PCB_RENDER_SETTINGS::DZ_SHOW_OUTLINED )
+ {
+ m_gal->SetIsFill( false );
+ m_gal->SetIsStroke( true );
+ }
+
+ for( int i = 0; i < polySet.OutlineCount(); i++ )
+ {
+ const SHAPE_LINE_CHAIN& outline = polySet.COutline( i );
+ // fixme: GAL drawing API that accepts SHAPEs directly (this fiddling with double<>int conversion
+ // is just a performance hog)
+
+ for( int j = 0; j < outline.PointCount(); j++ )
+ corners.push_back ( (VECTOR2D) outline.CPoint( j ) );
+
+ corners.push_back( (VECTOR2D) outline.CPoint( 0 ) );
+
+ if( displayMode == PCB_RENDER_SETTINGS::DZ_SHOW_FILLED )
+ {
+ m_gal->DrawPolygon( corners );
+ m_gal->DrawPolyline( corners );
+ }
+ else if( displayMode == PCB_RENDER_SETTINGS::DZ_SHOW_OUTLINED )
+ {
+ m_gal->DrawPolyline( corners );
+ }
+
+ corners.clear();
+ }
+ }
+}
+
+
+void PCB_PAINTER::draw( const DIMENSION* aDimension, int aLayer )
+{
+ const COLOR4D& strokeColor = m_pcbSettings.GetColor( aDimension, aLayer );
+
+ m_gal->SetStrokeColor( strokeColor );
+ m_gal->SetIsFill( false );
+ m_gal->SetIsStroke( true );
+ m_gal->SetLineWidth( aDimension->GetWidth() );
+
+ // Draw an arrow
+ m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarO ), VECTOR2D( aDimension->m_crossBarF ) );
+ m_gal->DrawLine( VECTOR2D( aDimension->m_featureLineGO ),
+ VECTOR2D( aDimension->m_featureLineGF ) );
+ m_gal->DrawLine( VECTOR2D( aDimension->m_featureLineDO ),
+ VECTOR2D( aDimension->m_featureLineDF ) );
+ m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarF ), VECTOR2D( aDimension->m_arrowD1F ) );
+ m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarF ), VECTOR2D( aDimension->m_arrowD2F ) );
+ m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarO ), VECTOR2D( aDimension->m_arrowG1F ) );
+ m_gal->DrawLine( VECTOR2D( aDimension->m_crossBarO ), VECTOR2D( aDimension->m_arrowG2F ) );
+
+ // Draw text
+ TEXTE_PCB& text = aDimension->Text();
+ VECTOR2D position( text.GetTextPosition().x, text.GetTextPosition().y );
+ double orientation = text.GetOrientation() * M_PI / 1800.0;
+
+ m_gal->SetLineWidth( text.GetThickness() );
+ m_gal->SetTextAttributes( &text );
+ m_gal->StrokeText( text.GetShownText(), position, orientation );
+}
+
+
+void PCB_PAINTER::draw( const PCB_TARGET* aTarget )
+{
+ const COLOR4D& strokeColor = m_pcbSettings.GetColor( aTarget, aTarget->GetLayer() );
+ VECTOR2D position( aTarget->GetPosition() );
+ double size, radius;
+
+ m_gal->SetLineWidth( aTarget->GetWidth() );
+ m_gal->SetStrokeColor( strokeColor );
+ m_gal->SetIsFill( false );
+ m_gal->SetIsStroke( true );
+
+ m_gal->Save();
+ m_gal->Translate( position );
+
+ if( aTarget->GetShape() )
+ {
+ // shape x
+ m_gal->Rotate( M_PI / 4.0 );
+ size = 2.0 * aTarget->GetSize() / 3.0;
+ radius = aTarget->GetSize() / 2.0;
+ }
+ else
+ {
+ // shape +
+ size = aTarget->GetSize() / 2.0;
+ radius = aTarget->GetSize() / 3.0;
+ }
+
+ m_gal->DrawLine( VECTOR2D( -size, 0.0 ), VECTOR2D( size, 0.0 ) );
+ m_gal->DrawLine( VECTOR2D( 0.0, -size ), VECTOR2D( 0.0, size ) );
+ m_gal->DrawCircle( VECTOR2D( 0.0, 0.0 ), radius );
+
+ m_gal->Restore();
+}
+
+
+void PCB_PAINTER::draw( const MARKER_PCB* aMarker )
+{
+ const int scale = 100000;
+ const VECTOR2D arrow[] = {
+ VECTOR2D( 0 * scale, 0 * scale ),
+ VECTOR2D( 8 * scale, 1 * scale ),
+ VECTOR2D( 4 * scale, 3 * scale ),
+ VECTOR2D( 13 * scale, 8 * scale ),
+ VECTOR2D( 9 * scale, 9 * scale ),
+ VECTOR2D( 8 * scale, 13 * scale ),
+ VECTOR2D( 3 * scale, 4 * scale ),
+ VECTOR2D( 1 * scale, 8 * scale )
+ };
+
+ m_gal->Save();
+ m_gal->Translate( aMarker->GetPosition() );
+ m_gal->SetFillColor( COLOR4D( 1.0, 0.0, 0.0, 1.0 ) );
+ m_gal->SetIsFill( true );
+ m_gal->SetIsStroke( false );
+ m_gal->DrawPolygon( arrow, sizeof( arrow ) / sizeof( VECTOR2D ) );
+ m_gal->Restore();
+}
+
+
+const double PCB_RENDER_SETTINGS::MAX_FONT_SIZE = Millimeter2iu( 10.0 );
diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h
new file mode 100644
index 0000000..c6ea211
--- /dev/null
+++ b/pcbnew/pcb_painter.h
@@ -0,0 +1,219 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 CERN
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __CLASS_PCB_PAINTER_H
+#define __CLASS_PCB_PAINTER_H
+
+#include <layers_id_colors_and_visibility.h>
+#include <boost/shared_ptr.hpp>
+#include <painter.h>
+
+
+class EDA_ITEM;
+class COLORS_DESIGN_SETTINGS;
+class DISPLAY_OPTIONS;
+
+class BOARD_ITEM;
+class BOARD;
+class VIA;
+class TRACK;
+class D_PAD;
+class DRAWSEGMENT;
+class MODULE;
+class SEGZONE;
+class ZONE_CONTAINER;
+class TEXTE_PCB;
+class TEXTE_MODULE;
+class DIMENSION;
+class PCB_TARGET;
+class MARKER_PCB;
+
+namespace KIGFX
+{
+class GAL;
+
+/**
+ * Class PCB_RENDER_SETTINGS
+ * Stores PCB specific render settings.
+ */
+class PCB_RENDER_SETTINGS : public RENDER_SETTINGS
+{
+public:
+ friend class PCB_PAINTER;
+
+ enum ClearanceMode {
+ CL_VIAS = 0x1,
+ CL_PADS = 0x2,
+ CL_TRACKS = 0x4
+ };
+
+ ///> Determines how zones should be displayed
+ enum DisplayZonesMode {
+ DZ_HIDE_FILLED = 0,
+ DZ_SHOW_FILLED,
+ DZ_SHOW_OUTLINED
+ };
+
+ PCB_RENDER_SETTINGS();
+
+ /// @copydoc RENDER_SETTINGS::ImportLegacyColors()
+ void ImportLegacyColors( const COLORS_DESIGN_SETTINGS* aSettings );
+
+ /**
+ * Function LoadDisplayOptions
+ * Loads settings related to display options (high-contrast mode, full or outline modes
+ * for vias/pads/tracks and so on).
+ * @param aOptions are settings that you want to use for displaying items.
+ */
+ void LoadDisplayOptions( const DISPLAY_OPTIONS* aOptions );
+
+ /// @copydoc RENDER_SETTINGS::GetColor()
+ virtual const COLOR4D& GetColor( const VIEW_ITEM* aItem, int aLayer ) const;
+
+ /**
+ * Function GetLayerColor
+ * Returns the color used to draw a layer.
+ * @param aLayer is the layer number.
+ */
+ inline const COLOR4D& GetLayerColor( int aLayer ) const
+ {
+ return m_layerColors[aLayer];
+ }
+
+ /**
+ * Function SetLayerColor
+ * Changes the color used to draw a layer.
+ * @param aLayer is the layer number.
+ * @param aColor is the new color.
+ */
+ inline void SetLayerColor( int aLayer, const COLOR4D& aColor )
+ {
+ m_layerColors[aLayer] = aColor;
+
+ update(); // recompute other shades of the color
+ }
+
+ /**
+ * Function SetSketchMode
+ * Turns on/off sketch mode for given item layer.
+ * @param aItemLayer is the item layer that is changed.
+ * @param aEnabled decides if it is drawn in sketch mode (true for sketched mode,
+ * false for filled mode).
+ */
+ inline void SetSketchMode( int aItemLayer, bool aEnabled )
+ {
+ m_sketchMode[aItemLayer] = aEnabled;
+ }
+
+ /**
+ * Function GetSketchMode
+ * Returns sketch mode setting for a given item layer.
+ * @param aItemLayer is the item layer that is changed.
+ */
+ inline bool GetSketchMode( int aItemLayer ) const
+ {
+ return m_sketchMode[aItemLayer];
+ }
+
+protected:
+ ///> @copydoc RENDER_SETTINGS::Update()
+ void update();
+
+ ///> Colors for all layers (normal)
+ COLOR4D m_layerColors[TOTAL_LAYER_COUNT];
+
+ ///> Colors for all layers (highlighted)
+ COLOR4D m_layerColorsHi[TOTAL_LAYER_COUNT];
+
+ ///> Colors for all layers (selected)
+ COLOR4D m_layerColorsSel[TOTAL_LAYER_COUNT];
+
+ ///> Colors for all layers (darkened)
+ COLOR4D m_layerColorsDark[TOTAL_LAYER_COUNT];
+
+ ///> Flag determining if items on a given layer should be drawn as an outline or a filled item
+ bool m_sketchMode[TOTAL_LAYER_COUNT];
+
+ ///> Flag determining if pad numbers should be visible
+ bool m_padNumbers;
+
+ ///> Flag determining if net names should be visible for pads
+ bool m_netNamesOnPads;
+
+ ///> Flag determining if net names should be visible for tracks
+ bool m_netNamesOnTracks;
+
+ ///> Maximum font size for netnames (and other dynamically shown strings)
+ static const double MAX_FONT_SIZE;
+
+ ///> Option for different display modes for zones
+ DisplayZonesMode m_displayZoneMode;
+};
+
+
+/**
+ * Class PCB_PAINTER
+ * Contains methods for drawing PCB-specific items.
+ */
+class PCB_PAINTER : public PAINTER
+{
+public:
+ PCB_PAINTER( GAL* aGal );
+
+ /// @copydoc PAINTER::ApplySettings()
+ virtual void ApplySettings( const RENDER_SETTINGS* aSettings )
+ {
+ m_pcbSettings = *static_cast<const PCB_RENDER_SETTINGS*>( aSettings );
+ }
+
+ /// @copydoc PAINTER::GetSettings()
+ virtual RENDER_SETTINGS* GetSettings()
+ {
+ return &m_pcbSettings;
+ }
+
+ /// @copydoc PAINTER::Draw()
+ virtual bool Draw( const VIEW_ITEM* aItem, int aLayer );
+
+protected:
+ PCB_RENDER_SETTINGS m_pcbSettings;
+
+ // Drawing functions for various types of PCB-specific items
+ void draw( const TRACK* aTrack, int aLayer );
+ void draw( const VIA* aVia, int aLayer );
+ void draw( const D_PAD* aPad, int aLayer );
+ void draw( const DRAWSEGMENT* aSegment, int aLayer );
+ void draw( const TEXTE_PCB* aText, int aLayer );
+ void draw( const TEXTE_MODULE* aText, int aLayer );
+ void draw( const MODULE* aModule, int aLayer );
+ void draw( const ZONE_CONTAINER* aZone );
+ void draw( const DIMENSION* aDimension, int aLayer );
+ void draw( const PCB_TARGET* aTarget );
+ void draw( const MARKER_PCB* aMarker );
+};
+} // namespace KIGFX
+
+#endif /* __CLASS_PAINTER_H */
+
diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp
new file mode 100644
index 0000000..45d6c69
--- /dev/null
+++ b/pcbnew/pcb_parser.cpp
@@ -0,0 +1,3073 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 CERN
+ * Copyright (C) 2012-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_parser.cpp
+ * @brief Pcbnew s-expression file format parser implementation.
+ */
+
+#include <errno.h>
+#include <common.h>
+#include <confirm.h>
+#include <macros.h>
+#include <convert_from_iu.h>
+#include <trigo.h>
+#include <3d_struct.h>
+#include <class_title_block.h>
+
+#include <class_board.h>
+#include <class_dimension.h>
+#include <class_drawsegment.h>
+#include <class_edge_mod.h>
+#include <class_mire.h>
+#include <class_module.h>
+#include <class_netclass.h>
+#include <class_pad.h>
+#include <class_track.h>
+#include <class_zone.h>
+#include <kicad_plugin.h>
+#include <pcb_plot_params_parser.h>
+#include <pcb_plot_params.h>
+#include <zones.h>
+#include <pcb_parser.h>
+
+#include <boost/make_shared.hpp>
+
+using namespace PCB_KEYS_T;
+
+
+void PCB_PARSER::init()
+{
+ m_tooRecent = false;
+ m_requiredVersion = 0;
+ m_layerIndices.clear();
+ m_layerMasks.clear();
+
+ // Add untranslated default (i.e. english) layernames.
+ // Some may be overridden later if parsing a board rather than a footprint.
+ // The english name will survive if parsing only a footprint.
+ for( LAYER_NUM layer = 0; layer < LAYER_ID_COUNT; ++layer )
+ {
+ std::string untranslated = TO_UTF8( wxString( LSET::Name( LAYER_ID( layer ) ) ) );
+
+ m_layerIndices[ untranslated ] = LAYER_ID( layer );
+ m_layerMasks[ untranslated ] = LSET( LAYER_ID( layer ) );
+ }
+
+ m_layerMasks[ "*.Cu" ] = LSET::AllCuMask();
+ m_layerMasks[ "F&B.Cu" ] = LSET( 2, F_Cu, B_Cu );
+ m_layerMasks[ "*.Adhes" ] = LSET( 2, B_Adhes, F_Adhes );
+ m_layerMasks[ "*.Paste" ] = LSET( 2, B_Paste, F_Paste );
+ m_layerMasks[ "*.Mask" ] = LSET( 2, B_Mask, F_Mask );
+ m_layerMasks[ "*.SilkS" ] = LSET( 2, B_SilkS, F_SilkS );
+ m_layerMasks[ "*.Fab" ] = LSET( 2, B_Fab, F_Fab );
+ m_layerMasks[ "*.CrtYd" ] = LSET( 2, B_CrtYd, F_CrtYd );
+
+ // This is for the first pretty & *.kicad_pcb formats, which had
+ // Inner1_Cu - Inner14_Cu with the numbering sequence
+ // reversed from the subsequent format's In1_Cu - In30_Cu numbering scheme.
+ // The newer format brought in an additional 16 Cu layers and flipped the cu stack but
+ // kept the gap between one of the outside layers and the last cu internal.
+
+ for( int i=1; i<=14; ++i )
+ {
+ std::string key = StrPrintf( "Inner%d.Cu", i );
+
+ m_layerMasks[ key ] = LSET( LAYER_ID( In15_Cu - i ) );
+ }
+
+#if defined(DEBUG) && 0
+ printf( "m_layerMasks:\n" );
+ for( LSET_MAP::const_iterator it = m_layerMasks.begin(); it != m_layerMasks.end(); ++it )
+ {
+ printf( " [%s] == 0x%s\n", it->first.c_str(), it->second.FmtHex().c_str() );
+ }
+
+ printf( "m_layerIndices:\n" );
+ for( LAYER_ID_MAP::const_iterator it = m_layerIndices.begin(); it != m_layerIndices.end(); ++it )
+ {
+ printf( " [%s] == %d\n", it->first.c_str(), it->second );
+ }
+#endif
+
+}
+
+
+void PCB_PARSER::pushValueIntoMap( int aIndex, int aValue )
+{
+ // Add aValue in netcode mapping (m_netCodes) at index aNetCode
+ // ensure there is room in m_netCodes for that, and add room if needed.
+
+ if( (int)m_netCodes.size() <= aIndex )
+ m_netCodes.resize( aIndex+1 );
+
+ m_netCodes[aIndex] = aValue;
+}
+
+double PCB_PARSER::parseDouble() throw( IO_ERROR )
+{
+ char* tmp;
+
+ errno = 0;
+
+ double fval = strtod( CurText(), &tmp );
+
+ if( errno )
+ {
+ wxString error;
+ error.Printf( _( "invalid floating point number in\nfile: <%s>\nline: %d\noffset: %d" ),
+ GetChars( CurSource() ), CurLineNumber(), CurOffset() );
+
+ THROW_IO_ERROR( error );
+ }
+
+ if( CurText() == tmp )
+ {
+ wxString error;
+ error.Printf( _( "missing floating point number in\nfile: <%s>\nline: %d\noffset: %d" ),
+ GetChars( CurSource() ), CurLineNumber(), CurOffset() );
+
+ THROW_IO_ERROR( error );
+ }
+
+ return fval;
+}
+
+
+bool PCB_PARSER::parseBool() throw( PARSE_ERROR )
+{
+ T token = NextTok();
+
+ if( token == T_yes )
+ return true;
+ else if( token == T_no )
+ return false;
+ else
+ Expecting( "yes or no" );
+
+ return false;
+}
+
+
+int PCB_PARSER::parseVersion() throw( IO_ERROR, PARSE_ERROR )
+{
+ if( NextTok() != T_version )
+ Expecting( GetTokenText( T_version ) );
+
+ int pcb_version = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
+
+ NeedRIGHT();
+
+ return pcb_version;
+}
+
+
+wxString PCB_PARSER::GetRequiredVersion()
+{
+ int year, month, day;
+
+ year = m_requiredVersion / 10000;
+ month = ( m_requiredVersion / 100 ) - ( year * 100 );
+ day = m_requiredVersion - ( year * 10000 ) - ( month * 100 );
+
+ // wx throws an assertion, not a catchable exception, when the date is invalid.
+ // User input shouldn't give wx asserts, so check manually and throw a proper
+ // error instead
+ if( day <= 0 || month <= 0 || month > 12 ||
+ day > wxDateTime::GetNumberOfDays( (wxDateTime::Month)( month - 1 ), year ) )
+ {
+ wxString err;
+ err.Printf( _( "cannot interpret date code %d" ), m_requiredVersion );
+ THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
+ }
+
+ wxDateTime date( day, (wxDateTime::Month)( month - 1 ), year, 0, 0, 0, 0 );
+ return date.FormatDate();
+}
+
+
+wxPoint PCB_PARSER::parseXY() throw( PARSE_ERROR, IO_ERROR )
+{
+ if( CurTok() != T_LEFT )
+ NeedLEFT();
+
+ wxPoint pt;
+ T token = NextTok();
+
+ if( token != T_xy )
+ Expecting( T_xy );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+
+ NeedRIGHT();
+
+ return pt;
+}
+
+
+void PCB_PARSER::parseXY( int* aX, int* aY ) throw( PARSE_ERROR, IO_ERROR )
+{
+ wxPoint pt = parseXY();
+
+ if( aX )
+ *aX = pt.x;
+
+ if( aY )
+ *aY = pt.y;
+}
+
+
+void PCB_PARSER::parseEDA_TEXT( EDA_TEXT* aText ) throw( PARSE_ERROR, IO_ERROR )
+{
+ wxCHECK_RET( CurTok() == T_effects,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as EDA_TEXT." ) );
+
+ T token;
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_font:
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token == T_LEFT )
+ continue;
+
+ switch( token )
+ {
+ case T_size:
+ {
+ wxSize sz;
+ sz.SetHeight( parseBoardUnits( "text height" ) );
+ sz.SetWidth( parseBoardUnits( "text width" ) );
+ aText->SetSize( sz );
+ NeedRIGHT();
+ }
+ break;
+
+ case T_thickness:
+ aText->SetThickness( parseBoardUnits( "text thickness" ) );
+ NeedRIGHT();
+ break;
+
+ case T_bold:
+ aText->SetBold( true );
+ break;
+
+ case T_italic:
+ aText->SetItalic( true );
+ break;
+
+ default:
+ Expecting( "size, bold, or italic" );
+ }
+ }
+
+ break;
+
+ case T_justify:
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token == T_LEFT )
+ continue;
+
+ switch( token )
+ {
+ case T_left:
+ aText->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+ break;
+
+ case T_right:
+ aText->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+ break;
+
+ case T_top:
+ aText->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
+ break;
+
+ case T_bottom:
+ aText->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+ break;
+
+ case T_mirror:
+ aText->SetMirrored( true );
+ break;
+
+ default:
+ Expecting( "left, right, top, bottom, or mirror" );
+ }
+
+ }
+ break;
+
+ case T_hide:
+ aText->SetVisible( false );
+ break;
+
+ default:
+ Expecting( "font, justify, or hide" );
+ }
+ }
+}
+
+
+S3D_MASTER* PCB_PARSER::parse3DModel() throw( PARSE_ERROR, IO_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_model, NULL,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as S3D_MASTER." ) );
+
+ T token;
+
+ std::auto_ptr< S3D_MASTER > n3D( new S3D_MASTER( NULL ) );
+
+ NeedSYMBOLorNUMBER();
+ n3D->SetShape3DName( FromUTF8() );
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_at:
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_xyz )
+ Expecting( T_xyz );
+
+ n3D->m_MatPosition.x = parseDouble( "x value" );
+ n3D->m_MatPosition.y = parseDouble( "y value" );
+ n3D->m_MatPosition.z = parseDouble( "z value" );
+ NeedRIGHT();
+ break;
+
+ case T_scale:
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_xyz )
+ Expecting( T_xyz );
+
+ n3D->m_MatScale.x = parseDouble( "x value" );
+ n3D->m_MatScale.y = parseDouble( "y value" );
+ n3D->m_MatScale.z = parseDouble( "z value" );
+ NeedRIGHT();
+ break;
+
+ case T_rotate:
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_xyz )
+ Expecting( T_xyz );
+
+ n3D->m_MatRotation.x = parseDouble( "x value" );
+ n3D->m_MatRotation.y = parseDouble( "y value" );
+ n3D->m_MatRotation.z = parseDouble( "z value" );
+ NeedRIGHT();
+ break;
+
+ default:
+ Expecting( "at, scale, or rotate" );
+ }
+
+ NeedRIGHT();
+ }
+
+ return n3D.release();
+}
+
+
+BOARD_ITEM* PCB_PARSER::Parse() throw( IO_ERROR, PARSE_ERROR )
+{
+ T token;
+ BOARD_ITEM* item;
+ LOCALE_IO toggle;
+
+ // MODULEs can be prefixed with an initial block of single line comments and these
+ // are kept for Format() so they round trip in s-expression form. BOARDs might
+ // eventually do the same, but currently do not.
+ std::auto_ptr<wxArrayString> initial_comments( ReadCommentLines() );
+
+ token = CurTok();
+
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ switch( NextTok() )
+ {
+ case T_kicad_pcb:
+ if( m_board == NULL )
+ m_board = new BOARD();
+
+ item = (BOARD_ITEM*) parseBOARD();
+ break;
+
+ case T_module:
+ item = (BOARD_ITEM*) parseMODULE( initial_comments.release() );
+ break;
+
+ default:
+ wxString err;
+ err.Printf( _( "unknown token \"%s\"" ), GetChars( FromUTF8() ) );
+ THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
+ }
+
+ return item;
+}
+
+
+BOARD* PCB_PARSER::parseBOARD() throw( IO_ERROR, PARSE_ERROR, FUTURE_FORMAT_ERROR )
+{
+ try
+ {
+ return parseBOARD_unchecked();
+ }
+ catch( const PARSE_ERROR& parse_error )
+ {
+ if( m_tooRecent )
+ throw FUTURE_FORMAT_ERROR( parse_error, GetRequiredVersion() );
+ else
+ throw;
+ }
+}
+
+
+BOARD* PCB_PARSER::parseBOARD_unchecked() throw( IO_ERROR, PARSE_ERROR )
+{
+ T token;
+
+ parseHeader();
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_general:
+ parseGeneralSection();
+ break;
+
+ case T_page:
+ parsePAGE_INFO();
+ break;
+
+ case T_title_block:
+ parseTITLE_BLOCK();
+ break;
+
+ case T_layers:
+ parseLayers();
+ break;
+
+ case T_setup:
+ parseSetup();
+ break;
+
+ case T_net:
+ parseNETINFO_ITEM();
+ break;
+
+ case T_net_class:
+ parseNETCLASS();
+ break;
+
+ case T_gr_arc:
+ case T_gr_circle:
+ case T_gr_curve:
+ case T_gr_line:
+ case T_gr_poly:
+ m_board->Add( parseDRAWSEGMENT(), ADD_APPEND );
+ break;
+
+ case T_gr_text:
+ m_board->Add( parseTEXTE_PCB(), ADD_APPEND );
+ break;
+
+ case T_dimension:
+ m_board->Add( parseDIMENSION(), ADD_APPEND );
+ break;
+
+ case T_module:
+ m_board->Add( parseMODULE(), ADD_APPEND );
+ break;
+
+ case T_segment:
+ m_board->Add( parseTRACK(), ADD_APPEND );
+ break;
+
+ case T_via:
+ m_board->Add( parseVIA(), ADD_APPEND );
+ break;
+
+ case T_zone:
+ m_board->Add( parseZONE_CONTAINER(), ADD_APPEND );
+ break;
+
+ case T_target:
+ m_board->Add( parsePCB_TARGET(), ADD_APPEND );
+ break;
+
+ default:
+ wxString err;
+ err.Printf( _( "unknown token \"%s\"" ), GetChars( FromUTF8() ) );
+ THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
+ }
+ }
+
+ return m_board;
+}
+
+
+void PCB_PARSER::parseHeader() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_RET( CurTok() == T_kicad_pcb,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a header." ) );
+
+ NeedLEFT();
+
+ T tok = NextTok();
+ if( tok == T_version )
+ {
+ m_requiredVersion = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
+ m_tooRecent = ( m_requiredVersion > SEXPR_BOARD_FILE_VERSION );
+ NeedRIGHT();
+
+ // Skip the host name and host build version information.
+ NeedLEFT();
+ NeedSYMBOL();
+ NeedSYMBOL();
+ NeedSYMBOL();
+ NeedRIGHT();
+ }
+ else
+ {
+ m_requiredVersion = SEXPR_BOARD_FILE_VERSION;
+ m_tooRecent = ( m_requiredVersion > SEXPR_BOARD_FILE_VERSION );
+
+ // Skip the host name and host build version information.
+ NeedSYMBOL();
+ NeedSYMBOL();
+ NeedRIGHT();
+ }
+
+ m_board->SetFileFormatVersionAtLoad( m_requiredVersion );
+}
+
+
+void PCB_PARSER::parseGeneralSection() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_RET( CurTok() == T_general,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
+ wxT( " as a general section." ) );
+
+ T token;
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_thickness:
+ m_board->GetDesignSettings().SetBoardThickness( parseBoardUnits( T_thickness ) );
+ NeedRIGHT();
+ break;
+
+ case T_nets:
+ m_netCodes.resize( parseInt( "nets number" ) );
+ NeedRIGHT();
+ break;
+
+ case T_no_connects:
+ m_board->SetUnconnectedNetCount( parseInt( "no connect count" ) );
+ NeedRIGHT();
+ break;
+
+ default: // Skip everything but the board thickness.
+ wxLogDebug( wxT( "Skipping general section token %s " ),
+ GetChars( GetTokenString( token ) ) );
+
+ while( ( token = NextTok() ) != T_RIGHT )
+ {
+ if( !IsSymbol( token ) && token != T_NUMBER )
+ Expecting( "symbol or number" );
+ }
+ }
+ }
+}
+
+
+void PCB_PARSER::parsePAGE_INFO() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_RET( CurTok() == T_page,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a PAGE_INFO." ) );
+
+ T token;
+ PAGE_INFO pageInfo;
+
+ NeedSYMBOL();
+
+ wxString pageType = FromUTF8();
+
+ if( !pageInfo.SetType( pageType ) )
+ {
+ wxString err;
+ err.Printf( _( "page type \"%s\" is not valid " ), GetChars( FromUTF8() ) );
+ THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
+ }
+
+ if( pageType == PAGE_INFO::Custom )
+ {
+ double width = parseDouble( "width" ); // width in mm
+
+ // Perform some controls to avoid crashes if the size is edited by hands
+ if( width < 100.0 )
+ width = 100.0;
+ else if( width > 1200.0 )
+ width = 1200.0;
+
+ double height = parseDouble( "height" ); // height in mm
+
+ if( height < 100.0 )
+ height = 100.0;
+ else if( height > 1200.0 )
+ height = 1200.0;
+
+ pageInfo.SetWidthMils( Mm2mils( width ) );
+ pageInfo.SetHeightMils( Mm2mils( height ) );
+ }
+
+ token = NextTok();
+
+ if( token == T_portrait )
+ {
+ pageInfo.SetPortrait( true );
+ NeedRIGHT();
+ }
+ else if( token != T_RIGHT )
+ {
+ Expecting( "portrait|)" );
+ }
+
+ m_board->SetPageSettings( pageInfo );
+}
+
+
+void PCB_PARSER::parseTITLE_BLOCK() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_RET( CurTok() == T_title_block,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
+ wxT( " as TITLE_BLOCK." ) );
+
+ T token;
+ TITLE_BLOCK titleBlock;
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_title:
+ NextTok();
+ titleBlock.SetTitle( FromUTF8() );
+ break;
+
+ case T_date:
+ NextTok();
+ titleBlock.SetDate( FromUTF8() );
+ break;
+
+ case T_rev:
+ NextTok();
+ titleBlock.SetRevision( FromUTF8() );
+ break;
+
+ case T_company:
+ NextTok();
+ titleBlock.SetCompany( FromUTF8() );
+ break;
+
+ case T_comment:
+ {
+ int commentNumber = parseInt( "comment" );
+
+ switch( commentNumber )
+ {
+ case 1:
+ NextTok();
+ titleBlock.SetComment1( FromUTF8() );
+ break;
+
+ case 2:
+ NextTok();
+ titleBlock.SetComment2( FromUTF8() );
+ break;
+
+ case 3:
+ NextTok();
+ titleBlock.SetComment3( FromUTF8() );
+ break;
+
+ case 4:
+ NextTok();
+ titleBlock.SetComment4( FromUTF8() );
+ break;
+
+ default:
+ wxString err;
+ err.Printf( wxT( "%d is not a valid title block comment number" ), commentNumber );
+ THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
+ }
+ }
+ break;
+
+ default:
+ Expecting( "title, date, rev, company, or comment" );
+ }
+
+ NeedRIGHT();
+ }
+
+ m_board->SetTitleBlock( titleBlock );
+}
+
+
+void PCB_PARSER::parseLayer( LAYER* aLayer ) throw( IO_ERROR, PARSE_ERROR )
+{
+ T token;
+
+ std::string name;
+ std::string type;
+ bool isVisible = true;
+
+ aLayer->clear();
+
+ if( CurTok() != T_LEFT )
+ Expecting( T_LEFT );
+
+ // this layer_num is not used, we DO depend on LAYER_T however.
+ LAYER_NUM layer_num = parseInt( "layer index" );
+
+ NeedSYMBOLorNUMBER();
+ name = CurText();
+
+ NeedSYMBOL();
+ type = CurText();
+
+ token = NextTok();
+
+ if( token == T_hide )
+ {
+ isVisible = false;
+ NeedRIGHT();
+ }
+ else if( token != T_RIGHT )
+ {
+ Expecting( "hide or )" );
+ }
+
+ aLayer->m_name = FROM_UTF8( name.c_str() );
+ aLayer->m_type = LAYER::ParseType( type.c_str() );
+ aLayer->m_number = layer_num;
+ aLayer->m_visible = isVisible;
+}
+
+
+
+void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_RET( CurTok() == T_layers,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as layers." ) );
+
+ T token;
+ LSET visibleLayers;
+ LSET enabledLayers;
+ int copperLayerCount = 0;
+ LAYER layer;
+
+ std::vector<LAYER> cu;
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ parseLayer( &layer );
+
+ if( layer.m_type == LT_UNDEFINED ) // it's a non-copper layer
+ break;
+
+ cu.push_back( layer ); // it's copper
+ }
+
+ // All Cu layers are parsed, but not the non-cu layers here.
+
+ // The original *.kicad_pcb file format and the inverted
+ // Cu stack format both have all the Cu layers first, so use this
+ // trick to handle either. The layer number in the (layers ..)
+ // s-expression element are ignored.
+ if( cu.size() )
+ {
+ // Rework the layer numbers, which changed when the Cu stack
+ // was flipped. So we instead use position in the list.
+ cu[cu.size()-1].m_number = B_Cu;
+
+ for( unsigned i=0; i < cu.size()-1; ++i )
+ {
+ cu[i].m_number = i;
+ }
+
+ for( std::vector<LAYER>::const_iterator it = cu.begin(); it<cu.end(); ++it )
+ {
+ enabledLayers.set( it->m_number );
+
+ if( it->m_visible )
+ visibleLayers.set( it->m_number );
+
+ m_board->SetLayerDescr( LAYER_ID( it->m_number ), *it );
+
+ UTF8 name = it->m_name;
+
+ m_layerIndices[ name ] = LAYER_ID( it->m_number );
+ m_layerMasks[ name ] = LSET( LAYER_ID( it->m_number ) );
+ }
+
+ copperLayerCount = cu.size();
+ }
+
+ // process non-copper layers
+ while( token != T_RIGHT )
+ {
+ LAYER_ID_MAP::const_iterator it = m_layerIndices.find( UTF8( layer.m_name ) );
+
+ if( it == m_layerIndices.end() )
+ {
+ wxString error = wxString::Format(
+ _( "Layer '%s' in file '%s' at line %d, is not in fixed layer hash" ),
+ GetChars( layer.m_name ),
+ GetChars( CurSource() ),
+ CurLineNumber(),
+ CurOffset()
+ );
+
+ THROW_IO_ERROR( error );
+ }
+
+ layer.m_number = it->second;
+
+ enabledLayers.set( layer.m_number );
+
+ if( layer.m_visible )
+ visibleLayers.set( layer.m_number );
+
+ // DBG( printf( "aux m_visible:%s\n", layer.m_visible ? "true" : "false" );)
+
+ m_board->SetLayerDescr( it->second, layer );
+
+ token = NextTok();
+
+ if( token != T_LEFT )
+ break;
+
+ parseLayer( &layer );
+ }
+
+ // We need at least 2 copper layers and there must be an even number of them.
+ if( copperLayerCount < 2 || (copperLayerCount % 2) != 0 )
+ {
+ wxString err = wxString::Format(
+ _( "%d is not a valid layer count" ), copperLayerCount );
+
+ THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
+ }
+
+ m_board->SetCopperLayerCount( copperLayerCount );
+ m_board->SetEnabledLayers( enabledLayers );
+
+ // call SetEnabledLayers before SetVisibleLayers()
+ m_board->SetVisibleLayers( visibleLayers );
+}
+
+
+template<class T, class M>
+T PCB_PARSER::lookUpLayer( const M& aMap ) throw( PARSE_ERROR, IO_ERROR )
+{
+ // avoid constructing another std::string, use lexer's directly
+ typename M::const_iterator it = aMap.find( curText );
+
+ if( it == aMap.end() )
+ {
+#if 0 && defined(DEBUG)
+ // dump the whole darn table, there's something wrong with it.
+ for( it = aMap.begin(); it != aMap.end(); ++it )
+ {
+ wxLogDebug( &aMap == (void*)&m_layerIndices ? wxT( "lm[%s] = %d" ) :
+ wxT( "lm[%s] = %08X" ), it->first.c_str(), it->second );
+ }
+#endif
+
+ wxString error = wxString::Format( _(
+ "Layer '%s' in file\n"
+ "'%s'\n"
+ "at line %d, position %d\n"
+ "was not defined in the layers section"
+ ),
+ GetChars( FROM_UTF8( CurText() ) ),
+ GetChars( CurSource() ),
+ CurLineNumber(), CurOffset() );
+
+ THROW_IO_ERROR( error );
+ }
+
+ return it->second;
+}
+
+
+LAYER_ID PCB_PARSER::parseBoardItemLayer() throw( PARSE_ERROR, IO_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_layer, UNDEFINED_LAYER,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as layer." ) );
+
+ NextTok();
+
+ LAYER_ID layerIndex = lookUpLayer<LAYER_ID>( m_layerIndices );
+
+ // Handle closing ) in object parser.
+
+ return layerIndex;
+}
+
+
+LSET PCB_PARSER::parseBoardItemLayersAsMask() throw( PARSE_ERROR, IO_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_layers, LSET(),
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
+ wxT( " as item layer mask." ) );
+
+ LSET layerMask;
+
+ for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ LSET mask = lookUpLayer<LSET>( m_layerMasks );
+ layerMask |= mask;
+ }
+
+ return layerMask;
+}
+
+
+void PCB_PARSER::parseSetup() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_RET( CurTok() == T_setup,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as setup." ) );
+
+ T token;
+ NETCLASSPTR defaultNetClass = m_board->GetDesignSettings().GetDefault();
+ // TODO Orson: is it really necessary to first operate on a copy and then apply it?
+ // would not it be better to use reference here and apply all the changes instantly?
+ BOARD_DESIGN_SETTINGS designSettings = m_board->GetDesignSettings();
+ ZONE_SETTINGS zoneSettings = m_board->GetZoneSettings();
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_last_trace_width: // not used now
+ /* lastTraceWidth =*/ parseBoardUnits( T_last_trace_width );
+ NeedRIGHT();
+ break;
+
+ case T_user_trace_width:
+ designSettings.m_TrackWidthList.push_back( parseBoardUnits( T_user_trace_width ) );
+ NeedRIGHT();
+ break;
+
+ case T_trace_clearance:
+ defaultNetClass->SetClearance( parseBoardUnits( T_trace_clearance ) );
+ NeedRIGHT();
+ break;
+
+ case T_zone_clearance:
+ zoneSettings.m_ZoneClearance = parseBoardUnits( T_zone_clearance );
+ NeedRIGHT();
+ break;
+
+ case T_zone_45_only:
+ zoneSettings.m_Zone_45_Only = parseBool();
+ NeedRIGHT();
+ break;
+
+ case T_trace_min:
+ designSettings.m_TrackMinWidth = parseBoardUnits( T_trace_min );
+ NeedRIGHT();
+ break;
+
+ case T_segment_width:
+ designSettings.m_DrawSegmentWidth = parseBoardUnits( T_segment_width );
+ NeedRIGHT();
+ break;
+
+ case T_edge_width:
+ designSettings.m_EdgeSegmentWidth = parseBoardUnits( T_edge_width );
+ NeedRIGHT();
+ break;
+
+ case T_via_size:
+ defaultNetClass->SetViaDiameter( parseBoardUnits( T_via_size ) );
+ NeedRIGHT();
+ break;
+
+ case T_via_drill:
+ defaultNetClass->SetViaDrill( parseBoardUnits( T_via_drill ) );
+ NeedRIGHT();
+ break;
+
+ case T_via_min_size:
+ designSettings.m_ViasMinSize = parseBoardUnits( T_via_min_size );
+ NeedRIGHT();
+ break;
+
+ case T_via_min_drill:
+ designSettings.m_ViasMinDrill = parseBoardUnits( T_via_min_drill );
+ NeedRIGHT();
+ break;
+
+ case T_user_via:
+ {
+ int viaSize = parseBoardUnits( "user via size" );
+ int viaDrill = parseBoardUnits( "user via drill" );
+ designSettings.m_ViasDimensionsList.push_back( VIA_DIMENSION( viaSize, viaDrill ) );
+ NeedRIGHT();
+ }
+ break;
+
+ case T_uvia_size:
+ defaultNetClass->SetuViaDiameter( parseBoardUnits( T_uvia_size ) );
+ NeedRIGHT();
+ break;
+
+ case T_uvia_drill:
+ defaultNetClass->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
+ NeedRIGHT();
+ break;
+
+ case T_uvias_allowed:
+ designSettings.m_MicroViasAllowed = parseBool();
+ NeedRIGHT();
+ break;
+
+ case T_blind_buried_vias_allowed:
+ designSettings.m_BlindBuriedViaAllowed = parseBool();
+ NeedRIGHT();
+ break;
+
+ case T_uvia_min_size:
+ designSettings.m_MicroViasMinSize = parseBoardUnits( T_uvia_min_size );
+ NeedRIGHT();
+ break;
+
+ case T_uvia_min_drill:
+ designSettings.m_MicroViasMinDrill = parseBoardUnits( T_uvia_min_drill );
+ NeedRIGHT();
+ break;
+
+ case T_pcb_text_width:
+ designSettings.m_PcbTextWidth = parseBoardUnits( T_pcb_text_width );
+ NeedRIGHT();
+ break;
+
+ case T_pcb_text_size:
+ designSettings.m_PcbTextSize.x = parseBoardUnits( "pcb text width" );
+ designSettings.m_PcbTextSize.y = parseBoardUnits( "pcb text height" );
+ NeedRIGHT();
+ break;
+
+ case T_mod_edge_width:
+ designSettings.m_ModuleSegmentWidth = parseBoardUnits( T_mod_edge_width );
+ NeedRIGHT();
+ break;
+
+ case T_mod_text_size:
+ designSettings.m_ModuleTextSize.x = parseBoardUnits( "module text width" );
+ designSettings.m_ModuleTextSize.y = parseBoardUnits( "module text height" );
+ NeedRIGHT();
+ break;
+
+ case T_mod_text_width:
+ designSettings.m_ModuleTextWidth = parseBoardUnits( T_mod_text_width );
+ NeedRIGHT();
+ break;
+
+ case T_pad_size:
+ {
+ wxSize sz;
+ sz.SetWidth( parseBoardUnits( "master pad width" ) );
+ sz.SetHeight( parseBoardUnits( "master pad height" ) );
+ designSettings.m_Pad_Master.SetSize( sz );
+ NeedRIGHT();
+ }
+ break;
+
+ case T_pad_drill:
+ {
+ int drillSize = parseBoardUnits( T_pad_drill );
+ designSettings.m_Pad_Master.SetDrillSize( wxSize( drillSize, drillSize ) );
+ NeedRIGHT();
+ }
+ break;
+
+ case T_pad_to_mask_clearance:
+ designSettings.m_SolderMaskMargin = parseBoardUnits( T_pad_to_mask_clearance );
+ NeedRIGHT();
+ break;
+
+ case T_solder_mask_min_width:
+ designSettings.m_SolderMaskMinWidth = parseBoardUnits( T_solder_mask_min_width );
+ NeedRIGHT();
+ break;
+
+ case T_pad_to_paste_clearance:
+ designSettings.m_SolderPasteMargin = parseBoardUnits( T_pad_to_paste_clearance );
+ NeedRIGHT();
+ break;
+
+ case T_pad_to_paste_clearance_ratio:
+ designSettings.m_SolderPasteMarginRatio = parseDouble( T_pad_to_paste_clearance_ratio );
+ NeedRIGHT();
+ break;
+
+ case T_aux_axis_origin:
+ {
+ int x = parseBoardUnits( "auxiliary origin X" );
+ int y = parseBoardUnits( "auxiliary origin Y" );
+ // m_board->SetAuxOrigin( wxPoint( x, y ) ); gets overwritten via SetDesignSettings below
+ designSettings.m_AuxOrigin = wxPoint( x, y );
+ NeedRIGHT();
+ }
+ break;
+
+ case T_grid_origin:
+ {
+ int x = parseBoardUnits( "grid origin X" );
+ int y = parseBoardUnits( "grid origin Y" );
+ // m_board->SetGridOrigin( wxPoint( x, y ) ); gets overwritten SetDesignSettings below
+ designSettings.m_GridOrigin = wxPoint( x, y );
+ NeedRIGHT();
+ }
+ break;
+
+ case T_visible_elements:
+ designSettings.SetVisibleElements( parseHex() | MIN_VISIBILITY_MASK );
+ NeedRIGHT();
+ break;
+
+ case T_pcbplotparams:
+ {
+ PCB_PLOT_PARAMS plotParams;
+ PCB_PLOT_PARAMS_PARSER parser( reader );
+ // parser must share the same current line as our current PCB parser
+ // synchronize it.
+ parser.SyncLineReaderWith( *this );
+
+ plotParams.Parse( &parser );
+ SyncLineReaderWith( parser );
+
+ m_board->SetPlotOptions( plotParams );
+ }
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+
+ m_board->SetDesignSettings( designSettings );
+ m_board->SetZoneSettings( zoneSettings );
+}
+
+
+void PCB_PARSER::parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_RET( CurTok() == T_net,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net." ) );
+
+ int netCode = parseInt( "net number" );
+
+ NeedSYMBOLorNUMBER();
+ wxString name = FromUTF8();
+
+ NeedRIGHT();
+
+ // net 0 should be already in list, so store this net
+ // if it is not the net 0, or if the net 0 does not exists.
+ // (TODO: a better test.)
+ if( netCode > 0 || m_board->FindNet( 0 ) == NULL )
+ {
+ NETINFO_ITEM* net = new NETINFO_ITEM( m_board, name, netCode );
+ m_board->AppendNet( net );
+
+ // Store the new code mapping
+ pushValueIntoMap( netCode, net->GetNet() );
+ }
+}
+
+
+void PCB_PARSER::parseNETCLASS() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_RET( CurTok() == T_net_class,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as net class." ) );
+
+ T token;
+
+ NETCLASSPTR nc = boost::make_shared<NETCLASS>( wxEmptyString );
+
+ // Read netclass name (can be a name or just a number like track width)
+ NeedSYMBOLorNUMBER();
+ nc->SetName( FromUTF8() );
+ NeedSYMBOL();
+ nc->SetDescription( FromUTF8() );
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_clearance:
+ nc->SetClearance( parseBoardUnits( T_clearance ) );
+ break;
+
+ case T_trace_width:
+ nc->SetTrackWidth( parseBoardUnits( T_trace_width ) );
+ break;
+
+ case T_via_dia:
+ nc->SetViaDiameter( parseBoardUnits( T_via_dia ) );
+ break;
+
+ case T_via_drill:
+ nc->SetViaDrill( parseBoardUnits( T_via_drill ) );
+ break;
+
+ case T_uvia_dia:
+ nc->SetuViaDiameter( parseBoardUnits( T_uvia_dia ) );
+ break;
+
+ case T_uvia_drill:
+ nc->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
+ break;
+
+ case T_add_net:
+ NeedSYMBOLorNUMBER();
+ nc->Add( FromUTF8() );
+ break;
+
+ default:
+ Expecting( "clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, or add_net" );
+ }
+
+ NeedRIGHT();
+ }
+
+ if( !m_board->GetDesignSettings().m_NetClasses.Add( nc ) )
+ {
+ // Must have been a name conflict, this is a bad board file.
+ // User may have done a hand edit to the file.
+
+ // auto_ptr will delete nc on this code path
+
+ wxString error;
+ error.Printf( _( "duplicate NETCLASS name '%s' in file <%s> at line %d, offset %d" ),
+ nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(), CurOffset() );
+ THROW_IO_ERROR( error );
+ }
+}
+
+
+DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
+ CurTok() == T_gr_line || CurTok() == T_gr_poly, NULL,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DRAWSEGMENT." ) );
+
+ T token;
+ wxPoint pt;
+ std::auto_ptr< DRAWSEGMENT > segment( new DRAWSEGMENT( NULL ) );
+
+ switch( CurTok() )
+ {
+ case T_gr_arc:
+ segment->SetShape( S_ARC );
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_start )
+ Expecting( T_start );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ segment->SetStart( pt );
+ NeedRIGHT();
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_end )
+ Expecting( T_end );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ segment->SetEnd( pt );
+ NeedRIGHT();
+ break;
+
+ case T_gr_circle:
+ segment->SetShape( S_CIRCLE );
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_center )
+ Expecting( T_center );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ segment->SetStart( pt );
+ NeedRIGHT();
+ NeedLEFT();
+
+ token = NextTok();
+
+ if( token != T_end )
+ Expecting( T_end );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ segment->SetEnd( pt );
+ NeedRIGHT();
+ break;
+
+ case T_gr_curve:
+ segment->SetShape( S_CURVE );
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ segment->SetStart( parseXY() );
+ segment->SetBezControl1( parseXY() );
+ segment->SetBezControl2( parseXY() );
+ segment->SetEnd( parseXY() );
+ NeedRIGHT();
+ break;
+
+ case T_gr_line:
+ // Default DRAWSEGMENT type is S_SEGMENT.
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_start )
+ Expecting( T_start );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ segment->SetStart( pt );
+ NeedRIGHT();
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_end )
+ Expecting( T_end );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ segment->SetEnd( pt );
+ NeedRIGHT();
+ break;
+
+ case T_gr_poly:
+ {
+ segment->SetShape( S_POLYGON );
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ std::vector< wxPoint > pts;
+
+ while( (token = NextTok()) != T_RIGHT )
+ pts.push_back( parseXY() );
+
+ segment->SetPolyPoints( pts );
+ }
+ break;
+
+ default:
+ Expecting( "gr_arc, gr_circle, gr_curve, gr_line, or gr_poly" );
+ }
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_angle:
+ segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
+ break;
+
+ case T_layer:
+ segment->SetLayer( parseBoardItemLayer() );
+ break;
+
+ case T_width:
+ segment->SetWidth( parseBoardUnits( T_width ) );
+ break;
+
+ case T_tstamp:
+ segment->SetTimeStamp( parseHex() );
+ break;
+
+ case T_status:
+ segment->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
+ break;
+
+ default:
+ Expecting( "layer, width, tstamp, or status" );
+ }
+
+ NeedRIGHT();
+ }
+
+ return segment.release();
+}
+
+
+TEXTE_PCB* PCB_PARSER::parseTEXTE_PCB() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_gr_text, NULL,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as TEXTE_PCB." ) );
+
+ T token;
+
+ std::auto_ptr<TEXTE_PCB> text( new TEXTE_PCB( m_board ) );
+ NeedSYMBOLorNUMBER();
+
+ text->SetText( FromUTF8() );
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_at )
+ Expecting( T_at );
+
+ wxPoint pt;
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ text->SetTextPosition( pt );
+
+ // If there is no orientation defined, then it is the default value of 0 degrees.
+ token = NextTok();
+
+ if( token == T_NUMBER )
+ {
+ text->SetOrientation( parseDouble() * 10.0 );
+ NeedRIGHT();
+ }
+ else if( token != T_RIGHT )
+ {
+ Unexpected( CurText() );
+ }
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_layer:
+ text->SetLayer( parseBoardItemLayer() );
+ NeedRIGHT();
+ break;
+
+ case T_tstamp:
+ text->SetTimeStamp( parseHex() );
+ NeedRIGHT();
+ break;
+
+ case T_effects:
+ parseEDA_TEXT( (EDA_TEXT*) text.get() );
+ break;
+
+ default:
+ Expecting( "layer, tstamp or effects" );
+ }
+ }
+
+ return text.release();
+}
+
+
+DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_dimension, NULL,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DIMENSION." ) );
+
+ T token;
+
+ std::auto_ptr<DIMENSION> dimension( new DIMENSION( NULL ) );
+
+ dimension->SetValue( parseBoardUnits( "dimension value" ) );
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_width )
+ Expecting( T_width );
+
+ dimension->SetWidth( parseBoardUnits( "dimension width value" ) );
+ NeedRIGHT();
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_layer:
+ dimension->SetLayer( parseBoardItemLayer() );
+ NeedRIGHT();
+ break;
+
+ case T_tstamp:
+ dimension->SetTimeStamp( parseHex() );
+ NeedRIGHT();
+ break;
+
+ case T_gr_text:
+ {
+ TEXTE_PCB* text = parseTEXTE_PCB();
+ dimension->Text() = *text;
+ dimension->SetPosition( text->GetTextPosition() );
+ delete text;
+ break;
+ }
+
+ case T_feature1:
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ parseXY( &dimension->m_featureLineDO.x, &dimension->m_featureLineDO.y );
+ parseXY( &dimension->m_featureLineDF.x, &dimension->m_featureLineDF.y );
+ dimension->UpdateHeight();
+ NeedRIGHT();
+ NeedRIGHT();
+ break;
+
+ case T_feature2:
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ parseXY( &dimension->m_featureLineGO.x, &dimension->m_featureLineGO.y );
+ parseXY( &dimension->m_featureLineGF.x, &dimension->m_featureLineGF.y );
+ dimension->UpdateHeight();
+ NeedRIGHT();
+ NeedRIGHT();
+ break;
+
+
+ case T_crossbar:
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
+ parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
+ dimension->UpdateHeight();
+ NeedRIGHT();
+ NeedRIGHT();
+ break;
+
+ case T_arrow1a:
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
+ parseXY( &dimension->m_arrowD1F.x, &dimension->m_arrowD1F.y );
+ NeedRIGHT();
+ NeedRIGHT();
+ break;
+
+ case T_arrow1b:
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
+ parseXY( &dimension->m_arrowD2F.x, &dimension->m_arrowD2F.y );
+ NeedRIGHT();
+ NeedRIGHT();
+ break;
+
+ case T_arrow2a:
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
+ parseXY( &dimension->m_arrowG1F.x, &dimension->m_arrowG1F.y );
+ NeedRIGHT();
+ NeedRIGHT();
+ break;
+
+ case T_arrow2b:
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
+ parseXY( &dimension->m_arrowG2F.x, &dimension->m_arrowG2F.y );
+ NeedRIGHT();
+ NeedRIGHT();
+ break;
+
+ default:
+ Expecting( "layer, tstamp, gr_text, feature1, feature2 crossbar, arrow1a, "
+ "arrow1b, arrow2a, or arrow2b" );
+ }
+ }
+
+ return dimension.release();
+}
+
+
+MODULE* PCB_PARSER::parseMODULE( wxArrayString* aInitialComments )
+ throw( IO_ERROR, PARSE_ERROR, FUTURE_FORMAT_ERROR )
+{
+ try
+ {
+ return parseMODULE_unchecked( aInitialComments );
+ }
+ catch( const PARSE_ERROR& parse_error )
+ {
+ if( m_tooRecent )
+ throw FUTURE_FORMAT_ERROR( parse_error, GetRequiredVersion() );
+ else
+ throw;
+ }
+}
+
+
+MODULE* PCB_PARSER::parseMODULE_unchecked( wxArrayString* aInitialComments )
+ throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_module, NULL,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as MODULE." ) );
+
+ wxString name;
+ wxPoint pt;
+ T token;
+ FPID fpid;
+
+ std::auto_ptr<MODULE> module( new MODULE( m_board ) );
+
+ module->SetInitialComments( aInitialComments );
+
+ token = NextTok();
+
+ if( !IsSymbol( token ) && token != T_NUMBER )
+ Expecting( "symbol|number" );
+
+ name = FromUTF8();
+
+ if( !name.IsEmpty() && fpid.Parse( FromUTF8() ) >= 0 )
+ {
+ wxString error;
+ error.Printf( _( "invalid footprint ID in\nfile: <%s>\nline: %d\noffset: %d" ),
+ GetChars( CurSource() ), CurLineNumber(), CurOffset() );
+ THROW_IO_ERROR( error );
+ }
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_version:
+ {
+ // Theoretically a module nested in a PCB could declare its own version, though
+ // as of writing this comment we don't do that. Just in case, take the greater
+ // version.
+ int this_version = parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
+ NeedRIGHT();
+ m_requiredVersion = std::max( m_requiredVersion, this_version );
+ m_tooRecent = ( m_requiredVersion > SEXPR_BOARD_FILE_VERSION );
+ break;
+ }
+
+ case T_locked:
+ module->SetLocked( true );
+ break;
+
+ case T_placed:
+ module->SetIsPlaced( true );
+ break;
+
+ case T_layer:
+ {
+ // Footprints can be only on the front side or the back side.
+ // but because we can find some stupid layer in file, ensure a
+ // acceptable layer is set for the footprint
+ LAYER_ID layer = parseBoardItemLayer();
+ module->SetLayer( layer == B_Cu ? B_Cu : F_Cu );
+ }
+ NeedRIGHT();
+ break;
+
+ case T_tedit:
+ module->SetLastEditTime( parseHex() );
+ NeedRIGHT();
+ break;
+
+ case T_tstamp:
+ module->SetTimeStamp( parseHex() );
+ NeedRIGHT();
+ break;
+
+ case T_at:
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ module->SetPosition( pt );
+ token = NextTok();
+
+ if( token == T_NUMBER )
+ {
+ module->SetOrientation( parseDouble() * 10.0 );
+ NeedRIGHT();
+ }
+ else if( token != T_RIGHT )
+ {
+ Expecting( T_RIGHT );
+ }
+
+ break;
+
+ case T_descr:
+ NeedSYMBOLorNUMBER(); // some symbols can be 0508, so a number is also a symbol here
+ module->SetDescription( FromUTF8() );
+ NeedRIGHT();
+ break;
+
+ case T_tags:
+ NeedSYMBOLorNUMBER(); // some symbols can be 0508, so a number is also a symbol here
+ module->SetKeywords( FromUTF8() );
+ NeedRIGHT();
+ break;
+
+ case T_path:
+ NeedSYMBOLorNUMBER(); // Paths can be numerical so a number is also a symbol here
+ module->SetPath( FromUTF8() );
+ NeedRIGHT();
+ break;
+
+ case T_autoplace_cost90:
+ module->SetPlacementCost90( parseInt( "auto place cost at 90 degrees" ) );
+ NeedRIGHT();
+ break;
+
+ case T_autoplace_cost180:
+ module->SetPlacementCost180( parseInt( "auto place cost at 180 degrees" ) );
+ NeedRIGHT();
+ break;
+
+ case T_solder_mask_margin:
+ module->SetLocalSolderMaskMargin( parseBoardUnits( "local solder mask margin value" ) );
+ NeedRIGHT();
+ break;
+
+ case T_solder_paste_margin:
+ module->SetLocalSolderPasteMargin(
+ parseBoardUnits( "local solder paste margin value" ) );
+ NeedRIGHT();
+ break;
+
+ case T_solder_paste_ratio:
+ module->SetLocalSolderPasteMarginRatio(
+ parseDouble( "local solder paste margin ratio value" ) );
+ NeedRIGHT();
+ break;
+
+ case T_clearance:
+ module->SetLocalClearance( parseBoardUnits( "local clearance value" ) );
+ NeedRIGHT();
+ break;
+
+ case T_zone_connect:
+ module->SetZoneConnection( (ZoneConnection) parseInt( "zone connection value" ) );
+ NeedRIGHT();
+ break;
+
+ case T_thermal_width:
+ module->SetThermalWidth( parseBoardUnits( "thermal width value" ) );
+ NeedRIGHT();
+ break;
+
+ case T_thermal_gap:
+ module->SetThermalGap( parseBoardUnits( "thermal gap value" ) );
+ NeedRIGHT();
+ break;
+
+ case T_attr:
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ switch( token )
+ {
+ case T_smd:
+ module->SetAttributes( module->GetAttributes() | MOD_CMS );
+ break;
+
+ case T_virtual:
+ module->SetAttributes( module->GetAttributes() | MOD_VIRTUAL );
+ break;
+
+ default:
+ Expecting( "smd and/or virtual" );
+ }
+ }
+
+ break;
+
+ case T_fp_text:
+ {
+ TEXTE_MODULE* text = parseTEXTE_MODULE();
+ text->SetParent( module.get() );
+ double orientation = text->GetOrientation();
+ orientation -= module->GetOrientation();
+ text->SetOrientation( orientation );
+ text->SetDrawCoord();
+
+ switch( text->GetType() )
+ {
+ case TEXTE_MODULE::TEXT_is_REFERENCE:
+ module->Reference() = *text;
+ delete text;
+ break;
+
+ case TEXTE_MODULE::TEXT_is_VALUE:
+ module->Value() = *text;
+ delete text;
+ break;
+
+ default:
+ module->GraphicalItems().PushBack( text );
+ }
+ }
+ break;
+
+ case T_fp_arc:
+ case T_fp_circle:
+ case T_fp_curve:
+ case T_fp_line:
+ case T_fp_poly:
+ {
+ EDGE_MODULE* em = parseEDGE_MODULE();
+ em->SetParent( module.get() );
+ em->SetDrawCoord();
+ module->GraphicalItems().PushBack( em );
+ }
+ break;
+
+ case T_pad:
+ {
+ D_PAD* pad = parseD_PAD( module.get() );
+ wxPoint pt = pad->GetPos0();
+
+ RotatePoint( &pt, module->GetOrientation() );
+ pad->SetPosition( pt + module->GetPosition() );
+ module->Add( pad, ADD_APPEND );
+ }
+ break;
+
+ case T_model:
+ module->Add3DModel( parse3DModel() );
+ break;
+
+ default:
+ Expecting( "locked, placed, tedit, tstamp, at, descr, tags, path, "
+ "autoplace_cost90, autoplace_cost180, solder_mask_margin, "
+ "solder_paste_margin, solder_paste_ratio, clearance, "
+ "zone_connect, thermal_width, thermal_gap, attr, fp_text, "
+ "fp_arc, fp_circle, fp_curve, fp_line, fp_poly, pad, or model" );
+ }
+ }
+
+ module->SetFPID( fpid );
+ module->CalculateBoundingBox();
+
+ return module.release();
+}
+
+
+TEXTE_MODULE* PCB_PARSER::parseTEXTE_MODULE() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_fp_text, NULL,
+ wxString::Format( wxT( "Cannot parse %s as TEXTE_MODULE at line %d, offset %d." ),
+ GetChars( GetTokenString( CurTok() ) ),
+ CurLineNumber(), CurOffset() ) );
+
+ T token = NextTok();
+
+ std::auto_ptr<TEXTE_MODULE> text( new TEXTE_MODULE( NULL ) );
+
+ switch( token )
+ {
+ case T_reference:
+ text->SetType( TEXTE_MODULE::TEXT_is_REFERENCE );
+ break;
+
+ case T_value:
+ text->SetType( TEXTE_MODULE::TEXT_is_VALUE );
+ break;
+
+ case T_user:
+ break; // Default type is user text.
+
+ default:
+ THROW_IO_ERROR( wxString::Format( _( "cannot handle footprint text type %s" ),
+ GetChars( FromUTF8() ) ) );
+ }
+
+ NeedSYMBOLorNUMBER();
+
+ text->SetText( FromUTF8() );
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_at )
+ Expecting( T_at );
+
+ wxPoint pt;
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ text->SetPos0( pt );
+ token = NextTok();
+
+ // If there is no orientation defined, then it is the default value of 0 degrees.
+ if( token == T_NUMBER )
+ {
+ text->SetOrientation( parseDouble() * 10.0 );
+ NeedRIGHT();
+ }
+ else if( token != T_RIGHT )
+ {
+ Unexpected( CurText() );
+ }
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_layer:
+ text->SetLayer( parseBoardItemLayer() );
+ NeedRIGHT();
+ break;
+
+ case T_hide:
+ text->SetVisible( false );
+ break;
+
+ case T_effects:
+ parseEDA_TEXT( (EDA_TEXT*) text.get() );
+ // Due to a double definition (a bug) of SetVisible (one in EDA_TEXT and
+ // one in TEXTE_MODULE), verify if the EDA_TEXT is set to invisible
+ // This allows compatibility with files which could be created
+ // by pcbnew version janv 25, 2017, which fix a old bug (this one)
+ // This compatibility is especially important for footprint files.
+ if( !text->EDA_TEXT::IsVisible() )
+ {
+ // Only if the EDA_TEXT visibility is false, set the
+ // TEXTE_MODULE visibility to false.
+ // in files created by 4.05 version and older, the EDA_TEXT
+ // visibility is always true (the default), due to this bug
+ text->SetVisible( false );
+ // If we want a full compatibiliy with previous stable version,
+ // this ugly workaround avoids writing "hide" token
+ // in "effects" section, when the file comes from some recent pcbnew version
+ text->EDA_TEXT::SetVisible( true );
+ }
+ break;
+
+ default:
+ Expecting( "hide or effects" );
+ }
+ }
+
+ return text.release();
+}
+
+
+EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve ||
+ CurTok() == T_fp_line || CurTok() == T_fp_poly, NULL,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as EDGE_MODULE." ) );
+
+ wxPoint pt;
+ T token;
+
+ std::auto_ptr< EDGE_MODULE > segment( new EDGE_MODULE( NULL ) );
+
+ switch( CurTok() )
+ {
+ case T_fp_arc:
+ segment->SetShape( S_ARC );
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_start )
+ Expecting( T_start );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ segment->SetStart0( pt );
+ NeedRIGHT();
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_end )
+ Expecting( T_end );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ segment->SetEnd0( pt );
+ NeedRIGHT();
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_angle )
+ Expecting( T_angle );
+
+ segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
+ NeedRIGHT();
+ break;
+
+ case T_fp_circle:
+ segment->SetShape( S_CIRCLE );
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_center )
+ Expecting( T_center );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ segment->SetStart0( pt );
+ NeedRIGHT();
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_end )
+ Expecting( T_end );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ segment->SetEnd0( pt );
+ NeedRIGHT();
+ break;
+
+ case T_fp_curve:
+ segment->SetShape( S_CURVE );
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ segment->SetStart0( parseXY() );
+ segment->SetBezControl1( parseXY() );
+ segment->SetBezControl2( parseXY() );
+ segment->SetEnd0( parseXY() );
+ NeedRIGHT();
+ break;
+
+ case T_fp_line:
+ // Default DRAWSEGMENT type is S_SEGMENT.
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_start )
+ Expecting( T_start );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ segment->SetStart0( pt );
+
+ NeedRIGHT();
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_end )
+ Expecting( T_end );
+
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ segment->SetEnd0( pt );
+ NeedRIGHT();
+ break;
+
+ case T_fp_poly:
+ {
+ segment->SetShape( S_POLYGON );
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ std::vector< wxPoint > pts;
+
+ while( (token = NextTok()) != T_RIGHT )
+ pts.push_back( parseXY() );
+
+ segment->SetPolyPoints( pts );
+ }
+ break;
+
+ default:
+ Expecting( "fp_arc, fp_circle, fp_curve, fp_line, or fp_poly" );
+ }
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_layer:
+ segment->SetLayer( parseBoardItemLayer() );
+ break;
+
+ case T_width:
+ segment->SetWidth( parseBoardUnits( T_width ) );
+ break;
+
+ case T_tstamp:
+ segment->SetTimeStamp( parseHex() );
+ break;
+
+ case T_status:
+ segment->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
+ break;
+
+ default:
+ Expecting( "layer or width" );
+ }
+
+ NeedRIGHT();
+ }
+
+ return segment.release();
+}
+
+
+D_PAD* PCB_PARSER::parseD_PAD( MODULE* aParent ) throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_pad, NULL,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as D_PAD." ) );
+
+ wxSize sz;
+ wxPoint pt;
+
+ std::auto_ptr< D_PAD > pad( new D_PAD( aParent ) );
+
+ NeedSYMBOLorNUMBER();
+ pad->SetPadName( FromUTF8() );
+
+ T token = NextTok();
+
+ switch( token )
+ {
+ case T_thru_hole:
+ pad->SetAttribute( PAD_ATTRIB_STANDARD );
+ break;
+
+ case T_smd:
+ pad->SetAttribute( PAD_ATTRIB_SMD );
+
+ // Default D_PAD object is thru hole with drill.
+ // SMD pads have no hole
+ pad->SetDrillSize( wxSize( 0, 0 ) );
+ break;
+
+ case T_connect:
+ pad->SetAttribute( PAD_ATTRIB_CONN );
+
+ // Default D_PAD object is thru hole with drill.
+ // CONN pads have no hole
+ pad->SetDrillSize( wxSize( 0, 0 ) );
+ break;
+
+ case T_np_thru_hole:
+ pad->SetAttribute( PAD_ATTRIB_HOLE_NOT_PLATED );
+ break;
+
+ default:
+ Expecting( "thru_hole, smd, connect, or np_thru_hole" );
+ }
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_circle:
+ pad->SetShape( PAD_SHAPE_CIRCLE );
+ break;
+
+ case T_rect:
+ pad->SetShape( PAD_SHAPE_RECT );
+ break;
+
+ case T_oval:
+ pad->SetShape( PAD_SHAPE_OVAL );
+ break;
+
+ case T_trapezoid:
+ pad->SetShape( PAD_SHAPE_TRAPEZOID );
+ break;
+
+ default:
+ Expecting( "circle, rectangle, oval, or trapezoid" );
+ }
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_size:
+ sz.SetWidth( parseBoardUnits( "width value" ) );
+ sz.SetHeight( parseBoardUnits( "height value" ) );
+ pad->SetSize( sz );
+ NeedRIGHT();
+ break;
+
+ case T_at:
+ pt.x = parseBoardUnits( "X coordinate" );
+ pt.y = parseBoardUnits( "Y coordinate" );
+ pad->SetPos0( pt );
+ token = NextTok();
+
+ if( token == T_NUMBER )
+ {
+ pad->SetOrientation( parseDouble() * 10.0 );
+ NeedRIGHT();
+ }
+ else if( token != T_RIGHT )
+ {
+ Expecting( ") or angle value" );
+ }
+
+ break;
+
+ case T_rect_delta:
+ {
+ wxSize delta;
+ delta.SetWidth( parseBoardUnits( "rectangle delta width" ) );
+ delta.SetHeight( parseBoardUnits( "rectangle delta height" ) );
+ pad->SetDelta( delta );
+ NeedRIGHT();
+ }
+ break;
+
+ case T_drill:
+ {
+ bool haveWidth = false;
+ wxSize drillSize = pad->GetDrillSize();
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_oval:
+ pad->SetDrillShape( PAD_DRILL_SHAPE_OBLONG );
+ break;
+
+ case T_NUMBER:
+ {
+ if( !haveWidth )
+ {
+ drillSize.SetWidth( parseBoardUnits() );
+
+ // If height is not defined the width and height are the same.
+ drillSize.SetHeight( drillSize.GetWidth() );
+ haveWidth = true;
+ }
+ else
+ {
+ drillSize.SetHeight( parseBoardUnits() );
+ }
+
+ }
+ break;
+
+ case T_offset:
+ pt.x = parseBoardUnits( "drill offset x" );
+ pt.y = parseBoardUnits( "drill offset y" );
+ pad->SetOffset( pt );
+ NeedRIGHT();
+ break;
+
+ default:
+ Expecting( "oval, size, or offset" );
+ }
+ }
+
+ // This fixes a bug caused by setting the default D_PAD drill size to a value
+ // other than 0 used to fix a bunch of debug assertions even though it is defined
+ // as a through hole pad. Wouldn't a though hole pad with no drill be a surface
+ // mount pad (or a conn pad which is a smd pad with no solder paste)?
+ if( ( pad->GetAttribute() != PAD_ATTRIB_SMD ) && ( pad->GetAttribute() != PAD_ATTRIB_CONN ) )
+ pad->SetDrillSize( drillSize );
+ else
+ pad->SetDrillSize( wxSize( 0, 0 ) );
+
+ }
+ break;
+
+ case T_layers:
+ {
+ LSET layerMask = parseBoardItemLayersAsMask();
+ pad->SetLayerSet( layerMask );
+ }
+ break;
+
+ case T_net:
+ if( ! pad->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) )
+ THROW_IO_ERROR(
+ wxString::Format( _( "invalid net ID in\nfile: <%s>\nline: %d\noffset: %d" ),
+ GetChars( CurSource() ), CurLineNumber(), CurOffset() )
+ );
+ NeedSYMBOLorNUMBER();
+ if( m_board && FromUTF8() != m_board->FindNet( pad->GetNetCode() )->GetNetname() )
+ THROW_IO_ERROR(
+ wxString::Format( _( "invalid net ID in\nfile: <%s>\nline: %d\noffset: %d" ),
+ GetChars( CurSource() ), CurLineNumber(), CurOffset() )
+ );
+ NeedRIGHT();
+ break;
+
+ case T_die_length:
+ pad->SetPadToDieLength( parseBoardUnits( T_die_length ) );
+ NeedRIGHT();
+ break;
+
+ case T_solder_mask_margin:
+ pad->SetLocalSolderMaskMargin( parseBoardUnits( T_solder_mask_margin ) );
+ NeedRIGHT();
+ break;
+
+ case T_solder_paste_margin:
+ pad->SetLocalSolderPasteMargin( parseBoardUnits( T_solder_paste_margin ) );
+ NeedRIGHT();
+ break;
+
+ case T_solder_paste_margin_ratio:
+ pad->SetLocalSolderPasteMarginRatio(
+ parseDouble( "pad local solder paste margin ratio value" ) );
+ NeedRIGHT();
+ break;
+
+ case T_clearance:
+ pad->SetLocalClearance( parseBoardUnits( "local clearance value" ) );
+ NeedRIGHT();
+ break;
+
+ case T_zone_connect:
+ pad->SetZoneConnection( (ZoneConnection) parseInt( "zone connection value" ) );
+ NeedRIGHT();
+ break;
+
+ case T_thermal_width:
+ pad->SetThermalWidth( parseBoardUnits( T_thermal_width ) );
+ NeedRIGHT();
+ break;
+
+ case T_thermal_gap:
+ pad->SetThermalGap( parseBoardUnits( T_thermal_gap ) );
+ NeedRIGHT();
+ break;
+
+ default:
+ Expecting( "at, drill, layers, net, die_length, solder_mask_margin, "
+ "solder_paste_margin, solder_paste_margin_ratio, clearance, "
+ "zone_connect, thermal_width, or thermal_gap" );
+ }
+ }
+
+ return pad.release();
+}
+
+
+TRACK* PCB_PARSER::parseTRACK() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_segment, NULL,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as TRACK." ) );
+
+ wxPoint pt;
+ T token;
+
+ std::auto_ptr< TRACK > track( new TRACK( m_board ) );
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_start:
+ pt.x = parseBoardUnits( "start x" );
+ pt.y = parseBoardUnits( "start y" );
+ track->SetStart( pt );
+ break;
+
+ case T_end:
+ pt.x = parseBoardUnits( "end x" );
+ pt.y = parseBoardUnits( "end y" );
+ track->SetEnd( pt );
+ break;
+
+ case T_width:
+ track->SetWidth( parseBoardUnits( "width" ) );
+ break;
+
+ case T_layer:
+ track->SetLayer( parseBoardItemLayer() );
+ break;
+
+ case T_net:
+ if( ! track->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true ) )
+ THROW_IO_ERROR(
+ wxString::Format( _( "invalid net ID in\nfile: <%s>\nline: %d\noffset: %d" ),
+ GetChars( CurSource() ), CurLineNumber(), CurOffset() )
+ );
+ break;
+
+ case T_tstamp:
+ track->SetTimeStamp( parseHex() );
+ break;
+
+ case T_status:
+ track->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
+ break;
+
+ default:
+ Expecting( "start, end, width, layer, net, tstamp, or status" );
+ }
+
+ NeedRIGHT();
+ }
+
+ return track.release();
+}
+
+
+VIA* PCB_PARSER::parseVIA() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_via, NULL,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as VIA." ) );
+
+ wxPoint pt;
+ T token;
+
+ std::auto_ptr< VIA > via( new VIA( m_board ) );
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_blind:
+ via->SetViaType( VIA_BLIND_BURIED );
+ break;
+
+ case T_micro:
+ via->SetViaType( VIA_MICROVIA );
+ break;
+
+ case T_at:
+ pt.x = parseBoardUnits( "start x" );
+ pt.y = parseBoardUnits( "start y" );
+ via->SetStart( pt );
+ via->SetEnd( pt );
+ NeedRIGHT();
+ break;
+
+ case T_size:
+ via->SetWidth( parseBoardUnits( "via width" ) );
+ NeedRIGHT();
+ break;
+
+ case T_drill:
+ via->SetDrill( parseBoardUnits( "drill diameter" ) );
+ NeedRIGHT();
+ break;
+
+ case T_layers:
+ {
+ LAYER_ID layer1, layer2;
+ NextTok();
+ layer1 = lookUpLayer<LAYER_ID>( m_layerIndices );
+ NextTok();
+ layer2 = lookUpLayer<LAYER_ID>( m_layerIndices );
+ via->SetLayerPair( layer1, layer2 );
+ NeedRIGHT();
+ }
+ break;
+
+ case T_net:
+ if(! via->SetNetCode( getNetCode( parseInt( "net number" ) ), /* aNoAssert */ true))
+ THROW_IO_ERROR(
+ wxString::Format( _( "invalid net ID in\nfile: <%s>\nline: %d\noffset: %d" ),
+ GetChars( CurSource() ), CurLineNumber(), CurOffset() )
+ );
+ NeedRIGHT();
+ break;
+
+ case T_tstamp:
+ via->SetTimeStamp( parseHex() );
+ NeedRIGHT();
+ break;
+
+ case T_status:
+ via->SetStatus( static_cast<STATUS_FLAGS>( parseHex() ) );
+ NeedRIGHT();
+ break;
+
+ default:
+ Expecting( "blind, micro, at, size, drill, layers, net, tstamp, or status" );
+ }
+ }
+
+ return via.release();
+}
+
+
+ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_zone, NULL,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
+ wxT( " as ZONE_CONTAINER." ) );
+
+ CPolyLine::HATCH_STYLE hatchStyle = CPolyLine::NO_HATCH;
+
+ int hatchPitch = Mils2iu( CPolyLine::GetDefaultHatchPitchMils() );
+ wxPoint pt;
+ T token;
+ int tmp;
+ wxString netnameFromfile; // the zone net name find in file
+
+ // bigger scope since each filled_polygon is concatenated in here
+ SHAPE_POLY_SET pts;
+
+ std::auto_ptr< ZONE_CONTAINER > zone( new ZONE_CONTAINER( m_board ) );
+
+ zone->SetPriority( 0 );
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_net:
+ // Init the net code only, not the netname, to be sure
+ // the zone net name is the name read in file.
+ // (When mismatch, the user will be prompted in DRC, to fix the actual name)
+ tmp = getNetCode( parseInt( "net number" ) );
+
+ if( tmp < 0 )
+ tmp = 0;
+
+ if( ! zone->SetNetCode( tmp, /* aNoAssert */ true ) )
+ THROW_IO_ERROR(
+ wxString::Format( _( "invalid net ID in\nfile: <%s>\nline: %d\noffset: %d" ),
+ GetChars( CurSource() ), CurLineNumber(), CurOffset() )
+ );
+
+ NeedRIGHT();
+ break;
+
+ case T_net_name:
+ NeedSYMBOLorNUMBER();
+ netnameFromfile = FromUTF8();
+ NeedRIGHT();
+ break;
+
+ case T_layer:
+ zone->SetLayer( parseBoardItemLayer() );
+ NeedRIGHT();
+ break;
+
+ case T_tstamp:
+ zone->SetTimeStamp( parseHex() );
+ NeedRIGHT();
+ break;
+
+ case T_hatch:
+ token = NextTok();
+
+ if( token != T_none && token != T_edge && token != T_full )
+ Expecting( "none, edge, or full" );
+
+ switch( token )
+ {
+ default:
+ case T_none: hatchStyle = CPolyLine::NO_HATCH; break;
+ case T_edge: hatchStyle = CPolyLine::DIAGONAL_EDGE; break;
+ case T_full: hatchStyle = CPolyLine::DIAGONAL_FULL;
+ }
+
+ hatchPitch = parseBoardUnits( "hatch pitch" );
+ NeedRIGHT();
+ break;
+
+ case T_priority:
+ zone->SetPriority( parseInt( "zone priority" ) );
+ NeedRIGHT();
+ break;
+
+ case T_connect_pads:
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_yes:
+ zone->SetPadConnection( PAD_ZONE_CONN_FULL );
+ break;
+
+ case T_no:
+ zone->SetPadConnection( PAD_ZONE_CONN_NONE );
+ break;
+
+ case T_thru_hole_only:
+ zone->SetPadConnection( PAD_ZONE_CONN_THT_THERMAL );
+ break;
+
+ case T_clearance:
+ zone->SetZoneClearance( parseBoardUnits( "zone clearance" ) );
+ NeedRIGHT();
+ break;
+
+ default:
+ Expecting( "yes, no, or clearance" );
+ }
+ }
+
+ break;
+
+ case T_min_thickness:
+ zone->SetMinThickness( parseBoardUnits( T_min_thickness ) );
+ NeedRIGHT();
+ break;
+
+ case T_fill:
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_yes:
+ zone->SetIsFilled( true );
+ break;
+
+ case T_mode:
+ token = NextTok();
+
+ if( token != T_segment && token != T_polygon )
+ Expecting( "segment or polygon" );
+
+ // @todo Create an enum for fill modes.
+ zone->SetFillMode( token == T_polygon ? 0 : 1 );
+ NeedRIGHT();
+ break;
+
+ case T_arc_segments:
+ zone->SetArcSegmentCount( parseInt( "arc segment count" ) );
+ NeedRIGHT();
+ break;
+
+ case T_thermal_gap:
+ zone->SetThermalReliefGap( parseBoardUnits( T_thermal_gap ) );
+ NeedRIGHT();
+ break;
+
+ case T_thermal_bridge_width:
+ zone->SetThermalReliefCopperBridge( parseBoardUnits( T_thermal_bridge_width ) );
+ NeedRIGHT();
+ break;
+
+ case T_smoothing:
+ switch( NextTok() )
+ {
+ case T_none:
+ zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_NONE );
+ break;
+
+ case T_chamfer:
+ if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
+ zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_CHAMFER );
+ break;
+
+ case T_fillet:
+ if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
+ zone->SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_FILLET );
+ break;
+
+ default:
+ Expecting( "none, chamfer, or fillet" );
+ }
+ NeedRIGHT();
+ break;
+
+ case T_radius:
+ tmp = parseBoardUnits( "corner radius" );
+ if( !zone->GetIsKeepout() ) // smoothing has meaning only for filled zones
+ zone->SetCornerRadius( tmp );
+ NeedRIGHT();
+ break;
+
+ default:
+ Expecting( "mode, arc_segments, thermal_gap, thermal_bridge_width, "
+ "smoothing, or radius" );
+ }
+ }
+ break;
+
+ case T_keepout:
+ zone->SetIsKeepout( true );
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_tracks:
+ token = NextTok();
+
+ if( token != T_allowed && token != T_not_allowed )
+ Expecting( "allowed or not_allowed" );
+ zone->SetDoNotAllowTracks( token == T_not_allowed );
+ break;
+
+ case T_vias:
+ token = NextTok();
+
+ if( token != T_allowed && token != T_not_allowed )
+ Expecting( "allowed or not_allowed" );
+ zone->SetDoNotAllowVias( token == T_not_allowed );
+ break;
+
+ case T_copperpour:
+ token = NextTok();
+
+ if( token != T_allowed && token != T_not_allowed )
+ Expecting( "allowed or not_allowed" );
+ zone->SetDoNotAllowCopperPour( token == T_not_allowed );
+ break;
+
+ default:
+ Expecting( "tracks, vias or copperpour" );
+ }
+
+ NeedRIGHT();
+ }
+
+ break;
+
+ case T_polygon:
+ {
+ std::vector< wxPoint > corners;
+
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ corners.push_back( parseXY() );
+ }
+
+ NeedRIGHT();
+ zone->AddPolygon( corners );
+ }
+ break;
+
+ case T_filled_polygon:
+ {
+ // "(filled_polygon (pts"
+ NeedLEFT();
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ pts.NewOutline();
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ pts.Append( parseXY() );
+ }
+
+ NeedRIGHT();
+ }
+ break;
+
+ case T_fill_segments:
+ {
+ std::vector< SEGMENT > segs;
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token != T_LEFT )
+ Expecting( T_LEFT );
+
+ token = NextTok();
+
+ if( token != T_pts )
+ Expecting( T_pts );
+
+ SEGMENT segment( parseXY(), parseXY() );
+ NeedRIGHT();
+ segs.push_back( segment );
+ }
+
+ zone->AddFillSegments( segs );
+ }
+ break;
+
+ default:
+ Expecting( "net, layer, tstamp, hatch, priority, connect_pads, min_thickness, "
+ "fill, polygon, filled_polygon, or fill_segments" );
+ }
+ }
+
+ if( zone->GetNumCorners() > 2 )
+ {
+ if( !zone->IsOnCopperLayer() )
+ {
+ zone->SetFillMode( 0 );
+ zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
+ }
+
+ // Set hatch here, after outlines corners are read
+ zone->Outline()->SetHatch( hatchStyle, hatchPitch, true );
+ }
+
+ if( !pts.IsEmpty() )
+ zone->AddFilledPolysList( pts );
+
+ // Ensure keepout and non copper zones do not have a net
+ // (which have no sense for these zones)
+ // the netcode 0 is used for these zones
+ bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsKeepout();
+
+ if( !zone_has_net )
+ zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
+
+ // Ensure the zone net name is valid, and matches the net code, for copper zones
+ if( zone_has_net && ( zone->GetNet()->GetNetname() != netnameFromfile ) )
+ {
+ // Can happens which old boards, with nonexistent nets ...
+ // or after being edited by hand
+ // We try to fix the mismatch.
+ NETINFO_ITEM* net = m_board->FindNet( netnameFromfile );
+
+ if( net ) // An existing net has the same net name. use it for the zone
+ zone->SetNetCode( net->GetNet() );
+ else // Not existing net: add a new net to keep trace of the zone netname
+ {
+ int newnetcode = m_board->GetNetCount();
+ net = new NETINFO_ITEM( m_board, netnameFromfile, newnetcode );
+ m_board->AppendNet( net );
+
+ // Store the new code mapping
+ pushValueIntoMap( newnetcode, net->GetNet() );
+ // and update the zone netcode
+ zone->SetNetCode( net->GetNet() );
+
+ // Prompt the user
+ wxString msg;
+ msg.Printf( _( "There is a zone that belongs to a not existing net\n"
+ "\"%s\"\n"
+ "you should verify and edit it (run DRC test)." ),
+ GetChars( netnameFromfile ) );
+ DisplayError( NULL, msg );
+ }
+ }
+
+ return zone.release();
+}
+
+
+PCB_TARGET* PCB_PARSER::parsePCB_TARGET() throw( IO_ERROR, PARSE_ERROR )
+{
+ wxCHECK_MSG( CurTok() == T_target, NULL,
+ wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as PCB_TARGET." ) );
+
+ wxPoint pt;
+ T token;
+
+ std::auto_ptr< PCB_TARGET > target( new PCB_TARGET( NULL ) );
+
+ for( token = NextTok(); token != T_RIGHT; token = NextTok() )
+ {
+ if( token == T_LEFT )
+ token = NextTok();
+
+ switch( token )
+ {
+ case T_x:
+ target->SetShape( 1 );
+ break;
+
+ case T_plus:
+ target->SetShape( 0 );
+ break;
+
+ case T_at:
+ pt.x = parseBoardUnits( "target x position" );
+ pt.y = parseBoardUnits( "target y position" );
+ target->SetPosition( pt );
+ NeedRIGHT();
+ break;
+
+ case T_size:
+ target->SetSize( parseBoardUnits( "target size" ) );
+ NeedRIGHT();
+ break;
+
+ case T_width:
+ target->SetWidth( parseBoardUnits( "target thickness" ) );
+ NeedRIGHT();
+ break;
+
+ case T_layer:
+ target->SetLayer( parseBoardItemLayer() );
+ NeedRIGHT();
+ break;
+
+ case T_tstamp:
+ target->SetTimeStamp( parseHex() );
+ NeedRIGHT();
+ break;
+
+ default:
+ Expecting( "x, plus, at, size, width, layer or tstamp" );
+ }
+ }
+
+ return target.release();
+}
diff --git a/pcbnew/pcb_parser.h b/pcbnew/pcb_parser.h
new file mode 100644
index 0000000..cd815ad
--- /dev/null
+++ b/pcbnew/pcb_parser.h
@@ -0,0 +1,327 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 CERN
+ * Copyright (C) 2012-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcb_parser.h
+ * @brief Pcbnew s-expression file format parser definition.
+ */
+
+#ifndef _PCBNEW_PARSER_H_
+#define _PCBNEW_PARSER_H_
+
+#include <pcb_lexer.h>
+#include <hashtables.h>
+#include <layers_id_colors_and_visibility.h> // LAYER_ID
+#include <common.h> // KiROUND
+#include <convert_to_biu.h> // IU_PER_MM
+
+
+class BOARD;
+class BOARD_ITEM;
+class D_PAD;
+class DIMENSION;
+class DRAWSEGMENT;
+class EDA_TEXT;
+class EDGE_MODULE;
+class TEXTE_MODULE;
+class TEXTE_PCB;
+class TRACK;
+class MODULE;
+class PCB_TARGET;
+class VIA;
+class S3D_MASTER;
+class ZONE_CONTAINER;
+struct LAYER;
+
+
+/**
+ * Class PCB_PARSER
+ * reads a Pcbnew s-expression formatted #LINE_READER object and returns the appropriate
+ * #BOARD_ITEM object.
+ */
+class PCB_PARSER : public PCB_LEXER
+{
+ typedef boost::unordered_map< std::string, LAYER_ID > LAYER_ID_MAP;
+ typedef boost::unordered_map< std::string, LSET > LSET_MAP;
+
+ BOARD* m_board;
+ LAYER_ID_MAP m_layerIndices; ///< map layer name to it's index
+ LSET_MAP m_layerMasks; ///< map layer names to their masks
+ std::vector<int> m_netCodes; ///< net codes mapping for boards being loaded
+ bool m_tooRecent; ///< true if version parses as later than supported
+ int m_requiredVersion; ///< set to the KiCad format version this board requires
+
+ ///> Converts net code using the mapping table if available,
+ ///> otherwise returns unchanged net code if < 0 or if is is out of range
+ inline int getNetCode( int aNetCode )
+ {
+ if( ( aNetCode >= 0 ) && ( aNetCode < (int) m_netCodes.size() ) )
+ return m_netCodes[aNetCode];
+
+ return aNetCode;
+ }
+
+ /**
+ * function pushValueIntoMap
+ * Add aValue value in netcode mapping (m_netCodes) at index aIndex
+ * ensure there is room in m_netCodes for that, and add room if needed.
+ * @param aIndex = the index ( expected >=0 )of the location to use in m_netCodes
+ * @param aValue = the netcode value to map
+ */
+ void pushValueIntoMap( int aIndex, int aValue );
+
+ /**
+ * Function init
+ * clears and re-establishes m_layerMap with the default layer names.
+ * m_layerMap will have some of its entries overwritten whenever a (new) board
+ * is encountered.
+ */
+ void init();
+
+ void parseHeader() throw( IO_ERROR, PARSE_ERROR );
+ void parseGeneralSection() throw( IO_ERROR, PARSE_ERROR );
+ void parsePAGE_INFO() throw( IO_ERROR, PARSE_ERROR );
+ void parseTITLE_BLOCK() throw( IO_ERROR, PARSE_ERROR );
+
+ void parseLayers() throw( IO_ERROR, PARSE_ERROR );
+ void parseLayer( LAYER* aLayer ) throw( IO_ERROR, PARSE_ERROR );
+
+ void parseSetup() throw( IO_ERROR, PARSE_ERROR );
+ void parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR );
+ void parseNETCLASS() throw( IO_ERROR, PARSE_ERROR );
+
+ DRAWSEGMENT* parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR );
+ TEXTE_PCB* parseTEXTE_PCB() throw( IO_ERROR, PARSE_ERROR );
+ DIMENSION* parseDIMENSION() throw( IO_ERROR, PARSE_ERROR );
+
+ /**
+ * Function parseMODULE
+ * @param aInitialComments may be a pointer to a heap allocated initial comment block
+ * or NULL. If not NULL, then caller has given ownership of a wxArrayString to
+ * this function and care must be taken to delete it even on exception.
+ */
+ MODULE* parseMODULE( wxArrayString* aInitialComments = 0 )
+ throw( IO_ERROR, PARSE_ERROR, FUTURE_FORMAT_ERROR );
+
+ /**
+ * Function parseMODULE_unchecked
+ * Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.
+ */
+ MODULE* parseMODULE_unchecked( wxArrayString* aInitialComments = 0 )
+ throw( IO_ERROR, PARSE_ERROR );
+ TEXTE_MODULE* parseTEXTE_MODULE() throw( IO_ERROR, PARSE_ERROR );
+ EDGE_MODULE* parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR );
+ D_PAD* parseD_PAD( MODULE* aParent = NULL ) throw( IO_ERROR, PARSE_ERROR );
+ TRACK* parseTRACK() throw( IO_ERROR, PARSE_ERROR );
+ VIA* parseVIA() throw( IO_ERROR, PARSE_ERROR );
+ ZONE_CONTAINER* parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR );
+ PCB_TARGET* parsePCB_TARGET() throw( IO_ERROR, PARSE_ERROR );
+ BOARD* parseBOARD() throw( IO_ERROR, PARSE_ERROR, FUTURE_FORMAT_ERROR );
+
+ /**
+ * Function parseBOARD_unchecked
+ * Parse a module, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.
+ */
+ BOARD* parseBOARD_unchecked() throw( IO_ERROR, PARSE_ERROR );
+
+
+ /**
+ * Function lookUpLayer
+ * parses the current token for the layer definition of a #BOARD_ITEM object.
+ *
+ * @param aMap is the LAYER_{NUM|MSK}_MAP to use for the lookup.
+ *
+ * @throw IO_ERROR if the layer is not valid.
+ * @throw PARSE_ERROR if the layer syntax is incorrect.
+ * @return int - The result of the parsed #BOARD_ITEM layer or set designator.
+ */
+ template<class T, class M>
+ T lookUpLayer( const M& aMap ) throw( PARSE_ERROR, IO_ERROR );
+
+ /**
+ * Function parseBoardItemLayer
+ * parses the layer definition of a #BOARD_ITEM object.
+ *
+ * @throw IO_ERROR if the layer is not valid.
+ * @throw PARSE_ERROR if the layer syntax is incorrect.
+ * @return The index the parsed #BOARD_ITEM layer.
+ */
+ LAYER_ID parseBoardItemLayer() throw( IO_ERROR, PARSE_ERROR );
+
+ /**
+ * Function parseBoardItemLayersAsMask
+ * parses the layers definition of a #BOARD_ITEM object.
+ *
+ * @throw IO_ERROR if any of the layers is not valid.
+ * @throw PARSE_ERROR if the layers syntax is incorrect.
+ * @return The mask of layers the parsed #BOARD_ITEM is on.
+ */
+ LSET parseBoardItemLayersAsMask() throw( PARSE_ERROR, IO_ERROR );
+
+ /**
+ * Function parseXY
+ * parses a coordinate pair (xy X Y) in board units (mm).
+ *
+ * The parser checks if the previous token was T_LEFT and parses the remainder of
+ * the token syntax. This is used when parsing a list of coordinate points. This
+ * way the parser can be used in either case.
+ *
+ * @throw PARSE_ERROR if the coordinate pair syntax is incorrect.
+ * @return A wxPoint object containing the coordinate pair.
+ */
+ wxPoint parseXY() throw( PARSE_ERROR, IO_ERROR );
+
+ void parseXY( int* aX, int* aY ) throw( PARSE_ERROR, IO_ERROR );
+
+ /**
+ * Function parseEDA_TEXT
+ * parses the common settings for any object derived from #EDA_TEXT.
+ *
+ * @throw PARSE_ERROR if the text syntax is not valid.
+ * @param aText A point to the #EDA_TEXT object to save the parsed settings into.
+ */
+ void parseEDA_TEXT( EDA_TEXT* aText ) throw( PARSE_ERROR, IO_ERROR );
+
+ S3D_MASTER* parse3DModel() throw( PARSE_ERROR, IO_ERROR );
+
+ /**
+ * Function parseDouble
+ * parses the current token as an ASCII numeric string with possible leading
+ * whitespace into a double precision floating point number.
+ *
+ * @throw IO_ERROR if an error occurs attempting to convert the current token.
+ * @return The result of the parsed token.
+ */
+ double parseDouble() throw( IO_ERROR );
+
+ inline double parseDouble( const char* aExpected ) throw( IO_ERROR )
+ {
+ NeedNUMBER( aExpected );
+ return parseDouble();
+ }
+
+ inline double parseDouble( PCB_KEYS_T::T aToken ) throw( IO_ERROR )
+ {
+ return parseDouble( GetTokenText( aToken ) );
+ }
+
+ inline int parseBoardUnits() throw( IO_ERROR )
+ {
+ // There should be no major rounding issues here, since the values in
+ // the file are in mm and get converted to nano-meters.
+ // See test program tools/test-nm-biu-to-ascii-mm-round-tripping.cpp
+ // to confirm or experiment. Use a similar strategy in both places, here
+ // and in the test program. Make that program with:
+ // $ make test-nm-biu-to-ascii-mm-round-tripping
+ return KiROUND( parseDouble() * IU_PER_MM );
+ }
+
+ inline int parseBoardUnits( const char* aExpected ) throw( PARSE_ERROR, IO_ERROR )
+ {
+ // Use here KiROUND, not KIROUND (see comments about them)
+ // when having a function as argument, because it will be called twice
+ // with KIROUND
+ return KiROUND( parseDouble( aExpected ) * IU_PER_MM );
+ }
+
+ inline int parseBoardUnits( PCB_KEYS_T::T aToken ) throw( PARSE_ERROR, IO_ERROR )
+ {
+ return parseBoardUnits( GetTokenText( aToken ) );
+ }
+
+ inline int parseInt() throw( PARSE_ERROR )
+ {
+ return (int)strtol( CurText(), NULL, 10 );
+ }
+
+ inline int parseInt( const char* aExpected ) throw( PARSE_ERROR )
+ {
+ NeedNUMBER( aExpected );
+ return parseInt();
+ }
+
+ inline long parseHex() throw( PARSE_ERROR )
+ {
+ NextTok();
+ return strtol( CurText(), NULL, 16 );
+ }
+
+ bool parseBool() throw( PARSE_ERROR );
+
+ /**
+ * Parse a format version tag like (version 20160417) return the version.
+ * Expects to start on 'version', and eats the closing paren.
+ */
+ int parseVersion() throw( IO_ERROR, PARSE_ERROR );
+
+public:
+
+ PCB_PARSER( LINE_READER* aReader = NULL ) :
+ PCB_LEXER( aReader ),
+ m_board( 0 )
+ {
+ init();
+ }
+
+ // ~PCB_PARSER() {}
+
+ /**
+ * Function SetLineReader
+ * sets @a aLineReader into the parser, and returns the previous one, if any.
+ * @param aReader is what to read from for tokens, no ownership is received.
+ * @return LINE_READER* - previous LINE_READER or NULL if none.
+ */
+ LINE_READER* SetLineReader( LINE_READER* aReader )
+ {
+ LINE_READER* ret = PopReader();
+ PushReader( aReader );
+ return ret;
+ }
+
+ void SetBoard( BOARD* aBoard )
+ {
+ init();
+ m_board = aBoard;
+ }
+
+ BOARD_ITEM* Parse() throw( IO_ERROR, PARSE_ERROR );
+
+ /**
+ * Return whether a version number, if any was parsed, was too recent
+ */
+ bool IsTooRecent()
+ {
+ return m_tooRecent;
+ }
+
+ /**
+ * Return a string representing the version of kicad required to open this
+ * file. Not particularly meaningful if IsTooRecent() returns false.
+ */
+ wxString GetRequiredVersion();
+
+};
+
+
+#endif // _PCBNEW_PARSER_H_
diff --git a/pcbnew/pcb_plot_params.cpp b/pcbnew/pcb_plot_params.cpp
new file mode 100644
index 0000000..6e23b1e
--- /dev/null
+++ b/pcbnew/pcb_plot_params.cpp
@@ -0,0 +1,579 @@
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+//#include <wx/wx.h>
+#include <pcb_plot_params_parser.h>
+#include <pcb_plot_params.h>
+#include <layers_id_colors_and_visibility.h>
+#include <plot_common.h>
+#include <macros.h>
+#include <convert_to_biu.h>
+
+
+#define PLOT_LINEWIDTH_MIN (0.02*IU_PER_MM) // min value for default line thickness
+#define PLOT_LINEWIDTH_MAX (2*IU_PER_MM) // max value for default line thickness
+#define PLOT_LINEWIDTH_DEFAULT (0.15*IU_PER_MM) // def. value for default line thickness
+#define HPGL_PEN_DIAMETER_MIN 0
+#define HPGL_PEN_DIAMETER_MAX 100 // Unit = mil
+#define HPGL_PEN_SPEED_MIN 1 // this param is always in cm/s
+#define HPGL_PEN_SPEED_MAX 99 // this param is always in cm/s
+#define HPGL_PEN_NUMBER_MIN 1
+#define HPGL_PEN_NUMBER_MAX 16
+#define HPGL_PEN_OVERLAP_MIN 0
+#define HPGL_PEN_OVERLAP_MAX 50 // Unit = mil
+
+
+/**
+ * Default line thickness in internal units used to draw or plot items using a
+ * default thickness line value (Frame references)
+ */
+int g_DrawDefaultLineThickness = PLOT_LINEWIDTH_DEFAULT;
+
+// default trailing digits in Gerber coordinates, when units are mm
+// This is also the max usable precision (i.e. internal Pcbnew Units)
+static const int gbrDefaultPrecision = 6;
+
+
+using namespace PCBPLOTPARAMS_T;
+
+
+static const char* getTokenName( T aTok )
+{
+ return PCB_PLOT_PARAMS_LEXER::TokenName( aTok );
+}
+
+
+static bool setInt( int* aInt, int aValue, int aMin, int aMax )
+{
+ int temp = aValue;
+
+ if( aValue < aMin )
+ temp = aMin;
+ else if( aValue > aMax )
+ temp = aMax;
+
+ *aInt = temp;
+ return (temp == aValue);
+}
+
+// PCB_PLOT_PARAMS
+
+PCB_PLOT_PARAMS::PCB_PLOT_PARAMS() :
+ m_layerSelection( 4, B_Cu, F_Cu, F_SilkS, B_SilkS )
+{
+ m_useGerberProtelExtensions = false;
+ m_useGerberAttributes = false;
+ m_gerberPrecision = gbrDefaultPrecision;
+ m_excludeEdgeLayer = true;
+ m_lineWidth = g_DrawDefaultLineThickness;
+ m_plotFrameRef = false;
+ m_plotViaOnMaskLayer = false;
+ m_plotMode = FILLED;
+ m_DXFplotPolygonMode = true;
+ m_useAuxOrigin = false;
+ m_HPGLPenNum = 1;
+ m_HPGLPenSpeed = 20; // this param is always in cm/s
+ m_HPGLPenDiam = 15; // in mils
+ m_HPGLPenOvr = 2; // in mils
+ m_negative = false;
+ m_A4Output = false;
+ m_plotReference = true;
+ m_plotValue = true;
+ m_plotInvisibleText = false;
+ m_plotPadsOnSilkLayer = false;
+ m_subtractMaskFromSilk = false;
+ m_format = PLOT_FORMAT_GERBER;
+ m_mirror = false;
+ m_drillMarks = SMALL_DRILL_SHAPE;
+ m_autoScale = false;
+ m_scale = 1.0;
+ m_scaleSelection = 1;
+ m_fineScaleAdjustX = 1.0;
+ m_fineScaleAdjustY = 1.0;
+ m_widthAdjust = 0.;
+ m_outputDirectory.clear();
+ m_color = BLACK;
+ m_textMode = PLOTTEXTMODE_DEFAULT;
+
+ // This parameter controls if the NPTH pads will be plotted or not
+ // it is a "local" parameter
+ m_skipNPTH_Pads = false;
+}
+
+void PCB_PLOT_PARAMS::SetGerberPrecision( int aPrecision )
+{
+ // Currently geber files use mm.
+ // accepted precision is only 6 (max value, this is the resolution of Pcbnew)
+ // or 5, min value for professional boards, when 6 creates problems
+ // to board makers.
+
+ m_gerberPrecision = aPrecision == gbrDefaultPrecision-1 ? gbrDefaultPrecision-1 :
+ gbrDefaultPrecision;
+}
+
+
+// PLEASE NOTE: only plot dialog options are processed
+void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter,
+ int aNestLevel, int aControl ) const throw( IO_ERROR )
+{
+ const char* falseStr = getTokenName( T_false );
+ const char* trueStr = getTokenName( T_true );
+
+ aFormatter->Print( aNestLevel, "(%s\n", getTokenName( T_pcbplotparams ) );
+
+ aFormatter->Print( aNestLevel+1, "(%s 0x%s)\n", getTokenName( T_layerselection ),
+ m_layerSelection.FmtHex().c_str() );
+
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberextensions ),
+ m_useGerberProtelExtensions ? trueStr : falseStr );
+
+ if( m_useGerberAttributes ) // save this option only if active,
+ // to avoid incompatibility with older Pcbnew version
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberattributes ), trueStr );
+
+ if( m_gerberPrecision != gbrDefaultPrecision ) // save this option only if it is not the default value,
+ // to avoid incompatibility with older Pcbnew version
+ aFormatter->Print( aNestLevel+1, "(%s %d)\n",
+ getTokenName( T_gerberprecision ), m_gerberPrecision );
+
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_excludeedgelayer ),
+ m_excludeEdgeLayer ? trueStr : falseStr );
+ aFormatter->Print( aNestLevel+1, "(%s %f)\n", getTokenName( T_linewidth ),
+ m_lineWidth / IU_PER_MM );
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_plotframeref ),
+ m_plotFrameRef ? trueStr : falseStr );
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_viasonmask ),
+ m_plotViaOnMaskLayer ? trueStr : falseStr );
+ aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_mode ),
+ GetPlotMode() == SKETCH ? 2 : 1 ); // Value 0 (LINE mode) no more used
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_useauxorigin ),
+ m_useAuxOrigin ? trueStr : falseStr );
+ aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_hpglpennumber ),
+ m_HPGLPenNum );
+
+ // Obsolete parameter, pen speed is no more managed, because hpgl format
+ // is now an export format, and for this, pen speed has no meaning
+ // aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_hpglpenspeed ),
+ // m_HPGLPenSpeed );
+
+ aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_hpglpenspeed ),
+ m_HPGLPenSpeed );
+ aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_hpglpendiameter ),
+ m_HPGLPenDiam );
+ aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_hpglpenoverlay ),
+ m_HPGLPenOvr );
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_psnegative ),
+ m_negative ? trueStr : falseStr );
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_psa4output ),
+ m_A4Output ? trueStr : falseStr );
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_plotreference ),
+ m_plotReference ? trueStr : falseStr );
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_plotvalue ),
+ m_plotValue ? trueStr : falseStr );
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_plotinvisibletext ),
+ m_plotInvisibleText ? trueStr : falseStr );
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_padsonsilk ),
+ m_plotPadsOnSilkLayer ? trueStr : falseStr );
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_subtractmaskfromsilk ),
+ m_subtractMaskFromSilk ? trueStr : falseStr );
+ aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_outputformat ),
+ m_format );
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_mirror ),
+ m_mirror ? trueStr : falseStr );
+ aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_drillshape ),
+ m_drillMarks );
+ aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_scaleselection ),
+ m_scaleSelection );
+ aFormatter->Print( aNestLevel+1, "(%s %s)", getTokenName( T_outputdirectory ),
+ aFormatter->Quotew( m_outputDirectory ).c_str() );
+ aFormatter->Print( 0, ")\n" );
+}
+
+
+void PCB_PLOT_PARAMS::Parse( PCB_PLOT_PARAMS_PARSER* aParser )
+ throw( PARSE_ERROR, IO_ERROR )
+{
+ aParser->Parse( this );
+}
+
+
+bool PCB_PLOT_PARAMS::IsSameAs( const PCB_PLOT_PARAMS &aPcbPlotParams, bool aCompareOnlySavedPrms ) const
+{
+ if( m_layerSelection != aPcbPlotParams.m_layerSelection )
+ return false;
+ if( m_useGerberProtelExtensions != aPcbPlotParams.m_useGerberProtelExtensions )
+ return false;
+ if( m_useGerberAttributes != aPcbPlotParams.m_useGerberAttributes )
+ return false;
+ if( m_gerberPrecision != aPcbPlotParams.m_gerberPrecision )
+ return false;
+ if( m_excludeEdgeLayer != aPcbPlotParams.m_excludeEdgeLayer )
+ return false;
+ if( m_lineWidth != aPcbPlotParams.m_lineWidth )
+ return false;
+ if( m_plotFrameRef != aPcbPlotParams.m_plotFrameRef )
+ return false;
+ if( m_plotViaOnMaskLayer != aPcbPlotParams.m_plotViaOnMaskLayer )
+ return false;
+ if( m_plotMode != aPcbPlotParams.m_plotMode )
+ return false;
+
+ if( !aCompareOnlySavedPrms )
+ {
+ if( m_DXFplotPolygonMode != aPcbPlotParams.m_DXFplotPolygonMode )
+ return false;
+ }
+
+ if( m_useAuxOrigin != aPcbPlotParams.m_useAuxOrigin )
+ return false;
+ if( m_HPGLPenNum != aPcbPlotParams.m_HPGLPenNum )
+ return false;
+ if( m_HPGLPenSpeed != aPcbPlotParams.m_HPGLPenSpeed )
+ return false;
+ if( m_HPGLPenDiam != aPcbPlotParams.m_HPGLPenDiam )
+ return false;
+ if( m_HPGLPenOvr != aPcbPlotParams.m_HPGLPenOvr )
+ return false;
+ if( m_negative != aPcbPlotParams.m_negative )
+ return false;
+ if( m_A4Output != aPcbPlotParams.m_A4Output )
+ return false;
+ if( m_plotReference != aPcbPlotParams.m_plotReference )
+ return false;
+ if( m_plotValue != aPcbPlotParams.m_plotValue )
+ return false;
+ if( m_plotInvisibleText != aPcbPlotParams.m_plotInvisibleText )
+ return false;
+ if( m_plotPadsOnSilkLayer != aPcbPlotParams.m_plotPadsOnSilkLayer )
+ return false;
+ if( m_subtractMaskFromSilk != aPcbPlotParams.m_subtractMaskFromSilk )
+ return false;
+ if( m_format != aPcbPlotParams.m_format )
+ return false;
+ if( m_mirror != aPcbPlotParams.m_mirror )
+ return false;
+ if( m_drillMarks != aPcbPlotParams.m_drillMarks )
+ return false;
+ if( m_scaleSelection != aPcbPlotParams.m_scaleSelection )
+ return false;
+ if( m_autoScale != aPcbPlotParams.m_autoScale )
+ return false;
+ if( m_scale != aPcbPlotParams.m_scale )
+ return false;
+ if( m_fineScaleAdjustX != aPcbPlotParams.m_fineScaleAdjustX )
+ return false;
+ if( m_fineScaleAdjustY != aPcbPlotParams.m_fineScaleAdjustY )
+ return false;
+ if( m_widthAdjust != aPcbPlotParams.m_widthAdjust )
+ return false;
+
+ if( !aCompareOnlySavedPrms )
+ {
+ if( m_color != aPcbPlotParams.m_color )
+ return false;
+ }
+
+ if( m_textMode != aPcbPlotParams.m_textMode )
+ return false;
+ if( !m_outputDirectory.IsSameAs( aPcbPlotParams.m_outputDirectory ) )
+ return false;
+ return true;
+}
+
+
+bool PCB_PLOT_PARAMS::SetHPGLPenDiameter( int aValue )
+{
+ return setInt( &m_HPGLPenDiam, aValue, HPGL_PEN_DIAMETER_MIN, HPGL_PEN_DIAMETER_MAX );
+}
+
+
+bool PCB_PLOT_PARAMS::SetHPGLPenSpeed( int aValue )
+{
+ return setInt( &m_HPGLPenSpeed, aValue, HPGL_PEN_SPEED_MIN, HPGL_PEN_SPEED_MAX );
+}
+
+
+bool PCB_PLOT_PARAMS::SetHPGLPenOverlay( int aValue )
+{
+ return setInt( &m_HPGLPenOvr, aValue, HPGL_PEN_OVERLAP_MIN, HPGL_PEN_OVERLAP_MAX );
+}
+
+
+bool PCB_PLOT_PARAMS::SetLineWidth( int aValue )
+{
+ return setInt( &m_lineWidth, aValue, PLOT_LINEWIDTH_MIN, PLOT_LINEWIDTH_MAX );
+}
+
+// PCB_PLOT_PARAMS_PARSER
+
+PCB_PLOT_PARAMS_PARSER::PCB_PLOT_PARAMS_PARSER( LINE_READER* aReader ) :
+ PCB_PLOT_PARAMS_LEXER( aReader )
+{
+}
+
+
+PCB_PLOT_PARAMS_PARSER::PCB_PLOT_PARAMS_PARSER( char* aLine, const wxString& aSource ) :
+ PCB_PLOT_PARAMS_LEXER( aLine, aSource )
+{
+}
+
+
+void PCB_PLOT_PARAMS_PARSER::Parse( PCB_PLOT_PARAMS* aPcbPlotParams )
+ throw( PARSE_ERROR, IO_ERROR )
+{
+ T token;
+
+ while( ( token = NextTok() ) != T_RIGHT )
+ {
+ if( token == T_EOF)
+ Unexpected( T_EOF );
+
+ if( token == T_LEFT )
+ token = NextTok();
+
+ if( token == T_pcbplotparams )
+ continue;
+
+ bool skip_right = false;
+
+ switch( token )
+ {
+ case T_layerselection:
+ {
+ token = NeedSYMBOLorNUMBER();
+
+ const std::string& cur = CurStr();
+
+ if( token == T_NUMBER ) // pretty 3 format had legacy Cu stack.
+ {
+ // unsigned legacy_mask = atol( cur.c_str() );
+
+ /* It's not possible to convert a legacy Cu layer number to a new
+ Cu layer number without knowing the number or total Cu layers
+ in the legacy board. We do not have that information here.
+ So simply set all layers ON. User can turn them off in the UI.
+ This is one of the superiorities of the new Cu sequence.
+ aPcbPlotParams->m_layerSelection = LEGACY_PLUGIN::leg_mask2new( cu_count, legacy_mask );
+ */
+
+ // sorry, use the UI once to fix:
+ aPcbPlotParams->m_layerSelection = LSET( 4, B_Cu, F_Cu, F_SilkS, B_SilkS );
+ }
+ else if( cur.find_first_of( "0x" ) == 0 ) // pretty ver. 4.
+ {
+ // skip the leading 2 0x bytes.
+ aPcbPlotParams->m_layerSelection.ParseHex( cur.c_str()+2, cur.size()-2 );
+ }
+ else
+ Expecting( "integer or hex layerSelection" );
+ }
+ break;
+
+ case T_usegerberextensions:
+ aPcbPlotParams->m_useGerberProtelExtensions = parseBool();
+ break;
+
+ case T_usegerberattributes:
+ aPcbPlotParams->m_useGerberAttributes = parseBool();
+ break;
+
+ case T_gerberprecision:
+ aPcbPlotParams->m_gerberPrecision =
+ parseInt( gbrDefaultPrecision-1, gbrDefaultPrecision);
+ break;
+
+ case T_psa4output:
+ aPcbPlotParams->m_A4Output = parseBool();
+ break;
+
+ case T_excludeedgelayer:
+ aPcbPlotParams->m_excludeEdgeLayer = parseBool();
+ break;
+
+ case T_linewidth:
+ {
+ // Due to a bug, this (minor) parameter was saved in biu
+ // and now is saved in mm
+ // If the read value is outside bounds, force a default value
+ double tmp = parseDouble();
+ if( !aPcbPlotParams->SetLineWidth( KiROUND( tmp * IU_PER_MM ) ) )
+ aPcbPlotParams->SetLineWidth( PLOT_LINEWIDTH_DEFAULT );
+ }
+ break;
+
+ case T_plotframeref:
+ aPcbPlotParams->m_plotFrameRef = parseBool();
+ break;
+
+ case T_viasonmask:
+ aPcbPlotParams->m_plotViaOnMaskLayer = parseBool();
+ break;
+
+ case T_mode:
+ aPcbPlotParams->SetPlotMode( parseInt( 0, 2 ) > 1 ? SKETCH : FILLED );
+ break;
+
+ case T_useauxorigin:
+ aPcbPlotParams->m_useAuxOrigin = parseBool();
+ break;
+
+ case T_hpglpennumber:
+ aPcbPlotParams->m_HPGLPenNum = parseInt( HPGL_PEN_NUMBER_MIN,
+ HPGL_PEN_NUMBER_MAX );
+ break;
+ case T_hpglpenspeed:
+ aPcbPlotParams->m_HPGLPenSpeed = parseInt( HPGL_PEN_SPEED_MIN,
+ HPGL_PEN_SPEED_MAX );
+ break;
+ case T_hpglpendiameter:
+ aPcbPlotParams->m_HPGLPenDiam = parseInt( HPGL_PEN_DIAMETER_MIN,
+ HPGL_PEN_DIAMETER_MAX );
+ break;
+ case T_hpglpenoverlay:
+ aPcbPlotParams->m_HPGLPenOvr = parseInt( HPGL_PEN_OVERLAP_MIN,
+ HPGL_PEN_OVERLAP_MAX );
+ break;
+ case T_pscolor:
+ NeedSYMBOL(); // This actually was never used...
+ break;
+
+ case T_psnegative:
+ aPcbPlotParams->m_negative = parseBool();
+ break;
+
+ case T_plotreference:
+ aPcbPlotParams->m_plotReference = parseBool();
+ break;
+
+ case T_plotvalue:
+ aPcbPlotParams->m_plotValue = parseBool();
+ break;
+
+ case T_plotinvisibletext:
+ aPcbPlotParams->m_plotInvisibleText = parseBool();
+ break;
+
+ case T_padsonsilk:
+ aPcbPlotParams->m_plotPadsOnSilkLayer= parseBool();
+ break;
+
+ case T_subtractmaskfromsilk:
+ aPcbPlotParams->m_subtractMaskFromSilk = parseBool();
+ break;
+
+ case T_outputformat:
+ aPcbPlotParams->m_format = static_cast<PlotFormat>(
+ parseInt( PLOT_FIRST_FORMAT, PLOT_LAST_FORMAT ) );
+ break;
+
+ case T_mirror:
+ aPcbPlotParams->m_mirror = parseBool();
+ break;
+
+ case T_drillshape:
+ aPcbPlotParams->m_drillMarks = static_cast<PCB_PLOT_PARAMS::DrillMarksType>
+ ( parseInt( 0, 2 ) );
+ break;
+
+ case T_scaleselection:
+ aPcbPlotParams->m_scaleSelection = parseInt( 0, 4 );
+ break;
+
+ case T_outputdirectory:
+ NeedSYMBOL();
+ aPcbPlotParams->m_outputDirectory = FROM_UTF8( CurText() );
+ break;
+
+ default:
+ skipCurrent(); // skip unknown or outdated plot parameter
+ skip_right = true; // the closing right token is already read.
+ break;
+ }
+
+ if( ! skip_right )
+ NeedRIGHT();
+ }
+}
+
+
+bool PCB_PLOT_PARAMS_PARSER::parseBool()
+{
+ T token = NeedSYMBOL();
+
+ if( token != T_false && token != T_true )
+ Expecting( "true|false" );
+
+ return token == T_true;
+}
+
+
+int PCB_PLOT_PARAMS_PARSER::parseInt( int aMin, int aMax )
+{
+ T token = NextTok();
+
+ if( token != T_NUMBER )
+ Expecting( T_NUMBER );
+
+ int val = atoi( CurText() );
+
+ if( val < aMin )
+ val = aMin;
+ else if( val > aMax )
+ val = aMax;
+
+ return val;
+}
+
+
+double PCB_PLOT_PARAMS_PARSER::parseDouble()
+{
+ T token = NextTok();
+
+ if( token != T_NUMBER )
+ Expecting( T_NUMBER );
+
+ double val = strtod( CurText(), NULL );
+
+ return val;
+}
+
+void PCB_PLOT_PARAMS_PARSER::skipCurrent() throw( IO_ERROR, PARSE_ERROR )
+{
+ int curr_level = 0;
+ T token;
+
+ while( ( token = NextTok() ) != T_EOF )
+ {
+ if( token == T_LEFT )
+ curr_level--;
+
+ if( token == T_RIGHT )
+ {
+ curr_level++;
+
+ if( curr_level > 0 )
+ return;
+ }
+ }
+}
diff --git a/pcbnew/pcb_plot_params.h b/pcbnew/pcb_plot_params.h
new file mode 100644
index 0000000..def8b5c
--- /dev/null
+++ b/pcbnew/pcb_plot_params.h
@@ -0,0 +1,292 @@
+#ifndef PCB_PLOT_PARAMS_H_
+#define PCB_PLOT_PARAMS_H_
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wx/wx.h>
+#include <eda_text.h> // EDA_DRAW_MODE_T
+#include <plot_common.h>
+#include <layers_id_colors_and_visibility.h>
+
+class PCB_PLOT_PARAMS_PARSER;
+
+/**
+ * Class PCB_PLOT_PARAMS
+ * handles plot parameters and options when plotting/printing a board.
+ */
+class PCB_PLOT_PARAMS
+{
+ friend class PCB_PLOT_PARAMS_PARSER;
+public:
+ enum DrillMarksType {
+ NO_DRILL_SHAPE = 0,
+ SMALL_DRILL_SHAPE = 1,
+ FULL_DRILL_SHAPE = 2
+ };
+
+private:
+ // If true, do not plot NPTH pads
+ // (mainly used to disable NPTH pads plotting on copper layers)
+ bool m_skipNPTH_Pads;
+
+ /** FILLED or SKETCH selects how to plot filled objects.
+ * FILLED or SKETCH not available with all drivers: some have fixed mode
+ */
+ EDA_DRAW_MODE_T m_plotMode;
+
+ /** DXF format: Plot items in outline (polygon) mode
+ * In polygon mode, each item to plot is converted to a polygon, and all
+ * polygons are merged.
+ */
+ bool m_DXFplotPolygonMode;
+
+ /// Plot format type (chooses the driver to be used)
+ PlotFormat m_format;
+
+ /// Holes can be not plotted, have a small mark or plotted in actual size
+ DrillMarksType m_drillMarks;
+
+ /// Choose how represent text with PS, PDF and DXF drivers
+ PlotTextMode m_textMode;
+
+ /// The default line width (used to draw items having no defined width)
+ int m_lineWidth;
+
+ /// When true set the scale to fit the board in the page
+ bool m_autoScale;
+
+ /// Global scale factor, 1.0 plots a board with its actual size.
+ double m_scale;
+
+ /// Mirror the plot around the X axis
+ bool m_mirror;
+
+ /// Plot in negative color (supported only by some drivers)
+ bool m_negative;
+
+ /// True if vias are drawn on Mask layer (ie untented, *exposed* by mask)
+ bool m_plotViaOnMaskLayer;
+
+ /// True to plot/print frame references
+ bool m_plotFrameRef;
+
+ /// If false always plot (merge) the pcb edge layer on other layers
+ bool m_excludeEdgeLayer;
+
+ /// Set of layers to plot
+ LSET m_layerSelection;
+
+ /** When plotting gerber files, use a conventional set of Protel extensions
+ * instead of .gbr, that is now the offical gerber file extension
+ * this is a deprecated feature
+ */
+ bool m_useGerberProtelExtensions;
+
+ /// Include attributes from the Gerber X2 format (chapter 5 in revision J2)
+ bool m_useGerberAttributes;
+
+ /// precision of coordinates in Gerber files: accepted 5 or 6
+ /// when units are in mm (6 or 7 in inches, but Pcbnew uses mm).
+ /// 6 is the internal resolution of Pcbnew, but not alwys accepted by board maker
+ /// 5 is the minimal value for professional boards.
+ int m_gerberPrecision;
+
+ /// Plot gerbers using auxiliary (drill) origin instead of absolute coordinates
+ bool m_useAuxOrigin;
+
+ /// On gerbers 'scrape' away the solder mask from silkscreen (trim silks)
+ bool m_subtractMaskFromSilk;
+
+ /// Autoscale the plot to fit an A4 (landscape?) sheet
+ bool m_A4Output;
+
+ /// Scale ratio index (UI only)
+ int m_scaleSelection;
+
+ /// Output directory for plot files (usually relative to the board file)
+ wxString m_outputDirectory;
+
+ /// Enable plotting of part references
+ bool m_plotReference;
+
+ /// Enable plotting of part values
+ bool m_plotValue;
+
+ /// Force plotting of fields marked invisible
+ bool m_plotInvisibleText;
+
+ /// Allows pads outlines on silkscreen layer
+ /// (when pads are also on silk screen)
+ bool m_plotPadsOnSilkLayer;
+
+ /* These next two scale factors are intended to compensate plotters
+ * (mainly printers) X and Y scale error. Therefore they are expected very
+ * near 1.0; only X and Y dimensions are adjusted: circles are plotted as
+ * circles, even if X and Y fine scale differ; because of this it is mostly
+ * useful for printers: postscript plots would be best adjusted using
+ * the prologue (that would change the whole output matrix
+ */
+ double m_fineScaleAdjustX; ///< fine scale adjust X axis
+ double m_fineScaleAdjustY; ///< fine scale adjust Y axis
+
+ /** This width factor is intended to compensate PS printers/ plotters that do
+ * not strictly obey line width settings. Only used to plot pads and tracks
+ */
+ int m_widthAdjust;
+
+ int m_HPGLPenNum; ///< HPGL only: pen number selection(1 to 9)
+ int m_HPGLPenSpeed; ///< HPGL only: pen speed, always in cm/s (1 to 99 cm/s)
+ int m_HPGLPenDiam; ///< HPGL only: pen diameter in MILS, useful to fill areas
+ int m_HPGLPenOvr; ///< HPGL only: pen overlay in MILS, useful only to fill areas
+ EDA_COLOR_T m_color; ///< Color for plotting the current layer
+
+public:
+ PCB_PLOT_PARAMS();
+
+ void SetSkipPlotNPTH_Pads( bool aSkip ) { m_skipNPTH_Pads = aSkip; }
+ bool GetSkipPlotNPTH_Pads() const { return m_skipNPTH_Pads; }
+
+ void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl=0 )
+ const throw( IO_ERROR );
+ void Parse( PCB_PLOT_PARAMS_PARSER* aParser ) throw( PARSE_ERROR, IO_ERROR );
+
+ /**
+ * Compare current settings to aPcbPlotParams, including not saved parameters in brd file
+ * @param aPcbPlotParams = the PCB_PLOT_PARAMS to compare
+ * @param aCompareOnlySavedPrms = true to compare only saved in file parameters,
+ * and false to compare the full set of parameters.
+ * @return true is parameters are same, false if one (or more) parameter does not match
+ */
+ bool IsSameAs( const PCB_PLOT_PARAMS &aPcbPlotParams, bool aCompareOnlySavedPrms ) const;
+
+ void SetColor( EDA_COLOR_T aVal ) { m_color = aVal; }
+ EDA_COLOR_T GetColor() const { return m_color; }
+
+ void SetTextMode( PlotTextMode aVal ) { m_textMode = aVal; }
+ PlotTextMode GetTextMode() const { return m_textMode; }
+
+ void SetPlotMode( EDA_DRAW_MODE_T aPlotMode ) { m_plotMode = aPlotMode; }
+ EDA_DRAW_MODE_T GetPlotMode() const { return m_plotMode; }
+
+ void SetDXFPlotPolygonMode( bool aFlag ) { m_DXFplotPolygonMode = aFlag; }
+ bool GetDXFPlotPolygonMode() const { return m_DXFplotPolygonMode; }
+
+ void SetDrillMarksType( DrillMarksType aVal ) { m_drillMarks = aVal; }
+ DrillMarksType GetDrillMarksType() const { return m_drillMarks; }
+
+ void SetScale( double aVal ) { m_scale = aVal; }
+ double GetScale() const { return m_scale; }
+
+ void SetFineScaleAdjustX( double aVal ) { m_fineScaleAdjustX = aVal; }
+ double GetFineScaleAdjustX() const { return m_fineScaleAdjustX; }
+ void SetFineScaleAdjustY( double aVal ) { m_fineScaleAdjustY = aVal; }
+ double GetFineScaleAdjustY() const { return m_fineScaleAdjustY; }
+ void SetWidthAdjust( int aVal ) { m_widthAdjust = aVal; }
+ int GetWidthAdjust() const { return m_widthAdjust; }
+
+ void SetAutoScale( bool aFlag ) { m_autoScale = aFlag; }
+ bool GetAutoScale() const { return m_autoScale; }
+
+ void SetMirror( bool aFlag ) { m_mirror = aFlag; }
+ bool GetMirror() const { return m_mirror; }
+
+ void SetPlotPadsOnSilkLayer( bool aFlag ) { m_plotPadsOnSilkLayer = aFlag; }
+ bool GetPlotPadsOnSilkLayer() const { return m_plotPadsOnSilkLayer; }
+
+ void SetPlotInvisibleText( bool aFlag ) { m_plotInvisibleText = aFlag; }
+ bool GetPlotInvisibleText() const { return m_plotInvisibleText; }
+ void SetPlotValue( bool aFlag ) { m_plotValue = aFlag; }
+ bool GetPlotValue() const { return m_plotValue; }
+ void SetPlotReference( bool aFlag ) { m_plotReference = aFlag; }
+ bool GetPlotReference() const { return m_plotReference; }
+
+ void SetNegative( bool aFlag ) { m_negative = aFlag; }
+ bool GetNegative() const { return m_negative; }
+
+ void SetPlotViaOnMaskLayer( bool aFlag ) { m_plotViaOnMaskLayer = aFlag; }
+ bool GetPlotViaOnMaskLayer() const { return m_plotViaOnMaskLayer; }
+
+ void SetPlotFrameRef( bool aFlag ) { m_plotFrameRef = aFlag; }
+ bool GetPlotFrameRef() const { return m_plotFrameRef; }
+
+ void SetExcludeEdgeLayer( bool aFlag ) { m_excludeEdgeLayer = aFlag; }
+ bool GetExcludeEdgeLayer() const { return m_excludeEdgeLayer; }
+
+ void SetFormat( PlotFormat aFormat ) { m_format = aFormat; }
+ PlotFormat GetFormat() const { return m_format; }
+
+ void SetOutputDirectory( wxString aDir ) { m_outputDirectory = aDir; }
+ wxString GetOutputDirectory() const { return m_outputDirectory; }
+
+ void SetUseGerberAttributes( bool aUse ) { m_useGerberAttributes = aUse; }
+ bool GetUseGerberAttributes() const { return m_useGerberAttributes; }
+
+ void SetUseGerberProtelExtensions( bool aUse ) { m_useGerberProtelExtensions = aUse; }
+ bool GetUseGerberProtelExtensions() const { return m_useGerberProtelExtensions; }
+
+ void SetGerberPrecision( int aPrecision );
+ int GetGerberPrecision() const { return m_gerberPrecision; }
+
+ /** Default precision of coordinates in Gerber files.
+ * when units are in mm (7 in inches, but Pcbnew uses mm).
+ * 6 is the internal resolution of Pcbnew, so the default is 6
+ */
+ static int GetGerberDefaultPrecision() { return 6; }
+
+ void SetSubtractMaskFromSilk( bool aSubtract ) { m_subtractMaskFromSilk = aSubtract; };
+ bool GetSubtractMaskFromSilk() const { return m_subtractMaskFromSilk; }
+
+ void SetLayerSelection( LSET aSelection ) { m_layerSelection = aSelection; };
+ LSET GetLayerSelection() const { return m_layerSelection; };
+
+ void SetUseAuxOrigin( bool aAux ) { m_useAuxOrigin = aAux; };
+ bool GetUseAuxOrigin() const { return m_useAuxOrigin; };
+
+ void SetScaleSelection( int aSelection ) { m_scaleSelection = aSelection; };
+ int GetScaleSelection() const { return m_scaleSelection; };
+
+ void SetA4Output( int aForce ) { m_A4Output = aForce; };
+ bool GetA4Output() const { return m_A4Output; };
+
+ int GetHPGLPenDiameter() const { return m_HPGLPenDiam; };
+ bool SetHPGLPenDiameter( int aValue );
+ int GetHPGLPenSpeed() const { return m_HPGLPenSpeed; };
+ bool SetHPGLPenSpeed( int aValue );
+ int GetHPGLPenOverlay() const { return m_HPGLPenOvr; };
+ bool SetHPGLPenOverlay( int aValue );
+ void SetHPGLPenNum( int aVal ) { m_HPGLPenNum = aVal; }
+ int GetHPGLPenNum() const { return m_HPGLPenNum; }
+
+ int GetLineWidth() const { return m_lineWidth; };
+ bool SetLineWidth( int aValue );
+};
+
+
+/**
+ * Default line thickness in PCnew units used to draw or plot items having a
+ * default thickness line value (Frame references) (i.e. = 0 ).
+ * 0 = single pixel line width.
+ */
+extern int g_DrawDefaultLineThickness;
+
+#endif // PCB_PLOT_PARAMS_H_
diff --git a/pcbnew/pcb_plot_params_parser.h b/pcbnew/pcb_plot_params_parser.h
new file mode 100644
index 0000000..cc3137e
--- /dev/null
+++ b/pcbnew/pcb_plot_params_parser.h
@@ -0,0 +1,73 @@
+#ifndef PCB_PLOT_PARAMS_PARSER_H_
+#define PCB_PLOT_PARAMS_PARSER_H_
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2011 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <pcb_plot_params_lexer.h>
+
+class PCB_PLOT_PARAMS;
+class LINE_READER;
+
+
+/**
+ * Class PCB_PLOT_PARAMS_PARSER
+ * is the parser class for PCB_PLOT_PARAMS.
+ */
+class PCB_PLOT_PARAMS_PARSER : public PCB_PLOT_PARAMS_LEXER
+{
+public:
+ PCB_PLOT_PARAMS_PARSER( LINE_READER* aReader );
+ PCB_PLOT_PARAMS_PARSER( char* aLine, const wxString& aSource );
+
+ LINE_READER* GetReader() { return reader; };
+
+ void Parse( PCB_PLOT_PARAMS* aPcbPlotParams ) throw( PARSE_ERROR, IO_ERROR );
+
+private:
+ bool parseBool();
+
+ /**
+ * Function parseInt
+ * parses an integer and constrains it between two values.
+ * @param aMin is the smallest return value.
+ * @param aMax is the largest return value.
+ * @return int - the parsed integer.
+ */
+ int parseInt( int aMin, int aMax );
+
+ /**
+ * Function parseDouble
+ * parses a double
+ * @return double - the parsed double.
+ */
+ double parseDouble();
+
+ /**
+ * Function skipCurrent
+ * Skip the current token level, i.e
+ * search for the RIGHT parenthesis which closes the current description
+ */
+ void skipCurrent() throw( IO_ERROR, PARSE_ERROR );
+};
+
+#endif // PCB_PLOT_PARAMS_PARSER_H_
diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp
new file mode 100644
index 0000000..90c3272
--- /dev/null
+++ b/pcbnew/pcbframe.cpp
@@ -0,0 +1,1087 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2013-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbframe.cpp
+ * @brief PCB editor main window implementation.
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <collectors.h>
+#include <build_version.h>
+#include <macros.h>
+#include <3d_viewer.h>
+#include <msgpanel.h>
+#include <fp_lib_table.h>
+
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <drc_stuff.h>
+#include <layer_widget.h>
+#include <dialog_design_rules.h>
+#include <class_pcb_layer_widget.h>
+#include <hotkeys.h>
+#include <pcbnew_config.h>
+#include <module_editor_frame.h>
+#include <dialog_helpers.h>
+#include <dialog_plot.h>
+#include <convert_from_iu.h>
+#include <view/view.h>
+#include <view/view_controls.h>
+#include <pcb_painter.h>
+#include <invoke_pcb_dialog.h>
+
+#include <class_track.h>
+#include <class_board.h>
+#include <class_module.h>
+#include <worksheet_viewitem.h>
+#include <ratsnest_data.h>
+#include <ratsnest_viewitem.h>
+
+#include <tool/tool_manager.h>
+#include <tool/tool_dispatcher.h>
+#include <tools/common_actions.h>
+
+#include <scripting/python_console_frame.h>
+
+#if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON)
+#include <python_scripting.h>
+#endif
+
+#include <pcb_draw_panel_gal.h>
+#include <gal/graphics_abstraction_layer.h>
+#include <boost/bind.hpp>
+
+// Keys used in read/write config
+#define OPTKEY_DEFAULT_LINEWIDTH_VALUE wxT( "PlotLineWidth_mm" )
+#define PCB_MAGNETIC_PADS_OPT wxT( "PcbMagPadOpt" )
+#define PCB_MAGNETIC_TRACKS_OPT wxT( "PcbMagTrackOpt" )
+#define SHOW_MICROWAVE_TOOLS wxT( "ShowMicrowaveTools" )
+#define SHOW_LAYER_MANAGER_TOOLS wxT( "ShowLayerManagerTools" )
+#define SHOW_PAGE_LIMITS_KEY wxT( "ShowPageLimits" )
+
+
+BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
+ EVT_SOCKET( ID_EDA_SOCKET_EVENT_SERV, PCB_EDIT_FRAME::OnSockRequestServer )
+ EVT_SOCKET( ID_EDA_SOCKET_EVENT, PCB_EDIT_FRAME::OnSockRequest )
+
+ EVT_CHOICE( ID_ON_ZOOM_SELECT, PCB_EDIT_FRAME::OnSelectZoom )
+ EVT_CHOICE( ID_ON_GRID_SELECT, PCB_EDIT_FRAME::OnSelectGrid )
+
+ EVT_CLOSE( PCB_EDIT_FRAME::OnCloseWindow )
+ EVT_SIZE( PCB_EDIT_FRAME::OnSize )
+
+ EVT_TOOL( ID_LOAD_FILE, PCB_EDIT_FRAME::Files_io )
+ EVT_TOOL( ID_MENU_READ_BOARD_BACKUP_FILE, PCB_EDIT_FRAME::Files_io )
+ EVT_TOOL( ID_MENU_RECOVER_BOARD_AUTOSAVE, PCB_EDIT_FRAME::Files_io )
+ EVT_TOOL( ID_NEW_BOARD, PCB_EDIT_FRAME::Files_io )
+ EVT_TOOL( ID_SAVE_BOARD, PCB_EDIT_FRAME::Files_io )
+ EVT_TOOL( ID_OPEN_MODULE_EDITOR, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_OPEN_MODULE_VIEWER, PCB_EDIT_FRAME::Process_Special_Functions )
+
+ // Menu Files:
+ EVT_MENU( ID_MAIN_MENUBAR, PCB_EDIT_FRAME::Process_Special_Functions )
+
+ EVT_MENU( ID_APPEND_FILE, PCB_EDIT_FRAME::Files_io )
+ EVT_MENU( ID_SAVE_BOARD_AS, PCB_EDIT_FRAME::Files_io )
+ EVT_MENU( ID_COPY_BOARD_AS, PCB_EDIT_FRAME::Files_io )
+ EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, PCB_EDIT_FRAME::OnFileHistory )
+
+ EVT_MENU( ID_GEN_PLOT, PCB_EDIT_FRAME::ToPlotter )
+
+ EVT_MENU( ID_GEN_EXPORT_SPECCTRA, PCB_EDIT_FRAME::ExportToSpecctra )
+ EVT_MENU( ID_GEN_EXPORT_FILE_GENCADFORMAT, PCB_EDIT_FRAME::ExportToGenCAD )
+ EVT_MENU( ID_GEN_EXPORT_FILE_MODULE_REPORT, PCB_EDIT_FRAME::GenFootprintsReport )
+ EVT_MENU( ID_GEN_EXPORT_FILE_VRML, PCB_EDIT_FRAME::OnExportVRML )
+ EVT_MENU( ID_GEN_EXPORT_FILE_IDF3, PCB_EDIT_FRAME::ExportToIDF3 )
+
+ EVT_MENU( ID_GEN_IMPORT_SPECCTRA_SESSION,PCB_EDIT_FRAME::ImportSpecctraSession )
+ EVT_MENU( ID_GEN_IMPORT_SPECCTRA_DESIGN, PCB_EDIT_FRAME::ImportSpecctraDesign )
+ EVT_MENU( ID_GEN_IMPORT_DXF_FILE, PCB_EDIT_FRAME::Process_Special_Functions )
+
+ EVT_MENU( ID_MENU_ARCHIVE_MODULES_IN_LIBRARY, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_MENU_CREATE_LIBRARY_AND_ARCHIVE_MODULES, PCB_EDIT_FRAME::Process_Special_Functions )
+
+ EVT_MENU( wxID_EXIT, PCB_EDIT_FRAME::OnQuit )
+
+ // menu Config
+ EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, PCB_EDIT_FRAME::OnConfigurePcbOptions )
+ EVT_MENU( ID_PCB_LIB_TABLE_EDIT, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_PCB_LIB_WIZARD, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_PCB_3DSHAPELIB_WIZARD, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_PREFERENCES_CONFIGURE_PATHS, PCB_EDIT_FRAME::OnConfigurePaths )
+ EVT_MENU( ID_CONFIG_SAVE, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_CONFIG_READ, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU_RANGE( ID_PREFERENCES_HOTKEY_START, ID_PREFERENCES_HOTKEY_END,
+ PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( wxID_PREFERENCES, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_PCB_LAYERS_SETUP, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_PCB_MASK_CLEARANCE, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_PCB_PAD_SETUP, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_CONFIG_SAVE, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_CONFIG_READ, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_PREFRENCES_MACROS_SAVE, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_PREFRENCES_MACROS_READ, PCB_EDIT_FRAME::Process_Config )
+ EVT_MENU( ID_PCB_DISPLAY_OPTIONS_SETUP, PCB_EDIT_FRAME::InstallDisplayOptionsDialog )
+ EVT_MENU( ID_PCB_USER_GRID_SETUP, PCB_EDIT_FRAME::Process_Special_Functions )
+
+ // menu Postprocess
+ EVT_MENU( ID_PCB_GEN_POS_MODULES_FILE, PCB_EDIT_FRAME::GenFootprintsPositionFile )
+ EVT_MENU( ID_PCB_GEN_DRILL_FILE, PCB_EDIT_FRAME::InstallDrillFrame )
+ EVT_MENU( ID_PCB_GEN_D356_FILE, PCB_EDIT_FRAME::GenD356File )
+ EVT_MENU( ID_PCB_GEN_CMP_FILE, PCB_EDIT_FRAME::RecreateCmpFileFromBoard )
+ EVT_MENU( ID_PCB_GEN_BOM_FILE_FROM_BOARD, PCB_EDIT_FRAME::RecreateBOMFileFromBoard )
+
+ // menu Miscellaneous
+ EVT_MENU( ID_MENU_LIST_NETS, PCB_EDIT_FRAME::ListNetsAndSelect )
+ EVT_MENU( ID_PCB_GLOBAL_DELETE, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_MENU_PCB_CLEAN, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_MENU_PCB_SWAP_LAYERS, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_MENU_PCB_RESET_TEXTMODULE_FIELDS_SIZES,
+ PCB_EDIT_FRAME::OnResetModuleTextSizes )
+
+ // Menu Help
+ EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_INDEX, EDA_DRAW_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::GetKicadAbout )
+
+ // Menu 3D Frame
+ EVT_MENU( ID_MENU_PCB_SHOW_3D_FRAME, PCB_EDIT_FRAME::Show3D_Frame )
+
+ // Switching canvases
+ EVT_MENU( ID_MENU_CANVAS_DEFAULT, PCB_BASE_FRAME::SwitchCanvas )
+ EVT_MENU( ID_MENU_CANVAS_CAIRO, PCB_BASE_FRAME::SwitchCanvas )
+ EVT_MENU( ID_MENU_CANVAS_OPENGL, PCB_BASE_FRAME::SwitchCanvas )
+
+ // Menu Get Design Rules Editor
+ EVT_MENU( ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG, PCB_EDIT_FRAME::ShowDesignRulesEditor )
+
+ // Horizontal toolbar
+ EVT_TOOL( ID_RUN_LIBRARY, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_SHEET_SET, EDA_DRAW_FRAME::Process_PageSettings )
+ EVT_TOOL( wxID_CUT, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( wxID_COPY, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( wxID_PASTE, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( wxID_UNDO, PCB_EDIT_FRAME::RestoreCopyFromUndoList )
+ EVT_TOOL( wxID_REDO, PCB_EDIT_FRAME::RestoreCopyFromRedoList )
+ EVT_TOOL( wxID_PRINT, PCB_EDIT_FRAME::ToPrinter )
+ EVT_TOOL( ID_GEN_PLOT_SVG, PCB_EDIT_FRAME::SVG_Print )
+ EVT_TOOL( ID_GEN_PLOT, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_FIND_ITEMS, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_GET_NETLIST, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_DRC_CONTROL, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_TOOL( ID_AUX_TOOLBAR_PCB_SELECT_AUTO_WIDTH, PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event )
+ EVT_COMBOBOX( ID_TOOLBARH_PCB_SELECT_LAYER, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_CHOICE( ID_AUX_TOOLBAR_PCB_TRACK_WIDTH, PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event )
+ EVT_CHOICE( ID_AUX_TOOLBAR_PCB_VIA_SIZE, PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event )
+ EVT_TOOL( ID_TOOLBARH_PCB_MODE_MODULE, PCB_EDIT_FRAME::OnSelectAutoPlaceMode )
+ EVT_TOOL( ID_TOOLBARH_PCB_MODE_TRACKS, PCB_EDIT_FRAME::OnSelectAutoPlaceMode )
+ EVT_TOOL( ID_TOOLBARH_PCB_FREEROUTE_ACCESS, PCB_EDIT_FRAME::Access_to_External_Tool )
+
+ // has meaning only with KICAD_SCRIPTING_WXPYTHON enabled
+ EVT_TOOL( ID_TOOLBARH_PCB_SCRIPTING_CONSOLE, PCB_EDIT_FRAME::ScriptingConsoleEnableDisable )
+ EVT_UPDATE_UI( ID_TOOLBARH_PCB_SCRIPTING_CONSOLE,
+ PCB_EDIT_FRAME::OnUpdateScriptingConsoleState )
+
+ // Option toolbar
+ EVT_TOOL( ID_TB_OPTIONS_DRC_OFF,
+ PCB_EDIT_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_RATSNEST,
+ PCB_EDIT_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_MODULE_RATSNEST,
+ PCB_EDIT_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_AUTO_DEL_TRACK,
+ PCB_EDIT_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_VIAS_SKETCH,
+ PCB_EDIT_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_TRACKS_SKETCH,
+ PCB_EDIT_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE,
+ PCB_EDIT_FRAME::OnSelectOptionToolbar )
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE,
+ PCB_EDIT_FRAME::OnSelectOptionToolbar )
+
+ EVT_TOOL_RANGE( ID_TB_OPTIONS_SHOW_ZONES, ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY,
+ PCB_EDIT_FRAME::OnSelectOptionToolbar )
+
+ EVT_TOOL( ID_TB_OPTIONS_SHOW_MANAGE_LAYERS_VERTICAL_TOOLBAR,
+ PCB_EDIT_FRAME::OnSelectOptionToolbar )
+
+ // Vertical main toolbar:
+ EVT_TOOL( ID_NO_TOOL_SELECTED, PCB_EDIT_FRAME::OnSelectTool )
+ EVT_TOOL_RANGE( ID_PCB_HIGHLIGHT_BUTT, ID_PCB_PLACE_GRID_COORD_BUTT,
+ PCB_EDIT_FRAME::OnSelectTool )
+
+ EVT_TOOL_RANGE( ID_PCB_MUWAVE_START_CMD, ID_PCB_MUWAVE_END_CMD,
+ PCB_EDIT_FRAME::ProcessMuWaveFunctions )
+
+ EVT_MENU_RANGE( ID_POPUP_PCB_AUTOPLACE_START_RANGE, ID_POPUP_PCB_AUTOPLACE_END_RANGE,
+ PCB_EDIT_FRAME::OnPlaceOrRouteFootprints )
+
+ EVT_MENU( ID_POPUP_PCB_REORIENT_ALL_MODULES, PCB_EDIT_FRAME::OnOrientFootprints )
+
+ EVT_MENU_RANGE( ID_POPUP_PCB_START_RANGE, ID_POPUP_PCB_END_RANGE,
+ PCB_EDIT_FRAME::Process_Special_Functions )
+
+ // Tracks and vias sizes general options
+ EVT_MENU_RANGE( ID_POPUP_PCB_SELECT_WIDTH_START_RANGE,
+ ID_POPUP_PCB_SELECT_WIDTH_END_RANGE,
+ PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event )
+
+ // popup menus
+ EVT_MENU( ID_POPUP_PCB_DELETE_TRACKSEG, PCB_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE,
+ PCB_EDIT_FRAME::Process_Special_Functions )
+
+ // User interface update event handlers.
+ EVT_UPDATE_UI( ID_SAVE_BOARD, PCB_EDIT_FRAME::OnUpdateSave )
+ EVT_UPDATE_UI( ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR, PCB_EDIT_FRAME::OnUpdateLayerPair )
+ EVT_UPDATE_UI( ID_TOOLBARH_PCB_SELECT_LAYER, PCB_EDIT_FRAME::OnUpdateLayerSelectBox )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_DRC_OFF, PCB_EDIT_FRAME::OnUpdateDrcEnable )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_RATSNEST, PCB_EDIT_FRAME::OnUpdateShowBoardRatsnest )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_MODULE_RATSNEST, PCB_EDIT_FRAME::OnUpdateShowModuleRatsnest )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_AUTO_DEL_TRACK, PCB_EDIT_FRAME::OnUpdateAutoDeleteTrack )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_VIAS_SKETCH, PCB_EDIT_FRAME::OnUpdateViaDrawMode )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_TRACKS_SKETCH, PCB_EDIT_FRAME::OnUpdateTraceDrawMode )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE,
+ PCB_EDIT_FRAME::OnUpdateHighContrastDisplayMode )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_MANAGE_LAYERS_VERTICAL_TOOLBAR,
+ PCB_EDIT_FRAME::OnUpdateShowLayerManager )
+ EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE,
+ PCB_EDIT_FRAME::OnUpdateShowMicrowaveToolbar )
+ EVT_UPDATE_UI( ID_NO_TOOL_SELECTED, PCB_EDIT_FRAME::OnUpdateVerticalToolbar )
+ EVT_UPDATE_UI( ID_AUX_TOOLBAR_PCB_TRACK_WIDTH, PCB_EDIT_FRAME::OnUpdateSelectTrackWidth )
+ EVT_UPDATE_UI( ID_AUX_TOOLBAR_PCB_SELECT_AUTO_WIDTH,
+ PCB_EDIT_FRAME::OnUpdateSelectAutoTrackWidth )
+ EVT_UPDATE_UI( ID_POPUP_PCB_SELECT_AUTO_WIDTH, PCB_EDIT_FRAME::OnUpdateSelectAutoTrackWidth )
+ EVT_UPDATE_UI( ID_POPUP_PCB_SELECT_CUSTOM_WIDTH,
+ PCB_EDIT_FRAME::OnUpdateSelectCustomTrackWidth )
+ EVT_UPDATE_UI( ID_AUX_TOOLBAR_PCB_VIA_SIZE, PCB_EDIT_FRAME::OnUpdateSelectViaSize )
+ EVT_UPDATE_UI( ID_TOOLBARH_PCB_MODE_MODULE, PCB_EDIT_FRAME::OnUpdateAutoPlaceModulesMode )
+ EVT_UPDATE_UI( ID_TOOLBARH_PCB_MODE_TRACKS, PCB_EDIT_FRAME::OnUpdateAutoPlaceTracksMode )
+ EVT_UPDATE_UI_RANGE( ID_POPUP_PCB_SELECT_WIDTH1, ID_POPUP_PCB_SELECT_WIDTH8,
+ PCB_EDIT_FRAME::OnUpdateSelectTrackWidth )
+ EVT_UPDATE_UI_RANGE( ID_POPUP_PCB_SELECT_VIASIZE1, ID_POPUP_PCB_SELECT_VIASIZE8,
+ PCB_EDIT_FRAME::OnUpdateSelectViaSize )
+ EVT_UPDATE_UI_RANGE( ID_PCB_HIGHLIGHT_BUTT, ID_PCB_PLACE_GRID_COORD_BUTT,
+ PCB_EDIT_FRAME::OnUpdateVerticalToolbar )
+ EVT_UPDATE_UI_RANGE( ID_TB_OPTIONS_SHOW_ZONES, ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY,
+ PCB_EDIT_FRAME::OnUpdateZoneDisplayStyle )
+ EVT_UPDATE_UI_RANGE( ID_PCB_MUWAVE_START_CMD, ID_PCB_MUWAVE_END_CMD,
+ PCB_EDIT_FRAME::OnUpdateMuWaveToolbar )
+
+ EVT_COMMAND( wxID_ANY, LAYER_WIDGET::EVT_LAYER_COLOR_CHANGE, PCB_EDIT_FRAME::OnLayerColorChange )
+END_EVENT_TABLE()
+
+
+PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
+ PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB, wxT( "Pcbnew" ), wxDefaultPosition,
+ wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PCB_EDIT_FRAME_NAME )
+{
+ m_showBorderAndTitleBlock = true; // true to display sheet references
+ m_showAxis = false; // true to display X and Y axis
+ m_showOriginAxis = true;
+ m_showGridAxis = true;
+ m_SelTrackWidthBox = NULL;
+ m_SelViaSizeBox = NULL;
+ m_SelLayerBox = NULL;
+ m_show_microwave_tools = false;
+ m_show_layer_manager_tools = true;
+ m_hotkeysDescrList = g_Board_Editor_Hokeys_Descr;
+ m_hasAutoSave = true;
+ m_RecordingMacros = -1;
+ m_microWaveToolBar = NULL;
+
+ m_rotationAngle = 900;
+
+ for ( int i = 0; i < 10; i++ )
+ m_Macros[i].m_Record.clear();
+
+ // Create GAL canvas
+ EDA_DRAW_PANEL_GAL* galCanvas = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ),
+ m_FrameSize, EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE );
+
+ SetGalCanvas( galCanvas );
+
+ SetBoard( new BOARD() );
+
+ // Create the PCB_LAYER_WIDGET *after* SetBoard():
+
+ wxFont font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
+ int pointSize = font.GetPointSize();
+ int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
+
+ // printf( "pointSize:%d 80%%:%d\n", pointSize, (pointSize*8)/10 );
+
+ if( screenHeight <= 900 )
+ pointSize = (pointSize * 8) / 10;
+
+ m_Layers = new PCB_LAYER_WIDGET( this, GetCanvas(), pointSize );
+
+ m_drc = new DRC( this ); // these 2 objects point to each other
+
+ wxIcon icon;
+ icon.CopyFromBitmap( KiBitmap( icon_pcbnew_xpm ) );
+ SetIcon( icon );
+
+ // LoadSettings() *after* creating m_LayersManager, because LoadSettings()
+ // initialize parameters in m_LayersManager
+ LoadSettings( config() );
+
+ SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) );
+ GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
+
+ // PCB drawings start in the upper left corner.
+ GetScreen()->m_Center = false;
+
+ SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
+
+ GetScreen()->AddGrid( m_UserGridSize, m_UserGridUnit, ID_POPUP_GRID_USER );
+ GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
+
+ if( m_canvas )
+ m_canvas->SetEnableBlockCommands( true );
+
+ ReCreateMenuBar();
+ ReCreateHToolbar();
+ ReCreateAuxiliaryToolbar();
+ ReCreateVToolbar();
+ ReCreateOptToolbar();
+
+ ReCreateMicrowaveVToolbar();
+
+ m_auimgr.SetManagedWindow( this );
+
+ EDA_PANEINFO horiz;
+ horiz.HorizontalToolbarPane();
+
+ EDA_PANEINFO vert;
+ vert.VerticalToolbarPane();
+
+ EDA_PANEINFO mesg;
+ mesg.MessageToolbarPane();
+
+ // Create a wxAuiPaneInfo for the Layers Manager, not derived from the template.
+ // LAYER_WIDGET is floatable, but initially docked at far right
+ EDA_PANEINFO lyrs;
+ lyrs.LayersToolbarPane();
+ lyrs.MinSize( m_Layers->GetBestSize() ); // updated in ReFillLayerWidget
+ lyrs.BestSize( m_Layers->GetBestSize() );
+ lyrs.Caption( _( "Visibles" ) );
+ lyrs.TopDockable( false ).BottomDockable( false );
+
+ if( m_mainToolBar ) // The main horizontal toolbar
+ {
+ m_auimgr.AddPane( m_mainToolBar,
+ wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top().Row( 0 ) );
+ }
+
+ if( m_auxiliaryToolBar ) // the auxiliary horizontal toolbar, that shows track and via sizes, zoom ...)
+ {
+ m_auimgr.AddPane( m_auxiliaryToolBar,
+ wxAuiPaneInfo( horiz ).Name( wxT( "m_auxiliaryToolBar" ) ).Top().Row( 1 ) );
+ }
+
+ if( m_microWaveToolBar ) // The auxiliary vertical right toolbar (currently microwave tools)
+ m_auimgr.AddPane( m_microWaveToolBar,
+ wxAuiPaneInfo( vert ).Name( wxT( "m_microWaveToolBar" ) ).
+ Right().Layer( 1 ).Position(1).Hide() );
+
+ if( m_drawToolBar ) // The main right vertical toolbar
+ m_auimgr.AddPane( m_drawToolBar,
+ wxAuiPaneInfo( vert ).Name( wxT( "m_VToolBar" ) ).Right().Layer( 2 ) );
+
+ // Add the layer manager ( most right side of pcbframe )
+ m_auimgr.AddPane( m_Layers, lyrs.Name( wxT( "m_LayersManagerToolBar" ) ).Right().Layer( 3 ) );
+
+ if( m_optionsToolBar ) // The left vertical toolbar (fast acces display options of Pcbnew)
+ {
+ m_auimgr.AddPane( m_optionsToolBar,
+ wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ).Left().Layer(1) );
+
+ m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( m_show_layer_manager_tools );
+ m_auimgr.GetPane( wxT( "m_microWaveToolBar" ) ).Show( m_show_microwave_tools );
+ }
+
+ if( m_canvas )
+ m_auimgr.AddPane( m_canvas,
+ wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
+
+ if( GetGalCanvas() )
+ m_auimgr.AddPane( (wxWindow*) GetGalCanvas(),
+ wxAuiPaneInfo().Name( wxT( "DrawFrameGal" ) ).CentrePane().Hide() );
+
+ if( m_messagePanel )
+ m_auimgr.AddPane( m_messagePanel,
+ wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );
+
+ ReFillLayerWidget(); // this is near end because contents establish size
+ m_Layers->ReFillRender(); // Update colors in Render after the config is read
+ syncLayerWidgetLayer();
+
+ m_auimgr.Update();
+
+ setupTools();
+
+ Zoom_Automatique( false );
+
+ EDA_DRAW_PANEL_GAL::GAL_TYPE canvasType = LoadCanvasTypeSetting();
+
+ if( canvasType != EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE )
+ {
+ if( GetGalCanvas()->SwitchBackend( canvasType ) )
+ UseGalCanvas( true );
+ }
+
+ enableGALSpecificMenus();
+}
+
+
+PCB_EDIT_FRAME::~PCB_EDIT_FRAME()
+{
+ m_RecordingMacros = -1;
+
+ for( int i = 0; i < 10; i++ )
+ m_Macros[i].m_Record.clear();
+
+ delete m_drc;
+}
+
+
+void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard )
+{
+ PCB_BASE_EDIT_FRAME::SetBoard( aBoard );
+
+ if( IsGalCanvasActive() )
+ {
+ aBoard->GetRatsnest()->Recalculate();
+
+ // reload the worksheet
+ SetPageSettings( aBoard->GetPageSettings() );
+ }
+}
+
+
+void PCB_EDIT_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
+{
+ PCB_BASE_FRAME::SetPageSettings( aPageSettings );
+
+ if( IsGalCanvasActive() )
+ {
+ PCB_DRAW_PANEL_GAL* drawPanel = static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() );
+
+ // Prepare worksheet template
+ KIGFX::WORKSHEET_VIEWITEM* worksheet;
+ worksheet = new KIGFX::WORKSHEET_VIEWITEM( &m_Pcb->GetPageSettings(),
+ &m_Pcb->GetTitleBlock() );
+ worksheet->SetSheetName( std::string( GetScreenDesc().mb_str() ) );
+
+ BASE_SCREEN* screen = GetScreen();
+
+ if( screen != NULL )
+ {
+ worksheet->SetSheetNumber( screen->m_ScreenNumber );
+ worksheet->SetSheetCount( screen->m_NumberOfScreens );
+ }
+
+ // PCB_DRAW_PANEL_GAL takes ownership of the worksheet
+ drawPanel->SetWorksheet( worksheet );
+ }
+}
+
+
+bool PCB_EDIT_FRAME::isAutoSaveRequired() const
+{
+ if( GetScreen() )
+ return GetScreen()->IsSave();
+
+ return false;
+}
+
+
+void PCB_EDIT_FRAME::setupTools()
+{
+ // Create the manager and dispatcher & route draw panel events to the dispatcher
+ m_toolManager = new TOOL_MANAGER;
+ m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(),
+ GetGalCanvas()->GetViewControls(), this );
+ m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
+
+ // Register tools
+ registerAllTools( m_toolManager );
+
+ m_toolManager->ResetTools( TOOL_BASE::RUN );
+
+ // Run the selection tool, it is supposed to be always active
+ m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" );
+}
+
+
+void PCB_EDIT_FRAME::ReFillLayerWidget()
+{
+ m_Layers->ReFill();
+
+ wxAuiPaneInfo& lyrs = m_auimgr.GetPane( m_Layers );
+
+ wxSize bestz = m_Layers->GetBestSize();
+
+ lyrs.MinSize( bestz );
+ lyrs.BestSize( bestz );
+ lyrs.FloatingSize( bestz );
+
+ if( lyrs.IsDocked() )
+ m_auimgr.Update();
+ else
+ m_Layers->SetSize( bestz );
+}
+
+
+void PCB_EDIT_FRAME::OnQuit( wxCommandEvent& event )
+{
+ Close( false );
+}
+
+
+void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
+{
+ m_canvas->SetAbortRequest( true );
+
+ if( GetScreen()->IsModify() )
+ {
+ wxString msg = wxString::Format( _(
+ "Save the changes in\n"
+ "'%s'\n"
+ "before closing?" ),
+ GetChars( GetBoard()->GetFileName() )
+ );
+
+ int ii = DisplayExitDialog( this, msg );
+ switch( ii )
+ {
+ case wxID_CANCEL:
+ Event.Veto();
+ return;
+
+ case wxID_NO:
+ break;
+
+ case wxID_YES:
+ // save the board. if the board has no name,
+ // the ID_SAVE_BOARD_AS will actually made
+ Files_io_from_id( ID_SAVE_BOARD );
+ break;
+ }
+ }
+
+ GetGalCanvas()->StopDrawing();
+
+ // Delete the auto save file if it exists.
+ wxFileName fn = GetBoard()->GetFileName();
+
+ // Auto save file name is the normal file name prefixed with '_autosave'.
+ fn.SetName( GetAutoSaveFilePrefix() + fn.GetName() );
+
+ // When the auto save feature does not have write access to the board file path, it falls
+ // back to a platform specific user temporary file path.
+ if( !fn.IsOk() || !fn.IsDirWritable() )
+ fn.SetPath( wxFileName::GetTempDir() );
+
+ wxLogTrace( traceAutoSave, "Deleting auto save file <" + fn.GetFullPath() + ">" );
+
+ // Remove the auto save file on a normal close of Pcbnew.
+ if( fn.FileExists() && !wxRemoveFile( fn.GetFullPath() ) )
+ {
+ wxString msg = wxString::Format( _(
+ "The auto save file '%s' could not be removed!" ),
+ GetChars( fn.GetFullPath() )
+ );
+
+ wxMessageBox( msg, Pgm().App().GetAppName(), wxOK | wxICON_ERROR, this );
+ }
+
+ // Delete board structs and undo/redo lists, to avoid crash on exit
+ // when deleting some structs (mainly in undo/redo lists) too late
+ Clear_Pcb( false );
+
+ // do not show the window because ScreenPcb will be deleted and we do not
+ // want any paint event
+ Show( false );
+
+ Destroy();
+}
+
+
+void PCB_EDIT_FRAME::Show3D_Frame( wxCommandEvent& event )
+{
+ if( m_Draw3DFrame )
+ {
+ // Raising the window does not show the window on Windows if iconized.
+ // This should work on any platform.
+ if( m_Draw3DFrame->IsIconized() )
+ m_Draw3DFrame->Iconize( false );
+
+ m_Draw3DFrame->Raise();
+
+ // Raising the window does not set the focus on Linux. This should work on any platform.
+ if( wxWindow::FindFocus() != m_Draw3DFrame )
+ m_Draw3DFrame->SetFocus();
+
+ return;
+ }
+
+ m_Draw3DFrame = new EDA_3D_FRAME( &Kiway(), this, _( "3D Viewer" ) );
+ m_Draw3DFrame->SetDefaultFileName( GetBoard()->GetFileName() );
+ m_Draw3DFrame->Raise(); // Needed with some Window Managers
+ m_Draw3DFrame->Show( true );
+}
+
+
+void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable )
+{
+ if( aEnable )
+ {
+ BOARD* board = GetBoard();
+
+ if( board )
+ board->GetRatsnest()->ProcessBoard();
+ }
+ else
+ {
+ Compile_Ratsnest( NULL, true );
+ }
+
+ PCB_BASE_EDIT_FRAME::UseGalCanvas( aEnable );
+
+ enableGALSpecificMenus();
+}
+
+
+void PCB_EDIT_FRAME::enableGALSpecificMenus()
+{
+ // some menus are active only in GAL mode and do nothing in legacy mode.
+ // So enable or disable them, depending on the display mode
+
+ if( GetMenuBar() )
+ {
+ // Enable / disable some menus which are usable only on GAL
+ pcbnew_ids id_list[] =
+ {
+ ID_MENU_INTERACTIVE_ROUTER_SETTINGS,
+ ID_DIFF_PAIR_BUTT,
+ ID_TUNE_SINGLE_TRACK_LEN_BUTT,
+ ID_TUNE_DIFF_PAIR_LEN_BUTT,
+ ID_TUNE_DIFF_PAIR_SKEW_BUTT,
+ ID_MENU_DIFF_PAIR_DIMENSIONS
+ };
+
+ bool enbl = IsGalCanvasActive();
+
+ for( unsigned ii = 0; ii < DIM( id_list ); ii++ )
+ {
+ if( GetMenuBar()->FindItem( id_list[ii] ) )
+ GetMenuBar()->FindItem( id_list[ii] )->Enable( enbl );
+ }
+ }
+}
+
+
+void PCB_EDIT_FRAME::ShowDesignRulesEditor( wxCommandEvent& event )
+{
+ DIALOG_DESIGN_RULES dR_editor( this );
+ int returncode = dR_editor.ShowModal();
+
+ if( returncode == wxID_OK ) // New rules, or others changes.
+ {
+ ReCreateLayerBox();
+ ReCreateAuxiliaryToolbar();
+ OnModify();
+ }
+}
+
+
+void PCB_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg )
+{
+ PCB_BASE_FRAME::LoadSettings( aCfg );
+
+ wxConfigLoadSetups( aCfg, GetConfigurationSettings() );
+
+ double dtmp;
+ aCfg->Read( OPTKEY_DEFAULT_LINEWIDTH_VALUE, &dtmp, 0.1 ); // stored in mm
+
+ if( dtmp < 0.01 )
+ dtmp = 0.01;
+
+ if( dtmp > 5.0 )
+ dtmp = 5.0;
+
+ g_DrawDefaultLineThickness = Millimeter2iu( dtmp );
+
+ aCfg->Read( PCB_MAGNETIC_PADS_OPT, &g_MagneticPadOption );
+ aCfg->Read( PCB_MAGNETIC_TRACKS_OPT, &g_MagneticTrackOption );
+ aCfg->Read( SHOW_MICROWAVE_TOOLS, &m_show_microwave_tools );
+ aCfg->Read( SHOW_LAYER_MANAGER_TOOLS, &m_show_layer_manager_tools );
+ aCfg->Read( SHOW_PAGE_LIMITS_KEY, &m_showPageLimits );
+}
+
+
+void PCB_EDIT_FRAME::SaveSettings( wxConfigBase* aCfg )
+{
+ PCB_BASE_FRAME::SaveSettings( aCfg );
+
+ wxConfigSaveSetups( aCfg, GetConfigurationSettings() );
+
+ // This value is stored in mm )
+ aCfg->Write( OPTKEY_DEFAULT_LINEWIDTH_VALUE, MM_PER_IU * g_DrawDefaultLineThickness );
+ aCfg->Write( PCB_MAGNETIC_PADS_OPT, (long) g_MagneticPadOption );
+ aCfg->Write( PCB_MAGNETIC_TRACKS_OPT, (long) g_MagneticTrackOption );
+ aCfg->Write( SHOW_MICROWAVE_TOOLS, (long) m_show_microwave_tools );
+ aCfg->Write( SHOW_LAYER_MANAGER_TOOLS, (long)m_show_layer_manager_tools );
+ aCfg->Write( SHOW_PAGE_LIMITS_KEY, m_showPageLimits );
+}
+
+
+bool PCB_EDIT_FRAME::IsGridVisible() const
+{
+ return IsElementVisible( GRID_VISIBLE );
+}
+
+
+void PCB_EDIT_FRAME::SetGridVisibility(bool aVisible)
+{
+ SetElementVisibility( GRID_VISIBLE, aVisible );
+}
+
+
+EDA_COLOR_T PCB_EDIT_FRAME::GetGridColor() const
+{
+ return GetBoard()->GetVisibleElementColor( GRID_VISIBLE );
+}
+
+
+void PCB_EDIT_FRAME::SetGridColor( EDA_COLOR_T aColor )
+{
+
+ GetBoard()->SetVisibleElementColor( GRID_VISIBLE, aColor );
+
+ if( IsGalCanvasActive() )
+ {
+ StructColors c = g_ColorRefs[ aColor ];
+ KIGFX::COLOR4D color( (double) c.m_Red / 255.0,
+ (double) c.m_Green / 255.0,
+ (double) c.m_Blue / 255.0,
+ 0.7 );
+
+ GetGalCanvas()->GetGAL()->SetGridColor( color );
+ }
+}
+
+
+void PCB_EDIT_FRAME::SetCursorShape( int aCursorShape )
+{
+ const unsigned int BIG_CURSOR = 8000;
+ const unsigned int SMALL_CURSOR = 80;
+
+ EDA_DRAW_FRAME::SetCursorShape( aCursorShape );
+ KIGFX::GAL* gal = GetGalCanvas()->GetGAL();
+
+ if( gal )
+ gal->SetCursorSize( aCursorShape ? BIG_CURSOR : SMALL_CURSOR );
+}
+
+
+bool PCB_EDIT_FRAME::IsMicroViaAcceptable()
+{
+ int copperlayercnt = GetBoard()->GetCopperLayerCount( );
+ LAYER_ID currLayer = GetActiveLayer();
+
+ if( !GetDesignSettings().m_MicroViasAllowed )
+ return false; // Obvious..
+
+ if( copperlayercnt < 4 )
+ return false; // Only on multilayer boards..
+
+ if( ( currLayer == B_Cu )
+ || ( currLayer == F_Cu )
+ || ( currLayer == copperlayercnt - 2 )
+ || ( currLayer == In1_Cu ) )
+ return true;
+
+ return false;
+}
+
+
+void PCB_EDIT_FRAME::SetActiveLayer( LAYER_ID aLayer )
+{
+ PCB_BASE_FRAME::SetActiveLayer( aLayer );
+
+ syncLayerWidgetLayer();
+
+ if( IsGalCanvasActive() )
+ {
+ m_toolManager->RunAction( COMMON_ACTIONS::layerChanged ); // notify other tools
+ GetGalCanvas()->SetFocus(); // otherwise hotkeys are stuck somewhere
+ GetGalCanvas()->SetHighContrastLayer( aLayer );
+ GetGalCanvas()->Refresh();
+ }
+}
+
+
+void PCB_EDIT_FRAME::syncLayerWidgetLayer()
+{
+ m_Layers->SelectLayer( GetActiveLayer() );
+ m_Layers->OnLayerSelected();
+}
+
+
+void PCB_EDIT_FRAME::syncRenderStates()
+{
+ m_Layers->SyncRenderStates();
+}
+
+
+void PCB_EDIT_FRAME::syncLayerVisibilities()
+{
+ m_Layers->SyncLayerVisibilities();
+ static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() )->SyncLayersVisibility( m_Pcb );
+}
+
+
+void PCB_EDIT_FRAME::unitsChangeRefresh()
+{
+ PCB_BASE_FRAME::unitsChangeRefresh(); // Update the grid size select box.
+
+ ReCreateAuxiliaryToolbar();
+}
+
+
+bool PCB_EDIT_FRAME::IsElementVisible( int aElement ) const
+{
+ return GetBoard()->IsElementVisible( aElement );
+}
+
+
+void PCB_EDIT_FRAME::SetElementVisibility( int aElement, bool aNewState )
+{
+ GetGalCanvas()->GetView()->SetLayerVisible( ITEM_GAL_LAYER( aElement ), aNewState );
+ GetBoard()->SetElementVisibility( aElement, aNewState );
+ m_Layers->SetRenderState( aElement, aNewState );
+}
+
+
+void PCB_EDIT_FRAME::SetVisibleAlls()
+{
+ GetBoard()->SetVisibleAlls();
+
+ for( int ii = 0; ii < PCB_VISIBLE( END_PCB_VISIBLE_LIST ); ii++ )
+ m_Layers->SetRenderState( ii, true );
+}
+
+
+void PCB_EDIT_FRAME::ShowChangedLanguage()
+{
+ // call my base class
+ PCB_BASE_FRAME::ShowChangedLanguage();
+
+ m_Layers->SetLayersManagerTabsText();
+
+ wxAuiPaneInfo& pane_info = m_auimgr.GetPane( m_Layers );
+
+ pane_info.Caption( _( "Visibles" ) );
+ m_auimgr.Update();
+ ReFillLayerWidget();
+}
+
+
+wxString PCB_EDIT_FRAME::GetLastNetListRead()
+{
+ wxFileName absoluteFileName = m_lastNetListRead;
+ wxFileName pcbFileName = GetBoard()->GetFileName();
+
+ if( !absoluteFileName.MakeAbsolute( pcbFileName.GetPath() ) || !absoluteFileName.FileExists() )
+ {
+ absoluteFileName.Clear();
+ m_lastNetListRead = wxEmptyString;
+ }
+
+ return absoluteFileName.GetFullPath();
+}
+
+
+void PCB_EDIT_FRAME::SetLastNetListRead( const wxString& aLastNetListRead )
+{
+ wxFileName relativeFileName = aLastNetListRead;
+ wxFileName pcbFileName = GetBoard()->GetFileName();
+
+ if( relativeFileName.MakeRelativeTo( pcbFileName.GetPath() )
+ && relativeFileName.GetFullPath() != aLastNetListRead )
+ {
+ m_lastNetListRead = relativeFileName.GetFullPath();
+ }
+}
+
+
+void PCB_EDIT_FRAME::OnModify( )
+{
+ PCB_BASE_FRAME::OnModify();
+
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->ReloadRequest();
+}
+
+
+void PCB_EDIT_FRAME::SVG_Print( wxCommandEvent& event )
+{
+ PCB_PLOT_PARAMS plot_prms = GetPlotSettings();
+
+ // we don't want dialogs knowing about complex wxFrame functions so
+ // pass everything the dialog needs without reference to *this frame's class.
+ if( InvokeSVGPrint( this, GetBoard(), &plot_prms ) )
+ {
+ if( !plot_prms.IsSameAs( GetPlotSettings(), false ) )
+ {
+ // First, mark board as modified only for parameters saved in file
+ if( !plot_prms.IsSameAs( GetPlotSettings(), true ) )
+ OnModify();
+
+ // Now, save any change, for the session
+ SetPlotSettings( plot_prms );
+ }
+ }
+}
+
+
+void PCB_EDIT_FRAME::UpdateTitle()
+{
+ wxFileName fileName = GetBoard()->GetFileName();
+ wxString title = wxString::Format( wxT( "Pcbnew %s " ), GetChars( GetBuildVersion() ) );
+
+ if( fileName.IsOk() && fileName.FileExists() )
+ {
+ title << fileName.GetFullPath();
+
+ if( !fileName.IsFileWritable() )
+ title << _( " [Read Only]" );
+ }
+ else
+ {
+ title << _( " [new file]" ) << wxT(" ") << fileName.GetFullPath();
+ }
+
+ SetTitle( title );
+}
+
+
+wxSize PYTHON_CONSOLE_FRAME::m_frameSize; ///< The size of the PYTHON_CONSOLE_FRAME frame, stored during a session
+wxPoint PYTHON_CONSOLE_FRAME::m_framePos; ///< The position ofPYTHON_CONSOLE_FRAME the frame, stored during a session
+
+void PCB_EDIT_FRAME::ScriptingConsoleEnableDisable( wxCommandEvent& aEvent )
+{
+
+ wxWindow * pythonPanelFrame = findPythonConsole();
+ bool pythonPanelShown = true;
+
+ if( pythonPanelFrame == NULL )
+ pythonPanelFrame = new PYTHON_CONSOLE_FRAME( this, pythonConsoleNameId() );
+ else
+ pythonPanelShown = ! pythonPanelFrame->IsShown();
+
+ if( pythonPanelFrame )
+ pythonPanelFrame->Show( pythonPanelShown );
+ else
+ wxMessageBox( wxT( "Error: unable to create the Python Console" ) );
+}
+
+
+void PCB_EDIT_FRAME::OnSelectAutoPlaceMode( wxCommandEvent& aEvent )
+{
+ // Automatic placement of modules and tracks is a mutually exclusive operation so
+ // clear the other tool if one of the two is selected.
+ // Be careful: this event function is called both by the
+ // ID_TOOLBARH_PCB_MODE_MODULE and the ID_TOOLBARH_PCB_MODE_TRACKS tool
+ // Therefore we should avoid a race condition when deselecting one of these tools
+ // inside this function (seems happen on some Linux/wxWidgets versions)
+ // when the other tool is selected
+
+ switch( aEvent.GetId() )
+ {
+ case ID_TOOLBARH_PCB_MODE_MODULE:
+ if( aEvent.IsChecked() &&
+ m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) )
+ {
+ m_mainToolBar->ToggleTool( ID_TOOLBARH_PCB_MODE_TRACKS, false );
+ }
+ break;
+
+ case ID_TOOLBARH_PCB_MODE_TRACKS:
+ if( aEvent.IsChecked() &&
+ m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_MODULE ) )
+ {
+ m_mainToolBar->ToggleTool( ID_TOOLBARH_PCB_MODE_MODULE, false );
+ }
+ break;
+ }
+}
+
+
+void PCB_EDIT_FRAME::OnLayerColorChange( wxCommandEvent& aEvent )
+{
+ ReCreateLayerBox();
+}
+
+
+void PCB_EDIT_FRAME::ToPlotter( wxCommandEvent& event )
+{
+ DIALOG_PLOT dlg( this );
+
+ dlg.ShowModal();
+}
+
+
+bool PCB_EDIT_FRAME::SetCurrentNetClass( const wxString& aNetClassName )
+{
+ bool change = GetDesignSettings().SetCurrentNetClass( aNetClassName );
+
+ if( change )
+ {
+ ReCreateAuxiliaryToolbar();
+ }
+
+ return change;
+}
+
+
+void PCB_EDIT_FRAME::OnConfigurePaths( wxCommandEvent& aEvent )
+{
+ Pgm().ConfigurePaths( this );
+}
diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp
new file mode 100644
index 0000000..c6421ed
--- /dev/null
+++ b/pcbnew/pcbnew.cpp
@@ -0,0 +1,380 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew.cpp
+ * @brief Pcbnew main program.
+ */
+
+#ifdef KICAD_SCRIPTING
+ #include <python_scripting.h>
+ #include <pcbnew_scripting_helpers.h>
+#endif
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <kiface_i.h>
+#include <confirm.h>
+#include <macros.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+#include <eda_dde.h>
+#include <pcbcommon.h>
+#include <colors_selection.h>
+#include <wx/stdpaths.h>
+
+#include <wx/file.h>
+#include <wx/snglinst.h>
+#include <wx/dir.h>
+#include <gestfich.h>
+
+#include <pcbnew.h>
+#include <hotkeys.h>
+#include <wildcards_and_files_ext.h>
+#include <class_board.h>
+#include <3d_viewer.h>
+#include <fp_lib_table.h>
+#include <module_editor_frame.h>
+#include <modview_frame.h>
+#include <footprint_wizard_frame.h>
+
+extern bool IsWxPythonLoaded();
+
+// Colors for layers and items
+COLORS_DESIGN_SETTINGS g_ColorsSettings;
+
+bool g_Drc_On = true;
+bool g_AutoDeleteOldTrack = true;
+bool g_Raccord_45_Auto = true;
+bool g_Alternate_Track_Posture = false;
+bool g_Track_45_Only_Allowed = true; // True to allow horiz, vert. and 45deg only tracks
+bool g_Segments_45_Only; // True to allow horiz, vert. and 45deg only graphic segments
+bool g_TwoSegmentTrackBuild = true;
+
+LAYER_ID g_Route_Layer_TOP;
+LAYER_ID g_Route_Layer_BOTTOM;
+int g_MagneticPadOption = capture_cursor_in_track_tool;
+int g_MagneticTrackOption = capture_cursor_in_track_tool;
+
+wxPoint g_Offset_Module; // module offset used when moving a footprint
+
+/* Name of the document footprint list
+ * usually located in share/modules/footprints_doc
+ * this is of the responsibility to users to create this file
+ * if they want to have a list of footprints
+ */
+wxString g_DocModulesFileName = wxT( "footprints_doc/footprints.pdf" );
+
+/*
+ * Used in track creation, a list of track segments currently being created,
+ * with the newest track at the end of the list, sorted by new-ness. e.g. use
+ * TRACK->Back() to get the next older track, TRACK->Next() to get the next
+ * newer track.
+ */
+DLIST<TRACK> g_CurrentTrackList;
+
+bool g_DumpZonesWhenFilling = false;
+
+namespace PCB {
+
+static struct IFACE : public KIFACE_I
+{
+ // Of course all are virtual overloads, implementations of the KIFACE.
+
+ IFACE( const char* aName, KIWAY::FACE_T aType ) :
+ KIFACE_I( aName, aType )
+ {}
+
+ bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits );
+
+ void OnKifaceEnd();
+
+ wxWindow* CreateWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 )
+ {
+ wxWindow* frame = NULL;
+
+ switch( aClassId )
+ {
+ case FRAME_PCB:
+ frame = dynamic_cast< wxWindow* >( new PCB_EDIT_FRAME( aKiway, aParent ) );
+
+#if defined( KICAD_SCRIPTING )
+ // give the scripting helpers access to our frame
+ ScriptingSetPcbEditFrame( (PCB_EDIT_FRAME*) frame );
+#endif
+
+ if( Kiface().IsSingle() )
+ {
+ // only run this under single_top, not under a project manager.
+ CreateServer( frame, KICAD_PCB_PORT_SERVICE_NUMBER );
+ }
+
+ break;
+
+ case FRAME_PCB_MODULE_EDITOR:
+ frame = dynamic_cast< wxWindow* >( new FOOTPRINT_EDIT_FRAME( aKiway, aParent ) );
+ break;
+
+ case FRAME_PCB_MODULE_VIEWER:
+ case FRAME_PCB_MODULE_VIEWER_MODAL:
+ frame = dynamic_cast< wxWindow* >( new FOOTPRINT_VIEWER_FRAME( aKiway, aParent,
+ FRAME_T( aClassId ) ) );
+ break;
+
+ case FRAME_PCB_FOOTPRINT_WIZARD_MODAL:
+ frame = dynamic_cast< wxWindow* >( new FOOTPRINT_WIZARD_FRAME( aKiway, aParent,
+ FRAME_T( aClassId ) ) );
+ break;
+
+ default:
+ ;
+ }
+
+ return frame;
+ }
+
+ /**
+ * Function IfaceOrAddress
+ * return a pointer to the requested object. The safest way to use this
+ * is to retrieve a pointer to a static instance of an interface, similar to
+ * how the KIFACE interface is exported. But if you know what you are doing
+ * use it to retrieve anything you want.
+ *
+ * @param aDataId identifies which object you want the address of.
+ *
+ * @return void* - and must be cast into the know type.
+ */
+ void* IfaceOrAddress( int aDataId )
+ {
+ return NULL;
+ }
+
+} kiface( "pcbnew", KIWAY::FACE_PCB );
+
+} // namespace
+
+using namespace PCB;
+
+
+static PGM_BASE* process;
+
+
+KIFACE_I& Kiface() { return kiface; }
+
+
+// KIFACE_GETTER's actual spelling is a substitution macro found in kiway.h.
+// KIFACE_GETTER will not have name mangling due to declaration in kiway.h.
+MY_API( KIFACE* ) KIFACE_GETTER( int* aKIFACEversion, int aKiwayVersion, PGM_BASE* aProgram )
+{
+ process = aProgram;
+ return &kiface;
+}
+
+#if defined( BUILD_KIWAY_DLL )
+PGM_BASE& Pgm()
+{
+ wxASSERT( process ); // KIFACE_GETTER has already been called.
+ return *process;
+}
+#endif
+
+
+#if defined( KICAD_SCRIPTING )
+static bool scriptingSetup()
+{
+ wxString path_frag;
+
+#if defined( __WINDOWS__ )
+ // If our python.exe (in kicad/bin) exists, force our kicad python environment
+ wxString kipython = FindKicadFile( "python.exe" );
+
+ // we need only the path:
+ wxFileName fn( kipython );
+ kipython = fn.GetPath();
+
+ // If our python install is existing inside kicad, use it
+ // Note: this is usefull only when an other python version is installed
+ if( wxDirExists( kipython ) )
+ {
+ // clear any PYTHONPATH and PYTHONHOME env var definition: the default
+ // values work fine inside Kicad:
+ wxSetEnv( wxT( "PYTHONPATH" ), wxEmptyString );
+ wxSetEnv( wxT( "PYTHONHOME" ), wxEmptyString );
+
+ // Add our python executable path in first position:
+ wxString ppath;
+ wxGetEnv( wxT( "PATH" ), &ppath );
+
+ kipython << wxT( ";" ) << ppath;
+ wxSetEnv( wxT( "PATH" ), kipython );
+ }
+
+ // TODO: make this path definable by the user, and set more than one path
+ // (and remove the fixed paths from <src>/scripting/kicadplugins.i)
+
+ // wizard plugins are stored in kicad/bin/plugins.
+ // so add this path to python scripting default search paths
+ // which are ( [KICAD_PATH] is an environment variable to define)
+ // [KICAD_PATH]/scripting/plugins
+ // Add this default search path:
+ path_frag = Pgm().GetExecutablePath() + wxT( "../share/kicad/scripting/plugins" );
+
+#elif defined( __WXMAC__ )
+ // TODO:
+ // For scripting currently only the bundle scripting path and the path
+ // defined by $(KICAD_PATH)/scripting/plugins is defined.
+ // These paths are defined here and in kicadplugins.i
+ // In future, probably more paths are of interest:
+ // * User folder (~/Library/Application Support/kicad/scripting/plugins)
+ // => GetOSXKicadUserDataDir() + wxT( "/scripting/plugins" );
+ // * Machine folder (/Library/Application Support/kicad/scripting/plugins)
+ // => GetOSXKicadMachineDataDir() + wxT( "/scripting/plugins" );
+
+ // This path is given to LoadPlugins() from kicadplugins.i, which
+ // only supports one path. Only use bundle scripting path for now.
+ path_frag = GetOSXKicadDataDir() + wxT( "/scripting/plugins" );
+
+ // Add default paths to PYTHONPATH
+ wxString pypath;
+
+ // Bundle scripting folder (<kicad.app>/Contents/SharedSupport/scripting/plugins)
+ pypath += GetOSXKicadDataDir() + wxT( "/scripting/plugins" );
+
+ // $(KICAD_PATH)/scripting/plugins is always added in kicadplugins.i
+ if( wxGetenv("KICAD_PATH") != NULL )
+ {
+ pypath += wxT( ":" ) + wxString( wxGetenv("KICAD_PATH") );
+ }
+
+ // Bundle wxPython folder (<kicad.app>/Contents/Frameworks/python/site-packages)
+ pypath += wxT( ":" ) + Pgm().GetExecutablePath() +
+ wxT( "Contents/Frameworks/python/site-packages" );
+
+ // Original content of $PYTHONPATH
+ if( wxGetenv( wxT( "PYTHONPATH" ) ) != NULL )
+ {
+ pypath = wxString( wxGetenv( wxT( "PYTHONPATH" ) ) ) + wxT( ":" ) + pypath;
+ }
+
+ // set $PYTHONPATH
+ wxSetEnv( "PYTHONPATH", pypath );
+
+#else
+ // Linux-specific setup
+ wxString pypath;
+
+ pypath = Pgm().GetExecutablePath() + wxT( "../lib/python2.7/dist-packages" );
+
+ if( !wxIsEmpty( wxGetenv( wxT( "PYTHONPATH" ) ) ) )
+ pypath = wxString( wxGetenv( wxT( "PYTHONPATH" ) ) ) + wxT( ":" ) + pypath;
+
+ wxSetEnv( wxT( "PYTHONPATH" ), pypath );
+
+ // Add this default search path:
+ path_frag = Pgm().GetExecutablePath() + wxT( "../share/kicad/scripting/plugins" );
+#endif
+
+ if( !pcbnewInitPythonScripting( TO_UTF8( path_frag ) ) )
+ {
+ wxLogError( wxT( "pcbnewInitPythonScripting() failed." ) );
+ return false;
+ }
+
+ return true;
+}
+#endif // KICAD_SCRIPTING
+
+
+/// The global footprint library table. This is not dynamically allocated because
+/// in a multiple project environment we must keep its address constant (since it is
+/// the fallback table for multiple projects).
+FP_LIB_TABLE GFootprintTable;
+
+
+bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
+{
+ // This is process level, not project level, initialization of the DSO.
+
+ // Do nothing in here pertinent to a project!
+
+ start_common( aCtlBits );
+
+ // Must be called before creating the main frame in order to
+ // display the real hotkeys in menus or tool tips
+ ReadHotkeyConfig( PCB_EDIT_FRAME_NAME, g_Board_Editor_Hokeys_Descr );
+
+ try
+ {
+ // The global table is not related to a specific project. All projects
+ // will use the same global table. So the KIFACE::OnKifaceStart() contract
+ // of avoiding anything project specific is not violated here.
+
+ if( !FP_LIB_TABLE::LoadGlobalTable( GFootprintTable ) )
+ {
+ DisplayInfoMessage( NULL, _(
+ "You have run Pcbnew for the first time using the "
+ "new footprint library table method for finding footprints.\n"
+ "Pcbnew has either copied the default "
+ "table or created an empty table in the kicad configuration folder.\n"
+ "You must first configure the library "
+ "table to include all footprint libraries you want to use.\n"
+ "See the \"Footprint Library Table\" section of "
+ "the CvPcb or Pcbnew documentation for more information." ) );
+ }
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ // if we are here, a incorrect global footprint library table was found.
+ // Incorrect global footprint library table is not a fatal error:
+ // the user just has to edit the (partially) loaded table.
+ wxString msg = wxString::Format( _(
+ "An error occurred attempting to load the global footprint library "
+ "table:\n\n%s\n\n"
+ "Please edit this global footprint library table in Preferences menu" ),
+ GetChars( ioe.errorText )
+ );
+ DisplayError( NULL, msg );
+ }
+
+#if defined(KICAD_SCRIPTING)
+ scriptingSetup();
+#endif
+
+ return true;
+}
+
+
+void IFACE::OnKifaceEnd()
+{
+ end_common();
+
+#if KICAD_SCRIPTING_WXPYTHON
+ // Restore the thread state and tell Python to cleanup after itself.
+ // wxPython will do its own cleanup as part of that process.
+ // This should only be called if python was setup correctly.
+
+ if( IsWxPythonLoaded() )
+ pcbnewFinishPythonScripting();
+#endif
+}
diff --git a/pcbnew/pcbnew.h b/pcbnew/pcbnew.h
new file mode 100644
index 0000000..fbd71f2
--- /dev/null
+++ b/pcbnew/pcbnew.h
@@ -0,0 +1,114 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew.h
+ */
+
+#ifndef PCBNEW_H
+#define PCBNEW_H
+
+
+#include <fctsys.h> // wxWidgets include.
+#include <base_struct.h> // IS_DRAGGED and IN_EDIT definitions.
+#include <dlist.h>
+#include <convert_to_biu.h> // to define DMils2iu() conversion function
+#include <layers_id_colors_and_visibility.h>
+
+// Arcs are approximated by segments: define the number of segments per 360 deg (KiCad uses 0.1
+// deg approximation). Be aware 3600 / ARC_APPROX_SEGMENTS_COUNT_LOW_DEF is an integer.
+#define ARC_APPROX_SEGMENTS_COUNT_LOW_DEF 16
+#define ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF 32
+
+/* Flag used in locate functions. The locate ref point is the on grid cursor or the off
+ * grid mouse cursor. */
+#define CURSEUR_ON_GRILLE (0 << 0)
+#define CURSEUR_OFF_GRILLE (1 << 0)
+
+#define IGNORE_LOCKED (1 << 1) ///< if module is locked, do not select for single module operation
+#define MATCH_LAYER (1 << 2) ///< if module not on current layer, do not select
+#define VISIBLE_ONLY (1 << 3) ///< if module not on a visible layer, do not select
+
+/// Flag used in locate routines (from which endpoint work)
+enum ENDPOINT_T {
+ ENDPOINT_START = 0,
+ ENDPOINT_END = 1
+};
+
+#define DIM_ANCRE_MODULE 3 // Anchor size (footprint center)
+
+
+#define TEXTS_MIN_SIZE DMils2iu( 50 ) ///< Minimum text size in Pcbnew units value (50 * 0.0001 mils)
+#define TEXTS_MAX_SIZE DMils2iu( 10000 ) ///< Maximum text size in Pcbnew units value (1 inch) )
+#define TEXTS_MAX_WIDTH DMils2iu( 5000 ) ///< Maximum text width in Pcbnew units value (0.5 inches)
+#define MIN_DRAW_WIDTH 1 ///< Minimum trace drawing width in pixels.
+
+
+// Flag to force the SKETCH mode to display items (.m_Flags member)
+#define FORCE_SKETCH ( IS_DRAGGED | IN_EDIT )
+
+/* Name of the document footprint list
+ * usually located in share/modules/footprints_doc
+ * this is of the responsibility to users to create this file
+ * if they want to have a list of footprints
+ * default is "footprints_doc/footprints.pdf"
+ */
+extern wxString g_DocModulesFileName;
+
+// variables
+extern bool g_Drc_On;
+extern bool g_AutoDeleteOldTrack;
+extern bool g_Raccord_45_Auto;
+extern bool g_Track_45_Only_Allowed;
+extern bool g_Alternate_Track_Posture;
+extern bool g_Segments_45_Only;
+
+// Layer pair for auto routing and switch layers by hotkey
+extern LAYER_ID g_Route_Layer_TOP;
+extern LAYER_ID g_Route_Layer_BOTTOM;
+
+extern bool g_TwoSegmentTrackBuild;
+
+extern int g_MagneticPadOption;
+extern int g_MagneticTrackOption;
+
+extern bool g_DumpZonesWhenFilling;
+
+extern wxPoint g_Offset_Module; // Offset trace when moving footprint.
+
+/// List of segments of the trace currently being drawn.
+class TRACK;
+extern DLIST<TRACK> g_CurrentTrackList;
+#define g_CurrentTrackSegment g_CurrentTrackList.GetLast() ///< most recently created segment
+#define g_FirstTrackSegment g_CurrentTrackList.GetFirst() ///< first segment created
+
+
+enum MagneticPadOptionValues {
+ no_effect,
+ capture_cursor_in_track_tool,
+ capture_always
+};
+
+
+#endif // PCBNEW_H
diff --git a/pcbnew/pcbnew.icns b/pcbnew/pcbnew.icns
new file mode 100644
index 0000000..211735b
--- /dev/null
+++ b/pcbnew/pcbnew.icns
Binary files differ
diff --git a/pcbnew/pcbnew.rc b/pcbnew/pcbnew.rc
new file mode 100644
index 0000000..f568bb0
--- /dev/null
+++ b/pcbnew/pcbnew.rc
@@ -0,0 +1,3 @@
+icon_pcbnew ICON "../bitmaps_png/icons/icon_pcbnew.ico"
+
+#include "wx/msw/wx.rc"
diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp
new file mode 100644
index 0000000..deb126f
--- /dev/null
+++ b/pcbnew/pcbnew_config.cpp
@@ -0,0 +1,553 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew_config.cpp
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <project.h>
+#include <class_drawpanel.h>
+#include <pcb_draw_panel_gal.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <xnode.h>
+#include <common.h>
+#include <macros.h>
+#include <wxPcbStruct.h>
+#include <class_board_design_settings.h>
+#include <plot_common.h>
+#include <worksheet.h>
+#include <dialog_hotkeys_editor.h>
+#include <fp_lib_table.h>
+#include <fp_lib_table_lexer.h>
+#include <worksheet_shape_builder.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <pcbplot.h>
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <hotkeys.h>
+#include <pcbnew_config.h>
+#include <module_editor_frame.h>
+#include <modview_frame.h>
+
+#include <invoke_pcb_dialog.h>
+#include <dialog_mask_clearance.h>
+#include <dialog_general_options.h>
+#include <wildcards_and_files_ext.h>
+
+
+void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ wxFileName fn;
+
+ switch( id )
+ {
+ case ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG:
+ m_show_layer_manager_tools = ! m_show_layer_manager_tools;
+ m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( m_show_layer_manager_tools );
+ m_auimgr.Update();
+
+ GetMenuBar()->SetLabel( ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
+ m_show_layer_manager_tools ?
+ _("Hide &Layers Manager" ) : _("Show &Layers Manager" ));
+ break;
+
+ case ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR:
+ m_show_microwave_tools = ! m_show_microwave_tools;
+ m_auimgr.GetPane( wxT( "m_microWaveToolBar" ) ).Show( m_show_microwave_tools );
+ m_auimgr.Update();
+
+ GetMenuBar()->SetLabel( ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR,
+ m_show_microwave_tools ?
+ _( "Hide Microwave Toolbar" ): _( "Show Microwave Toolbar" ));
+ break;
+
+
+ case ID_PCB_LAYERS_SETUP:
+ if( InvokeLayerSetup( this, GetBoard() ) )
+ {
+ LAYER_ID cur_layer = GetActiveLayer();
+
+ // If after showing the dialog the user has removed the active layer,
+ // then select a new active layer (front copper layer).
+ if( !GetBoard()->GetEnabledLayers()[ cur_layer ] )
+ cur_layer = F_Cu;
+
+ SetActiveLayer( cur_layer );
+
+ OnModify();
+ ReCreateLayerBox();
+ ReFillLayerWidget();
+
+ if( IsGalCanvasActive() )
+ static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() )->SyncLayersVisibility( GetBoard() );
+ }
+ break;
+
+ case ID_PCB_LIB_WIZARD:
+ case ID_PCB_LIB_TABLE_EDIT:
+ {
+ bool tableChanged = false;
+ int r = 0;
+
+ if( id == ID_PCB_LIB_TABLE_EDIT )
+ r = InvokePcbLibTableEditor( this, &GFootprintTable, Prj().PcbFootprintLibs() );
+ else
+ r = InvokeFootprintWizard( this, &GFootprintTable, Prj().PcbFootprintLibs() );
+
+ if( r & 1 )
+ {
+ try
+ {
+ FILE_OUTPUTFORMATTER sf( FP_LIB_TABLE::GetGlobalTableFileName() );
+
+ GFootprintTable.Format( &sf, 0 );
+ tableChanged = true;
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _(
+ "Error occurred saving the global footprint library "
+ "table:\n\n%s" ),
+ GetChars( ioe.errorText.GetData() )
+ );
+ wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
+ }
+ }
+
+ // If no board file is defined, do not save the project specific library table. It
+ // is kept in memory and created in the path when the new board is saved.
+ if( (r & 2) && !GetBoard()->GetFileName().IsEmpty() )
+ {
+ wxString tblName = Prj().FootprintLibTblName();
+
+ try
+ {
+ Prj().PcbFootprintLibs()->Save( tblName );
+ tableChanged = true;
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _(
+ "Error occurred saving project specific footprint library "
+ "table:\n\n%s" ),
+ GetChars( ioe.errorText )
+ );
+ wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
+ }
+ }
+
+ FOOTPRINT_VIEWER_FRAME* viewer;
+
+ if( tableChanged && (viewer = (FOOTPRINT_VIEWER_FRAME*)Kiway().Player( FRAME_PCB_MODULE_VIEWER, false )) != NULL )
+ {
+ viewer->ReCreateLibraryList();
+ }
+ }
+ break;
+
+ case ID_PCB_3DSHAPELIB_WIZARD:
+#ifdef BUILD_GITHUB_PLUGIN
+ Invoke3DShapeLibsDownloaderWizard( this );
+#endif
+ break;
+
+ case ID_PCB_MASK_CLEARANCE:
+ {
+ DIALOG_PADS_MASK_CLEARANCE dlg( this );
+
+ if( dlg.ShowModal() == 1 && IsGalCanvasActive() )
+ {
+ for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
+ module->ViewUpdate();
+
+ GetGalCanvas()->Refresh();
+ }
+ }
+ break;
+
+ case wxID_PREFERENCES:
+ {
+ DIALOG_GENERALOPTIONS dlg( this );
+ dlg.ShowModal();
+ }
+ break;
+
+ case ID_PCB_PAD_SETUP:
+ InstallPadOptionsFrame( NULL );
+ break;
+
+ case ID_CONFIG_SAVE:
+ SaveProjectSettings( true );
+ break;
+
+ case ID_CONFIG_READ:
+ {
+ fn = GetBoard()->GetFileName();
+ fn.SetExt( ProjectFileExtension );
+
+ wxFileDialog dlg( this, _( "Read Project File" ), fn.GetPath(),
+ fn.GetFullName(), ProjectFileWildcard,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ break;
+
+ if( !wxFileExists( dlg.GetPath() ) )
+ {
+ wxString msg = wxString::Format( _(
+ "File %s not found" ),
+ GetChars( dlg.GetPath() )
+ );
+ DisplayError( this, msg );
+ break;
+ }
+
+ wxString pro_file = dlg.GetPath();
+
+ Prj().ConfigLoad( Kiface().KifaceSearch(), GROUP_PCB, GetProjectFileParameters(), pro_file );
+ }
+ break;
+
+ // Hotkey IDs
+ case ID_PREFERENCES_HOTKEY_EXPORT_CONFIG:
+ ExportHotkeyConfigToFile( g_Board_Editor_Hokeys_Descr, wxT( "pcbnew" ) );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_IMPORT_CONFIG:
+ ImportHotkeyConfigFromFile( g_Board_Editor_Hokeys_Descr, wxT( "pcbnew" ) );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_SHOW_EDITOR:
+ InstallHotkeyFrame( this, g_Board_Editor_Hokeys_Descr );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST:
+ // Display current hotkey list for Pcbnew.
+ DisplayHotkeyList( this, g_Board_Editor_Hokeys_Descr );
+ break;
+
+ // Macros IDs
+ case ID_PREFRENCES_MACROS_SAVE:
+ SaveMacros();
+ break;
+
+ case ID_PREFRENCES_MACROS_READ:
+ ReadMacros();
+ break;
+
+ default:
+ DisplayError( this, wxT( "PCB_EDIT_FRAME::Process_Config error" ) );
+ }
+}
+
+
+bool PCB_EDIT_FRAME::LoadProjectSettings()
+{
+ wxLogDebug( wxT( "Loading project '%s' settings." ),
+ GetChars( Prj().GetProjectFullName() ) );
+
+ bool rc = Prj().ConfigLoad( Kiface().KifaceSearch(), GROUP_PCB, GetProjectFileParameters() );
+
+ // Load the page layout decr file, from the filename stored in
+ // BASE_SCREEN::m_PageLayoutDescrFileName, read in config project file
+ // If empty, or not existing, the default descr is loaded
+ WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
+ wxString pg_fullfilename = WORKSHEET_LAYOUT::MakeFullFileName(
+ BASE_SCREEN::m_PageLayoutDescrFileName,
+ Prj().GetProjectPath() );
+
+ pglayout.SetPageLayout( pg_fullfilename );
+
+ return rc;
+}
+
+
+void PCB_EDIT_FRAME::SaveProjectSettings( bool aAskForSave )
+{
+ wxFileName fn = Prj().GetProjectFullName();
+
+ if( aAskForSave )
+ {
+ wxFileDialog dlg( this, _( "Save Project File" ),
+ fn.GetPath(), fn.GetFullName(),
+ ProjectFileWildcard, wxFD_SAVE | wxFD_CHANGE_DIR );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ fn = dlg.GetPath();
+ }
+
+ wxString pro_name = fn.GetFullPath();
+
+ Prj().ConfigSave( Kiface().KifaceSearch(), GROUP_PCB, GetProjectFileParameters(), pro_name );
+}
+
+
+PARAM_CFG_ARRAY PCB_EDIT_FRAME::GetProjectFileParameters()
+{
+ PARAM_CFG_ARRAY pca;
+
+ // This one cannot be cached because some settings are going to/from the BOARD,
+ // so pointers into that cannot be saved for long.
+
+ pca.push_back( new PARAM_CFG_FILENAME( wxT( "PageLayoutDescrFile" ),
+ &BASE_SCREEN::m_PageLayoutDescrFileName ) );
+
+ pca.push_back( new PARAM_CFG_FILENAME( wxT( "LastNetListRead" ), &m_lastNetListRead ) );
+
+ GetBoard()->GetDesignSettings().AppendConfigs( &pca );
+
+ return pca;
+}
+
+
+PARAM_CFG_ARRAY& PCB_EDIT_FRAME::GetConfigurationSettings()
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ if( m_configSettings.empty() )
+ {
+ COLORS_DESIGN_SETTINGS cds; // constructor fills this with sensible colors
+
+ // Units used in dialogs and toolbars
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "Units" ),
+ (int*)&g_UserUnit, MILLIMETRES ) );
+
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "DisplayPolarCoords" ),
+ &displ_opts->m_DisplayPolarCood, false ) );
+ // Display options and modes:
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "ViaHoleDisplayMode" ),
+ (int*) &displ_opts->m_DisplayViaMode,
+ VIA_SPECIAL_HOLE_SHOW, VIA_HOLE_NOT_SHOW,
+ OPT_VIA_HOLE_END - 1 ) );
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "ShowNetNamesMode" ),
+ &displ_opts->m_DisplayNetNamesMode, 3, 0, 3 ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "DisplayTrackFilled" ),
+ &displ_opts->m_DisplayPcbTrackFill, true ) );
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "TrackDisplayClearance" ),
+ (int*) &displ_opts->m_ShowTrackClearanceMode,
+ SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "PadFill" ),
+ &displ_opts->m_DisplayPadFill, true ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "ViaFill" ),
+ &displ_opts->m_DisplayViaFill, true ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "PadAffG" ),
+ &displ_opts->m_DisplayPadIsol, true ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "PadSNum" ),
+ &displ_opts->m_DisplayPadNum, true ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "ModAffC" ),
+ &displ_opts->m_DisplayModEdgeFill, FILLED ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "ModAffT" ),
+ &displ_opts->m_DisplayModTextFill, FILLED ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "PcbAffT" ),
+ &displ_opts->m_DisplayDrawItemsFill, FILLED ) );
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "PcbShowZonesMode" ),
+ &displ_opts->m_DisplayZonesMode, 0, 0, 2 ) );
+
+ // layer colors:
+ wxASSERT( DIM( cds.m_LayersColors ) == LAYER_ID_COUNT );
+ for( int i = 0; i<LAYER_ID_COUNT; ++i )
+ {
+ wxString vn = wxString::Format(
+ wxT( "ColorPCBLayer_%s" ),
+ LSET::Name( LAYER_ID( i ) ) );
+
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, vn, LOC_COLOR( i ), cds.m_LayersColors[i] ) );
+ }
+
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorTxtFrontEx" ),
+ ITEM_COLOR( MOD_TEXT_FR_VISIBLE ),
+ LIGHTGRAY ) );
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorTxtBackEx" ),
+ ITEM_COLOR( MOD_TEXT_BK_VISIBLE ),
+ BLUE ) );
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorTxtInvisEx" ),
+ ITEM_COLOR( MOD_TEXT_INVISIBLE ),
+ DARKGRAY ) );
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorAnchorEx" ),
+ ITEM_COLOR( ANCHOR_VISIBLE ), BLUE ) );
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorPadBackEx" ),
+ ITEM_COLOR( PAD_BK_VISIBLE ), GREEN ) );
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorPadFrontEx" ),
+ ITEM_COLOR( PAD_FR_VISIBLE ), RED ) );
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorViaThruEx" ),
+ ITEM_COLOR( VIA_THROUGH_VISIBLE ),
+ LIGHTGRAY ) );
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorViaBBlindEx" ),
+ ITEM_COLOR( VIA_BBLIND_VISIBLE ),
+ BROWN ) );
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorViaMicroEx" ),
+ ITEM_COLOR( VIA_MICROVIA_VISIBLE ),
+ CYAN ) );
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorNonPlatedEx" ),
+ ITEM_COLOR( NON_PLATED_VISIBLE ),
+ YELLOW ) );
+ m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorRatsEx" ),
+ ITEM_COLOR( RATSNEST_VISIBLE ),
+ WHITE ) );
+
+ // Miscellaneous:
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "RotationAngle" ), &m_rotationAngle,
+ 900, 1, 900 ) );
+ m_configSettings.push_back( new PARAM_CFG_INT( true, wxT( "MaxLnkS" ),
+ &displ_opts->m_MaxLinksShowed,
+ 3, 0, 15 ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "ShowMRa" ),
+ &displ_opts->m_Show_Module_Ratsnest, true ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "TwoSegT" ),
+ &g_TwoSegmentTrackBuild, true ) );
+ m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "SegmPcb45Only" )
+ , &g_Segments_45_Only, true ) );
+ }
+
+ return m_configSettings;
+}
+
+
+void PCB_EDIT_FRAME::SaveMacros()
+{
+ wxXmlDocument xml;
+ wxXmlAttribute *macrosProp, *hkProp, *xProp, *yProp;
+ wxString str, hkStr, xStr, yStr;
+
+ wxFileName fn = GetBoard()->GetFileName();
+ fn.SetExt( MacrosFileExtension );
+
+ wxFileDialog dlg( this, _( "Save Macros File" ), fn.GetPath(), fn.GetFullName(),
+ MacrosFileWildcard, wxFD_SAVE | wxFD_CHANGE_DIR );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ XNODE *rootNode = new XNODE( wxXML_ELEMENT_NODE, wxT( "macrosrootnode" ), wxEmptyString );
+ xml.SetRoot( rootNode );
+
+ for( int number = 9; number >= 0; number-- )
+ {
+ str.Printf( wxT( "%d" ), number );
+ macrosProp = new wxXmlAttribute( wxT( "number" ), str );
+
+ XNODE * macrosNode = new XNODE( rootNode, wxXML_ELEMENT_NODE,
+ wxT( "macros" ), wxEmptyString,
+ macrosProp );
+
+ for( std::list<MACROS_RECORD>::reverse_iterator i = m_Macros[number].m_Record.rbegin();
+ i != m_Macros[number].m_Record.rend();
+ i++ )
+ {
+ hkStr.Printf( wxT( "%d" ), i->m_HotkeyCode );
+ xStr.Printf( wxT( "%d" ), i->m_Position.x );
+ yStr.Printf( wxT( "%d" ), i->m_Position.y );
+
+ yProp = new wxXmlAttribute( wxT( "y" ), yStr );
+ xProp = new wxXmlAttribute( wxT( "x" ), xStr, yProp );
+ hkProp = new wxXmlAttribute( wxT( "hkcode" ), hkStr, xProp );
+
+ new XNODE( macrosNode, wxXML_ELEMENT_NODE, wxT( "hotkey" ),
+ wxEmptyString, hkProp );
+ }
+ }
+
+ xml.SetFileEncoding( wxT( "UTF-8" ) );
+ xml.Save( dlg.GetFilename() );
+}
+
+
+void PCB_EDIT_FRAME::ReadMacros()
+{
+ wxFileName fn;
+
+ fn = GetBoard()->GetFileName();
+ fn.SetExt( MacrosFileExtension );
+
+ wxFileDialog dlg( this, _( "Read Macros File" ), fn.GetPath(),
+ fn.GetFullName(), MacrosFileWildcard,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ if( !wxFileExists( dlg.GetPath() ) )
+ {
+ wxString msg;
+ msg.Printf( _( "File %s not found" ), GetChars( dlg.GetPath() ) );
+ DisplayError( this, msg );
+ return;
+ }
+
+ wxXmlDocument xml;
+
+ xml.SetFileEncoding( wxT( "UTF-8" ) );
+
+ if( !xml.Load( dlg.GetFilename() ) )
+ return;
+
+ XNODE *macrosNode = (XNODE*) xml.GetRoot()->GetChildren();
+
+ while( macrosNode )
+ {
+ int number = -1;
+
+ if( macrosNode->GetName() == wxT( "macros" ) )
+ {
+ number = wxAtoi( macrosNode->GetAttribute( wxT( "number" ), wxT( "-1" ) ) );
+
+ if( number >= 0 && number < 10 )
+ {
+ m_Macros[number].m_Record.clear();
+
+ XNODE *hotkeyNode = macrosNode->GetChildren();
+
+ while( hotkeyNode )
+ {
+ if( hotkeyNode->GetName() == wxT( "hotkey" ) )
+ {
+ int x = wxAtoi( hotkeyNode->GetAttribute( wxT( "x" ), wxT( "0" ) ) );
+ int y = wxAtoi( hotkeyNode->GetAttribute( wxT( "y" ), wxT( "0" ) ) );
+ int hk = wxAtoi( hotkeyNode->GetAttribute( wxT( "hkcode" ), wxT( "0" ) ) );
+
+ MACROS_RECORD macros_record;
+ macros_record.m_HotkeyCode = hk;
+ macros_record.m_Position.x = x;
+ macros_record.m_Position.y = y;
+ m_Macros[number].m_Record.push_back( macros_record );
+ }
+
+ hotkeyNode = hotkeyNode->GetNext();
+ }
+ }
+ }
+
+ macrosNode = macrosNode->GetNext();
+ }
+}
diff --git a/pcbnew/pcbnew_config.h b/pcbnew/pcbnew_config.h
new file mode 100644
index 0000000..f4c153e
--- /dev/null
+++ b/pcbnew/pcbnew_config.h
@@ -0,0 +1,17 @@
+/**
+ * @file pcbnew_config.h
+ * @brief Configuration parameters for Pcbnew.
+ */
+
+#ifndef _PCBNEW_CONFIG_H_
+#define _PCBNEW_CONFIG_H_
+
+#include <config_params.h>
+#include <colors_selection.h>
+
+/* Useful macro : */
+#define LOC_COLOR(layer) &g_ColorsSettings.m_LayersColors[layer]
+#define ITEM_COLOR(item_visible) &g_ColorsSettings.m_ItemsColors[item_visible]
+
+
+#endif // _PCBNEW_CONFIG_H_
diff --git a/pcbnew/pcbnew_doc.icns b/pcbnew/pcbnew_doc.icns
new file mode 100644
index 0000000..38b6074
--- /dev/null
+++ b/pcbnew/pcbnew_doc.icns
Binary files differ
diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h
new file mode 100644
index 0000000..90bdc66
--- /dev/null
+++ b/pcbnew/pcbnew_id.h
@@ -0,0 +1,399 @@
+#ifndef PCBNEW_ID_H_
+#define PCBNEW_ID_H_
+
+#include <id.h>
+
+/**
+ * Command IDs for the printed circuit board editor.
+ *
+ * Please add IDs that are unique to the printed circuit board editor (Pcbnew)
+ * here and not in the global id.h file. This will prevent the entire project
+ * from being rebuilt when adding new commands to the Pcbnew.
+ */
+
+#define MAX_ITEMS_IN_PICKER 15 ///< max no. items in the popup menu for item selection
+
+enum pcbnew_ids
+{
+ ID_MAIN_MENUBAR = ID_END_LIST,
+ ID_MICROWAVE_V_TOOLBAR,
+ ID_OPEN_MODULE_EDITOR,
+ ID_OPEN_MODULE_VIEWER,
+ ID_READ_NETLIST,
+ ID_SET_RELATIVE_OFFSET,
+ ID_COPY_BOARD_AS,
+
+ // Right vertical tool bar command IDs.
+ ID_PCB_HIGHLIGHT_BUTT,
+ ID_PCB_SHOW_1_RATSNEST_BUTT,
+ ID_PCB_MODULE_BUTT,
+ ID_TRACK_BUTT,
+ ID_PCB_ZONES_BUTT,
+ ID_PCB_KEEPOUT_AREA_BUTT,
+ ID_PCB_ADD_LINE_BUTT,
+ ID_PCB_CIRCLE_BUTT,
+ ID_PCB_ARC_BUTT,
+ ID_PCB_ADD_TEXT_BUTT,
+ ID_PCB_DIMENSION_BUTT,
+ ID_PCB_MIRE_BUTT,
+ ID_PCB_DELETE_ITEM_BUTT,
+ ID_PCB_PLACE_OFFSET_COORD_BUTT,
+ ID_PCB_PLACE_GRID_COORD_BUTT,
+ ID_DIFF_PAIR_BUTT,
+ ID_TUNE_SINGLE_TRACK_LEN_BUTT,
+ ID_TUNE_DIFF_PAIR_LEN_BUTT,
+ ID_TUNE_DIFF_PAIR_SKEW_BUTT,
+ ID_MENU_REMOVE_MEANDERS,
+ ID_MENU_MITER_TRACES,
+ ID_MENU_ADD_TEARDROPS,
+ ID_MENU_DIFF_PAIR_DIMENSIONS,
+ ID_MENU_INTERACTIVE_ROUTER_SETTINGS,
+
+ ID_PCB_MASK_CLEARANCE,
+ ID_PCB_LAYERS_SETUP,
+
+ ID_POPUP_PCB_START_RANGE,
+ ID_POPUP_PCB_MOVE_MODULE_REQUEST,
+ ID_POPUP_PCB_DRAG_MODULE_REQUEST,
+ ID_POPUP_PCB_EDIT_MODULE_PRMS,
+ ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT,
+ ID_POPUP_PCB_CHANGE_SIDE_MODULE,
+ ID_POPUP_PCB_DELETE_MODULE,
+ ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE,
+ ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE,
+ ID_POPUP_PCB_EXCHANGE_FOOTPRINTS,
+
+ ID_POPUP_PCB_EDIT_PAD,
+ ID_POPUP_PCB_EDIT_MORE_PAD,
+ ID_POPUP_PCB_EDIT_PADS_ON_MODULE,
+ ID_POPUP_PCB_DELETE_PAD,
+ ID_POPUP_PCB_ADD_PAD,
+ ID_POPUP_PCB_NEWSIZE_PAD,
+ ID_POPUP_PCB_ROTATE_PAD,
+ ID_POPUP_PCB_MOVE_PAD_REQUEST,
+ ID_POPUP_PCB_DRAG_PAD_REQUEST,
+ ID_POPUP_PCB_DUPLICATE_ITEM,
+ ID_POPUP_PCB_DUPLICATE_ITEM_AND_INCREMENT,
+ ID_POPUP_PCB_MOVE_EXACT,
+ ID_POPUP_PCB_CREATE_ARRAY,
+
+ ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST,
+ ID_POPUP_PCB_ROTATE_TEXTMODULE,
+ ID_POPUP_PCB_EDIT_TEXTMODULE,
+ ID_POPUP_PCB_DELETE_TEXTMODULE,
+ ID_POPUP_PCB_RESET_TEXT_SIZE,
+
+ ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST,
+ ID_POPUP_PCB_ROTATE_TEXTEPCB,
+ ID_POPUP_PCB_COPY_TEXTEPCB,
+ ID_POPUP_PCB_FLIP_TEXTEPCB,
+ ID_POPUP_PCB_EDIT_TEXTEPCB,
+ ID_POPUP_PCB_DELETE_TEXTEPCB,
+
+ ID_POPUP_PCB_MOVE_DRAWING_REQUEST,
+ ID_POPUP_PCB_EDIT_DRAWING,
+ ID_POPUP_PCB_DELETE_DRAWING,
+ ID_POPUP_PCB_DELETE_DRAWING_LAYER,
+ ID_POPUP_PCB_END_LINE,
+
+ ID_POPUP_PCB_BEGIN_TRACK,
+ ID_POPUP_PCB_EDIT_TRACK,
+ ID_POPUP_PCB_DELETE_TRACK,
+ ID_POPUP_PCB_DELETE_TRACKNET,
+ ID_POPUP_PCB_DELETE_TRACK_MNU,
+
+ ID_POPUP_PCB_MOVE_ZONE_CORNER,
+ ID_POPUP_PCB_ADD_ZONE_CORNER,
+ ID_POPUP_PCB_DELETE_ZONE_CORNER,
+ ID_POPUP_PCB_PLACE_ZONE_CORNER,
+ ID_POPUP_PCB_DELETE_ZONE_LAST_CREATED_CORNER,
+ ID_POPUP_PCB_EDIT_ZONE_PARAMS,
+ ID_POPUP_PCB_DELETE_ZONE,
+ ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE,
+ ID_POPUP_PCB_FILL_ALL_ZONES,
+ ID_POPUP_PCB_FILL_ZONE,
+ ID_POPUP_PCB_DELETE_ZONE_CONTAINER,
+ ID_POPUP_PCB_ZONE_DUPLICATE,
+ ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE,
+ ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE,
+ ID_POPUP_PCB_DELETE_ZONE_CUTOUT,
+ ID_POPUP_PCB_MOVE_ZONE_OUTLINES,
+ ID_POPUP_PCB_PLACE_ZONE_OUTLINES,
+ ID_POPUP_PCB_DRAG_ZONE_OUTLINE_SEGMENT,
+ ID_POPUP_PCB_PLACE_DRAGGED_ZONE_OUTLINE_SEGMENT,
+ ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES,
+ ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_CURRENT_ZONE,
+
+ ID_POPUP_PCB_DELETE_MARKER,
+
+ ID_POPUP_PCB_DELETE_DIMENSION,
+ ID_POPUP_PCB_MOVE_TEXT_DIMENSION_REQUEST,
+
+ ID_POPUP_PCB_MOVE_MIRE_REQUEST,
+ ID_POPUP_PCB_DELETE_MIRE,
+ ID_POPUP_PCB_EDIT_MIRE,
+
+ ID_POPUP_PCB_STOP_CURRENT_DRAWING,
+
+ ID_POPUP_PCB_EDIT_DIMENSION,
+ ID_POPUP_PCB_END_TRACK,
+ ID_POPUP_PCB_PLACE_THROUGH_VIA,
+ ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA,
+ ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA,
+ ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA,
+ ID_POPUP_PCB_PLACE_MICROVIA,
+ ID_POPUP_PCB_SWITCH_TRACK_POSTURE,
+
+ ID_POPUP_PCB_IMPORT_PAD_SETTINGS,
+ ID_POPUP_PCB_EXPORT_PAD_SETTINGS,
+
+ ID_POPUP_PCB_EDIT_TRACKSEG,
+ ID_POPUP_PCB_EDIT_TRACK_MNU,
+ ID_POPUP_PCB_EDIT_NET,
+ ID_POPUP_PCB_SELECT_LAYER,
+ ID_POPUP_PCB_SELECT_CU_LAYER,
+ ID_POPUP_PCB_SELECT_NO_CU_LAYER,
+ ID_POPUP_PCB_SELECT_LAYER_PAIR,
+ ID_POPUP_PCB_DELETE_EDGE,
+ ID_POPUP_PCB_MOVE_EDGE,
+ ID_POPUP_PCB_PLACE_EDGE,
+ ID_POPUP_PCB_END_EDGE,
+ ID_POPUP_PCB_LOCK_ON_TRACKSEG,
+ ID_POPUP_PCB_LOCK_OFF_TRACKSEG,
+ ID_POPUP_PCB_LOCK_ON_TRACK,
+ ID_POPUP_PCB_LOCK_OFF_TRACK,
+ ID_POPUP_PCB_LOCK_ON_NET,
+ ID_POPUP_PCB_LOCK_OFF_NET,
+ ID_POPUP_PCB_SETFLAGS_TRACK_MNU,
+
+ ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS,
+ ID_POPUP_PCB_EDIT_ALL_VIAS_AND_TRACK_SIZE,
+ ID_POPUP_PCB_EDIT_ALL_VIAS_SIZE,
+ ID_POPUP_PCB_EDIT_ALL_TRACK_SIZE,
+ ID_POPUP_PCB_DISPLAY_FOOTPRINT_DOC,
+ ID_POPUP_PCB_MOVE_TRACK_NODE,
+ ID_POPUP_PCB_BREAK_TRACK,
+ ID_POPUP_PCB_PLACE_MOVED_TRACK_NODE,
+ ID_POPUP_PCB_DRAG_TRACK_SEGMENT_KEEP_SLOPE,
+ ID_POPUP_PCB_DRAG_TRACK_SEGMENT,
+ ID_POPUP_PCB_MOVE_TRACK_SEGMENT,
+ ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST,
+ ID_POPUP_PCB_GETINFO_MARKER,
+ ID_POPUP_PCB_END_RANGE,
+
+ // Tracks and vias sizes general options
+ ID_AUX_TOOLBAR_PCB_VIA_SIZE,
+ ID_AUX_TOOLBAR_PCB_TRACK_WIDTH,
+ ID_AUX_TOOLBAR_PCB_SELECT_AUTO_WIDTH,
+ ID_POPUP_PCB_SELECT_WIDTH_START_RANGE,
+ ID_POPUP_PCB_SELECT_WIDTH,
+ ID_POPUP_PCB_SELECT_CUSTOM_WIDTH,
+ ID_POPUP_PCB_SELECT_AUTO_WIDTH,
+ ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES,
+ ID_POPUP_PCB_SELECT_WIDTH1,
+ ID_POPUP_PCB_SELECT_WIDTH2,
+ ID_POPUP_PCB_SELECT_WIDTH3,
+ ID_POPUP_PCB_SELECT_WIDTH4,
+ ID_POPUP_PCB_SELECT_WIDTH5,
+ ID_POPUP_PCB_SELECT_WIDTH6,
+ ID_POPUP_PCB_SELECT_WIDTH7,
+ ID_POPUP_PCB_SELECT_WIDTH8,
+ ID_POPUP_PCB_SELECT_WIDTH9,
+ ID_POPUP_PCB_SELECT_WIDTH10,
+ ID_POPUP_PCB_SELECT_WIDTH11,
+ ID_POPUP_PCB_SELECT_WIDTH12,
+ ID_POPUP_PCB_SELECT_WIDTH13,
+ ID_POPUP_PCB_SELECT_WIDTH14,
+ ID_POPUP_PCB_SELECT_WIDTH15,
+ ID_POPUP_PCB_SELECT_WIDTH16,
+ ID_POPUP_PCB_SELECT_VIASIZE,
+ ID_POPUP_PCB_SELECT_VIASIZE1,
+ ID_POPUP_PCB_SELECT_VIASIZE2,
+ ID_POPUP_PCB_SELECT_VIASIZE3,
+ ID_POPUP_PCB_SELECT_VIASIZE4,
+ ID_POPUP_PCB_SELECT_VIASIZE5,
+ ID_POPUP_PCB_SELECT_VIASIZE6,
+ ID_POPUP_PCB_SELECT_VIASIZE7,
+ ID_POPUP_PCB_SELECT_VIASIZE8,
+ ID_POPUP_PCB_SELECT_VIASIZE9,
+ ID_POPUP_PCB_SELECT_VIASIZE10,
+ ID_POPUP_PCB_SELECT_VIASIZE11,
+ ID_POPUP_PCB_SELECT_VIASIZE12,
+ ID_POPUP_PCB_SELECT_VIASIZE13,
+ ID_POPUP_PCB_SELECT_VIASIZE14,
+ ID_POPUP_PCB_SELECT_VIASIZE15,
+ ID_POPUP_PCB_SELECT_VIASIZE16,
+ ID_POPUP_PCB_SELECT_WIDTH_END_RANGE,
+
+ // reserve a block of MAX_ITEMS_IN_PICKER ids for the item selection popup
+ ID_POPUP_PCB_ITEM_SELECTION_START,
+ ID_POPUP_PCB_ITEM_SELECTION_END = MAX_ITEMS_IN_PICKER + ID_POPUP_PCB_ITEM_SELECTION_START,
+ ID_POPUP_PCB_AUTOPLACE_START_RANGE,
+ ID_POPUP_PCB_AUTOPLACE_FIXE_MODULE,
+ ID_POPUP_PCB_AUTOPLACE_FREE_MODULE,
+ ID_POPUP_PCB_AUTOPLACE_FREE_ALL_MODULES,
+ ID_POPUP_PCB_AUTOPLACE_FIXE_ALL_MODULES,
+ ID_POPUP_PCB_AUTOPLACE_CURRENT_MODULE,
+ ID_POPUP_PCB_SPREAD_ALL_MODULES,
+ ID_POPUP_PCB_SPREAD_NEW_MODULES,
+ ID_POPUP_PCB_AUTOPLACE_COMMANDS,
+ ID_POPUP_PCB_AUTOPLACE_ALL_MODULES,
+ ID_POPUP_PCB_AUTOPLACE_NEW_MODULES,
+ ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE,
+
+ ID_POPUP_PCB_AUTOROUTE_COMMANDS,
+ ID_POPUP_PCB_AUTOROUTE_ALL_MODULES,
+ ID_POPUP_PCB_AUTOROUTE_MODULE,
+ ID_POPUP_PCB_AUTOROUTE_PAD,
+ ID_POPUP_PCB_AUTOROUTE_NET,
+
+ ID_POPUP_PCB_AUTOROUTE_RESET_UNROUTED,
+ ID_POPUP_PCB_AUTOROUTE_SELECT_LAYERS,
+ ID_POPUP_PCB_AUTOPLACE_END_RANGE,
+
+ ID_POPUP_PCB_REORIENT_ALL_MODULES,
+
+ ID_MENU_READ_BOARD_BACKUP_FILE,
+ ID_MENU_RECOVER_BOARD_AUTOSAVE,
+ ID_MENU_ARCHIVE_MODULES,
+ ID_MENU_ARCHIVE_MODULES_IN_LIBRARY,
+ ID_MENU_CREATE_LIBRARY_AND_ARCHIVE_MODULES,
+ ID_MENU_MICELLANOUS,
+ ID_MENU_LIST_NETS,
+ ID_MENU_PCB_CLEAN,
+ ID_MENU_PCB_SWAP_LAYERS,
+ ID_MENU_PCB_RESET_TEXTMODULE_FIELDS_SIZES,
+
+ ID_GEN_EXPORT_FILE_IDF3,
+ ID_GEN_EXPORT_FILE_VRML,
+ ID_GEN_EXPORT_SPECCTRA,
+ ID_GEN_EXPORT_FILE_GENCADFORMAT,
+ ID_GEN_EXPORT_FILE_MODULE_REPORT,
+ ID_GEN_IMPORT_SPECCTRA_SESSION,
+ ID_GEN_IMPORT_SPECCTRA_DESIGN,
+ ID_GEN_IMPORT_DXF_FILE,
+
+ ID_TOOLBARH_PCB_MODE_MODULE,
+ ID_TOOLBARH_PCB_MODE_TRACKS,
+ ID_TOOLBARH_PCB_FREEROUTE_ACCESS,
+ ID_TOOLBARH_PCB_SCRIPTING_CONSOLE,
+
+ ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR,
+
+ ID_PCB_GEN_POS_MODULES_FILE,
+ ID_PCB_GEN_DRILL_FILE,
+ ID_PCB_GEN_D356_FILE,
+
+ ID_PCB_PAD_SETUP,
+
+ ID_PCB_DRAWINGS_WIDTHS_SETUP,
+
+ ID_PCB_GEN_CMP_FILE,
+ ID_MENU_PCB_SHOW_3D_FRAME,
+ ID_MENU_CANVAS_DEFAULT,
+ ID_MENU_CANVAS_OPENGL,
+ ID_MENU_CANVAS_CAIRO,
+ ID_PCB_USER_GRID_SETUP,
+ ID_PCB_GEN_BOM_FILE_FROM_BOARD,
+ ID_PCB_LIB_WIZARD,
+ ID_PCB_3DSHAPELIB_WIZARD,
+ ID_PCB_LIB_TABLE_EDIT,
+ ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG,
+ ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
+ ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR,
+
+ ID_TB_OPTIONS_SHOW_MANAGE_LAYERS_VERTICAL_TOOLBAR,
+ ID_TB_OPTIONS_SHOW_ZONES,
+ ID_TB_OPTIONS_SHOW_ZONES_DISABLE,
+ ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY,
+ ID_TB_OPTIONS_DRC_OFF,
+ ID_TB_OPTIONS_SHOW_RATSNEST,
+ ID_TB_OPTIONS_SHOW_MODULE_RATSNEST,
+ ID_TB_OPTIONS_AUTO_DEL_TRACK,
+ ID_TB_OPTIONS_SHOW_VIAS_SKETCH,
+ ID_TB_OPTIONS_SHOW_TRACKS_SKETCH,
+ ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE,
+ ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE,
+
+ ID_PCB_MUWAVE_START_CMD,
+ ID_PCB_MUWAVE_TOOL_DISPLAY_TOOLS,
+ ID_PCB_MUWAVE_TOOL_SELF_CMD,
+ ID_PCB_MUWAVE_TOOL_GAP_CMD,
+ ID_PCB_MUWAVE_TOOL_STUB_CMD,
+ ID_PCB_MUWAVE_TOOL_STUB_ARC_CMD,
+ ID_PCB_MUWAVE_TOOL_FUNCTION_SHAPE_CMD,
+ ID_PCB_MUWAVE_END_CMD,
+
+ ID_DRC_CONTROL,
+ ID_PCB_GLOBAL_DELETE,
+ ID_POPUP_PCB_DELETE_TRACKSEG,
+ ID_TOOLBARH_PCB_SELECT_LAYER,
+ ID_PCB_DISPLAY_OPTIONS_SETUP,
+
+ // Module editor right vertical tool bar commands.
+ ID_MODEDIT_PAD_TOOL,
+ ID_MODEDIT_LINE_TOOL,
+ ID_MODEDIT_CIRCLE_TOOL,
+ ID_MODEDIT_ARC_TOOL,
+ ID_MODEDIT_TEXT_TOOL,
+ ID_MODEDIT_ANCHOR_TOOL,
+ ID_MODEDIT_DELETE_TOOL,
+ ID_MODEDIT_PLACE_GRID_COORD,
+
+ // ID used in module editor:
+ ID_POPUP_MODEDIT_GLOBAL_EDIT_EDGE,
+ ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE,
+ ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE,
+ ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH,
+ ID_POPUP_MODEDIT_EDIT_EDGE,
+ ID_MODEDIT_CHECK,
+ ID_MODEDIT_SELECT_CURRENT_LIB,
+ ID_MODEDIT_SAVE_LIBMODULE,
+ ID_MODEDIT_SAVE_LIBRARY_AS,
+ ID_MODEDIT_DELETE_PART,
+ ID_MODEDIT_NEW_MODULE,
+ ID_MODEDIT_NEW_MODULE_FROM_WIZARD,
+ ID_MODEDIT_SHEET_SET,
+ ID_MODEDIT_LOAD_MODULE,
+ ID_MODEDIT_PAD_SETTINGS,
+ ID_MODEDIT_LOAD_MODULE_FROM_BOARD,
+ ID_MODEDIT_INSERT_MODULE_IN_BOARD,
+ ID_MODEDIT_UPDATE_MODULE_IN_BOARD,
+ ID_MODEDIT_EDIT_MODULE_PROPERTIES,
+ ID_MODEDIT_TRANSFORM_MODULE,
+ ID_MODEDIT_MODULE_ROTATE,
+ ID_MODEDIT_MODULE_MIRROR,
+ ID_MODEDIT_MODULE_MOVE_EXACT,
+ ID_MODEDIT_IMPORT_PART,
+ ID_MODEDIT_EXPORT_PART,
+ ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
+ ID_POPUP_MODEDIT_EDIT_BODY_ITEM,
+
+ ID_MODVIEW_LIBWINDOW,
+ ID_MODVIEW_FOOTPRINT_WINDOW,
+ ID_MODVIEW_LIB_LIST,
+ ID_MODVIEW_FOOTPRINT_LIST,
+ ID_MODVIEW_SELECT_LIB,
+ ID_MODVIEW_SELECT_PART,
+ ID_MODVIEW_PREVIOUS,
+ ID_MODVIEW_NEXT,
+ ID_MODVIEW_SHOW_3D_VIEW,
+ ID_MODVIEW_FOOTPRINT_EXPORT_TO_BOARD,
+ ID_FOOTPRINT_WIZARD_WINDOW,
+ ID_FOOTPRINT_WIZARD_PAGES,
+ ID_FOOTPRINT_WIZARD_PARAMETERS,
+ ID_FOOTPRINT_WIZARD_NEXT,
+ ID_FOOTPRINT_WIZARD_PREVIOUS,
+ ID_FOOTPRINT_WIZARD_DONE,
+ ID_FOOTPRINT_WIZARD_SHOW_3D_VIEW,
+ ID_FOOTPRINT_WIZARD_PAGE_LIST,
+ ID_FOOTPRINT_WIZARD_PARAMETER_LIST,
+ ID_FOOTPRINT_WIZARD_PAGES_WINDOW,
+ ID_FOOTPRINT_WIZARD_PARAMETERS_WINDOW,
+ ID_FOOTPRINT_WIZARD_SELECT_WIZARD,
+ ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD,
+
+ ID_PCBNEW_END_LIST
+};
+
+#endif // PCBNEW_ID_H_
diff --git a/pcbnew/pcbplot.cpp b/pcbnew/pcbplot.cpp
new file mode 100644
index 0000000..6d1b1c3
--- /dev/null
+++ b/pcbnew/pcbplot.cpp
@@ -0,0 +1,426 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/pcbplot.cpp
+ */
+
+#include <fctsys.h>
+#include <plot_common.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+#include <pcbplot.h>
+#include <pcbstruct.h>
+#include <base_units.h>
+#include <reporter.h>
+#include <class_board.h>
+#include <pcbnew.h>
+#include <plotcontroller.h>
+#include <pcb_plot_params.h>
+#include <wx/ffile.h>
+#include <dialog_plot.h>
+#include <macros.h>
+#include <build_version.h>
+
+
+const wxString GetGerberProtelExtension( LAYER_NUM aLayer )
+{
+ if( IsCopperLayer( aLayer ) )
+ {
+ if( aLayer == F_Cu )
+ return wxT( "gtl" );
+ else if( aLayer == B_Cu )
+ return wxT( "gbl" );
+ else
+ {
+ return wxString::Format( wxT( "g%d" ), aLayer+1 );
+ }
+ }
+ else
+ {
+ switch( aLayer )
+ {
+ case B_Adhes: return wxT( "gba" );
+ case F_Adhes: return wxT( "gta" );
+
+ case B_Paste: return wxT( "gbp" );
+ case F_Paste: return wxT( "gtp" );
+
+ case B_SilkS: return wxT( "gbo" );
+ case F_SilkS: return wxT( "gto" );
+
+ case B_Mask: return wxT( "gbs" );
+ case F_Mask: return wxT( "gts" );
+
+ case Edge_Cuts: return wxT( "gm1" );
+
+ case Dwgs_User:
+ case Cmts_User:
+ case Eco1_User:
+ case Eco2_User:
+ default: return wxT( "gbr" );
+ }
+ }
+}
+
+
+wxString GetGerberFileFunctionAttribute( const BOARD *aBoard,
+ LAYER_NUM aLayer, bool aUseX1CompatibilityMode )
+{
+ wxString attrib;
+
+ switch( aLayer )
+ {
+ case F_Adhes:
+ attrib = wxString( wxT( "Glue,Top" ) );
+ break;
+
+ case B_Adhes:
+ attrib = wxString( wxT( "Glue,Bot" ) );
+ break;
+
+ case F_SilkS:
+ attrib = wxString( wxT( "Legend,Top" ) );
+ break;
+
+ case B_SilkS:
+ attrib = wxString( wxT( "Legend,Bot" ) );
+ break;
+
+ case F_Mask:
+ attrib = wxString( wxT( "Soldermask,Top" ) );
+ break;
+
+ case B_Mask:
+ attrib = wxString( wxT( "Soldermask,Bot" ) );
+ break;
+
+ case F_Paste:
+ attrib = wxString( wxT( "Paste,Top" ) );
+ break;
+
+ case B_Paste:
+ attrib = wxString( wxT( "Paste,Bot" ) );
+ break;
+
+ case Edge_Cuts:
+ // Board outline.
+ // Can be "Profile,NP" (Not Plated: usual) or "Profile,P"
+ // This last is the exception (Plated)
+ attrib = wxString( wxT( "Profile,NP" ) );
+ break;
+
+ case Dwgs_User:
+ attrib = wxString( wxT( "Drawing" ) );
+ break;
+
+ case Cmts_User:
+ attrib = wxString( wxT( "Other,Comment" ) );
+ break;
+
+ case Eco1_User:
+ attrib = wxString( wxT( "Other,ECO1" ) );
+ break;
+
+ case Eco2_User:
+ attrib = wxString( wxT( "Other,ECO2" ) );
+ break;
+
+ case B_Fab:
+ attrib = wxString( wxT( "Other,Fab,Bot" ) );
+ break;
+
+ case F_Fab:
+ attrib = wxString( wxT( "Other,Fab,Top" ) );
+ break;
+
+ case B_Cu:
+ attrib = wxString::Format( wxT( "Copper,L%d,Bot" ), aBoard->GetCopperLayerCount() );
+ break;
+
+ case F_Cu:
+ attrib = wxString::Format( wxT( "Copper,L1,Top" ) );
+ break;
+
+ default:
+ if( IsCopperLayer( aLayer ) )
+ attrib = wxString::Format( wxT( "Copper,L%d,Inr" ), aLayer+1 );
+ else
+ attrib = wxString::Format( wxT( "Other,User" ), aLayer+1 );
+ break;
+ }
+
+ // Add the signal type of the layer, if relevant
+ if( IsCopperLayer( aLayer ) )
+ {
+ LAYER_T type = aBoard->GetLayerType( ToLAYER_ID( aLayer ) );
+
+ switch( type )
+ {
+ case LT_SIGNAL:
+ attrib += wxString( wxT( ",Signal" ) );
+ break;
+ case LT_POWER:
+ attrib += wxString( wxT( ",Plane" ) );
+ break;
+ case LT_MIXED:
+ attrib += wxString( wxT( ",Mixed" ) );
+ break;
+ default:
+ break; // do nothing (but avoid a warning for unhandled LAYER_T values from GCC)
+ }
+ }
+
+ wxString fileFct;
+
+ if( aUseX1CompatibilityMode )
+ fileFct.Printf( "G04 #@! TF.FileFunction,%s*", GetChars( attrib ) );
+ else
+ fileFct.Printf( "%%TF.FileFunction,%s*%%", GetChars( attrib ) );
+
+ return fileFct;
+}
+
+/* Add some X2 attributes to the file header, as defined in the
+ * Gerber file format specification J4 and "Revision 2015.06"
+ */
+#define USE_REVISION_2015_06_ATTR
+void AddGerberX2Attribute( PLOTTER * aPlotter,
+ const BOARD *aBoard, LAYER_NUM aLayer )
+{
+ wxString text;
+
+#ifdef USE_REVISION_2015_06_ATTR
+ // Creates the TF,.GenerationSoftware. Format is:
+ // %TF,.GenerationSoftware,<vendor>,<application name>[,<application version>]*%
+ text.Printf( wxT( "%%TF.GenerationSoftware,KiCad,Pcbnew,%s*%%" ), GetBuildVersion() );
+ aPlotter->AddLineToHeader( text );
+
+ // creates the TF.CreationDate ext:
+ // The attribute value must conform to the full version of the ISO 8601
+ // date and time format, including time and time zone. Note that this is
+ // the date the Gerber file was effectively created,
+ // not the time the project of PCB was started
+ wxDateTime date( wxDateTime::GetTimeNow() );
+ // Date format: see http://www.cplusplus.com/reference/ctime/strftime
+ wxString msg = date.Format( wxT( "%z" ) ); // Extract the time zone offset
+ // The time zone offset format is + (or -) mm or hhmm (mm = number of minutes, hh = number of hours)
+ // we want +(or -) hh:mm
+ if( msg.Len() > 3 )
+ msg.insert( 3, ":", 1 ),
+ text.Printf( wxT( "%%TF.CreationDate,%s%s*%%" ), GetChars( date.FormatISOCombined() ), GetChars( msg ) );
+ aPlotter->AddLineToHeader( text );
+
+ // Creates the TF,.ProjectId. Format is (from Gerber file format doc):
+ // %TF.ProjectId,<project id>,<project GUID>,<revision id>*%
+ // <project id> is the name of the project, restricted to basic ASCII symbols only,
+ // and comma not accepted
+ // All illegal chars will be replaced by underscore
+ // <project GUID> is a 32 hexadecimal digits string which is an unique id of a project.
+ // This is a random 128-bit number expressed in 32 hexadecimal digits.
+ // See en.wikipedia.org/wiki/GUID for more information
+ // However Kicad does not handle such a project GUID, so it is built from the board name
+ // Rem: <project id> accepts only ASCII 7 code (only basic ASCII codes are allowed in gerber files).
+ wxFileName fn = aBoard->GetFileName();
+ msg = fn.GetFullName();
+ wxString guid;
+
+ // Build a 32 digits GUID from the board name:
+ for( unsigned ii = 0; ii < msg.Len(); ii++ )
+ {
+ int cc1 = int( msg[ii] ) & 0x0F;
+ int cc2 = ( int( msg[ii] ) >> 4) & 0x0F;
+ guid << wxString::Format( wxT( "%X%X" ), cc2, cc1 );
+
+ if( guid.Len() >= 32 )
+ break;
+ }
+
+ // guid has 32 digits, so add missing digits
+ int cnt = 32 - guid.Len();
+
+ if( cnt > 0 )
+ guid.Append( '0', cnt );
+
+ // build the <project id> string: this is the board short filename (without ext)
+ // and all non ASCII chars and comma are replaced by '_'
+ msg = fn.GetName();
+ msg.Replace( wxT( "," ), wxT( "_" ) );
+
+ // build the <rec> string. All non ASCII chars and comma are replaced by '_'
+ wxString rev = ((BOARD*)aBoard)->GetTitleBlock().GetRevision();
+ rev.Replace( wxT( "," ), wxT( "_" ) );
+
+ if( rev.IsEmpty() )
+ rev = wxT( "rev?" );
+
+ text.Printf( wxT( "%%TF.ProjectId,%s,%s,%s*%%" ), msg.ToAscii(), GetChars( guid ), rev.ToAscii() );
+ aPlotter->AddLineToHeader( text );
+#endif
+
+ // Add the TF.FileFunction
+ text = GetGerberFileFunctionAttribute( aBoard, aLayer, false );
+ aPlotter->AddLineToHeader( text );
+}
+
+
+void BuildPlotFileName( wxFileName* aFilename, const wxString& aOutputDir,
+ const wxString& aSuffix, const wxString& aExtension )
+{
+ // aFilename contains the base filename only (without path and extension)
+ // when calling this function.
+ // It is expected to be a valid filename (this is usually the board filename)
+ aFilename->SetPath( aOutputDir );
+
+ // Set the file extension
+ aFilename->SetExt( aExtension );
+
+ // remove leading and trailing spaces if any from the suffix, if
+ // something survives add it to the name;
+ // also the suffix can contain some not allowed chars in filename (/ \ . :),
+ // so change them to underscore
+ // Remember it can be called from a python script, so the illegal chars
+ // have to be filtered here.
+ wxString suffix = aSuffix;
+ suffix.Trim( true );
+ suffix.Trim( false );
+
+ wxString badchars = wxFileName::GetForbiddenChars(wxPATH_DOS);
+ badchars.Append( '%' );
+
+ for( unsigned ii = 0; ii < badchars.Len(); ii++ )
+ suffix.Replace( badchars[ii], wxT("_") );
+
+ if( !suffix.IsEmpty() )
+ aFilename->SetName( aFilename->GetName() + wxT( "-" ) + suffix );
+}
+
+
+PLOT_CONTROLLER::PLOT_CONTROLLER( BOARD *aBoard )
+{
+ m_plotter = NULL;
+ m_board = aBoard;
+ m_plotLayer = UNDEFINED_LAYER;
+}
+
+
+PLOT_CONTROLLER::~PLOT_CONTROLLER()
+{
+ ClosePlot();
+}
+
+
+/* IMPORTANT THING TO KNOW: the locale during plots *MUST* be kept as
+ * C/POSIX using a LOCALE_IO object on the stack. This even when
+ * opening/closing the plotfile, since some drivers do I/O even then */
+
+void PLOT_CONTROLLER::ClosePlot()
+{
+ LOCALE_IO toggle;
+
+ if( m_plotter )
+ {
+ m_plotter->EndPlot();
+ delete m_plotter;
+ m_plotter = NULL;
+ }
+}
+
+
+bool PLOT_CONTROLLER::OpenPlotfile( const wxString &aSuffix,
+ PlotFormat aFormat,
+ const wxString &aSheetDesc )
+{
+ LOCALE_IO toggle;
+
+ /* Save the current format: sadly some plot routines depends on this
+ but the main reason is that the StartPlot method uses it to
+ dispatch the plotter creation */
+ GetPlotOptions().SetFormat( aFormat );
+
+ // Ensure that the previous plot is closed
+ ClosePlot();
+
+ // Now compute the full filename for the output and start the plot
+ // (after ensuring the output directory is OK)
+ wxString outputDirName = GetPlotOptions().GetOutputDirectory() ;
+ wxFileName outputDir = wxFileName::DirName( outputDirName );
+ wxString boardFilename = m_board->GetFileName();
+
+ if( EnsureFileDirectoryExists( &outputDir, boardFilename ) )
+ {
+ // outputDir contains now the full path of plot files
+ m_plotFile = boardFilename;
+ m_plotFile.SetPath( outputDir.GetPath() );
+ wxString fileExt = GetDefaultPlotExtension( aFormat );
+
+ // Gerber format can use specific file ext, depending on layers
+ // (now not a good practice, because the official file ext is .gbr)
+ if( GetPlotOptions().GetFormat() == PLOT_FORMAT_GERBER &&
+ GetPlotOptions().GetUseGerberProtelExtensions() )
+ fileExt = GetGerberProtelExtension( GetLayer() );
+
+ // Build plot filenames from the board name and layer names:
+ BuildPlotFileName( &m_plotFile, outputDir.GetPath(), aSuffix, fileExt );
+
+ m_plotter = StartPlotBoard( m_board, &GetPlotOptions(), ToLAYER_ID( GetLayer() ),
+ m_plotFile.GetFullPath(), aSheetDesc );
+ }
+
+ return( m_plotter != NULL );
+}
+
+
+bool PLOT_CONTROLLER::PlotLayer()
+{
+ LOCALE_IO toggle;
+
+ // No plot open, nothing to do...
+ if( !m_plotter )
+ return false;
+
+ // Fully delegated to the parent
+ PlotOneBoardLayer( m_board, m_plotter, ToLAYER_ID( GetLayer() ), GetPlotOptions() );
+
+ return true;
+}
+
+
+void PLOT_CONTROLLER::SetColorMode( bool aColorMode )
+{
+ if( !m_plotter )
+ return;
+
+ m_plotter->SetColorMode( aColorMode );
+}
+
+
+bool PLOT_CONTROLLER::GetColorMode()
+{
+ if( !m_plotter )
+ return false;
+
+ return m_plotter->GetColorMode();
+}
diff --git a/pcbnew/pcbplot.h b/pcbnew/pcbplot.h
new file mode 100644
index 0000000..1570ac2
--- /dev/null
+++ b/pcbnew/pcbplot.h
@@ -0,0 +1,281 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/pcbplot.h
+ * @brief Board plot function definition file.
+ */
+
+#ifndef PCBPLOT_H_
+#define PCBPLOT_H_
+
+#include <wx/filename.h>
+#include <pad_shapes.h>
+#include <pcb_plot_params.h>
+#include <layers_id_colors_and_visibility.h>
+
+class PLOTTER;
+class TEXTE_PCB;
+class DRAWSEGMENT;
+class DIMENSION;
+class MODULE;
+class EDGE_MODULE;
+class PCB_TARGET;
+class TEXTE_MODULE;
+class ZONE_CONTAINER;
+class BOARD;
+class REPORTER;
+
+// Shared Config keys for plot and print
+#define OPTKEY_LAYERBASE wxT( "PlotLayer_%d" )
+#define OPTKEY_PRINT_X_FINESCALE_ADJ wxT( "PrintXFineScaleAdj" )
+#define OPTKEY_PRINT_Y_FINESCALE_ADJ wxT( "PrintYFineScaleAdj" )
+#define OPTKEY_PRINT_SCALE wxT( "PrintScale" )
+#define OPTKEY_PRINT_MODULE_SCALE wxT( "PrintModuleScale" )
+#define OPTKEY_PRINT_PAGE_FRAME wxT( "PrintPageFrame" )
+#define OPTKEY_PRINT_MONOCHROME_MODE wxT( "PrintMonochrome" )
+#define OPTKEY_PRINT_PAGE_PER_LAYER wxT( "PrintSinglePage" )
+#define OPTKEY_PRINT_PADS_DRILL wxT( "PrintPadsDrillOpt" )
+#define OPTKEY_PLOT_X_FINESCALE_ADJ wxT( "PlotXFineScaleAdj" )
+#define OPTKEY_PLOT_Y_FINESCALE_ADJ wxT( "PlotYFineScaleAdj" )
+#define CONFIG_PS_FINEWIDTH_ADJ wxT( "PSPlotFineWidthAdj" )
+
+// Define min and max reasonable values for plot/print scale
+#define PLOT_MIN_SCALE 0.01
+#define PLOT_MAX_SCALE 100.0
+
+// Small drill marks (small pad holes) diameter value
+#define SMALL_DRILL KiROUND( 0.35 * IU_PER_MM )
+
+
+// A helper class to plot board items
+class BRDITEMS_PLOTTER : public PCB_PLOT_PARAMS
+{
+ PLOTTER* m_plotter;
+ BOARD* m_board;
+ LSET m_layerMask;
+
+public:
+ BRDITEMS_PLOTTER( PLOTTER* aPlotter, BOARD* aBoard, const PCB_PLOT_PARAMS& aPlotOpts ) :
+ PCB_PLOT_PARAMS( aPlotOpts )
+ {
+ m_plotter = aPlotter;
+ m_board = aBoard;
+ }
+
+ /**
+ * @return a 'width adjustment' for the postscript engine
+ * (useful for controlling toner bleeding during direct transfer)
+ * added to track width and via/pads size
+ */
+ int getFineWidthAdj()
+ {
+ if( GetFormat() == PLOT_FORMAT_POST )
+ return GetWidthAdjust();
+ else
+ return 0;
+ }
+
+ // Basic functions to plot a board item
+ void SetLayerSet( LSET aLayerMask ) { m_layerMask = aLayerMask; }
+ void Plot_Edges_Modules();
+ void Plot_1_EdgeModule( EDGE_MODULE* aEdge );
+ void PlotTextModule( TEXTE_MODULE* aTextMod, EDA_COLOR_T aColor );
+
+ /*
+ * Plot field of a module (footprint)
+ * Reference, Value, and other fields are plotted only if
+ * the corresponding option is enabled
+ * Invisible text fields are plotted only if PlotInvisibleText option is set
+ * usually they are not plotted.
+ */
+ bool PlotAllTextsModule( MODULE* aModule );
+
+ void PlotDimension( DIMENSION* Dimension );
+ void PlotPcbTarget( PCB_TARGET* PtMire );
+ void PlotFilledAreas( ZONE_CONTAINER* aZone );
+ void PlotTextePcb( TEXTE_PCB* pt_texte );
+ void PlotDrawSegment( DRAWSEGMENT* PtSegm );
+
+ /**
+ * Plot a pad.
+ * unlike other items, a pad had not a specific color,
+ * and be drawn as a non filled item although the plot mode is filled
+ * color and plot mode are needed by this function
+ */
+ void PlotPad( D_PAD* aPad, EDA_COLOR_T aColor, EDA_DRAW_MODE_T aPlotMode );
+
+ /**
+ * plot items like text and graphics,
+ * but not tracks and modules
+ */
+ void PlotBoardGraphicItems();
+
+ /** Function PlotDrillMarks
+ * Draw a drill mark for pads and vias.
+ * Must be called after all drawings, because it
+ * redraw the drill mark on a pad or via, as a negative (i.e. white) shape in
+ * FILLED plot mode (for PS and PDF outputs)
+ */
+ void PlotDrillMarks();
+
+ /**
+ * Function getColor
+ * @return the layer color
+ * @param aLayer = the layer id
+ * White color is special: cannot be seen on a white paper
+ * and in B&W mode, is plotted as white but other colors are plotted in BLACK
+ * so the returned color is LIGHTGRAY when the layer color is WHITE
+ */
+ EDA_COLOR_T getColor( LAYER_NUM aLayer );
+
+private:
+ /** Helper function to plot a single drill mark. It compensate and clamp
+ * the drill mark size depending on the current plot options
+ */
+ void plotOneDrillMark( PAD_DRILL_SHAPE_T aDrillShape,
+ const wxPoint& aDrillPos, wxSize aDrillSize,
+ const wxSize& aPadSize,
+ double aOrientation, int aSmallDrill );
+
+};
+
+PLOTTER* StartPlotBoard( BOARD* aBoard,
+ PCB_PLOT_PARAMS* aPlotOpts,
+ int aLayer,
+ const wxString& aFullFileName,
+ const wxString& aSheetDesc );
+
+/**
+ * Function PlotOneBoardLayer
+ * main function to plot one copper or technical layer.
+ * It prepare options and calls the specialized plot function,
+ * according to the layer type
+ * @param aBoard = the board to plot
+ * @param aPlotter = the plotter to use
+ * @param aLayer = the layer id to plot
+ * @param aPlotOpt = the plot options (files, sketch). Has meaning for some formats only
+ */
+void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, LAYER_ID aLayer,
+ const PCB_PLOT_PARAMS& aPlotOpt );
+
+/**
+ * Function PlotStandardLayer
+ * plot copper or technical layers.
+ * not used for silk screen layers, because these layers have specific
+ * requirements, mainly for pads
+ * @param aBoard = the board to plot
+ * @param aPlotter = the plotter to use
+ * @param aLayerMask = the mask to define the layers to plot
+ * @param aPlotOpt = the plot options (files, sketch). Has meaning for some formats only
+ *
+ * aPlotOpt has 3 important options to control this plot,
+ * which are set, depending on the layer type to plot
+ * SetEnablePlotVia( bool aEnable )
+ * aEnable = true to plot vias, false to skip vias (has meaning
+ * only for solder mask layers).
+ * SetSkipPlotNPTH_Pads( bool aSkip )
+ * aSkip = true to skip NPTH Pads, when the pad size and the pad hole
+ * have the same size. Used in GERBER format only.
+ * SetDrillMarksType( DrillMarksType aVal ) controle the actual hole:
+ * no hole, small hole, actual hole
+ */
+void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
+ const PCB_PLOT_PARAMS& aPlotOpt );
+
+/**
+ * Function PlotLayerOutlines
+ * plot copper outline of a copper layer.
+ * @param aBoard = the board to plot
+ * @param aPlotter = the plotter to use
+ * @param aLayerMask = the mask to define the layers to plot
+ * @param aPlotOpt = the plot options. Has meaning for some formats only
+ */
+void PlotLayerOutlines( BOARD *aBoard, PLOTTER* aPlotter,
+ LSET aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt );
+
+/**
+ * Function PlotSilkScreen
+ * plot silkscreen layers which have specific requirements, mainly for pads.
+ * Should not be used for other layers
+ * @param aBoard = the board to plot
+ * @param aPlotter = the plotter to use
+ * @param aLayerMask = the mask to define the layers to plot (silkscreen Front and/or Back)
+ * @param aPlotOpt = the plot options (files, sketch). Has meaning for some formats only
+ */
+void PlotSilkScreen( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
+ const PCB_PLOT_PARAMS& aPlotOpt );
+
+
+/**
+ * Function BuildPlotFileName (helper function)
+ * Complete a plot filename: forces the output directory,
+ * add a suffix to the name and sets the specified extension
+ * the suffix is usually the layer name
+ * replaces not allowed chars in suffix by '_'
+ * @param aFilename = the wxFileName to initialize
+ * Contains the base filename
+ * @param aOutputDir = the path
+ * @param aSuffix = the suffix to add to the base filename
+ * @param aExtension = the file extension
+ */
+void BuildPlotFileName( wxFileName* aFilename,
+ const wxString& aOutputDir,
+ const wxString& aSuffix,
+ const wxString& aExtension );
+
+
+/**
+ * Function GetGerberProtelExtension
+ * @return the appropriate Gerber file extension for \a aLayer
+ * used by Protel, and still sometimes in use (although the
+ * official Gerber Ext is now .gbr)
+ */
+const wxString GetGerberProtelExtension( LAYER_NUM aLayer );
+
+/**
+ * Function GetGerberFileFunctionAttribute
+ * Returns the "file function" attribute for \a aLayer, as defined in the
+ * Gerber file format specification J1 (chapter 5). The returned string includes
+ * the "%TF.FileFunction" attribute prefix and the "*%" suffix.
+ * @param aBoard = the board, needed to get the total count of copper layers
+ * @param aLayer = the layer number to create the attribute for
+ * @param aUseX1CompatibilityMode = true to use a file function attribute like G04 comment
+ * , compatible with X1 (rx274) notation (G04#@!TF.FileFunction)
+ * @return The attribute, as a text string
+ */
+extern wxString GetGerberFileFunctionAttribute( const BOARD *aBoard,
+ LAYER_NUM aLayer, bool aUseX1CompatibilityMode );
+
+/**
+ * Function AddGerberX2Attribute
+ * Calculates some X2 attributes, as defined in the
+ * Gerber file format specification J4 (chapter 5) and add them
+ * the to the gerber file header
+ * @param aPlotter, the current plotter.
+ * @param aBoard = the board, needed to extract some info
+ * @param aLayer = the layer number to create the attribute for
+ */
+extern void AddGerberX2Attribute( PLOTTER * aPlotter, const BOARD *aBoard, LAYER_NUM aLayer );
+
+#endif // PCBPLOT_H_
diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp
new file mode 100644
index 0000000..34c08fd
--- /dev/null
+++ b/pcbnew/plot_board_layers.cpp
@@ -0,0 +1,1040 @@
+/**
+ * @file plot_board_layers.cpp
+ * @brief Functions to plot one board layer (silkscreen layers or other layers).
+ * Silkscreen layers have specific requirement for pads (not filled) and texts
+ * (with option to remove them from some copper areas (pads...)
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <common.h>
+#include <plot_common.h>
+#include <base_struct.h>
+#include <drawtxt.h>
+#include <trigo.h>
+#include <wxBasePcbFrame.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_edge_mod.h>
+#include <class_pcb_text.h>
+#include <class_zone.h>
+#include <class_drawsegment.h>
+#include <class_mire.h>
+#include <class_dimension.h>
+
+#include <pcbnew.h>
+#include <pcbplot.h>
+
+// Local
+/* Plot a solder mask layer.
+ * Solder mask layers have a minimum thickness value and cannot be drawn like standard layers,
+ * unless the minimum thickness is 0.
+ */
+static void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
+ LSET aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt,
+ int aMinThickness );
+
+/* Creates the plot for silkscreen layers
+ * Silkscreen layers have specific requirement for pads (not filled) and texts
+ * (with option to remove them from some copper areas (pads...)
+ */
+void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
+ const PCB_PLOT_PARAMS& aPlotOpt )
+{
+ BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
+ itemplotter.SetLayerSet( aLayerMask );
+
+ // Plot edge layer and graphic items
+ itemplotter.PlotBoardGraphicItems();
+
+ // Plot footprint outlines :
+ itemplotter.Plot_Edges_Modules();
+
+ // Plot pads (creates pads outlines, for pads on silkscreen layers)
+ LSET layersmask_plotpads = aLayerMask;
+
+ // Calculate the mask layers of allowed layers for pads
+
+ if( !aPlotOpt.GetPlotPadsOnSilkLayer() ) // Do not plot pads on silk screen layers
+ layersmask_plotpads.set( B_SilkS, false ).set( F_SilkS, false );
+
+ if( layersmask_plotpads.any() )
+ {
+ for( MODULE* Module = aBoard->m_Modules; Module; Module = Module->Next() )
+ {
+ for( D_PAD * pad = Module->Pads(); pad; pad = pad->Next() )
+ {
+ // See if the pad is on this layer
+ LSET masklayer = pad->GetLayerSet();
+ if( !( masklayer & layersmask_plotpads ).any() )
+ continue;
+
+ EDA_COLOR_T color = ColorFromInt( 0 );
+
+ if( layersmask_plotpads[B_SilkS] )
+ color = aBoard->GetLayerColor( B_SilkS );
+
+ if( layersmask_plotpads[F_SilkS] )
+ color = ColorFromInt( color | aBoard->GetLayerColor( F_SilkS ) );
+
+ itemplotter.PlotPad( pad, color, SKETCH );
+ }
+ }
+ }
+
+ // Plot footprints fields (ref, value ...)
+ for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
+ {
+ if( ! itemplotter.PlotAllTextsModule( module ) )
+ {
+ wxLogMessage( _( "Your BOARD has a bad layer number for footprint %s" ),
+ GetChars( module->GetReference() ) );
+ }
+ }
+
+ // Plot filled areas
+ for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* edge_zone = aBoard->GetArea( ii );
+
+ if( !aLayerMask[ edge_zone->GetLayer() ] )
+ continue;
+
+ itemplotter.PlotFilledAreas( edge_zone );
+ }
+
+ // Plot segments used to fill zone areas (outdated, but here for old boards
+ // compatibility):
+ for( SEGZONE* seg = aBoard->m_Zone; seg; seg = seg->Next() )
+ {
+ if( !aLayerMask[ seg->GetLayer() ] )
+ continue;
+
+ aPlotter->ThickSegment( seg->GetStart(), seg->GetEnd(), seg->GetWidth(),
+ itemplotter.GetPlotMode() );
+ }
+}
+
+void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, LAYER_ID aLayer,
+ const PCB_PLOT_PARAMS& aPlotOpt )
+{
+ PCB_PLOT_PARAMS plotOpt = aPlotOpt;
+ int soldermask_min_thickness = aBoard->GetDesignSettings().m_SolderMaskMinWidth;
+
+ // Set a default color and the text mode for this layer
+ aPlotter->SetColor( aPlotOpt.GetColor() );
+ aPlotter->SetTextMode( aPlotOpt.GetTextMode() );
+
+ // Specify that the contents of the "Edges Pcb" layer are to be plotted
+ // in addition to the contents of the currently specified layer.
+ LSET layer_mask( aLayer );
+
+ if( !aPlotOpt.GetExcludeEdgeLayer() )
+ layer_mask.set( Edge_Cuts );
+
+ if( IsCopperLayer( aLayer ) )
+ {
+ // Skip NPTH pads on copper layers ( only if hole size == pad size ):
+ // Drill mark will be plotted,
+ // if drill mark is SMALL_DRILL_SHAPE or FULL_DRILL_SHAPE
+ if( plotOpt.GetFormat() == PLOT_FORMAT_DXF )
+ {
+ plotOpt.SetSkipPlotNPTH_Pads( false );
+ PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
+ }
+ else
+ {
+ plotOpt.SetSkipPlotNPTH_Pads( true );
+ PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
+ }
+ }
+ else
+ {
+ switch( aLayer )
+ {
+ case B_Mask:
+ case F_Mask:
+ plotOpt.SetSkipPlotNPTH_Pads( false );
+ // Disable plot pad holes
+ plotOpt.SetDrillMarksType( PCB_PLOT_PARAMS::NO_DRILL_SHAPE );
+
+ // Plot solder mask:
+ if( soldermask_min_thickness == 0 )
+ {
+ if( plotOpt.GetFormat() == PLOT_FORMAT_DXF )
+ PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
+ else
+ PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
+ }
+ else
+ PlotSolderMaskLayer( aBoard, aPlotter, layer_mask, plotOpt,
+ soldermask_min_thickness );
+
+ break;
+
+ case B_Adhes:
+ case F_Adhes:
+ case B_Paste:
+ case F_Paste:
+ plotOpt.SetSkipPlotNPTH_Pads( false );
+ // Disable plot pad holes
+ plotOpt.SetDrillMarksType( PCB_PLOT_PARAMS::NO_DRILL_SHAPE );
+
+ if( plotOpt.GetFormat() == PLOT_FORMAT_DXF )
+ PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
+ else
+ PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
+ break;
+
+ case F_SilkS:
+ case B_SilkS:
+ if( plotOpt.GetFormat() == PLOT_FORMAT_DXF && plotOpt.GetDXFPlotPolygonMode() )
+ // PlotLayerOutlines() is designed only for DXF plotters.
+ // and must not be used for other plot formats
+ PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
+ else
+ PlotSilkScreen( aBoard, aPlotter, layer_mask, plotOpt );
+
+ // Gerber: Subtract soldermask from silkscreen if enabled
+ if( aPlotter->GetPlotterType() == PLOT_FORMAT_GERBER
+ && plotOpt.GetSubtractMaskFromSilk() )
+ {
+ if( aLayer == F_SilkS )
+ layer_mask = LSET( F_Mask );
+ else
+ layer_mask = LSET( B_Mask );
+
+ // Create the mask to subtract by creating a negative layer polarity
+ aPlotter->SetLayerPolarity( false );
+
+ // Disable plot pad holes
+ plotOpt.SetDrillMarksType( PCB_PLOT_PARAMS::NO_DRILL_SHAPE );
+
+ // Plot the mask
+ PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
+ }
+ break;
+
+ // These layers are plotted like silk screen layers.
+ // Mainly, pads on these layers are not filled.
+ // This is not necessary the best choice.
+ case Dwgs_User:
+ case Cmts_User:
+ case Eco1_User:
+ case Eco2_User:
+ case Edge_Cuts:
+ case Margin:
+ case F_CrtYd:
+ case B_CrtYd:
+ case F_Fab:
+ case B_Fab:
+ plotOpt.SetSkipPlotNPTH_Pads( false );
+ plotOpt.SetDrillMarksType( PCB_PLOT_PARAMS::NO_DRILL_SHAPE );
+
+ if ( plotOpt.GetFormat() == PLOT_FORMAT_DXF && plotOpt.GetDXFPlotPolygonMode() )
+ // PlotLayerOutlines() is designed only for DXF plotters.
+ // and must not be used for other plot formats
+ PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
+ else
+ PlotSilkScreen( aBoard, aPlotter, layer_mask, plotOpt );
+ break;
+
+ default:
+ plotOpt.SetSkipPlotNPTH_Pads( false );
+ plotOpt.SetDrillMarksType( PCB_PLOT_PARAMS::NO_DRILL_SHAPE );
+
+ if ( plotOpt.GetFormat() == PLOT_FORMAT_DXF && plotOpt.GetDXFPlotPolygonMode() )
+ // PlotLayerOutlines() is designed only for DXF plotters.
+ // and must not be used for other plot formats
+ PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
+ else
+ PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
+ break;
+ }
+ }
+}
+
+
+/* Plot a copper layer or mask.
+ * Silk screen layers are not plotted here.
+ */
+void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
+ LSET aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt )
+{
+ BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
+
+ itemplotter.SetLayerSet( aLayerMask );
+
+ EDA_DRAW_MODE_T plotMode = aPlotOpt.GetPlotMode();
+
+ // Plot edge layer and graphic items
+ itemplotter.PlotBoardGraphicItems();
+
+ // Draw footprint shapes without pads (pads will plotted later)
+ // We plot here module texts, but they are usually on silkscreen layer,
+ // so they are not plot here but plot by PlotSilkScreen()
+ // Plot footprints fields (ref, value ...)
+ for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
+ {
+ if( ! itemplotter.PlotAllTextsModule( module ) )
+ {
+ wxLogMessage( _( "Your BOARD has a bad layer number for footprint %s" ),
+ GetChars( module->GetReference() ) );
+ }
+ }
+
+ for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
+ {
+ for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item->Next() )
+ {
+ if( !aLayerMask[ item->GetLayer() ] )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_EDGE_T:
+ itemplotter.Plot_1_EdgeModule( (EDGE_MODULE*) item );
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ // Plot footprint pads
+ for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ if( (pad->GetLayerSet() & aLayerMask) == 0 )
+ continue;
+
+ wxSize margin;
+ double width_adj = 0;
+
+ if( ( aLayerMask & LSET::AllCuMask() ).any() )
+ width_adj = itemplotter.getFineWidthAdj();
+
+ static const LSET speed( 4, B_Mask, F_Mask, B_Paste, F_Paste );
+
+ LSET anded = ( speed & aLayerMask );
+
+ if( anded == LSET( F_Mask ) || anded == LSET( B_Mask ) )
+ {
+ margin.x = margin.y = pad->GetSolderMaskMargin();
+ }
+ else if( anded == LSET( F_Paste ) || anded == LSET( B_Paste ) )
+ {
+ margin = pad->GetSolderPasteMargin();
+ }
+
+ wxSize padPlotsSize;
+ padPlotsSize.x = pad->GetSize().x + ( 2 * margin.x ) + width_adj;
+ padPlotsSize.y = pad->GetSize().y + ( 2 * margin.y ) + width_adj;
+
+ // Don't draw a null size item :
+ if( padPlotsSize.x <= 0 || padPlotsSize.y <= 0 )
+ continue;
+
+ EDA_COLOR_T color = BLACK;
+
+ if( pad->GetLayerSet()[B_Cu] )
+ color = aBoard->GetVisibleElementColor( PAD_BK_VISIBLE );
+
+ if( pad->GetLayerSet()[F_Cu] )
+ color = ColorFromInt( color | aBoard->GetVisibleElementColor( PAD_FR_VISIBLE ) );
+
+ // Temporary set the pad size to the required plot size:
+ wxSize tmppadsize = pad->GetSize();
+ pad->SetSize( padPlotsSize );
+ switch( pad->GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+ case PAD_SHAPE_OVAL:
+ if( aPlotOpt.GetSkipPlotNPTH_Pads() &&
+ (pad->GetSize() == pad->GetDrillSize()) &&
+ (pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED) )
+ break;
+
+ // Fall through:
+ case PAD_SHAPE_TRAPEZOID:
+ case PAD_SHAPE_RECT:
+ default:
+ itemplotter.PlotPad( pad, color, plotMode );
+ break;
+ }
+
+ pad->SetSize( tmppadsize ); // Restore the pad size
+ }
+ }
+
+ // Plot vias on copper layers, and if aPlotOpt.GetPlotViaOnMaskLayer() is true,
+ // plot them on solder mask
+ for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
+ {
+ const VIA* Via = dyn_cast<const VIA*>( track );
+
+ if( !Via )
+ continue;
+
+ // vias are not plotted if not on selected layer, but if layer
+ // is SOLDERMASK_LAYER_BACK or SOLDERMASK_LAYER_FRONT,vias are drawn,
+ // only if they are on the corresponding external copper layer
+ LSET via_mask_layer = Via->GetLayerSet();
+
+ if( aPlotOpt.GetPlotViaOnMaskLayer() )
+ {
+ if( via_mask_layer[B_Cu] )
+ via_mask_layer.set( B_Mask );
+
+ if( via_mask_layer[F_Cu] )
+ via_mask_layer.set( F_Mask );
+ }
+
+ if( !( via_mask_layer & aLayerMask ).any() )
+ continue;
+
+ int via_margin = 0;
+ double width_adj = 0;
+
+ // If the current layer is a solder mask, use the global mask
+ // clearance for vias
+ if( aLayerMask[B_Mask] || aLayerMask[F_Mask] )
+ via_margin = aBoard->GetDesignSettings().m_SolderMaskMargin;
+
+ if( ( aLayerMask & LSET::AllCuMask() ).any() )
+ width_adj = itemplotter.getFineWidthAdj();
+
+ int diameter = Via->GetWidth() + 2 * via_margin + width_adj;
+
+ // Don't draw a null size item :
+ if( diameter <= 0 )
+ continue;
+
+ EDA_COLOR_T color = aBoard->GetVisibleElementColor(VIAS_VISIBLE + Via->GetViaType());
+ // Set plot color (change WHITE to LIGHTGRAY because
+ // the white items are not seen on a white paper or screen
+ aPlotter->SetColor( color != WHITE ? color : LIGHTGRAY);
+ aPlotter->FlashPadCircle( Via->GetStart(), diameter, plotMode );
+ }
+
+ // Plot tracks (not vias) :
+ for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
+ {
+ if( track->Type() == PCB_VIA_T )
+ continue;
+
+ if( !aLayerMask[track->GetLayer()] )
+ continue;
+
+ int width = track->GetWidth() + itemplotter.getFineWidthAdj();
+ aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) );
+ aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode );
+ }
+
+ // Plot zones (outdated, for old boards compatibility):
+ for( TRACK* track = aBoard->m_Zone; track; track = track->Next() )
+ {
+ if( !aLayerMask[track->GetLayer()] )
+ continue;
+
+ int width = track->GetWidth() + itemplotter.getFineWidthAdj();
+ aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) );
+ aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode );
+ }
+
+ // Plot filled ares
+ for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* zone = aBoard->GetArea( ii );
+
+ if( !aLayerMask[zone->GetLayer()] )
+ continue;
+
+ itemplotter.PlotFilledAreas( zone );
+ }
+
+ // Adding drill marks, if required and if the plotter is able to plot them:
+ if( aPlotOpt.GetDrillMarksType() != PCB_PLOT_PARAMS::NO_DRILL_SHAPE )
+ itemplotter.PlotDrillMarks();
+}
+
+
+// Seems like we want to plot from back to front?
+static const LAYER_ID plot_seq[] = {
+
+ B_Adhes, // 32
+ F_Adhes,
+ B_Paste,
+ F_Paste,
+ B_SilkS,
+ B_Mask,
+ F_Mask,
+ Dwgs_User,
+ Cmts_User,
+ Eco1_User,
+ Eco2_User,
+ Edge_Cuts,
+ Margin,
+
+ F_CrtYd, // CrtYd & Body are footprint only
+ B_CrtYd,
+ F_Fab,
+ B_Fab,
+
+ B_Cu,
+ In30_Cu,
+ In29_Cu,
+ In28_Cu,
+ In27_Cu,
+ In26_Cu,
+ In25_Cu,
+ In24_Cu,
+ In23_Cu,
+ In22_Cu,
+ In21_Cu,
+ In20_Cu,
+ In19_Cu,
+ In18_Cu,
+ In17_Cu,
+ In16_Cu,
+ In15_Cu,
+ In14_Cu,
+ In13_Cu,
+ In12_Cu,
+ In11_Cu,
+ In10_Cu,
+ In9_Cu,
+ In8_Cu,
+ In7_Cu,
+ In6_Cu,
+ In5_Cu,
+ In4_Cu,
+ In3_Cu,
+ In2_Cu,
+ In1_Cu,
+ F_Cu,
+
+ F_SilkS,
+};
+
+
+/* Plot outlines of copper, for copper layer
+ */
+void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter,
+ LSET aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt )
+{
+
+ BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
+ itemplotter.SetLayerSet( aLayerMask );
+
+ SHAPE_POLY_SET outlines;
+
+ for( LSEQ seq = aLayerMask.Seq( plot_seq, DIM( plot_seq ) ); seq; ++seq )
+ {
+ LAYER_ID layer = *seq;
+
+ outlines.RemoveAllContours();
+ aBoard->ConvertBrdLayerToPolygonalContours( layer, outlines );
+
+ outlines.Simplify();
+
+ // Plot outlines
+ std::vector< wxPoint > cornerList;
+
+ // Now we have one or more basic polygons: plot each polygon
+ for( int ii = 0; ii < outlines.OutlineCount(); ii++ )
+ {
+ for(int kk = 0; kk <= outlines.HoleCount (ii); kk++ )
+ {
+ cornerList.clear();
+ const SHAPE_LINE_CHAIN& path = (kk == 0) ? outlines.COutline( ii ) : outlines.CHole( ii, kk - 1 );
+
+ for( int jj = 0; jj < path.PointCount(); jj++ )
+ cornerList.push_back( wxPoint( path.CPoint( jj ).x , path.CPoint( jj ).y ) );
+
+
+ // Ensure the polygon is closed
+ if( cornerList[0] != cornerList[cornerList.size() - 1] )
+ cornerList.push_back( cornerList[0] );
+
+ aPlotter->PlotPoly( cornerList, NO_FILL );
+ }
+ }
+
+ // Plot pad holes
+ if( aPlotOpt.GetDrillMarksType() != PCB_PLOT_PARAMS::NO_DRILL_SHAPE )
+ {
+ for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ wxSize hole = pad->GetDrillSize();
+
+ if( hole.x == 0 || hole.y == 0 )
+ continue;
+
+ if( hole.x == hole.y )
+ aPlotter->Circle( pad->GetPosition(), hole.x, NO_FILL );
+ else
+ {
+ wxPoint drl_start, drl_end;
+ int width;
+ pad->GetOblongDrillGeometry( drl_start, drl_end, width );
+ aPlotter->ThickSegment( pad->GetPosition() + drl_start,
+ pad->GetPosition() + drl_end, width, SKETCH );
+ }
+ }
+ }
+ }
+
+ // Plot vias holes
+ for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
+ {
+ const VIA* via = dyn_cast<const VIA*>( track );
+
+ if( via && via->IsOnLayer( layer ) ) // via holes can be not through holes
+ {
+ aPlotter->Circle( via->GetPosition(), via->GetDrillValue(), NO_FILL );
+ }
+ }
+ }
+}
+
+
+/* Plot a solder mask layer.
+ * Solder mask layers have a minimum thickness value and cannot be drawn like standard layers,
+ * unless the minimum thickness is 0.
+ * Currently the algo is:
+ * 1 - build all pad shapes as polygons with a size inflated by
+ * mask clearance + (min width solder mask /2)
+ * 2 - Merge shapes
+ * 3 - deflate result by (min width solder mask /2)
+ * 4 - oring result by all pad shapes as polygons with a size inflated by
+ * mask clearance only (because deflate sometimes creates shape artifacts)
+ * 5 - draw result as polygons
+ *
+ * TODO:
+ * make this calculation only for shapes with clearance near than (min width solder mask)
+ * (using DRC algo)
+ * plot all other shapes by flashing the basing shape
+ * (shapes will be better, and calculations faster)
+ */
+void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
+ LSET aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt,
+ int aMinThickness )
+{
+ LAYER_ID layer = aLayerMask[B_Mask] ? B_Mask : F_Mask;
+ int inflate = aMinThickness/2;
+
+ BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
+ itemplotter.SetLayerSet( aLayerMask );
+
+ // Plot edge layer and graphic items
+ // They do not have a solder Mask margin, because they are only graphic items
+ // on this layer (like logos), not actually areas around pads.
+ itemplotter.PlotBoardGraphicItems();
+
+ for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
+ {
+ for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item->Next() )
+ {
+ if( layer != item->GetLayer() )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_EDGE_T:
+ itemplotter.Plot_1_EdgeModule( (EDGE_MODULE*) item );
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ // Build polygons for each pad shape.
+ // the size of the shape on solder mask should be:
+ // size of pad + clearance around the pad.
+ // clearance = solder mask clearance + extra margin
+ // extra margin is half the min width for solder mask
+ // This extra margin is used to merge too close shapes
+ // (distance < aMinThickness), and will be removed when creating
+ // the actual shapes
+ SHAPE_POLY_SET areas; // Contains shapes to plot
+ SHAPE_POLY_SET initialPolys; // Contains exact shapes to plot
+
+ /* calculates the coeff to compensate radius reduction of holes clearance
+ * due to the segment approx ( 1 /cos( PI/circleToSegmentsCount )
+ */
+ int circleToSegmentsCount = 32;
+ double correction = 1.0 / cos( M_PI / circleToSegmentsCount );
+
+ // Plot pads
+ for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
+ {
+ // add shapes with exact size
+ module->TransformPadsShapesWithClearanceToPolygon( layer,
+ initialPolys, 0,
+ circleToSegmentsCount, correction );
+ // add shapes inflated by aMinThickness/2
+ module->TransformPadsShapesWithClearanceToPolygon( layer,
+ areas, inflate,
+ circleToSegmentsCount, correction );
+ }
+
+ // Plot vias on solder masks, if aPlotOpt.GetPlotViaOnMaskLayer() is true,
+ if( aPlotOpt.GetPlotViaOnMaskLayer() )
+ {
+ // The current layer is a solder mask,
+ // use the global mask clearance for vias
+ int via_clearance = aBoard->GetDesignSettings().m_SolderMaskMargin;
+ int via_margin = via_clearance + inflate;
+
+ for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
+ {
+ const VIA* via = dyn_cast<const VIA*>( track );
+
+ if( !via )
+ continue;
+
+ // vias are plotted only if they are on the corresponding
+ // external copper layer
+ LSET via_set = via->GetLayerSet();
+
+ if( via_set[B_Cu] )
+ via_set.set( B_Mask );
+
+ if( via_set[F_Cu] )
+ via_set.set( F_Mask );
+
+ if( !( via_set & aLayerMask ).any() )
+ continue;
+
+ via->TransformShapeWithClearanceToPolygon( areas, via_margin,
+ circleToSegmentsCount,
+ correction );
+ via->TransformShapeWithClearanceToPolygon( initialPolys, via_clearance,
+ circleToSegmentsCount,
+ correction );
+ }
+ }
+
+ // Add filled zone areas.
+#if 0 // Set to 1 if a solder mask margin must be applied to zones on solder mask
+ int zone_margin = aBoard->GetDesignSettings().m_SolderMaskMargin;
+#else
+ int zone_margin = 0;
+#endif
+
+ for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* zone = aBoard->GetArea( ii );
+
+ if( zone->GetLayer() != layer )
+ continue;
+
+ zone->TransformOutlinesShapeWithClearanceToPolygon( areas,
+ inflate+zone_margin, false );
+ zone->TransformOutlinesShapeWithClearanceToPolygon( initialPolys,
+ zone_margin, false );
+ }
+
+ // To avoid a lot of code, use a ZONE_CONTAINER
+ // to handle and plot polygons, because our polygons look exactly like
+ // filled areas in zones
+ // Note, also this code is not optimized: it creates a lot of copy/duplicate data
+ // However it is not complex, and fast enough for plot purposes (copy/convert data
+ // is only a very small calculation time for these calculations)
+ ZONE_CONTAINER zone( aBoard );
+ zone.SetArcSegmentCount( 32 );
+ zone.SetMinThickness( 0 ); // trace polygons only
+ zone.SetLayer ( layer );
+
+ areas.BooleanAdd( initialPolys );
+ areas.Inflate( -inflate, circleToSegmentsCount );
+
+ // Combine the current areas to initial areas. This is mandatory because
+ // inflate/deflate transform is not perfect, and we want the initial areas perfectly kept
+ areas.BooleanAdd( initialPolys );
+ areas.Fracture();
+
+ zone.AddFilledPolysList( areas );
+
+ itemplotter.PlotFilledAreas( &zone );
+}
+
+
+
+/** Set up most plot options for plotting a board (especially the viewport)
+ * Important thing:
+ * page size is the 'drawing' page size,
+ * paper size is the physical page size
+ */
+static void initializePlotter( PLOTTER *aPlotter, BOARD * aBoard,
+ PCB_PLOT_PARAMS *aPlotOpts )
+{
+ PAGE_INFO pageA4( wxT( "A4" ) );
+ const PAGE_INFO& pageInfo = aBoard->GetPageSettings();
+ const PAGE_INFO* sheet_info;
+ double paperscale; // Page-to-paper ratio
+ wxSize paperSizeIU;
+ wxSize pageSizeIU( pageInfo.GetSizeIU() );
+ bool autocenter = false;
+
+ /* Special options: to fit the sheet to an A4 sheet replace
+ the paper size. However there is a difference between
+ the autoscale and the a4paper option:
+ - Autoscale fits the board to the paper size
+ - A4paper fits the original paper size to an A4 sheet
+ - Both of them fit the board to an A4 sheet
+ */
+ if( aPlotOpts->GetA4Output() ) // Fit paper to A4
+ {
+ sheet_info = &pageA4;
+ paperSizeIU = pageA4.GetSizeIU();
+ paperscale = (double) paperSizeIU.x / pageSizeIU.x;
+ autocenter = true;
+ }
+ else
+ {
+ sheet_info = &pageInfo;
+ paperSizeIU = pageSizeIU;
+ paperscale = 1;
+
+ // Need autocentering only if scale is not 1:1
+ autocenter = (aPlotOpts->GetScale() != 1.0);
+ }
+
+ EDA_RECT bbox = aBoard->ComputeBoundingBox();
+ wxPoint boardCenter = bbox.Centre();
+ wxSize boardSize = bbox.GetSize();
+
+ double compound_scale;
+
+ /* Fit to 80% of the page if asked; it could be that the board is empty,
+ * in this case regress to 1:1 scale */
+ if( aPlotOpts->GetAutoScale() && boardSize.x > 0 && boardSize.y > 0 )
+ {
+ double xscale = (paperSizeIU.x * 0.8) / boardSize.x;
+ double yscale = (paperSizeIU.y * 0.8) / boardSize.y;
+
+ compound_scale = std::min( xscale, yscale ) * paperscale;
+ }
+ else
+ compound_scale = aPlotOpts->GetScale() * paperscale;
+
+
+ /* For the plot offset we have to keep in mind the auxiliary origin
+ too: if autoscaling is off we check that plot option (i.e. autoscaling
+ overrides auxiliary origin) */
+ wxPoint offset( 0, 0);
+
+ if( autocenter )
+ {
+ offset.x = KiROUND( boardCenter.x - ( paperSizeIU.x / 2.0 ) / compound_scale );
+ offset.y = KiROUND( boardCenter.y - ( paperSizeIU.y / 2.0 ) / compound_scale );
+ }
+ else
+ {
+ if( aPlotOpts->GetUseAuxOrigin() )
+ offset = aBoard->GetAuxOrigin();
+ }
+
+ /* Configure the plotter object with all the stuff computed and
+ most of that taken from the options */
+ aPlotter->SetPageSettings( *sheet_info );
+
+ aPlotter->SetViewport( offset, IU_PER_DECIMILS, compound_scale,
+ aPlotOpts->GetMirror() );
+
+ // has meaning only for gerber plotter. Must be called only after SetViewport
+ aPlotter->SetGerberCoordinatesFormat( aPlotOpts->GetGerberPrecision() );
+
+ aPlotter->SetDefaultLineWidth( aPlotOpts->GetLineWidth() );
+ aPlotter->SetCreator( wxT( "PCBNEW" ) );
+ aPlotter->SetColorMode( false ); // default is plot in Black and White.
+ aPlotter->SetTextMode( aPlotOpts->GetTextMode() );
+}
+
+/** Prefill in black an area a little bigger than the board to prepare for the
+ * negative plot */
+static void FillNegativeKnockout( PLOTTER *aPlotter, const EDA_RECT &aBbbox )
+{
+ const int margin = 5 * IU_PER_MM; // Add a 5 mm margin around the board
+ aPlotter->SetNegative( true );
+ aPlotter->SetColor( WHITE ); // Which will be plotted as black
+ EDA_RECT area = aBbbox;
+ area.Inflate( margin );
+ aPlotter->Rect( area.GetOrigin(), area.GetEnd(), FILLED_SHAPE );
+ aPlotter->SetColor( BLACK );
+}
+
+/** Calculate the effective size of HPGL pens and set them in the
+ * plotter object */
+static void ConfigureHPGLPenSizes( HPGL_PLOTTER *aPlotter,
+ PCB_PLOT_PARAMS *aPlotOpts )
+{
+ /* Compute pen_dim (the value is given in mils) in pcb units,
+ with plot scale (if Scale is 2, pen diameter value is always m_HPGLPenDiam
+ so apparent pen diam is actually pen diam / Scale */
+ int pen_diam = KiROUND( aPlotOpts->GetHPGLPenDiameter() * IU_PER_MILS /
+ aPlotOpts->GetScale() );
+
+ // compute pen_overlay (value comes in mils) in pcb units with plot scale
+ if( aPlotOpts->GetHPGLPenOverlay() < 0 )
+ aPlotOpts->SetHPGLPenOverlay( 0 );
+
+ if( aPlotOpts->GetHPGLPenOverlay() >= aPlotOpts->GetHPGLPenDiameter() )
+ aPlotOpts->SetHPGLPenOverlay( aPlotOpts->GetHPGLPenDiameter() - 1 );
+
+ int pen_overlay = KiROUND( aPlotOpts->GetHPGLPenOverlay() * IU_PER_MILS /
+ aPlotOpts->GetScale() );
+
+ // Set HPGL-specific options and start
+ aPlotter->SetPenSpeed( aPlotOpts->GetHPGLPenSpeed() );
+ aPlotter->SetPenNumber( aPlotOpts->GetHPGLPenNum() );
+ aPlotter->SetPenOverlap( pen_overlay );
+ aPlotter->SetPenDiameter( pen_diam );
+}
+
+/** Open a new plotfile using the options (and especially the format)
+ * specified in the options and prepare the page for plotting.
+ * Return the plotter object if OK, NULL if the file is not created
+ * (or has a problem)
+ */
+PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts,
+ int aLayer,
+ const wxString& aFullFileName,
+ const wxString& aSheetDesc )
+{
+ // Create the plotter driver and set the few plotter specific
+ // options
+ PLOTTER* plotter = NULL;
+
+ switch( aPlotOpts->GetFormat() )
+ {
+ case PLOT_FORMAT_DXF:
+ plotter = new DXF_PLOTTER();
+ break;
+
+ case PLOT_FORMAT_POST:
+ PS_PLOTTER* PS_plotter;
+ PS_plotter = new PS_PLOTTER();
+ PS_plotter->SetScaleAdjust( aPlotOpts->GetFineScaleAdjustX(),
+ aPlotOpts->GetFineScaleAdjustY() );
+ plotter = PS_plotter;
+ break;
+
+ case PLOT_FORMAT_PDF:
+ plotter = new PDF_PLOTTER();
+ break;
+
+ case PLOT_FORMAT_HPGL:
+ HPGL_PLOTTER* HPGL_plotter;
+ HPGL_plotter = new HPGL_PLOTTER();
+
+ /* HPGL options are a little more convoluted to compute, so
+ they're split in an other function */
+ ConfigureHPGLPenSizes( HPGL_plotter, aPlotOpts );
+ plotter = HPGL_plotter;
+ break;
+
+ case PLOT_FORMAT_GERBER:
+ plotter = new GERBER_PLOTTER();
+ break;
+
+ case PLOT_FORMAT_SVG:
+ plotter = new SVG_PLOTTER();
+ break;
+
+ default:
+ wxASSERT( false );
+ return NULL;
+ }
+
+ // Compute the viewport and set the other options
+
+ // page layout is not mirrored, so temporary change mirror option
+ // just to plot the page layout
+ PCB_PLOT_PARAMS plotOpts = *aPlotOpts;
+
+ if( plotOpts.GetPlotFrameRef() && plotOpts.GetMirror() )
+ plotOpts.SetMirror( false );
+
+ initializePlotter( plotter, aBoard, &plotOpts );
+
+ if( plotter->OpenFile( aFullFileName ) )
+ {
+ plotter->ClearHeaderLinesList();
+
+ // For the Gerber "file function" attribute, set the layer number
+ if( plotter->GetPlotterType() == PLOT_FORMAT_GERBER )
+ {
+ bool useX2mode = plotOpts.GetUseGerberAttributes();
+
+ if( useX2mode )
+ AddGerberX2Attribute( plotter, aBoard, aLayer );
+ else
+ plotter->AddLineToHeader( GetGerberFileFunctionAttribute(
+ aBoard, aLayer, true ) );
+ }
+
+ plotter->StartPlot();
+
+ // Plot the frame reference if requested
+ if( aPlotOpts->GetPlotFrameRef() )
+ {
+ PlotWorkSheet( plotter, aBoard->GetTitleBlock(),
+ aBoard->GetPageSettings(),
+ 1, 1, // Only one page
+ aSheetDesc, aBoard->GetFileName() );
+
+ if( aPlotOpts->GetMirror() )
+ initializePlotter( plotter, aBoard, aPlotOpts );
+ }
+
+ /* When plotting a negative board: draw a black rectangle
+ * (background for plot board in white) and switch the current
+ * color to WHITE; note the color inversion is actually done
+ * in the driver (if supported) */
+ if( aPlotOpts->GetNegative() )
+ {
+ EDA_RECT bbox = aBoard->ComputeBoundingBox();
+ FillNegativeKnockout( plotter, bbox );
+ }
+
+ return plotter;
+ }
+
+ delete plotter;
+ return NULL;
+}
diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp
new file mode 100644
index 0000000..248eda7
--- /dev/null
+++ b/pcbnew/plot_brditems_plotter.cpp
@@ -0,0 +1,688 @@
+/**
+ * @file plot_brditems_plotter.cpp
+ * @brief basic plot functions to plot board items, or a group of board items.
+ */
+
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <plot_common.h>
+#include <base_struct.h>
+#include <drawtxt.h>
+#include <trigo.h>
+#include <macros.h>
+#include <wxBasePcbFrame.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_edge_mod.h>
+#include <class_pcb_text.h>
+#include <class_zone.h>
+#include <class_drawsegment.h>
+#include <class_mire.h>
+#include <class_dimension.h>
+
+#include <pcbnew.h>
+#include <pcbplot.h>
+
+/* class BRDITEMS_PLOTTER is a helper class to plot board items
+ * and a group of board items
+ */
+
+
+EDA_COLOR_T BRDITEMS_PLOTTER::getColor( LAYER_NUM aLayer )
+{
+ EDA_COLOR_T color = m_board->GetLayerColor( ToLAYER_ID( aLayer ) );
+ if (color == WHITE)
+ color = LIGHTGRAY;
+ return color;
+}
+
+
+void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, EDA_COLOR_T aColor, EDA_DRAW_MODE_T aPlotMode )
+{
+ wxPoint shape_pos = aPad->ShapePos();
+
+ // Set plot color (change WHITE to LIGHTGRAY because
+ // the white items are not seen on a white paper or screen
+ m_plotter->SetColor( aColor != WHITE ? aColor : LIGHTGRAY);
+
+ switch( aPad->GetShape() )
+ {
+ case PAD_SHAPE_CIRCLE:
+ m_plotter->FlashPadCircle( shape_pos, aPad->GetSize().x, aPlotMode );
+ break;
+
+ case PAD_SHAPE_OVAL:
+ m_plotter->FlashPadOval( shape_pos, aPad->GetSize(),
+ aPad->GetOrientation(), aPlotMode );
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ {
+ wxPoint coord[4];
+ aPad->BuildPadPolygon( coord, wxSize(0,0), 0 );
+ m_plotter->FlashPadTrapez( shape_pos, coord,
+ aPad->GetOrientation(), aPlotMode );
+ }
+ break;
+
+ case PAD_SHAPE_RECT:
+ default:
+ m_plotter->FlashPadRect( shape_pos, aPad->GetSize(),
+ aPad->GetOrientation(), aPlotMode );
+ break;
+ }
+}
+
+
+bool BRDITEMS_PLOTTER::PlotAllTextsModule( MODULE* aModule )
+{
+ // see if we want to plot VALUE and REF fields
+ bool trace_val = GetPlotValue();
+ bool trace_ref = GetPlotReference();
+
+ TEXTE_MODULE* textModule = &aModule->Reference();
+ LAYER_NUM textLayer = textModule->GetLayer();
+
+ if( textLayer >= LAYER_ID_COUNT ) // how will this ever be true?
+ return false;
+
+ if( !m_layerMask[textLayer] )
+ trace_ref = false;
+
+ if( !textModule->IsVisible() && !GetPlotInvisibleText() )
+ trace_ref = false;
+
+ textModule = &aModule->Value();
+ textLayer = textModule->GetLayer();
+
+ if( textLayer > LAYER_ID_COUNT ) // how will this ever be true?
+ return false;
+
+ if( !m_layerMask[textLayer] )
+ trace_val = false;
+
+ if( !textModule->IsVisible() && !GetPlotInvisibleText() )
+ trace_val = false;
+
+ // Plot text fields, if allowed
+ if( trace_ref )
+ {
+ PlotTextModule( &aModule->Reference(), getColor( textLayer ) );
+ }
+
+ if( trace_val )
+ {
+ PlotTextModule( &aModule->Value(), getColor( textLayer ) );
+ }
+
+ for( BOARD_ITEM *item = aModule->GraphicalItems().GetFirst(); item; item = item->Next() )
+ {
+ textModule = dyn_cast<TEXTE_MODULE*>( item );
+
+ if( !textModule )
+ continue;
+
+ if( !textModule->IsVisible() )
+ continue;
+
+ textLayer = textModule->GetLayer();
+
+ if( textLayer >= LAYER_ID_COUNT )
+ return false;
+
+ if( !m_layerMask[textLayer] )
+ continue;
+
+ PlotTextModule( textModule, getColor( textLayer ) );
+ }
+
+ return true;
+}
+
+
+// plot items like text and graphics, but not tracks and module
+void BRDITEMS_PLOTTER::PlotBoardGraphicItems()
+{
+ for( BOARD_ITEM* item = m_board->m_Drawings; item; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case PCB_LINE_T:
+ PlotDrawSegment( (DRAWSEGMENT*) item);
+ break;
+
+ case PCB_TEXT_T:
+ PlotTextePcb( (TEXTE_PCB*) item );
+ break;
+
+ case PCB_DIMENSION_T:
+ PlotDimension( (DIMENSION*) item );
+ break;
+
+ case PCB_TARGET_T:
+ PlotPcbTarget( (PCB_TARGET*) item );
+ break;
+
+ case PCB_MARKER_T:
+ default:
+ break;
+ }
+ }
+}
+
+void BRDITEMS_PLOTTER::PlotTextModule( TEXTE_MODULE* pt_texte, EDA_COLOR_T aColor )
+{
+ wxSize size;
+ wxPoint pos;
+ double orient;
+ int thickness;
+
+ if( aColor == WHITE )
+ aColor = LIGHTGRAY;
+
+ m_plotter->SetColor( aColor );
+
+ // calculate some text parameters :
+ size = pt_texte->GetSize();
+ pos = pt_texte->GetTextPosition();
+
+ orient = pt_texte->GetDrawRotation();
+
+ thickness = pt_texte->GetThickness();
+
+ if( pt_texte->IsMirrored() )
+ size.x = -size.x; // Text is mirrored
+
+ // Non bold texts thickness is clamped at 1/6 char size by the low level draw function.
+ // but in Pcbnew we do not manage bold texts and thickness up to 1/4 char size
+ // (like bold text) and we manage the thickness.
+ // So we set bold flag to true
+ bool allow_bold = pt_texte->IsBold() || thickness;
+
+ m_plotter->Text( pos, aColor,
+ pt_texte->GetShownText(),
+ orient, size,
+ pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
+ thickness, pt_texte->IsItalic(), allow_bold );
+}
+
+
+void BRDITEMS_PLOTTER::PlotDimension( DIMENSION* aDim )
+{
+ if( !m_layerMask[aDim->GetLayer()] )
+ return;
+
+ DRAWSEGMENT draw;
+
+ draw.SetWidth( aDim->GetWidth() );
+ draw.SetLayer( aDim->GetLayer() );
+
+ EDA_COLOR_T color = getColor( aDim->GetLayer() );
+
+ // Set plot color (change WHITE to LIGHTGRAY because
+ // the white items are not seen on a white paper or screen
+ m_plotter->SetColor( color );
+
+ PlotTextePcb( &aDim->Text() );
+
+ draw.SetStart( aDim->m_crossBarO );
+ draw.SetEnd( aDim->m_crossBarF );
+ PlotDrawSegment( &draw );
+
+ draw.SetStart( aDim->m_featureLineGO);
+ draw.SetEnd( aDim->m_featureLineGF );
+ PlotDrawSegment( &draw );
+
+ draw.SetStart( aDim->m_featureLineDO );
+ draw.SetEnd( aDim->m_featureLineDF );
+ PlotDrawSegment( &draw );
+
+ draw.SetStart( aDim->m_crossBarF );
+ draw.SetEnd( aDim->m_arrowD1F );
+ PlotDrawSegment( &draw );
+
+ draw.SetStart( aDim->m_crossBarF );
+ draw.SetEnd( aDim->m_arrowD2F );
+ PlotDrawSegment( &draw );
+
+ draw.SetStart( aDim->m_crossBarO );
+ draw.SetEnd( aDim->m_arrowG1F );
+ PlotDrawSegment( &draw );
+
+ draw.SetStart( aDim->m_crossBarO );
+ draw.SetEnd( aDim->m_arrowG2F );
+ PlotDrawSegment( &draw );
+}
+
+
+void BRDITEMS_PLOTTER::PlotPcbTarget( PCB_TARGET* aMire )
+{
+ int dx1, dx2, dy1, dy2, radius;
+
+ if( !m_layerMask[aMire->GetLayer()] )
+ return;
+
+ m_plotter->SetColor( getColor( aMire->GetLayer() ) );
+
+ DRAWSEGMENT draw;
+
+ draw.SetShape( S_CIRCLE );
+ draw.SetWidth( aMire->GetWidth() );
+ draw.SetLayer( aMire->GetLayer() );
+ draw.SetStart( aMire->GetPosition() );
+ radius = aMire->GetSize() / 3;
+
+ if( aMire->GetShape() ) // shape X
+ radius = aMire->GetSize() / 2;
+
+ // Draw the circle
+ draw.SetEnd( wxPoint( draw.GetStart().x + radius, draw.GetStart().y ));
+
+ PlotDrawSegment( &draw );
+
+ draw.SetShape( S_SEGMENT );
+
+ radius = aMire->GetSize() / 2;
+ dx1 = radius;
+ dy1 = 0;
+ dx2 = 0;
+ dy2 = radius;
+
+ if( aMire->GetShape() ) // Shape X
+ {
+ dx1 = dy1 = radius;
+ dx2 = dx1;
+ dy2 = -dy1;
+ }
+
+ wxPoint mirePos( aMire->GetPosition() );
+
+ // Draw the X or + shape:
+ draw.SetStart( wxPoint( mirePos.x - dx1, mirePos.y - dy1 ));
+ draw.SetEnd( wxPoint( mirePos.x + dx1, mirePos.y + dy1 ));
+ PlotDrawSegment( &draw );
+
+ draw.SetStart( wxPoint( mirePos.x - dx2, mirePos.y - dy2 ));
+ draw.SetEnd( wxPoint( mirePos.x + dx2, mirePos.y + dy2 ));
+ PlotDrawSegment( &draw );
+}
+
+
+// Plot footprints graphic items (outlines)
+void BRDITEMS_PLOTTER::Plot_Edges_Modules()
+{
+ for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
+ {
+ for( BOARD_ITEM* item = module->GraphicalItems().GetFirst(); item; item = item->Next() )
+ {
+ EDGE_MODULE* edge = dyn_cast<EDGE_MODULE*>( item );
+
+ if( !edge || !m_layerMask[edge->GetLayer()] )
+ continue;
+
+ Plot_1_EdgeModule( edge );
+ }
+ }
+}
+
+
+//* Plot a graphic item (outline) relative to a footprint
+void BRDITEMS_PLOTTER::Plot_1_EdgeModule( EDGE_MODULE* aEdge )
+{
+ int type_trace; // Type of item to plot.
+ int thickness; // Segment thickness.
+ int radius; // Circle radius.
+
+ if( aEdge->Type() != PCB_MODULE_EDGE_T )
+ return;
+
+ m_plotter->SetColor( getColor( aEdge->GetLayer() ) );
+
+ type_trace = aEdge->GetShape();
+ thickness = aEdge->GetWidth();
+
+ wxPoint pos( aEdge->GetStart() );
+ wxPoint end( aEdge->GetEnd() );
+
+ switch( type_trace )
+ {
+ case S_SEGMENT:
+ m_plotter->ThickSegment( pos, end, thickness, GetPlotMode() );
+ break;
+
+ case S_CIRCLE:
+ radius = KiROUND( GetLineLength( end, pos ) );
+ m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode() );
+ break;
+
+ case S_ARC:
+ {
+ radius = KiROUND( GetLineLength( end, pos ) );
+ double startAngle = ArcTangente( end.y - pos.y, end.x - pos.x );
+ double endAngle = startAngle + aEdge->GetAngle();
+
+ m_plotter->ThickArc( pos, -endAngle, -startAngle, radius, thickness, GetPlotMode() );
+ }
+ break;
+
+ case S_POLYGON:
+ {
+ const std::vector<wxPoint>& polyPoints = aEdge->GetPolyPoints();
+
+ if( polyPoints.size() <= 1 ) // Malformed polygon
+ break;
+
+ // We must compute true coordinates from m_PolyList
+ // which are relative to module position, orientation 0
+ MODULE* module = aEdge->GetParentModule();
+
+ std::vector< wxPoint > cornerList;
+
+ cornerList.reserve( polyPoints.size() );
+
+ for( unsigned ii = 0; ii < polyPoints.size(); ii++ )
+ {
+ wxPoint corner = polyPoints[ii];
+
+ if( module )
+ {
+ RotatePoint( &corner, module->GetOrientation() );
+ corner += module->GetPosition();
+ }
+
+ cornerList.push_back( corner );
+ }
+
+ m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness );
+ }
+ break;
+ }
+}
+
+
+// Plot a PCB Text, i;e. a text found on a copper or technical layer
+void BRDITEMS_PLOTTER::PlotTextePcb( TEXTE_PCB* pt_texte )
+{
+ double orient;
+ int thickness;
+ wxPoint pos;
+ wxSize size;
+ wxString shownText( pt_texte->GetShownText() );
+
+ if( shownText.IsEmpty() )
+ return;
+
+ if( !m_layerMask[pt_texte->GetLayer()] )
+ return;
+
+ EDA_COLOR_T color = getColor( pt_texte->GetLayer() );
+ m_plotter->SetColor( color );
+
+ size = pt_texte->GetSize();
+ pos = pt_texte->GetTextPosition();
+ orient = pt_texte->GetOrientation();
+ thickness = pt_texte->GetThickness();
+
+ if( pt_texte->IsMirrored() )
+ size.x = -size.x;
+
+ // Non bold texts thickness is clamped at 1/6 char size by the low level draw function.
+ // but in Pcbnew we do not manage bold texts and thickness up to 1/4 char size
+ // (like bold text) and we manage the thickness.
+ // So we set bold flag to true
+ bool allow_bold = pt_texte->IsBold() || thickness;
+
+ if( pt_texte->IsMultilineAllowed() )
+ {
+ std::vector<wxPoint> positions;
+ wxArrayString strings_list;
+ wxStringSplit( shownText, strings_list, '\n' );
+ positions.reserve( strings_list.Count() );
+
+ pt_texte->GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() );
+
+ for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
+ {
+ wxString& txt = strings_list.Item( ii );
+ m_plotter->Text( positions[ii], color, txt, orient, size,
+ pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
+ thickness, pt_texte->IsItalic(), allow_bold );
+ }
+ }
+ else
+ {
+ m_plotter->Text( pos, color, shownText, orient, size,
+ pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
+ thickness, pt_texte->IsItalic(), allow_bold );
+ }
+}
+
+
+/* Plot areas (given by .m_FilledPolysList member) in a zone
+ */
+void BRDITEMS_PLOTTER::PlotFilledAreas( ZONE_CONTAINER* aZone )
+{
+ const SHAPE_POLY_SET& polysList = aZone->GetFilledPolysList();
+
+ if( polysList.IsEmpty() )
+ return;
+
+ // We need a buffer to store corners coordinates:
+ static std::vector< wxPoint > cornerList;
+ cornerList.clear();
+
+ m_plotter->SetColor( getColor( aZone->GetLayer() ) );
+
+ /* Plot all filled areas: filled areas have a filled area and a thick
+ * outline we must plot the filled area itself ( as a filled polygon
+ * OR a set of segments ) and plot the thick outline itself
+ *
+ * in non filled mode the outline is plotted, but not the filling items
+ */
+ for( SHAPE_POLY_SET::CONST_ITERATOR ic = polysList.CIterate(); ic; ++ic )
+ {
+ wxPoint pos( ic->x, ic->y );
+ cornerList.push_back( pos );
+
+ if( ic.IsEndContour() ) // Plot the current filled area outline
+ {
+ // First, close the outline
+ if( cornerList[0] != cornerList[cornerList.size() - 1] )
+ {
+ cornerList.push_back( cornerList[0] );
+ }
+
+ // Plot the current filled area and its outline
+ if( GetPlotMode() == FILLED )
+ {
+ // Plot the filled area polygon.
+ // The area can be filled by segments or uses solid polygons
+ if( aZone->GetFillMode() == 0 ) // We are using solid polygons
+ {
+ m_plotter->PlotPoly( cornerList, FILLED_SHAPE, aZone->GetMinThickness() );
+ }
+ else // We are using areas filled by segments: plot segments and outline
+ {
+ for( unsigned iseg = 0; iseg < aZone->FillSegments().size(); iseg++ )
+ {
+ wxPoint start = aZone->FillSegments()[iseg].m_Start;
+ wxPoint end = aZone->FillSegments()[iseg].m_End;
+ m_plotter->ThickSegment( start, end,
+ aZone->GetMinThickness(),
+ GetPlotMode() );
+ }
+
+ // Plot the area outline only
+ if( aZone->GetMinThickness() > 0 )
+ m_plotter->PlotPoly( cornerList, NO_FILL, aZone->GetMinThickness() );
+ }
+ }
+ else
+ {
+ if( aZone->GetMinThickness() > 0 )
+ {
+ for( unsigned jj = 1; jj<cornerList.size(); jj++ )
+ m_plotter->ThickSegment( cornerList[jj -1], cornerList[jj],
+ aZone->GetMinThickness(),
+ GetPlotMode() );
+ }
+
+ m_plotter->SetCurrentLineWidth( -1 );
+ }
+
+ cornerList.clear();
+ }
+ }
+}
+
+
+/* Plot items type DRAWSEGMENT on layers allowed by aLayerMask
+ */
+void BRDITEMS_PLOTTER::PlotDrawSegment( DRAWSEGMENT* aSeg )
+{
+ if( !m_layerMask[aSeg->GetLayer()] )
+ return;
+
+ int radius = 0;
+ double StAngle = 0, EndAngle = 0;
+ int thickness = aSeg->GetWidth();
+
+ m_plotter->SetColor( getColor( aSeg->GetLayer() ) );
+
+ wxPoint start( aSeg->GetStart() );
+ wxPoint end( aSeg->GetEnd() );
+
+ m_plotter->SetCurrentLineWidth( thickness );
+
+ switch( aSeg->GetShape() )
+ {
+ case S_CIRCLE:
+ radius = KiROUND( GetLineLength( end, start ) );
+ m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode() );
+ break;
+
+ case S_ARC:
+ radius = KiROUND( GetLineLength( end, start ) );
+ StAngle = ArcTangente( end.y - start.y, end.x - start.x );
+ EndAngle = StAngle + aSeg->GetAngle();
+ m_plotter->ThickArc( start, -EndAngle, -StAngle, radius, thickness, GetPlotMode() );
+ break;
+
+ case S_CURVE:
+ {
+ const std::vector<wxPoint>& bezierPoints = aSeg->GetBezierPoints();
+
+ for( unsigned i = 1; i < bezierPoints.size(); i++ )
+ m_plotter->ThickSegment( bezierPoints[i - 1],
+ bezierPoints[i],
+ thickness, GetPlotMode() );
+ }
+ break;
+
+ default:
+ m_plotter->ThickSegment( start, end, thickness, GetPlotMode() );
+ }
+}
+
+
+/** Helper function to plot a single drill mark. It compensate and clamp
+ * the drill mark size depending on the current plot options
+ */
+void BRDITEMS_PLOTTER::plotOneDrillMark( PAD_DRILL_SHAPE_T aDrillShape,
+ const wxPoint &aDrillPos, wxSize aDrillSize,
+ const wxSize &aPadSize,
+ double aOrientation, int aSmallDrill )
+{
+ // Small drill marks have no significance when applied to slots
+ if( aSmallDrill && aDrillShape == PAD_DRILL_SHAPE_CIRCLE )
+ aDrillSize.x = std::min( aSmallDrill, aDrillSize.x );
+
+ // Round holes only have x diameter, slots have both
+ aDrillSize.x -= getFineWidthAdj();
+ aDrillSize.x = Clamp( 1, aDrillSize.x, aPadSize.x - 1 );
+
+ if( aDrillShape == PAD_DRILL_SHAPE_OBLONG )
+ {
+ aDrillSize.y -= getFineWidthAdj();
+ aDrillSize.y = Clamp( 1, aDrillSize.y, aPadSize.y - 1 );
+ m_plotter->FlashPadOval( aDrillPos, aDrillSize, aOrientation, GetPlotMode() );
+ }
+ else
+ m_plotter->FlashPadCircle( aDrillPos, aDrillSize.x, GetPlotMode() );
+}
+
+
+void BRDITEMS_PLOTTER::PlotDrillMarks()
+{
+ /* If small drills marks were requested prepare a clamp value to pass
+ to the helper function */
+ int small_drill = (GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE) ?
+ SMALL_DRILL : 0;
+
+ /* In the filled trace mode drill marks are drawn white-on-black to scrape
+ the underlying pad. This works only for drivers supporting color change,
+ obviously... it means that:
+ - PS, SVG and PDF output is correct (i.e. you have a 'donut' pad)
+ - In HPGL you can't see them
+ - In gerbers you can't see them, too. This is arguably the right thing to
+ do since having drill marks and high speed drill stations is a sure
+ recipe for broken tools and angry manufacturers. If you *really* want them
+ you could start a layer with negative polarity to scrape the film.
+ - In DXF they go into the 'WHITE' layer. This could be useful.
+ */
+ if( GetPlotMode() == FILLED )
+ m_plotter->SetColor( WHITE );
+
+ for( TRACK *pts = m_board->m_Track; pts != NULL; pts = pts->Next() )
+ {
+ const VIA* via = dyn_cast<const VIA*>( pts );
+
+ if( via )
+ plotOneDrillMark( PAD_DRILL_SHAPE_CIRCLE, via->GetStart(),
+ wxSize( via->GetDrillValue(), 0 ),
+ wxSize( via->GetWidth(), 0 ), 0, small_drill );
+ }
+
+ for( MODULE *Module = m_board->m_Modules; Module != NULL; Module = Module->Next() )
+ {
+ for( D_PAD *pad = Module->Pads(); pad != NULL; pad = pad->Next() )
+ {
+ if( pad->GetDrillSize().x == 0 )
+ continue;
+
+ plotOneDrillMark( pad->GetDrillShape(),
+ pad->GetPosition(), pad->GetDrillSize(),
+ pad->GetSize(), pad->GetOrientation(),
+ small_drill );
+ }
+ }
+
+ if( GetPlotMode() == FILLED )
+ m_plotter->SetColor( GetColor() );
+}
diff --git a/pcbnew/plotcontroller.h b/pcbnew/plotcontroller.h
new file mode 100644
index 0000000..013afed
--- /dev/null
+++ b/pcbnew/plotcontroller.h
@@ -0,0 +1,129 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Lorenzo Marcantonio, <l.marcantonio@logossrl.com>
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/pcbplot.h
+ */
+
+#ifndef PLOTCONTROLLER_H_
+#define PLOTCONTROLLER_H_
+
+#include <pcb_plot_params.h>
+#include <layers_id_colors_and_visibility.h>
+
+class PLOTTER;
+class BOARD;
+
+
+/**
+ * Batch plotter state object. Keeps the plot options and handles multiple
+ * plot requests
+ * Especially useful in Python scripts
+ */
+class PLOT_CONTROLLER
+{
+public:
+ /** Batch plotter constructor, nothing interesting here */
+ PLOT_CONTROLLER( BOARD *aBoard );
+
+ /** Batch plotter destructor, ensures that the last plot is closed
+ */
+ ~PLOT_CONTROLLER();
+
+ /**
+ * Accessor to the plot parameters and options
+ */
+ PCB_PLOT_PARAMS& GetPlotOptions() { return m_plotOptions; }
+
+ void SetLayer( LAYER_NUM aLayer ) { m_plotLayer = aLayer; }
+ LAYER_NUM GetLayer() { return m_plotLayer; }
+
+
+ /**
+ * @return true if a plotter is initialized and can be used
+ */
+ bool IsPlotOpen() const { return m_plotter != NULL; }
+
+ /** Close the current plot, nothing happens if it isn't open
+ */
+ void ClosePlot();
+
+ /** Open a new plotfile; works as a factory for plotter objects
+ * @param aSuffix is a string added to the base filename (derived from
+ * the board filename) to identify the plot file
+ * @param aFormat is the plot file format identifier
+ * @param aSheetDesc
+ */
+ bool OpenPlotfile( const wxString &aSuffix, PlotFormat aFormat,
+ const wxString &aSheetDesc );
+
+ /** Plot a single layer on the current plotfile
+ * m_plotLayer is the layer to plot
+ */
+ bool PlotLayer();
+
+ /**
+ * @return the current plot full filename, set by OpenPlotfile
+ */
+ const wxString GetPlotFileName() { return m_plotFile.GetFullPath(); }
+
+ /**
+ * @return the current plot full filename, set by OpenPlotfile
+ */
+ const wxString GetPlotDirName() { return m_plotFile.GetPathWithSep(); }
+
+ /**
+ * Plotters can plot in Black and White mode or Color mode
+ * SetColorMode activate/de-actiavte the Color mode.
+ * @param aColorMode = true to activate the plot color mode
+ */
+ void SetColorMode( bool );
+
+ /**
+ * @return true if the current plot color mode is Color,
+ * false if the current plot color mode is Black and White
+ */
+ bool GetColorMode();
+
+private:
+ /// the layer to plot
+ LAYER_NUM m_plotLayer;
+
+ /// Option bank
+ PCB_PLOT_PARAMS m_plotOptions;
+
+ /// This is the plotter object; it starts NULL and become instantiated
+ /// when a plotfile is requested
+ PLOTTER* m_plotter;
+
+ /// The board we're plotting
+ BOARD* m_board;
+
+ /// The current plot filename, set by OpenPlotfile
+ wxFileName m_plotFile;
+};
+
+#endif
+
diff --git a/pcbnew/plugin.cpp b/pcbnew/plugin.cpp
new file mode 100644
index 0000000..9b5f5ab
--- /dev/null
+++ b/pcbnew/plugin.cpp
@@ -0,0 +1,147 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2011-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <io_mgr.h>
+
+#define FMT_UNIMPLEMENTED _( "Plugin '%s' does not implement the '%s' function." )
+
+/**
+ * Function not_implemented
+ * throws an IO_ERROR and complains of an API function not being implemented.
+ *
+ * @param aPlugin is a PLUGIN instance
+ * @param aCaller is the name of the unimplemented API function.
+ */
+static void not_implemented( PLUGIN* aPlugin, const char* aCaller )
+{
+ THROW_IO_ERROR( wxString::Format( FMT_UNIMPLEMENTED,
+ aPlugin->PluginName().GetData(),
+ wxString::FromUTF8( aCaller ).GetData() )
+ );
+}
+
+
+BOARD* PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties )
+{
+ not_implemented( this, __FUNCTION__ );
+ return NULL;
+}
+
+
+void PLUGIN::Save( const wxString& aFileName, BOARD* aBoard, const PROPERTIES* aProperties )
+{
+ // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
+ not_implemented( this, __FUNCTION__ );
+}
+
+
+wxArrayString PLUGIN::FootprintEnumerate( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
+ not_implemented( this, __FUNCTION__ );
+ return wxArrayString();
+}
+
+
+MODULE* PLUGIN::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
+ const PROPERTIES* aProperties )
+{
+ // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
+ not_implemented( this, __FUNCTION__ );
+ return NULL;
+}
+
+
+void PLUGIN::FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint, const PROPERTIES* aProperties )
+{
+ // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
+ not_implemented( this, __FUNCTION__ );
+}
+
+
+void PLUGIN::FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName, const PROPERTIES* aProperties )
+{
+ // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
+ not_implemented( this, __FUNCTION__ );
+}
+
+
+void PLUGIN::FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
+ not_implemented( this, __FUNCTION__ );
+}
+
+
+bool PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties )
+{
+ // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
+ not_implemented( this, __FUNCTION__ );
+ return false;
+}
+
+
+bool PLUGIN::IsFootprintLibWritable( const wxString& aLibraryPath )
+{
+ // not pure virtual so that plugins only have to implement subset of the PLUGIN interface.
+ not_implemented( this, __FUNCTION__ );
+ return false;
+}
+
+
+void PLUGIN::FootprintLibOptions( PROPERTIES* aListToAppendTo ) const
+{
+ // disable all these in another couple of months, after everyone has seen them:
+#if 1
+ (*aListToAppendTo)["debug_level"] = UTF8( _(
+ "Enable <b>debug</b> logging for Footprint*() functions in this PLUGIN."
+ ));
+
+ (*aListToAppendTo)["read_filter_regex"] = UTF8( _(
+ "Regular expression <b>footprint name</b> filter."
+ ));
+
+ (*aListToAppendTo)["enable_transaction_logging"] = UTF8( _(
+ "Enable transaction logging. The mere presence of this option turns on the "
+ "logging, no need to set a Value."
+ ));
+
+ (*aListToAppendTo)["username"] = UTF8( _(
+ "User name for <b>login</b> to some special library server."
+ ));
+
+ (*aListToAppendTo)["password"] = UTF8( _(
+ "Password for <b>login</b> to some special library server."
+ ));
+#endif
+
+#if 1
+ // Suitable for a C++ to python PLUGIN::Footprint*() adapter, move it to the adapter
+ // if and when implemented.
+ (*aListToAppendTo)["python_footprint_plugin"] = UTF8( _(
+ "Enter the python module which implements the PLUGIN::Footprint*() functions."
+ ));
+#endif
+}
+
diff --git a/pcbnew/print_board_functions.cpp b/pcbnew/print_board_functions.cpp
new file mode 100644
index 0000000..47291ed
--- /dev/null
+++ b/pcbnew/print_board_functions.cpp
@@ -0,0 +1,389 @@
+/**
+ * @file print_board_functions.cpp
+ * @brief Functions to print boards.
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+#include <printout_controler.h>
+#include <colors_selection.h>
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+#include <class_track.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <pcbplot.h>
+#include <module_editor_frame.h>
+
+
+static void Print_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, MODULE* aModule,
+ GR_DRAWMODE aDraw_mode, LSET aMasklayer,
+ PRINT_PARAMETERS::DrillShapeOptT aDrillShapeOpt );
+
+void FOOTPRINT_EDIT_FRAME::PrintPage( wxDC* aDC,
+ LSET aPrintMaskLayer,
+ bool aPrintMirrorMode,
+ void * aData)
+{
+ const GR_DRAWMODE drawmode = (GR_DRAWMODE) 0;
+ int defaultPenSize = Millimeter2iu( 0.2 );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ DISPLAY_OPTIONS save_opt;
+
+ PRINT_PARAMETERS * printParameters = (PRINT_PARAMETERS*) aData; // can be null
+ PRINT_PARAMETERS::DrillShapeOptT drillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE;
+
+ if( printParameters )
+ defaultPenSize = printParameters->m_PenDefaultSize;
+
+ save_opt = *displ_opts;
+
+ displ_opts->m_ContrastModeDisplay = false;
+ displ_opts->m_DisplayPadFill = true;
+ displ_opts->m_DisplayViaFill = true;
+ displ_opts->m_DisplayPadNum = false;
+ bool nctmp = GetBoard()->IsElementVisible(NO_CONNECTS_VISIBLE);
+ GetBoard()->SetElementVisibility(NO_CONNECTS_VISIBLE, false);
+ displ_opts->m_DisplayPadIsol = false;
+ displ_opts->m_DisplayModEdgeFill = FILLED;
+ displ_opts->m_DisplayModTextFill = FILLED;
+ displ_opts->m_DisplayPcbTrackFill = true;
+ displ_opts->m_ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE;
+ displ_opts->m_DisplayDrawItemsFill = FILLED;
+ displ_opts->m_DisplayZonesMode = 0;
+ displ_opts->m_DisplayNetNamesMode = 0;
+
+ m_canvas->SetPrintMirrored( aPrintMirrorMode );
+
+ // Draw footprints, this is done at last in order to print the pad holes in
+ // white after the tracks and zones
+ int tmp = D_PAD::m_PadSketchModePenSize;
+ D_PAD::m_PadSketchModePenSize = defaultPenSize;
+
+ wxSize pageSizeIU = GetPageSizeIU() / 2;
+ wxPoint offset( pageSizeIU.x, pageSizeIU.y );
+
+ for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
+ {
+ module->Move( offset );
+ Print_Module( m_canvas, aDC, module, drawmode, aPrintMaskLayer, drillShapeOpt );
+ module->Move( -offset );
+ }
+
+ D_PAD::m_PadSketchModePenSize = tmp;
+
+ m_canvas->SetPrintMirrored( false );
+
+ *displ_opts = save_opt;
+ GetBoard()->SetElementVisibility( NO_CONNECTS_VISIBLE, nctmp );
+}
+
+
+void PCB_EDIT_FRAME::PrintPage( wxDC* aDC,
+ LSET aPrintMask,
+ bool aPrintMirrorMode,
+ void* aData)
+{
+ const GR_DRAWMODE drawmode = (GR_DRAWMODE) 0;
+ DISPLAY_OPTIONS save_opt;
+ BOARD* Pcb = GetBoard();
+ int defaultPenSize = Millimeter2iu( 0.2 );
+ bool onePagePerLayer = false;
+
+ PRINT_PARAMETERS* printParameters = (PRINT_PARAMETERS*) aData; // can be null
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ if( printParameters && printParameters->m_OptionPrintPage == 0 )
+ onePagePerLayer = true;
+
+ PRINT_PARAMETERS::DrillShapeOptT drillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE;
+
+ if( printParameters )
+ {
+ drillShapeOpt = printParameters->m_DrillShapeOpt;
+ defaultPenSize = printParameters->m_PenDefaultSize;
+ }
+
+ save_opt = *displ_opts;
+
+ LAYER_ID activeLayer = GetScreen()->m_Active_Layer;
+
+ displ_opts->m_ContrastModeDisplay = false;
+ displ_opts->m_DisplayPadFill = true;
+ displ_opts->m_DisplayViaFill = true;
+
+ if( !( aPrintMask & LSET::AllCuMask() ).any() )
+ {
+ if( onePagePerLayer )
+ {
+ // We can print mask layers (solder mask and solder paste) with the actual
+ // pad sizes. To do that, we must set ContrastModeDisplay to true and set
+ // the GetScreen()->m_Active_Layer to the current printed layer
+ displ_opts->m_ContrastModeDisplay = true;
+ displ_opts->m_DisplayPadFill = true;
+
+ // Calculate the active layer number to print from its mask layer:
+ GetScreen()->m_Active_Layer = B_Cu;
+
+ for( LAYER_NUM id = LAYER_ID_COUNT-1; id >= 0; --id )
+ {
+ if( aPrintMask[id] )
+ {
+ GetScreen()->m_Active_Layer = LAYER_ID( id );
+ break;
+ }
+ }
+
+ // pads on Silkscreen layer are usually plot in sketch mode:
+ if( GetScreen()->m_Active_Layer == B_SilkS ||
+ GetScreen()->m_Active_Layer == F_SilkS )
+ {
+ displ_opts->m_DisplayPadFill = false;
+ }
+ }
+ else
+ {
+ displ_opts->m_DisplayPadFill = false;
+ }
+ }
+
+ displ_opts->m_DisplayPadNum = false;
+
+ bool nctmp = GetBoard()->IsElementVisible( NO_CONNECTS_VISIBLE );
+
+ GetBoard()->SetElementVisibility( NO_CONNECTS_VISIBLE, false );
+
+ bool anchorsTmp = GetBoard()->IsElementVisible( ANCHOR_VISIBLE );
+
+ GetBoard()->SetElementVisibility( ANCHOR_VISIBLE, false );
+
+ displ_opts->m_DisplayPadIsol = false;
+ displ_opts->m_DisplayModEdgeFill = FILLED;
+ displ_opts->m_DisplayModTextFill = FILLED;
+ displ_opts->m_DisplayPcbTrackFill = true;
+ displ_opts->m_ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE;
+ displ_opts->m_DisplayDrawItemsFill = FILLED;
+ displ_opts->m_DisplayZonesMode = 0;
+ displ_opts->m_DisplayNetNamesMode = 0;
+
+ m_canvas->SetPrintMirrored( aPrintMirrorMode );
+
+ for( BOARD_ITEM* item = Pcb->m_Drawings; item; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case PCB_LINE_T:
+ case PCB_DIMENSION_T:
+ case PCB_TEXT_T:
+ case PCB_TARGET_T:
+ if( aPrintMask[item->GetLayer()] )
+ item->Draw( m_canvas, aDC, drawmode );
+ break;
+
+ case PCB_MARKER_T:
+ default:
+ break;
+ }
+ }
+
+ // Print tracks
+ for( TRACK* track = Pcb->m_Track; track; track = track->Next() )
+ {
+ if( !( aPrintMask & track->GetLayerSet() ).any() )
+ continue;
+
+ if( track->Type() == PCB_VIA_T ) // VIA encountered.
+ {
+ int radius = track->GetWidth() / 2;
+ const VIA* via = static_cast<const VIA*>( track );
+
+ EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + via->GetViaType() );
+
+ GRFilledCircle( m_canvas->GetClipBox(), aDC,
+ via->GetStart().x,
+ via->GetStart().y,
+ radius,
+ 0, color, color );
+ }
+ else
+ {
+ track->Draw( m_canvas, aDC, drawmode );
+ }
+ }
+
+ // Outdated: only for compatibility to old boards
+ for( TRACK* track = Pcb->m_Zone; track; track = track->Next() )
+ {
+ if( !( aPrintMask & track->GetLayerSet() ).any() )
+ continue;
+
+ track->Draw( m_canvas, aDC, drawmode );
+ }
+
+ // Draw filled areas (i.e. zones)
+ for( int ii = 0; ii < Pcb->GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* zone = Pcb->GetArea( ii );
+
+ if( aPrintMask[zone->GetLayer()] )
+ zone->DrawFilledArea( m_canvas, aDC, drawmode );
+ }
+
+ // Draw footprints, this is done at last in order to print the pad holes in
+ // white after the tracks and zones
+ int tmp = D_PAD::m_PadSketchModePenSize;
+ D_PAD::m_PadSketchModePenSize = defaultPenSize;
+
+ for( MODULE* module = (MODULE*) Pcb->m_Modules; module; module = module->Next() )
+ {
+ Print_Module( m_canvas, aDC, module, drawmode, aPrintMask, drillShapeOpt );
+ }
+
+ D_PAD::m_PadSketchModePenSize = tmp;
+
+ /* Print via holes in bg color: Not sure it is good for buried or blind
+ * vias */
+ if( drillShapeOpt != PRINT_PARAMETERS::NO_DRILL_SHAPE )
+ {
+ TRACK* track = Pcb->m_Track;
+ EDA_COLOR_T color = WHITE;
+
+ bool blackpenstate = GetGRForceBlackPenState();
+
+ GRForceBlackPen( false );
+
+ for( ; track; track = track->Next() )
+ {
+ if( !( aPrintMask & track->GetLayerSet() ).any() )
+ continue;
+
+ if( track->Type() == PCB_VIA_T ) // VIA encountered.
+ {
+ int diameter;
+ const VIA *via = static_cast<const VIA*>( track );
+
+ if( drillShapeOpt == PRINT_PARAMETERS::SMALL_DRILL_SHAPE )
+ diameter = std::min( SMALL_DRILL, via->GetDrillValue() );
+ else
+ diameter = via->GetDrillValue();
+
+ GRFilledCircle( m_canvas->GetClipBox(), aDC,
+ track->GetStart().x, track->GetStart().y,
+ diameter/2,
+ 0, color, color );
+ }
+ }
+
+ GRForceBlackPen( blackpenstate );
+ }
+
+ m_canvas->SetPrintMirrored( false );
+
+ *displ_opts = save_opt;
+ GetScreen()->m_Active_Layer = activeLayer;
+
+ GetBoard()->SetElementVisibility( NO_CONNECTS_VISIBLE, nctmp );
+ GetBoard()->SetElementVisibility( ANCHOR_VISIBLE, anchorsTmp );
+}
+
+
+static void Print_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, MODULE* aModule,
+ GR_DRAWMODE aDraw_mode, LSET aMask,
+ PRINT_PARAMETERS::DrillShapeOptT aDrillShapeOpt )
+{
+ // Print pads
+ for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
+ {
+ if( !( pad->GetLayerSet() & aMask ).any() )
+ continue;
+
+ // Manage hole according to the print drill option
+ wxSize drill_tmp = pad->GetDrillSize();
+
+ switch( aDrillShapeOpt )
+ {
+ case PRINT_PARAMETERS::NO_DRILL_SHAPE:
+ pad->SetDrillSize( wxSize(0,0) );
+ break;
+
+ case PRINT_PARAMETERS::SMALL_DRILL_SHAPE:
+ {
+ wxSize sz( std::min( SMALL_DRILL, pad->GetDrillSize().x ),
+ std::min( SMALL_DRILL, pad->GetDrillSize().y ) );
+
+ pad->SetDrillSize( sz );
+ }
+ break;
+
+ case PRINT_PARAMETERS::FULL_DRILL_SHAPE:
+ // Do nothing
+ break;
+ }
+
+ pad->Draw( aPanel, aDC, aDraw_mode );
+ pad->SetDrillSize( drill_tmp );
+ }
+
+ if( aModule->Reference().IsVisible() && aMask[aModule->Reference().GetLayer()] )
+ aModule->Reference().Draw( aPanel, aDC, aDraw_mode );
+
+ if( aModule->Value().IsVisible() && aMask[aModule->Value().GetLayer()] )
+ aModule->Value().Draw( aPanel, aDC, aDraw_mode );
+
+ for( EDA_ITEM* item = aModule->GraphicalItems(); item; item = item->Next() )
+ {
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ {
+ TEXTE_MODULE* textMod = static_cast<TEXTE_MODULE*>( item );
+
+ if( !aMask[textMod->GetLayer()] )
+ break;
+
+ textMod->Draw( aPanel, aDC, aDraw_mode );
+ break;
+ }
+
+ case PCB_MODULE_EDGE_T:
+ {
+ EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( item );
+
+ if( !aMask[edge->GetLayer()] )
+ break;
+
+ edge->Draw( aPanel, aDC, aDraw_mode );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
diff --git a/pcbnew/printout_controler.cpp b/pcbnew/printout_controler.cpp
new file mode 100644
index 0000000..7ad346f
--- /dev/null
+++ b/pcbnew/printout_controler.cpp
@@ -0,0 +1,353 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file printout_controler.cpp
+ * @brief Board print handler implementation file.
+ */
+
+
+// Set this to 1 if you want to test PostScript printing under MSW.
+#define wxTEST_POSTSCRIPT_IN_MSW 1
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <gr_basic.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <base_units.h>
+#include <wxBasePcbFrame.h>
+#include <class_board.h>
+#include <pcbnew.h>
+
+#include <printout_controler.h>
+
+
+/**
+ * Definition for enabling and disabling print controller trace output. See the
+ * wxWidgets documentation on using the WXTRACE environment variable.
+ */
+static const wxString tracePrinting( wxT( "KicadPrinting" ) );
+
+
+PRINT_PARAMETERS::PRINT_PARAMETERS()
+{
+ m_PenDefaultSize = Millimeter2iu( 0.2 ); // A reasonable default value to draw items
+ // which do not have a specified line width
+ m_PrintScale = 1.0;
+ m_XScaleAdjust = 1.0;
+ m_YScaleAdjust = 1.0;
+ m_Print_Sheet_Ref = false;
+ m_PrintMaskLayer.set();
+ m_PrintMirror = false;
+ m_Print_Black_and_White = true;
+ m_OptionPrintPage = 1;
+ m_PageCount = 1;
+ m_ForceCentered = false;
+ m_Flags = 0;
+ m_DrillShapeOpt = PRINT_PARAMETERS::SMALL_DRILL_SHAPE;
+ m_PageSetupData = NULL;
+}
+
+
+BOARD_PRINTOUT_CONTROLLER::BOARD_PRINTOUT_CONTROLLER( const PRINT_PARAMETERS& aParams,
+ EDA_DRAW_FRAME* aParent,
+ const wxString& aTitle ) :
+ wxPrintout( aTitle )
+{
+ m_PrintParams = aParams; // Make a local copy of the print parameters.
+ m_Parent = aParent;
+}
+
+
+bool BOARD_PRINTOUT_CONTROLLER::OnPrintPage( int aPage )
+{
+ LSET lset = m_PrintParams.m_PrintMaskLayer;
+
+ // compute layer mask from page number if we want one page per layer
+ if( m_PrintParams.m_OptionPrintPage == 0 ) // One page per layer
+ {
+ // This sequence is TBD, call a different
+ // sequencer if needed, such as Seq(). Could not find documentation on
+ // page order.
+ LSEQ seq = lset.UIOrder();
+
+ // aPage starts at 1, not 0
+ if( unsigned( aPage-1 ) < seq.size() )
+ m_PrintParams.m_PrintMaskLayer = LSET( seq[aPage-1] );
+ }
+
+ if( !m_PrintParams.m_PrintMaskLayer.any() )
+ return false;
+
+ // In Pcbnew we can want the layer EDGE always printed
+ if( m_PrintParams.m_Flags == 1 )
+ m_PrintParams.m_PrintMaskLayer.set( Edge_Cuts );
+
+ DrawPage();
+
+ m_PrintParams.m_PrintMaskLayer = lset;
+
+ return true;
+}
+
+
+void BOARD_PRINTOUT_CONTROLLER::GetPageInfo( int* minPage, int* maxPage,
+ int* selPageFrom, int* selPageTo )
+{
+ *minPage = 1;
+ *selPageFrom = 1;
+
+ int icnt = 1;
+
+ if( m_PrintParams.m_OptionPrintPage == 0 )
+ icnt = m_PrintParams.m_PageCount;
+
+ *maxPage = icnt;
+ *selPageTo = icnt;
+}
+
+
+void BOARD_PRINTOUT_CONTROLLER::DrawPage()
+{
+ wxPoint offset;
+ double userscale;
+ EDA_RECT boardBoundingBox;
+ EDA_RECT drawRect;
+ wxDC* dc = GetDC();
+ BASE_SCREEN* screen = m_Parent->GetScreen();
+ bool printMirror = m_PrintParams.m_PrintMirror;
+ wxSize pageSizeIU = m_Parent->GetPageSizeIU();
+
+ wxBusyCursor dummy;
+
+ BOARD* brd = ((PCB_BASE_FRAME*) m_Parent)->GetBoard();
+ boardBoundingBox = brd->ComputeBoundingBox();
+ wxString titleblockFilename = brd->GetFileName();
+
+ // Use the page size as the drawing area when the board is shown or the user scale
+ // is less than 1.
+ if( m_PrintParams.PrintBorderAndTitleBlock() )
+ boardBoundingBox = EDA_RECT( wxPoint( 0, 0 ), pageSizeIU );
+
+ wxLogTrace( tracePrinting, wxT( "Drawing bounding box: x=%d, y=%d, w=%d, h=%d" ),
+ boardBoundingBox.GetX(), boardBoundingBox.GetY(),
+ boardBoundingBox.GetWidth(), boardBoundingBox.GetHeight() );
+
+ // Compute the PCB size in internal units
+ userscale = m_PrintParams.m_PrintScale;
+
+ if( m_PrintParams.m_PrintScale == 0 ) // fit in page option
+ {
+ if( boardBoundingBox.GetWidth() && boardBoundingBox.GetHeight() )
+ {
+ int margin = Millimeter2iu( 10.0 ); // add a margin around the drawings
+ double scaleX = (double)(pageSizeIU.x - (2 * margin)) /
+ boardBoundingBox.GetWidth();
+ double scaleY = (double)(pageSizeIU.y - (2 * margin)) /
+ boardBoundingBox.GetHeight();
+ userscale = (scaleX < scaleY) ? scaleX : scaleY;
+ }
+ else
+ userscale = 1.0;
+ }
+
+ wxSize scaledPageSize = pageSizeIU;
+ drawRect.SetSize( scaledPageSize );
+ scaledPageSize.x = wxRound( scaledPageSize.x / userscale );
+ scaledPageSize.y = wxRound( scaledPageSize.y / userscale );
+
+
+ if( m_PrintParams.m_PageSetupData )
+ {
+ wxLogTrace( tracePrinting, wxT( "Fit size to page margins: x=%d, y=%d" ),
+ scaledPageSize.x, scaledPageSize.y );
+
+ // Always scale to the size of the paper.
+ FitThisSizeToPageMargins( scaledPageSize, *m_PrintParams.m_PageSetupData );
+ }
+
+ // Compute Accurate scale 1
+ if( m_PrintParams.m_PrintScale == 1.0 )
+ {
+ // We want a 1:1 scale, regardless the page setup
+ // like page size, margin ...
+ MapScreenSizeToPaper(); // set best scale and offset (scale is not used)
+ int w, h;
+ GetPPIPrinter( &w, &h );
+ double accurate_Xscale = (double) w / (IU_PER_MILS*1000);
+ double accurate_Yscale = (double) h / (IU_PER_MILS*1000);
+
+ if( IsPreview() ) // Scale must take in account the DC size in Preview
+ {
+ // Get the size of the DC in pixels
+ wxSize PlotAreaSize;
+ dc->GetSize( &PlotAreaSize.x, &PlotAreaSize.y );
+ GetPageSizePixels( &w, &h );
+ accurate_Xscale *= (double)PlotAreaSize.x / w;
+ accurate_Yscale *= (double)PlotAreaSize.y / h;
+ }
+ // Fine scale adjust
+ accurate_Xscale *= m_PrintParams.m_XScaleAdjust;
+ accurate_Yscale *= m_PrintParams.m_YScaleAdjust;
+
+ // Set print scale for 1:1 exact scale
+ dc->SetUserScale( accurate_Xscale, accurate_Yscale );
+ }
+
+ // Get the final size of the DC in pixels
+ wxSize PlotAreaSizeInPixels;
+ dc->GetSize( &PlotAreaSizeInPixels.x, &PlotAreaSizeInPixels.y );
+ wxLogTrace( tracePrinting, wxT( "Plot area in pixels: x=%d, y=%d" ),
+ PlotAreaSizeInPixels.x, PlotAreaSizeInPixels.y );
+ double scalex, scaley;
+ dc->GetUserScale( &scalex, &scaley );
+ wxLogTrace( tracePrinting, wxT( "DC user scale: x=%g, y=%g" ),
+ scalex, scaley );
+
+ wxSize PlotAreaSizeInUserUnits;
+ PlotAreaSizeInUserUnits.x = KiROUND( PlotAreaSizeInPixels.x / scalex );
+ PlotAreaSizeInUserUnits.y = KiROUND( PlotAreaSizeInPixels.y / scaley );
+ wxLogTrace( tracePrinting, wxT( "Scaled plot area in user units: x=%d, y=%d" ),
+ PlotAreaSizeInUserUnits.x, PlotAreaSizeInUserUnits.y );
+
+ // In module editor, the module is located at 0,0 but for printing
+ // it is moved to pageSizeIU.x/2, pageSizeIU.y/2.
+ // So the equivalent board must be moved to the center of the page:
+ if( m_Parent->IsType( FRAME_PCB_MODULE_EDITOR ) )
+ {
+ boardBoundingBox.Move( wxPoint( pageSizeIU.x/2, pageSizeIU.y/2 ) );
+ }
+
+ // In some cases the plot origin is the centre of the board outline rather than the center
+ // of the selected paper size.
+ if( m_PrintParams.CenterOnBoardOutline() )
+ {
+ // Here we are only drawing the board and it's contents.
+ drawRect = boardBoundingBox;
+ offset.x += wxRound( (double) -scaledPageSize.x / 2.0 );
+ offset.y += wxRound( (double) -scaledPageSize.y / 2.0 );
+
+ wxPoint center = boardBoundingBox.Centre();
+
+ if( printMirror )
+ {
+ // Calculate the mirrored center of the board.
+ center.x = m_Parent->GetPageSizeIU().x - boardBoundingBox.Centre().x;
+ }
+
+ offset += center;
+ }
+
+ GRResetPenAndBrush( dc );
+
+ EDA_DRAW_PANEL* panel = m_Parent->GetCanvas();
+ EDA_RECT tmp = *panel->GetClipBox();
+
+ // Set clip box to the max size
+ #define MAX_VALUE (INT_MAX/2) // MAX_VALUE is the max we can use in an integer
+ // and that allows calculations without overflow
+ panel->SetClipBox( EDA_RECT( wxPoint( 0, 0 ), wxSize( MAX_VALUE, MAX_VALUE ) ) );
+
+ screen->m_IsPrinting = true;
+ EDA_COLOR_T bg_color = m_Parent->GetDrawBgColor();
+
+ // Print frame reference, if requested, before
+ if( m_PrintParams.m_Print_Black_and_White )
+ GRForceBlackPen( true );
+
+ if( m_PrintParams.PrintBorderAndTitleBlock() )
+ m_Parent->DrawWorkSheet( dc, screen, m_PrintParams.m_PenDefaultSize,
+ IU_PER_MILS, titleblockFilename );
+
+ if( printMirror )
+ {
+ // To plot mirror, we reverse the x axis, and modify the plot x origin
+ dc->SetAxisOrientation( false, false);
+
+ /* Plot offset x is moved by the x plot area size in order to have
+ * the old draw area in the new draw area, because the draw origin has not moved
+ * (this is the upper left corner) but the X axis is reversed, therefore the plotting area
+ * is the x coordinate values from - PlotAreaSize.x to 0 */
+ int x_dc_offset = PlotAreaSizeInPixels.x;
+ x_dc_offset = KiROUND( x_dc_offset * userscale );
+ dc->SetDeviceOrigin( x_dc_offset, 0 );
+
+ wxLogTrace( tracePrinting, wxT( "Device origin: x=%d, y=%d" ),
+ x_dc_offset, 0 );
+
+ panel->SetClipBox( EDA_RECT( wxPoint( -MAX_VALUE/2, -MAX_VALUE/2 ),
+ panel->GetClipBox()->GetSize() ) );
+ }
+
+ // screen->m_DrawOrg = offset;
+ dc->SetLogicalOrigin( offset.x, offset.y );
+
+ wxLogTrace( tracePrinting, wxT( "Logical origin: x=%d, y=%d" ),
+ offset.x, offset.y );
+
+#if defined(wxUSE_LOG_TRACE) && defined( DEBUG )
+ wxRect paperRect = GetPaperRectPixels();
+ wxLogTrace( tracePrinting, wxT( "Paper rectangle: left=%d, top=%d, "
+ "right=%d, bottom=%d" ),
+ paperRect.GetLeft(), paperRect.GetTop(), paperRect.GetRight(),
+ paperRect.GetBottom() );
+
+ int devLeft = dc->LogicalToDeviceX( drawRect.GetX() );
+ int devTop = dc->LogicalToDeviceY( drawRect.GetY() );
+ int devRight = dc->LogicalToDeviceX( drawRect.GetRight() );
+ int devBottom = dc->LogicalToDeviceY( drawRect.GetBottom() );
+ wxLogTrace( tracePrinting, wxT( "Final device rectangle: left=%d, top=%d, "
+ "right=%d, bottom=%d\n" ),
+ devLeft, devTop, devRight, devBottom );
+#endif
+
+ m_Parent->SetDrawBgColor( WHITE );
+
+ /* when printing in color mode, we use the graphic OR mode that gives the same look as
+ * the screen but because the background is white when printing, we must use a trick:
+ * In order to plot on a white background in OR mode we must:
+ * 1 - Plot all items in black, this creates a local black background
+ * 2 - Plot in OR mode on black "local" background
+ */
+ if( !m_PrintParams.m_Print_Black_and_White )
+ {
+ // Creates a "local" black background
+ GRForceBlackPen( true );
+ m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer,
+ printMirror, &m_PrintParams );
+ GRForceBlackPen( false );
+ }
+ else
+ GRForceBlackPen( true );
+
+
+ m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror,
+ &m_PrintParams );
+
+ m_Parent->SetDrawBgColor( bg_color );
+ screen->m_IsPrinting = false;
+ panel->SetClipBox( tmp );
+ GRForceBlackPen( false );
+}
diff --git a/pcbnew/printout_controler.h b/pcbnew/printout_controler.h
new file mode 100644
index 0000000..a9cd6c2
--- /dev/null
+++ b/pcbnew/printout_controler.h
@@ -0,0 +1,129 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/**
+ * @file printout_controler.h
+ * @brief Board print handler definition file.
+ */
+
+#ifndef PRINTOUT_CONTROLLER_H
+#define PRINTOUT_CONTROLLER_H
+
+
+#include <wx/dcps.h>
+#include <layers_id_colors_and_visibility.h>
+#include <wx/print.h>
+
+#define DEFAULT_ORIENTATION_PAPER wxLANDSCAPE // other option is wxPORTRAIT
+
+
+/**
+ * Class PRINT_PARAMETERS
+ * handles the parameters used to print a board drawing.
+ */
+
+class PRINT_PARAMETERS
+{
+public:
+ int m_PenDefaultSize; // The default value pen size to plot/print items
+ // that have no defined pen size
+ double m_PrintScale; // general scale when printing
+ double m_XScaleAdjust; // fine scale adjust for X axis
+ double m_YScaleAdjust; // fine scale adjust for Y axis
+ bool m_Print_Sheet_Ref; // Option: print page references
+ LSET m_PrintMaskLayer; // Layers to print
+ bool m_PrintMirror; // Option: Print mirrored
+ bool m_Print_Black_and_White; // Option: Print in B&W or Color
+ int m_OptionPrintPage; // Option: 0 = a layer per page, 1 = all layers at once
+ int m_PageCount; // Number of pages to print
+ bool m_ForceCentered; // Force plot origin to page centre (used in modedit)
+ int m_Flags; // Can be used to pass some other info
+ wxPageSetupDialogData* m_PageSetupData; // A wxPageSetupDialogData for page options (margins)
+
+ enum DrillShapeOptT {
+ NO_DRILL_SHAPE = 0,
+ SMALL_DRILL_SHAPE = 1,
+ FULL_DRILL_SHAPE = 2
+ };
+
+ DrillShapeOptT m_DrillShapeOpt; // Options to print pads and via holes
+
+public:
+ PRINT_PARAMETERS();
+
+ /**
+ * Function PrintBorderAndTitleBlock
+ * returns true if the drawing border and title block should be printed.
+ *
+ * For scale factors greater than one, the border is not printed because it will end up
+ * scaling off of the page.
+ */
+ bool PrintBorderAndTitleBlock() const { return m_PrintScale <= 1.0 && m_Print_Sheet_Ref; }
+
+ /**
+ * Function CenterOnBoardOutline
+ * returns true if the print should be centered by the board outline instead of the
+ * paper size.
+ */
+ bool CenterOnBoardOutline() const
+ {
+ return !PrintBorderAndTitleBlock() && ( m_ForceCentered || (m_PrintScale > 1.0) ||
+ (m_PrintScale == 0) );
+ }
+};
+
+
+/**
+ * Class BOARD_PRINTOUT_CONTROLLER
+ * is a class derived from wxPrintout to handle the necessary information to control a printer
+ * when printing a board
+ */
+class BOARD_PRINTOUT_CONTROLLER : public wxPrintout
+{
+private:
+ EDA_DRAW_FRAME* m_Parent;
+ PRINT_PARAMETERS m_PrintParams;
+
+public:
+ BOARD_PRINTOUT_CONTROLLER( const PRINT_PARAMETERS& aParams,
+ EDA_DRAW_FRAME* aParent,
+ const wxString& aTitle );
+
+ bool OnPrintPage( int aPage );
+
+ bool HasPage( int aPage ) // do not test page num
+ {
+ if( aPage <= m_PrintParams.m_PageCount )
+ return true;
+ else
+ return false;
+ }
+
+ void GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo );
+
+ void DrawPage();
+};
+
+#endif // PRINTOUT_CONTROLLER_H
diff --git a/pcbnew/protos.h b/pcbnew/protos.h
new file mode 100644
index 0000000..0dfb258
--- /dev/null
+++ b/pcbnew/protos.h
@@ -0,0 +1,82 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007 Jean-Pierre Charras, jp.charras@wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew/protos.h
+ */
+
+#ifndef PROTO_H
+#define PROTO_H
+#include <gr_basic.h>
+
+class wxDC;
+class wxPoint;
+class EDA_DRAW_PANEL;
+class BOARD_ITEM;
+class TRACK;
+class MODULE;
+
+
+/***************/
+/* TRPISTE.CPP */
+/***************/
+
+/**
+ * Function DrawTraces
+ * Draws n consecutive track segments in list.
+ * Useful to show a track when it is a chain of segments
+ * (for instance when creating a new track)
+ *
+ * @param panel A EDA_DRAW_ITEM pointer to the canvas.
+ * @param DC A wxDC pointer of the device context used for drawing.
+ * @param aStartTrace First segment
+ * @param nbsegment Number of segments in list
+ * @param mode_color Drawing mode (GRXOR, GROR ..)
+ */
+
+void DrawTraces( EDA_DRAW_PANEL* panel,
+ wxDC* DC,
+ TRACK* aStartTrace,
+ int nbsegment,
+ GR_DRAWMODE mode_color );
+
+void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
+ bool aErase );
+
+/**
+ * Determine coordinate for a segment direction of 0, 90, or 45 degrees
+ * depending on it's position from the origin (ox, oy) and \a aPosiition.
+ */
+void CalculateSegmentEndPoint( const wxPoint& aPosition, int ox, int oy, int* fx, int* fy );
+
+/**
+ * Finds the projection of a grid point on a track. This is the point
+ * from where we want to draw new orthogonal tracks when starting on a track.
+ */
+bool Project( wxPoint* res, wxPoint on_grid, const TRACK* track );
+TRACK* LocateIntrusion( TRACK* listStart, TRACK* aTrack, LAYER_NUM aLayer, const wxPoint& aRef );
+
+
+
+#endif /* #define PROTO_H */
diff --git a/pcbnew/ratsnest.cpp b/pcbnew/ratsnest.cpp
new file mode 100644
index 0000000..b388085
--- /dev/null
+++ b/pcbnew/ratsnest.cpp
@@ -0,0 +1,929 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file ratsnest.cpp
+ * @brief Ratsnets functions.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <colors_selection.h>
+#include <wxBasePcbFrame.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+
+#include <pcbnew.h>
+
+#include <minimun_spanning_tree.h>
+
+/**
+ * @brief class MIN_SPAN_TREE_PADS (derived from MIN_SPAN_TREE) specializes
+ * the base class to calculate a minimum spanning tree from a list of pads,
+ * and to add this tree as ratsnest to the main ratsnest list.
+ */
+class MIN_SPAN_TREE_PADS: public MIN_SPAN_TREE
+{
+ friend class MIN_SPAN_TREE;
+public:
+ std::vector <D_PAD*>* m_PadsList; // list of pads:
+ /* these pads are the parents of nodes of the tree.
+ * Each node position is the corresponding pad position.
+ * This pad list is used to evaluate the weight of an edge in tree.
+ * -> edge = link between 2 nodes = links between 2 pads.
+ * -> weight of a link = rectilinear distance between the 2 pads
+ */
+
+public:
+ MIN_SPAN_TREE_PADS(): MIN_SPAN_TREE()
+ {
+ m_PadsList = NULL;
+ }
+
+ void MSP_Init( std::vector <D_PAD*>* aPadsList )
+ {
+ m_PadsList = aPadsList;
+ MIN_SPAN_TREE::MSP_Init( (int) m_PadsList->size() );
+ }
+
+ /**
+ * Function AddTreeToRatsnest
+ * Adds the current minimum spanning tree as ratsnest items
+ * to the main ratsnest list
+ * @param aRatsnestList = a ratsnest list to add to
+ */
+ void AddTreeToRatsnest( std::vector<RATSNEST_ITEM>* aRatsnestList );
+
+ /**
+ * Function GetWeight
+ * calculates the weight between 2 items
+ * NOTE: The weight between a node and itself should be 0
+ * @param aItem1 = first item
+ * @param aItem2 = other item
+ * @return the weight between items ( the rectilinear distance )
+ */
+ int GetWeight( int aItem1, int aItem2 );
+};
+
+
+void MIN_SPAN_TREE_PADS::AddTreeToRatsnest( std::vector<RATSNEST_ITEM>* aRatsnestList )
+{
+ std::vector<D_PAD*>& padsBuffer = *m_PadsList;
+
+ if( padsBuffer.empty() )
+ return;
+
+ int netcode = padsBuffer[0]->GetNetCode();
+
+ // Note: to get edges in minimum spanning tree,
+ // the index value 0 is not used: it is just
+ // the entry point of the minimum spanning tree.
+ // The first edge (i.e. rastnest) starts at index 1
+ for( int ii = 1; ii < m_Size; ii++ )
+ {
+ // Create the new ratsnest
+ RATSNEST_ITEM net;
+
+ net.SetNet( netcode );
+ net.m_Status = CH_ACTIF | CH_VISIBLE;
+ net.m_Lenght = GetDist(ii);
+ net.m_PadStart = padsBuffer[ii];
+ net.m_PadEnd = padsBuffer[ GetWhoTo(ii) ];
+
+ aRatsnestList->push_back( net );
+ }
+}
+
+/* Function GetWeight
+ * calculates the weight between 2 items
+ * Here it calculate the rectilinear distance between 2 pads (2 items)
+ * NOTE: The weight between a node and itself should be <=0
+ * aItem1 and aItem2 are the 2 items
+ * return the rectilinear distance
+ */
+int MIN_SPAN_TREE_PADS::GetWeight( int aItem1, int aItem2 )
+{
+ // NOTE: The distance (weight) between a node and itself should be 0
+ // so we add 1 to other distances to be sure we never have 0
+ // in cases other than a node and itself
+
+ D_PAD* pad1 = (*m_PadsList)[aItem1];
+ D_PAD* pad2 = (*m_PadsList)[aItem2];
+
+ if( pad1 == pad2 )
+ return 0;
+
+ int weight = abs( pad2->GetPosition().x - pad1->GetPosition().x ) +
+ abs( pad2->GetPosition().y - pad1->GetPosition().y );
+ return weight + 1;
+}
+
+
+/* Note about the ratsnest computation:
+ * Building the general ratsnest:
+ * For each net, the ratsnest is the set of lines connecting pads,
+ * using the shorter distance
+ * Therefore this problem is well known in graph therory, and sloved
+ * using the "minimum spanning tree".
+ * We use here an algorithm to build the minimum spanning tree known as Prim's algorithm
+ */
+
+/**
+ * Function Compile_Ratsnest
+ * Create the entire board ratsnest.
+ * Must be called after a board change (changes for
+ * pads, footprints or a read netlist ).
+ * @param aDC = the current device context (can be NULL)
+ * @param aDisplayStatus : if true, display the computation results
+ */
+void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus )
+{
+ wxString msg;
+
+ GetBoard()->m_Status_Pcb = 0; // we want a full ratsnest computation, from the scratch
+ ClearMsgPanel();
+
+ // Rebuild the full pads and net info list
+ RecalculateAllTracksNetcode();
+
+ if( aDisplayStatus )
+ {
+ msg.Printf( wxT( " %d" ), m_Pcb->GetPadCount() );
+ AppendMsgPanel( wxT( "Pads" ), msg, RED );
+ msg.Printf( wxT( " %d" ), m_Pcb->GetNetCount() );
+ AppendMsgPanel( wxT( "Nets" ), msg, CYAN );
+ }
+
+ /* Compute the full ratsnest
+ * which can be see like all the possible links or logical connections.
+ * some of them are active (no track connected) and others are inactive
+ * (when tracks connect pads)
+ * This full ratsnest is not modified by track editing.
+ * It changes only when a netlist is read, or footprints are modified
+ */
+ Build_Board_Ratsnest();
+
+ // Compute the pad connections due to the existing tracks (physical connections)
+ TestConnections();
+
+ /* Compute the active ratsnest, i.e. the unconnected links
+ */
+ TestForActiveLinksInRatsnest( 0 );
+
+ // Redraw the active ratsnest ( if enabled )
+ if( GetBoard()->IsElementVisible(RATSNEST_VISIBLE) && aDC )
+ DrawGeneralRatsnest( aDC, 0 );
+
+ if( aDisplayStatus )
+ SetMsgPanel( m_Pcb );
+}
+
+
+/* Sort function used by QSORT
+ * Sort pads by net code
+ */
+static bool sortByNetcode( const D_PAD* const & ref, const D_PAD* const & item )
+{
+ return ref->GetNetCode() < item->GetNetCode();
+}
+
+
+/**
+ * Function to compute the full ratsnest
+ * This is the "basic" ratsnest depending only on pads.
+ *
+ * Create the sorted pad list (if necessary)
+ * The active pads (i.e included in a net ) are called nodes
+ * This pad list is sorted by net codes
+ * A ratsnest can be seen as a logical connection.
+ *
+ * Update :
+ * nb_nodes = Active pads count for the board
+ * nb_links = link count for the board (logical connection count)
+ * (there are n-1 links in a net which counting n active pads) .
+ */
+void PCB_BASE_FRAME::Build_Board_Ratsnest()
+{
+ D_PAD* pad;
+ int noconn;
+
+ m_Pcb->SetUnconnectedNetCount( 0 );
+
+ m_Pcb->m_FullRatsnest.clear();
+
+ if( m_Pcb->GetPadCount() == 0 )
+ return;
+
+ // Created pad list and the net_codes if needed
+ if( (m_Pcb->m_Status_Pcb & NET_CODES_OK) == 0 )
+ m_Pcb->BuildListOfNets();
+
+ for( unsigned ii = 0; ii<m_Pcb->GetPadCount(); ++ii )
+ {
+ pad = m_Pcb->GetPad( ii );
+ pad->SetSubRatsnest( 0 );
+ }
+
+ if( m_Pcb->GetNodesCount() == 0 )
+ return; // No useful connections.
+
+ // Ratsnest computation
+ unsigned current_net_code = 1; // First net code is analyzed.
+ // (net_code = 0 -> no connect)
+ noconn = 0;
+ MIN_SPAN_TREE_PADS min_spanning_tree;
+
+ for( ; current_net_code < m_Pcb->GetNetCount(); current_net_code++ )
+ {
+ NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code );
+
+ if( !net ) // Should not occur
+ {
+ UTF8 msg = StrPrintf( "%s: error, net %d not found", __func__, current_net_code );
+ wxMessageBox( msg ); // BTW, it does happen.
+ return;
+ }
+
+ net->m_RatsnestStartIdx = m_Pcb->GetRatsnestsCount();
+
+ min_spanning_tree.MSP_Init( &net->m_PadInNetList );
+ min_spanning_tree.BuildTree();
+ min_spanning_tree.AddTreeToRatsnest( &m_Pcb->m_FullRatsnest );
+ net->m_RatsnestEndIdx = m_Pcb->GetRatsnestsCount();
+ }
+
+ m_Pcb->SetUnconnectedNetCount( noconn );
+ m_Pcb->m_Status_Pcb |= LISTE_RATSNEST_ITEM_OK;
+
+ // Update the ratsnest display option (visible/invisible) flag
+ for( unsigned ii = 0; ii < m_Pcb->GetRatsnestsCount(); ii++ )
+ {
+ if( !GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) ) // Clear VISIBLE flag
+ m_Pcb->m_FullRatsnest[ii].m_Status &= ~CH_VISIBLE;
+ }
+}
+
+
+/**
+ * function DrawGeneralRatsnest
+ * Only ratsnest items with the status bit CH_VISIBLE set are displayed
+ * @param aDC = the current device context (can be NULL)
+ * @param aNetcode: if > 0, Display only the ratsnest relative to the
+ * corresponding net_code
+ */
+void PCB_BASE_FRAME::DrawGeneralRatsnest( wxDC* aDC, int aNetcode )
+{
+ if( ( m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
+ return;
+
+ if( ( m_Pcb->m_Status_Pcb & DO_NOT_SHOW_GENERAL_RASTNEST ) )
+ return;
+
+ if( aDC == NULL )
+ return;
+
+ const int state = CH_VISIBLE | CH_ACTIF;
+
+ for( unsigned ii = 0; ii < m_Pcb->GetRatsnestsCount(); ii++ )
+ {
+ RATSNEST_ITEM& item = m_Pcb->m_FullRatsnest[ii];
+
+ if( ( item.m_Status & state ) != state )
+ continue;
+
+ if( ( aNetcode <= 0 ) || ( aNetcode == item.GetNet() ) )
+ {
+ item.Draw( m_canvas, aDC, GR_XOR, wxPoint( 0, 0 ) );
+ }
+ }
+}
+
+
+/**
+ * Function used by TestForActiveLinksInRatsnest
+ * Function testing the ratsnest between 2 blocks ( of the same net )
+ * The search is made between pads in block 1 and the others blocks
+ * The block n ( n > 1 ) is merged with block 1 and linked by the smallest ratsnest
+ * between block 1 and the block n (activate the logical connection)
+ * @param aRatsnestBuffer = the buffer to store NETINFO_ITEM* items
+ * @param aNetinfo = the current NETINFO_ITEM for the current net
+ * output: .state member, bit CH_ACTIF of the ratsnest item
+ * @return last subratsnest id in use
+ */
+static int tst_links_between_blocks( NETINFO_ITEM* aNetinfo,
+ std::vector<RATSNEST_ITEM>& aRatsnestBuffer )
+{
+ int subratsnest_id, min_id;
+ RATSNEST_ITEM* link, * best_link;
+
+ // Search a link from a block to an other block
+ best_link = NULL;
+
+ for( unsigned ii = aNetinfo->m_RatsnestStartIdx; ii < aNetinfo->m_RatsnestEndIdx; ii++ )
+ {
+ link = &aRatsnestBuffer[ii];
+
+ // If this link joints 2 pads inside the same block, do nothing
+ // (these pads are already connected)
+ if( link->m_PadStart->GetSubRatsnest() == link->m_PadEnd->GetSubRatsnest() )
+ continue;
+
+ // This link joints 2 pads of different blocks: this is a candidate,
+ // but we want to select the shorter link, so use it only if it is shorter
+ // than the previous candidate:
+ if( best_link == NULL ) // no candidate
+ best_link = link;
+ else if( best_link->m_Lenght > link->m_Lenght ) // It is a better candidate.
+ best_link = link;
+ }
+
+ if( best_link == NULL )
+ return 1;
+
+ /* At this point we have found a link between 2 different blocks (subratsnest)
+ * we must set its status to ACTIVE and merge the 2 blocks
+ */
+ best_link->m_Status |= CH_ACTIF;
+ subratsnest_id = best_link->m_PadStart->GetSubRatsnest();
+ min_id = best_link->m_PadEnd->GetSubRatsnest();
+
+ if( min_id > subratsnest_id )
+ std::swap( min_id, subratsnest_id );
+
+ // Merge the 2 blocks in one sub ratsnest:
+ for( unsigned ii = 0; ii < aNetinfo->m_PadInNetList.size(); ii++ )
+ {
+ if( aNetinfo->m_PadInNetList[ii]->GetSubRatsnest() == subratsnest_id )
+ {
+ aNetinfo->m_PadInNetList[ii]->SetSubRatsnest( min_id );
+ }
+ }
+
+ return subratsnest_id;
+}
+
+
+/**
+ * Function used by TestForActiveLinksInRatsnest_general
+ * The general ratsnest list must exists because this function explores this ratsnest
+ * Activates (i.e. set the CH_ACTIF flag) the ratsnest links between 2 pads when
+ * at least one pad not already connected (SubRatsnest = 0)
+ * and actives the corresponding link
+ *
+ * @param aFirstItem = starting address for the ratsnest list
+ * @param aLastItem = ending address for the ratsnest list
+ * @param aCurrSubRatsnestId = last sub ratsnest id in use (computed from the track
+ * analysis)
+ *
+ * output:
+ * ratsnest list (status member bit CH_ACTIF set)
+ * and pads linked (m_SubRatsnest value set)
+ *
+ * @return new block number
+ */
+static void tst_links_between_pads( int & aCurrSubRatsnestId,
+ RATSNEST_ITEM* aFirstItem,
+ RATSNEST_ITEM* aLastItem )
+{
+ for( RATSNEST_ITEM* item = aFirstItem; item < aLastItem; item++ )
+ {
+ D_PAD* pad_start = item->m_PadStart;
+ D_PAD* pad_end = item->m_PadEnd;
+
+ /* Update the current SubRatsnest if the 2 pads are not connected :
+ * a new cluster is created and the link activated
+ */
+ if( (pad_start->GetSubRatsnest() == 0) && (pad_end->GetSubRatsnest() == 0) )
+ {
+ aCurrSubRatsnestId++;
+ pad_start->SetSubRatsnest( aCurrSubRatsnestId );
+ pad_end->SetSubRatsnest( aCurrSubRatsnestId );
+ item->m_Status |= CH_ACTIF;
+ }
+
+ /* If a pad is already connected to a subratsnest: activate the link
+ * the pad other is merged in the existing subratsnest
+ */
+ else if( pad_start->GetSubRatsnest() == 0 )
+ {
+ pad_start->SetSubRatsnest( pad_end->GetSubRatsnest() );
+ item->m_Status |= CH_ACTIF;
+ }
+ else if( pad_end->GetSubRatsnest() == 0 )
+ {
+ pad_end->SetSubRatsnest( pad_start->GetSubRatsnest() );
+ item->m_Status |= CH_ACTIF;
+ }
+ }
+}
+
+/* function TestForActiveLinksInRatsnest
+ * determine the active links inside the full ratsnest
+ *
+ * I used an algorithm inspired by the "Lee algorithm".
+ * The idea is all pads must be connected by a physical track or a logical track
+ * a physical track is the existing track on copper layers.
+ * a logical track is the link that must be activated (visible) if
+ * no track found between 2 pads.
+ * The algorithm explore the existing full ratnest
+ * This is a 2 steps algorithm (executed for each net).
+ * - First:
+ * Initialise for each pad the subratsnest id to its subnet value
+ * explore the full ratnest (relative to the net) and active a link each time at least one pad of
+ * the given link is not connected to an other pad by a track ( subratsnest = 0)
+ * If the 2 pads linked have both the subratsnest id = 0, a new subratsnest value is created
+ * - Second:
+ * explore the full ratnest (relative to the net) and find a link that links
+ * 2 pads having different subratsnest values
+ * Active the link and merge the 2 subratsnest value.
+ *
+ * This is usually fast because the ratsnest is not built here: it is just explored
+ * to see what link must be activated
+ */
+void PCB_BASE_FRAME::TestForActiveLinksInRatsnest( int aNetCode )
+{
+ RATSNEST_ITEM* rats;
+ D_PAD* pad;
+ NETINFO_ITEM* net;
+
+ if( m_Pcb->GetPadCount() == 0 )
+ return;
+
+ if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
+ Build_Board_Ratsnest();
+
+ for( int net_code = 1; net_code < (int) m_Pcb->GetNetCount(); net_code++ )
+ {
+ net = m_Pcb->FindNet( net_code );
+
+ wxCHECK_RET( net != NULL,
+ wxString::Format( wxT( "Net code %d not found!" ), net_code ) );
+
+ if( aNetCode && (net_code != aNetCode) )
+ continue;
+
+ // Create subratsnests id from subnets created by existing tracks:
+ int subratsnest = 0;
+ for( unsigned ip = 0; ip < net->m_PadInNetList.size(); ip++ )
+ {
+ pad = net->m_PadInNetList[ip];
+ int subnet = pad->GetSubNet();
+ pad->SetSubRatsnest( subnet );
+ subratsnest = std::max( subratsnest, subnet );
+ }
+
+ for( unsigned ii = net->m_RatsnestStartIdx; ii < net->m_RatsnestEndIdx; ii++ )
+ {
+ m_Pcb->m_FullRatsnest[ii].m_Status &= ~CH_ACTIF;
+ }
+
+ // First pass - activate links for not connected pads
+ rats = &m_Pcb->m_FullRatsnest[0];
+ tst_links_between_pads( subratsnest,
+ rats + net->m_RatsnestStartIdx,
+ rats + net->m_RatsnestEndIdx );
+
+ // Second pass activate links between blocks (Iteration)
+ while( subratsnest > 1 )
+ {
+ subratsnest = tst_links_between_blocks( net, m_Pcb->m_FullRatsnest );
+ }
+ }
+
+ m_Pcb->SetUnconnectedNetCount( 0 );
+
+ unsigned cnt = 0;
+
+ for( unsigned ii = 0; ii < m_Pcb->GetRatsnestsCount(); ii++ )
+ {
+ if( m_Pcb->m_FullRatsnest[ii].IsActive() )
+ cnt++;
+ }
+
+ m_Pcb->SetUnconnectedNetCount( cnt );
+}
+
+
+void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule )
+{
+ // for local ratsnest calculation when moving a footprint:
+ // list of pads to use for this local ratsnets:
+ // this is the list of connected pads of the current module,
+ // and all pads connected to these pads:
+ static std::vector <D_PAD*> localPadList;
+ static unsigned pads_module_count; // node count (node = pad with a net
+ // code) for the footprint being moved
+ static unsigned internalRatsCount; // number of internal links (links
+ // between pads of the module)
+ D_PAD* pad_ref;
+ D_PAD* pad_externe;
+ int current_net_code;
+ int distance;
+ wxPoint pad_pos; // True pad position according to the
+ // current footprint position
+
+ if( (GetBoard()->m_Status_Pcb & LISTE_PAD_OK) == 0 )
+ {
+ GetBoard()->m_Status_Pcb = 0;
+ GetBoard()->BuildListOfNets();
+ }
+
+ /* Compute the "local" ratsnest if needed (when this footprint starts move)
+ * and the list of external pads to consider, i.e pads in others
+ * footprints which are "connected" to
+ * a pad in the current footprint
+ */
+ if( (m_Pcb->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK) == 0 )
+ {
+ // Compute the "internal" ratsnest, i.e the links between the current
+ // footprint pads
+ localPadList.clear();
+ m_Pcb->m_LocalRatsnest.clear();
+
+ // collect active pads of the module:
+ for( pad_ref = aModule->Pads(); pad_ref; pad_ref = pad_ref->Next() )
+ {
+ if( pad_ref->GetNetCode() == NETINFO_LIST::UNCONNECTED )
+ continue;
+
+ localPadList.push_back( pad_ref );
+ pad_ref->SetSubRatsnest( 0 );
+ pad_ref->SetSubNet( 0 );
+ }
+
+ pads_module_count = localPadList.size();
+
+ if( pads_module_count == 0 )
+ return; // no connection!
+
+ sort( localPadList.begin(), localPadList.end(), sortByNetcode );
+
+ // Build the list of pads linked to the current footprint pads
+ current_net_code = 0;
+
+ for( unsigned ii = 0; ii < pads_module_count; ii++ )
+ {
+ pad_ref = localPadList[ii];
+
+ if( pad_ref->GetNetCode() == current_net_code )
+ continue;
+
+ // A new net was found, load all pads of others modules members of this net:
+ NETINFO_ITEM* net = pad_ref->GetNet();
+
+ if( net == NULL ) //Should not occur
+ {
+ wxMessageBox( wxT( "build_ratsnest_module() error: net not found" ) );
+ return;
+ }
+
+ for( unsigned jj = 0; jj < net->m_PadInNetList.size(); jj++ )
+ {
+ pad_externe = net->m_PadInNetList[jj];
+
+ if( pad_externe->GetParent() == aModule )
+ continue;
+
+ pad_externe->SetSubRatsnest( 0 );
+ pad_externe->SetSubNet( 0 );
+
+ localPadList.push_back( pad_externe );
+ }
+ }
+
+ // Sort the pad list by net_code
+ sort( localPadList.begin() + pads_module_count, localPadList.end(),
+ sortByNetcode );
+
+ /* Compute the internal rats nest:
+ * this is the same as general ratsnest, but considers only the current
+ * footprint pads it is therefore not time consuming, and it is made only
+ * once
+ */
+ current_net_code = localPadList[0]->GetNetCode();
+
+ MIN_SPAN_TREE_PADS min_spanning_tree;
+ std::vector<D_PAD*> padsBuffer; // contains pads of only one net
+
+ for( unsigned ii = 0; ii < pads_module_count; ii++ )
+ {
+ // Search the end of pad list relative to the current net
+ unsigned jj = ii + 1;
+
+ for( ; jj <= pads_module_count; jj++ )
+ {
+ if( jj >= pads_module_count )
+ break;
+
+ if( localPadList[jj]->GetNetCode() != current_net_code )
+ break;
+ }
+
+ for( unsigned kk = ii; kk < jj; kk++ )
+ padsBuffer.push_back( localPadList[kk] );
+
+ min_spanning_tree.MSP_Init( &padsBuffer );
+ min_spanning_tree.BuildTree();
+ min_spanning_tree.AddTreeToRatsnest( &m_Pcb->m_LocalRatsnest );
+ padsBuffer.clear();
+
+ ii = jj;
+
+ if( ii < localPadList.size() )
+ current_net_code = localPadList[ii]->GetNetCode();
+ }
+
+ internalRatsCount = m_Pcb->m_LocalRatsnest.size();
+
+ // set the flag LOCAL_RATSNEST_ITEM of the ratsnest status:
+ for( unsigned ii = 0; ii < m_Pcb->m_LocalRatsnest.size(); ii++ )
+ m_Pcb->m_LocalRatsnest[ii].m_Status = LOCAL_RATSNEST_ITEM;
+
+ m_Pcb->m_Status_Pcb |= RATSNEST_ITEM_LOCAL_OK;
+ } // End of internal ratsnest build
+
+ /* This section computes the "external" ratsnest: it is done when the
+ * footprint position changes
+ *
+ * This section search:
+ * for each current module pad the nearest neighbor external pad (of
+ * course for the same net code).
+ * For each current footprint cluster of pad (pads having the same net
+ * code),
+ * we search the smaller rats nest.
+ * so, for each net, only one rats nest item is created
+ */
+ RATSNEST_ITEM local_rats;
+
+ local_rats.m_Lenght = INT_MAX;
+ local_rats.m_Status = 0;
+ bool addRats = false;
+
+ // Erase external ratsnest items:
+ if( internalRatsCount < m_Pcb->m_LocalRatsnest.size() )
+ m_Pcb->m_LocalRatsnest.erase( m_Pcb->m_LocalRatsnest.begin() + internalRatsCount,
+ m_Pcb->m_LocalRatsnest.end() );
+
+ current_net_code = localPadList[0]->GetNetCode();
+
+ for( unsigned ii = 0; ii < pads_module_count; ii++ )
+ {
+ pad_ref = localPadList[ii];
+
+ if( pad_ref->GetNetCode() != current_net_code )
+ {
+ // if needed, creates a new ratsnest for the old net
+ if( addRats )
+ {
+ m_Pcb->m_LocalRatsnest.push_back( local_rats );
+ }
+
+ addRats = false;
+ current_net_code = pad_ref->GetNetCode();
+ local_rats.m_Lenght = INT_MAX;
+ }
+
+ pad_pos = pad_ref->GetPosition() - g_Offset_Module;
+
+ // Search the nearest external pad of this current pad
+ for( unsigned jj = pads_module_count; jj < localPadList.size(); jj++ )
+ {
+ pad_externe = localPadList[jj];
+
+ // we search pads having the same net code
+ if( pad_externe->GetNetCode() < pad_ref->GetNetCode() )
+ continue;
+
+ if( pad_externe->GetNetCode() > pad_ref->GetNetCode() ) // pads are sorted by net code
+ break;
+
+ distance = abs( pad_externe->GetPosition().x - pad_pos.x ) +
+ abs( pad_externe->GetPosition().y - pad_pos.y );
+
+ if( distance < local_rats.m_Lenght )
+ {
+ local_rats.m_PadStart = pad_ref;
+ local_rats.m_PadEnd = pad_externe;
+ local_rats.SetNet( pad_ref->GetNetCode() );
+ local_rats.m_Lenght = distance;
+ local_rats.m_Status = 0;
+
+ addRats = true;
+ }
+ }
+ }
+
+ if( addRats ) // Ensure the last created rats nest item is stored in buffer
+ m_Pcb->m_LocalRatsnest.push_back( local_rats );
+}
+
+
+void PCB_BASE_FRAME::TraceModuleRatsNest( wxDC* DC )
+{
+ if( DC == NULL )
+ return;
+
+ if( ( m_Pcb->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK ) == 0 )
+ return;
+
+ EDA_COLOR_T tmpcolor = g_ColorsSettings.GetItemColor(RATSNEST_VISIBLE);
+
+ for( unsigned ii = 0; ii < m_Pcb->m_LocalRatsnest.size(); ii++ )
+ {
+ RATSNEST_ITEM* rats = &m_Pcb->m_LocalRatsnest[ii];
+
+ if( rats->m_Status & LOCAL_RATSNEST_ITEM )
+ {
+ g_ColorsSettings.SetItemColor(RATSNEST_VISIBLE, YELLOW);
+ rats->Draw( m_canvas, DC, GR_XOR, g_Offset_Module );
+ }
+ else
+ {
+ g_ColorsSettings.SetItemColor(RATSNEST_VISIBLE, tmpcolor);
+
+ wxPoint tmp = rats->m_PadStart->GetPosition();
+
+ rats->m_PadStart->SetPosition( tmp - g_Offset_Module );
+ rats->Draw( m_canvas, DC, GR_XOR, wxPoint( 0, 0 ) );
+
+ rats->m_PadStart->SetPosition( tmp );
+ }
+ }
+
+ g_ColorsSettings.SetItemColor( RATSNEST_VISIBLE, tmpcolor );
+}
+
+
+/*
+ * PCB_BASE_FRAME::BuildAirWiresTargetsList and
+ * PCB_BASE_FRAME::TraceAirWiresToTargets
+ * are 2 function to show the near connecting points when
+ * a new track is created, by displaying g_MaxLinksShowed airwires
+ * between the on grid mouse cursor and these connecting points
+ * during the creation of a track
+ */
+
+/* Buffer to store pads coordinates when creating a track.
+ * these pads are members of the net
+ * and when the mouse is moved, the g_MaxLinksShowed links to neighbors are
+ * drawn
+ */
+static std::vector <wxPoint> s_TargetsLocations;
+static wxPoint s_CursorPos; // Coordinate of the moving point (mouse cursor and
+ // end of current track segment)
+
+/* Used by BuildAirWiresTargetsList(): sort function by link length
+ * (rectilinear distance between s_CursorPos and item pos)
+ */
+static bool sort_by_distance( const wxPoint& ref, const wxPoint& compare )
+{
+ wxPoint deltaref = ref - s_CursorPos; // relative coordinate of ref
+ wxPoint deltacmp = compare - s_CursorPos; // relative coordinate of compare
+
+ // rectilinear distance between ref and s_CursorPos:
+ int lengthref = abs( deltaref.x ) + abs( deltaref.y );
+
+ // rectilinear distance between compare and s_CursorPos:
+ int lengthcmp = abs( deltacmp.x ) + abs( deltacmp.y );
+
+ return lengthref < lengthcmp;
+}
+
+static bool sort_by_point( const wxPoint& ref, const wxPoint& compare )
+{
+ if( ref.x == compare.x )
+ return ref.y < compare.y;
+
+ return ref.x < compare.x;
+}
+
+/* Function BuildAirWiresTargetsList
+ * Build a list of candidates that can be a coonection point
+ * when a track is started.
+ * This functions prepares data to show airwires to nearest connecting points (pads)
+ * from the current new track to candidates during track creation
+ */
+void PCB_BASE_FRAME::BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef,
+ const wxPoint& aPosition, bool aInit )
+{
+ if( ( ( m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
+ || ( ( m_Pcb->m_Status_Pcb & LISTE_PAD_OK ) == 0 )
+ || ( ( m_Pcb->m_Status_Pcb & NET_CODES_OK ) == 0 ) )
+ {
+ s_TargetsLocations.clear();
+ return;
+ }
+
+ s_CursorPos = aPosition; // needed for sort_by_distance
+
+ if( aInit )
+ {
+ s_TargetsLocations.clear();
+
+ if( aItemRef == NULL )
+ return;
+
+ int net_code = aItemRef->GetNetCode();
+ int subnet = aItemRef->GetSubNet();
+
+ if( net_code <= 0 )
+ return;
+
+ NETINFO_ITEM* net = m_Pcb->FindNet( net_code );
+
+ if( net == NULL ) // Should not occur
+ {
+ wxMessageBox( wxT( "BuildAirWiresTargetsList() error: net not found" ) );
+ return;
+ }
+
+ // Create a list of pads candidates ( pads not already connected to the
+ // current track ):
+ for( unsigned ii = 0; ii < net->m_PadInNetList.size(); ii++ )
+ {
+ D_PAD* pad = net->m_PadInNetList[ii];
+
+ if( pad == aItemRef )
+ continue;
+
+ if( !pad->GetSubNet() || (pad->GetSubNet() != subnet) )
+ s_TargetsLocations.push_back( pad->GetPosition() );
+ }
+
+ // Create a list of tracks ends candidates, not already connected to the
+ // current track:
+ for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() )
+ {
+ if( track->GetNetCode() < net_code )
+ continue;
+ if( track->GetNetCode() > net_code )
+ break;
+
+ if( !track->GetSubNet() || (track->GetSubNet() != subnet) )
+ {
+ if( aPosition != track->GetStart() )
+ s_TargetsLocations.push_back( track->GetStart() );
+ if( aPosition != track->GetEnd() && track->GetStart() != track->GetEnd() )
+ s_TargetsLocations.push_back( track->GetEnd() );
+ }
+ }
+
+ // Remove duplicate targets, using the C++ unique algorithm
+ sort( s_TargetsLocations.begin(), s_TargetsLocations.end(), sort_by_point );
+ std::vector< wxPoint >::iterator it = unique( s_TargetsLocations.begin(), s_TargetsLocations.end() );
+
+ // Using the C++ unique algorithm only moves the duplicate entries to the end of
+ // of the array. This removes the duplicate entries from the array.
+ s_TargetsLocations.resize( it - s_TargetsLocations.begin() );
+ } // end if Init
+
+ // in all cases, sort by distances:
+ sort( s_TargetsLocations.begin(), s_TargetsLocations.end(), sort_by_distance );
+}
+
+
+void PCB_BASE_FRAME::TraceAirWiresToTargets( wxDC* aDC )
+{
+ if( aDC == NULL )
+ return;
+
+ if( s_TargetsLocations.size() == 0 )
+ return;
+
+ GRSetDrawMode( aDC, GR_XOR );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ for( int ii = 0; ii < (int) s_TargetsLocations.size(); ii++ )
+ {
+ if( ii >= displ_opts->m_MaxLinksShowed )
+ break;
+
+ GRLine( m_canvas->GetClipBox(), aDC, s_CursorPos, s_TargetsLocations[ii], 0, YELLOW );
+ }
+}
diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp
new file mode 100644
index 0000000..8ddb85e
--- /dev/null
+++ b/pcbnew/ratsnest_data.cpp
@@ -0,0 +1,1271 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2013-2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file ratsnest_data.cpp
+ * @brief Class that computes missing connections on a PCB.
+ */
+
+#ifdef USE_OPENMP
+#include <omp.h>
+#endif /* USE_OPENMP */
+
+#include <ratsnest_data.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_pad.h>
+#include <class_track.h>
+#include <class_zone.h>
+
+#include <boost/range/adaptor/map.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/bind.hpp>
+
+#include <geometry/shape_poly_set.h>
+
+#include <cassert>
+#include <algorithm>
+#include <limits>
+
+#ifdef PROFILE
+#include <profile.h>
+#endif
+
+static uint64_t getDistance( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2 )
+{
+ // Drop the least significant bits to avoid overflow
+ int64_t x = ( aNode1->GetX() - aNode2->GetX() ) >> 16;
+ int64_t y = ( aNode1->GetY() - aNode2->GetY() ) >> 16;
+
+ // We do not need sqrt() here, as the distance is computed only for comparison
+ return ( x * x + y * y );
+}
+
+
+static bool sortDistance( const RN_NODE_PTR& aOrigin, const RN_NODE_PTR& aNode1,
+ const RN_NODE_PTR& aNode2 )
+{
+ return getDistance( aOrigin, aNode1 ) < getDistance( aOrigin, aNode2 );
+}
+
+
+static bool sortWeight( const RN_EDGE_PTR& aEdge1, const RN_EDGE_PTR& aEdge2 )
+{
+ return aEdge1->GetWeight() < aEdge2->GetWeight();
+}
+
+
+bool sortArea( const RN_POLY& aP1, const RN_POLY& aP2 )
+{
+ return aP1.m_bbox.GetArea() < aP2.m_bbox.GetArea();
+}
+
+
+bool operator==( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond )
+{
+ return aFirst->GetX() == aSecond->GetX() && aFirst->GetY() == aSecond->GetY();
+}
+
+
+bool operator!=( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond )
+{
+ return aFirst->GetX() != aSecond->GetX() || aFirst->GetY() != aSecond->GetY();
+}
+
+
+RN_NODE_AND_FILTER operator&&( const RN_NODE_FILTER& aFilter1, const RN_NODE_FILTER& aFilter2 )
+{
+ return RN_NODE_AND_FILTER( aFilter1, aFilter2 );
+}
+
+
+RN_NODE_OR_FILTER operator||( const RN_NODE_FILTER& aFilter1, const RN_NODE_FILTER& aFilter2 )
+{
+ return RN_NODE_OR_FILTER( aFilter1, aFilter2 );
+}
+
+
+static bool isEdgeConnectingNode( const RN_EDGE_PTR& aEdge, const RN_NODE_PTR& aNode )
+{
+ return aEdge->GetSourceNode() == aNode || aEdge->GetTargetNode() == aNode;
+}
+
+
+static std::vector<RN_EDGE_MST_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
+ std::vector<RN_NODE_PTR>& aNodes )
+{
+ unsigned int nodeNumber = aNodes.size();
+ unsigned int mstExpectedSize = nodeNumber - 1;
+ unsigned int mstSize = 0;
+ bool ratsnestLines = false;
+
+ // The output
+ std::vector<RN_EDGE_MST_PTR>* mst = new std::vector<RN_EDGE_MST_PTR>;
+ mst->reserve( mstExpectedSize );
+
+ // Set tags for marking cycles
+ boost::unordered_map<RN_NODE_PTR, int> tags;
+ unsigned int tag = 0;
+ BOOST_FOREACH( RN_NODE_PTR& node, aNodes )
+ {
+ node->SetTag( tag );
+ tags[node] = tag++;
+ }
+
+ // Lists of nodes connected together (subtrees) to detect cycles in the graph
+ std::vector<std::list<int> > cycles( nodeNumber );
+ for( unsigned int i = 0; i < nodeNumber; ++i )
+ cycles[i].push_back( i );
+
+ // Kruskal algorithm requires edges to be sorted by their weight
+ aEdges.sort( sortWeight );
+
+ while( mstSize < mstExpectedSize && !aEdges.empty() )
+ {
+ RN_EDGE_PTR& dt = aEdges.front();
+
+ int srcTag = tags[dt->GetSourceNode()];
+ int trgTag = tags[dt->GetTargetNode()];
+
+ // Check if by adding this edge we are going to join two different forests
+ if( srcTag != trgTag )
+ {
+ // Because edges are sorted by their weight, first we always process connected
+ // items (weight == 0). Once we stumble upon an edge with non-zero weight,
+ // it means that the rest of the lines are ratsnest.
+ if( !ratsnestLines && dt->GetWeight() != 0 )
+ ratsnestLines = true;
+
+ // Update tags
+ std::list<int>::iterator it, itEnd;
+
+ if( ratsnestLines )
+ {
+ for( it = cycles[trgTag].begin(), itEnd = cycles[trgTag].end(); it != itEnd; ++it )
+ tags[aNodes[*it]] = srcTag;
+ }
+ else
+ {
+ for( it = cycles[trgTag].begin(), itEnd = cycles[trgTag].end(); it != itEnd; ++it ) {
+ tags[aNodes[*it]] = srcTag;
+ aNodes[*it]->SetTag( srcTag );
+ }
+ }
+
+ // Move nodes that were marked with old tag to the list marked with the new tag
+ cycles[srcTag].splice( cycles[srcTag].end(), cycles[trgTag] );
+
+ if( ratsnestLines )
+ {
+ // Do a copy of edge, but make it RN_EDGE_MST. In contrary to RN_EDGE,
+ // RN_EDGE_MST saves both source and target node and does not require any other
+ // edges to exist for getting source/target nodes
+ RN_EDGE_MST_PTR newEdge = boost::make_shared<RN_EDGE_MST>( dt->GetSourceNode(),
+ dt->GetTargetNode(),
+ dt->GetWeight() );
+ mst->push_back( newEdge );
+ ++mstSize;
+ }
+ else
+ {
+ // Processing a connection, decrease the expected size of the ratsnest MST
+ --mstExpectedSize;
+ }
+ }
+
+ // Remove the edge that was just processed
+ aEdges.erase( aEdges.begin() );
+ }
+
+ // Probably we have discarded some of edges, so reduce the size
+ mst->resize( mstSize );
+
+ return mst;
+}
+
+
+void RN_NET::validateEdge( RN_EDGE_MST_PTR& aEdge )
+{
+ RN_NODE_PTR source = aEdge->GetSourceNode();
+ RN_NODE_PTR target = aEdge->GetTargetNode();
+ bool valid = true;
+
+ // If any of nodes belonging to the edge has the flag set,
+ // change it to the closest node that has flag cleared
+ if( source->GetFlag() )
+ {
+ valid = false;
+
+ std::list<RN_NODE_PTR> closest = GetClosestNodes( source, WITHOUT_FLAG() );
+ BOOST_FOREACH( RN_NODE_PTR& node, closest )
+ {
+ if( node && node != target )
+ {
+ source = node;
+ break;
+ }
+ }
+ }
+
+ if( target->GetFlag() )
+ {
+ valid = false;
+
+ std::list<RN_NODE_PTR> closest = GetClosestNodes( target, WITHOUT_FLAG() );
+ BOOST_FOREACH( RN_NODE_PTR& node, closest )
+ {
+ if( node && node != source )
+ {
+ target = node;
+ break;
+ }
+ }
+ }
+
+ // Replace an invalid edge with new, valid one
+ if( !valid )
+ aEdge.reset( new RN_EDGE_MST( source, target ) );
+}
+
+
+void RN_NET::removeNode( RN_NODE_PTR& aNode, const BOARD_CONNECTED_ITEM* aParent )
+{
+ aNode->RemoveParent( aParent );
+
+ if( m_links.RemoveNode( aNode ) )
+ {
+ clearNode( aNode );
+ m_dirty = true;
+ }
+}
+
+
+void RN_NET::removeEdge( RN_EDGE_MST_PTR& aEdge, const BOARD_CONNECTED_ITEM* aParent )
+{
+ // Save nodes, so they can be cleared later
+ RN_NODE_PTR start = aEdge->GetSourceNode();
+ RN_NODE_PTR end = aEdge->GetTargetNode();
+
+ start->RemoveParent( aParent );
+ end->RemoveParent( aParent );
+
+ // Connection has to be removed before running RemoveNode(),
+ // as RN_NODE influences the reference counter
+ m_links.RemoveConnection( aEdge );
+
+ // Remove nodes associated with the edge. It is done in a safe way, there is a check
+ // if nodes are not used by other edges.
+ if( m_links.RemoveNode( start ) )
+ clearNode( start );
+
+ if( m_links.RemoveNode( end ) )
+ clearNode( end );
+
+ m_dirty = true;
+}
+
+
+const RN_NODE_PTR& RN_LINKS::AddNode( int aX, int aY )
+{
+ RN_NODE_SET::iterator node;
+ bool wasNewElement;
+
+ boost::tie( node, wasNewElement ) = m_nodes.emplace( boost::make_shared<RN_NODE>( aX, aY ) );
+
+ return *node;
+}
+
+
+bool RN_LINKS::RemoveNode( const RN_NODE_PTR& aNode )
+{
+ if( aNode->GetRefCount() == 0 )
+ {
+ m_nodes.erase( aNode );
+
+ return true;
+ }
+
+ return false;
+}
+
+
+RN_EDGE_MST_PTR RN_LINKS::AddConnection( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2,
+ unsigned int aDistance )
+{
+ assert( aNode1 != aNode2 );
+ RN_EDGE_MST_PTR edge = boost::make_shared<RN_EDGE_MST>( aNode1, aNode2, aDistance );
+ m_edges.push_back( edge );
+
+ return edge;
+}
+
+
+void RN_NET::compute()
+{
+ const RN_LINKS::RN_NODE_SET& boardNodes = m_links.GetNodes();
+ const RN_LINKS::RN_EDGE_LIST& boardEdges = m_links.GetConnections();
+
+ // Special cases do not need complicated algorithms
+ if( boardNodes.size() <= 2 )
+ {
+ m_rnEdges.reset( new std::vector<RN_EDGE_MST_PTR>( 0 ) );
+
+ // Check if the only possible connection exists
+ if( boardEdges.size() == 0 && boardNodes.size() == 2 )
+ {
+ RN_LINKS::RN_NODE_SET::iterator last = ++boardNodes.begin();
+
+ // There can be only one possible connection, but it is missing
+ m_rnEdges->push_back( boost::make_shared<RN_EDGE_MST>( *boardNodes.begin(), *last ) );
+ }
+
+ // Set tags to nodes as connected
+ BOOST_FOREACH( RN_NODE_PTR node, boardNodes )
+ node->SetTag( 0 );
+
+ return;
+ }
+
+ // Move and sort (sorting speeds up) all nodes to a vector for the Delaunay triangulation
+ std::vector<RN_NODE_PTR> nodes( boardNodes.size() );
+ std::partial_sort_copy( boardNodes.begin(), boardNodes.end(), nodes.begin(), nodes.end() );
+
+ TRIANGULATOR triangulator;
+ triangulator.CreateDelaunay( nodes.begin(), nodes.end() );
+ boost::scoped_ptr<RN_LINKS::RN_EDGE_LIST> triangEdges( triangulator.GetEdges() );
+
+ // Compute weight/distance for edges resulting from triangulation
+ RN_LINKS::RN_EDGE_LIST::iterator eit, eitEnd;
+ for( eit = (*triangEdges).begin(), eitEnd = (*triangEdges).end(); eit != eitEnd; ++eit )
+ (*eit)->SetWeight( getDistance( (*eit)->GetSourceNode(), (*eit)->GetTargetNode() ) );
+
+ // Add the currently existing connections list to the results of triangulation
+ std::copy( boardEdges.begin(), boardEdges.end(), std::front_inserter( *triangEdges ) );
+
+ // Get the minimal spanning tree
+ m_rnEdges.reset( kruskalMST( *triangEdges, nodes ) );
+}
+
+
+void RN_NET::clearNode( const RN_NODE_PTR& aNode )
+{
+ if( !m_rnEdges )
+ return;
+
+ std::vector<RN_EDGE_MST_PTR>::iterator newEnd;
+
+ // Remove all ratsnest edges for associated with the node
+ newEnd = std::remove_if( m_rnEdges->begin(), m_rnEdges->end(),
+ boost::bind( isEdgeConnectingNode, _1, boost::cref( aNode ) ) );
+
+ m_rnEdges->resize( std::distance( m_rnEdges->begin(), newEnd ) );
+}
+
+
+RN_POLY::RN_POLY( const SHAPE_POLY_SET* aParent,
+ int aSubpolygonIndex,
+ RN_LINKS& aConnections, const BOX2I& aBBox ) :
+ m_subpolygonIndex( aSubpolygonIndex ),
+ m_bbox( aBBox ),
+ m_parentPolyset( aParent )
+{
+ const VECTOR2I& p = aParent->CVertex( 0, aSubpolygonIndex );
+
+ m_node = aConnections.AddNode( p.x, p.y );
+
+ // Mark it as not appropriate as a destination of ratsnest edges
+ // (edges coming out from a polygon vertex look weird)
+ m_node->SetFlag( true );
+}
+
+
+bool RN_POLY::HitTest( const RN_NODE_PTR& aNode ) const
+{
+ VECTOR2I p( aNode->GetX(), aNode->GetY() );
+
+ return m_parentPolyset->Contains( p, m_subpolygonIndex );
+}
+
+
+void RN_NET::Update()
+{
+ // Add edges resulting from nodes being connected by zones
+ processZones();
+ processPads();
+
+ compute();
+
+ BOOST_FOREACH( RN_EDGE_MST_PTR& edge, *m_rnEdges )
+ validateEdge( edge );
+
+ m_dirty = false;
+}
+
+
+void RN_NET::AddItem( const D_PAD* aPad )
+{
+ RN_NODE_PTR node = m_links.AddNode( aPad->GetPosition().x, aPad->GetPosition().y );
+ node->AddParent( aPad );
+ m_pads[aPad].m_Node = node;
+
+ m_dirty = true;
+}
+
+
+void RN_NET::AddItem( const VIA* aVia )
+{
+ RN_NODE_PTR node = m_links.AddNode( aVia->GetPosition().x, aVia->GetPosition().y );
+ node->AddParent( aVia );
+ m_vias[aVia] = node;
+
+ m_dirty = true;
+}
+
+
+void RN_NET::AddItem( const TRACK* aTrack )
+{
+ if( aTrack->GetStart() == aTrack->GetEnd() )
+ return;
+
+ RN_NODE_PTR start = m_links.AddNode( aTrack->GetStart().x, aTrack->GetStart().y );
+ RN_NODE_PTR end = m_links.AddNode( aTrack->GetEnd().x, aTrack->GetEnd().y );
+
+ start->AddParent( aTrack );
+ end->AddParent( aTrack );
+ m_tracks[aTrack] = m_links.AddConnection( start, end );
+
+ m_dirty = true;
+}
+
+
+void RN_NET::AddItem( const ZONE_CONTAINER* aZone )
+{
+ // Prepare a list of polygons (every zone can contain one or more polygons)
+ const SHAPE_POLY_SET& polySet = aZone->GetFilledPolysList();
+
+ for( int i = 0; i < polySet.OutlineCount(); ++i )
+ {
+ const SHAPE_LINE_CHAIN& path = polySet.COutline( i );
+
+ RN_POLY poly = RN_POLY( &polySet, i, m_links, path.BBox() );
+ m_zones[aZone].m_Polygons.push_back( poly );
+ }
+
+ m_dirty = true;
+}
+
+
+void RN_NET::RemoveItem( const D_PAD* aPad )
+{
+ PAD_NODE_MAP::iterator it = m_pads.find( aPad );
+
+ if( it == m_pads.end() )
+ return;
+
+ RN_PAD_DATA& pad_data = it->second;
+ removeNode( pad_data.m_Node, aPad );
+
+ BOOST_FOREACH( RN_EDGE_MST_PTR& edge, pad_data.m_Edges )
+ removeEdge( edge, aPad );
+
+ m_pads.erase( aPad );
+}
+
+
+void RN_NET::RemoveItem( const VIA* aVia )
+{
+ VIA_NODE_MAP::iterator it = m_vias.find( aVia );
+
+ if( it == m_vias.end() )
+ return;
+
+ removeNode( it->second, aVia );
+ m_vias.erase( it );
+}
+
+
+void RN_NET::RemoveItem( const TRACK* aTrack )
+{
+ TRACK_EDGE_MAP::iterator it = m_tracks.find( aTrack );
+
+ if( it == m_tracks.end() )
+ return;
+
+ removeEdge( it->second, aTrack );
+ m_tracks.erase( it );
+}
+
+
+void RN_NET::RemoveItem( const ZONE_CONTAINER* aZone )
+{
+ ZONE_DATA_MAP::iterator it = m_zones.find( aZone );
+
+ if( it == m_zones.end() )
+ return;
+
+ RN_ZONE_DATA& zoneData = it->second;
+
+ // Remove all subpolygons that make the zone
+ std::deque<RN_POLY>& polygons = zoneData.m_Polygons;
+ BOOST_FOREACH( RN_POLY& polygon, polygons )
+ removeNode( polygon.GetNode(), aZone );
+ polygons.clear();
+
+ // Remove all connections added by the zone
+ std::deque<RN_EDGE_MST_PTR>& edges = zoneData.m_Edges;
+ BOOST_FOREACH( RN_EDGE_MST_PTR edge, edges )
+ removeEdge( edge, aZone );
+ edges.clear();
+
+ m_zones.erase( it );
+}
+
+
+const RN_NODE_PTR RN_NET::GetClosestNode( const RN_NODE_PTR& aNode ) const
+{
+ const RN_LINKS::RN_NODE_SET& nodes = m_links.GetNodes();
+ RN_LINKS::RN_NODE_SET::const_iterator it, itEnd;
+
+ unsigned int minDistance = std::numeric_limits<unsigned int>::max();
+ RN_NODE_PTR closest;
+
+ for( it = nodes.begin(), itEnd = nodes.end(); it != itEnd; ++it )
+ {
+ RN_NODE_PTR node = *it;
+
+ // Obviously the distance between node and itself is the shortest,
+ // that's why we have to skip it
+ if( node != aNode )
+ {
+ unsigned int distance = getDistance( node, aNode );
+ if( distance < minDistance )
+ {
+ minDistance = distance;
+ closest = node;
+ }
+ }
+ }
+
+ return closest;
+}
+
+
+const RN_NODE_PTR RN_NET::GetClosestNode( const RN_NODE_PTR& aNode,
+ const RN_NODE_FILTER& aFilter ) const
+{
+ const RN_LINKS::RN_NODE_SET& nodes = m_links.GetNodes();
+ RN_LINKS::RN_NODE_SET::const_iterator it, itEnd;
+
+ unsigned int minDistance = std::numeric_limits<unsigned int>::max();
+ RN_NODE_PTR closest;
+
+ for( it = nodes.begin(), itEnd = nodes.end(); it != itEnd; ++it )
+ {
+ RN_NODE_PTR node = *it;
+
+ // Obviously the distance between node and itself is the shortest,
+ // that's why we have to skip it
+ if( node != aNode && aFilter( node ) )
+ {
+ unsigned int distance = getDistance( node, aNode );
+
+ if( distance < minDistance )
+ {
+ minDistance = distance;
+ closest = node;
+ }
+ }
+ }
+
+ return closest;
+}
+
+
+std::list<RN_NODE_PTR> RN_NET::GetClosestNodes( const RN_NODE_PTR& aNode, int aNumber ) const
+{
+ std::list<RN_NODE_PTR> closest;
+ const RN_LINKS::RN_NODE_SET& nodes = m_links.GetNodes();
+
+ // Copy nodes
+ BOOST_FOREACH( const RN_NODE_PTR& node, nodes )
+ closest.push_back( node );
+
+ // Sort by the distance from aNode
+ closest.sort( boost::bind( sortDistance, boost::cref( aNode ), _1, _2 ) );
+
+ // aNode should not be returned in the results
+ closest.remove( aNode );
+
+ // Trim the result to the asked size
+ if( aNumber > 0 )
+ closest.resize( std::min( (size_t)aNumber, nodes.size() ) );
+
+ return closest;
+}
+
+
+std::list<RN_NODE_PTR> RN_NET::GetClosestNodes( const RN_NODE_PTR& aNode,
+ const RN_NODE_FILTER& aFilter, int aNumber ) const
+{
+ std::list<RN_NODE_PTR> closest;
+ const RN_LINKS::RN_NODE_SET& nodes = m_links.GetNodes();
+
+ // Copy nodes
+ BOOST_FOREACH( const RN_NODE_PTR& node, nodes )
+ closest.push_back( node );
+
+ // Sort by the distance from aNode
+ closest.sort( boost::bind( sortDistance, boost::cref( aNode ), _1, _2 ) );
+
+ // aNode should not be returned in the results
+ closest.remove( aNode );
+
+ // Filter out by condition
+ std::remove_if( closest.begin(), closest.end(), aFilter );
+
+ // Trim the result to the asked size
+ if( aNumber > 0 )
+ closest.resize( std::min( static_cast<size_t>( aNumber ), nodes.size() ) );
+
+ return closest;
+}
+
+
+void RN_NET::AddSimple( const BOARD_CONNECTED_ITEM* aItem )
+{
+ BOOST_FOREACH( RN_NODE_PTR node, GetNodes( aItem ) )
+ {
+ // Block all nodes, so they do not become targets for dynamic ratsnest lines
+ AddBlockedNode( node );
+
+ // Filter out junctions
+ if( node->GetRefCount() == 1 )
+ m_simpleNodes.insert( node );
+ }
+}
+
+
+std::list<RN_NODE_PTR> RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) const
+{
+ std::list<RN_NODE_PTR> nodes;
+
+ try
+ {
+ switch( aItem->Type() )
+ {
+ case PCB_PAD_T:
+ {
+ const D_PAD* pad = static_cast<const D_PAD*>( aItem );
+ nodes.push_back( m_pads.at( pad ).m_Node );
+ }
+ break;
+
+ case PCB_VIA_T:
+ {
+ const VIA* via = static_cast<const VIA*>( aItem );
+ nodes.push_back( m_vias.at( via ) );
+ }
+ break;
+
+ case PCB_TRACE_T:
+ {
+ const TRACK* track = static_cast<const TRACK*>( aItem );
+ const RN_EDGE_MST_PTR& edge = m_tracks.at( track );
+
+ nodes.push_back( edge->GetSourceNode() );
+ nodes.push_back( edge->GetTargetNode() );
+ }
+ break;
+
+ case PCB_ZONE_AREA_T:
+ {
+ const ZONE_CONTAINER* zone = static_cast<const ZONE_CONTAINER*>( aItem );
+ const std::deque<RN_POLY>& polys = m_zones.at( zone ).m_Polygons;
+
+ for( std::deque<RN_POLY>::const_iterator it = polys.begin(); it != polys.end(); ++it )
+ nodes.push_back( it->GetNode() );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ catch( ... )
+ {
+ // It is fine, just return empty list of nodes
+ }
+
+ return nodes;
+}
+
+
+void RN_NET::GetAllItems( std::list<BOARD_CONNECTED_ITEM*>& aOutput, RN_ITEM_TYPE aType ) const
+{
+ if( aType & RN_PADS )
+ {
+ BOOST_FOREACH( const BOARD_CONNECTED_ITEM* item, m_pads | boost::adaptors::map_keys )
+ aOutput.push_back( const_cast<BOARD_CONNECTED_ITEM*>( item ) );
+ }
+
+ if( aType & RN_VIAS )
+ {
+ BOOST_FOREACH( const BOARD_CONNECTED_ITEM* item, m_vias | boost::adaptors::map_keys )
+ aOutput.push_back( const_cast<BOARD_CONNECTED_ITEM*>( item ) );
+ }
+
+ if( aType & RN_TRACKS )
+ {
+ BOOST_FOREACH( const BOARD_CONNECTED_ITEM* item, m_tracks | boost::adaptors::map_keys )
+ aOutput.push_back( const_cast<BOARD_CONNECTED_ITEM*>( item ) );
+ }
+
+ if( aType & RN_ZONES )
+ {
+ BOOST_FOREACH( const BOARD_CONNECTED_ITEM* item, m_zones | boost::adaptors::map_keys )
+ aOutput.push_back( const_cast<BOARD_CONNECTED_ITEM*>( item ) );
+ }
+}
+
+
+void RN_NET::ClearSimple()
+{
+ BOOST_FOREACH( const RN_NODE_PTR& node, m_blockedNodes )
+ node->SetFlag( false );
+
+ m_blockedNodes.clear();
+ m_simpleNodes.clear();
+}
+
+
+void RN_NET::GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem,
+ std::list<BOARD_CONNECTED_ITEM*>& aOutput,
+ RN_ITEM_TYPE aTypes ) const
+{
+ std::list<RN_NODE_PTR> nodes = GetNodes( aItem );
+ assert( !nodes.empty() );
+
+ int tag = nodes.front()->GetTag();
+ assert( tag >= 0 );
+
+ if( aTypes & RN_PADS )
+ {
+ for( PAD_NODE_MAP::const_iterator it = m_pads.begin(); it != m_pads.end(); ++it )
+ {
+ if( it->second.m_Node->GetTag() == tag )
+ aOutput.push_back( const_cast<D_PAD*>( it->first ) );
+ }
+ }
+
+ if( aTypes & RN_VIAS )
+ {
+ for( VIA_NODE_MAP::const_iterator it = m_vias.begin(); it != m_vias.end(); ++it )
+ {
+ if( it->second->GetTag() == tag )
+ aOutput.push_back( const_cast<VIA*>( it->first ) );
+ }
+ }
+
+ if( aTypes & RN_TRACKS )
+ {
+ for( TRACK_EDGE_MAP::const_iterator it = m_tracks.begin(); it != m_tracks.end(); ++it )
+ {
+ if( it->second->GetTag() == tag )
+ aOutput.push_back( const_cast<TRACK*>( it->first ) );
+ }
+ }
+
+ if( aTypes & RN_ZONES )
+ {
+ for( ZONE_DATA_MAP::const_iterator it = m_zones.begin(); it != m_zones.end(); ++it )
+ {
+ BOOST_FOREACH( const RN_EDGE_MST_PTR& edge, it->second.m_Edges )
+ {
+ if( edge->GetTag() == tag )
+ {
+ aOutput.push_back( const_cast<ZONE_CONTAINER*>( it->first ) );
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+void RN_DATA::AddSimple( const BOARD_ITEM* aItem )
+{
+ int net;
+
+ if( aItem->IsConnected() )
+ {
+ const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( aItem );
+ net = item->GetNetCode();
+
+ if( net < 1 ) // do not process unconnected items
+ return;
+
+ m_nets[net].AddSimple( item );
+ }
+ else if( aItem->Type() == PCB_MODULE_T )
+ {
+ const MODULE* module = static_cast<const MODULE*>( aItem );
+
+ for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
+ AddSimple( pad );
+
+ return;
+ }
+ else
+ return;
+}
+
+
+void RN_DATA::AddBlocked( const BOARD_ITEM* aItem )
+{
+ int net;
+
+ if( aItem->IsConnected() )
+ {
+ const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( aItem );
+ net = item->GetNetCode();
+
+ if( net < 1 ) // do not process unconnected items
+ return;
+
+ // Block all nodes belonging to the item
+ BOOST_FOREACH( RN_NODE_PTR node, m_nets[net].GetNodes( item ) )
+ m_nets[net].AddBlockedNode( node );
+ }
+ else if( aItem->Type() == PCB_MODULE_T )
+ {
+ const MODULE* module = static_cast<const MODULE*>( aItem );
+
+ for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
+ AddBlocked( pad );
+
+ return;
+ }
+ else
+ return;
+}
+
+
+void RN_DATA::GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem,
+ std::list<BOARD_CONNECTED_ITEM*>& aOutput,
+ RN_ITEM_TYPE aTypes ) const
+{
+ int net = aItem->GetNetCode();
+
+ if( net < 1 )
+ return;
+
+ assert( net < (int) m_nets.size() );
+
+ m_nets[net].GetConnectedItems( aItem, aOutput, aTypes );
+}
+
+
+void RN_DATA::GetNetItems( int aNetCode, std::list<BOARD_CONNECTED_ITEM*>& aOutput,
+ RN_ITEM_TYPE aTypes ) const
+{
+ if( aNetCode < 1 )
+ return;
+
+ assert( aNetCode < (int) m_nets.size() );
+
+ m_nets[aNetCode].GetAllItems( aOutput, aTypes );
+}
+
+
+bool RN_DATA::AreConnected( const BOARD_CONNECTED_ITEM* aItem, const BOARD_CONNECTED_ITEM* aOther )
+{
+ int net1 = aItem->GetNetCode();
+ int net2 = aOther->GetNetCode();
+
+ if( net1 < 1 || net2 < 1 || net1 != net2 )
+ return false;
+
+ assert( net1 < (int) m_nets.size() && net2 < (int) m_nets.size() );
+
+ // net1 == net2
+ std::list<RN_NODE_PTR> items1 = m_nets[net1].GetNodes( aItem );
+ std::list<RN_NODE_PTR> items2 = m_nets[net1].GetNodes( aOther );
+
+ assert( !items1.empty() && !items2.empty() );
+
+ return ( items1.front()->GetTag() == items2.front()->GetTag() );
+}
+
+
+int RN_DATA::GetUnconnectedCount() const
+{
+ int count = 0;
+
+ for( unsigned i = 0; i < m_nets.size(); ++i )
+ {
+ const std::vector<RN_EDGE_MST_PTR>* unconnected = m_nets[i].GetUnconnected();
+
+ if( unconnected )
+ count += unconnected->size();
+ }
+
+ return count;
+}
+
+
+void RN_NET::processZones()
+{
+ for( ZONE_DATA_MAP::iterator it = m_zones.begin(); it != m_zones.end(); ++it )
+ {
+ const ZONE_CONTAINER* zone = it->first;
+ RN_ZONE_DATA& zoneData = it->second;
+
+ // Reset existing connections
+ BOOST_FOREACH( RN_EDGE_MST_PTR edge, zoneData.m_Edges )
+ m_links.RemoveConnection( edge );
+
+ zoneData.m_Edges.clear();
+ LSET layers = zone->GetLayerSet();
+
+ // Compute new connections
+ RN_LINKS::RN_NODE_SET candidates = m_links.GetNodes();
+ RN_LINKS::RN_NODE_SET::iterator point, pointEnd;
+
+ // Sorting by area should speed up the processing, as smaller polygons are computed
+ // faster and may reduce the number of points for further checks
+ std::sort( zoneData.m_Polygons.begin(), zoneData.m_Polygons.end(), sortArea );
+
+ for( std::deque<RN_POLY>::iterator poly = zoneData.m_Polygons.begin(),
+ polyEnd = zoneData.m_Polygons.end(); poly != polyEnd; ++poly )
+ {
+ const RN_NODE_PTR& node = poly->GetNode();
+
+ point = candidates.begin();
+ pointEnd = candidates.end();
+
+ while( point != pointEnd )
+ {
+ if( *point != node && ( (*point)->GetLayers() & layers ).any()
+ && poly->HitTest( *point ) )
+ {
+ //(*point)->AddParent( zone ); // do not assign parent for helper links
+
+ RN_EDGE_MST_PTR connection = m_links.AddConnection( node, *point );
+ zoneData.m_Edges.push_back( connection );
+
+ // This point already belongs to a polygon, we do not need to check it anymore
+ point = candidates.erase( point );
+ pointEnd = candidates.end();
+ }
+ else
+ {
+ ++point;
+ }
+ }
+ }
+ }
+}
+
+
+void RN_NET::processPads()
+{
+ for( PAD_NODE_MAP::iterator it = m_pads.begin(); it != m_pads.end(); ++it )
+ {
+ const D_PAD* pad = it->first;
+ RN_NODE_PTR node = it->second.m_Node;
+ std::deque<RN_EDGE_MST_PTR>& edges = it->second.m_Edges;
+
+ // Reset existing connections
+ BOOST_FOREACH( RN_EDGE_MST_PTR edge, edges )
+ m_links.RemoveConnection( edge );
+
+ LSET layers = pad->GetLayerSet();
+ RN_LINKS::RN_NODE_SET candidates = m_links.GetNodes();
+ RN_LINKS::RN_NODE_SET::iterator point, pointEnd;
+
+ point = candidates.begin();
+ pointEnd = candidates.end();
+
+ while( point != pointEnd )
+ {
+ if( *point != node && ( (*point)->GetLayers() & layers ).any() &&
+ pad->HitTest( wxPoint( (*point)->GetX(), (*point)->GetY() ) ) )
+ {
+ //(*point)->AddParent( pad ); // do not assign parent for helper links
+
+ RN_EDGE_MST_PTR connection = m_links.AddConnection( node, *point );
+ edges.push_back( connection );
+ }
+
+ ++point;
+ }
+ }
+}
+
+
+void RN_DATA::Add( const BOARD_ITEM* aItem )
+{
+ int net;
+
+ if( aItem->IsConnected() )
+ {
+ net = static_cast<const BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode();
+ if( net < 1 ) // do not process unconnected items
+ return;
+
+ if( net >= (int) m_nets.size() ) // Autoresize
+ m_nets.resize( net + 1 );
+ }
+ else if( aItem->Type() == PCB_MODULE_T )
+ {
+ const MODULE* module = static_cast<const MODULE*>( aItem );
+ for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
+ {
+ net = pad->GetNetCode();
+
+ if( net < 1 ) // do not process unconnected items
+ continue;
+
+ if( net >= (int) m_nets.size() ) // Autoresize
+ m_nets.resize( net + 1 );
+
+ m_nets[net].AddItem( pad );
+ }
+
+ return;
+ }
+ else
+ return;
+
+ switch( aItem->Type() )
+ {
+ case PCB_PAD_T:
+ m_nets[net].AddItem( static_cast<const D_PAD*>( aItem ) );
+ break;
+
+ case PCB_TRACE_T:
+ m_nets[net].AddItem( static_cast<const TRACK*>( aItem ) );
+ break;
+
+ case PCB_VIA_T:
+ m_nets[net].AddItem( static_cast<const VIA*>( aItem ) );
+ break;
+
+ case PCB_ZONE_AREA_T:
+ m_nets[net].AddItem( static_cast<const ZONE_CONTAINER*>( aItem ) );
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void RN_DATA::Remove( const BOARD_ITEM* aItem )
+{
+ int net;
+
+ if( aItem->IsConnected() )
+ {
+ net = static_cast<const BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode();
+
+ if( net < 1 ) // do not process unconnected items
+ return;
+
+#ifdef NDEBUG
+ if( net >= (int) m_nets.size() ) // Autoresize
+ {
+ m_nets.resize( net + 1 );
+
+ return; // if it was resized, then surely the item had not been added before
+ }
+#endif
+ assert( net < (int) m_nets.size() );
+ }
+ else if( aItem->Type() == PCB_MODULE_T )
+ {
+ const MODULE* module = static_cast<const MODULE*>( aItem );
+ for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
+ {
+ net = pad->GetNetCode();
+
+ if( net < 1 ) // do not process unconnected items
+ continue;
+
+#ifdef NDEBUG
+ if( net >= (int) m_nets.size() ) // Autoresize
+ {
+ m_nets.resize( net + 1 );
+
+ return; // if it was resized, then surely the item had not been added before
+ }
+#endif
+ assert( net < (int) m_nets.size() );
+
+ m_nets[net].RemoveItem( pad );
+ }
+
+ return;
+ }
+ else
+ return;
+
+ switch( aItem->Type() )
+ {
+ case PCB_PAD_T:
+ m_nets[net].RemoveItem( static_cast<const D_PAD*>( aItem ) );
+ break;
+
+ case PCB_TRACE_T:
+ m_nets[net].RemoveItem( static_cast<const TRACK*>( aItem ) );
+ break;
+
+ case PCB_VIA_T:
+ m_nets[net].RemoveItem( static_cast<const VIA*>( aItem ) );
+ break;
+
+ case PCB_ZONE_AREA_T:
+ m_nets[net].RemoveItem( static_cast<const ZONE_CONTAINER*>( aItem ) );
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void RN_DATA::Update( const BOARD_ITEM* aItem )
+{
+ Remove( aItem );
+ Add( aItem );
+}
+
+
+void RN_DATA::ProcessBoard()
+{
+ int netCount = m_board->GetNetCount();
+ m_nets.clear();
+ m_nets.resize( netCount );
+ int netCode;
+
+ // Iterate over all items that may need to be connected
+ for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
+ {
+ netCode = pad->GetNetCode();
+
+ assert( netCode >= 0 && netCode < netCount );
+
+ if( netCode > 0 && netCode < netCount )
+ m_nets[netCode].AddItem( pad );
+ }
+ }
+
+ for( TRACK* track = m_board->m_Track; track; track = track->Next() )
+ {
+ netCode = track->GetNetCode();
+
+ assert( netCode >= 0 && netCode < netCount );
+
+ if( netCode > 0 && netCode < netCount )
+ {
+ if( track->Type() == PCB_VIA_T )
+ m_nets[netCode].AddItem( static_cast<VIA*>( track ) );
+ else if( track->Type() == PCB_TRACE_T )
+ m_nets[netCode].AddItem( track );
+ }
+ }
+
+ for( int i = 0; i < m_board->GetAreaCount(); ++i )
+ {
+ ZONE_CONTAINER* zone = m_board->GetArea( i );
+
+ netCode = zone->GetNetCode();
+
+ assert( netCode >= 0 && netCode < netCount );
+
+ if( netCode > 0 && netCode < netCount )
+ m_nets[netCode].AddItem( zone );
+ }
+
+ Recalculate();
+}
+
+
+void RN_DATA::Recalculate( int aNet )
+{
+ unsigned int netCount = m_board->GetNetCount();
+
+ if( netCount > m_nets.size() )
+ m_nets.resize( netCount );
+
+ if( aNet < 0 && netCount > 1 ) // Recompute everything
+ {
+#ifdef PROFILE
+ prof_counter totalRealTime;
+ prof_start( &totalRealTime );
+#endif
+
+ unsigned int i;
+
+#ifdef USE_OPENMP
+ #pragma omp parallel shared(netCount) private(i)
+ {
+ #pragma omp for schedule(guided, 1)
+#else /* USE_OPENMP */
+ {
+#endif
+ // Start with net number 1, as 0 stands for not connected
+ for( i = 1; i < netCount; ++i )
+ {
+ if( m_nets[i].IsDirty() )
+ updateNet( i );
+ }
+ } /* end of parallel section */
+#ifdef PROFILE
+ prof_end( &totalRealTime );
+
+ wxLogDebug( wxT( "Recalculate all nets: %.1f ms" ), totalRealTime.msecs() );
+#endif /* PROFILE */
+ }
+ else if( aNet > 0 ) // Recompute only specific net
+ {
+ updateNet( aNet );
+ }
+}
+
+
+void RN_DATA::updateNet( int aNetCode )
+{
+ assert( aNetCode < (int) m_nets.size() );
+
+ if( aNetCode < 1 || aNetCode > (int) m_nets.size() )
+ return;
+
+ m_nets[aNetCode].ClearSimple();
+ m_nets[aNetCode].Update();
+}
diff --git a/pcbnew/ratsnest_data.h b/pcbnew/ratsnest_data.h
new file mode 100644
index 0000000..72e0530
--- /dev/null
+++ b/pcbnew/ratsnest_data.h
@@ -0,0 +1,781 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2013-2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file ratsnest_data.h
+ * @brief Class that computes missing connections on a PCB.
+ */
+
+#ifndef RATSNEST_DATA_H
+#define RATSNEST_DATA_H
+
+#include <ttl/halfedge/hetriang.h>
+#include <ttl/halfedge/hetraits.h>
+
+#include <math/box2.h>
+
+#include <boost/unordered_set.hpp>
+#include <boost/unordered_map.hpp>
+#include <boost/foreach.hpp>
+
+class BOARD;
+class BOARD_ITEM;
+class BOARD_CONNECTED_ITEM;
+class MODULE;
+class D_PAD;
+class VIA;
+class TRACK;
+class ZONE_CONTAINER;
+class SHAPE_POLY_SET;
+
+///> Types of items that are handled by the class
+enum RN_ITEM_TYPE
+{
+ RN_PADS = 0x01,
+ RN_VIAS = 0x02,
+ RN_TRACKS = 0x04,
+ RN_ZONES = 0x08,
+ RN_ALL = 0xFF
+};
+
+// Preserve KiCad coding style policy
+typedef hed::NODE RN_NODE;
+typedef hed::NODE_PTR RN_NODE_PTR;
+typedef hed::EDGE RN_EDGE;
+typedef hed::EDGE_PTR RN_EDGE_PTR;
+typedef hed::EDGE_MST RN_EDGE_MST;
+typedef hed::TRIANGULATION TRIANGULATOR;
+typedef boost::shared_ptr<hed::EDGE_MST> RN_EDGE_MST_PTR;
+
+bool operator==( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond );
+bool operator!=( const RN_NODE_PTR& aFirst, const RN_NODE_PTR& aSecond );
+
+struct RN_NODE_OR_FILTER;
+struct RN_NODE_AND_FILTER;
+
+///> General interface for filtering out nodes in search functions.
+struct RN_NODE_FILTER : public std::unary_function<const RN_NODE_PTR&, bool>
+{
+ virtual ~RN_NODE_FILTER() {}
+
+ virtual bool operator()( const RN_NODE_PTR& aNode ) const
+ {
+ return true; // By default everything passes
+ }
+
+ friend RN_NODE_AND_FILTER operator&&( const RN_NODE_FILTER& aFilter1, const RN_NODE_FILTER& aFilter2 );
+ friend RN_NODE_OR_FILTER operator||( const RN_NODE_FILTER& aFilter1, const RN_NODE_FILTER& aFilter2 );
+};
+
+RN_NODE_AND_FILTER operator&&( const RN_NODE_FILTER& aFilter1, const RN_NODE_FILTER& aFilter2 );
+RN_NODE_OR_FILTER operator||( const RN_NODE_FILTER& aFilter1, const RN_NODE_FILTER& aFilter2 );
+
+///> Filters out nodes that have the flag set.
+struct WITHOUT_FLAG : public RN_NODE_FILTER
+{
+ bool operator()( const RN_NODE_PTR& aNode ) const
+ {
+ return !aNode->GetFlag();
+ }
+};
+
+///> Filters out nodes with a specific tag
+struct DIFFERENT_TAG : public RN_NODE_FILTER
+{
+ DIFFERENT_TAG( int aTag ) :
+ m_tag( aTag )
+ {}
+
+ bool operator()( const RN_NODE_PTR& aNode ) const
+ {
+ return aNode->GetTag() != m_tag;
+ }
+
+ private:
+ int m_tag;
+};
+
+struct RN_NODE_AND_FILTER : public RN_NODE_FILTER
+{
+ RN_NODE_AND_FILTER( const RN_NODE_FILTER& aFilter1, const RN_NODE_FILTER& aFilter2 ) :
+ m_filter1( aFilter1 ), m_filter2( aFilter2 )
+ {}
+
+ bool operator()( const RN_NODE_PTR& aNode ) const
+ {
+ return m_filter1( aNode ) && m_filter2( aNode );
+ }
+
+ private:
+ const RN_NODE_FILTER& m_filter1;
+ const RN_NODE_FILTER& m_filter2;
+};
+
+struct RN_NODE_OR_FILTER : public RN_NODE_FILTER
+{
+ RN_NODE_OR_FILTER( const RN_NODE_FILTER& aFilter1, const RN_NODE_FILTER& aFilter2 ) :
+ m_filter1( aFilter1 ), m_filter2( aFilter2 )
+ {}
+
+ bool operator()( const RN_NODE_PTR& aNode ) const
+ {
+ return m_filter1( aNode ) || m_filter2( aNode );
+ }
+
+ private:
+ const RN_NODE_FILTER& m_filter1;
+ const RN_NODE_FILTER& m_filter2;
+};
+
+
+///> Functor comparing if two nodes are equal by their coordinates. It is required to make set of
+///> shared pointers work properly.
+struct RN_NODE_COMPARE : std::binary_function<RN_NODE_PTR, RN_NODE_PTR, bool>
+{
+ bool operator()( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2 ) const
+ {
+ return aNode1 == aNode2;
+ }
+};
+
+///> Functor calculating hash for a given node. It is required to make set of shared pointers
+///> work properly.
+struct RN_NODE_HASH : std::unary_function<RN_NODE_PTR, std::size_t>
+{
+ std::size_t operator()( const RN_NODE_PTR& aNode ) const
+ {
+ std::size_t hash = 2166136261u;
+
+ hash ^= aNode->GetX();
+ hash *= 16777619;
+ hash ^= aNode->GetY();
+
+ return hash;
+ }
+};
+
+
+/**
+ * Class RN_LINKS
+ * Manages data describing nodes and connections for a given net.
+ */
+class RN_LINKS
+{
+public:
+ // Helper typedefs
+ typedef boost::unordered_set<RN_NODE_PTR, RN_NODE_HASH, RN_NODE_COMPARE> RN_NODE_SET;
+ typedef std::list<RN_EDGE_PTR> RN_EDGE_LIST;
+
+ /**
+ * Function AddNode()
+ * Adds a node with given coordinates and returns pointer to the newly added node. If the node
+ * existed before, only appropriate pointer is returned.
+ * @param aX is the x coordinate of a node.
+ * @param aY is the y coordinate of a node.
+ * @return Pointer to the node with given coordinates.
+ */
+ const RN_NODE_PTR& AddNode( int aX, int aY );
+
+ /**
+ * Function RemoveNode()
+ * Removes a node described by a given node pointer.
+ * @param aNode is a pointer to node to be removed.
+ * @return True if node was removed, false if there were other references, so it was kept.
+ */
+ bool RemoveNode( const RN_NODE_PTR& aNode );
+
+ /**
+ * Function GetNodes()
+ * Returns the set of currently used nodes.
+ * @return The set of currently used nodes.
+ */
+ const RN_NODE_SET& GetNodes() const
+ {
+ return m_nodes;
+ }
+
+ /**
+ * Function AddConnection()
+ * Adds a connection between two nodes and of given distance. Edges with distance equal 0 are
+ * considered to be existing connections. Distance different than 0 means that the connection
+ * is missing.
+ * @param aNode1 is the origin node of a new connection.
+ * @param aNode2 is the end node of a new connection.
+ * @param aDistance is the distance of the connection (0 means that nodes are actually
+ * connected, >0 means a missing connection).
+ */
+ RN_EDGE_MST_PTR AddConnection( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2,
+ unsigned int aDistance = 0 );
+
+ /**
+ * Function RemoveConnection()
+ * Removes a connection described by a given edge pointer.
+ * @param aEdge is a pointer to edge to be removed.
+ */
+ void RemoveConnection( const RN_EDGE_PTR& aEdge )
+ {
+ m_edges.remove( aEdge );
+ }
+
+ /**
+ * Function GetConnections()
+ * Returns the list of edges that currently connect nodes.
+ * @return the list of edges that currently connect nodes.
+ */
+ const RN_EDGE_LIST& GetConnections() const
+ {
+ return m_edges;
+ }
+
+protected:
+ ///> Set of nodes that are expected to be connected together (vias, tracks, pads).
+ RN_NODE_SET m_nodes;
+
+ ///> List of edges that currently connect nodes.
+ RN_EDGE_LIST m_edges;
+};
+
+
+/**
+ * Class RN_POLY
+ * Describes a single subpolygon (ZONE_CONTAINER is supposed to contain one or more of those) and
+ * performs fast point-inside-polygon test.
+ */
+class RN_POLY
+{
+public:
+ RN_POLY( const SHAPE_POLY_SET* aParent,
+ int aSubpolygonIndex,
+ RN_LINKS& aConnections, const BOX2I& aBBox );
+
+ /**
+ * Function GetNode()
+ * Returns node representing a polygon (it has the same coordinates as the first point of its
+ * bounding polyline.
+ */
+ inline const RN_NODE_PTR& GetNode() const
+ {
+ return m_node;
+ }
+
+ inline RN_NODE_PTR& GetNode()
+ {
+ return m_node;
+ }
+
+ /**
+ * Function HitTest()
+ * Tests if selected node is located within polygon boundaries.
+ * @param aNode is a node to be checked.
+ * @return True is the node is located within polygon boundaries.
+ */
+ bool HitTest( const RN_NODE_PTR& aNode ) const;
+
+private:
+
+ ///> Index of the outline in the parent polygon set
+ int m_subpolygonIndex;
+
+ ///> Bounding box of the polygon.
+ BOX2I m_bbox;
+
+ ///> Polygon set containing the geometry
+ const SHAPE_POLY_SET* m_parentPolyset;
+
+ ///> Node representing a polygon (it has the same coordinates as the first point of its
+ ///> bounding polyline.
+ RN_NODE_PTR m_node;
+
+ friend bool sortArea( const RN_POLY& aP1, const RN_POLY& aP2 );
+};
+
+
+/**
+ * Class RN_NET
+ * Describes ratsnest for a single net.
+ */
+class RN_NET
+{
+public:
+ ///> Default constructor.
+ RN_NET() : m_dirty( true ), m_visible( true )
+ {}
+
+ /**
+ * Function SetVisible()
+ * Sets state of the visibility flag.
+ * @param aEnabled is new state. True if ratsnest for a given net is meant to be displayed,
+ * false otherwise.
+ */
+ void SetVisible( bool aEnabled )
+ {
+ m_visible = aEnabled;
+ }
+
+ /**
+ * Function IsVisible()
+ * Returns the visibility flag state.
+ * @return True if ratsnest for given net is set as visible, false otherwise,
+ */
+ bool IsVisible() const
+ {
+ return m_visible;
+ }
+
+ /**
+ * Function MarkDirty()
+ * Marks ratsnest for given net as 'dirty', i.e. requiring recomputation.
+ */
+ void MarkDirty()
+ {
+ m_dirty = true;
+ }
+
+ /**
+ * Function IsDirty()
+ * Returns state of the 'dirty' flag, indicating that ratsnest for a given net is invalid
+ * and requires an update.
+ * @return True if ratsnest requires recomputation, false otherwise.
+ */
+ bool IsDirty() const
+ {
+ return m_dirty;
+ }
+
+ /**
+ * Function GetUnconnected()
+ * Returns pointer to a vector of edges that makes ratsnest for a given net.
+ * @return Pointer to a vector of edges that makes ratsnest for a given net.
+ */
+ const std::vector<RN_EDGE_MST_PTR>* GetUnconnected() const
+ {
+ return m_rnEdges.get();
+ }
+
+ /**
+ * Function Update()
+ * Recomputes ratsnest for a net.
+ */
+ void Update();
+
+ /**
+ * Function AddItem()
+ * Adds an appropriate node associated with selected pad, so it is
+ * taken into account during ratsnest computations.
+ * @param aPad is a pad for which node is added.
+ */
+ void AddItem( const D_PAD* aPad );
+
+ /**
+ * Function AddItem()
+ * Adds an appropriate node associated with selected via, so it is
+ * taken into account during ratsnest computations.
+ * @param aVia is a via for which node is added.
+ */
+ void AddItem( const VIA* aVia );
+
+ /**
+ * Function AddItem()
+ * Adds appropriate nodes and edges associated with selected track, so they are
+ * taken into account during ratsnest computations.
+ * @param aTrack is a track for which nodes and edges are added.
+ */
+ void AddItem( const TRACK* aTrack );
+
+ /**
+ * Function AddItem()
+ * Processes zone to split it into subpolygons and adds appropriate nodes for them, so they are
+ * taken into account during ratsnest computations.
+ * @param aZone is a zone to be processed.
+ */
+ void AddItem( const ZONE_CONTAINER* aZone );
+
+ /**
+ * Function RemoveItem()
+ * Removes all nodes and edges associated with selected pad, so they are not
+ * taken into account during ratsnest computations anymore.
+ * @param aPad is a pad for which nodes and edges are removed.
+ */
+ void RemoveItem( const D_PAD* aPad );
+
+ /**
+ * Function RemoveItem()
+ * Removes all nodes and edges associated with selected via, so they are not
+ * taken into account during ratsnest computations anymore.
+ * @param aVia is a via for which nodes and edges are removed.
+ */
+ void RemoveItem( const VIA* aVia );
+
+ /**
+ * Function RemoveItem()
+ * Removes all nodes and edges associated with selected track, so they are not
+ * taken into account during ratsnest computations anymore.
+ * @param aTrack is a track for which nodes and edges are removed.
+ */
+ void RemoveItem( const TRACK* aTrack );
+
+ /**
+ * Function RemoveItem()
+ * Removes all nodes and edges associated with selected zone, so they are not
+ * taken into account during ratsnest computations anymore.
+ * @param aZone is a zone for which nodes and edges are removed.
+ */
+ void RemoveItem( const ZONE_CONTAINER* aZone );
+
+ /**
+ * Function GetNodes()
+ * Returns list of nodes that are associated with a given item.
+ * @param aItem is an item for which the list is generated.
+ * @return List of associated nodes.
+ */
+ std::list<RN_NODE_PTR> GetNodes( const BOARD_CONNECTED_ITEM* aItem ) const;
+
+ /**
+ * Function GetAllItems()
+ * Adds all stored items to a list.
+ * @param aOutput is the list that will have items added.
+ * @param aType determines the type of added items.
+ */
+ void GetAllItems( std::list<BOARD_CONNECTED_ITEM*>& aOutput, RN_ITEM_TYPE aType = RN_ALL ) const;
+
+ /**
+ * Function GetClosestNode()
+ * Returns a single node that lies in the shortest distance from a specific node.
+ * @param aNode is the node for which the closest node is searched.
+ */
+ const RN_NODE_PTR GetClosestNode( const RN_NODE_PTR& aNode ) const;
+
+ /**
+ * Function GetClosestNode()
+ * Returns a single node that lies in the shortest distance from a specific node and meets
+ * selected filter criterion..
+ * @param aNode is the node for which the closest node is searched.
+ * @param aFilter is a functor that filters nodes.
+ */
+ const RN_NODE_PTR GetClosestNode( const RN_NODE_PTR& aNode,
+ const RN_NODE_FILTER& aFilter ) const;
+
+ /**
+ * Function GetClosestNodes()
+ * Returns list of nodes sorted by the distance from a specific node.
+ * @param aNode is the node for which the closest nodes are searched.
+ * @param aNumber is asked number of returned nodes. If it is negative then all nodes that
+ * belong to the same net are returned. If asked number is greater than number of possible
+ * nodes then the size of list is limited to number of possible nodes.
+ */
+ std::list<RN_NODE_PTR> GetClosestNodes( const RN_NODE_PTR& aNode, int aNumber = -1 ) const;
+
+ /**
+ * Function GetClosestNodes()
+ * Returns filtered list of nodes sorted by the distance from a specific node.
+ * @param aNode is the node for which the closest nodes are searched.
+ * @param aFilter is a functor that filters nodes.
+ * @param aNumber is asked number of returned nodes. If it is negative then all nodes that
+ * belong to the same net are returned. If asked number is greater than number of possible
+ * nodes then the size of list is limited to number of possible nodes.
+ */
+ std::list<RN_NODE_PTR> GetClosestNodes( const RN_NODE_PTR& aNode,
+ const RN_NODE_FILTER& aFilter, int aNumber = -1 ) const;
+
+ /**
+ * Function AddSimple()
+ * Changes drawing mode for an item to simple (i.e. one ratsnest line per node).
+ * @param aNode is a node that changes its drawing mode.
+ */
+ void AddSimple( const BOARD_CONNECTED_ITEM* aItem );
+
+ /**
+ * Function AddBlockedNode()
+ * Specifies a node as not suitable as a ratsnest line target (i.e. ratsnest lines will not
+ * target the node). The status is cleared after calling ClearSimple().
+ * @param aNode is the node that is not going to be used as a ratsnest line target.
+ */
+ inline void AddBlockedNode( RN_NODE_PTR& aNode )
+ {
+ m_blockedNodes.insert( aNode );
+ aNode->SetFlag( true );
+ }
+
+ /**
+ * Function GetSimpleNodes()
+ * Returns list of nodes for which ratsnest is drawn in simple mode (i.e. one
+ * ratsnest line per node).
+ * @return list of nodes for which ratsnest is drawn in simple mode.
+ */
+ inline const boost::unordered_set<RN_NODE_PTR>& GetSimpleNodes() const
+ {
+ return m_simpleNodes;
+ }
+
+ /**
+ * Function ClearSimple()
+ * Removes all nodes and edges that are used for displaying ratsnest in simple mode.
+ */
+ void ClearSimple();
+
+ /**
+ * Function GetConnectedItems()
+ * Adds items that are connected together to a list.
+ * @param aItem is the reference item to find other connected items.
+ * @param aOutput is the list that will contain found items.
+ * @param aTypes allows to filter by item types.
+ */
+ void GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem,
+ std::list<BOARD_CONNECTED_ITEM*>& aOutput,
+ RN_ITEM_TYPE aTypes = RN_ALL ) const;
+
+protected:
+ ///> Validates edge, i.e. modifies source and target nodes for an edge
+ ///> to make sure that they are not ones with the flag set.
+ void validateEdge( RN_EDGE_MST_PTR& aEdge );
+
+ ///> Removes a link between a node and a parent,
+ ///> and clears linked edges if it was the last parent.
+ void removeNode( RN_NODE_PTR& aNode, const BOARD_CONNECTED_ITEM* aParent );
+
+ ///> Removes a link between an edge and a parent,
+ ///> and clears its node data if it was the last parent.
+ void removeEdge( RN_EDGE_MST_PTR& aEdge, const BOARD_CONNECTED_ITEM* aParent );
+
+ ///> Removes all ratsnest edges for a given node.
+ void clearNode( const RN_NODE_PTR& aNode );
+
+ ///> Adds appropriate edges for nodes that are connected by zones.
+ void processZones();
+
+ ///> Adds additional edges to account for connections made by items located in pads areas.
+ void processPads();
+
+ ///> Recomputes ratsnset from scratch.
+ void compute();
+
+ ////> Stores information about connections for a given net.
+ RN_LINKS m_links;
+
+ ///> Vector of edges that makes ratsnest for a given net.
+ boost::shared_ptr< std::vector<RN_EDGE_MST_PTR> > m_rnEdges;
+
+ ///> List of nodes which will not be used as ratsnest target nodes.
+ boost::unordered_set<RN_NODE_PTR> m_blockedNodes;
+
+ ///> Nodes to be displayed using the simplified ratsnest algorithm.
+ boost::unordered_set<RN_NODE_PTR> m_simpleNodes;
+
+ ///> Flag indicating necessity of recalculation of ratsnest for a net.
+ bool m_dirty;
+
+ ///> Structure to hold ratsnest data for ZONE_CONTAINER objects.
+ typedef struct
+ {
+ ///> Subpolygons belonging to a zone
+ std::deque<RN_POLY> m_Polygons;
+
+ ///> Connections to other nodes
+ std::deque<RN_EDGE_MST_PTR> m_Edges;
+ } RN_ZONE_DATA;
+
+ ///> Structureo to hold ratsnest data for D_PAD objects.
+ typedef struct
+ {
+ ///> Node representing the pad.
+ RN_NODE_PTR m_Node;
+
+ ///> Helper nodes that make for connections to items located in the pad area.
+ std::deque<RN_EDGE_MST_PTR> m_Edges;
+ } RN_PAD_DATA;
+
+ ///> Helper typedefs
+ typedef boost::unordered_map<const D_PAD*, RN_PAD_DATA> PAD_NODE_MAP;
+ typedef boost::unordered_map<const VIA*, RN_NODE_PTR> VIA_NODE_MAP;
+ typedef boost::unordered_map<const TRACK*, RN_EDGE_MST_PTR> TRACK_EDGE_MAP;
+ typedef boost::unordered_map<const ZONE_CONTAINER*, RN_ZONE_DATA> ZONE_DATA_MAP;
+
+ ///> Map that associates nodes in the ratsnest model to respective nodes.
+ PAD_NODE_MAP m_pads;
+
+ ///> Map that associates nodes in the ratsnest model to respective vias.
+ VIA_NODE_MAP m_vias;
+
+ ///> Map that associates edges in the ratsnest model to respective tracks.
+ TRACK_EDGE_MAP m_tracks;
+
+ ///> Map that associates groups of subpolygons in the ratsnest model to respective zones.
+ ZONE_DATA_MAP m_zones;
+
+ ///> Visibility flag.
+ bool m_visible;
+};
+
+
+/**
+ * Class RN_DATA
+ *
+ * Stores information about unconnected items for a board.
+ */
+class RN_DATA
+{
+public:
+ /**
+ * Default constructor
+ * @param aBoard is the board to be processed in order to look for unconnected items.
+ */
+ RN_DATA( const BOARD* aBoard ) : m_board( aBoard ) {}
+
+ /**
+ * Function Add()
+ * Adds an item to the ratsnest data.
+ * @param aItem is an item to be added.
+ */
+ void Add( const BOARD_ITEM* aItem );
+
+ /**
+ * Function Remove()
+ * Removes an item from the ratsnest data.
+ * @param aItem is an item to be updated.
+ */
+ void Remove( const BOARD_ITEM* aItem );
+
+ /**
+ * Function Update()
+ * Updates the ratsnest data for an item.
+ * @param aItem is an item to be updated.
+ */
+ void Update( const BOARD_ITEM* aItem );
+
+ /**
+ * Function AddSimple()
+ * Sets an item to be drawn in simple mode (i.e. one line per node, instead of full ratsnest).
+ * It is used for drawing quick, temporary ratsnest, eg. while moving an item.
+ * @param aItem is an item to be drawn in simple node.
+ */
+ void AddSimple( const BOARD_ITEM* aItem );
+
+ /**
+ * Function AddBlocked()
+ * Specifies an item as not suitable as a ratsnest line target (i.e. ratsnest lines will not
+ * target its node(s)). The status is cleared after calling ClearSimple().
+ * @param aItem is the item of which node(s) are not going to be used as a ratsnest line target.
+ */
+ void AddBlocked( const BOARD_ITEM* aItem );
+
+ /**
+ * Function ClearSimple()
+ * Clears the list of nodes for which ratsnest is drawn in simple mode (one line per node).
+ */
+ void ClearSimple()
+ {
+ BOOST_FOREACH( RN_NET& net, m_nets )
+ net.ClearSimple();
+ }
+
+ /**
+ * Function ProcessBoard()
+ * Prepares data for computing (computes a list of current nodes and connections). It is
+ * required to run only once after loading a board.
+ */
+ void ProcessBoard();
+
+ /**
+ * Function Recalculate()
+ * Recomputes ratsnest for selected net number or all nets that need updating.
+ * @param aNet is a net number. If it is negative, all nets that need updating are recomputed.
+ */
+ void Recalculate( int aNet = -1 );
+
+ /**
+ * Function GetNetCount()
+ * Returns the number of nets handled by the ratsnest.
+ * @return Number of the nets.
+ */
+ int GetNetCount() const
+ {
+ return m_nets.size();
+ }
+
+ /**
+ * Function GetNet()
+ * Returns ratsnest grouped by net numbers.
+ * @param aNetCode is the net code.
+ * @return Ratsnest data for a specified net.
+ */
+ RN_NET& GetNet( int aNetCode )
+ {
+ assert( aNetCode > 0 ); // ratsnest does not handle the unconnected net
+
+ return m_nets[aNetCode];
+ }
+
+ /**
+ * Function GetConnectedItems()
+ * Adds items that are connected together to a list.
+ * @param aItem is the reference item to find other connected items.
+ * @param aOutput is the list that will contain found items.
+ * @param aTypes allows to filter by item types.
+ */
+ void GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem,
+ std::list<BOARD_CONNECTED_ITEM*>& aOutput,
+ RN_ITEM_TYPE aTypes = RN_ALL ) const;
+
+ /**
+ * Function GetNetItems()
+ * Adds all items that belong to a certain net to a list.
+ * @param aNetCode is the net code.
+ * @param aOutput is the list that will have items added.
+ * @param aTypes allows to filter by item types.
+ */
+ void GetNetItems( int aNetCode, std::list<BOARD_CONNECTED_ITEM*>& aOutput,
+ RN_ITEM_TYPE aTypes = RN_ALL ) const;
+
+ /**
+ * Function AreConnected()
+ * Checks if two items are connected with copper.
+ * @param aThis is the first item.
+ * @param aOther is the second item.
+ * @return True if they are connected, false otherwise.
+ */
+ bool AreConnected( const BOARD_CONNECTED_ITEM* aItem, const BOARD_CONNECTED_ITEM* aOther );
+
+ /**
+ * Function GetUnconnectedCount()
+ * Returns the number of missing connections.
+ * @return Number of missing connections.
+ */
+ int GetUnconnectedCount() const;
+
+protected:
+ /**
+ * Function updateNet()
+ * Recomputes ratsnest for a single net.
+ * @param aNetCode is the net number to be recomputed.
+ */
+ void updateNet( int aNetCode );
+
+ ///> Board to be processed.
+ const BOARD* m_board;
+
+ ///> Stores information about ratsnest grouped by net numbers.
+ std::vector<RN_NET> m_nets;
+};
+
+#endif /* RATSNEST_DATA_H */
diff --git a/pcbnew/ratsnest_viewitem.cpp b/pcbnew/ratsnest_viewitem.cpp
new file mode 100644
index 0000000..252ef3c
--- /dev/null
+++ b/pcbnew/ratsnest_viewitem.cpp
@@ -0,0 +1,120 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file ratsnest_viewitem.cpp
+ * @brief Class that draws missing connections on a PCB.
+ */
+
+#include <ratsnest_viewitem.h>
+#include <ratsnest_data.h>
+#include <gal/graphics_abstraction_layer.h>
+#include <pcb_painter.h>
+#include <layers_id_colors_and_visibility.h>
+
+#include <boost/foreach.hpp>
+
+using namespace KIGFX;
+
+RATSNEST_VIEWITEM::RATSNEST_VIEWITEM( RN_DATA* aData ) :
+ EDA_ITEM( NOT_USED ), m_data( aData )
+{
+}
+
+
+const BOX2I RATSNEST_VIEWITEM::ViewBBox() const
+{
+ // Make it always visible
+ BOX2I bbox;
+ bbox.SetMaximum();
+
+ return bbox;
+}
+
+
+void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
+{
+ aGal->SetIsStroke( true );
+ aGal->SetIsFill( false );
+ aGal->SetLineWidth( 1.0 );
+ RENDER_SETTINGS* rs = m_view->GetPainter()->GetSettings();
+ COLOR4D color = rs->GetColor( NULL, ITEM_GAL_LAYER( RATSNEST_VISIBLE ) );
+ int highlightedNet = rs->GetHighlightNetCode();
+
+ // Dynamic ratsnest (for e.g. dragged items)
+ for( int i = 1; i < m_data->GetNetCount(); ++i )
+ {
+ RN_NET& net = m_data->GetNet( i );
+
+ if( !net.IsVisible() )
+ continue;
+
+ // Set brighter color for the temporary ratsnest
+ aGal->SetStrokeColor( color.Brightened( 0.8 ) );
+
+ // Draw the "dynamic" ratsnest (i.e. for objects that may be currently being moved)
+ BOOST_FOREACH( const RN_NODE_PTR& node, net.GetSimpleNodes() )
+ {
+ // Skipping nodes with higher reference count avoids displaying redundant lines
+ if( node->GetRefCount() > 1 )
+ continue;
+
+ RN_NODE_PTR dest = net.GetClosestNode( node, WITHOUT_FLAG() );
+
+ if( dest )
+ {
+ VECTOR2D origin( node->GetX(), node->GetY() );
+ VECTOR2D end( dest->GetX(), dest->GetY() );
+
+ aGal->DrawLine( origin, end );
+ }
+ }
+
+ // Draw the "static" ratsnest
+ if( i != highlightedNet )
+ aGal->SetStrokeColor( color ); // using the default ratsnest color for not highlighted
+
+ const std::vector<RN_EDGE_MST_PTR>* edges = net.GetUnconnected();
+
+ if( edges == NULL )
+ continue;
+
+ BOOST_FOREACH( const RN_EDGE_MST_PTR& edge, *edges )
+ {
+ const RN_NODE_PTR& sourceNode = edge->GetSourceNode();
+ const RN_NODE_PTR& targetNode = edge->GetTargetNode();
+ VECTOR2D source( sourceNode->GetX(), sourceNode->GetY() );
+ VECTOR2D target( targetNode->GetX(), targetNode->GetY() );
+
+ aGal->DrawLine( source, target );
+ }
+ }
+}
+
+
+void RATSNEST_VIEWITEM::ViewGetLayers( int aLayers[], int& aCount ) const
+{
+ aCount = 1;
+ aLayers[0] = ITEM_GAL_LAYER( RATSNEST_VISIBLE );
+}
diff --git a/pcbnew/ratsnest_viewitem.h b/pcbnew/ratsnest_viewitem.h
new file mode 100644
index 0000000..8898be8
--- /dev/null
+++ b/pcbnew/ratsnest_viewitem.h
@@ -0,0 +1,77 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file ratsnest_viewitem.h
+ * @brief Class that draws missing connections on a PCB.
+ */
+
+#ifndef RATSNEST_VIEWITEM_H
+#define RATSNEST_VIEWITEM_H
+
+#include <base_struct.h>
+#include <math/vector2d.h>
+
+class GAL;
+class RN_DATA;
+
+namespace KIGFX
+{
+class RATSNEST_VIEWITEM : public EDA_ITEM
+{
+public:
+ RATSNEST_VIEWITEM( RN_DATA* aData );
+
+ /// @copydoc VIEW_ITEM::ViewBBox()
+ const BOX2I ViewBBox() const;
+
+ /// @copydoc VIEW_ITEM::ViewDraw()
+ void ViewDraw( int aLayer, GAL* aGal ) const;
+
+ /// @copydoc VIEW_ITEM::ViewGetLayers()
+ void ViewGetLayers( int aLayers[], int& aCount ) const;
+
+#if defined(DEBUG)
+ /// @copydoc EDA_ITEM::Show()
+ void Show( int x, std::ostream& st ) const
+ {
+ }
+#endif
+
+ /** Get class name
+ * @return string "RATSNEST_VIEWITEM"
+ */
+ virtual wxString GetClass() const
+ {
+ return wxT( "RATSNEST_VIEWITEM" );
+ }
+
+protected:
+ ///> Object containing ratsnest data.
+ RN_DATA* m_data;
+};
+
+} // namespace KIGFX
+
+#endif /* RATSNEST_VIEWITEM_H */
diff --git a/pcbnew/router/CMakeLists.txt b/pcbnew/router/CMakeLists.txt
new file mode 100644
index 0000000..2f324de
--- /dev/null
+++ b/pcbnew/router/CMakeLists.txt
@@ -0,0 +1,47 @@
+include_directories( BEFORE ${INC_BEFORE} )
+
+include_directories(
+ ./
+ ../
+ ../../include
+ ../../pcbnew
+ ../../polygon
+ ${INC_AFTER}
+)
+
+set( PCBNEW_PNS_SRCS
+ time_limit.cpp
+
+ pns_algo_base.cpp
+ pns_diff_pair.cpp
+ pns_diff_pair_placer.cpp
+ pns_dp_meander_placer.cpp
+ pns_dragger.cpp
+ pns_item.cpp
+ pns_itemset.cpp
+ pns_line.cpp
+ pns_line_placer.cpp
+ pns_logger.cpp
+ pns_meander.cpp
+ pns_meander_placer.cpp
+ pns_meander_placer_base.cpp
+ pns_meander_skew_placer.cpp
+ pns_node.cpp
+ pns_optimizer.cpp
+ pns_router.cpp
+ pns_routing_settings.cpp
+ pns_shove.cpp
+ pns_sizes_settings.cpp
+ pns_solid.cpp
+ pns_tool_base.cpp
+ pns_topology.cpp
+ pns_tune_status_popup.cpp
+ pns_utils.cpp
+ pns_via.cpp
+ pns_walkaround.cpp
+ router_preview_item.cpp
+ router_tool.cpp
+ length_tuner_tool.cpp
+)
+
+add_library( pnsrouter STATIC ${PCBNEW_PNS_SRCS} )
diff --git a/pcbnew/router/direction.h b/pcbnew/router/direction.h
new file mode 100644
index 0000000..402d4c9
--- /dev/null
+++ b/pcbnew/router/direction.h
@@ -0,0 +1,357 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.or/licenses/>.
+ */
+
+#ifndef __DIRECTION_H
+#define __DIRECTION_H
+
+#include <geometry/seg.h>
+#include <geometry/shape_line_chain.h>
+
+/**
+ * Class DIRECTION_45.
+ * Represents route directions & corner angles in a 45-degree metric.
+ */
+
+class DIRECTION_45
+{
+public:
+
+ /**
+ * Enum Directions
+ * Represents available directions - there are 8 of them, as on a rectilinear map (north = up) +
+ * an extra undefined direction, reserved for traces that don't respect 45-degree routing regime.
+ */
+ enum Directions
+ {
+ N = 0,
+ NE = 1,
+ E = 2,
+ SE = 3,
+ S = 4,
+ SW = 5,
+ W = 6,
+ NW = 7,
+ UNDEFINED = -1
+ };
+
+ /**
+ * Enum AngleType
+ * Represents kind of angle formed by vectors heading in two DIRECTION_45s.
+ */
+ enum AngleType
+ {
+ ANG_OBTUSE = 0x01,
+ ANG_RIGHT = 0x02,
+ ANG_ACUTE = 0x04,
+ ANG_STRAIGHT = 0x08,
+ ANG_HALF_FULL = 0x10,
+ ANG_UNDEFINED = 0x20
+ };
+
+ DIRECTION_45( Directions aDir = UNDEFINED ) : m_dir( aDir ) {}
+
+ /**
+ * Constructor
+ * @param aVec vector, whose direction will be translated into a DIRECTION_45.
+ */
+ DIRECTION_45( const VECTOR2I& aVec )
+ {
+ construct_( aVec );
+ }
+
+ /**
+ * Constructor
+ * @param aSeg segment, whose direction will be translated into a DIRECTION_45.
+ */
+ DIRECTION_45( const SEG& aSeg )
+ {
+ construct_( aSeg.B - aSeg.A );
+ }
+
+ /**
+ * Function Format()
+ * Formats the direction in a human readable word.
+ * @return name of the direction
+ */
+ const std::string Format() const
+ {
+ switch( m_dir )
+ {
+ case N:
+ return "north";
+
+ case NE:
+ return "north-east";
+
+ case E:
+ return "east";
+
+ case SE:
+ return "south-east";
+
+ case S:
+ return "south";
+
+ case SW:
+ return "south-west";
+
+ case W:
+ return "west";
+
+ case NW:
+ return "north-west";
+
+ case UNDEFINED:
+ return "undefined";
+
+ default:
+ return "<Error>";
+ }
+ }
+
+ /**
+ * Function Opposite()
+ * Returns a direction opposite (180 degree) to (this)
+ * @return opposite direction
+ */
+ DIRECTION_45 Opposite() const
+ {
+ const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE, UNDEFINED };
+ return OppositeMap[m_dir];
+ }
+
+ /**
+ * Function Angle()
+ * Returns the type of angle between directions (this) and aOther.
+ * @param aOther direction to compare angle with
+ */
+ AngleType Angle( const DIRECTION_45& aOther ) const
+ {
+ if( m_dir == UNDEFINED || aOther.m_dir == UNDEFINED )
+ return ANG_UNDEFINED;
+
+ int d = std::abs( m_dir - aOther.m_dir );
+
+ if( d == 1 || d == 7 )
+ return ANG_OBTUSE;
+ else if( d == 2 || d == 6 )
+ return ANG_RIGHT;
+ else if( d == 3 || d == 5 )
+ return ANG_ACUTE;
+ else if( d == 4 )
+ return ANG_HALF_FULL;
+ else
+ return ANG_STRAIGHT;
+ }
+
+ /**
+ * Function IsObtuse()
+ * @return true, when (this) forms an obtuse angle with aOther
+ */
+ bool IsObtuse( const DIRECTION_45& aOther ) const
+ {
+ return Angle( aOther ) == ANG_OBTUSE;
+ }
+
+ /**
+ * Function IsDiagonal()
+ * Returns true if the direction is diagonal (e.g. North-West, South-East, etc)
+ * @return true, when diagonal.
+ */
+ bool IsDiagonal() const
+ {
+ return ( m_dir % 2 ) == 1;
+ }
+
+ bool IsDefined() const
+ {
+ return m_dir != UNDEFINED;
+ }
+
+ /**
+ * Function BuildInitialTrace()
+ *
+ * Builds a 2-segment line chain between points aP0 and aP1 and following 45-degree routing
+ * regime. If aStartDiagonal is true, the trace starts with a diagonal segment.
+ * @param aP0 starting point
+ * @param aP1 ending point
+ * @param aStartDiagonal whether the first segment has to be diagonal
+ * @return the trace
+ */
+ const SHAPE_LINE_CHAIN BuildInitialTrace( const VECTOR2I& aP0,
+ const VECTOR2I& aP1,
+ bool aStartDiagonal = false ) const
+ {
+ int w = abs( aP1.x - aP0.x );
+ int h = abs( aP1.y - aP0.y );
+ int sw = sign( aP1.x - aP0.x );
+ int sh = sign( aP1.y - aP0.y );
+
+ VECTOR2I mp0, mp1;
+
+ // we are more horizontal than vertical?
+ if( w > h )
+ {
+ mp0 = VECTOR2I( ( w - h ) * sw, 0 ); // direction: E
+ mp1 = VECTOR2I( h * sw, h * sh ); // direction: NE
+ }
+ else
+ {
+ mp0 = VECTOR2I( 0, sh * ( h - w ) ); // direction: N
+ mp1 = VECTOR2I( sw * w, sh * w ); // direction: NE
+ }
+
+ bool start_diagonal;
+
+ if( m_dir == UNDEFINED )
+ start_diagonal = aStartDiagonal;
+ else
+ start_diagonal = IsDiagonal();
+
+ SHAPE_LINE_CHAIN pl;
+
+ pl.Append( aP0 );
+
+ if( start_diagonal )
+ pl.Append( aP0 + mp1 );
+ else
+ pl.Append( aP0 + mp0 );
+
+ pl.Append( aP1 );
+ pl.Simplify();
+ return pl;
+ }
+
+ bool operator==( const DIRECTION_45& aOther ) const
+ {
+ return aOther.m_dir == m_dir;
+ }
+
+ bool operator!=( const DIRECTION_45& aOther ) const
+ {
+ return aOther.m_dir != m_dir;
+ }
+
+ /**
+ * Function Right()
+ *
+ * Returns the direction on the right side of this (i.e. turns right
+ * by 45 deg)
+ */
+ const DIRECTION_45 Right() const
+ {
+ DIRECTION_45 r;
+
+ if ( m_dir != UNDEFINED )
+ r.m_dir = static_cast<Directions>( ( m_dir + 1 ) % 8 );
+
+ return r;
+ }
+
+ /**
+ * Function Left()
+ *
+ * Returns the direction on the left side of this (i.e. turns left
+ * by 45 deg)
+ */
+ const DIRECTION_45 Left() const
+ {
+ DIRECTION_45 l;
+
+ if ( m_dir == UNDEFINED )
+ return l;
+
+ if( m_dir == N )
+ l.m_dir = NW;
+ else
+ l.m_dir = static_cast<Directions>( m_dir - 1 );
+
+ return l;
+ }
+
+ /**
+ * Function ToVector()
+ *
+ * Returns a unit vector corresponding to our direction.
+ */
+ const VECTOR2I ToVector() const
+ {
+ switch( m_dir )
+ {
+ case N: return VECTOR2I( 0, 1 );
+ case S: return VECTOR2I( 0, -1 );
+ case E: return VECTOR2I( 1, 0 );
+ case W: return VECTOR2I( -1, 0 );
+ case NE: return VECTOR2I( 1, 1 );
+ case NW: return VECTOR2I( -1, 1 );
+ case SE: return VECTOR2I( 1, -1 );
+ case SW: return VECTOR2I( -1, -1 );
+
+ default:
+ return VECTOR2I( 0, 0 );
+ }
+ }
+
+ int Mask() const
+ {
+ return 1 << ( (int) m_dir );
+ }
+
+private:
+
+ /**
+ * Function construct()
+ * Calculates the direction from a vector. If the vector's angle is not a multiple of 45
+ * degrees, the direction is rounded to the nearest octant.
+ * @param aVec our vector
+ */
+ void construct_( const VECTOR2I& aVec )
+ {
+ m_dir = UNDEFINED;
+
+ if( aVec.x == 0 && aVec.y == 0 )
+ return;
+
+ double mag = 360.0 - ( 180.0 / M_PI * atan2( (double) aVec.y, (double) aVec.x ) ) + 90.0;
+
+ if( mag >= 360.0 )
+ mag -= 360.0;
+
+ if( mag < 0.0 )
+ mag += 360.0;
+
+ int dir = ( mag + 22.5 ) / 45.0;
+
+ if( dir >= 8 )
+ dir = dir - 8;
+
+ if( dir < 0 )
+ dir = dir + 8;
+
+ m_dir = (Directions) dir;
+
+ return;
+ }
+
+ ///> our actual direction
+ Directions m_dir;
+};
+
+#endif // __DIRECTION_H
diff --git a/pcbnew/router/length_tuner_tool.cpp b/pcbnew/router/length_tuner_tool.cpp
new file mode 100644
index 0000000..7c49db9
--- /dev/null
+++ b/pcbnew/router/length_tuner_tool.cpp
@@ -0,0 +1,311 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+#include <boost/optional.hpp>
+
+#include "class_draw_panel_gal.h"
+#include "class_board.h"
+
+#include <wxPcbStruct.h>
+#include <pcbnew_id.h>
+#include <view/view_controls.h>
+#include <pcb_painter.h>
+#include <dialogs/dialog_pns_settings.h>
+#include <dialogs/dialog_pns_length_tuning_settings.h>
+
+#include <tool/context_menu.h>
+#include <tool/tool_manager.h>
+#include <tools/common_actions.h>
+
+#include "pns_segment.h"
+#include "pns_router.h"
+#include "pns_meander_placer.h" // fixme: move settings to separate header
+#include "pns_tune_status_popup.h"
+
+#include "length_tuner_tool.h"
+
+#include "trace.h"
+
+using namespace KIGFX;
+using boost::optional;
+
+static TOOL_ACTION ACT_StartTuning( "pcbnew.LengthTuner.StartTuning", AS_CONTEXT, 'X',
+ _( "New Track" ), _( "Starts laying a new track." ) );
+
+static TOOL_ACTION ACT_EndTuning( "pcbnew.LengthTuner.EndTuning", AS_CONTEXT, WXK_END,
+ _( "End Track" ), _( "Stops laying the current meander." ) );
+
+static TOOL_ACTION ACT_Settings( "pcbnew.LengthTuner.Settings", AS_CONTEXT, 'L',
+ _( "Length Tuning Settings" ), _( "Sets the length tuning parameters for currently routed item." ) );
+
+static TOOL_ACTION ACT_SpacingIncrease( "pcbnew.LengthTuner.SpacingIncrease", AS_CONTEXT, '1',
+ _( "Increase spacing" ), _( "Increase meander spacing by one step." ) );
+
+static TOOL_ACTION ACT_SpacingDecrease( "pcbnew.LengthTuner.SpacingDecrease", AS_CONTEXT, '2',
+ _( "Decrease spacing" ), _( "Decrease meander spacing by one step." ) );
+
+static TOOL_ACTION ACT_AmplIncrease( "pcbnew.LengthTuner.AmplIncrease", AS_CONTEXT, '3',
+ _( "Increase amplitude" ), _( "Increase meander amplitude by one step." ) );
+
+static TOOL_ACTION ACT_AmplDecrease( "pcbnew.LengthTuner.AmplDecrease", AS_CONTEXT, '4',
+ _( "Decrease amplitude" ), _( "Decrease meander amplitude by one step." ) );
+
+
+LENGTH_TUNER_TOOL::LENGTH_TUNER_TOOL() :
+ PNS_TOOL_BASE( "pcbnew.LengthTuner" )
+{
+}
+
+
+class TUNER_TOOL_MENU: public CONTEXT_MENU
+{
+public:
+ TUNER_TOOL_MENU( BOARD* aBoard )
+ {
+ SetTitle( _( "Length Tuner" ) );
+
+ //Add( ACT_StartTuning );
+ //Add( ACT_EndTuning );
+
+ //AppendSeparator();
+
+ Add( ACT_SpacingIncrease );
+ Add( ACT_SpacingDecrease );
+ Add( ACT_AmplIncrease );
+ Add( ACT_AmplDecrease );
+ Add( ACT_Settings );
+ }
+};
+
+
+LENGTH_TUNER_TOOL::~LENGTH_TUNER_TOOL()
+{
+}
+
+
+void LENGTH_TUNER_TOOL::Reset( RESET_REASON aReason )
+{
+ PNS_TOOL_BASE::Reset( aReason );
+
+ Go( &LENGTH_TUNER_TOOL::TuneSingleTrace, COMMON_ACTIONS::routerActivateTuneSingleTrace.MakeEvent() );
+ Go( &LENGTH_TUNER_TOOL::TuneDiffPair, COMMON_ACTIONS::routerActivateTuneDiffPair.MakeEvent() );
+ Go( &LENGTH_TUNER_TOOL::TuneDiffPairSkew, COMMON_ACTIONS::routerActivateTuneDiffPairSkew.MakeEvent() );
+}
+
+
+void LENGTH_TUNER_TOOL::handleCommonEvents( const TOOL_EVENT& aEvent )
+{
+ if( aEvent.IsAction( &ACT_RouterOptions ) )
+ {
+ DIALOG_PNS_SETTINGS settingsDlg( m_frame, m_router->Settings() );
+
+ if( settingsDlg.ShowModal() == wxID_OK )
+ {
+ // FIXME: do we need an explicit update?
+ }
+ }
+
+ PNS_MEANDER_PLACER_BASE* placer = static_cast<PNS_MEANDER_PLACER_BASE*>( m_router->Placer() );
+
+ if( !placer )
+ return;
+
+ if( aEvent.IsAction( &ACT_Settings ) )
+ {
+ PNS_MEANDER_SETTINGS settings = placer->MeanderSettings();
+ DIALOG_PNS_LENGTH_TUNING_SETTINGS settingsDlg( m_frame, settings, m_router->Mode() );
+
+ if( settingsDlg.ShowModal() )
+ {
+ placer->UpdateSettings( settings );
+ }
+
+ m_savedMeanderSettings = placer->MeanderSettings();
+ }
+}
+
+void LENGTH_TUNER_TOOL::updateStatusPopup( PNS_TUNE_STATUS_POPUP& aPopup )
+{
+ wxPoint p = wxGetMousePosition();
+
+ p.x += 20;
+ p.y += 20;
+
+ aPopup.UpdateStatus( m_router );
+ aPopup.Move( p );
+}
+
+void LENGTH_TUNER_TOOL::performTuning()
+{
+ if( m_startItem )
+ {
+ m_frame->SetActiveLayer( ToLAYER_ID ( m_startItem->Layers().Start() ) );
+
+ if( m_startItem->Net() >= 0 )
+ highlightNet( true, m_startItem->Net() );
+ }
+
+ m_ctls->ForceCursorPosition( false );
+ m_ctls->SetAutoPan( true );
+
+ if( !m_router->StartRouting( m_startSnapPoint, m_startItem, 0 ) )
+ {
+ wxMessageBox( m_router->FailureReason(), _( "Error" ) );
+ highlightNet( false );
+ return;
+ }
+
+ PNS_MEANDER_PLACER_BASE* placer = static_cast<PNS_MEANDER_PLACER_BASE*>( m_router->Placer() );
+
+ placer->UpdateSettings( m_savedMeanderSettings );
+
+ VECTOR2I end( m_startSnapPoint );
+
+ PNS_TUNE_STATUS_POPUP statusPopup( m_frame );
+ statusPopup.Popup();
+
+ m_router->Move( end, NULL );
+ updateStatusPopup( statusPopup );
+
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ if( evt->IsCancel() || evt->IsActivate() )
+ break;
+ else if( evt->IsMotion() )
+ {
+ end = evt->Position();
+ m_router->Move( end, NULL );
+ updateStatusPopup( statusPopup );
+ }
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ if( m_router->FixRoute( evt->Position(), NULL ) )
+ break;
+ }
+ else if( evt->IsAction( &ACT_EndTuning ) )
+ {
+ if( m_router->FixRoute( end, NULL ) )
+ break;
+ }
+ else if( evt->IsAction( &ACT_AmplDecrease ) )
+ {
+ placer->AmplitudeStep( -1 );
+ m_router->Move( end, NULL );
+ }
+ else if( evt->IsAction( &ACT_AmplIncrease ) )
+ {
+ placer->AmplitudeStep( 1 );
+ m_router->Move( end, NULL );
+ }
+ else if(evt->IsAction( &ACT_SpacingDecrease ) )
+ {
+ placer->SpacingStep( -1 );
+ m_router->Move( end, NULL );
+ }
+ else if( evt->IsAction( &ACT_SpacingIncrease ) )
+ {
+ placer->SpacingStep( 1 );
+ m_router->Move( end, NULL );
+ }
+
+ handleCommonEvents( *evt );
+ }
+
+ m_router->StopRouting();
+
+ // Save the recent changes in the undo buffer
+ m_frame->SaveCopyInUndoList( m_router->GetUndoBuffer(), UR_UNSPECIFIED );
+ m_router->ClearUndoBuffer();
+ m_frame->OnModify();
+
+ highlightNet( false );
+}
+
+
+int LENGTH_TUNER_TOOL::TuneSingleTrace( const TOOL_EVENT& aEvent )
+{
+ m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Trace Length" ) );
+ return mainLoop( PNS_MODE_TUNE_SINGLE );
+}
+
+
+int LENGTH_TUNER_TOOL::TuneDiffPair( const TOOL_EVENT& aEvent )
+{
+ m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Diff Pair Length" ) );
+ return mainLoop( PNS_MODE_TUNE_DIFF_PAIR );
+}
+
+
+int LENGTH_TUNER_TOOL::TuneDiffPairSkew( const TOOL_EVENT& aEvent )
+{
+ m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Tune Diff Pair Skew" ) );
+ return mainLoop( PNS_MODE_TUNE_DIFF_PAIR_SKEW );
+}
+
+
+int LENGTH_TUNER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
+{
+ // Deselect all items
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ Activate();
+
+ m_router->SetMode( aMode );
+
+ m_ctls->SetSnapping( true );
+ m_ctls->ShowCursor( true );
+ m_frame->UndoRedoBlock( true );
+
+ std::auto_ptr<TUNER_TOOL_MENU> ctxMenu( new TUNER_TOOL_MENU( m_board ) );
+ SetContextMenu( ctxMenu.get() );
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ if( m_needsSync )
+ {
+ m_router->SyncWorld();
+ m_router->SetView( getView() );
+ m_needsSync = false;
+ }
+
+ if( evt->IsCancel() || evt->IsActivate() )
+ break; // Finish
+ else if( evt->IsMotion() )
+ updateStartItem( *evt );
+ else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_StartTuning ) )
+ {
+ updateStartItem( *evt );
+ performTuning();
+ }
+
+ handleCommonEvents( *evt );
+ }
+
+ m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+ m_frame->UndoRedoBlock( false );
+
+ // Store routing settings till the next invocation
+ m_savedSettings = m_router->Settings();
+ m_savedSizes = m_router->Sizes();
+
+ return 0;
+}
diff --git a/pcbnew/router/length_tuner_tool.h b/pcbnew/router/length_tuner_tool.h
new file mode 100644
index 0000000..075d907
--- /dev/null
+++ b/pcbnew/router/length_tuner_tool.h
@@ -0,0 +1,54 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ * Author: Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LENGTH_TUNER_TOOL_H
+#define __LENGTH_TUNER_TOOL_H
+
+#include "pns_tool_base.h"
+#include "pns_meander.h"
+
+class PNS_TUNE_STATUS_POPUP;
+
+class APIEXPORT LENGTH_TUNER_TOOL : public PNS_TOOL_BASE
+{
+public:
+ LENGTH_TUNER_TOOL();
+ ~LENGTH_TUNER_TOOL();
+
+ void Reset( RESET_REASON aReason );
+
+ int TuneSingleTrace( const TOOL_EVENT& aEvent );
+ int TuneDiffPair( const TOOL_EVENT& aEvent );
+ int TuneDiffPairSkew( const TOOL_EVENT& aEvent );
+ int ClearMeanders( const TOOL_EVENT& aEvent );
+
+private:
+ void performTuning( );
+ int mainLoop( PNS_ROUTER_MODE aMode );
+ void handleCommonEvents( const TOOL_EVENT& aEvent );
+ void updateStatusPopup ( PNS_TUNE_STATUS_POPUP& aPopup );
+
+
+
+ PNS_MEANDER_SETTINGS m_savedMeanderSettings;
+};
+
+#endif
diff --git a/pcbnew/router/pns_algo_base.cpp b/pcbnew/router/pns_algo_base.cpp
new file mode 100644
index 0000000..b72243b
--- /dev/null
+++ b/pcbnew/router/pns_algo_base.cpp
@@ -0,0 +1,32 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pns_algo_base.h"
+#include "pns_router.h"
+
+PNS_ROUTING_SETTINGS& PNS_ALGO_BASE::Settings() const
+{
+ return m_router->Settings();
+}
+
+PNS_LOGGER *PNS_ALGO_BASE::Logger()
+{
+ return NULL;
+}
diff --git a/pcbnew/router/pns_algo_base.h b/pcbnew/router/pns_algo_base.h
new file mode 100644
index 0000000..a6429ea
--- /dev/null
+++ b/pcbnew/router/pns_algo_base.h
@@ -0,0 +1,62 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_ALGO_BASE_H
+#define __PNS_ALGO_BASE_H
+
+#include <wx/wx.h> // for wxString
+
+#include "pns_routing_settings.h"
+
+class PNS_ROUTER;
+class PNS_LOGGER;
+
+/**
+ * Class PNS_ALGO_BASE
+ *
+ * Base class for all P&S algorithms (shoving, walkaround, line placement, dragging, etc.)
+ * Holds a bunch of objects commonly used by all algorithms (P&S settings, parent router instance, logging)
+ */
+class PNS_ALGO_BASE
+{
+public:
+ PNS_ALGO_BASE( PNS_ROUTER* aRouter ) :
+ m_router( aRouter )
+ {}
+
+ virtual ~PNS_ALGO_BASE() {}
+
+ ///> Returns the instance of our router
+ PNS_ROUTER* Router() const
+ {
+ return m_router;
+ }
+
+ ///> Returns current router settings
+ PNS_ROUTING_SETTINGS& Settings() const;
+
+ ///> Returns the logger object, allowing to dump geometry to a file.
+ virtual PNS_LOGGER* Logger();
+
+private:
+ PNS_ROUTER* m_router;
+};
+
+#endif
diff --git a/pcbnew/router/pns_diff_pair.cpp b/pcbnew/router/pns_diff_pair.cpp
new file mode 100644
index 0000000..771928b
--- /dev/null
+++ b/pcbnew/router/pns_diff_pair.cpp
@@ -0,0 +1,870 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+
+#include <cstdio>
+#include <cstdlib>
+#include <limits>
+
+#include <geometry/shape.h>
+#include <geometry/shape_rect.h>
+#include <geometry/shape_circle.h>
+#include <geometry/shape_segment.h>
+
+#include "direction.h"
+
+#include "pns_diff_pair.h"
+#include "pns_router.h"
+#include "pns_solid.h"
+#include "pns_utils.h"
+
+
+class PNS_LINE;
+
+PNS_DP_PRIMITIVE_PAIR::PNS_DP_PRIMITIVE_PAIR( PNS_ITEM* aPrimP, PNS_ITEM* aPrimN )
+{
+ m_primP = aPrimP->Clone();
+ m_primN = aPrimN->Clone();
+
+ m_anchorP = m_primP->Anchor( 0 );
+ m_anchorN = m_primN->Anchor( 0 );
+}
+
+
+void PNS_DP_PRIMITIVE_PAIR::SetAnchors( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN )
+{
+ m_anchorP = aAnchorP;
+ m_anchorN = aAnchorN;
+}
+
+
+PNS_DP_PRIMITIVE_PAIR::PNS_DP_PRIMITIVE_PAIR( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN )
+{
+ m_anchorP = aAnchorP;
+ m_anchorN = aAnchorN;
+ m_primP = m_primN = NULL;
+}
+
+
+PNS_DP_PRIMITIVE_PAIR::PNS_DP_PRIMITIVE_PAIR( const PNS_DP_PRIMITIVE_PAIR& aOther )
+{
+ m_primP = m_primN = NULL;
+
+ if( aOther.m_primP )
+ m_primP = aOther.m_primP->Clone();
+
+ if( aOther.m_primN )
+ m_primN = aOther.m_primN->Clone();
+
+ m_anchorP = aOther.m_anchorP;
+ m_anchorN = aOther.m_anchorN;
+}
+
+
+PNS_DP_PRIMITIVE_PAIR& PNS_DP_PRIMITIVE_PAIR::operator=( const PNS_DP_PRIMITIVE_PAIR& aOther )
+{
+ if( aOther.m_primP )
+ m_primP = aOther.m_primP->Clone();
+ if( aOther.m_primN )
+ m_primN = aOther.m_primN->Clone();
+
+ m_anchorP = aOther.m_anchorP;
+ m_anchorN = aOther.m_anchorN;
+
+ return *this;
+}
+
+
+PNS_DP_PRIMITIVE_PAIR::~PNS_DP_PRIMITIVE_PAIR()
+{
+ delete m_primP;
+ delete m_primN;
+}
+
+
+bool PNS_DP_PRIMITIVE_PAIR::Directional() const
+{
+ if( !m_primP )
+ return false;
+
+ return m_primP->OfKind( PNS_ITEM::SEGMENT );
+}
+
+
+DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::anchorDirection( PNS_ITEM* aItem, const VECTOR2I& aP ) const
+{
+ if( !aItem->OfKind ( PNS_ITEM::SEGMENT ) )
+ return DIRECTION_45();
+
+ PNS_SEGMENT* s = static_cast<PNS_SEGMENT*>( aItem );
+
+ if( s->Seg().A == aP )
+ return DIRECTION_45( s->Seg().A - s->Seg().B );
+ else
+ return DIRECTION_45( s->Seg().B - s->Seg().A );
+}
+
+
+DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirP() const
+{
+ return anchorDirection( m_primP, m_anchorP );
+}
+
+
+DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirN() const
+{
+ return anchorDirection( m_primN, m_anchorN );
+}
+
+
+static void drawGw( VECTOR2I p, int color )
+{
+ SHAPE_LINE_CHAIN l;
+
+ l.Append( p - VECTOR2I( -50000, -50000 ) );
+ l.Append( p + VECTOR2I( -50000, -50000 ) );
+
+ l.Clear();
+ l.Append( p - VECTOR2I( 50000, -50000 ) );
+ l.Append( p + VECTOR2I( 50000, -50000 ) );
+}
+
+
+static DIRECTION_45::AngleType angle( const VECTOR2I &a, const VECTOR2I &b )
+{
+ DIRECTION_45 dir_a( a );
+ DIRECTION_45 dir_b( b );
+
+ return dir_a.Angle( dir_b );
+}
+
+
+static bool checkGap( const SHAPE_LINE_CHAIN &p, const SHAPE_LINE_CHAIN &n, int gap )
+{
+ int i, j;
+
+ for( i = 0; i < p.SegmentCount(); i++ )
+ {
+ for( j = 0; j < n.SegmentCount() ; j++ )
+ {
+ int dist = p.CSegment( i ).Distance( n.CSegment( j ) );
+
+ if( dist < gap - 100 )
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+void PNS_DP_GATEWAY::Reverse()
+{
+ m_entryN = m_entryN.Reverse();
+ m_entryP = m_entryP.Reverse();
+}
+
+
+bool PNS_DIFF_PAIR::BuildInitial( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY &aTarget, bool aPrefDiagonal )
+{
+ SHAPE_LINE_CHAIN p = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorP(), aTarget.AnchorP(), aPrefDiagonal );
+ SHAPE_LINE_CHAIN n = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorN(), aTarget.AnchorN(), aPrefDiagonal );
+
+ int mask = aEntry.AllowedAngles() | DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_OBTUSE;
+
+ SHAPE_LINE_CHAIN sum_n, sum_p;
+ m_p = p;
+ m_n = n;
+
+ if( aEntry.HasEntryLines() )
+ {
+ if( !aEntry.Entry().CheckConnectionAngle( *this, mask ) )
+ return false;
+
+ sum_p = aEntry.Entry().CP();
+ sum_n = aEntry.Entry().CN();
+ sum_p.Append( p );
+ sum_n.Append( n );
+ }
+ else
+ {
+ sum_p = p;
+ sum_n = n;
+ }
+
+ mask = aTarget.AllowedAngles() | DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_OBTUSE;
+
+ m_p = sum_p;
+ m_n = sum_n;
+
+ if( aTarget.HasEntryLines() )
+ {
+ PNS_DP_GATEWAY t(aTarget) ;
+ t.Reverse();
+
+ if( !CheckConnectionAngle( t.Entry(), mask ) )
+ return false;
+
+ sum_p.Append( t.Entry().CP() );
+ sum_n.Append( t.Entry().CN() );
+ }
+
+ m_p = sum_p;
+ m_n = sum_n;
+
+ if( !checkGap ( p, n, m_gapConstraint ) )
+ return false;
+
+ if( p.SelfIntersecting() || n.SelfIntersecting() )
+ return false;
+
+ if( p.Intersects( n ) )
+ return false;
+
+ return true;
+}
+
+
+bool PNS_DIFF_PAIR::CheckConnectionAngle( const PNS_DIFF_PAIR& aOther, int aAllowedAngles ) const
+{
+ bool checkP, checkN;
+
+ if( m_p.SegmentCount() == 0 || aOther.m_p.SegmentCount() == 0 )
+ checkP = true;
+ else
+ {
+ DIRECTION_45 p0( m_p.CSegment( -1 ) );
+ DIRECTION_45 p1( aOther.m_p.CSegment( 0 ) );
+
+ checkP = ( p0.Angle( p1 ) & aAllowedAngles ) != 0;
+ }
+
+ if( m_n.SegmentCount() == 0 || aOther.m_n.SegmentCount() == 0 )
+ checkN = true;
+ else
+ {
+ DIRECTION_45 n0( m_n.CSegment( -1 ) );
+ DIRECTION_45 n1( aOther.m_n.CSegment( 0 ) );
+
+ checkN = ( n0.Angle( n1 ) & aAllowedAngles ) != 0;
+ }
+
+ return checkP && checkN;
+}
+
+
+const PNS_DIFF_PAIR PNS_DP_GATEWAY::Entry() const
+{
+ return PNS_DIFF_PAIR( m_entryP, m_entryN, 0 );
+}
+
+
+void PNS_DP_GATEWAYS::BuildOrthoProjections( PNS_DP_GATEWAYS& aEntries,
+ const VECTOR2I& aCursorPos, int aOrthoScore )
+{
+ BOOST_FOREACH( PNS_DP_GATEWAY g, aEntries.Gateways() )
+ {
+ VECTOR2I midpoint( ( g.AnchorP() + g.AnchorN() ) / 2 );
+ SEG guide_s( midpoint, midpoint + VECTOR2I( 1, 0 ) );
+ SEG guide_d( midpoint, midpoint + VECTOR2I( 1, 1 ) );
+
+ VECTOR2I proj_s = guide_s.LineProject( aCursorPos );
+ VECTOR2I proj_d = guide_d.LineProject( aCursorPos );
+
+ int dist_s = ( proj_s - aCursorPos ).EuclideanNorm();
+ int dist_d = ( proj_d - aCursorPos ).EuclideanNorm();
+
+
+ VECTOR2I proj = ( dist_s < dist_d ? proj_s : proj_d );
+
+ PNS_DP_GATEWAYS targets( m_gap );
+
+ targets.m_viaGap = m_viaGap;
+ targets.m_viaDiameter = m_viaDiameter;
+ targets.m_fitVias = m_fitVias;
+
+ targets.BuildForCursor( proj );
+
+ BOOST_FOREACH( PNS_DP_GATEWAY t, targets.Gateways() )
+ {
+ t.SetPriority( aOrthoScore );
+ m_gateways.push_back( t );
+ }
+ }
+}
+
+
+bool PNS_DP_GATEWAYS::FitGateways( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& aTarget,
+ bool aPrefDiagonal, PNS_DIFF_PAIR& aDp )
+{
+ std::vector<DP_CANDIDATE> candidates;
+
+ BOOST_FOREACH( PNS_DP_GATEWAY g_entry, aEntry.Gateways() )
+ {
+ BOOST_FOREACH( PNS_DP_GATEWAY g_target, aTarget.Gateways() )
+ {
+ for( int attempt = 0; attempt < 2; attempt++ )
+ {
+ PNS_DIFF_PAIR l( m_gap );
+
+ if( l.BuildInitial( g_entry, g_target, aPrefDiagonal ^ ( attempt ? true : false ) ) )
+ {
+ int score = ( attempt == 1 ? -3 : 0 );
+ score +=g_entry.Priority();
+ score +=g_target.Priority();
+
+ DP_CANDIDATE c;
+ c.score = score;
+ c.p = l.CP();
+ c.n = l.CN();
+ candidates.push_back( c );
+ }
+ }
+ }
+ }
+
+ int bestScore = -1000;
+ DP_CANDIDATE best;
+ bool found = false;
+
+ BOOST_FOREACH( DP_CANDIDATE c, candidates )
+ {
+ if( c.score > bestScore )
+ {
+ bestScore = c.score;
+ best = c;
+ found = true;
+ }
+ }
+
+ if( found )
+ {
+ aDp.SetGap( m_gap );
+ aDp.SetShape( best.p, best.n );
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PNS_DP_GATEWAYS::checkDiagonalAlignment( const VECTOR2I& a, const VECTOR2I& b ) const
+{
+ VECTOR2I dir ( std::abs (a.x - b.x), std::abs ( a.y - b.y ));
+
+ return (dir.x == 0 && dir.y != 0) || (dir.x == dir.y) || (dir.y == 0 && dir.x != 0);
+}
+
+
+void PNS_DP_GATEWAYS::BuildFromPrimitivePair( PNS_DP_PRIMITIVE_PAIR aPair, bool aPreferDiagonal )
+{
+ VECTOR2I majorDirection;
+ VECTOR2I p0_p, p0_n;
+ int orthoFanDistance;
+ int diagFanDistance;
+ const SHAPE* shP = NULL;
+
+ if( aPair.PrimP() == NULL )
+ {
+ BuildGeneric( aPair.AnchorP(), aPair.AnchorN(), true );
+ return;
+ }
+
+ const int pvMask = PNS_ITEM::SOLID | PNS_ITEM::VIA;
+
+ if( aPair.PrimP()->OfKind( pvMask ) && aPair.PrimN()->OfKind( pvMask ) )
+ {
+ p0_p = aPair.AnchorP();
+ p0_n = aPair.AnchorN();
+
+ shP = aPair.PrimP()->Shape();
+ }
+ else if( aPair.PrimP()->OfKind( PNS_ITEM::SEGMENT ) && aPair.PrimN()->OfKind( PNS_ITEM::SEGMENT ) )
+ {
+ buildDpContinuation( aPair, aPreferDiagonal );
+
+ return;
+ }
+
+ majorDirection = ( p0_p - p0_n ).Perpendicular();
+
+ if( shP == NULL )
+ return;
+
+ switch( shP->Type() )
+ {
+ case SH_RECT:
+ {
+ int w = static_cast<const SHAPE_RECT*>( shP )->GetWidth();
+ int h = static_cast<const SHAPE_RECT*>( shP )->GetHeight();
+
+ if( w < h )
+ std::swap( w, h );
+
+ orthoFanDistance = w * 3/4;
+ diagFanDistance = ( w - h ) / 2;
+ break;
+ }
+
+ case SH_SEGMENT:
+ {
+ int w = static_cast<const SHAPE_SEGMENT*>( shP )->GetWidth();
+ SEG s = static_cast<const SHAPE_SEGMENT*>( shP )->GetSeg();
+
+ orthoFanDistance = w + ( s.B - s.A ).EuclideanNorm() / 2;
+ diagFanDistance = ( s.B - s.A ).EuclideanNorm() / 2;
+ break;
+ }
+
+ default:
+ BuildGeneric ( p0_p, p0_n, true );
+ return;
+ }
+
+ if( checkDiagonalAlignment( p0_p, p0_n ) )
+ {
+ int padDist = ( p0_p - p0_n ).EuclideanNorm();
+
+ for( int k = 0; k < 2; k++ )
+ {
+ VECTOR2I dir, dp, dv;
+
+ if( k == 0 )
+ {
+ dir = majorDirection.Resize( orthoFanDistance );
+ int d = ( padDist - m_gap ) / 2;
+
+ dp = dir.Resize( d );
+ dv = ( p0_n - p0_p ).Resize( d );
+ }
+ else
+ {
+ dir = majorDirection.Resize( diagFanDistance );
+ int d = ( padDist - m_gap ) / 2;
+ dp = dir.Resize( d );
+ dv = ( p0_n - p0_p ).Resize( d );
+ }
+
+ for( int i = 0; i < 2; i++ )
+ {
+ int sign = i ? -1 : 1;
+
+ VECTOR2I gw_p( p0_p + sign * ( dir + dp ) + dv );
+ VECTOR2I gw_n( p0_n + sign * ( dir + dp ) - dv );
+
+ SHAPE_LINE_CHAIN entryP( p0_p, p0_p + sign * dir, gw_p );
+ SHAPE_LINE_CHAIN entryN( p0_n, p0_n + sign * dir, gw_n );
+
+ PNS_DP_GATEWAY gw( gw_p, gw_n, false );
+
+ gw.SetEntryLines( entryP, entryN );
+ gw.SetPriority( 100 - k );
+ m_gateways.push_back( gw );
+ }
+ }
+ }
+
+ BuildGeneric( p0_p, p0_n, true );
+}
+
+
+void PNS_DP_GATEWAYS::BuildForCursor( const VECTOR2I& aCursorPos )
+{
+ int gap = m_fitVias ? m_viaGap + m_viaDiameter : m_gap;
+
+ for( int attempt = 0; attempt < 2; attempt++ )
+ {
+ for( int i = 0; i < 4; i++ )
+ {
+ VECTOR2I dir;
+
+ if( !attempt )
+ {
+ dir = VECTOR2I( gap, gap ).Resize( gap / 2 );
+
+ if( i % 2 == 0 )
+ dir.x = -dir.x;
+
+ if( i / 2 == 0 )
+ dir.y = -dir.y;
+ }
+ else
+ {
+ if( i /2 == 0 )
+ dir = VECTOR2I( gap / 2 * ( ( i % 2 ) ? -1 : 1 ), 0 );
+ else
+ dir = VECTOR2I( 0, gap / 2 * ( ( i % 2 ) ? -1 : 1) );
+ }
+
+ if( m_fitVias )
+ BuildGeneric( aCursorPos + dir, aCursorPos - dir, true, true );
+ else
+ m_gateways.push_back( PNS_DP_GATEWAY( aCursorPos + dir,
+ aCursorPos - dir, attempt ? true : false ) );
+
+ drawGw ( aCursorPos + dir, 2 );
+ drawGw ( aCursorPos - dir, 3 );
+ }
+ }
+}
+
+
+void PNS_DP_GATEWAYS::buildEntries( const VECTOR2I& p0_p, const VECTOR2I& p0_n )
+{
+ BOOST_FOREACH( PNS_DP_GATEWAY &g, m_gateways )
+ {
+ if( !g.HasEntryLines() )
+ {
+ SHAPE_LINE_CHAIN lead_p = DIRECTION_45().BuildInitialTrace ( g.AnchorP(), p0_p, g.IsDiagonal() ).Reverse();
+ SHAPE_LINE_CHAIN lead_n = DIRECTION_45().BuildInitialTrace ( g.AnchorN(), p0_n, g.IsDiagonal() ).Reverse();
+ g.SetEntryLines( lead_p, lead_n );
+ }
+ }
+}
+
+
+void PNS_DP_GATEWAYS::buildDpContinuation( PNS_DP_PRIMITIVE_PAIR aPair, bool aIsDiagonal )
+{
+ PNS_DP_GATEWAY gw( aPair.AnchorP(), aPair.AnchorN(), aIsDiagonal );
+ gw.SetPriority( 100 );
+ m_gateways.push_back( gw );
+
+ if( !aPair.Directional() )
+ return;
+
+ DIRECTION_45 dP = aPair.DirP();
+ DIRECTION_45 dN = aPair.DirN();
+
+ int gap = ( aPair.AnchorP() - aPair.AnchorN() ).EuclideanNorm();
+
+ VECTOR2I vdP = aPair.AnchorP() + dP.Left().ToVector();
+ VECTOR2I vdN = aPair.AnchorN() + dN.Left().ToVector();
+
+ PNS_SEGMENT* sP = static_cast<PNS_SEGMENT*>( aPair.PrimP() );
+
+ VECTOR2I t1, t2;
+
+ if( sP->Seg().Side( vdP ) == sP->Seg().Side( vdN ) )
+ {
+ t1 = aPair.AnchorP() + dP.Left().ToVector().Resize( gap );
+ t2 = aPair.AnchorN() + dP.Right().ToVector().Resize( gap );
+ }
+ else
+ {
+ t1 = aPair.AnchorP() + dP.Right().ToVector().Resize( gap );
+ t2 = aPair.AnchorN() + dP.Left().ToVector().Resize( gap );
+ }
+
+ PNS_DP_GATEWAY gwL( t2, aPair.AnchorN(), !aIsDiagonal );
+ SHAPE_LINE_CHAIN ep = dP.BuildInitialTrace( aPair.AnchorP(), t2, !aIsDiagonal );
+
+ gwL.SetPriority( 10 );
+ gwL.SetEntryLines( ep , SHAPE_LINE_CHAIN() );
+
+ m_gateways.push_back( gwL );
+
+ PNS_DP_GATEWAY gwR( aPair.AnchorP(), t1, !aIsDiagonal );
+ SHAPE_LINE_CHAIN en = dP.BuildInitialTrace( aPair.AnchorN(), t1, !aIsDiagonal );
+ gwR.SetPriority( 10) ;
+ gwR.SetEntryLines( SHAPE_LINE_CHAIN(), en );
+
+ m_gateways.push_back( gwR );
+}
+
+
+void PNS_DP_GATEWAYS::BuildGeneric( const VECTOR2I& p0_p, const VECTOR2I& p0_n, bool aBuildEntries, bool aViaMode )
+{
+ SEG st_p[2], st_n[2];
+ SEG d_n[2], d_p[2];
+
+ const int padToGapThreshold = 3;
+ int padDist = ( p0_p - p0_p ).EuclideanNorm();
+
+ st_p[0] = SEG(p0_p + VECTOR2I( -100, 0 ), p0_p + VECTOR2I( 100, 0 ) );
+ st_n[0] = SEG(p0_n + VECTOR2I( -100, 0 ), p0_n + VECTOR2I( 100, 0 ) );
+ st_p[1] = SEG(p0_p + VECTOR2I( 0, -100 ), p0_p + VECTOR2I( 0, 100 ) );
+ st_n[1] = SEG(p0_n + VECTOR2I( 0, -100 ), p0_n + VECTOR2I( 0, 100 ) );
+ d_p[0] = SEG( p0_p + VECTOR2I( -100, -100 ), p0_p + VECTOR2I( 100, 100 ) );
+ d_p[1] = SEG( p0_p + VECTOR2I( 100, -100 ), p0_p + VECTOR2I( -100, 100 ) );
+ d_n[0] = SEG( p0_n + VECTOR2I( -100, -100 ), p0_n + VECTOR2I( 100, 100 ) );
+ d_n[1] = SEG( p0_n + VECTOR2I( 100, -100 ), p0_n + VECTOR2I( -100, 100 ) );
+
+ // midpoint exit & side-by exits
+ for( int i = 0; i < 2; i++ )
+ {
+ bool straightColl = st_p[i].Collinear( st_n[i] );
+ bool diagColl = d_p[i].Collinear( d_n[i] );
+
+ if( straightColl || diagColl )
+ {
+ VECTOR2I dir = ( p0_n - p0_p ).Resize( m_gap / 2 );
+ VECTOR2I m = ( p0_p + p0_n ) / 2;
+ int prio = ( padDist > padToGapThreshold * m_gap ? 2 : 1);
+
+ if( !aViaMode )
+ {
+ m_gateways.push_back( PNS_DP_GATEWAY( m - dir, m + dir, diagColl, DIRECTION_45::ANG_RIGHT, prio ) );
+
+ dir = ( p0_n - p0_p ).Resize( m_gap );
+ m_gateways.push_back( PNS_DP_GATEWAY( p0_p - dir, p0_p - dir + dir.Perpendicular(), diagColl ) );
+ m_gateways.push_back( PNS_DP_GATEWAY( p0_p - dir, p0_p - dir - dir.Perpendicular(), diagColl ) );
+ m_gateways.push_back( PNS_DP_GATEWAY( p0_n + dir + dir.Perpendicular(), p0_n + dir, diagColl ) );
+ m_gateways.push_back( PNS_DP_GATEWAY( p0_n + dir - dir.Perpendicular(), p0_n + dir, diagColl ) );
+ }
+ }
+ }
+
+ for( int i = 0; i < 2; i++ )
+ {
+ for( int j = 0; j < 2; j++ )
+ {
+ OPT_VECTOR2I ips[2];
+
+ ips[0] = d_n[i].IntersectLines( d_p[j] );
+ ips[1] = st_p[i].IntersectLines( st_n[j] );
+
+ if( d_n[i].Collinear( d_p[j] ) )
+ ips[0] = boost::none;
+ if( st_p[i].Collinear( st_p[j] ) )
+ ips[1] = boost::none;
+
+ // diagonal-diagonal and straight-straight cases - the most typical case if the pads
+ // are on the same straight/diagonal line
+ for( int k = 0; k < 2; k++ )
+ {
+ if( ips[k] )
+ {
+ const VECTOR2I m( *ips[k] );
+
+ if( m != p0_p && m != p0_n )
+ {
+ int prio = ( padDist > padToGapThreshold * m_gap ? 10 : 20 );
+ VECTOR2I g_p( ( p0_p - m ).Resize( (double) m_gap * M_SQRT1_2 ) );
+ VECTOR2I g_n( ( p0_n - m ).Resize( (double) m_gap * M_SQRT1_2 ) );
+
+ m_gateways.push_back( PNS_DP_GATEWAY( m + g_p, m + g_n, k == 0 ? true : false, DIRECTION_45::ANG_OBTUSE, prio ) );
+ }
+ }
+ }
+
+ ips[0] = st_n[i].IntersectLines( d_p[j] );
+ ips[1] = st_p[i].IntersectLines( d_n[j] );
+
+// diagonal-straight cases: 8 possibilities of "weirder" exists
+ for( int k = 0; k < 2; k++ )
+ {
+ if( ips[k] )
+ {
+ const VECTOR2I m( *ips[k] );
+
+ if( !aViaMode && m != p0_p && m != p0_n )
+ {
+ VECTOR2I g_p, g_n;
+
+ g_p = ( p0_p - m ).Resize( (double) m_gap * M_SQRT2 );
+ g_n = ( p0_n - m ).Resize( (double) m_gap );
+
+ if( angle( g_p, g_n ) != DIRECTION_45::ANG_ACUTE )
+ m_gateways.push_back( PNS_DP_GATEWAY( m + g_p, m + g_n, true ) );
+
+ g_p = ( p0_p - m ).Resize( m_gap );
+ g_n = ( p0_n - m ).Resize( (double) m_gap * M_SQRT2 );
+
+ if( angle( g_p, g_n ) != DIRECTION_45::ANG_ACUTE )
+ m_gateways.push_back( PNS_DP_GATEWAY( m + g_p, m + g_n, true ) );
+ }
+ }
+ }
+ }
+ }
+
+ if( aBuildEntries )
+ buildEntries( p0_p, p0_n );
+}
+
+
+PNS_DP_PRIMITIVE_PAIR PNS_DIFF_PAIR::EndingPrimitives()
+{
+ if( m_hasVias )
+ return PNS_DP_PRIMITIVE_PAIR( &m_via_p, &m_via_n );
+ else
+ {
+ const PNS_LINE lP( PLine() );
+ const PNS_LINE lN( NLine() );
+
+ PNS_SEGMENT sP( lP, lP.CSegment( -1 ) );
+ PNS_SEGMENT sN( lN, lN.CSegment( -1 ) );
+
+ PNS_DP_PRIMITIVE_PAIR dpair( &sP, &sN );
+ dpair.SetAnchors( sP.Seg().B, sN.Seg().B );
+
+ return dpair;
+ }
+}
+
+
+bool commonParallelProjection( SEG n, SEG p, SEG &pClip, SEG& nClip )
+{
+ SEG n_proj_p( p.LineProject( n.A ), p.LineProject( n.B ) );
+
+ int64_t t_a = 0;
+ int64_t t_b = p.TCoef( p.B );
+
+ int64_t tproj_a = p.TCoef( n_proj_p.A );
+ int64_t tproj_b = p.TCoef( n_proj_p.B );
+
+ if( t_b < t_a )
+ std::swap( t_b, t_a );
+
+ if( tproj_b < tproj_a )
+ std::swap( tproj_b, tproj_a );
+
+ if( t_b <= tproj_a )
+ return false;
+
+ if( t_a >= tproj_b )
+ return false;
+
+ int64_t t[4] = { 0, p.TCoef( p.B ), p.TCoef( n_proj_p.A ), p.TCoef( n_proj_p.B ) };
+ std::vector<int64_t> tv( t, t + 4 );
+ std::sort( tv.begin(), tv.end() ); // fixme: awful and disgusting way of finding 2 midpoints
+
+ int64_t pLenSq = p.SquaredLength();
+
+ VECTOR2I dp = p.B - p.A;
+ pClip.A.x = p.A.x + rescale( (int64_t)dp.x, tv[1], pLenSq );
+ pClip.A.y = p.A.y + rescale( (int64_t)dp.y, tv[1], pLenSq );
+
+ pClip.B.x = p.A.x + rescale( (int64_t)dp.x, tv[2], pLenSq );
+ pClip.B.y = p.A.y + rescale( (int64_t)dp.y, tv[2], pLenSq );
+
+ nClip.A = n.LineProject( pClip.A );
+ nClip.B = n.LineProject( pClip.B );
+
+ return true;
+}
+
+
+double PNS_DIFF_PAIR::Skew() const
+{
+ return m_p.Length() - m_n.Length();
+}
+
+
+void PNS_DIFF_PAIR::CoupledSegmentPairs( COUPLED_SEGMENTS_VEC& aPairs ) const
+{
+ SHAPE_LINE_CHAIN p( m_p );
+ SHAPE_LINE_CHAIN n( m_n );
+
+ p.Simplify();
+ n.Simplify();
+
+ for( int i = 0; i < p.SegmentCount(); i++ )
+ {
+ for( int j = 0; j < n.SegmentCount(); j++ )
+ {
+ SEG sp = p.CSegment( i );
+ SEG sn = n.CSegment( j );
+
+ SEG p_clip, n_clip;
+
+ int64_t dist = std::abs( sp.Distance( sn ) - m_width );
+
+ if( sp.ApproxParallel( sn ) && m_gapConstraint.Matches( dist ) && commonParallelProjection( sp, sn, p_clip, n_clip ) )
+ {
+ const COUPLED_SEGMENTS spair( p_clip, sp, i, n_clip, sn, j );
+ aPairs.push_back( spair );
+ }
+ }
+ }
+}
+
+
+int64_t PNS_DIFF_PAIR::CoupledLength( const SHAPE_LINE_CHAIN& aP, const SHAPE_LINE_CHAIN& aN ) const
+{
+ int64_t total = 0;
+
+ for( int i = 0; i < aP.SegmentCount(); i++ )
+ {
+ for( int j = 0; j < aN.SegmentCount(); j++ )
+ {
+ SEG sp = aP.CSegment( i );
+ SEG sn = aN.CSegment( j );
+
+ SEG p_clip, n_clip;
+
+ int64_t dist = std::abs( sp.Distance(sn) - m_width );
+
+ if( sp.ApproxParallel( sn ) && m_gapConstraint.Matches( dist ) &&
+ commonParallelProjection( sp, sn, p_clip, n_clip ) )
+ total += p_clip.Length();
+ }
+ }
+
+ return total;
+}
+
+
+double PNS_DIFF_PAIR::CoupledLength() const
+{
+ COUPLED_SEGMENTS_VEC pairs;
+
+ CoupledSegmentPairs( pairs );
+
+ double l = 0.0;
+ for( unsigned int i = 0; i < pairs.size(); i++ )
+ l += pairs[i].coupledP.Length();
+
+ return l;
+}
+
+
+double PNS_DIFF_PAIR::CoupledLengthFactor() const
+{
+ double t = TotalLength();
+
+ if( t == 0.0 )
+ return 0.0;
+
+ return CoupledLength() / t;
+}
+
+
+double PNS_DIFF_PAIR::TotalLength() const
+{
+ double lenP = m_p.Length();
+ double lenN = m_n.Length();
+
+ return (lenN + lenP ) / 2.0;
+}
+
+
+int PNS_DIFF_PAIR::CoupledLength ( const SEG& aP, const SEG& aN ) const
+{
+ SEG p_clip, n_clip;
+ int64_t dist = std::abs( aP.Distance( aN ) - m_width );
+
+ if( aP.ApproxParallel( aN ) && m_gapConstraint.Matches( dist ) &&
+ commonParallelProjection ( aP, aN, p_clip, n_clip ) )
+ return p_clip.Length();
+
+ return 0;
+}
diff --git a/pcbnew/router/pns_diff_pair.h b/pcbnew/router/pns_diff_pair.h
new file mode 100644
index 0000000..234ef89
--- /dev/null
+++ b/pcbnew/router/pns_diff_pair.h
@@ -0,0 +1,495 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __PNS_DIFF_PAIR_H
+#define __PNS_DIFF_PAIR_H
+
+#include <vector>
+
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+
+#include "pns_line.h"
+#include "pns_via.h"
+
+#include "ranged_num.h"
+
+class PNS_DIFF_PAIR;
+
+/**
+ * Class PNS_DP_GATEWAY
+ *
+ * Defines a "gateway" for routing a differential pair - e.g. a pair of points (anchors) with certain
+ * orientation, spacing and (optionally) predefined entry paths. The routing algorithm connects such
+ * gateways with parallel lines, thus creating a difrerential pair.
+ **/
+class PNS_DP_GATEWAY {
+public:
+ PNS_DP_GATEWAY( const VECTOR2I& aAnchorP,
+ const VECTOR2I& aAnchorN,
+ bool aIsDiagonal,
+ int aAllowedEntryAngles = DIRECTION_45::ANG_OBTUSE,
+ int aPriority = 0 )
+ : m_anchorP( aAnchorP ),
+ m_anchorN( aAnchorN ),
+ m_isDiagonal( aIsDiagonal ),
+ m_allowedEntryAngles( aAllowedEntryAngles ),
+ m_priority( aPriority )
+ {
+ m_hasEntryLines = false;
+ }
+
+ ~PNS_DP_GATEWAY()
+ {
+ }
+
+ /**
+ * Function IsDiagonal()
+ *
+ * @return true, if the gateway anchors lie on a diagonal line
+ */
+ bool IsDiagonal() const
+ {
+ return m_isDiagonal;
+ }
+
+ const VECTOR2I& AnchorP() const { return m_anchorP; }
+
+ const VECTOR2I& AnchorN() const { return m_anchorN; }
+
+ /**
+ * Function AllowedAngles()
+ *
+ * @return a mask of 45-degree entry directoins allowed for the
+ * gateway.
+ */
+ int AllowedAngles () const { return m_allowedEntryAngles; }
+
+ /**
+ * Function Priority()
+ *
+ * @return priority/score value for gateway matching
+ */
+ int Priority() const
+ {
+ return m_priority;
+ }
+
+ void SetPriority(int aPriority)
+ {
+ m_priority = aPriority;
+ }
+
+ void SetEntryLines( const SHAPE_LINE_CHAIN& aEntryP, const SHAPE_LINE_CHAIN& aEntryN )
+ {
+ m_entryP = aEntryP;
+ m_entryN = aEntryN;
+ m_hasEntryLines = true;
+ }
+
+ const SHAPE_LINE_CHAIN& EntryP() const { return m_entryP; }
+ const SHAPE_LINE_CHAIN& EntryN() const { return m_entryN; }
+ const PNS_DIFF_PAIR Entry() const ;
+
+ void Reverse();
+
+ bool HasEntryLines () const
+ {
+ return m_hasEntryLines;
+ }
+
+private:
+ SHAPE_LINE_CHAIN m_entryP, m_entryN;
+ bool m_hasEntryLines;
+ VECTOR2I m_anchorP, m_anchorN;
+ bool m_isDiagonal;
+ int m_allowedEntryAngles;
+ int m_priority;
+};
+
+/**
+ * Class PNS_DP_PRIMITIVE_PAIR
+ *
+ * Stores staring/ending primitives (pads, vias or segments) for a differential pair.
+ **/
+class PNS_DP_PRIMITIVE_PAIR
+{
+public:
+ PNS_DP_PRIMITIVE_PAIR():
+ m_primP( NULL ), m_primN( NULL ) {};
+
+ PNS_DP_PRIMITIVE_PAIR( const PNS_DP_PRIMITIVE_PAIR& aOther );
+ PNS_DP_PRIMITIVE_PAIR( PNS_ITEM* aPrimP, PNS_ITEM* aPrimN );
+ PNS_DP_PRIMITIVE_PAIR( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN );
+
+ ~PNS_DP_PRIMITIVE_PAIR();
+
+ void SetAnchors( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN );
+
+ const VECTOR2I& AnchorP() const { return m_anchorP; }
+ const VECTOR2I& AnchorN() const { return m_anchorN; }
+
+ PNS_DP_PRIMITIVE_PAIR& operator=( const PNS_DP_PRIMITIVE_PAIR& aOther );
+
+ PNS_ITEM* PrimP() const { return m_primP; }
+ PNS_ITEM* PrimN() const { return m_primN; }
+
+ bool Directional() const;
+
+ DIRECTION_45 DirP() const;
+ DIRECTION_45 DirN() const;
+
+private:
+ DIRECTION_45 anchorDirection( PNS_ITEM* aItem, const VECTOR2I& aP ) const;
+
+ PNS_ITEM* m_primP;
+ PNS_ITEM* m_primN;
+ VECTOR2I m_anchorP, m_anchorN;
+};
+
+/**
+ * Class PNS_GATEWAYS
+ *
+ * A set of gateways calculated for the cursor or starting/ending primitive pair.
+ **/
+
+class PNS_DP_GATEWAYS
+{
+
+ public:
+ PNS_DP_GATEWAYS ( int aGap ):
+ m_gap(aGap), m_viaGap( aGap )
+ {
+ // Do not leave unitialized members, and keep static analyser quiet:
+ m_viaDiameter = 0;
+ m_fitVias = true;
+ }
+
+ void SetGap ( int aGap )
+ {
+ m_gap = aGap;
+ m_viaGap = aGap;
+ }
+
+ void Clear()
+ {
+ m_gateways.clear();
+ }
+
+ void SetFitVias ( bool aEnable, int aDiameter = 0, int aViaGap = -1 )
+ {
+ m_fitVias = aEnable;
+ m_viaDiameter = aDiameter;
+ if(aViaGap < 0)
+ m_viaGap = m_gap;
+ else
+ m_viaGap = aViaGap;
+ }
+
+
+ void BuildForCursor ( const VECTOR2I& aCursorPos );
+ void BuildOrthoProjections ( PNS_DP_GATEWAYS &aEntries, const VECTOR2I& aCursorPos, int aOrthoScore );
+ void BuildGeneric ( const VECTOR2I& p0_p, const VECTOR2I& p0_n, bool aBuildEntries = false, bool aViaMode = false );
+ void BuildFromPrimitivePair( PNS_DP_PRIMITIVE_PAIR aPair, bool aPreferDiagonal );
+
+ bool FitGateways ( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& aTarget, bool aPrefDiagonal, PNS_DIFF_PAIR& aDp );
+
+ std::vector<PNS_DP_GATEWAY>& Gateways()
+ {
+ return m_gateways;
+ }
+
+ private:
+
+ struct DP_CANDIDATE
+ {
+ SHAPE_LINE_CHAIN p, n;
+ VECTOR2I gw_p, gw_n;
+ int score;
+ };
+
+ bool checkDiagonalAlignment ( const VECTOR2I& a, const VECTOR2I& b) const;
+ void buildDpContinuation ( PNS_DP_PRIMITIVE_PAIR aPair, bool aIsDiagonal );
+ void buildEntries ( const VECTOR2I& p0_p, const VECTOR2I& p0_n );
+
+ int m_gap;
+ int m_viaGap;
+ int m_viaDiameter;
+ bool m_fitVias;
+
+ std::vector<PNS_DP_GATEWAY> m_gateways;
+};
+
+
+/**
+ * Class PNS_DIFF_PAIR
+ *
+ * Basic class for a differential pair. Stores two PNS_LINEs (for positive and negative nets, respectively),
+ * the gap and coupling constraints.
+ **/
+class PNS_DIFF_PAIR : public PNS_ITEM {
+
+public:
+ struct COUPLED_SEGMENTS {
+ COUPLED_SEGMENTS ( const SEG& aCoupledP, const SEG& aParentP, int aIndexP,
+ const SEG& aCoupledN, const SEG& aParentN, int aIndexN ) :
+ coupledP ( aCoupledP ),
+ coupledN ( aCoupledN ),
+ parentP ( aParentP ),
+ parentN ( aParentN ),
+ indexP ( aIndexP ),
+ indexN ( aIndexN )
+ {}
+
+ SEG coupledP;
+ SEG coupledN;
+ SEG parentP;
+ SEG parentN;
+ int indexP;
+ int indexN;
+ };
+
+ typedef std::vector<COUPLED_SEGMENTS> COUPLED_SEGMENTS_VEC;
+
+ PNS_DIFF_PAIR ( ) : PNS_ITEM ( DIFF_PAIR ), m_hasVias (false)
+ {
+ // Initialize some members, to avoid uninitialized variables.
+ m_net_p = 0;
+ m_net_n = 0;;
+ m_width = 0;
+ m_gap = 0;
+ m_viaGap = 0;
+ m_maxUncoupledLength = 0;
+ m_chamferLimit = 0;
+ }
+
+ PNS_DIFF_PAIR ( int aGap ) :
+ PNS_ITEM ( DIFF_PAIR ),
+ m_hasVias (false)
+ {
+ m_gapConstraint = aGap;
+
+ // Initialize other members, to avoid uninitialized variables.
+ m_net_p = 0;
+ m_net_n = 0;;
+ m_width = 0;
+ m_gap = 0;
+ m_viaGap = 0;
+ m_maxUncoupledLength = 0;
+ m_chamferLimit = 0;
+ }
+
+ PNS_DIFF_PAIR ( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, int aGap = 0 ):
+ PNS_ITEM ( DIFF_PAIR ),
+ m_n (aN),
+ m_p (aP),
+ m_hasVias (false)
+ {
+ m_gapConstraint = aGap;
+
+ // Initialize other members, to avoid uninitialized variables.
+ m_net_p = 0;
+ m_net_n = 0;;
+ m_width = 0;
+ m_gap = 0;
+ m_viaGap = 0;
+ m_maxUncoupledLength = 0;
+ m_chamferLimit = 0;
+ }
+
+ PNS_DIFF_PAIR ( const PNS_LINE &aLineP, const PNS_LINE &aLineN, int aGap = 0 ):
+ PNS_ITEM ( DIFF_PAIR ),
+ m_line_p ( aLineP ),
+ m_line_n ( aLineN ),
+ m_hasVias (false)
+ {
+ m_gapConstraint = aGap;
+ m_net_p = aLineP.Net();
+ m_net_n = aLineN.Net();
+ m_p = aLineP.CLine();
+ m_n = aLineN.CLine();
+
+ // Do not leave unitialized members, and keep static analyser quiet:
+ m_width = 0;
+ m_gap = 0;
+ m_viaGap = 0;
+ m_maxUncoupledLength = 0;
+ m_chamferLimit = 0;
+ }
+
+ static inline bool ClassOf( const PNS_ITEM* aItem )
+ {
+ return aItem && DIFF_PAIR == aItem->Kind();
+ }
+
+ PNS_DIFF_PAIR * Clone() const { assert(false); return NULL; }
+
+ static PNS_DIFF_PAIR* AssembleDp ( PNS_LINE *aLine );
+
+ void SetShape ( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, bool aSwapLanes = false)
+ {
+ if (aSwapLanes)
+ {
+ m_p = aN;
+ m_n = aP;
+ } else {
+ m_p = aP;
+ m_n = aN;
+ }
+ }
+
+ void SetShape ( const PNS_DIFF_PAIR& aPair )
+ {
+ m_p = aPair.m_p;
+ m_n = aPair.m_n;
+ }
+
+ void SetNets ( int aP, int aN )
+ {
+ m_net_p = aP;
+ m_net_n = aN;
+ }
+
+ void SetWidth ( int aWidth )
+ {
+ m_width = aWidth;
+ }
+
+ int Width() const { return m_width; }
+
+ void SetGap ( int aGap)
+ {
+ m_gap = aGap;
+ m_gapConstraint = RANGED_NUM<int> ( m_gap, 10000, 10000 );
+ }
+
+ int Gap() const {
+ return m_gap;
+ }
+
+ void AppendVias ( const PNS_VIA &aViaP, const PNS_VIA& aViaN )
+ {
+ m_hasVias = true;
+ m_via_p = aViaP;
+ m_via_n = aViaN;
+ }
+
+ void RemoveVias ()
+ {
+ m_hasVias = false;
+ }
+
+ bool EndsWithVias() const
+ {
+ return m_hasVias;
+ }
+
+ int NetP() const
+ {
+ return m_net_p;
+ }
+
+ int NetN() const
+ {
+ return m_net_n;
+ }
+
+ PNS_LINE& PLine()
+ {
+ if ( !m_line_p.IsLinked ( ) )
+ updateLine(m_line_p, m_p, m_net_p, m_via_p );
+ return m_line_p;
+ }
+
+ PNS_LINE& NLine()
+ {
+ if ( !m_line_n.IsLinked ( ) )
+ updateLine(m_line_n, m_n, m_net_n, m_via_n );
+ return m_line_n;
+ }
+
+ PNS_DP_PRIMITIVE_PAIR EndingPrimitives();
+
+ double CoupledLength() const;
+ double TotalLength() const;
+ double CoupledLengthFactor () const;
+ double Skew () const;
+
+ void CoupledSegmentPairs ( COUPLED_SEGMENTS_VEC& aPairs ) const;
+
+ void Clear()
+ {
+ m_n.Clear();
+ m_p.Clear();
+ }
+
+ void Append (const PNS_DIFF_PAIR& aOther )
+ {
+ m_n.Append ( aOther.m_n );
+ m_p.Append ( aOther.m_p );
+ }
+
+ bool Empty() const
+ {
+ return (m_n.SegmentCount() == 0) || (m_p.SegmentCount() == 0);
+ }
+ const SHAPE_LINE_CHAIN& CP() const { return m_p; }
+ const SHAPE_LINE_CHAIN& CN() const { return m_n; }
+
+ bool BuildInitial ( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY& aTarget, bool aPrefDiagonal );
+ bool CheckConnectionAngle ( const PNS_DIFF_PAIR &aOther, int allowedAngles ) const;
+ int CoupledLength ( const SEG& aP, const SEG& aN ) const;
+
+ int64_t CoupledLength ( const SHAPE_LINE_CHAIN& aP, const SHAPE_LINE_CHAIN& aN ) const;
+
+ const RANGED_NUM<int> GapConstraint() const {
+ return m_gapConstraint;
+ }
+
+private:
+
+ void updateLine( PNS_LINE &aLine, const SHAPE_LINE_CHAIN& aShape, int aNet, PNS_VIA& aVia )
+ {
+ aLine.SetShape( aShape );
+ aLine.SetWidth( m_width );
+ aLine.SetNet(aNet);
+ aLine.SetLayer (Layers().Start());
+
+ if(m_hasVias)
+ aLine.AppendVia ( aVia );
+ }
+
+ SHAPE_LINE_CHAIN m_n, m_p;
+ PNS_LINE m_line_p, m_line_n;
+ PNS_VIA m_via_p, m_via_n;
+
+ bool m_hasVias;
+ int m_net_p, m_net_n;
+ int m_width;
+ int m_gap;
+ int m_viaGap;
+ int m_maxUncoupledLength;
+ int m_chamferLimit;
+ RANGED_NUM<int> m_gapConstraint;
+};
+
+
+#endif
diff --git a/pcbnew/router/pns_diff_pair_placer.cpp b/pcbnew/router/pns_diff_pair_placer.cpp
new file mode 100644
index 0000000..c9fc2bf
--- /dev/null
+++ b/pcbnew/router/pns_diff_pair_placer.cpp
@@ -0,0 +1,859 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+#include <boost/optional.hpp>
+
+#include <colors.h>
+#include <class_board.h>
+#include <class_board_item.h>
+#include <class_netinfo.h>
+
+#include "trace.h"
+
+#include "pns_node.h"
+#include "pns_walkaround.h"
+#include "pns_shove.h"
+#include "pns_utils.h"
+#include "pns_router.h"
+#include "pns_diff_pair_placer.h"
+#include "pns_solid.h"
+#include "pns_topology.h"
+
+using boost::optional;
+
+PNS_DIFF_PAIR_PLACER::PNS_DIFF_PAIR_PLACER( PNS_ROUTER* aRouter ) :
+ PNS_PLACEMENT_ALGO( aRouter )
+{
+ m_state = RT_START;
+ m_chainedPlacement = false;
+ m_initialDiagonal = false;
+ m_startDiagonal = false;
+ m_fitOk = false;
+ m_netP = 0;
+ m_netN = 0;
+ m_iteration = 0;
+ m_world = NULL;
+ m_shove = NULL;
+ m_currentNode = NULL;
+ m_lastNode = NULL;
+ m_placingVia = false;
+ m_viaDiameter = 0;
+ m_viaDrill = 0;
+ m_currentWidth = 0;
+ m_currentNet = 0;
+ m_currentLayer = 0;
+ m_startsOnVia = false;
+ m_orthoMode = false;
+ m_snapOnTarget = false;
+ m_currentEndItem = NULL;
+ m_currentMode = RM_MarkObstacles;
+ m_idle = true;
+}
+
+PNS_DIFF_PAIR_PLACER::~PNS_DIFF_PAIR_PLACER()
+{
+ if( m_shove )
+ delete m_shove;
+}
+
+
+void PNS_DIFF_PAIR_PLACER::setWorld( PNS_NODE* aWorld )
+{
+ m_world = aWorld;
+}
+
+
+const PNS_VIA PNS_DIFF_PAIR_PLACER::makeVia( const VECTOR2I& aP, int aNet )
+{
+ const PNS_LAYERSET layers( m_sizes.GetLayerTop(), m_sizes.GetLayerBottom() );
+
+ PNS_VIA v( aP, layers, m_sizes.ViaDiameter(), m_sizes.ViaDrill(), -1, m_sizes.ViaType() );
+ v.SetNet( aNet );
+
+ return v;
+}
+
+
+void PNS_DIFF_PAIR_PLACER::SetOrthoMode ( bool aOrthoMode )
+{
+ m_orthoMode = aOrthoMode;
+
+ if( !m_idle )
+ Move( m_currentEnd, NULL );
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::ToggleVia( bool aEnabled )
+{
+ m_placingVia = aEnabled;
+
+ if( !m_idle )
+ Move( m_currentEnd, NULL );
+
+ return true;
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::rhMarkObstacles( const VECTOR2I& aP )
+{
+ if( !routeHead( aP ) )
+ return false;
+
+ bool collP = static_cast<bool>( m_currentNode->CheckColliding( &m_currentTrace.PLine() ) );
+ bool collN = static_cast<bool>( m_currentNode->CheckColliding( &m_currentTrace.NLine() ) );
+
+ m_fitOk = !( collP || collN ) ;
+
+ return m_fitOk;
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNewP )
+{
+ PNS_VIA virtHead = makeVia( aP, -1 );
+
+ if( m_placingVia )
+ virtHead.SetDiameter( viaGap() + 2 * virtHead.Diameter() );
+ else
+ {
+ virtHead.SetLayer( m_currentLayer );
+ virtHead.SetDiameter( m_sizes.DiffPairGap() + 2 * m_sizes.TrackWidth() );
+ }
+
+ VECTOR2I lead( 0, 0 );// = aP - m_currentStart ;
+ VECTOR2I force;
+ bool solidsOnly = true;
+
+ if( m_currentMode == RM_MarkObstacles )
+ {
+ aNewP = aP;
+ return true;
+ }
+ else if( m_currentMode == RM_Walkaround )
+ {
+ solidsOnly = false;
+ }
+
+ // fixme: I'm too lazy to do it well. Circular approximaton will do for the moment.
+ if( virtHead.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
+ {
+ aNewP = aP + force;
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::attemptWalk ( PNS_NODE* aNode, PNS_DIFF_PAIR* aCurrent, PNS_DIFF_PAIR& aWalk, bool aPFirst, bool aWindCw, bool aSolidsOnly )
+{
+ PNS_WALKAROUND walkaround( aNode, Router() );
+ PNS_WALKAROUND::WALKAROUND_STATUS wf1;
+
+ Router()->GetClearanceFunc()->OverrideClearance( true, aCurrent->NetP(), aCurrent->NetN(), aCurrent->Gap() );
+
+ walkaround.SetSolidsOnly( aSolidsOnly );
+ walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
+
+ PNS_SHOVE shove( aNode, Router() );
+ PNS_LINE walkP, walkN;
+
+ aWalk = *aCurrent;
+
+ int iter = 0;
+
+ PNS_DIFF_PAIR cur( *aCurrent );
+
+ bool currentIsP = aPFirst;
+
+ int mask = aSolidsOnly ? PNS_ITEM::SOLID : PNS_ITEM::ANY;
+
+ do
+ {
+ PNS_LINE preWalk = ( currentIsP ? cur.PLine() : cur.NLine() );
+ PNS_LINE preShove = ( currentIsP ? cur.NLine() : cur.PLine() );
+ PNS_LINE postWalk;
+
+ if( !aNode->CheckColliding ( &preWalk, mask ) )
+ {
+ currentIsP = !currentIsP;
+
+ if( !aNode->CheckColliding( &preShove, mask ) )
+ break;
+ else
+ continue;
+ }
+
+ wf1 = walkaround.Route( preWalk, postWalk, false );
+
+ if( wf1 != PNS_WALKAROUND::DONE )
+ return false;
+
+ PNS_LINE postShove( preShove );
+
+ shove.ForceClearance( true, cur.Gap() - 2 * PNS_HULL_MARGIN );
+
+ PNS_SHOVE::SHOVE_STATUS sh1;
+
+ sh1 = shove.ProcessSingleLine( postWalk, preShove, postShove );
+
+ if( sh1 != PNS_SHOVE::SH_OK )
+ return false;
+
+ postWalk.Line().Simplify();
+ postShove.Line().Simplify();
+
+ cur.SetShape( postWalk.CLine(), postShove.CLine(), !currentIsP );
+
+ currentIsP = !currentIsP;
+
+ if( !aNode->CheckColliding( &postShove, mask ) )
+ break;
+
+ iter++;
+ }
+ while( iter < 3 );
+
+ if( iter == 3 )
+ return false;
+
+ aWalk.SetShape( cur.CP(), cur.CN() );
+ Router()->GetClearanceFunc()->OverrideClearance( false );
+
+ return true;
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::tryWalkDp( PNS_NODE* aNode, PNS_DIFF_PAIR &aPair, bool aSolidsOnly )
+{
+ PNS_DIFF_PAIR best;
+ double bestScore = 100000000000000.0;
+
+ for( int attempt = 0; attempt <= 1; attempt++ )
+ {
+ PNS_DIFF_PAIR p;
+ PNS_NODE *tmp = m_currentNode->Branch();
+
+ bool pfirst = attempt % 2 ? true : false;
+ bool wind_cw = attempt / 2 ? true : false;
+
+ if( attemptWalk ( tmp, &aPair, p, pfirst, wind_cw, aSolidsOnly ) )
+ {
+ // double len = p.TotalLength();
+ double cl = p.CoupledLength();
+ double skew = p.Skew();
+
+ double score = cl + fabs(skew) * 3.0;
+
+ if( score < bestScore )
+ {
+ bestScore = score;
+ best = p;
+ }
+ }
+
+ delete tmp;
+ }
+
+ if( bestScore > 0.0 )
+ {
+ PNS_OPTIMIZER optimizer( m_currentNode );
+
+ aPair.SetShape( best );
+ optimizer.Optimize( &aPair );
+
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::rhWalkOnly( const VECTOR2I& aP )
+{
+ if( !routeHead ( aP ) )
+ return false;
+
+ m_fitOk = tryWalkDp( m_currentNode, m_currentTrace, false );
+
+ return m_fitOk;
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::route( const VECTOR2I& aP )
+{
+ switch( m_currentMode )
+ {
+ case RM_MarkObstacles:
+ return rhMarkObstacles( aP );
+ case RM_Walkaround:
+ return rhWalkOnly( aP );
+ case RM_Shove:
+ return rhShoveOnly( aP );
+ default:
+ break;
+ }
+
+ return false;
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::rhShoveOnly( const VECTOR2I& aP )
+{
+ m_currentNode = m_shove->CurrentNode();
+
+ bool ok = routeHead( aP );
+
+ m_fitOk = false;
+
+ if( !ok )
+ return false;
+
+ if( !tryWalkDp( m_currentNode, m_currentTrace, true ) )
+ return false;
+
+ PNS_LINE pLine( m_currentTrace.PLine() );
+ PNS_LINE nLine( m_currentTrace.NLine() );
+ PNS_ITEMSET head;
+
+ head.Add( &pLine );
+ head.Add( &nLine );
+
+ PNS_SHOVE::SHOVE_STATUS status = m_shove->ShoveMultiLines( head );
+
+ m_currentNode = m_shove->CurrentNode();
+
+ if( status == PNS_SHOVE::SH_OK )
+ {
+ m_currentNode = m_shove->CurrentNode();
+
+ if( !m_currentNode->CheckColliding( &m_currentTrace.PLine() ) &&
+ !m_currentNode->CheckColliding( &m_currentTrace.NLine() ) )
+ {
+ m_fitOk = true;
+ }
+ }
+
+ return m_fitOk;
+}
+
+
+const PNS_ITEMSET PNS_DIFF_PAIR_PLACER::Traces()
+{
+ PNS_ITEMSET t;
+
+ t.Add( const_cast<PNS_LINE*>( &m_currentTrace.PLine() ) );
+ t.Add( const_cast<PNS_LINE*>( &m_currentTrace.NLine() ) );
+
+ return t;
+}
+
+
+void PNS_DIFF_PAIR_PLACER::FlipPosture()
+{
+ m_startDiagonal = !m_startDiagonal;
+
+ if( !m_idle )
+ Move( m_currentEnd, NULL );
+}
+
+
+PNS_NODE* PNS_DIFF_PAIR_PLACER::CurrentNode( bool aLoopsRemoved ) const
+{
+ if( m_lastNode )
+ return m_lastNode;
+
+ return m_currentNode;
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::SetLayer( int aLayer )
+{
+ if( m_idle )
+ {
+ m_currentLayer = aLayer;
+ return true;
+ } else if( m_chainedPlacement )
+ return false;
+ else if( !m_prevPair )
+ return false;
+ else if( m_prevPair->PrimP() || ( m_prevPair->PrimP()->OfKind( PNS_ITEM::VIA ) &&
+ m_prevPair->PrimP()->Layers().Overlaps( aLayer ) ) )
+ {
+ m_currentLayer = aLayer;
+ m_start = *m_prevPair;
+ initPlacement( false );
+ Move( m_currentEnd, NULL );
+ return true;
+ }
+
+ return false;
+}
+
+
+int PNS_DIFF_PAIR_PLACER::matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName )
+{
+ int rv = 0;
+
+ if( aNetName.EndsWith( "+" ) )
+ {
+ aComplementNet = "-";
+ rv = 1;
+ }
+ else if( aNetName.EndsWith( "_P" ) )
+ {
+ aComplementNet = "_N";
+ rv = 1;
+ }
+ else if( aNetName.EndsWith( "-" ) )
+ {
+ aComplementNet = "+";
+ rv = -1;
+ }
+ else if( aNetName.EndsWith( "_N" ) )
+ {
+ aComplementNet = "_P";
+ rv = -1;
+ }
+
+ if( rv != 0 )
+ {
+ aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
+ }
+
+ return rv;
+}
+
+
+OPT_VECTOR2I PNS_DIFF_PAIR_PLACER::getDanglingAnchor( PNS_NODE* aNode, PNS_ITEM* aItem )
+{
+ switch( aItem->Kind() )
+ {
+ case PNS_ITEM::VIA:
+ case PNS_ITEM::SOLID:
+ return aItem->Anchor( 0 );
+
+ case PNS_ITEM::SEGMENT:
+ {
+ PNS_SEGMENT* s =static_cast<PNS_SEGMENT*>( aItem );
+
+ PNS_JOINT* jA = aNode->FindJoint( s->Seg().A, s );
+ PNS_JOINT* jB = aNode->FindJoint( s->Seg().B, s );
+
+ if( jA->LinkCount() == 1 )
+ return s->Seg().A;
+ else if( jB->LinkCount() == 1 )
+ return s->Seg().B;
+ else
+ return OPT_VECTOR2I();
+ }
+
+ default:
+ return OPT_VECTOR2I();
+ break;
+ }
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::findDpPrimitivePair( const VECTOR2I& aP, PNS_ITEM* aItem, PNS_DP_PRIMITIVE_PAIR& aPair )
+{
+ if( !aItem || !aItem->Parent() || !aItem->Parent()->GetNet() )
+ return false;
+
+ wxString netNameP = aItem->Parent()->GetNet()->GetNetname();
+ wxString netNameN, netNameBase;
+
+ BOARD* brd = Router()->GetBoard();
+ PNS_ITEM *primRef = NULL, *primP = NULL, *primN = NULL;
+
+ int refNet;
+
+ wxString suffix;
+
+ int r = matchDpSuffix ( netNameP, suffix, netNameBase );
+
+ if( r == 0 )
+ return false;
+ else if( r == 1 )
+ {
+ primRef = primP = static_cast<PNS_SOLID*>( aItem );
+ netNameN = netNameBase + suffix;
+ }
+ else
+ {
+ primRef = primN = static_cast<PNS_SOLID*>( aItem );
+ netNameN = netNameP;
+ netNameP = netNameBase + suffix;
+ }
+
+ NETINFO_ITEM* netInfoP = brd->FindNet( netNameP );
+ NETINFO_ITEM* netInfoN = brd->FindNet( netNameN );
+
+ if( !netInfoP || !netInfoN )
+ return false;
+
+ int netP = netInfoP->GetNet();
+ int netN = netInfoN->GetNet();
+
+ if( primP )
+ refNet = netN;
+ else
+ refNet = netP;
+
+
+ std::set<PNS_ITEM*> items;
+
+ OPT_VECTOR2I refAnchor = getDanglingAnchor( m_currentNode, primRef );
+
+ if( !refAnchor )
+ return false;
+
+ m_currentNode->AllItemsInNet( refNet, items );
+ double bestDist = std::numeric_limits<double>::max();
+ bool found = false;
+
+ BOOST_FOREACH( PNS_ITEM* item, items )
+ {
+ if( item->Kind() == aItem->Kind() )
+ {
+ OPT_VECTOR2I anchor = getDanglingAnchor( m_currentNode, item );
+ if( !anchor )
+ continue;
+
+ double dist = ( *anchor - *refAnchor ).EuclideanNorm();
+
+ bool shapeMatches = true;
+
+ if( item->OfKind( PNS_ITEM::SOLID ) && item->Layers() != aItem->Layers() )
+ {
+ shapeMatches = false;
+ }
+
+ if( dist < bestDist && shapeMatches )
+ {
+ found = true;
+ bestDist = dist;
+
+ if( refNet == netP )
+ {
+ aPair = PNS_DP_PRIMITIVE_PAIR ( item, primRef );
+ aPair.SetAnchors( *anchor, *refAnchor );
+ }
+ else
+ {
+ aPair = PNS_DP_PRIMITIVE_PAIR( primRef, item );
+ aPair.SetAnchors( *refAnchor, *anchor );
+ }
+ }
+ }
+ }
+
+ return found;
+}
+
+
+int PNS_DIFF_PAIR_PLACER::viaGap() const
+{
+ return m_sizes.DiffPairViaGap();
+}
+
+
+int PNS_DIFF_PAIR_PLACER::gap() const
+{
+ return m_sizes.DiffPairGap() + m_sizes.DiffPairWidth();
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
+{
+ VECTOR2I p( aP );
+
+ bool split;
+
+ if( Router()->SnappingEnabled() )
+ p = Router()->SnapToItem( aStartItem, aP, split );
+
+ if( !aStartItem )
+ {
+ Router()->SetFailureReason( _( "Can't start a differential pair "
+ " in the middle of nowhere." ) );
+ return false;
+ }
+
+ m_currentNode = Router()->GetWorld();
+
+ if( !findDpPrimitivePair( aP, aStartItem, m_start ) )
+ {
+ Router()->SetFailureReason( _( "Unable to find complementary differential pair "
+ "net. Make sure the names of the nets belonging "
+ "to a differential pair end with either _N/_P or +/-." ) );
+ return false;
+ }
+
+ m_netP = m_start.PrimP()->Net();
+ m_netN = m_start.PrimN()->Net();
+
+ // Check if the current track/via gap & track width settings are violated
+ BOARD* brd = Router()->GetBoard();
+ NETCLASSPTR netclassP = brd->FindNet( m_netP )->GetNetClass();
+ NETCLASSPTR netclassN = brd->FindNet( m_netN )->GetNetClass();
+ int clearance = std::min( m_sizes.DiffPairGap(), m_sizes.DiffPairViaGap() );
+
+ if( clearance < netclassP->GetClearance() || clearance < netclassN->GetClearance() )
+ {
+ Router()->SetFailureReason( _( "Current track/via gap setting violates "
+ "design rules for this net." ) );
+ return false;
+ }
+
+ if( m_sizes.DiffPairWidth() < brd->GetDesignSettings().m_TrackMinWidth )
+ {
+ Router()->SetFailureReason( _( "Current track width setting violates design rules." ) );
+ return false;
+ }
+
+ m_currentStart = p;
+ m_currentEnd = p;
+ m_placingVia = false;
+ m_chainedPlacement = false;
+
+ initPlacement( false );
+
+ return true;
+}
+
+
+void PNS_DIFF_PAIR_PLACER::initPlacement( bool aSplitSeg )
+{
+ m_idle = false;
+ m_orthoMode = false;
+ m_currentEndItem = NULL;
+ m_startDiagonal = m_initialDiagonal;
+
+ PNS_NODE* world = Router()->GetWorld();
+
+ world->KillChildren();
+ PNS_NODE* rootNode = world->Branch();
+
+ setWorld( rootNode );
+
+ m_lastNode = NULL;
+ m_currentNode = rootNode;
+ m_currentMode = Settings().Mode();
+
+ if( m_shove )
+ delete m_shove;
+
+ m_shove = NULL;
+
+ if( m_currentMode == RM_Shove || m_currentMode == RM_Smart )
+ {
+ m_shove = new PNS_SHOVE( m_currentNode, Router() );
+ }
+}
+
+bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP )
+{
+ m_fitOk = false;
+
+ PNS_DP_GATEWAYS gwsEntry( gap() );
+ PNS_DP_GATEWAYS gwsTarget( gap() );
+
+ if( !m_prevPair )
+ m_prevPair = m_start;
+
+ gwsEntry.BuildFromPrimitivePair( *m_prevPair, m_startDiagonal );
+
+ PNS_DP_PRIMITIVE_PAIR target;
+
+ if( findDpPrimitivePair ( aP, m_currentEndItem, target ) )
+ {
+ gwsTarget.BuildFromPrimitivePair( target, m_startDiagonal );
+ m_snapOnTarget = true;
+ } else {
+ VECTOR2I fp;
+
+ if( !propagateDpHeadForces( aP, fp ) )
+ return false;
+
+ gwsTarget.SetFitVias( m_placingVia, m_sizes.ViaDiameter(), viaGap() );
+ gwsTarget.BuildForCursor( fp );
+ gwsTarget.BuildOrthoProjections( gwsEntry, fp, m_orthoMode ? 200 : -200 );
+ m_snapOnTarget = false;
+ }
+
+ m_currentTrace = PNS_DIFF_PAIR();
+ m_currentTrace.SetGap( gap() );
+ m_currentTrace.SetLayer( m_currentLayer );
+
+ if ( gwsEntry.FitGateways( gwsEntry, gwsTarget, m_startDiagonal, m_currentTrace ) )
+ {
+ m_currentTrace.SetNets( m_netP, m_netN );
+ m_currentTrace.SetWidth( m_sizes.DiffPairWidth() );
+ m_currentTrace.SetGap( m_sizes.DiffPairGap() );
+
+ if( m_placingVia )
+ {
+ m_currentTrace.AppendVias ( makeVia ( m_currentTrace.CP().CPoint(-1), m_netP ),
+ makeVia ( m_currentTrace.CN().CPoint(-1), m_netN ) );
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::Move( const VECTOR2I& aP , PNS_ITEM* aEndItem )
+{
+ m_currentEndItem = aEndItem;
+ m_fitOk = false;
+
+ delete m_lastNode;
+ m_lastNode = NULL;
+
+ if( !route( aP ) )
+ return false;
+
+ PNS_NODE* latestNode = m_currentNode;
+ m_lastNode = latestNode->Branch();
+
+ assert( m_lastNode != NULL );
+ m_currentEnd = aP;
+
+ updateLeadingRatLine();
+
+ return true;
+}
+
+
+void PNS_DIFF_PAIR_PLACER::UpdateSizes( const PNS_SIZES_SETTINGS& aSizes )
+{
+ m_sizes = aSizes;
+
+ if( !m_idle )
+ {
+ initPlacement();
+ Move( m_currentEnd, NULL );
+ }
+}
+
+
+bool PNS_DIFF_PAIR_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
+{
+ if( !m_fitOk )
+ return false;
+
+ if( m_currentTrace.CP().SegmentCount() < 1 ||
+ m_currentTrace.CN().SegmentCount() < 1 )
+ return false;
+
+ if( m_currentTrace.CP().SegmentCount() > 1 )
+ m_initialDiagonal = !DIRECTION_45( m_currentTrace.CP().CSegment( -2 ) ).IsDiagonal();
+
+ PNS_TOPOLOGY topo( m_lastNode );
+
+ if( !m_snapOnTarget && !m_currentTrace.EndsWithVias() )
+ {
+ SHAPE_LINE_CHAIN newP( m_currentTrace.CP() );
+ SHAPE_LINE_CHAIN newN( m_currentTrace.CN() );
+
+ if( newP.SegmentCount() > 1 && newN.SegmentCount() > 1 )
+ {
+ newP.Remove( -1, -1 );
+ newN.Remove( -1, -1 );
+ }
+
+ m_currentTrace.SetShape( newP, newN );
+ }
+
+ if( m_currentTrace.EndsWithVias() )
+ {
+ m_lastNode->Add( m_currentTrace.PLine().Via().Clone() );
+ m_lastNode->Add( m_currentTrace.NLine().Via().Clone() );
+ m_chainedPlacement = false;
+ }
+ else
+ {
+ m_chainedPlacement = !m_snapOnTarget;
+ }
+
+ PNS_LINE lineP( m_currentTrace.PLine() );
+ PNS_LINE lineN( m_currentTrace.NLine() );
+
+ m_lastNode->Add( &lineP );
+ m_lastNode->Add( &lineN );
+
+ topo.SimplifyLine( &lineP );
+ topo.SimplifyLine( &lineN );
+
+ m_prevPair = m_currentTrace.EndingPrimitives();
+
+ Router()->CommitRouting( m_lastNode );
+
+ m_lastNode = NULL;
+ m_placingVia = false;
+
+ if( m_snapOnTarget )
+ {
+ m_idle = true;
+ return true;
+ }
+ else
+ {
+ initPlacement();
+ return false;
+ }
+}
+
+
+void PNS_DIFF_PAIR_PLACER::GetModifiedNets( std::vector<int> &aNets ) const
+{
+ aNets.push_back( m_netP );
+ aNets.push_back( m_netN );
+}
+
+
+void PNS_DIFF_PAIR_PLACER::updateLeadingRatLine()
+{
+ SHAPE_LINE_CHAIN ratLineN, ratLineP;
+ PNS_TOPOLOGY topo( m_lastNode );
+
+ if( topo.LeadingRatLine( &m_currentTrace.PLine(), ratLineP ) )
+ {
+ Router()->DisplayDebugLine( ratLineP, 1, 10000 );
+ }
+
+ if( topo.LeadingRatLine ( &m_currentTrace.NLine(), ratLineN ) )
+ {
+ Router()->DisplayDebugLine( ratLineN, 3, 10000 );
+ }
+}
+
+
+const std::vector<int> PNS_DIFF_PAIR_PLACER::CurrentNets() const
+{
+ std::vector<int> rv;
+ rv.push_back( m_netP );
+ rv.push_back( m_netN );
+ return rv;
+}
diff --git a/pcbnew/router/pns_diff_pair_placer.h b/pcbnew/router/pns_diff_pair_placer.h
new file mode 100644
index 0000000..9bbed4c
--- /dev/null
+++ b/pcbnew/router/pns_diff_pair_placer.h
@@ -0,0 +1,299 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_DIFF_PLACER_H
+#define __PNS_DIFF_PLACER_H
+
+#include <math/vector2d.h>
+
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+
+#include "pns_sizes_settings.h"
+#include "pns_node.h"
+#include "pns_via.h"
+#include "pns_line.h"
+#include "pns_algo_base.h"
+#include "pns_diff_pair.h"
+
+#include "pns_placement_algo.h"
+
+class PNS_ROUTER;
+class PNS_SHOVE;
+class PNS_OPTIMIZER;
+class PNS_ROUTER_BASE;
+class PNS_VIA;
+class PNS_SIZES_SETTINGS;
+
+
+/**
+ * Class PNS_LINE_PLACER
+ *
+ * Single track placement algorithm. Interactively routes a track.
+ * Applies shove and walkaround algorithms when needed.
+ */
+
+class PNS_DIFF_PAIR_PLACER : public PNS_PLACEMENT_ALGO
+{
+public:
+ PNS_DIFF_PAIR_PLACER( PNS_ROUTER* aRouter );
+ ~PNS_DIFF_PAIR_PLACER();
+
+ /**
+ * Function Start()
+ *
+ * Starts routing a single track at point aP, taking item aStartItem as anchor
+ * (unless NULL).
+ */
+ bool Start( const VECTOR2I& aP, PNS_ITEM* aStartItem );
+
+ /**
+ * Function Move()
+ *
+ * Moves the end of the currently routed trace to the point aP, taking
+ * aEndItem as anchor (if not NULL).
+ * (unless NULL).
+ */
+ bool Move( const VECTOR2I& aP, PNS_ITEM* aEndItem );
+
+ /**
+ * Function FixRoute()
+ *
+ * Commits the currently routed track to the parent node, taking
+ * aP as the final end point and aEndItem as the final anchor (if provided).
+ * @return true, if route has been commited. May return false if the routing
+ * result is violating design rules - in such case, the track is only committed
+ * if Settings.CanViolateDRC() is on.
+ */
+ bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem );
+
+ /**
+ * Function ToggleVia()
+ *
+ * Enables/disables a via at the end of currently routed trace.
+ */
+ bool ToggleVia( bool aEnabled );
+
+ /**
+ * Function SetLayer()
+ *
+ * Sets the current routing layer.
+ */
+ bool SetLayer( int aLayer );
+
+ /**
+ * Function Traces()
+ *
+ * Returns the complete routed line, as a single-member PNS_ITEMSET.
+ */
+ const PNS_ITEMSET Traces();
+
+ /**
+ * Function CurrentEnd()
+ *
+ * Returns the current end of the line being placed. It may not be equal
+ * to the cursor position due to collisions.
+ */
+ const VECTOR2I& CurrentEnd() const
+ {
+ return m_currentEnd;
+ }
+
+ /**
+ * Function CurrentNets()
+ *
+ * Returns the net code of currently routed track.
+ */
+ const std::vector<int> CurrentNets() const;
+
+ /**
+ * Function CurrentLayer()
+ *
+ * Returns the layer of currently routed track.
+ */
+ int CurrentLayer() const
+ {
+ return m_currentLayer;
+ }
+
+ /**
+ * Function CurrentNode()
+ *
+ * Returns the most recent world state.
+ */
+ PNS_NODE* CurrentNode( bool aLoopsRemoved = false ) const;
+
+ /**
+ * Function FlipPosture()
+ *
+ * Toggles the current posture (straight/diagonal) of the trace head.
+ */
+ void FlipPosture();
+
+ /**
+ * Function UpdateSizes()
+ *
+ * Performs on-the-fly update of the width, via diameter & drill size from
+ * a settings class. Used to dynamically change these parameters as
+ * the track is routed.
+ */
+ void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes );
+
+ bool IsPlacingVia() const { return m_placingVia; }
+
+ void SetOrthoMode( bool aOrthoMode );
+
+ void GetModifiedNets( std::vector<int>& aNets ) const;
+
+private:
+ int viaGap() const;
+ int gap() const;
+
+ /**
+ * Function route()
+ *
+ * Re-routes the current track to point aP. Returns true, when routing has
+ * completed successfully (i.e. the trace end has reached point aP), and false
+ * if the trace was stuck somewhere on the way. May call routeStep()
+ * repetitively due to mouse smoothing.
+ * @param aP ending point of current route.
+ * @return true, if the routing is complete.
+ */
+ bool route( const VECTOR2I& aP );
+
+ /**
+ * Function updateLeadingRatLine()
+ *
+ * Draws the "leading" ratsnest line, which connects the end of currently
+ * routed track and the nearest yet unrouted item. If the routing for
+ * current net is complete, draws nothing.
+ */
+ void updateLeadingRatLine();
+
+ /**
+ * Function setWorld()
+ *
+ * Sets the board to route.
+ */
+ void setWorld( PNS_NODE* aWorld );
+
+ /**
+ * Function startPlacement()
+ *
+ * Initializes placement of a new line with given parameters.
+ */
+ void initPlacement( bool aSplitSeg = false );
+
+ /**
+ * Function setInitialDirection()
+ *
+ * Sets preferred direction of the very first track segment to be laid.
+ * Used by posture switching mechanism.
+ */
+ void setInitialDirection( const DIRECTION_45& aDirection );
+
+
+ bool routeHead( const VECTOR2I& aP );
+ bool tryWalkDp( PNS_NODE* aNode, PNS_DIFF_PAIR& aPair, bool aSolidsOnly );
+
+ ///> route step, walkaround mode
+ bool rhWalkOnly( const VECTOR2I& aP );
+
+ ///> route step, shove mode
+ bool rhShoveOnly ( const VECTOR2I& aP );
+
+ ///> route step, mark obstacles mode
+ bool rhMarkObstacles( const VECTOR2I& aP );
+
+ const PNS_VIA makeVia ( const VECTOR2I& aP, int aNet );
+
+ bool findDpPrimitivePair( const VECTOR2I& aP, PNS_ITEM* aItem, PNS_DP_PRIMITIVE_PAIR& aPair );
+ OPT_VECTOR2I getDanglingAnchor( PNS_NODE* aNode, PNS_ITEM* aItem );
+ int matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName );
+ bool attemptWalk( PNS_NODE* aNode, PNS_DIFF_PAIR* aCurrent, PNS_DIFF_PAIR& aWalk, bool aPFirst, bool aWindCw, bool aSolidsOnly );
+ bool propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNewP );
+
+ enum State {
+ RT_START = 0,
+ RT_ROUTE = 1,
+ RT_FINISH = 2
+ };
+
+ State m_state;
+
+ bool m_chainedPlacement;
+ bool m_initialDiagonal;
+ bool m_startDiagonal;
+ bool m_fitOk;
+
+ int m_netP, m_netN;
+
+ PNS_DP_PRIMITIVE_PAIR m_start;
+ boost::optional<PNS_DP_PRIMITIVE_PAIR> m_prevPair;
+
+ ///> current algorithm iteration
+ int m_iteration;
+
+ ///> pointer to world to search colliding items
+ PNS_NODE* m_world;
+
+ ///> current routing start point (end of tail, beginning of head)
+ VECTOR2I m_p_start;
+
+ ///> The shove engine
+ PNS_SHOVE* m_shove;
+
+ ///> Current world state
+ PNS_NODE* m_currentNode;
+
+ ///> Postprocessed world state (including marked collisions & removed loops)
+ PNS_NODE* m_lastNode;
+
+ PNS_SIZES_SETTINGS m_sizes;
+
+ ///> Are we placing a via?
+ bool m_placingVia;
+
+ ///> current via diameter
+ int m_viaDiameter;
+
+ ///> current via drill
+ int m_viaDrill;
+
+ ///> current track width
+ int m_currentWidth;
+
+ int m_currentNet;
+ int m_currentLayer;
+
+ bool m_startsOnVia;
+ bool m_orthoMode;
+ bool m_snapOnTarget;
+
+ VECTOR2I m_currentEnd, m_currentStart;
+ PNS_DIFF_PAIR m_currentTrace;
+
+ PNS_ITEM* m_currentEndItem;
+ PNS_MODE m_currentMode;
+
+ bool m_idle;
+};
+
+#endif // __PNS_LINE_PLACER_H
diff --git a/pcbnew/router/pns_dp_meander_placer.cpp b/pcbnew/router/pns_dp_meander_placer.cpp
new file mode 100644
index 0000000..5179e19
--- /dev/null
+++ b/pcbnew/router/pns_dp_meander_placer.cpp
@@ -0,0 +1,406 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+#include <boost/optional.hpp>
+
+#include <base_units.h> // God forgive me doing this...
+#include <colors.h>
+
+#include "trace.h"
+
+#include "pns_node.h"
+#include "pns_itemset.h"
+#include "pns_topology.h"
+#include "pns_dp_meander_placer.h"
+#include "pns_diff_pair.h"
+#include "pns_router.h"
+#include "pns_utils.h"
+
+using boost::optional;
+
+PNS_DP_MEANDER_PLACER::PNS_DP_MEANDER_PLACER( PNS_ROUTER* aRouter ) :
+ PNS_MEANDER_PLACER_BASE( aRouter )
+{
+ m_world = NULL;
+ m_currentNode = NULL;
+
+ // Init temporary variables (do not leave uninitialized members)
+ m_initialSegment = NULL;
+ m_lastLength = 0;
+ m_lastStatus = TOO_SHORT;
+}
+
+
+PNS_DP_MEANDER_PLACER::~PNS_DP_MEANDER_PLACER()
+{
+}
+
+
+const PNS_LINE PNS_DP_MEANDER_PLACER::Trace() const
+{
+ return m_currentTraceP;
+}
+
+
+PNS_NODE* PNS_DP_MEANDER_PLACER::CurrentNode( bool aLoopsRemoved ) const
+{
+ if( !m_currentNode )
+ return m_world;
+
+ return m_currentNode;
+}
+
+
+bool PNS_DP_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
+{
+ VECTOR2I p;
+
+ if( !aStartItem || !aStartItem->OfKind( PNS_ITEM::SEGMENT ) )
+ {
+ Router()->SetFailureReason( _( "Please select a track whose length you want to tune." ) );
+ return false;
+ }
+
+ m_initialSegment = static_cast<PNS_SEGMENT*>( aStartItem );
+
+ p = m_initialSegment->Seg().NearestPoint( aP );
+
+ m_currentNode=NULL;
+ m_currentStart = p;
+
+ m_world = Router()->GetWorld()->Branch();
+
+ PNS_TOPOLOGY topo( m_world );
+
+ if( !topo.AssembleDiffPair( m_initialSegment, m_originPair ) )
+ {
+ Router()->SetFailureReason( _( "Unable to find complementary differential pair "
+ "net for length tuning. Make sure the names of the nets belonging "
+ "to a differential pair end with either _N/_P or +/-." ) );
+ return false;
+ }
+
+ if( m_originPair.Gap() < 0 )
+ m_originPair.SetGap( Router()->Sizes().DiffPairGap() );
+
+ if( !m_originPair.PLine().SegmentCount() ||
+ !m_originPair.NLine().SegmentCount() )
+ return false;
+
+ m_tunedPathP = topo.AssembleTrivialPath( m_originPair.PLine().GetLink( 0 ) );
+ m_tunedPathN = topo.AssembleTrivialPath( m_originPair.NLine().GetLink( 0 ) );
+
+ m_world->Remove( m_originPair.PLine() );
+ m_world->Remove( m_originPair.NLine() );
+
+ m_currentWidth = m_originPair.Width();
+
+ return true;
+}
+
+
+void PNS_DP_MEANDER_PLACER::release()
+{
+
+}
+
+
+int PNS_DP_MEANDER_PLACER::origPathLength() const
+{
+ int totalP = 0;
+ int totalN = 0;
+
+ BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathP.CItems() )
+ {
+ if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
+ totalP += l->CLine().Length();
+
+ }
+
+ BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathN.CItems() )
+ {
+ if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
+ totalN += l->CLine().Length();
+ }
+
+ return std::max( totalP, totalN );
+}
+
+
+const SEG PNS_DP_MEANDER_PLACER::baselineSegment( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& aCoupledSegs )
+{
+ const VECTOR2I a( ( aCoupledSegs.coupledP.A + aCoupledSegs.coupledN.A ) / 2 );
+ const VECTOR2I b( ( aCoupledSegs.coupledP.B + aCoupledSegs.coupledN.B ) / 2 );
+
+ return SEG( a, b );
+}
+
+
+static bool pairOrientation( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& aPair )
+{
+ VECTOR2I midp = ( aPair.coupledP.A + aPair.coupledN.A ) / 2;
+
+ //DrawDebugPoint (midp, 6);
+
+ return aPair.coupledP.Side( midp ) > 0;
+}
+
+
+bool PNS_DP_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
+{
+// return false;
+
+ PNS_DIFF_PAIR::COUPLED_SEGMENTS_VEC coupledSegments;
+
+ if( m_currentNode )
+ delete m_currentNode;
+
+ m_currentNode = m_world->Branch();
+
+ SHAPE_LINE_CHAIN preP, tunedP, postP;
+ SHAPE_LINE_CHAIN preN, tunedN, postN;
+
+ cutTunedLine( m_originPair.CP(), m_currentStart, aP, preP, tunedP, postP );
+ cutTunedLine( m_originPair.CN(), m_currentStart, aP, preN, tunedN, postN );
+
+ PNS_DIFF_PAIR tuned ( m_originPair );
+
+ tuned.SetShape( tunedP, tunedN );
+
+ tuned.CoupledSegmentPairs( coupledSegments );
+
+ if( coupledSegments.size() == 0 )
+ return false;
+
+ //Router()->DisplayDebugLine ( tuned.CP(), 5, 20000 );
+ //Router()->DisplayDebugLine ( tuned.CN(), 4, 20000 );
+
+ //Router()->DisplayDebugLine ( m_originPair.CP(), 5, 20000 );
+ //Router()->DisplayDebugLine ( m_originPair.CN(), 4, 20000 );
+
+ m_result = PNS_MEANDERED_LINE( this, true );
+ m_result.SetWidth( tuned.Width() );
+
+ int offset = ( tuned.Gap() + tuned.Width() ) / 2;
+
+ if( !pairOrientation( coupledSegments[0] ) )
+ offset *= -1;
+
+ m_result.SetBaselineOffset( offset );
+
+ BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathP.CItems() )
+ {
+ if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
+ Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
+ }
+
+ BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathN.CItems() )
+ {
+ if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
+ Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
+ }
+
+ int curIndexP = 0, curIndexN = 0;
+
+ BOOST_FOREACH( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& sp, coupledSegments )
+ {
+ SEG base = baselineSegment( sp );
+
+ DrawDebugSeg( base, 3 );
+
+ while( sp.indexP >= curIndexP )
+ {
+ m_result.AddCorner( tunedP.CPoint( curIndexP ), tunedN.CPoint( curIndexN ) );
+ curIndexP++;
+ }
+
+ while( sp.indexN >= curIndexN )
+ {
+ m_result.AddCorner( tunedP.CPoint( sp.indexP ), tunedN.CPoint( curIndexN ) );
+ curIndexN++;
+ }
+
+ m_result.MeanderSegment( base );
+ }
+
+ while( curIndexP < tunedP.PointCount() )
+ m_result.AddCorner( tunedP.CPoint( curIndexP++ ), tunedN.CPoint( curIndexN ) );
+
+ while( curIndexN < tunedN.PointCount() )
+ m_result.AddCorner( tunedP.CPoint( -1 ), tunedN.CPoint( curIndexN++ ) );
+
+ int dpLen = origPathLength();
+
+ m_lastStatus = TUNED;
+
+ if( dpLen - m_settings.m_targetLength > m_settings.m_lengthTolerance )
+ {
+ m_lastStatus = TOO_LONG;
+ m_lastLength = dpLen;
+ }
+ else
+ {
+ m_lastLength = dpLen - std::max( tunedP.Length(), tunedN.Length() );
+ tuneLineLength( m_result, m_settings.m_targetLength - dpLen );
+ }
+
+ if( m_lastStatus != TOO_LONG )
+ {
+ tunedP.Clear();
+ tunedN.Clear();
+
+ BOOST_FOREACH( PNS_MEANDER_SHAPE* m, m_result.Meanders() )
+ {
+ if( m->Type() != MT_EMPTY )
+ {
+ tunedP.Append ( m->CLine( 0 ) );
+ tunedN.Append ( m->CLine( 1 ) );
+ }
+ }
+
+ m_lastLength += std::max( tunedP.Length(), tunedN.Length() );
+
+ int comp = compareWithTolerance( m_lastLength - m_settings.m_targetLength, 0, m_settings.m_lengthTolerance );
+
+ if( comp > 0 )
+ m_lastStatus = TOO_LONG;
+ else if( comp < 0 )
+ m_lastStatus = TOO_SHORT;
+ else
+ m_lastStatus = TUNED;
+ }
+
+ m_finalShapeP.Clear();
+ m_finalShapeP.Append( preP );
+ m_finalShapeP.Append( tunedP );
+ m_finalShapeP.Append( postP );
+ m_finalShapeP.Simplify();
+
+ m_finalShapeN.Clear();
+ m_finalShapeN.Append( preN );
+ m_finalShapeN.Append( tunedN );
+ m_finalShapeN.Append( postN );
+ m_finalShapeN.Simplify();
+
+ return true;
+}
+
+
+bool PNS_DP_MEANDER_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
+{
+ PNS_LINE lP( m_originPair.PLine(), m_finalShapeP );
+ PNS_LINE lN( m_originPair.NLine(), m_finalShapeN );
+
+ m_currentNode->Add( &lP );
+ m_currentNode->Add( &lN );
+
+ Router()->CommitRouting( m_currentNode );
+
+ return true;
+}
+
+
+bool PNS_DP_MEANDER_PLACER::CheckFit( PNS_MEANDER_SHAPE* aShape )
+{
+ PNS_LINE l1( m_originPair.PLine(), aShape->CLine( 0 ) );
+ PNS_LINE l2( m_originPair.NLine(), aShape->CLine( 1 ) );
+
+ if( m_currentNode->CheckColliding( &l1 ) )
+ return false;
+
+ if( m_currentNode->CheckColliding( &l2 ) )
+ return false;
+
+ int w = aShape->Width();
+ int clearance = w + m_settings.m_spacing;
+
+ return m_result.CheckSelfIntersections( aShape, clearance );
+}
+
+
+const PNS_ITEMSET PNS_DP_MEANDER_PLACER::Traces()
+{
+ m_currentTraceP = PNS_LINE( m_originPair.PLine(), m_finalShapeP );
+ m_currentTraceN = PNS_LINE( m_originPair.NLine(), m_finalShapeN );
+
+ PNS_ITEMSET traces;
+
+ traces.Add( &m_currentTraceP );
+ traces.Add( &m_currentTraceN );
+
+ return traces;
+}
+
+
+const VECTOR2I& PNS_DP_MEANDER_PLACER::CurrentEnd() const
+{
+ return m_currentEnd;
+}
+
+
+int PNS_DP_MEANDER_PLACER::CurrentLayer() const
+{
+ return m_initialSegment->Layers().Start();
+}
+
+
+const wxString PNS_DP_MEANDER_PLACER::TuningInfo() const
+{
+ wxString status;
+
+ switch( m_lastStatus )
+ {
+ case TOO_LONG:
+ status = _( "Too long: " );
+ break;
+ case TOO_SHORT:
+ status = _("Too short: " );
+ break;
+ case TUNED:
+ status = _( "Tuned: " );
+ break;
+ default:
+ return _( "?" );
+ }
+
+ status += LengthDoubleToString( (double) m_lastLength, false );
+ status += "/";
+ status += LengthDoubleToString( (double) m_settings.m_targetLength, false );
+ status += " (gap: ";
+ status += LengthDoubleToString( (double) m_originPair.Gap(), false );
+ status += ")";
+
+ return status;
+}
+
+
+PNS_DP_MEANDER_PLACER::TUNING_STATUS PNS_DP_MEANDER_PLACER::TuningStatus() const
+{
+ return m_lastStatus;
+}
+
+const std::vector<int> PNS_DP_MEANDER_PLACER::CurrentNets() const
+{
+ std::vector<int> rv;
+ rv.push_back( m_originPair.NetP() );
+ rv.push_back( m_originPair.NetN() );
+ return rv;
+}
diff --git a/pcbnew/router/pns_dp_meander_placer.h b/pcbnew/router/pns_dp_meander_placer.h
new file mode 100644
index 0000000..eb89e10
--- /dev/null
+++ b/pcbnew/router/pns_dp_meander_placer.h
@@ -0,0 +1,146 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_DP_MEANDER_PLACER_H
+#define __PNS_DP_MEANDER_PLACER_H
+
+#include <math/vector2d.h>
+
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+
+#include "pns_node.h"
+#include "pns_via.h"
+#include "pns_line.h"
+#include "pns_placement_algo.h"
+#include "pns_meander.h"
+#include "pns_meander_placer_base.h"
+#include "pns_diff_pair.h"
+
+class PNS_ROUTER;
+class PNS_SHOVE;
+class PNS_OPTIMIZER;
+class PNS_ROUTER_BASE;
+
+/**
+ * Class PNS_DP_MEANDER_PLACER
+ *
+ * Differential Pair length-matching/meandering tool.
+ */
+
+class PNS_DP_MEANDER_PLACER : public PNS_MEANDER_PLACER_BASE
+{
+public:
+ PNS_DP_MEANDER_PLACER( PNS_ROUTER* aRouter );
+ ~PNS_DP_MEANDER_PLACER();
+
+ /**
+ * Function Start()
+ *
+ * Starts routing a single track at point aP, taking item aStartItem as anchor
+ * (unless NULL).
+ */
+ bool Start ( const VECTOR2I& aP, PNS_ITEM* aStartItem );
+
+ /**
+ * Function Move()
+ *
+ * Moves the end of the currently routed trace to the point aP, taking
+ * aEndItem as anchor (if not NULL).
+ * (unless NULL).
+ */
+ bool Move( const VECTOR2I& aP, PNS_ITEM* aEndItem );
+
+ /**
+ * Function FixRoute()
+ *
+ * Commits the currently routed track to the parent node, taking
+ * aP as the final end point and aEndItem as the final anchor (if provided).
+ * @return true, if route has been commited. May return false if the routing
+ * result is violating design rules - in such case, the track is only committed
+ * if Settings.CanViolateDRC() is on.
+ */
+ bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem );
+
+ const PNS_LINE Trace() const;
+
+ /**
+ * Function CurrentNode()
+ *
+ * Returns the most recent world state.
+ */
+ PNS_NODE* CurrentNode( bool aLoopsRemoved = false ) const;
+
+ const PNS_ITEMSET Traces();
+
+ const VECTOR2I& CurrentEnd() const;
+
+ /// @copydoc PNS_PLACEMENT_ALGO::CurrentNets()
+ const std::vector<int> CurrentNets() const;
+
+ int CurrentLayer() const;
+
+ int totalLength();
+
+ const wxString TuningInfo() const;
+ TUNING_STATUS TuningStatus() const;
+
+ bool CheckFit( PNS_MEANDER_SHAPE* aShape );
+
+
+private:
+ friend class PNS_MEANDER_SHAPE;
+
+ void meanderSegment ( const SEG& aBase );
+
+// void addMeander ( PNS_MEANDER *aM );
+// void addCorner ( const VECTOR2I& aP );
+
+ const SEG baselineSegment( const PNS_DIFF_PAIR::COUPLED_SEGMENTS& aCoupledSegs );
+
+ void setWorld( PNS_NODE* aWorld );
+ void release();
+
+ int origPathLength() const;
+
+ ///> pointer to world to search colliding items
+ PNS_NODE* m_world;
+
+ ///> current routing start point (end of tail, beginning of head)
+ VECTOR2I m_currentStart;
+
+ ///> Current world state
+ PNS_NODE* m_currentNode;
+
+ PNS_DIFF_PAIR m_originPair;
+ PNS_DIFF_PAIR::COUPLED_SEGMENTS_VEC m_coupledSegments;
+
+ PNS_LINE m_currentTraceN, m_currentTraceP;
+ PNS_ITEMSET m_tunedPath, m_tunedPathP, m_tunedPathN;
+
+ SHAPE_LINE_CHAIN m_finalShapeP, m_finalShapeN;
+ PNS_MEANDERED_LINE m_result;
+ PNS_SEGMENT* m_initialSegment;
+
+ int m_lastLength;
+ TUNING_STATUS m_lastStatus;
+};
+
+#endif // __PNS_DP_MEANDER_PLACER_H
diff --git a/pcbnew/router/pns_dragger.cpp b/pcbnew/router/pns_dragger.cpp
new file mode 100644
index 0000000..a30e7cd
--- /dev/null
+++ b/pcbnew/router/pns_dragger.cpp
@@ -0,0 +1,336 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+
+#include "pns_dragger.h"
+#include "pns_shove.h"
+#include "pns_router.h"
+
+PNS_DRAGGER::PNS_DRAGGER( PNS_ROUTER* aRouter ) :
+ PNS_ALGO_BASE( aRouter )
+{
+ m_world = NULL;
+ m_lastNode = NULL;
+ m_mode = SEGMENT;
+ m_draggedVia = NULL;
+ m_shove = NULL;
+ m_draggedSegmentIndex = 0;
+ m_dragStatus = false;
+ m_currentMode = RM_MarkObstacles;
+ m_initialVia = NULL;
+}
+
+
+PNS_DRAGGER::~PNS_DRAGGER()
+{
+ if( m_shove )
+ delete m_shove;
+}
+
+
+void PNS_DRAGGER::SetWorld( PNS_NODE* aWorld )
+{
+ m_world = aWorld;
+}
+
+
+bool PNS_DRAGGER::startDragSegment( const VECTOR2D& aP, PNS_SEGMENT* aSeg )
+{
+ int w2 = aSeg->Width() / 2;
+
+ m_draggedLine = m_world->AssembleLine( aSeg, &m_draggedSegmentIndex );
+ m_shove->SetInitialLine( m_draggedLine );
+ m_lastValidDraggedLine = m_draggedLine;
+ m_lastValidDraggedLine.ClearSegmentLinks();
+
+ if( ( aP - aSeg->Seg().A ).EuclideanNorm() <= w2 )
+ m_mode = CORNER;
+ else if( ( aP - aSeg->Seg().B ).EuclideanNorm() <= w2 )
+ {
+ m_draggedSegmentIndex++;
+ m_mode = CORNER;
+ } else
+ m_mode = SEGMENT;
+
+ return true;
+}
+
+
+bool PNS_DRAGGER::startDragVia( const VECTOR2D& aP, PNS_VIA* aVia )
+{
+ m_draggedVia = aVia;
+ m_initialVia = aVia;
+ m_mode = VIA;
+
+ VECTOR2I p0( aVia->Pos() );
+ PNS_JOINT* jt = m_world->FindJoint( p0, aVia->Layers().Start(), aVia->Net() );
+
+ if( !jt )
+ return false;
+
+ BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
+ {
+ if( item->OfKind( PNS_ITEM::SEGMENT ) )
+ {
+ int segIndex;
+ PNS_SEGMENT* seg = ( PNS_SEGMENT*) item;
+ PNS_LINE l = m_world->AssembleLine( seg, &segIndex );
+
+ if( segIndex != 0 )
+ l.Reverse();
+
+ m_origViaConnections.Add( l );
+ }
+ }
+
+ return true;
+}
+
+
+bool PNS_DRAGGER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
+{
+ m_shove = new PNS_SHOVE( m_world, Router() );
+ m_lastNode = NULL;
+ m_draggedItems.Clear();
+ m_currentMode = Settings().Mode();
+
+ TRACE( 2, "StartDragging: item %p [kind %d]", aStartItem % aStartItem->Kind() );
+
+ switch( aStartItem->Kind() )
+ {
+ case PNS_ITEM::SEGMENT:
+ return startDragSegment( aP, static_cast<PNS_SEGMENT*>( aStartItem ) );
+
+ case PNS_ITEM::VIA:
+ return startDragVia( aP, static_cast<PNS_VIA*>( aStartItem ) );
+
+ default:
+ return false;
+ }
+}
+
+
+bool PNS_DRAGGER::dragMarkObstacles( const VECTOR2I& aP )
+{
+ if( m_lastNode )
+ {
+ delete m_lastNode;
+ m_lastNode = NULL;
+ }
+
+ switch( m_mode )
+ {
+ case SEGMENT:
+ case CORNER:
+ {
+ int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
+ PNS_LINE dragged( m_draggedLine );
+
+ if( m_mode == SEGMENT )
+ dragged.DragSegment( aP, m_draggedSegmentIndex, thresh );
+ else
+ dragged.DragCorner( aP, m_draggedSegmentIndex, thresh );
+
+ m_lastNode = m_shove->CurrentNode()->Branch();
+
+ m_lastValidDraggedLine = dragged;
+ m_lastValidDraggedLine.ClearSegmentLinks();
+ m_lastValidDraggedLine.Unmark();
+
+ m_lastNode->Add( &m_lastValidDraggedLine );
+ m_draggedItems.Clear();
+ m_draggedItems.Add( m_lastValidDraggedLine );
+
+ break;
+ }
+
+ case VIA: // fixme...
+ {
+ m_lastNode = m_shove->CurrentNode()->Branch();
+ dumbDragVia( m_initialVia, m_lastNode, aP );
+
+ break;
+ }
+ }
+
+ if( Settings().CanViolateDRC() )
+ m_dragStatus = true;
+ else
+ m_dragStatus = !m_world->CheckColliding( m_draggedItems );
+
+ return true;
+}
+
+
+void PNS_DRAGGER::dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& aP )
+{
+ m_draggedItems.Clear();
+
+ // fixme: this is awful.
+ m_draggedVia = aVia->Clone();
+ m_draggedVia->SetPos( aP );
+
+ m_draggedItems.Add( m_draggedVia );
+
+ m_lastNode->Remove( aVia );
+ m_lastNode->Add( m_draggedVia );
+
+ BOOST_FOREACH( PNS_ITEM* item, m_origViaConnections.Items() )
+ {
+ if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
+ {
+ PNS_LINE origLine( *l );
+ PNS_LINE draggedLine( *l );
+
+ draggedLine.DragCorner( aP, origLine.CLine().Find( aVia->Pos() ) );
+ draggedLine.ClearSegmentLinks();
+
+ m_draggedItems.Add( draggedLine );
+
+ m_lastNode->Remove( &origLine );
+ m_lastNode->Add( &draggedLine );
+ }
+ }
+}
+
+
+bool PNS_DRAGGER::dragShove( const VECTOR2I& aP )
+{
+ bool ok = false;
+
+ if( m_lastNode )
+ {
+ delete m_lastNode;
+ m_lastNode = NULL;
+ }
+
+ switch( m_mode )
+ {
+ case SEGMENT:
+ case CORNER:
+ {
+ int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
+ PNS_LINE dragged( m_draggedLine );
+
+ if( m_mode == SEGMENT )
+ dragged.DragSegment( aP, m_draggedSegmentIndex, thresh );
+ else
+ dragged.DragCorner( aP, m_draggedSegmentIndex, thresh );
+
+ PNS_SHOVE::SHOVE_STATUS st = m_shove->ShoveLines( dragged );
+
+ if( st == PNS_SHOVE::SH_OK )
+ ok = true;
+ else if( st == PNS_SHOVE::SH_HEAD_MODIFIED )
+ {
+ dragged = m_shove->NewHead();
+ ok = true;
+ }
+
+ m_lastNode = m_shove->CurrentNode()->Branch();
+
+ if( ok )
+ m_lastValidDraggedLine = dragged;
+
+ m_lastValidDraggedLine.ClearSegmentLinks();
+ m_lastValidDraggedLine.Unmark();
+ m_lastNode->Add( &m_lastValidDraggedLine );
+ m_draggedItems.Clear();
+ m_draggedItems.Add( m_lastValidDraggedLine );
+
+ break;
+ }
+
+ case VIA:
+ {
+ PNS_VIA* newVia;
+ PNS_SHOVE::SHOVE_STATUS st = m_shove->ShoveDraggingVia( m_draggedVia, aP, &newVia );
+
+ if( st == PNS_SHOVE::SH_OK || st == PNS_SHOVE::SH_HEAD_MODIFIED )
+ ok = true;
+
+ m_lastNode = m_shove->CurrentNode()->Branch();
+
+ if( ok )
+ {
+ m_draggedVia = newVia;
+ m_draggedItems.Clear();
+ }
+
+ break;
+ }
+ }
+
+ m_dragStatus = ok;
+
+ return ok;
+}
+
+
+bool PNS_DRAGGER::FixRoute()
+{
+ if( m_dragStatus )
+ {
+ Router()->CommitRouting( CurrentNode() );
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PNS_DRAGGER::Drag( const VECTOR2I& aP )
+{
+ switch( m_currentMode )
+ {
+ case RM_MarkObstacles:
+ return dragMarkObstacles( aP );
+
+ case RM_Shove:
+ case RM_Walkaround:
+ case RM_Smart:
+ return dragShove( aP );
+
+ default:
+ return false;
+ }
+}
+
+
+PNS_NODE* PNS_DRAGGER::CurrentNode() const
+{
+ return m_lastNode;
+}
+
+
+const PNS_ITEMSET PNS_DRAGGER::Traces()
+{
+ return m_draggedItems;
+}
+
+
+PNS_LOGGER* PNS_DRAGGER::Logger()
+{
+ if( m_shove )
+ return m_shove->Logger();
+
+ return NULL;
+}
diff --git a/pcbnew/router/pns_dragger.h b/pcbnew/router/pns_dragger.h
new file mode 100644
index 0000000..ed6a59b
--- /dev/null
+++ b/pcbnew/router/pns_dragger.h
@@ -0,0 +1,126 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_DRAGGER_H
+#define __PNS_DRAGGER_H
+
+#include <math/vector2d.h>
+
+#include "pns_node.h"
+#include "pns_via.h"
+#include "pns_line.h"
+#include "pns_algo_base.h"
+#include "pns_itemset.h"
+
+class PNS_ROUTER;
+class PNS_SHOVE;
+class PNS_OPTIMIZER;
+class PNS_ROUTER_BASE;
+
+/**
+ * Class PNS_DRAGGER
+ *
+ * Via, segment and corner dragging algorithm.
+ */
+class PNS_DRAGGER : public PNS_ALGO_BASE
+{
+public:
+ PNS_DRAGGER( PNS_ROUTER* aRouter );
+ ~PNS_DRAGGER();
+
+ /**
+ * Function SetWorld()
+ *
+ * Sets the board to work on.
+ */
+ void SetWorld( PNS_NODE* aWorld );
+
+ /**
+ * Function Start()
+ *
+ * Starts routing a single track at point aP, taking item aStartItem as anchor
+ * (unless NULL). Returns true if a dragging operation has started.
+ */
+ bool Start( const VECTOR2I& aP, PNS_ITEM* aStartItem );
+
+ /**
+ * Function Drag()
+ *
+ * Drags the current segment/corner/via to the point aP.
+ * @return true, if dragging finished with success.
+ */
+ bool Drag( const VECTOR2I& aP );
+
+ /**
+ * Function FixRoute()
+ *
+ * Checks if the result of current dragging operation is correct
+ * and eventually commits it to the world.
+ * @return true, if dragging finished with success.
+ */
+ bool FixRoute();
+
+ /**
+ * Function CurrentNode()
+ *
+ * Returns the most recent world state, including all
+ * items changed due to dragging operation.
+ */
+ PNS_NODE* CurrentNode() const;
+
+ /**
+ * Function Traces()
+ *
+ * Returns the set of dragged items.
+ */
+ const PNS_ITEMSET Traces();
+
+ /// @copydoc PNS_ALGO_BASE::Logger()
+ virtual PNS_LOGGER* Logger();
+
+private:
+ enum DragMode {
+ CORNER = 0,
+ SEGMENT,
+ VIA
+ };
+
+ bool dragMarkObstacles( const VECTOR2I& aP );
+ bool dragShove(const VECTOR2I& aP );
+ bool startDragSegment( const VECTOR2D& aP, PNS_SEGMENT* aSeg );
+ bool startDragVia( const VECTOR2D& aP, PNS_VIA* aVia );
+ void dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& aP );
+
+ PNS_NODE* m_world;
+ PNS_NODE* m_lastNode;
+ DragMode m_mode;
+ PNS_LINE m_draggedLine;
+ PNS_VIA* m_draggedVia;
+ PNS_LINE m_lastValidDraggedLine;
+ PNS_SHOVE* m_shove;
+ int m_draggedSegmentIndex;
+ bool m_dragStatus;
+ PNS_MODE m_currentMode;
+ PNS_ITEMSET m_origViaConnections;
+ PNS_VIA* m_initialVia;
+ PNS_ITEMSET m_draggedItems;
+};
+
+#endif
diff --git a/pcbnew/router/pns_index.h b/pcbnew/router/pns_index.h
new file mode 100644
index 0000000..6c895dc
--- /dev/null
+++ b/pcbnew/router/pns_index.h
@@ -0,0 +1,315 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_INDEX_H
+#define __PNS_INDEX_H
+
+#include <layers_id_colors_and_visibility.h>
+#include <map>
+
+#include <boost/foreach.hpp>
+#include <boost/range/adaptor/map.hpp>
+
+#include <list>
+#include <geometry/shape_index.h>
+
+#include "pns_item.h"
+
+/**
+ * Class PNS_INDEX
+ *
+ * Custom spatial index, holding our board items and allowing for very fast searches. Items
+ * are assigned to separate R-Tree subindices depending on their type and spanned layers, reducing
+ * overlap and improving search time.
+ **/
+class PNS_INDEX
+{
+public:
+ typedef std::list<PNS_ITEM*> NET_ITEMS_LIST;
+ typedef SHAPE_INDEX<PNS_ITEM*> ITEM_SHAPE_INDEX;
+ typedef boost::unordered_set<PNS_ITEM*> ITEM_SET;
+
+ PNS_INDEX();
+ ~PNS_INDEX();
+
+ /**
+ * Function Add()
+ *
+ * Adds item to the spatial index.
+ */
+ void Add( PNS_ITEM* aItem );
+
+ /**
+ * Function Remove()
+ *
+ * Removes an item from the spatial index.
+ */
+ void Remove( PNS_ITEM* aItem );
+
+ /**
+ * Function Add()
+ *
+ * Replaces one item with another.
+ */
+ void Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem );
+
+ /**
+ * Function Query()
+ *
+ * Searches items in the index that are in proximity of aItem.
+ * For each item, function object aVisitor is called. Only items on
+ * overlapping layers are considered.
+ *
+ * @param aItem item to search against
+ * @param aMinDistance proximity distance (wrs to the item's shape)
+ * @param aVisitor function object called on each found item. Return
+ false from the visitor to stop searching.
+ * @return number of items found.
+ */
+ template<class Visitor>
+ int Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& aVisitor );
+
+ /**
+ * Function Query()
+ *
+ * Searches items in the index that are in proximity of aShape.
+ * For each item, function object aVisitor is called. Treats all
+ * layers as colliding.
+ *
+ * @param aShape shape to search against
+ * @param aMinDistance proximity distance (wrs to the item's shape)
+ * @param aVisitor function object called on each found item. Return
+ false from the visitor to stop searching.
+ * @return number of items found.
+ */
+ template<class Visitor>
+ int Query( const SHAPE* aShape, int aMinDistance, Visitor& aVisitor );
+
+ /**
+ * Function Clear()
+ *
+ * Removes all items from the index.
+ */
+ void Clear();
+
+ /**
+ * Function GetItemsForNet()
+ *
+ * Returns list of all items in a given net.
+ */
+ NET_ITEMS_LIST* GetItemsForNet( int aNet );
+
+ /**
+ * Function Contains()
+ *
+ * Returns true if item aItem exists in the index.
+ */
+ bool Contains( PNS_ITEM* aItem ) const
+ {
+ return m_allItems.find( aItem ) != m_allItems.end();
+ }
+
+ /**
+ * Function Size()
+ *
+ * Returns number of items stored in the index.
+ */
+ int Size() const { return m_allItems.size(); }
+
+ ITEM_SET::iterator begin() { return m_allItems.begin(); }
+ ITEM_SET::iterator end() { return m_allItems.end(); }
+
+private:
+ static const int MaxSubIndices = 128;
+ static const int SI_Multilayer = 2;
+ static const int SI_SegDiagonal = 0;
+ static const int SI_SegStraight = 1;
+ static const int SI_Traces = 3;
+ static const int SI_PadsTop = 0;
+ static const int SI_PadsBottom = 1;
+
+ template <class Visitor>
+ int querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& aVisitor );
+
+ ITEM_SHAPE_INDEX* getSubindex( const PNS_ITEM* aItem );
+
+ ITEM_SHAPE_INDEX* m_subIndices[MaxSubIndices];
+ std::map<int, NET_ITEMS_LIST> m_netMap;
+ ITEM_SET m_allItems;
+};
+
+PNS_INDEX::PNS_INDEX()
+{
+ memset( m_subIndices, 0, sizeof( m_subIndices ) );
+}
+
+PNS_INDEX::ITEM_SHAPE_INDEX* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
+{
+ int idx_n = -1;
+
+ const PNS_LAYERSET l = aItem->Layers();
+
+ switch( aItem->Kind() )
+ {
+ case PNS_ITEM::VIA:
+ idx_n = SI_Multilayer;
+ break;
+
+ case PNS_ITEM::SOLID:
+ {
+ if( l.IsMultilayer() )
+ idx_n = SI_Multilayer;
+ else if( l.Start() == B_Cu ) // fixme: use kicad layer codes
+ idx_n = SI_PadsTop;
+ else if( l.Start() == F_Cu )
+ idx_n = SI_PadsBottom;
+ }
+ break;
+
+ case PNS_ITEM::SEGMENT:
+ case PNS_ITEM::LINE:
+ idx_n = SI_Traces + 2 * l.Start() + SI_SegStraight;
+ break;
+
+ default:
+ break;
+ }
+
+ assert( idx_n >= 0 && idx_n < MaxSubIndices );
+
+ if( !m_subIndices[idx_n] )
+ m_subIndices[idx_n] = new ITEM_SHAPE_INDEX;
+
+ return m_subIndices[idx_n];
+}
+
+void PNS_INDEX::Add( PNS_ITEM* aItem )
+{
+ ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
+
+ idx->Add( aItem );
+ m_allItems.insert( aItem );
+ int net = aItem->Net();
+
+ if( net >= 0 )
+ {
+ m_netMap[net].push_back( aItem );
+ }
+}
+
+void PNS_INDEX::Remove( PNS_ITEM* aItem )
+{
+ ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
+
+ idx->Remove( aItem );
+ m_allItems.erase( aItem );
+
+ int net = aItem->Net();
+
+ if( net >= 0 && m_netMap.find( net ) != m_netMap.end() )
+ m_netMap[net].remove( aItem );
+}
+
+void PNS_INDEX::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem )
+{
+ Remove( aOldItem );
+ Add( aNewItem );
+}
+
+template<class Visitor>
+int PNS_INDEX::querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& aVisitor )
+{
+ if( !m_subIndices[index] )
+ return 0;
+
+ return m_subIndices[index]->Query( aShape, aMinDistance, aVisitor, false );
+}
+
+template<class Visitor>
+int PNS_INDEX::Query( const PNS_ITEM* aItem, int aMinDistance, Visitor& aVisitor )
+{
+ const SHAPE* shape = aItem->Shape();
+ int total = 0;
+
+ total += querySingle( SI_Multilayer, shape, aMinDistance, aVisitor );
+
+ const PNS_LAYERSET layers = aItem->Layers();
+
+ if( layers.IsMultilayer() )
+ {
+ total += querySingle( SI_PadsTop, shape, aMinDistance, aVisitor );
+ total += querySingle( SI_PadsBottom, shape, aMinDistance, aVisitor );
+
+ for( int i = layers.Start(); i <= layers.End(); ++i )
+ total += querySingle( SI_Traces + 2 * i + SI_SegStraight, shape, aMinDistance, aVisitor );
+ }
+ else
+ {
+ int l = layers.Start();
+
+ if( l == B_Cu )
+ total += querySingle( SI_PadsTop, shape, aMinDistance, aVisitor );
+ else if( l == F_Cu )
+ total += querySingle( SI_PadsBottom, shape, aMinDistance, aVisitor );
+
+ total += querySingle( SI_Traces + 2 * l + SI_SegStraight, shape, aMinDistance, aVisitor );
+ }
+
+ return total;
+}
+
+template<class Visitor>
+int PNS_INDEX::Query( const SHAPE* aShape, int aMinDistance, Visitor& aVisitor )
+{
+ int total = 0;
+
+ for( int i = 0; i < MaxSubIndices; i++ )
+ total += querySingle( i, aShape, aMinDistance, aVisitor );
+
+ return total;
+}
+
+void PNS_INDEX::Clear()
+{
+ for( int i = 0; i < MaxSubIndices; ++i )
+ {
+ ITEM_SHAPE_INDEX* idx = m_subIndices[i];
+
+ if( idx )
+ delete idx;
+
+ m_subIndices[i] = NULL;
+ }
+}
+
+PNS_INDEX::~PNS_INDEX()
+{
+ Clear();
+}
+
+PNS_INDEX::NET_ITEMS_LIST* PNS_INDEX::GetItemsForNet( int aNet )
+{
+ if( m_netMap.find( aNet ) == m_netMap.end() )
+ return NULL;
+
+ return &m_netMap[aNet];
+}
+
+#endif
diff --git a/pcbnew/router/pns_item.cpp b/pcbnew/router/pns_item.cpp
new file mode 100644
index 0000000..eb4b607
--- /dev/null
+++ b/pcbnew/router/pns_item.cpp
@@ -0,0 +1,87 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pns_item.h"
+#include "pns_line.h"
+
+bool PNS_ITEM::collideSimple( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV,
+ VECTOR2I& aMTV, bool aDifferentNetsOnly ) const
+{
+ // same nets? no collision!
+ if( aDifferentNetsOnly && m_net == aOther->m_net )
+ return false;
+
+ // check if we are not on completely different layers first
+ if( !m_layers.Overlaps( aOther->m_layers ) )
+ return false;
+
+ return Shape()->Collide( aOther->Shape(), aClearance );
+
+ // fixme: MTV
+}
+
+
+bool PNS_ITEM::Collide( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV,
+ VECTOR2I& aMTV, bool aDifferentNetsOnly ) const
+{
+ if( collideSimple( aOther, aClearance, aNeedMTV, aMTV, aDifferentNetsOnly ) )
+ return true;
+
+ // special case for "head" line with a via attached at the end.
+ if( aOther->m_kind == LINE )
+ {
+ const PNS_LINE* line = static_cast<const PNS_LINE*>( aOther );
+
+ if( line->EndsWithVia() )
+ return collideSimple( &line->Via(), aClearance - line->Width() / 2, aNeedMTV, aMTV, aDifferentNetsOnly );
+ }
+
+ return false;
+}
+
+
+const std::string PNS_ITEM::KindStr() const
+{
+ switch( m_kind )
+ {
+ case LINE:
+ return "line";
+
+ case SEGMENT:
+ return "segment";
+
+ case VIA:
+ return "via";
+
+ case JOINT:
+ return "joint";
+
+ case SOLID:
+ return "solid";
+
+ default:
+ return "unknown";
+ }
+}
+
+
+PNS_ITEM::~PNS_ITEM()
+{
+}
diff --git a/pcbnew/router/pns_item.h b/pcbnew/router/pns_item.h
new file mode 100644
index 0000000..a7511a7
--- /dev/null
+++ b/pcbnew/router/pns_item.h
@@ -0,0 +1,350 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_ITEM_H
+#define __PNS_ITEM_H
+
+#include <math/vector2d.h>
+
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+
+#include "trace.h"
+
+#include "pns_layerset.h"
+
+class BOARD_CONNECTED_ITEM;
+class PNS_NODE;
+
+enum LineMarker {
+ MK_HEAD = ( 1 << 0 ),
+ MK_VIOLATION = ( 1 << 3 ),
+ MK_LOCKED = ( 1 << 4 ),
+ MK_DP_COUPLED = ( 1 << 5 )
+};
+
+
+/**
+ * Class PNS_ITEM
+ *
+ * Base class for PNS router board items. Implements the shared properties of all PCB items -
+ * net, spanned layers, geometric shape & refererence to owning model.
+ */
+class PNS_ITEM
+{
+public:
+ static const int UnusedNet = INT_MAX;
+
+ ///> Supported item types
+ enum PnsKind
+ {
+ SOLID = 1,
+ LINE = 2,
+ JOINT = 4,
+ SEGMENT = 8,
+ VIA = 16,
+ DIFF_PAIR = 32,
+ ANY = 0xff
+ };
+
+ PNS_ITEM( PnsKind aKind )
+ {
+ m_net = UnusedNet;
+ m_movable = true;
+ m_kind = aKind;
+ m_parent = NULL;
+ m_owner = NULL;
+ m_marker = 0;
+ m_rank = -1;
+ }
+
+ PNS_ITEM( const PNS_ITEM& aOther )
+ {
+ m_layers = aOther.m_layers;
+ m_net = aOther.m_net;
+ m_movable = aOther.m_movable;
+ m_kind = aOther.m_kind;
+ m_parent = aOther.m_parent;
+ m_owner = NULL;
+ m_marker = aOther.m_marker;
+ m_rank = aOther.m_rank;
+ }
+
+ virtual ~PNS_ITEM();
+
+ /**
+ * Function Clone()
+ *
+ * Returns a deep copy of the item
+ */
+ virtual PNS_ITEM* Clone() const = 0;
+
+ /*
+ * Function Hull()
+ *
+ * Returns a convex polygon "hull" of a the item, that is used as the walk-around
+ * path.
+ * @param aClearance defines how far from the body of the item the hull should be,
+ * @param aWalkaroundThickness is the width of the line that walks around this hull.
+ */
+ virtual const SHAPE_LINE_CHAIN Hull( int aClearance = 0, int aWalkaroundThickness = 0 ) const
+ {
+ return SHAPE_LINE_CHAIN();
+ }
+
+ /**
+ * Function Kind()
+ *
+ * Returns the type (kind) of the item
+ */
+ PnsKind Kind() const
+ {
+ return m_kind;
+ }
+
+ /**
+ * Function OfKind()
+ *
+ * Returns true if the item's type matches the mask aKindMask.
+ */
+ bool OfKind( int aKindMask ) const
+ {
+ return ( aKindMask & m_kind ) != 0;
+ }
+
+ /**
+ * Function KindStr()
+ *
+ * Returns the kind of the item, as string
+ */
+ const std::string KindStr() const;
+
+ /**
+ * Function SetParent()
+ *
+ * Sets the corresponding parent object in the host application's model.
+ */
+ void SetParent( BOARD_CONNECTED_ITEM* aParent )
+ {
+ m_parent = aParent;
+ }
+
+ /**
+ * Function Parent()
+ *
+ * Returns the corresponding parent object in the host application's model.
+ */
+ BOARD_CONNECTED_ITEM* Parent() const
+ {
+ return m_parent;
+ }
+
+ /**
+ * Function SetNet()
+ *
+ * Sets the item's net to aNet
+ */
+ void SetNet( int aNet )
+ {
+ m_net = aNet;
+ }
+
+ /**
+ * Function Net()
+ *
+ * Returns the item's net.
+ */
+ int Net() const
+ {
+ return m_net;
+ }
+
+ /**
+ * Function SetLayers()
+ *
+ * Sets the layers spanned by the item to aLayers.
+ */
+ void SetLayers( const PNS_LAYERSET& aLayers )
+ {
+ m_layers = aLayers;
+ }
+
+ /**
+ * Function SetLayer()
+ *
+ * Sets the layers spanned by the item to a single layer aLayer.
+ */
+ void SetLayer( int aLayer )
+ {
+ m_layers = PNS_LAYERSET( aLayer, aLayer );
+ }
+
+ /**
+ * Function Layers()
+ *
+ * Returns the contiguous set of layers spanned by the item.
+ */
+ const PNS_LAYERSET& Layers() const
+ {
+ return m_layers;
+ }
+
+ /**
+ * Function Layer()
+ *
+ * Returns the item's layer, for single-layered items only.
+ */
+ virtual int Layer() const
+ {
+ return Layers().Start();
+ }
+
+ /**
+ * Function LayersOverlap()
+ *
+ * Returns true if the set of layers spanned by aOther overlaps our
+ * layers.
+ */
+ bool LayersOverlap( const PNS_ITEM* aOther ) const
+ {
+ return Layers().Overlaps( aOther->Layers() );
+ }
+
+ /**
+ * Functon SetOwner()
+ *
+ * Sets the node that owns this item. An item can belong to a single
+ * PNS_NODE or stay unowned.
+ */
+ void SetOwner( PNS_NODE* aOwner )
+ {
+ m_owner = aOwner;
+ }
+
+ /**
+ * Function BelongsTo()
+ *
+ * @return true if the item is owned by the node aNode.
+ */
+ bool BelongsTo( PNS_NODE* aNode ) const
+ {
+ return m_owner == aNode;
+ }
+
+ /**
+ * Function Owner()
+ *
+ * Returns the owner of this item, or NULL if there's none.
+ */
+ PNS_NODE* Owner() const { return m_owner; }
+
+ /**
+ * Function Collide()
+ *
+ * Checks for a collision (clearance violation) with between us and item aOther.
+ * Collision checking takes all PCB stuff into accound (layers, nets, DRC rules).
+ * Optionally returns a minimum translation vector for force propagation
+ * algorithm.
+ *
+ * @param aOther item to check collision against
+ * @param aClearance desired clearance
+ * @param aNeedMTV when true, the minimum translation vector is calculated
+ * @param aMTV the minimum translation vector
+ * @return true, if a collision was found.
+ */
+ virtual bool Collide( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV,
+ VECTOR2I& aMTV, bool aDifferentNetsOnly = true ) const;
+
+ /**
+ * Function Collide()
+ *
+ * A shortcut for PNS_ITEM::Colllide() without MTV stuff.
+ */
+ bool Collide( const PNS_ITEM* aOther, int aClearance, bool aDifferentNetsOnly = true ) const
+ {
+ VECTOR2I dummy;
+
+ return Collide( aOther, aClearance, false, dummy, aDifferentNetsOnly );
+ }
+
+ /**
+ * Function Shape()
+ *
+ * Returns the geometrical shape of the item. Used
+ * for collision detection & spatial indexing.
+ */
+ virtual const SHAPE* Shape() const
+ {
+ return NULL;
+ }
+
+ virtual void Mark(int aMarker)
+ {
+ m_marker = aMarker;
+ }
+
+ virtual void Unmark ()
+ {
+ m_marker = 0;
+ }
+
+ virtual int Marker() const
+ {
+ return m_marker;
+ }
+
+ virtual void SetRank( int aRank )
+ {
+ m_rank = aRank;
+ }
+
+ virtual int Rank() const
+ {
+ return m_rank;
+ }
+
+ virtual VECTOR2I Anchor( int n ) const
+ {
+ return VECTOR2I ();
+ }
+
+ virtual int AnchorCount() const
+ {
+ return 0;
+ }
+
+private:
+ bool collideSimple( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV,
+ VECTOR2I& aMTV, bool aDifferentNetsOnly ) const;
+
+protected:
+ PnsKind m_kind;
+
+ BOARD_CONNECTED_ITEM* m_parent;
+ PNS_NODE* m_owner;
+ PNS_LAYERSET m_layers;
+
+ bool m_movable;
+ int m_net;
+ int m_marker;
+ int m_rank;
+};
+
+#endif // __PNS_ITEM_H
diff --git a/pcbnew/router/pns_itemset.cpp b/pcbnew/router/pns_itemset.cpp
new file mode 100644
index 0000000..06561a7
--- /dev/null
+++ b/pcbnew/router/pns_itemset.cpp
@@ -0,0 +1,138 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+
+#include "pns_itemset.h"
+#include "pns_line.h"
+
+
+PNS_ITEMSET::~PNS_ITEMSET()
+{
+}
+
+
+void PNS_ITEMSET::Add( const PNS_LINE& aLine )
+{
+ PNS_LINE* copy = aLine.Clone();
+ m_items.push_back( ENTRY( copy, true ) );
+}
+
+
+void PNS_ITEMSET::Prepend( const PNS_LINE& aLine )
+{
+ PNS_LINE* copy = aLine.Clone();
+ m_items.insert( m_items.begin(), ENTRY( copy, true ) );
+}
+
+
+PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd, bool aInvert )
+{
+ ENTRIES newItems;
+ PNS_LAYERSET l;
+
+ if( aEnd < 0 )
+ l = PNS_LAYERSET( aStart );
+ else
+ l = PNS_LAYERSET( aStart, aEnd );
+
+ BOOST_FOREACH( const ENTRY& ent, m_items )
+ {
+ if( ent.item->Layers().Overlaps( l ) ^ aInvert )
+ {
+ newItems.push_back( ent );
+ }
+ }
+
+ m_items = newItems;
+
+ return *this;
+}
+
+
+PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask, bool aInvert )
+{
+ ENTRIES newItems;
+
+ BOOST_FOREACH( const ENTRY& ent, m_items )
+ {
+ if( ent.item->OfKind( aKindMask ) ^ aInvert )
+ {
+ newItems.push_back( ent );
+ }
+ }
+
+ m_items = newItems;
+
+ return *this;
+}
+
+
+PNS_ITEMSET& PNS_ITEMSET::FilterMarker( int aMarker, bool aInvert )
+{
+ ENTRIES newItems;
+
+ BOOST_FOREACH( const ENTRY& ent, m_items )
+ {
+ if( ent.item->Marker() & aMarker )
+ {
+ newItems.push_back( ent );
+ }
+ }
+
+ m_items = newItems;
+
+ return *this;
+}
+
+
+PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet, bool aInvert )
+{
+ ENTRIES newItems;
+
+ BOOST_FOREACH( const ENTRY& ent, m_items )
+ {
+ if( ( ent.item->Net() == aNet ) ^ aInvert )
+ {
+ newItems.push_back( ent );
+ }
+ }
+
+ m_items = newItems;
+
+ return *this;
+}
+
+
+PNS_ITEMSET& PNS_ITEMSET::ExcludeItem( const PNS_ITEM* aItem )
+{
+ ENTRIES newItems;
+
+ BOOST_FOREACH( const ENTRY& ent, m_items )
+ {
+ if( ent.item != aItem )
+
+ newItems.push_back( ent );
+ }
+
+ m_items = newItems;
+
+ return *this;
+}
diff --git a/pcbnew/router/pns_itemset.h b/pcbnew/router/pns_itemset.h
new file mode 100644
index 0000000..728d0ae
--- /dev/null
+++ b/pcbnew/router/pns_itemset.h
@@ -0,0 +1,227 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_ITEMSET_H
+#define __PNS_ITEMSET_H
+
+#include <vector>
+#include <boost/foreach.hpp>
+
+#include "pns_item.h"
+
+/**
+ * Class PNS_ITEMSET
+ *
+ * Holds a list of board items, that can be filtered against net, kinds,
+ * layers, etc.
+ **/
+class PNS_LINE;
+
+class PNS_ITEMSET
+{
+public:
+ struct ENTRY {
+
+ ENTRY( PNS_ITEM* aItem, bool aOwned = false ) :
+ item( aItem ),
+ owned( aOwned )
+ {}
+
+ ENTRY( const ENTRY& aOther )
+ {
+ owned = aOther.owned;
+
+ if( aOther.owned )
+ item = aOther.item->Clone();
+ else
+ item = aOther.item;
+ }
+
+ ~ENTRY()
+ {
+ if( owned )
+ delete item;
+ }
+
+ bool operator== ( const ENTRY& b ) const
+ {
+ return item == b.item;
+ }
+
+ bool operator< ( const ENTRY& b ) const
+ {
+ return item < b.item;
+ }
+
+ ENTRY& operator= ( const ENTRY& aOther )
+ {
+ owned = aOther.owned;
+
+ if( aOther.owned )
+ item = aOther.item->Clone();
+ else
+ item = aOther.item;
+
+ return *this;
+ }
+
+ operator PNS_ITEM* () const
+ {
+ return item;
+ }
+
+ PNS_ITEM *item;
+ bool owned;
+ };
+
+ typedef std::vector<ENTRY> ENTRIES;
+
+ PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL, bool aBecomeOwner = false )
+ {
+ if( aInitialItem )
+ {
+ m_items.push_back( ENTRY( aInitialItem, aBecomeOwner ) );
+ }
+ }
+
+ PNS_ITEMSET( const PNS_ITEMSET& aOther )
+ {
+ m_items = aOther.m_items;
+ }
+
+ ~PNS_ITEMSET();
+
+ const PNS_ITEMSET& operator=( const PNS_ITEMSET& aOther )
+ {
+ m_items = aOther.m_items;
+ return *this;
+ }
+
+ int Count( int aKindMask = -1 ) const
+ {
+ int n = 0;
+
+ BOOST_FOREACH( PNS_ITEM* item, m_items )
+ {
+ if( item->Kind() & aKindMask )
+ n++;
+ }
+
+ return n;
+ }
+
+ bool Empty() const
+ {
+ return m_items.empty();
+ }
+
+ ENTRIES& Items() { return m_items; }
+ const ENTRIES& CItems() const { return m_items; }
+
+ PNS_ITEMSET& FilterLayers( int aStart, int aEnd = -1, bool aInvert = false );
+ PNS_ITEMSET& FilterKinds( int aKindMask, bool aInvert = false );
+ PNS_ITEMSET& FilterNet( int aNet, bool aInvert = false );
+ PNS_ITEMSET& FilterMarker( int aMarker, bool aInvert = false );
+
+ PNS_ITEMSET& ExcludeLayers( int aStart, int aEnd = -1 )
+ {
+ return FilterLayers( aStart, aEnd, true );
+ }
+
+ PNS_ITEMSET& ExcludeKinds( int aKindMask )
+ {
+ return FilterKinds( aKindMask, true );
+ }
+
+ PNS_ITEMSET& ExcludeNet( int aNet )
+ {
+ return FilterNet( aNet, true );
+ }
+
+ PNS_ITEMSET& ExcludeItem( const PNS_ITEM* aItem );
+
+ int Size() const
+ {
+ return m_items.size();
+ }
+
+ void Add( const PNS_LINE& aLine );
+ void Prepend( const PNS_LINE& aLine );
+
+ PNS_ITEM* operator[] ( int index ) const
+ {
+ return m_items[index].item;
+ }
+
+ void Add( PNS_ITEM* aItem, bool aBecomeOwner = false )
+ {
+ m_items.push_back( ENTRY( aItem, aBecomeOwner ) );
+ }
+
+ void Prepend( PNS_ITEM* aItem, bool aBecomeOwner = false )
+ {
+ m_items.insert( m_items.begin(), ENTRY( aItem, aBecomeOwner ) );
+ }
+
+ void Clear()
+ {
+ m_items.clear();
+ }
+
+ bool Contains( PNS_ITEM* aItem ) const
+ {
+ const ENTRY ent( aItem );
+ return std::find( m_items.begin(), m_items.end(), ent ) != m_items.end();
+ }
+
+ void Erase( PNS_ITEM* aItem )
+ {
+ ENTRY ent( aItem );
+ ENTRIES::iterator f = std::find( m_items.begin(), m_items.end(), ent );
+
+ if( f != m_items.end() )
+ m_items.erase( f );
+ }
+
+ template<class T>
+ T* FindByKind( PNS_ITEM::PnsKind kind, int index = 0 )
+ {
+ int n = 0;
+
+ BOOST_FOREACH( const PNS_ITEM* item, m_items )
+ {
+ if( item->OfKind( kind ) )
+ {
+ if( index == n )
+ return static_cast<T*>( item );
+ else
+ n++;
+ }
+ }
+
+ return NULL;
+ }
+
+private:
+
+ ENTRIES m_items;
+};
+
+#endif
diff --git a/pcbnew/router/pns_joint.h b/pcbnew/router/pns_joint.h
new file mode 100644
index 0000000..eab4a56
--- /dev/null
+++ b/pcbnew/router/pns_joint.h
@@ -0,0 +1,259 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_JOINT_H
+#define __PNS_JOINT_H
+
+#include <vector>
+#include <boost/functional/hash.hpp>
+
+#include <math/vector2d.h>
+
+#include "pns_item.h"
+#include "pns_segment.h"
+#include "pns_itemset.h"
+
+/**
+ * Class PNS_JOINT
+ *
+ * Represents a 2D point on a given set of layers and belonging to a certain
+ * net, that links together a number of board items.
+ * A hash table of joints is used by the router to follow connectivity between
+ * the items.
+ **/
+class PNS_JOINT : public PNS_ITEM
+{
+public:
+ typedef PNS_ITEMSET::ENTRIES LINKED_ITEMS;
+
+ ///> Joints are hashed by their position, layers and net.
+ /// Linked items are, obviously, not hashed
+ struct HASH_TAG
+ {
+ VECTOR2I pos;
+ int net;
+ };
+
+ PNS_JOINT() :
+ PNS_ITEM( JOINT ), m_locked( false ) {}
+
+ PNS_JOINT( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, int aNet = -1 ) :
+ PNS_ITEM( JOINT )
+ {
+ m_tag.pos = aPos;
+ m_tag.net = aNet;
+ m_layers = aLayers;
+ m_locked = false;
+ }
+
+ PNS_JOINT( const PNS_JOINT& aB ) :
+ PNS_ITEM( JOINT )
+ {
+ m_layers = aB.m_layers;
+ m_tag.pos = aB.m_tag.pos;
+ m_tag.net = aB.m_tag.net;
+ m_linkedItems = aB.m_linkedItems;
+ m_layers = aB.m_layers;
+ m_locked = aB.m_locked;
+ }
+
+ PNS_ITEM* Clone( ) const
+ {
+ assert( false );
+ return NULL;
+ }
+
+ ///> Returns true if the joint is a trivial line corner, connecting two
+ /// segments of the same net, on the same layer.
+ bool IsLineCorner() const
+ {
+ if( m_linkedItems.Size() != 2 || m_linkedItems.Count( SEGMENT ) != 2 )
+ return false;
+
+ PNS_SEGMENT* seg1 = static_cast<PNS_SEGMENT*>( m_linkedItems[0] );
+ PNS_SEGMENT* seg2 = static_cast<PNS_SEGMENT*>( m_linkedItems[1] );
+
+ // joints between segments of different widths are not considered trivial.
+ return seg1->Width() == seg2->Width();
+ }
+
+ bool IsNonFanoutVia() const
+ {
+ int vias = m_linkedItems.Count( VIA );
+ int segs = m_linkedItems.Count( SEGMENT );
+
+ return ( m_linkedItems.Size() == 3 && vias == 1 && segs == 2 );
+ }
+
+ bool IsTraceWidthChange() const
+ {
+ if( m_linkedItems.Size() != 2 )
+ return false;
+
+ if( m_linkedItems.Count( SEGMENT ) != 2)
+ return false;
+
+ PNS_SEGMENT* seg1 = static_cast<PNS_SEGMENT*>( m_linkedItems[0] );
+ PNS_SEGMENT* seg2 = static_cast<PNS_SEGMENT*>( m_linkedItems[1] );
+
+ return seg1->Width() != seg2->Width();
+ }
+
+ ///> Links the joint to a given board item (when it's added to the PNS_NODE)
+ void Link( PNS_ITEM* aItem )
+ {
+ if( m_linkedItems.Contains( aItem ) )
+ return;
+
+ m_linkedItems.Add( aItem );
+ }
+
+ ///> Unlinks a given board item from the joint (upon its removal from a PNS_NODE)
+ ///> Returns true if the joint became dangling after unlinking.
+ bool Unlink( PNS_ITEM* aItem )
+ {
+ m_linkedItems.Erase( aItem );
+ return m_linkedItems.Size() == 0;
+ }
+
+ ///> For trivial joints, returns the segment adjacent to (aCurrent). For non-trival ones, returns
+ ///> NULL, indicating the end of line.
+ PNS_SEGMENT* NextSegment( PNS_SEGMENT* aCurrent ) const
+ {
+ if( !IsLineCorner() )
+ return NULL;
+
+ return static_cast<PNS_SEGMENT*>( m_linkedItems[m_linkedItems[0] == aCurrent ? 1 : 0] );
+ }
+
+ PNS_VIA* Via()
+ {
+ BOOST_FOREACH( PNS_ITEM* item, m_linkedItems.Items() )
+ {
+ if( item->OfKind( VIA ) )
+ return static_cast<PNS_VIA*>( item );
+ }
+
+ return NULL;
+ }
+
+
+ /// trivial accessors
+ const HASH_TAG& Tag() const
+ {
+ return m_tag;
+ }
+
+ const VECTOR2I& Pos() const
+ {
+ return m_tag.pos;
+ }
+
+ int Net() const
+ {
+ return m_tag.net;
+ }
+
+ const LINKED_ITEMS& LinkList() const
+ {
+ return m_linkedItems.CItems();
+ }
+
+ const PNS_ITEMSET& CLinks() const
+ {
+ return m_linkedItems;
+ }
+
+ PNS_ITEMSET& Links()
+ {
+ return m_linkedItems;
+ }
+
+ int LinkCount( int aMask = -1 ) const
+ {
+ return m_linkedItems.Count( aMask );
+ }
+
+ void Dump() const;
+
+ bool operator==( const PNS_JOINT& rhs ) const
+ {
+ return m_tag.pos == rhs.m_tag.pos && m_tag.net == rhs.m_tag.net;
+ }
+
+ void Merge( const PNS_JOINT& aJoint )
+ {
+ if( !Overlaps( aJoint ) )
+ return;
+
+ m_layers.Merge( aJoint.m_layers );
+
+ if( aJoint.IsLocked() )
+ m_locked = true;
+
+ BOOST_FOREACH( PNS_ITEM* item, aJoint.LinkList() )
+ {
+ m_linkedItems.Add( item );
+ }
+ }
+
+ bool Overlaps( const PNS_JOINT& rhs ) const
+ {
+ return m_tag.pos == rhs.m_tag.pos &&
+ m_tag.net == rhs.m_tag.net && m_layers.Overlaps( rhs.m_layers );
+ }
+
+ void Lock( bool aLock = true )
+ {
+ m_locked = aLock;
+ }
+
+ bool IsLocked() const
+ {
+ return m_locked;
+ }
+
+private:
+ ///> hash tag for unordered_multimap
+ HASH_TAG m_tag;
+
+ ///> list of items linked to this joint
+ PNS_ITEMSET m_linkedItems;
+
+ ///> locked (non-movable) flag
+ bool m_locked;
+};
+
+inline bool operator==( PNS_JOINT::HASH_TAG const& aP1, PNS_JOINT::HASH_TAG const& aP2 )
+{
+ return aP1.pos == aP2.pos && aP1.net == aP2.net;
+}
+
+inline std::size_t hash_value( PNS_JOINT::HASH_TAG const& aP )
+{
+ std::size_t seed = 0;
+ boost::hash_combine( seed, aP.pos.x );
+ boost::hash_combine( seed, aP.pos.y );
+ boost::hash_combine( seed, aP.net );
+
+ return seed;
+}
+
+#endif // __PNS_JOINT_H
diff --git a/pcbnew/router/pns_layerset.h b/pcbnew/router/pns_layerset.h
new file mode 100644
index 0000000..9d01dd1
--- /dev/null
+++ b/pcbnew/router/pns_layerset.h
@@ -0,0 +1,129 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_LAYERSET_H
+#define __PNS_LAYERSET_H
+
+#include <algorithm>
+
+/**
+ * Class PNS_LAYERSET
+ *
+ * Represents a contiguous set of PCB layers.
+ */
+class PNS_LAYERSET
+{
+public:
+ PNS_LAYERSET() :
+ m_start( -1 ),
+ m_end( -1 )
+ {};
+
+ PNS_LAYERSET( int aStart, int aEnd )
+ {
+ if( aStart > aEnd )
+ std::swap( aStart, aEnd );
+
+ m_start = aStart;
+ m_end = aEnd;
+ }
+
+ PNS_LAYERSET( int aLayer )
+ {
+ m_start = m_end = aLayer;
+ }
+
+ PNS_LAYERSET( const PNS_LAYERSET& aB ) :
+ m_start( aB.m_start ),
+ m_end( aB.m_end )
+ {}
+
+ ~PNS_LAYERSET() {};
+
+ const PNS_LAYERSET& operator=( const PNS_LAYERSET& aB )
+ {
+ m_start = aB.m_start;
+ m_end = aB.m_end;
+ return *this;
+ }
+
+ bool Overlaps( const PNS_LAYERSET& aOther ) const
+ {
+ return m_end >= aOther.m_start && m_start <= aOther.m_end;
+ }
+
+ bool Overlaps( const int aLayer ) const
+ {
+ return aLayer >= m_start && aLayer <= m_end;
+ }
+
+ bool IsMultilayer() const
+ {
+ return m_start != m_end;
+ }
+
+ int Start() const
+ {
+ return m_start;
+ }
+
+ int End() const
+ {
+ return m_end;
+ }
+
+ void Merge( const PNS_LAYERSET& aOther )
+ {
+ if( m_start < 0 || m_end < 0 )
+ {
+ m_start = aOther.m_start;
+ m_end = aOther.m_end;
+ return;
+ }
+
+ if( aOther.m_start < m_start )
+ m_start = aOther.m_start;
+
+ if( aOther.m_end > m_end )
+ m_end = aOther.m_end;
+ }
+
+ ///> Shortcut for comparisons/overlap tests
+ static PNS_LAYERSET All()
+ {
+ return PNS_LAYERSET( 0, 256 ); // fixme: use layer IDs header
+ }
+
+ bool operator==( const PNS_LAYERSET& aOther ) const
+ {
+ return ( m_start == aOther.m_start ) && ( m_end == aOther.m_end );
+ }
+
+ bool operator!=( const PNS_LAYERSET& aOther ) const
+ {
+ return ( m_start != aOther.m_start ) || ( m_end != aOther.m_end );
+ }
+
+private:
+ int m_start;
+ int m_end;
+};
+
+#endif // __PNS_LAYERSET_H
diff --git a/pcbnew/router/pns_line.cpp b/pcbnew/router/pns_line.cpp
new file mode 100644
index 0000000..39d5f5c
--- /dev/null
+++ b/pcbnew/router/pns_line.cpp
@@ -0,0 +1,889 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+#include <boost/optional.hpp>
+
+#include <math/vector2d.h>
+
+#include "pns_line.h"
+#include "pns_node.h"
+#include "pns_via.h"
+#include "pns_utils.h"
+#include "pns_router.h"
+
+#include <geometry/shape_rect.h>
+
+using boost::optional;
+
+PNS_LINE::PNS_LINE( const PNS_LINE& aOther ) :
+ PNS_ITEM( aOther ),
+ m_line( aOther.m_line ),
+ m_width( aOther.m_width )
+{
+ m_net = aOther.m_net;
+ m_movable = aOther.m_movable;
+ m_layers = aOther.m_layers;
+ m_via = aOther.m_via;
+ m_hasVia = aOther.m_hasVia;
+ m_marker = aOther.m_marker;
+ m_rank = aOther.m_rank;
+
+ copyLinks( &aOther );
+}
+
+
+PNS_LINE::~PNS_LINE()
+{
+ delete m_segmentRefs;
+}
+
+
+const PNS_LINE& PNS_LINE::operator=( const PNS_LINE& aOther )
+{
+ m_line = aOther.m_line;
+ m_width = aOther.m_width;
+ m_net = aOther.m_net;
+ m_movable = aOther.m_movable;
+ m_layers = aOther.m_layers;
+ m_via = aOther.m_via;
+ m_hasVia = aOther.m_hasVia;
+ m_marker = aOther.m_marker;
+ m_rank = aOther.m_rank;
+
+ copyLinks( &aOther );
+
+ return *this;
+}
+
+
+PNS_LINE* PNS_LINE::Clone() const
+{
+ PNS_LINE* l = new PNS_LINE( *this );
+
+ return l;
+}
+
+
+void PNS_LINE::Mark( int aMarker )
+{
+ m_marker = aMarker;
+
+ if( m_segmentRefs )
+ {
+ BOOST_FOREACH( PNS_SEGMENT* s, *m_segmentRefs )
+ s->Mark( aMarker );
+ }
+}
+
+
+void PNS_LINE::Unmark()
+{
+ if( m_segmentRefs )
+ {
+ BOOST_FOREACH( PNS_SEGMENT* s, *m_segmentRefs )
+ s->Unmark();
+ }
+
+ m_marker = 0;
+}
+
+
+int PNS_LINE::Marker() const
+{
+ int marker = m_marker;
+
+ if( m_segmentRefs )
+ {
+ BOOST_FOREACH( PNS_SEGMENT* s, *m_segmentRefs )
+ {
+ marker |= s->Marker();
+ }
+ }
+
+ return marker;
+}
+
+
+void PNS_LINE::copyLinks( const PNS_LINE* aParent )
+{
+ if( aParent->m_segmentRefs == NULL )
+ {
+ m_segmentRefs = NULL;
+ return;
+ }
+
+ m_segmentRefs = new SEGMENT_REFS();
+ *m_segmentRefs = *aParent->m_segmentRefs;
+}
+
+
+PNS_SEGMENT* PNS_SEGMENT::Clone() const
+{
+ PNS_SEGMENT* s = new PNS_SEGMENT;
+
+ s->m_seg = m_seg;
+ s->m_net = m_net;
+ s->m_layers = m_layers;
+ s->m_marker = m_marker;
+ s->m_rank = m_rank;
+
+ return s;
+}
+
+
+int PNS_LINE::CountCorners( int aAngles )
+{
+ int count = 0;
+
+ for( int i = 0; i < m_line.SegmentCount() - 1; i++ )
+ {
+ const SEG seg1 = m_line.CSegment( i );
+ const SEG seg2 = m_line.CSegment( i + 1 );
+
+ const DIRECTION_45 dir1( seg1 );
+ const DIRECTION_45 dir2( seg2 );
+
+ DIRECTION_45::AngleType a = dir1.Angle( dir2 );
+
+ if( a & aAngles )
+ count++;
+ }
+
+ return count;
+}
+
+
+bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
+ SHAPE_LINE_CHAIN& aWalk, SHAPE_LINE_CHAIN& aPost, bool aCw ) const
+{
+ const SHAPE_LINE_CHAIN& line( CLine() );
+ VECTOR2I ip_start;
+ VECTOR2I ip_end;
+
+ if( line.SegmentCount() < 1 )
+ return false;
+
+ if( aObstacle.PointInside( line.CPoint( 0 ) ) || aObstacle.PointInside( line.CPoint( -1 ) ) )
+ return false;
+
+ SHAPE_LINE_CHAIN::INTERSECTIONS ips, ips2;
+
+ line.Intersect( aObstacle, ips );
+
+ aWalk.Clear();
+ aPost.Clear();
+
+ int nearest_dist = INT_MAX;
+ int farthest_dist = 0;
+
+ SHAPE_LINE_CHAIN::INTERSECTION nearest, farthest;
+
+ for( int i = 0; i < (int) ips.size(); i++ )
+ {
+ const VECTOR2I p = ips[i].p;
+ int dist = line.PathLength( p );
+
+ if( dist < 0 )
+ return false;
+
+ if( dist <= nearest_dist )
+ {
+ nearest_dist = dist;
+ nearest = ips[i];
+ }
+
+ if( dist >= farthest_dist )
+ {
+ farthest_dist = dist;
+ farthest = ips[i];
+ }
+ }
+
+ if( ips.size() <= 1 || nearest.p == farthest.p )
+ {
+ aPre = line;
+ return true;
+ }
+
+ aPre = line.Slice( 0, nearest.our.Index() );
+ aPre.Append( nearest.p );
+ aPre.Simplify();
+
+ aWalk.Clear();
+ aWalk.SetClosed( false );
+ aWalk.Append( nearest.p );
+
+ assert( nearest.their.Index() >= 0 );
+ assert( farthest.their.Index() >= 0 );
+
+ assert( nearest_dist <= farthest_dist );
+
+ aObstacle.Split( nearest.p );
+ aObstacle.Split( farthest.p );
+
+ int i_first = aObstacle.Find( nearest.p );
+ int i_last = aObstacle.Find( farthest.p );
+
+ int i = i_first;
+
+ while( i != i_last )
+ {
+ aWalk.Append( aObstacle.CPoint( i ) );
+ i += ( aCw ? 1 : -1 );
+
+ if( i < 0 )
+ i = aObstacle.PointCount() - 1;
+ else if( i == aObstacle.PointCount() )
+ i = 0;
+ }
+
+ aWalk.Append( farthest.p );
+ aWalk.Simplify();
+
+ aPost.Clear();
+ aPost.Append( farthest.p );
+ aPost.Append( line.Slice( farthest.our.Index() + 1, -1 ) );
+ aPost.Simplify();
+
+ return true;
+}
+
+
+void PNS_LINE::Walkaround( const SHAPE_LINE_CHAIN& aObstacle,
+ SHAPE_LINE_CHAIN& aPath,
+ bool aCw ) const
+{
+ SHAPE_LINE_CHAIN walk, post;
+
+ Walkaround( aObstacle, aPath, walk, post, aCw );
+ aPath.Append( walk );
+ aPath.Append( post );
+ aPath.Simplify();
+}
+
+
+const SHAPE_LINE_CHAIN PNS_SEGMENT::Hull( int aClearance, int aWalkaroundThickness ) const
+{
+ return SegmentHull ( m_seg, aClearance, aWalkaroundThickness );
+}
+
+
+bool PNS_LINE::Is45Degree()
+{
+ for( int i = 0; i < m_line.SegmentCount(); i++ )
+ {
+ const SEG& s = m_line.CSegment( i );
+
+ if( s.Length() < 10 )
+ continue;
+
+ double angle = 180.0 / M_PI *
+ atan2( (double) s.B.y - (double) s.A.y,
+ (double) s.B.x - (double) s.A.x );
+
+ if( angle < 0 )
+ angle += 360.0;
+
+ double angle_a = fabs( fmod( angle, 45.0 ) );
+
+ if( angle_a > 1.0 && angle_a < 44.0 )
+ return false;
+ }
+
+ return true;
+}
+
+
+const PNS_LINE PNS_LINE::ClipToNearestObstacle( PNS_NODE* aNode ) const
+{
+ const int IterationLimit = 5;
+ int i;
+ PNS_LINE l( *this );
+
+ for( i = 0; i < IterationLimit; i++ )
+ {
+ PNS_NODE::OPT_OBSTACLE obs = aNode->NearestObstacle( &l );
+
+ if( obs )
+ {
+ l.RemoveVia();
+ int p = l.Line().Split( obs->m_ipFirst );
+ l.Line().Remove( p + 1, -1 );
+ } else
+ break;
+ }
+
+ if( i == IterationLimit )
+ l.Line().Clear();
+
+ return l;
+}
+
+
+void PNS_LINE::ShowLinks()
+{
+ if( !m_segmentRefs )
+ {
+ printf( "line %p: no links\n", this );
+ return;
+ }
+
+ printf( "line %p: %d linked segs\n", this, (int) m_segmentRefs->size() );
+
+ for( int i = 0; i < (int) m_segmentRefs->size(); i++ )
+ printf( "seg %d: %p\n", i, (*m_segmentRefs)[i] );
+}
+
+SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECTOR2I& aP )
+{
+ optional<SHAPE_LINE_CHAIN> picked;
+ int i;
+ int d = 2;
+
+ if( aOrigin.SegmentCount() == 1)
+ {
+ DIRECTION_45 dir( aOrigin.CPoint( 0 ) - aOrigin.CPoint( 1 ) );
+
+ return DIRECTION_45().BuildInitialTrace( aOrigin.CPoint( 0 ), aP, dir.IsDiagonal() );
+ }
+
+ if( aOrigin.CSegment( -1 ).Length() > 100000 * 30 ) // fixme: constant/parameter?
+ d = 1;
+
+ for( i = aOrigin.SegmentCount() - d; i >= 0; i-- )
+ {
+ DIRECTION_45 d_start ( aOrigin.CSegment( i ) );
+ VECTOR2I p_start = aOrigin.CPoint( i );
+ SHAPE_LINE_CHAIN paths[2];
+ DIRECTION_45 dirs[2];
+ DIRECTION_45 d_prev = ( i > 0 ? DIRECTION_45( aOrigin.CSegment( i - 1 ) ) : DIRECTION_45() );
+
+ for( int j = 0; j < 2; j++ )
+ {
+ paths[j] = d_start.BuildInitialTrace( p_start, aP, j );
+ dirs[j] = DIRECTION_45( paths[j].CSegment( 0 ) );
+ }
+
+ for( int j = 0; j < 2; j++ )
+ {
+ if( dirs[j] == d_start )
+ {
+ picked = paths[j];
+ break;
+ }
+ }
+
+ if( picked )
+ break;
+
+ for( int j = 0; j < 2; j++ )
+ {
+ if( dirs[j].IsObtuse( d_prev ) )
+ {
+ picked = paths[j];
+ break;
+ }
+ }
+
+ if( picked )
+ break;
+ }
+
+ if( picked )
+ {
+ SHAPE_LINE_CHAIN path = aOrigin.Slice( 0, i );
+ path.Append( *picked );
+
+ return path;
+ }
+
+ DIRECTION_45 dir( aOrigin.CPoint( -1 ) - aOrigin.CPoint( -2 ) );
+
+ return DIRECTION_45().BuildInitialTrace( aOrigin.CPoint( 0 ), aP, dir.IsDiagonal() );
+}
+
+
+void PNS_LINE::DragCorner ( const VECTOR2I& aP, int aIndex, int aSnappingThreshold )
+{
+ SHAPE_LINE_CHAIN path;
+
+ VECTOR2I snapped = snapDraggedCorner( m_line, aP, aIndex, aSnappingThreshold );
+
+ if( aIndex == 0 )
+ path = dragCornerInternal( m_line.Reverse(), snapped ).Reverse();
+ else if( aIndex == m_line.SegmentCount() )
+ path = dragCornerInternal( m_line, snapped );
+ else
+ {
+ // fixme: awkward behaviour for "outwards" drags
+ path = dragCornerInternal( m_line.Slice( 0, aIndex ), snapped );
+ SHAPE_LINE_CHAIN path_rev = dragCornerInternal( m_line.Slice( aIndex, -1 ).Reverse(),
+ snapped ).Reverse();
+ path.Append( path_rev );
+ }
+
+ path.Simplify();
+ m_line = path;
+}
+
+
+VECTOR2I PNS_LINE::snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I& aP,
+ int aIndex, int aThreshold ) const
+{
+ int s_start = std::max( aIndex - 2, 0 );
+ int s_end = std::min( aIndex + 2, aPath.SegmentCount() - 1 );
+
+ int i, j;
+ int best_dist = INT_MAX;
+ VECTOR2I best_snap = aP;
+
+ if( aThreshold <= 0 )
+ return aP;
+
+ for( i = s_start; i <= s_end; i++ )
+ {
+ const SEG& a = aPath.CSegment( i );
+
+ for( j = s_start; j < i; j++ )
+ {
+ const SEG& b = aPath.CSegment( j );
+
+ if( !( DIRECTION_45( a ).IsObtuse(DIRECTION_45( b ) ) ) )
+ continue;
+
+ OPT_VECTOR2I ip = a.IntersectLines(b);
+
+ if( ip )
+ {
+ int dist = ( *ip - aP ).EuclideanNorm();
+
+ if( dist < aThreshold && dist < best_dist )
+ {
+ best_dist = dist;
+ best_snap = *ip;
+ }
+ }
+ }
+ }
+
+ return best_snap;
+}
+
+VECTOR2I PNS_LINE::snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP,
+ int aIndex, int aThreshold ) const
+{
+ VECTOR2I snap_p[2];
+ DIRECTION_45 dragDir( aPath.CSegment( aIndex ) );
+ int snap_d[2] = { -1, -1 };
+
+ if( aThreshold == 0 )
+ return aP;
+
+ if( aIndex >= 2 )
+ {
+ SEG s = aPath.CSegment( aIndex - 2 );
+
+ if( DIRECTION_45( s ) == dragDir )
+ snap_d[0] = s.LineDistance( aP );
+
+ snap_p[0] = s.A;
+ }
+
+ if( aIndex < aPath.SegmentCount() - 2 )
+ {
+ SEG s = aPath.CSegment( aIndex + 2 );
+
+ if( DIRECTION_45( s ) == dragDir )
+ snap_d[1] = s.LineDistance(aP);
+
+ snap_p[1] = s.A;
+ }
+
+ VECTOR2I best = aP;
+ int minDist = INT_MAX;
+
+ for( int i = 0; i < 2; i++ )
+ {
+ if( snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <= aThreshold )
+ {
+ minDist = snap_d[i];
+ best = snap_p[i];
+ }
+ }
+
+ return best;
+}
+
+
+void PNS_LINE::DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThreshold )
+{
+ SHAPE_LINE_CHAIN path( m_line );
+ VECTOR2I target( aP );
+
+ SEG guideA[2], guideB[2];
+ int index = aIndex;
+
+ target = snapToNeighbourSegments( path, aP, aIndex, aSnappingThreshold );
+
+ if( index == 0 )
+ {
+ path.Insert( 0, path.CPoint( 0 ) );
+ index++;
+ }
+
+ if( index == path.SegmentCount() - 1 )
+ {
+ path.Insert( path.PointCount() - 1, path.CPoint( -1 ) );
+ }
+
+ SEG dragged = path.CSegment( index );
+ DIRECTION_45 drag_dir( dragged );
+
+ SEG s_prev = path.CSegment( index - 1 );
+ SEG s_next = path.CSegment( index + 1 );
+
+ DIRECTION_45 dir_prev( s_prev );
+ DIRECTION_45 dir_next( s_next );
+
+ if( dir_prev == drag_dir )
+ {
+ dir_prev = dir_prev.Left();
+ path.Insert( index, path.CPoint( index ) );
+ index++;
+ }
+
+ if( dir_next == drag_dir )
+ {
+ dir_next = dir_next.Right();
+ path.Insert( index + 1, path.CPoint( index + 1 ) );
+ }
+
+ s_prev = path.CSegment( index - 1 );
+ s_next = path.CSegment( index + 1 );
+ dragged = path.CSegment( index );
+
+ bool lockEndpointA = true;
+ bool lockEndpointB = true;
+
+ if( aIndex == 0 )
+ {
+ if( !lockEndpointA )
+ guideA[0] = guideA[1] = SEG( dragged.A, dragged.A + drag_dir.Right().Right().ToVector() );
+ else
+ {
+ guideA[0] = SEG( dragged.A, dragged.A + drag_dir.Right().ToVector() );
+ guideA[1] = SEG( dragged.A, dragged.A + drag_dir.Left().ToVector() );
+ }
+ }
+ else
+ {
+ if( dir_prev.IsObtuse(drag_dir ) )
+ {
+ guideA[0] = SEG( s_prev.A, s_prev.A + drag_dir.Left().ToVector() );
+ guideA[1] = SEG( s_prev.A, s_prev.A + drag_dir.Right().ToVector() );
+ }
+ else
+ guideA[0] = guideA[1] = SEG( dragged.A, dragged.A + dir_prev.ToVector() );
+ }
+
+ if( aIndex == m_line.SegmentCount() - 1 )
+ {
+ if( !lockEndpointB )
+ guideB[0] = guideB[1] = SEG( dragged.B, dragged.B + drag_dir.Right().Right().ToVector() );
+ else
+ {
+ guideB[0] = SEG( dragged.B, dragged.B + drag_dir.Right().ToVector() );
+ guideB[1] = SEG( dragged.B, dragged.B + drag_dir.Left().ToVector() );
+ }
+ }
+ else
+ {
+ if( dir_next.IsObtuse( drag_dir ) )
+ {
+ guideB[0] = SEG( s_next.B, s_next.B + drag_dir.Left().ToVector() );
+ guideB[1] = SEG( s_next.B, s_next.B + drag_dir.Right().ToVector() );
+ }
+ else
+ guideB[0] = guideB[1] = SEG( dragged.B, dragged.B + dir_next.ToVector() );
+ }
+
+ SEG s_current( target, target + drag_dir.ToVector() );
+
+ int best_len = INT_MAX;
+ SHAPE_LINE_CHAIN best;
+
+ for( int i = 0; i < 2; i++ )
+ {
+ for( int j = 0; j < 2; j++ )
+ {
+ OPT_VECTOR2I ip1 = s_current.IntersectLines( guideA[i] );
+ OPT_VECTOR2I ip2 = s_current.IntersectLines( guideB[j] );
+
+ SHAPE_LINE_CHAIN np;
+
+ if( !ip1 || !ip2 )
+ continue;
+
+ SEG s1( s_prev.A, *ip1 );
+ SEG s2( *ip1, *ip2 );
+ SEG s3( *ip2, s_next.B );
+
+ OPT_VECTOR2I ip;
+
+ if( (ip = s1.Intersect( s_next )) )
+ {
+ np.Append ( s1.A );
+ np.Append ( *ip );
+ np.Append ( s_next.B );
+ }
+ else if( (ip = s3.Intersect( s_prev )) )
+ {
+ np.Append ( s_prev.A );
+ np.Append ( *ip );
+ np.Append ( s3.B );
+ }
+ else if( (ip = s1.Intersect( s3 )) )
+ {
+ np.Append( s_prev.A );
+ np.Append( *ip );
+ np.Append( s_next.B );
+ }
+ else
+ {
+ np.Append( s_prev.A );
+ np.Append( *ip1 );
+ np.Append( *ip2 );
+ np.Append( s_next.B );
+ }
+
+ if( np.Length() < best_len )
+ {
+ best_len = np.Length();
+ best = np;
+ }
+ }
+ }
+
+ if( !lockEndpointA && aIndex == 0 )
+ best.Remove( 0, 0 );
+ if( !lockEndpointB && aIndex == m_line.SegmentCount() - 1 )
+ best.Remove( -1, -1 );
+
+ if( m_line.PointCount() == 1 )
+ m_line = best;
+ else if( aIndex == 0 )
+ m_line.Replace( 0, 1, best );
+ else if( aIndex == m_line.SegmentCount() - 1 )
+ m_line.Replace( -2, -1, best );
+ else
+ m_line.Replace( aIndex, aIndex + 1, best );
+
+ m_line.Simplify();
+}
+
+
+bool PNS_LINE::CompareGeometry( const PNS_LINE& aOther )
+{
+ return m_line.CompareGeometry( aOther.m_line );
+}
+
+
+void PNS_LINE::Reverse()
+{
+ m_line = m_line.Reverse();
+
+ if( m_segmentRefs )
+ std::reverse( m_segmentRefs->begin(), m_segmentRefs->end() );
+}
+
+
+void PNS_LINE::AppendVia( const PNS_VIA& aVia )
+{
+ if( m_line.PointCount() > 1 && aVia.Pos() == m_line.CPoint( 0 ) )
+ {
+ Reverse();
+ }
+
+ m_hasVia = true;
+ m_via = aVia;
+ m_via.SetNet( m_net );
+}
+
+
+void PNS_LINE::SetRank( int aRank )
+{
+ m_rank = aRank;
+
+ if( m_segmentRefs )
+ {
+ BOOST_FOREACH( PNS_SEGMENT* s, *m_segmentRefs )
+ s->SetRank( aRank );
+ }
+}
+
+
+int PNS_LINE::Rank() const
+{
+ int min_rank = INT_MAX;
+ int rank;
+
+ if( m_segmentRefs )
+ {
+ BOOST_FOREACH( PNS_SEGMENT *s, *m_segmentRefs )
+ min_rank = std::min( min_rank, s->Rank() );
+ rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
+ }
+ else
+ {
+ rank = m_rank;
+ }
+
+ return rank;
+}
+
+
+void PNS_LINE::ClipVertexRange( int aStart, int aEnd )
+{
+ m_line = m_line.Slice( aStart, aEnd );
+
+ if( m_segmentRefs )
+ {
+ SEGMENT_REFS* snew = new SEGMENT_REFS( m_segmentRefs->begin() + aStart,
+ m_segmentRefs->begin() + aEnd );
+
+ delete m_segmentRefs;
+ m_segmentRefs = snew;
+ }
+}
+
+
+bool PNS_LINE::HasLoops() const
+{
+ for( int i = 0; i < PointCount(); i++ )
+ {
+ for( int j = 0; j < PointCount(); j++ )
+ {
+ if( ( std::abs( i - j ) > 1 ) && CPoint( i ) == CPoint( j ) )
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+void PNS_LINE::ClearSegmentLinks()
+{
+ if( m_segmentRefs )
+ delete m_segmentRefs;
+
+ m_segmentRefs = NULL;
+}
+
+
+static void extendBox( BOX2I& aBox, bool& aDefined, const VECTOR2I& aP )
+{
+ if( aDefined )
+ aBox.Merge ( aP );
+ else {
+ aBox = BOX2I( aP, VECTOR2I( 0, 0 ) );
+ aDefined = true;
+ }
+}
+
+
+OPT_BOX2I PNS_LINE::ChangedArea( const PNS_LINE* aOther ) const
+{
+ BOX2I area;
+ bool areaDefined = false;
+
+ int i_start = -1;
+ int i_end_self = -1, i_end_other = -1;
+
+ SHAPE_LINE_CHAIN self( m_line );
+ self.Simplify();
+ SHAPE_LINE_CHAIN other( aOther->m_line );
+ other.Simplify();
+
+ int np_self = self.PointCount();
+ int np_other = other.PointCount();
+
+ int n = std::min( np_self, np_other );
+
+ for( int i = 0; i < n; i++ )
+ {
+ const VECTOR2I p1 = self.CPoint( i );
+ const VECTOR2I p2 = other.CPoint( i );
+
+ if( p1 != p2 )
+ {
+ if( i != n - 1 )
+ {
+ SEG s = self.CSegment( i );
+
+ if( !s.Contains( p2 ) )
+ {
+ i_start = i;
+ break;
+ }
+ } else {
+ i_start = i;
+ break;
+ }
+ }
+ }
+
+ for( int i = 0; i < n; i++ )
+ {
+ const VECTOR2I p1 = self.CPoint( np_self - 1 - i );
+ const VECTOR2I p2 = other.CPoint( np_other - 1 - i );
+
+ if( p1 != p2 )
+ {
+ i_end_self = np_self - 1 - i;
+ i_end_other = np_other - 1 - i;
+ break;
+ }
+ }
+
+ if( i_start < 0 )
+ i_start = n;
+
+ if( i_end_self < 0 )
+ i_end_self = np_self - 1;
+
+ if( i_end_other < 0 )
+ i_end_other = np_other - 1;
+
+ for( int i = i_start; i <= i_end_self; i++ )
+ extendBox( area, areaDefined, self.CPoint( i ) );
+
+ for( int i = i_start; i <= i_end_other; i++ )
+ extendBox( area, areaDefined, other.CPoint( i ) );
+
+ if( areaDefined )
+ {
+ area.Inflate( std::max( Width(), aOther->Width() ) );
+ return area;
+ }
+
+ return OPT_BOX2I();
+}
diff --git a/pcbnew/router/pns_line.h b/pcbnew/router/pns_line.h
new file mode 100644
index 0000000..32c0a71
--- /dev/null
+++ b/pcbnew/router/pns_line.h
@@ -0,0 +1,299 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_LINE_H
+#define __PNS_LINE_H
+
+#include <math/vector2d.h>
+
+#include <geometry/seg.h>
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+
+#include "direction.h"
+#include "pns_item.h"
+#include "pns_via.h"
+
+class PNS_NODE;
+class PNS_SEGMENT;
+class PNS_VIA;
+
+/**
+ * Class PNS_LINE
+ *
+ * Represents a track on a PCB, connecting two non-trivial joints (that is,
+ * vias, pads, junctions between multiple traces or two traces different widths
+ * and combinations of these). PNS_LINEs are NOT stored in the model (PNS_NODE).
+ * Instead, they are assembled on-the-fly, based on a via/pad/segment that
+ * belongs to/starts/ends them.
+ *
+ * PNS_LINEs can be either loose (consisting of segments that do not belong to
+ * any PNS_NODE) or owned (with segments taken from a PNS_NODE) - these are
+ * returned by PNS_NODE::AssembleLine and friends.
+ *
+ * A PNS_LINE may have a PNS_VIA attached at its end (i.e. the last point) - this is used by via
+ * dragging/force propagation stuff.
+ */
+
+#define PNS_HULL_MARGIN 10
+
+class PNS_LINE : public PNS_ITEM
+{
+public:
+ typedef std::vector<PNS_SEGMENT*> SEGMENT_REFS;
+
+ /**
+ * Constructor
+ * Makes an empty line.
+ */
+ PNS_LINE() : PNS_ITEM( LINE )
+ {
+ m_segmentRefs = NULL;
+ m_hasVia = false;
+ m_width = 1; // Dummy value
+ }
+
+ PNS_LINE( const PNS_LINE& aOther );
+
+ /**
+ * Constructor
+ * Copies properties (net, layers, etc.) from a base line and replaces the shape
+ * by another
+ **/
+ PNS_LINE( const PNS_LINE& aBase, const SHAPE_LINE_CHAIN& aLine ) :
+ PNS_ITEM( aBase ),
+ m_line( aLine ),
+ m_width( aBase.m_width )
+ {
+ m_net = aBase.m_net;
+ m_layers = aBase.m_layers;
+ m_segmentRefs = NULL;
+ m_hasVia = false;
+ }
+
+ ~PNS_LINE();
+
+ static inline bool ClassOf( const PNS_ITEM* aItem )
+ {
+ return aItem && LINE == aItem->Kind();
+ }
+
+ /// @copydoc PNS_ITEM::Clone()
+ virtual PNS_LINE* Clone() const;
+
+ const PNS_LINE& operator=( const PNS_LINE& aOther );
+
+ ///> Assigns a shape to the line (a polyline/line chain)
+ void SetShape( const SHAPE_LINE_CHAIN& aLine )
+ {
+ m_line = aLine;
+ }
+
+ ///> Returns the shape of the line
+ const SHAPE* Shape() const
+ {
+ return &m_line;
+ }
+
+ ///> Modifiable accessor to the underlying shape
+ SHAPE_LINE_CHAIN& Line()
+ {
+ return m_line;
+ }
+
+ ///> Const accessor to the underlying shape
+ const SHAPE_LINE_CHAIN& CLine() const
+ {
+ return m_line;
+ }
+
+ ///> Returns the number of segments in the line
+ int SegmentCount() const
+ {
+ return m_line.SegmentCount();
+ }
+
+ ///> Returns the number of points in the line
+ int PointCount() const
+ {
+ return m_line.PointCount();
+ }
+
+ ///> Returns the aIdx-th point of the line
+ const VECTOR2I& CPoint( int aIdx ) const
+ {
+ return m_line.CPoint( aIdx );
+ }
+
+ ///> Returns the aIdx-th segment of the line
+ const SEG CSegment( int aIdx ) const
+ {
+ return m_line.CSegment( aIdx );
+ }
+
+ ///> Sets line width
+ void SetWidth( int aWidth )
+ {
+ m_width = aWidth;
+ }
+
+ ///> Returns line width
+ int Width() const
+ {
+ return m_width;
+ }
+
+ ///> Returns true if the line is geometrically identical as line aOther
+ bool CompareGeometry( const PNS_LINE& aOther );
+
+ ///> Reverses the point/vertex order
+ void Reverse();
+
+
+ /* Linking functions */
+
+ ///> Adds a reference to a segment registered in a PNS_NODE that is a part of this line.
+ void LinkSegment( PNS_SEGMENT* aSeg )
+ {
+ if( !m_segmentRefs )
+ m_segmentRefs = new SEGMENT_REFS();
+
+ m_segmentRefs->push_back( aSeg );
+ }
+
+ ///> Returns the list of segments from the owning node that constitute this
+ ///> line (or NULL if the line is not linked)
+ SEGMENT_REFS* LinkedSegments()
+ {
+ return m_segmentRefs;
+ }
+
+ bool IsLinked() const
+ {
+ return m_segmentRefs != NULL;
+ }
+
+ ///> Checks if the segment aSeg is a part of the line.
+ bool ContainsSegment( PNS_SEGMENT* aSeg ) const
+ {
+ if( !m_segmentRefs )
+ return false;
+
+ return std::find( m_segmentRefs->begin(), m_segmentRefs->end(),
+ aSeg ) != m_segmentRefs->end();
+ }
+
+ PNS_SEGMENT* GetLink( int aIndex ) const
+ {
+ return (*m_segmentRefs)[aIndex];
+ }
+
+ ///> Erases the linking information. Used to detach the line from the owning node.
+ void ClearSegmentLinks();
+
+ ///> Returns the number of segments that were assembled together to form this line.
+ int LinkCount() const
+ {
+ if( !m_segmentRefs )
+ return -1;
+
+ return m_segmentRefs->size();
+ }
+
+ ///> Clips the line to the nearest obstacle, traversing from the line's start vertex (0).
+ ///> Returns the clipped line.
+ const PNS_LINE ClipToNearestObstacle( PNS_NODE* aNode ) const;
+
+ ///> Clips the line to a given range of vertices.
+ void ClipVertexRange ( int aStart, int aEnd );
+
+ ///> Returns the number of corners of angles specified by mask aAngles.
+ int CountCorners( int aAngles );
+
+ ///> Calculates a line thightly wrapping a convex hull
+ ///> of an obstacle object (aObstacle).
+ ///> aPrePath = path from origin to the obstacle
+ ///> aWalkaroundPath = path around the obstacle
+ ///> aPostPath = past from obstacle till the end
+ ///> aCW = whether to walk around in clockwise or counter-clockwise direction.
+ bool Walkaround( SHAPE_LINE_CHAIN aObstacle,
+ SHAPE_LINE_CHAIN& aPre,
+ SHAPE_LINE_CHAIN& aWalk,
+ SHAPE_LINE_CHAIN& aPost,
+ bool aCw ) const;
+
+ void Walkaround( const SHAPE_LINE_CHAIN& aObstacle,
+ SHAPE_LINE_CHAIN& aPath,
+ bool aCw ) const;
+
+ bool Is45Degree();
+
+ ///> Prints out all linked segments
+ void ShowLinks();
+
+ bool EndsWithVia() const { return m_hasVia; }
+
+ void AppendVia( const PNS_VIA& aVia );
+ void RemoveVia() { m_hasVia = false; }
+
+ const PNS_VIA& Via() const { return m_via; }
+
+ virtual void Mark( int aMarker );
+ virtual void Unmark ();
+ virtual int Marker() const;
+
+ void DragSegment( const VECTOR2I& aP, int aIndex, int aSnappingThreshold = 0 );
+ void DragCorner( const VECTOR2I& aP, int aIndex, int aSnappingThreshold = 0 );
+
+ void SetRank( int aRank );
+ int Rank() const;
+
+ bool HasLoops() const;
+
+ OPT_BOX2I ChangedArea( const PNS_LINE* aOther ) const;
+
+private:
+ VECTOR2I snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP,
+ int aIndex, int aThreshold) const;
+
+ VECTOR2I snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP,
+ int aIndex, int aThreshold ) const;
+
+ ///> Copies m_segmentRefs from the line aParent.
+ void copyLinks( const PNS_LINE* aParent ) ;
+
+ ///> List of segments in the owning PNS_NODE (PNS_ITEM::m_owner) that constitute this line, or NULL
+ ///> if the line is not a part of any node.
+ SEGMENT_REFS* m_segmentRefs;
+
+ ///> The actual shape of the line
+ SHAPE_LINE_CHAIN m_line;
+
+ ///> our width
+ int m_width;
+
+ ///> If true, the line ends with a via
+ bool m_hasVia;
+
+ ///> Via at the end point, if m_hasVia == true
+ PNS_VIA m_via;
+};
+
+#endif // __PNS_LINE_H
diff --git a/pcbnew/router/pns_line_placer.cpp b/pcbnew/router/pns_line_placer.cpp
new file mode 100644
index 0000000..7f4efb4
--- /dev/null
+++ b/pcbnew/router/pns_line_placer.cpp
@@ -0,0 +1,1112 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+#include <boost/optional.hpp>
+
+#include <colors.h>
+
+#include "trace.h"
+
+#include "pns_node.h"
+#include "pns_line_placer.h"
+#include "pns_walkaround.h"
+#include "pns_shove.h"
+#include "pns_utils.h"
+#include "pns_router.h"
+#include "pns_topology.h"
+
+#include <class_board_item.h>
+
+using boost::optional;
+
+PNS_LINE_PLACER::PNS_LINE_PLACER( PNS_ROUTER* aRouter ) :
+ PNS_PLACEMENT_ALGO( aRouter )
+{
+ m_initial_direction = DIRECTION_45::N;
+ m_world = NULL;
+ m_shove = NULL;
+ m_currentNode = NULL;
+ m_idle = true;
+
+ // Init temporary variables (do not leave uninitialized members)
+ m_lastNode = NULL;
+ m_placingVia = false;
+ m_currentNet = 0;
+ m_currentLayer = 0;
+ m_currentMode = RM_MarkObstacles;
+ m_startItem = NULL;
+ m_chainedPlacement = false;
+ m_splitSeg = false;
+ m_orthoMode = false;
+}
+
+
+PNS_LINE_PLACER::~PNS_LINE_PLACER()
+{
+ if( m_shove )
+ delete m_shove;
+}
+
+
+void PNS_LINE_PLACER::setWorld( PNS_NODE* aWorld )
+{
+ m_world = aWorld;
+}
+
+
+const PNS_VIA PNS_LINE_PLACER::makeVia( const VECTOR2I& aP )
+{
+ const PNS_LAYERSET layers( m_sizes.GetLayerTop(), m_sizes.GetLayerBottom() );
+
+ return PNS_VIA( aP, layers, m_sizes.ViaDiameter(), m_sizes.ViaDrill(), -1, m_sizes.ViaType() );
+}
+
+
+bool PNS_LINE_PLACER::ToggleVia( bool aEnabled )
+{
+ m_placingVia = aEnabled;
+
+ if( !aEnabled )
+ m_head.RemoveVia();
+
+ return true;
+}
+
+
+void PNS_LINE_PLACER::setInitialDirection( const DIRECTION_45& aDirection )
+{
+ m_initial_direction = aDirection;
+
+ if( m_tail.SegmentCount() == 0 )
+ m_direction = aDirection;
+}
+
+
+bool PNS_LINE_PLACER::handleSelfIntersections()
+{
+ SHAPE_LINE_CHAIN::INTERSECTIONS ips;
+ SHAPE_LINE_CHAIN& head = m_head.Line();
+ SHAPE_LINE_CHAIN& tail = m_tail.Line();
+
+ // if there is no tail, there is nothing to intersect with
+ if( tail.PointCount() < 2 )
+ return false;
+
+ tail.Intersect( head, ips );
+
+ // no intesection points - nothing to reduce
+ if( ips.empty() )
+ return false;
+
+ int n = INT_MAX;
+ VECTOR2I ipoint;
+
+ // if there is more than one intersection, find the one that is
+ // closest to the beginning of the tail.
+ BOOST_FOREACH( SHAPE_LINE_CHAIN::INTERSECTION i, ips )
+ {
+ if( i.our.Index() < n )
+ {
+ n = i.our.Index();
+ ipoint = i.p;
+ }
+ }
+
+ // ignore the point where head and tail meet
+ if( ipoint == head.CPoint( 0 ) || ipoint == tail.CPoint( -1 ) )
+ return false;
+
+ // Intersection point is on the first or the second segment: just start routing
+ // from the beginning
+ if( n < 2 )
+ {
+ m_p_start = tail.Point( 0 );
+ m_direction = m_initial_direction;
+ tail.Clear();
+ head.Clear();
+
+ return true;
+ }
+ else
+ {
+ // Clip till the last tail segment before intersection.
+ // Set the direction to the one of this segment.
+ const SEG last = tail.CSegment( n - 1 );
+ m_p_start = last.A;
+ m_direction = DIRECTION_45( last );
+ tail.Remove( n, -1 );
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PNS_LINE_PLACER::handlePullback()
+{
+ SHAPE_LINE_CHAIN& head = m_head.Line();
+ SHAPE_LINE_CHAIN& tail = m_tail.Line();
+
+ if( head.PointCount() < 2 )
+ return false;
+
+ int n = tail.PointCount();
+
+ if( n == 0 )
+ return false;
+ else if( n == 1 )
+ {
+ m_p_start = tail.CPoint( 0 );
+ tail.Clear();
+ return true;
+ }
+
+ DIRECTION_45 first_head( head.CSegment( 0 ) );
+ DIRECTION_45 last_tail( tail.CSegment( -1 ) );
+ DIRECTION_45::AngleType angle = first_head.Angle( last_tail );
+
+ // case 1: we have a defined routing direction, and the currently computed
+ // head goes in different one.
+ bool pullback_1 = false; // (m_direction != DIRECTION_45::UNDEFINED && m_direction != first_head);
+
+ // case 2: regardless of the current routing direction, if the tail/head
+ // extremities form an acute or right angle, reduce the tail by one segment
+ // (and hope that further iterations) will result with a cleaner trace
+ bool pullback_2 = ( angle == DIRECTION_45::ANG_RIGHT || angle == DIRECTION_45::ANG_ACUTE );
+
+ if( pullback_1 || pullback_2 )
+ {
+ const SEG last = tail.CSegment( -1 );
+ m_direction = DIRECTION_45( last );
+ m_p_start = last.A;
+
+ TRACE( 0, "Placer: pullback triggered [%d] [%s %s]",
+ n % last_tail.Format().c_str() % first_head.Format().c_str() );
+
+ // erase the last point in the tail, hoping that the next iteration will
+ // result with a head trace that starts with a segment following our
+ // current direction.
+ if( n < 2 )
+ tail.Clear(); // don't leave a single-point tail
+ else
+ tail.Remove( -1, -1 );
+
+ if( !tail.SegmentCount() )
+ m_direction = m_initial_direction;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PNS_LINE_PLACER::reduceTail( const VECTOR2I& aEnd )
+{
+ SHAPE_LINE_CHAIN& head = m_head.Line();
+ SHAPE_LINE_CHAIN& tail = m_tail.Line();
+
+ int n = tail.SegmentCount();
+
+ if( head.SegmentCount() < 1 )
+ return false;
+
+ // Don't attempt this for too short tails
+ if( n < 2 )
+ return false;
+
+ // Start from the segment farthest from the end of the tail
+ // int start_index = std::max(n - 1 - ReductionDepth, 0);
+
+ DIRECTION_45 new_direction;
+ VECTOR2I new_start;
+ int reduce_index = -1;
+
+ for( int i = tail.SegmentCount() - 1; i >= 0; i-- )
+ {
+ const SEG s = tail.CSegment( i );
+ DIRECTION_45 dir( s );
+
+ // calculate a replacement route and check if it matches
+ // the direction of the segment to be replaced
+ SHAPE_LINE_CHAIN replacement = dir.BuildInitialTrace( s.A, aEnd );
+
+ PNS_LINE tmp( m_tail, replacement );
+
+ if( m_currentNode->CheckColliding( &tmp, PNS_ITEM::ANY ) )
+ break;
+
+ if( DIRECTION_45( replacement.CSegment( 0 ) ) == dir )
+ {
+ new_start = s.A;
+ new_direction = dir;
+ reduce_index = i;
+ }
+ }
+
+ if( reduce_index >= 0 )
+ {
+ TRACE( 0, "Placer: reducing tail: %d", reduce_index );
+ SHAPE_LINE_CHAIN reducedLine = new_direction.BuildInitialTrace( new_start, aEnd );
+
+ m_p_start = new_start;
+ m_direction = new_direction;
+ tail.Remove( reduce_index + 1, -1 );
+ head.Clear();
+ return true;
+ }
+
+ if( !tail.SegmentCount() )
+ m_direction = m_initial_direction;
+
+ return false;
+}
+
+
+bool PNS_LINE_PLACER::checkObtusity( const SEG& aA, const SEG& aB ) const
+{
+ const DIRECTION_45 dir_a( aA );
+ const DIRECTION_45 dir_b( aB );
+
+ return dir_a.IsObtuse( dir_b ) || dir_a == dir_b;
+}
+
+
+bool PNS_LINE_PLACER::mergeHead()
+{
+ SHAPE_LINE_CHAIN& head = m_head.Line();
+ SHAPE_LINE_CHAIN& tail = m_tail.Line();
+
+ const int ForbiddenAngles = DIRECTION_45::ANG_ACUTE |
+ DIRECTION_45::ANG_HALF_FULL |
+ DIRECTION_45::ANG_UNDEFINED;
+
+ head.Simplify();
+ tail.Simplify();
+
+ int n_head = head.SegmentCount();
+ int n_tail = tail.SegmentCount();
+
+ if( n_head < 3 )
+ {
+ TRACEn( 4, "Merge failed: not enough head segs." );
+ return false;
+ }
+
+ if( n_tail && head.CPoint( 0 ) != tail.CPoint( -1 ) )
+ {
+ TRACEn( 4, "Merge failed: head and tail discontinuous." );
+ return false;
+ }
+
+ if( m_head.CountCorners( ForbiddenAngles ) != 0 )
+ return false;
+
+ DIRECTION_45 dir_tail, dir_head;
+
+ dir_head = DIRECTION_45( head.CSegment( 0 ) );
+
+ if( n_tail )
+ {
+ dir_tail = DIRECTION_45( tail.CSegment( -1 ) );
+
+ if( dir_head.Angle( dir_tail ) & ForbiddenAngles )
+ return false;
+ }
+
+ if( !n_tail )
+ tail.Append( head.CSegment( 0 ).A );
+
+ for( int i = 0; i < n_head - 2; i++ )
+ {
+ tail.Append( head.CSegment( i ).B );
+ }
+
+ tail.Simplify();
+
+ SEG last = tail.CSegment( -1 );
+
+ m_p_start = last.B;
+ m_direction = DIRECTION_45( last ).Right();
+
+ head.Remove( 0, n_head - 2 );
+
+ TRACE( 0, "Placer: merge %d, new direction: %s", n_head % m_direction.Format().c_str() );
+
+ head.Simplify();
+ tail.Simplify();
+
+ return true;
+}
+
+
+bool PNS_LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead )
+{
+ PNS_LINE initTrack( m_head );
+ PNS_LINE walkFull;
+ int effort = 0;
+ bool rv = true, viaOk;
+
+ viaOk = buildInitialLine( aP, initTrack );
+
+ PNS_WALKAROUND walkaround( m_currentNode, Router() );
+
+ walkaround.SetSolidsOnly( false );
+ walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
+
+ PNS_WALKAROUND::WALKAROUND_STATUS wf = walkaround.Route( initTrack, walkFull, false );
+
+ switch( Settings().OptimizerEffort() )
+ {
+ case OE_LOW:
+ effort = 0;
+ break;
+
+ case OE_MEDIUM:
+ case OE_FULL:
+ effort = PNS_OPTIMIZER::MERGE_SEGMENTS;
+ break;
+ }
+
+ if( Settings().SmartPads() )
+ effort |= PNS_OPTIMIZER::SMART_PADS;
+
+ if( wf == PNS_WALKAROUND::STUCK )
+ {
+ walkFull = walkFull.ClipToNearestObstacle( m_currentNode );
+ rv = true;
+ }
+ else if( m_placingVia && viaOk )
+ {
+ walkFull.AppendVia( makeVia( walkFull.CPoint( -1 ) ) );
+ }
+
+ PNS_OPTIMIZER::Optimize( &walkFull, effort, m_currentNode );
+
+ if( m_currentNode->CheckColliding( &walkFull ) )
+ {
+ aNewHead = m_head;
+ return false;
+ }
+
+ m_head = walkFull;
+ aNewHead = walkFull;
+
+ return rv;
+}
+
+
+bool PNS_LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead )
+{
+ buildInitialLine( aP, m_head );
+ aNewHead = m_head;
+ return static_cast<bool>( m_currentNode->CheckColliding( &m_head ) );
+}
+
+
+bool PNS_LINE_PLACER::rhShoveOnly( const VECTOR2I& aP, PNS_LINE& aNewHead )
+{
+ PNS_LINE initTrack( m_head );
+ PNS_LINE walkSolids, l2;
+
+ bool viaOk = buildInitialLine( aP, initTrack );
+
+ m_currentNode = m_shove->CurrentNode();
+ PNS_OPTIMIZER optimizer( m_currentNode );
+
+ PNS_WALKAROUND walkaround( m_currentNode, Router() );
+
+ walkaround.SetSolidsOnly( true );
+ walkaround.SetIterationLimit( 10 );
+ PNS_WALKAROUND::WALKAROUND_STATUS stat_solids = walkaround.Route( initTrack, walkSolids );
+
+ optimizer.SetEffortLevel( PNS_OPTIMIZER::MERGE_SEGMENTS );
+ optimizer.SetCollisionMask ( PNS_ITEM::SOLID );
+ optimizer.Optimize( &walkSolids );
+
+ if( stat_solids == PNS_WALKAROUND::DONE )
+ l2 = walkSolids;
+ else
+ l2 = initTrack.ClipToNearestObstacle( m_shove->CurrentNode() );
+
+ PNS_LINE l( m_tail );
+ l.Line().Append( l2.CLine() );
+ l.Line().Simplify();
+
+ if( l.PointCount() == 0 || l2.PointCount() == 0 )
+ {
+ aNewHead = m_head;
+ return false;
+ }
+
+ if( m_placingVia && viaOk )
+ {
+ PNS_VIA v1( makeVia( l.CPoint( -1 ) ) );
+ PNS_VIA v2( makeVia( l2.CPoint( -1 ) ) );
+
+ l.AppendVia( v1 );
+ l2.AppendVia( v2 );
+ }
+
+ l.Line().Simplify();
+
+ // in certain, uncommon cases there may be loops in the head+tail, In such case, we don't shove to avoid
+ // screwing up the database.
+ if( l.HasLoops() )
+ {
+ aNewHead = m_head;
+ return false;
+ }
+
+ PNS_SHOVE::SHOVE_STATUS status = m_shove->ShoveLines( l );
+
+ m_currentNode = m_shove->CurrentNode();
+
+ if( status == PNS_SHOVE::SH_OK || status == PNS_SHOVE::SH_HEAD_MODIFIED )
+ {
+ if( status == PNS_SHOVE::SH_HEAD_MODIFIED )
+ {
+ l2 = m_shove->NewHead();
+ }
+
+ optimizer.SetWorld( m_currentNode );
+ optimizer.SetEffortLevel( PNS_OPTIMIZER::MERGE_OBTUSE | PNS_OPTIMIZER::SMART_PADS );
+ optimizer.SetCollisionMask( PNS_ITEM::ANY );
+ optimizer.Optimize( &l2 );
+
+ aNewHead = l2;
+
+ return true;
+ }
+ else
+ {
+ walkaround.SetWorld( m_currentNode );
+ walkaround.SetSolidsOnly( false );
+ walkaround.SetIterationLimit( 10 );
+ walkaround.SetApproachCursor( true, aP );
+ walkaround.Route( initTrack, l2 );
+ aNewHead = l2.ClipToNearestObstacle( m_shove->CurrentNode() );
+
+ return false;
+ }
+
+ return false;
+}
+
+
+bool PNS_LINE_PLACER::routeHead( const VECTOR2I& aP, PNS_LINE& aNewHead )
+{
+ switch( m_currentMode )
+ {
+ case RM_MarkObstacles:
+ return rhMarkObstacles( aP, aNewHead );
+ case RM_Walkaround:
+ return rhWalkOnly( aP, aNewHead );
+ case RM_Shove:
+ return rhShoveOnly( aP, aNewHead );
+ default:
+ break;
+ }
+
+ return false;
+}
+
+
+bool PNS_LINE_PLACER::optimizeTailHeadTransition()
+{
+ PNS_LINE tmp = Trace();
+
+ if( PNS_OPTIMIZER::Optimize( &tmp, PNS_OPTIMIZER::FANOUT_CLEANUP, m_currentNode ) )
+ {
+ if( tmp.SegmentCount() < 1 )
+ return false;
+
+ m_head = tmp;
+ m_p_start = tmp.CLine().CPoint( 0 );
+ m_direction = DIRECTION_45( tmp.CSegment( 0 ) );
+ m_tail.Line().Clear();
+
+ return true;
+ }
+
+ SHAPE_LINE_CHAIN& head = m_head.Line();
+ SHAPE_LINE_CHAIN& tail = m_tail.Line();
+
+ int tailLookbackSegments = 3;
+
+ //if(m_currentMode() == RM_Walkaround)
+ // tailLookbackSegments = 10000;
+
+ int threshold = std::min( tail.PointCount(), tailLookbackSegments + 1 );
+
+ if( tail.SegmentCount() < 3 )
+ return false;
+
+ // assemble TailLookbackSegments tail segments with the current head
+ SHAPE_LINE_CHAIN opt_line = tail.Slice( -threshold, -1 );
+
+ int end = std::min(2, head.PointCount() - 1 );
+
+ opt_line.Append( head.Slice( 0, end ) );
+
+ PNS_LINE new_head( m_tail, opt_line );
+
+ // and see if it could be made simpler by merging obtuse/collnear segments.
+ // If so, replace the (threshold) last tail points and the head with
+ // the optimized line
+
+ if( PNS_OPTIMIZER::Optimize( &new_head, PNS_OPTIMIZER::MERGE_OBTUSE, m_currentNode ) )
+ {
+ PNS_LINE tmp( m_tail, opt_line );
+
+ TRACE( 0, "Placer: optimize tail-head [%d]", threshold );
+
+ head.Clear();
+ tail.Replace( -threshold, -1, new_head.CLine() );
+ tail.Simplify();
+
+ m_p_start = new_head.CLine().CPoint( -1 );
+ m_direction = DIRECTION_45( new_head.CSegment( -1 ) );
+
+ return true;
+ }
+
+ return false;
+}
+
+
+void PNS_LINE_PLACER::routeStep( const VECTOR2I& aP )
+{
+ bool fail = false;
+ bool go_back = false;
+
+ int i, n_iter = 1;
+
+ PNS_LINE new_head;
+
+ TRACE( 2, "INIT-DIR: %s head: %d, tail: %d segs\n",
+ m_initial_direction.Format().c_str() % m_head.SegmentCount() %
+ m_tail.SegmentCount() );
+
+ for( i = 0; i < n_iter; i++ )
+ {
+ if( !go_back && Settings().FollowMouse() )
+ reduceTail( aP );
+
+ go_back = false;
+
+ if( !routeHead( aP, new_head ) )
+ fail = true;
+
+ if( !new_head.Is45Degree() )
+ fail = true;
+
+ if( !Settings().FollowMouse() )
+ return;
+
+ m_head = new_head;
+
+ if( handleSelfIntersections() )
+ {
+ n_iter++;
+ go_back = true;
+ }
+
+ if( !go_back && handlePullback() )
+ {
+ n_iter++;
+ go_back = true;
+ }
+ }
+
+ if( !fail )
+ {
+ if( optimizeTailHeadTransition() )
+ return;
+
+ mergeHead();
+ }
+}
+
+
+bool PNS_LINE_PLACER::route( const VECTOR2I& aP )
+{
+ routeStep( aP );
+ return CurrentEnd() == aP;
+}
+
+
+const PNS_LINE PNS_LINE_PLACER::Trace() const
+{
+ PNS_LINE tmp( m_head );
+
+ tmp.SetShape( m_tail.CLine() );
+ tmp.Line().Append( m_head.CLine() );
+ tmp.Line().Simplify();
+ return tmp;
+}
+
+
+const PNS_ITEMSET PNS_LINE_PLACER::Traces()
+{
+ m_currentTrace = Trace();
+ return PNS_ITEMSET( &m_currentTrace );
+}
+
+
+void PNS_LINE_PLACER::FlipPosture()
+{
+ m_initial_direction = m_initial_direction.Right();
+ m_direction = m_direction.Right();
+}
+
+
+PNS_NODE* PNS_LINE_PLACER::CurrentNode( bool aLoopsRemoved ) const
+{
+ if( aLoopsRemoved && m_lastNode )
+ return m_lastNode;
+
+ return m_currentNode;
+}
+
+
+void PNS_LINE_PLACER::splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, const VECTOR2I& aP )
+{
+ if( aSeg && aSeg->OfKind( PNS_ITEM::SEGMENT ) )
+ {
+ PNS_JOINT* jt = aNode->FindJoint( aP, aSeg );
+
+ if( jt && jt->LinkCount() >= 1 )
+ return;
+
+ PNS_SEGMENT* s_old = static_cast<PNS_SEGMENT*>( aSeg );
+ PNS_SEGMENT* s_new[2];
+
+ s_new[0] = s_old->Clone();
+ s_new[1] = s_old->Clone();
+
+ s_new[0]->SetEnds( s_old->Seg().A, aP );
+ s_new[1]->SetEnds( aP, s_old->Seg().B );
+
+ aNode->Remove( s_old );
+ aNode->Add( s_new[0], true );
+ aNode->Add( s_new[1], true );
+ }
+}
+
+
+bool PNS_LINE_PLACER::SetLayer( int aLayer )
+{
+ if( m_idle )
+ {
+ m_currentLayer = aLayer;
+ return true;
+ }
+ else if( m_chainedPlacement )
+ {
+ return false;
+ }
+ else if( !m_startItem || ( m_startItem->OfKind( PNS_ITEM::VIA ) && m_startItem->Layers().Overlaps( aLayer ) ) ) {
+ m_currentLayer = aLayer;
+ m_splitSeg = false;
+ initPlacement ( m_splitSeg );
+ Move ( m_currentEnd, NULL );
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
+{
+ VECTOR2I p( aP );
+
+ static int unknowNetIdx = 0; // -10000;
+ int net = -1;
+
+ bool splitSeg = false;
+
+ if( Router()->SnappingEnabled() )
+ p = Router()->SnapToItem( aStartItem, aP, splitSeg );
+
+ if( !aStartItem || aStartItem->Net() < 0 )
+ net = unknowNetIdx--;
+ else
+ net = aStartItem->Net();
+
+ m_currentStart = p;
+ m_currentEnd = p;
+ m_currentNet = net;
+ m_startItem = aStartItem;
+ m_placingVia = false;
+ m_chainedPlacement = false;
+ m_splitSeg = splitSeg;
+
+ setInitialDirection( Settings().InitialDirection() );
+
+ initPlacement( m_splitSeg );
+ return true;
+}
+
+void PNS_LINE_PLACER::initPlacement( bool aSplitSeg )
+{
+ m_idle = false;
+
+ m_head.Line().Clear();
+ m_tail.Line().Clear();
+ m_head.SetNet( m_currentNet );
+ m_tail.SetNet( m_currentNet );
+ m_head.SetLayer( m_currentLayer );
+ m_tail.SetLayer( m_currentLayer );
+ m_head.SetWidth( m_sizes.TrackWidth() );
+ m_tail.SetWidth( m_sizes.TrackWidth() );
+ m_head.RemoveVia();
+ m_tail.RemoveVia();
+
+ m_p_start = m_currentStart;
+ m_direction = m_initial_direction;
+
+ PNS_NODE* world = Router()->GetWorld();
+
+ world->KillChildren();
+ PNS_NODE* rootNode = world->Branch();
+
+ if( aSplitSeg )
+ splitAdjacentSegments( rootNode, m_startItem, m_currentStart );
+
+ setWorld( rootNode );
+
+ TRACE( 1, "world %p, intitial-direction %s layer %d\n",
+ m_world % m_direction.Format().c_str() % aLayer );
+
+ m_lastNode = NULL;
+ m_currentNode = m_world;
+ m_currentMode = Settings().Mode();
+
+ if( m_shove )
+ delete m_shove;
+
+ m_shove = NULL;
+
+ if( m_currentMode == RM_Shove || m_currentMode == RM_Smart )
+ {
+ m_shove = new PNS_SHOVE( m_world->Branch(), Router() );
+ }
+}
+
+
+bool PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
+{
+ PNS_LINE current;
+ VECTOR2I p = aP;
+ int eiDepth = -1;
+
+ if( aEndItem && aEndItem->Owner() )
+ eiDepth = static_cast<PNS_NODE*>( aEndItem->Owner() )->Depth();
+
+ if( m_lastNode )
+ {
+ delete m_lastNode;
+ m_lastNode = NULL;
+ }
+
+ route( p );
+
+ current = Trace();
+
+ if( !current.PointCount() )
+ m_currentEnd = m_p_start;
+ else
+ m_currentEnd = current.CLine().CPoint( -1 );
+
+ PNS_NODE* latestNode = m_currentNode;
+ m_lastNode = latestNode->Branch();
+
+ if( eiDepth >= 0 && aEndItem && latestNode->Depth() > eiDepth && current.SegmentCount() )
+ {
+ splitAdjacentSegments( m_lastNode, aEndItem, current.CPoint( -1 ) );
+
+ if( Settings().RemoveLoops() )
+ removeLoops( m_lastNode, current );
+ }
+
+ updateLeadingRatLine();
+ return true;
+}
+
+
+bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
+{
+ bool realEnd = false;
+ int lastV;
+
+ PNS_LINE pl = Trace();
+
+ if( m_currentMode == RM_MarkObstacles &&
+ !Settings().CanViolateDRC() &&
+ m_world->CheckColliding( &pl ) )
+ return false;
+
+ const SHAPE_LINE_CHAIN& l = pl.CLine();
+
+ if( !l.SegmentCount() )
+ {
+ if( pl.EndsWithVia() )
+ {
+ m_lastNode->Add( pl.Via().Clone() );
+ Router()->CommitRouting( m_lastNode );
+
+ m_lastNode = NULL;
+ m_currentNode = NULL;
+
+ m_idle = true;
+ }
+
+ return true;
+ }
+
+ VECTOR2I p_pre_last = l.CPoint( -1 );
+ const VECTOR2I p_last = l.CPoint( -1 );
+ DIRECTION_45 d_last( l.CSegment( -1 ) );
+
+ if( l.PointCount() > 2 )
+ p_pre_last = l.CPoint( -2 );
+
+ if( aEndItem && m_currentNet >= 0 && m_currentNet == aEndItem->Net() )
+ realEnd = true;
+
+ if( realEnd || m_placingVia )
+ lastV = l.SegmentCount();
+ else
+ lastV = std::max( 1, l.SegmentCount() - 1 );
+
+ PNS_SEGMENT* lastSeg = NULL;
+
+ for( int i = 0; i < lastV; i++ )
+ {
+ const SEG& s = pl.CSegment( i );
+ PNS_SEGMENT* seg = new PNS_SEGMENT( s, m_currentNet );
+ seg->SetWidth( pl.Width() );
+ seg->SetLayer( m_currentLayer );
+ m_lastNode->Add( seg );
+ lastSeg = seg;
+ }
+
+ if( pl.EndsWithVia() )
+ m_lastNode->Add( pl.Via().Clone() );
+
+ if( realEnd )
+ simplifyNewLine( m_lastNode, lastSeg );
+
+ Router()->CommitRouting( m_lastNode );
+
+ m_lastNode = NULL;
+ m_currentNode = NULL;
+
+ if( !realEnd )
+ {
+ setInitialDirection( d_last );
+ m_currentStart = m_placingVia ? p_last : p_pre_last;
+ m_startItem = NULL;
+ m_placingVia = false;
+ m_chainedPlacement = !pl.EndsWithVia();
+ m_splitSeg = false;
+ initPlacement();
+ }
+ else
+ {
+ m_idle = true;
+ }
+
+ return realEnd;
+}
+
+
+void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE& aLatest )
+{
+ if( !aLatest.SegmentCount() )
+ return;
+
+ if( aLatest.CLine().CPoint( 0 ) == aLatest.CLine().CPoint( -1 ) )
+ return;
+
+ std::set<PNS_SEGMENT *> toErase;
+ aNode->Add( &aLatest, true );
+
+ for( int s = 0; s < aLatest.LinkCount(); s++ )
+ {
+ PNS_SEGMENT* seg = ( *aLatest.LinkedSegments() )[s];
+ PNS_LINE ourLine = aNode->AssembleLine( seg );
+ PNS_JOINT a, b;
+ std::vector<PNS_LINE> lines;
+
+ aNode->FindLineEnds( ourLine, a, b );
+
+ if( a == b )
+ {
+ aNode->FindLineEnds( aLatest, a, b );
+ }
+
+ aNode->FindLinesBetweenJoints( a, b, lines );
+
+ int removedCount = 0;
+ int total = 0;
+
+ BOOST_FOREACH( PNS_LINE& line, lines )
+ {
+ total++;
+
+ if( !( line.ContainsSegment( seg ) ) && line.SegmentCount() )
+ {
+ BOOST_FOREACH( PNS_SEGMENT *ss, *line.LinkedSegments() )
+ toErase.insert( ss );
+
+ removedCount++;
+ }
+ }
+
+ TRACE( 0, "total segs removed: %d/%d\n", removedCount % total );
+ }
+
+ BOOST_FOREACH( PNS_SEGMENT *s, toErase )
+ aNode->Remove( s );
+
+ aNode->Remove( &aLatest );
+}
+
+
+void PNS_LINE_PLACER::simplifyNewLine( PNS_NODE* aNode, PNS_SEGMENT* aLatest )
+{
+ PNS_LINE l = aNode->AssembleLine( aLatest );
+ SHAPE_LINE_CHAIN simplified( l.CLine() );
+
+ simplified.Simplify();
+
+ if( simplified.PointCount() != l.PointCount() )
+ {
+ PNS_LINE lnew( l );
+ aNode->Remove( &l );
+ lnew.SetShape( simplified );
+ aNode->Add( &lnew );
+ }
+}
+
+
+void PNS_LINE_PLACER::UpdateSizes( const PNS_SIZES_SETTINGS& aSizes )
+{
+ m_sizes = aSizes;
+
+ if( !m_idle )
+ {
+ initPlacement( m_splitSeg );
+ }
+}
+
+
+void PNS_LINE_PLACER::updateLeadingRatLine()
+{
+ PNS_LINE current = Trace();
+ SHAPE_LINE_CHAIN ratLine;
+ PNS_TOPOLOGY topo( m_lastNode );
+
+ if( topo.LeadingRatLine( &current, ratLine ) )
+ Router()->DisplayDebugLine( ratLine, 5, 10000 );
+}
+
+
+void PNS_LINE_PLACER::SetOrthoMode( bool aOrthoMode )
+{
+ m_orthoMode = aOrthoMode;
+}
+
+bool PNS_LINE_PLACER::buildInitialLine( const VECTOR2I& aP, PNS_LINE& aHead )
+{
+ SHAPE_LINE_CHAIN l;
+
+ if( m_p_start == aP )
+ {
+ l.Clear();
+ }
+ else
+ {
+ if( Settings().GetFreeAngleMode() && Settings().Mode() == RM_MarkObstacles )
+ {
+ l = SHAPE_LINE_CHAIN( m_p_start, aP );
+ }
+ else
+ {
+ l = m_direction.BuildInitialTrace( m_p_start, aP );
+ }
+
+ if( l.SegmentCount() > 1 && m_orthoMode )
+ {
+ VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) );
+
+ l.Remove( -1, -1 );
+ l.Point( 1 ) = newLast;
+ }
+ }
+
+ aHead.SetShape( l );
+
+ if( !m_placingVia )
+ return true;
+
+ PNS_VIA v( makeVia( aP ) );
+ v.SetNet( aHead.Net() );
+
+ if( m_currentMode == RM_MarkObstacles )
+ {
+ aHead.AppendVia( v );
+ return true;
+ }
+
+ VECTOR2I force;
+ VECTOR2I lead = aP - m_p_start;
+
+ bool solidsOnly = ( m_currentMode != RM_Walkaround );
+
+ if( v.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
+ {
+ SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace( m_p_start, aP + force );
+ aHead = PNS_LINE( aHead, line );
+
+ v.SetPos( v.Pos() + force );
+ return true;
+ }
+
+ return false; // via placement unsuccessful
+}
+
+
+void PNS_LINE_PLACER::GetModifiedNets( std::vector<int>& aNets ) const
+{
+ aNets.push_back( m_currentNet );
+}
+
+PNS_LOGGER* PNS_LINE_PLACER::Logger()
+{
+ if( m_shove )
+ return m_shove->Logger();
+
+ return NULL;
+}
diff --git a/pcbnew/router/pns_line_placer.h b/pcbnew/router/pns_line_placer.h
new file mode 100644
index 0000000..8a1f263
--- /dev/null
+++ b/pcbnew/router/pns_line_placer.h
@@ -0,0 +1,397 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_LINE_PLACER_H
+#define __PNS_LINE_PLACER_H
+
+#include <math/vector2d.h>
+
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+
+#include "pns_sizes_settings.h"
+#include "pns_node.h"
+#include "pns_via.h"
+#include "pns_line.h"
+#include "pns_placement_algo.h"
+
+class PNS_ROUTER;
+class PNS_SHOVE;
+class PNS_OPTIMIZER;
+class PNS_ROUTER_BASE;
+class PNS_VIA;
+class PNS_SIZES_SETTINGS;
+
+
+/**
+ * Class PNS_LINE_PLACER
+ *
+ * Single track placement algorithm. Interactively routes a track.
+ * Applies shove and walkaround algorithms when needed.
+ */
+
+class PNS_LINE_PLACER : public PNS_PLACEMENT_ALGO
+{
+public:
+ PNS_LINE_PLACER( PNS_ROUTER* aRouter );
+ ~PNS_LINE_PLACER();
+
+ /**
+ * Function Start()
+ *
+ * Starts routing a single track at point aP, taking item aStartItem as anchor
+ * (unless NULL).
+ */
+ bool Start( const VECTOR2I& aP, PNS_ITEM* aStartItem );
+
+ /**
+ * Function Move()
+ *
+ * Moves the end of the currently routed trace to the point aP, taking
+ * aEndItem as anchor (if not NULL).
+ * (unless NULL).
+ */
+ bool Move( const VECTOR2I& aP, PNS_ITEM* aEndItem );
+
+ /**
+ * Function FixRoute()
+ *
+ * Commits the currently routed track to the parent node, taking
+ * aP as the final end point and aEndItem as the final anchor (if provided).
+ * @return true, if route has been commited. May return false if the routing
+ * result is violating design rules - in such case, the track is only committed
+ * if Settings.CanViolateDRC() is on.
+ */
+ bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem );
+
+ /**
+ * Function ToggleVia()
+ *
+ * Enables/disables a via at the end of currently routed trace.
+ */
+ bool ToggleVia( bool aEnabled );
+
+ /**
+ * Function SetLayer()
+ *
+ * Sets the current routing layer.
+ */
+ bool SetLayer( int aLayer );
+
+ /**
+ * Function Head()
+ *
+ * Returns the "head" of the line being placed, that is the volatile part
+ * that has not "settled" yet.
+ */
+ const PNS_LINE& Head() const { return m_head; }
+
+ /**
+ * Function Tail()
+ *
+ * Returns the "tail" of the line being placed, the part which has already wrapped around
+ * and shoved some obstacles.
+ */
+ const PNS_LINE& Tail() const { return m_tail; }
+
+ /**
+ * Function Trace()
+ *
+ * Returns the complete routed line.
+ */
+ const PNS_LINE Trace() const;
+
+ /**
+ * Function Traces()
+ *
+ * Returns the complete routed line, as a single-member PNS_ITEMSET.
+ */
+ const PNS_ITEMSET Traces();
+
+ /**
+ * Function CurrentEnd()
+ *
+ * Returns the current end of the line being placed. It may not be equal
+ * to the cursor position due to collisions.
+ */
+ const VECTOR2I& CurrentEnd() const
+ {
+ return m_currentEnd;
+ }
+
+ /**
+ * Function CurrentNet()
+ *
+ * Returns the net code of currently routed track.
+ */
+ const std::vector<int> CurrentNets() const
+ {
+ return std::vector<int>( 1, m_currentNet );
+ }
+
+ /**
+ * Function CurrentLayer()
+ *
+ * Returns the layer of currently routed track.
+ */
+ int CurrentLayer() const
+ {
+ return m_currentLayer;
+ }
+
+ /**
+ * Function CurrentNode()
+ *
+ * Returns the most recent world state.
+ */
+ PNS_NODE* CurrentNode( bool aLoopsRemoved = false ) const;
+
+ /**
+ * Function FlipPosture()
+ *
+ * Toggles the current posture (straight/diagonal) of the trace head.
+ */
+ void FlipPosture();
+
+ /**
+ * Function UpdateSizes()
+ *
+ * Performs on-the-fly update of the width, via diameter & drill size from
+ * a settings class. Used to dynamically change these parameters as
+ * the track is routed.
+ */
+ void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes );
+
+ void SetOrthoMode( bool aOrthoMode );
+
+ bool IsPlacingVia() const { return m_placingVia; }
+
+ void GetModifiedNets( std::vector<int>& aNets ) const;
+
+ PNS_LOGGER* Logger();
+
+
+private:
+ /**
+ * Function route()
+ *
+ * Re-routes the current track to point aP. Returns true, when routing has
+ * completed successfully (i.e. the trace end has reached point aP), and false
+ * if the trace was stuck somewhere on the way. May call routeStep()
+ * repetitively due to mouse smoothing.
+ * @param aP ending point of current route.
+ * @return true, if the routing is complete.
+ */
+ bool route( const VECTOR2I& aP );
+
+ /**
+ * Function updateLeadingRatLine()
+ *
+ * Draws the "leading" ratsnest line, which connects the end of currently
+ * routed track and the nearest yet unrouted item. If the routing for
+ * current net is complete, draws nothing.
+ */
+ void updateLeadingRatLine();
+
+ /**
+ * Function setWorld()
+ *
+ * Sets the board to route.
+ */
+ void setWorld( PNS_NODE* aWorld );
+
+ /**
+ * Function startPlacement()
+ *
+ * Initializes placement of a new line with given parameters.
+ */
+ void initPlacement( bool aSplitSeg = false );
+
+ /**
+ * Function setInitialDirection()
+ *
+ * Sets preferred direction of the very first track segment to be laid.
+ * Used by posture switching mechanism.
+ */
+ void setInitialDirection( const DIRECTION_45& aDirection );
+
+ /**
+ * Function splitAdjacentSegments()
+ *
+ * Checks if point aP lies on segment aSeg. If so, splits the segment in two,
+ * forming a joint at aP and stores updated topology in node aNode.
+ */
+ void splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, const VECTOR2I& aP );
+
+ /**
+ * Function removeLoops()
+ *
+ * Searches aNode for traces concurrent to aLatest and removes them. Updated
+ * topology is stored in aNode.
+ */
+ void removeLoops( PNS_NODE* aNode, PNS_LINE& aLatest );
+
+ /**
+ * Function simplifyNewLine()
+ *
+ * Assembles a line starting from segment aLatest, removes collinear segments
+ * and redundant vertexes. If a simplification bhas been found, replaces the
+ * old line with the simplified one in aNode.
+ */
+ void simplifyNewLine( PNS_NODE* aNode, PNS_SEGMENT* aLatest );
+
+ /**
+ * Function checkObtusity()
+ *
+ * Helper function, checking if segments a and b form an obtuse angle
+ * (in 45-degree regime).
+ * @return true, if angle (aA, aB) is obtuse
+ */
+ bool checkObtusity( const SEG& aA, const SEG& aB ) const;
+
+ /**
+ * Function handleSelfIntersections()
+ *
+ * Checks if the head of the track intersects its tail. If so, cuts the
+ * tail up to the intersecting segment and fixes the head direction to match
+ * the last segment before the cut.
+ * @return true if the line has been changed.
+ */
+ bool handleSelfIntersections();
+
+ /**
+ * Function handlePullback()
+ *
+ * Deals with pull-back: reduces the tail if head trace is moved backwards
+ * wrs to the current tail direction.
+ * @return true if the line has been changed.
+ */
+ bool handlePullback();
+
+ /**
+ * Function mergeHead()
+ *
+ * Moves "estabished" segments from the head to the tail if certain
+ * conditions are met.
+ * @return true, if the line has been changed.
+ */
+ bool mergeHead();
+
+ /**
+ * Function reduceTail()
+ *
+ * Attempts to reduce the numer of segments in the tail by trying to replace a
+ * certain number of latest tail segments with a direct trace leading to aEnd
+ * that does not collide with anything.
+ * @param aEnd: current routing destination point.
+ * @return true if the line has been changed.
+ */
+ bool reduceTail( const VECTOR2I& aEnd );
+
+ /**
+ * Function optimizeTailHeadTransition()
+ *
+ * Tries to reduce the corner count of the most recent part of tail/head by
+ * merging obtuse/collinear segments.
+ * @return true, if the line has been changed.
+ */
+ bool optimizeTailHeadTransition();
+
+ /**
+ * Function routeHead()
+ *
+ * Computes the head trace between the current start point (m_p_start) and
+ * point aP, starting with direction defined in m_direction. The trace walks
+ * around all colliding solid or non-movable items. Movable segments are
+ * ignored, as they'll be handled later by the shove algorithm.
+ */
+ bool routeHead( const VECTOR2I& aP, PNS_LINE& aNewHead);
+
+ /**
+ * Function routeStep()
+ *
+ * Performs a single routing alorithm step, for the end point aP.
+ * @param aP ending point of current route
+ * @return true, if the line has been changed.
+ */
+ void routeStep( const VECTOR2I& aP );
+
+ ///> route step, walkaround mode
+ bool rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead);
+
+ ///> route step, shove mode
+ bool rhShoveOnly( const VECTOR2I& aP, PNS_LINE& aNewHead);
+
+ ///> route step, mark obstacles mode
+ bool rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead );
+
+ const PNS_VIA makeVia ( const VECTOR2I& aP );
+
+ bool buildInitialLine( const VECTOR2I& aP, PNS_LINE& aHead );
+
+ ///> current routing direction
+ DIRECTION_45 m_direction;
+
+ ///> routing direction for new traces
+ DIRECTION_45 m_initial_direction;
+
+ ///> routing "head": volatile part of the track from the previously
+ /// analyzed point to the current routing destination
+ PNS_LINE m_head;
+
+ ///> routing "tail": part of the track that has been already fixed due to collisions with obstacles
+ PNS_LINE m_tail;
+
+ ///> pointer to world to search colliding items
+ PNS_NODE* m_world;
+
+ ///> current routing start point (end of tail, beginning of head)
+ VECTOR2I m_p_start;
+
+ ///> The shove engine
+ PNS_SHOVE* m_shove;
+
+ ///> Current world state
+ PNS_NODE* m_currentNode;
+
+ ///> Postprocessed world state (including marked collisions & removed loops)
+ PNS_NODE* m_lastNode;
+
+ PNS_SIZES_SETTINGS m_sizes;
+
+ ///> Are we placing a via?
+ bool m_placingVia;
+
+ int m_currentNet;
+ int m_currentLayer;
+
+ VECTOR2I m_currentEnd, m_currentStart;
+ PNS_LINE m_currentTrace;
+
+ PNS_MODE m_currentMode;
+ PNS_ITEM* m_startItem;
+
+ bool m_idle;
+ bool m_chainedPlacement;
+ bool m_splitSeg;
+ bool m_orthoMode;
+};
+
+#endif // __PNS_LINE_PLACER_H
diff --git a/pcbnew/router/pns_logger.cpp b/pcbnew/router/pns_logger.cpp
new file mode 100644
index 0000000..69c725f
--- /dev/null
+++ b/pcbnew/router/pns_logger.cpp
@@ -0,0 +1,203 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pns_logger.h"
+#include "pns_item.h"
+#include "pns_via.h"
+#include "pns_line.h"
+#include "pns_segment.h"
+#include "pns_solid.h"
+
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+#include <geometry/shape_rect.h>
+#include <geometry/shape_circle.h>
+#include <geometry/shape_convex.h>
+
+PNS_LOGGER::PNS_LOGGER( )
+{
+ m_groupOpened = false;
+}
+
+
+PNS_LOGGER::~PNS_LOGGER()
+{
+}
+
+
+void PNS_LOGGER::Clear()
+{
+ m_theLog.str( std::string() );
+ m_groupOpened = false;
+}
+
+
+void PNS_LOGGER::NewGroup( const std::string& aName, int aIter )
+{
+ if( m_groupOpened )
+ m_theLog << "endgroup" << std::endl;
+
+ m_theLog << "group " << aName << " " << aIter << std::endl;
+ m_groupOpened = true;
+}
+
+
+void PNS_LOGGER::EndGroup()
+{
+ if( !m_groupOpened )
+ return;
+
+ m_groupOpened = false;
+ m_theLog << "endgroup" << std::endl;
+}
+
+
+void PNS_LOGGER::Log ( const PNS_ITEM* aItem, int aKind, const std::string aName )
+{
+ m_theLog << "item " << aKind << " " << aName << " ";
+ m_theLog << aItem->Net() << " " << aItem->Layers().Start() << " " <<
+ aItem->Layers().End() << " " << aItem->Marker() << " " << aItem->Rank();
+
+ switch( aItem->Kind() )
+ {
+ case PNS_ITEM::LINE:
+ {
+ PNS_LINE* l = (PNS_LINE*) aItem;
+ m_theLog << " line ";
+ m_theLog << l->Width() << " " << ( l->EndsWithVia() ? 1 : 0 ) << " ";
+ dumpShape ( l->Shape() );
+ m_theLog << std::endl;
+ break;
+ }
+
+ case PNS_ITEM::VIA:
+ {
+ m_theLog << " via 0 0 ";
+ dumpShape ( aItem->Shape() );
+ m_theLog << std::endl;
+ break;
+ }
+
+ case PNS_ITEM::SEGMENT:
+ {
+ PNS_SEGMENT* s =(PNS_SEGMENT*) aItem;
+ m_theLog << " line ";
+ m_theLog << s->Width() << " 0 linechain 2 0 " << s->Seg().A.x << " " <<
+ s->Seg().A.y << " " << s->Seg().B.x << " " <<s->Seg().B.y << std::endl;
+ break;
+ }
+
+ case PNS_ITEM::SOLID:
+ {
+ PNS_SOLID* s = (PNS_SOLID*) aItem;
+ m_theLog << " solid 0 0 ";
+ dumpShape( s->Shape() );
+ m_theLog << std::endl;
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+void PNS_LOGGER::Log( const SHAPE_LINE_CHAIN *aL, int aKind, const std::string aName )
+{
+ m_theLog << "item " << aKind << " " << aName << " ";
+ m_theLog << 0 << " " << 0 << " " << 0 << " " << 0 << " " << 0;
+ m_theLog << " line ";
+ m_theLog << 0 << " " << 0 << " ";
+ dumpShape( aL );
+ m_theLog << std::endl;
+}
+
+
+void PNS_LOGGER::Log( const VECTOR2I& aStart, const VECTOR2I& aEnd,
+ int aKind, const std::string aName)
+{
+}
+
+
+void PNS_LOGGER::dumpShape( const SHAPE* aSh )
+{
+ switch( aSh->Type() )
+ {
+ case SH_LINE_CHAIN:
+ {
+ const SHAPE_LINE_CHAIN* lc = (const SHAPE_LINE_CHAIN*) aSh;
+ m_theLog << "linechain " << lc->PointCount() << " " << ( lc->IsClosed() ? 1 : 0 ) << " ";
+
+ for( int i = 0; i < lc->PointCount(); i++ )
+ m_theLog << lc->CPoint( i ).x << " " << lc->CPoint( i ).y << " ";
+
+ break;
+ }
+
+ case SH_CIRCLE:
+ {
+ const SHAPE_CIRCLE *c = (const SHAPE_CIRCLE*) aSh;
+ m_theLog << "circle " << c->GetCenter().x << " " << c->GetCenter().y << " " << c->GetRadius();
+ break;
+ }
+
+ case SH_RECT:
+ {
+ const SHAPE_RECT* r = (const SHAPE_RECT*) aSh;
+ m_theLog << "rect " << r->GetPosition().x << " " << r->GetPosition().y << " " <<
+ r->GetSize().x << " " <<r->GetSize().y;
+ break;
+ }
+
+ case SH_SEGMENT:
+ {
+ const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) aSh;
+ m_theLog << "linechain 2 0 " << s->GetSeg().A.x << " " << s->GetSeg().A.y << " " <<
+ s->GetSeg().B.x << " " << s->GetSeg().B.y;
+ break;
+ }
+
+ case SH_CONVEX:
+ {
+ const SHAPE_CONVEX* c = (const SHAPE_CONVEX*) aSh;
+ m_theLog << "convex " << c->PointCount() << " ";
+
+ for( int i = 0; i < c->PointCount(); i++ )
+ m_theLog << c->CPoint( i ).x << " " << c->CPoint( i ).y << " ";
+
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+void PNS_LOGGER::Save( const std::string& aFilename )
+{
+ EndGroup();
+
+ FILE* f = fopen( aFilename.c_str(), "wb" );
+ printf( "Saving to '%s' [%p]\n", aFilename.c_str(), f );
+ const std::string s = m_theLog.str();
+ fwrite( s.c_str(), 1, s.length(), f );
+ fclose( f );
+}
diff --git a/pcbnew/router/pns_logger.h b/pcbnew/router/pns_logger.h
new file mode 100644
index 0000000..b38fd42
--- /dev/null
+++ b/pcbnew/router/pns_logger.h
@@ -0,0 +1,59 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_LOGGER_H
+#define __PNS_LOGGER_H
+
+#include <cstdio>
+#include <vector>
+#include <string>
+#include <sstream>
+
+#include <math/vector2d.h>
+
+class PNS_ITEM;
+class SHAPE_LINE_CHAIN;
+class SHAPE;
+
+class PNS_LOGGER
+{
+public:
+ PNS_LOGGER();
+ ~PNS_LOGGER();
+
+ void Save( const std::string& aFilename );
+ void Clear();
+
+ void NewGroup( const std::string& aName, int aIter = 0 );
+ void EndGroup();
+
+ void Log( const PNS_ITEM* aItem, int aKind = 0, const std::string aName = std::string() );
+ void Log( const SHAPE_LINE_CHAIN *aL, int aKind = 0, const std::string aName = std::string() );
+ void Log( const VECTOR2I& aStart, const VECTOR2I& aEnd, int aKind = 0,
+ const std::string aName = std::string() );
+
+private:
+ void dumpShape( const SHAPE* aSh );
+
+ bool m_groupOpened;
+ std::stringstream m_theLog;
+};
+
+#endif
diff --git a/pcbnew/router/pns_meander.cpp b/pcbnew/router/pns_meander.cpp
new file mode 100644
index 0000000..6739401
--- /dev/null
+++ b/pcbnew/router/pns_meander.cpp
@@ -0,0 +1,617 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+
+#include <base_units.h> // God forgive me doing this...
+#include <colors.h>
+
+#include "trace.h"
+
+#include "pns_node.h"
+#include "pns_itemset.h"
+#include "pns_topology.h"
+#include "pns_meander.h"
+#include "pns_meander_placer_base.h"
+#include "pns_router.h"
+
+const PNS_MEANDER_SETTINGS& PNS_MEANDER_SHAPE::Settings() const
+{
+ return m_placer->MeanderSettings();
+}
+
+const PNS_MEANDER_SETTINGS& PNS_MEANDERED_LINE::Settings() const
+{
+ return m_placer->MeanderSettings();
+}
+
+void PNS_MEANDERED_LINE::MeanderSegment( const SEG& aBase, int aBaseIndex )
+{
+ double base_len = aBase.Length();
+
+ SHAPE_LINE_CHAIN lc;
+
+ bool side = true;
+ VECTOR2D dir( aBase.B - aBase.A );
+
+ if( !m_dual )
+ AddCorner( aBase.A );
+
+ bool turning = false;
+ bool started = false;
+
+ m_last = aBase.A;
+
+ do
+ {
+ PNS_MEANDER_SHAPE m( m_placer, m_width, m_dual );
+
+ m.SetBaselineOffset( m_baselineOffset );
+ m.SetBaseIndex( aBaseIndex );
+
+ double thr = (double) m.spacing();
+
+ bool fail = false;
+ double remaining = base_len - ( m_last - aBase.A ).EuclideanNorm();
+
+ if( remaining < Settings( ).m_step )
+ break;
+
+ if( remaining > 3.0 * thr )
+ {
+ if( !turning )
+ {
+ for( int i = 0; i < 2; i++ )
+ {
+ if ( m.Fit( MT_CHECK_START, aBase, m_last, i ) )
+ {
+ turning = true;
+ AddMeander( new PNS_MEANDER_SHAPE( m ) );
+ side = !i;
+ started = true;
+ break;
+ }
+ }
+
+ if( !turning )
+ {
+ fail = true;
+
+ for( int i = 0; i < 2; i++ )
+ {
+ if ( m.Fit ( MT_SINGLE, aBase, m_last, i ) )
+ {
+ AddMeander( new PNS_MEANDER_SHAPE( m ) );
+ fail = false;
+ started = false;
+ side = !i;
+ break;
+ }
+ }
+ }
+ } else {
+ bool rv = m.Fit( MT_CHECK_FINISH, aBase, m_last, side );
+
+ if( rv )
+ {
+ m.Fit( MT_TURN, aBase, m_last, side );
+ AddMeander( new PNS_MEANDER_SHAPE( m ) );
+ started = true;
+ } else {
+ m.Fit( MT_FINISH, aBase, m_last, side );
+ started = false;
+ AddMeander( new PNS_MEANDER_SHAPE( m ) );
+ turning = false;
+ }
+
+ side = !side;
+ }
+ } else if( started )
+ {
+ bool rv = m.Fit( MT_FINISH, aBase, m_last, side );
+ if( rv )
+ AddMeander( new PNS_MEANDER_SHAPE( m ) );
+
+ break;
+
+ } else {
+ fail = true;
+ }
+
+ remaining = base_len - ( m_last - aBase.A ).EuclideanNorm( );
+
+ if( remaining < Settings( ).m_step )
+ break;
+
+ if( fail )
+ {
+ PNS_MEANDER_SHAPE tmp( m_placer, m_width, m_dual );
+ tmp.SetBaselineOffset( m_baselineOffset );
+ tmp.SetBaseIndex( aBaseIndex );
+
+ int nextP = tmp.spacing() - 2 * tmp.cornerRadius() + Settings().m_step;
+ VECTOR2I pn = m_last + dir.Resize( nextP );
+
+ if( aBase.Contains( pn ) && !m_dual )
+ {
+ AddCorner( pn );
+ } else
+ break;
+ }
+
+
+ } while( true );
+
+ if( !m_dual )
+ AddCorner( aBase.B );
+}
+
+
+int PNS_MEANDER_SHAPE::cornerRadius() const
+{
+ int cr = (int64_t) spacing() * Settings().m_cornerRadiusPercentage / 200;
+
+ return cr;
+}
+
+
+int PNS_MEANDER_SHAPE::spacing( ) const
+{
+ if ( !m_dual )
+ return std::max( 2 * m_width, Settings().m_spacing );
+ else
+ {
+ int sp = 2 * ( m_width + std::abs( m_baselineOffset ) );
+ return std::max ( sp, Settings().m_spacing );
+ }
+}
+
+
+SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::circleQuad( VECTOR2D aP, VECTOR2D aDir, bool aSide )
+{
+ SHAPE_LINE_CHAIN lc;
+
+ if( aDir.EuclideanNorm( ) == 0.0f )
+ {
+ lc.Append( aP );
+ return lc;
+ }
+
+ VECTOR2D dir_u( aDir );
+ VECTOR2D dir_v( aDir.Perpendicular( ) );
+
+ const int ArcSegments = Settings().m_cornerArcSegments;
+
+ double radius = (double) aDir.EuclideanNorm();
+ double angleStep = M_PI / 2.0 / (double) ArcSegments;
+
+ double correction = 12.0 * radius * ( 1.0 - cos( angleStep / 2.0 ) );
+
+ if( !m_dual )
+ correction = 0.0;
+ else if( radius < m_meanCornerRadius )
+ correction = 0.0;
+
+ VECTOR2D p = aP;
+ lc.Append( ( int ) p.x, ( int ) p.y );
+
+ VECTOR2D dir_uu = dir_u.Resize( radius - correction );
+ VECTOR2D dir_vv = dir_v.Resize( radius - correction );
+
+ VECTOR2D shift = dir_u.Resize( correction );
+
+ for( int i = ArcSegments - 1; i >= 0; i-- )
+ {
+ double alpha = (double) i / (double) ( ArcSegments - 1 ) * M_PI / 2.0;
+ p = aP + shift + dir_uu * cos( alpha ) + dir_vv * ( aSide ? -1.0 : 1.0 ) * ( 1.0 - sin( alpha ) );
+ lc.Append( ( int ) p.x, ( int ) p.y );
+ }
+
+ p = aP + dir_u + dir_v * ( aSide ? -1.0 : 1.0 );
+ lc.Append( ( int ) p.x, ( int ) p.y );
+
+ return lc;
+}
+
+
+VECTOR2I PNS_MEANDER_SHAPE::reflect( VECTOR2I p, const SEG& line )
+{
+ typedef int64_t ecoord;
+ VECTOR2I d = line.B - line.A;
+ ecoord l_squared = d.Dot( d );
+ ecoord t = d.Dot( p - line.A );
+ VECTOR2I c, rv;
+
+ if( !l_squared )
+ c = p;
+ else {
+ c.x = line.A.x + rescale( t, (ecoord) d.x, l_squared );
+ c.y = line.A.y + rescale( t, (ecoord) d.y, l_squared );
+ }
+
+ return 2 * c - p;
+}
+
+
+void PNS_MEANDER_SHAPE::start( SHAPE_LINE_CHAIN* aTarget, const VECTOR2D& aWhere, const VECTOR2D& aDir )
+{
+ m_currentTarget = aTarget;
+ m_currentTarget->Clear();
+ m_currentTarget->Append( aWhere );
+ m_currentDir = aDir;
+ m_currentPos = aWhere;
+}
+
+
+void PNS_MEANDER_SHAPE::forward( int aLength )
+{
+ m_currentPos += m_currentDir.Resize( aLength );
+ m_currentTarget->Append( m_currentPos );
+}
+
+
+void PNS_MEANDER_SHAPE::turn( int aAngle )
+{
+ m_currentDir = m_currentDir.Rotate( (double) aAngle * M_PI / 180.0 );
+}
+
+
+void PNS_MEANDER_SHAPE::arc( int aRadius, bool aSide )
+{
+ if( aRadius <= 0 )
+ {
+ turn( aSide ? -90 : 90 );
+ return;
+ }
+
+ VECTOR2D dir = m_currentDir.Resize( (double) aRadius );
+ SHAPE_LINE_CHAIN arc = circleQuad( m_currentPos, dir, aSide );
+ m_currentPos = arc.CPoint( -1 );
+ m_currentDir = dir.Rotate( aSide ? -M_PI / 2.0 : M_PI / 2.0 );
+
+ m_currentTarget->Append ( arc );
+}
+
+
+void PNS_MEANDER_SHAPE::uShape( int aSides, int aCorner, int aTop )
+{
+ forward( aSides );
+ arc( aCorner, true );
+ forward( aTop );
+ arc( aCorner, true );
+ forward( aSides );
+}
+
+
+SHAPE_LINE_CHAIN PNS_MEANDER_SHAPE::genMeanderShape( VECTOR2D aP, VECTOR2D aDir,
+ bool aSide, PNS_MEANDER_TYPE aType, int aAmpl, int aBaselineOffset )
+{
+ const PNS_MEANDER_SETTINGS& st = Settings();
+ int cr = cornerRadius();
+ int offset = aBaselineOffset;
+ int spc = spacing();
+
+ if( aSide )
+ offset *= -1;
+
+ VECTOR2D dir_u_b( aDir.Resize( offset ) );
+ VECTOR2D dir_v_b( dir_u_b.Perpendicular() );
+
+ if( 2 * cr > aAmpl )
+ {
+ cr = aAmpl / 2;
+ }
+
+ if( 2 * cr > spc )
+ {
+ cr = spc / 2;
+ }
+
+ m_meanCornerRadius = cr;
+
+ SHAPE_LINE_CHAIN lc;
+
+ start( &lc, aP + dir_v_b, aDir );
+
+ switch( aType )
+ {
+ case MT_EMPTY:
+ {
+ lc.Append( aP + dir_v_b + aDir );
+ break;
+ }
+ case MT_START:
+ {
+ arc( cr - offset, false );
+ uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
+ forward( std::min( cr - offset, cr + offset ) );
+ forward( std::abs( offset ) );
+
+ break;
+ }
+
+ case MT_FINISH:
+ {
+ start( &lc, aP - dir_u_b, aDir );
+ turn ( 90 );
+ forward( std::min( cr - offset, cr + offset ) );
+ forward( std::abs( offset ) );
+ uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
+ arc( cr - offset, false );
+ break;
+ }
+
+ case MT_TURN:
+ {
+ start( &lc, aP - dir_u_b, aDir );
+ turn( 90 );
+ forward( std::abs( offset ) );
+ uShape ( aAmpl - cr, cr + offset, spc - 2 * cr );
+ forward( std::abs( offset ) );
+ break;
+ }
+
+ case MT_SINGLE:
+ {
+ arc( cr - offset, false );
+ uShape( aAmpl - 2 * cr + std::abs( offset ), cr + offset, spc - 2 * cr );
+ arc( cr - offset, false );
+ lc.Append( aP + dir_v_b + aDir.Resize ( 2 * st.m_spacing ) );
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if( aSide )
+ {
+ SEG axis ( aP, aP + aDir );
+
+ for( int i = 0; i < lc.PointCount(); i++ )
+ lc.Point( i ) = reflect( lc.CPoint( i ), axis );
+ }
+
+ return lc;
+}
+
+
+bool PNS_MEANDERED_LINE::CheckSelfIntersections( PNS_MEANDER_SHAPE* aShape, int aClearance )
+{
+ for( int i = m_meanders.size() - 1; i >= 0; i-- )
+ {
+ PNS_MEANDER_SHAPE* m = m_meanders[i];
+
+ if( m->Type() == MT_EMPTY || m->Type() == MT_CORNER )
+ continue;
+
+ const SEG& b1 = aShape->BaseSegment();
+ const SEG& b2 = m->BaseSegment();
+
+ if( b1.ApproxParallel( b2 ) )
+ continue;
+
+ int n = m->CLine( 0 ).SegmentCount();
+
+ for( int j = n - 1; j >= 0; j-- )
+ if( aShape->CLine( 0 ).Collide ( m->CLine( 0 ) .CSegment( j ), aClearance ) )
+ return false;
+ }
+
+ return true;
+}
+
+
+bool PNS_MEANDER_SHAPE::Fit( PNS_MEANDER_TYPE aType, const SEG& aSeg, const VECTOR2I& aP, bool aSide )
+{
+ const PNS_MEANDER_SETTINGS& st = Settings();
+
+ bool checkMode = false;
+ PNS_MEANDER_TYPE prim1, prim2;
+
+ if( aType == MT_CHECK_START )
+ {
+ prim1 = MT_START;
+ prim2 = MT_TURN;
+ checkMode = true;
+ }
+ else if( aType == MT_CHECK_FINISH )
+ {
+ prim1 = MT_TURN;
+ prim2 = MT_FINISH;
+ checkMode = true;
+ }
+
+ if( checkMode )
+ {
+ PNS_MEANDER_SHAPE m1( m_placer, m_width, m_dual );
+ PNS_MEANDER_SHAPE m2( m_placer, m_width, m_dual );
+
+ m1.SetBaselineOffset( m_baselineOffset );
+ m2.SetBaselineOffset( m_baselineOffset );
+
+ bool c1 = m1.Fit( prim1, aSeg, aP, aSide );
+ bool c2 = false;
+
+ if( c1 )
+ c2 = m2.Fit( prim2, aSeg, m1.End(), !aSide );
+
+ if( c1 && c2 )
+ {
+ m_type = prim1;
+ m_shapes[0] = m1.m_shapes[0];
+ m_shapes[1] = m1.m_shapes[1];
+ m_baseSeg =aSeg;
+ m_p0 = aP;
+ m_side = aSide;
+ m_amplitude = m1.Amplitude();
+ m_dual = m1.m_dual;
+ m_baseSeg = m1.m_baseSeg;
+ m_baseIndex = m1.m_baseIndex;
+ updateBaseSegment();
+ m_baselineOffset = m1.m_baselineOffset;
+ return true;
+ } else
+ return false;
+ }
+
+ int minAmpl = st.m_minAmplitude;
+ int maxAmpl = st.m_maxAmplitude;
+
+ if( m_dual )
+ {
+ minAmpl = std::max( minAmpl, 2 * std::abs( m_baselineOffset ) );
+ maxAmpl = std::max( maxAmpl, 2 * std::abs( m_baselineOffset ) );
+ }
+
+ for( int ampl = maxAmpl; ampl >= minAmpl; ampl -= st.m_step )
+ {
+ if( m_dual )
+ {
+ m_shapes[0] = genMeanderShape( aP, aSeg.B - aSeg.A, aSide, aType, ampl, m_baselineOffset );
+ m_shapes[1] = genMeanderShape( aP, aSeg.B - aSeg.A, aSide, aType, ampl, -m_baselineOffset );
+ }
+ else
+ {
+ m_shapes[0] = genMeanderShape( aP, aSeg.B - aSeg.A, aSide, aType, ampl, 0 );
+ }
+
+ m_type = aType;
+ m_baseSeg = aSeg;
+ m_p0 = aP;
+ m_side = aSide;
+ m_amplitude = ampl;
+
+ updateBaseSegment();
+
+ if( m_placer->CheckFit( this ) )
+ return true;
+ }
+
+ return false;
+}
+
+
+void PNS_MEANDER_SHAPE::Recalculate()
+{
+ m_shapes[0] = genMeanderShape( m_p0, m_baseSeg.B - m_baseSeg.A, m_side, m_type, m_amplitude, m_dual ? m_baselineOffset : 0 );
+
+ if( m_dual )
+ m_shapes[1] = genMeanderShape( m_p0, m_baseSeg.B - m_baseSeg.A, m_side, m_type, m_amplitude, -m_baselineOffset );
+
+ updateBaseSegment();
+}
+
+
+void PNS_MEANDER_SHAPE::Resize( int aAmpl )
+{
+ if( aAmpl < 0 )
+ return;
+
+ m_amplitude = aAmpl;
+
+ Recalculate();
+}
+
+
+void PNS_MEANDER_SHAPE::MakeEmpty()
+{
+ updateBaseSegment();
+
+ VECTOR2I dir = m_clippedBaseSeg.B - m_clippedBaseSeg.A;
+
+ m_type = MT_EMPTY;
+
+ m_shapes[0] = genMeanderShape ( m_p0, dir, m_side, m_type, 0, m_dual ? m_baselineOffset : 0 );
+
+ if( m_dual )
+ m_shapes[1] = genMeanderShape( m_p0, dir, m_side, m_type, 0, -m_baselineOffset );
+}
+
+
+void PNS_MEANDERED_LINE::AddCorner( const VECTOR2I& aA, const VECTOR2I& aB )
+{
+ PNS_MEANDER_SHAPE* m = new PNS_MEANDER_SHAPE( m_placer, m_width, m_dual );
+
+ m->MakeCorner( aA, aB );
+ m_last = aA;
+
+ m_meanders.push_back( m );
+}
+
+
+void PNS_MEANDER_SHAPE::MakeCorner( VECTOR2I aP1, VECTOR2I aP2 )
+{
+ SetType( MT_CORNER );
+ m_shapes[0].Clear();
+ m_shapes[1].Clear();
+ m_shapes[0].Append( aP1 );
+ m_shapes[1].Append( aP2 );
+ m_clippedBaseSeg.A = aP1;
+ m_clippedBaseSeg.B = aP1;
+}
+
+
+void PNS_MEANDERED_LINE::AddMeander( PNS_MEANDER_SHAPE* aShape )
+{
+ m_last = aShape->BaseSegment().B;
+ m_meanders.push_back( aShape );
+}
+
+
+void PNS_MEANDERED_LINE::Clear()
+{
+ BOOST_FOREACH( PNS_MEANDER_SHAPE* m, m_meanders )
+ {
+ delete m;
+ }
+
+ m_meanders.clear( );
+}
+
+
+int PNS_MEANDER_SHAPE::BaselineLength() const
+{
+ return m_clippedBaseSeg.Length();
+}
+
+
+int PNS_MEANDER_SHAPE::MaxTunableLength() const
+{
+ return CLine( 0 ).Length();
+}
+
+
+void PNS_MEANDER_SHAPE::updateBaseSegment( )
+{
+ if( m_dual )
+ {
+ VECTOR2I midpA = ( CLine( 0 ).CPoint( 0 ) + CLine( 1 ).CPoint( 0 ) ) / 2;
+ VECTOR2I midpB = ( CLine( 0 ).CPoint( -1 ) + CLine( 1 ).CPoint( -1 ) ) / 2;
+
+ m_clippedBaseSeg.A = m_baseSeg.LineProject( midpA );
+ m_clippedBaseSeg.B = m_baseSeg.LineProject( midpB );
+ }
+ else
+ {
+ m_clippedBaseSeg.A = m_baseSeg.LineProject( CLine( 0 ).CPoint( 0 ) );
+ m_clippedBaseSeg.B = m_baseSeg.LineProject( CLine( 0 ).CPoint( -1 ) );
+ }
+}
diff --git a/pcbnew/router/pns_meander.h b/pcbnew/router/pns_meander.h
new file mode 100644
index 0000000..5d1ae51
--- /dev/null
+++ b/pcbnew/router/pns_meander.h
@@ -0,0 +1,514 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_MEANDER_H
+#define __PNS_MEANDER_H
+
+#include <math/vector2d.h>
+
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+
+class PNS_MEANDER_PLACER_BASE;
+
+///< Shapes of available meanders
+enum PNS_MEANDER_TYPE {
+ MT_SINGLE, // _|^|_, single-sided
+ MT_START, // _|^|
+ MT_FINISH, // |^|_
+ MT_TURN, // |^| or |_|
+ MT_CHECK_START, // try fitting a start type, but don't produce a line
+ MT_CHECK_FINISH, // try fitting a finish type, but don't produce a line
+ MT_CORNER, // line corner
+ MT_EMPTY // no meander (straight line)
+};
+
+/**
+ * Class PNS_MEANDER_SETTINGS
+ *
+ * Holds dimensions for the meandering algorithm.
+ */
+class PNS_MEANDER_SETTINGS
+{
+public:
+
+ ///> meander corner shape
+ enum CornerType {
+ ROUND = 1, // rounded (90 degree arc)
+ CHAMFER // chamfered (45 degree segment)
+ };
+
+ PNS_MEANDER_SETTINGS()
+ {
+ m_minAmplitude = 100000;
+ m_maxAmplitude = 1000000;
+ m_step = 50000;
+ m_spacing = 600000;
+ m_targetLength = 100000000;
+ m_targetSkew = 0;
+ m_cornerType = ROUND;
+ m_cornerRadiusPercentage = 100;
+ m_lengthTolerance = 100000;
+ m_cornerArcSegments = 8;
+ }
+
+ ///> minimum meandering amplitude
+ int m_minAmplitude;
+ ///> maximum meandering amplitude
+ int m_maxAmplitude;
+ ///> meandering period/spacing (see dialog picture for explanation)
+ int m_spacing;
+ ///> amplitude/spacing adjustment step
+ int m_step;
+ ///> desired length of the tuned line/diff pair
+ int m_targetLength;
+ ///> type of corners for the meandered line
+ CornerType m_cornerType;
+ ///> rounding percentage (0 - 100)
+ int m_cornerRadiusPercentage;
+ ///> allowable tuning error
+ int m_lengthTolerance;
+ ///> number of line segments for arc approximation
+ int m_cornerArcSegments;
+ ///> target skew value for diff pair de-skewing
+ int m_targetSkew;
+};
+
+class PNS_MEANDERED_LINE;
+
+/**
+ * Class PNS_MEANDER_SETTINGS
+ *
+ * Holds the geometry of a single meander.
+ */
+class PNS_MEANDER_SHAPE
+{
+public:
+ /**
+ * Constructor
+ *
+ * @param aPlacer the meander placer instance
+ * @param aWidth width of the meandered line
+ * @param aIsDual when true, the shape contains two meandered
+ * lines at a given offset (diff pairs)
+ */
+ PNS_MEANDER_SHAPE( PNS_MEANDER_PLACER_BASE *aPlacer, int aWidth, bool aIsDual = false ) :
+ m_placer( aPlacer ),
+ m_dual( aIsDual ),
+ m_width( aWidth ),
+ m_baselineOffset( 0 )
+ {
+ // Do not leave unitialized members, and keep static analyser quiet:
+ m_type = MT_SINGLE;
+ m_amplitude = 0;
+ m_side = false;
+ m_baseIndex = 0;
+ m_currentTarget = NULL;
+ m_meanCornerRadius = 0;
+ }
+
+ /**
+ * Function SetType()
+ *
+ * Sets the type of the meander.
+ */
+ void SetType( PNS_MEANDER_TYPE aType )
+ {
+ m_type = aType;
+ }
+
+ /**
+ * Function Type()
+ *
+ * @return the type of the meander.
+ */
+ PNS_MEANDER_TYPE Type() const
+ {
+ return m_type;
+ }
+
+ /**
+ * Function SetBaseIndex()
+ *
+ * Sets an auxillary index of the segment being meandered in its original PNS_LINE.
+ */
+ void SetBaseIndex( int aIndex )
+ {
+ m_baseIndex = aIndex;
+ }
+
+ /**
+ * Function BaseIndex()
+ *
+ * @return auxillary index of the segment being meandered in its original PNS_LINE.
+ */
+ int BaseIndex() const
+ {
+ return m_baseIndex;
+ }
+
+ /**
+ * Function Amplitude()
+ *
+ * @return the amplitude of the meander shape.
+ */
+ int Amplitude() const
+ {
+ return m_amplitude;
+ }
+
+ /**
+ * Function MakeCorner()
+ *
+ * Creates a dummy meander shape representing a line corner. Used to define
+ * the starts/ends of meandered segments.
+ * @param aP1 corner point of the 1st line
+ * @param aP2 corner point of the 2nd line (if m_dual == true)
+ */
+ void MakeCorner( VECTOR2I aP1, VECTOR2I aP2 = VECTOR2I( 0, 0 ) );
+
+ /**
+ * Function Resize()
+ *
+ * Changes the amplitude of the meander shape to aAmpl and recalculates
+ * the resulting line chain.
+ * @param aAmpl new amplitude.
+ */
+ void Resize( int aAmpl );
+
+ /**
+ * Function Recalculate()
+ *
+ * Recalculates the line chain representing the meanders's shape.
+ */
+ void Recalculate();
+
+ /**
+ * Function IsDual()
+ *
+ * @return true if the shape represents 2 parallel lines (diff pair).
+ */
+ bool IsDual() const
+ {
+ return m_dual;
+ }
+
+ /**
+ * Function Side()
+ *
+ * @return true if the meander is to the right of its base segment.
+ */
+ bool Side() const
+ {
+ return m_side;
+ }
+
+ /**
+ * Function End()
+ *
+ * @return end vertex of the base segment of the meander shape.
+ */
+ VECTOR2I End() const
+ {
+ return m_clippedBaseSeg.B;
+ }
+
+ /**
+ * Function CLine()
+ *
+ * @return the line chain representing the shape of the meander.
+ */
+ const SHAPE_LINE_CHAIN& CLine( int aShape ) const
+ {
+ return m_shapes[aShape];
+ }
+
+ /**
+ * Function MakeEmpty()
+ *
+ * Replaces the meander with straight bypass line(s), effectively
+ * clearing it.
+ */
+ void MakeEmpty();
+
+ /**
+ * Function Fit()
+ *
+ * Attempts to fit a meander of a given type onto a segment, avoiding
+ * collisions with other board features.
+ * @param aType type of meander shape
+ * @param aSeg base segment for meandering
+ * @param aP start point of the meander
+ * @param aSide side of aSeg to put the meander on (true = right)
+ * @return true on success.
+ */
+ bool Fit( PNS_MEANDER_TYPE aType, const SEG& aSeg, const VECTOR2I& aP, bool aSide );
+
+ /**
+ * Function BaseSegment()
+ *
+ * Returns the base segment the meadner was fitted to.
+ * @return the base segment.
+ */
+ const SEG& BaseSegment() const
+ {
+ return m_clippedBaseSeg;
+ }
+
+ /**
+ * Function BaselineLength()
+ *
+ * @return length of the base segment for the meander (i.e.
+ * the minimum tuned length.
+ */
+ int BaselineLength() const;
+
+ /**
+ * Function MaxTunableLength()
+ *
+ * @return the length of the fitted line chain.
+ */
+ int MaxTunableLength() const;
+
+ /**
+ * Function Settings()
+ *
+ * @return the current meandering settings.
+ */
+ const PNS_MEANDER_SETTINGS& Settings() const;
+
+ /**
+ * Function Width()
+ *
+ * @return width of the meandered line.
+ */
+ int Width() const
+ {
+ return m_width;
+ }
+
+ /**
+ * Function SetBaselineOffset()
+ *
+ * Sets the parallel offset between the base segment and the meandered
+ * line. Used for dual menaders (diff pair) only.
+ * @param aOffset the offset
+ */
+ void SetBaselineOffset( int aOffset )
+ {
+ m_baselineOffset = aOffset;
+ }
+
+private:
+ friend class PNS_MEANDERED_LINE;
+
+ ///> starts turtle drawing
+ void start( SHAPE_LINE_CHAIN* aTarget, const VECTOR2D& aWhere, const VECTOR2D& aDir );
+ ///> moves turtle forward by aLength
+ void forward( int aLength );
+ ///> turns the turtle by aAngle
+ void turn( int aAngle );
+ ///> tells the turtle to draw an arc of given radius and turn direction
+ void arc( int aRadius, bool aSide );
+ ///> tells the turtle to draw an U-like shape
+ void uShape( int aSides, int aCorner, int aTop );
+
+ ///> generates a 90-degree circular arc
+ SHAPE_LINE_CHAIN circleQuad( VECTOR2D aP, VECTOR2D aDir, bool aSide );
+
+ ///> reflects a point onto other side of a given segment
+ VECTOR2I reflect( VECTOR2I aP, const SEG& aLine );
+
+ ///> produces a meander shape of given type
+ SHAPE_LINE_CHAIN genMeanderShape( VECTOR2D aP, VECTOR2D aDir, bool aSide, PNS_MEANDER_TYPE aType, int aAmpl, int aBaselineOffset = 0 );
+
+ ///> recalculates the clipped baseline after the parameters of
+ ///> the meander have been changed.
+ void updateBaseSegment();
+
+ ///> returns sanitized corner radius value
+ int cornerRadius() const;
+
+ ///> returns sanitized spacing value
+ int spacing() const;
+
+ ///> the type
+ PNS_MEANDER_TYPE m_type;
+ ///> the placer that placed this meander
+ PNS_MEANDER_PLACER_BASE* m_placer;
+ ///> dual or single line
+ bool m_dual;
+ ///> width of the line
+ int m_width;
+ ///> amplitude of the meander
+ int m_amplitude;
+ ///> offset wrs the base segment (dual only)
+ int m_baselineOffset;
+ ///> average radius of meander corners (for correction of DP meanders)
+ int m_meanCornerRadius;
+ ///> first point of the meandered line
+ VECTOR2I m_p0;
+ ///> base segment (unclipped)
+ SEG m_baseSeg;
+ ///> base segment (clipped)
+ SEG m_clippedBaseSeg;
+ ///> side (true = right)
+ bool m_side;
+ ///> the actual shapes (0 used for single, both for dual)
+ SHAPE_LINE_CHAIN m_shapes[2];
+ ///> index of the meandered segment in the base line
+ int m_baseIndex;
+ ///> current turtle direction
+ VECTOR2D m_currentDir;
+ ///> current turtle position
+ VECTOR2D m_currentPos;
+ ///> the line the turtle is drawing on
+ SHAPE_LINE_CHAIN* m_currentTarget;
+};
+
+
+/**
+ * Class PNS_MEANDERED_LINE
+ *
+ * Represents a set of meanders fitted over a single or two lines.
+ */
+class PNS_MEANDERED_LINE
+{
+public:
+ PNS_MEANDERED_LINE()
+ {
+ // Do not leave unitialized members, and keep static analyser quiet:
+ m_placer = NULL;
+ m_dual = false;
+ m_width = 0;
+ m_baselineOffset = 0;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param aPlacer the meander placer instance
+ * @param aIsDual when true, the meanders are generated for two coupled lines
+ */
+ PNS_MEANDERED_LINE( PNS_MEANDER_PLACER_BASE* aPlacer, bool aIsDual = false ) :
+ m_placer( aPlacer ),
+ m_dual( aIsDual )
+ {
+ // Do not leave unitialized members, and keep static analyser quiet:
+ m_width = 0;
+ m_baselineOffset = 0;
+ }
+
+ ~PNS_MEANDERED_LINE()
+ {
+ Clear();
+ }
+
+ /**
+ * Function AddCorner()
+ *
+ * Creates a dummy meander shape representing a line corner. Used to define
+ * the starts/ends of meandered segments.
+ * @param aA corner point of the 1st line
+ * @param aB corner point of the 2nd line (if m_dual == true)
+ */
+ void AddCorner( const VECTOR2I& aA, const VECTOR2I& aB = VECTOR2I( 0, 0 ) );
+
+ /**
+ * Function AddMeander()
+ *
+ * Adds a new meander shape the the meandered line.
+ * @param aShape the meander shape to add
+ */
+ void AddMeander( PNS_MEANDER_SHAPE* aShape );
+
+ /**
+ * Function Clear()
+ *
+ * Clears the line geometry, removing all corners and meanders.
+ */
+ void Clear();
+
+ /**
+ * Function SetWidth()
+ *
+ * Sets the line width.
+ */
+ void SetWidth( int aWidth )
+ {
+ m_width = aWidth;
+ }
+
+ /**
+ * Function MeanderSegment()
+ *
+ * Fits maximum amplitude meanders on a given segment and adds to the
+ * current line.
+ * @param aSeg the base segment to meander
+ * @param aBaseIndex index of the base segment in the original line
+ */
+ void MeanderSegment( const SEG& aSeg, int aBaseIndex = 0 );
+
+ /// @copydoc PNS_MEANDER_SHAPE::SetBaselineOffset()
+ void SetBaselineOffset( int aOffset )
+ {
+ m_baselineOffset = aOffset;
+ }
+
+ /**
+ * Function Meanders()
+ *
+ * @return set of meander shapes for this line
+ */
+ std::vector<PNS_MEANDER_SHAPE*>& Meanders()
+ {
+ return m_meanders;
+ }
+
+ /**
+ * Function CheckSelfIntersections()
+ *
+ * Checks if the given shape is intersecting with any other meander in
+ * the current line.
+ * @param aShape the shape to check
+ * @param aClearance clearance value
+ * @return true, if the meander shape is not colliding
+ */
+ bool CheckSelfIntersections ( PNS_MEANDER_SHAPE* aShape, int aClearance );
+
+ /**
+ * Function Settings()
+ *
+ * @return the current meandering settings.
+ */
+ const PNS_MEANDER_SETTINGS& Settings() const;
+
+private:
+ VECTOR2I m_last;
+
+ PNS_MEANDER_PLACER_BASE* m_placer;
+ std::vector<PNS_MEANDER_SHAPE*> m_meanders;
+
+ bool m_dual;
+ int m_width;
+ int m_baselineOffset;
+};
+
+#endif // __PNS_MEANDER_H
diff --git a/pcbnew/router/pns_meander_placer.cpp b/pcbnew/router/pns_meander_placer.cpp
new file mode 100644
index 0000000..14b9f9b
--- /dev/null
+++ b/pcbnew/router/pns_meander_placer.cpp
@@ -0,0 +1,268 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+
+#include <base_units.h> // God forgive me doing this...
+#include <colors.h>
+
+#include "trace.h"
+
+#include "pns_node.h"
+#include "pns_itemset.h"
+#include "pns_topology.h"
+#include "pns_meander_placer.h"
+#include "pns_router.h"
+
+
+PNS_MEANDER_PLACER::PNS_MEANDER_PLACER( PNS_ROUTER* aRouter ) :
+ PNS_MEANDER_PLACER_BASE( aRouter )
+{
+ m_world = NULL;
+ m_currentNode = NULL;
+
+ // Init temporary variables (do not leave uninitialized members)
+ m_initialSegment = NULL;
+ m_lastLength = 0;
+ m_lastStatus = TOO_SHORT;
+}
+
+
+PNS_MEANDER_PLACER::~PNS_MEANDER_PLACER()
+{
+}
+
+
+PNS_NODE* PNS_MEANDER_PLACER::CurrentNode( bool aLoopsRemoved ) const
+{
+ if( !m_currentNode )
+ return m_world;
+
+ return m_currentNode;
+}
+
+
+bool PNS_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
+{
+ VECTOR2I p;
+
+ if( !aStartItem || !aStartItem->OfKind( PNS_ITEM::SEGMENT ) )
+ {
+ Router()->SetFailureReason( _( "Please select a track whose length you want to tune." ) );
+ return false;
+ }
+
+ m_initialSegment = static_cast<PNS_SEGMENT*>( aStartItem );
+
+ p = m_initialSegment->Seg().NearestPoint( aP );
+
+ m_currentNode = NULL;
+ m_currentStart = p;
+
+ m_world = Router()->GetWorld()->Branch();
+ m_originLine = m_world->AssembleLine( m_initialSegment );
+
+ PNS_TOPOLOGY topo( m_world );
+ m_tunedPath = topo.AssembleTrivialPath( m_initialSegment );
+
+ m_world->Remove( &m_originLine );
+
+ m_currentWidth = m_originLine.Width();
+ m_currentEnd = VECTOR2I( 0, 0 );
+
+ return true;
+}
+
+
+int PNS_MEANDER_PLACER::origPathLength() const
+{
+ int total = 0;
+ BOOST_FOREACH( const PNS_ITEM* item, m_tunedPath.CItems() )
+ {
+ if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
+ {
+ total += l->CLine().Length();
+ }
+ }
+
+ return total;
+}
+
+
+bool PNS_MEANDER_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
+{
+ return doMove( aP, aEndItem, m_settings.m_targetLength );
+}
+
+
+bool PNS_MEANDER_PLACER::doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTargetLength )
+{
+ SHAPE_LINE_CHAIN pre, tuned, post;
+
+ if( m_currentNode )
+ delete m_currentNode;
+
+ m_currentNode = m_world->Branch();
+
+ cutTunedLine( m_originLine.CLine(), m_currentStart, aP, pre, tuned, post );
+
+ m_result = PNS_MEANDERED_LINE( this, false );
+ m_result.SetWidth( m_originLine.Width() );
+ m_result.SetBaselineOffset( 0 );
+
+ for( int i = 0; i < tuned.SegmentCount(); i++ )
+ {
+ const SEG s = tuned.CSegment( i );
+ m_result.AddCorner( s.A );
+ m_result.MeanderSegment( s );
+ m_result.AddCorner( s.B );
+ }
+
+ int lineLen = origPathLength();
+
+ m_lastLength = lineLen;
+ m_lastStatus = TUNED;
+
+ if( compareWithTolerance( lineLen, aTargetLength, m_settings.m_lengthTolerance ) > 0 )
+ {
+ m_lastStatus = TOO_LONG;
+ } else {
+ m_lastLength = lineLen - tuned.Length();
+ tuneLineLength( m_result, aTargetLength - lineLen );
+ }
+
+ BOOST_FOREACH ( const PNS_ITEM* item, m_tunedPath.CItems() )
+ {
+ if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
+ {
+ Router()->DisplayDebugLine( l->CLine(), 5, 30000 );
+ }
+ }
+
+ if( m_lastStatus != TOO_LONG )
+ {
+ tuned.Clear();
+
+ BOOST_FOREACH( PNS_MEANDER_SHAPE* m, m_result.Meanders() )
+ {
+ if( m->Type() != MT_EMPTY )
+ {
+ tuned.Append ( m->CLine( 0 ) );
+ }
+ }
+
+ m_lastLength += tuned.Length();
+
+ int comp = compareWithTolerance( m_lastLength - aTargetLength, 0, m_settings.m_lengthTolerance );
+
+ if( comp > 0 )
+ m_lastStatus = TOO_LONG;
+ else if( comp < 0 )
+ m_lastStatus = TOO_SHORT;
+ else
+ m_lastStatus = TUNED;
+ }
+
+ m_finalShape.Clear();
+ m_finalShape.Append( pre );
+ m_finalShape.Append( tuned );
+ m_finalShape.Append( post );
+ m_finalShape.Simplify();
+
+ return true;
+}
+
+
+bool PNS_MEANDER_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
+{
+ if( !m_currentNode )
+ return false;
+
+ m_currentTrace = PNS_LINE( m_originLine, m_finalShape );
+ m_currentNode->Add( &m_currentTrace );
+
+ Router()->CommitRouting( m_currentNode );
+ return true;
+}
+
+
+bool PNS_MEANDER_PLACER::CheckFit( PNS_MEANDER_SHAPE* aShape )
+{
+ PNS_LINE l( m_originLine, aShape->CLine( 0 ) );
+
+ if( m_currentNode->CheckColliding( &l ) )
+ return false;
+
+ int w = aShape->Width();
+ int clearance = w + m_settings.m_spacing;
+
+ return m_result.CheckSelfIntersections( aShape, clearance );
+}
+
+
+const PNS_ITEMSET PNS_MEANDER_PLACER::Traces()
+{
+ m_currentTrace = PNS_LINE( m_originLine, m_finalShape );
+ return PNS_ITEMSET( &m_currentTrace );
+}
+
+
+const VECTOR2I& PNS_MEANDER_PLACER::CurrentEnd() const
+{
+ return m_currentEnd;
+}
+
+int PNS_MEANDER_PLACER::CurrentLayer() const
+{
+ return m_initialSegment->Layers().Start();
+}
+
+
+const wxString PNS_MEANDER_PLACER::TuningInfo() const
+{
+ wxString status;
+
+ switch ( m_lastStatus )
+ {
+ case TOO_LONG:
+ status = _( "Too long: " );
+ break;
+ case TOO_SHORT:
+ status = _( "Too short: " );
+ break;
+ case TUNED:
+ status = _( "Tuned: " );
+ break;
+ default:
+ return _( "?" );
+ }
+
+ status += LengthDoubleToString( (double) m_lastLength, false );
+ status += "/";
+ status += LengthDoubleToString( (double) m_settings.m_targetLength, false );
+
+ return status;
+}
+
+
+PNS_MEANDER_PLACER::TUNING_STATUS PNS_MEANDER_PLACER::TuningStatus() const
+{
+ return m_lastStatus;
+}
diff --git a/pcbnew/router/pns_meander_placer.h b/pcbnew/router/pns_meander_placer.h
new file mode 100644
index 0000000..b38457e
--- /dev/null
+++ b/pcbnew/router/pns_meander_placer.h
@@ -0,0 +1,118 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_MEANDER_PLACER_H
+#define __PNS_MEANDER_PLACER_H
+
+#include <math/vector2d.h>
+
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+
+#include "pns_node.h"
+#include "pns_via.h"
+#include "pns_line.h"
+#include "pns_placement_algo.h"
+#include "pns_meander.h"
+#include "pns_meander_placer_base.h"
+
+class PNS_ROUTER;
+class PNS_SHOVE;
+class PNS_OPTIMIZER;
+class PNS_ROUTER_BASE;
+
+/**
+ * Class PNS_MEANDER_PLACER
+ *
+ * Single track length matching/meandering tool.
+ */
+class PNS_MEANDER_PLACER : public PNS_MEANDER_PLACER_BASE
+{
+public:
+
+ PNS_MEANDER_PLACER( PNS_ROUTER* aRouter );
+ virtual ~PNS_MEANDER_PLACER();
+
+ /// @copydoc PNS_PLACEMENT_ALGO::Start()
+ virtual bool Start( const VECTOR2I& aP, PNS_ITEM* aStartItem );
+
+ /// @copydoc PNS_PLACEMENT_ALGO::Move()
+ virtual bool Move( const VECTOR2I& aP, PNS_ITEM* aEndItem );
+
+ /// @copydoc PNS_PLACEMENT_ALGO::FixRoute()
+ virtual bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem );
+
+ /// @copydoc PNS_PLACEMENT_ALGO::CurrentNode()
+ PNS_NODE* CurrentNode( bool aLoopsRemoved = false ) const;
+
+ /// @copydoc PNS_PLACEMENT_ALGO::Traces()
+ const PNS_ITEMSET Traces();
+
+ /// @copydoc PNS_PLACEMENT_ALGO::CurrentEnd()
+ const VECTOR2I& CurrentEnd() const;
+
+ /// @copydoc PNS_PLACEMENT_ALGO::CurrentNets()
+ const std::vector<int> CurrentNets() const
+ {
+ return std::vector<int> (1, m_originLine.Net() );
+ }
+
+ /// @copydoc PNS_PLACEMENT_ALGO::CurrentLayer()
+ int CurrentLayer() const;
+
+ /// @copydoc PNS_MEANDER_PLACER_BASE::TuningInfo()
+ virtual const wxString TuningInfo() const;
+
+ /// @copydoc PNS_MEANDER_PLACER_BASE::TuningStatus()
+ virtual TUNING_STATUS TuningStatus() const;
+
+ /// @copydoc PNS_MEANDER_PLACER_BASE::CheckFit()
+ bool CheckFit ( PNS_MEANDER_SHAPE* aShape );
+
+protected:
+
+ bool doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTargetLength );
+
+ void setWorld( PNS_NODE* aWorld );
+
+ virtual int origPathLength() const;
+
+ ///> pointer to world to search colliding items
+ PNS_NODE* m_world;
+
+ ///> current routing start point (end of tail, beginning of head)
+ VECTOR2I m_currentStart;
+
+ ///> Current world state
+ PNS_NODE* m_currentNode;
+
+ PNS_LINE m_originLine;
+ PNS_LINE m_currentTrace;
+ PNS_ITEMSET m_tunedPath;
+
+ SHAPE_LINE_CHAIN m_finalShape;
+ PNS_MEANDERED_LINE m_result;
+ PNS_SEGMENT* m_initialSegment;
+
+ int m_lastLength;
+ TUNING_STATUS m_lastStatus;
+};
+
+#endif // __PNS_MEANDER_PLACER_H
diff --git a/pcbnew/router/pns_meander_placer_base.cpp b/pcbnew/router/pns_meander_placer_base.cpp
new file mode 100644
index 0000000..0a655e4
--- /dev/null
+++ b/pcbnew/router/pns_meander_placer_base.cpp
@@ -0,0 +1,187 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pns_router.h"
+#include "pns_meander.h"
+#include "pns_meander_placer_base.h"
+
+PNS_MEANDER_PLACER_BASE::PNS_MEANDER_PLACER_BASE( PNS_ROUTER* aRouter ) :
+ PNS_PLACEMENT_ALGO( aRouter )
+{
+ m_currentWidth = 0;
+}
+
+
+PNS_MEANDER_PLACER_BASE::~PNS_MEANDER_PLACER_BASE()
+{
+}
+
+
+void PNS_MEANDER_PLACER_BASE::AmplitudeStep( int aSign )
+{
+ int a = m_settings.m_maxAmplitude + aSign * m_settings.m_step;
+ a = std::max( a, m_settings.m_minAmplitude );
+
+ m_settings.m_maxAmplitude = a;
+}
+
+
+void PNS_MEANDER_PLACER_BASE::SpacingStep( int aSign )
+{
+ int s = m_settings.m_spacing + aSign * m_settings.m_step;
+ s = std::max( s, 2 * m_currentWidth );
+
+ m_settings.m_spacing = s;
+}
+
+
+void PNS_MEANDER_PLACER_BASE::UpdateSettings( const PNS_MEANDER_SETTINGS& aSettings )
+{
+ m_settings = aSettings;
+}
+
+
+void PNS_MEANDER_PLACER_BASE::cutTunedLine( const SHAPE_LINE_CHAIN& aOrigin,
+ const VECTOR2I& aTuneStart,
+ const VECTOR2I& aCursorPos,
+ SHAPE_LINE_CHAIN& aPre,
+ SHAPE_LINE_CHAIN& aTuned,
+ SHAPE_LINE_CHAIN& aPost )
+{
+ VECTOR2I cp ( aCursorPos );
+
+ if ( cp == aTuneStart ) // we don't like tuning segments with 0 length
+ {
+ int idx = aOrigin.FindSegment( cp );
+ if( idx >= 0 )
+ {
+ const SEG& s = aOrigin.CSegment( idx );
+ cp += (s.B - s.A).Resize(2);
+ } else
+ cp += VECTOR2I (2, 5); // some arbitrary value that is not 45 degrees oriented
+ }
+
+ VECTOR2I n = aOrigin.NearestPoint( cp );
+ VECTOR2I m = aOrigin.NearestPoint( aTuneStart );
+
+ SHAPE_LINE_CHAIN l( aOrigin );
+ l.Split( n );
+ l.Split( m );
+
+ int i_start = l.Find( m );
+ int i_end = l.Find( n );
+
+ if( i_start > i_end )
+ {
+ l = l.Reverse();
+ i_start = l.Find( m );
+ i_end = l.Find( n );
+ }
+
+ aPre = l.Slice( 0, i_start );
+ aPost = l.Slice( i_end, -1 );
+ aTuned = l.Slice( i_start, i_end );
+
+ aTuned.Simplify();
+}
+
+
+void PNS_MEANDER_PLACER_BASE::tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aElongation )
+{
+ int remaining = aElongation;
+ bool finished = false;
+
+ BOOST_FOREACH( PNS_MEANDER_SHAPE* m, aTuned.Meanders() )
+ {
+ if( m->Type() != MT_CORNER )
+ {
+ if( remaining >= 0 )
+ remaining -= m->MaxTunableLength() - m->BaselineLength();
+
+ if( remaining < 0 )
+ {
+ if( !finished )
+ {
+ PNS_MEANDER_TYPE newType;
+
+ if( m->Type() == MT_START || m->Type() == MT_SINGLE )
+ newType = MT_SINGLE;
+ else
+ newType = MT_FINISH;
+
+ m->SetType( newType );
+ m->Recalculate();
+
+ finished = true;
+ } else {
+ m->MakeEmpty();
+ }
+ }
+ }
+ }
+
+ remaining = aElongation;
+ int meanderCount = 0;
+
+ BOOST_FOREACH(PNS_MEANDER_SHAPE* m, aTuned.Meanders())
+ {
+ if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY )
+ {
+ if(remaining >= 0)
+ {
+ remaining -= m->MaxTunableLength() - m->BaselineLength();
+ meanderCount ++;
+ }
+ }
+ }
+
+ int balance = 0;
+
+ if( meanderCount )
+ balance = -remaining / meanderCount;
+
+ if( balance >= 0 )
+ {
+ BOOST_FOREACH( PNS_MEANDER_SHAPE* m, aTuned.Meanders() )
+ {
+ if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY )
+ {
+ m->Resize( std::max( m->Amplitude() - balance / 2, m_settings.m_minAmplitude ) );
+ }
+ }
+ }
+}
+
+
+const PNS_MEANDER_SETTINGS& PNS_MEANDER_PLACER_BASE::MeanderSettings() const
+{
+ return m_settings;
+}
+
+
+int PNS_MEANDER_PLACER_BASE::compareWithTolerance( int aValue, int aExpected, int aTolerance ) const
+{
+ if( aValue < aExpected - aTolerance )
+ return -1;
+ else if( aValue > aExpected + aTolerance )
+ return 1;
+ else
+ return 0;
+}
diff --git a/pcbnew/router/pns_meander_placer_base.h b/pcbnew/router/pns_meander_placer_base.h
new file mode 100644
index 0000000..070e322
--- /dev/null
+++ b/pcbnew/router/pns_meander_placer_base.h
@@ -0,0 +1,165 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_MEANDER_PLACER_BASE_H
+#define __PNS_MEANDER_PLACER_BASE_H
+
+#include <math/vector2d.h>
+
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+
+#include "pns_node.h"
+#include "pns_via.h"
+#include "pns_line.h"
+#include "pns_placement_algo.h"
+#include "pns_meander.h"
+
+class PNS_ROUTER;
+class PNS_SHOVE;
+class PNS_OPTIMIZER;
+class PNS_ROUTER_BASE;
+
+/**
+ * Class PNS_MEANDER_PLACER_BASE
+ *
+ * Base class for Single trace & Differenial pair meandering tools, as
+ * both of them share a lot of code.
+ */
+class PNS_MEANDER_PLACER_BASE : public PNS_PLACEMENT_ALGO
+{
+public:
+ ///> Result of the length tuning operation
+ enum TUNING_STATUS {
+ TOO_SHORT = 0,
+ TOO_LONG,
+ TUNED
+ };
+
+ PNS_MEANDER_PLACER_BASE( PNS_ROUTER* aRouter );
+ virtual ~PNS_MEANDER_PLACER_BASE();
+
+ /**
+ * Function TuningInfo()
+ *
+ * Returns a string describing the status and length of the
+ * tuned traces.
+ */
+ virtual const wxString TuningInfo() const = 0;
+
+ /**
+ * Function TuningStatus()
+ *
+ * Returns the tuning status (too short, too long, etc.)
+ * of the trace(s) being tuned.
+ */
+ virtual TUNING_STATUS TuningStatus() const = 0;
+
+ /**
+ * Function AmplitudeStep()
+ *
+ * Increases/decreases the current meandering amplitude by one step.
+ * @param aSign direction (negative = decrease, positive = increase).
+ */
+ virtual void AmplitudeStep( int aSign );
+
+ /**
+ * Function SpacingStep()
+ *
+ * Increases/decreases the current meandering spcing by one step.
+ * @param aSign direction (negative = decrease, positive = increase).
+ */
+ virtual void SpacingStep( int aSign );
+
+ /**
+ * Function MeanderSettings()
+ *
+ * Returns the current meandering configuration.
+ * @return the settings
+ */
+ virtual const PNS_MEANDER_SETTINGS& MeanderSettings() const;
+
+ /*
+ * Function UpdateSettings()
+ *
+ * Sets the current meandering configuration.
+ * @param aSettings the settings
+ */
+ virtual void UpdateSettings( const PNS_MEANDER_SETTINGS& aSettings);
+
+ /**
+ * Function CheckFit()
+ *
+ * Checks if it's ok to place the shape aShape (i.e.
+ * if it doesn't cause DRC violations or collide with
+ * other meanders).
+ * @param aShape the shape to check
+ * @return true if the shape fits
+ */
+ virtual bool CheckFit( PNS_MEANDER_SHAPE* aShape )
+ {
+ return false;
+ }
+
+protected:
+
+ /**
+ * Function cutTunedLine()
+ *
+ * Extracts the part of a track to be meandered, depending on the
+ * starting point and the cursor position.
+ * @param aOrigin the original line
+ * @param aTuneStart point where we start meandering (start click coorinates)
+ * @param aCursorPos current cursor position
+ * @param aPre part before the beginning of meanders
+ * @param aTuned part to be meandered
+ * @param aPost part after the end of meanders
+ */
+ void cutTunedLine( const SHAPE_LINE_CHAIN& aOrigin,
+ const VECTOR2I& aTuneStart,
+ const VECTOR2I& aCursorPos,
+ SHAPE_LINE_CHAIN& aPre,
+ SHAPE_LINE_CHAIN& aTuned,
+ SHAPE_LINE_CHAIN& aPost );
+
+ /**
+ * Function tuneLineLength()
+ *
+ * Takes a set of meanders in aTuned and tunes their length to
+ * extend the original line length by aElongation.
+ */
+ void tuneLineLength( PNS_MEANDERED_LINE& aTuned, int aElongation );
+
+ /**
+ * Function compareWithTolerance()
+ *
+ * Compares aValue against aExpected with given tolerance.
+ */
+ int compareWithTolerance ( int aValue, int aExpected, int aTolerance = 0 ) const;
+
+ ///> width of the meandered trace(s)
+ int m_currentWidth;
+ ///> meandering settings
+ PNS_MEANDER_SETTINGS m_settings;
+ ///> current end point
+ VECTOR2I m_currentEnd;
+};
+
+#endif // __PNS_MEANDER_PLACER_BASE_H
diff --git a/pcbnew/router/pns_meander_skew_placer.cpp b/pcbnew/router/pns_meander_skew_placer.cpp
new file mode 100644
index 0000000..3d4626d
--- /dev/null
+++ b/pcbnew/router/pns_meander_skew_placer.cpp
@@ -0,0 +1,174 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+
+#include <base_units.h> // God forgive me doing this...
+#include <colors.h>
+
+#include "trace.h"
+
+#include "pns_node.h"
+#include "pns_itemset.h"
+#include "pns_topology.h"
+#include "pns_meander_skew_placer.h"
+
+#include "pns_router.h"
+
+
+PNS_MEANDER_SKEW_PLACER::PNS_MEANDER_SKEW_PLACER ( PNS_ROUTER* aRouter ) :
+ PNS_MEANDER_PLACER ( aRouter )
+{
+ // Init temporary variables (do not leave uninitialized members)
+ m_coupledLength = 0;
+}
+
+
+PNS_MEANDER_SKEW_PLACER::~PNS_MEANDER_SKEW_PLACER( )
+{
+}
+
+
+bool PNS_MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
+{
+ VECTOR2I p;
+
+ if( !aStartItem || !aStartItem->OfKind( PNS_ITEM::SEGMENT ) )
+ {
+ Router()->SetFailureReason( _( "Please select a differential pair trace you want to tune." ) );
+ return false;
+ }
+
+ m_initialSegment = static_cast<PNS_SEGMENT*>( aStartItem );
+
+ p = m_initialSegment->Seg().NearestPoint( aP );
+
+ m_currentNode = NULL;
+ m_currentStart = p;
+
+ m_world = Router()->GetWorld( )->Branch();
+ m_originLine = m_world->AssembleLine( m_initialSegment );
+
+ PNS_TOPOLOGY topo( m_world );
+ m_tunedPath = topo.AssembleTrivialPath( m_initialSegment );
+
+ if( !topo.AssembleDiffPair ( m_initialSegment, m_originPair ) )
+ {
+ Router()->SetFailureReason( _( "Unable to find complementary differential pair "
+ "net for skew tuning. Make sure the names of the nets belonging "
+ "to a differential pair end with either _N/_P or +/-." ) );
+ return false;
+ }
+
+ if( m_originPair.Gap() < 0 )
+ m_originPair.SetGap( Router()->Sizes().DiffPairGap() );
+
+ if( !m_originPair.PLine().SegmentCount() ||
+ !m_originPair.NLine().SegmentCount() )
+ return false;
+
+ m_tunedPathP = topo.AssembleTrivialPath( m_originPair.PLine().GetLink( 0 ) );
+ m_tunedPathN = topo.AssembleTrivialPath( m_originPair.NLine().GetLink( 0 ) );
+
+ m_world->Remove( &m_originLine );
+
+ m_currentWidth = m_originLine.Width();
+ m_currentEnd = VECTOR2I( 0, 0 );
+
+ if ( m_originPair.PLine().Net() == m_originLine.Net() )
+ m_coupledLength = itemsetLength( m_tunedPathN );
+ else
+ m_coupledLength = itemsetLength( m_tunedPathP );
+
+ return true;
+}
+
+
+int PNS_MEANDER_SKEW_PLACER::origPathLength( ) const
+{
+ return itemsetLength ( m_tunedPath );
+}
+
+
+int PNS_MEANDER_SKEW_PLACER::itemsetLength( const PNS_ITEMSET& aSet ) const
+{
+ int total = 0;
+ BOOST_FOREACH( const PNS_ITEM* item, aSet.CItems() )
+ {
+ if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
+ {
+ total += l->CLine().Length();
+ }
+ }
+
+ return total;
+}
+
+
+int PNS_MEANDER_SKEW_PLACER::currentSkew() const
+{
+ return m_lastLength - m_coupledLength;
+}
+
+
+bool PNS_MEANDER_SKEW_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
+{
+ BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathP.CItems() )
+ {
+ if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
+ Router()->DisplayDebugLine( l->CLine(), 5, 10000 );
+ }
+
+ BOOST_FOREACH( const PNS_ITEM* item, m_tunedPathN.CItems() )
+ {
+ if( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
+ Router()->DisplayDebugLine( l->CLine(), 4, 10000 );
+ }
+
+ return doMove( aP, aEndItem, m_coupledLength + m_settings.m_targetSkew );
+}
+
+
+const wxString PNS_MEANDER_SKEW_PLACER::TuningInfo() const
+{
+ wxString status;
+
+ switch( m_lastStatus )
+ {
+ case TOO_LONG:
+ status = _( "Too long: skew " );
+ break;
+ case TOO_SHORT:
+ status = _( "Too short: skew " );
+ break;
+ case TUNED:
+ status = _( "Tuned: skew " );
+ break;
+ default:
+ return _( "?" );
+ }
+
+ status += LengthDoubleToString( (double) m_lastLength - m_coupledLength, false );
+ status += "/";
+ status += LengthDoubleToString( (double) m_settings.m_targetSkew, false );
+
+ return status;
+}
+
diff --git a/pcbnew/router/pns_meander_skew_placer.h b/pcbnew/router/pns_meander_skew_placer.h
new file mode 100644
index 0000000..7cb303c
--- /dev/null
+++ b/pcbnew/router/pns_meander_skew_placer.h
@@ -0,0 +1,65 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_MEANDER_SKEW_PLACER_H
+#define __PNS_MEANDER_SKEW_PLACER_H
+
+#include "pns_meander_placer.h"
+#include "pns_diff_pair.h"
+
+class PNS_ROUTER;
+class PNS_SHOVE;
+class PNS_OPTIMIZER;
+class PNS_ROUTER_BASE;
+
+/**
+ * Class PNS_MEANDER_SKEW_PLACER
+ *
+ * Differential pair skew adjustment algorithm.
+ */
+class PNS_MEANDER_SKEW_PLACER : public PNS_MEANDER_PLACER
+{
+public:
+ PNS_MEANDER_SKEW_PLACER( PNS_ROUTER* aRouter );
+ ~PNS_MEANDER_SKEW_PLACER();
+
+ /// @copydoc PNS_PLACEMENT_ALGO::Start()
+ bool Start( const VECTOR2I& aP, PNS_ITEM* aStartItem );
+
+ /// @copydoc PNS_PLACEMENT_ALGO::Move()
+ bool Move( const VECTOR2I& aP, PNS_ITEM* aEndItem );
+
+ /// @copydoc PNS_MEANDER_PLACER_BASE::TuningInfo()
+ const wxString TuningInfo() const;
+
+private:
+
+ int currentSkew( ) const;
+ int itemsetLength( const PNS_ITEMSET& aSet ) const;
+
+ int origPathLength () const;
+
+ PNS_DIFF_PAIR m_originPair;
+ PNS_ITEMSET m_tunedPath, m_tunedPathP, m_tunedPathN;
+
+ int m_coupledLength;
+};
+
+#endif // __PNS_MEANDER_SKEW_PLACER_H
diff --git a/pcbnew/router/pns_node.cpp b/pcbnew/router/pns_node.cpp
new file mode 100644
index 0000000..3f9bf12
--- /dev/null
+++ b/pcbnew/router/pns_node.cpp
@@ -0,0 +1,1288 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <vector>
+#include <cassert>
+
+#include <math/vector2d.h>
+
+#include <geometry/seg.h>
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+#include <geometry/shape_index.h>
+
+#include "trace.h"
+#include "pns_item.h"
+#include "pns_line.h"
+#include "pns_node.h"
+#include "pns_via.h"
+#include "pns_solid.h"
+#include "pns_joint.h"
+#include "pns_index.h"
+#include "pns_router.h"
+
+using boost::unordered_set;
+using boost::unordered_map;
+
+#ifdef DEBUG
+static boost::unordered_set<PNS_NODE*> allocNodes;
+#endif
+
+PNS_NODE::PNS_NODE()
+{
+ TRACE( 0, "PNS_NODE::create %p", this );
+ m_depth = 0;
+ m_root = this;
+ m_parent = NULL;
+ m_maxClearance = 800000; // fixme: depends on how thick traces are.
+ m_clearanceFunctor = NULL;
+ m_index = new PNS_INDEX;
+ m_collisionFilter = NULL;
+
+#ifdef DEBUG
+ allocNodes.insert( this );
+#endif
+}
+
+
+PNS_NODE::~PNS_NODE()
+{
+ TRACE( 0, "PNS_NODE::delete %p", this );
+
+ if( !m_children.empty() )
+ {
+ TRACEn( 0, "attempting to free a node that has kids.\n" );
+ assert( false );
+ }
+
+#ifdef DEBUG
+ if( allocNodes.find( this ) == allocNodes.end() )
+ {
+ TRACEn( 0, "attempting to free an already-free'd node.\n" );
+ assert( false );
+ }
+
+ allocNodes.erase( this );
+#endif
+
+ m_joints.clear();
+
+ for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
+ {
+ if( (*i)->BelongsTo( this ) )
+ delete *i;
+ }
+
+ releaseGarbage();
+ unlinkParent();
+
+ delete m_index;
+}
+
+int PNS_NODE::GetClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const
+{
+ if( !m_clearanceFunctor )
+ return 100000;
+
+ return (*m_clearanceFunctor)( aA, aB );
+}
+
+
+PNS_NODE* PNS_NODE::Branch()
+{
+ PNS_NODE* child = new PNS_NODE;
+
+ TRACE( 0, "PNS_NODE::branch %p (parent %p)", child % this );
+
+ m_children.insert( child );
+
+ child->m_depth = m_depth + 1;
+ child->m_parent = this;
+ child->m_clearanceFunctor = m_clearanceFunctor;
+ child->m_root = isRoot() ? this : m_root;
+ child->m_collisionFilter = m_collisionFilter;
+
+ // immmediate offspring of the root branch needs not copy anything.
+ // For the rest, deep-copy joints, overridden item map and pointers
+ // to stored items.
+ if( !isRoot() )
+ {
+ JOINT_MAP::iterator j;
+
+ for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
+ child->m_index->Add( *i );
+
+ child->m_joints = m_joints;
+ child->m_override = m_override;
+ }
+
+ TRACE( 2, "%d items, %d joints, %d overrides",
+ child->m_index->Size() % child->m_joints.size() % child->m_override.size() );
+
+ return child;
+}
+
+
+void PNS_NODE::unlinkParent()
+{
+ if( isRoot() )
+ return;
+
+ m_parent->m_children.erase( this );
+}
+
+
+// function object that visits potential obstacles and performs
+// the actual collision refining
+struct PNS_NODE::OBSTACLE_VISITOR
+{
+ ///> node we are searching in (either root or a branch)
+ PNS_NODE* m_node;
+
+ ///> node that overrides root entries
+ PNS_NODE* m_override;
+
+ ///> list of encountered obstacles
+ OBSTACLES& m_tab;
+
+ ///> the item we are looking for collisions with
+ const PNS_ITEM* m_item;
+
+ ///> acccepted kinds of colliding items (solids, vias, segments, etc...)
+ int m_kindMask;
+
+ ///> max number of hits
+ int m_limitCount;
+
+ ///> number of items found so far
+ int m_matchCount;
+
+ ///> additional clearance
+ int m_extraClearance;
+
+ bool m_differentNetsOnly;
+
+ int m_forceClearance;
+
+ OBSTACLE_VISITOR( PNS_NODE::OBSTACLES& aTab, const PNS_ITEM* aItem, int aKindMask, bool aDifferentNetsOnly ) :
+ m_node( NULL ),
+ m_override( NULL ),
+ m_tab( aTab ),
+ m_item( aItem ),
+ m_kindMask( aKindMask ),
+ m_limitCount( -1 ),
+ m_matchCount( 0 ),
+ m_extraClearance( 0 ),
+ m_differentNetsOnly( aDifferentNetsOnly ),
+ m_forceClearance( -1 )
+ {
+ if( aItem->Kind() == PNS_ITEM::LINE )
+ m_extraClearance += static_cast<const PNS_LINE*>( aItem )->Width() / 2;
+ }
+
+ void SetCountLimit( int aLimit )
+ {
+ m_limitCount = aLimit;
+ }
+
+ void SetWorld( PNS_NODE* aNode, PNS_NODE* aOverride = NULL )
+ {
+ m_node = aNode;
+ m_override = aOverride;
+ }
+
+ bool operator()( PNS_ITEM* aItem )
+ {
+ if( !aItem->OfKind( m_kindMask ) )
+ return true;
+
+ // check if there is a more recent branch with a newer
+ // (possibily modified) version of this item.
+ if( m_override && m_override->overrides( aItem ) )
+ return true;
+
+ int clearance = m_extraClearance + m_node->GetClearance( aItem, m_item );
+
+ if( m_node->m_collisionFilter && (*m_node->m_collisionFilter)( aItem, m_item ) )
+ return true;
+
+ if( aItem->Kind() == PNS_ITEM::LINE )
+ clearance += static_cast<PNS_LINE*>( aItem )->Width() / 2;
+
+ if( m_forceClearance >= 0 )
+ clearance = m_forceClearance;
+
+ if( !aItem->Collide( m_item, clearance, m_differentNetsOnly ) )
+ return true;
+
+ PNS_OBSTACLE obs;
+
+ obs.m_item = aItem;
+ obs.m_head = m_item;
+ m_tab.push_back( obs );
+
+ m_matchCount++;
+
+ if( m_limitCount > 0 && m_matchCount >= m_limitCount )
+ return false;
+
+ return true;
+ };
+};
+
+
+int PNS_NODE::QueryColliding( const PNS_ITEM* aItem,
+ PNS_NODE::OBSTACLES& aObstacles, int aKindMask, int aLimitCount, bool aDifferentNetsOnly, int aForceClearance )
+{
+ OBSTACLE_VISITOR visitor( aObstacles, aItem, aKindMask, aDifferentNetsOnly );
+
+#ifdef DEBUG
+ assert( allocNodes.find( this ) != allocNodes.end() );
+#endif
+
+ visitor.SetCountLimit( aLimitCount );
+ visitor.SetWorld( this, NULL );
+ visitor.m_forceClearance = aForceClearance;
+ // first, look for colliding items in the local index
+ m_index->Query( aItem, m_maxClearance, visitor );
+
+ // if we haven't found enough items, look in the root branch as well.
+ if( !isRoot() && ( visitor.m_matchCount < aLimitCount || aLimitCount < 0 ) )
+ {
+ visitor.SetWorld( m_root, this );
+ m_root->m_index->Query( aItem, m_maxClearance, visitor );
+ }
+
+ return aObstacles.size();
+}
+
+
+PNS_NODE::OPT_OBSTACLE PNS_NODE::NearestObstacle( const PNS_LINE* aItem,
+ int aKindMask,
+ const std::set<PNS_ITEM*>* aRestrictedSet )
+{
+ OBSTACLES obs_list;
+ bool found_isects = false;
+
+ const SHAPE_LINE_CHAIN& line = aItem->CLine();
+
+ obs_list.reserve( 100 );
+
+ int n = 0;
+
+ for( int i = 0; i < line.SegmentCount(); i++ )
+ {
+ const PNS_SEGMENT s( *aItem, line.CSegment( i ) );
+ n += QueryColliding( &s, obs_list, aKindMask );
+ }
+
+ if( aItem->EndsWithVia() )
+ n += QueryColliding( &aItem->Via(), obs_list, aKindMask );
+
+ if( !n )
+ return OPT_OBSTACLE();
+
+ PNS_LINE& aLine = (PNS_LINE&) *aItem;
+
+ PNS_OBSTACLE nearest;
+ nearest.m_item = NULL;
+ nearest.m_distFirst = INT_MAX;
+
+ BOOST_FOREACH( PNS_OBSTACLE obs, obs_list )
+ {
+ VECTOR2I ip_first, ip_last;
+ int dist_max = INT_MIN;
+
+ if( aRestrictedSet && aRestrictedSet->find( obs.m_item ) == aRestrictedSet->end() )
+ continue;
+
+ std::vector<SHAPE_LINE_CHAIN::INTERSECTION> isect_list;
+
+ int clearance = GetClearance( obs.m_item, &aLine );
+
+ SHAPE_LINE_CHAIN hull = obs.m_item->Hull( clearance, aItem->Width() );
+
+ if( aLine.EndsWithVia() )
+ {
+ int clearance = GetClearance( obs.m_item, &aLine.Via() );
+
+ SHAPE_LINE_CHAIN viaHull = aLine.Via().Hull( clearance, aItem->Width() );
+
+ viaHull.Intersect( hull, isect_list );
+
+ BOOST_FOREACH( SHAPE_LINE_CHAIN::INTERSECTION isect, isect_list )
+ {
+ int dist = aLine.CLine().Length() +
+ ( isect.p - aLine.Via().Pos() ).EuclideanNorm();
+
+ if( dist < nearest.m_distFirst )
+ {
+ found_isects = true;
+ nearest.m_distFirst = dist;
+ nearest.m_ipFirst = isect.p;
+ nearest.m_item = obs.m_item;
+ nearest.m_hull = hull;
+ }
+
+ if( dist > dist_max )
+ {
+ dist_max = dist;
+ ip_last = isect.p;
+ }
+ }
+ }
+
+ isect_list.clear();
+
+ hull.Intersect( aLine.CLine(), isect_list );
+
+ BOOST_FOREACH( SHAPE_LINE_CHAIN::INTERSECTION isect, isect_list )
+ {
+ int dist = aLine.CLine().PathLength( isect.p );
+
+ if( dist < nearest.m_distFirst )
+ {
+ found_isects = true;
+ nearest.m_distFirst = dist;
+ nearest.m_ipFirst = isect.p;
+ nearest.m_item = obs.m_item;
+ nearest.m_hull = hull;
+ }
+
+ if( dist > dist_max )
+ {
+ dist_max = dist;
+ ip_last = isect.p;
+ }
+ }
+
+ nearest.m_ipLast = ip_last;
+ nearest.m_distLast = dist_max;
+ }
+
+ if( !found_isects )
+ nearest.m_item = obs_list[0].m_item;
+
+ return nearest;
+}
+
+
+PNS_NODE::OPT_OBSTACLE PNS_NODE::CheckColliding( const PNS_ITEMSET& aSet, int aKindMask )
+{
+ BOOST_FOREACH( const PNS_ITEM* item, aSet.CItems() )
+ {
+ OPT_OBSTACLE obs = CheckColliding( item, aKindMask );
+
+ if( obs )
+ return obs;
+ }
+
+ return OPT_OBSTACLE();
+}
+
+
+PNS_NODE::OPT_OBSTACLE PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, int aKindMask )
+{
+ OBSTACLES obs;
+
+ obs.reserve( 100 );
+
+ if( aItemA->Kind() == PNS_ITEM::LINE )
+ {
+ int n = 0;
+ const PNS_LINE* line = static_cast<const PNS_LINE*>( aItemA );
+ const SHAPE_LINE_CHAIN& l = line->CLine();
+
+ for( int i = 0; i < l.SegmentCount(); i++ )
+ {
+ const PNS_SEGMENT s( *line, l.CSegment( i ) );
+ n += QueryColliding( &s, obs, aKindMask, 1 );
+
+ if( n )
+ return OPT_OBSTACLE( obs[0] );
+ }
+
+ if( line->EndsWithVia() )
+ {
+ n += QueryColliding( &line->Via(), obs, aKindMask, 1 );
+
+ if( n )
+ return OPT_OBSTACLE( obs[0] );
+ }
+ }
+ else if( QueryColliding( aItemA, obs, aKindMask, 1 ) > 0 )
+ return OPT_OBSTACLE( obs[0] );
+
+ return OPT_OBSTACLE();
+}
+
+
+bool PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, const PNS_ITEM* aItemB, int aKindMask, int aForceClearance )
+{
+ assert( aItemB );
+ int clearance;
+ if( aForceClearance >= 0 )
+ clearance = aForceClearance;
+ else
+ clearance = GetClearance( aItemA, aItemB );
+
+ // fixme: refactor
+ if( aItemA->Kind() == PNS_ITEM::LINE )
+ clearance += static_cast<const PNS_LINE*>( aItemA )->Width() / 2;
+ if( aItemB->Kind() == PNS_ITEM::LINE )
+ clearance += static_cast<const PNS_LINE*>( aItemB )->Width() / 2;
+
+ return aItemA->Collide( aItemB, clearance );
+}
+
+
+struct HIT_VISITOR
+{
+ PNS_ITEMSET& m_items;
+ const VECTOR2I& m_point;
+ const PNS_NODE* m_world;
+
+ HIT_VISITOR( PNS_ITEMSET& aTab, const VECTOR2I& aPoint, const PNS_NODE* aWorld ) :
+ m_items( aTab ), m_point( aPoint ), m_world( aWorld )
+ {}
+
+ bool operator()( PNS_ITEM* aItem )
+ {
+ SHAPE_CIRCLE cp( m_point, 0 );
+
+ int cl = 0;
+
+ if( aItem->Shape()->Collide( &cp, cl ) )
+ m_items.Add( aItem );
+
+ return true;
+ }
+};
+
+
+const PNS_ITEMSET PNS_NODE::HitTest( const VECTOR2I& aPoint ) const
+{
+ PNS_ITEMSET items;
+
+ // fixme: we treat a point as an infinitely small circle - this is inefficient.
+ SHAPE_CIRCLE s( aPoint, 0 );
+ HIT_VISITOR visitor( items, aPoint, this );
+
+ m_index->Query( &s, m_maxClearance, visitor );
+
+ if( !isRoot() ) // fixme: could be made cleaner
+ {
+ PNS_ITEMSET items_root;
+ HIT_VISITOR visitor_root( items_root, aPoint, m_root );
+ m_root->m_index->Query( &s, m_maxClearance, visitor_root );
+
+ BOOST_FOREACH( PNS_ITEM* item, items_root.Items() )
+ {
+ if( !overrides( item ) )
+ items.Add( item );
+ }
+ }
+
+ return items;
+}
+
+
+void PNS_NODE::addSolid( PNS_SOLID* aSolid )
+{
+ linkJoint( aSolid->Pos(), aSolid->Layers(), aSolid->Net(), aSolid );
+ m_index->Add( aSolid );
+}
+
+
+void PNS_NODE::addVia( PNS_VIA* aVia )
+{
+ linkJoint( aVia->Pos(), aVia->Layers(), aVia->Net(), aVia );
+ m_index->Add( aVia );
+}
+
+
+void PNS_NODE::addLine( PNS_LINE* aLine, bool aAllowRedundant )
+{
+ SHAPE_LINE_CHAIN& l = aLine->Line();
+
+ for( int i = 0; i < l.SegmentCount(); i++ )
+ {
+ SEG s = l.CSegment( i );
+
+ if( s.A != s.B )
+ {
+ PNS_SEGMENT* pseg = new PNS_SEGMENT( *aLine, s );
+ PNS_SEGMENT* psegR = NULL;
+
+ if( !aAllowRedundant )
+ psegR = findRedundantSegment( pseg );
+
+ if( psegR )
+ {
+ aLine->LinkSegment( psegR );
+
+ delete pseg;
+ }
+ else
+ {
+ pseg->SetOwner( this );
+
+ linkJoint( s.A, pseg->Layers(), aLine->Net(), pseg );
+ linkJoint( s.B, pseg->Layers(), aLine->Net(), pseg );
+
+ aLine->LinkSegment( pseg );
+
+ m_index->Add( pseg );
+ }
+ }
+ }
+}
+
+
+void PNS_NODE::addSegment( PNS_SEGMENT* aSeg, bool aAllowRedundant )
+{
+ if( aSeg->Seg().A == aSeg->Seg().B )
+ {
+ TRACEn( 0, "attempting to add a segment with same end coordinates, ignoring." )
+ return;
+ }
+
+ if( !aAllowRedundant && findRedundantSegment ( aSeg ) )
+ return;
+
+ aSeg->SetOwner( this );
+
+ linkJoint( aSeg->Seg().A, aSeg->Layers(), aSeg->Net(), aSeg );
+ linkJoint( aSeg->Seg().B, aSeg->Layers(), aSeg->Net(), aSeg );
+
+ m_index->Add( aSeg );
+}
+
+
+void PNS_NODE::Add( PNS_ITEM* aItem, bool aAllowRedundant )
+{
+ aItem->SetOwner( this );
+
+ switch( aItem->Kind() )
+ {
+ case PNS_ITEM::SOLID:
+ addSolid( static_cast<PNS_SOLID*>( aItem ) );
+ break;
+
+ case PNS_ITEM::SEGMENT:
+ addSegment( static_cast<PNS_SEGMENT*>( aItem ), aAllowRedundant );
+ break;
+
+ case PNS_ITEM::LINE:
+ addLine( static_cast<PNS_LINE*>( aItem ), aAllowRedundant );
+ break;
+
+ case PNS_ITEM::VIA:
+ addVia( static_cast<PNS_VIA*>( aItem ) );
+ break;
+
+ default:
+ assert( false );
+ }
+}
+
+
+void PNS_NODE::doRemove( PNS_ITEM* aItem )
+{
+ // case 1: removing an item that is stored in the root node from any branch:
+ // mark it as overridden, but do not remove
+ if( aItem->BelongsTo( m_root ) && !isRoot() )
+ m_override.insert( aItem );
+
+ // case 2: the item belongs to this branch or a parent, non-root branch,
+ // or the root itself and we are the root: remove from the index
+ else if( !aItem->BelongsTo( m_root ) || isRoot() )
+ m_index->Remove( aItem );
+
+ // the item belongs to this particular branch: un-reference it
+ if( aItem->BelongsTo( this ) )
+ {
+ aItem->SetOwner( NULL );
+ m_root->m_garbageItems.insert( aItem );
+ }
+}
+
+
+void PNS_NODE::removeSegment( PNS_SEGMENT* aSeg )
+{
+ unlinkJoint( aSeg->Seg().A, aSeg->Layers(), aSeg->Net(), aSeg );
+ unlinkJoint( aSeg->Seg().B, aSeg->Layers(), aSeg->Net(), aSeg );
+
+ doRemove( aSeg );
+}
+
+
+void PNS_NODE::removeLine( PNS_LINE* aLine )
+{
+ std::vector<PNS_SEGMENT*>* segRefs = aLine->LinkedSegments();
+
+ assert( segRefs != NULL );
+
+ BOOST_FOREACH( PNS_SEGMENT* seg, *segRefs )
+ {
+ removeSegment( seg );
+ }
+}
+
+void PNS_NODE::removeVia( PNS_VIA* aVia )
+{
+ // We have to split a single joint (associated with a via, binding together multiple layers)
+ // into multiple independent joints. As I'm a lazy bastard, I simply delete the via and all its links and re-insert them.
+
+ PNS_JOINT::HASH_TAG tag;
+
+ VECTOR2I p( aVia->Pos() );
+ PNS_LAYERSET vLayers( aVia->Layers() );
+ int net = aVia->Net();
+
+ PNS_JOINT* jt = FindJoint( p, vLayers.Start(), net );
+ PNS_JOINT::LINKED_ITEMS links( jt->LinkList() );
+
+ tag.net = net;
+ tag.pos = p;
+
+ bool split;
+ do
+ {
+ split = false;
+ std::pair<JOINT_MAP::iterator, JOINT_MAP::iterator> range = m_joints.equal_range( tag );
+
+ if( range.first == m_joints.end() )
+ break;
+
+ // find and remove all joints containing the via to be removed
+
+ for( JOINT_MAP::iterator f = range.first; f != range.second; ++f )
+ {
+ if( aVia->LayersOverlap ( &f->second ) )
+ {
+ m_joints.erase( f );
+ split = true;
+ break;
+ }
+ }
+ } while( split );
+
+ // and re-link them, using the former via's link list
+ BOOST_FOREACH(PNS_ITEM* item, links)
+ {
+ if( item != aVia )
+ linkJoint ( p, item->Layers(), net, item );
+ }
+
+ doRemove( aVia );
+}
+
+
+void PNS_NODE::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem )
+{
+ Remove( aOldItem );
+ Add( aNewItem );
+}
+
+
+void PNS_NODE::Remove( PNS_ITEM* aItem )
+{
+ switch( aItem->Kind() )
+ {
+ case PNS_ITEM::SOLID:
+ // fixme: this fucks up the joints, but it's only used for marking colliding obstacles for the moment, so we don't care.
+ doRemove( aItem );
+ break;
+
+ case PNS_ITEM::SEGMENT:
+ removeSegment( static_cast<PNS_SEGMENT*>( aItem ) );
+ break;
+
+ case PNS_ITEM::LINE:
+ removeLine( static_cast<PNS_LINE*>( aItem ) );
+ break;
+
+ case PNS_ITEM::VIA:
+ removeVia( static_cast<PNS_VIA*>( aItem ) );
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void PNS_NODE::Remove( PNS_LINE& aLine )
+{
+ removeLine( &aLine );
+}
+
+
+void PNS_NODE::followLine( PNS_SEGMENT* aCurrent, bool aScanDirection, int& aPos,
+ int aLimit, VECTOR2I* aCorners, PNS_SEGMENT** aSegments, bool& aGuardHit,
+ bool aStopAtLockedJoints )
+{
+ bool prevReversed = false;
+
+ const VECTOR2I guard = aScanDirection ? aCurrent->Seg().B : aCurrent->Seg().A;
+
+ for( int count = 0 ; ; ++count )
+ {
+ const VECTOR2I p =
+ ( aScanDirection ^ prevReversed ) ? aCurrent->Seg().B : aCurrent->Seg().A;
+ const PNS_JOINT* jt = FindJoint( p, aCurrent );
+
+ assert( jt );
+
+ aCorners[aPos] = jt->Pos();
+ aSegments[aPos] = aCurrent;
+ aPos += ( aScanDirection ? 1 : -1 );
+
+ if( count && guard == p)
+ {
+ aSegments[aPos] = NULL;
+ aGuardHit = true;
+ break;
+ }
+
+ bool locked = aStopAtLockedJoints ? jt->IsLocked() : false;
+
+ if( locked || !jt->IsLineCorner() || aPos < 0 || aPos == aLimit )
+ break;
+
+ aCurrent = jt->NextSegment( aCurrent );
+
+ prevReversed =
+ ( jt->Pos() == ( aScanDirection ? aCurrent->Seg().B : aCurrent->Seg().A ) );
+ }
+}
+
+
+const PNS_LINE PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex, bool aStopAtLockedJoints )
+{
+ const int MaxVerts = 1024 * 16;
+
+ VECTOR2I corners[MaxVerts + 1];
+ PNS_SEGMENT* segs[MaxVerts + 1];
+
+ PNS_LINE pl;
+ bool guardHit = false;
+
+ int i_start = MaxVerts / 2, i_end = i_start + 1;
+
+ pl.SetWidth( aSeg->Width() );
+ pl.SetLayers( aSeg->Layers() );
+ pl.SetNet( aSeg->Net() );
+ pl.SetOwner( this );
+
+ followLine( aSeg, false, i_start, MaxVerts, corners, segs, guardHit, aStopAtLockedJoints );
+
+ if( !guardHit )
+ followLine( aSeg, true, i_end, MaxVerts, corners, segs, guardHit, aStopAtLockedJoints );
+
+ int n = 0;
+
+ PNS_SEGMENT* prev_seg = NULL;
+ bool originSet = false;
+
+ for( int i = i_start + 1; i < i_end; i++ )
+ {
+ const VECTOR2I& p = corners[i];
+
+ pl.Line().Append( p );
+
+ if( segs[i] && prev_seg != segs[i] )
+ {
+ pl.LinkSegment( segs[i] );
+
+ // latter condition to avoid loops
+ if( segs[i] == aSeg && aOriginSegmentIndex && !originSet )
+ {
+ *aOriginSegmentIndex = n;
+ originSet = true;
+ }
+ n++;
+ }
+
+ prev_seg = segs[i];
+ }
+
+ assert( pl.SegmentCount() != 0 );
+
+ return pl;
+}
+
+
+void PNS_NODE::FindLineEnds( const PNS_LINE& aLine, PNS_JOINT& aA, PNS_JOINT& aB )
+{
+ aA = *FindJoint( aLine.CPoint( 0 ), &aLine );
+ aB = *FindJoint( aLine.CPoint( -1 ), &aLine );
+}
+
+
+#if 0
+void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*>& aFoundJoints )
+{
+ std::deque<PNS_JOINT*> searchQueue;
+ std::set<PNS_JOINT*> processed;
+
+ searchQueue.push_back( aStart );
+ processed.insert( aStart );
+
+ while( !searchQueue.empty() )
+ {
+ PNS_JOINT* current = searchQueue.front();
+ searchQueue.pop_front();
+
+ BOOST_FOREACH( PNS_ITEM* item, current->LinkList() )
+ {
+ if ( item->OfKind( PNS_ITEM::SEGMENT ) )
+ {
+ PNS_SEGMENT* seg = static_cast<PNS_SEGMENT *>( item );
+ PNS_JOINT* a = FindJoint( seg->Seg().A, seg );
+ PNS_JOINT* b = FindJoint( seg->Seg().B, seg );
+ PNS_JOINT* next = ( *a == *current ) ? b : a;
+
+ if( processed.find( next ) == processed.end() )
+ {
+ processed.insert( next );
+ searchQueue.push_back( next );
+ }
+ }
+ }
+ }
+
+ BOOST_FOREACH(PNS_JOINT* jt, processed)
+ aFoundJoints.push_back( jt );
+}
+#endif
+
+
+int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& aA, PNS_JOINT& aB, std::vector<PNS_LINE>& aLines )
+{
+ BOOST_FOREACH( PNS_ITEM* item, aA.LinkList() )
+ {
+ if( item->Kind() == PNS_ITEM::SEGMENT )
+ {
+ PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( item );
+ PNS_LINE line = AssembleLine( seg );
+
+ if ( !line.Layers().Overlaps( aB.Layers() ) )
+ continue;
+
+ PNS_JOINT j_start, j_end;
+
+ FindLineEnds( line, j_start, j_end );
+
+ int id_start = line.CLine().Find( aA.Pos() );
+ int id_end = line.CLine().Find( aB.Pos() );
+
+ if( id_end < id_start )
+ std::swap( id_end, id_start );
+
+ if( id_start >= 0 && id_end >= 0 )
+ {
+ line.ClipVertexRange( id_start, id_end );
+ aLines.push_back( line );
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+PNS_JOINT* PNS_NODE::FindJoint( const VECTOR2I& aPos, int aLayer, int aNet )
+{
+ PNS_JOINT::HASH_TAG tag;
+
+ tag.net = aNet;
+ tag.pos = aPos;
+
+ JOINT_MAP::iterator f = m_joints.find( tag ), end = m_joints.end();
+
+ if( f == end && !isRoot() )
+ {
+ end = m_root->m_joints.end();
+ f = m_root->m_joints.find( tag ); // m_root->FindJoint(aPos, aLayer, aNet);
+ }
+
+ if( f == end )
+ return NULL;
+
+ while( f != end )
+ {
+ if( f->second.Layers().Overlaps( aLayer ) )
+ return &f->second;
+
+ ++f;
+ }
+
+ return NULL;
+}
+
+
+void PNS_NODE::LockJoint( const VECTOR2I& aPos, const PNS_ITEM* aItem, bool aLock )
+{
+ PNS_JOINT& jt = touchJoint( aPos, aItem->Layers(), aItem->Net() );
+ jt.Lock( aLock );
+}
+
+
+PNS_JOINT& PNS_NODE::touchJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, int aNet )
+{
+ PNS_JOINT::HASH_TAG tag;
+
+ tag.pos = aPos;
+ tag.net = aNet;
+
+ // try to find the joint in this node.
+ JOINT_MAP::iterator f = m_joints.find( tag );
+
+ std::pair<JOINT_MAP::iterator, JOINT_MAP::iterator> range;
+
+ // not found and we are not root? find in the root and copy results here.
+ if( f == m_joints.end() && !isRoot() )
+ {
+ range = m_root->m_joints.equal_range( tag );
+
+ for( f = range.first; f != range.second; ++f )
+ m_joints.insert( *f );
+ }
+
+ // now insert and combine overlapping joints
+ PNS_JOINT jt( aPos, aLayers, aNet );
+
+ bool merged;
+
+ do
+ {
+ merged = false;
+ range = m_joints.equal_range( tag );
+
+ if( range.first == m_joints.end() )
+ break;
+
+ for( f = range.first; f != range.second; ++f )
+ {
+ if( aLayers.Overlaps( f->second.Layers() ) )
+ {
+ jt.Merge( f->second );
+ m_joints.erase( f );
+ merged = true;
+ break;
+ }
+ }
+ }
+ while( merged );
+
+ return m_joints.insert( TagJointPair( tag, jt ) )->second;
+}
+
+
+void PNS_JOINT::Dump() const
+{
+ printf( "joint layers %d-%d, net %d, pos %s, links: %d\n", m_layers.Start(),
+ m_layers.End(), m_tag.net, m_tag.pos.Format().c_str(), LinkCount() );
+}
+
+
+void PNS_NODE::linkJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers,
+ int aNet, PNS_ITEM* aWhere )
+{
+ PNS_JOINT& jt = touchJoint( aPos, aLayers, aNet );
+
+ jt.Link( aWhere );
+}
+
+
+void PNS_NODE::unlinkJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers,
+ int aNet, PNS_ITEM* aWhere )
+{
+ // fixme: remove dangling joints
+ PNS_JOINT& jt = touchJoint( aPos, aLayers, aNet );
+
+ jt.Unlink( aWhere );
+}
+
+
+void PNS_NODE::Dump( bool aLong )
+{
+#if 0
+ boost::unordered_set<PNS_SEGMENT*> all_segs;
+ SHAPE_INDEX_LIST<PNS_ITEM*>::iterator i;
+
+ for( i = m_items.begin(); i != m_items.end(); i++ )
+ {
+ if( (*i)->GetKind() == PNS_ITEM::SEGMENT )
+ all_segs.insert( static_cast<PNS_SEGMENT*>( *i ) );
+ }
+
+ if( !isRoot() )
+ {
+ for( i = m_root->m_items.begin(); i != m_root->m_items.end(); i++ )
+ {
+ if( (*i)->GetKind() == PNS_ITEM::SEGMENT && !overrides( *i ) )
+ all_segs.insert( static_cast<PNS_SEGMENT*>(*i) );
+ }
+ }
+
+ JOINT_MAP::iterator j;
+
+ if( aLong )
+ for( j = m_joints.begin(); j != m_joints.end(); ++j )
+ {
+ printf( "joint : %s, links : %d\n",
+ j->second.GetPos().Format().c_str(), j->second.LinkCount() );
+ PNS_JOINT::LINKED_ITEMS::const_iterator k;
+
+ for( k = j->second.GetLinkList().begin(); k != j->second.GetLinkList().end(); ++k )
+ {
+ const PNS_ITEM* m_item = *k;
+
+ switch( m_item->GetKind() )
+ {
+ case PNS_ITEM::SEGMENT:
+ {
+ const PNS_SEGMENT* seg = static_cast<const PNS_SEGMENT*>( m_item );
+ printf( " -> seg %s %s\n", seg->GetSeg().A.Format().c_str(),
+ seg->GetSeg().B.Format().c_str() );
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ }
+
+
+ int lines_count = 0;
+
+ while( !all_segs.empty() )
+ {
+ PNS_SEGMENT* s = *all_segs.begin();
+ PNS_LINE* l = AssembleLine( s );
+
+ PNS_LINE::LinkedSegments* seg_refs = l->GetLinkedSegments();
+
+ if( aLong )
+ printf( "Line: %s, net %d ", l->GetLine().Format().c_str(), l->GetNet() );
+
+ for( std::vector<PNS_SEGMENT*>::iterator j = seg_refs->begin(); j != seg_refs->end(); ++j )
+ {
+ printf( "%s ", (*j)->GetSeg().A.Format().c_str() );
+
+ if( j + 1 == seg_refs->end() )
+ printf( "%s\n", (*j)->GetSeg().B.Format().c_str() );
+
+ all_segs.erase( *j );
+ }
+
+ lines_count++;
+ }
+
+ printf( "Local joints: %d, lines : %d \n", m_joints.size(), lines_count );
+#endif
+}
+
+
+void PNS_NODE::GetUpdatedItems( ITEM_VECTOR& aRemoved, ITEM_VECTOR& aAdded )
+{
+ aRemoved.reserve( m_override.size() );
+ aAdded.reserve( m_index->Size() );
+
+ if( isRoot() )
+ return;
+
+ BOOST_FOREACH( PNS_ITEM* item, m_override )
+ aRemoved.push_back( item );
+
+ for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
+ aAdded.push_back( *i );
+}
+
+void PNS_NODE::releaseChildren()
+{
+ // copy the kids as the PNS_NODE destructor erases the item from the parent node.
+ std::set<PNS_NODE*> kids = m_children;
+
+ BOOST_FOREACH( PNS_NODE* node, kids )
+ {
+ node->releaseChildren();
+ delete node;
+ }
+}
+
+
+void PNS_NODE::releaseGarbage()
+{
+ if( !isRoot() )
+ return;
+
+ BOOST_FOREACH( PNS_ITEM* item, m_garbageItems )
+ {
+ if( !item->BelongsTo( this ) )
+ delete item;
+ }
+
+ m_garbageItems.clear();
+}
+
+
+void PNS_NODE::Commit( PNS_NODE* aNode )
+{
+ if( aNode->isRoot() )
+ return;
+
+ BOOST_FOREACH( PNS_ITEM* item, aNode->m_override )
+ Remove( item );
+
+ for( PNS_INDEX::ITEM_SET::iterator i = aNode->m_index->begin();
+ i != aNode->m_index->end(); ++i )
+ {
+ (*i)->SetRank( -1 );
+ (*i)->Unmark();
+ Add( *i );
+ }
+
+ releaseChildren();
+ releaseGarbage();
+}
+
+
+void PNS_NODE::KillChildren()
+{
+ assert( isRoot() );
+ releaseChildren();
+}
+
+
+void PNS_NODE::AllItemsInNet( int aNet, std::set<PNS_ITEM*>& aItems )
+{
+ PNS_INDEX::NET_ITEMS_LIST* l_cur = m_index->GetItemsForNet( aNet );
+
+ if( l_cur )
+ {
+ BOOST_FOREACH( PNS_ITEM*item, *l_cur )
+ aItems.insert( item );
+ }
+
+ if( !isRoot() )
+ {
+ PNS_INDEX::NET_ITEMS_LIST* l_root = m_root->m_index->GetItemsForNet( aNet );
+
+ if( l_root )
+ for( PNS_INDEX::NET_ITEMS_LIST::iterator i = l_root->begin(); i!= l_root->end(); ++i )
+ if( !overrides( *i ) )
+ aItems.insert( *i );
+ }
+}
+
+
+void PNS_NODE::ClearRanks( int aMarkerMask )
+{
+ for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
+ {
+ (*i)->SetRank( -1 );
+ (*i)->Mark( (*i)->Marker() & (~aMarkerMask) );
+ }
+}
+
+
+int PNS_NODE::FindByMarker( int aMarker, PNS_ITEMSET& aItems )
+{
+ for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
+ {
+ if( (*i)->Marker() & aMarker )
+ aItems.Add( *i );
+ }
+
+ return 0;
+}
+
+
+int PNS_NODE::RemoveByMarker( int aMarker )
+{
+ std::list<PNS_ITEM*> garbage;
+
+ for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
+ {
+ if ( (*i)->Marker() & aMarker )
+ {
+ garbage.push_back( *i );
+ }
+ }
+
+ for( std::list<PNS_ITEM*>::const_iterator i = garbage.begin(), end = garbage.end(); i != end; ++i )
+ {
+ Remove( *i );
+ }
+
+ return 0;
+}
+
+
+PNS_SEGMENT* PNS_NODE::findRedundantSegment( PNS_SEGMENT* aSeg )
+{
+ PNS_JOINT* jtStart = FindJoint ( aSeg->Seg().A, aSeg );
+
+ if( !jtStart )
+ return NULL;
+
+ BOOST_FOREACH( PNS_ITEM* item, jtStart->LinkList() )
+ {
+ if( item->OfKind( PNS_ITEM::SEGMENT ) )
+ {
+ PNS_SEGMENT* seg2 = (PNS_SEGMENT*) item;
+
+ const VECTOR2I a1( aSeg->Seg().A );
+ const VECTOR2I b1( aSeg->Seg().B );
+
+ const VECTOR2I a2( seg2->Seg().A );
+ const VECTOR2I b2( seg2->Seg().B );
+
+ if( seg2->Layers().Start() == aSeg->Layers().Start() &&
+ ( ( a1 == a2 && b1 == b2 ) || ( a1 == b2 && a2 == b1 ) ) )
+ return seg2;
+ }
+ }
+
+ return NULL;
+}
+
+
+void PNS_NODE::SetCollisionFilter( PNS_COLLISION_FILTER* aFilter )
+{
+ m_collisionFilter = aFilter;
+}
+
+
+PNS_ITEM *PNS_NODE::FindItemByParent( const BOARD_CONNECTED_ITEM* aParent )
+{
+ PNS_INDEX::NET_ITEMS_LIST* l_cur = m_index->GetItemsForNet( aParent->GetNetCode() );
+
+ BOOST_FOREACH( PNS_ITEM*item, *l_cur )
+ if( item->Parent() == aParent )
+ return item;
+
+ return NULL;
+}
diff --git a/pcbnew/router/pns_node.h b/pcbnew/router/pns_node.h
new file mode 100644
index 0000000..9846da8
--- /dev/null
+++ b/pcbnew/router/pns_node.h
@@ -0,0 +1,487 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_NODE_H
+#define __PNS_NODE_H
+
+#include <vector>
+#include <list>
+
+#include <boost/unordered_set.hpp>
+#include <boost/unordered_map.hpp>
+#include <boost/optional.hpp>
+
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+#include <geometry/shape_index.h>
+
+#include "pns_item.h"
+#include "pns_joint.h"
+#include "pns_itemset.h"
+
+class PNS_SEGMENT;
+class PNS_LINE;
+class PNS_SOLID;
+class PNS_VIA;
+class PNS_RATSNEST;
+class PNS_INDEX;
+class PNS_ROUTER;
+
+/**
+ * Class PNS_CLEARANCE_FUNC
+ *
+ * An abstract function object, returning a required clearance between two items.
+ **/
+class PNS_CLEARANCE_FUNC
+{
+public:
+ virtual ~PNS_CLEARANCE_FUNC() {}
+ virtual int operator()( const PNS_ITEM* aA, const PNS_ITEM* aB ) = 0;
+ virtual void OverrideClearance (bool aEnable, int aNetA = 0, int aNetB = 0, int aClearance = 0) = 0;
+};
+
+class PNS_PCBNEW_CLEARANCE_FUNC : public PNS_CLEARANCE_FUNC
+{
+public:
+ PNS_PCBNEW_CLEARANCE_FUNC( PNS_ROUTER *aRouter );
+ virtual ~PNS_PCBNEW_CLEARANCE_FUNC();
+
+ virtual int operator()( const PNS_ITEM* aA, const PNS_ITEM* aB );
+ virtual void OverrideClearance (bool aEnable, int aNetA = 0, int aNetB = 0, int aClearance = 0);
+
+ void UseDpGap( bool aUseDpGap ) { m_useDpGap = aUseDpGap; }
+
+private:
+ struct CLEARANCE_ENT {
+ int coupledNet;
+ int clearance;
+ };
+
+ PNS_ROUTER *m_router;
+
+ int localPadClearance( const PNS_ITEM* aItem ) const;
+ std::vector<CLEARANCE_ENT> m_clearanceCache;
+ int m_defaultClearance;
+ bool m_overrideEnabled;
+ int m_overrideNetA, m_overrideNetB;
+ int m_overrideClearance;
+ bool m_useDpGap;
+};
+
+/**
+ * Struct PNS_OBSTACLE
+ *
+ * Holds an object colliding with another object, along with
+ * some useful data about the collision.
+ **/
+struct PNS_OBSTACLE
+{
+ ///> Item we search collisions with
+ const PNS_ITEM* m_head;
+
+ ///> Item found to be colliding with m_head
+ PNS_ITEM* m_item;
+
+ ///> Hull of the colliding m_item
+ SHAPE_LINE_CHAIN m_hull;
+
+ ///> First and last intersection point between the head item and the hull
+ ///> of the colliding m_item
+ VECTOR2I m_ipFirst, m_ipLast;
+
+ ///> ... and the distance thereof
+ int m_distFirst, m_distLast;
+};
+
+/**
+ * Struct PNS_COLLISION_FILTER
+ * Used to override the decision of the collision search algorithm whether two
+ * items collide.
+ **/
+struct PNS_COLLISION_FILTER {
+ virtual bool operator()( const PNS_ITEM *aItemA, const PNS_ITEM *aItemB ) const = 0;
+};
+
+/**
+ * Class PNS_NODE
+ *
+ * Keeps the router "world" - i.e. all the tracks, vias, solids in a
+ * hierarchical and indexed way.
+ * Features:
+ * - spatial-indexed container for PCB item shapes
+ * - collision search & clearance checking
+ * - assembly of lines connecting joints, finding loops and unique paths
+ * - lightweight cloning/branching (for recursive optimization and shove
+ * springback)
+ **/
+class PNS_NODE
+{
+public:
+ typedef boost::optional<PNS_OBSTACLE> OPT_OBSTACLE;
+ typedef std::vector<PNS_ITEM*> ITEM_VECTOR;
+ typedef std::vector<PNS_OBSTACLE> OBSTACLES;
+
+ PNS_NODE();
+ ~PNS_NODE();
+
+ ///> Returns the expected clearance between items a and b.
+ int GetClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const;
+
+ ///> Returns the pre-set worst case clearance between any pair of items
+ int GetMaxClearance() const
+ {
+ return m_maxClearance;
+ }
+
+ ///> Sets the worst-case clerance between any pair of items
+ void SetMaxClearance( int aClearance )
+ {
+ m_maxClearance = aClearance;
+ }
+
+ ///> Assigns a clerance resolution function object
+ void SetClearanceFunctor( PNS_CLEARANCE_FUNC* aFunc )
+ {
+ m_clearanceFunctor = aFunc;
+ }
+
+ ///> Returns the number of joints
+ int JointCount() const
+ {
+ return m_joints.size();
+ }
+
+ ///> Returns the number of nodes in the inheritance chain (wrs to the root node)
+ int Depth() const
+ {
+ return m_depth;
+ }
+
+ /**
+ * Function QueryColliding()
+ *
+ * Finds items collliding (closer than clearance) with the item aItem.
+ * @param aItem item to check collisions against
+ * @param aObstacles set of colliding objects found
+ * @param aKindMask mask of obstacle types to take into account
+ * @param aLimitCount stop looking for collisions after finding this number of colliding items
+ * @return number of obstacles found
+ */
+ int QueryColliding( const PNS_ITEM* aItem,
+ OBSTACLES& aObstacles,
+ int aKindMask = PNS_ITEM::ANY,
+ int aLimitCount = -1,
+ bool aDifferentNetsOnly = true,
+ int aForceClearance = -1 );
+
+ /**
+ * Function NearestObstacle()
+ *
+ * Follows the line in search of an obstacle that is nearest to the starting to the line's starting
+ * point.
+ * @param aItem the item to find collisions with
+ * @param aKindMask mask of obstacle types to take into account
+ * @return the obstacle, if found, otherwise empty.
+ */
+ OPT_OBSTACLE NearestObstacle( const PNS_LINE* aItem,
+ int aKindMask = PNS_ITEM::ANY,
+ const std::set<PNS_ITEM*>* aRestrictedSet = NULL );
+
+ /**
+ * Function CheckColliding()
+ *
+ * Checks if the item collides with anything else in the world,
+ * and if found, returns the obstacle.
+ * @param aItem the item to find collisions with
+ * @param aKindMask mask of obstacle types to take into account
+ * @return the obstacle, if found, otherwise empty.
+ */
+ OPT_OBSTACLE CheckColliding( const PNS_ITEM* aItem,
+ int aKindMask = PNS_ITEM::ANY );
+
+
+ /**
+ * Function CheckColliding()
+ *
+ * Checks if any item in the set collides with anything else in the world,
+ * and if found, returns the obstacle.
+ * @param aSet set of items to find collisions with
+ * @param aKindMask mask of obstacle types to take into account
+ * @return the obstacle, if found, otherwise empty.
+ */
+ OPT_OBSTACLE CheckColliding( const PNS_ITEMSET& aSet,
+ int aKindMask = PNS_ITEM::ANY );
+
+
+ /**
+ * Function CheckColliding()
+ *
+ * Checks if 2 items collide.
+ * and if found, returns the obstacle.
+ * @param aItemA first item to find collisions with
+ * @param aItemB second item to find collisions with
+ * @param aKindMask mask of obstacle types to take into account
+ * @return the obstacle, if found, otherwise empty.
+ */
+ bool CheckColliding( const PNS_ITEM* aItemA,
+ const PNS_ITEM* aItemB,
+ int aKindMask = PNS_ITEM::ANY,
+ int aForceClearance = -1 );
+
+ /**
+ * Function HitTest()
+ *
+ * Finds all items that contain the point aPoint.
+ * @param aPoint the point
+ * @return the items
+ */
+ const PNS_ITEMSET HitTest( const VECTOR2I& aPoint ) const;
+
+ /**
+ * Function Add()
+ *
+ * Adds an item to the current node.
+ * @param aItem item to add
+ * @param aAllowRedundant if true, duplicate items are allowed (e.g. a segment or via
+ * at the same coordinates as an existing one)
+ */
+ void Add( PNS_ITEM* aItem, bool aAllowRedundant = false );
+
+ /**
+ * Function Remove()
+ *
+ * Just as the name says, removes an item from this branch.
+ * @param aItem item to remove
+ */
+ void Remove( PNS_ITEM* aItem );
+
+ /**
+ * Function Remove()
+ *
+ * Just as the name says, removes a line from this branch.
+ * @param aItem item to remove
+ */
+ void Remove( PNS_LINE& aLine );
+
+
+ /**
+ * Function Replace()
+ *
+ * Just as the name says, replaces an item with another one.
+ * @param aOldItem item to be removed
+ * @param aNewItem item add instead
+ */
+ void Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem );
+
+ /**
+ * Function Branch()
+ *
+ * Creates a lightweight copy (called branch) of self that tracks
+ * the changes (added/removed items) wrs to the root. Note that if there are
+ * any branches in use, their parents must NOT be deleted.
+ * @return the new branch
+ */
+ PNS_NODE* Branch();
+
+ /**
+ * Function AssembleLine()
+ *
+ * Follows the joint map to assemble a line connecting two non-trivial
+ * joints starting from segment aSeg.
+ * @param aSeg the initial segment
+ * @param aOriginSegmentIndex index of aSeg in the resulting line
+ * @return the line
+ */
+ const PNS_LINE AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex = NULL,
+ bool aStopAtLockedJoints = false );
+
+ ///> Prints the contents and joints structure
+ void Dump( bool aLong = false );
+
+ /**
+ * Function GetUpdatedItems()
+ *
+ * Returns the lists of items removed and added in this branch, with
+ * respect to the root branch.
+ * @param aRemoved removed items
+ * @param aAdded added items
+ */
+ void GetUpdatedItems( ITEM_VECTOR& aRemoved, ITEM_VECTOR& aAdded );
+
+ /**
+ * Function Commit()
+ *
+ * Applies the changes from a given branch (aNode) to the root branch. Called on
+ * a non-root branch will fail. Calling commit also kills all children nodes of the root branch.
+ * @param aNode node to commit changes from
+ */
+ void Commit( PNS_NODE* aNode );
+
+ /**
+ * Function FindJoint()
+ *
+ * Searches for a joint at a given position, layer and belonging to given net.
+ * @return the joint, if found, otherwise empty
+ */
+ PNS_JOINT* FindJoint( const VECTOR2I& aPos, int aLayer, int aNet );
+
+ void LockJoint( const VECTOR2I& aPos, const PNS_ITEM* aItem, bool aLock );
+
+ /**
+ * Function FindJoint()
+ *
+ * Searches for a joint at a given position, linked to given item.
+ * @return the joint, if found, otherwise empty
+ */
+ PNS_JOINT* FindJoint( const VECTOR2I& aPos, const PNS_ITEM* aItem )
+ {
+ return FindJoint( aPos, aItem->Layers().Start(), aItem->Net() );
+ }
+
+#if 0
+ void MapConnectivity( PNS_JOINT* aStart, std::vector<PNS_JOINT*> & aFoundJoints );
+
+ PNS_ITEM* NearestUnconnectedItem( PNS_JOINT* aStart, int *aAnchor = NULL,
+ int aKindMask = PNS_ITEM::ANY);
+
+#endif
+
+ ///> finds all lines between a pair of joints. Used by the loop removal procedure.
+ int FindLinesBetweenJoints( PNS_JOINT& aA,
+ PNS_JOINT& aB,
+ std::vector<PNS_LINE>& aLines );
+
+ ///> finds the joints corresponding to the ends of line aLine
+ void FindLineEnds( const PNS_LINE& aLine, PNS_JOINT& aA, PNS_JOINT& aB );
+
+ ///> Destroys all child nodes. Applicable only to the root node.
+ void KillChildren();
+
+ void AllItemsInNet( int aNet, std::set<PNS_ITEM*>& aItems );
+
+ void ClearRanks( int aMarkerMask = MK_HEAD | MK_VIOLATION );
+
+ int FindByMarker( int aMarker, PNS_ITEMSET& aItems );
+ int RemoveByMarker( int aMarker );
+ void SetCollisionFilter( PNS_COLLISION_FILTER* aFilter );
+
+ PNS_ITEM* FindItemByParent( const BOARD_CONNECTED_ITEM *aParent );
+
+ bool HasChildren() const
+ {
+ return !m_children.empty();
+ }
+
+private:
+ struct OBSTACLE_VISITOR;
+ typedef boost::unordered_multimap<PNS_JOINT::HASH_TAG, PNS_JOINT> JOINT_MAP;
+ typedef JOINT_MAP::value_type TagJointPair;
+
+ /// nodes are not copyable
+ PNS_NODE( const PNS_NODE& aB );
+ PNS_NODE& operator=( const PNS_NODE& aB );
+
+ ///> tries to find matching joint and creates a new one if not found
+ PNS_JOINT& touchJoint( const VECTOR2I& aPos,
+ const PNS_LAYERSET& aLayers,
+ int aNet );
+
+ ///> touches a joint and links it to an m_item
+ void linkJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers,
+ int aNet, PNS_ITEM* aWhere );
+
+ ///> unlinks an item from a joint
+ void unlinkJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers,
+ int aNet, PNS_ITEM* aWhere );
+
+ ///> helpers for adding/removing items
+ void addSolid( PNS_SOLID* aSeg );
+ void addSegment( PNS_SEGMENT* aSeg, bool aAllowRedundant );
+ void addLine( PNS_LINE* aLine, bool aAllowRedundant );
+ void addVia( PNS_VIA* aVia );
+ void removeSolid( PNS_SOLID* aSeg );
+ void removeLine( PNS_LINE* aLine );
+ void removeSegment( PNS_SEGMENT* aSeg );
+ void removeVia( PNS_VIA* aVia );
+
+ void doRemove( PNS_ITEM* aItem );
+ void unlinkParent();
+ void releaseChildren();
+ void releaseGarbage();
+
+ bool isRoot() const
+ {
+ return m_parent == NULL;
+ }
+
+ ///> checks if this branch contains an updated version of the m_item
+ ///> from the root branch.
+ bool overrides( PNS_ITEM* aItem ) const
+ {
+ return m_override.find( aItem ) != m_override.end();
+ }
+
+ PNS_SEGMENT* findRedundantSegment( PNS_SEGMENT* aSeg );
+
+ ///> scans the joint map, forming a line starting from segment (current).
+ void followLine( PNS_SEGMENT* aCurrent,
+ bool aScanDirection,
+ int& aPos,
+ int aLimit,
+ VECTOR2I* aCorners,
+ PNS_SEGMENT** aSegments,
+ bool& aGuardHit,
+ bool aStopAtLockedJoints );
+
+ ///> hash table with the joints, linking the items. Joints are hashed by
+ ///> their position, layer set and net.
+ JOINT_MAP m_joints;
+
+ ///> node this node was branched from
+ PNS_NODE* m_parent;
+
+ ///> root node of the whole hierarchy
+ PNS_NODE* m_root;
+
+ ///> list of nodes branched from this one
+ std::set<PNS_NODE*> m_children;
+
+ ///> hash of root's items that have been changed in this node
+ boost::unordered_set<PNS_ITEM*> m_override;
+
+ ///> worst case item-item clearance
+ int m_maxClearance;
+
+ ///> Clearance resolution functor
+ PNS_CLEARANCE_FUNC* m_clearanceFunctor;
+
+ ///> Geometric/Net index of the items
+ PNS_INDEX* m_index;
+
+ ///> depth of the node (number of parent nodes in the inheritance chain)
+ int m_depth;
+
+ ///> optional collision filtering object
+ PNS_COLLISION_FILTER* m_collisionFilter;
+
+ boost::unordered_set<PNS_ITEM*> m_garbageItems;
+};
+
+#endif
diff --git a/pcbnew/router/pns_optimizer.cpp b/pcbnew/router/pns_optimizer.cpp
new file mode 100644
index 0000000..d18933f
--- /dev/null
+++ b/pcbnew/router/pns_optimizer.cpp
@@ -0,0 +1,1224 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+
+#include <geometry/shape_line_chain.h>
+#include <geometry/shape_rect.h>
+#include <geometry/shape_convex.h>
+
+#include "pns_line.h"
+#include "pns_diff_pair.h"
+#include "pns_node.h"
+#include "pns_solid.h"
+#include "pns_optimizer.h"
+#include "pns_utils.h"
+#include "pns_router.h"
+
+/**
+ * Cost Estimator Methods
+ */
+int PNS_COST_ESTIMATOR::CornerCost( const SEG& aA, const SEG& aB )
+{
+ DIRECTION_45 dir_a( aA ), dir_b( aB );
+
+ switch( dir_a.Angle( dir_b ) )
+ {
+ case DIRECTION_45::ANG_OBTUSE:
+ return 1;
+
+ case DIRECTION_45::ANG_STRAIGHT:
+ return 0;
+
+ case DIRECTION_45::ANG_ACUTE:
+ return 50;
+
+ case DIRECTION_45::ANG_RIGHT:
+ return 30;
+
+ case DIRECTION_45::ANG_HALF_FULL:
+ return 60;
+
+ default:
+ return 100;
+ }
+}
+
+
+int PNS_COST_ESTIMATOR::CornerCost( const SHAPE_LINE_CHAIN& aLine )
+{
+ int total = 0;
+
+ for( int i = 0; i < aLine.SegmentCount() - 1; ++i )
+ total += CornerCost( aLine.CSegment( i ), aLine.CSegment( i + 1 ) );
+
+ return total;
+}
+
+
+int PNS_COST_ESTIMATOR::CornerCost( const PNS_LINE& aLine )
+{
+ return CornerCost( aLine.CLine() );
+}
+
+
+void PNS_COST_ESTIMATOR::Add( PNS_LINE& aLine )
+{
+ m_lengthCost += aLine.CLine().Length();
+ m_cornerCost += CornerCost( aLine );
+}
+
+
+void PNS_COST_ESTIMATOR::Remove( PNS_LINE& aLine )
+{
+ m_lengthCost -= aLine.CLine().Length();
+ m_cornerCost -= CornerCost( aLine );
+}
+
+
+void PNS_COST_ESTIMATOR::Replace( PNS_LINE& aOldLine, PNS_LINE& aNewLine )
+{
+ m_lengthCost -= aOldLine.CLine().Length();
+ m_cornerCost -= CornerCost( aOldLine );
+ m_lengthCost += aNewLine.CLine().Length();
+ m_cornerCost += CornerCost( aNewLine );
+}
+
+
+bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
+ double aLengthTolerance,
+ double aCornerTolerance ) const
+{
+ if( aOther.m_cornerCost < m_cornerCost && aOther.m_lengthCost < m_lengthCost )
+ return true;
+
+ else if( aOther.m_cornerCost < m_cornerCost * aCornerTolerance &&
+ aOther.m_lengthCost < m_lengthCost * aLengthTolerance )
+ return true;
+
+ return false;
+}
+
+
+/**
+ * Optimizer
+ **/
+PNS_OPTIMIZER::PNS_OPTIMIZER( PNS_NODE* aWorld ) :
+ m_world( aWorld ),
+ m_collisionKindMask( PNS_ITEM::ANY ),
+ m_effortLevel( MERGE_SEGMENTS ),
+ m_keepPostures( false ),
+ m_restrictAreaActive( false )
+{
+}
+
+
+PNS_OPTIMIZER::~PNS_OPTIMIZER()
+{
+}
+
+
+struct PNS_OPTIMIZER::CACHE_VISITOR
+{
+ CACHE_VISITOR( const PNS_ITEM* aOurItem, PNS_NODE* aNode, int aMask ) :
+ m_ourItem( aOurItem ),
+ m_collidingItem( NULL ),
+ m_node( aNode ),
+ m_mask( aMask )
+ {}
+
+ bool operator()( PNS_ITEM* aOtherItem )
+ {
+ if( !( m_mask & aOtherItem->Kind() ) )
+ return true;
+
+ int clearance = m_node->GetClearance( aOtherItem, m_ourItem );
+
+ if( !aOtherItem->Collide( m_ourItem, clearance ) )
+ return true;
+
+ m_collidingItem = aOtherItem;
+ return false;
+ }
+
+ const PNS_ITEM* m_ourItem;
+ PNS_ITEM* m_collidingItem;
+ PNS_NODE* m_node;
+ int m_mask;
+};
+
+
+void PNS_OPTIMIZER::cacheAdd( PNS_ITEM* aItem, bool aIsStatic = false )
+{
+ if( m_cacheTags.find( aItem ) != m_cacheTags.end() )
+ return;
+
+ m_cache.Add( aItem );
+ m_cacheTags[aItem].m_hits = 1;
+ m_cacheTags[aItem].m_isStatic = aIsStatic;
+}
+
+
+void PNS_OPTIMIZER::removeCachedSegments( PNS_LINE* aLine, int aStartVertex, int aEndVertex )
+{
+ PNS_LINE::SEGMENT_REFS* segs = aLine->LinkedSegments();
+
+ if( !segs )
+ return;
+
+ if( aEndVertex < 0 )
+ aEndVertex += aLine->PointCount();
+
+ for( int i = aStartVertex; i < aEndVertex - 1; i++ )
+ {
+ PNS_SEGMENT* s = (*segs)[i];
+ m_cacheTags.erase( s );
+ m_cache.Remove( s );
+ }
+}
+
+
+void PNS_OPTIMIZER::CacheRemove( PNS_ITEM* aItem )
+{
+ if( aItem->Kind() == PNS_ITEM::LINE )
+ removeCachedSegments( static_cast<PNS_LINE*>( aItem ) );
+}
+
+
+void PNS_OPTIMIZER::CacheStaticItem( PNS_ITEM* aItem )
+{
+ cacheAdd( aItem, true );
+}
+
+
+void PNS_OPTIMIZER::ClearCache( bool aStaticOnly )
+{
+ if( !aStaticOnly )
+ {
+ m_cacheTags.clear();
+ m_cache.Clear();
+ return;
+ }
+
+ for( CachedItemTags::iterator i = m_cacheTags.begin(); i!= m_cacheTags.end(); ++i )
+ {
+ if( i->second.m_isStatic )
+ {
+ m_cache.Remove( i->first );
+ m_cacheTags.erase( i->first );
+ }
+ }
+}
+
+
+class LINE_RESTRICTIONS
+{
+ public:
+ LINE_RESTRICTIONS() {};
+ ~LINE_RESTRICTIONS() {};
+
+ void Build( PNS_NODE* aWorld, PNS_LINE* aOriginLine, const SHAPE_LINE_CHAIN& aLine, const BOX2I& aRestrictedArea, bool aRestrictedAreaEnable );
+ bool Check ( int aVertex1, int aVertex2, const SHAPE_LINE_CHAIN& aReplacement );
+ void Dump();
+
+ private:
+ int allowedAngles( PNS_NODE* aWorld, const PNS_LINE* aLine, const VECTOR2I& aP, bool aFirst );
+
+ struct RVERTEX
+ {
+ RVERTEX ( bool aRestricted, int aAllowedAngles ) :
+ restricted( aRestricted ),
+ allowedAngles( aAllowedAngles )
+ {
+ }
+
+ bool restricted;
+ int allowedAngles;
+ };
+
+ std::vector<RVERTEX> m_rs;
+};
+
+
+// fixme: use later
+int LINE_RESTRICTIONS::allowedAngles( PNS_NODE* aWorld, const PNS_LINE* aLine, const VECTOR2I& aP, bool aFirst )
+{
+ PNS_JOINT* jt = aWorld->FindJoint( aP , aLine );
+
+ if( !jt )
+ return 0xff;
+
+ DIRECTION_45 dirs [8];
+
+ int n_dirs = 0;
+
+ BOOST_FOREACH( const PNS_ITEM* item, jt->Links().CItems() )
+ {
+ if( item->OfKind( PNS_ITEM::VIA ) || item->OfKind( PNS_ITEM::SOLID ) )
+ return 0xff;
+ else if( const PNS_SEGMENT* seg = dyn_cast<const PNS_SEGMENT*>( item ) )
+ {
+ SEG s = seg->Seg();
+ if( s.A != aP )
+ s.Reverse();
+
+ if( n_dirs < 8 )
+ dirs[n_dirs++] = aFirst ? DIRECTION_45( s ) : DIRECTION_45( s ).Opposite();
+ }
+ }
+
+ const int angleMask = DIRECTION_45::ANG_OBTUSE | DIRECTION_45::ANG_HALF_FULL | DIRECTION_45::ANG_STRAIGHT;
+ int outputMask = 0xff;
+
+ for( int d = 0; d < 8; d++ )
+ {
+ DIRECTION_45 refDir( ( DIRECTION_45::Directions ) d );
+
+ for( int i = 0; i < n_dirs; i++ )
+ {
+ if( !( refDir.Angle( dirs[i] ) & angleMask ) )
+ outputMask &= ~refDir.Mask();
+ }
+ }
+
+ DrawDebugDirs( aP, outputMask, 3 );
+ return 0xff;
+}
+
+
+void LINE_RESTRICTIONS::Build( PNS_NODE* aWorld, PNS_LINE* aOriginLine, const SHAPE_LINE_CHAIN& aLine, const BOX2I& aRestrictedArea, bool aRestrictedAreaEnable )
+{
+ const SHAPE_LINE_CHAIN& l = aLine;
+ VECTOR2I v_prev;
+ int n = l.PointCount( );
+
+ m_rs.reserve( n );
+
+ for( int i = 0; i < n; i++ )
+ {
+ const VECTOR2I &v = l.CPoint( i ), v_next;
+ RVERTEX r( false, 0xff );
+
+ if( aRestrictedAreaEnable )
+ {
+ bool exiting = ( i > 0 && aRestrictedArea.Contains( v_prev ) && !aRestrictedArea.Contains( v ) );
+ bool entering = false;
+
+ if( i != l.PointCount() - 1 )
+ {
+ const VECTOR2I& v_next = l.CPoint( i + 1 );
+ entering = ( !aRestrictedArea.Contains( v ) && aRestrictedArea.Contains( v_next ) );
+ }
+
+ if( entering )
+ {
+ const SEG& sp = l.CSegment( i );
+ r.allowedAngles = DIRECTION_45( sp ).Mask();
+ }
+ else if( exiting )
+ {
+ const SEG& sp = l.CSegment( i - 1 );
+ r.allowedAngles = DIRECTION_45( sp ).Mask();
+ }
+ else
+ {
+ r.allowedAngles = ( !aRestrictedArea.Contains( v ) ) ? 0 : 0xff;
+ r.restricted = r.allowedAngles ? false : true;
+ }
+ }
+
+ v_prev = v;
+ m_rs.push_back( r );
+ }
+}
+
+
+void LINE_RESTRICTIONS::Dump()
+{
+}
+
+
+bool LINE_RESTRICTIONS::Check( int aVertex1, int aVertex2, const SHAPE_LINE_CHAIN& aReplacement )
+{
+ if( m_rs.empty( ) )
+ return true;
+
+ for( int i = aVertex1; i <= aVertex2; i++ )
+ if ( m_rs[i].restricted )
+ return false;
+
+ const RVERTEX& v1 = m_rs[ aVertex1 ];
+ const RVERTEX& v2 = m_rs[ aVertex2 ];
+
+ int m1 = DIRECTION_45( aReplacement.CSegment( 0 ) ).Mask();
+ int m2;
+
+ if( aReplacement.SegmentCount() == 1 )
+ m2 = m1;
+ else
+ m2 = DIRECTION_45( aReplacement.CSegment( 1 ) ).Mask();
+
+ return ( ( v1.allowedAngles & m1 ) != 0 ) &&
+ ( ( v2.allowedAngles & m2 ) != 0 );
+}
+
+
+bool PNS_OPTIMIZER::checkColliding( PNS_ITEM* aItem, bool aUpdateCache )
+{
+ CACHE_VISITOR v( aItem, m_world, m_collisionKindMask );
+
+ return static_cast<bool>( m_world->CheckColliding( aItem ) );
+
+ // something is wrong with the cache, need to investigate.
+ m_cache.Query( aItem->Shape(), m_world->GetMaxClearance(), v, false );
+
+ if( !v.m_collidingItem )
+ {
+ PNS_NODE::OPT_OBSTACLE obs = m_world->CheckColliding( aItem );
+
+ if( obs )
+ {
+ if( aUpdateCache )
+ cacheAdd( obs->m_item );
+
+ return true;
+ }
+ }
+ else
+ {
+ m_cacheTags[v.m_collidingItem].m_hits++;
+ return true;
+ }
+
+ return false;
+}
+
+
+bool PNS_OPTIMIZER::checkColliding( PNS_LINE* aLine, const SHAPE_LINE_CHAIN& aOptPath )
+{
+ PNS_LINE tmp( *aLine, aOptPath );
+
+ return checkColliding( &tmp );
+}
+
+
+bool PNS_OPTIMIZER::mergeObtuse( PNS_LINE* aLine )
+{
+ SHAPE_LINE_CHAIN& line = aLine->Line();
+
+ int step = line.PointCount() - 3;
+ int iter = 0;
+ int segs_pre = line.SegmentCount();
+
+ if( step < 0 )
+ return false;
+
+ SHAPE_LINE_CHAIN current_path( line );
+
+ while( 1 )
+ {
+ iter++;
+ int n_segs = current_path.SegmentCount();
+ int max_step = n_segs - 2;
+
+ if( step > max_step )
+ step = max_step;
+
+ if( step < 2 )
+ {
+ line = current_path;
+ return current_path.SegmentCount() < segs_pre;
+ }
+
+ bool found_anything = false;
+ int n = 0;
+
+ while( n < n_segs - step )
+ {
+ const SEG s1 = current_path.CSegment( n );
+ const SEG s2 = current_path.CSegment( n + step );
+ SEG s1opt, s2opt;
+
+ if( DIRECTION_45( s1 ).IsObtuse( DIRECTION_45( s2 ) ) )
+ {
+ VECTOR2I ip = *s1.IntersectLines( s2 );
+
+ if( s1.Distance( ip ) <= 1 || s2.Distance( ip ) <= 1 )
+ {
+ s1opt = SEG( s1.A, ip );
+ s2opt = SEG( ip, s2.B );
+ }
+ else
+ {
+ s1opt = SEG( s1.A, ip );
+ s2opt = SEG( ip, s2.B );
+ }
+
+ if( DIRECTION_45( s1opt ).IsObtuse( DIRECTION_45( s2opt ) ) )
+ {
+ SHAPE_LINE_CHAIN opt_path;
+ opt_path.Append( s1opt.A );
+ opt_path.Append( s1opt.B );
+ opt_path.Append( s2opt.B );
+
+ PNS_LINE opt_track( *aLine, opt_path );
+
+ if( !checkColliding( &opt_track ) )
+ {
+ current_path.Replace( s1.Index() + 1, s2.Index(), ip );
+ // removeCachedSegments(aLine, s1.Index(), s2.Index());
+ n_segs = current_path.SegmentCount();
+ found_anything = true;
+ break;
+ }
+ }
+ }
+
+ n++;
+ }
+
+ if( !found_anything )
+ {
+ if( step <= 2 )
+ {
+ line = current_path;
+ return line.SegmentCount() < segs_pre;
+ }
+
+ step--;
+ }
+ }
+
+ return line.SegmentCount() < segs_pre;
+}
+
+
+bool PNS_OPTIMIZER::mergeFull( PNS_LINE* aLine )
+{
+ SHAPE_LINE_CHAIN& line = aLine->Line();
+ int step = line.SegmentCount() - 1;
+
+ int segs_pre = line.SegmentCount();
+
+ line.Simplify();
+
+ if( step < 0 )
+ return false;
+
+ SHAPE_LINE_CHAIN current_path( line );
+
+ while( 1 )
+ {
+ int n_segs = current_path.SegmentCount();
+ int max_step = n_segs - 2;
+
+ if( step > max_step )
+ step = max_step;
+
+ if( step < 1 )
+ break;
+
+ bool found_anything = mergeStep( aLine, current_path, step );
+
+ if( !found_anything )
+ step--;
+ }
+
+ aLine->SetShape( current_path );
+
+ return current_path.SegmentCount() < segs_pre;
+}
+
+
+bool PNS_OPTIMIZER::Optimize( PNS_LINE* aLine, PNS_LINE* aResult )
+{
+ if( !aResult )
+ aResult = aLine;
+ else
+ *aResult = *aLine;
+
+ m_keepPostures = false;
+
+ bool rv = false;
+
+ if( m_effortLevel & MERGE_SEGMENTS )
+ rv |= mergeFull( aResult );
+
+ if( m_effortLevel & MERGE_OBTUSE )
+ rv |= mergeObtuse( aResult );
+
+ if( m_effortLevel & SMART_PADS )
+ rv |= runSmartPads( aResult );
+
+ if( m_effortLevel & FANOUT_CLEANUP )
+ rv |= fanoutCleanup( aResult );
+
+ return rv;
+}
+
+
+bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath, int step )
+{
+ int n = 0;
+ int n_segs = aCurrentPath.SegmentCount();
+
+ int cost_orig = PNS_COST_ESTIMATOR::CornerCost( aCurrentPath );
+
+ LINE_RESTRICTIONS restr;
+
+ if( aLine->SegmentCount() < 4 )
+ return false;
+
+ DIRECTION_45 orig_start( aLine->CSegment( 0 ) );
+ DIRECTION_45 orig_end( aLine->CSegment( -1 ) );
+
+ restr.Build( m_world, aLine, aCurrentPath, m_restrictArea, m_restrictAreaActive );
+
+ while( n < n_segs - step )
+ {
+ const SEG s1 = aCurrentPath.CSegment( n );
+ const SEG s2 = aCurrentPath.CSegment( n + step );
+
+ SHAPE_LINE_CHAIN path[2];
+ SHAPE_LINE_CHAIN* picked = NULL;
+ int cost[2];
+
+ for( int i = 0; i < 2; i++ )
+ {
+ bool postureMatch = true;
+ SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B, i );
+ cost[i] = INT_MAX;
+
+ bool restrictionsOK = restr.Check ( n, n + step + 1, bypass );
+
+ if( n == 0 && orig_start != DIRECTION_45( bypass.CSegment( 0 ) ) )
+ postureMatch = false;
+ else if( n == n_segs - step && orig_end != DIRECTION_45( bypass.CSegment( -1 ) ) )
+ postureMatch = false;
+
+ if( restrictionsOK && (postureMatch || !m_keepPostures) && !checkColliding( aLine, bypass ) )
+ {
+ path[i] = aCurrentPath;
+ path[i].Replace( s1.Index(), s2.Index(), bypass );
+ path[i].Simplify();
+ cost[i] = PNS_COST_ESTIMATOR::CornerCost( path[i] );
+ }
+ }
+
+ if( cost[0] < cost_orig && cost[0] < cost[1] )
+ picked = &path[0];
+ else if( cost[1] < cost_orig )
+ picked = &path[1];
+
+ if( picked )
+ {
+ n_segs = aCurrentPath.SegmentCount();
+ aCurrentPath = *picked;
+ return true;
+ }
+
+ n++;
+ }
+
+ return false;
+}
+
+
+PNS_OPTIMIZER::BREAKOUT_LIST PNS_OPTIMIZER::circleBreakouts( int aWidth,
+ const SHAPE* aShape, bool aPermitDiagonal ) const
+{
+ BREAKOUT_LIST breakouts;
+
+ for( int angle = 0; angle < 360; angle += 45 )
+ {
+ const SHAPE_CIRCLE* cir = static_cast<const SHAPE_CIRCLE*>( aShape );
+ SHAPE_LINE_CHAIN l;
+ VECTOR2I p0 = cir->GetCenter();
+ VECTOR2I v0( cir->GetRadius() * M_SQRT2, 0 );
+ l.Append( p0 );
+ l.Append( p0 + v0.Rotate( angle * M_PI / 180.0 ) );
+ breakouts.push_back( l );
+ }
+
+ return breakouts;
+}
+
+
+PNS_OPTIMIZER::BREAKOUT_LIST PNS_OPTIMIZER::convexBreakouts( int aWidth,
+ const SHAPE* aShape, bool aPermitDiagonal ) const
+{
+ BREAKOUT_LIST breakouts;
+ const SHAPE_CONVEX* convex = static_cast<const SHAPE_CONVEX*>( aShape );
+
+ BOX2I bbox = convex->BBox( 0 );
+ VECTOR2I p0 = bbox.Centre();
+ // must be large enough to guarantee intersecting the convex polygon
+ int length = bbox.GetSize().EuclideanNorm() / 2 + 5;
+
+ for( int angle = 0; angle < 360; angle += ( aPermitDiagonal ? 45 : 90 ) )
+ {
+ SHAPE_LINE_CHAIN l;
+ VECTOR2I v0( p0 + VECTOR2I( length, 0 ).Rotate( angle * M_PI / 180.0 ) );
+ SHAPE_LINE_CHAIN::INTERSECTIONS intersections;
+ int n = convex->Vertices().Intersect( SEG( p0, v0 ), intersections );
+ // if n == 1 intersected a segment
+ // if n == 2 intersected the common point of 2 segments
+ // n == 0 can not happen I think, but...
+ if( n > 0 )
+ {
+ l.Append( p0 );
+
+ // for a breakout distance relative to the distance between
+ // center and polygon edge
+ //l.Append( intersections[0].p + (v0 - p0).Resize( (intersections[0].p - p0).EuclideanNorm() * 0.4 ) );
+
+ // for an absolute breakout distance, e.g. 0.1 mm
+ l.Append( intersections[0].p + (v0 - p0).Resize( 100000 ) );
+
+ // for the breakout right on the polygon edge
+ //l.Append( intersections[0].p );
+
+ breakouts.push_back( l );
+ }
+ }
+
+ return breakouts;
+}
+
+
+PNS_OPTIMIZER::BREAKOUT_LIST PNS_OPTIMIZER::rectBreakouts( int aWidth,
+ const SHAPE* aShape, bool aPermitDiagonal ) const
+{
+ const SHAPE_RECT* rect = static_cast<const SHAPE_RECT*>(aShape);
+ VECTOR2I s = rect->GetSize(), c = rect->GetPosition() + VECTOR2I( s.x / 2, s.y / 2 );
+ BREAKOUT_LIST breakouts;
+
+ VECTOR2I d_offset;
+
+ d_offset.x = ( s.x > s.y ) ? ( s.x - s.y ) / 2 : 0;
+ d_offset.y = ( s.x < s.y ) ? ( s.y - s.x ) / 2 : 0;
+
+ VECTOR2I d_vert = VECTOR2I( 0, s.y / 2 + aWidth );
+ VECTOR2I d_horiz = VECTOR2I( s.x / 2 + aWidth, 0 );
+
+ breakouts.push_back( SHAPE_LINE_CHAIN( c, c + d_horiz ) );
+ breakouts.push_back( SHAPE_LINE_CHAIN( c, c - d_horiz ) );
+ breakouts.push_back( SHAPE_LINE_CHAIN( c, c + d_vert ) );
+ breakouts.push_back( SHAPE_LINE_CHAIN( c, c - d_vert ) );
+
+ if( aPermitDiagonal )
+ {
+ int l = aWidth + std::min( s.x, s.y ) / 2;
+ VECTOR2I d_diag;
+
+ if( s.x >= s.y )
+ {
+ breakouts.push_back( SHAPE_LINE_CHAIN( c, c + d_offset,
+ c + d_offset + VECTOR2I( l, l ) ) );
+ breakouts.push_back( SHAPE_LINE_CHAIN( c, c + d_offset,
+ c + d_offset - VECTOR2I( -l, l ) ) );
+ breakouts.push_back( SHAPE_LINE_CHAIN( c, c - d_offset,
+ c - d_offset + VECTOR2I( -l, l ) ) );
+ breakouts.push_back( SHAPE_LINE_CHAIN( c, c - d_offset,
+ c - d_offset - VECTOR2I( l, l ) ) );
+ }
+ else
+ {
+ // fixme: this could be done more efficiently
+ breakouts.push_back( SHAPE_LINE_CHAIN( c, c + d_offset,
+ c + d_offset + VECTOR2I( l, l ) ) );
+ breakouts.push_back( SHAPE_LINE_CHAIN( c, c - d_offset,
+ c - d_offset - VECTOR2I( -l, l ) ) );
+ breakouts.push_back( SHAPE_LINE_CHAIN( c, c + d_offset,
+ c + d_offset + VECTOR2I( -l, l ) ) );
+ breakouts.push_back( SHAPE_LINE_CHAIN( c, c - d_offset,
+ c - d_offset - VECTOR2I( l, l ) ) );
+ }
+ }
+
+ return breakouts;
+}
+
+
+PNS_OPTIMIZER::BREAKOUT_LIST PNS_OPTIMIZER::computeBreakouts( int aWidth,
+ const PNS_ITEM* aItem, bool aPermitDiagonal ) const
+{
+ switch( aItem->Kind() )
+ {
+ case PNS_ITEM::VIA:
+ {
+ const PNS_VIA* via = static_cast<const PNS_VIA*>( aItem );
+ return circleBreakouts( aWidth, via->Shape(), aPermitDiagonal );
+ }
+
+ case PNS_ITEM::SOLID:
+ {
+ const SHAPE* shape = aItem->Shape();
+
+ switch( shape->Type() )
+ {
+ case SH_RECT:
+ return rectBreakouts( aWidth, shape, aPermitDiagonal );
+
+ case SH_SEGMENT:
+ {
+ const SHAPE_SEGMENT* seg = static_cast<const SHAPE_SEGMENT*> (shape);
+ const SHAPE_RECT rect = ApproximateSegmentAsRect ( *seg );
+ return rectBreakouts( aWidth, &rect, aPermitDiagonal );
+ }
+
+ case SH_CIRCLE:
+ return circleBreakouts( aWidth, shape, aPermitDiagonal );
+
+ case SH_CONVEX:
+ return convexBreakouts( aWidth, shape, aPermitDiagonal );
+
+ default:
+ break;
+ }
+ }
+
+ default:
+ break;
+ }
+
+ return BREAKOUT_LIST();
+}
+
+
+PNS_ITEM* PNS_OPTIMIZER::findPadOrVia( int aLayer, int aNet, const VECTOR2I& aP ) const
+{
+ PNS_JOINT* jt = m_world->FindJoint( aP, aLayer, aNet );
+
+ if( !jt )
+ return NULL;
+
+ BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
+ {
+ if( item->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID ) )
+ return item;
+ }
+
+ return NULL;
+}
+
+
+int PNS_OPTIMIZER::smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd, int aEndVertex )
+{
+ int min_cost = INT_MAX; // PNS_COST_ESTIMATOR::CornerCost( line );
+ int min_len = INT_MAX;
+ DIRECTION_45 dir;
+
+ const int ForbiddenAngles = DIRECTION_45::ANG_ACUTE | DIRECTION_45::ANG_RIGHT |
+ DIRECTION_45::ANG_HALF_FULL | DIRECTION_45::ANG_UNDEFINED;
+
+ typedef std::pair<int, SHAPE_LINE_CHAIN> RtVariant;
+ std::vector<RtVariant> variants;
+
+ PNS_SOLID* solid = dyn_cast<PNS_SOLID*>( aPad );
+
+ // don't do auto-neckdown for offset pads
+ if( solid && solid->Offset() != VECTOR2I( 0, 0 ) )
+ return -1;
+
+
+ BREAKOUT_LIST breakouts = computeBreakouts( aLine->Width(), aPad, true );
+
+ SHAPE_LINE_CHAIN line = ( aEnd ? aLine->CLine().Reverse() : aLine->CLine() );
+
+
+ int p_end = std::min( aEndVertex, std::min( 3, line.PointCount() - 1 ) );
+
+ for( int p = 1; p <= p_end; p++ )
+ {
+ BOOST_FOREACH( SHAPE_LINE_CHAIN & l, breakouts ) {
+
+ for( int diag = 0; diag < 2; diag++ )
+ {
+ SHAPE_LINE_CHAIN v;
+ SHAPE_LINE_CHAIN connect = dir.BuildInitialTrace( l.CPoint( -1 ),
+ line.CPoint( p ), diag == 0 );
+
+ DIRECTION_45 dir_bkout( l.CSegment( -1 ) );
+
+ if(!connect.SegmentCount())
+ continue;
+
+ int ang1 = dir_bkout.Angle( DIRECTION_45( connect.CSegment( 0 ) ) );
+ int ang2 = 0;
+
+ if( (ang1 | ang2) & ForbiddenAngles )
+ continue;
+
+ if( l.Length() > line.Length() )
+ continue;
+
+ v = l;
+
+ v.Append( connect );
+
+ for( int i = p + 1; i < line.PointCount(); i++ )
+ v.Append( line.CPoint( i ) );
+
+ PNS_LINE tmp( *aLine, v );
+ int cc = tmp.CountCorners( ForbiddenAngles );
+
+ if( cc == 0 )
+ {
+ RtVariant vp;
+ vp.first = p;
+ vp.second = aEnd ? v.Reverse() : v;
+ vp.second.Simplify();
+ variants.push_back( vp );
+ }
+ }
+ }
+ }
+
+ SHAPE_LINE_CHAIN l_best;
+ bool found = false;
+ int p_best = -1;
+
+ BOOST_FOREACH( RtVariant& vp, variants )
+ {
+ PNS_LINE tmp( *aLine, vp.second );
+ int cost = PNS_COST_ESTIMATOR::CornerCost( vp.second );
+ int len = vp.second.Length();
+
+ if( !checkColliding( &tmp ) )
+ {
+ if( cost < min_cost || ( cost == min_cost && len < min_len ) )
+ {
+ l_best = vp.second;
+ p_best = vp.first;
+ found = true;
+
+ if( cost == min_cost )
+ min_len = std::min( len, min_len );
+
+ min_cost = std::min( cost, min_cost );
+ }
+ }
+ }
+
+ if( found )
+ {
+ aLine->SetShape( l_best );
+ return p_best;
+ }
+
+ return -1;
+}
+
+bool PNS_OPTIMIZER::runSmartPads( PNS_LINE* aLine )
+{
+ SHAPE_LINE_CHAIN& line = aLine->Line();
+
+ if( line.PointCount() < 3 )
+ return false;
+
+ VECTOR2I p_start = line.CPoint( 0 ), p_end = line.CPoint( -1 );
+
+ PNS_ITEM* startPad = findPadOrVia( aLine->Layer(), aLine->Net(), p_start );
+ PNS_ITEM* endPad = findPadOrVia( aLine->Layer(), aLine->Net(), p_end );
+
+ int vtx = -1;
+
+ if( startPad )
+ vtx = smartPadsSingle( aLine, startPad, false, 3 );
+
+ if( endPad )
+ smartPadsSingle( aLine, endPad, true,
+ vtx < 0 ? line.PointCount() - 1 : line.PointCount() - 1 - vtx );
+
+ aLine->Line().Simplify();
+
+ return true;
+}
+
+
+bool PNS_OPTIMIZER::Optimize( PNS_LINE* aLine, int aEffortLevel, PNS_NODE* aWorld )
+{
+ PNS_OPTIMIZER opt( aWorld );
+
+ opt.SetEffortLevel( aEffortLevel );
+ opt.SetCollisionMask( -1 );
+ return opt.Optimize( aLine );
+}
+
+
+bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE* aLine )
+{
+ if( aLine->PointCount() < 3 )
+ return false;
+
+ VECTOR2I p_start = aLine->CPoint( 0 ), p_end = aLine->CPoint( -1 );
+
+ PNS_ITEM* startPad = findPadOrVia( aLine->Layer(), aLine->Net(), p_start );
+ PNS_ITEM* endPad = findPadOrVia( aLine->Layer(), aLine->Net(), p_end );
+
+ int thr = aLine->Width() * 10;
+ int len = aLine->CLine().Length();
+
+ if( !startPad )
+ return false;
+
+ bool startMatch = startPad->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID );
+ bool endMatch = false;
+
+ if(endPad)
+ {
+ endMatch = endPad->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID );
+ }
+ else
+ {
+ endMatch = aLine->EndsWithVia();
+ }
+
+ if( startMatch && endMatch && len < thr )
+ {
+ for( int i = 0; i < 2; i++ )
+ {
+ SHAPE_LINE_CHAIN l2 = DIRECTION_45().BuildInitialTrace( p_start, p_end, i );
+ PNS_LINE repl;
+ repl = PNS_LINE( *aLine, l2 );
+
+ if( !m_world->CheckColliding( &repl ) )
+ {
+ aLine->SetShape( repl.CLine() );
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+int findCoupledVertices( const VECTOR2I& aVertex, const SEG& aOrigSeg, const SHAPE_LINE_CHAIN& aCoupled, PNS_DIFF_PAIR* aPair, int* aIndices )
+{
+ int count = 0;
+ for ( int i = 0; i < aCoupled.SegmentCount(); i++ )
+ {
+ SEG s = aCoupled.CSegment( i );
+ VECTOR2I projOverCoupled = s.LineProject ( aVertex );
+
+ if( s.ApproxParallel ( aOrigSeg ) )
+ {
+ int64_t dist = ( projOverCoupled - aVertex ).EuclideanNorm() - aPair->Width();
+
+ if( aPair->GapConstraint().Matches( dist ) )
+ {
+ *aIndices++ = i;
+ count++;
+ }
+ }
+ }
+
+ return count;
+}
+
+
+bool verifyDpBypass( PNS_NODE* aNode, PNS_DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LINE_CHAIN& aNewRef, const SHAPE_LINE_CHAIN& aNewCoupled )
+{
+ PNS_LINE refLine ( aRefIsP ? aPair->PLine() : aPair->NLine(), aNewRef );
+ PNS_LINE coupledLine ( aRefIsP ? aPair->NLine() : aPair->PLine(), aNewCoupled );
+
+ if( aNode->CheckColliding( &refLine, &coupledLine, PNS_ITEM::ANY, aPair->Gap() - 10 ) )
+ return false;
+
+ if( aNode->CheckColliding ( &refLine ) )
+ return false;
+
+ if( aNode->CheckColliding ( &coupledLine ) )
+ return false;
+
+ return true;
+}
+
+
+bool coupledBypass( PNS_NODE* aNode, PNS_DIFF_PAIR* aPair, bool aRefIsP, const SHAPE_LINE_CHAIN& aRef, const SHAPE_LINE_CHAIN& aRefBypass, const SHAPE_LINE_CHAIN& aCoupled, SHAPE_LINE_CHAIN& aNewCoupled )
+{
+ int vStartIdx[1024]; // fixme: possible overflow
+
+ int nStarts = findCoupledVertices( aRefBypass.CPoint( 0 ), aRefBypass.CSegment( 0 ), aCoupled, aPair, vStartIdx );
+ DIRECTION_45 dir( aRefBypass.CSegment( 0 ) );
+
+ int64_t bestLength = -1;
+ bool found = false;
+ SHAPE_LINE_CHAIN bestBypass;
+ int si, ei;
+
+ for( int i=0; i< nStarts; i++ )
+ {
+ for( int j = 1; j < aCoupled.PointCount() - 1; j++ )
+ {
+ int delta = std::abs ( vStartIdx[i] - j );
+
+ if( delta > 1 )
+ {
+ const VECTOR2I& vs = aCoupled.CPoint( vStartIdx[i] );
+ SHAPE_LINE_CHAIN bypass = dir.BuildInitialTrace( vs, aCoupled.CPoint(j), dir.IsDiagonal() );
+
+ int64_t coupledLength = aPair->CoupledLength( aRef, bypass );
+
+ SHAPE_LINE_CHAIN newCoupled = aCoupled;
+
+ si = vStartIdx[i];
+ ei = j;
+
+ if(si < ei)
+ newCoupled.Replace( si, ei, bypass );
+ else
+ newCoupled.Replace( ei, si, bypass.Reverse() );
+
+ if(coupledLength > bestLength && verifyDpBypass( aNode, aPair, aRefIsP, aRef, newCoupled) )
+ {
+ bestBypass = newCoupled;
+ bestLength = coupledLength;
+ found = true;
+ }
+ }
+ }
+ }
+
+
+ if( found )
+ aNewCoupled = bestBypass;
+
+ return found;
+}
+
+
+bool checkDpColliding( PNS_NODE* aNode, PNS_DIFF_PAIR* aPair, bool aIsP, const SHAPE_LINE_CHAIN& aPath )
+{
+ PNS_LINE tmp ( aIsP ? aPair->PLine() : aPair->NLine(), aPath );
+
+ return static_cast<bool>( aNode->CheckColliding( &tmp ) );
+}
+
+
+bool PNS_OPTIMIZER::mergeDpStep( PNS_DIFF_PAIR* aPair, bool aTryP, int step )
+{
+ int n = 1;
+
+ SHAPE_LINE_CHAIN currentPath = aTryP ? aPair->CP() : aPair->CN();
+ SHAPE_LINE_CHAIN coupledPath = aTryP ? aPair->CN() : aPair->CP();
+
+ int n_segs = currentPath.SegmentCount() - 1;
+
+ int64_t clenPre = aPair->CoupledLength( currentPath, coupledPath );
+ int64_t budget = clenPre / 10; // fixme: come up with somethig more intelligent here...
+
+ while( n < n_segs - step )
+ {
+ const SEG s1 = currentPath.CSegment( n );
+ const SEG s2 = currentPath.CSegment( n + step );
+
+ DIRECTION_45 dir1( s1 );
+ DIRECTION_45 dir2( s2 );
+
+ if( dir1.IsObtuse( dir2 ) )
+ {
+ SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B, dir1.IsDiagonal() );
+ SHAPE_LINE_CHAIN newRef;
+ SHAPE_LINE_CHAIN newCoup;
+ int64_t deltaCoupled = -1, deltaUni = -1;
+
+ newRef = currentPath;
+ newRef.Replace( s1.Index(), s2.Index(), bypass );
+
+ deltaUni = aPair->CoupledLength ( newRef, coupledPath ) - clenPre + budget;
+
+ if ( coupledBypass( m_world, aPair, aTryP, newRef, bypass, coupledPath, newCoup ) )
+ {
+ deltaCoupled = aPair->CoupledLength( newRef, newCoup ) - clenPre + budget;
+
+ if( deltaCoupled >= 0 )
+ {
+ newRef.Simplify();
+ newCoup.Simplify();
+
+ aPair->SetShape( newRef, newCoup, !aTryP );
+ return true;
+ }
+ }
+ else if( deltaUni >= 0 && verifyDpBypass ( m_world, aPair, aTryP, newRef, coupledPath ) )
+ {
+ newRef.Simplify();
+ coupledPath.Simplify();
+
+ aPair->SetShape( newRef, coupledPath, !aTryP );
+ return true;
+ }
+ }
+
+ n++;
+ }
+
+ return false;
+}
+
+
+bool PNS_OPTIMIZER::mergeDpSegments( PNS_DIFF_PAIR* aPair )
+{
+ int step_p = aPair->CP().SegmentCount() - 2;
+ int step_n = aPair->CN().SegmentCount() - 2;
+
+ while( 1 )
+ {
+ int n_segs_p = aPair->CP().SegmentCount();
+ int n_segs_n = aPair->CN().SegmentCount();
+
+ int max_step_p = n_segs_p - 2;
+ int max_step_n = n_segs_n - 2;
+
+ if( step_p > max_step_p )
+ step_p = max_step_p;
+
+ if( step_n > max_step_n )
+ step_n = max_step_n;
+
+ if( step_p < 1 && step_n < 1)
+ break;
+
+ bool found_anything_p = false;
+ bool found_anything_n = false;
+
+ if( step_p > 1 )
+ found_anything_p = mergeDpStep( aPair, true, step_p );
+
+ if( step_n > 1 )
+ found_anything_n = mergeDpStep( aPair, false, step_n );
+
+ if( !found_anything_n && !found_anything_p )
+ {
+ step_n--;
+ step_p--;
+ }
+ }
+ return true;
+}
+
+
+bool PNS_OPTIMIZER::Optimize( PNS_DIFF_PAIR* aPair )
+{
+ return mergeDpSegments( aPair );
+}
diff --git a/pcbnew/router/pns_optimizer.h b/pcbnew/router/pns_optimizer.h
new file mode 100644
index 0000000..36bced6
--- /dev/null
+++ b/pcbnew/router/pns_optimizer.h
@@ -0,0 +1,181 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_OPTIMIZER_H
+#define __PNS_OPTIMIZER_H
+
+#include <boost/unordered_map.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <geometry/shape_index_list.h>
+#include <geometry/shape_line_chain.h>
+
+#include "range.h"
+
+class PNS_NODE;
+class PNS_ROUTER;
+class PNS_LINE;
+class PNS_DIFF_PAIR;
+
+/**
+ * Class PNS_COST_ESTIMATOR
+ *
+ * Calculates the cost of a given line, taking corner angles and total length into account.
+ **/
+class PNS_COST_ESTIMATOR
+{
+public:
+ PNS_COST_ESTIMATOR() :
+ m_lengthCost( 0 ),
+ m_cornerCost( 0 )
+ {}
+
+ PNS_COST_ESTIMATOR( const PNS_COST_ESTIMATOR& aB ) :
+ m_lengthCost( aB.m_lengthCost ),
+ m_cornerCost( aB.m_cornerCost )
+ {}
+
+ ~PNS_COST_ESTIMATOR() {};
+
+ static int CornerCost( const SEG& aA, const SEG& aB );
+ static int CornerCost( const SHAPE_LINE_CHAIN& aLine );
+ static int CornerCost( const PNS_LINE& aLine );
+
+ void Add( PNS_LINE& aLine );
+ void Remove( PNS_LINE& aLine );
+ void Replace( PNS_LINE& aOldLine, PNS_LINE& aNewLine );
+
+ bool IsBetter( PNS_COST_ESTIMATOR& aOther, double aLengthTolerance,
+ double aCornerTollerace ) const;
+
+ double GetLengthCost() const { return m_lengthCost; }
+ double GetCornerCost() const { return m_cornerCost; }
+
+private:
+ double m_lengthCost;
+ int m_cornerCost;
+};
+
+/**
+ * Class PNS_OPTIMIZER
+ *
+ * Performs various optimizations of the lines being routed, attempting to make the lines shorter
+ * and less cornery. There are 3 kinds of optimizations so far:
+ * - Merging obtuse segments (MERGE_OBTUSE): tries to join together as many
+ * obtuse segments as possible without causing collisions
+ * - Rerouting path between pair of line corners with a 2-segment "\__" line and iteratively repeating
+ * the procedure as long as the total cost of the line keeps decreasing
+ * - "Smart Pads" - that is, rerouting pad/via exits to make them look nice (SMART_PADS).
+ **/
+class PNS_OPTIMIZER
+{
+public:
+ enum OptimizationEffort
+ {
+ MERGE_SEGMENTS = 0x01,
+ SMART_PADS = 0x02,
+ MERGE_OBTUSE = 0x04,
+ FANOUT_CLEANUP = 0x08
+ };
+
+ PNS_OPTIMIZER( PNS_NODE* aWorld );
+ ~PNS_OPTIMIZER();
+
+ ///> a quick shortcut to optmize a line without creating and setting up an optimizer
+ static bool Optimize( PNS_LINE* aLine, int aEffortLevel, PNS_NODE* aWorld);
+
+ bool Optimize( PNS_LINE* aLine, PNS_LINE* aResult = NULL );
+ bool Optimize( PNS_DIFF_PAIR* aPair );
+
+
+ void SetWorld( PNS_NODE* aNode ) { m_world = aNode; }
+ void CacheStaticItem( PNS_ITEM* aItem );
+ void CacheRemove( PNS_ITEM* aItem );
+ void ClearCache( bool aStaticOnly = false );
+
+ void SetCollisionMask( int aMask )
+ {
+ m_collisionKindMask = aMask;
+ }
+
+ void SetEffortLevel( int aEffort )
+ {
+ m_effortLevel = aEffort;
+ }
+
+
+ void SetRestrictArea( const BOX2I& aArea )
+ {
+ m_restrictArea = aArea;
+ m_restrictAreaActive = true;
+ }
+
+private:
+ static const int MaxCachedItems = 256;
+
+ typedef std::vector<SHAPE_LINE_CHAIN> BREAKOUT_LIST;
+
+ struct CACHE_VISITOR;
+
+ struct CACHED_ITEM
+ {
+ int m_hits;
+ bool m_isStatic;
+ };
+
+ bool mergeObtuse( PNS_LINE* aLine );
+ bool mergeFull( PNS_LINE* aLine );
+ bool removeUglyCorners( PNS_LINE* aLine );
+ bool runSmartPads( PNS_LINE* aLine );
+ bool mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentLine, int step );
+ bool fanoutCleanup( PNS_LINE * aLine );
+ bool mergeDpSegments( PNS_DIFF_PAIR *aPair );
+ bool mergeDpStep( PNS_DIFF_PAIR *aPair, bool aTryP, int step );
+
+ bool checkColliding( PNS_ITEM* aItem, bool aUpdateCache = true );
+ bool checkColliding( PNS_LINE* aLine, const SHAPE_LINE_CHAIN& aOptPath );
+
+ void cacheAdd( PNS_ITEM* aItem, bool aIsStatic );
+ void removeCachedSegments( PNS_LINE* aLine, int aStartVertex = 0, int aEndVertex = -1 );
+
+ BREAKOUT_LIST circleBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
+ BREAKOUT_LIST rectBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
+ BREAKOUT_LIST ovalBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
+ BREAKOUT_LIST convexBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
+ BREAKOUT_LIST computeBreakouts( int aWidth, const PNS_ITEM* aItem, bool aPermitDiagonal ) const;
+
+ int smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd, int aEndVertex );
+
+ PNS_ITEM* findPadOrVia( int aLayer, int aNet, const VECTOR2I& aP ) const;
+
+ SHAPE_INDEX_LIST<PNS_ITEM*> m_cache;
+
+ typedef boost::unordered_map<PNS_ITEM*, CACHED_ITEM> CachedItemTags;
+ CachedItemTags m_cacheTags;
+ PNS_NODE* m_world;
+ int m_collisionKindMask;
+ int m_effortLevel;
+ bool m_keepPostures;
+
+ BOX2I m_restrictArea;
+ bool m_restrictAreaActive;
+};
+
+#endif
diff --git a/pcbnew/router/pns_placement_algo.h b/pcbnew/router/pns_placement_algo.h
new file mode 100644
index 0000000..6598d82
--- /dev/null
+++ b/pcbnew/router/pns_placement_algo.h
@@ -0,0 +1,185 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_PLACEMENT_ALGO_H
+#define __PNS_PLACEMENT_ALGO_H
+
+#include <math/vector2d.h>
+
+#include "pns_algo_base.h"
+#include "pns_sizes_settings.h"
+#include "pns_itemset.h"
+
+class PNS_ROUTER;
+class PNS_ITEM;
+class PNS_NODE;
+
+/**
+ * Class PNS_PLACEMENT_ALGO
+ *
+ * Abstract class for a P&S placement/dragging algorithm.
+ * All subtools (drag, single/diff pair routing and meandering)
+ * are derived from it.
+ */
+
+class PNS_PLACEMENT_ALGO : public PNS_ALGO_BASE
+{
+public:
+ PNS_PLACEMENT_ALGO( PNS_ROUTER* aRouter ) :
+ PNS_ALGO_BASE( aRouter ) {};
+
+ virtual ~PNS_PLACEMENT_ALGO () {};
+
+ /**
+ * Function Start()
+ *
+ * Starts placement/drag operation at point aP, taking item aStartItem as anchor
+ * (unless NULL).
+ */
+ virtual bool Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) = 0;
+
+ /**
+ * Function Move()
+ *
+ * Moves the end of the currently routed primtive(s) to the point aP, taking
+ * aEndItem as the anchor (if not NULL).
+ * (unless NULL).
+ */
+ virtual bool Move( const VECTOR2I& aP, PNS_ITEM* aEndItem ) = 0;
+
+ /**
+ * Function FixRoute()
+ *
+ * Commits the currently routed items to the parent node, taking
+ * aP as the final end point and aEndItem as the final anchor (if provided).
+ * @return true, if route has been commited. May return false if the routing
+ * result is violating design rules - in such case, the track is only committed
+ * if Settings.CanViolateDRC() is on.
+ */
+ virtual bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) = 0;
+
+ /**
+ * Function ToggleVia()
+ *
+ * Enables/disables a via at the end of currently routed trace.
+ */
+ virtual bool ToggleVia( bool aEnabled )
+ {
+ return false;
+ }
+
+ /**
+ * Function IsPlacingVia()
+ *
+ * Returns true if the placer is placing a via (or more vias).
+ */
+ virtual bool IsPlacingVia() const
+ {
+ return false;
+ }
+
+ /**
+ * Function SetLayer()
+ *
+ * Sets the current routing layer.
+ */
+ virtual bool SetLayer( int aLayer )
+ {
+ return false;
+ }
+
+ /**
+ * Function Traces()
+ *
+ * Returns all routed/tuned traces.
+ */
+ virtual const PNS_ITEMSET Traces() = 0;
+
+ /**
+ * Function CurrentEnd()
+ *
+ * Returns the current end of the line(s) being placed/tuned. It may not be equal
+ * to the cursor position due to collisions.
+ */
+ virtual const VECTOR2I& CurrentEnd() const = 0;
+
+ /**
+ * Function CurrentNets()
+ *
+ * Returns the net code(s) of currently routed track(s).
+ */
+ virtual const std::vector<int> CurrentNets() const = 0;
+
+ /**
+ * Function CurrentLayer()
+ *
+ * Returns the layer of currently routed track.
+ */
+ virtual int CurrentLayer() const = 0;
+
+ /**
+ * Function CurrentNode()
+ *
+ * Returns the most recent board state.
+ */
+ virtual PNS_NODE* CurrentNode( bool aLoopsRemoved = false ) const = 0;
+
+ /**
+ * Function FlipPosture()
+ *
+ * Toggles the current posture (straight/diagonal) of the trace head.
+ */
+ virtual void FlipPosture()
+ {
+ }
+
+ /**
+ * Function UpdateSizes()
+ *
+ * Performs on-the-fly update of the width, via diameter & drill size from
+ * a settings class. Used to dynamically change these parameters as
+ * the track is routed.
+ */
+ virtual void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes )
+ {
+ }
+
+ /**
+ * Function SetOrthoMode()
+ *
+ * Forces the router to place a straight 90/45 degree trace (with the end
+ * as near to the cursor as possible) instead of a standard 135 degree
+ * two-segment bend.
+ */
+ virtual void SetOrthoMode ( bool aOrthoMode )
+ {
+ }
+
+ /**
+ * Function GetModifiedNets
+ *
+ * Returns the net codes of all currently routed trace(s)
+ */
+ virtual void GetModifiedNets( std::vector<int> &aNets ) const
+ {
+ }
+};
+
+#endif
diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp
new file mode 100644
index 0000000..6f64f96
--- /dev/null
+++ b/pcbnew/router/pns_router.cpp
@@ -0,0 +1,1084 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cstdio>
+#include <vector>
+
+#include <boost/foreach.hpp>
+
+#include <view/view.h>
+#include <view/view_item.h>
+#include <view/view_group.h>
+#include <gal/graphics_abstraction_layer.h>
+
+#include <pcb_painter.h>
+
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+#include <geometry/shape_rect.h>
+#include <geometry/shape_circle.h>
+
+#include <tools/grid_helper.h>
+
+#include "trace.h"
+#include "pns_node.h"
+#include "pns_line_placer.h"
+#include "pns_line.h"
+#include "pns_solid.h"
+#include "pns_utils.h"
+#include "pns_router.h"
+#include "pns_shove.h"
+#include "pns_dragger.h"
+#include "pns_topology.h"
+#include "pns_diff_pair_placer.h"
+#include "pns_meander_placer.h"
+#include "pns_meander_skew_placer.h"
+#include "pns_dp_meander_placer.h"
+
+#include <router/router_preview_item.h>
+
+#include <class_board.h>
+#include <class_board_connected_item.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <ratsnest_data.h>
+#include <layers_id_colors_and_visibility.h>
+
+// an ugly singleton for drawing debug items within the router context.
+// To be fixed sometime in the future.
+static PNS_ROUTER* theRouter;
+
+
+PNS_PCBNEW_CLEARANCE_FUNC::PNS_PCBNEW_CLEARANCE_FUNC( PNS_ROUTER* aRouter ) :
+ m_router( aRouter )
+{
+ BOARD* brd = m_router->GetBoard();
+ PNS_NODE* world = m_router->GetWorld();
+
+ PNS_TOPOLOGY topo( world );
+ m_clearanceCache.resize( brd->GetNetCount() );
+ m_useDpGap = false;
+
+ for( unsigned int i = 0; i < brd->GetNetCount(); i++ )
+ {
+ NETINFO_ITEM* ni = brd->FindNet( i );
+ if( ni == NULL )
+ continue;
+
+ CLEARANCE_ENT ent;
+ ent.coupledNet = topo.DpCoupledNet( i );
+
+ wxString netClassName = ni->GetClassName();
+ NETCLASSPTR nc = brd->GetDesignSettings().m_NetClasses.Find( netClassName );
+
+ int clearance = nc->GetClearance();
+ ent.clearance = clearance;
+ m_clearanceCache[i] = ent;
+
+ TRACE( 1, "Add net %d netclass %s clearance %d", i % netClassName.mb_str() %
+ clearance );
+ }
+
+ m_overrideEnabled = false;
+ m_defaultClearance = Millimeter2iu( 0.254 ); // aBoard->m_NetClasses.Find ("Default clearance")->GetClearance();
+ m_overrideNetA = 0;
+ m_overrideNetB = 0;
+ m_overrideClearance = 0;
+}
+
+
+PNS_PCBNEW_CLEARANCE_FUNC::~PNS_PCBNEW_CLEARANCE_FUNC()
+{
+}
+
+
+int PNS_PCBNEW_CLEARANCE_FUNC::localPadClearance( const PNS_ITEM* aItem ) const
+{
+ if( !aItem->Parent() || aItem->Parent()->Type() != PCB_PAD_T )
+ return 0;
+
+ const D_PAD* pad = static_cast<D_PAD*>( aItem->Parent() );
+ return pad->GetLocalClearance();
+}
+
+
+int PNS_PCBNEW_CLEARANCE_FUNC::operator()( const PNS_ITEM* aA, const PNS_ITEM* aB )
+{
+ int net_a = aA->Net();
+ int cl_a = ( net_a >= 0 ? m_clearanceCache[net_a].clearance : m_defaultClearance );
+ int net_b = aB->Net();
+ int cl_b = ( net_b >= 0 ? m_clearanceCache[net_b].clearance : m_defaultClearance );
+
+ bool linesOnly = aA->OfKind( PNS_ITEM::SEGMENT | PNS_ITEM::LINE ) && aB->OfKind( PNS_ITEM::SEGMENT | PNS_ITEM::LINE );
+
+ if( net_a == net_b )
+ return 0;
+
+ if( m_useDpGap && linesOnly && net_a >= 0 && net_b >= 0 && m_clearanceCache[net_a].coupledNet == net_b )
+ {
+ cl_a = cl_b = m_router->Sizes().DiffPairGap() - 2 * PNS_HULL_MARGIN;
+ }
+
+ int pad_a = localPadClearance( aA );
+ int pad_b = localPadClearance( aB );
+
+ cl_a = std::max( cl_a, pad_a );
+ cl_b = std::max( cl_b, pad_b );
+
+ return std::max( cl_a, cl_b );
+}
+
+
+// fixme: ugly hack to make the optimizer respect gap width for currently routed differential pair.
+void PNS_PCBNEW_CLEARANCE_FUNC::OverrideClearance( bool aEnable, int aNetA, int aNetB , int aClearance )
+{
+ m_overrideEnabled = aEnable;
+ m_overrideNetA = aNetA;
+ m_overrideNetB = aNetB;
+ m_overrideClearance = aClearance;
+}
+
+
+PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
+{
+ PNS_LAYERSET layers( 0, MAX_CU_LAYERS - 1 );
+
+ // ignore non-copper pads
+ if ( (aPad->GetLayerSet() & LSET::AllCuMask()).none() )
+ return NULL;
+
+ switch( aPad->GetAttribute() )
+ {
+ case PAD_ATTRIB_STANDARD:
+ break;
+
+ case PAD_ATTRIB_SMD:
+ case PAD_ATTRIB_HOLE_NOT_PLATED:
+ case PAD_ATTRIB_CONN:
+ {
+ LSET lmsk = aPad->GetLayerSet();
+ bool is_copper = false;
+
+ for( int i = 0; i < MAX_CU_LAYERS; i++ )
+ {
+ if( lmsk[i] )
+ {
+ is_copper = true;
+ if( aPad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
+ layers = PNS_LAYERSET( i );
+ break;
+ }
+ }
+
+ if( !is_copper )
+ return NULL;
+ }
+ break;
+
+ default:
+ TRACE( 0, "unsupported pad type 0x%x", aPad->GetAttribute() );
+ return NULL;
+ }
+
+ PNS_SOLID* solid = new PNS_SOLID;
+
+ solid->SetLayers( layers );
+ solid->SetNet( aPad->GetNetCode() );
+ solid->SetParent( aPad );
+
+ wxPoint wx_c = aPad->ShapePos();
+ wxSize wx_sz = aPad->GetSize();
+ wxPoint offset = aPad->GetOffset();
+
+ VECTOR2I c( wx_c.x, wx_c.y );
+ VECTOR2I sz( wx_sz.x, wx_sz.y );
+
+ RotatePoint( &offset, aPad->GetOrientation() );
+
+ solid->SetPos( VECTOR2I( c.x - offset.x, c.y - offset.y ) );
+ solid->SetOffset ( VECTOR2I ( offset.x, offset.y ) );
+
+ double orient = aPad->GetOrientation() / 10.0;
+
+ if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
+ {
+ solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
+ }
+ else
+ {
+ if( orient == 0.0 || orient == 90.0 || orient == 180.0 || orient == 270.0 )
+ {
+ if( orient == 90.0 || orient == 270.0 )
+ sz = VECTOR2I( sz.y, sz.x );
+
+ switch( aPad->GetShape() )
+ {
+ case PAD_SHAPE_OVAL:
+ if( sz.x == sz.y )
+ solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
+ else
+ {
+ VECTOR2I delta;
+
+ if( sz.x > sz.y )
+ delta = VECTOR2I( ( sz.x - sz.y ) / 2, 0 );
+ else
+ delta = VECTOR2I( 0, ( sz.y - sz.x ) / 2 );
+
+ SHAPE_SEGMENT* shape = new SHAPE_SEGMENT( c - delta, c + delta,
+ std::min( sz.x, sz.y ) );
+ solid->SetShape( shape );
+ }
+ break;
+
+ case PAD_SHAPE_RECT:
+ solid->SetShape( new SHAPE_RECT( c - sz / 2, sz.x, sz.y ) );
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ {
+ wxPoint coords[4];
+ aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() );
+ SHAPE_CONVEX* shape = new SHAPE_CONVEX();
+
+ for( int ii = 0; ii < 4; ii++ )
+ {
+ shape->Append( wx_c + coords[ii] );
+ }
+
+ solid->SetShape( shape );
+ break;
+ }
+
+ default:
+ TRACEn( 0, "unsupported pad shape" );
+ delete solid;
+ return NULL;
+ }
+ }
+ else
+ {
+ switch( aPad->GetShape() )
+ {
+ // PAD_SHAPE_CIRCLE already handled above
+
+ case PAD_SHAPE_OVAL:
+ if( sz.x == sz.y )
+ solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
+ else
+ {
+ wxPoint start;
+ wxPoint end;
+ wxPoint corner;
+
+ SHAPE_CONVEX* shape = new SHAPE_CONVEX();
+
+ int w = aPad->BuildSegmentFromOvalShape( start, end, 0.0, wxSize( 0, 0 ) );
+
+ if( start.y == 0 )
+ corner = wxPoint( start.x, -( w / 2 ) );
+ else
+ corner = wxPoint( w / 2, start.y );
+
+ RotatePoint( &start, aPad->GetOrientation() );
+ RotatePoint( &corner, aPad->GetOrientation() );
+ shape->Append( wx_c + corner );
+
+ for( int rot = 100; rot <= 1800; rot += 100 )
+ {
+ wxPoint p( corner );
+ RotatePoint( &p, start, rot );
+ shape->Append( wx_c + p );
+ }
+
+ if( end.y == 0 )
+ corner = wxPoint( end.x, w / 2 );
+ else
+ corner = wxPoint( -( w / 2 ), end.y );
+
+ RotatePoint( &end, aPad->GetOrientation() );
+ RotatePoint( &corner, aPad->GetOrientation() );
+ shape->Append( wx_c + corner );
+
+ for( int rot = 100; rot <= 1800; rot += 100 )
+ {
+ wxPoint p( corner );
+ RotatePoint( &p, end, rot );
+ shape->Append( wx_c + p );
+ }
+
+ solid->SetShape( shape );
+ }
+ break;
+
+ case PAD_SHAPE_RECT:
+ case PAD_SHAPE_TRAPEZOID:
+ {
+ wxPoint coords[4];
+ aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() );
+
+ SHAPE_CONVEX* shape = new SHAPE_CONVEX();
+ for( int ii = 0; ii < 4; ii++ )
+ {
+ shape->Append( wx_c + coords[ii] );
+ }
+
+ solid->SetShape( shape );
+ break;
+ }
+
+ default:
+ TRACEn( 0, "unsupported pad shape" );
+ delete solid;
+
+ return NULL;
+ }
+ }
+ }
+ return solid;
+}
+
+
+PNS_ITEM* PNS_ROUTER::syncTrack( TRACK* aTrack )
+{
+ PNS_SEGMENT* s =
+ new PNS_SEGMENT( SEG( aTrack->GetStart(), aTrack->GetEnd() ), aTrack->GetNetCode() );
+
+ s->SetWidth( aTrack->GetWidth() );
+ s->SetLayers( PNS_LAYERSET( aTrack->GetLayer() ) );
+ s->SetParent( aTrack );
+ return s;
+}
+
+
+PNS_ITEM* PNS_ROUTER::syncVia( VIA* aVia )
+{
+ LAYER_ID top, bottom;
+ aVia->LayerPair( &top, &bottom );
+ PNS_VIA* v = new PNS_VIA(
+ aVia->GetPosition(),
+ PNS_LAYERSET( top, bottom ),
+ aVia->GetWidth(),
+ aVia->GetDrillValue(),
+ aVia->GetNetCode(),
+ aVia->GetViaType() );
+
+ v->SetParent( aVia );
+
+ return v;
+}
+
+
+void PNS_ROUTER::SetBoard( BOARD* aBoard )
+{
+ m_board = aBoard;
+ TRACE( 1, "m_board = %p\n", m_board );
+}
+
+
+void PNS_ROUTER::SyncWorld()
+{
+ if( !m_board )
+ {
+ TRACEn( 0, "No board attached, aborting sync." );
+ return;
+ }
+
+ ClearWorld();
+
+ m_world = new PNS_NODE();
+
+ for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ PNS_ITEM* solid = syncPad( pad );
+
+ if( solid )
+ m_world->Add( solid );
+ }
+ }
+
+ for( TRACK* t = m_board->m_Track; t; t = t->Next() )
+ {
+ KICAD_T type = t->Type();
+ PNS_ITEM* item = NULL;
+
+ if( type == PCB_TRACE_T )
+ item = syncTrack( t );
+ else if( type == PCB_VIA_T )
+ item = syncVia( static_cast<VIA*>( t ) );
+
+ if( item )
+ m_world->Add( item );
+ }
+
+ int worstClearance = m_board->GetDesignSettings().GetBiggestClearanceValue();
+ m_clearanceFunc = new PNS_PCBNEW_CLEARANCE_FUNC( this );
+ m_world->SetClearanceFunctor( m_clearanceFunc );
+ m_world->SetMaxClearance( 4 * worstClearance );
+}
+
+
+PNS_ROUTER::PNS_ROUTER()
+{
+ theRouter = this;
+
+ m_clearanceFunc = NULL;
+
+ m_state = IDLE;
+ m_world = NULL;
+ m_placer = NULL;
+ m_previewItems = NULL;
+ m_board = NULL;
+ m_dragger = NULL;
+ m_mode = PNS_MODE_ROUTE_SINGLE;
+
+ // Initialize all other variables:
+ m_lastNode = NULL;
+ m_shove = NULL;
+ m_iterLimit = 0;
+ m_showInterSteps = false;
+ m_snapshotIter = 0;
+ m_view = NULL;
+ m_snappingEnabled = false;
+ m_violation = false;
+ m_gridHelper = NULL;
+
+}
+
+
+void PNS_ROUTER::SetView( KIGFX::VIEW* aView )
+{
+ if( m_previewItems )
+ {
+ m_previewItems->FreeItems();
+ delete m_previewItems;
+ }
+
+ m_view = aView;
+ m_previewItems = new KIGFX::VIEW_GROUP( m_view );
+ m_previewItems->SetLayer( ITEM_GAL_LAYER( GP_OVERLAY ) );
+ m_view->Add( m_previewItems );
+ m_previewItems->ViewSetVisible( true );
+}
+
+
+PNS_ROUTER* PNS_ROUTER::GetInstance()
+{
+ return theRouter;
+}
+
+
+PNS_ROUTER::~PNS_ROUTER()
+{
+ ClearWorld();
+ theRouter = NULL;
+
+ if( m_previewItems )
+ delete m_previewItems;
+}
+
+
+void PNS_ROUTER::ClearWorld()
+{
+ if( m_world )
+ {
+ m_world->KillChildren();
+ delete m_world;
+ }
+
+ if( m_clearanceFunc )
+ delete m_clearanceFunc;
+
+ if( m_placer )
+ delete m_placer;
+
+ if( m_previewItems )
+ delete m_previewItems;
+
+ m_clearanceFunc = NULL;
+ m_world = NULL;
+ m_placer = NULL;
+ m_previewItems = NULL;
+}
+
+
+bool PNS_ROUTER::RoutingInProgress() const
+{
+ return m_state != IDLE;
+}
+
+
+const PNS_ITEMSET PNS_ROUTER::QueryHoverItems( const VECTOR2I& aP )
+{
+ if( m_state == IDLE )
+ return m_world->HitTest( aP );
+ else
+ {
+ return m_placer->CurrentNode()->HitTest( aP );
+ }
+}
+
+
+const VECTOR2I PNS_ROUTER::SnapToItem( PNS_ITEM* aItem, VECTOR2I aP, bool& aSplitsSegment )
+{
+ VECTOR2I anchor;
+
+ if( !aItem )
+ {
+ aSplitsSegment = false;
+ return aP;
+ }
+
+ switch( aItem->Kind() )
+ {
+ case PNS_ITEM::SOLID:
+ anchor = static_cast<PNS_SOLID*>( aItem )->Pos();
+ aSplitsSegment = false;
+ break;
+
+ case PNS_ITEM::VIA:
+ anchor = static_cast<PNS_VIA*>( aItem )->Pos();
+ aSplitsSegment = false;
+ break;
+
+ case PNS_ITEM::SEGMENT:
+ {
+ PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( aItem );
+ const SEG& s = seg->Seg();
+ int w = seg->Width();
+
+ aSplitsSegment = false;
+
+ if( ( aP - s.A ).EuclideanNorm() < w / 2 )
+ anchor = s.A;
+ else if( ( aP - s.B ).EuclideanNorm() < w / 2 )
+ anchor = s.B;
+ else
+ {
+ anchor = m_gridHelper->AlignToSegment ( aP, s );
+ aSplitsSegment = (anchor != s.A && anchor != s.B );
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return anchor;
+}
+
+
+bool PNS_ROUTER::StartDragging( const VECTOR2I& aP, PNS_ITEM* aStartItem )
+{
+ if( !aStartItem || aStartItem->OfKind( PNS_ITEM::SOLID ) )
+ return false;
+
+ m_dragger = new PNS_DRAGGER( this );
+ m_dragger->SetWorld( m_world );
+
+ if( m_dragger->Start ( aP, aStartItem ) )
+ m_state = DRAG_SEGMENT;
+ else
+ {
+ delete m_dragger;
+ m_state = IDLE;
+ return false;
+ }
+
+ return true;
+}
+
+bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem, int aLayer )
+{
+ m_clearanceFunc->UseDpGap( false );
+
+ switch( m_mode )
+ {
+ case PNS_MODE_ROUTE_SINGLE:
+ m_placer = new PNS_LINE_PLACER( this );
+ break;
+ case PNS_MODE_ROUTE_DIFF_PAIR:
+ m_placer = new PNS_DIFF_PAIR_PLACER( this );
+ m_clearanceFunc->UseDpGap( true );
+ break;
+ case PNS_MODE_TUNE_SINGLE:
+ m_placer = new PNS_MEANDER_PLACER( this );
+ break;
+ case PNS_MODE_TUNE_DIFF_PAIR:
+ m_placer = new PNS_DP_MEANDER_PLACER( this );
+ break;
+ case PNS_MODE_TUNE_DIFF_PAIR_SKEW:
+ m_placer = new PNS_MEANDER_SKEW_PLACER( this );
+ break;
+
+ default:
+ return false;
+ }
+
+ m_placer->UpdateSizes ( m_sizes );
+ m_placer->SetLayer( aLayer );
+
+ bool rv = m_placer->Start( aP, aStartItem );
+
+ if( !rv )
+ return false;
+
+ m_currentEnd = aP;
+ m_state = ROUTE_TRACK;
+ return rv;
+}
+
+
+BOARD* PNS_ROUTER::GetBoard()
+{
+ return m_board;
+}
+
+
+void PNS_ROUTER::eraseView()
+{
+ BOOST_FOREACH( BOARD_ITEM* item, m_hiddenItems )
+ {
+ item->ViewSetVisible( true );
+ }
+
+ m_hiddenItems.clear();
+
+ if( m_previewItems )
+ {
+ m_previewItems->FreeItems();
+ m_previewItems->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+}
+
+
+void PNS_ROUTER::DisplayItem( const PNS_ITEM* aItem, int aColor, int aClearance )
+{
+ ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, m_previewItems );
+
+ if( aColor >= 0 )
+ pitem->SetColor( KIGFX::COLOR4D( aColor ) );
+
+ if( aClearance >= 0 )
+ pitem->SetClearance( aClearance );
+
+ m_previewItems->Add( pitem );
+
+ pitem->ViewSetVisible( true );
+ m_previewItems->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY | KIGFX::VIEW_ITEM::APPEARANCE );
+}
+
+
+void PNS_ROUTER::DisplayItems( const PNS_ITEMSET& aItems )
+{
+ BOOST_FOREACH( const PNS_ITEM* item, aItems.CItems() )
+ DisplayItem( item );
+}
+
+
+void PNS_ROUTER::DisplayDebugLine( const SHAPE_LINE_CHAIN& aLine, int aType, int aWidth )
+{
+ ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( NULL, m_previewItems );
+
+ pitem->Line( aLine, aWidth, aType );
+ m_previewItems->Add( pitem );
+ pitem->ViewSetVisible( true );
+ m_previewItems->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY | KIGFX::VIEW_ITEM::APPEARANCE );
+}
+
+
+void PNS_ROUTER::DisplayDebugPoint( const VECTOR2I aPos, int aType )
+{
+ ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( NULL, m_previewItems );
+
+ pitem->Point( aPos, aType );
+ m_previewItems->Add( pitem );
+ pitem->ViewSetVisible( true );
+ m_previewItems->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY | KIGFX::VIEW_ITEM::APPEARANCE );
+}
+
+
+void PNS_ROUTER::Move( const VECTOR2I& aP, PNS_ITEM* endItem )
+{
+ m_currentEnd = aP;
+
+ switch( m_state )
+ {
+ case ROUTE_TRACK:
+ movePlacing( aP, endItem );
+ break;
+
+ case DRAG_SEGMENT:
+ moveDragging( aP, endItem );
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void PNS_ROUTER::moveDragging( const VECTOR2I& aP, PNS_ITEM* aEndItem )
+{
+ eraseView();
+
+ m_dragger->Drag( aP );
+ PNS_ITEMSET dragged = m_dragger->Traces();
+
+ updateView( m_dragger->CurrentNode(), dragged );
+}
+
+
+void PNS_ROUTER::markViolations( PNS_NODE* aNode, PNS_ITEMSET& aCurrent,
+ PNS_NODE::ITEM_VECTOR& aRemoved )
+{
+ BOOST_FOREACH( PNS_ITEM* item, aCurrent.Items() )
+ {
+ PNS_NODE::OBSTACLES obstacles;
+
+ aNode->QueryColliding( item, obstacles, PNS_ITEM::ANY );
+
+ if( item->OfKind( PNS_ITEM::LINE ) )
+ {
+ PNS_LINE* l = static_cast<PNS_LINE*>( item );
+
+ if( l->EndsWithVia() )
+ {
+ PNS_VIA v( l->Via() );
+ aNode->QueryColliding( &v, obstacles, PNS_ITEM::ANY );
+ }
+ }
+
+ BOOST_FOREACH( PNS_OBSTACLE& obs, obstacles )
+ {
+ int clearance = aNode->GetClearance( item, obs.m_item );
+ std::auto_ptr<PNS_ITEM> tmp( obs.m_item->Clone() );
+ tmp->Mark( MK_VIOLATION );
+ DisplayItem( tmp.get(), -1, clearance );
+ aRemoved.push_back( obs.m_item );
+ }
+ }
+}
+
+
+void PNS_ROUTER::updateView( PNS_NODE* aNode, PNS_ITEMSET& aCurrent )
+{
+ PNS_NODE::ITEM_VECTOR removed, added;
+ PNS_NODE::OBSTACLES obstacles;
+
+ if( !aNode )
+ return;
+
+ if( Settings().Mode() == RM_MarkObstacles )
+ markViolations( aNode, aCurrent, removed );
+
+ aNode->GetUpdatedItems( removed, added );
+
+ BOOST_FOREACH( PNS_ITEM* item, added )
+ {
+ DisplayItem( item );
+ }
+
+ BOOST_FOREACH( PNS_ITEM* item, removed )
+ {
+ BOARD_CONNECTED_ITEM* parent = item->Parent();
+
+ if( parent )
+ {
+ if( parent->ViewIsVisible() )
+ m_hiddenItems.insert( parent );
+
+ parent->ViewSetVisible( false );
+ parent->ViewUpdate( KIGFX::VIEW_ITEM::APPEARANCE );
+ }
+ }
+}
+
+
+void PNS_ROUTER::UpdateSizes ( const PNS_SIZES_SETTINGS& aSizes )
+{
+ m_sizes = aSizes;
+
+ // Change track/via size settings
+ if( m_state == ROUTE_TRACK)
+ {
+ m_placer->UpdateSizes( m_sizes );
+ }
+}
+
+
+void PNS_ROUTER::movePlacing( const VECTOR2I& aP, PNS_ITEM* aEndItem )
+{
+ eraseView();
+
+ m_placer->Move( aP, aEndItem );
+ PNS_ITEMSET current = m_placer->Traces();
+
+ BOOST_FOREACH( const PNS_ITEM* item, current.CItems() )
+ {
+ if( !item->OfKind( PNS_ITEM::LINE ) )
+ continue;
+
+ const PNS_LINE* l = static_cast<const PNS_LINE*>( item );
+ DisplayItem( l );
+
+ if( l->EndsWithVia() )
+ DisplayItem( &l->Via() );
+ }
+
+ //PNS_ITEMSET tmp( &current );
+
+ updateView( m_placer->CurrentNode( true ), current );
+}
+
+
+void PNS_ROUTER::CommitRouting( PNS_NODE* aNode )
+{
+ PNS_NODE::ITEM_VECTOR removed, added;
+
+ aNode->GetUpdatedItems( removed, added );
+
+ for( unsigned int i = 0; i < removed.size(); i++ )
+ {
+ BOARD_CONNECTED_ITEM* parent = removed[i]->Parent();
+
+ if( parent )
+ {
+ m_view->Remove( parent );
+ m_board->Remove( parent );
+ m_undoBuffer.PushItem( ITEM_PICKER( parent, UR_DELETED ) );
+ }
+ }
+
+ BOOST_FOREACH( PNS_ITEM* item, added )
+ {
+ BOARD_CONNECTED_ITEM* newBI = NULL;
+
+ switch( item->Kind() )
+ {
+ case PNS_ITEM::SEGMENT:
+ {
+ PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( item );
+ TRACK* track = new TRACK( m_board );
+ const SEG& s = seg->Seg();
+
+ track->SetStart( wxPoint( s.A.x, s.A.y ) );
+ track->SetEnd( wxPoint( s.B.x, s.B.y ) );
+ track->SetWidth( seg->Width() );
+ track->SetLayer( ToLAYER_ID( seg->Layers().Start() ) );
+ track->SetNetCode( seg->Net() > 0 ? seg->Net() : 0 );
+ newBI = track;
+ break;
+ }
+
+ case PNS_ITEM::VIA:
+ {
+ VIA* via_board = new VIA( m_board );
+ PNS_VIA* via = static_cast<PNS_VIA*>( item );
+ via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) );
+ via_board->SetWidth( via->Diameter() );
+ via_board->SetDrill( via->Drill() );
+ via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 );
+ via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair()
+ via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ),
+ ToLAYER_ID( via->Layers().End() ) );
+ newBI = via_board;
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if( newBI )
+ {
+ item->SetParent( newBI );
+ newBI->ClearFlags();
+ m_view->Add( newBI );
+ m_board->Add( newBI );
+ m_undoBuffer.PushItem( ITEM_PICKER( newBI, UR_NEW ) );
+ newBI->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ m_board->GetRatsnest()->Recalculate();
+ m_world->Commit( aNode );
+}
+
+
+bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
+{
+ bool rv = false;
+
+ switch( m_state )
+ {
+ case ROUTE_TRACK:
+ rv = m_placer->FixRoute( aP, aEndItem );
+ break;
+
+ case DRAG_SEGMENT:
+ rv = m_dragger->FixRoute();
+ break;
+
+ default:
+ break;
+ }
+
+ if( rv )
+ StopRouting();
+
+ return rv;
+}
+
+
+void PNS_ROUTER::StopRouting()
+{
+ // Update the ratsnest with new changes
+
+ if( m_placer )
+ {
+ std::vector<int> nets;
+ m_placer->GetModifiedNets( nets );
+
+ BOOST_FOREACH ( int n, nets )
+ {
+ // Update the ratsnest with new changes
+ m_board->GetRatsnest()->Recalculate( n );
+ }
+ }
+
+ if( !RoutingInProgress() )
+ return;
+
+ if( m_placer )
+ delete m_placer;
+
+ if( m_dragger )
+ delete m_dragger;
+
+ m_placer = NULL;
+ m_dragger = NULL;
+
+ eraseView();
+
+ m_state = IDLE;
+ m_world->KillChildren();
+ m_world->ClearRanks();
+}
+
+
+void PNS_ROUTER::FlipPosture()
+{
+ if( m_state == ROUTE_TRACK )
+ {
+ m_placer->FlipPosture();
+ }
+}
+
+
+void PNS_ROUTER::SwitchLayer( int aLayer )
+{
+ switch( m_state )
+ {
+ case ROUTE_TRACK:
+ m_placer->SetLayer( aLayer );
+ break;
+ default:
+ break;
+ }
+}
+
+
+void PNS_ROUTER::ToggleViaPlacement()
+{
+ if( m_state == ROUTE_TRACK )
+ {
+ bool toggle = !m_placer->IsPlacingVia();
+ m_placer->ToggleVia( toggle );
+ }
+}
+
+
+const std::vector<int> PNS_ROUTER::GetCurrentNets() const
+{
+ if( m_placer )
+ return m_placer->CurrentNets();
+
+ return std::vector<int>();
+}
+
+
+int PNS_ROUTER::GetCurrentLayer() const
+{
+ if( m_placer )
+ return m_placer->CurrentLayer();
+ return -1;
+}
+
+
+void PNS_ROUTER::DumpLog()
+{
+ PNS_LOGGER* logger = NULL;
+
+ switch( m_state )
+ {
+ case DRAG_SEGMENT:
+ logger = m_dragger->Logger();
+ break;
+
+ case ROUTE_TRACK:
+ logger = m_placer->Logger();
+ break;
+
+ default:
+ break;
+ }
+
+ if( logger )
+ logger->Save( "/tmp/shove.log" );
+}
+
+
+bool PNS_ROUTER::IsPlacingVia() const
+{
+ if( !m_placer )
+ return false;
+
+ return m_placer->IsPlacingVia();
+}
+
+
+void PNS_ROUTER::SetOrthoMode( bool aEnable )
+{
+ if( !m_placer )
+ return;
+
+ m_placer->SetOrthoMode( aEnable );
+}
+
+
+void PNS_ROUTER::SetMode( PNS_ROUTER_MODE aMode )
+{
+ m_mode = aMode;
+}
diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h
new file mode 100644
index 0000000..4bc4bc3
--- /dev/null
+++ b/pcbnew/router/pns_router.h
@@ -0,0 +1,285 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_ROUTER_H
+#define __PNS_ROUTER_H
+
+#include <list>
+
+#include <boost/optional.hpp>
+#include <boost/unordered_set.hpp>
+
+#include <geometry/shape_line_chain.h>
+#include <class_undoredo_container.h>
+
+#include "pns_routing_settings.h"
+#include "pns_sizes_settings.h"
+#include "pns_item.h"
+#include "pns_itemset.h"
+#include "pns_node.h"
+
+class BOARD;
+class BOARD_ITEM;
+class D_PAD;
+class TRACK;
+class VIA;
+class GRID_HELPER;
+class PNS_NODE;
+class PNS_DIFF_PAIR_PLACER;
+class PNS_PLACEMENT_ALGO;
+class PNS_LINE_PLACER;
+class PNS_ITEM;
+class PNS_LINE;
+class PNS_SOLID;
+class PNS_SEGMENT;
+class PNS_JOINT;
+class PNS_VIA;
+class PNS_CLEARANCE_FUNC;
+class PNS_SHOVE;
+class PNS_DRAGGER;
+
+namespace KIGFX
+{
+ class VIEW;
+ class VIEW_GROUP;
+};
+
+
+enum PNS_ROUTER_MODE {
+ PNS_MODE_ROUTE_SINGLE = 1,
+ PNS_MODE_ROUTE_DIFF_PAIR,
+ PNS_MODE_TUNE_SINGLE,
+ PNS_MODE_TUNE_DIFF_PAIR,
+ PNS_MODE_TUNE_DIFF_PAIR_SKEW
+};
+
+/**
+ * Class PNS_ROUTER
+ *
+ * Main router class.
+ */
+class PNS_ROUTER
+{
+private:
+ enum RouterState
+ {
+ IDLE,
+ DRAG_SEGMENT,
+ ROUTE_TRACK
+ };
+
+public:
+ PNS_ROUTER();
+ ~PNS_ROUTER();
+
+ void SetMode ( PNS_ROUTER_MODE aMode );
+ PNS_ROUTER_MODE Mode() const { return m_mode; }
+
+ static PNS_ROUTER* GetInstance();
+
+ void ClearWorld();
+ void SetBoard( BOARD* aBoard );
+ void SyncWorld();
+
+ void SetView( KIGFX::VIEW* aView );
+
+ bool RoutingInProgress() const;
+ bool StartRouting( const VECTOR2I& aP, PNS_ITEM* aItem, int aLayer );
+ void Move( const VECTOR2I& aP, PNS_ITEM* aItem );
+ bool FixRoute( const VECTOR2I& aP, PNS_ITEM* aItem );
+
+ void StopRouting();
+
+ int GetClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const;
+
+ PNS_NODE* GetWorld() const
+ {
+ return m_world;
+ }
+
+ void FlipPosture();
+
+ void DisplayItem( const PNS_ITEM* aItem, int aColor = -1, int aClearance = -1 );
+ void DisplayItems( const PNS_ITEMSET& aItems );
+
+ void DisplayDebugLine( const SHAPE_LINE_CHAIN& aLine, int aType = 0, int aWidth = 0 );
+ void DisplayDebugPoint( const VECTOR2I aPos, int aType = 0 );
+ void DisplayDebugBox( const BOX2I& aBox, int aType = 0, int aWidth = 0 );
+
+ void SwitchLayer( int layer );
+
+ void ToggleViaPlacement();
+ void SetOrthoMode ( bool aEnable );
+
+ int GetCurrentLayer() const;
+ const std::vector<int> GetCurrentNets() const;
+
+ void DumpLog();
+
+ PNS_CLEARANCE_FUNC* GetClearanceFunc() const
+ {
+ return m_clearanceFunc;
+ }
+ bool IsPlacingVia() const;
+
+ const PNS_ITEMSET QueryHoverItems( const VECTOR2I& aP );
+ const VECTOR2I SnapToItem( PNS_ITEM* aItem, VECTOR2I aP, bool& aSplitsSegment );
+
+ bool StartDragging( const VECTOR2I& aP, PNS_ITEM* aItem );
+
+ void SetIterLimit( int aX ) { m_iterLimit = aX; }
+ int GetIterLimit() const { return m_iterLimit; };
+
+ void SetShowIntermediateSteps( bool aX, int aSnapshotIter = -1 )
+ {
+ m_showInterSteps = aX;
+ m_snapshotIter = aSnapshotIter;
+ }
+
+ bool GetShowIntermediateSteps() const { return m_showInterSteps; }
+ int GetShapshotIter() const { return m_snapshotIter; }
+
+ PNS_ROUTING_SETTINGS& Settings() { return m_settings; }
+
+ void CommitRouting( PNS_NODE* aNode );
+
+ /**
+ * Returns the last changes introduced by the router (since the last time ClearLastChanges()
+ * was called or a new track has been started).
+ */
+ const PICKED_ITEMS_LIST& GetUndoBuffer() const
+ {
+ return m_undoBuffer;
+ }
+
+ /**
+ * Clears the list of recent changes, saved to be stored in the undo buffer.
+ */
+ void ClearUndoBuffer()
+ {
+ m_undoBuffer.ClearItemsList();
+ }
+
+ /**
+ * Applies stored settings.
+ * @see Settings()
+ */
+ void UpdateSizes( const PNS_SIZES_SETTINGS& aSizes );
+
+ /**
+ * Changes routing settings to ones passed in the parameter.
+ * @param aSettings are the new settings.
+ */
+ void LoadSettings( const PNS_ROUTING_SETTINGS& aSettings )
+ {
+ m_settings = aSettings;
+ }
+
+ void EnableSnapping( bool aEnable )
+ {
+ m_snappingEnabled = aEnable;
+ }
+
+ bool SnappingEnabled() const
+ {
+ return m_snappingEnabled;
+ }
+
+ PNS_SIZES_SETTINGS& Sizes()
+ {
+ return m_sizes;
+ }
+
+ PNS_ITEM *QueryItemByParent ( const BOARD_ITEM *aItem ) const;
+
+ BOARD *GetBoard();
+
+ void SetFailureReason ( const wxString& aReason ) { m_failureReason = aReason; }
+ const wxString& FailureReason() const { return m_failureReason; }
+
+ PNS_PLACEMENT_ALGO *Placer() { return m_placer; }
+
+ void SetGrid( GRID_HELPER *aGridHelper )
+ {
+ m_gridHelper = aGridHelper;
+ }
+
+private:
+ void movePlacing( const VECTOR2I& aP, PNS_ITEM* aItem );
+ void moveDragging( const VECTOR2I& aP, PNS_ITEM* aItem );
+
+ void eraseView();
+ void updateView( PNS_NODE* aNode, PNS_ITEMSET& aCurrent );
+
+ void clearViewFlags();
+
+ // optHoverItem queryHoverItemEx(const VECTOR2I& aP);
+
+ PNS_ITEM* pickSingleItem( PNS_ITEMSET& aItems ) const;
+ void splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, const VECTOR2I& aP );
+
+ PNS_ITEM* syncPad( D_PAD* aPad );
+ PNS_ITEM* syncTrack( TRACK* aTrack );
+ PNS_ITEM* syncVia( VIA* aVia );
+
+ void commitPad( PNS_SOLID* aPad );
+ void commitSegment( PNS_SEGMENT* aTrack );
+ void commitVia( PNS_VIA* aVia );
+
+ void highlightCurrent( bool enabled );
+
+ void markViolations( PNS_NODE* aNode, PNS_ITEMSET& aCurrent, PNS_NODE::ITEM_VECTOR& aRemoved );
+
+ VECTOR2I m_currentEnd;
+ RouterState m_state;
+
+ BOARD* m_board;
+ PNS_NODE* m_world;
+ PNS_NODE* m_lastNode;
+ PNS_PLACEMENT_ALGO * m_placer;
+ PNS_DRAGGER* m_dragger;
+ PNS_SHOVE* m_shove;
+ int m_iterLimit;
+ bool m_showInterSteps;
+ int m_snapshotIter;
+
+ KIGFX::VIEW* m_view;
+ KIGFX::VIEW_GROUP* m_previewItems;
+
+ bool m_snappingEnabled;
+ bool m_violation;
+
+ PNS_ROUTING_SETTINGS m_settings;
+ PNS_PCBNEW_CLEARANCE_FUNC* m_clearanceFunc;
+
+ boost::unordered_set<BOARD_CONNECTED_ITEM*> m_hiddenItems;
+
+ ///> Stores list of modified items in the current operation
+ PICKED_ITEMS_LIST m_undoBuffer;
+ PNS_SIZES_SETTINGS m_sizes;
+ PNS_ROUTER_MODE m_mode;
+
+ wxString m_toolStatusbarName;
+ wxString m_failureReason;
+
+ GRID_HELPER *m_gridHelper;
+};
+
+#endif
diff --git a/pcbnew/router/pns_routing_settings.cpp b/pcbnew/router/pns_routing_settings.cpp
new file mode 100644
index 0000000..4ff25e3
--- /dev/null
+++ b/pcbnew/router/pns_routing_settings.cpp
@@ -0,0 +1,105 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <tool/tool_settings.h>
+
+#include "pns_routing_settings.h"
+#include "direction.h"
+
+PNS_ROUTING_SETTINGS::PNS_ROUTING_SETTINGS()
+{
+ m_routingMode = RM_Walkaround;
+ m_optimizerEffort = OE_MEDIUM;
+ m_removeLoops = true;
+ m_smartPads = true;
+ m_shoveVias = true;
+ m_suggestFinish = false;
+ m_followMouse = true;
+ m_startDiagonal = false;
+ m_shoveIterationLimit = 250;
+ m_shoveTimeLimit = 1000;
+ m_walkaroundIterationLimit = 40;
+ m_jumpOverObstacles = false;
+ m_smoothDraggedSegments = true;
+ m_canViolateDRC = false;
+ m_freeAngleMode = false;
+ m_inlineDragEnabled = false;
+}
+
+
+void PNS_ROUTING_SETTINGS::Save( TOOL_SETTINGS& aSettings ) const
+{
+ aSettings.Set( "Mode", (int) m_routingMode );
+ aSettings.Set( "OptimizerEffort", (int) m_optimizerEffort );
+ aSettings.Set( "RemoveLoops", m_removeLoops );
+ aSettings.Set( "SmartPads", m_smartPads );
+ aSettings.Set( "ShoveVias", m_shoveVias );
+ aSettings.Set( "StartDiagonal", m_startDiagonal );
+ aSettings.Set( "ShoveTimeLimit", m_shoveTimeLimit.Get() );
+ aSettings.Set( "ShoveIterationLimit", m_shoveIterationLimit );
+ aSettings.Set( "WalkaroundIterationLimit", m_walkaroundIterationLimit );
+ aSettings.Set( "JumpOverObstacles", m_jumpOverObstacles );
+ aSettings.Set( "SmoothDraggedSegments", m_smoothDraggedSegments );
+ aSettings.Set( "CanViolateDRC", m_canViolateDRC );
+ aSettings.Set( "SuggestFinish", m_suggestFinish );
+ aSettings.Set( "FreeAngleMode", m_freeAngleMode );
+ aSettings.Set( "InlineDragEnabled", m_inlineDragEnabled );
+}
+
+
+void PNS_ROUTING_SETTINGS::Load( const TOOL_SETTINGS& aSettings )
+{
+ m_routingMode = (PNS_MODE) aSettings.Get( "Mode", (int) RM_Walkaround );
+ m_optimizerEffort = (PNS_OPTIMIZATION_EFFORT) aSettings.Get( "OptimizerEffort", (int) OE_MEDIUM );
+ m_removeLoops = aSettings.Get( "RemoveLoops", true );
+ m_smartPads = aSettings.Get( "SmartPads", true );
+ m_shoveVias = aSettings.Get( "ShoveVias", true );
+ m_startDiagonal = aSettings.Get( "StartDiagonal", false );
+ m_shoveTimeLimit.Set( aSettings.Get( "ShoveTimeLimit", 1000 ) );
+ m_shoveIterationLimit = aSettings.Get( "ShoveIterationLimit", 250 );
+ m_walkaroundIterationLimit = aSettings.Get( "WalkaroundIterationLimit", 50 );
+ m_jumpOverObstacles = aSettings.Get( "JumpOverObstacles", false );
+ m_smoothDraggedSegments = aSettings.Get( "SmoothDraggedSegments", true );
+ m_canViolateDRC = aSettings.Get( "CanViolateDRC", false );
+ m_suggestFinish = aSettings.Get( "SuggestFinish", false );
+ m_freeAngleMode = aSettings.Get( "FreeAngleMode", false );
+ m_inlineDragEnabled = aSettings.Get( "InlineDragEnabled", false );
+}
+
+
+const DIRECTION_45 PNS_ROUTING_SETTINGS::InitialDirection() const
+{
+ if( m_startDiagonal )
+ return DIRECTION_45( DIRECTION_45::NE );
+ else
+ return DIRECTION_45( DIRECTION_45::N );
+}
+
+
+TIME_LIMIT PNS_ROUTING_SETTINGS::ShoveTimeLimit() const
+{
+ return TIME_LIMIT ( m_shoveTimeLimit );
+}
+
+
+int PNS_ROUTING_SETTINGS::ShoveIterationLimit() const
+{
+ return m_shoveIterationLimit;
+}
diff --git a/pcbnew/router/pns_routing_settings.h b/pcbnew/router/pns_routing_settings.h
new file mode 100644
index 0000000..f390045
--- /dev/null
+++ b/pcbnew/router/pns_routing_settings.h
@@ -0,0 +1,158 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_ROUTING_SETTINGS
+#define __PNS_ROUTING_SETTINGS
+
+#include <cstdio>
+
+#include "time_limit.h"
+
+class DIRECTION_45;
+class TOOL_SETTINGS;
+
+///> Routing modes
+enum PNS_MODE
+{
+ RM_MarkObstacles = 0, ///> Ignore collisions, mark obstacles
+ RM_Shove, ///> Only shove
+ RM_Walkaround, ///> Only walkaround
+ RM_Smart ///> Guess what's better, try to make least mess on the PCB
+};
+
+///> Optimization effort
+enum PNS_OPTIMIZATION_EFFORT
+{
+ OE_LOW = 0,
+ OE_MEDIUM = 1,
+ OE_FULL = 2
+};
+
+/**
+ * Class PNS_ROUTING_SETTINGS
+ *
+ * Contains all persistent settings of the router, such as the mode, optimization effort, etc.
+ */
+
+class PNS_ROUTING_SETTINGS
+{
+public:
+ PNS_ROUTING_SETTINGS();
+
+ void Load( const TOOL_SETTINGS& where );
+ void Save( TOOL_SETTINGS& where ) const;
+
+ ///> Returns the routing mode.
+ PNS_MODE Mode() const { return m_routingMode; }
+
+ ///> Sets the routing mode.
+ void SetMode( PNS_MODE aMode ) { m_routingMode = aMode; }
+
+ ///> Returns the optimizer effort. Bigger means cleaner traces, but slower routing.
+ PNS_OPTIMIZATION_EFFORT OptimizerEffort() const { return m_optimizerEffort; }
+
+ ///> Sets the optimizer effort. Bigger means cleaner traces, but slower routing.
+ void SetOptimizerEffort( PNS_OPTIMIZATION_EFFORT aEffort ) { m_optimizerEffort = aEffort; }
+
+ ///> Returns true if shoving vias is enbled.
+ bool ShoveVias() const { return m_shoveVias; }
+
+ ///> Enables/disables shoving vias.
+ void SetShoveVias( bool aShoveVias ) { m_shoveVias = aShoveVias; }
+
+ ///> Returns true if loop (redundant track) removal is on.
+ bool RemoveLoops() const { return m_removeLoops; }
+
+ ///> Enables/disables loop (redundant track) removal.
+ void SetRemoveLoops( bool aRemoveLoops ) { m_removeLoops = aRemoveLoops; }
+
+ ///> Returns true if suggesting the finish of currently placed track is on.
+ bool SuggestFinish() { return m_suggestFinish; }
+
+ ///> Enables displaying suggestions for finishing the currently placed track.
+ void SetSuggestFinish( bool aSuggestFinish ) { m_suggestFinish = aSuggestFinish; }
+
+ ///> Returns true if Smart Pads (automatic neckdown) is enabled.
+ bool SmartPads () const { return m_smartPads; }
+
+ ///> Enables/disables Smart Pads (automatic neckdown).
+ void SetSmartPads( bool aSmartPads ) { m_smartPads = aSmartPads; }
+
+ ///> Returns true if follow mouse mode is active (permanently on for the moment).
+ bool FollowMouse() const
+ {
+ return m_followMouse && !( Mode() == RM_MarkObstacles );
+ }
+
+ ///> Returns true if smoothing segments durign dragging is enabled.
+ bool SmoothDraggedSegments() const { return m_smoothDraggedSegments; }
+
+ ///> Enables/disabled smoothing segments during dragging.
+ void SetSmoothDraggedSegments( bool aSmooth ) { m_smoothDraggedSegments = aSmooth; }
+
+ ///> Returns true if jumping over unmovable obstacles is on.
+ bool JumpOverObstacles() const { return m_jumpOverObstacles; }
+
+ ///> Enables/disables jumping over unmovable obstacles.
+ void SetJumpOverObstacles( bool aJumpOverObstacles ) { m_jumpOverObstacles = aJumpOverObstacles; }
+
+ void SetStartDiagonal( bool aStartDiagonal ) { m_startDiagonal = aStartDiagonal; }
+
+ bool CanViolateDRC() const { return m_canViolateDRC; }
+ void SetCanViolateDRC( bool aViolate ) { m_canViolateDRC = aViolate; }
+
+ bool GetFreeAngleMode() const { return m_freeAngleMode; }
+
+ void SetFreeAngleMode( bool aEnable ) { m_freeAngleMode = aEnable; }
+
+ const DIRECTION_45 InitialDirection() const;
+
+ int ShoveIterationLimit() const;
+ TIME_LIMIT ShoveTimeLimit() const;
+
+ int WalkaroundIterationLimit() const { return m_walkaroundIterationLimit; };
+ TIME_LIMIT WalkaroundTimeLimit() const;
+
+ void SetInlineDragEnabled ( bool aEnable ) { m_inlineDragEnabled = aEnable; }
+ bool InlineDragEnabled( ) const { return m_inlineDragEnabled; }
+
+private:
+ bool m_shoveVias;
+ bool m_startDiagonal;
+ bool m_removeLoops;
+ bool m_smartPads;
+ bool m_suggestFinish;
+ bool m_followMouse;
+ bool m_jumpOverObstacles;
+ bool m_smoothDraggedSegments;
+ bool m_canViolateDRC;
+ bool m_freeAngleMode;
+ bool m_inlineDragEnabled;
+
+ PNS_MODE m_routingMode;
+ PNS_OPTIMIZATION_EFFORT m_optimizerEffort;
+
+ int m_walkaroundIterationLimit;
+ int m_shoveIterationLimit;
+ TIME_LIMIT m_shoveTimeLimit;
+ TIME_LIMIT m_walkaroundTimeLimit;
+};
+
+#endif
diff --git a/pcbnew/router/pns_segment.h b/pcbnew/router/pns_segment.h
new file mode 100644
index 0000000..dbcb165
--- /dev/null
+++ b/pcbnew/router/pns_segment.h
@@ -0,0 +1,130 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_SEGMENT_H
+#define __PNS_SEGMENT_H
+
+#include <math/vector2d.h>
+
+#include <geometry/seg.h>
+#include <geometry/shape_segment.h>
+#include <geometry/shape_line_chain.h>
+
+#include "pns_item.h"
+#include "pns_line.h"
+
+class PNS_NODE;
+
+class PNS_SEGMENT : public PNS_ITEM
+{
+public:
+ PNS_SEGMENT() :
+ PNS_ITEM( SEGMENT )
+ {}
+
+ PNS_SEGMENT( const SEG& aSeg, int aNet ) :
+ PNS_ITEM( SEGMENT ), m_seg( aSeg, 0 )
+ {
+ m_net = aNet;
+ }
+
+ PNS_SEGMENT( const PNS_LINE& aParentLine, const SEG& aSeg ) :
+ PNS_ITEM( SEGMENT ),
+ m_seg( aSeg, aParentLine.Width() )
+ {
+ m_net = aParentLine.Net();
+ m_layers = aParentLine.Layers();
+ m_marker = aParentLine.Marker();
+ m_rank = aParentLine.Rank();
+ }
+
+ static inline bool ClassOf( const PNS_ITEM* aItem )
+ {
+ return aItem && SEGMENT == aItem->Kind();
+ }
+
+ PNS_SEGMENT* Clone() const;
+
+ const SHAPE* Shape() const
+ {
+ return static_cast<const SHAPE*>( &m_seg );
+ }
+
+ void SetLayer( int aLayer )
+ {
+ SetLayers( PNS_LAYERSET( aLayer ) );
+ }
+
+ int Layer() const
+ {
+ return Layers().Start();
+ }
+
+ void SetWidth( int aWidth )
+ {
+ m_seg.SetWidth(aWidth);
+ }
+
+ int Width() const
+ {
+ return m_seg.GetWidth();
+ }
+
+ const SEG& Seg() const
+ {
+ return m_seg.GetSeg();
+ }
+
+ const SHAPE_LINE_CHAIN CLine() const
+ {
+ return SHAPE_LINE_CHAIN( m_seg.GetSeg().A, m_seg.GetSeg().B );
+ }
+
+ void SetEnds( const VECTOR2I& a, const VECTOR2I& b )
+ {
+ m_seg.SetSeg( SEG ( a, b ) );
+ }
+
+ void SwapEnds()
+ {
+ SEG tmp = m_seg.GetSeg();
+ m_seg.SetSeg( SEG (tmp.B , tmp.A ) );
+ }
+
+ const SHAPE_LINE_CHAIN Hull( int aClearance, int aWalkaroundThickness ) const;
+
+ virtual VECTOR2I Anchor( int n ) const
+ {
+ if( n == 0 )
+ return m_seg.GetSeg().A;
+ else
+ return m_seg.GetSeg().B;
+ }
+
+ virtual int AnchorCount() const
+ {
+ return 2;
+ }
+
+private:
+ SHAPE_SEGMENT m_seg;
+};
+
+#endif
diff --git a/pcbnew/router/pns_shove.cpp b/pcbnew/router/pns_shove.cpp
new file mode 100644
index 0000000..3e72443
--- /dev/null
+++ b/pcbnew/router/pns_shove.cpp
@@ -0,0 +1,1375 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define PNS_DEBUG
+
+#include <deque>
+#include <cassert>
+
+#include <boost/foreach.hpp>
+
+#include "trace.h"
+#include "range.h"
+
+#include "pns_line.h"
+#include "pns_node.h"
+#include "pns_walkaround.h"
+#include "pns_shove.h"
+#include "pns_solid.h"
+#include "pns_optimizer.h"
+#include "pns_via.h"
+#include "pns_utils.h"
+#include "pns_router.h"
+#include "pns_shove.h"
+#include "pns_utils.h"
+#include "pns_topology.h"
+
+#include "time_limit.h"
+
+#include <profile.h>
+
+void PNS_SHOVE::replaceItems( PNS_ITEM* aOld, PNS_ITEM* aNew )
+{
+ OPT_BOX2I changed_area = ChangedArea( aOld, aNew );
+
+ if( changed_area )
+ {
+ m_affectedAreaSum = m_affectedAreaSum ? m_affectedAreaSum->Merge ( *changed_area ) : *changed_area;
+ }
+
+ m_currentNode->Replace( aOld, aNew );
+}
+
+
+int PNS_SHOVE::getClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const
+{
+ if( m_forceClearance >= 0 )
+ return m_forceClearance;
+
+ return m_currentNode->GetClearance( aA, aB );
+}
+
+
+void PNS_SHOVE::sanityCheck( PNS_LINE* aOld, PNS_LINE* aNew )
+{
+ assert( aOld->CPoint( 0 ) == aNew->CPoint( 0 ) );
+ assert( aOld->CPoint( -1 ) == aNew->CPoint( -1 ) );
+}
+
+
+PNS_SHOVE::PNS_SHOVE( PNS_NODE* aWorld, PNS_ROUTER* aRouter ) :
+ PNS_ALGO_BASE ( aRouter )
+{
+ m_forceClearance = -1;
+ m_root = aWorld;
+ m_currentNode = aWorld;
+
+ // Initialize other temporary variables:
+ m_draggedVia = NULL;
+ m_iter = 0;
+ m_multiLineMode = false;
+}
+
+
+PNS_SHOVE::~PNS_SHOVE()
+{
+}
+
+
+PNS_LINE PNS_SHOVE::assembleLine( const PNS_SEGMENT* aSeg, int* aIndex )
+{
+ return m_currentNode->AssembleLine( const_cast<PNS_SEGMENT*>( aSeg ), aIndex, true );
+}
+
+// A dumb function that checks if the shoved line is shoved the right way, e.g.
+// visually "outwards" of the line/via applying pressure on it. Unfortunately there's no
+// mathematical concept of orientation of an open curve, so we use some primitive heuristics:
+// if the shoved line wraps around the start of the "pusher", it's likely shoved in wrong direction.
+bool PNS_SHOVE::checkBumpDirection( const PNS_LINE& aCurrent, const PNS_LINE& aShoved ) const
+{
+ const SEG& ss = aCurrent.CSegment( 0 );
+
+ int dist = getClearance( &aCurrent, &aShoved ) + PNS_HULL_MARGIN;
+
+ dist += aCurrent.Width() / 2;
+ dist += aShoved.Width() / 2;
+
+ const VECTOR2I ps = ss.A - ( ss.B - ss.A ).Resize( dist );
+
+ return !aShoved.CLine().PointOnEdge( ps );
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::walkaroundLoneVia( PNS_LINE& aCurrent, PNS_LINE& aObstacle,
+ PNS_LINE& aShoved )
+{
+ int clearance = getClearance( &aCurrent, &aObstacle );
+ const SHAPE_LINE_CHAIN hull = aCurrent.Via().Hull( clearance, aObstacle.Width() );
+ SHAPE_LINE_CHAIN path_cw, path_ccw;
+
+ aObstacle.Walkaround( hull, path_cw, true );
+ aObstacle.Walkaround( hull, path_ccw, false );
+
+ const SHAPE_LINE_CHAIN& shortest = path_ccw.Length() < path_cw.Length() ? path_ccw : path_cw;
+
+ if( shortest.PointCount() < 2 )
+ return SH_INCOMPLETE;
+
+ if( aObstacle.CPoint( -1 ) != shortest.CPoint( -1 ) )
+ return SH_INCOMPLETE;
+
+ if( aObstacle.CPoint( 0 ) != shortest.CPoint( 0 ) )
+ return SH_INCOMPLETE;
+
+ aShoved.SetShape( shortest );
+
+ if( m_currentNode->CheckColliding( &aShoved, &aCurrent ) )
+ return SH_INCOMPLETE;
+
+ return SH_OK;
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processHullSet( PNS_LINE& aCurrent, PNS_LINE& aObstacle,
+ PNS_LINE& aShoved, const HULL_SET& aHulls )
+{
+ const SHAPE_LINE_CHAIN& obs = aObstacle.CLine();
+
+ int attempt;
+
+ for( attempt = 0; attempt < 4; attempt++ )
+ {
+ bool invertTraversal = ( attempt >= 2 );
+ bool clockwise = attempt % 2;
+ int vFirst = -1, vLast = -1;
+
+ SHAPE_LINE_CHAIN path;
+ PNS_LINE l( aObstacle );
+
+ for( int i = 0; i < (int) aHulls.size(); i++ )
+ {
+ const SHAPE_LINE_CHAIN& hull = aHulls[invertTraversal ? aHulls.size() - 1 - i : i];
+
+ l.Walkaround( hull, path, clockwise );
+ path.Simplify();
+ l.SetShape( path );
+ }
+
+ for( int i = 0; i < std::min ( path.PointCount(), obs.PointCount() ); i++ )
+ {
+ if( path.CPoint( i ) != obs.CPoint( i ) )
+ {
+ vFirst = i;
+ break;
+ }
+ }
+
+ int k = obs.PointCount() - 1;
+ for( int i = path.PointCount() - 1; i >= 0 && k >= 0; i--, k-- )
+ {
+ if( path.CPoint( i ) != obs.CPoint( k ) )
+ {
+ vLast = i;
+ break;
+ }
+ }
+
+ if( ( vFirst < 0 || vLast < 0 ) && !path.CompareGeometry( aObstacle.CLine() ) )
+ {
+ TRACE( 100, "attempt %d fail vfirst-last", attempt );
+ continue;
+ }
+
+ if( path.CPoint( -1 ) != obs.CPoint( -1 ) || path.CPoint( 0 ) != obs.CPoint( 0 ) )
+ {
+ TRACE( 100, "attempt %d fail vend-start\n", attempt );
+ continue;
+ }
+
+ if( !checkBumpDirection( aCurrent, l ) )
+ {
+ TRACE( 100, "attempt %d fail direction-check", attempt );
+ aShoved.SetShape( l.CLine() );
+
+ continue;
+ }
+
+ if( path.SelfIntersecting() )
+ {
+ TRACE( 100, "attempt %d fail self-intersect", attempt );
+ continue;
+ }
+
+ bool colliding = m_currentNode->CheckColliding( &l, &aCurrent, PNS_ITEM::ANY, m_forceClearance );
+
+ if( ( aCurrent.Marker() & MK_HEAD ) && !colliding )
+ {
+ PNS_JOINT* jtStart = m_currentNode->FindJoint( aCurrent.CPoint( 0 ), &aCurrent );
+
+ BOOST_FOREACH( PNS_ITEM* item, jtStart->LinkList() )
+ {
+ if( m_currentNode->CheckColliding( item, &l ) )
+ colliding = true;
+ }
+ }
+
+ if( colliding )
+ {
+ TRACE( 100, "attempt %d fail coll-check", attempt );
+ continue;
+ }
+
+ aShoved.SetShape( l.CLine() );
+
+ return SH_OK;
+ }
+
+ return SH_INCOMPLETE;
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ProcessSingleLine( PNS_LINE& aCurrent, PNS_LINE& aObstacle,
+ PNS_LINE& aShoved )
+{
+ aShoved.ClearSegmentLinks();
+
+ bool obstacleIsHead = false;
+
+ if( aObstacle.LinkedSegments() )
+ {
+ BOOST_FOREACH( PNS_SEGMENT* s, *aObstacle.LinkedSegments() )
+
+ if( s->Marker() & MK_HEAD )
+ {
+ obstacleIsHead = true;
+ break;
+ }
+ }
+
+ SHOVE_STATUS rv;
+
+ bool viaOnEnd = aCurrent.EndsWithVia();
+
+ if( viaOnEnd && ( !aCurrent.LayersOverlap( &aObstacle ) || aCurrent.SegmentCount() == 0 ) )
+ {
+ rv = walkaroundLoneVia( aCurrent, aObstacle, aShoved );
+ }
+ else
+ {
+ int w = aObstacle.Width();
+ int n_segs = aCurrent.SegmentCount();
+
+ int clearance = getClearance( &aCurrent, &aObstacle ) + 1;
+
+ HULL_SET hulls;
+
+ hulls.reserve( n_segs + 1 );
+
+ for( int i = 0; i < n_segs; i++ )
+ {
+ PNS_SEGMENT seg( aCurrent, aCurrent.CSegment( i ) );
+ SHAPE_LINE_CHAIN hull = seg.Hull( clearance, w );
+
+ hulls.push_back( hull );
+ }
+
+ if( viaOnEnd )
+ hulls.push_back ( aCurrent.Via().Hull( clearance, w ) );
+
+ rv = processHullSet ( aCurrent, aObstacle, aShoved, hulls );
+ }
+
+ if( obstacleIsHead )
+ aShoved.Mark( aShoved.Marker() | MK_HEAD );
+
+ return rv;
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSegment( PNS_LINE& aCurrent, PNS_SEGMENT* aObstacleSeg )
+{
+ int segIndex;
+ PNS_LINE obstacleLine = assembleLine( aObstacleSeg, &segIndex );
+ PNS_LINE shovedLine( obstacleLine );
+ PNS_SEGMENT tmp( *aObstacleSeg );
+
+ SHOVE_STATUS rv = ProcessSingleLine( aCurrent, obstacleLine, shovedLine );
+
+ const double extensionWalkThreshold = 1.0;
+
+ double obsLen = obstacleLine.CLine().Length();
+ double shovedLen = shovedLine.CLine().Length();
+ double extensionFactor = 0.0;
+
+ if( obsLen != 0.0f )
+ extensionFactor = shovedLen / obsLen - 1.0;
+
+ if( extensionFactor > extensionWalkThreshold )
+ return SH_TRY_WALK;
+
+ assert( obstacleLine.LayersOverlap( &shovedLine ) );
+
+#ifdef DEBUG
+ m_logger.NewGroup( "on-colliding-segment", m_iter );
+ m_logger.Log( &tmp, 0, "obstacle-segment" );
+ m_logger.Log( &aCurrent, 1, "current-line" );
+ m_logger.Log( &obstacleLine, 2, "obstacle-line" );
+ m_logger.Log( &shovedLine, 3, "shoved-line" );
+#endif
+
+ if( rv == SH_OK )
+ {
+ if( shovedLine.Marker() & MK_HEAD )
+ {
+ if( m_multiLineMode )
+ return SH_INCOMPLETE;
+
+ m_newHead = shovedLine;
+ }
+
+ int rank = aCurrent.Rank();
+ shovedLine.SetRank( rank - 1 );
+
+ sanityCheck( &obstacleLine, &shovedLine );
+ replaceItems( &obstacleLine, &shovedLine );
+
+ if( !pushLine( shovedLine ) )
+ rv = SH_INCOMPLETE;
+ }
+
+ return rv;
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingLine( PNS_LINE& aCurrent, PNS_LINE& aObstacle )
+{
+ PNS_LINE shovedLine( aObstacle );
+
+ SHOVE_STATUS rv = ProcessSingleLine( aCurrent, aObstacle, shovedLine );
+
+ #ifdef DEBUG
+ m_logger.NewGroup( "on-colliding-line", m_iter );
+ m_logger.Log( &aObstacle, 0, "obstacle-line" );
+ m_logger.Log( &aCurrent, 1, "current-line" );
+ m_logger.Log( &shovedLine, 3, "shoved-line" );
+ #endif
+
+ if( rv == SH_OK )
+ {
+ if( shovedLine.Marker() & MK_HEAD )
+ {
+ if( m_multiLineMode )
+ return SH_INCOMPLETE;
+
+ m_newHead = shovedLine;
+ }
+
+ sanityCheck( &aObstacle, &shovedLine );
+ replaceItems( &aObstacle, &shovedLine );
+
+ int rank = aObstacle.Rank();
+ shovedLine.SetRank( rank - 1 );
+
+
+ if( !pushLine( shovedLine ) )
+ {
+ rv = SH_INCOMPLETE;
+ }
+ }
+
+ return rv;
+}
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSolid( PNS_LINE& aCurrent, PNS_ITEM* aObstacle )
+{
+ PNS_WALKAROUND walkaround( m_currentNode, Router() );
+ PNS_LINE walkaroundLine( aCurrent );
+
+ if( aCurrent.EndsWithVia() )
+ {
+ PNS_VIA vh = aCurrent.Via();
+ PNS_VIA* via = NULL;
+ PNS_JOINT* jtStart = m_currentNode->FindJoint( vh.Pos(), &aCurrent );
+
+ if( !jtStart )
+ return SH_INCOMPLETE;
+
+ BOOST_FOREACH( PNS_ITEM* item, jtStart->LinkList() )
+ {
+ if( item->OfKind( PNS_ITEM::VIA ) )
+ {
+ via = (PNS_VIA*) item;
+ break;
+ }
+ }
+
+ if( via && m_currentNode->CheckColliding( via, aObstacle ) )
+ return onCollidingVia( aObstacle, via );
+ }
+
+ PNS_TOPOLOGY topo( m_currentNode );
+
+ std::set<PNS_ITEM*> cluster = topo.AssembleCluster( aObstacle, aCurrent.Layers().Start() );
+
+#ifdef DEBUG
+ m_logger.NewGroup( "on-colliding-solid-cluster", m_iter );
+ BOOST_FOREACH( PNS_ITEM* item, cluster )
+ {
+ m_logger.Log( item, 0, "cluster-entry" );
+ }
+#endif
+
+ walkaround.SetSolidsOnly( false );
+ walkaround.RestrictToSet( true, cluster );
+ walkaround.SetIterationLimit( 16 ); // fixme: make configurable
+
+ int currentRank = aCurrent.Rank();
+ int nextRank;
+
+ for( int attempt = 0; attempt < 2; attempt++ )
+ {
+
+ if( attempt == 1 || Settings().JumpOverObstacles() )
+ {
+ nextRank = currentRank - 1;
+ walkaround.SetSingleDirection( true );
+ }
+ else
+ {
+ nextRank = currentRank + 10000;
+ walkaround.SetSingleDirection( false );
+ }
+
+
+ if( walkaround.Route( aCurrent, walkaroundLine, false ) != PNS_WALKAROUND::DONE )
+ return SH_INCOMPLETE;
+
+ walkaroundLine.ClearSegmentLinks();
+ walkaroundLine.Unmark();
+ walkaroundLine.Line().Simplify();
+
+ if( walkaroundLine.HasLoops() )
+ return SH_INCOMPLETE;
+
+ if( aCurrent.Marker() & MK_HEAD )
+ {
+ walkaroundLine.Mark( MK_HEAD );
+
+ if( m_multiLineMode )
+ return SH_INCOMPLETE;
+
+ m_newHead = walkaroundLine;
+ }
+
+ sanityCheck( &aCurrent, &walkaroundLine );
+
+ if( !m_lineStack.empty() )
+ {
+ PNS_LINE lastLine = m_lineStack.front();
+
+ if( m_currentNode->CheckColliding( &lastLine, &walkaroundLine ) )
+ {
+ PNS_LINE dummy ( lastLine );
+
+ if( ProcessSingleLine( walkaroundLine, lastLine, dummy ) == SH_OK )
+ break;
+ } else
+ break;
+ }
+ }
+
+ replaceItems( &aCurrent, &walkaroundLine );
+ walkaroundLine.SetRank( nextRank );
+
+#ifdef DEBUG
+ m_logger.NewGroup( "on-colliding-solid", m_iter );
+ m_logger.Log( aObstacle, 0, "obstacle-solid" );
+ m_logger.Log( &aCurrent, 1, "current-line" );
+ m_logger.Log( &walkaroundLine, 3, "walk-line" );
+#endif
+
+ popLine();
+
+ if( !pushLine( walkaroundLine ) )
+ return SH_INCOMPLETE;
+
+ return SH_OK;
+}
+
+
+bool PNS_SHOVE::reduceSpringback( const PNS_ITEMSET& aHeadSet )
+{
+ bool rv = false;
+
+ while( !m_nodeStack.empty() )
+ {
+ SPRINGBACK_TAG spTag = m_nodeStack.back();
+
+ if( !spTag.m_node->CheckColliding( aHeadSet ) )
+ {
+ rv = true;
+
+ delete spTag.m_node;
+ m_nodeStack.pop_back();
+ }
+ else
+ break;
+ }
+
+ return rv;
+}
+
+
+bool PNS_SHOVE::pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems,
+ const PNS_COST_ESTIMATOR& aCost, const OPT_BOX2I& aAffectedArea )
+{
+ SPRINGBACK_TAG st;
+ OPT_BOX2I prev_area;
+
+ if( !m_nodeStack.empty() )
+ prev_area = m_nodeStack.back().m_affectedArea;
+
+ st.m_node = aNode;
+ st.m_cost = aCost;
+ st.m_headItems = aHeadItems;
+
+ if( aAffectedArea )
+ {
+ if( prev_area )
+ st.m_affectedArea = prev_area->Merge ( *aAffectedArea );
+ else
+ st.m_affectedArea = aAffectedArea;
+ } else
+ st.m_affectedArea = prev_area;
+
+ m_nodeStack.push_back( st );
+
+ return true;
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank, bool aDryRun )
+{
+ LINE_PAIR_VEC draggedLines;
+ VECTOR2I p0( aVia->Pos() );
+ PNS_JOINT* jt = m_currentNode->FindJoint( p0, aVia );
+ VECTOR2I p0_pushed( p0 + aForce );
+
+ if( !jt )
+ {
+ TRACEn( 1, "weird, can't find the center-of-via joint\n" );
+ return SH_INCOMPLETE;
+ }
+
+ if( jt->IsLocked() )
+ return SH_INCOMPLETE;
+
+ while( aForce.x != 0 || aForce.y != 0 )
+ {
+ PNS_JOINT* jt_next = m_currentNode->FindJoint( p0_pushed, aVia );
+
+ if( !jt_next )
+ break;
+
+ p0_pushed += aForce.Resize( 2 ); // make sure pushed via does not overlap with any existing joint
+ }
+
+ PNS_VIA* pushedVia = aVia->Clone();
+ pushedVia->SetPos( p0_pushed );
+ pushedVia->Mark( aVia->Marker() );
+
+ if( aVia->Marker() & MK_HEAD )
+ {
+ m_draggedVia = pushedVia;
+ m_draggedViaHeadSet.Clear();
+ }
+
+ BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
+ {
+ if( PNS_SEGMENT* seg = dyn_cast<PNS_SEGMENT*>( item ) )
+ {
+ LINE_PAIR lp;
+ int segIndex;
+
+ lp.first = assembleLine( seg, &segIndex );
+
+ assert( segIndex == 0 || ( segIndex == ( lp.first.SegmentCount() - 1 ) ) );
+
+ if( segIndex == 0 )
+ lp.first.Reverse();
+
+ lp.second = lp.first;
+ lp.second.ClearSegmentLinks();
+ lp.second.DragCorner( p0_pushed, lp.second.CLine().Find( p0 ) );
+ lp.second.AppendVia( *pushedVia );
+ draggedLines.push_back( lp );
+
+ if( aVia->Marker() & MK_HEAD )
+ m_draggedViaHeadSet.Add( lp.second );
+ }
+ }
+
+ m_draggedViaHeadSet.Add( pushedVia );
+
+ if( aDryRun )
+ return SH_OK;
+
+ replaceItems( aVia, pushedVia );
+
+#ifdef DEBUG
+ m_logger.Log( aVia, 0, "obstacle-via" );
+#endif
+
+ pushedVia->SetRank( aCurrentRank - 1 );
+
+#ifdef DEBUG
+ m_logger.Log( pushedVia, 1, "pushed-via" );
+#endif
+
+ BOOST_FOREACH( LINE_PAIR lp, draggedLines )
+ {
+ if( lp.first.Marker() & MK_HEAD )
+ {
+ lp.second.Mark( MK_HEAD );
+
+ if( m_multiLineMode )
+ return SH_INCOMPLETE;
+
+ m_newHead = lp.second;
+ }
+
+ unwindStack( &lp.first );
+
+ if( lp.second.SegmentCount() )
+ {
+ replaceItems( &lp.first, &lp.second );
+ lp.second.SetRank( aCurrentRank - 1 );
+
+ if( !pushLine( lp.second, true ) )
+ return SH_INCOMPLETE;
+ }
+ else
+ {
+ m_currentNode->Remove( &lp.first );
+ }
+
+#ifdef DEBUG
+ m_logger.Log( &lp.first, 2, "fan-pre" );
+ m_logger.Log( &lp.second, 3, "fan-post" );
+#endif
+ }
+
+ return SH_OK;
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingVia( PNS_ITEM* aCurrent, PNS_VIA* aObstacleVia )
+{
+ int clearance = getClearance( aCurrent, aObstacleVia ) ;
+ LINE_PAIR_VEC draggedLines;
+ bool colLine = false, colVia = false;
+ PNS_LINE* currentLine = NULL;
+ VECTOR2I mtvLine, mtvVia, mtv, mtvSolid;
+ int rank = -1;
+
+ if( aCurrent->OfKind( PNS_ITEM::LINE ) )
+ {
+#ifdef DEBUG
+ m_logger.NewGroup( "push-via-by-line", m_iter );
+ m_logger.Log( aCurrent, 4, "current" );
+#endif
+
+ currentLine = (PNS_LINE*) aCurrent;
+ colLine = CollideShapes( aObstacleVia->Shape(), currentLine->Shape(),
+ clearance + currentLine->Width() / 2 + PNS_HULL_MARGIN,
+ true, mtvLine );
+
+ if( currentLine->EndsWithVia() )
+ colVia = CollideShapes( currentLine->Via().Shape(), aObstacleVia->Shape(),
+ clearance + PNS_HULL_MARGIN, true, mtvVia );
+
+ if( !colLine && !colVia )
+ return SH_OK;
+
+ if( colLine && colVia )
+ mtv = mtvVia.EuclideanNorm() > mtvLine.EuclideanNorm() ? mtvVia : mtvLine;
+ else if( colLine )
+ mtv = mtvLine;
+ else
+ mtv = mtvVia;
+
+ rank = currentLine->Rank();
+ }
+ else if( aCurrent->OfKind( PNS_ITEM::SOLID ) )
+ {
+ CollideShapes( aObstacleVia->Shape(), aCurrent->Shape(),
+ clearance + PNS_HULL_MARGIN, true, mtvSolid );
+ mtv = -mtvSolid;
+ rank = aCurrent->Rank() + 10000;
+ }
+
+ return pushVia( aObstacleVia, mtv, rank );
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onReverseCollidingVia( PNS_LINE& aCurrent, PNS_VIA* aObstacleVia )
+{
+ int n = 0;
+ PNS_LINE cur( aCurrent );
+ cur.ClearSegmentLinks();
+
+ PNS_JOINT* jt = m_currentNode->FindJoint( aObstacleVia->Pos(), aObstacleVia );
+ PNS_LINE shoved( aCurrent );
+ shoved.ClearSegmentLinks();
+
+ cur.RemoveVia();
+ unwindStack( &aCurrent );
+
+ BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
+ {
+ if( item->OfKind( PNS_ITEM::SEGMENT ) && item->LayersOverlap( &aCurrent ) )
+ {
+ PNS_SEGMENT* seg = (PNS_SEGMENT*) item;
+ PNS_LINE head = assembleLine( seg );
+
+ head.AppendVia( *aObstacleVia );
+
+ SHOVE_STATUS st = ProcessSingleLine( head, cur, shoved );
+
+ if( st != SH_OK )
+ {
+#ifdef DEBUG
+ m_logger.NewGroup( "on-reverse-via-fail-shove", m_iter );
+ m_logger.Log( aObstacleVia, 0, "the-via" );
+ m_logger.Log( &aCurrent, 1, "current-line" );
+ m_logger.Log( &shoved, 3, "shoved-line" );
+#endif
+
+ return st;
+ }
+
+ cur.SetShape( shoved.CLine() );
+ n++;
+ }
+ }
+
+ if( !n )
+ {
+#ifdef DEBUG
+ m_logger.NewGroup( "on-reverse-via-fail-lonevia", m_iter );
+ m_logger.Log( aObstacleVia, 0, "the-via" );
+ m_logger.Log( &aCurrent, 1, "current-line" );
+#endif
+
+ PNS_LINE head( aCurrent );
+ head.Line().Clear();
+ head.AppendVia( *aObstacleVia );
+ head.ClearSegmentLinks();
+
+ SHOVE_STATUS st = ProcessSingleLine( head, aCurrent, shoved );
+
+ if( st != SH_OK )
+ return st;
+
+ cur.SetShape( shoved.CLine() );
+ }
+
+ if( aCurrent.EndsWithVia() )
+ shoved.AppendVia( aCurrent.Via() );
+
+#ifdef DEBUG
+ m_logger.NewGroup( "on-reverse-via", m_iter );
+ m_logger.Log( aObstacleVia, 0, "the-via" );
+ m_logger.Log( &aCurrent, 1, "current-line" );
+ m_logger.Log( &shoved, 3, "shoved-line" );
+#endif
+ int currentRank = aCurrent.Rank();
+ replaceItems( &aCurrent, &shoved );
+
+ if( !pushLine( shoved ) )
+ return SH_INCOMPLETE;
+
+ shoved.SetRank( currentRank );
+
+ return SH_OK;
+}
+
+
+void PNS_SHOVE::unwindStack( PNS_SEGMENT *aSeg )
+{
+ for( std::vector<PNS_LINE>::iterator i = m_lineStack.begin(); i != m_lineStack.end() ; )
+ {
+ if( i->ContainsSegment( aSeg ) )
+ i = m_lineStack.erase( i );
+ else
+ i++;
+ }
+
+ for( std::vector<PNS_LINE>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end() ; )
+ {
+ if( i->ContainsSegment( aSeg ) )
+ i = m_optimizerQueue.erase( i );
+ else
+ i++;
+ }
+}
+
+
+void PNS_SHOVE::unwindStack( PNS_ITEM* aItem )
+{
+ if( aItem->OfKind( PNS_ITEM::SEGMENT ) )
+ unwindStack( static_cast<PNS_SEGMENT*>( aItem ) );
+ else if( aItem->OfKind( PNS_ITEM::LINE ) )
+ {
+ PNS_LINE* l = static_cast<PNS_LINE*>( aItem );
+
+ if( !l->LinkedSegments() )
+ return;
+
+ BOOST_FOREACH( PNS_SEGMENT* seg, *l->LinkedSegments() )
+ unwindStack( seg );
+ }
+}
+
+
+bool PNS_SHOVE::pushLine( const PNS_LINE& aL, bool aKeepCurrentOnTop )
+{
+ if( aL.LinkCount() >= 0 && ( aL.LinkCount() != aL.SegmentCount() ) )
+ return false;
+
+ if( aKeepCurrentOnTop && m_lineStack.size() > 0)
+ {
+ m_lineStack.insert( m_lineStack.begin() + m_lineStack.size() - 1, aL );
+ }
+ else
+ {
+ m_lineStack.push_back( aL );
+ }
+
+ m_optimizerQueue.push_back( aL );
+
+ return true;
+}
+
+void PNS_SHOVE::popLine( )
+{
+ PNS_LINE& l = m_lineStack.back();
+
+ for( std::vector<PNS_LINE>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end(); )
+ {
+ bool found = false;
+
+ if( !l.LinkedSegments() )
+ continue;
+
+ BOOST_FOREACH( PNS_SEGMENT *s, *l.LinkedSegments() )
+ {
+ if( i->ContainsSegment( s ) )
+ {
+ i = m_optimizerQueue.erase( i );
+ found = true;
+ break;
+ }
+ }
+
+ if( !found )
+ i++;
+ }
+
+ m_lineStack.pop_back();
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveIteration( int aIter )
+{
+ PNS_LINE currentLine = m_lineStack.back();
+ PNS_NODE::OPT_OBSTACLE nearest;
+ SHOVE_STATUS st = SH_NULL;
+
+ PNS_ITEM::PnsKind search_order[] = { PNS_ITEM::SOLID, PNS_ITEM::VIA, PNS_ITEM::SEGMENT };
+
+ for( int i = 0; i < 3; i++ )
+ {
+ nearest = m_currentNode->NearestObstacle( &currentLine, search_order[i] );
+
+ if( nearest )
+ break;
+ }
+
+ if( !nearest )
+ {
+ m_lineStack.pop_back();
+ return SH_OK;
+ }
+
+ PNS_ITEM* ni = nearest->m_item;
+
+ unwindStack( ni );
+
+ if( !ni->OfKind( PNS_ITEM::SOLID ) && ni->Rank() >= 0 && ni->Rank() > currentLine.Rank() )
+ {
+ switch( ni->Kind() )
+ {
+ case PNS_ITEM::VIA:
+ {
+ PNS_VIA* revVia = (PNS_VIA*) ni;
+ TRACE( 2, "iter %d: reverse-collide-via", aIter );
+
+ if( currentLine.EndsWithVia() && m_currentNode->CheckColliding( &currentLine.Via(), revVia ) )
+ {
+ st = SH_INCOMPLETE;
+ }
+ else
+ {
+ st = onReverseCollidingVia ( currentLine, revVia );
+ }
+
+ break;
+ }
+
+ case PNS_ITEM::SEGMENT:
+ {
+ PNS_SEGMENT* seg = (PNS_SEGMENT*) ni;
+ TRACE( 2, "iter %d: reverse-collide-segment ", aIter );
+ PNS_LINE revLine = assembleLine( seg );
+
+ popLine();
+ st = onCollidingLine( revLine, currentLine );
+ if( !pushLine( revLine ) )
+ return SH_INCOMPLETE;
+
+ break;
+ }
+
+ default:
+ assert( false );
+ }
+ }
+ else
+ { // "forward" collisions
+ switch( ni->Kind() )
+ {
+ case PNS_ITEM::SEGMENT:
+ TRACE( 2, "iter %d: collide-segment ", aIter );
+ st = onCollidingSegment( currentLine, (PNS_SEGMENT*) ni );
+
+ if( st == SH_TRY_WALK )
+ {
+ st = onCollidingSolid( currentLine, (PNS_SOLID*) ni );
+ }
+ break;
+
+ case PNS_ITEM::VIA:
+ TRACE( 2, "iter %d: shove-via ", aIter );
+ st = onCollidingVia( &currentLine, (PNS_VIA*) ni );
+ break;
+
+ case PNS_ITEM::SOLID:
+ TRACE( 2, "iter %d: walk-solid ", aIter );
+ st = onCollidingSolid( currentLine, (PNS_SOLID*) ni );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return st;
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveMainLoop()
+{
+ SHOVE_STATUS st = SH_OK;
+
+ m_affectedAreaSum = OPT_BOX2I();
+
+ TRACE( 1, "ShoveStart [root: %d jts, current: %d jts]", m_root->JointCount() %
+ m_currentNode->JointCount() );
+
+ int iterLimit = Settings().ShoveIterationLimit();
+ TIME_LIMIT timeLimit = Settings().ShoveTimeLimit();
+
+ m_iter = 0;
+
+ timeLimit.Restart();
+
+ while( !m_lineStack.empty() )
+ {
+ st = shoveIteration( m_iter );
+
+ m_iter++;
+
+ if( st == SH_INCOMPLETE || timeLimit.Expired() || m_iter >= iterLimit )
+ {
+ st = SH_INCOMPLETE;
+ break;
+ }
+ }
+
+ return st;
+}
+
+
+OPT_BOX2I PNS_SHOVE::totalAffectedArea() const
+{
+ OPT_BOX2I area;
+ if( !m_nodeStack.empty() )
+ area = m_nodeStack.back().m_affectedArea;
+
+ if( area )
+ {
+ if( m_affectedAreaSum )
+ area->Merge ( *m_affectedAreaSum );
+ } else
+ area = m_affectedAreaSum;
+
+ return area;
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
+{
+ SHOVE_STATUS st = SH_OK;
+
+ m_multiLineMode = false;
+
+ // empty head? nothing to shove...
+
+ if( !aCurrentHead.SegmentCount() && !aCurrentHead.EndsWithVia() )
+ return SH_INCOMPLETE;
+
+ PNS_LINE head( aCurrentHead );
+ head.ClearSegmentLinks();
+
+ m_lineStack.clear();
+ m_optimizerQueue.clear();
+ m_newHead = OPT_LINE();
+ m_logger.Clear();
+
+ PNS_ITEMSET headSet;
+ headSet.Add( aCurrentHead );
+
+ reduceSpringback( headSet );
+
+ PNS_NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
+
+ m_currentNode = parent->Branch();
+ m_currentNode->ClearRanks();
+ m_currentNode->Add( &head );
+
+ m_currentNode->LockJoint( head.CPoint(0), &head, true );
+
+ if( !head.EndsWithVia() )
+ m_currentNode->LockJoint( head.CPoint( -1 ), &head, true );
+
+ head.Mark( MK_HEAD );
+ head.SetRank( 100000 );
+
+ m_logger.NewGroup( "initial", 0 );
+ m_logger.Log( &head, 0, "head" );
+
+ PNS_VIA* headVia = NULL;
+
+ if( head.EndsWithVia() )
+ {
+ headVia = head.Via().Clone();
+ m_currentNode->Add( headVia );
+ headVia->Mark( MK_HEAD );
+ headVia->SetRank( 100000 );
+ m_logger.Log( headVia, 0, "head-via" );
+ }
+
+ if( !pushLine( head ) )
+ {
+ delete m_currentNode;
+ m_currentNode = parent;
+
+ return SH_INCOMPLETE;
+ }
+
+ st = shoveMainLoop();
+
+ if( st == SH_OK )
+ {
+ runOptimizer( m_currentNode );
+
+ if( m_newHead )
+ st = m_currentNode->CheckColliding( &(*m_newHead) ) ? SH_INCOMPLETE : SH_HEAD_MODIFIED;
+ else
+ st = m_currentNode->CheckColliding( &head ) ? SH_INCOMPLETE : SH_OK;
+ }
+
+ m_currentNode->RemoveByMarker( MK_HEAD );
+
+ TRACE( 1, "Shove status : %s after %d iterations",
+ ( ( st == SH_OK || st == SH_HEAD_MODIFIED ) ? "OK" : "FAILURE") % m_iter );
+
+ if( st == SH_OK || st == SH_HEAD_MODIFIED )
+ {
+ pushSpringback( m_currentNode, headSet, PNS_COST_ESTIMATOR(), m_affectedAreaSum );
+ }
+ else
+ {
+ delete m_currentNode;
+
+ m_currentNode = parent;
+ m_newHead = OPT_LINE();
+ }
+
+ if( m_newHead && head.EndsWithVia() )
+ {
+ PNS_VIA v = head.Via();
+ v.SetPos( m_newHead->CPoint( -1 ) );
+ m_newHead->AppendVia(v);
+ }
+
+ return st;
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet )
+{
+ SHOVE_STATUS st = SH_OK;
+
+ m_multiLineMode = true;
+
+ PNS_ITEMSET headSet;
+
+ BOOST_FOREACH( const PNS_ITEM* item, aHeadSet.CItems() )
+ {
+ const PNS_LINE* headOrig = static_cast<const PNS_LINE*>( item );
+
+ // empty head? nothing to shove...
+ if( !headOrig->SegmentCount() )
+ return SH_INCOMPLETE;
+
+ headSet.Add( *headOrig );
+ }
+
+ m_lineStack.clear();
+ m_optimizerQueue.clear();
+ m_logger.Clear();
+
+ reduceSpringback( headSet );
+
+ PNS_NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
+
+ m_currentNode = parent->Branch();
+ m_currentNode->ClearRanks();
+ int n = 0;
+
+ BOOST_FOREACH( const PNS_ITEM* item, aHeadSet.CItems() )
+ {
+ const PNS_LINE* headOrig = static_cast<const PNS_LINE*>( item );
+ PNS_LINE head( *headOrig );
+ head.ClearSegmentLinks();
+
+ m_currentNode->Add( &head );
+
+ head.Mark( MK_HEAD );
+ head.SetRank( 100000 );
+ n++;
+
+ if( !pushLine( head ) )
+ return SH_INCOMPLETE;
+
+ PNS_VIA* headVia = NULL;
+
+ if( head.EndsWithVia() )
+ {
+ headVia = head.Via().Clone(); // fixme: leak
+ m_currentNode->Add( headVia );
+ headVia->Mark( MK_HEAD );
+ headVia->SetRank( 100000 );
+ m_logger.Log( headVia, 0, "head-via" );
+ }
+ }
+
+ m_logger.NewGroup( "initial", 0 );
+ //m_logger.Log( head, 0, "head" );
+
+ st = shoveMainLoop();
+
+ if( st == SH_OK )
+ runOptimizer( m_currentNode );
+
+ m_currentNode->RemoveByMarker( MK_HEAD );
+
+ TRACE( 1, "Shove status : %s after %d iterations",
+ ( st == SH_OK ? "OK" : "FAILURE") % m_iter );
+
+ if( st == SH_OK )
+ {
+ pushSpringback( m_currentNode, PNS_ITEMSET(), PNS_COST_ESTIMATOR(), m_affectedAreaSum );
+ }
+ else
+ {
+ delete m_currentNode;
+ m_currentNode = parent;
+ }
+
+ return st;
+}
+
+
+PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR2I& aWhere,
+ PNS_VIA** aNewVia )
+{
+ SHOVE_STATUS st = SH_OK;
+
+ m_lineStack.clear();
+ m_optimizerQueue.clear();
+ m_newHead = OPT_LINE();
+ m_draggedVia = NULL;
+ m_draggedViaHeadSet.Clear();
+
+ PNS_NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
+
+ m_currentNode = parent;
+
+ parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
+
+ m_currentNode = parent->Branch();
+ m_currentNode->ClearRanks();
+
+ aVia->Mark( MK_HEAD );
+
+ st = pushVia( aVia, ( aWhere - aVia->Pos() ), 0 );
+ st = shoveMainLoop();
+
+ if( st == SH_OK )
+ runOptimizer( m_currentNode );
+
+ if( st == SH_OK || st == SH_HEAD_MODIFIED )
+ {
+ pushSpringback( m_currentNode, m_draggedViaHeadSet, PNS_COST_ESTIMATOR(), m_affectedAreaSum );
+ }
+ else
+ {
+ delete m_currentNode;
+ m_currentNode = parent;
+ }
+
+ if( aNewVia )
+ {
+ *aNewVia = m_draggedVia;
+ }
+ return st;
+}
+
+
+void PNS_SHOVE::runOptimizer( PNS_NODE* aNode )
+{
+ PNS_OPTIMIZER optimizer( aNode );
+ int optFlags = 0, n_passes = 0;
+
+ PNS_OPTIMIZATION_EFFORT effort = Settings().OptimizerEffort();
+
+ OPT_BOX2I area = totalAffectedArea();
+
+ int maxWidth = 0;
+
+ for( std::vector<PNS_LINE>::iterator i = m_optimizerQueue.begin();
+ i != m_optimizerQueue.end(); ++i )
+ {
+ maxWidth = std::max( i->Width(), maxWidth );
+ }
+
+ if( area )
+ {
+ area->Inflate( 10 * maxWidth );
+ }
+
+ switch( effort )
+ {
+ case OE_LOW:
+ optFlags = PNS_OPTIMIZER::MERGE_OBTUSE;
+ n_passes = 1;
+ break;
+
+ case OE_MEDIUM:
+ optFlags = PNS_OPTIMIZER::MERGE_SEGMENTS;
+
+ if( area )
+ optimizer.SetRestrictArea( *area );
+
+ n_passes = 2;
+ break;
+
+ case OE_FULL:
+ optFlags = PNS_OPTIMIZER::MERGE_SEGMENTS;
+ n_passes = 2;
+ break;
+
+ default:
+ break;
+ }
+
+ if( Settings().SmartPads() )
+ optFlags |= PNS_OPTIMIZER::SMART_PADS;
+
+ optimizer.SetEffortLevel( optFlags );
+ optimizer.SetCollisionMask( PNS_ITEM::ANY );
+
+ for( int pass = 0; pass < n_passes; pass++ )
+ {
+ std::reverse( m_optimizerQueue.begin(), m_optimizerQueue.end() );
+
+ for( std::vector<PNS_LINE>::iterator i = m_optimizerQueue.begin();
+ i != m_optimizerQueue.end(); ++i )
+ {
+ PNS_LINE& line = *i;
+
+ if( !( line.Marker() & MK_HEAD ) )
+ {
+ PNS_LINE optimized;
+
+ if( optimizer.Optimize( &line, &optimized ) )
+ {
+ aNode->Remove( &line );
+ line.SetShape( optimized.CLine() );
+ aNode->Add( &line );
+ }
+ }
+ }
+ }
+}
+
+
+PNS_NODE* PNS_SHOVE::CurrentNode()
+{
+ return m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
+}
+
+
+const PNS_LINE PNS_SHOVE::NewHead() const
+{
+ assert( m_newHead );
+
+ return *m_newHead;
+}
+
+
+void PNS_SHOVE::SetInitialLine( PNS_LINE& aInitial )
+{
+ m_root = m_root->Branch();
+ m_root->Remove( &aInitial );
+}
diff --git a/pcbnew/router/pns_shove.h b/pcbnew/router/pns_shove.h
new file mode 100644
index 0000000..f9eb60b
--- /dev/null
+++ b/pcbnew/router/pns_shove.h
@@ -0,0 +1,159 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_SHOVE_H
+#define __PNS_SHOVE_H
+
+#include <vector>
+#include <stack>
+
+#include "pns_optimizer.h"
+#include "pns_routing_settings.h"
+#include "pns_algo_base.h"
+#include "pns_logger.h"
+#include "range.h"
+
+class PNS_LINE;
+class PNS_NODE;
+class PNS_ROUTER;
+
+/**
+ * Class PNS_SHOVE
+ *
+ * The actual Push and Shove algorithm.
+ */
+
+class PNS_SHOVE : public PNS_ALGO_BASE
+{
+public:
+
+ enum SHOVE_STATUS
+ {
+ SH_OK = 0,
+ SH_NULL,
+ SH_INCOMPLETE,
+ SH_HEAD_MODIFIED,
+ SH_TRY_WALK
+ };
+
+ PNS_SHOVE( PNS_NODE* aWorld, PNS_ROUTER* aRouter );
+ ~PNS_SHOVE();
+
+ virtual PNS_LOGGER* Logger()
+ {
+ return &m_logger;
+ }
+
+ SHOVE_STATUS ShoveLines( const PNS_LINE& aCurrentHead );
+ SHOVE_STATUS ShoveMultiLines( const PNS_ITEMSET& aHeadSet );
+
+ SHOVE_STATUS ShoveDraggingVia( PNS_VIA* aVia, const VECTOR2I& aWhere, PNS_VIA** aNewVia );
+ SHOVE_STATUS ProcessSingleLine( PNS_LINE& aCurrent, PNS_LINE& aObstacle,
+ PNS_LINE& aShoved );
+
+ void ForceClearance ( bool aEnabled, int aClearance )
+ {
+ if( aEnabled )
+ m_forceClearance = aClearance;
+ else
+ m_forceClearance = -1;
+ }
+
+ PNS_NODE* CurrentNode();
+
+ const PNS_LINE NewHead() const;
+
+ void SetInitialLine( PNS_LINE& aInitial );
+
+private:
+ typedef std::vector<SHAPE_LINE_CHAIN> HULL_SET;
+ typedef boost::optional<PNS_LINE> OPT_LINE;
+ typedef std::pair<PNS_LINE, PNS_LINE> LINE_PAIR;
+ typedef std::vector<LINE_PAIR> LINE_PAIR_VEC;
+
+ struct SPRINGBACK_TAG
+ {
+ int64_t m_length;
+ int m_segments;
+ VECTOR2I m_p;
+ PNS_NODE* m_node;
+ PNS_ITEMSET m_headItems;
+ PNS_COST_ESTIMATOR m_cost;
+ OPT_BOX2I m_affectedArea;
+ };
+
+ SHOVE_STATUS processHullSet( PNS_LINE& aCurrent, PNS_LINE& aObstacle,
+ PNS_LINE& aShoved, const HULL_SET& hulls );
+
+ bool reduceSpringback( const PNS_ITEMSET& aHeadItems );
+ bool pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems,
+ const PNS_COST_ESTIMATOR& aCost, const OPT_BOX2I& aAffectedArea );
+
+ SHOVE_STATUS walkaroundLoneVia( PNS_LINE& aCurrent, PNS_LINE& aObstacle, PNS_LINE& aShoved );
+ bool checkBumpDirection( const PNS_LINE& aCurrent, const PNS_LINE& aShoved ) const;
+
+ SHOVE_STATUS onCollidingLine( PNS_LINE& aCurrent, PNS_LINE& aObstacle );
+ SHOVE_STATUS onCollidingSegment( PNS_LINE& aCurrent, PNS_SEGMENT* aObstacleSeg );
+ SHOVE_STATUS onCollidingSolid( PNS_LINE& aCurrent, PNS_ITEM* aObstacle );
+ SHOVE_STATUS onCollidingVia( PNS_ITEM* aCurrent, PNS_VIA* aObstacleVia );
+ SHOVE_STATUS onReverseCollidingVia( PNS_LINE& aCurrent, PNS_VIA* aObstacleVia );
+ SHOVE_STATUS pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank, bool aDryRun = false );
+
+ OPT_BOX2I totalAffectedArea() const;
+
+ void unwindStack( PNS_SEGMENT* aSeg );
+ void unwindStack( PNS_ITEM* aItem );
+
+ void runOptimizer( PNS_NODE* aNode );
+
+ bool pushLine( const PNS_LINE& aL, bool aKeepCurrentOnTop = false );
+ void popLine();
+
+ PNS_LINE assembleLine( const PNS_SEGMENT* aSeg, int* aIndex = NULL );
+
+ void replaceItems( PNS_ITEM* aOld, PNS_ITEM* aNew );
+
+ OPT_BOX2I m_affectedAreaSum;
+
+ SHOVE_STATUS shoveIteration( int aIter );
+ SHOVE_STATUS shoveMainLoop();
+
+ int getClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const;
+
+ std::vector<SPRINGBACK_TAG> m_nodeStack;
+ std::vector<PNS_LINE> m_lineStack;
+ std::vector<PNS_LINE> m_optimizerQueue;
+
+ PNS_NODE* m_root;
+ PNS_NODE* m_currentNode;
+
+ OPT_LINE m_newHead;
+
+ PNS_LOGGER m_logger;
+ PNS_VIA* m_draggedVia;
+ PNS_ITEMSET m_draggedViaHeadSet;
+
+ int m_iter;
+ int m_forceClearance;
+ bool m_multiLineMode;
+ void sanityCheck( PNS_LINE* aOld, PNS_LINE* aNew );
+};
+
+#endif // __PNS_SHOVE_H
diff --git a/pcbnew/router/pns_sizes_settings.cpp b/pcbnew/router/pns_sizes_settings.cpp
new file mode 100644
index 0000000..dae3ea3
--- /dev/null
+++ b/pcbnew/router/pns_sizes_settings.cpp
@@ -0,0 +1,167 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <class_board.h>
+
+#include "pns_item.h"
+#include "pns_via.h"
+#include "pns_solid.h"
+#include "pns_node.h"
+#include "pns_sizes_settings.h"
+
+int PNS_SIZES_SETTINGS::inheritTrackWidth( PNS_ITEM* aItem )
+{
+ VECTOR2I p;
+
+ assert( aItem->Owner() != NULL );
+
+ switch( aItem->Kind() )
+ {
+ case PNS_ITEM::VIA:
+ p = static_cast<PNS_VIA*>( aItem )->Pos();
+ break;
+
+ case PNS_ITEM::SOLID:
+ p = static_cast<PNS_SOLID*>( aItem )->Pos();
+ break;
+
+ case PNS_ITEM::SEGMENT:
+ return static_cast<PNS_SEGMENT*>( aItem )->Width();
+
+ default:
+ return 0;
+ }
+
+ PNS_JOINT* jt = static_cast<PNS_NODE*>( aItem->Owner() )->FindJoint( p, aItem );
+
+ assert( jt != NULL );
+
+ int mval = INT_MAX;
+
+
+ PNS_ITEMSET linkedSegs = jt->Links();
+ linkedSegs.ExcludeItem( aItem ).FilterKinds( PNS_ITEM::SEGMENT );
+
+ BOOST_FOREACH( PNS_ITEM* item, linkedSegs.Items() )
+ {
+ int w = static_cast<PNS_SEGMENT*>( item )->Width();
+ mval = std::min( w, mval );
+ }
+
+ return ( mval == INT_MAX ? 0 : mval );
+}
+
+
+void PNS_SIZES_SETTINGS::Init( BOARD* aBoard, PNS_ITEM* aStartItem, int aNet )
+{
+ BOARD_DESIGN_SETTINGS &bds = aBoard->GetDesignSettings();
+
+ NETCLASSPTR netClass;
+ int net = aNet;
+
+ if( aStartItem )
+ net = aStartItem->Net();
+
+ if( net >= 0 )
+ {
+ NETINFO_ITEM* ni = aBoard->FindNet( net );
+
+ if( ni )
+ {
+ wxString netClassName = ni->GetClassName();
+ netClass = bds.m_NetClasses.Find( netClassName );
+ }
+ }
+
+ if( !netClass )
+ netClass = bds.GetDefault();
+
+ m_trackWidth = 0;
+
+ if( bds.m_UseConnectedTrackWidth && aStartItem != NULL )
+ {
+ m_trackWidth = inheritTrackWidth( aStartItem );
+ }
+
+ if( !m_trackWidth && ( bds.UseNetClassTrack() && netClass != NULL ) ) // netclass value
+ {
+ m_trackWidth = netClass->GetTrackWidth();
+ }
+
+ if( !m_trackWidth )
+ {
+ m_trackWidth = bds.GetCurrentTrackWidth();
+ }
+
+ if( bds.UseNetClassVia() && netClass != NULL ) // netclass value
+ {
+ m_viaDiameter = netClass->GetViaDiameter();
+ m_viaDrill = netClass->GetViaDrill();
+ }
+ else
+ {
+ m_viaDiameter = bds.GetCurrentViaSize();
+ m_viaDrill = bds.GetCurrentViaDrill();
+ }
+
+ m_layerPairs.clear();
+}
+
+
+void PNS_SIZES_SETTINGS::ClearLayerPairs()
+{
+ m_layerPairs.clear();
+}
+
+
+void PNS_SIZES_SETTINGS::AddLayerPair( int aL1, int aL2 )
+{
+ int top = std::min( aL1, aL2 );
+ int bottom = std::max( aL1, aL2 );
+
+ m_layerPairs[bottom] = top;
+ m_layerPairs[top] = bottom;
+}
+
+
+void PNS_SIZES_SETTINGS::ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings )
+{
+ m_trackWidth = aSettings.GetCurrentTrackWidth();
+ m_viaDiameter = aSettings.GetCurrentViaSize();
+ m_viaDrill = aSettings.GetCurrentViaDrill();
+}
+
+
+int PNS_SIZES_SETTINGS::GetLayerTop() const
+{
+ if( m_layerPairs.empty() )
+ return F_Cu;
+ else
+ return m_layerPairs.begin()->first;
+}
+
+
+int PNS_SIZES_SETTINGS::GetLayerBottom() const
+{
+ if( m_layerPairs.empty() )
+ return B_Cu;
+ else
+ return m_layerPairs.begin()->second;
+}
diff --git a/pcbnew/router/pns_sizes_settings.h b/pcbnew/router/pns_sizes_settings.h
new file mode 100644
index 0000000..bb30c9a
--- /dev/null
+++ b/pcbnew/router/pns_sizes_settings.h
@@ -0,0 +1,113 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_SIZES_SETTINGS_H
+#define __PNS_SIZES_SETTINGS_H
+
+#include <map>
+#include <boost/optional.hpp>
+
+#include "../class_track.h" // for VIATYPE_T
+
+class BOARD;
+class BOARD_DESIGN_SETTINGS;
+class PNS_ITEM;
+
+class PNS_SIZES_SETTINGS {
+
+public:
+ PNS_SIZES_SETTINGS() :
+ m_trackWidth( 155000 ),
+ m_diffPairWidth( 125000 ),
+ m_diffPairGap( 180000 ),
+ m_diffPairViaGap( 180000 ),
+ m_viaDiameter( 600000 ),
+ m_viaDrill( 250000 ),
+ m_diffPairViaGapSameAsTraceGap( true ),
+ m_viaType( VIA_THROUGH )
+ {};
+
+ ~PNS_SIZES_SETTINGS() {};
+
+ void Init( BOARD* aBoard, PNS_ITEM* aStartItem = NULL, int aNet = -1 );
+ void ImportCurrent( BOARD_DESIGN_SETTINGS& aSettings );
+
+ void ClearLayerPairs();
+ void AddLayerPair( int aL1, int aL2 );
+
+ int TrackWidth() const { return m_trackWidth; }
+ void SetTrackWidth( int aWidth ) { m_trackWidth = aWidth; }
+
+ int DiffPairWidth() const { return m_diffPairWidth; }
+ int DiffPairGap() const { return m_diffPairGap; }
+
+ int DiffPairViaGap() const {
+ if( m_diffPairViaGapSameAsTraceGap )
+ return m_diffPairGap;
+ else
+ return m_diffPairViaGap;
+ }
+
+ bool DiffPairViaGapSameAsTraceGap() const { return m_diffPairViaGapSameAsTraceGap; }
+
+ void SetDiffPairWidth( int aWidth ) { m_diffPairWidth = aWidth; }
+ void SetDiffPairGap( int aGap ) { m_diffPairGap = aGap; }
+ void SetDiffPairViaGapSameAsTraceGap ( bool aEnable ) { m_diffPairViaGapSameAsTraceGap = aEnable; }
+ void SetDiffPairViaGap( int aGap ) { m_diffPairViaGap = aGap; }
+
+ int ViaDiameter() const { return m_viaDiameter; }
+ void SetViaDiameter( int aDiameter ) { m_viaDiameter = aDiameter; }
+
+ int ViaDrill() const { return m_viaDrill; }
+ void SetViaDrill( int aDrill ) { m_viaDrill = aDrill; }
+
+ boost::optional<int> PairedLayer( int aLayerId )
+ {
+ if( m_layerPairs.find(aLayerId) == m_layerPairs.end() )
+ return boost::optional<int>();
+
+ return m_layerPairs[aLayerId];
+ }
+
+ int GetLayerTop() const;
+ int GetLayerBottom() const;
+
+ void SetViaType( VIATYPE_T aViaType ) { m_viaType = aViaType; }
+ VIATYPE_T ViaType() const { return m_viaType; }
+
+private:
+
+ int inheritTrackWidth( PNS_ITEM* aItem );
+
+ int m_trackWidth;
+ int m_diffPairWidth;
+ int m_diffPairGap;
+ int m_diffPairViaGap;
+ int m_viaDiameter;
+ int m_viaDrill;
+
+ bool m_diffPairViaGapSameAsTraceGap;
+
+ VIATYPE_T m_viaType;
+
+ std::map<int, int> m_layerPairs;
+};
+
+#endif // __PNS_SIZES_SETTINGS_H
diff --git a/pcbnew/router/pns_solid.cpp b/pcbnew/router/pns_solid.cpp
new file mode 100644
index 0000000..d728015
--- /dev/null
+++ b/pcbnew/router/pns_solid.cpp
@@ -0,0 +1,77 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <math/vector2d.h>
+
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+#include <geometry/shape_rect.h>
+#include <geometry/shape_circle.h>
+#include <geometry/shape_convex.h>
+
+#include "pns_solid.h"
+#include "pns_utils.h"
+
+const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness ) const
+{
+ int cl = aClearance + ( aWalkaroundThickness + 1 )/ 2;
+
+ switch( m_shape->Type() )
+ {
+ case SH_RECT:
+ {
+ SHAPE_RECT* rect = static_cast<SHAPE_RECT*>( m_shape );
+ return OctagonalHull( rect->GetPosition(), rect->GetSize(), cl + 1, 0.2 * cl );
+ }
+
+ case SH_CIRCLE:
+ {
+ SHAPE_CIRCLE* circle = static_cast<SHAPE_CIRCLE*>( m_shape );
+ int r = circle->GetRadius();
+ return OctagonalHull( circle->GetCenter() - VECTOR2I( r, r ), VECTOR2I( 2 * r, 2 * r ),
+ cl + 1, 0.52 * ( r + cl ) );
+ }
+
+ case SH_SEGMENT:
+ {
+ SHAPE_SEGMENT* seg = static_cast<SHAPE_SEGMENT*>( m_shape );
+ return SegmentHull( *seg, aClearance, aWalkaroundThickness );
+ }
+
+ case SH_CONVEX:
+ {
+ SHAPE_CONVEX* convex = static_cast<SHAPE_CONVEX*>( m_shape );
+
+ return ConvexHull( *convex, cl );
+ }
+
+ default:
+ break;
+ }
+
+ return SHAPE_LINE_CHAIN();
+}
+
+
+PNS_ITEM* PNS_SOLID::Clone() const
+{
+ PNS_ITEM* solid = new PNS_SOLID( *this );
+ return solid;
+}
diff --git a/pcbnew/router/pns_solid.h b/pcbnew/router/pns_solid.h
new file mode 100644
index 0000000..593b3b0
--- /dev/null
+++ b/pcbnew/router/pns_solid.h
@@ -0,0 +1,107 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_SOLID_H
+#define __PNS_SOLID_H
+
+#include <math/vector2d.h>
+
+#include <geometry/seg.h>
+#include <geometry/shape.h>
+#include <geometry/shape_line_chain.h>
+
+#include "pns_item.h"
+
+class PNS_SOLID : public PNS_ITEM
+{
+public:
+ PNS_SOLID() : PNS_ITEM( SOLID ), m_shape( NULL )
+ {
+ m_movable = false;
+ }
+
+ ~PNS_SOLID()
+ {
+ delete m_shape;
+ }
+
+ PNS_SOLID( const PNS_SOLID& aSolid ) :
+ PNS_ITEM( aSolid )
+ {
+ m_shape = aSolid.m_shape->Clone();
+ m_pos = aSolid.m_pos;
+ }
+
+ static inline bool ClassOf( const PNS_ITEM* aItem )
+ {
+ return aItem && SOLID == aItem->Kind();
+ }
+
+ PNS_ITEM* Clone() const;
+
+ const SHAPE* Shape() const { return m_shape; }
+
+ const SHAPE_LINE_CHAIN Hull( int aClearance = 0, int aWalkaroundThickness = 0 ) const;
+
+ void SetShape( SHAPE* shape )
+ {
+ if( m_shape )
+ delete m_shape;
+
+ m_shape = shape;
+ }
+
+ const VECTOR2I& Pos() const
+ {
+ return m_pos;
+ }
+
+ void SetPos( const VECTOR2I& aCenter )
+ {
+ m_pos = aCenter;
+ }
+
+ virtual VECTOR2I Anchor( int aN ) const
+ {
+ return m_pos;
+ }
+
+ virtual int AnchorCount() const
+ {
+ return 1;
+ }
+
+ VECTOR2I Offset() const
+ {
+ return m_offset;
+ }
+
+ void SetOffset( const VECTOR2I& aOffset )
+ {
+ m_offset = aOffset;
+ }
+
+private:
+ VECTOR2I m_pos;
+ SHAPE* m_shape;
+ VECTOR2I m_offset;
+};
+
+#endif
diff --git a/pcbnew/router/pns_tool_base.cpp b/pcbnew/router/pns_tool_base.cpp
new file mode 100644
index 0000000..5ebbb2d
--- /dev/null
+++ b/pcbnew/router/pns_tool_base.cpp
@@ -0,0 +1,308 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <wx/numdlg.h>
+
+#include <boost/foreach.hpp>
+#include <boost/optional.hpp>
+#include <boost/bind.hpp>
+
+#include "class_draw_panel_gal.h"
+#include "class_board.h"
+
+#include <wxPcbStruct.h>
+#include <id.h>
+#include <macros.h>
+#include <pcbnew_id.h>
+#include <view/view_controls.h>
+#include <pcbcommon.h>
+#include <pcb_painter.h>
+#include <dialogs/dialog_pns_settings.h>
+#include <dialogs/dialog_pns_diff_pair_dimensions.h>
+#include <dialogs/dialog_pns_length_tuning_settings.h>
+#include <dialogs/dialog_track_via_size.h>
+#include <base_units.h>
+
+#include <tool/context_menu.h>
+#include <tools/common_actions.h>
+#include <tools/grid_helper.h>
+
+#include <ratsnest_data.h>
+
+#include "pns_tool_base.h"
+#include "pns_segment.h"
+#include "pns_router.h"
+#include "pns_meander_placer.h" // fixme: move settings to separate header
+#include "pns_tune_status_popup.h"
+#include "trace.h"
+
+using namespace KIGFX;
+using boost::optional;
+
+TOOL_ACTION PNS_TOOL_BASE::ACT_RouterOptions( "pcbnew.InteractiveRouter.RouterOptions",
+ AS_CONTEXT, 'E',
+ _( "Routing Options..." ),
+ _( "Shows a dialog containing router options." ), tools_xpm );
+
+
+PNS_TOOL_BASE::PNS_TOOL_BASE( const std::string& aToolName ) :
+ TOOL_INTERACTIVE( aToolName )
+{
+ m_router = NULL;
+ m_startItem = NULL;
+ m_startLayer = 0;
+
+ m_endItem = NULL;
+
+ m_needsSync = false;
+
+ m_frame = NULL;
+ m_ctls = NULL;
+ m_board = NULL;
+ m_gridHelper = NULL;
+}
+
+
+PNS_TOOL_BASE::~PNS_TOOL_BASE()
+{
+ delete m_router;
+ delete m_gridHelper;
+}
+
+
+
+void PNS_TOOL_BASE::Reset( RESET_REASON aReason )
+{
+ if( m_router )
+ delete m_router;
+
+ if( m_gridHelper)
+ delete m_gridHelper;
+
+ m_frame = getEditFrame<PCB_EDIT_FRAME>();
+ m_ctls = getViewControls();
+ m_board = getModel<BOARD>();
+
+ m_router = new PNS_ROUTER;
+
+ m_router->ClearWorld();
+ m_router->SetBoard( m_board );
+ m_router->SyncWorld();
+ m_router->LoadSettings( m_savedSettings );
+ m_router->UpdateSizes( m_savedSizes );
+
+ m_gridHelper = new GRID_HELPER( m_frame );
+ m_router->SetGrid( m_gridHelper );
+
+ m_needsSync = false;
+
+ if( getView() )
+ m_router->SetView( getView() );
+}
+
+
+PNS_ITEM* PNS_TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer )
+{
+ int tl = getView()->GetTopLayer();
+
+ if( aLayer > 0 )
+ tl = aLayer;
+
+ PNS_ITEM* prioritized[4];
+
+ for( int i = 0; i < 4; i++ )
+ prioritized[i] = 0;
+
+ PNS_ITEMSET candidates = m_router->QueryHoverItems( aWhere );
+
+ BOOST_FOREACH( PNS_ITEM* item, candidates.Items() )
+ {
+ if( !IsCopperLayer( item->Layers().Start() ) )
+ continue;
+
+ // fixme: this causes flicker with live loop removal...
+ //if( item->Parent() && !item->Parent()->ViewIsVisible() )
+ // continue;
+
+ if( aNet < 0 || item->Net() == aNet )
+ {
+ if( item->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID ) )
+ {
+ if( !prioritized[2] )
+ prioritized[2] = item;
+ if( item->Layers().Overlaps( tl ) )
+ prioritized[0] = item;
+ }
+ else
+ {
+ if( !prioritized[3] )
+ prioritized[3] = item;
+ if( item->Layers().Overlaps( tl ) )
+ prioritized[1] = item;
+ }
+ }
+ }
+
+ PNS_ITEM* rv = NULL;
+ PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)frame->GetDisplayOptions();
+
+ for( int i = 0; i < 4; i++ )
+ {
+ PNS_ITEM* item = prioritized[i];
+
+ if( displ_opts->m_ContrastModeDisplay )
+ if( item && !item->Layers().Overlaps( tl ) )
+ item = NULL;
+
+ if( item )
+ {
+ rv = item;
+ break;
+ }
+ }
+
+ if( rv && aLayer >= 0 && !rv->Layers().Overlaps( aLayer ) )
+ rv = NULL;
+
+ if( rv )
+ TRACE( 0, "%s, layer : %d, tl: %d", rv->KindStr().c_str() % rv->Layers().Start() % tl );
+
+ return rv;
+}
+
+
+void PNS_TOOL_BASE::highlightNet( bool aEnabled, int aNetcode )
+{
+ RENDER_SETTINGS* rs = getView()->GetPainter()->GetSettings();
+
+ if( aNetcode >= 0 && aEnabled )
+ rs->SetHighlight( true, aNetcode );
+ else
+ rs->SetHighlight( false );
+
+ getView()->UpdateAllLayersColor();
+}
+
+
+void PNS_TOOL_BASE::updateStartItem( TOOL_EVENT& aEvent )
+{
+ int tl = getView()->GetTopLayer();
+ VECTOR2I cp = m_ctls->GetCursorPosition();
+ VECTOR2I p;
+
+ PNS_ITEM* startItem = NULL;
+ bool snapEnabled = true;
+
+ if( aEvent.IsMotion() || aEvent.IsClick() )
+ {
+ snapEnabled = !aEvent.Modifier( MD_SHIFT );
+ p = aEvent.Position();
+ } else {
+ p = cp;
+ }
+
+ startItem = pickSingleItem( p );
+ m_router->EnableSnapping ( snapEnabled );
+
+ if( !snapEnabled && startItem && !startItem->Layers().Overlaps( tl ) )
+ startItem = NULL;
+
+ if( startItem && startItem->Net() >= 0 )
+ {
+ bool dummy;
+ VECTOR2I psnap = m_router->SnapToItem( startItem, p, dummy );
+
+ if( snapEnabled )
+ {
+ m_startSnapPoint = psnap;
+ m_ctls->ForceCursorPosition( true, psnap );
+ }
+ else
+ {
+ m_startSnapPoint = cp;
+ m_ctls->ForceCursorPosition( false );
+ }
+
+ m_startItem = startItem;
+ }
+ else
+ {
+ m_startItem = NULL;
+ m_startSnapPoint = cp;
+ m_ctls->ForceCursorPosition( false );
+ }
+}
+
+
+void PNS_TOOL_BASE::updateEndItem( TOOL_EVENT& aEvent )
+{
+ VECTOR2I mp = m_ctls->GetMousePosition();
+ VECTOR2I p = getView()->ToWorld( mp );
+ VECTOR2I cp = m_ctls->GetCursorPosition();
+ int layer;
+ bool snapEnabled = !aEvent.Modifier( MD_SHIFT );
+
+ m_router->EnableSnapping( snapEnabled );
+
+ if( m_router->GetCurrentNets().empty() || m_router->GetCurrentNets().front() < 0 )
+ {
+ m_endItem = NULL;
+ m_endSnapPoint = cp;
+ return;
+ }
+
+ bool dummy;
+
+ if( m_router->IsPlacingVia() )
+ layer = -1;
+ else
+ layer = m_router->GetCurrentLayer();
+
+ PNS_ITEM* endItem = NULL;
+
+ std::vector<int> nets = m_router->GetCurrentNets();
+
+ BOOST_FOREACH( int net, nets )
+ {
+ endItem = pickSingleItem( p, net, layer );
+
+ if( endItem )
+ break;
+ }
+
+ if( endItem )
+ {
+ VECTOR2I cursorPos = m_router->SnapToItem( endItem, p, dummy );
+ m_ctls->ForceCursorPosition( true, cursorPos );
+ m_endItem = endItem;
+ m_endSnapPoint = cursorPos;
+ }
+ else
+ {
+ m_endItem = NULL;
+ m_endSnapPoint = cp;
+ m_ctls->ForceCursorPosition( false );
+ }
+
+ if( m_endItem )
+ TRACE( 0, "%s, layer : %d", m_endItem->KindStr().c_str() % m_endItem->Layers().Start() );
+}
+
diff --git a/pcbnew/router/pns_tool_base.h b/pcbnew/router/pns_tool_base.h
new file mode 100644
index 0000000..20bed42
--- /dev/null
+++ b/pcbnew/router/pns_tool_base.h
@@ -0,0 +1,82 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ * Author: Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_TOOL_BASE_H
+#define __PNS_TOOL_BASE_H
+
+#include <import_export.h>
+
+#include <math/vector2d.h>
+#include <tool/tool_interactive.h>
+
+#include <msgpanel.h>
+
+#include "pns_router.h"
+
+class PNS_TUNE_STATUS_POPUP;
+class GRID_HELPER;
+
+class APIEXPORT PNS_TOOL_BASE : public TOOL_INTERACTIVE
+{
+public:
+ static TOOL_ACTION ACT_RouterOptions;
+
+ PNS_TOOL_BASE( const std::string& aToolName );
+ virtual ~PNS_TOOL_BASE();
+
+ virtual void Reset( RESET_REASON aReason );
+
+ const PNS_ROUTING_SETTINGS& PNSSettings() const
+ {
+ return m_savedSettings;
+ }
+
+protected:
+
+ virtual PNS_ITEM* pickSingleItem( const VECTOR2I& aWhere, int aNet = -1, int aLayer = -1 );
+ virtual void highlightNet( bool aEnabled, int aNetcode = -1 );
+ virtual void updateStartItem( TOOL_EVENT& aEvent );
+ virtual void updateEndItem( TOOL_EVENT& aEvent );
+
+ MSG_PANEL_ITEMS m_panelItems;
+
+ PNS_ROUTER* m_router;
+ PNS_ROUTING_SETTINGS m_savedSettings; ///< Stores routing settings between router invocations
+ PNS_SIZES_SETTINGS m_savedSizes; ///< Stores sizes settings between router invocations
+ PNS_ITEM* m_startItem;
+ int m_startLayer;
+ VECTOR2I m_startSnapPoint;
+
+ PNS_ITEM* m_endItem;
+ VECTOR2I m_endSnapPoint;
+
+ ///> Flag marking that the router's world needs syncing.
+ bool m_needsSync;
+
+ PCB_EDIT_FRAME* m_frame;
+ KIGFX::VIEW_CONTROLS* m_ctls;
+ BOARD* m_board;
+ GRID_HELPER* m_gridHelper;
+
+
+};
+
+#endif
diff --git a/pcbnew/router/pns_topology.cpp b/pcbnew/router/pns_topology.cpp
new file mode 100644
index 0000000..3fb17b0
--- /dev/null
+++ b/pcbnew/router/pns_topology.cpp
@@ -0,0 +1,433 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pns_line.h"
+#include "pns_segment.h"
+#include "pns_node.h"
+#include "pns_joint.h"
+#include "pns_solid.h"
+#include "pns_router.h"
+#include "pns_utils.h"
+
+#include "pns_diff_pair.h"
+#include "pns_topology.h"
+
+#include <class_board.h>
+
+bool PNS_TOPOLOGY::SimplifyLine( PNS_LINE* aLine )
+{
+ if( !aLine->LinkedSegments() || !aLine->SegmentCount() )
+ return false;
+
+ PNS_SEGMENT* root = ( *aLine->LinkedSegments() )[0];
+ PNS_LINE l = m_world->AssembleLine( root );
+ SHAPE_LINE_CHAIN simplified( l.CLine() );
+
+ simplified.Simplify();
+
+ if( simplified.PointCount() != l.PointCount() )
+ {
+ PNS_LINE lnew( l );
+ m_world->Remove( &l );
+ lnew.SetShape( simplified );
+ m_world->Add( &lnew );
+ return true;
+ }
+
+ return false;
+}
+
+
+const PNS_TOPOLOGY::JOINT_SET PNS_TOPOLOGY::ConnectedJoints( PNS_JOINT* aStart )
+{
+ std::deque<PNS_JOINT*> searchQueue;
+ JOINT_SET processed;
+
+ searchQueue.push_back( aStart );
+ processed.insert( aStart );
+
+ while( !searchQueue.empty() )
+ {
+ PNS_JOINT* current = searchQueue.front();
+ searchQueue.pop_front();
+
+ BOOST_FOREACH( PNS_ITEM* item, current->LinkList() )
+ {
+ if( item->OfKind( PNS_ITEM::SEGMENT ) )
+ {
+ PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( item );
+ PNS_JOINT* a = m_world->FindJoint( seg->Seg().A, seg );
+ PNS_JOINT* b = m_world->FindJoint( seg->Seg().B, seg );
+ PNS_JOINT* next = ( *a == *current ) ? b : a;
+
+ if( processed.find( next ) == processed.end() )
+ {
+ processed.insert( next );
+ searchQueue.push_back( next );
+ }
+ }
+ }
+ }
+
+ return processed;
+}
+
+
+bool PNS_TOPOLOGY::LeadingRatLine( const PNS_LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine )
+{
+ PNS_LINE track( *aTrack );
+ VECTOR2I end;
+
+ if( !track.PointCount() )
+ return false;
+
+ std::auto_ptr<PNS_NODE> tmpNode( m_world->Branch() );
+ tmpNode->Add( &track );
+
+ PNS_JOINT* jt = tmpNode->FindJoint( track.CPoint( -1 ), &track );
+
+ if( !jt )
+ return false;
+
+ if( ( !track.EndsWithVia() && jt->LinkCount() >= 2 ) || ( track.EndsWithVia() && jt->LinkCount() >= 3 ) ) // we got something connected
+ {
+ end = jt->Pos();
+ }
+ else
+ {
+ int anchor;
+
+ PNS_TOPOLOGY topo( tmpNode.get() );
+ PNS_ITEM* it = topo.NearestUnconnectedItem( jt, &anchor );
+
+ if( !it )
+ return false;
+
+ end = it->Anchor( anchor );
+ }
+
+ aRatLine.Clear();
+ aRatLine.Append( track.CPoint( -1 ) );
+ aRatLine.Append( end );
+ return true;
+}
+
+
+PNS_ITEM* PNS_TOPOLOGY::NearestUnconnectedItem( PNS_JOINT* aStart, int* aAnchor, int aKindMask )
+{
+ std::set<PNS_ITEM*> disconnected;
+
+ m_world->AllItemsInNet( aStart->Net(), disconnected );
+
+ BOOST_FOREACH( const PNS_JOINT* jt, ConnectedJoints( aStart ) )
+ {
+ BOOST_FOREACH( PNS_ITEM* link, jt->LinkList() )
+ {
+ if( disconnected.find( link ) != disconnected.end() )
+ disconnected.erase( link );
+ }
+ }
+
+ int best_dist = INT_MAX;
+ PNS_ITEM* best = NULL;
+
+ BOOST_FOREACH( PNS_ITEM* item, disconnected )
+ {
+ if( item->OfKind( aKindMask ) )
+ {
+ for(int i = 0; i < item->AnchorCount(); i++)
+ {
+ VECTOR2I p = item->Anchor( i );
+ int d = ( p - aStart->Pos() ).EuclideanNorm();
+
+ if( d < best_dist )
+ {
+ best_dist = d;
+ best = item;
+
+ if( aAnchor )
+ *aAnchor = i;
+ }
+ }
+ }
+ }
+
+ return best;
+}
+
+
+bool PNS_TOPOLOGY::followTrivialPath( PNS_LINE* aLine, bool aLeft, PNS_ITEMSET& aSet, std::set<PNS_ITEM*>& aVisited )
+{
+ VECTOR2I anchor = aLeft ? aLine->CPoint( 0 ) : aLine->CPoint( -1 );
+ PNS_SEGMENT* last = aLeft ? aLine->LinkedSegments()->front() : aLine->LinkedSegments()->back();
+ PNS_JOINT* jt = m_world->FindJoint( anchor, aLine );
+
+ assert( jt != NULL );
+
+ aVisited.insert( last );
+
+ if( jt->IsNonFanoutVia() || jt->IsTraceWidthChange() )
+ {
+ PNS_ITEM* via = NULL;
+ PNS_SEGMENT* next_seg = NULL;
+
+ BOOST_FOREACH( PNS_ITEM* link, jt->Links().Items() )
+ {
+ if( link->OfKind( PNS_ITEM::VIA ) )
+ via = link;
+ else if( aVisited.find( link ) == aVisited.end() )
+ next_seg = static_cast<PNS_SEGMENT*>( link );
+ }
+
+ if( !next_seg )
+ return false;
+
+ PNS_LINE l = m_world->AssembleLine( next_seg );
+
+ VECTOR2I nextAnchor = ( aLeft ? l.CLine().CPoint( -1 ) : l.CLine().CPoint( 0 ) );
+
+ if( nextAnchor != anchor )
+ {
+ l.Reverse();
+ }
+
+ if( aLeft )
+ {
+ if( via )
+ aSet.Prepend( via );
+
+ aSet.Prepend( l );
+ }
+ else
+ {
+ if( via )
+ aSet.Add( via );
+
+ aSet.Add( l );
+ }
+
+ return followTrivialPath( &l, aLeft, aSet, aVisited );
+ }
+
+ return false;
+}
+
+
+const PNS_ITEMSET PNS_TOPOLOGY::AssembleTrivialPath( PNS_SEGMENT* aStart )
+{
+ PNS_ITEMSET path;
+ std::set<PNS_ITEM*> visited;
+
+ PNS_LINE l = m_world->AssembleLine( aStart );
+
+ path.Add( l );
+
+ followTrivialPath( &l, false, path, visited );
+ followTrivialPath( &l, true, path, visited );
+
+ return path;
+}
+
+
+const PNS_ITEMSET PNS_TOPOLOGY::ConnectedItems( PNS_JOINT* aStart, int aKindMask )
+{
+ return PNS_ITEMSET();
+}
+
+
+const PNS_ITEMSET PNS_TOPOLOGY::ConnectedItems( PNS_ITEM* aStart, int aKindMask )
+{
+ return PNS_ITEMSET();
+}
+
+
+int PNS_TOPOLOGY::MatchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName )
+{
+ int rv = 0;
+
+ if( aNetName.EndsWith( "+" ) )
+ {
+ aComplementNet = "-";
+ rv = 1;
+ }
+ else if( aNetName.EndsWith( "_P" ) )
+ {
+ aComplementNet = "_N";
+ rv = 1;
+ }
+ else if( aNetName.EndsWith( "-" ) )
+ {
+ aComplementNet = "+";
+ rv = -1;
+ }
+ else if( aNetName.EndsWith( "_N" ) )
+ {
+ aComplementNet = "_P";
+ rv = -1;
+ }
+
+ if( rv != 0 )
+ {
+ aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
+ aComplementNet = aBaseDpName + aComplementNet;
+ }
+
+ return rv;
+}
+
+
+int PNS_TOPOLOGY::DpCoupledNet( int aNet )
+{
+ BOARD* brd = PNS_ROUTER::GetInstance()->GetBoard();
+
+ wxString refName = brd->FindNet( aNet )->GetNetname();
+ wxString dummy, coupledNetName;
+
+ if( MatchDpSuffix( refName, coupledNetName, dummy ) )
+ {
+ NETINFO_ITEM* net = brd->FindNet( coupledNetName );
+
+ if( !net )
+ return -1;
+
+ return net->GetNet();
+
+ }
+
+ return -1;
+}
+
+
+int PNS_TOPOLOGY::DpNetPolarity( int aNet )
+{
+ BOARD* brd = PNS_ROUTER::GetInstance()->GetBoard();
+
+ wxString refName = brd->FindNet( aNet )->GetNetname();
+ wxString dummy1, dummy2;
+
+ return MatchDpSuffix( refName, dummy1, dummy2 );
+}
+
+
+bool commonParallelProjection( SEG n, SEG p, SEG &pClip, SEG& nClip );
+
+
+bool PNS_TOPOLOGY::AssembleDiffPair( PNS_ITEM* aStart, PNS_DIFF_PAIR& aPair )
+{
+ int refNet = aStart->Net();
+ int coupledNet = DpCoupledNet( refNet );
+
+ if( coupledNet < 0 )
+ return false;
+
+ std::set<PNS_ITEM*> coupledItems;
+
+ m_world->AllItemsInNet( coupledNet, coupledItems );
+
+ PNS_SEGMENT* coupledSeg = NULL, *refSeg;
+ int minDist = std::numeric_limits<int>::max();
+
+ if( ( refSeg = dyn_cast<PNS_SEGMENT*>( aStart ) ) != NULL )
+ {
+ BOOST_FOREACH( PNS_ITEM* item, coupledItems )
+ {
+ if( PNS_SEGMENT* s = dyn_cast<PNS_SEGMENT*>( item ) )
+ {
+ if( s->Layers().Start() == refSeg->Layers().Start() && s->Width() == refSeg->Width() )
+ {
+ int dist = s->Seg().Distance( refSeg->Seg() );
+ bool isParallel = refSeg->Seg().ApproxParallel( s->Seg() );
+ SEG p_clip, n_clip;
+
+ bool isCoupled = commonParallelProjection( refSeg->Seg(), s->Seg(), p_clip, n_clip );
+
+ if( isParallel && isCoupled && dist < minDist )
+ {
+ minDist = dist;
+ coupledSeg = s;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ if( !coupledSeg )
+ return false;
+
+ PNS_LINE lp = m_world->AssembleLine( refSeg );
+ PNS_LINE ln = m_world->AssembleLine( coupledSeg );
+
+ if( DpNetPolarity( refNet ) < 0 )
+ {
+ std::swap( lp, ln );
+ }
+
+ int gap = -1;
+
+ if( refSeg->Seg().ApproxParallel( coupledSeg->Seg() ) )
+ {
+ // Segments are parallel -> compute pair gap
+ const VECTOR2I refDir = refSeg->Anchor( 1 ) - refSeg->Anchor( 0 );
+ const VECTOR2I displacement = refSeg->Anchor( 1 ) - coupledSeg->Anchor( 1 );
+ gap = (int) std::abs( refDir.Cross( displacement ) / refDir.EuclideanNorm() ) - lp.Width();
+ }
+
+ aPair = PNS_DIFF_PAIR( lp, ln );
+ aPair.SetWidth( lp.Width() );
+ aPair.SetLayers( lp.Layers() );
+ aPair.SetGap( gap );
+
+ return true;
+}
+
+const std::set<PNS_ITEM*> PNS_TOPOLOGY::AssembleCluster( PNS_ITEM* aStart, int aLayer )
+{
+ std::set<PNS_ITEM*> visited;
+ std::deque<PNS_ITEM*> pending;
+
+ pending.push_back( aStart );
+
+ while( !pending.empty() )
+ {
+ PNS_NODE::OBSTACLES obstacles;
+ PNS_ITEM* top = pending.front();
+
+ pending.pop_front();
+
+ visited.insert( top );
+
+ m_world->QueryColliding( top, obstacles, PNS_ITEM::ANY, -1, false, 0 );
+
+ BOOST_FOREACH( PNS_OBSTACLE& obs, obstacles )
+ {
+ if( visited.find( obs.m_item ) == visited.end() && obs.m_item->Layers().Overlaps( aLayer ) && !( obs.m_item->Marker() & MK_HEAD ) )
+ {
+ visited.insert( obs.m_item );
+ pending.push_back( obs.m_item );
+ }
+ }
+ }
+
+ return visited;
+}
diff --git a/pcbnew/router/pns_topology.h b/pcbnew/router/pns_topology.h
new file mode 100644
index 0000000..bbc36a8
--- /dev/null
+++ b/pcbnew/router/pns_topology.h
@@ -0,0 +1,72 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_TOPOLOGY_H
+#define __PNS_TOPOLOGY_H
+
+#include <vector>
+#include <set>
+
+#include "pns_itemset.h"
+
+class PNS_NODE;
+class PNS_SEGMENT;
+class PNS_JOINT;
+class PNS_ITEM;
+class PNS_SOLID;
+class PNS_DIFF_PAIR;
+
+class PNS_TOPOLOGY
+{
+public:
+ typedef std::set<PNS_JOINT*> JOINT_SET;
+
+ PNS_TOPOLOGY( PNS_NODE* aNode ):
+ m_world( aNode ) {};
+
+ ~PNS_TOPOLOGY() {};
+
+ bool SimplifyLine( PNS_LINE *aLine );
+ PNS_ITEM* NearestUnconnectedItem( PNS_JOINT* aStart, int* aAnchor = NULL, int aKindMask = PNS_ITEM::ANY );
+ bool LeadingRatLine( const PNS_LINE* aTrack, SHAPE_LINE_CHAIN& aRatLine );
+
+ const JOINT_SET ConnectedJoints( PNS_JOINT* aStart );
+ const PNS_ITEMSET ConnectedItems( PNS_JOINT* aStart, int aKindMask = PNS_ITEM::ANY );
+ const PNS_ITEMSET ConnectedItems( PNS_ITEM* aStart, int aKindMask = PNS_ITEM::ANY );
+ int64_t ShortestConnectionLength( PNS_ITEM* aFrom, PNS_ITEM* aTo );
+
+ const PNS_ITEMSET AssembleTrivialPath( PNS_SEGMENT* aStart );
+ const PNS_DIFF_PAIR AssembleDiffPair( PNS_SEGMENT* aStart );
+
+ int MatchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName );
+ int DpCoupledNet( int aNet );
+ int DpNetPolarity( int aNet );
+ const PNS_LINE DpCoupledLine( PNS_LINE* aLine );
+ bool AssembleDiffPair( PNS_ITEM* aStart, PNS_DIFF_PAIR& aPair );
+
+ const std::set<PNS_ITEM*> AssembleCluster( PNS_ITEM* aStart, int aLayer );
+
+private:
+ bool followTrivialPath( PNS_LINE* aLine, bool aLeft, PNS_ITEMSET& aSet, std::set<PNS_ITEM*>& aVisited );
+
+ PNS_NODE *m_world;
+};
+
+#endif
diff --git a/pcbnew/router/pns_tune_status_popup.cpp b/pcbnew/router/pns_tune_status_popup.cpp
new file mode 100644
index 0000000..40be366
--- /dev/null
+++ b/pcbnew/router/pns_tune_status_popup.cpp
@@ -0,0 +1,67 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pns_tune_status_popup.h"
+#include "pns_router.h"
+#include "pns_meander_placer.h"
+
+PNS_TUNE_STATUS_POPUP::PNS_TUNE_STATUS_POPUP( PCB_EDIT_FRAME* aParent ) :
+ WX_STATUS_POPUP( aParent )
+{
+ m_panel->SetBackgroundColour( wxColour( 64, 64, 64 ) );
+ m_statusLine = new wxStaticText( m_panel, wxID_ANY, wxEmptyString ) ;
+ m_topSizer->Add( m_statusLine, 1, wxALL | wxEXPAND, 5 );
+}
+
+
+PNS_TUNE_STATUS_POPUP::~PNS_TUNE_STATUS_POPUP()
+{
+}
+
+
+void PNS_TUNE_STATUS_POPUP::UpdateStatus( PNS_ROUTER* aRouter )
+{
+ PNS_MEANDER_PLACER_BASE* placer = dynamic_cast<PNS_MEANDER_PLACER_BASE*>( aRouter->Placer() );
+
+ if( !placer )
+ return;
+
+ m_statusLine->SetLabel( placer->TuningInfo() );
+
+ wxColour color;
+
+ switch( placer->TuningStatus() )
+ {
+ case PNS_MEANDER_PLACER::TUNED:
+ color = wxColour( 0, 255, 0 );
+ break;
+ case PNS_MEANDER_PLACER::TOO_SHORT:
+ color = wxColour( 255, 128, 128 );
+ break;
+ case PNS_MEANDER_PLACER::TOO_LONG:
+ color = wxColour( 128, 128, 255 );
+ break;
+ }
+
+ m_statusLine->SetForegroundColour( color );
+
+ updateSize();
+}
+
diff --git a/pcbnew/router/pns_tune_status_popup.h b/pcbnew/router/pns_tune_status_popup.h
new file mode 100644
index 0000000..c6fe469
--- /dev/null
+++ b/pcbnew/router/pns_tune_status_popup.h
@@ -0,0 +1,44 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __PNS_TUNE_STATUS_POPUP_H_
+#define __PNS_TUNE_STATUS_POPUP_H_
+
+#include <wx_status_popup.h>
+
+class PNS_ROUTER;
+
+class PNS_TUNE_STATUS_POPUP : public WX_STATUS_POPUP
+{
+public:
+ PNS_TUNE_STATUS_POPUP( PCB_EDIT_FRAME* aParent );
+ ~PNS_TUNE_STATUS_POPUP();
+
+ void UpdateStatus( PNS_ROUTER* aRouter );
+
+private:
+ wxStaticText* m_statusLine;
+};
+
+#endif /* __PNS_TUNE_STATUS_POPUP_H_*/
diff --git a/pcbnew/router/pns_utils.cpp b/pcbnew/router/pns_utils.cpp
new file mode 100644
index 0000000..31eb78d
--- /dev/null
+++ b/pcbnew/router/pns_utils.cpp
@@ -0,0 +1,244 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pns_utils.h"
+#include "pns_line.h"
+#include "pns_via.h"
+#include "pns_router.h"
+
+#include <geometry/shape_segment.h>
+
+const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0, const VECTOR2I& aSize,
+ int aClearance, int aChamfer )
+{
+ SHAPE_LINE_CHAIN s;
+
+ s.SetClosed( true );
+
+ s.Append( aP0.x - aClearance, aP0.y - aClearance + aChamfer );
+ s.Append( aP0.x - aClearance + aChamfer, aP0.y - aClearance );
+ s.Append( aP0.x + aSize.x + aClearance - aChamfer, aP0.y - aClearance );
+ s.Append( aP0.x + aSize.x + aClearance, aP0.y - aClearance + aChamfer );
+ s.Append( aP0.x + aSize.x + aClearance, aP0.y + aSize.y + aClearance - aChamfer );
+ s.Append( aP0.x + aSize.x + aClearance - aChamfer, aP0.y + aSize.y + aClearance );
+ s.Append( aP0.x - aClearance + aChamfer, aP0.y + aSize.y + aClearance );
+ s.Append( aP0.x - aClearance, aP0.y + aSize.y + aClearance - aChamfer );
+
+ return s;
+}
+
+
+const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, int aClearance,
+ int aWalkaroundThickness )
+{
+ int d = aSeg.GetWidth() / 2 + aClearance + aWalkaroundThickness / 2 + HULL_MARGIN;
+ int x = (int)( 2.0 / ( 1.0 + M_SQRT2 ) * d );
+
+ const VECTOR2I a = aSeg.GetSeg().A;
+ const VECTOR2I b = aSeg.GetSeg().B;
+
+ VECTOR2I dir = b - a;
+ VECTOR2I p0 = dir.Perpendicular().Resize( d );
+ VECTOR2I ds = dir.Perpendicular().Resize( x / 2 );
+ VECTOR2I pd = dir.Resize( x / 2 );
+ VECTOR2I dp = dir.Resize( d );
+
+ SHAPE_LINE_CHAIN s;
+
+ s.SetClosed( true );
+
+ s.Append( b + p0 + pd );
+ s.Append( b + dp + ds );
+ s.Append( b + dp - ds );
+ s.Append( b - p0 + pd );
+ s.Append( a - p0 - pd );
+ s.Append( a - dp - ds );
+ s.Append( a - dp + ds );
+ s.Append( a + p0 - pd );
+
+ // make sure the hull outline is always clockwise
+ if( s.CSegment( 0 ).Side( a ) < 0 )
+ return s.Reverse();
+ else
+ return s;
+}
+
+
+static void MoveDiagonal( SEG& aDiagonal, const SHAPE_LINE_CHAIN& aVertices, int aClearance )
+{
+ int dist;
+
+ aVertices.NearestPoint( aDiagonal, dist );
+ dist -= HULL_MARGIN;
+ VECTOR2I moveBy = ( aDiagonal.A - aDiagonal.B ).Perpendicular().Resize( dist - aClearance );
+ aDiagonal.A += moveBy;
+ aDiagonal.B += moveBy;
+}
+
+
+const SHAPE_LINE_CHAIN ConvexHull( const SHAPE_CONVEX& convex, int aClearance )
+{
+ // this defines the horizontal and vertical lines in the hull octagon
+ BOX2I box = convex.BBox( aClearance + HULL_MARGIN );
+ box.Normalize();
+
+ SEG topline = SEG( VECTOR2I( box.GetX(), box.GetY() + box.GetHeight() ),
+ VECTOR2I( box.GetX() + box.GetWidth(), box.GetY() + box.GetHeight() ) );
+ SEG rightline = SEG( VECTOR2I( box.GetX() + box.GetWidth(), box.GetY() + box.GetHeight() ),
+ VECTOR2I( box.GetX() + box.GetWidth(), box.GetY() ) );
+ SEG bottomline = SEG( VECTOR2I( box.GetX() + box.GetWidth(), box.GetY() ),
+ box.GetOrigin() );
+ SEG leftline = SEG( box.GetOrigin(), VECTOR2I( box.GetX(), box.GetY() + box.GetHeight() ) );
+
+ const SHAPE_LINE_CHAIN& vertices = convex.Vertices();
+
+ // top right diagonal
+ VECTOR2I corner = box.GetOrigin() + box.GetSize();
+ SEG toprightline = SEG( corner,
+ corner + VECTOR2I( box.GetHeight(), -box.GetHeight() ) );
+ MoveDiagonal( toprightline, vertices, aClearance );
+
+ // bottom right diagonal
+ corner = box.GetOrigin() + VECTOR2I( box.GetWidth(), 0 );
+ SEG bottomrightline = SEG( corner + VECTOR2I( box.GetHeight(), box.GetHeight() ),
+ corner );
+ MoveDiagonal( bottomrightline, vertices, aClearance );
+
+ // bottom left diagonal
+ corner = box.GetOrigin();
+ SEG bottomleftline = SEG( corner,
+ corner + VECTOR2I( -box.GetHeight(), box.GetHeight() ) );
+ MoveDiagonal( bottomleftline, vertices, aClearance );
+
+ // top left diagonal
+ corner = box.GetOrigin() + VECTOR2I( 0, box.GetHeight() );
+ SEG topleftline = SEG( corner + VECTOR2I( -box.GetHeight(), -box.GetHeight() ),
+ corner );
+ MoveDiagonal( topleftline, vertices, aClearance );
+
+ SHAPE_LINE_CHAIN octagon;
+ octagon.SetClosed( true );
+
+ octagon.Append( leftline.IntersectLines( bottomleftline ).get() );
+ octagon.Append( bottomline.IntersectLines( bottomleftline ).get() );
+ octagon.Append( bottomline.IntersectLines( bottomrightline ).get() );
+ octagon.Append( rightline.IntersectLines( bottomrightline ).get() );
+ octagon.Append( rightline.IntersectLines( toprightline ).get() );
+ octagon.Append( topline.IntersectLines( toprightline ).get() );
+ octagon.Append( topline.IntersectLines( topleftline ).get() );
+ octagon.Append( leftline.IntersectLines( topleftline ).get() );
+
+ return octagon;
+}
+
+
+SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg )
+{
+ SHAPE_RECT r;
+
+ VECTOR2I delta( aSeg.GetWidth() / 2, aSeg.GetWidth() / 2 );
+ VECTOR2I p0( aSeg.GetSeg().A - delta );
+ VECTOR2I p1( aSeg.GetSeg().B + delta );
+
+ return SHAPE_RECT( std::min( p0.x, p1.x ), std::min( p0.y, p1.y ),
+ std::abs( p1.x - p0.x ), std::abs( p1.y - p0.y ) );
+}
+
+
+void DrawDebugPoint( VECTOR2I aP, int aColor )
+{
+ SHAPE_LINE_CHAIN l;
+
+ l.Append( aP - VECTOR2I( -50000, -50000 ) );
+ l.Append( aP + VECTOR2I( -50000, -50000 ) );
+
+ PNS_ROUTER::GetInstance()->DisplayDebugLine ( l, aColor, 10000 );
+
+ l.Clear();
+ l.Append( aP - VECTOR2I( 50000, -50000 ) );
+ l.Append( aP + VECTOR2I( 50000, -50000 ) );
+
+ PNS_ROUTER::GetInstance()->DisplayDebugLine( l, aColor, 10000 );
+}
+
+
+void DrawDebugBox( BOX2I aB, int aColor )
+{
+ SHAPE_LINE_CHAIN l;
+
+ VECTOR2I o = aB.GetOrigin();
+ VECTOR2I s = aB.GetSize();
+
+ l.Append( o );
+ l.Append( o.x + s.x, o.y );
+ l.Append( o.x + s.x, o.y + s.y );
+ l.Append( o.x, o.y + s.y );
+ l.Append( o );
+
+ PNS_ROUTER::GetInstance()->DisplayDebugLine( l, aColor, 10000 );
+}
+
+
+void DrawDebugSeg( SEG aS, int aColor )
+{
+ SHAPE_LINE_CHAIN l;
+
+ l.Append( aS.A );
+ l.Append( aS.B );
+
+ PNS_ROUTER::GetInstance()->DisplayDebugLine( l, aColor, 10000 );
+}
+
+
+void DrawDebugDirs( VECTOR2D aP, int aMask, int aColor )
+{
+ BOX2I b( aP - VECTOR2I( 10000, 10000 ), VECTOR2I( 20000, 20000 ) );
+
+ DrawDebugBox( b, aColor );
+ for( int i = 0; i < 8; i++ )
+ {
+ if( ( 1 << i ) & aMask )
+ {
+ VECTOR2I v = DIRECTION_45( ( DIRECTION_45::Directions ) i ).ToVector() * 100000;
+ DrawDebugSeg( SEG( aP, aP + v ), aColor );
+ }
+ }
+}
+
+
+OPT_BOX2I ChangedArea( const PNS_ITEM* aItemA, const PNS_ITEM* aItemB )
+{
+ if( aItemA->OfKind( PNS_ITEM::VIA ) && aItemB->OfKind( PNS_ITEM::VIA ) )
+ {
+ const PNS_VIA* va = static_cast<const PNS_VIA*>( aItemA );
+ const PNS_VIA* vb = static_cast<const PNS_VIA*>( aItemB );
+
+ return va->ChangedArea( vb );
+ }
+ else if( aItemA->OfKind( PNS_ITEM::LINE ) && aItemB->OfKind( PNS_ITEM::LINE ) )
+ {
+ const PNS_LINE* la = static_cast<const PNS_LINE*> ( aItemA );
+ const PNS_LINE* lb = static_cast<const PNS_LINE*> ( aItemB );
+
+ return la->ChangedArea( lb );
+ }
+
+ return OPT_BOX2I();
+}
diff --git a/pcbnew/router/pns_utils.h b/pcbnew/router/pns_utils.h
new file mode 100644
index 0000000..bc300a9
--- /dev/null
+++ b/pcbnew/router/pns_utils.h
@@ -0,0 +1,62 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_UTILS_H
+#define __PNS_UTILS_H
+
+#include <math/vector2d.h>
+#include <math/box2.h>
+#include <geometry/shape_line_chain.h>
+#include <geometry/shape_segment.h>
+#include <geometry/shape_rect.h>
+#include <geometry/shape_convex.h>
+
+#define HULL_MARGIN 10
+
+class PNS_ITEM;
+
+/** Various utility functions */
+
+const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0, const VECTOR2I& aSize,
+ int aClearance, int aChamfer );
+
+const SHAPE_LINE_CHAIN SegmentHull( const SHAPE_SEGMENT& aSeg, int aClearance,
+ int aWalkaroundThickness );
+
+/**
+ * Function ConvexHull()
+ *
+ * Creates an octagonal hull around a convex polygon.
+ * @param convex The convex polygon.
+ * @param clearance The minimum distance between polygon and hull.
+ * @return A closed line chain describing the octagon.
+ */
+const SHAPE_LINE_CHAIN ConvexHull( const SHAPE_CONVEX& convex, int aClearance );
+
+SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg );
+
+void DrawDebugPoint( VECTOR2I aP, int aColor );
+void DrawDebugBox( BOX2I aB, int aColor );
+void DrawDebugSeg( SEG aS, int aColor );
+void DrawDebugDirs( VECTOR2D aP, int aMask, int aColor );
+
+OPT_BOX2I ChangedArea( const PNS_ITEM* aItemA, const PNS_ITEM* aItemB );
+
+#endif // __PNS_UTILS_H
diff --git a/pcbnew/router/pns_via.cpp b/pcbnew/router/pns_via.cpp
new file mode 100644
index 0000000..e090139
--- /dev/null
+++ b/pcbnew/router/pns_via.cpp
@@ -0,0 +1,109 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pns_via.h"
+#include "pns_node.h"
+#include "pns_utils.h"
+#include "pns_router.h"
+
+#include <geometry/shape_rect.h>
+
+bool PNS_VIA::PushoutForce( PNS_NODE* aNode, const VECTOR2I& aDirection, VECTOR2I& aForce,
+ bool aSolidsOnly, int aMaxIterations )
+{
+ int iter = 0;
+ PNS_VIA mv( *this );
+ VECTOR2I force, totalForce, force2;
+
+ while( iter < aMaxIterations )
+ {
+ PNS_NODE::OPT_OBSTACLE obs = aNode->CheckColliding( &mv,
+ aSolidsOnly ? PNS_ITEM::SOLID : PNS_ITEM::ANY );
+
+ if( !obs )
+ break;
+
+ int clearance = aNode->GetClearance( obs->m_item, &mv );
+
+ if( iter > aMaxIterations / 2 )
+ {
+ VECTOR2I l = aDirection.Resize( m_diameter / 2 );
+ totalForce += l;
+ mv.SetPos( mv.Pos() + l );
+ }
+
+ bool col = CollideShapes( obs->m_item->Shape(), mv.Shape(), clearance, true, force2 );
+
+ if( col ) {
+ totalForce += force2;
+ mv.SetPos( mv.Pos() + force2 );
+ }
+
+ iter++;
+ }
+
+ if( iter == aMaxIterations )
+ return false;
+
+ aForce = totalForce;
+
+ return true;
+}
+
+
+const SHAPE_LINE_CHAIN PNS_VIA::Hull( int aClearance, int aWalkaroundThickness ) const
+{
+ int cl = ( aClearance + aWalkaroundThickness / 2 );
+
+ return OctagonalHull( m_pos -
+ VECTOR2I( m_diameter / 2, m_diameter / 2 ), VECTOR2I( m_diameter, m_diameter ),
+ cl + 1, ( 2 * cl + m_diameter ) * 0.26 );
+}
+
+
+PNS_VIA* PNS_VIA::Clone() const
+{
+ PNS_VIA* v = new PNS_VIA();
+
+ v->SetNet( Net() );
+ v->SetLayers( Layers() );
+ v->m_pos = m_pos;
+ v->m_diameter = m_diameter;
+ v->m_drill = m_drill;
+ v->m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 );
+ v->m_rank = m_rank;
+ v->m_marker = m_marker;
+ v->m_viaType = m_viaType;
+
+ return v;
+}
+
+
+OPT_BOX2I PNS_VIA::ChangedArea( const PNS_VIA* aOther ) const
+{
+ if ( aOther->Pos() != Pos() )
+ {
+ BOX2I tmp = Shape()->BBox();
+ tmp.Merge( aOther->Shape()->BBox() );
+ return tmp;
+ }
+
+ return OPT_BOX2I();
+}
diff --git a/pcbnew/router/pns_via.h b/pcbnew/router/pns_via.h
new file mode 100644
index 0000000..97c9954
--- /dev/null
+++ b/pcbnew/router/pns_via.h
@@ -0,0 +1,162 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_VIA_H
+#define __PNS_VIA_H
+
+#include <geometry/shape_line_chain.h>
+#include <geometry/shape_circle.h>
+
+#include "../class_track.h"
+
+#include "pns_item.h"
+
+class PNS_NODE;
+
+class PNS_VIA : public PNS_ITEM
+{
+public:
+ PNS_VIA() :
+ PNS_ITEM( VIA )
+ {
+ m_diameter = 2; // Dummy value
+ m_drill = 0;
+ m_viaType = VIA_THROUGH;
+ }
+
+ PNS_VIA( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers,
+ int aDiameter, int aDrill, int aNet = -1, VIATYPE_T aViaType = VIA_THROUGH ) :
+ PNS_ITEM( VIA )
+ {
+ SetNet( aNet );
+ SetLayers( aLayers );
+ m_pos = aPos;
+ m_diameter = aDiameter;
+ m_drill = aDrill;
+ m_shape = SHAPE_CIRCLE( aPos, aDiameter / 2 );
+ m_viaType = aViaType;
+
+ //If we're a through-board via, use all layers regardless of the set passed
+ if( aViaType == VIA_THROUGH )
+ {
+ PNS_LAYERSET allLayers( 0, MAX_CU_LAYERS - 1 );
+ SetLayers( allLayers );
+ }
+ }
+
+
+ PNS_VIA( const PNS_VIA& aB ) :
+ PNS_ITEM( VIA )
+ {
+ SetNet( aB.Net() );
+ SetLayers( aB.Layers() );
+ m_pos = aB.m_pos;
+ m_diameter = aB.m_diameter;
+ m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 );
+ m_marker = aB.m_marker;
+ m_rank = aB.m_rank;
+ m_drill = aB.m_drill;
+ m_viaType = aB.m_viaType;
+ }
+
+ static inline bool ClassOf( const PNS_ITEM* aItem )
+ {
+ return aItem && VIA == aItem->Kind();
+ }
+
+
+ const VECTOR2I& Pos() const
+ {
+ return m_pos;
+ }
+
+ void SetPos( const VECTOR2I& aPos )
+ {
+ m_pos = aPos;
+ m_shape.SetCenter( aPos );
+ }
+
+ VIATYPE_T ViaType() const
+ {
+ return m_viaType;
+ }
+
+ void SetViaType( VIATYPE_T aViaType )
+ {
+ m_viaType = aViaType;
+ }
+
+ int Diameter() const
+ {
+ return m_diameter;
+ }
+
+ void SetDiameter( int aDiameter )
+ {
+ m_diameter = aDiameter;
+ m_shape.SetRadius( m_diameter / 2 );
+ }
+
+ int Drill() const
+ {
+ return m_drill;
+ }
+
+ void SetDrill( int aDrill )
+ {
+ m_drill = aDrill;
+ }
+
+ bool PushoutForce( PNS_NODE* aNode,
+ const VECTOR2I& aDirection,
+ VECTOR2I& aForce,
+ bool aSolidsOnly = true,
+ int aMaxIterations = 10 );
+
+ const SHAPE* Shape() const
+ {
+ return &m_shape;
+ }
+
+ PNS_VIA* Clone() const;
+
+ const SHAPE_LINE_CHAIN Hull( int aClearance = 0, int aWalkaroundThickness = 0 ) const;
+
+ virtual VECTOR2I Anchor( int n ) const
+ {
+ return m_pos;
+ }
+
+ virtual int AnchorCount() const
+ {
+ return 1;
+ }
+
+ OPT_BOX2I ChangedArea( const PNS_VIA* aOther ) const;
+
+private:
+ int m_diameter;
+ int m_drill;
+ VECTOR2I m_pos;
+ SHAPE_CIRCLE m_shape;
+ VIATYPE_T m_viaType;
+};
+
+#endif
diff --git a/pcbnew/router/pns_walkaround.cpp b/pcbnew/router/pns_walkaround.cpp
new file mode 100644
index 0000000..c7e7e19
--- /dev/null
+++ b/pcbnew/router/pns_walkaround.cpp
@@ -0,0 +1,273 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/foreach.hpp>
+#include <boost/optional.hpp>
+
+#include <geometry/shape_line_chain.h>
+
+#include "pns_walkaround.h"
+#include "pns_optimizer.h"
+#include "pns_utils.h"
+#include "pns_router.h"
+using boost::optional;
+
+void PNS_WALKAROUND::start( const PNS_LINE& aInitialPath )
+{
+ m_iteration = 0;
+ m_iterationLimit = 50;
+}
+
+
+PNS_NODE::OPT_OBSTACLE PNS_WALKAROUND::nearestObstacle( const PNS_LINE& aPath )
+{
+ PNS_NODE::OPT_OBSTACLE obs = m_world->NearestObstacle( &aPath, m_itemMask, m_restrictedSet.empty() ? NULL : &m_restrictedSet );
+
+ if( m_restrictedSet.empty() )
+ return obs;
+
+ else if( obs && m_restrictedSet.find ( obs->m_item ) != m_restrictedSet.end() )
+ return obs;
+
+ return PNS_NODE::OPT_OBSTACLE();
+}
+
+
+PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
+ bool aWindingDirection )
+{
+ optional<PNS_OBSTACLE>& current_obs =
+ aWindingDirection ? m_currentObstacle[0] : m_currentObstacle[1];
+
+ bool& prev_recursive = aWindingDirection ? m_recursiveCollision[0] : m_recursiveCollision[1];
+
+ if( !current_obs )
+ return DONE;
+
+ SHAPE_LINE_CHAIN path_pre[2], path_walk[2], path_post[2];
+
+ VECTOR2I last = aPath.CPoint( -1 );
+
+ if( ( current_obs->m_hull ).PointInside( last ) || ( current_obs->m_hull ).PointOnEdge( last ) )
+ {
+ m_recursiveBlockageCount++;
+
+ if( m_recursiveBlockageCount < 3 )
+ aPath.Line().Append( current_obs->m_hull.NearestPoint( last ) );
+ else
+ {
+ aPath = aPath.ClipToNearestObstacle( m_world );
+ return DONE;
+ }
+ }
+
+ aPath.Walkaround( current_obs->m_hull, path_pre[0], path_walk[0],
+ path_post[0], aWindingDirection );
+ aPath.Walkaround( current_obs->m_hull, path_pre[1], path_walk[1],
+ path_post[1], !aWindingDirection );
+
+#ifdef DEBUG
+ m_logger.NewGroup( aWindingDirection ? "walk-cw" : "walk-ccw", m_iteration );
+ m_logger.Log( &path_walk[0], 0, "path-walk" );
+ m_logger.Log( &path_pre[0], 1, "path-pre" );
+ m_logger.Log( &path_post[0], 4, "path-post" );
+ m_logger.Log( &current_obs->m_hull, 2, "hull" );
+ m_logger.Log( current_obs->m_item, 3, "item" );
+#endif
+
+ int len_pre = path_walk[0].Length();
+ int len_alt = path_walk[1].Length();
+
+ PNS_LINE walk_path( aPath, path_walk[1] );
+
+ bool alt_collides = static_cast<bool>( m_world->CheckColliding( &walk_path, m_itemMask ) );
+
+ SHAPE_LINE_CHAIN pnew;
+
+ if( !m_forceLongerPath && len_alt < len_pre && !alt_collides && !prev_recursive )
+ {
+ pnew = path_pre[1];
+ pnew.Append( path_walk[1] );
+ pnew.Append( path_post[1] );
+
+ if( !path_post[1].PointCount() || !path_walk[1].PointCount() )
+ current_obs = nearestObstacle( PNS_LINE( aPath, path_pre[1] ) );
+ else
+ current_obs = nearestObstacle( PNS_LINE( aPath, path_post[1] ) );
+ prev_recursive = false;
+ }
+ else
+ {
+ pnew = path_pre[0];
+ pnew.Append( path_walk[0] );
+ pnew.Append( path_post[0] );
+
+ if( !path_post[0].PointCount() || !path_walk[0].PointCount() )
+ current_obs = nearestObstacle( PNS_LINE( aPath, path_pre[0] ) );
+ else
+ current_obs = nearestObstacle( PNS_LINE( aPath, path_walk[0] ) );
+
+ if( !current_obs )
+ {
+ prev_recursive = false;
+ current_obs = nearestObstacle( PNS_LINE( aPath, path_post[0] ) );
+ }
+ else
+ prev_recursive = true;
+ }
+
+ pnew.Simplify();
+ aPath.SetShape( pnew );
+
+ return IN_PROGRESS;
+}
+
+
+PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::Route( const PNS_LINE& aInitialPath,
+ PNS_LINE& aWalkPath, bool aOptimize )
+{
+ PNS_LINE path_cw( aInitialPath ), path_ccw( aInitialPath );
+ WALKAROUND_STATUS s_cw = IN_PROGRESS, s_ccw = IN_PROGRESS;
+ SHAPE_LINE_CHAIN best_path;
+
+ // special case for via-in-the-middle-of-track placement
+ if( aInitialPath.PointCount() <= 1 )
+ {
+ if( aInitialPath.EndsWithVia() && m_world->CheckColliding( &aInitialPath.Via(), m_itemMask ) )
+ return STUCK;
+
+ aWalkPath = aInitialPath;
+ return DONE;
+ }
+
+ start( aInitialPath );
+
+ m_currentObstacle[0] = m_currentObstacle[1] = nearestObstacle( aInitialPath );
+ m_recursiveBlockageCount = 0;
+
+ aWalkPath = aInitialPath;
+
+ if( m_forceWinding )
+ {
+ s_cw = m_forceCw ? IN_PROGRESS : STUCK;
+ s_ccw = m_forceCw ? STUCK : IN_PROGRESS;
+ m_forceSingleDirection = true;
+ } else {
+ m_forceSingleDirection = false;
+ }
+
+ while( m_iteration < m_iterationLimit )
+ {
+ if( s_cw != STUCK )
+ s_cw = singleStep( path_cw, true );
+
+ if( s_ccw != STUCK )
+ s_ccw = singleStep( path_ccw, false );
+
+ if( ( s_cw == DONE && s_ccw == DONE ) || ( s_cw == STUCK && s_ccw == STUCK ) )
+ {
+ int len_cw = path_cw.CLine().Length();
+ int len_ccw = path_ccw.CLine().Length();
+
+ if( m_forceLongerPath )
+ aWalkPath = ( len_cw > len_ccw ? path_cw : path_ccw );
+ else
+ aWalkPath = ( len_cw < len_ccw ? path_cw : path_ccw );
+
+ break;
+ }
+ else if( s_cw == DONE && !m_forceLongerPath )
+ {
+ aWalkPath = path_cw;
+ break;
+ }
+ else if( s_ccw == DONE && !m_forceLongerPath )
+ {
+ aWalkPath = path_ccw;
+ break;
+ }
+
+ m_iteration++;
+ }
+
+ if( m_iteration == m_iterationLimit )
+ {
+ int len_cw = path_cw.CLine().Length();
+ int len_ccw = path_ccw.CLine().Length();
+
+ if( m_forceLongerPath )
+ aWalkPath = ( len_cw > len_ccw ? path_cw : path_ccw );
+ else
+ aWalkPath = ( len_cw < len_ccw ? path_cw : path_ccw );
+ }
+
+ if( m_cursorApproachMode )
+ {
+ // int len_cw = path_cw.GetCLine().Length();
+ // int len_ccw = path_ccw.GetCLine().Length();
+ bool found = false;
+
+ SHAPE_LINE_CHAIN l = aWalkPath.CLine();
+
+ for( int i = 0; i < l.SegmentCount(); i++ )
+ {
+ const SEG s = l.Segment( i );
+
+ VECTOR2I nearest = s.NearestPoint( m_cursorPos );
+ VECTOR2I::extended_type dist_a = ( s.A - m_cursorPos ).SquaredEuclideanNorm();
+ VECTOR2I::extended_type dist_b = ( s.B - m_cursorPos ).SquaredEuclideanNorm();
+ VECTOR2I::extended_type dist_n = ( nearest - m_cursorPos ).SquaredEuclideanNorm();
+
+ if( dist_n <= dist_a && dist_n < dist_b )
+ {
+ l.Remove( i + 1, -1 );
+ l.Append( nearest );
+ l.Simplify();
+ found = true;
+ break;
+ }
+ }
+
+ if( found )
+ {
+ aWalkPath = aInitialPath;
+ aWalkPath.SetShape( l );
+ }
+ }
+
+ aWalkPath.Line().Simplify();
+
+ if( aWalkPath.SegmentCount() < 1 )
+ return STUCK;
+ if( aWalkPath.CPoint( -1 ) != aInitialPath.CPoint( -1 ) )
+ return STUCK;
+ if( aWalkPath.CPoint( 0 ) != aInitialPath.CPoint( 0 ) )
+ return STUCK;
+
+ WALKAROUND_STATUS st = s_ccw == DONE || s_cw == DONE ? DONE : STUCK;
+
+ if( st == DONE )
+ {
+ if( aOptimize )
+ PNS_OPTIMIZER::Optimize( &aWalkPath, PNS_OPTIMIZER::MERGE_OBTUSE, m_world );
+ }
+
+ return st;
+}
diff --git a/pcbnew/router/pns_walkaround.h b/pcbnew/router/pns_walkaround.h
new file mode 100644
index 0000000..f143b46
--- /dev/null
+++ b/pcbnew/router/pns_walkaround.h
@@ -0,0 +1,149 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PNS_WALKAROUND_H
+#define __PNS_WALKAROUND_H
+
+#include <set>
+
+#include "pns_line.h"
+#include "pns_node.h"
+#include "pns_router.h"
+#include "pns_logger.h"
+#include "pns_algo_base.h"
+
+class PNS_WALKAROUND : public PNS_ALGO_BASE
+{
+ static const int DefaultIterationLimit = 50;
+
+public:
+ PNS_WALKAROUND( PNS_NODE* aWorld, PNS_ROUTER* aRouter ) :
+ PNS_ALGO_BASE ( aRouter ),
+ m_world( aWorld ),
+ m_iterationLimit( DefaultIterationLimit )
+ {
+ m_forceSingleDirection = false;
+ m_forceLongerPath = false;
+ m_forceWinding = false;
+ m_cursorApproachMode = false;
+ m_itemMask = PNS_ITEM::ANY;
+
+ // Initialize other members, to avoid uninitialized variables.
+ m_recursiveBlockageCount = 0;
+ m_recursiveCollision[0] = m_recursiveCollision[1] = false;
+ m_iteration = 0;
+ m_forceCw = false;
+ }
+
+ ~PNS_WALKAROUND() {};
+
+ enum WALKAROUND_STATUS
+ {
+ IN_PROGRESS = 0,
+ DONE,
+ STUCK
+ };
+
+ void SetWorld( PNS_NODE* aNode )
+ {
+ m_world = aNode;
+ }
+
+ void SetIterationLimit( const int aIterLimit )
+ {
+ m_iterationLimit = aIterLimit;
+ }
+
+ void SetSolidsOnly( bool aSolidsOnly )
+ {
+ if( aSolidsOnly )
+ m_itemMask = PNS_ITEM::SOLID;
+ else
+ m_itemMask = PNS_ITEM::ANY;
+ }
+
+ void SetItemMask( int aMask )
+ {
+ m_itemMask = aMask;
+ }
+
+ void SetSingleDirection( bool aForceSingleDirection )
+ {
+ m_forceSingleDirection = aForceSingleDirection;
+ m_forceLongerPath = aForceSingleDirection;
+ }
+
+ void SetSingleDirection2( bool aForceSingleDirection )
+ {
+ m_forceSingleDirection = aForceSingleDirection;
+ }
+
+ void SetApproachCursor( bool aEnabled, const VECTOR2I& aPos )
+ {
+ m_cursorPos = aPos;
+ m_cursorApproachMode = aEnabled;
+ }
+
+ void SetForceWinding ( bool aEnabled, bool aCw )
+ {
+ m_forceCw = aCw;
+ m_forceWinding = aEnabled;
+ }
+
+ void RestrictToSet( bool aEnabled, const std::set<PNS_ITEM*>& aSet )
+ {
+ if( aEnabled )
+ m_restrictedSet = aSet;
+ else
+ m_restrictedSet.clear();
+ }
+
+ WALKAROUND_STATUS Route( const PNS_LINE& aInitialPath, PNS_LINE& aWalkPath,
+ bool aOptimize = true );
+
+ virtual PNS_LOGGER* Logger()
+ {
+ return &m_logger;
+ }
+
+private:
+ void start( const PNS_LINE& aInitialPath );
+
+ WALKAROUND_STATUS singleStep( PNS_LINE& aPath, bool aWindingDirection );
+ PNS_NODE::OPT_OBSTACLE nearestObstacle( const PNS_LINE& aPath );
+
+ PNS_NODE* m_world;
+
+ int m_recursiveBlockageCount;
+ int m_iteration;
+ int m_iterationLimit;
+ int m_itemMask;
+ bool m_forceSingleDirection, m_forceLongerPath;
+ bool m_cursorApproachMode;
+ bool m_forceWinding;
+ bool m_forceCw;
+ VECTOR2I m_cursorPos;
+ PNS_NODE::OPT_OBSTACLE m_currentObstacle[2];
+ bool m_recursiveCollision[2];
+ PNS_LOGGER m_logger;
+ std::set<PNS_ITEM*> m_restrictedSet;
+};
+
+#endif // __PNS_WALKAROUND_H
diff --git a/pcbnew/router/range.h b/pcbnew/router/range.h
new file mode 100644
index 0000000..5b47c74
--- /dev/null
+++ b/pcbnew/router/range.h
@@ -0,0 +1,93 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __RANGE_H
+#define __RANGE_H
+
+template<class T>
+class RANGE
+{
+public:
+ RANGE( T aMin, T aMax ) :
+ m_min( aMin ),
+ m_max( aMax ),
+ m_defined( true ) {}
+
+ RANGE():
+ m_defined( false ) {}
+
+ T MinV() const
+ {
+ return m_min;
+ }
+
+ T MaxV() const
+ {
+ return m_max;
+ }
+
+ void Set( T aMin, T aMax ) const
+ {
+ m_max = aMax;
+ m_min = aMin;
+ }
+
+ void Grow( T aValue )
+ {
+ if( !m_defined )
+ {
+ m_min = aValue;
+ m_max = aValue;
+ m_defined = true;
+ }
+ else
+ {
+ m_min = std::min( m_min, aValue );
+ m_max = std::max( m_max, aValue );
+ }
+ }
+
+ bool Inside( const T& aValue ) const
+ {
+ if( !m_defined )
+ return true;
+
+ return aValue >= m_min && aValue <= m_max;
+ }
+
+ bool Overlaps ( const RANGE<T>& aOther ) const
+ {
+ if( !m_defined || !aOther.m_defined )
+ return true;
+
+ return m_max >= aOther.m_min && m_min <= aOther.m_max;
+ }
+
+ bool Defined() const
+ {
+ return m_defined;
+ }
+
+private:
+ T m_min, m_max;
+ bool m_defined;
+};
+
+#endif
diff --git a/pcbnew/router/ranged_num.h b/pcbnew/router/ranged_num.h
new file mode 100644
index 0000000..5eadaf6
--- /dev/null
+++ b/pcbnew/router/ranged_num.h
@@ -0,0 +1,52 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2015 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __RANGED_NUM_H
+#define __RANGED_NUM_H
+
+template <class T> class RANGED_NUM {
+ public:
+ RANGED_NUM( T aValue = 0, T aTolerancePlus = 0, T aToleranceMinus = 0 ) :
+ m_value( aValue ),
+ m_tolerancePlus( aTolerancePlus ),
+ m_toleranceMinus( aToleranceMinus )
+ {}
+
+ operator T()
+ {
+ return m_value;
+ }
+
+ RANGED_NUM& operator=( const T aValue )
+ {
+ m_value = aValue;
+ return *this;
+ }
+
+ bool Matches( const T& aOther ) const
+ {
+ return ( aOther >= m_value - m_toleranceMinus && aOther <= m_value + m_tolerancePlus );
+ }
+
+ private:
+ T m_value, m_tolerancePlus, m_toleranceMinus;
+};
+
+#endif
diff --git a/pcbnew/router/router_preview_item.cpp b/pcbnew/router/router_preview_item.cpp
new file mode 100644
index 0000000..c490ae4
--- /dev/null
+++ b/pcbnew/router/router_preview_item.cpp
@@ -0,0 +1,343 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <deque>
+#include <gal/color4d.h>
+
+#include <geometry/shape_rect.h>
+#include <geometry/shape_convex.h>
+
+#include "class_track.h"
+#include <pcb_painter.h>
+#include <colors.h>
+
+#include "router_preview_item.h"
+
+#include "pns_line.h"
+#include "pns_segment.h"
+#include "pns_via.h"
+
+using namespace KIGFX;
+
+ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const PNS_ITEM* aItem, VIEW_GROUP* aParent ) :
+ EDA_ITEM( NOT_USED )
+{
+ m_parent = aParent;
+
+ m_shape = NULL;
+ m_clearance = -1;
+ m_originLayer = m_layer = ITEM_GAL_LAYER( GP_OVERLAY );
+
+ // initialize variables, overwritten by Update( aItem ), if aItem != NULL
+ m_router = NULL;
+ m_type = PR_SHAPE;
+ m_style = 0;
+ m_width = 0;
+ m_depth = 0;
+
+ if( aItem )
+ Update( aItem );
+}
+
+
+ROUTER_PREVIEW_ITEM::~ROUTER_PREVIEW_ITEM()
+{
+ delete m_shape;
+}
+
+
+void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem )
+{
+ m_originLayer = aItem->Layers().Start();
+
+ if( aItem->OfKind( PNS_ITEM::LINE ) )
+ {
+ const PNS_LINE* l = static_cast<const PNS_LINE*>( aItem );
+
+ if( !l->SegmentCount() )
+ return;
+ }
+
+ assert( m_originLayer >= 0 );
+
+ m_layer = m_originLayer;
+ m_color = getLayerColor( m_originLayer );
+ m_color.a = 0.8;
+ m_depth = BaseOverlayDepth - aItem->Layers().Start();
+ m_shape = aItem->Shape()->Clone();
+
+ switch( aItem->Kind() )
+ {
+ case PNS_ITEM::LINE:
+ m_type = PR_SHAPE;
+ m_width = ( (PNS_LINE*) aItem )->Width();
+ break;
+
+ case PNS_ITEM::SEGMENT:
+ {
+ PNS_SEGMENT* seg = (PNS_SEGMENT*) aItem;
+ m_type = PR_SHAPE;
+ m_width = seg->Width();
+ break;
+ }
+
+ case PNS_ITEM::VIA:
+ m_originLayer = m_layer = ITEM_GAL_LAYER( VIAS_VISIBLE );
+ m_type = PR_SHAPE;
+ m_width = 0;
+ m_color = COLOR4D( 0.7, 0.7, 0.7, 0.8 );
+ m_depth = ViaOverlayDepth;
+ break;
+
+ case PNS_ITEM::SOLID:
+ m_type = PR_SHAPE;
+ m_width = 0;
+ break;
+
+ default:
+ break;
+ }
+
+ if( aItem->Marker() & MK_VIOLATION )
+ m_color = COLOR4D( 0, 1, 0, 1 );
+
+ if( aItem->Marker() & MK_HEAD )
+ m_color.Brighten( 0.7 );
+
+ ViewSetVisible( true );
+ ViewUpdate( GEOMETRY | APPEARANCE );
+}
+
+
+const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const
+{
+ BOX2I bbox;
+
+ switch( m_type )
+ {
+ case PR_SHAPE:
+ bbox = m_shape->BBox();
+ bbox.Inflate( m_width / 2 );
+ return bbox;
+
+ case PR_POINT:
+ bbox = BOX2I ( m_pos - VECTOR2I( 100000, 100000 ), VECTOR2I( 200000, 200000 ) );
+ return bbox;
+
+ default:
+ break;
+ }
+
+ return bbox;
+}
+
+
+void ROUTER_PREVIEW_ITEM::drawLineChain( const SHAPE_LINE_CHAIN& aL, KIGFX::GAL* aGal ) const
+{
+ for( int s = 0; s < aL.SegmentCount(); s++ )
+ aGal->DrawLine( aL.CSegment( s ).A, aL.CSegment( s ).B );
+
+ if( aL.IsClosed() )
+ aGal->DrawLine( aL.CSegment( -1 ).B, aL.CSegment( 0 ).A );
+}
+
+
+void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
+{
+ //col.Brighten(0.7);
+ aGal->SetLayerDepth( m_depth );
+
+ if( m_type == PR_SHAPE )
+ {
+ if( !m_shape )
+ return;
+
+ aGal->SetLineWidth( m_width );
+ aGal->SetStrokeColor( m_color );
+ aGal->SetFillColor( m_color );
+ aGal->SetIsStroke( m_width ? true : false );
+ aGal->SetIsFill( true );
+
+ switch( m_shape->Type() )
+ {
+ case SH_LINE_CHAIN:
+ {
+ const SHAPE_LINE_CHAIN* l = (const SHAPE_LINE_CHAIN*) m_shape;
+ drawLineChain( *l, aGal );
+ break;
+ }
+
+ case SH_SEGMENT:
+ {
+ const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) m_shape;
+ aGal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() );
+
+ if( m_clearance > 0 )
+ {
+ aGal->SetLayerDepth( ClearanceOverlayDepth );
+ aGal->SetStrokeColor( COLOR4D( DARKDARKGRAY ) );
+ aGal->SetFillColor( COLOR4D( DARKDARKGRAY ) );
+ aGal->DrawSegment( s->GetSeg().A, s->GetSeg().B, s->GetWidth() + 2 * m_clearance );
+ }
+
+ break;
+ }
+
+ case SH_CIRCLE:
+ {
+ const SHAPE_CIRCLE* c = (const SHAPE_CIRCLE*) m_shape;
+ aGal->DrawCircle( c->GetCenter(), c->GetRadius() );
+
+ if( m_clearance > 0 )
+ {
+ aGal->SetLayerDepth( ClearanceOverlayDepth );
+ aGal->SetFillColor( COLOR4D( DARKDARKGRAY ) );
+ aGal->SetIsStroke( false );
+ aGal->DrawCircle( c->GetCenter(), c->GetRadius() + m_clearance );
+ }
+
+ break;
+ }
+
+ case SH_RECT:
+ {
+ const SHAPE_RECT* r = (const SHAPE_RECT*) m_shape;
+ aGal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
+
+ if( m_clearance > 0 )
+ {
+ aGal->SetLayerDepth( ClearanceOverlayDepth );
+ VECTOR2I p0( r->GetPosition() ), s( r->GetSize() );
+ aGal->SetStrokeColor( COLOR4D( DARKDARKGRAY ) );
+ aGal->SetIsStroke( true );
+ aGal->SetLineWidth( 2 * m_clearance );
+ aGal->DrawLine( p0, VECTOR2I( p0.x + s.x, p0.y ) );
+ aGal->DrawLine( p0, VECTOR2I( p0.x, p0.y + s.y ) );
+ aGal->DrawLine( p0 + s , VECTOR2I( p0.x + s.x, p0.y ) );
+ aGal->DrawLine( p0 + s, VECTOR2I( p0.x, p0.y + s.y ) );
+ }
+
+ break;
+ }
+
+ case SH_CONVEX:
+ {
+ const SHAPE_CONVEX* c = (const SHAPE_CONVEX*) m_shape;
+ std::deque<VECTOR2D> polygon = std::deque<VECTOR2D>();
+ for( int i = 0; i < c->PointCount(); i++ )
+ {
+ polygon.push_back( c->CDPoint( i ) );
+ }
+ aGal->DrawPolygon( polygon );
+
+ if( m_clearance > 0 )
+ {
+ aGal->SetLayerDepth( ClearanceOverlayDepth );
+ aGal->SetStrokeColor( COLOR4D( DARKDARKGRAY ) );
+ aGal->SetIsStroke( true );
+ aGal->SetLineWidth( 2 * m_clearance );
+ // need the implicit last segment to be explicit for DrawPolyline
+ polygon.push_back( c->CDPoint( 0 ) );
+ aGal->DrawPolyline( polygon );
+ }
+ break;
+ }
+
+ case SH_POLY_SET:
+ case SH_COMPOUND:
+ break; // Not yet in use
+ }
+ }
+}
+
+
+void ROUTER_PREVIEW_ITEM::Line( const SHAPE_LINE_CHAIN& aLine, int aWidth, int aStyle )
+{
+ m_originLayer = m_layer = 0;
+ m_width = aWidth;
+ m_color = assignColor( aStyle );
+ m_type = PR_SHAPE;
+ m_depth = -1024; // TODO gal->GetMinDepth()
+ m_shape = aLine.Clone();
+
+ ViewSetVisible( true );
+ ViewUpdate( GEOMETRY | APPEARANCE );
+}
+
+
+void ROUTER_PREVIEW_ITEM::Point( const VECTOR2I& aPos, int aStyle )
+{
+}
+
+
+void ROUTER_PREVIEW_ITEM::Box( const BOX2I& aBox, int aStyle )
+{
+}
+
+
+const COLOR4D ROUTER_PREVIEW_ITEM::getLayerColor( int aLayer ) const
+{
+ PCB_RENDER_SETTINGS* settings =
+ static_cast<PCB_RENDER_SETTINGS*>( m_parent->GetView()->GetPainter()->GetSettings() );
+
+ return settings->GetLayerColor( aLayer );
+}
+
+
+const COLOR4D ROUTER_PREVIEW_ITEM::assignColor( int aStyle ) const
+{
+ COLOR4D color;
+
+ switch( aStyle )
+ {
+ case 0:
+ color = COLOR4D( 0, 1, 0, 1 ); break;
+
+ case 1:
+ color = COLOR4D( 1, 0, 0, 1 ); break;
+
+ case 2:
+ color = COLOR4D( 1, 1, 0, 1 ); break;
+
+ case 3:
+ color = COLOR4D( 0, 0, 1, 1 ); break;
+
+ case 4:
+ color = COLOR4D( 1, 1, 1, 1 ); break;
+
+ case 5:
+ color = COLOR4D( 1, 1, 0, 1 ); break;
+
+ case 6:
+ color = COLOR4D( 0, 1, 1, 1 ); break;
+
+ case 32:
+ color = COLOR4D( 0, 0, 1, 1 ); break;
+
+ default:
+ color = COLOR4D( 0.4, 0.4, 0.4, 1 ); break;
+ }
+
+ return color;
+}
+
+const int ROUTER_PREVIEW_ITEM::ClearanceOverlayDepth = -300;
+const int ROUTER_PREVIEW_ITEM::BaseOverlayDepth = -310;
+const int ROUTER_PREVIEW_ITEM::ViaOverlayDepth = -346;
diff --git a/pcbnew/router/router_preview_item.h b/pcbnew/router/router_preview_item.h
new file mode 100644
index 0000000..653900d
--- /dev/null
+++ b/pcbnew/router/router_preview_item.h
@@ -0,0 +1,127 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ROUTER_PREVIEW_ITEM_H
+#define __ROUTER_PREVIEW_ITEM_H
+
+#include <cstdio>
+
+#include <view/view.h>
+#include <view/view_item.h>
+#include <view/view_group.h>
+
+#include <math/vector2d.h>
+#include <math/box2.h>
+
+#include <geometry/shape_line_chain.h>
+#include <geometry/shape_circle.h>
+
+#include <gal/color4d.h>
+#include <gal/graphics_abstraction_layer.h>
+
+#include <layers_id_colors_and_visibility.h>
+
+class PNS_ITEM;
+class PNS_ROUTER;
+
+class ROUTER_PREVIEW_ITEM : public EDA_ITEM
+{
+public:
+ enum ITEM_TYPE
+ {
+ PR_STUCK_MARKER = 0,
+ PR_POINT,
+ PR_SHAPE
+ };
+
+ ROUTER_PREVIEW_ITEM( const PNS_ITEM* aItem = NULL, KIGFX::VIEW_GROUP* aParent = NULL );
+ ~ROUTER_PREVIEW_ITEM();
+
+ void Update( const PNS_ITEM* aItem );
+
+ void StuckMarker( VECTOR2I& aPosition );
+
+ void Line( const SHAPE_LINE_CHAIN& aLine, int aWidth = 0, int aStyle = 0 );
+ void Box( const BOX2I& aBox, int aStyle = 0 );
+ void Point ( const VECTOR2I& aPos, int aStyle = 0);
+
+ void SetColor( const KIGFX::COLOR4D& aColor )
+ {
+ m_color = aColor;
+ }
+
+ void SetClearance( int aClearance )
+ {
+ m_clearance = aClearance;
+ }
+
+#if defined(DEBUG)
+ void Show( int aA, std::ostream& aB ) const {};
+#endif
+
+ /** Get class name
+ * @return string "ROUTER_PREVIEW_ITEM"
+ */
+ virtual wxString GetClass() const
+ {
+ return wxT( "ROUTER_PREVIEW_ITEM" );
+ }
+
+ const BOX2I ViewBBox() const;
+
+ virtual void ViewDraw( int aLayer, KIGFX::GAL* aGal ) const;
+
+ virtual void ViewGetLayers( int aLayers[], int& aCount ) const
+ {
+ aLayers[0] = m_layer;
+ aCount = 1;
+ }
+
+ void drawLineChain( const SHAPE_LINE_CHAIN& aL, KIGFX::GAL* aGal ) const;
+
+private:
+ const KIGFX::COLOR4D assignColor( int aStyle ) const;
+ const KIGFX::COLOR4D getLayerColor( int aLayer ) const;
+
+ KIGFX::VIEW_GROUP* m_parent;
+
+ PNS_ROUTER* m_router;
+ SHAPE* m_shape;
+
+ ITEM_TYPE m_type;
+
+ int m_style;
+ int m_width;
+ int m_layer;
+ int m_originLayer;
+ int m_clearance;
+
+ // fixme: shouldn't this go to VIEW?
+ static const int ClearanceOverlayDepth;
+ static const int BaseOverlayDepth;
+ static const int ViaOverlayDepth;
+
+ double m_depth;
+
+ KIGFX::COLOR4D m_color;
+ VECTOR2I m_pos;
+};
+
+#endif
diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp
new file mode 100644
index 0000000..7e03f8b
--- /dev/null
+++ b/pcbnew/router/router_tool.cpp
@@ -0,0 +1,854 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <wx/numdlg.h>
+
+#include <boost/foreach.hpp>
+#include <boost/optional.hpp>
+#include <boost/bind.hpp>
+
+#include "class_draw_panel_gal.h"
+#include "class_board.h"
+
+#include <wxPcbStruct.h>
+#include <id.h>
+#include <macros.h>
+#include <pcbnew_id.h>
+#include <view/view_controls.h>
+#include <pcbcommon.h>
+#include <pcb_painter.h>
+#include <dialogs/dialog_pns_settings.h>
+#include <dialogs/dialog_pns_diff_pair_dimensions.h>
+#include <dialogs/dialog_track_via_size.h>
+#include <base_units.h>
+#include <hotkeys.h>
+#include <confirm.h>
+
+#include <tool/context_menu.h>
+#include <tool/tool_manager.h>
+#include <tool/tool_settings.h>
+#include <tools/common_actions.h>
+#include <tools/size_menu.h>
+#include <tools/selection_tool.h>
+#include <tools/edit_tool.h>
+
+#include <ratsnest_data.h>
+
+#include "router_tool.h"
+#include "pns_segment.h"
+#include "pns_router.h"
+#include "trace.h"
+
+using namespace KIGFX;
+using boost::optional;
+
+static TOOL_ACTION ACT_NewTrack( "pcbnew.InteractiveRouter.NewTrack", AS_CONTEXT,
+ TOOL_ACTION::LegacyHotKey( HK_ADD_NEW_TRACK ),
+ _( "New Track" ), _( "Starts laying a new track." ), add_tracks_xpm );
+
+static TOOL_ACTION ACT_EndTrack( "pcbnew.InteractiveRouter.EndTrack", AS_CONTEXT, WXK_END,
+ _( "End Track" ), _( "Stops laying the current track." ), checked_ok_xpm );
+
+static TOOL_ACTION ACT_AutoEndRoute( "pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'F',
+ _( "Auto-end Track" ), _( "Automagically finishes currently routed track." ) );
+
+static TOOL_ACTION ACT_Drag( "pcbnew.InteractiveRouter.Drag", AS_CONTEXT,
+ TOOL_ACTION::LegacyHotKey( HK_DRAG_TRACK_KEEP_SLOPE ),
+ _( "Drag Track/Via" ), _( "Drags a track or a via." ), drag_track_segment_xpm );
+
+static TOOL_ACTION ACT_PlaceThroughVia( "pcbnew.InteractiveRouter.PlaceVia",
+ AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_ADD_THROUGH_VIA ),
+ _( "Place Through Via" ),
+ _( "Adds a through-hole via at the end of currently routed track." ),
+ via_xpm );
+
+static TOOL_ACTION ACT_PlaceBlindVia( "pcbnew.InteractiveRouter.PlaceBlindVia",
+ AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_ADD_BLIND_BURIED_VIA ),
+ _( "Place Blind/Buried Via" ),
+ _( "Adds a blind or buried via at the end of currently routed track."),
+ via_buried_xpm );
+
+static TOOL_ACTION ACT_PlaceMicroVia( "pcbnew.InteractiveRouter.PlaceMicroVia",
+ AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_ADD_MICROVIA ),
+ _( "Place Microvia" ), _( "Adds a microvia at the end of currently routed track." ),
+ via_microvia_xpm );
+
+static TOOL_ACTION ACT_CustomTrackWidth( "pcbnew.InteractiveRouter.CustomTrackViaSize",
+ AS_CONTEXT, 'Q',
+ _( "Custom Track/Via Size" ),
+ _( "Shows a dialog for changing the track width and via size." ),
+ width_track_xpm );
+
+static TOOL_ACTION ACT_SwitchPosture( "pcbnew.InteractiveRouter.SwitchPosture", AS_CONTEXT,
+ TOOL_ACTION::LegacyHotKey( HK_SWITCH_TRACK_POSTURE ),
+ _( "Switch Track Posture" ),
+ _( "Switches posture of the currently routed track." ),
+ change_entry_orient_xpm );
+
+static TOOL_ACTION ACT_SetDpDimensions( "pcbnew.InteractiveRouter.SetDpDimensions",
+ AS_CONTEXT, 'P',
+ _( "Differential Pair Dimensions..." ),
+ _( "Sets the width and gap of the currently routed differential pair." ),
+ ps_diff_pair_tune_length_xpm );
+
+
+ROUTER_TOOL::ROUTER_TOOL() :
+ PNS_TOOL_BASE( "pcbnew.InteractiveRouter" )
+{
+}
+
+
+class CONTEXT_TRACK_WIDTH_MENU: public CONTEXT_TRACK_VIA_SIZE_MENU
+{
+public:
+ CONTEXT_TRACK_WIDTH_MENU()
+ : CONTEXT_TRACK_VIA_SIZE_MENU( true, true ), m_board( NULL )
+ {
+ SetMenuHandler( boost::bind( &CONTEXT_TRACK_WIDTH_MENU::EventHandler, this, _1 ) );
+ }
+
+ void SetBoard( BOARD* aBoard )
+ {
+ m_board = aBoard;
+
+ Append( ID_POPUP_PCB_SELECT_CUSTOM_WIDTH, _( "Custom size" ),
+ wxEmptyString, wxITEM_CHECK );
+
+ Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH, _( "Use the starting track width" ),
+ _( "Route using the width of the starting track." ), wxITEM_CHECK );
+
+ Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES, _( "Use net class values" ),
+ _( "Use track and via sizes from the net class" ), wxITEM_CHECK );
+
+ AppendSeparator();
+
+ // Append the list of tracks & via sizes
+ AppendSizes( aBoard );
+ }
+
+ OPT_TOOL_EVENT EventHandler( const wxMenuEvent& aEvent )
+ {
+#if ID_POPUP_PCB_SELECT_VIASIZE1 < ID_POPUP_PCB_SELECT_WIDTH1
+#error You have changed event ids order, it breaks code. Check the source code for more details.
+// Recognising type of event (track width/via size) is based on comparison if the event id is
+// within a specific range. If ranges of event ids changes, then the following is not valid anymore.
+#endif
+ BOARD_DESIGN_SETTINGS &bds = m_board->GetDesignSettings();
+
+ int id = aEvent.GetId();
+
+ // Initial settings, to be modified below
+ bds.m_UseConnectedTrackWidth = false;
+ bds.UseCustomTrackViaSize( false );
+
+ if( id == ID_POPUP_PCB_SELECT_CUSTOM_WIDTH )
+ {
+ bds.UseCustomTrackViaSize( true );
+ }
+
+ else if( id == ID_POPUP_PCB_SELECT_AUTO_WIDTH )
+ {
+ bds.m_UseConnectedTrackWidth = true;
+ }
+
+ else if( id == ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES )
+ {
+ bds.SetViaSizeIndex( 0 );
+ bds.SetTrackWidthIndex( 0 );
+ }
+
+ else if( id >= ID_POPUP_PCB_SELECT_VIASIZE1 ) // via size has changed
+ {
+ assert( id < ID_POPUP_PCB_SELECT_WIDTH_END_RANGE );
+
+ bds.SetViaSizeIndex( id - ID_POPUP_PCB_SELECT_VIASIZE1 );
+ }
+
+ else // track width has changed
+ {
+ assert( id >= ID_POPUP_PCB_SELECT_WIDTH1 );
+ assert( id < ID_POPUP_PCB_SELECT_VIASIZE );
+
+ bds.SetTrackWidthIndex( id - ID_POPUP_PCB_SELECT_WIDTH1 );
+ }
+
+ return OPT_TOOL_EVENT( COMMON_ACTIONS::trackViaSizeChanged.MakeEvent() );
+ }
+
+private:
+ BOARD* m_board;
+};
+
+
+class ROUTER_TOOL_MENU: public CONTEXT_MENU
+{
+public:
+ ROUTER_TOOL_MENU( BOARD* aBoard, PNS_ROUTER_MODE aMode )
+ {
+ SetTitle( _( "Interactive Router" ) );
+ Add( ACT_NewTrack );
+ Add( ACT_EndTrack );
+// Add( ACT_AutoEndRoute ); // fixme: not implemented yet. Sorry.
+ Add( ACT_Drag );
+ Add( ACT_PlaceThroughVia );
+ Add( ACT_PlaceBlindVia );
+ Add( ACT_PlaceMicroVia );
+ Add( ACT_SwitchPosture );
+
+ AppendSeparator();
+
+ m_widthMenu.SetBoard( aBoard );
+ Add( &m_widthMenu, _( "Select Track/Via Width" ) );
+
+ Add( ACT_CustomTrackWidth );
+
+ if( aMode == PNS_MODE_ROUTE_DIFF_PAIR )
+ Add( ACT_SetDpDimensions );
+
+ AppendSeparator();
+ Add( PNS_TOOL_BASE::ACT_RouterOptions );
+ }
+
+private:
+ CONTEXT_TRACK_WIDTH_MENU m_widthMenu;
+};
+
+
+ROUTER_TOOL::~ROUTER_TOOL()
+{
+ m_savedSettings.Save( GetSettings() );
+}
+
+bool ROUTER_TOOL::Init()
+{
+ m_savedSettings.Load( GetSettings() );
+ return true;
+}
+
+
+void ROUTER_TOOL::Reset( RESET_REASON aReason )
+{
+ PNS_TOOL_BASE::Reset( aReason );
+
+ Go( &ROUTER_TOOL::RouteSingleTrace, COMMON_ACTIONS::routerActivateSingle.MakeEvent() );
+ Go( &ROUTER_TOOL::RouteDiffPair, COMMON_ACTIONS::routerActivateDiffPair.MakeEvent() );
+ Go( &ROUTER_TOOL::DpDimensionsDialog, COMMON_ACTIONS::routerActivateDpDimensionsDialog.MakeEvent() );
+ Go( &ROUTER_TOOL::SettingsDialog, COMMON_ACTIONS::routerActivateSettingsDialog.MakeEvent() );
+ Go( &ROUTER_TOOL::InlineDrag, COMMON_ACTIONS::routerInlineDrag.MakeEvent() );
+}
+
+
+int ROUTER_TOOL::getDefaultWidth( int aNetCode )
+{
+ int w, d1, d2;
+
+ getNetclassDimensions( aNetCode, w, d1, d2 );
+
+ return w;
+}
+
+
+void ROUTER_TOOL::getNetclassDimensions( int aNetCode, int& aWidth,
+ int& aViaDiameter, int& aViaDrill )
+{
+ BOARD_DESIGN_SETTINGS &bds = m_board->GetDesignSettings();
+
+ NETCLASSPTR netClass;
+ NETINFO_ITEM* ni = m_board->FindNet( aNetCode );
+
+ if( ni )
+ {
+ wxString netClassName = ni->GetClassName();
+ netClass = bds.m_NetClasses.Find( netClassName );
+ }
+
+ if( !netClass )
+ netClass = bds.GetDefault();
+
+ aWidth = netClass->GetTrackWidth();
+ aViaDiameter = netClass->GetViaDiameter();
+ aViaDrill = netClass->GetViaDrill();
+}
+
+
+void ROUTER_TOOL::handleCommonEvents( const TOOL_EVENT& aEvent )
+{
+#ifdef DEBUG
+ if( aEvent.IsKeyPressed() )
+ {
+ switch( aEvent.KeyCode() )
+ {
+ case '0':
+ TRACEn( 2, "saving drag/route log...\n" );
+ m_router->DumpLog();
+ break;
+ }
+ }
+ else
+#endif
+ if( aEvent.IsAction( &ACT_RouterOptions ) )
+ {
+ DIALOG_PNS_SETTINGS settingsDlg( m_frame, m_router->Settings() );
+
+ if( settingsDlg.ShowModal() == wxID_OK )
+ {
+ // FIXME: do we need an explicit update?
+ }
+ }
+ else if( aEvent.IsAction( &ACT_SetDpDimensions ) )
+ {
+ PNS_SIZES_SETTINGS sizes = m_router->Sizes();
+ DIALOG_PNS_DIFF_PAIR_DIMENSIONS settingsDlg( m_frame, sizes );
+
+ if( settingsDlg.ShowModal() )
+ {
+ m_router->UpdateSizes( sizes );
+ }
+ }
+ else if( aEvent.IsAction( &ACT_CustomTrackWidth ) )
+ {
+ BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
+ DIALOG_TRACK_VIA_SIZE sizeDlg( m_frame, bds );
+
+ if( sizeDlg.ShowModal() )
+ {
+ bds.UseCustomTrackViaSize( true );
+ m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged );
+ }
+ }
+
+ else if( aEvent.IsAction( &COMMON_ACTIONS::trackViaSizeChanged ) )
+ {
+
+ PNS_SIZES_SETTINGS sizes( m_router->Sizes() );
+ sizes.ImportCurrent( m_board->GetDesignSettings() );
+ m_router->UpdateSizes( sizes );
+ }
+}
+
+
+int ROUTER_TOOL::getStartLayer( const PNS_ITEM* aItem )
+{
+ int tl = getView()->GetTopLayer();
+
+ if( m_startItem )
+ {
+ const PNS_LAYERSET& ls = m_startItem->Layers();
+
+ if( ls.Overlaps( tl ) )
+ return tl;
+ else
+ return ls.Start();
+ }
+
+ return tl;
+}
+
+
+void ROUTER_TOOL::switchLayerOnViaPlacement()
+{
+ int al = m_frame->GetActiveLayer();
+ int cl = m_router->GetCurrentLayer();
+
+ if( cl != al )
+ {
+ m_router->SwitchLayer( al );
+ }
+
+ optional<int> newLayer = m_router->Sizes().PairedLayer( cl );
+
+ if( !newLayer )
+ newLayer = m_router->Sizes().GetLayerTop();
+
+ m_router->SwitchLayer( *newLayer );
+ m_frame->SetActiveLayer( ToLAYER_ID( *newLayer ) );
+}
+
+
+bool ROUTER_TOOL::onViaCommand( TOOL_EVENT& aEvent, VIATYPE_T aType )
+{
+ BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
+
+ const int layerCount = bds.GetCopperLayerCount();
+ int currentLayer = m_router->GetCurrentLayer();
+ LAYER_ID pairTop = m_frame->GetScreen()->m_Route_Layer_TOP;
+ LAYER_ID pairBottom = m_frame->GetScreen()->m_Route_Layer_BOTTOM;
+
+ PNS_SIZES_SETTINGS sizes = m_router->Sizes();
+
+ // fixme: P&S supports more than one fixed layer pair. Update the dialog?
+ sizes.ClearLayerPairs();
+
+ if( !m_router->IsPlacingVia() )
+ {
+ // Cannot place microvias or blind vias if not allowed (obvious)
+ if( ( aType == VIA_BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) )
+ {
+ DisplayError( m_frame, _( "Blind/buried vias have to be enabled in the design settings." ) );
+ return false;
+ }
+
+ if( ( aType == VIA_MICROVIA ) && ( !bds.m_MicroViasAllowed ) )
+ {
+ DisplayError( m_frame, _( "Microvias have to be enabled in the design settings." ) );
+ return false;
+ }
+
+ // Can only place through vias on 2-layer boards
+ if( ( aType != VIA_THROUGH ) && ( layerCount <= 2 ) )
+ {
+ DisplayError( m_frame, _( "Only through vias are allowed on 2 layer boards." ) );
+ return false;
+ }
+
+ // Can only place microvias if we're on an outer layer, or directly adjacent to one
+ if( ( aType == VIA_MICROVIA ) && ( currentLayer > In1_Cu ) && ( currentLayer < layerCount - 2 ) )
+ {
+ DisplayError( m_frame, _( "Microvias can be placed only between the outer layers " \
+ "(F.Cu/B.Cu) and the ones directly adjacent to them." ) );
+ return false;
+ }
+ }
+
+ // Convert blind/buried via to a through hole one, if it goes through all layers
+ if( aType == VIA_BLIND_BURIED && ( ( currentLayer == B_Cu ) || ( currentLayer == F_Cu ) )
+ && ( ( pairTop == B_Cu && pairBottom == F_Cu )
+ || ( pairTop == F_Cu && pairBottom == B_Cu ) ) )
+ {
+ aType = VIA_THROUGH;
+ }
+
+ switch( aType )
+ {
+ case VIA_THROUGH:
+ sizes.SetViaDiameter( bds.GetCurrentViaSize() );
+ sizes.SetViaDrill( bds.GetCurrentViaDrill() );
+ sizes.AddLayerPair( pairTop, pairBottom );
+ break;
+
+ case VIA_MICROVIA:
+ sizes.SetViaDiameter( bds.GetCurrentMicroViaSize() );
+ sizes.SetViaDrill( bds.GetCurrentMicroViaDrill() );
+
+ if( currentLayer == F_Cu || currentLayer == In1_Cu )
+ sizes.AddLayerPair( F_Cu, In1_Cu );
+ else if( currentLayer == B_Cu || currentLayer == layerCount - 2 )
+ sizes.AddLayerPair( B_Cu, layerCount - 2 );
+ else
+ wxASSERT( false );
+ break;
+
+ case VIA_BLIND_BURIED:
+ sizes.SetViaDiameter( bds.GetCurrentViaSize() );
+ sizes.SetViaDrill( bds.GetCurrentViaDrill() );
+
+ if( currentLayer == pairTop || currentLayer == pairBottom )
+ sizes.AddLayerPair( pairTop, pairBottom );
+ else
+ sizes.AddLayerPair( pairTop, currentLayer );
+ break;
+
+ default:
+ wxASSERT( false );
+ break;
+ }
+
+ sizes.SetViaType( aType );
+
+ m_router->UpdateSizes( sizes );
+ m_router->ToggleViaPlacement();
+
+ updateEndItem( aEvent );
+
+ m_router->Move( m_endSnapPoint, m_endItem ); // refresh
+
+ return false;
+}
+
+
+bool ROUTER_TOOL::prepareInteractive()
+{
+ int routingLayer = getStartLayer( m_startItem );
+
+ if( !IsCopperLayer( routingLayer ) )
+ {
+ DisplayError( m_frame, _( "Tracks on Copper layers only " ) );
+ return false;
+ }
+
+ m_frame->SetActiveLayer( ToLAYER_ID( routingLayer ) );
+
+ // fixme: switch on invisible layer
+
+ // for some reason I don't understand, GetNetclass() may return null sometimes...
+ if( m_startItem &&
+ m_startItem->Net() >= 0 &&
+ m_startItem->Parent() &&
+ m_startItem->Parent()->GetNetClass() )
+ {
+ highlightNet( true, m_startItem->Net() );
+ // Update track width and via size shown in main toolbar comboboxes
+ m_frame->SetCurrentNetClass( m_startItem->Parent()->GetNetClass()->GetName() );
+ }
+ else
+ m_frame->SetCurrentNetClass( NETCLASS::Default );
+
+ m_ctls->ForceCursorPosition( false );
+ m_ctls->SetAutoPan( true );
+
+ PNS_SIZES_SETTINGS sizes( m_router->Sizes() );
+
+ sizes.Init( m_board, m_startItem );
+ sizes.AddLayerPair( m_frame->GetScreen()->m_Route_Layer_TOP,
+ m_frame->GetScreen()->m_Route_Layer_BOTTOM );
+ m_router->UpdateSizes( sizes );
+
+ if( !m_router->StartRouting( m_startSnapPoint, m_startItem, routingLayer ) )
+ {
+ DisplayError( m_frame, m_router->FailureReason() );
+ highlightNet( false );
+ return false;
+ }
+
+ m_endItem = NULL;
+ m_endSnapPoint = m_startSnapPoint;
+
+ return true;
+}
+
+
+bool ROUTER_TOOL::finishInteractive()
+{
+ m_router->StopRouting();
+
+ // Save the recent changes in the undo buffer
+ m_frame->SaveCopyInUndoList( m_router->GetUndoBuffer(), UR_UNSPECIFIED );
+ m_router->ClearUndoBuffer();
+ m_frame->OnModify();
+
+ m_ctls->SetAutoPan( false );
+ m_ctls->ForceCursorPosition( false );
+ highlightNet( false );
+
+ return true;
+}
+
+
+void ROUTER_TOOL::performRouting()
+{
+ if( !prepareInteractive() )
+ return;
+
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ if( evt->IsCancel() || evt->IsActivate() )
+ break;
+ else if( evt->IsMotion() )
+ {
+ m_router->SetOrthoMode( evt->Modifier( MD_CTRL ) );
+ updateEndItem( *evt );
+ m_router->Move( m_endSnapPoint, m_endItem );
+ }
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ updateEndItem( *evt );
+ bool needLayerSwitch = m_router->IsPlacingVia();
+
+ if( m_router->FixRoute( m_endSnapPoint, m_endItem ) )
+ break;
+
+ if( needLayerSwitch )
+ switchLayerOnViaPlacement();
+
+ // Synchronize the indicated layer
+ m_frame->SetActiveLayer( ToLAYER_ID( m_router->GetCurrentLayer() ) );
+ updateEndItem( *evt );
+ m_router->Move( m_endSnapPoint, m_endItem );
+ m_startItem = NULL;
+ }
+ else if( evt->IsAction( &ACT_PlaceThroughVia ) )
+ {
+ onViaCommand( *evt, VIA_THROUGH );
+ }
+ else if( evt->IsAction( &ACT_PlaceBlindVia ) )
+ {
+ onViaCommand( *evt, VIA_BLIND_BURIED );
+ }
+ else if( evt->IsAction( &ACT_PlaceMicroVia ) )
+ {
+ onViaCommand( *evt, VIA_MICROVIA );
+ }
+ else if( evt->IsAction( &ACT_SwitchPosture ) )
+ {
+ m_router->FlipPosture();
+ updateEndItem( *evt );
+ m_router->Move( m_endSnapPoint, m_endItem ); // refresh
+ }
+ else if( evt->IsAction( &COMMON_ACTIONS::layerChanged ) )
+ {
+ m_router->SwitchLayer( m_frame->GetActiveLayer() );
+ updateEndItem( *evt );
+ m_router->Move( m_endSnapPoint, m_endItem ); // refresh
+ }
+ else if( evt->IsAction( &ACT_EndTrack ) )
+ {
+ bool still_routing = true;
+ while( still_routing )
+ still_routing = m_router->FixRoute( m_endSnapPoint, m_endItem );
+ break;
+ }
+
+ handleCommonEvents( *evt );
+ }
+
+ finishInteractive();
+}
+
+
+int ROUTER_TOOL::DpDimensionsDialog( const TOOL_EVENT& aEvent )
+{
+ Activate();
+
+ PNS_SIZES_SETTINGS sizes = m_router->Sizes();
+ DIALOG_PNS_DIFF_PAIR_DIMENSIONS settingsDlg( m_frame, sizes );
+
+ if( settingsDlg.ShowModal() )
+ {
+ m_router->UpdateSizes( sizes );
+ m_savedSizes = sizes;
+ }
+
+ return 0;
+}
+
+
+int ROUTER_TOOL::SettingsDialog( const TOOL_EVENT& aEvent )
+{
+ Activate();
+
+ DIALOG_PNS_SETTINGS settingsDlg( m_frame, m_router->Settings() );
+
+ if( settingsDlg.ShowModal() )
+ {
+ m_savedSettings = m_router->Settings();
+ }
+ return 0;
+}
+
+
+int ROUTER_TOOL::RouteSingleTrace( const TOOL_EVENT& aEvent )
+{
+ m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Route Track" ) );
+ return mainLoop( PNS_MODE_ROUTE_SINGLE );
+}
+
+
+int ROUTER_TOOL::RouteDiffPair( const TOOL_EVENT& aEvent )
+{
+ m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Router Differential Pair" ) );
+ return mainLoop( PNS_MODE_ROUTE_DIFF_PAIR );
+}
+
+
+int ROUTER_TOOL::mainLoop( PNS_ROUTER_MODE aMode )
+{
+ PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
+ BOARD* board = getModel<BOARD>();
+
+ // Deselect all items
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ Activate();
+
+ m_router->SetMode( aMode );
+
+ m_ctls->SetSnapping( true );
+ m_ctls->ShowCursor( true );
+ frame->UndoRedoBlock( true );
+
+ m_startSnapPoint = getViewControls()->GetCursorPosition();
+
+ std::auto_ptr<ROUTER_TOOL_MENU> ctxMenu( new ROUTER_TOOL_MENU( board, aMode ) );
+ SetContextMenu( ctxMenu.get() );
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ if( m_needsSync )
+ {
+ m_router->SyncWorld();
+ m_router->SetView( getView() );
+ m_needsSync = false;
+ }
+
+ if( evt->IsCancel() || evt->IsActivate() )
+ break; // Finish
+ else if( evt->IsMotion() )
+ updateStartItem( *evt );
+ else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_NewTrack ) )
+ {
+ updateStartItem( *evt );
+
+ if( evt->Modifier( MD_CTRL ) )
+ performDragging();
+ else
+ performRouting();
+ }
+ else if( evt->IsAction( &ACT_Drag ) )
+ {
+ updateStartItem( *evt );
+ performDragging();
+ }
+ else if( evt->IsAction( &ACT_PlaceThroughVia ) )
+ {
+ m_toolMgr->RunAction( COMMON_ACTIONS::layerToggle, true );
+ }
+
+ handleCommonEvents( *evt );
+ }
+
+ frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+ frame->UndoRedoBlock( false );
+
+ // Store routing settings till the next invocation
+ m_savedSettings = m_router->Settings();
+ m_savedSizes = m_router->Sizes();
+
+ // Disable the context menu before it is destroyed
+ SetContextMenu( NULL, CMENU_OFF );
+
+ return 0;
+}
+
+
+void ROUTER_TOOL::performDragging()
+{
+ PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
+ VIEW_CONTROLS* ctls = getViewControls();
+
+ bool dragStarted = m_router->StartDragging( m_startSnapPoint, m_startItem );
+
+ if( !dragStarted )
+ return;
+
+ if( m_startItem && m_startItem->Net() >= 0 )
+ highlightNet( true, m_startItem->Net() );
+
+ ctls->SetAutoPan( true );
+
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ ctls->ForceCursorPosition( false );
+
+ if( evt->IsCancel() || evt->IsActivate() )
+ break;
+ else if( evt->IsMotion() )
+ {
+ updateEndItem( *evt );
+ m_router->Move( m_endSnapPoint, m_endItem );
+ }
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ if( m_router->FixRoute( m_endSnapPoint, m_endItem ) )
+ break;
+ }
+
+ handleCommonEvents( *evt );
+ }
+
+ if( m_router->RoutingInProgress() )
+ m_router->StopRouting();
+
+ // Save the recent changes in the undo buffer
+ frame->SaveCopyInUndoList( m_router->GetUndoBuffer(), UR_UNSPECIFIED );
+ m_router->ClearUndoBuffer();
+ frame->OnModify();
+
+ m_startItem = NULL;
+
+ ctls->SetAutoPan( false );
+ ctls->ForceCursorPosition( false );
+ highlightNet( false );
+}
+
+
+int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
+{
+ const BOARD_CONNECTED_ITEM *item = aEvent.Parameter<const BOARD_CONNECTED_ITEM*>();
+ PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
+ VIEW_CONTROLS* ctls = getViewControls();
+
+ Activate();
+
+ m_router->SyncWorld();
+ m_router->SetView( getView() );
+
+ m_startItem = m_router->GetWorld()->FindItemByParent( item );
+
+ VECTOR2I p0 = ctls->GetCursorPosition();
+
+ bool dragStarted = m_router->StartDragging( p0, m_startItem );
+
+ if( !dragStarted )
+ return 0;
+
+ ctls->ForceCursorPosition( false );
+ ctls->SetAutoPan( true );
+ frame->UndoRedoBlock( true );
+
+ bool saveUndoBuffer = true;
+
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ p0 = ctls->GetCursorPosition();
+
+ if( evt->IsCancel() )
+ {
+ saveUndoBuffer = false;
+ break;
+ }
+ else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
+ {
+ m_router->Move( p0, NULL );
+ }
+ else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
+ {
+ saveUndoBuffer = m_router->FixRoute( p0, NULL );
+ break;
+ }
+ }
+
+ if( m_router->RoutingInProgress() )
+ m_router->StopRouting();
+
+ if( saveUndoBuffer )
+ {
+ frame->SaveCopyInUndoList( m_router->GetUndoBuffer(), UR_UNSPECIFIED );
+ m_router->ClearUndoBuffer();
+ frame->OnModify();
+ }
+
+ ctls->SetAutoPan( false );
+ ctls->ShowCursor( false );
+ frame->UndoRedoBlock( false );
+
+ return 0;
+}
+
diff --git a/pcbnew/router/router_tool.h b/pcbnew/router/router_tool.h
new file mode 100644
index 0000000..c1bd1a2
--- /dev/null
+++ b/pcbnew/router/router_tool.h
@@ -0,0 +1,63 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ * Author: Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ROUTER_TOOL_H
+#define __ROUTER_TOOL_H
+
+#include "pns_tool_base.h"
+
+class APIEXPORT ROUTER_TOOL : public PNS_TOOL_BASE
+{
+public:
+ ROUTER_TOOL();
+ ~ROUTER_TOOL();
+
+ bool Init();
+ void Reset( RESET_REASON aReason );
+
+ int RouteSingleTrace ( const TOOL_EVENT& aEvent );
+ int RouteDiffPair ( const TOOL_EVENT& aEvent );
+ int InlineDrag ( const TOOL_EVENT& aEvent );
+
+ int DpDimensionsDialog ( const TOOL_EVENT& aEvent );
+ int SettingsDialog ( const TOOL_EVENT& aEvent );
+
+private:
+
+ int mainLoop( PNS_ROUTER_MODE aMode );
+
+ int getDefaultWidth( int aNetCode );
+
+ void performRouting();
+ void performDragging();
+
+ void getNetclassDimensions( int aNetCode, int& aWidth, int& aViaDiameter, int& aViaDrill );
+ void handleCommonEvents( const TOOL_EVENT& evt );
+
+ int getStartLayer( const PNS_ITEM* aItem );
+ void switchLayerOnViaPlacement();
+ bool onViaCommand( TOOL_EVENT& aEvent, VIATYPE_T aType );
+
+ bool prepareInteractive();
+ bool finishInteractive();
+};
+
+#endif
diff --git a/pcbnew/router/time_limit.cpp b/pcbnew/router/time_limit.cpp
new file mode 100644
index 0000000..b4cef54
--- /dev/null
+++ b/pcbnew/router/time_limit.cpp
@@ -0,0 +1,51 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <wx/timer.h>
+
+#include "time_limit.h"
+
+TIME_LIMIT::TIME_LIMIT( int aMilliseconds ) :
+ m_limitMs( aMilliseconds )
+{
+ Restart();
+}
+
+
+TIME_LIMIT::~TIME_LIMIT()
+{}
+
+
+bool TIME_LIMIT::Expired() const
+{
+ return ( wxGetLocalTimeMillis().GetValue() - m_startTics ) >= m_limitMs;
+}
+
+
+void TIME_LIMIT::Restart()
+{
+ m_startTics = wxGetLocalTimeMillis().GetValue();
+}
+
+
+void TIME_LIMIT::Set( int aMilliseconds )
+{
+ m_limitMs = aMilliseconds;
+}
diff --git a/pcbnew/router/time_limit.h b/pcbnew/router/time_limit.h
new file mode 100644
index 0000000..d917533
--- /dev/null
+++ b/pcbnew/router/time_limit.h
@@ -0,0 +1,43 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013-2014 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TIME_LIMIT_H
+#define __TIME_LIMIT_H
+
+#include <stdint.h>
+
+class TIME_LIMIT
+{
+public:
+ TIME_LIMIT( int aMilliseconds = 0 );
+ ~TIME_LIMIT();
+
+ bool Expired() const;
+ void Restart();
+
+ void Set( int aMilliseconds );
+ int Get() const { return m_limitMs; }
+
+private:
+ int m_limitMs;
+ int64_t m_startTics;
+};
+
+#endif
diff --git a/pcbnew/router/trace.h b/pcbnew/router/trace.h
new file mode 100644
index 0000000..c115b67
--- /dev/null
+++ b/pcbnew/router/trace.h
@@ -0,0 +1,46 @@
+/*
+ * KiRouter - a push-and-(sometimes-)shove PCB router
+ *
+ * Copyright (C) 2013 CERN
+ * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TRACE_H
+#define __TRACE_H
+
+#include <string>
+#include <iostream>
+#include <boost/format.hpp>
+
+static inline void _trace_print( const char* aFuncName, int aLevel, const std::string& aMsg )
+{
+#ifdef DEBUG
+ std::cerr << "trace[" << aLevel << "]: " << aFuncName << ": " << aMsg << std::endl;
+#endif
+}
+
+#ifdef PNS_DEBUG
+ #define TRACE( level, fmt, ... ) \
+ _trace_print( __FUNCTION__, level, ( boost::format( fmt ) % __VA_ARGS__ ).str() );
+
+ #define TRACEn( level, msg ) \
+ _trace_print( __FUNCTION__, level, std::string( msg ) );
+#else
+ #define TRACE( ... )
+ #define TRACEn( ... )
+#endif
+
+#endif
diff --git a/pcbnew/scripting/TODO.txt b/pcbnew/scripting/TODO.txt
new file mode 100644
index 0000000..c0f3160
--- /dev/null
+++ b/pcbnew/scripting/TODO.txt
@@ -0,0 +1,11 @@
+
+* think about documentation, how to do it
+* Action plugins:
+ right click hooks,
+ toolbar hooks,
+ menu hooks,
+* IO plugins
+* better footprint wizard (preview in footprint wizard list)
+
+
+
diff --git a/pcbnew/scripting/board.i b/pcbnew/scripting/board.i
new file mode 100644
index 0000000..da0e10a
--- /dev/null
+++ b/pcbnew/scripting/board.i
@@ -0,0 +1,117 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo <miguelangel@nbee.es>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file board.i
+ * @brief Specific BOARD extensions and templates
+ */
+
+
+%extend BOARD
+{
+ %pythoncode
+ %{
+ def GetModules(self): return self.m_Modules
+ def GetDrawings(self): return self.m_Drawings
+ def GetTracks(self): return self.m_Track
+ def GetFullRatsnest(self): return self.m_FullRatsnest
+
+ def Save(self,filename):
+ return SaveBoard(filename,self,IO_MGR.KICAD)
+
+ #
+ # add function, clears the thisown to avoid python from deleting
+ # the object in the garbage collector
+ #
+
+ def Add(self,item):
+ item.thisown=0
+ self.AddNative(item)
+ %}
+
+}
+
+// this is to help python with the * accessor of DLIST templates
+
+%rename(Get) operator BOARD_ITEM*;
+%rename(Get) operator TRACK*;
+%rename(Get) operator D_PAD*;
+%rename(Get) operator MODULE*;
+
+
+// we must translate C++ templates to scripting languages
+
+%template(BOARD_ITEM_List) DLIST<BOARD_ITEM>;
+%template(MODULE_List) DLIST<MODULE>;
+%template(TRACK_List) DLIST<TRACK>;
+%template(PAD_List) DLIST<D_PAD>;
+
+// std::vector templates
+
+%template(VIA_DIMENSION_Vector) std::vector<VIA_DIMENSION>;
+%template (RATSNEST_Vector) std::vector<RATSNEST_ITEM>;
+
+%extend BOARD
+{
+ %pythoncode
+ {
+ def GetNetClasses(self):
+ return self.GetDesignSettings().m_NetClasses
+
+ def GetCurrentNetClassName(self):
+ return self.GetDesignSettings().m_CurrentNetClassName
+
+ def GetViasDimensionsList(self):
+ return self.GetDesignSettings().m_ViasDimensionsList
+
+ def GetTrackWidthList(self):
+ return self.GetDesignSettings().m_TrackWidthList
+ }
+}
+
+
+%extend DRAWSEGMENT
+{
+ %pythoncode
+ {
+ def GetShapeStr(self):
+ return self.ShowShape(self.GetShape())
+ }
+}
+
+%extend BOARD_ITEM
+{
+ %pythoncode
+ {
+ def SetPos(self,p):
+ self.SetPosition(p)
+ self.SetPos0(p)
+
+ def SetStartEnd(self,start,end):
+ self.SetStart(start)
+ self.SetStart0(start)
+ self.SetEnd(end)
+ self.SetEnd0(end)
+ }
+}
diff --git a/pcbnew/scripting/board_item.i b/pcbnew/scripting/board_item.i
new file mode 100644
index 0000000..93f3026
--- /dev/null
+++ b/pcbnew/scripting/board_item.i
@@ -0,0 +1,98 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Miguel Angel Ajo <miguelangel@nbee.es>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file board_item.i
+ * @brief board_item helpers, mainly for casting down to all child classes
+ */
+
+
+/* Cast downs from EDA_ITEM/BOARD_ITEM to childs */
+
+%inline
+{
+ BOARD_ITEM* Cast_to_BOARD_ITEM(EDA_ITEM* base) { return dynamic_cast<BOARD_ITEM*>(base); }
+}
+
+%extend BOARD_ITEM
+{
+ TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast<TEXTE_PCB*>(self); }
+ DIMENSION* Cast_to_DIMENSION() { return dynamic_cast<DIMENSION*>(self); }
+ MODULE* Cast_to_MODULE() { return dynamic_cast<MODULE*>(self); }
+ TEXTE_MODULE* Cast_to_TEXTE_MODULE() { return dynamic_cast<TEXTE_MODULE*>(self); }
+ DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast<DRAWSEGMENT*>(self); }
+ MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast<MARKER_PCB*>(self); }
+ BOARD* Cast_to_BOARD() { return dynamic_cast<BOARD*>(self); }
+ EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast<EDGE_MODULE*>(self); }
+ D_PAD* Cast_to_D_PAD() { return dynamic_cast<D_PAD*>(self); }
+ TRACK* Cast_to_TRACK() { return dynamic_cast<TRACK*>(self); }
+ VIA* Cast_to_VIA() { return dynamic_cast<VIA*>(self); }
+ ZONE_CONTAINER* Cast_to_ZONE_CONTAINER() { return dynamic_cast<ZONE_CONTAINER*>(self);}
+ PCB_TARGET* Cast_to_PCB_TARGET() { return dynamic_cast<PCB_TARGET*>(self); }
+
+
+ %pythoncode
+ {
+ def Cast(self):
+
+ ct = self.GetClass()
+
+ if ct=="PTEXT":
+ return self.Cast_to_TEXTE_PCB()
+ elif ct=="BOARD":
+ return self.Cast_to_BOARD()
+ elif ct=="DIMENSION":
+ return self.Cast_to_DIMENSION()
+ elif ct=="DRAWSEGMENT":
+ return self.Cast_to_DRAWSEGMENT()
+ elif ct=="MGRAPHIC":
+ return self.Cast_to_EDGE_MODULE()
+ elif ct=="MODULE":
+ return self.Cast_to_MODULE()
+ elif ct=="PAD":
+ return self.Cast_to_D_PAD()
+ elif ct=="MTEXT":
+ return self.Cast_to_TEXTE_MODULE()
+ elif ct=="VIA":
+ return self.Cast_to_VIA()
+ elif ct=="TRACK":
+ return self.Cast_to_TRACK()
+ elif ct=="PCB_TARGET":
+ return self.Cast_to_PCB_TARGET()
+ elif ct=="ZONE_CONTAINER":
+ return self.Cast_to_ZONE_CONTAINER()
+ else:
+ return None
+
+
+ def Duplicate(self):
+
+ ct = self.GetClass()
+
+ if ct=="BOARD":
+ return None
+ else:
+ return Cast_to_BOARD_ITEM(self.Clone()).Cast()
+ }
+}
diff --git a/pcbnew/scripting/examples/createFPC40.py b/pcbnew/scripting/examples/createFPC40.py
new file mode 100755
index 0000000..7c6568e
--- /dev/null
+++ b/pcbnew/scripting/examples/createFPC40.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python2.7
+from pcbnew import *
+
+size_025_160mm = wxSizeMM(0.25,1.6)
+size_150_200mm = wxSizeMM(1.50,2.0)
+pads = 40
+
+# create a blank board
+pcb = BOARD()
+
+pcb.m_NetClasses.GetDefault().SetClearance(FromMM(0.1))
+
+# create a new module, it's parent is our previously created pcb
+module = MODULE(pcb)
+module.SetReference("FPC"+str(pads)) # give it a reference name
+module.Reference().SetPos0(wxPointMM(-1,-1))
+pcb.Add(module) # add it to our pcb
+m_pos = wxPointMM(50,50)
+module.SetPosition(m_pos)
+
+# create a pad array and add it to the module
+
+
+def smdRectPad(module,size,pos,name):
+ pad = D_PAD(module)
+ pad.SetSize(size)
+ pad.SetShape(PAD_RECT)
+ pad.SetAttribute(PAD_SMD)
+ pad.SetLayerMask(PAD_SMD_DEFAULT_LAYERS)
+ pad.SetPos0(pos)
+ pad.SetPadName(name)
+ return pad
+
+for n in range (0,pads):
+ pad = smdRectPad(module,size_025_160mm,wxPointMM(0.5*n,0),str(n+1))
+ module.Add(pad)
+
+
+pad_s0 = smdRectPad(module,size_150_200mm,wxPointMM(-1.6,1.3),"0")
+pad_s1 = smdRectPad(module,size_150_200mm,wxPointMM((pads-1)*0.5+1.6,1.3),"0")
+module.Add(pad_s0)
+module.Add(pad_s1)
+
+e = EDGE_MODULE(module)
+e.SetStart0(wxPointMM(-1,0))
+e.SetEnd0(wxPointMM(0,0))
+e.SetWidth(FromMM(0.2))
+e.SetLayer(EDGE_LAYER)
+e.SetShape(S_SEGMENT)
+module.Add(e)
+
+# save the PCB to disk
+fpid = FPID("FPC"+str(pads)) #the name in library
+module.SetFPID( fpid )
+
+try:
+ FootprintLibCreate("fpc40.mod")
+except:
+ pass # we try to create, but may be it exists already
+FootprintSave("fpc40.mod",module)
diff --git a/pcbnew/scripting/examples/createPcb.py b/pcbnew/scripting/examples/createPcb.py
new file mode 100755
index 0000000..21c3803
--- /dev/null
+++ b/pcbnew/scripting/examples/createPcb.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python2.7
+from pcbnew import *
+
+size_0_6mm = wxSizeMM(0.6,0.6)
+size_1_0mm = wxSizeMM(1.0,1.0)
+
+# create a blank board
+pcb = BOARD()
+
+pcb.m_NetClasses.GetDefault().SetClearance(FromMM(0.1))
+
+# create a new module, it's parent is our previously created pcb
+module = MODULE(pcb)
+module.SetReference("M1") # give it a reference name
+module.Reference().SetPos0(wxPointMM(-10,-10))
+pcb.Add(module) # add it to our pcb
+m_pos = wxPointMM(50,50)
+module.SetPosition(m_pos)
+
+# create a pad array and add it to the module
+n = 1
+for y in range (0,10):
+ for x in range (0,10):
+ pad = D_PAD(module)
+ pad.SetDrillSize(size_0_6mm)
+ pad.SetSize(size_1_0mm)
+ pt = wxPointMM(1.27*x,1.27*y)
+ pad.SetPos0(pt);
+ #pad.SetPosition(pt)
+ pad.SetPadName(str(n))
+ module.Add(pad)
+ n+=1
+
+
+# save the PCB to disk
+pcb.Save("my2.kicad_pcb")
+pcb.Save("my2.brd")
+
+pcb = LoadBoard("my2.kicad_pcb")
+
+print map( lambda x: x.GetReference() , list(pcb.GetModules()))
+
+for m in pcb.GetModules():
+ for p in m.Pads():
+ print p.GetPadName(), p.GetPosition(), p.GetOffset()
+
+
+# pcb.GetDesignSettings()
diff --git a/pcbnew/scripting/examples/hidePcbValuesShowReferences.py b/pcbnew/scripting/examples/hidePcbValuesShowReferences.py
new file mode 100644
index 0000000..6b37842
--- /dev/null
+++ b/pcbnew/scripting/examples/hidePcbValuesShowReferences.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+import sys
+from pcbnew import *
+
+filename=sys.argv[1]
+
+pcb = LoadBoard(filename)
+
+for module in pcb.GetModules():
+ print "* Module: %s"%module.GetReference()
+ module.Value().SetVisible(False) # set Value as Hidden
+ module.Reference().SetVisible(True) # set Reference as Visible
+
+pcb.Save("mod_"+filename)
diff --git a/pcbnew/scripting/examples/listPcb.py b/pcbnew/scripting/examples/listPcb.py
new file mode 100755
index 0000000..60ed093
--- /dev/null
+++ b/pcbnew/scripting/examples/listPcb.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+import sys
+from pcbnew import *
+
+filename=sys.argv[1]
+
+pcb = LoadBoard(filename)
+
+ToUnits = ToMM
+FromUnits = FromMM
+#ToUnits=ToMils
+#FromUnits=FromMils
+
+print "LISTING VIAS:"
+
+for item in pcb.GetTracks():
+ if type(item) is VIA:
+
+ pos = item.GetPosition()
+ drill = item.GetDrillValue()
+ width = item.GetWidth()
+ print " * Via: %s - %f/%f "%(ToUnits(pos),ToUnits(drill),ToUnits(width))
+
+ elif type(item) is TRACK:
+
+ start = item.GetStart()
+ end = item.GetEnd()
+ width = item.GetWidth()
+
+ print " * Track: %s to %s, width %f" % (ToUnits(start),ToUnits(end),ToUnits(width))
+
+ else:
+ print "Unknown type %s" % type(item)
+
+print ""
+print "LIST DRAWINGS:"
+
+for item in pcb.GetDrawings():
+ if type(item) is TEXTE_PCB:
+ print "* Text: '%s' at %s"%(item.GetText(), item.GetPosition())
+ elif type(item) is DRAWSEGMENT:
+ print "* Drawing: %s"%item.GetShapeStr() # dir(item)
+ else:
+ print type(item)
+
+print ""
+print "LIST MODULES:"
+
+for module in pcb.GetModules():
+ print "* Module: %s at %s"%(module.GetReference(),ToUnits(module.GetPosition()))
+
+print ""
+print "Ratsnest cnt:",len(pcb.GetFullRatsnest())
+print "track w cnt:",len(pcb.GetTrackWidthList())
+print "via s cnt:",len(pcb.GetViasDimensionsList())
+
+print ""
+print "LIST ZONES:", pcb.GetAreaCount()
+
+for idx in range(0, pcb.GetAreaCount()):
+ zone=pcb.GetArea(idx)
+ print "zone:", idx, "priority:", zone.GetPriority(), "netname", zone.GetNetname()
+
+print ""
+print "NetClasses:", pcb.GetNetClasses().GetCount(),
+
diff --git a/pcbnew/scripting/examples/listPcbLibrary.py b/pcbnew/scripting/examples/listPcbLibrary.py
new file mode 100755
index 0000000..8262c17
--- /dev/null
+++ b/pcbnew/scripting/examples/listPcbLibrary.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+from pcbnew import *
+
+lst = FootprintEnumerate("/usr/share/kicad/modules/sockets.mod")
+
+for name in lst:
+ m = FootprintLoad("/usr/share/kicad/modules/sockets.mod",name)
+ print name,"->",m.GetLibRef(), m.GetReference()
+
+ for p in m.Pads():
+ print "\t",p.GetPadName(),p.GetPosition(),p.GetPos0(), p.GetOffset()
+
diff --git a/pcbnew/scripting/module.i b/pcbnew/scripting/module.i
new file mode 100644
index 0000000..21902bf
--- /dev/null
+++ b/pcbnew/scripting/module.i
@@ -0,0 +1,110 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo <miguelangel@nbee.es>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file module.i
+ * @brief Specific BOARD extensions and templates
+ */
+
+
+%extend MODULE
+{
+ %pythoncode
+ %{
+
+ #def SaveToLibrary(self,filename):
+ # return SaveModuleToLibrary(filename,self)
+
+ #
+ # add function, clears the thisown to avoid python from deleting
+ # the object in the garbage collector
+ #
+
+ def Add(self,item):
+
+ itemC = item.Cast()
+
+ if type(itemC) is D_PAD:
+ item.thisown=0
+ self.Pads().PushBack(itemC)
+ elif type(itemC) in [ TEXTE_PCB, DIMENSION, TEXTE_MODULE, DRAWSEGMENT,EDGE_MODULE]:
+ item.thisown = 0
+ self.GraphicalItems().PushBack(item)
+ %}
+
+}
+
+%pythoncode
+{
+
+ def GetPluginForPath(lpath):
+ return IO_MGR.PluginFind(IO_MGR.LEGACY)
+
+ def FootprintEnumerate(lpath):
+ plug = GetPluginForPath(lpath)
+ return plug.FootprintEnumerate(lpath)
+
+ def FootprintLoad(lpath,name):
+ plug = GetPluginForPath(lpath)
+ return plug.FootprintLoad(lpath,name)
+
+ def FootprintSave(lpath,module):
+ plug = GetPluginForPath(lpath)
+ return plug.FootprintSave(lpath,module)
+
+ def FootprintDelete(lpath,name):
+ plug = GetPluginForPath(lpath)
+ plug.FootprintDelete(lpath,name)
+
+ def FootprintLibCreate(lpath):
+ plug = GetPluginForPath(lpath)
+ plug.FootprintLibCreate(lpath)
+
+ def FootprintLibDelete(lpath):
+ plug = GetPluginForPath(lpath)
+ plug.FootprintLibDelete(lpath)
+
+ def FootprintIsWritable(lpath):
+ plug = GetPluginForPath(lpath)
+ plug.FootprintLibIsWritable(lpath)
+}
+
+%{
+ MODULE *PyModule_to_MODULE(PyObject *obj0)
+ {
+ void *argp;
+ int res1 = SWIG_ConvertPtr(obj0, &argp,SWIGTYPE_p_MODULE, 0 | 0 );
+ if (!SWIG_IsOK(res1))
+ {
+ SWIG_exception_fail(SWIG_ArgError(res1), "Converting object to MODULE*");
+ }
+
+ return (MODULE*)argp;
+
+ fail:
+ return NULL;
+
+ }
+
+%}
diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i
new file mode 100644
index 0000000..4e8c7b4
--- /dev/null
+++ b/pcbnew/scripting/pcbnew.i
@@ -0,0 +1,169 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo <miguelangel@nbee.es>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew.i
+ * @brief Specific pcbnew wrappers
+ */
+
+
+%module pcbnew
+
+%feature("autodoc", "1");
+#ifdef ENABLE_DOCSTRINGS_FROM_DOXYGEN
+%include "docstrings.i"
+#endif
+
+%include "kicad.i"
+
+// ignore a couple of items that generate warnings from swig built code
+
+%ignore BOARD_ITEM::ZeroOffset;
+%ignore D_PAD::m_PadSketchModePenSize;
+
+// rename the Add method of classes to Add native, so we will handle
+// the Add method in python
+
+%rename(AddNative) *::Add;
+
+// fix method names conflicts
+%rename(AddChild) MODULE::Add;
+%rename(RemoveChild) MODULE::Remove;
+%rename(DeleteChild) MODULE::Delete;
+
+%exception {
+ try{
+ $action
+ }
+ catch( IO_ERROR e )
+ {
+ std::string str = TO_UTF8( e.errorText );
+ str += '\n';
+ PyErr_SetString( PyExc_IOError, str.c_str() );
+ return NULL;
+ }
+ catch( std::exception &e )
+ {
+ std::string str = e.what();
+ str += '\n';
+ PyErr_SetString( PyExc_IOError, str.c_str() );
+ return NULL;
+ }
+ catch( ... )
+ {
+ SWIG_fail;
+ }
+}
+%include exception.i
+
+
+// this is what it must be included in the wrapper .cxx code to compile
+
+%{
+ #include <wx_python_helpers.h>
+ #include <class_board_item.h>
+ #include <class_board_connected_item.h>
+ #include <class_board_design_settings.h>
+ #include <class_board.h>
+ #include <class_module.h>
+ #include <class_track.h>
+ #include <class_zone.h>
+ #include <zones.h>
+ #include <layers_id_colors_and_visibility.h>
+ #include <class_pad.h>
+ #include <pad_shapes.h>
+ #include <class_netinfo.h>
+ #include <class_pcb_text.h>
+ #include <class_dimension.h>
+ #include <class_drawsegment.h>
+ #include <class_marker_pcb.h>
+ #include <class_mire.h>
+ #include <class_text_mod.h>
+ #include <class_edge_mod.h>
+ #include <dlist.h>
+ #include <class_zone_settings.h>
+ #include <class_netclass.h>
+ #include <class_netinfo.h>
+ #include <pcbnew_scripting_helpers.h>
+
+ #include <plotcontroller.h>
+ #include <pcb_plot_params.h>
+ #include <exporters/gendrill_Excellon_writer.h>
+ #include <colors.h>
+
+ BOARD *GetBoard(); /* get current editor board */
+%}
+
+
+%{
+ #include <io_mgr.h>
+ #include <kicad_plugin.h>
+%}
+
+%include <class_board_item.h>
+%include <class_board_connected_item.h>
+%include <class_board_design_settings.h>
+%include <class_board.h>
+%include <class_module.h>
+%include <class_track.h>
+%include <class_zone.h>
+%include <zones.h>
+%include <layers_id_colors_and_visibility.h>
+%include <class_pad.h>
+%include <pad_shapes.h>
+%include <class_netinfo.h>
+%include <class_pcb_text.h>
+%include <class_dimension.h>
+%include <class_drawsegment.h>
+%include <class_marker_pcb.h>
+%include <class_mire.h>
+%include <class_text_mod.h>
+%include <class_edge_mod.h>
+%include <dlist.h>
+%include <class_zone_settings.h>
+%include <class_netclass.h>
+%include <class_netinfo.h>
+
+%include <plotcontroller.h>
+%include <pcb_plot_params.h>
+%include <plot_common.h>
+%include <exporters/gendrill_Excellon_writer.h>
+%include <colors.h>
+
+%include "board_item.i"
+
+%include <pcbnew_scripting_helpers.h>
+
+
+// ignore RELEASER as nested classes are still unsupported by swig
+%ignore IO_MGR::RELEASER;
+%include <io_mgr.h>
+%include <kicad_plugin.h>
+
+%include "board.i"
+%include "module.i"
+%include "plugins.i"
+%include "units.i"
+
+
diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.cpp b/pcbnew/scripting/pcbnew_footprint_wizards.cpp
new file mode 100644
index 0000000..e0f3854
--- /dev/null
+++ b/pcbnew/scripting/pcbnew_footprint_wizards.cpp
@@ -0,0 +1,361 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 NBEE Embedded Systems SL, Miguel Angel Ajo <miguelangel@ajo.es>
+ * Copyright (C) 2013 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew_footprint_wizards.cpp
+ * @brief Class PCBNEW_PYTHON_FOOTPRINT_WIZARDS
+ */
+
+#include "pcbnew_footprint_wizards.h"
+#include <python_scripting.h>
+#include <stdio.h>
+#include <macros.h>
+
+
+PYTHON_FOOTPRINT_WIZARD::PYTHON_FOOTPRINT_WIZARD( PyObject* aWizard )
+{
+ PyLOCK lock;
+
+ this->m_PyWizard = aWizard;
+ Py_XINCREF( aWizard );
+}
+
+
+PYTHON_FOOTPRINT_WIZARD::~PYTHON_FOOTPRINT_WIZARD()
+{
+ PyLOCK lock;
+
+ Py_XDECREF( this->m_PyWizard );
+}
+
+
+PyObject* PYTHON_FOOTPRINT_WIZARD::CallMethod( const char* aMethod, PyObject* aArglist )
+{
+ PyLOCK lock;
+
+ PyErr_Clear();
+ // pFunc is a new reference to the desired method
+ PyObject* pFunc = PyObject_GetAttrString( this->m_PyWizard, aMethod );
+
+ if( pFunc && PyCallable_Check( pFunc ) )
+ {
+ PyObject* result = PyObject_CallObject( pFunc, aArglist );
+
+ if( PyErr_Occurred() )
+ {
+#if 1 // defined(DEBUG)
+ wxMessageBox( PyErrStringWithTraceback(),
+ wxT( "Exception on python footprint wizard code" ),
+ wxICON_ERROR | wxOK );
+#endif
+ }
+
+ if( result )
+ {
+ Py_XDECREF( pFunc );
+ return result;
+ }
+ }
+ else
+ {
+ printf( "method not found, or not callable: %s\n", aMethod );
+ }
+
+ if( pFunc )
+ {
+ Py_XDECREF( pFunc );
+ }
+
+ return NULL;
+}
+
+
+wxString PYTHON_FOOTPRINT_WIZARD::CallRetStrMethod( const char* aMethod, PyObject* aArglist )
+{
+ wxString ret;
+ PyLOCK lock;
+
+ PyObject* result = CallMethod( aMethod, aArglist );
+
+ if( result )
+ {
+ const char* str_res = PyString_AsString( result );
+ ret = FROM_UTF8( str_res );
+ Py_DECREF( result );
+ }
+
+ return ret;
+}
+
+
+wxArrayString PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod( const char* aMethod,
+ PyObject* aArglist )
+{
+ wxArrayString ret;
+ wxString str_item;
+ PyLOCK lock;
+
+ PyObject* result = CallMethod( aMethod, aArglist );
+
+ if( result )
+ {
+ if( !PyList_Check( result ) )
+ {
+ Py_DECREF( result );
+ ret.Add( wxT(
+ "PYTHON_FOOTPRINT_WIZARD::CallRetArrayStrMethod, result is not a list" ),
+ 1 );
+ return ret;
+ }
+
+ ret = PyArrayStringToWx( result );
+
+ Py_DECREF( result );
+ }
+
+ return ret;
+}
+
+
+wxString PYTHON_FOOTPRINT_WIZARD::GetName()
+{
+ PyLOCK lock;
+
+ return CallRetStrMethod( "GetName" );
+}
+
+
+wxString PYTHON_FOOTPRINT_WIZARD::GetImage()
+{
+ PyLOCK lock;
+
+ return CallRetStrMethod( "GetImage" );
+}
+
+
+wxString PYTHON_FOOTPRINT_WIZARD::GetDescription()
+{
+ PyLOCK lock;
+
+ return CallRetStrMethod( "GetDescription" );
+}
+
+
+int PYTHON_FOOTPRINT_WIZARD::GetNumParameterPages()
+{
+ int ret = 0;
+ PyLOCK lock;
+
+ // Time to call the callback
+ PyObject* result = CallMethod( "GetNumParameterPages", NULL );
+
+ if( result )
+ {
+ if( !PyInt_Check( result ) )
+ return -1;
+
+ ret = PyInt_AsLong( result );
+ Py_DECREF( result );
+ }
+
+ return ret;
+}
+
+
+wxString PYTHON_FOOTPRINT_WIZARD::GetParameterPageName( int aPage )
+{
+ wxString ret;
+ PyLOCK lock;
+
+ // Time to call the callback
+ PyObject* arglist = Py_BuildValue( "(i)", aPage );
+ PyObject* result = CallMethod( "GetParameterPageName", arglist );
+
+ Py_DECREF( arglist );
+
+ if( result )
+ {
+ const char* str_res = PyString_AsString( result );
+ ret = FROM_UTF8( str_res );
+ Py_DECREF( result );
+ }
+
+ return ret;
+}
+
+
+wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterNames( int aPage )
+{
+ wxArrayString ret;
+ PyLOCK lock;
+
+ PyObject* arglist = Py_BuildValue( "(i)", aPage );
+
+ ret = CallRetArrayStrMethod( "GetParameterNames", arglist );
+ Py_DECREF( arglist );
+
+ for( unsigned i = 0; i < ret.GetCount(); i++ )
+ {
+ wxString rest;
+ wxString item = ret[i];
+
+ if( item.StartsWith( wxT( "*" ), &rest ) )
+ {
+ ret[i] = rest;
+ }
+ }
+
+ return ret;
+}
+
+
+wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterTypes( int aPage )
+{
+ wxArrayString ret;
+ PyLOCK lock;
+
+ PyObject* arglist = Py_BuildValue( "(i)", aPage );
+
+ ret = CallRetArrayStrMethod( "GetParameterNames", arglist );
+ Py_DECREF( arglist );
+
+ for( unsigned i = 0; i<ret.GetCount(); i++ )
+ {
+ wxString rest;
+ wxString item = ret[i];
+
+ if( item.StartsWith( wxT( "*" ), &rest ) )
+ {
+ ret[i] = wxT( "UNITS" ); // units
+ }
+ else
+ {
+ ret[i] = wxT( "IU" ); // internal units
+ }
+ }
+
+ return ret;
+}
+
+
+wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterValues( int aPage )
+{
+ PyLOCK lock;
+
+ PyObject* arglist = Py_BuildValue( "(i)", aPage );
+ wxArrayString ret = CallRetArrayStrMethod( "GetParameterValues", arglist );
+
+ Py_DECREF( arglist );
+
+ return ret;
+}
+
+
+wxArrayString PYTHON_FOOTPRINT_WIZARD::GetParameterErrors( int aPage )
+{
+ PyLOCK lock;
+
+ PyObject* arglist = Py_BuildValue( "(i)", aPage );
+ wxArrayString ret = CallRetArrayStrMethod( "GetParameterErrors", arglist );
+
+ Py_DECREF( arglist );
+
+ return ret;
+}
+
+
+wxString PYTHON_FOOTPRINT_WIZARD::SetParameterValues( int aPage, wxArrayString& aValues )
+{
+ int len = aValues.size();
+
+ PyLOCK lock;
+
+ PyObject* py_list = PyList_New( len );
+
+ for( int i = 0; i < len; i++ )
+ {
+ wxString& str = aValues[i];
+ PyObject* py_str = PyString_FromString( (const char*) str.mb_str() );
+ PyList_SetItem( py_list, i, py_str );
+ }
+
+ PyObject* arglist;
+
+ arglist = Py_BuildValue( "(i,O)", aPage, py_list );
+ wxString res = CallRetStrMethod( "SetParameterValues", arglist );
+ Py_DECREF( arglist );
+
+ return res;
+}
+
+
+// this is a SWIG function declaration -from module.i
+MODULE* PyModule_to_MODULE( PyObject* obj0 );
+
+
+MODULE* PYTHON_FOOTPRINT_WIZARD::GetFootprint( wxString * aMessages )
+{
+ PyLOCK lock;
+
+ PyObject* result = CallMethod( "GetFootprint", NULL );
+
+ if( aMessages )
+ *aMessages = CallRetStrMethod( "GetBuildMessages", NULL );
+
+ if( !result )
+ return NULL;
+
+ PyObject* obj = PyObject_GetAttrString( result, "this" );
+
+ if( PyErr_Occurred() )
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ MODULE* mod = PyModule_to_MODULE( obj );
+
+ return mod;
+}
+
+
+void* PYTHON_FOOTPRINT_WIZARD::GetObject()
+{
+ return (void*) m_PyWizard;
+}
+
+
+void PYTHON_FOOTPRINT_WIZARDS::register_wizard( PyObject* aPyWizard )
+{
+ PYTHON_FOOTPRINT_WIZARD* fw = new PYTHON_FOOTPRINT_WIZARD( aPyWizard );
+
+ fw->register_wizard();
+}
+
+
+void PYTHON_FOOTPRINT_WIZARDS::deregister_wizard( PyObject* aPyWizard )
+{
+ // deregister also destroyes the previously created "PYTHON_FOOTPRINT_WIZARD object"
+ FOOTPRINT_WIZARDS::deregister_object( (void*) aPyWizard );
+}
diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.h b/pcbnew/scripting/pcbnew_footprint_wizards.h
new file mode 100644
index 0000000..ada111f
--- /dev/null
+++ b/pcbnew/scripting/pcbnew_footprint_wizards.h
@@ -0,0 +1,71 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 NBEE Embedded Systems SL, Miguel Angel Ajo <miguelangel@ajo.es>
+ * Copyright (C) 2013 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew_footprint_wizards.h
+ * @brief Class PCBNEW_FOOTPRINT_WIZARDS
+ */
+
+#ifndef PCBNEW_FOOTPRINT_WIZARDS_H
+#define PCBNEW_FOOTPRINT_WIZARDS_H
+#include <Python.h>
+#include <vector>
+#include <class_footprint_wizard.h>
+
+
+class PYTHON_FOOTPRINT_WIZARD : public FOOTPRINT_WIZARD
+{
+ PyObject* m_PyWizard;
+ PyObject* CallMethod( const char* aMethod, PyObject* aArglist = NULL );
+ wxString CallRetStrMethod( const char* aMethod, PyObject* aArglist = NULL );
+ wxArrayString CallRetArrayStrMethod( const char* aMethod,
+ PyObject* aArglist = NULL );
+
+public:
+ PYTHON_FOOTPRINT_WIZARD( PyObject* wizard );
+ ~PYTHON_FOOTPRINT_WIZARD();
+ wxString GetName();
+ wxString GetImage();
+ wxString GetDescription();
+ int GetNumParameterPages();
+ wxString GetParameterPageName( int aPage );
+ wxArrayString GetParameterNames( int aPage );
+ wxArrayString GetParameterTypes( int aPage );
+ wxArrayString GetParameterValues( int aPage );
+ wxArrayString GetParameterErrors( int aPage );
+ // must return an empty string or an error description
+ wxString SetParameterValues( int aPage, wxArrayString& aValues );
+ MODULE* GetFootprint( wxString * aMessages );
+ void* GetObject();
+};
+
+
+class PYTHON_FOOTPRINT_WIZARDS
+{
+public:
+ static void register_wizard( PyObject* aPyWizard );
+ static void deregister_wizard( PyObject* aPyWizard );
+};
+
+#endif /* PCBNEW_FOOTPRINT_WIZARDS_H */
diff --git a/pcbnew/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/scripting/pcbnew_scripting_helpers.cpp
new file mode 100644
index 0000000..62b21b3
--- /dev/null
+++ b/pcbnew/scripting/pcbnew_scripting_helpers.cpp
@@ -0,0 +1,109 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo <miguelangel@nbee.es>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file pcbnew_scripting_helpers.cpp
+ * @brief Scripting helper functions for pcbnew functionality
+ */
+
+#include <Python.h>
+
+#include <pcbnew_scripting_helpers.h>
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <build_version.h>
+#include <class_board.h>
+#include <kicad_string.h>
+#include <io_mgr.h>
+#include <macros.h>
+#include <stdlib.h>
+
+static PCB_EDIT_FRAME* PcbEditFrame = NULL;
+
+BOARD* GetBoard()
+{
+ if( PcbEditFrame )
+ return PcbEditFrame->GetBoard();
+ else
+ return NULL;
+}
+
+
+void ScriptingSetPcbEditFrame( PCB_EDIT_FRAME* aPCBEdaFrame )
+{
+ PcbEditFrame = aPCBEdaFrame;
+}
+
+
+BOARD* LoadBoard( wxString& aFileName )
+{
+ if( aFileName.EndsWith( wxT( ".kicad_pcb" ) ) )
+ return LoadBoard( aFileName, IO_MGR::KICAD );
+
+ else if( aFileName.EndsWith( wxT( ".brd" ) ) )
+ return LoadBoard( aFileName, IO_MGR::LEGACY );
+
+ // as fall back for any other kind use the legacy format
+ return LoadBoard( aFileName, IO_MGR::LEGACY );
+}
+
+
+BOARD* LoadBoard( wxString& aFileName, IO_MGR::PCB_FILE_T aFormat )
+{
+ return IO_MGR::Load( aFormat, aFileName );
+}
+
+
+bool SaveBoard( wxString& aFilename, BOARD* aBoard )
+{
+ return SaveBoard( aFilename, aBoard, IO_MGR::KICAD );
+}
+
+
+bool SaveBoard( wxString& aFileName, BOARD* aBoard,
+ IO_MGR::PCB_FILE_T aFormat )
+{
+ aBoard->m_Status_Pcb &= ~CONNEXION_OK;
+ aBoard->SynchronizeNetsAndNetClasses();
+ aBoard->GetDesignSettings().SetCurrentNetClass( NETCLASS::Default );
+
+#if 0
+ wxString header;
+ PROPERTIES props;
+
+ if( aFormat==IO_MGR::LEGACY )
+ {
+ header = wxString::Format(
+ wxT( "PCBNEW-BOARD Version %d date %s\n\n# Created by Pcbnew%s scripting\n\n" ),
+ LEGACY_BOARD_FILE_VERSION, DateAndTime().GetData(),
+ GetBuildVersion().GetData() );
+ props["header"] = header;
+ }
+
+ IO_MGR::Save( aFormat, aFileName, aBoard, &props );
+#else
+ IO_MGR::Save( aFormat, aFileName, aBoard, NULL );
+#endif
+ return true;
+}
diff --git a/pcbnew/scripting/pcbnew_scripting_helpers.h b/pcbnew/scripting/pcbnew_scripting_helpers.h
new file mode 100644
index 0000000..bff3d0e
--- /dev/null
+++ b/pcbnew/scripting/pcbnew_scripting_helpers.h
@@ -0,0 +1,47 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 NBEE Embedded Systems SL, Miguel Angel Ajo <miguelangel@ajo.es>
+ * Copyright (C) 2013 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __PCBNEW_SCRIPTING_HELPERS_H
+#define __PCBNEW_SCRIPTING_HELPERS_H
+
+#include <wxPcbStruct.h>
+#include <io_mgr.h>
+/* we could be including all these methods as static in a class, but
+ * we want plain pcbnew.<method_name> access from python */
+
+#ifndef SWIG
+void ScriptingSetPcbEditFrame( PCB_EDIT_FRAME* aPCBEdaFrame );
+
+#endif
+
+BOARD* GetBoard();
+
+BOARD* LoadBoard( wxString& aFileName, IO_MGR::PCB_FILE_T aFormat );
+BOARD* LoadBoard( wxString& aFileName );
+
+bool SaveBoard( wxString& aFileName, BOARD* aBoard, IO_MGR::PCB_FILE_T aFormat );
+bool SaveBoard( wxString& aFileName, BOARD* aBoard );
+
+
+#endif
diff --git a/pcbnew/scripting/plugins.i b/pcbnew/scripting/plugins.i
new file mode 100644
index 0000000..7e7dcb7
--- /dev/null
+++ b/pcbnew/scripting/plugins.i
@@ -0,0 +1,35 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 NBEE Embedded Systems SL, Miguel Angel Ajo <miguelangel@ajo.es>
+ * Copyright (C) 2013 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+%{
+#include <scripting/pcbnew_footprint_wizards.h>
+%}
+
+class PYTHON_FOOTPRINT_WIZARDS
+{
+public:
+ static void register_wizard(PyObject *wizard);
+ static void deregister_wizard(PyObject *wizard);
+
+};
diff --git a/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py b/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py
new file mode 100644
index 0000000..8526b45
--- /dev/null
+++ b/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py
@@ -0,0 +1,156 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+from __future__ import division
+import pcbnew
+
+import HelpfulFootprintWizardPlugin as HFPW
+
+
+class FPC_FootprintWizard(HFPW.HelpfulFootprintWizardPlugin):
+
+ def GetName(self):
+ return "FPC (SMT connector)"
+
+ def GetDescription(self):
+ return "FPC (SMT connector) Footprint Wizard"
+
+ def GetValue(self):
+ pins = self.parameters["Pads"]["*n"]
+ return "FPC_%d" % pins
+
+ def GenerateParameterList(self):
+ self.AddParam( "Pads", "n", self.uNatural, 40 )
+ self.AddParam( "Pads", "pitch", self.uMM, 0.5 )
+ self.AddParam( "Pads", "width", self.uMM, 0.25 )
+ self.AddParam( "Pads", "height", self.uMM, 1.6)
+ self.AddParam( "Shield", "shield_to_pad", self.uMM, 1.6 )
+ self.AddParam( "Shield", "from_top", self.uMM, 1.3 )
+ self.AddParam( "Shield", "width", self.uMM, 1.5 )
+ self.AddParam( "Shield", "height", self.uMM, 2 )
+
+
+ # build a rectangular pad
+ def smdRectPad(self,module,size,pos,name):
+ pad = pcbnew.D_PAD(module)
+ pad.SetSize(size)
+ pad.SetShape(pcbnew.PAD_SHAPE_RECT)
+ pad.SetAttribute(pcbnew.PAD_ATTRIB_SMD)
+ pad.SetLayerSet( pad.SMDMask() )
+ pad.SetPos0(pos)
+ pad.SetPosition(pos)
+ pad.SetPadName(name)
+ return pad
+
+ def CheckParameters(self):
+ p = self.parameters
+ self.CheckParamInt( "Pads", "*n" ) # not internal units preceded by "*"
+
+
+ def BuildThisFootprint(self):
+ p = self.parameters
+ pad_count = int(p["Pads"]["*n"])
+ pad_width = p["Pads"]["width"]
+ pad_height = p["Pads"]["height"]
+ pad_pitch = p["Pads"]["pitch"]
+ shl_width = p["Shield"]["width"]
+ shl_height = p["Shield"]["height"]
+ shl_to_pad = p["Shield"]["shield_to_pad"]
+ shl_from_top = p["Shield"]["from_top"]
+
+ offsetX = pad_pitch * ( pad_count-1 ) / 2
+ size_pad = pcbnew.wxSize( pad_width, pad_height )
+ size_shld = pcbnew.wxSize(shl_width, shl_height)
+ size_text = self.GetTextSize() # IPC nominal
+
+ # Gives a position and size to ref and value texts:
+ textposy = pad_height/2 + pcbnew.FromMM(1) + self.GetTextThickness()
+ self.draw.Reference( 0, textposy, size_text )
+
+ textposy = textposy + size_text + self.GetTextThickness()
+ self.draw.Value( 0, textposy, size_text )
+
+ # create a pad array and add it to the module
+ for n in range ( 0, pad_count ):
+ xpos = pad_pitch*n - offsetX
+ pad = self.smdRectPad(self.module,size_pad, pcbnew.wxPoint(xpos,0),str(n+1))
+ self.module.Add(pad)
+
+
+ # Mechanical shield pads: left pad and right pad
+ xpos = -shl_to_pad-offsetX
+ pad_s0_pos = pcbnew.wxPoint(xpos,shl_from_top)
+ pad_s0 = self.smdRectPad(self.module, size_shld, pad_s0_pos, "0")
+ xpos = (pad_count-1) * pad_pitch+shl_to_pad - offsetX
+ pad_s1_pos = pcbnew.wxPoint(xpos,shl_from_top)
+ pad_s1 = self.smdRectPad(self.module, size_shld, pad_s1_pos, "0")
+
+ self.module.Add(pad_s0)
+ self.module.Add(pad_s1)
+
+ # add footprint outline
+ linewidth = self.draw.GetLineTickness()
+ margin = linewidth
+
+ # upper line
+ posy = -pad_height/2 - linewidth/2 - margin
+ xstart = - pad_pitch*0.5-offsetX
+ xend = pad_pitch * pad_count + xstart;
+ self.draw.Line( xstart, posy, xend, posy )
+
+ # lower line
+ posy = pad_height/2 + linewidth/2 + margin
+ self.draw.Line(xstart, posy, xend, posy)
+
+ # around left mechanical pad (the outline around right pad is mirrored/y axix)
+ yend = pad_s0_pos.y + shl_height/2 + margin
+ self.draw.Line(xstart, posy, xstart, yend)
+ self.draw.Line(-xstart, posy, -xstart, yend)
+
+ posy = yend
+ xend = pad_s0_pos.x - (shl_width/2 + linewidth + margin*2)
+ self.draw.Line(xstart, posy, xend, posy)
+
+ # right pad side
+ self.draw.Line(-xstart, posy, -xend, yend)
+
+ # vertical segment at left of the pad
+ xstart = xend
+ yend = posy - (shl_height + linewidth + margin*2)
+ self.draw.Line(xstart, posy, xend, yend)
+
+ # right pad side
+ self.draw.Line(-xstart, posy, -xend, yend)
+
+ # horizontal segment above the pad
+ xstart = xend
+ xend = - pad_pitch*0.5-offsetX
+ posy = yend
+ self.draw.Line(xstart, posy, xend, yend)
+
+ # right pad side
+ self.draw.Line(-xstart, posy,-xend, yend)
+
+ # vertical segment above the pad
+ xstart = xend
+ yend = -pad_height/2 - linewidth/2 - margin
+ self.draw.Line(xstart, posy, xend, yend)
+
+ # right pad side
+ self.draw.Line(-xstart, posy, -xend, yend)
+
+
+FPC_FootprintWizard().register()
diff --git a/pcbnew/scripting/plugins/FootprintWizardDrawingAids.py b/pcbnew/scripting/plugins/FootprintWizardDrawingAids.py
new file mode 100644
index 0000000..058fe1e
--- /dev/null
+++ b/pcbnew/scripting/plugins/FootprintWizardDrawingAids.py
@@ -0,0 +1,523 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+from __future__ import division
+
+import pcbnew
+import math
+
+
+class FootprintWizardDrawingAids:
+ """
+ Collection of handy functions to simplify drawing shapes from within
+ footprint wizards
+
+ A "drawing context" is provided which can be used to set and retain
+ settings such as line tickness and layer
+ """
+
+ # directions (in degrees, compass-like)
+ dirN = 0
+ dirNE = 45
+ dirE = 90
+ dirSE = 135
+ dirS = 180
+ dirSW = 225
+ dirW = 270
+ dirNW = 315
+
+ # flip constants
+ flipNone = 0
+ flipX = 1 # flip X values, i.e. about Y
+ flipY = 2 # flip Y valuersabout X
+ flipBoth = 3
+
+ xfrmIDENTITY = [1, 0, 0, 0, 1, 0] # no transform
+
+ # these values come from our KiCad Library Convention 0.11
+ defaultLineThickness = pcbnew.FromMM(0.15)
+
+ def DefaultGraphicLayer(self):
+ return pcbnew.F_SilkS
+
+ def DefaultTextValueLayer(self):
+ return pcbnew.F_Fab
+
+ def __init__(self, module):
+ self.module = module
+ # drawing context defaults
+ self.dc = {
+ 'layer': self.DefaultGraphicLayer(),
+ 'lineThickness': self.defaultLineThickness,
+ 'transforms': [],
+ 'transform': self.xfrmIDENTITY
+ }
+
+ def PushTransform(self, mat):
+ """
+ Add a transform to the top of the stack and recompute the
+ overall transform
+ """
+ self.dc['transforms'].append(mat)
+ self.RecomputeTransforms()
+
+ def PopTransform(self, num=1):
+ """
+ Remove a transform from the top of the stack and recompute the
+ overall transform
+ """
+
+ for i in range(num):
+ mat = self.dc['transforms'].pop()
+ self.RecomputeTransforms()
+ return mat
+
+ def ResetTransform(self):
+ """
+ Reset the transform stack to the identity matrix
+ """
+ self.dc['transforms'] = []
+ self.RecomputeTransforms()
+
+ def _ComposeMatricesWithIdentity(self, mats):
+ """
+ Compose a sequence of matrices together by sequential
+ pre-mutiplciation with the identity matrix
+ """
+
+ x = self.xfrmIDENTITY
+
+ for mat in mats:
+ #precompose with each transform in turn
+ x = [
+ x[0] * mat[0] + x[1] * mat[3],
+ x[0] * mat[1] + x[1] * mat[4],
+ x[0] * mat[2] + x[1] * mat[5] + x[2],
+ x[3] * mat[0] + x[4] * mat[3],
+ x[3] * mat[1] + x[4] * mat[4],
+ x[3] * mat[2] + x[4] * mat[5] + x[5]]
+
+ return x
+
+ def RecomputeTransforms(self):
+ """
+ Re-compute the transform stack into a single transform and
+ store in the DC
+ """
+ self.dc['transform'] = self._ComposeMatricesWithIdentity(
+ self.dc['transforms'])
+
+ def TransformTranslate(self, x, y, push=True):
+ """
+ Set up and return a transform matrix representing a translartion
+ optionally pushing onto the stack
+
+ ( 1 0 x )
+ ( 0 1 y )
+ """
+ mat = [1, 0, x, 0, 1, y]
+
+ if push:
+ self.PushTransform(mat)
+ return mat
+
+ def TransformFlipOrigin(self, flip, push=True):
+ """
+ Set up and return a transform matrix representing a horizontal,
+ vertical or both flip about the origin
+ """
+ mat = None
+ if flip == self.flipX:
+ mat = [-1, 0, 0, 0, 1, 0]
+ elif flip == self.flipY:
+ mat = [1, 0, 0, 0, -1, 0]
+ elif flip == self.flipBoth:
+ mat = [-1, 0, 0, 0, -1, 0]
+ elif flip == self.flipNone:
+ mat = self.xfrmIDENTITY
+ else:
+ raise ValueError
+
+ if push:
+ self.PushTransform(mat)
+ return mat
+
+ def TransformFlip(self, x, y, flip=flipNone, push=True):
+ """
+ Set up and return a transform matrix representing a horizontal,
+ vertical or both flip about a point (x,y)
+
+ This is performed by a translate-to-origin, flip, translate-
+ back sequence
+ """
+ mats = [self.TransformTranslate(x, y, push=False),
+ self.TransformFlipOrigin(flip, push=False),
+ self.TransformTranslate(-x, -y, push=False)]
+
+ #distill into a single matrix
+ mat = self._ComposeMatricesWithIdentity(mats)
+
+ if push:
+ self.PushTransform(mat)
+ return mat
+
+ def TransformRotationOrigin(self, rot, push=True):
+ """
+ Set up and return a transform matrix representing a rotation
+ about the origin, and optionally push onto the stack
+
+ ( cos(t) -sin(t) 0 )
+ ( sin(t) cos(t) 0 )
+ """
+ rads = rot * math.pi / 180
+ mat = [math.cos(rads), -math.sin(rads), 0,
+ math.sin(rads), math.cos(rads), 0]
+
+ if push:
+ self.PushTransform(mat)
+ return mat
+
+ def TransformRotation(self, x, y, rot, push=True):
+ """
+ Set up and return a transform matrix representing a rotation
+ about the point (x,y), and optionally push onto the stack
+
+ This is performed by a translate-to-origin, rotate, translate-
+ back sequence
+ """
+
+ mats = [self.TransformTranslate(x, y, push=False),
+ self.TransformRotationOrigin(rot, push=False),
+ self.TransformTranslate(-x, -y, push=False)]
+
+ #distill into a single matrix
+ mat = self._ComposeMatricesWithIdentity(mats)
+
+ if push:
+ self.PushTransform(mat)
+ return mat
+
+ def TransformScaleOrigin(self, sx, sy=None, push=True):
+ """
+ Set up and return a transform matrix representing a scale about
+ the origin, and optionally push onto the stack
+
+ ( sx 0 0 )
+ ( 0 sy 0 )
+ """
+
+ if sy is None:
+ sy = sx
+
+ mat = [sx, 0, 0, 0, sy, 0]
+
+ if push:
+ self.PushTransform(mat)
+ return mat
+
+ def TransformPoint(self, x, y, mat=None):
+ """
+ Return a point (x, y) transformed by the given matrix, or if
+ that is not given, the drawing context transform
+ """
+
+ if not mat:
+ mat = self.dc['transform']
+
+ return pcbnew.wxPoint(x * mat[0] + y * mat[1] + mat[2],
+ x * mat[3] + y * mat[4] + mat[5])
+
+ def SetLineTickness(self, lineThickness):
+ """
+ Set the current pen lineThickness used for subsequent drawing
+ operations
+ """
+ self.dc['lineThickness'] = lineThickness
+
+ def GetLineTickness(self):
+ """
+ Get the current drawing context line tickness
+ """
+ return self.dc['lineThickness']
+
+ def SetLayer(self, layer):
+ """
+ Set the current drawing layer, used for subsequent drawing
+ operations
+ """
+ self.dc['layer'] = layer
+
+ def GetLayer(self):
+ """
+ return the current drawing layer, used drawing operations
+ """
+ return self.dc['layer']
+
+ def Line(self, x1, y1, x2, y2):
+ """
+ Draw a line from (x1, y1) to (x2, y2)
+ """
+ outline = pcbnew.EDGE_MODULE(self.module)
+ outline.SetWidth(self.GetLineTickness())
+ outline.SetLayer(self.GetLayer())
+ outline.SetShape(pcbnew.S_SEGMENT)
+ start = self.TransformPoint(x1, y1)
+ end = self.TransformPoint(x2, y2)
+ outline.SetStartEnd(start, end)
+ self.module.Add(outline)
+
+ def Circle(self, x, y, r, filled=False):
+ """
+ Draw a circle at (x,y) of radius r
+ If filled is true, the thickness and radius of the line will be set
+ such that the circle appears filled
+ """
+ circle = pcbnew.EDGE_MODULE(self.module)
+ start = self.TransformPoint(x, y)
+
+ if filled:
+ circle.SetWidth(r)
+ end = self.TransformPoint(x, y + r/2)
+ else:
+ circle.SetWidth(self.dc['lineThickness'])
+ end = self.TransformPoint(x, y + r)
+
+ circle.SetLayer(self.dc['layer'])
+ circle.SetShape(pcbnew.S_CIRCLE)
+ circle.SetStartEnd(start, end)
+ self.module.Add(circle)
+
+ def Arc(self, cx, cy, sx, sy, a):
+ """
+ Draw an arc based on centre, start and angle
+
+ The transform matrix is applied
+
+ Note that this won't work properly if the result is not a
+ circular arc (eg a horzontal scale)
+ """
+ circle = pcbnew.EDGE_MODULE(self.module)
+ circle.SetWidth(self.dc['lineThickness'])
+
+ center = self.TransformPoint(cx, cy)
+ start = self.TransformPoint(sx, sy)
+
+ circle.SetLayer(self.dc['layer'])
+ circle.SetShape(pcbnew.S_ARC)
+
+ # check if the angle needs to be reverse (a flip scaling)
+ if cmp(self.dc['transform'][0], 0) != cmp(self.dc['transform'][4], 0):
+ a = -a
+
+ circle.SetAngle(a)
+ circle.SetStartEnd(center, start)
+ self.module.Add(circle)
+
+ # extends from (x1,y1) right
+ def HLine(self, x, y, l):
+ """
+ Draw a horizontal line from (x,y), rightwards
+ """
+ self.Line(x, y, x + l, y)
+
+ def VLine(self, x, y, l):
+ """
+ Draw a vertical line from (x1,y1), downwards
+ """
+ self.Line(x, y, x, y + l)
+
+ def Polyline(self, pts, mirrorX=None, mirrorY=None):
+ """
+ Draw a polyline, optinally mirroring around the given points
+ """
+
+ def _PolyLineInternal(pts):
+ if len(pts) < 2:
+ return
+
+ for i in range(0, len(pts) - 1):
+ self.Line(pts[i][0], pts[i][1], pts[i+1][0], pts[i+1][1])
+
+ _PolyLineInternal(pts) # original
+
+ if mirrorX is not None:
+ self.TransformFlip(mirrorX, 0, self.flipX)
+ _PolyLineInternal(pts)
+ self.PopTransform()
+
+ if mirrorY is not None:
+ self.TransformFlipOrigin(0, mirrorY, self.flipY)
+ _PolyLineInternal(pts)
+ self.PopTransform()
+
+ if mirrorX is not None and mirrorY is not None:
+ self.TransformFlip(mirrorX, mirrorY, self.flipBoth) # both
+ _PolyLineInternal(pts)
+ self.PopTransform()
+
+ def Reference(self, x, y, size, orientation_degree = 0):
+ """
+ Draw the module's reference as the given point.
+
+ The actual setting of the reference is not done in this drawing
+ aid - that is up to the wizard
+ """
+
+ text_size = pcbnew.wxSize(size, size)
+
+ self.module.Reference().SetPos0(self.TransformPoint(x, y))
+ self.module.Reference().SetTextPosition(
+ self.module.Reference().GetPos0())
+ self.module.Reference().SetSize(text_size)
+ self.module.Reference().SetOrientation(orientation_degree*10) # internal angles are in 0.1 deg
+
+ def Value(self, x, y, size, orientation_degree = 0):
+ """
+ As for references, draw the module's value
+ """
+ text_size = pcbnew.wxSize(size, size)
+
+ self.module.Value().SetPos0(self.TransformPoint(x, y))
+ self.module.Value().SetTextPosition(self.module.Value().GetPos0())
+ self.module.Value().SetSize(text_size)
+ self.module.Value().SetLayer(self.DefaultTextValueLayer())
+ self.module.Value().SetOrientation(orientation_degree*10) # internal angles are in 0.1 deg
+
+ def Box(self, x, y, w, h):
+ """
+ Draw a rectangular box, centred at (x,y), with given width and
+ height
+ """
+
+ pts = [[x - w/2, y - h/2], # left
+ [x + w/2, y - h/2], # right
+ [x + w/2, y + h/2], # bottom
+ [x - w/2, y + h/2], # top
+ [x - w/2, y - h/2]] # close
+
+ self.Polyline(pts)
+
+ def NotchedCircle(self, x, y, r, notch_w, notch_h, rotate=0):
+ """
+ Circle radus r centred at (x, y) with a raised or depressed notch
+ at the top
+ Notch height is measured from the top of the circle radius
+ """
+
+ self.TransformRotation(x, y, rotate)
+
+ # find the angle where the notch vertical meets the circle
+ angle_intercept = math.asin(notch_w/(2 * r))
+
+ # and find the co-ords of this point
+ sx = math.sin(angle_intercept) * r
+ sy = -math.cos(angle_intercept) * r
+
+ # NOTE: this may be out by a factor of ten one day
+ arc_angle = (math.pi * 2 - angle_intercept * 2) * (1800/math.pi)
+
+ self.Arc(x,y, sx, sy, arc_angle)
+
+ pts = [[sx, sy],
+ [sx, -r - notch_h],
+ [-sx, -r - notch_h],
+ [-sx, sy]]
+
+ self.Polyline(pts)
+ self.PopTransform()
+
+ def NotchedBox(self, x, y, w, h, notchW, notchH, rotate=0):
+ """
+ Draw a box with a notch in the top edge
+ """
+
+ self.TransformRotation(x, y, rotate)
+
+ # limit to half the overall width
+ notchW = min(x + w/2, notchW)
+
+ # draw notch
+ self.Polyline([ # three sides of box
+ (x - w/2, y - h/2),
+ (x - w/2, y + h/2),
+ (x + w/2, y + h/2),
+ (x + w/2, y - h/2),
+ # the notch
+ (notchW/2, y - h/2),
+ (notchW/2, y - h/2 + notchH),
+ (-notchW/2, y - h/2 + notchH),
+ (-notchW/2, y - h/2),
+ (x - w/2, y - h/2)
+ ])
+
+ self.PopTransform()
+
+ def BoxWithDiagonalAtCorner(self, x, y, w, h,
+ setback=pcbnew.FromMM(1.27), flip=flipNone):
+ """
+ Draw a box with a diagonal at the top left corner
+ """
+
+ self.TransformFlip(x, y, flip, push=True)
+
+ pts = [[x - w/2 + setback, y - h/2],
+ [x - w/2, y - h/2 + setback],
+ [x - w/2, y + h/2],
+ [x + w/2, y + h/2],
+ [x + w/2, y - h/2],
+ [x - w/2 + setback, y - h/2]]
+
+ self.Polyline(pts)
+
+ self.PopTransform()
+
+ def BoxWithOpenCorner(self, x, y, w, h,
+ setback=pcbnew.FromMM(1.27), flip=flipNone):
+ """
+ Draw a box with an opening at the top left corner
+ """
+
+ self.TransformTranslate(x, y)
+ self.TransformFlipOrigin(flip)
+
+ pts = [[- w/2, - h/2 + setback],
+ [- w/2, + h/2],
+ [+ w/2, + h/2],
+ [+ w/2, - h/2],
+ [- w/2 + setback, - h/2]]
+
+ self.Polyline(pts)
+
+ self.PopTransform(num=2)
+
+ def MarkerArrow(self, x, y, direction=dirN, width=pcbnew.FromMM(1)):
+ """
+ Draw a marker arrow facing in the given direction, with the
+ point at (x,y)
+
+ Direction of 0 is north
+ """
+
+ self.TransformTranslate(x, y)
+ self.TransformRotationOrigin(direction)
+
+ pts = [[0, 0],
+ [width / 2, width / 2],
+ [-width / 2, width / 2],
+ [0, 0]]
+
+ self.Polyline(pts)
+ self.PopTransform(2)
diff --git a/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py b/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py
new file mode 100644
index 0000000..90d2498
--- /dev/null
+++ b/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py
@@ -0,0 +1,330 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+import pcbnew
+import math
+import FootprintWizardDrawingAids
+
+
+class FootprintWizardParameterManager:
+ """
+ Functions for helpfully managing parameters to a KiCAD Footprint
+ Wizard.
+
+ Abstracts away from whatever structure is used by pcbnew's footprint
+ wizard class
+ """
+
+ def __init__(self):
+ self.parameters = {}
+ self.GenerateParameterList()
+
+ def GenerateParameterList(self):
+ """
+ Construct parameters here, or leave out to have no parameters
+ """
+ pass
+
+ def CheckParameters(self):
+ """
+ Implement this to make checks on parameter values, filling
+ parameter_errors (or using the checker routines)
+
+ Subclasses can implment their own and override the parent
+ defaults and add new ones
+ """
+ pass
+
+ uMM = 1
+ uMils = 2
+ uNatural = 3
+ uBool = 4
+ uString = 5
+
+ def AddParam(self, section, param, unit, default, hint=''):
+ """
+ Add a parameter with some properties.
+
+ TODO: Hints are not supported, as there is as yet nowhere to
+ put them in the KiCAD interface
+ """
+ error = ""
+ val = None
+ if unit == self.uMM:
+ val = pcbnew.FromMM(default)
+ elif unit == self.uMils:
+ val = pcbnew.FromMils(default)
+ elif unit == self.uNatural:
+ val = default
+ elif unit == self.uString:
+ val = str(default)
+ elif unit == self.uBool:
+ val = "True" if default else "False" # ugly stringing
+ else:
+ error = "Warning: Unknown unit type: %s" % unit
+ return error
+
+ if unit in [self.uNatural, self.uBool, self.uString]:
+ param = "*%s" % param # star prefix for natural
+
+ if section not in self.parameters:
+ if not hasattr(self, 'page_order'):
+ self.page_order = []
+ self.page_order.append(section)
+ self.parameters[section] = {}
+ if not hasattr(self, 'parameter_order'):
+ self.parameter_order = {}
+ self.parameter_order[section] = []
+
+ self.parameters[section][param] = val
+ self.parameter_order[section].append(param)
+
+ return error
+
+
+ def _PrintParameterTable(self):
+ """
+ Pretty-print the parameters we have
+ """
+ message = ""
+
+ for name, section in self.parameters.iteritems():
+ message += " %s:\n" % name
+
+ for key, value in section.iteritems():
+ unit = ""
+ if ((type(value) is int or type(value) is float)
+ and not "*" in key):
+ unit = "mm"
+
+ if "*" in key:
+ key = key[1:]
+ else:
+ value = pcbnew.ToMM(value)
+
+ message += " %s: %s%s\n" % (key, value, unit)
+
+ return message
+
+
+ def _ParametersHaveErrors(self):
+ """
+ Return true if we discovered errors during parameter processing
+ """
+
+ for name, section in self.parameter_errors.iteritems():
+ for k, v in section.iteritems():
+ if v:
+ return True
+
+ return False
+
+ def _PrintParameterErrors(self):
+ """
+ Pretty-print parameters with errors
+ """
+ errors = ""
+
+ for name, section in self.parameter_errors.iteritems():
+ printed_section = False
+
+ for key, value in section.iteritems():
+ if value:
+ if not printed_section:
+ errors += " %s:" % name
+
+ errors += " %s: %s (have %s)\n" % (
+ key, value, self.parameters[name][key])
+
+ return errors
+
+ def ProcessParameters(self):
+ """
+ Make sure the parameters we have meet whatever expectations the
+ footprint wizard has of them
+ """
+
+ self.ClearErrors()
+ self.CheckParameters()
+
+ if self._ParametersHaveErrors():
+ return False
+
+ return True
+
+ #################################################################
+ # PARAMETER CHECKERS
+ #################################################################
+
+ def CheckParamInt(self, section, param, min_value=1,
+ max_value=None, is_multiple_of=1):
+ """
+ Make sure a parameter can be made into an int, and enforce
+ limits if required
+ """
+
+ try:
+ self.parameters[section][param] = (
+ int(self.parameters[section][param]))
+ except ValueError:
+ self.parameter_errors[section][param] = (
+ "Must be a valid integer")
+ return
+
+ if min_value is not None and (
+ self.parameters[section][param] < min_value):
+ self.parameter_errors[section][param] = (
+ "Must be greater than or equal to %d" % (min_value))
+ return
+
+ if max_value is not None and (
+ self.parameters[section][param] > max_value):
+ self.parameter_errors[section][param] = (
+ "Must be less than or equal to %d" % (max_value))
+ return
+
+ if is_multiple_of > 1 and (
+ self.parameters[section][param] % is_multiple_of) > 0:
+ self.parameter_errors[section][param] = (
+ "Must be a multiple of %d" % is_multiple_of)
+ return
+
+ return
+
+ def CheckParamBool(self, section, param):
+ """
+ Make sure a parameter looks like a boolean, convert to native
+ boolean type if so
+ """
+ if str(self.parameters[section][param]).lower() in [
+ "true", "t", "y", "yes", "on", "1", "1.0"]:
+ self.parameters[section][param] = True
+ return
+ elif str(self.parameters[section][param]).lower() in [
+ "false", "f", "n", "no", "off", "0", "0.0"]:
+ self.parameters[section][param] = False
+ return
+
+ self.parameter_errors[section][param] = "Must be boolean (true/false)"
+ return
+
+
+class HelpfulFootprintWizardPlugin(pcbnew.FootprintWizardPlugin,
+ FootprintWizardParameterManager):
+ """
+ A class to simplify many aspects of footprint creation, leaving only
+ the foot-print specific routines to the wizards themselves
+
+ Generally, you need to implement:
+ GetReference()
+ GetValue()
+ GenerateParameterList()
+ CheckParameters()
+ BuildThisFootprint()
+ GetName()
+ GetDescription()
+ """
+ def __init__(self):
+ pcbnew.FootprintWizardPlugin.__init__(self)
+ FootprintWizardParameterManager.__init__(self)
+
+ self.name = self.GetName()
+ self.decription = self.GetDescription()
+ self.image = self.GetImage()
+
+ def GetValue(self):
+ raise NotImplementedError
+
+ # this value come from our KiCad Library Convention 0.11
+ def GetReferencePrefix(self):
+ return "REF"
+
+ def GetImage(self):
+ return ""
+
+ def GetTextSize(self):
+ """
+ IPC nominal
+ """
+ return pcbnew.FromMM(1.2)
+
+ def GetTextThickness(self):
+ """
+ Thicker than IPC guidelines (10% of text height = 0.12mm)
+ as 5 wires/mm is a common silk screen limitation
+ """
+ return pcbnew.FromMM(0.15)
+
+ def SetModule3DModel(self):
+ """
+ Set a 3D model for the module
+
+ Default is to do nothing, you need to implement this if you have
+ a model to set
+
+ FIXME: This doesn't seem to be enabled yet?
+ """
+ pass
+
+ def BuildThisFootprint(self):
+ """
+ Draw the footprint.
+
+ This is specific to each footprint class, you need to implment
+ this to draw what you want
+ """
+ raise NotImplementedError
+
+ def BuildFootprint( self ):
+ """
+ Actually make the footprint. We defer all but the setup to
+ the implementing class
+ """
+
+ self.buildmessages = ""
+
+ self.module = pcbnew.MODULE(None) # create a new module
+ # do it first, so if we return early, we don't segfault KiCad
+
+ if not self.ProcessParameters():
+ self.buildmessages = "Cannot build footprint: Parameters have errors:\n"
+ self.buildmessages += self._PrintParameterErrors()
+ return
+
+ self.buildmessages = ("Building new %s footprint with the following parameters:\n"
+ % self.name)
+
+ self.buildmessages += self._PrintParameterTable()
+
+ self.draw = FootprintWizardDrawingAids.FootprintWizardDrawingAids(
+ self.module)
+
+ self.module.SetValue(self.GetValue())
+ self.module.SetReference("%s**" % self.GetReferencePrefix())
+
+ fpid = pcbnew.FPID(self.module.GetValue()) # the name in library
+ self.module.SetFPID(fpid)
+
+ self.SetModule3DModel() # add a 3d module if specified
+
+ thick = self.GetTextThickness()
+
+ self.module.Reference().SetThickness(thick)
+ self.module.Value().SetThickness(thick)
+
+ self.BuildThisFootprint() # implementer's build function
+
+ return
diff --git a/pcbnew/scripting/plugins/PadArray.py b/pcbnew/scripting/plugins/PadArray.py
new file mode 100644
index 0000000..5908d38
--- /dev/null
+++ b/pcbnew/scripting/plugins/PadArray.py
@@ -0,0 +1,275 @@
+# PadArray.py
+#
+# Copyright 2014 john <john@johndev>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+#
+
+from __future__ import division
+
+import math
+import pcbnew
+
+class PadMaker:
+ """
+ Useful construction functions for common types of pads
+ """
+
+ def __init__(self, module):
+ self.module = module
+
+ def THPad(self, Vsize, Hsize, drill, shape=pcbnew.PAD_SHAPE_OVAL, rot_degree = 0):
+ pad = pcbnew.D_PAD(self.module)
+ pad.SetSize(pcbnew.wxSize(Hsize, Vsize))
+ pad.SetShape(shape)
+ pad.SetAttribute(pcbnew.PAD_ATTRIB_STANDARD)
+ pad.SetLayerSet(pad.StandardMask())
+ pad.SetDrillSize(pcbnew.wxSize(drill, drill))
+ pad.SetOrientation(rot_degree*10) # rotation is in 0.1 degrees
+
+ return pad
+
+ def THRoundPad(self, size, drill):
+ pad = self.THPad(size, size, drill, shape=pcbnew.PAD_SHAPE_CIRCLE)
+ return pad
+
+ def NPTHRoundPad(self, drill):
+ pad = pcbnew.D_PAD(self.module)
+ pad.SetSize(pcbnew.wxSize(drill, drill))
+ pad.SetShape(pcbnew.PAD_SHAPE_CIRCLE)
+ pad.SetAttribute(pcbnew.PAD_ATTRIB_HOLE_NOT_PLATED)
+ pad.SetLayerSet(pad.UnplatedHoleMask())
+ pad.SetDrillSize(pcbnew.wxSize(drill, drill))
+ return pad
+
+ def SMDPad(self, Vsize, Hsize, shape=pcbnew.PAD_SHAPE_RECT, rot_degree=0):
+ pad = pcbnew.D_PAD(self.module)
+ pad.SetSize(pcbnew.wxSize(Hsize, Vsize))
+ pad.SetShape(shape)
+ pad.SetAttribute(pcbnew.PAD_ATTRIB_SMD)
+ pad.SetLayerSet(pad.SMDMask())
+ pad.SetOrientation(rot_degree*10) # rotation is in 0.1 degrees
+
+ return pad
+
+ def SMTRoundPad(self, size):
+ pad = self.SMDPad(size, size, shape=pcbnew.PAD_SHAPE_CIRCLE)
+ return pad
+
+
+class PadArray:
+
+ def __init__(self):
+ self.firstPadNum = 1
+ self.pinNames = None
+ self.firstPad = None
+
+ def SetPinNames(self, pinNames):
+ """
+ Set a name for all the pins
+ """
+ self.pinNames = pinNames
+
+ def SetFirstPadType(self, firstPad):
+ self.firstPad = firstPad
+
+ def SetFirstPadInArray(self, fpNum):
+ self.firstPadNum = fpNum
+
+ def AddPad(self, pad):
+ self.pad.GetParent().Add(pad)
+
+ def GetPad(self, is_first_pad, pos):
+ if (self.firstPad and is_first_pad):
+ pad = self.firstPad
+ else:
+ pad = self.pad
+
+ # create a new pad with same characteristics
+ pad = pad.Duplicate()
+ pad.SetPos0(pos)
+ pad.SetPosition(pos)
+
+ return pad
+
+ def GetName(self, *args, **kwargs):
+
+ if self.pinNames is None:
+ return self.NamingFunction(*args, **kwargs)
+
+ return self.pinNames
+
+ def NamingFunction(self, *args, **kwargs):
+ """
+ Implement this as needed for each array type
+ """
+ raise NotImplementedError;
+
+
+class PadGridArray(PadArray):
+
+ def __init__(self, pad, nx, ny, px, py, centre=pcbnew.wxPoint(0, 0)):
+ PadArray.__init__(self)
+ # this pad is more of a "context", we will use it as a source of
+ # pad data, but not actually add it
+ self.pad = pad
+ self.nx = int(nx)
+ self.ny = int(ny)
+ self.px = px
+ self.py = py
+ self.centre = centre
+
+ # handy utility function 1 - A, 2 - B, 26 - AA, etc
+ # aIndex = 0 for 0 - A
+ # alphabet = set of allowable chars if not A-Z,
+ # eg ABCDEFGHJKLMNPRTUVWY for BGA
+ def AlphaNameFromNumber(self, n, aIndex=1,
+ alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
+
+ div, mod = divmod(n - aIndex, len(alphabet))
+ alpha = alphabet[mod]
+
+ if div > 0:
+ return self.AlphaNameFromNumber(div, aIndex, alphabet) + alpha
+
+ return alpha
+
+ # right to left, top to bottom
+ def NamingFunction(self, x, y):
+ return self.firstPadNum + (self.nx * y + x)
+
+ #relocate the pad and add it as many times as we need
+ def AddPadsToModule(self, dc):
+
+ pin1posX = self.centre.x - self.px * (self.nx - 1) / 2
+ pin1posY = self.centre.y - self.py * (self.ny - 1) / 2
+
+ for x in range(0, self.nx):
+ posX = pin1posX + (x * self.px)
+
+ for y in range(self.ny):
+ posY = pin1posY + (self.py * y)
+ pos = dc.TransformPoint(posX, posY)
+ pad = self.GetPad(x == 0 and y == 0, pos)
+ pad.SetPadName(self.GetName(x,y))
+ self.AddPad(pad)
+
+
+class PadZGridArray(PadArray):
+
+ def __init__(self, pad, pad_count, line_count, line_pitch,
+ pad_pitch, centre=pcbnew.wxPoint(0, 0)):
+ PadArray.__init__(self)
+ # this pad is more of a "context", we will use it as a source of
+ # pad data, but not actually add it
+ self.pad = pad
+ self.pad_count = int(pad_count)
+ self.line_count = int(line_count)
+ self.line_pitch = line_pitch
+ self.pad_pitch = pad_pitch
+ self.centre = centre
+
+
+ # right to left, top to bottom
+ def NamingFunction(self, pad_pos):
+ return self.firstPadNum + pad_pos
+
+ #relocate the pad and add it as many times as we need
+ def AddPadsToModule(self, dc):
+
+ pin1posX = self.centre.x - self.pad_pitch * (self.pad_count - 1) / 2
+ pin1posY = self.centre.y + self.line_pitch * (self.line_count - 1) / 2
+ line = 0
+
+ for padnum in range(0, self.pad_count):
+ posX = pin1posX + (padnum * self.pad_pitch)
+ posY = pin1posY - (self.line_pitch * line)
+
+ pos = dc.TransformPoint(posX, posY)
+ pad = self.GetPad(padnum == 0, pos)
+ pad.SetPadName(self.GetName(padnum))
+ self.AddPad(pad)
+
+ line += 1
+
+ if line >= self.line_count:
+ line = 0
+
+class PadLineArray(PadGridArray):
+
+ def __init__(self, pad, n, pitch, isVertical,
+ centre=pcbnew.wxPoint(0, 0)):
+
+ if isVertical:
+ PadGridArray.__init__(self, pad, 1, n, 0, pitch, centre)
+ else:
+ PadGridArray.__init__(self, pad, n, 1, pitch, 0, centre)
+
+class PadCircleArray(PadArray):
+
+ def __init__(self, pad, n, r, angle_offset=0, centre=pcbnew.wxPoint(0, 0),
+ clockwise=True):
+ PadArray.__init__(self)
+ # this pad is more of a "context", we will use it as a source of
+ # pad data, but not actually add it
+ self.pad = pad
+ self.n = int(n)
+ self.r = r
+ self.angle_offset = angle_offset
+ self.centre = centre
+ self.clockwise = clockwise
+
+ # around the circle, CW or CCW according to the flag
+ def NamingFunction(self, n):
+ return str(self.firstPadNum + n)
+
+ #relocate the pad and add it as many times as we need
+ def AddPadsToModule(self, dc):
+ for pin in range(0, self.n):
+ angle = self.angle_offset + (360 / self.n) * pin
+
+ if not self.clockwise:
+ angle = -angle
+
+ pos_x = math.sin(angle * math.pi / 180) * self.r
+ pos_y = -math.cos(angle * math.pi / 180) * self.r
+ pos = dc.TransformPoint(pos_x, pos_y)
+ pad = self.GetPad(pin == 0, pos)
+ pad.SetPadName(self.GetName(pin))
+ self.AddPad(pad)
+
+class PadCustomArray(PadArray):
+ """
+ Layout pads according to a custom array of [x,y] data
+ """
+
+ def __init__(self, pad, array):
+ PadArray.__init__(self)
+ self.pad = pad
+ self.array = array
+
+ def NamingFunction(self, n):
+ return str(self.firstPadNum + n)
+
+ #relocate the pad and add it as many times as we need
+ def AddPadsToModule(self, dc):
+
+ for i in range(len(self.array)):
+ pos = dc.TransformPoint(self.array[i][0], self.array[i][1])
+ pad = self.GetPad(i == 0, pos)
+ pad.SetPadName(self.GetName(i))
+ self.AddPad(pad)
diff --git a/pcbnew/scripting/plugins/__init__.py b/pcbnew/scripting/plugins/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pcbnew/scripting/plugins/__init__.py
@@ -0,0 +1 @@
+
diff --git a/pcbnew/scripting/plugins/bga_wizard.py b/pcbnew/scripting/plugins/bga_wizard.py
new file mode 100644
index 0000000..ed3500f
--- /dev/null
+++ b/pcbnew/scripting/plugins/bga_wizard.py
@@ -0,0 +1,98 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+from __future__ import division
+import pcbnew
+
+import HelpfulFootprintWizardPlugin as HFPW
+import PadArray as PA
+
+
+class BGAPadGridArray(PA.PadGridArray):
+
+ def NamingFunction(self, n_x, n_y):
+ return "%s%d" % (
+ self.AlphaNameFromNumber(n_y + 1, alphabet="ABCDEFGHJKLMNPRTUVWY"),
+ n_x + 1)
+
+
+class BGAWizard(HFPW.HelpfulFootprintWizardPlugin):
+
+ def GetName(self):
+ return "BGA"
+
+ def GetDescription(self):
+ return "Ball Grid Array Footprint Wizard"
+
+ def GenerateParameterList(self):
+ self.AddParam("Pads", "pad pitch", self.uMM, 1)
+ self.AddParam("Pads", "pad size", self.uMM, 0.5)
+ self.AddParam("Pads", "row count", self.uNatural, 5)
+ self.AddParam("Pads", "column count", self.uNatural, 5)
+ self.AddParam("Pads", "outline x margin", self.uMM, 1)
+ self.AddParam("Pads", "outline y margin", self.uMM, 1)
+
+ def CheckParameters(self):
+ self.CheckParamInt("Pads", "*row count")
+ self.CheckParamInt("Pads", "*column count")
+
+ def GetValue(self):
+ pins = (self.parameters["Pads"]["*row count"]
+ * self.parameters["Pads"]["*column count"])
+
+ return "BGA_%d" % pins
+
+ def BuildThisFootprint(self):
+
+ pads = self.parameters["Pads"]
+
+ rows = pads["*row count"]
+ cols = pads["*column count"]
+ pad_size = pads["pad size"]
+ pad_size = pcbnew.wxSize(pad_size, pad_size)
+ pad_pitch = pads["pad pitch"]
+
+ # add in the pads
+ pad = PA.PadMaker(self.module).SMTRoundPad(pads["pad size"])
+
+ pin1_pos = pcbnew.wxPoint(-((cols - 1) * pad_pitch) / 2,
+ -((rows - 1) * pad_pitch) / 2)
+
+ array = BGAPadGridArray(pad, cols, rows, pad_pitch, pad_pitch)
+ array.AddPadsToModule(self.draw)
+
+ #box
+ ssx = -pin1_pos.x + pads["outline x margin"]
+ ssy = -pin1_pos.y + pads["outline y margin"]
+
+ self.draw.BoxWithDiagonalAtCorner(0, 0, ssx*2, ssy*2,
+ pads["outline x margin"])
+
+ # Courtyard
+ cmargin = self.draw.GetLineTickness()
+ self.draw.SetLayer(pcbnew.F_CrtYd)
+ sizex = (ssx + cmargin) * 2
+ sizey = (ssy + cmargin) * 2
+ self.draw.Box(0, 0, sizex, sizey)
+
+ #reference and value
+ text_size = self.GetTextSize() # IPC nominal
+ ypos = ssy + text_size
+ self.draw.Value(0, ypos, text_size)
+ self.draw.Reference(0, -ypos, text_size)
+
+
+BGAWizard().register()
diff --git a/pcbnew/scripting/plugins/circular_pad_array_wizard.py b/pcbnew/scripting/plugins/circular_pad_array_wizard.py
new file mode 100644
index 0000000..0b2a280
--- /dev/null
+++ b/pcbnew/scripting/plugins/circular_pad_array_wizard.py
@@ -0,0 +1,83 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+from __future__ import division
+
+import math
+
+import pcbnew
+import HelpfulFootprintWizardPlugin as HFPW
+import PadArray as PA
+
+
+class circular_pad_array_wizard(HFPW.HelpfulFootprintWizardPlugin):
+
+ def GetName(self):
+ return "Circular Pad Array"
+
+ def GetDescription(self):
+ return "Circular array of pads"
+
+ def GenerateParameterList(self):
+
+ self.AddParam("Pads", "n", self.uNatural, 6)
+ self.AddParam("Pads", "pad width", self.uMM, 1.5)
+ self.AddParam("Pads", "drill", self.uMM, 1)
+ self.AddParam("Pads", "circle diameter", self.uMM, 5)
+ self.AddParam("Pads", "first pad angle", self.uNatural, 0)
+ self.AddParam("Pads", "number clockwise", self.uBool, True)
+ self.AddParam("Pads", "first pad number", self.uNatural, 1)
+
+ def CheckParameters(self):
+
+ self.CheckParamInt("Pads", "*n")
+ self.CheckParamInt("Pads", "*first pad number")
+ self.CheckParamBool("Pads", "*number clockwise")
+
+ def GetValue(self):
+ pins = self.parameters["Pads"]["*n"]
+ return "CPA_%d" % pins
+
+ def BuildThisFootprint(self):
+
+ prm = self.parameters['Pads']
+
+ pad_size = prm['pad width']
+
+ pad = PA.PadMaker(self.module).THPad(
+ prm['pad width'], prm['pad width'], prm['drill'])
+
+ array = PA.PadCircleArray(
+ pad, prm['*n'], prm['circle diameter'] / 2,
+ angle_offset=prm["*first pad angle"],
+ centre=pcbnew.wxPoint(0, 0),
+ clockwise=prm["*number clockwise"])
+
+ array.SetFirstPadInArray(prm["*first pad number"])
+
+ array.AddPadsToModule(self.draw)
+
+ body_radius = (prm['circle diameter'] + prm['pad width'])/2 + self.draw.GetLineTickness()
+ self.draw.Circle(0, 0, body_radius)
+
+ text_size = self.GetTextSize() # IPC nominal
+ thickness = self.GetTextThickness()
+ textposy = body_radius + self.draw.GetLineTickness()/2 + self.GetTextSize()/2 + thickness
+ self.draw.Value( 0, textposy, text_size )
+ self.draw.Reference( 0, -textposy, text_size )
+
+
+
+circular_pad_array_wizard().register()
diff --git a/pcbnew/scripting/plugins/qfp_wizard.py b/pcbnew/scripting/plugins/qfp_wizard.py
new file mode 100644
index 0000000..3cd1eda
--- /dev/null
+++ b/pcbnew/scripting/plugins/qfp_wizard.py
@@ -0,0 +1,125 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+from __future__ import division
+import pcbnew
+
+import HelpfulFootprintWizardPlugin
+import PadArray as PA
+
+
+class QFPWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):
+
+ def GetName(self):
+ return "QFP"
+
+ def GetDescription(self):
+ return "Quad Flat Package footprint wizard"
+
+ def GenerateParameterList(self):
+ self.AddParam("Pads", "n", self.uNatural, 100)
+ self.AddParam("Pads", "pad pitch", self.uMM, 0.5)
+ self.AddParam("Pads", "pad width", self.uMM, 0.25)
+ self.AddParam("Pads", "pad length", self.uMM, 1.5)
+ self.AddParam("Pads", "vertical pitch", self.uMM, 15)
+ self.AddParam("Pads", "horizontal pitch", self.uMM, 15)
+ self.AddParam("Pads", "oval", self.uBool, True)
+
+ self.AddParam("Package", "package width", self.uMM, 14)
+ self.AddParam("Package", "package height", self.uMM, 14)
+ self.AddParam("Package", "courtyard margin", self.uMM, 1)
+
+ def CheckParameters(self):
+ self.CheckParamInt("Pads", "*n", is_multiple_of=4)
+ self.CheckParamBool("Pads", "*oval")
+
+ def GetValue(self):
+ return "QFP_%d" % self.parameters["Pads"]["*n"]
+
+ def BuildThisFootprint(self):
+ pads = self.parameters["Pads"]
+
+ pad_pitch = pads["pad pitch"]
+ pad_length = self.parameters["Pads"]["pad length"]
+ pad_width = self.parameters["Pads"]["pad width"]
+
+ v_pitch = pads["vertical pitch"]
+ h_pitch = pads["horizontal pitch"]
+
+ pads_per_row = pads["*n"] // 4
+
+ row_len = (pads_per_row - 1) * pad_pitch
+
+ pad_shape = pcbnew.PAD_SHAPE_OVAL if pads["*oval"] else pcbnew.PAD_SHAPE_RECT
+
+ h_pad = PA.PadMaker(self.module).SMDPad( pad_length, pad_width,
+ shape=pad_shape, rot_degree=90.0)
+ v_pad = PA.PadMaker(self.module).SMDPad( pad_length, pad_width, shape=pad_shape)
+
+ #left row
+ pin1Pos = pcbnew.wxPoint(-h_pitch / 2, 0)
+ array = PA.PadLineArray(h_pad, pads_per_row, pad_pitch, True, pin1Pos)
+ array.SetFirstPadInArray(1)
+ array.AddPadsToModule(self.draw)
+
+ #bottom row
+ pin1Pos = pcbnew.wxPoint(0, v_pitch / 2)
+ array = PA.PadLineArray(v_pad, pads_per_row, pad_pitch, False, pin1Pos)
+ array.SetFirstPadInArray(pads_per_row + 1)
+ array.AddPadsToModule(self.draw)
+
+ #right row
+ pin1Pos = pcbnew.wxPoint(h_pitch / 2, 0)
+ array = PA.PadLineArray(h_pad, pads_per_row, -pad_pitch, True,
+ pin1Pos)
+ array.SetFirstPadInArray(2*pads_per_row + 1)
+ array.AddPadsToModule(self.draw)
+
+ #top row
+ pin1Pos = pcbnew.wxPoint(0, -v_pitch / 2)
+ array = PA.PadLineArray(v_pad, pads_per_row, -pad_pitch, False,
+ pin1Pos)
+ array.SetFirstPadInArray(3*pads_per_row + 1)
+ array.AddPadsToModule(self.draw)
+
+ lim_x = self.parameters["Package"]["package width"] / 2
+ lim_y = self.parameters["Package"]["package height"] / 2
+ inner = (row_len / 2) + pad_pitch
+
+ #top left - diagonal
+ self.draw.Line(-lim_x, -inner, -inner, -lim_y)
+ # top right
+ self.draw.Polyline([(inner, -lim_y), (lim_x, -lim_y), (lim_x, -inner)])
+ # bottom left
+ self.draw.Polyline([(-inner, lim_y), (-lim_x, lim_y), (-lim_x, inner)])
+ # bottom right
+ self.draw.Polyline([(inner, lim_y), (lim_x, lim_y), (lim_x, inner)])
+
+ # Courtyard
+ cmargin = self.parameters["Package"]["courtyard margin"]
+ self.draw.SetLayer(pcbnew.F_CrtYd)
+ sizex = (lim_x + cmargin) * 2 + pad_length
+ sizey = (lim_y + cmargin) * 2 + pad_length
+ self.draw.Box(0, 0, sizex, sizey)
+
+ #reference and value
+ text_size = self.GetTextSize() # IPC nominal
+ text_offset = v_pitch / 2 + text_size + pad_length / 2
+
+ self.draw.Value(0, text_offset, text_size)
+ self.draw.Reference(0, -text_offset, text_size)
+
+QFPWizard().register()
diff --git a/pcbnew/scripting/plugins/sdip_wizard.py b/pcbnew/scripting/plugins/sdip_wizard.py
new file mode 100644
index 0000000..31f53cd
--- /dev/null
+++ b/pcbnew/scripting/plugins/sdip_wizard.py
@@ -0,0 +1,237 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+from __future__ import division
+import pcbnew
+
+import HelpfulFootprintWizardPlugin as HFPW
+import PadArray as PA
+
+
+class RowedGridArray(PA.PadGridArray):
+
+ def NamingFunction(self, x, y):
+ pad_cnt = self.nx*self.ny
+
+ if self.ny == 1:
+ return x+1
+
+ if (y % 2) == 0: # upper row, count down
+ return pad_cnt-x
+ else: # lower row, count up
+ return x+1
+
+
+class RowedFootprint(HFPW.HelpfulFootprintWizardPlugin):
+
+ pad_count_key = 'pas count'
+ row_count_key = 'row count'
+ row_spacing_key = 'row spacing'
+ pad_length_key = 'pad length'
+ pad_width_key = 'pad width'
+ pad_pitch_key = 'pad pitch'
+
+ silkscreen_inside_key = 'silk screen inside'
+ outline_x_margin_key = 'outline x margin'
+ outline_y_margin_key = 'outline y margin'
+
+ def GenerateParameterList(self):
+ # defaults for a DIP package
+ self.AddParam("Pads", self.pad_count_key, self.uNatural, 24)
+ self.AddParam("Pads", self.row_count_key, self.uNatural, 2)
+
+ self.AddParam("Body", self.silkscreen_inside_key, self.uBool, False)
+ self.AddParam("Body", self.outline_x_margin_key, self.uMM, 0.5)
+ self.AddParam("Body", self.outline_y_margin_key, self.uMM, 0.5)
+
+ def CheckParameters(self):
+ self.CheckParamInt("Pads", '*' + self.row_count_key, min_value=1, max_value=2)
+ self.CheckParamInt(
+ "Pads", '*' + self.pad_count_key,
+ is_multiple_of=self.parameters["Pads"]['*' + self.row_count_key])
+
+ # can do this internally to parameter manager?
+ self.CheckParamBool("Body", '*' + self.silkscreen_inside_key)
+
+ def BuildThisFootprint(self):
+ pads = self.parameters["Pads"]
+ body = self.parameters["Body"]
+ num_pads = pads['*' + self.pad_count_key]
+ pad_length = pads[self.pad_length_key]
+ pad_width = pads[self.pad_width_key]
+ row_pitch = pads[self.row_spacing_key]
+ pad_pitch = pads[self.pad_pitch_key]
+ num_rows = pads['*' + self.row_count_key]
+
+ pads_per_row = num_pads // num_rows
+
+ # add in the pads
+ pad = self.GetPad()
+
+ array = RowedGridArray(pad, pads_per_row, num_rows, pad_pitch, row_pitch)
+ array.AddPadsToModule(self.draw)
+
+ # draw the Silk Screen
+ Hsize = pad_pitch * (num_pads / num_rows - 1)
+ Vsize = row_pitch * (num_rows - 1)
+ pin1_posY = -Vsize / 2
+ pin1_posX = -Hsize / 2
+
+ pad_length = pads[self.pad_length_key]
+ pad_width = pads[self.pad_width_key]
+
+ ssx_offset = -pad_width / 2 - body[self.outline_x_margin_key]
+ ssy_offset = -pad_length / 2 - body[self.outline_y_margin_key]
+
+ if body['*' + self.silkscreen_inside_key]:
+ ssy_offset *= -1
+
+ ssx = -pin1_posX - ssx_offset
+ ssy = -pin1_posY - ssy_offset
+
+ self.DrawBox(ssx, ssy)
+
+ #reference and value
+ text_size = self.GetTextSize() # IPC nominal
+
+ if num_rows == 1:
+ text_py = ssy + text_size
+ self.draw.Value(0, -text_py, text_size)
+ self.draw.Reference(0, text_py, text_size)
+ else:
+ text_px = ssx + text_size
+ # self.draw.Value(text_px, 0, text_size, orientation_degree=90)
+ self.draw.Value(0, 0, text_size)
+ self.draw.Reference(-text_px, 0, text_size, orientation_degree=90)
+
+
+class SDIPWizard(RowedFootprint):
+
+ def GetName(self):
+ return "S-DIP"
+
+ def GetDescription(self):
+ return "Single/Dual Inline Package Footprint Wizard"
+
+ def GenerateParameterList(self):
+ RowedFootprint.GenerateParameterList(self)
+
+ self.AddParam("Pads", self.pad_pitch_key, self.uMM, 2.54)
+ self.AddParam("Pads", self.pad_width_key, self.uMM, 1.2)
+ self.AddParam("Pads", self.pad_length_key, self.uMM, 2)
+ self.AddParam("Pads", self.row_spacing_key, self.uMM, 7.52)
+ self.AddParam("Pads", "drill size", self.uMM, 0.8)
+
+ def GetValue(self):
+ pads = self.parameters["Pads"]
+ rows = pads['*' + self.row_count_key]
+ pad_count = pads['*' + self.pad_count_key]
+ row_dist_mil = pcbnew.Iu2Mils(int(self.parameters["Pads"][self.row_spacing_key])) #int(self.parameters["Pads"][self.row_spacing_key] / 2.54 * 100)
+ pad_shape = ""
+
+ if pads[self.pad_width_key] != pads[self.pad_length_key]:
+ pad_shape = '_ELL'
+
+ if rows == 1:
+ name = "SIP"
+ return "%s-%d" % (name, pad_count)
+
+ name = "DIP"
+ return "%s-%d_%d%s" % (name, pad_count, row_dist_mil, pad_shape)
+
+ def GetPad(self):
+ pad_length = self.parameters["Pads"][self.pad_length_key]
+ pad_width = self.parameters["Pads"][self.pad_width_key]
+ drill = self.parameters["Pads"]["drill size"]
+ shape = pcbnew.PAD_SHAPE_CIRCLE
+
+ if pad_length != pad_width:
+ shape = pcbnew.PAD_SHAPE_OVAL
+
+ return PA.PadMaker(self.module).THPad(
+ pad_length, pad_width, drill, shape=shape)
+
+ def DrawBox(self, ssx, ssy):
+
+ if self.parameters["Pads"]['*' + self.row_count_key] == 2:
+
+ # ----------
+ # |8 7 6 5 |
+ # > |
+ # |1 2 3 4 |
+ # ----------
+
+ # draw the notch
+ notchWidth = ssy/1.5
+ notchHeight = self.draw.GetLineTickness()*3
+
+ # NotchedBox draws the notch on top. Rotate the box 90 degrees
+ # to have it on the left
+ self.draw.NotchedBox(0, 0, ssy*2, ssx*2, notchWidth, notchHeight, -90)
+ else:
+ # -----------------
+ # |1|2 3 4 5 6 7 8|
+ # -----------------
+ self.draw.Box(0, 0, ssx*2, ssy*2)
+
+ #line between pin1 and pin2
+ pad_pitch = self.parameters["Pads"][self.pad_pitch_key]
+ pad_cnt = self.parameters["Pads"]['*' + self.pad_count_key]
+ line_x = ( pad_cnt/2 - 1) * pad_pitch
+ self.draw.VLine(-line_x, -ssy, ssy * 2)
+
+ return ssx, ssy
+
+SDIPWizard().register()
+
+
+class SOICWizard(RowedFootprint):
+
+ def GetName(self):
+ return "SOIC"
+
+ def GetDescription(self):
+ return "SOIC, MSOP, SSOP, TSSOP, etc, footprint wizard"
+
+ def GetValue(self):
+ pad_count = self.parameters["Pads"]['*' + self.pad_count_key]
+ return "%s-%d" % ("SOIC", pad_count)
+
+ def GenerateParameterList(self):
+ RowedFootprint.GenerateParameterList(self)
+
+ #and override some of them
+ self.AddParam("Pads", self.pad_pitch_key, self.uMM, 1.27)
+ self.AddParam("Pads", self.pad_width_key, self.uMM, 0.6)
+ self.AddParam("Pads", self.pad_length_key, self.uMM, 2.2)
+ self.AddParam("Pads", self.row_spacing_key, self.uMM, 5.2)
+
+ def GetPad(self):
+ pad_length = self.parameters["Pads"][self.pad_length_key]
+ pad_width = self.parameters["Pads"][self.pad_width_key]
+ return PA.PadMaker(self.module).SMDPad(
+ pad_length, pad_width, shape=pcbnew.PAD_SHAPE_RECT)
+
+ def DrawBox(self, ssx, ssy):
+
+ # ----------
+ # |8 7 6 5 |
+ # |1 2 3 4 |
+ # \---------
+
+ self.draw.BoxWithDiagonalAtCorner(0, 0, ssx*2, ssy*2, pcbnew.FromMM(1))
+
+SOICWizard().register()
diff --git a/pcbnew/scripting/plugins/touch_slider_wizard.py b/pcbnew/scripting/plugins/touch_slider_wizard.py
new file mode 100644
index 0000000..ee2ae53
--- /dev/null
+++ b/pcbnew/scripting/plugins/touch_slider_wizard.py
@@ -0,0 +1,205 @@
+#!/usr/bin/python
+
+#
+# This program source code file is part of KiCad, a free EDA CAD application.
+#
+# Copyright (C) 2012-2014 KiCad Developers, see change_log.txt for contributors.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, you may find one here:
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# or you may search the http://www.gnu.org website for the version 2 license,
+# or you may write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+
+from pcbnew import *
+import HelpfulFootprintWizardPlugin as HFPW
+
+
+class TouchSliderWizard(HFPW.HelpfulFootprintWizardPlugin):
+
+ def GetName(self):
+ """
+ Return footprint name.
+ This is specific to each footprint class, you need to implement this
+ """
+ return 'Touch Slider'
+
+ def GetDescription(self):
+ """
+ Return footprint description.
+ This is specific to each footprint class, you need to implement this
+ """
+ return 'Capacitive Touch Slider wizard'
+
+ def GetValue(self):
+ steps = int(self.parameters["Pads"]["*steps"])
+ return "TS"+str(steps)
+
+ def GenerateParameterList(self):
+ self.AddParam("Pads", "steps", self.uNatural, 4)
+ self.AddParam("Pads", "bands", self.uNatural, 2)
+ self.AddParam("Pads", "width", self.uMM, 10)
+ self.AddParam("Pads", "length", self.uMM, 50)
+ self.AddParam("Pads", "clearance", self.uMM, 1)
+
+ # build a rectangular pad
+ def smdRectPad(self,module,size,pos,name):
+ pad = D_PAD(module)
+ pad.SetSize(size)
+ pad.SetShape(PAD_SHAPE_RECT)
+ pad.SetAttribute(PAD_ATTRIB_SMD)
+ pad.SetLayerSet(pad.ConnSMDMask())
+ pad.SetPos0(pos)
+ pad.SetPosition(pos)
+ pad.SetPadName(name)
+ return pad
+
+
+ def smdTrianglePad(self,module,size,pos,name,up_down=1,left_right=0):
+ pad = D_PAD(module)
+ pad.SetSize(wxSize(size[0],size[1]))
+ pad.SetShape(PAD_SHAPE_TRAPEZOID)
+ pad.SetAttribute(PAD_ATTRIB_SMD)
+ pad.SetLayerSet(pad.ConnSMDMask())
+ pad.SetPos0(pos)
+ pad.SetPosition(pos)
+ pad.SetPadName(name)
+ pad.SetDelta(wxSize(left_right*size[1],up_down*size[0]))
+ return pad
+
+
+ # This method checks the parameters provided to wizard and set errors
+ def CheckParameters(self):
+ prms = self.parameters["Pads"]
+ steps = prms["*steps"]
+ bands = prms["*bands"]
+
+ if steps < 1:
+ self.parameter_errors["Pads"]["*steps"]="steps must be positive"
+ if bands < 1:
+ self.parameter_errors["Pads"]["*bands"]="bands must be positive"
+
+ touch_width = prms["width"]
+ touch_length = prms["length"]
+ touch_clearance = prms["clearance"]
+
+ # The start pad is made of a rectangular pad plus a couple of
+ # triangular pads facing tips on the middle/right of the first
+ # rectangular pad
+ def AddStartPad(self,position,touch_width,step_length,clearance,name):
+ module = self.module
+ step_length = step_length - clearance
+ size_pad = wxSize(step_length/2.0+(step_length/3),touch_width)
+ pad = self.smdRectPad(module,size_pad,position-wxPoint(step_length/6,0),name)
+ module.Add(pad)
+
+ size_pad = wxSize(step_length/2.0,touch_width)
+
+ tp = self.smdTrianglePad(module,wxSize(size_pad[0],size_pad[1]/2),
+ position+wxPoint(size_pad[0]/2,size_pad[1]/4),
+ name)
+ module.Add(tp)
+ tp = self.smdTrianglePad(module,wxSize(size_pad[0],size_pad[1]/2),
+ position+wxPoint(size_pad[0]/2,-size_pad[1]/4),
+ name
+ ,-1)
+ module.Add(tp)
+
+ # compound a "start pad" shape plus a triangle on the left, pointing to
+ # the previous touch-pad
+ def AddMiddlePad(self,position,touch_width,step_length,clearance,name):
+ module = self.module
+ step_length = step_length - clearance
+ size_pad = wxSize(step_length/2.0,touch_width)
+
+ size_pad = wxSize(step_length/2.0,touch_width)
+ pad = self.smdRectPad(module,size_pad,position,name)
+ module.Add(pad)
+
+ tp = self.smdTrianglePad(module,wxSize(size_pad[0],size_pad[1]/2),
+ position+wxPoint(size_pad[0]/2,size_pad[1]/4),
+ name)
+ module.Add(tp)
+ tp = self.smdTrianglePad(module,wxSize(size_pad[0],size_pad[1]/2),
+ position+wxPoint(size_pad[0]/2,-size_pad[1]/4),
+ name
+ ,-1)
+ module.Add(tp)
+
+ tp = self.smdTrianglePad(module,wxSize(size_pad[0],size_pad[1]/2),
+ position+wxPoint(-size_pad[0],0),
+ name,
+ 0,
+ -1)
+ module.Add(tp)
+
+
+ def AddFinalPad(self,position,touch_width,step_length,clearance,name):
+ module = self.module
+ step_length = step_length - clearance
+ size_pad = wxSize(step_length/2.0,touch_width)
+
+ pad = self.smdRectPad(module,
+ wxSize(size_pad[0]+(step_length/3),size_pad[1]),
+ position+wxPoint(step_length/6,0),
+ name)
+ module.Add(pad)
+
+ tp = self.smdTrianglePad(module,wxSize(size_pad[0],size_pad[1]/2),
+ position+wxPoint(-size_pad[0],0),
+ name,
+ 0,
+ -1)
+ module.Add(tp)
+
+ def AddStrip(self,pos,steps,touch_width,step_length,touch_clearance):
+ self.AddStartPad(pos,touch_width,step_length,touch_clearance,"1")
+
+ for n in range(2,steps):
+ pos = pos + wxPoint(step_length,0)
+ self.AddMiddlePad(pos,touch_width,step_length,touch_clearance,str(n))
+
+ pos = pos + wxPoint(step_length,0)
+ self.AddFinalPad(pos,touch_width,step_length,touch_clearance,str(steps))
+
+ # build the footprint from parameters
+ # FIX ME: the X and Y position of the footprint can be better.
+ def BuildThisFootprint(self):
+ prm = self.parameters["Pads"]
+ steps = int(prm["*steps"])
+ bands = int(prm["*bands"])
+ touch_width = prm["width"]
+ touch_length = prm["length"]
+ touch_clearance = prm["clearance"]
+
+ step_length = float(touch_length) / float(steps)
+
+ t_size = self.GetTextSize()
+ w_text = self.draw.GetLineTickness()
+ ypos = touch_width/(bands*2) + t_size/2 + w_text
+ self.draw.Value(0, -ypos, t_size)
+ ypos += t_size + w_text*2
+ self.draw.Reference(0, -ypos, t_size)
+
+ # starting pad
+ pos = wxPointMM(0,0)
+ band_width = touch_width/bands
+
+ for b in range(bands):
+ self.AddStrip(pos,steps,band_width,step_length,touch_clearance)
+ pos += wxPoint(0,band_width)
+
+TouchSliderWizard().register()
+
diff --git a/pcbnew/scripting/plugins/uss39_barcode.py b/pcbnew/scripting/plugins/uss39_barcode.py
new file mode 100644
index 0000000..846a2bc
--- /dev/null
+++ b/pcbnew/scripting/plugins/uss39_barcode.py
@@ -0,0 +1,149 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+from __future__ import division
+import pcbnew as B
+
+import HelpfulFootprintWizardPlugin
+
+'''
+Created on Jan 16, 2015
+
+@author: ejohns
+Rewritten by LordBlick
+'''
+ptd = {
+ '0': '000110100', '1': '100100001', '2': '001100001', '3': '101100000',
+ '4': '000110001', '5': '100110000', '6': '001110000', '7': '000100101',
+ '8': '100100100', '9': '001100100', 'A': '100001001', 'B': '001001001',
+ 'C': '101001000', 'D': '000011001', 'E': '100011000', 'F': '001011000',
+ 'G': '000001101', 'H': '100001100', 'I': '001001100', 'J': '000011100',
+ 'K': '100000011', 'L': '001000011', 'M': '101000010', 'N': '000010011',
+ 'O': '100010010', 'P': '001010010', 'Q': '000000111', 'R': '100000110',
+ 'S': '001000110', 'T': '000010110', 'U': '110000001', 'V': '011000001',
+ 'W': '111000000', 'X': '010010001', 'Y': '110010000', 'Z': '011010000',
+ '-': '010000101', '.': '110000100', ' ': '011000100', '*': '010010100',
+ '$': '010101000', '/': '010100010', '+': '010001010', '%': '000101010'}
+
+class Uss39:
+ def __init__(self, text):
+ self.Text = self.makePrintable(text)
+
+ __str__ = lambda self: self.Text
+ makePrintable = lambda self, text: ''.join((c for c in text.upper() if ptd.has_key(c)))
+
+ def getBarCodePattern(self, text = None):
+ text = text if not(text is None) else self.Text
+ # Reformated text with start and end characters
+ return reduce(lambda a1, a2: a1 + [0] + a2, [map(int, ptd[c]) for c in ("*%s*" % self.makePrintable(text))])
+
+class Uss39Wizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):
+ GetName = lambda self: 'BARCODE USS-39'
+ GetDescription = lambda self: 'USS-39 Barcode'
+ GetReferencePrefix = lambda self: 'BARCODE'
+ GetValue = lambda self: self.module.Value().GetText()
+
+ def GenerateParameterList(self):
+ # Silkscreen parameters
+ self.AddParam("Barcode", "Pixel Width", self.uMM, 0.20)
+ self.AddParam("Barcode", "Height", self.uMM, 3.0)
+ self.AddParam("Barcode", "Margin", self.uMM, 2.0)
+ self.AddParam("Barcode", "Contents", self.uString, 'BARCODE')
+ self.AddParam("Caption", "Enabled", self.uBool, True)
+ self.AddParam("Caption", "Height", self.uMM, 1.2)
+ self.AddParam("Caption", "Thickness", self.uMM, 0.12)
+
+ def CheckParameters(self):
+ # Reset constants
+ self.CourtyardLineWidth = B.FromMM(0.05)
+ # Set bar height to the greater of 6.35mm or 0.15*L
+ # Set quiet width to 10*X
+ # User-defined parameters
+ # Create barcode object
+ self.Barcode = Uss39('=' + str(self.parameters['Barcode']['*Contents']))
+ self.X = int(self.parameters['Barcode']['Pixel Width'])
+ self.module.Value().SetText( str(self.Barcode) )
+ self.C = len(str(self.Barcode))
+ # Inter-character gap
+ if self.X < 0.250:
+ self.I = B.FromMM(3.15)
+ else:
+ self.I = (2 * self.X) if (2*self.X) > B.FromMM(1.35) else B.FromMM(1.35)
+ # Wide to narrow ratio
+ if self.X >= B.FromMM(0.508):
+ self.N = B.FromMM(int((2.0+3.0)/2))
+ else:
+ self.N = B.FromMM(int((2.2+3.0)/2))
+ self.H = self.parameters['Barcode']['Height']
+ self.Q = (10 * self.X) if (10 * self.X) > B.FromMM(6.35) else B.FromMM(6.35)
+ self.L = self.I * (1 + self.C) + (self.C + 2) * (6 * self.X + 3 * self.N * self.X) + 2 * self.Q
+
+
+ def __drawBar__(self, bit, x):
+ offset = (bit + 1) * self.X
+ return x + offset
+
+ def __drawSpace__(self, bit, x):
+ self.draw.SetLayer(B.F_SilkS)
+ self.draw.SetLineTickness(self.X)
+ self.draw.Line(x, 0, x, self.H)
+ if (bit == 1):
+ self.draw.Line(x + self.X, 0, x + self.X, self.H)
+ self.draw.Line(x + self.X/2, 0, x + self.X/2, self.H)
+ self.draw.Line(x, 0, x + self.X, 0)
+ self.draw.Line(x, self.H, x + self.X, self.H)
+ offset = (bit + 1) * self.X
+ return x + offset
+
+ def drawBars(self):
+ x = 0
+ bars = self.Barcode.getBarCodePattern()
+ for index in range(0, len(bars), 2):
+ # Draw bar
+ barBit = bars[index]
+ x = self.__drawBar__(barBit, x)
+ # Draw space
+ if index < len(bars)-1:
+ spaceBit = bars[index + 1]
+ x = self.__drawSpace__(spaceBit, x)
+ return x
+
+ def drawQuietZone(self, x0, y0, width, height):
+ self.draw.SetLayer(B.F_SilkS)
+ self.draw.SetLineTickness(self.X)
+
+ for offset in range(0, int(self.Q), int(self.X/2)):
+ xoffset = offset + self.X
+ yoffset = offset + self.X/2
+ self.draw.Line(x0 - xoffset, -yoffset, width + xoffset, -yoffset)
+ self.draw.Line(x0 - xoffset, self.H+yoffset, width + xoffset, self.H+yoffset)
+ self.draw.Line(x0 - xoffset, -yoffset, x0-xoffset, self.H+yoffset)
+ self.draw.Line(width + xoffset, -yoffset, width+xoffset, self.H+yoffset)
+
+ def BuildThisFootprint(self):
+ # Draw bars
+ x = self.drawBars()
+ # Draw quiet zone
+ self.drawQuietZone(0, 0, x, self.H)
+ # Draw courtyard origin
+ self.draw.SetLayer(B.F_CrtYd)
+ self.draw.SetLineTickness(self.CourtyardLineWidth)
+ ch_lim = B.FromMM(0.35)
+ self.draw.Line(-ch_lim, 0, ch_lim, 0)
+ self.draw.Line(0, -ch_lim, 0, ch_lim)
+ self.draw.Circle(0, 0, B.FromMM(0.25))
+ self.module.Value().SetLayer(B.F_Fab)
+
+Uss39Wizard().register()
diff --git a/pcbnew/scripting/plugins/zip_wizard.py b/pcbnew/scripting/plugins/zip_wizard.py
new file mode 100644
index 0000000..4e0f477
--- /dev/null
+++ b/pcbnew/scripting/plugins/zip_wizard.py
@@ -0,0 +1,201 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+from __future__ import division
+import pcbnew
+
+import HelpfulFootprintWizardPlugin as HFPW
+import PadArray as PA
+
+
+class RowedFootprint(HFPW.HelpfulFootprintWizardPlugin):
+
+ pad_count_key = '#pad count'
+ line_count_key = '#line count'
+ pad_vertical_size_key = 'pad vertical size'
+ pad_horizontal_size_key = 'pad horizontal size'
+ line_spacing_key = 'line spacing'
+ pad_pitch_key = 'pad pitch'
+ drill_size_key = 'drill size'
+
+ courtyard_x_margin_key = 'courtyard x margin'
+ courtyard_y_margin_key = 'courtyard y margin'
+ outline_x_margin_key = 'outline x margin'
+ outline_y_margin_key = 'outline y margin'
+ silkscreen_inside_key = 'silk screen inside'
+
+ def GenerateParameterList(self):
+
+ # defaults for a ZIP package
+ self.AddParam("Pads", self.pad_count_key, self.uNatural, 24)
+ self.AddParam("Pads", self.line_count_key, self.uNatural, 2)
+ self.AddParam("Body", self.silkscreen_inside_key, self.uBool, False)
+ self.AddParam("Body", self.courtyard_x_margin_key, self.uMM, 1)
+ self.AddParam("Body", self.courtyard_y_margin_key, self.uMM, 1)
+
+ def CheckParameters(self):
+ self.CheckParamInt("Pads", '*' + self.pad_count_key)
+ self.CheckParamInt("Pads", '*' + self.line_count_key)
+
+ # can do this internally to parameter manager?
+ self.CheckParamBool("Body", '*' + self.silkscreen_inside_key)
+
+ def BuildThisFootprint(self):
+ pads = self.parameters["Pads"]
+ body = self.parameters["Body"]
+
+ pad_count = pads['*' + self.pad_count_key]
+ pad_Vsize = pads[self.pad_vertical_size_key]
+ pad_Hsize = pads[self.pad_horizontal_size_key]
+ line_pitch = pads[self.line_spacing_key]
+ pad_pitch = pads[self.pad_pitch_key]
+ line_count = pads['*' + self.line_count_key]
+
+ if line_count == 1:
+ singleline = True
+ else:
+ singleline = False
+
+ # add in the pads
+ pad = self.GetPad()
+
+ array = PA.PadZGridArray(pad, pad_count, line_count, line_pitch, pad_pitch)
+ array.AddPadsToModule(self.draw)
+
+ # draw the Silk Screen
+ pads_per_line = pad_count // line_count
+ row_length = pad_pitch * (pads_per_line - 1) # fenceposts
+ ssx_offset = pad_Hsize / 2 + body[self.outline_x_margin_key]
+ ssy_offset = pad_Vsize / 2 + body[self.outline_y_margin_key]
+
+ pin1posX = pad_pitch * (pad_count - 1) / 2
+ pin1posY = line_pitch * (line_count - 1) / 2
+ leftx = pin1posX + ssx_offset
+ lowy = pin1posY + ssy_offset
+
+ cornery = lowy
+
+ # body inside pads is possible only for 2 rows.
+ # for other values, there is no room
+ linew = self.draw.GetLineTickness()
+ if body['*'+self.silkscreen_inside_key] and line_count == 2:
+ cornery = pin1posY - ssy_offset
+ if cornery < linew:
+ cornery = linew
+
+ self.DrawBox(leftx*2, cornery*2)
+
+ # Courtyard
+ cmarginx = body[self.courtyard_x_margin_key]
+ cmarginy = body[self.courtyard_y_margin_key]
+ self.draw.SetLayer(pcbnew.F_CrtYd)
+ sizex = (pin1posX + cmarginx) * 2 + pad_Hsize
+ sizey = (pin1posY + cmarginy) * 2 + pad_Vsize
+ self.draw.Box(0, 0, sizex, sizey)
+
+ #reference and value
+ text_size = self.GetTextSize() # IPC nominal
+ t_posy = lowy + text_size
+
+ self.draw.Value(0, t_posy, text_size)
+ self.draw.Reference(0, -t_posy, text_size)
+
+ def DrawBox(self, sizex, sizey):
+
+ # ----------
+ # | 2 4 6 8|
+ # |1 3 5 7 |
+ # \---------
+ setback = pcbnew.FromMM(1)
+
+ if setback > sizey/2:
+ setback = sizey/2
+
+ self.draw.BoxWithDiagonalAtCorner(0, 0, sizex, sizey, setback, self.draw.flipY)
+
+
+class ZIPWizard(RowedFootprint):
+
+ def GetName(self):
+ return "ZIP"
+
+ def GetDescription(self):
+ return "N lines Zip Package Footprint Wizard"
+
+ def GenerateParameterList(self):
+ RowedFootprint.GenerateParameterList(self)
+
+ self.AddParam("Pads", self.pad_pitch_key, self.uMM, 1.27)
+ self.AddParam("Pads", self.pad_horizontal_size_key, self.uMM, 1.2)
+ self.AddParam("Pads", self.pad_vertical_size_key, self.uMM, 2)
+ self.AddParam("Pads", self.line_spacing_key, self.uMM, 2.54)
+ self.AddParam("Pads", self.drill_size_key, self.uMM, 0.8)
+ self.AddParam("Body", self.outline_x_margin_key, self.uMM, 1)
+ self.AddParam("Body", self.outline_y_margin_key, self.uMM, 0.5)
+
+ def GetValue(self):
+ rows = self.parameters["Pads"]['*' + self.line_count_key]
+ pad_cnt = self.parameters["Pads"]['*' + self.pad_count_key]
+
+ if rows == 1:
+ name = "SIP"
+ elif rows == 2:
+ name = "ZIP"
+ else: # triple and up aren't really a thing, but call it something!
+ name = "xIP"
+
+ return "%s-%d" % (name, pad_cnt)
+
+ def GetPad(self):
+ pad_Vsize = self.parameters["Pads"][self.pad_vertical_size_key]
+ pad_Hsize = self.parameters["Pads"][self.pad_horizontal_size_key]
+ drill = self.parameters["Pads"][self.drill_size_key]
+ return PA.PadMaker(self.module).THPad(
+ pad_Vsize, pad_Hsize, drill, shape=pcbnew.PAD_SHAPE_OVAL)
+
+ZIPWizard().register()
+
+
+class ZOICWizard(RowedFootprint):
+
+ def GetName(self):
+ return "ZOIC"
+
+ def GetDescription(self):
+ return "ZOIC, etc, Footprint Wizard"
+
+ def GetValue(self):
+ return "%s-%d" % ("ZOIC", self.parameters["Pads"]['*' + self.pad_count_key])
+
+ def GenerateParameterList(self):
+ RowedFootprint.GenerateParameterList(self)
+
+ #and override some of them
+ self.AddParam("Pads", self.pad_pitch_key, self.uMM, 0.6)
+ self.AddParam("Pads", self.pad_horizontal_size_key, self.uMM, 0.6)
+ self.AddParam("Pads", self.pad_vertical_size_key, self.uMM, 1.8)
+ self.AddParam("Pads", self.line_spacing_key, self.uMM, 5.2)
+
+ self.AddParam("Body", self.outline_x_margin_key, self.uMM, 0.5)
+ self.AddParam("Body", self.outline_y_margin_key, self.uMM, 1)
+
+ def GetPad(self):
+ pad_Vsize = self.parameters["Pads"][self.pad_vertical_size_key]
+ pad_Hsize = self.parameters["Pads"][self.pad_horizontal_size_key]
+ return PA.PadMaker(self.module).SMDPad(
+ pad_Vsize, pad_Hsize, shape=pcbnew.PAD_SHAPE_RECT)
+
+ZOICWizard().register()
diff --git a/pcbnew/scripting/python_console_frame.h b/pcbnew/scripting/python_console_frame.h
new file mode 100644
index 0000000..042e6b0
--- /dev/null
+++ b/pcbnew/scripting/python_console_frame.h
@@ -0,0 +1,105 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file python_console_frame.h
+ */
+
+#ifndef PYTHON_CONSOLE_FRAME_H_
+#define PYTHON_CONSOLE_FRAME_H_
+
+#if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON)
+#include <python_scripting.h>
+#endif
+
+
+/**
+ * Class PYTHON_CONSOLE_FRAME is a simple derived class from wxMiniFrame
+ * to handle the scripting python console
+ */
+#define PC_STYLE wxCAPTION|wxCLOSE_BOX|wxRESIZE_BORDER
+
+class PYTHON_CONSOLE_FRAME : public wxMiniFrame
+{
+private:
+ static wxSize m_frameSize; ///< The size of the frame, stored during a session
+ static wxPoint m_framePos; ///< The position of the frame, stored during a session
+ wxWindow * m_pythonPanel; ///< the window managed by the python shell
+
+public:
+
+ PYTHON_CONSOLE_FRAME( wxWindow* aParent, const wxString& aFramenameId )
+ : wxMiniFrame( aParent, wxID_ANY, wxT("Python console"), wxDefaultPosition, wxDefaultSize,
+ PC_STYLE | wxFRAME_FLOAT_ON_PARENT, aFramenameId )
+ {
+ wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
+ SetSizer( sizer );
+ SetMinSize( wxSize( 500, 200 ) );
+
+#if defined(KICAD_SCRIPTING_WXPYTHON)
+ m_pythonPanel = CreatePythonShellWindow( this );
+ sizer->Add( m_pythonPanel, 1, wxEXPAND, 0 );
+#else
+ m_pythonPanel = NULL;
+#endif
+
+ if( m_frameSize.x <= 0 || m_frameSize.y <= 0 )
+ SetSize( wxSize( 600, 300 ) );
+ else
+ SetSize( m_frameSize );
+
+ if( m_framePos.x == 0 && m_framePos.y == 0 )
+ Centre();
+ else
+ SetPosition( m_framePos );
+
+ Layout();
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW,
+ wxCloseEventHandler( PYTHON_CONSOLE_FRAME::OnClose ) );
+ }
+
+ ~PYTHON_CONSOLE_FRAME()
+ {
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW,
+ wxCloseEventHandler( PYTHON_CONSOLE_FRAME::OnClose ) );
+ }
+
+private:
+
+ void OnClose( wxCloseEvent& event )
+ {
+ if( !IsIconized() )
+ {
+ m_frameSize = GetSize();
+ m_framePos = GetPosition();
+ }
+
+ event.Skip();
+ }
+};
+
+#endif // PYTHON_CONSOLE_FRAME_H_
diff --git a/pcbnew/scripting/tests/test1.py b/pcbnew/scripting/tests/test1.py
new file mode 100644
index 0000000..b1f7cff
--- /dev/null
+++ b/pcbnew/scripting/tests/test1.py
@@ -0,0 +1,11 @@
+import pcbnew
+
+pcb = pcbnew.GetBoard()
+
+for m in pcb.GetModules():
+ print m.GetPosition()
+ for p in m.Pads():
+ print "p=>",p.GetPosition(),p.GetPadName()
+ print p.GetPosition()
+
+
diff --git a/pcbnew/scripting/tests/test2.py b/pcbnew/scripting/tests/test2.py
new file mode 100644
index 0000000..e925f88
--- /dev/null
+++ b/pcbnew/scripting/tests/test2.py
@@ -0,0 +1,8 @@
+import pcbnew
+
+pcb = pcbnew.GetBoard()
+
+for m in pcb.GetModules():
+ print m.GetReference(),"(",m.GetValue(),") at ", m.GetPosition()
+ for p in m.Pads():
+ print " pad",p.GetPadName(), "at",p.GetPosition()
diff --git a/pcbnew/scripting/units.i b/pcbnew/scripting/units.i
new file mode 100644
index 0000000..56ea213
--- /dev/null
+++ b/pcbnew/scripting/units.i
@@ -0,0 +1,78 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo <miguelangel@nbee.es>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file units.i
+ * @brief unit conversion code
+ */
+
+// Unit conversion, between internal units and mm or mils
+
+%pythoncode
+{
+ def ToMM(iu):
+ if type(iu) in [int,float]:
+ return float(iu) / float(IU_PER_MM)
+ elif type(iu) in [wxPoint,wxSize]:
+ return tuple(map(ToMM,iu))
+
+ def FromMM(mm):
+ if type(mm) in [int,float]:
+ return int(float(mm) * float(IU_PER_MM))
+ elif type(mm) in [wxPoint,wxSize]:
+ return tuple(map(FromMM,mm))
+
+ def ToMils(iu):
+ if type(iu) in [int,float]:
+ return float(iu) / float(IU_PER_MILS)
+ elif type(iu) in [wxPoint,wxSize]:
+ return tuple(map(ToMils,iu))
+
+ def FromMils(mils):
+ if type(mils) in [int,float]:
+ return int(float(mils)*float(IU_PER_MILS))
+ elif type(mils) in [wxPoint,wxSize]:
+ return tuple(map(FromMils,mils))
+
+ def wxSizeMM(mmx,mmy): return wxSize(FromMM(mmx),FromMM(mmy))
+ def wxSizeMils(mmx,mmy): return wxSize(FromMils(mmx),FromMils(mmy))
+
+ def wxPointMM(mmx,mmy): return wxPoint(FromMM(mmx),FromMM(mmy))
+ def wxPointMils(mmx,mmy): return wxPoint(FromMils(mmx),FromMils(mmy))
+
+ def wxRectMM(x,y,wx,wy):
+ x = int(FromMM(x))
+ y = int(FromMM(y))
+ wx = int(FromMM(wx))
+ wy = int (FromMM(wy))
+ return wxRect(x,y,wx,wy)
+
+ def wxRectMils(x,y,wx,wy):
+ x = int(FromMils(x))
+ y = int(FromMils(y))
+ wx = int(FromMils(wx))
+ wy = int (FromMils(wy))
+ return wxRect(x,y,wx,wy)
+
+}
diff --git a/pcbnew/sel_layer.cpp b/pcbnew/sel_layer.cpp
new file mode 100644
index 0000000..b32b032
--- /dev/null
+++ b/pcbnew/sel_layer.cpp
@@ -0,0 +1,429 @@
+/**
+ * @file sel_layer.cpp
+ * @brief dialogs for one layer selection and a layer pair selection.
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <common.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxBasePcbFrame.h>
+#include <class_layer_box_selector.h>
+#include <class_board.h>
+#include <dialogs/dialog_layer_selection_base.h>
+
+
+/* classes to display a layer list using a wxGrid.
+ */
+class PCB_LAYER_SELECTOR: public LAYER_SELECTOR
+{
+public:
+ PCB_LAYER_SELECTOR( BOARD* aBrd ) :
+ LAYER_SELECTOR()
+ {
+ m_brd = aBrd;
+ }
+
+protected:
+ BOARD* m_brd;
+
+ // Returns true if the layer id is enabled (i.e. is it should be displayed)
+ bool IsLayerEnabled( LAYER_NUM aLayer ) const
+ {
+ return m_brd->IsLayerEnabled( LAYER_ID( aLayer ) );
+ }
+
+ // Returns a color index from the layer id
+ // Virtual function
+ EDA_COLOR_T GetLayerColor( LAYER_NUM aLayer ) const
+ {
+ return m_brd->GetLayerColor( ToLAYER_ID( aLayer ) );
+ }
+
+ // Returns the name of the layer id
+ wxString GetLayerName( LAYER_NUM aLayer ) const // overrides LAYER_SELECTOR
+ {
+ return m_brd->GetLayerName( ToLAYER_ID( aLayer ) );
+ }
+};
+
+
+/*
+ * This class display a pcb layers list in a dialog,
+ * to select one layer from this list
+ */
+class PCB_ONE_LAYER_SELECTOR : public PCB_LAYER_SELECTOR,
+ public DIALOG_LAYER_SELECTION_BASE
+{
+ LAYER_ID m_layerSelected;
+ LSET m_notAllowedLayersMask;
+
+ std::vector<LAYER_ID> m_layersIdLeftColumn;
+ std::vector<LAYER_ID> m_layersIdRightColumn;
+
+public:
+ PCB_ONE_LAYER_SELECTOR( wxWindow* aParent, BOARD * aBrd,
+ LAYER_ID aDefaultLayer,
+ LSET aNotAllowedLayersMask );
+
+ LAYER_NUM GetLayerSelection() { return m_layerSelected; }
+
+private:
+ // Event handlers
+ void OnLeftGridCellClick( wxGridEvent& event );
+ void OnRightGridCellClick( wxGridEvent& event );
+
+ void buildList();
+};
+
+
+PCB_ONE_LAYER_SELECTOR::PCB_ONE_LAYER_SELECTOR( wxWindow* aParent,
+ BOARD* aBrd, LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask )
+ : PCB_LAYER_SELECTOR( aBrd ), DIALOG_LAYER_SELECTION_BASE( aParent )
+{
+ m_layerSelected = aDefaultLayer;
+ m_notAllowedLayersMask = aNotAllowedLayersMask;
+ buildList();
+ Layout();
+ GetSizer()->SetSizeHints( this );
+ SetFocus();
+}
+
+
+// Build the layers list
+// Column position by function:
+#define SELECT_COLNUM 0
+#define COLOR_COLNUM 1
+#define LAYERNAME_COLNUM 2
+
+void PCB_ONE_LAYER_SELECTOR::buildList()
+{
+ // Hide layerid column which is used only to know the layer id
+ // not to be shown in dialogs
+ m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 );
+ m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 );
+
+ int left_row = 0;
+ int right_row = 0;
+ wxString layername;
+
+ for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder(); ui_seq; ++ui_seq )
+ {
+ LAYER_ID layerid = *ui_seq;
+
+ if( m_notAllowedLayersMask[layerid] )
+ continue;
+
+ wxColour color = MakeColour( GetLayerColor( layerid ) );
+ layername = GetLayerName( layerid );
+
+ if( IsCopperLayer( layerid ) )
+ {
+ if( left_row )
+ m_leftGridLayers->AppendRows( 1 );
+
+ m_leftGridLayers->SetCellBackgroundColour ( left_row, COLOR_COLNUM,
+ color );
+ m_leftGridLayers->SetCellValue( left_row, LAYERNAME_COLNUM,
+ layername );
+
+ if( m_layerSelected == layerid )
+ {
+ m_leftGridLayers->SetCellValue( left_row, SELECT_COLNUM,
+ wxT("X") );
+ m_leftGridLayers->SetCellBackgroundColour ( left_row, SELECT_COLNUM,
+ color );
+ m_leftGridLayers->SetGridCursor( left_row, LAYERNAME_COLNUM );
+ }
+
+ m_layersIdLeftColumn.push_back( layerid );
+ left_row++;
+ }
+ else
+ {
+ if( right_row )
+ m_rightGridLayers->AppendRows( 1 );
+
+ m_rightGridLayers->SetCellBackgroundColour ( right_row, COLOR_COLNUM,
+ color );
+ m_rightGridLayers->SetCellValue( right_row, LAYERNAME_COLNUM,
+ layername );
+
+ if( m_layerSelected == layerid )
+ {
+ m_rightGridLayers->SetCellValue( right_row, SELECT_COLNUM,
+ wxT("X") );
+ m_rightGridLayers->SetCellBackgroundColour ( right_row, SELECT_COLNUM,
+ color );
+ m_rightGridLayers->SetGridCursor( right_row, LAYERNAME_COLNUM );
+ }
+
+ m_layersIdRightColumn.push_back( layerid );
+ right_row++;
+ }
+ }
+
+ // Show only populated lists:
+ if( left_row <= 0 )
+ m_leftGridLayers->Show( false );
+
+ if( right_row <= 0 )
+ m_rightGridLayers->Show( false );
+
+ m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
+ m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
+ m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM);
+ m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM);
+}
+
+
+void PCB_ONE_LAYER_SELECTOR::OnLeftGridCellClick( wxGridEvent& event )
+{
+ m_layerSelected = m_layersIdLeftColumn[ event.GetRow() ];
+ m_leftGridLayers->SetGridCursor( event.GetRow(), LAYERNAME_COLNUM );
+ EndModal( 1 );
+}
+
+
+void PCB_ONE_LAYER_SELECTOR::OnRightGridCellClick( wxGridEvent& event )
+{
+ m_layerSelected = m_layersIdRightColumn[ event.GetRow() ];
+ m_rightGridLayers->SetGridCursor( event.GetRow(), LAYERNAME_COLNUM );
+ EndModal( 2 );
+}
+
+
+LAYER_ID PCB_BASE_FRAME::SelectLayer( LAYER_ID aDefaultLayer,
+ LSET aNotAllowedLayersMask, wxPoint aDlgPosition )
+{
+ PCB_ONE_LAYER_SELECTOR dlg( this, GetBoard(), aDefaultLayer, aNotAllowedLayersMask );
+
+ if( aDlgPosition != wxDefaultPosition )
+ {
+ wxSize dlgSize = dlg.GetSize();
+ aDlgPosition.x -= dlgSize.x/2;
+ aDlgPosition.y -= dlgSize.y/2;
+ dlg.SetPosition( aDlgPosition );
+ }
+
+ dlg.ShowModal();
+
+ LAYER_ID layer = ToLAYER_ID( dlg.GetLayerSelection() );
+ return layer;
+}
+
+
+/**
+ * Class SELECT_COPPER_LAYERS_PAIR_DIALOG
+ * displays a double pcb copper layers list in a dialog,
+ * to select a layer pair from these lists
+ */
+class SELECT_COPPER_LAYERS_PAIR_DIALOG: public PCB_LAYER_SELECTOR,
+ public DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE
+{
+private:
+ LAYER_ID m_frontLayer;
+ LAYER_ID m_backLayer;
+ int m_leftRowSelected;
+ int m_rightRowSelected;
+
+ std::vector<LAYER_ID> m_layersId;
+
+public:
+ SELECT_COPPER_LAYERS_PAIR_DIALOG( wxWindow* aParent, BOARD* aPcb,
+ LAYER_ID aFrontLayer, LAYER_ID aBackLayer );
+
+ void GetLayerPair( LAYER_ID& aFrontLayer, LAYER_ID& aBackLayer )
+ {
+ aFrontLayer = m_frontLayer;
+ aBackLayer = m_backLayer;
+ }
+
+private:
+ void OnLeftGridCellClick( wxGridEvent& event );
+ void OnRightGridCellClick( wxGridEvent& event );
+
+ void OnOkClick( wxCommandEvent& event )
+ {
+ EndModal( wxID_OK );
+ }
+
+ void OnCancelClick( wxCommandEvent& event )
+ {
+ EndModal( wxID_CANCEL );
+ }
+
+ void buildList();
+ void SetGridCursor( wxGrid* aGrid, int aRow, bool aEnable );
+};
+
+
+void PCB_BASE_FRAME::SelectCopperLayerPair()
+{
+ PCB_SCREEN* screen = GetScreen();
+
+ SELECT_COPPER_LAYERS_PAIR_DIALOG dlg( this, GetBoard(),
+ screen->m_Route_Layer_TOP,
+ screen->m_Route_Layer_BOTTOM );
+
+ if( dlg.ShowModal() == wxID_OK )
+ {
+ dlg.GetLayerPair( screen->m_Route_Layer_TOP, screen->m_Route_Layer_BOTTOM );
+
+ // select the same layer for both layers is allowed (normal in some boards)
+ // but could be a mistake. So display an info message
+ if( screen->m_Route_Layer_TOP == screen->m_Route_Layer_BOTTOM )
+ DisplayInfoMessage( this,
+ _( "Warning: The Top Layer and Bottom Layer are same." ) );
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+}
+
+
+SELECT_COPPER_LAYERS_PAIR_DIALOG::SELECT_COPPER_LAYERS_PAIR_DIALOG(
+ wxWindow* aParent, BOARD * aPcb, LAYER_ID aFrontLayer, LAYER_ID aBackLayer) :
+ PCB_LAYER_SELECTOR( aPcb ),
+ DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE( aParent )
+{
+ m_frontLayer = aFrontLayer;
+ m_backLayer = aBackLayer;
+ m_leftRowSelected = 0;
+ m_rightRowSelected = 0;
+ buildList();
+ SetFocus();
+ GetSizer()->SetSizeHints( this );
+ Center();
+}
+
+
+void SELECT_COPPER_LAYERS_PAIR_DIALOG::buildList()
+{
+ m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 );
+ m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 );
+
+ // Select a not show cell, to avoid a wrong cell selection for user
+
+ int row = 0;
+ wxString layername;
+
+ for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder(); ui_seq; ++ui_seq )
+ {
+ LAYER_ID layerid = *ui_seq;
+
+ if( !IsCopperLayer( layerid ) )
+ break;
+
+ wxColour color = MakeColour( GetLayerColor( layerid ) );
+
+ layername = GetLayerName( layerid );
+
+ if( row )
+ m_leftGridLayers->AppendRows( 1 );
+
+ m_leftGridLayers->SetCellBackgroundColour( row, COLOR_COLNUM, color );
+ m_leftGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername );
+ m_layersId.push_back( layerid );
+
+ if( m_frontLayer == layerid )
+ {
+ SetGridCursor( m_leftGridLayers, row, true );
+ m_leftRowSelected = row;
+ }
+
+ if( row )
+ m_rightGridLayers->AppendRows( 1 );
+ m_rightGridLayers->SetCellBackgroundColour ( row, COLOR_COLNUM,
+ color );
+ m_rightGridLayers->SetCellValue( row, LAYERNAME_COLNUM,
+ layername );
+
+ if( m_backLayer == layerid )
+ {
+ SetGridCursor( m_rightGridLayers, row, true );
+ m_rightRowSelected = row;
+ }
+
+ row++;
+ }
+
+ m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
+ m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
+ m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM);
+ m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM);
+}
+
+
+void SELECT_COPPER_LAYERS_PAIR_DIALOG::SetGridCursor( wxGrid* aGrid, int aRow,
+ bool aEnable )
+{
+ if( aEnable )
+ {
+ LAYER_ID layerid = m_layersId[aRow];
+ wxColour color = MakeColour( GetLayerColor( layerid ) );
+ aGrid->SetCellValue( aRow, SELECT_COLNUM, wxT("X") );
+ aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM, color );
+ aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM );
+ }
+ else
+ {
+ aGrid->SetCellValue( aRow, SELECT_COLNUM, wxEmptyString );
+ aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM,
+ aGrid->GetDefaultCellBackgroundColour() );
+ aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM );
+ }
+}
+
+
+void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnLeftGridCellClick( wxGridEvent& event )
+{
+ int row = event.GetRow();
+ LAYER_ID layer = m_layersId[row];
+
+ if( m_frontLayer == layer )
+ return;
+
+ SetGridCursor( m_leftGridLayers, m_leftRowSelected, false );
+ m_frontLayer = layer;
+ m_leftRowSelected = row;
+ SetGridCursor( m_leftGridLayers, m_leftRowSelected, true );
+}
+
+
+void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnRightGridCellClick( wxGridEvent& event )
+{
+ int row = event.GetRow();
+ LAYER_ID layer = m_layersId[row];
+
+ if( m_backLayer == layer )
+ return;
+
+ SetGridCursor( m_rightGridLayers, m_rightRowSelected, false );
+ m_backLayer = layer;
+ m_rightRowSelected = row;
+ SetGridCursor( m_rightGridLayers, m_rightRowSelected, true );
+}
diff --git a/pcbnew/specctra.cpp b/pcbnew/specctra.cpp
new file mode 100644
index 0000000..2358d3b
--- /dev/null
+++ b/pcbnew/specctra.cpp
@@ -0,0 +1,3793 @@
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2007-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* This source file implements export and import capabilities to the
+ specctra dsn file format. The grammar for that file format is documented
+ fairly well. There are classes for each major type of descriptor in the
+ spec.
+
+ Since there are so many classes in here, it may be helpful to generate
+ the Doxygen directory:
+
+ $ cd <kicadSourceRoot>
+ $ doxygen
+
+ Then you can view the html documentation in the <kicadSourceRoot>/doxygen
+ directory. The main class in this file is SPECCTRA_DB and its main
+ functions are LoadPCB(), LoadSESSION(), and ExportPCB().
+
+ Wide use is made of boost::ptr_vector<> and std::vector<> template classes.
+ If the contained object is small, then std::vector tends to be used.
+ If the contained object is large, variable size, or would require writing
+ an assignment operator() or copy constructor, then boost::ptr_vector
+ cannot be beat.
+*/
+
+
+#include <cstdarg>
+#include <cstdio>
+
+#include <build_version.h>
+
+#include <class_board.h>
+#include <class_track.h>
+
+#include <specctra.h>
+#include <macros.h>
+
+
+namespace DSN {
+
+#define NESTWIDTH 2 ///< how many spaces per nestLevel
+
+//-----<SPECCTRA_DB>-------------------------------------------------
+
+
+const char* GetTokenText( T aTok )
+{
+ return SPECCTRA_LEXER::TokenName( aTok );
+}
+
+void SPECCTRA_DB::buildLayerMaps( BOARD* aBoard )
+{
+ // specctra wants top physical layer first, then going down to the
+ // bottom most physical layer in physical sequence.
+ // Same as KiCad now except for B_Cu
+ unsigned layerCount = aBoard->GetCopperLayerCount();
+
+ layerIds.clear();
+ pcbLayer2kicad.resize( layerCount );
+ kicadLayer2pcb.resize( B_Cu + 1 );
+
+#if 0 // was:
+ for( LAYER_NUM kiNdx = layerCount - 1, pcbNdx=FIRST_LAYER;
+ kiNdx >= 0; --kiNdx, ++pcbNdx )
+ {
+ LAYER_NUM kilayer = (kiNdx>0 && kiNdx==layerCount-1) ? F_Cu : kiNdx;
+
+ // establish bi-directional mapping between KiCad's BOARD layer and PCB layer
+ pcbLayer2kicad[pcbNdx] = kilayer;
+ kicadLayer2pcb[kilayer] = pcbNdx;
+
+ // save the specctra layer name in SPECCTRA_DB::layerIds for later.
+ layerIds.push_back( TO_UTF8( aBoard->GetLayerName( ToLAYER_ID( kilayer ) ) ) );
+ }
+#else
+
+ // establish bi-directional mapping between KiCad's BOARD layer and PCB layer
+
+ for( unsigned i = 0; i < kicadLayer2pcb.size(); ++i )
+ {
+ if( i < layerCount-1 )
+ kicadLayer2pcb[i] = i;
+ else
+ kicadLayer2pcb[i] = layerCount - 1;
+ }
+
+ for( unsigned i = 0; i < pcbLayer2kicad.size(); ++i )
+ {
+ LAYER_ID id = ( i < layerCount-1 ) ? ToLAYER_ID( i ) : B_Cu;
+
+ pcbLayer2kicad[i] = id;
+
+ // save the specctra layer name in SPECCTRA_DB::layerIds for later.
+ layerIds.push_back( TO_UTF8( aBoard->GetLayerName( id ) ) );
+ }
+
+#endif
+}
+
+
+int SPECCTRA_DB::findLayerName( const std::string& aLayerName ) const
+{
+ for( int i=0; i < int(layerIds.size()); ++i )
+ {
+ if( 0 == aLayerName.compare( layerIds[i] ) )
+ return i;
+ }
+ return -1;
+}
+
+
+void SPECCTRA_DB::ThrowIOError( const wxString& fmt, ... ) throw( IO_ERROR )
+{
+ wxString errText;
+ va_list args;
+
+ va_start( args, fmt );
+ errText.PrintfV( fmt, args );
+ va_end( args );
+
+ THROW_IO_ERROR( errText );
+}
+
+
+void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id ) throw( IO_ERROR )
+{
+ T tok;
+
+ static const char pin_def[] = "<pin_reference>::=<component_id>-<pin_id>";
+
+ if( !IsSymbol( (T) CurTok() ) )
+ Expecting( pin_def );
+
+ // case for: A12-14, i.e. no wrapping quotes. This should be a single
+ // token, so split it.
+ if( CurTok() != T_STRING )
+ {
+ const char* toktext = CurText();
+ const char* dash = strchr( toktext, '-' );
+
+ if( !dash )
+ Expecting( pin_def );
+
+ while( toktext != dash )
+ *component_id += *toktext++;
+
+ ++toktext; // skip the dash
+
+ while( *toktext )
+ *pin_id += *toktext++;
+ }
+
+ // quoted string: "U12"-"14" or "U12"-14, 3 tokens in either case
+ else
+ {
+ *component_id = CurText();
+
+ tok = NextTok();
+ if( tok!=T_DASH )
+ Expecting( pin_def );
+
+ NextTok(); // accept anything after the dash.
+ *pin_id = CurText();
+ }
+}
+
+
+void SPECCTRA_DB::readTIME( time_t* time_stamp ) throw( IO_ERROR )
+{
+ T tok;
+
+ struct tm mytime;
+
+ static const char time_toks[] = "<month> <day> <hour> : <minute> : <second> <year>";
+
+ static const char* months[] = { // index 0 = Jan
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL
+ };
+
+ NeedSYMBOL(); // month
+
+ const char* ptok = CurText();
+
+ mytime.tm_mon = 0; // remains if we don't find a month match.
+ for( int m=0; months[m]; ++m )
+ {
+ if( !stricmp( months[m], ptok ) )
+ {
+ mytime.tm_mon = m;
+ break;
+ }
+ }
+
+ tok = NextTok(); // day
+ if( tok != T_NUMBER )
+ Expecting( time_toks );
+ mytime.tm_mday = atoi( CurText() );
+
+ tok = NextTok(); // hour
+ if( tok != T_NUMBER )
+ Expecting( time_toks );
+ mytime.tm_hour = atoi( CurText() );
+
+ // : colon
+ NeedSYMBOL();
+ if( *CurText() != ':' || strlen( CurText() )!=1 )
+ Expecting( time_toks );
+
+ tok = NextTok(); // minute
+ if( tok != T_NUMBER )
+ Expecting( time_toks );
+ mytime.tm_min = atoi( CurText() );
+
+ // : colon
+ NeedSYMBOL();
+ if( *CurText() != ':' || strlen( CurText() )!=1 )
+ Expecting( time_toks );
+
+ tok = NextTok(); // second
+ if( tok != T_NUMBER )
+ Expecting( time_toks );
+ mytime.tm_sec = atoi( CurText() );
+
+ tok = NextTok(); // year
+ if( tok != T_NUMBER )
+ Expecting( time_toks );
+ mytime.tm_year = atoi( CurText() ) - 1900;
+
+ *time_stamp = mktime( &mytime );
+}
+
+
+void SPECCTRA_DB::LoadPCB( const wxString& filename ) throw( IO_ERROR, boost::bad_pointer )
+{
+ FILE_LINE_READER reader( filename );
+
+ PushReader( &reader );
+
+ if( NextTok() != T_LEFT )
+ Expecting( T_LEFT );
+
+ if( NextTok() != T_pcb )
+ Expecting( T_pcb );
+
+ SetPCB( new PCB() );
+
+ doPCB( pcb );
+ PopReader();
+}
+
+
+void SPECCTRA_DB::LoadSESSION( const wxString& filename ) throw( IO_ERROR, boost::bad_pointer )
+{
+ FILE_LINE_READER reader( filename );
+
+ PushReader( &reader );
+
+ if( NextTok() != T_LEFT )
+ Expecting( T_LEFT );
+
+ if( NextTok() != T_session )
+ Expecting( T_session );
+
+ SetSESSION( new SESSION() );
+
+ doSESSION( session );
+
+ PopReader();
+}
+
+
+void SPECCTRA_DB::doPCB( PCB* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* <design_descriptor >::=
+ (pcb <pcb_id >
+ [<parser_descriptor> ]
+ [<capacitance_resolution_descriptor> ]
+ [<conductance_resolution_descriptor> ]
+ [<current_resolution_descriptor> ]
+ [<inductance_resolution_descriptor> ]
+ [<resistance_resolution_descriptor> ]
+ [<resolution_descriptor> ]
+ [<time_resolution_descriptor> ]
+ [<voltage_resolution_descriptor> ]
+ [<unit_descriptor> ]
+ [<structure_descriptor> | <file_descriptor> ]
+ [<placement_descriptor> | <file_descriptor> ]
+ [<library_descriptor> | <file_descriptor> ]
+ [<floor_plan_descriptor> | <file_descriptor> ]
+ [<part_library_descriptor> | <file_descriptor> ]
+ [<network_descriptor> | <file_descriptor> ]
+ [<wiring_descriptor> ]
+ [<color_descriptor> ]
+ )
+ */
+
+ NeedSYMBOL();
+ growth->pcbname = CurText();
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_parser:
+ if( growth->parser )
+ Unexpected( tok );
+ growth->parser = new PARSER( growth );
+ doPARSER( growth->parser );
+ break;
+
+ case T_unit:
+ if( growth->unit )
+ Unexpected( tok );
+ growth->unit = new UNIT_RES( growth, tok );
+ doUNIT( growth->unit );
+ break;
+
+ case T_resolution:
+ if( growth->resolution )
+ Unexpected( tok );
+ growth->resolution = new UNIT_RES( growth, tok );
+ doRESOLUTION( growth->resolution );
+ break;
+
+ case T_structure:
+ if( growth->structure )
+ Unexpected( tok );
+ growth->structure = new STRUCTURE( growth );
+ doSTRUCTURE( growth->structure );
+ break;
+
+ case T_placement:
+ if( growth->placement )
+ Unexpected( tok );
+ growth->placement = new PLACEMENT( growth );
+ doPLACEMENT( growth->placement );
+ break;
+
+ case T_library:
+ if( growth->library )
+ Unexpected( tok );
+ growth->library = new LIBRARY( growth );
+ doLIBRARY( growth->library );
+ break;
+
+ case T_network:
+ if( growth->network )
+ Unexpected( tok );
+ growth->network = new NETWORK( growth );
+ doNETWORK( growth->network );
+ break;
+
+ case T_wiring:
+ if( growth->wiring )
+ Unexpected( tok );
+ growth->wiring = new WIRING( growth );
+ doWIRING( growth->wiring );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+
+ tok = NextTok();
+ if( tok != T_EOF )
+ Expecting( T_EOF );
+}
+
+
+void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IO_ERROR )
+{
+ T tok;
+ std::string const1;
+ std::string const2;
+
+ /* <parser_descriptor >::=
+ (parser
+ [(string_quote <quote_char >)]
+ (space_in_quoted_tokens [on | off])
+ [(host_cad <id >)]
+ [(host_version <id >)]
+ [{(constant <id > <id >)}]
+ [(write_resolution] {<character> <positive_integer >})]
+ [(routes_include {[testpoint | guides |
+ image_conductor]})]
+ [(wires_include testpoint)]
+ [(case_sensitive [on | off])]
+ [(via_rotate_first [on | off])]
+ )
+ */
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_STRING_QUOTE:
+ tok = NextTok();
+ if( tok != T_QUOTE_DEF )
+ Expecting( T_QUOTE_DEF );
+ SetStringDelimiter( (unsigned char) *CurText() );
+ growth->string_quote = *CurText();
+ quote_char = CurText();
+ NeedRIGHT();
+ break;
+
+ case T_space_in_quoted_tokens:
+ tok = NextTok();
+ if( tok!=T_on && tok!=T_off )
+ Expecting( "on|off" );
+ SetSpaceInQuotedTokens( tok==T_on );
+ growth->space_in_quoted_tokens = (tok==T_on);
+ NeedRIGHT();
+ break;
+
+ case T_host_cad:
+ NeedSYMBOL();
+ growth->host_cad = CurText();
+ NeedRIGHT();
+ break;
+
+ case T_host_version:
+ NeedSYMBOLorNUMBER();
+ growth->host_version = CurText();
+ NeedRIGHT();
+ break;
+
+ case T_constant:
+ NeedSYMBOLorNUMBER();
+ const1 = CurText();
+ NeedSYMBOLorNUMBER();
+ const2 = CurText();
+ NeedRIGHT();
+ growth->constants.push_back( const1 );
+ growth->constants.push_back( const2 );
+ break;
+
+ case T_write_resolution: // [(writee_resolution {<character> <positive_integer >})]
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok!=T_SYMBOL )
+ Expecting( T_SYMBOL );
+ tok = NextTok();
+ if( tok!=T_NUMBER )
+ Expecting( T_NUMBER );
+ // @todo
+ }
+ break;
+
+ case T_routes_include: // [(routes_include {[testpoint | guides | image_conductor]})]
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ switch( tok )
+ {
+ case T_testpoint:
+ growth->routes_include_testpoint = true;
+ break;
+ case T_guide:
+ growth->routes_include_guides = true;
+ break;
+ case T_image_conductor:
+ growth->routes_include_image_conductor = true;
+ break;
+ default:
+ Expecting( "testpoint|guides|image_conductor" );
+ }
+ }
+ break;
+
+ case T_wires_include: // [(wires_include testpoint)]
+ tok = NextTok();
+ if( tok != T_testpoint )
+ Expecting( T_testpoint );
+ growth->routes_include_testpoint = true;
+ NeedRIGHT();
+ break;
+
+ case T_case_sensitive:
+ tok = NextTok();
+ if( tok!=T_on && tok!=T_off )
+ Expecting( "on|off" );
+ growth->case_sensitive = (tok==T_on);
+ NeedRIGHT();
+ break;
+
+ case T_via_rotate_first: // [(via_rotate_first [on | off])]
+ tok = NextTok();
+ if( tok!=T_on && tok!=T_off )
+ Expecting( "on|off" );
+ growth->via_rotate_first = (tok==T_on);
+ NeedRIGHT();
+ break;
+
+ case T_generated_by_freeroute:
+ growth->generated_by_freeroute = true;
+ NeedRIGHT();
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doRESOLUTION( UNIT_RES* growth ) throw( IO_ERROR )
+{
+ T tok = NextTok();
+
+ switch( tok )
+ {
+ case T_inch:
+ case T_mil:
+ case T_cm:
+ case T_mm:
+ case T_um:
+ growth->units = tok;
+ break;
+ default:
+ Expecting( "inch|mil|cm|mm|um" );
+ }
+
+ tok = NextTok();
+ if( tok != T_NUMBER )
+ Expecting( T_NUMBER );
+
+ growth->value = atoi( CurText() );
+
+ NeedRIGHT();
+}
+
+
+void SPECCTRA_DB::doUNIT( UNIT_RES* growth ) throw( IO_ERROR )
+{
+ T tok = NextTok();
+
+ switch( tok )
+ {
+ case T_inch:
+ case T_mil:
+ case T_cm:
+ case T_mm:
+ case T_um:
+ growth->units = tok;
+ break;
+ default:
+ Expecting( "inch|mil|cm|mm|um" );
+ }
+
+ NeedRIGHT();
+}
+
+
+void SPECCTRA_DB::doLAYER_PAIR( LAYER_PAIR* growth ) throw( IO_ERROR )
+{
+ NeedSYMBOL();
+ growth->layer_id0 = CurText();
+
+ NeedSYMBOL();
+ growth->layer_id1 = CurText();
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->layer_weight = strtod( CurText(), 0 );
+
+ NeedRIGHT();
+}
+
+
+void SPECCTRA_DB::doLAYER_NOISE_WEIGHT( LAYER_NOISE_WEIGHT* growth )
+ throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ if( NextTok() != T_layer_pair )
+ Expecting( T_layer_pair );
+
+ LAYER_PAIR* layer_pair = new LAYER_PAIR( growth );
+ growth->layer_pairs.push_back( layer_pair );
+ doLAYER_PAIR( layer_pair );
+ }
+}
+
+
+void SPECCTRA_DB::doSTRUCTURE( STRUCTURE* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_unit:
+ if( growth->unit )
+ Unexpected( tok );
+ growth->unit = new UNIT_RES( growth, tok );
+ doUNIT( growth->unit );
+ break;
+
+ case T_resolution:
+ if( growth->unit )
+ Unexpected( tok );
+ growth->unit = new UNIT_RES( growth, tok );
+ doRESOLUTION( growth->unit );
+ break;
+
+ case T_layer_noise_weight:
+ if( growth->layer_noise_weight )
+ Unexpected( tok );
+ growth->layer_noise_weight = new LAYER_NOISE_WEIGHT( growth );
+ doLAYER_NOISE_WEIGHT( growth->layer_noise_weight );
+ break;
+
+ case T_place_boundary:
+L_place:
+ if( growth->place_boundary )
+ Unexpected( tok );
+ growth->place_boundary = new BOUNDARY( growth, T_place_boundary );
+ doBOUNDARY( growth->place_boundary );
+ break;
+
+ case T_boundary:
+ if( growth->boundary )
+ {
+ if( growth->place_boundary )
+ Unexpected( tok );
+ goto L_place;
+ }
+ growth->boundary = new BOUNDARY( growth );
+ doBOUNDARY( growth->boundary );
+ break;
+
+ case T_plane:
+ COPPER_PLANE* plane;
+ plane = new COPPER_PLANE( growth );
+ growth->planes.push_back( plane );
+ doKEEPOUT( plane );
+ break;
+
+ case T_region:
+ REGION* region;
+ region = new REGION( growth );
+ growth->regions.push_back( region );
+ doREGION( region );
+ break;
+
+ case T_snap_angle:
+ STRINGPROP* stringprop;
+ stringprop = new STRINGPROP( growth, T_snap_angle );
+ growth->Append( stringprop );
+ doSTRINGPROP( stringprop );
+ break;
+
+ case T_via:
+ if( growth->via )
+ Unexpected( tok );
+ growth->via = new VIA( growth );
+ doVIA( growth->via );
+ break;
+
+ case T_control:
+ if( growth->control )
+ Unexpected( tok );
+ growth->control = new CONTROL( growth );
+ doCONTROL( growth->control );
+ break;
+
+ case T_layer:
+ LAYER* layer;
+ layer = new LAYER( growth );
+ growth->layers.push_back( layer );
+ doLAYER( layer );
+ break;
+
+ case T_rule:
+ if( growth->rules )
+ Unexpected( tok );
+ growth->rules = new RULE( growth, T_rule );
+ doRULE( growth->rules );
+ break;
+
+ case T_place_rule:
+ if( growth->place_rules )
+ Unexpected( tok );
+ growth->place_rules = new RULE( growth, T_place_rule );
+ doRULE( growth->place_rules );
+ break;
+
+ case T_keepout:
+ case T_place_keepout:
+ case T_via_keepout:
+ case T_wire_keepout:
+ case T_bend_keepout:
+ case T_elongate_keepout:
+ KEEPOUT* keepout;
+ keepout = new KEEPOUT( growth, tok );
+ growth->keepouts.push_back( keepout );
+ doKEEPOUT( keepout );
+ break;
+
+ case T_grid:
+ GRID* grid;
+ grid = new GRID( growth );
+ growth->grids.push_back( grid );
+ doGRID( grid );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doSTRUCTURE_OUT( STRUCTURE_OUT* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ /*
+ <structure_out_descriptor >::=
+ (structure_out
+ {<layer_descriptor> }
+ [<rule_descriptor> ]
+ )
+ */
+
+ T tok = NextTok();
+
+ while( tok != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_layer:
+ LAYER* layer;
+ layer = new LAYER( growth );
+ growth->layers.push_back( layer );
+ doLAYER( layer );
+ break;
+
+ case T_rule:
+ if( growth->rules )
+ Unexpected( tok );
+ growth->rules = new RULE( growth, T_rule );
+ doRULE( growth->rules );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+
+ tok = NextTok();
+ }
+}
+
+
+void SPECCTRA_DB::doKEEPOUT( KEEPOUT* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok = NextTok();
+
+ if( IsSymbol(tok) )
+ {
+ growth->name = CurText();
+ tok = NextTok();
+ }
+
+ if( tok!=T_LEFT )
+ Expecting( T_LEFT );
+
+ while( tok != T_RIGHT )
+ {
+ if( tok!=T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_sequence_number:
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->sequence_number = atoi( CurText() );
+ NeedRIGHT();
+ break;
+
+ case T_rule:
+ if( growth->rules )
+ Unexpected( tok );
+ growth->rules = new RULE( growth, T_rule );
+ doRULE( growth->rules );
+ break;
+
+ case T_place_rule:
+ if( growth->place_rules )
+ Unexpected( tok );
+ growth->place_rules = new RULE( growth, T_place_rule );
+ doRULE( growth->place_rules );
+ break;
+
+ case T_rect:
+ if( growth->shape )
+ Unexpected( tok );
+ growth->shape = new RECTANGLE( growth );
+ doRECTANGLE( (RECTANGLE*) growth->shape );
+ break;
+
+ case T_circle:
+ if( growth->shape )
+ Unexpected( tok );
+ growth->shape = new CIRCLE( growth );
+ doCIRCLE( (CIRCLE*) growth->shape );
+ break;
+
+ case T_polyline_path:
+ tok = T_path;
+ case T_path:
+ case T_polygon:
+ if( growth->shape )
+ Unexpected( tok );
+ growth->shape = new PATH( growth, tok );
+ doPATH( (PATH*) growth->shape );
+ break;
+
+ case T_qarc:
+ if( growth->shape )
+ Unexpected( tok );
+ growth->shape = new QARC( growth );
+ doQARC( (QARC*) growth->shape );
+ break;
+
+ case T_window:
+ WINDOW* window;
+ window = new WINDOW( growth );
+ growth->windows.push_back( window );
+ doWINDOW( window );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+
+ tok = NextTok();
+ }
+}
+
+
+void SPECCTRA_DB::doCONNECT( CONNECT* growth ) throw( IO_ERROR )
+{
+ /* from page 143 of specctra spec:
+
+ (connect
+ {(terminal <object_type> [<pin_reference> ])}
+ )
+ */
+
+ T tok = NextTok();
+
+ while( tok != T_RIGHT )
+ {
+ if( tok!=T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+
+ switch( tok )
+ {
+ case T_terminal:
+ // since we do not use the terminal information, simlpy toss it.
+ while( ( tok = NextTok() ) != T_RIGHT && tok != T_EOF )
+ ;
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+
+ tok = NextTok();
+ }
+}
+
+
+void SPECCTRA_DB::doWINDOW( WINDOW* growth ) throw( IO_ERROR )
+{
+ T tok = NextTok();
+
+ while( tok != T_RIGHT )
+ {
+ if( tok!=T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_rect:
+ if( growth->shape )
+ Unexpected( tok );
+ growth->shape = new RECTANGLE( growth );
+ doRECTANGLE( (RECTANGLE*) growth->shape );
+ break;
+
+ case T_circle:
+ if( growth->shape )
+ Unexpected( tok );
+ growth->shape = new CIRCLE( growth );
+ doCIRCLE( (CIRCLE*) growth->shape );
+ break;
+
+ case T_polyline_path:
+ tok = T_path;
+ case T_path:
+ case T_polygon:
+ if( growth->shape )
+ Unexpected( tok );
+ growth->shape = new PATH( growth, tok );
+ doPATH( (PATH*) growth->shape );
+ break;
+
+ case T_qarc:
+ if( growth->shape )
+ Unexpected( tok );
+ growth->shape = new QARC( growth );
+ doQARC( (QARC*) growth->shape );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+
+ tok = NextTok();
+ }
+}
+
+
+void SPECCTRA_DB::doBOUNDARY( BOUNDARY* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok = NextTok();
+
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ if( tok == T_rect )
+ {
+ if( growth->paths.size() )
+ Unexpected( "rect when path already encountered" );
+
+ growth->rectangle = new RECTANGLE( growth );
+ doRECTANGLE( growth->rectangle );
+ NeedRIGHT();
+ }
+ else if( tok == T_path )
+ {
+ if( growth->rectangle )
+ Unexpected( "path when rect already encountered" );
+
+ for(;;)
+ {
+ if( tok != T_path )
+ Expecting( T_path );
+
+ PATH* path = new PATH( growth, T_path ) ;
+ growth->paths.push_back( path );
+
+ doPATH( path );
+
+ tok = NextTok();
+ if( tok == T_RIGHT )
+ break;
+
+ if( tok != T_LEFT )
+ Expecting(T_LEFT);
+
+ tok = NextTok();
+ }
+ }
+ else
+ Expecting( "rect|path" );
+}
+
+
+void SPECCTRA_DB::doPATH( PATH* growth ) throw( IO_ERROR )
+{
+ T tok = NextTok();
+
+ if( !IsSymbol( tok ) )
+ Expecting( "layer_id" );
+
+ growth->layer_id = CurText();
+
+ if( NextTok() != T_NUMBER )
+ Expecting( "aperture_width" );
+
+ growth->aperture_width = strtod( CurText(), NULL );
+
+ POINT ptTemp;
+
+ tok = NextTok();
+
+ do
+ {
+ if( tok != T_NUMBER )
+ Expecting( T_NUMBER );
+ ptTemp.x = strtod( CurText(), NULL );
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ ptTemp.y = strtod( CurText(), NULL );
+
+ growth->points.push_back( ptTemp );
+
+ } while( (tok = NextTok())!=T_RIGHT && tok!=T_LEFT );
+
+ if( tok == T_LEFT )
+ {
+ if( NextTok() != T_aperture_type )
+ Expecting( T_aperture_type );
+
+ tok = NextTok();
+ if( tok!=T_round && tok!=T_square )
+ Expecting( "round|square" );
+
+ growth->aperture_type = tok;
+
+ NeedRIGHT();
+ }
+}
+
+
+void SPECCTRA_DB::doRECTANGLE( RECTANGLE* growth ) throw( IO_ERROR )
+{
+ NeedSYMBOL();
+ growth->layer_id = CurText();
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->point0.x = strtod( CurText(), NULL );
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->point0.y = strtod( CurText(), NULL );
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->point1.x = strtod( CurText(), NULL );
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->point1.y = strtod( CurText(), NULL );
+
+ NeedRIGHT();
+}
+
+
+void SPECCTRA_DB::doCIRCLE( CIRCLE* growth ) throw( IO_ERROR )
+{
+ T tok;
+
+ NeedSYMBOL();
+ growth->layer_id = CurText();
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->diameter = strtod( CurText(), 0 );
+
+ tok = NextTok();
+ if( tok == T_NUMBER )
+ {
+ growth->vertex.x = strtod( CurText(), 0 );
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->vertex.y = strtod( CurText(), 0 );
+
+ tok = NextTok();
+ }
+
+ if( tok != T_RIGHT )
+ Expecting( T_RIGHT );
+}
+
+
+void SPECCTRA_DB::doQARC( QARC* growth ) throw( IO_ERROR )
+{
+ NeedSYMBOL();
+ growth->layer_id = CurText();
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->aperture_width = strtod( CurText(), 0 );
+
+ for( int i=0; i<3; ++i )
+ {
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->vertex[i].x = strtod( CurText(), 0 );
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->vertex[i].y = strtod( CurText(), 0 );
+ }
+
+ NeedRIGHT();
+}
+
+
+void SPECCTRA_DB::doSTRINGPROP( STRINGPROP* growth ) throw( IO_ERROR )
+{
+ NeedSYMBOL();
+ growth->value = CurText();
+ NeedRIGHT();
+}
+
+
+void SPECCTRA_DB::doTOKPROP( TOKPROP* growth ) throw( IO_ERROR )
+{
+ T tok = NextTok();
+
+ if( tok<0 )
+ Unexpected( CurText() );
+
+ growth->value = tok;
+
+ NeedRIGHT();
+}
+
+
+void SPECCTRA_DB::doVIA( VIA* growth ) throw( IO_ERROR )
+{
+ T tok;
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok == T_LEFT )
+ {
+ if( NextTok() != T_spare )
+ Expecting( T_spare );
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( !IsSymbol( tok ) )
+ Expecting( T_SYMBOL );
+
+ growth->spares.push_back( CurText() );
+ }
+ }
+ else if( IsSymbol( tok ) )
+ {
+ growth->padstacks.push_back( CurText() );
+ }
+ else
+ Unexpected( CurText() );
+ }
+}
+
+
+void SPECCTRA_DB::doCONTROL( CONTROL* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_via_at_smd:
+ tok = NextTok();
+ if( tok!=T_on && tok!=T_off )
+ Expecting( "on|off" );
+ growth->via_at_smd = (tok==T_on);
+ NeedRIGHT();
+ break;
+
+ case T_off_grid:
+ case T_route_to_fanout_only:
+ case T_force_to_terminal_point:
+ case T_same_net_checking:
+ case T_checking_trim_by_pin:
+ case T_noise_calculation:
+ case T_noise_accumulation:
+ case T_include_pins_in_crosstalk:
+ case T_bbv_ctr2ctr:
+ case T_average_pair_length:
+ case T_crosstalk_model:
+ case T_roundoff_rotation:
+ case T_microvia:
+ case T_reroute_order_viols:
+ TOKPROP* tokprop;
+ tokprop = new TOKPROP( growth, tok ) ;
+ growth->Append( tokprop );
+ doTOKPROP( tokprop );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doPROPERTIES( PROPERTIES* growth ) throw( IO_ERROR )
+{
+ T tok;
+ PROPERTY property; // construct it once here, append multiple times.
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ NeedSYMBOLorNUMBER();
+ property.name = CurText();
+
+ NeedSYMBOLorNUMBER();
+ property.value = CurText();
+
+ growth->push_back( property );
+
+ NeedRIGHT();
+ }
+}
+
+
+void SPECCTRA_DB::doLAYER( LAYER* growth ) throw( IO_ERROR )
+{
+ T tok = NextTok();
+
+ if( !IsSymbol(tok) )
+ Expecting(T_SYMBOL);
+
+ growth->name = CurText();
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_type:
+ tok = NextTok();
+ if( tok!=T_signal && tok!=T_power && tok!=T_mixed && tok!=T_jumper )
+ Expecting( "signal|power|mixed|jumper" );
+ growth->layer_type = tok;
+ if( NextTok()!=T_RIGHT )
+ Expecting(T_RIGHT);
+ break;
+
+ case T_rule:
+ growth->rules = new RULE( growth, T_rule );
+ doRULE( growth->rules );
+ break;
+
+ case T_property:
+ doPROPERTIES( &growth->properties );
+ break;
+
+ case T_direction:
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_horizontal:
+ case T_vertical:
+ case T_orthogonal:
+ case T_positive_diagonal:
+ case T_negative_diagonal:
+ case T_diagonal:
+ case T_off:
+ growth->direction = tok;
+ break;
+ default:
+ // the spec has an example show an abbreviation of the "horizontal" keyword. Ouch.
+ if( !strcmp( "hori", CurText() ) )
+ {
+ growth->direction = T_horizontal;
+ break;
+ }
+ else if( !strcmp( "vert", CurText() ) )
+ {
+ growth->direction = T_vertical;
+ break;
+ }
+ Expecting( "horizontal|vertical|orthogonal|positive_diagonal|negative_diagonal|diagonal|off" );
+ }
+ if( NextTok()!=T_RIGHT )
+ Expecting(T_RIGHT);
+ break;
+
+ case T_cost:
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_forbidden:
+ case T_high:
+ case T_medium:
+ case T_low:
+ case T_free:
+ growth->cost = tok;
+ break;
+ case T_NUMBER:
+ // store as negative so we can differentiate between
+ // T (positive) and T_NUMBER (negative)
+ growth->cost = -atoi( CurText() );
+ break;
+ default:
+ Expecting( "forbidden|high|medium|low|free|<positive_integer>|-1" );
+ }
+ tok = NextTok();
+ if( tok == T_LEFT )
+ {
+ if( NextTok() != T_type )
+ Unexpected( CurText() );
+
+ tok = NextTok();
+ if( tok!=T_length && tok!=T_way )
+ Expecting( "length|way" );
+
+ growth->cost_type = tok;
+ if( NextTok()!=T_RIGHT )
+ Expecting(T_RIGHT);
+
+ tok = NextTok();
+ }
+ if( tok!=T_RIGHT )
+ Expecting(T_RIGHT);
+ break;
+
+ case T_use_net:
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( !IsSymbol(tok) )
+ Expecting( T_SYMBOL );
+
+ growth->use_net.push_back( CurText() );
+ }
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doRULE( RULE* growth ) throw( IO_ERROR )
+{
+ std::string builder;
+ int bracketNesting = 1; // we already saw the opening T_LEFT
+ T tok = T_NONE;
+
+ while( bracketNesting!=0 && tok!=T_EOF )
+ {
+ tok = NextTok();
+
+ if( tok==T_LEFT)
+ ++bracketNesting;
+
+ else if( tok==T_RIGHT )
+ --bracketNesting;
+
+ if( bracketNesting >= 1 )
+ {
+ if( PrevTok()!=T_LEFT && tok!=T_RIGHT && (tok!=T_LEFT || bracketNesting>2) )
+ builder += ' ';
+
+ if( tok==T_STRING )
+ builder += quote_char;
+
+ builder += CurText();
+
+ if( tok==T_STRING )
+ builder += quote_char;
+ }
+
+ // When the nested rule is closed with a T_RIGHT and we are back down
+ // to bracketNesting == 1, (inside the <rule_descriptor> but outside
+ // the last rule). Then save the last rule and clear the string builder.
+ if( bracketNesting == 1 )
+ {
+ growth->rules.push_back( builder );
+ builder.clear();
+ }
+ }
+
+ if( tok==T_EOF )
+ Unexpected( T_EOF );
+}
+
+
+#if 0
+void SPECCTRA_DB::doPLACE_RULE( PLACE_RULE* growth, bool expect_object_type ) throw( IO_ERROR )
+{
+ /* (place_rule [<structure_place_rule_object> ]
+ {[<spacing_descriptor> |
+ <permit_orient_descriptor> |
+ <permit_side_descriptor> |
+ <opposite_side_descriptor> ]}
+ )
+ */
+
+ T tok = NextTok();
+
+ if( tok!=T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ if( tok==T_object_type )
+ {
+ if( !expect_object_type )
+ Unexpected( tok );
+
+ /* [(object_type
+ [pcb |
+ image_set [large | small | discrete | capacitor | resistor]
+ [(image_type [smd | pin])]]
+ )]
+ */
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_pcb:
+ growth->object_type = tok;
+ break;
+
+ case T_image_set:
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_large:
+ case T_small:
+ case T_discrete:
+ case T_capacitor:
+ case T_resistor:
+ growth->object_type = tok;
+ break;
+ default:
+ Unexpected( CurText() );
+ }
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+
+ tok = NextTok();
+ if( tok == T_LEFT )
+ {
+ tok = NextTok();
+ if( tok != T_image_type )
+ Expecting( T_image_type );
+
+ tok = NextTok();
+ if( tok!=T_smd && tok!=T_pin )
+ Expecting( "smd|pin" );
+
+ NeedRIGHT();
+
+ tok = NextTok();
+ }
+
+ if( tok != T_RIGHT )
+ Expecting( T_RIGHT );
+
+ tok = NextTok();
+ }
+
+ /* {[<spacing_descriptor> |
+ <permit_orient_descriptor> |
+ <permit_side_descriptor> | <opposite_side_descriptor> ]}
+ */
+ doRULE( growth );
+}
+#endif
+
+
+void SPECCTRA_DB::doREGION( REGION* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok = NextTok();
+
+ if( IsSymbol(tok) )
+ {
+ growth->region_id = CurText();
+ tok = NextTok();
+ }
+
+ for(;;)
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_rect:
+ if( growth->rectangle )
+ Unexpected( tok );
+ growth->rectangle = new RECTANGLE( growth );
+ doRECTANGLE( growth->rectangle );
+ break;
+
+ case T_polygon:
+ if( growth->polygon )
+ Unexpected( tok );
+ growth->polygon = new PATH( growth, T_polygon );
+ doPATH( growth->polygon );
+ break;
+
+ case T_region_net:
+ case T_region_class:
+ STRINGPROP* stringprop;
+ stringprop = new STRINGPROP( growth, tok );
+ growth->Append( stringprop );
+ doSTRINGPROP( stringprop );
+ break;
+
+ case T_region_class_class:
+ CLASS_CLASS* class_class;
+ class_class = new CLASS_CLASS( growth, tok );
+ growth->Append( class_class );
+ doCLASS_CLASS( class_class );
+ break;
+
+ case T_rule:
+ if( growth->rules )
+ Unexpected( tok );
+ growth->rules = new RULE( growth, T_rule );
+ doRULE( growth->rules );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+
+ tok = NextTok();
+ if( tok == T_RIGHT )
+ {
+ if( !growth->rules )
+ Expecting( T_rule );
+ break;
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doCLASS_CLASS( CLASS_CLASS* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok = NextTok();
+
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ switch( tok )
+ {
+ case T_classes:
+ if( growth->classes )
+ Unexpected( tok );
+ growth->classes = new CLASSES( growth );
+ doCLASSES( growth->classes );
+ break;
+
+ case T_rule:
+ // only T_class_class takes a T_rule
+ if( growth->Type() == T_region_class_class )
+ Unexpected( tok );
+ RULE* rule;
+ rule = new RULE( growth, T_rule );
+ growth->Append( rule );
+ doRULE( rule );
+ break;
+
+ case T_layer_rule:
+ // only T_class_class takes a T_layer_rule
+ if( growth->Type() == T_region_class_class )
+ Unexpected( tok );
+ LAYER_RULE* layer_rule;
+ layer_rule = new LAYER_RULE( growth );
+ growth->Append( layer_rule );
+ doLAYER_RULE( layer_rule );
+ break;
+
+ default:
+ Unexpected( tok );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doCLASSES( CLASSES* growth ) throw( IO_ERROR )
+{
+ T tok = NextTok();
+
+ // require at least 2 class_ids
+
+ if( !IsSymbol( tok ) )
+ Expecting( "class_id" );
+
+ growth->class_ids.push_back( CurText() );
+
+ do
+ {
+ tok = NextTok();
+ if( !IsSymbol( tok ) )
+ Expecting( "class_id" );
+
+ growth->class_ids.push_back( CurText() );
+
+ } while( (tok = NextTok()) != T_RIGHT );
+}
+
+
+void SPECCTRA_DB::doGRID( GRID* growth ) throw( IO_ERROR )
+{
+ T tok = NextTok();
+
+ switch( tok )
+ {
+ case T_via:
+ case T_wire:
+ case T_via_keepout:
+ case T_snap:
+ case T_place:
+ growth->grid_type = tok;
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->dimension = strtod( CurText(), 0 );
+ tok = NextTok();
+ if( tok == T_LEFT )
+ {
+ while( (tok=NextTok()) != T_RIGHT )
+ {
+ if( tok==T_direction )
+ {
+ if( growth->grid_type == T_place )
+ Unexpected( tok );
+ tok = NextTok();
+ if( tok!=T_x && tok!=T_y )
+ Unexpected( CurText() );
+ growth->direction = tok;
+ if( NextTok() != T_RIGHT )
+ Expecting(T_RIGHT);
+ }
+ else if( tok==T_offset )
+ {
+ if( growth->grid_type == T_place )
+ Unexpected( tok );
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+
+ growth->offset = strtod( CurText(), 0 );
+
+ if( NextTok() != T_RIGHT )
+ Expecting(T_RIGHT);
+ }
+ else if( tok==T_image_type )
+ {
+ if( growth->grid_type != T_place )
+ Unexpected( tok );
+ tok = NextTok();
+ if( tok!=T_smd && tok!=T_pin )
+ Unexpected( CurText() );
+ growth->image_type = tok;
+ if( NextTok() != T_RIGHT )
+ Expecting(T_RIGHT);
+ }
+ }
+ }
+ break;
+
+ default:
+ Unexpected( tok );
+ }
+}
+
+
+void SPECCTRA_DB::doLAYER_RULE( LAYER_RULE* growth ) throw( IO_ERROR )
+{
+ T tok;
+
+ NeedSYMBOL();
+
+ do
+ {
+ growth->layer_ids.push_back( CurText() );
+
+ } while( IsSymbol(tok = NextTok()) );
+
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ if( NextTok() != T_rule )
+ Expecting( T_rule );
+
+ growth->rule = new RULE( growth, T_rule );
+ doRULE( growth->rule );
+
+ NeedRIGHT();
+}
+
+
+void SPECCTRA_DB::doPLACE( PLACE* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok = NextTok();
+
+ if( !IsSymbol( tok ) )
+ Expecting( "component_id" );
+
+ growth->component_id = CurText();
+
+ tok = NextTok();
+ if( tok == T_NUMBER )
+ {
+ POINT point;
+
+ point.x = strtod( CurText(), 0 );
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ point.y = strtod( CurText(), 0 );
+
+ growth->SetVertex( point );
+
+ tok = NextTok();
+ if( tok!=T_front && tok!=T_back )
+ Expecting( "front|back" );
+ growth->side = tok;
+
+ if( NextTok() != T_NUMBER )
+ Expecting( "rotation" );
+ growth->SetRotation( strtod( CurText(), 0) );
+ }
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_mirror:
+ tok = NextTok();
+ if( tok==T_x || tok==T_y || tok==T_xy || tok==T_off )
+ growth->mirror = tok;
+ else
+ Expecting("x|y|xy|off");
+ break;
+
+ case T_status:
+ tok = NextTok();
+ if( tok==T_added || tok==T_deleted || tok==T_substituted )
+ growth->status = tok;
+ else
+ Expecting("added|deleted|substituted");
+ break;
+
+ case T_logical_part:
+ if( growth->logical_part.size() )
+ Unexpected( tok );
+ tok = NextTok();
+ if( !IsSymbol( tok ) )
+ Expecting( "logical_part_id");
+ growth->logical_part = CurText();
+ break;
+
+ case T_place_rule:
+ if( growth->place_rules )
+ Unexpected( tok );
+ growth->place_rules = new RULE( growth, T_place_rule );
+ doRULE( growth->place_rules );
+ break;
+
+ case T_property:
+ if( growth->properties.size() )
+ Unexpected( tok );
+ doPROPERTIES( &growth->properties );
+ break;
+
+ case T_lock_type:
+ tok = NextTok();
+ if( tok==T_position || tok==T_gate || tok==T_subgate || tok==T_pin )
+ growth->lock_type = tok;
+ else
+ Expecting("position|gate|subgate|pin");
+ break;
+
+ case T_rule:
+ if( growth->rules || growth->region )
+ Unexpected( tok );
+ growth->rules = new RULE( growth, T_rule );
+ doRULE( growth->rules );
+ break;
+
+ case T_region:
+ if( growth->rules || growth->region )
+ Unexpected( tok );
+ growth->region = new REGION( growth );
+ doREGION( growth->region );
+ break;
+
+ case T_pn:
+ if( growth->part_number.size() )
+ Unexpected( tok );
+ NeedSYMBOLorNUMBER();
+ growth->part_number = CurText();
+ NeedRIGHT();
+ break;
+
+ default:
+ Unexpected( tok );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doCOMPONENT( COMPONENT* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok = NextTok();
+
+ if( !IsSymbol( tok ) && tok != T_NUMBER )
+ Expecting( "image_id" );
+ growth->image_id = CurText();
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_place:
+ PLACE* place;
+ place = new PLACE( growth );
+ growth->places.push_back( place );
+ doPLACE( place );
+ break;
+
+ default:
+ Unexpected(tok);
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doPLACEMENT( PLACEMENT* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok == T_EOF )
+ Unexpected( T_EOF );
+
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+
+ switch( tok )
+ {
+ case T_unit:
+ case T_resolution:
+ growth->unit = new UNIT_RES( growth, tok );
+ if( tok==T_resolution )
+ doRESOLUTION( growth->unit );
+ else
+ doUNIT( growth->unit );
+ break;
+
+ case T_place_control:
+ NeedRIGHT();
+ tok = NextTok();
+ if( tok != T_flip_style )
+ Expecting( T_flip_style );
+
+ tok = NextTok();
+ if( tok==T_mirror_first || tok==T_rotate_first )
+ growth->flip_style = tok;
+ else
+ Expecting( "mirror_first|rotate_first" );
+
+ NeedRIGHT();
+ NeedRIGHT();
+ break;
+
+ case T_component:
+ COMPONENT* component;
+ component = new COMPONENT( growth );
+ growth->components.push_back( component );
+ doCOMPONENT( component );
+ break;
+
+ default:
+ Unexpected( tok );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doPADSTACK( PADSTACK* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok = NextTok();
+
+ /* (padstack <padstack_id >
+ [<unit_descriptor> ]
+ {(shape <shape_descriptor>
+ [<reduced_shape_descriptor> ]
+ [(connect [on | off])]
+ [{<window_descriptor> }]
+ )}
+ [<attach_descriptor> ]
+ [{<pad_via_site_descriptor> }]
+ [(rotate [on | off])]
+ [(absolute [on | off])]
+ [(rule <clearance_descriptor> )])
+ */
+
+ // padstack_id may be a number
+ if( !IsSymbol( tok ) && tok!=T_NUMBER )
+ Expecting( "padstack_id" );
+
+ growth->padstack_id = CurText();
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_unit:
+ if( growth->unit )
+ Unexpected( tok );
+ growth->unit = new UNIT_RES( growth, tok );
+ doUNIT( growth->unit );
+ break;
+
+ case T_rotate:
+ tok = NextTok();
+ if( tok!=T_on && tok!=T_off )
+ Expecting( "on|off" );
+ growth->rotate = tok;
+ NeedRIGHT();
+ break;
+
+ case T_absolute:
+ tok = NextTok();
+ if( tok!=T_on && tok!=T_off )
+ Expecting( "on|off" );
+ growth->absolute = tok;
+ NeedRIGHT();
+ break;
+
+ case T_shape:
+ SHAPE* shape;
+ shape = new SHAPE( growth );
+ growth->Append( shape );
+ doSHAPE( shape );
+ break;
+
+ case T_attach:
+ tok = NextTok();
+ if( tok!=T_off && tok!=T_on )
+ Expecting( "off|on" );
+ growth->attach = tok;
+ tok = NextTok();
+ if( tok == T_LEFT )
+ {
+ if( NextTok() != T_use_via )
+ Expecting( T_use_via );
+
+ NeedSYMBOL();
+ growth->via_id = CurText();
+
+ NeedRIGHT();
+ NeedRIGHT();
+ }
+ break;
+
+ /*
+ case T_via_site: not supported
+ break;
+ */
+
+ case T_rule:
+ if( growth->rules )
+ Unexpected( tok );
+ growth->rules = new RULE( growth, T_rule );
+ doRULE( growth->rules );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doSHAPE( SHAPE* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* (shape <shape_descriptor>
+ [<reduced_shape_descriptor> ]
+ [(connect [on | off])]
+ [{<window_descriptor> }])
+ */
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_polyline_path:
+ tok = T_path;
+ case T_rect:
+ case T_circle:
+ case T_path:
+ case T_polygon:
+ case T_qarc:
+L_done_that:
+ if( growth->shape )
+ Unexpected( tok );
+ break;
+ default:
+ // the example in the spec uses "circ" instead of "circle". Bad!
+ if( !strcmp( "circ", CurText() ) )
+ {
+ tok = T_circle;
+ goto L_done_that;
+ }
+ }
+
+ switch( tok )
+ {
+ case T_rect:
+ growth->shape = new RECTANGLE( growth );
+ doRECTANGLE( (RECTANGLE*) growth->shape );
+ break;
+
+ case T_circle:
+ growth->shape = new CIRCLE( growth );
+ doCIRCLE( (CIRCLE*)growth->shape );
+ break;
+
+ case T_path:
+ case T_polygon:
+ growth->shape = new PATH( growth, tok );
+ doPATH( (PATH*)growth->shape );
+ break;
+
+ case T_qarc:
+ growth->shape = new QARC( growth );
+ doQARC( (QARC*)growth->shape );
+ break;
+
+ case T_connect:
+ tok = NextTok();
+ if( tok!=T_on && tok!=T_off )
+ Expecting( "on|off" );
+ growth->connect = tok;
+ NeedRIGHT();
+ break;
+
+ case T_window:
+ WINDOW* window;
+ window = new WINDOW( growth );
+ growth->windows.push_back( window );
+ doWINDOW( window );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doIMAGE( IMAGE* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok = NextTok();
+
+ /* <image_descriptor >::=
+ (image <image_id >
+ [(side [front | back | both])]
+ [<unit_descriptor> ]
+ [<outline_descriptor> ]
+ {(pin <padstack_id > [(rotate <rotation> )]
+ [<reference_descriptor> | <pin_array_descriptor> ]
+ [<user_property_descriptor> ])}
+ [{<conductor_shape_descriptor> }]
+ [{<conductor_via_descriptor> }]
+ [<rule_descriptor> ]
+ [<place_rule_descriptor> ]
+ [{<keepout_descriptor> }]
+ [<image_property_descriptor> ]
+ )
+ */
+
+ if( !IsSymbol( tok ) && tok != T_NUMBER )
+ Expecting( "image_id" );
+
+ growth->image_id = CurText();
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_unit:
+ if( growth->unit )
+ Unexpected( tok );
+ growth->unit = new UNIT_RES( growth, tok );
+ doUNIT( growth->unit );
+ break;
+
+ case T_side:
+ tok = NextTok();
+ if( tok!=T_front && tok!=T_back && tok!=T_both )
+ Expecting( "front|back|both" );
+ growth->side = tok;
+ NeedRIGHT();
+ break;
+
+ case T_outline:
+ SHAPE* outline;
+ outline = new SHAPE( growth, T_outline ); // use SHAPE for T_outline
+ growth->Append( outline );
+ doSHAPE( outline );
+ break;
+
+ case T_pin:
+ PIN* pin;
+ pin = new PIN( growth );
+ growth->pins.push_back( pin );
+ doPIN( pin );
+ break;
+
+ case T_rule:
+ if( growth->rules )
+ Unexpected( tok );
+ growth->rules = new RULE( growth, tok );
+ doRULE( growth->rules );
+ break;
+
+ case T_place_rule:
+ if( growth->place_rules )
+ Unexpected( tok );
+ growth->place_rules = new RULE( growth, tok );
+ doRULE( growth->place_rules );
+ break;
+
+ case T_keepout:
+ case T_place_keepout:
+ case T_via_keepout:
+ case T_wire_keepout:
+ case T_bend_keepout:
+ case T_elongate_keepout:
+ KEEPOUT* keepout;
+ keepout = new KEEPOUT( growth, tok );
+ growth->keepouts.push_back( keepout );
+ doKEEPOUT( keepout );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doPIN( PIN* growth ) throw( IO_ERROR )
+{
+ T tok = NextTok();
+
+ /* (pin <padstack_id > [(rotate <rotation> )]
+ [<reference_descriptor> | <pin_array_descriptor> ]
+ [<user_property_descriptor> ])
+ */
+
+ // a padstack_id may be a number
+ if( !IsSymbol( tok ) && tok!=T_NUMBER )
+ Expecting( "padstack_id" );
+
+ growth->padstack_id = CurText();
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok == T_LEFT )
+ {
+ tok = NextTok();
+ if( tok != T_rotate )
+ Expecting( T_rotate );
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->SetRotation( strtod( CurText(), 0 ) );
+ NeedRIGHT();
+ }
+ else
+ {
+ if( !IsSymbol(tok) && tok!=T_NUMBER )
+ Expecting( "pin_id" );
+
+ growth->pin_id = CurText();
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->vertex.x = strtod( CurText(), 0 );
+
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->vertex.y = strtod( CurText(), 0 );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* <library_descriptor >::=
+ (library
+ [<unit_descriptor> ]
+ {<image_descriptor> }
+ [{<jumper_descriptor> }]
+ {<padstack_descriptor> }
+ {<via_array_template_descriptor> }
+ [<directory_descriptor> ]
+ [<extra_image_directory_descriptor> ]
+ [{<family_family_descriptor> }]
+ [{<image_image_descriptor> }]
+ )
+ */
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_unit:
+ if( growth->unit )
+ Unexpected( tok );
+ growth->unit = new UNIT_RES( growth, tok );
+ doUNIT( growth->unit );
+ break;
+
+ case T_padstack:
+ PADSTACK* padstack;
+ padstack = new PADSTACK();
+ growth->AddPadstack( padstack );
+ doPADSTACK( padstack );
+ break;
+
+ case T_image:
+ IMAGE* image;
+ image = new IMAGE( growth );
+ growth->images.push_back( image );
+ doIMAGE( image );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doNET( NET* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok = NextTok();
+ PIN_REFS* pin_refs;
+
+ /* <net_descriptor >::=
+ (net <net_id >
+ [(unassigned)]
+ [(net_number <integer >)]
+ [(pins {<pin_reference> }) | (order {<pin_reference> })]
+ [<component_order_descriptor> ]
+ [(type [fix | normal])]
+ [<user_property_descriptor> ]
+ [<circuit_descriptor> ]
+ [<rule_descriptor> ]
+ [{<layer_rule_descriptor> }]
+ [<fromto_descriptor> ]
+ [(expose {<pin_reference> })]
+ [(noexpose {<pin_reference> })]
+ [(source {<pin_reference> })]
+ [(load {<pin_reference> })]
+ [(terminator {<pin_reference> })]
+ [(supply [power | ground])]
+ )
+ */
+
+ if( !IsSymbol( tok ) )
+ Expecting( "net_id" );
+
+ growth->net_id = CurText();
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_unassigned:
+ growth->unassigned = true;
+ NeedRIGHT();
+ break;
+
+ case T_net_number:
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->net_number = atoi( CurText() );
+ NeedRIGHT();
+ break;
+
+ case T_pins:
+ case T_order:
+ growth->pins_type = tok;
+ pin_refs = &growth->pins;
+ goto L_pins;
+
+ case T_expose:
+ pin_refs = &growth->expose;
+ goto L_pins;
+
+ case T_noexpose:
+ pin_refs = &growth->noexpose;
+ goto L_pins;
+
+ case T_source:
+ pin_refs = &growth->source;
+ goto L_pins;
+
+ case T_load:
+ pin_refs = &growth->load;
+ goto L_pins;
+
+ case T_terminator:
+ pin_refs = &growth->terminator;
+ //goto L_pins;
+
+L_pins:
+ {
+ PIN_REF empty( growth );
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ // copy the empty one, then fill its copy later thru pin_ref.
+ pin_refs->push_back( empty );
+
+ PIN_REF* pin_ref = &pin_refs->back();
+
+ readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
+ }
+ }
+ break;
+
+ case T_comp_order:
+ if( growth->comp_order )
+ Unexpected( tok );
+ growth->comp_order = new COMP_ORDER( growth );
+ doCOMP_ORDER( growth->comp_order );
+ break;
+
+ case T_type:
+ tok = NextTok();
+ if( tok!=T_fix && tok!=T_normal )
+ Expecting( "fix|normal" );
+ growth->type = tok;
+ NeedRIGHT();
+ break;
+
+/* @todo
+ case T_circuit:
+ break;
+*/
+
+ case T_rule:
+ if( growth->rules )
+ Unexpected( tok );
+ growth->rules = new RULE( growth, T_rule );
+ doRULE( growth->rules );
+ break;
+
+ case T_layer_rule:
+ LAYER_RULE* layer_rule;
+ layer_rule = new LAYER_RULE( growth );
+ growth->layer_rules.push_back( layer_rule );
+ doLAYER_RULE( layer_rule );
+ break;
+
+ case T_fromto:
+ FROMTO* fromto;
+ fromto = new FROMTO( growth );
+ growth->fromtos.push_back( fromto );
+ doFROMTO( fromto );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doTOPOLOGY( TOPOLOGY* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* <topology_descriptor >::=
+ (topology {[<fromto_descriptor> |
+ <component_order_descriptor> ]})
+ */
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_fromto:
+ FROMTO* fromto;
+ fromto = new FROMTO( growth );
+ growth->fromtos.push_back( fromto );
+ doFROMTO( fromto );
+ break;
+
+ case T_comp_order:
+ COMP_ORDER* comp_order;
+ comp_order = new COMP_ORDER( growth );
+ growth->comp_orders.push_back( comp_order );
+ doCOMP_ORDER( comp_order );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* <class_descriptor >::=
+ (class
+ <class_id > {[{<net_id >} | {<composite_name_list> }]}
+ [<circuit_descriptor> ]
+ [<rule_descriptor> ]
+ [{<layer_rule_descriptor> }]
+ [<topology_descriptor> ]
+ )
+ */
+
+ NeedSYMBOL();
+
+ growth->class_id = CurText();
+
+ // do net_ids, do not support <composite_name_list>s at this time
+ while( IsSymbol(tok = NextTok()) )
+ {
+ growth->net_ids.push_back( CurText() );
+ }
+
+
+ while( tok != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_rule:
+ if( growth->rules )
+ Unexpected( tok );
+ growth->rules = new RULE( growth, T_rule );
+ doRULE( growth->rules );
+ break;
+
+ case T_layer_rule:
+ LAYER_RULE* layer_rule;
+ layer_rule = new LAYER_RULE( growth );
+ growth->layer_rules.push_back( layer_rule );
+ doLAYER_RULE( layer_rule );
+ break;
+
+ case T_topology:
+ if( growth->topology )
+ Unexpected( tok );
+ growth->topology = new TOPOLOGY( growth );
+ doTOPOLOGY( growth->topology );
+ break;
+
+ case T_circuit: // handle all the circuit_descriptor here as strings
+ {
+ std::string builder;
+ int bracketNesting = 1; // we already saw the opening T_LEFT
+ T tok = T_NONE;
+
+ while( bracketNesting!=0 && tok!=T_EOF )
+ {
+ tok = NextTok();
+
+ if( tok==T_LEFT)
+ ++bracketNesting;
+
+ else if( tok==T_RIGHT )
+ --bracketNesting;
+
+ if( bracketNesting >= 1 )
+ {
+ T prevTok = (T) PrevTok();
+
+ if( prevTok!=T_LEFT && prevTok!=T_circuit && tok!=T_RIGHT )
+ builder += ' ';
+
+ if( tok==T_STRING )
+ builder += quote_char;
+
+ builder += CurText();
+
+ if( tok==T_STRING )
+ builder += quote_char;
+ }
+
+ // When the nested rule is closed with a T_RIGHT and we are back down
+ // to bracketNesting == 0, then save the builder and break;
+ if( bracketNesting == 0 )
+ {
+ growth->circuit.push_back( builder );
+ break;
+ }
+ }
+
+ if( tok==T_EOF )
+ Unexpected( T_EOF );
+ } // scope bracket
+ break;
+
+ default:
+ Unexpected( CurText() );
+ } // switch
+
+ tok = NextTok();
+
+ } // while
+}
+
+
+void SPECCTRA_DB::doNETWORK( NETWORK* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* <network_descriptor >::=
+ (network
+ {<net_descriptor>}
+ [{<class_descriptor> }]
+ [{<class_class_descriptor> }]
+ [{<group_descriptor> }]
+ [{<group_set_descriptor> }]
+ [{<pair_descriptor> }]
+ [{<bundle_descriptor> }]
+ )
+ */
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_net:
+ NET* net;
+ net = new NET( growth );
+ growth->nets.push_back( net );
+ doNET( net );
+ break;
+
+ case T_class:
+ CLASS* myclass;
+ myclass = new CLASS( growth );
+ growth->classes.push_back( myclass );
+ doCLASS( myclass );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doCOMP_ORDER( COMP_ORDER* growth ) throw( IO_ERROR )
+{
+ T tok;
+
+ /* <component_order_descriptor >::=
+ (comp_order {<placement_id> })
+ */
+
+ while( IsSymbol(tok = NextTok()) )
+ {
+ growth->placement_ids.push_back( CurText() );
+ }
+
+ if( tok != T_RIGHT )
+ Expecting( T_RIGHT );
+}
+
+
+void SPECCTRA_DB::doFROMTO( FROMTO* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* <fromto_descriptor >::=
+ {(fromto
+ [<pin_reference> | <virtual_pin_descriptor> ] | <component_id >]
+ [<pin_reference> | <virtual_pin_descriptor> | <component_id >]
+ [(type [fix | normal | soft])]
+ [(net <net_id >)]
+ [<rule_descriptor> ]
+ [<circuit_descriptor> ]
+ [{<layer_rule_descriptor> }]
+ )}
+ */
+
+
+ // read the first two grammar items in as 2 single tokens, i.e. do not
+ // split apart the <pin_reference>s into 3 separate tokens. Do this by
+ // turning off the string delimiter in the lexer.
+
+ char old = SetStringDelimiter( 0 );
+
+ if( !IsSymbol(NextTok() ) )
+ {
+ SetStringDelimiter( old );
+ Expecting( T_SYMBOL );
+ }
+ growth->fromText = CurText();
+
+ if( !IsSymbol(NextTok() ) )
+ {
+ SetStringDelimiter( old );
+ Expecting( T_SYMBOL );
+ }
+ growth->toText = CurText();
+
+ SetStringDelimiter( old );
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_type:
+ tok = NextTok();
+ if( tok!=T_fix && tok!=T_normal && tok!=T_soft )
+ Expecting( "fix|normal|soft" );
+ growth->fromto_type = tok;
+ NeedRIGHT();
+ break;
+
+ case T_rule:
+ if( growth->rules )
+ Unexpected( tok );
+ growth->rules = new RULE( growth, T_rule );
+ doRULE( growth->rules );
+ break;
+
+ case T_layer_rule:
+ LAYER_RULE* layer_rule;
+ layer_rule = new LAYER_RULE( growth );
+ growth->layer_rules.push_back( layer_rule );
+ doLAYER_RULE( layer_rule );
+ break;
+
+ case T_net:
+ if( growth->net_id.size() )
+ Unexpected( tok );
+ NeedSYMBOL();
+ growth->net_id = CurText();
+ NeedRIGHT();
+ break;
+
+ // circuit descriptor not supported at this time
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doWIRE( WIRE* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* <wire_shape_descriptor >::=
+ (wire
+ <shape_descriptor>
+ [(net <net_id >)]
+ [(turret <turret#> )]
+ [(type [fix | route | normal | protect])]
+ [(attr [test | fanout | bus | jumper])]
+ [(shield <net_id >)]
+ [{<window_descriptor> }]
+ [(connect
+ (terminal <object_type> [<pin_reference> ])
+ (terminal <object_type> [<pin_reference> ])
+ )]
+ [(supply)]
+ )
+ */
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_rect:
+ if( growth->shape )
+ Unexpected( tok );
+ growth->shape = new RECTANGLE( growth );
+ doRECTANGLE( (RECTANGLE*) growth->shape );
+ break;
+
+ case T_circle:
+ if( growth->shape )
+ Unexpected( tok );
+ growth->shape = new CIRCLE( growth );
+ doCIRCLE( (CIRCLE*) growth->shape );
+ break;
+
+ case T_polyline_path:
+ tok = T_path;
+ case T_path:
+ case T_polygon:
+ if( growth->shape )
+ Unexpected( tok );
+ growth->shape = new PATH( growth, tok );
+ doPATH( (PATH*) growth->shape );
+ break;
+
+ case T_qarc:
+ if( growth->shape )
+ Unexpected( tok );
+ growth->shape = new QARC( growth );
+ doQARC( (QARC*) growth->shape );
+ break;
+
+ case T_net:
+ NeedSYMBOL();
+ growth->net_id = CurText();
+ NeedRIGHT();
+ break;
+
+ case T_turret:
+ if( NextTok() != T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->turret = atoi( CurText() );
+ NeedRIGHT();
+ break;
+
+ case T_type:
+ tok = NextTok();
+ if( tok!=T_fix && tok!=T_route && tok!=T_normal && tok!=T_protect )
+ Expecting( "fix|route|normal|protect" );
+ growth->wire_type = tok;
+ NeedRIGHT();
+ break;
+
+ case T_attr:
+ tok = NextTok();
+ if( tok!=T_test && tok!=T_fanout && tok!=T_bus && tok!=T_jumper )
+ Expecting( "test|fanout|bus|jumper" );
+ growth->attr = tok;
+ NeedRIGHT();
+ break;
+
+ case T_shield:
+ NeedSYMBOL();
+ growth->shield = CurText();
+ NeedRIGHT();
+ break;
+
+ case T_window:
+ WINDOW* window;
+ window = new WINDOW( growth );
+ growth->windows.push_back( window );
+ doWINDOW( window );
+ break;
+
+ case T_connect:
+ if( growth->connect )
+ Unexpected( tok );
+ growth->connect = new CONNECT( growth );
+ doCONNECT( growth->connect );
+ break;
+
+ case T_supply:
+ growth->supply = true;
+ NeedRIGHT();
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doWIRE_VIA( WIRE_VIA* growth ) throw( IO_ERROR )
+{
+ T tok;
+ POINT point;
+
+ /* <wire_via_descriptor >::=
+ (via
+ <padstack_id > {<vertex> }
+ [(net <net_id >)]
+ [(via_number <via#> )]
+ [(type [fix | route | normal | protect])]
+ [(attr [test | fanout | jumper |
+ virtual_pin <virtual_pin_name> ])]
+ [(contact {<layer_id >})]
+ [(supply)]
+ )
+ (virtual_pin
+ <virtual_pin_name> <vertex> (net <net_id >)
+ )
+ */
+
+ NeedSYMBOL();
+ growth->padstack_id = CurText();
+
+ while( (tok = NextTok()) == T_NUMBER )
+ {
+ point.x = strtod( CurText(), 0 );
+
+ if( NextTok() != T_NUMBER )
+ Expecting( "vertex.y" );
+
+ point.y = strtod( CurText(), 0 );
+
+ growth->vertexes.push_back( point );
+ }
+
+ while( tok != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_net:
+ NeedSYMBOL();
+ growth->net_id = CurText();
+ NeedRIGHT();
+ break;
+
+ case T_via_number:
+ if( NextTok() != T_NUMBER )
+ Expecting( "<via#>" );
+ growth->via_number = atoi( CurText() );
+ NeedRIGHT();
+ break;
+
+ case T_type:
+ tok = NextTok();
+ if( tok!=T_fix && tok!=T_route && tok!=T_normal && tok!=T_protect )
+ Expecting( "fix|route|normal|protect" );
+ growth->via_type = tok;
+ NeedRIGHT();
+ break;
+
+ case T_attr:
+ tok = NextTok();
+ if( tok!=T_test && tok!=T_fanout && tok!=T_jumper && tok!=T_virtual_pin )
+ Expecting( "test|fanout|jumper|virtual_pin" );
+ growth->attr = tok;
+ if( tok == T_virtual_pin )
+ {
+ NeedSYMBOL();
+ growth->virtual_pin_name = CurText();
+ }
+ NeedRIGHT();
+ break;
+
+ case T_contact:
+ NeedSYMBOL();
+ tok = T_SYMBOL;
+ while( IsSymbol(tok) )
+ {
+ growth->contact_layers.push_back( CurText() );
+ tok = NextTok();
+ }
+ if( tok != T_RIGHT )
+ Expecting( T_RIGHT );
+ break;
+
+ case T_supply:
+ growth->supply = true;
+ NeedRIGHT();
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+
+ tok = NextTok();
+ }
+}
+
+
+void SPECCTRA_DB::doWIRING( WIRING* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* <wiring_descriptor >::=
+ (wiring
+ [<unit_descriptor> | <resolution_descriptor> | null]
+ {<wire_descriptor> }
+ [<test_points_descriptor> ]
+ {[<supply_pin_descriptor> ]}
+ )
+ */
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_unit:
+ if( growth->unit )
+ Unexpected( tok );
+ growth->unit = new UNIT_RES( growth, tok );
+ doUNIT( growth->unit );
+ break;
+
+ case T_resolution:
+ if( growth->unit )
+ Unexpected( tok );
+ growth->unit = new UNIT_RES( growth, tok );
+ doRESOLUTION( growth->unit );
+ break;
+
+ case T_wire:
+ WIRE* wire;
+ wire = new WIRE( growth );
+ growth->wires.push_back( wire );
+ doWIRE( wire );
+ break;
+
+ case T_via:
+ WIRE_VIA* wire_via;
+ wire_via = new WIRE_VIA( growth );
+ growth->wire_vias.push_back( wire_via );
+ doWIRE_VIA( wire_via );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doANCESTOR( ANCESTOR* growth ) throw( IO_ERROR )
+{
+ T tok;
+
+ /* <ancestor_file_descriptor >::=
+ (ancestor <file_path_name> (created_time <time_stamp> )
+ [(comment <comment_string> )])
+ */
+
+ NeedSYMBOL();
+ growth->filename = CurText();
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_created_time:
+ readTIME( &growth->time_stamp );
+ NeedRIGHT();
+ break;
+
+ case T_comment:
+ NeedSYMBOL();
+ growth->comment = CurText();
+ NeedRIGHT();
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doHISTORY( HISTORY* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* <history_descriptor >::=
+ (history [{<ancestor_file_descriptor> }] <self_descriptor> )
+ */
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_ancestor:
+ ANCESTOR* ancestor;
+ ancestor = new ANCESTOR( growth );
+ growth->ancestors.push_back( ancestor );
+ doANCESTOR( ancestor );
+ break;
+
+ case T_self:
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_created_time:
+ readTIME( &growth->time_stamp );
+ NeedRIGHT();
+ break;
+
+ case T_comment:
+ NeedSYMBOL();
+ growth->comments.push_back( CurText() );
+ NeedRIGHT();
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doSESSION( SESSION* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* <session_file_descriptor >::=
+ (session <session_id >
+ (base_design <path/filename >)
+ [<history_descriptor> ]
+ [<session_structure_descriptor> ]
+ [<placement_descriptor> ]
+ [<floor_plan_descriptor> ]
+ [<net_pin_changes_descriptor> ]
+ [<was_is_descriptor> ]
+ <swap_history_descriptor> ]
+ [<route_descriptor> ]
+ )
+ */
+
+ NeedSYMBOL();
+ growth->session_id = CurText();
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_base_design:
+ NeedSYMBOL();
+ growth->base_design = CurText();
+ NeedRIGHT();
+ break;
+
+ case T_history:
+ if( growth->history )
+ Unexpected( tok );
+ growth->history = new HISTORY( growth );
+ doHISTORY( growth->history );
+ break;
+
+ case T_structure:
+ if( growth->structure )
+ Unexpected( tok );
+ growth->structure = new STRUCTURE( growth );
+ doSTRUCTURE( growth->structure );
+ break;
+
+ case T_placement:
+ if( growth->placement )
+ Unexpected( tok );
+ growth->placement = new PLACEMENT( growth );
+ doPLACEMENT( growth->placement );
+ break;
+
+ case T_was_is:
+ if( growth->was_is )
+ Unexpected( tok );
+ growth->was_is = new WAS_IS( growth );
+ doWAS_IS( growth->was_is );
+ break;
+
+ case T_routes:
+ if( growth->route )
+ Unexpected( tok );
+ growth->route = new ROUTE( growth );
+ doROUTE( growth->route );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doWAS_IS( WAS_IS* growth ) throw( IO_ERROR )
+{
+ T tok;
+ PIN_PAIR empty( growth );
+ PIN_PAIR* pin_pair;
+
+ /* <was_is_descriptor >::=
+ (was_is {(pins <pin_reference> <pin_reference> )})
+ */
+
+ // none of the pins is ok too
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_pins:
+ // copy the empty one, then fill its copy later thru pin_pair.
+ growth->pin_pairs.push_back( empty );
+ pin_pair= &growth->pin_pairs.back();
+
+ NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
+ readCOMPnPIN( &pin_pair->was.component_id, &pin_pair->was.pin_id );
+
+ NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
+ readCOMPnPIN( &pin_pair->is.component_id, &pin_pair->is.pin_id );
+
+ NeedRIGHT();
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doROUTE( ROUTE* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* <route_descriptor >::=
+ (routes
+ <resolution_descriptor>
+ <parser_descriptor>
+ <structure_out_descriptor>
+ <library_out_descriptor>
+ <network_out_descriptor>
+ <test_points_descriptor>
+ )
+ */
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_resolution:
+ if( growth->resolution )
+ Unexpected( tok );
+ growth->resolution = new UNIT_RES( growth, tok );
+ doRESOLUTION( growth->resolution );
+ break;
+
+ case T_parser:
+ if( growth->parser )
+ {
+#if 0 // Electra 2.9.1 emits two (parser ) elements in a row.
+ // Work around their bug for now.
+ Unexpected( tok );
+#else
+ delete growth->parser;
+#endif
+ }
+ growth->parser = new PARSER( growth );
+ doPARSER( growth->parser );
+ break;
+
+ case T_structure_out:
+ if( growth->structure_out )
+ Unexpected( tok );
+ growth->structure_out = new STRUCTURE_OUT( growth );
+ doSTRUCTURE_OUT( growth->structure_out );
+ break;
+
+ case T_library_out:
+ if( growth->library )
+ Unexpected( tok );
+ growth->library = new LIBRARY( growth, tok );
+ doLIBRARY( growth->library );
+ break;
+
+ case T_network_out:
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ if( tok != T_net ) // it is class NET_OUT, but token T_net
+ Unexpected( CurText() );
+
+ NET_OUT* net_out;
+ net_out = new NET_OUT( growth );
+
+ growth->net_outs.push_back( net_out );
+ doNET_OUT( net_out );
+ }
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doNET_OUT( NET_OUT* growth ) throw( IO_ERROR, boost::bad_pointer )
+{
+ T tok;
+
+ /* <net_out_descriptor >::=
+ (net <net_id >
+ [(net_number <integer >)]
+ [<rule_descriptor> ]
+ {[<wire_shape_descriptor> | <wire_guide_descriptor> |
+ <wire_via_descriptor> | <bond_shape_descriptor> ]}
+ {[<supply_pin_descriptor> ]}
+ )
+ */
+
+ NeedSYMBOLorNUMBER();
+ growth->net_id = CurText();
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( tok != T_LEFT )
+ Expecting( T_LEFT );
+
+ tok = NextTok();
+ switch( tok )
+ {
+ case T_net_number:
+ tok = NextTok();
+ if( tok!= T_NUMBER )
+ Expecting( T_NUMBER );
+ growth->net_number = atoi( CurText() );
+ NeedRIGHT();
+ break;
+
+ case T_rule:
+ if( growth->rules )
+ Unexpected( tok );
+ growth->rules = new RULE( growth, tok );
+ doRULE( growth->rules );
+ break;
+
+ case T_wire:
+ WIRE* wire;
+ wire = new WIRE( growth );
+ growth->wires.push_back( wire );
+ doWIRE( wire );
+ break;
+
+ case T_via:
+ WIRE_VIA* wire_via;
+ wire_via = new WIRE_VIA( growth );
+ growth->wire_vias.push_back( wire_via );
+ doWIRE_VIA( wire_via );
+ break;
+
+ case T_supply_pin:
+ SUPPLY_PIN* supply_pin;
+ supply_pin = new SUPPLY_PIN( growth );
+ growth->supply_pins.push_back( supply_pin );
+ doSUPPLY_PIN( supply_pin );
+ break;
+
+ default:
+ Unexpected( CurText() );
+ }
+ }
+}
+
+
+void SPECCTRA_DB::doSUPPLY_PIN( SUPPLY_PIN* growth ) throw( IO_ERROR )
+{
+ T tok;
+ PIN_REF empty(growth);
+
+ /* <supply_pin_descriptor >::=
+ (supply_pin {<pin_reference> } [(net <net_id >)])
+ */
+
+ NeedSYMBOL();
+ growth->net_id = CurText();
+
+ while( (tok = NextTok()) != T_RIGHT )
+ {
+ if( IsSymbol(tok) )
+ {
+ growth->pin_refs.push_back( empty );
+
+ PIN_REF* pin_ref = &growth->pin_refs.back();
+
+ readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
+ }
+ else if( tok == T_LEFT )
+ {
+ tok = NextTok();
+ if( tok != T_net )
+ Expecting( T_net );
+ growth->net_id = CurText();
+ NeedRIGHT();
+ }
+ else
+ Unexpected( CurText() );
+ }
+}
+
+
+void SPECCTRA_DB::ExportPCB( wxString filename, bool aNameChange ) throw( IO_ERROR )
+{
+ if( pcb )
+ {
+ FILE_OUTPUTFORMATTER formatter( filename, wxT( "wt" ), quote_char[0] );
+
+ if( aNameChange )
+ pcb->pcbname = TO_UTF8( filename );
+
+ pcb->Format( &formatter, 0 );
+ }
+}
+
+
+void SPECCTRA_DB::ExportSESSION( wxString filename )
+{
+ if( session )
+ {
+ FILE_OUTPUTFORMATTER formatter( filename, wxT( "wt" ), quote_char[0] );
+
+ session->Format( &formatter, 0 );
+ }
+}
+
+
+PCB* SPECCTRA_DB::MakePCB()
+{
+ PCB* pcb = new PCB();
+
+ pcb->parser = new PARSER( pcb );
+ pcb->resolution = new UNIT_RES( pcb, T_resolution );
+ pcb->unit = new UNIT_RES( pcb, T_unit );
+
+ pcb->structure = new STRUCTURE( pcb );
+ pcb->structure->boundary = new BOUNDARY( pcb->structure );
+ pcb->structure->via = new VIA( pcb->structure );
+ pcb->structure->rules = new RULE( pcb->structure, T_rule );
+
+ pcb->placement = new PLACEMENT( pcb );
+
+ pcb->library = new LIBRARY( pcb );
+
+ pcb->network = new NETWORK( pcb );
+
+ pcb->wiring = new WIRING( pcb );
+
+ return pcb;
+}
+
+
+//-----<ELEM>---------------------------------------------------------------
+
+ELEM::ELEM( T aType, ELEM* aParent ) :
+ type( aType ),
+ parent( aParent )
+{
+}
+
+
+ELEM::~ELEM()
+{
+}
+
+const char* ELEM::Name() const
+{
+ return SPECCTRA_DB::TokenName( type );
+}
+
+UNIT_RES* ELEM::GetUnits() const
+{
+ if( parent )
+ return parent->GetUnits();
+
+ return &UNIT_RES::Default;
+}
+
+
+void ELEM::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+{
+ out->Print( nestLevel, "(%s\n", Name() );
+
+ FormatContents( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+}
+
+
+void ELEM_HOLDER::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+{
+ for( int i=0; i<Length(); ++i )
+ {
+ At(i)->Format( out, nestLevel );
+ }
+}
+
+
+int ELEM_HOLDER::FindElem( T aType, int instanceNum )
+{
+ int repeats=0;
+ for( unsigned i=0; i<kids.size(); ++i )
+ {
+ if( kids[i].Type() == aType )
+ {
+ if( repeats == instanceNum )
+ return i;
+ ++repeats;
+ }
+ }
+ return -1;
+}
+
+
+// a reasonably small memory price to pay for improved performance
+STRING_FORMATTER ELEM::sf;
+
+
+//-----<UNIT_RES>---------------------------------------------------------
+
+UNIT_RES UNIT_RES::Default( NULL, T_resolution );
+
+
+//-----<PADSTACK>---------------------------------------------------------
+
+int PADSTACK::Compare( PADSTACK* lhs, PADSTACK* rhs )
+{
+ // printf( "PADSTACK::Compare( %p, %p)\n", lhs, rhs );
+
+ if( !lhs->hash.size() )
+ lhs->hash = lhs->makeHash();
+
+ if( !rhs->hash.size() )
+ rhs->hash = rhs->makeHash();
+
+ int result = lhs->hash.compare( rhs->hash );
+ if( result )
+ return result;
+
+ // Via names hold the drill diameters, so we have to include those to discern
+ // between two vias with same copper size but with different drill sizes.
+ result = lhs->padstack_id.compare( rhs->padstack_id );
+
+ return result;
+}
+
+
+//-----<IMAGE>------------------------------------------------------------
+
+int IMAGE::Compare( IMAGE* lhs, IMAGE* rhs )
+{
+ if( !lhs->hash.size() )
+ lhs->hash = lhs->makeHash();
+
+ if( !rhs->hash.size() )
+ rhs->hash = rhs->makeHash();
+
+ int result = lhs->hash.compare( rhs->hash );
+
+ // printf("\"%s\" \"%s\" ret=%d\n", lhs->hash.c_str(), rhs->hash.c_str(), result );
+
+ return result;
+}
+
+
+//-----<COMPONENT>--------------------------------------------------------
+
+/*
+int COMPONENT::Compare( COMPONENT* lhs, COMPONENT* rhs )
+{
+ if( !lhs->hash.size() )
+ lhs->hash = lhs->makeHash();
+
+ if( !rhs->hash.size() )
+ rhs->hash = rhs->makeHash();
+
+ int result = lhs->hash.compare( rhs->hash );
+ return result;
+}
+*/
+
+//-----<PARSER>-----------------------------------------------------------
+PARSER::PARSER( ELEM* aParent ) :
+ ELEM( T_parser, aParent )
+{
+ string_quote = '"';
+ space_in_quoted_tokens = false;
+
+ case_sensitive = false;
+ wires_include_testpoint = false;
+ routes_include_testpoint = false;
+ routes_include_guides = false;
+ routes_include_image_conductor = false;
+ via_rotate_first = true;
+ generated_by_freeroute = false;
+
+ host_cad = "KiCad's Pcbnew";
+ wxString msg = GetBuildVersion();
+ host_version = TO_UTF8(msg);
+}
+
+
+void PARSER::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+{
+ out->Print( nestLevel, "(string_quote %c)\n", string_quote );
+ out->Print( nestLevel, "(space_in_quoted_tokens %s)\n", space_in_quoted_tokens ? "on" : "off" );
+ out->Print( nestLevel, "(host_cad \"%s\")\n", host_cad.c_str() );
+ out->Print( nestLevel, "(host_version \"%s\")\n", host_version.c_str() );
+
+ for( STRINGS::iterator i=constants.begin(); i!=constants.end(); )
+ {
+ const std::string& s1 = *i++;
+ const std::string& s2 = *i++;
+
+ const char* q1 = out->GetQuoteChar( s1.c_str() );
+ const char* q2 = out->GetQuoteChar( s2.c_str() );
+ out->Print( nestLevel, "(constant %s%s%s %s%s%s)\n",
+ q1, s1.c_str(), q1,
+ q2, s2.c_str(), q2 );
+ }
+
+ if( routes_include_testpoint || routes_include_guides || routes_include_image_conductor )
+ out->Print( nestLevel, "(routes_include%s%s%s)\n",
+ routes_include_testpoint ? " testpoint" : "",
+ routes_include_guides ? " guides" : "",
+ routes_include_image_conductor ? " image_conductor" : "");
+
+ if( wires_include_testpoint )
+ out->Print( nestLevel, "(wires_include testpoint)\n" );
+
+ if( !via_rotate_first )
+ out->Print( nestLevel, "(via_rotate_first off)\n" );
+
+ if( case_sensitive )
+ out->Print( nestLevel, "(case_sensitive %s)\n", case_sensitive ? "on" : "off" );
+}
+
+
+void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+{
+ bool useMultiLine;
+
+ const char* quote = out->GetQuoteChar( component_id.c_str() );
+
+ if( place_rules || properties.size() || rules || region )
+ {
+ useMultiLine = true;
+
+ out->Print( nestLevel, "(%s %s%s%s\n", Name(),
+ quote, component_id.c_str(), quote );
+
+ out->Print( nestLevel+1, "%s", "" );
+ }
+ else
+ {
+ useMultiLine = false;
+
+ out->Print( nestLevel, "(%s %s%s%s", Name(),
+ quote, component_id.c_str(), quote );
+ }
+
+ if( hasVertex )
+ {
+ out->Print( 0, " %.6g %.6g", vertex.x, vertex.y );
+
+ out->Print( 0, " %s", GetTokenText( side ) );
+
+ out->Print( 0, " %.6g", rotation );
+ }
+
+ const char* space = " "; // one space, as c string.
+
+ if( mirror != T_NONE )
+ {
+ out->Print( 0, "%s(mirror %s)", space, GetTokenText( mirror ) );
+ space = "";
+ }
+
+ if( status != T_NONE )
+ {
+ out->Print( 0, "%s(status %s)", space, GetTokenText( status ) );
+ space = "";
+ }
+
+ if( logical_part.size() )
+ {
+ quote = out->GetQuoteChar( logical_part.c_str() );
+ out->Print( 0, "%s(logical_part %s%s%s)", space,
+ quote, logical_part.c_str(), quote );
+ space = "";
+ }
+
+ if( useMultiLine )
+ {
+ out->Print( 0, "\n" );
+ if( place_rules )
+ {
+ place_rules->Format( out, nestLevel+1 );
+ }
+
+ if( properties.size() )
+ {
+ out->Print( nestLevel+1, "(property \n" );
+
+ for( PROPERTIES::const_iterator i = properties.begin();
+ i != properties.end(); ++i )
+ {
+ i->Format( out, nestLevel+2 );
+ }
+ out->Print( nestLevel+1, ")\n" );
+ }
+ if( lock_type != T_NONE )
+ out->Print( nestLevel+1, "(lock_type %s)\n", GetTokenText(lock_type) );
+ if( rules )
+ rules->Format( out, nestLevel+1 );
+
+ if( region )
+ region->Format( out, nestLevel+1 );
+
+ if( part_number.size() )
+ {
+ const char* quote = out->GetQuoteChar( part_number.c_str() );
+ out->Print( nestLevel+1, "(PN %s%s%s)\n",
+ quote, part_number.c_str(), quote );
+ }
+ }
+ else
+ {
+ if( lock_type != T_NONE )
+ {
+ out->Print( 0, "%s(lock_type %s)", space, GetTokenText(lock_type) );
+ space = "";
+ }
+
+ if( part_number.size() )
+ {
+ const char* quote = out->GetQuoteChar( part_number.c_str() );
+ out->Print( 0, "%s(PN %s%s%s)", space,
+ quote, part_number.c_str(), quote );
+ }
+ }
+
+ out->Print( 0, ")\n" );
+}
+
+} // namespace DSN
+
+
+//EOF
diff --git a/pcbnew/specctra.h b/pcbnew/specctra.h
new file mode 100644
index 0000000..540fcf9
--- /dev/null
+++ b/pcbnew/specctra.h
@@ -0,0 +1,4004 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2007-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef SPECCTRA_H_
+#define SPECCTRA_H_
+
+
+// see http://www.boost.org/libs/ptr_container/doc/ptr_sequence_adapter.html
+#include <boost/ptr_container/ptr_vector.hpp>
+
+// see http://www.boost.org/libs/ptr_container/doc/ptr_set.html
+#include <boost/ptr_container/ptr_set.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <fctsys.h>
+#include <specctra_lexer.h>
+#include <pcbnew.h>
+
+// all outside the DSN namespace:
+class BOARD;
+class TRACK;
+class VIA;
+class NETCLASS;
+class MODULE;
+class SHAPE_POLY_SET;
+
+typedef DSN::T DSN_T;
+
+
+/**
+ This source file implements export and import capabilities to the
+ specctra dsn file format. The grammar for that file format is documented
+ fairly well. There are classes for each major type of descriptor in the
+ spec.
+
+ Since there are so many classes in here, it may be helpful to generate
+ the Doxygen directory:
+
+ $ cd &ltkicadSourceRoot&gt
+ $ doxygen
+
+ Then you can view the html documentation in the &ltkicadSourceRoot&gt/doxygen
+ directory. The main class in this file is SPECCTRA_DB and its main
+ functions are LoadPCB(), LoadSESSION(), and ExportPCB().
+
+ Wide use is made of boost::ptr_vector&lt&gt and std::vector&lt&gt template classes.
+ If the contained object is small, then std::vector tends to be used.
+ If the contained object is large, variable size, or would require writing
+ an assignment operator() or copy constructore, then boost::ptr_vector
+ cannot be beat.
+*/
+namespace DSN {
+
+
+class SPECCTRA_DB;
+
+
+/**
+ * Function GetTokenText
+ * is in the DSN namespace and returns the C string representing a
+ * SPECCTRA_DB::keyword. We needed a non-instanance function to get at
+ * the SPECCTRA_DB::keyword[] and class SPECCTRA_DB is not defined yet.
+ */
+const char* GetTokenText( T aTok );
+
+
+/**
+ * Struct POINT
+ * is a holder for a point in the SPECCTRA DSN coordinate system. It can also
+ * be used to hold a distance (vector really) from some origin.
+ */
+struct POINT
+{
+ double x;
+ double y;
+
+ POINT() { x=0.0; y=0.0; }
+
+ POINT( double aX, double aY ) :
+ x(aX), y(aY)
+ {
+ }
+
+ bool operator==( const POINT& other ) const
+ {
+ return x==other.x && y==other.y;
+ }
+
+ bool operator!=( const POINT& other ) const
+ {
+ return !( *this == other );
+ }
+
+ POINT& operator+=( const POINT& other )
+ {
+ x += other.x;
+ y += other.y;
+ return *this;
+ }
+
+ POINT& operator=( const POINT& other )
+ {
+ x = other.x;
+ y = other.y;
+ return *this;
+ }
+
+ /**
+ * Function FixNegativeZero
+ * will change negative zero to positive zero in the IEEE floating point
+ * storage format. Basically turns off the sign bit if the mantissa and
+ * exponent say the value is otherwise zero.
+ */
+ void FixNegativeZero()
+ {
+ if( x == -0.0 )
+ x = 0.0;
+ if( y == -0.0 )
+ y = 0.0;
+ }
+
+ /**
+ * Function Format
+ * writes this object as ASCII out to an OUTPUTFORMATTER according to the
+ * SPECCTRA DSN format.
+ * @param out The formatter to write to.
+ * @param nestLevel A multiple of the number of spaces to preceed the output with.
+ * @throw IO_ERROR if a system error writing the output, such as a full disk.
+ */
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR )
+ {
+ out->Print( nestLevel, " %.6g %.6g", x, y );
+ }
+};
+
+typedef std::vector<std::string> STRINGS;
+typedef std::vector<POINT> POINTS;
+
+struct PROPERTY
+{
+ std::string name;
+ std::string value;
+
+ /**
+ * Function Format
+ * writes this object as ASCII out to an OUTPUTFORMATTER according to the
+ * SPECCTRA DSN format.
+ * @param out The formatter to write to.
+ * @param nestLevel A multiple of the number of spaces to preceed the output with.
+ * @throw IO_ERROR if a system error writing the output, such as a full disk.
+ */
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR )
+ {
+ const char* quoteName = out->GetQuoteChar( name.c_str() );
+ const char* quoteValue = out->GetQuoteChar( value.c_str() );
+
+ out->Print( nestLevel, "(%s%s%s %s%s%s)\n",
+ quoteName, name.c_str(), quoteName,
+ quoteValue, value.c_str(), quoteValue );
+ }
+};
+typedef std::vector<PROPERTY> PROPERTIES;
+
+
+class UNIT_RES;
+
+/**
+ * Class ELEM
+ * is a base class for any DSN element class.
+ * See class ELEM_HOLDER also.
+ */
+class ELEM
+{
+ friend class SPECCTRA_DB;
+
+protected:
+ DSN_T type;
+ ELEM* parent;
+
+
+ /**
+ * Function makeHash
+ * returns a string which uniquely represents this ELEM amoung other
+ * ELEMs of the same derived class as "this" one.
+ * It is not useable for all derived classes, only those which plan for
+ * it by implementing a FormatContents() function that captures all info
+ * which will be used in the subsequent string compare. THIS SHOULD
+ * NORMALLY EXCLUDE THE TYPENAME, AND INSTANCE NAME OR ID AS WELL.
+ */
+ std::string makeHash()
+ {
+ sf.Clear();
+ FormatContents( &sf, 0 );
+ sf.StripUseless();
+
+ return sf.GetString();
+ }
+
+ // avoid creating this for every compare, make static.
+ static STRING_FORMATTER sf;
+
+
+public:
+
+ ELEM( DSN_T aType, ELEM* aParent = 0 );
+
+ virtual ~ELEM();
+
+ DSN_T Type() const { return type; }
+
+ const char* Name() const;
+
+
+ /**
+ * Function GetUnits
+ * returns the units for this section. Derived classes may override this
+ * to check for section specific overrides.
+ * @return UNIT_RES* - from a local or parent scope
+ */
+ virtual UNIT_RES* GetUnits() const;
+
+ /**
+ * Function Format
+ * writes this object as ASCII out to an OUTPUTFORMATTER according to the
+ * SPECCTRA DSN format.
+ * @param out The formatter to write to.
+ * @param nestLevel A multiple of the number of spaces to preceed the output with.
+ * @throw IO_ERROR if a system error writing the output, such as a full disk.
+ */
+ virtual void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR );
+
+
+ /**
+ * Function FormatContents
+ * writes the contents as ASCII out to an OUTPUTFORMATTER according to the
+ * SPECCTRA DSN format. This is the same as Format() except that the outer
+ * wrapper is not included.
+ * @param out The formatter to write to.
+ * @param nestLevel A multiple of the number of spaces to preceed the output with.
+ * @throw IO_ERROR if a system error writing the output, such as a full disk.
+ */
+ virtual void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ // overridden in ELEM_HOLDER
+ }
+
+ void SetParent( ELEM* aParent )
+ {
+ parent = aParent;
+ }
+};
+
+
+/**
+ * Class ELEM_HOLDER
+ * is a holder for any DSN class. It can contain other
+ * class instances, including classes derived from this class.
+ */
+class ELEM_HOLDER : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ typedef boost::ptr_vector<ELEM> ELEM_ARRAY;
+
+ ELEM_ARRAY kids; ///< ELEM pointers
+
+public:
+
+ ELEM_HOLDER( DSN_T aType, ELEM* aParent = 0 ) :
+ ELEM( aType, aParent )
+ {
+ }
+
+ virtual void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR );
+
+
+ //-----< list operations >--------------------------------------------
+
+ /**
+ * Function FindElem
+ * finds a particular instance number of a given type of ELEM.
+ * @param aType The type of ELEM to find
+ * @param instanceNum The instance number of to find: 0 for first, 1 for second, etc.
+ * @return int - The index into the kids array or -1 if not found.
+ */
+ int FindElem( DSN_T aType, int instanceNum = 0 );
+
+
+ /**
+ * Function Length
+ * returns the number of ELEMs in this ELEM.
+ * @return int - the count of children
+ */
+ int Length() const
+ {
+ return kids.size();
+ }
+
+ void Append( ELEM* aElem )
+ {
+ kids.push_back( aElem );
+ }
+
+ ELEM* Replace( int aIndex, ELEM* aElem )
+ {
+ ELEM_ARRAY::auto_type ret = kids.replace( aIndex, aElem );
+ return ret.release();
+ }
+
+ ELEM* Remove( int aIndex )
+ {
+ ELEM_ARRAY::auto_type ret = kids.release( kids.begin()+aIndex );
+ return ret.release();
+ }
+
+ void Insert( int aIndex, ELEM* aElem )
+ {
+ kids.insert( kids.begin()+aIndex, aElem );
+ }
+
+ ELEM* At( int aIndex ) const
+ {
+ // we have varying sized objects and are using polymorphism, so we
+ // must return a pointer not a reference.
+ return (ELEM*) &kids[aIndex];
+ }
+
+ ELEM* operator[]( int aIndex ) const
+ {
+ return At( aIndex );
+ }
+
+ void Delete( int aIndex )
+ {
+ kids.erase( kids.begin()+aIndex );
+ }
+};
+
+
+/**
+ * Class PARSER
+ * is simply a configuration record per the SPECCTRA DSN file spec.
+ * It is not actually a parser, but rather corresponds to &lt;parser_descriptor&gt;
+ */
+class PARSER : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ char string_quote;
+ bool space_in_quoted_tokens;
+ bool case_sensitive;
+ bool wires_include_testpoint;
+ bool routes_include_testpoint;
+ bool routes_include_guides;
+ bool routes_include_image_conductor;
+ bool via_rotate_first;
+ bool generated_by_freeroute;
+
+ /// This holds pairs of strings, one pair for each constant definition
+ STRINGS constants;
+
+ std::string host_cad;
+ std::string host_version;
+
+
+public:
+
+ PARSER( ELEM* aParent );
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR );
+};
+
+
+/**
+ * Class UNIT_RES
+ * is a holder for either a T_unit or T_resolution object which are usually
+ * mutually exclusive in the dsn grammar, except within the T_pcb level.
+ */
+class UNIT_RES : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ DSN_T units;
+ int value;
+
+public:
+
+ /**
+ * A static instance which holds the default units of T_inch and 2540000.
+ * See page 108 of the specctra spec, May 2000.
+ */
+ static UNIT_RES Default;
+
+ UNIT_RES( ELEM* aParent, DSN_T aType ) :
+ ELEM( aType, aParent )
+ {
+ units = T_inch;
+ value = 2540000;
+ }
+
+ DSN_T GetEngUnits() const { return units; }
+ int GetValue() const { return value; }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ if( type == T_unit )
+ out->Print( nestLevel, "(%s %s)\n", Name(),
+ GetTokenText(units) );
+
+ else // T_resolution
+ out->Print( nestLevel, "(%s %s %d)\n", Name(),
+ GetTokenText(units), value );
+ }
+};
+
+
+class RECTANGLE : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string layer_id;
+
+ POINT point0; ///< one of two opposite corners
+ POINT point1;
+
+public:
+
+ RECTANGLE( ELEM* aParent ) :
+ ELEM( T_rect, aParent )
+ {
+ }
+
+ void SetLayerId( const char* aLayerId )
+ {
+ layer_id = aLayerId;
+ }
+
+ void SetCorners( const POINT& aPoint0, const POINT& aPoint1 )
+ {
+ point0 = aPoint0;
+ point0.FixNegativeZero();
+
+ point1 = aPoint1;
+ point1.FixNegativeZero();
+ }
+
+ POINT GetOrigin() { return point0; }
+ POINT GetEnd() { return point1; }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* newline = nestLevel ? "\n" : "";
+
+ const char* quote = out->GetQuoteChar( layer_id.c_str() );
+
+ out->Print( nestLevel, "(%s %s%s%s %.6g %.6g %.6g %.6g)%s",
+ Name(),
+ quote, layer_id.c_str(), quote,
+ point0.x, point0.y,
+ point1.x, point1.y,
+ newline );
+ }
+};
+
+
+/**
+ * Class RULE
+ * corresponds to the &lt;rule_descriptor&gt; in the specctra dsn spec.
+ */
+class RULE : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ STRINGS rules; ///< rules are saved in std::string form.
+
+public:
+
+ RULE( ELEM* aParent, DSN_T aType ) :
+ ELEM( aType, aParent )
+ {
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ out->Print( nestLevel, "(%s", Name() );
+
+ bool singleLine;
+
+ if( rules.size() == 1 )
+ {
+ singleLine = true;
+ out->Print( 0, " %s)", rules.begin()->c_str() );
+ }
+
+ else
+ {
+ out->Print( 0, "\n" );
+ singleLine = false;
+ for( STRINGS::const_iterator i = rules.begin(); i!=rules.end(); ++i )
+ out->Print( nestLevel+1, "%s\n", i->c_str() );
+ out->Print( nestLevel, ")" );
+ }
+
+ if( nestLevel || !singleLine )
+ out->Print( 0, "\n" );
+ }
+};
+
+
+class LAYER_RULE : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ STRINGS layer_ids;
+ RULE* rule;
+
+public:
+
+ LAYER_RULE( ELEM* aParent ) :
+ ELEM( T_layer_rule, aParent )
+ {
+ rule = 0;
+ }
+ ~LAYER_RULE()
+ {
+ delete rule;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ out->Print( nestLevel, "(%s", Name() );
+
+ for( STRINGS::const_iterator i=layer_ids.begin(); i!=layer_ids.end(); ++i )
+ {
+ const char* quote = out->GetQuoteChar( i->c_str() );
+ out->Print( 0, " %s%s%s", quote, i->c_str(), quote );
+ }
+ out->Print( 0 , "\n" );
+
+ if( rule )
+ rule->Format( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+ }
+};
+typedef boost::ptr_vector<LAYER_RULE> LAYER_RULES;
+
+
+/**
+ * Class PATH
+ * supports both the &lt;path_descriptor&gt; and the &lt;polygon_descriptor&gt; per
+ * the specctra dsn spec.
+ */
+class PATH : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string layer_id;
+ double aperture_width;
+
+ POINTS points;
+ DSN_T aperture_type;
+
+public:
+
+ PATH( ELEM* aParent, DSN_T aType = T_path ) :
+ ELEM( aType, aParent )
+ {
+ aperture_width = 0.0;
+ aperture_type = T_round;
+ }
+
+ void AppendPoint( const POINT& aPoint )
+ {
+ points.push_back( aPoint );
+ }
+
+ POINTS& GetPoints() {return points; }
+
+ void SetLayerId( const char* aLayerId )
+ {
+ layer_id = aLayerId;
+ }
+
+ void SetAperture( double aWidth )
+ {
+ aperture_width = aWidth;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* newline = nestLevel ? "\n" : "";
+
+ const char* quote = out->GetQuoteChar( layer_id.c_str() );
+
+ const int RIGHTMARGIN = 70;
+ int perLine = out->Print( nestLevel, "(%s %s%s%s %.6g",
+ Name(),
+ quote, layer_id.c_str(), quote,
+ aperture_width );
+
+ int wrapNest = std::max( nestLevel+1, 6 );
+ for( unsigned i=0; i<points.size(); ++i )
+ {
+ if( perLine > RIGHTMARGIN )
+ {
+ out->Print( 0, "\n" );
+ perLine = out->Print( wrapNest, "%s", "" );
+ }
+ else
+ perLine += out->Print( 0, " " );
+
+ perLine += out->Print( 0, "%.6g %.6g", points[i].x, points[i].y );
+ }
+
+ if( aperture_type == T_square )
+ {
+ out->Print( 0, "(aperture_type square)" );
+ }
+
+ out->Print( 0, ")%s", newline );
+ }
+};
+typedef boost::ptr_vector<PATH> PATHS;
+
+
+class BOUNDARY : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ // only one or the other of these two is used, not both
+ PATHS paths;
+ RECTANGLE* rectangle;
+
+
+public:
+
+ BOUNDARY( ELEM* aParent, DSN_T aType = T_boundary ) :
+ ELEM( aType, aParent )
+ {
+ rectangle = 0;
+ }
+
+ ~BOUNDARY()
+ {
+ delete rectangle;
+ }
+
+ /**
+ * GetCorners fills aBuffer with a list of coordinates (x,y) of corners
+ */
+ void GetCorners( std::vector<double>& aBuffer )
+ {
+ if( rectangle )
+ {
+ aBuffer.push_back( rectangle->GetOrigin().x );
+ aBuffer.push_back( rectangle->GetOrigin().y );
+
+ aBuffer.push_back( rectangle->GetOrigin().x );
+ aBuffer.push_back( rectangle->GetEnd().y );
+
+ aBuffer.push_back( rectangle->GetEnd().x );
+ aBuffer.push_back( rectangle->GetEnd().y );
+
+ aBuffer.push_back( rectangle->GetEnd().x );
+ aBuffer.push_back( rectangle->GetOrigin().y );
+ }
+ else
+ {
+ for( PATHS::iterator i=paths.begin(); i!=paths.end(); ++i )
+ {
+ POINTS& plist = i->GetPoints();
+ for( unsigned jj = 0; jj < plist.size(); jj++ )
+ {
+ aBuffer.push_back( plist[jj].x );
+ aBuffer.push_back( plist[jj].y );
+ }
+ }
+ }
+ }
+
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ out->Print( nestLevel, "(%s\n", Name() );
+
+ if( rectangle )
+ rectangle->Format( out, nestLevel+1 );
+ else
+ {
+ for( PATHS::iterator i=paths.begin(); i!=paths.end(); ++i )
+ i->Format( out, nestLevel+1 );
+ }
+
+ out->Print( nestLevel, ")\n" );
+ }
+};
+
+
+class CIRCLE : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string layer_id;
+
+ double diameter;
+ POINT vertex; // POINT's constructor sets to (0,0)
+
+public:
+ CIRCLE( ELEM* aParent ) :
+ ELEM( T_circle, aParent )
+ {
+ diameter = 0.0;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* newline = nestLevel ? "\n" : "";
+
+ const char* quote = out->GetQuoteChar( layer_id.c_str() );
+ out->Print( nestLevel, "(%s %s%s%s %.6g", Name(),
+ quote, layer_id.c_str(), quote,
+ diameter );
+
+ if( vertex.x!=0.0 || vertex.y!=0.0 )
+ out->Print( 0, " %.6g %.6g)%s", vertex.x, vertex.y, newline );
+ else
+ out->Print( 0, ")%s", newline );
+ }
+
+ void SetLayerId( const char* aLayerId )
+ {
+ layer_id = aLayerId;
+ }
+
+ void SetDiameter( double aDiameter )
+ {
+ diameter = aDiameter;
+ }
+
+ void SetVertex( const POINT& aVertex )
+ {
+ vertex = aVertex;
+ }
+};
+
+
+class QARC : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string layer_id;
+ double aperture_width;
+ POINT vertex[3];
+
+public:
+ QARC( ELEM* aParent ) :
+ ELEM( T_qarc, aParent )
+ {
+ aperture_width = 0.0;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* newline = nestLevel ? "\n" : "";
+
+ const char* quote = out->GetQuoteChar( layer_id.c_str() );
+ out->Print( nestLevel, "(%s %s%s%s %.6g", Name() ,
+ quote, layer_id.c_str(), quote,
+ aperture_width);
+
+ for( int i=0; i<3; ++i )
+ out->Print( 0, " %.6g %.6g", vertex[i].x, vertex[i].y );
+
+ out->Print( 0, ")%s", newline );
+ }
+
+ void SetLayerId( const char* aLayerId )
+ {
+ layer_id = aLayerId;
+ }
+ void SetStart( const POINT& aStart )
+ {
+ vertex[0] = aStart;
+ // no -0.0 on the printouts!
+ vertex[0].FixNegativeZero();
+ }
+ void SetEnd( const POINT& aEnd )
+ {
+ vertex[1] = aEnd;
+ // no -0.0 on the printouts!
+ vertex[1].FixNegativeZero();
+ }
+ void SetCenter( const POINT& aCenter )
+ {
+ vertex[2] = aCenter;
+ // no -0.0 on the printouts!
+ vertex[2].FixNegativeZero();
+ }
+};
+
+
+class WINDOW : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+protected:
+ /* <shape_descriptor >::=
+ [<rectangle_descriptor> |
+ <circle_descriptor> |
+ <polygon_descriptor> |
+ <path_descriptor> |
+ <qarc_descriptor> ]
+ */
+ ELEM* shape;
+
+public:
+
+ WINDOW( ELEM* aParent, DSN_T aType = T_window ) :
+ ELEM( aType, aParent )
+ {
+ shape = 0;
+ }
+
+ ~WINDOW()
+ {
+ delete shape;
+ }
+
+ void SetShape( ELEM* aShape )
+ {
+ delete shape;
+ shape = aShape;
+
+ if( aShape )
+ {
+ wxASSERT(aShape->Type()==T_rect || aShape->Type()==T_circle
+ || aShape->Type()==T_qarc || aShape->Type()==T_path
+ || aShape->Type()==T_polygon);
+
+ aShape->SetParent( this );
+ }
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ out->Print( nestLevel, "(%s ", Name() );
+
+ if( shape )
+ shape->Format( out, 0 );
+
+ out->Print( 0, ")\n" );
+ }
+};
+typedef boost::ptr_vector<WINDOW> WINDOWS;
+
+
+/**
+ * Class KEEPOUT
+ * is used for &lt;keepout_descriptor&gt; and &lt;plane_descriptor&gt;.
+ */
+class KEEPOUT : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+protected:
+ std::string name;
+ int sequence_number;
+ RULE* rules;
+ RULE* place_rules;
+
+ WINDOWS windows;
+
+ /* <shape_descriptor >::=
+ [<rectangle_descriptor> |
+ <circle_descriptor> |
+ <polygon_descriptor> |
+ <path_descriptor> |
+ <qarc_descriptor> ]
+ */
+ ELEM* shape;
+
+public:
+
+ /**
+ * Constructor KEEPOUT
+ * requires a DSN_T because this class is used for T_place_keepout, T_via_keepout,
+ * T_wire_keepout, T_bend_keepout, and T_elongate_keepout as well as T_keepout.
+ */
+ KEEPOUT( ELEM* aParent, DSN_T aType ) :
+ ELEM( aType, aParent )
+ {
+ rules = 0;
+ place_rules = 0;
+ shape = 0;
+
+ sequence_number = -1;
+ }
+
+ ~KEEPOUT()
+ {
+ delete rules;
+ delete place_rules;
+ delete shape;
+ }
+
+ void SetShape( ELEM* aShape )
+ {
+ delete shape;
+ shape = aShape;
+
+ if( aShape )
+ {
+ wxASSERT(aShape->Type()==T_rect || aShape->Type()==T_circle
+ || aShape->Type()==T_qarc || aShape->Type()==T_path
+ || aShape->Type()==T_polygon);
+
+ aShape->SetParent( this );
+ }
+ }
+
+ void AddWindow( WINDOW* aWindow )
+ {
+ aWindow->SetParent( this );
+ windows.push_back( aWindow );
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* newline = "\n";
+
+ out->Print( nestLevel, "(%s", Name() );
+
+ if( name.size() )
+ {
+ const char* quote = out->GetQuoteChar( name.c_str() );
+ out->Print( 0, " %s%s%s", quote, name.c_str(), quote );
+ }
+ else
+ out->Print( 0, " \"\"" ); // the zone with no name or net_code == 0
+
+ if( sequence_number != -1 )
+ out->Print( 0, " (sequence_number %d)", sequence_number );
+
+ if( shape )
+ {
+ out->Print( 0, " " );
+ shape->Format( out, 0 );
+ }
+
+ if( rules )
+ {
+ out->Print( 0, "%s", newline );
+ newline = "";
+ rules->Format( out, nestLevel+1 );
+ }
+
+ if( place_rules )
+ {
+ out->Print( 0, "%s", newline );
+ newline = "";
+ place_rules->Format( out, nestLevel+1 );
+ }
+
+ if( windows.size() )
+ {
+ out->Print( 0, "%s", newline );
+ newline = "";
+
+ for( WINDOWS::iterator i=windows.begin(); i!=windows.end(); ++i )
+ i->Format( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+ }
+ else
+ out->Print( 0, ")\n" );
+ }
+};
+typedef boost::ptr_vector<KEEPOUT> KEEPOUTS;
+
+
+/**
+ * Class VIA
+ * corresponds to the &lt;via_descriptor&gt; in the specctra dsn spec.
+ */
+class VIA : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ STRINGS padstacks;
+ STRINGS spares;
+
+public:
+
+ VIA( ELEM* aParent ) :
+ ELEM( T_via, aParent )
+ {
+ }
+
+ void AppendVia( const char* aViaName )
+ {
+ padstacks.push_back( aViaName );
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const int RIGHTMARGIN = 80;
+ int perLine = out->Print( nestLevel, "(%s", Name() );
+
+ for( STRINGS::iterator i=padstacks.begin(); i!=padstacks.end(); ++i )
+ {
+ if( perLine > RIGHTMARGIN )
+ {
+ out->Print( 0, "\n" );
+ perLine = out->Print( nestLevel+1, "%s", "");
+ }
+
+ const char* quote = out->GetQuoteChar( i->c_str() );
+ perLine += out->Print( 0, " %s%s%s", quote, i->c_str(), quote );
+ }
+
+ if( spares.size() )
+ {
+ out->Print( 0, "\n" );
+
+ perLine = out->Print( nestLevel+1, "(spare" );
+
+ for( STRINGS::iterator i=spares.begin(); i!=spares.end(); ++i )
+ {
+ if( perLine > RIGHTMARGIN )
+ {
+ out->Print( 0, "\n" );
+ perLine = out->Print( nestLevel+2, "%s", "");
+ }
+ const char* quote = out->GetQuoteChar( i->c_str() );
+ perLine += out->Print( 0, " %s%s%s", quote, i->c_str(), quote );
+ }
+
+ out->Print( 0, ")" );
+ }
+
+ out->Print( 0, ")\n" );
+ }
+};
+
+
+class CLASSES : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ STRINGS class_ids;
+
+public:
+ CLASSES( ELEM* aParent ) :
+ ELEM( T_classes, aParent )
+ {
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ for( STRINGS::iterator i=class_ids.begin(); i!=class_ids.end(); ++i )
+ {
+ const char* quote = out->GetQuoteChar( i->c_str() );
+ out->Print( nestLevel, "%s%s%s\n", quote, i->c_str(), quote );
+ }
+ }
+};
+
+
+class CLASS_CLASS : public ELEM_HOLDER
+{
+ friend class SPECCTRA_DB;
+
+ CLASSES* classes;
+
+ /* rule | layer_rule are put into the kids container.
+ */
+
+
+public:
+
+ /**
+ * Constructor CLASS_CLASS
+ * @param aParent - Parent element of the object.
+ * @param aType May be either T_class_class or T_region_class_class
+ */
+ CLASS_CLASS( ELEM* aParent, DSN_T aType ) :
+ ELEM_HOLDER( aType, aParent )
+ {
+ classes = 0;
+ }
+
+ ~CLASS_CLASS()
+ {
+ delete classes;
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ if( classes )
+ classes->Format( out, nestLevel );
+
+ // format the kids
+ ELEM_HOLDER::FormatContents( out, nestLevel );
+ }
+};
+
+
+class CONTROL : public ELEM_HOLDER
+{
+ friend class SPECCTRA_DB;
+
+ bool via_at_smd;
+ bool via_at_smd_grid_on;
+
+public:
+ CONTROL( ELEM* aParent ) :
+ ELEM_HOLDER( T_control, aParent )
+ {
+ via_at_smd = false;
+ via_at_smd_grid_on = false;
+ }
+
+ ~CONTROL()
+ {
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ out->Print( nestLevel, "(%s\n", Name() );
+
+ //if( via_at_smd )
+ {
+ out->Print( nestLevel+1, "(via_at_smd %s", via_at_smd ? "on" : "off" );
+ if( via_at_smd_grid_on )
+ out->Print( 0, " grid %s", via_at_smd_grid_on ? "on" : "off" );
+
+ out->Print( 0, ")\n" );
+ }
+
+ for( int i=0; i<Length(); ++i )
+ {
+ At(i)->Format( out, nestLevel+1 );
+ }
+
+ out->Print( nestLevel, ")\n" );
+ }
+};
+
+
+class LAYER : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string name;
+ DSN_T layer_type; ///< one of: T_signal, T_power, T_mixed, T_jumper
+ int direction;
+ int cost; ///< [forbidden | high | medium | low | free | \<positive_integer\> | -1]
+ int cost_type; ///< T_length | T_way
+ RULE* rules;
+ STRINGS use_net;
+
+ PROPERTIES properties;
+
+public:
+
+ LAYER( ELEM* aParent ) :
+ ELEM( T_layer, aParent )
+ {
+ layer_type = T_signal;
+ direction = -1;
+ cost = -1;
+ cost_type = -1;
+
+ rules = 0;
+ }
+
+ ~LAYER()
+ {
+ delete rules;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* quote = out->GetQuoteChar( name.c_str() );
+
+ out->Print( nestLevel, "(%s %s%s%s\n", Name(),
+ quote, name.c_str(), quote );
+
+ out->Print( nestLevel+1, "(type %s)\n", GetTokenText( layer_type ) );
+
+ if( properties.size() )
+ {
+ out->Print( nestLevel+1, "(property\n" );
+
+ for( PROPERTIES::iterator i = properties.begin(); i != properties.end(); ++i )
+ {
+ i->Format( out, nestLevel+2 );
+ }
+ out->Print( nestLevel+1, ")\n" );
+ }
+
+ if( direction != -1 )
+ out->Print( nestLevel+1, "(direction %s)\n",
+ GetTokenText( (DSN_T)direction ) );
+
+ if( rules )
+ rules->Format( out, nestLevel+1 );
+
+ if( cost != -1 )
+ {
+ if( cost < 0 )
+ out->Print( nestLevel+1, "(cost %d", -cost ); // positive integer, stored as negative
+ else
+ out->Print( nestLevel+1, "(cost %s", GetTokenText( (DSN_T)cost ) );
+
+ if( cost_type != -1 )
+ out->Print( 0, " (type %s)", GetTokenText( (DSN_T)cost_type ) );
+
+ out->Print( 0, ")\n" );
+ }
+
+ if( use_net.size() )
+ {
+ out->Print( nestLevel+1, "(use_net" );
+ for( STRINGS::const_iterator i = use_net.begin(); i!=use_net.end(); ++i )
+ {
+ const char* quote = out->GetQuoteChar( i->c_str() );
+ out->Print( 0, " %s%s%s", quote, i->c_str(), quote );
+ }
+ out->Print( 0, ")\n" );
+ }
+
+ out->Print( nestLevel, ")\n" );
+ }
+};
+
+typedef boost::ptr_vector<LAYER> LAYERS;
+
+
+class LAYER_PAIR : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string layer_id0;
+ std::string layer_id1;
+
+ double layer_weight;
+
+public:
+ LAYER_PAIR( ELEM* aParent ) :
+ ELEM( T_layer_pair, aParent )
+ {
+ layer_weight = 0.0;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* quote0 = out->GetQuoteChar( layer_id0.c_str() );
+ const char* quote1 = out->GetQuoteChar( layer_id1.c_str() );
+
+ out->Print( nestLevel, "(%s %s%s%s %s%s%s %.6g)\n", Name(),
+ quote0, layer_id0.c_str(), quote0,
+ quote1, layer_id1.c_str(), quote1,
+ layer_weight );
+ }
+};
+typedef boost::ptr_vector<LAYER_PAIR> LAYER_PAIRS;
+
+
+class LAYER_NOISE_WEIGHT : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ LAYER_PAIRS layer_pairs;
+
+public:
+
+ LAYER_NOISE_WEIGHT( ELEM* aParent ) :
+ ELEM( T_layer_noise_weight, aParent )
+ {
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ out->Print( nestLevel, "(%s\n", Name() );
+
+ for( LAYER_PAIRS::iterator i=layer_pairs.begin(); i!=layer_pairs.end(); ++i )
+ i->Format( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+ }
+};
+
+
+/**
+ * Class COPPER_PLANE
+ * corresponds to a &lt;plane_descriptor&gt; in the specctra dsn spec.
+ */
+class COPPER_PLANE : public KEEPOUT
+{
+ friend class SPECCTRA_DB;
+
+public:
+ COPPER_PLANE( ELEM* aParent ) :
+ KEEPOUT( aParent, T_plane )
+ {}
+};
+typedef boost::ptr_vector<COPPER_PLANE> COPPER_PLANES;
+
+
+/**
+ * Class TOKPROP
+ * is a container for a single property whose value is another DSN_T token.
+ * The name of the property is obtained from the DSN_T Type().
+ */
+class TOKPROP : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ DSN_T value;
+
+public:
+
+ TOKPROP( ELEM* aParent, DSN_T aType ) :
+ ELEM( aType, aParent )
+ {
+ // Do not leave uninitialized members
+ value = T_NONE;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ out->Print( nestLevel, "(%s %s)\n", Name(),
+ GetTokenText( value ) );
+ }
+};
+
+
+/**
+ * Class STRINGPROP
+ * is a container for a single property whose value is a string.
+ * The name of the property is obtained from the DSN_T.
+ */
+class STRINGPROP : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string value;
+
+public:
+
+ STRINGPROP( ELEM* aParent, DSN_T aType ) :
+ ELEM( aType, aParent )
+ {
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* quote = out->GetQuoteChar( value.c_str() );
+
+ out->Print( nestLevel, "(%s %s%s%s)\n", Name(),
+ quote, value.c_str(), quote );
+ }
+};
+
+
+class REGION : public ELEM_HOLDER
+{
+ friend class SPECCTRA_DB;
+
+ std::string region_id;
+
+ //-----<mutually exclusive>--------------------------------------
+ RECTANGLE* rectangle;
+ PATH* polygon;
+ //-----</mutually exclusive>-------------------------------------
+
+ /* region_net | region_class | region_class_class are all mutually
+ exclusive and are put into the kids container.
+ */
+
+ RULE* rules;
+
+public:
+ REGION( ELEM* aParent ) :
+ ELEM_HOLDER( T_region, aParent )
+ {
+ rectangle = 0;
+ polygon = 0;
+ rules = 0;
+ }
+
+ ~REGION()
+ {
+ delete rectangle;
+ delete polygon;
+ delete rules;
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ if( region_id.size() )
+ {
+ const char* quote = out->GetQuoteChar( region_id.c_str() );
+ out->Print( nestLevel, "%s%s%s\n", quote, region_id.c_str(), quote );
+ }
+
+ if( rectangle )
+ rectangle->Format( out, nestLevel );
+
+ if( polygon )
+ polygon->Format( out, nestLevel );
+
+ ELEM_HOLDER::FormatContents( out, nestLevel );
+
+ if( rules )
+ rules->Format( out, nestLevel );
+ }
+};
+
+
+class GRID : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ DSN_T grid_type; ///< T_via | T_wire | T_via_keepout | T_place | T_snap
+ double dimension;
+ DSN_T direction; ///< T_x | T_y | -1 for both
+ double offset;
+ DSN_T image_type;
+
+public:
+
+ GRID( ELEM* aParent ) :
+ ELEM( T_grid, aParent )
+ {
+ grid_type = T_via;
+ direction = T_NONE;
+ dimension = 0.0;
+ offset = 0.0;
+ image_type= T_NONE;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ out->Print( nestLevel, "(%s %s %.6g",
+ Name(),
+ GetTokenText( grid_type ), dimension );
+
+ if( grid_type == T_place )
+ {
+ if( image_type==T_smd || image_type==T_pin )
+ out->Print( 0, " (image_type %s)", GetTokenText( image_type ) );
+ }
+ else
+ {
+ if( direction==T_x || direction==T_y )
+ out->Print( 0, " (direction %s)", GetTokenText( direction ) );
+ }
+
+ if( offset != 0.0 )
+ out->Print( 0, " (offset %.6g)", offset );
+
+ out->Print( 0, ")\n");
+ }
+};
+
+
+class STRUCTURE_OUT : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ LAYERS layers;
+ RULE* rules;
+
+public:
+ STRUCTURE_OUT( ELEM* aParent ) :
+ ELEM( T_structure_out, aParent )
+ {
+ rules = 0;
+ }
+
+ ~STRUCTURE_OUT()
+ {
+ delete rules;
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ for( LAYERS::iterator i=layers.begin(); i!=layers.end(); ++i )
+ i->Format( out, nestLevel );
+
+ if( rules )
+ rules->Format( out, nestLevel );
+ }
+};
+
+
+class STRUCTURE : public ELEM_HOLDER
+{
+ friend class SPECCTRA_DB;
+
+ UNIT_RES* unit;
+
+ LAYERS layers;
+
+ LAYER_NOISE_WEIGHT* layer_noise_weight;
+
+ BOUNDARY* boundary;
+ BOUNDARY* place_boundary;
+ VIA* via;
+ CONTROL* control;
+ RULE* rules;
+
+ KEEPOUTS keepouts;
+
+ COPPER_PLANES planes;
+
+ typedef boost::ptr_vector<REGION> REGIONS;
+ REGIONS regions;
+
+ RULE* place_rules;
+
+ typedef boost::ptr_vector<GRID> GRIDS;
+ GRIDS grids;
+
+public:
+
+ STRUCTURE( ELEM* aParent ) :
+ ELEM_HOLDER( T_structure, aParent )
+ {
+ unit = 0;
+ layer_noise_weight = 0;
+ boundary = 0;
+ place_boundary = 0;
+ via = 0;
+ control = 0;
+ rules = 0;
+ place_rules = 0;
+ }
+
+ ~STRUCTURE()
+ {
+ delete unit;
+ delete layer_noise_weight;
+ delete boundary;
+ delete place_boundary;
+ delete via;
+ delete control;
+ delete rules;
+ delete place_rules;
+ }
+
+ void SetBOUNDARY( BOUNDARY *aBoundary )
+ {
+ delete boundary;
+ boundary = aBoundary;
+ if( boundary )
+ {
+ boundary->SetParent( this );
+ }
+ }
+
+ void SetPlaceBOUNDARY( BOUNDARY *aBoundary )
+ {
+ delete place_boundary;
+ place_boundary = aBoundary;
+ if( place_boundary )
+ place_boundary->SetParent( this );
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ if( unit )
+ unit->Format( out, nestLevel );
+
+ for( LAYERS::iterator i=layers.begin(); i!=layers.end(); ++i )
+ i->Format( out, nestLevel );
+
+ if( layer_noise_weight )
+ layer_noise_weight->Format( out, nestLevel );
+
+ if( boundary )
+ boundary->Format( out, nestLevel );
+
+ if( place_boundary )
+ place_boundary->Format( out, nestLevel );
+
+ for( COPPER_PLANES::iterator i=planes.begin(); i!=planes.end(); ++i )
+ i->Format( out, nestLevel );
+
+ for( REGIONS::iterator i=regions.begin(); i!=regions.end(); ++i )
+ i->Format( out, nestLevel );
+
+ for( KEEPOUTS::iterator i=keepouts.begin(); i!=keepouts.end(); ++i )
+ i->Format( out, nestLevel );
+
+ if( via )
+ via->Format( out, nestLevel );
+
+ if( control )
+ control->Format( out, nestLevel );
+
+ for( int i=0; i<Length(); ++i )
+ {
+ At(i)->Format( out, nestLevel );
+ }
+
+ if( rules )
+ rules->Format( out, nestLevel );
+
+ if( place_rules )
+ place_rules->Format( out, nestLevel );
+
+ for( GRIDS::iterator i=grids.begin(); i!=grids.end(); ++i )
+ i->Format( out, nestLevel );
+ }
+
+ UNIT_RES* GetUnits() const
+ {
+ if( unit )
+ return unit;
+
+ return ELEM::GetUnits();
+ }
+};
+
+
+/**
+ * Class PLACE
+ * implements the &lt;placement_reference&gt; in the specctra dsn spec.
+ */
+class PLACE : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string component_id; ///< reference designator
+
+ DSN_T side;
+
+ double rotation;
+
+ bool hasVertex;
+ POINT vertex;
+
+ DSN_T mirror;
+ DSN_T status;
+
+ std::string logical_part;
+
+ RULE* place_rules;
+
+ PROPERTIES properties;
+
+ DSN_T lock_type;
+
+ //-----<mutually exclusive>--------------
+ RULE* rules;
+ REGION* region;
+ //-----</mutually exclusive>-------------
+
+ std::string part_number;
+
+public:
+
+ PLACE( ELEM* aParent ) :
+ ELEM( T_place, aParent )
+ {
+ side = T_front;
+
+ rotation = 0.0;
+
+ hasVertex = false;
+
+ mirror = T_NONE;
+ status = T_NONE;
+
+ place_rules = 0;
+
+ lock_type = T_NONE;
+ rules = 0;
+ region = 0;
+ }
+
+ ~PLACE()
+ {
+ delete place_rules;
+ delete rules;
+ delete region;
+ }
+
+ void SetVertex( const POINT& aVertex )
+ {
+ vertex = aVertex;
+ vertex.FixNegativeZero();
+ hasVertex = true;
+ }
+
+ void SetRotation( double aRotation )
+ {
+ rotation = aRotation;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR );
+};
+typedef boost::ptr_vector<PLACE> PLACES;
+
+
+/**
+ * Class COMPONENT
+ * implements the &lt;component_descriptor&gt; in the specctra dsn spec.
+ */
+class COMPONENT : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+// std::string hash; ///< a hash string used by Compare(), not Format()ed/exported.
+
+ std::string image_id;
+ PLACES places;
+
+public:
+ COMPONENT( ELEM* aParent ) :
+ ELEM( T_component, aParent )
+ {
+ }
+
+ const std::string& GetImageId() const { return image_id; }
+ void SetImageId( const std::string& aImageId )
+ {
+ image_id = aImageId;
+ }
+
+
+ /**
+ * Function Compare
+ * compares two objects of this type and returns <0, 0, or >0.
+ */
+// static int Compare( IMAGE* lhs, IMAGE* rhs );
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* quote = out->GetQuoteChar( image_id.c_str() );
+ out->Print( nestLevel, "(%s %s%s%s\n", Name(),
+ quote, image_id.c_str(), quote );
+
+ FormatContents( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ for( PLACES::iterator i=places.begin(); i!=places.end(); ++i )
+ i->Format( out, nestLevel );
+ }
+};
+typedef boost::ptr_vector<COMPONENT> COMPONENTS;
+
+
+class PLACEMENT : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ UNIT_RES* unit;
+
+ DSN_T flip_style;
+
+ COMPONENTS components;
+
+public:
+ PLACEMENT( ELEM* aParent ) :
+ ELEM( T_placement, aParent )
+ {
+ unit = 0;
+ flip_style = DSN_T( T_NONE );
+ }
+
+ ~PLACEMENT()
+ {
+ delete unit;
+ }
+
+ /**
+ * Function LookupCOMPONENT
+ * looks up a COMPONENT by name. If the name is not found, a new
+ * COMPONENT is added to the components container. At any time the
+ * names in the component container should remain unique.
+ * @return COMPONENT* - an existing or new
+ */
+ COMPONENT* LookupCOMPONENT( const std::string& imageName )
+ {
+ for( unsigned i=0; i<components.size(); ++i )
+ {
+ if( 0 == components[i].GetImageId().compare( imageName ) )
+ return &components[i];
+ }
+
+ COMPONENT* added = new COMPONENT(this);
+ components.push_back( added );
+ added->SetImageId( imageName );
+ return added;
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ if( unit )
+ unit->Format( out, nestLevel );
+
+ if( flip_style != DSN_T( T_NONE ) )
+ {
+ out->Print( nestLevel, "(place_control (flip_style %s))\n",
+ GetTokenText( flip_style ) );
+ }
+
+ for( COMPONENTS::iterator i=components.begin(); i!=components.end(); ++i )
+ i->Format( out, nestLevel );
+ }
+
+ UNIT_RES* GetUnits() const
+ {
+ if( unit )
+ return unit;
+
+ return ELEM::GetUnits();
+ }
+};
+
+
+/**
+ * Class SHAPE
+ * corresponds to the "(shape ..)" element in the specctra dsn spec.
+ * It is not a &lt;shape_descriptor&gt;, which is one of things that this
+ * elements contains, i.e. in its "shape" field. This class also implements
+ * the "(outline ...)" element as a dual personality.
+ */
+class SHAPE : public WINDOW
+{
+ friend class SPECCTRA_DB;
+
+ DSN_T connect;
+
+ /* <shape_descriptor >::=
+ [<rectangle_descriptor> |
+ <circle_descriptor> |
+ <polygon_descriptor> |
+ <path_descriptor> |
+ <qarc_descriptor> ]
+ ELEM* shape; // inherited from WINDOW
+ */
+
+ WINDOWS windows;
+
+public:
+
+ /**
+ * Constructor SHAPE
+ * alternatively takes a DSN_T aType of T_outline
+ */
+ SHAPE( ELEM* aParent, DSN_T aType = T_shape ) :
+ WINDOW( aParent, aType )
+ {
+ connect = T_on;
+ }
+
+ void SetConnect( DSN_T aConnect )
+ {
+ connect = aConnect;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ out->Print( nestLevel, "(%s ", Name() );
+
+ if( shape )
+ shape->Format( out, 0 );
+
+ if( connect == T_off )
+ out->Print( 0, "(connect %s)", GetTokenText( connect ) );
+
+ if( windows.size() )
+ {
+ out->Print( 0, "\n" );
+
+ for( WINDOWS::iterator i=windows.begin(); i!=windows.end(); ++i )
+ i->Format( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+ }
+ else
+ out->Print( 0, ")\n" );
+ }
+};
+
+
+class PIN : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string padstack_id;
+ double rotation;
+ bool isRotated;
+ std::string pin_id;
+ POINT vertex;
+
+ int kiNetCode; ///< KiCad netcode
+
+
+public:
+ PIN( ELEM* aParent ) :
+ ELEM( T_pin, aParent )
+ {
+ rotation = 0.0;
+ isRotated = false;
+ kiNetCode = 0;
+ }
+
+ void SetRotation( double aRotation )
+ {
+ rotation = aRotation;
+ isRotated = (aRotation != 0.0);
+ }
+
+ void SetVertex( const POINT& aPoint )
+ {
+ vertex = aPoint;
+ vertex.FixNegativeZero();
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* quote = out->GetQuoteChar( padstack_id.c_str() );
+ if( isRotated )
+ out->Print( nestLevel, "(pin %s%s%s (rotate %.6g)",
+ quote, padstack_id.c_str(), quote,
+ rotation
+ );
+ else
+ out->Print( nestLevel, "(pin %s%s%s", quote, padstack_id.c_str(), quote );
+
+ quote = out->GetQuoteChar( pin_id.c_str() );
+ out->Print( 0, " %s%s%s %.6g %.6g)\n", quote, pin_id.c_str(), quote,
+ vertex.x, vertex.y );
+ }
+};
+typedef boost::ptr_vector<PIN> PINS;
+
+
+class LIBRARY;
+class IMAGE : public ELEM_HOLDER
+{
+ friend class SPECCTRA_DB;
+ friend class LIBRARY;
+
+ std::string hash; ///< a hash string used by Compare(), not Format()ed/exported.
+
+ std::string image_id;
+ DSN_T side;
+ UNIT_RES* unit;
+
+ /* The grammar spec says only one outline is supported, but I am seeing
+ *.dsn examples with multiple outlines. So the outlines will go into
+ the kids list.
+ */
+
+ PINS pins;
+
+ RULE* rules;
+ RULE* place_rules;
+
+ KEEPOUTS keepouts;
+
+ int duplicated; ///< no. times this image_id is duplicated
+
+public:
+
+ IMAGE( ELEM* aParent ) :
+ ELEM_HOLDER( T_image, aParent )
+ {
+ side = T_both;
+ unit = 0;
+ rules = 0;
+ place_rules = 0;
+ duplicated = 0;
+ }
+ ~IMAGE()
+ {
+ delete unit;
+ delete rules;
+ delete place_rules;
+ }
+
+ /**
+ * Function Compare
+ * compares two objects of this type and returns <0, 0, or >0.
+ */
+ static int Compare( IMAGE* lhs, IMAGE* rhs );
+
+ std::string GetImageId()
+ {
+ if( duplicated )
+ {
+ char buf[32];
+
+ std::string ret = image_id;
+ ret += "::";
+ sprintf( buf, "%d", duplicated );
+ ret += buf;
+ return ret;
+ }
+
+ return image_id;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ std::string imageId = GetImageId();
+
+ const char* quote = out->GetQuoteChar( imageId.c_str() );
+
+ out->Print( nestLevel, "(%s %s%s%s", Name(),
+ quote, imageId.c_str(), quote );
+
+ FormatContents( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+ }
+
+ // this is here for makeHash()
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ if( side != T_both )
+ out->Print( 0, " (side %s)", GetTokenText( side ) );
+
+ out->Print( 0, "\n");
+
+ if( unit )
+ unit->Format( out, nestLevel );
+
+ // format the kids, which in this class are the shapes
+ ELEM_HOLDER::FormatContents( out, nestLevel );
+
+ for( PINS::iterator i=pins.begin(); i!=pins.end(); ++i )
+ i->Format( out, nestLevel );
+
+ if( rules )
+ rules->Format( out, nestLevel );
+
+ if( place_rules )
+ place_rules->Format( out, nestLevel );
+
+ for( KEEPOUTS::iterator i=keepouts.begin(); i!=keepouts.end(); ++i )
+ i->Format( out, nestLevel );
+ }
+
+
+ UNIT_RES* GetUnits() const
+ {
+ if( unit )
+ return unit;
+
+ return ELEM::GetUnits();
+ }
+};
+typedef boost::ptr_vector<IMAGE> IMAGES;
+
+
+/**
+ * Class PADSTACK
+ * holds either a via or a pad definition.
+ */
+class PADSTACK : public ELEM_HOLDER
+{
+ friend class SPECCTRA_DB;
+
+ std::string hash; ///< a hash string used by Compare(), not Format()ed/exported.
+
+ std::string padstack_id;
+ UNIT_RES* unit;
+
+ /* The shapes are stored in the kids list */
+
+ DSN_T rotate;
+ DSN_T absolute;
+ DSN_T attach;
+ std::string via_id;
+
+ RULE* rules;
+
+public:
+
+ /**
+ * Constructor PADSTACK()
+ * cannot take ELEM* aParent because PADSTACKSET confuses this with a
+ * copy constructor and causes havoc. Instead set parent with
+ * LIBRARY::AddPadstack()
+ */
+ PADSTACK() :
+ ELEM_HOLDER( T_padstack, NULL )
+ {
+ unit = 0;
+ rotate = T_on;
+ absolute = T_off;
+ rules = 0;
+ attach = T_off;
+ }
+ ~PADSTACK()
+ {
+ delete unit;
+ delete rules;
+ }
+
+ const std::string& GetPadstackId()
+ {
+ return padstack_id;
+ }
+
+ /**
+ * Function Compare
+ * compares two objects of this type and returns <0, 0, or >0.
+ */
+ static int Compare( PADSTACK* lhs, PADSTACK* rhs );
+
+
+ void SetPadstackId( const char* aPadstackId )
+ {
+ padstack_id = aPadstackId;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* quote = out->GetQuoteChar( padstack_id.c_str() );
+
+ out->Print( nestLevel, "(%s %s%s%s\n", Name(),
+ quote, padstack_id.c_str(), quote );
+
+ FormatContents( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+ }
+
+
+ // this factored out for use by Compare()
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ if( unit )
+ unit->Format( out, nestLevel );
+
+ // format the kids, which in this class are the shapes
+ ELEM_HOLDER::FormatContents( out, nestLevel );
+
+ out->Print( nestLevel, "%s", "" );
+
+ // spec for <attach_descriptor> says default is on, so
+ // print the off condition to override this.
+ if( attach == T_off )
+ out->Print( 0, "(attach off)" );
+ else if( attach == T_on )
+ {
+ const char* quote = out->GetQuoteChar( via_id.c_str() );
+ out->Print( 0, "(attach on (use_via %s%s%s))",
+ quote, via_id.c_str(), quote );
+ }
+
+ if( rotate == T_off ) // print the non-default
+ out->Print( 0, "(rotate %s)", GetTokenText( rotate ) );
+
+ if( absolute == T_on ) // print the non-default
+ out->Print( 0, "(absolute %s)", GetTokenText( absolute ) );
+
+ out->Print( 0, "\n" );
+
+ if( rules )
+ rules->Format( out, nestLevel );
+ }
+
+
+ UNIT_RES* GetUnits() const
+ {
+ if( unit )
+ return unit;
+
+ return ELEM::GetUnits();
+ }
+};
+typedef boost::ptr_vector<PADSTACK> PADSTACKS;
+
+
+/**
+ * Function operator<
+ * is used by the PADSTACKSET boost::ptr_set below
+ */
+inline bool operator<( const PADSTACK& lhs, const PADSTACK& rhs )
+{
+ return PADSTACK::Compare( (PADSTACK*) &lhs, (PADSTACK*) &rhs ) < 0;
+}
+
+
+/**
+ * Class LIBRARY
+ * corresponds to the &lt;library_descriptor&gt; in the specctra dsn specification.
+ * Only unit_descriptor, image_descriptors, and padstack_descriptors are
+ * included as children at this time.
+ */
+class LIBRARY : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ UNIT_RES* unit;
+ IMAGES images;
+
+ PADSTACKS padstacks; ///< all except vias, which are in 'vias'
+ PADSTACKS vias;
+
+public:
+
+ LIBRARY( ELEM* aParent, DSN_T aType = T_library ) :
+ ELEM( aType, aParent )
+ {
+ unit = 0;
+// via_start_index = -1; // 0 or greater means there is at least one via
+ }
+ ~LIBRARY()
+ {
+ delete unit;
+ }
+
+ void AddPadstack( PADSTACK* aPadstack )
+ {
+ aPadstack->SetParent( this );
+ padstacks.push_back( aPadstack );
+ }
+
+/*
+ void SetViaStartIndex( int aIndex )
+ {
+ via_start_index = aIndex;
+ }
+ int GetViaStartIndex()
+ {
+ return via_start_index;
+ }
+*/
+
+
+ /**
+ * Function FindIMAGE
+ * searches this LIBRARY for an image which matches the argument.
+ * @return int - if found the index into the images list, else -1.
+ */
+ int FindIMAGE( IMAGE* aImage )
+ {
+ unsigned i;
+ for( i=0; i<images.size(); ++i )
+ {
+ if( 0 == IMAGE::Compare( aImage, &images[i] ) )
+ return (int) i;
+ }
+
+ // There is no match to the IMAGE contents, but now generate a unique
+ // name for it.
+ int dups = 1;
+ for( i=0; i<images.size(); ++i )
+ {
+ if( 0 == aImage->image_id.compare( images[i].image_id ) )
+ aImage->duplicated = dups++;
+ }
+
+ return -1;
+ }
+
+
+ /**
+ * Function AppendIMAGE
+ * adds the image to the image list.
+ */
+ void AppendIMAGE( IMAGE* aImage )
+ {
+ aImage->SetParent( this );
+ images.push_back( aImage );
+ }
+
+ /**
+ * Function LookupIMAGE
+ * will add the image only if one exactly like it does not already exist
+ * in the image container.
+ * @return IMAGE* - the IMAGE which is registered in the LIBRARY that
+ * matches the argument, and it will be either the argument or
+ * a previous image which is a duplicate.
+ */
+ IMAGE* LookupIMAGE( IMAGE* aImage )
+ {
+ int ndx = FindIMAGE( aImage );
+ if( ndx == -1 )
+ {
+ AppendIMAGE( aImage );
+ return aImage;
+ }
+ return &images[ndx];
+ }
+
+ /**
+ * Function FindVia
+ * searches this LIBRARY for a via which matches the argument.
+ * @return int - if found the index into the padstack list, else -1.
+ */
+ int FindVia( PADSTACK* aVia )
+ {
+ for( unsigned i=0; i<vias.size(); ++i )
+ {
+ if( 0 == PADSTACK::Compare( aVia, &vias[i] ) )
+ return int( i );
+ }
+ return -1;
+ }
+
+ /**
+ * Function AppendVia
+ * adds \a aVia to the internal via container.
+ */
+ void AppendVia( PADSTACK* aVia )
+ {
+ aVia->SetParent( this );
+ vias.push_back( aVia );
+ }
+
+
+ /**
+ * Function AppendPADSTACK
+ * adds the padstack to the padstack container.
+ */
+ void AppendPADSTACK( PADSTACK* aPadstack )
+ {
+ aPadstack->SetParent( this );
+ padstacks.push_back( aPadstack );
+ }
+
+ /**
+ * Function LookupVia
+ * will add the via only if one exactly like it does not already exist
+ * in the padstack container.
+ * @return PADSTACK* - the PADSTACK which is registered in the LIBRARY that
+ * matches the argument, and it will be either the argument or
+ * a previous padstack which is a duplicate.
+ */
+ PADSTACK* LookupVia( PADSTACK* aVia )
+ {
+ int ndx = FindVia( aVia );
+ if( ndx == -1 )
+ {
+ AppendVia( aVia );
+ return aVia;
+ }
+ return &vias[ndx];
+ }
+
+ /**
+ * Function FindPADSTACK
+ * searches the padstack container by name.
+ * @return PADSTACK* - The PADSTACK with a matching name if it exists, else NULL.
+ */
+ PADSTACK* FindPADSTACK( const std::string& aPadstackId )
+ {
+ for( unsigned i=0; i<padstacks.size(); ++i )
+ {
+ PADSTACK* ps = &padstacks[i];
+ if( 0 == ps->GetPadstackId().compare( aPadstackId ) )
+ return ps;
+ }
+ return NULL;
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ if( unit )
+ unit->Format( out, nestLevel );
+
+ for( IMAGES::iterator i=images.begin(); i!=images.end(); ++i )
+ i->Format( out, nestLevel );
+
+ for( PADSTACKS::iterator i=padstacks.begin(); i!=padstacks.end(); ++i )
+ i->Format( out, nestLevel );
+
+ for( PADSTACKS::iterator i=vias.begin(); i!=vias.end(); ++i )
+ i->Format( out, nestLevel );
+ }
+
+ UNIT_RES* GetUnits() const
+ {
+ if( unit )
+ return unit;
+
+ return ELEM::GetUnits();
+ }
+};
+
+
+/**
+ * Class PIN_REF
+ * corresponds to the &lt;pin_reference&gt; definition in the specctra dsn spec.
+ */
+struct PIN_REF : public ELEM
+{
+ std::string component_id;
+ std::string pin_id;
+
+ PIN_REF( ELEM* aParent ) :
+ ELEM( T_pin, aParent )
+ {
+ }
+
+
+ /**
+ * Function FormatIt
+ * is like Format() but is not virual and returns the number of characters
+ * that were output.
+ */
+ int FormatIt( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ // only print the newline if there is a nest level, and make
+ // the quotes unconditional on this one.
+ const char* newline = nestLevel ? "\n" : "";
+
+ const char* cquote = out->GetQuoteChar( component_id.c_str() );
+ const char* pquote = out->GetQuoteChar( pin_id.c_str() );
+
+ return out->Print( nestLevel, "%s%s%s-%s%s%s%s",
+ cquote, component_id.c_str(), cquote,
+ pquote, pin_id.c_str(), pquote,
+ newline );
+ }
+};
+typedef std::vector<PIN_REF> PIN_REFS;
+
+
+class FROMTO : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string fromText;
+ std::string toText;
+
+ DSN_T fromto_type;
+ std::string net_id;
+ RULE* rules;
+// std::string circuit;
+ LAYER_RULES layer_rules;
+
+
+public:
+ FROMTO( ELEM* aParent ) :
+ ELEM( T_fromto, aParent )
+ {
+ rules = 0;
+ fromto_type = DSN_T( T_NONE );
+ }
+ ~FROMTO()
+ {
+ delete rules;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ // no quoting on these two, the lexer preserved the quotes on input
+ out->Print( nestLevel, "(%s %s %s ",
+ Name(), fromText.c_str(), toText.c_str() );
+
+ if( fromto_type != DSN_T( T_NONE ) )
+ out->Print( 0, "(type %s)", GetTokenText( fromto_type ) );
+
+ if( net_id.size() )
+ {
+ const char* quote = out->GetQuoteChar( net_id.c_str() );
+ out->Print( 0, "(net %s%s%s)", quote, net_id.c_str(), quote );
+ }
+
+ bool singleLine = true;
+
+ if( rules || layer_rules.size() )
+ {
+ out->Print( 0, "\n" );
+ singleLine = false;
+ }
+
+ if( rules )
+ rules->Format( out, nestLevel+1 );
+
+ /*
+ if( circuit.size() )
+ out->Print( nestLevel, "%s\n", circuit.c_str() );
+ */
+
+ for( LAYER_RULES::iterator i=layer_rules.begin(); i!=layer_rules.end(); ++i )
+ i->Format( out, nestLevel+1 );
+
+ out->Print( singleLine ? 0 : nestLevel, ")" );
+ if( nestLevel || !singleLine )
+ out->Print( 0, "\n" );
+ }
+};
+typedef boost::ptr_vector<FROMTO> FROMTOS;
+
+
+/**
+ * Class COMP_ORDER
+ * corresponds to the &lt;component_order_descriptor&gt;
+ */
+class COMP_ORDER : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ STRINGS placement_ids;
+
+public:
+ COMP_ORDER( ELEM* aParent ) :
+ ELEM( T_comp_order, aParent )
+ {
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ out->Print( nestLevel, "(%s", Name() );
+
+ for( STRINGS::iterator i=placement_ids.begin(); i!=placement_ids.end(); ++i )
+ {
+ const char* quote = out->GetQuoteChar( i->c_str() );
+ out->Print( 0, " %s%s%s", quote, i->c_str(), quote );
+ }
+
+ out->Print( 0, ")" );
+ if( nestLevel )
+ out->Print( 0, "\n" );
+ }
+};
+typedef boost::ptr_vector<COMP_ORDER> COMP_ORDERS;
+
+/**
+ * Class NET
+ * corresponds to a &lt;net_descriptor&gt;
+ * in the DSN spec.
+ */
+class NET : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string net_id;
+ bool unassigned;
+ int net_number;
+
+ DSN_T pins_type; ///< T_pins | T_order, type of field 'pins' below
+ PIN_REFS pins;
+
+ PIN_REFS expose;
+ PIN_REFS noexpose;
+ PIN_REFS source;
+ PIN_REFS load;
+ PIN_REFS terminator;
+
+ DSN_T type; ///< T_fix | T_normal
+
+ DSN_T supply; ///< T_power | T_ground
+
+ RULE* rules;
+
+ LAYER_RULES layer_rules;
+
+ FROMTOS fromtos;
+
+ COMP_ORDER* comp_order;
+
+public:
+
+ NET( ELEM* aParent ) :
+ ELEM( T_net, aParent )
+ {
+ unassigned = false;
+ net_number = T_NONE;
+ pins_type = T_pins;
+
+ type = T_NONE;
+ supply = T_NONE;
+
+ rules = 0;
+ comp_order = 0;
+ }
+
+ ~NET()
+ {
+ delete rules;
+ delete comp_order;
+ }
+
+ int FindPIN_REF( const std::string& aComponent )
+ {
+ for( unsigned i=0; i<pins.size(); ++i )
+ {
+ if( 0 == aComponent.compare( pins[i].component_id ) )
+ return int(i);
+ }
+ return -1;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* quote = out->GetQuoteChar( net_id.c_str() );
+ const char* space = " ";
+
+ out->Print( nestLevel, "(%s %s%s%s", Name(),
+ quote, net_id.c_str(), quote );
+
+ if( unassigned )
+ {
+ out->Print( 0, "%s(unassigned)", space );
+ space = ""; // only needed one space
+ }
+
+ if( net_number != T_NONE )
+ {
+ out->Print( 0, "%s(net_number %d)", space, net_number );
+ // space = "";
+ }
+
+ out->Print( 0, "\n" );
+
+ if( pins.size() )
+ {
+ const int RIGHTMARGIN = 80;
+ int perLine = out->Print( nestLevel+1, "(%s", GetTokenText( pins_type ) );
+
+ for( PIN_REFS::iterator i=pins.begin(); i!=pins.end(); ++i )
+ {
+ if( perLine > RIGHTMARGIN )
+ {
+ out->Print( 0, "\n");
+ perLine = out->Print( nestLevel+2, "%s", "" );
+ }
+ else
+ perLine += out->Print( 0, " " );
+
+ perLine += i->FormatIt( out, 0 );
+ }
+ out->Print( 0, ")\n" );
+ }
+
+ if( comp_order )
+ comp_order->Format( out, nestLevel+1 );
+
+ if( type != T_NONE )
+ out->Print( nestLevel+1, "(type %s)\n", GetTokenText( type ) );
+
+ if( rules )
+ rules->Format( out, nestLevel+1 );
+
+ for( LAYER_RULES::iterator i=layer_rules.begin(); i!=layer_rules.end(); ++i )
+ i->Format( out, nestLevel+1 );
+
+ for( FROMTOS::iterator i=fromtos.begin(); i!=fromtos.end(); ++i )
+ i->Format( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+ }
+};
+typedef boost::ptr_vector<NET> NETS;
+
+
+class TOPOLOGY : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ FROMTOS fromtos;
+
+ COMP_ORDERS comp_orders;
+
+public:
+ TOPOLOGY( ELEM* aParent ) :
+ ELEM( T_topology, aParent )
+ {
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ for( FROMTOS::iterator i=fromtos.begin(); i!=fromtos.end(); ++i )
+ i->Format( out, nestLevel );
+
+ for( COMP_ORDERS::iterator i=comp_orders.begin(); i!=comp_orders.end(); ++i )
+ i->Format( out, nestLevel );
+ }
+};
+
+
+/**
+ * Class CLASS
+ * corresponds to the &lt;class_descriptor&gt; in the specctra spec.
+ */
+class CLASS : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string class_id;
+
+ STRINGS net_ids;
+
+ /// circuit descriptor list
+ STRINGS circuit;
+
+ RULE* rules;
+
+ LAYER_RULES layer_rules;
+
+ TOPOLOGY* topology;
+
+public:
+
+ CLASS( ELEM* aParent ) :
+ ELEM( T_class, aParent )
+ {
+ rules = 0;
+ topology = 0;
+ }
+ ~CLASS()
+ {
+ delete rules;
+ delete topology;
+ }
+
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* quote = out->GetQuoteChar( class_id.c_str() );
+
+ int perLine = out->Print( nestLevel, "(%s %s%s%s",
+ Name(),
+ quote, class_id.c_str(), quote );
+
+ const int RIGHTMARGIN = 72;
+
+ for( STRINGS::iterator i=net_ids.begin(); i!=net_ids.end(); ++i )
+ {
+ const char* space = " ";
+ if( perLine > RIGHTMARGIN )
+ {
+ out->Print( 0, "\n" );
+ perLine = out->Print( nestLevel+1, "%s", "" );
+ space = ""; // no space at first net_id of the line
+ }
+
+ quote = out->GetQuoteChar( i->c_str() );
+ perLine += out->Print( 0, "%s%s%s%s", space, quote, i->c_str(), quote );
+ }
+
+ bool newLine = false;
+ if( circuit.size() || rules || layer_rules.size() || topology )
+ {
+ out->Print( 0, "\n" );
+ newLine = true;
+ }
+
+ if( circuit.size() )
+ {
+ out->Print( nestLevel+1, "(circuit\n" );
+ for( STRINGS::iterator i=circuit.begin(); i!=circuit.end(); ++i )
+ out->Print( nestLevel+2, "%s\n", i->c_str() );
+ out->Print( nestLevel+1, ")\n" );
+ }
+
+ if( rules )
+ rules->Format( out, nestLevel+1 );
+
+ for( LAYER_RULES::iterator i=layer_rules.begin(); i!=layer_rules.end(); ++i )
+ i->Format( out, nestLevel+1 );
+
+ if( topology )
+ topology->Format( out, nestLevel+1 );
+
+ out->Print( newLine ? nestLevel : 0, ")\n" );
+ }
+};
+typedef boost::ptr_vector<CLASS> CLASSLIST;
+
+
+class NETWORK : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ NETS nets;
+ CLASSLIST classes;
+
+
+public:
+
+ NETWORK( ELEM* aParent ) :
+ ELEM( T_network, aParent )
+ {
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ for( NETS::iterator i=nets.begin(); i!=nets.end(); ++i )
+ i->Format( out, nestLevel );
+
+ for( CLASSLIST::iterator i=classes.begin(); i!=classes.end(); ++i )
+ i->Format( out, nestLevel );
+ }
+};
+
+
+class CONNECT : public ELEM
+{
+ // @todo not completed.
+
+public:
+ CONNECT( ELEM* parent ) :
+ ELEM( T_connect, parent ) {}
+};
+
+
+/**
+ * Class WIRE
+ * corresponds to &lt;wire_shape_descriptor&gt; in the specctra dsn spec.
+ */
+class WIRE : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ /* <shape_descriptor >::=
+ [<rectangle_descriptor> |
+ <circle_descriptor> |
+ <polygon_descriptor> |
+ <path_descriptor> |
+ <qarc_descriptor> ]
+ */
+ ELEM* shape;
+
+ std::string net_id;
+ int turret;
+ DSN_T wire_type;
+ DSN_T attr;
+ std::string shield;
+ WINDOWS windows;
+ CONNECT* connect;
+ bool supply;
+
+public:
+ WIRE( ELEM* aParent ) :
+ ELEM( T_wire, aParent )
+ {
+ shape = 0;
+ connect = 0;
+
+ turret = -1;
+ wire_type = T_NONE;
+ attr = T_NONE;
+ supply = false;
+ }
+
+ ~WIRE()
+ {
+ delete shape;
+ delete connect;
+ }
+
+ void SetShape( ELEM* aShape )
+ {
+ delete shape;
+ shape = aShape;
+
+ if( aShape )
+ {
+ wxASSERT(aShape->Type()==T_rect || aShape->Type()==T_circle
+ || aShape->Type()==T_qarc || aShape->Type()==T_path
+ || aShape->Type()==T_polygon);
+
+ aShape->SetParent( this );
+ }
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ out->Print( nestLevel, "(%s ", Name() );
+
+ if( shape )
+ shape->Format( out, 0 );
+
+ if( net_id.size() )
+ {
+ const char* quote = out->GetQuoteChar( net_id.c_str() );
+ out->Print( 0, "(net %s%s%s)",
+ quote, net_id.c_str(), quote );
+ }
+
+ if( turret >= 0 )
+ out->Print( 0, "(turrent %d)", turret );
+
+ if( wire_type != T_NONE )
+ out->Print( 0, "(type %s)", GetTokenText( wire_type ) );
+
+ if( attr != T_NONE )
+ out->Print( 0, "(attr %s)", GetTokenText( attr ) );
+
+ if( shield.size() )
+ {
+ const char* quote = out->GetQuoteChar( shield.c_str() );
+ out->Print( 0, "(shield %s%s%s)",
+ quote, shield.c_str(), quote );
+ }
+
+ if( windows.size() )
+ {
+ out->Print( 0, "\n" );
+
+ for( WINDOWS::iterator i=windows.begin(); i!=windows.end(); ++i )
+ i->Format( out, nestLevel+1 );
+ }
+
+ if( connect )
+ connect->Format( out, 0 );
+
+ if( supply )
+ out->Print( 0, "(supply)" );
+
+ out->Print( 0, ")\n" );
+ }
+};
+typedef boost::ptr_vector<WIRE> WIRES;
+
+
+/**
+ * Class WIRE_VIA
+ * corresponds to &lt;wire_via_descriptor&gt; in the specctra dsn spec.
+ */
+class WIRE_VIA : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string padstack_id;
+ POINTS vertexes;
+ std::string net_id;
+ int via_number;
+ DSN_T via_type;
+ DSN_T attr;
+ std::string virtual_pin_name;
+ STRINGS contact_layers;
+ bool supply;
+
+
+public:
+ WIRE_VIA( ELEM* aParent ) :
+ ELEM( T_via, aParent )
+ {
+ via_number = -1;
+ via_type = T_NONE;
+ attr = T_NONE;
+ supply = false;
+ }
+
+ const std::string& GetPadstackId()
+ {
+ return padstack_id;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* quote = out->GetQuoteChar( padstack_id.c_str() );
+
+ const int RIGHTMARGIN = 80;
+ int perLine = out->Print( nestLevel, "(%s %s%s%s",
+ Name(),
+ quote, padstack_id.c_str(), quote );
+
+ for( POINTS::iterator i=vertexes.begin(); i!=vertexes.end(); ++i )
+ {
+ if( perLine > RIGHTMARGIN )
+ {
+ out->Print( 0, "\n" );
+ perLine = out->Print( nestLevel+1, "%s", "" );
+ }
+ else
+ perLine += out->Print( 0, " " );
+
+ perLine += out->Print( 0, "%.6g %.6g", i->x, i->y );
+ }
+
+ if( net_id.size() || via_number!=-1 || via_type!=T_NONE || attr!=T_NONE || supply)
+ out->Print( 0, " " );
+
+ if( net_id.size() )
+ {
+ if( perLine > RIGHTMARGIN )
+ {
+ out->Print( 0, "\n" );
+ perLine = out->Print( nestLevel+1, "%s", "" );
+ }
+ const char* quote = out->GetQuoteChar( net_id.c_str() );
+ perLine += out->Print( 0, "(net %s%s%s)", quote, net_id.c_str(), quote );
+ }
+
+ if( via_number != -1 )
+ {
+ if( perLine > RIGHTMARGIN )
+ {
+ out->Print( 0, "\n" );
+ perLine = out->Print( nestLevel+1, "%s", "" );
+ }
+ perLine += out->Print( 0, "(via_number %d)", via_number );
+ }
+
+ if( via_type != T_NONE )
+ {
+ if( perLine > RIGHTMARGIN )
+ {
+ out->Print( 0, "\n" );
+ perLine = out->Print( nestLevel+1, "%s", "" );
+ }
+ perLine += out->Print( 0, "(type %s)", GetTokenText( via_type ) );
+ }
+
+ if( attr != T_NONE )
+ {
+ if( perLine > RIGHTMARGIN )
+ {
+ out->Print( 0, "\n" );
+ perLine = out->Print( nestLevel+1, "%s", "" );
+ }
+ if( attr == T_virtual_pin )
+ {
+ const char* quote = out->GetQuoteChar( virtual_pin_name.c_str() );
+ perLine += out->Print( 0, "(attr virtual_pin %s%s%s)",
+ quote, virtual_pin_name.c_str(), quote );
+ }
+ else
+ perLine += out->Print( 0, "(attr %s)", GetTokenText( attr ) );
+ }
+
+ if( supply )
+ {
+ if( perLine > RIGHTMARGIN )
+ {
+ out->Print( 0, "\n" );
+ perLine = out->Print( nestLevel+1, "%s", "" );
+ }
+ perLine += out->Print( 0, "(supply)" );
+ }
+
+ if( contact_layers.size() )
+ {
+ out->Print( 0, "\n" );
+ out->Print( nestLevel+1, "(contact\n" );
+
+ for( STRINGS::iterator i=contact_layers.begin(); i!=contact_layers.end(); ++i )
+ {
+ const char* quote = out->GetQuoteChar( i->c_str() );
+ out->Print( nestLevel+2, "%s%s%s\n", quote, i->c_str(), quote );
+ }
+ out->Print( nestLevel+1, "))\n" );
+ }
+ else
+ out->Print( 0, ")\n" );
+ }
+};
+typedef boost::ptr_vector<WIRE_VIA> WIRE_VIAS;
+
+
+/**
+ * Class WIRING
+ * corresponds to &lt;wiring_descriptor&gt; in the specctra dsn spec.
+ */
+class WIRING : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ UNIT_RES* unit;
+ WIRES wires;
+ WIRE_VIAS wire_vias;
+
+public:
+
+ WIRING( ELEM* aParent ) :
+ ELEM( T_wiring, aParent )
+ {
+ unit = 0;
+ }
+ ~WIRING()
+ {
+ delete unit;
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ if( unit )
+ unit->Format( out, nestLevel );
+
+ for( WIRES::iterator i=wires.begin(); i!=wires.end(); ++i )
+ i->Format( out, nestLevel );
+
+ for( WIRE_VIAS::iterator i=wire_vias.begin(); i!=wire_vias.end(); ++i )
+ i->Format( out, nestLevel );
+ }
+
+ UNIT_RES* GetUnits() const
+ {
+ if( unit )
+ return unit;
+
+ return ELEM::GetUnits();
+ }
+};
+
+
+class PCB : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string pcbname;
+ PARSER* parser;
+ UNIT_RES* resolution;
+ UNIT_RES* unit;
+ STRUCTURE* structure;
+ PLACEMENT* placement;
+ LIBRARY* library;
+ NETWORK* network;
+ WIRING* wiring;
+
+public:
+
+ PCB( ELEM* aParent = 0 ) :
+ ELEM( T_pcb, aParent )
+ {
+ parser = 0;
+ resolution = 0;
+ unit = 0;
+ structure = 0;
+ placement = 0;
+ library = 0;
+ network = 0;
+ wiring = 0;
+ }
+
+ ~PCB()
+ {
+ delete parser;
+ delete resolution;
+ delete unit;
+ delete structure;
+ delete placement;
+ delete library;
+ delete network;
+ delete wiring;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* quote = out->GetQuoteChar( pcbname.c_str() );
+
+ out->Print( nestLevel, "(%s %s%s%s\n", Name(),
+ quote, pcbname.c_str(), quote );
+
+ if( parser )
+ parser->Format( out, nestLevel+1 );
+
+ if( resolution )
+ resolution->Format( out, nestLevel+1 );
+
+ if( unit )
+ unit->Format( out, nestLevel+1 );
+
+ if( structure )
+ structure->Format( out, nestLevel+1 );
+
+ if( placement )
+ placement->Format( out, nestLevel+1 );
+
+ if( library )
+ library->Format( out, nestLevel+1 );
+
+ if( network )
+ network->Format( out, nestLevel+1 );
+
+ if( wiring )
+ wiring->Format( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+ }
+
+ UNIT_RES* GetUnits() const
+ {
+ if( unit )
+ return unit;
+
+ if( resolution )
+ return resolution->GetUnits();
+
+ return ELEM::GetUnits();
+ }
+};
+
+
+class ANCESTOR : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string filename;
+ std::string comment;
+ time_t time_stamp;
+
+
+public:
+ ANCESTOR( ELEM* aParent ) :
+ ELEM( T_ancestor, aParent )
+ {
+ time_stamp = time(NULL);
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ char temp[80];
+ struct tm* tmp;
+
+ tmp = localtime( &time_stamp );
+ strftime( temp, sizeof(temp), "%b %d %H : %M : %S %Y", tmp );
+
+ // format the time first to temp
+ // filename may be empty, so quote it just in case.
+ out->Print( nestLevel, "(%s \"%s\" (created_time %s)\n",
+ Name(),
+ filename.c_str(),
+ temp );
+
+ if( comment.size() )
+ {
+ const char* quote = out->GetQuoteChar( comment.c_str() );
+ out->Print( nestLevel+1, "(comment %s%s%s)\n",
+ quote, comment.c_str(), quote );
+ }
+
+ out->Print( nestLevel, ")\n" );
+ }
+};
+typedef boost::ptr_vector<ANCESTOR> ANCESTORS;
+
+
+class HISTORY : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ ANCESTORS ancestors;
+ time_t time_stamp;
+ STRINGS comments;
+
+public:
+
+ HISTORY( ELEM* aParent ) :
+ ELEM( T_history, aParent )
+ {
+ time_stamp = time(NULL);
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ for( ANCESTORS::iterator i=ancestors.begin(); i!=ancestors.end(); ++i )
+ i->Format( out, nestLevel );
+
+ char temp[80];
+ struct tm* tmp;
+
+ tmp = localtime( &time_stamp );
+ strftime( temp, sizeof(temp), "%b %d %H : %M : %S %Y", tmp );
+
+ // format the time first to temp
+ out->Print( nestLevel, "(self (created_time %s)\n", temp );
+
+ for( STRINGS::iterator i=comments.begin(); i!=comments.end(); ++i )
+ {
+ const char* quote = out->GetQuoteChar( i->c_str() );
+ out->Print( nestLevel+1, "(comment %s%s%s)\n",
+ quote, i->c_str(), quote );
+ }
+
+ out->Print( nestLevel, ")\n" );
+ }
+};
+
+
+/**
+ * Class SUPPLY_PIN
+ * corresponds to the &lt;supply_pin_descriptor&gt; in the specctra dsn spec.
+*/
+class SUPPLY_PIN : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ PIN_REFS pin_refs;
+ std::string net_id;
+
+public:
+ SUPPLY_PIN( ELEM* aParent ) :
+ ELEM( T_supply_pin, aParent )
+ {
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ bool singleLine = pin_refs.size() <= 1;
+ out->Print( nestLevel, "(%s", Name() );
+
+ if( singleLine )
+ {
+ out->Print( 0, "%s", " " );
+ pin_refs.begin()->Format( out, 0 );
+ }
+ else
+ {
+ for( PIN_REFS::iterator i=pin_refs.begin(); i!=pin_refs.end(); ++i )
+ i->FormatIt( out, nestLevel+1 );
+ }
+
+ if( net_id.size() )
+ {
+ const char* newline = singleLine ? "" : "\n";
+
+ const char* quote = out->GetQuoteChar( net_id.c_str() );
+ out->Print( singleLine ? 0 : nestLevel+1,
+ " (net %s%s%s)%s", quote, net_id.c_str(), quote, newline );
+ }
+
+ out->Print( singleLine ? 0 : nestLevel, ")\n");
+ }
+};
+typedef boost::ptr_vector<SUPPLY_PIN> SUPPLY_PINS;
+
+
+/**
+ * Class NET_OUT
+ * corresponds to the &lt;net_out_descriptor&gt; of the specctra dsn spec.
+ */
+class NET_OUT : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string net_id;
+ int net_number;
+ RULE* rules;
+ WIRES wires;
+ WIRE_VIAS wire_vias;
+ SUPPLY_PINS supply_pins;
+
+
+public:
+ NET_OUT( ELEM* aParent ) :
+ ELEM( T_net_out, aParent )
+ {
+ rules = 0;
+ net_number = -1;
+ }
+ ~NET_OUT()
+ {
+ delete rules;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* quote = out->GetQuoteChar( net_id.c_str() );
+
+ // cannot use Type() here, it is T_net_out and we need "(net "
+ out->Print( nestLevel, "(net %s%s%s\n",
+ quote, net_id.c_str(), quote );
+
+ if( net_number>= 0 )
+ out->Print( nestLevel+1, "(net_number %d)\n", net_number );
+
+ if( rules )
+ rules->Format( out, nestLevel+1 );
+
+ for( WIRES::iterator i=wires.begin(); i!=wires.end(); ++i )
+ i->Format( out, nestLevel+1 );
+
+ for( WIRE_VIAS::iterator i=wire_vias.begin(); i!=wire_vias.end(); ++i )
+ i->Format( out, nestLevel+1 );
+
+ for( SUPPLY_PINS::iterator i=supply_pins.begin(); i!=supply_pins.end(); ++i )
+ i->Format( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+ }
+};
+typedef boost::ptr_vector<NET_OUT> NET_OUTS;
+
+
+class ROUTE : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ UNIT_RES* resolution;
+ PARSER* parser;
+ STRUCTURE_OUT* structure_out;
+ LIBRARY* library;
+ NET_OUTS net_outs;
+// TEST_POINTS* test_points;
+
+public:
+
+ ROUTE( ELEM* aParent ) :
+ ELEM( T_route, aParent )
+ {
+ resolution = 0;
+ parser = 0;
+ structure_out = 0;
+ library = 0;
+ }
+ ~ROUTE()
+ {
+ delete resolution;
+ delete parser;
+ delete structure_out;
+ delete library;
+// delete test_points;
+ }
+
+ UNIT_RES* GetUnits() const
+ {
+ if( resolution )
+ return resolution;
+
+ return ELEM::GetUnits();
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ if( resolution )
+ resolution->Format( out, nestLevel );
+
+ if( parser )
+ parser->Format( out, nestLevel );
+
+ if( structure_out )
+ structure_out->Format( out, nestLevel );
+
+ if( library )
+ library->Format( out, nestLevel );
+
+ if( net_outs.size() )
+ {
+ out->Print( nestLevel, "(network_out\n" );
+ for( NET_OUTS::iterator i=net_outs.begin(); i!=net_outs.end(); ++i )
+ i->Format( out, nestLevel+1 );
+ out->Print( nestLevel, ")\n" );
+ }
+
+// if( test_poinst )
+// test_points->Format( out, nestLevel );
+ }
+};
+
+
+/**
+ * Struct PIN_PAIR
+ * is used within the WAS_IS class below to hold a pair of PIN_REFs and
+ * corresponds to the (pins was is) construct within the specctra dsn spec.
+ */
+struct PIN_PAIR
+{
+ PIN_PAIR( ELEM* aParent = 0 ) :
+ was( aParent ),
+ is( aParent )
+ {
+ }
+
+ PIN_REF was;
+ PIN_REF is;
+};
+typedef std::vector<PIN_PAIR> PIN_PAIRS;
+
+
+/**
+ * Class WAS_IS
+ * corresponds to the &lt;was_is_descriptor&gt; in the specctra dsn spec.
+ */
+class WAS_IS : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ PIN_PAIRS pin_pairs;
+
+public:
+ WAS_IS( ELEM* aParent ) :
+ ELEM( T_was_is, aParent )
+ {
+ }
+
+ void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ for( PIN_PAIRS::iterator i=pin_pairs.begin(); i!=pin_pairs.end(); ++i )
+ {
+ out->Print( nestLevel, "(pins " );
+ i->was.Format( out, 0 );
+ out->Print( 0, " " );
+ i->is.Format( out, 0 );
+ out->Print( 0, ")\n" );
+ }
+ }
+};
+
+
+/**
+ * Class SESSION
+ * corresponds to the &lt;session_file_descriptor&gt; in the specctra dsn spec.
+ */
+class SESSION : public ELEM
+{
+ friend class SPECCTRA_DB;
+
+ std::string session_id;
+ std::string base_design;
+
+ HISTORY* history;
+ STRUCTURE* structure;
+ PLACEMENT* placement;
+ WAS_IS* was_is;
+ ROUTE* route;
+
+/* not supported:
+ FLOOR_PLAN* floor_plan;
+ NET_PIN_CHANGES* net_pin_changes;
+ SWAP_HISTORY* swap_history;
+*/
+
+public:
+
+ SESSION( ELEM* aParent = 0 ) :
+ ELEM( T_session, aParent )
+ {
+ history = 0;
+ structure = 0;
+ placement = 0;
+ was_is = 0;
+ route = 0;
+ }
+ ~SESSION()
+ {
+ delete history;
+ delete structure;
+ delete placement;
+ delete was_is;
+ delete route;
+ }
+
+ void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
+ {
+ const char* quote = out->GetQuoteChar( session_id.c_str() );
+ out->Print( nestLevel, "(%s %s%s%s\n", Name(),
+ quote, session_id.c_str(), quote );
+
+ out->Print( nestLevel+1, "(base_design \"%s\")\n", base_design.c_str() );
+
+ if( history )
+ history->Format( out, nestLevel+1 );
+
+ if( structure )
+ structure->Format( out, nestLevel+1 );
+
+ if( placement )
+ placement->Format( out, nestLevel+1 );
+
+ if( was_is )
+ was_is->Format( out, nestLevel+1 );
+
+ if( route )
+ route->Format( out, nestLevel+1 );
+
+ out->Print( nestLevel, ")\n" );
+ }
+};
+
+typedef boost::ptr_set<PADSTACK> PADSTACKSET;
+
+
+/**
+ * Class SPECCTRA_DB
+ * holds a DSN data tree, usually coming from a DSN file. Is essentially a
+ * SPECCTRA_PARSER class.
+ */
+class SPECCTRA_DB : public SPECCTRA_LEXER
+{
+ /// specctra DSN keywords
+ static const KEYWORD keywords[];
+ static const unsigned keywordCount;
+
+ PCB* pcb;
+ SESSION* session;
+ wxString filename;
+ std::string quote_char;
+
+ bool modulesAreFlipped;
+
+ STRING_FORMATTER sf;
+
+ STRINGS layerIds; ///< indexed by PCB layer number
+
+ /// maps BOARD layer number to PCB layer numbers
+ std::vector<int> kicadLayer2pcb;
+
+ /// maps PCB layer number to BOARD layer numbers
+ std::vector<LAYER_ID> pcbLayer2kicad;
+
+ /// used during FromSESSION() only, memory for it is not owned here.
+ UNIT_RES* routeResolution;
+
+ /// a copy to avoid passing as an argument, memory for it is not owned here.
+ BOARD* sessionBoard;
+
+ static const KICAD_T scanPADs[];
+
+ PADSTACKSET padstackset;
+
+ /// we don't want ownership here permanently, so we don't use boost::ptr_vector
+ std::vector<NET*> nets;
+
+ /// specctra cu layers, 0 based index:
+ int m_top_via_layer;
+ int m_bot_via_layer;
+
+
+ /**
+ * Function buildLayerMaps
+ * creates a few data translation structures for layer name and number
+ * mapping between the DSN::PCB structure and the KiCad BOARD structure.
+ * @param aBoard The BOARD to create the maps for.
+ */
+ void buildLayerMaps( BOARD* aBoard );
+
+ /**
+ * Function findLayerName
+ * returns the PCB layer index for a given layer name, within the specctra session
+ * file.
+ *
+ * @return int - the layer index within the specctra session file, or -1 if
+ * aLayerName is not found.
+ */
+ int findLayerName( const std::string& aLayerName ) const;
+
+ /**
+ * Function readCOMPnPIN
+ * reads a &lt;pin_reference&gt; and splits it into the two parts which are
+ * on either side of the hyphen. This function is specialized because
+ * pin_reference may or may not be using double quotes. Both of these
+ * are legal: U2-14 or "U2"-"14". The lexer treats the first one as a
+ * single T_SYMBOL, so in that case we have to split it into two here.
+ * <p>
+ * The caller should have already read in the first token comprizing the
+ * pin_reference and it will be tested through CurTok().
+ *
+ * @param component_id Where to put the text preceeding the '-' hyphen.
+ * @param pid_id Where to put the text which trails the '-'.
+ * @throw IO_ERROR, if the next token or two do no make up a pin_reference,
+ * or there is an error reading from the input stream.
+ */
+ void readCOMPnPIN( std::string* component_id, std::string* pid_id ) throw( IO_ERROR );
+
+ /**
+ * Function readTIME
+ * reads a &lt;time_stamp&gt; which consists of 8 lexer tokens:
+ * "month date hour : minute : second year".
+ * This function is specialized because time_stamps occur more than
+ * once in a session file.
+ * <p>
+ * The caller should not have already read in the first token comprizing the
+ * time stamp.
+ *
+ * @param time_stamp Where to put the parsed time value.
+ * @throw IO_ERROR, if the next token or 8 do no make up a time stamp,
+ * or there is an error reading from the input stream.
+ */
+ void readTIME( time_t* time_stamp ) throw( IO_ERROR );
+
+ void doPCB( PCB* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doPARSER( PARSER* growth ) throw( IO_ERROR );
+ void doRESOLUTION( UNIT_RES* growth ) throw( IO_ERROR );
+ void doUNIT( UNIT_RES* growth ) throw( IO_ERROR );
+ void doSTRUCTURE( STRUCTURE* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doSTRUCTURE_OUT( STRUCTURE_OUT* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doLAYER_NOISE_WEIGHT( LAYER_NOISE_WEIGHT* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doLAYER_PAIR( LAYER_PAIR* growth ) throw( IO_ERROR );
+ void doBOUNDARY( BOUNDARY* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doRECTANGLE( RECTANGLE* growth ) throw( IO_ERROR );
+ void doPATH( PATH* growth ) throw( IO_ERROR );
+ void doSTRINGPROP( STRINGPROP* growth ) throw( IO_ERROR );
+ void doTOKPROP( TOKPROP* growth ) throw( IO_ERROR );
+ void doVIA( VIA* growth ) throw( IO_ERROR );
+ void doCONTROL( CONTROL* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doLAYER( LAYER* growth ) throw( IO_ERROR );
+ void doRULE( RULE* growth ) throw( IO_ERROR );
+ void doKEEPOUT( KEEPOUT* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doCIRCLE( CIRCLE* growth ) throw( IO_ERROR );
+ void doQARC( QARC* growth ) throw( IO_ERROR );
+ void doWINDOW( WINDOW* growth ) throw( IO_ERROR );
+ void doCONNECT( CONNECT* growth ) throw( IO_ERROR );
+ void doREGION( REGION* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doCLASS_CLASS( CLASS_CLASS* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doLAYER_RULE( LAYER_RULE* growth ) throw( IO_ERROR );
+ void doCLASSES( CLASSES* growth ) throw( IO_ERROR );
+ void doGRID( GRID* growth ) throw( IO_ERROR );
+ void doPLACE( PLACE* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doCOMPONENT( COMPONENT* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doPLACEMENT( PLACEMENT* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doPROPERTIES( PROPERTIES* growth ) throw( IO_ERROR );
+ void doPADSTACK( PADSTACK* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doSHAPE( SHAPE* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doIMAGE( IMAGE* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doLIBRARY( LIBRARY* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doPIN( PIN* growth ) throw( IO_ERROR );
+ void doNET( NET* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doNETWORK( NETWORK* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doCLASS( CLASS* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doTOPOLOGY( TOPOLOGY* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doFROMTO( FROMTO* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doCOMP_ORDER( COMP_ORDER* growth ) throw( IO_ERROR );
+ void doWIRE( WIRE* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doWIRE_VIA( WIRE_VIA* growth ) throw( IO_ERROR );
+ void doWIRING( WIRING* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doSESSION( SESSION* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doANCESTOR( ANCESTOR* growth ) throw( IO_ERROR );
+ void doHISTORY( HISTORY* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doROUTE( ROUTE* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doWAS_IS( WAS_IS* growth ) throw( IO_ERROR );
+ void doNET_OUT( NET_OUT* growth ) throw( IO_ERROR, boost::bad_pointer );
+ void doSUPPLY_PIN( SUPPLY_PIN* growth ) throw( IO_ERROR );
+
+ //-----<FromBOARD>-------------------------------------------------------
+
+ /**
+ * Function fillBOUNDARY
+ * makes the board perimeter for the DSN file by filling the BOUNDARY element
+ * in the specctra element tree.
+ * @param aBoard The BOARD to get information from in order to make the BOUNDARY.
+ * @param aBoundary The empty BOUNDARY to fill in.
+ */
+ void fillBOUNDARY( BOARD* aBoard, BOUNDARY* aBoundary ) throw( IO_ERROR, boost::bad_pointer );
+
+ /**
+ * Function makeIMAGE
+ * allocates an IMAGE on the heap and creates all the PINs according
+ * to the D_PADs in the MODULE.
+ * @param aBoard The owner of the MODULE.
+ * @param aModule The MODULE from which to build the IMAGE.
+ * @return IMAGE* - not tested for duplication yet.
+ */
+ IMAGE* makeIMAGE( BOARD* aBoard, MODULE* aModule );
+
+ /**
+ * Function makePADSTACK
+ * creates a PADSTACK which matches the given pad. Only pads which do not
+ * satisfy the function isKeepout() should be passed to this function.
+ * @param aBoard The owner of the MODULE.
+ * @param aPad The D_PAD which needs to be made into a PADSTACK.
+ * @return PADSTACK* - The created padstack, including its padstack_id.
+ */
+ PADSTACK* makePADSTACK( BOARD* aBoard, D_PAD* aPad );
+
+ /**
+ * Function makeVia
+ * makes a round through hole PADSTACK using the given KiCad diameter in deci-mils.
+ * @param aCopperDiameter The diameter of the copper pad.
+ * @param aDrillDiameter The drill diameter, used on re-import of the session file.
+ * @param aTopLayer The DSN::PCB top most layer index.
+ * @param aBotLayer The DSN::PCB bottom most layer index.
+ * @return PADSTACK* - The padstack, which is on the heap only, user must save
+ * or delete it.
+ */
+ PADSTACK* makeVia( int aCopperDiameter, int aDrillDiameter,
+ int aTopLayer, int aBotLayer );
+
+ /**
+ * Function makeVia
+ * makes any kind of PADSTACK using the given KiCad VIA.
+ * @param aVia The VIA to build the padstack from.
+ * @return PADSTACK* - The padstack, which is on the heap only, user must save
+ * or delete it.
+ */
+ PADSTACK* makeVia( const ::VIA* aVia );
+
+ /**
+ * Function deleteNETs
+ * deletes all the NETs that may be in here.
+ */
+ void deleteNETs()
+ {
+ for( unsigned n=0; n<nets.size(); ++n )
+ delete nets[n];
+
+ nets.clear();
+ }
+
+ /**
+ * Function exportNETCLASS
+ * exports \a aNetClass to the DSN file.
+ */
+ void exportNETCLASS( boost::shared_ptr<NETCLASS> aNetClass, BOARD* aBoard );
+
+ //-----</FromBOARD>------------------------------------------------------
+
+ //-----<FromSESSION>-----------------------------------------------------
+
+ /**
+ * Function makeTRACK
+ * creates a TRACK form the PATH and BOARD info.
+ */
+ TRACK* makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) throw( IO_ERROR );
+
+ /**
+ * Function makeVIA
+ * instantiates a KiCad VIA on the heap and initializes it with internal
+ * values consistent with the given PADSTACK, POINT, and netcode.
+ */
+ ::VIA* makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNetCode, int aViaDrillDefault )
+ throw( IO_ERROR );
+
+ //-----</FromSESSION>----------------------------------------------------
+
+public:
+
+ SPECCTRA_DB() :
+ SPECCTRA_LEXER( 0 ) // LINE_READER* == NULL, no DSNLEXER::PushReader()
+ {
+ // The LINE_READER will be pushed from an automatic instantiation,
+ // we don't own it:
+ wxASSERT( !iOwnReaders );
+
+ pcb = 0;
+ session = 0;
+ quote_char += '"';
+ modulesAreFlipped = false;
+
+ SetSpecctraMode( true );
+
+ // Avoid not initialized members:
+ routeResolution = NULL;
+ sessionBoard = NULL;
+ m_top_via_layer = 0;
+ m_bot_via_layer = 0;
+ }
+
+ virtual ~SPECCTRA_DB()
+ {
+ delete pcb;
+ delete session;
+
+ deleteNETs();
+ }
+
+ /**
+ * Function MakePCB
+ * makes a PCB with all the default ELEMs and parts on the heap.
+ */
+ static PCB* MakePCB();
+
+ /**
+ * Function SetPCB
+ * deletes any existing PCB and replaces it with the given one.
+ */
+ void SetPCB( PCB* aPcb )
+ {
+ delete pcb;
+ pcb = aPcb;
+ }
+ PCB* GetPCB() { return pcb; }
+
+ /**
+ * Function SetSESSION
+ * deletes any existing SESSION and replaces it with the given one.
+ */
+ void SetSESSION( SESSION* aSession )
+ {
+ delete session;
+ session = aSession;
+ }
+ SESSION* GetSESSION() { return session; }
+
+ /**
+ * Function LoadPCB
+ * is a recursive descent parser for a SPECCTRA DSN "design" file.
+ * A design file is nearly a full description of a PCB (seems to be
+ * missing only the silkscreen stuff).
+ *
+ * @param filename The name of the dsn file to load.
+ * @throw IO_ERROR if there is a lexer or parser error.
+ */
+ void LoadPCB( const wxString& filename ) throw( IO_ERROR, boost::bad_pointer );
+
+ /**
+ * Function LoadSESSION
+ * is a recursive descent parser for a SPECCTRA DSN "session" file.
+ * A session file is a file that is fed back from the router to the layout
+ * tool (Pcbnew) and should be used to update a BOARD object with the new
+ * tracks, vias, and component locations.
+ *
+ * @param filename The name of the dsn file to load.
+ * @throw IO_ERROR if there is a lexer or parser error.
+ */
+ void LoadSESSION( const wxString& filename ) throw( IO_ERROR, boost::bad_pointer );
+
+ void ThrowIOError( const wxString& fmt, ... ) throw( IO_ERROR );
+
+ /**
+ * Function ExportPCB
+ * writes the internal PCB instance out as a SPECTRA DSN format file.
+ *
+ * @param aFilename The file to save to.
+ * @param aNameChange If true, causes the pcb's name to change to "aFilename"
+ * and also to to be changed in the output file.
+ * @throw IO_ERROR, if an i/o error occurs saving the file.
+ */
+ void ExportPCB( wxString aFilename, bool aNameChange=false ) throw( IO_ERROR );
+
+ /**
+ * Function FromBOARD
+ * adds the entire BOARD to the PCB but does not write it out. Note that
+ * the BOARD given to this function must have all the MODULEs on the component
+ * side of the BOARD.
+ *
+ * See void PCB_EDIT_FRAME::ExportToSpecctra( wxCommandEvent& event )
+ * for how this can be done before calling this function.
+ *
+ * @param aBoard The BOARD to convert to a PCB.
+ */
+ void FromBOARD( BOARD* aBoard ) throw( IO_ERROR, boost::bad_ptr_container_operation );
+
+ /**
+ * Function FromSESSION
+ * adds the entire SESSION info to a BOARD but does not write it out. The
+ * the BOARD given to this function will have all its tracks and via's replaced,
+ * and all its components are subject to being moved.
+ *
+ * @param aBoard The BOARD to merge the SESSION information into.
+ */
+ void FromSESSION( BOARD* aBoard ) throw( IO_ERROR );
+
+ /**
+ * Function ExportSESSION
+ * writes the internal SESSION instance out as a SPECTRA DSN format file.
+ *
+ * @param aFilename The file to save to.
+ */
+ void ExportSESSION( wxString aFilename );
+
+ /**
+ * Function FlipMODULEs
+ * flips the modules which are on the back side of the board to the front.
+ */
+ void FlipMODULEs( BOARD* aBoard );
+
+ /**
+ * Function RevertMODULEs
+ * flips the modules which were on the back side of the board back to the back.
+ */
+ void RevertMODULEs( BOARD* aBoard );
+
+ /**
+ * Function GetBoardPolygonOutlines
+ * Is not used in SPECCTRA export, but uses a lot of functions from it
+ * and is used to extract a board outlines (3D view, automatic zones build ...)
+ * makes the board perimeter by filling the BOUNDARY element
+ * any closed outline inside the main outline is a hole
+ * All contours should be closed, i.e. have valid vertices to build a closed polygon
+ * @param aBoard The BOARD to get information from in order to make the outlines.
+ * @param aOutlines The SHAPE_POLY_SET to fill in with main outlines.
+ * @param aHoles The empty SHAPE_POLY_SET to fill in with holes, if any.
+ * @param aErrorText = a wxString reference to display an error message
+ * with the coordinate of the point which creates the error
+ * (default = NULL , no message returned on error)
+ * @return true if success, false if a contour is not valid
+ */
+ bool GetBoardPolygonOutlines( BOARD* aBoard,
+ SHAPE_POLY_SET& aOutlines,
+ SHAPE_POLY_SET& aHoles,
+ wxString* aErrorText = NULL );
+};
+
+
+} // namespace DSN
+
+#endif // SPECCTRA_H_
+
+//EOF
diff --git a/pcbnew/specctra.keywords b/pcbnew/specctra.keywords
new file mode 100644
index 0000000..0ecfba0
--- /dev/null
+++ b/pcbnew/specctra.keywords
@@ -0,0 +1,392 @@
+
+# Copyright (C) 2007-2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+# These are keywords for the Specctra DSN (s-expression) lexer and parser.
+
+absolute
+added
+add_group
+add_pins
+allow_antenna
+allow_redundant_wiring
+amp
+ancestor
+antipad
+aperture_type
+array
+attach
+attr
+average_pair_length
+back
+base_design
+bbv_ctr2ctr
+bend_keepout
+bond
+both
+bottom
+bottom_layer_sel
+boundary
+brickpat
+bundle
+bus
+bypass
+capacitance_resolution
+capacitor
+case_sensitive
+cct1
+cct1a
+center_center
+checking_trim_by_pin
+circ
+circle
+circuit
+class
+class_class
+classes
+clear
+clearance
+cluster
+cm
+color
+colors
+comment
+comp
+comp_edge_center
+comp_order
+component
+composite
+conductance_resolution
+conductor
+conflict
+connect
+constant
+contact
+control
+corner
+corners
+cost
+created_time
+cross
+crosstalk_model
+current_resolution
+delete_pins
+deleted
+deleted_keepout
+delta
+diagonal
+direction
+directory
+discrete
+effective_via_length
+elongate_keepout
+exclude
+expose
+extra_image_directory
+family
+family_family
+family_family_spacing
+fanout
+farad
+file
+fit
+fix
+flip_style
+floor_plan
+footprint
+forbidden
+force_to_terminal_point
+forgotten
+free
+fromto
+front
+front_only
+gap
+gate
+gates
+generated_by_freeroute
+global
+grid
+group
+group_set
+guide
+hard
+height
+high
+history
+horizontal
+host_cad
+host_version
+image
+image_conductor
+image_image
+image_image_spacing
+image_outline_clearance
+image_set
+image_type
+inch
+include
+include_pins_in_crosstalk
+inductance_resolution
+insert
+instcnfg
+inter_layer_clearance
+jumper
+junction_type
+keepout
+kg
+kohm
+large
+large_large
+layer
+layer_depth
+layer_noise_weight
+layer_pair
+layer_rule
+length
+length_amplitude
+length_factor
+length_gap
+library
+library_out
+limit
+limit_bends
+limit_crossing
+limit_vias
+limit_way
+linear
+linear_interpolation
+load
+lock_type
+logical_part
+logical_part_mapping
+low
+match_fromto_delay
+match_fromto_length
+match_group_delay
+match_group_length
+match_net_delay
+match_net_length
+max_delay
+max_len
+max_length
+max_noise
+max_restricted_layer_length
+max_stagger
+max_stub
+max_total_delay
+max_total_length
+max_total_vias
+medium
+mhenry
+mho
+microvia
+mid_driven
+mil
+min_gap
+mirror
+mirror_first
+mixed
+mm
+negative_diagonal
+net
+net_number
+net_out
+net_pin_changes
+nets
+network
+network_out
+no
+noexpose
+noise_accumulation
+noise_calculation
+normal
+object_type
+off
+off_grid
+offset
+on
+open
+opposite_side
+order
+orthogonal
+outline
+overlap
+pad
+pad_pad
+padstack
+pair
+parallel
+parallel_noise
+parallel_segment
+parser
+part_library
+path
+pcb
+permit_orient
+permit_side
+physical
+physical_part_mapping
+piggyback
+pin
+pin_allow
+pin_cap_via
+pin_via_cap
+pin_width_taper
+pins
+pintype
+place
+place_boundary
+place_control
+place_keepout
+place_rule
+placement
+plan
+plane
+pn
+point
+polyline_path
+polygon
+position
+positive_diagonal
+power
+power_dissipation
+power_fanout
+prefix
+primary
+priority
+property
+protect
+qarc
+quarter
+radius
+ratio
+ratio_tolerance
+rect
+reduced
+region
+region_class
+region_class_class
+region_net
+relative_delay
+relative_group_delay
+relative_group_length
+relative_length
+reorder
+reroute_order_viols
+resistance_resolution
+resistor
+resolution
+restricted_layer_length_factor
+room
+rotate
+rotate_first
+round
+roundoff_rotation
+route
+route_to_fanout_only
+routes
+routes_include
+rule
+same_net_checking
+sample_window
+saturation_length
+sec
+secondary
+self
+sequence_number
+session
+set_color
+set_pattern
+shape
+shield
+shield_gap
+shield_loop
+shield_tie_down_interval
+shield_width
+side
+signal
+site
+small
+smd
+snap
+snap_angle
+soft
+source
+space_in_quoted_tokens
+spacing
+spare
+spiral_via
+square
+stack_via
+stack_via_depth
+standard
+starburst
+status
+structure
+structure_out
+subgate
+subgates
+substituted
+such
+suffix
+super_placement
+supply
+supply_pin
+swapping
+switch_window
+system
+tandem_noise
+tandem_segment
+tandem_shield_overhang
+terminal
+terminator
+term_only
+test
+test_points
+testpoint
+threshold
+time_length_factor
+time_resolution
+tjunction
+tolerance
+top
+topology
+total
+track_id
+turret
+type
+um
+unassigned
+unconnects
+unit
+up
+use_array
+use_layer
+use_net
+use_via
+value
+vertical
+via
+via_array_template
+via_at_smd
+via_keepout
+via_number
+via_rotate_first
+via_site
+via_size
+virtual_pin
+volt
+voltage_resolution
+was_is
+way
+weight
+width
+window
+wire
+wire_keepout
+wires
+wires_include
+wiring
+write_resolution
+ x # test cmake script with indent and comment
+xy
+y
diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp
new file mode 100644
index 0000000..96c96cf
--- /dev/null
+++ b/pcbnew/specctra_export.cpp
@@ -0,0 +1,2247 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* This source is a complement to specctra.cpp and implements the export to
+ specctra dsn file format. The specification for the grammar of the specctra
+ dsn file used to develop this code is given here:
+ http://tech.groups.yahoo.com/group/kicad-users/files/ then file "specctra.pdf"
+
+ Also see the comments at the top of the specctra.cpp file itself.
+*/
+
+#include <wxPcbStruct.h>
+#include <pcbstruct.h> // HISTORY_NUMBER
+#include <confirm.h> // DisplayError()
+#include <gestfich.h> // EDA_FileSelector()
+#include <trigo.h> // RotatePoint()
+#include <macros.h>
+
+#include <set> // std::set
+#include <map> // std::map
+
+#include <boost/utility.hpp> // boost::addressof()
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+#include <class_track.h>
+#include <class_zone.h>
+#include <class_drawsegment.h>
+#include <base_units.h>
+
+#include <collectors.h>
+
+#include <geometry/shape_poly_set.h>
+
+#include <specctra.h>
+
+using namespace DSN;
+
+
+// Add .1 mil to the requested clearances as a safety margin.
+// There has been disagreement about interpretation of clearance in the past
+// between KiCad and Freerouter, so keep this safetyMargin until the
+// disagreement is resolved and stable. Freerouter seems to be moving
+// (protected) traces upon loading the DSN file, and even though it seems to sometimes
+// add its own 0.1 to the clearances, I believe this is happening after
+// the load process (and moving traces) so I am of the opinion this is
+// still needed.
+static const double safetyMargin = 0.1;
+
+
+/**
+ * Function close_ness
+ * is a non-exact distance calculator used to approximate the distance between
+ * two points. The distance is very in-exact, but can be helpful when used
+ * to pick between alternative neighboring points.
+ * @param aLeft is the first point
+ * @param aRight is the second point
+ * @return unsigned - a measure of proximity that the caller knows about, in BIU,
+ * but remember it is only an approximation.
+ */
+static unsigned close_ness( const wxPoint& aLeft, const wxPoint& aRight )
+{
+ // Don't need an accurate distance calculation, just something
+ // approximating it, for relative ordering.
+ return unsigned( abs( aLeft.x - aRight.x ) + abs( aLeft.y - aRight.y ) );
+}
+
+
+/**
+ * Function close_enough
+ * is a local and tunable method of qualifying the proximity of two points.
+ *
+ * @param aLeft is the first point
+ * @param aRight is the second point
+ * @param aLimit is a measure of proximity that the caller knows about.
+ * @return bool - true if the two points are close enough, else false.
+ */
+inline bool close_enough( const wxPoint& aLeft, const wxPoint& aRight, unsigned aLimit )
+{
+ // We don't use an accurate distance calculation, just something
+ // approximating it, since aLimit is non-exact anyway except when zero.
+ return close_ness( aLeft, aRight ) <= aLimit;
+}
+
+
+/**
+ * Function close_st
+ * is a local method of qualifying if either the start of end point of a segment is closest to a point.
+ *
+ * @param aReference is the reference point
+ * @param aFirst is the first point
+ * @param aSecond is the second point
+ * @return bool - true if the the first point is closest to the reference, otherwise false.
+ */
+inline bool close_st( const wxPoint& aReference, const wxPoint& aFirst, const wxPoint& aSecond )
+{
+ // We don't use an accurate distance calculation, just something
+ // approximating to find the closest to the reference.
+ return close_ness( aReference, aFirst ) <= close_ness( aReference, aSecond );
+}
+
+
+// see wxPcbStruct.h
+void PCB_EDIT_FRAME::ExportToSpecctra( wxCommandEvent& event )
+{
+ wxString fullFileName = GetBoard()->GetFileName();
+ wxString path;
+ wxString name;
+ wxString ext;
+ wxString dsn_ext = wxT( ".dsn" );
+ wxString mask = wxT( "*" ) + dsn_ext;
+
+ wxFileName::SplitPath( fullFileName, &path, &name, &ext );
+
+ name += dsn_ext;
+
+ fullFileName = EDA_FILE_SELECTOR( _( "Specctra DSN file:" ),
+ path,
+ name, // name.ext without path!
+ dsn_ext,
+ mask,
+ this,
+ wxFD_SAVE,
+ false );
+
+ if( fullFileName == wxEmptyString )
+ return;
+
+ ExportSpecctraFile( fullFileName );
+}
+
+
+bool PCB_EDIT_FRAME::ExportSpecctraFile( const wxString& aFullFilename )
+{
+ SPECCTRA_DB db;
+ bool ok = true;
+ wxString errorText;
+
+ BASE_SCREEN* screen = GetScreen();
+ bool wasModified = screen->IsModify();
+
+ db.SetPCB( SPECCTRA_DB::MakePCB() );
+
+ LOCALE_IO toggle; // Switch the locale to standard C
+
+ // DSN Images (=KiCad MODULES and pads) must be presented from the
+ // top view. So we temporarily flip any modules which are on the back
+ // side of the board to the front, and record this in the MODULE's flag field.
+ db.FlipMODULEs( GetBoard() );
+
+ try
+ {
+ GetBoard()->SynchronizeNetsAndNetClasses();
+ db.FromBOARD( GetBoard() );
+ db.ExportPCB( aFullFilename, true );
+
+ // if an exception is thrown by FromBOARD or ExportPCB(), then
+ // ~SPECCTRA_DB() will close the file.
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ ok = false;
+
+ // copy the error string to safe place, ioe is in this scope only.
+ errorText = ioe.errorText;
+ }
+
+ // done assuredly, even if an exception was thrown and caught.
+ db.RevertMODULEs( GetBoard() );
+
+ // The two calls below to MODULE::Flip(), both set the
+ // modified flag, yet their actions cancel each other out, so it should
+ // be ok to clear the modify flag.
+ if( !wasModified )
+ screen->ClrModify();
+
+ if( ok )
+ {
+ SetStatusText( wxString( _( "BOARD exported OK." ) ) );
+ }
+ else
+ {
+ errorText += '\n';
+ errorText += _( "Unable to export, please fix and try again." );
+ DisplayError( this, errorText );
+ }
+
+ return ok;
+}
+
+
+namespace DSN {
+
+const KICAD_T SPECCTRA_DB::scanPADs[] = { PCB_PAD_T, EOT };
+
+// "specctra reported units" are what we tell the external router that our
+// exported lengths are in.
+
+
+/**
+ * Function scale
+ * converts a distance from PCBNEW internal units to the reported specctra dsn units
+ * in floating point format.
+ */
+static inline double scale( int kicadDist )
+{
+ // nanometers to um
+ return kicadDist / ( IU_PER_MM / 1000.0 );
+}
+
+
+// / Convert integer internal units to float um
+static inline double IU2um( int kicadDist )
+{
+ return kicadDist * (1000.0 / IU_PER_MM);
+}
+
+
+static inline double mapX( int x )
+{
+ return scale( x );
+}
+
+
+static inline double mapY( int y )
+{
+ return -scale( y ); // make y negative, since it is increasing going down.
+}
+
+
+/**
+ * Function mapPt
+ * converts a KiCad point into a DSN file point. Kicad's BOARD coordinates
+ * are in nanometers (called Internal Units or IU)and we are exporting in units
+ * of mils, so we have to scale them.
+ */
+static POINT mapPt( const wxPoint& pt )
+{
+ POINT ret;
+
+ ret.x = mapX( pt.x );
+ ret.y = mapY( pt.y );
+ ret.FixNegativeZero();
+ return ret;
+}
+
+
+/**
+ * Function findPoint
+ * searches for a DRAWSEGMENT with an end point or start point of aPoint, and
+ * if found, removes it from the TYPE_COLLECTOR and returns it, else returns NULL.
+ * @param aPoint The starting or ending point to search for.
+ * @param items The list to remove from.
+ * @param aLimit is the distance from \a aPoint that still constitutes a valid find.
+ * @return DRAWSEGMENT* - The first DRAWSEGMENT that has a start or end point matching
+ * aPoint, otherwise NULL if none.
+ */
+static DRAWSEGMENT* findPoint( const wxPoint& aPoint, ::PCB_TYPE_COLLECTOR* items, unsigned aLimit )
+{
+ unsigned min_d = INT_MAX;
+ int ndx_min = 0;
+
+ // find the point closest to aPoint and perhaps exactly matching aPoint.
+ for( int i = 0; i < items->GetCount(); ++i )
+ {
+ DRAWSEGMENT* graphic = (DRAWSEGMENT*) (*items)[i];
+ unsigned d;
+
+ wxASSERT( graphic->Type() == PCB_LINE_T || graphic->Type() == PCB_MODULE_EDGE_T );
+
+ switch( graphic->GetShape() )
+ {
+ case S_ARC:
+ if( aPoint == graphic->GetArcStart() || aPoint == graphic->GetArcEnd() )
+ {
+ items->Remove( i );
+ return graphic;
+ }
+
+ d = close_ness( aPoint, graphic->GetArcStart() );
+ if( d < min_d )
+ {
+ min_d = d;
+ ndx_min = i;
+ }
+
+ d = close_ness( aPoint, graphic->GetArcEnd() );
+ if( d < min_d )
+ {
+ min_d = d;
+ ndx_min = i;
+ }
+ break;
+
+ default:
+ if( aPoint == graphic->GetStart() || aPoint == graphic->GetEnd() )
+ {
+ items->Remove( i );
+ return graphic;
+ }
+
+ d = close_ness( aPoint, graphic->GetStart() );
+ if( d < min_d )
+ {
+ min_d = d;
+ ndx_min = i;
+ }
+
+ d = close_ness( aPoint, graphic->GetEnd() );
+ if( d < min_d )
+ {
+ min_d = d;
+ ndx_min = i;
+ }
+ }
+ }
+
+ if( min_d <= aLimit )
+ {
+ DRAWSEGMENT* graphic = (DRAWSEGMENT*) (*items)[ndx_min];
+ items->Remove( ndx_min );
+ return graphic;
+ }
+
+#if defined(DEBUG)
+ if( items->GetCount() )
+ {
+ printf( "Unable to find segment matching point (%.6g;%.6g) (seg count %d)\n",
+ IU2um( aPoint.x )/1000, IU2um( aPoint.y )/1000,
+ items->GetCount());
+
+ for( int i = 0; i< items->GetCount(); ++i )
+ {
+ DRAWSEGMENT* graphic = (DRAWSEGMENT*) (*items)[i];
+
+ if( graphic->GetShape() == S_ARC )
+ printf( "item %d, type=%s, start=%.6g;%.6g end=%.6g;%.6g\n",
+ i + 1,
+ TO_UTF8( BOARD_ITEM::ShowShape( graphic->GetShape() ) ),
+ IU2um( graphic->GetArcStart().x )/1000,
+ IU2um( graphic->GetArcStart().y )/1000,
+ IU2um( graphic->GetArcEnd().x )/1000,
+ IU2um( graphic->GetArcEnd().y )/1000 );
+ else
+ printf( "item %d, type=%s, start=%.6g;%.6g end=%.6g;%.6g\n",
+ i + 1,
+ TO_UTF8( BOARD_ITEM::ShowShape( graphic->GetShape() ) ),
+ IU2um( graphic->GetStart().x )/1000,
+ IU2um( graphic->GetStart().y )/1000,
+ IU2um( graphic->GetEnd().x )/1000,
+ IU2um( graphic->GetEnd().y )/1000 );
+ }
+ }
+#endif
+
+ return NULL;
+}
+
+
+/**
+ * Function isRoundKeepout
+ * decides if the pad is a copper-less through hole which needs to be made into
+ * a round keepout.
+ */
+static bool isRoundKeepout( D_PAD* aPad )
+{
+ if( aPad->GetShape()==PAD_SHAPE_CIRCLE )
+ {
+ if( aPad->GetDrillSize().x >= aPad->GetSize().x )
+ return true;
+
+ if( !( aPad->GetLayerSet() & LSET::AllCuMask() ).any() )
+ return true;
+ }
+
+ return false;
+}
+
+
+/**
+ * Function makePath
+ * creates a PATH element with a single straight line, a pair of vertices.
+ */
+static PATH* makePath( const POINT& aStart, const POINT& aEnd, const std::string& aLayerName )
+{
+ PATH* path = new PATH( 0, T_path );
+
+ path->AppendPoint( aStart );
+ path->AppendPoint( aEnd );
+ path->SetLayerId( aLayerName.c_str() );
+ return path;
+}
+
+
+PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
+{
+ char name[256]; // padstack name builder
+ std::string uniqifier;
+
+ // caller must do these checks before calling here.
+ wxASSERT( !isRoundKeepout( aPad ) );
+
+ PADSTACK* padstack = new PADSTACK();
+
+ int reportedLayers = 0; // how many in reported padstack
+ const char* layerName[MAX_CU_LAYERS];
+
+ uniqifier = '[';
+
+ static const LSET all_cu = LSET::AllCuMask();
+
+ bool onAllCopperLayers = ( (aPad->GetLayerSet() & all_cu) == all_cu );
+
+ if( onAllCopperLayers )
+ uniqifier += 'A'; // A for all layers
+
+ const int copperCount = aBoard->GetCopperLayerCount();
+ for( int layer=0; layer<copperCount; ++layer )
+ {
+ LAYER_ID kilayer = pcbLayer2kicad[layer];
+
+ if( onAllCopperLayers || aPad->IsOnLayer( kilayer ) )
+ {
+ layerName[reportedLayers++] = layerIds[layer].c_str();
+
+ if( !onAllCopperLayers )
+ {
+ if( layer == 0 )
+ uniqifier += 'T';
+ else if( layer == copperCount - 1 )
+ uniqifier += 'B';
+ else
+ uniqifier += char('0' + layer); // layer index char
+ }
+ }
+ }
+
+ uniqifier += ']';
+
+ POINT dsnOffset;
+
+ if( aPad->GetOffset().x || aPad->GetOffset().y )
+ {
+ char offsetTxt[64];
+
+ wxPoint offset( aPad->GetOffset().x, aPad->GetOffset().y );
+
+ dsnOffset = mapPt( offset );
+
+ // using '(' or ')' would cause padstack name to be quote wrapped,
+ // so use other brackets, and {} locks freerouter.
+ sprintf( offsetTxt, "[%.6g,%.6g]", dsnOffset.x, dsnOffset.y );
+
+ uniqifier += offsetTxt;
+ }
+
+ switch( aPad->GetShape() )
+ {
+ default:
+ case PAD_SHAPE_CIRCLE:
+ {
+ double diameter = scale( aPad->GetSize().x );
+
+ for( int ndx=0; ndx<reportedLayers; ++ndx )
+ {
+ SHAPE* shape = new SHAPE( padstack );
+
+ padstack->Append( shape );
+
+ CIRCLE* circle = new CIRCLE( shape );
+
+ shape->SetShape( circle );
+
+ circle->SetLayerId( layerName[ndx] );
+ circle->SetDiameter( diameter );
+ circle->SetVertex( dsnOffset );
+ }
+
+ snprintf( name, sizeof(name), "Round%sPad_%.6g_um",
+ uniqifier.c_str(), IU2um( aPad->GetSize().x ) );
+
+ name[ sizeof(name) - 1 ] = 0;
+
+ padstack->SetPadstackId( name );
+ }
+ break;
+
+ case PAD_SHAPE_RECT:
+ {
+ double dx = scale( aPad->GetSize().x ) / 2.0;
+ double dy = scale( aPad->GetSize().y ) / 2.0;
+
+ POINT lowerLeft( -dx, -dy );
+ POINT upperRight( dx, dy );
+
+ lowerLeft += dsnOffset;
+ upperRight += dsnOffset;
+
+ for( int ndx=0; ndx<reportedLayers; ++ndx )
+ {
+ SHAPE* shape = new SHAPE( padstack );
+
+ padstack->Append( shape );
+
+ RECTANGLE* rect = new RECTANGLE( shape );
+
+ shape->SetShape( rect );
+
+ rect->SetLayerId( layerName[ndx] );
+ rect->SetCorners( lowerLeft, upperRight );
+ }
+
+ snprintf( name, sizeof(name), "Rect%sPad_%.6gx%.6g_um",
+ uniqifier.c_str(),
+ IU2um( aPad->GetSize().x ),
+ IU2um( aPad->GetSize().y ) );
+
+ name[ sizeof(name) - 1 ] = 0;
+
+ padstack->SetPadstackId( name );
+ }
+ break;
+
+ case PAD_SHAPE_OVAL:
+ {
+ double dx = scale( aPad->GetSize().x ) / 2.0;
+ double dy = scale( aPad->GetSize().y ) / 2.0;
+ double dr = dx - dy;
+ double radius;
+ POINT start;
+ POINT stop;
+
+ if( dr >= 0 ) // oval is horizontal
+ {
+ radius = dy;
+
+ start = POINT( -dr, 0.0 );
+ stop = POINT( dr, 0.0 );
+ }
+ else // oval is vertical
+ {
+ radius = dx;
+ dr = -dr;
+
+ start = POINT( 0.0, -dr );
+ stop = POINT( 0.0, dr );
+ }
+
+ start += dsnOffset;
+ stop += dsnOffset;
+
+ for( int ndx=0; ndx<reportedLayers; ++ndx )
+ {
+ SHAPE* shape;
+ PATH* path;
+ // see http://www.freerouting.net/usren/viewtopic.php?f=3&t=317#p408
+ shape = new SHAPE( padstack );
+
+ padstack->Append( shape );
+ path = makePath( start, stop, layerName[ndx] );
+ shape->SetShape( path );
+ path->aperture_width = 2.0 * radius;
+ }
+
+ snprintf( name, sizeof(name), "Oval%sPad_%.6gx%.6g_um",
+ uniqifier.c_str(),
+ IU2um( aPad->GetSize().x ),
+ IU2um( aPad->GetSize().y ) );
+ name[ sizeof(name) - 1 ] = 0;
+
+ padstack->SetPadstackId( name );
+ }
+ break;
+
+ case PAD_SHAPE_TRAPEZOID:
+ {
+ double dx = scale( aPad->GetSize().x ) / 2.0;
+ double dy = scale( aPad->GetSize().y ) / 2.0;
+
+ double ddx = scale( aPad->GetDelta().x ) / 2.0;
+ double ddy = scale( aPad->GetDelta().y ) / 2.0;
+
+ // see class_pad_draw_functions.cpp which draws the trapezoid pad
+ POINT lowerLeft( -dx - ddy, -dy - ddx );
+ POINT upperLeft( -dx + ddy, +dy + ddx );
+ POINT upperRight( +dx - ddy, +dy - ddx );
+ POINT lowerRight( +dx + ddy, -dy + ddx );
+
+ lowerLeft += dsnOffset;
+ upperLeft += dsnOffset;
+ upperRight += dsnOffset;
+ lowerRight += dsnOffset;
+
+ for( int ndx=0; ndx<reportedLayers; ++ndx )
+ {
+ SHAPE* shape = new SHAPE( padstack );
+
+ padstack->Append( shape );
+
+ // a T_polygon exists as a PATH
+ PATH* polygon = new PATH( shape, T_polygon );
+
+ shape->SetShape( polygon );
+
+ polygon->SetLayerId( layerName[ndx] );
+
+ polygon->AppendPoint( lowerLeft );
+ polygon->AppendPoint( upperLeft );
+ polygon->AppendPoint( upperRight );
+ polygon->AppendPoint( lowerRight );
+ }
+
+ // this string _must_ be unique for a given physical shape
+ snprintf( name, sizeof(name), "Trapz%sPad_%.6gx%.6g_%c%.6gx%c%.6g_um",
+ uniqifier.c_str(), IU2um( aPad->GetSize().x ), IU2um( aPad->GetSize().y ),
+ aPad->GetDelta().x < 0 ? 'n' : 'p',
+ std::abs( IU2um( aPad->GetDelta().x )),
+ aPad->GetDelta().y < 0 ? 'n' : 'p',
+ std::abs( IU2um( aPad->GetDelta().y ) )
+ );
+ name[ sizeof(name)-1 ] = 0;
+
+ padstack->SetPadstackId( name );
+ }
+ break;
+ }
+
+ return padstack;
+}
+
+
+/// data type used to ensure unique-ness of pin names, holding (wxString and int)
+typedef std::map<wxString, int> PINMAP;
+
+
+IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, MODULE* aModule )
+{
+ PINMAP pinmap;
+ wxString padName;
+
+ PCB_TYPE_COLLECTOR moduleItems;
+
+ // get all the MODULE's pads.
+ moduleItems.Collect( aModule, scanPADs );
+
+ IMAGE* image = new IMAGE(0);
+
+ image->image_id = aModule->GetFPID().Format().c_str();
+
+ // from the pads, and make an IMAGE using collated padstacks.
+ for( int p=0; p<moduleItems.GetCount(); ++p )
+ {
+ D_PAD* pad = (D_PAD*) moduleItems[p];
+
+ // see if this pad is a through hole with no copper on its perimeter
+ if( isRoundKeepout( pad ) )
+ {
+ double diameter = scale( pad->GetDrillSize().x );
+ POINT vertex = mapPt( pad->GetPos0() );
+
+ int layerCount = aBoard->GetCopperLayerCount();
+ for( int layer=0; layer<layerCount; ++layer )
+ {
+ KEEPOUT* keepout = new KEEPOUT( image, T_keepout );
+
+ image->keepouts.push_back( keepout );
+
+ CIRCLE* circle = new CIRCLE( keepout );
+
+ keepout->SetShape( circle );
+
+ circle->SetDiameter( diameter );
+ circle->SetVertex( vertex );
+ circle->SetLayerId( layerIds[layer].c_str() );
+ }
+ }
+ // else if() could there be a square keepout here?
+
+ else
+ {
+ PADSTACK* padstack = makePADSTACK( aBoard, pad );
+ PADSTACKSET::iterator iter = padstackset.find( *padstack );
+
+ if( iter != padstackset.end() )
+ {
+ // padstack is a duplicate, delete it and use the original
+ delete padstack;
+ padstack = (PADSTACK*) *iter.base(); // folklore, be careful here
+ }
+ else
+ {
+ padstackset.insert( padstack );
+ }
+
+ PIN* pin = new PIN( image );
+
+ padName = pad->GetPadName();
+ pin->pin_id = TO_UTF8( padName );
+
+ if( padName!=wxEmptyString && pinmap.find( padName )==pinmap.end() )
+ {
+ pinmap[ padName ] = 0;
+ }
+ else // pad name is a duplicate within this module
+ {
+ char buf[32];
+
+ int duplicates = ++pinmap[ padName ];
+
+ sprintf( buf, "@%d", duplicates );
+
+ pin->pin_id += buf; // append "@1" or "@2", etc. to pin name
+ }
+
+ pin->kiNetCode = pad->GetNetCode();
+
+ image->pins.push_back( pin );
+
+ pin->padstack_id = padstack->padstack_id;
+
+ int angle = pad->GetOrientation() - aModule->GetOrientation(); // tenths of degrees
+
+ if( angle )
+ {
+ NORMALIZE_ANGLE_POS( angle );
+ pin->SetRotation( angle / 10.0 );
+ }
+
+ wxPoint pos( pad->GetPos0() );
+
+ pin->SetVertex( mapPt( pos ) );
+ }
+ }
+
+#if 1 // enable image (outline) scopes.
+ static const KICAD_T scanEDGEs[] = { PCB_MODULE_EDGE_T, EOT };
+
+ // get all the MODULE's EDGE_MODULEs and convert those to DSN outlines.
+ moduleItems.Collect( aModule, scanEDGEs );
+
+ for( int i = 0; i<moduleItems.GetCount(); ++i )
+ {
+ EDGE_MODULE* graphic = (EDGE_MODULE*) moduleItems[i];
+ SHAPE* outline;
+ PATH* path;
+
+ switch( graphic->GetShape() )
+ {
+ case S_SEGMENT:
+ outline = new SHAPE( image, T_outline );
+
+ image->Append( outline );
+ path = new PATH( outline );
+
+ outline->SetShape( path );
+ path->SetAperture( scale( graphic->GetWidth() ) );
+ path->SetLayerId( "signal" );
+ path->AppendPoint( mapPt( graphic->GetStart0() ) );
+ path->AppendPoint( mapPt( graphic->GetEnd0() ) );
+ break;
+
+ case S_CIRCLE:
+ {
+ // this is best done by 4 QARC's but freerouter does not yet support QARCs.
+ // for now, support by using line segments.
+
+ outline = new SHAPE( image, T_outline );
+
+ image->Append( outline );
+ path = new PATH( outline );
+
+ outline->SetShape( path );
+ path->SetAperture( scale( graphic->GetWidth() ) );
+ path->SetLayerId( "signal" );
+
+ // Do the math using KiCad units, that way we stay out of the
+ // scientific notation range of floating point numbers in the
+ // DSN file. We do not parse scientific notation in our own
+ // lexer/beautifier, and the spec is not clear that this is
+ // required. Fixed point floats are all that should be needed.
+
+ double radius = GetLineLength( graphic->GetStart(), graphic->GetEnd() );
+
+ // better if evenly divisible into 360
+ const int DEGREE_INTERVAL = 18; // 18 means 20 line segments
+
+ for( double radians = 0.0;
+ radians < 2 * M_PI;
+ radians += DEGREE_INTERVAL * M_PI / 180.0 )
+ {
+ wxPoint point( KiROUND( radius * cos( radians ) ),
+ KiROUND( radius * sin( radians ) ) );
+
+ point += graphic->m_Start0; // an offset
+
+ path->AppendPoint( mapPt( point ) );
+ }
+ }
+ break;
+
+ case S_RECT:
+ case S_ARC:
+ default:
+ DBG( printf( "makeIMAGE(): unsupported shape %s\n",
+ TO_UTF8( BOARD_ITEM::ShowShape( graphic->GetShape() ) ) ); )
+ continue;
+ }
+ }
+
+#endif
+
+ return image;
+}
+
+
+PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter, int aDrillDiameter,
+ int aTopLayer, int aBotLayer )
+{
+ char name[48];
+ PADSTACK* padstack = new PADSTACK();
+ double dsnDiameter = scale( aCopperDiameter );
+
+ for( int layer=aTopLayer; layer<=aBotLayer; ++layer )
+ {
+ SHAPE* shape = new SHAPE( padstack );
+
+ padstack->Append( shape );
+
+ CIRCLE* circle = new CIRCLE( shape );
+
+ shape->SetShape( circle );
+
+ circle->SetDiameter( dsnDiameter );
+ circle->SetLayerId( layerIds[layer].c_str() );
+ }
+
+ snprintf( name, sizeof(name), "Via[%d-%d]_%.6g:%.6g_um",
+ aTopLayer, aBotLayer, dsnDiameter,
+ // encode the drill value into the name for later import
+ IU2um( aDrillDiameter )
+ );
+
+ name[ sizeof(name) - 1 ] = 0;
+ padstack->SetPadstackId( name );
+
+ return padstack;
+}
+
+
+PADSTACK* SPECCTRA_DB::makeVia( const ::VIA* aVia )
+{
+ LAYER_ID topLayerNum;
+ LAYER_ID botLayerNum;
+
+ aVia->LayerPair( &topLayerNum, &botLayerNum );
+
+ int topLayer = kicadLayer2pcb[topLayerNum];
+ int botLayer = kicadLayer2pcb[botLayerNum];
+
+ if( topLayer > botLayer )
+ std::swap( topLayer, botLayer );
+
+ return makeVia( aVia->GetWidth(), aVia->GetDrillValue(), topLayer, botLayer );
+}
+
+
+/**
+ * Function makeCircle
+ * does a line segmented circle into aPath.
+ */
+static void makeCircle( PATH* aPath, DRAWSEGMENT* aGraphic )
+{
+ // do a circle segmentation
+ const int STEPS = 2 * 36;
+
+ int radius = aGraphic->GetRadius();
+
+ if( radius <= 0 ) // Should not occur, but ...
+ return;
+
+ wxPoint center = aGraphic->GetCenter();
+ double angle = 3600.0;
+ wxPoint start = center;
+ start.x += radius;
+
+ wxPoint nextPt;
+
+ for( int step = 0; step<STEPS; ++step )
+ {
+ double rotation = ( angle * step ) / STEPS;
+
+ nextPt = start;
+
+ RotatePoint( &nextPt.x, &nextPt.y, center.x, center.y, rotation );
+
+ aPath->AppendPoint( mapPt( nextPt ) );
+ }
+}
+
+
+void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary )
+ throw( IO_ERROR, boost::bad_pointer )
+{
+ PCB_TYPE_COLLECTOR items;
+
+ unsigned prox; // a proximity BIU metric, not an accurate distance
+ const int STEPS = 36; // for a segmentation of an arc of 360 degrees
+
+ // Get all the DRAWSEGMENTS and module graphics into 'items',
+ // then keep only those on layer == Edge_Cuts.
+
+ static const KICAD_T scan_graphics[] = { PCB_LINE_T, PCB_MODULE_EDGE_T, EOT };
+
+ items.Collect( aBoard, scan_graphics );
+
+ for( int i = 0; i<items.GetCount(); )
+ {
+ if( items[i]->GetLayer() != Edge_Cuts )
+ items.Remove( i );
+ else // remove graphics not on Edge_Cuts layer
+ ++i;
+ }
+
+ if( items.GetCount() )
+ {
+ PATH* path = new PATH( boundary );
+ boundary->paths.push_back( path );
+ path->layer_id = "pcb";
+
+ wxPoint prevPt;
+
+ DRAWSEGMENT* graphic;
+
+ // Find edge point with minimum x, this should be in the outer polygon
+ // which will define the perimeter Edge.Cuts polygon.
+ wxPoint xmin = wxPoint( INT_MAX, 0 );
+ int xmini = 0;
+
+ for( int i = 0; i < items.GetCount(); i++ )
+ {
+ graphic = (DRAWSEGMENT*) items[i];
+
+ switch( graphic->GetShape() )
+ {
+ case S_SEGMENT:
+ {
+ if( graphic->GetStart().x < xmin.x )
+ {
+ xmin = graphic->GetStart();
+ xmini = i;
+ }
+
+ if( graphic->GetEnd().x < xmin.x )
+ {
+ xmin = graphic->GetEnd();
+ xmini = i;
+ }
+ }
+ break;
+
+ case S_ARC:
+ // Freerouter does not yet understand arcs, so approximate
+ // an arc with a series of short lines and put those
+ // line segments into the !same! PATH.
+ {
+ wxPoint start = graphic->GetArcStart();
+ wxPoint center = graphic->GetCenter();
+ double angle = -graphic->GetAngle();
+ int steps = STEPS * fabs(angle) /3600.0;
+
+ if( steps == 0 )
+ steps = 1;
+
+ wxPoint pt;
+
+ for( int step = 1; step<=steps; ++step )
+ {
+ double rotation = ( angle * step ) / steps;
+
+ pt = start;
+
+ RotatePoint( &pt.x, &pt.y, center.x, center.y, rotation );
+
+ if( pt.x < xmin.x )
+ {
+ xmin = pt;
+ xmini = i;
+ }
+ }
+ }
+ break;
+
+ case S_CIRCLE:
+ {
+ wxPoint pt = graphic->GetCenter();
+
+ // pt has minimum x point
+ pt.x -= graphic->GetRadius();
+
+ // when the radius <= 0, this is a mal-formed circle. Skip it
+ if( graphic->GetRadius() > 0 && pt.x < xmin.x )
+ {
+ xmin = pt;
+ xmini = i;
+ }
+ }
+ break;
+
+ default:
+ {
+ wxString error = wxString::Format( _( "Unsupported DRAWSEGMENT type %s" ),
+ GetChars( BOARD_ITEM::ShowShape( graphic->GetShape() ) ) );
+
+ ThrowIOError( error );
+ }
+ break;
+ }
+ }
+
+ // Grab the left most point, assume its on the board's perimeter, and see if we
+ // can put enough graphics together by matching endpoints to formulate a cohesive
+ // polygon.
+
+ graphic = (DRAWSEGMENT*) items[xmini];
+
+ // The first DRAWSEGMENT is in 'graphic', ok to remove it from 'items'
+ items.Remove( xmini );
+
+ // Set maximum proximity threshold for point to point nearness metric for
+ // board perimeter only, not interior keepouts yet.
+ prox = Millimeter2iu( 0.01 ); // should be enough to fix rounding issues
+ // is arc start and end point calculations
+
+ // Output the Edge.Cuts perimeter as circle or polygon.
+ if( graphic->GetShape() == S_CIRCLE )
+ {
+ makeCircle( path, graphic );
+ }
+ else
+ {
+ // Polygon start point. Arbitrarily chosen end of the
+ // segment and build the poly from here.
+
+ wxPoint startPt = wxPoint( graphic->GetEnd() );
+ prevPt = graphic->GetEnd();
+ path->AppendPoint( mapPt( prevPt ) );
+
+ // Do not append the other end point yet of this 'graphic', this first
+ // 'graphic' might be an arc.
+
+ for(;;)
+ {
+ switch( graphic->GetShape() )
+ {
+ case S_SEGMENT:
+ {
+ wxPoint nextPt;
+
+ // Use the line segment end point furthest away from
+ // prevPt as we assume the other end to be ON prevPt or
+ // very close to it.
+
+ if( close_st( prevPt, graphic->GetStart(), graphic->GetEnd() ) )
+ {
+ nextPt = graphic->GetEnd();
+ }
+ else
+ {
+ nextPt = graphic->GetStart();
+ }
+
+ path->AppendPoint( mapPt( nextPt ) );
+ prevPt = nextPt;
+ }
+ break;
+
+ case S_ARC:
+ // Freerouter does not yet understand arcs, so approximate
+ // an arc with a series of short lines and put those
+ // line segments into the !same! PATH.
+ {
+ wxPoint start = graphic->GetArcStart();
+ wxPoint end = graphic->GetArcEnd();
+ wxPoint center = graphic->GetCenter();
+ double angle = -graphic->GetAngle();
+ int steps = STEPS * fabs(angle) /3600.0;
+
+ if( steps == 0 )
+ steps = 1;
+
+ if( !close_enough( prevPt, start, prox ) )
+ {
+ wxASSERT( close_enough( prevPt, graphic->GetArcEnd(), prox ) );
+
+ angle = -angle;
+ std::swap( start, end );
+ }
+
+ wxPoint nextPt;
+
+ for( int step = 1; step<=steps; ++step )
+ {
+ double rotation = ( angle * step ) / steps;
+
+ nextPt = start;
+
+ RotatePoint( &nextPt.x, &nextPt.y, center.x, center.y, rotation );
+
+ path->AppendPoint( mapPt( nextPt ) );
+ }
+
+ prevPt = nextPt;
+ }
+ break;
+
+ default:
+ {
+ wxString error = wxString::Format( _( "Unsupported DRAWSEGMENT type %s" ),
+ GetChars( BOARD_ITEM::ShowShape( graphic->GetShape() ) ) );
+
+ ThrowIOError( error );
+ }
+ break;
+ }
+
+ // Get next closest segment.
+
+ graphic = findPoint( prevPt, &items, prox );
+
+ // If there are no more close segments, check if the board
+ // outline polygon can be closed.
+
+ if( !graphic )
+ {
+ if( close_enough( startPt, prevPt, prox ) )
+ {
+ // Close the polygon back to start point
+ path->AppendPoint( mapPt( startPt ) );
+ }
+ else
+ {
+ wxString error = wxString::Format(
+ _( "Unable to find the next boundary segment with an endpoint of (%s mm, %s mm).\n"
+ "Edit Edge.Cuts perimeter graphics, making them contiguous polygons each." ),
+ GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.x ).c_str() ) ),
+ GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.y ).c_str() ) )
+ );
+ ThrowIOError( error );
+ }
+ break;
+ }
+ }
+ }
+
+ // Output the interior Edge.Cuts graphics as keepouts, using same nearness
+ // metric as the board edge as otherwise we have trouble completing complex
+ // polygons.
+ prox = Millimeter2iu( 0.05 );
+
+ while( items.GetCount() )
+ {
+ // emit a signal layers keepout for every interior polygon left...
+ KEEPOUT* keepout = new KEEPOUT( NULL, T_keepout );
+ PATH* poly_ko = new PATH( NULL, T_polygon );
+
+ keepout->SetShape( poly_ko );
+ poly_ko->SetLayerId( "signal" );
+ pcb->structure->keepouts.push_back( keepout );
+ graphic = (DRAWSEGMENT*) items[0];
+ items.Remove( 0 );
+
+ if( graphic->GetShape() == S_CIRCLE )
+ {
+ makeCircle( poly_ko, graphic );
+ }
+ else
+ {
+ // Polygon start point. Arbitrarily chosen end of the
+ // segment and build the poly from here.
+
+ wxPoint startPt( graphic->GetEnd() );
+ prevPt = graphic->GetEnd();
+ poly_ko->AppendPoint( mapPt( prevPt ) );
+
+ // do not append the other end point yet, this first 'graphic' might be an arc
+ for(;;)
+ {
+ switch( graphic->GetShape() )
+ {
+ case S_SEGMENT:
+ {
+ wxPoint nextPt;
+
+ // Use the line segment end point furthest away from
+ // prevPt as we assume the other end to be ON prevPt or
+ // very close to it.
+
+ if( close_st( prevPt, graphic->GetStart(), graphic->GetEnd() ) )
+ {
+ nextPt = graphic->GetEnd();
+ }
+ else
+ {
+ nextPt = graphic->GetStart();
+ }
+
+ prevPt = nextPt;
+ poly_ko->AppendPoint( mapPt( prevPt ) );
+ }
+ break;
+
+ case S_ARC:
+ // Freerouter does not yet understand arcs, so approximate
+ // an arc with a series of short lines and put those
+ // line segments into the !same! PATH.
+ {
+ wxPoint start = graphic->GetArcStart();
+ wxPoint end = graphic->GetArcEnd();
+ wxPoint center = graphic->GetCenter();
+ double angle = -graphic->GetAngle();
+ int steps = STEPS * fabs(angle) /3600.0;
+
+ if( steps == 0 )
+ steps = 1;
+
+ if( !close_enough( prevPt, start, prox ) )
+ {
+ wxASSERT( close_enough( prevPt, graphic->GetArcEnd(), prox ) );
+
+ angle = -angle;
+ std::swap( start, end );
+ }
+
+ wxPoint nextPt;
+
+ for( int step = 1; step<=steps; ++step )
+ {
+ double rotation = ( angle * step ) / steps;
+
+ nextPt = start;
+
+ RotatePoint( &nextPt.x, &nextPt.y, center.x, center.y, rotation );
+
+ poly_ko->AppendPoint( mapPt( nextPt ) );
+ }
+
+ prevPt = nextPt;
+ }
+ break;
+
+ default:
+ {
+ wxString error = wxString::Format(
+ _( "Unsupported DRAWSEGMENT type %s" ),
+ GetChars( BOARD_ITEM::ShowShape( graphic->GetShape() ) ) );
+
+ ThrowIOError( error );
+ }
+ break;
+ }
+
+ // Get next closest segment.
+
+ graphic = findPoint( prevPt, &items, prox );
+
+ // If there are no more close segments, check if polygon
+ // can be closed.
+
+ if( !graphic )
+ {
+ if( close_enough( startPt, prevPt, prox ) )
+ {
+ // Close the polygon back to start point
+ poly_ko->AppendPoint( mapPt( startPt ) );
+ }
+ else
+ {
+ wxString error = wxString::Format(
+ _( "Unable to find the next keepout segment with an endpoint of (%s mm, %s mm).\n"
+ "Edit Edge.Cuts interior graphics, making them contiguous polygons each." ),
+ GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.x ).c_str() ) ),
+ GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.y ).c_str() ) )
+ );
+
+ ThrowIOError( error );
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // User has not defined a board perimeter yet...
+
+ EDA_RECT bbbox = aBoard->ComputeBoundingBox();
+ RECTANGLE* rect = new RECTANGLE( boundary );
+
+ boundary->rectangle = rect;
+
+ rect->layer_id = "pcb";
+
+ // opposite corners
+ wxPoint bottomRight( bbbox.GetRight(), bbbox.GetBottom() );
+
+ rect->SetCorners( mapPt( bbbox.GetOrigin() ),
+ mapPt( bottomRight ) );
+ }
+}
+
+/* This function is not used in SPECCTRA export,
+ * but uses a lot of functions from it
+ * and is used to extract a board outlines (3D view, automatic zones build ...)
+ * makes the board perimeter for the DSN file by filling the BOUNDARY element.
+ * Any closed outline inside the main outline is a hole
+ * All contours should be closed, i.e. valid closed polygon vertices
+ */
+bool SPECCTRA_DB::GetBoardPolygonOutlines( BOARD* aBoard,
+ SHAPE_POLY_SET& aOutlines,
+ SHAPE_POLY_SET& aHoles,
+ wxString* aErrorText )
+{
+ bool success = true;
+ double specctra2UIfactor = IU_PER_MM / 1000.0; // Specctra unite = micron
+
+ if( ! pcb )
+ {
+ pcb = new PCB();
+ pcb->structure = new STRUCTURE( pcb );
+ }
+
+ CPolyPt corner;
+ BOUNDARY* boundary = new BOUNDARY( 0 );
+ pcb->structure->SetBOUNDARY( boundary );
+
+ aOutlines.NewOutline();
+
+ try
+ {
+ fillBOUNDARY( aBoard, boundary );
+ std::vector<double> buffer;
+ boundary->GetCorners( buffer );
+
+ for( unsigned ii = 0; ii < buffer.size(); ii+=2 )
+ {
+ corner.x = buffer[ii] * specctra2UIfactor;
+ corner.y = - buffer[ii+1] * specctra2UIfactor;
+ aOutlines.Append( corner.x, corner.y );
+ }
+
+ // Export holes, stored as keepouts polygonal shapes.
+ // by fillBOUNDARY()
+ KEEPOUTS& holes = pcb->structure->keepouts;
+
+ for( KEEPOUTS::iterator i=holes.begin(); i!=holes.end(); ++i )
+ {
+ KEEPOUT& keepout = *i;
+ PATH* poly_hole = (PATH*)keepout.shape;
+ POINTS& plist = poly_hole->GetPoints();
+
+ aHoles.NewOutline();
+
+ for( unsigned ii = 0; ii < plist.size(); ii++ )
+ {
+ corner.x = plist[ii].x * specctra2UIfactor;
+ corner.y = - plist[ii].y * specctra2UIfactor;
+ aHoles.Append( corner.x, corner.y );
+ }
+ }
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ // Creates a valid polygon outline is not possible.
+ // So uses the board edge cuts bounding box to create a
+ // rectangular outline
+ // (when no edge cuts items, fillBOUNDARY build a contour
+ // from global bounding box
+ success = false;
+ if( aErrorText )
+ *aErrorText = ioe.errorText;
+
+ EDA_RECT bbbox = aBoard->ComputeBoundingBox( true );
+
+ // Ensure non null area. If happen, gives a minimal size.
+ if( ( bbbox.GetWidth() ) == 0 || ( bbbox.GetHeight() == 0 ) )
+ bbbox.Inflate( Millimeter2iu( 1.0 ) );
+
+ aOutlines.RemoveAllContours();
+ aOutlines.NewOutline();
+
+ corner.x = bbbox.GetOrigin().x;
+ corner.y = bbbox.GetOrigin().y;
+ aOutlines.Append( corner.x, corner.y );
+
+ corner.x = bbbox.GetOrigin().x;
+ corner.y = bbbox.GetEnd().y;
+ aOutlines.Append( corner.x, corner.y );
+
+ corner.x = bbbox.GetEnd().x;
+ corner.y = bbbox.GetEnd().y;
+ aOutlines.Append( corner.x, corner.y );
+
+ corner.x = bbbox.GetEnd().x;
+ corner.y = bbbox.GetOrigin().y;
+ aOutlines.Append( corner.x, corner.y );
+ }
+
+ return success;
+}
+
+
+typedef std::set<std::string> STRINGSET;
+typedef std::pair<STRINGSET::iterator, bool> STRINGSET_PAIR;
+
+
+void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
+ throw( IO_ERROR, boost::bad_ptr_container_operation )
+{
+ PCB_TYPE_COLLECTOR items;
+
+ static const KICAD_T scanMODULEs[] = { PCB_MODULE_T, EOT };
+
+ // Not all boards are exportable. Check that all reference Ids are unique.
+ // Unless they are unique, we cannot import the session file which comes
+ // back to us later from the router.
+ {
+ items.Collect( aBoard, scanMODULEs );
+
+ STRINGSET refs; // holds module reference designators
+
+ for( int i=0; i<items.GetCount(); ++i )
+ {
+ MODULE* module = (MODULE*) items[i];
+
+ if( module->GetReference() == wxEmptyString )
+ {
+ ThrowIOError( _( "Component with value of '%s' has empty reference id." ),
+ GetChars( module->GetValue() ) );
+ }
+
+ // if we cannot insert OK, that means the reference has been seen before.
+ STRINGSET_PAIR refpair = refs.insert( TO_UTF8( module->GetReference() ) );
+ if( !refpair.second ) // insert failed
+ {
+ ThrowIOError( _( "Multiple components have identical reference IDs of '%s'." ),
+ GetChars( module->GetReference() ) );
+ }
+ }
+ }
+
+ if( !pcb )
+ pcb = SPECCTRA_DB::MakePCB();
+
+ //-----<layer_descriptor>-----------------------------------------------
+ {
+ // specctra wants top physical layer first, then going down to the
+ // bottom most physical layer in physical sequence.
+ // @question : why does KiCad not display layers in that order?
+
+ buildLayerMaps( aBoard );
+
+ int layerCount = aBoard->GetCopperLayerCount();
+
+ for( int pcbNdx=0; pcbNdx<layerCount; ++pcbNdx )
+ {
+ LAYER* layer = new LAYER( pcb->structure );
+
+ pcb->structure->layers.push_back( layer );
+
+ layer->name = layerIds[pcbNdx];
+
+ DSN_T layerType;
+
+ switch( aBoard->GetLayerType( pcbLayer2kicad[pcbNdx] ) )
+ {
+ default:
+ case LT_SIGNAL: layerType = T_signal; break;
+ case LT_POWER: layerType = T_power; break;
+
+#if 1 // Freerouter does not support type "mixed", only signal and power.
+ // Remap "mixed" to "signal".
+ case LT_MIXED: layerType = T_signal; break;
+#else
+ case LT_MIXED: layerType = T_mixed; break;
+#endif
+ case LT_JUMPER: layerType = T_jumper; break;
+ }
+
+ layer->layer_type = layerType;
+
+ layer->properties.push_back( PROPERTY() );
+ PROPERTY* property = &layer->properties.back();
+ property->name = "index";
+ char temp[32];
+ sprintf( temp, "%d", pcbNdx );
+ property->value = temp;
+ }
+ }
+
+ // a space in a quoted token is NOT a terminator, true establishes this.
+ pcb->parser->space_in_quoted_tokens = true;
+
+ //-----<unit_descriptor> & <resolution_descriptor>--------------------
+ {
+ // tell freerouter to use "tenths of micrometers",
+ // which is 100 nm resolution. Possibly more resolution is possible
+ // in freerouter, but it would need testing.
+
+ pcb->unit->units = T_um;
+ pcb->resolution->units = T_um;
+ pcb->resolution->value = 10; // tenths of a um
+ // pcb->resolution->value = 1000; // "thousandths of a um" (i.e. "nm")
+ }
+
+ //-----<boundary_descriptor>------------------------------------------
+ {
+ // Because fillBOUNDARY() can throw an exception, we link in an
+ // empty boundary so the BOUNDARY does not get lost in the event of
+ // of an exception.
+ BOUNDARY* boundary = new BOUNDARY( 0 );
+
+ pcb->structure->SetBOUNDARY( boundary );
+ fillBOUNDARY( aBoard, boundary );
+ }
+
+
+ //-----<rules>--------------------------------------------------------
+ {
+ char rule[80];
+ NETCLASSPTR defaultClass = aBoard->GetDesignSettings().GetDefault();
+
+ int defaultTrackWidth = defaultClass->GetTrackWidth();
+ int defaultClearance = defaultClass->GetClearance();
+
+ double clearance = scale( defaultClearance );
+
+ STRINGS& rules = pcb->structure->rules->rules;
+
+ sprintf( rule, "(width %.6g)", scale( defaultTrackWidth ) );
+ rules.push_back( rule );
+
+ sprintf( rule, "(clearance %.6g)", clearance + safetyMargin );
+ rules.push_back( rule );
+
+ // On a high density board (a board with 4 mil tracks, 4 mil spacing)
+ // a typical solder mask clearance will be 2-3 mils.
+ // This exposes 2 to 3 mils of bare board around each pad, and would
+ // leave only 1 to 2 mils of solder mask between the solder mask's boundary
+ // to the edge of any trace within "clearance" of the pad. So we need at least
+ // 2 mils *extra* clearance for traces which would come near a pad on
+ // a different net. So if the baseline trace to trace clearance was say 4 mils, then
+ // the SMD to trace clearance should be at least 6 mils.
+ double default_smd = clearance + safetyMargin;
+
+ if( default_smd <= 6.0 )
+ default_smd = 6.0;
+
+ sprintf( rule, "(clearance %.6g (type default_smd))", default_smd );
+
+ rules.push_back( rule );
+
+ /* see: http://www.freerouting.net/usren/viewtopic.php?f=5&t=339#p474
+ sprintf( rule, "(clearance %.6g (type pad_to_turn_gap))", clearance + safetyMargin );
+ rules.push_back( rule );
+
+ sprintf( rule, "(clearance %.6g (type smd_to_turn_gap))", clearance + safetyMargin );
+ rules.push_back( rule );
+
+ sprintf( rule, "(clearance %.6g (type via_via))", clearance + safetyMargin );
+ rules.push_back( rule );
+
+ sprintf( rule, "(clearance %.6g (type via_smd))", clearance + safetyMargin );
+ rules.push_back( rule );
+
+ sprintf( rule, "(clearance %.6g (type via_pin))", clearance + safetyMargin );
+ rules.push_back( rule );
+
+ sprintf( rule, "(clearance %.6g (type pin_pin))", clearance + safetyMargin );
+ rules.push_back( rule );
+
+ sprintf( rule, "(clearance %.6g (type smd_pin))", clearance + safetyMargin );
+ rules.push_back( rule );
+ */
+
+ // Pad to pad spacing on a single SMT part can be closer than our
+ // clearance, we don't want freerouter complaining about that, so
+ // output a significantly smaller pad to pad clearance to freerouter.
+ clearance = scale( defaultClearance ) / 4;
+
+ sprintf( rule, "(clearance %.6g (type smd_smd))", clearance );
+ rules.push_back( rule );
+ }
+
+
+ //-----<zone containers (not keepout areas) become planes>--------------------------------
+ // Note: only zones are output here, keepout areas be be created later
+ {
+ int netlessZones = 0;
+
+ static const KICAD_T scanZONEs[] = { PCB_ZONE_AREA_T, EOT };
+ items.Collect( aBoard, scanZONEs );
+
+ for( int i = 0; i<items.GetCount(); ++i )
+ {
+ ZONE_CONTAINER* item = (ZONE_CONTAINER*) items[i];
+
+ if( item->GetIsKeepout() )
+ continue;
+
+ // Currently, we export only copper layers
+ if( ! IsCopperLayer( item->GetLayer() ) )
+ continue;
+
+ COPPER_PLANE* plane = new COPPER_PLANE( pcb->structure );
+
+ pcb->structure->planes.push_back( plane );
+
+ PATH* mainPolygon = new PATH( plane, T_polygon );
+
+ plane->SetShape( mainPolygon );
+
+ plane->name = TO_UTF8( item->GetNetname() );
+
+ if( plane->name.size() == 0 )
+ {
+ char name[32];
+
+ // This is one of those no connection zones, netcode=0, and it has no name.
+ // Create a unique, bogus netname.
+ NET* no_net = new NET( pcb->network );
+
+ sprintf( name, "@:no_net_%d", netlessZones++ );
+ no_net->net_id = name;
+
+ // add the bogus net name to network->nets.
+ pcb->network->nets.push_back( no_net );
+
+ // use the bogus net name in the netless zone.
+ plane->name = no_net->net_id;
+ }
+
+ mainPolygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ];
+
+ int count = item->Outline()->m_CornersList.GetCornersCount();
+ int ndx = 0; // used in 2 for() loops below
+ for( ; ndx<count; ++ndx )
+ {
+ wxPoint point( item->Outline()->m_CornersList[ndx].x,
+ item->Outline()->m_CornersList[ndx].y );
+ mainPolygon->AppendPoint( mapPt(point) );
+
+ // this was the end of the main polygon
+ if( item->Outline()->m_CornersList[ndx].end_contour )
+ break;
+ }
+
+ WINDOW* window = 0;
+ PATH* cutout = 0;
+
+ // handle the cutouts
+ for( ++ndx; ndx<count; ++ndx )
+ {
+ if( item->Outline()->m_CornersList[ndx-1].end_contour )
+ {
+ window = new WINDOW( plane );
+
+ plane->AddWindow( window );
+
+ cutout = new PATH( window, T_polygon );
+
+ window->SetShape( cutout );
+
+ cutout->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ];
+ }
+
+ wxASSERT( window );
+ wxASSERT( cutout );
+
+ wxPoint point(item->Outline()->m_CornersList[ndx].x,
+ item->Outline()->m_CornersList[ndx].y );
+ cutout->AppendPoint( mapPt(point) );
+ }
+ }
+ }
+
+ //-----<zone containers flagged keepout areas become keepout>--------------------------------
+ {
+ static const KICAD_T scanZONEs[] = { PCB_ZONE_AREA_T, EOT };
+ items.Collect( aBoard, scanZONEs );
+
+ for( int i=0; i<items.GetCount(); ++i )
+ {
+ ZONE_CONTAINER* item = (ZONE_CONTAINER*) items[i];
+
+ if( ! item->GetIsKeepout() )
+ continue;
+
+ // keepout areas have a type. types are
+ // T_place_keepout, T_via_keepout, T_wire_keepout,
+ // T_bend_keepout, T_elongate_keepout, T_keepout.
+ // Pcbnew knows only T_keepout, T_via_keepout and T_wire_keepout
+ DSN_T keepout_type;
+
+ if( item->GetDoNotAllowVias() && item->GetDoNotAllowTracks() )
+ keepout_type = T_keepout;
+ else if( item->GetDoNotAllowVias() )
+ keepout_type = T_via_keepout;
+ else if( item->GetDoNotAllowTracks() )
+ keepout_type = T_wire_keepout;
+ else
+ keepout_type = T_keepout;
+
+ KEEPOUT* keepout = new KEEPOUT( pcb->structure, keepout_type );
+ pcb->structure->keepouts.push_back( keepout );
+
+ PATH* mainPolygon = new PATH( keepout, T_polygon );
+ keepout->SetShape( mainPolygon );
+
+ mainPolygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ];
+
+ int count = item->Outline()->m_CornersList.GetCornersCount();
+ int ndx = 0; // used in 2 for() loops below
+ for( ; ndx<count; ++ndx )
+ {
+ wxPoint point( item->Outline()->m_CornersList[ndx].x,
+ item->Outline()->m_CornersList[ndx].y );
+ mainPolygon->AppendPoint( mapPt(point) );
+
+ // this was the end of the main polygon
+ if( item->Outline()->m_CornersList[ndx].end_contour )
+ break;
+ }
+
+ WINDOW* window = 0;
+ PATH* cutout = 0;
+
+ // handle the cutouts
+ for( ++ndx; ndx<count; ++ndx )
+ {
+ if( item->Outline()->m_CornersList[ndx-1].end_contour )
+ {
+ window = new WINDOW( keepout );
+ keepout->AddWindow( window );
+
+ cutout = new PATH( window, T_polygon );
+ window->SetShape( cutout );
+
+ cutout->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ];
+ }
+
+ wxASSERT( window );
+ wxASSERT( cutout );
+
+ wxPoint point(item->Outline()->m_CornersList[ndx].x,
+ item->Outline()->m_CornersList[ndx].y );
+ cutout->AppendPoint( mapPt(point) );
+ }
+ }
+ }
+
+ //-----<build the images, components, and netlist>-----------------------
+ {
+ PIN_REF empty( pcb->network );
+
+ std::string componentId;
+
+ // find the highest numbered netCode within the board.
+ int highestNetCode = aBoard->GetNetCount() - 1;
+
+ deleteNETs();
+
+ // expand the net vector to highestNetCode+1, setting empty to NULL
+ nets.resize( highestNetCode + 1, NULL );
+
+ // skip netcode = 0
+ for( unsigned i = 1; i<nets.size(); ++i )
+ nets[i] = new NET( pcb->network );
+
+ for( unsigned ii = 0; ii < aBoard->GetNetCount(); ii++ )
+ {
+ NETINFO_ITEM* net = aBoard->FindNet( ii );
+ int netcode = net->GetNet();
+
+ if( netcode > 0 )
+ nets[ netcode ]->net_id = TO_UTF8( net->GetNetname() );
+ }
+
+ items.Collect( aBoard, scanMODULEs );
+
+ padstackset.clear();
+
+ for( int m = 0; m<items.GetCount(); ++m )
+ {
+ MODULE* module = (MODULE*) items[m];
+
+ IMAGE* image = makeIMAGE( aBoard, module );
+
+ componentId = TO_UTF8( module->GetReference() );
+
+ // create a net list entry for all the actual pins in the image
+ // for the current module. location of this code is critical
+ // because we fabricated some pin names to ensure unique-ness
+ // of pin names within a module, do not move this code because
+ // the life of this 'IMAGE* image' is not necessarily long. The
+ // exported netlist will have some fabricated pin names in it.
+ // If you don't like fabricated pin names, then make sure all pads
+ // within your MODULEs are uniquely named!
+ for( unsigned p = 0; p<image->pins.size(); ++p )
+ {
+ PIN* pin = &image->pins[p];
+
+ int netcode = pin->kiNetCode;
+
+ if( netcode > 0 )
+ {
+ NET* net = nets[netcode];
+
+ net->pins.push_back( empty );
+
+ PIN_REF& pin_ref = net->pins.back();
+
+ pin_ref.component_id = componentId;
+ pin_ref.pin_id = pin->pin_id;
+ }
+ }
+
+
+ IMAGE* registered = pcb->library->LookupIMAGE( image );
+
+ if( registered != image )
+ {
+ // If our new 'image' is not a unique IMAGE, delete it.
+ // and use the registered one, known as 'image' after this.
+ delete image;
+ image = registered;
+ }
+
+ COMPONENT* comp = pcb->placement->LookupCOMPONENT( image->GetImageId() );
+
+ PLACE* place = new PLACE( comp );
+
+ comp->places.push_back( place );
+
+ place->SetRotation( module->GetOrientation()/10.0 );
+ place->SetVertex( mapPt( module->GetPosition() ) );
+ place->component_id = componentId;
+ place->part_number = TO_UTF8( module->GetValue() );
+
+ // module is flipped from bottom side, set side to T_back
+ if( module->GetFlag() )
+ {
+ int angle = 1800 - module->GetOrientation();
+ NORMALIZE_ANGLE_POS( angle );
+ place->SetRotation( angle / 10.0 );
+
+ place->side = T_back;
+ }
+ }
+
+ // copy the SPECCTRA_DB::padstackset to the LIBRARY. Since we are
+ // removing, do not increment the iterator
+ for( PADSTACKSET::iterator i = padstackset.begin(); i!=padstackset.end();
+ i = padstackset.begin() )
+ {
+ PADSTACKSET::auto_type ps = padstackset.release( i );
+ PADSTACK* padstack = ps.release();
+
+ pcb->library->AddPadstack( padstack );
+ }
+
+ // copy our SPECCTRA_DB::nets to the pcb->network
+ for( unsigned n = 1; n<nets.size(); ++n )
+ {
+ NET* net = nets[n];
+
+ if( net->pins.size() )
+ {
+ // give ownership to pcb->network
+ pcb->network->nets.push_back( net );
+ nets[n] = 0;
+ }
+ }
+ }
+
+
+ //-----< output vias used in netclasses >-----------------------------------
+ {
+ NETCLASSES& nclasses = aBoard->GetDesignSettings().m_NetClasses;
+
+ // Assume the netclass vias are all the same kind of thru, blind, or buried vias.
+ // This is in lieu of either having each netclass via have its own layer pair in
+ // the netclass dialog, or such control in the specctra export dialog.
+
+
+ // if( aBoard->GetDesignSettings().m_CurrentViaType == VIA_THROUGH )
+ {
+ m_top_via_layer = 0; // first specctra cu layer is number zero.
+ m_bot_via_layer = aBoard->GetCopperLayerCount()-1;
+ }
+ /*
+ else
+ {
+ // again, should be in the BOARD:
+ topLayer = kicadLayer2pcb[ GetScreen()->m_Route_Layer_TOP ];
+ botLayer = kicadLayer2pcb[ GetScreen()->m_Route_Layer_BOTTOM ];
+ }
+ */
+
+ // Add the via from the Default netclass first. The via container
+ // in pcb->library preserves the sequence of addition.
+
+ NETCLASSPTR netclass = nclasses.GetDefault();
+
+ PADSTACK* via = makeVia( netclass->GetViaDiameter(), netclass->GetViaDrill(),
+ m_top_via_layer, m_bot_via_layer );
+
+ // we AppendVia() this first one, there is no way it can be a duplicate,
+ // the pcb->library via container is empty at this point. After this,
+ // we'll have to use LookupVia().
+ wxASSERT( pcb->library->vias.size() == 0 );
+ pcb->library->AppendVia( via );
+
+#if 0
+ // I've seen no way to make stock vias useable by freerouter. Also the
+ // zero based diameter was leading to duplicates in the LookupVia() function.
+ // User should use netclass based vias when going to freerouter.
+
+ // Output the stock vias, but preserve uniqueness in the via container by
+ // using LookupVia().
+ for( unsigned i = 0; i < aBoard->m_ViasDimensionsList.size(); ++i )
+ {
+ int viaSize = aBoard->m_ViasDimensionsList[i].m_Diameter;
+ int viaDrill = aBoard->m_ViasDimensionsList[i].m_Drill;
+
+ via = makeVia( viaSize, viaDrill,
+ m_top_via_layer, m_bot_via_layer );
+
+ // maybe add 'via' to the library, but only if unique.
+ PADSTACK* registered = pcb->library->LookupVia( via );
+
+ if( registered != via )
+ delete via;
+ }
+#endif
+
+ // set the "spare via" index at the start of the
+ // pcb->library->spareViaIndex = pcb->library->vias.size();
+
+ // output the non-Default netclass vias
+ for( NETCLASSES::iterator nc = nclasses.begin(); nc != nclasses.end(); ++nc )
+ {
+ netclass = nc->second;
+
+ via = makeVia( netclass->GetViaDiameter(), netclass->GetViaDrill(),
+ m_top_via_layer, m_bot_via_layer );
+
+ // maybe add 'via' to the library, but only if unique.
+ PADSTACK* registered = pcb->library->LookupVia( via );
+
+ if( registered != via )
+ delete via;
+ }
+ }
+
+
+#if 1 // do existing wires and vias
+
+ //-----<create the wires from tracks>-----------------------------------
+ {
+ // export all of them for now, later we'll decide what controls we need
+ // on this.
+ static const KICAD_T scanTRACKs[] = { PCB_TRACE_T, EOT };
+
+ items.Collect( aBoard, scanTRACKs );
+
+ std::string netname;
+ WIRING* wiring = pcb->wiring;
+ PATH* path = 0;
+
+ int old_netcode = -1;
+ int old_width = -1;
+ LAYER_NUM old_layer = UNDEFINED_LAYER;
+
+ for( int i=0; i<items.GetCount(); ++i )
+ {
+ TRACK* track = (TRACK*) items[i];
+
+ int netcode = track->GetNetCode();
+
+ if( netcode == 0 )
+ continue;
+
+ if( old_netcode != netcode ||
+ old_width != track->GetWidth() ||
+ old_layer != track->GetLayer() ||
+ (path && path->points.back() != mapPt(track->GetStart()) )
+ )
+ {
+ old_width = track->GetWidth();
+ old_layer = track->GetLayer();
+
+ if( old_netcode != netcode )
+ {
+ old_netcode = netcode;
+ NETINFO_ITEM* net = aBoard->FindNet( netcode );
+ wxASSERT( net );
+ netname = TO_UTF8( net->GetNetname() );
+ }
+
+ WIRE* wire = new WIRE( wiring );
+
+ wiring->wires.push_back( wire );
+ wire->net_id = netname;
+
+ wire->wire_type = T_protect; // @todo, this should be configurable
+
+ LAYER_NUM kiLayer = track->GetLayer();
+ int pcbLayer = kicadLayer2pcb[kiLayer];
+
+ path = new PATH( wire );
+
+ wire->SetShape( path );
+
+ path->layer_id = layerIds[pcbLayer];
+ path->aperture_width = scale( old_width );
+
+ path->AppendPoint( mapPt( track->GetStart() ) );
+ }
+
+ if( path ) // Should not occur
+ path->AppendPoint( mapPt( track->GetEnd() ) );
+ }
+ }
+
+
+ //-----<export the existing real BOARD instantiated vias>-----------------
+ {
+ // Export all vias, once per unique size and drill diameter combo.
+ static const KICAD_T scanVIAs[] = { PCB_VIA_T, EOT };
+
+ items.Collect( aBoard, scanVIAs );
+
+ for( int i = 0; i<items.GetCount(); ++i )
+ {
+ ::VIA* via = (::VIA*) items[i];
+ wxASSERT( via->Type() == PCB_VIA_T );
+
+ int netcode = via->GetNetCode();
+
+ if( netcode == 0 )
+ continue;
+
+ PADSTACK* padstack = makeVia( via );
+ PADSTACK* registered = pcb->library->LookupVia( padstack );
+
+ // if the one looked up is not our padstack, then delete our padstack
+ // since it was a duplicate of one already registered.
+ if( padstack != registered )
+ {
+ delete padstack;
+ }
+
+ WIRE_VIA* dsnVia = new WIRE_VIA( pcb->wiring );
+
+ pcb->wiring->wire_vias.push_back( dsnVia );
+
+ dsnVia->padstack_id = registered->padstack_id;
+ dsnVia->vertexes.push_back( mapPt( via->GetPosition() ) );
+
+ NETINFO_ITEM* net = aBoard->FindNet( netcode );
+ wxASSERT( net );
+
+ dsnVia->net_id = TO_UTF8( net->GetNetname() );
+
+ dsnVia->via_type = T_protect; // @todo, this should be configurable
+ }
+ }
+
+#endif // do existing wires and vias
+
+ //-----<via_descriptor>-------------------------------------------------
+ {
+ // The pcb->library will output <padstack_descriptors> which is a combined
+ // list of part padstacks and via padstacks. specctra dsn uses the
+ // <via_descriptors> to say which of those padstacks are vias.
+
+ // Output the vias in the padstack list here, by name only. This must
+ // be done after exporting existing vias as WIRE_VIAs.
+ VIA* vias = pcb->structure->via;
+
+ for( unsigned viaNdx = 0; viaNdx < pcb->library->vias.size(); ++viaNdx )
+ {
+ vias->AppendVia( pcb->library->vias[viaNdx].padstack_id.c_str() );
+ }
+ }
+
+
+ //-----<output NETCLASSs>----------------------------------------------------
+ NETCLASSES& nclasses = aBoard->GetDesignSettings().m_NetClasses;
+
+ exportNETCLASS( nclasses.GetDefault(), aBoard );
+
+ for( NETCLASSES::iterator nc = nclasses.begin(); nc != nclasses.end(); ++nc )
+ {
+ NETCLASSPTR netclass = nc->second;
+ exportNETCLASS( netclass, aBoard );
+ }
+}
+
+
+void SPECCTRA_DB::exportNETCLASS( NETCLASSPTR aNetClass, BOARD* aBoard )
+{
+ /* From page 11 of specctra spec:
+ *
+ * Routing and Placement Rule Hierarchies
+ *
+ * Routing and placement rules can be defined at multiple levels of design
+ * specification. When a routing or placement rule is defined for an object at
+ * multiple levels, a predefined routing or placement precedence order
+ * automatically determines which rule to apply to the object. The routing rule
+ * precedence order is
+ *
+ * pcb < layer < class < class layer < group_set < group_set layer < net <
+ * net layer < group < group layer < fromto < fromto layer < class_class <
+ * class_class layer < padstack < region < class region < net region <
+ * class_class region
+ *
+ * A pcb rule (global rule for the PCB design) has the lowest precedence in the
+ * hierarchy. A class-to-class region rule has the highest precedence. Rules
+ * set at one level of the hierarchy override conflicting rules set at lower
+ * levels. The placement rule precedence order is
+ *
+ * pcb < image_set < image < component < super cluster < room <
+ * room_image_set < family_family < image_image
+ *
+ * A pcb rule (global rule for the PCB design) has the lowest precedence in the
+ * hierarchy. An image-to-image rule has the highest precedence. Rules set at
+ * one level of the hierarchy override conflicting rules set at lower levels.
+ */
+
+ char text[256];
+
+ CLASS* clazz = new CLASS( pcb->network );
+
+ pcb->network->classes.push_back( clazz );
+
+ // freerouter creates a class named 'default' anyway, and if we
+ // try and use that, we end up with two 'default' via rules so use
+ // something else as the name of our default class.
+ clazz->class_id = TO_UTF8( aNetClass->GetName() );
+
+ for( NETCLASS::iterator net = aNetClass->begin(); net != aNetClass->end(); ++net )
+ clazz->net_ids.push_back( TO_UTF8( *net ) );
+
+ clazz->rules = new RULE( clazz, T_rule );
+
+ // output the track width.
+ int trackWidth = aNetClass->GetTrackWidth();
+ sprintf( text, "(width %.6g)", scale( trackWidth ) );
+ clazz->rules->rules.push_back( text );
+
+ // output the clearance.
+ int clearance = aNetClass->GetClearance();
+ sprintf( text, "(clearance %.6g)", scale( clearance ) + safetyMargin );
+ clazz->rules->rules.push_back( text );
+
+ if( aNetClass->GetName() == NETCLASS::Default )
+ {
+ clazz->class_id = "kicad_default";
+ }
+
+ // the easiest way to get the via name is to create a via (which generates
+ // the name internal to the PADSTACK), and then grab the name and then
+ // delete the via. There are not that many netclasses so
+ // this should never become a performance issue.
+
+ PADSTACK* via = makeVia( aNetClass->GetViaDiameter(), aNetClass->GetViaDrill(),
+ m_top_via_layer, m_bot_via_layer );
+
+ snprintf( text, sizeof(text), "(use_via %s)", via->GetPadstackId().c_str() );
+ clazz->circuit.push_back( text );
+
+ delete via;
+}
+
+
+void SPECCTRA_DB::FlipMODULEs( BOARD* aBoard )
+{
+ for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
+ {
+ module->SetFlag( 0 );
+ if( module->GetLayer() == B_Cu )
+ {
+ module->Flip( module->GetPosition() );
+ module->SetFlag( 1 );
+ }
+ }
+
+ modulesAreFlipped = true;
+}
+
+
+void SPECCTRA_DB::RevertMODULEs( BOARD* aBoard )
+{
+ if( !modulesAreFlipped )
+ return;
+
+ // DSN Images (=KiCad MODULES and pads) must be presented from the
+ // top view. Restore those that were flipped.
+ for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
+ {
+ if( module->GetFlag() )
+ {
+ module->Flip( module->GetPosition() );
+ module->SetFlag( 0 );
+ }
+ }
+
+ modulesAreFlipped = false;
+}
+
+} // namespace DSN
+
diff --git a/pcbnew/specctra_import.cpp b/pcbnew/specctra_import.cpp
new file mode 100644
index 0000000..b8e2d86
--- /dev/null
+++ b/pcbnew/specctra_import.cpp
@@ -0,0 +1,564 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* This source is a complement to specctra.cpp and implements the import of
+ a specctra session file (*.ses), and import of a specctra design file
+ (*.dsn) file. The specification for the grammar of the specctra dsn file
+ used to develop this code is given here:
+ http://tech.groups.yahoo.com/group/kicad-users/files/ then file "specctra.pdf"
+ Also see the comments at the top of the specctra.cpp file itself.
+*/
+
+
+#include <class_drawpanel.h> // m_canvas
+#include <confirm.h> // DisplayError()
+#include <gestfich.h> // EDA_FileSelector()
+#include <wxPcbStruct.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+#include <class_track.h>
+#include <class_zone.h>
+#include <class_drawsegment.h>
+
+#include <specctra.h>
+
+
+using namespace DSN;
+
+void PCB_EDIT_FRAME::ImportSpecctraDesign( wxCommandEvent& event )
+{
+ /* @todo write this someday
+
+ if( !Clear_Pcb( true ) )
+ return;
+ */
+}
+
+
+void PCB_EDIT_FRAME::ImportSpecctraSession( wxCommandEvent& event )
+{
+/*
+ if( GetScreen()->IsModify() )
+ {
+ if( !IsOK( this, _( "Board Modified: Continue ?" ) ) )
+ return;
+ }
+*/
+
+ wxString fullFileName = GetBoard()->GetFileName();
+ wxString path;
+ wxString name;
+ wxString ext;
+
+ wxString sessionExt( wxT( ".ses" ) );
+ wxString mask = wxT( "*" ) + sessionExt;
+
+ wxFileName::SplitPath( fullFileName, &path, &name, &ext );
+ name += sessionExt;
+
+ fullFileName = EDA_FILE_SELECTOR( _( "Merge Specctra Session file:" ),
+ path,
+ name,
+ sessionExt,
+ mask,
+ this,
+ wxFD_OPEN,
+ false );
+
+ if( fullFileName == wxEmptyString )
+ return;
+
+ SPECCTRA_DB db;
+ LOCALE_IO toggle;
+
+ try
+ {
+ db.LoadSESSION( fullFileName );
+ db.FromSESSION( GetBoard() );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = ioe.errorText;
+ msg += '\n';
+ msg += _("BOARD may be corrupted, do not save it.");
+ msg += '\n';
+ msg += _("Fix problem and try again.");
+
+ DisplayError( this, msg );
+ return;
+ }
+
+ OnModify();
+ GetBoard()->m_Status_Pcb = 0;
+
+ /* At this point we should call Compile_Ratsnest()
+ * but this could be time consumming.
+ * So if incorrect number of Connected and No connected pads is accepted
+ * until Compile_Ratsnest() is called (when track tool selected for instance)
+ * leave the next line commented
+ * Otherwise uncomment this line
+ */
+ //Compile_Ratsnest( NULL, true );
+
+ SetStatusText( wxString( _( "Session file imported and merged OK." ) ) );
+
+ m_canvas->Refresh( true );
+}
+
+
+namespace DSN {
+
+
+/**
+ * Function scale
+ * converts a session file distance to KiCad units of deci-mils.
+ * @param distance The session file length to convert.
+ * @param aResolution The session UNIT_RES which holds the engineering unit
+ * specifier
+ * @return int - The KiCad length in deci-mils
+ */
+static int scale( double distance, UNIT_RES* aResolution )
+{
+ double resValue = aResolution->GetValue();
+ double factor;
+
+ switch( aResolution->GetEngUnits() )
+ {
+ default:
+ case T_inch:
+ factor = 25.4e6; // nanometers per inch
+ break;
+ case T_mil:
+ factor = 25.4e3; // nanometers per mil
+ break;
+ case T_cm:
+ factor = 1e7; // nanometers per cm
+ break;
+ case T_mm:
+ factor = 1e6; // nanometers per mm
+ break;
+ case T_um:
+ factor = 1e3; // nanometers per um
+ break;
+ }
+
+ int ret = KiROUND( factor * distance / resValue );
+
+ return ret;
+}
+
+
+/**
+ * Function mapPt
+ * translates a point from the Specctra Session format coordinate system
+ * to the KiCad coordinate system.
+ * @param aPoint The session point to translate
+ * @param aResolution - The amount to scale the point.
+ * @return wxPoint - The KiCad coordinate system point.
+ */
+static wxPoint mapPt( const POINT& aPoint, UNIT_RES* aResolution )
+{
+ wxPoint ret( scale( aPoint.x, aResolution ),
+ -scale( aPoint.y, aResolution ) ); // negate y
+
+ return ret;
+}
+
+
+TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) throw( IO_ERROR )
+{
+ int layerNdx = findLayerName( aPath->layer_id );
+
+ if( layerNdx == -1 )
+ {
+ wxString layerName = FROM_UTF8( aPath->layer_id.c_str() );
+ ThrowIOError( _("Session file uses invalid layer id \"%s\""),
+ GetChars( layerName ) );
+ }
+
+ TRACK* track = new TRACK( sessionBoard );
+
+ track->SetStart( mapPt( aPath->points[aPointIndex+0], routeResolution ) );
+ track->SetEnd( mapPt( aPath->points[aPointIndex+1], routeResolution ) );
+ track->SetLayer( pcbLayer2kicad[layerNdx] );
+ track->SetWidth( scale( aPath->aperture_width, routeResolution ) );
+ track->SetNetCode( aNetcode );
+
+ return track;
+}
+
+
+::VIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint,
+ int aNetCode, int aViaDrillDefault )
+ throw( IO_ERROR )
+{
+ ::VIA* via = 0;
+ SHAPE* shape;
+
+ int shapeCount = aPadstack->Length();
+ int drill_diam_iu = -1;
+ int copperLayerCount = sessionBoard->GetCopperLayerCount();
+
+
+ // The drill diameter is encoded in the padstack name if Pcbnew did the DSN export.
+ // It is after the colon and before the last '_'
+ int drillStartNdx = aPadstack->padstack_id.find( ':' );
+
+ if( drillStartNdx != -1 )
+ {
+ ++drillStartNdx; // skip over the ':'
+
+ int drillEndNdx = aPadstack->padstack_id.rfind( '_' );
+ if( drillEndNdx != -1 )
+ {
+ std::string diam_txt( aPadstack->padstack_id,
+ drillStartNdx, drillEndNdx-drillStartNdx );
+
+ double drill_um = strtod( diam_txt.c_str(), 0 );
+
+ drill_diam_iu = int( drill_um * (IU_PER_MM / 1000.0) );
+
+ if( drill_diam_iu == aViaDrillDefault )
+ drill_diam_iu = UNDEFINED_DRILL_DIAMETER;
+ }
+ }
+
+ if( shapeCount == 0 )
+ {
+ ThrowIOError( _( "Session via padstack has no shapes" ) );
+ }
+ else if( shapeCount == 1 )
+ {
+ shape = (SHAPE*) (*aPadstack)[0];
+ DSN_T type = shape->shape->Type();
+ if( type != T_circle )
+ ThrowIOError( _( "Unsupported via shape: %s"),
+ GetChars( GetTokenString( type ) ) );
+
+ CIRCLE* circle = (CIRCLE*) shape->shape;
+ int viaDiam = scale( circle->diameter, routeResolution );
+
+ via = new ::VIA( sessionBoard );
+ via->SetPosition( mapPt( aPoint, routeResolution ) );
+ via->SetDrill( drill_diam_iu );
+ via->SetViaType( VIA_THROUGH );
+ via->SetWidth( viaDiam );
+ via->SetLayerPair( F_Cu, B_Cu );
+ }
+ else if( shapeCount == copperLayerCount )
+ {
+ shape = (SHAPE*) (*aPadstack)[0];
+ DSN_T type = shape->shape->Type();
+ if( type != T_circle )
+ ThrowIOError( _( "Unsupported via shape: %s"),
+ GetChars( GetTokenString( type ) ) );
+
+ CIRCLE* circle = (CIRCLE*) shape->shape;
+ int viaDiam = scale( circle->diameter, routeResolution );
+
+ via = new ::VIA( sessionBoard );
+ via->SetPosition( mapPt( aPoint, routeResolution ) );
+ via->SetDrill( drill_diam_iu );
+ via->SetViaType( VIA_THROUGH );
+ via->SetWidth( viaDiam );
+ via->SetLayerPair( F_Cu, B_Cu );
+ }
+ else // VIA_MICROVIA or VIA_BLIND_BURIED
+ {
+ int topLayerNdx = -1; // session layer detectors
+ int botLayerNdx = INT_MAX;
+
+ int viaDiam = -1;
+
+ for( int i=0; i<shapeCount; ++i )
+ {
+ shape = (SHAPE*) (*aPadstack)[i];
+ DSN_T type = shape->shape->Type();
+ if( type != T_circle )
+ ThrowIOError( _( "Unsupported via shape: %s"),
+ GetChars( GetTokenString( type ) ) );
+
+ CIRCLE* circle = (CIRCLE*) shape->shape;
+
+ int layerNdx = findLayerName( circle->layer_id );
+ if( layerNdx == -1 )
+ {
+ wxString layerName = FROM_UTF8( circle->layer_id.c_str() );
+ ThrowIOError( _("Session file uses invalid layer id \"%s\""),
+ GetChars( layerName ) );
+ }
+
+ if( layerNdx > topLayerNdx )
+ topLayerNdx = layerNdx;
+
+ if( layerNdx < botLayerNdx )
+ botLayerNdx = layerNdx;
+
+ if( viaDiam == -1 )
+ viaDiam = scale( circle->diameter, routeResolution );
+ }
+
+ via = new ::VIA( sessionBoard );
+ via->SetPosition( mapPt( aPoint, routeResolution ) );
+ via->SetDrill( drill_diam_iu );
+
+ if( (topLayerNdx==0 && botLayerNdx==1)
+ || (topLayerNdx==copperLayerCount-2 && botLayerNdx==copperLayerCount-1))
+ via->SetViaType( VIA_MICROVIA );
+ else
+ via->SetViaType( VIA_BLIND_BURIED );
+
+ via->SetWidth( viaDiam );
+
+ LAYER_ID topLayer = pcbLayer2kicad[topLayerNdx];
+ LAYER_ID botLayer = pcbLayer2kicad[botLayerNdx];
+
+ via->SetLayerPair( topLayer, botLayer );
+ }
+
+ if( via )
+ via->SetNetCode( aNetCode );
+
+ return via;
+}
+
+
+// no UI code in this function, throw exception to report problems to the
+// UI handler: void PCB_EDIT_FRAME::ImportSpecctraSession( wxCommandEvent& event )
+
+void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR )
+{
+ sessionBoard = aBoard; // not owned here
+
+ if( !session )
+ ThrowIOError( _("Session file is missing the \"session\" section") );
+
+ /* Dick 16-Jan-2012: session need not have a placement section.
+ if( !session->placement )
+ ThrowIOError( _("Session file is missing the \"placement\" section") );
+ */
+
+ if( !session->route )
+ ThrowIOError( _("Session file is missing the \"routes\" section") );
+
+ if( !session->route->library )
+ ThrowIOError( _("Session file is missing the \"library_out\" section") );
+
+ // delete all the old tracks and vias
+ aBoard->m_Track.DeleteAll();
+
+ aBoard->DeleteMARKERs();
+
+ buildLayerMaps( aBoard );
+
+ if( session->placement )
+ {
+ // Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within
+ // each COMPONENT, reposition and re-orient each component and put on
+ // correct side of the board.
+ COMPONENTS& components = session->placement->components;
+ for( COMPONENTS::iterator comp=components.begin(); comp!=components.end(); ++comp )
+ {
+ PLACES& places = comp->places;
+ for( unsigned i=0; i<places.size(); ++i )
+ {
+ PLACE* place = &places[i]; // '&' even though places[] holds a pointer!
+
+ wxString reference = FROM_UTF8( place->component_id.c_str() );
+ MODULE* module = aBoard->FindModuleByReference( reference );
+ if( !module )
+ {
+ ThrowIOError(
+ _("Session file has 'reference' to non-existent component \"%s\""),
+ GetChars( reference ) );
+ }
+
+ if( !place->hasVertex )
+ continue;
+
+ UNIT_RES* resolution = place->GetUnits();
+ wxASSERT( resolution );
+
+ wxPoint newPos = mapPt( place->vertex, resolution );
+ module->SetPosition( newPos );
+
+ if( place->side == T_front )
+ {
+ // convert from degrees to tenths of degrees used in KiCad.
+ int orientation = KiROUND( place->rotation * 10.0 );
+
+ if( module->GetLayer() != F_Cu )
+ {
+ // module is on copper layer (back)
+ module->Flip( module->GetPosition() );
+ }
+
+ module->SetOrientation( orientation );
+ }
+ else if( place->side == T_back )
+ {
+ int orientation = KiROUND( (place->rotation + 180.0) * 10.0 );
+
+ if( module->GetLayer() != B_Cu )
+ {
+ // module is on component layer (front)
+ module->Flip( module->GetPosition() );
+ }
+
+ module->SetOrientation( orientation );
+ }
+ else
+ {
+ // as I write this, the PARSER *is* catching this, so we should never see below:
+ wxFAIL_MSG( wxT("DSN::PARSER did not catch an illegal side := 'back|front'") );
+ }
+ }
+ }
+ }
+
+ routeResolution = session->route->GetUnits();
+
+ // Walk the NET_OUTs and create tracks and vias anew.
+ NET_OUTS& net_outs = session->route->net_outs;
+ for( NET_OUTS::iterator net=net_outs.begin(); net!=net_outs.end(); ++net )
+ {
+ int netCode = 0;
+
+ // page 143 of spec says wire's net_id is optional
+ if( net->net_id.size() )
+ {
+ wxString netName = FROM_UTF8( net->net_id.c_str() );
+
+ NETINFO_ITEM* net = aBoard->FindNet( netName );
+ if( net )
+ netCode = net->GetNet();
+ else // else netCode remains 0
+ {
+ // int breakhere = 1;
+ }
+ }
+
+ WIRES& wires = net->wires;
+ for( unsigned i=0; i<wires.size(); ++i )
+ {
+ WIRE* wire = &wires[i];
+ DSN_T shape = wire->shape->Type();
+
+ if( shape != T_path )
+ {
+ /* shape == T_polygon is expected from freerouter if you have
+ a zone on a non "power" type layer, i.e. a T_signal layer
+ and the design does a round trip back in as session here.
+ We kept our own zones in the BOARD, so ignore this so called
+ 'wire'.
+
+ wxString netId = FROM_UTF8( wire->net_id.c_str() );
+ ThrowIOError(
+ _("Unsupported wire shape: \"%s\" for net: \"%s\""),
+ DLEX::GetTokenString(shape).GetData(),
+ netId.GetData()
+ );
+ */
+ }
+ else
+ {
+ PATH* path = (PATH*) wire->shape;
+ for( unsigned pt=0; pt<path->points.size()-1; ++pt )
+ {
+ /* a debugging aid, may come in handy
+ if( path->points[pt].x == 547800
+ && path->points[pt].y == -380250 )
+ {
+ int breakhere = 1;
+ }
+ */
+
+ TRACK* track = makeTRACK( path, pt, netCode );
+ aBoard->Add( track );
+ }
+ }
+ }
+
+ WIRE_VIAS& wire_vias = net->wire_vias;
+ LIBRARY& library = *session->route->library;
+ for( unsigned i=0; i<wire_vias.size(); ++i )
+ {
+ int netCode = 0;
+
+ // page 144 of spec says wire_via's net_id is optional
+ if( net->net_id.size() )
+ {
+ wxString netName = FROM_UTF8( net->net_id.c_str() );
+
+ NETINFO_ITEM* net = aBoard->FindNet( netName );
+ if( net )
+ netCode = net->GetNet();
+
+ // else netCode remains 0
+ }
+
+ WIRE_VIA* wire_via = &wire_vias[i];
+
+ // example: (via Via_15:8_mil 149000 -71000 )
+
+ PADSTACK* padstack = library.FindPADSTACK( wire_via->GetPadstackId() );
+ if( !padstack )
+ {
+ // Dick Feb 29, 2008:
+ // Freerouter has a bug where it will not round trip all vias.
+ // Vias which have a (use_via) element will be round tripped.
+ // Vias which do not, don't come back in in the session library,
+ // even though they may be actually used in the pre-routed,
+ // protected wire_vias. So until that is fixed, create the
+ // padstack from its name as a work around.
+
+
+ // Could use a STRING_FORMATTER here and convert the entire
+ // wire_via to text and put that text into the exception.
+ wxString psid( FROM_UTF8( wire_via->GetPadstackId().c_str() ) );
+
+ ThrowIOError( _("A wire_via references a missing padstack \"%s\""),
+ GetChars( psid ) );
+ }
+
+ NETCLASSPTR netclass = aBoard->GetDesignSettings().m_NetClasses.GetDefault();
+
+ int via_drill_default = netclass->GetViaDrill();
+
+ for( unsigned v=0; v<wire_via->vertexes.size(); ++v )
+ {
+ ::VIA* via = makeVIA( padstack, wire_via->vertexes[v], netCode, via_drill_default );
+ aBoard->Add( via );
+ }
+ }
+ }
+}
+
+
+} // namespace DSN
+
diff --git a/pcbnew/specctra_test.cpp b/pcbnew/specctra_test.cpp
new file mode 100644
index 0000000..3a6cc0b
--- /dev/null
+++ b/pcbnew/specctra_test.cpp
@@ -0,0 +1,108 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+// unit test the specctra.cpp file. You can use the beautifiers below to output
+// exactly what you read in but beautified and without #comments. This can
+// then be used along with program 'diff' to test the parsing and formatting
+// of every element. You may have to run the first output back through to
+// get two files that should match, the 2nd and 3rd outputs.
+
+
+
+#include <cstdarg>
+#include <cstdio>
+
+#include <specctra.h>
+#include <common.h>
+
+
+using namespace DSN;
+
+
+int main( int argc, char** argv )
+{
+// wxString filename( wxT("/tmp/fpcroute/Sample_1sided/demo_1sided.dsn") );
+// wxString filename( wxT("/tmp/testdesigns/test.dsn") );
+// wxString filename( wxT("/tmp/testdesigns/test.ses") );
+ wxString filename( wxT("/tmp/specctra_big.dsn") );
+
+ SPECCTRA_DB db;
+ bool failed = false;
+
+ LOCALE_IO toggle; // Temporary switch the locale to standard C to r/w floats
+
+ if( argc == 2 )
+ {
+ filename = FROM_UTF8( argv[1] );
+ }
+
+ try
+ {
+// db.LoadPCB( filename );
+ db.LoadSESSION( filename );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ fprintf( stderr, "%s\n", TO_UTF8(ioe.errorText) );
+ failed = true;
+ }
+
+ if( !failed )
+ fprintf( stderr, "loaded OK\n" );
+
+ // export what we read in, making this test program basically a beautifier
+ // hose the beautified DSN file to stdout. If an exception occurred,
+ // we will be outputting only a portion of what we wanted to read in.
+ db.SetFILE( stdout );
+
+#if 0
+ // export a PCB
+ DSN::PCB* pcb = db.GetPCB();
+ pcb->Format( &db, 0 );
+
+#else
+ // export a SESSION file.
+ DSN::SESSION* ses = db.GetSESSION();
+ ses->Format( &db, 0 );
+#endif
+}
+
+//-----<dummy code>---------------------------------------------------
+
+// a dummy to satisfy link of specctra_test without pulling in BOARD stuff.
+int BOARD::GetCopperLayerCount() const
+{
+ return 0;
+}
+
+// a dummy to satisfy link of specctra_test without pulling in BOARD stuff.
+wxString BOARD::GetLayerName( LAYER_NUM aLayer ) const
+{
+ return wxEmptyString;
+}
+
+//-----</dummy code>--------------------------------------------------
+
+//EOF
diff --git a/pcbnew/swap_layers.cpp b/pcbnew/swap_layers.cpp
new file mode 100644
index 0000000..f27fe8e
--- /dev/null
+++ b/pcbnew/swap_layers.cpp
@@ -0,0 +1,430 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file swap_layers.cpp
+ * @brief Dialog to swap layers.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+#include <dialog_shim.h>
+
+#include <class_board.h>
+#include <class_track.h>
+#include <class_drawsegment.h>
+
+#include <pcbnew.h>
+
+#include <wx/statline.h>
+
+
+#define NO_CHANGE LAYER_ID(-3)
+
+
+enum swap_layer_id {
+ ID_WINEDA_SWAPLAYERFRAME = 1800,
+ ID_BUTTON_0,
+ ID_TEXT_0 = ID_BUTTON_0 + LAYER_ID_COUNT
+};
+
+
+class SWAP_LAYERS_DIALOG : public DIALOG_SHIM
+{
+public:
+ SWAP_LAYERS_DIALOG( PCB_BASE_FRAME* parent, LAYER_ID* aArray );
+ // ~SWAP_LAYERS_DIALOG() { };
+
+private:
+ PCB_BASE_FRAME* m_Parent;
+ wxBoxSizer* OuterBoxSizer;
+ wxBoxSizer* MainBoxSizer;
+ wxFlexGridSizer* FlexColumnBoxSizer;
+ wxStaticText* label;
+ wxButton* Button;
+ wxStaticText* text;
+ wxStaticLine* Line;
+ wxStdDialogButtonSizer* StdDialogButtonSizer;
+
+ LAYER_ID* m_callers_nlayers; // DIM() is LAYER_ID_COUNT
+ wxStaticText* layer_list[LAYER_ID_COUNT];
+
+ void Sel_Layer( wxCommandEvent& event );
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+
+ DECLARE_EVENT_TABLE()
+};
+
+
+BEGIN_EVENT_TABLE( SWAP_LAYERS_DIALOG, wxDialog )
+ EVT_COMMAND_RANGE( ID_BUTTON_0, ID_BUTTON_0 + LAYER_ID_COUNT - 1,
+ wxEVT_COMMAND_BUTTON_CLICKED, SWAP_LAYERS_DIALOG::Sel_Layer )
+
+ EVT_BUTTON( wxID_OK, SWAP_LAYERS_DIALOG::OnOkClick )
+
+ EVT_BUTTON( wxID_CANCEL, SWAP_LAYERS_DIALOG::OnCancelClick )
+END_EVENT_TABLE()
+
+
+SWAP_LAYERS_DIALOG::SWAP_LAYERS_DIALOG( PCB_BASE_FRAME* parent, LAYER_ID* aArray ) :
+ DIALOG_SHIM( parent, -1, _( "Swap Layers:" ), wxPoint( -1, -1 ),
+ wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ),
+ m_callers_nlayers( aArray )
+{
+ memset( layer_list, 0, sizeof( layer_list ) );
+
+ BOARD* board = parent->GetBoard();
+
+ OuterBoxSizer = NULL;
+ MainBoxSizer = NULL;
+ FlexColumnBoxSizer = NULL;
+ label = NULL;
+ Button = NULL;
+ text = NULL;
+ Line = NULL;
+ StdDialogButtonSizer = NULL;
+
+ m_Parent = parent;
+
+ int item_ID;
+ wxSize goodSize;
+
+ /* Experimentation has shown that buttons in the Windows version can be
+ * 20 pixels wide and 20 pixels high, but that they need to be 26 pixels
+ * wide and 26 pixels high in the Linux version. (And although the
+ * dimensions of those buttons could be set to 26 pixels wide and 26
+ * pixels high in both of those versions, that would result in a dialog
+ * box which would be excessively high in the Windows version.)
+ */
+#ifdef __WINDOWS__
+ int w = 20;
+ int h = 20;
+#else
+ int w = 26;
+ int h = 26;
+#endif
+
+ /* As currently implemented, the dimensions of the buttons in the Mac
+ * version are also 26 pixels wide and 26 pixels high. If appropriate,
+ * the above code should be modified as required in the event that those
+ * buttons should be some other size in that version.
+ */
+
+ OuterBoxSizer = new wxBoxSizer( wxVERTICAL );
+ SetSizer( OuterBoxSizer );
+
+ MainBoxSizer = new wxBoxSizer( wxHORIZONTAL );
+ OuterBoxSizer->Add( MainBoxSizer, 1, wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
+
+ for( unsigned layer = 0; layer < DIM( layer_list ); ++layer )
+ {
+ // Provide a vertical line to separate the two FlexGrid sizers
+ if( layer == 32 )
+ {
+ Line = new wxStaticLine( this,
+ -1,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxLI_VERTICAL );
+ MainBoxSizer->Add( Line, 0, wxGROW | wxLEFT | wxRIGHT, 5 );
+ }
+
+ // Provide a separate FlexGrid sizer for every sixteen sets of controls
+ if( layer % 16 == 0 )
+ {
+ /* Each layer has an associated static text string (to identify
+ * that layer), a button (for invoking a child dialog box to
+ * change which layer that the layer is mapped to), and a second
+ * static text string (to depict which layer that the layer has
+ * been mapped to). Each of those items are placed into the left
+ * hand column, middle column, and right hand column (respectively)
+ * of the Flexgrid sizer, and the color of the second text string
+ * is set to fuchsia or blue (to respectively indicate whether the
+ * layer has been swapped to another layer or is not being swapped
+ * at all). (Experimentation has shown that if a text control is
+ * used to depict which layer that each layer is mapped to (instead
+ * of a static text string), then those controls do not behave in
+ * a fully satisfactory manner in the Linux version. Even when the
+ * read-only attribute is specified for all of those controls, they
+ * can still be selected when the arrow keys or Tab key is used
+ * to step through all of the controls within the dialog box, and
+ * directives to set the foreground color of the text of each such
+ * control to blue (to indicate that the text is of a read-only
+ * nature) are disregarded.)
+ *
+ * Specify a FlexGrid sizer with sixteen rows and three columns.
+ */
+ FlexColumnBoxSizer = new wxFlexGridSizer( 16, 3, 0, 0 );
+
+ // Specify that all of the rows can be expanded.
+ for( int jj = 0; jj < 16; jj++ )
+ {
+ FlexColumnBoxSizer->AddGrowableRow( jj );
+ }
+
+ // Specify that (just) the right-hand column can be expanded.
+ FlexColumnBoxSizer->AddGrowableCol( 2 );
+
+ MainBoxSizer->Add( FlexColumnBoxSizer, 1, wxGROW | wxTOP, 5 );
+ }
+
+ /* Provide a text string to identify this layer (with trailing spaces
+ * within that string being purged).
+ */
+ label = new wxStaticText( this, wxID_STATIC, board->GetLayerName( ToLAYER_ID( layer ) ),
+ wxDefaultPosition, wxDefaultSize,
+ wxALIGN_RIGHT );
+
+ FlexColumnBoxSizer->Add( label, 0,
+ wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL |
+ wxLEFT | wxBOTTOM,
+ 5 );
+
+ // Provide a button for this layer (which will invoke a child dialog box)
+ item_ID = ID_BUTTON_0 + layer;
+
+ Button = new wxButton( this, item_ID, wxT( "..." ), wxDefaultPosition,
+ wxSize( w, h ), 0 );
+ FlexColumnBoxSizer->Add( Button, 0,
+ wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
+ wxLEFT | wxBOTTOM, 5 );
+
+ /* Provide another text string to specify which layer that this layer
+ * is mapped to, set the initial text to "No Change" (to indicate that
+ * this layer is currently unmapped to any other layer), and set the
+ * foreground color of the text to blue (which also indicates that the
+ * layer is currently unmapped to any other layer).
+ */
+ item_ID = ID_TEXT_0 + layer;
+
+ /* When the first of these text strings is being added, determine
+ * what size is necessary to to be able to display the longest
+ * string without truncation. Then use that size as the
+ * minimum size for all text strings. (If the minimum
+ * size is not this size, strings can be truncated after
+ * some other layer is selected.)
+ */
+ if( layer == 0 )
+ {
+ text = new wxStaticText( this, item_ID, board->GetLayerName( LAYER_ID( 0 ) ),
+ wxDefaultPosition, wxDefaultSize, 0 );
+ goodSize = text->GetSize();
+
+ for( unsigned jj = 1; jj < DIM( layer_list ); ++jj )
+ {
+ text->SetLabel( board->GetLayerName( ToLAYER_ID( jj ) ) );
+
+ if( goodSize.x < text->GetSize().x )
+ goodSize.x = text->GetSize().x;
+ }
+
+ text->SetLabel( _( "No Change" ) );
+
+ if( goodSize.x < text->GetSize().x )
+ goodSize.x = text->GetSize().x;
+ }
+ else
+ {
+ text = new wxStaticText( this, item_ID, _( "No Change" ),
+ wxDefaultPosition, wxDefaultSize, 0 );
+ }
+
+ text->SetMinSize( goodSize );
+ FlexColumnBoxSizer->Add( text, 1,
+ wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
+ wxLEFT | wxRIGHT | wxBOTTOM, 5 );
+ layer_list[layer] = text;
+ }
+
+ /* Provide spacers to occupy otherwise blank cells within the second
+ * FlexGrid sizer. (Becuse there are three columns, three spacers
+ * are thus required for each unused row.)
+ for( int ii = 3 * NB_PCB_LAYERS; ii < 96; ii++ )
+ {
+ FlexColumnBoxSizer->Add( 5, h, 0, wxALIGN_CENTER_HORIZONTAL |
+ wxALIGN_CENTER_VERTICAL | wxLEFT |
+ wxRIGHT | wxBOTTOM, 5 );
+ }
+ */
+
+ // Provide a line to separate the controls which have been provided so far
+ // from the OK and Cancel buttons (which will be provided after this line)
+ Line = new wxStaticLine( this, -1, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ OuterBoxSizer->Add( Line, 0, wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
+
+ // Provide a StdDialogButtonSizer to accommodate the OK and Cancel buttons;
+ // using that type of sizer results in those buttons being automatically
+ // located in positions appropriate for each (OS) version of KiCad.
+ StdDialogButtonSizer = new wxStdDialogButtonSizer;
+ OuterBoxSizer->Add( StdDialogButtonSizer, 0, wxGROW | wxALL, 10 );
+
+ Button = new wxButton( this, wxID_OK, _( "&OK" ), wxDefaultPosition, wxDefaultSize, 0 );
+ Button->SetDefault();
+ StdDialogButtonSizer->AddButton( Button );
+
+ Button = new wxButton( this, wxID_CANCEL, _( "&Cancel" ),
+ wxDefaultPosition, wxDefaultSize, 0 );
+ StdDialogButtonSizer->AddButton( Button );
+ StdDialogButtonSizer->Realize();
+
+ // Resize the dialog
+ if( GetSizer() )
+ {
+ GetSizer()->SetSizeHints( this );
+ }
+
+ Center();
+}
+
+
+void SWAP_LAYERS_DIALOG::Sel_Layer( wxCommandEvent& event )
+{
+ int ii;
+
+ ii = event.GetId();
+
+ if( ii < ID_BUTTON_0 || ii >= ID_BUTTON_0 + LAYER_ID_COUNT )
+ return;
+
+ ii = event.GetId() - ID_BUTTON_0;
+
+ LAYER_ID layer = m_callers_nlayers[ii];
+
+ LSET notallowed_mask = IsCopperLayer( ii ) ? LSET::AllNonCuMask() : LSET::AllCuMask();
+
+ layer = m_Parent->SelectLayer( layer == NO_CHANGE ? ToLAYER_ID( ii ): layer, notallowed_mask );
+
+ if( !IsValidLayer( layer ) )
+ return;
+
+ if( layer != m_callers_nlayers[ii] )
+ {
+ m_callers_nlayers[ii] = layer;
+
+ if( layer == NO_CHANGE || layer == ii )
+ {
+ layer_list[ii]->SetLabel( _( "No Change" ) );
+
+ // Change the text color to blue (to highlight
+ // that this layer is *not* being swapped)
+ layer_list[ii]->SetForegroundColour( *wxBLUE );
+ }
+ else
+ {
+ layer_list[ii]->SetLabel( m_Parent->GetBoard()->GetLayerName( layer ) );
+
+ // Change the text color to fuchsia (to highlight
+ // that this layer *is* being swapped)
+ layer_list[ii]->SetForegroundColour( wxColour( 255, 0, 128 ) );
+ }
+ }
+}
+
+
+void SWAP_LAYERS_DIALOG::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( -1 );
+}
+
+
+void SWAP_LAYERS_DIALOG::OnOkClick( wxCommandEvent& event )
+{
+ EndModal( 1 );
+}
+
+
+void PCB_EDIT_FRAME::Swap_Layers( wxCommandEvent& event )
+{
+ LAYER_ID new_layer[LAYER_ID_COUNT];
+
+ for( unsigned i = 0; i < DIM( new_layer ); ++i )
+ new_layer[i] = NO_CHANGE;
+
+ SWAP_LAYERS_DIALOG dlg( this, new_layer );
+
+ if( dlg.ShowModal() != 1 )
+ return; // (Canceled dialog box returns -1 instead)
+
+ // Change traces.
+ for( TRACK* segm = GetBoard()->m_Track; segm; segm = segm->Next() )
+ {
+ OnModify();
+
+ if( segm->Type() == PCB_VIA_T )
+ {
+ VIA* via = (VIA*) segm;
+
+ if( via->GetViaType() == VIA_THROUGH )
+ continue;
+
+ LAYER_ID top_layer, bottom_layer;
+
+ via->LayerPair( &top_layer, &bottom_layer );
+
+ if( new_layer[bottom_layer] != NO_CHANGE )
+ bottom_layer = new_layer[bottom_layer];
+
+ if( new_layer[top_layer] != NO_CHANGE )
+ top_layer = new_layer[top_layer];
+
+ via->SetLayerPair( top_layer, bottom_layer );
+ }
+ else
+ {
+ int jj = segm->GetLayer();
+
+ if( new_layer[jj] != NO_CHANGE )
+ segm->SetLayer( new_layer[jj] );
+ }
+ }
+
+ // Change zones.
+ for( TRACK* segm = GetBoard()->m_Zone; segm; segm = segm->Next() )
+ {
+ OnModify();
+ int jj = segm->GetLayer();
+
+ if( new_layer[jj] != NO_CHANGE )
+ segm->SetLayer( new_layer[jj] );
+ }
+
+ // Change other segments.
+ for( EDA_ITEM* item = GetBoard()->m_Drawings; item; item = item->Next() )
+ {
+ if( item->Type() == PCB_LINE_T )
+ {
+ OnModify();
+
+ DRAWSEGMENT* drawsegm = (DRAWSEGMENT*) item;
+ int jj = drawsegm->GetLayer();
+
+ if( new_layer[jj] != NO_CHANGE )
+ drawsegm->SetLayer( new_layer[jj] );
+ }
+ }
+
+ m_canvas->Refresh( true );
+}
diff --git a/pcbnew/target_edit.cpp b/pcbnew/target_edit.cpp
new file mode 100644
index 0000000..77d353d
--- /dev/null
+++ b/pcbnew/target_edit.cpp
@@ -0,0 +1,288 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file target_edit.cpp
+ * @brief Functions to edit targets (class #PCB_TARGET).
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+#include <dialog_helpers.h>
+#include <base_units.h>
+#include <gr_basic.h>
+
+#include <class_board.h>
+#include <class_mire.h>
+
+#include <pcbnew.h>
+#include <dialog_target_properties_base.h>
+
+
+// Routines Locales
+static void AbortMoveAndEditTarget( EDA_DRAW_PANEL* Panel, wxDC* DC );
+static void ShowTargetShapeWhileMovingMouse( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC,
+ const wxPoint& aPosition,
+ bool aErase );
+
+// Local variables :
+static int MireDefaultSize = Millimeter2iu( 5 );
+
+static PCB_TARGET s_TargetCopy( NULL ); /* Used to store "old" values of the
+ * current item parameters before
+ * edition (used in undo/redo or
+ * cancel operations)
+ */
+
+/*****************************************/
+/* class TARGET_PROPERTIES_DIALOG_EDITOR */
+/*****************************************/
+
+class TARGET_PROPERTIES_DIALOG_EDITOR : public TARGET_PROPERTIES_DIALOG_EDITOR_BASE
+{
+private:
+ PCB_EDIT_FRAME* m_Parent;
+ wxDC* m_DC;
+ PCB_TARGET* m_Target;
+
+public:
+ TARGET_PROPERTIES_DIALOG_EDITOR( PCB_EDIT_FRAME* parent, PCB_TARGET* Mire, wxDC* DC );
+ ~TARGET_PROPERTIES_DIALOG_EDITOR() { }
+
+private:
+ void OnOkClick( wxCommandEvent& event );
+ void OnCancelClick( wxCommandEvent& event );
+};
+
+
+void PCB_EDIT_FRAME::ShowTargetOptionsDialog( PCB_TARGET* aTarget, wxDC* DC )
+{
+ TARGET_PROPERTIES_DIALOG_EDITOR* frame =
+ new TARGET_PROPERTIES_DIALOG_EDITOR( this, aTarget, DC );
+
+ frame->ShowModal();
+ frame->Destroy();
+}
+
+
+TARGET_PROPERTIES_DIALOG_EDITOR::TARGET_PROPERTIES_DIALOG_EDITOR( PCB_EDIT_FRAME* parent,
+ PCB_TARGET* aTarget, wxDC* DC ) :
+ TARGET_PROPERTIES_DIALOG_EDITOR_BASE( parent )
+{
+ m_Parent = parent;
+ m_DC = DC;
+ m_Target = aTarget;
+
+ // Size:
+ m_staticTextSizeUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
+ m_TargetSizeCtrl->SetValue( StringFromValue( g_UserUnit, m_Target->GetSize() ) );
+
+ // Thickness:
+ m_staticTextThicknessUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
+ m_TargetThicknessCtrl->SetValue( StringFromValue( g_UserUnit, m_Target->GetWidth() ) );
+
+ // Shape
+ m_TargetShape->SetSelection( m_Target->GetShape() ? 1 : 0 );
+
+ // OK button on return key.
+ SetDefaultItem( m_sdbSizerButtsOK );
+
+ FixOSXCancelButtonIssue();
+
+ // Now all widgets have the size fixed, call FinishDialogSettings
+ FinishDialogSettings();
+}
+
+
+void TARGET_PROPERTIES_DIALOG_EDITOR::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( -1 );
+}
+
+
+/* Updates the different parameters for the component being edited
+ */
+void TARGET_PROPERTIES_DIALOG_EDITOR::OnOkClick( wxCommandEvent& event )
+{
+ if( m_DC )
+ m_Target->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR );
+
+ // Save old item in undo list, if is is not currently edited (will be later if so)
+ if( m_Target->GetFlags() == 0 )
+ m_Parent->SaveCopyInUndoList( m_Target, UR_CHANGED );
+
+ if( m_Target->GetFlags() != 0 ) // other edition in progress (MOVE, NEW ..)
+ m_Target->SetFlags( IN_EDIT ); // set flag in edit to force
+ // undo/redo/abort proper operation
+
+ int tmp = ValueFromString( g_UserUnit, m_TargetThicknessCtrl->GetValue() );
+ m_Target->SetWidth( tmp );
+
+ MireDefaultSize = ValueFromString( g_UserUnit, m_TargetSizeCtrl->GetValue() );
+ m_Target->SetSize( MireDefaultSize );
+
+ m_Target->SetShape( m_TargetShape->GetSelection() ? 1 : 0 );
+
+ if( m_DC )
+ m_Target->Draw( m_Parent->GetCanvas(), m_DC, ( m_Target->IsMoving() ) ? GR_XOR : GR_OR );
+
+ m_Parent->OnModify();
+ EndModal( 1 );
+}
+
+
+void PCB_EDIT_FRAME::DeleteTarget( PCB_TARGET* aTarget, wxDC* DC )
+{
+ if( aTarget == NULL )
+ return;
+
+ aTarget->Draw( m_canvas, DC, GR_XOR );
+ SaveCopyInUndoList( aTarget, UR_DELETED );
+ aTarget->UnLink();
+}
+
+
+static void AbortMoveAndEditTarget( EDA_DRAW_PANEL* Panel, wxDC* DC )
+{
+ BASE_SCREEN* screen = Panel->GetScreen();
+ PCB_TARGET* target = (PCB_TARGET*) screen->GetCurItem();
+
+ ( (PCB_EDIT_FRAME*) Panel->GetParent() )->SetCurItem( NULL );
+
+ Panel->SetMouseCapture( NULL, NULL );
+
+ if( target == NULL )
+ return;
+
+ target->Draw( Panel, DC, GR_XOR );
+
+ if( target->IsNew() ) // If it is new, delete it
+ {
+ target->Draw( Panel, DC, GR_XOR );
+ target->DeleteStructure();
+ target = NULL;
+ }
+ else // it is an existing item: retrieve initial values of parameters
+ {
+ if( ( target->GetFlags() & (IN_EDIT | IS_MOVED) ) )
+ {
+ target->SetPosition( s_TargetCopy.GetPosition() );
+ target->SetWidth( s_TargetCopy.GetWidth() );
+ target->SetSize( s_TargetCopy.GetSize() );
+ target->SetShape( s_TargetCopy.GetShape() );
+ }
+
+ target->ClearFlags();
+ target->Draw( Panel, DC, GR_OR );
+ }
+}
+
+
+PCB_TARGET* PCB_EDIT_FRAME::CreateTarget( wxDC* DC )
+{
+ PCB_TARGET* target = new PCB_TARGET( GetBoard() );
+
+ target->SetFlags( IS_NEW );
+
+ GetBoard()->Add( target );
+
+ target->SetLayer( Edge_Cuts );
+ target->SetWidth( GetDesignSettings().m_EdgeSegmentWidth );
+ target->SetSize( MireDefaultSize );
+ target->SetPosition( GetCrossHairPosition() );
+
+ PlaceTarget( target, DC );
+
+ return target;
+}
+
+
+void PCB_EDIT_FRAME::BeginMoveTarget( PCB_TARGET* aTarget, wxDC* DC )
+{
+ if( aTarget == NULL )
+ return;
+
+ s_TargetCopy = *aTarget;
+ aTarget->SetFlags( IS_MOVED );
+ m_canvas->SetMouseCapture( ShowTargetShapeWhileMovingMouse, AbortMoveAndEditTarget );
+ SetCurItem( aTarget );
+}
+
+
+void PCB_EDIT_FRAME::PlaceTarget( PCB_TARGET* aTarget, wxDC* DC )
+{
+ if( aTarget == NULL )
+ return;
+
+ aTarget->Draw( m_canvas, DC, GR_OR );
+ m_canvas->SetMouseCapture( NULL, NULL );
+ SetCurItem( NULL );
+ OnModify();
+
+ if( aTarget->IsNew() )
+ {
+ SaveCopyInUndoList( aTarget, UR_NEW );
+ aTarget->ClearFlags();
+ return;
+ }
+
+ if( aTarget->GetFlags() == IS_MOVED )
+ {
+ SaveCopyInUndoList( aTarget, UR_MOVED,
+ aTarget->GetPosition() - s_TargetCopy.GetPosition() );
+ aTarget->ClearFlags();
+ return;
+ }
+
+ if( (aTarget->GetFlags() & IN_EDIT) )
+ {
+ aTarget->SwapData( &s_TargetCopy );
+ SaveCopyInUndoList( aTarget, UR_CHANGED );
+ aTarget->SwapData( &s_TargetCopy );
+ }
+
+ aTarget->ClearFlags();
+}
+
+
+// Redraw the contour of the track while moving the mouse
+static void ShowTargetShapeWhileMovingMouse( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase )
+{
+ BASE_SCREEN* screen = aPanel->GetScreen();
+ PCB_TARGET* target = (PCB_TARGET*) screen->GetCurItem();
+
+ if( target == NULL )
+ return;
+
+ if( aErase )
+ target->Draw( aPanel, aDC, GR_XOR );
+
+ target->SetPosition( aPanel->GetParent()->GetCrossHairPosition() );
+
+ target->Draw( aPanel, aDC, GR_XOR );
+}
diff --git a/pcbnew/tool_modedit.cpp b/pcbnew/tool_modedit.cpp
new file mode 100644
index 0000000..3f613e5
--- /dev/null
+++ b/pcbnew/tool_modedit.cpp
@@ -0,0 +1,279 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file tool_modedit.cpp
+ * @brief Footprint editor tool bars
+ */
+
+#include <fctsys.h>
+
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <module_editor_frame.h>
+#include <dialog_helpers.h>
+#include <pcbnew_id.h>
+#include <hotkeys.h>
+
+
+void FOOTPRINT_EDIT_FRAME::ReCreateHToolbar()
+{
+ if( m_mainToolBar != NULL )
+ return;
+
+ wxString msg;
+
+ m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
+
+ // Set up toolbar
+ m_mainToolBar->AddTool( ID_MODEDIT_SELECT_CURRENT_LIB, wxEmptyString,
+ KiBitmap( open_library_xpm ),
+ _( "Select active library" ) );
+
+ m_mainToolBar->AddTool( ID_MODEDIT_SAVE_LIBMODULE, wxEmptyString, KiBitmap( save_library_xpm ),
+ _( "Save footprint in active library" ) );
+
+ m_mainToolBar->AddTool( ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART, wxEmptyString,
+ KiBitmap( new_library_xpm ),
+ _( "Create new library and save current footprint" ) );
+
+ m_mainToolBar->AddTool( ID_OPEN_MODULE_VIEWER, wxEmptyString, KiBitmap( modview_icon_xpm ),
+ _( "Open footprint viewer" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_MODEDIT_DELETE_PART, wxEmptyString, KiBitmap( delete_xpm ),
+ _( "Delete part from active library" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_MODEDIT_NEW_MODULE, wxEmptyString, KiBitmap( new_footprint_xpm ),
+ _( "New footprint" ) );
+
+#ifdef KICAD_SCRIPTING
+ m_mainToolBar->AddTool( ID_MODEDIT_NEW_MODULE_FROM_WIZARD, wxEmptyString,
+ KiBitmap( module_wizard_xpm ),
+ _( "New footprint using the footprint wizard" ) );
+#endif
+
+
+ m_mainToolBar->AddTool( ID_MODEDIT_LOAD_MODULE, wxEmptyString,
+ KiBitmap( load_module_lib_xpm ),
+ _( "Load footprint from library" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_MODEDIT_LOAD_MODULE_FROM_BOARD, wxEmptyString,
+ KiBitmap( load_module_board_xpm ),
+ _( "Load footprint from current board" ) );
+
+ m_mainToolBar->AddTool( ID_MODEDIT_UPDATE_MODULE_IN_BOARD, wxEmptyString,
+ KiBitmap( update_module_board_xpm ),
+ _( "Update footprint in current board" ) );
+
+ m_mainToolBar->AddTool( ID_MODEDIT_INSERT_MODULE_IN_BOARD, wxEmptyString,
+ KiBitmap( insert_module_board_xpm ),
+ _( "Insert footprint into current board" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_MODEDIT_IMPORT_PART, wxEmptyString, KiBitmap( import_module_xpm ),
+ _( "Import footprint" ) );
+
+ m_mainToolBar->AddTool( ID_MODEDIT_EXPORT_PART, wxEmptyString, KiBitmap( export_module_xpm ),
+ _( "Export footprint" ) );
+
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( wxID_UNDO, wxEmptyString, KiBitmap( undo_xpm ),
+ _( "Undo last edition" ) );
+ m_mainToolBar->AddTool( wxID_REDO, wxEmptyString, KiBitmap( redo_xpm ),
+ _( "Redo the last undo command" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_MODEDIT_EDIT_MODULE_PROPERTIES, wxEmptyString,
+ KiBitmap( module_options_xpm ),
+ _( "Footprint properties" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( wxID_PRINT, wxEmptyString, KiBitmap( print_button_xpm ),
+ _( "Print footprint" ) );
+
+ m_mainToolBar->AddSeparator();
+ msg = AddHotkeyName( _( "Zoom in" ), g_Module_Editor_Hokeys_Descr, HK_ZOOM_IN, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_IN, wxEmptyString, KiBitmap( zoom_in_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Zoom out" ), g_Module_Editor_Hokeys_Descr, HK_ZOOM_OUT, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_OUT, wxEmptyString, KiBitmap( zoom_out_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Redraw view" ), g_Module_Editor_Hokeys_Descr, HK_ZOOM_REDRAW,
+ IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_REDRAW, wxEmptyString, KiBitmap( zoom_redraw_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Zoom auto" ), g_Module_Editor_Hokeys_Descr, HK_ZOOM_AUTO, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ), msg );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_MODEDIT_PAD_SETTINGS, wxEmptyString, KiBitmap( options_pad_xpm ),
+ _( "Pad settings" ) );
+
+#if 0 // Currently there is no check footprint function defined, so do not show this tool
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_MODEDIT_CHECK, wxEmptyString,
+ KiBitmap( module_check_xpm ),
+ _( "Check footprint" ) );
+#endif
+
+ // after adding the buttons to the toolbar, must call Realize() to reflect the changes
+ m_mainToolBar->Realize();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::ReCreateVToolbar()
+{
+ if( m_drawToolBar )
+ return;
+
+ m_drawToolBar = new wxAuiToolBar( this, ID_V_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
+
+ // Set up toolbar
+ m_drawToolBar->AddTool( ID_NO_TOOL_SELECTED, wxEmptyString, KiBitmap( cursor_xpm ),
+ wxEmptyString, wxITEM_CHECK );
+
+ m_drawToolBar->AddSeparator();
+ m_drawToolBar->AddTool( ID_MODEDIT_PAD_TOOL, wxEmptyString, KiBitmap( pad_xpm ),
+ _( "Add pads" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddSeparator();
+ m_drawToolBar->AddTool( ID_MODEDIT_LINE_TOOL, wxEmptyString, KiBitmap( add_polygon_xpm ),
+ _( "Add graphic line or polygon" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_MODEDIT_CIRCLE_TOOL, wxEmptyString, KiBitmap( add_circle_xpm ),
+ _( "Add graphic circle" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_MODEDIT_ARC_TOOL, wxEmptyString, KiBitmap( add_arc_xpm ),
+ _( "Add graphic arc" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_MODEDIT_TEXT_TOOL, wxEmptyString, KiBitmap( add_text_xpm ),
+ _( "Add Text" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddSeparator();
+ m_drawToolBar->AddTool( ID_MODEDIT_ANCHOR_TOOL, wxEmptyString, KiBitmap( anchor_xpm ),
+ _( "Place the footprint reference anchor" ),
+ wxITEM_CHECK );
+
+ m_drawToolBar->AddSeparator();
+ m_drawToolBar->AddTool( ID_MODEDIT_DELETE_TOOL, wxEmptyString, KiBitmap( delete_xpm ),
+ _( "Delete items" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_MODEDIT_PLACE_GRID_COORD, wxEmptyString,
+ KiBitmap( grid_select_axis_xpm ),
+ _( "Set the origin point for the grid" ),
+ wxITEM_CHECK );
+
+ m_drawToolBar->Realize();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::ReCreateOptToolbar()
+{
+ if( m_optionsToolBar )
+ return;
+
+ // Create options tool bar.
+ m_optionsToolBar = new wxAuiToolBar( this, ID_OPT_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GRID, wxEmptyString, KiBitmap( grid_xpm ),
+ _( "Hide grid" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_POLAR_COORD, wxEmptyString,
+ KiBitmap( polar_coord_xpm ),
+ _( "Display Polar Coord ON" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_INCH, wxEmptyString,
+ KiBitmap( unit_inch_xpm ),
+ _( "Units in inches" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_MM, wxEmptyString,
+ KiBitmap( unit_mm_xpm ),
+ _( "Units in millimeters" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_CURSOR, wxEmptyString,
+ KiBitmap( cursor_shape_xpm ),
+ _( "Change Cursor Shape" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_PADS_SKETCH, wxEmptyString,
+ KiBitmap( pad_sketch_xpm ),
+ _( "Show Pads Sketch" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH, wxEmptyString,
+ KiBitmap( text_sketch_xpm ),
+ _( "Show Texts Sketch" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH, wxEmptyString,
+ KiBitmap( show_mod_edge_xpm ),
+ _( "Show Edges Sketch" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE, wxEmptyString,
+ KiBitmap( contrast_mode_xpm ),
+ _( "Enable high contrast display mode" ),
+ wxITEM_CHECK );
+
+ m_optionsToolBar->Realize();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::ReCreateAuxiliaryToolbar()
+{
+ if( m_auxiliaryToolBar )
+ return;
+
+ m_auxiliaryToolBar = new wxAuiToolBar( this, ID_AUX_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
+
+ // Set up toolbar
+ m_auxiliaryToolBar->AddSeparator();
+
+ // Grid selection choice box.
+ m_gridSelectBox = new wxChoice( m_auxiliaryToolBar,
+ ID_ON_GRID_SELECT,
+ wxDefaultPosition, wxDefaultSize,
+ 0, NULL );
+ // Update tool bar to reflect setting.
+ updateGridSelectBox();
+ m_auxiliaryToolBar->AddControl( m_gridSelectBox );
+
+ // Zoom selection choice box.
+ m_auxiliaryToolBar->AddSeparator();
+ m_zoomSelectBox = new wxChoice( m_auxiliaryToolBar,
+ ID_ON_ZOOM_SELECT,
+ wxDefaultPosition, wxDefaultSize,
+ 0, NULL );
+ updateZoomSelectBox();
+ m_auxiliaryToolBar->AddControl( m_zoomSelectBox );
+
+ // after adding the buttons to the toolbar, must call Realize() to reflect the changes
+ m_auxiliaryToolBar->Realize();
+}
diff --git a/pcbnew/tool_modview.cpp b/pcbnew/tool_modview.cpp
new file mode 100644
index 0000000..5a56a35
--- /dev/null
+++ b/pcbnew/tool_modview.cpp
@@ -0,0 +1,218 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file tool_modview.cpp
+ * @brief Build the toolbars for the library browser.
+ */
+
+#include <fctsys.h>
+#include <macros.h>
+#include <pcbnew_id.h>
+
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <menus_helpers.h>
+#include <hotkeys.h>
+#include <dialog_helpers.h>
+#include <modview_frame.h>
+#include <help_common_strings.h>
+
+
+void FOOTPRINT_VIEWER_FRAME::ReCreateHToolbar()
+{
+ wxString msg;
+
+ if( m_mainToolBar == NULL )
+ {
+ m_mainToolBar = new wxAuiToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT
+ | wxAUI_TB_OVERFLOW );
+
+ // Set up toolbar
+ m_mainToolBar->AddTool( ID_MODVIEW_SELECT_LIB, wxEmptyString,
+ KiBitmap( library_xpm ),
+ _( "Select library to browse" ) );
+
+ m_mainToolBar->AddTool( ID_MODVIEW_SELECT_PART, wxEmptyString,
+ KiBitmap( module_xpm ),
+ _( "Select footprint to browse" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_MODVIEW_PREVIOUS, wxEmptyString,
+ KiBitmap( lib_previous_xpm ),
+ _( "Display previous footprint" ) );
+
+ m_mainToolBar->AddTool( ID_MODVIEW_NEXT, wxEmptyString,
+ KiBitmap( lib_next_xpm ),
+ _( "Display next footprint" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_MODVIEW_SHOW_3D_VIEW, wxEmptyString,
+ KiBitmap( three_d_xpm ),
+ _( "Show footprint in 3D viewer" ) );
+
+ m_mainToolBar->AddSeparator();
+ msg = AddHotkeyName( _( "Zoom in" ), g_Module_Viewer_Hokeys_Descr,
+ HK_ZOOM_IN, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_VIEWER_ZOOM_IN, wxEmptyString,
+ KiBitmap( zoom_in_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Zoom out" ), g_Module_Viewer_Hokeys_Descr,
+ HK_ZOOM_OUT, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_VIEWER_ZOOM_OUT, wxEmptyString,
+ KiBitmap( zoom_out_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Redraw view" ), g_Module_Viewer_Hokeys_Descr,
+ HK_ZOOM_REDRAW );
+ m_mainToolBar->AddTool( ID_VIEWER_ZOOM_REDRAW, wxEmptyString,
+ KiBitmap( zoom_redraw_xpm ), msg );
+
+ msg = AddHotkeyName( _( "Zoom auto" ), g_Module_Viewer_Hokeys_Descr,
+ HK_ZOOM_AUTO );
+ m_mainToolBar->AddTool( ID_VIEWER_ZOOM_PAGE, wxEmptyString,
+ KiBitmap( zoom_fit_in_page_xpm ), msg );
+
+ if( IsModal() )
+ {
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_MODVIEW_FOOTPRINT_EXPORT_TO_BOARD, wxEmptyString,
+ KiBitmap( export_footprint_names_xpm ),
+ _( "Insert footprint in board" ) );
+ }
+
+ // after adding the buttons to the toolbar, must call Realize() to
+ // reflect the changes
+ m_mainToolBar->Realize();
+ }
+
+ m_mainToolBar->Refresh();
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::ReCreateVToolbar()
+{
+}
+
+
+// Virtual function
+void FOOTPRINT_VIEWER_FRAME::ReCreateMenuBar( void )
+{
+ // Create and try to get the current menubar
+ wxMenuBar* menuBar = GetMenuBar();
+
+ if( !menuBar )
+ menuBar = new wxMenuBar();
+
+ // Delete all existing menus so they can be rebuilt.
+ // This allows language changes of the menu text on the fly.
+ menuBar->Freeze();
+
+ while( menuBar->GetMenuCount() )
+ delete menuBar->Remove( 0 );
+
+ // Recreate all menus:
+ wxString text;
+
+ // Menu File:
+ wxMenu* fileMenu = new wxMenu;
+
+ // Active library selection
+ AddMenuItem( fileMenu, ID_MODVIEW_SELECT_LIB, _("Set Current Library"),
+ _( "Select library to be displayed" ), KiBitmap( open_library_xpm ) );
+ fileMenu->AppendSeparator();
+
+ // Close viewer
+ AddMenuItem( fileMenu, wxID_EXIT,
+ _( "Cl&ose" ),
+ _( "Close footprint viewer" ),
+ KiBitmap( exit_xpm ) );
+
+ // View menu
+ wxMenu* viewMenu = new wxMenu;
+
+ text = AddHotkeyName( _( "Zoom &In" ), g_Module_Viewer_Hokeys_Descr,
+ HK_ZOOM_IN, IS_ACCELERATOR );
+ AddMenuItem( viewMenu, ID_VIEWER_ZOOM_IN, text, HELP_ZOOM_IN, KiBitmap( zoom_in_xpm ) );
+
+ text = AddHotkeyName( _( "Zoom &Out" ), g_Module_Viewer_Hokeys_Descr,
+ HK_ZOOM_OUT, IS_ACCELERATOR );
+ AddMenuItem( viewMenu, ID_VIEWER_ZOOM_OUT, text, HELP_ZOOM_OUT, KiBitmap( zoom_out_xpm ) );
+
+ text = AddHotkeyName( _( "&Fit on Screen" ), g_Module_Viewer_Hokeys_Descr,
+ HK_ZOOM_AUTO );
+ AddMenuItem( viewMenu, ID_VIEWER_ZOOM_PAGE, text, HELP_ZOOM_FIT,
+ KiBitmap( zoom_fit_in_page_xpm ) );
+
+ text = AddHotkeyName( _( "&Redraw" ), g_Module_Viewer_Hokeys_Descr, HK_ZOOM_REDRAW );
+ AddMenuItem( viewMenu, ID_VIEWER_ZOOM_REDRAW, text,
+ HELP_ZOOM_REDRAW, KiBitmap( zoom_redraw_xpm ) );
+
+ viewMenu->AppendSeparator();
+
+ // 3D view
+ text = AddHotkeyName( _( "3&D Viewer" ), g_Module_Viewer_Hokeys_Descr, HK_3D_VIEWER );
+ AddMenuItem( viewMenu, ID_MODVIEW_SHOW_3D_VIEW, text, _( "Show footprint in 3D viewer" ),
+ KiBitmap( three_d_xpm ) );
+
+ // Menu Help:
+ wxMenu* helpMenu = new wxMenu;
+
+ // Version info
+ AddHelpVersionInfoMenuEntry( helpMenu );
+
+ // Contents
+ AddMenuItem( helpMenu, wxID_HELP,
+ _( "Pcbnew &Manual" ),
+ _( "Open the Pcbnew manual" ),
+ KiBitmap( online_help_xpm ) );
+
+ AddMenuItem( helpMenu, wxID_INDEX,
+ _( "&Getting Started in KiCad" ),
+ _( "Open the \"Getting Started in KiCad\" guide for beginners" ),
+ KiBitmap( help_xpm ) );
+
+ // About Pcbnew
+ helpMenu->AppendSeparator();
+ AddMenuItem( helpMenu, wxID_ABOUT,
+ _( "&About Pcbnew" ),
+ _( "About Pcbnew PCB designer" ),
+ KiBitmap( info_xpm ) );
+
+ // Append menus to the menubar
+ menuBar->Append( fileMenu, _( "&File" ) );
+
+ menuBar->Append( viewMenu, _( "&View" ) );
+ menuBar->Append( helpMenu, _( "&Help" ) );
+
+ menuBar->Thaw();
+
+ // Associate the menu bar with the frame, if no previous menubar
+ if( GetMenuBar() == NULL )
+ SetMenuBar( menuBar );
+ else
+ menuBar->Refresh();
+}
diff --git a/pcbnew/tool_onrightclick.cpp b/pcbnew/tool_onrightclick.cpp
new file mode 100644
index 0000000..c397575
--- /dev/null
+++ b/pcbnew/tool_onrightclick.cpp
@@ -0,0 +1,107 @@
+/**
+ * @file tool_onrightclick.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <pcbnew.h>
+#include <wxPcbStruct.h>
+#include <module_editor_frame.h>
+#include <dialog_design_rules.h>
+#include <pcbnew_id.h>
+
+
+void PCB_EDIT_FRAME::ToolOnRightClick( wxCommandEvent& event )
+{
+ wxPoint pos;
+ int id = event.GetSelection();
+
+ wxGetMousePosition( &pos.x, &pos.y );
+
+ switch( id )
+ {
+ case ID_TRACK_BUTT:
+ {
+ DIALOG_DESIGN_RULES dlg( this );
+
+ if( dlg.ShowModal() == wxID_OK )
+ {
+ ReCreateAuxiliaryToolbar();
+ }
+
+ break;
+ }
+
+ case ID_PCB_MODULE_BUTT:
+ break;
+
+ case ID_PCB_CIRCLE_BUTT:
+ case ID_PCB_ARC_BUTT:
+ case ID_PCB_ADD_LINE_BUTT:
+ case ID_PCB_DIMENSION_BUTT:
+ case ID_PCB_ADD_TEXT_BUTT:
+ OnConfigurePcbOptions( event );
+ break;
+
+ case ID_PCB_PLACE_GRID_COORD_BUTT:
+ InvokeDialogGrid();
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void FOOTPRINT_EDIT_FRAME::ToolOnRightClick( wxCommandEvent& event )
+{
+ wxPoint pos;
+ int id = event.GetSelection();
+
+ wxGetMousePosition( &pos.x, &pos.y );
+ pos.x -= 400;
+ pos.y -= 30;
+
+ switch( id )
+ {
+ case ID_MODEDIT_PAD_TOOL:
+ InstallPadOptionsFrame( NULL );
+ break;
+
+ case ID_MODEDIT_CIRCLE_TOOL:
+ case ID_MODEDIT_ARC_TOOL:
+ case ID_MODEDIT_LINE_TOOL:
+ case ID_MODEDIT_TEXT_TOOL:
+ InstallOptionsFrame( pos );
+ break;
+
+ default:
+ DisplayError( this, wxT( "ToolOnRightClick() error" ) );
+ break;
+ }
+}
diff --git a/pcbnew/tool_pcb.cpp b/pcbnew/tool_pcb.cpp
new file mode 100644
index 0000000..ee27942
--- /dev/null
+++ b/pcbnew/tool_pcb.cpp
@@ -0,0 +1,814 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012=2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file tool_pcb.cpp
+ * @brief PCB editor tool bars
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <help_common_strings.h>
+#include <dialog_helpers.h>
+#include <class_layer_box_selector.h>
+#include <colors_selection.h>
+#include <wxPcbStruct.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+
+#include <class_board.h>
+
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <hotkeys.h>
+#include <class_pcb_layer_box_selector.h>
+
+#include <wx/wupdlock.h>
+
+extern bool IsWxPythonLoaded();
+
+#define SEL_LAYER_HELP _( \
+ "Show active layer selections\nand select layer pair for route and place via" )
+
+
+/* Data to build the layer pair indicator button */
+static wxBitmap* LayerPairBitmap = NULL;
+
+#define BM_LAYERICON_SIZE 24
+static const char s_BitmapLayerIcon[BM_LAYERICON_SIZE][BM_LAYERICON_SIZE] =
+{
+ // 0 = draw pixel with active layer color
+ // 1 = draw pixel with top layer color (top/bottom layer used inautoroute and place via)
+ // 2 = draw pixel with bottom layer color
+ // 3 = draw pixel with via color
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0 },
+ { 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 0, 1, 1, 1, 1, 3, 3, 2, 2, 2, 2, 2, 2, 2 },
+ { 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 1, 1, 1, 1, 0, 3, 3, 2, 2, 2, 2, 2, 2, 2 },
+ { 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 1, 1, 1, 1, 0, 3, 3, 2, 2, 2, 2, 2, 2, 2 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1, 1, 1, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+};
+
+
+void PCB_EDIT_FRAME::PrepareLayerIndicator()
+{
+ int ii, jj;
+ EDA_COLOR_T active_layer_color, Route_Layer_TOP_color,
+ Route_Layer_BOTTOM_color, via_color;
+ bool change = false;
+ bool first_call = LayerPairBitmap == NULL;
+
+ static int previous_active_layer_color, previous_Route_Layer_TOP_color,
+ previous_Route_Layer_BOTTOM_color, previous_via_color;
+
+ /* get colors, and redraw bitmap button only on changes */
+ active_layer_color = GetBoard()->GetLayerColor(GetActiveLayer());
+
+ if( previous_active_layer_color != active_layer_color )
+ {
+ previous_active_layer_color = active_layer_color;
+ change = true;
+ }
+
+ Route_Layer_TOP_color =
+ g_ColorsSettings.GetLayerColor( GetScreen()->m_Route_Layer_TOP );
+
+ if( previous_Route_Layer_TOP_color != Route_Layer_TOP_color )
+ {
+ previous_Route_Layer_TOP_color = Route_Layer_TOP_color;
+ change = true;
+ }
+
+ Route_Layer_BOTTOM_color =
+ g_ColorsSettings.GetLayerColor( GetScreen()->m_Route_Layer_BOTTOM );
+
+ if( previous_Route_Layer_BOTTOM_color != Route_Layer_BOTTOM_color )
+ {
+ previous_Route_Layer_BOTTOM_color = Route_Layer_BOTTOM_color;
+ change = true;
+ }
+
+ int via_type = GetDesignSettings().m_CurrentViaType;
+ via_color = GetBoard()->GetVisibleElementColor(VIAS_VISIBLE+via_type);
+
+ if( previous_via_color != via_color )
+ {
+ previous_via_color = via_color;
+ change = true;
+ }
+
+ if( !change && (LayerPairBitmap != NULL) )
+ return;
+
+ /* Create the bitmap and its Memory DC, if not already made */
+ if( LayerPairBitmap == NULL )
+ {
+ LayerPairBitmap = new wxBitmap( 24, 24 );
+ }
+
+ /* Draw the icon, with colors according to the active layer and layer
+ * pairs for via command (change layer)
+ */
+ wxMemoryDC iconDC;
+ iconDC.SelectObject( *LayerPairBitmap );
+ wxPen pen;
+ int buttonColor = -1;
+
+ for( ii = 0; ii < BM_LAYERICON_SIZE; ii++ )
+ {
+ for( jj = 0; jj < BM_LAYERICON_SIZE; jj++ )
+ {
+ if( s_BitmapLayerIcon[ii][jj] != buttonColor )
+ {
+ switch( s_BitmapLayerIcon[ii][jj] )
+ {
+ default:
+ case 0:
+ pen.SetColour( MakeColour( active_layer_color ) );
+ break;
+
+ case 1:
+ pen.SetColour( MakeColour( Route_Layer_TOP_color) );
+ break;
+
+ case 2:
+ pen.SetColour( MakeColour( Route_Layer_BOTTOM_color ) );
+ break;
+
+ case 3:
+ pen.SetColour( MakeColour( via_color ) );
+ break;
+ }
+
+ buttonColor = s_BitmapLayerIcon[ii][jj];
+ iconDC.SetPen( pen );
+ }
+
+ iconDC.DrawPoint( jj, ii );
+ }
+ }
+
+ /* Deselect the Tool Bitmap from DC,
+ * in order to delete the MemoryDC safely without deleting the bitmap */
+ iconDC.SelectObject( wxNullBitmap );
+
+ if( m_mainToolBar && ! first_call )
+ {
+ m_mainToolBar->SetToolBitmap( ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR, *LayerPairBitmap );
+ m_mainToolBar->Refresh();
+ }
+}
+
+
+void PCB_EDIT_FRAME::ReCreateHToolbar()
+{
+ wxString msg;
+
+ if( m_mainToolBar )
+ return;
+
+ wxWindowUpdateLocker dummy( this );
+
+ m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
+
+ // Set up toolbar
+ if( Kiface().IsSingle() )
+ {
+ m_mainToolBar->AddTool( ID_NEW_BOARD, wxEmptyString, KiBitmap( new_pcb_xpm ),
+ _( "New board" ) );
+ m_mainToolBar->AddTool( ID_LOAD_FILE, wxEmptyString, KiBitmap( open_brd_file_xpm ),
+ _( "Open existing board" ) );
+ }
+
+ m_mainToolBar->AddTool( ID_SAVE_BOARD, wxEmptyString, KiBitmap( save_xpm ),
+ _( "Save board" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_SHEET_SET, wxEmptyString, KiBitmap( sheetset_xpm ),
+ _( "Page settings for paper size and texts" ) );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_OPEN_MODULE_EDITOR, wxEmptyString,
+ KiBitmap( module_editor_xpm ),
+ _( "Open footprint editor" ) );
+
+ m_mainToolBar->AddTool( ID_OPEN_MODULE_VIEWER, wxEmptyString,
+ KiBitmap( modview_icon_xpm ),
+ _( "Open footprint viewer" ) );
+
+ m_mainToolBar->AddSeparator();
+ msg = AddHotkeyName( HELP_UNDO, g_Board_Editor_Hokeys_Descr, HK_UNDO, IS_COMMENT );
+ m_mainToolBar->AddTool( wxID_UNDO, wxEmptyString, KiBitmap( undo_xpm ), msg );
+ msg = AddHotkeyName( HELP_REDO, g_Board_Editor_Hokeys_Descr, HK_REDO, IS_COMMENT );
+ m_mainToolBar->AddTool( wxID_REDO, wxEmptyString, KiBitmap( redo_xpm ), msg );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( wxID_PRINT, wxEmptyString, KiBitmap( print_button_xpm ),
+ _( "Print board" ) );
+ m_mainToolBar->AddTool( ID_GEN_PLOT, wxEmptyString, KiBitmap( plot_xpm ),
+ _( "Plot (HPGL, PostScript, or GERBER format)" ) );
+
+ m_mainToolBar->AddSeparator();
+ msg = AddHotkeyName( HELP_ZOOM_IN, g_Board_Editor_Hokeys_Descr, HK_ZOOM_IN, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_IN, wxEmptyString, KiBitmap( zoom_in_xpm ), msg );
+
+ msg = AddHotkeyName( HELP_ZOOM_OUT, g_Board_Editor_Hokeys_Descr, HK_ZOOM_OUT, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_OUT, wxEmptyString, KiBitmap( zoom_out_xpm ), msg );
+
+ msg = AddHotkeyName( HELP_ZOOM_REDRAW, g_Board_Editor_Hokeys_Descr, HK_ZOOM_REDRAW,
+ IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_REDRAW, wxEmptyString, KiBitmap( zoom_redraw_xpm ), msg );
+
+ msg = AddHotkeyName( HELP_ZOOM_FIT, g_Board_Editor_Hokeys_Descr, HK_ZOOM_AUTO, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ), msg );
+
+ m_mainToolBar->AddSeparator();
+ msg = AddHotkeyName( HELP_FIND, g_Board_Editor_Hokeys_Descr, HK_FIND_ITEM, IS_COMMENT );
+ m_mainToolBar->AddTool( ID_FIND_ITEMS, wxEmptyString, KiBitmap( find_xpm ), msg );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_GET_NETLIST, wxEmptyString, KiBitmap( netlist_xpm ),
+ _( "Read netlist" ) );
+ m_mainToolBar->AddTool( ID_DRC_CONTROL, wxEmptyString, KiBitmap( erc_xpm ),
+ _( "Perform design rules check" ) );
+
+ m_mainToolBar->AddSeparator();
+
+ if( m_SelLayerBox == NULL )
+ {
+ m_SelLayerBox = new PCB_LAYER_BOX_SELECTOR( m_mainToolBar, ID_TOOLBARH_PCB_SELECT_LAYER );
+ m_SelLayerBox->SetBoardFrame( this );
+ }
+
+ ReCreateLayerBox( false );
+ m_mainToolBar->AddControl( m_SelLayerBox );
+
+ PrepareLayerIndicator(); // Initialize the bitmap with current
+ // active layer colors for the next tool
+ m_mainToolBar->AddTool( ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR, wxEmptyString,
+ *LayerPairBitmap, SEL_LAYER_HELP );
+
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_TOOLBARH_PCB_MODE_MODULE, wxEmptyString, KiBitmap( mode_module_xpm ),
+ _( "Mode footprint: manual and automatic movement and placement" ),
+ wxITEM_CHECK );
+ m_mainToolBar->AddTool( ID_TOOLBARH_PCB_MODE_TRACKS, wxEmptyString, KiBitmap( mode_track_xpm ),
+ _( "Mode track: autorouting" ), wxITEM_CHECK );
+
+ // Fast call to FreeROUTE Web Bases router
+ m_mainToolBar->AddSeparator();
+ m_mainToolBar->AddTool( ID_TOOLBARH_PCB_FREEROUTE_ACCESS, wxEmptyString,
+ KiBitmap( web_support_xpm ),
+ _( "Fast access to the FreeROUTE external advanced router" ) );
+
+ // Access to the scripting console
+#if defined(KICAD_SCRIPTING_WXPYTHON)
+ if( IsWxPythonLoaded() )
+ {
+ m_mainToolBar->AddSeparator();
+
+ m_mainToolBar->AddTool( ID_TOOLBARH_PCB_SCRIPTING_CONSOLE, wxEmptyString,
+ KiBitmap( py_script_xpm ),
+ _( "Show/Hide the Python Scripting console" ),
+ wxITEM_CHECK );
+ }
+#endif
+
+ // after adding the buttons to the toolbar, must call Realize() to reflect the changes
+ m_mainToolBar->Realize();
+}
+
+
+void PCB_EDIT_FRAME::ReCreateOptToolbar()
+{
+ if( m_optionsToolBar )
+ return;
+
+ wxWindowUpdateLocker dummy( this );
+
+ m_optionsToolBar = new wxAuiToolBar( this, ID_OPT_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_DRC_OFF, wxEmptyString, KiBitmap( drc_off_xpm ),
+ _( "Enable design rule checking" ), wxITEM_CHECK );
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GRID, wxEmptyString, KiBitmap( grid_xpm ),
+ _( "Hide grid" ), wxITEM_CHECK );
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_POLAR_COORD, wxEmptyString,
+ KiBitmap( polar_coord_xpm ),
+ _( "Display polar coordinates" ), wxITEM_CHECK );
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_INCH, wxEmptyString,
+ KiBitmap( unit_inch_xpm ),
+ _( "Units in inches" ), wxITEM_CHECK );
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_MM, wxEmptyString,
+ KiBitmap( unit_mm_xpm ),
+ _( "Units in millimeters" ), wxITEM_CHECK );
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_CURSOR, wxEmptyString,
+ KiBitmap( cursor_shape_xpm ),
+ _( "Change cursor shape" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_RATSNEST, wxEmptyString,
+ KiBitmap( general_ratsnest_xpm ),
+ _( "Show board ratsnest" ), wxITEM_CHECK );
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_MODULE_RATSNEST, wxEmptyString,
+ KiBitmap( local_ratsnest_xpm ),
+ _( "Show footprint ratsnest when moving" ),
+ wxITEM_CHECK );
+
+ m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_AUTO_DEL_TRACK, wxEmptyString,
+ KiBitmap( auto_delete_track_xpm ),
+ _( "Enable automatic track deletion" ),
+ wxITEM_CHECK );
+
+ m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_ZONES, wxEmptyString, KiBitmap( show_zone_xpm ),
+ _( "Show filled areas in zones" ), wxITEM_CHECK );
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_ZONES_DISABLE, wxEmptyString,
+ KiBitmap( show_zone_disable_xpm ),
+ _( "Do not show filled areas in zones" ) , wxITEM_CHECK );
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY, wxEmptyString,
+ KiBitmap( show_zone_outline_only_xpm ),
+ _( "Show outlines of filled areas only in zones" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_PADS_SKETCH, wxEmptyString,
+ KiBitmap( pad_sketch_xpm ),
+ _( "Show pads in outline mode" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_VIAS_SKETCH, wxEmptyString,
+ KiBitmap( via_sketch_xpm ),
+ _( "Show vias in outline mode" ), wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_TRACKS_SKETCH, wxEmptyString,
+ KiBitmap( showtrack_xpm ),
+ _( "Show tracks in outline mode" ),
+ wxITEM_CHECK );
+
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE, wxEmptyString,
+ KiBitmap( contrast_mode_xpm ),
+ _( "Enable high contrast display mode" ),
+ wxITEM_CHECK );
+
+ // Tools to show/hide toolbars:
+ m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_MANAGE_LAYERS_VERTICAL_TOOLBAR,
+ wxEmptyString,
+ KiBitmap( layers_manager_xpm ),
+ HELP_SHOW_HIDE_LAYERMANAGER,
+ wxITEM_CHECK );
+ m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE,
+ wxEmptyString,
+ KiBitmap( mw_toolbar_xpm ),
+ HELP_SHOW_HIDE_MICROWAVE_TOOLS,
+ wxITEM_CHECK );
+
+
+ m_optionsToolBar->AddSeparator();
+ m_optionsToolBar->Realize();
+}
+
+
+void PCB_EDIT_FRAME::ReCreateVToolbar()
+{
+ if( m_drawToolBar )
+ return;
+
+ wxWindowUpdateLocker dummy( this );
+
+ m_drawToolBar = new wxAuiToolBar( this, ID_V_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
+
+ // Set up toolbar
+ m_drawToolBar->AddTool( ID_NO_TOOL_SELECTED, wxEmptyString, KiBitmap( cursor_xpm ),
+ wxEmptyString, wxITEM_CHECK );
+ m_drawToolBar->AddSeparator();
+
+ m_drawToolBar->AddTool( ID_PCB_HIGHLIGHT_BUTT, wxEmptyString, KiBitmap( net_highlight_xpm ),
+ _( "Highlight net" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_PCB_SHOW_1_RATSNEST_BUTT, wxEmptyString,
+ KiBitmap( tool_ratsnest_xpm ),
+ _( "Display local ratsnest" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddSeparator();
+ m_drawToolBar->AddTool( ID_PCB_MODULE_BUTT, wxEmptyString, KiBitmap( module_xpm ),
+ _( "Add footprints" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_TRACK_BUTT, wxEmptyString, KiBitmap( add_tracks_xpm ),
+ _( "Add tracks and vias" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_PCB_ZONES_BUTT, wxEmptyString, KiBitmap( add_zone_xpm ),
+ _( "Add filled zones" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_PCB_KEEPOUT_AREA_BUTT, wxEmptyString,
+ KiBitmap( add_keepout_area_xpm ),
+ _( "Add keepout areas" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddSeparator();
+ m_drawToolBar->AddTool( ID_PCB_ADD_LINE_BUTT, wxEmptyString, KiBitmap( add_dashed_line_xpm ),
+ _( "Add graphic line or polygon" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_PCB_CIRCLE_BUTT, wxEmptyString, KiBitmap( add_circle_xpm ),
+ _( "Add graphic circle" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_PCB_ARC_BUTT, wxEmptyString, KiBitmap( add_arc_xpm ),
+ _( "Add graphic arc" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_PCB_ADD_TEXT_BUTT, wxEmptyString, KiBitmap( add_text_xpm ),
+ _( "Add text on copper layers or graphic text" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddSeparator();
+ m_drawToolBar->AddTool( ID_PCB_DIMENSION_BUTT, wxEmptyString, KiBitmap( add_dimension_xpm ),
+ _( "Add dimension" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_PCB_MIRE_BUTT, wxEmptyString, KiBitmap( add_mires_xpm ),
+ _( "Add layer alignment target" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddSeparator();
+ m_drawToolBar->AddTool( ID_PCB_DELETE_ITEM_BUTT, wxEmptyString, KiBitmap( delete_xpm ),
+ _( "Delete items" ), wxITEM_CHECK );
+
+ m_drawToolBar->AddSeparator();
+ m_drawToolBar->AddTool( ID_PCB_PLACE_OFFSET_COORD_BUTT, wxEmptyString,
+ KiBitmap( pcb_offset_xpm ),
+ _( "Place the origin point for drill and place files" ),
+ wxITEM_CHECK );
+
+ m_drawToolBar->AddTool( ID_PCB_PLACE_GRID_COORD_BUTT, wxEmptyString,
+ KiBitmap( grid_select_axis_xpm ),
+ _( "Set the origin point for the grid" ),
+ wxITEM_CHECK );
+
+ m_drawToolBar->Realize();
+}
+
+
+/* Create the auxiliary vertical right toolbar, showing tools for microwave applications
+ */
+void PCB_EDIT_FRAME::ReCreateMicrowaveVToolbar()
+{
+ if( m_microWaveToolBar )
+ return;
+
+ wxWindowUpdateLocker dummy(this);
+
+ m_microWaveToolBar = new wxAuiToolBar( this, ID_MICROWAVE_V_TOOLBAR, wxDefaultPosition,
+ wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
+
+ // Set up toolbar
+ m_microWaveToolBar->AddTool( ID_PCB_MUWAVE_TOOL_SELF_CMD, wxEmptyString,
+ KiBitmap( mw_add_line_xpm ),
+ _( "Create line of specified length for microwave applications" ),
+ wxITEM_CHECK );
+
+ m_microWaveToolBar->AddTool( ID_PCB_MUWAVE_TOOL_GAP_CMD, wxEmptyString,
+ KiBitmap( mw_add_gap_xpm ),
+ _( "Create gap of specified length for microwave applications" ),
+ wxITEM_CHECK );
+
+ m_microWaveToolBar->AddSeparator();
+
+ m_microWaveToolBar->AddTool( ID_PCB_MUWAVE_TOOL_STUB_CMD, wxEmptyString,
+ KiBitmap( mw_add_stub_xpm ),
+ _( "Create stub of specified length for microwave applications" ),
+ wxITEM_CHECK );
+
+ m_microWaveToolBar->AddTool( ID_PCB_MUWAVE_TOOL_STUB_ARC_CMD, wxEmptyString,
+ KiBitmap( mw_add_stub_arc_xpm ),
+ _( "Create stub (arc) of specified length for microwave applications" ),
+ wxITEM_CHECK );
+
+ m_microWaveToolBar->AddTool( ID_PCB_MUWAVE_TOOL_FUNCTION_SHAPE_CMD, wxEmptyString,
+ KiBitmap( mw_add_shape_xpm ),
+ _( "Create a polynomial shape for microwave applications" ),
+ wxITEM_CHECK );
+
+ m_microWaveToolBar->Realize();
+}
+
+
+void PCB_EDIT_FRAME::ReCreateAuxiliaryToolbar()
+{
+ wxWindowUpdateLocker dummy( this );
+
+ if( m_auxiliaryToolBar )
+ {
+ updateTraceWidthSelectBox();
+ updateViaSizeSelectBox();
+
+ // combobox sizes can have changed: apply new best sizes
+ wxAuiToolBarItem* item = m_auxiliaryToolBar->FindTool( ID_AUX_TOOLBAR_PCB_TRACK_WIDTH );
+ item->SetMinSize( m_SelTrackWidthBox->GetBestSize() );
+ item = m_auxiliaryToolBar->FindTool( ID_AUX_TOOLBAR_PCB_VIA_SIZE );
+ item->SetMinSize( m_SelViaSizeBox->GetBestSize() );
+
+ m_auxiliaryToolBar->Realize();
+ m_auimgr.Update();
+ return;
+ }
+
+ m_auxiliaryToolBar = new wxAuiToolBar( this, ID_AUX_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
+
+ /* Set up toolbar items */
+
+ // Creates box to display and choose tracks widths:
+ m_SelTrackWidthBox = new wxChoice( m_auxiliaryToolBar,
+ ID_AUX_TOOLBAR_PCB_TRACK_WIDTH,
+ wxDefaultPosition, wxDefaultSize,
+ 0, NULL );
+ updateTraceWidthSelectBox();
+ m_auxiliaryToolBar->AddControl( m_SelTrackWidthBox );
+
+ // Creates box to display and choose vias diameters:
+ m_SelViaSizeBox = new wxChoice( m_auxiliaryToolBar,
+ ID_AUX_TOOLBAR_PCB_VIA_SIZE,
+ wxDefaultPosition, wxDefaultSize,
+ 0, NULL );
+ updateViaSizeSelectBox();
+ m_auxiliaryToolBar->AddControl( m_SelViaSizeBox );
+ m_auxiliaryToolBar->AddSeparator();
+
+ // Creates box to display and choose strategy to handle tracks an vias sizes:
+ m_auxiliaryToolBar->AddTool( ID_AUX_TOOLBAR_PCB_SELECT_AUTO_WIDTH,
+ wxEmptyString,
+ KiBitmap( auto_track_width_xpm ),
+ _( "Auto track width: when starting on an existing track "
+ "use its width\notherwise, use current width setting" ),
+ wxITEM_CHECK );
+
+ // Add the box to display and select the current grid size:
+ m_auxiliaryToolBar->AddSeparator();
+ m_gridSelectBox = new wxChoice( m_auxiliaryToolBar,
+ ID_ON_GRID_SELECT,
+ wxDefaultPosition, wxDefaultSize,
+ 0, NULL );
+ updateGridSelectBox();
+ m_auxiliaryToolBar->AddControl( m_gridSelectBox );
+
+ // Add the box to display and select the current Zoom
+ m_auxiliaryToolBar->AddSeparator();
+ m_zoomSelectBox = new wxChoice( m_auxiliaryToolBar,
+ ID_ON_ZOOM_SELECT,
+ wxDefaultPosition, wxDefaultSize,
+ 0, NULL );
+ updateZoomSelectBox();
+ m_auxiliaryToolBar->AddControl( m_zoomSelectBox );
+
+ // after adding the buttons to the toolbar, must call Realize()
+ m_auxiliaryToolBar->Realize();
+}
+
+
+void PCB_EDIT_FRAME::updateTraceWidthSelectBox()
+{
+ if( m_SelTrackWidthBox == NULL )
+ return;
+
+ wxString msg;
+ bool mmFirst = g_UserUnit != INCHES;
+
+ m_SelTrackWidthBox->Clear();
+
+ for( unsigned ii = 0; ii < GetDesignSettings().m_TrackWidthList.size(); ii++ )
+ {
+ int size = GetDesignSettings().m_TrackWidthList[ii];
+
+ double valueMils = To_User_Unit( INCHES, size ) * 1000;
+ double value_mm = To_User_Unit( MILLIMETRES, size );
+
+ if( mmFirst )
+ msg.Printf( _( "Track: %.3f mm (%.2f mils)" ),
+ value_mm, valueMils );
+ else
+ msg.Printf( _( "Track: %.2f mils (%.3f mm)" ),
+ valueMils, value_mm );
+
+ // Mark the netclass track width value (the first in list)
+ if( ii == 0 )
+ msg << wxT( " *" );
+
+ m_SelTrackWidthBox->Append( msg );
+ }
+
+ if( GetDesignSettings().GetTrackWidthIndex() >= GetDesignSettings().m_TrackWidthList.size() )
+ GetDesignSettings().SetTrackWidthIndex( 0 );
+
+ m_SelTrackWidthBox->SetSelection( GetDesignSettings().GetTrackWidthIndex() );
+}
+
+
+void PCB_EDIT_FRAME::updateViaSizeSelectBox()
+{
+ if( m_SelViaSizeBox == NULL )
+ return;
+
+ wxString msg;
+
+ m_SelViaSizeBox->Clear();
+ bool mmFirst = g_UserUnit != INCHES;
+
+ for( unsigned ii = 0; ii < GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
+ {
+ int diam = GetDesignSettings().m_ViasDimensionsList[ii].m_Diameter;
+
+ double valueMils = To_User_Unit( INCHES, diam ) * 1000;
+ double value_mm = To_User_Unit( MILLIMETRES, diam );
+
+ if( mmFirst )
+ msg.Printf( _( "Via: %.2f mm (%.1f mils)" ),
+ value_mm, valueMils );
+ else
+ msg.Printf( _( "Via: %.1f mils (%.2f mm)" ),
+ valueMils, value_mm );
+
+ int hole = GetDesignSettings().m_ViasDimensionsList[ii].m_Drill;
+
+ if( hole )
+ {
+ msg << wxT("/ ");
+ wxString hole_str;
+ double valueMils = To_User_Unit( INCHES, hole ) * 1000;
+ double value_mm = To_User_Unit( MILLIMETRES, hole );
+
+ if( mmFirst )
+ hole_str.Printf( _( "%.2f mm (%.1f mils)" ),
+ value_mm, valueMils );
+ else
+ hole_str.Printf( _( "%.1f mils (%.2f mm)" ),
+ valueMils, value_mm );
+
+ msg += hole_str;
+ }
+
+ // Mark the netclass via size value (the first in list)
+ if( ii == 0 )
+ msg << wxT( " *" );
+
+ m_SelViaSizeBox->Append( msg );
+ }
+
+ if( GetDesignSettings().GetViaSizeIndex() >= GetDesignSettings().m_ViasDimensionsList.size() )
+ GetDesignSettings().SetViaSizeIndex( 0 );
+
+ m_SelViaSizeBox->SetSelection( GetDesignSettings().GetViaSizeIndex() );
+}
+
+
+void PCB_EDIT_FRAME::ReCreateLayerBox( bool aForceResizeToolbar )
+{
+ if( m_SelLayerBox == NULL || m_mainToolBar == NULL )
+ return;
+
+ m_SelLayerBox->SetToolTip( _( "+/- to switch" ) );
+ m_SelLayerBox->m_hotkeys = g_Board_Editor_Hokeys_Descr;
+ m_SelLayerBox->Resync();
+
+ if( aForceResizeToolbar )
+ {
+ // the layer box can have its size changed
+ // Update the aui manager, to take in account the new size
+ m_auimgr.Update();
+ }
+}
+
+
+void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ bool state = event.IsChecked();
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ switch( id )
+ {
+ case ID_TB_OPTIONS_DRC_OFF:
+ g_Drc_On = !state;
+
+ if( GetToolId() == ID_TRACK_BUTT )
+ {
+ if( g_Drc_On )
+ m_canvas->SetCursor( wxCURSOR_PENCIL );
+ else
+ m_canvas->SetCursor( wxCURSOR_QUESTION_ARROW );
+ }
+ break;
+
+ case ID_TB_OPTIONS_SHOW_RATSNEST:
+ SetElementVisibility( RATSNEST_VISIBLE, state );
+ OnModify();
+
+ if( state && (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
+ Compile_Ratsnest( NULL, true );
+
+ m_canvas->Refresh();
+ break;
+
+ case ID_TB_OPTIONS_SHOW_MODULE_RATSNEST:
+ displ_opts->m_Show_Module_Ratsnest = state; // TODO: see if we can use the visibility list
+ break;
+
+ case ID_TB_OPTIONS_AUTO_DEL_TRACK:
+ g_AutoDeleteOldTrack = state;
+ break;
+
+ case ID_TB_OPTIONS_SHOW_ZONES:
+ displ_opts->m_DisplayZonesMode = 0;
+ m_canvas->Refresh();
+ break;
+
+ case ID_TB_OPTIONS_SHOW_ZONES_DISABLE:
+ displ_opts->m_DisplayZonesMode = 1;
+ m_canvas->Refresh();
+ break;
+
+ case ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY:
+ displ_opts->m_DisplayZonesMode = 2;
+ m_canvas->Refresh();
+ break;
+
+ case ID_TB_OPTIONS_SHOW_VIAS_SKETCH:
+ displ_opts->m_DisplayViaFill = !state;
+ m_canvas->Refresh();
+ break;
+
+ case ID_TB_OPTIONS_SHOW_TRACKS_SKETCH:
+ displ_opts->m_DisplayPcbTrackFill = !state;
+ m_canvas->Refresh();
+ break;
+
+ case ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE:
+ {
+ displ_opts->m_ContrastModeDisplay = state;
+ m_canvas->Refresh();
+ break;
+ }
+
+ case ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE:
+ m_show_microwave_tools = state;
+ m_auimgr.GetPane( wxT( "m_microWaveToolBar" ) ).Show( m_show_microwave_tools );
+ m_auimgr.Update();
+
+ GetMenuBar()->SetLabel( ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR,
+ m_show_microwave_tools ?
+ _( "Hide Microwave Toolbar" ): _( "Show Microwave Toolbar" ));
+ break;
+
+ case ID_TB_OPTIONS_SHOW_MANAGE_LAYERS_VERTICAL_TOOLBAR:
+ // show auxiliary Vertical layers and visibility manager toolbar
+ m_show_layer_manager_tools = state;
+ m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( m_show_layer_manager_tools );
+ m_auimgr.Update();
+
+ GetMenuBar()->SetLabel( ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
+ m_show_layer_manager_tools ?
+ _( "Hide &Layers Manager" ) : _( "Show &Layers Manager" ) );
+ break;
+
+ default:
+ DisplayError( this,
+ wxT( "PCB_EDIT_FRAME::OnSelectOptionToolbar error \n (event not handled!)" ) );
+ break;
+ }
+}
diff --git a/pcbnew/toolbars_update_user_interface.cpp b/pcbnew/toolbars_update_user_interface.cpp
new file mode 100644
index 0000000..8bd2aaf
--- /dev/null
+++ b/pcbnew/toolbars_update_user_interface.cpp
@@ -0,0 +1,241 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2012-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file toolbars_update_user_interface.cpp
+ * @brief Function to update toolbars UI after changing parameters.
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+#include <3d_viewer.h>
+#include <dialog_helpers.h>
+#include <class_board.h>
+#include <pcbnew.h>
+#include <pcbnew_id.h>
+#include <drc_stuff.h>
+#include <class_pcb_layer_box_selector.h>
+
+
+void PCB_EDIT_FRAME::OnUpdateLayerPair( wxUpdateUIEvent& aEvent )
+{
+ PrepareLayerIndicator();
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateSelectTrackWidth( wxUpdateUIEvent& aEvent )
+{
+ if( aEvent.GetId() == ID_AUX_TOOLBAR_PCB_TRACK_WIDTH )
+ {
+ if( m_SelTrackWidthBox->GetSelection() != (int) GetDesignSettings().GetTrackWidthIndex() )
+ m_SelTrackWidthBox->SetSelection( GetDesignSettings().GetTrackWidthIndex() );
+ }
+ else
+ {
+ bool check = ( ( ( ID_POPUP_PCB_SELECT_WIDTH1 +
+ (int) GetDesignSettings().GetTrackWidthIndex() ) == aEvent.GetId() ) &&
+ !GetDesignSettings().m_UseConnectedTrackWidth &&
+ !GetDesignSettings().UseCustomTrackViaSize() );
+
+ aEvent.Check( check );
+ }
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateSelectAutoTrackWidth( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( GetDesignSettings().m_UseConnectedTrackWidth &&
+ !GetDesignSettings().UseCustomTrackViaSize() );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateSelectCustomTrackWidth( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( GetDesignSettings().UseCustomTrackViaSize() );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateSelectViaSize( wxUpdateUIEvent& aEvent )
+{
+ if( aEvent.GetId() == ID_AUX_TOOLBAR_PCB_VIA_SIZE )
+ {
+ if( m_SelViaSizeBox->GetSelection() != (int) GetDesignSettings().GetViaSizeIndex() )
+ m_SelViaSizeBox->SetSelection( GetDesignSettings().GetViaSizeIndex() );
+ }
+ else
+ {
+ bool check = ( ( ( ID_POPUP_PCB_SELECT_VIASIZE1 +
+ (int) GetDesignSettings().GetViaSizeIndex() ) == aEvent.GetId() ) &&
+ !GetDesignSettings().m_UseConnectedTrackWidth &&
+ !GetDesignSettings().UseCustomTrackViaSize() );
+
+ aEvent.Check( check );
+ }
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent )
+{
+ m_SelLayerBox->SetLayerSelection( GetActiveLayer() );
+}
+
+// Used only when the DKICAD_SCRIPTING_WXPYTHON option is on
+void PCB_EDIT_FRAME::OnUpdateScriptingConsoleState( wxUpdateUIEvent& aEvent )
+{
+ wxMiniFrame * pythonPanelFrame = (wxMiniFrame *) findPythonConsole();
+ bool pythonPanelShown = pythonPanelFrame ? pythonPanelFrame->IsShown() : false;
+ aEvent.Check( pythonPanelShown );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateZoneDisplayStyle( wxUpdateUIEvent& aEvent )
+{
+ int selected = aEvent.GetId() - ID_TB_OPTIONS_SHOW_ZONES;
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+
+ if( aEvent.IsChecked() && ( displ_opts->m_DisplayZonesMode == selected ) )
+ return;
+
+ aEvent.Check( displ_opts->m_DisplayZonesMode == selected );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateDrcEnable( wxUpdateUIEvent& aEvent )
+{
+ bool state = !g_Drc_On;
+ aEvent.Check( state );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_DRC_OFF,
+ g_Drc_On ?
+ _( "Disable design rule checking" ) :
+ _( "Enable design rule checking" ) );
+}
+
+void PCB_EDIT_FRAME::OnUpdateShowBoardRatsnest( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_SHOW_RATSNEST,
+ GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) ?
+ _( "Hide board ratsnest" ) :
+ _( "Show board ratsnest" ) );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateShowModuleRatsnest( wxUpdateUIEvent& aEvent )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+ aEvent.Check( displ_opts->m_Show_Module_Ratsnest );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_SHOW_MODULE_RATSNEST,
+ displ_opts->m_Show_Module_Ratsnest ?
+ _( "Hide footprint ratsnest" ) :
+ _( "Show footprint ratsnest" ) );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateAutoDeleteTrack( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( g_AutoDeleteOldTrack );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_AUTO_DEL_TRACK,
+ g_AutoDeleteOldTrack ?
+ _( "Disable auto delete old track" ) :
+ _( "Enable auto delete old track" ) );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateViaDrawMode( wxUpdateUIEvent& aEvent )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+ aEvent.Check( !displ_opts->m_DisplayViaFill );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_SHOW_VIAS_SKETCH,
+ displ_opts->m_DisplayViaFill ?
+ _( "Show vias in outline mode" ) :
+ _( "Show vias in fill mode" ) );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateTraceDrawMode( wxUpdateUIEvent& aEvent )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+ aEvent.Check( !displ_opts->m_DisplayPcbTrackFill );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_SHOW_TRACKS_SKETCH,
+ displ_opts->m_DisplayPcbTrackFill ?
+ _( "Show tracks in outline mode" ) :
+ _( "Show tracks in fill mode" ) );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateHighContrastDisplayMode( wxUpdateUIEvent& aEvent )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
+ aEvent.Check( displ_opts->m_ContrastModeDisplay );
+ m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE,
+ displ_opts->m_ContrastModeDisplay ?
+ _( "Normal contrast display mode" ) :
+ _( "High contrast display mode" ) );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateShowLayerManager( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).IsShown() );
+}
+
+void PCB_EDIT_FRAME::OnUpdateShowMicrowaveToolbar( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Check( m_auimgr.GetPane( wxT( "m_microWaveToolBar" ) ).IsShown() );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateSave( wxUpdateUIEvent& aEvent )
+{
+ aEvent.Enable( GetScreen()->IsModify() );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateVerticalToolbar( wxUpdateUIEvent& aEvent )
+{
+ if( aEvent.GetEventObject() == m_drawToolBar )
+ aEvent.Check( GetToolId() == aEvent.GetId() );
+}
+
+void PCB_EDIT_FRAME::OnUpdateMuWaveToolbar( wxUpdateUIEvent& aEvent )
+{
+ if( aEvent.GetEventObject() == m_microWaveToolBar )
+ aEvent.Check( GetToolId() == aEvent.GetId() );
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateAutoPlaceTracksMode( wxUpdateUIEvent& aEvent )
+{
+ //Nothing to do.
+}
+
+
+void PCB_EDIT_FRAME::OnUpdateAutoPlaceModulesMode( wxUpdateUIEvent& aEvent )
+{
+ //Nothing to do.
+}
diff --git a/pcbnew/tools/bright_box.cpp b/pcbnew/tools/bright_box.cpp
new file mode 100644
index 0000000..7901de2
--- /dev/null
+++ b/pcbnew/tools/bright_box.cpp
@@ -0,0 +1,61 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "bright_box.h"
+#include <gal/graphics_abstraction_layer.h>
+#include <class_track.h>
+
+using namespace KIGFX;
+
+const double BRIGHT_BOX::LINE_WIDTH = 100000.0;
+const COLOR4D BRIGHT_BOX::BOX_COLOR = KIGFX::COLOR4D( 0.0, 1.0, 0.0, 1.0 );
+
+BRIGHT_BOX::BRIGHT_BOX( BOARD_ITEM* aItem ) :
+ EDA_ITEM( NOT_USED ), // this item is never added to a BOARD so it needs no type
+ m_item( aItem )
+{
+}
+
+
+void BRIGHT_BOX::ViewDraw( int aLayer, GAL* aGal ) const
+{
+ aGal->SetIsStroke( true );
+ aGal->SetIsFill( false );
+ aGal->SetLineWidth( LINE_WIDTH );
+ aGal->SetStrokeColor( BOX_COLOR );
+
+ if( m_item->Type() == PCB_TRACE_T )
+ {
+ const TRACK* track = static_cast<const TRACK*>( m_item );
+
+ aGal->DrawSegment( track->GetStart(), track->GetEnd(), track->GetWidth() );
+ }
+ else
+ {
+ BOX2I box = m_item->ViewBBox();
+
+ aGal->DrawRectangle( box.GetOrigin(), box.GetOrigin() + box.GetSize() );
+ }
+}
+
diff --git a/pcbnew/tools/bright_box.h b/pcbnew/tools/bright_box.h
new file mode 100644
index 0000000..fc9aeee
--- /dev/null
+++ b/pcbnew/tools/bright_box.h
@@ -0,0 +1,79 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __BRIGHT_BOX_H
+#define __BRIGHT_BOX_H
+
+#include <math/box2.h>
+#include <view/view.h>
+#include <class_board_item.h>
+#include <layers_id_colors_and_visibility.h>
+#include <gal/color4d.h>
+
+/**
+ * Class BRIGHT_BOX
+ *
+ * Draws a decoration to indicate a brightened item.
+ */
+class BRIGHT_BOX : public EDA_ITEM
+{
+public:
+ BRIGHT_BOX( BOARD_ITEM* aItem );
+ ~BRIGHT_BOX() {};
+
+ virtual const BOX2I ViewBBox() const
+ {
+ return m_item->ViewBBox();
+ }
+
+ void ViewDraw( int aLayer, KIGFX::GAL* aGal ) const;
+
+ void ViewGetLayers( int aLayers[], int& aCount ) const
+ {
+ aLayers[0] = ITEM_GAL_LAYER( GP_OVERLAY );
+ aCount = 1;
+ }
+
+#if defined(DEBUG)
+ void Show( int x, std::ostream& st ) const
+ {
+ }
+#endif
+
+ /** Get class name
+ * @return string "BRIGHT_BOX"
+ */
+ virtual wxString GetClass() const
+ {
+ return wxT( "BRIGHT_BOX" );
+ }
+
+private:
+ static const KIGFX::COLOR4D BOX_COLOR;
+ static const double LINE_WIDTH;
+
+ BOARD_ITEM* m_item;
+};
+
+#endif
diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp
new file mode 100644
index 0000000..f452719
--- /dev/null
+++ b/pcbnew/tools/common_actions.cpp
@@ -0,0 +1,726 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013-2016 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "common_actions.h"
+#include <tool/action_manager.h>
+#include <pcbnew_id.h>
+#include <layers_id_colors_and_visibility.h>
+#include <bitmaps.h>
+#include <wx/defs.h>
+#include <hotkeys.h>
+
+// These members are static in class COMMON_ACTIONS: Build them here:
+
+// Selection tool actions
+TOOL_ACTION COMMON_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection",
+ AS_GLOBAL, 0,
+ "", "", NULL, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
+
+TOOL_ACTION COMMON_ACTIONS::selectionCursor( "pcbnew.InteractiveSelection.Cursor",
+ AS_GLOBAL, 0,
+ "", "" ); // No description, it is not supposed to be shown anywhere
+
+TOOL_ACTION COMMON_ACTIONS::selectItem( "pcbnew.InteractiveSelection.SelectItem",
+ AS_GLOBAL, 0,
+ "", "" ); // No description, it is not supposed to be shown anywhere
+
+TOOL_ACTION COMMON_ACTIONS::unselectItem( "pcbnew.InteractiveSelection.UnselectItem",
+ AS_GLOBAL, 0,
+ "", "" ); // No description, it is not supposed to be shown anywhere
+
+TOOL_ACTION COMMON_ACTIONS::selectionClear( "pcbnew.InteractiveSelection.Clear",
+ AS_GLOBAL, 0,
+ "", "" ); // No description, it is not supposed to be shown anywhere
+
+TOOL_ACTION COMMON_ACTIONS::selectConnection( "pcbnew.InteractiveSelection.SelectConnection",
+ AS_GLOBAL, 'U',
+ _( "trivial connection" ), _( "Selects a connection between two junctions." ) );
+
+TOOL_ACTION COMMON_ACTIONS::selectCopper( "pcbnew.InteractiveSelection.SelectCopper",
+ AS_GLOBAL, 'I',
+ _( "copper connection" ), _( "Selects whole copper connection." ) );
+
+TOOL_ACTION COMMON_ACTIONS::selectNet( "pcbnew.InteractiveSelection.SelectNet",
+ AS_GLOBAL, 0,
+ _( "whole net" ), _( "Selects all tracks & vias belonging to the same net." ) );
+
+TOOL_ACTION COMMON_ACTIONS::find( "pcbnew.InteractiveSelection.Find",
+ AS_GLOBAL, 0, //TOOL_ACTION::LegacyHotKey( HK_FIND_ITEM ), // handled by wxWidgets
+ _( "Find an item" ), _( "Searches the document for an item" ), find_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::findMove( "pcbnew.InteractiveSelection.FindMove",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_GET_AND_MOVE_FOOTPRINT ) );
+
+
+// Edit tool actions
+TOOL_ACTION COMMON_ACTIONS::editFootprintInFpEditor( "pcbnew.InteractiveEdit.editFootprintInFpEditor",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_EDIT_MODULE_WITH_MODEDIT ),
+ _( "Open in Footprint Editor" ),
+ _( "Opens the selected footprint in the Footprint Editor" ),
+ module_editor_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::copyPadToSettings( "pcbnew.InteractiveEdit.copyPadToSettings",
+ AS_GLOBAL, 0,
+ _( "Copy pad settings to Current Settings" ),
+ _( "Copies the properties of selected pad to the current template pad settings." ) );
+
+TOOL_ACTION COMMON_ACTIONS::copySettingsToPads( "pcbnew.InteractiveEdit.copySettingsToPads",
+ AS_GLOBAL, 0,
+ _( "Copy Current Settings to pads" ),
+ _( "Copies the current template pad settings to the selected pad(s)." ) );
+
+TOOL_ACTION COMMON_ACTIONS::globalEditPads( "pcbnew.InteractiveEdit.globalPadEdit",
+ AS_GLOBAL, 0,
+ _( "Global Pad Edition" ),
+ _( "Changes pad properties globally." ), global_options_pad_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_MOVE_ITEM ),
+ _( "Move" ), _( "Moves the selected item(s)" ), move_xpm, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::duplicate( "pcbnew.InteractiveEdit.duplicate",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_DUPLICATE_ITEM ),
+ _( "Duplicate" ), _( "Duplicates the selected item(s)" ), duplicate_module_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::duplicateIncrement( "pcbnew.InteractiveEdit.duplicateIncrementPads",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_DUPLICATE_ITEM_AND_INCREMENT ),
+ _( "Duplicate" ), _( "Duplicates the selected item(s), incrementing pad numbers" ) );
+
+TOOL_ACTION COMMON_ACTIONS::moveExact( "pcbnew.InteractiveEdit.moveExact",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_MOVE_ITEM_EXACT ),
+ _( "Move Exactly..." ), _( "Moves the selected item(s) by an exact amount" ),
+ move_module_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::createArray( "pcbnew.InteractiveEdit.createArray",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_CREATE_ARRAY ),
+ _( "Create array" ), _( "Create array" ), array_module_xpm, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.InteractiveEdit.rotate",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ROTATE_ITEM ),
+ _( "Rotate" ), _( "Rotates selected item(s)" ), rotate_cw_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveEdit.flip",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_FLIP_ITEM ),
+ _( "Flip" ), _( "Flips selected item(s)" ), swap_layer_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::remove( "pcbnew.InteractiveEdit.remove",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_DELETE ),
+ _( "Remove" ), _( "Deletes selected item(s)" ), delete_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_EDIT_ITEM ),
+ _( "Properties..." ), _( "Displays item properties dialog" ), editor_xpm );
+
+
+// Drawing tool actions
+TOOL_ACTION COMMON_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line",
+ AS_GLOBAL, 0,
+ _( "Draw a line" ), _( "Draw a line" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::drawCircle( "pcbnew.InteractiveDrawing.circle",
+ AS_GLOBAL, 0,
+ _( "Draw a circle" ), _( "Draw a circle" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::drawArc( "pcbnew.InteractiveDrawing.arc",
+ AS_GLOBAL, 0,
+ _( "Draw an arc" ), _( "Draw an arc" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::placeText( "pcbnew.InteractiveDrawing.text",
+ AS_GLOBAL, 0,
+ _( "Add a text" ), _( "Add a text" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::drawDimension( "pcbnew.InteractiveDrawing.dimension",
+ AS_GLOBAL, 0,
+ _( "Add a dimension" ), _( "Add a dimension" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::drawZone( "pcbnew.InteractiveDrawing.zone",
+ AS_GLOBAL, 0,
+ _( "Add a filled zone" ), _( "Add a filled zone" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::drawKeepout( "pcbnew.InteractiveDrawing.keepout",
+ AS_GLOBAL, 0,
+ _( "Add a keepout area" ), _( "Add a keepout area" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::placeDXF( "pcbnew.InteractiveDrawing.placeDXF",
+ AS_GLOBAL, 0,
+ "", "", NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::setAnchor( "pcbnew.InteractiveDrawing.setAnchor",
+ AS_GLOBAL, 0,
+ _( "Place the footprint anchor" ), _( "Place the footprint anchor" ),
+ NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::incWidth( "pcbnew.InteractiveDrawing.incWidth",
+ AS_CONTEXT, '+',
+ _( "Increase the line width" ), _( "Increase the line width" ) );
+
+TOOL_ACTION COMMON_ACTIONS::decWidth( "pcbnew.InteractiveDrawing.decWidth",
+ AS_CONTEXT, '-',
+ _( "Decrease the line width" ), _( "Decrease the line width" ) );
+
+TOOL_ACTION COMMON_ACTIONS::arcPosture( "pcbnew.InteractiveDrawing.arcPosture",
+ AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_SWITCH_TRACK_POSTURE ),
+ _( "Switch the arc posture" ), _( "Switch the arc posture" ) );
+
+
+// View Controls
+TOOL_ACTION COMMON_ACTIONS::zoomIn( "common.Control.zoomIn",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ZOOM_IN ),
+ _( "Zoom In" ), "", zoom_in_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::zoomOut( "common.Control.zoomOut",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ZOOM_OUT ),
+ _( "Zoom Out" ), "", zoom_out_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::zoomInCenter( "common.Control.zoomInCenter",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::zoomOutCenter( "common.Control.zoomOutCenter",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::zoomCenter( "common.Control.zoomCenter",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ZOOM_CENTER ),
+ _( "Center" ), "", zoom_center_on_screen_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::zoomFitScreen( "common.Control.zoomFitScreen",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ZOOM_AUTO ),
+ _( "Zoom Auto" ), "", zoom_fit_in_page_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::zoomPreset( "common.Control.zoomPreset",
+ AS_GLOBAL, 0,
+ "", "" );
+
+
+// Display modes
+TOOL_ACTION COMMON_ACTIONS::trackDisplayMode( "pcbnew.Control.trackDisplayMode",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_TRACK_DISPLAY_MODE ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::padDisplayMode( "pcbnew.Control.padDisplayMode",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::viaDisplayMode( "pcbnew.Control.viaDisplayMode",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::zoneDisplayEnable( "pcbnew.Control.zoneDisplayEnable",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::zoneDisplayDisable( "pcbnew.Control.zoneDisplayDisable",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::zoneDisplayOutlines( "pcbnew.Control.zoneDisplayOutlines",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::highContrastMode( "pcbnew.Control.highContrastMode",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_HIGHCONTRAST_MODE ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::highContrastInc( "pcbnew.Control.highContrastInc",
+ AS_GLOBAL, '>',
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::highContrastDec( "pcbnew.Control.highContrastDec",
+ AS_GLOBAL, '<',
+ "", "" );
+
+
+// Layer control
+TOOL_ACTION COMMON_ACTIONS::layerTop( "pcbnew.Control.layerTop",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_LAYER_TO_COMPONENT ),
+ "", "", NULL, AF_NONE, (void*) F_Cu );
+
+TOOL_ACTION COMMON_ACTIONS::layerInner1( "pcbnew.Control.layerInner1",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_LAYER_TO_INNER1 ),
+ "", "", NULL, AF_NONE, (void*) In1_Cu );
+
+TOOL_ACTION COMMON_ACTIONS::layerInner2( "pcbnew.Control.layerInner2",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_LAYER_TO_INNER2 ),
+ "", "", NULL, AF_NONE, (void*) In2_Cu );
+
+TOOL_ACTION COMMON_ACTIONS::layerInner3( "pcbnew.Control.layerInner3",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_LAYER_TO_INNER3 ),
+ "", "", NULL, AF_NONE, (void*) In3_Cu );
+
+TOOL_ACTION COMMON_ACTIONS::layerInner4( "pcbnew.Control.layerInner4",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_LAYER_TO_INNER4 ),
+ "", "", NULL, AF_NONE, (void*) In4_Cu );
+
+TOOL_ACTION COMMON_ACTIONS::layerInner5( "pcbnew.Control.layerInner5",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_LAYER_TO_INNER5 ),
+ "", "", NULL, AF_NONE, (void*) In5_Cu );
+
+TOOL_ACTION COMMON_ACTIONS::layerInner6( "pcbnew.Control.layerInner6",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_LAYER_TO_INNER6 ),
+ "", "", NULL, AF_NONE, (void*) In6_Cu );
+
+TOOL_ACTION COMMON_ACTIONS::layerBottom( "pcbnew.Control.layerBottom",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_LAYER_TO_COPPER ),
+ "", "", NULL, AF_NONE, (void*) B_Cu );
+
+TOOL_ACTION COMMON_ACTIONS::layerNext( "pcbnew.Control.layerNext",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_LAYER_TO_NEXT ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::layerPrev( "pcbnew.Control.layerPrev",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_LAYER_TO_PREVIOUS ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::layerToggle( "pcbnew.Control.layerToggle",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ADD_THROUGH_VIA ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::layerAlphaInc( "pcbnew.Control.layerAlphaInc",
+ AS_GLOBAL, '}',
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::layerAlphaDec( "pcbnew.Control.layerAlphaDec",
+ AS_GLOBAL, '{',
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::layerChanged( "pcbnew.Control.layerChanged",
+ AS_GLOBAL, 0,
+ "", "", NULL, AF_NOTIFY );
+
+
+// Grid control
+TOOL_ACTION COMMON_ACTIONS::gridFast1( "common.Control.gridFast1",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_GRID_TO_FASTGRID1 ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::gridFast2( "common.Control.gridFast2",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_GRID_TO_FASTGRID2 ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::gridNext( "common.Control.gridNext",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_GRID_TO_NEXT ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::gridPrev( "common.Control.gridPrev",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_GRID_TO_PREVIOUS ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::gridSetOrigin( "common.Control.gridSetOrigin",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SET_GRID_ORIGIN ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::gridResetOrigin( "common.Control.gridResetOrigin",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_RESET_GRID_ORIGIN ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::gridPreset( "common.Control.gridPreset",
+ AS_GLOBAL, 0,
+ "", "" );
+
+// Track & via size control
+TOOL_ACTION COMMON_ACTIONS::trackWidthInc( "pcbnew.EditorControl.trackWidthInc",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_TRACK_WIDTH_TO_NEXT ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::trackWidthDec( "pcbnew.EditorControl.trackWidthDec",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_TRACK_WIDTH_TO_PREVIOUS ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::viaSizeInc( "pcbnew.EditorControl.viaSizeInc",
+ AS_GLOBAL, '\'',
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::viaSizeDec( "pcbnew.EditorControl.viaSizeDec",
+ AS_GLOBAL, '\\',
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::trackViaSizeChanged( "pcbnew.EditorControl.trackViaSizeChanged",
+ AS_GLOBAL, 0,
+ "", "", NULL, AF_NOTIFY );
+
+
+// Zone actions
+TOOL_ACTION COMMON_ACTIONS::zoneFill( "pcbnew.EditorControl.zoneFill",
+ AS_GLOBAL, 0,
+ _( "Fill" ), _( "Fill zone(s)" ), fill_zone_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::zoneFillAll( "pcbnew.EditorControl.zoneFillAll",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ZONE_FILL_OR_REFILL ),
+ _( "Fill all" ), _( "Fill all zones" ) );
+
+TOOL_ACTION COMMON_ACTIONS::zoneUnfill( "pcbnew.EditorControl.zoneUnfill",
+ AS_GLOBAL, 0,
+ _( "Unfill" ), _( "Unfill zone(s)" ), zone_unfill_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::zoneUnfillAll( "pcbnew.EditorControl.zoneUnfillAll",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ZONE_REMOVE_FILLED ),
+ _( "Unfill all" ), _( "Unfill all zones" ) );
+
+TOOL_ACTION COMMON_ACTIONS::zoneMerge( "pcbnew.EditorControl.zoneMerge",
+ AS_GLOBAL, 0,
+ _( "Merge zones" ), _( "Merge zones" ) );
+
+
+TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.EditorControl.placeTarget",
+ AS_GLOBAL, 0,
+ _( "Add layer alignment target" ), _( "Add layer alignment target" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::placeModule( "pcbnew.EditorControl.placeModule",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ADD_MODULE ),
+ _( "Add footprints" ), _( "Add footprints" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::drillOrigin( "pcbnew.EditorControl.drillOrigin",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::crossProbeSchToPcb( "pcbnew.EditorControl.crossProbSchToPcb",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::toggleLockModule( "pcbnew.EditorControl.toggleLockModule",
+ AS_GLOBAL, 'L',
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::appendBoard( "pcbnew.EditorControl.appendBoard",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::highlightNet( "pcbnew.EditorControl.highlightNet",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::highlightNetCursor( "pcbnew.EditorControl.highlightNetCursor",
+ AS_GLOBAL, 0,
+ "", "" );
+
+
+// Module editor tools
+TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.ModuleEditor.placePad",
+ AS_GLOBAL, 0,
+ _( "Add pads" ), _( "Add pads" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::enumeratePads( "pcbnew.ModuleEditor.enumeratePads",
+ AS_GLOBAL, 0,
+ _( "Enumerate pads" ), _( "Enumerate pads" ), pad_enumerate_xpm, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::copyItems( "pcbnew.ModuleEditor.copyItems",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_COPY_ITEM ),
+ _( "Copy items" ), _( "Copy items" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::pasteItems( "pcbnew.ModuleEditor.pasteItems",
+ AS_GLOBAL, MD_CTRL + int( 'V' ),
+ _( "Paste items" ), _( "Paste items" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::moduleEdgeOutlines( "pcbnew.ModuleEditor.graphicOutlines",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::moduleTextOutlines( "pcbnew.ModuleEditor.textOutlines",
+ AS_GLOBAL, 0,
+ "", "" );
+
+
+// Cursor control
+TOOL_ACTION COMMON_ACTIONS::cursorUp( "pcbnew.Control.cursorUp",
+ AS_GLOBAL, WXK_UP, "", "", NULL, AF_NONE, (void*) CURSOR_UP );
+TOOL_ACTION COMMON_ACTIONS::cursorDown( "pcbnew.Control.cursorDown",
+ AS_GLOBAL, WXK_DOWN, "", "" , NULL, AF_NONE, (void*) CURSOR_DOWN );
+TOOL_ACTION COMMON_ACTIONS::cursorLeft( "pcbnew.Control.cursorLeft",
+ AS_GLOBAL, WXK_LEFT, "", "" , NULL, AF_NONE, (void*) CURSOR_LEFT );
+TOOL_ACTION COMMON_ACTIONS::cursorRight( "pcbnew.Control.cursorRight",
+ AS_GLOBAL, WXK_RIGHT, "", "" , NULL, AF_NONE, (void*) CURSOR_RIGHT );
+
+TOOL_ACTION COMMON_ACTIONS::cursorUpFast( "pcbnew.Control.cursorUpFast",
+ AS_GLOBAL, MD_CTRL + WXK_UP, "", "", NULL, AF_NONE, (void*) ( CURSOR_UP | CURSOR_FAST_MOVE ) );
+TOOL_ACTION COMMON_ACTIONS::cursorDownFast( "pcbnew.Control.cursorDownFast",
+ AS_GLOBAL, MD_CTRL + WXK_DOWN, "", "" , NULL, AF_NONE, (void*) ( CURSOR_DOWN | CURSOR_FAST_MOVE ) );
+TOOL_ACTION COMMON_ACTIONS::cursorLeftFast( "pcbnew.Control.cursorLeftFast",
+ AS_GLOBAL, MD_CTRL + WXK_LEFT, "", "" , NULL, AF_NONE, (void*) ( CURSOR_LEFT | CURSOR_FAST_MOVE ) );
+TOOL_ACTION COMMON_ACTIONS::cursorRightFast( "pcbnew.Control.cursorRightFast",
+ AS_GLOBAL, MD_CTRL + WXK_RIGHT, "", "" , NULL, AF_NONE, (void*) ( CURSOR_RIGHT | CURSOR_FAST_MOVE ) );
+
+TOOL_ACTION COMMON_ACTIONS::cursorClick( "pcbnew.Control.cursorClick",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_LEFT_CLICK ),
+ "", "", NULL, AF_NONE, (void*) CURSOR_CLICK );
+TOOL_ACTION COMMON_ACTIONS::cursorDblClick( "pcbnew.Control.cursorDblClick",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_LEFT_DCLICK ),
+ "", "", NULL, AF_NONE, (void*) CURSOR_DBL_CLICK );
+
+TOOL_ACTION COMMON_ACTIONS::panUp( "pcbnew.Control.panUp",
+ AS_GLOBAL, MD_SHIFT + WXK_UP, "", "", NULL, AF_NONE, (void*) CURSOR_UP );
+TOOL_ACTION COMMON_ACTIONS::panDown( "pcbnew.Control.panDown",
+ AS_GLOBAL, MD_SHIFT + WXK_DOWN, "", "" , NULL, AF_NONE, (void*) CURSOR_DOWN );
+TOOL_ACTION COMMON_ACTIONS::panLeft( "pcbnew.Control.panLeft",
+ AS_GLOBAL, MD_SHIFT + WXK_LEFT, "", "" , NULL, AF_NONE, (void*) CURSOR_LEFT );
+TOOL_ACTION COMMON_ACTIONS::panRight( "pcbnew.Control.panRight",
+ AS_GLOBAL, MD_SHIFT + WXK_RIGHT, "", "" , NULL, AF_NONE, (void*) CURSOR_RIGHT );
+
+// Miscellaneous
+TOOL_ACTION COMMON_ACTIONS::selectionTool( "pcbnew.Control.selectionTool",
+ AS_GLOBAL, 0,
+ "", "", NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::pickerTool( "pcbnew.Picker", AS_GLOBAL, 0, "", "", NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::resetCoords( "pcbnew.Control.resetCoords",
+ AS_GLOBAL, ' ',
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::switchCursor( "pcbnew.Control.switchCursor",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::switchUnits( "pcbnew.Control.switchUnits",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SWITCH_UNITS ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::deleteItemCursor( "pcbnew.Control.deleteItemCursor",
+ AS_GLOBAL, 0,
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::showHelp( "pcbnew.Control.showHelp",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_HELP ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::toBeDone( "pcbnew.Control.toBeDone",
+ AS_GLOBAL, 0, // dialog saying it is not implemented yet
+ "", "" ); // so users are aware of that
+
+
+TOOL_ACTION COMMON_ACTIONS::routerActivateSingle( "pcbnew.InteractiveRouter.SingleTrack",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ADD_NEW_TRACK ),
+ _( "Run push & shove router (single tracks)" ),
+ _( "Run push & shove router (single tracks)" ), ps_router_xpm, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::routerActivateDiffPair( "pcbnew.InteractiveRouter.DiffPair",
+ AS_GLOBAL, '6',
+ _( "Run push & shove router (differential pairs)" ),
+ _( "Run push & shove router (differential pairs)" ), ps_diff_pair_xpm, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::routerActivateSettingsDialog( "pcbnew.InteractiveRouter.SettingsDialog",
+ AS_GLOBAL, 0,
+ _( "Open Interactive Router settings" ),
+ _( "Open Interactive Router settings" ), NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::routerActivateDpDimensionsDialog( "pcbnew.InteractiveRouter.DpDimensionsDialog",
+ AS_GLOBAL, 0,
+ _( "Open Differential Pair Dimension settings" ),
+ _( "Open Differential Pair Dimension settings" ), ps_diff_pair_gap_xpm, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::routerActivateTuneSingleTrace( "pcbnew.LengthTuner.TuneSingleTrack",
+ AS_GLOBAL, '7',
+ _( "Tune length of a single track" ), "", ps_tune_length_xpm, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::routerActivateTuneDiffPair( "pcbnew.LengthTuner.TuneDiffPair",
+ AS_GLOBAL, '8',
+ _( "Tune length of a differential pair" ), "", NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::routerActivateTuneDiffPairSkew( "pcbnew.LengthTuner.TuneDiffPairSkew",
+ AS_GLOBAL, '9',
+ _( "Tune skew of a differential pair" ), "", NULL, AF_ACTIVATE );
+
+TOOL_ACTION COMMON_ACTIONS::routerInlineDrag( "pcbnew.InteractiveRouter.InlineDrag",
+ AS_GLOBAL, 0,
+ "", "" );
+
+// Point editor
+TOOL_ACTION COMMON_ACTIONS::pointEditorUpdate( "pcbnew.PointEditor.update",
+ AS_GLOBAL, 0,
+ "", "" ); // No description, it is not supposed to be shown anywhere
+
+TOOL_ACTION COMMON_ACTIONS::pointEditorAddCorner( "pcbnew.PointEditor.addCorner",
+ AS_GLOBAL, 0,
+ _( "Create corner" ), _( "Create corner" ), add_corner_xpm );
+
+TOOL_ACTION COMMON_ACTIONS::pointEditorRemoveCorner( "pcbnew.PointEditor.removeCorner",
+ AS_GLOBAL, 0,
+ _( "Remove corner" ), _( "Remove corner" ), delete_xpm );
+
+// Placement tool
+TOOL_ACTION COMMON_ACTIONS::alignTop( "pcbnew.Place.alignTop",
+ AS_GLOBAL, 0,
+ _( "Align items to the top" ),
+ _( "Aligns selected items to the top edge" ) );
+
+TOOL_ACTION COMMON_ACTIONS::alignBottom( "pcbnew.Place.alignBottom",
+ AS_GLOBAL, 0,
+ _( "Align items to the bottom" ),
+ _( "Aligns selected items to the bottom edge" ) );
+
+TOOL_ACTION COMMON_ACTIONS::alignLeft( "pcbnew.Place.alignLeft",
+ AS_GLOBAL, 0,
+ _( "Align items to the left" ),
+ _( "Aligns selected items to the left edge" ) );
+
+TOOL_ACTION COMMON_ACTIONS::alignRight( "pcbnew.Place.alignRight",
+ AS_GLOBAL, 0,
+ _( "Align items to the right" ),
+ _( "Aligns selected items to the right edge" ) );
+
+TOOL_ACTION COMMON_ACTIONS::distributeHorizontally( "pcbnew.Place.distributeHorizontally",
+ AS_GLOBAL, 0,
+ _( "Distribute horizontally" ),
+ _( "Distributes selected items along the horizontal axis" ) );
+
+TOOL_ACTION COMMON_ACTIONS::distributeVertically( "pcbnew.Place.distributeVertically",
+ AS_GLOBAL, 0,
+ _( "Distribute vertically" ),
+ _( "Distributes selected items along the vertical axis" ) );
+
+
+boost::optional<TOOL_EVENT> COMMON_ACTIONS::TranslateLegacyId( int aId )
+{
+ switch( aId )
+ {
+ case ID_PCB_MODULE_BUTT:
+ return COMMON_ACTIONS::placeModule.MakeEvent();
+
+ case ID_TRACK_BUTT:
+ return COMMON_ACTIONS::routerActivateSingle.MakeEvent();
+
+ case ID_DIFF_PAIR_BUTT:
+ return COMMON_ACTIONS::routerActivateDiffPair.MakeEvent();
+
+ case ID_TUNE_SINGLE_TRACK_LEN_BUTT:
+ return COMMON_ACTIONS::routerActivateTuneSingleTrace.MakeEvent();
+
+ case ID_TUNE_DIFF_PAIR_LEN_BUTT:
+ return COMMON_ACTIONS::routerActivateTuneDiffPair.MakeEvent();
+
+ case ID_TUNE_DIFF_PAIR_SKEW_BUTT:
+ return COMMON_ACTIONS::routerActivateTuneDiffPairSkew.MakeEvent();
+
+ case ID_MENU_INTERACTIVE_ROUTER_SETTINGS:
+ return COMMON_ACTIONS::routerActivateSettingsDialog.MakeEvent();
+
+ case ID_MENU_DIFF_PAIR_DIMENSIONS:
+ return COMMON_ACTIONS::routerActivateDpDimensionsDialog.MakeEvent();
+
+ case ID_PCB_ZONES_BUTT:
+ return COMMON_ACTIONS::drawZone.MakeEvent();
+
+ case ID_PCB_KEEPOUT_AREA_BUTT:
+ return COMMON_ACTIONS::drawKeepout.MakeEvent();
+
+ case ID_PCB_ADD_LINE_BUTT:
+ case ID_MODEDIT_LINE_TOOL:
+ return COMMON_ACTIONS::drawLine.MakeEvent();
+
+ case ID_PCB_CIRCLE_BUTT:
+ case ID_MODEDIT_CIRCLE_TOOL:
+ return COMMON_ACTIONS::drawCircle.MakeEvent();
+
+ case ID_PCB_ARC_BUTT:
+ case ID_MODEDIT_ARC_TOOL:
+ return COMMON_ACTIONS::drawArc.MakeEvent();
+
+ case ID_PCB_ADD_TEXT_BUTT:
+ case ID_MODEDIT_TEXT_TOOL:
+ return COMMON_ACTIONS::placeText.MakeEvent();
+
+ case ID_PCB_DIMENSION_BUTT:
+ return COMMON_ACTIONS::drawDimension.MakeEvent();
+
+ case ID_PCB_MIRE_BUTT:
+ return COMMON_ACTIONS::placeTarget.MakeEvent();
+
+ case ID_MODEDIT_PAD_TOOL:
+ return COMMON_ACTIONS::placePad.MakeEvent();
+
+ case ID_GEN_IMPORT_DXF_FILE:
+ return COMMON_ACTIONS::placeDXF.MakeEvent();
+
+ case ID_MODEDIT_ANCHOR_TOOL:
+ return COMMON_ACTIONS::setAnchor.MakeEvent();
+
+ case ID_PCB_PLACE_GRID_COORD_BUTT:
+ case ID_MODEDIT_PLACE_GRID_COORD:
+ return COMMON_ACTIONS::gridSetOrigin.MakeEvent();
+
+ case ID_ZOOM_IN: // toolbar button "Zoom In"
+ return COMMON_ACTIONS::zoomInCenter.MakeEvent();
+
+ case ID_ZOOM_OUT: // toolbar button "Zoom In"
+ return COMMON_ACTIONS::zoomOutCenter.MakeEvent();
+
+ case ID_ZOOM_PAGE: // toolbar button "Fit on Screen"
+ return COMMON_ACTIONS::zoomFitScreen.MakeEvent();
+
+ case ID_TB_OPTIONS_SHOW_TRACKS_SKETCH:
+ return COMMON_ACTIONS::trackDisplayMode.MakeEvent();
+
+ case ID_TB_OPTIONS_SHOW_PADS_SKETCH:
+ return COMMON_ACTIONS::padDisplayMode.MakeEvent();
+
+ case ID_TB_OPTIONS_SHOW_VIAS_SKETCH:
+ return COMMON_ACTIONS::viaDisplayMode.MakeEvent();
+
+ case ID_TB_OPTIONS_SHOW_ZONES:
+ return COMMON_ACTIONS::zoneDisplayEnable.MakeEvent();
+
+ case ID_TB_OPTIONS_SHOW_ZONES_DISABLE:
+ return COMMON_ACTIONS::zoneDisplayDisable.MakeEvent();
+
+ case ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY:
+ return COMMON_ACTIONS::zoneDisplayOutlines.MakeEvent();
+
+ case ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH:
+ return COMMON_ACTIONS::moduleEdgeOutlines.MakeEvent();
+
+ case ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH:
+ return COMMON_ACTIONS::moduleTextOutlines.MakeEvent();
+
+ case ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE:
+ return COMMON_ACTIONS::highContrastMode.MakeEvent();
+
+ case ID_FIND_ITEMS:
+ return COMMON_ACTIONS::find.MakeEvent();
+
+ case ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST:
+ return COMMON_ACTIONS::findMove.MakeEvent();
+
+ case ID_NO_TOOL_SELECTED:
+ return COMMON_ACTIONS::selectionTool.MakeEvent();
+
+ case ID_PCB_DELETE_ITEM_BUTT:
+ case ID_MODEDIT_DELETE_TOOL:
+ return COMMON_ACTIONS::deleteItemCursor.MakeEvent();
+
+ case ID_PCB_PLACE_OFFSET_COORD_BUTT:
+ return COMMON_ACTIONS::drillOrigin.MakeEvent();
+
+ case ID_PCB_HIGHLIGHT_BUTT:
+ return COMMON_ACTIONS::highlightNetCursor.MakeEvent();
+
+ case ID_APPEND_FILE:
+ return COMMON_ACTIONS::appendBoard.MakeEvent();
+
+ case ID_PCB_SHOW_1_RATSNEST_BUTT:
+ case ID_TB_OPTIONS_SHOW_MODULE_RATSNEST:
+ return COMMON_ACTIONS::toBeDone.MakeEvent();
+ }
+
+ return boost::optional<TOOL_EVENT>();
+}
diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h
new file mode 100644
index 0000000..fbedcdc
--- /dev/null
+++ b/pcbnew/tools/common_actions.h
@@ -0,0 +1,337 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013-2016 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __COMMON_ACTIONS_H
+#define __COMMON_ACTIONS_H
+
+#include <tool/tool_action.h>
+#include <boost/optional.hpp>
+
+class TOOL_EVENT;
+class TOOL_MANAGER;
+
+/**
+ * Class COMMON_ACTIONS
+ *
+ * Gathers all the actions that are shared by tools. The instance of COMMON_ACTION is created
+ * inside of ACTION_MANAGER object that registers the actions.
+ */
+class COMMON_ACTIONS
+{
+public:
+ // Selection Tool
+ /// Activation of the selection tool
+ static TOOL_ACTION selectionActivate;
+
+ /// Select a single item under the cursor position
+ static TOOL_ACTION selectionCursor;
+
+ /// Clears the current selection
+ static TOOL_ACTION selectionClear;
+
+ /// Selects an item (specified as the event parameter).
+ static TOOL_ACTION selectItem;
+
+ /// Unselects an item (specified as the event parameter).
+ static TOOL_ACTION unselectItem;
+
+ /// Selects a connection between junctions.
+ static TOOL_ACTION selectConnection;
+
+ /// Selects whole copper connection.
+ static TOOL_ACTION selectCopper;
+
+ /// Selects all connections belonging to a single net.
+ static TOOL_ACTION selectNet;
+
+ // Edit Tool
+ /// Activation of the edit tool
+ static TOOL_ACTION editActivate;
+
+ /// Rotation of selected objects
+ static TOOL_ACTION rotate;
+
+ /// Flipping of selected objects
+ static TOOL_ACTION flip;
+
+ /// Activation of the edit tool
+ static TOOL_ACTION properties;
+
+ /// Activation of the exact move tool
+ static TOOL_ACTION moveExact;
+
+ /// Activation of the duplication tool
+ static TOOL_ACTION duplicate;
+
+ /// Activation of the duplication tool with incrementing (e.g. pad number)
+ static TOOL_ACTION duplicateIncrement;
+
+ /// Deleting a BOARD_ITEM
+ static TOOL_ACTION remove;
+
+ // Drawing Tool
+ /// Activation of the drawing tool (line)
+ static TOOL_ACTION drawLine;
+
+ /// Activation of the drawing tool (circle)
+ static TOOL_ACTION drawCircle;
+
+ /// Activation of the drawing tool (arc)
+ static TOOL_ACTION drawArc;
+
+ /// Activation of the drawing tool (text)
+ static TOOL_ACTION placeText;
+
+ /// Activation of the drawing tool (dimension)
+ static TOOL_ACTION drawDimension;
+
+ /// Activation of the drawing tool (drawing a ZONE)
+ static TOOL_ACTION drawZone;
+
+ /// Activation of the drawing tool (drawing a keepout area)
+ static TOOL_ACTION drawKeepout;
+
+ /// Activation of the drawing tool (placing a TARGET)
+ static TOOL_ACTION placeTarget;
+
+ /// Activation of the drawing tool (placing a MODULE)
+ static TOOL_ACTION placeModule;
+
+ /// Activation of the drawing tool (placing a drawing from DXF file)
+ static TOOL_ACTION placeDXF;
+
+ /// Activation of the drawing tool (placing the footprint anchor)
+ static TOOL_ACTION setAnchor;
+
+ /// Increase width of currently drawn line
+ static TOOL_ACTION incWidth;
+
+ /// Decrease width of currently drawn line
+ static TOOL_ACTION decWidth;
+
+ /// Switch posture when drawing arc
+ static TOOL_ACTION arcPosture;
+
+ // Push and Shove Router Tool
+
+ /// Activation of the Push and Shove router
+ static TOOL_ACTION routerActivateSingle;
+
+ /// Activation of the Push and Shove router (differential pair mode)
+ static TOOL_ACTION routerActivateDiffPair;
+
+ /// Activation of the Push and Shove router (tune single line mode)
+ static TOOL_ACTION routerActivateTuneSingleTrace;
+
+ /// Activation of the Push and Shove router (diff pair tuning mode)
+ static TOOL_ACTION routerActivateTuneDiffPair;
+
+ /// Activation of the Push and Shove router (skew tuning mode)
+ static TOOL_ACTION routerActivateTuneDiffPairSkew;
+
+ /// Activation of the Push and Shove settings dialogs
+ static TOOL_ACTION routerActivateSettingsDialog;
+ static TOOL_ACTION routerActivateDpDimensionsDialog;
+
+
+ /// Activation of the Push and Shove router (inline dragging mode)
+ static TOOL_ACTION routerInlineDrag;
+
+ // Point Editor
+ /// Update edit points
+ static TOOL_ACTION pointEditorUpdate;
+
+ /// Break outline (insert additional points to an edge)
+ static TOOL_ACTION pointEditorAddCorner;
+
+ /// Removes a corner
+ static TOOL_ACTION pointEditorRemoveCorner;
+
+ // Placement tool
+ /// Align items to the top edge of selection bounding box
+ static TOOL_ACTION alignTop;
+
+ /// Align items to the bottom edge of selection bounding box
+ static TOOL_ACTION alignBottom;
+
+ /// Align items to the left edge of selection bounding box
+ static TOOL_ACTION alignLeft;
+
+ /// Align items to the right edge of selection bounding box
+ static TOOL_ACTION alignRight;
+
+ /// Distributes items evenly along the horizontal axis
+ static TOOL_ACTION distributeHorizontally;
+
+ /// Distributes items evenly along the vertical axis
+ static TOOL_ACTION distributeVertically;
+
+ // View controls
+ static TOOL_ACTION zoomIn;
+ static TOOL_ACTION zoomOut;
+ static TOOL_ACTION zoomInCenter;
+ static TOOL_ACTION zoomOutCenter;
+ static TOOL_ACTION zoomCenter;
+ static TOOL_ACTION zoomFitScreen;
+ static TOOL_ACTION zoomPreset;
+
+ // Display modes
+ static TOOL_ACTION trackDisplayMode;
+ static TOOL_ACTION padDisplayMode;
+ static TOOL_ACTION viaDisplayMode;
+ static TOOL_ACTION zoneDisplayEnable;
+ static TOOL_ACTION zoneDisplayDisable;
+ static TOOL_ACTION zoneDisplayOutlines;
+ static TOOL_ACTION highContrastMode;
+ static TOOL_ACTION highContrastInc;
+ static TOOL_ACTION highContrastDec;
+
+ // Layer control
+ static TOOL_ACTION layerTop;
+ static TOOL_ACTION layerInner1;
+ static TOOL_ACTION layerInner2;
+ static TOOL_ACTION layerInner3;
+ static TOOL_ACTION layerInner4;
+ static TOOL_ACTION layerInner5;
+ static TOOL_ACTION layerInner6;
+ static TOOL_ACTION layerBottom;
+ static TOOL_ACTION layerNext;
+ static TOOL_ACTION layerPrev;
+ static TOOL_ACTION layerAlphaInc;
+ static TOOL_ACTION layerAlphaDec;
+ static TOOL_ACTION layerToggle;
+
+ static TOOL_ACTION layerChanged; // notification
+
+ // Grid control
+ static TOOL_ACTION gridFast1;
+ static TOOL_ACTION gridFast2;
+ static TOOL_ACTION gridNext;
+ static TOOL_ACTION gridPrev;
+ static TOOL_ACTION gridSetOrigin;
+ static TOOL_ACTION gridResetOrigin;
+ static TOOL_ACTION gridPreset;
+
+ // Track & via size control
+ static TOOL_ACTION trackWidthInc;
+ static TOOL_ACTION trackWidthDec;
+ static TOOL_ACTION viaSizeInc;
+ static TOOL_ACTION viaSizeDec;
+
+ static TOOL_ACTION trackViaSizeChanged; // notification
+
+ // Zone actions
+ static TOOL_ACTION zoneFill;
+ static TOOL_ACTION zoneFillAll;
+ static TOOL_ACTION zoneUnfill;
+ static TOOL_ACTION zoneUnfillAll;
+ static TOOL_ACTION zoneMerge;
+
+ // Module editor tools
+ /// Activation of the drawing tool (placing a PAD)
+ static TOOL_ACTION placePad;
+
+ /// Tool for quick pad enumeration
+ static TOOL_ACTION enumeratePads;
+
+ /// Tool for creating an array of objects
+ static TOOL_ACTION createArray;
+
+ /// Copying module items to clipboard
+ static TOOL_ACTION copyItems;
+
+ /// Pasting module items from clipboard
+ static TOOL_ACTION pasteItems;
+
+ /// Display module edges as outlines
+ static TOOL_ACTION moduleEdgeOutlines;
+
+ /// Display module texts as outlines
+ static TOOL_ACTION moduleTextOutlines;
+
+ /// Cursor control with keyboard
+ static TOOL_ACTION cursorUp;
+ static TOOL_ACTION cursorDown;
+ static TOOL_ACTION cursorLeft;
+ static TOOL_ACTION cursorRight;
+
+ static TOOL_ACTION cursorUpFast;
+ static TOOL_ACTION cursorDownFast;
+ static TOOL_ACTION cursorLeftFast;
+ static TOOL_ACTION cursorRightFast;
+
+ static TOOL_ACTION cursorClick;
+ static TOOL_ACTION cursorDblClick;
+
+ // Panning with keyboard
+ static TOOL_ACTION panUp;
+ static TOOL_ACTION panDown;
+ static TOOL_ACTION panLeft;
+ static TOOL_ACTION panRight;
+
+ // Miscellaneous
+ static TOOL_ACTION selectionTool;
+ static TOOL_ACTION pickerTool;
+ static TOOL_ACTION resetCoords;
+ static TOOL_ACTION switchCursor;
+ static TOOL_ACTION switchUnits;
+ static TOOL_ACTION deleteItemCursor;
+ static TOOL_ACTION highlightNet;
+ static TOOL_ACTION highlightNetCursor;
+ static TOOL_ACTION drillOrigin;
+ static TOOL_ACTION crossProbeSchToPcb;
+ static TOOL_ACTION toggleLockModule;
+ static TOOL_ACTION appendBoard;
+ static TOOL_ACTION showHelp;
+ static TOOL_ACTION toBeDone;
+
+ /// Find an item
+ static TOOL_ACTION find;
+
+ /// Find an item and start moving
+ static TOOL_ACTION findMove;
+
+ static TOOL_ACTION editFootprintInFpEditor;
+ static TOOL_ACTION copyPadToSettings;
+ static TOOL_ACTION copySettingsToPads;
+ static TOOL_ACTION globalEditPads;
+
+
+ /**
+ * Function TranslateLegacyId()
+ * Translates legacy tool ids to the corresponding TOOL_ACTION name.
+ * @param aId is legacy tool id to be translated.
+ * @return std::string is name of the corresponding TOOL_ACTION. It may be empty, if there is
+ * no corresponding TOOL_ACTION.
+ */
+ static boost::optional<TOOL_EVENT> TranslateLegacyId( int aId );
+
+ ///> Cursor control event types
+ enum CURSOR_EVENT_TYPE { CURSOR_UP, CURSOR_DOWN, CURSOR_LEFT, CURSOR_RIGHT,
+ CURSOR_CLICK, CURSOR_DBL_CLICK, CURSOR_FAST_MOVE = 0x8000 };
+};
+
+void registerAllTools( TOOL_MANAGER* aToolManager );
+
+#endif
diff --git a/pcbnew/tools/conditional_menu.cpp b/pcbnew/tools/conditional_menu.cpp
new file mode 100644
index 0000000..a0e0937
--- /dev/null
+++ b/pcbnew/tools/conditional_menu.cpp
@@ -0,0 +1,109 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "conditional_menu.h"
+#include <tool/context_menu.h>
+
+void CONDITIONAL_MENU::AddItem( const TOOL_ACTION& aAction, const SELECTION_CONDITION& aCondition,
+ int aOrder )
+{
+ assert( aAction.GetId() > 0 ); // Check if action was previously registered in ACTION_MANAGER
+ addEntry( ENTRY( &aAction, aCondition, aOrder ) );
+}
+
+
+void CONDITIONAL_MENU::AddMenu( CONTEXT_MENU* aMenu, const wxString& aLabel, bool aExpand,
+ const SELECTION_CONDITION& aCondition, int aOrder )
+{
+ addEntry( ENTRY( aMenu, aLabel, aExpand, aCondition, aOrder ) );
+}
+
+
+void CONDITIONAL_MENU::AddSeparator( const SELECTION_CONDITION& aCondition, int aOrder )
+{
+ addEntry( ENTRY( aCondition, aOrder ) );
+}
+
+
+CONTEXT_MENU* CONDITIONAL_MENU::Generate( SELECTION& aSelection )
+{
+ CONTEXT_MENU* m_menu = new CONTEXT_MENU;
+ m_menu->SetTool( m_tool );
+
+ for( std::list<ENTRY>::iterator it = m_entries.begin(); it != m_entries.end(); ++it )
+ {
+ const SELECTION_CONDITION& cond = it->Condition();
+
+ try
+ {
+ if( !cond( aSelection ) )
+ continue;
+ }
+ catch( std::exception& e )
+ {
+ continue;
+ }
+
+ switch( it->Type() )
+ {
+ case ENTRY::ACTION:
+ m_menu->Add( *it->Action() );
+ break;
+
+ case ENTRY::MENU:
+ it->Menu()->UpdateAll();
+ m_menu->Add( it->Menu(), it->Label(), it->Expand() );
+ break;
+
+ case ENTRY::WXITEM:
+ m_menu->Append( it->wxItem() );
+ break;
+
+ case ENTRY::SEPARATOR:
+ m_menu->AppendSeparator();
+ break;
+
+ default:
+ assert( false );
+ break;
+ }
+ }
+
+ return m_menu;
+}
+
+
+void CONDITIONAL_MENU::addEntry( ENTRY aEntry )
+{
+ if( aEntry.Order() < 0 ) // Any order, so give it any order number
+ aEntry.SetOrder( m_entries.size() );
+
+ std::list<ENTRY>::iterator it = m_entries.begin();
+
+ // Find the right spot for the entry
+ while( it != m_entries.end() && it->Order() <= aEntry.Order() )
+ ++it;
+
+ m_entries.insert( it, aEntry );
+}
diff --git a/pcbnew/tools/conditional_menu.h b/pcbnew/tools/conditional_menu.h
new file mode 100644
index 0000000..af9ef2f
--- /dev/null
+++ b/pcbnew/tools/conditional_menu.h
@@ -0,0 +1,221 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef CONDITIONAL_MENU_H
+#define CONDITIONAL_MENU_H
+
+#include "selection_conditions.h"
+#include <boost/unordered_map.hpp>
+#include <wx/wx.h>
+
+class SELECTION_TOOL;
+class TOOL_ACTION;
+class TOOL_INTERACTIVE;
+class CONTEXT_MENU;
+
+class CONDITIONAL_MENU
+{
+public:
+ ///> Constant to indicate that we do not care about an ENTRY location in the menu.
+ static const int ANY_ORDER = -1;
+
+ CONDITIONAL_MENU( TOOL_INTERACTIVE* aTool ) :
+ m_tool( aTool )
+ {}
+
+ /**
+ * Function AddItem()
+ *
+ * Adds a menu entry to run a TOOL_ACTION on selected items.
+ * @param aAction is a menu entry to be added.
+ * @param aCondition is a condition that has to be fulfilled to enable the menu entry.
+ * @param aOrder determines location of the added item, higher numbers are put on the bottom.
+ * You may use ANY_ORDER here if you think it does not matter.
+ */
+ void AddItem( const TOOL_ACTION& aAction,
+ const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways,
+ int aOrder = ANY_ORDER );
+
+ /**
+ * Function AddMenu()
+ *
+ * Adds a submenu to the menu. CONDITIONAL_MENU takes ownership of the added menu, so it will
+ * be freed when the CONDITIONAL_MENU object is destroyed.
+ * @param aMenu is the submenu to be added.
+ * @param aLabel is the label of added submenu.
+ * @param aExpand determines if the added submenu items should be added as individual items
+ * or as a submenu.
+ * @param aCondition is a condition that has to be fulfilled to enable the submenu entry.
+ * @param aOrder determines location of the added menu, higher numbers are put on the bottom.
+ * You may use ANY_ORDER here if you think it does not matter.
+ */
+ void AddMenu( CONTEXT_MENU* aMenu, const wxString& aLabel, bool aExpand = false,
+ const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways,
+ int aOrder = ANY_ORDER );
+
+ /**
+ * Function AddSeparator()
+ *
+ * Adds a separator to the menu.
+ * @param aCondition is a condition that has to be fulfilled to enable the submenu entry.
+ * @param aOrder determines location of the added menu, higher numbers are put on the bottom.
+ * You may use ANY_ORDER here if you think it does not matter.
+ */
+ void AddSeparator( const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways,
+ int aOrder = ANY_ORDER );
+
+ /**
+ * Function Generate()
+ *
+ * Generates a context menu that contains only entries that are satisfying assigned conditions.
+ * @param aSelection is selection for which the conditions are checked against.
+ * @return Menu filtered by the entry conditions.
+ */
+ CONTEXT_MENU* Generate( SELECTION& aSelection );
+
+private:
+ ///> Helper class to organize menu entries.
+ class ENTRY
+ {
+ public:
+ ENTRY( const TOOL_ACTION* aAction,
+ const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways,
+ int aOrder = ANY_ORDER ) :
+ m_type( ACTION ), m_condition( aCondition ), m_order( aOrder ), m_expand( false )
+ {
+ m_data.action = aAction;
+ }
+
+ ENTRY( CONTEXT_MENU* aMenu, const wxString aLabel, bool aExpand = false,
+ const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways,
+ int aOrder = ANY_ORDER ) :
+ m_type( MENU ), m_condition( aCondition ), m_order( aOrder ), m_label( aLabel ), m_expand( aExpand )
+ {
+ m_data.menu = aMenu;
+ }
+
+ ENTRY( wxMenuItem* aItem, const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways,
+ int aOrder = ANY_ORDER ) :
+ m_type( WXITEM ), m_condition( aCondition ), m_order( aOrder ), m_expand( false )
+ {
+ m_data.wxItem = aItem;
+ }
+
+ // Separator
+ ENTRY( const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways,
+ int aOrder = ANY_ORDER ) :
+ m_type( SEPARATOR ), m_condition( aCondition ), m_order( aOrder ), m_expand( false )
+ {
+ m_data.wxItem = NULL;
+ }
+
+ ///> Possible entry types.
+ enum ENTRY_TYPE {
+ ACTION,
+ MENU,
+ WXITEM,
+ SEPARATOR
+ };
+
+ inline ENTRY_TYPE Type() const
+ {
+ return m_type;
+ }
+
+ inline const TOOL_ACTION* Action() const
+ {
+ assert( m_type == ACTION );
+ return m_data.action;
+ }
+
+ inline CONTEXT_MENU* Menu() const
+ {
+ assert( m_type == MENU );
+ return m_data.menu;
+ }
+
+ inline wxMenuItem* wxItem() const
+ {
+ assert( m_type == WXITEM );
+ return m_data.wxItem;
+ }
+
+ inline const wxString& Label() const
+ {
+ assert( m_type == MENU );
+ return m_label;
+ }
+
+ inline bool Expand() const
+ {
+ assert( m_type == MENU );
+ return m_expand;
+ }
+
+ inline const SELECTION_CONDITION& Condition() const
+ {
+ return m_condition;
+ }
+
+ inline int Order() const
+ {
+ return m_order;
+ }
+
+ inline void SetOrder( int aOrder )
+ {
+ m_order = aOrder;
+ }
+
+ private:
+ ENTRY_TYPE m_type;
+
+ union {
+ const TOOL_ACTION* action;
+ CONTEXT_MENU* menu;
+ wxMenuItem* wxItem;
+ } m_data;
+
+ ///> Condition to be fulfilled to show the entry in menu.
+ SELECTION_CONDITION m_condition;
+
+ ///> Order number, the higher the number the lower position it takes it is in the menu.
+ int m_order;
+
+ /// CONTEXT_MENU specific fields.
+ const wxString m_label;
+ bool m_expand;
+ };
+
+ ///> Inserts the entry, preserving the requested order.
+ void addEntry( ENTRY aEntry );
+
+ ///> List of all menu entries.
+ std::list<ENTRY> m_entries;
+
+ ///> tool owning the menu
+ TOOL_INTERACTIVE* m_tool;
+};
+
+#endif /* CONDITIONAL_MENU_H */
diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp
new file mode 100644
index 0000000..8628113
--- /dev/null
+++ b/pcbnew/tools/drawing_tool.cpp
@@ -0,0 +1,1541 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "drawing_tool.h"
+#include "common_actions.h"
+
+#include <wxPcbStruct.h>
+#include <class_draw_panel_gal.h>
+#include <project.h>
+#include <id.h>
+#include <pcbnew_id.h>
+#include <confirm.h>
+#include <dialog_edit_module_text.h>
+#include <import_dxf/dialog_dxf_import.h>
+
+#include <view/view_group.h>
+#include <view/view_controls.h>
+#include <gal/graphics_abstraction_layer.h>
+#include <tool/tool_manager.h>
+#include <router/direction.h>
+#include <ratsnest_data.h>
+
+#include <class_board.h>
+#include <class_edge_mod.h>
+#include <class_pcb_text.h>
+#include <class_dimension.h>
+#include <class_zone.h>
+#include <class_module.h>
+
+DRAWING_TOOL::DRAWING_TOOL() :
+ TOOL_INTERACTIVE( "pcbnew.InteractiveDrawing" ), m_view( NULL ),
+ m_controls( NULL ), m_board( NULL ), m_frame( NULL ), m_editModules( false ), m_lineWidth( 1 )
+{
+}
+
+
+DRAWING_TOOL::~DRAWING_TOOL()
+{
+}
+
+
+void DRAWING_TOOL::Reset( RESET_REASON aReason )
+{
+ // Init variables used by every drawing tool
+ m_view = getView();
+ m_controls = getViewControls();
+ m_board = getModel<BOARD>();
+ m_frame = getEditFrame<PCB_EDIT_FRAME>();
+}
+
+
+int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
+{
+ boost::optional<VECTOR2D> startingPoint;
+
+ if( m_editModules )
+ {
+ m_frame->SetToolID( ID_MODEDIT_LINE_TOOL, wxCURSOR_PENCIL, _( "Add graphic line" ) );
+
+ EDGE_MODULE* line = new EDGE_MODULE( m_board->m_Modules );
+
+ while( drawSegment( S_SEGMENT, reinterpret_cast<DRAWSEGMENT*&>( line ), startingPoint ) )
+ {
+ if( line )
+ {
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
+ line->SetParent( m_board->m_Modules );
+ line->SetLocalCoord();
+ m_board->m_Modules->GraphicalItems().PushFront( line );
+ startingPoint = line->GetEnd();
+ }
+ else
+ {
+ startingPoint = boost::none;
+ }
+
+ line = new EDGE_MODULE( m_board->m_Modules );
+ }
+ }
+ else // !m_editModules case
+ {
+ m_frame->SetToolID( ID_PCB_ADD_LINE_BUTT, wxCURSOR_PENCIL, _( "Add graphic line" ) );
+
+ DRAWSEGMENT* line = new DRAWSEGMENT;
+
+ while( drawSegment( S_SEGMENT, line, startingPoint ) )
+ {
+ if( line )
+ {
+ m_board->Add( line );
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( line, UR_NEW );
+ startingPoint = line->GetEnd();
+ }
+ else
+ {
+ startingPoint = boost::none;
+ }
+
+ line = new DRAWSEGMENT;
+ }
+ }
+
+ m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+
+ return 0;
+}
+
+
+int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
+{
+ if( m_editModules )
+ {
+ m_frame->SetToolID( ID_MODEDIT_CIRCLE_TOOL, wxCURSOR_PENCIL, _( "Add graphic circle" ) );
+
+ EDGE_MODULE* circle = new EDGE_MODULE( m_board->m_Modules );
+
+ while( drawSegment( S_CIRCLE, reinterpret_cast<DRAWSEGMENT*&>( circle ) ) )
+ {
+ if( circle )
+ {
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
+ circle->SetParent( m_board->m_Modules );
+ circle->SetLocalCoord();
+ m_board->m_Modules->GraphicalItems().PushFront( circle );
+ }
+
+ circle = new EDGE_MODULE( m_board->m_Modules );
+ }
+ }
+ else // !m_editModules case
+ {
+ m_frame->SetToolID( ID_PCB_CIRCLE_BUTT, wxCURSOR_PENCIL, _( "Add graphic circle" ) );
+
+ DRAWSEGMENT* circle = new DRAWSEGMENT;
+
+ while( drawSegment( S_CIRCLE, circle ) )
+ {
+ if( circle )
+ {
+ m_board->Add( circle );
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( circle, UR_NEW );
+ }
+
+ circle = new DRAWSEGMENT;
+ }
+ }
+
+ m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+
+ return 0;
+}
+
+
+int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
+{
+ if( m_editModules )
+ {
+ m_frame->SetToolID( ID_MODEDIT_ARC_TOOL, wxCURSOR_PENCIL, _( "Add graphic arc" ) );
+
+ EDGE_MODULE* arc = new EDGE_MODULE( m_board->m_Modules );
+
+ while( drawArc( reinterpret_cast<DRAWSEGMENT*&>( arc ) ) )
+ {
+ if( arc )
+ {
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
+ arc->SetParent( m_board->m_Modules );
+ arc->SetLocalCoord();
+ m_board->m_Modules->GraphicalItems().PushFront( arc );
+ }
+
+ arc = new EDGE_MODULE( m_board->m_Modules );
+ }
+ }
+ else // !m_editModules case
+ {
+ m_frame->SetToolID( ID_PCB_ARC_BUTT, wxCURSOR_PENCIL, _( "Add graphic arc" ) );
+
+ DRAWSEGMENT* arc = new DRAWSEGMENT;
+
+ while( drawArc( arc ) )
+ {
+ if( arc )
+ {
+ m_board->Add( arc );
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( arc, UR_NEW );
+ }
+
+ arc = new DRAWSEGMENT;
+ }
+ }
+
+ m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+
+ return 0;
+}
+
+
+int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
+{
+ if( m_editModules )
+ return placeTextModule();
+ else
+ return placeTextPcb();
+}
+
+
+int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
+{
+ DIMENSION* dimension = NULL;
+ int width, maxThickness;
+
+ // if one day it is possible to draw dimensions in the footprint editor,
+ // then hereby I'm letting you know that this tool does not handle UR_MODEDIT undo yet
+ assert( !m_editModules );
+
+ // Add a VIEW_GROUP that serves as a preview for the new item
+ KIGFX::VIEW_GROUP preview( m_view );
+ m_view->Add( &preview );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ m_controls->ShowCursor( true );
+ m_controls->SetSnapping( true );
+
+ Activate();
+ m_frame->SetToolID( ID_PCB_DIMENSION_BUTT, wxCURSOR_PENCIL, _( "Add dimension" ) );
+
+ enum DIMENSION_STEPS
+ {
+ SET_ORIGIN = 0,
+ SET_END,
+ SET_HEIGHT,
+ FINISHED
+ };
+ int step = SET_ORIGIN;
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+
+ if( evt->IsCancel() || evt->IsActivate() )
+ {
+ if( step != SET_ORIGIN ) // start from the beginning
+ {
+ preview.Clear();
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+
+ delete dimension;
+ step = SET_ORIGIN;
+ }
+ else
+ break;
+
+ if( evt->IsActivate() ) // now finish unconditionally
+ break;
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::incWidth ) && step != SET_ORIGIN )
+ {
+ dimension->SetWidth( dimension->GetWidth() + WIDTH_STEP );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::decWidth ) && step != SET_ORIGIN )
+ {
+ int width = dimension->GetWidth();
+
+ if( width > WIDTH_STEP )
+ {
+ dimension->SetWidth( width - WIDTH_STEP );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ switch( step )
+ {
+ case SET_ORIGIN:
+ {
+ LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer;
+
+ if( IsCopperLayer( layer ) || layer == Edge_Cuts )
+ {
+ DisplayInfoMessage( NULL, _( "Dimension not allowed on Copper or Edge Cut layers" ) );
+ --step;
+ }
+ else
+ {
+ // Init the new item attributes
+ dimension = new DIMENSION( m_board );
+ dimension->SetLayer( layer );
+ dimension->SetOrigin( wxPoint( cursorPos.x, cursorPos.y ) );
+ dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+ dimension->Text().SetSize( m_board->GetDesignSettings().m_PcbTextSize );
+
+ width = m_board->GetDesignSettings().m_PcbTextWidth;
+ maxThickness = Clamp_Text_PenSize( width, dimension->Text().GetSize() );
+
+ if( width > maxThickness )
+ width = maxThickness;
+
+ dimension->Text().SetThickness( width );
+ dimension->SetWidth( width );
+ dimension->AdjustDimensionDetails();
+
+ preview.Add( dimension );
+
+ m_controls->SetAutoPan( true );
+ m_controls->CaptureCursor( true );
+ }
+ }
+ break;
+
+ case SET_END:
+ dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+
+ // Dimensions that have origin and end in the same spot are not valid
+ if( dimension->GetOrigin() == dimension->GetEnd() )
+ --step;
+ break;
+
+ case SET_HEIGHT:
+ {
+ if( wxPoint( cursorPos.x, cursorPos.y ) != dimension->GetPosition() )
+ {
+ assert( dimension->GetOrigin() != dimension->GetEnd() );
+ assert( dimension->GetWidth() > 0 );
+
+ m_view->Add( dimension );
+ m_board->Add( dimension );
+ dimension->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( dimension, UR_NEW );
+
+ preview.Remove( dimension );
+ }
+ }
+ break;
+ }
+
+ if( ++step == FINISHED )
+ {
+ step = SET_ORIGIN;
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+ }
+ }
+
+ else if( evt->IsMotion() )
+ {
+ switch( step )
+ {
+ case SET_END:
+ dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+ break;
+
+ case SET_HEIGHT:
+ {
+ // Calculating the direction of travel perpendicular to the selected axis
+ double angle = dimension->GetAngle() + ( M_PI / 2 );
+
+ wxPoint pos( cursorPos.x, cursorPos.y );
+ wxPoint delta( pos - dimension->m_featureLineDO );
+ double height = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
+ dimension->SetHeight( height );
+ }
+ break;
+ }
+
+ // Show a preview of the item
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ if( step != SET_ORIGIN )
+ delete dimension;
+
+ m_controls->ShowCursor( false );
+ m_controls->SetSnapping( false );
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+ m_view->Remove( &preview );
+
+ m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+
+ return 0;
+}
+
+
+int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
+{
+ m_frame->SetToolID( ID_PCB_ZONES_BUTT, wxCURSOR_PENCIL, _( "Add zones" ) );
+
+ return drawZone( false );
+}
+
+
+int DRAWING_TOOL::DrawKeepout( const TOOL_EVENT& aEvent )
+{
+ m_frame->SetToolID( ID_PCB_KEEPOUT_AREA_BUTT, wxCURSOR_PENCIL, _( "Add keepout" ) );
+
+ return drawZone( true );
+}
+
+
+int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
+{
+ if( m_editModules && !m_board->m_Modules )
+ return 0;
+
+ DIALOG_DXF_IMPORT dlg( m_frame );
+ int dlgResult = dlg.ShowModal();
+
+ const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems();
+
+ if( dlgResult != wxID_OK || list.empty() )
+ return 0;
+
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+ VECTOR2I delta = cursorPos - (*list.begin())->GetPosition();
+
+ // Add a VIEW_GROUP that serves as a preview for the new item
+ KIGFX::VIEW_GROUP preview( m_view );
+
+ // Build the undo list & add items to the current view
+ std::list<BOARD_ITEM*>::const_iterator it, itEnd;
+ for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it )
+ {
+ KICAD_T type = (*it)->Type();
+ assert( type == PCB_LINE_T || type == PCB_TEXT_T );
+
+ if( type == PCB_LINE_T || type == PCB_TEXT_T )
+ preview.Add( *it );
+ }
+
+ BOARD_ITEM* firstItem = static_cast<BOARD_ITEM*>( *preview.Begin() );
+ m_view->Add( &preview );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ m_controls->ShowCursor( true );
+ m_controls->SetSnapping( true );
+
+ Activate();
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ cursorPos = m_controls->GetCursorPosition();
+
+ if( evt->IsMotion() )
+ {
+ delta = cursorPos - firstItem->GetPosition();
+
+ for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it )
+ static_cast<BOARD_ITEM*>( *it )->Move( wxPoint( delta.x, delta.y ) );
+
+ preview.ViewUpdate();
+ }
+
+ else if( evt->Category() == TC_COMMAND )
+ {
+ if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
+ {
+ for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it )
+ static_cast<BOARD_ITEM*>( *it )->Rotate( wxPoint( cursorPos.x, cursorPos.y ),
+ m_frame->GetRotationAngle() );
+
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
+ {
+ for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it )
+ static_cast<BOARD_ITEM*>( *it )->Flip( wxPoint( cursorPos.x, cursorPos.y ) );
+
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ else if( evt->IsCancel() || evt->IsActivate() )
+ {
+ preview.FreeItems();
+ break;
+ }
+ }
+
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ // Place the drawing
+ if( m_editModules )
+ {
+ assert( m_board->m_Modules );
+ m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
+ m_board->m_Modules->SetLastEditTime();
+
+ for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it )
+ {
+ BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it );
+ BOARD_ITEM* converted = NULL;
+
+ // Modules use different types for the same things,
+ // so we need to convert imported items to appropriate classes.
+ switch( item->Type() )
+ {
+ case PCB_TEXT_T:
+ converted = new TEXTE_MODULE( m_board->m_Modules );
+ // Copy coordinates, layer, etc.
+ *static_cast<TEXTE_PCB*>( converted ) = *static_cast<TEXTE_PCB*>( item );
+ static_cast<TEXTE_MODULE*>( converted )->SetLocalCoord();
+ break;
+
+ case PCB_LINE_T:
+ converted = new EDGE_MODULE( m_board->m_Modules );
+ // Copy coordinates, layer, etc.
+ *static_cast<DRAWSEGMENT*>( converted ) = *static_cast<DRAWSEGMENT*>( item );
+ static_cast<EDGE_MODULE*>( converted )->SetLocalCoord();
+ break;
+
+ default:
+ assert( false );
+ break;
+ }
+
+ delete item;
+
+ if( converted )
+ {
+ m_board->m_Modules->Add( converted );
+ m_view->Add( converted );
+ }
+ }
+ }
+ else // !m_editModules case
+ {
+ PICKED_ITEMS_LIST picklist;
+
+ for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it )
+ {
+ BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it );
+ m_board->Add( item );
+
+ ITEM_PICKER itemWrapper( item, UR_NEW );
+ picklist.PushItem( itemWrapper );
+
+ m_view->Add( item );
+ }
+
+ m_frame->SaveCopyInUndoList( picklist, UR_NEW );
+ }
+
+ m_frame->OnModify();
+ break;
+ }
+ }
+
+ preview.Clear();
+
+ m_controls->ShowCursor( false );
+ m_controls->SetSnapping( false );
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+ m_view->Remove( &preview );
+
+ return 0;
+}
+
+
+int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
+{
+ assert( m_editModules );
+
+ Activate();
+ m_frame->SetToolID( ID_MODEDIT_ANCHOR_TOOL, wxCURSOR_PENCIL,
+ _( "Place the footprint anchor" ) );
+
+ m_controls->ShowCursor( true );
+ m_controls->SetSnapping( true );
+ m_controls->SetAutoPan( true );
+ m_controls->CaptureCursor( false );
+
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ if( evt->IsClick( BUT_LEFT ) )
+ {
+ m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
+ m_board->m_Modules->SetLastEditTime();
+
+ // set the new relative internal local coordinates of footprint items
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+ wxPoint moveVector = m_board->m_Modules->GetPosition() - wxPoint( cursorPos.x, cursorPos.y );
+ m_board->m_Modules->MoveAnchorPosition( moveVector );
+
+ m_board->m_Modules->ViewUpdate();
+
+ // Usually, we do not need to change twice the anchor position,
+ // so deselect the active tool
+ break;
+ }
+
+ else if( evt->IsCancel() || evt->IsActivate() )
+ break;
+ }
+
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+ m_controls->SetSnapping( false );
+ m_controls->ShowCursor( false );
+
+ m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+
+ return 0;
+}
+
+
+bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
+ boost::optional<VECTOR2D> aStartingPoint )
+{
+ // Only two shapes are currently supported
+ assert( aShape == S_SEGMENT || aShape == S_CIRCLE );
+
+ DRAWSEGMENT line45;
+
+ // Add a VIEW_GROUP that serves as a preview for the new item
+ KIGFX::VIEW_GROUP preview( m_view );
+ m_view->Add( &preview );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ m_controls->ShowCursor( true );
+ m_controls->SetSnapping( true );
+
+ Activate();
+
+ bool direction45 = false; // 45 degrees only mode
+ bool started = false;
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+
+ if( aStartingPoint )
+ {
+ LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer;
+
+ // Init the new item attributes
+ aGraphic->SetShape( (STROKE_T) aShape );
+ aGraphic->SetWidth( m_lineWidth );
+ aGraphic->SetStart( wxPoint( aStartingPoint->x, aStartingPoint->y ) );
+ aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+ aGraphic->SetLayer( layer );
+
+ if( aShape == S_SEGMENT )
+ line45 = *aGraphic; // used only for direction 45 mode with lines
+
+ preview.Add( aGraphic );
+ m_controls->SetAutoPan( true );
+ m_controls->CaptureCursor( true );
+
+ started = true;
+ }
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ bool updatePreview = false; // should preview be updated
+ cursorPos = m_controls->GetCursorPosition();
+
+ // Enable 45 degrees lines only mode by holding control
+ if( direction45 != evt->Modifier( MD_CTRL ) && started && aShape == S_SEGMENT )
+ {
+ direction45 = evt->Modifier( MD_CTRL );
+
+ if( direction45 )
+ {
+ preview.Add( &line45 );
+ make45DegLine( aGraphic, &line45 );
+ }
+ else
+ {
+ preview.Remove( &line45 );
+ aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+ }
+
+ updatePreview = true;
+ }
+
+ if( evt->IsCancel() || evt->IsActivate() || evt->IsAction( &COMMON_ACTIONS::layerChanged ) )
+ {
+ preview.Clear();
+ updatePreview = true;
+ delete aGraphic;
+ aGraphic = NULL;
+ break;
+ }
+
+ else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
+ {
+ if( !started )
+ {
+ LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer;
+
+ if( IsCopperLayer( layer ) )
+ {
+ DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) );
+ }
+ else
+ {
+ // Init the new item attributes
+ aGraphic->SetShape( (STROKE_T) aShape );
+ m_lineWidth = getSegmentWidth( layer );
+ aGraphic->SetWidth( m_lineWidth );
+ aGraphic->SetStart( wxPoint( cursorPos.x, cursorPos.y ) );
+ aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+ aGraphic->SetLayer( layer );
+
+ if( aShape == S_SEGMENT )
+ line45 = *aGraphic; // used only for direction 45 mode with lines
+
+ preview.Add( aGraphic );
+ m_controls->SetAutoPan( true );
+ m_controls->CaptureCursor( true );
+
+ started = true;
+ }
+ }
+ else
+ {
+ if( aGraphic->GetEnd() == aGraphic->GetStart() ||
+ ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) )
+ // User has clicked twice in the same spot
+ { // a clear sign that the current drawing is finished
+ if( direction45 )
+ {
+ // Now we have to add the helper line as well
+ if( m_editModules )
+ {
+ EDGE_MODULE* l = new EDGE_MODULE( m_board->m_Modules );
+
+ // Copy coordinates, layer, etc.
+ *static_cast<DRAWSEGMENT*>( l ) = line45;
+ l->SetEnd( aGraphic->GetStart() );
+ l->SetLocalCoord();
+
+ m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
+ m_board->m_Modules->SetLastEditTime();
+ m_board->m_Modules->GraphicalItems().PushFront( l );
+
+ m_view->Add( l );
+ l->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ else
+ {
+ DRAWSEGMENT* l = static_cast<DRAWSEGMENT*>( line45.Clone() );
+ l->SetEnd( aGraphic->GetStart() );
+
+ m_frame->SaveCopyInUndoList( l, UR_NEW );
+ m_board->Add( l );
+
+ m_view->Add( l );
+ l->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ m_frame->OnModify();
+ }
+
+ delete aGraphic;
+ aGraphic = NULL;
+ }
+ else
+ {
+ assert( aGraphic->GetLength() > 0 );
+ assert( aGraphic->GetWidth() > 0 );
+
+ m_view->Add( aGraphic );
+ aGraphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ preview.Clear();
+ break;
+ }
+ }
+
+ else if( evt->IsMotion() )
+ {
+ // 45 degree lines
+ if( direction45 && aShape == S_SEGMENT )
+ make45DegLine( aGraphic, &line45 );
+ else
+ aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+
+ updatePreview = true;
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::incWidth ) )
+ {
+ m_lineWidth += WIDTH_STEP;
+ aGraphic->SetWidth( m_lineWidth );
+ updatePreview = true;
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::decWidth ) )
+ {
+ if( m_lineWidth > (unsigned) WIDTH_STEP )
+ {
+ m_lineWidth -= WIDTH_STEP;
+ aGraphic->SetWidth( m_lineWidth );
+ updatePreview = true;
+ }
+ }
+
+ if( updatePreview )
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ m_controls->ShowCursor( false );
+ m_controls->SetSnapping( false );
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+ m_view->Remove( &preview );
+
+ return started;
+}
+
+
+bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic )
+{
+ bool clockwise = true; // drawing direction of the arc
+ double startAngle = 0.0f; // angle of the first arc line
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+
+ DRAWSEGMENT helperLine;
+ helperLine.SetShape( S_SEGMENT );
+ helperLine.SetLayer( Dwgs_User );
+ helperLine.SetWidth( 1 );
+
+ // Add a VIEW_GROUP that serves as a preview for the new item
+ KIGFX::VIEW_GROUP preview( m_view );
+ m_view->Add( &preview );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ m_controls->ShowCursor( true );
+ m_controls->SetSnapping( true );
+
+ Activate();
+
+ enum ARC_STEPS
+ {
+ SET_ORIGIN = 0,
+ SET_END,
+ SET_ANGLE,
+ FINISHED
+ };
+ int step = SET_ORIGIN;
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ cursorPos = m_controls->GetCursorPosition();
+
+ if( evt->IsCancel() || evt->IsActivate() )
+ {
+ preview.Clear();
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ delete aGraphic;
+ aGraphic = NULL;
+ break;
+ }
+
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ switch( step )
+ {
+ case SET_ORIGIN:
+ {
+ LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer;
+
+ if( IsCopperLayer( layer ) )
+ {
+ DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) );
+ --step;
+ }
+ else
+ {
+ // Init the new item attributes
+ aGraphic->SetShape( S_ARC );
+ aGraphic->SetAngle( 0.0 );
+ aGraphic->SetWidth( getSegmentWidth( layer ) );
+ aGraphic->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) );
+ aGraphic->SetLayer( layer );
+
+ helperLine.SetStart( aGraphic->GetCenter() );
+ helperLine.SetEnd( aGraphic->GetCenter() );
+
+ preview.Add( aGraphic );
+ preview.Add( &helperLine );
+
+ m_controls->SetAutoPan( true );
+ m_controls->CaptureCursor( true );
+ }
+ }
+ break;
+
+ case SET_END:
+ {
+ if( wxPoint( cursorPos.x, cursorPos.y ) != aGraphic->GetCenter() )
+ {
+ VECTOR2D startLine( aGraphic->GetArcStart() - aGraphic->GetCenter() );
+ startAngle = startLine.Angle();
+ aGraphic->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) );
+ }
+ else
+ --step; // one another chance to draw a proper arc
+ }
+ break;
+
+ case SET_ANGLE:
+ {
+ if( wxPoint( cursorPos.x, cursorPos.y ) != aGraphic->GetArcStart() && aGraphic->GetAngle() != 0 )
+ {
+ assert( aGraphic->GetArcStart() != aGraphic->GetArcEnd() );
+ assert( aGraphic->GetWidth() > 0 );
+
+ m_view->Add( aGraphic );
+ aGraphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+
+ preview.Remove( aGraphic );
+ preview.Remove( &helperLine );
+ }
+ else
+ --step; // one another chance to draw a proper arc
+ }
+ break;
+ }
+
+ if( ++step == FINISHED )
+ break;
+ }
+
+ else if( evt->IsMotion() )
+ {
+ switch( step )
+ {
+ case SET_END:
+ helperLine.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+ aGraphic->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) );
+ break;
+
+ case SET_ANGLE:
+ {
+ VECTOR2D endLine( wxPoint( cursorPos.x, cursorPos.y ) - aGraphic->GetCenter() );
+ double newAngle = RAD2DECIDEG( endLine.Angle() - startAngle );
+
+ // Adjust the new angle to (counter)clockwise setting
+ if( clockwise && newAngle < 0.0 )
+ newAngle += 3600.0;
+ else if( !clockwise && newAngle > 0.0 )
+ newAngle -= 3600.0;
+
+ aGraphic->SetAngle( newAngle );
+ }
+ break;
+ }
+
+ // Show a preview of the item
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::incWidth ) )
+ {
+ aGraphic->SetWidth( aGraphic->GetWidth() + WIDTH_STEP );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::decWidth ) )
+ {
+ int width = aGraphic->GetWidth();
+
+ if( width > WIDTH_STEP )
+ {
+ aGraphic->SetWidth( width - WIDTH_STEP );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::arcPosture ) )
+ {
+ if( clockwise )
+ aGraphic->SetAngle( aGraphic->GetAngle() - 3600.0 );
+ else
+ aGraphic->SetAngle( aGraphic->GetAngle() + 3600.0 );
+
+ clockwise = !clockwise;
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ m_controls->ShowCursor( false );
+ m_controls->SetSnapping( false );
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+ m_view->Remove( &preview );
+
+ return ( step > SET_ORIGIN );
+}
+
+
+int DRAWING_TOOL::drawZone( bool aKeepout )
+{
+ ZONE_CONTAINER* zone = NULL;
+ DRAWSEGMENT line45;
+ DRAWSEGMENT* helperLine = NULL; // we will need more than one helper line
+
+ // if one day it is possible to draw zones in the footprint editor,
+ // then hereby I'm letting you know that this tool does not handle UR_MODEDIT undo yet
+ assert( !m_editModules );
+
+ // Add a VIEW_GROUP that serves as a preview for the new item
+ KIGFX::VIEW_GROUP preview( m_view );
+ m_view->Add( &preview );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ m_controls->ShowCursor( true );
+ m_controls->SetSnapping( true );
+
+ Activate();
+
+ VECTOR2I origin;
+ int numPoints = 0;
+ bool direction45 = false; // 45 degrees only mode
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ bool updatePreview = false; // should preview be updated
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+
+ // Enable 45 degrees lines only mode by holding control
+ if( direction45 != ( evt->Modifier( MD_CTRL ) && numPoints > 0 ) )
+ {
+ direction45 = evt->Modifier( MD_CTRL );
+
+ if( direction45 )
+ {
+ preview.Add( &line45 );
+ make45DegLine( helperLine, &line45 );
+ }
+ else
+ {
+ preview.Remove( &line45 );
+ helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+ }
+
+ updatePreview = true;
+ }
+
+ if( evt->IsCancel() || evt->IsActivate() )
+ {
+ if( numPoints > 0 ) // cancel the current zone
+ {
+ delete zone;
+ zone = NULL;
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+
+ if( direction45 )
+ {
+ preview.Remove( &line45 );
+ direction45 = false;
+ }
+
+ preview.FreeItems();
+ updatePreview = true;
+
+ numPoints = 0;
+ }
+ else // there is no zone currently drawn - just stop the tool
+ break;
+
+ if( evt->IsActivate() ) // now finish unconditionally
+ break;
+ }
+
+ else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
+ {
+ // Check if it is double click / closing line (so we have to finish the zone)
+ if( evt->IsDblClick( BUT_LEFT ) || ( numPoints > 0 && cursorPos == origin ) )
+ {
+ if( numPoints > 2 ) // valid zone consists of more than 2 points
+ {
+ assert( zone->GetNumCorners() > 2 );
+
+ // Finish the zone
+ if( direction45 )
+ zone->AppendCorner( cursorPos == origin ? line45.GetStart() : line45.GetEnd() );
+
+ zone->Outline()->CloseLastContour();
+ zone->Outline()->RemoveNullSegments();
+
+ m_board->Add( zone );
+ m_view->Add( zone );
+
+ if( !aKeepout )
+ static_cast<PCB_EDIT_FRAME*>( m_frame )->Fill_Zone( zone );
+
+ zone->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ m_board->GetRatsnest()->Update( zone );
+
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( zone, UR_NEW );
+
+ zone = NULL;
+ }
+ else
+ {
+ delete zone;
+ zone = NULL;
+ }
+
+ numPoints = 0;
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+
+ if( direction45 )
+ {
+ preview.Remove( &line45 );
+ direction45 = false;
+ }
+
+ preview.FreeItems();
+ updatePreview = true;
+ }
+ else
+ {
+ if( numPoints == 0 ) // it's the first click
+ {
+ // Get the current default settings for zones
+ ZONE_SETTINGS zoneInfo = m_frame->GetZoneSettings();
+ zoneInfo.m_CurrentZone_Layer = m_frame->GetScreen()->m_Active_Layer;
+ zoneInfo.SetIsKeepout(aKeepout);
+
+ m_controls->SetAutoPan( true );
+ m_controls->CaptureCursor( true );
+
+ // Show options dialog
+ ZONE_EDIT_T dialogResult;
+
+ if( aKeepout )
+ dialogResult = InvokeKeepoutAreaEditor( m_frame, &zoneInfo );
+ else
+ {
+ if( IsCopperLayer( zoneInfo.m_CurrentZone_Layer ) )
+ dialogResult = InvokeCopperZonesEditor( m_frame, &zoneInfo );
+ else
+ dialogResult = InvokeNonCopperZonesEditor( m_frame, NULL, &zoneInfo );
+ }
+
+ if( dialogResult == ZONE_ABORT )
+ {
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+ continue;
+ }
+
+ // Apply the selected settings
+ zone = new ZONE_CONTAINER( m_board );
+ zoneInfo.ExportSetting( *zone );
+ m_frame->GetGalCanvas()->SetTopLayer( zoneInfo.m_CurrentZone_Layer );
+
+ // Add the first point
+ zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer,
+ cursorPos.x, cursorPos.y,
+ zone->GetHatchStyle() );
+ origin = cursorPos;
+
+ // Helper line represents the currently drawn line of the zone polygon
+ helperLine = new DRAWSEGMENT;
+ helperLine->SetShape( S_SEGMENT );
+ helperLine->SetWidth( 1 );
+ helperLine->SetLayer( zoneInfo.m_CurrentZone_Layer );
+ helperLine->SetStart( wxPoint( cursorPos.x, cursorPos.y ) );
+ helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+ line45 = *helperLine;
+
+ preview.Add( helperLine );
+ }
+ else
+ {
+ zone->AppendCorner( helperLine->GetEnd() );
+ helperLine = new DRAWSEGMENT( *helperLine );
+ helperLine->SetStart( helperLine->GetEnd() );
+ preview.Add( helperLine );
+ }
+
+ ++numPoints;
+ updatePreview = true;
+ }
+ }
+
+ else if( evt->IsMotion() && numPoints > 0 )
+ {
+ // 45 degree lines
+ if( direction45 )
+ make45DegLine( helperLine, &line45 );
+ else
+ helperLine->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+
+ // Show a preview of the item
+ updatePreview = true;
+ }
+
+ if( updatePreview )
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ m_controls->ShowCursor( false );
+ m_controls->SetSnapping( false );
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+ m_view->Remove( &preview );
+
+ m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+
+ return 0;
+}
+
+
+int DRAWING_TOOL::placeTextModule()
+{
+ TEXTE_MODULE* text = new TEXTE_MODULE( NULL );
+ const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
+
+ assert( m_editModules );
+
+ // Add a VIEW_GROUP that serves as a preview for the new item
+ KIGFX::VIEW_GROUP preview( m_view );
+ m_view->Add( &preview );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ m_controls->ShowCursor( true );
+ m_controls->SetSnapping( true );
+ // do not capture or auto-pan until we start placing some text
+
+ Activate();
+ m_frame->SetToolID( ID_MODEDIT_TEXT_TOOL, wxCURSOR_PENCIL, _( "Add text" ) );
+ bool placing = false;
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+
+ if( evt->IsCancel() || evt->IsActivate() )
+ {
+ preview.Clear();
+ preview.ViewUpdate();
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+ m_controls->ShowCursor( true );
+
+ if( !placing || evt->IsActivate() )
+ {
+ delete text;
+ break;
+ }
+ else
+ {
+ placing = false; // start from the beginning
+ }
+ }
+
+ else if( text && evt->Category() == TC_COMMAND )
+ {
+ if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
+ {
+ text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
+ {
+ text->Flip( text->GetPosition() );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ if( !placing )
+ {
+ text->SetSize( dsnSettings.m_ModuleTextSize );
+ text->SetThickness( dsnSettings.m_ModuleTextWidth );
+ text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) );
+
+ DialogEditModuleText textDialog( m_frame, text, NULL );
+ placing = textDialog.ShowModal() && ( text->GetText().Length() > 0 );
+
+ if( !placing )
+ continue;
+
+ m_controls->CaptureCursor( true );
+ m_controls->SetAutoPan( true );
+ m_controls->ShowCursor( false );
+ text->SetParent( m_board->m_Modules ); // it has to set after the settings dialog
+ // otherwise the dialog stores it in undo buffer
+ preview.Add( text );
+ }
+ else
+ {
+ assert( text->GetText().Length() > 0 );
+ assert( text->GetSize().x > 0 && text->GetSize().y > 0 );
+
+ text->SetLocalCoord();
+ text->ClearFlags();
+
+ // Module has to be saved before any modification is made
+ m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
+ m_board->m_Modules->SetLastEditTime();
+ m_board->m_Modules->GraphicalItems().PushFront( text );
+
+ m_view->Add( text );
+ text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+
+ m_frame->OnModify();
+
+ preview.Remove( text );
+ m_controls->CaptureCursor( false );
+ m_controls->SetAutoPan( false );
+ m_controls->ShowCursor( true );
+
+ text = new TEXTE_MODULE( NULL );
+ placing = false;
+ }
+ }
+
+ else if( text && evt->IsMotion() )
+ {
+ text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) );
+
+ // Show a preview of the item
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ m_controls->ShowCursor( false );
+ m_controls->SetSnapping( false );
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+ m_view->Remove( &preview );
+
+ m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+
+ return 0;
+}
+
+
+int DRAWING_TOOL::placeTextPcb()
+{
+ TEXTE_PCB* text = NULL;
+
+ assert( !m_editModules );
+
+ // Add a VIEW_GROUP that serves as a preview for the new item
+ KIGFX::VIEW_GROUP preview( m_view );
+ m_view->Add( &preview );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ m_controls->ShowCursor( true );
+ m_controls->SetSnapping( true );
+ // do not capture or auto-pan until we start placing some text
+
+ Activate();
+ m_frame->SetToolID( ID_PCB_ADD_TEXT_BUTT, wxCURSOR_PENCIL, _( "Add text" ) );
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+
+ if( evt->IsCancel() || evt->IsActivate() )
+ {
+ if( text )
+ {
+ // Delete the old text and have another try
+ m_board->Delete( text ); // it was already added by CreateTextPcb()
+ text = NULL;
+
+ preview.Clear();
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+ m_controls->ShowCursor( true );
+ }
+ else
+ break;
+
+ if( evt->IsActivate() ) // now finish unconditionally
+ break;
+ }
+
+ else if( text && evt->Category() == TC_COMMAND )
+ {
+ if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
+ {
+ text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
+ {
+ text->Flip( text->GetPosition() );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ if( !text )
+ {
+ // Init the new item attributes
+ text = static_cast<PCB_EDIT_FRAME*>( m_frame )->CreateTextePcb( NULL );
+
+ if( text == NULL )
+ continue;
+
+ m_controls->CaptureCursor( true );
+ m_controls->SetAutoPan( true );
+ preview.Add( text );
+ }
+ else
+ {
+ assert( text->GetText().Length() > 0 );
+ assert( text->GetSize().x > 0 && text->GetSize().y > 0 );
+
+ text->ClearFlags();
+ m_view->Add( text );
+ // m_board->Add( text ); // it is already added by CreateTextePcb()
+ text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( text, UR_NEW );
+
+ preview.Remove( text );
+ m_controls->CaptureCursor( false );
+ m_controls->SetAutoPan( false );
+
+ text = NULL;
+ }
+ }
+
+ else if( text && evt->IsMotion() )
+ {
+ text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) );
+
+ // Show a preview of the item
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ m_controls->ShowCursor( false );
+ m_controls->SetSnapping( false );
+ m_controls->SetAutoPan( false );
+ m_controls->CaptureCursor( false );
+ m_view->Remove( &preview );
+
+ m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+
+ return 0;
+}
+
+
+void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const
+{
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+ VECTOR2I origin( aSegment->GetStart() );
+ DIRECTION_45 direction( origin - cursorPos );
+ SHAPE_LINE_CHAIN newChain = direction.BuildInitialTrace( origin, cursorPos );
+
+ if( newChain.PointCount() > 2 )
+ {
+ aSegment->SetEnd( wxPoint( newChain.Point( -2 ).x, newChain.Point( -2 ).y ) );
+ aHelper->SetStart( wxPoint( newChain.Point( -2 ).x, newChain.Point( -2 ).y ) );
+ aHelper->SetEnd( wxPoint( newChain.Point( -1 ).x, newChain.Point( -1 ).y ) );
+ }
+ else
+ {
+ aSegment->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+ aHelper->SetStart( wxPoint( cursorPos.x, cursorPos.y ) );
+ aHelper->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
+ }
+}
+
+
+void DRAWING_TOOL::SetTransitions()
+{
+ Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() );
+ Go( &DRAWING_TOOL::DrawCircle, COMMON_ACTIONS::drawCircle.MakeEvent() );
+ Go( &DRAWING_TOOL::DrawArc, COMMON_ACTIONS::drawArc.MakeEvent() );
+ Go( &DRAWING_TOOL::DrawDimension, COMMON_ACTIONS::drawDimension.MakeEvent() );
+ Go( &DRAWING_TOOL::DrawZone, COMMON_ACTIONS::drawZone.MakeEvent() );
+ Go( &DRAWING_TOOL::DrawKeepout, COMMON_ACTIONS::drawKeepout.MakeEvent() );
+ Go( &DRAWING_TOOL::PlaceText, COMMON_ACTIONS::placeText.MakeEvent() );
+ Go( &DRAWING_TOOL::PlaceDXF, COMMON_ACTIONS::placeDXF.MakeEvent() );
+ Go( &DRAWING_TOOL::SetAnchor, COMMON_ACTIONS::setAnchor.MakeEvent() );
+}
+
+
+int DRAWING_TOOL::getSegmentWidth( unsigned int aLayer ) const
+{
+ assert( m_board );
+
+ if( aLayer == Edge_Cuts )
+ return m_board->GetDesignSettings().m_EdgeSegmentWidth;
+ else if( m_editModules )
+ return m_board->GetDesignSettings().m_ModuleSegmentWidth;
+ else
+ return m_board->GetDesignSettings().m_DrawSegmentWidth;
+}
+
+
+const int DRAWING_TOOL::WIDTH_STEP = 100000;
diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h
new file mode 100644
index 0000000..432da1e
--- /dev/null
+++ b/pcbnew/tools/drawing_tool.h
@@ -0,0 +1,200 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __DRAWING_TOOL_H
+#define __DRAWING_TOOL_H
+
+#include <tool/tool_interactive.h>
+#include <boost/optional.hpp>
+
+namespace KIGFX
+{
+ class VIEW;
+ class VIEW_CONTROLS;
+}
+class BOARD;
+class PCB_EDIT_FRAME;
+class DRAWSEGMENT;
+
+/**
+ * Class DRAWING_TOOL
+ *
+ * Tool responsible for drawing graphical elements like lines, arcs, circles, etc.
+ */
+
+class DRAWING_TOOL : public TOOL_INTERACTIVE
+{
+public:
+ DRAWING_TOOL();
+ ~DRAWING_TOOL();
+
+ /// @copydoc TOOL_INTERACTIVE::Reset()
+ void Reset( RESET_REASON aReason );
+
+ /**
+ * Function DrawLine()
+ * Starts interactively drawing a line. After invoking the function it expects the user
+ * to click at least two times to determine the origin and the end for a line. If there are
+ * more clicks, the line is drawn as a continous polyline.
+ */
+ int DrawLine( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function DrawCircle()
+ * Starts interactively drawing a circle. After invoking the function it expects the user
+ * to first click on a point that is going to be used as the center of the circle. The second
+ * click determines the circle radius.
+ */
+ int DrawCircle( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function DrawArc()
+ * Starts interactively drawing an arc. After invoking the function it expects the user
+ * to first click on a point that is going to be used as the center of the arc. The second
+ * click determines the origin and radius, the third one - the angle.
+ */
+ int DrawArc( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function PlaceText()
+ * Displays a dialog that allows to input text and its settings and then lets the user decide
+ * where to place the text in editor.
+ */
+ int PlaceText( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function DrawDimension()
+ * Starts interactively drawing a dimension. After invoking the function it expects the user
+ * to first click on a point that is going to be used as the origin of the dimension.
+ * The second click determines the end and the third click modifies its height.
+ */
+ int DrawDimension( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function DrawZone()
+ * Starts interactively drawing a zone. After invoking the function a zone settings dialog
+ * is displayed. After confirmation it allows the user to set points that are going to be used
+ * as a boundary polygon of the zone. Double click or clicking on the origin of the boundary
+ * polyline finishes the drawing.
+ */
+ int DrawZone( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function DrawKeepout()
+ * Starts interactively drawing a keepout area. After invoking the function an area settings
+ * dialog is displayed. After confirmation it allows the user to set points that are going to
+ * be used as a boundary polygon of the area. Double click or clicking on the origin of the
+ * boundary polyline finishes the drawing.
+ */
+ int DrawKeepout( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function PlaceDXF()
+ * Places a drawing imported from a DXF file in module editor.
+ */
+ int PlaceDXF( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function SetAnchor()
+ * Places the footprint anchor (only in module editor).
+ */
+ int SetAnchor( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function EditModules()
+ * Toggles edit module mode. When enabled, one may select parts of modules individually
+ * (graphics, pads, etc.), so they can be modified.
+ * @param aEnabled decides if the mode should be enabled.
+ */
+ void EditModules( bool aEnabled )
+ {
+ m_editModules = aEnabled;
+ }
+
+ ///> Sets up handlers for various events.
+ void SetTransitions();
+
+private:
+ ///> Starts drawing a selected shape (i.e. DRAWSEGMENT).
+ ///> @param aShape is the type of created shape (@see STROKE_T).
+ ///> @param aGraphic is an object that is going to be used by the tool for drawing. It has to
+ ///> be already created. The tool deletes the object if it is not added to a BOARD.
+ ///> @return False if the tool was cancelled before the origin was set or origin and end are
+ ///> the same point.
+ bool drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
+ boost::optional<VECTOR2D> aStartingPoint = boost::none );
+
+ ///> Starts drawing an arc.
+ ///> @param aGraphic is an object that is going to be used by the tool for drawing. It has to
+ ///> be already created. The tool deletes the object if it is not added to a BOARD.
+ ///> @return False if the tool was cancelled before the origin was set or origin and end are
+ ///> the same point.
+ bool drawArc( DRAWSEGMENT*& aGraphic );
+
+ ///> Draws a polygon, that is added as a zone or a keepout area.
+ ///> @param aKeepout decides if the drawn polygon is a zone or a keepout area.
+ int drawZone( bool aKeepout );
+
+ /**
+ * Function placeTextModule()
+ * Displays a dialog that allows to input text and its settings and then lets the user decide
+ * where to place the text in module .
+ */
+ int placeTextModule();
+
+ /**
+ * Function placeTextPcb()
+ * Displays a dialog that allows to input text and its settings and then lets the user decide
+ * where to place the text in board editor.
+ */
+ int placeTextPcb();
+
+ /**
+ * Function make45DegLine()
+ * Forces a DRAWSEGMENT to be drawn at multiple of 45 degrees. The origin stays the same,
+ * the end of the aSegment is modified according to the current cursor position.
+ * @param aSegment is the segment that is currently drawn.
+ * @param aHelper is a helper line that shows the next possible segment.
+ */
+ void make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const;
+
+ ///> Returns the appropriate width for a segment depending on the settings.
+ int getSegmentWidth( unsigned int aLayer ) const;
+
+ KIGFX::VIEW* m_view;
+ KIGFX::VIEW_CONTROLS* m_controls;
+ BOARD* m_board;
+ PCB_EDIT_FRAME* m_frame;
+
+ /// Edit module mode flag
+ bool m_editModules;
+
+ /// Stores the current line width for multisegment drawing.
+ unsigned int m_lineWidth;
+
+ // How does line width change after one -/+ key press.
+ static const int WIDTH_STEP;
+};
+
+#endif /* __DRAWING_TOOL_H */
diff --git a/pcbnew/tools/edit_constraints.cpp b/pcbnew/tools/edit_constraints.cpp
new file mode 100644
index 0000000..b73ac0c
--- /dev/null
+++ b/pcbnew/tools/edit_constraints.cpp
@@ -0,0 +1,191 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "edit_constraints.h"
+#include "edit_points.h"
+
+#include <geometry/seg.h>
+
+#include <common.h>
+
+void EC_VERTICAL::Apply( EDIT_POINT& aHandle )
+{
+ VECTOR2I point = aHandle.GetPosition();
+ point.x = m_constrainer.GetPosition().x;
+ aHandle.SetPosition( point );
+}
+
+
+void EC_HORIZONTAL::Apply( EDIT_POINT& aHandle )
+{
+ VECTOR2I point = aHandle.GetPosition();
+ point.y = m_constrainer.GetPosition().y;
+ aHandle.SetPosition( point );
+}
+
+
+void EC_45DEGREE::Apply( EDIT_POINT& aHandle )
+{
+ // Current line vector
+ VECTOR2I lineVector( aHandle.GetPosition() - m_constrainer.GetPosition() );
+ double angle = lineVector.Angle();
+
+ // Find the closest angle, which is a multiple of 45 degrees
+ double newAngle = KiROUND( angle / ( M_PI / 4.0 ) ) * M_PI / 4.0;
+ VECTOR2I newLineVector = lineVector.Rotate( newAngle - angle );
+
+ aHandle.SetPosition( m_constrainer.GetPosition() + newLineVector );
+}
+
+
+EC_LINE::EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) :
+ EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ), m_constrainer( aConstrainer )
+{
+ m_line = m_constrained.GetPosition() - m_constrainer.GetPosition();
+}
+
+
+void EC_LINE::Apply( EDIT_POINT& aHandle )
+{
+ SEG main( m_constrainer.GetPosition(), m_constrainer.GetPosition() + m_line );
+ SEG projection( aHandle.GetPosition(), aHandle.GetPosition() + m_line.Perpendicular() );
+
+ if( OPT_VECTOR2I intersect = projection.IntersectLines( main ) )
+ aHandle.SetPosition( *intersect );
+}
+
+
+void EC_CIRCLE::Apply( EDIT_POINT& aHandle )
+{
+ VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition();
+ VECTOR2I centerToPoint = aHandle.GetPosition() - m_center.GetPosition();
+
+ int radius = centerToEnd.EuclideanNorm();
+ double angle = centerToPoint.Angle();
+
+ VECTOR2I newLine( radius, 0 );
+ newLine = newLine.Rotate( angle );
+
+ aHandle.SetPosition( m_center.GetPosition() + newLine );
+}
+
+
+EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) :
+ EDIT_CONSTRAINT<EDIT_LINE>( aLine ),
+ m_colinearConstraint( NULL ), m_editPoints( aPoints )
+{
+ // Dragged segment endings
+ EDIT_POINT& origin = aLine.GetOrigin();
+ EDIT_POINT& end = aLine.GetEnd();
+
+ // Previous and next points, to make constraining lines (adjacent to the dragged line)
+ EDIT_POINT& prevOrigin = *aPoints.Previous( origin, false );
+ EDIT_POINT& nextEnd = *aPoints.Next( end, false );
+
+ // Constraints for segments adjacent to the dragged one
+ m_originSideConstraint = new EC_LINE( origin, prevOrigin );
+ m_endSideConstraint = new EC_LINE( end, nextEnd );
+
+ // Store the current vector of the line
+ m_draggedVector = end.GetPosition() - origin.GetPosition();
+
+ // Check for colinearity
+ SEG originSide( origin.GetPosition(), prevOrigin.GetPosition() );
+ SEG endSide( end.GetPosition(), nextEnd.GetPosition() );
+ SEG dragged( origin.GetPosition(), end.GetPosition() );
+
+ if( dragged.Collinear( originSide ) )
+ m_colinearConstraint = m_originSideConstraint;
+ else if( dragged.Collinear( endSide ) )
+ m_colinearConstraint = m_endSideConstraint;
+}
+
+
+EC_CONVERGING::~EC_CONVERGING()
+{
+ delete m_originSideConstraint;
+ delete m_endSideConstraint;
+ // m_colinearConstraint should not be freed, it is a pointer to one of the above
+}
+
+
+void EC_CONVERGING::Apply( EDIT_LINE& aHandle )
+{
+ // The dragged segment endpoints
+ EDIT_POINT& origin = aHandle.GetOrigin();
+ EDIT_POINT& end = aHandle.GetEnd();
+
+ if( m_colinearConstraint )
+ {
+ m_colinearConstraint->Apply( origin );
+ m_colinearConstraint->Apply( end );
+ }
+
+ // The dragged segment
+ SEG dragged( origin.GetPosition(), origin.GetPosition() + m_draggedVector );
+
+ // Do not allow points on the adjacent segments move freely
+ m_originSideConstraint->Apply();
+ m_endSideConstraint->Apply();
+
+ EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin, false );
+ EDIT_POINT& nextEnd = *m_editPoints.Next( end, false );
+
+ // Two segments adjacent to the dragged segment
+ SEG originSide = SEG( origin.GetPosition(), prevOrigin.GetPosition() );
+ SEG endSide = SEG( end.GetPosition(), nextEnd.GetPosition() );
+
+ // First intersection point (dragged segment against origin side)
+ if( OPT_VECTOR2I originIntersect = dragged.IntersectLines( originSide ) )
+ origin.SetPosition( *originIntersect );
+
+ // Second intersection point (dragged segment against end side)
+ if( OPT_VECTOR2I endIntersect = dragged.IntersectLines( endSide ) )
+ end.SetPosition( *endIntersect );
+
+ // Check if adjacent segments intersect (did we dragged the line to the point that it may
+ // create a selfintersecting polygon?)
+ originSide = SEG( origin.GetPosition(), prevOrigin.GetPosition() );
+ endSide = SEG( end.GetPosition(), nextEnd.GetPosition() );
+
+ if( OPT_VECTOR2I originEndIntersect = endSide.Intersect( originSide ) )
+ {
+ origin.SetPosition( *originEndIntersect );
+ end.SetPosition( *originEndIntersect );
+ }
+}
+
+
+EC_SNAPLINE::EC_SNAPLINE( EDIT_LINE& aLine, V2D_TRANSFORM_FUN aSnapFun ) :
+ EDIT_CONSTRAINT<EDIT_LINE>( aLine ), m_snapFun( aSnapFun )
+{}
+
+
+void EC_SNAPLINE::Apply( EDIT_LINE& aHandle )
+{
+ VECTOR2D delta = aHandle.GetEnd().GetPosition() - aHandle.GetOrigin().GetPosition();
+
+ aHandle.GetOrigin().SetPosition( m_snapFun( aHandle.GetOrigin().GetPosition() ) );
+ aHandle.GetEnd().SetPosition( aHandle.GetOrigin().GetPosition() + delta );
+}
diff --git a/pcbnew/tools/edit_constraints.h b/pcbnew/tools/edit_constraints.h
new file mode 100644
index 0000000..a1744d3
--- /dev/null
+++ b/pcbnew/tools/edit_constraints.h
@@ -0,0 +1,267 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef EDIT_CONSTRAINTS_H_
+#define EDIT_CONSTRAINTS_H_
+
+#include <math/vector2d.h>
+#include <boost/function.hpp>
+
+class EDIT_POINT;
+class EDIT_LINE;
+class EDIT_POINTS;
+
+/**
+ * Class EDIT_CONSTRAINT
+ *
+ * Allows to describe constraints between two edit handles. After the constrained handle is changed,
+ * Apply() has to be called to fix its coordinates according to the implemented constraint.
+ */
+template<class EDIT_TYPE>
+class EDIT_CONSTRAINT
+{
+public:
+ /**
+ * Constructor
+ *
+ * @param aConstrained is EDIT_POINT to which the constraint is applied.
+ */
+ EDIT_CONSTRAINT( EDIT_TYPE& aConstrained ) : m_constrained( aConstrained ) {};
+
+ virtual ~EDIT_CONSTRAINT() {};
+
+ /**
+ * Function Apply()
+ *
+ * Corrects coordinates of the constrained edit handle.
+ */
+ virtual void Apply( EDIT_TYPE& aHandle ) = 0;
+
+ /**
+ * Function Apply()
+ *
+ * Corrects coordinates of the constrained edit handle.
+ */
+ void Apply()
+ {
+ Apply( m_constrained );
+ }
+
+protected:
+ EDIT_TYPE& m_constrained; ///< Point that is constrained by rules implemented by Apply()
+};
+
+
+/**
+ * Class EC_VERTICAL.
+ *
+ * EDIT_CONSTRAINT that imposes a constraint that two points have to have the same X coordinate.
+ */
+class EC_VERTICAL : public EDIT_CONSTRAINT<EDIT_POINT>
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @param aConstrained is the point that is put under constrain.
+ * @param aConstrainer is the point that is the source of the constrain.
+ */
+ EC_VERTICAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) :
+ EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ), m_constrainer( aConstrainer )
+ {}
+
+ ///> @copydoc EDIT_CONSTRAINT::Apply()
+ virtual void Apply( EDIT_POINT& aHandle );
+
+private:
+ const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint.
+};
+
+
+/**
+ * Class EC_HORIZONTAL.
+ *
+ * EDIT_CONSTRAINT that imposes a constraint that two points have to have the same Y coordinate.
+ */
+class EC_HORIZONTAL : public EDIT_CONSTRAINT<EDIT_POINT>
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @param aConstrained is the point that is put under constrain.
+ * @param aConstrainer is the point that is the source of the constrain.
+ */
+ EC_HORIZONTAL( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) :
+ EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ), m_constrainer( aConstrainer )
+ {}
+
+ ///> @copydoc EDIT_CONSTRAINT::Apply()
+ virtual void Apply( EDIT_POINT& aHandle );
+
+private:
+ const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint.
+};
+
+
+/**
+ * Class EC_45DEGREE
+ *
+ * EDIT_CONSTRAINT that imposes a constraint that two points have to be located at angle of 45
+ * degree multiplicity.
+ */
+class EC_45DEGREE : public EDIT_CONSTRAINT<EDIT_POINT>
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @param aConstrained is the point that is put under constrain.
+ * @param aConstrainer is the point that is the source of the constrain.
+ */
+ EC_45DEGREE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer ) :
+ EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ), m_constrainer( aConstrainer )
+ {}
+
+ ///> @copydoc EDIT_CONSTRAINT::Apply()
+ virtual void Apply( EDIT_POINT& aHandle );
+
+private:
+ const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint.
+};
+
+
+/**
+ * Class EC_LINE
+ *
+ * EDIT_CONSTRAINT that imposes a constraint that a point has to lie on a line (determined
+ * by 2 points).
+ */
+class EC_LINE : public EDIT_CONSTRAINT<EDIT_POINT>
+{
+public:
+ EC_LINE( EDIT_POINT& aConstrained, const EDIT_POINT& aConstrainer );
+
+ ///> @copydoc EDIT_CONSTRAINT::Apply()
+ virtual void Apply( EDIT_POINT& aHandle );
+
+private:
+ const EDIT_POINT& m_constrainer; ///< Point that imposes the constraint.
+ VECTOR2I m_line; ///< Vector representing the constraining line.
+};
+
+
+/**
+ * Class EC_CIRCLE.
+ *
+ * EDIT_CONSTRAINT that imposes a constraint that a point has to lie on a circle.
+ */
+class EC_CIRCLE : public EDIT_CONSTRAINT<EDIT_POINT>
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @param aConstrained is the point that is put under constrain.
+ * @param aCenter is the point that is the center of the circle.
+ * @param aEnd is the point that decides on the radius of the circle.
+ */
+ EC_CIRCLE( EDIT_POINT& aConstrained, const EDIT_POINT& aCenter, const EDIT_POINT& aEnd ) :
+ EDIT_CONSTRAINT<EDIT_POINT>( aConstrained ), m_center( aCenter ), m_end( aEnd )
+ {}
+
+ ///> @copydoc EDIT_CONSTRAINT::Apply()
+ virtual void Apply( EDIT_POINT& aHandle );
+
+private:
+ ///> Point that imposes the constraint (center of the circle).
+ const EDIT_POINT& m_center;
+
+ ///> Point that imposes the constraint (decides on the radius of the circle).
+ const EDIT_POINT& m_end;
+};
+
+
+/**
+ * Class EC_CONVERGING
+ *
+ * EDIT_CONSTRAINT for 3 segments: dragged and two adjacent ones, enforcing to keep their slopes
+ * and allows only to change ending points. Applied to zones.
+ */
+class EC_CONVERGING : public EDIT_CONSTRAINT<EDIT_LINE>
+{
+public:
+ EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints );
+
+ virtual ~EC_CONVERGING();
+
+ ///> @copydoc EDIT_CONSTRAINT::Apply()
+ virtual void Apply( EDIT_LINE& aHandle );
+
+private:
+ ///> Constraint for origin side segment.
+ EDIT_CONSTRAINT<EDIT_POINT>* m_originSideConstraint;
+
+ ///> Constraint for end side segment.
+ EDIT_CONSTRAINT<EDIT_POINT>* m_endSideConstraint;
+
+ ///> Additional constriant, applied when at least two points are collinear. It is a pointer to
+ ///> m_[origin/end]SideConstraint, so it should not be freed.
+ EDIT_CONSTRAINT<EDIT_POINT>* m_colinearConstraint;
+
+ ///> EDIT_POINTS instance that stores currently modified lines.
+ EDIT_POINTS& m_editPoints;
+
+ ///> Vector that represents the initial direction of the dragged segment.
+ VECTOR2I m_draggedVector;
+};
+
+
+/**
+ * Class EC_SNAPLINE
+ *
+ * EDIT_CONSTRAINT for a EDIT_LINE, one of the ends is snapped to a spot determined by a
+ * transform function passed as parameter (e.g. it can be snapped to a grid), instead of having
+ * the line center snapped to a point.
+ */
+class EC_SNAPLINE : public EDIT_CONSTRAINT<EDIT_LINE>
+{
+public:
+ ///> Typedef for a function that determines snapping point.
+ typedef boost::function<VECTOR2D (const VECTOR2D&)> V2D_TRANSFORM_FUN;
+
+ EC_SNAPLINE( EDIT_LINE& aLine, V2D_TRANSFORM_FUN aSnapFun );
+
+ virtual ~EC_SNAPLINE()
+ {}
+
+ ///> @copydoc EDIT_CONSTRAINT::Apply()
+ virtual void Apply( EDIT_LINE& aHandle );
+
+private:
+ ///> Function that determines snapping point.
+ V2D_TRANSFORM_FUN m_snapFun;
+};
+
+#endif /* EDIT_CONSTRAINTS_H_ */
diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp
new file mode 100644
index 0000000..cbd2a77
--- /dev/null
+++ b/pcbnew/tools/edit_points.cpp
@@ -0,0 +1,227 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <boost/foreach.hpp>
+
+#include <gal/graphics_abstraction_layer.h>
+#include "edit_points.h"
+
+bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const
+{
+ // Corners of the EDIT_POINT square
+ VECTOR2I topLeft = GetPosition() - aSize;
+ VECTOR2I bottomRight = GetPosition() + aSize;
+
+ return ( aPoint.x > topLeft.x && aPoint.y > topLeft.y &&
+ aPoint.x < bottomRight.x && aPoint.y < bottomRight.y );
+}
+
+
+EDIT_POINTS::EDIT_POINTS( EDA_ITEM* aParent ) :
+ EDA_ITEM( NOT_USED ), m_parent( aParent )
+{
+}
+
+
+EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation )
+{
+ float size = m_view->ToWorld( EDIT_POINT::POINT_SIZE );
+
+ std::deque<EDIT_POINT>::iterator pit, pitEnd;
+ for( pit = m_points.begin(), pitEnd = m_points.end(); pit != pitEnd; ++pit )
+ {
+ EDIT_POINT& point = *pit;
+
+ if( point.WithinPoint( aLocation, size ) )
+ return &point;
+ }
+
+ std::deque<EDIT_LINE>::iterator lit, litEnd;
+ for( lit = m_lines.begin(), litEnd = m_lines.end(); lit != litEnd; ++lit )
+ {
+ EDIT_LINE& line = *lit;
+
+ if( line.WithinPoint( aLocation, size ) )
+ return &line;
+ }
+
+ return NULL;
+}
+
+
+int EDIT_POINTS::GetContourStartIdx( int aPointIdx ) const
+{
+ int lastIdx = 0;
+
+ BOOST_FOREACH( int idx, m_contours )
+ {
+ if( idx >= aPointIdx )
+ return lastIdx;
+
+ lastIdx = idx + 1;
+ }
+
+ return lastIdx;
+}
+
+
+int EDIT_POINTS::GetContourEndIdx( int aPointIdx ) const
+{
+ BOOST_FOREACH( int idx, m_contours )
+ {
+ if( idx >= aPointIdx )
+ return idx;
+ }
+
+ return m_points.size() - 1;
+}
+
+
+bool EDIT_POINTS::IsContourStart( int aPointIdx ) const
+{
+ BOOST_FOREACH( int idx, m_contours )
+ {
+ if( idx + 1 == aPointIdx )
+ return true;
+
+ // the list is sorted, so we cannot expect it any further
+ if( idx > aPointIdx )
+ break;
+ }
+
+ return ( aPointIdx == 0 );
+}
+
+
+bool EDIT_POINTS::IsContourEnd( int aPointIdx ) const
+{
+ BOOST_FOREACH( int idx, m_contours )
+ {
+ if( idx == aPointIdx )
+ return true;
+
+ // the list is sorted, so we cannot expect it any further
+ if( idx > aPointIdx )
+ break;
+ }
+
+ // the end of the list surely is the end of a contour
+ return ( aPointIdx == (int) m_points.size() - 1 );
+}
+
+
+EDIT_POINT* EDIT_POINTS::Previous( const EDIT_POINT& aPoint, bool aTraverseContours )
+{
+ for( unsigned int i = 0; i < m_points.size(); ++i )
+ {
+ if( m_points[i] == aPoint )
+ {
+ if( !aTraverseContours && IsContourStart( i ) )
+ return &m_points[GetContourEndIdx( i )];
+
+ if( i == 0 )
+ return &m_points[m_points.size() - 1];
+ else
+ return &m_points[i - 1];
+ }
+ }
+
+ return NULL;
+}
+
+
+EDIT_LINE* EDIT_POINTS::Previous( const EDIT_LINE& aLine )
+{
+ for( unsigned int i = 0; i < m_lines.size(); ++i )
+ {
+ if( m_lines[i] == aLine )
+ {
+ if( i == 0 )
+ return &m_lines[m_lines.size() - 1];
+ else
+ return &m_lines[i - 1];
+ }
+ }
+
+ return NULL;
+}
+
+
+EDIT_POINT* EDIT_POINTS::Next( const EDIT_POINT& aPoint, bool aTraverseContours )
+{
+ for( unsigned int i = 0; i < m_points.size(); ++i )
+ {
+ if( m_points[i] == aPoint )
+ {
+ if( !aTraverseContours && IsContourEnd( i ) )
+ return &m_points[GetContourStartIdx( i )];
+
+ if( i == m_points.size() - 1 )
+ return &m_points[0];
+ else
+ return &m_points[i + 1];
+ }
+ }
+
+ return NULL;
+}
+
+
+EDIT_LINE* EDIT_POINTS::Next( const EDIT_LINE& aLine )
+{
+ for( unsigned int i = 0; i < m_lines.size(); ++i )
+ {
+ if( m_lines[i] == aLine )
+ {
+ if( i == m_lines.size() - 1 )
+ return &m_lines[0];
+ else
+ return &m_lines[i + 1];
+ }
+ }
+
+ return NULL;
+}
+
+
+void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
+{
+ aGal->SetFillColor( KIGFX::COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
+ aGal->SetIsFill( true );
+ aGal->SetIsStroke( false );
+ aGal->PushDepth();
+ aGal->SetLayerDepth( aGal->GetMinDepth() );
+
+ float size = m_view->ToWorld( EDIT_POINT::POINT_SIZE );
+
+ BOOST_FOREACH( const EDIT_POINT& point, m_points )
+ aGal->DrawRectangle( point.GetPosition() - size / 2, point.GetPosition() + size / 2 );
+
+ BOOST_FOREACH( const EDIT_LINE& line, m_lines )
+ {
+ aGal->DrawCircle( line.GetPosition(), size / 2 );
+ }
+
+ aGal->PopDepth();
+}
diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h
new file mode 100644
index 0000000..c939eca
--- /dev/null
+++ b/pcbnew/tools/edit_points.h
@@ -0,0 +1,527 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef EDIT_POINTS_H_
+#define EDIT_POINTS_H_
+
+#include <boost/shared_ptr.hpp>
+
+#include <base_struct.h>
+#include <layers_id_colors_and_visibility.h>
+
+#include "edit_constraints.h"
+
+/**
+ * Class EDIT_POINT
+ *
+ * Represents a single point that can be used for modifying items. It is directly related to one
+ * of points in a graphical item (e.g. vertex of a zone or center of a circle).
+ */
+class EDIT_POINT
+{
+public:
+ /**
+ * Constructor
+ *
+ * @param aPoint stores coordinates for EDIT_POINT.
+ */
+ EDIT_POINT( const VECTOR2I& aPoint ) :
+ m_position( aPoint ) {};
+
+ virtual ~EDIT_POINT() {}
+
+ /**
+ * Function GetPosition()
+ *
+ * Returns coordinates of an EDIT_POINT. Note that it may be different than coordinates of
+ * a graphical item that is bound to the EDIT_POINT.
+ */
+ virtual VECTOR2I GetPosition() const
+ {
+ return m_position;
+ }
+
+ /**
+ * Function GetX()
+ *
+ * Returns X coordinate of an EDIT_POINT.
+ */
+ inline int GetX() const
+ {
+ return GetPosition().x;
+ }
+
+ /**
+ * Function GetY()
+ *
+ * Returns Y coordinate of an EDIT_POINT.
+ */
+ inline int GetY() const
+ {
+ return GetPosition().y;
+ }
+
+ /**
+ * Function SetPosition()
+ *
+ * Sets new coordinates for an EDIT_POINT. It does not change the coordinates of a graphical
+ * item.
+ * @param aPosition are new coordinates.
+ */
+ virtual void SetPosition( const VECTOR2I& aPosition )
+ {
+ m_position = aPosition;
+ }
+
+ /**
+ * Function WithinPoint()
+ *
+ * Checks if given point is within a square centered in the EDIT_POINT position.
+ * @param aPoint is point to be checked.
+ * @param aSize is length of the square side.
+ */
+ bool WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const;
+
+ /**
+ * Function SetConstraint()
+ *
+ * Sets a constraint for and EDIT_POINT.
+ * @param aConstraint is the constraint to be set.
+ */
+ void SetConstraint( EDIT_CONSTRAINT<EDIT_POINT>* aConstraint )
+ {
+ m_constraint.reset( aConstraint );
+ }
+
+ /**
+ * Function GetConstraint()
+ *
+ * Returns the constraint imposed on an EDIT_POINT. If there are no constraints, NULL is
+ * returned.
+ */
+ EDIT_CONSTRAINT<EDIT_POINT>* GetConstraint() const
+ {
+ return m_constraint.get();
+ }
+
+ /**
+ * Function ClearConstraint()
+ *
+ * Removes previously set constraint.
+ */
+ inline void ClearConstraint()
+ {
+ m_constraint.reset();
+ }
+
+ /**
+ * Function IsConstrained()
+ *
+ * Checks if point is constrained.
+ * @return True is point is constrained, false otherwise.
+ */
+ inline bool IsConstrained() const
+ {
+ return m_constraint != NULL;
+ }
+
+ /**
+ * Function ApplyConstraint()
+ *
+ * Corrects coordinates of an EDIT_POINT by applying previously set constraint.
+ */
+ virtual void ApplyConstraint()
+ {
+ if( m_constraint )
+ m_constraint->Apply();
+ }
+
+ bool operator==( const EDIT_POINT& aOther ) const
+ {
+ return m_position == aOther.m_position;
+ }
+
+ ///> Single point size in pixels
+ static const int POINT_SIZE = 10;
+
+private:
+ ///> Position of EDIT_POINT
+ VECTOR2I m_position;
+
+ ///> Constraint for the point, NULL if none
+ boost::shared_ptr<EDIT_CONSTRAINT<EDIT_POINT> > m_constraint;
+};
+
+
+/**
+ * Class EDIT_LINE
+ *
+ * Represents a line connecting two EDIT_POINTs. That allows to move them both by dragging the
+ * EDIT_POINT in the middle. As it uses references to EDIT_POINTs, all coordinates are
+ * automatically synchronized.
+ */
+class EDIT_LINE : public EDIT_POINT
+{
+public:
+ /**
+ * Constructor
+ *
+ * @param aOrigin is the origin of EDIT_LINE.
+ * @param aEnd is the end of EDIT_LINE.
+ */
+ EDIT_LINE( EDIT_POINT& aOrigin, EDIT_POINT& aEnd ) :
+ EDIT_POINT( aOrigin.GetPosition() + ( aEnd.GetPosition() - aOrigin.GetPosition() ) / 2 ),
+ m_origin( aOrigin ), m_end( aEnd )
+ {
+ }
+
+ ///> @copydoc EDIT_POINT::GetPosition()
+ virtual VECTOR2I GetPosition() const
+ {
+ return ( m_origin.GetPosition() + m_end.GetPosition() ) / 2;
+ }
+
+ ///> @copydoc EDIT_POINT::GetPosition()
+ virtual void SetPosition( const VECTOR2I& aPosition )
+ {
+ VECTOR2I difference = aPosition - GetPosition();
+
+ m_origin.SetPosition( m_origin.GetPosition() + difference );
+ m_end.SetPosition( m_end.GetPosition() + difference );
+ }
+
+ ///> @copydoc EDIT_POINT::ApplyConstraint()
+ virtual void ApplyConstraint()
+ {
+ m_origin.ApplyConstraint();
+ m_end.ApplyConstraint();
+
+ if( m_constraint )
+ m_constraint->Apply();
+ }
+
+ /**
+ * Function SetConstraint()
+ *
+ * Sets a constraint for and EDIT_POINT.
+ * @param aConstraint is the constraint to be set.
+ */
+ void SetConstraint( EDIT_CONSTRAINT<EDIT_LINE>* aConstraint )
+ {
+ m_constraint.reset( aConstraint );
+ }
+
+ /**
+ * Function GetConstraint()
+ *
+ * Returns the constraint imposed on an EDIT_POINT. If there are no constraints, NULL is
+ * returned.
+ */
+ EDIT_CONSTRAINT<EDIT_LINE>* GetConstraint() const
+ {
+ return m_constraint.get();
+ }
+
+ /**
+ * Function GetOrigin()
+ *
+ * Returns the origin EDIT_POINT.
+ */
+ EDIT_POINT& GetOrigin()
+ {
+ return m_origin;
+ }
+
+ const EDIT_POINT& GetOrigin() const
+ {
+ return m_origin;
+ }
+
+ /**
+ * Function GetEnd()
+ *
+ * Returns the end EDIT_POINT.
+ */
+ EDIT_POINT& GetEnd()
+ {
+ return m_end;
+ }
+
+ const EDIT_POINT& GetEnd() const
+ {
+ return m_end;
+ }
+
+ bool operator==( const EDIT_POINT& aOther ) const
+ {
+ return GetPosition() == aOther.GetPosition();
+ }
+
+ bool operator==( const EDIT_LINE& aOther ) const
+ {
+ return m_origin == aOther.m_origin && m_end == aOther.m_end;
+ }
+
+private:
+ EDIT_POINT& m_origin; ///< Origin point for a line
+ EDIT_POINT& m_end; ///< End point for a line
+
+ ///> Constraint for the point, NULL if none
+ boost::shared_ptr<EDIT_CONSTRAINT<EDIT_LINE> > m_constraint;
+};
+
+
+/**
+ * Class EDIT_POINTS
+ *
+ * EDIT_POINTS is a VIEW_ITEM that manages EDIT_POINTs and EDIT_LINEs and draws them.
+ */
+class EDIT_POINTS : public EDA_ITEM
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @param aParent is the item to which EDIT_POINTs are related.
+ */
+ EDIT_POINTS( EDA_ITEM* aParent );
+
+ /**
+ * Function FindPoint()
+ *
+ * Returns a point that is at given coordinates or NULL if there is no such point.
+ * @param aLocation is the location for searched point.
+ */
+ EDIT_POINT* FindPoint( const VECTOR2I& aLocation );
+
+ /**
+ * Function GetParent()
+ *
+ * Returns parent of the EDIT_POINTS.
+ */
+ EDA_ITEM* GetParent() const
+ {
+ return m_parent;
+ }
+
+ /**
+ * Function AddPoint()
+ *
+ * Adds an EDIT_POINT.
+ * @param aPoint is the new point.
+ */
+ void AddPoint( const EDIT_POINT& aPoint )
+ {
+ m_points.push_back( aPoint );
+ }
+
+ /**
+ * Function AddPoint()
+ *
+ * Adds an EDIT_POINT.
+ * @param aPoint are coordinates of the new point.
+ */
+ void AddPoint( const VECTOR2I& aPoint )
+ {
+ AddPoint( EDIT_POINT( aPoint ) );
+ }
+
+ /**
+ * Function AddLine()
+ *
+ * Adds an EDIT_LINE.
+ * @param aLine is the new line.
+ */
+ void AddLine( const EDIT_LINE& aLine )
+ {
+ m_lines.push_back( aLine );
+ }
+
+ /**
+ * Function AddLine()
+ *
+ * Adds an EDIT_LINE.
+ * @param aOrigin is the origin for a new line.
+ * @param aEnd is the end for a new line.
+ */
+ void AddLine( EDIT_POINT& aOrigin, EDIT_POINT& aEnd )
+ {
+ m_lines.push_back( EDIT_LINE( aOrigin, aEnd ) );
+ }
+
+ /**
+ * Function AddBreak()
+ *
+ * Adds a break, indicating the end of a contour.
+ */
+ void AddBreak()
+ {
+ assert( m_points.size() > 0 );
+ m_contours.push_back( m_points.size() - 1 );
+ }
+
+ /**
+ * Function GetContourStartIdx()
+ *
+ * Returns index of the contour origin for a point with given index.
+ * @param aPointIdx is the index of point for which the contour origin is searched.
+ * @return Index of the contour origin point.
+ */
+ int GetContourStartIdx( int aPointIdx ) const;
+
+ /**
+ * Function GetContourEndIdx()
+ *
+ * Returns index of the contour finish for a point with given index.
+ * @param aPointIdx is the index of point for which the contour finish is searched.
+ * @return Index of the contour finish point.
+ */
+ int GetContourEndIdx( int aPointIdx ) const;
+
+ /**
+ * Function IsContourStart()
+ *
+ * Checks is a point with given index is a contour origin.
+ * @param aPointIdx is the index of the point to be checked.
+ * @return True if the point is an origin of a contour.
+ */
+ bool IsContourStart( int aPointIdx ) const;
+
+ /**
+ * Function IsContourEnd()
+ *
+ * Checks is a point with given index is a contour finish.
+ * @param aPointIdx is the index of the point to be checked.
+ * @return True if the point is a finish of a contour.
+ */
+ bool IsContourEnd( int aPointIdx ) const;
+
+ /**
+ * Function Previous()
+ *
+ * Returns the point that is after the given point in the list.
+ * @param aPoint is the point that is supposed to be preceding the searched point.
+ * @param aTraverseContours decides if in case of breaks should we return to the origin
+ * of contour or continue with the next contour.
+ * @return The point following aPoint in the list. If aPoint is the first in
+ * the list, the last from the list will be returned. If there are no points at all, NULL
+ * is returned.
+ */
+ EDIT_POINT* Previous( const EDIT_POINT& aPoint, bool aTraverseContours = true );
+
+ EDIT_LINE* Previous( const EDIT_LINE& aLine );
+
+ /**
+ * Function Next()
+ *
+ * Returns the point that is before the given point in the list.
+ * @param aPoint is the point that is supposed to be following the searched point.
+ * @param aTraverseContours decides if in case of breaks should we return to the origin
+ * of contour or continue with the next contour.
+ * @return The point preceding aPoint in the list. If aPoint is the last in
+ * the list, the first point from the list will be returned. If there are no points at all,
+ * NULL is returned.
+ */
+ EDIT_POINT* Next( const EDIT_POINT& aPoint, bool aTraverseContours = true );
+
+ EDIT_LINE* Next( const EDIT_LINE& aLine );
+
+ EDIT_POINT& Point( unsigned int aIndex )
+ {
+ return m_points[aIndex];
+ }
+
+ const EDIT_POINT& Point( unsigned int aIndex ) const
+ {
+ return m_points[aIndex];
+ }
+
+ EDIT_LINE& Line( unsigned int aIndex )
+ {
+ return m_lines[aIndex];
+ }
+
+ const EDIT_LINE& Line( unsigned int aIndex ) const
+ {
+ return m_lines[aIndex];
+ }
+
+ /**
+ * Function PointsSize()
+ *
+ * Returns number of stored EDIT_POINTs.
+ */
+ unsigned int PointsSize() const
+ {
+ return m_points.size();
+ }
+
+ /**
+ * Function LinesSize()
+ *
+ * Returns number of stored EDIT_LINEs.
+ */
+ unsigned int LinesSize() const
+ {
+ return m_lines.size();
+ }
+
+ ///> @copydoc VIEW_ITEM::ViewBBox()
+ virtual const BOX2I ViewBBox() const
+ {
+ return m_parent->ViewBBox();
+ }
+
+ ///> @copydoc VIEW_ITEM::ViewDraw()
+ virtual void ViewDraw( int aLayer, KIGFX::GAL* aGal ) const;
+
+ ///> @copydoc VIEW_ITEM::ViewGetLayers()
+ virtual void ViewGetLayers( int aLayers[], int& aCount ) const
+ {
+ aCount = 1;
+ aLayers[0] = ITEM_GAL_LAYER( GP_OVERLAY );
+ }
+
+#if defined(DEBUG)
+ void Show( int x, std::ostream& st ) const
+ {
+ }
+#endif
+
+ /** Get class name
+ * @return string "EDIT_POINTS"
+ */
+ virtual wxString GetClass() const
+ {
+ return wxT( "EDIT_POINTS" );
+ }
+
+private:
+ EDA_ITEM* m_parent; ///< Parent of the EDIT_POINTs
+ std::deque<EDIT_POINT> m_points; ///< EDIT_POINTs for modifying m_parent
+ std::deque<EDIT_LINE> m_lines; ///< EDIT_LINEs for modifying m_parent
+ std::list<int> m_contours; ///< Indices of end contour points
+};
+
+#endif /* EDIT_POINTS_H_ */
diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp
new file mode 100644
index 0000000..81d547b
--- /dev/null
+++ b/pcbnew/tools/edit_tool.cpp
@@ -0,0 +1,1099 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013-2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <limits>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+#include <class_zone.h>
+#include <wxPcbStruct.h>
+#include <kiway.h>
+#include <class_draw_panel_gal.h>
+#include <module_editor_frame.h>
+
+#include <tool/tool_manager.h>
+#include <view/view_controls.h>
+#include <gal/graphics_abstraction_layer.h>
+#include <ratsnest_data.h>
+#include <confirm.h>
+
+#include <cassert>
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+
+#include "common_actions.h"
+#include "selection_tool.h"
+#include "edit_tool.h"
+#include "grid_helper.h"
+
+#include <router/router_tool.h>
+
+#include <dialogs/dialog_create_array.h>
+#include <dialogs/dialog_move_exact.h>
+#include <dialogs/dialog_track_via_properties.h>
+
+EDIT_TOOL::EDIT_TOOL() :
+ TOOL_INTERACTIVE( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
+ m_dragging( false ), m_editModules( false ), m_undoInhibit( 0 ),
+ m_updateFlag( KIGFX::VIEW_ITEM::NONE )
+{
+}
+
+
+void EDIT_TOOL::Reset( RESET_REASON aReason )
+{
+ m_dragging = false;
+ m_updateFlag = KIGFX::VIEW_ITEM::NONE;
+}
+
+
+bool EDIT_TOOL::Init()
+{
+ // Find the selection tool, so they can cooperate
+ m_selectionTool = static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
+
+ if( !m_selectionTool )
+ {
+ DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) );
+ return false;
+ }
+
+ // Vector storing track & via types, used for specifying 'Properties' menu entry condition
+ m_tracksViasType.push_back( PCB_TRACE_T );
+ m_tracksViasType.push_back( PCB_VIA_T );
+
+ // Add context menu entries that are displayed when selection tool is active
+ m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::editActivate, SELECTION_CONDITIONS::NotEmpty );
+ m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::rotate, SELECTION_CONDITIONS::NotEmpty );
+ m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::flip, SELECTION_CONDITIONS::NotEmpty );
+ m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::remove, SELECTION_CONDITIONS::NotEmpty );
+ m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::properties, SELECTION_CONDITIONS::Count( 1 )
+ || SELECTION_CONDITIONS::OnlyTypes( m_tracksViasType ) );
+ m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::moveExact, SELECTION_CONDITIONS::NotEmpty );
+ m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::duplicate, SELECTION_CONDITIONS::NotEmpty );
+ m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::createArray, SELECTION_CONDITIONS::NotEmpty );
+
+ // Footprint actions
+ m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::editFootprintInFpEditor,
+ SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T ) &&
+ SELECTION_CONDITIONS::Count( 1 ) );
+
+ m_offset.x = 0;
+ m_offset.y = 0;
+
+ return true;
+}
+
+
+bool EDIT_TOOL::invokeInlineRouter()
+{
+ TRACK* track = uniqueSelected<TRACK>();
+ VIA* via = uniqueSelected<VIA>();
+
+ if( isUndoInhibited() )
+ return false;
+
+ if( track || via )
+ {
+ ROUTER_TOOL* theRouter = static_cast<ROUTER_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
+ assert( theRouter );
+
+ if( !theRouter->PNSSettings().InlineDragEnabled() )
+ return false;
+
+ TOOL_EVENT dummy;
+ m_selectionTool->ClearSelection( dummy );
+ m_toolMgr->RunAction( COMMON_ACTIONS::routerInlineDrag, true, track ? track : via );
+ return true;
+ }
+
+ return false;
+}
+
+
+int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
+{
+ KIGFX::VIEW_CONTROLS* controls = getViewControls();
+ PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
+
+ VECTOR2I originalCursorPos = controls->GetCursorPosition();
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ // Shall the selection be cleared at the end?
+ bool unselect = selection.Empty();
+
+ // Be sure that there is at least one item that we can modify. If nothing was selected before,
+ // try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
+ if( !hoverSelection( selection ) )
+ return 0;
+
+ Activate();
+
+ m_dragging = false; // Are selected items being dragged?
+ bool restore = false; // Should items' state be restored when finishing the tool?
+ bool lockOverride = false;
+
+ // By default, modified items need to update their geometry
+ m_updateFlag = KIGFX::VIEW_ITEM::GEOMETRY;
+
+ controls->ShowCursor( true );
+
+ // cumulative translation
+ wxPoint totalMovement( 0, 0 );
+
+ GRID_HELPER grid( editFrame );
+ OPT_TOOL_EVENT evt = aEvent;
+
+ // Main loop: keep receiving events
+ do
+ {
+ if( evt->IsCancel() )
+ {
+ restore = true; // Cancelling the tool means that items have to be restored
+ break; // Finish
+ }
+
+ else if( evt->Action() == TA_UNDO_REDO )
+ {
+ unselect = true;
+ break;
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::editActivate )
+ || evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 );
+
+ if( m_dragging && evt->Category() == TC_MOUSE )
+ {
+ m_cursor = grid.BestSnapAnchor( evt->Position(), item );
+ controls->ForceCursorPosition( true, m_cursor );
+
+ wxPoint movement = wxPoint( m_cursor.x, m_cursor.y ) - item->GetPosition();
+ totalMovement += movement;
+
+ // Drag items to the current cursor position
+ for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
+ selection.Item<BOARD_ITEM>( i )->Move( movement + m_offset );
+
+ updateRatsnest( true );
+ }
+ else if( !m_dragging ) // Prepare to start dragging
+ {
+ if( !invokeInlineRouter() )
+ {
+ m_selectionTool->SanitizeSelection();
+
+ if( selection.Empty() )
+ break;
+
+ // deal with locked items (override lock or abort the operation)
+ SELECTION_LOCK_FLAGS lockFlags = m_selectionTool->CheckLock();
+
+ if( lockFlags == SELECTION_LOCKED )
+ break;
+ else if( lockFlags == SELECTION_LOCK_OVERRIDE )
+ lockOverride = true;
+
+ // Save items, so changes can be undone
+ if( !isUndoInhibited() )
+ {
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+ }
+
+ m_cursor = controls->GetCursorPosition();
+
+ if( selection.Size() == 1 )
+ {
+ // Set the current cursor position to the first dragged item origin, so the
+ // movement vector could be computed later
+ m_cursor = grid.BestDragOrigin( originalCursorPos, item );
+ grid.SetAuxAxes( true, m_cursor );
+ }
+ else
+ {
+ m_cursor = grid.Align( m_cursor );
+ }
+
+ controls->ForceCursorPosition( true, m_cursor );
+ controls->WarpCursor( m_cursor, true );
+
+ VECTOR2I o = VECTOR2I( item->GetPosition() );
+ m_offset.x = o.x - m_cursor.x;
+ m_offset.y = o.y - m_cursor.y;
+
+ controls->SetAutoPan( true );
+ m_dragging = true;
+ incUndoInhibit();
+ }
+ }
+
+ selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
+ }
+
+ // Dispatch TOOL_ACTIONs
+ else if( evt->Category() == TC_COMMAND )
+ {
+ if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
+ {
+ Rotate( aEvent );
+ }
+ else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
+ {
+ Flip( aEvent );
+
+ // Flip causes change of layers
+ enableUpdateFlag( KIGFX::VIEW_ITEM::LAYERS );
+ }
+ else if( evt->IsAction( &COMMON_ACTIONS::remove ) )
+ {
+ Remove( aEvent );
+
+ break; // exit the loop, as there is no further processing for removed items
+ }
+ else if( evt->IsAction( &COMMON_ACTIONS::duplicate ) )
+ {
+ // On duplicate, stop moving this item
+ // The duplicate tool should then select the new item and start
+ // a new move procedure
+ break;
+ }
+ else if( evt->IsAction( &COMMON_ACTIONS::moveExact ) )
+ {
+ // Can't do this, because the selection will then contain
+ // stale pointers and it will all go horribly wrong...
+ //editFrame->RestoreCopyFromUndoList( dummy );
+ //
+ // So, instead, reset the position manually
+ for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+ item->SetPosition( item->GetPosition() - totalMovement );
+
+ // And what about flipping and rotation?
+ // for now, they won't be undone, but maybe that is how
+ // it should be, so you can flip and move exact in the
+ // same action?
+ }
+
+ // This causes a double event, so we will get the dialogue
+ // correctly, somehow - why does Rotate not?
+ //MoveExact( aEvent );
+ break; // exit the loop - we move exactly, so we have finished moving
+ }
+ }
+
+ else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
+ {
+ if( !lockOverride )
+ break; // Finish
+
+ lockOverride = false;
+ }
+ } while( evt = Wait() );
+
+ if( m_dragging )
+ decUndoInhibit();
+
+ m_dragging = false;
+ m_offset.x = 0;
+ m_offset.y = 0;
+
+ if( restore )
+ {
+ // Modifications have to be rollbacked, so restore the previous state of items
+ wxCommandEvent dummy;
+ editFrame->RestoreCopyFromUndoList( dummy );
+ }
+ else
+ {
+ // Changes are applied, so update the items
+ selection.group->ItemsViewUpdate( m_updateFlag );
+ }
+
+ if( unselect )
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+ ratsnest->ClearSimple();
+ ratsnest->Recalculate();
+
+ controls->ShowCursor( false );
+ controls->SetAutoPan( false );
+
+ return 0;
+}
+
+
+int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+ PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
+
+ // Shall the selection be cleared at the end?
+ bool unselect = selection.Empty();
+
+ if( !hoverSelection( selection, false ) )
+ return 0;
+
+ // Tracks & vias are treated in a special way:
+ if( ( SELECTION_CONDITIONS::OnlyTypes( m_tracksViasType ) )( selection ) )
+ {
+ DIALOG_TRACK_VIA_PROPERTIES dlg( editFrame, selection );
+
+ if( dlg.ShowModal() )
+ {
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+ dlg.Apply();
+
+ selection.ForAll<KIGFX::VIEW_ITEM>( boost::bind( &KIGFX::VIEW_ITEM::ViewUpdate, _1,
+ KIGFX::VIEW_ITEM::ALL ) );
+ selection.ForAll<BOARD_ITEM>( boost::bind( &RN_DATA::Update, ratsnest, _1 ) );
+ ratsnest->Recalculate();
+ }
+ }
+ else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected
+ {
+ // Display properties dialog
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 );
+
+ // Store the head of the undo list to compare if anything has changed
+ std::vector<PICKED_ITEMS_LIST*>& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList;
+
+ // Some of properties dialogs alter pointers, so we should deselect them
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ STATUS_FLAGS flags = item->GetFlags();
+ item->ClearFlags();
+
+ // It is necessary to determine if anything has changed, so store the current undo save point
+ PICKED_ITEMS_LIST* undoSavePoint = undoList.empty() ? NULL : undoList.back();
+
+ // Display properties dialog provided by the legacy canvas frame
+ editFrame->OnEditItemRequest( NULL, item );
+
+ if( !undoList.empty() && undoList.back() != undoSavePoint ) // Undo buffer has changed
+ {
+ // Process changes stored after undoSavePoint
+ processUndoBuffer( undoSavePoint );
+
+ // Update the modified item
+ item->ViewUpdate();
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+ ratsnest->Recalculate();
+
+ // TODO OBSERVER! I miss you so much..
+ m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
+ }
+
+ item->SetFlags( flags );
+ }
+
+ if( unselect )
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ return 0;
+}
+
+
+int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+ PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
+
+ // Shall the selection be cleared at the end?
+ bool unselect = selection.Empty();
+
+ if( !hoverSelection( selection ) || m_selectionTool->CheckLock() == SELECTION_LOCKED )
+ return 0;
+
+ wxPoint rotatePoint = getModificationPoint( selection );
+
+ // If it is being dragged, then it is already saved with UR_CHANGED flag
+ if( !isUndoInhibited() )
+ {
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selection.items, UR_ROTATED, rotatePoint );
+ }
+
+ for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+
+ item->Rotate( rotatePoint, editFrame->GetRotationAngle() );
+
+ if( !m_dragging )
+ item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ updateRatsnest( m_dragging );
+
+ // Update dragging offset (distance between cursor and the first dragged item)
+ m_offset = static_cast<BOARD_ITEM*>( selection.items.GetPickedItem( 0 ) )->GetPosition() -
+ rotatePoint;
+
+ if( m_dragging )
+ selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ else
+ getModel<BOARD>()->GetRatsnest()->Recalculate();
+
+ if( unselect )
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
+
+ return 0;
+}
+
+
+int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+ PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
+
+ // Shall the selection be cleared at the end?
+ bool unselect = selection.Empty();
+
+ if( !hoverSelection( selection ) || m_selectionTool->CheckLock() == SELECTION_LOCKED )
+ return 0;
+
+ wxPoint flipPoint = getModificationPoint( selection );
+
+ if( !isUndoInhibited() ) // If it is being dragged, then it is already saved with UR_CHANGED flag
+ {
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selection.items, UR_FLIPPED, flipPoint );
+ }
+
+ for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+
+ item->Flip( flipPoint );
+
+ if( !m_dragging )
+ item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS );
+ }
+
+ updateRatsnest( m_dragging );
+
+ // Update dragging offset (distance between cursor and the first dragged item)
+ m_offset = static_cast<BOARD_ITEM*>( selection.items.GetPickedItem( 0 ) )->GetPosition() -
+ flipPoint;
+
+ if( m_dragging )
+ selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ else
+ getModel<BOARD>()->GetRatsnest()->Recalculate();
+
+ if( unselect )
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
+
+ return 0;
+}
+
+
+int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ if( !hoverSelection( selection ) || m_selectionTool->CheckLock() == SELECTION_LOCKED )
+ return 0;
+
+ // Get a copy of the selected items set
+ PICKED_ITEMS_LIST selectedItems = selection.items;
+ PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
+
+ // As we are about to remove items, they have to be removed from the selection first
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ // Save them
+ for( unsigned int i = 0; i < selectedItems.GetCount(); ++i )
+ selectedItems.SetPickedItemStatus( UR_DELETED, i );
+
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selectedItems, UR_DELETED );
+
+ // And now remove
+ for( unsigned int i = 0; i < selectedItems.GetCount(); ++i )
+ remove( static_cast<BOARD_ITEM*>( selectedItems.GetPickedItem( i ) ) );
+
+ getModel<BOARD>()->GetRatsnest()->Recalculate();
+
+ return 0;
+}
+
+
+void EDIT_TOOL::remove( BOARD_ITEM* aItem )
+{
+ BOARD* board = getModel<BOARD>();
+
+ switch( aItem->Type() )
+ {
+ case PCB_MODULE_T:
+ {
+ MODULE* module = static_cast<MODULE*>( aItem );
+ module->ClearFlags();
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, getView(), _1 ) );
+
+ // Module itself is deleted after the switch scope is finished
+ // list of pads is rebuild by BOARD::BuildListOfNets()
+
+ // Clear flags to indicate, that the ratsnest, list of nets & pads are not valid anymore
+ board->m_Status_Pcb = 0;
+ }
+ break;
+
+ // Default removal procedure
+ case PCB_MODULE_TEXT_T:
+ {
+ TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( aItem );
+
+ switch( text->GetType() )
+ {
+ case TEXTE_MODULE::TEXT_is_REFERENCE:
+ DisplayError( getEditFrame<PCB_BASE_FRAME>(), _( "Cannot delete component reference." ) );
+ return;
+
+ case TEXTE_MODULE::TEXT_is_VALUE:
+ DisplayError( getEditFrame<PCB_BASE_FRAME>(), _( "Cannot delete component value." ) );
+ return;
+
+ case TEXTE_MODULE::TEXT_is_DIVERS: // suppress warnings
+ break;
+ }
+
+ if( m_editModules )
+ {
+ MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
+ module->SetLastEditTime();
+ board->m_Status_Pcb = 0; // it is done in the legacy view
+ aItem->DeleteStructure();
+ }
+
+ return;
+ }
+
+ case PCB_PAD_T:
+ case PCB_MODULE_EDGE_T:
+ {
+ MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
+ module->SetLastEditTime();
+
+ board->m_Status_Pcb = 0; // it is done in the legacy view
+
+
+ if( !m_editModules )
+ {
+ getView()->Remove( aItem );
+ board->Remove( aItem );
+ }
+
+ aItem->DeleteStructure();
+
+ return;
+ }
+
+ case PCB_LINE_T: // a segment not on copper layers
+ case PCB_TEXT_T: // a text on a layer
+ case PCB_TRACE_T: // a track segment (segment on a copper layer)
+ case PCB_VIA_T: // a via (like track segment on a copper layer)
+ case PCB_DIMENSION_T: // a dimension (graphic item)
+ case PCB_TARGET_T: // a target (graphic item)
+ case PCB_MARKER_T: // a marker used to show something
+ case PCB_ZONE_T: // SEG_ZONE items are now deprecated
+ case PCB_ZONE_AREA_T:
+ break;
+
+ default: // other types do not need to (or should not) be handled
+ assert( false );
+ return;
+ }
+
+ getView()->Remove( aItem );
+ board->Remove( aItem );
+}
+
+
+int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ // Shall the selection be cleared at the end?
+ bool unselect = selection.Empty();
+
+ if( !hoverSelection( selection ) || m_selectionTool->CheckLock() == SELECTION_LOCKED )
+ return 0;
+
+ wxPoint translation;
+ double rotation = 0;
+
+ PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
+
+ DIALOG_MOVE_EXACT dialog( editFrame, translation, rotation );
+ int ret = dialog.ShowModal();
+
+ if( ret == wxID_OK )
+ {
+ if( !isUndoInhibited() )
+ {
+ editFrame->OnModify();
+ // Record an action of move and rotate
+ editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+ }
+
+ VECTOR2I rp = selection.GetCenter();
+ wxPoint rotPoint( rp.x, rp.y );
+
+ for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+
+ item->Move( translation );
+ item->Rotate( rotPoint, rotation );
+
+ if( !m_dragging )
+ item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ updateRatsnest( m_dragging );
+
+ if( m_dragging )
+ selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ else
+ getModel<BOARD>()->GetRatsnest()->Recalculate();
+
+ if( unselect )
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
+ }
+
+ return 0;
+}
+
+
+int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
+{
+ // Note: original items are no more modified.
+
+ bool increment = aEvent.IsAction( &COMMON_ACTIONS::duplicateIncrement );
+
+ // first, check if we have a selection, or try to get one
+ SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
+ const SELECTION& selection = selTool->GetSelection();
+
+ // Be sure that there is at least one item that we can modify
+ if( !hoverSelection( selection ) )
+ return 0;
+
+ // we have a selection to work on now, so start the tool process
+
+ PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
+ editFrame->OnModify();
+
+ // prevent other tools making undo points while the duplicate is going on
+ // so that if you cancel, you don't get a duplicate object hiding over
+ // the original
+ incUndoInhibit();
+
+ if( m_editModules )
+ editFrame->SaveCopyInUndoList( editFrame->GetBoard()->m_Modules, UR_MODEDIT );
+
+ std::vector<BOARD_ITEM*> old_items;
+
+ for( int i = 0; i < selection.Size(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+
+ if( item )
+ old_items.push_back( item );
+ }
+
+ for( unsigned i = 0; i < old_items.size(); ++i )
+ {
+ BOARD_ITEM* item = old_items[i];
+
+ // Unselect the item, so we won't pick it up again
+ // Do this first, so a single-item duplicate will correctly call
+ // SetCurItem and show the item properties
+ m_toolMgr->RunAction( COMMON_ACTIONS::unselectItem, true, item );
+
+ BOARD_ITEM* new_item = NULL;
+
+ if( m_editModules )
+ new_item = editFrame->GetBoard()->m_Modules->DuplicateAndAddItem( item, increment );
+ else
+ {
+#if 0
+ // @TODO: see if we allow zone duplication here
+ // Duplicate zones is especially tricky (overlaping zones must be merged)
+ // so zones are not duplicated
+ if( item->Type() != PCB_ZONE_AREA_T )
+#endif
+ new_item = editFrame->GetBoard()->DuplicateAndAddItem( item, increment );
+ }
+
+ if( new_item )
+ {
+ if( new_item->Type() == PCB_MODULE_T )
+ {
+ static_cast<MODULE*>( new_item )->RunOnChildren( boost::bind( &KIGFX::VIEW::Add,
+ getView(), _1 ) );
+ }
+
+ editFrame->GetGalCanvas()->GetView()->Add( new_item );
+
+ // Select the new item, so we can pick it up
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, new_item );
+ }
+ }
+
+ // record the new items as added
+ if( !m_editModules && !selection.Empty() )
+ {
+ editFrame->SaveCopyInUndoList( selection.items, UR_NEW );
+
+ editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
+ (int) old_items.size() ) );
+
+ // If items were duplicated, pick them up
+ // this works well for "dropping" copies around
+ TOOL_EVENT evt = COMMON_ACTIONS::editActivate.MakeEvent();
+ Main( evt );
+ }
+
+ // and re-enable undos
+ decUndoInhibit();
+
+ return 0;
+}
+
+
+int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
+{
+ // first, check if we have a selection, or try to get one
+ SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
+ const SELECTION& selection = selTool->GetSelection();
+
+ // Be sure that there is at least one item that we can modify
+ if( !hoverSelection( selection ) )
+ return 0;
+
+ // we have a selection to work on now, so start the tool process
+
+ PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
+ editFrame->OnModify();
+
+ if( m_editModules )
+ {
+ // Module editors do their undo point upfront for the whole module
+ editFrame->SaveCopyInUndoList( editFrame->GetBoard()->m_Modules, UR_MODEDIT );
+ }
+
+ DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* array_opts = NULL;
+
+ VECTOR2I rp = selection.GetCenter();
+ const wxPoint rotPoint( rp.x, rp.y );
+
+ DIALOG_CREATE_ARRAY dialog( editFrame, rotPoint, &array_opts );
+ int ret = dialog.ShowModal();
+
+ if( ret == wxID_OK && array_opts != NULL )
+ {
+ PICKED_ITEMS_LIST newItemList;
+
+ for( int i = 0; i < selection.Size(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+
+ if( !item )
+ continue;
+
+ // iterate across the array, laying out the item at the
+ // correct position
+ const unsigned nPoints = array_opts->GetArraySize();
+
+ // The first item in list is the original item. We do not modify it
+ for( unsigned ptN = 1; ptN < nPoints; ++ptN )
+ {
+ BOARD_ITEM* newItem = NULL;
+
+ // Some items cannot be duplicated
+ // i.e. the ref and value fields of a footprint or zones
+ // therefore newItem can be null
+
+ #define INCREMENT_REF false
+ #define INCREMENT_PADNUMBER true
+
+ if( m_editModules )
+ newItem = editFrame->GetBoard()->m_Modules->DuplicateAndAddItem(
+ item, INCREMENT_PADNUMBER );
+ else
+ {
+#if 0
+ // @TODO: see if we allow zone duplication here
+ // Duplicate zones is especially tricky (overlaping zones must be merged)
+ // so zones are not duplicated
+ if( item->Type() == PCB_ZONE_AREA_T )
+ newItem = NULL;
+ else
+#endif
+ newItem = editFrame->GetBoard()->DuplicateAndAddItem(
+ item, INCREMENT_REF );
+ // @TODO: we should merge zones. This is a bit tricky, because
+ // the undo command needs saving old area, if it is merged.
+ }
+
+ if( newItem )
+ {
+ array_opts->TransformItem( ptN, newItem, rotPoint );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::unselectItem, true, newItem );
+
+ newItemList.PushItem( newItem );
+
+ if( newItem->Type() == PCB_MODULE_T)
+ {
+ static_cast<MODULE*>( newItem )->RunOnChildren( boost::bind( &KIGFX::VIEW::Add,
+ getView(), _1 ) );
+ }
+
+ editFrame->GetGalCanvas()->GetView()->Add( newItem );
+ getModel<BOARD>()->GetRatsnest()->Update( newItem );
+ }
+
+ // Only renumbering pads has meaning:
+ if( newItem && array_opts->ShouldRenumberItems() )
+ {
+ if( newItem->Type() == PCB_PAD_T )
+ {
+ const wxString padName = array_opts->GetItemNumber( ptN );
+ static_cast<D_PAD*>( newItem )->SetPadName( padName );
+ }
+ }
+ }
+ }
+
+ if( !m_editModules )
+ {
+ // Add all items as a single undo point for PCB editors
+ editFrame->SaveCopyInUndoList( newItemList, UR_NEW );
+ }
+ }
+
+ getModel<BOARD>()->GetRatsnest()->Recalculate();
+
+ return 0;
+}
+
+
+void EDIT_TOOL::SetTransitions()
+{
+ Go( &EDIT_TOOL::Main, COMMON_ACTIONS::editActivate.MakeEvent() );
+ Go( &EDIT_TOOL::Rotate, COMMON_ACTIONS::rotate.MakeEvent() );
+ Go( &EDIT_TOOL::Flip, COMMON_ACTIONS::flip.MakeEvent() );
+ Go( &EDIT_TOOL::Remove, COMMON_ACTIONS::remove.MakeEvent() );
+ Go( &EDIT_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() );
+ Go( &EDIT_TOOL::MoveExact, COMMON_ACTIONS::moveExact.MakeEvent() );
+ Go( &EDIT_TOOL::Duplicate, COMMON_ACTIONS::duplicate.MakeEvent() );
+ Go( &EDIT_TOOL::Duplicate, COMMON_ACTIONS::duplicateIncrement.MakeEvent() );
+ Go( &EDIT_TOOL::CreateArray,COMMON_ACTIONS::createArray.MakeEvent() );
+ Go( &EDIT_TOOL::editFootprintInFpEditor, COMMON_ACTIONS::editFootprintInFpEditor.MakeEvent() );
+}
+
+
+void EDIT_TOOL::updateRatsnest( bool aRedraw )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+
+ ratsnest->ClearSimple();
+
+ for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+
+ ratsnest->Update( item );
+
+ if( aRedraw )
+ ratsnest->AddSimple( item );
+ }
+}
+
+
+wxPoint EDIT_TOOL::getModificationPoint( const SELECTION& aSelection )
+{
+ if( aSelection.Size() == 1 )
+ {
+ return aSelection.Item<BOARD_ITEM>( 0 )->GetPosition() - m_offset;
+ }
+ else
+ {
+ // If EDIT_TOOL is not currently active then it means that the cursor position is not
+ // updated, so we have to fetch the latest value
+ if( m_toolMgr->GetCurrentToolId() != m_toolId )
+ m_cursor = getViewControls()->GetCursorPosition();
+
+ return wxPoint( m_cursor.x, m_cursor.y );
+ }
+}
+
+
+bool EDIT_TOOL::hoverSelection( const SELECTION& aSelection, bool aSanitize )
+{
+ if( aSelection.Empty() ) // Try to find an item that could be modified
+ {
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionCursor, true );
+
+ if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
+ {
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ return false;
+ }
+ }
+
+ if( aSanitize )
+ m_selectionTool->SanitizeSelection();
+
+ if( aSelection.Empty() ) // TODO is it necessary?
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ return !aSelection.Empty();
+}
+
+void EDIT_TOOL::processUndoBuffer( const PICKED_ITEMS_LIST* aLastChange )
+{
+ PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
+ const std::vector<PICKED_ITEMS_LIST*>& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList;
+ bool process = false;
+
+ BOOST_FOREACH( const PICKED_ITEMS_LIST* list, undoList )
+ {
+ if( process )
+ processPickedList( list );
+ else if( list == aLastChange )
+ process = true; // Start processing starting with the next undo save point
+ }
+
+ // If we could not find the requested save point in the current undo list
+ // then the undo list must have been completely altered, so process everything
+ if( !process )
+ {
+ BOOST_FOREACH( const PICKED_ITEMS_LIST* list, undoList )
+ processPickedList( list );
+ }
+}
+
+
+void EDIT_TOOL::processPickedList( const PICKED_ITEMS_LIST* aList )
+{
+ KIGFX::VIEW* view = getView();
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+
+ for( unsigned int i = 0; i < aList->GetCount(); ++i )
+ {
+ UNDO_REDO_T operation = aList->GetPickedItemStatus( i );
+ BOARD_ITEM* updItem = static_cast<BOARD_ITEM*>( aList->GetPickedItem( i ) );
+
+ switch( operation )
+ {
+ case UR_CHANGED:
+ ratsnest->Update( updItem );
+ // fall through
+
+ case UR_MODEDIT:
+ updItem->ViewUpdate( KIGFX::VIEW_ITEM::ALL );
+ break;
+
+ case UR_DELETED:
+ if( updItem->Type() == PCB_MODULE_T )
+ static_cast<MODULE*>( updItem )->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove,
+ view, _1 ) );
+
+ view->Remove( updItem );
+ //ratsnest->Remove( updItem ); // this is done in BOARD::Remove
+ break;
+
+ case UR_NEW:
+ if( updItem->Type() == PCB_MODULE_T )
+ static_cast<MODULE*>( updItem )->RunOnChildren( boost::bind( &KIGFX::VIEW::Add,
+ view, _1 ) );
+
+ view->Add( updItem );
+ //ratsnest->Add( updItem ); // this is done in BOARD::Add
+ break;
+
+ default:
+ assert( false ); // Not handled
+ break;
+ }
+ }
+}
+
+
+int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+ bool unselect = selection.Empty();
+
+ if( !hoverSelection( selection ) )
+ return 0;
+
+ MODULE* mod = uniqueSelected<MODULE>();
+
+ if( !mod )
+ return 0;
+
+ PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
+
+ editFrame-> SetCurItem( mod );
+
+ if( editFrame->GetCurItem()->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
+ {
+ editFrame->GetCurItem()->SetTimeStamp( GetNewTimeStamp() );
+ editFrame->OnModify();
+ }
+
+ FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) editFrame->Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
+
+ editor->Load_Module_From_BOARD( (MODULE*) editFrame->GetCurItem() );
+ editFrame->SetCurItem( NULL ); // the current module could be deleted by
+
+ editor->Show( true );
+ editor->Raise(); // Iconize( false );
+
+ if( unselect )
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ return 0;
+}
diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h
new file mode 100644
index 0000000..0c24018
--- /dev/null
+++ b/pcbnew/tools/edit_tool.h
@@ -0,0 +1,238 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013-2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __EDIT_TOOL_H
+#define __EDIT_TOOL_H
+
+#include <math/vector2d.h>
+#include <tool/tool_interactive.h>
+#include <view/view_group.h>
+
+class BOARD_ITEM;
+class SELECTION_TOOL;
+
+namespace KIGFX
+{
+class VIEW_GROUP;
+}
+
+/**
+ * Class EDIT_TOOL
+ *
+ * The interactive edit tool. Allows to move, rotate, flip and change properties of items selected
+ * using the pcbnew.InteractiveSelection tool.
+ */
+
+class EDIT_TOOL : public TOOL_INTERACTIVE
+{
+public:
+ EDIT_TOOL();
+
+ /// @copydoc TOOL_INTERACTIVE::Reset()
+ void Reset( RESET_REASON aReason );
+
+ /// @copydoc TOOL_INTERACTIVE::Init()
+ bool Init();
+
+ /**
+ * Function Main()
+ *
+ * Main loop in which events are handled.
+ * @param aEvent is the handled event.
+ */
+ int Main( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function Edit()
+ *
+ * Displays properties window for the selected object.
+ */
+ int Properties( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function Rotate()
+ *
+ * Rotates currently selected items.
+ */
+ int Rotate( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function Flip()
+ *
+ * Rotates currently selected items. The rotation point is the current cursor position.
+ */
+ int Flip( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function Remove()
+ *
+ * Deletes currently selected items. The rotation point is the current cursor position.
+ */
+ int Remove( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function Duplicate()
+ *
+ * Duplicates a selection and starts a move action
+ */
+ int Duplicate( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function MoveExact()
+ *
+ * Invokes a dialog box to allow moving of the item by an exact amount.
+ */
+ int MoveExact( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function CreateArray()
+ *
+ * Creates an array of the selected items, invoking the array editor dialog
+ * to set the array options
+ */
+ int CreateArray( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function EditModules()
+ *
+ * Toggles edit module mode. When enabled, one may select parts of modules individually
+ * (graphics, pads, etc.), so they can be modified.
+ * @param aEnabled decides if the mode should be enabled.
+ */
+ void EditModules( bool aEnabled )
+ {
+ m_editModules = aEnabled;
+ }
+
+ ///> Sets up handlers for various events.
+ void SetTransitions();
+
+private:
+ ///> Selection tool used for obtaining selected items
+ SELECTION_TOOL* m_selectionTool;
+
+ ///> Flag determining if anything is being dragged right now
+ bool m_dragging;
+
+ ///> Offset from the dragged item's center (anchor)
+ wxPoint m_offset;
+
+ ///> Last cursor position (needed for getModificationPoint() to avoid changes
+ ///> of edit reference point).
+ VECTOR2I m_cursor;
+
+ /// Edit module mode flag
+ bool m_editModules;
+
+ /// Counter of undo inhibitions. When zero, undo is not inhibited.
+ int m_undoInhibit;
+
+ // Vector storing track & via types, used for specifying 'Properties' menu entry condition
+ std::vector<KICAD_T> m_tracksViasType;
+
+ ///> Removes and frees a single BOARD_ITEM.
+ void remove( BOARD_ITEM* aItem );
+
+ ///> The required update flag for modified items
+ KIGFX::VIEW_ITEM::VIEW_UPDATE_FLAGS m_updateFlag;
+
+ ///> Enables higher order update flag
+ void enableUpdateFlag( KIGFX::VIEW_ITEM::VIEW_UPDATE_FLAGS aFlag )
+ {
+ if( m_updateFlag < aFlag )
+ m_updateFlag = aFlag;
+ }
+
+ ///> Updates ratsnest for selected items.
+ ///> @param aRedraw says if selected items should be drawn using the simple mode (e.g. one line
+ ///> per item).
+ void updateRatsnest( bool aRedraw );
+
+ ///> Returns the right modification point (e.g. for rotation), depending on the number of
+ ///> selected items.
+ wxPoint getModificationPoint( const SELECTION& aSelection );
+
+ ///> If there are no items currently selected, it tries to choose the item that is under
+ ///> the cursor or displays a disambiguation menu if there are multpile items.
+ bool hoverSelection( const SELECTION& aSelection, bool aSanitize = true );
+
+ ///> Processes the current undo buffer since the last change. If the last change does not occur
+ ///> in the current buffer, then the whole list is processed.
+ void processUndoBuffer( const PICKED_ITEMS_LIST* aLastChange );
+
+ ///> Updates items stored in the list.
+ void processPickedList( const PICKED_ITEMS_LIST* aList );
+
+ /**
+ * Increments the undo inhibit counter. This will indicate that tools
+ * should not create an undo point, as another tool is doing it already,
+ * and considers that its operation is atomic, even if it calls another one
+ * (for example a duplicate calls a move).
+ */
+ inline void incUndoInhibit()
+ {
+ m_undoInhibit++;
+ }
+
+ /**
+ * Decrements the inhibit counter. An assert is raised if the counter drops
+ * below zero.
+ */
+ inline void decUndoInhibit()
+ {
+ m_undoInhibit--;
+
+ wxASSERT_MSG( m_undoInhibit >= 0, wxT( "Undo inhibit count decremented past zero" ) );
+ }
+
+ /**
+ * Report if the tool manager has been told at least once that undo
+ * points should not be created. This can be ignored if the undo point
+ * is still required.
+ *
+ * @return true if undo are inhibited
+ */
+ inline bool isUndoInhibited() const
+ {
+ return m_undoInhibit > 0;
+ }
+
+ int editFootprintInFpEditor( const TOOL_EVENT& aEvent );
+
+ bool invokeInlineRouter();
+
+ template<class T> T* uniqueSelected()
+ {
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ if( selection.items.GetCount() != 1 )
+ return NULL;
+
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 );
+ return dyn_cast<T*>( item );
+ }
+};
+
+#endif
diff --git a/pcbnew/tools/grid_helper.cpp b/pcbnew/tools/grid_helper.cpp
new file mode 100644
index 0000000..4e811ca
--- /dev/null
+++ b/pcbnew/tools/grid_helper.cpp
@@ -0,0 +1,393 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+
+#include <wxPcbStruct.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+#include <class_zone.h>
+#include <class_draw_panel_gal.h>
+
+#include <view/view_controls.h>
+#include <gal/graphics_abstraction_layer.h>
+
+#include <geometry/shape_line_chain.h>
+
+#include "grid_helper.h"
+
+GRID_HELPER::GRID_HELPER( PCB_BASE_FRAME* aFrame ) :
+ m_frame( aFrame )
+{
+ m_diagonalAuxAxesEnable = true;
+}
+
+
+GRID_HELPER::~GRID_HELPER()
+{
+}
+
+
+void GRID_HELPER::SetGrid( int aSize )
+{
+ assert( false );
+}
+
+
+void GRID_HELPER::SetOrigin( const VECTOR2I& aOrigin )
+{
+ assert( false );
+}
+
+
+VECTOR2I GRID_HELPER::GetGrid() const
+{
+ PCB_SCREEN* screen = m_frame->GetScreen();
+
+ const wxRealPoint& size = screen->GetGridSize();
+
+ return VECTOR2I( KiROUND( size.x ), KiROUND( size.y ) );
+}
+
+
+VECTOR2I GRID_HELPER::GetOrigin() const
+{
+ return VECTOR2I( m_frame->GetGridOrigin() );
+}
+
+
+void GRID_HELPER::SetAuxAxes( bool aEnable, const VECTOR2I& aOrigin, bool aEnableDiagonal )
+{
+ if( aEnable )
+ m_auxAxis = aOrigin;
+ else
+ m_auxAxis = boost::optional<VECTOR2I>();
+
+ m_diagonalAuxAxesEnable = aEnable;
+}
+
+
+VECTOR2I GRID_HELPER::Align( const VECTOR2I& aPoint ) const
+{
+ const VECTOR2D gridOffset( GetOrigin() );
+ const VECTOR2D gridSize( GetGrid() );
+
+ VECTOR2I nearest( KiROUND( ( aPoint.x - gridOffset.x ) / gridSize.x ) * gridSize.x + gridOffset.x,
+ KiROUND( ( aPoint.y - gridOffset.y ) / gridSize.y ) * gridSize.y + gridOffset.y );
+
+ if( !m_auxAxis )
+ return nearest;
+
+ if( std::abs( m_auxAxis->x - aPoint.x ) < std::abs( nearest.x - aPoint.x ) )
+ nearest.x = m_auxAxis->x;
+
+ if( std::abs( m_auxAxis->y - aPoint.y ) < std::abs( nearest.y - aPoint.y ) )
+ nearest.y = m_auxAxis->y;
+
+ return nearest;
+}
+
+
+VECTOR2I GRID_HELPER::AlignToSegment ( const VECTOR2I& aPoint, const SEG& aSeg )
+{
+ OPT_VECTOR2I pts[6];
+
+ VECTOR2I origin( GetOrigin() );
+ VECTOR2I grid( GetGrid() );
+
+ const VECTOR2D gridOffset( GetOrigin() );
+ const VECTOR2D gridSize( GetGrid() );
+
+ VECTOR2I nearest( KiROUND( ( aPoint.x - gridOffset.x ) / gridSize.x ) * gridSize.x + gridOffset.x,
+ KiROUND( ( aPoint.y - gridOffset.y ) / gridSize.y ) * gridSize.y + gridOffset.y );
+
+ pts[0] = aSeg.A;
+ pts[1] = aSeg.B;
+ pts[2] = aSeg.IntersectLines( SEG( nearest, nearest + VECTOR2I( 1, 0 ) ) );
+ pts[3] = aSeg.IntersectLines( SEG( nearest, nearest + VECTOR2I( 0, 1 ) ) );
+
+ int min_d = std::numeric_limits<int>::max();
+
+ for( int i = 0; i < 4; i++ )
+ {
+ if( pts[i] && aSeg.Contains( *pts[i] ) )
+ {
+ int d = (*pts[i] - aPoint).EuclideanNorm();
+
+ if( d < min_d )
+ {
+ min_d = d;
+ nearest = *pts[i];
+ }
+ }
+ }
+
+ return nearest;
+}
+
+VECTOR2I GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, BOARD_ITEM* aItem )
+{
+ clearAnchors();
+ computeAnchors( aItem, aMousePos );
+
+ double worldScale = m_frame->GetGalCanvas()->GetGAL()->GetWorldScale();
+ double lineSnapMinCornerDistance = 50.0 / worldScale;
+
+ ANCHOR* nearestOutline = nearestAnchor( aMousePos, OUTLINE, LSET::AllLayersMask() );
+ ANCHOR* nearestCorner = nearestAnchor( aMousePos, CORNER, LSET::AllLayersMask() );
+ ANCHOR* nearestOrigin = nearestAnchor( aMousePos, ORIGIN, LSET::AllLayersMask() );
+ ANCHOR* best = NULL;
+ double minDist = std::numeric_limits<double>::max();
+
+ if( nearestOrigin )
+ {
+ minDist = nearestOrigin->Distance( aMousePos );
+ best = nearestOrigin;
+ }
+
+ if( nearestCorner )
+ {
+ double dist = nearestCorner->Distance( aMousePos );
+
+ if( dist < minDist )
+ {
+ minDist = dist;
+ best = nearestCorner;
+ }
+ }
+
+ if( nearestOutline )
+ {
+ double dist = nearestOutline->Distance( aMousePos );
+
+ if( minDist > lineSnapMinCornerDistance && dist < minDist )
+ best = nearestOutline;
+ }
+
+ return best ? best->pos : aMousePos;
+}
+
+
+std::set<BOARD_ITEM*> GRID_HELPER::queryVisible( const BOX2I& aArea ) const
+{
+ std::set<BOARD_ITEM*> items;
+
+ std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
+ std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
+
+ m_frame->GetGalCanvas()->GetView()->Query( aArea, selectedItems ); // Get the list of selected items
+
+ for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it )
+ {
+ BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first );
+ if( item->ViewIsVisible() )
+ items.insert ( item );
+ }
+
+ return items;
+}
+
+
+VECTOR2I GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, BOARD_ITEM* aDraggedItem )
+{
+ double worldScale = m_frame->GetGalCanvas()->GetGAL()->GetWorldScale();
+ int snapRange = (int) ( 100.0 / worldScale );
+
+ BOX2I bb( VECTOR2I( aOrigin.x - snapRange / 2, aOrigin.y - snapRange / 2 ), VECTOR2I( snapRange, snapRange ) );
+
+ clearAnchors();
+
+ BOOST_FOREACH( BOARD_ITEM* item, queryVisible( bb ) )
+ {
+ computeAnchors( item, aOrigin );
+ }
+
+ LSET layers( aDraggedItem->GetLayer() );
+ ANCHOR* nearest = nearestAnchor( aOrigin, CORNER | SNAPPABLE, layers );
+
+ VECTOR2I nearestGrid = Align( aOrigin );
+ double gridDist = ( nearestGrid - aOrigin ).EuclideanNorm();
+ if( nearest )
+ {
+ double snapDist = nearest->Distance( aOrigin );
+
+ if( nearest && snapDist < gridDist )
+ return nearest->pos;
+ }
+
+ return nearestGrid;
+}
+
+
+void GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos )
+{
+ VECTOR2I origin;
+
+ switch( aItem->Type() )
+ {
+ case PCB_MODULE_T:
+ {
+ MODULE* mod = static_cast<MODULE*>( aItem );
+ addAnchor( mod->GetPosition(), ORIGIN | SNAPPABLE, mod );
+
+ for( D_PAD* pad = mod->Pads(); pad; pad = pad->Next() )
+ addAnchor( pad->GetPosition(), CORNER | SNAPPABLE, pad );
+
+ break;
+ }
+
+
+ case PCB_PAD_T:
+ {
+ D_PAD* pad = static_cast<D_PAD*>( aItem );
+ addAnchor( pad->GetPosition(), CORNER | SNAPPABLE, pad );
+
+ break;
+ }
+
+ case PCB_MODULE_EDGE_T:
+ case PCB_LINE_T:
+ {
+ DRAWSEGMENT* dseg = static_cast<DRAWSEGMENT*>( aItem );
+ VECTOR2I start = dseg->GetStart();
+ VECTOR2I end = dseg->GetEnd();
+ //LAYER_ID layer = dseg->GetLayer();
+
+ switch( dseg->GetShape() )
+ {
+ case S_CIRCLE:
+ {
+ int r = ( start - end ).EuclideanNorm();
+
+ addAnchor( start, ORIGIN | SNAPPABLE, dseg );
+ addAnchor( start + VECTOR2I( -r, 0 ), OUTLINE | SNAPPABLE, dseg );
+ addAnchor( start + VECTOR2I( r, 0 ), OUTLINE | SNAPPABLE, dseg );
+ addAnchor( start + VECTOR2I( 0, -r ), OUTLINE | SNAPPABLE, dseg );
+ addAnchor( start + VECTOR2I( 0, r ), OUTLINE | SNAPPABLE, dseg );
+ break;
+ }
+
+ case S_ARC:
+ {
+ origin = dseg->GetCenter();
+ addAnchor( dseg->GetArcStart(), CORNER | SNAPPABLE, dseg );
+ addAnchor( dseg->GetArcEnd(), CORNER | SNAPPABLE, dseg );
+ addAnchor( origin, ORIGIN | SNAPPABLE, dseg );
+ break;
+ }
+
+ case S_SEGMENT:
+ {
+ origin.x = start.x + ( start.x - end.x ) / 2;
+ origin.y = start.y + ( start.y - end.y ) / 2;
+ addAnchor( start, CORNER | SNAPPABLE, dseg );
+ addAnchor( end, CORNER | SNAPPABLE, dseg );
+ addAnchor( origin, ORIGIN, dseg );
+ break;
+ }
+
+ default:
+ {
+ origin = dseg->GetStart();
+ addAnchor( origin, ORIGIN | SNAPPABLE, dseg );
+ break;
+ }
+ }
+ break;
+ }
+
+ case PCB_TRACE_T:
+ {
+ TRACK* track = static_cast<TRACK*>( aItem );
+ VECTOR2I start = track->GetStart();
+ VECTOR2I end = track->GetEnd();
+ origin.x = start.x + ( start.x - end.x ) / 2;
+ origin.y = start.y + ( start.y - end.y ) / 2;
+ addAnchor( start, CORNER | SNAPPABLE, track );
+ addAnchor( end, CORNER | SNAPPABLE, track );
+ addAnchor( origin, ORIGIN, track);
+ break;
+ }
+
+ case PCB_VIA_T:
+ addAnchor( aItem->GetPosition(), CORNER | SNAPPABLE, aItem );
+ break;
+
+ case PCB_ZONE_AREA_T:
+ {
+ const CPolyLine* outline = static_cast<const ZONE_CONTAINER*>( aItem )->Outline();
+ int cornersCount = outline->GetCornersCount();
+
+ SHAPE_LINE_CHAIN lc;
+ lc.SetClosed( true );
+
+ for( int i = 0; i < cornersCount; ++i )
+ {
+ const VECTOR2I p ( outline->GetPos( i ) );
+ addAnchor( p, CORNER, aItem );
+ lc.Append( p );
+ }
+
+ addAnchor( lc.NearestPoint( aRefPos ), OUTLINE, aItem );
+
+ break;
+ }
+
+ case PCB_MODULE_TEXT_T:
+ case PCB_TEXT_T:
+ addAnchor( aItem->GetPosition(), ORIGIN, aItem );
+ default:
+
+ break;
+ }
+}
+
+
+GRID_HELPER::ANCHOR* GRID_HELPER::nearestAnchor( const VECTOR2I& aPos, int aFlags, LSET aMatchLayers )
+{
+ double minDist = std::numeric_limits<double>::max();
+ ANCHOR* best = NULL;
+
+ BOOST_FOREACH( ANCHOR& a, m_anchors )
+ {
+ if( !aMatchLayers[a.item->GetLayer()] )
+ continue;
+
+ if( ( aFlags & a.flags ) != aFlags )
+ continue;
+
+ double dist = a.Distance( aPos );
+
+ if( dist < minDist )
+ {
+ minDist = dist;
+ best = &a;
+ }
+ }
+
+ return best;
+}
diff --git a/pcbnew/tools/grid_helper.h b/pcbnew/tools/grid_helper.h
new file mode 100644
index 0000000..6401b69
--- /dev/null
+++ b/pcbnew/tools/grid_helper.h
@@ -0,0 +1,108 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __GRID_HELPER_H
+#define __GRID_HELPER_H
+
+#include <vector>
+
+#include <math/vector2d.h>
+#include <boost/optional.hpp>
+
+#include <layers_id_colors_and_visibility.h>
+
+#include <geometry/seg.h>
+
+class PCB_BASE_FRAME;
+
+class GRID_HELPER {
+public:
+
+ GRID_HELPER( PCB_BASE_FRAME* aFrame );
+ ~GRID_HELPER();
+
+ void SetGrid( int aSize );
+ void SetOrigin( const VECTOR2I& aOrigin );
+
+ VECTOR2I GetGrid() const;
+ VECTOR2I GetOrigin() const;
+
+ void SetAuxAxes( bool aEnable, const VECTOR2I& aOrigin = VECTOR2I( 0, 0 ), bool aEnableDiagonal = false );
+
+ VECTOR2I Align( const VECTOR2I& aPoint ) const;
+
+ VECTOR2I AlignToSegment ( const VECTOR2I& aPoint, const SEG& aSeg );
+
+ VECTOR2I BestDragOrigin( const VECTOR2I& aMousePos, BOARD_ITEM* aItem );
+ VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, BOARD_ITEM* aDraggedItem );
+
+private:
+ enum ANCHOR_FLAGS {
+ CORNER = 0x1,
+ OUTLINE = 0x2,
+ SNAPPABLE = 0x4,
+ ORIGIN = 0x8
+ };
+
+ struct ANCHOR
+ {
+ ANCHOR( VECTOR2I aPos, int aFlags = CORNER | SNAPPABLE, BOARD_ITEM* aItem = NULL ):
+ pos( aPos ), flags( aFlags ), item( aItem ) {} ;
+
+ VECTOR2I pos;
+ int flags;
+ BOARD_ITEM* item;
+
+ double Distance( const VECTOR2I& aP ) const
+ {
+ return ( aP - pos ).EuclideanNorm();
+ }
+
+ //bool CanSnapItem( const BOARD_ITEM* aItem ) const;
+ };
+
+ std::vector<ANCHOR> m_anchors;
+
+ std::set<BOARD_ITEM*> queryVisible( const BOX2I& aArea ) const;
+
+ void addAnchor( const VECTOR2I& aPos, int aFlags = CORNER | SNAPPABLE, BOARD_ITEM* aItem = NULL )
+ {
+ m_anchors.push_back( ANCHOR( aPos, aFlags, aItem ) );
+ }
+
+ ANCHOR* nearestAnchor( const VECTOR2I& aPos, int aFlags, LSET aMatchLayers );
+
+ void computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos );
+
+ void clearAnchors()
+ {
+ m_anchors.clear();
+ }
+
+ PCB_BASE_FRAME* m_frame;
+ boost::optional<VECTOR2I> m_auxAxis;
+ bool m_diagonalAuxAxesEnable;
+};
+
+#endif
diff --git a/pcbnew/tools/grid_menu.cpp b/pcbnew/tools/grid_menu.cpp
new file mode 100644
index 0000000..4d23351
--- /dev/null
+++ b/pcbnew/tools/grid_menu.cpp
@@ -0,0 +1,68 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "grid_menu.h"
+#include <id.h>
+#include <draw_frame.h>
+#include <class_base_screen.h>
+#include <tools/common_actions.h>
+
+#include <boost/bind.hpp>
+
+GRID_MENU::GRID_MENU( EDA_DRAW_FRAME* aParent ) : m_parent( aParent )
+{
+ BASE_SCREEN* screen = aParent->GetScreen();
+
+ SetIcon( grid_select_xpm );
+ SetMenuHandler( boost::bind( &GRID_MENU::EventHandler, this, _1 ) );
+ SetUpdateHandler( boost::bind( &GRID_MENU::Update, this ) );
+
+ wxArrayString gridsList;
+ screen->BuildGridsChoiceList( gridsList, g_UserUnit != INCHES );
+
+ for( unsigned int i = 0; i < gridsList.GetCount(); ++i )
+ {
+ GRID_TYPE& grid = screen->GetGrid( i );
+ Append( grid.m_CmdId, gridsList[i], wxEmptyString, true );
+ }
+}
+
+
+OPT_TOOL_EVENT GRID_MENU::EventHandler( const wxMenuEvent& aEvent )
+{
+ OPT_TOOL_EVENT event( COMMON_ACTIONS::gridPreset.MakeEvent() );
+ long idx = aEvent.GetId() - ID_POPUP_GRID_SELECT - 1;
+ event->SetParameter( idx );
+
+ return event;
+}
+
+
+void GRID_MENU::Update()
+{
+ for( unsigned int i = 0; i < GetMenuItemCount(); ++i )
+ Check( ID_POPUP_GRID_SELECT + 1 + i, false );
+
+ Check( m_parent->GetScreen()->GetGridCmdId(), true );
+}
diff --git a/pcbnew/tools/grid_menu.h b/pcbnew/tools/grid_menu.h
new file mode 100644
index 0000000..b73920c
--- /dev/null
+++ b/pcbnew/tools/grid_menu.h
@@ -0,0 +1,44 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef GRID_MENU_H
+#define GRID_MENU_H
+
+#include <tool/context_menu.h>
+
+class EDA_DRAW_FRAME;
+
+class GRID_MENU : public CONTEXT_MENU
+{
+public:
+ GRID_MENU( EDA_DRAW_FRAME* aParent );
+
+ OPT_TOOL_EVENT EventHandler( const wxMenuEvent& aEvent );
+ void Update();
+
+private:
+ EDA_DRAW_FRAME* m_parent;
+};
+
+#endif /* GRID_MENU_H */
diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp
new file mode 100644
index 0000000..3a5d9a3
--- /dev/null
+++ b/pcbnew/tools/module_tools.cpp
@@ -0,0 +1,608 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014-2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "module_tools.h"
+#include "selection_tool.h"
+#include "common_actions.h"
+#include <tool/tool_manager.h>
+
+#include <class_draw_panel_gal.h>
+#include <view/view_controls.h>
+#include <view/view_group.h>
+#include <pcb_painter.h>
+#include <origin_viewitem.h>
+
+#include <kicad_plugin.h>
+#include <pcbnew_id.h>
+#include <collectors.h>
+#include <confirm.h>
+#include <dialogs/dialog_enum_pads.h>
+
+#include <wxPcbStruct.h>
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+
+#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
+#include <wx/defs.h>
+
+MODULE_TOOLS::MODULE_TOOLS() :
+ TOOL_INTERACTIVE( "pcbnew.ModuleEditor" ), m_view( NULL ), m_controls( NULL ),
+ m_board( NULL ), m_frame( NULL )
+{
+ // Generate an origin marker at 0,0 which is used as an axis origin marker (0,0)
+ m_axisOrigin = new KIGFX::ORIGIN_VIEWITEM( KIGFX::COLOR4D(0.0, 0.0, 0.8, 1.0),
+ KIGFX::ORIGIN_VIEWITEM::CROSS,
+ 20000,
+ VECTOR2D(0,0) );
+ m_axisOrigin->SetDrawAtZero( true );
+}
+
+
+MODULE_TOOLS::~MODULE_TOOLS()
+{
+ delete m_axisOrigin;
+}
+
+
+void MODULE_TOOLS::Reset( RESET_REASON aReason )
+{
+ // Init variables used by every drawing tool
+ m_view = getView();
+ m_controls = getViewControls();
+ m_board = getModel<BOARD>();
+ m_frame = getEditFrame<PCB_EDIT_FRAME>();
+
+ if( aReason == MODEL_RELOAD || aReason == GAL_SWITCH )
+ {
+ // Draw the axis origin if we're editing modules (essentially in the footprint editor)
+ m_view->Remove( m_axisOrigin );
+ m_view->Add( m_axisOrigin );
+ }
+}
+
+
+bool MODULE_TOOLS::Init()
+{
+ // Find the selection tool, so they can cooperate
+ SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
+
+ if( !selectionTool )
+ {
+ DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) );
+ return false;
+ }
+
+ selectionTool->GetMenu().AddItem( COMMON_ACTIONS::enumeratePads );
+
+ return true;
+}
+
+
+int MODULE_TOOLS::PlacePad( const TOOL_EVENT& aEvent )
+{
+ m_frame->SetToolID( ID_MODEDIT_PAD_TOOL, wxCURSOR_PENCIL, _( "Add pads" ) );
+
+ assert( m_board->m_Modules );
+
+ D_PAD* pad = new D_PAD( m_board->m_Modules );
+ m_frame->Import_Pad_Settings( pad, false ); // use the global settings for pad
+
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+ pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
+
+ // Add a VIEW_GROUP that serves as a preview for the new item
+ KIGFX::VIEW_GROUP preview( m_view );
+ preview.Add( pad );
+ m_view->Add( &preview );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ m_controls->ShowCursor( true );
+ m_controls->SetSnapping( true );
+
+ Activate();
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ cursorPos = m_controls->GetCursorPosition();
+
+ if( evt->IsMotion() )
+ {
+ pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
+ preview.ViewUpdate();
+ }
+
+ else if( evt->Category() == TC_COMMAND )
+ {
+ if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
+ {
+ pad->Rotate( pad->GetPosition(), m_frame->GetRotationAngle() );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
+ {
+ pad->Flip( pad->GetPosition() );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ else if( evt->IsCancel() || evt->IsActivate() )
+ {
+ preview.Clear();
+ delete pad;
+ break;
+ }
+ }
+
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
+
+ m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view
+ pad->SetParent( m_board->m_Modules );
+ m_board->m_Modules->SetLastEditTime();
+ m_board->m_Modules->Pads().PushBack( pad );
+
+ // Set the relative pad position
+ // ( pad position for module orient, 0, and relative to the module position)
+ pad->SetLocalCoord();
+
+ // Take the next available pad number
+ pad->IncrementPadName( true, true );
+
+ // Handle the view aspect
+ preview.Remove( pad );
+ m_view->Add( pad );
+
+ // Start placing next pad
+ pad = new D_PAD( m_board->m_Modules );
+ m_frame->Import_Pad_Settings( pad, false );
+ pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
+ preview.Add( pad );
+ }
+ }
+
+ m_controls->ShowCursor( false );
+ m_controls->SetSnapping( false );
+ m_controls->SetAutoPan( false );
+ m_view->Remove( &preview );
+
+ m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+
+ return 0;
+}
+
+
+int MODULE_TOOLS::EnumeratePads( const TOOL_EVENT& aEvent )
+{
+ std::list<D_PAD*> pads;
+ std::set<D_PAD*> allPads;
+
+ if( !m_board->m_Modules || !m_board->m_Modules->Pads() )
+ return 0;
+
+ GENERAL_COLLECTOR collector;
+ const KICAD_T types[] = { PCB_PAD_T, EOT };
+
+ GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide();
+ guide.SetIgnoreMTextsMarkedNoShow( true );
+ guide.SetIgnoreMTextsOnBack( true );
+ guide.SetIgnoreMTextsOnFront( true );
+ guide.SetIgnoreModulesVals( true );
+ guide.SetIgnoreModulesRefs( true );
+
+ // Create a set containing all pads (to avoid double adding to the list)
+ for( D_PAD* p = m_board->m_Modules->Pads(); p; p = p->Next() )
+ allPads.insert( p );
+
+ DIALOG_ENUM_PADS settingsDlg( m_frame );
+
+ if( settingsDlg.ShowModal() == wxID_CANCEL )
+ return 0;
+
+ int padNumber = settingsDlg.GetStartNumber();
+ wxString padPrefix = settingsDlg.GetPrefix();
+
+ m_frame->DisplayToolMsg( _( "Hold left mouse button and move cursor over pads to enumerate them" ) );
+
+ Activate();
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ m_controls->ShowCursor( true );
+ VECTOR2I oldCursorPos = m_controls->GetCursorPosition();
+ std::list<D_PAD*> selectedPads;
+
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ if( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
+ {
+ selectedPads.clear();
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+
+ if( evt->IsClick( BUT_LEFT ) )
+ {
+ oldCursorPos = m_controls->GetCursorPosition();
+ collector.Empty();
+ collector.Collect( m_board, types, wxPoint( cursorPos.x, cursorPos.y ), guide );
+
+ for( int i = 0; i < collector.GetCount(); ++i )
+ {
+ if( collector[i]->Type() == PCB_PAD_T )
+ selectedPads.push_back( static_cast<D_PAD*>( collector[i] ) );
+ }
+ }
+ else //evt->IsDrag( BUT_LEFT )
+ {
+ // wxWidgets deliver mouse move events not frequently enough, resulting in skipping
+ // pads if the user moves cursor too fast. To solve it, create a line that approximates
+ // the mouse move and select items intersecting with the line.
+ int distance = ( cursorPos - oldCursorPos ).EuclideanNorm();
+ int segments = distance / 100000 + 1;
+ const wxPoint LINE_STEP( ( cursorPos - oldCursorPos ).x / segments,
+ ( cursorPos - oldCursorPos ).y / segments );
+
+ collector.Empty();
+ for( int j = 0; j < segments; ++j ) {
+ collector.Collect( m_board, types,
+ wxPoint( oldCursorPos.x, oldCursorPos.y ) + j * LINE_STEP,
+ guide );
+
+ for( int i = 0; i < collector.GetCount(); ++i )
+ {
+ if( collector[i]->Type() == PCB_PAD_T )
+ selectedPads.push_back( static_cast<D_PAD*>( collector[i] ) );
+ }
+ }
+
+ selectedPads.unique();
+ }
+
+ BOOST_FOREACH( D_PAD* pad, selectedPads )
+ {
+ std::set<D_PAD*>::iterator it = allPads.find( pad );
+
+ // Add the pad to the list, if it was not selected previously..
+ if( it != allPads.end() )
+ {
+ allPads.erase( it );
+ pads.push_back( pad );
+ pad->SetSelected();
+ }
+
+ // ..or remove it from the list if it was clicked
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ allPads.insert( pad );
+ pads.remove( pad );
+ pad->ClearSelected();
+ }
+ }
+
+ oldCursorPos = cursorPos;
+ }
+
+ else if( ( evt->IsKeyPressed() && evt->KeyCode() == WXK_RETURN ) ||
+ evt->IsDblClick( BUT_LEFT ) )
+ {
+ // Accept changes
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
+
+ BOOST_FOREACH( D_PAD* pad, pads )
+ pad->SetPadName( wxString::Format( wxT( "%s%d" ), padPrefix.c_str(), padNumber++ ) );
+
+ break;
+ }
+
+ else if( evt->IsCancel() || evt->IsActivate() )
+ {
+ break;
+ }
+ }
+
+ BOOST_FOREACH( D_PAD* pad, pads )
+ pad->ClearSelected();
+
+ m_frame->DisplayToolMsg( wxEmptyString );
+ m_controls->ShowCursor( false );
+
+ return 0;
+}
+
+
+int MODULE_TOOLS::CopyItems( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
+
+ Activate();
+
+ m_controls->SetSnapping( true );
+ m_controls->ShowCursor( true );
+ m_controls->SetAutoPan( true );
+
+ m_frame->DisplayToolMsg( _( "Select reference point" ) );
+
+ bool cancelled = false;
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ if( evt->IsMotion() )
+ {
+ cursorPos = m_controls->GetCursorPosition();
+ }
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ break;
+ }
+ else if( evt->IsCancel() || evt->IsActivate() )
+ {
+ cancelled = true;
+ break;
+ }
+ }
+
+ if( !cancelled )
+ {
+ PCB_IO io( CTL_FOR_CLIPBOARD );
+
+ // Create a temporary module that contains selected items to ease serialization
+ MODULE module( m_board );
+
+ for( int i = 0; i < selection.Size(); ++i )
+ {
+ BOARD_ITEM* clone = static_cast<BOARD_ITEM*>( selection.Item<BOARD_ITEM>( i )->Clone() );
+
+ // Do not add reference/value - convert them to the common type
+ if( TEXTE_MODULE* text = dyn_cast<TEXTE_MODULE*>( clone ) )
+ text->SetType( TEXTE_MODULE::TEXT_is_DIVERS );
+
+ module.Add( clone );
+ }
+
+ // Set the new relative internal local coordinates of copied items
+ MODULE* editedModule = m_board->m_Modules;
+ wxPoint moveVector = module.GetPosition() + editedModule->GetPosition() -
+ wxPoint( cursorPos.x, cursorPos.y );
+ module.MoveAnchorPosition( moveVector );
+
+ io.Format( &module, 0 );
+ std::string data = io.GetStringOutput( true );
+ m_toolMgr->SaveClipboard( data );
+ }
+
+ m_frame->DisplayToolMsg( wxString::Format( _( "Copied %d item(s)" ), selection.Size() ) );
+ m_controls->SetSnapping( false );
+ m_controls->ShowCursor( false );
+ m_controls->SetAutoPan( false );
+
+ return 0;
+}
+
+
+int MODULE_TOOLS::PasteItems( const TOOL_EVENT& aEvent )
+{
+ // Parse clipboard
+ PCB_IO io( CTL_FOR_CLIPBOARD );
+ MODULE* currentModule = m_board->m_Modules;
+ MODULE* pastedModule = NULL;
+
+ try
+ {
+ BOARD_ITEM* item = io.Parse( wxString( m_toolMgr->GetClipboard().c_str(), wxConvUTF8 ) );
+ assert( item->Type() == PCB_MODULE_T );
+ pastedModule = dyn_cast<MODULE*>( item );
+ }
+ catch( ... )
+ {
+ m_frame->DisplayToolMsg( _( "Invalid clipboard contents" ) );
+ return 0;
+ }
+
+ // Placement tool part
+ VECTOR2I cursorPos = m_controls->GetCursorPosition();
+
+ // Add a VIEW_GROUP that serves as a preview for the new item
+ KIGFX::VIEW_GROUP preview( m_view );
+ pastedModule->SetParent( m_board );
+ pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
+ pastedModule->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Add, boost::ref( preview ), _1 ) );
+ preview.Add( pastedModule );
+ m_view->Add( &preview );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ m_controls->ShowCursor( true );
+ m_controls->SetSnapping( true );
+ m_controls->SetAutoPan( true );
+
+ Activate();
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ cursorPos = m_controls->GetCursorPosition();
+
+ if( evt->IsMotion() )
+ {
+ pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
+ preview.ViewUpdate();
+ }
+
+ else if( evt->Category() == TC_COMMAND )
+ {
+ if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
+ {
+ pastedModule->Rotate( pastedModule->GetPosition(), m_frame->GetRotationAngle() );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
+ {
+ pastedModule->Flip( pastedModule->GetPosition() );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ else if( evt->IsCancel() || evt->IsActivate() )
+ {
+ preview.Clear();
+ break;
+ }
+ }
+
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( currentModule, UR_MODEDIT );
+
+ m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view
+ currentModule->SetLastEditTime();
+
+ // MODULE::RunOnChildren is infeasible here: we need to create copies of items, do not
+ // directly modify them
+
+ for( D_PAD* pad = pastedModule->Pads(); pad; pad = pad->Next() )
+ {
+ D_PAD* clone = static_cast<D_PAD*>( pad->Clone() );
+
+ currentModule->Add( clone );
+ clone->SetLocalCoord();
+ m_view->Add( clone );
+ }
+
+ for( BOARD_ITEM* drawing = pastedModule->GraphicalItems();
+ drawing; drawing = drawing->Next() )
+ {
+ BOARD_ITEM* clone = static_cast<BOARD_ITEM*>( drawing->Clone() );
+
+ if( TEXTE_MODULE* text = dyn_cast<TEXTE_MODULE*>( clone ) )
+ {
+ // Do not add reference/value - convert them to the common type
+ text->SetType( TEXTE_MODULE::TEXT_is_DIVERS );
+ currentModule->Add( text );
+ text->SetLocalCoord();
+
+ // Whyyyyyyyyyyyyyyyyyyyyyy?! All other items conform to rotation performed
+ // on its parent module, but texts are so independent..
+ text->Rotate( text->GetPosition(), pastedModule->GetOrientation() );
+ }
+ else if( EDGE_MODULE* edge = dyn_cast<EDGE_MODULE*>( clone ) )
+ {
+ currentModule->Add( edge );
+ edge->SetLocalCoord();
+ }
+
+ m_view->Add( clone );
+ }
+
+ preview.Clear();
+
+ break;
+ }
+ }
+
+ delete pastedModule;
+ m_controls->ShowCursor( false );
+ m_controls->SetSnapping( false );
+ m_controls->SetAutoPan( false );
+ m_view->Remove( &preview );
+
+ return 0;
+}
+
+
+int MODULE_TOOLS::ModuleTextOutlines( const TOOL_EVENT& aEvent )
+{
+ KIGFX::PCB_PAINTER* painter =
+ static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetGalCanvas()->GetView()->GetPainter() );
+ KIGFX::PCB_RENDER_SETTINGS* settings =
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
+
+ const LAYER_NUM layers[] = { ITEM_GAL_LAYER( MOD_TEXT_BK_VISIBLE ),
+ ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ),
+ ITEM_GAL_LAYER( MOD_TEXT_INVISIBLE ),
+ ITEM_GAL_LAYER( MOD_REFERENCES_VISIBLE ),
+ ITEM_GAL_LAYER( MOD_VALUES_VISIBLE ) };
+
+ bool enable = !settings->GetSketchMode( layers[0] );
+
+ BOOST_FOREACH( LAYER_NUM layer, layers )
+ settings->SetSketchMode( layer, enable );
+
+ for( MODULE* module = getModel<BOARD>()->m_Modules; module; module = module->Next() )
+ {
+ for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item ->Next() )
+ {
+ if( item->Type() == PCB_MODULE_TEXT_T )
+ item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ module->Reference().ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ module->Value().ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ m_frame->GetGalCanvas()->Refresh();
+
+ return 0;
+}
+
+
+int MODULE_TOOLS::ModuleEdgeOutlines( const TOOL_EVENT& aEvent )
+{
+ KIGFX::PCB_PAINTER* painter =
+ static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetGalCanvas()->GetView()->GetPainter() );
+ KIGFX::PCB_RENDER_SETTINGS* settings =
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
+
+ const LAYER_ID layers[] = { F_Adhes, B_Adhes, F_Paste, B_Paste,
+ F_SilkS, B_SilkS, F_Mask, B_Mask,
+ Dwgs_User, Cmts_User, Eco1_User, Eco2_User, Edge_Cuts };
+
+ bool enable = !settings->GetSketchMode( layers[0] );
+
+ BOOST_FOREACH( LAYER_NUM layer, layers )
+ settings->SetSketchMode( layer, enable );
+
+ for( MODULE* module = getModel<BOARD>()->m_Modules; module; module = module->Next() )
+ {
+ for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item ->Next() )
+ {
+ if( item->Type() == PCB_MODULE_EDGE_T )
+ item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ m_frame->GetGalCanvas()->Refresh();
+
+ return 0;
+}
+
+
+void MODULE_TOOLS::SetTransitions()
+{
+ Go( &MODULE_TOOLS::PlacePad, COMMON_ACTIONS::placePad.MakeEvent() );
+ Go( &MODULE_TOOLS::EnumeratePads, COMMON_ACTIONS::enumeratePads.MakeEvent() );
+ Go( &MODULE_TOOLS::CopyItems, COMMON_ACTIONS::copyItems.MakeEvent() );
+ Go( &MODULE_TOOLS::PasteItems, COMMON_ACTIONS::pasteItems.MakeEvent() );
+ Go( &MODULE_TOOLS::ModuleTextOutlines, COMMON_ACTIONS::moduleTextOutlines.MakeEvent() );
+ Go( &MODULE_TOOLS::ModuleEdgeOutlines, COMMON_ACTIONS::moduleEdgeOutlines.MakeEvent() );
+}
diff --git a/pcbnew/tools/module_tools.h b/pcbnew/tools/module_tools.h
new file mode 100644
index 0000000..b2178ba
--- /dev/null
+++ b/pcbnew/tools/module_tools.h
@@ -0,0 +1,117 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef MODULE_TOOLS_H
+#define MODULE_TOOLS_H
+
+#include <tool/tool_interactive.h>
+#include <origin_viewitem.h>
+
+namespace KIGFX
+{
+ class VIEW;
+ class VIEW_CONTROLS;
+}
+class BOARD;
+class PCB_EDIT_FRAME;
+
+/**
+ * Class MODULE_TOOLS
+ *
+ * Module editor specific tools.
+ */
+class MODULE_TOOLS : public TOOL_INTERACTIVE
+{
+public:
+ MODULE_TOOLS();
+ ~MODULE_TOOLS();
+
+ /// @copydoc TOOL_INTERACTIVE::Reset()
+ void Reset( RESET_REASON aReason );
+
+ /// @copydoc TOOL_INTERACTIVE::Init()
+ bool Init();
+
+ /**
+ * Function PlacePad()
+ * Places a pad in module editor.
+ */
+ int PlacePad( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function EnumeratePads()
+ * Tool for quick pad enumeration.
+ */
+ int EnumeratePads( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function CopyItems()
+ *
+ * Copies selected items to the clipboard. Works only in "edit modules" mode.
+ */
+ int CopyItems( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function PastePad()
+ *
+ * Pastes items from the clipboard. Works only in "edit modules" mode.
+ */
+ int PasteItems( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function CreateArray
+ *
+ * Creates an array of objects using settings from a dialog
+ */
+ int CreateArray( TOOL_EVENT& aEvent );
+
+ /**
+ * Function ModuleTextOutlines()
+ *
+ * Toggles display mode for module texts (outline/filled).
+ */
+ int ModuleTextOutlines( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function ModuleEdgeOutlines()
+ *
+ * Toggles display mode for module edges (outline/filled).
+ */
+ int ModuleEdgeOutlines( const TOOL_EVENT& aEvent );
+
+ ///> Sets up handlers for various events.
+ void SetTransitions();
+
+private:
+ KIGFX::VIEW* m_view;
+ KIGFX::VIEW_CONTROLS* m_controls;
+ BOARD* m_board;
+ PCB_EDIT_FRAME* m_frame;
+
+ ///> Axis 0 marker
+ KIGFX::ORIGIN_VIEWITEM* m_axisOrigin;
+
+};
+
+#endif
diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp
new file mode 100644
index 0000000..15a0fc6
--- /dev/null
+++ b/pcbnew/tools/pcb_editor_control.cpp
@@ -0,0 +1,792 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <boost/bind.hpp>
+
+#include "pcb_editor_control.h"
+#include "common_actions.h"
+#include <tool/tool_manager.h>
+
+#include "selection_tool.h"
+#include "picker_tool.h"
+
+#include <painter.h>
+#include <project.h>
+#include <pcbnew_id.h>
+#include <wxPcbStruct.h>
+#include <class_board.h>
+#include <class_zone.h>
+#include <class_draw_panel_gal.h>
+#include <class_module.h>
+#include <class_mire.h>
+#include <ratsnest_data.h>
+#include <collectors.h>
+#include <zones_functions_for_undo_redo.h>
+
+#include <view/view_group.h>
+#include <view/view_controls.h>
+#include <origin_viewitem.h>
+
+#include <boost/bind.hpp>
+
+
+class ZONE_CONTEXT_MENU : public CONTEXT_MENU
+{
+public:
+ ZONE_CONTEXT_MENU()
+ {
+ SetIcon( add_zone_xpm );
+ SetUpdateHandler( boost::bind( &ZONE_CONTEXT_MENU::update, this ) );
+ Add( COMMON_ACTIONS::zoneFill );
+ Add( COMMON_ACTIONS::zoneFillAll );
+ Add( COMMON_ACTIONS::zoneUnfill );
+ Add( COMMON_ACTIONS::zoneUnfillAll );
+ Add( COMMON_ACTIONS::zoneMerge );
+ }
+
+private:
+ void update()
+ {
+ SELECTION_TOOL* selTool = getToolManager()->GetTool<SELECTION_TOOL>();
+
+ // lines like this make me really think about a better name for SELECTION_CONDITIONS class
+ bool mergeEnabled = ( SELECTION_CONDITIONS::MoreThan( 1 ) &&
+ /*SELECTION_CONDITIONS::OnlyType( PCB_ZONE_AREA_T ) &&*/
+ SELECTION_CONDITIONS::SameNet( true ) &&
+ SELECTION_CONDITIONS::SameLayer() )( selTool->GetSelection() );
+
+ Enable( getMenuId( COMMON_ACTIONS::zoneMerge ), mergeEnabled );
+ }
+};
+
+
+PCB_EDITOR_CONTROL::PCB_EDITOR_CONTROL() :
+ TOOL_INTERACTIVE( "pcbnew.EditorControl" ), m_frame( NULL ), m_zoneMenu( NULL )
+{
+ m_placeOrigin = new KIGFX::ORIGIN_VIEWITEM( KIGFX::COLOR4D( 0.8, 0.0, 0.0, 1.0 ),
+ KIGFX::ORIGIN_VIEWITEM::CIRCLE_CROSS );
+ m_probingSchToPcb = false;
+}
+
+
+PCB_EDITOR_CONTROL::~PCB_EDITOR_CONTROL()
+{
+ delete m_placeOrigin;
+ delete m_zoneMenu;
+}
+
+
+void PCB_EDITOR_CONTROL::Reset( RESET_REASON aReason )
+{
+ m_frame = getEditFrame<PCB_EDIT_FRAME>();
+
+ if( aReason == MODEL_RELOAD || aReason == GAL_SWITCH )
+ {
+ m_placeOrigin->SetPosition( getModel<BOARD>()->GetAuxOrigin() );
+ getView()->Remove( m_placeOrigin );
+ getView()->Add( m_placeOrigin );
+ }
+}
+
+
+bool PCB_EDITOR_CONTROL::Init()
+{
+ SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
+
+ if( selTool )
+ {
+ m_zoneMenu = new ZONE_CONTEXT_MENU;
+ m_zoneMenu->SetTool( this );
+ selTool->GetMenu().AddMenu( m_zoneMenu, _( "Zones" ), false,
+ SELECTION_CONDITIONS::OnlyType( PCB_ZONE_AREA_T ) );
+ }
+
+ return true;
+}
+
+
+// Track & via size control
+int PCB_EDITOR_CONTROL::TrackWidthInc( const TOOL_EVENT& aEvent )
+{
+ BOARD* board = getModel<BOARD>();
+ int widthIndex = board->GetDesignSettings().GetTrackWidthIndex() + 1;
+
+ if( widthIndex >= (int) board->GetDesignSettings().m_TrackWidthList.size() )
+ widthIndex = board->GetDesignSettings().m_TrackWidthList.size() - 1;
+
+ board->GetDesignSettings().SetTrackWidthIndex( widthIndex );
+ board->GetDesignSettings().UseCustomTrackViaSize( false );
+
+ wxUpdateUIEvent dummy;
+ m_frame->OnUpdateSelectTrackWidth( dummy );
+ m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged );
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::TrackWidthDec( const TOOL_EVENT& aEvent )
+{
+ BOARD* board = getModel<BOARD>();
+ int widthIndex = board->GetDesignSettings().GetTrackWidthIndex() - 1;
+
+ if( widthIndex < 0 )
+ widthIndex = 0;
+
+ board->GetDesignSettings().SetTrackWidthIndex( widthIndex );
+ board->GetDesignSettings().UseCustomTrackViaSize( false );
+
+ wxUpdateUIEvent dummy;
+ m_frame->OnUpdateSelectTrackWidth( dummy );
+ m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged );
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::ViaSizeInc( const TOOL_EVENT& aEvent )
+{
+ BOARD* board = getModel<BOARD>();
+ int sizeIndex = board->GetDesignSettings().GetViaSizeIndex() + 1;
+
+ if( sizeIndex >= (int) board->GetDesignSettings().m_ViasDimensionsList.size() )
+ sizeIndex = board->GetDesignSettings().m_ViasDimensionsList.size() - 1;
+
+ board->GetDesignSettings().SetViaSizeIndex( sizeIndex );
+ board->GetDesignSettings().UseCustomTrackViaSize( false );
+
+ wxUpdateUIEvent dummy;
+ m_frame->OnUpdateSelectViaSize( dummy );
+ m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged );
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::ViaSizeDec( const TOOL_EVENT& aEvent )
+{
+ BOARD* board = getModel<BOARD>();
+ int sizeIndex = board->GetDesignSettings().GetViaSizeIndex() - 1;
+
+ if( sizeIndex < 0 )
+ sizeIndex = 0;
+
+ board->GetDesignSettings().SetViaSizeIndex( sizeIndex );
+ board->GetDesignSettings().UseCustomTrackViaSize( false );
+
+ wxUpdateUIEvent dummy;
+ m_frame->OnUpdateSelectViaSize( dummy );
+ m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged );
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
+{
+ MODULE* module = NULL;
+ KIGFX::VIEW* view = getView();
+ KIGFX::VIEW_CONTROLS* controls = getViewControls();
+ BOARD* board = getModel<BOARD>();
+
+ // Add a VIEW_GROUP that serves as a preview for the new item
+ KIGFX::VIEW_GROUP preview( view );
+ view->Add( &preview );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ controls->ShowCursor( true );
+ controls->SetSnapping( true );
+
+ Activate();
+ m_frame->SetToolID( ID_PCB_MODULE_BUTT, wxCURSOR_HAND, _( "Add footprint" ) );
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ VECTOR2I cursorPos = controls->GetCursorPosition();
+
+ if( evt->IsCancel() || evt->IsActivate() )
+ {
+ if( module )
+ {
+ board->Delete( module ); // it was added by LoadModuleFromLibrary()
+ module = NULL;
+
+ preview.Clear();
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ controls->ShowCursor( true );
+ }
+ else
+ break;
+
+ if( evt->IsActivate() ) // now finish unconditionally
+ break;
+ }
+
+ else if( module && evt->Category() == TC_COMMAND )
+ {
+ if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
+ {
+ module->Rotate( module->GetPosition(), m_frame->GetRotationAngle() );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
+ {
+ module->Flip( module->GetPosition() );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ if( !module )
+ {
+ // Pick the module to be placed
+ module = m_frame->LoadModuleFromLibrary( wxEmptyString,
+ m_frame->Prj().PcbFootprintLibs(),
+ true, NULL );
+ if( module == NULL )
+ continue;
+
+ module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
+
+ // Add all the drawable parts to preview
+ preview.Add( module );
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Add, &preview, _1 ) );
+
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ else
+ {
+ // Place the selected module
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
+ view->Add( module );
+ module->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( module, UR_NEW );
+
+ // Remove from preview
+ preview.Remove( module );
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Remove, &preview, _1 ) );
+ module = NULL; // to indicate that there is no module that we currently modify
+ }
+
+ bool placing = ( module != NULL );
+
+ controls->SetAutoPan( placing );
+ controls->CaptureCursor( placing );
+ controls->ShowCursor( !placing );
+ }
+
+ else if( module && evt->IsMotion() )
+ {
+ module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ controls->ShowCursor( false );
+ controls->SetSnapping( false );
+ controls->SetAutoPan( false );
+ controls->CaptureCursor( false );
+ view->Remove( &preview );
+
+ m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::ToggleLockModule( const TOOL_EVENT& aEvent )
+{
+ SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
+ const SELECTION& selection = selTool->GetSelection();
+ bool clearSelection = selection.Empty();
+
+ if( clearSelection )
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionCursor, true );
+
+ for( int i = 0; i < selection.Size(); ++i )
+ {
+ if( selection.Item<BOARD_ITEM>( i )->Type() == PCB_MODULE_T )
+ {
+ MODULE* module = selection.Item<MODULE>( i );
+ module->SetLocked( !module->IsLocked() );
+ }
+ }
+
+ if( clearSelection )
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
+{
+ KIGFX::VIEW* view = getView();
+ KIGFX::VIEW_CONTROLS* controls = getViewControls();
+ BOARD* board = getModel<BOARD>();
+ PCB_TARGET* target = new PCB_TARGET( board );
+
+ // Init the new item attributes
+ target->SetLayer( Edge_Cuts );
+ target->SetWidth( board->GetDesignSettings().m_EdgeSegmentWidth );
+ target->SetSize( Millimeter2iu( 5 ) );
+ VECTOR2I cursorPos = controls->GetCursorPosition();
+ target->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
+
+ // Add a VIEW_GROUP that serves as a preview for the new item
+ KIGFX::VIEW_GROUP preview( view );
+ preview.Add( target );
+ view->Add( &preview );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ controls->SetSnapping( true );
+
+ Activate();
+ m_frame->SetToolID( ID_PCB_MIRE_BUTT, wxCURSOR_PENCIL, _( "Add layer alignment target" ) );
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ cursorPos = controls->GetCursorPosition();
+
+ if( evt->IsCancel() || evt->IsActivate() )
+ break;
+
+ else if( evt->IsAction( &COMMON_ACTIONS::incWidth ) )
+ {
+ target->SetWidth( target->GetWidth() + WIDTH_STEP );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::decWidth ) )
+ {
+ int width = target->GetWidth();
+
+ if( width > WIDTH_STEP )
+ {
+ target->SetWidth( width - WIDTH_STEP );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ else if( evt->IsClick( BUT_LEFT ) )
+ {
+ assert( target->GetSize() > 0 );
+ assert( target->GetWidth() > 0 );
+
+ view->Add( target );
+ board->Add( target );
+ target->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( target, UR_NEW );
+
+ preview.Remove( target );
+
+ // Create next PCB_TARGET
+ target = new PCB_TARGET( *target );
+ preview.Add( target );
+ }
+
+ else if( evt->IsMotion() )
+ {
+ target->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
+ preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+ }
+
+ delete target;
+
+ controls->SetSnapping( false );
+ view->Remove( &preview );
+
+ m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+
+ return 0;
+}
+
+
+// Zone actions
+int PCB_EDITOR_CONTROL::ZoneFill( const TOOL_EVENT& aEvent )
+{
+ SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
+ const SELECTION& selection = selTool->GetSelection();
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+
+ for( int i = 0; i < selection.Size(); ++i )
+ {
+ assert( selection.Item<BOARD_ITEM>( i )->Type() == PCB_ZONE_AREA_T );
+
+ ZONE_CONTAINER* zone = selection.Item<ZONE_CONTAINER>( i );
+ m_frame->Fill_Zone( zone );
+ zone->SetIsFilled( true );
+ ratsnest->Update( zone );
+ zone->ViewUpdate();
+ }
+
+ ratsnest->Recalculate();
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::ZoneFillAll( const TOOL_EVENT& aEvent )
+{
+ BOARD* board = getModel<BOARD>();
+ RN_DATA* ratsnest = board->GetRatsnest();
+
+ for( int i = 0; i < board->GetAreaCount(); ++i )
+ {
+ ZONE_CONTAINER* zone = board->GetArea( i );
+ m_frame->Fill_Zone( zone );
+ zone->SetIsFilled( true );
+ ratsnest->Update( zone );
+ zone->ViewUpdate();
+ }
+
+ ratsnest->Recalculate();
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::ZoneUnfill( const TOOL_EVENT& aEvent )
+{
+ SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
+ const SELECTION& selection = selTool->GetSelection();
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+
+ for( int i = 0; i < selection.Size(); ++i )
+ {
+ assert( selection.Item<BOARD_ITEM>( i )->Type() == PCB_ZONE_AREA_T );
+
+ ZONE_CONTAINER* zone = selection.Item<ZONE_CONTAINER>( i );
+ zone->SetIsFilled( false );
+ zone->ClearFilledPolysList();
+ ratsnest->Update( zone );
+ zone->ViewUpdate();
+ }
+
+ ratsnest->Recalculate();
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::ZoneUnfillAll( const TOOL_EVENT& aEvent )
+{
+ BOARD* board = getModel<BOARD>();
+ RN_DATA* ratsnest = board->GetRatsnest();
+
+ for( int i = 0; i < board->GetAreaCount(); ++i )
+ {
+ ZONE_CONTAINER* zone = board->GetArea( i );
+ zone->SetIsFilled( false );
+ zone->ClearFilledPolysList();
+ ratsnest->Update( zone );
+ zone->ViewUpdate();
+ }
+
+ ratsnest->Recalculate();
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent )
+{
+ SELECTION selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
+ BOARD* board = getModel<BOARD>();
+ RN_DATA* ratsnest = board->GetRatsnest();
+ KIGFX::VIEW* view = getView();
+
+ if( selection.Size() < 2 )
+ return 0;
+
+ PICKED_ITEMS_LIST changes;
+ int netcode = -1;
+
+ // Loop through all combinations
+ for( int ia1 = 0; ia1 < selection.Size() - 1; ++ia1 )
+ {
+ ZONE_CONTAINER* curr_area = dynamic_cast<ZONE_CONTAINER*>( selection.Item<EDA_ITEM>( ia1 ) );
+
+ if( !curr_area )
+ continue;
+
+ netcode = curr_area->GetNetCode();
+
+ EDA_RECT b1 = curr_area->Outline()->GetBoundingBox();
+ bool mod_ia1 = false;
+
+ for( int ia2 = selection.Size() - 1; ia2 > ia1; --ia2 )
+ {
+ ZONE_CONTAINER* area2 = dynamic_cast<ZONE_CONTAINER*>( selection.Item<EDA_ITEM>( ia2 ) );
+
+ if( !area2 )
+ continue;
+
+ if( area2->GetNetCode() != netcode )
+ continue;
+
+ if( curr_area->GetPriority() != area2->GetPriority() )
+ continue;
+
+ if( curr_area->GetIsKeepout() != area2->GetIsKeepout() )
+ continue;
+
+ if( curr_area->GetLayer() != area2->GetLayer() )
+ continue;
+
+ EDA_RECT b2 = area2->Outline()->GetBoundingBox();
+
+ if( b1.Intersects( b2 ) )
+ {
+ EDA_ITEM* backup = curr_area->Clone();
+ bool ret = board->TestAreaIntersection( curr_area, area2 );
+
+ if( ret && board->CombineAreas( &changes, curr_area, area2 ) )
+ {
+ mod_ia1 = true;
+ selection.items.RemovePicker( ia2 );
+
+ ITEM_PICKER picker( curr_area, UR_CHANGED );
+ picker.SetLink( backup );
+ changes.PushItem( picker );
+ }
+ else
+ {
+ delete backup;
+ }
+ }
+ }
+
+ if( mod_ia1 )
+ --ia1; // if modified, we need to check it again
+ }
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ m_frame->SaveCopyInUndoList( changes, UR_UNSPECIFIED );
+
+ for( unsigned i = 0; i < changes.GetCount(); ++i )
+ {
+ ITEM_PICKER picker = changes.GetItemWrapper( i );
+ BOARD_ITEM* item = static_cast<BOARD_ITEM*>( picker.GetItem() );
+
+ if( picker.GetStatus() == UR_DELETED )
+ {
+ view->Remove( item );
+ ratsnest->Remove( item );
+ }
+ else if( picker.GetStatus() == UR_CHANGED )
+ {
+ item->ViewUpdate( KIGFX::VIEW_ITEM::ALL );
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, item );
+ }
+ }
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::CrossProbePcbToSch( const TOOL_EVENT& aEvent )
+{
+ if( m_probingSchToPcb )
+ {
+ m_probingSchToPcb = false;
+ return 0;
+ }
+
+ SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
+ const SELECTION& selection = selTool->GetSelection();
+
+ if( selection.Size() == 1 )
+ m_frame->SendMessageToEESCHEMA( selection.Item<BOARD_ITEM>( 0 ) );
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::CrossProbeSchToPcb( const TOOL_EVENT& aEvent )
+{
+ BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
+
+ if( item )
+ {
+ m_probingSchToPcb = true;
+ getView()->SetCenter( VECTOR2D( item->GetPosition() ) );
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ // If it is a pad and the net highlighting tool is enabled, highlight the net
+ if( item->Type() == PCB_PAD_T && m_frame->GetToolId() == ID_PCB_HIGHLIGHT_BUTT )
+ {
+ int net = static_cast<D_PAD*>( item )->GetNetCode();
+ m_toolMgr->RunAction( COMMON_ACTIONS::highlightNet, false, net );
+ }
+ else
+ // Otherwise simply select the corresponding item
+ {
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, item );
+ }
+ }
+
+ return 0;
+}
+
+
+static bool setDrillOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
+ KIGFX::ORIGIN_VIEWITEM* aItem, const VECTOR2D& aPosition )
+{
+ aFrame->SetAuxOrigin( wxPoint( aPosition.x, aPosition.y ) );
+ aItem->SetPosition( aPosition );
+ aView->MarkDirty();
+
+ return true;
+}
+
+
+int PCB_EDITOR_CONTROL::DrillOrigin( const TOOL_EVENT& aEvent )
+{
+ Activate();
+
+ PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
+ assert( picker );
+
+ m_frame->SetToolID( ID_PCB_PLACE_OFFSET_COORD_BUTT, wxCURSOR_PENCIL, _( "Adjust zero" ) );
+ picker->SetClickHandler( boost::bind( setDrillOrigin, getView(), m_frame, m_placeOrigin, _1 ) );
+ picker->Activate();
+ Wait();
+
+ return 0;
+}
+
+/**
+ * Function highlightNet()
+ * Looks for a BOARD_CONNECTED_ITEM in a given spot, and if one is found - it enables
+ * highlight for its net.
+ * @param aPoint is the point where an item is expected (world coordinates).
+ */
+static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
+{
+ KIGFX::RENDER_SETTINGS* render = aToolMgr->GetView()->GetPainter()->GetSettings();
+ GENERAL_COLLECTORS_GUIDE guide = static_cast<PCB_BASE_FRAME*>( aToolMgr->GetEditFrame() )->GetCollectorsGuide();
+ BOARD* board = static_cast<BOARD*>( aToolMgr->GetModel() );
+ GENERAL_COLLECTOR collector;
+ int net = -1;
+
+ // Find a connected item for which we are going to highlight a net
+ collector.Collect( board, GENERAL_COLLECTOR::PadsTracksOrZones,
+ wxPoint( aPosition.x, aPosition.y ), guide );
+ bool enableHighlight = ( collector.GetCount() > 0 );
+
+ // Obtain net code for the clicked item
+ if( enableHighlight )
+ net = static_cast<BOARD_CONNECTED_ITEM*>( collector[0] )->GetNetCode();
+
+ // Toggle highlight when the same net was picked
+ if( net > 0 && net == render->GetHighlightNetCode() )
+ enableHighlight = !render->IsHighlightEnabled();
+
+ if( enableHighlight != render->IsHighlightEnabled() || net != render->GetHighlightNetCode() )
+ {
+ render->SetHighlight( enableHighlight, net );
+ aToolMgr->GetView()->UpdateAllLayersColor();
+ }
+
+ return true;
+}
+
+
+int PCB_EDITOR_CONTROL::HighlightNet( const TOOL_EVENT& aEvent )
+{
+ int netcode = aEvent.Parameter<long>();
+
+ if( netcode > 0 )
+ {
+ KIGFX::RENDER_SETTINGS* render = m_toolMgr->GetView()->GetPainter()->GetSettings();
+ render->SetHighlight( true, netcode );
+ m_toolMgr->GetView()->UpdateAllLayersColor();
+ }
+ else
+ {
+ // No net code specified, pick the net code belonging to the item under the cursor
+ highlightNet( m_toolMgr, getView()->ToWorld( getViewControls()->GetMousePosition() ) );
+ }
+
+ return 0;
+}
+
+
+int PCB_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent )
+{
+ Activate();
+
+ PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
+ assert( picker );
+
+ m_frame->SetToolID( ID_PCB_HIGHLIGHT_BUTT, wxCURSOR_PENCIL, _( "Highlight net" ) );
+ picker->SetClickHandler( boost::bind( highlightNet, m_toolMgr, _1 ) );
+ picker->SetSnapping( false );
+ picker->Activate();
+ Wait();
+
+ return 0;
+}
+
+
+void PCB_EDITOR_CONTROL::SetTransitions()
+{
+ // Track & via size control
+ Go( &PCB_EDITOR_CONTROL::TrackWidthInc, COMMON_ACTIONS::trackWidthInc.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::TrackWidthDec, COMMON_ACTIONS::trackWidthDec.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::ViaSizeInc, COMMON_ACTIONS::viaSizeInc.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::ViaSizeDec, COMMON_ACTIONS::viaSizeDec.MakeEvent() );
+
+ // Zone actions
+ Go( &PCB_EDITOR_CONTROL::ZoneFill, COMMON_ACTIONS::zoneFill.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::ZoneFillAll, COMMON_ACTIONS::zoneFillAll.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::ZoneUnfill, COMMON_ACTIONS::zoneUnfill.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::ZoneUnfillAll, COMMON_ACTIONS::zoneUnfillAll.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::ZoneMerge, COMMON_ACTIONS::zoneMerge.MakeEvent() );
+
+ // Placing tools
+ Go( &PCB_EDITOR_CONTROL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() );
+
+ // Other
+ Go( &PCB_EDITOR_CONTROL::ToggleLockModule, COMMON_ACTIONS::toggleLockModule.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, SELECTION_TOOL::SelectedEvent );
+ Go( &PCB_EDITOR_CONTROL::CrossProbeSchToPcb, COMMON_ACTIONS::crossProbeSchToPcb.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::DrillOrigin, COMMON_ACTIONS::drillOrigin.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::HighlightNet, COMMON_ACTIONS::highlightNet.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::HighlightNetCursor, COMMON_ACTIONS::highlightNetCursor.MakeEvent() );
+}
+
+
+const int PCB_EDITOR_CONTROL::WIDTH_STEP = 100000;
diff --git a/pcbnew/tools/pcb_editor_control.h b/pcbnew/tools/pcb_editor_control.h
new file mode 100644
index 0000000..51de402
--- /dev/null
+++ b/pcbnew/tools/pcb_editor_control.h
@@ -0,0 +1,116 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef PCB_EDITOR_CONTROL_H
+#define PCB_EDITOR_CONTROL_H
+
+#include <tool/tool_interactive.h>
+
+namespace KIGFX {
+ class ORIGIN_VIEWITEM;
+}
+
+class PCB_EDIT_FRAME;
+class ZONE_CONTEXT_MENU;
+
+/**
+ * Class PCB_EDITOR_CONTROL
+ *
+ * Handles actions specific to the board editor in pcbnew.
+ */
+class PCB_EDITOR_CONTROL : public TOOL_INTERACTIVE
+{
+public:
+ PCB_EDITOR_CONTROL();
+ ~PCB_EDITOR_CONTROL();
+
+ /// @copydoc TOOL_INTERACTIVE::Reset()
+ void Reset( RESET_REASON aReason );
+
+ /// @copydoc TOOL_INTERACTIVE::Init()
+ bool Init();
+
+ // Track & via size control
+ int TrackWidthInc( const TOOL_EVENT& aEvent );
+ int TrackWidthDec( const TOOL_EVENT& aEvent );
+ int ViaSizeInc( const TOOL_EVENT& aEvent );
+ int ViaSizeDec( const TOOL_EVENT& aEvent );
+
+ // Zone actions
+ int ZoneFill( const TOOL_EVENT& aEvent );
+ int ZoneFillAll( const TOOL_EVENT& aEvent );
+ int ZoneUnfill( const TOOL_EVENT& aEvent );
+ int ZoneUnfillAll( const TOOL_EVENT& aEvent );
+ int ZoneMerge( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function PlaceTarget()
+ * Allows user to place a layer alignment target.
+ */
+ int PlaceTarget( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function PlaceModule()
+ * Displays a dialog to select a module to be added and allows the user to set its position.
+ */
+ int PlaceModule( const TOOL_EVENT& aEvent );
+
+ ///> (Un)locks module.
+ int ToggleLockModule( const TOOL_EVENT& aEvent );
+
+ ///> Notifies eeschema about the selected item.
+ int CrossProbePcbToSch( const TOOL_EVENT& aEvent );
+
+ ///> Reacts to selection change in eeschema.
+ int CrossProbeSchToPcb( const TOOL_EVENT& aEvent );
+
+ ///> Places the origin point for drill and pick-and-place files.
+ int DrillOrigin( const TOOL_EVENT& aEvent );
+
+ ///> Highlights net belonging to the item under the cursor.
+ int HighlightNet( const TOOL_EVENT& aEvent );
+
+ ///> Launches a tool to pick the item whose net is going to be highlighted.
+ int HighlightNetCursor( const TOOL_EVENT& aEvent );
+
+ ///> Sets up handlers for various events.
+ void SetTransitions();
+
+private:
+ ///> Pointer to the currently used edit frame.
+ PCB_EDIT_FRAME* m_frame;
+
+ ///> Place & drill origin marker.
+ KIGFX::ORIGIN_VIEWITEM* m_placeOrigin;
+
+ ///> Flag to ignore a single crossprobe message from eeschema.
+ bool m_probingSchToPcb;
+
+ // How does line width change after one -/+ key press.
+ static const int WIDTH_STEP;
+
+ ZONE_CONTEXT_MENU* m_zoneMenu;
+};
+
+#endif
diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp
new file mode 100644
index 0000000..1afe10f
--- /dev/null
+++ b/pcbnew/tools/pcbnew_control.cpp
@@ -0,0 +1,1014 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014-2016 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "pcbnew_control.h"
+#include "common_actions.h"
+#include "selection_tool.h"
+#include "picker_tool.h"
+#include "grid_helper.h"
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_zone.h>
+#include <class_pcb_screen.h>
+
+#include <confirm.h>
+#include <hotkeys_basic.h>
+#include <io_mgr.h>
+
+#include <pcbnew_id.h>
+#include <wxPcbStruct.h>
+#include <pcb_draw_panel_gal.h>
+#include <ratsnest_data.h>
+#include <tool/tool_manager.h>
+#include <gal/graphics_abstraction_layer.h>
+#include <view/view_controls.h>
+#include <pcb_painter.h>
+#include <origin_viewitem.h>
+
+#include <boost/bind.hpp>
+
+
+// files.cpp
+extern bool AskLoadBoardFileName( wxWindow* aParent, int* aCtl, wxString* aFileName,
+ bool aKicadFilesOnly = false );
+extern IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl );
+
+
+PCBNEW_CONTROL::PCBNEW_CONTROL() :
+ TOOL_INTERACTIVE( "pcbnew.Control" ), m_frame( NULL )
+{
+ m_gridOrigin = new KIGFX::ORIGIN_VIEWITEM();
+}
+
+
+PCBNEW_CONTROL::~PCBNEW_CONTROL()
+{
+ delete m_gridOrigin;
+}
+
+
+void PCBNEW_CONTROL::Reset( RESET_REASON aReason )
+{
+ m_frame = getEditFrame<PCB_BASE_FRAME>();
+
+ if( aReason == MODEL_RELOAD || aReason == GAL_SWITCH )
+ {
+ m_gridOrigin->SetPosition( getModel<BOARD>()->GetGridOrigin() );
+ getView()->Remove( m_gridOrigin );
+ getView()->Add( m_gridOrigin );
+ }
+}
+
+
+int PCBNEW_CONTROL::ZoomInOut( const TOOL_EVENT& aEvent )
+{
+ KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView();
+ KIGFX::VIEW_CONTROLS* ctls = getViewControls();
+ double zoomScale = 1.0;
+
+ if( aEvent.IsAction( &COMMON_ACTIONS::zoomIn ) )
+ zoomScale = 1.3;
+ else if( aEvent.IsAction( &COMMON_ACTIONS::zoomOut ) )
+ zoomScale = 0.7;
+
+ view->SetScale( view->GetScale() * zoomScale, getViewControls()->GetCursorPosition() );
+
+ if( ctls->IsCursorWarpingEnabled() )
+ ctls->CenterOnCursor();
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::ZoomInOutCenter( const TOOL_EVENT& aEvent )
+{
+ KIGFX::VIEW* view = getView();
+ double zoomScale = 1.0;
+
+ if( aEvent.IsAction( &COMMON_ACTIONS::zoomInCenter ) )
+ zoomScale = 1.3;
+ else if( aEvent.IsAction( &COMMON_ACTIONS::zoomOutCenter ) )
+ zoomScale = 0.7;
+
+ view->SetScale( view->GetScale() * zoomScale );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::ZoomCenter( const TOOL_EVENT& aEvent )
+{
+ KIGFX::VIEW_CONTROLS* ctls = getViewControls();
+
+ if( ctls->IsCursorWarpingEnabled() )
+ ctls->CenterOnCursor();
+ else
+ getView()->SetCenter( getViewControls()->GetCursorPosition() );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::ZoomFitScreen( const TOOL_EVENT& aEvent )
+{
+ KIGFX::VIEW* view = getView();
+ EDA_DRAW_PANEL_GAL* galCanvas = m_frame->GetGalCanvas();
+ BOARD* board = getModel<BOARD>();
+ board->ComputeBoundingBox();
+
+ BOX2I boardBBox = board->ViewBBox();
+ VECTOR2D scrollbarSize = VECTOR2D( galCanvas->GetSize() - galCanvas->GetClientSize() );
+ VECTOR2D screenSize = view->ToWorld( galCanvas->GetClientSize(), false );
+
+ if( boardBBox.GetWidth() == 0 || boardBBox.GetHeight() == 0 )
+ {
+ // Empty view
+ view->SetScale( 17.0 ); // works fine for the standard worksheet frame
+
+ view->SetCenter( screenSize / 2.0 );
+ }
+ else
+ {
+ VECTOR2D vsize = boardBBox.GetSize();
+ double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ),
+ fabs( vsize.y / screenSize.y ) );
+
+ view->SetScale( scale );
+ view->SetCenter( boardBBox.Centre() );
+ }
+
+
+ // Take scrollbars into account
+ VECTOR2D worldScrollbarSize = view->ToWorld( scrollbarSize, false );
+ view->SetCenter( view->GetCenter() + worldScrollbarSize / 2.0 );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::ZoomPreset( const TOOL_EVENT& aEvent )
+{
+ unsigned int idx = aEvent.Parameter<long>();
+ std::vector<double>& zoomList = m_frame->GetScreen()->m_ZoomList;
+ KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView();
+ KIGFX::GAL* gal = m_frame->GetGalCanvas()->GetGAL();
+
+ m_frame->SetPresetZoom( idx );
+
+ if( idx == 0 ) // Zoom Auto
+ {
+ return ZoomFitScreen( aEvent );
+ }
+ else if( idx >= zoomList.size() )
+ {
+ assert( false );
+ return 0;
+ }
+
+ double selectedZoom = zoomList[idx];
+ double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor();
+ view->SetScale( 1.0 / ( zoomFactor * selectedZoom ) );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::TrackDisplayMode( const TOOL_EVENT& aEvent )
+{
+ KIGFX::PCB_PAINTER* painter =
+ static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetGalCanvas()->GetView()->GetPainter() );
+ KIGFX::PCB_RENDER_SETTINGS* settings =
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
+
+ // Apply new display options to the GAL canvas
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)m_frame->GetDisplayOptions();
+ displ_opts->m_DisplayPcbTrackFill = !displ_opts->m_DisplayPcbTrackFill;
+ settings->LoadDisplayOptions( displ_opts );
+
+ for( TRACK* track = getModel<BOARD>()->m_Track; track; track = track->Next() )
+ {
+ if( track->Type() == PCB_TRACE_T )
+ track->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ m_frame->GetGalCanvas()->Refresh();
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::PadDisplayMode( const TOOL_EVENT& aEvent )
+{
+ KIGFX::PCB_PAINTER* painter =
+ static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetGalCanvas()->GetView()->GetPainter() );
+ KIGFX::PCB_RENDER_SETTINGS* settings =
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)m_frame->GetDisplayOptions();
+
+ // Apply new display options to the GAL canvas
+ displ_opts->m_DisplayPadFill = !displ_opts->m_DisplayPadFill;
+ settings->LoadDisplayOptions( displ_opts );
+
+ for( MODULE* module = getModel<BOARD>()->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ pad->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ m_frame->GetGalCanvas()->Refresh();
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::ViaDisplayMode( const TOOL_EVENT& aEvent )
+{
+ KIGFX::PCB_PAINTER* painter =
+ static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetGalCanvas()->GetView()->GetPainter() );
+ KIGFX::PCB_RENDER_SETTINGS* settings =
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)m_frame->GetDisplayOptions();
+
+ // Apply new display options to the GAL canvas
+ displ_opts->m_DisplayViaFill = !displ_opts->m_DisplayViaFill;
+ settings->LoadDisplayOptions( displ_opts );
+
+ for( TRACK* track = getModel<BOARD>()->m_Track; track; track = track->Next() )
+ {
+ if( track->Type() == PCB_VIA_T )
+ track->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ m_frame->GetGalCanvas()->Refresh();
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::ZoneDisplayMode( const TOOL_EVENT& aEvent )
+{
+ KIGFX::PCB_PAINTER* painter =
+ static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetGalCanvas()->GetView()->GetPainter() );
+ KIGFX::PCB_RENDER_SETTINGS* settings =
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)m_frame->GetDisplayOptions();
+
+ // Apply new display options to the GAL canvas
+ if( aEvent.IsAction( &COMMON_ACTIONS::zoneDisplayEnable ) )
+ displ_opts->m_DisplayZonesMode = 0;
+ else if( aEvent.IsAction( &COMMON_ACTIONS::zoneDisplayDisable ) )
+ displ_opts->m_DisplayZonesMode = 1;
+ else if( aEvent.IsAction( &COMMON_ACTIONS::zoneDisplayOutlines ) )
+ displ_opts->m_DisplayZonesMode = 2;
+ else
+ assert( false );
+
+ settings->LoadDisplayOptions( displ_opts );
+
+ BOARD* board = getModel<BOARD>();
+ for( int i = 0; i < board->GetAreaCount(); ++i )
+ board->GetArea( i )->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+
+ m_frame->GetGalCanvas()->Refresh();
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::HighContrastMode( const TOOL_EVENT& aEvent )
+{
+ KIGFX::PCB_PAINTER* painter =
+ static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetGalCanvas()->GetView()->GetPainter() );
+ KIGFX::PCB_RENDER_SETTINGS* settings =
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*> ( painter->GetSettings() );
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)m_frame->GetDisplayOptions();
+
+ displ_opts->m_ContrastModeDisplay = !displ_opts->m_ContrastModeDisplay;
+ settings->LoadDisplayOptions( displ_opts );
+ m_frame->GetGalCanvas()->SetHighContrastLayer( m_frame->GetActiveLayer() );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::HighContrastInc( const TOOL_EVENT& aEvent )
+{
+ std::cout << __PRETTY_FUNCTION__ << std::endl;
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::HighContrastDec( const TOOL_EVENT& aEvent )
+{
+ std::cout << __PRETTY_FUNCTION__ << std::endl;
+
+ return 0;
+}
+
+
+// Layer control
+int PCBNEW_CONTROL::LayerSwitch( const TOOL_EVENT& aEvent )
+{
+ m_frame->SwitchLayer( NULL, (LAYER_ID) aEvent.Parameter<long>() );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::LayerNext( const TOOL_EVENT& aEvent )
+{
+ PCB_BASE_FRAME* editFrame = m_frame;
+ LAYER_NUM layer = editFrame->GetActiveLayer();
+
+ if( layer < F_Cu || layer > B_Cu )
+ return 0;
+
+ int layerCount = getModel<BOARD>()->GetCopperLayerCount();
+
+ if( layer == layerCount - 2 || layerCount < 2 )
+ layer = B_Cu;
+ else if( layer == B_Cu )
+ layer = F_Cu;
+ else
+ ++layer;
+
+ assert( IsCopperLayer( layer ) );
+ editFrame->SwitchLayer( NULL, ToLAYER_ID( layer ) );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::LayerPrev( const TOOL_EVENT& aEvent )
+{
+ PCB_BASE_FRAME* editFrame = m_frame;
+ LAYER_NUM layer = editFrame->GetActiveLayer();
+
+ if( layer < F_Cu || layer > B_Cu )
+ return 0;
+
+ int layerCount = getModel<BOARD>()->GetCopperLayerCount();
+
+ if( layer == F_Cu || layerCount < 2 )
+ layer = B_Cu;
+ else if( layer == B_Cu )
+ layer = layerCount - 2;
+ else
+ --layer;
+
+ assert( IsCopperLayer( layer ) );
+ editFrame->SwitchLayer( NULL, ToLAYER_ID( layer ) );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::LayerToggle( const TOOL_EVENT& aEvent )
+{
+ LAYER_NUM currentLayer = m_frame->GetActiveLayer();
+ PCB_SCREEN* screen = m_frame->GetScreen();
+
+ if( currentLayer == screen->m_Route_Layer_TOP )
+ m_frame->SwitchLayer( NULL, screen->m_Route_Layer_BOTTOM );
+ else
+ m_frame->SwitchLayer( NULL, screen->m_Route_Layer_TOP );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::LayerAlphaInc( const TOOL_EVENT& aEvent )
+{
+ KIGFX::PCB_PAINTER* painter =
+ static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetGalCanvas()->GetView()->GetPainter() );
+ KIGFX::PCB_RENDER_SETTINGS* settings =
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*> ( painter->GetSettings() );
+
+ LAYER_NUM currentLayer = m_frame->GetActiveLayer();
+ KIGFX::COLOR4D currentColor = settings->GetLayerColor( currentLayer );
+
+ if( currentColor.a <= 0.95 )
+ {
+ currentColor.a += 0.05;
+ settings->SetLayerColor( currentLayer, currentColor );
+ m_frame->GetGalCanvas()->GetView()->UpdateLayerColor( currentLayer );
+ }
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::LayerAlphaDec( const TOOL_EVENT& aEvent )
+{
+ KIGFX::PCB_PAINTER* painter =
+ static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetGalCanvas()->GetView()->GetPainter() );
+ KIGFX::PCB_RENDER_SETTINGS* settings =
+ static_cast<KIGFX::PCB_RENDER_SETTINGS*> ( painter->GetSettings() );
+
+ LAYER_NUM currentLayer = m_frame->GetActiveLayer();
+ KIGFX::COLOR4D currentColor = settings->GetLayerColor( currentLayer );
+
+ if( currentColor.a >= 0.05 )
+ {
+ currentColor.a -= 0.05;
+ settings->SetLayerColor( currentLayer, currentColor );
+ m_frame->GetGalCanvas()->GetView()->UpdateLayerColor( currentLayer );
+ }
+
+ return 0;
+}
+
+
+// Cursor control
+int PCBNEW_CONTROL::CursorControl( const TOOL_EVENT& aEvent )
+{
+ long type = aEvent.Parameter<long>();
+ bool fastMove = type & COMMON_ACTIONS::CURSOR_FAST_MOVE;
+ type &= ~COMMON_ACTIONS::CURSOR_FAST_MOVE;
+
+ GRID_HELPER gridHelper( m_frame );
+ VECTOR2D cursor = getViewControls()->GetCursorPosition();
+ VECTOR2I gridSize = gridHelper.GetGrid();
+ VECTOR2D newCursor = gridHelper.Align( cursor );
+
+ if( fastMove )
+ gridSize = gridSize * 10;
+
+ switch( type )
+ {
+ case COMMON_ACTIONS::CURSOR_UP:
+ newCursor -= VECTOR2D( 0, gridSize.y );
+ break;
+
+ case COMMON_ACTIONS::CURSOR_DOWN:
+ newCursor += VECTOR2D( 0, gridSize.y );
+ break;
+
+ case COMMON_ACTIONS::CURSOR_LEFT:
+ newCursor -= VECTOR2D( gridSize.x, 0 );
+ break;
+
+ case COMMON_ACTIONS::CURSOR_RIGHT:
+ newCursor += VECTOR2D( gridSize.x, 0 );
+ break;
+
+ case COMMON_ACTIONS::CURSOR_CLICK: // fall through
+ case COMMON_ACTIONS::CURSOR_DBL_CLICK:
+ {
+ TOOL_ACTIONS action;
+ int modifiers = 0;
+
+ modifiers |= wxGetKeyState( WXK_SHIFT ) ? MD_SHIFT : 0;
+ modifiers |= wxGetKeyState( WXK_CONTROL ) ? MD_CTRL : 0;
+ modifiers |= wxGetKeyState( WXK_ALT ) ? MD_ALT : 0;
+
+ if( type == COMMON_ACTIONS::CURSOR_CLICK )
+ action = TA_MOUSE_CLICK;
+ else if( type == COMMON_ACTIONS::CURSOR_DBL_CLICK )
+ action = TA_MOUSE_DBLCLICK;
+ else
+ assert( false );
+
+ TOOL_EVENT evt( TC_MOUSE, action, BUT_LEFT | modifiers );
+ evt.SetMousePosition( getViewControls()->GetCursorPosition() );
+ m_toolMgr->ProcessEvent( evt );
+
+ return 0;
+ }
+ break;
+ }
+
+ // Handler cursor movement
+ KIGFX::VIEW* view = getView();
+ newCursor = view->ToScreen( newCursor );
+ newCursor.x = KiROUND( newCursor.x );
+ newCursor.y = KiROUND( newCursor.y );
+
+ // Pan the screen if required
+ const VECTOR2I& screenSize = view->GetGAL()->GetScreenPixelSize();
+ BOX2I screenBox( VECTOR2I( 0, 0 ), screenSize );
+
+ if( !screenBox.Contains( newCursor ) )
+ {
+ VECTOR2D delta( 0, 0 );
+
+ if( newCursor.x < screenBox.GetLeft() )
+ {
+ delta.x = newCursor.x - screenBox.GetLeft();
+ newCursor.x = screenBox.GetLeft();
+ }
+ else if( newCursor.x > screenBox.GetRight() )
+ {
+ delta.x = newCursor.x - screenBox.GetRight();
+ // -1 is to keep the cursor within the drawing area,
+ // so the cursor coordinates are still updated
+ newCursor.x = screenBox.GetRight() - 1;
+ }
+
+ if( newCursor.y < screenBox.GetTop() )
+ {
+ delta.y = newCursor.y - screenBox.GetTop();
+ newCursor.y = screenBox.GetTop();
+ }
+ else if( newCursor.y > screenBox.GetBottom() )
+ {
+ delta.y = newCursor.y - screenBox.GetBottom();
+ // -1 is to keep the cursor within the drawing area,
+ // so the cursor coordinates are still updated
+ newCursor.y = screenBox.GetBottom() - 1;
+ }
+
+ view->SetCenter( view->GetCenter() + view->ToWorld( delta, false ) );
+ }
+
+ m_frame->GetGalCanvas()->WarpPointer( newCursor.x, newCursor.y );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::PanControl( const TOOL_EVENT& aEvent )
+{
+ long type = aEvent.Parameter<long>();
+ KIGFX::VIEW* view = getView();
+ GRID_HELPER gridHelper( m_frame );
+ VECTOR2D center = view->GetCenter();
+ VECTOR2I gridSize = gridHelper.GetGrid() * 10;
+
+ switch( type )
+ {
+ case COMMON_ACTIONS::CURSOR_UP:
+ center -= VECTOR2D( 0, gridSize.y );
+ break;
+
+ case COMMON_ACTIONS::CURSOR_DOWN:
+ center += VECTOR2D( 0, gridSize.y );
+ break;
+
+ case COMMON_ACTIONS::CURSOR_LEFT:
+ center -= VECTOR2D( gridSize.x, 0 );
+ break;
+
+ case COMMON_ACTIONS::CURSOR_RIGHT:
+ center += VECTOR2D( gridSize.x, 0 );
+ break;
+
+ default:
+ assert( false );
+ break;
+ }
+
+ view->SetCenter( center );
+
+ return 0;
+}
+
+
+// Grid control
+int PCBNEW_CONTROL::GridFast1( const TOOL_EVENT& aEvent )
+{
+ m_frame->SetFastGrid1();
+ updateGrid();
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::GridFast2( const TOOL_EVENT& aEvent )
+{
+ m_frame->SetFastGrid2();
+ updateGrid();
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::GridNext( const TOOL_EVENT& aEvent )
+{
+ m_frame->SetNextGrid();
+ updateGrid();
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::GridPrev( const TOOL_EVENT& aEvent )
+{
+ m_frame->SetPrevGrid();
+ updateGrid();
+
+ return 0;
+}
+
+
+static bool setOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
+ KIGFX::ORIGIN_VIEWITEM* aItem, const VECTOR2D& aPoint )
+{
+ aFrame->SetGridOrigin( wxPoint( aPoint.x, aPoint.y ) );
+ aView->GetGAL()->SetGridOrigin( aPoint );
+ aItem->SetPosition( aPoint );
+ aView->MarkDirty();
+
+ return true;
+}
+
+
+int PCBNEW_CONTROL::GridSetOrigin( const TOOL_EVENT& aEvent )
+{
+ VECTOR2D* origin = aEvent.Parameter<VECTOR2D*>();
+
+ if( origin )
+ {
+ setOrigin( getView(), m_frame, m_gridOrigin, *origin );
+ delete origin;
+ }
+ else
+ {
+ Activate();
+
+ PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
+ assert( picker );
+
+ // TODO it will not check the toolbar button in module editor, as it uses a different ID..
+ m_frame->SetToolID( ID_PCB_PLACE_GRID_COORD_BUTT, wxCURSOR_PENCIL, _( "Adjust grid origin" ) );
+ picker->SetClickHandler( boost::bind( setOrigin, getView(), m_frame, m_gridOrigin, _1 ) );
+ picker->Activate();
+ Wait();
+ }
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::GridResetOrigin( const TOOL_EVENT& aEvent )
+{
+ getModel<BOARD>()->SetGridOrigin( wxPoint( 0, 0 ) );
+ m_gridOrigin->SetPosition( VECTOR2D( 0, 0 ) );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::GridPreset( const TOOL_EVENT& aEvent )
+{
+ long idx = aEvent.Parameter<long>();
+
+ m_frame->SetPresetGrid( idx );
+ updateGrid();
+
+ return 0;
+}
+
+
+// Miscellaneous
+int PCBNEW_CONTROL::ResetCoords( const TOOL_EVENT& aEvent )
+{
+ VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
+
+ m_frame->GetScreen()->m_O_Curseur = wxPoint( cursorPos.x, cursorPos.y );
+ m_frame->UpdateStatusBar();
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::SwitchCursor( const TOOL_EVENT& aEvent )
+{
+ const unsigned int BIG_CURSOR = 8000;
+ const unsigned int SMALL_CURSOR = 80;
+
+ PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
+ KIGFX::GAL* gal = frame->GetGalCanvas()->GetGAL();
+ gal->SetCursorSize( frame->GetCursorShape() ? BIG_CURSOR : SMALL_CURSOR );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::SwitchUnits( const TOOL_EVENT& aEvent )
+{
+ // TODO should not it be refactored to pcb_frame member function?
+ wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
+
+ if( g_UserUnit == INCHES )
+ evt.SetId( ID_TB_OPTIONS_SELECT_UNIT_MM );
+ else
+ evt.SetId( ID_TB_OPTIONS_SELECT_UNIT_INCH );
+
+ m_frame->ProcessEvent( evt );
+
+ return 0;
+}
+
+
+static bool deleteItem( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
+{
+ SELECTION_TOOL* selectionTool = aToolMgr->GetTool<SELECTION_TOOL>();
+ assert( selectionTool );
+
+ aToolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+ aToolMgr->RunAction( COMMON_ACTIONS::selectionCursor, true );
+ selectionTool->SanitizeSelection();
+
+ const SELECTION& selection = selectionTool->GetSelection();
+
+ if( selection.Empty() )
+ return true;
+
+ bool canBeRemoved = ( selection.Item<EDA_ITEM>( 0 )->Type() != PCB_MODULE_T );
+
+ if( canBeRemoved || IsOK( aToolMgr->GetEditFrame(), _( "Are you sure you want to delete item?" ) ) )
+ aToolMgr->RunAction( COMMON_ACTIONS::remove, true );
+ else
+ aToolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ return true;
+}
+
+
+int PCBNEW_CONTROL::DeleteItemCursor( const TOOL_EVENT& aEvent )
+{
+ Activate();
+
+ PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
+ assert( picker );
+
+ // TODO it will not check the toolbar button in the module editor, as it uses a different ID..
+ m_frame->SetToolID( ID_PCB_DELETE_ITEM_BUTT, wxCURSOR_PENCIL, _( "Delete item" ) );
+ picker->SetSnapping( false );
+ picker->SetClickHandler( boost::bind( deleteItem, m_toolMgr, _1 ) );
+ picker->Activate();
+ Wait();
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::AppendBoard( const TOOL_EVENT& aEvent )
+{
+ int open_ctl;
+ wxString fileName;
+ PICKED_ITEMS_LIST undoListPicker;
+ ITEM_PICKER picker( NULL, UR_NEW );
+
+ PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
+ BOARD* board = getModel<BOARD>();
+ KIGFX::VIEW* view = getView();
+
+ if( !editFrame )
+ return 0;
+
+ // Pick a file to append
+ if( !AskLoadBoardFileName( editFrame, &open_ctl, &fileName, true ) )
+ return 0;
+
+ IO_MGR::PCB_FILE_T pluginType = plugin_type( fileName, open_ctl );
+ PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
+
+ // keep track of existing items, in order to know what are the new items
+ // (for undo command for instance)
+
+ // Tracks are inserted, not appended, so mark the existing tracks to know what are the new tracks
+ for( TRACK* track = board->m_Track; track; track = track->Next() )
+ track->SetFlags( FLAG0 );
+
+ // Other items are appended to the item list, so keep trace to the last existing item is enough
+ MODULE* module = board->m_Modules.GetLast();
+ BOARD_ITEM* drawing = board->m_Drawings.GetLast();
+ int zonescount = board->GetAreaCount();
+
+ // Keep also the count of copper layers, to adjust if necessary
+ int initialCopperLayerCount = board->GetCopperLayerCount();
+ LSET initialEnabledLayers = board->GetEnabledLayers();
+
+ // Load the data
+ try
+ {
+ PROPERTIES props;
+ char xbuf[30];
+ char ybuf[30];
+
+ // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
+ sprintf( xbuf, "%d", editFrame->GetPageSizeIU().x );
+ sprintf( ybuf, "%d", editFrame->GetPageSizeIU().y );
+
+ props["page_width"] = xbuf;
+ props["page_height"] = ybuf;
+
+ editFrame->GetDesignSettings().m_NetClasses.Clear();
+ pi->Load( fileName, board, &props );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxString msg = wxString::Format( _( "Error loading board.\n%s" ), GetChars( ioe.errorText ));
+ DisplayError( editFrame, msg );
+
+ return 0;
+ }
+
+ // rebuild nets and ratsnest before any use of nets
+ board->BuildListOfNets();
+ board->GetRatsnest()->Recalculate();
+ board->SynchronizeNetsAndNetClasses();
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ // Process the new items
+ for( TRACK* track = board->m_Track; track; track = track->Next() )
+ {
+ if( track->GetFlags() & FLAG0 )
+ {
+ track->ClearFlags( FLAG0 );
+ continue;
+ }
+
+ picker.SetItem( track );
+ undoListPicker.PushItem( picker );
+ view->Add( track );
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, track );
+ }
+
+ module = module ? module->Next() : board->m_Modules;
+
+ for( ; module; module = module->Next() )
+ {
+ picker.SetItem( module );
+ undoListPicker.PushItem( picker );
+
+ module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
+ view->Add( module );
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, module );
+ }
+
+ drawing = drawing ? drawing->Next() : board->m_Drawings;
+
+ for( ; drawing; drawing = drawing->Next() )
+ {
+ picker.SetItem( drawing );
+ undoListPicker.PushItem( picker );
+ view->Add( drawing );
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, drawing );
+ }
+
+ for( ZONE_CONTAINER* zone = board->GetArea( zonescount ); zone;
+ zone = board->GetArea( zonescount ) )
+ {
+ picker.SetItem( zone );
+ undoListPicker.PushItem( picker );
+ zonescount++;
+ view->Add( zone );
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, zone );
+ }
+
+ if( undoListPicker.GetCount() == 0 )
+ return 0;
+
+ editFrame->SaveCopyInUndoList( undoListPicker, UR_NEW );
+
+ // Synchronize layers
+ // we should not ask PLUGINs to do these items:
+ int copperLayerCount = board->GetCopperLayerCount();
+
+ if( copperLayerCount > initialCopperLayerCount )
+ board->SetCopperLayerCount( copperLayerCount );
+
+ // Enable all used layers, and make them visible:
+ LSET enabledLayers = board->GetEnabledLayers();
+ enabledLayers |= initialEnabledLayers;
+ board->SetEnabledLayers( enabledLayers );
+ board->SetVisibleLayers( enabledLayers );
+ editFrame->ReCreateLayerBox();
+ editFrame->ReFillLayerWidget();
+ static_cast<PCB_DRAW_PANEL_GAL*>( editFrame->GetGalCanvas() )->SyncLayersVisibility( board );
+
+ // Start dragging the appended board
+ VECTOR2D v( static_cast<BOARD_ITEM*>( undoListPicker.GetPickedItem( 0 ) )->GetPosition() );
+ getViewControls()->WarpCursor( v, true, true );
+ m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::ShowHelp( const TOOL_EVENT& aEvent )
+{
+ DisplayHotkeyList( m_frame, m_frame->GetHotkeyConfig() );
+
+ return 0;
+}
+
+
+int PCBNEW_CONTROL::ToBeDone( const TOOL_EVENT& aEvent )
+{
+ DisplayInfoMessage( m_frame, _( "Not available in OpenGL/Cairo canvases." ) );
+
+ return 0;
+}
+
+
+void PCBNEW_CONTROL::SetTransitions()
+{
+ // View controls
+ Go( &PCBNEW_CONTROL::ZoomInOut, COMMON_ACTIONS::zoomIn.MakeEvent() );
+ Go( &PCBNEW_CONTROL::ZoomInOut, COMMON_ACTIONS::zoomOut.MakeEvent() );
+ Go( &PCBNEW_CONTROL::ZoomInOutCenter, COMMON_ACTIONS::zoomInCenter.MakeEvent() );
+ Go( &PCBNEW_CONTROL::ZoomInOutCenter, COMMON_ACTIONS::zoomOutCenter.MakeEvent() );
+ Go( &PCBNEW_CONTROL::ZoomCenter, COMMON_ACTIONS::zoomCenter.MakeEvent() );
+ Go( &PCBNEW_CONTROL::ZoomFitScreen, COMMON_ACTIONS::zoomFitScreen.MakeEvent() );
+ Go( &PCBNEW_CONTROL::ZoomPreset, COMMON_ACTIONS::zoomPreset.MakeEvent() );
+
+ // Display modes
+ Go( &PCBNEW_CONTROL::TrackDisplayMode, COMMON_ACTIONS::trackDisplayMode.MakeEvent() );
+ Go( &PCBNEW_CONTROL::PadDisplayMode, COMMON_ACTIONS::padDisplayMode.MakeEvent() );
+ Go( &PCBNEW_CONTROL::ViaDisplayMode, COMMON_ACTIONS::viaDisplayMode.MakeEvent() );
+ Go( &PCBNEW_CONTROL::ZoneDisplayMode, COMMON_ACTIONS::zoneDisplayEnable.MakeEvent() );
+ Go( &PCBNEW_CONTROL::ZoneDisplayMode, COMMON_ACTIONS::zoneDisplayDisable.MakeEvent() );
+ Go( &PCBNEW_CONTROL::ZoneDisplayMode, COMMON_ACTIONS::zoneDisplayOutlines.MakeEvent() );
+ Go( &PCBNEW_CONTROL::HighContrastMode, COMMON_ACTIONS::highContrastMode.MakeEvent() );
+ Go( &PCBNEW_CONTROL::HighContrastInc, COMMON_ACTIONS::highContrastInc.MakeEvent() );
+ Go( &PCBNEW_CONTROL::HighContrastDec, COMMON_ACTIONS::highContrastDec.MakeEvent() );
+
+ // Layer control
+ Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerTop.MakeEvent() );
+ Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerInner1.MakeEvent() );
+ Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerInner2.MakeEvent() );
+ Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerInner3.MakeEvent() );
+ Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerInner4.MakeEvent() );
+ Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerInner5.MakeEvent() );
+ Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerInner6.MakeEvent() );
+ Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerBottom.MakeEvent() );
+ Go( &PCBNEW_CONTROL::LayerNext, COMMON_ACTIONS::layerNext.MakeEvent() );
+ Go( &PCBNEW_CONTROL::LayerPrev, COMMON_ACTIONS::layerPrev.MakeEvent() );
+ Go( &PCBNEW_CONTROL::LayerToggle, COMMON_ACTIONS::layerToggle.MakeEvent() );
+ Go( &PCBNEW_CONTROL::LayerAlphaInc, COMMON_ACTIONS::layerAlphaInc.MakeEvent() );
+ Go( &PCBNEW_CONTROL::LayerAlphaDec, COMMON_ACTIONS::layerAlphaDec.MakeEvent() );
+
+ // Cursor control
+ Go( &PCBNEW_CONTROL::CursorControl, COMMON_ACTIONS::cursorUp.MakeEvent() );
+ Go( &PCBNEW_CONTROL::CursorControl, COMMON_ACTIONS::cursorDown.MakeEvent() );
+ Go( &PCBNEW_CONTROL::CursorControl, COMMON_ACTIONS::cursorLeft.MakeEvent() );
+ Go( &PCBNEW_CONTROL::CursorControl, COMMON_ACTIONS::cursorRight.MakeEvent() );
+ Go( &PCBNEW_CONTROL::CursorControl, COMMON_ACTIONS::cursorUpFast.MakeEvent() );
+ Go( &PCBNEW_CONTROL::CursorControl, COMMON_ACTIONS::cursorDownFast.MakeEvent() );
+ Go( &PCBNEW_CONTROL::CursorControl, COMMON_ACTIONS::cursorLeftFast.MakeEvent() );
+ Go( &PCBNEW_CONTROL::CursorControl, COMMON_ACTIONS::cursorRightFast.MakeEvent() );
+ Go( &PCBNEW_CONTROL::CursorControl, COMMON_ACTIONS::cursorClick.MakeEvent() );
+ Go( &PCBNEW_CONTROL::CursorControl, COMMON_ACTIONS::cursorDblClick.MakeEvent() );
+
+ // Pan control
+ Go( &PCBNEW_CONTROL::PanControl, COMMON_ACTIONS::panUp.MakeEvent() );
+ Go( &PCBNEW_CONTROL::PanControl, COMMON_ACTIONS::panDown.MakeEvent() );
+ Go( &PCBNEW_CONTROL::PanControl, COMMON_ACTIONS::panLeft.MakeEvent() );
+ Go( &PCBNEW_CONTROL::PanControl, COMMON_ACTIONS::panRight.MakeEvent() );
+
+ // Grid control
+ Go( &PCBNEW_CONTROL::GridFast1, COMMON_ACTIONS::gridFast1.MakeEvent() );
+ Go( &PCBNEW_CONTROL::GridFast2, COMMON_ACTIONS::gridFast2.MakeEvent() );
+ Go( &PCBNEW_CONTROL::GridNext, COMMON_ACTIONS::gridNext.MakeEvent() );
+ Go( &PCBNEW_CONTROL::GridPrev, COMMON_ACTIONS::gridPrev.MakeEvent() );
+ Go( &PCBNEW_CONTROL::GridSetOrigin, COMMON_ACTIONS::gridSetOrigin.MakeEvent() );
+ Go( &PCBNEW_CONTROL::GridResetOrigin, COMMON_ACTIONS::gridResetOrigin.MakeEvent() );
+ Go( &PCBNEW_CONTROL::GridPreset, COMMON_ACTIONS::gridPreset.MakeEvent() );
+
+ // Miscellaneous
+ Go( &PCBNEW_CONTROL::ResetCoords, COMMON_ACTIONS::resetCoords.MakeEvent() );
+ Go( &PCBNEW_CONTROL::SwitchCursor, COMMON_ACTIONS::switchCursor.MakeEvent() );
+ Go( &PCBNEW_CONTROL::SwitchUnits, COMMON_ACTIONS::switchUnits.MakeEvent() );
+ Go( &PCBNEW_CONTROL::DeleteItemCursor, COMMON_ACTIONS::deleteItemCursor.MakeEvent() );
+ Go( &PCBNEW_CONTROL::AppendBoard, COMMON_ACTIONS::appendBoard.MakeEvent() );
+ Go( &PCBNEW_CONTROL::ShowHelp, COMMON_ACTIONS::showHelp.MakeEvent() );
+ Go( &PCBNEW_CONTROL::ToBeDone, COMMON_ACTIONS::toBeDone.MakeEvent() );
+}
+
+
+void PCBNEW_CONTROL::updateGrid()
+{
+ BASE_SCREEN* screen = m_frame->GetScreen();
+ //GRID_TYPE grid = screen->GetGrid( idx );
+ getView()->GetGAL()->SetGridSize( VECTOR2D( screen->GetGridSize() ) );
+ getView()->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
+}
diff --git a/pcbnew/tools/pcbnew_control.h b/pcbnew/tools/pcbnew_control.h
new file mode 100644
index 0000000..1117b77
--- /dev/null
+++ b/pcbnew/tools/pcbnew_control.h
@@ -0,0 +1,109 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014-2016 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef PCBNEW_CONTROL_H
+#define PCBNEW_CONTROL_H
+
+#include <tool/tool_interactive.h>
+
+namespace KIGFX {
+ class ORIGIN_VIEWITEM;
+}
+class PCB_BASE_FRAME;
+
+/**
+ * Class PCBNEW_CONTROL
+ *
+ * Handles actions that are shared between different frames in pcbnew.
+ */
+
+class PCBNEW_CONTROL : public TOOL_INTERACTIVE
+{
+public:
+ PCBNEW_CONTROL();
+ ~PCBNEW_CONTROL();
+
+ /// @copydoc TOOL_INTERACTIVE::Reset()
+ void Reset( RESET_REASON aReason );
+
+ // View controls
+ int ZoomInOut( const TOOL_EVENT& aEvent );
+ int ZoomInOutCenter( const TOOL_EVENT& aEvent );
+ int ZoomCenter( const TOOL_EVENT& aEvent );
+ int ZoomFitScreen( const TOOL_EVENT& aEvent );
+ int ZoomPreset( const TOOL_EVENT& aEvent );
+
+ // Display modes
+ int TrackDisplayMode( const TOOL_EVENT& aEvent );
+ int PadDisplayMode( const TOOL_EVENT& aEvent );
+ int ViaDisplayMode( const TOOL_EVENT& aEvent );
+ int ZoneDisplayMode( const TOOL_EVENT& aEvent );
+ int HighContrastMode( const TOOL_EVENT& aEvent );
+ int HighContrastInc( const TOOL_EVENT& aEvent );
+ int HighContrastDec( const TOOL_EVENT& aEvent );
+
+ // Layer control
+ int LayerSwitch( const TOOL_EVENT& aEvent );
+ int LayerNext( const TOOL_EVENT& aEvent );
+ int LayerPrev( const TOOL_EVENT& aEvent );
+ int LayerToggle( const TOOL_EVENT& aEvent );
+ int LayerAlphaInc( const TOOL_EVENT& aEvent );
+ int LayerAlphaDec( const TOOL_EVENT& aEvent );
+
+ int CursorControl( const TOOL_EVENT& aEvent );
+ int PanControl( const TOOL_EVENT& aEvent );
+
+ // Grid control
+ int GridFast1( const TOOL_EVENT& aEvent );
+ int GridFast2( const TOOL_EVENT& aEvent );
+ int GridNext( const TOOL_EVENT& aEvent );
+ int GridPrev( const TOOL_EVENT& aEvent );
+ int GridSetOrigin( const TOOL_EVENT& aEvent );
+ int GridResetOrigin( const TOOL_EVENT& aEvent );
+ int GridPreset( const TOOL_EVENT& aEvent );
+
+ // Miscellaneous
+ int ResetCoords( const TOOL_EVENT& aEvent );
+ int SwitchCursor( const TOOL_EVENT& aEvent );
+ int SwitchUnits( const TOOL_EVENT& aEvent );
+ int DeleteItemCursor( const TOOL_EVENT& aEvent );
+ int AppendBoard( const TOOL_EVENT& aEvent );
+ int ShowHelp( const TOOL_EVENT& aEvent );
+ int ToBeDone( const TOOL_EVENT& aEvent );
+
+ ///> Sets up handlers for various events.
+ void SetTransitions();
+
+private:
+ ///> Pointer to the currently used edit frame.
+ PCB_BASE_FRAME* m_frame;
+
+ ///> Grid origin marker.
+ KIGFX::ORIGIN_VIEWITEM* m_gridOrigin;
+
+ ///> Applies the legacy canvas grid settings for GAL.
+ void updateGrid();
+};
+
+#endif
diff --git a/pcbnew/tools/picker_tool.cpp b/pcbnew/tools/picker_tool.cpp
new file mode 100644
index 0000000..6234346
--- /dev/null
+++ b/pcbnew/tools/picker_tool.cpp
@@ -0,0 +1,115 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "picker_tool.h"
+#include "common_actions.h"
+
+#include <wxPcbStruct.h>
+#include <view/view_controls.h>
+#include <tool/tool_manager.h>
+
+PICKER_TOOL::PICKER_TOOL()
+ : TOOL_INTERACTIVE( "pcbnew.Picker" )
+{
+ reset();
+}
+
+
+int PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
+{
+ KIGFX::VIEW_CONTROLS* controls = getViewControls();
+
+ assert( !m_picking );
+ m_picking = true;
+ m_picked = boost::none;
+
+ setControls();
+
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ if( evt->IsClick( BUT_LEFT ) )
+ {
+ bool getNext = false;
+ m_picked = controls->GetCursorPosition();
+
+ if( m_clickHandler )
+ {
+ try
+ {
+ getNext = (*m_clickHandler)( *m_picked );
+ }
+ catch( std::exception& e )
+ {
+ std::cerr << "PICKER_TOOL click handler error: " << e.what() << std::endl;
+ break;
+ }
+ }
+
+ if( !getNext )
+ break;
+ else
+ m_toolMgr->PassEvent();
+ }
+
+ else if( evt->IsCancel() || evt->IsActivate() )
+ break;
+
+ else
+ m_toolMgr->PassEvent();
+ }
+
+ reset();
+ getEditFrame<PCB_BASE_FRAME>()->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
+
+ return 0;
+}
+
+
+void PICKER_TOOL::SetTransitions()
+{
+ Go( &PICKER_TOOL::Main, COMMON_ACTIONS::pickerTool.MakeEvent() );
+}
+
+
+void PICKER_TOOL::reset()
+{
+ m_cursorSnapping = true;
+ m_cursorVisible = true;
+ m_cursorCapture = false;
+ m_autoPanning = false;
+
+ m_picking = false;
+ m_clickHandler = boost::none;
+}
+
+
+void PICKER_TOOL::setControls()
+{
+ KIGFX::VIEW_CONTROLS* controls = getViewControls();
+
+ controls->ShowCursor( m_cursorVisible );
+ controls->SetSnapping( m_cursorSnapping );
+ controls->CaptureCursor( m_cursorCapture );
+ controls->SetAutoPan( m_autoPanning );
+}
diff --git a/pcbnew/tools/picker_tool.h b/pcbnew/tools/picker_tool.h
new file mode 100644
index 0000000..6512d95
--- /dev/null
+++ b/pcbnew/tools/picker_tool.h
@@ -0,0 +1,127 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef PICKER_TOOL_H
+#define PICKER_TOOL_H
+
+#include <tool/tool_interactive.h>
+#include <boost/optional/optional.hpp>
+#include <boost/function.hpp>
+
+/**
+ * @brief Generic tool for picking a point.
+ */
+class PICKER_TOOL : public TOOL_INTERACTIVE
+{
+public:
+ PICKER_TOOL();
+ ~PICKER_TOOL() {}
+
+ ///> Mouse event click handler type.
+ typedef boost::function<bool(const VECTOR2D&)> CLICK_HANDLER;
+
+ ///> @copydoc TOOL_INTERACTIVE::Reset()
+ void Reset( RESET_REASON aReason ) {}
+
+ ///> Main event loop.
+ int Main( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function SetSnapping()
+ * Sets cursor snapping to grid for the period when the tool is active.
+ */
+ inline void SetSnapping( bool aEnable ) { m_cursorSnapping = aEnable; }
+
+ /**
+ * Function SetCursorVisible()
+ * Sets cursor visibility for the period when the tool is active.
+ */
+ inline void SetCursorVisible( bool aEnable ) { m_cursorVisible = aEnable; }
+
+ /**
+ * Function SetAutoPanning()
+ * Sets autopanning mode for the period when the tool is active.
+ */
+ inline void SetAutoPanning( bool aEnable ) { m_autoPanning = aEnable; }
+
+ /**
+ * Function SetAutoPanning()
+ * Toggles cursor capture mode for the period when the tool is active.
+ */
+ inline void SetCursorCapture( bool aEnable ) { m_cursorCapture = aEnable; }
+
+ /**
+ * Function GetPoint()
+ * Returns picked point.
+ */
+ inline boost::optional<VECTOR2D> GetPoint() const
+ {
+ assert( !m_picking );
+ return m_picked;
+ }
+
+ /**
+ * Function IsPicking()
+ * Returns information whether the tool is still active.
+ */
+ bool IsPicking() const { return m_picking; }
+
+ /**
+ * Function SetClickHandler()
+ * Sets a handler for mouse click event. Handler may decide to receive further click by
+ * returning true.
+ */
+ inline void SetClickHandler( CLICK_HANDLER aHandler )
+ {
+ assert( !m_clickHandler );
+ m_clickHandler = aHandler;
+ }
+
+ ///> @copydoc TOOL_INTERACTIVE::SetTransitions();
+ void SetTransitions();
+
+private:
+ // Tool settings.
+ bool m_cursorSnapping;
+ bool m_cursorVisible;
+ bool m_cursorCapture;
+ bool m_autoPanning;
+
+ ///> Optional mouse click event handler.
+ boost::optional<CLICK_HANDLER> m_clickHandler;
+
+ ///> Picked point (if any).
+ boost::optional<VECTOR2D> m_picked;
+
+ ///> Activity status.
+ bool m_picking;
+
+ ///> Reinitializes tool to its initial state.
+ void reset();
+
+ ///> Applies the requested VIEW_CONTROLS settings.
+ void setControls();
+};
+
+#endif /* PICKER_TOOL_H */
diff --git a/pcbnew/tools/placement_tool.cpp b/pcbnew/tools/placement_tool.cpp
new file mode 100644
index 0000000..d962492
--- /dev/null
+++ b/pcbnew/tools/placement_tool.cpp
@@ -0,0 +1,354 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "placement_tool.h"
+#include "common_actions.h"
+#include "selection_tool.h"
+#include <tool/tool_manager.h>
+
+#include <wxPcbStruct.h>
+#include <class_board.h>
+#include <ratsnest_data.h>
+
+#include <confirm.h>
+#include <boost/foreach.hpp>
+
+PLACEMENT_TOOL::PLACEMENT_TOOL() :
+ TOOL_INTERACTIVE( "pcbnew.Placement" ), m_selectionTool( NULL ), m_placementMenu( NULL )
+{
+}
+
+PLACEMENT_TOOL::~PLACEMENT_TOOL()
+{
+ delete m_placementMenu;
+}
+
+
+bool PLACEMENT_TOOL::Init()
+{
+ // Find the selection tool, so they can cooperate
+ m_selectionTool = static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
+
+ if( !m_selectionTool )
+ {
+ DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) );
+ return false;
+ }
+
+ // Create a context menu and make it available through selection tool
+ m_placementMenu = new CONTEXT_MENU;
+ m_placementMenu->Add( COMMON_ACTIONS::alignTop );
+ m_placementMenu->Add( COMMON_ACTIONS::alignBottom );
+ m_placementMenu->Add( COMMON_ACTIONS::alignLeft );
+ m_placementMenu->Add( COMMON_ACTIONS::alignRight );
+ m_placementMenu->AppendSeparator();
+ m_placementMenu->Add( COMMON_ACTIONS::distributeHorizontally );
+ m_placementMenu->Add( COMMON_ACTIONS::distributeVertically );
+ m_selectionTool->GetMenu().AddMenu( m_placementMenu, _( "Align/distribute" ), false,
+ SELECTION_CONDITIONS::MoreThan( 1 ) );
+
+ return true;
+}
+
+
+int PLACEMENT_TOOL::AlignTop( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ if( selection.Size() > 1 )
+ {
+ PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+
+ // Compute the highest point of selection - it will be the edge of alignment
+ int top = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetY();
+
+ for( int i = 1; i < selection.Size(); ++i )
+ {
+ int currentTop = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetY();
+
+ if( top > currentTop ) // Y decreases when going up
+ top = currentTop;
+ }
+
+ // Move the selected items
+ for( int i = 0; i < selection.Size(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+ int difference = top - item->GetBoundingBox().GetY();
+
+ item->Move( wxPoint( 0, difference ) );
+ item->ViewUpdate();
+ ratsnest->Update( item );
+ }
+
+ getModel<BOARD>()->GetRatsnest()->Recalculate();
+ }
+
+ return 0;
+}
+
+
+int PLACEMENT_TOOL::AlignBottom( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ if( selection.Size() > 1 )
+ {
+ PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+
+ // Compute the lowest point of selection - it will be the edge of alignment
+ int bottom = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetBottom();
+
+ for( int i = 1; i < selection.Size(); ++i )
+ {
+ int currentBottom = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetBottom();
+
+ if( bottom < currentBottom ) // Y increases when going down
+ bottom = currentBottom;
+ }
+
+ // Move the selected items
+ for( int i = 0; i < selection.Size(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+ int difference = bottom - item->GetBoundingBox().GetBottom();
+
+ item->Move( wxPoint( 0, difference ) );
+ item->ViewUpdate();
+ ratsnest->Update( item );
+ }
+
+ getModel<BOARD>()->GetRatsnest()->Recalculate();
+ }
+
+ return 0;
+}
+
+
+int PLACEMENT_TOOL::AlignLeft( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ if( selection.Size() > 1 )
+ {
+ PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+
+ // Compute the leftmost point of selection - it will be the edge of alignment
+ int left = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetX();
+
+ for( int i = 1; i < selection.Size(); ++i )
+ {
+ int currentLeft = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetX();
+
+ if( left > currentLeft ) // X decreases when going left
+ left = currentLeft;
+ }
+
+ // Move the selected items
+ for( int i = 0; i < selection.Size(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+ int difference = left - item->GetBoundingBox().GetX();
+
+ item->Move( wxPoint( difference, 0 ) );
+ item->ViewUpdate();
+ ratsnest->Update( item );
+ }
+
+ getModel<BOARD>()->GetRatsnest()->Recalculate();
+ }
+
+ return 0;
+}
+
+
+int PLACEMENT_TOOL::AlignRight( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ if( selection.Size() > 1 )
+ {
+ PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+
+ // Compute the rightmost point of selection - it will be the edge of alignment
+ int right = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetRight();
+
+ for( int i = 1; i < selection.Size(); ++i )
+ {
+ int currentRight = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetRight();
+
+ if( right < currentRight ) // X increases when going right
+ right = currentRight;
+ }
+
+ // Move the selected items
+ for( int i = 0; i < selection.Size(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+ int difference = right - item->GetBoundingBox().GetRight();
+
+ item->Move( wxPoint( difference, 0 ) );
+ item->ViewUpdate();
+ ratsnest->Update( item );
+ }
+
+ getModel<BOARD>()->GetRatsnest()->Recalculate();
+ }
+
+ return 0;
+}
+
+
+static bool compareX( const BOARD_ITEM* aA, const BOARD_ITEM* aB )
+{
+ return aA->GetBoundingBox().Centre().x < aB->GetBoundingBox().Centre().x;
+}
+
+
+static bool compareY( const BOARD_ITEM* aA, const BOARD_ITEM* aB )
+{
+ return aA->GetBoundingBox().Centre().y < aB->GetBoundingBox().Centre().y;
+}
+
+
+int PLACEMENT_TOOL::DistributeHorizontally( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ if( selection.Size() > 1 )
+ {
+ PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+
+ // Prepare a list, so the items can be sorted by their X coordinate
+ std::list<BOARD_ITEM*> itemsList;
+ for( int i = 0; i < selection.Size(); ++i )
+ itemsList.push_back( selection.Item<BOARD_ITEM>( i ) );
+
+ // Sort items by X coordinate
+ itemsList.sort( compareX );
+
+ // Expected X coordinate for the next item (=minX)
+ int position = (*itemsList.begin())->GetBoundingBox().Centre().x;
+
+ // X coordinate for the last item
+ const int maxX = (*itemsList.rbegin())->GetBoundingBox().Centre().x;
+
+ // Distance between items
+ const int distance = ( maxX - position ) / ( itemsList.size() - 1 );
+
+ BOOST_FOREACH( BOARD_ITEM* item, itemsList )
+ {
+ int difference = position - item->GetBoundingBox().Centre().x;
+
+ item->Move( wxPoint( difference, 0 ) );
+ item->ViewUpdate();
+ ratsnest->Update( item );
+
+ position += distance;
+ }
+
+ getModel<BOARD>()->GetRatsnest()->Recalculate();
+ }
+
+ return 0;
+}
+
+
+int PLACEMENT_TOOL::DistributeVertically( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ if( selection.Size() > 1 )
+ {
+ PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+
+ // Prepare a list, so the items can be sorted by their Y coordinate
+ std::list<BOARD_ITEM*> itemsList;
+ for( int i = 0; i < selection.Size(); ++i )
+ itemsList.push_back( selection.Item<BOARD_ITEM>( i ) );
+
+ // Sort items by Y coordinate
+ itemsList.sort( compareY );
+
+ // Expected Y coordinate for the next item (=minY)
+ int position = (*itemsList.begin())->GetBoundingBox().Centre().y;
+
+ // Y coordinate for the last item
+ const int maxY = (*itemsList.rbegin())->GetBoundingBox().Centre().y;
+
+ // Distance between items
+ const int distance = ( maxY - position ) / ( itemsList.size() - 1 );
+
+ BOOST_FOREACH( BOARD_ITEM* item, itemsList )
+ {
+ int difference = position - item->GetBoundingBox().Centre().y;
+
+ item->Move( wxPoint( 0, difference ) );
+ item->ViewUpdate();
+ ratsnest->Update( item );
+
+ position += distance;
+ }
+
+ getModel<BOARD>()->GetRatsnest()->Recalculate();
+ }
+
+ return 0;
+}
+
+
+void PLACEMENT_TOOL::SetTransitions()
+{
+ Go( &PLACEMENT_TOOL::AlignTop, COMMON_ACTIONS::alignTop.MakeEvent() );
+ Go( &PLACEMENT_TOOL::AlignBottom, COMMON_ACTIONS::alignBottom.MakeEvent() );
+ Go( &PLACEMENT_TOOL::AlignLeft, COMMON_ACTIONS::alignLeft.MakeEvent() );
+ Go( &PLACEMENT_TOOL::AlignRight, COMMON_ACTIONS::alignRight.MakeEvent() );
+
+ Go( &PLACEMENT_TOOL::DistributeHorizontally, COMMON_ACTIONS::distributeHorizontally.MakeEvent() );
+ Go( &PLACEMENT_TOOL::DistributeVertically, COMMON_ACTIONS::distributeVertically.MakeEvent() );
+}
diff --git a/pcbnew/tools/placement_tool.h b/pcbnew/tools/placement_tool.h
new file mode 100644
index 0000000..db8ec92
--- /dev/null
+++ b/pcbnew/tools/placement_tool.h
@@ -0,0 +1,89 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef PLACEMENT_TOOL_H_
+#define PLACEMENT_TOOL_H_
+
+#include <tool/tool_interactive.h>
+
+class SELECTION_TOOL;
+
+class PLACEMENT_TOOL : public TOOL_INTERACTIVE
+{
+public:
+ PLACEMENT_TOOL();
+ virtual ~PLACEMENT_TOOL();
+
+ /// @copydoc TOOL_INTERACTIVE::Reset()
+ void Reset( RESET_REASON aReason ) {};
+
+ /// @copydoc TOOL_INTERACTIVE::Init()
+ bool Init();
+
+ /**
+ * Function AlignTop()
+ * Sets Y coordinate of the selected items to the value of the top-most selected item Y coordinate.
+ */
+ int AlignTop( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function AlignBottom()
+ * Sets Y coordinate of the selected items to the value of the bottom-most selected item Y coordinate.
+ */
+ int AlignBottom( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function AlignLeft()
+ * Sets X coordinate of the selected items to the value of the left-most selected item X coordinate.
+ */
+ int AlignLeft( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function AlignRight()
+ * Sets X coordinate of the selected items to the value of the right-most selected item X coordinate.
+ */
+ int AlignRight( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function DistributeHorizontally()
+ * Distributes the selected items along the X axis.
+ */
+ int DistributeHorizontally( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function DistributeVertically()
+ * Distributes the selected items along the Y axis.
+ */
+ int DistributeVertically( const TOOL_EVENT& aEvent );
+
+ ///> Sets up handlers for various events.
+ void SetTransitions();
+
+private:
+ SELECTION_TOOL* m_selectionTool;
+
+ CONTEXT_MENU* m_placementMenu;
+};
+
+#endif /* PLACEMENT_TOOL_H_ */
diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp
new file mode 100644
index 0000000..bb1bf39
--- /dev/null
+++ b/pcbnew/tools/point_editor.cpp
@@ -0,0 +1,890 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <boost/make_shared.hpp>
+#include <boost/bind.hpp>
+
+#include <tool/tool_manager.h>
+#include <view/view_controls.h>
+#include <gal/graphics_abstraction_layer.h>
+#include <geometry/seg.h>
+#include <confirm.h>
+
+#include "common_actions.h"
+#include "selection_tool.h"
+#include "point_editor.h"
+
+#include <wxPcbStruct.h>
+#include <class_edge_mod.h>
+#include <class_dimension.h>
+#include <class_zone.h>
+#include <class_board.h>
+#include <class_module.h>
+
+// Few constants to avoid using bare numbers for point indices
+enum SEG_POINTS
+{
+ SEG_START, SEG_END
+};
+
+enum ARC_POINTS
+{
+ ARC_CENTER, ARC_START, ARC_END
+};
+
+enum CIRCLE_POINTS
+{
+ CIRC_CENTER, CIRC_END
+};
+
+enum DIMENSION_POINTS
+{
+ DIM_CROSSBARO,
+ DIM_CROSSBARF,
+ DIM_FEATUREGO,
+ DIM_FEATUREDO,
+};
+
+
+class EDIT_POINTS_FACTORY
+{
+public:
+ static boost::shared_ptr<EDIT_POINTS> Make( EDA_ITEM* aItem, KIGFX::GAL* aGal )
+ {
+ boost::shared_ptr<EDIT_POINTS> points = boost::make_shared<EDIT_POINTS>( aItem );
+
+ // Generate list of edit points basing on the item type
+ switch( aItem->Type() )
+ {
+ case PCB_LINE_T:
+ case PCB_MODULE_EDGE_T:
+ {
+ const DRAWSEGMENT* segment = static_cast<const DRAWSEGMENT*>( aItem );
+
+ switch( segment->GetShape() )
+ {
+ case S_SEGMENT:
+ points->AddPoint( segment->GetStart() );
+ points->AddPoint( segment->GetEnd() );
+ break;
+
+ case S_ARC:
+ points->AddPoint( segment->GetCenter() );
+ points->AddPoint( segment->GetArcStart() );
+ points->AddPoint( segment->GetArcEnd() );
+
+ // Set constraints
+ // Arc end has to stay at the same radius as the start
+ points->Point( ARC_END ).SetConstraint( new EC_CIRCLE( points->Point( ARC_END ),
+ points->Point( ARC_CENTER ),
+ points->Point( ARC_START ) ) );
+ break;
+
+ case S_CIRCLE:
+ points->AddPoint( segment->GetCenter() );
+ points->AddPoint( segment->GetEnd() );
+ break;
+
+ default: // suppress warnings
+ break;
+ }
+
+ break;
+ }
+
+ case PCB_ZONE_AREA_T:
+ {
+ const CPolyLine* outline = static_cast<const ZONE_CONTAINER*>( aItem )->Outline();
+ int cornersCount = outline->GetCornersCount();
+
+ for( int i = 0; i < cornersCount; ++i )
+ {
+ points->AddPoint( outline->GetPos( i ) );
+
+ if( outline->IsEndContour( i ) )
+ points->AddBreak();
+ }
+
+ // Lines have to be added after creating edit points,
+ // as they use EDIT_POINT references
+ for( int i = 0; i < cornersCount - 1; ++i )
+ {
+ if( points->IsContourEnd( i ) )
+ {
+ points->AddLine( points->Point( i ),
+ points->Point( points->GetContourStartIdx( i ) ) );
+ }
+ else
+ {
+ points->AddLine( points->Point( i ), points->Point( i + 1 ) );
+ }
+
+ points->Line( i ).SetConstraint( new EC_SNAPLINE( points->Line( i ),
+ boost::bind( &KIGFX::GAL::GetGridPoint, aGal, _1 ) ) );
+ }
+
+ // The last missing line, connecting the last and the first polygon point
+ points->AddLine( points->Point( cornersCount - 1 ),
+ points->Point( points->GetContourStartIdx( cornersCount - 1 ) ) );
+
+ points->Line( points->LinesSize() - 1 ).SetConstraint(
+ new EC_SNAPLINE( points->Line( points->LinesSize() - 1 ),
+ boost::bind( &KIGFX::GAL::GetGridPoint, aGal, _1 ) ) );
+ break;
+ }
+
+ case PCB_DIMENSION_T:
+ {
+ const DIMENSION* dimension = static_cast<const DIMENSION*>( aItem );
+
+ points->AddPoint( dimension->m_crossBarO );
+ points->AddPoint( dimension->m_crossBarF );
+ points->AddPoint( dimension->m_featureLineGO );
+ points->AddPoint( dimension->m_featureLineDO );
+
+ // Dimension height setting - edit points should move only along the feature lines
+ points->Point( DIM_CROSSBARO ).SetConstraint( new EC_LINE( points->Point( DIM_CROSSBARO ),
+ points->Point( DIM_FEATUREGO ) ) );
+ points->Point( DIM_CROSSBARF ).SetConstraint( new EC_LINE( points->Point( DIM_CROSSBARF ),
+ points->Point( DIM_FEATUREDO ) ) );
+
+ break;
+ }
+
+ default:
+ points.reset();
+ break;
+ }
+
+ return points;
+ }
+
+private:
+ EDIT_POINTS_FACTORY() {};
+};
+
+
+POINT_EDITOR::POINT_EDITOR() :
+ TOOL_INTERACTIVE( "pcbnew.PointEditor" ), m_selectionTool( NULL ), m_editedPoint( NULL ),
+ m_original( VECTOR2I( 0, 0 ) ), m_altConstrainer( VECTOR2I( 0, 0 ) )
+{
+}
+
+
+void POINT_EDITOR::Reset( RESET_REASON aReason )
+{
+ m_editPoints.reset();
+ m_altConstraint.reset();
+}
+
+
+bool POINT_EDITOR::Init()
+{
+ // Find the selection tool, so they can cooperate
+ m_selectionTool = static_cast<SELECTION_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) );
+
+ if( !m_selectionTool )
+ {
+ DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) );
+ return false;
+ }
+
+ m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::pointEditorAddCorner,
+ POINT_EDITOR::addCornerCondition );
+ m_selectionTool->GetMenu().AddItem( COMMON_ACTIONS::pointEditorRemoveCorner,
+ boost::bind( &POINT_EDITOR::removeCornerCondition, this, _1 ) );
+
+ return true;
+}
+
+
+void POINT_EDITOR::updateEditedPoint( const TOOL_EVENT& aEvent )
+{
+ EDIT_POINT* point = m_editedPoint;
+
+ if( aEvent.IsMotion() )
+ {
+ point = m_editPoints->FindPoint( aEvent.Position() );
+ }
+ else if( aEvent.IsDrag( BUT_LEFT ) )
+ {
+ point = m_editPoints->FindPoint( aEvent.DragOrigin() );
+ }
+
+ if( m_editedPoint != point )
+ setEditedPoint( point );
+}
+
+
+int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ if( selection.Size() == 1 )
+ {
+ Activate();
+
+ KIGFX::VIEW_CONTROLS* controls = getViewControls();
+ KIGFX::VIEW* view = getView();
+ PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
+ EDA_ITEM* item = selection.items.GetPickedItem( 0 );
+
+ m_editPoints = EDIT_POINTS_FACTORY::Make( item, getView()->GetGAL() );
+
+ if( !m_editPoints )
+ return 0;
+
+ view->Add( m_editPoints.get() );
+ m_editedPoint = NULL;
+ bool modified = false;
+
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ if( !m_editPoints ||
+ evt->Matches( m_selectionTool->ClearedEvent ) ||
+ evt->Matches( m_selectionTool->UnselectedEvent ) ||
+ evt->Matches( m_selectionTool->SelectedEvent ) )
+ {
+ break;
+ }
+
+ if ( !modified )
+ updateEditedPoint( *evt );
+
+ if( evt->IsAction( &COMMON_ACTIONS::pointEditorAddCorner ) )
+ {
+ addCorner( controls->GetCursorPosition() );
+ updatePoints();
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::pointEditorRemoveCorner ) )
+ {
+ if( m_editedPoint )
+ {
+ removeCorner( m_editedPoint );
+ updatePoints();
+ }
+ }
+
+ else if( evt->IsDrag( BUT_LEFT ) && m_editedPoint )
+ {
+ if( !modified )
+ {
+ // Save items, so changes can be undone
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+ controls->ForceCursorPosition( false );
+ m_original = *m_editedPoint; // Save the original position
+ controls->SetAutoPan( true );
+ modified = true;
+ }
+
+ bool enableAltConstraint = !!evt->Modifier( MD_CTRL );
+ if( enableAltConstraint != (bool) m_altConstraint ) // alternative constraint
+ setAltConstraint( enableAltConstraint );
+
+ m_editedPoint->SetPosition( controls->GetCursorPosition() );
+
+ if( m_altConstraint )
+ m_altConstraint->Apply();
+ else
+ m_editedPoint->ApplyConstraint();
+
+ updateItem();
+ updatePoints();
+
+ m_editPoints->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::pointEditorUpdate ) )
+ {
+ updatePoints();
+ }
+
+ else if( evt->IsMouseUp( BUT_LEFT ) )
+ {
+ controls->SetAutoPan( false );
+ setAltConstraint( false );
+ modified = false;
+ m_toolMgr->PassEvent();
+ }
+
+ else if( evt->IsCancel() )
+ {
+ if( modified ) // Restore the last change
+ {
+ wxCommandEvent dummy;
+ editFrame->RestoreCopyFromUndoList( dummy );
+
+ updatePoints();
+ modified = false;
+ }
+
+ // Let the selection tool receive the event too
+ m_toolMgr->PassEvent();
+
+ break;
+ }
+
+ else
+ {
+ m_toolMgr->PassEvent();
+ }
+ }
+
+ if( m_editPoints )
+ {
+ finishItem();
+ item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ view->Remove( m_editPoints.get() );
+ m_editPoints.reset();
+ }
+
+ controls->ShowCursor( false );
+ controls->SetAutoPan( false );
+ controls->SetSnapping( false );
+ }
+
+ return 0;
+}
+
+
+void POINT_EDITOR::updateItem() const
+{
+ EDA_ITEM* item = m_editPoints->GetParent();
+
+ switch( item->Type() )
+ {
+ case PCB_LINE_T:
+ case PCB_MODULE_EDGE_T:
+ {
+ DRAWSEGMENT* segment = static_cast<DRAWSEGMENT*>( item );
+ switch( segment->GetShape() )
+ {
+ case S_SEGMENT:
+ if( isModified( m_editPoints->Point( SEG_START ) ) )
+ segment->SetStart( wxPoint( m_editPoints->Point( SEG_START ).GetPosition().x,
+ m_editPoints->Point( SEG_START ).GetPosition().y ) );
+
+ else if( isModified( m_editPoints->Point( SEG_END ) ) )
+ segment->SetEnd( wxPoint( m_editPoints->Point( SEG_END ).GetPosition().x,
+ m_editPoints->Point( SEG_END ).GetPosition().y ) );
+
+ break;
+
+ case S_ARC:
+ {
+ const VECTOR2I& center = m_editPoints->Point( ARC_CENTER ).GetPosition();
+ const VECTOR2I& start = m_editPoints->Point( ARC_START ).GetPosition();
+ const VECTOR2I& end = m_editPoints->Point( ARC_END ).GetPosition();
+
+ if( center != segment->GetCenter() )
+ {
+ wxPoint moveVector = wxPoint( center.x, center.y ) - segment->GetCenter();
+ segment->Move( moveVector );
+
+ m_editPoints->Point( ARC_START ).SetPosition( segment->GetArcStart() );
+ m_editPoints->Point( ARC_END ).SetPosition( segment->GetArcEnd() );
+ }
+
+ else
+ {
+ segment->SetArcStart( wxPoint( start.x, start.y ) );
+
+ VECTOR2D startLine = start - center;
+ VECTOR2I endLine = end - center;
+ double newAngle = RAD2DECIDEG( endLine.Angle() - startLine.Angle() );
+
+ // Adjust the new angle to (counter)clockwise setting
+ bool clockwise = ( segment->GetAngle() > 0 );
+
+ if( clockwise && newAngle < 0.0 )
+ newAngle += 3600.0;
+ else if( !clockwise && newAngle > 0.0 )
+ newAngle -= 3600.0;
+
+ segment->SetAngle( newAngle );
+ }
+
+ break;
+ }
+
+ case S_CIRCLE:
+ {
+ const VECTOR2I& center = m_editPoints->Point( CIRC_CENTER ).GetPosition();
+ const VECTOR2I& end = m_editPoints->Point( CIRC_END ).GetPosition();
+
+ if( isModified( m_editPoints->Point( CIRC_CENTER ) ) )
+ {
+ wxPoint moveVector = wxPoint( center.x, center.y ) - segment->GetCenter();
+ segment->Move( moveVector );
+ }
+ else
+ {
+ segment->SetEnd( wxPoint( end.x, end.y ) );
+ }
+
+ break;
+ }
+
+ default: // suppress warnings
+ break;
+ }
+
+ // Update relative coordinates for module edges
+ if( EDGE_MODULE* edge = dyn_cast<EDGE_MODULE*>( item ) )
+ edge->SetLocalCoord();
+
+ break;
+ }
+
+ case PCB_ZONE_AREA_T:
+ {
+ ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
+ zone->ClearFilledPolysList();
+ CPolyLine* outline = zone->Outline();
+
+ for( int i = 0; i < outline->GetCornersCount(); ++i )
+ {
+ VECTOR2I point = m_editPoints->Point( i ).GetPosition();
+ outline->SetX( i, point.x );
+ outline->SetY( i, point.y );
+ }
+
+ break;
+ }
+
+ case PCB_DIMENSION_T:
+ {
+ DIMENSION* dimension = static_cast<DIMENSION*>( item );
+
+ // Check which point is currently modified and updated dimension's points respectively
+ if( isModified( m_editPoints->Point( DIM_CROSSBARO ) ) )
+ {
+ VECTOR2D featureLine( m_editedPoint->GetPosition() - dimension->GetOrigin() );
+ VECTOR2D crossBar( dimension->GetEnd() - dimension->GetOrigin() );
+
+ if( featureLine.Cross( crossBar ) > 0 )
+ dimension->SetHeight( -featureLine.EuclideanNorm() );
+ else
+ dimension->SetHeight( featureLine.EuclideanNorm() );
+ }
+
+ else if( isModified( m_editPoints->Point( DIM_CROSSBARF ) ) )
+ {
+ VECTOR2D featureLine( m_editedPoint->GetPosition() - dimension->GetEnd() );
+ VECTOR2D crossBar( dimension->GetEnd() - dimension->GetOrigin() );
+
+ if( featureLine.Cross( crossBar ) > 0 )
+ dimension->SetHeight( -featureLine.EuclideanNorm() );
+ else
+ dimension->SetHeight( featureLine.EuclideanNorm() );
+ }
+
+ else if( isModified( m_editPoints->Point( DIM_FEATUREGO ) ) )
+ {
+ dimension->SetOrigin( wxPoint( m_editedPoint->GetPosition().x, m_editedPoint->GetPosition().y ) );
+ m_editPoints->Point( DIM_CROSSBARO ).SetConstraint( new EC_LINE( m_editPoints->Point( DIM_CROSSBARO ),
+ m_editPoints->Point( DIM_FEATUREGO ) ) );
+ m_editPoints->Point( DIM_CROSSBARF ).SetConstraint( new EC_LINE( m_editPoints->Point( DIM_CROSSBARF ),
+ m_editPoints->Point( DIM_FEATUREDO ) ) );
+ }
+
+ else if( isModified( m_editPoints->Point( DIM_FEATUREDO ) ) )
+ {
+ dimension->SetEnd( wxPoint( m_editedPoint->GetPosition().x, m_editedPoint->GetPosition().y ) );
+ m_editPoints->Point( DIM_CROSSBARO ).SetConstraint( new EC_LINE( m_editPoints->Point( DIM_CROSSBARO ),
+ m_editPoints->Point( DIM_FEATUREGO ) ) );
+ m_editPoints->Point( DIM_CROSSBARF ).SetConstraint( new EC_LINE( m_editPoints->Point( DIM_CROSSBARF ),
+ m_editPoints->Point( DIM_FEATUREDO ) ) );
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+void POINT_EDITOR::finishItem() const
+{
+ EDA_ITEM* item = m_editPoints->GetParent();
+
+ if( item->Type() == PCB_ZONE_AREA_T )
+ {
+ ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
+
+ if( zone->IsFilled() )
+ getEditFrame<PCB_EDIT_FRAME>()->Fill_Zone( zone );
+ }
+}
+
+
+void POINT_EDITOR::updatePoints()
+{
+ EDA_ITEM* item = m_editPoints->GetParent();
+
+ switch( item->Type() )
+ {
+ case PCB_LINE_T:
+ case PCB_MODULE_EDGE_T:
+ {
+ const DRAWSEGMENT* segment = static_cast<const DRAWSEGMENT*>( item );
+ {
+ switch( segment->GetShape() )
+ {
+ case S_SEGMENT:
+ m_editPoints->Point( SEG_START ).SetPosition( segment->GetStart() );
+ m_editPoints->Point( SEG_END ).SetPosition( segment->GetEnd() );
+ break;
+
+ case S_ARC:
+ m_editPoints->Point( ARC_CENTER ).SetPosition( segment->GetCenter() );
+ m_editPoints->Point( ARC_START).SetPosition( segment->GetArcStart() );
+ m_editPoints->Point( ARC_END ).SetPosition( segment->GetArcEnd() );
+ break;
+
+ case S_CIRCLE:
+ m_editPoints->Point( CIRC_CENTER ).SetPosition( segment->GetCenter() );
+ m_editPoints->Point( CIRC_END ).SetPosition( segment->GetEnd() );
+ break;
+
+ default: // suppress warnings
+ break;
+ }
+
+ break;
+ }
+ }
+
+ case PCB_ZONE_AREA_T:
+ {
+ const ZONE_CONTAINER* zone = static_cast<const ZONE_CONTAINER*>( item );
+ const CPolyLine* outline = zone->Outline();
+
+ if( m_editPoints->PointsSize() != (unsigned) outline->GetCornersCount() )
+ {
+ getView()->Remove( m_editPoints.get() );
+ m_editPoints = EDIT_POINTS_FACTORY::Make( item, getView()->GetGAL() );
+ getView()->Add( m_editPoints.get() );
+ }
+ else
+ {
+ for( int i = 0; i < outline->GetCornersCount(); ++i )
+ m_editPoints->Point( i ).SetPosition( outline->GetPos( i ) );
+ }
+
+ break;
+ }
+
+ case PCB_DIMENSION_T:
+ {
+ const DIMENSION* dimension = static_cast<const DIMENSION*>( item );
+
+ m_editPoints->Point( DIM_CROSSBARO ).SetPosition( dimension->m_crossBarO );
+ m_editPoints->Point( DIM_CROSSBARF ).SetPosition( dimension->m_crossBarF );
+ m_editPoints->Point( DIM_FEATUREGO ).SetPosition( dimension->m_featureLineGO );
+ m_editPoints->Point( DIM_FEATUREDO ).SetPosition( dimension->m_featureLineDO );
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+void POINT_EDITOR::setEditedPoint( EDIT_POINT* aPoint )
+{
+ KIGFX::VIEW_CONTROLS* controls = getViewControls();
+
+ if( aPoint )
+ {
+ controls->ForceCursorPosition( true, aPoint->GetPosition() );
+ controls->ShowCursor( true );
+ controls->SetSnapping( true );
+ }
+ else
+ {
+ controls->ShowCursor( false );
+ controls->SetSnapping( false );
+ controls->ForceCursorPosition( false );
+ }
+
+ m_editedPoint = aPoint;
+}
+
+
+void POINT_EDITOR::setAltConstraint( bool aEnabled )
+{
+ if( aEnabled )
+ {
+ EDIT_LINE* line = dynamic_cast<EDIT_LINE*>( m_editedPoint );
+
+ if( line )
+ {
+ if( m_editPoints->GetParent()->Type() == PCB_ZONE_AREA_T )
+ m_altConstraint.reset( (EDIT_CONSTRAINT<EDIT_POINT>*)( new EC_CONVERGING( *line, *m_editPoints ) ) );
+ }
+ else
+ {
+ // Find a proper constraining point for 45 degrees mode
+ m_altConstrainer = get45DegConstrainer();
+ m_altConstraint.reset( new EC_45DEGREE( *m_editedPoint, m_altConstrainer ) );
+ }
+ }
+ else
+ {
+ m_altConstraint.reset();
+ }
+}
+
+
+EDIT_POINT POINT_EDITOR::get45DegConstrainer() const
+{
+ EDA_ITEM* item = m_editPoints->GetParent();
+
+ switch( item->Type() )
+ {
+ case PCB_LINE_T:
+ case PCB_MODULE_EDGE_T:
+ {
+ const DRAWSEGMENT* segment = static_cast<const DRAWSEGMENT*>( item );
+ {
+ switch( segment->GetShape() )
+ {
+ case S_SEGMENT:
+ return *( m_editPoints->Next( *m_editedPoint ) ); // select the other end of line
+
+ case S_ARC:
+ case S_CIRCLE:
+ return m_editPoints->Point( CIRC_CENTER );
+
+ default: // suppress warnings
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case PCB_DIMENSION_T:
+ {
+ // Constraint for crossbar
+ if( isModified( m_editPoints->Point( DIM_FEATUREGO ) ) )
+ return m_editPoints->Point( DIM_FEATUREDO );
+
+ else if( isModified( m_editPoints->Point( DIM_FEATUREDO ) ) )
+ return m_editPoints->Point( DIM_FEATUREGO );
+
+ else
+ return EDIT_POINT( m_editedPoint->GetPosition() ); // no constraint
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ // In any other case we may align item to its original position
+ return m_original;
+}
+
+
+void POINT_EDITOR::addCorner( const VECTOR2I& aBreakPoint )
+{
+ EDA_ITEM* item = m_editPoints->GetParent();
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ if( item->Type() == PCB_ZONE_AREA_T )
+ {
+ getEditFrame<PCB_BASE_FRAME>()->OnModify();
+ getEditFrame<PCB_BASE_FRAME>()->SaveCopyInUndoList( selection.items, UR_CHANGED );
+
+ ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
+ CPolyLine* outline = zone->Outline();
+
+ // Handle the last segment, so other segments can be easily handled in a loop
+ unsigned int nearestIdx = outline->GetCornersCount() - 1, nextNearestIdx = 0;
+ SEG side( VECTOR2I( outline->GetPos( nearestIdx ) ),
+ VECTOR2I( outline->GetPos( nextNearestIdx ) ) );
+ unsigned int nearestDist = side.Distance( aBreakPoint );
+
+ for( int i = 0; i < outline->GetCornersCount() - 1; ++i )
+ {
+ side = SEG( VECTOR2I( outline->GetPos( i ) ), VECTOR2I( outline->GetPos( i + 1 ) ) );
+
+ unsigned int distance = side.Distance( aBreakPoint );
+ if( distance < nearestDist )
+ {
+ nearestDist = distance;
+ nearestIdx = i;
+ nextNearestIdx = i + 1;
+ }
+ }
+
+ // Find the point on the closest segment
+ VECTOR2I sideOrigin( outline->GetPos( nearestIdx ) );
+ VECTOR2I sideEnd( outline->GetPos( nextNearestIdx ) );
+ SEG nearestSide( sideOrigin, sideEnd );
+ VECTOR2I nearestPoint = nearestSide.NearestPoint( aBreakPoint );
+
+ // Do not add points that have the same coordinates as ones that already belong to polygon
+ // instead, add a point in the middle of the side
+ if( nearestPoint == sideOrigin || nearestPoint == sideEnd )
+ nearestPoint = ( sideOrigin + sideEnd ) / 2;
+
+ outline->InsertCorner( nearestIdx, nearestPoint.x, nearestPoint.y );
+ }
+
+ else if( item->Type() == PCB_LINE_T || item->Type() == PCB_MODULE_EDGE_T )
+ {
+ bool moduleEdge = item->Type() == PCB_MODULE_EDGE_T;
+ PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
+
+ frame->OnModify();
+
+ if( moduleEdge )
+ frame->SaveCopyInUndoList( getModel<BOARD>()->m_Modules, UR_MODEDIT );
+ else
+ frame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+
+ DRAWSEGMENT* segment = static_cast<DRAWSEGMENT*>( item );
+
+ if( segment->GetShape() == S_SEGMENT )
+ {
+ SEG seg( segment->GetStart(), segment->GetEnd() );
+ VECTOR2I nearestPoint = seg.NearestPoint( aBreakPoint );
+
+ // Move the end of the line to the break point..
+ segment->SetEnd( wxPoint( nearestPoint.x, nearestPoint.y ) );
+
+ // and add another one starting from the break point
+ DRAWSEGMENT* newSegment;
+
+ if( moduleEdge )
+ {
+ EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( segment );
+ assert( segment->GetParent()->Type() == PCB_MODULE_T );
+ newSegment = new EDGE_MODULE( *edge );
+ edge->SetLocalCoord();
+ }
+ else
+ {
+ newSegment = new DRAWSEGMENT( *segment );
+ }
+
+ newSegment->ClearSelected();
+ newSegment->SetStart( wxPoint( nearestPoint.x, nearestPoint.y ) );
+ newSegment->SetEnd( wxPoint( seg.B.x, seg.B.y ) );
+
+ if( moduleEdge )
+ {
+ static_cast<EDGE_MODULE*>( newSegment )->SetLocalCoord();
+ getModel<BOARD>()->m_Modules->Add( newSegment );
+ }
+ else
+ {
+ getModel<BOARD>()->Add( newSegment );
+ }
+
+ getView()->Add( newSegment );
+ }
+ }
+}
+
+
+void POINT_EDITOR::removeCorner( EDIT_POINT* aPoint )
+{
+ EDA_ITEM* item = m_editPoints->GetParent();
+
+ if( item->Type() == PCB_ZONE_AREA_T )
+ {
+ const SELECTION& selection = m_selectionTool->GetSelection();
+ PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
+
+ ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
+ CPolyLine* outline = zone->Outline();
+
+ for( int i = 0; i < outline->GetCornersCount(); ++i )
+ {
+ if( VECTOR2I( outline->GetPos( i ) ) == aPoint->GetPosition() )
+ {
+ frame->OnModify();
+ frame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+ outline->DeleteCorner( i );
+ setEditedPoint( NULL );
+ break;
+ }
+ }
+ }
+}
+
+
+void POINT_EDITOR::SetTransitions()
+{
+ Go( &POINT_EDITOR::OnSelectionChange, SELECTION_TOOL::SelectedEvent );
+ Go( &POINT_EDITOR::OnSelectionChange, SELECTION_TOOL::UnselectedEvent );
+}
+
+
+bool POINT_EDITOR::addCornerCondition( const SELECTION& aSelection )
+{
+ if( aSelection.Size() != 1 )
+ return false;
+
+ BOARD_ITEM* item = aSelection.Item<BOARD_ITEM>( 0 );
+
+ // Works only for zones and line segments
+ return item->Type() == PCB_ZONE_AREA_T ||
+ ( ( item->Type() == PCB_LINE_T || item->Type() == PCB_MODULE_EDGE_T ) &&
+ static_cast<DRAWSEGMENT*>( item )->GetShape() == S_SEGMENT );
+}
+
+
+bool POINT_EDITOR::removeCornerCondition( const SELECTION& )
+{
+ if( !m_editPoints )
+ return false;
+
+ EDA_ITEM* item = m_editPoints->GetParent();
+
+ if( item->Type() != PCB_ZONE_AREA_T )
+ return false;
+
+ ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
+
+ if( zone->GetNumCorners() <= 3 )
+ return false;
+
+ // Remove corner does not work with lines
+ if( dynamic_cast<EDIT_LINE*>( m_editedPoint ) )
+ return false;
+
+ return m_editedPoint != NULL;
+}
diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h
new file mode 100644
index 0000000..fc4c6a0
--- /dev/null
+++ b/pcbnew/tools/point_editor.h
@@ -0,0 +1,120 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __POINT_EDITOR_H
+#define __POINT_EDITOR_H
+
+#include <boost/shared_ptr.hpp>
+
+#include <tool/tool_interactive.h>
+#include "edit_points.h"
+
+class SELECTION_TOOL;
+
+/**
+ * Class POINT_EDITOR
+ *
+ * Tool that displays edit points allowing to modify items by dragging the points.
+ */
+class POINT_EDITOR : public TOOL_INTERACTIVE
+{
+public:
+ POINT_EDITOR();
+
+ /// @copydoc TOOL_INTERACTIVE::Reset()
+ void Reset( RESET_REASON aReason );
+
+ /// @copydoc TOOL_INTERACTIVE::Init()
+ bool Init();
+
+ /**
+ * Function OnSelected()
+ *
+ * Change selection event handler.
+ */
+ int OnSelectionChange( const TOOL_EVENT& aEvent );
+
+ ///> Sets up handlers for various events.
+ void SetTransitions();
+
+private:
+ ///> Selection tool used for obtaining selected items
+ SELECTION_TOOL* m_selectionTool;
+
+ ///> Currently edited point, NULL if there is none.
+ EDIT_POINT* m_editedPoint;
+
+ ///> Original position for the current drag point.
+ EDIT_POINT m_original;
+
+ ///> Currently available edit points.
+ boost::shared_ptr<EDIT_POINTS> m_editPoints;
+
+ // Alternative constraint, enabled while a modifier key is held
+ boost::shared_ptr<EDIT_CONSTRAINT<EDIT_POINT> > m_altConstraint;
+
+ // EDIT_POINT for alternative constraint mode
+ EDIT_POINT m_altConstrainer;
+
+ ///> Updates item's points with edit points.
+ void updateItem() const;
+
+ ///> Applies the last changes to the edited item.
+ void finishItem() const;
+
+ ///> Updates edit points with item's points.
+ void updatePoints();
+
+ ///> Updates which point is being edited.
+ void updateEditedPoint( const TOOL_EVENT& aEvent );
+
+ ///> Sets the current point being edited. NULL means none.
+ void setEditedPoint( EDIT_POINT* aPoint );
+
+ ///> Returns true if aPoint is the currently modified point.
+ inline bool isModified( const EDIT_POINT& aPoint ) const
+ {
+ return m_editedPoint == &aPoint;
+ }
+
+ ///> Sets up an alternative constraint (typically enabled upon a modifier key being pressed).
+ void setAltConstraint( bool aEnabled );
+
+ ///> Returns a point that should be used as a constrainer for 45 degrees mode.
+ EDIT_POINT get45DegConstrainer() const;
+
+ ///> Adds a new edit point on a zone outline/line.
+ void addCorner( const VECTOR2I& aPoint );
+
+ ///> Removes a corner.
+ void removeCorner( EDIT_POINT* aPoint );
+
+ ///> Condition to display "Create corner" context menu entry.
+ static bool addCornerCondition( const SELECTION& aSelection );
+
+ ///> Condition to display "Remove corner" context menu entry.
+ bool removeCornerCondition( const SELECTION& aSelection );
+};
+
+#endif
diff --git a/pcbnew/tools/selection_area.cpp b/pcbnew/tools/selection_area.cpp
new file mode 100644
index 0000000..8bfdcec
--- /dev/null
+++ b/pcbnew/tools/selection_area.cpp
@@ -0,0 +1,63 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 CERN
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "selection_area.h"
+#include <gal/graphics_abstraction_layer.h>
+#include <gal/color4d.h>
+
+using namespace KIGFX;
+
+const BOX2I SELECTION_AREA::ViewBBox() const
+{
+ BOX2I tmp;
+
+ tmp.SetOrigin( m_origin );
+ tmp.SetEnd( m_end );
+ tmp.Normalize();
+ return tmp;
+}
+
+
+void SELECTION_AREA::ViewGetLayers( int aLayers[], int& aCount ) const
+{
+ aLayers[0] = SelectionLayer;
+ aCount = 1;
+}
+
+
+void SELECTION_AREA::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
+{
+ aGal->SetLineWidth( 1.0 );
+ aGal->SetStrokeColor( COLOR4D( 1.0, 1.0, 0.4, 1.0 ) );
+ aGal->SetFillColor( COLOR4D( 0.3, 0.3, 0.5, 0.3 ) );
+ aGal->SetIsStroke( true );
+ aGal->SetIsFill( true );
+ aGal->DrawRectangle( m_origin, m_end );
+}
+
+
+SELECTION_AREA::SELECTION_AREA() :
+ EDA_ITEM( NOT_USED ) // this item is never added to a BOARD so it needs no type.
+{
+}
diff --git a/pcbnew/tools/selection_area.h b/pcbnew/tools/selection_area.h
new file mode 100644
index 0000000..737e7be
--- /dev/null
+++ b/pcbnew/tools/selection_area.h
@@ -0,0 +1,84 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 CERN
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __SELECTION_AREA_H
+#define __SELECTION_AREA_H
+
+#include <base_struct.h>
+#include <layers_id_colors_and_visibility.h>
+#include <math/box2.h>
+
+namespace KIGFX
+{
+class GAL;
+}
+
+/**
+ * Class SELECTION_AREA
+ *
+ * Represents a selection area (currently a rectangle) in a VIEW.
+ */
+class SELECTION_AREA : public EDA_ITEM
+{
+public:
+ static const int SelectionLayer = ITEM_GAL_LAYER( GP_OVERLAY );
+
+ SELECTION_AREA();
+ ~SELECTION_AREA() {};
+
+ virtual const BOX2I ViewBBox() const;
+
+ void ViewDraw( int aLayer, KIGFX::GAL* aGal ) const;
+
+ void ViewGetLayers( int aLayers[], int& aCount ) const;
+
+ void SetOrigin( VECTOR2I aOrigin )
+ {
+ m_origin = aOrigin;
+ }
+
+ void SetEnd( VECTOR2I aEnd )
+ {
+ m_end = aEnd;
+ }
+
+#if defined(DEBUG)
+ void Show( int x, std::ostream& st ) const
+ {
+ }
+#endif
+
+ /** Get class name
+ * @return string "SELECTION_AREA"
+ */
+ virtual wxString GetClass() const
+ {
+ return wxT( "SELECTION_AREA" );
+ }
+
+private:
+ VECTOR2I m_origin, m_end;
+};
+
+#endif
diff --git a/pcbnew/tools/selection_conditions.cpp b/pcbnew/tools/selection_conditions.cpp
new file mode 100644
index 0000000..55cbc77
--- /dev/null
+++ b/pcbnew/tools/selection_conditions.cpp
@@ -0,0 +1,256 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "selection_conditions.h"
+#include "selection_tool.h"
+#include <class_board_connected_item.h>
+
+#include <boost/bind.hpp>
+
+
+bool SELECTION_CONDITIONS::NotEmpty( const SELECTION& aSelection )
+{
+ return !aSelection.Empty();
+}
+
+
+bool SELECTION_CONDITIONS::OnlyConnectedItems( const SELECTION& aSelection )
+{
+ if( aSelection.Empty() )
+ return false;
+
+ for( int i = 0; i < aSelection.Size(); ++i )
+ {
+ KICAD_T type = aSelection.Item<EDA_ITEM>( i )->Type();
+
+ if( type != PCB_PAD_T && type != PCB_VIA_T && type != PCB_TRACE_T && type != PCB_ZONE_T )
+ return false;
+ }
+
+ return true;
+}
+
+
+SELECTION_CONDITION SELECTION_CONDITIONS::SameNet( bool aAllowUnconnected )
+{
+ return boost::bind( &SELECTION_CONDITIONS::sameNetFunc, _1, aAllowUnconnected );
+}
+
+
+SELECTION_CONDITION SELECTION_CONDITIONS::SameLayer()
+{
+ return boost::bind( &SELECTION_CONDITIONS::sameLayerFunc, _1 );
+}
+
+
+SELECTION_CONDITION SELECTION_CONDITIONS::HasType( KICAD_T aType )
+{
+ return boost::bind( &SELECTION_CONDITIONS::hasTypeFunc, _1, aType );
+}
+
+
+SELECTION_CONDITION SELECTION_CONDITIONS::OnlyType( KICAD_T aType )
+{
+ return boost::bind( &SELECTION_CONDITIONS::onlyTypeFunc, _1, aType );
+}
+
+
+SELECTION_CONDITION SELECTION_CONDITIONS::OnlyTypes( const std::vector<KICAD_T>& aTypes )
+{
+ return boost::bind( &SELECTION_CONDITIONS::onlyTypesFunc, _1, aTypes );
+}
+
+
+SELECTION_CONDITION SELECTION_CONDITIONS::Count( int aNumber )
+{
+ return boost::bind( &SELECTION_CONDITIONS::countFunc, _1, aNumber );
+}
+
+
+SELECTION_CONDITION SELECTION_CONDITIONS::MoreThan( int aNumber )
+{
+ return boost::bind( &SELECTION_CONDITIONS::moreThanFunc, _1, aNumber );
+}
+
+
+SELECTION_CONDITION SELECTION_CONDITIONS::LessThan( int aNumber )
+{
+ return boost::bind( &SELECTION_CONDITIONS::lessThanFunc, _1, aNumber );
+}
+
+
+bool SELECTION_CONDITIONS::sameNetFunc( const SELECTION& aSelection, bool aAllowUnconnected )
+{
+ if( aSelection.Empty() )
+ return false;
+
+ int netcode = -1; // -1 stands for 'net code is not yet determined'
+
+ for( int i = 0; i < aSelection.Size(); ++i )
+ {
+ int current_netcode = -1;
+
+ const BOARD_CONNECTED_ITEM* item =
+ dynamic_cast<const BOARD_CONNECTED_ITEM*>( aSelection.Item<EDA_ITEM>( i ) );
+
+ if( item )
+ {
+ current_netcode = item->GetNetCode();
+ }
+ else
+ {
+ if( !aAllowUnconnected )
+ return false;
+ else
+ // if it is not a BOARD_CONNECTED_ITEM, treat it as if there was no net assigned
+ current_netcode = 0;
+ }
+
+ assert( current_netcode >= 0 );
+
+ if( netcode < 0 )
+ {
+ netcode = current_netcode;
+
+ if( netcode == NETINFO_LIST::UNCONNECTED && !aAllowUnconnected )
+ return false;
+ }
+ else if( netcode != current_netcode )
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+bool SELECTION_CONDITIONS::sameLayerFunc( const SELECTION& aSelection )
+{
+ if( aSelection.Empty() )
+ return false;
+
+ LSET layerSet;
+ layerSet.set();
+
+ for( int i = 0; i < aSelection.Size(); ++i )
+ {
+ const BOARD_ITEM* item = dynamic_cast<const BOARD_ITEM*>( aSelection.Item<EDA_ITEM>( i ) );
+
+ if( !item )
+ return false;
+
+ layerSet &= item->GetLayerSet();
+
+ if( !layerSet.any() ) // there are no common layers left
+ return false;
+ }
+
+ return true;
+}
+
+
+bool SELECTION_CONDITIONS::hasTypeFunc( const SELECTION& aSelection, KICAD_T aType )
+{
+ for( int i = 0; i < aSelection.Size(); ++i )
+ {
+ if( aSelection.Item<EDA_ITEM>( i )->Type() == aType )
+ return true;
+ }
+
+ return false;
+}
+
+
+bool SELECTION_CONDITIONS::onlyTypeFunc( const SELECTION& aSelection, KICAD_T aType )
+{
+ if( aSelection.Empty() )
+ return false;
+
+ for( int i = 0; i < aSelection.Size(); ++i )
+ {
+ if( aSelection.Item<EDA_ITEM>( i )->Type() != aType )
+ return false;
+ }
+
+ return true;
+}
+
+
+bool SELECTION_CONDITIONS::onlyTypesFunc( const SELECTION& aSelection, const std::vector<KICAD_T>& aTypes )
+{
+ if( aSelection.Empty() )
+ return false;
+
+ for( int i = 0; i < aSelection.Size(); ++i )
+ {
+ bool valid = false;
+
+ for( std::vector<KICAD_T>::const_iterator it = aTypes.begin(); it != aTypes.end(); ++it )
+ {
+ if( aSelection.Item<EDA_ITEM>( i )->Type() == *it )
+ {
+ valid = true;
+ break;
+ }
+ }
+
+ if( !valid )
+ return false;
+ }
+
+ return true;
+}
+
+
+bool SELECTION_CONDITIONS::countFunc( const SELECTION& aSelection, int aNumber )
+{
+ return aSelection.Size() == aNumber;
+}
+
+
+bool SELECTION_CONDITIONS::moreThanFunc( const SELECTION& aSelection, int aNumber )
+{
+ return aSelection.Size() > aNumber;
+}
+
+
+bool SELECTION_CONDITIONS::lessThanFunc( const SELECTION& aSelection, int aNumber )
+{
+ return aSelection.Size() < aNumber;
+}
+
+
+SELECTION_CONDITION operator||( const SELECTION_CONDITION& aConditionA,
+ const SELECTION_CONDITION& aConditionB )
+{
+ return boost::bind( &SELECTION_CONDITIONS::orFunc, aConditionA, aConditionB, _1 );
+}
+
+
+SELECTION_CONDITION operator&&( const SELECTION_CONDITION& aConditionA,
+ const SELECTION_CONDITION& aConditionB )
+{
+ return boost::bind( &SELECTION_CONDITIONS::andFunc, aConditionA, aConditionB, _1 );
+}
diff --git a/pcbnew/tools/selection_conditions.h b/pcbnew/tools/selection_conditions.h
new file mode 100644
index 0000000..0c508a8
--- /dev/null
+++ b/pcbnew/tools/selection_conditions.h
@@ -0,0 +1,193 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef SELECTION_CONDITIONS_H_
+#define SELECTION_CONDITIONS_H_
+
+#include <boost/function.hpp>
+#include <core/typeinfo.h>
+#include <vector>
+
+struct SELECTION;
+
+///> Functor type that checks a specific condition for selected items.
+typedef boost::function<bool (const SELECTION&)> SELECTION_CONDITION;
+
+SELECTION_CONDITION operator||( const SELECTION_CONDITION& aConditionA,
+ const SELECTION_CONDITION& aConditionB );
+
+SELECTION_CONDITION operator&&( const SELECTION_CONDITION& aConditionA,
+ const SELECTION_CONDITION& aConditionB );
+
+
+/**
+ * Class that groups generic conditions for selected items.
+ */
+class SELECTION_CONDITIONS
+{
+public:
+ /**
+ * Function ShowAlways
+ * The default condition function (always returns true).
+ * @param aSelection is the selection to be tested.
+ * @return Always true;
+ */
+ static bool ShowAlways( const SELECTION& aSelection )
+ {
+ return true;
+ }
+
+ /**
+ * Function NotEmpty
+ * Tests if there are any items selected.
+ * @param aSelection is the selection to be tested.
+ * @return True if there is at least one item selected.
+ */
+ static bool NotEmpty( const SELECTION& aSelection );
+
+ /**
+ * Function OnlyConnectedItems
+ * Tests if selection contains exclusively connected items (pads, tracks, vias, zones).
+ * @param aSelection is the selection to be tested.
+ * @return True if there are only connected items connected.
+ */
+ static bool OnlyConnectedItems( const SELECTION& aSelection );
+
+ /**
+ * Function SameNet
+ * Creates a functor that tests if selection contains items belonging to the same net or are
+ * unconnected if aAllowUnconnected == true.
+ * @param aAllowUnconnected determines if unconnected items (with no net code assigned) should
+ * be treated as connected to the same net.
+ * @return Functor testing if selected items are belonging to the same net.
+ */
+ static SELECTION_CONDITION SameNet( bool aAllowUnconnected = false );
+
+ /**
+ * Function SameLayer
+ * Creates a functor that tests if selection contains items that belong exclusively to the same
+ * layer. In case of items belonging to multiple layers, it is enough to have a single common
+ * layer with other items.
+ * @return Functor testing if selected items share at least one common layer.
+ */
+ static SELECTION_CONDITION SameLayer();
+
+ /**
+ * Function HasType
+ * Creates a functor that tests if among the selected items there is at least one of a given type.
+ * @param aType is the type that is searched.
+ * @return Functor testing for presence of items of a given type.
+ */
+ static SELECTION_CONDITION HasType( KICAD_T aType );
+
+ /**
+ * Function OnlyType
+ * Creates a functor that tests if the selected items are *only* of given type.
+ * @param aType is the type that is searched.
+ * @return Functor testing if selected items are exclusively of one type.
+ */
+ static SELECTION_CONDITION OnlyType( KICAD_T aType );
+
+ /**
+ * Function OnlyTypes
+ * Creates a functor that tests if the selected items are *only* of given types.
+ * @param aType is a vector containing types that are searched.
+ * @return Functor testing if selected items are exclusively of the requested types.
+ */
+ static SELECTION_CONDITION OnlyTypes( const std::vector<KICAD_T>& aTypes );
+
+ /**
+ * Function Count
+ * Creates a functor that tests if the number of selected items is equal to the value given as
+ * parameter.
+ * @param aNumber is the number of expected items.
+ * @return Functor testing if the number of selected items is equal aNumber.
+ */
+ static SELECTION_CONDITION Count( int aNumber );
+
+ /**
+ * Function MoreThan
+ * Creates a functor that tests if the number of selected items is greater than the value given
+ * as parameter.
+ * @param aNumber is the number used for comparison.
+ * @return Functor testing if the number of selected items is greater than aNumber.
+ */
+ static SELECTION_CONDITION MoreThan( int aNumber );
+
+ /**
+ * Function LessThan
+ * Creates a functor that tests if the number of selected items is smaller than the value given
+ * as parameter.
+ * @param aNumber is the number used for comparison.
+ * @return Functor testing if the number of selected items is smaller than aNumber.
+ */
+ static SELECTION_CONDITION LessThan( int aNumber );
+
+private:
+ ///> Helper function used by SameNet()
+ static bool sameNetFunc( const SELECTION& aSelection, bool aAllowUnconnected );
+
+ ///> Helper function used by SameLayer()
+ static bool sameLayerFunc( const SELECTION& aSelection );
+
+ ///> Helper function used by HasType()
+ static bool hasTypeFunc( const SELECTION& aSelection, KICAD_T aType );
+
+ ///> Helper function used by OnlyType()
+ static bool onlyTypeFunc( const SELECTION& aSelection, KICAD_T aType );
+
+ ///> Helper function used by OnlyTypes()
+ static bool onlyTypesFunc( const SELECTION& aSelection, const std::vector<KICAD_T>& aTypes );
+
+ ///> Helper function used by Count()
+ static bool countFunc( const SELECTION& aSelection, int aNumber );
+
+ ///> Helper function used by MoreThan()
+ static bool moreThanFunc( const SELECTION& aSelection, int aNumber );
+
+ ///> Helper function used by LessThan()
+ static bool lessThanFunc( const SELECTION& aSelection, int aNumber );
+
+ ///> Helper function used by operator||
+ static bool orFunc( const SELECTION_CONDITION& aConditionA,
+ const SELECTION_CONDITION& aConditionB, const SELECTION& aSelection )
+ {
+ return aConditionA( aSelection ) || aConditionB( aSelection );
+ }
+
+ ///> Helper function used by operator&&
+ static bool andFunc( const SELECTION_CONDITION& aConditionA,
+ const SELECTION_CONDITION& aConditionB, const SELECTION& aSelection )
+ {
+ return aConditionA( aSelection ) && aConditionB( aSelection );
+ }
+
+ friend SELECTION_CONDITION operator||( const SELECTION_CONDITION& aConditionA,
+ const SELECTION_CONDITION& aConditionB );
+
+ friend SELECTION_CONDITION operator&&( const SELECTION_CONDITION& aConditionA,
+ const SELECTION_CONDITION& aConditionB );
+};
+
+#endif /* SELECTION_CONDITIONS_H_ */
diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp
new file mode 100644
index 0000000..fb18e54
--- /dev/null
+++ b/pcbnew/tools/selection_tool.cpp
@@ -0,0 +1,1459 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013-2016 CERN
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include <limits>
+
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+
+#include <class_board.h>
+#include <class_board_item.h>
+#include <class_track.h>
+#include <class_module.h>
+#include <class_pcb_text.h>
+#include <class_drawsegment.h>
+
+#include <wxPcbStruct.h>
+#include <collectors.h>
+#include <confirm.h>
+#include <dialog_find.h>
+
+#include <class_draw_panel_gal.h>
+#include <view/view_controls.h>
+#include <view/view_group.h>
+#include <painter.h>
+
+#include <tool/tool_event.h>
+#include <tool/tool_manager.h>
+#include <ratsnest_data.h>
+
+#include "selection_tool.h"
+#include "selection_area.h"
+#include "zoom_menu.h"
+#include "grid_menu.h"
+#include "bright_box.h"
+#include "common_actions.h"
+
+class SELECT_MENU: public CONTEXT_MENU
+{
+public:
+ SELECT_MENU()
+ {
+ Add( COMMON_ACTIONS::selectConnection );
+ Add( COMMON_ACTIONS::selectCopper );
+ Add( COMMON_ACTIONS::selectNet );
+ }
+};
+
+
+SELECTION_TOOL::SELECTION_TOOL() :
+ TOOL_INTERACTIVE( "pcbnew.InteractiveSelection" ),
+ m_frame( NULL ), m_additive( false ), m_multiple( false ), m_editModules( false ),
+ m_locked( true ), m_menu( this ), m_contextMenu( NULL ), m_selectMenu( NULL ),
+ m_zoomMenu( NULL ), m_gridMenu( NULL )
+{
+ // Do not leave uninitialized members:
+ m_preliminary = false;
+}
+
+
+SELECTION_TOOL::~SELECTION_TOOL()
+{
+ delete m_selection.group;
+ delete m_contextMenu;
+ delete m_selectMenu;
+ delete m_zoomMenu;
+ delete m_gridMenu;
+}
+
+
+bool SELECTION_TOOL::Init()
+{
+ m_selection.group = new KIGFX::VIEW_GROUP;
+
+ m_selectMenu = new SELECT_MENU;
+ m_selectMenu->SetTool( this );
+
+ m_menu.AddMenu( m_selectMenu, _( "Select..." ), false,
+ ( SELECTION_CONDITIONS::OnlyType( PCB_VIA_T ) || SELECTION_CONDITIONS::OnlyType( PCB_TRACE_T ) ) &&
+ SELECTION_CONDITIONS::Count( 1 ) );
+
+ m_menu.AddSeparator( SELECTION_CONDITIONS::ShowAlways, 1000 );
+
+ m_menu.AddItem( COMMON_ACTIONS::zoomCenter, SELECTION_CONDITIONS::ShowAlways, 1000 );
+ m_menu.AddItem( COMMON_ACTIONS::zoomIn, SELECTION_CONDITIONS::ShowAlways, 1000 );
+ m_menu.AddItem( COMMON_ACTIONS::zoomOut , SELECTION_CONDITIONS::ShowAlways, 1000 );
+ m_menu.AddItem( COMMON_ACTIONS::zoomFitScreen , SELECTION_CONDITIONS::ShowAlways, 1000 );
+
+ PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
+
+ m_zoomMenu = new ZOOM_MENU( frame );
+ m_menu.AddMenu( m_zoomMenu, _( "Zoom" ), false, SELECTION_CONDITIONS::ShowAlways, 1000 );
+
+ m_gridMenu = new GRID_MENU( frame );
+ m_menu.AddMenu( m_gridMenu, _( "Grid" ), false, SELECTION_CONDITIONS::ShowAlways, 1000 );
+
+ return true;
+}
+
+
+void SELECTION_TOOL::Reset( RESET_REASON aReason )
+{
+ m_frame = getEditFrame<PCB_BASE_FRAME>();
+ m_locked = true;
+ m_preliminary = true;
+
+ if( aReason == TOOL_BASE::MODEL_RELOAD )
+ {
+ // Remove pointers to the selected items from containers
+ // without changing their properties (as they are already deleted
+ // while a new board is loaded)
+ m_selection.clear();
+ getView()->GetPainter()->GetSettings()->SetHighlight( false );
+ }
+ else
+ // Restore previous properties of selected items and remove them from containers
+ clearSelection();
+
+ // Reinsert the VIEW_GROUP, in case it was removed from the VIEW
+ getView()->Remove( m_selection.group );
+ getView()->Add( m_selection.group );
+}
+
+
+int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
+{
+ // Main loop: keep receiving events
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ // Should selected items be added to the current selection or
+ // become the new selection (discarding previously selected items)
+ m_additive = evt->Modifier( MD_SHIFT );
+
+ // single click? Select single object
+ if( evt->IsClick( BUT_LEFT ) )
+ {
+ if( evt->Modifier( MD_CTRL ) && !m_editModules )
+ {
+ m_toolMgr->RunAction( COMMON_ACTIONS::highlightNet, true );
+ }
+ else
+ {
+ if( !m_additive )
+ clearSelection();
+
+ selectPoint( evt->Position() );
+ }
+ }
+
+ // right click? if there is any object - show the context menu
+ else if( evt->IsClick( BUT_RIGHT ) )
+ {
+ bool emptySelection = m_selection.Empty();
+
+ if( emptySelection )
+ selectPoint( evt->Position() );
+
+ delete m_contextMenu;
+ m_contextMenu = m_menu.Generate( m_selection );
+
+ if( m_contextMenu->GetMenuItemCount() > 0 )
+ SetContextMenu( m_contextMenu, CMENU_NOW );
+
+ m_preliminary = emptySelection;
+ }
+
+ // double click? Display the properties window
+ else if( evt->IsDblClick( BUT_LEFT ) )
+ {
+ if( m_selection.Empty() )
+ selectPoint( evt->Position() );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::properties );
+ }
+
+ // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
+ else if( evt->IsDrag( BUT_LEFT ) )
+ {
+ if( m_additive )
+ {
+ m_preliminary = false;
+
+ selectMultiple();
+ }
+ else if( m_selection.Empty() )
+ {
+ m_preliminary = false;
+
+ // There is nothing selected, so try to select something
+ if( !selectCursor() )
+ {
+ // If nothings has been selected or user wants to select more
+ // draw the selection box
+ selectMultiple();
+ }
+ else
+ {
+ m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
+ }
+ }
+
+ else
+ {
+ // Check if dragging has started within any of selected items bounding box
+ if( selectionContains( evt->Position() ) )
+ {
+ // Yes -> run the move tool and wait till it finishes
+ m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
+ }
+ else
+ {
+ // No -> clear the selection list
+ clearSelection();
+ }
+ }
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::selectionCursor ) )
+ {
+ selectCursor( true );
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::find ) )
+ {
+ find( *evt );
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::findMove ) )
+ {
+ findMove( *evt );
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::selectItem ) )
+ {
+ SelectItem( *evt );
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::unselectItem ) )
+ {
+ UnselectItem( *evt );
+ }
+
+ else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO ||
+ evt->IsAction( &COMMON_ACTIONS::selectionClear ) )
+ {
+ clearSelection();
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::selectConnection ) )
+ {
+ selectConnection( *evt );
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::selectCopper ) )
+ {
+ selectCopper( *evt );
+ }
+
+ else if( evt->IsAction( &COMMON_ACTIONS::selectNet ) )
+ {
+ selectNet( *evt );
+ }
+
+ else if( evt->Action() == TA_CONTEXT_MENU_CLOSED )
+ {
+ if( m_preliminary )
+ clearSelection();
+
+ if( evt->Parameter<CONTEXT_MENU*>() == m_contextMenu )
+ {
+ delete m_contextMenu;
+ m_contextMenu = NULL;
+ }
+ }
+ }
+
+ // This tool is supposed to be active forever
+ assert( false );
+
+ return 0;
+}
+
+
+const SELECTION& SELECTION_TOOL::GetSelection()
+{
+ // The selected items list has been requested, so it is no longer preliminary
+ m_preliminary = false;
+
+ // Filter out not modifiable items
+ for( int i = 0; i < m_selection.Size(); )
+ {
+ BOARD_ITEM* item = m_selection.Item<BOARD_ITEM>( i );
+
+ if( !modifiable( item ) )
+ {
+ m_selection.items.RemovePicker( i );
+ m_selection.group->Remove( item );
+ }
+ else
+ {
+ ++i;
+ }
+ }
+
+ return m_selection;
+}
+
+
+void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem )
+{
+ if( aItem->IsSelected() )
+ {
+ unselect( aItem );
+
+ // Inform other potentially interested tools
+ m_toolMgr->ProcessEvent( UnselectedEvent );
+ }
+ else
+ {
+ if( !m_additive )
+ clearSelection();
+
+ // Prevent selection of invisible or inactive items
+ if( selectable( aItem ) )
+ {
+ select( aItem );
+
+ // Inform other potentially interested tools
+ m_toolMgr->ProcessEvent( SelectedEvent );
+ }
+ }
+}
+
+
+bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag )
+{
+ BOARD_ITEM* item;
+ GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide();
+ GENERAL_COLLECTOR collector;
+
+ if( m_editModules )
+ collector.Collect( getModel<BOARD>(), GENERAL_COLLECTOR::ModuleItems,
+ wxPoint( aWhere.x, aWhere.y ), guide );
+ else
+ collector.Collect( getModel<BOARD>(), GENERAL_COLLECTOR::AllBoardItems,
+ wxPoint( aWhere.x, aWhere.y ), guide );
+
+ bool anyCollected = collector.GetCount() != 0;
+
+ // Remove unselectable items
+ for( int i = collector.GetCount() - 1; i >= 0; --i )
+ {
+ if( !selectable( collector[i] ) || ( aOnDrag && collector[i]->IsLocked() ) )
+ collector.Remove( i );
+ }
+
+ switch( collector.GetCount() )
+ {
+ case 0:
+ if( !m_additive && anyCollected )
+ clearSelection();
+
+ return false;
+
+ case 1:
+ toggleSelection( collector[0] );
+
+ return true;
+
+ default:
+ // Apply some ugly heuristics to avoid disambiguation menus whenever possible
+ guessSelectionCandidates( collector );
+
+ // Let's see if there is still disambiguation in selection..
+ if( collector.GetCount() == 1 )
+ {
+ toggleSelection( collector[0] );
+
+ return true;
+ }
+ else if( collector.GetCount() > 1 )
+ {
+ if( aOnDrag )
+ Wait( TOOL_EVENT( TC_ANY, TA_MOUSE_UP, BUT_LEFT ) );
+
+ item = disambiguationMenu( &collector );
+
+ if( item )
+ {
+ toggleSelection( item );
+
+ return true;
+ }
+ }
+ break;
+ }
+
+ return false;
+}
+
+
+bool SELECTION_TOOL::selectCursor( bool aSelectAlways )
+{
+ if( aSelectAlways || m_selection.Empty() )
+ {
+ clearSelection();
+ selectPoint( getViewControls()->GetCursorPosition() );
+ }
+
+ return !m_selection.Empty();
+}
+
+
+bool SELECTION_TOOL::selectMultiple()
+{
+ bool cancelled = false; // Was the tool cancelled while it was running?
+ m_multiple = true; // Multiple selection mode is active
+ KIGFX::VIEW* view = getView();
+ getViewControls()->SetAutoPan( true );
+
+ SELECTION_AREA area;
+ view->Add( &area );
+
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ if( evt->IsCancel() )
+ {
+ cancelled = true;
+ break;
+ }
+
+ if( evt->IsDrag( BUT_LEFT ) )
+ {
+ if( !m_additive )
+ clearSelection();
+
+ // Start drawing a selection box
+ area.SetOrigin( evt->DragOrigin() );
+ area.SetEnd( evt->Position() );
+ area.ViewSetVisible( true );
+ area.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ if( evt->IsMouseUp( BUT_LEFT ) )
+ {
+ // End drawing the selection box
+ area.ViewSetVisible( false );
+
+ // Mark items within the selection box as selected
+ std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
+ BOX2I selectionBox = area.ViewBBox();
+ view->Query( selectionBox, selectedItems ); // Get the list of selected items
+
+ std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>::iterator it, it_end;
+
+ for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it )
+ {
+ BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first );
+
+ // Add only those items that are visible and fully within the selection box
+ if( !item->IsSelected() && selectable( item ) &&
+ selectionBox.Contains( item->ViewBBox() ) )
+ {
+ select( item );
+ }
+ }
+
+ if( m_selection.Size() == 1 )
+ m_frame->SetCurItem( m_selection.Item<BOARD_ITEM>( 0 ) );
+ else
+ m_frame->SetCurItem( NULL );
+
+ // Inform other potentially interested tools
+ if( !m_selection.Empty() )
+ m_toolMgr->ProcessEvent( SelectedEvent );
+
+ break; // Stop waiting for events
+ }
+ }
+
+ // Stop drawing the selection box
+ area.ViewSetVisible( false );
+ view->Remove( &area );
+ m_multiple = false; // Multiple selection mode is inactive
+ getViewControls()->SetAutoPan( false );
+
+ return cancelled;
+}
+
+
+void SELECTION_TOOL::SetTransitions()
+{
+ Go( &SELECTION_TOOL::Main, COMMON_ACTIONS::selectionActivate.MakeEvent() );
+ Go( &SELECTION_TOOL::CursorSelection, COMMON_ACTIONS::selectionCursor.MakeEvent() );
+ Go( &SELECTION_TOOL::ClearSelection, COMMON_ACTIONS::selectionClear.MakeEvent() );
+ Go( &SELECTION_TOOL::SelectItem, COMMON_ACTIONS::selectItem.MakeEvent() );
+ Go( &SELECTION_TOOL::UnselectItem, COMMON_ACTIONS::unselectItem.MakeEvent() );
+ Go( &SELECTION_TOOL::find, COMMON_ACTIONS::find.MakeEvent() );
+ Go( &SELECTION_TOOL::findMove, COMMON_ACTIONS::findMove.MakeEvent() );
+ Go( &SELECTION_TOOL::selectConnection, COMMON_ACTIONS::selectConnection.MakeEvent() );
+ Go( &SELECTION_TOOL::selectCopper, COMMON_ACTIONS::selectCopper.MakeEvent() );
+ Go( &SELECTION_TOOL::selectNet, COMMON_ACTIONS::selectNet.MakeEvent() );
+}
+
+
+SELECTION_LOCK_FLAGS SELECTION_TOOL::CheckLock()
+{
+ if( !m_locked || m_editModules )
+ return SELECTION_UNLOCKED;
+
+ bool containsLocked = false;
+
+ // Check if the selection contains locked items
+ for( int i = 0; i < m_selection.Size(); ++i )
+ {
+ BOARD_ITEM* item = m_selection.Item<BOARD_ITEM>( i );
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_T:
+ if( static_cast<MODULE*>( item )->IsLocked() )
+ containsLocked = true;
+ break;
+
+ case PCB_MODULE_EDGE_T:
+ case PCB_MODULE_TEXT_T:
+ if( static_cast<MODULE*>( item->GetParent() )->IsLocked() )
+ containsLocked = true;
+ break;
+
+ default: // suppress warnings
+ break;
+ }
+ }
+
+ if( containsLocked )
+ {
+ if( IsOK( m_frame, _( "Selection contains locked items. Do you want to continue?" ) ) )
+ {
+ m_locked = false;
+ return SELECTION_LOCK_OVERRIDE;
+ }
+ else
+ return SELECTION_LOCKED;
+ }
+
+ m_locked = false;
+
+ return SELECTION_UNLOCKED;
+}
+
+
+int SELECTION_TOOL::CursorSelection( const TOOL_EVENT& aEvent )
+{
+ selectCursor( true );
+
+ return 0;
+}
+
+
+int SELECTION_TOOL::ClearSelection( const TOOL_EVENT& aEvent )
+{
+ clearSelection();
+
+ return 0;
+}
+
+
+int SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent )
+{
+ // Check if there is an item to be selected
+ BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
+
+ if( item )
+ {
+ select( item );
+
+ // Inform other potentially interested tools
+ m_toolMgr->ProcessEvent( SelectedEvent );
+ }
+
+ return 0;
+}
+
+
+int SELECTION_TOOL::UnselectItem( const TOOL_EVENT& aEvent )
+{
+ // Check if there is an item to be selected
+ BOARD_ITEM* item = aEvent.Parameter<BOARD_ITEM*>();
+
+ if( item )
+ {
+ unselect( item );
+
+ // Inform other potentially interested tools
+ m_toolMgr->ProcessEvent( UnselectedEvent );
+ }
+
+ return 0;
+}
+
+
+int SELECTION_TOOL::selectConnection( const TOOL_EVENT& aEvent )
+{
+ if( !selectCursor( true ) )
+ return 0;
+
+ BOARD_CONNECTED_ITEM* item = m_selection.Item<BOARD_CONNECTED_ITEM>( 0 );
+ clearSelection();
+
+ if( item->Type() != PCB_TRACE_T && item->Type() != PCB_VIA_T )
+ return 0;
+
+ int segmentCount;
+ TRACK* trackList = getModel<BOARD>()->MarkTrace( static_cast<TRACK*>( item ), &segmentCount,
+ NULL, NULL, true );
+
+ if( segmentCount == 0 )
+ return 0;
+
+ for( int i = 0; i < segmentCount; ++i )
+ {
+ select( trackList );
+ trackList = trackList->Next();
+ }
+
+ // Inform other potentially interested tools
+ m_toolMgr->ProcessEvent( SelectedEvent );
+
+ return 0;
+}
+
+
+int SELECTION_TOOL::selectCopper( const TOOL_EVENT& aEvent )
+{
+ if( !selectCursor( true ) )
+ return 0;
+
+ BOARD_CONNECTED_ITEM* item = m_selection.Item<BOARD_CONNECTED_ITEM>( 0 );
+ clearSelection();
+
+ if( item->Type() != PCB_TRACE_T && item->Type() != PCB_VIA_T )
+ return 0;
+
+ std::list<BOARD_CONNECTED_ITEM*> itemsList;
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+
+ ratsnest->GetConnectedItems( item, itemsList, (RN_ITEM_TYPE)( RN_TRACKS | RN_VIAS ) );
+
+ BOOST_FOREACH( BOARD_CONNECTED_ITEM* i, itemsList )
+ select( i );
+
+ // Inform other potentially interested tools
+ if( itemsList.size() > 0 )
+ m_toolMgr->ProcessEvent( SelectedEvent );
+
+ return 0;
+}
+
+
+int SELECTION_TOOL::selectNet( const TOOL_EVENT& aEvent )
+{
+ if( !selectCursor( true ) )
+ return 0;
+
+ BOARD_CONNECTED_ITEM* item = m_selection.Item<BOARD_CONNECTED_ITEM>( 0 );
+
+ std::list<BOARD_CONNECTED_ITEM*> itemsList;
+ RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
+ int netCode = item->GetNetCode();
+
+ clearSelection();
+ ratsnest->GetNetItems( netCode, itemsList, (RN_ITEM_TYPE)( RN_TRACKS | RN_VIAS ) );
+
+ BOOST_FOREACH( BOARD_CONNECTED_ITEM* i, itemsList )
+ select( i );
+
+ // Inform other potentially interested tools
+ if( itemsList.size() > 0 )
+ m_toolMgr->ProcessEvent( SelectedEvent );
+
+ return 0;
+}
+
+
+void SELECTION_TOOL::findCallback( BOARD_ITEM* aItem )
+{
+ clearSelection();
+
+ if( aItem )
+ {
+ select( aItem );
+ EDA_RECT bbox = aItem->GetBoundingBox();
+ BOX2D viewport( VECTOR2D( bbox.GetOrigin() ), VECTOR2D( bbox.GetSize() ) );
+ getView()->SetViewport( viewport );
+
+ // Inform other potentially interested tools
+ m_toolMgr->ProcessEvent( SelectedEvent );
+ }
+
+ m_frame->GetGalCanvas()->ForceRefresh();
+}
+
+
+int SELECTION_TOOL::find( const TOOL_EVENT& aEvent )
+{
+ DIALOG_FIND dlg( m_frame );
+ dlg.EnableWarp( false );
+ dlg.SetCallback( boost::bind( &SELECTION_TOOL::findCallback, this, _1 ) );
+ dlg.ShowModal();
+
+ return 0;
+}
+
+
+int SELECTION_TOOL::findMove( const TOOL_EVENT& aEvent )
+{
+ MODULE* module = m_frame->GetModuleByName();
+
+ if( module )
+ {
+ clearSelection();
+ toggleSelection( module );
+ m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );
+ }
+
+ return 0;
+}
+
+
+void SELECTION_TOOL::clearSelection()
+{
+ if( m_selection.Empty() )
+ return;
+
+ KIGFX::VIEW_GROUP::const_iter it, it_end;
+
+ // Restore the initial properties
+ for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it )
+ {
+ BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it );
+
+ item->ViewHide( false );
+ item->ClearSelected();
+ item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ) ;
+ }
+
+ m_selection.clear();
+
+ m_frame->SetCurItem( NULL );
+ m_locked = true;
+
+ // Inform other potentially interested tools
+ m_toolMgr->ProcessEvent( ClearedEvent );
+}
+
+
+BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
+{
+ BOARD_ITEM* current = NULL;
+ boost::shared_ptr<BRIGHT_BOX> brightBox;
+ CONTEXT_MENU menu;
+
+ int limit = std::min( 10, aCollector->GetCount() );
+
+ for( int i = 0; i < limit; ++i )
+ {
+ wxString text;
+ BOARD_ITEM* item = ( *aCollector )[i];
+ text = item->GetSelectMenuText();
+ menu.Add( text, i + 1 );
+ }
+
+ menu.SetTitle( _( "Clarify selection" ) );
+ SetContextMenu( &menu, CMENU_NOW );
+
+ while( OPT_TOOL_EVENT evt = Wait() )
+ {
+ if( evt->Action() == TA_CONTEXT_MENU_UPDATE )
+ {
+ if( current )
+ current->ClearBrightened();
+
+ int id = *evt->GetCommandId();
+
+ // User has pointed an item, so show it in a different way
+ if( id > 0 && id <= limit )
+ {
+ current = ( *aCollector )[id - 1];
+ current->SetBrightened();
+ }
+ else
+ {
+ current = NULL;
+ }
+ }
+ else if( evt->Action() == TA_CONTEXT_MENU_CHOICE )
+ {
+ boost::optional<int> id = evt->GetCommandId();
+
+ // User has selected an item, so this one will be returned
+ if( id && ( *id > 0 ) )
+ current = ( *aCollector )[*id - 1];
+ else
+ current = NULL;
+
+ break;
+ }
+
+ // Draw a mark to show which item is available to be selected
+ if( current && current->IsBrightened() )
+ {
+ brightBox.reset( new BRIGHT_BOX( current ) );
+ getView()->Add( brightBox.get() );
+ // BRIGHT_BOX is removed from view on destruction
+ }
+ }
+
+ return current;
+}
+
+
+BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector )
+{
+ int count = aCollector->GetPrimaryCount(); // try to use preferred layer
+
+ if( 0 == count )
+ count = aCollector->GetCount();
+
+ for( int i = 0; i < count; ++i )
+ {
+ if( ( *aCollector )[i]->Type() != PCB_MODULE_T )
+ return NULL;
+ }
+
+ // All are modules, now find smallest MODULE
+ int minDim = 0x7FFFFFFF;
+ int minNdx = 0;
+
+ for( int i = 0; i < count; ++i )
+ {
+ MODULE* module = (MODULE*) ( *aCollector )[i];
+
+ int lx = module->GetBoundingBox().GetWidth();
+ int ly = module->GetBoundingBox().GetHeight();
+
+ int lmin = std::min( lx, ly );
+
+ if( lmin < minDim )
+ {
+ minDim = lmin;
+ minNdx = i;
+ }
+ }
+
+ return (*aCollector)[minNdx];
+}
+
+
+bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
+{
+ // Is high contrast mode enabled?
+ bool highContrast = getView()->GetPainter()->GetSettings()->GetHighContrast();
+
+ if( highContrast )
+ {
+ bool onActive = false; // Is the item on any of active layers?
+ int layers[KIGFX::VIEW::VIEW_MAX_LAYERS], layers_count;
+
+ // Filter out items that do not belong to active layers
+ const std::set<unsigned int>& activeLayers = getView()->GetPainter()->
+ GetSettings()->GetActiveLayers();
+ aItem->ViewGetLayers( layers, layers_count );
+
+ for( int i = 0; i < layers_count; ++i )
+ {
+ if( activeLayers.count( layers[i] ) > 0 ) // Item is on at least one of the active layers
+ {
+ onActive = true;
+ break;
+ }
+ }
+
+ if( !onActive ) // We do not want to select items that are in the background
+ return false;
+ }
+
+ BOARD* board = getModel<BOARD>();
+
+ switch( aItem->Type() )
+ {
+ case PCB_VIA_T:
+ {
+ // For vias it is enough if only one of layers is visible
+ LAYER_ID top, bottom;
+
+ static_cast<const VIA*>( aItem )->LayerPair( &top, &bottom );
+
+ return board->IsLayerVisible( top ) || board->IsLayerVisible( bottom );
+ }
+ break;
+
+ case PCB_MODULE_T:
+ if( aItem->IsOnLayer( F_Cu ) && board->IsElementVisible( MOD_FR_VISIBLE ) )
+ return !m_editModules;
+
+ if( aItem->IsOnLayer( B_Cu ) && board->IsElementVisible( MOD_BK_VISIBLE ) )
+ return !m_editModules;
+
+ return false;
+
+ break;
+
+ case PCB_MODULE_TEXT_T:
+ if( m_multiple && !m_editModules )
+ return false;
+
+ return aItem->ViewIsVisible() && board->IsLayerVisible( aItem->GetLayer() );
+
+ case PCB_MODULE_EDGE_T:
+ case PCB_PAD_T:
+ {
+ if( m_multiple && !m_editModules )
+ return false;
+
+ MODULE* mod = static_cast<const D_PAD*>( aItem )->GetParent();
+ if( mod && mod->IsLocked() )
+ return false;
+
+ break;
+ }
+
+ // These are not selectable
+ case NOT_USED:
+ case TYPE_NOT_INIT:
+ return false;
+
+ default: // Suppress warnings
+ break;
+ }
+
+ // All other items are selected only if the layer on which they exist is visible
+ return board->IsLayerVisible( aItem->GetLayer() );
+}
+
+
+bool SELECTION_TOOL::modifiable( const BOARD_ITEM* aItem ) const
+{
+ if( aItem->Type() == PCB_MARKER_T )
+ return false;
+
+ return true;
+}
+
+
+void SELECTION_TOOL::select( BOARD_ITEM* aItem )
+{
+ if( aItem->IsSelected() )
+ return;
+
+ // Modules are treated in a special way - when they are selected, we have to mark
+ // all the parts that make the module as selected
+ if( aItem->Type() == PCB_MODULE_T )
+ {
+ MODULE* module = static_cast<MODULE*>( aItem );
+ module->RunOnChildren( boost::bind( &SELECTION_TOOL::selectVisually, this, _1 ) );
+ }
+
+ if( aItem->Type() == PCB_PAD_T )
+ {
+ MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
+
+ if( m_selection.items.FindItem( module ) >= 0 )
+ return;
+ }
+
+ selectVisually( aItem );
+ ITEM_PICKER picker( aItem );
+ m_selection.items.PushItem( picker );
+
+ if( m_selection.Size() == 1 )
+ {
+ // Set as the current item, so the information about selection is displayed
+ m_frame->SetCurItem( aItem, true );
+ }
+ else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
+ { // called for every next selected item
+ // If multiple items are selected, do not show the information about the selected item
+ m_frame->SetCurItem( NULL, true );
+ }
+}
+
+
+void SELECTION_TOOL::unselect( BOARD_ITEM* aItem )
+{
+ if( !aItem->IsSelected() )
+ return;
+
+ // Modules are treated in a special way - when they are selected, we have to
+ // unselect all the parts that make the module, not the module itself
+ if( aItem->Type() == PCB_MODULE_T )
+ {
+ MODULE* module = static_cast<MODULE*>( aItem );
+ module->RunOnChildren( boost::bind( &SELECTION_TOOL::unselectVisually, this, _1 ) );
+ }
+
+ unselectVisually( aItem );
+
+ int itemIdx = m_selection.items.FindItem( aItem );
+ if( itemIdx >= 0 )
+ m_selection.items.RemovePicker( itemIdx );
+
+ if( m_selection.Empty() )
+ {
+ m_frame->SetCurItem( NULL );
+ m_locked = true;
+ }
+}
+
+
+void SELECTION_TOOL::selectVisually( BOARD_ITEM* aItem ) const
+{
+ m_selection.group->Add( aItem );
+
+ // Hide the original item, so it is shown only on overlay
+ aItem->ViewHide( true );
+ aItem->SetSelected();
+}
+
+
+void SELECTION_TOOL::unselectVisually( BOARD_ITEM* aItem ) const
+{
+ m_selection.group->Remove( aItem );
+
+ // Restore original item visibility
+ aItem->ViewHide( false );
+ aItem->ClearSelected();
+ aItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+}
+
+
+bool SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
+{
+ const unsigned GRIP_MARGIN = 20;
+ VECTOR2D margin = getView()->ToWorld( VECTOR2D( GRIP_MARGIN, GRIP_MARGIN ), false );
+
+ // Check if the point is located within any of the currently selected items bounding boxes
+ for( unsigned int i = 0; i < m_selection.items.GetCount(); ++i )
+ {
+ BOARD_ITEM* item = m_selection.Item<BOARD_ITEM>( i );
+ BOX2I itemBox = item->ViewBBox();
+ itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
+
+ if( itemBox.Contains( aPoint ) )
+ return true;
+ }
+
+ return false;
+}
+
+
+static EDA_RECT getRect( const BOARD_ITEM* aItem )
+{
+ if( aItem->Type() == PCB_MODULE_T )
+ return static_cast<const MODULE*>( aItem )->GetFootprintRect();
+
+ return aItem->GetBoundingBox();
+}
+
+
+static double calcArea( const BOARD_ITEM* aItem )
+{
+ if( aItem->Type() == PCB_TRACE_T )
+ {
+ const TRACK* t = static_cast<const TRACK*>( aItem );
+ return ( t->GetWidth() + t->GetLength() ) * t->GetWidth();
+ }
+
+ return getRect( aItem ).GetArea();
+}
+
+
+static double calcMinArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
+{
+ double best = std::numeric_limits<double>::max();
+
+ if( !aCollector.GetCount() )
+ return 0.0;
+
+ for( int i = 0; i < aCollector.GetCount(); i++ )
+ {
+ BOARD_ITEM* item = aCollector[i];
+ if( item->Type() == aType )
+ best = std::min( best, calcArea( item ) );
+ }
+
+ return best;
+}
+
+
+static double calcMaxArea( GENERAL_COLLECTOR& aCollector, KICAD_T aType )
+{
+ double best = 0.0;
+
+ for( int i = 0; i < aCollector.GetCount(); i++ )
+ {
+ BOARD_ITEM* item = aCollector[i];
+ if( item->Type() == aType )
+ best = std::max( best, calcArea( item ) );
+ }
+
+ return best;
+}
+
+
+static inline double calcCommonArea( const BOARD_ITEM* aItem, const BOARD_ITEM* aOther )
+{
+ return getRect( aItem ).Common( getRect( aOther ) ).GetArea();
+}
+
+
+double calcRatio( double a, double b )
+{
+ if( a == 0.0 && b == 0.0 )
+ return 1.0;
+ if( b == 0.0 )
+ return 10000000.0; // something arbitrarily big for the moment
+
+ return a / b;
+}
+
+
+// todo: explain the selection heuristics
+void SELECTION_TOOL::guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) const
+{
+ std::set<BOARD_ITEM*> rejected;
+
+ const double footprintAreaRatio = 0.2;
+ const double modulePadMinCoverRatio = 0.45;
+ const double padViaAreaRatio = 0.5;
+ const double trackViaLengthRatio = 2.0;
+ const double trackTrackLengthRatio = 0.3;
+ const double textToFeatureMinRatio = 0.2;
+ const double textToFootprintMinRatio = 0.4;
+ // If the common area of two compared items is above the following threshold, they cannot
+ // be rejected (it means they overlap and it might be hard to pick one by selecting
+ // its unique area).
+ const double commonAreaRatio = 0.6;
+
+ LAYER_ID actLayer = m_frame->GetActiveLayer();
+
+ LSET silkLayers( 2, B_SilkS, F_SilkS );
+
+ if( silkLayers[actLayer] )
+ {
+ std::set<BOARD_ITEM*> preferred;
+
+ for( int i = 0; i < aCollector.GetCount(); ++i )
+ {
+ BOARD_ITEM* item = aCollector[i];
+ KICAD_T type = item->Type();
+
+ if( ( type == PCB_MODULE_TEXT_T || type == PCB_TEXT_T || type == PCB_LINE_T )
+ && silkLayers[item->GetLayer()] )
+ {
+ preferred.insert( item );
+ }
+ }
+
+ if( preferred.size() != 0 )
+ {
+ aCollector.Empty();
+
+ BOOST_FOREACH( BOARD_ITEM* item, preferred )
+ aCollector.Append( item );
+ return;
+ }
+ }
+
+ if( aCollector.CountType( PCB_MODULE_TEXT_T ) > 0 )
+ {
+ for( int i = 0; i < aCollector.GetCount(); ++i )
+ {
+ if( TEXTE_MODULE* txt = dyn_cast<TEXTE_MODULE*>( aCollector[i] ) )
+ {
+ double textArea = calcArea( txt );
+
+ for( int j = 0; j < aCollector.GetCount(); ++j )
+ {
+ if( i == j )
+ continue;
+
+ BOARD_ITEM* item = aCollector[j];
+ double itemArea = calcArea( item );
+ double areaRatio = calcRatio( textArea, itemArea );
+ double commonArea = calcCommonArea( txt, item );
+ double itemCommonRatio = calcRatio( commonArea, itemArea );
+ double txtCommonRatio = calcRatio( commonArea, textArea );
+
+ if( item->Type() == PCB_MODULE_T && areaRatio < textToFootprintMinRatio &&
+ itemCommonRatio < commonAreaRatio )
+ rejected.insert( item );
+
+ switch( item->Type() )
+ {
+ case PCB_TRACE_T:
+ case PCB_PAD_T:
+ case PCB_LINE_T:
+ case PCB_VIA_T:
+ case PCB_MODULE_T:
+ if( areaRatio > textToFeatureMinRatio && txtCommonRatio < commonAreaRatio )
+ rejected.insert( txt );
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if( aCollector.CountType( PCB_MODULE_T ) > 0 )
+ {
+ double minArea = calcMinArea( aCollector, PCB_MODULE_T );
+ double maxArea = calcMaxArea( aCollector, PCB_MODULE_T );
+
+ if( calcRatio( minArea, maxArea ) <= footprintAreaRatio )
+ {
+ for( int i = 0; i < aCollector.GetCount(); ++i )
+ {
+ if( MODULE* mod = dyn_cast<MODULE*>( aCollector[i] ) )
+ {
+ double normalizedArea = calcRatio( calcArea( mod ), maxArea );
+
+ if( normalizedArea > footprintAreaRatio )
+ rejected.insert( mod );
+ }
+ }
+ }
+ }
+
+ if( aCollector.CountType( PCB_PAD_T ) > 0 )
+ {
+ for( int i = 0; i < aCollector.GetCount(); ++i )
+ {
+ if( D_PAD* pad = dyn_cast<D_PAD*>( aCollector[i] ) )
+ {
+ double ratio = pad->GetParent()->PadCoverageRatio();
+
+ if( ratio < modulePadMinCoverRatio )
+ rejected.insert( pad->GetParent() );
+ }
+ }
+ }
+
+ if( aCollector.CountType( PCB_VIA_T ) > 0 )
+ {
+ for( int i = 0; i < aCollector.GetCount(); ++i )
+ {
+ if( VIA* via = dyn_cast<VIA*>( aCollector[i] ) )
+ {
+ double viaArea = calcArea( via );
+
+ for( int j = 0; j < aCollector.GetCount(); ++j )
+ {
+ if( i == j )
+ continue;
+
+ BOARD_ITEM* item = aCollector[j];
+ double areaRatio = calcRatio( viaArea, calcArea( item ) );
+
+ if( item->Type() == PCB_MODULE_T && areaRatio < modulePadMinCoverRatio )
+ rejected.insert( item );
+
+ if( item->Type() == PCB_PAD_T && areaRatio < padViaAreaRatio )
+ rejected.insert( item );
+
+ if( TRACK* track = dyn_cast<TRACK*>( item ) )
+ {
+ if( track->GetNetCode() != via->GetNetCode() )
+ continue;
+
+ double lenRatio = (double) ( track->GetLength() + track->GetWidth() ) /
+ (double) via->GetWidth();
+
+ if( lenRatio > trackViaLengthRatio )
+ rejected.insert( track );
+ }
+ }
+ }
+ }
+ }
+
+ int nTracks = aCollector.CountType( PCB_TRACE_T );
+
+ if( nTracks > 0 )
+ {
+ double maxLength = 0.0;
+ double minLength = std::numeric_limits<double>::max();
+ double maxArea = 0.0;
+
+ for( int i = 0; i < aCollector.GetCount(); ++i )
+ {
+ if( TRACK* track = dyn_cast<TRACK*> ( aCollector[i] ) )
+ {
+ maxLength = std::max( track->GetLength(), maxLength );
+ maxLength = std::max( (double) track->GetWidth(), maxLength );
+
+ minLength = std::min( std::max( track->GetLength(), (double)track->GetWidth() ), minLength );
+
+ double area = ( track->GetLength() + track->GetWidth() * track->GetWidth() );
+ maxArea = std::max(area, maxArea);
+ }
+ }
+
+ if( maxLength > 0.0 && minLength / maxLength < trackTrackLengthRatio && nTracks > 1 )
+ {
+ for( int i = 0; i < aCollector.GetCount(); ++i )
+ {
+ if( TRACK* track = dyn_cast<TRACK*>( aCollector[i] ) )
+ {
+ double ratio = std::max( (double) track->GetWidth(), track->GetLength() ) / maxLength;
+
+ if( ratio > trackTrackLengthRatio )
+ rejected.insert( track );
+ }
+ }
+ }
+
+ for( int j = 0; j < aCollector.GetCount(); ++j )
+ {
+ if( MODULE* mod = dyn_cast<MODULE*>( aCollector[j] ) )
+ {
+ double ratio = maxArea / mod->GetFootprintRect().GetArea();
+
+ if( ratio < modulePadMinCoverRatio )
+ rejected.insert( mod );
+ }
+ }
+ }
+
+ if( (unsigned) aCollector.GetCount() > rejected.size() ) // do not remove everything
+ {
+ BOOST_FOREACH( BOARD_ITEM* item, rejected )
+ {
+ aCollector.Remove( item );
+ }
+ }
+}
+
+
+bool SELECTION_TOOL::SanitizeSelection()
+{
+ std::set<BOARD_ITEM*> rejected;
+ std::set<BOARD_ITEM*> added;
+
+ if( !m_editModules )
+ {
+ for( unsigned int i = 0; i < m_selection.items.GetCount(); ++i )
+ {
+ BOARD_ITEM* item = m_selection.Item<BOARD_ITEM>( i );
+
+ if( item->Type() == PCB_PAD_T )
+ {
+ MODULE* mod = static_cast<MODULE*>( item->GetParent() );
+
+ // case 1: module (or its pads) are locked
+ if( mod && ( mod->PadsLocked() || mod->IsLocked() ) )
+ {
+ rejected.insert( item );
+
+ if( !mod->IsLocked() && !mod->IsSelected() )
+ added.insert( mod );
+ }
+
+ // case 2: multi-item selection contains both the module and its pads - remove the pads
+ if( mod && m_selection.items.FindItem( mod ) >= 0 )
+ rejected.insert( item );
+ }
+ }
+ }
+
+ if( !rejected.empty() )
+ {
+ BOOST_FOREACH( BOARD_ITEM* item, rejected )
+ unselect( item );
+
+ // Inform other potentially interested tools
+ m_toolMgr->ProcessEvent( UnselectedEvent );
+ }
+
+ if( !added.empty() )
+ {
+ BOOST_FOREACH( BOARD_ITEM* item, added )
+ select( item );
+
+ // Inform other potentially interested tools
+ m_toolMgr->ProcessEvent( UnselectedEvent );
+ }
+
+ return true;
+}
+
+
+void SELECTION::clear()
+{
+ items.ClearItemsList();
+ group->Clear();
+}
+
+
+VECTOR2I SELECTION::GetCenter() const
+{
+ VECTOR2I centre;
+
+ if( Size() == 1 )
+ {
+ centre = Item<BOARD_ITEM>( 0 )->GetCenter();
+ }
+ else
+ {
+ EDA_RECT bbox = Item<BOARD_ITEM>( 0 )->GetBoundingBox();
+ for( unsigned int i = 1; i < items.GetCount(); ++i )
+ {
+ BOARD_ITEM* item = Item<BOARD_ITEM>( i );
+ bbox.Merge( item->GetBoundingBox() );
+ }
+
+ centre = bbox.Centre();
+ }
+
+ return centre;
+}
+
+
+const TOOL_EVENT SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" );
+const TOOL_EVENT SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.unselected" );
+const TOOL_EVENT SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" );
diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h
new file mode 100644
index 0000000..4e7046c
--- /dev/null
+++ b/pcbnew/tools/selection_tool.h
@@ -0,0 +1,361 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013-2016 CERN
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __SELECTION_TOOL_H
+#define __SELECTION_TOOL_H
+
+#include <math/vector2d.h>
+#include <tool/tool_interactive.h>
+#include <tool/context_menu.h>
+#include <class_undoredo_container.h>
+
+#include "selection_conditions.h"
+#include "conditional_menu.h"
+
+class PCB_BASE_FRAME;
+class SELECTION_AREA;
+class BOARD_ITEM;
+class GENERAL_COLLECTOR;
+class SELECT_MENU;
+class ZOOM_MENU;
+class GRID_MENU;
+
+namespace KIGFX
+{
+class VIEW_GROUP;
+}
+
+struct SELECTION
+{
+ /// Set of selected items
+ PICKED_ITEMS_LIST items;
+
+ /// VIEW_GROUP that holds currently selected items
+ KIGFX::VIEW_GROUP* group;
+
+ /// Checks if there is anything selected
+ bool Empty() const
+ {
+ return ( items.GetCount() == 0 );
+ }
+
+ /// Returns the number of selected parts
+ int Size() const
+ {
+ return items.GetCount();
+ }
+
+ /// Alias to make code shorter and clearer
+ template <typename T>
+ T* Item( unsigned int aIndex ) const
+ {
+ return static_cast<T*>( items.GetPickedItem( aIndex ) );
+ }
+
+ /// Returns the center point of the selection area bounding box.
+ VECTOR2I GetCenter() const;
+
+ /// Runs a function on all selected items.
+ template <typename T>
+ void ForAll( boost::function<void (T*)> aFunction ) const
+ {
+ for( unsigned int i = 0; i < items.GetCount(); ++i )
+ aFunction( Item<T>( i ) );
+ }
+
+private:
+ /// Clears both the VIEW_GROUP and set of selected items. Please note that it does not
+ /// change properties of selected items (e.g. selection flag).
+ void clear();
+
+ friend class SELECTION_TOOL;
+};
+
+enum SELECTION_LOCK_FLAGS
+{
+ SELECTION_UNLOCKED = 0,
+ SELECTION_LOCK_OVERRIDE = 1,
+ SELECTION_LOCKED = 2
+};
+
+/**
+ * Class SELECTION_TOOL
+ *
+ * Our sample selection tool: currently supports:
+ * - pick single objects (click LMB)
+ * - add objects to existing selection (Shift+LMB)
+ * - draw selection box (drag LMB)
+ * - handles MODULEs properly (i.e. selects either MODULE or its PADs, TEXTs, etc.)
+ * - takes into account high-contrast & layer visibility settings
+ * - invokes InteractiveEdit tool when user starts to drag selected items
+ */
+class SELECTION_TOOL : public TOOL_INTERACTIVE
+{
+public:
+ SELECTION_TOOL();
+ ~SELECTION_TOOL();
+
+ /// @copydoc TOOL_BASE::Init()
+ bool Init();
+
+ /// @copydoc TOOL_BASE::Reset()
+ void Reset( RESET_REASON aReason );
+
+ /**
+ * Function Main()
+ *
+ * The main loop.
+ */
+ int Main( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function GetSelection()
+ *
+ * Returns the set of currently selected items.
+ */
+ const SELECTION& GetSelection();
+
+ /**
+ * Function EditModules()
+ *
+ * Toggles edit module mode. When enabled, one may select parts of modules individually
+ * (graphics, pads, etc.), so they can be modified.
+ * @param aEnabled decides if the mode should be enabled.
+ */
+ inline void EditModules( bool aEnabled )
+ {
+ m_editModules = aEnabled;
+ }
+
+ inline CONDITIONAL_MENU& GetMenu()
+ {
+ return m_menu;
+ }
+
+ ///> Checks if the user has agreed to modify locked items for the given selection.
+ SELECTION_LOCK_FLAGS CheckLock();
+
+ ///> Select a single item under cursor event handler.
+ int CursorSelection( const TOOL_EVENT& aEvent );
+
+ ///> Clear current selection event handler.
+ int ClearSelection( const TOOL_EVENT& aEvent );
+
+ ///> Makes sure a group selection does not contain items that would cause
+ ///> conflicts when moving/rotating together (e.g. a footprint and one of the same footprint's pads)
+ bool SanitizeSelection();
+
+ ///> Item selection event handler.
+ int SelectItem( const TOOL_EVENT& aEvent );
+
+ ///> Item unselection event handler.
+ int UnselectItem( const TOOL_EVENT& aEvent );
+
+ ///> Event sent after an item is selected.
+ static const TOOL_EVENT SelectedEvent;
+
+ ///> Event sent after an item is unselected.
+ static const TOOL_EVENT UnselectedEvent;
+
+ ///> Event sent after selection is cleared.
+ static const TOOL_EVENT ClearedEvent;
+
+ ///> Sets up handlers for various events.
+ void SetTransitions();
+
+private:
+ /**
+ * Function selectPoint()
+ * Selects an item pointed by the parameter aWhere. If there is more than one item at that
+ * place, there is a menu displayed that allows to choose the item.
+ *
+ * @param aWhere is the place where the item should be selected.
+ * @param aAllowDisambiguation decides what to do in case of disambiguation. If true, then
+ * a menu is shown, otherise function finishes without selecting anything.
+ * @return True if an item was selected, false otherwise.
+ */
+ bool selectPoint( const VECTOR2I& aWhere, bool aOnDrag = false );
+
+ /**
+ * Function selectCursor()
+ * Selects an item under the cursor unless there is something already selected or aSelectAlways
+ * is true.
+ * @param aSelectAlways forces to select an item even if there is an item already selected.
+ * @return true if eventually there is an item selected, false otherwise.
+ */
+ bool selectCursor( bool aSelectAlways = false );
+
+ /**
+ * Function selectMultiple()
+ * Handles drawing a selection box that allows to select many items at the same time.
+ *
+ * @return true if the function was cancelled (i.e. CancelEvent was received).
+ */
+ bool selectMultiple();
+
+ ///> Selects a trivial connection (between two junctions).
+ int selectConnection( const TOOL_EVENT& aEvent );
+
+ ///> Selects a continuous copper connection.
+ int selectCopper( const TOOL_EVENT& aEvent );
+
+ ///> Selects all copper connections belonging to a single net.
+ int selectNet( const TOOL_EVENT& aEvent );
+
+ ///> Find dialog callback.
+ void findCallback( BOARD_ITEM* aItem );
+
+ ///> Find an item.
+ int find( const TOOL_EVENT& aEvent );
+
+ ///> Find an item and start moving.
+ int findMove( const TOOL_EVENT& aEvent );
+
+ /**
+ * Function clearSelection()
+ * Clears the current selection.
+ */
+ void clearSelection();
+
+ /**
+ * Function disambiguationMenu()
+ * Handles the menu that allows to select one of many items in case there is more than one
+ * item at the selected point (@see selectCursor()).
+ *
+ * @param aItems contains list of items that are displayed to the user.
+ */
+ BOARD_ITEM* disambiguationMenu( GENERAL_COLLECTOR* aItems );
+
+ /**
+ * Function pickSmallestComponent()
+ * Allows to find the smallest (in terms of bounding box area) item from the list.
+ *
+ * @param aCollector containes the list of items.
+ */
+ BOARD_ITEM* pickSmallestComponent( GENERAL_COLLECTOR* aCollector );
+
+ /**
+ * Function toggleSelection()
+ * Changes selection status of a given item.
+ *
+ * @param aItem is the item to have selection status changed.
+ */
+ void toggleSelection( BOARD_ITEM* aItem );
+
+ /**
+ * Function selectable()
+ * Checks conditions for an item to be selected.
+ *
+ * @return True if the item fulfills conditions to be selected.
+ */
+ bool selectable( const BOARD_ITEM* aItem ) const;
+
+ /**
+ * Function modifiable()
+ * Checks if an item might be modified. This function is used to filter out items
+ * from the selection when it is passed to other tools.
+ *
+ * @return True if the item fulfills conditions to be modified.
+ */
+ bool modifiable( const BOARD_ITEM* aItem ) const;
+
+ /**
+ * Function select()
+ * Takes necessary action mark an item as selected.
+ *
+ * @param aItem is an item to be selected.
+ */
+ void select( BOARD_ITEM* aItem );
+
+ /**
+ * Function unselect()
+ * Takes necessary action mark an item as unselected.
+ *
+ * @param aItem is an item to be unselected.
+ */
+ void unselect( BOARD_ITEM* aItem );
+
+ /**
+ * Function selectVisually()
+ * Marks item as selected, but does not add it to the ITEMS_PICKED_LIST.
+ * @param aItem is an item to be be marked.
+ */
+ void selectVisually( BOARD_ITEM* aItem ) const;
+
+ /**
+ * Function unselectVisually()
+ * Marks item as selected, but does not add it to the ITEMS_PICKED_LIST.
+ * @param aItem is an item to be be marked.
+ */
+ void unselectVisually( BOARD_ITEM* aItem ) const;
+
+ /**
+ * Function selectionContains()
+ * Checks if the given point is placed within any of selected items' bounding box.
+ *
+ * @return True if the given point is contained in any of selected items' bouding box.
+ */
+ bool selectionContains( const VECTOR2I& aPoint ) const;
+
+ /**
+ * Function guessSelectionCandidates()
+ * Tries to guess best selection candidates in case multiple items are clicked, by
+ * doing some braindead heuristics.
+ * @param aCollector is the collector that has a list of items to be queried.
+ */
+ void guessSelectionCandidates( GENERAL_COLLECTOR& aCollector ) const;
+
+ /// Pointer to the parent frame.
+ PCB_BASE_FRAME* m_frame;
+
+ /// Current state of selection.
+ SELECTION m_selection;
+
+ /// Flag saying if items should be added to the current selection or rather replace it.
+ bool m_additive;
+
+ /// Flag saying if multiple selection mode is active.
+ bool m_multiple;
+
+ /// Edit module mode flag.
+ bool m_editModules;
+
+ /// Can other tools modify locked items.
+ bool m_locked;
+
+ /// Determines if the selection is preliminary or final.
+ bool m_preliminary;
+
+ /// Menu displayed by the tool.
+ CONDITIONAL_MENU m_menu;
+
+ /// Pointers to context menus
+ CONTEXT_MENU* m_contextMenu;
+ SELECT_MENU* m_selectMenu;
+ ZOOM_MENU* m_zoomMenu;
+ GRID_MENU* m_gridMenu;
+};
+
+#endif
diff --git a/pcbnew/tools/size_menu.cpp b/pcbnew/tools/size_menu.cpp
new file mode 100644
index 0000000..7dc63e4
--- /dev/null
+++ b/pcbnew/tools/size_menu.cpp
@@ -0,0 +1,85 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "size_menu.h"
+
+#include <class_board.h>
+#include <pcbnew_id.h>
+
+CONTEXT_TRACK_VIA_SIZE_MENU::CONTEXT_TRACK_VIA_SIZE_MENU( bool aTrackSizes, bool aViaSizes ) :
+ m_tracks( aTrackSizes ), m_vias( aViaSizes )
+{
+ SetIcon( width_track_via_xpm );
+}
+
+
+void CONTEXT_TRACK_VIA_SIZE_MENU::AppendSizes( const BOARD* aBoard )
+{
+ wxString msg;
+
+ const BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings();
+
+ if( m_tracks )
+ {
+ for( unsigned i = 0; i < bds.m_TrackWidthList.size(); i++ )
+ {
+ if( m_vias ) // == if( m_tracks && m_vias )
+ msg = _( "Track ");
+
+ if( i == 0 )
+ msg << _( "net class width" );
+ else
+ msg << StringFromValue( g_UserUnit, bds.m_TrackWidthList[i], true );
+
+ Append( ID_POPUP_PCB_SELECT_WIDTH1 + i, msg, wxEmptyString, wxITEM_CHECK );
+ }
+ }
+
+ if( m_tracks && m_vias )
+ AppendSeparator();
+
+ if( m_vias )
+ {
+ for( unsigned i = 0; i < bds.m_ViasDimensionsList.size(); i++ )
+ {
+ if( m_tracks ) // == if( m_tracks && m_vias )
+ msg = _( "Via " );
+
+ if( i == 0 )
+ {
+ msg << _( "net class size" );
+ }
+ else
+ {
+ msg << StringFromValue( g_UserUnit, bds.m_ViasDimensionsList[i].m_Diameter, true );
+ wxString drill = StringFromValue( g_UserUnit,
+ bds.m_ViasDimensionsList[i].m_Drill, true );
+
+ if( bds.m_ViasDimensionsList[i].m_Drill <= 0 )
+ msg << _( ", drill: default" );
+ else
+ msg << _( ", drill: " ) << drill;
+ }
+
+ Append( ID_POPUP_PCB_SELECT_VIASIZE1 + i, msg, wxEmptyString, wxITEM_CHECK );
+ }
+ }
+}
diff --git a/pcbnew/tools/size_menu.h b/pcbnew/tools/size_menu.h
new file mode 100644
index 0000000..248e366
--- /dev/null
+++ b/pcbnew/tools/size_menu.h
@@ -0,0 +1,55 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <tool/context_menu.h>
+
+class BOARD;
+
+/**
+ * @brief Context menu that displays track and/or via sizes basing on the board design settings
+ * of a BOARD object.
+ */
+class CONTEXT_TRACK_VIA_SIZE_MENU: public CONTEXT_MENU
+{
+public:
+ /**
+ * Constructor.
+ * @param aTrackSizes decides if the context menu should contain track sizes.
+ * @param aTrackSizes decides if the context menu should contain via sizes.
+ */
+ CONTEXT_TRACK_VIA_SIZE_MENU( bool aTrackSizes, bool aViaSizes );
+
+ virtual ~CONTEXT_TRACK_VIA_SIZE_MENU() {}
+
+ /**
+ * Function AppendSizes()
+ * Appends the list of tracks/vias (depending on the parameters passed to the constructor).
+ * @param aBoard is the BOARD object whose board settings will be used to generate the list.
+ */
+ virtual void AppendSizes( const BOARD* aBoard );
+
+protected:
+ ///> Whether the generated menu should contain track sizes.
+ bool m_tracks;
+
+ ///> Whether the generated menu should contain via sizes.
+ bool m_vias;
+};
diff --git a/pcbnew/tools/tools_common.cpp b/pcbnew/tools/tools_common.cpp
new file mode 100644
index 0000000..ee46245
--- /dev/null
+++ b/pcbnew/tools/tools_common.cpp
@@ -0,0 +1,54 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <io_mgr.h>
+
+#include <tool/tool_manager.h>
+
+#include <tools/selection_tool.h>
+#include <tools/picker_tool.h>
+#include <tools/edit_tool.h>
+#include <tools/drawing_tool.h>
+#include <tools/point_editor.h>
+#include <tools/pcbnew_control.h>
+#include <tools/pcb_editor_control.h>
+#include <tools/placement_tool.h>
+#include <tools/common_actions.h>
+
+#include <router/router_tool.h>
+#include <router/length_tuner_tool.h>
+
+void registerAllTools( TOOL_MANAGER *aToolManager )
+{
+ aToolManager->RegisterTool( new SELECTION_TOOL );
+ aToolManager->RegisterTool( new PICKER_TOOL );
+ aToolManager->RegisterTool( new ROUTER_TOOL );
+ aToolManager->RegisterTool( new LENGTH_TUNER_TOOL );
+ aToolManager->RegisterTool( new EDIT_TOOL );
+ aToolManager->RegisterTool( new DRAWING_TOOL );
+ aToolManager->RegisterTool( new POINT_EDITOR );
+ aToolManager->RegisterTool( new PCBNEW_CONTROL );
+ aToolManager->RegisterTool( new PCB_EDITOR_CONTROL );
+ aToolManager->RegisterTool( new PLACEMENT_TOOL );
+} \ No newline at end of file
diff --git a/pcbnew/tools/zoom_menu.cpp b/pcbnew/tools/zoom_menu.cpp
new file mode 100644
index 0000000..42aa093
--- /dev/null
+++ b/pcbnew/tools/zoom_menu.cpp
@@ -0,0 +1,71 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "zoom_menu.h"
+#include <id.h>
+#include <draw_frame.h>
+#include <class_base_screen.h>
+#include <tools/common_actions.h>
+
+#include <boost/bind.hpp>
+
+ZOOM_MENU::ZOOM_MENU( EDA_DRAW_FRAME* aParent ) : m_parent( aParent )
+{
+ BASE_SCREEN* screen = aParent->GetScreen();
+
+ SetIcon( zoom_selection_xpm );
+ SetMenuHandler( boost::bind( &ZOOM_MENU::EventHandler, this, _1 ) );
+ SetUpdateHandler( boost::bind( &ZOOM_MENU::Update, this ) );
+
+ //int zoom = screen->GetZoom();
+ int maxZoomIds = std::min( ID_POPUP_ZOOM_LEVEL_END - ID_POPUP_ZOOM_LEVEL_START,
+ (int) screen->m_ZoomList.size() );
+
+ for( int i = 0; i < maxZoomIds; ++i )
+ {
+ Append( ID_POPUP_ZOOM_LEVEL_START + i,
+ wxString::Format( _( "Zoom: %.2f" ), aParent->GetZoomLevelCoeff() / screen->m_ZoomList[i] ),
+ wxEmptyString, wxITEM_CHECK );
+ }
+}
+
+
+OPT_TOOL_EVENT ZOOM_MENU::EventHandler( const wxMenuEvent& aEvent )
+{
+ OPT_TOOL_EVENT event( COMMON_ACTIONS::zoomPreset.MakeEvent() );
+ long idx = aEvent.GetId() - ID_POPUP_ZOOM_LEVEL_START;
+ event->SetParameter( idx );
+
+ return event;
+}
+
+
+void ZOOM_MENU::Update()
+{
+ double zoom = m_parent->GetScreen()->GetZoom();
+ const std::vector<double>& zoomList = m_parent->GetScreen()->m_ZoomList;
+
+ for( unsigned int i = 0; i < GetMenuItemCount(); ++i )
+ Check( ID_POPUP_ZOOM_LEVEL_START + i, std::fabs( zoomList[i] - zoom ) < 1e-6 );
+}
diff --git a/pcbnew/tools/zoom_menu.h b/pcbnew/tools/zoom_menu.h
new file mode 100644
index 0000000..0a7de81
--- /dev/null
+++ b/pcbnew/tools/zoom_menu.h
@@ -0,0 +1,44 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef ZOOM_MENU_H
+#define ZOOM_MENU_H
+
+#include <tool/context_menu.h>
+
+class EDA_DRAW_FRAME;
+
+class ZOOM_MENU : public CONTEXT_MENU
+{
+public:
+ ZOOM_MENU( EDA_DRAW_FRAME* aParent );
+
+private:
+ OPT_TOOL_EVENT EventHandler( const wxMenuEvent& aEvent );
+ void Update();
+
+ EDA_DRAW_FRAME* m_parent;
+};
+
+#endif /* ZOOM_MENU_H */
diff --git a/pcbnew/tr_modif.cpp b/pcbnew/tr_modif.cpp
new file mode 100644
index 0000000..5c5d5e2
--- /dev/null
+++ b/pcbnew/tr_modif.cpp
@@ -0,0 +1,324 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file tr_modif.cpp
+ * @brief Trace editing: detects an removes a track which is become redunding,
+ * after a new track is craeted.
+ */
+
+#include <fctsys.h>
+#include <gr_basic.h>
+#include <wxPcbStruct.h>
+
+#include <class_board.h>
+#include <class_track.h>
+
+#include <pcbnew.h>
+#include <protos.h>
+
+
+static void ListSetState( EDA_ITEM* Start, int NbItem, STATUS_FLAGS State,
+ bool onoff );
+
+
+void DrawTraces( EDA_DRAW_PANEL* panel, wxDC* DC, TRACK* aTrackList, int nbsegment,
+ GR_DRAWMODE draw_mode )
+{
+ // preserve the start of the list for debugging.
+ for( TRACK* track = aTrackList; nbsegment > 0 && track; nbsegment--, track = track->Next() )
+ {
+ track->Draw( panel, DC, draw_mode );
+ }
+}
+
+/*
+ * This function try to remove an old track, when a new track is created,
+ * and the old track is no more needed
+ */
+int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC,
+ TRACK* aNewTrack,
+ int aNewTrackSegmentsCount,
+ PICKED_ITEMS_LIST* aItemsListPicker )
+{
+ TRACK* StartTrack, * EndTrack;
+ TRACK* pt_segm;
+ TRACK* pt_del;
+ int ii, jj, nb_segm, nbconnect;
+ wxPoint start;
+ wxPoint end;
+ LSET startmasklayer, endmasklayer;
+
+ int netcode = aNewTrack->GetNetCode();
+
+ /* Reconstruct the complete track (the new track has to start on a segment of track).
+ */
+ ListSetState( aNewTrack, aNewTrackSegmentsCount, BUSY, false );
+
+ /* If the new track begins with a via, complete the track segment using
+ * the following segment as a reference because a via is often a hub of
+ * segments, and does not characterize track.
+ */
+ if( aNewTrack->Type() == PCB_VIA_T && ( aNewTrackSegmentsCount > 1 ) )
+ aNewTrack = aNewTrack->Next();
+
+ aNewTrack = GetBoard()->MarkTrace( aNewTrack, &aNewTrackSegmentsCount, NULL, NULL, true );
+ wxASSERT( aNewTrack );
+
+#if 0 && defined(DEBUG)
+ TRACK* EndNewTrack; // The last segment of the list chained to the track
+
+ EndNewTrack = aNewTrack;
+
+ for( ii = 1; ii < aNewTrackSegmentsCount; ii++ )
+ {
+ wxASSERT( EndNewTrack->GetState( -1 ) != 0 );
+ D( printf( "track %p is newly part of net %d\n", EndNewTrack, netcode ); )
+ EndNewTrack = EndNewTrack->Next();
+ }
+
+ wxASSERT( EndNewTrack->GetState( -1 ) != 0 );
+ D( printf( "track %p is newly part of net %d\n", EndNewTrack, netcode ); )
+
+ for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() )
+ track->Show( 0, std::cout );
+
+#endif
+
+ TRACK* bufStart = m_Pcb->m_Track->GetStartNetCode( netcode ); // Beginning of tracks of the net
+ TRACK* bufEnd = bufStart->GetEndNetCode( netcode ); // End of tracks of the net
+
+ // Flags for cleaning the net.
+ for( pt_del = bufStart; pt_del; pt_del = pt_del->Next() )
+ {
+// D( std::cout<<"track "<<pt_del<<" turning off BUSY | IN_EDIT | IS_LINKED"<<std::endl; )
+ pt_del->SetState( BUSY | IN_EDIT | IS_LINKED, false );
+
+ if( pt_del == bufEnd ) // Last segment reached
+ break;
+ }
+
+ if( aNewTrack->GetEndSegments( aNewTrackSegmentsCount, &StartTrack, &EndTrack ) == 0 )
+ return 0;
+
+ if( ( StartTrack == NULL ) || ( EndTrack == NULL ) )
+ return 0;
+
+ start = StartTrack->GetStart();
+ end = EndTrack->GetEnd();
+
+ // The start and end points cannot be the same.
+ if( start == end )
+ return 0;
+
+ // Determine layers interconnected these points.
+ startmasklayer = StartTrack->GetLayerSet();
+ endmasklayer = EndTrack->GetLayerSet();
+
+ // There may be a via or a pad on the end points.
+ pt_segm = m_Pcb->m_Track->GetVia( NULL, start, startmasklayer );
+
+ if( pt_segm )
+ startmasklayer |= pt_segm->GetLayerSet();
+
+ if( StartTrack->start && ( StartTrack->start->Type() == PCB_PAD_T ) )
+ {
+ // Start on pad.
+ D_PAD* pad = (D_PAD*) StartTrack->start;
+ startmasklayer |= pad->GetLayerSet();
+ }
+
+ pt_segm = m_Pcb->m_Track->GetVia( NULL, end, endmasklayer );
+
+ if( pt_segm )
+ endmasklayer |= pt_segm->GetLayerSet();
+
+ if( EndTrack->end && ( EndTrack->end->Type() == PCB_PAD_T ) )
+ {
+ D_PAD* pad = (D_PAD*) EndTrack->end;
+ endmasklayer |= pad->GetLayerSet();
+ }
+
+ // Mark as deleted a new track (which is not involved in the search for other connections)
+ ListSetState( aNewTrack, aNewTrackSegmentsCount, IS_DELETED, true );
+
+ /* A segment must be connected to the starting point, otherwise
+ * it is unnecessary to analyze the other point
+ */
+ pt_segm = GetTrack( bufStart, bufEnd, start, startmasklayer );
+
+ if( pt_segm == NULL ) // Not connected to the track starting point.
+ {
+ // Clear the delete flag.
+ ListSetState( aNewTrack, aNewTrackSegmentsCount, IS_DELETED, false );
+ return 0;
+ }
+
+ /* Marking a list of candidate segmented connect to endpoint
+ * Note: the vias are not taken into account because they do
+ * not define a track, since they are on an intersection.
+ */
+ for( pt_del = bufStart, nbconnect = 0; ; )
+ {
+ pt_segm = GetTrack( pt_del, bufEnd, end, endmasklayer );
+
+ if( pt_segm == NULL )
+ break;
+
+ if( pt_segm->Type() != PCB_VIA_T )
+ {
+ if( pt_segm->GetState( IS_LINKED ) == 0 )
+ {
+ pt_segm->SetState( IS_LINKED, true );
+ nbconnect++;
+ }
+ }
+
+ if( pt_del == bufEnd )
+ break;
+
+ pt_del = pt_segm->Next();
+ }
+
+ if( nbconnect == 0 )
+ {
+ // Clear used flags
+ for( pt_del = bufStart; pt_del; pt_del = pt_del->Next() )
+ {
+ pt_del->SetState( BUSY | IS_DELETED | IN_EDIT | IS_LINKED, false );
+
+ if( pt_del == bufEnd ) // Last segment reached
+ break;
+ }
+
+ return 0;
+ }
+
+ // Mark trace as edited (which does not involve searching for other tracks)
+ ListSetState( aNewTrack, aNewTrackSegmentsCount, IS_DELETED, false );
+ ListSetState( aNewTrack, aNewTrackSegmentsCount, IN_EDIT, true );
+
+ // Test all marked segments.
+ while( nbconnect )
+ {
+ for( pt_del = bufStart; pt_del; pt_del = pt_del->Next() )
+ {
+ if( pt_del->GetState( IS_LINKED ) )
+ break;
+
+ if( pt_del == bufEnd ) // Last segment reached
+ break;
+ }
+
+ nbconnect--;
+
+ if( pt_del )
+ pt_del->SetState( IS_LINKED, false );
+
+ pt_del = GetBoard()->MarkTrace( pt_del, &nb_segm, NULL, NULL, true );
+
+ /* Test if the marked track is redundant, i.e. if one of marked segments
+ * is connected to the starting point of the new track.
+ */
+ ii = 0;
+ pt_segm = pt_del;
+
+ for( ; pt_segm && (ii < nb_segm); pt_segm = pt_segm->Next(), ii++ )
+ {
+ if( pt_segm->GetState( BUSY ) == 0 )
+ break;
+
+ if( pt_segm->GetStart() == start || pt_segm->GetEnd() == start )
+ {
+ // Marked track can be erased.
+ TRACK* NextS;
+
+ DrawTraces( m_canvas, aDC, pt_del, nb_segm, GR_XOR | GR_HIGHLIGHT );
+
+ for( jj = 0; jj < nb_segm; jj++, pt_del = NextS )
+ {
+ NextS = pt_del->Next();
+
+ if( aItemsListPicker )
+ {
+ pt_del->UnLink();
+ pt_del->SetStatus( 0 );
+ pt_del->ClearFlags();
+ ITEM_PICKER picker( pt_del, UR_DELETED );
+ aItemsListPicker->PushItem( picker );
+ }
+ else
+ {
+ pt_del->DeleteStructure();
+ }
+ }
+
+ // Clean up flags.
+ for( pt_del = m_Pcb->m_Track; pt_del != NULL; pt_del = pt_del->Next() )
+ {
+ if( pt_del->GetState( IN_EDIT ) )
+ {
+ pt_del->SetState( IN_EDIT, false );
+
+ if( aDC )
+ pt_del->Draw( m_canvas, aDC, GR_OR );
+ }
+
+ pt_del->SetState( IN_EDIT | IS_LINKED, false );
+ }
+
+ return 1;
+ }
+ }
+
+ // Clear BUSY flag here because the track did not get marked.
+ ListSetState( pt_del, nb_segm, BUSY, false );
+ }
+
+ // Clear used flags
+ for( pt_del = m_Pcb->m_Track; pt_del; pt_del = pt_del->Next() )
+ {
+ pt_del->SetState( BUSY | IS_DELETED | IN_EDIT | IS_LINKED, false );
+
+ if( pt_del == bufEnd ) // Last segment reached
+ break;
+ }
+
+ return 0;
+}
+
+
+/* Set the bits of .m_State member to on/off value, using bit mask State
+ * of a list of EDA_ITEM
+ */
+static void ListSetState( EDA_ITEM* Start, int NbItem, STATUS_FLAGS State,
+ bool onoff )
+{
+ for( ; (Start != NULL ) && ( NbItem > 0 ); NbItem--, Start = Start->Next() )
+ {
+ Start->SetState( State, onoff );
+ }
+}
diff --git a/pcbnew/tracepcb.cpp b/pcbnew/tracepcb.cpp
new file mode 100644
index 0000000..56b3a8b
--- /dev/null
+++ b/pcbnew/tracepcb.cpp
@@ -0,0 +1,314 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file tracepcb.cpp
+ * @brief Functions to redraw the current board.
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+#include <base_units.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_zone.h>
+#include <class_marker_pcb.h>
+
+#include <pcbnew.h>
+#include <module_editor_frame.h>
+#include <pcbplot.h>
+
+#include <wx/overlay.h>
+
+
+// Local functions:
+/* Trace the pads of a module in sketch mode.
+ * Used to display pads when when the module visibility is set to not visible
+ * and we want to see pad through.
+ * The pads must appear on the layers selected in LayerMask
+ */
+static void Trace_Pads_Only( EDA_DRAW_PANEL* panel, wxDC* DC, MODULE* Module,
+ int ox, int oy, LSET LayerMask, GR_DRAWMODE draw_mode );
+
+
+void FOOTPRINT_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
+{
+ PCB_SCREEN* screen = GetScreen();
+
+ if( !GetBoard() || !screen )
+ return;
+
+ GRSetDrawMode( DC, GR_COPY );
+
+ m_canvas->DrawBackGround( DC );
+ DrawWorkSheet( DC, screen, 0, IU_PER_MILS, wxEmptyString );
+
+ // Redraw the footprints
+ for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
+ module->Draw( m_canvas, DC, GR_OR | GR_ALLOW_HIGHCONTRAST );
+
+#ifdef USE_WX_OVERLAY
+
+ if( IsShown() )
+ {
+ m_overlay.Reset();
+ wxDCOverlay overlaydc( m_overlay, (wxWindowDC*) DC );
+ overlaydc.Clear();
+ }
+
+#endif
+
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ // Redraw the cursor
+ m_canvas->DrawCrossHair( DC );
+}
+
+
+/* Draw the BOARD, and others elements : axis, grid ..
+ */
+void PCB_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
+{
+ PCB_SCREEN* screen = GetScreen();
+
+ if( !GetBoard() || !screen )
+ return;
+
+ GRSetDrawMode( DC, GR_COPY );
+
+ m_canvas->DrawBackGround( DC );
+
+ DrawWorkSheet( DC, GetScreen(), g_DrawDefaultLineThickness,
+ IU_PER_MILS, GetBoard()->GetFileName() );
+
+ GetBoard()->Draw( m_canvas, DC, GR_OR | GR_ALLOW_HIGHCONTRAST );
+
+ DrawGeneralRatsnest( DC );
+
+#ifdef USE_WX_OVERLAY
+
+ if( IsShown() )
+ {
+ m_overlay.Reset();
+ wxDCOverlay overlaydc( m_overlay, (wxWindowDC*) DC );
+ overlaydc.Clear();
+ }
+
+#endif
+
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+
+ // Redraw the cursor
+ m_canvas->DrawCrossHair( DC );
+}
+
+
+// Redraw the BOARD items but not cursors, axis or grid
+void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset )
+{
+ /* The order of drawing is flexible on some systems and not on others. For
+ * OSes which use OR to draw, the order is not important except for the
+ * effect of the highlight and its relationship to markers. See comment
+ * below.
+ * This order independence comes from the fact that a binary OR operation is
+ * commutative in nature.
+ * However on the OSX, the OR operation is not used, and so this sequence
+ * below is chosen to give MODULEs the highest visible priority.
+ */
+
+ /* Draw all tracks and zones. As long as dark colors are used for the
+ * tracks, Then the OR draw mode should show tracks underneath other
+ * tracks. But a white track will cover any other color since it has
+ * more bits to OR in.
+ */
+ for( TRACK* track = m_Track; track; track = track->Next() )
+ {
+ if( track->IsMoving() )
+ continue;
+
+ track->Draw( aPanel, DC, aDrawMode );
+ }
+
+ // SEGZONE is outdated, only her for compatibility with
+ // very old designs
+ for( SEGZONE* zone = m_Zone; zone; zone = zone->Next() )
+ {
+ if( zone->IsMoving() )
+ continue;
+
+ zone->Draw( aPanel, DC, aDrawMode );
+ }
+
+ // Draw the graphic items
+ for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
+ {
+ if( item->IsMoving() )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_DIMENSION_T:
+ case PCB_TEXT_T:
+ case PCB_TARGET_T:
+ case PCB_LINE_T:
+ item->Draw( aPanel, DC, aDrawMode );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Draw areas (i.e. zones)
+ for( int ii = 0; ii < GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* zone = GetArea( ii );
+
+ // Areas must be drawn here only if not moved or dragged,
+ // because these areas are drawn by ManageCursor() in a specific manner
+ if( ( zone->GetFlags() & (IN_EDIT | IS_DRAGGED | IS_MOVED) ) == 0 )
+ {
+ zone->Draw( aPanel, DC, aDrawMode );
+ zone->DrawFilledArea( aPanel, DC, aDrawMode );
+ }
+ }
+
+ LSET all_cu = LSET::AllCuMask();
+
+ for( MODULE* module = m_Modules; module; module = module->Next() )
+ {
+ bool display = true;
+ LSET layerMask = all_cu;
+
+ if( module->IsMoving() )
+ continue;
+
+ if( !IsElementVisible( PCB_VISIBLE( MOD_FR_VISIBLE ) ) )
+ {
+ if( module->GetLayer() == F_Cu )
+ display = false;
+
+ layerMask.set( F_Cu, false );
+ }
+
+ if( !IsElementVisible( PCB_VISIBLE( MOD_BK_VISIBLE ) ) )
+ {
+ if( module->GetLayer() == B_Cu )
+ display = false;
+
+ layerMask.set( B_Cu, false );
+ }
+
+ if( display )
+ module->Draw( aPanel, DC, aDrawMode );
+ else
+ Trace_Pads_Only( aPanel, DC, module, 0, 0, layerMask, aDrawMode );
+ }
+
+ if( IsHighLightNetON() )
+ DrawHighLight( aPanel, DC, GetHighLightNetCode() );
+
+ // draw the BOARD's markers last, otherwise the high light will erase any marker on a pad
+ for( unsigned i = 0; i < m_markers.size(); ++i )
+ {
+ m_markers[i]->Draw( aPanel, DC, aDrawMode );
+ }
+}
+
+
+void BOARD::DrawHighLight( EDA_DRAW_PANEL* am_canvas, wxDC* DC, int aNetCode )
+{
+ GR_DRAWMODE draw_mode;
+
+ if( IsHighLightNetON() )
+ draw_mode = GR_HIGHLIGHT | GR_OR;
+ else
+ draw_mode = GR_AND | GR_HIGHLIGHT;
+
+ // Redraw zones
+ for( int ii = 0; ii < GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* zone = GetArea( ii );
+
+ if( zone->GetNetCode() == aNetCode )
+ {
+ zone->Draw( am_canvas, DC, draw_mode );
+ }
+ }
+
+ // Redraw any pads that have aNetCode
+ for( MODULE* module = m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ {
+ if( pad->GetNetCode() == aNetCode )
+ {
+ pad->Draw( am_canvas, DC, draw_mode );
+ }
+ }
+ }
+
+ // Redraw track and vias that have aNetCode
+ for( TRACK* seg = m_Track; seg; seg = seg->Next() )
+ {
+ if( seg->GetNetCode() == aNetCode )
+ {
+ seg->Draw( am_canvas, DC, draw_mode );
+ }
+ }
+}
+
+
+/* Trace the pads of a module in sketch mode.
+ * Used to display pads when when the module visibility is set to not visible
+ * and we want to see pad through.
+ * The pads must appear on the layers selected in LayerMask
+ */
+static void Trace_Pads_Only( EDA_DRAW_PANEL* panel, wxDC* DC, MODULE* aModule,
+ int ox, int oy, LSET aLayerMask, GR_DRAWMODE draw_mode )
+{
+ DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
+
+ int tmp = displ_opts->m_DisplayPadFill;
+
+ displ_opts->m_DisplayPadFill = false;
+
+ // Draw pads.
+ for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
+ {
+ if( (pad->GetLayerSet() & aLayerMask) == 0 )
+ continue;
+
+ pad->Draw( panel, DC, draw_mode, wxPoint( ox, oy ) );
+ }
+
+ displ_opts->m_DisplayPadFill = tmp;
+}
diff --git a/pcbnew/xchgmod.cpp b/pcbnew/xchgmod.cpp
new file mode 100644
index 0000000..fa29048
--- /dev/null
+++ b/pcbnew/xchgmod.cpp
@@ -0,0 +1,561 @@
+/**
+ * @file xchgmod.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <class_drawpanel.h>
+#include <class_draw_panel_gal.h>
+#include <confirm.h>
+#include <kicad_string.h>
+#include <wxPcbStruct.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <project.h>
+
+#include <pcbnew.h>
+#include <dialog_exchange_modules_base.h>
+#include <wildcards_and_files_ext.h>
+#include <kiway.h>
+
+
+static bool RecreateCmpFile( BOARD * aBrd, const wxString& aFullCmpFileName );
+
+
+class DIALOG_EXCHANGE_MODULE : public DIALOG_EXCHANGE_MODULE_BASE
+{
+private:
+ PCB_EDIT_FRAME* m_parent;
+ MODULE* m_currentModule;
+ static int m_selectionMode; // Remember the last exchange option
+
+public:
+ DIALOG_EXCHANGE_MODULE( PCB_EDIT_FRAME* aParent, MODULE* aModule );
+ ~DIALOG_EXCHANGE_MODULE() { };
+
+private:
+ void OnSelectionClicked( wxCommandEvent& event );
+ void OnOkClick( wxCommandEvent& event );
+ void OnQuit( wxCommandEvent& event );
+ void BrowseAndSelectFootprint( wxCommandEvent& event );
+ void ViewAndSelectFootprint( wxCommandEvent& event );
+ void RebuildCmpList( wxCommandEvent& event );
+ void init();
+
+ bool changeCurrentFootprint();
+ bool changeSameFootprints( bool aUseValue);
+ bool changeAllFootprints();
+ bool change_1_Module( MODULE* aModule,
+ const FPID& aNewFootprintFPID,
+ bool eShowError );
+
+ PICKED_ITEMS_LIST m_undoPickList;
+};
+
+
+int DIALOG_EXCHANGE_MODULE::m_selectionMode = 0;
+
+
+DIALOG_EXCHANGE_MODULE::DIALOG_EXCHANGE_MODULE( PCB_EDIT_FRAME* parent, MODULE* Module ) :
+ DIALOG_EXCHANGE_MODULE_BASE( parent )
+{
+ m_parent = parent;
+ m_currentModule = Module;
+ init();
+ GetSizer()->Fit( this );
+ GetSizer()->SetSizeHints( this );
+ Center();
+}
+
+
+int PCB_EDIT_FRAME::InstallExchangeModuleFrame( MODULE* Module )
+{
+ DIALOG_EXCHANGE_MODULE dialog( this, Module );
+
+ return dialog.ShowQuasiModal();
+}
+
+
+void DIALOG_EXCHANGE_MODULE::OnQuit( wxCommandEvent& event )
+{
+ m_selectionMode = m_Selection->GetSelection();
+ Show( false );
+ EndQuasiModal( wxID_CANCEL );
+}
+
+
+void DIALOG_EXCHANGE_MODULE::init()
+{
+ SetFocus();
+
+ m_CurrentFootprintFPID->AppendText( FROM_UTF8( m_currentModule->GetFPID().Format().c_str() ) );
+ m_NewFootprintFPID->AppendText( FROM_UTF8( m_currentModule->GetFPID().Format().c_str() ) );
+ m_CmpValue->AppendText( m_currentModule->GetValue() );
+ m_CmpReference->AppendText( m_currentModule->GetReference() );
+ m_Selection->SetString( 0, wxString::Format(
+ _("Change footprint of '%s'" ),
+ GetChars( m_currentModule->GetReference() ) ) );
+ wxString fpname = m_CurrentFootprintFPID->GetValue().AfterLast(':');
+
+ if( fpname.IsEmpty() ) // Happens for old fp names
+ fpname = m_CurrentFootprintFPID->GetValue();
+
+ m_Selection->SetString( 1, wxString::Format(
+ _("Change footprints '%s'" ),
+ GetChars( fpname.Left( 12 ) ) ) );
+
+ m_Selection->SetSelection( m_selectionMode );
+
+ // Enable/disable widgets:
+ wxCommandEvent event;
+ OnSelectionClicked( event );
+}
+
+
+void DIALOG_EXCHANGE_MODULE::OnOkClick( wxCommandEvent& event )
+{
+ m_undoPickList.ClearItemsList();
+ m_selectionMode = m_Selection->GetSelection();
+ bool result = false;
+
+ switch( m_Selection->GetSelection() )
+ {
+ case 0:
+ result = changeCurrentFootprint();
+ break;
+
+ case 1:
+ result = changeSameFootprints( false );
+ break;
+
+ case 2:
+ result = changeSameFootprints( true );
+ break;
+
+ case 3:
+ result = changeAllFootprints();
+ break;
+ }
+
+ if( result )
+ {
+ if( m_parent->GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) )
+ m_parent->Compile_Ratsnest( NULL, true );
+
+ m_parent->GetCanvas()->Refresh();
+ }
+
+ if( m_undoPickList.GetCount() )
+ m_parent->SaveCopyInUndoList( m_undoPickList, UR_UNSPECIFIED );
+}
+
+
+void DIALOG_EXCHANGE_MODULE::OnSelectionClicked( wxCommandEvent& event )
+{
+ bool enable = true;
+
+ switch( m_Selection->GetSelection() )
+ {
+ case 0:
+ case 1:
+ case 2:
+ break;
+
+ case 3:
+ enable = false;
+ break;
+ }
+
+ m_NewFootprintFPID->Enable( enable );
+ m_Browsebutton->Enable( enable );
+}
+
+
+/*
+ * Rebuild the file name.CMP (if any) after exchanging footprints
+ * if the footprint are managed by this file
+ * Return false if error
+ */
+void DIALOG_EXCHANGE_MODULE::RebuildCmpList( wxCommandEvent& event )
+{
+ wxFileName fn;
+ wxString msg;
+
+ // Build the .cmp file name from the board name
+ fn = m_parent->GetBoard()->GetFileName();
+ fn.SetExt( ComponentFileExtension );
+
+ if( RecreateCmpFile( m_parent->GetBoard(), fn.GetFullPath() ) )
+ {
+ msg.Printf( _( "File '%s' created\n" ),
+ GetChars( fn.GetFullPath() ) );
+ }
+ else
+ {
+ msg.Printf( _( "** Could not create file '%s' ***\n" ),
+ GetChars( fn.GetFullPath() ) );
+ }
+
+ m_WinMessages->AppendText( msg );
+}
+
+
+/* Change the current footprint at the current cursor position.
+ * Retains the following:
+ * - position, orientation and side
+ * - value and ref
+ * - pads net names
+ */
+bool DIALOG_EXCHANGE_MODULE::changeCurrentFootprint()
+{
+ wxString newmodulename = m_NewFootprintFPID->GetValue();
+
+ if( newmodulename == wxEmptyString )
+ return false;
+
+ return change_1_Module( m_currentModule, newmodulename, true );
+}
+
+
+/*
+ * Change all footprints having the same fpid by a new one from lib
+ * Retains:
+ * - direction, position, side
+ * - value and ref
+ * - pads net names
+ * Note: m_currentModule is no longer the current footprint
+ * since it has been changed!
+ * if aUseValue is true, footprints having the same fpid should
+ * also have the same value
+ */
+bool DIALOG_EXCHANGE_MODULE::changeSameFootprints( bool aUseValue )
+{
+ wxString msg;
+ MODULE* Module;
+ MODULE* PtBack;
+ bool change = false;
+ wxString newmodulename = m_NewFootprintFPID->GetValue();
+ wxString value;
+ FPID lib_reference;
+ bool check_module_value = false;
+ int ShowErr = 3; // Post 3 error messages max.
+
+ if( m_parent->GetBoard()->m_Modules == NULL )
+ return false;
+
+ if( newmodulename == wxEmptyString )
+ return false;
+
+ lib_reference = m_currentModule->GetFPID();
+
+ if( aUseValue )
+ {
+ check_module_value = true;
+ value = m_currentModule->GetValue();
+ msg.Printf( _( "Change footprint %s -> %s (for value = %s)?" ),
+ GetChars( FROM_UTF8( m_currentModule->GetFPID().Format().c_str() ) ),
+ GetChars( newmodulename ),
+ GetChars( m_currentModule->GetValue() ) );
+ }
+ else
+ {
+ msg.Printf( _( "Change footprint %s -> %s ?" ),
+ GetChars( FROM_UTF8( lib_reference.Format().c_str() ) ),
+ GetChars( newmodulename ) );
+ }
+
+ if( !IsOK( this, msg ) )
+ return false;
+
+ /* The change is done from the last module because
+ * change_1_Module () modifies the last item in the list.
+ *
+ * note: for the first module in chain (the last here), Module->Back()
+ * points the board or is NULL
+ */
+ Module = m_parent->GetBoard()->m_Modules.GetLast();
+
+ for( ; Module && ( Module->Type() == PCB_MODULE_T ); Module = PtBack )
+ {
+ PtBack = Module->Back();
+
+ if( lib_reference != Module->GetFPID() )
+ continue;
+
+ if( check_module_value )
+ {
+ if( value.CmpNoCase( Module->GetValue() ) != 0 )
+ continue;
+ }
+
+ if( change_1_Module( Module, newmodulename, ShowErr ) )
+ change = true;
+ else if( ShowErr )
+ ShowErr--;
+ }
+
+ return change;
+}
+
+
+/*
+ * Change all modules with module of the same name in library.
+ * Maintains:
+ * - direction, position, side
+ * - value and ref
+ * - pads net names
+ */
+bool DIALOG_EXCHANGE_MODULE::changeAllFootprints()
+{
+ MODULE* Module, * PtBack;
+ bool change = false;
+ int ShowErr = 3; // Post 3 error max.
+
+ if( m_parent->GetBoard()->m_Modules == NULL )
+ return false;
+
+ if( !IsOK( this, _( "Are you sure you want to change all footprints?" ) ) )
+ return false;
+
+ /* The change is done from the last module because the function
+ * change_1_Module () modifies the last module in the list
+ *
+ * note: for the first module in chain (the last here), Module->Back()
+ * points the board or is NULL
+ */
+ Module = m_parent->GetBoard()->m_Modules.GetLast();
+
+ for( ; Module && ( Module->Type() == PCB_MODULE_T ); Module = PtBack )
+ {
+ PtBack = Module->Back();
+
+ if( change_1_Module( Module, Module->GetFPID(), ShowErr ) )
+ change = true;
+ else if( ShowErr )
+ ShowErr--;
+ }
+
+ return change;
+}
+
+
+/*
+ * Change aModule to a new, fresh one from lib
+ * Retains
+ * - direction, position, side
+ * - value and ref
+ * - pads net names
+ * Returns: false if no change (if the new module is not found)
+ * true if OK
+ */
+bool DIALOG_EXCHANGE_MODULE::change_1_Module( MODULE* aModule,
+ const FPID& aNewFootprintFPID,
+ bool aShowError )
+{
+ MODULE* newModule;
+ wxString line;
+
+ if( aModule == NULL )
+ return false;
+
+ wxBusyCursor dummy;
+
+ // Copy parameters from the old module.
+ FPID oldFootprintFPID = aModule->GetFPID();
+
+ // Load module.
+ line.Printf( _( "Change footprint '%s' (from '%s') to '%s'" ),
+ GetChars( aModule->GetReference() ),
+ oldFootprintFPID.Format().c_str(),
+ aNewFootprintFPID.Format().c_str() );
+ m_WinMessages->AppendText( line );
+
+ newModule = m_parent->LoadFootprint( aNewFootprintFPID );
+
+ if( newModule == NULL ) // New module not found, redraw the old one.
+ {
+ m_WinMessages->AppendText( wxT( " No\n" ) );
+ return false;
+ }
+
+ m_parent->Exchange_Module( aModule, newModule, &m_undoPickList );
+ m_parent->GetBoard()->Add( newModule, ADD_APPEND );
+
+ if( aModule == m_currentModule )
+ m_currentModule = newModule;
+
+ m_WinMessages->AppendText( wxT( " OK\n" ) );
+
+ return true;
+}
+
+
+void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule,
+ MODULE* aNewModule,
+ PICKED_ITEMS_LIST* aUndoPickList )
+{
+ aNewModule->SetParent( GetBoard() );
+
+ /* place module without ratsnest refresh: this will be made later
+ * when all modules are on board
+ */
+ PlaceModule( aNewModule, NULL, true );
+
+ // Copy full placement and pad net names (when possible)
+ // but not local settings like clearances (use library values)
+ aOldModule->CopyNetlistSettings( aNewModule, false );
+
+ // Copy reference and value
+ aNewModule->SetReference( aOldModule->GetReference() );
+ aNewModule->SetValue( aOldModule->GetValue() );
+
+ // Updating other parameters
+ aNewModule->SetTimeStamp( aOldModule->GetTimeStamp() );
+ aNewModule->SetPath( aOldModule->GetPath() );
+
+ if( aUndoPickList )
+ {
+ GetBoard()->Remove( aOldModule );
+ ITEM_PICKER picker_old( aOldModule, UR_DELETED );
+ ITEM_PICKER picker_new( aNewModule, UR_NEW );
+ aUndoPickList->PushItem( picker_old );
+ aUndoPickList->PushItem( picker_new );
+ }
+ else
+ {
+ GetGalCanvas()->GetView()->Remove( aOldModule );
+ aOldModule->DeleteStructure();
+ }
+
+ GetBoard()->m_Status_Pcb = 0;
+ aNewModule->ClearFlags();
+ OnModify();
+}
+
+
+// Displays the list of available footprints in library name and select a footprint.
+void DIALOG_EXCHANGE_MODULE::BrowseAndSelectFootprint( wxCommandEvent& event )
+{
+ wxString newname;
+
+ newname = m_parent->SelectFootprint( m_parent, wxEmptyString, wxEmptyString, wxEmptyString,
+ Prj().PcbFootprintLibs() );
+
+ if( newname != wxEmptyString )
+ m_NewFootprintFPID->SetValue( newname );
+}
+
+
+// Runs the footprint viewer to select a footprint.
+void DIALOG_EXCHANGE_MODULE::ViewAndSelectFootprint( wxCommandEvent& event )
+{
+ wxString newname;
+
+ KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true );
+
+ if( frame->ShowModal( &newname, this ) )
+ {
+ m_NewFootprintFPID->SetValue( newname );
+ }
+
+ frame->Destroy();
+}
+
+
+void PCB_EDIT_FRAME::RecreateCmpFileFromBoard( wxCommandEvent& aEvent )
+{
+ wxFileName fn;
+ MODULE* module = GetBoard()->m_Modules;
+ wxString msg;
+ wxString wildcard;
+
+ if( module == NULL )
+ {
+ DisplayError( this, _( "No footprints!" ) );
+ return;
+ }
+
+ // Build the .cmp file name from the board name
+ fn = GetBoard()->GetFileName();
+ fn.SetExt( ComponentFileExtension );
+ wildcard = wxGetTranslation( ComponentFileWildcard );
+
+ wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
+
+ wxFileDialog dlg( this, _( "Save Footprint Association File" ), pro_dir,
+ fn.GetFullName(), wildcard,
+ wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ fn = dlg.GetPath();
+
+ if( ! RecreateCmpFile( GetBoard(), fn.GetFullPath() ) )
+ {
+ msg.Printf( _( "Could not create file '%s'" ), GetChars(fn.GetFullPath() ) );
+ DisplayError( this, msg );
+ return;
+ }
+}
+
+
+bool RecreateCmpFile( BOARD * aBrd, const wxString& aFullCmpFileName )
+{
+ FILE* cmpFile;
+
+ cmpFile = wxFopen( aFullCmpFileName, wxT( "wt" ) );
+
+ if( cmpFile == NULL )
+ return false;
+
+ fprintf( cmpFile, "Cmp-Mod V01 Created by PcbNew date = %s\n", TO_UTF8( DateAndTime() ) );
+
+ MODULE* module = aBrd->m_Modules;
+ for( ; module != NULL; module = module->Next() )
+ {
+ fprintf( cmpFile, "\nBeginCmp\n" );
+ fprintf( cmpFile, "TimeStamp = %8.8lX\n", module->GetTimeStamp() );
+ fprintf( cmpFile, "Path = %s\n", TO_UTF8( module->GetPath() ) );
+ fprintf( cmpFile, "Reference = %s;\n",
+ !module->GetReference().IsEmpty() ?
+ TO_UTF8( module->GetReference() ) : "[NoRef]" );
+ fprintf( cmpFile, "ValeurCmp = %s;\n",
+ !module->GetValue().IsEmpty() ?
+ TO_UTF8( module->GetValue() ) : "[NoVal]" );
+ fprintf( cmpFile, "IdModule = %s;\n", module->GetFPID().Format().c_str() );
+ fprintf( cmpFile, "EndCmp\n" );
+ }
+
+ fprintf( cmpFile, "\nEndListe\n" );
+ fclose( cmpFile );
+
+ return true;
+}
diff --git a/pcbnew/zone_filling_algorithm.cpp b/pcbnew/zone_filling_algorithm.cpp
new file mode 100644
index 0000000..e56e786
--- /dev/null
+++ b/pcbnew/zone_filling_algorithm.cpp
@@ -0,0 +1,249 @@
+/**
+ * @file zone_filling_algorithm.cpp:
+ * Algorithms used to fill a zone defined by a polygon and a filling starting point.
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <algorithm> // sort
+
+#include <fctsys.h>
+#include <trigo.h>
+#include <wxPcbStruct.h>
+
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <zones.h>
+
+/* Build the filled solid areas data from real outlines (stored in m_Poly)
+ * The solid areas can be more than one on copper layers, and do not have holes
+ ( holes are linked by overlapping segments to the main outline)
+ * aPcb: the current board (can be NULL for non copper zones)
+ * aCornerBuffer: A reference to a buffer to store polygon corners, or NULL
+ * if aCornerBuffer == NULL:
+ * - m_FilledPolysList is used to store solid areas polygons.
+ * - on copper layers, tracks and other items shapes of other nets are
+ * removed from solid areas
+ * if not null:
+ * Only the zone outline (with holes, if any) are stored in aCornerBuffer
+ * with holes linked. Therefore only one polygon is created
+ * This function calls AddClearanceAreasPolygonsToPolysList()
+ * to add holes for pads and tracks and other items not in net.
+ */
+
+bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb, SHAPE_POLY_SET* aOutlineBuffer )
+{
+ /* convert outlines + holes to outlines without holes (adding extra segments if necessary)
+ * m_Poly data is expected normalized, i.e. NormalizeAreaOutlines was used after building
+ * this zone
+ */
+
+ if( GetNumCorners() <= 2 ) // malformed zone. polygon calculations do not like it ...
+ return 0;
+
+ // Make a smoothed polygon out of the user-drawn polygon if required
+ if( m_smoothedPoly )
+ {
+ delete m_smoothedPoly;
+ m_smoothedPoly = NULL;
+ }
+
+ switch( m_cornerSmoothingType )
+ {
+ case ZONE_SETTINGS::SMOOTHING_CHAMFER:
+ m_smoothedPoly = m_Poly->Chamfer( m_cornerRadius );
+ break;
+
+ case ZONE_SETTINGS::SMOOTHING_FILLET:
+ m_smoothedPoly = m_Poly->Fillet( m_cornerRadius, m_ArcToSegmentsCount );
+ break;
+
+ default:
+ // Acute angles between adjacent edges can create issues in calculations,
+ // in inflate/deflate outlines transforms, especially when the angle is very small.
+ // We can avoid issues by creating a very small chamfer which remove acute angles,
+ // or left it without chamfer and use only CPOLYGONS_LIST::InflateOutline to create
+ // clearance areas
+ m_smoothedPoly = m_Poly->Chamfer( Millimeter2iu( 0.0 ) );
+ break;
+ }
+
+ if( aOutlineBuffer )
+ aOutlineBuffer->Append( ConvertPolyListToPolySet( m_smoothedPoly->m_CornersList ) );
+
+ /* For copper layers, we now must add holes in the Polygon list.
+ * holes are pads and tracks with their clearance area
+ * for non copper layers just recalculate the m_FilledPolysList
+ * with m_ZoneMinThickness taken in account
+ */
+ else
+ {
+ m_FilledPolysList.RemoveAllContours();
+
+ if( IsOnCopperLayer() )
+ {
+ AddClearanceAreasPolygonsToPolysList_NG( aPcb );
+ }
+ else
+ {
+ int margin = m_ZoneMinThickness / 2;
+ m_FilledPolysList = ConvertPolyListToPolySet( m_smoothedPoly->m_CornersList );
+ m_FilledPolysList.Inflate( -margin, 16 );
+ m_FilledPolysList.Fracture();
+ }
+
+ if( m_FillMode ) // if fill mode uses segments, create them:
+ FillZoneAreasWithSegments();
+
+ m_IsFilled = true;
+ }
+
+ return true;
+}
+
+
+// Sort function to build filled zones
+static bool SortByXValues( const int& a, const int &b )
+{
+ return a < b;
+}
+
+
+int ZONE_CONTAINER::FillZoneAreasWithSegments()
+{
+ int count = 0;
+ std::vector <int> x_coordinates;
+ bool error = false;
+ int margin = m_ZoneMinThickness * 2 / 10;
+ int minwidth = Mils2iu( 2 );
+ margin = std::max ( minwidth, margin );
+ int step = m_ZoneMinThickness - margin;
+ step = std::max( step, minwidth );
+
+ // Read all filled areas in m_FilledPolysList
+ m_FillSegmList.clear();
+
+ for ( int index = 0; index < m_FilledPolysList.OutlineCount(); index++ )
+ {
+ const SHAPE_LINE_CHAIN& outline = m_FilledPolysList.COutline( index );
+ const BOX2I& rect = outline.BBox();
+
+ // Calculate the y limits of the zone
+ for( int refy = rect.GetY(), endy = rect.GetBottom(); refy < endy; refy += step )
+ {
+ // find all intersection points of an infinite line with polyline sides
+ x_coordinates.clear();
+
+ for( int v = 0; v < outline.PointCount(); v++ )
+ {
+
+ int seg_startX = outline.CPoint( v ).x;
+ int seg_startY = outline.CPoint( v ).y;
+ int seg_endX = outline.CPoint( v + 1 ).x;
+ int seg_endY = outline.CPoint( v + 1 ).y;
+
+ /* Trivial cases: skip if ref above or below the segment to test */
+ if( ( seg_startY > refy ) && ( seg_endY > refy ) )
+ continue;
+
+ // segment below ref point, or its Y end pos on Y coordinate ref point: skip
+ if( ( seg_startY <= refy ) && (seg_endY <= refy ) )
+ continue;
+
+ /* at this point refy is between seg_startY and seg_endY
+ * see if an horizontal line at Y = refy is intersecting this segment
+ */
+ // calculate the x position of the intersection of this segment and the
+ // infinite line this is more easier if we move the X,Y axis origin to
+ // the segment start point:
+
+ seg_endX -= seg_startX;
+ seg_endY -= seg_startY;
+ double newrefy = (double) ( refy - seg_startY );
+ double intersec_x;
+
+ if ( seg_endY == 0 ) // horizontal segment on the same line: skip
+ continue;
+
+ // Now calculate the x intersection coordinate of the horizontal line at
+ // y = newrefy and the segment from (0,0) to (seg_endX,seg_endY) with the
+ // horizontal line at the new refy position the line slope is:
+ // slope = seg_endY/seg_endX; and inv_slope = seg_endX/seg_endY
+ // and the x pos relative to the new origin is:
+ // intersec_x = refy/slope = refy * inv_slope
+ // Note: because horizontal segments are already tested and skipped, slope
+ // exists (seg_end_y not O)
+ double inv_slope = (double) seg_endX / seg_endY;
+ intersec_x = newrefy * inv_slope;
+ x_coordinates.push_back( (int) intersec_x + seg_startX );
+ }
+
+ // A line scan is finished: build list of segments
+
+ // Sort intersection points by increasing x value:
+ // So 2 consecutive points are the ends of a segment
+ sort( x_coordinates.begin(), x_coordinates.end(), SortByXValues );
+
+ // Create segments
+
+ if( !error && ( x_coordinates.size() & 1 ) != 0 )
+ { // An even number of coordinates is expected, because a segment has 2 ends.
+ // An if this algorithm always works, it must always find an even count.
+ wxString msg = wxT( "Fill Zone: odd number of points at y = " );
+ msg << refy;
+ wxMessageBox( msg );
+ error = true;
+ }
+
+ if( error )
+ break;
+
+ int iimax = x_coordinates.size() - 1;
+
+ for( int ii = 0; ii < iimax; ii += 2 )
+ {
+ wxPoint seg_start, seg_end;
+ count++;
+ seg_start.x = x_coordinates[ii];
+ seg_start.y = refy;
+ seg_end.x = x_coordinates[ii + 1];
+ seg_end.y = refy;
+ SEGMENT segment( seg_start, seg_end );
+ m_FillSegmList.push_back( segment );
+ }
+ } //End examine segments in one area
+
+ if( error )
+ break;
+ }
+
+ if( !error )
+ m_IsFilled = true;
+
+ return count;
+}
+
+
diff --git a/pcbnew/zones.h b/pcbnew/zones.h
new file mode 100644
index 0000000..c08a300
--- /dev/null
+++ b/pcbnew/zones.h
@@ -0,0 +1,102 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2008-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef ZONES_H_
+#define ZONES_H_
+
+// keys used to store net sort option in config file :
+#define ZONE_NET_OUTLINES_HATCH_OPTION_KEY wxT( "Zone_Ouline_Hatch_Opt" )
+#define ZONE_NET_SORT_OPTION_KEY wxT( "Zone_NetSort_Opt" )
+#define ZONE_NET_FILTER_STRING_KEY wxT( "Zone_Filter_Opt" )
+#define ZONE_THERMAL_RELIEF_GAP_STRING_KEY wxT( "Zone_TH_Gap" )
+#define ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY wxT( "Zone_TH_Copper_Width" )
+#define ZONE_CLEARANCE_WIDTH_STRING_KEY wxT( "Zone_Clearance" )
+#define ZONE_MIN_THICKNESS_WIDTH_STRING_KEY wxT( "Zone_Thickness" )
+
+// Default values in mils for parameters in ZONE_CONTAINER
+#define ZONE_THERMAL_RELIEF_GAP_MIL 20 // default value for ZONE_SETTINGS::m_ThermalReliefGap
+#define ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL 20 // default value for ZONE_SETTINGS::m_ThermalReliefCopperBridge
+#define ZONE_THICKNESS_MIL 10 // default value for ZONE_SETTINGS::m_ZoneMinThickness
+#define ZONE_THICKNESS_MIN_VALUE_MIL 1 // minimum acceptable value for ZONE_SETTINGS::m_ZoneMinThickness
+#define ZONE_CLEARANCE_MIL 20 // default value for ZONE_SETTINGS::m_ZoneClearance
+#define ZONE_CLEARANCE_MAX_VALUE_MIL 500 // maximum acceptable value for ZONE_SETTINGS::m_ZoneClearance
+
+
+/// Exit codes for zone editing dialogs
+enum ZONE_EDIT_T {
+ ZONE_ABORT, ///< if no change
+ ZONE_OK, ///< if new values were accepted
+ ZONE_EXPORT_VALUES ///< if values were exported to others zones
+};
+
+
+/// How pads are covered by copper in zone
+enum ZoneConnection {
+ PAD_ZONE_CONN_INHERITED = -1,
+ PAD_ZONE_CONN_NONE, ///< Pads are not covered
+ PAD_ZONE_CONN_THERMAL, ///< Use thermal relief for pads
+ PAD_ZONE_CONN_FULL, ///< pads are covered by copper
+ PAD_ZONE_CONN_THT_THERMAL ///< Thermal relief only for THT pads
+};
+
+class ZONE_CONTAINER;
+class ZONE_SETTINGS;
+class PCB_BASE_FRAME;
+
+/**
+ * Function InvokeNonCopperZonesEditor
+ * invokes up a modal dialog window for non-copper zone editing.
+ *
+ * @param aParent is the PCB_BASE_FRAME calling parent window for the modal dialog,
+ * and it gives access to the BOARD through PCB_BASE_FRAME::GetBoard().
+ * @param aZone is the ZONE_CONTAINER to edit.
+ * @param aSettings points to the ZONE_SETTINGS to edit.
+ * @return ZONE_EDIT_T - tells if user aborted, changed only one zone, or all of them.
+ */
+ZONE_EDIT_T InvokeNonCopperZonesEditor( PCB_BASE_FRAME* aParent, ZONE_CONTAINER* aZone,
+ ZONE_SETTINGS* aSettings );
+
+/**
+ * Function InvokeCopperZonesEditor
+ * invokes up a modal dialog window for copper zone editing.
+ *
+ * @param aCaller is the PCB_BASE_FRAME calling parent window for the modal dialog,
+ * and it gives access to the BOARD through PCB_BASE_FRAME::GetBoard().
+ * @param aSettings points to the ZONE_SETTINGS to edit.
+ * @return ZONE_EDIT_T - tells if user aborted, changed only one zone, or all of them.
+ */
+ZONE_EDIT_T InvokeCopperZonesEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings );
+
+/**
+ * Function InvokeKeepoutAreaEditor
+ * invokes up a modal dialog window for copper zone editing.
+ *
+ * @param aCaller is the PCB_BASE_FRAME calling parent window for the modal dialog,
+ * and it gives access to the BOARD through PCB_BASE_FRAME::GetBoard().
+ * @param aSettings points to the ZONE_SETTINGS to edit.
+ * @return ZONE_EDIT_T - tells if user aborted, changed only one zone, or all of them.
+ */
+ZONE_EDIT_T InvokeKeepoutAreaEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings );
+
+#endif // ZONES_H_
diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp
new file mode 100644
index 0000000..31db133
--- /dev/null
+++ b/pcbnew/zones_by_polygon.cpp
@@ -0,0 +1,968 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file zones_by_polygon.cpp
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <class_drawpanel.h>
+#include <confirm.h>
+#include <wxPcbStruct.h>
+
+#include <class_board.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <zones.h>
+#include <pcbnew_id.h>
+#include <protos.h>
+#include <zones_functions_for_undo_redo.h>
+#include <drc_stuff.h>
+
+// Outline creation:
+static void Abort_Zone_Create_Outline( EDA_DRAW_PANEL* Panel, wxDC* DC );
+static void Show_New_Edge_While_Move_Mouse( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase );
+
+// Corner moving
+static void Abort_Zone_Move_Corner_Or_Outlines( EDA_DRAW_PANEL* Panel, wxDC* DC );
+static void Show_Zone_Corner_Or_Outline_While_Move_Mouse( EDA_DRAW_PANEL* aPanel,
+ wxDC* aDC,
+ const wxPoint& aPosition,
+ bool aErase );
+
+// Local variables
+static wxPoint s_CornerInitialPosition; // Used to abort a move corner command
+static bool s_CornerIsNew; // Used to abort a move corner command (if it is a new corner, it must be deleted)
+static bool s_AddCutoutToCurrentZone; // if true, the next outline will be added to s_CurrentZone
+static ZONE_CONTAINER* s_CurrentZone; // if != NULL, these ZONE_CONTAINER params will be used for the next zone
+static wxPoint s_CursorLastPosition; // in move zone outline, last cursor position. Used to calculate the move vector
+static PICKED_ITEMS_LIST s_PickedList; // a picked list to save zones for undo/redo command
+static PICKED_ITEMS_LIST s_AuxiliaryList; // a picked list to store zones that are deleted or added when combined
+
+
+void PCB_EDIT_FRAME::Add_Similar_Zone( wxDC* DC, ZONE_CONTAINER* aZone )
+{
+ if( !aZone )
+ return;
+
+ s_AddCutoutToCurrentZone = false;
+ s_CurrentZone = aZone;
+
+ // set zone settings to the current zone
+ ZONE_SETTINGS zoneInfo = GetZoneSettings();
+ zoneInfo << *aZone;
+ SetZoneSettings( zoneInfo );
+
+ // Use the general event handler to set others params (like toolbar)
+ wxCommandEvent evt;
+ evt.SetId( aZone->GetIsKeepout() ? ID_PCB_KEEPOUT_AREA_BUTT : ID_PCB_ZONES_BUTT );
+ OnSelectTool( evt );
+}
+
+
+void PCB_EDIT_FRAME::Add_Zone_Cutout( wxDC* DC, ZONE_CONTAINER* aZone )
+{
+ if( !aZone )
+ return;
+
+ s_AddCutoutToCurrentZone = true;
+ s_CurrentZone = aZone;
+
+ // set zones setup to the current zone
+ ZONE_SETTINGS zoneInfo = GetZoneSettings();
+ zoneInfo << *aZone;
+ SetZoneSettings( zoneInfo );
+
+ // Use the general event handle to set others params (like toolbar)
+ wxCommandEvent evt;
+ evt.SetId( aZone->GetIsKeepout() ? ID_PCB_KEEPOUT_AREA_BUTT : ID_PCB_ZONES_BUTT );
+ OnSelectTool( evt );
+}
+
+
+void PCB_EDIT_FRAME::duplicateZone( wxDC* aDC, ZONE_CONTAINER* aZone )
+{
+ ZONE_CONTAINER* newZone = new ZONE_CONTAINER( GetBoard() );
+ newZone->Copy( aZone );
+ newZone->UnFill();
+ ZONE_SETTINGS zoneSettings;
+ zoneSettings << *aZone;
+
+ bool success;
+
+ if( aZone->GetIsKeepout() )
+ success = InvokeKeepoutAreaEditor( this, &zoneSettings );
+ else if( aZone->IsOnCopperLayer() )
+ success = InvokeCopperZonesEditor( this, &zoneSettings );
+ else
+ success = InvokeNonCopperZonesEditor( this, aZone, &zoneSettings );
+
+ // If the new zone is on the same layer as the the initial zone,
+ // do nothing
+ if( success && ( aZone->GetLayer() == zoneSettings.m_CurrentZone_Layer ) )
+ {
+ DisplayError( this,
+ _( "The duplicated zone is on the same layer as the initial zone, which has no sense.\n"
+ "Please, choose an other layer for the new zone") );
+ success = false;
+ }
+
+ if( success )
+ {
+ zoneSettings.ExportSetting( *newZone );
+ newZone->Outline()->Hatch();
+
+ s_AuxiliaryList.ClearListAndDeleteItems();
+ s_PickedList.ClearListAndDeleteItems();
+ SaveCopyOfZones( s_PickedList, GetBoard(), newZone->GetNetCode(), newZone->GetLayer() );
+ GetBoard()->Add( newZone );
+
+ ITEM_PICKER picker( newZone, UR_NEW );
+ s_PickedList.PushItem( picker );
+
+ GetScreen()->SetCurItem( NULL ); // This outline may be deleted when merging outlines
+
+ // Combine zones if possible
+ GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, newZone );
+
+ // Redraw zones
+ GetBoard()->RedrawAreasOutlines( m_canvas, aDC, GR_OR, newZone->GetLayer() );
+ GetBoard()->RedrawFilledAreas( m_canvas, aDC, GR_OR, newZone->GetLayer() );
+
+ if( GetBoard()->GetAreaIndex( newZone ) >= 0
+ && GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( newZone, true ) )
+ {
+ DisplayError( this,
+ _( "The outline of the duplicated zone fails DRC check!" ) );
+ }
+
+ UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
+ SaveCopyInUndoList( s_PickedList, UR_UNSPECIFIED );
+ s_PickedList.ClearItemsList();
+
+ OnModify();
+ }
+ else
+ delete newZone;
+}
+
+
+int PCB_EDIT_FRAME::Delete_LastCreatedCorner( wxDC* DC )
+{
+ ZONE_CONTAINER* zone = GetBoard()->m_CurrentZoneContour;
+
+ if( !zone )
+ return 0;
+
+ if( !zone->GetNumCorners() )
+ return 0;
+
+ zone->DrawWhileCreateOutline( m_canvas, DC, GR_XOR );
+
+ if( zone->GetNumCorners() > 2 )
+ {
+ zone->Outline()->DeleteCorner( zone->GetNumCorners() - 1 );
+
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
+ }
+ else
+ {
+ m_canvas->SetMouseCapture( NULL, NULL );
+ SetCurItem( NULL );
+ zone->RemoveAllContours();
+ zone->ClearFlags();
+ }
+
+ return zone->GetNumCorners();
+}
+
+
+/**
+ * Function Abort_Zone_Create_Outline
+ * cancels the Begin_Zone command if at least one EDGE_ZONE was created.
+ */
+static void Abort_Zone_Create_Outline( EDA_DRAW_PANEL* Panel, wxDC* DC )
+{
+ PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Panel->GetParent();
+ ZONE_CONTAINER* zone = pcbframe->GetBoard()->m_CurrentZoneContour;
+
+ if( zone )
+ {
+ zone->DrawWhileCreateOutline( Panel, DC, GR_XOR );
+ zone->RemoveAllContours();
+ if( zone->IsNew() )
+ {
+ delete zone;
+ pcbframe->GetBoard()->m_CurrentZoneContour = NULL;
+ }
+ else
+ zone->ClearFlags();
+ }
+
+ pcbframe->SetCurItem( NULL );
+ s_AddCutoutToCurrentZone = false;
+ s_CurrentZone = NULL;
+ Panel->SetMouseCapture( NULL, NULL );
+}
+
+
+void PCB_EDIT_FRAME::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone,
+ int corner_id, bool IsNewCorner )
+{
+ if( aZone->IsOnCopperLayer() ) // Show the Net
+ {
+ if( GetBoard()->IsHighLightNetON() && DC )
+ {
+ HighLight( DC ); // Remove old highlight selection
+ }
+
+ ZONE_SETTINGS zoneInfo = GetZoneSettings();
+ zoneInfo.m_NetcodeSelection = aZone->GetNetCode();
+ SetZoneSettings( zoneInfo );
+
+ GetBoard()->SetHighLightNet( aZone->GetNetCode() );
+
+ if( DC )
+ HighLight( DC );
+ }
+
+
+ // Prepare copy of old zones, for undo/redo.
+ // if the corner is new, remove it from list, save and insert it in list
+ int cx = aZone->Outline()->GetX( corner_id );
+ int cy = aZone->Outline()->GetY( corner_id );
+
+ if ( IsNewCorner )
+ aZone->Outline()->DeleteCorner( corner_id );
+
+ s_AuxiliaryList.ClearListAndDeleteItems();
+ s_PickedList.ClearListAndDeleteItems();
+
+ SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() );
+
+ if ( IsNewCorner )
+ aZone->Outline()->InsertCorner(corner_id-1, cx, cy );
+
+ aZone->SetFlags( IN_EDIT );
+ m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse,
+ Abort_Zone_Move_Corner_Or_Outlines );
+ s_CornerInitialPosition = aZone->GetCornerPosition( corner_id );
+ s_CornerIsNew = IsNewCorner;
+ s_AddCutoutToCurrentZone = false;
+ s_CurrentZone = NULL;
+}
+
+
+void PCB_EDIT_FRAME::Start_Move_Zone_Drag_Outline_Edge( wxDC* DC,
+ ZONE_CONTAINER* aZone,
+ int corner_id )
+{
+ aZone->SetFlags( IS_DRAGGED );
+ aZone->SetSelectedCorner( corner_id );
+ m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse,
+ Abort_Zone_Move_Corner_Or_Outlines );
+ s_CursorLastPosition = s_CornerInitialPosition = GetCrossHairPosition();
+ s_AddCutoutToCurrentZone = false;
+ s_CurrentZone = NULL;
+
+ s_PickedList.ClearListAndDeleteItems();
+ s_AuxiliaryList.ClearListAndDeleteItems();
+ SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() );
+}
+
+
+void PCB_EDIT_FRAME::Start_Move_Zone_Outlines( wxDC* DC, ZONE_CONTAINER* aZone )
+{
+ // Show the Net
+ if( aZone->IsOnCopperLayer() ) // Show the Net
+ {
+ if( GetBoard()->IsHighLightNetON() )
+ {
+ HighLight( DC ); // Remove old highlight selection
+ }
+
+ ZONE_SETTINGS zoneInfo = GetZoneSettings();
+ zoneInfo.m_NetcodeSelection = aZone->GetNetCode();
+ SetZoneSettings( zoneInfo );
+
+ GetBoard()->SetHighLightNet( aZone->GetNetCode() );
+ HighLight( DC );
+ }
+
+ s_PickedList.ClearListAndDeleteItems();
+ s_AuxiliaryList.ClearListAndDeleteItems();
+ SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() );
+
+ aZone->SetFlags( IS_MOVED );
+ m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse,
+ Abort_Zone_Move_Corner_Or_Outlines );
+ s_CursorLastPosition = s_CornerInitialPosition = GetCrossHairPosition();
+ s_CornerIsNew = false;
+ s_AddCutoutToCurrentZone = false;
+ s_CurrentZone = NULL;
+}
+
+
+void PCB_EDIT_FRAME::End_Move_Zone_Corner_Or_Outlines( wxDC* DC, ZONE_CONTAINER* aZone )
+{
+ aZone->ClearFlags();
+ m_canvas->SetMouseCapture( NULL, NULL );
+
+ if( DC )
+ aZone->Draw( m_canvas, DC, GR_OR );
+
+ OnModify();
+ s_AddCutoutToCurrentZone = false;
+ s_CurrentZone = NULL;
+
+ SetCurItem( NULL ); // This outline can be deleted when merging outlines
+
+ // Combine zones if possible
+ GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone );
+ m_canvas->Refresh();
+
+ int ii = GetBoard()->GetAreaIndex( aZone ); // test if aZone exists
+
+ if( ii < 0 )
+ aZone = NULL; // was removed by combining zones
+
+ UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
+ SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
+ s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
+
+ int error_count = GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( aZone, true );
+
+ if( error_count )
+ {
+ DisplayError( this, _( "Area: DRC outline error" ) );
+ }
+}
+
+
+void PCB_EDIT_FRAME::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone )
+{
+ OnModify();
+
+ if( aZone->Outline()->GetCornersCount() <= 3 )
+ {
+ m_canvas->RefreshDrawingRect( aZone->GetBoundingBox() );
+
+ if( DC )
+ { // Remove the full zone because this is no more an area
+ aZone->UnFill();
+ aZone->DrawFilledArea( m_canvas, DC, GR_XOR );
+ }
+
+ GetBoard()->Delete( aZone );
+ return;
+ }
+
+ LAYER_ID layer = aZone->GetLayer();
+
+ if( DC )
+ {
+ GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_XOR, layer );
+ GetBoard()->RedrawFilledAreas( m_canvas, DC, GR_XOR, layer );
+ }
+
+ s_AuxiliaryList.ClearListAndDeleteItems();
+ s_PickedList. ClearListAndDeleteItems();
+ SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() );
+ aZone->Outline()->DeleteCorner( aZone->GetSelectedCorner() );
+
+ // modify zones outlines according to the new aZone shape
+ GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone );
+
+ if( DC )
+ {
+ GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_OR, layer );
+ GetBoard()->RedrawFilledAreas( m_canvas, DC, GR_OR, layer );
+ }
+
+ UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
+ SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
+ s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
+
+ int ii = GetBoard()->GetAreaIndex( aZone ); // test if aZone exists
+
+ if( ii < 0 )
+ aZone = NULL; // aZone does not exist anymore, after combining zones
+
+ int error_count = GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( aZone, true );
+
+ if( error_count )
+ {
+ DisplayError( this, _( "Area: DRC outline error" ) );
+ }
+}
+
+
+/**
+ * Function Abort_Zone_Move_Corner_Or_Outlines
+ * cancels the Begin_Zone state if at least one EDGE_ZONE has been created.
+ */
+void Abort_Zone_Move_Corner_Or_Outlines( EDA_DRAW_PANEL* Panel, wxDC* DC )
+{
+ PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Panel->GetParent();
+ ZONE_CONTAINER* zone = (ZONE_CONTAINER*) pcbframe->GetCurItem();
+
+ if( zone->IsMoving() )
+ {
+ wxPoint offset;
+ offset = s_CornerInitialPosition - s_CursorLastPosition;
+ zone->Move( offset );
+ }
+ else if( zone->IsDragging() )
+ {
+ wxPoint offset = s_CornerInitialPosition - s_CursorLastPosition;
+ int selection = zone->GetSelectedCorner();
+ zone->MoveEdge( offset, selection );
+ }
+ else
+ {
+ if( s_CornerIsNew )
+ {
+ zone->Outline()->DeleteCorner( zone->GetSelectedCorner() );
+ }
+ else
+ {
+ wxPoint pos = s_CornerInitialPosition;
+ zone->Outline()->MoveCorner( zone->GetSelectedCorner(), pos.x, pos.y );
+ }
+ }
+
+ Panel->SetMouseCapture( NULL, NULL );
+ s_AuxiliaryList.ClearListAndDeleteItems();
+ s_PickedList. ClearListAndDeleteItems();
+ Panel->Refresh();
+
+ pcbframe->SetCurItem( NULL );
+ zone->ClearFlags();
+ s_AddCutoutToCurrentZone = false;
+ s_CurrentZone = NULL;
+}
+
+
+/// Redraws the zone outline when moving a corner according to the cursor position
+void Show_Zone_Corner_Or_Outline_While_Move_Mouse( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase )
+{
+ PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) aPanel->GetParent();
+ ZONE_CONTAINER* zone = (ZONE_CONTAINER*) pcbframe->GetCurItem();
+
+ if( aErase ) // Undraw edge in old position
+ {
+ zone->Draw( aPanel, aDC, GR_XOR );
+ }
+
+ wxPoint pos = pcbframe->GetCrossHairPosition();
+
+ if( zone->IsMoving() )
+ {
+ wxPoint offset;
+ offset = pos - s_CursorLastPosition;
+ zone->Move( offset );
+ s_CursorLastPosition = pos;
+ }
+ else if( zone->IsDragging() )
+ {
+ wxPoint offset = pos - s_CursorLastPosition;
+ int selection = zone->GetSelectedCorner();
+ zone->MoveEdge( offset, selection );
+ s_CursorLastPosition = pos;
+ }
+ else
+ {
+ zone->Outline()->MoveCorner( zone->GetSelectedCorner(), pos.x, pos.y );
+ }
+
+ zone->Draw( aPanel, aDC, GR_XOR );
+}
+
+
+
+int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC )
+{
+ ZONE_SETTINGS zoneInfo = GetZoneSettings();
+
+ // verify if s_CurrentZone exists (could be deleted since last selection) :
+ int ii;
+ for( ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
+ {
+ if( s_CurrentZone == GetBoard()->GetArea( ii ) )
+ break;
+ }
+
+ if( ii >= GetBoard()->GetAreaCount() ) // Not found: could be deleted since last selection
+ {
+ s_AddCutoutToCurrentZone = false;
+ s_CurrentZone = NULL;
+ }
+
+ ZONE_CONTAINER* zone = GetBoard()->m_CurrentZoneContour;
+
+ // Verify if a new zone is allowed on this layer:
+ if( zone == NULL )
+ {
+ if( GetToolId() == ID_PCB_KEEPOUT_AREA_BUTT && !IsCopperLayer( GetActiveLayer() ) )
+ {
+ DisplayError( this,
+ _( "Error: a keepout area is allowed only on copper layers" ) );
+ return 0;
+ }
+ }
+
+ // If no zone contour in progress, a new zone is being created,
+ if( zone == NULL )
+ {
+ zone = GetBoard()->m_CurrentZoneContour = new ZONE_CONTAINER( GetBoard() );
+ zone->SetFlags( IS_NEW );
+ zone->SetTimeStamp( GetNewTimeStamp() );
+ }
+
+ if( zone->GetNumCorners() == 0 ) // Start a new contour: init zone params (net, layer ...)
+ {
+ if( !s_CurrentZone ) // A new outline is created, from scratch
+ {
+ ZONE_EDIT_T edited;
+
+ // Init zone params to reasonable values
+ zone->SetLayer( GetActiveLayer() );
+
+ // Prompt user for parameters:
+ m_canvas->SetIgnoreMouseEvents( true );
+
+ if( zone->IsOnCopperLayer() )
+ {
+ // Put a zone on a copper layer
+ if( GetBoard()->GetHighLightNetCode() > 0 )
+ {
+ zoneInfo.m_NetcodeSelection = GetBoard()->GetHighLightNetCode();
+ zone->SetNetCode( zoneInfo.m_NetcodeSelection );
+ }
+
+ double tmp = ZONE_THERMAL_RELIEF_GAP_MIL;
+
+ wxConfigBase* cfg = Kiface().KifaceSettings();
+ cfg->Read( ZONE_THERMAL_RELIEF_GAP_STRING_KEY, &tmp );
+ zoneInfo.m_ThermalReliefGap = KiROUND( tmp * IU_PER_MILS);
+
+ tmp = ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL;
+ cfg->Read( ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY, &tmp );
+ zoneInfo.m_ThermalReliefCopperBridge = KiROUND( tmp * IU_PER_MILS );
+
+ tmp = ZONE_CLEARANCE_MIL;
+ cfg->Read( ZONE_CLEARANCE_WIDTH_STRING_KEY, &tmp );
+ zoneInfo.m_ZoneClearance = KiROUND( tmp * IU_PER_MILS );
+
+ tmp = ZONE_THICKNESS_MIL;
+ cfg->Read( ZONE_MIN_THICKNESS_WIDTH_STRING_KEY, &tmp );
+ zoneInfo.m_ZoneMinThickness = KiROUND( tmp * IU_PER_MILS );
+
+ zoneInfo.m_CurrentZone_Layer = zone->GetLayer();
+
+ if( GetToolId() == ID_PCB_KEEPOUT_AREA_BUTT )
+ {
+ zoneInfo.SetIsKeepout( true );
+ // Netcode, netname and some other settings are irrelevant,
+ // so ensure they are cleared
+ zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
+ zoneInfo.SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_NONE );
+ zoneInfo.SetCornerRadius( 0 );
+
+ edited = InvokeKeepoutAreaEditor( this, &zoneInfo );
+ }
+ else
+ {
+ zoneInfo.SetIsKeepout( false );
+ edited = InvokeCopperZonesEditor( this, &zoneInfo );
+ }
+ }
+ else // Put a zone on a non copper layer (technical layer)
+ {
+ zoneInfo.SetIsKeepout( false );
+ zoneInfo.m_NetcodeSelection = 0; // No net for non copper zones
+ edited = InvokeNonCopperZonesEditor( this, zone, &zoneInfo );
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+
+ if( edited == ZONE_ABORT )
+ {
+ GetBoard()->m_CurrentZoneContour = NULL;
+ delete zone;
+ return 0;
+ }
+
+ // Switch active layer to the selected zone layer
+ SetActiveLayer( zoneInfo.m_CurrentZone_Layer );
+ SetZoneSettings( zoneInfo );
+ }
+ else
+ {
+ // Start a new contour: init zone params (net and layer) from an existing
+ // zone (add cutout or similar zone)
+
+ zoneInfo.m_CurrentZone_Layer = s_CurrentZone->GetLayer();
+ SetActiveLayer( s_CurrentZone->GetLayer() );
+
+ zoneInfo << *s_CurrentZone;
+
+ SetZoneSettings( zoneInfo );
+ }
+
+ // Show the Net for zones on copper layers
+ if( IsCopperLayer( zoneInfo.m_CurrentZone_Layer ) &&
+ !zoneInfo.GetIsKeepout() )
+ {
+ if( s_CurrentZone )
+ {
+ zoneInfo.m_NetcodeSelection = s_CurrentZone->GetNetCode();
+ GetBoard()->SetZoneSettings( zoneInfo );
+ }
+
+ if( GetBoard()->IsHighLightNetON() )
+ {
+ HighLight( DC ); // Remove old highlight selection
+ }
+
+ GetBoard()->SetHighLightNet( zoneInfo.m_NetcodeSelection );
+ HighLight( DC );
+ }
+
+ if( !s_AddCutoutToCurrentZone )
+ s_CurrentZone = NULL; // the zone is used only once ("add similar zone" command)
+ }
+
+ // if first segment
+ if( zone->GetNumCorners() == 0 )
+ {
+ zoneInfo.ExportSetting( *zone );
+
+ zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer,
+ GetCrossHairPosition().x,
+ GetCrossHairPosition().y,
+ zone->GetHatchStyle() );
+
+ zone->AppendCorner( GetCrossHairPosition() );
+
+ if( g_Drc_On && (m_drc->Drc( zone, 0 ) == BAD_DRC) && zone->IsOnCopperLayer() )
+ {
+ zone->ClearFlags();
+ zone->RemoveAllContours();
+
+ // use the form of SetCurItem() which does not write to the msg panel,
+ // SCREEN::SetCurItem(), so the DRC error remains on screen.
+ // PCB_EDIT_FRAME::SetCurItem() calls DisplayInfo().
+ GetScreen()->SetCurItem( NULL );
+ DisplayError( this,
+ _( "DRC error: this start point is inside or too close an other area" ) );
+ return 0;
+ }
+
+ SetCurItem( zone );
+ m_canvas->SetMouseCapture( Show_New_Edge_While_Move_Mouse, Abort_Zone_Create_Outline );
+ }
+ else // edge in progress:
+ {
+ ii = zone->GetNumCorners() - 1;
+
+ // edge in progress : the current corner coordinate was set
+ // by Show_New_Edge_While_Move_Mouse
+ if( zone->GetCornerPosition( ii - 1 ) != zone->GetCornerPosition( ii ) )
+ {
+ if( !g_Drc_On || !zone->IsOnCopperLayer() || ( m_drc->Drc( zone, ii - 1 ) == OK_DRC ) )
+ {
+ // Ok, we can add a new corner
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxPoint(0,0), false );
+ zone->AppendCorner( GetCrossHairPosition() );
+ SetCurItem( zone ); // calls DisplayInfo().
+ if( m_canvas->IsMouseCaptured() )
+ m_canvas->CallMouseCapture( DC, wxPoint(0,0), false );
+ }
+ }
+ }
+
+ return zone->GetNumCorners();
+}
+
+
+bool PCB_EDIT_FRAME::End_Zone( wxDC* DC )
+{
+ ZONE_CONTAINER* zone = GetBoard()->m_CurrentZoneContour;
+
+ if( !zone )
+ return true;
+
+ // Validate the current outline:
+ if( zone->GetNumCorners() <= 2 ) // An outline must have 3 corners or more
+ {
+ Abort_Zone_Create_Outline( m_canvas, DC );
+ return true;
+ }
+
+ // Remove the last corner if is is at the same location as the prevoius corner
+ zone->Outline()->RemoveNullSegments();
+
+ // Validate the current edge:
+ int icorner = zone->GetNumCorners() - 1;
+ if( zone->IsOnCopperLayer() )
+ {
+ if( g_Drc_On && m_drc->Drc( zone, icorner - 1 ) == BAD_DRC ) // we can't validate last edge
+ return false;
+
+ if( g_Drc_On && m_drc->Drc( zone, icorner ) == BAD_DRC ) // we can't validate the closing edge
+ {
+ DisplayError( this,
+ _( "DRC error: closing this area creates a DRC error with an other area" ) );
+ m_canvas->MoveCursorToCrossHair();
+ return false;
+ }
+ }
+
+ zone->ClearFlags();
+
+ zone->DrawWhileCreateOutline( m_canvas, DC, GR_XOR );
+
+ m_canvas->SetMouseCapture( NULL, NULL );
+
+ // Undraw old drawings, because they can have important changes
+ LAYER_ID layer = zone->GetLayer();
+ GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_XOR, layer );
+ GetBoard()->RedrawFilledAreas( m_canvas, DC, GR_XOR, layer );
+
+ // Save initial zones configuration, for undo/redo, before adding new zone
+ s_AuxiliaryList.ClearListAndDeleteItems();
+ s_PickedList.ClearListAndDeleteItems();
+ SaveCopyOfZones(s_PickedList, GetBoard(), zone->GetNetCode(), zone->GetLayer() );
+
+ // Put new zone in list
+ if( !s_CurrentZone )
+ {
+ zone->Outline()->CloseLastContour(); // Close the current corner list
+ GetBoard()->Add( zone );
+ GetBoard()->m_CurrentZoneContour = NULL;
+
+ // Add this zone in picked list, as new item
+ ITEM_PICKER picker( zone, UR_NEW );
+ s_PickedList.PushItem( picker );
+ }
+ else // Append this outline as a cutout to an existing zone
+ {
+ for( int ii = 0; ii < zone->GetNumCorners(); ii++ )
+ {
+ s_CurrentZone->AppendCorner( zone->GetCornerPosition( ii ) );
+ }
+
+ s_CurrentZone->Outline()->CloseLastContour(); // Close the current corner list
+ zone->RemoveAllContours(); // All corners are copied in s_CurrentZone. Free corner list.
+ zone = s_CurrentZone;
+ }
+
+ s_AddCutoutToCurrentZone = false;
+ s_CurrentZone = NULL;
+
+ GetScreen()->SetCurItem( NULL ); // This outline can be deleted when merging outlines
+
+ // Combine zones if possible :
+ GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, zone );
+
+ // Redraw the real edge zone :
+ GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_OR, layer );
+ GetBoard()->RedrawFilledAreas( m_canvas, DC, GR_OR, layer );
+
+ int ii = GetBoard()->GetAreaIndex( zone ); // test if zone exists
+
+ if( ii < 0 )
+ zone = NULL; // was removed by combining zones
+
+ int error_count = GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( zone, true );
+
+ if( error_count )
+ {
+ DisplayError( this, _( "Area: DRC outline error" ) );
+ }
+
+ UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
+ SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
+ s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
+
+ OnModify();
+ return true;
+}
+
+
+/* Redraws the zone outlines when moving mouse
+ */
+static void Show_New_Edge_While_Move_Mouse( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
+ const wxPoint& aPosition, bool aErase )
+{
+ PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) aPanel->GetParent();
+ wxPoint c_pos = pcbframe->GetCrossHairPosition();
+ ZONE_CONTAINER* zone = pcbframe->GetBoard()->m_CurrentZoneContour;
+
+ if( !zone )
+ return;
+
+ int icorner = zone->GetNumCorners() - 1;
+
+ if( icorner < 1 )
+ return; // We must have 2 (or more) corners
+
+ if( aErase ) // Undraw edge in old position
+ {
+ zone->DrawWhileCreateOutline( aPanel, aDC );
+ }
+
+ // Redraw the current edge in its new position
+ if( pcbframe->GetZoneSettings().m_Zone_45_Only )
+ {
+ // calculate the new position as allowed
+ wxPoint StartPoint = zone->GetCornerPosition( icorner - 1 );
+ CalculateSegmentEndPoint( c_pos, StartPoint.x, StartPoint.y, &c_pos.x, &c_pos.y );
+ }
+
+ zone->SetCornerPosition( icorner, c_pos );
+
+ zone->DrawWhileCreateOutline( aPanel, aDC );
+}
+
+
+void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone )
+{
+ ZONE_EDIT_T edited;
+ ZONE_SETTINGS zoneInfo = GetZoneSettings();
+
+ m_canvas->SetIgnoreMouseEvents( true );
+
+ // Save initial zones configuration, for undo/redo, before adding new zone
+ // note the net name and the layer can be changed, so we must save all zones
+ s_AuxiliaryList.ClearListAndDeleteItems();
+ s_PickedList.ClearListAndDeleteItems();
+ SaveCopyOfZones(s_PickedList, GetBoard(), -1, UNDEFINED_LAYER );
+
+ if( aZone->GetIsKeepout() )
+ {
+ // edit a keepout area on a copper layer
+ zoneInfo << *aZone;
+ edited = InvokeKeepoutAreaEditor( this, &zoneInfo );
+ }
+ else if( IsCopperLayer( aZone->GetLayer() ) )
+ {
+ // edit a zone on a copper layer
+
+ zoneInfo << *aZone;
+
+ edited = InvokeCopperZonesEditor( this, &zoneInfo );
+ }
+ else
+ {
+ edited = InvokeNonCopperZonesEditor( this, aZone, &zoneInfo );
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+
+ if( edited == ZONE_ABORT )
+ {
+ s_AuxiliaryList.ClearListAndDeleteItems();
+ s_PickedList.ClearListAndDeleteItems();
+ return;
+ }
+
+ SetZoneSettings( zoneInfo );
+
+ if( edited == ZONE_EXPORT_VALUES )
+ {
+ UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
+ SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
+ s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
+ return;
+ }
+
+ // Undraw old zone outlines
+ for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* edge_zone = GetBoard()->GetArea( ii );
+ edge_zone->Draw( m_canvas, DC, GR_XOR );
+ }
+
+ zoneInfo.ExportSetting( *aZone );
+
+ NETINFO_ITEM* net = GetBoard()->FindNet( zoneInfo.m_NetcodeSelection );
+
+ if( net ) // net == NULL should not occur
+ aZone->SetNetCode( net->GetNet() );
+
+ // Combine zones if possible
+ GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone );
+
+ // Redraw the real new zone outlines
+ GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_OR, UNDEFINED_LAYER );
+
+ UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
+ SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
+
+ s_PickedList.ClearItemsList(); // s_ItemsListPicker is no longer owner of picked items
+
+ OnModify();
+}
+
+
+void PCB_EDIT_FRAME::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* aZone )
+{
+ int ncont = aZone->Outline()->GetContour( aZone->GetSelectedCorner() );
+
+ EDA_RECT dirty = aZone->GetBoundingBox();
+
+ // For compatibility with old boards: remove old SEGZONE fill segments
+ Delete_OldZone_Fill( NULL, aZone->GetTimeStamp() );
+
+ // Remove current filling:
+ aZone->UnFill();
+
+ if( ncont == 0 ) // This is the main outline: remove all
+ {
+ SaveCopyInUndoList( aZone, UR_DELETED );
+ GetBoard()->Remove( aZone );
+ }
+
+ else
+ {
+ SaveCopyInUndoList( aZone, UR_CHANGED );
+ aZone->Outline()->RemoveContour( ncont );
+ }
+
+ m_canvas->RefreshDrawingRect( dirty );
+
+ OnModify();
+}
diff --git a/pcbnew/zones_by_polygon_fill_functions.cpp b/pcbnew/zones_by_polygon_fill_functions.cpp
new file mode 100644
index 0000000..16e2088
--- /dev/null
+++ b/pcbnew/zones_by_polygon_fill_functions.cpp
@@ -0,0 +1,188 @@
+/*
+ * @file zones_by_polygon_fill_functions.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
+ * Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <wx/progdlg.h>
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <class_draw_panel_gal.h>
+#include <ratsnest_data.h>
+#include <wxPcbStruct.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_track.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <zones.h>
+
+#define FORMAT_STRING _( "Filling zone %d out of %d (net %s)..." )
+
+
+/**
+ * Function Delete_OldZone_Fill (obsolete)
+ * Used for compatibility with old boards
+ * Remove the zone filling which include the segment aZone, or the zone which have the
+ * given time stamp.
+ * A zone is a group of segments which have the same TimeStamp
+ * @param aZone = zone segment within the zone to delete. Can be NULL
+ * @param aTimestamp = Timestamp for the zone to delete, used if aZone == NULL
+ */
+void PCB_EDIT_FRAME::Delete_OldZone_Fill( SEGZONE* aZone, time_t aTimestamp )
+{
+ bool modify = false;
+ time_t TimeStamp;
+
+ if( aZone == NULL )
+ TimeStamp = aTimestamp;
+ else
+ TimeStamp = aZone->GetTimeStamp(); // Save reference time stamp (aZone will be deleted)
+
+ SEGZONE* next;
+
+ for( SEGZONE* zone = GetBoard()->m_Zone; zone != NULL; zone = next )
+ {
+ next = zone->Next();
+
+ if( zone->GetTimeStamp() == TimeStamp )
+ {
+ modify = true;
+ // remove item from linked list and free memory
+ zone->DeleteStructure();
+ }
+ }
+
+ if( modify )
+ {
+ OnModify();
+ m_canvas->Refresh();
+ }
+}
+
+
+int PCB_EDIT_FRAME::Fill_Zone( ZONE_CONTAINER* aZone )
+{
+ aZone->ClearFilledPolysList();
+ aZone->UnFill();
+
+ // Cannot fill keepout zones:
+ if( aZone->GetIsKeepout() )
+ return 1;
+
+ wxString msg;
+
+ ClearMsgPanel();
+
+ // Shows the net
+ ZONE_SETTINGS zoneInfo = GetZoneSettings();
+ zoneInfo.m_NetcodeSelection = aZone->GetNetCode();
+ SetZoneSettings( zoneInfo );
+
+ msg = aZone->GetNetname();
+
+ if( msg.IsEmpty() )
+ msg = wxT( "No net" );
+
+ AppendMsgPanel( _( "NetName" ), msg, RED );
+
+ wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor)
+
+ aZone->BuildFilledSolidAreasPolygons( GetBoard() );
+ aZone->ViewUpdate( KIGFX::VIEW_ITEM::ALL );
+ GetBoard()->GetRatsnest()->Update( aZone );
+
+ OnModify();
+
+ return 0;
+}
+
+
+int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose )
+{
+ int errorLevel = 0;
+ int areaCount = GetBoard()->GetAreaCount();
+ wxBusyCursor dummyCursor;
+ wxString msg;
+ wxProgressDialog * progressDialog = NULL;
+
+ // Create a message with a long net name, and build a wxProgressDialog
+ // with a correct size to show this long net name
+ msg.Printf( FORMAT_STRING, 000, areaCount, wxT("XXXXXXXXXXXXXXXXX" ) );
+
+ if( aActiveWindow )
+ progressDialog = new wxProgressDialog( _( "Fill All Zones" ), msg,
+ areaCount+2, aActiveWindow,
+ wxPD_AUTO_HIDE | wxPD_CAN_ABORT |
+ wxPD_APP_MODAL | wxPD_ELAPSED_TIME );
+ // Display the actual message
+ if( progressDialog )
+ progressDialog->Update( 0, _( "Starting zone fill..." ) );
+
+ // Remove segment zones
+ GetBoard()->m_Zone.DeleteAll();
+
+ int ii;
+
+ for( ii = 0; ii < areaCount; ii++ )
+ {
+ ZONE_CONTAINER* zoneContainer = GetBoard()->GetArea( ii );
+ if( zoneContainer->GetIsKeepout() )
+ continue;
+
+ msg.Printf( FORMAT_STRING, ii + 1, areaCount, GetChars( zoneContainer->GetNetname() ) );
+
+ if( progressDialog )
+ {
+ if( !progressDialog->Update( ii+1, msg ) )
+ break; // Aborted by user
+ }
+
+ errorLevel = Fill_Zone( zoneContainer );
+
+ if( errorLevel && !aVerbose )
+ break;
+ }
+
+ if( progressDialog )
+ {
+ progressDialog->Update( ii+2, _( "Updating ratsnest..." ) );
+#ifdef __WXMAC__
+ // Work around a dialog z-order issue on OS X
+ aActiveWindow->Raise();
+#endif
+ }
+ TestConnections();
+
+ // Recalculate the active ratsnest, i.e. the unconnected links
+ TestForActiveLinksInRatsnest( 0 );
+ if( progressDialog )
+ progressDialog->Destroy();
+ return errorLevel;
+}
diff --git a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp
new file mode 100644
index 0000000..c02d570
--- /dev/null
+++ b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp
@@ -0,0 +1,508 @@
+/**
+ * @file zones_convert_brd_items_to_polygons_with_Boost.cpp
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Functions to convert some board items to polygons
+ * (pads, tracks ..)
+ * This is used to calculate filled areas in copper zones.
+ * Filled areas are areas remainder of the full zone area after removed all polygons
+ * calculated from these items shapes and the clearance area
+ *
+ * Important note:
+ * Because filled areas must have a minimum thickness to match with Design rule, they are
+ * draw in 2 step:
+ * 1 - filled polygons are drawn
+ * 2 - polygon outlines are drawn with a "minimum thickness width" ( or with a minimum
+ * thickness pen )
+ * So outlines of filled polygons are calculated with the constraint they match with clearance,
+ * taking in account outlines have thickness
+ * This ensures:
+ * - areas meet the minimum thickness requirement.
+ * - shapes are smoothed.
+ */
+
+#include <cmath>
+#include <sstream>
+
+#include <fctsys.h>
+#include <wxPcbStruct.h>
+#include <trigo.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_edge_mod.h>
+#include <class_drawsegment.h>
+#include <class_pcb_text.h>
+#include <class_zone.h>
+#include <project.h>
+
+#include <pcbnew.h>
+#include <zones.h>
+#include <convert_basic_shapes_to_polygon.h>
+
+#include <geometry/shape_poly_set.h>
+#include <geometry/shape_file_io.h>
+
+#include <boost/foreach.hpp>
+
+extern void BuildUnconnectedThermalStubsPolygonList( SHAPE_POLY_SET& aCornerBuffer,
+ BOARD* aPcb, ZONE_CONTAINER* aZone,
+ double aArcCorrection,
+ double aRoundPadThermalRotation);
+
+extern void Test_For_Copper_Island_And_Remove( BOARD* aPcb,
+ ZONE_CONTAINER* aZone_container );
+
+extern void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
+ D_PAD& aPad,
+ int aThermalGap,
+ int aCopperThickness,
+ int aMinThicknessValue,
+ int aCircleToSegmentsCount,
+ double aCorrectionFactor,
+ double aThermalRot );
+
+// Local Variables:
+static double s_thermalRot = 450; // angle of stubs in thermal reliefs for round pads
+
+void ZONE_CONTAINER::buildFeatureHoleList( BOARD* aPcb, SHAPE_POLY_SET& aFeatures )
+{
+ int segsPerCircle;
+ double correctionFactor;
+
+ // Set the number of segments in arc approximations
+ if( m_ArcToSegmentsCount == ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF )
+ segsPerCircle = ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF;
+ else
+ segsPerCircle = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF;
+
+ /* calculates the coeff to compensate radius reduction of holes clearance
+ * due to the segment approx.
+ * For a circle the min radius is radius * cos( 2PI / s_CircleToSegmentsCount / 2)
+ * s_Correction is 1 /cos( PI/s_CircleToSegmentsCount )
+ */
+ correctionFactor = 1.0 / cos( M_PI / (double) segsPerCircle );
+
+ aFeatures.RemoveAllContours();
+
+ int outline_half_thickness = m_ZoneMinThickness / 2;
+
+ int zone_clearance = std::max( m_ZoneClearance, GetClearance() );
+ zone_clearance += outline_half_thickness;
+
+ /* store holes (i.e. tracks and pads areas as polygons outlines)
+ * in a polygon list
+ */
+
+ /* items ouside the zone bounding box are skipped
+ * the bounding box is the zone bounding box + the biggest clearance found in Netclass list
+ */
+ EDA_RECT item_boundingbox;
+ EDA_RECT zone_boundingbox = GetBoundingBox();
+ int biggest_clearance = aPcb->GetDesignSettings().GetBiggestClearanceValue();
+ biggest_clearance = std::max( biggest_clearance, zone_clearance );
+ zone_boundingbox.Inflate( biggest_clearance );
+
+ /*
+ * First : Add pads. Note: pads having the same net as zone are left in zone.
+ * Thermal shapes will be created later if necessary
+ */
+ int item_clearance;
+
+ /* Use a dummy pad to calculate hole clerance when a pad is not on all copper layers
+ * and this pad has a hole
+ * This dummy pad has the size and shape of the hole
+ * Therefore, this dummy pad is a circle or an oval.
+ * A pad must have a parent because some functions expect a non null parent
+ * to find the parent board, and some other data
+ */
+ MODULE dummymodule( aPcb ); // Creates a dummy parent
+ D_PAD dummypad( &dummymodule );
+
+ for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
+ {
+ D_PAD* nextpad;
+
+ for( D_PAD* pad = module->Pads(); pad != NULL; pad = nextpad )
+ {
+ nextpad = pad->Next(); // pad pointer can be modified by next code, so
+ // calculate the next pad here
+
+ if( !pad->IsOnLayer( GetLayer() ) )
+ {
+ /* Test for pads that are on top or bottom only and have a hole.
+ * There are curious pads but they can be used for some components that are
+ * inside the board (in fact inside the hole. Some photo diodes and Leds are
+ * like this)
+ */
+ if( pad->GetDrillSize().x == 0 && pad->GetDrillSize().y == 0 )
+ continue;
+
+ // Use a dummy pad to calculate a hole shape that have the same dimension as
+ // the pad hole
+ dummypad.SetSize( pad->GetDrillSize() );
+ dummypad.SetOrientation( pad->GetOrientation() );
+ dummypad.SetShape( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
+ PAD_SHAPE_OVAL : PAD_SHAPE_CIRCLE );
+ dummypad.SetPosition( pad->GetPosition() );
+
+ pad = &dummypad;
+ }
+
+ // Note: netcode <=0 means not connected item
+ if( ( pad->GetNetCode() != GetNetCode() ) || ( pad->GetNetCode() <= 0 ) )
+ {
+ item_clearance = pad->GetClearance() + outline_half_thickness;
+ item_boundingbox = pad->GetBoundingBox();
+ item_boundingbox.Inflate( item_clearance );
+
+ if( item_boundingbox.Intersects( zone_boundingbox ) )
+ {
+ int clearance = std::max( zone_clearance, item_clearance );
+ pad->TransformShapeWithClearanceToPolygon( aFeatures,
+ clearance,
+ segsPerCircle,
+ correctionFactor );
+ }
+
+ continue;
+ }
+
+ if( GetPadConnection( pad ) == PAD_ZONE_CONN_NONE )
+ {
+ int gap = zone_clearance;
+ int thermalGap = GetThermalReliefGap( pad );
+ gap = std::max( gap, thermalGap );
+ item_boundingbox = pad->GetBoundingBox();
+
+ if( item_boundingbox.Intersects( zone_boundingbox ) )
+ {
+ pad->TransformShapeWithClearanceToPolygon( aFeatures,
+ gap,
+ segsPerCircle,
+ correctionFactor );
+ }
+ }
+ }
+ }
+
+ /* Add holes (i.e. tracks and vias areas as polygons outlines)
+ * in cornerBufferPolysToSubstract
+ */
+ for( TRACK* track = aPcb->m_Track; track; track = track->Next() )
+ {
+ if( !track->IsOnLayer( GetLayer() ) )
+ continue;
+
+ if( track->GetNetCode() == GetNetCode() && (GetNetCode() != 0) )
+ continue;
+
+ item_clearance = track->GetClearance() + outline_half_thickness;
+ item_boundingbox = track->GetBoundingBox();
+
+ if( item_boundingbox.Intersects( zone_boundingbox ) )
+ {
+ int clearance = std::max( zone_clearance, item_clearance );
+ track->TransformShapeWithClearanceToPolygon( aFeatures,
+ clearance,
+ segsPerCircle,
+ correctionFactor );
+ }
+ }
+
+ /* Add module edge items that are on copper layers
+ * Pcbnew allows these items to be on copper layers in microwave applictions
+ * This is a bad thing, but must be handled here, until a better way is found
+ */
+ for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
+ {
+ for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item->Next() )
+ {
+ if( !item->IsOnLayer( GetLayer() ) && !item->IsOnLayer( Edge_Cuts ) )
+ continue;
+
+ if( item->Type() != PCB_MODULE_EDGE_T )
+ continue;
+
+ item_boundingbox = item->GetBoundingBox();
+
+ if( item_boundingbox.Intersects( zone_boundingbox ) )
+ {
+ ( (EDGE_MODULE*) item )->TransformShapeWithClearanceToPolygon(
+ aFeatures, zone_clearance,
+ segsPerCircle, correctionFactor );
+ }
+ }
+ }
+
+ // Add graphic items (copper texts) and board edges
+ for( BOARD_ITEM* item = aPcb->m_Drawings; item; item = item->Next() )
+ {
+ if( item->GetLayer() != GetLayer() && item->GetLayer() != Edge_Cuts )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_LINE_T:
+ ( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon(
+ aFeatures,
+ zone_clearance, segsPerCircle, correctionFactor );
+ break;
+
+ case PCB_TEXT_T:
+ ( (TEXTE_PCB*) item )->TransformBoundingBoxWithClearanceToPolygon(
+ aFeatures, zone_clearance );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Add zones outlines having an higher priority and keepout
+ for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
+ {
+ ZONE_CONTAINER* zone = GetBoard()->GetArea( ii );
+ if( zone->GetLayer() != GetLayer() )
+ continue;
+
+ if( !zone->GetIsKeepout() && zone->GetPriority() <= GetPriority() )
+ continue;
+
+ if( zone->GetIsKeepout() && ! zone->GetDoNotAllowCopperPour() )
+ continue;
+
+ // A highter priority zone or keepout area is found: remove this area
+ item_boundingbox = zone->GetBoundingBox();
+ if( !item_boundingbox.Intersects( zone_boundingbox ) )
+ continue;
+
+ // Add the zone outline area.
+ // However if the zone has the same net as the current zone,
+ // do not add any clearance.
+ // the zone will be connected to the current zone, but filled areas
+ // will use different parameters (clearance, thermal shapes )
+ bool same_net = GetNetCode() == zone->GetNetCode();
+ bool use_net_clearance = true;
+ int min_clearance = zone_clearance;
+
+ // Do not forget to make room to draw the thick outlines
+ // of the hole created by the area of the zone to remove
+ int holeclearance = zone->GetClearance() + outline_half_thickness;
+
+ // The final clearance is obviously the max value of each zone clearance
+ min_clearance = std::max( min_clearance, holeclearance );
+
+ if( zone->GetIsKeepout() || same_net )
+ {
+ // Just take in account the fact the outline has a thickness, so
+ // the actual area to substract is inflated to take in account this fact
+ min_clearance = outline_half_thickness;
+ use_net_clearance = false;
+ }
+
+ zone->TransformOutlinesShapeWithClearanceToPolygon(
+ aFeatures,
+ min_clearance, use_net_clearance );
+ }
+
+ // Remove thermal symbols
+ for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad != NULL; pad = pad->Next() )
+ {
+ // Rejects non-standard pads with tht-only thermal reliefs
+ if( GetPadConnection( pad ) == PAD_ZONE_CONN_THT_THERMAL
+ && pad->GetAttribute() != PAD_ATTRIB_STANDARD )
+ continue;
+
+ if( GetPadConnection( pad ) != PAD_ZONE_CONN_THERMAL
+ && GetPadConnection( pad ) != PAD_ZONE_CONN_THT_THERMAL )
+ continue;
+
+ if( !pad->IsOnLayer( GetLayer() ) )
+ continue;
+
+ if( pad->GetNetCode() != GetNetCode() )
+ continue;
+ item_boundingbox = pad->GetBoundingBox();
+ int thermalGap = GetThermalReliefGap( pad );
+ item_boundingbox.Inflate( thermalGap, thermalGap );
+
+ if( item_boundingbox.Intersects( zone_boundingbox ) )
+ {
+ CreateThermalReliefPadPolygon( aFeatures,
+ *pad, thermalGap,
+ GetThermalReliefCopperBridge( pad ),
+ m_ZoneMinThickness,
+ segsPerCircle,
+ correctionFactor, s_thermalRot );
+ }
+ }
+ }
+
+}
+
+
+/**
+ * Function AddClearanceAreasPolygonsToPolysList
+ * Supports a min thickness area constraint.
+ * Add non copper areas polygons (pads and tracks with clearance)
+ * to the filled copper area found
+ * in BuildFilledPolysListData after calculating filled areas in a zone
+ * Non filled copper areas are pads and track and their clearance areas
+ * The filled copper area must be computed just before.
+ * BuildFilledPolysListData() call this function just after creating the
+ * filled copper area polygon (without clearance areas)
+ * to do that this function:
+ * 1 - Creates the main outline (zone outline) using a correction to shrink the resulting area
+ * with m_ZoneMinThickness/2 value.
+ * The result is areas with a margin of m_ZoneMinThickness/2
+ * When drawing outline with segments having a thickness of m_ZoneMinThickness, the
+ * outlines will match exactly the initial outlines
+ * 3 - Add all non filled areas (pads, tracks) in group B with a clearance of m_Clearance +
+ * m_ZoneMinThickness/2
+ * in a buffer
+ * - If Thermal shapes are wanted, add non filled area, in order to create these thermal shapes
+ * 4 - calculates the polygon A - B
+ * 5 - put resulting list of polygons (filled areas) in m_FilledPolysList
+ * This zone contains pads with the same net.
+ * 6 - Remove insulated copper islands
+ * 7 - If Thermal shapes are wanted, remove unconnected stubs in thermal shapes:
+ * creates a buffer of polygons corresponding to stubs to remove
+ * sub them to the filled areas.
+ * Remove new insulated copper islands
+ */
+
+void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList_NG( BOARD* aPcb )
+{
+ int segsPerCircle;
+ double correctionFactor;
+ int outline_half_thickness = m_ZoneMinThickness / 2;
+
+
+ std::auto_ptr<SHAPE_FILE_IO> dumper( new SHAPE_FILE_IO(
+ g_DumpZonesWhenFilling ? "zones_dump.txt" : "", SHAPE_FILE_IO::IOM_APPEND ) );
+
+ // Set the number of segments in arc approximations
+ if( m_ArcToSegmentsCount == ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF )
+ segsPerCircle = ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF;
+ else
+ segsPerCircle = ARC_APPROX_SEGMENTS_COUNT_LOW_DEF;
+
+ /* calculates the coeff to compensate radius reduction of holes clearance
+ * due to the segment approx.
+ * For a circle the min radius is radius * cos( 2PI / s_CircleToSegmentsCount / 2)
+ * s_Correction is 1 /cos( PI/s_CircleToSegmentsCount )
+ */
+ correctionFactor = 1.0 / cos( M_PI / (double) segsPerCircle );
+
+ CPOLYGONS_LIST tmp;
+
+ if(g_DumpZonesWhenFilling)
+ dumper->BeginGroup("clipper-zone");
+
+ SHAPE_POLY_SET solidAreas = ConvertPolyListToPolySet( m_smoothedPoly->m_CornersList );
+
+ solidAreas.Inflate( -outline_half_thickness, segsPerCircle );
+ solidAreas.Simplify();
+
+ SHAPE_POLY_SET holes;
+
+ if(g_DumpZonesWhenFilling)
+ dumper->Write( &solidAreas, "solid-areas" );
+
+ tmp.RemoveAllContours();
+ buildFeatureHoleList( aPcb, holes );
+
+ if(g_DumpZonesWhenFilling)
+ dumper->Write( &holes, "feature-holes" );
+
+ holes.Simplify( true );
+
+ if (g_DumpZonesWhenFilling)
+ dumper->Write( &holes, "feature-holes-postsimplify" );
+
+ // Generate the filled areas (currently, without thermal shapes, which will
+ // be created later).
+ // Generate strictly simple polygons needed by Gerber files and Fracture()
+ solidAreas.BooleanSubtract( holes, false );
+
+ if (g_DumpZonesWhenFilling)
+ dumper->Write( &solidAreas, "solid-areas-minus-holes" );
+
+ SHAPE_POLY_SET fractured = solidAreas;
+ fractured.Fracture();
+
+ if (g_DumpZonesWhenFilling)
+ dumper->Write( &fractured, "fractured" );
+
+ m_FilledPolysList = fractured;
+
+ // Remove insulated islands:
+ if( GetNetCode() > 0 )
+ TestForCopperIslandAndRemoveInsulatedIslands( aPcb );
+
+ SHAPE_POLY_SET thermalHoles;
+
+ // Test thermal stubs connections and add polygons to remove unconnected stubs.
+ // (this is a refinement for thermal relief shapes)
+ if( GetNetCode() > 0 )
+ BuildUnconnectedThermalStubsPolygonList( thermalHoles, aPcb, this,
+ correctionFactor, s_thermalRot );
+
+ // remove copper areas corresponding to not connected stubs
+ if( !thermalHoles.IsEmpty() )
+ {
+ thermalHoles.Simplify();
+ // Remove unconnected stubs.
+ // Generate strictly simple polygons needed by Gerber files and Fracture()
+ solidAreas.BooleanSubtract( thermalHoles, false );
+
+ if( g_DumpZonesWhenFilling )
+ dumper->Write( &thermalHoles, "thermal-holes" );
+
+ // put these areas in m_FilledPolysList
+ SHAPE_POLY_SET fractured = solidAreas;
+ fractured.Fracture();
+
+ if( g_DumpZonesWhenFilling )
+ dumper->Write ( &fractured, "fractured" );
+
+ m_FilledPolysList = fractured;
+
+ if( GetNetCode() > 0 )
+ TestForCopperIslandAndRemoveInsulatedIslands( aPcb );
+ }
+
+ if(g_DumpZonesWhenFilling)
+ dumper->EndGroup();
+}
+
+void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
+{
+}
diff --git a/pcbnew/zones_convert_to_polygons_aux_functions.cpp b/pcbnew/zones_convert_to_polygons_aux_functions.cpp
new file mode 100644
index 0000000..1671936
--- /dev/null
+++ b/pcbnew/zones_convert_to_polygons_aux_functions.cpp
@@ -0,0 +1,251 @@
+/**
+ * @file zones_convert_to_polygons_aux_functions.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <PolyLine.h>
+#include <wxPcbStruct.h>
+#include <trigo.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <zones.h>
+
+ /* Function TransformOutlinesShapeWithClearanceToPolygon
+ * Convert the zone filled areas polygons to polygons
+ * inflated (optional) by max( aClearanceValue, the zone clearance)
+ * and copy them in aCornerBuffer
+ * param aClearanceValue = the clearance around polygons
+ * param aAddClearance = true to add a clearance area to the polygon
+ * false to create the outline polygon.
+ */
+void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon(
+ SHAPE_POLY_SET& aCornerBuffer, int aMinClearanceValue, bool aUseNetClearance )
+{
+ // Creates the zone outline polygon (with holes if any)
+ SHAPE_POLY_SET polybuffer;
+ BuildFilledSolidAreasPolygons( NULL, &polybuffer );
+
+ // add clearance to outline
+ int clearance = aMinClearanceValue;
+
+ if( aUseNetClearance && IsOnCopperLayer() )
+ {
+ clearance = GetClearance();
+ if( aMinClearanceValue > clearance )
+ clearance = aMinClearanceValue;
+ }
+
+ // Calculate the polygon with clearance
+ // holes are linked to the main outline, so only one polygon is created.
+ if( clearance )
+ polybuffer.Inflate( clearance, 16 );
+
+ polybuffer.Fracture();
+ aCornerBuffer.Append( polybuffer );
+}
+
+
+
+/**
+ * Function BuildUnconnectedThermalStubsPolygonList
+ * Creates a set of polygons corresponding to stubs created by thermal shapes on pads
+ * which are not connected to a zone (dangling bridges)
+ * @param aCornerBuffer = a SHAPE_POLY_SET where to store polygons
+ * @param aPcb = the board.
+ * @param aZone = a pointer to the ZONE_CONTAINER to examine.
+ * @param aArcCorrection = a pointer to the ZONE_CONTAINER to examine.
+ * @param aRoundPadThermalRotation = the rotation in 1.0 degree for thermal stubs in round pads
+ */
+
+void BuildUnconnectedThermalStubsPolygonList( SHAPE_POLY_SET& aCornerBuffer,
+ BOARD* aPcb,
+ ZONE_CONTAINER* aZone,
+ double aArcCorrection,
+ double aRoundPadThermalRotation )
+{
+ std::vector<wxPoint> corners_buffer; // a local polygon buffer to store one stub
+ corners_buffer.reserve( 4 );
+ wxPoint ptTest[4];
+
+ int zone_clearance = aZone->GetZoneClearance();
+
+ EDA_RECT item_boundingbox;
+ EDA_RECT zone_boundingbox = aZone->GetBoundingBox();
+ int biggest_clearance = aPcb->GetDesignSettings().GetBiggestClearanceValue();
+ biggest_clearance = std::max( biggest_clearance, zone_clearance );
+ zone_boundingbox.Inflate( biggest_clearance );
+
+ // half size of the pen used to draw/plot zones outlines
+ int pen_radius = aZone->GetMinThickness() / 2;
+
+ for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad != NULL; pad = pad->Next() )
+ {
+ // Rejects non-standard pads with tht-only thermal reliefs
+ if( aZone->GetPadConnection( pad ) == PAD_ZONE_CONN_THT_THERMAL
+ && pad->GetAttribute() != PAD_ATTRIB_STANDARD )
+ continue;
+
+ if( aZone->GetPadConnection( pad ) != PAD_ZONE_CONN_THERMAL
+ && aZone->GetPadConnection( pad ) != PAD_ZONE_CONN_THT_THERMAL )
+ continue;
+
+ // check
+ if( !pad->IsOnLayer( aZone->GetLayer() ) )
+ continue;
+
+ if( pad->GetNetCode() != aZone->GetNetCode() )
+ continue;
+
+ // Calculate thermal bridge half width
+ int thermalBridgeWidth = aZone->GetThermalReliefCopperBridge( pad )
+ - aZone->GetMinThickness();
+ if( thermalBridgeWidth <= 0 )
+ continue;
+
+ // we need the thermal bridge half width
+ // with a small extra size to be sure we create a stub
+ // slightly larger than the actual stub
+ thermalBridgeWidth = ( thermalBridgeWidth + 4 ) / 2;
+
+ int thermalReliefGap = aZone->GetThermalReliefGap( pad );
+
+ item_boundingbox = pad->GetBoundingBox();
+ item_boundingbox.Inflate( thermalReliefGap );
+ if( !( item_boundingbox.Intersects( zone_boundingbox ) ) )
+ continue;
+
+ // Thermal bridges are like a segment from a starting point inside the pad
+ // to an ending point outside the pad
+
+ // calculate the ending point of the thermal pad, outside the pad
+ wxPoint endpoint;
+ endpoint.x = ( pad->GetSize().x / 2 ) + thermalReliefGap;
+ endpoint.y = ( pad->GetSize().y / 2 ) + thermalReliefGap;
+
+ // Calculate the starting point of the thermal stub
+ // inside the pad
+ wxPoint startpoint;
+ int copperThickness = aZone->GetThermalReliefCopperBridge( pad )
+ - aZone->GetMinThickness();
+
+ if( copperThickness < 0 )
+ copperThickness = 0;
+
+ // Leave a small extra size to the copper area inside to pad
+ copperThickness += KiROUND( IU_PER_MM * 0.04 );
+
+ startpoint.x = std::min( pad->GetSize().x, copperThickness );
+ startpoint.y = std::min( pad->GetSize().y, copperThickness );
+
+ startpoint.x /= 2;
+ startpoint.y /= 2;
+
+ // This is a CIRCLE pad tweak
+ // for circle pads, the thermal stubs orientation is 45 deg
+ double fAngle = pad->GetOrientation();
+ if( pad->GetShape() == PAD_SHAPE_CIRCLE )
+ {
+ endpoint.x = KiROUND( endpoint.x * aArcCorrection );
+ endpoint.y = endpoint.x;
+ fAngle = aRoundPadThermalRotation;
+ }
+
+ // contour line width has to be taken into calculation to avoid "thermal stub bleed"
+ endpoint.x += pen_radius;
+ endpoint.y += pen_radius;
+ // compute north, south, west and east points for zone connection.
+ ptTest[0] = wxPoint( 0, endpoint.y ); // lower point
+ ptTest[1] = wxPoint( 0, -endpoint.y ); // upper point
+ ptTest[2] = wxPoint( endpoint.x, 0 ); // right point
+ ptTest[3] = wxPoint( -endpoint.x, 0 ); // left point
+
+ // Test all sides
+ for( int i = 0; i < 4; i++ )
+ {
+ // rotate point
+ RotatePoint( &ptTest[i], fAngle );
+
+ // translate point
+ ptTest[i] += pad->ShapePos();
+
+ if( aZone->HitTestFilledArea( ptTest[i] ) )
+ continue;
+
+ corners_buffer.clear();
+
+ // polygons are rectangles with width of copper bridge value
+ switch( i )
+ {
+ case 0: // lower stub
+ corners_buffer.push_back( wxPoint( -thermalBridgeWidth, endpoint.y ) );
+ corners_buffer.push_back( wxPoint( +thermalBridgeWidth, endpoint.y ) );
+ corners_buffer.push_back( wxPoint( +thermalBridgeWidth, startpoint.y ) );
+ corners_buffer.push_back( wxPoint( -thermalBridgeWidth, startpoint.y ) );
+ break;
+
+ case 1: // upper stub
+ corners_buffer.push_back( wxPoint( -thermalBridgeWidth, -endpoint.y ) );
+ corners_buffer.push_back( wxPoint( +thermalBridgeWidth, -endpoint.y ) );
+ corners_buffer.push_back( wxPoint( +thermalBridgeWidth, -startpoint.y ) );
+ corners_buffer.push_back( wxPoint( -thermalBridgeWidth, -startpoint.y ) );
+ break;
+
+ case 2: // right stub
+ corners_buffer.push_back( wxPoint( endpoint.x, -thermalBridgeWidth ) );
+ corners_buffer.push_back( wxPoint( endpoint.x, thermalBridgeWidth ) );
+ corners_buffer.push_back( wxPoint( +startpoint.x, thermalBridgeWidth ) );
+ corners_buffer.push_back( wxPoint( +startpoint.x, -thermalBridgeWidth ) );
+ break;
+
+ case 3: // left stub
+ corners_buffer.push_back( wxPoint( -endpoint.x, -thermalBridgeWidth ) );
+ corners_buffer.push_back( wxPoint( -endpoint.x, thermalBridgeWidth ) );
+ corners_buffer.push_back( wxPoint( -startpoint.x, thermalBridgeWidth ) );
+ corners_buffer.push_back( wxPoint( -startpoint.x, -thermalBridgeWidth ) );
+ break;
+ }
+
+ aCornerBuffer.NewOutline();
+
+ // add computed polygon to list
+ for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
+ {
+ wxPoint cpos = corners_buffer[ic];
+ RotatePoint( &cpos, fAngle ); // Rotate according to module orientation
+ cpos += pad->ShapePos(); // Shift origin to position
+ aCornerBuffer.Append( cpos.x, cpos.y );
+ }
+ }
+ }
+ }
+}
diff --git a/pcbnew/zones_functions_for_undo_redo.cpp b/pcbnew/zones_functions_for_undo_redo.cpp
new file mode 100644
index 0000000..65e761f
--- /dev/null
+++ b/pcbnew/zones_functions_for_undo_redo.cpp
@@ -0,0 +1,310 @@
+/**
+ * @file zones_functions_for_undo_redo.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras <jp.charras@wanadoo.fr>
+ * Copyright (C) 2007-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* These functions are relative to undo redo function, when zones are involved.
+ * When a zone outline is modified (or created) this zone, or others zones on the same layer
+ * and with the same netcode can change or can be deleted
+ * This is due to the fact overlapping zones are merged
+ * Also, when a zone outline is modified by adding a cutout area,
+ * this zone can be converted to more than one area, if the outline is break to 2 or more outlines
+ * and therefore new zones are created
+ *
+ * Due to the complexity of potential changes, and the fact there are only few zones
+ * in a board, and a zone has only few segments outlines, the more easy way to
+ * undo redo changes is to make a copy of all zones that can be changed
+ * and see after zone edition or creation what zones that are really modified,
+ * and ones they are modified (changes, deletion or addition)
+ */
+
+#include <fctsys.h>
+#include <pgm_base.h>
+#include <class_drawpanel.h>
+#include <wxPcbStruct.h>
+
+#include <class_board.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <zones.h>
+#include <zones_functions_for_undo_redo.h>
+
+/**
+ * Function IsSame
+ * test is 2 zones are equivalent:
+ * 2 zones are equivalent if they have same parameters and same outlines
+ * info relative to filling is not take in account
+ * @param aZoneToCompare = zone to compare with "this"
+ */
+bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare )
+{
+ // compare basic parameters:
+ if( GetLayer() != aZoneToCompare.GetLayer() )
+ return false;
+
+ if( GetNetCode() != aZoneToCompare.GetNetCode() )
+ return false;
+
+ if( GetPriority() != aZoneToCompare.GetPriority() )
+ return false;
+
+ // Compare zone specific parameters
+ if( GetIsKeepout() != aZoneToCompare.GetIsKeepout() )
+ return false;
+
+ if( GetIsKeepout() )
+ {
+ if( GetDoNotAllowCopperPour() != aZoneToCompare.GetDoNotAllowCopperPour() )
+ return false;
+
+ if( GetDoNotAllowVias() != aZoneToCompare.GetDoNotAllowVias() )
+ return false;
+
+ if( GetDoNotAllowTracks() != aZoneToCompare.GetDoNotAllowTracks() )
+ return false;
+ }
+
+ if( m_ArcToSegmentsCount != aZoneToCompare.GetArcSegmentCount() )
+ return false;
+
+ if( m_ZoneClearance != aZoneToCompare.m_ZoneClearance )
+ return false;
+
+ if( m_ZoneMinThickness != aZoneToCompare.GetMinThickness() )
+ return false;
+
+ if( m_FillMode != aZoneToCompare.GetFillMode() )
+ return false;
+
+ if( m_PadConnection != aZoneToCompare.m_PadConnection )
+ return false;
+
+ if( m_ThermalReliefGap != aZoneToCompare.m_ThermalReliefGap )
+ return false;
+
+ if( m_ThermalReliefCopperBridge != aZoneToCompare.m_ThermalReliefCopperBridge )
+ return false;
+
+
+ // Compare outlines
+ wxASSERT( m_Poly ); // m_Poly == NULL Should never happen
+ wxASSERT( aZoneToCompare.Outline() );
+
+ if( Outline()->m_CornersList.GetList() !=
+ aZoneToCompare.Outline()->m_CornersList.GetList() ) // Compare vector
+ return false;
+
+ return true;
+}
+
+
+/**
+ * Function SaveCopyOfZones
+ * creates a copy of zones having a given netcode on a given layer,
+ * and fill a pick list with pickers to handle these copies
+ * the UndoRedo status is set to UR_CHANGED for all items in list
+ * Later, UpdateCopyOfZonesList will change and update these pickers after a zone edition
+ * @param aPickList = the pick list
+ * @param aPcb = the Board
+ * @param aNetCode = the reference netcode. if aNetCode < 0 all netcodes are used
+ * @param aLayer = the layer of zones. if aLayer < 0, all layers are used
+ * @return the count of saved copies
+ */
+int SaveCopyOfZones( PICKED_ITEMS_LIST& aPickList, BOARD* aPcb, int aNetCode, LAYER_NUM aLayer )
+{
+ int copyCount = 0;
+
+ for( unsigned ii = 0; ; ii++ )
+ {
+ ZONE_CONTAINER* zone = aPcb->GetArea( ii );
+
+ if( zone == NULL ) // End of list
+ break;
+
+ if( aNetCode >= 0 && aNetCode != zone->GetNetCode() )
+ continue;
+
+ if( aLayer >= 0 && aLayer != zone->GetLayer() )
+ continue;
+
+ ZONE_CONTAINER* zoneDup = new ZONE_CONTAINER( *zone );
+ zoneDup->SetParent( aPcb );
+ ITEM_PICKER picker( zone, UR_CHANGED );
+ picker.SetLink( zoneDup );
+ aPickList.PushItem( picker );
+ copyCount++;
+ }
+
+ return copyCount;
+}
+
+
+/**
+ * Function UpdateCopyOfZonesList
+ * check a pick list to remove zones identical to their copies
+ * and set the type of operation in picker (UR_DELETED, UR_CHANGED)
+ * if an item is deleted, the initial values are retrievered,
+ * because they can have changed in edition
+ * @param aPickList = the main pick list
+ * @param aAuxiliaryList = the list of deleted or added (new created) items after calculations
+ * @param aPcb = the Board
+ *
+ * aAuxiliaryList is a list of pickers updated by zone algorithms:
+ * This list contains zones which were added or deleted during the zones combine process
+ * aPickList :is a list of zones that can be modified (changed or deleted, or not modified)
+ * Typically, this is the list of existing zones on the layer of the edited zone,
+ * before any change.
+ * >> if the picked zone is not changed, it is removed from list
+ * >> if the picked zone was deleted (i.e. not found in board list), the picker is modified:
+ * its status becomes UR_DELETED
+ * the aAuxiliaryList corresponding picker is removed (if not found : set an error)
+ * >> if the picked zone was flagged as UR_NEW, and was after deleted ,
+ * perhaps combined with an other zone (i.e. not found in board list):
+ * the picker is removed
+ * the zone itself if really deleted
+ * the aAuxiliaryList corresponding picker is removed (if not found : set an error)
+ * After aPickList is cleaned, the aAuxiliaryList is read
+ * All pickers flagged UR_NEW are moved to aPickList
+ * (the corresponding zones are zone that were created by the zone normalize and combine process,
+ * mainly when adding cutout areas, or creating self intersecting contours)
+ * All pickers flagged UR_DELETED are removed, and the coresponding zones actually deleted
+ * (the corresponding zones are new zone that were created by the zone normalize process,
+ * when creating self intersecting contours, and after combined with an existing zone.
+ * At the end of the update process the aAuxiliaryList must be void,
+ * because all pickers created by the combine process
+ * must have been removed (removed for new and deleted zones, or moved in aPickList.)
+ * If not an error is set.
+ */
+void UpdateCopyOfZonesList( PICKED_ITEMS_LIST& aPickList,
+ PICKED_ITEMS_LIST& aAuxiliaryList,
+ BOARD* aPcb )
+{
+ for( unsigned kk = 0; kk < aPickList.GetCount(); kk++ )
+ {
+ UNDO_REDO_T status = aPickList.GetPickedItemStatus( kk );
+
+ ZONE_CONTAINER* ref = (ZONE_CONTAINER*) aPickList.GetPickedItem( kk );
+
+ for( unsigned ii = 0; ; ii++ ) // analyse the main picked list
+ {
+ ZONE_CONTAINER* zone = aPcb->GetArea( ii );
+
+ if( zone == NULL )
+ {
+ /* End of list: the stored item is not found:
+ * it must be in aDeletedList:
+ * search it and restore initial values
+ * or
+ * if flagged UR_NEW: remove it definitively
+ */
+ if( status == UR_NEW )
+ {
+ delete ref;
+ ref = NULL;
+ aPickList.RemovePicker( kk );
+ kk--;
+ }
+ else
+ {
+ ZONE_CONTAINER* zcopy = (ZONE_CONTAINER*) aPickList.GetPickedItemLink( kk );
+ aPickList.SetPickedItemStatus( UR_DELETED, kk );
+
+ wxASSERT_MSG( zcopy != NULL,
+ wxT( "UpdateCopyOfZonesList() error: link = NULL" ) );
+
+ ref->Copy( zcopy );
+
+ // the copy was deleted; the link does not exists now.
+ aPickList.SetPickedItemLink( NULL, kk );
+ delete zcopy;
+ }
+
+ // Remove this item from aAuxiliaryList, mainly for tests purpose
+ bool notfound = true;
+
+ for( unsigned nn = 0; nn < aAuxiliaryList.GetCount(); nn++ )
+ {
+ if( ref != NULL && aAuxiliaryList.GetPickedItem( nn ) == ref )
+ {
+ aAuxiliaryList.RemovePicker( nn );
+ notfound = false;
+ break;
+ }
+ }
+
+ if( notfound ) // happens when the new zone overlaps an existing zone
+ // and these zones are combined
+ {
+ DBG( printf(
+ "UpdateCopyOfZonesList(): item not found in aAuxiliaryList,"
+ "combined with an other zone\n" ) );
+ }
+ break;
+ }
+
+ if( zone == ref ) // picked zone found
+ {
+ if( aPickList.GetPickedItemStatus( kk ) != UR_NEW )
+ {
+ ZONE_CONTAINER* zcopy = (ZONE_CONTAINER*) aPickList.GetPickedItemLink( kk );
+
+ if( zone->IsSame( *zcopy ) ) // Remove picked, because no changes
+ {
+ delete zcopy; // Delete copy
+ aPickList.RemovePicker( kk );
+ kk--;
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Add new zones in main pick list, and remove pickers from Auxiliary List
+ for( unsigned ii = 0; ii < aAuxiliaryList.GetCount(); )
+ {
+ if( aAuxiliaryList.GetPickedItemStatus( ii ) == UR_NEW )
+ {
+ ITEM_PICKER picker = aAuxiliaryList.GetItemWrapper( ii );
+ aPickList.PushItem( picker );
+ aAuxiliaryList.RemovePicker( ii );
+ }
+ else if( aAuxiliaryList.GetPickedItemStatus( ii ) == UR_DELETED )
+ {
+ delete aAuxiliaryList.GetPickedItemLink( ii );
+ aAuxiliaryList.RemovePicker( ii );
+ }
+ else
+ ii++;
+ }
+
+ // Should not occur:
+ wxASSERT_MSG( aAuxiliaryList.GetCount() == 0,
+ wxT( "UpdateCopyOfZonesList() error: aAuxiliaryList not empty." ) );
+}
diff --git a/pcbnew/zones_functions_for_undo_redo.h b/pcbnew/zones_functions_for_undo_redo.h
new file mode 100644
index 0000000..a5260a3
--- /dev/null
+++ b/pcbnew/zones_functions_for_undo_redo.h
@@ -0,0 +1,72 @@
+/**
+ * @file zones_functions_for_undo_redo.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2009 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
+ * Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* These functions are relative to undo redo function, when zones are involved.
+ * When a zone outline is modified (or created) this zone, or others zones on the same layer
+ * and with the same netcode can change or can be deleted
+ * This is due to the fact overlapping zones are merged
+ * Also, when a zone outline is modified by adding a cutout area,
+ * this zone can be converted to more than one area, if the outline is break to 2 or more outlines
+ * and therefore new zones are created
+ *
+ * Due to the complexity of potential changes, and the fact there are only few zones
+ * in a board, and a zone has only few segments outlines, the more easy way to
+ * undo redo changes is to make a copy of all zones that can be changed
+ * and see after zone edition or creation what zones that are really modified,
+ * and ones they are modified (changes, deletion or addition)
+*/
+
+#ifndef ZONES_FUNCTIONS_TO_UNDO_REDO_H
+#define ZONES_FUNCTIONS_TO_UNDO_REDO_H
+
+
+/**
+ * Function SaveCopyOfZones
+ * creates a copy of zones having a given netcode on a given layer,
+ * and fill a pick list with pickers to handle these copies
+ * @param aPickList = the pick list
+ * @param aPcb = the Board
+ * @param aNetCode = the reference netcode. if aNetCode < 0 all netcodes are used
+ * @param aLayer = the layer of zones. if aLayer < 0, all layers are used
+ * @return the count of saved copies
+ */
+int SaveCopyOfZones(PICKED_ITEMS_LIST & aPickList, BOARD* aPcb, int aNetCode, LAYER_NUM aLayer );
+
+
+/**
+ * Function UpdateCopyOfZonesList
+ * check a pick list to remove zones identical to their copies
+ * and set the type of operation in picker (UR_DELETED, UR_CHANGED)
+ * @param aPickList = the main pick list
+ * @param aAuxiliaryList = the list of deleted or added (new created) items after calculations
+ * @param aPcb = the Board
+ */
+void UpdateCopyOfZonesList( PICKED_ITEMS_LIST& aPickList, PICKED_ITEMS_LIST& aAuxiliaryList, BOARD* aPcb );
+
+#endif // ZONES_FUNCTIONS_TO_UNDO_REDO_H
diff --git a/pcbnew/zones_polygons_insulated_copper_islands.cpp b/pcbnew/zones_polygons_insulated_copper_islands.cpp
new file mode 100644
index 0000000..bfb861e
--- /dev/null
+++ b/pcbnew/zones_polygons_insulated_copper_islands.cpp
@@ -0,0 +1,102 @@
+/**
+ * @file zones_polygons_insulated_copper_islands.cpp
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <zones.h>
+#include <polygon_test_point_inside.h>
+
+
+void ZONE_CONTAINER::TestForCopperIslandAndRemoveInsulatedIslands( BOARD* aPcb )
+{
+ if( m_FilledPolysList.IsEmpty() )
+ return;
+
+ // Build a list of points connected to the net:
+ // list of coordinates of pads and vias on this layer and on this net.
+ std::vector <wxPoint> listPointsCandidates;
+
+ for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad != NULL; pad = pad->Next() )
+ {
+ if( !pad->IsOnLayer( GetLayer() ) )
+ continue;
+
+ if( pad->GetNetCode() != GetNetCode() )
+ continue;
+
+ listPointsCandidates.push_back( pad->GetPosition() );
+ }
+ }
+
+ for( TRACK* track = aPcb->m_Track; track; track = track->Next() )
+ {
+ if( !track->IsOnLayer( GetLayer() ) )
+ continue;
+
+ if( track->GetNetCode() != GetNetCode() )
+ continue;
+
+ listPointsCandidates.push_back( track->GetStart() );
+
+ if( track->Type() != PCB_VIA_T )
+ listPointsCandidates.push_back( track->GetEnd() );
+ }
+
+ // test if a point is inside
+
+ for( int outline = 0; outline < m_FilledPolysList.OutlineCount(); outline++ )
+ {
+ bool connected = false;
+
+ for( unsigned ic = 0; ic < listPointsCandidates.size(); ic++ )
+ {
+ // test if this area is connected to a board item:
+ wxPoint pos = listPointsCandidates[ic];
+
+ if( m_FilledPolysList.Contains( VECTOR2I( pos.x, pos.y ), outline ) )
+ {
+ connected = true;
+ break;
+ }
+ }
+
+ if( !connected ) // this polygon is connected: analyse next polygon
+ {
+ m_FilledPolysList.DeletePolygon( outline );
+ outline--;
+ }
+ }
+}
diff --git a/pcbnew/zones_polygons_test_connections.cpp b/pcbnew/zones_polygons_test_connections.cpp
new file mode 100644
index 0000000..f0177fe
--- /dev/null
+++ b/pcbnew/zones_polygons_test_connections.cpp
@@ -0,0 +1,409 @@
+/**
+ * @file zones_polygons_test_connections.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <algorithm> // sort
+
+#include <fctsys.h>
+#include <common.h>
+#include <macros.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_track.h>
+#include <class_zone.h>
+
+#include <pcbnew.h>
+#include <zones.h>
+#include <polygon_test_point_inside.h>
+
+static bool CmpZoneSubnetValue( const BOARD_CONNECTED_ITEM* a, const BOARD_CONNECTED_ITEM* b );
+
+void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode );
+
+// This helper function sort a list of zones by netcode,
+// and for a given netcode by zone size
+// zone size = size of the m_FilledPolysList buffer
+bool sort_areas( const ZONE_CONTAINER* ref, const ZONE_CONTAINER* tst )
+{
+ if( ref->GetNetCode() == tst->GetNetCode() )
+ return ref->GetFilledPolysList().TotalVertices() <
+ tst->GetFilledPolysList().TotalVertices();
+ else
+ return ref->GetNetCode() < tst->GetNetCode();
+}
+
+/**
+ * Function Test_Connection_To_Copper_Areas
+ * init .m_ZoneSubnet parameter in tracks and pads according to the connections to areas found
+ * @param aNetcode = netcode to analyse. if -1, analyse all nets
+ */
+void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
+{
+ // list of pads and tracks candidates on this layer and on this net.
+ // It is static to avoid multiple memory realloc.
+ static std::vector <BOARD_CONNECTED_ITEM*> candidates;
+
+ // clear .m_ZoneSubnet parameter for pads
+ for( MODULE* module = m_Modules; module; module = module->Next() )
+ {
+ for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
+ if( aNetcode < 0 || aNetcode == pad->GetNetCode() )
+ pad->SetZoneSubNet( 0 );
+ }
+
+ // clear .m_ZoneSubnet parameter for tracks and vias
+ for( TRACK* track = m_Track; track; track = track->Next() )
+ {
+ if( aNetcode < 0 || aNetcode == track->GetNetCode() )
+ track->SetZoneSubNet( 0 );
+ }
+
+ // examine all zones, net by net:
+ int subnet = 0;
+
+ // Build zones candidates list
+ std::vector<ZONE_CONTAINER*> zones_candidates;
+
+ zones_candidates.reserve( GetAreaCount() );
+
+ for( int index = 0; index < GetAreaCount(); index++ )
+ {
+ ZONE_CONTAINER* zone = GetArea( index );
+
+ if( !zone->IsOnCopperLayer() )
+ continue;
+
+ if( aNetcode >= 0 && aNetcode != zone->GetNetCode() )
+ continue;
+
+ if( zone->GetFilledPolysList().IsEmpty() )
+ continue;
+
+ zones_candidates.push_back( zone );
+ }
+
+ // sort them by netcode then vertices count.
+ // For a given net, examine the smaller zones first slightly speed up calculation
+ // (25% faster)
+ // this is only noticeable with very large boards and depends on board zones topology
+ // This is due to the fact some items are connected by small zones ares,
+ // before examining large zones areas and these items are not tested after a connection is found
+ sort( zones_candidates.begin(), zones_candidates.end(), sort_areas );
+
+ int oldnetcode = -1;
+ for( unsigned idx = 0; idx < zones_candidates.size(); idx++ )
+ {
+ ZONE_CONTAINER* zone = zones_candidates[idx];
+
+ int netcode = zone->GetNetCode();
+
+ // Build a list of candidates connected to the net:
+ // At this point, layers are not considered, because areas on different layers can
+ // be connected by a via or a pad.
+ // (because zones are sorted by netcode, there is made only once per net)
+ NETINFO_ITEM* net = FindNet( netcode );
+
+ wxASSERT( net );
+ if( net == NULL )
+ continue;
+
+ if( oldnetcode != netcode )
+ {
+ oldnetcode = netcode;
+ candidates.clear();
+
+ // Build the list of pads candidates connected to the net:
+ candidates.reserve( net->m_PadInNetList.size() );
+
+ for( unsigned ii = 0; ii < net->m_PadInNetList.size(); ii++ )
+ candidates.push_back( net->m_PadInNetList[ii] );
+
+ // If we have any tracks...
+ if( m_Track.GetCount() > 0 )
+ {
+ // Build the list of track candidates connected to the net:
+ TRACK* track = m_Track.GetFirst()->GetStartNetCode( netcode );
+
+ for( ; track; track = track->Next() )
+ {
+ if( track->GetNetCode() != netcode )
+ break;
+
+ candidates.push_back( track );
+ }
+ }
+ }
+
+ // test if a candidate is inside a filled area of this zone
+ const SHAPE_POLY_SET& polysList = zone->GetFilledPolysList();
+
+ for( int outline = 0; outline < polysList.OutlineCount(); outline++ )
+ {
+ subnet++;
+
+ for( unsigned ic = 0; ic < candidates.size(); ic++ )
+ {
+ // test if this area is connected to a board item:
+ BOARD_CONNECTED_ITEM* item = candidates[ic];
+
+ if( item->GetZoneSubNet() == subnet ) // Already merged
+ continue;
+
+ if( !item->IsOnLayer( zone->GetLayer() ) )
+ continue;
+
+ wxPoint pos1, pos2;
+
+ if( item->Type() == PCB_PAD_T )
+ {
+ // For pads we use the shape position instead of
+ // the pad position, because the zones are connected
+ // to the center of the shape, not the pad position
+ // (this is important for pads with thermal relief)
+ pos1 = pos2 = ( (D_PAD*) item )->ShapePos();
+ }
+ else if( item->Type() == PCB_VIA_T )
+ {
+ const VIA *via = static_cast<const VIA*>( item );
+ pos1 = via->GetStart();
+ pos2 = pos1;
+ }
+ else if( item->Type() == PCB_TRACE_T )
+ {
+ const TRACK *trk = static_cast<const TRACK*>( item );
+ pos1 = trk->GetStart();
+ pos2 = trk->GetEnd();
+ }
+ else
+ {
+ continue;
+ }
+
+ bool connected = false;
+
+ if( polysList.Contains( VECTOR2I( pos1.x, pos1.y ), outline ) )
+ connected = true;
+
+ if( !connected && ( pos1 != pos2 ) )
+ {
+ if( polysList.Contains( VECTOR2I( pos2.x, pos2.y ), outline ) )
+ connected = true;
+ }
+
+ if( connected )
+ {
+ // Set ZoneSubnet to the current subnet value.
+ // If the previous subnet is not 0, merge all items with old subnet
+ // to the new one
+ int old_subnet = item->GetZoneSubNet();
+ item->SetZoneSubNet( subnet );
+
+ // Merge previous subnet with the current
+ if( (old_subnet > 0) && (old_subnet != subnet) )
+ {
+ for( unsigned jj = 0; jj < candidates.size(); jj++ )
+ {
+ BOARD_CONNECTED_ITEM* item_to_merge = candidates[jj];
+
+ if( old_subnet == item_to_merge->GetZoneSubNet() )
+ {
+ item_to_merge->SetZoneSubNet( subnet );
+ }
+ }
+ } // End if ( old_subnet > 0 )
+ } // End if( connected )
+ }
+ }
+ } // End read all zones candidates
+}
+
+
+/**
+ * Function Merge_SubNets_Connected_By_CopperAreas(BOARD* aPcb)
+ * Calls Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode ) for each
+ * netcode found in zone list
+ * @param aPcb = the current board
+ */
+void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb )
+{
+ for( int index = 0; index < aPcb->GetAreaCount(); index++ )
+ {
+ ZONE_CONTAINER* zone = aPcb->GetArea( index );
+
+ if ( ! zone->IsOnCopperLayer() )
+ continue;
+
+ if ( zone->GetNetCode() <= 0 )
+ continue;
+
+ Merge_SubNets_Connected_By_CopperAreas( aPcb, zone->GetNetCode() );
+ }
+}
+
+
+/**
+ * Function Merge_SubNets_Connected_By_CopperAreas(BOARD* aPcb, int aNetcode)
+ * Used after connections by tracks calculations
+ * Merge subnets, in tracks ans pads when they are connected by a filled copper area
+ * for pads, this is the .m_physical_connexion member which is tested and modified
+ * for tracks, this is the .m_Subnet member which is tested and modified
+ * these members are block numbers (or cluster numbers) for a given net,
+ * calculated by Build_Pads_Info_Connections_By_Tracks()
+ * The result is merging 2 blocks (or subnets)
+ * @param aPcb = the current board
+ * @param aNetcode = netcode to consider
+ */
+void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode )
+{
+ // Ensure a zone with the given netcode exists: examine all zones:
+ bool found = false;
+
+ for( int index = 0; index < aPcb->GetAreaCount(); index++ )
+ {
+ ZONE_CONTAINER* zone = aPcb->GetArea( index );
+
+ if( aNetcode == zone->GetNetCode() )
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if( !found ) // No zone with this netcode, therefore no connection by zone
+ return;
+
+ // list of pads and tracks candidates to test:
+ // It is static to avoid multiple memory realloc.
+ static std::vector <BOARD_CONNECTED_ITEM*> Candidates;
+ Candidates.clear();
+
+ // Build the list of pads candidates connected to the net:
+ NETINFO_ITEM* net = aPcb->FindNet( aNetcode );
+ wxASSERT( net );
+ Candidates.reserve( net->m_PadInNetList.size() );
+ for( unsigned ii = 0; ii < net->m_PadInNetList.size(); ii++ )
+ Candidates.push_back( net->m_PadInNetList[ii] );
+
+ // Build the list of track candidates connected to the net:
+ TRACK* track;
+
+ if( aPcb->m_Track.GetCount() > 0 )
+ {
+ track = aPcb->m_Track.GetFirst()->GetStartNetCode( aNetcode );
+
+ for( ; track; track = track->Next() )
+ {
+ if( track->GetNetCode() != aNetcode )
+ break;
+
+ Candidates.push_back( track );
+ }
+ }
+
+ if( Candidates.size() == 0 )
+ return;
+
+ int next_subnet_free_number = 0;
+ for( unsigned ii = 0; ii < Candidates.size(); ii++ )
+ {
+ int subnet = Candidates[ii]->GetSubNet();
+ next_subnet_free_number = std::max( next_subnet_free_number, subnet );
+ }
+
+ next_subnet_free_number++; // This is a subnet we can use with not connected items
+ // by tracks, but connected by zone.
+
+ // Sort by zone_subnet:
+ sort( Candidates.begin(), Candidates.end(), CmpZoneSubnetValue );
+
+ // Some items can be not connected, but they can be connected to a filled area:
+ // give them a subnet common to these items connected only by the area,
+ // and not already used.
+ // a value like next_subnet_free_number+zone_subnet is right
+ for( unsigned jj = 0; jj < Candidates.size(); jj++ )
+ {
+ BOARD_CONNECTED_ITEM* item = Candidates[jj];
+ if ( item->GetSubNet() == 0 && (item->GetZoneSubNet() > 0) )
+ {
+ item->SetSubNet( next_subnet_free_number + item->GetZoneSubNet() );
+ }
+ }
+
+ // Now, for each zone subnet, we search for 2 items with different subnets.
+ // if found, the 2 subnet are merged in the whole candidate list.
+ int old_subnet = 0;
+ int old_zone_subnet = 0;
+ for( unsigned ii = 0; ii < Candidates.size(); ii++ )
+ {
+ BOARD_CONNECTED_ITEM* item = Candidates[ii];
+ int zone_subnet = item->GetZoneSubNet();
+
+ if( zone_subnet == 0 ) // Not connected by a filled area, skip it
+ continue;
+
+ int subnet = item->GetSubNet();
+
+ if( zone_subnet != old_zone_subnet ) // a new zone subnet is found
+ {
+ old_subnet = subnet;
+ old_zone_subnet = zone_subnet;
+ continue;
+ }
+
+ // 2 successive items already from the same cluster: nothing to do
+ if( subnet == old_subnet )
+ continue;
+
+ // Here we have 2 items connected by the same area have 2 differents subnets: merge subnets
+ if( (subnet > old_subnet) || ( subnet <= 0) )
+ std::swap( subnet, old_subnet );
+
+ for( unsigned jj = 0; jj < Candidates.size(); jj++ )
+ {
+ BOARD_CONNECTED_ITEM * item_to_merge = Candidates[jj];
+
+ if( item_to_merge->GetSubNet() == old_subnet )
+ item_to_merge->SetSubNet( subnet );
+ }
+
+ old_subnet = subnet;
+ }
+}
+
+
+/* Compare function used for sorting candidates by increasing zone subnet
+ */
+static bool CmpZoneSubnetValue( const BOARD_CONNECTED_ITEM* a, const BOARD_CONNECTED_ITEM* b )
+{
+ int asubnet, bsubnet;
+
+ asubnet = a->GetZoneSubNet();
+ bsubnet = b->GetZoneSubNet();
+
+ return asubnet < bsubnet;
+}
diff --git a/pcbnew/zones_test_and_combine_areas.cpp b/pcbnew/zones_test_and_combine_areas.cpp
new file mode 100644
index 0000000..9793756
--- /dev/null
+++ b/pcbnew/zones_test_and_combine_areas.cpp
@@ -0,0 +1,623 @@
+/**
+ * @file zones_test_and_combine_areas.cpp
+ * @brief Functions to test, merge and cut polygons used as copper areas outlines
+ * some pieces of code come from FreePCB.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * Some code comes from FreePCB.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <common.h>
+#include <confirm.h>
+#include <class_undoredo_container.h>
+
+#include <class_board.h>
+#include <class_zone.h>
+#include <class_marker_pcb.h>
+
+#include <pcbnew.h>
+#include <drc_stuff.h>
+#include <math_for_graphics.h>
+
+#define STRAIGHT 0 // To be remove after math_for_graphics code cleanup
+
+
+bool BOARD::OnAreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList,
+ ZONE_CONTAINER* modified_area )
+{
+ // clip polygon against itself
+ bool modified = NormalizeAreaPolygon( aModifiedZonesList, modified_area );
+
+ // now see if we need to clip against other areas
+ LAYER_NUM layer = modified_area->GetLayer();
+ bool bCheckAllAreas = TestAreaIntersections( modified_area );
+
+ if( bCheckAllAreas )
+ {
+ modified = true;
+ CombineAllAreasInNet( aModifiedZonesList, modified_area->GetNetCode(), true );
+ }
+
+ if( !IsCopperLayer( layer ) ) // Refill non copper zones on this layer
+ {
+ for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
+ if( m_ZoneDescriptorList[ia]->GetLayer() == layer )
+ m_ZoneDescriptorList[ia]->BuildFilledSolidAreasPolygons( this );
+ }
+
+ // Test for bad areas: all zones must have more than 2 corners:
+ // Note: should not happen, but just in case.
+ for( unsigned ii = 0; ii < m_ZoneDescriptorList.size(); )
+ {
+ ZONE_CONTAINER* zone = m_ZoneDescriptorList[ii];
+
+ if( zone->GetNumCorners() >= 3 )
+ ii++;
+ else // Remove zone because it is incorrect:
+ RemoveArea( aModifiedZonesList, zone );
+ }
+
+ return modified;
+}
+
+
+bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode,
+ bool aUseLocalFlags )
+{
+ if( m_ZoneDescriptorList.size() <= 1 )
+ return false;
+
+ bool modified = false;
+
+ // Loop through all combinations
+ for( unsigned ia1 = 0; ia1 < m_ZoneDescriptorList.size() - 1; ia1++ )
+ {
+ ZONE_CONTAINER* curr_area = m_ZoneDescriptorList[ia1];
+
+ if( curr_area->GetNetCode() != aNetCode )
+ continue;
+
+ // legal polygon
+ EDA_RECT b1 = curr_area->Outline()->GetBoundingBox();
+ bool mod_ia1 = false;
+
+ for( unsigned ia2 = m_ZoneDescriptorList.size() - 1; ia2 > ia1; ia2-- )
+ {
+ ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2];
+
+ if( area2->GetNetCode() != aNetCode )
+ continue;
+
+ if( curr_area->GetPriority() != area2->GetPriority() )
+ continue;
+
+ if( curr_area->GetIsKeepout() != area2->GetIsKeepout() )
+ continue;
+
+ if( curr_area->GetLayer() != area2->GetLayer() )
+ continue;
+
+ EDA_RECT b2 = area2->Outline()->GetBoundingBox();
+
+ if( b1.Intersects( b2 ) )
+ {
+ // check area2 against curr_area
+ if( curr_area->GetLocalFlags() || area2->GetLocalFlags()
+ || aUseLocalFlags == false )
+ {
+ bool ret = TestAreaIntersection( curr_area, area2 );
+
+ if( ret )
+ ret = CombineAreas( aDeletedList, curr_area, area2 );
+
+ if( ret )
+ {
+ mod_ia1 = true;
+ modified = true;
+ }
+ }
+ }
+ }
+
+ if( mod_ia1 )
+ ia1--; // if modified, we need to check it again
+ }
+
+ return modified;
+}
+
+
+bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test )
+{
+ for( unsigned ia2 = 0; ia2 < m_ZoneDescriptorList.size(); ia2++ )
+ {
+ ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2];
+
+ if( area_to_test->GetNetCode() != area2->GetNetCode() )
+ continue;
+
+ if( area_to_test == area2 )
+ continue;
+
+ // see if areas are on same layer
+ if( area_to_test->GetLayer() != area2->GetLayer() )
+ continue;
+
+ // test for different priorities
+ if( area_to_test->GetPriority() != area2->GetPriority() )
+ continue;
+
+ // test for different types
+ if( area_to_test->GetIsKeepout() != area2->GetIsKeepout() )
+ continue;
+
+ if( TestAreaIntersection( area_to_test, area2 ) )
+ return true;
+ }
+
+ return false;
+}
+
+
+bool BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test )
+{
+ // see if areas are on same layer
+ if( area_ref->GetLayer() != area_to_test->GetLayer() )
+ return false;
+
+ CPolyLine* poly1 = area_ref->Outline();
+ CPolyLine* poly2 = area_to_test->Outline();
+
+ // test bounding rects
+ EDA_RECT b1 = poly1->GetBoundingBox();
+ EDA_RECT b2 = poly2->GetBoundingBox();
+
+ if( ! b1.Intersects( b2 ) )
+ return false;
+
+ // now test for intersecting segments
+ for( int icont1 = 0; icont1<poly1->GetContoursCount(); icont1++ )
+ {
+ int is1 = poly1->GetContourStart( icont1 );
+ int ie1 = poly1->GetContourEnd( icont1 );
+
+ for( int ic1 = is1; ic1<=ie1; ic1++ )
+ {
+ int xi1 = poly1->GetX( ic1 );
+ int yi1 = poly1->GetY( ic1 );
+ int xf1, yf1;
+
+ if( ic1 < ie1 )
+ {
+ xf1 = poly1->GetX( ic1 + 1 );
+ yf1 = poly1->GetY( ic1 + 1 );
+ }
+ else
+ {
+ xf1 = poly1->GetX( is1 );
+ yf1 = poly1->GetY( is1 );
+ }
+
+ for( int icont2 = 0; icont2<poly2->GetContoursCount(); icont2++ )
+ {
+ int is2 = poly2->GetContourStart( icont2 );
+ int ie2 = poly2->GetContourEnd( icont2 );
+
+ for( int ic2 = is2; ic2<=ie2; ic2++ )
+ {
+ int xi2 = poly2->GetX( ic2 );
+ int yi2 = poly2->GetY( ic2 );
+ int xf2, yf2;
+
+ if( ic2 < ie2 )
+ {
+ xf2 = poly2->GetX( ic2 + 1 );
+ yf2 = poly2->GetY( ic2 + 1 );
+ }
+ else
+ {
+ xf2 = poly2->GetX( is2 );
+ yf2 = poly2->GetY( is2 );
+ }
+
+ bool intersect = FindSegmentIntersections( xi1, yi1, xf1, yf1,
+ xi2, yi2, xf2, yf2 );
+ if( intersect )
+ return true;
+ }
+ }
+ }
+ }
+
+ // If a contour is inside an other contour, no segments intersects, but the zones
+ // can be combined if a corner is inside an outline (only one corner is enought)
+ for( int ic2 = 0; ic2 < poly2->GetCornersCount(); ic2++ )
+ {
+ int x = poly2->GetX( ic2 );
+ int y = poly2->GetY( ic2 );
+
+ if( poly1->TestPointInside( x, y ) )
+ {
+ return true;
+ }
+ }
+
+ for( int ic1 = 0; ic1 < poly1->GetCornersCount(); ic1++ )
+ {
+ int x = poly1->GetX( ic1 );
+ int y = poly1->GetY( ic1 );
+
+ if( poly2->TestPointInside( x, y ) )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+bool BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_ref,
+ ZONE_CONTAINER* area_to_combine )
+{
+ if( area_ref == area_to_combine )
+ {
+ wxASSERT( 0 );
+ return false;
+ }
+
+ SHAPE_POLY_SET mergedOutlines = ConvertPolyListToPolySet( area_ref->Outline()->m_CornersList );
+ SHAPE_POLY_SET areaToMergePoly = ConvertPolyListToPolySet( area_to_combine->Outline()->m_CornersList );
+
+ mergedOutlines.BooleanAdd( areaToMergePoly );
+ mergedOutlines.Simplify();
+
+ // We should have one polygon with hole
+ // We can have 2 polygons with hole, if the 2 initial polygons have only one common corner
+ // and therefore cannot be merged (they are dectected as intersecting)
+ // but we should never have more than 2 polys
+ if( mergedOutlines.OutlineCount() > 2 )
+ {
+ wxLogMessage(wxT("BOARD::CombineAreas error: more than 2 polys after merging") );
+ return false;
+ }
+
+ if( mergedOutlines.OutlineCount() > 1 )
+ return false;
+
+ area_ref->Outline()->m_CornersList = ConvertPolySetToPolyList( mergedOutlines );
+
+ RemoveArea( aDeletedList, area_to_combine );
+
+ area_ref->SetLocalFlags( 1 );
+ area_ref->Outline()->Hatch();
+
+ return true;
+}
+
+
+int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine,
+ bool aCreate_Markers )
+{
+ int nerrors = 0;
+
+ // iterate through all areas
+ for( int ia = 0; ia < GetAreaCount(); ia++ )
+ {
+ ZONE_CONTAINER* Area_Ref = GetArea( ia );
+ CPolyLine* refSmoothedPoly = Area_Ref->GetSmoothedPoly();
+
+ if( !Area_Ref->IsOnCopperLayer() )
+ continue;
+
+ // When testing only a single area, skip all others
+ if( aArea_To_Examine && (aArea_To_Examine != Area_Ref) )
+ continue;
+
+ for( int ia2 = 0; ia2 < GetAreaCount(); ia2++ )
+ {
+ ZONE_CONTAINER* area_to_test = GetArea( ia2 );
+ CPolyLine* testSmoothedPoly = area_to_test->GetSmoothedPoly();
+
+ if( Area_Ref == area_to_test )
+ continue;
+
+ // test for same layer
+ if( Area_Ref->GetLayer() != area_to_test->GetLayer() )
+ continue;
+
+ // Test for same net
+ if( Area_Ref->GetNetCode() == area_to_test->GetNetCode() && Area_Ref->GetNetCode() >= 0 )
+ continue;
+
+ // test for different priorities
+ if( Area_Ref->GetPriority() != area_to_test->GetPriority() )
+ continue;
+
+ // test for different types
+ if( Area_Ref->GetIsKeepout() != area_to_test->GetIsKeepout() )
+ continue;
+
+ // Examine a candidate zone: compare area_to_test to Area_Ref
+
+ // Get clearance used in zone to zone test. The policy used to
+ // obtain that value is now part of the zone object itself by way of
+ // ZONE_CONTAINER::GetClearance().
+ int zone2zoneClearance = Area_Ref->GetClearance( area_to_test );
+
+ // Keepout areas have no clearance, so set zone2zoneClearance to 1
+ // ( zone2zoneClearance = 0 can create problems in test functions)
+ if( Area_Ref->GetIsKeepout() )
+ zone2zoneClearance = 1;
+
+ // test for some corners of Area_Ref inside area_to_test
+ for( int ic = 0; ic < refSmoothedPoly->GetCornersCount(); ic++ )
+ {
+ int x = refSmoothedPoly->GetX( ic );
+ int y = refSmoothedPoly->GetY( ic );
+
+ if( testSmoothedPoly->TestPointInside( x, y ) )
+ {
+ // COPPERAREA_COPPERAREA error: copper area ref corner inside copper area
+ if( aCreate_Markers )
+ {
+ wxString msg1 = Area_Ref->GetSelectMenuText();
+ wxString msg2 = area_to_test->GetSelectMenuText();
+ MARKER_PCB* marker = new MARKER_PCB( COPPERAREA_INSIDE_COPPERAREA,
+ wxPoint( x, y ),
+ msg1, wxPoint( x, y ),
+ msg2, wxPoint( x, y ) );
+ Add( marker );
+ }
+
+ nerrors++;
+ }
+ }
+
+ // test for some corners of area_to_test inside Area_Ref
+ for( int ic2 = 0; ic2 < testSmoothedPoly->GetCornersCount(); ic2++ )
+ {
+ int x = testSmoothedPoly->GetX( ic2 );
+ int y = testSmoothedPoly->GetY( ic2 );
+
+ if( refSmoothedPoly->TestPointInside( x, y ) )
+ {
+ // COPPERAREA_COPPERAREA error: copper area corner inside copper area ref
+ if( aCreate_Markers )
+ {
+ wxString msg1 = area_to_test->GetSelectMenuText();
+ wxString msg2 = Area_Ref->GetSelectMenuText();
+ MARKER_PCB* marker = new MARKER_PCB( COPPERAREA_INSIDE_COPPERAREA,
+ wxPoint( x, y ),
+ msg1, wxPoint( x, y ),
+ msg2, wxPoint( x, y ) );
+ Add( marker );
+ }
+
+ nerrors++;
+ }
+ }
+
+ // now test spacing between areas
+ for( int icont = 0; icont < refSmoothedPoly->GetContoursCount(); icont++ )
+ {
+ int ic_start = refSmoothedPoly->GetContourStart( icont );
+ int ic_end = refSmoothedPoly->GetContourEnd( icont );
+
+ for( int ic = ic_start; ic<=ic_end; ic++ )
+ {
+ int ax1 = refSmoothedPoly->GetX( ic );
+ int ay1 = refSmoothedPoly->GetY( ic );
+ int ax2, ay2;
+
+ if( ic == ic_end )
+ {
+ ax2 = refSmoothedPoly->GetX( ic_start );
+ ay2 = refSmoothedPoly->GetY( ic_start );
+ }
+ else
+ {
+ ax2 = refSmoothedPoly->GetX( ic + 1 );
+ ay2 = refSmoothedPoly->GetY( ic + 1 );
+ }
+
+ for( int icont2 = 0; icont2 < testSmoothedPoly->GetContoursCount(); icont2++ )
+ {
+ int ic_start2 = testSmoothedPoly->GetContourStart( icont2 );
+ int ic_end2 = testSmoothedPoly->GetContourEnd( icont2 );
+
+ for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ )
+ {
+ int bx1 = testSmoothedPoly->GetX( ic2 );
+ int by1 = testSmoothedPoly->GetY( ic2 );
+ int bx2, by2;
+
+ if( ic2 == ic_end2 )
+ {
+ bx2 = testSmoothedPoly->GetX( ic_start2 );
+ by2 = testSmoothedPoly->GetY( ic_start2 );
+ }
+ else
+ {
+ bx2 = testSmoothedPoly->GetX( ic2 + 1 );
+ by2 = testSmoothedPoly->GetY( ic2 + 1 );
+ }
+
+ int x, y;
+
+ int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2,
+ 0,
+ ax1, ay1, ax2, ay2,
+ 0,
+ zone2zoneClearance,
+ &x, &y );
+
+ if( d < zone2zoneClearance )
+ {
+ // COPPERAREA_COPPERAREA error : intersect or too close
+ if( aCreate_Markers )
+ {
+ wxString msg1 = Area_Ref->GetSelectMenuText();
+ wxString msg2 = area_to_test->GetSelectMenuText();
+ MARKER_PCB* marker = new MARKER_PCB( COPPERAREA_CLOSE_TO_COPPERAREA,
+ wxPoint( x, y ),
+ msg1, wxPoint( x, y ),
+ msg2, wxPoint( x, y ) );
+ Add( marker );
+ }
+
+ nerrors++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return nerrors;
+}
+
+
+bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
+{
+ if( !aArea->IsOnCopperLayer() ) // Cannot have a Drc error if not on copper layer
+ return true;
+
+ wxPoint start = aArea->GetCornerPosition( aCornerIndex );
+ wxPoint end;
+
+ // Search the end point of the edge starting at aCornerIndex
+ if( aArea->Outline()->m_CornersList[aCornerIndex].end_contour == false
+ && aCornerIndex < (aArea->GetNumCorners() - 1) )
+ {
+ end = aArea->GetCornerPosition( aCornerIndex + 1 );
+ }
+ else // aCornerIndex is the last corner of an outline.
+ // the corresponding end point of the segment is the first corner of the outline
+ {
+ int ii = aCornerIndex - 1;
+ end = aArea->GetCornerPosition( ii );
+
+ while( ii >= 0 )
+ {
+ if( aArea->Outline()->m_CornersList[ii].end_contour )
+ break;
+
+ end = aArea->GetCornerPosition( ii );
+ ii--;
+ }
+ }
+
+ // iterate through all areas
+ for( int ia2 = 0; ia2 < m_pcb->GetAreaCount(); ia2++ )
+ {
+ ZONE_CONTAINER* area_to_test = m_pcb->GetArea( ia2 );
+ int zone_clearance = std::max( area_to_test->GetZoneClearance(),
+ aArea->GetZoneClearance() );
+
+ // test for same layer
+ if( area_to_test->GetLayer() != aArea->GetLayer() )
+ continue;
+
+ // Test for same net
+ if( ( aArea->GetNetCode() == area_to_test->GetNetCode() ) && (aArea->GetNetCode() >= 0) )
+ continue;
+
+ // test for same priority
+ if( area_to_test->GetPriority() != aArea->GetPriority() )
+ continue;
+
+ // test for same type
+ if( area_to_test->GetIsKeepout() != aArea->GetIsKeepout() )
+ continue;
+
+ // For keepout, there is no clearance, so use a minimal value for it
+ // use 1, not 0 as value to avoid some issues in tests
+ if( area_to_test->GetIsKeepout() )
+ zone_clearance = 1;
+
+ // test for ending line inside area_to_test
+ if( area_to_test->Outline()->TestPointInside( end.x, end.y ) )
+ {
+ // COPPERAREA_COPPERAREA error: corner inside copper area
+ m_currentMarker = fillMarker( aArea, end,
+ COPPERAREA_INSIDE_COPPERAREA,
+ m_currentMarker );
+ return false;
+ }
+
+ // now test spacing between areas
+ int ax1 = start.x;
+ int ay1 = start.y;
+ int ax2 = end.x;
+ int ay2 = end.y;
+
+ for( int icont2 = 0; icont2 < area_to_test->Outline()->GetContoursCount(); icont2++ )
+ {
+ int ic_start2 = area_to_test->Outline()->GetContourStart( icont2 );
+ int ic_end2 = area_to_test->Outline()->GetContourEnd( icont2 );
+
+ for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ )
+ {
+ int bx1 = area_to_test->Outline()->GetX( ic2 );
+ int by1 = area_to_test->Outline()->GetY( ic2 );
+ int bx2, by2;
+
+ if( ic2 == ic_end2 )
+ {
+ bx2 = area_to_test->Outline()->GetX( ic_start2 );
+ by2 = area_to_test->Outline()->GetY( ic_start2 );
+ }
+ else
+ {
+ bx2 = area_to_test->Outline()->GetX( ic2 + 1 );
+ by2 = area_to_test->Outline()->GetY( ic2 + 1 );
+ }
+
+ int x, y; // variables containing the intersecting point coordinates
+ int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2,
+ 0,
+ ax1, ay1, ax2, ay2,
+ 0,
+ zone_clearance,
+ &x, &y );
+
+ if( d < zone_clearance )
+ {
+ // COPPERAREA_COPPERAREA error : edge intersect or too close
+ m_currentMarker = fillMarker( aArea, wxPoint( x, y ),
+ COPPERAREA_CLOSE_TO_COPPERAREA,
+ m_currentMarker );
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}